Преглед изворни кода

[bsp][rockchip] Port to DM

RK3588/RK3576/RK356x/RK3308

Signed-off-by: GuEe-GUI <2991707448@qq.com>
GuEe-GUI пре 1 недеља
родитељ
комит
45fe9ee96b
100 измењених фајлова са 24065 додато и 191 уклоњено
  1. 13 13
      bsp/README.md
  2. 24 0
      bsp/rockchip/dm/Kconfig
  3. 1 2
      bsp/rockchip/dm/SConscript
  4. 6 0
      bsp/rockchip/dm/adc/Kconfig
  5. 14 0
      bsp/rockchip/dm/adc/SConscript
  6. 527 0
      bsp/rockchip/dm/adc/adc-rockchip_saradc.c
  7. 7 0
      bsp/rockchip/dm/can/Kconfig
  8. 12 0
      bsp/rockchip/dm/can/SConscript
  9. 1061 0
      bsp/rockchip/dm/can/canfd-rockchip.c
  10. 36 0
      bsp/rockchip/dm/clk/Kconfig
  11. 33 0
      bsp/rockchip/dm/clk/SConscript
  12. 210 0
      bsp/rockchip/dm/clk/clk-link.c
  13. 51 0
      bsp/rockchip/dm/clk/clk-rk-composite.c
  14. 191 0
      bsp/rockchip/dm/clk/clk-rk-composite.h
  15. 278 0
      bsp/rockchip/dm/clk/clk-rk-cpu.c
  16. 87 0
      bsp/rockchip/dm/clk/clk-rk-cpu.h
  17. 595 0
      bsp/rockchip/dm/clk/clk-rk-divider.c
  18. 52 0
      bsp/rockchip/dm/clk/clk-rk-divider.h
  19. 61 0
      bsp/rockchip/dm/clk/clk-rk-factor.c
  20. 63 0
      bsp/rockchip/dm/clk/clk-rk-factor.h
  21. 370 0
      bsp/rockchip/dm/clk/clk-rk-fraction-divider.c
  22. 95 0
      bsp/rockchip/dm/clk/clk-rk-fraction-divider.h
  23. 109 0
      bsp/rockchip/dm/clk/clk-rk-gate.c
  24. 32 0
      bsp/rockchip/dm/clk/clk-rk-gate.h
  25. 182 0
      bsp/rockchip/dm/clk/clk-rk-half-divider.c
  26. 126 0
      bsp/rockchip/dm/clk/clk-rk-half-divider.h
  27. 68 19
      bsp/rockchip/dm/clk/clk-rk-mmc-phase.c
  28. 48 0
      bsp/rockchip/dm/clk/clk-rk-mmc-phase.h
  29. 159 0
      bsp/rockchip/dm/clk/clk-rk-mux.c
  30. 57 0
      bsp/rockchip/dm/clk/clk-rk-mux.h
  31. 85 0
      bsp/rockchip/dm/clk/clk-rk-muxgrf.c
  32. 50 0
      bsp/rockchip/dm/clk/clk-rk-muxgrf.h
  33. 1546 0
      bsp/rockchip/dm/clk/clk-rk-pll.c
  34. 144 0
      bsp/rockchip/dm/clk/clk-rk-pll.h
  35. 169 0
      bsp/rockchip/dm/clk/clk-rk.c
  36. 107 0
      bsp/rockchip/dm/clk/clk-rk.h
  37. 950 0
      bsp/rockchip/dm/clk/clk-rk3308.c
  38. 1488 0
      bsp/rockchip/dm/clk/clk-rk3568.c
  39. 1839 0
      bsp/rockchip/dm/clk/clk-rk3576.c
  40. 2166 0
      bsp/rockchip/dm/clk/clk-rk3588.c
  41. 203 0
      bsp/rockchip/dm/clk/clk-rk8xx-clkout.c
  42. 31 18
      bsp/rockchip/dm/clk/softrst.c
  43. 5 0
      bsp/rockchip/dm/hwcrypto/Kconfig
  44. 5 6
      bsp/rockchip/dm/hwcrypto/SConscript
  45. 565 0
      bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c
  46. 3 0
      bsp/rockchip/dm/hwspinlock/Kconfig
  47. 12 0
      bsp/rockchip/dm/hwspinlock/SConscript
  48. 135 0
      bsp/rockchip/dm/hwspinlock/hwspinlock-rockchip.c
  49. 0 2
      bsp/rockchip/dm/hwtimer/Kconfig
  50. 3 4
      bsp/rockchip/dm/hwtimer/SConscript
  51. 58 122
      bsp/rockchip/dm/hwtimer/hwtimer-rockchip_timer.c
  52. 5 0
      bsp/rockchip/dm/i2c/Kconfig
  53. 12 0
      bsp/rockchip/dm/i2c/SConscript
  54. 1375 0
      bsp/rockchip/dm/i2c/i2c-rk3x.c
  55. 387 0
      bsp/rockchip/dm/include/dt-bindings/clock/rk3308-cru.h
  56. 7 1
      bsp/rockchip/dm/include/dt-bindings/clock/rk3568-cru.h
  57. 1151 0
      bsp/rockchip/dm/include/dt-bindings/clock/rk3576-cru.h
  58. 8 4
      bsp/rockchip/dm/include/dt-bindings/clock/rk3588-cru.h
  59. 22 0
      bsp/rockchip/dm/include/dt-bindings/phye/phye-snps-pcie3.h
  60. 232 0
      bsp/rockchip/dm/include/dt-bindings/pinctrl/rockchip.h
  61. 32 0
      bsp/rockchip/dm/include/dt-bindings/power/px30-power.h
  62. 25 0
      bsp/rockchip/dm/include/dt-bindings/power/rk1808-power.h
  63. 18 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3036-power.h
  64. 27 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3066-power.h
  65. 19 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3128-power.h
  66. 29 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3188-power.h
  67. 22 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3228-power.h
  68. 33 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3288-power.h
  69. 21 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3328-power.h
  70. 30 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3366-power.h
  71. 34 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3368-power.h
  72. 59 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3399-power.h
  73. 23 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3528-power.h
  74. 37 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3562-power.h
  75. 37 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3568-power.h
  76. 35 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3576-power.h
  77. 74 0
      bsp/rockchip/dm/include/dt-bindings/power/rk3588-power.h
  78. 39 0
      bsp/rockchip/dm/include/dt-bindings/power/rv1126-power.h
  79. 40 0
      bsp/rockchip/dm/include/hw-decompress.h
  80. 183 0
      bsp/rockchip/dm/include/pinctrl-rockchip.h
  81. 912 0
      bsp/rockchip/dm/include/rk8xx.h
  82. 86 0
      bsp/rockchip/dm/include/rockchip.h
  83. 13 0
      bsp/rockchip/dm/input/SConscript
  84. 5 0
      bsp/rockchip/dm/input/misc/Kconfig
  85. 13 0
      bsp/rockchip/dm/input/misc/SConscript
  86. 115 0
      bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c
  87. 3 0
      bsp/rockchip/dm/mailbox/Kconfig
  88. 12 0
      bsp/rockchip/dm/mailbox/SConscript
  89. 575 0
      bsp/rockchip/dm/mailbox/mailbox-rockchip.c
  90. 19 0
      bsp/rockchip/dm/mfd/Kconfig
  91. 18 0
      bsp/rockchip/dm/mfd/SConscript
  92. 187 0
      bsp/rockchip/dm/mfd/rk8xx-i2c.c
  93. 148 0
      bsp/rockchip/dm/mfd/rk8xx-spi.c
  94. 1088 0
      bsp/rockchip/dm/mfd/rk8xx.c
  95. 3 0
      bsp/rockchip/dm/nvmem/Kconfig
  96. 12 0
      bsp/rockchip/dm/nvmem/SConscript
  97. 1037 0
      bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c
  98. 11 0
      bsp/rockchip/dm/pci/Kconfig
  99. 15 0
      bsp/rockchip/dm/pci/SConscript
  100. 1645 0
      bsp/rockchip/dm/pci/pcie-dw-rockchip.c

+ 13 - 13
bsp/README.md

@@ -342,11 +342,11 @@ This document is based on the RT-Thread mainline repository and categorizes the
 
 #### 🟡 Rockchip
 
-| BSP Name | GPIO | UART | ADC | I2C | SPI | WDT |
-|----------|------|------|-----|-----|-----|-----|
-| [rk2108](rockchip/rk2108) | - | ✅ | - | - | - | - |
-| [rk3500](rockchip/rk3500) | - | ✅ | - | - | - | - |
-| [rk3568](rockchip/rk3568) | - | ✅ | - | - | - | - |
+| BSP Name | GPIO | UART | ADC | I2C | SPI | WDT | HWTimer | PWM | RTC | SDIO | CAN | PCI |
+|----------|------|------|-----|-----|-----|-----|---------|-----|-----|------|-----|------|
+| [rk2108](rockchip/rk2108) | - | ✅ | - | - | - | - | - | - | - | - | - | - |
+| [rk3300](rockchip/rk3300) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - |
+| [rk3500](rockchip/rk3500) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
 
 #### 🟡 APM32
 
@@ -417,22 +417,22 @@ This document is based on the RT-Thread mainline repository and categorizes the
 | [swm320-mini](synwit/swm320-mini) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
 | [swm341-mini](synwit/swm341-mini) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
 
-#### ⚪ N32G452xx 
+#### ⚪ N32G452xx
 | BSP Name | GPIO | UART | ADC | CAN | DAC | Flash | HWTimer | I2C | PWM | RTC | SDIO | SPI | WDT |
 |----------|------|------|-----|-----|-----|-------|---------|-----|-----|-----|------|-----|-----|
 | [n32g452xx-mini-system](n32g452xx/n32g452xx-mini-system) | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ |
 
-#### ⚪ W60x 
+#### ⚪ W60x
 | BSP Name | GPIO | UART | ADC | Crypto | Flash | HWTimer | WDT | PWM | I2C | SPI |
 |----------|------|------|-----|--------|-------|---------|-----|-----|-----|-----|
 | [w60x](w60x) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
 
-#### ⚪ Allwinner Tina 
+#### ⚪ Allwinner Tina
 | BSP Name | GPIO | UART | SPI | SDIO |
 |----------|------|------|-----|------|
 | [allwinner_tina](allwinner_tina) | ✅ | ✅ | ✅ | ✅ |
 
-#### ⚪ HC321136 
+#### ⚪ HC321136
 | BSP Name | GPIO | UART | I2C |
 |----------|------|------|-----|
 | [hc321136](hc32/hc321136) | ✅ | ✅ | ✅ |
@@ -442,7 +442,7 @@ This document is based on the RT-Thread mainline repository and categorizes the
 |----------|------|------|
 | [hc321196](hc32/hc321196) | ✅ | ✅ |
 
-#### ⚪ Amebaz 
+#### ⚪ Amebaz
 | BSP Name | GPIO | UART | WLAN |
 |----------|------|------|------|
 | [amebaz](amebaz) | - | ✅ | ✅ |
@@ -840,17 +840,17 @@ This document is based on the RT-Thread mainline repository and categorizes the
 |----------|------|------|-----|-------|---------|------|-----|-----|------|----------|-----|
 | [ab32vg1-ab-prougen](bluetrum/ab32vg1-ab-prougen) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
 
-#### ⚪ Core-V-MCU 
+#### ⚪ Core-V-MCU
 | BSP Name | UART |
 |----------|------|
 | [core-v-cv32e40p](core-v-mcu/core-v-cv32e40p) | ✅ |
 
-#### ⚪ HiFive1 
+#### ⚪ HiFive1
 | BSP Name | GPIO | UART |
 |----------|------|------|
 | [hifive1](hifive1) | ✅ | ✅ |
 
-#### ⚪ Sparkfun-RedV 
+#### ⚪ Sparkfun-RedV
 | BSP Name | GPIO | UART | ADC | I2C | SPI | WDT | Timer | PWM | RTC |
 |----------|------|------|-----|-----|-----|-----|-------|-----|-----|
 | [sparkfun-redv](sparkfun-redv) | ✅ | ✅ | - | - | - | - | ✅ | - | - |

+ 24 - 0
bsp/rockchip/dm/Kconfig

@@ -0,0 +1,24 @@
+SOC_DM_ADC_DIR          = $(SOC_DM_DIR)/adc
+SOC_DM_CAN_DIR          = $(SOC_DM_DIR)/can
+SOC_DM_CLK_DIR          = $(SOC_DM_DIR)/clk
+SOC_DM_HWCRYPTO_DIR     = $(SOC_DM_DIR)/hwcrypto
+SOC_DM_HWSPINLOCK_DIR   = $(SOC_DM_DIR)/hwspinlock
+SOC_DM_HWTIMER_DIR      = $(SOC_DM_DIR)/hwtimer
+SOC_DM_I2C_DIR          = $(SOC_DM_DIR)/i2c
+SOC_DM_INPUT_MISC_DIR   = $(SOC_DM_DIR)/input/misc
+SOC_DM_MBOX_DIR         = $(SOC_DM_DIR)/mailbox
+SOC_DM_MFD_DIR          = $(SOC_DM_DIR)/mfd
+SOC_DM_NVMEM_DIR        = $(SOC_DM_DIR)/nvmem
+SOC_DM_PCI_DIR          = $(SOC_DM_DIR)/pci
+SOC_DM_PHYE_DIR         = $(SOC_DM_DIR)/phye
+SOC_DM_PIN_DIR          = $(SOC_DM_DIR)/pin
+SOC_DM_PINCTRL_DIR      = $(SOC_DM_DIR)/pinctrl
+SOC_DM_PMDOMAIN_DIR     = $(SOC_DM_DIR)/pmdomain
+SOC_DM_PWM_DIR          = $(SOC_DM_DIR)/pwm
+SOC_DM_REGULATOR_DIR    = $(SOC_DM_DIR)/regulator
+SOC_DM_RTC_DIR          = $(SOC_DM_DIR)/rtc
+SOC_DM_SDIO_DIR         = $(SOC_DM_DIR)/sdio
+SOC_DM_SOC_DIR          = $(SOC_DM_DIR)/soc
+SOC_DM_SPI_DIR          = $(SOC_DM_DIR)/spi
+SOC_DM_THERMAL_DIR      = $(SOC_DM_DIR)/thermal
+SOC_DM_WDT_DIR          = $(SOC_DM_DIR)/watchdog

+ 1 - 2
bsp/rockchip/rk3568/SConscript → bsp/rockchip/dm/SConscript

@@ -1,8 +1,7 @@
-# for module compiling
 import os
 from building import *
 
-cwd  = GetCurrentDir()
+cwd = GetCurrentDir()
 objs = []
 list = os.listdir(cwd)
 

+ 6 - 0
bsp/rockchip/dm/adc/Kconfig

@@ -0,0 +1,6 @@
+config RT_ADC_ROCKCHIP_SARADC
+    bool "Rockchip SARADC driver"
+    depends on RT_USING_ADC
+    depends on RT_USING_RESET
+    depends on RT_USING_REGULATOR
+    default n

+ 14 - 0
bsp/rockchip/dm/adc/SConscript

@@ -0,0 +1,14 @@
+from building import *
+
+group = []
+cwd = GetCurrentDir()
+CPPPATH = [cwd + '/../include']
+
+src = []
+
+if GetDepend(['RT_USING_ADC']):
+    src += ['adc-rockchip_saradc.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 527 - 0
bsp/rockchip/dm/adc/adc-rockchip_saradc.c

@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define SARADC_DATA             0x00
+
+#define SARADC_STAS             0x04
+#define SARADC_STAS_BUSY        RT_BIT(0)
+
+#define SARADC_CTRL             0x08
+#define SARADC_CTRL_IRQ_STATUS  RT_BIT(6)
+#define SARADC_CTRL_IRQ_ENABLE  RT_BIT(5)
+#define SARADC_CTRL_POWER_CTRL  RT_BIT(3)
+#define SARADC_CTRL_CHN_MASK    0x7
+
+#define SARADC_DLY_PU_SOC       0x0c
+#define SARADC_DLY_PU_SOC_MASK  0x3f
+
+#define SARADC_TIMEOUT          rt_tick_from_millisecond(100)
+#define SARADC_MAX_CHANNELS     8
+
+/* v2 registers */
+#define SARADC2_CONV_CON        0x000
+#define SARADC_T_PD_SOC         0x004
+#define SARADC_T_DAS_SOC        0x00c
+#define SARADC2_END_INT_EN      0x104
+#define SARADC2_ST_CON          0x108
+#define SARADC2_STATUS          0x10c
+#define SARADC2_END_INT_ST      0x110
+#define SARADC2_DATA_BASE       0x120
+
+#define SARADC2_EN_END_INT      RT_BIT(0)
+#define SARADC2_START           RT_BIT(4)
+#define SARADC2_SINGLE_MODE     RT_BIT(5)
+
+#define SARADC2_CONV_CHANNELS   RT_GENMASK(15, 0)
+
+struct saradc_channel
+{
+    int channel;
+    int scan_index;
+
+    struct
+    {
+        char sign;
+        rt_uint8_t realbits;
+        rt_uint8_t storagebits;
+        rt_uint8_t repeat;
+    } scan_type;
+
+    rt_base_t info_mask_separate;
+    rt_base_t info_mask_shared_by_type;
+
+    const char *datasheet_name;
+};
+
+struct rockchip_saradc;
+
+struct rockchip_saradc_soc_data
+{
+    const struct saradc_channel *channels;
+    int num_channels;
+
+    rt_ubase_t clk_rate;
+    void (*start)(struct rockchip_saradc *rk_saradc, int chn);
+    int (*read)(struct rockchip_saradc *rk_saradc);
+    void (*power_down)(struct rockchip_saradc *rk_saradc);
+};
+
+struct rockchip_saradc
+{
+    struct rt_adc_device parent;
+
+    int irq;
+    void *regs;
+    struct rt_clk *clk;
+    struct rt_clk *pclk;
+    struct rt_regulator *vref;
+    struct rt_reset_control *rstc;
+
+    const struct rockchip_saradc_soc_data *soc_data;
+
+    rt_uint16_t last_val;
+    struct saradc_channel *last_chan;
+
+    struct rt_mutex lock;
+    struct rt_completion completion;
+};
+
+#define raw_to_rockchip_saradc(raw) rt_container_of(raw, struct rockchip_saradc, parent)
+
+#define SARADC_CHANNEL(INDEX, ID, RES)      \
+{                                           \
+    .channel = INDEX,                       \
+    .info_mask_separate = RT_BIT(0),        \
+    .info_mask_shared_by_type = RT_BIT(2),  \
+    .datasheet_name = ID,                   \
+    .scan_index = INDEX,                    \
+    .scan_type =                            \
+    {                                       \
+        .sign = 'u',                        \
+        .realbits = RES,                    \
+        .storagebits = 16,                  \
+    },                                      \
+}
+
+static void rockchip_saradc_start_v1(struct rockchip_saradc *rk_saradc, int chn)
+{
+    /* 8 clock periods as delay between power up and start cmd */
+    HWREG32(rk_saradc->regs + SARADC_DLY_PU_SOC) = 8;
+    /* Select the channel to be used and trigger conversion */
+    HWREG32(rk_saradc->regs + SARADC_CTRL) = SARADC_CTRL_POWER_CTRL |
+            (chn & SARADC_CTRL_CHN_MASK) | SARADC_CTRL_IRQ_ENABLE;
+}
+
+static void rockchip_saradc_reset_controller(struct rockchip_saradc *rk_saradc);
+
+static void rockchip_saradc_start_v2(struct rockchip_saradc *rk_saradc, int chn)
+{
+    int val;
+
+    if (rk_saradc->rstc)
+    {
+        rockchip_saradc_reset_controller(rk_saradc);
+    }
+
+    HWREG32(rk_saradc->regs + SARADC_T_DAS_SOC) = 0xc;
+    HWREG32(rk_saradc->regs + SARADC_T_PD_SOC) = 0x20;
+
+    val = RT_FIELD_PREP(SARADC2_EN_END_INT, 1);
+    val |= val << 16;
+    HWREG32(rk_saradc->regs + SARADC2_END_INT_EN) = val;
+
+    val = RT_FIELD_PREP(SARADC2_START, 1) |
+          RT_FIELD_PREP(SARADC2_SINGLE_MODE, 1) |
+          RT_FIELD_PREP(SARADC2_CONV_CHANNELS, chn);
+    val |= val << 16;
+    HWREG32(rk_saradc->regs + SARADC2_CONV_CON) = val;
+}
+
+static int rockchip_saradc_read_v1(struct rockchip_saradc *rk_saradc)
+{
+    return HWREG32(rk_saradc->regs + SARADC_DATA);
+}
+
+static int rockchip_saradc_read_v2(struct rockchip_saradc *rk_saradc)
+{
+    int offset;
+
+    /* Clear irq */
+    HWREG32(rk_saradc->regs + SARADC2_END_INT_ST) = 0x1;
+
+    offset = SARADC2_DATA_BASE + rk_saradc->last_chan->channel * 0x4;
+
+    return HWREG32(rk_saradc->regs + offset);
+}
+
+static void rockchip_saradc_power_down_v1(struct rockchip_saradc *rk_saradc)
+{
+    HWREG32(rk_saradc->regs + SARADC_CTRL) = 0;
+}
+
+static const struct saradc_channel rockchip_saradc_channels[] =
+{
+    SARADC_CHANNEL(0, "adc0", 10),
+    SARADC_CHANNEL(1, "adc1", 10),
+    SARADC_CHANNEL(2, "adc2", 10),
+};
+
+static const struct rockchip_saradc_soc_data saradc_data =
+{
+    .channels = rockchip_saradc_channels,
+    .num_channels = RT_ARRAY_SIZE(rockchip_saradc_channels),
+    .clk_rate = 1000000,
+    .start = rockchip_saradc_start_v1,
+    .read = rockchip_saradc_read_v1,
+    .power_down = rockchip_saradc_power_down_v1,
+};
+
+static const struct saradc_channel rk3066_tsadc_channels[] =
+{
+    SARADC_CHANNEL(0, "adc0", 12),
+    SARADC_CHANNEL(1, "adc1", 12),
+};
+
+static const struct rockchip_saradc_soc_data rk3066_tsadc_data =
+{
+    .channels = rk3066_tsadc_channels,
+    .num_channels = RT_ARRAY_SIZE(rk3066_tsadc_channels),
+    .clk_rate = 50000,
+    .start = rockchip_saradc_start_v1,
+    .read = rockchip_saradc_read_v1,
+    .power_down = rockchip_saradc_power_down_v1,
+};
+
+static const struct saradc_channel rk3399_saradc_channels[] =
+{
+    SARADC_CHANNEL(0, "adc0", 10),
+    SARADC_CHANNEL(1, "adc1", 10),
+    SARADC_CHANNEL(2, "adc2", 10),
+    SARADC_CHANNEL(3, "adc3", 10),
+    SARADC_CHANNEL(4, "adc4", 10),
+    SARADC_CHANNEL(5, "adc5", 10),
+};
+
+static const struct rockchip_saradc_soc_data rk3399_saradc_data =
+{
+    .channels = rk3399_saradc_channels,
+    .num_channels = RT_ARRAY_SIZE(rk3399_saradc_channels),
+    .clk_rate = 1000000,
+    .start = rockchip_saradc_start_v1,
+    .read = rockchip_saradc_read_v1,
+    .power_down = rockchip_saradc_power_down_v1,
+};
+
+static const struct saradc_channel rk3568_saradc_channels[] =
+{
+    SARADC_CHANNEL(0, "adc0", 10),
+    SARADC_CHANNEL(1, "adc1", 10),
+    SARADC_CHANNEL(2, "adc2", 10),
+    SARADC_CHANNEL(3, "adc3", 10),
+    SARADC_CHANNEL(4, "adc4", 10),
+    SARADC_CHANNEL(5, "adc5", 10),
+    SARADC_CHANNEL(6, "adc6", 10),
+    SARADC_CHANNEL(7, "adc7", 10),
+};
+
+static const struct rockchip_saradc_soc_data rk3568_saradc_data =
+{
+    .channels = rk3568_saradc_channels,
+    .num_channels = RT_ARRAY_SIZE(rk3568_saradc_channels),
+    .clk_rate = 1000000,
+    .start = rockchip_saradc_start_v1,
+    .read = rockchip_saradc_read_v1,
+    .power_down = rockchip_saradc_power_down_v1,
+};
+
+static const struct saradc_channel rk3588_saradc_channels[] =
+{
+    SARADC_CHANNEL(0, "adc0", 12),
+    SARADC_CHANNEL(1, "adc1", 12),
+    SARADC_CHANNEL(2, "adc2", 12),
+    SARADC_CHANNEL(3, "adc3", 12),
+    SARADC_CHANNEL(4, "adc4", 12),
+    SARADC_CHANNEL(5, "adc5", 12),
+    SARADC_CHANNEL(6, "adc6", 12),
+    SARADC_CHANNEL(7, "adc7", 12),
+};
+
+static const struct rockchip_saradc_soc_data rk3588_saradc_data =
+{
+    .channels = rk3588_saradc_channels,
+    .num_channels = RT_ARRAY_SIZE(rk3588_saradc_channels),
+    .clk_rate = 1000000,
+    .start = rockchip_saradc_start_v2,
+    .read = rockchip_saradc_read_v2,
+};
+
+static void rockchip_saradc_start(struct rockchip_saradc *rk_saradc, int chn)
+{
+    rk_saradc->soc_data->start(rk_saradc, chn);
+}
+
+static int rockchip_saradc_read(struct rockchip_saradc *rk_saradc)
+{
+    return rk_saradc->soc_data->read(rk_saradc);
+}
+
+static void rockchip_saradc_power_down(struct rockchip_saradc *rk_saradc)
+{
+    if (rk_saradc->soc_data->power_down)
+    {
+        rk_saradc->soc_data->power_down(rk_saradc);
+    }
+}
+
+static rt_err_t rockchip_saradc_enabled(struct rt_adc_device *adc, rt_int8_t channel, rt_bool_t enabled)
+{
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_saradc_convert(struct rt_adc_device *adc, rt_int8_t channel, rt_uint32_t *value)
+{
+    rt_err_t err = RT_EOK;
+    struct rockchip_saradc *rk_saradc = raw_to_rockchip_saradc(adc);
+
+    rt_mutex_take(&rk_saradc->lock, RT_WAITING_FOREVER);
+
+    rk_saradc->last_chan = (struct saradc_channel *)&rk_saradc->soc_data->channels[channel];
+    rockchip_saradc_start(rk_saradc, channel);
+
+    /* Select the channel to be used and trigger conversion */
+    HWREG32(rk_saradc->regs + SARADC_CTRL) =SARADC_CTRL_POWER_CTRL |
+            (channel & SARADC_CTRL_CHN_MASK) | SARADC_CTRL_IRQ_ENABLE;
+
+    /* Delay 100ms */
+    if (!(err = rt_completion_wait(&rk_saradc->completion, SARADC_TIMEOUT)))
+    {
+        *value = rk_saradc->last_val;
+    }
+
+    rt_mutex_release(&rk_saradc->lock);
+
+    return err;
+}
+
+static const struct rt_adc_ops rockchip_saradc_ops =
+{
+    .enabled = rockchip_saradc_enabled,
+    .convert = rockchip_saradc_convert,
+};
+
+static void rockchip_saradc_isr(int irqno, void *param)
+{
+    struct rockchip_saradc *rk_saradc = (struct rockchip_saradc *)param;
+
+    /* Read value */
+    rk_saradc->last_val = rockchip_saradc_read(rk_saradc);
+    rk_saradc->last_val &= RT_GENMASK(rk_saradc->last_chan->scan_type.realbits - 1, 0);
+
+    rockchip_saradc_power_down(rk_saradc);
+
+    rt_completion_done(&rk_saradc->completion);
+}
+
+static void rockchip_saradc_reset_controller(struct rockchip_saradc *rk_saradc)
+{
+    rt_reset_control_assert(rk_saradc->rstc);
+    rt_hw_us_delay(15);
+    rt_reset_control_deassert(rk_saradc->rstc);
+}
+
+static void rockchip_saradc_free(struct rockchip_saradc *rk_saradc)
+{
+    if (rk_saradc->regs)
+    {
+        rt_iounmap(rk_saradc->regs);
+    }
+
+    if (!rt_is_err_or_null(rk_saradc->rstc))
+    {
+        rt_reset_control_put(rk_saradc->rstc);
+    }
+
+    if (!rt_is_err_or_null(rk_saradc->vref))
+    {
+        rt_regulator_disable(rk_saradc->vref);
+    }
+
+    if (!rt_is_err_or_null(rk_saradc->clk))
+    {
+        rt_clk_disable(rk_saradc->clk);
+        rt_clk_put(rk_saradc->clk);
+    }
+
+    if (!rt_is_err_or_null(rk_saradc->pclk))
+    {
+        rt_clk_disable(rk_saradc->pclk);
+        rt_clk_put(rk_saradc->pclk);
+    }
+
+    rt_free(rk_saradc);
+}
+
+static rt_err_t rockchip_saradc_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err = RT_EOK;
+    const char *dev_name;
+    struct rt_device *dev = &pdev->parent;
+    const struct rockchip_saradc_soc_data *soc_data = pdev->id->data;
+    struct rockchip_saradc *rk_saradc = rt_calloc(1, sizeof(*rk_saradc));
+
+    if (!rk_saradc)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk_saradc->soc_data = soc_data;
+    rk_saradc->regs = rt_dm_dev_iomap(dev, 0);
+
+    if (!rk_saradc->regs)
+    {
+        err = -RT_EIO;
+        goto _free_res;
+    }
+
+    rk_saradc->irq = rt_dm_dev_get_irq(dev, 0);
+
+    if (rk_saradc->irq < 0)
+    {
+        err = rk_saradc->irq;
+        goto _free_res;
+    }
+
+    rk_saradc->vref = rt_regulator_get(dev, "vref");
+
+    if (rt_is_err(rk_saradc->vref))
+    {
+        err = rt_ptr_err(rk_saradc->vref);
+        goto _free_res;
+    }
+
+    rk_saradc->rstc = rt_reset_control_get_by_name(dev, "saradc-apb");
+
+    if (rt_is_err(rk_saradc->rstc))
+    {
+        err = rt_ptr_err(rk_saradc->rstc);
+        goto _free_res;
+    }
+
+    if (rk_saradc->rstc)
+    {
+        rockchip_saradc_reset_controller(rk_saradc);
+    }
+
+    rk_saradc->pclk = rt_clk_get_by_name(dev, "apb_pclk");
+
+    if (rt_is_err(rk_saradc->pclk))
+    {
+        err = rt_ptr_err(rk_saradc->pclk);
+        goto _free_res;
+    }
+
+    if ((err = rt_clk_enable(rk_saradc->pclk)))
+    {
+        goto _free_res;
+    }
+
+    rk_saradc->clk = rt_clk_get_by_name(dev, "saradc");
+
+    if (rt_is_err(rk_saradc->clk))
+    {
+        err = rt_ptr_err(rk_saradc->clk);
+        goto _free_res;
+    }
+
+    if ((err = rt_clk_enable(rk_saradc->clk)))
+    {
+        goto _free_res;
+    }
+
+    if ((err = rt_clk_set_rate(rk_saradc->clk, soc_data->clk_rate)))
+    {
+        goto _free_res;
+    }
+
+    if ((err = rt_regulator_enable(rk_saradc->vref)))
+    {
+        goto _free_res;
+    }
+
+    dev->user_data = rk_saradc;
+
+    rt_dm_dev_set_name_auto(&rk_saradc->parent.parent, "saradc");
+    dev_name = rt_dm_dev_get_name(&rk_saradc->parent.parent);
+
+    rt_mutex_init(&rk_saradc->lock, dev_name, RT_IPC_FLAG_PRIO);
+    rt_completion_init(&rk_saradc->completion);
+
+    rt_hw_adc_register(&rk_saradc->parent, dev_name, &rockchip_saradc_ops, rk_saradc);
+    rt_hw_interrupt_install(rk_saradc->irq, rockchip_saradc_isr, rk_saradc, dev_name);
+    rt_hw_interrupt_umask(rk_saradc->irq);
+
+    rt_dm_dev_bind_fwdata(dev, RT_NULL, rk_saradc);
+
+    return RT_EOK;
+
+_free_res:
+    rockchip_saradc_free(rk_saradc);
+
+    return err;
+}
+
+static rt_err_t rockchip_saradc_remove(struct rt_platform_device *pdev)
+{
+    struct rt_device *dev = &pdev->parent;
+    struct rockchip_saradc *rk_saradc = dev->user_data;
+
+    rt_dm_dev_unbind_fwdata(dev, RT_NULL);
+
+    rt_hw_interrupt_mask(rk_saradc->irq);
+    rt_pic_detach_irq(rk_saradc->irq, rk_saradc);
+
+    rt_device_unregister(&rk_saradc->parent.parent);
+
+    rockchip_saradc_free(rk_saradc);
+
+    return RT_EOK;
+}
+
+static const struct rt_ofw_node_id rockchip_saradc_ofw_ids[] =
+{
+    { .compatible = "rockchip,saradc", .data = &saradc_data },
+    { .compatible = "rockchip,rk3066-tsadc", .data = &rk3066_tsadc_data },
+    { .compatible = "rockchip,rk3399-saradc", .data = &rk3399_saradc_data },
+    { .compatible = "rockchip,rk3568-saradc", .data = &rk3568_saradc_data },
+    { .compatible = "rockchip,rk3588-saradc", .data = &rk3588_saradc_data, },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_saradc_driver =
+{
+    .name = "rockchip-saradc",
+    .ids = rockchip_saradc_ofw_ids,
+
+    .probe = rockchip_saradc_probe,
+    .remove = rockchip_saradc_remove,
+};
+
+static int rockchip_saradc_register(void)
+{
+    /* If the regulator is a i2c device, saradc should init later */
+    rt_platform_driver_register(&rockchip_saradc_driver);
+
+    return 0;
+}
+INIT_COMPONENT_EXPORT(rockchip_saradc_register);

+ 7 - 0
bsp/rockchip/dm/can/Kconfig

@@ -0,0 +1,7 @@
+config RT_CAN_CANFD_ROCKCHIP
+    bool "Rockchip CANFD controller"
+    depends on RT_CAN_USING_CANFD
+    depends on RT_USING_RESET
+    select RT_USING_DEVICE_IPC
+    select RT_USING_SYSTEM_WORKQUEUE
+    default n

+ 12 - 0
bsp/rockchip/dm/can/SConscript

@@ -0,0 +1,12 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/can']
+
+if GetDepend(['RT_CAN_CANFD_ROCKCHIP']):
+    src += ['canfd-rockchip.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 1061 - 0
bsp/rockchip/dm/can/canfd-rockchip.c

@@ -0,0 +1,1061 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include "can_dm.h"
+
+#define DBG_TAG "canfd.rockchip"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define CAN_MODE            0x00
+#define CAN_CMD             0x04
+#define CAN_STATE           0x08
+#define CAN_INT             0x0c
+#define CAN_INT_MASK        0x10
+#define CAN_LOSTARB_CODE    0x28
+#define CAN_ERR_CODE        0x2c
+#define CAN_RX_ERR_CNT      0x34
+#define CAN_TX_ERR_CNT      0x38
+#define CAN_IDCODE          0x3c
+#define CAN_IDMASK          0x40
+#define CAN_TX_CHECK_FIC    0x50
+#define CAN_NBTP            0x100
+#define CAN_DBTP            0x104
+#define CAN_TDCR            0x108
+#define CAN_TSCC            0x10c
+#define CAN_TSCV            0x110
+#define CAN_TXEFC           0x114
+#define CAN_RXFC            0x118
+#define CAN_AFC             0x11c
+#define CAN_IDCODE0         0x120
+#define CAN_IDMASK0         0x124
+#define CAN_IDCODE1         0x128
+#define CAN_IDMASK1         0x12c
+#define CAN_IDCODE2         0x130
+#define CAN_IDMASK2         0x134
+#define CAN_IDCODE3         0x138
+#define CAN_IDMASK3         0x13c
+#define CAN_IDCODE4         0x140
+#define CAN_IDMASK4         0x144
+#define CAN_TXFIC           0x200
+#define CAN_TXID            0x204
+#define CAN_TXDAT0          0x208
+#define CAN_TXDAT1          0x20c
+#define CAN_TXDAT2          0x210
+#define CAN_TXDAT3          0x214
+#define CAN_TXDAT4          0x218
+#define CAN_TXDAT5          0x21c
+#define CAN_TXDAT6          0x220
+#define CAN_TXDAT7          0x224
+#define CAN_TXDAT8          0x228
+#define CAN_TXDAT9          0x22c
+#define CAN_TXDAT10         0x230
+#define CAN_TXDAT11         0x234
+#define CAN_TXDAT12         0x238
+#define CAN_TXDAT13         0x23c
+#define CAN_TXDAT14         0x240
+#define CAN_TXDAT15         0x244
+#define CAN_RXFIC           0x300
+#define CAN_RXID            0x304
+#define CAN_RXTS            0x308
+#define CAN_RXDAT0          0x30c
+#define CAN_RXDAT1          0x310
+#define CAN_RXDAT2          0x314
+#define CAN_RXDAT3          0x318
+#define CAN_RXDAT4          0x31c
+#define CAN_RXDAT5          0x320
+#define CAN_RXDAT6          0x324
+#define CAN_RXDAT7          0x328
+#define CAN_RXDAT8          0x32c
+#define CAN_RXDAT9          0x330
+#define CAN_RXDAT10         0x334
+#define CAN_RXDAT11         0x338
+#define CAN_RXDAT12         0x33c
+#define CAN_RXDAT13         0x340
+#define CAN_RXDAT14         0x344
+#define CAN_RXDAT15         0x348
+#define CAN_RXFRD           0x400
+#define CAN_TXEFRD          0x500
+
+enum
+{
+    ROCKCHIP_CANFD_MODE = 0,
+    ROCKCHIP_CAN_MODE,
+    ROCKCHIP_RK3568_CAN_MODE,
+    ROCKCHIP_RK3568_CAN_MODE_V2,
+};
+
+#define DATE_LENGTH_12_BYTE     0x9
+#define DATE_LENGTH_16_BYTE     0xa
+#define DATE_LENGTH_20_BYTE     0xb
+#define DATE_LENGTH_24_BYTE     0xc
+#define DATE_LENGTH_32_BYTE     0xd
+#define DATE_LENGTH_48_BYTE     0xe
+#define DATE_LENGTH_64_BYTE     0xf
+
+#define CAN_TX0_REQ             RT_BIT(0)
+#define CAN_TX1_REQ             RT_BIT(1)
+#define CAN_TX_REQ_FULL         ((CAN_TX0_REQ) | (CAN_TX1_REQ))
+
+#define MODE_FDOE               RT_BIT(15)
+#define MODE_BRSD               RT_BIT(13)
+#define MODE_SPACE_RX           RT_BIT(12)
+#define MODE_AUTO_RETX          RT_BIT(10)
+#define MODE_RXSORT             RT_BIT(7)
+#define MODE_TXORDER            RT_BIT(6)
+#define MODE_RXSTX              RT_BIT(5)
+#define MODE_LBACK              RT_BIT(4)
+#define MODE_SILENT             RT_BIT(3)
+#define MODE_SELF_TEST          RT_BIT(2)
+#define MODE_SLEEP              RT_BIT(1)
+#define RESET_MODE              0
+#define WORK_MODE               RT_BIT(0)
+
+#define RX_FINISH_INT           RT_BIT(0)
+#define TX_FINISH_INT           RT_BIT(1)
+#define ERR_WARN_INT            RT_BIT(2)
+#define RX_BUF_OV_INT           RT_BIT(3)
+#define PASSIVE_ERR_INT         RT_BIT(4)
+#define TX_LOSTARB_INT          RT_BIT(5)
+#define BUS_ERR_INT             RT_BIT(6)
+#define RX_FIFO_FULL_INT        RT_BIT(7)
+#define RX_FIFO_OV_INT          RT_BIT(8)
+#define BUS_OFF_INT             RT_BIT(9)
+#define BUS_OFF_RECOVERY_INT    RT_BIT(10)
+#define TSC_OV_INT              RT_BIT(11)
+#define TXE_FIFO_OV_INT         RT_BIT(12)
+#define TXE_FIFO_FULL_INT       RT_BIT(13)
+#define WAKEUP_INT              RT_BIT(14)
+
+#define ERR_TYPE_MASK           RT_GENMASK(28, 26)
+#define ERR_TYPE_SHIFT          26
+#define BIT_ERR                 0
+#define STUFF_ERR               1
+#define FORM_ERR                2
+#define ACK_ERR                 3
+#define CRC_ERR                 4
+#define ERR_DIR_RX              RT_BIT(25)
+#define ERR_LOC_MASK            RT_GENMASK(15, 0)
+
+/* Nominal Bit Timing & Prescaler Register (NBTP) */
+#define NBTP_MODE_3_SAMPLES     RT_BIT(31)
+#define NBTP_NSJW_SHIFT         24
+#define NBTP_NSJW_MASK          (0x7f << NBTP_NSJW_SHIFT)
+#define NBTP_NBRP_SHIFT         16
+#define NBTP_NBRP_MASK          (0xff << NBTP_NBRP_SHIFT)
+#define NBTP_NTSEG2_SHIFT       8
+#define NBTP_NTSEG2_MASK        (0x7f << NBTP_NTSEG2_SHIFT)
+#define NBTP_NTSEG1_SHIFT       0
+#define NBTP_NTSEG1_MASK        (0x7f << NBTP_NTSEG1_SHIFT)
+
+/* Data Bit Timing & Prescaler Register (DBTP) */
+#define DBTP_MODE_3_SAMPLES     RT_BIT(21)
+#define DBTP_DSJW_SHIFT         17
+#define DBTP_DSJW_MASK          (0xf << DBTP_DSJW_SHIFT)
+#define DBTP_DBRP_SHIFT         9
+#define DBTP_DBRP_MASK          (0xff << DBTP_DBRP_SHIFT)
+#define DBTP_DTSEG2_SHIFT       5
+#define DBTP_DTSEG2_MASK        (0xf << DBTP_DTSEG2_SHIFT)
+#define DBTP_DTSEG1_SHIFT       0
+#define DBTP_DTSEG1_MASK        (0x1f << DBTP_DTSEG1_SHIFT)
+
+/* Transmitter Delay Compensation Register (TDCR) */
+#define TDCR_TDCO_SHIFT         1
+#define TDCR_TDCO_MASK          (0x3f << TDCR_TDCO_SHIFT)
+#define TDCR_TDC_ENABLE         RT_BIT(0)
+
+#define TX_FD_ENABLE            RT_BIT(5)
+#define TX_FD_BRS_ENABLE        RT_BIT(4)
+
+#define FIFO_ENABLE             RT_BIT(0)
+#define RX_FIFO_CNT0_SHIFT      4
+#define RX_FIFO_CNT0_MASK       (0x7 << RX_FIFO_CNT0_SHIFT)
+#define RX_FIFO_CNT1_SHIFT      5
+#define RX_FIFO_CNT1_MASK       (0x7 << RX_FIFO_CNT1_SHIFT)
+#define RX_FIFO_COUNT_MAX       (RT_GENMASK(7, 5) >> RX_FIFO_CNT1_SHIFT)
+#define RX_FIFO_ERR_IDX         RX_FIFO_COUNT_MAX
+
+#define FORMAT_SHIFT            7
+#define FORMAT_MASK             (0x1 << FORMAT_SHIFT)
+#define RTR_SHIFT               6
+#define RTR_MASK                (0x1 << RTR_SHIFT)
+#define FDF_SHIFT               5
+#define FDF_MASK                (0x1 << FDF_SHIFT)
+#define BRS_SHIFT               4
+#define BRS_MASK                (0x1 << BRS_SHIFT)
+#define TDC_SHIFT               1
+#define TDC_MASK                (0x3f << TDC_SHIFT)
+#define DLC_SHIFT               0
+#define DLC_MASK                (0xf << DLC_SHIFT)
+
+#define CAN_RF_SIZE             0x48
+#define CAN_TEF_SIZE            0x8
+#define CAN_TXEFRD_OFFSET(n)    (CAN_TXEFRD + CAN_TEF_SIZE * (n))
+#define CAN_RXFRD_OFFSET(n)     (CAN_RXFRD + CAN_RF_SIZE * (n))
+
+#define CAN_RX_FILTER_MASK      0x1fffffff
+#define NOACK_ERR_FLAG          0xc200800
+#define CAN_BUSOFF_FLAG         0x20
+#define NSEC_PER_USEC           1000L
+
+struct rockchip_canfd
+{
+    struct rt_can_device parent;
+
+    int irq;
+    void *regs;
+    rt_ubase_t mode;
+    rt_bool_t txtorx;
+    rt_uint32_t tx_invalid[4];
+    rt_uint32_t rx_fifo_shift;
+    rt_uint32_t rx_fifo_mask;
+    rt_uint32_t delay_time_ms;
+
+    struct rt_can_msg rx_msg[RX_FIFO_COUNT_MAX + 1], tx_msg;
+
+    struct rt_clk_array *clk_arr;
+    struct rt_reset_control *rstc;
+
+    struct rt_work tx_err_work;
+};
+
+#define raw_to_rockchip_canfd(raw) rt_container_of(raw, struct rockchip_canfd, parent)
+
+#define READ_POLL_TIMEOUT_ATOMIC(OP, VAL, COND, DELAY_US,   \
+        TIMEOUT_US, DELAY_BEFORE_READ, ARGS...)             \
+({                                                          \
+    rt_uint64_t timeout_us = (TIMEOUT_US);                  \
+    rt_int64_t left_ns = timeout_us * NSEC_PER_USEC;        \
+    rt_ubase_t delay_us = (DELAY_US);                       \
+    rt_uint64_t delay_ns = delay_us * NSEC_PER_USEC;        \
+    if (DELAY_BEFORE_READ && delay_us)                      \
+    {                                                       \
+        rt_hw_us_delay(delay_us);                           \
+        if (timeout_us)                                     \
+        {                                                   \
+            left_ns -= delay_ns;                            \
+        }                                                   \
+    }                                                       \
+    for (;;)                                                \
+    {                                                       \
+        (VAL) = OP(ARGS);                                   \
+        if (COND)                                           \
+        {                                                   \
+            break;                                          \
+        }                                                   \
+        if (timeout_us && left_ns < 0)                      \
+        {                                                   \
+            (VAL) = OP(ARGS);                               \
+            break;                                          \
+        }                                                   \
+        if (delay_us)                                       \
+        {                                                   \
+            rt_hw_us_delay(delay_us);                       \
+            if (timeout_us)                                 \
+            {                                               \
+                left_ns -= delay_ns;                        \
+            }                                               \
+        }                                                   \
+        rt_hw_cpu_relax();                                  \
+        if (timeout_us)                                     \
+        {                                                   \
+            --left_ns;                                      \
+        }                                                   \
+    }                                                       \
+    (COND) ? 0 : -RT_ETIMEOUT;                              \
+})
+
+static const struct rt_can_bit_timing rockchip_canfd_bittiming_const =
+{
+    .prescaler = 256,
+    .num_seg1 = 128,
+    .num_seg2 = 128,
+    .num_sjw = 128,
+    .num_sspoff = 2,
+};
+
+static const struct rt_can_bit_timing rockchip_canfd_data_bittiming_const =
+{
+    .prescaler = 256,
+    .num_seg1 = 32,
+    .num_seg2 = 16,
+    .num_sjw = 16,
+    .num_sspoff = 2,
+};
+
+rt_inline rt_uint32_t rockchip_canfd_read(struct rockchip_canfd *rk_canfd,
+        int offset)
+{
+    return HWREG32(rk_canfd->regs + offset);
+}
+
+rt_inline void rockchip_canfd_write(struct rockchip_canfd *rk_canfd,
+        int offset, rt_uint32_t val)
+{
+    HWREG32(rk_canfd->regs + offset) = val;
+}
+
+static rt_err_t set_reset_mode(struct rockchip_canfd *rk_canfd)
+{
+    rt_reset_control_assert(rk_canfd->rstc);
+    rt_hw_us_delay(2);
+    rt_reset_control_deassert(rk_canfd->rstc);
+
+    rockchip_canfd_write(rk_canfd, CAN_MODE, 0);
+
+    return RT_EOK;
+}
+
+static rt_err_t set_normal_mode(struct rockchip_canfd *rk_canfd)
+{
+    rt_uint32_t val;
+
+    val = rockchip_canfd_read(rk_canfd, CAN_MODE);
+    val |= WORK_MODE;
+    rockchip_canfd_write(rk_canfd, CAN_MODE, val);
+
+    return RT_EOK;
+}
+
+static int rockchip_canfd_get_rx_fifo_cnt(struct rockchip_canfd *rk_canfd)
+{
+    int quota = 0;
+
+    if (READ_POLL_TIMEOUT_ATOMIC(rockchip_canfd_read, quota,
+            (quota & rk_canfd->rx_fifo_mask) >> rk_canfd->rx_fifo_shift,
+                0, 500000, false, rk_canfd, CAN_RXFC))
+    {
+        LOG_D("%s get fifo cnt failed",
+                rt_dm_dev_get_name(&rk_canfd.parent.parent));
+    }
+
+    quota = (quota & rk_canfd->rx_fifo_mask) >> rk_canfd->rx_fifo_shift;
+
+    return quota;
+}
+
+static void rockchip_canfd_tx_err_delay_work(struct rt_work *work, void *work_data)
+{
+    rt_uint32_t mode, err_code;
+    struct rockchip_canfd *rk_canfd = work_data;
+
+    mode = rockchip_canfd_read(rk_canfd, CAN_MODE);
+    err_code = rockchip_canfd_read(rk_canfd, CAN_ERR_CODE);
+
+    if ((err_code & NOACK_ERR_FLAG) == NOACK_ERR_FLAG)
+    {
+        rockchip_canfd_write(rk_canfd, CAN_MODE,
+                rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_SPACE_RX);
+        rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX0_REQ);
+        rockchip_canfd_write(rk_canfd, CAN_MODE,
+                rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_SPACE_RX));
+
+        rt_work_submit(&rk_canfd->tx_err_work,
+                rt_tick_from_millisecond(rk_canfd->delay_time_ms));
+    }
+    else
+    {
+        rockchip_canfd_write(rk_canfd, CAN_MODE, 0);
+        rockchip_canfd_write(rk_canfd, CAN_MODE, mode);
+        rockchip_canfd_write(rk_canfd, CAN_MODE,
+                rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_SPACE_RX);
+        rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX0_REQ);
+        rockchip_canfd_write(rk_canfd, CAN_MODE,
+                rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_SPACE_RX));
+
+        rt_work_submit(&rk_canfd->tx_err_work,
+                rt_tick_from_millisecond(rk_canfd->delay_time_ms));
+    }
+}
+
+static rt_err_t rockchip_canfd_configure(struct rt_can_device *can,
+        struct can_configure *conf)
+{
+    rt_uint32_t val, reg_btp;
+    rt_uint16_t brp, sjw, tseg1, tseg2;
+    struct rockchip_canfd *rk_canfd = raw_to_rockchip_canfd(can);
+    struct rt_can_bit_timing *bt = &rk_canfd->parent.config.can_timing;
+    struct rt_can_bit_timing *dbt = &rk_canfd->parent.config.canfd_timing;
+
+    set_reset_mode(rk_canfd);
+
+    rockchip_canfd_write(rk_canfd, CAN_INT_MASK, 0);
+
+    /* RECEIVING FILTER, accept all */
+    rockchip_canfd_write(rk_canfd, CAN_IDCODE, 0);
+    rockchip_canfd_write(rk_canfd, CAN_IDMASK, CAN_RX_FILTER_MASK);
+    rockchip_canfd_write(rk_canfd, CAN_IDCODE0, 0);
+    rockchip_canfd_write(rk_canfd, CAN_IDMASK0, CAN_RX_FILTER_MASK);
+    rockchip_canfd_write(rk_canfd, CAN_IDCODE1, 0);
+    rockchip_canfd_write(rk_canfd, CAN_IDMASK1, CAN_RX_FILTER_MASK);
+    rockchip_canfd_write(rk_canfd, CAN_IDCODE2, 0);
+    rockchip_canfd_write(rk_canfd, CAN_IDMASK2, CAN_RX_FILTER_MASK);
+    rockchip_canfd_write(rk_canfd, CAN_IDCODE3, 0);
+    rockchip_canfd_write(rk_canfd, CAN_IDMASK3, CAN_RX_FILTER_MASK);
+    rockchip_canfd_write(rk_canfd, CAN_IDCODE4, 0);
+    rockchip_canfd_write(rk_canfd, CAN_IDMASK4, CAN_RX_FILTER_MASK);
+
+    /* Set mode */
+    val = rockchip_canfd_read(rk_canfd, CAN_MODE);
+
+    /* RX fifo enable */
+    rockchip_canfd_write(rk_canfd, CAN_RXFC,
+            rockchip_canfd_read(rk_canfd, CAN_RXFC) | FIFO_ENABLE);
+
+    val |= MODE_FDOE;
+
+    /* Mode */
+    if (conf->mode & RT_CAN_MODE_LISTEN)
+    {
+        val |= MODE_SILENT;
+    }
+
+    if (conf->mode & RT_CAN_MODE_LOOPBACK)
+    {
+        val |= MODE_SELF_TEST | MODE_LBACK;
+    }
+
+    rockchip_canfd_write(rk_canfd, CAN_MODE, val);
+
+    /* Set bittiming */
+    brp = (bt->prescaler >> 1) - 1;
+    sjw = bt->num_sjw ? bt->num_sjw - 1 : 0;
+    tseg1 = bt->num_seg1;
+    tseg2 = bt->num_seg2;
+    reg_btp = (brp << NBTP_NBRP_SHIFT) | (sjw << NBTP_NSJW_SHIFT) |
+            (tseg1 << NBTP_NTSEG1_SHIFT) | (tseg2 << NBTP_NTSEG2_SHIFT);
+
+    rockchip_canfd_write(rk_canfd, CAN_NBTP, reg_btp);
+
+    if (rk_canfd->parent.config.mode == RT_CAN_MODE_NORMAL)
+    {
+        rt_uint32_t baud_rate_fd = rk_canfd->parent.config.baud_rate_fd;
+
+        brp = (dbt->prescaler >> 1) - 1;
+        sjw = dbt->num_sjw ? dbt->num_sjw - 1 : 0;
+        tseg1 = dbt->num_seg1;
+        tseg2 = dbt->num_seg2;
+
+        if (baud_rate_fd > 2200000)
+        {
+            rt_uint32_t tdco;
+
+            tdco = (rk_canfd->parent.config.baud_rate / baud_rate_fd) * 2 / 3;
+
+            /* Max valid TDCO value is 63 */
+            if (tdco > 63)
+            {
+                tdco = 63;
+            }
+
+            rockchip_canfd_write(rk_canfd, CAN_TDCR,
+                    (tdco << TDC_SHIFT) | TDCR_TDC_ENABLE);
+        }
+
+        reg_btp = (brp << DBTP_DBRP_SHIFT) | (sjw << DBTP_DSJW_SHIFT) |
+                (tseg1 << DBTP_DTSEG1_SHIFT) | (tseg2 << DBTP_DTSEG2_SHIFT);
+
+        rockchip_canfd_write(rk_canfd, CAN_DBTP, reg_btp);
+    }
+
+    if (conf->baud_rate > 200000)
+    {
+        rk_canfd->delay_time_ms = 1;
+    }
+    else if (conf->baud_rate > 50000)
+    {
+        rk_canfd->delay_time_ms = 5;
+    }
+    else
+    {
+        rk_canfd->delay_time_ms = 20;
+    }
+
+    set_normal_mode(rk_canfd);
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_canfd_control(struct rt_can_device *can, int cmd, void *args)
+{
+    struct rt_can_bit_timing_config *timing;
+
+    switch (cmd)
+    {
+    case RT_CAN_CMD_SET_MODE:
+        switch ((rt_base_t)args)
+        {
+        case RT_CAN_MODE_NORMAL:
+        case RT_CAN_MODE_LISTEN:
+        case RT_CAN_MODE_LOOPBACK:
+        case RT_CAN_MODE_LOOPBACKANLISTEN:
+            can->config.mode = (rt_uint32_t)(rt_base_t)args;
+            break;
+
+        default:
+            return -RT_ENOSYS;
+        }
+        break;
+
+    case RT_CAN_CMD_SET_BAUD:
+        can->config.baud_rate = (rt_uint32_t)(rt_base_t)args;
+        break;
+
+    case RT_CAN_CMD_GET_STATUS:
+        rt_memcpy(args, &can->status, sizeof(can->status));
+        return RT_EOK;
+
+    case RT_CAN_CMD_SET_CANFD:
+        can->config.enable_canfd = (rt_ubase_t)args;
+        break;
+
+    case RT_CAN_CMD_SET_BAUD_FD:
+        can->config.baud_rate_fd = (rt_ubase_t)args;
+        break;
+
+    case RT_CAN_CMD_SET_BITTIMING:
+        timing = args;
+
+        if (!timing || timing->count < 1 || timing->count > 2)
+        {
+            return -RT_EINVAL;
+        }
+
+        if (timing->count)
+        {
+            rt_memcpy(&can->config.can_timing, &timing->items[0],
+                    sizeof(&timing->items[0]));
+        }
+
+        if (timing->count == 2)
+        {
+            rt_memcpy(&can->config.canfd_timing, &timing->items[1],
+                    sizeof(&timing->items[1]));
+        }
+        break;
+
+    default:
+        return -RT_ENOSYS;
+    }
+
+    if (can->config.enable_canfd)
+    {
+        rockchip_canfd_configure(can, &can->config);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_canfd_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
+{
+    rt_uint32_t id, dlc, cmd;
+    struct rt_can_msg *tx_msg;
+    struct rockchip_canfd *rk_canfd = raw_to_rockchip_canfd(can);
+
+    tx_msg = &rk_canfd->tx_msg;
+    rt_memcpy(tx_msg, buf, sizeof(*tx_msg));
+
+    if (rockchip_canfd_read(rk_canfd, CAN_CMD) & CAN_TX0_REQ)
+    {
+        cmd = CAN_TX1_REQ;
+    }
+    else
+    {
+        cmd = CAN_TX0_REQ;
+    }
+
+    if (tx_msg->id & CAN_EFF_FLAG)
+    {
+        /* Extended CAN ID format */
+        id = tx_msg->id & CAN_EFF_MASK;
+        dlc = (can_len2dlc(tx_msg->len) & DLC_MASK) | FORMAT_MASK;
+    }
+    else
+    {
+        /* Standard CAN ID format */
+        id = tx_msg->id & CAN_SFF_MASK;
+        dlc = can_len2dlc(tx_msg->len) & DLC_MASK;
+    }
+
+    if (tx_msg->id & CAN_RTR_FLAG)
+    {
+        dlc |= RTR_MASK;
+    }
+
+    if (can->config.mode == RT_CAN_MODE_NORMAL && tx_msg->len <= CANFD_MAX_DLEN)
+    {
+        dlc |= TX_FD_ENABLE;
+    }
+
+    if (tx_msg->ide)
+    {
+        dlc |= FORMAT_MASK;
+    }
+
+    if (tx_msg->rtr)
+    {
+        dlc |= RTR_MASK;
+    }
+
+    if (rk_canfd->txtorx && rk_canfd->mode <= ROCKCHIP_RK3568_CAN_MODE &&
+        tx_msg->id & CAN_EFF_FLAG)
+    {
+        rockchip_canfd_write(rk_canfd, CAN_MODE,
+                rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_RXSTX);
+    }
+    else
+    {
+        rockchip_canfd_write(rk_canfd, CAN_MODE,
+                rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_RXSTX));
+    }
+
+    if (!rk_canfd->txtorx && rk_canfd->mode <= ROCKCHIP_RK3568_CAN_MODE &&
+        tx_msg->id & CAN_EFF_FLAG)
+    {
+        /*
+         * Two frames are sent consecutively.
+         * Before the first frame is tx finished,
+         * the register of the second frame is configured.
+         * Don't be interrupted in the middle.
+         */
+        rt_ubase_t level;
+        static struct rt_spinlock pe_lock = {};
+
+        level = rt_spin_lock_irqsave(&pe_lock);
+
+        rockchip_canfd_write(rk_canfd, CAN_TXID, rk_canfd->tx_invalid[1]);
+        rockchip_canfd_write(rk_canfd, CAN_TXFIC, rk_canfd->tx_invalid[0]);
+        rockchip_canfd_write(rk_canfd, CAN_TXDAT0, rk_canfd->tx_invalid[2]);
+        rockchip_canfd_write(rk_canfd, CAN_TXDAT1, rk_canfd->tx_invalid[3]);
+        rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX0_REQ);
+        rockchip_canfd_write(rk_canfd, CAN_TXID, id);
+        rockchip_canfd_write(rk_canfd, CAN_TXFIC, dlc);
+
+        for (int i = 0; i < tx_msg->len; i += 4)
+        {
+            rockchip_canfd_write(rk_canfd, CAN_TXDAT0 + i,
+                    *(rt_uint32_t *)(tx_msg->data + i));
+        }
+
+        rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX1_REQ);
+
+        rt_spin_unlock_irqrestore(&pe_lock, level);
+
+        return RT_EOK;
+    }
+
+    rockchip_canfd_write(rk_canfd, CAN_TXID, id);
+    rockchip_canfd_write(rk_canfd, CAN_TXFIC, dlc);
+
+    for (int i = 0; i < tx_msg->len; i += 4)
+    {
+        rockchip_canfd_write(rk_canfd, CAN_TXDAT0 + i,
+                *(rt_uint32_t *)(tx_msg->data + i));
+    }
+
+    rockchip_canfd_write(rk_canfd, CAN_MODE,
+            rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_SPACE_RX);
+    rockchip_canfd_write(rk_canfd, CAN_CMD, cmd);
+    rockchip_canfd_write(rk_canfd, CAN_MODE,
+            rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_SPACE_RX));
+
+    rt_work_submit(&rk_canfd->tx_err_work,
+            rt_tick_from_millisecond(rk_canfd->delay_time_ms));
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_canfd_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
+{
+    struct rockchip_canfd *rk_canfd = raw_to_rockchip_canfd(can);
+
+    rt_memcpy(buf, &rk_canfd->rx_msg[boxno], sizeof(rk_canfd->rx_msg[boxno]));
+
+    return RT_EOK;
+}
+
+static const struct rt_can_ops rockchip_canfd_ops =
+{
+    .configure = rockchip_canfd_configure,
+    .control = rockchip_canfd_control,
+    .sendmsg = rockchip_canfd_sendmsg,
+    .recvmsg = rockchip_canfd_recvmsg,
+};
+
+static rt_uint32_t rockchip_canfd_rx(struct rockchip_canfd *rk_canfd, int boxno)
+{
+    struct rt_can_msg *rx_msg = &rk_canfd->rx_msg[boxno];
+    rt_uint32_t id_rockchip_canfd, dlc, tx_id, ts, data[16] = { 0 };
+
+    dlc = rockchip_canfd_read(rk_canfd, CAN_RXFRD);
+    id_rockchip_canfd = rockchip_canfd_read(rk_canfd, CAN_RXFRD);
+    ts = rockchip_canfd_read(rk_canfd, CAN_RXFRD);
+
+    for (int i = 0; i < RT_ARRAY_SIZE(data); ++i)
+    {
+        data[i] = rockchip_canfd_read(rk_canfd, CAN_RXFRD);
+    }
+
+    if (rk_canfd->mode >= ROCKCHIP_CAN_MODE)
+    {
+        if (!dlc && !id_rockchip_canfd)
+        {
+            return 1;
+        }
+
+        if (rk_canfd->txtorx)
+        {
+            if (rockchip_canfd_read(rk_canfd, CAN_TX_CHECK_FIC) & FORMAT_MASK)
+            {
+                tx_id = rockchip_canfd_read(rk_canfd, CAN_TXID) & CAN_SFF_MASK;
+
+                if (id_rockchip_canfd == tx_id && !(dlc & FORMAT_MASK))
+                {
+                    rockchip_canfd_write(rk_canfd, CAN_TX_CHECK_FIC,
+                            ts | CAN_TX0_REQ);
+
+                    return 1;
+                }
+            }
+        }
+    }
+
+    if (dlc & FDF_MASK)
+    {
+        rx_msg->len = can_dlc2len(dlc & DLC_MASK);
+    }
+    else
+    {
+        rx_msg->len = can_get_dlc(dlc & DLC_MASK);
+    }
+
+    rx_msg->id = id_rockchip_canfd;
+
+    if (dlc & FORMAT_MASK)
+    {
+        rx_msg->id |= CAN_EFF_FLAG;
+    }
+
+    if (dlc & RTR_MASK)
+    {
+        rx_msg->id |= CAN_RTR_FLAG;
+    }
+
+    rx_msg->ide = (dlc & FORMAT_MASK) >> FORMAT_SHIFT;
+    rx_msg->rtr = (dlc & RTR_MASK) >> RTR_SHIFT;
+
+    if (!(rx_msg->id & CAN_RTR_FLAG))
+    {
+        for (int i = 0; i < rx_msg->len; i += 4)
+        {
+            *(rt_uint32_t *)(rx_msg->data + i) = data[i / 4];
+        }
+    }
+
+    return 1;
+}
+
+static rt_err_t rockchip_canfd_err(struct rockchip_canfd *rk_canfd, rt_uint8_t ints)
+{
+    rt_uint32_t sta_reg;
+    struct rt_can_device *can = &rk_canfd->parent;
+
+    can->status.rcverrcnt = rockchip_canfd_read(rk_canfd, CAN_RX_ERR_CNT);
+    can->status.snderrcnt = rockchip_canfd_read(rk_canfd, CAN_TX_ERR_CNT);
+    sta_reg = rockchip_canfd_read(rk_canfd, CAN_STATE);
+
+    if (ints & BUS_OFF_INT)
+    {
+        can->status.errcode = BUSOFF;
+    }
+    else if (ints & ERR_WARN_INT)
+    {
+        can->status.errcode = ERRWARNING;
+    }
+    else if (ints & PASSIVE_ERR_INT)
+    {
+        can->status.errcode = ERRPASSIVE;
+    }
+
+    if (can->status.errcode >= BUSOFF ||
+        (sta_reg & CAN_BUSOFF_FLAG) == CAN_BUSOFF_FLAG)
+    {
+        rt_work_cancel(&rk_canfd->tx_err_work);
+
+        /* Stop */
+        set_reset_mode(rk_canfd);
+        /* Disable all interrupts */
+        rockchip_canfd_write(rk_canfd, CAN_INT_MASK, 0xffff);
+
+        /* Start */
+        rockchip_canfd_configure(&rk_canfd->parent, &can->config);
+    }
+
+    return RT_EOK;
+}
+
+static void rockchip_canfd_isr(int irqno, void *param)
+{
+    rt_uint32_t ints, dlc, quota, work_done = 0;
+    struct rockchip_canfd *rk_canfd = param;
+    const rt_uint32_t err_ints = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT |
+            TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT;
+
+    ints = rockchip_canfd_read(rk_canfd, CAN_INT);
+
+    if (ints & TX_FINISH_INT)
+    {
+        rt_work_cancel(&rk_canfd->tx_err_work);
+        dlc = rockchip_canfd_read(rk_canfd, CAN_TXFIC);
+
+        if (rk_canfd->txtorx && rk_canfd->mode <= ROCKCHIP_RK3568_CAN_MODE &&
+            dlc & FORMAT_MASK)
+        {
+            rockchip_canfd_write(rk_canfd, CAN_TX_CHECK_FIC, FORMAT_MASK);
+            quota = rockchip_canfd_get_rx_fifo_cnt(rk_canfd);
+
+            for (int boxno = 0; work_done < quota; ++boxno)
+            {
+                work_done += rockchip_canfd_rx(rk_canfd, boxno);
+                rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_TX_DONE | (boxno << 8));
+            }
+
+            if (rockchip_canfd_read(rk_canfd, CAN_TX_CHECK_FIC) & CAN_TX0_REQ)
+            {
+                rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX1_REQ);
+            }
+            rockchip_canfd_write(rk_canfd, CAN_TX_CHECK_FIC, 0);
+        }
+        else
+        {
+            rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_TX_DONE);
+        }
+
+        if (READ_POLL_TIMEOUT_ATOMIC(rockchip_canfd_read, quota,
+                !(quota & 0x3), 0, 5000000, false, rk_canfd, CAN_CMD))
+        {
+            LOG_E("%s: Wait tx req timeout",
+                    rt_dm_dev_get_name(&rk_canfd->parent.parent));
+        }
+
+        rockchip_canfd_write(rk_canfd, CAN_CMD, 0);
+    }
+
+    if (ints & RX_FINISH_INT)
+    {
+        if (rk_canfd->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
+        {
+            rockchip_canfd_write(rk_canfd, CAN_INT_MASK, 0x1);
+        }
+        else
+        {
+            work_done = 0;
+            quota = (rockchip_canfd_read(rk_canfd, CAN_RXFC) &
+                    rk_canfd->rx_fifo_mask) >> rk_canfd->rx_fifo_shift;
+
+            for (int boxno = 0; work_done < quota; ++boxno)
+            {
+                work_done += rockchip_canfd_rx(rk_canfd, boxno);
+                rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_RX_IND | (boxno << 8));
+            }
+        }
+
+    }
+
+    if (ints & (RX_FIFO_FULL_INT | RX_FIFO_OV_INT))
+    {
+        rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_RXOF_IND);
+        rockchip_canfd_rx(rk_canfd, RX_FIFO_ERR_IDX);
+    }
+
+    if (ints & err_ints)
+    {
+        rockchip_canfd_err(rk_canfd, ints);
+        rockchip_canfd_rx(rk_canfd, RX_FIFO_ERR_IDX);
+    }
+
+    rockchip_canfd_write(rk_canfd, CAN_INT, ints);
+}
+
+static void rockchip_canfd_free(struct rockchip_canfd *rk_canfd)
+{
+    if (rk_canfd->regs)
+    {
+        rt_iounmap(rk_canfd->regs);
+    }
+
+    if (!rt_is_err_or_null(rk_canfd->clk_arr))
+    {
+        rt_clk_array_put(rk_canfd->clk_arr);
+    }
+
+    if (!rt_is_err_or_null(rk_canfd->rstc))
+    {
+        rt_reset_control_put(rk_canfd->rstc);
+    }
+
+    rt_free(rk_canfd);
+}
+
+static rt_err_t rockchip_canfd_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    const char *dev_name;
+    struct rt_can_device *can;
+    struct can_configure *conf;
+    struct rt_device *dev = &pdev->parent;
+    struct rockchip_canfd *rk_canfd = rt_calloc(1, sizeof(*rk_canfd));
+
+    if (!rk_canfd)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk_canfd->mode = (rt_ubase_t)pdev->id->data;
+    rk_canfd->regs = rt_dm_dev_iomap(dev, 0);
+
+    if (!rk_canfd->regs)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    rk_canfd->irq = rt_dm_dev_get_irq(dev, 0);
+
+    if (rk_canfd->irq < 0)
+    {
+        err = rk_canfd->irq;
+        goto _fail;
+    }
+
+    rk_canfd->clk_arr = rt_clk_get_array(dev);
+
+    if (rt_is_err(rk_canfd->clk_arr))
+    {
+        err = rt_ptr_err(rk_canfd->clk_arr);
+        goto _fail;
+    }
+
+    rk_canfd->rstc = rt_reset_control_get_array(dev);
+
+    if (rt_is_err(rk_canfd->rstc))
+    {
+        err = rt_ptr_err(rk_canfd->rstc);
+        goto _fail;
+    }
+
+#ifdef RT_USING_OFW
+    /* RockChip CPU version = 3 */
+    if ((rt_ofw_machine_is_compatible("rockchip,rk3566") ||
+        rt_ofw_machine_is_compatible("rockchip,rk3568")))
+    {
+        rk_canfd->mode = ROCKCHIP_RK3568_CAN_MODE_V2;
+    }
+#endif
+
+    can = &rk_canfd->parent;
+    conf = &can->config;
+
+    conf->baud_rate = rt_clk_get_rate(rk_canfd->clk_arr->clks[0]);
+    conf->msgboxsz = 1;
+    conf->sndboxnumber = 1;
+    conf->mode = RT_CAN_MODE_NORMAL;
+    conf->ticks = 50;
+#ifdef RT_CAN_USING_HDR
+    conf->maxhdr = 4;
+#endif
+    conf->use_bit_timing = 1;
+    rt_memcpy(&conf->can_timing, &rockchip_canfd_bittiming_const, sizeof(conf->can_timing));
+
+    if (rk_canfd->mode == ROCKCHIP_CAN_MODE)
+    {
+        rk_canfd->rx_fifo_shift = RX_FIFO_CNT1_SHIFT;
+        rk_canfd->rx_fifo_mask = RX_FIFO_CNT1_MASK;
+    }
+    else
+    {
+        if (rk_canfd->mode == ROCKCHIP_CANFD_MODE)
+        {
+            rt_memcpy(&conf->canfd_timing, &rockchip_canfd_data_bittiming_const,
+                    sizeof(conf->canfd_timing));
+        }
+
+        rk_canfd->rx_fifo_shift = RX_FIFO_CNT0_SHIFT;
+        rk_canfd->rx_fifo_mask = RX_FIFO_CNT0_MASK;
+    }
+
+    if (rt_dm_dev_prop_read_u32_array_index(dev, "rockchip,tx-invalid-info",
+            0, 4, rk_canfd->tx_invalid) < 0)
+    {
+        rk_canfd->txtorx = RT_TRUE;
+    }
+
+    if (rk_canfd->mode == ROCKCHIP_RK3568_CAN_MODE_V2)
+    {
+        rk_canfd->txtorx = RT_FALSE;
+    }
+
+    dev->user_data = rk_canfd;
+
+    rt_work_init(&rk_canfd->tx_err_work, rockchip_canfd_tx_err_delay_work, rk_canfd);
+
+    rt_dm_dev_set_name_auto(&can->parent, "can");
+    dev_name = rt_dm_dev_get_name(&can->parent);
+
+    rt_hw_interrupt_install(rk_canfd->irq, rockchip_canfd_isr, rk_canfd, dev_name);
+    rt_hw_interrupt_umask(rk_canfd->irq);
+
+    if ((err = rt_hw_can_register(can, dev_name, &rockchip_canfd_ops, rk_canfd)))
+    {
+        goto _fail;
+    }
+
+    return RT_EOK;
+
+_fail:
+    rockchip_canfd_free(rk_canfd);
+
+    return err;
+}
+
+static rt_err_t rockchip_canfd_remove(struct rt_platform_device *pdev)
+{
+    struct rockchip_canfd *rk_canfd = pdev->parent.user_data;
+
+    rt_hw_interrupt_mask(rk_canfd->irq);
+    rt_pic_detach_irq(rk_canfd->irq, rk_canfd);
+
+    rt_device_unregister(&rk_canfd->parent.parent);
+
+    rockchip_canfd_free(rk_canfd);
+
+    return RT_EOK;
+}
+
+static const struct rt_ofw_node_id rockchip_canfd_ofw_ids[] =
+{
+    { .compatible = "rockchip,canfd-1.0", .data = (void *)ROCKCHIP_CANFD_MODE },
+    { .compatible = "rockchip,can-2.0", .data = (void *)ROCKCHIP_CAN_MODE },
+    { .compatible = "rockchip,rk3568-can-2.0", .data = (void *)ROCKCHIP_RK3568_CAN_MODE },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_canfd_driver =
+{
+    .name = "canfd-rockchip",
+    .ids = rockchip_canfd_ofw_ids,
+
+    .probe = rockchip_canfd_probe,
+    .remove = rockchip_canfd_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rockchip_canfd_driver);

+ 36 - 0
bsp/rockchip/dm/clk/Kconfig

@@ -0,0 +1,36 @@
+menuconfig RT_CLK_ROCKCHIP_RK8XX_CLKOUT
+    bool "Clock driver for RK805/RK808/RK809/RK817/RK818"
+    depends on RT_MFD_RK8XX
+    depends on RT_USING_OFW
+    default n
+
+menuconfig RT_CLK_ROCKCHIP_LINK
+    bool "Rockchip link clock controller"
+    depends on RT_USING_OFW
+    default y
+
+menuconfig RT_CLK_ROCKCHIP
+    bool "Rockchip clock controller common"
+    depends on RT_USING_OFW
+    depends on RT_USING_RESET
+    default y
+
+config RT_CLK_ROCKCHIP_RK3308
+    bool "Rockchip RK3308 clock controller support"
+    depends on RT_CLK_ROCKCHIP
+    default n
+
+config RT_CLK_ROCKCHIP_RK3568
+    bool "Rockchip RK3568 clock controller support"
+    depends on RT_CLK_ROCKCHIP
+    default n
+
+config RT_CLK_ROCKCHIP_RK3576
+    bool "Rockchip RK3576 clock controller support"
+    depends on RT_CLK_ROCKCHIP
+    default n
+
+config RT_CLK_ROCKCHIP_RK3588
+    bool "Rockchip RK3588 clock controller support"
+    depends on RT_CLK_ROCKCHIP
+    default n

+ 33 - 0
bsp/rockchip/dm/clk/SConscript

@@ -0,0 +1,33 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include']
+
+if GetDepend(['RT_CLK_ROCKCHIP_LINK']):
+    src += ['clk-link.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK8XX_CLKOUT']):
+    src += ['clk-rk8xx-clkout.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP']):
+    src += ['clk-rk-cpu.c', 'clk-rk-composite.c', 'clk-rk-divider.c', 'clk-rk-factor.c',
+            'clk-rk-fraction-divider.c', 'clk-rk-gate.c', 'clk-rk-mmc-phase.c',
+            'clk-rk-mux.c', 'clk-rk-muxgrf.c', 'clk-rk-pll.c', 'clk-rk-half-divider.c',
+            'clk-rk.c', 'softrst.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK3308']):
+    src += ['clk-rk3308.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK3568']):
+    src += ['clk-rk3568.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK3576']):
+    src += ['clk-rk3576.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK3588']):
+    src += ['clk-rk3588.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 210 - 0
bsp/rockchip/dm/clk/clk-link.c

@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "clk.link"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+struct rockchip_link_data
+{
+    rt_size_t cells_nr;
+    struct rt_clk_cell **cells;
+};
+
+struct rockchip_link_cell
+{
+    struct rt_clk_cell cell;
+    rt_uint32_t bit_idx;
+};
+
+#define cell_to_rockchip_link_cell(cell) rt_container_of(cell, struct rockchip_link_cell, cell)
+
+struct rockchip_link_clk
+{
+    struct rt_clk_node parent;
+
+    void *base;
+};
+
+#define raw_to_rockchip_link_clk(raw) rt_container_of(raw, struct rockchip_link_clk, parent)
+
+static void clk_gate_endisable(struct rt_clk_cell *cell, int enable)
+{
+    rt_uint32_t reg;
+    int set = 1 ^ enable;
+    struct rockchip_link_cell *link_cell = cell_to_rockchip_link_cell(cell);
+    struct rockchip_link_clk *link_clk = raw_to_rockchip_link_clk(cell->clk_np);
+
+    reg = RT_BIT(link_cell->bit_idx + 16);
+
+    if (set)
+    {
+        reg |= RT_BIT(link_cell->bit_idx);
+    }
+
+    HWREG32(link_clk->base) = reg;
+}
+
+static rt_err_t rockchip_link_clk_enable(struct rt_clk_cell *cell)
+{
+    clk_gate_endisable(cell, 1);
+
+    return RT_EOK;
+}
+
+static void rockchip_link_clk_disable(struct rt_clk_cell *cell)
+{
+    clk_gate_endisable(cell, 0);
+}
+
+static rt_bool_t rockchip_link_clk_is_enabled(struct rt_clk_cell *cell)
+{
+    rt_uint32_t reg;
+    struct rockchip_link_cell *link_cell = cell_to_rockchip_link_cell(cell);
+    struct rockchip_link_clk *link_clk = raw_to_rockchip_link_clk(cell->clk_np);
+
+    reg = HWREG32(link_clk->base);
+    reg ^= RT_BIT(link_cell->bit_idx);
+    reg &= RT_BIT(link_cell->bit_idx);
+
+    return !!reg;
+}
+
+const struct rt_clk_ops clk_gate_ops =
+{
+    .enable = rockchip_link_clk_enable,
+    .disable = rockchip_link_clk_disable,
+    .is_enabled = rockchip_link_clk_is_enabled,
+};
+
+#define GATE_LINK(_name, _pname, _bit_idx)  \
+(void *)&(struct rockchip_link_cell)        \
+{                                           \
+    .cell.name = _name,                     \
+    .cell.parents_nr = 1,                   \
+    .cell.parent_name = _pname,             \
+    .cell.ops = &clk_gate_ops,              \
+    .cell.flags = RT_CLK_F_SET_RATE_PARENT, \
+    .bit_idx = _bit_idx,                    \
+}
+
+static struct rt_clk_cell *rk3562_clk_cells[] =
+{
+    GATE_LINK("aclk_rga_jdec", "aclk_rga_pre", 3),
+    GATE_LINK("aclk_vdpu", "aclk_vdpu_pre", 5),
+    GATE_LINK("aclk_vepu", "aclk_vepu_pre", 3),
+    GATE_LINK("aclk_vi_isp", "aclk_vi", 3),
+    GATE_LINK("aclk_vo", "aclk_vo_pre", 3),
+    GATE_LINK("hclk_vepu", "hclk_vepu_pre", 4),
+};
+
+static const struct rockchip_link_data rk3562_clk_data =
+{
+    .cells = rk3562_clk_cells,
+    .cells_nr = RT_ARRAY_SIZE(rk3562_clk_cells),
+};
+
+static struct rt_clk_cell *rk3588_clk_cells[] =
+{
+    GATE_LINK("aclk_isp1_pre", "aclk_isp1_root", 6),
+    GATE_LINK("hclk_isp1_pre", "hclk_isp1_root", 8),
+    GATE_LINK("hclk_nvm", "hclk_nvm_root", 2),
+    GATE_LINK("aclk_usb", "aclk_usb_root", 2),
+    GATE_LINK("hclk_usb", "hclk_usb_root", 3),
+    GATE_LINK("aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", 7),
+    GATE_LINK("aclk_vdpu_low_pre", "aclk_vdpu_low_root", 5),
+    GATE_LINK("aclk_rkvenc1_pre", "aclk_rkvenc1_root", 3),
+    GATE_LINK("hclk_rkvenc1_pre", "hclk_rkvenc1_root", 2),
+    GATE_LINK("hclk_rkvdec0_pre", "hclk_rkvdec0_root", 5),
+    GATE_LINK("aclk_rkvdec0_pre", "aclk_rkvdec0_root", 6),
+    GATE_LINK("hclk_rkvdec1_pre", "hclk_rkvdec1_root", 4),
+    GATE_LINK("aclk_rkvdec1_pre", "aclk_rkvdec1_root", 5),
+    GATE_LINK("aclk_hdcp0_pre", "aclk_vo0_root", 9),
+    GATE_LINK("hclk_vo0", "hclk_vo0_root", 5),
+    GATE_LINK("aclk_hdcp1_pre", "aclk_hdcp1_root", 6),
+    GATE_LINK("hclk_vo1", "hclk_vo1_root", 9),
+    GATE_LINK("aclk_av1_pre", "aclk_av1_root", 1),
+    GATE_LINK("pclk_av1_pre", "pclk_av1_root", 4),
+    GATE_LINK("hclk_sdio_pre", "hclk_sdio_root", 1),
+    GATE_LINK("pclk_vo0_grf", "pclk_vo0_root", 10),
+    GATE_LINK("pclk_vo1_grf", "pclk_vo1_root", 12),
+};
+
+static const struct rockchip_link_data rk3588_clk_data =
+{
+    .cells = rk3588_clk_cells,
+    .cells_nr = RT_ARRAY_SIZE(rk3588_clk_cells),
+};
+
+static rt_err_t rockchip_clk_link_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_device *dev = &pdev->parent;
+    const struct rockchip_link_data *clk_data = pdev->id->data;
+    struct rockchip_link_clk *link_clk = rt_calloc(1, sizeof(*link_clk));
+
+    if (!link_clk)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if (!(link_clk->base = rt_dm_dev_iomap(dev, 0)))
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    link_clk->parent.dev = dev;
+    link_clk->parent.cells = clk_data->cells;
+    link_clk->parent.cells_nr = clk_data->cells_nr;
+
+    if ((err = rt_clk_register(&link_clk->parent)))
+    {
+        goto _fail;
+    }
+
+    return RT_EOK;
+
+_fail:
+    if (link_clk->base)
+    {
+        rt_iounmap(link_clk->base);
+    }
+
+    rt_free(link_clk);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id rockchip_clk_link_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3562-clock-gate-link", .data = &rk3562_clk_data },
+    { .compatible = "rockchip,rk3588-clock-gate-link", .data = &rk3588_clk_data },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_clk_link_driver =
+{
+    .name = "clk-link",
+    .ids = rockchip_clk_link_ofw_ids,
+
+    .probe = rockchip_clk_link_probe,
+};
+
+static int rockchip_clk_link_register(void)
+{
+    rt_platform_driver_register(&rockchip_clk_link_driver);
+
+    return 0;
+}
+INIT_SUBSYS_EXPORT(rockchip_clk_link_register);

+ 51 - 0
bsp/rockchip/dm/clk/clk-rk-composite.c

@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-composite.h"
+#include "clk-rk-divider.h"
+#include "clk-rk-gate.h"
+#include "clk-rk-mux.h"
+
+void rockchip_composite_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+	struct rockchip_composite_clk_cell *composite_cell = cell_to_rockchip_composite_cell(&rk_cell->cell);
+
+    rk_cell->cell.ops = &composite_cell->ops;
+
+	if (rk_cell->cell.parents_nr > 1)
+	{
+		rockchip_mux_clk_cell_init(rk_cell);
+
+        composite_cell->ops.get_parent = rockchip_mux_clk_ops.get_parent;
+
+        if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY)))
+        {
+            composite_cell->ops.set_parent = rockchip_mux_clk_ops.set_parent;
+        }
+	}
+
+    if (rk_cell->gate_offset >= 0)
+    {
+        composite_cell->ops.enable = rockchip_gate_clk_ops.enable;
+        composite_cell->ops.disable = rockchip_gate_clk_ops.disable;
+        composite_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled;
+    }
+
+    if (rk_cell->div_width > 0)
+    {
+        composite_cell->ops.recalc_rate = clk_divider_ops.recalc_rate;
+        composite_cell->ops.round_rate = clk_divider_ops.round_rate;
+
+        if (!((rk_cell->div_flags & CLK_DIVIDER_READ_ONLY)))
+        {
+            composite_cell->ops.set_rate = clk_divider_ops.set_rate;
+        }
+    }
+}

+ 191 - 0
bsp/rockchip/dm/clk/clk-rk-composite.h

@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_COMPOSITE_H__
+#define __CLK_RK_COMPOSITE_H__
+
+#include "clk-rk.h"
+
+struct rockchip_composite_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+
+    struct rt_clk_ops ops;
+};
+
+#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_MUXTBL(_id, cname, pnames, f, mo, ms, mw, mf, mt, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.mux_table = mt,                            \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, mf, do, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_offset = do,                           \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_name = pname,                  \
+    .rk_cell.cell.parents_nr = 1,                       \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw, df, dt, go, gs, gf) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_name = pname,                  \
+    .rk_cell.cell.parents_nr = 1,                       \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.div_table = dt,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, go, gs, gf) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = -1,                          \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df, dt) \
+(void *)&(struct rockchip_composite_clk_cell)           \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.div_table = dt,                            \
+    .rk_cell.gate_offset = -1,                          \
+    .rk_cell.init = rockchip_composite_clk_cell_init,   \
+}
+
+rt_inline struct rockchip_composite_clk_cell *cell_to_rockchip_composite_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_composite_clk_cell, rk_cell);
+}
+
+void rockchip_composite_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_COMPOSITE_H__ */

+ 278 - 0
bsp/rockchip/dm/clk/clk-rk-cpu.c

@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-cpu.h"
+
+static rt_ubase_t rockchip_cpu_clk_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
+{
+    void *base;
+    rt_uint32_t clksel0;
+    struct rockchip_cpu_clk_cell *cpu_clk_cell = cell_to_rockchip_cpu_cell(cell);
+    const struct rockchip_cpu_clk_reg_data *reg_data = cpu_clk_cell->reg_data;
+
+    base = cpu_clk_cell->rk_cell.provider->reg_base;
+
+    clksel0 = HWREG32(base + reg_data->core_reg[0]);
+    clksel0 >>= reg_data->div_core_shift[0];
+    clksel0 &= reg_data->div_core_mask[0];
+
+    return parent_rate / (clksel0 + 1);
+}
+
+const struct rt_clk_ops rockchip_cpu_clk_ops =
+{
+    .recalc_rate = rockchip_cpu_clk_recalc_rate,
+};
+
+static const struct rockchip_cpu_clk_rate_table *rockchip_get_cpu_clk_settings(
+        struct rockchip_cpu_clk_cell *cpu_clk_cell, rt_ubase_t rate)
+{
+    const struct rockchip_cpu_clk_rate_table *rate_table = cpu_clk_cell->rate_table;
+
+    for (int i = 0; i < cpu_clk_cell->rate_count; ++i)
+    {
+        if (rate == rate_table[i].prate)
+        {
+            return &rate_table[i];
+        }
+    }
+
+    return RT_NULL;
+}
+
+static void rockchip_cpu_clk_set_dividers(struct rockchip_cpu_clk_cell *cpu_clk_cell,
+    const struct rockchip_cpu_clk_rate_table *rate)
+{
+    void *base = cpu_clk_cell->rk_cell.provider->reg_base;
+
+    /* Alternate parent is active now. set the dividers */
+    for (int i = 0; i < RT_ARRAY_SIZE(rate->divs); ++i)
+    {
+        const struct rockchip_cpu_clk_clksel *clksel = &rate->divs[i];
+
+        if (!clksel->reg)
+        {
+            continue;
+        }
+
+        HWREG32(base + clksel->reg) = clksel->val;
+    }
+}
+
+static void rockchip_cpu_clk_set_pre_muxs(struct rockchip_cpu_clk_cell *cpu_clk_cell,
+        const struct rockchip_cpu_clk_rate_table *rate)
+{
+    void *base = cpu_clk_cell->rk_cell.provider->reg_base;
+
+    /* Alternate parent is active now. set the pre_muxs */
+    for (int i = 0; i < RT_ARRAY_SIZE(rate->pre_muxs); ++i)
+    {
+        const struct rockchip_cpu_clk_clksel *clksel = &rate->pre_muxs[i];
+
+        if (!clksel->reg)
+        {
+            break;
+        }
+
+        HWREG32(base + clksel->reg) = clksel->val;
+    }
+}
+
+static void rockchip_cpu_clk_set_post_muxs(struct rockchip_cpu_clk_cell *cpu_clk_cell,
+        const struct rockchip_cpu_clk_rate_table *rate)
+{
+    void *base = cpu_clk_cell->rk_cell.provider->reg_base;
+
+    /* Alternate parent is active now. set the muxs */
+    for (int i = 0; i < RT_ARRAY_SIZE(rate->post_muxs); ++i)
+    {
+        const struct rockchip_cpu_clk_clksel *clksel = &rate->post_muxs[i];
+
+        if (!clksel->reg)
+        {
+            break;
+        }
+
+        HWREG32(base + clksel->reg) = clksel->val;
+    }
+}
+
+static int rockchip_cpu_clk_pre_rate_change(struct rockchip_cpu_clk_cell *cpu_clk_cell,
+        rt_ubase_t old_rate, rt_ubase_t new_rate)
+{
+    rt_ubase_t alt_prate, alt_div;
+    void *base = cpu_clk_cell->rk_cell.provider->reg_base;
+    const struct rockchip_cpu_clk_reg_data *reg_data = cpu_clk_cell->reg_data;
+    const struct rockchip_cpu_clk_rate_table *rate;
+
+    /* Check validity of the new rate */
+    if (!(rate = rockchip_get_cpu_clk_settings(cpu_clk_cell, new_rate)))
+    {
+        return -RT_EINVAL;
+    }
+
+    alt_prate = rt_clk_cell_get_rate(&cpu_clk_cell->rk_cell_alt_parent->cell);
+
+    /*
+     * If the old parent clock speed is less than the clock speed
+     * of the alternate parent, then it should be ensured that at no point
+     * the armclk speed is more than the old_rate until the dividers are
+     * set.
+     */
+    if (alt_prate > old_rate)
+    {
+        /* Calculate dividers */
+        alt_div =  RT_DIV_ROUND_UP(alt_prate, old_rate) - 1;
+
+        if (alt_div > reg_data->div_core_mask[0])
+        {
+            alt_div = reg_data->div_core_mask[0];
+        }
+
+        /*
+         * Change parents and add dividers in a single transaction.
+         *
+         * NOTE: we do this in a single transaction so we're never
+         * dividing the primary parent by the extra dividers that were
+         * needed for the alt.
+         */
+
+        for (int i = 0; i < reg_data->num_cores; ++i)
+        {
+            HWREG32(base + reg_data->core_reg[i]) = HIWORD_UPDATE(
+                    alt_div,
+                    reg_data->div_core_mask[i],
+                    reg_data->div_core_shift[i]);
+        }
+    }
+
+    rockchip_cpu_clk_set_pre_muxs(cpu_clk_cell, rate);
+
+    /* select alternate parent */
+    if (reg_data->mux_core_reg)
+    {
+        HWREG32(base + reg_data->mux_core_reg) = HIWORD_UPDATE(
+                reg_data->mux_core_alt,
+                reg_data->mux_core_mask,
+                reg_data->mux_core_shift);
+    }
+    else
+    {
+        HWREG32(base + reg_data->core_reg[0]) = HIWORD_UPDATE(
+                reg_data->mux_core_alt,
+                reg_data->mux_core_mask,
+                reg_data->mux_core_shift);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_cpu_clk_post_rate_change(struct rockchip_cpu_clk_cell *cpu_clk_cell,
+        rt_ubase_t old_rate, rt_ubase_t new_rate)
+{
+    void *base = cpu_clk_cell->rk_cell.provider->reg_base;
+    const struct rockchip_cpu_clk_rate_table *rate;
+    const struct rockchip_cpu_clk_reg_data *reg_data = cpu_clk_cell->reg_data;
+
+    if (!(rate = rockchip_get_cpu_clk_settings(cpu_clk_cell, new_rate)))
+    {
+        return -RT_EINVAL;
+    }
+
+    if (old_rate < new_rate)
+    {
+        rockchip_cpu_clk_set_dividers(cpu_clk_cell, rate);
+    }
+
+    /*
+     * post-rate change event, re-mux to primary parent and remove dividers.
+     *
+     * NOTE: we do this in a single transaction so we're never dividing the
+     * primary parent by the extra dividers that were needed for the alt.
+     */
+
+    if (reg_data->mux_core_reg)
+    {
+        HWREG32(base + reg_data->mux_core_reg) = HIWORD_UPDATE(
+                reg_data->mux_core_main,
+                reg_data->mux_core_mask,
+                reg_data->mux_core_shift);
+    }
+    else
+    {
+        HWREG32(base + reg_data->core_reg[0]) = HIWORD_UPDATE(
+                reg_data->mux_core_main,
+                reg_data->mux_core_mask,
+                reg_data->mux_core_shift);
+    }
+
+    rockchip_cpu_clk_set_post_muxs(cpu_clk_cell, rate);
+
+    /* Remove dividers */
+    for (int i = 0; i < reg_data->num_cores; ++i)
+    {
+        HWREG32(base + reg_data->core_reg[i]) = HIWORD_UPDATE(
+                    0,
+                    reg_data->div_core_mask[i],
+                    reg_data->div_core_shift[i]);
+    }
+
+    if (old_rate > new_rate)
+    {
+        rockchip_cpu_clk_set_dividers(cpu_clk_cell, rate);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_cpu_clk_notify(struct rt_clk_notifier *notifier,
+        rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate)
+{
+    rt_err_t err = RT_EOK;
+    struct rockchip_cpu_clk_cell *cpu_cell;
+
+    cpu_cell = rt_container_of(notifier, struct rockchip_cpu_clk_cell, notifier);
+
+    if (msg == RT_CLK_MSG_PRE_RATE_CHANGE)
+    {
+        err = rockchip_cpu_clk_pre_rate_change(cpu_cell, old_rate, new_rate);
+    }
+    else if (msg == RT_CLK_MSG_POST_RATE_CHANGE)
+    {
+        err = rockchip_cpu_clk_post_rate_change(cpu_cell, old_rate, new_rate);
+    }
+
+    return err;
+}
+
+void rockchip_cpu_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_cpu_clk_cell *cpu_clk_cell = cell_to_rockchip_cpu_cell(&rk_cell->cell);
+
+    rk_cell->cell.parents_nr = 1;
+    rk_cell->cell.parent_name = cpu_clk_cell->rk_cell_parent->cell.name;
+
+    if (cpu_clk_cell->rate_count > 0)
+    {
+        rk_cell->cell.flags |= RT_CLK_F_SET_RATE_PARENT;
+    }
+}
+
+void rockchip_cpu_clk_cell_setup(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_cpu_clk_cell *cpu_clk_cell = cell_to_rockchip_cpu_cell(&rk_cell->cell);
+
+    rt_clk_prepare_enable(rt_clk_cell_get_clk(&cpu_clk_cell->rk_cell_alt_parent->cell, RT_NULL));
+
+    cpu_clk_cell->notifier.callback = rockchip_cpu_clk_notify;
+
+    rt_clk_notifier_register(rt_clk_cell_get_clk(&cpu_clk_cell->rk_cell_parent->cell, RT_NULL),
+            &cpu_clk_cell->notifier);
+}

+ 87 - 0
bsp/rockchip/dm/clk/clk-rk-cpu.h

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_CPU_H__
+#define __CLK_RK_CPU_H__
+
+#include "clk-rk.h"
+
+#define ROCKCHIP_CPUCLK_NUM_DIVIDERS    6
+#define ROCKCHIP_CPUCLK_MAX_CORES       4
+
+struct rockchip_cpu_clk_clksel
+{
+    int reg;
+    rt_uint32_t val;
+};
+
+struct rockchip_cpu_clk_rate_table
+{
+    rt_ubase_t prate;
+    struct rockchip_cpu_clk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
+    struct rockchip_cpu_clk_clksel pre_muxs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
+    struct rockchip_cpu_clk_clksel post_muxs[ROCKCHIP_CPUCLK_NUM_DIVIDERS];
+};
+
+struct rockchip_cpu_clk_reg_data
+{
+    int core_reg[ROCKCHIP_CPUCLK_MAX_CORES];
+    rt_uint8_t div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES];
+    rt_uint32_t div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES];
+    int num_cores;
+    int mux_core_reg;
+    rt_uint8_t mux_core_alt;
+    rt_uint8_t mux_core_main;
+    rt_uint8_t mux_core_shift;
+    rt_uint32_t mux_core_mask;
+    const char *pll_name;
+};
+
+struct rockchip_cpu_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+    struct rockchip_clk_cell *rk_cell_parent, *rk_cell_alt_parent;
+
+    int rate_count;
+    const struct rockchip_cpu_clk_rate_table *rate_table;
+    const struct rockchip_cpu_clk_reg_data *reg_data;
+
+    struct rt_clk_notifier notifier;
+};
+
+#define CPU(_id, cname, parent, alt_parent, _rates, _nrates, _reg_data) \
+(void *)&(struct rockchip_cpu_clk_cell)                     \
+{                                                           \
+    .rk_cell.cell.name = cname,                             \
+    .rk_cell.cell.ops = &rockchip_cpu_clk_ops,              \
+    .rk_cell.cell.flags = RT_CLK_F_GET_RATE_NOCACHE,        \
+    .rk_cell.id = _id,                                      \
+    .rk_cell.init = rockchip_cpu_clk_cell_init,             \
+    .rk_cell.setup = rockchip_cpu_clk_cell_setup,           \
+    .rk_cell_parent = parent,                               \
+    .rk_cell_alt_parent = alt_parent,                       \
+    .rate_count = _nrates,                                  \
+    .rate_table = _rates,                                   \
+    .reg_data = _reg_data,                                  \
+}
+
+extern const struct rt_clk_ops rockchip_cpu_clk_ops;
+
+rt_inline struct rockchip_cpu_clk_cell *cell_to_rockchip_cpu_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_cpu_clk_cell, rk_cell);
+}
+
+void rockchip_cpu_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+void rockchip_cpu_clk_cell_setup(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_cpu_H__ */

+ 595 - 0
bsp/rockchip/dm/clk/clk-rk-divider.c

@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-divider.h"
+
+struct clk_rate_request
+{
+    rt_ubase_t rate;
+    rt_ubase_t best_parent_rate;
+    struct rt_clk_cell *best_parent_cell;
+};
+
+#define clk_div_mask(width) ((1 << (width)) - 1)
+
+rt_inline rt_uint32_t clk_div_readl(struct rockchip_clk_cell *rk_cell)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    base += rk_cell->div_offset ? : rk_cell->muxdiv_offset;
+
+    if (rk_cell->div_flags & CLK_DIVIDER_BIG_ENDIAN)
+    {
+        return rt_be32_to_cpu(HWREG32(base));
+    }
+
+    return HWREG32(base);
+}
+
+rt_inline void clk_div_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    base += rk_cell->div_offset ? : rk_cell->muxdiv_offset;
+
+    if (rk_cell->div_flags & CLK_DIVIDER_BIG_ENDIAN)
+    {
+        HWREG32(base) = rt_cpu_to_be32(val);
+    }
+    else
+    {
+        HWREG32(base) = val;
+    }
+}
+
+static rt_uint32_t _get_table_maxdiv(const struct clk_div_table *table, rt_uint8_t width)
+{
+    rt_uint32_t maxdiv = 0, mask = clk_div_mask(width);
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->div > maxdiv && clkt->val <= mask)
+        {
+            maxdiv = clkt->div;
+        }
+    }
+    return maxdiv;
+}
+
+static rt_uint32_t _get_table_mindiv(const struct clk_div_table *table)
+{
+    rt_uint32_t mindiv = RT_UINT32_MAX;
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->div < mindiv)
+        {
+            mindiv = clkt->div;
+        }
+    }
+    return mindiv;
+}
+
+static rt_uint32_t _get_maxdiv(const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags)
+{
+    if (flags & CLK_DIVIDER_ONE_BASED)
+    {
+        return clk_div_mask(width);
+    }
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        return 1 << clk_div_mask(width);
+    }
+    if (table)
+    {
+        return _get_table_maxdiv(table, width);
+    }
+
+    return clk_div_mask(width) + 1;
+}
+
+static rt_uint32_t _get_table_div(const struct clk_div_table *table, rt_uint32_t val)
+{
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->val == val)
+        {
+            return clkt->div;
+        }
+    }
+
+    return 0;
+}
+
+static rt_uint32_t _get_div(const struct clk_div_table *table,
+        rt_uint32_t val, rt_ubase_t flags, rt_uint8_t width)
+{
+    if (flags & CLK_DIVIDER_ONE_BASED)
+    {
+        return val;
+    }
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        return 1 << val;
+    }
+    if (flags & CLK_DIVIDER_MAX_AT_ZERO)
+    {
+        return val ? val : clk_div_mask(width) + 1;
+    }
+    if (table)
+    {
+        return _get_table_div(table, val);
+    }
+    return val + 1;
+}
+
+static rt_uint32_t _get_table_val(const struct clk_div_table *table, rt_uint32_t div)
+{
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->div == div)
+        {
+            return clkt->val;
+        }
+    }
+
+    return 0;
+}
+
+static rt_uint32_t _get_val(const struct clk_div_table *table,
+        rt_uint32_t div, rt_ubase_t flags, rt_uint8_t width)
+{
+    if (flags & CLK_DIVIDER_ONE_BASED)
+    {
+        return div;
+    }
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        return __rt_ffs(div) - 1;
+    }
+    if (flags & CLK_DIVIDER_MAX_AT_ZERO)
+    {
+        return (div == clk_div_mask(width) + 1) ? 0 : div;
+    }
+    if (table)
+    {
+        return  _get_table_val(table, div);
+    }
+    return div - 1;
+}
+
+static int _round_up_table(const struct clk_div_table *table, int div)
+{
+    int up = RT_UINT32_MAX >> 1;
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->div == div)
+        {
+            return clkt->div;
+        }
+        else if (clkt->div < div)
+        {
+            continue;
+        }
+
+        if (clkt->div - div < up - div)
+        {
+            up = clkt->div;
+        }
+    }
+
+    return up;
+}
+
+static int _round_down_table(const struct clk_div_table *table, int div)
+{
+    int down = _get_table_mindiv(table);
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->div == div)
+        {
+            return clkt->div;
+        }
+        else if (clkt->div > div)
+        {
+            continue;
+        }
+
+        if (div - clkt->div < div - down)
+        {
+            down = clkt->div;
+        }
+    }
+
+    return down;
+}
+
+static int _div_round_up(const struct clk_div_table *table,
+        rt_ubase_t parent_rate, rt_ubase_t rate, rt_ubase_t flags)
+{
+    int div = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, rate);
+
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        div = __roundup_pow_of_two(div);
+    }
+    if (table)
+    {
+        div = _round_up_table(table, div);
+    }
+
+    return div;
+}
+
+static int _div_round_closest(const struct clk_div_table *table,
+        rt_ubase_t parent_rate, rt_ubase_t rate, rt_ubase_t flags)
+{
+    int up, down;
+    rt_ubase_t up_rate, down_rate;
+
+    up = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, rate);
+    down = parent_rate / rate;
+
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        up = __roundup_pow_of_two(up);
+        down = __rounddown_pow_of_two(down);
+    }
+    else if (table)
+    {
+        up = _round_up_table(table, up);
+        down = _round_down_table(table, down);
+    }
+
+    up_rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, up);
+    down_rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, down);
+
+    return (rate - up_rate) <= (down_rate - rate) ? up : down;
+}
+
+static int _div_round(const struct clk_div_table *table,
+        rt_ubase_t parent_rate, rt_ubase_t rate, rt_ubase_t flags)
+{
+    if (flags & CLK_DIVIDER_ROUND_CLOSEST)
+    {
+        return _div_round_closest(table, parent_rate, rate, flags);
+    }
+
+    return _div_round_up(table, parent_rate, rate, flags);
+}
+
+static rt_bool_t _is_best_div(rt_ubase_t rate, rt_ubase_t now, rt_ubase_t best, rt_ubase_t flags)
+{
+    if (flags & CLK_DIVIDER_ROUND_CLOSEST)
+    {
+        return rt_abs(rate - now) < rt_abs(rate - best);
+    }
+
+    return now <= rate && now > best;
+}
+
+static int _next_div(const struct clk_div_table *table, int div, rt_ubase_t flags)
+{
+    ++div;
+
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        return __roundup_pow_of_two(div);
+    }
+    if (table)
+    {
+        return _round_up_table(table, div);
+    }
+
+    return div;
+}
+
+static int clk_divider_bestdiv(struct rt_clk_cell *cell, struct rt_clk_cell *parent,
+        rt_ubase_t rate, rt_ubase_t *best_parent_rate,
+        const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags)
+{
+    int bestdiv = 0;
+    rt_ubase_t parent_rate, best = 0, now, maxdiv, parent_rate_saved = *best_parent_rate;
+
+    if (!rate)
+    {
+        rate = 1;
+    }
+
+    maxdiv = _get_maxdiv(table, width, flags);
+
+    if (!(cell->flags & RT_CLK_F_SET_RATE_PARENT))
+    {
+        parent_rate = *best_parent_rate;
+        bestdiv = _div_round(table, parent_rate, rate, flags);
+        bestdiv = bestdiv == 0 ? 1 : bestdiv;
+        bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
+        return bestdiv;
+    }
+
+    /*
+     * The maximum divider we can use without overflowing
+     * rt_ubase_t in rate * i below
+     */
+    maxdiv = rt_min((~0UL) / rate, maxdiv);
+
+    for (int i = _next_div(table, 0, flags); i <= maxdiv; i = _next_div(table, i, flags))
+    {
+        if (rate * i == parent_rate_saved)
+        {
+            /*
+             * It's the most ideal case if the requested rate can be
+             * divided from parent clock without needing to change
+             * parent rate, so return the divider immediately.
+             */
+            *best_parent_rate = parent_rate_saved;
+            return i;
+        }
+
+        parent_rate = rt_clk_cell_round_rate(parent, rate * i);
+        now = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, i);
+
+        if (_is_best_div(rate, now, best, flags))
+        {
+            bestdiv = i;
+            best = now;
+            *best_parent_rate = parent_rate;
+        }
+    }
+
+    if (!bestdiv)
+    {
+        bestdiv = _get_maxdiv(table, width, flags);
+        *best_parent_rate = rt_clk_cell_round_rate(parent, 1);
+    }
+
+    return bestdiv;
+}
+
+rt_inline rt_bool_t is_power_of_2(rt_ubase_t n)
+{
+    return (n != 0 && ((n & (n - 1)) == 0));
+}
+
+static rt_bool_t _is_valid_table_div(const struct clk_div_table *table, rt_uint32_t div)
+{
+    const struct clk_div_table *clkt;
+
+    for (clkt = table; clkt->div; ++clkt)
+    {
+        if (clkt->div == div)
+        {
+            return RT_TRUE;
+        }
+    }
+    return RT_FALSE;
+}
+
+static rt_bool_t _is_valid_div(const struct clk_div_table *table, rt_uint32_t div, rt_ubase_t flags)
+{
+    if (flags & CLK_DIVIDER_POWER_OF_TWO)
+    {
+        return is_power_of_2(div);
+    }
+
+    if (table)
+    {
+        return _is_valid_table_div(table, div);
+    }
+
+    return RT_TRUE;
+}
+
+static int divider_get_val(rt_ubase_t rate, rt_ubase_t parent_rate,
+        const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags)
+{
+    rt_uint32_t div, value;
+
+    div = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, rate);
+
+    if (!_is_valid_div(table, div, flags))
+    {
+        return -RT_EINVAL;
+    }
+
+    value = _get_val(table, div, flags, width);
+
+    return rt_min_t(rt_uint32_t, value, clk_div_mask(width));
+}
+
+static int divider_determine_rate(struct rt_clk_cell *cell, struct clk_rate_request *req,
+        const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags)
+{
+    int div;
+
+    div = clk_divider_bestdiv(cell, req->best_parent_cell, req->rate,
+            &req->best_parent_rate, table, width, flags);
+
+    req->rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)req->best_parent_rate, div);
+
+    return 0;
+}
+
+static int divider_ro_determine_rate(struct rt_clk_cell *cell, struct clk_rate_request *req,
+        const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags, rt_uint32_t val)
+{
+    int div;
+
+    div = _get_div(table, val, flags, width);
+
+    /* Even a read-only clock can propagate a rate change */
+    if (cell->flags & RT_CLK_F_SET_RATE_PARENT)
+    {
+        if (!req->best_parent_cell)
+        {
+            return -RT_EINVAL;
+        }
+
+        req->best_parent_rate = rt_clk_cell_round_rate(req->best_parent_cell, req->rate * div);
+    }
+
+    req->rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)req->best_parent_rate, div);
+
+    return 0;
+}
+
+static long divider_round_rate_parent(struct rt_clk_cell *cell, struct rt_clk_cell *parent,
+        rt_ubase_t rate, rt_ubase_t *prate,
+        const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags)
+{
+    int ret;
+    struct clk_rate_request req;
+
+    req.rate = rate;
+    req.best_parent_rate = *prate;
+    req.best_parent_cell = parent;
+
+    if ((ret = divider_determine_rate(cell, &req, table, width, flags)))
+    {
+        return ret;
+    }
+
+    *prate = req.best_parent_rate;
+
+    return req.rate;
+}
+
+static long divider_ro_round_rate_parent(struct rt_clk_cell *cell, struct rt_clk_cell *parent,
+        rt_ubase_t rate, rt_ubase_t *prate,
+        const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags, rt_uint32_t val)
+{
+    int ret;
+    struct clk_rate_request req;
+
+    req.rate = rate;
+    req.best_parent_rate = *prate;
+    req.best_parent_cell = parent;
+
+    if ((ret = divider_ro_determine_rate(cell, &req, table, width, flags, val)))
+    {
+        return ret;
+    }
+
+    *prate = req.best_parent_rate;
+
+    return req.rate;
+}
+
+static rt_ubase_t divider_recalc_rate(rt_ubase_t parent_rate, rt_uint32_t val,
+        const struct clk_div_table *table, rt_ubase_t flags, rt_ubase_t width)
+{
+    rt_uint32_t div = _get_div(table, val, flags, width);
+
+    if (!div)
+    {
+        return parent_rate;
+    }
+
+    return RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, div);
+}
+
+static rt_ubase_t clk_divider_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
+{
+    rt_uint32_t val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    val = clk_div_readl(rk_cell) >> rk_cell->div_shift;
+    val &= clk_div_mask(rk_cell->div_width);
+
+    return divider_recalc_rate(parent_rate, val,
+            rk_cell->div_table, rk_cell->div_flags, rk_cell->div_width);
+}
+
+static rt_base_t clk_divider_round_rate(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t *prate)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    if (rk_cell->div_flags & CLK_DIVIDER_READ_ONLY)
+    {
+        rt_uint32_t val;
+
+        val = clk_div_readl(rk_cell) >> rk_cell->div_shift;
+        val &= clk_div_mask(rk_cell->div_width);
+
+        return divider_ro_round_rate_parent(cell, rt_clk_cell_get_parent(cell),
+                rate, prate, rk_cell->div_table,
+                rk_cell->div_width, rk_cell->div_flags, val);
+    }
+
+    return divider_round_rate_parent(cell, rt_clk_cell_get_parent(cell),
+            rate, prate, rk_cell->div_table,
+            rk_cell->div_width, rk_cell->div_flags);
+}
+
+static rt_err_t clk_divider_set_rate(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t parent_rate)
+{
+    int value;
+    rt_uint32_t val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    value = divider_get_val(rate, parent_rate,
+            rk_cell->div_table, rk_cell->div_width, rk_cell->div_flags);
+
+    if (value < 0)
+    {
+        return value;
+    }
+
+    if (rk_cell->div_flags & CLK_DIVIDER_HIWORD_MASK)
+    {
+        val = clk_div_mask(rk_cell->div_width) << (rk_cell->div_shift + 16);
+    }
+    else
+    {
+        val = clk_div_readl(rk_cell);
+        val &= ~(clk_div_mask(rk_cell->div_width) << rk_cell->div_shift);
+    }
+    val |= (rt_uint32_t)value << rk_cell->div_shift;
+    clk_div_writel(rk_cell, val);
+
+    return 0;
+}
+
+const struct rt_clk_ops clk_divider_ops =
+{
+    .recalc_rate = clk_divider_recalc_rate,
+    .round_rate = clk_divider_round_rate,
+    .set_rate = clk_divider_set_rate,
+};
+
+const struct rt_clk_ops clk_divider_ro_ops =
+{
+    .recalc_rate = clk_divider_recalc_rate,
+    .round_rate = clk_divider_round_rate,
+};
+
+void rockchip_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    if (rk_cell->div_flags & CLK_DIVIDER_READ_ONLY)
+    {
+        rk_cell->cell.ops = &clk_divider_ro_ops;
+    }
+    else
+    {
+        rk_cell->cell.ops = &clk_divider_ops;
+    }
+}

+ 52 - 0
bsp/rockchip/dm/clk/clk-rk-divider.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_DIVIDER_H__
+#define __CLK_RK_DIVIDER_H__
+
+#include "clk-rk.h"
+
+#define DIV(_id, cname, pname, f, o, s, w, df)  \
+(void *)&(struct rockchip_clk_cell)         \
+{                                           \
+    .cell.name = cname,                     \
+    .cell.parent_name = pname,              \
+    .cell.parents_nr = 1,                   \
+    .cell.flags = f,                        \
+    .id = _id,                              \
+    .muxdiv_offset = o,                     \
+    .div_shift = s,                         \
+    .div_width = w,                         \
+    .div_flags = df,                        \
+    .gate_offset = -1,                      \
+    .init = rockchip_divider_clk_cell_init, \
+}
+
+#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \
+(void *)&(struct rockchip_clk_cell)         \
+{                                           \
+    .cell.name = cname,                     \
+    .cell.parent_name = pname,              \
+    .cell.parents_nr = 1,                   \
+    .cell.flags = f,                        \
+    .id = _id,                              \
+    .muxdiv_offset = o,                     \
+    .div_shift = s,                         \
+    .div_width = w,                         \
+    .div_flags = df,                        \
+    .div_table = dt,                        \
+    .init = rockchip_divider_clk_cell_init, \
+}
+
+extern const struct rt_clk_ops clk_divider_ops, clk_divider_ro_ops;
+
+void rockchip_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_DIVIDER_H__ */

+ 61 - 0
bsp/rockchip/dm/clk/clk-rk-factor.c

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-factor.h"
+#include "clk-rk-gate.h"
+
+static rt_ubase_t clk_factor_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
+{
+    rt_uint64_t rate;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    rate = (rt_uint64_t)parent_rate * rk_cell->div_shift;
+    rt_do_div(rate, rk_cell->div_width);
+
+    return (rt_ubase_t)rate;
+}
+
+static rt_base_t clk_factor_round_rate(struct rt_clk_cell *cell, rt_ubase_t rate, rt_ubase_t *prate)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    if (cell->flags & RT_CLK_F_SET_RATE_PARENT)
+    {
+        rt_ubase_t best_parent;
+
+        best_parent = (rate / rk_cell->div_shift) * rk_cell->div_width;
+        *prate = rt_clk_cell_round_rate(rt_clk_cell_get_parent(cell), best_parent);
+    }
+
+    return (*prate / rk_cell->div_width) * rk_cell->div_shift;
+}
+
+static rt_err_t clk_factor_set_rate(struct rt_clk_cell *cell, rt_ubase_t rate, rt_ubase_t parent_rate)
+{
+    return RT_EOK;
+}
+
+void rockchip_factor_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_factor_clk_cell *factor_cell = cell_to_rockchip_factor_clk_cell(&rk_cell->cell);
+
+    rk_cell->cell.ops = &factor_cell->ops;
+
+    factor_cell->ops.recalc_rate = clk_factor_recalc_rate;
+    factor_cell->ops.round_rate = clk_factor_round_rate;
+    factor_cell->ops.set_rate = clk_factor_set_rate;
+
+    if (rk_cell->gate_offset >= 0)
+    {
+        factor_cell->ops.enable = rockchip_gate_clk_ops.enable;
+        factor_cell->ops.disable = rockchip_gate_clk_ops.disable;
+        factor_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled;
+    }
+}

+ 63 - 0
bsp/rockchip/dm/clk/clk-rk-factor.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_FACTOR_H__
+#define __CLK_RK_FACTOR_H__
+
+#include "clk-rk.h"
+
+struct rockchip_factor_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+
+    struct rt_clk_ops ops;
+};
+
+#define FACTOR(_id, cname, pname, f, fm, fd)        \
+(void *)&(struct rockchip_factor_clk_cell)          \
+{                                                   \
+    .rk_cell.cell.name = cname,                     \
+    .rk_cell.cell.parent_name = pname,              \
+    .rk_cell.cell.parents_nr = 1,                   \
+    .rk_cell.cell.flags = f,                        \
+    .rk_cell.id = _id,                              \
+    .rk_cell.div_shift = fm,                        \
+    .rk_cell.div_width = fd,                        \
+    .rk_cell.init = rockchip_factor_clk_cell_init,  \
+}
+
+#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \
+(void *)&(struct rockchip_factor_clk_cell)          \
+{                                                   \
+    .rk_cell.cell.name = cname,                     \
+    .rk_cell.cell.parent_name = pname,              \
+    .rk_cell.cell.parents_nr = 1,                   \
+    .rk_cell.cell.flags = f,                        \
+    .rk_cell.id = _id,                              \
+    .rk_cell.div_shift = fm,                        \
+    .rk_cell.div_width = fd,                        \
+    .rk_cell.gate_offset = go,                      \
+    .rk_cell.gate_shift = gb,                       \
+    .rk_cell.gate_flags = gf,                       \
+    .rk_cell.init = rockchip_factor_clk_cell_init,  \
+}
+
+#define SGRF_GATE(_id, cname, pname)    FACTOR(_id, cname, pname, 0, 1, 1)
+
+rt_inline struct rockchip_factor_clk_cell *cell_to_rockchip_factor_clk_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_factor_clk_cell, rk_cell);
+}
+
+void rockchip_factor_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_FACTOR_H__ */

+ 370 - 0
bsp/rockchip/dm/clk/clk-rk-fraction-divider.c

@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-fraction-divider.h"
+#include "clk-rk-mux.h"
+#include "clk-rk-gate.h"
+
+struct u32_fract
+{
+    rt_uint32_t numerator;
+    rt_uint32_t denominator;
+};
+
+#define CLK_FD_MSHIFT   16
+#define CLK_FD_MWIDTH   16
+#define CLK_FD_NSHIFT   0
+#define CLK_FD_NWIDTH   16
+
+rt_inline rt_uint32_t clk_fd_readl(struct rockchip_clk_cell *rk_cell)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    if (rk_cell->div_flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
+    {
+        return rt_be32_to_cpu(HWREG32(base + rk_cell->muxdiv_offset));
+    }
+
+    return HWREG32(base + rk_cell->muxdiv_offset);
+}
+
+rt_inline void clk_fd_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    if (rk_cell->div_flags & CLK_FRAC_DIVIDER_BIG_ENDIAN)
+    {
+        HWREG32(base + rk_cell->muxdiv_offset) = rt_cpu_to_be32(val);
+    }
+    else
+    {
+        HWREG32(base + rk_cell->muxdiv_offset) = val;
+    }
+}
+
+static void clk_fd_get_div(struct rt_clk_cell *cell, struct u32_fract *fract)
+{
+    rt_ubase_t m, n;
+    rt_uint32_t val, mmask, nmask;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    val = clk_fd_readl(rk_cell);
+
+    mmask = RT_GENMASK(CLK_FD_MWIDTH - 1, 0) << CLK_FD_MSHIFT;
+    nmask = RT_GENMASK(CLK_FD_NWIDTH - 1, 0) << CLK_FD_NSHIFT;
+
+    m = (val & mmask) >> CLK_FD_MSHIFT;
+    n = (val & nmask) >> CLK_FD_NSHIFT;
+
+    if (rk_cell->div_flags & CLK_FRAC_DIVIDER_ZERO_BASED)
+    {
+        ++m;
+        ++n;
+    }
+
+    fract->numerator = m;
+    fract->denominator = n;
+}
+
+static rt_ubase_t clk_fd_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
+{
+    rt_uint64_t ret;
+    struct u32_fract fract;
+
+    clk_fd_get_div(cell, &fract);
+
+    if (!fract.numerator || !fract.denominator)
+    {
+        return parent_rate;
+    }
+
+    ret = (rt_uint64_t)parent_rate * fract.numerator;
+    rt_do_div(ret, fract.denominator);
+
+    return ret;
+}
+
+static void clk_fractional_divider_general_approximation(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t *parent_rate, rt_ubase_t *m, rt_ubase_t *n)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    /*
+     * Get rate closer to *parent_rate to guarantee there is no overflow
+     * for m and n. In the result it will be the nearest rate left shifted
+     * by (scale - CLK_FD_NWIDTH) bits.
+     *
+     * For the detailed explanation see the top comment in this file.
+     */
+    if (rk_cell->div_flags & CLK_FRAC_DIVIDER_POWER_OF_TWO_PS)
+    {
+        rt_ubase_t scale = fls_long(*parent_rate / rate - 1);
+
+        if (scale > CLK_FD_NWIDTH)
+        {
+            rate <<= scale - CLK_FD_NWIDTH;
+        }
+    }
+
+    rational_best_approximation(rate, *parent_rate,
+            RT_GENMASK(CLK_FD_MWIDTH - 1, 0), RT_GENMASK(CLK_FD_NWIDTH - 1, 0), m, n);
+}
+
+/*
+ * fractional divider must set that denominator is 20 times larger than
+ * numerator to generate precise clock frequency.
+ */
+static void rockchip_fractional_approximation(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t *parent_rate, rt_ubase_t *m, rt_ubase_t *n)
+{
+    struct rt_clk_cell *p_parent;
+    rt_ubase_t p_rate, p_parent_rate;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    if (rate == 0)
+    {
+        *m = 0;
+        *n = 1;
+        return;
+    }
+
+    p_rate = rt_clk_cell_get_rate(rt_clk_cell_get_parent(cell));
+
+    if (rate * 20 > p_rate && p_rate % rate != 0)
+    {
+        p_parent = rt_clk_cell_get_parent(rt_clk_cell_get_parent(cell));
+
+        if (!p_parent)
+        {
+            *parent_rate = p_rate;
+        }
+        else
+        {
+            p_parent_rate = rt_clk_cell_get_rate(p_parent);
+            *parent_rate = p_parent_rate;
+        }
+
+        if (*parent_rate == 0)
+        {
+            *m = 0;
+            *n = 1;
+            return;
+        }
+
+        if (*parent_rate < rate * 20)
+        {
+            /*
+             * Fractional frequency divider to do
+             * integer frequency divider does not need 20 times the limit.
+             */
+            if (!(*parent_rate % rate))
+            {
+                *m = 1;
+                *n = *parent_rate / rate;
+                return;
+            }
+            else if (!(rk_cell->div_flags & CLK_FRAC_DIVIDER_NO_LIMIT))
+            {
+                *m = 0;
+                *n = 1;
+                return;
+            }
+        }
+    }
+
+    rk_cell->div_flags |= CLK_FRAC_DIVIDER_POWER_OF_TWO_PS;
+
+    clk_fractional_divider_general_approximation(cell, rate, parent_rate, m, n);
+}
+
+static rt_base_t clk_fd_round_rate(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t *parent_rate)
+{
+    rt_ubase_t m, n;
+    rt_uint64_t ret;
+
+    if (!rate || rate >= *parent_rate)
+    {
+        return *parent_rate;
+    }
+
+    rockchip_fractional_approximation(cell, rate, parent_rate, &m, &n);
+
+    ret = (rt_uint64_t)*parent_rate * m;
+    rt_do_div(ret, n);
+
+    return ret;
+}
+
+static rt_err_t clk_fd_set_rate(struct rt_clk_cell *cell, rt_ubase_t rate, rt_ubase_t parent_rate)
+{
+    rt_ubase_t m, n;
+    rt_uint32_t mmask, nmask, val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    rational_best_approximation(rate, parent_rate,
+            RT_GENMASK(CLK_FD_MWIDTH - 1, 0), RT_GENMASK(CLK_FD_NWIDTH - 1, 0), &m, &n);
+
+    if (rk_cell->div_flags & CLK_FRAC_DIVIDER_ZERO_BASED)
+    {
+        --m;
+        --n;
+    }
+
+    mmask = RT_GENMASK(CLK_FD_MWIDTH - 1, 0) << CLK_FD_MSHIFT;
+    nmask = RT_GENMASK(CLK_FD_NWIDTH - 1, 0) << CLK_FD_NSHIFT;
+
+    /*
+     * When compensation the fractional divider,
+     * the [1:0] bits of the numerator register are omitted,
+     * which will lead to a large deviation in the result.
+     * Therefore, it is required that the numerator must
+     * be greater than 4.
+     *
+     * Note that there are some exceptions here:
+     * If there is an even frac div, we need to keep the original
+     * numerator(<4) and denominator. Otherwise, it may cause the
+     * issue that the duty ratio is not 50%.
+     */
+    if (m < 4 && m != 0)
+    {
+        if (n % 2 == 0)
+        {
+            val = 1;
+        }
+        else
+        {
+            val = RT_DIV_ROUND_UP(4, m);
+        }
+
+        n *= val;
+        m *= val;
+
+        if (n > nmask)
+        {
+            n = nmask;
+        }
+    }
+
+    mmask = RT_GENMASK(CLK_FD_MWIDTH - 1, 0) << CLK_FD_MSHIFT;
+    nmask = RT_GENMASK(CLK_FD_NWIDTH - 1, 0) << CLK_FD_NSHIFT;
+
+    val = clk_fd_readl(rk_cell);
+    val &= ~(mmask | nmask);
+    val |= (m << CLK_FD_MSHIFT) | (n << CLK_FD_NSHIFT);
+    clk_fd_writel(rk_cell, val);
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_clk_frac_notify(struct rt_clk_notifier *notifier,
+        rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate)
+{
+    struct rt_clk_cell *cell;
+    struct rockchip_fraction_divider_clk_cell *fraction_divider_cell;
+
+    fraction_divider_cell = rt_container_of(notifier, struct rockchip_fraction_divider_clk_cell, notifier);
+    cell = &fraction_divider_cell->rk_cell_child->cell;
+
+    if (msg == RT_CLK_MSG_PRE_RATE_CHANGE)
+    {
+        fraction_divider_cell->rate_change_idx = cell->ops->get_parent(cell);
+
+        if (fraction_divider_cell->rate_change_idx != fraction_divider_cell->mux_frac_idx)
+        {
+            cell->ops->set_parent(cell, fraction_divider_cell->mux_frac_idx);
+            fraction_divider_cell->rate_change_remuxed = 1;
+        }
+    }
+    else if (msg == RT_CLK_MSG_POST_RATE_CHANGE)
+    {
+        /*
+         * The RT_CLK_MSG_POST_RATE_CHANGE notifier runs directly after the
+         * divider clock is set in clk_change_rate, so we'll have
+         * remuxed back to the original parent before clk_change_rate
+         * reaches the mux itself.
+         */
+        if (fraction_divider_cell->rate_change_remuxed)
+        {
+            cell->ops->set_parent(cell, fraction_divider_cell->rate_change_idx);
+            fraction_divider_cell->rate_change_remuxed = 0;
+        }
+    }
+
+    return RT_EOK;
+}
+
+static int match_string(const char * const *array, size_t n, const char *string)
+{
+    for (int index = 0; index < n; ++index)
+    {
+        const char *item = array[index];
+
+        if (!item)
+        {
+            break;
+        }
+        if (!rt_strcmp(item, string))
+        {
+            return index;
+        }
+    }
+
+    return -RT_EINVAL;
+}
+
+void rockchip_fraction_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_fraction_divider_clk_cell *fraction_divider_cell = cell_to_rockchip_fraction_divider_clk_cell(&rk_cell->cell);
+
+    rk_cell->cell.ops = &fraction_divider_cell->ops;
+    rk_cell->cell.flags |= RT_CLK_F_SET_RATE_UNGATE;
+
+    if (fraction_divider_cell->rk_cell_child)
+    {
+        struct rockchip_clk_cell *rk_cell_child = fraction_divider_cell->rk_cell_child;
+        struct rt_clk_cell *cell = &rk_cell_child->cell;
+
+        rk_cell_child->cell.flags |= RT_CLK_F_SET_RATE_PARENT;
+
+        fraction_divider_cell->mux_frac_idx = match_string(cell->parent_names, cell->parents_nr,
+                rk_cell->cell.name);
+
+        rockchip_mux_clk_cell_init(rk_cell);
+
+        fraction_divider_cell->ops.get_parent = rockchip_mux_clk_ops.get_parent;
+        fraction_divider_cell->ops.set_parent = rockchip_mux_clk_ops.set_parent;
+    }
+
+    if (rk_cell->gate_offset >= 0)
+    {
+        fraction_divider_cell->ops.enable = rockchip_gate_clk_ops.enable;
+        fraction_divider_cell->ops.disable = rockchip_gate_clk_ops.disable;
+        fraction_divider_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled;
+    }
+
+    fraction_divider_cell->ops.recalc_rate = clk_fd_recalc_rate;
+    fraction_divider_cell->ops.round_rate = clk_fd_round_rate;
+    fraction_divider_cell->ops.set_rate = clk_fd_set_rate;
+}
+
+void rockchip_fraction_divider_clk_cell_setup(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_fraction_divider_clk_cell *fraction_divider_cell = cell_to_rockchip_fraction_divider_clk_cell(&rk_cell->cell);
+    struct rockchip_clk_cell *rk_cell_child = fraction_divider_cell->rk_cell_child;
+
+    if (fraction_divider_cell->mux_frac_idx >= 0)
+    {
+        fraction_divider_cell->notifier.callback = rockchip_clk_frac_notify;
+
+        rt_clk_notifier_register(rt_clk_cell_get_clk(&rk_cell_child->cell, RT_NULL),
+                &fraction_divider_cell->notifier);
+    }
+}

+ 95 - 0
bsp/rockchip/dm/clk/clk-rk-fraction-divider.h

@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_FRACTION_DIVIDER_H__
+#define __CLK_RK_FRACTION_DIVIDER_H__
+
+#include "clk-rk.h"
+
+struct rockchip_fraction_divider_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+
+    struct rt_clk_ops ops;
+    struct rockchip_clk_cell *rk_cell_child;
+
+    int mux_frac_idx;
+    int rate_change_idx;
+    int rate_change_remuxed;
+    struct rt_clk_notifier notifier;
+};
+
+#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\
+(void *)&(struct rockchip_fraction_divider_clk_cell)            \
+{                                                               \
+    .rk_cell.cell.name = cname,                                 \
+    .rk_cell.cell.parent_name = pname,                          \
+    .rk_cell.cell.parents_nr = 1,                               \
+    .rk_cell.cell.flags = f,                                    \
+    .rk_cell.id = _id,                                          \
+    .rk_cell.muxdiv_offset = mo,                                \
+    .rk_cell.div_shift = 16,                                    \
+    .rk_cell.div_width = 16,                                    \
+    .rk_cell.div_flags = df,                                    \
+    .rk_cell.gate_offset = go,                                  \
+    .rk_cell.gate_shift = gs,                                   \
+    .rk_cell.gate_flags = gf,                                   \
+    .rk_cell.init = rockchip_fraction_divider_clk_cell_init,    \
+}
+
+#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \
+(void *)&(struct rockchip_fraction_divider_clk_cell)            \
+{                                                               \
+    .rk_cell.cell.name = cname,                                 \
+    .rk_cell.cell.parent_name = pname,                          \
+    .rk_cell.cell.parents_nr = 1,                               \
+    .rk_cell.cell.flags = f,                                    \
+    .rk_cell.id = _id,                                          \
+    .rk_cell.muxdiv_offset = mo,                                \
+    .rk_cell.div_shift = 16,                                    \
+    .rk_cell.div_width = 16,                                    \
+    .rk_cell.div_flags = df,                                    \
+    .rk_cell.gate_offset = go,                                  \
+    .rk_cell.gate_shift = gs,                                   \
+    .rk_cell.gate_flags = gf,                                   \
+    .rk_cell.init = rockchip_fraction_divider_clk_cell_init,    \
+    .rk_cell.setup = rockchip_fraction_divider_clk_cell_setup,  \
+    .rk_cell_child = ch,                                        \
+}
+
+#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \
+(void *)&(struct rockchip_fraction_divider_clk_cell)            \
+{                                                               \
+    .rk_cell.cell.name = cname,                                 \
+    .rk_cell.cell.parent_name = pname,                          \
+    .rk_cell.cell.parents_nr = 1,                               \
+    .rk_cell.cell.flags = f,                                    \
+    .rk_cell.id = _id,                                          \
+    .rk_cell.muxdiv_offset = mo,                                \
+    .rk_cell.div_shift = 16,                                    \
+    .rk_cell.div_width = 16,                                    \
+    .rk_cell.div_flags = df,                                    \
+    .rk_cell.gate_offset = -1,                                  \
+    .rk_cell.init = rockchip_fraction_divider_clk_cell_init,    \
+    .rk_cell.setup = rockchip_fraction_divider_clk_cell_setup,  \
+    .rk_cell_child = ch,                                        \
+}
+
+rt_inline struct rockchip_fraction_divider_clk_cell *cell_to_rockchip_fraction_divider_clk_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_fraction_divider_clk_cell, rk_cell);
+}
+
+void rockchip_fraction_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+void rockchip_fraction_divider_clk_cell_setup(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_FRACTION_DIVIDER_H__ */

+ 109 - 0
bsp/rockchip/dm/clk/clk-rk-gate.c

@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-gate.h"
+
+rt_inline rt_uint32_t clk_gate_readl(struct rockchip_clk_cell *rk_cell)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    if (rk_cell->gate_flags & CLK_GATE_BIG_ENDIAN)
+    {
+        return rt_be32_to_cpu(HWREG32(base + rk_cell->gate_offset));
+    }
+
+    return HWREG32(base + rk_cell->gate_offset);
+}
+
+rt_inline void clk_gate_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    if (rk_cell->gate_flags & CLK_GATE_BIG_ENDIAN)
+    {
+        HWREG32(base + rk_cell->gate_offset) = rt_cpu_to_be32(val);
+    }
+    else
+    {
+        HWREG32(base + rk_cell->gate_offset) = val;
+    }
+}
+
+static void clk_gate_endisable(struct rt_clk_cell *cell, int enable)
+{
+    int set;
+    rt_uint32_t reg;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    set = rk_cell->gate_flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0;
+    set ^= enable;
+
+    if (rk_cell->gate_flags & CLK_GATE_HIWORD_MASK)
+    {
+        reg = RT_BIT(rk_cell->gate_shift + 16);
+
+        if (set)
+        {
+            reg |= RT_BIT(rk_cell->gate_shift);
+        }
+    }
+    else
+    {
+        reg = clk_gate_readl(rk_cell);
+
+        if (set)
+        {
+            reg |= RT_BIT(rk_cell->gate_shift);
+        }
+        else
+        {
+            reg &= ~RT_BIT(rk_cell->gate_shift);
+        }
+    }
+
+    clk_gate_writel(rk_cell, reg);
+}
+
+static rt_err_t rockchip_gate_clk_enable(struct rt_clk_cell *cell)
+{
+    clk_gate_endisable(cell, 1);
+
+    return RT_EOK;
+}
+
+static void rockchip_gate_clk_disable(struct rt_clk_cell *cell)
+{
+    clk_gate_endisable(cell, 0);
+}
+
+static rt_bool_t rockchip_gate_clk_is_enabled(struct rt_clk_cell *cell)
+{
+    rt_uint32_t reg;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    reg = clk_gate_readl(rk_cell);
+
+    /* If a set bit disables this clk, flip it before masking */
+    if (rk_cell->gate_flags & CLK_GATE_SET_TO_DISABLE)
+    {
+        reg ^= RT_BIT(rk_cell->gate_shift);
+    }
+
+    reg &= RT_BIT(rk_cell->gate_shift);
+
+    return !!reg;
+}
+
+const struct rt_clk_ops rockchip_gate_clk_ops =
+{
+    .enable = rockchip_gate_clk_enable,
+    .disable = rockchip_gate_clk_disable,
+    .is_enabled = rockchip_gate_clk_is_enabled,
+};

+ 32 - 0
bsp/rockchip/dm/clk/clk-rk-gate.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_GATE_H__
+#define __CLK_RK_GATE_H__
+
+#include "clk-rk.h"
+
+#define GATE(_id, cname, pname, f, o, b, gf)    \
+(void *)&(struct rockchip_clk_cell)             \
+{                                               \
+    .cell.name = cname,                         \
+    .cell.ops = &rockchip_gate_clk_ops,         \
+    .cell.parent_name = pname,                  \
+    .cell.parents_nr = 1,                       \
+    .cell.flags = f | RT_CLK_F_SET_RATE_PARENT, \
+    .id = _id,                                  \
+    .gate_offset = o,                           \
+    .gate_shift = b,                            \
+    .gate_flags = gf,                           \
+}
+
+extern const struct rt_clk_ops rockchip_gate_clk_ops;
+
+#endif /* __CLK_RK_GATE_H__ */

+ 182 - 0
bsp/rockchip/dm/clk/clk-rk-half-divider.c

@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-half-divider.h"
+#include "clk-rk-gate.h"
+#include "clk-rk-mux.h"
+
+#define clk_div_mask(width) ((1 << (width)) - 1)
+
+static rt_bool_t _is_best_half_div(rt_ubase_t rate, rt_ubase_t now,
+        rt_ubase_t best, rt_ubase_t flags)
+{
+    if (flags & CLK_DIVIDER_ROUND_CLOSEST)
+    {
+        return rt_abs(rate - now) <= rt_abs(rate - best);
+    }
+
+    return now <= rate && now >= best;
+}
+
+rt_inline rt_uint32_t clk_div_readl(struct rockchip_clk_cell *rk_cell)
+{
+    return HWREG32(rk_cell->provider->reg_base + (rk_cell->div_offset ? : rk_cell->muxdiv_offset));
+}
+
+rt_inline void clk_div_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
+{
+    HWREG32(rk_cell->provider->reg_base + (rk_cell->div_offset ? : rk_cell->muxdiv_offset)) = val;
+}
+
+static rt_ubase_t clk_div_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
+{
+    rt_uint32_t val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    val = clk_div_readl(rk_cell) >> rk_cell->div_shift;
+    val &= clk_div_mask(rk_cell->div_width);
+    val = val * 2 + 3;
+
+    return RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), val);
+}
+
+static int clk_div_bestdiv(struct rt_clk_cell *cell, rt_ubase_t rate,
+        rt_ubase_t *best_parent_rate, rt_uint8_t width, rt_ubase_t flags)
+{
+    rt_uint32_t bestdiv = 0;
+    rt_bool_t is_bestdiv = RT_FALSE;
+    rt_ubase_t parent_rate, best = 0, now, maxdiv;
+
+    if (!rate)
+    {
+        rate = 1;
+    }
+
+    maxdiv = clk_div_mask(width);
+
+    if (!(cell->flags & RT_CLK_F_SET_RATE_PARENT))
+    {
+        parent_rate = *best_parent_rate;
+        bestdiv = RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), rate);
+
+        if (bestdiv < 3)
+        {
+            bestdiv = 0;
+        }
+        else
+        {
+            bestdiv = RT_DIV_ROUND_UP(bestdiv - 3, 2);
+        }
+
+        bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv;
+
+        return bestdiv;
+    }
+
+    /*
+     * The maximum divider we can use without overflowing
+     * rt_ubase_t in rate * i below
+     */
+    maxdiv = rt_min((~0UL) / rate, maxdiv);
+
+    for (int i = 0; i <= maxdiv; ++i)
+    {
+        parent_rate = rt_clk_cell_round_rate(rt_clk_cell_get_parent(cell),
+                ((rt_uint64_t)rate * (i * 2 + 3)) / 2);
+        now = RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), (i * 2 + 3));
+
+        if (_is_best_half_div(rate, now, best, flags))
+        {
+            is_bestdiv = RT_TRUE;
+            bestdiv = i;
+            best = now;
+            *best_parent_rate = parent_rate;
+        }
+    }
+
+    if (!is_bestdiv)
+    {
+        bestdiv = clk_div_mask(width);
+        *best_parent_rate = rt_clk_cell_round_rate(rt_clk_cell_get_parent(cell), 1);
+    }
+
+    return bestdiv;
+}
+
+static rt_base_t clk_div_round_rate(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t *prate)
+{
+    int div;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    div = clk_div_bestdiv(cell, rate, prate, rk_cell->div_width, rk_cell->div_flags);
+
+    return RT_DIV_ROUND_UP_ULL(((rt_uint64_t)*prate * 2), div * 2 + 3);
+}
+
+static rt_err_t clk_div_set_rate(struct rt_clk_cell *cell,
+        rt_ubase_t rate, rt_ubase_t parent_rate)
+{
+    rt_uint32_t value, val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    value = RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), rate);
+    value = RT_DIV_ROUND_UP(value - 3, 2);
+    value = rt_min_t(rt_uint32_t, value, clk_div_mask(rk_cell->div_width));
+
+    if (rk_cell->div_flags & CLK_DIVIDER_HIWORD_MASK)
+    {
+        val = clk_div_mask(rk_cell->div_width) << (rk_cell->div_shift + 16);
+    }
+    else
+    {
+        val = clk_div_readl(rk_cell);
+        val &= ~(clk_div_mask(rk_cell->div_width) << rk_cell->div_shift);
+    }
+
+    val |= value << rk_cell->div_shift;
+    clk_div_writel(rk_cell, val);
+
+    return RT_EOK;
+}
+
+void rockchip_half_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_half_divider_clk_cell *half_divider_cell = cell_to_rockchip_half_divider_clk_cell(&rk_cell->cell);
+
+    rk_cell->cell.ops = &half_divider_cell->ops;
+
+    if (rk_cell->cell.parents_nr > 1)
+    {
+        rockchip_mux_clk_cell_init(rk_cell);
+
+        half_divider_cell->ops.get_parent = rockchip_mux_clk_ops.get_parent;
+
+        if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY)))
+        {
+            half_divider_cell->ops.set_parent = rockchip_mux_clk_ops.set_parent;
+        }
+    }
+
+    if (rk_cell->gate_offset >= 0)
+    {
+        half_divider_cell->ops.enable = rockchip_gate_clk_ops.enable;
+        half_divider_cell->ops.disable = rockchip_gate_clk_ops.disable;
+        half_divider_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled;
+        half_divider_cell->ops.recalc_rate = clk_div_recalc_rate;
+        half_divider_cell->ops.round_rate = clk_div_round_rate;
+        half_divider_cell->ops.set_rate = clk_div_set_rate;
+    }
+
+    if (rk_cell->div_width > 0)
+    {
+        half_divider_cell->ops.set_rate = clk_div_set_rate;
+    }
+}

+ 126 - 0
bsp/rockchip/dm/clk/clk-rk-half-divider.h

@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_HALF_DIVIDER_H__
+#define __CLK_RK_HALF_DIVIDER_H__
+
+#include "clk-rk.h"
+
+struct rockchip_half_divider_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+
+    struct rt_clk_ops ops;
+};
+
+#define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_half_divider_clk_cell)        \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_half_divider_clk_cell_init,\
+}
+
+#define COMPOSITE_HALFDIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, mf, do, ds, dw, df, go, gs, gf) \
+(void *)&(struct rockchip_half_divider_clk_cell)        \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_offset = do,                           \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_half_divider_clk_cell_init,\
+}
+
+#define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df)                            \
+(void *)&(struct rockchip_half_divider_clk_cell)        \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_names = pnames,                \
+    .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.mux_shift = ms,                            \
+    .rk_cell.mux_width = mw,                            \
+    .rk_cell.mux_flags = mf,                            \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = -1,                          \
+    .rk_cell.init = rockchip_half_divider_clk_cell_init,\
+}
+
+#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, go, gs, gf)                             \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_name = pname,                  \
+    .rk_cell.cell.parents_nr = 1,                       \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = mo,                        \
+    .rk_cell.div_shift = ds,                            \
+    .rk_cell.div_width = dw,                            \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = go,                          \
+    .rk_cell.gate_shift = gs,                           \
+    .rk_cell.gate_flags = gf,                           \
+    .rk_cell.init = rockchip_half_divider_clk_cell_init,\
+}
+
+#define DIV_HALF(_id, cname, pname, f, o, s, w, df)     \
+{                                                       \
+    .rk_cell.cell.name = cname,                         \
+    .rk_cell.cell.parent_name = pname,                  \
+    .rk_cell.cell.parents_nr = 1,                       \
+    .rk_cell.cell.flags = f,                            \
+    .rk_cell.id = _id,                                  \
+    .rk_cell.muxdiv_offset = o,                         \
+    .rk_cell.div_shift = s,                             \
+    .rk_cell.div_width = w,                             \
+    .rk_cell.div_flags = df,                            \
+    .rk_cell.gate_offset = -1,                          \
+    .rk_cell.init = rockchip_half_divider_clk_cell_init,\
+}
+
+rt_inline struct rockchip_half_divider_clk_cell *cell_to_rockchip_half_divider_clk_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_half_divider_clk_cell, rk_cell);
+}
+
+void rockchip_half_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_HALF_DIVIDER_H__ */

+ 68 - 19
bsp/rockchip/rk3500/driver/clk/clk-mmc-phase.c → bsp/rockchip/dm/clk/clk-rk-mmc-phase.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2024 RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
@@ -8,10 +8,11 @@
  * 2022-3-08      GuEe-GUI     the first version
  */
 
-#define ROCKCHIP_MMC_DELAY_SEL          RT_BIT(11)
-#define ROCKCHIP_MMC_DEGREE_OFFSET      1
-#define ROCKCHIP_MMC_DEGREE_MASK        (0x3 << ROCKCHIP_MMC_DEGREE_OFFSET)
-#define ROCKCHIP_MMC_DELAYNUM_OFFSET    3
+#include "clk-rk-mmc-phase.h"
+
+#define ROCKCHIP_MMC_DELAY_SEL          RT_BIT(10)
+#define ROCKCHIP_MMC_DEGREE_MASK        0x3
+#define ROCKCHIP_MMC_DELAYNUM_OFFSET    2
 #define ROCKCHIP_MMC_DELAYNUM_MASK      (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
 /*
  * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
@@ -19,20 +20,24 @@
  */
 #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
 
-#define PSECS_PER_SEC 1000000000000LL
+#define PSECS_PER_SEC                   1000000000000LL
 
-#define RK3288_MMC_CLKGEN_DIV 2
+#define RK3288_MMC_CLKGEN_DIV           2
 
-rt_inline rt_ubase_t rk_clk_mmc_recalc(rt_ubase_t parent_rate)
+static rt_ubase_t rockchip_mmc_recalc(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
 {
     return parent_rate / RK3288_MMC_CLKGEN_DIV;
 }
 
-static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift,
-        int degrees)
+static rt_err_t rockchip_mmc_set_phase(struct rt_clk_cell *cell, int degrees)
 {
+    rt_ubase_t rate;
     rt_uint32_t raw_value, delay;
     rt_uint8_t nineties, remainder, delay_num;
+    struct rockchip_mmc_clk_cell *mmc_cell = cell_to_rockchip_mmc_clk_cell(cell);
+    struct rockchip_clk_cell *rk_cell = &mmc_cell->rk_cell;
+
+    rate = rt_clk_cell_get_rate(cell);
 
     /*
      * The below calculation is based on the output clock from
@@ -48,8 +53,6 @@ static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift,
      */
     if (!rate)
     {
-        LOG_E("Invalid CLK rate in phase setting");
-
         return -RT_EINVAL;
     }
 
@@ -81,23 +84,30 @@ static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift,
      */
     delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */
     delay *= remainder;
-    delay = RT_DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 *
-                (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
+    delay = RT_DIV_ROUND_CLOSEST(delay,
+            (rate / 1000) * 36 * (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10));
 
     delay_num = (rt_uint8_t)rt_min_t(rt_uint32_t, delay, 255);
 
     raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
     raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
     raw_value |= nineties;
-    HWREG32(reg) = HIWORD_UPDATE(raw_value, 0x07ff, shift);
+
+    HWREG32(rk_cell->provider->reg_base + rk_cell->muxdiv_offset) =
+            HIWORD_UPDATE(raw_value, 0x07ff, rk_cell->div_shift);
 
     return RT_EOK;
 }
 
-static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift)
+static rt_base_t rockchip_mmc_get_phase(struct rt_clk_cell *cell)
 {
+    rt_ubase_t rate;
     rt_uint16_t degrees;
     rt_uint32_t raw_value, delay_num = 0;
+    struct rockchip_mmc_clk_cell *mmc_cell = cell_to_rockchip_mmc_clk_cell(cell);
+    struct rockchip_clk_cell *rk_cell = &mmc_cell->rk_cell;
+
+    rate = rt_clk_cell_get_rate(cell);
 
     /* Constant signal, no measurable phase shift */
     if (!rate)
@@ -105,14 +115,14 @@ static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift)
         return 0;
     }
 
-    raw_value = HWREG32(reg) >> shift;
+    raw_value = HWREG32(rk_cell->provider->reg_base + rk_cell->muxdiv_offset) >> rk_cell->div_shift;
+
     degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
 
     if (raw_value & ROCKCHIP_MMC_DELAY_SEL)
     {
         /* degrees/delaynum * 1000000 */
-        rt_ubase_t factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) *
-                36 * (rate / 10000);
+        rt_ubase_t factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 36 * (rate / 10000);
 
         delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
         delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
@@ -121,3 +131,42 @@ static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift)
 
     return degrees % 360;
 }
+
+const struct rt_clk_ops rockchip_mmc_clk_ops =
+{
+    .recalc_rate = rockchip_mmc_recalc,
+    .set_phase = rockchip_mmc_set_phase,
+    .get_phase = rockchip_mmc_get_phase,
+};
+
+static rt_err_t rockchip_mmc_clk_rate_notify(struct rt_clk_notifier *notifier,
+        rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate)
+{
+    struct rockchip_mmc_clk_cell *mmc_cell = rt_container_of(notifier, struct rockchip_mmc_clk_cell, notifier);
+
+    if (old_rate <= new_rate)
+    {
+        return RT_EOK;
+    }
+
+    if (msg == RT_CLK_MSG_PRE_RATE_CHANGE)
+    {
+        mmc_cell->cached_phase = rockchip_mmc_get_phase(&mmc_cell->rk_cell.cell);
+    }
+    else if (mmc_cell->cached_phase != -RT_EINVAL && msg == RT_CLK_MSG_POST_RATE_CHANGE)
+    {
+        rockchip_mmc_set_phase(&mmc_cell->rk_cell.cell, mmc_cell->cached_phase);
+    }
+
+    return RT_EOK;
+}
+
+void rockchip_mmc_clk_cell_setup(struct rockchip_clk_cell *rk_cell)
+{
+    struct rt_clk_cell *cell = &rk_cell->cell;
+    struct rockchip_mmc_clk_cell *mmc_cell = cell_to_rockchip_mmc_clk_cell(cell);
+
+    mmc_cell->notifier.callback = rockchip_mmc_clk_rate_notify;
+
+    rt_clk_notifier_register(rt_clk_cell_get_clk(cell, RT_NULL), &mmc_cell->notifier);
+}

+ 48 - 0
bsp/rockchip/dm/clk/clk-rk-mmc-phase.h

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_MMC_PHASE_H__
+#define __CLK_RK_MMC_PHASE_H__
+
+#include "clk-rk.h"
+
+struct rockchip_mmc_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+
+    int cached_phase;
+    struct rt_clk_notifier notifier;
+};
+
+#define MMC(_id, cname, pname, offset, shift)       \
+(void *)&(struct rockchip_mmc_clk_cell)             \
+{                                                   \
+    .rk_cell.cell.name = cname,                     \
+    .rk_cell.cell.ops = &rockchip_mmc_clk_ops,      \
+    .rk_cell.cell.parent_name = pname,              \
+    .rk_cell.cell.parents_nr = 1,                   \
+    .rk_cell.id = _id,                              \
+    .rk_cell.muxdiv_offset = offset,                \
+    .rk_cell.div_shift = shift,                     \
+    .rk_cell.setup = rockchip_mmc_clk_cell_setup,   \
+}
+
+extern const struct rt_clk_ops rockchip_mmc_clk_ops;
+
+rt_inline struct rockchip_mmc_clk_cell *cell_to_rockchip_mmc_clk_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_mmc_clk_cell, rk_cell);
+}
+
+void rockchip_mmc_clk_cell_setup(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_MMC_PHASE_H__ */

+ 159 - 0
bsp/rockchip/dm/clk/clk-rk-mux.c

@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-mux.h"
+
+rt_inline rt_uint32_t clk_mux_readl(struct rockchip_clk_cell *rk_cell)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    if (rk_cell->mux_flags & CLK_MUX_BIG_ENDIAN)
+    {
+        return rt_be32_to_cpu(HWREG32(base + rk_cell->muxdiv_offset));
+    }
+
+    return HWREG32(base + rk_cell->muxdiv_offset);
+}
+
+rt_inline void clk_mux_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val)
+{
+    void *base = rk_cell->provider->reg_base;
+
+    if (rk_cell->mux_flags & CLK_MUX_BIG_ENDIAN)
+    {
+        HWREG32(base + rk_cell->muxdiv_offset) = rt_cpu_to_be32(val);
+    }
+    else
+    {
+        HWREG32(base + rk_cell->muxdiv_offset) = val;
+    }
+}
+
+static int clk_mux_val_to_index(struct rt_clk_cell *cell,
+        const rt_uint32_t *table, rt_uint32_t flags, rt_uint32_t val)
+{
+    int num_parents = cell->parents_nr;
+
+    if (table)
+    {
+        for (int i = 0; i < num_parents; ++i)
+        {
+            if (table[i] == val)
+            {
+                return i;
+            }
+        }
+
+        return -RT_EINVAL;
+    }
+
+    if (val && (flags & CLK_MUX_INDEX_BIT))
+    {
+        val = __rt_ffs(val) - 1;
+    }
+
+    if (val && (flags & CLK_MUX_INDEX_ONE))
+    {
+        --val;
+    }
+
+    if (val >= num_parents)
+    {
+        return -RT_EINVAL;
+    }
+
+    return val;
+}
+
+static rt_uint32_t clk_mux_index_to_val(const rt_uint32_t *table, rt_uint32_t flags, rt_uint8_t index)
+{
+    rt_uint32_t val = index;
+
+    if (table)
+    {
+        val = table[index];
+    }
+    else
+    {
+        if (flags & CLK_MUX_INDEX_BIT)
+        {
+            val = 1 << index;
+        }
+
+        if (flags & CLK_MUX_INDEX_ONE)
+        {
+            val++;
+        }
+    }
+
+    return val;
+}
+
+static rt_err_t rockchip_mux_clk_set_parent(struct rt_clk_cell *cell, rt_uint8_t index)
+{
+    rt_uint32_t val, reg;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    val = clk_mux_index_to_val(rk_cell->mux_table, rk_cell->mux_flags, index);
+
+    if (rk_cell->mux_flags & CLK_MUX_HIWORD_MASK)
+    {
+        reg = rk_cell->mux_mask << (rk_cell->mux_shift + 16);
+    }
+    else
+    {
+        reg = clk_mux_readl(rk_cell);
+        reg &= ~(rk_cell->mux_mask << rk_cell->mux_shift);
+    }
+    val = val << rk_cell->mux_shift;
+    reg |= val;
+    clk_mux_writel(rk_cell, reg);
+
+    return RT_EOK;
+}
+
+static rt_uint8_t rockchip_mux_clk_get_parent(struct rt_clk_cell *cell)
+{
+    rt_uint32_t val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    val = clk_mux_readl(rk_cell) >> rk_cell->mux_shift;
+    val &= rk_cell->mux_mask;
+
+    return clk_mux_val_to_index(cell, rk_cell->mux_table, rk_cell->mux_flags, val);
+}
+
+const struct rt_clk_ops rockchip_mux_clk_ops =
+{
+    .set_parent = rockchip_mux_clk_set_parent,
+    .get_parent = rockchip_mux_clk_get_parent,
+};
+
+const struct rt_clk_ops rockchip_mux_ro_clk_ops =
+{
+    .get_parent = rockchip_mux_clk_get_parent,
+};
+
+void rockchip_mux_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    rk_cell->mux_mask = RT_BIT(rk_cell->mux_width) - 1;
+
+    if (!rk_cell->cell.ops)
+    {
+        if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY)))
+        {
+            rk_cell->cell.ops = &rockchip_mux_clk_ops;
+        }
+        else
+        {
+            rk_cell->cell.ops = &rockchip_mux_ro_clk_ops;
+        }
+    }
+}

+ 57 - 0
bsp/rockchip/dm/clk/clk-rk-mux.h

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_MUX_H__
+#define __CLK_RK_MUX_H__
+
+#include "clk-rk.h"
+
+#define MUX_RAW(_id, cname, pnames, f, o, s, w, mf) \
+{                                               \
+    .cell.name = cname,                         \
+    .cell.parent_names = pnames,                \
+    .cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .cell.flags = f,                            \
+    .id = _id,                                  \
+    .muxdiv_offset = o,                         \
+    .mux_shift = s,                             \
+    .mux_width = w,                             \
+    .mux_flags = mf,                            \
+    .gate_offset = -1,                          \
+    .init = rockchip_mux_clk_cell_init,         \
+}
+
+#define MUX(_id, cname, pnames, f, o, s, w, mf) \
+    (void *)&(struct rockchip_clk_cell)MUX_RAW(_id, cname, pnames, f, o, s, w, mf)
+
+#define MUXTBL_RAW(_id, cname, pnames, f, o, s, w, mf, mt) \
+{                                               \
+    .cell.name = cname,                         \
+    .cell.parent_names = pname,                 \
+    .cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .cell.flags = f,                            \
+    .id = _id,                                  \
+    .muxdiv_offset = o,                         \
+    .mux_shift = s,                             \
+    .mux_width = w,                             \
+    .mux_flags = mf,                            \
+    .gate_offset = -1,                          \
+    .mux_table = mt,                            \
+    .init = rockchip_mux_clk_cell_init,         \
+}
+
+#define MUXTBL(_id, cname, pnames, f, o, s, w, mf, mt) \
+    (void *)&(struct rockchip_clk_cell)MUXTBL_RAW(_id, cname, pnames, f, o, s, w, mf, mt)
+
+extern const struct rt_clk_ops rockchip_mux_clk_ops, rockchip_mux_ro_clk_ops;
+
+void rockchip_mux_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_MUX_H__ */

+ 85 - 0
bsp/rockchip/dm/clk/clk-rk-muxgrf.c

@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-muxgrf.h"
+
+static rt_err_t rockchip_muxgrf_set_parent_common(struct rt_clk_cell *cell, struct rt_syscon *grf,
+        rt_uint8_t index)
+{
+    rt_uint32_t mask, val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    mask = RT_GENMASK(rk_cell->mux_width + rk_cell->mux_shift - 1, rk_cell->mux_shift);
+
+    val = index;
+    val <<= rk_cell->mux_shift;
+
+    if (rk_cell->mux_flags & CLK_MUX_HIWORD_MASK)
+    {
+        return rt_syscon_write(grf, rk_cell->muxdiv_offset, val | (mask << 16));
+    }
+
+    return rt_syscon_update_bits(grf, rk_cell->muxdiv_offset, mask, val);
+}
+
+static rt_uint8_t rockchip_muxgrf_get_parent_common(struct rt_clk_cell *cell, struct rt_syscon *grf)
+{
+    rt_uint32_t mask, val;
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    mask = RT_GENMASK(rk_cell->mux_width - 1, 0);
+
+    rt_syscon_read(grf, rk_cell->muxdiv_offset, &val);
+
+    val >>= rk_cell->mux_shift;
+    val &= mask;
+
+    return val;
+}
+
+static rt_err_t rockchip_muxgrf_set_parent(struct rt_clk_cell *cell, rt_uint8_t index)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rockchip_muxgrf_set_parent_common(cell, rk_cell->provider->grf, index);
+}
+
+static rt_uint8_t rockchip_muxgrf_get_parent(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rockchip_muxgrf_get_parent_common(cell, rk_cell->provider->grf);
+}
+
+const struct rt_clk_ops rockchip_muxgrf_clk_ops =
+{
+    .set_parent = rockchip_muxgrf_set_parent,
+    .get_parent = rockchip_muxgrf_get_parent,
+};
+
+static rt_err_t rockchip_muxpmugrf_set_parent(struct rt_clk_cell *cell, rt_uint8_t index)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rockchip_muxgrf_set_parent_common(cell, rk_cell->provider->pmugrf, index);
+}
+
+static rt_uint8_t rockchip_muxpmugrf_get_parent(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rockchip_muxgrf_get_parent_common(cell, rk_cell->provider->pmugrf);
+}
+
+const struct rt_clk_ops rockchip_muxpmugrf_clk_ops =
+{
+    .set_parent = rockchip_muxpmugrf_set_parent,
+    .get_parent = rockchip_muxpmugrf_get_parent,
+};

+ 50 - 0
bsp/rockchip/dm/clk/clk-rk-muxgrf.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_MUXGRF_H__
+#define __CLK_RK_MUXGRF_H__
+
+#include "clk-rk.h"
+
+#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \
+(void *)&(struct rockchip_clk_cell)             \
+{                                               \
+    .cell.name = cname,                         \
+    .cell.ops = &rockchip_muxgrf_clk_ops,       \
+    .cell.parent_names = pnames,                \
+    .cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .cell.flags = f,                            \
+    .id = _id,                                  \
+    .muxdiv_offset = o,                         \
+    .mux_shift = s,                             \
+    .mux_width = w,                             \
+    .mux_flags = mf,                            \
+    .gate_offset = -1,                          \
+}
+
+#define MUXPMUGRF(_id, cname, pnames, f, o, s, w, mf) \
+(void *)&(struct rockchip_clk_cell)             \
+{                                               \
+    .cell.name = cname,                         \
+    .cell.ops = &rockchip_muxpmugrf_clk_ops,    \
+    .cell.parent_names = pnames,                \
+    .cell.parents_nr = RT_ARRAY_SIZE(pnames),   \
+    .cell.flags = f,                            \
+    .id = _id,                                  \
+    .muxdiv_offset = o,                         \
+    .mux_shift = s,                             \
+    .mux_width = w,                             \
+    .mux_flags = mf,                            \
+    .gate_offset = -1,                          \
+}
+
+extern const struct rt_clk_ops rockchip_muxgrf_clk_ops, rockchip_muxpmugrf_clk_ops;
+
+#endif /* __CLK_RK_MUXGRF_H__ */

+ 1546 - 0
bsp/rockchip/dm/clk/clk-rk-pll.c

@@ -0,0 +1,1546 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-pll.h"
+#include "clk-rk-mux.h"
+
+#define PLL_MODE_MASK           0x3
+#define PLL_MODE_SLOW           0x0
+#define PLL_MODE_NORM           0x1
+#define PLL_MODE_DEEP           0x2
+#define PLL_RK3328_MODE_MASK    0x1
+
+#define MHZ                     (1000UL * 1000UL)
+#define KHZ                     (1000UL)
+
+/* CLK_PLL_TYPE_RK3066_AUTO type ops */
+#define PLL_FREF_MIN            (269 * KHZ)
+#define PLL_FREF_MAX            (2200 * MHZ)
+
+#define PLL_FVCO_MIN            (440 * MHZ)
+#define PLL_FVCO_MAX            (2200 * MHZ)
+
+#define PLL_FOUT_MIN            (27500 * KHZ)
+#define PLL_FOUT_MAX            (2200 * MHZ)
+
+#define PLL_NF_MAX              (4096)
+#define PLL_NR_MAX              (64)
+#define PLL_NO_MAX              (16)
+
+/* CLK_PLL_TYPE_RK3036/3366/3399_AUTO type ops */
+#define MIN_FOUTVCO_FREQ        (800 * MHZ)
+#define MAX_FOUTVCO_FREQ        (2000 * MHZ)
+
+static struct rockchip_pll_rate_table auto_table;
+
+static void rockchip_pll_clk_set_postdiv(rt_ubase_t fout_hz,
+        rt_uint32_t *postdiv1, rt_uint32_t *postdiv2, rt_uint32_t *foutvco)
+{
+    rt_ubase_t freq;
+
+    if (fout_hz < MIN_FOUTVCO_FREQ)
+    {
+        for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++)
+        {
+            for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++)
+            {
+                freq = fout_hz * (*postdiv1) * (*postdiv2);
+
+                if (freq >= MIN_FOUTVCO_FREQ && freq <= MAX_FOUTVCO_FREQ)
+                {
+                    *foutvco = freq;
+                    return;
+                }
+            }
+        }
+    }
+    else
+    {
+        *postdiv1 = 1;
+        *postdiv2 = 1;
+    }
+}
+
+static struct rockchip_pll_rate_table *rockchip_pll_clk_set_by_auto(
+        rt_ubase_t fin_hz, rt_ubase_t fout_hz)
+{
+    rt_ubase_t clk_gcd = 0;
+    rt_uint64_t fin_64, frac_64;
+    rt_uint32_t foutvco = fout_hz, f_frac, postdiv1, postdiv2;
+    struct rockchip_pll_rate_table *rate_table = &auto_table;
+
+    if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+    {
+        return RT_NULL;
+    }
+
+    rockchip_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco);
+    rate_table->postdiv1 = postdiv1;
+    rate_table->postdiv2 = postdiv2;
+    rate_table->dsmpd = 1;
+
+    if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz)
+    {
+        fin_hz /= MHZ;
+        foutvco /= MHZ;
+        clk_gcd = rockchip_gcd(fin_hz, foutvco);
+        rate_table->refdiv = fin_hz / clk_gcd;
+        rate_table->fbdiv = foutvco / clk_gcd;
+
+        rate_table->frac = 0;
+    }
+    else
+    {
+        clk_gcd = rockchip_gcd(fin_hz / MHZ, foutvco / MHZ);
+        rate_table->refdiv = fin_hz / MHZ / clk_gcd;
+        rate_table->fbdiv = foutvco / MHZ / clk_gcd;
+
+        rate_table->frac = 0;
+
+        f_frac = (foutvco % MHZ);
+        fin_64 = fin_hz;
+        rt_do_div(fin_64, (rt_uint64_t)rate_table->refdiv);
+        frac_64 = (rt_uint64_t)f_frac << 24;
+        rt_do_div(frac_64, fin_64);
+        rate_table->frac = (rt_uint32_t)frac_64;
+        if (rate_table->frac > 0)
+        {
+            rate_table->dsmpd = 0;
+        }
+    }
+
+    return rate_table;
+}
+
+static void *rockchip_pll_base(struct rockchip_pll_clk_cell *pll_clk_cell)
+{
+    return pll_clk_cell->rk_cell.provider->reg_base + pll_clk_cell->con_offset;
+}
+
+static struct rockchip_pll_rate_table * rockchip_rk3066_pll_clk_set_by_auto(
+        rt_ubase_t fin_hz, rt_ubase_t fout_hz)
+{
+    rt_ubase_t clk_gcd = 0;
+    rt_uint64_t fref, fvco, fout;
+    rt_uint32_t nr, nf, no, nonr, nr_out, nf_out, no_out, n, numerator, denominator;
+    struct rockchip_pll_rate_table *rate_table = &auto_table;
+
+    nr_out = PLL_NR_MAX + 1;
+    no_out = 0;
+    nf_out = 0;
+
+    if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+    {
+        return RT_NULL;
+    }
+
+    clk_gcd = rockchip_gcd(fin_hz, fout_hz);
+
+    numerator = fout_hz / clk_gcd;
+    denominator = fin_hz / clk_gcd;
+
+    for (n = 1;; ++n)
+    {
+        nf = numerator * n;
+        nonr = denominator * n;
+
+        if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX))
+        {
+            break;
+        }
+
+        for (no = 1; no <= PLL_NO_MAX; ++no)
+        {
+            if (!(no == 1 || !(no % 2)))
+            {
+                continue;
+            }
+
+            if (nonr % no)
+            {
+                continue;
+            }
+            nr = nonr / no;
+
+            if (nr > PLL_NR_MAX)
+            {
+                continue;
+            }
+
+            fref = fin_hz / nr;
+            if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX)
+            {
+                continue;
+            }
+
+            fvco = fref * nf;
+            if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX)
+            {
+                continue;
+            }
+
+            fout = fvco / no;
+            if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX)
+            {
+                continue;
+            }
+
+            /* select the best from all available PLL settings */
+            if ((no > no_out) || ((no == no_out) && (nr < nr_out)))
+            {
+                nr_out = nr;
+                nf_out = nf;
+                no_out = no;
+            }
+        }
+    }
+
+    /* output the best PLL setting */
+    if ((nr_out <= PLL_NR_MAX) && (no_out > 0))
+    {
+        rate_table->nr = nr_out;
+        rate_table->nf = nf_out;
+        rate_table->no = no_out;
+    }
+    else
+    {
+        return RT_NULL;
+    }
+
+    return rate_table;
+}
+
+static rt_uint32_t rockchip_rk3588_pll_frac_get(
+        rt_uint32_t m, rt_uint32_t p, rt_uint32_t s, rt_uint64_t fin_hz, rt_uint64_t fvco)
+{
+    rt_uint32_t k = 0;
+    rt_uint64_t fref, fout, ffrac;
+
+    fref = fin_hz / p;
+    ffrac = fvco - (m * fref);
+    fout = ffrac * 65536;
+    k = fout / fref;
+
+    if (k > 32767)
+    {
+        fref = fin_hz / p;
+        ffrac = ((m + 1) * fref) - fvco;
+        fout = ffrac * 65536;
+        k = ((fout * 10 / fref) + 7) / 10;
+
+        if (k > 32767)
+        {
+            k = 0;
+        }
+        else
+        {
+            k = ~k + 1;
+        }
+    }
+    return k;
+}
+
+static struct rockchip_pll_rate_table *rockchip_rk3588_pll_frac_by_auto(
+        rt_ubase_t fin_hz, rt_ubase_t fout_hz)
+{
+    rt_uint32_t p, m, s, k;
+    rt_uint64_t fvco, fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ;
+    struct rockchip_pll_rate_table *rate_table = &auto_table;
+
+    for (s = 0; s <= 6; ++s)
+    {
+        fvco = (rt_uint64_t)fout_hz << s;
+
+        if (fvco < fvco_min || fvco > fvco_max)
+        {
+            continue;
+        }
+        for (p = 1; p <= 4; ++p)
+        {
+            for (m = 64; m <= 1023; ++m)
+            {
+                if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p))
+                {
+                    k = rockchip_rk3588_pll_frac_get(m, p, s, (rt_uint64_t)fin_hz, fvco);
+
+                    if (!k)
+                    {
+                        continue;
+                    }
+
+                    rate_table->p = p;
+                    rate_table->s = s;
+                    rate_table->k = k;
+
+                    if (k > 32767)
+                    {
+                        rate_table->m = m + 1;
+                    }
+                    else
+                    {
+                        rate_table->m = m;
+                    }
+
+                    return rate_table;
+                }
+            }
+        }
+    }
+
+    return RT_NULL;
+}
+
+static struct rockchip_pll_rate_table *rockchip_rk3588_pll_clk_set_by_auto(
+        rt_ubase_t fin_hz, rt_ubase_t fout_hz)
+{
+    rt_uint32_t p, m, s;
+    rt_uint64_t fvco, fout_min = 37 * MHZ, fout_max = 4500 * MHZ;
+    rt_uint64_t fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ;
+    struct rockchip_pll_rate_table *rate_table = &auto_table;
+
+    if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+    {
+        return RT_NULL;
+    }
+
+    if (fout_hz > fout_max || fout_hz < fout_min)
+    {
+        return RT_NULL;
+    }
+
+    if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz)
+    {
+        for (s = 0; s <= 6; ++s)
+        {
+            fvco = (rt_uint64_t)fout_hz << s;
+
+            if (fvco < fvco_min || fvco > fvco_max)
+            {
+                continue;
+            }
+
+            for (p = 2; p <= 4; ++p)
+            {
+                for (m = 64; m <= 1023; ++m)
+                {
+                    if (fvco == m * fin_hz / p)
+                    {
+                        rate_table->p = p;
+                        rate_table->m = m;
+                        rate_table->s = s;
+                        rate_table->k = 0;
+
+                        return rate_table;
+                    }
+                }
+            }
+        }
+    }
+    else
+    {
+        if ((rate_table = rockchip_rk3588_pll_frac_by_auto(fin_hz, fout_hz)))
+        {
+            return rate_table;
+        }
+    }
+
+    return RT_NULL;
+}
+
+static const struct rockchip_pll_rate_table *rockchip_get_pll_settings(
+        struct rockchip_pll_clk_cell *pll_clk_cell, rt_ubase_t rate)
+{
+    const struct rockchip_pll_rate_table *rate_table = pll_clk_cell->rate_table;
+
+    for (int i = 0; i < rate_table[i].rate; ++i)
+    {
+        if (rate == rate_table[i].rate)
+        {
+            if (i < pll_clk_cell->sel)
+            {
+                pll_clk_cell->scaling = rate;
+
+                return &rate_table[pll_clk_cell->sel];
+            }
+            pll_clk_cell->scaling = 0;
+
+            return &rate_table[i];
+        }
+    }
+    pll_clk_cell->scaling = 0;
+
+    if (pll_clk_cell->type == pll_type_rk3066)
+    {
+        return rockchip_rk3066_pll_clk_set_by_auto(24 * MHZ, rate);
+    }
+    else if (pll_clk_cell->type == pll_type_rk3588 || pll_clk_cell->type == pll_type_rk3588_core)
+    {
+        return rockchip_rk3588_pll_clk_set_by_auto(24 * MHZ, rate);
+    }
+    else
+    {
+        return rockchip_pll_clk_set_by_auto(24 * MHZ, rate);
+    }
+}
+
+static rt_base_t rockchip_pll_round_rate(struct rt_clk_cell *cell,
+        rt_ubase_t drate, rt_ubase_t *prate)
+{
+    return drate;
+}
+
+#define LINK_GRF(grf, off)   grf, off
+
+static rt_uint32_t grf_read(struct rt_syscon *grf, int offset)
+{
+    rt_uint32_t val;
+
+    rt_syscon_read(grf, offset, &val);
+
+    return val;
+}
+
+/*
+ * Wait for the pll to reach the locked state.
+ * The calling set_rate function is responsible for making sure the
+ * grf regmap is available.
+ */
+static rt_err_t rockchip_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell)
+{
+    rt_uint32_t val;
+    struct rt_syscon *grf = pll_clk_cell->rk_cell.provider->grf;
+
+    return readx_poll_timeout(grf_read,
+                              LINK_GRF(grf, pll_clk_cell->grf_lock_offset),
+                              val,
+                              val & RT_BIT(pll_clk_cell->lock_shift),
+                              0, 1000);
+}
+
+static rt_err_t rockchip_pll_set_parent(struct rt_clk_cell *cell, rt_uint8_t index)
+{
+    return rockchip_mux_clk_ops.set_parent(cell, index);
+}
+
+static rt_uint8_t rockchip_pll_get_parent(struct rt_clk_cell *cell)
+{
+    return rockchip_mux_clk_ops.get_parent(cell);
+}
+
+/*
+ * PLL used in RK3036
+ */
+
+#define RK3036_PLLCON(i)                (i * 0x4)
+#define RK3036_PLLCON0_FBDIV_MASK       0xfff
+#define RK3036_PLLCON0_FBDIV_SHIFT      0
+#define RK3036_PLLCON0_POSTDIV1_MASK    0x7
+#define RK3036_PLLCON0_POSTDIV1_SHIFT   12
+#define RK3036_PLLCON1_REFDIV_MASK      0x3f
+#define RK3036_PLLCON1_REFDIV_SHIFT     0
+#define RK3036_PLLCON1_POSTDIV2_MASK    0x7
+#define RK3036_PLLCON1_POSTDIV2_SHIFT   6
+#define RK3036_PLLCON1_LOCK_STATUS      RT_BIT(10)
+#define RK3036_PLLCON1_DSMPD_MASK       0x1
+#define RK3036_PLLCON1_DSMPD_SHIFT      12
+#define RK3036_PLLCON1_PWRDOWN          RT_BIT(13)
+#define RK3036_PLLCON1_PLLPDSEL         RT_BIT(15)
+#define RK3036_PLLCON2_FRAC_MASK        0xffffff
+#define RK3036_PLLCON2_FRAC_SHIFT       0
+
+static rt_err_t rockchip_rk3036_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    /*
+     * Lock time typical 250, max 500 input clock cycles @24MHz
+     * So define a very safe maximum of 1000us, meaning 24000 cycles.
+     */
+    return readl_poll_timeout(base + RK3036_PLLCON(1),
+                              pllcon,
+                              pllcon & RK3036_PLLCON1_LOCK_STATUS,
+                              0, 1000);
+}
+
+
+static rt_err_t rockchip_rk3036_pll_enable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    HWREG32(base + RK3036_PLLCON(1)) = HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0);
+    rockchip_rk3036_pll_wait_lock(pll_clk_cell);
+
+    rockchip_mux_clk_ops.set_parent(cell, PLL_MODE_NORM);
+
+    return RT_EOK;
+}
+
+static void rockchip_rk3036_pll_disable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    rockchip_mux_clk_ops.set_parent(cell, PLL_MODE_SLOW);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    HWREG32(base + RK3036_PLLCON(1)) = HIWORD_UPDATE(
+            RK3036_PLLCON1_PWRDOWN, RK3036_PLLCON1_PWRDOWN, 0);
+}
+
+static rt_bool_t rockchip_rk3036_pll_is_enabled(struct rt_clk_cell *cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+    pllcon = HWREG32(base + RK3036_PLLCON(1));
+
+    return !(pllcon & RK3036_PLLCON1_PWRDOWN);
+}
+
+static void rockchip_rk3036_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        struct rockchip_pll_rate_table *rate)
+{
+    rt_uint32_t pllcon;
+    void *base = rockchip_pll_base(pll_clk_cell);
+
+    pllcon = HWREG32(base + RK3036_PLLCON(0));
+    rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) & RK3036_PLLCON0_FBDIV_MASK);
+    rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK);
+
+    pllcon = HWREG32(base + RK3036_PLLCON(1));
+    rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) & RK3036_PLLCON1_REFDIV_MASK);
+    rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK);
+    rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK);
+
+    pllcon = HWREG32(base + RK3036_PLLCON(2));
+    rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK);
+}
+
+static rt_ubase_t rockchip_rk3036_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate)
+{
+    rt_uint64_t rate64 = prate, frac_rate64 = prate;
+    struct rockchip_pll_rate_table cur;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    if (pll_clk_cell->sel && pll_clk_cell->scaling)
+    {
+        return pll_clk_cell->scaling;
+    }
+
+    rockchip_rk3036_pll_get_params(pll_clk_cell, &cur);
+
+    rate64 *= cur.fbdiv;
+    rt_do_div(rate64, cur.refdiv);
+
+    if (cur.dsmpd == 0)
+    {
+        /* Fractional mode */
+        frac_rate64 *= cur.frac;
+
+        rt_do_div(frac_rate64, cur.refdiv);
+        rate64 += frac_rate64 >> 24;
+    }
+
+    rt_do_div(rate64, cur.postdiv1);
+    rt_do_div(rate64, cur.postdiv2);
+
+    return (rt_ubase_t)rate64;
+}
+
+static rt_err_t rockchip_rk3036_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        const struct rockchip_pll_rate_table *rate)
+{
+    void *base;
+    rt_err_t err;
+    rt_uint32_t pllcon;
+    int rate_change_remuxed = 0, cur_parent;
+    struct rockchip_pll_rate_table cur;
+
+    rockchip_rk3036_pll_get_params(pll_clk_cell, &cur);
+    cur.rate = 0;
+
+    if (!(pll_clk_cell->flags & ROCKCHIP_PLL_FIXED_MODE))
+    {
+        cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell);
+
+        if (cur_parent == PLL_MODE_NORM)
+        {
+            rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW);
+            rate_change_remuxed = 1;
+        }
+    }
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    /* Update pll values */
+    HWREG32(base + RK3036_PLLCON(0)) =
+            HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK, RK3036_PLLCON0_FBDIV_SHIFT) |
+            HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK, RK3036_PLLCON0_POSTDIV1_SHIFT);
+
+    HWREG32(base + RK3036_PLLCON(1)) =
+            HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK, RK3036_PLLCON1_REFDIV_SHIFT) |
+            HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK, RK3036_PLLCON1_POSTDIV2_SHIFT) |
+            HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK, RK3036_PLLCON1_DSMPD_SHIFT);
+
+    /* GPLL CON2 is not HIWORD_MASK */
+    pllcon = HWREG32(base + RK3036_PLLCON(2));
+    pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT);
+    pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT;
+    HWREG32(base + RK3036_PLLCON(2)) = pllcon;
+
+    /* Wait for the pll to lock */
+    if ((err = rockchip_rk3036_pll_wait_lock(pll_clk_cell)))
+    {
+        rockchip_rk3036_pll_set_params(pll_clk_cell, &cur);
+    }
+
+    if (rate_change_remuxed)
+    {
+        rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM);
+    }
+
+    return err;
+}
+
+static rt_err_t rockchip_rk3036_pll_set_rate(struct rt_clk_cell *cell,
+        rt_ubase_t drate, rt_ubase_t prate)
+{
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    /* Get required rate settings from table */
+    if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate)))
+    {
+        return -RT_EINVAL;
+    }
+
+    return rockchip_rk3036_pll_set_params(pll_clk_cell, rate);
+}
+
+static const struct rt_clk_ops rockchip_rk3036_pll_clk_norate_ops =
+{
+    .enable = rockchip_rk3036_pll_enable,
+    .disable = rockchip_rk3036_pll_disable,
+    .is_enabled = rockchip_rk3036_pll_is_enabled,
+    .recalc_rate = rockchip_rk3036_pll_recalc_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static const struct rt_clk_ops rockchip_rk3036_pll_clk_ops =
+{
+    .enable = rockchip_rk3036_pll_enable,
+    .disable = rockchip_rk3036_pll_disable,
+    .is_enabled = rockchip_rk3036_pll_is_enabled,
+    .recalc_rate = rockchip_rk3036_pll_recalc_rate,
+    .round_rate = rockchip_pll_round_rate,
+    .set_rate = rockchip_rk3036_pll_set_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static void rockchip_rk3036_pll_init(struct rt_clk_cell *cell)
+{
+    rt_ubase_t drate;
+    struct rockchip_pll_rate_table cur;
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    if (!(pll_clk_cell->flags & ROCKCHIP_PLL_SYNC_RATE))
+    {
+        return;
+    }
+
+    drate = rt_clk_cell_get_rate(cell);
+    rate = rockchip_get_pll_settings(pll_clk_cell, drate);
+
+    /* when no rate setting for the current rate, rely on clk_set_rate */
+    if (!rate)
+    {
+        return;
+    }
+
+    rockchip_rk3036_pll_get_params(pll_clk_cell, &cur);
+
+    if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
+        rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
+        rate->dsmpd != cur.dsmpd || (!cur.dsmpd && (rate->frac != cur.frac)))
+    {
+        if (!rt_clk_cell_get_parent(cell))
+        {
+            return;
+        }
+
+        rockchip_rk3036_pll_set_params(pll_clk_cell, rate);
+    }
+}
+
+/*
+ * PLL used in RK3066, RK3188 and RK3288
+ */
+
+#define RK3066_PLL_RESET_DELAY(nr)  ((nr * 500) / 24 + 1)
+
+#define RK3066_PLLCON(i)            (i * 0x4)
+#define RK3066_PLLCON0_OD_MASK      0xf
+#define RK3066_PLLCON0_OD_SHIFT     0
+#define RK3066_PLLCON0_NR_MASK      0x3f
+#define RK3066_PLLCON0_NR_SHIFT     8
+#define RK3066_PLLCON1_NF_MASK      0x1fff
+#define RK3066_PLLCON1_NF_SHIFT     0
+#define RK3066_PLLCON2_NB_MASK      0xfff
+#define RK3066_PLLCON2_NB_SHIFT     0
+#define RK3066_PLLCON3_RESET        (1 << 5)
+#define RK3066_PLLCON3_PWRDOWN      (1 << 1)
+#define RK3066_PLLCON3_BYPASS       (1 << 0)
+
+static rt_err_t rockchip_rk3066_pll_enable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0);
+    rockchip_pll_wait_lock(pll_clk_cell);
+
+    return RT_EOK;
+}
+
+static void rockchip_rk3066_pll_disable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE(
+            RK3066_PLLCON3_PWRDOWN, RK3066_PLLCON3_PWRDOWN, 0);
+}
+
+static rt_bool_t rockchip_rk3066_pll_is_enabled(struct rt_clk_cell *cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+    pllcon = HWREG32(base + RK3066_PLLCON(3));
+
+    return !(pllcon & RK3066_PLLCON3_PWRDOWN);
+}
+
+static void rockchip_rk3066_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        struct rockchip_pll_rate_table *rate)
+{
+    rt_uint32_t pllcon;
+    void *base = rockchip_pll_base(pll_clk_cell);
+
+    pllcon = HWREG32(base + RK3066_PLLCON(0));
+    rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1;
+    rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1;
+
+    pllcon = HWREG32(base + RK3066_PLLCON(1));
+    rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1;
+
+    pllcon = HWREG32(base + RK3066_PLLCON(2));
+    rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1;
+}
+
+static rt_ubase_t rockchip_rk3066_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate)
+{
+    void *base;
+    rt_uint32_t pllcon;
+    rt_uint64_t rate64 = prate;
+    struct rockchip_pll_rate_table cur;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    pllcon = HWREG32(base + RK3066_PLLCON(3));
+    if (pllcon & RK3066_PLLCON3_BYPASS)
+    {
+        return prate;
+    }
+
+    if (pll_clk_cell->sel && pll_clk_cell->scaling)
+    {
+        return pll_clk_cell->scaling;
+    }
+
+    rockchip_rk3066_pll_get_params(pll_clk_cell, &cur);
+
+    rate64 *= cur.nf;
+    rt_do_div(rate64, cur.nr);
+    rt_do_div(rate64, cur.no);
+
+    return (rt_ubase_t)rate64;
+}
+
+static rt_err_t rockchip_rk3066_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        const struct rockchip_pll_rate_table *rate)
+{
+    void *base;
+    rt_err_t err;
+    int rate_change_remuxed = 0, cur_parent;
+    struct rockchip_pll_rate_table cur;
+
+    rockchip_rk3066_pll_get_params(pll_clk_cell, &cur);
+    cur.rate = 0;
+
+    cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell);
+    if (cur_parent == PLL_MODE_NORM)
+    {
+        rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW);
+        rate_change_remuxed = 1;
+    }
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    /* Enter reset mode */
+    HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE(
+            RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0);
+
+    /* Update pll values */
+    HWREG32(base + RK3066_PLLCON(0)) =
+            HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK, RK3066_PLLCON0_NR_SHIFT) |
+            HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK, RK3066_PLLCON0_OD_SHIFT);
+
+    HWREG32(base + RK3066_PLLCON(1)) = HIWORD_UPDATE(
+            rate->nf - 1, RK3066_PLLCON1_NF_MASK, RK3066_PLLCON1_NF_SHIFT);
+    HWREG32(base + RK3066_PLLCON(2)) = HIWORD_UPDATE(
+            rate->nb - 1, RK3066_PLLCON2_NB_MASK, RK3066_PLLCON2_NB_SHIFT);
+
+    /* Leave reset and wait the reset_delay */
+    HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0);
+    rt_hw_us_delay(RK3066_PLL_RESET_DELAY(rate->nr));
+
+    /* Wait for the pll to lock */
+    if ((err = rockchip_pll_wait_lock(pll_clk_cell)))
+    {
+        rockchip_rk3066_pll_set_params(pll_clk_cell, &cur);
+    }
+
+    if (rate_change_remuxed)
+    {
+        rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM);
+    }
+
+    return err;
+}
+
+static rt_err_t rockchip_rk3066_pll_set_rate(struct rt_clk_cell *cell,
+        rt_ubase_t drate, rt_ubase_t prate)
+{
+    rt_err_t err;
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    rockchip_rk3066_pll_recalc_rate(cell, prate);
+
+    /* Get required rate settings from table */
+    if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate)))
+    {
+        return -RT_EINVAL;
+    }
+
+    if ((err = rockchip_rk3066_pll_set_params(pll_clk_cell, rate)))
+    {
+        pll_clk_cell->scaling = 0;
+    }
+
+    return err;
+}
+
+static const struct rt_clk_ops rockchip_rk3066_pll_clk_norate_ops =
+{
+    .enable = rockchip_rk3066_pll_enable,
+    .disable = rockchip_rk3066_pll_disable,
+    .is_enabled = rockchip_rk3066_pll_is_enabled,
+    .recalc_rate = rockchip_rk3066_pll_recalc_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static const struct rt_clk_ops rockchip_rk3066_pll_clk_ops =
+{
+    .enable = rockchip_rk3066_pll_enable,
+    .disable = rockchip_rk3066_pll_disable,
+    .is_enabled = rockchip_rk3066_pll_is_enabled,
+    .recalc_rate = rockchip_rk3066_pll_recalc_rate,
+    .round_rate = rockchip_pll_round_rate,
+    .set_rate = rockchip_rk3066_pll_set_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static void rockchip_rk3066_pll_init(struct rt_clk_cell *cell)
+{
+    rt_ubase_t drate;
+    struct rockchip_pll_rate_table cur;
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    if (!(pll_clk_cell->flags & ROCKCHIP_PLL_SYNC_RATE))
+    {
+        return;
+    }
+
+    drate = rt_clk_cell_get_rate(cell);
+
+    /* when no rate setting for the current rate, rely on clk_set_rate */
+    if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate)))
+    {
+        return;
+    }
+
+    rockchip_rk3066_pll_get_params(pll_clk_cell, &cur);
+
+    if (rate->nr != cur.nr || rate->no != cur.no ||
+        rate->nf != cur.nf || rate->nb != cur.nb)
+    {
+        rockchip_rk3066_pll_set_params(pll_clk_cell, rate);
+    }
+}
+
+/*
+ * PLL used in RK3399
+ */
+
+#define RK3399_PLLCON(i)                (i * 0x4)
+#define RK3399_PLLCON0_FBDIV_MASK       0xfff
+#define RK3399_PLLCON0_FBDIV_SHIFT      0
+#define RK3399_PLLCON1_REFDIV_MASK      0x3f
+#define RK3399_PLLCON1_REFDIV_SHIFT     0
+#define RK3399_PLLCON1_POSTDIV1_MASK    0x7
+#define RK3399_PLLCON1_POSTDIV1_SHIFT   8
+#define RK3399_PLLCON1_POSTDIV2_MASK    0x7
+#define RK3399_PLLCON1_POSTDIV2_SHIFT   12
+#define RK3399_PLLCON2_FRAC_MASK        0xffffff
+#define RK3399_PLLCON2_FRAC_SHIFT       0
+#define RK3399_PLLCON2_LOCK_STATUS      RT_BIT(31)
+#define RK3399_PLLCON3_PWRDOWN          RT_BIT(0)
+#define RK3399_PLLCON3_DSMPD_MASK       0x1
+#define RK3399_PLLCON3_DSMPD_SHIFT      3
+
+static rt_err_t rockchip_rk3399_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    /*
+    * Lock time typical 250, max 500 input clock cycles @24MHz
+    * So define a very safe maximum of 1000us, meaning 24000 cycles.
+    */
+    return readl_poll_timeout(base + RK3399_PLLCON(2),
+                              pllcon,
+                              pllcon & RK3399_PLLCON2_LOCK_STATUS,
+                              0, 1000);
+}
+
+static rt_err_t rockchip_rk3399_pll_enable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+    HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0);
+    rockchip_rk3399_pll_wait_lock(pll_clk_cell);
+
+    return RT_EOK;
+}
+
+static void rockchip_rk3399_pll_disable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+    HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE(
+            RK3399_PLLCON3_PWRDOWN, RK3399_PLLCON3_PWRDOWN, 0);
+}
+
+static rt_bool_t rockchip_rk3399_pll_is_enabled(struct rt_clk_cell *cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+    pllcon = HWREG32(base + RK3399_PLLCON(3));
+
+    return !(pllcon & RK3399_PLLCON3_PWRDOWN);
+}
+
+static void rockchip_rk3399_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        struct rockchip_pll_rate_table *rate)
+{
+    rt_uint32_t pllcon;
+    void *base = rockchip_pll_base(pll_clk_cell);
+
+    pllcon = HWREG32(base + RK3399_PLLCON(0));
+    rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT) & RK3399_PLLCON0_FBDIV_MASK);
+
+    pllcon = HWREG32(base + RK3399_PLLCON(1));
+    rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT) & RK3399_PLLCON1_REFDIV_MASK);
+    rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT) & RK3399_PLLCON1_POSTDIV1_MASK);
+    rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT) & RK3399_PLLCON1_POSTDIV2_MASK);
+
+    pllcon = HWREG32(base + RK3399_PLLCON(2));
+    rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT) & RK3399_PLLCON2_FRAC_MASK);
+
+    pllcon = HWREG32(base + RK3399_PLLCON(3));
+    rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT) & RK3399_PLLCON3_DSMPD_MASK);
+}
+
+static rt_ubase_t rockchip_rk3399_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate)
+{
+    rt_uint64_t rate64 = prate;
+    struct rockchip_pll_rate_table cur;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    if (pll_clk_cell->sel && pll_clk_cell->scaling)
+    {
+        return pll_clk_cell->scaling;
+    }
+
+    rockchip_rk3399_pll_get_params(pll_clk_cell, &cur);
+
+    rate64 *= cur.fbdiv;
+    rt_do_div(rate64, cur.refdiv);
+
+    if (cur.dsmpd == 0)
+    {
+        /* Fractional mode */
+        rt_uint64_t frac_rate64 = prate * cur.frac;
+
+        rt_do_div(frac_rate64, cur.refdiv);
+        rate64 += frac_rate64 >> 24;
+    }
+
+    rt_do_div(rate64, cur.postdiv1);
+    rt_do_div(rate64, cur.postdiv2);
+
+    return (rt_ubase_t)rate64;
+}
+
+static rt_err_t rockchip_rk3399_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        const struct rockchip_pll_rate_table *rate)
+{
+    rt_err_t err;
+    rt_uint32_t pllcon;
+    int rate_change_remuxed = 0, cur_parent;
+    void *base = rockchip_pll_base(pll_clk_cell);
+    struct rockchip_pll_rate_table cur;
+
+    rockchip_rk3399_pll_get_params(pll_clk_cell, &cur);
+    cur.rate = 0;
+
+    cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell);
+
+    if (cur_parent == PLL_MODE_NORM)
+    {
+        rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW);
+        rate_change_remuxed = 1;
+    }
+
+    /* Set pll power down */
+    HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE(
+            RK3399_PLLCON3_PWRDOWN, RK3399_PLLCON3_PWRDOWN, 0);
+
+    /* Update pll values */
+    HWREG32(base + RK3399_PLLCON(0)) = HIWORD_UPDATE(
+            rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK, RK3399_PLLCON0_FBDIV_SHIFT);
+
+    HWREG32(base + RK3399_PLLCON(1)) =
+            HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK, RK3399_PLLCON1_REFDIV_SHIFT) |
+            HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK, RK3399_PLLCON1_POSTDIV1_SHIFT) |
+            HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK, RK3399_PLLCON1_POSTDIV2_SHIFT);
+
+    /* xPLL CON2 is not HIWORD_MASK */
+    pllcon = HWREG32(base + RK3399_PLLCON(2));
+    pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT);
+    pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT;
+    HWREG32(base + RK3399_PLLCON(2)) = pllcon;
+
+    HWREG32(base + RK3399_PLLCON(3)) =
+            HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK, RK3399_PLLCON3_DSMPD_SHIFT);
+
+    /* Set pll power up */
+    HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0);
+
+    /* Wait for the pll to lock */
+    if ((err = rockchip_rk3399_pll_wait_lock(pll_clk_cell)))
+    {
+        rockchip_rk3399_pll_set_params(pll_clk_cell, &cur);
+    }
+
+    if (rate_change_remuxed)
+    {
+        rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM);
+    }
+
+    return err;
+}
+
+static rt_err_t rockchip_rk3399_pll_set_rate(struct rt_clk_cell *cell,
+        rt_ubase_t drate, rt_ubase_t prate)
+{
+    rt_err_t err;
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    rockchip_rk3399_pll_recalc_rate(cell, prate);
+
+    /* Get required rate settings from table */
+    if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate)))
+    {
+        return -RT_EINVAL;
+    }
+
+    if ((err = rockchip_rk3399_pll_set_params(pll_clk_cell, rate)))
+    {
+        pll_clk_cell->scaling = 0;
+    }
+
+    return err;
+}
+
+static const struct rt_clk_ops rockchip_rk3399_pll_clk_norate_ops =
+{
+    .enable = rockchip_rk3399_pll_enable,
+    .disable = rockchip_rk3399_pll_disable,
+    .is_enabled = rockchip_rk3399_pll_is_enabled,
+    .recalc_rate = rockchip_rk3399_pll_recalc_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static const struct rt_clk_ops rockchip_rk3399_pll_clk_ops =
+{
+    .enable = rockchip_rk3399_pll_enable,
+    .disable = rockchip_rk3399_pll_disable,
+    .is_enabled = rockchip_rk3399_pll_is_enabled,
+    .recalc_rate = rockchip_rk3399_pll_recalc_rate,
+    .round_rate = rockchip_pll_round_rate,
+    .set_rate = rockchip_rk3399_pll_set_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static void rockchip_rk3399_pll_init(struct rt_clk_cell *cell)
+{
+    rt_ubase_t drate;
+    struct rockchip_pll_rate_table cur;
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    if (!(pll_clk_cell->flags & ROCKCHIP_PLL_SYNC_RATE))
+    {
+        return;
+    }
+
+    drate = rt_clk_cell_get_rate(cell);
+    rate = rockchip_get_pll_settings(pll_clk_cell, drate);
+
+    /* When no rate setting for the current rate, rely on clk_set_rate */
+    if (!rate)
+    {
+        return;
+    }
+
+    rockchip_rk3399_pll_get_params(pll_clk_cell, &cur);
+
+    if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 ||
+        rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 ||
+        rate->dsmpd != cur.dsmpd ||
+        (!cur.dsmpd && (rate->frac != cur.frac)))
+    {
+        if (!rt_clk_cell_get_parent(cell))
+        {
+            return;
+        }
+
+        rockchip_rk3399_pll_set_params(pll_clk_cell, rate);
+    }
+}
+
+/*
+ * PLL used in RK3588
+ */
+#define RK3588_PLLCON(i)            (i * 0x4)
+#define RK3588_PLLCON0_M_MASK       0x3ff
+#define RK3588_PLLCON0_M_SHIFT      0
+#define RK3588_PLLCON1_P_MASK       0x3f
+#define RK3588_PLLCON1_P_SHIFT      0
+#define RK3588_PLLCON1_S_MASK       0x7
+#define RK3588_PLLCON1_S_SHIFT      6
+#define RK3588_PLLCON2_K_MASK       0xffff
+#define RK3588_PLLCON2_K_SHIFT      0
+#define RK3588_PLLCON1_PWRDOWN      RT_BIT(13)
+#define RK3588_PLLCON6_LOCK_STATUS  RT_BIT(15)
+
+static rt_err_t rockchip_rk3588_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    /*
+     * Lock time typical 250, max 500 input clock cycles @24MHz
+     * So define a very safe maximum of 1000us, meaning 24000 cycles.
+     */
+    return readl_poll_timeout(base + RK3588_PLLCON(6),
+                             pllcon,
+                             pllcon & RK3588_PLLCON6_LOCK_STATUS,
+                             0, 1000);
+}
+
+static rt_err_t rockchip_rk3588_pll_enable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0);
+
+    rockchip_rk3588_pll_wait_lock(pll_clk_cell);
+
+    rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM);
+
+    return RT_EOK;
+}
+
+static void rockchip_rk3588_pll_disable(struct rt_clk_cell *cell)
+{
+    void *base;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+
+    rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW);
+
+    HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE(
+            RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0);
+}
+
+static rt_bool_t rockchip_rk3588_pll_is_enabled(struct rt_clk_cell *cell)
+{
+    void *base;
+    rt_uint32_t pllcon;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    base = rockchip_pll_base(pll_clk_cell);
+    pllcon = HWREG32(base + RK3588_PLLCON(1));
+
+    return !(pllcon & RK3588_PLLCON1_PWRDOWN);
+}
+
+static void rockchip_rk3588_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        struct rockchip_pll_rate_table *rate)
+{
+    rt_uint32_t pllcon;
+    void *base = rockchip_pll_base(pll_clk_cell);
+
+    pllcon = HWREG32(base + RK3588_PLLCON(0));
+    rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT) & RK3588_PLLCON0_M_MASK);
+
+    pllcon = HWREG32(base + RK3588_PLLCON(1));
+    rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT) & RK3588_PLLCON1_P_MASK);
+    rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT) & RK3588_PLLCON1_S_MASK);
+
+    pllcon = HWREG32(base + RK3588_PLLCON(2));
+    rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT) & RK3588_PLLCON2_K_MASK);
+}
+
+static rt_ubase_t rockchip_rk3588_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate)
+{
+    rt_uint64_t rate64 = prate, postdiv;
+    struct rockchip_pll_rate_table cur;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    if (pll_clk_cell->sel && pll_clk_cell->scaling)
+    {
+        return pll_clk_cell->scaling;
+    }
+
+    rockchip_rk3588_pll_get_params(pll_clk_cell, &cur);
+
+    if (cur.p == 0)
+    {
+        return prate;
+    }
+
+    rate64 *= cur.m;
+    rt_do_div(rate64, cur.p);
+
+    if (cur.k & RT_BIT(15))
+    {
+        /* Fractional mode */
+        rt_uint64_t frac_rate64;
+
+        cur.k = (~(cur.k - 1)) & RK3588_PLLCON2_K_MASK;
+        frac_rate64 = prate * cur.k;
+        postdiv = cur.p;
+        postdiv *= 65536;
+        rt_do_div(frac_rate64, postdiv);
+        rate64 -= frac_rate64;
+    }
+    else
+    {
+        /* Fractional mode */
+        rt_uint64_t frac_rate64 = prate * cur.k;
+
+        postdiv = cur.p;
+        postdiv *= 65536;
+        rt_do_div(frac_rate64, postdiv);
+        rate64 += frac_rate64;
+    }
+    rate64 = rate64 >> cur.s;
+
+    if (pll_clk_cell->type == pll_type_rk3588_ddr)
+    {
+        return (rt_ubase_t)rate64 * 2;
+    }
+
+    return (rt_ubase_t)rate64;
+}
+
+static rt_base_t rockchip_rk3588_pll_round_rate(struct rt_clk_cell *cell,
+        rt_ubase_t drate, rt_ubase_t *prate)
+{
+    if ((drate < 37 * MHZ) || (drate > 4500 * MHZ))
+    {
+        return -RT_EINVAL;
+    }
+
+    return drate;
+}
+
+static rt_err_t rockchip_rk3588_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell,
+        const struct rockchip_pll_rate_table *rate)
+{
+    rt_err_t err;
+    void *base = rockchip_pll_base(pll_clk_cell);
+    int rate_change_remuxed = 0, cur_parent;
+    struct rockchip_pll_rate_table cur;
+
+    rockchip_rk3588_pll_get_params(pll_clk_cell, &cur);
+    cur.rate = 0;
+
+    if (pll_clk_cell->type == pll_type_rk3588)
+    {
+        cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell);
+
+        if (cur_parent == PLL_MODE_NORM)
+        {
+            rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW);
+            rate_change_remuxed = 1;
+        }
+    }
+
+    /* Set pll power down */
+    HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE(
+            RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0);
+
+    /* Update pll values */
+    HWREG32(base + RK3588_PLLCON(0)) = HIWORD_UPDATE(
+            rate->m, RK3588_PLLCON0_M_MASK, RK3588_PLLCON0_M_SHIFT);
+
+    HWREG32(base + RK3588_PLLCON(1)) =
+            HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK, RK3588_PLLCON1_P_SHIFT) |
+            HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK, RK3588_PLLCON1_S_SHIFT);
+
+    HWREG32(base + RK3588_PLLCON(2)) = HIWORD_UPDATE(
+            rate->k, RK3588_PLLCON2_K_MASK, RK3588_PLLCON2_K_SHIFT);
+
+    /* Set pll power up */
+    HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0);
+
+    /* Wait for the pll to lock */
+    if ((err = rockchip_rk3588_pll_wait_lock(pll_clk_cell)))
+    {
+        rockchip_rk3588_pll_set_params(pll_clk_cell, &cur);
+    }
+
+    if ((pll_clk_cell->type == pll_type_rk3588) && rate_change_remuxed)
+    {
+        rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM);
+    }
+
+    return err;
+}
+
+static rt_err_t rockchip_rk3588_pll_set_rate(struct rt_clk_cell *cell,
+        rt_ubase_t drate, rt_ubase_t prate)
+{
+    rt_err_t err;
+    const struct rockchip_pll_rate_table *rate;
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell);
+
+    rockchip_rk3588_pll_recalc_rate(cell, prate);
+
+    /* Get required rate settings from table */
+    if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate)))
+    {
+        return -RT_EINVAL;
+    }
+
+    if ((err = rockchip_rk3588_pll_set_params(pll_clk_cell, rate)))
+    {
+        pll_clk_cell->scaling = 0;
+    }
+
+    return err;
+}
+
+static const struct rt_clk_ops rockchip_rk3588_pll_clk_norate_ops =
+{
+    .enable = rockchip_rk3588_pll_enable,
+    .disable = rockchip_rk3588_pll_disable,
+    .is_enabled = rockchip_rk3588_pll_is_enabled,
+    .recalc_rate = rockchip_rk3588_pll_recalc_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+static const struct rt_clk_ops rockchip_rk3588_pll_clk_ops =
+{
+    .enable = rockchip_rk3588_pll_enable,
+    .disable = rockchip_rk3588_pll_disable,
+    .is_enabled = rockchip_rk3588_pll_is_enabled,
+    .recalc_rate = rockchip_rk3588_pll_recalc_rate,
+    .round_rate = rockchip_rk3588_pll_round_rate,
+    .set_rate = rockchip_rk3588_pll_set_rate,
+    .set_parent = rockchip_pll_set_parent,
+    .get_parent = rockchip_pll_get_parent,
+};
+
+void rockchip_pll_clk_cell_init(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(&rk_cell->cell);
+
+    rk_cell->muxdiv_offset = pll_clk_cell->mode_offset;
+    rk_cell->mux_shift = pll_clk_cell->mode_shift;
+
+    if (pll_clk_cell->type == pll_type_rk3328)
+    {
+        rk_cell->mux_mask = PLL_RK3328_MODE_MASK;
+    }
+    else
+    {
+        rk_cell->mux_mask = PLL_MODE_MASK;
+    }
+
+    rk_cell->mux_flags |= CLK_MUX_HIWORD_MASK;
+
+    rk_cell->cell.ops = &rockchip_mux_clk_ops;
+
+    switch (pll_clk_cell->type)
+    {
+    case pll_type_rk3036:
+    case pll_type_rk3328:
+        if (!pll_clk_cell->rate_table)
+        {
+            rk_cell->cell.ops = &rockchip_rk3036_pll_clk_norate_ops;
+        }
+        else
+        {
+            rk_cell->cell.ops = &rockchip_rk3036_pll_clk_ops;
+        }
+        break;
+    case pll_type_rk3066:
+        if (!pll_clk_cell->rate_table || !rk_cell->provider->grf)
+        {
+            rk_cell->cell.ops = &rockchip_rk3066_pll_clk_norate_ops;
+        }
+        else
+        {
+            rk_cell->cell.ops = &rockchip_rk3066_pll_clk_ops;
+        }
+        break;
+    case pll_type_rk3399:
+        if (!pll_clk_cell->rate_table)
+        {
+            rk_cell->cell.ops = &rockchip_rk3399_pll_clk_norate_ops;
+        }
+        else
+        {
+            rk_cell->cell.ops = &rockchip_rk3399_pll_clk_ops;
+        }
+        break;
+    case pll_type_rk3588:
+    case pll_type_rk3588_core:
+    case pll_type_rk3588_ddr:
+        if (!pll_clk_cell->rate_table)
+        {
+            rk_cell->cell.ops = &rockchip_rk3588_pll_clk_norate_ops;
+        }
+        else
+        {
+            rk_cell->cell.ops = &rockchip_rk3588_pll_clk_ops;
+        }
+        goto _set_falgs_done;
+    default:
+        break;
+    }
+
+    if (!(pll_clk_cell->flags & ROCKCHIP_PLL_ALLOW_POWER_DOWN))
+    {
+        /* Keep all plls untouched for now */
+        rk_cell->cell.flags |= RT_CLK_F_IGNORE_UNUSED;
+    }
+
+_set_falgs_done:
+    return;
+}
+
+void rockchip_pll_clk_cell_setup(struct rockchip_clk_cell *rk_cell)
+{
+    struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(&rk_cell->cell);
+
+    switch (pll_clk_cell->type)
+    {
+    case pll_type_rk3036:
+    case pll_type_rk3328:
+        if (pll_clk_cell->rate_table)
+        {
+            rockchip_rk3036_pll_init(&rk_cell->cell);
+        }
+        break;
+    case pll_type_rk3066:
+        if (pll_clk_cell->rate_table && rk_cell->provider->grf)
+        {
+            rockchip_rk3066_pll_init(&rk_cell->cell);
+        }
+        break;
+    case pll_type_rk3399:
+        if (pll_clk_cell->rate_table)
+        {
+            rockchip_rk3399_pll_init(&rk_cell->cell);
+        }
+        break;
+    default:
+        break;
+    }
+}

+ 144 - 0
bsp/rockchip/dm/clk/clk-rk-pll.h

@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_PLL_H__
+#define __CLK_RK_PLL_H__
+
+#include "clk-rk.h"
+
+enum rockchip_pll_type
+{
+    pll_type_rk3036,
+    pll_type_rk3066,
+    pll_type_rk3328,
+    pll_type_rk3399,
+    pll_type_rk3588,
+    pll_type_rk3588_core,
+    pll_type_rk3588_ddr,
+};
+
+struct rockchip_pll_rate_table
+{
+    rt_ubase_t rate;
+    union
+    {
+        struct
+        {
+            /* For RK3066 */
+            rt_uint32_t nr;
+            rt_uint32_t nf;
+            rt_uint32_t no;
+            rt_uint32_t nb;
+        };
+        struct
+        {
+            /* For RK3036/RK3399 */
+            rt_uint32_t fbdiv;
+            rt_uint32_t postdiv1;
+            rt_uint32_t refdiv;
+            rt_uint32_t postdiv2;
+            rt_uint32_t dsmpd;
+            rt_uint32_t frac;
+        };
+        struct
+        {
+            /* For RK3588 */
+            rt_uint32_t m;
+            rt_uint32_t p;
+            rt_uint32_t s;
+            rt_uint32_t k;
+        };
+    };
+};
+
+#define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \
+{                                       \
+    .rate = _rate##U,                   \
+    .nr = _nr,                          \
+    .nf = _nf,                          \
+    .no = _no,                          \
+    .nb = ((_nf) < 2) ? 1 : (_nf) >> 1, \
+}
+
+#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac) \
+{                           \
+    .rate = _rate##U,       \
+    .fbdiv = _fbdiv,        \
+    .postdiv1 = _postdiv1,  \
+    .refdiv = _refdiv,      \
+    .postdiv2 = _postdiv2,  \
+    .dsmpd = _dsmpd,        \
+    .frac = _frac,          \
+}
+
+#define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \
+{                       \
+    .rate = _rate##U,   \
+    .p = _p,            \
+    .m = _m,            \
+    .s = _s,            \
+    .k = _k,            \
+}
+
+struct rockchip_pll_clk_cell
+{
+    struct rockchip_clk_cell rk_cell;
+
+    enum rockchip_pll_type type;
+
+    int con_offset;
+    int mode_offset;
+    int mode_shift;
+    int lock_shift;
+    int grf_lock_offset;
+
+    int sel;
+    rt_ubase_t scaling;
+
+#define ROCKCHIP_PLL_SYNC_RATE          RT_BIT(0)
+#define ROCKCHIP_PLL_FIXED_MODE         RT_BIT(1)
+#define ROCKCHIP_PLL_ALLOW_POWER_DOWN   RT_BIT(2)
+    rt_uint8_t flags;
+    struct rockchip_pll_rate_table *rate_table;
+};
+
+#define PLL_RAW(_type, _id, _name, _pnames, _pnames_nr, _flags, _con, _mode, _mshift, _lshift, _glock, _pflags, _rtable) \
+{                                                               \
+    .rk_cell.cell.name = _name,                                 \
+    .rk_cell.cell.parent_names = (void *)_pnames,               \
+    .rk_cell.cell.parents_nr = _pnames_nr,                      \
+    .rk_cell.cell.flags = RT_CLK_F_GET_RATE_NOCACHE | _flags,   \
+    .rk_cell.id = _id,                                          \
+    .rk_cell.init = rockchip_pll_clk_cell_init,                 \
+    .rk_cell.setup = rockchip_pll_clk_cell_setup,               \
+    .type = _type,                                              \
+    .con_offset = _con,                                         \
+    .mode_offset = _mode,                                       \
+    .mode_shift = _mshift,                                      \
+    .lock_shift = _lshift,                                      \
+    .grf_lock_offset = _glock,                                  \
+    .flags = _pflags,                                           \
+    .rate_table = _rtable,                                      \
+}
+
+#define PLL(_type, _id, _name, _pnames, _pnames_nr, _flags, _con, _mode, _mshift, _lshift, _glock, _pflags, _rtable) \
+    (void *)&(struct rockchip_pll_clk_cell)PLL_RAW(_type, _id, _name, _pnames, _pnames_nr, _flags, _con, _mode, _mshift, _lshift, _glock, _pflags, _rtable)
+
+rt_inline struct rockchip_pll_clk_cell *cell_to_rockchip_pll_clk_cell(struct rt_clk_cell *cell)
+{
+    struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell);
+
+    return rt_container_of(rk_cell, struct rockchip_pll_clk_cell, rk_cell);
+}
+
+void rockchip_pll_clk_cell_init(struct rockchip_clk_cell *rk_cell);
+void rockchip_pll_clk_cell_setup(struct rockchip_clk_cell *rk_cell);
+
+#endif /* __CLK_RK_PLL_H__ */

+ 169 - 0
bsp/rockchip/dm/clk/clk-rk.c

@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk.h"
+
+int rockchip_gcd(int m, int n)
+{
+    while (m > 0)
+    {
+        if (n > m)
+        {
+            int t = m;
+            m = n;
+            n = t;
+        }
+        m -= n;
+    }
+
+    return n;
+}
+
+/*
+ * rational_best_approximation(31415, 10000,
+ *          (1 << 8) - 1, (1 << 5) - 1, &n, &d);
+ *
+ * you may look at given_numerator as a fixed point number,
+ * with the fractional part size described in given_denominator.
+ *
+ * for theoretical background, see:
+ * http://en.wikipedia.org/wiki/Continued_fraction
+ */
+void rational_best_approximation(rt_ubase_t given_numerator,
+        rt_ubase_t given_denominator,
+        rt_ubase_t max_numerator,
+        rt_ubase_t max_denominator,
+        rt_ubase_t *best_numerator,
+        rt_ubase_t *best_denominator)
+{
+    rt_ubase_t n, d, n0, d0, n1, d1;
+
+    n = given_numerator;
+    d = given_denominator;
+    n0 = 0;
+    d1 = 0;
+    n1 = 1;
+    d0 = 1;
+
+    for (;;)
+    {
+        rt_ubase_t t, a;
+
+        if (n1 > max_numerator || d1 > max_denominator)
+        {
+            n1 = n0;
+            d1 = d0;
+            break;
+        }
+        if (d == 0)
+        {
+            break;
+        }
+        t = d;
+        a = n / d;
+        d = n % d;
+        n = t;
+        t = n0 + a * n1;
+        n0 = n1;
+        n1 = t;
+        t = d0 + a * d1;
+        d0 = d1;
+        d1 = t;
+    }
+    *best_numerator = n1;
+    *best_denominator = d1;
+}
+
+void rockchip_clk_init(struct rockchip_clk_provider *provider,
+        struct rt_clk_cell **cells, rt_size_t cells_nr)
+{
+    for (rt_size_t i = 0; i < cells_nr; ++i)
+    {
+        struct rt_clk_cell *cell = cells[i];
+        struct rockchip_clk_cell *rk_cell;
+
+        if (!cell)
+        {
+            continue;
+        }
+
+        rk_cell = cell_to_rockchip_clk_cell(cell);
+        rk_cell->provider = provider;
+
+        if (rk_cell->init)
+        {
+            rk_cell->init(rk_cell);
+        }
+    }
+}
+
+void rockchip_clk_setup(struct rockchip_clk_provider *provider,
+        struct rt_clk_cell **cells, rt_size_t cells_nr)
+{
+    for (rt_size_t i = 0; i < cells_nr; ++i)
+    {
+        struct rt_clk_cell *cell = cells[i];
+        struct rockchip_clk_cell *rk_cell;
+
+        if (!cell)
+        {
+            continue;
+        }
+
+        rk_cell = cell_to_rockchip_clk_cell(cell);
+
+        if (rk_cell->setup)
+        {
+            rk_cell->setup(rk_cell);
+        }
+    }
+}
+
+struct rockchip_restart
+{
+    struct rt_device parent;
+
+    rt_uint32_t reg;
+    struct rockchip_clk_provider *provider;
+    void (*callback)(struct rockchip_clk_provider *provider);
+};
+
+static rt_err_t rockchip_restart_handler(struct rt_device *dev)
+{
+    struct rockchip_restart *rdev = rt_container_of(dev, struct rockchip_restart, parent);
+
+    if (rdev->callback)
+    {
+        rdev->callback(rdev->provider);
+    }
+
+    HWREG32(rdev->provider->reg_base + rdev->reg) = 0xfdb9;
+
+    return RT_EOK;
+}
+
+void rockchip_register_restart_notifier(struct rockchip_clk_provider *provider,
+        rt_uint32_t reg, void (*callback)(struct rockchip_clk_provider *provider))
+{
+    struct rockchip_restart *rdev = rt_calloc(1, sizeof(*rdev));
+
+    if (!rdev)
+    {
+        return;
+    }
+
+    rdev->reg = reg;
+    rdev->provider = provider;
+    rdev->callback = callback;
+    rt_dm_dev_set_name(&rdev->parent, "RK-CLK");
+
+    rt_dm_power_off_handler(&rdev->parent, RT_DM_POWER_OFF_MODE_RESET,
+            RT_DM_POWER_OFF_PRIO_PLATFORM, rockchip_restart_handler);
+}

+ 107 - 0
bsp/rockchip/dm/clk/clk-rk.h

@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __CLK_RK_H__
+#define __CLK_RK_H__
+
+#include <rockchip.h>
+
+struct rockchip_clk_provider
+{
+    void *reg_base;
+    struct rt_syscon *grf;
+    struct rt_syscon *pmugrf;
+};
+
+struct clk_div_table
+{
+    rt_uint32_t val;
+    rt_uint32_t div;
+};
+
+struct rockchip_clk_cell
+{
+    struct rt_clk_cell cell;
+
+    int id;
+
+    int muxdiv_offset;
+    rt_uint8_t mux_shift;
+    rt_uint8_t mux_width;
+#define CLK_MUX_INDEX_ONE                   RT_BIT(0)
+#define CLK_MUX_INDEX_BIT                   RT_BIT(1)
+#define CLK_MUX_HIWORD_MASK                 RT_BIT(2)
+#define CLK_MUX_READ_ONLY                   RT_BIT(3)
+#define CLK_MUX_ROUND_CLOSEST               RT_BIT(4)
+#define CLK_MUX_BIG_ENDIAN                  RT_BIT(5)
+    rt_uint8_t mux_flags;
+    rt_uint32_t mux_mask;
+    rt_uint32_t *mux_table;
+
+    int div_offset;
+    rt_uint8_t div_shift;
+    rt_uint8_t div_width;
+#define CLK_DIVIDER_ONE_BASED               RT_BIT(0)
+#define CLK_DIVIDER_POWER_OF_TWO            RT_BIT(1)
+#define CLK_DIVIDER_ALLOW_ZERO              RT_BIT(2)
+#define CLK_DIVIDER_HIWORD_MASK             RT_BIT(3)
+#define CLK_DIVIDER_ROUND_CLOSEST           RT_BIT(4)
+#define CLK_DIVIDER_READ_ONLY               RT_BIT(5)
+#define CLK_DIVIDER_MAX_AT_ZERO             RT_BIT(6)
+#define CLK_DIVIDER_BIG_ENDIAN              RT_BIT(7)
+
+#define CLK_FRAC_DIVIDER_ZERO_BASED         RT_BIT(0)
+#define CLK_FRAC_DIVIDER_BIG_ENDIAN         RT_BIT(1)
+#define CLK_FRAC_DIVIDER_POWER_OF_TWO_PS    RT_BIT(2)
+#define CLK_FRAC_DIVIDER_NO_LIMIT           RT_BIT(3)
+    rt_uint8_t div_flags;
+    struct clk_div_table *div_table;
+
+    int gate_offset;
+    rt_uint8_t gate_shift;
+#define CLK_GATE_SET_TO_DISABLE             RT_BIT(0)
+#define CLK_GATE_HIWORD_MASK                RT_BIT(1)
+#define CLK_GATE_BIG_ENDIAN                 RT_BIT(2)
+    rt_uint8_t gate_flags;
+
+    struct rockchip_clk_provider *provider;
+    void (*init)(struct rockchip_clk_cell *cell);
+    void (*setup)(struct rockchip_clk_cell *cell);
+};
+
+#define cell_to_rockchip_clk_cell(cell) rt_container_of(cell, struct rockchip_clk_cell, cell)
+
+#define PNAME(x)    static const char *const x
+#define PNAMES(x)   PNAME(x)[]
+
+void rational_best_approximation(rt_ubase_t given_numerator,
+        rt_ubase_t given_denominator,
+        rt_ubase_t max_numerator,
+        rt_ubase_t max_denominator,
+        rt_ubase_t *best_numerator,
+        rt_ubase_t *best_denominator);
+
+#define ROCKCHIP_SOFTRST_HIWORD_MASK    RT_BIT(0)
+
+int rockchip_gcd(int m, int n);
+
+void rockchip_clk_init(struct rockchip_clk_provider *provider,
+        struct rt_clk_cell **cells, rt_size_t cells_nr);
+
+void rockchip_clk_setup(struct rockchip_clk_provider *provider,
+        struct rt_clk_cell **cells, rt_size_t cells_nr);
+
+rt_err_t rockchip_register_softrst(struct rt_reset_controller *rstcer,
+        struct rt_ofw_node *np, const int *lookup_table, void *regs, rt_uint8_t flags);
+
+void rockchip_register_restart_notifier(struct rockchip_clk_provider *provider,
+        rt_uint32_t reg, void (*callback)(struct rockchip_clk_provider *provider));
+
+#endif /* __CLK_RK_H__ */

+ 950 - 0
bsp/rockchip/dm/clk/clk-rk3308.c

@@ -0,0 +1,950 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-composite.h"
+#include "clk-rk-cpu.h"
+#include "clk-rk-divider.h"
+#include "clk-rk-factor.h"
+#include "clk-rk-fraction-divider.h"
+#include "clk-rk-gate.h"
+#include "clk-rk.h"
+#include "clk-rk-half-divider.h"
+#include "clk-rk-mmc-phase.h"
+#include "clk-rk-muxgrf.h"
+#include "clk-rk-mux.h"
+#include "clk-rk-pll.h"
+
+#define DBG_TAG "clk.rk3308"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <dt-bindings/clock/rk3308-cru.h>
+
+#define RK3308_PLL_CON(x)           ((x) * 0x4)
+#define RK3308_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
+#define RK3308_CLKGATE_CON(x)       ((x) * 0x4 + 0x300)
+#define RK3308_GLB_SRST_FST         0xb8
+#define RK3308_SOFTRST_CON(x)       ((x) * 0x4 + 0x400)
+#define RK3308_MODE_CON             0xa0
+#define RK3308_SDMMC_CON0           0x480
+#define RK3308_SDMMC_CON1           0x484
+#define RK3308_SDIO_CON0            0x488
+#define RK3308_SDIO_CON1            0x48c
+#define RK3308_EMMC_CON0            0x490
+#define RK3308_EMMC_CON1            0x494
+#define RK3308_GRF_SOC_STATUS0      0x380
+
+#define RK3308_DIV_ACLKM_MASK       0x7
+#define RK3308_DIV_ACLKM_SHIFT      12
+#define RK3308_DIV_PCLK_DBG_MASK    0xf
+#define RK3308_DIV_PCLK_DBG_SHIFT   8
+
+struct clk_rk3308_cru
+{
+    struct rt_clk_node clk_parent;
+    struct rt_reset_controller rstc_parent;
+
+    struct rockchip_clk_provider provider;
+};
+
+static struct rockchip_pll_rate_table rk3308_pll_rates[] =
+{
+    /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+    RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0),
+    RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0),
+    RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
+    RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0),
+    RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+    RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0),
+    RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0),
+    RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0),
+    RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0),
+    RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+    RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0),
+    RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0),
+    RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0),
+    RK3036_PLL_RATE(624000000, 1, 52, 2, 1, 1, 0),
+    RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0),
+    RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
+    RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0),
+    RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0),
+    RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+    RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0),
+    RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+    RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0),
+    { /* sentinel */ },
+};
+
+#define RK3308_CLKSEL0(_aclk_core, _pclk_dbg)                   \
+{                                                               \
+    .reg = RK3308_CLKSEL_CON(0),                                \
+    .val = HIWORD_UPDATE(_aclk_core, RK3308_DIV_ACLKM_MASK,     \
+                         RK3308_DIV_ACLKM_SHIFT) |              \
+           HIWORD_UPDATE(_pclk_dbg, RK3308_DIV_PCLK_DBG_MASK,   \
+                         RK3308_DIV_PCLK_DBG_SHIFT),            \
+}
+
+#define RK3308_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg)   \
+{                                                           \
+    .prate = _prate,                                        \
+    .divs =                                                 \
+    {                                                       \
+        RK3308_CLKSEL0(_aclk_core, _pclk_dbg),              \
+    },                                                      \
+}
+
+static struct rockchip_cpu_clk_rate_table rk3308_cpu_clk_rates[] =
+{
+    RK3308_CPUCLK_RATE(1608000000, 1, 7),
+    RK3308_CPUCLK_RATE(1512000000, 1, 7),
+    RK3308_CPUCLK_RATE(1488000000, 1, 5),
+    RK3308_CPUCLK_RATE(1416000000, 1, 5),
+    RK3308_CPUCLK_RATE(1392000000, 1, 5),
+    RK3308_CPUCLK_RATE(1296000000, 1, 5),
+    RK3308_CPUCLK_RATE(1200000000, 1, 5),
+    RK3308_CPUCLK_RATE(1104000000, 1, 5),
+    RK3308_CPUCLK_RATE(1008000000, 1, 5),
+    RK3308_CPUCLK_RATE(912000000, 1, 5),
+    RK3308_CPUCLK_RATE(816000000, 1, 3),
+    RK3308_CPUCLK_RATE(696000000, 1, 3),
+    RK3308_CPUCLK_RATE(600000000, 1, 3),
+    RK3308_CPUCLK_RATE(408000000, 1, 1),
+    RK3308_CPUCLK_RATE(312000000, 1, 1),
+    RK3308_CPUCLK_RATE(216000000, 1, 1),
+    RK3308_CPUCLK_RATE(96000000, 1, 1),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3308_cpu_clk_data =
+{
+    .core_reg[0] = RK3308_CLKSEL_CON(0),
+    .div_core_shift[0] = 0,
+    .div_core_mask[0] = 0xf,
+    .num_cores = 1,
+    .mux_core_alt = 1,
+    .mux_core_main = 0,
+    .mux_core_shift = 6,
+    .mux_core_mask = 0x3,
+};
+
+PNAME(mux_pll_p)                                = "xin24m";
+PNAMES(mux_usb480m_p)                           = { "xin24m", "usb480m_phy", "clk_rtc32k" };
+PNAMES(mux_dpll_vpll0_p)                        = { "dpll", "vpll0" };
+PNAMES(mux_dpll_vpll0_xin24m_p)                 = { "dpll", "vpll0", "xin24m" };
+PNAMES(mux_dpll_vpll0_vpll1_p)                  = { "dpll", "vpll0", "vpll1" };
+PNAMES(mux_dpll_vpll0_vpll1_xin24m_p)           = { "dpll", "vpll0", "vpll1", "xin24m" };
+PNAMES(mux_vpll0_vpll1_p)                       = { "vpll0", "vpll1" };
+PNAMES(mux_vpll0_vpll1_xin24m_p)                = { "vpll0", "vpll1", "xin24m" };
+PNAMES(mux_uart0_p)                             = { "clk_uart0_src", "dummy", "clk_uart0_frac" };
+PNAMES(mux_uart1_p)                             = { "clk_uart1_src", "dummy", "clk_uart1_frac" };
+PNAMES(mux_uart2_p)                             = { "clk_uart2_src", "dummy", "clk_uart2_frac" };
+PNAMES(mux_uart3_p)                             = { "clk_uart3_src", "dummy", "clk_uart3_frac" };
+PNAMES(mux_uart4_p)                             = { "clk_uart4_src", "dummy", "clk_uart4_frac" };
+PNAMES(mux_dclk_vop_p)                          = { "dclk_vop_src", "dclk_vop_frac", "xin24m" };
+PNAMES(mux_nandc_p)                             = { "clk_nandc_div", "clk_nandc_div50" };
+PNAMES(mux_sdmmc_p)                             = { "clk_sdmmc_div", "clk_sdmmc_div50" };
+PNAMES(mux_sdio_p)                              = { "clk_sdio_div", "clk_sdio_div50" };
+PNAMES(mux_emmc_p)                              = { "clk_emmc_div", "clk_emmc_div50" };
+PNAMES(mux_mac_p)                               = { "clk_mac_src", "mac_clkin" };
+PNAMES(mux_mac_rmii_sel_p)                      = { "clk_mac_rx_tx_div20", "clk_mac_rx_tx_div2" };
+PNAMES(mux_ddrstdby_p)                          = { "clk_ddrphy1x_out", "clk_ddr_stdby_div4" };
+PNAMES(mux_rtc32k_p)                            = { "xin32k", "clk_pvtm_32k", "clk_rtc32k_frac", "clk_rtc32k_div" };
+PNAMES(mux_usbphy_ref_p)                        = { "xin24m", "clk_usbphy_ref_src" };
+PNAMES(mux_wifi_src_p)                          = { "clk_wifi_dpll", "clk_wifi_vpll0" };
+PNAMES(mux_wifi_p)                              = { "clk_wifi_osc", "clk_wifi_src" };
+PNAMES(mux_pdm_p)                               = { "clk_pdm_src", "clk_pdm_frac" };
+PNAMES(mux_i2s0_8ch_tx_p)                       = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "mclk_i2s0_8ch_in" };
+PNAMES(mux_i2s0_8ch_tx_rx_p)                    = { "clk_i2s0_8ch_tx_mux", "clk_i2s0_8ch_rx_mux"};
+PNAMES(mux_i2s0_8ch_tx_out_p)                   = { "clk_i2s0_8ch_tx", "xin12m" };
+PNAMES(mux_i2s0_8ch_rx_p)                       = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "mclk_i2s0_8ch_in" };
+PNAMES(mux_i2s0_8ch_rx_tx_p)                    = { "clk_i2s0_8ch_rx_mux", "clk_i2s0_8ch_tx_mux"};
+PNAMES(mux_i2s1_8ch_tx_p)                       = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "mclk_i2s1_8ch_in" };
+PNAMES(mux_i2s1_8ch_tx_rx_p)                    = { "clk_i2s1_8ch_tx_mux", "clk_i2s1_8ch_rx_mux"};
+PNAMES(mux_i2s1_8ch_tx_out_p)                   = { "clk_i2s1_8ch_tx", "xin12m" };
+PNAMES(mux_i2s1_8ch_rx_p)                       = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "mclk_i2s1_8ch_in" };
+PNAMES(mux_i2s1_8ch_rx_tx_p)                    = { "clk_i2s1_8ch_rx_mux", "clk_i2s1_8ch_tx_mux"};
+PNAMES(mux_i2s2_8ch_tx_p)                       = { "clk_i2s2_8ch_tx_src", "clk_i2s2_8ch_tx_frac", "mclk_i2s2_8ch_in" };
+PNAMES(mux_i2s2_8ch_tx_rx_p)                    = { "clk_i2s2_8ch_tx_mux", "clk_i2s2_8ch_rx_mux"};
+PNAMES(mux_i2s2_8ch_tx_out_p)                   = { "clk_i2s2_8ch_tx", "xin12m" };
+PNAMES(mux_i2s2_8ch_rx_p)                       = { "clk_i2s2_8ch_rx_src", "clk_i2s2_8ch_rx_frac", "mclk_i2s2_8ch_in" };
+PNAMES(mux_i2s2_8ch_rx_tx_p)                    = { "clk_i2s2_8ch_rx_mux", "clk_i2s2_8ch_tx_mux"};
+PNAMES(mux_i2s3_8ch_tx_p)                       = { "clk_i2s3_8ch_tx_src", "clk_i2s3_8ch_tx_frac", "mclk_i2s3_8ch_in" };
+PNAMES(mux_i2s3_8ch_tx_rx_p)                    = { "clk_i2s3_8ch_tx_mux", "clk_i2s3_8ch_rx_mux"};
+PNAMES(mux_i2s3_8ch_tx_out_p)                   = { "clk_i2s3_8ch_tx", "xin12m" };
+PNAMES(mux_i2s3_8ch_rx_p)                       = { "clk_i2s3_8ch_rx_src", "clk_i2s3_8ch_rx_frac", "mclk_i2s3_8ch_in" };
+PNAMES(mux_i2s3_8ch_rx_tx_p)                    = { "clk_i2s3_8ch_rx_mux", "clk_i2s3_8ch_tx_mux"};
+PNAMES(mux_i2s0_2ch_p)                          = { "clk_i2s0_2ch_src", "clk_i2s0_2ch_frac", "mclk_i2s0_2ch_in" };
+PNAMES(mux_i2s0_2ch_out_p)                      = { "clk_i2s0_2ch", "xin12m" };
+PNAMES(mux_i2s1_2ch_p)                          = { "clk_i2s1_2ch_src", "clk_i2s1_2ch_frac", "mclk_i2s1_2ch_in"};
+PNAMES(mux_i2s1_2ch_out_p)                      = { "clk_i2s1_2ch", "xin12m" };
+PNAMES(mux_spdif_tx_src_p)                      = { "clk_spdif_tx_div", "clk_spdif_tx_div50" };
+PNAMES(mux_spdif_tx_p)                          = { "clk_spdif_tx_src", "clk_spdif_tx_frac", "mclk_i2s0_2ch_in" };
+PNAMES(mux_spdif_rx_src_p)                      = { "clk_spdif_rx_div", "clk_spdif_rx_div50" };
+PNAMES(mux_spdif_rx_p)                          = { "clk_spdif_rx_src", "clk_spdif_rx_frac" };
+PNAMES(mux_uart_src_p)                          = { "usb480m", "xin24m", "dpll", "vpll0", "vpll1" };
+static rt_uint32_t uart_src_mux_idx[]   = { 3, 4, 0, 1, 2 };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clk_cell rk3308_pll_apll =
+    PLL_RAW(pll_type_rk3328, PLL_APLL, "apll", mux_pll_p, 1, 0, RK3308_PLL_CON(0), RK3308_MODE_CON,
+            0, 0, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates);
+static struct rockchip_pll_clk_cell rk3308_pll_dpll =
+    PLL_RAW(pll_type_rk3328, PLL_DPLL, "dpll", mux_pll_p, 1, 0, RK3308_PLL_CON(8), RK3308_MODE_CON,
+            2, 1, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates);
+static struct rockchip_pll_clk_cell rk3308_pll_vpll0 =
+    PLL_RAW(pll_type_rk3328, PLL_VPLL0, "vpll0", mux_pll_p, 1, 0, RK3308_PLL_CON(16), RK3308_MODE_CON,
+            4, 2, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates);
+static struct rockchip_pll_clk_cell rk3308_pll_vpll1 =
+    PLL_RAW(pll_type_rk3328, PLL_VPLL1, "vpll1", mux_pll_p, 1, 0, RK3308_PLL_CON(24), RK3308_MODE_CON,
+            6, 3, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates);
+
+static struct rockchip_clk_cell rk3308_uart0_fracmux =
+    MUX_RAW(0, "clk_uart0_mux", mux_uart0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(11), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_uart1_fracmux =
+    MUX_RAW(0, "clk_uart1_mux", mux_uart1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(14), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_uart2_fracmux =
+    MUX_RAW(0, "clk_uart2_mux", mux_uart2_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(17), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_uart3_fracmux =
+    MUX_RAW(0, "clk_uart3_mux", mux_uart3_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(20), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_uart4_fracmux =
+    MUX_RAW(0, "clk_uart4_mux", mux_uart4_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(23), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_dclk_vop_fracmux =
+    MUX_RAW(0, "dclk_vop_mux", mux_dclk_vop_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(8), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_rtc32k_fracmux =
+    MUX_RAW(SCLK_RTC32K, "clk_rtc32k", mux_rtc32k_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(2), 8, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_pdm_fracmux =
+    MUX_RAW(0, "clk_pdm_mux", mux_pdm_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(46), 15, 1, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s0_8ch_tx_fracmux =
+    MUX_RAW(SCLK_I2S0_8CH_TX_MUX, "clk_i2s0_8ch_tx_mux", mux_i2s0_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(52), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s0_8ch_rx_fracmux =
+    MUX_RAW(SCLK_I2S0_8CH_RX_MUX, "clk_i2s0_8ch_rx_mux", mux_i2s0_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(54), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s1_8ch_tx_fracmux =
+    MUX_RAW(SCLK_I2S1_8CH_TX_MUX, "clk_i2s1_8ch_tx_mux", mux_i2s1_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(56), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s1_8ch_rx_fracmux =
+    MUX_RAW(SCLK_I2S1_8CH_RX_MUX, "clk_i2s1_8ch_rx_mux", mux_i2s1_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(58), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s2_8ch_tx_fracmux =
+    MUX_RAW(SCLK_I2S2_8CH_TX_MUX, "clk_i2s2_8ch_tx_mux", mux_i2s2_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(60), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s2_8ch_rx_fracmux =
+    MUX_RAW(SCLK_I2S2_8CH_RX_MUX, "clk_i2s2_8ch_rx_mux", mux_i2s2_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(62), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s3_8ch_tx_fracmux =
+    MUX_RAW(SCLK_I2S3_8CH_TX_MUX, "clk_i2s3_8ch_tx_mux", mux_i2s3_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(64), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s3_8ch_rx_fracmux =
+    MUX_RAW(SCLK_I2S3_8CH_RX_MUX, "clk_i2s3_8ch_rx_mux", mux_i2s3_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(66), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s0_2ch_fracmux =
+    MUX_RAW(0, "clk_i2s0_2ch_mux", mux_i2s0_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(68), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_i2s1_2ch_fracmux =
+    MUX_RAW(0, "clk_i2s1_2ch_mux", mux_i2s1_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(70), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_spdif_tx_fracmux =
+    MUX_RAW(0, "clk_spdif_tx_mux", mux_spdif_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(48), 14, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3308_spdif_rx_fracmux =
+    MUX_RAW(0, "clk_spdif_rx_mux", mux_spdif_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(50), 15, 1, MFLAGS);
+
+static struct rt_clk_cell *rk3308_clk_cells[] =
+{
+    [PLL_APLL] = &rk3308_pll_apll.rk_cell.cell,
+    [PLL_DPLL] = &rk3308_pll_dpll.rk_cell.cell,
+    [PLL_VPLL0] = &rk3308_pll_vpll0.rk_cell.cell,
+    [PLL_VPLL1] = &rk3308_pll_vpll1.rk_cell.cell,
+    [ARMCLK] = CPU(ARMCLK, "armclk", &rk3308_pll_apll.rk_cell, &rk3308_pll_vpll0.rk_cell,
+            rk3308_cpu_clk_rates, RT_ARRAY_SIZE(rk3308_cpu_clk_rates), &rk3308_cpu_clk_data),
+    [USB480M] = MUX(USB480M, "usb480m", mux_usb480m_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_MODE_CON, 8, 2, MFLAGS),
+    [SCLK_RTC32K] = &rk3308_rtc32k_fracmux.cell,
+    [SCLK_PVTM_CORE] = GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0,
+            RK3308_CLKGATE_CON(0), 4, GFLAGS),
+    [SCLK_UART0] = GATE(SCLK_UART0, "clk_uart0", "clk_uart0_mux", 0,
+            RK3308_CLKGATE_CON(1), 12, GFLAGS),
+    [SCLK_UART1] = GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", 0,
+            RK3308_CLKGATE_CON(2), 0, GFLAGS),
+    [SCLK_UART2] = GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKGATE_CON(2), 4, GFLAGS),
+    [SCLK_UART3] = GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", 0,
+            RK3308_CLKGATE_CON(2), 8, GFLAGS),
+    [SCLK_UART4] = GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", 0,
+            RK3308_CLKGATE_CON(2), 12, GFLAGS),
+    [SCLK_I2C0] = COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(25), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(2), 13, GFLAGS),
+    [SCLK_I2C1] = COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(26), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(2), 14, GFLAGS),
+    [SCLK_I2C2] = COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(27), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(2), 15, GFLAGS),
+    [SCLK_I2C3] =COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(28), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(3), 0, GFLAGS),
+    [SCLK_PWM0] = COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(29), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(3), 1, GFLAGS),
+    [SCLK_SPI0] = COMPOSITE(SCLK_SPI0, "clk_spi0", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(30), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(3), 2, GFLAGS),
+    [SCLK_SPI1] = COMPOSITE(SCLK_SPI1, "clk_spi1", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(31), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(3), 3, GFLAGS),
+    [SCLK_SPI2] = COMPOSITE(SCLK_SPI2, "clk_spi2", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(32), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(3), 4, GFLAGS),
+    [SCLK_TIMER0] = GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, RK3308_CLKGATE_CON(3), 10, GFLAGS),
+    [SCLK_TIMER1] = GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, RK3308_CLKGATE_CON(3), 11, GFLAGS),
+    [SCLK_TIMER2] = GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, RK3308_CLKGATE_CON(3), 12, GFLAGS),
+    [SCLK_TIMER3] = GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, RK3308_CLKGATE_CON(3), 13, GFLAGS),
+    [SCLK_TIMER4] = GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, RK3308_CLKGATE_CON(3), 14, GFLAGS),
+    [SCLK_TIMER5] = GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, RK3308_CLKGATE_CON(3), 15, GFLAGS),
+    [SCLK_TSADC] = COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "xin24m", 0,
+            RK3308_CLKSEL_CON(33), 0, 11, DFLAGS,
+            RK3308_CLKGATE_CON(3), 5, GFLAGS),
+    [SCLK_SARADC] = COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0,
+            RK3308_CLKSEL_CON(34), 0, 11, DFLAGS,
+            RK3308_CLKGATE_CON(3), 6, GFLAGS),
+    [SCLK_OTP] = COMPOSITE_NOMUX(SCLK_OTP, "clk_otp", "xin24m", 0,
+            RK3308_CLKSEL_CON(35), 0, 4, DFLAGS,
+            RK3308_CLKGATE_CON(3), 7, GFLAGS),
+    [SCLK_OTP_USR] = COMPOSITE_NOMUX(SCLK_OTP_USR, "clk_otp_usr", "clk_otp", 0,
+            RK3308_CLKSEL_CON(35), 4, 2, DFLAGS,
+            RK3308_CLKGATE_CON(3), 8, GFLAGS),
+    [SCLK_CPU_BOOST] = GATE(SCLK_CPU_BOOST, "clk_cpu_boost", "xin24m", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(3), 9, GFLAGS),
+    [SCLK_CRYPTO] = COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_dpll_vpll0_vpll1_p, 0,
+            RK3308_CLKSEL_CON(7), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 4, GFLAGS),
+    [SCLK_CRYPTO_APK] = COMPOSITE(SCLK_CRYPTO_APK, "clk_crypto_apk", mux_dpll_vpll0_vpll1_p, 0,
+            RK3308_CLKSEL_CON(7), 14, 2, MFLAGS, 8, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 5, GFLAGS),
+    [SCLK_NANDC_DIV] = COMPOSITE(SCLK_NANDC_DIV, "clk_nandc_div", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(8), 4, GFLAGS),
+    [SCLK_NANDC_DIV50] = COMPOSITE(SCLK_NANDC_DIV50, "clk_nandc_div50", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(8), 4, GFLAGS),
+    [SCLK_NANDC] = COMPOSITE_NODIV(SCLK_NANDC, "clk_nandc", mux_nandc_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(38), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(8), 5, GFLAGS),
+    [SCLK_SDMMC_DIV] = COMPOSITE(SCLK_SDMMC_DIV, "clk_sdmmc_div", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(39), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(8), 6, GFLAGS),
+    [SCLK_SDMMC_DIV50] = COMPOSITE(SCLK_SDMMC_DIV50, "clk_sdmmc_div50", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(39), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(8), 6, GFLAGS),
+    [SCLK_SDMMC] =COMPOSITE_NODIV(SCLK_SDMMC, "clk_sdmmc", mux_sdmmc_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(39), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(8), 7, GFLAGS),
+    [SCLK_SDMMC_DRV] = MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", RK3308_SDMMC_CON0, 1),
+    [SCLK_SDMMC_SAMPLE] = MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", RK3308_SDMMC_CON1, 1),
+    [SCLK_SDIO_DIV] = COMPOSITE(SCLK_SDIO_DIV, "clk_sdio_div", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(40), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(8), 8, GFLAGS),
+    [SCLK_SDIO_DIV50] = COMPOSITE(SCLK_SDIO_DIV50, "clk_sdio_div50", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(40), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(8), 8, GFLAGS),
+    [SCLK_SDIO] = COMPOSITE_NODIV(SCLK_SDIO, "clk_sdio", mux_sdio_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(40), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(8), 9, GFLAGS),
+    [SCLK_SDIO_DRV] = MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RK3308_SDIO_CON0, 1),
+    [SCLK_SDIO_SAMPLE] = MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RK3308_SDIO_CON1, 1),
+    [SCLK_EMMC_DIV] = COMPOSITE(SCLK_EMMC_DIV, "clk_emmc_div", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(41), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(8), 10, GFLAGS),
+    [SCLK_EMMC_DIV50] = COMPOSITE(SCLK_EMMC_DIV50, "clk_emmc_div50", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(41), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(8), 10, GFLAGS),
+    [SCLK_EMMC] = COMPOSITE_NODIV(SCLK_EMMC, "clk_emmc", mux_emmc_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(41), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(8), 11, GFLAGS),
+    [SCLK_EMMC_DRV] = MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", RK3308_EMMC_CON0, 1),
+    [SCLK_EMMC_SAMPLE] = MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", RK3308_EMMC_CON1, 1),
+    [SCLK_SFC] = COMPOSITE(SCLK_SFC, "clk_sfc", mux_dpll_vpll0_vpll1_p, 0,
+            RK3308_CLKSEL_CON(42), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(8), 12, GFLAGS),
+    [SCLK_OTG_ADP] = GATE(SCLK_OTG_ADP, "clk_otg_adp", "clk_rtc32k", 0,
+            RK3308_CLKGATE_CON(8), 13, GFLAGS),
+    [SCLK_MAC_SRC] = COMPOSITE(SCLK_MAC_SRC, "clk_mac_src", mux_dpll_vpll0_vpll1_p, 0,
+            RK3308_CLKSEL_CON(43), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(8), 14, GFLAGS),
+    [SCLK_MAC] = MUX(SCLK_MAC, "clk_mac", mux_mac_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(43), 14, 1, MFLAGS),
+    [SCLK_MAC_REF] = GATE(SCLK_MAC_REF, "clk_mac_ref", "clk_mac", 0,
+            RK3308_CLKGATE_CON(9), 1, GFLAGS),
+    [SCLK_MAC_RX_TX] = GATE(SCLK_MAC_RX_TX, "clk_mac_rx_tx", "clk_mac", 0,
+            RK3308_CLKGATE_CON(9), 0, GFLAGS),
+    [SCLK_MAC_RMII] = MUX(SCLK_MAC_RMII, "clk_mac_rmii_sel", mux_mac_rmii_sel_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(43), 15, 1, MFLAGS),
+    [SCLK_DDRCLK] = COMPOSITE(SCLK_DDRCLK, "clk_ddrphy4x_src", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 3, DFLAGS,
+            RK3308_CLKGATE_CON(0), 10, GFLAGS),
+    [SCLK_PMU] = GATE(SCLK_PMU, "clk_pmu", "pclk_bus", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 6, GFLAGS),
+    [SCLK_USBPHY_REF] = COMPOSITE_NODIV(SCLK_USBPHY_REF, "clk_usbphy_ref", mux_usbphy_ref_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(72), 7, 1, MFLAGS,
+            RK3308_CLKGATE_CON(4), 8, GFLAGS),
+    [SCLK_WIFI] = COMPOSITE_NODIV(SCLK_WIFI, "clk_wifi", mux_wifi_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(44), 7, 1, MFLAGS,
+            RK3308_CLKGATE_CON(4), 1, GFLAGS),
+    [SCLK_PVTM_PMU] = GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0,
+            RK3308_CLKGATE_CON(4), 4, GFLAGS),
+    [SCLK_PDM] = GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", 0,
+            RK3308_CLKGATE_CON(10), 5, GFLAGS),
+    [SCLK_I2S0_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", mux_i2s0_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(52), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(10), 14, GFLAGS),
+    [SCLK_I2S0_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S0_8CH_TX_OUT, "clk_i2s0_8ch_tx_out", mux_i2s0_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(52), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(10), 15, GFLAGS),
+    [SCLK_I2S0_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", mux_i2s0_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(54), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(11), 2, GFLAGS),
+    [SCLK_I2S0_8CH_RX_OUT] = GATE(SCLK_I2S0_8CH_RX_OUT, "clk_i2s0_8ch_rx_out", "clk_i2s0_8ch_rx", 0,
+            RK3308_CLKGATE_CON(11), 3, GFLAGS),
+    [SCLK_I2S1_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", mux_i2s1_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(56), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(11), 6, GFLAGS),
+    [SCLK_I2S1_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S1_8CH_TX_OUT, "clk_i2s1_8ch_tx_out", mux_i2s1_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(56), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(11), 7, GFLAGS),
+    [SCLK_I2S1_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", mux_i2s1_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(58), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(11), 10, GFLAGS),
+    [SCLK_I2S1_8CH_RX_OUT] = GATE(SCLK_I2S1_8CH_RX_OUT, "clk_i2s1_8ch_rx_out", "clk_i2s1_8ch_rx", 0,
+            RK3308_CLKGATE_CON(11), 11, GFLAGS),
+    [SCLK_I2S2_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S2_8CH_TX, "clk_i2s2_8ch_tx", mux_i2s2_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(60), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(11), 14, GFLAGS),
+    [SCLK_I2S2_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S2_8CH_TX_OUT, "clk_i2s2_8ch_tx_out", mux_i2s2_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(60), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(11), 15, GFLAGS),
+    [SCLK_I2S2_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S2_8CH_RX, "clk_i2s2_8ch_rx", mux_i2s2_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(62), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(12), 2, GFLAGS),
+    [SCLK_I2S2_8CH_RX_OUT] = GATE(SCLK_I2S2_8CH_RX_OUT, "clk_i2s2_8ch_rx_out", "clk_i2s2_8ch_rx", 0,
+            RK3308_CLKGATE_CON(12), 3, GFLAGS),
+    [SCLK_I2S3_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S3_8CH_TX, "clk_i2s3_8ch_tx", mux_i2s3_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(64), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(12), 6, GFLAGS),
+    [SCLK_I2S3_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S3_8CH_TX_OUT, "clk_i2s3_8ch_tx_out", mux_i2s3_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(64), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(12), 7, GFLAGS),
+    [SCLK_I2S3_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S3_8CH_RX, "clk_i2s3_8ch_rx", mux_i2s3_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(66), 12, 1, MFLAGS,
+            RK3308_CLKGATE_CON(12), 10, GFLAGS),
+    [SCLK_I2S3_8CH_RX_OUT] = GATE(SCLK_I2S3_8CH_RX_OUT, "clk_i2s3_8ch_rx_out", "clk_i2s3_8ch_rx", 0,
+            RK3308_CLKGATE_CON(12), 11, GFLAGS),
+    [SCLK_I2S0_2CH] = GATE(SCLK_I2S0_2CH, "clk_i2s0_2ch", "clk_i2s0_2ch_mux", 0,
+            RK3308_CLKGATE_CON(12), 14, GFLAGS),
+    [SCLK_I2S0_2CH_OUT] = COMPOSITE_NODIV(SCLK_I2S0_2CH_OUT, "clk_i2s0_2ch_out", mux_i2s0_2ch_out_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(68), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(12), 15, GFLAGS),
+    [SCLK_I2S1_2CH] = GATE(SCLK_I2S1_2CH, "clk_i2s1_2ch", "clk_i2s1_2ch_mux", 0,
+            RK3308_CLKGATE_CON(13), 2, GFLAGS),
+    [SCLK_I2S1_2CH_OUT] = COMPOSITE_NODIV(SCLK_I2S1_2CH_OUT, "clk_i2s1_2ch_out", mux_i2s1_2ch_out_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(70), 15, 1, MFLAGS,
+            RK3308_CLKGATE_CON(13), 3, GFLAGS),
+    [SCLK_SPDIF_TX_DIV] = COMPOSITE(SCLK_SPDIF_TX_DIV, "clk_spdif_tx_div", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(10), 6, GFLAGS),
+    [SCLK_SPDIF_TX_DIV50] = COMPOSITE(SCLK_SPDIF_TX_DIV50, "clk_spdif_tx_div50", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(10), 6, GFLAGS),
+    [SCLK_SPDIF_TX] = GATE(SCLK_SPDIF_TX, "clk_spdif_tx", "clk_spdif_tx_mux", 0,
+            RK3308_CLKGATE_CON(10), 8, GFLAGS),
+    [SCLK_SPDIF_RX_DIV] = COMPOSITE(SCLK_SPDIF_RX_DIV, "clk_spdif_rx_div", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(10), 9, GFLAGS),
+    [SCLK_SPDIF_RX_DIV50] = COMPOSITE(SCLK_SPDIF_RX_DIV50, "clk_spdif_rx_div50", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(10), 9, GFLAGS),
+    [SCLK_SPDIF_RX] = GATE(SCLK_SPDIF_RX, "clk_spdif_rx", "clk_spdif_rx_mux", 0,
+            RK3308_CLKGATE_CON(10), 11, GFLAGS),
+    [SCLK_I2S0_8CH_TX_MUX] = &rk3308_i2s0_8ch_tx_fracmux.cell,
+    [SCLK_I2S0_8CH_RX_MUX] = &rk3308_i2s0_8ch_rx_fracmux.cell,
+    [SCLK_I2S1_8CH_TX_MUX] = &rk3308_i2s1_8ch_tx_fracmux.cell,
+    [SCLK_I2S1_8CH_RX_MUX] = &rk3308_i2s1_8ch_rx_fracmux.cell,
+    [SCLK_I2S2_8CH_TX_MUX] = &rk3308_i2s2_8ch_tx_fracmux.cell,
+    [SCLK_I2S2_8CH_RX_MUX] = &rk3308_i2s2_8ch_rx_fracmux.cell,
+    [SCLK_I2S3_8CH_TX_MUX] = &rk3308_i2s3_8ch_tx_fracmux.cell,
+    [SCLK_I2S3_8CH_RX_MUX] = &rk3308_i2s3_8ch_rx_fracmux.cell,
+    [SCLK_I2S0_8CH_TX_SRC] = COMPOSITE(SCLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(52), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(10), 12, GFLAGS),
+    [SCLK_I2S0_8CH_RX_SRC] = COMPOSITE(SCLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(54), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(11), 0, GFLAGS),
+    [SCLK_I2S1_8CH_TX_SRC] = COMPOSITE(SCLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(56), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(11), 4, GFLAGS),
+    [SCLK_I2S1_8CH_RX_SRC] = COMPOSITE(SCLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(58), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(11), 8, GFLAGS),
+    [SCLK_I2S2_8CH_TX_SRC] = COMPOSITE(SCLK_I2S2_8CH_TX_SRC, "clk_i2s2_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(60), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(11), 12, GFLAGS),
+    [SCLK_I2S2_8CH_RX_SRC] = COMPOSITE(SCLK_I2S2_8CH_RX_SRC, "clk_i2s2_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(62), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(12), 0, GFLAGS),
+    [SCLK_I2S3_8CH_TX_SRC] = COMPOSITE(SCLK_I2S3_8CH_TX_SRC, "clk_i2s3_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(64), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(12), 4, GFLAGS),
+    [SCLK_I2S3_8CH_RX_SRC] = COMPOSITE(SCLK_I2S3_8CH_RX_SRC, "clk_i2s3_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(66), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(12), 8, GFLAGS),
+    [SCLK_I2S0_2CH_SRC] = COMPOSITE(SCLK_I2S0_2CH_SRC, "clk_i2s0_2ch_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(68), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(12), 12, GFLAGS),
+    [SCLK_I2S1_2CH_SRC] = COMPOSITE(SCLK_I2S1_2CH_SRC, "clk_i2s1_2ch_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(70), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(13), 0, GFLAGS),
+    [SCLK_PWM1] = COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(74), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(15), 0, GFLAGS),
+    [SCLK_PWM2] = COMPOSITE(SCLK_PWM2, "clk_pwm2", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(75), 14, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(15), 1, GFLAGS),
+    [SCLK_OWIRE] = COMPOSITE(SCLK_OWIRE, "clk_owire", mux_dpll_vpll0_xin24m_p, 0,
+            RK3308_CLKSEL_CON(44), 14, 2, MFLAGS, 8, 6, DFLAGS,
+            RK3308_CLKGATE_CON(8), 15, GFLAGS),
+    [DCLK_VOP] = GATE(DCLK_VOP, "dclk_vop", "dclk_vop_mux", 0,
+            RK3308_CLKGATE_CON(1), 8, GFLAGS),
+    [ACLK_BUS_SRC] = COMPOSITE_NODIV(ACLK_BUS_SRC, "clk_bus_src", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(5), 6, 2, MFLAGS,
+            RK3308_CLKGATE_CON(1), 0, GFLAGS),
+    [ACLK_BUS] = COMPOSITE_NOMUX(ACLK_BUS, "aclk_bus", "clk_bus_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(5), 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 1, GFLAGS),
+    [ACLK_PERI_SRC] = COMPOSITE_NODIV(ACLK_PERI_SRC, "clk_peri_src", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(36), 6, 2, MFLAGS,
+            RK3308_CLKGATE_CON(8), 0, GFLAGS),
+    [ACLK_PERI] = COMPOSITE_NOMUX(ACLK_PERI, "aclk_peri", "clk_peri_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(36), 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(8), 1, GFLAGS),
+    [ACLK_MAC] = GATE(ACLK_MAC, "aclk_mac", "aclk_peri", 0, RK3308_CLKGATE_CON(9), 4, GFLAGS),
+    [ACLK_CRYPTO] = GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_bus", 0, RK3308_CLKGATE_CON(5), 2, GFLAGS),
+    [ACLK_VOP] = GATE(ACLK_VOP, "aclk_vop", "aclk_bus", 0, RK3308_CLKGATE_CON(5), 3, GFLAGS),
+    [ACLK_GIC] = GATE(ACLK_GIC, "aclk_gic", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 4, GFLAGS),
+    [ACLK_DMAC0] = SGRF_GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus"),
+    [ACLK_DMAC1] = SGRF_GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus"),
+    [HCLK_BUS] = COMPOSITE_NOMUX(HCLK_BUS, "hclk_bus", "clk_bus_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(6), 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 2, GFLAGS),
+    [HCLK_PERI] = COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "clk_peri_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(37), 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(8), 2, GFLAGS),
+    [HCLK_AUDIO] = COMPOSITE_NOMUX(HCLK_AUDIO, "hclk_audio", "clk_audio_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(45), 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(10), 1, GFLAGS),
+    [HCLK_NANDC] = GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 6, GFLAGS),
+    [HCLK_SDMMC] = GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 7, GFLAGS),
+    [HCLK_SDIO] = GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 8, GFLAGS),
+    [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 9, GFLAGS),
+    [HCLK_SFC] = GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 10, GFLAGS),
+    [HCLK_OTG] = GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 11, GFLAGS),
+    [HCLK_HOST] = GATE(HCLK_HOST, "hclk_host", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 12, GFLAGS),
+    [HCLK_HOST_ARB] = GATE(HCLK_HOST_ARB, "hclk_host_arb", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 13, GFLAGS),
+    [HCLK_PDM] = GATE(HCLK_PDM, "hclk_pdm", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 1, GFLAGS),
+    [HCLK_SPDIFTX] = GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 2, GFLAGS),
+    [HCLK_SPDIFRX] = GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 3, GFLAGS),
+    [HCLK_I2S0_8CH] = GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 4, GFLAGS),
+    [HCLK_I2S1_8CH] = GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 5, GFLAGS),
+    [HCLK_I2S2_8CH] = GATE(HCLK_I2S2_8CH, "hclk_i2s2_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 6, GFLAGS),
+    [HCLK_I2S3_8CH] = GATE(HCLK_I2S3_8CH, "hclk_i2s3_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 7, GFLAGS),
+    [HCLK_I2S0_2CH] = GATE(HCLK_I2S0_2CH, "hclk_i2s0_2ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 8, GFLAGS),
+    [HCLK_I2S1_2CH] = GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 9, GFLAGS),
+    [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 10, GFLAGS),
+    [HCLK_CRYPTO] = GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_bus", 0, RK3308_CLKGATE_CON(5), 7, GFLAGS),
+    [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_bus", 0, RK3308_CLKGATE_CON(5), 8, GFLAGS),
+    [PCLK_BUS] = COMPOSITE_NOMUX(PCLK_BUS, "pclk_bus", "clk_bus_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(6), 8, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 3, GFLAGS),
+    [PCLK_DDR] = GATE(PCLK_DDR, "pclk_ddr", "pclk_bus", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 15, GFLAGS),
+    [PCLK_PERI] = COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "clk_peri_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(37), 8, 5, DFLAGS,
+            RK3308_CLKGATE_CON(8), 3, GFLAGS),
+    [PCLK_PMU] = GATE(PCLK_PMU, "pclk_pmu", "pclk_bus", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 5, GFLAGS),
+    [PCLK_AUDIO] = COMPOSITE_NOMUX(PCLK_AUDIO, "pclk_audio", "clk_audio_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(45), 8, 5, DFLAGS,
+            RK3308_CLKGATE_CON(10), 2, GFLAGS),
+    [PCLK_MAC] = GATE(PCLK_MAC, "pclk_mac", "pclk_peri", 0, RK3308_CLKGATE_CON(9), 15, GFLAGS),
+    [PCLK_ACODEC] = GATE(PCLK_ACODEC, "pclk_acodec", "pclk_audio", 0, RK3308_CLKGATE_CON(14), 12, GFLAGS),
+    [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 10, GFLAGS),
+    [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 11, GFLAGS),
+    [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 12, GFLAGS),
+    [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 13, GFLAGS),
+    [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 14, GFLAGS),
+    [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 15, GFLAGS),
+    [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 0, GFLAGS),
+    [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 1, GFLAGS),
+    [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 2, GFLAGS),
+    [PCLK_PWM0] = GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 3, GFLAGS),
+    [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 4, GFLAGS),
+    [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 5, GFLAGS),
+    [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 6, GFLAGS),
+    [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 7, GFLAGS),
+    [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 8, GFLAGS),
+    [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 9, GFLAGS),
+    [PCLK_OTP_NS] = GATE(PCLK_OTP_NS, "pclk_otp_ns", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 10, GFLAGS),
+    [PCLK_WDT] = SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_bus"),
+    [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 12, GFLAGS),
+    [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 13, GFLAGS),
+    [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 14, GFLAGS),
+    [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 15, GFLAGS),
+    [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 0, RK3308_CLKGATE_CON(7), 0, GFLAGS),
+    [PCLK_SGRF] = GATE(PCLK_SGRF, "pclk_sgrf", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 1, GFLAGS),
+    [PCLK_GRF] = GATE(PCLK_GRF, "pclk_grf", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 2, GFLAGS),
+    [PCLK_USBSD_DET] = GATE(PCLK_USBSD_DET, "pclk_usbsd_det", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 3, GFLAGS),
+    [PCLK_DDR_UPCTL] = GATE(PCLK_DDR_UPCTL, "pclk_ddr_upctl", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 4, GFLAGS),
+    [PCLK_DDR_MON] = GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 5, GFLAGS),
+    [PCLK_DDRPHY] = GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 6, GFLAGS),
+    [PCLK_DDR_STDBY] = GATE(PCLK_DDR_STDBY, "pclk_ddr_stdby", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 7, GFLAGS),
+    [PCLK_USB_GRF] = GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 8, GFLAGS),
+    [PCLK_CRU] = GATE(PCLK_CRU, "pclk_cru", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 9, GFLAGS),
+    [PCLK_OTP_PHY] = GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_bus", 0, RK3308_CLKGATE_CON(7), 10, GFLAGS),
+    [PCLK_CPU_BOOST] = GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 11, GFLAGS),
+    [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 12, GFLAGS),
+    [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 13, GFLAGS),
+    [PCLK_CAN] = GATE(PCLK_CAN, "pclk_can", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 14, GFLAGS),
+    [PCLK_OWIRE] = GATE(PCLK_OWIRE, "pclk_owire", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 15, GFLAGS),
+
+    FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+    GATE(0, "apll_core", "apll", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(0), 0, GFLAGS),
+    GATE(0, "vpll0_core", "vpll0", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(0), 0, GFLAGS),
+    GATE(0, "vpll1_core", "vpll1", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(0), 0, GFLAGS),
+    COMPOSITE_NOMUX(0, "pclk_core_dbg", "armclk", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(0), 8, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3308_CLKGATE_CON(0), 2, GFLAGS),
+    COMPOSITE_NOMUX(0, "aclk_core", "armclk", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(0), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3308_CLKGATE_CON(0), 1, GFLAGS),
+    GATE(0, "clk_jtag", "jtag_clkin", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(0), 3, GFLAGS),
+    COMPOSITE_MUXTBL(0, "clk_uart0_src", mux_uart_src_p, 0,
+            RK3308_CLKSEL_CON(10), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 9, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(12), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3308_CLKGATE_CON(1), 11, GFLAGS,
+            &rk3308_uart0_fracmux),
+    COMPOSITE_MUXTBL(0, "clk_uart1_src", mux_uart_src_p, 0,
+            RK3308_CLKSEL_CON(13), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(1), 13, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(15), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3308_CLKGATE_CON(1), 15, GFLAGS,
+            &rk3308_uart1_fracmux),
+    COMPOSITE_MUXTBL(0, "clk_uart2_src", mux_uart_src_p, 0,
+            RK3308_CLKSEL_CON(16), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(2), 1, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(18), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3308_CLKGATE_CON(2), 3, GFLAGS,
+            &rk3308_uart2_fracmux),
+    COMPOSITE_MUXTBL(0, "clk_uart3_src", mux_uart_src_p, 0,
+            RK3308_CLKSEL_CON(19), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(2), 5, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(21), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3308_CLKGATE_CON(2), 7, GFLAGS,
+            &rk3308_uart3_fracmux),
+    COMPOSITE_MUXTBL(0, "clk_uart4_src", mux_uart_src_p, 0,
+            RK3308_CLKSEL_CON(22), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS,
+            RK3308_CLKGATE_CON(2), 9, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(24), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3308_CLKGATE_CON(2), 11, GFLAGS,
+            &rk3308_uart4_fracmux),
+    COMPOSITE(0, "dclk_vop_src", mux_dpll_vpll0_vpll1_p, 0,
+            RK3308_CLKSEL_CON(8), 10, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3308_CLKGATE_CON(1), 6, GFLAGS),
+    COMPOSITE_FRACMUX(0, "dclk_vop_frac", "dclk_vop_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(9), 0,
+            RK3308_CLKGATE_CON(1), 7, GFLAGS,
+            &rk3308_dclk_vop_fracmux),
+
+    &rk3308_uart0_fracmux.cell,
+    &rk3308_uart1_fracmux.cell,
+    &rk3308_uart2_fracmux.cell,
+    &rk3308_uart3_fracmux.cell,
+    &rk3308_uart4_fracmux.cell,
+    &rk3308_dclk_vop_fracmux.cell,
+    &rk3308_pdm_fracmux.cell,
+    &rk3308_i2s0_2ch_fracmux.cell,
+    &rk3308_i2s1_2ch_fracmux.cell,
+    &rk3308_spdif_tx_fracmux.cell,
+    &rk3308_spdif_rx_fracmux.cell,
+
+    FACTOR(0, "clk_mac_rx_tx_div2", "clk_mac_rx_tx", 0, 1, 2),
+    FACTOR(0, "clk_mac_rx_tx_div20", "clk_mac_rx_tx", 0, 1, 20),
+    GATE(0, "clk_ddr_mon_timer", "xin24m", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(0), 12, GFLAGS),
+    GATE(0, "clk_ddr_mon", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 10, GFLAGS),
+    GATE(0, "clk_ddr_upctrl", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 11, GFLAGS),
+    GATE(0, "clk_ddr_msch", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 12, GFLAGS),
+    GATE(0, "clk_ddr_msch_peribus", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKGATE_CON(4), 13, GFLAGS),
+    GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKGATE_CON(0), 11, GFLAGS),
+    FACTOR_GATE(0, "clk_ddr_stdby_div4", "clk_ddrphy4x", RT_CLK_F_IGNORE_UNUSED, 1, 4,
+            RK3308_CLKGATE_CON(0), 13, GFLAGS),
+    COMPOSITE_NODIV(0, "clk_ddrstdby", mux_ddrstdby_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(1), 8, 1, MFLAGS,
+            RK3308_CLKGATE_CON(4), 14, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_rtc32k_frac", "xin24m", RT_CLK_F_IGNORE_UNUSED,
+            RK3308_CLKSEL_CON(3), 0,
+            RK3308_CLKGATE_CON(4), 3, GFLAGS,
+            &rk3308_rtc32k_fracmux),
+    MUX(0, "clk_rtc32k_div_src", mux_vpll0_vpll1_p, 0,
+            RK3308_CLKSEL_CON(2), 10, 1, MFLAGS),
+    COMPOSITE_NOMUX(0, "clk_rtc32k_div", "clk_rtc32k_div_src", RT_CLK_F_IGNORE_UNUSED | RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(4), 0, 16, DFLAGS,
+            RK3308_CLKGATE_CON(4), 2, GFLAGS),
+    COMPOSITE(0, "clk_usbphy_ref_src", mux_dpll_vpll0_p, 0,
+            RK3308_CLKSEL_CON(72), 6, 1, MFLAGS, 0, 6, DFLAGS,
+            RK3308_CLKGATE_CON(4), 7, GFLAGS),
+    GATE(0, "clk_wifi_dpll", "dpll", 0,
+            RK3308_CLKGATE_CON(15), 2, GFLAGS),
+    GATE(0, "clk_wifi_vpll0", "vpll0", 0,
+            RK3308_CLKGATE_CON(15), 3, GFLAGS),
+    GATE(0, "clk_wifi_osc", "xin24m", 0,
+            RK3308_CLKGATE_CON(15), 4, GFLAGS),
+    COMPOSITE(0, "clk_wifi_src", mux_wifi_src_p, 0,
+            RK3308_CLKSEL_CON(44), 6, 1, MFLAGS, 0, 6, DFLAGS,
+            RK3308_CLKGATE_CON(4), 0, GFLAGS),
+    COMPOSITE_NODIV(0, "clk_audio_src", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3308_CLKSEL_CON(45), 6, 2, MFLAGS,
+            RK3308_CLKGATE_CON(10), 0, GFLAGS),
+    COMPOSITE(0, "clk_pdm_src", mux_vpll0_vpll1_xin24m_p, 0,
+            RK3308_CLKSEL_CON(46), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3308_CLKGATE_CON(10), 3, GFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_pdm_frac", "clk_pdm_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(47), 0,
+            RK3308_CLKGATE_CON(10), 4, GFLAGS,
+            &rk3308_pdm_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(53), 0,
+            RK3308_CLKGATE_CON(10), 13, GFLAGS,
+            &rk3308_i2s0_8ch_tx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(55), 0,
+            RK3308_CLKGATE_CON(11), 1, GFLAGS,
+            &rk3308_i2s0_8ch_rx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(57), 0,
+            RK3308_CLKGATE_CON(11), 5, GFLAGS,
+            &rk3308_i2s1_8ch_tx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(59), 0,
+            RK3308_CLKGATE_CON(11), 9, GFLAGS,
+            &rk3308_i2s1_8ch_rx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s2_8ch_tx_frac", "clk_i2s2_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(61), 0,
+            RK3308_CLKGATE_CON(11), 13, GFLAGS,
+            &rk3308_i2s2_8ch_tx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s2_8ch_rx_frac", "clk_i2s2_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(63), 0,
+            RK3308_CLKGATE_CON(12), 1, GFLAGS,
+            &rk3308_i2s2_8ch_rx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s3_8ch_tx_frac", "clk_i2s3_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(65), 0,
+            RK3308_CLKGATE_CON(12), 5, GFLAGS,
+            &rk3308_i2s3_8ch_tx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s3_8ch_rx_frac", "clk_i2s3_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(67), 0,
+            RK3308_CLKGATE_CON(12), 9, GFLAGS,
+            &rk3308_i2s3_8ch_rx_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s0_2ch_frac", "clk_i2s0_2ch_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(69), 0,
+            RK3308_CLKGATE_CON(12), 13, GFLAGS,
+            &rk3308_i2s0_2ch_fracmux),
+    COMPOSITE_FRACMUX(0, "clk_i2s1_2ch_frac", "clk_i2s1_2ch_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(71), 0,
+            RK3308_CLKGATE_CON(13), 1, GFLAGS,
+            &rk3308_i2s1_2ch_fracmux),
+    MUX(0, "clk_spdif_tx_src", mux_spdif_tx_src_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(48), 12, 1, MFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_spdif_tx_frac", "clk_spdif_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(49), 0,
+            RK3308_CLKGATE_CON(10), 7, GFLAGS,
+            &rk3308_spdif_tx_fracmux),
+    MUX(0, "clk_spdif_rx_src", mux_spdif_rx_src_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(50), 14, 1, MFLAGS),
+    COMPOSITE_FRACMUX(0, "clk_spdif_rx_frac", "clk_spdif_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(51), 0,
+            RK3308_CLKGATE_CON(10), 10, GFLAGS,
+            &rk3308_spdif_rx_fracmux),
+    GATE(0, "aclk_core_niu", "aclk_core", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 5, GFLAGS),
+    GATE(0, "pclk_core_dbg_niu", "aclk_core", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 6, GFLAGS),
+    GATE(0, "pclk_core_dbg_daplite", "pclk_core_dbg", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 7, GFLAGS),
+    GATE(0, "aclk_core_perf", "pclk_core_dbg", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 8, GFLAGS),
+    GATE(0, "pclk_core_grf", "pclk_core_dbg", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 9, GFLAGS),
+    GATE(0, "aclk_peri_niu", "aclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 2, GFLAGS),
+    GATE(0, "aclk_peribus_niu", "aclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 3, GFLAGS),
+    GATE(0, "hclk_peri_niu", "hclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 5, GFLAGS),
+    GATE(0, "pclk_peri_niu", "pclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 14, GFLAGS),
+    GATE(0, "hclk_audio_niu", "hclk_audio", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(14), 0, GFLAGS),
+    GATE(0, "pclk_audio_niu", "pclk_audio", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(14), 11, GFLAGS),
+    GATE(0, "aclk_bus_niu", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 0, GFLAGS),
+    GATE(0, "aclk_intmem", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 1, GFLAGS),
+    GATE(0, "hclk_bus_niu", "hclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 5, GFLAGS),
+    GATE(0, "hclk_rom", "hclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 6, GFLAGS),
+    GATE(0, "pclk_bus_niu", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 9, GFLAGS),
+    COMPOSITE_FRACMUX(0, "dclk_vop_frac", "dclk_vop_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3308_CLKSEL_CON(9), 0,
+            RK3308_CLKGATE_CON(1), 7, GFLAGS,
+            &rk3308_dclk_vop_fracmux),
+};
+
+static rt_err_t clk_rk3308_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_device *dev = &pdev->parent;
+    struct clk_rk3308_cru *cru = rt_calloc(1, sizeof(*cru));
+
+    if (!cru)
+    {
+        return -RT_ENOMEM;
+    }
+
+    cru->provider.reg_base = rt_dm_dev_iomap(dev, 0);
+
+    if (!cru->provider.reg_base)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf");
+    cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf");
+
+    cru->clk_parent.dev = dev;
+    cru->clk_parent.cells = rk3308_clk_cells;
+    cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3308_clk_cells);
+
+    rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rt_clk_register(&cru->clk_parent)))
+    {
+        goto _fail;
+    }
+
+    rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL,
+        cru->provider.reg_base + RK3308_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK)))
+    {
+        goto _clk_unregister;
+    }
+
+    rockchip_register_restart_notifier(&cru->provider, RK3308_GLB_SRST_FST, RT_NULL);
+
+    return RT_EOK;
+
+_clk_unregister:
+    rt_clk_unregister(&cru->clk_parent);
+
+_fail:
+    if (cru->provider.reg_base)
+    {
+        rt_iounmap(cru->provider.reg_base);
+    }
+
+    rt_free(cru);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id clk_rk3308_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3308-cru", },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver clk_rk3308_driver =
+{
+    .name = "clk-rk3308",
+    .ids = clk_rk3308_ofw_ids,
+
+    .probe = clk_rk3308_probe,
+};
+
+static int clk_rk3308_register(void)
+{
+    rt_platform_driver_register(&clk_rk3308_driver);
+
+    return 0;
+}
+INIT_SUBSYS_EXPORT(clk_rk3308_register);

+ 1488 - 0
bsp/rockchip/dm/clk/clk-rk3568.c

@@ -0,0 +1,1488 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-composite.h"
+#include "clk-rk-cpu.h"
+#include "clk-rk-divider.h"
+#include "clk-rk-factor.h"
+#include "clk-rk-fraction-divider.h"
+#include "clk-rk-gate.h"
+#include "clk-rk.h"
+#include "clk-rk-half-divider.h"
+#include "clk-rk-mmc-phase.h"
+#include "clk-rk-muxgrf.h"
+#include "clk-rk-mux.h"
+#include "clk-rk-pll.h"
+
+#define DBG_TAG "clk.rk3568"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <dt-bindings/clock/rk3568-cru.h>
+
+#define RK3568_PLL_CON(x)               ((x) * 0x4)
+#define RK3568_MODE_CON0                0xc0
+#define RK3568_MISC_CON0                0xc4
+#define RK3568_MISC_CON1                0xc8
+#define RK3568_MISC_CON2                0xcc
+#define RK3568_GLB_CNT_TH               0xd0
+#define RK3568_GLB_SRST_FST             0xd4
+#define RK3568_GLB_SRST_SND             0xd8
+#define RK3568_GLB_RST_CON              0xdc
+#define RK3568_GLB_RST_ST               0xe0
+#define RK3568_CLKSEL_CON(x)            ((x) * 0x4 + 0x100)
+#define RK3568_CLKGATE_CON(x)           ((x) * 0x4 + 0x300)
+#define RK3568_SOFTRST_CON(x)           ((x) * 0x4 + 0x400)
+#define RK3568_SDMMC0_CON0              0x580
+#define RK3568_SDMMC0_CON1              0x584
+#define RK3568_SDMMC1_CON0              0x588
+#define RK3568_SDMMC1_CON1              0x58c
+#define RK3568_SDMMC2_CON0              0x590
+#define RK3568_SDMMC2_CON1              0x594
+#define RK3568_EMMC_CON0                0x598
+#define RK3568_EMMC_CON1                0x59c
+
+#define RK3568_PMU_PLL_CON(x)           ((x) * 0x4)
+#define RK3568_PMU_MODE_CON0            0x80
+#define RK3568_PMU_CLKSEL_CON(x)        ((x) * 0x4 + 0x100)
+#define RK3568_PMU_CLKGATE_CON(x)       ((x) * 0x4 + 0x180)
+#define RK3568_PMU_SOFTRST_CON(x)       ((x) * 0x4 + 0x200)
+
+#define RK3568_GRF_SOC_CON1             0x504
+#define RK3568_GRF_SOC_CON2             0x508
+#define RK3568_GRF_SOC_STATUS0          0x580
+#define RK3568_PMU_GRF_SOC_CON0         0x100
+
+#define RK3568_FRAC_MAX_PRATE           1000000000
+#define RK3568_SPDIF_FRAC_MAX_PRATE     600000000
+#define RK3568_UART_FRAC_MAX_PRATE      600000000
+#define RK3568_DCLK_PARENT_MAX_PRATE    600000000
+
+#define RK3568_DIV_ATCLK_CORE_MASK      0x1f
+#define RK3568_DIV_ATCLK_CORE_SHIFT     0
+#define RK3568_DIV_GICCLK_CORE_MASK     0x1f
+#define RK3568_DIV_GICCLK_CORE_SHIFT    8
+#define RK3568_DIV_PCLK_CORE_MASK       0x1f
+#define RK3568_DIV_PCLK_CORE_SHIFT      0
+#define RK3568_DIV_PERIPHCLK_CORE_MASK  0x1f
+#define RK3568_DIV_PERIPHCLK_CORE_SHIFT 8
+#define RK3568_DIV_ACLK_CORE_MASK       0x1f
+#define RK3568_DIV_ACLK_CORE_SHIFT      8
+
+#define RK3568_DIV_SCLK_CORE_MASK       0xf
+#define RK3568_DIV_SCLK_CORE_SHIFT      0
+#define RK3568_MUX_SCLK_CORE_MASK       0x3
+#define RK3568_MUX_SCLK_CORE_SHIFT      8
+#define RK3568_MUX_SCLK_CORE_NPLL_MASK  0x1
+#define RK3568_MUX_SCLK_CORE_NPLL_SHIFT 15
+#define RK3568_MUX_CLK_CORE_APLL_MASK   0x1
+#define RK3568_MUX_CLK_CORE_APLL_SHIFT  7
+#define RK3568_MUX_CLK_PVTPLL_MASK      0x1
+#define RK3568_MUX_CLK_PVTPLL_SHIFT     15
+
+struct clk_rk3568_cru
+{
+    struct rt_clk_node clk_parent;
+    struct rt_reset_controller rstc_parent;
+
+    struct rockchip_clk_provider provider;
+};
+
+static struct rockchip_pll_rate_table rk3568_pll_rates[] =
+{
+    /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+    RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0),
+    RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0),
+    RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0),
+    RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0),
+    RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0),
+    RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0),
+    RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+    RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
+    RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+    RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
+    RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
+    RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
+    RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0),
+    RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0),
+    RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0),
+    RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0),
+    RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0),
+    RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
+    RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
+    RK3036_PLL_RATE(297000000, 1, 99, 4, 2, 1, 0),
+    RK3036_PLL_RATE(292500000, 1, 195, 4, 4, 1, 0),
+    RK3036_PLL_RATE(241500000, 1, 161, 4, 4, 1, 0),
+    RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
+    RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0),
+    RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0),
+    RK3036_PLL_RATE(135000000, 1, 45, 4, 2, 1, 0),
+    RK3036_PLL_RATE(119000000, 3, 119, 4, 2, 1, 0),
+    RK3036_PLL_RATE(108000000, 1, 45, 5, 2, 1, 0),
+    RK3036_PLL_RATE(101000000, 1, 101, 6, 4, 1, 0),
+    RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
+    RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
+    RK3036_PLL_RATE(78750000, 4, 315, 6, 4, 1, 0),
+    RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
+    { /* sentinel */ },
+};
+
+#define RK3568_CLKSEL1(_sclk_core)                                      \
+{                                                                       \
+    .reg = RK3568_CLKSEL_CON(2),                                        \
+    .val = HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_NPLL_MASK,    \
+            RK3568_MUX_SCLK_CORE_NPLL_SHIFT) |                          \
+           HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_MASK,         \
+            RK3568_MUX_SCLK_CORE_SHIFT) |                               \
+           HIWORD_UPDATE(1, RK3568_DIV_SCLK_CORE_MASK,                  \
+            RK3568_DIV_SCLK_CORE_SHIFT),                                \
+}
+
+#define RK3568_CLKSEL2(_aclk_core)                                      \
+{                                                                       \
+    .reg = RK3568_CLKSEL_CON(5),                                        \
+    .val = HIWORD_UPDATE(_aclk_core, RK3568_DIV_ACLK_CORE_MASK,         \
+            RK3568_DIV_ACLK_CORE_SHIFT),                                \
+}
+
+#define RK3568_CLKSEL3(_atclk_core, _gic_core)                          \
+{                                                                       \
+    .reg = RK3568_CLKSEL_CON(3),                                        \
+    .val = HIWORD_UPDATE(_atclk_core, RK3568_DIV_ATCLK_CORE_MASK,       \
+            RK3568_DIV_ATCLK_CORE_SHIFT) |                              \
+           HIWORD_UPDATE(_gic_core, RK3568_DIV_GICCLK_CORE_MASK,        \
+            RK3568_DIV_GICCLK_CORE_SHIFT),                              \
+}
+
+#define RK3568_CLKSEL4(_pclk_core, _periph_core)                        \
+{                                                                       \
+    .reg = RK3568_CLKSEL_CON(4),                                        \
+    .val = HIWORD_UPDATE(_pclk_core, RK3568_DIV_PCLK_CORE_MASK,         \
+            RK3568_DIV_PCLK_CORE_SHIFT) |                               \
+           HIWORD_UPDATE(_periph_core, RK3568_DIV_PERIPHCLK_CORE_MASK,  \
+            RK3568_DIV_PERIPHCLK_CORE_SHIFT),                           \
+}
+
+#define RK3568_CPUCLK_RATE(_prate, _sclk, _acore, _atcore, _gicclk, _pclk, _periph) \
+{                                           \
+    .prate = _prate##U,                     \
+    .divs =                                 \
+    {                                       \
+        RK3568_CLKSEL1(_sclk),              \
+        RK3568_CLKSEL2(_acore),             \
+        RK3568_CLKSEL3(_atcore, _gicclk),   \
+        RK3568_CLKSEL4(_pclk, _periph),     \
+    },                                      \
+}
+
+static struct rockchip_cpu_clk_rate_table rk3568_cpu_clk_rates[] =
+{
+    RK3568_CPUCLK_RATE(1800000000, 0, 1, 7, 7, 7, 7),
+    RK3568_CPUCLK_RATE(1704000000, 0, 1, 7, 7, 7, 7),
+    RK3568_CPUCLK_RATE(1608000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1584000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1560000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1536000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1512000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1488000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1464000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1440000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1416000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1392000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1368000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1344000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1320000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1296000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1272000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1248000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1224000000, 0, 1, 5, 5, 5, 5),
+    RK3568_CPUCLK_RATE(1200000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(1104000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(1008000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(912000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(816000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(696000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(600000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(408000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(312000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(216000000, 0, 1, 3, 3, 3, 3),
+    RK3568_CPUCLK_RATE(96000000, 0, 1, 3, 3, 3, 3),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3568_cpu_clk_data =
+{
+    .core_reg[0] = RK3568_CLKSEL_CON(0),
+    .div_core_shift[0] = 0,
+    .div_core_mask[0] = 0x1f,
+    .core_reg[1] = RK3568_CLKSEL_CON(0),
+    .div_core_shift[1] = 8,
+    .div_core_mask[1] = 0x1f,
+    .core_reg[2] = RK3568_CLKSEL_CON(1),
+    .div_core_shift[2] = 0,
+    .div_core_mask[2] = 0x1f,
+    .core_reg[3] = RK3568_CLKSEL_CON(1),
+    .div_core_shift[3] = 8,
+    .div_core_mask[3] = 0x1f,
+    .num_cores = 4,
+    .mux_core_alt = 1,
+    .mux_core_main = 0,
+    .mux_core_shift = 6,
+    .mux_core_mask = 0x1,
+};
+
+PNAME(mux_pll_p)                            = "xin24m";
+PNAMES(mux_usb480m_p)                       = { "xin24m", "usb480m_phy", "clk_rtc_32k" };
+PNAMES(clk_i2s0_8ch_tx_p)                   = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin_osc0_half" };
+PNAMES(clk_i2s0_8ch_rx_p)                   = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin_osc0_half" };
+PNAMES(clk_i2s1_8ch_tx_p)                   = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "i2s1_mclkin", "xin_osc0_half" };
+PNAMES(clk_i2s1_8ch_rx_p)                   = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "i2s1_mclkin", "xin_osc0_half" };
+PNAMES(clk_i2s2_2ch_p)                      = { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "i2s2_mclkin", "xin_osc0_half "};
+PNAMES(clk_i2s3_2ch_tx_p)                   = { "clk_i2s3_2ch_tx_src", "clk_i2s3_2ch_tx_frac", "i2s3_mclkin", "xin_osc0_half" };
+PNAMES(clk_i2s3_2ch_rx_p)                   = { "clk_i2s3_2ch_rx_src", "clk_i2s3_2ch_rx_frac", "i2s3_mclkin", "xin_osc0_half" };
+PNAMES(mclk_spdif_8ch_p)                    = { "mclk_spdif_8ch_src", "mclk_spdif_8ch_frac" };
+PNAMES(sclk_audpwm_p)                       = { "sclk_audpwm_src", "sclk_audpwm_frac" };
+PNAMES(sclk_uart1_p)                        = { "clk_uart1_src", "clk_uart1_frac", "xin24m" };
+PNAMES(sclk_uart2_p)                        = { "clk_uart2_src", "clk_uart2_frac", "xin24m" };
+PNAMES(sclk_uart3_p)                        = { "clk_uart3_src", "clk_uart3_frac", "xin24m" };
+PNAMES(sclk_uart4_p)                        = { "clk_uart4_src", "clk_uart4_frac", "xin24m" };
+PNAMES(sclk_uart5_p)                        = { "clk_uart5_src", "clk_uart5_frac", "xin24m" };
+PNAMES(sclk_uart6_p)                        = { "clk_uart6_src", "clk_uart6_frac", "xin24m" };
+PNAMES(sclk_uart7_p)                        = { "clk_uart7_src", "clk_uart7_frac", "xin24m" };
+PNAMES(sclk_uart8_p)                        = { "clk_uart8_src", "clk_uart8_frac", "xin24m" };
+PNAMES(sclk_uart9_p)                        = { "clk_uart9_src", "clk_uart9_frac", "xin24m" };
+PNAMES(sclk_uart0_p)                        = { "sclk_uart0_div", "sclk_uart0_frac", "xin24m" };
+PNAMES(clk_rtc32k_pmu_p)                    = { "clk_32k_pvtm", "xin32k", "clk_rtc32k_frac" };
+PNAMES(mpll_gpll_cpll_npll_p)               = { "mpll", "gpll", "cpll", "npll" };
+PNAMES(gpll_cpll_npll_p)                    = { "gpll", "cpll", "npll" };
+PNAMES(npll_gpll_p)                         = { "npll", "gpll" };
+PNAMES(cpll_gpll_p)                         = { "cpll", "gpll" };
+PNAMES(gpll_cpll_p)                         = { "gpll", "cpll" };
+PNAMES(gpll_cpll_npll_vpll_p)               = { "gpll", "cpll", "npll", "vpll" };
+PNAMES(apll_gpll_npll_p)                    = { "apll", "gpll", "npll" };
+PNAMES(sclk_core_pre_p)                     = { "sclk_core_src", "npll" };
+PNAMES(gpll150_gpll100_gpll75_xin24m_p)     = { "gpll_150m", "gpll_100m", "gpll_75m", "xin24m" };
+PNAMES(clk_gpu_pre_mux_p)                   = { "clk_gpu_src", "gpu_pvtpll_out" };
+PNAMES(clk_npu_pre_ndft_p)                  = { "clk_npu_src", "clk_npu_np5"};
+PNAMES(clk_npu_p)                           = { "clk_npu_pre_ndft", "npu_pvtpll_out" };
+PNAMES(dpll_gpll_cpll_p)                    = { "dpll", "gpll", "cpll" };
+PNAMES(clk_ddr1x_p)                         = { "clk_ddrphy1x_src", "dpll" };
+PNAMES(gpll200_gpll150_gpll100_xin24m_p)    = { "gpll_200m", "gpll_150m", "gpll_100m", "xin24m" };
+PNAMES(gpll100_gpll75_gpll50_p)             = { "gpll_100m", "gpll_75m", "cpll_50m" };
+PNAMES(i2s0_mclkout_tx_p)                   = { "mclk_i2s0_8ch_tx", "xin_osc0_half" };
+PNAMES(i2s0_mclkout_rx_p)                   = { "mclk_i2s0_8ch_rx", "xin_osc0_half" };
+PNAMES(i2s1_mclkout_tx_p)                   = { "mclk_i2s1_8ch_tx", "xin_osc0_half" };
+PNAMES(i2s1_mclkout_rx_p)                   = { "mclk_i2s1_8ch_rx", "xin_osc0_half" };
+PNAMES(i2s2_mclkout_p)                      = { "mclk_i2s2_2ch", "xin_osc0_half" };
+PNAMES(i2s3_mclkout_tx_p)                   = { "mclk_i2s3_2ch_tx", "xin_osc0_half" };
+PNAMES(i2s3_mclkout_rx_p)                   = { "mclk_i2s3_2ch_rx", "xin_osc0_half" };
+PNAMES(mclk_pdm_p)                          = { "gpll_300m", "cpll_250m", "gpll_200m", "gpll_100m" };
+PNAMES(clk_i2c_p)                           = { "gpll_200m", "gpll_100m", "xin24m", "cpll_100m" };
+PNAMES(gpll200_gpll150_gpll100_p)           = { "gpll_200m", "gpll_150m", "gpll_100m" };
+PNAMES(gpll300_gpll200_gpll100_p)           = { "gpll_300m", "gpll_200m", "gpll_100m" };
+PNAMES(clk_nandc_p)                         = { "gpll_200m", "gpll_150m", "cpll_100m", "xin24m" };
+PNAMES(sclk_sfc_p)                          = { "xin24m", "cpll_50m", "gpll_75m", "gpll_100m", "cpll_125m", "gpll_150m" };
+PNAMES(gpll200_gpll150_cpll125_p)           = { "gpll_200m", "gpll_150m", "cpll_125m" };
+PNAMES(cclk_emmc_p)                         = { "xin24m", "gpll_200m", "gpll_150m", "cpll_100m", "cpll_50m", "clk_osc0_div_375k" };
+PNAMES(aclk_pipe_p)                         = { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" };
+PNAMES(gpll200_cpll125_p)                   = { "gpll_200m", "cpll_125m" };
+PNAMES(gpll300_gpll200_gpll100_xin24m_p)    = { "gpll_300m", "gpll_200m", "gpll_100m", "xin24m" };
+PNAMES(clk_sdmmc_p)                         = { "xin24m", "gpll_400m", "gpll_300m", "cpll_100m", "cpll_50m", "clk_osc0_div_750k" };
+PNAMES(cpll125_cpll50_cpll25_xin24m_p)      = { "cpll_125m", "cpll_50m", "cpll_25m", "xin24m" };
+PNAMES(clk_gmac_ptp_p)                      = { "cpll_62p5", "gpll_100m", "cpll_50m", "xin24m" };
+PNAMES(cpll333_gpll300_gpll200_p)           = { "cpll_333m", "gpll_300m", "gpll_200m" };
+PNAMES(cpll_gpll_hpll_p)                    = { "cpll", "gpll", "hpll" };
+PNAMES(gpll_usb480m_xin24m_p)               = { "gpll", "usb480m", "xin24m", "xin24m" };
+PNAMES(gpll300_cpll250_gpll100_xin24m_p)    = { "gpll_300m", "cpll_250m", "gpll_100m", "xin24m" };
+PNAMES(cpll_gpll_hpll_vpll_p)               = { "cpll", "gpll", "hpll", "vpll" };
+PNAMES(hpll_vpll_gpll_cpll_p)               = { "hpll", "vpll", "gpll", "cpll" };
+PNAMES(gpll400_cpll333_gpll200_p)           = { "gpll_400m", "cpll_333m", "gpll_200m" };
+PNAMES(gpll100_gpll75_cpll50_xin24m_p)      = { "gpll_100m", "gpll_75m", "cpll_50m", "xin24m" };
+PNAMES(xin24m_gpll100_cpll100_p)            = { "xin24m", "gpll_100m", "cpll_100m" };
+PNAMES(gpll_cpll_usb480m_p)                 = { "gpll", "cpll", "usb480m" };
+PNAMES(gpll100_xin24m_cpll100_p)            = { "gpll_100m", "xin24m", "cpll_100m" };
+PNAMES(gpll200_xin24m_cpll100_p)            = { "gpll_200m", "xin24m", "cpll_100m" };
+PNAMES(xin24m_32k_p)                        = { "xin24m", "clk_rtc_32k" };
+PNAMES(cpll500_gpll400_gpll300_xin24m_p)    = { "cpll_500m", "gpll_400m", "gpll_300m", "xin24m" };
+PNAMES(gpll400_gpll300_gpll200_xin24m_p)    = { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" };
+PNAMES(xin24m_cpll100_p)                    = { "xin24m", "cpll_100m" };
+PNAMES(ppll_usb480m_cpll_gpll_p)            = { "ppll", "usb480m", "cpll", "gpll"};
+PNAMES(clk_usbphy0_ref_p)                   = { "clk_ref24m", "xin_osc0_usbphy0_g" };
+PNAMES(clk_usbphy1_ref_p)                   = { "clk_ref24m", "xin_osc0_usbphy1_g" };
+PNAMES(clk_mipidsiphy0_ref_p)               = { "clk_ref24m", "xin_osc0_mipidsiphy0_g" };
+PNAMES(clk_mipidsiphy1_ref_p)               = { "clk_ref24m", "xin_osc0_mipidsiphy1_g" };
+PNAMES(clk_wifi_p)                          = { "clk_wifi_osc0", "clk_wifi_div" };
+PNAMES(clk_pciephy0_ref_p)                  = { "clk_pciephy0_osc0", "clk_pciephy0_div" };
+PNAMES(clk_pciephy1_ref_p)                  = { "clk_pciephy1_osc0", "clk_pciephy1_div" };
+PNAMES(clk_pciephy2_ref_p)                  = { "clk_pciephy2_osc0", "clk_pciephy2_div" };
+PNAMES(mux_gmac0_p)                         = { "clk_mac0_2top", "gmac0_clkin" };
+PNAMES(mux_gmac0_rgmii_speed_p)             = { "clk_gmac0", "clk_gmac0", "clk_gmac0_tx_div50", "clk_gmac0_tx_div5" };
+PNAMES(mux_gmac0_rmii_speed_p)              = { "clk_gmac0_rx_div20", "clk_gmac0_rx_div2" };
+PNAMES(mux_gmac0_rx_tx_p)                   = { "clk_gmac0_rgmii_speed", "clk_gmac0_rmii_speed", "clk_gmac0_xpcs_mii" };
+PNAMES(mux_gmac1_p)                         = { "clk_mac1_2top", "gmac1_clkin" };
+PNAMES(mux_gmac1_rgmii_speed_p)             = { "clk_gmac1", "clk_gmac1", "clk_gmac1_tx_div50", "clk_gmac1_tx_div5" };
+PNAMES(mux_gmac1_rmii_speed_p)              = { "clk_gmac1_rx_div20", "clk_gmac1_rx_div2" };
+PNAMES(mux_gmac1_rx_tx_p)                   = { "clk_gmac1_rgmii_speed", "clk_gmac1_rmii_speed", "clk_gmac1_xpcs_mii" };
+PNAMES(clk_hdmi_ref_p)                      = { "hpll", "hpll_ph0" };
+PNAMES(clk_pdpmu_p)                         = { "ppll", "gpll" };
+PNAMES(clk_mac_2top_p)                      = { "cpll_125m", "cpll_50m", "cpll_25m", "ppll" };
+PNAMES(clk_pwm0_p)                          = { "xin24m", "clk_pdpmu" };
+PNAMES(aclk_rkvdec_pre_p)                   = { "gpll", "cpll" };
+PNAMES(clk_rkvdec_core_p)                   = { "gpll", "cpll" };
+PNAMES(clk_32k_ioe_p)                       = { "clk_rtc_32k", "xin32k" };
+PNAMES(i2s1_mclkout_p)                      = { "i2s1_mclkout_rx", "i2s1_mclkout_tx" };
+PNAMES(i2s3_mclkout_p)                      = { "i2s3_mclkout_rx", "i2s3_mclkout_tx" };
+PNAMES(i2s1_mclk_rx_ioe_p)                  = { "i2s1_mclkin_rx", "i2s1_mclkout_rx" };
+PNAMES(i2s1_mclk_tx_ioe_p)                  = { "i2s1_mclkin_tx", "i2s1_mclkout_tx" };
+PNAMES(i2s2_mclk_ioe_p)                     = { "i2s2_mclkin", "i2s2_mclkout" };
+PNAMES(i2s3_mclk_ioe_p)                     = { "i2s3_mclkin", "i2s3_mclkout" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clk_cell rk3568_pmu_pll_ppll =
+    PLL_RAW(pll_type_rk3328, PLL_PPLL, "ppll", mux_pll_p, 1, 0, RK3568_PMU_PLL_CON(0), RK3568_PMU_MODE_CON0,
+            0, 4, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+static struct rockchip_pll_clk_cell rk3568_pmu_pll_hpll =
+    PLL_RAW(pll_type_rk3328, PLL_HPLL, "hpll", mux_pll_p, 1, 0, RK3568_PMU_PLL_CON(16), RK3568_PMU_MODE_CON0,
+            2, 7, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+
+static struct rockchip_pll_clk_cell rk3568_pll_apll =
+    PLL_RAW(pll_type_rk3328, PLL_APLL, "apll", mux_pll_p, 1, 0, RK3568_PLL_CON(0), RK3568_MODE_CON0,
+            0, 0, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+static struct rockchip_pll_clk_cell rk3568_pll_dpll =
+    PLL_RAW(pll_type_rk3328, PLL_DPLL, "dpll", mux_pll_p, 1, 0, RK3568_PLL_CON(8), RK3568_MODE_CON0,
+            2, 1, RK3568_GRF_SOC_STATUS0, 0, RT_NULL);
+static struct rockchip_pll_clk_cell rk3568_pll_cpll =
+    PLL_RAW(pll_type_rk3328, PLL_CPLL, "cpll", mux_pll_p, 1, 0, RK3568_PLL_CON(24), RK3568_MODE_CON0,
+            4, 2, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+static struct rockchip_pll_clk_cell rk3568_pll_gpll =
+    PLL_RAW(pll_type_rk3328, PLL_GPLL, "gpll", mux_pll_p, 1, 0, RK3568_PLL_CON(16), RK3568_MODE_CON0,
+            6, 3, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+static struct rockchip_pll_clk_cell rk3568_pll_npll =
+    PLL_RAW(pll_type_rk3328, PLL_NPLL, "npll", mux_pll_p, 1, RT_CLK_F_IS_CRITICAL, RK3568_PLL_CON(32), RK3568_MODE_CON0,
+            10, 5, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+static struct rockchip_pll_clk_cell rk3568_pll_vpll =
+    PLL_RAW(pll_type_rk3328, PLL_VPLL, "vpll", mux_pll_p, 1, 0, RK3568_PLL_CON(40), RK3568_MODE_CON0,
+            12, 6, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates);
+
+static struct rockchip_clk_cell rk3568_i2s0_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(11), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_i2s0_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(13), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_i2s1_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", clk_i2s1_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(15), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_i2s1_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", clk_i2s1_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(17), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_i2s2_2ch_fracmux =
+    MUX_RAW(CLK_I2S2_2CH, "clk_i2s2_2ch", clk_i2s2_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(19), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_i2s3_2ch_tx_fracmux =
+    MUX_RAW(CLK_I2S3_2CH_TX, "clk_i2s3_2ch_tx", clk_i2s3_2ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(21), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_i2s3_2ch_rx_fracmux =
+    MUX_RAW(CLK_I2S3_2CH_RX, "clk_i2s3_2ch_rx", clk_i2s3_2ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(83), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_spdif_8ch_fracmux =
+    MUX_RAW(MCLK_SPDIF_8CH, "mclk_spdif_8ch", mclk_spdif_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(23), 15, 1, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_audpwm_fracmux =
+    MUX_RAW(SCLK_AUDPWM, "sclk_audpwm", sclk_audpwm_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(25), 15, 1, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart1_fracmux =
+    MUX_RAW(0, "sclk_uart1_mux", sclk_uart1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(52), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart2_fracmux =
+    MUX_RAW(0, "sclk_uart2_mux", sclk_uart2_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(54), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart3_fracmux =
+    MUX_RAW(0, "sclk_uart3_mux", sclk_uart3_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(56), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart4_fracmux =
+    MUX_RAW(0, "sclk_uart4_mux", sclk_uart4_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(58), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart5_fracmux =
+    MUX_RAW(0, "sclk_uart5_mux", sclk_uart5_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(60), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart6_fracmux =
+    MUX_RAW(0, "sclk_uart6_mux", sclk_uart6_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(62), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart7_fracmux =
+    MUX_RAW(0, "sclk_uart7_mux", sclk_uart7_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(64), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart8_fracmux =
+    MUX_RAW(0, "sclk_uart8_mux", sclk_uart8_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(66), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart9_fracmux =
+    MUX_RAW(0, "sclk_uart9_mux", sclk_uart9_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(68), 12, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_uart0_fracmux =
+    MUX_RAW(0, "sclk_uart0_mux", sclk_uart0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(4), 10, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3568_rtc32k_pmu_fracmux =
+    MUX_RAW(CLK_RTC_32K, "clk_rtc_32k", clk_rtc32k_pmu_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(0), 6, 2, MFLAGS);
+
+static struct rt_clk_cell *rk3568_clk_pmu_cells[] =
+{
+    [PLL_PPLL] = &rk3568_pmu_pll_ppll.rk_cell.cell,
+    [PLL_HPLL] = &rk3568_pmu_pll_hpll.rk_cell.cell,
+    [XIN_OSC0_DIV] = COMPOSITE_NOMUX(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_PMU_CLKSEL_CON(0), 0, 5, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(0), 0, GFLAGS),
+    [CLK_RTC_32K] = &rk3568_rtc32k_pmu_fracmux.cell,
+    [CLK_PMU] = GATE(CLK_PMU, "clk_pmu", "xin24m", RT_CLK_F_IS_CRITICAL, RK3568_PMU_CLKGATE_CON(0), 7, GFLAGS),
+    [CLK_I2C0] = COMPOSITE_NOMUX(CLK_I2C0, "clk_i2c0", "clk_pdpmu", 0,
+            RK3568_PMU_CLKSEL_CON(3), 0, 7, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(1), 1, GFLAGS),
+    [CLK_RTC32K_FRAC] = COMPOSITE_FRACMUX(CLK_RTC32K_FRAC, "clk_rtc32k_frac", "xin24m", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_PMU_CLKSEL_CON(1), 0,
+            RK3568_PMU_CLKGATE_CON(0), 1, GFLAGS,
+            &rk3568_rtc32k_pmu_fracmux),
+    [CLK_UART0_DIV] = COMPOSITE(CLK_UART0_DIV, "sclk_uart0_div", ppll_usb480m_cpll_gpll_p, 0,
+            RK3568_PMU_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(1), 3, GFLAGS),
+    [CLK_UART0_FRAC] = COMPOSITE_FRACMUX(CLK_UART0_FRAC, "sclk_uart0_frac", "sclk_uart0_div", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(5), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_PMU_CLKGATE_CON(1), 4, GFLAGS,
+            &rk3568_uart0_fracmux),
+    [SCLK_UART0] = GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_mux", 0, RK3568_PMU_CLKGATE_CON(1), 5, GFLAGS),
+    [DBCLK_GPIO0] = COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", xin24m_32k_p, 0,
+            RK3568_PMU_CLKSEL_CON(6), 15, 1, MFLAGS,
+            RK3568_PMU_CLKGATE_CON(1), 10, GFLAGS),
+    [CLK_PWM0] = COMPOSITE(CLK_PWM0, "clk_pwm0", clk_pwm0_p, 0,
+            RK3568_PMU_CLKSEL_CON(6), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(1), 7, GFLAGS),
+    [CLK_CAPTURE_PWM0_NDFT] = GATE(CLK_CAPTURE_PWM0_NDFT, "clk_capture_pwm0_ndft", "xin24m", 0, RK3568_PMU_CLKGATE_CON(1), 8, GFLAGS),
+    [CLK_PMUPVTM] = GATE(CLK_PMUPVTM, "clk_pmupvtm", "xin24m", 0, RK3568_PMU_CLKGATE_CON(1), 12, GFLAGS),
+    [CLK_CORE_PMUPVTM] = GATE(CLK_CORE_PMUPVTM, "clk_core_pmupvtm", "xin24m", 0, RK3568_PMU_CLKGATE_CON(1), 13, GFLAGS),
+    [CLK_REF24M] = COMPOSITE_NOMUX(CLK_REF24M, "clk_ref24m", "clk_pdpmu", 0,
+            RK3568_PMU_CLKSEL_CON(7), 0, 6, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(2), 0, GFLAGS),
+    [XIN_OSC0_USBPHY0_G] = GATE(XIN_OSC0_USBPHY0_G, "xin_osc0_usbphy0_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 1, GFLAGS),
+    [CLK_USBPHY0_REF] = MUX(CLK_USBPHY0_REF, "clk_usbphy0_ref", clk_usbphy0_ref_p, 0,
+            RK3568_PMU_CLKSEL_CON(8), 0, 1, MFLAGS),
+    [XIN_OSC0_USBPHY1_G] = GATE(XIN_OSC0_USBPHY1_G, "xin_osc0_usbphy1_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 2, GFLAGS),
+    [CLK_USBPHY1_REF] = MUX(CLK_USBPHY1_REF, "clk_usbphy1_ref", clk_usbphy1_ref_p, 0,
+            RK3568_PMU_CLKSEL_CON(8), 1, 1, MFLAGS),
+    [XIN_OSC0_MIPIDSIPHY0_G] = GATE(XIN_OSC0_MIPIDSIPHY0_G, "xin_osc0_mipidsiphy0_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 3, GFLAGS),
+    [CLK_MIPIDSIPHY0_REF] = MUX(CLK_MIPIDSIPHY0_REF, "clk_mipidsiphy0_ref", clk_mipidsiphy0_ref_p, 0,
+            RK3568_PMU_CLKSEL_CON(8), 2, 1, MFLAGS),
+    [XIN_OSC0_MIPIDSIPHY1_G] = GATE(XIN_OSC0_MIPIDSIPHY1_G, "xin_osc0_mipidsiphy1_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 4, GFLAGS),
+    [CLK_MIPIDSIPHY1_REF] = MUX(CLK_MIPIDSIPHY1_REF, "clk_mipidsiphy1_ref", clk_mipidsiphy1_ref_p, 0,
+            RK3568_PMU_CLKSEL_CON(8), 3, 1, MFLAGS),
+    [CLK_WIFI_DIV] = COMPOSITE_NOMUX(CLK_WIFI_DIV, "clk_wifi_div", "clk_pdpmu", 0,
+            RK3568_PMU_CLKSEL_CON(8), 8, 6, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(2), 5, GFLAGS),
+    [CLK_WIFI_OSC0] = GATE(CLK_WIFI_OSC0, "clk_wifi_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 6, GFLAGS),
+    [CLK_WIFI] = MUX(CLK_WIFI, "clk_wifi", clk_wifi_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(8), 15, 1, MFLAGS),
+    [CLK_PCIEPHY0_DIV] = COMPOSITE_NOMUX(CLK_PCIEPHY0_DIV, "clk_pciephy0_div", "ppll_ph0", 0,
+            RK3568_PMU_CLKSEL_CON(9), 0, 3, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(2), 7, GFLAGS),
+    [CLK_PCIEPHY0_OSC0] = GATE(CLK_PCIEPHY0_OSC0, "clk_pciephy0_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 8, GFLAGS),
+    [CLK_PCIEPHY0_REF] = MUX(CLK_PCIEPHY0_REF, "clk_pciephy0_ref", clk_pciephy0_ref_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(9), 3, 1, MFLAGS),
+    [CLK_PCIEPHY1_DIV] = COMPOSITE_NOMUX(CLK_PCIEPHY1_DIV, "clk_pciephy1_div", "ppll_ph0", 0,
+            RK3568_PMU_CLKSEL_CON(9), 4, 3, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(2), 9, GFLAGS),
+    [CLK_PCIEPHY1_OSC0] = GATE(CLK_PCIEPHY1_OSC0, "clk_pciephy1_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 10, GFLAGS),
+    [CLK_PCIEPHY1_REF] = MUX(CLK_PCIEPHY1_REF, "clk_pciephy1_ref", clk_pciephy1_ref_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(9), 7, 1, MFLAGS),
+    [CLK_PCIEPHY2_DIV] = COMPOSITE_NOMUX(CLK_PCIEPHY2_DIV, "clk_pciephy2_div", "ppll_ph0", 0,
+            RK3568_PMU_CLKSEL_CON(9), 8, 3, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(2), 11, GFLAGS),
+    [CLK_PCIEPHY2_OSC0] = GATE(CLK_PCIEPHY2_OSC0, "clk_pciephy2_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 12, GFLAGS),
+    [CLK_PCIEPHY2_REF] = MUX(CLK_PCIEPHY2_REF, "clk_pciephy2_ref", clk_pciephy2_ref_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_PMU_CLKSEL_CON(9), 11, 1, MFLAGS),
+    [CLK_PCIE30PHY_REF_M] = GATE(CLK_PCIE30PHY_REF_M, "clk_pcie30phy_ref_m", "ppll_ph0", 0, RK3568_PMU_CLKGATE_CON(2), 13, GFLAGS),
+    [CLK_PCIE30PHY_REF_N] = GATE(CLK_PCIE30PHY_REF_N, "clk_pcie30phy_ref_n", "ppll_ph180", 0, RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS),
+    [CLK_HDMI_REF] = MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0,
+            RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS),
+    [XIN_OSC0_EDPPHY_G] = GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS),
+    [PCLK_PDPMU] = COMPOSITE_NOMUX(PCLK_PDPMU, "pclk_pdpmu", "clk_pdpmu", RT_CLK_F_IS_CRITICAL,
+            RK3568_PMU_CLKSEL_CON(2), 0, 5, DFLAGS,
+            RK3568_PMU_CLKGATE_CON(0), 2, GFLAGS),
+    [PCLK_PMU] = GATE(PCLK_PMU, "pclk_pmu", "pclk_pdpmu", RT_CLK_F_IS_CRITICAL, RK3568_PMU_CLKGATE_CON(0), 6, GFLAGS),
+    [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 2, GFLAGS),
+    [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 0, GFLAGS),
+    [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 9, GFLAGS),
+    [PCLK_PMUPVTM] = GATE(PCLK_PMUPVTM, "pclk_pmupvtm", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 11, GFLAGS),
+    [PCLK_PWM0] = GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 6, GFLAGS),
+    [CLK_PDPMU] = MUX(CLK_PDPMU, "clk_pdpmu", clk_pdpmu_p, 0,
+            RK3568_PMU_CLKSEL_CON(2), 15, 1, MFLAGS),
+    [SCLK_32K_IOE] = MUXPMUGRF(SCLK_32K_IOE, "clk_32k_ioe", clk_32k_ioe_p, 0,
+            RK3568_PMU_GRF_SOC_CON0, 0, 1, MFLAGS),
+
+    &rk3568_uart0_fracmux.cell,
+
+    FACTOR(0, "ppll_ph0", "ppll", 0, 1, 2),
+    FACTOR(0, "ppll_ph180", "ppll", 0, 1, 2),
+    FACTOR(0, "hpll_ph0", "hpll", 0, 1, 2),
+};
+
+static struct rt_clk_cell *rk3568_clk_cells[] =
+{
+    [PLL_APLL] = &rk3568_pll_apll.rk_cell.cell,
+    [PLL_DPLL] = &rk3568_pll_dpll.rk_cell.cell,
+    [PLL_CPLL] = &rk3568_pll_cpll.rk_cell.cell,
+    [PLL_GPLL] = &rk3568_pll_gpll.rk_cell.cell,
+    [PLL_VPLL] = &rk3568_pll_npll.rk_cell.cell,
+    [PLL_NPLL] = &rk3568_pll_vpll.rk_cell.cell,
+    [CPLL_333M] = COMPOSITE_NOMUX(CPLL_333M, "cpll_333m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(79), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 8, GFLAGS),
+    [ARMCLK] = CPU(ARMCLK, "armclk", &rk3568_pll_apll.rk_cell, &rk3568_pll_gpll.rk_cell,
+            rk3568_cpu_clk_rates, RT_ARRAY_SIZE(rk3568_cpu_clk_rates), &rk3568_cpu_clk_data),
+    [USB480M] = MUX(USB480M, "usb480m", mux_usb480m_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_MODE_CON0, 14, 2, MFLAGS),
+    [ACLK_CORE_NIU2BUS] = COMPOSITE_NODIV(ACLK_CORE_NIU2BUS, "aclk_core_niu2bus", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(5), 14, 2, MFLAGS,
+            RK3568_CLKGATE_CON(1), 2, GFLAGS),
+    [CLK_CORE_PVTM] = GATE(CLK_CORE_PVTM, "clk_core_pvtm", "xin24m", 0, RK3568_CLKGATE_CON(1), 10, GFLAGS),
+    [CLK_CORE_PVTM_CORE] = GATE(CLK_CORE_PVTM_CORE, "clk_core_pvtm_core", "armclk", 0, RK3568_CLKGATE_CON(1), 11, GFLAGS),
+    [CLK_CORE_PVTPLL] = GATE(CLK_CORE_PVTPLL, "clk_core_pvtpll", "armclk", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(1), 12, GFLAGS),
+    [CLK_GPU_SRC] = COMPOSITE(CLK_GPU_SRC, "clk_gpu_src", mpll_gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(6), 6, 2, MFLAGS | CLK_MUX_READ_ONLY, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(2), 0, GFLAGS),
+    [CLK_GPU_PRE_MUX] = MUX(CLK_GPU_PRE_MUX, "clk_gpu_pre_mux", clk_gpu_pre_mux_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(6), 11, 1, MFLAGS | CLK_MUX_READ_ONLY),
+    [ACLK_GPU_PRE] = DIV(ACLK_GPU_PRE, "aclk_gpu_pre", "clk_gpu_pre_mux", 0,
+            RK3568_CLKSEL_CON(6), 8, 2, DFLAGS),
+    [PCLK_GPU_PRE] = DIV(PCLK_GPU_PRE, "pclk_gpu_pre", "clk_gpu_pre_mux", 0,
+            RK3568_CLKSEL_CON(6), 12, 4, DFLAGS),
+    [CLK_GPU] = GATE(CLK_GPU, "clk_gpu", "clk_gpu_pre_mux", 0, RK3568_CLKGATE_CON(2), 3, GFLAGS),
+    [PCLK_GPU_PVTM] = GATE(PCLK_GPU_PVTM, "pclk_gpu_pvtm", "pclk_gpu_pre", 0, RK3568_CLKGATE_CON(2), 6, GFLAGS),
+    [CLK_GPU_PVTM] =  GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 0, RK3568_CLKGATE_CON(2), 7, GFLAGS),
+    [CLK_GPU_PVTM_CORE] = GATE(CLK_GPU_PVTM_CORE, "clk_gpu_pvtm_core", "clk_gpu_src", 0, RK3568_CLKGATE_CON(2), 8, GFLAGS),
+    [CLK_GPU_PVTPLL] = GATE(CLK_GPU_PVTPLL, "clk_gpu_pvtpll", "clk_gpu_src", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(2), 9, GFLAGS),
+    [CLK_NPU_SRC] = COMPOSITE(CLK_NPU_SRC, "clk_npu_src", npll_gpll_p, 0,
+            RK3568_CLKSEL_CON(7), 6, 1, MFLAGS, 0, 4, DFLAGS,
+            RK3568_CLKGATE_CON(3), 0, GFLAGS),
+    [CLK_NPU_PRE_NDFT] = MUX(CLK_NPU_PRE_NDFT, "clk_npu_pre_ndft", clk_npu_pre_ndft_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(7), 8, 1, MFLAGS),
+    [CLK_NPU] = MUX(CLK_NPU, "clk_npu", clk_npu_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(7), 15, 1, MFLAGS),
+    [CLK_NPU_NP5] = COMPOSITE_HALFDIV(CLK_NPU_NP5, "clk_npu_np5", npll_gpll_p, 0,
+            RK3568_CLKSEL_CON(7), 7, 1, MFLAGS, 4, 2, DFLAGS,
+            RK3568_CLKGATE_CON(3), 1, GFLAGS),
+    [HCLK_NPU_PRE] = COMPOSITE_NOMUX(HCLK_NPU_PRE, "hclk_npu_pre", "clk_npu", 0,
+            RK3568_CLKSEL_CON(8), 0, 4, DFLAGS,
+            RK3568_CLKGATE_CON(3), 2, GFLAGS),
+    [PCLK_NPU_PRE] = COMPOSITE_NOMUX(PCLK_NPU_PRE, "pclk_npu_pre", "clk_npu", 0,
+            RK3568_CLKSEL_CON(8), 4, 4, DFLAGS,
+            RK3568_CLKGATE_CON(3), 3, GFLAGS),
+    [ACLK_NPU_PRE] = GATE(ACLK_NPU_PRE, "aclk_npu_pre", "clk_npu", 0, RK3568_CLKGATE_CON(3), 4, GFLAGS),
+    [ACLK_NPU] = GATE(ACLK_NPU, "aclk_npu", "aclk_npu_pre", 0, RK3568_CLKGATE_CON(3), 7, GFLAGS),
+    [HCLK_NPU] = GATE(HCLK_NPU, "hclk_npu", "hclk_npu_pre", 0, RK3568_CLKGATE_CON(3), 8, GFLAGS),
+    [PCLK_NPU_PVTM] = GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_pre", 0, RK3568_CLKGATE_CON(3), 9, GFLAGS),
+    [CLK_NPU_PVTM] = GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 0, RK3568_CLKGATE_CON(3), 10, GFLAGS),
+    [CLK_NPU_PVTM_CORE] = GATE(CLK_NPU_PVTM_CORE, "clk_npu_pvtm_core", "clk_npu_pre_ndft", 0, RK3568_CLKGATE_CON(3), 11, GFLAGS),
+    [CLK_NPU_PVTPLL] = GATE(CLK_NPU_PVTPLL, "clk_npu_pvtpll", "clk_npu_pre_ndft", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(3), 12, GFLAGS),
+    [CLK_DDRPHY1X_SRC] = COMPOSITE(CLK_DDRPHY1X_SRC, "clk_ddrphy1x_src", dpll_gpll_cpll_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(4), 0, GFLAGS),
+    [CLK_DDR1X] = MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(9), 15, 1, MFLAGS),
+    [CLK_MSCH] = COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(10), 0, 2, DFLAGS,
+            RK3568_CLKGATE_CON(4), 2, GFLAGS),
+    [CLK24_DDRMON] = GATE(CLK24_DDRMON, "clk24_ddrmon", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(4), 15, GFLAGS),
+    [ACLK_GIC_AUDIO] = COMPOSITE_NODIV(ACLK_GIC_AUDIO, "aclk_gic_audio", gpll200_gpll150_gpll100_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(10), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(5), 0, GFLAGS),
+    [HCLK_GIC_AUDIO] = COMPOSITE_NODIV(HCLK_GIC_AUDIO, "hclk_gic_audio", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(10), 10, 2, MFLAGS,
+            RK3568_CLKGATE_CON(5), 1, GFLAGS),
+    [HCLK_SDMMC_BUFFER] = GATE(HCLK_SDMMC_BUFFER, "hclk_sdmmc_buffer", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 8, GFLAGS),
+    [DCLK_SDMMC_BUFFER] = COMPOSITE_NODIV(DCLK_SDMMC_BUFFER, "dclk_sdmmc_buffer", gpll100_gpll75_gpll50_p, 0,
+            RK3568_CLKSEL_CON(10), 12, 2, MFLAGS,
+            RK3568_CLKGATE_CON(5), 9, GFLAGS),
+    [ACLK_GIC600] = GATE(ACLK_GIC600, "aclk_gic600", "aclk_gic_audio", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(5), 4, GFLAGS),
+    [ACLK_SPINLOCK] = GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_gic_audio", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(5), 7, GFLAGS),
+    [HCLK_I2S0_8CH] = GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 10, GFLAGS),
+    [HCLK_I2S1_8CH] = GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 11, GFLAGS),
+    [HCLK_I2S2_2CH] = GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 12, GFLAGS),
+    [HCLK_I2S3_2CH] = GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 13, GFLAGS),
+    [CLK_I2S0_8CH_TX_SRC] = COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(6), 0, GFLAGS),
+    [CLK_I2S0_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(12), 0,
+            RK3568_CLKGATE_CON(6), 1, GFLAGS,
+            &rk3568_i2s0_8ch_tx_fracmux),
+    [MCLK_I2S0_8CH_TX] = GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0, RK3568_CLKGATE_CON(6), 2, GFLAGS),
+    [I2S0_MCLKOUT_TX] = COMPOSITE_NODIV(I2S0_MCLKOUT_TX, "i2s0_mclkout_tx", i2s0_mclkout_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(11), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(6), 3, GFLAGS),
+    [CLK_I2S0_8CH_RX_SRC] = COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(13), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(6), 4, GFLAGS),
+    [CLK_I2S0_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(14), 0,
+            RK3568_CLKGATE_CON(6), 5, GFLAGS,
+            &rk3568_i2s0_8ch_rx_fracmux),
+    [MCLK_I2S0_8CH_RX] = GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0, RK3568_CLKGATE_CON(6), 6, GFLAGS),
+    [I2S0_MCLKOUT_RX] = COMPOSITE_NODIV(I2S0_MCLKOUT_RX, "i2s0_mclkout_rx", i2s0_mclkout_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(13), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(6), 7, GFLAGS),
+    [CLK_I2S1_8CH_TX_SRC] = COMPOSITE(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(15), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(6), 8, GFLAGS),
+    [CLK_I2S1_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(16), 0,
+            RK3568_CLKGATE_CON(6), 9, GFLAGS,
+            &rk3568_i2s1_8ch_tx_fracmux),
+    [MCLK_I2S1_8CH_TX] = GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 0, RK3568_CLKGATE_CON(6), 10, GFLAGS),
+    [I2S1_MCLKOUT_TX] = COMPOSITE_NODIV(I2S1_MCLKOUT_TX, "i2s1_mclkout_tx", i2s1_mclkout_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(15), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(6), 11, GFLAGS),
+    [CLK_I2S1_8CH_RX_SRC] = COMPOSITE(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(17), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(6), 12, GFLAGS),
+    [CLK_I2S1_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(18), 0,
+            RK3568_CLKGATE_CON(6), 13, GFLAGS,
+            &rk3568_i2s1_8ch_rx_fracmux),
+    [MCLK_I2S1_8CH_RX] = GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 0, RK3568_CLKGATE_CON(6), 14, GFLAGS),
+    [I2S1_MCLKOUT_RX] = COMPOSITE_NODIV(I2S1_MCLKOUT_RX, "i2s1_mclkout_rx", i2s1_mclkout_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(17), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(6), 15, GFLAGS),
+    [CLK_I2S2_2CH_SRC] = COMPOSITE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(19), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(7), 0, GFLAGS),
+    [CLK_I2S2_2CH_FRAC] = COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(20), 0,
+            RK3568_CLKGATE_CON(7), 1, GFLAGS,
+            &rk3568_i2s2_2ch_fracmux),
+    [MCLK_I2S2_2CH] = GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 0, RK3568_CLKGATE_CON(7), 2, GFLAGS),
+    [I2S2_MCLKOUT] = COMPOSITE_NODIV(I2S2_MCLKOUT, "i2s2_mclkout", i2s2_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(19), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(7), 3, GFLAGS),
+    [CLK_I2S3_2CH_TX_SRC] = COMPOSITE(CLK_I2S3_2CH_TX_SRC, "clk_i2s3_2ch_tx_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(21), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(7), 4, GFLAGS),
+    [CLK_I2S3_2CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S3_2CH_TX_FRAC, "clk_i2s3_2ch_tx_frac", "clk_i2s3_2ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(22), 0,
+            RK3568_CLKGATE_CON(7), 5, GFLAGS,
+            &rk3568_i2s3_2ch_tx_fracmux),
+    [MCLK_I2S3_2CH_TX] = GATE(MCLK_I2S3_2CH_TX, "mclk_i2s3_2ch_tx", "clk_i2s3_2ch_tx", 0, RK3568_CLKGATE_CON(7), 6, GFLAGS),
+    [I2S3_MCLKOUT_TX] = COMPOSITE_NODIV(I2S3_MCLKOUT_TX, "i2s3_mclkout_tx", i2s3_mclkout_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(21), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(7), 7, GFLAGS),
+    [CLK_I2S3_2CH_RX_SRC] = COMPOSITE(CLK_I2S3_2CH_RX_SRC, "clk_i2s3_2ch_rx_src", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(83), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(7), 8, GFLAGS),
+    [CLK_I2S3_2CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S3_2CH_RX_FRAC, "clk_i2s3_2ch_rx_frac", "clk_i2s3_2ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(84), 0,
+            RK3568_CLKGATE_CON(7), 9, GFLAGS,
+            &rk3568_i2s3_2ch_rx_fracmux),
+    [MCLK_I2S3_2CH_RX] = GATE(MCLK_I2S3_2CH_RX, "mclk_i2s3_2ch_rx", "clk_i2s3_2ch_rx", 0, RK3568_CLKGATE_CON(7), 10, GFLAGS),
+    [I2S3_MCLKOUT_RX] = COMPOSITE_NODIV(I2S3_MCLKOUT_RX, "i2s3_mclkout_rx", i2s3_mclkout_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(83), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(7), 11, GFLAGS),
+    [HCLK_PDM] = GATE(HCLK_PDM, "hclk_pdm", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 14, GFLAGS),
+    [MCLK_PDM] = COMPOSITE_NODIV(MCLK_PDM, "mclk_pdm", mclk_pdm_p, 0,
+            RK3568_CLKSEL_CON(23), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(5), 15, GFLAGS),
+    [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(7), 12, GFLAGS),
+    [HCLK_SPDIF_8CH] = GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(7), 13, GFLAGS),
+    [MCLK_SPDIF_8CH_SRC] = COMPOSITE(MCLK_SPDIF_8CH_SRC, "mclk_spdif_8ch_src", cpll_gpll_p, 0,
+            RK3568_CLKSEL_CON(23), 14, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(7), 14, GFLAGS),
+    [MCLK_SPDIF_8CH_FRAC] = COMPOSITE_FRACMUX(MCLK_SPDIF_8CH_FRAC, "mclk_spdif_8ch_frac", "mclk_spdif_8ch_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(24), 0,
+            RK3568_CLKGATE_CON(7), 15, GFLAGS,
+            &rk3568_spdif_8ch_fracmux),
+    [MCLK_SPDIF_8CH] = &rk3568_spdif_8ch_fracmux.cell,
+    [HCLK_AUDPWM] = GATE(HCLK_AUDPWM, "hclk_audpwm", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(8), 0, GFLAGS),
+    [SCLK_AUDPWM_SRC] = COMPOSITE(SCLK_AUDPWM_SRC, "sclk_audpwm_src", gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(25), 14, 1, MFLAGS, 0, 6, DFLAGS,
+            RK3568_CLKGATE_CON(8), 1, GFLAGS),
+    [SCLK_AUDPWM_FRAC] = COMPOSITE_FRACMUX(SCLK_AUDPWM_FRAC, "sclk_audpwm_frac", "sclk_audpwm_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(26), 0,
+            RK3568_CLKGATE_CON(8), 2, GFLAGS,
+            &rk3568_audpwm_fracmux),
+    [SCLK_AUDPWM] = &rk3568_audpwm_fracmux.cell,
+    [HCLK_ACDCDIG] = GATE(HCLK_ACDCDIG, "hclk_acdcdig", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(8), 3, GFLAGS),
+    [CLK_ACDCDIG_I2C] = COMPOSITE_NODIV(CLK_ACDCDIG_I2C, "clk_acdcdig_i2c", clk_i2c_p, 0,
+            RK3568_CLKSEL_CON(23), 10, 2, MFLAGS,
+            RK3568_CLKGATE_CON(8), 4, GFLAGS),
+    [CLK_ACDCDIG_DAC] = GATE(CLK_ACDCDIG_DAC, "clk_acdcdig_dac", "mclk_i2s3_2ch_tx", 0, RK3568_CLKGATE_CON(8), 5, GFLAGS),
+    [CLK_ACDCDIG_ADC] = GATE(CLK_ACDCDIG_ADC, "clk_acdcdig_adc", "mclk_i2s3_2ch_rx", 0, RK3568_CLKGATE_CON(8), 6, GFLAGS),
+    [ACLK_SECURE_FLASH] = COMPOSITE_NODIV(ACLK_SECURE_FLASH, "aclk_secure_flash", gpll200_gpll150_gpll100_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(27), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(8), 7, GFLAGS),
+    [HCLK_SECURE_FLASH] = COMPOSITE_NODIV(HCLK_SECURE_FLASH, "hclk_secure_flash", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(27), 2, 2, MFLAGS,
+            RK3568_CLKGATE_CON(8), 8, GFLAGS),
+    [ACLK_CRYPTO_NS] = GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_flash", 0, RK3568_CLKGATE_CON(8), 11, GFLAGS),
+    [HCLK_CRYPTO_NS] = GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(8), 12, GFLAGS),
+    [CLK_CRYPTO_NS_CORE] = COMPOSITE_NODIV(CLK_CRYPTO_NS_CORE, "clk_crypto_ns_core", gpll200_gpll150_gpll100_p, 0,
+            RK3568_CLKSEL_CON(27), 4, 2, MFLAGS,
+            RK3568_CLKGATE_CON(8), 13, GFLAGS),
+    [CLK_CRYPTO_NS_PKA] = COMPOSITE_NODIV(CLK_CRYPTO_NS_PKA, "clk_crypto_ns_pka", gpll300_gpll200_gpll100_p, 0,
+            RK3568_CLKSEL_CON(27), 6, 2, MFLAGS,
+            RK3568_CLKGATE_CON(8), 14, GFLAGS),
+    [CLK_CRYPTO_NS_RNG] = GATE(CLK_CRYPTO_NS_RNG, "clk_crypto_ns_rng", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(8), 15, GFLAGS),
+    [HCLK_TRNG_NS] =GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_flash", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(9), 10, GFLAGS),
+    [CLK_TRNG_NS] = GATE(CLK_TRNG_NS, "clk_trng_ns", "hclk_secure_flash", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(9), 11, GFLAGS),
+    [PCLK_OTPC_NS] = GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(26), 9, GFLAGS),
+    [CLK_OTPC_NS_SBPI] = GATE(CLK_OTPC_NS_SBPI, "clk_otpc_ns_sbpi", "xin24m", 0, RK3568_CLKGATE_CON(26), 10, GFLAGS),
+    [CLK_OTPC_NS_USR] = GATE(CLK_OTPC_NS_USR, "clk_otpc_ns_usr", "xin_osc0_half", 0, RK3568_CLKGATE_CON(26), 11, GFLAGS),
+    [HCLK_NANDC] = GATE(HCLK_NANDC, "hclk_nandc", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 0, GFLAGS),
+    [NCLK_NANDC] = COMPOSITE_NODIV(NCLK_NANDC, "nclk_nandc", clk_nandc_p, 0,
+            RK3568_CLKSEL_CON(28), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(9), 1, GFLAGS),
+
+    [HCLK_SFC] = GATE(HCLK_SFC, "hclk_sfc", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 2, GFLAGS),
+    [HCLK_SFC_XIP] = GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 3, GFLAGS),
+    [SCLK_SFC] = COMPOSITE_NODIV(SCLK_SFC, "sclk_sfc", sclk_sfc_p, 0,
+            RK3568_CLKSEL_CON(28), 4, 3, MFLAGS,
+            RK3568_CLKGATE_CON(9), 4, GFLAGS),
+    [ACLK_EMMC] = GATE(ACLK_EMMC, "aclk_emmc", "aclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 5, GFLAGS),
+    [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 6, GFLAGS),
+    [BCLK_EMMC] = COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", gpll200_gpll150_cpll125_p, 0,
+            RK3568_CLKSEL_CON(28), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(9), 7, GFLAGS),
+    [CCLK_EMMC] = COMPOSITE_NODIV(CCLK_EMMC, "cclk_emmc", cclk_emmc_p, 0,
+            RK3568_CLKSEL_CON(28), 12, 3, MFLAGS,
+            RK3568_CLKGATE_CON(9), 8, GFLAGS),
+    [TCLK_EMMC] =GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0, RK3568_CLKGATE_CON(9), 9, GFLAGS),
+    [ACLK_PIPE] = COMPOSITE_NODIV(ACLK_PIPE, "aclk_pipe", aclk_pipe_p, 0,
+            RK3568_CLKSEL_CON(29), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(10), 0, GFLAGS),
+    [PCLK_PIPE] = COMPOSITE_NOMUX(PCLK_PIPE, "pclk_pipe", "aclk_pipe", 0,
+            RK3568_CLKSEL_CON(29), 4, 4, DFLAGS,
+            RK3568_CLKGATE_CON(10), 1, GFLAGS),
+    [ACLK_PCIE20_MST] = GATE(ACLK_PCIE20_MST, "aclk_pcie20_mst", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 0, GFLAGS),
+    [ACLK_PCIE20_SLV] = GATE(ACLK_PCIE20_SLV, "aclk_pcie20_slv", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 1, GFLAGS),
+    [ACLK_PCIE20_DBI] = GATE(ACLK_PCIE20_DBI, "aclk_pcie20_dbi", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 2, GFLAGS),
+    [PCLK_PCIE20] = GATE(PCLK_PCIE20, "pclk_pcie20", "pclk_pipe", 0, RK3568_CLKGATE_CON(12), 3, GFLAGS),
+    [CLK_PCIE20_AUX_NDFT] = GATE(CLK_PCIE20_AUX_NDFT, "clk_pcie20_aux_ndft", "xin24m", 0, RK3568_CLKGATE_CON(12), 4, GFLAGS),
+    [ACLK_PCIE30X1_MST] = GATE(ACLK_PCIE30X1_MST, "aclk_pcie30x1_mst", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 8, GFLAGS),
+    [ACLK_PCIE30X1_SLV] = GATE(ACLK_PCIE30X1_SLV, "aclk_pcie30x1_slv", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 9, GFLAGS),
+    [ACLK_PCIE30X1_DBI] = GATE(ACLK_PCIE30X1_DBI, "aclk_pcie30x1_dbi", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 10, GFLAGS),
+    [PCLK_PCIE30X1] = GATE(PCLK_PCIE30X1, "pclk_pcie30x1", "pclk_pipe", 0, RK3568_CLKGATE_CON(12), 11, GFLAGS),
+    [CLK_PCIE30X1_AUX_NDFT] = GATE(CLK_PCIE30X1_AUX_NDFT, "clk_pcie30x1_aux_ndft", "xin24m", 0, RK3568_CLKGATE_CON(12), 12, GFLAGS),
+    [ACLK_PCIE30X2_MST] = GATE(ACLK_PCIE30X2_MST, "aclk_pcie30x2_mst", "aclk_pipe", 0, RK3568_CLKGATE_CON(13), 0, GFLAGS),
+    [ACLK_PCIE30X2_SLV] = GATE(ACLK_PCIE30X2_SLV, "aclk_pcie30x2_slv", "aclk_pipe", 0, RK3568_CLKGATE_CON(13), 1, GFLAGS),
+    [ACLK_PCIE30X2_DBI] = GATE(ACLK_PCIE30X2_DBI, "aclk_pcie30x2_dbi", "aclk_pipe", 0, RK3568_CLKGATE_CON(13), 2, GFLAGS),
+    [PCLK_PCIE30X2] = GATE(PCLK_PCIE30X2, "pclk_pcie30x2", "pclk_pipe", 0, RK3568_CLKGATE_CON(13), 3, GFLAGS),
+    [CLK_PCIE30X2_AUX_NDFT] = GATE(CLK_PCIE30X2_AUX_NDFT, "clk_pcie30x2_aux_ndft", "xin24m", 0, RK3568_CLKGATE_CON(13), 4, GFLAGS),
+    [ACLK_SATA0] = GATE(ACLK_SATA0, "aclk_sata0", "aclk_pipe", 0, RK3568_CLKGATE_CON(11), 0, GFLAGS),
+    [CLK_SATA0_PMALIVE] = GATE(CLK_SATA0_PMALIVE, "clk_sata0_pmalive", "gpll_20m", 0, RK3568_CLKGATE_CON(11), 1, GFLAGS),
+    [CLK_SATA0_RXOOB] = GATE(CLK_SATA0_RXOOB, "clk_sata0_rxoob", "cpll_50m", 0, RK3568_CLKGATE_CON(11), 2, GFLAGS),
+    [ACLK_SATA1] = GATE(ACLK_SATA1, "aclk_sata1", "aclk_pipe", 0, RK3568_CLKGATE_CON(11), 4, GFLAGS),
+    [CLK_SATA1_PMALIVE] = GATE(CLK_SATA1_PMALIVE, "clk_sata1_pmalive", "gpll_20m", 0, RK3568_CLKGATE_CON(11), 5, GFLAGS),
+    [CLK_SATA1_RXOOB] = GATE(CLK_SATA1_RXOOB, "clk_sata1_rxoob", "cpll_50m", 0, RK3568_CLKGATE_CON(11), 6, GFLAGS),
+    [ACLK_SATA2] = GATE(ACLK_SATA2, "aclk_sata2", "aclk_pipe", 0, RK3568_CLKGATE_CON(11), 8, GFLAGS),
+    [CLK_SATA2_PMALIVE] = GATE(CLK_SATA2_PMALIVE, "clk_sata2_pmalive", "gpll_20m", 0, RK3568_CLKGATE_CON(11), 9, GFLAGS),
+    [CLK_SATA2_RXOOB] = GATE(CLK_SATA2_RXOOB, "clk_sata2_rxoob", "cpll_50m", 0, RK3568_CLKGATE_CON(11), 10, GFLAGS),
+    [ACLK_USB3OTG0] = GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_pipe", 0, RK3568_CLKGATE_CON(10), 8, GFLAGS),
+    [CLK_USB3OTG0_REF] = GATE(CLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0, RK3568_CLKGATE_CON(10), 9, GFLAGS),
+    [CLK_USB3OTG0_SUSPEND] = COMPOSITE_NODIV(CLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", xin24m_32k_p, 0,
+            RK3568_CLKSEL_CON(29), 8, 1, MFLAGS,
+            RK3568_CLKGATE_CON(10), 10, GFLAGS),
+    [ACLK_USB3OTG1] = GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_pipe", 0, RK3568_CLKGATE_CON(10), 12, GFLAGS),
+    [CLK_USB3OTG1_REF] = GATE(CLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0, RK3568_CLKGATE_CON(10), 13, GFLAGS),
+    [CLK_USB3OTG1_SUSPEND] = COMPOSITE_NODIV(CLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", xin24m_32k_p, 0,
+            RK3568_CLKSEL_CON(29), 9, 1, MFLAGS,
+            RK3568_CLKGATE_CON(10), 14, GFLAGS),
+    [CLK_XPCS_EEE] = COMPOSITE_NODIV(CLK_XPCS_EEE, "clk_xpcs_eee", gpll200_cpll125_p, 0,
+            RK3568_CLKSEL_CON(29), 13, 1, MFLAGS,
+            RK3568_CLKGATE_CON(10), 4, GFLAGS),
+    [PCLK_XPCS] = GATE(PCLK_XPCS, "pclk_xpcs", "pclk_pipe", 0, RK3568_CLKGATE_CON(13), 6, GFLAGS),
+    [ACLK_PHP] = COMPOSITE_NODIV(ACLK_PHP, "aclk_php", gpll300_gpll200_gpll100_xin24m_p, 0,
+            RK3568_CLKSEL_CON(30), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(14), 8, GFLAGS),
+    [HCLK_PHP] = COMPOSITE_NODIV(HCLK_PHP, "hclk_php", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(30), 2, 2, MFLAGS,
+            RK3568_CLKGATE_CON(14), 9, GFLAGS),
+    [PCLK_PHP] = COMPOSITE_NOMUX(PCLK_PHP, "pclk_php", "aclk_php", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(30), 4, 4, DFLAGS,
+            RK3568_CLKGATE_CON(14), 10, GFLAGS),
+    [HCLK_SDMMC0] = GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_php", 0, RK3568_CLKGATE_CON(15), 0, GFLAGS),
+    [CLK_SDMMC0] = COMPOSITE_NODIV(CLK_SDMMC0, "clk_sdmmc0", clk_sdmmc_p, 0,
+            RK3568_CLKSEL_CON(30), 8, 3, MFLAGS,
+            RK3568_CLKGATE_CON(15), 1, GFLAGS),
+    [HCLK_SDMMC1] = GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_php", 0, RK3568_CLKGATE_CON(15), 2, GFLAGS),
+    [CLK_SDMMC1] = COMPOSITE_NODIV(CLK_SDMMC1, "clk_sdmmc1", clk_sdmmc_p, 0,
+            RK3568_CLKSEL_CON(30), 12, 3, MFLAGS,
+            RK3568_CLKGATE_CON(15), 3, GFLAGS),
+    [ACLK_GMAC0] = GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_php", 0, RK3568_CLKGATE_CON(15), 5, GFLAGS),
+    [PCLK_GMAC0] = GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php", 0, RK3568_CLKGATE_CON(15), 6, GFLAGS),
+    [CLK_MAC0_2TOP] = COMPOSITE_NODIV(CLK_MAC0_2TOP, "clk_mac0_2top", clk_mac_2top_p, 0,
+            RK3568_CLKSEL_CON(31), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(15), 7, GFLAGS),
+    [CLK_MAC0_OUT] = COMPOSITE_NODIV(CLK_MAC0_OUT, "clk_mac0_out", cpll125_cpll50_cpll25_xin24m_p, 0,
+            RK3568_CLKSEL_CON(31), 14, 2, MFLAGS,
+            RK3568_CLKGATE_CON(15), 8, GFLAGS),
+    [CLK_MAC0_REFOUT] = GATE(CLK_MAC0_REFOUT, "clk_mac0_refout", "clk_mac0_2top", 0, RK3568_CLKGATE_CON(15), 12, GFLAGS),
+    [CLK_GMAC0_PTP_REF] = COMPOSITE_NODIV(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", clk_gmac_ptp_p, 0,
+            RK3568_CLKSEL_CON(31), 12, 2, MFLAGS,
+            RK3568_CLKGATE_CON(15), 4, GFLAGS),
+    [ACLK_USB] = COMPOSITE_NODIV(ACLK_USB, "aclk_usb", gpll300_gpll200_gpll100_xin24m_p, 0,
+            RK3568_CLKSEL_CON(32), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(16), 0, GFLAGS),
+    [HCLK_USB] = COMPOSITE_NODIV(HCLK_USB, "hclk_usb", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(32), 2, 2, MFLAGS,
+            RK3568_CLKGATE_CON(16), 1, GFLAGS),
+    [PCLK_USB] = COMPOSITE_NOMUX(PCLK_USB, "pclk_usb", "aclk_usb", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(32), 4, 4, DFLAGS,
+            RK3568_CLKGATE_CON(16), 2, GFLAGS),
+    [HCLK_USB2HOST0] = GATE(HCLK_USB2HOST0, "hclk_usb2host0", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 12, GFLAGS),
+    [HCLK_USB2HOST0_ARB] = GATE(HCLK_USB2HOST0_ARB, "hclk_usb2host0_arb", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 13, GFLAGS),
+    [HCLK_USB2HOST1] = GATE(HCLK_USB2HOST1, "hclk_usb2host1", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 14, GFLAGS),
+    [HCLK_USB2HOST1_ARB] = GATE(HCLK_USB2HOST1_ARB, "hclk_usb2host1_arb", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 15, GFLAGS),
+    [HCLK_SDMMC2] = GATE(HCLK_SDMMC2, "hclk_sdmmc2", "hclk_usb", 0, RK3568_CLKGATE_CON(17), 0, GFLAGS),
+    [CLK_SDMMC2] = COMPOSITE_NODIV(CLK_SDMMC2, "clk_sdmmc2", clk_sdmmc_p, 0,
+            RK3568_CLKSEL_CON(32), 8, 3, MFLAGS,
+            RK3568_CLKGATE_CON(17), 1, GFLAGS),
+    [ACLK_GMAC1] = GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_usb", 0, RK3568_CLKGATE_CON(17), 3, GFLAGS),
+    [PCLK_GMAC1] = GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_usb", 0, RK3568_CLKGATE_CON(17), 4, GFLAGS),
+    [CLK_MAC1_2TOP] = COMPOSITE_NODIV(CLK_MAC1_2TOP, "clk_mac1_2top", clk_mac_2top_p, 0,
+            RK3568_CLKSEL_CON(33), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(17), 5, GFLAGS),
+    [CLK_MAC1_OUT] = COMPOSITE_NODIV(CLK_MAC1_OUT, "clk_mac1_out", cpll125_cpll50_cpll25_xin24m_p, 0,
+            RK3568_CLKSEL_CON(33), 14, 2, MFLAGS,
+            RK3568_CLKGATE_CON(17), 6, GFLAGS),
+    [CLK_MAC1_REFOUT] = GATE(CLK_MAC1_REFOUT, "clk_mac1_refout", "clk_mac1_2top", 0, RK3568_CLKGATE_CON(17), 10, GFLAGS),
+    [CLK_GMAC1_PTP_REF] = COMPOSITE_NODIV(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", clk_gmac_ptp_p, 0,
+            RK3568_CLKSEL_CON(33), 12, 2, MFLAGS,
+            RK3568_CLKGATE_CON(17), 2, GFLAGS),
+    [ACLK_PERIMID] = COMPOSITE_NODIV(ACLK_PERIMID, "aclk_perimid", gpll300_gpll200_gpll100_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(10), 4, 2, MFLAGS,
+            RK3568_CLKGATE_CON(14), 0, GFLAGS),
+    [HCLK_PERIMID] = COMPOSITE_NODIV(HCLK_PERIMID, "hclk_perimid", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(10), 6, 2, MFLAGS,
+            RK3568_CLKGATE_CON(14), 1, GFLAGS),
+    [ACLK_VI] = COMPOSITE_NODIV(ACLK_VI, "aclk_vi", gpll400_gpll300_gpll200_xin24m_p, 0,
+            RK3568_CLKSEL_CON(34), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(18), 0, GFLAGS),
+    [HCLK_VI] = COMPOSITE_NOMUX(HCLK_VI, "hclk_vi", "aclk_vi", 0,
+            RK3568_CLKSEL_CON(34), 4, 4, DFLAGS,
+            RK3568_CLKGATE_CON(18), 1, GFLAGS),
+    [PCLK_VI] = COMPOSITE_NOMUX(PCLK_VI, "pclk_vi", "aclk_vi", 0,
+            RK3568_CLKSEL_CON(34), 8, 4, DFLAGS,
+            RK3568_CLKGATE_CON(18), 2, GFLAGS),
+    [ACLK_VICAP] = GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi", 0, RK3568_CLKGATE_CON(18), 9, GFLAGS),
+    [HCLK_VICAP] = GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi", 0, RK3568_CLKGATE_CON(18), 10, GFLAGS),
+    [DCLK_VICAP] = COMPOSITE_NODIV(DCLK_VICAP, "dclk_vicap", cpll333_gpll300_gpll200_p, 0,
+            RK3568_CLKSEL_CON(34), 14, 2, MFLAGS,
+            RK3568_CLKGATE_CON(18), 11, GFLAGS),
+    [ICLK_VICAP_G] = GATE(ICLK_VICAP_G, "iclk_vicap_g", "iclk_vicap", 0, RK3568_CLKGATE_CON(18), 13, GFLAGS),
+    [ACLK_ISP] = GATE(ACLK_ISP, "aclk_isp", "aclk_vi", 0, RK3568_CLKGATE_CON(19), 0, GFLAGS),
+    [HCLK_ISP] = GATE(HCLK_ISP, "hclk_isp", "hclk_vi", 0, RK3568_CLKGATE_CON(19), 1, GFLAGS),
+    [CLK_ISP] = COMPOSITE(CLK_ISP, "clk_isp", cpll_gpll_hpll_p, 0,
+            RK3568_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(19), 2, GFLAGS),
+    [PCLK_CSI2HOST1] =GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi", 0, RK3568_CLKGATE_CON(19), 4, GFLAGS),
+    [CLK_CIF_OUT] = COMPOSITE(CLK_CIF_OUT, "clk_cif_out", gpll_usb480m_xin24m_p, 0,
+            RK3568_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 6, DFLAGS,
+            RK3568_CLKGATE_CON(19), 8, GFLAGS),
+    [CLK_CAM0_OUT] = COMPOSITE(CLK_CAM0_OUT, "clk_cam0_out", gpll_usb480m_xin24m_p, 0,
+            RK3568_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 6, DFLAGS,
+            RK3568_CLKGATE_CON(19), 9, GFLAGS),
+    [CLK_CAM1_OUT] = COMPOSITE(CLK_CAM1_OUT, "clk_cam1_out", gpll_usb480m_xin24m_p, 0,
+            RK3568_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 6, DFLAGS,
+            RK3568_CLKGATE_CON(19), 10, GFLAGS),
+    [ACLK_VO] = COMPOSITE_NODIV(ACLK_VO, "aclk_vo", gpll300_cpll250_gpll100_xin24m_p, 0,
+            RK3568_CLKSEL_CON(37), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(20), 0, GFLAGS),
+    [HCLK_VO] = COMPOSITE_NOMUX(HCLK_VO, "hclk_vo", "aclk_vo", 0,
+            RK3568_CLKSEL_CON(37), 8, 4, DFLAGS,
+            RK3568_CLKGATE_CON(20), 1, GFLAGS),
+    [PCLK_VO] = COMPOSITE_NOMUX(PCLK_VO, "pclk_vo", "aclk_vo", 0,
+            RK3568_CLKSEL_CON(37), 12, 4, DFLAGS,
+            RK3568_CLKGATE_CON(20), 2, GFLAGS),
+    [ACLK_VOP_PRE] = COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", cpll_gpll_hpll_vpll_p, 0,
+            RK3568_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(20), 6, GFLAGS),
+    [ACLK_VOP] = GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK3568_CLKGATE_CON(20), 8, GFLAGS),
+    [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0, RK3568_CLKGATE_CON(20), 9, GFLAGS),
+    [DCLK_VOP0] = COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3568_CLKGATE_CON(20), 10, GFLAGS),
+    [DCLK_VOP1] = COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3568_CLKGATE_CON(20), 11, GFLAGS),
+    [DCLK_VOP2] = COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3568_CLKGATE_CON(20), 12, GFLAGS),
+    [CLK_VOP_PWM] = GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0, RK3568_CLKGATE_CON(20), 13, GFLAGS),
+    [ACLK_HDCP] = GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vo", 0, RK3568_CLKGATE_CON(21), 0, GFLAGS),
+    [HCLK_HDCP] = GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vo", 0, RK3568_CLKGATE_CON(21), 1, GFLAGS),
+    [PCLK_HDCP] = GATE(PCLK_HDCP, "pclk_hdcp", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 2, GFLAGS),
+    [PCLK_HDMI_HOST] = GATE(PCLK_HDMI_HOST, "pclk_hdmi_host", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 3, GFLAGS),
+    [CLK_HDMI_SFR] = GATE(CLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0, RK3568_CLKGATE_CON(21), 4, GFLAGS),
+    [PCLK_DSITX_0] = GATE(PCLK_DSITX_0, "pclk_dsitx_0", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 6, GFLAGS),
+    [PCLK_DSITX_1] = GATE(PCLK_DSITX_1, "pclk_dsitx_1", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 7, GFLAGS),
+    [PCLK_EDP_CTRL] = GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 8, GFLAGS),
+    [CLK_EDP_200M] = COMPOSITE_NODIV(CLK_EDP_200M, "clk_edp_200m", gpll200_gpll150_cpll125_p, 0,
+            RK3568_CLKSEL_CON(38), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(21), 9, GFLAGS),
+    [ACLK_VPU_PRE] = COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(42), 7, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(22), 0, GFLAGS),
+    [HCLK_VPU_PRE] =COMPOSITE_NOMUX(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0,
+            RK3568_CLKSEL_CON(42), 8, 4, DFLAGS,
+            RK3568_CLKGATE_CON(22), 1, GFLAGS),
+    [ACLK_VPU] = GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK3568_CLKGATE_CON(22), 4, GFLAGS),
+    [HCLK_VPU] = GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK3568_CLKGATE_CON(22), 5, GFLAGS),
+    [ACLK_RGA_PRE] = COMPOSITE_NODIV(ACLK_RGA_PRE, "aclk_rga_pre", gpll300_cpll250_gpll100_xin24m_p, 0,
+            RK3568_CLKSEL_CON(43), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(23), 0, GFLAGS),
+    [HCLK_RGA_PRE] = COMPOSITE_NOMUX(HCLK_RGA_PRE, "hclk_rga_pre", "aclk_rga_pre", 0,
+            RK3568_CLKSEL_CON(43), 8, 4, DFLAGS,
+            RK3568_CLKGATE_CON(23), 1, GFLAGS),
+    [PCLK_RGA_PRE] = COMPOSITE_NOMUX(PCLK_RGA_PRE, "pclk_rga_pre", "aclk_rga_pre", 0,
+            RK3568_CLKSEL_CON(43), 12, 4, DFLAGS,
+            RK3568_CLKGATE_CON(22), 12, GFLAGS),
+    [ACLK_RGA] = GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 4, GFLAGS),
+    [HCLK_RGA] = GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 5, GFLAGS),
+    [CLK_RGA_CORE] = COMPOSITE_NODIV(CLK_RGA_CORE, "clk_rga_core", gpll300_gpll200_gpll100_p, 0,
+            RK3568_CLKSEL_CON(43), 2, 2, MFLAGS,
+            RK3568_CLKGATE_CON(23), 6, GFLAGS),
+    [ACLK_IEP] = GATE(ACLK_IEP, "aclk_iep", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 7, GFLAGS),
+    [HCLK_IEP] = GATE(HCLK_IEP, "hclk_iep", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 8, GFLAGS),
+    [CLK_IEP_CORE] = COMPOSITE_NODIV(CLK_IEP_CORE, "clk_iep_core", gpll300_gpll200_gpll100_p, 0,
+            RK3568_CLKSEL_CON(43), 4, 2, MFLAGS,
+            RK3568_CLKGATE_CON(23), 9, GFLAGS),
+    [HCLK_EBC] = GATE(HCLK_EBC, "hclk_ebc", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 10, GFLAGS),
+    [DCLK_EBC] = COMPOSITE_NODIV(DCLK_EBC, "dclk_ebc", gpll400_cpll333_gpll200_p, 0,
+            RK3568_CLKSEL_CON(43), 6, 2, MFLAGS,
+            RK3568_CLKGATE_CON(23), 11, GFLAGS),
+    [ACLK_JDEC] = GATE(ACLK_JDEC, "aclk_jdec", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 12, GFLAGS),
+    [HCLK_JDEC] = GATE(HCLK_JDEC, "hclk_jdec", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 13, GFLAGS),
+    [ACLK_JENC] = GATE(ACLK_JENC, "aclk_jenc", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 14, GFLAGS),
+    [HCLK_JENC] = GATE(HCLK_JENC, "hclk_jenc", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 15, GFLAGS),
+    [PCLK_EINK] = GATE(PCLK_EINK, "pclk_eink", "pclk_rga_pre", 0, RK3568_CLKGATE_CON(22), 14, GFLAGS),
+    [HCLK_EINK] = GATE(HCLK_EINK, "hclk_eink", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(22), 15, GFLAGS),
+    [ACLK_RKVENC_PRE] = COMPOSITE(ACLK_RKVENC_PRE, "aclk_rkvenc_pre", gpll_cpll_npll_p, 0,
+            RK3568_CLKSEL_CON(44), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(24), 0, GFLAGS),
+    [HCLK_RKVENC_PRE] = COMPOSITE_NOMUX(HCLK_RKVENC_PRE, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0,
+            RK3568_CLKSEL_CON(44), 8, 4, DFLAGS,
+            RK3568_CLKGATE_CON(24), 1, GFLAGS),
+    [ACLK_RKVENC] = GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0, RK3568_CLKGATE_CON(24), 6, GFLAGS),
+    [HCLK_RKVENC] = GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0, RK3568_CLKGATE_CON(24), 7, GFLAGS),
+    [CLK_RKVENC_CORE] = COMPOSITE(CLK_RKVENC_CORE, "clk_rkvenc_core", gpll_cpll_npll_vpll_p, 0,
+            RK3568_CLKSEL_CON(45), 14, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(24), 8, GFLAGS),
+    [ACLK_RKVDEC_PRE] = COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", aclk_rkvdec_pre_p, 0,
+            RK3568_CLKSEL_CON(47), 7, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(25), 0, GFLAGS),
+    [HCLK_RKVDEC_PRE] = COMPOSITE_NOMUX(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0,
+            RK3568_CLKSEL_CON(47), 8, 4, DFLAGS,
+            RK3568_CLKGATE_CON(25), 1, GFLAGS),
+    [ACLK_RKVDEC] = GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK3568_CLKGATE_CON(25), 4, GFLAGS),
+    [HCLK_RKVDEC] = GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK3568_CLKGATE_CON(25), 5, GFLAGS),
+    [CLK_RKVDEC_CA] = COMPOSITE(CLK_RKVDEC_CA, "clk_rkvdec_ca", gpll_cpll_npll_vpll_p, 0,
+            RK3568_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(25), 6, GFLAGS),
+    [CLK_RKVDEC_CORE] = COMPOSITE(CLK_RKVDEC_CORE, "clk_rkvdec_core", clk_rkvdec_core_p, 0,
+            RK3568_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(25), 7, GFLAGS),
+    [CLK_RKVDEC_HEVC_CA] = COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_npll_vpll_p, 0,
+            RK3568_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(25), 8, GFLAGS),
+    [ACLK_BUS] = COMPOSITE_NODIV(ACLK_BUS, "aclk_bus", gpll200_gpll150_gpll100_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(50), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(26), 0, GFLAGS),
+    [PCLK_BUS] = COMPOSITE_NODIV(PCLK_BUS, "pclk_bus", gpll100_gpll75_cpll50_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(50), 4, 2, MFLAGS,
+            RK3568_CLKGATE_CON(26), 1, GFLAGS),
+    [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0, RK3568_CLKGATE_CON(26), 4, GFLAGS),
+    [CLK_TSADC_TSEN] = COMPOSITE(CLK_TSADC_TSEN, "clk_tsadc_tsen", xin24m_gpll100_cpll100_p, 0,
+            RK3568_CLKSEL_CON(51), 4, 2, MFLAGS, 0, 3, DFLAGS,
+            RK3568_CLKGATE_CON(26), 5, GFLAGS),
+    [CLK_TSADC] = COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "clk_tsadc_tsen", 0,
+            RK3568_CLKSEL_CON(51), 8, 7, DFLAGS,
+            RK3568_CLKGATE_CON(26), 6, GFLAGS),
+    [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3568_CLKGATE_CON(26), 7, GFLAGS),
+    [CLK_SARADC] = GATE(CLK_SARADC, "clk_saradc", "xin24m", 0, RK3568_CLKGATE_CON(26), 8, GFLAGS),
+    [PCLK_SCR] = GATE(PCLK_SCR, "pclk_scr", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(26), 12, GFLAGS),
+    [PCLK_WDT_NS] = GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus", 0, RK3568_CLKGATE_CON(26), 13, GFLAGS),
+    [TCLK_WDT_NS] = GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0, RK3568_CLKGATE_CON(26), 14, GFLAGS),
+    [ACLK_MCU] = GATE(ACLK_MCU, "aclk_mcu", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(32), 13, GFLAGS),
+    [PCLK_INTMUX] = GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(32), 14, GFLAGS),
+    [PCLK_MAILBOX] = GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus", 0, RK3568_CLKGATE_CON(32), 15, GFLAGS),
+    [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 12, GFLAGS),
+    [CLK_UART1_SRC] = COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(52), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(27), 13, GFLAGS),
+    [CLK_UART1_FRAC] = COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(53), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(27), 14, GFLAGS,
+            &rk3568_uart1_fracmux),
+    [SCLK_UART1] = GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_mux", 0, RK3568_CLKGATE_CON(27), 15, GFLAGS),
+    [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 0, GFLAGS),
+    [CLK_UART2_SRC] = COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(54), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(28), 1, GFLAGS),
+    [CLK_UART2_FRAC] = COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(55), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(28), 2, GFLAGS,
+            &rk3568_uart2_fracmux),
+    [SCLK_UART2] = GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_mux", 0, RK3568_CLKGATE_CON(28), 3, GFLAGS),
+    [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 4, GFLAGS),
+    [CLK_UART3_SRC] = COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(56), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(28), 5, GFLAGS),
+    [CLK_UART3_FRAC] = COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(57), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(28), 6, GFLAGS,
+            &rk3568_uart3_fracmux),
+    [SCLK_UART3] = GATE(SCLK_UART3, "sclk_uart3", "sclk_uart3_mux", 0, RK3568_CLKGATE_CON(28), 7, GFLAGS),
+    [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 8, GFLAGS),
+    [CLK_UART4_SRC] = COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(58), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(28), 9, GFLAGS),
+    [CLK_UART4_FRAC] = COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(59), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(28), 10, GFLAGS,
+            &rk3568_uart4_fracmux),
+    [SCLK_UART4] = GATE(SCLK_UART4, "sclk_uart4", "sclk_uart4_mux", 0, RK3568_CLKGATE_CON(28), 11, GFLAGS),
+    [PCLK_UART5] = GATE(PCLK_UART5, "pclk_uart5", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 12, GFLAGS),
+    [CLK_UART5_SRC] = COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(60), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(28), 13, GFLAGS),
+    [CLK_UART5_FRAC] = COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(61), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(28), 14, GFLAGS,
+            &rk3568_uart5_fracmux),
+    [SCLK_UART5] = GATE(SCLK_UART5, "sclk_uart5", "sclk_uart5_mux", 0, RK3568_CLKGATE_CON(28), 15, GFLAGS),
+    [PCLK_UART6] =GATE(PCLK_UART6, "pclk_uart6", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 0, GFLAGS),
+    [CLK_UART6_SRC] = COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(62), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(29), 1, GFLAGS),
+    [CLK_UART6_FRAC] = COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(63), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(29), 2, GFLAGS,
+            &rk3568_uart6_fracmux),
+    [SCLK_UART6] = GATE(SCLK_UART6, "sclk_uart6", "sclk_uart6_mux", 0, RK3568_CLKGATE_CON(29), 3, GFLAGS),
+    [PCLK_UART7] = GATE(PCLK_UART7, "pclk_uart7", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 4, GFLAGS),
+    [CLK_UART7_SRC] = COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(64), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(29), 5, GFLAGS),
+    [CLK_UART7_FRAC] = COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(65), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(29), 6, GFLAGS,
+            &rk3568_uart7_fracmux),
+    [SCLK_UART7] = GATE(SCLK_UART7, "sclk_uart7", "sclk_uart7_mux", 0, RK3568_CLKGATE_CON(29), 7, GFLAGS),
+    [PCLK_UART8] = GATE(PCLK_UART8, "pclk_uart8", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 8, GFLAGS),
+    [CLK_UART8_SRC] = COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(66), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(29), 9, GFLAGS),
+    [CLK_UART8_FRAC] = COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(67), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(29), 10, GFLAGS,
+            &rk3568_uart8_fracmux),
+    [SCLK_UART8] = GATE(SCLK_UART8, "sclk_uart8", "sclk_uart8_mux", 0, RK3568_CLKGATE_CON(29), 11, GFLAGS),
+    [PCLK_UART9] =GATE(PCLK_UART9, "pclk_uart9", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 12, GFLAGS),
+    [CLK_UART9_SRC] =COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_usb480m_p, 0,
+            RK3568_CLKSEL_CON(68), 8, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3568_CLKGATE_CON(29), 13, GFLAGS),
+    [CLK_UART9_FRAC] =COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(69), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3568_CLKGATE_CON(29), 14, GFLAGS,
+            &rk3568_uart9_fracmux),
+    [SCLK_UART9] =GATE(SCLK_UART9, "sclk_uart9", "sclk_uart9_mux", 0, RK3568_CLKGATE_CON(29), 15, GFLAGS),
+    [PCLK_CAN0] =GATE(PCLK_CAN0, "pclk_can0", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 5, GFLAGS),
+    [CLK_CAN0] =COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(70), 7, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(27), 6, GFLAGS),
+    [PCLK_CAN1] = GATE(PCLK_CAN1, "pclk_can1", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 7, GFLAGS),
+    [CLK_CAN1] = COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(70), 15, 1, MFLAGS, 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(27), 8, GFLAGS),
+    [PCLK_CAN2] = GATE(PCLK_CAN2, "pclk_can2", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 9, GFLAGS),
+    [CLK_CAN2] = COMPOSITE(CLK_CAN2, "clk_can2", gpll_cpll_p, 0,
+            RK3568_CLKSEL_CON(71), 7, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(27), 10, GFLAGS),
+    [CLK_I2C] = COMPOSITE_NODIV(CLK_I2C, "clk_i2c", clk_i2c_p, 0,
+            RK3568_CLKSEL_CON(71), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(32), 10, GFLAGS),
+    [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 0, GFLAGS),
+    [CLK_I2C1] = GATE(CLK_I2C1, "clk_i2c1", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 1, GFLAGS),
+    [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 2, GFLAGS),
+    [CLK_I2C2] = GATE(CLK_I2C2, "clk_i2c2", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 3, GFLAGS),
+    [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 4, GFLAGS),
+    [CLK_I2C3] = GATE(CLK_I2C3, "clk_i2c3", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 5, GFLAGS),
+    [PCLK_I2C4] = GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 6, GFLAGS),
+    [CLK_I2C4] = GATE(CLK_I2C4, "clk_i2c4", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 7, GFLAGS),
+    [PCLK_I2C5] = GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 8, GFLAGS),
+    [CLK_I2C5] = GATE(CLK_I2C5, "clk_i2c5", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 9, GFLAGS),
+    [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 10, GFLAGS),
+    [CLK_SPI0] = COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", gpll200_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 0, 1, MFLAGS,
+            RK3568_CLKGATE_CON(30), 11, GFLAGS),
+    [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 12, GFLAGS),
+    [CLK_SPI1] = COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", gpll200_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 2, 1, MFLAGS,
+            RK3568_CLKGATE_CON(30), 13, GFLAGS),
+    [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 14, GFLAGS),
+    [CLK_SPI2] = COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", gpll200_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 4, 1, MFLAGS,
+            RK3568_CLKGATE_CON(30), 15, GFLAGS),
+    [PCLK_SPI3] = GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 0, GFLAGS),
+    [CLK_SPI3] = COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", gpll200_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 6, 1, MFLAGS, RK3568_CLKGATE_CON(31), 1, GFLAGS),
+    [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 10, GFLAGS),
+    [CLK_PWM1] = COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", gpll100_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(31), 11, GFLAGS),
+    [CLK_PWM1_CAPTURE] = GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 0, RK3568_CLKGATE_CON(31), 12, GFLAGS),
+    [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 13, GFLAGS),
+    [CLK_PWM2] = COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", gpll100_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 10, 2, MFLAGS,
+            RK3568_CLKGATE_CON(31), 14, GFLAGS),
+    [CLK_PWM2_CAPTURE] = GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 0, RK3568_CLKGATE_CON(31), 15, GFLAGS),
+    [PCLK_PWM3] = GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus", 0, RK3568_CLKGATE_CON(32), 0, GFLAGS),
+    [CLK_PWM3] = COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", gpll100_xin24m_cpll100_p, 0,
+            RK3568_CLKSEL_CON(72), 12, 2, MFLAGS,
+            RK3568_CLKGATE_CON(32), 1, GFLAGS),
+    [CLK_PWM3_CAPTURE] = GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 0, RK3568_CLKGATE_CON(32), 2, GFLAGS),
+    [DBCLK_GPIO] = COMPOSITE_NODIV(DBCLK_GPIO, "dbclk_gpio", xin24m_32k_p, 0,
+            RK3568_CLKSEL_CON(72), 14, 1, MFLAGS,
+            RK3568_CLKGATE_CON(32), 11, GFLAGS),
+    [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 2, GFLAGS),
+    [DBCLK_GPIO1] = GATE(DBCLK_GPIO1, "dbclk_gpio1", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 3, GFLAGS),
+    [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 4, GFLAGS),
+    [DBCLK_GPIO2] = GATE(DBCLK_GPIO2, "dbclk_gpio2", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 5, GFLAGS),
+    [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 6, GFLAGS),
+    [DBCLK_GPIO3] = GATE(DBCLK_GPIO3, "dbclk_gpio3", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 7, GFLAGS),
+    [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 8, GFLAGS),
+    [DBCLK_GPIO4] = GATE(DBCLK_GPIO4, "dbclk_gpio4", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 9, GFLAGS),
+    [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0, RK3568_CLKGATE_CON(32), 3, GFLAGS),
+    [CLK_TIMER0] = GATE(CLK_TIMER0, "clk_timer0", "xin24m", 0, RK3568_CLKGATE_CON(32), 4, GFLAGS),
+    [CLK_TIMER1] = GATE(CLK_TIMER1, "clk_timer1", "xin24m", 0, RK3568_CLKGATE_CON(32), 5, GFLAGS),
+    [CLK_TIMER2] = GATE(CLK_TIMER2, "clk_timer2", "xin24m", 0, RK3568_CLKGATE_CON(32), 6, GFLAGS),
+    [CLK_TIMER3] = GATE(CLK_TIMER3, "clk_timer3", "xin24m", 0, RK3568_CLKGATE_CON(32), 7, GFLAGS),
+    [CLK_TIMER4] = GATE(CLK_TIMER4, "clk_timer4", "xin24m", 0, RK3568_CLKGATE_CON(32), 8, GFLAGS),
+    [CLK_TIMER5] = GATE(CLK_TIMER5, "clk_timer5", "xin24m", 0, RK3568_CLKGATE_CON(32), 9, GFLAGS),
+    [ACLK_TOP_HIGH] = COMPOSITE_NODIV(ACLK_TOP_HIGH, "aclk_top_high", cpll500_gpll400_gpll300_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(73), 0, 2, MFLAGS,
+            RK3568_CLKGATE_CON(33), 0, GFLAGS),
+    [ACLK_TOP_LOW] = COMPOSITE_NODIV(ACLK_TOP_LOW, "aclk_top_low", gpll400_gpll300_gpll200_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(73), 4, 2, MFLAGS,
+            RK3568_CLKGATE_CON(33), 1, GFLAGS),
+    [HCLK_TOP] = COMPOSITE_NODIV(HCLK_TOP, "hclk_top", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(73), 8, 2, MFLAGS,
+            RK3568_CLKGATE_CON(33), 2, GFLAGS),
+    [PCLK_TOP] = COMPOSITE_NODIV(PCLK_TOP, "pclk_top", gpll100_gpll75_cpll50_xin24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(73), 12, 2, MFLAGS,
+            RK3568_CLKGATE_CON(33), 3, GFLAGS),
+    [PCLK_PCIE30PHY] = GATE(PCLK_PCIE30PHY, "pclk_pcie30phy", "pclk_top", 0, RK3568_CLKGATE_CON(33), 8, GFLAGS),
+    [CLK_OPTC_ARB] = COMPOSITE_NODIV(CLK_OPTC_ARB, "clk_optc_arb", xin24m_cpll100_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(73), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(33), 9, GFLAGS),
+    [PCLK_MIPICSIPHY] = GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top", 0, RK3568_CLKGATE_CON(33), 13, GFLAGS),
+    [PCLK_MIPIDSIPHY0] = GATE(PCLK_MIPIDSIPHY0, "pclk_mipidsiphy0", "pclk_top", 0, RK3568_CLKGATE_CON(33), 14, GFLAGS),
+    [PCLK_MIPIDSIPHY1] = GATE(PCLK_MIPIDSIPHY1, "pclk_mipidsiphy1", "pclk_top", 0, RK3568_CLKGATE_CON(33), 15, GFLAGS),
+    [PCLK_PIPEPHY0] = GATE(PCLK_PIPEPHY0, "pclk_pipephy0", "pclk_top", 0, RK3568_CLKGATE_CON(34), 4, GFLAGS),
+    [PCLK_PIPEPHY1] = GATE(PCLK_PIPEPHY1, "pclk_pipephy1", "pclk_top", 0, RK3568_CLKGATE_CON(34), 5, GFLAGS),
+    [PCLK_PIPEPHY2] = GATE(PCLK_PIPEPHY2, "pclk_pipephy2", "pclk_top", 0, RK3568_CLKGATE_CON(34), 6, GFLAGS),
+    [PCLK_CPU_BOOST] = GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_top", 0, RK3568_CLKGATE_CON(34), 11, GFLAGS),
+    [CLK_CPU_BOOST] = GATE(CLK_CPU_BOOST, "clk_cpu_boost", "xin24m", 0, RK3568_CLKGATE_CON(34), 12, GFLAGS),
+    [PCLK_OTPPHY] = GATE(PCLK_OTPPHY, "pclk_otpphy", "pclk_top", 0, RK3568_CLKGATE_CON(34), 13, GFLAGS),
+    [SCLK_GMAC0] = MUX(SCLK_GMAC0, "clk_gmac0", mux_gmac0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(31), 2, 1, MFLAGS),
+    [SCLK_GMAC0_RGMII_SPEED] = MUX(SCLK_GMAC0_RGMII_SPEED, "clk_gmac0_rgmii_speed", mux_gmac0_rgmii_speed_p, 0,
+            RK3568_CLKSEL_CON(31), 4, 2, MFLAGS),
+    [SCLK_GMAC0_RMII_SPEED] = MUX(SCLK_GMAC0_RMII_SPEED, "clk_gmac0_rmii_speed", mux_gmac0_rmii_speed_p, 0,
+            RK3568_CLKSEL_CON(31), 3, 1, MFLAGS),
+    [SCLK_GMAC0_RX_TX] = MUX(SCLK_GMAC0_RX_TX, "clk_gmac0_rx_tx", mux_gmac0_rx_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(31), 0, 2, MFLAGS),
+    [SCLK_GMAC1] = MUX(SCLK_GMAC1, "clk_gmac1", mux_gmac1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(33), 2, 1, MFLAGS),
+    [SCLK_GMAC1_RGMII_SPEED] = MUX(SCLK_GMAC1_RGMII_SPEED, "clk_gmac1_rgmii_speed", mux_gmac1_rgmii_speed_p, 0,
+            RK3568_CLKSEL_CON(33), 4, 2, MFLAGS),
+    [SCLK_GMAC1_RMII_SPEED] = MUX(SCLK_GMAC1_RMII_SPEED, "clk_gmac1_rmii_speed", mux_gmac1_rmii_speed_p, 0,
+            RK3568_CLKSEL_CON(33), 3, 1, MFLAGS),
+    [SCLK_GMAC1_RX_TX] = MUX(SCLK_GMAC1_RX_TX, "clk_gmac1_rx_tx", mux_gmac1_rx_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_CLKSEL_CON(33), 0, 2, MFLAGS),
+    [SCLK_SDMMC0_DRV] = MMC(SCLK_SDMMC0_DRV, "sdmmc0_drv", "clk_sdmmc0", RK3568_SDMMC0_CON0, 1),
+    [SCLK_SDMMC0_SAMPLE] = MMC(SCLK_SDMMC0_SAMPLE, "sdmmc0_sample", "clk_sdmmc0", RK3568_SDMMC0_CON1, 1),
+    [SCLK_SDMMC1_DRV] = MMC(SCLK_SDMMC1_DRV, "sdmmc1_drv", "clk_sdmmc1", RK3568_SDMMC1_CON0, 1),
+    [SCLK_SDMMC1_SAMPLE] = MMC(SCLK_SDMMC1_SAMPLE, "sdmmc1_sample", "clk_sdmmc1", RK3568_SDMMC1_CON1, 1),
+    [SCLK_SDMMC2_DRV] = MMC(SCLK_SDMMC2_DRV, "sdmmc2_drv", "clk_sdmmc2", RK3568_SDMMC2_CON0, 1),
+    [SCLK_SDMMC2_SAMPLE] = MMC(SCLK_SDMMC2_SAMPLE, "sdmmc2_sample", "clk_sdmmc2", RK3568_SDMMC2_CON1, 1),
+    [SCLK_EMMC_DRV] = MMC(SCLK_EMMC_DRV, "emmc_drv", "cclk_emmc", RK3568_EMMC_CON0, 1),
+    [SCLK_EMMC_SAMPLE] = MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "cclk_emmc", RK3568_EMMC_CON1, 1),
+    [PCLK_EDPPHY_GRF] = GATE(PCLK_EDPPHY_GRF, "pclk_edpphy_grf", "pclk_top", 0, RK3568_CLKGATE_CON(34), 14, GFLAGS),
+    [CLK_HDMI_CEC] = GATE(CLK_HDMI_CEC, "clk_hdmi_cec", "clk_rtc_32k", 0, RK3568_CLKGATE_CON(21), 5, GFLAGS),
+    [CLK_I2S0_8CH_TX] = &rk3568_i2s0_8ch_tx_fracmux.cell,
+    [CLK_I2S0_8CH_RX] = &rk3568_i2s0_8ch_rx_fracmux.cell,
+    [CLK_I2S1_8CH_TX] = &rk3568_i2s1_8ch_tx_fracmux.cell,
+    [CLK_I2S1_8CH_RX] = &rk3568_i2s1_8ch_rx_fracmux.cell,
+    [CLK_I2S2_2CH] = &rk3568_i2s2_2ch_fracmux.cell,
+    [CLK_I2S3_2CH_TX] = &rk3568_i2s3_2ch_tx_fracmux.cell,
+    [CLK_I2S3_2CH_RX] = &rk3568_i2s3_2ch_rx_fracmux.cell,
+    [CPLL_500M] = COMPOSITE_NOMUX(CPLL_500M, "cpll_500m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(78), 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 7, GFLAGS),
+    [CPLL_250M] = COMPOSITE_NOMUX(CPLL_250M, "cpll_250m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(79), 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 9, GFLAGS),
+    [CPLL_125M] = COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(80), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 10, GFLAGS),
+    [CPLL_62P5M] = COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(80), 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 12, GFLAGS),
+    [CPLL_50M] = COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(81), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 13, GFLAGS),
+    [CPLL_25M] = COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(81), 8, 6, DFLAGS,
+            RK3568_CLKGATE_CON(35), 14, GFLAGS),
+    [CPLL_100M] = COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(82), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 11, GFLAGS),
+    [I2S1_MCLKOUT] = MUXGRF(I2S1_MCLKOUT, "i2s1_mclkout", i2s1_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_GRF_SOC_CON1, 5, 1, MFLAGS),
+    [I2S3_MCLKOUT] = MUXGRF(I2S3_MCLKOUT, "i2s3_mclkout", i2s3_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3568_GRF_SOC_CON2, 15, 1, MFLAGS),
+    [I2S1_MCLK_RX_IOE] = MUXGRF(I2S1_MCLK_RX_IOE, "i2s1_mclk_rx_ioe", i2s1_mclk_rx_ioe_p, 0,
+            RK3568_GRF_SOC_CON2, 0, 1, MFLAGS),
+    [I2S1_MCLK_TX_IOE] = MUXGRF(I2S1_MCLK_TX_IOE, "i2s1_mclk_tx_ioe", i2s1_mclk_tx_ioe_p, 0,
+            RK3568_GRF_SOC_CON2, 1, 1, MFLAGS),
+    [I2S2_MCLK_IOE] = MUXGRF(I2S2_MCLK_IOE, "i2s2_mclk_ioe", i2s2_mclk_ioe_p, 0,
+            RK3568_GRF_SOC_CON2, 2, 1, MFLAGS),
+    [I2S3_MCLK_IOE] = MUXGRF(I2S3_MCLK_IOE, "i2s3_mclk_ioe", i2s3_mclk_ioe_p, 0,
+            RK3568_GRF_SOC_CON2, 3, 1, MFLAGS),
+    [PCLK_CORE_PVTM] = GATE(PCLK_CORE_PVTM, "pclk_core_pvtm", "pclk_core_pre", 0, RK3568_CLKGATE_CON(1), 9, GFLAGS),
+
+    &rk3568_uart1_fracmux.cell,
+    &rk3568_uart2_fracmux.cell,
+    &rk3568_uart3_fracmux.cell,
+    &rk3568_uart4_fracmux.cell,
+    &rk3568_uart5_fracmux.cell,
+    &rk3568_uart6_fracmux.cell,
+    &rk3568_uart7_fracmux.cell,
+    &rk3568_uart8_fracmux.cell,
+    &rk3568_uart9_fracmux.cell,
+
+    COMPOSITE_NOMUX(0, "gpll_400m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(75), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 0, GFLAGS),
+    COMPOSITE_NOMUX(0, "gpll_300m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(75), 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 1, GFLAGS),
+    COMPOSITE_NOMUX(0, "gpll_200m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(76), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 2, GFLAGS),
+    COMPOSITE_NOMUX(0, "gpll_150m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(76), 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 3, GFLAGS),
+    COMPOSITE_NOMUX(0, "gpll_100m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(77), 0, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 4, GFLAGS),
+    COMPOSITE_NOMUX(0, "gpll_75m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(77), 8, 5, DFLAGS,
+            RK3568_CLKGATE_CON(35), 5, GFLAGS),
+    COMPOSITE_NOMUX(0, "gpll_20m", "gpll", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(78), 0, 6, DFLAGS,
+            RK3568_CLKGATE_CON(35), 6, GFLAGS),
+    COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", RT_CLK_F_IGNORE_UNUSED,
+            RK3568_CLKSEL_CON(82), 8, 6, DFLAGS,
+            RK3568_CLKGATE_CON(35), 15, GFLAGS),
+    FACTOR(0, "clk_osc0_div_375k", "clk_osc0_div_750k", 0, 1, 2),
+    FACTOR(0, "xin_osc0_half", "xin24m", 0, 1, 2),
+    COMPOSITE(0, "sclk_core_src", apll_gpll_npll_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 5, GFLAGS),
+    COMPOSITE_NODIV(0, "sclk_core", sclk_core_pre_p, RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(2), 15, 1, MFLAGS,
+            RK3568_CLKGATE_CON(0), 7, GFLAGS),
+    COMPOSITE_NOMUX(0, "atclk_core", "armclk", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 8, GFLAGS),
+    COMPOSITE_NOMUX(0, "gicclk_core", "armclk", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 9, GFLAGS),
+    COMPOSITE_NOMUX(0, "pclk_core_pre", "armclk", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(4), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 10, GFLAGS),
+    COMPOSITE_NOMUX(0, "periphclk_core_pre", "armclk", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(4), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 11, GFLAGS),
+    COMPOSITE_NOMUX(0, "tsclk_core", "periphclk_core_pre", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(5), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 14, GFLAGS),
+    COMPOSITE_NOMUX(0, "cntclk_core", "periphclk_core_pre", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(5), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(0), 15, GFLAGS),
+    COMPOSITE_NOMUX(0, "aclk_core", "sclk_core", RT_CLK_F_IS_CRITICAL,
+            RK3568_CLKSEL_CON(5), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3568_CLKGATE_CON(1), 0, GFLAGS),
+    FACTOR(0, "clk_gmac0_tx_div5", "clk_gmac0", 0, 1, 5),
+    FACTOR(0, "clk_gmac0_tx_div50", "clk_gmac0", 0, 1, 50),
+    FACTOR(0, "clk_gmac0_rx_div2", "clk_gmac0", 0, 1, 2),
+    FACTOR(0, "clk_gmac0_rx_div20", "clk_gmac0", 0, 1, 20),
+    FACTOR(0, "clk_gmac1_tx_div5", "clk_gmac1", 0, 1, 5),
+    FACTOR(0, "clk_gmac1_tx_div50", "clk_gmac1", 0, 1, 50),
+    FACTOR(0, "clk_gmac1_rx_div2", "clk_gmac1", 0, 1, 2),
+    FACTOR(0, "clk_gmac1_rx_div20", "clk_gmac1", 0, 1, 20),
+};
+
+static rt_err_t clk_rk3568_cru_init(struct clk_rk3568_cru *cru)
+{
+    cru->clk_parent.cells = rk3568_clk_cells;
+    cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3568_clk_cells);
+
+    return RT_EOK;
+}
+
+static rt_err_t clk_rk3568_pmucru_init(struct clk_rk3568_cru *cru)
+{
+    cru->clk_parent.cells = rk3568_clk_pmu_cells;
+    cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3568_clk_pmu_cells);
+
+    return RT_EOK;
+}
+
+static rt_err_t clk_rk3568_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_device *dev = &pdev->parent;
+    struct clk_rk3568_cru *cru = rt_calloc(1, sizeof(*cru));
+    rt_err_t (*init)(struct clk_rk3568_cru *cru) = (void *)pdev->id->data;
+
+    if (!cru)
+    {
+        return -RT_ENOMEM;
+    }
+
+    cru->provider.reg_base = rt_dm_dev_iomap(dev, 0);
+
+    if (!cru->provider.reg_base)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf");
+    cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf");
+
+    cru->clk_parent.dev = dev;
+
+    if ((err = init(cru)))
+    {
+        goto _fail;
+    }
+
+    rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rt_clk_register(&cru->clk_parent)))
+    {
+        goto _fail;
+    }
+
+    rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL,
+        cru->provider.reg_base + RK3568_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK)))
+    {
+        goto _clk_unregister;
+    }
+
+    rockchip_register_restart_notifier(&cru->provider, RK3568_GLB_SRST_FST, RT_NULL);
+
+    return RT_EOK;
+
+_clk_unregister:
+    rt_clk_unregister(&cru->clk_parent);
+
+_fail:
+    if (cru->provider.reg_base)
+    {
+        rt_iounmap(cru->provider.reg_base);
+    }
+
+    rt_free(cru);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id clk_rk3568_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3568-cru", .data = (void *)clk_rk3568_cru_init },
+    { .compatible = "rockchip,rk3568-pmucru", .data = (void *)clk_rk3568_pmucru_init },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver clk_rk3568_driver =
+{
+    .name = "clk-rk3568",
+    .ids = clk_rk3568_ofw_ids,
+
+    .probe = clk_rk3568_probe,
+};
+
+static int clk_rk3568_register(void)
+{
+    rt_platform_driver_register(&clk_rk3568_driver);
+
+    return 0;
+}
+INIT_SUBSYS_EXPORT(clk_rk3568_register);

+ 1839 - 0
bsp/rockchip/dm/clk/clk-rk3576.c

@@ -0,0 +1,1839 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-composite.h"
+#include "clk-rk-cpu.h"
+#include "clk-rk-divider.h"
+#include "clk-rk-factor.h"
+#include "clk-rk-fraction-divider.h"
+#include "clk-rk-gate.h"
+#include "clk-rk.h"
+#include "clk-rk-half-divider.h"
+#include "clk-rk-mmc-phase.h"
+#include "clk-rk-muxgrf.h"
+#include "clk-rk-mux.h"
+#include "clk-rk-pll.h"
+
+#define DBG_TAG "clk.rk3576"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <dt-bindings/clock/rk3576-cru.h>
+
+#define RK3576_GRF_SOC_STATUS0              0x600
+#define RK3576_PMU0_GRF_OSC_CON6            0x18
+
+#define RK3576_PHP_CRU_BASE                 0x8000
+#define RK3576_SECURE_NS_CRU_BASE           0x10000
+#define RK3576_PMU_CRU_BASE                 0x20000
+#define RK3576_BIGCORE_CRU_BASE             0x38000
+#define RK3576_LITCORE_CRU_BASE             0x40000
+#define RK3576_CCI_CRU_BASE                 0x48000
+
+#define RK3576_PLL_CON(x)                   ((x) * 0x4)
+#define RK3576_MODE_CON0                    0x280
+#define RK3576_BPLL_MODE_CON0               (RK3576_BIGCORE_CRU_BASE + 0x280)
+#define RK3576_LPLL_MODE_CON0               (RK3576_LITCORE_CRU_BASE + 0x280)
+#define RK3576_PPLL_MODE_CON0               (RK3576_PHP_CRU_BASE + 0x280)
+#define RK3576_CLKSEL_CON(x)                ((x) * 0x4 + 0x300)
+#define RK3576_CLKGATE_CON(x)               ((x) * 0x4 + 0x800)
+#define RK3576_SOFTRST_CON(x)               ((x) * 0x4 + 0xa00)
+#define RK3576_GLB_CNT_TH                   0xc00
+#define RK3576_GLB_SRST_FST                 0xc08
+#define RK3576_GLB_SRST_SND                 0xc0c
+#define RK3576_GLB_RST_CON                  0xc10
+#define RK3576_GLB_RST_ST                   0xc04
+#define RK3576_SDIO_CON0                    0xc24
+#define RK3576_SDIO_CON1                    0xc28
+#define RK3576_SDMMC_CON0                   0xc30
+#define RK3576_SDMMC_CON1                   0xc34
+
+#define RK3576_PHP_CLKSEL_CON(x)            ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0x300)
+#define RK3576_PHP_CLKGATE_CON(x)           ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0x800)
+#define RK3576_PHP_SOFTRST_CON(x)           ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0xa00)
+
+#define RK3576_PMU_PLL_CON(x)               ((x) * 0x4 + RK3576_PHP_CRU_BASE)
+#define RK3576_PMU_CLKSEL_CON(x)            ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0x300)
+#define RK3576_PMU_CLKGATE_CON(x)           ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0x800)
+#define RK3576_PMU_SOFTRST_CON(x)           ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0xa00)
+
+#define RK3576_SECURE_NS_CLKSEL_CON(x)      ((x) * 0x4 + RK3576_SECURE_NS_CRU_BASE + 0x300)
+#define RK3576_SECURE_NS_CLKGATE_CON(x)     ((x) * 0x4 + RK3576_SECURE_NS_CRU_BASE + 0x800)
+#define RK3576_SECURE_NS_SOFTRST_CON(x)     ((x) * 0x4 + RK3576_SECURE_NS_CRU_BASE + 0xa00)
+
+#define RK3576_CCI_CLKSEL_CON(x)            ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0x300)
+#define RK3576_CCI_CLKGATE_CON(x)           ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0x800)
+#define RK3576_CCI_SOFTRST_CON(x)           ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0xa00)
+
+#define RK3576_BPLL_CON(x)                  ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE)
+#define RK3576_BIGCORE_CLKSEL_CON(x)        ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0x300)
+#define RK3576_BIGCORE_CLKGATE_CON(x)       ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0x800)
+#define RK3576_BIGCORE_SOFTRST_CON(x)       ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0xa00)
+#define RK3576_LPLL_CON(x)                  ((x) * 0x4 + RK3576_CCI_CRU_BASE)
+#define RK3576_LITCORE_CLKSEL_CON(x)        ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0x300)
+#define RK3576_LITCORE_CLKGATE_CON(x)       ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0x800)
+#define RK3576_LITCORE_SOFTRST_CON(x)       ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0xa00)
+#define RK3576_NON_SECURE_GATING_CON00      0xc48
+
+#define RK3576_ACLK_M_BIGCORE_DIV_MASK      0x1f
+#define RK3576_ACLK_M_BIGCORE_DIV_SHIFT     0
+#define RK3576_ACLK_M_LITCORE_DIV_MASK      0x1f
+#define RK3576_ACLK_M_LITCORE_DIV_SHIFT     8
+#define RK3576_PCLK_DBG_LITCORE_DIV_MASK    0x1f
+#define RK3576_PCLK_DBG_LITCORE_DIV_SHIFT   0
+#define RK3576_ACLK_CCI_DIV_MASK            0x1f
+#define RK3576_ACLK_CCI_DIV_SHIFT           7
+#define RK3576_ACLK_CCI_MUX_MASK            0x3
+#define RK3576_ACLK_CCI_MUX_SHIFT           12
+
+struct clk_rk3576_cru
+{
+    struct rt_clk_node clk_parent;
+    struct rt_reset_controller rstc_parent;
+
+    struct rockchip_clk_provider provider;
+};
+
+static struct rockchip_pll_rate_table rk3576_pll_rates[] =
+{
+    /* _mhz, _p, _m, _s, _k */
+    RK3588_PLL_RATE(2520000000, 2, 210, 0, 0),
+    RK3588_PLL_RATE(2496000000, 2, 208, 0, 0),
+    RK3588_PLL_RATE(2472000000, 2, 206, 0, 0),
+    RK3588_PLL_RATE(2448000000, 2, 204, 0, 0),
+    RK3588_PLL_RATE(2424000000, 2, 202, 0, 0),
+    RK3588_PLL_RATE(2400000000, 2, 200, 0, 0),
+    RK3588_PLL_RATE(2376000000, 2, 198, 0, 0),
+    RK3588_PLL_RATE(2352000000, 2, 196, 0, 0),
+    RK3588_PLL_RATE(2328000000, 2, 194, 0, 0),
+    RK3588_PLL_RATE(2304000000, 2, 192, 0, 0),
+    RK3588_PLL_RATE(2280000000, 2, 190, 0, 0),
+    RK3588_PLL_RATE(2256000000, 2, 376, 1, 0),
+    RK3588_PLL_RATE(2232000000, 2, 372, 1, 0),
+    RK3588_PLL_RATE(2208000000, 2, 368, 1, 0),
+    RK3588_PLL_RATE(2184000000, 2, 364, 1, 0),
+    RK3588_PLL_RATE(2160000000, 2, 360, 1, 0),
+    RK3588_PLL_RATE(2136000000, 2, 356, 1, 0),
+    RK3588_PLL_RATE(2112000000, 2, 352, 1, 0),
+    RK3588_PLL_RATE(2088000000, 2, 348, 1, 0),
+    RK3588_PLL_RATE(2064000000, 2, 344, 1, 0),
+    RK3588_PLL_RATE(2040000000, 2, 340, 1, 0),
+    RK3588_PLL_RATE(2016000000, 2, 336, 1, 0),
+    RK3588_PLL_RATE(1992000000, 2, 332, 1, 0),
+    RK3588_PLL_RATE(1968000000, 2, 328, 1, 0),
+    RK3588_PLL_RATE(1944000000, 2, 324, 1, 0),
+    RK3588_PLL_RATE(1920000000, 2, 320, 1, 0),
+    RK3588_PLL_RATE(1896000000, 2, 316, 1, 0),
+    RK3588_PLL_RATE(1872000000, 2, 312, 1, 0),
+    RK3588_PLL_RATE(1848000000, 2, 308, 1, 0),
+    RK3588_PLL_RATE(1824000000, 2, 304, 1, 0),
+    RK3588_PLL_RATE(1800000000, 2, 300, 1, 0),
+    RK3588_PLL_RATE(1776000000, 2, 296, 1, 0),
+    RK3588_PLL_RATE(1752000000, 2, 292, 1, 0),
+    RK3588_PLL_RATE(1728000000, 2, 288, 1, 0),
+    RK3588_PLL_RATE(1704000000, 2, 284, 1, 0),
+    RK3588_PLL_RATE(1680000000, 2, 280, 1, 0),
+    RK3588_PLL_RATE(1656000000, 2, 276, 1, 0),
+    RK3588_PLL_RATE(1632000000, 2, 272, 1, 0),
+    RK3588_PLL_RATE(1608000000, 2, 268, 1, 0),
+    RK3588_PLL_RATE(1584000000, 2, 264, 1, 0),
+    RK3588_PLL_RATE(1560000000, 2, 260, 1, 0),
+    RK3588_PLL_RATE(1536000000, 2, 256, 1, 0),
+    RK3588_PLL_RATE(1512000000, 2, 252, 1, 0),
+    RK3588_PLL_RATE(1488000000, 2, 248, 1, 0),
+    RK3588_PLL_RATE(1464000000, 2, 244, 1, 0),
+    RK3588_PLL_RATE(1440000000, 2, 240, 1, 0),
+    RK3588_PLL_RATE(1416000000, 2, 236, 1, 0),
+    RK3588_PLL_RATE(1392000000, 2, 232, 1, 0),
+    RK3588_PLL_RATE(1320000000, 2, 220, 1, 0),
+    RK3588_PLL_RATE(1200000000, 2, 200, 1, 0),
+    RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
+    RK3588_PLL_RATE(1186814000, 2, 198, 1, 52581),
+    RK3588_PLL_RATE(1186812000, 2, 198, 1, 52559),
+    RK3588_PLL_RATE(1109000000, 3, 554, 2, 32767),
+    RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
+    RK3588_PLL_RATE(1051000000, 3, 525, 2, 32767),
+    RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
+    RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
+    RK3588_PLL_RATE(983040000, 4, 655, 2, 23592),
+    RK3588_PLL_RATE(955520000, 3, 477, 2, 49806),
+    RK3588_PLL_RATE(903168000, 6, 903, 2, 11009),
+    RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
+    RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
+    RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
+    RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
+    RK3588_PLL_RATE(785560000, 3, 392, 2, 51117),
+    RK3588_PLL_RATE(773000000, 2, 258, 2, 43690),
+    RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
+    RK3588_PLL_RATE(697000000, 2, 232, 2, 21845),
+    RK3588_PLL_RATE(610400000, 3, 305, 2, 13107),
+    RK3588_PLL_RATE(604800000, 1, 101, 2, 52428),
+    RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
+    RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
+    RK3588_PLL_RATE(408000000, 2, 272, 3, 0),
+    RK3588_PLL_RATE(312000000, 2, 208, 3, 0),
+    RK3588_PLL_RATE(266580000, 1, 178, 4, 47185),
+    RK3588_PLL_RATE(216000000, 2, 288, 4, 0),
+    RK3588_PLL_RATE(96000000, 2, 256, 5, 0),
+    { /* sentinel */ },
+};
+
+static struct rockchip_pll_rate_table rk3576_ppll_rates[] =
+{
+    /* _mhz, _p, _m, _s, _k */
+    RK3588_PLL_RATE(1300000000, 3, 325, 2, 0),
+    { /* sentinel */ },
+};
+
+#define RK3576_BIGCORE_CLKSEL2(_amcore)                                 \
+{                                                                       \
+    .reg = RK3576_BIGCORE_CLKSEL_CON(2),                                \
+    .val = HIWORD_UPDATE(_amcore - 1, RK3576_ACLK_M_BIGCORE_DIV_MASK,   \
+                    RK3576_ACLK_M_BIGCORE_DIV_SHIFT),                   \
+}
+
+#define RK3576_LITCORE_CLKSEL1(_amcore)                                 \
+{                                                                       \
+    .reg = RK3576_LITCORE_CLKSEL_CON(1),                                \
+    .val = HIWORD_UPDATE(_amcore - 1, RK3576_ACLK_M_LITCORE_DIV_MASK,   \
+                    RK3576_ACLK_M_LITCORE_DIV_SHIFT),                   \
+}
+
+#define RK3576_LITCORE_CLKSEL2(_pclkdbg)                                \
+{                                                                       \
+    .reg = RK3576_LITCORE_CLKSEL_CON(2),                                \
+    .val = HIWORD_UPDATE(_pclkdbg - 1, RK3576_PCLK_DBG_LITCORE_DIV_MASK,\
+                    RK3576_PCLK_DBG_LITCORE_DIV_SHIFT),                 \
+}
+
+#define RK3576_CCI_CLKSEL4(_ccisel, _div)                       \
+{                                                               \
+    .reg = RK3576_CCI_CLKSEL_CON(4),                            \
+    .val = HIWORD_UPDATE(_ccisel, RK3576_ACLK_CCI_MUX_MASK,     \
+                    RK3576_ACLK_CCI_MUX_SHIFT) |                \
+           HIWORD_UPDATE(_div - 1, RK3576_ACLK_CCI_DIV_MASK,    \
+                    RK3576_ACLK_CCI_DIV_SHIFT),                 \
+}
+
+#define RK3576_CPUBCLK_RATE(_prate, _amcore) \
+{                                           \
+    .prate = _prate##U,                     \
+    .divs =                                 \
+    {                                       \
+        RK3576_BIGCORE_CLKSEL2(_amcore),    \
+    },                                      \
+}
+
+#define RK3576_CPULCLK_RATE(_prate, _amcore, _pclkdbg, _ccisel) \
+{                                           \
+    .prate = _prate##U,                     \
+    .divs =                                 \
+    {                                       \
+        RK3576_LITCORE_CLKSEL1(_amcore),    \
+        RK3576_LITCORE_CLKSEL2(_pclkdbg),   \
+    },                                      \
+    .pre_muxs =                             \
+    {                                       \
+        RK3576_CCI_CLKSEL4(2, 2),           \
+    },                                      \
+    .post_muxs =                            \
+    {                                       \
+        RK3576_CCI_CLKSEL4(_ccisel, 2),     \
+    },                                      \
+}
+
+static struct rockchip_cpu_clk_rate_table rk3576_cpubclk_rates[] =
+{
+    RK3576_CPUBCLK_RATE(2496000000, 2),
+    RK3576_CPUBCLK_RATE(2400000000, 2),
+    RK3576_CPUBCLK_RATE(2304000000, 2),
+    RK3576_CPUBCLK_RATE(2208000000, 2),
+    RK3576_CPUBCLK_RATE(2184000000, 2),
+    RK3576_CPUBCLK_RATE(2088000000, 2),
+    RK3576_CPUBCLK_RATE(2040000000, 2),
+    RK3576_CPUBCLK_RATE(2016000000, 2),
+    RK3576_CPUBCLK_RATE(1992000000, 2),
+    RK3576_CPUBCLK_RATE(1896000000, 2),
+    RK3576_CPUBCLK_RATE(1800000000, 2),
+    RK3576_CPUBCLK_RATE(1704000000, 2),
+    RK3576_CPUBCLK_RATE(1608000000, 2),
+    RK3576_CPUBCLK_RATE(1584000000, 2),
+    RK3576_CPUBCLK_RATE(1560000000, 2),
+    RK3576_CPUBCLK_RATE(1536000000, 2),
+    RK3576_CPUBCLK_RATE(1512000000, 2),
+    RK3576_CPUBCLK_RATE(1488000000, 2),
+    RK3576_CPUBCLK_RATE(1464000000, 2),
+    RK3576_CPUBCLK_RATE(1440000000, 2),
+    RK3576_CPUBCLK_RATE(1416000000, 2),
+    RK3576_CPUBCLK_RATE(1392000000, 2),
+    RK3576_CPUBCLK_RATE(1368000000, 2),
+    RK3576_CPUBCLK_RATE(1344000000, 2),
+    RK3576_CPUBCLK_RATE(1320000000, 2),
+    RK3576_CPUBCLK_RATE(1296000000, 2),
+    RK3576_CPUBCLK_RATE(1272000000, 2),
+    RK3576_CPUBCLK_RATE(1248000000, 2),
+    RK3576_CPUBCLK_RATE(1224000000, 2),
+    RK3576_CPUBCLK_RATE(1200000000, 2),
+    RK3576_CPUBCLK_RATE(1104000000, 2),
+    RK3576_CPUBCLK_RATE(1008000000, 2),
+    RK3576_CPUBCLK_RATE(912000000, 2),
+    RK3576_CPUBCLK_RATE(816000000, 2),
+    RK3576_CPUBCLK_RATE(696000000, 2),
+    RK3576_CPUBCLK_RATE(600000000, 2),
+    RK3576_CPUBCLK_RATE(408000000, 2),
+    RK3576_CPUBCLK_RATE(312000000, 2),
+    RK3576_CPUBCLK_RATE(216000000, 2),
+    RK3576_CPUBCLK_RATE(96000000, 2),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3576_cpubclk_data =
+{
+    .core_reg[0] = RK3576_BIGCORE_CLKSEL_CON(1),
+    .div_core_shift[0] = 7,
+    .div_core_mask[0] = 0x1f,
+    .num_cores = 1,
+    .mux_core_alt = 1,
+    .mux_core_main = 0,
+    .mux_core_shift = 12,
+    .mux_core_mask = 0x3,
+};
+
+static struct rockchip_cpu_clk_rate_table rk3576_cpulclk_rates[] =
+{
+    RK3576_CPULCLK_RATE(2400000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(2304000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(2208000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(2184000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(2088000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(2040000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(2016000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1992000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1896000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1800000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1704000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1608000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1584000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1560000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1536000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1512000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1488000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1464000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1440000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1416000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1392000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1368000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1344000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1320000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1296000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1272000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1248000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1224000000, 2, 6, 3),
+    RK3576_CPULCLK_RATE(1200000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(1104000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(1008000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(912000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(816000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(696000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(600000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(408000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(312000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(216000000, 2, 6, 2),
+    RK3576_CPULCLK_RATE(96000000, 2, 6, 2),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3576_cpulclk_data =
+{
+    .core_reg[0] = RK3576_LITCORE_CLKSEL_CON(0),
+    .div_core_shift[0] = 7,
+    .div_core_mask[0] = 0x1f,
+    .num_cores = 1,
+    .mux_core_alt = 1,
+    .mux_core_main = 0,
+    .mux_core_shift = 12,
+    .mux_core_mask = 0x3,
+};
+
+PNAMES(mux_pll_p)                           = { "xin24m", "xin32k" };
+PNAMES(mux_24m_32k_p)                       = { "xin24m", "xin_osc0_div" };
+PNAMES(gpll_24m_p)                          = { "gpll", "xin24m" };
+PNAMES(cpll_24m_p)                          = { "cpll", "xin24m" };
+PNAMES(gpll_cpll_p)                         = { "gpll", "cpll" };
+PNAMES(gpll_spll_p)                         = { "gpll", "spll" };
+PNAMES(gpll_cpll_aupll_p)                   = { "gpll", "cpll", "aupll" };
+PNAMES(gpll_cpll_24m_p)                     = { "gpll", "cpll", "xin24m" };
+PNAMES(gpll_cpll_24m_spll_p)                = { "gpll", "cpll", "xin24m", "spll" };
+PNAMES(gpll_cpll_aupll_24m_p)               = { "gpll", "cpll", "aupll", "xin24m" };
+PNAMES(gpll_cpll_aupll_spll_p)              = { "gpll", "cpll", "aupll", "spll" };
+PNAMES(gpll_cpll_aupll_spll_lpll_p)         = { "gpll", "cpll", "aupll", "spll", "lpll_dummy" };
+PNAMES(gpll_cpll_spll_bpll_p)               = { "gpll", "cpll", "spll", "bpll_dummy" };
+PNAMES(gpll_cpll_lpll_bpll_p)               = { "gpll", "cpll", "lpll_dummy", "bpll_dummy" };
+PNAMES(gpll_spll_cpll_bpll_lpll_p)          = { "gpll", "spll", "cpll", "bpll_dummy", "lpll_dummy" };
+PNAMES(gpll_cpll_vpll_aupll_24m_p)          = { "gpll", "cpll", "vpll", "aupll", "xin24m" };
+PNAMES(gpll_cpll_spll_aupll_bpll_p)         = { "gpll", "cpll", "spll", "aupll", "bpll_dummy" };
+PNAMES(gpll_cpll_spll_bpll_lpll_p)          = { "gpll", "cpll", "spll", "bpll_dummy", "lpll_dummy" };
+PNAMES(gpll_cpll_spll_lpll_bpll_p)          = { "gpll", "cpll", "spll", "lpll_dummy", "bpll_dummy" };
+PNAMES(gpll_cpll_vpll_bpll_lpll_p)          = { "gpll", "cpll", "vpll", "bpll_dummy", "lpll_dummy" };
+PNAMES(gpll_spll_aupll_bpll_lpll_p)         = { "gpll", "spll", "aupll", "bpll_dummy", "lpll_dummy" };
+PNAMES(gpll_spll_isppvtpll_bpll_lpll_p)     = { "gpll", "spll", "isp_pvtpll", "bpll_dummy", "lpll_dummy" };
+PNAMES(gpll_cpll_spll_aupll_lpll_24m_p)     = { "gpll", "cpll", "spll", "aupll", "lpll_dummy", "xin24m" };
+PNAMES(gpll_cpll_spll_vpll_bpll_lpll_p)     = { "gpll", "cpll", "spll", "vpll", "bpll_dummy", "lpll_dummy" };
+PNAMES(cpll_vpll_lpll_bpll_p)               = { "cpll", "vpll", "lpll_dummy", "bpll_dummy" };
+PNAMES(mux_24m_ccipvtpll_gpll_lpll_p)       = { "xin24m", "cci_pvtpll", "gpll", "lpll" };
+PNAMES(mux_24m_spll_gpll_cpll_p)            = {"xin24m", "spll", "gpll", "cpll" };
+PNAMES(audio_frac_int_p)                    = { "xin24m", "clk_audio_frac_0", "clk_audio_frac_1", "clk_audio_frac_2", "clk_audio_frac_3", "clk_audio_int_0", "clk_audio_int_1", "clk_audio_int_2" };
+PNAMES(audio_frac_p)                        = { "clk_audio_frac_0", "clk_audio_frac_1", "clk_audio_frac_2", "clk_audio_frac_3" };
+PNAMES(mux_100m_24m_p)                      = { "clk_cpll_div10", "xin24m" };
+PNAMES(mux_100m_50m_24m_p)                  = { "clk_cpll_div10", "clk_cpll_div20", "xin24m" };
+PNAMES(mux_100m_24m_lclk0_p)                = { "clk_cpll_div10", "xin24m", "lclk_asrc_src_0" };
+PNAMES(mux_100m_24m_lclk1_p)                = { "clk_cpll_div10", "xin24m", "lclk_asrc_src_1" };
+PNAMES(mux_150m_100m_50m_24m_p)             = { "clk_gpll_div8", "clk_cpll_div10", "clk_cpll_div20", "xin24m" };
+PNAMES(mux_200m_100m_50m_24m_p)             = { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", "xin24m" };
+PNAMES(mux_400m_200m_100m_24m_p)            = { "clk_gpll_div3", "clk_gpll_div6", "clk_cpll_div10", "xin24m" };
+PNAMES(mux_500m_250m_100m_24m_p)            = { "clk_cpll_div2", "clk_cpll_div4", "clk_cpll_div10", "xin24m" };
+PNAMES(mux_600m_400m_300m_24m_p)            = { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div4", "xin24m" };
+PNAMES(mux_350m_175m_116m_24m_p)            = { "clk_spll_div2", "clk_spll_div4", "clk_spll_div6", "xin24m" };
+PNAMES(mux_175m_116m_58m_24m_p)             = { "clk_spll_div4", "clk_spll_div6", "clk_spll_div12", "xin24m" };
+PNAMES(mux_116m_58m_24m_p)                  = { "clk_spll_div6", "clk_spll_div12", "xin24m" };
+PNAMES(mclk_sai0_8ch_p)                     = { "mclk_sai0_8ch_src", "sai0_mclkin", "sai1_mclkin" };
+PNAMES(mclk_sai1_8ch_p)                     = { "mclk_sai1_8ch_src", "sai1_mclkin" };
+PNAMES(mclk_sai2_2ch_p)                     = { "mclk_sai2_2ch_src", "sai2_mclkin", "sai1_mclkin" };
+PNAMES(mclk_sai3_2ch_p)                     = { "mclk_sai3_2ch_src", "sai3_mclkin", "sai1_mclkin" };
+PNAMES(mclk_sai4_2ch_p)                     = { "mclk_sai4_2ch_src", "sai4_mclkin", "sai1_mclkin" };
+PNAMES(mclk_sai5_8ch_p)                     = { "mclk_sai5_8ch_src", "sai1_mclkin" };
+PNAMES(mclk_sai6_8ch_p)                     = { "mclk_sai6_8ch_src", "sai1_mclkin" };
+PNAMES(mclk_sai7_8ch_p)                     = { "mclk_sai7_8ch_src", "sai1_mclkin" };
+PNAMES(mclk_sai8_8ch_p)                     = { "mclk_sai8_8ch_src", "sai1_mclkin" };
+PNAMES(mclk_sai9_8ch_p)                     = { "mclk_sai9_8ch_src", "sai1_mclkin" };
+PNAMES(uart1_p)                             = { "clk_uart1_src_top", "xin24m" };
+PNAMES(clk_gmac1_ptp_ref_src_p)             = { "gpll", "cpll", "gmac1_ptp_refclk_in" };
+PNAMES(clk_gmac0_ptp_ref_src_p)             = { "gpll", "cpll", "gmac0_ptp_refclk_in" };
+PNAMES(dclk_ebc_p)                          = { "gpll", "cpll", "vpll", "aupll", "lpll_dummy", "dclk_ebc_frac", "xin24m" };
+PNAMES(dclk_vp0_p)                          = { "dclk_vp0_src", "clk_hdmiphy_pixel0" };
+PNAMES(dclk_vp1_p)                          = { "dclk_vp1_src", "clk_hdmiphy_pixel0" };
+PNAMES(dclk_vp2_p)                          = { "dclk_vp2_src", "clk_hdmiphy_pixel0" };
+PNAMES(clk_uart_p)                          = { "gpll", "cpll", "aupll", "xin24m", "clk_uart_frac_0", "clk_uart_frac_1", "clk_uart_frac_2"};
+PNAMES(clk_freq_pwm1_p)                     = { "sai0_mclkin", "sai1_mclkin", "sai2_mclkin", "sai3_mclkin", "sai4_mclkin", "sai_sclkin_freq"};
+PNAMES(clk_counter_pwm1_p)                  = { "sai0_mclkin", "sai1_mclkin", "sai2_mclkin", "sai3_mclkin", "sai4_mclkin", "sai_sclkin_counter"};
+PNAMES(sai_sclkin_freq_p)                   = { "sai0_sclk_in", "sai1_sclk_in", "sai2_sclk_in", "sai3_sclk_in", "sai4_sclk_in"};
+PNAMES(clk_ref_pcie0_phy_p)                 = { "clk_pcie_100m_src", "clk_pcie_100m_nduty_src", "xin24m"};
+PNAMES(hclk_vi_root_p)                      = { "clk_gpll_div6", "clk_cpll_div10", "aclk_vi_root_inter", "xin24m"};
+PNAMES(clk_ref_osc_mphy_p)                  = { "xin24m", "clk_gpio_mphy_i", "clk_ref_mphy_26m"};
+PNAMES(mux_pmu200m_pmu100m_pmu50m_24m_p)    = { "clk_200m_pmu_src", "clk_100m_pmu_src", "clk_50m_pmu_src", "xin24m" };
+PNAMES(mux_pmu100m_pmu50m_24m_p)            = { "clk_100m_pmu_src", "clk_50m_pmu_src", "xin24m" };
+PNAMES(mux_pmu100m_24m_32k_p)               = { "clk_100m_pmu_src", "xin24m", "xin_osc0_div" };
+PNAMES(clk_phy_ref_src_p)                   = { "xin24m", "clk_pmuphy_ref_src" };
+PNAMES(clk_usbphy_ref_src_p)                = { "usbphy0_24m", "usbphy1_24m" };
+PNAMES(clk_cpll_ref_src_p)                  = { "xin24m", "clk_usbphy_ref_src" };
+PNAMES(clk_aupll_ref_src_p)                 = { "xin24m", "clk_aupll_ref_io" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clk_cell rk3576_pll_bpll =
+    PLL_RAW(pll_type_rk3588_core, PLL_BPLL, "bpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_PLL_CON(0), RK3576_BPLL_MODE_CON0,
+            0, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates);
+static struct rockchip_pll_clk_cell rk3576_pll_lpll =
+    PLL_RAW(pll_type_rk3588_core, PLL_LPLL, "lpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_LPLL_CON(16), RK3576_LPLL_MODE_CON0,
+            0, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates);
+static struct rockchip_pll_clk_cell rk3576_pll_vpll =
+    PLL_RAW(pll_type_rk3588, PLL_VPLL, "vpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_PLL_CON(88), RK3576_MODE_CON0,
+            4, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates);
+static struct rockchip_pll_clk_cell rk3576_pll_aupll =
+    PLL_RAW(pll_type_rk3588, PLL_AUPLL, "aupll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_PLL_CON(96), RK3576_MODE_CON0,
+            6, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates);
+static struct rockchip_pll_clk_cell rk3576_pll_cpll =
+    PLL_RAW(pll_type_rk3588, PLL_CPLL, "cpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3576_PLL_CON(104), RK3576_MODE_CON0,
+            8, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates);
+static struct rockchip_pll_clk_cell rk3576_pll_gpll =
+    PLL_RAW(pll_type_rk3588, PLL_GPLL, "gpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3576_PLL_CON(112), RK3576_MODE_CON0,
+            2, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates);
+static struct rockchip_pll_clk_cell rk3576_pll_ppll =
+    PLL_RAW(pll_type_rk3588_ddr, PLL_PPLL, "ppll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3576_PMU_PLL_CON(128), RK3576_MODE_CON0,
+            10, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_ppll_rates);
+
+static struct rt_clk_cell *rk3576_clk_cells[] =
+{
+    [PLL_BPLL] = &rk3576_pll_bpll.rk_cell.cell,
+    [PLL_LPLL] = &rk3576_pll_lpll.rk_cell.cell,
+    [PLL_VPLL] = &rk3576_pll_vpll.rk_cell.cell,
+    [PLL_AUPLL] = &rk3576_pll_aupll.rk_cell.cell,
+    [PLL_CPLL] = &rk3576_pll_cpll.rk_cell.cell,
+    [PLL_GPLL] = &rk3576_pll_gpll.rk_cell.cell,
+    [PLL_PPLL] = &rk3576_pll_ppll.rk_cell.cell,
+    [ARMCLK_L] = CPU(ARMCLK_L, "armclk_l", &rk3576_pll_lpll.rk_cell, &rk3576_pll_gpll.rk_cell,
+            rk3576_cpulclk_rates, RT_ARRAY_SIZE(rk3576_cpulclk_rates), &rk3576_cpulclk_data),
+    [ARMCLK_B] = CPU(ARMCLK_B, "armclk_b", &rk3576_pll_bpll.rk_cell, &rk3576_pll_gpll.rk_cell,
+            rk3576_cpubclk_rates, RT_ARRAY_SIZE(rk3576_cpubclk_rates), &rk3576_cpubclk_data),
+    [CLK_CPLL_DIV20] = COMPOSITE(CLK_CPLL_DIV20, "clk_cpll_div20", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 0, GFLAGS),
+    [CLK_CPLL_DIV10] = COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(0), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 1, GFLAGS),
+    [CLK_GPLL_DIV8] = COMPOSITE(CLK_GPLL_DIV8, "clk_gpll_div8", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 2, GFLAGS),
+    [CLK_GPLL_DIV6] = COMPOSITE(CLK_GPLL_DIV6, "clk_gpll_div6", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(1), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 3, GFLAGS),
+    [CLK_CPLL_DIV4] = COMPOSITE(CLK_CPLL_DIV4, "clk_cpll_div4", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 4, GFLAGS),
+    [CLK_GPLL_DIV4] = COMPOSITE(CLK_GPLL_DIV4, "clk_gpll_div4", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(2), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 5, GFLAGS),
+    [CLK_SPLL_DIV2] = COMPOSITE(CLK_SPLL_DIV2, "clk_spll_div2", gpll_cpll_spll_bpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(3), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 6, GFLAGS),
+    [CLK_GPLL_DIV3] = COMPOSITE(CLK_GPLL_DIV3, "clk_gpll_div3", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(3), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 7, GFLAGS),
+    [CLK_CPLL_DIV2] = COMPOSITE(CLK_CPLL_DIV2, "clk_cpll_div2", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(4), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 9, GFLAGS),
+    [CLK_GPLL_DIV2] = COMPOSITE(CLK_GPLL_DIV2, "clk_gpll_div2", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(5), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 10, GFLAGS),
+    [CLK_SPLL_DIV1] = COMPOSITE(CLK_SPLL_DIV1, "clk_spll_div1", gpll_cpll_spll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(6), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(0), 12, GFLAGS),
+    [PCLK_TOP_ROOT] = COMPOSITE_NODIV(PCLK_TOP_ROOT, "pclk_top_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(8), 7, 2, MFLAGS,
+            RK3576_CLKGATE_CON(1), 1, GFLAGS),
+    [ACLK_TOP] = COMPOSITE(ACLK_TOP, "aclk_top", gpll_cpll_aupll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(9), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(1), 3, GFLAGS),
+    [HCLK_TOP] = COMPOSITE_NODIV(HCLK_TOP, "hclk_top", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(19), 2, 2, MFLAGS,
+            RK3576_CLKGATE_CON(1), 14, GFLAGS),
+    [CLK_AUDIO_FRAC_0] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_0, "clk_audio_frac_0", "clk_audio_frac_0_src", 0,
+            RK3576_CLKSEL_CON(12), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(1), 10, GFLAGS),
+    [CLK_AUDIO_FRAC_1] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_1, "clk_audio_frac_1", "clk_audio_frac_1_src", 0,
+            RK3576_CLKSEL_CON(14), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(1), 11, GFLAGS),
+    [CLK_AUDIO_FRAC_2] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_2, "clk_audio_frac_2", "clk_audio_frac_2_src", 0,
+            RK3576_CLKSEL_CON(16), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(1), 12, GFLAGS),
+    [CLK_AUDIO_FRAC_3] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_3, "clk_audio_frac_3", "clk_audio_frac_3_src", 0,
+            RK3576_CLKSEL_CON(18), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(1), 13, GFLAGS),
+    [CLK_UART_FRAC_0] = COMPOSITE_FRAC(CLK_UART_FRAC_0, "clk_uart_frac_0", "clk_uart_frac_0_src", 0,
+            RK3576_CLKSEL_CON(21), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(2), 5, GFLAGS),
+    [CLK_UART_FRAC_1] = COMPOSITE_FRAC(CLK_UART_FRAC_1, "clk_uart_frac_1", "clk_uart_frac_1_src", 0,
+            RK3576_CLKSEL_CON(23), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(2), 6, GFLAGS),
+    [CLK_UART_FRAC_2] = COMPOSITE_FRAC(CLK_UART_FRAC_2, "clk_uart_frac_2", "clk_uart_frac_2_src", 0,
+            RK3576_CLKSEL_CON(25), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(2), 7, GFLAGS),
+    [CLK_UART1_SRC_TOP] = COMPOSITE(CLK_UART1_SRC_TOP, "clk_uart1_src_top", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(27), 13, 3, MFLAGS, 5, 8, DFLAGS,
+            RK3576_CLKGATE_CON(2), 13, GFLAGS),
+    [CLK_AUDIO_INT_0] = COMPOSITE_NOMUX(CLK_AUDIO_INT_0, "clk_audio_int_0", "gpll", 0,
+            RK3576_CLKSEL_CON(28), 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(2), 14, GFLAGS),
+    [CLK_AUDIO_INT_1] = COMPOSITE_NOMUX(CLK_AUDIO_INT_1, "clk_audio_int_1", "cpll", 0,
+            RK3576_CLKSEL_CON(28), 5, 5, DFLAGS,
+            RK3576_CLKGATE_CON(2), 15, GFLAGS),
+    [CLK_AUDIO_INT_2] = COMPOSITE_NOMUX(CLK_AUDIO_INT_2, "clk_audio_int_2", "aupll", 0,
+            RK3576_CLKSEL_CON(28), 10, 5, DFLAGS,
+            RK3576_CLKGATE_CON(3), 0, GFLAGS),
+    [CLK_PDM0_SRC_TOP] = COMPOSITE(CLK_PDM0_SRC_TOP, "clk_pdm0_src_top", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(29), 9, 3, MFLAGS, 0, 9, DFLAGS,
+            RK3576_CLKGATE_CON(3), 2, GFLAGS),
+    [CLK_PDM1_OUT] = GATE(CLK_PDM1_OUT, "clk_pdm1_out", "clk_pdm1", 0,
+            RK3576_CLKGATE_CON(3), 5, GFLAGS),
+    [CLK_GMAC0_125M_SRC] = COMPOSITE_NOMUX(CLK_GMAC0_125M_SRC, "clk_gmac0_125m_src", "cpll", 0,
+            RK3576_CLKSEL_CON(30), 10, 5, DFLAGS,
+            RK3576_CLKGATE_CON(3), 6, GFLAGS),
+    [CLK_GMAC1_125M_SRC] = COMPOSITE_NOMUX(CLK_GMAC1_125M_SRC, "clk_gmac1_125m_src", "cpll", 0,
+            RK3576_CLKSEL_CON(31), 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(3), 7, GFLAGS),
+    [LCLK_ASRC_SRC_0] = COMPOSITE(LCLK_ASRC_SRC_0, "lclk_asrc_src_0", audio_frac_p, 0,
+            RK3576_CLKSEL_CON(31), 10, 2, MFLAGS, 5, 5, DFLAGS,
+            RK3576_CLKGATE_CON(3), 10, GFLAGS),
+    [LCLK_ASRC_SRC_1] = COMPOSITE(LCLK_ASRC_SRC_1, "lclk_asrc_src_1", audio_frac_p, 0,
+            RK3576_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(3), 11, GFLAGS),
+    [REF_CLK0_OUT_PLL] = COMPOSITE(REF_CLK0_OUT_PLL, "ref_clk0_out_pll", gpll_cpll_spll_aupll_lpll_24m_p, 0,
+            RK3576_CLKSEL_CON(33), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(4), 1, GFLAGS),
+    [REF_CLK1_OUT_PLL] = COMPOSITE(REF_CLK1_OUT_PLL, "ref_clk1_out_pll", gpll_cpll_spll_aupll_lpll_24m_p, 0,
+            RK3576_CLKSEL_CON(34), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(4), 2, GFLAGS),
+    [REF_CLK2_OUT_PLL] = COMPOSITE(REF_CLK2_OUT_PLL, "ref_clk2_out_pll", gpll_cpll_spll_aupll_lpll_24m_p, 0,
+            RK3576_CLKSEL_CON(35), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(4), 3, GFLAGS),
+    [REFCLKO25M_GMAC0_OUT] = COMPOSITE(REFCLKO25M_GMAC0_OUT, "refclko25m_gmac0_out", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(36), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3576_CLKGATE_CON(5), 10, GFLAGS),
+    [REFCLKO25M_GMAC1_OUT] = COMPOSITE(REFCLKO25M_GMAC1_OUT, "refclko25m_gmac1_out", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(36), 15, 1, MFLAGS, 8, 7, DFLAGS,
+            RK3576_CLKGATE_CON(5), 11, GFLAGS),
+    [CLK_CIFOUT_OUT] = COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0,
+            RK3576_CLKSEL_CON(37), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(5), 12, GFLAGS),
+    [CLK_GMAC0_RMII_CRU] = GATE(CLK_GMAC0_RMII_CRU, "clk_gmac0_rmii_cru", "clk_cpll_div20", 0,
+            RK3576_CLKGATE_CON(5), 13, GFLAGS),
+    [CLK_GMAC1_RMII_CRU] = GATE(CLK_GMAC1_RMII_CRU, "clk_gmac1_rmii_cru", "clk_cpll_div20", 0,
+            RK3576_CLKGATE_CON(5), 14, GFLAGS),
+    [CLK_OTPC_AUTO_RD_G] = GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0,
+            RK3576_CLKGATE_CON(5), 15, GFLAGS),
+    [CLK_MIPI_CAMERAOUT_M0] = COMPOSITE(CLK_MIPI_CAMERAOUT_M0, "clk_mipi_cameraout_m0", mux_24m_spll_gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(38), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(6), 3, GFLAGS),
+    [CLK_MIPI_CAMERAOUT_M1] = COMPOSITE(CLK_MIPI_CAMERAOUT_M1, "clk_mipi_cameraout_m1", mux_24m_spll_gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(39), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(6), 4, GFLAGS),
+    [CLK_MIPI_CAMERAOUT_M2] = COMPOSITE(CLK_MIPI_CAMERAOUT_M2, "clk_mipi_cameraout_m2", mux_24m_spll_gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(40), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(6), 5, GFLAGS),
+    [MCLK_PDM0_SRC_TOP] = COMPOSITE(MCLK_PDM0_SRC_TOP, "mclk_pdm0_src_top", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(41), 7, 3, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(6), 8, GFLAGS),
+    [HCLK_AUDIO_ROOT] = COMPOSITE_NODIV(HCLK_AUDIO_ROOT, "hclk_audio_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(42), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(7), 1, GFLAGS),
+    [HCLK_ASRC_2CH_0] = GATE(HCLK_ASRC_2CH_0, "hclk_asrc_2ch_0", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(7), 3, GFLAGS),
+    [HCLK_ASRC_2CH_1] = GATE(HCLK_ASRC_2CH_1, "hclk_asrc_2ch_1", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(7), 4, GFLAGS),
+    [HCLK_ASRC_4CH_0] = GATE(HCLK_ASRC_4CH_0, "hclk_asrc_4ch_0", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(7), 5, GFLAGS),
+    [HCLK_ASRC_4CH_1] = GATE(HCLK_ASRC_4CH_1, "hclk_asrc_4ch_1", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(7), 6, GFLAGS),
+    [CLK_ASRC_2CH_0] = COMPOSITE(CLK_ASRC_2CH_0, "clk_asrc_2ch_0", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(42), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(7), 7, GFLAGS),
+    [CLK_ASRC_2CH_1] = COMPOSITE(CLK_ASRC_2CH_1, "clk_asrc_2ch_1", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(42), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3576_CLKGATE_CON(7), 8, GFLAGS),
+    [CLK_ASRC_4CH_0] = COMPOSITE(CLK_ASRC_4CH_0, "clk_asrc_4ch_0", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(43), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(7), 9, GFLAGS),
+    [CLK_ASRC_4CH_1] = COMPOSITE(CLK_ASRC_4CH_1, "clk_asrc_4ch_1", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(43), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(7), 10, GFLAGS),
+    [MCLK_SAI0_8CH_SRC] = COMPOSITE(MCLK_SAI0_8CH_SRC, "mclk_sai0_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(44), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(7), 11, GFLAGS),
+    [MCLK_SAI0_8CH] = COMPOSITE_NODIV(MCLK_SAI0_8CH, "mclk_sai0_8ch", mclk_sai0_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(44), 11, 2, MFLAGS,
+            RK3576_CLKGATE_CON(7), 12, GFLAGS),
+    [HCLK_SAI0_8CH] = GATE(HCLK_SAI0_8CH, "hclk_sai0_8ch", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(7), 13, GFLAGS),
+    [HCLK_SPDIF_RX0] = GATE(HCLK_SPDIF_RX0, "hclk_spdif_rx0", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(7), 14, GFLAGS),
+    [MCLK_SPDIF_RX0] = COMPOSITE(MCLK_SPDIF_RX0, "mclk_spdif_rx0", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(45), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(7), 15, GFLAGS),
+    [HCLK_SPDIF_RX1] = GATE(HCLK_SPDIF_RX1, "hclk_spdif_rx1", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(8), 0, GFLAGS),
+    [MCLK_SPDIF_RX1] = COMPOSITE(MCLK_SPDIF_RX1, "mclk_spdif_rx1", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(45), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(8), 1, GFLAGS),
+    [MCLK_SAI1_8CH_SRC] = COMPOSITE(MCLK_SAI1_8CH_SRC, "mclk_sai1_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(46), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(8), 4, GFLAGS),
+    [MCLK_SAI1_8CH] = COMPOSITE_NODIV(MCLK_SAI1_8CH, "mclk_sai1_8ch", mclk_sai1_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(46), 11, 1, MFLAGS,
+            RK3576_CLKGATE_CON(8), 5, GFLAGS),
+    [HCLK_SAI1_8CH] = GATE(HCLK_SAI1_8CH, "hclk_sai1_8ch", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(8), 6, GFLAGS),
+    [MCLK_SAI2_2CH_SRC] = COMPOSITE(MCLK_SAI2_2CH_SRC, "mclk_sai2_2ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(47), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(8), 7, GFLAGS),
+    [MCLK_SAI2_2CH] = COMPOSITE_NODIV(MCLK_SAI2_2CH, "mclk_sai2_2ch", mclk_sai2_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(47), 11, 2, MFLAGS,
+            RK3576_CLKGATE_CON(8), 8, GFLAGS),
+    [HCLK_SAI2_2CH] = GATE(HCLK_SAI2_2CH, "hclk_sai2_2ch", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(8), 10, GFLAGS),
+    [MCLK_SAI3_2CH_SRC] = COMPOSITE(MCLK_SAI3_2CH_SRC, "mclk_sai3_2ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(48), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(8), 11, GFLAGS),
+    [MCLK_SAI3_2CH] = COMPOSITE_NODIV(MCLK_SAI3_2CH, "mclk_sai3_2ch", mclk_sai3_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(48), 11, 2, MFLAGS,
+            RK3576_CLKGATE_CON(8), 12, GFLAGS),
+    [HCLK_SAI3_2CH] = GATE(HCLK_SAI3_2CH, "hclk_sai3_2ch", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(8), 14, GFLAGS),
+    [MCLK_SAI4_2CH_SRC] = COMPOSITE(MCLK_SAI4_2CH_SRC, "mclk_sai4_2ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(49), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(8), 15, GFLAGS),
+    [MCLK_SAI4_2CH] = COMPOSITE_NODIV(MCLK_SAI4_2CH, "mclk_sai4_2ch", mclk_sai4_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(49), 11, 2, MFLAGS,
+            RK3576_CLKGATE_CON(9), 0, GFLAGS),
+    [HCLK_SAI4_2CH] = GATE(HCLK_SAI4_2CH, "hclk_sai4_2ch", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(9), 2, GFLAGS),
+    [HCLK_ACDCDIG_DSM] = GATE(HCLK_ACDCDIG_DSM, "hclk_acdcdig_dsm", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(9), 3, GFLAGS),
+    [MCLK_ACDCDIG_DSM] = GATE(MCLK_ACDCDIG_DSM, "mclk_acdcdig_dsm", "mclk_sai4_2ch", 0,
+            RK3576_CLKGATE_CON(9), 4, GFLAGS),
+    [CLK_PDM1] = COMPOSITE(CLK_PDM1, "clk_pdm1", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(50), 9, 3, MFLAGS, 0, 9, DFLAGS,
+            RK3576_CLKGATE_CON(9), 5, GFLAGS),
+    [HCLK_PDM1] = GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(9), 7, GFLAGS),
+    [MCLK_PDM1] = COMPOSITE(MCLK_PDM1, "mclk_pdm1", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(51), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(9), 8, GFLAGS),
+    [HCLK_SPDIF_TX0] = GATE(HCLK_SPDIF_TX0, "hclk_spdif_tx0", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(9), 9, GFLAGS),
+    [MCLK_SPDIF_TX0] = COMPOSITE(MCLK_SPDIF_TX0, "mclk_spdif_tx0", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(52), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(9), 10, GFLAGS),
+    [HCLK_SPDIF_TX1] = GATE(HCLK_SPDIF_TX1, "hclk_spdif_tx1", "hclk_audio_root", 0,
+            RK3576_CLKGATE_CON(9), 11, GFLAGS),
+    [MCLK_SPDIF_TX1] = COMPOSITE(MCLK_SPDIF_TX1, "mclk_spdif_tx1", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(53), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(9), 12, GFLAGS),
+    [CLK_SAI1_MCLKOUT] = GATE(CLK_SAI1_MCLKOUT, "clk_sai1_mclkout", "mclk_sai1_8ch", 0,
+            RK3576_CLKGATE_CON(9), 13, GFLAGS),
+    [CLK_SAI2_MCLKOUT] = GATE(CLK_SAI2_MCLKOUT, "clk_sai2_mclkout", "mclk_sai2_2ch", 0,
+            RK3576_CLKGATE_CON(9), 14, GFLAGS),
+    [CLK_SAI3_MCLKOUT] = GATE(CLK_SAI3_MCLKOUT, "clk_sai3_mclkout", "mclk_sai3_2ch", 0,
+            RK3576_CLKGATE_CON(9), 15, GFLAGS),
+    [CLK_SAI4_MCLKOUT] = GATE(CLK_SAI4_MCLKOUT, "clk_sai4_mclkout", "mclk_sai4_2ch", 0,
+            RK3576_CLKGATE_CON(10), 0, GFLAGS),
+    [CLK_SAI0_MCLKOUT] = GATE(CLK_SAI0_MCLKOUT, "clk_sai0_mclkout", "mclk_sai0_8ch", 0,
+            RK3576_CLKGATE_CON(10), 1, GFLAGS),
+    [HCLK_BUS_ROOT] = COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(55), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(11), 0, GFLAGS),
+    [PCLK_BUS_ROOT] = COMPOSITE_NODIV(PCLK_BUS_ROOT, "pclk_bus_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(55), 2, 2, MFLAGS,
+            RK3576_CLKGATE_CON(11), 1, GFLAGS),
+    [ACLK_BUS_ROOT] = COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(55), 9, 1, MFLAGS, 4, 5, DFLAGS,
+            RK3576_CLKGATE_CON(11), 2, GFLAGS),
+    [HCLK_CAN0] = GATE(HCLK_CAN0, "hclk_can0", "hclk_bus_root", 0,
+            RK3576_CLKGATE_CON(11), 6, GFLAGS),
+    [CLK_CAN0] = COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(56), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(11), 7, GFLAGS),
+    [HCLK_CAN1] = GATE(HCLK_CAN1, "hclk_can1", "hclk_bus_root", 0,
+            RK3576_CLKGATE_CON(11), 8, GFLAGS),
+    [CLK_CAN1] = COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(56), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(11), 9, GFLAGS),
+    [CLK_KEY_SHIFT] = GATE(CLK_KEY_SHIFT, "clk_key_shift", "xin24m", RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKGATE_CON(11), 15, GFLAGS),
+    [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 0, GFLAGS),
+    [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 1, GFLAGS),
+    [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 2, GFLAGS),
+    [PCLK_I2C4] = GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 3, GFLAGS),
+    [PCLK_I2C5] = GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 4, GFLAGS),
+    [PCLK_I2C6] = GATE(PCLK_I2C6, "pclk_i2c6", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 5, GFLAGS),
+    [PCLK_I2C7] = GATE(PCLK_I2C7, "pclk_i2c7", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 6, GFLAGS),
+    [PCLK_I2C8] = GATE(PCLK_I2C8, "pclk_i2c8", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 7, GFLAGS),
+    [PCLK_I2C9] = GATE(PCLK_I2C9, "pclk_i2c9", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 8, GFLAGS),
+    [PCLK_WDT_BUSMCU] = GATE(PCLK_WDT_BUSMCU, "pclk_wdt_busmcu", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(12), 9, GFLAGS),
+    [TCLK_WDT_BUSMCU] = GATE(TCLK_WDT_BUSMCU, "tclk_wdt_busmcu", "xin24m", 0,
+            RK3576_CLKGATE_CON(12), 10, GFLAGS),
+    [ACLK_GIC] = GATE(ACLK_GIC, "aclk_gic", "aclk_bus_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKGATE_CON(12), 11, GFLAGS),
+    [CLK_I2C1] = COMPOSITE_NODIV(CLK_I2C1, "clk_i2c1", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(12), 12, GFLAGS),
+    [CLK_I2C2] = COMPOSITE_NODIV(CLK_I2C2, "clk_i2c2", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 2, 2, MFLAGS,
+            RK3576_CLKGATE_CON(12), 13, GFLAGS),
+    [CLK_I2C3] = COMPOSITE_NODIV(CLK_I2C3, "clk_i2c3", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 4, 2, MFLAGS,
+            RK3576_CLKGATE_CON(12), 14, GFLAGS),
+    [CLK_I2C4] = COMPOSITE_NODIV(CLK_I2C4, "clk_i2c4", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 6, 2, MFLAGS,
+            RK3576_CLKGATE_CON(12), 15, GFLAGS),
+    [CLK_I2C5] = COMPOSITE_NODIV(CLK_I2C5, "clk_i2c5", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 8, 2, MFLAGS,
+            RK3576_CLKGATE_CON(13), 0, GFLAGS),
+    [CLK_I2C6] = COMPOSITE_NODIV(CLK_I2C6, "clk_i2c6", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 10, 2, MFLAGS,
+            RK3576_CLKGATE_CON(13), 1, GFLAGS),
+    [CLK_I2C7] = COMPOSITE_NODIV(CLK_I2C7, "clk_i2c7", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 12, 2, MFLAGS,
+            RK3576_CLKGATE_CON(13), 2, GFLAGS),
+    [CLK_I2C8] = COMPOSITE_NODIV(CLK_I2C8, "clk_i2c8", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(57), 14, 2, MFLAGS,
+            RK3576_CLKGATE_CON(13), 3, GFLAGS),
+    [CLK_I2C9] = COMPOSITE_NODIV(CLK_I2C9, "clk_i2c9", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(58), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(13), 4, GFLAGS),
+    [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 6, GFLAGS),
+    [CLK_SARADC] = COMPOSITE(CLK_SARADC, "clk_saradc", gpll_24m_p, 0,
+            RK3576_CLKSEL_CON(58), 12, 1, MFLAGS, 4, 8, DFLAGS,
+            RK3576_CLKGATE_CON(13), 7, GFLAGS),
+    [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 8, GFLAGS),
+    [CLK_TSADC] = COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m", 0,
+            RK3576_CLKSEL_CON(59), 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(13), 9, GFLAGS),
+    [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 10, GFLAGS),
+    [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 11, GFLAGS),
+    [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 12, GFLAGS),
+    [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 13, GFLAGS),
+    [PCLK_UART5] = GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 14, GFLAGS),
+    [PCLK_UART6] = GATE(PCLK_UART6, "pclk_uart6", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(13), 15, GFLAGS),
+    [PCLK_UART7] = GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(14), 0, GFLAGS),
+    [PCLK_UART8] = GATE(PCLK_UART8, "pclk_uart8", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(14), 1, GFLAGS),
+    [PCLK_UART9] = GATE(PCLK_UART9, "pclk_uart9", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(14), 2, GFLAGS),
+    [PCLK_UART10] = GATE(PCLK_UART10, "pclk_uart10", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(14), 3, GFLAGS),
+    [PCLK_UART11] = GATE(PCLK_UART11, "pclk_uart11", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(14), 4, GFLAGS),
+    [SCLK_UART0] = COMPOSITE(SCLK_UART0, "sclk_uart0", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(14), 5, GFLAGS),
+    [SCLK_UART2] = COMPOSITE(SCLK_UART2, "sclk_uart2", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(61), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(14), 6, GFLAGS),
+    [SCLK_UART3] = COMPOSITE(SCLK_UART3, "sclk_uart3", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(62), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(14), 9, GFLAGS),
+    [SCLK_UART4] = COMPOSITE(SCLK_UART4, "sclk_uart4", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(63), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(14), 12, GFLAGS),
+    [SCLK_UART5] = COMPOSITE(SCLK_UART5, "sclk_uart5", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(64), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(14), 15, GFLAGS),
+    [SCLK_UART6] = COMPOSITE(SCLK_UART6, "sclk_uart6", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(65), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(15), 2, GFLAGS),
+    [SCLK_UART7] = COMPOSITE(SCLK_UART7, "sclk_uart7", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(66), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(15), 5, GFLAGS),
+    [SCLK_UART8] = COMPOSITE(SCLK_UART8, "sclk_uart8", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(67), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(15), 8, GFLAGS),
+    [SCLK_UART9] = COMPOSITE(SCLK_UART9, "sclk_uart9", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(68), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(15), 9, GFLAGS),
+    [SCLK_UART10] = COMPOSITE(SCLK_UART10, "sclk_uart10", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(69), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(15), 10, GFLAGS),
+    [SCLK_UART11] = COMPOSITE(SCLK_UART11, "sclk_uart11", clk_uart_p, 0,
+            RK3576_CLKSEL_CON(70), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(15), 11, GFLAGS),
+    [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(15), 13, GFLAGS),
+    [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(15), 14, GFLAGS),
+    [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(15), 15, GFLAGS),
+    [PCLK_SPI3] = GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(16), 0, GFLAGS),
+    [PCLK_SPI4] = GATE(PCLK_SPI4, "pclk_spi4", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(16), 1, GFLAGS),
+    [CLK_SPI0] = COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(70), 13, 2, MFLAGS,
+            RK3576_CLKGATE_CON(16), 2, GFLAGS),
+    [CLK_SPI1] = COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(71), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(16), 3, GFLAGS),
+    [CLK_SPI2] = COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(71), 2, 2, MFLAGS,
+            RK3576_CLKGATE_CON(16), 4, GFLAGS),
+    [CLK_SPI3] = COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(71), 4, 2, MFLAGS,
+            RK3576_CLKGATE_CON(16), 5, GFLAGS),
+    [CLK_SPI4] = COMPOSITE_NODIV(CLK_SPI4, "clk_spi4", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(71), 6, 2, MFLAGS,
+            RK3576_CLKGATE_CON(16), 6, GFLAGS),
+    [PCLK_WDT0] = GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(16), 7, GFLAGS),
+    [TCLK_WDT0] = GATE(TCLK_WDT0, "tclk_wdt0", "xin24m", 0,
+            RK3576_CLKGATE_CON(16), 8, GFLAGS),
+    [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(16), 10, GFLAGS),
+    [CLK_PWM1] = COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(71), 8, 2, MFLAGS,
+            RK3576_CLKGATE_CON(16), 11, GFLAGS),
+    [CLK_OSC_PWM1] = GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
+            RK3576_CLKGATE_CON(16), 13, GFLAGS),
+    [CLK_RC_PWM1] = GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_pvtm_clkout", 0,
+            RK3576_CLKGATE_CON(16), 15, GFLAGS),
+    [PCLK_BUSTIMER0] = GATE(PCLK_BUSTIMER0, "pclk_bustimer0", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(17), 3, GFLAGS),
+    [PCLK_BUSTIMER1] = GATE(PCLK_BUSTIMER1, "pclk_bustimer1", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(17), 4, GFLAGS),
+    [CLK_TIMER0_ROOT] = COMPOSITE_NODIV(CLK_TIMER0_ROOT, "clk_timer0_root", mux_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(71), 14, 1, MFLAGS,
+            RK3576_CLKGATE_CON(17), 5, GFLAGS),
+    [CLK_TIMER0] = GATE(CLK_TIMER0, "clk_timer0", "clk_timer0_root", 0,
+            RK3576_CLKGATE_CON(17), 6, GFLAGS),
+    [CLK_TIMER1] = GATE(CLK_TIMER1, "clk_timer1", "clk_timer0_root", 0,
+            RK3576_CLKGATE_CON(17), 7, GFLAGS),
+    [CLK_TIMER2] = GATE(CLK_TIMER2, "clk_timer2", "clk_timer0_root", 0,
+            RK3576_CLKGATE_CON(17), 8, GFLAGS),
+    [CLK_TIMER3] = GATE(CLK_TIMER3, "clk_timer3", "clk_timer0_root", 0,
+            RK3576_CLKGATE_CON(17), 9, GFLAGS),
+    [CLK_TIMER4] = GATE(CLK_TIMER4, "clk_timer4", "clk_timer0_root", 0,
+            RK3576_CLKGATE_CON(17), 10, GFLAGS),
+    [CLK_TIMER5] = GATE(CLK_TIMER5, "clk_timer5", "clk_timer0_root", 0,
+            RK3576_CLKGATE_CON(17), 11, GFLAGS),
+    [PCLK_MAILBOX0] = GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(17), 13, GFLAGS),
+    [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(17), 15, GFLAGS),
+    [DBCLK_GPIO1] = GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0,
+            RK3576_CLKGATE_CON(18), 0, GFLAGS),
+    [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(18), 1, GFLAGS),
+    [DBCLK_GPIO2] = GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0,
+            RK3576_CLKGATE_CON(18), 2, GFLAGS),
+    [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(18), 3, GFLAGS),
+    [DBCLK_GPIO3] = GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0,
+            RK3576_CLKGATE_CON(18), 4, GFLAGS),
+    [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(18), 5, GFLAGS),
+    [DBCLK_GPIO4] = GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0,
+            RK3576_CLKGATE_CON(18), 6, GFLAGS),
+    [ACLK_DECOM] = GATE(ACLK_DECOM, "aclk_decom", "aclk_bus_root", 0,
+            RK3576_CLKGATE_CON(18), 7, GFLAGS),
+    [PCLK_DECOM] = GATE(PCLK_DECOM, "pclk_decom", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(18), 8, GFLAGS),
+    [DCLK_DECOM] = COMPOSITE(DCLK_DECOM, "dclk_decom", gpll_spll_p, 0,
+            RK3576_CLKSEL_CON(72), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(18), 9, GFLAGS),
+    [CLK_TIMER1_ROOT] = COMPOSITE_NODIV(CLK_TIMER1_ROOT, "clk_timer1_root", mux_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(72), 6, 1, MFLAGS,
+            RK3576_CLKGATE_CON(18), 10, GFLAGS),
+    [CLK_TIMER6] = GATE(CLK_TIMER6, "clk_timer6", "clk_timer1_root", 0,
+            RK3576_CLKGATE_CON(18), 11, GFLAGS),
+    [CLK_TIMER7] = COMPOSITE(CLK_TIMER7, "clk_timer7", mux_100m_24m_lclk0_p, 0,
+            RK3576_CLKSEL_CON(72), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(18), 12, GFLAGS),
+    [CLK_TIMER8] = COMPOSITE(CLK_TIMER8, "clk_timer8", mux_100m_24m_lclk1_p, 0,
+            RK3576_CLKSEL_CON(73), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(18), 13, GFLAGS),
+    [CLK_TIMER9] = GATE(CLK_TIMER9, "clk_timer9", "clk_timer1_root", 0,
+            RK3576_CLKGATE_CON(18), 14, GFLAGS),
+    [CLK_TIMER10] = GATE(CLK_TIMER10, "clk_timer10", "clk_timer1_root", 0,
+            RK3576_CLKGATE_CON(18), 15, GFLAGS),
+    [CLK_TIMER11] = GATE(CLK_TIMER11, "clk_timer11", "clk_timer1_root", 0,
+            RK3576_CLKGATE_CON(19), 0, GFLAGS),
+    [ACLK_DMAC0] = GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
+            RK3576_CLKGATE_CON(19), 1, GFLAGS),
+    [ACLK_DMAC1] = GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
+            RK3576_CLKGATE_CON(19), 2, GFLAGS),
+    [ACLK_DMAC2] = GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_bus_root", 0,
+            RK3576_CLKGATE_CON(19), 3, GFLAGS),
+    [ACLK_SPINLOCK] = GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_bus_root", 0,
+            RK3576_CLKGATE_CON(19), 4, GFLAGS),
+    [HCLK_I3C0] = GATE(HCLK_I3C0, "hclk_i3c0", "hclk_bus_root", 0,
+            RK3576_CLKGATE_CON(19), 7, GFLAGS),
+    [HCLK_I3C1] = GATE(HCLK_I3C1, "hclk_i3c1", "hclk_bus_root", 0,
+            RK3576_CLKGATE_CON(19), 9, GFLAGS),
+    [HCLK_BUS_CM0_ROOT] = COMPOSITE_NODIV(HCLK_BUS_CM0_ROOT, "hclk_bus_cm0_root", mux_400m_200m_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(73), 13, 2, MFLAGS,
+            RK3576_CLKGATE_CON(19), 10, GFLAGS),
+    [FCLK_BUS_CM0_CORE] = GATE(FCLK_BUS_CM0_CORE, "fclk_bus_cm0_core", "hclk_bus_cm0_root", 0,
+            RK3576_CLKGATE_CON(19), 12, GFLAGS),
+    [CLK_BUS_CM0_RTC] = COMPOSITE(CLK_BUS_CM0_RTC, "clk_bus_cm0_rtc", mux_24m_32k_p, 0,
+            RK3576_CLKSEL_CON(74), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(19), 14, GFLAGS),
+    [PCLK_PMU2] = GATE(PCLK_PMU2, "pclk_pmu2", "pclk_bus_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKGATE_CON(19), 15, GFLAGS),
+    [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(20), 4, GFLAGS),
+    [CLK_PWM2] = COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(74), 6, 2, MFLAGS,
+            RK3576_CLKGATE_CON(20), 5, GFLAGS),
+    [CLK_RC_PWM2] = GATE(CLK_RC_PWM2, "clk_rc_pwm2", "clk_pvtm_clkout", 0,
+            RK3576_CLKGATE_CON(20), 6, GFLAGS),
+    [CLK_OSC_PWM2] = GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0,
+            RK3576_CLKGATE_CON(20), 7, GFLAGS),
+    [CLK_FREQ_PWM1] = COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_freq_pwm1_p, 0,
+            RK3576_CLKSEL_CON(74), 8, 3, MFLAGS,
+            RK3576_CLKGATE_CON(20), 8, GFLAGS),
+    [CLK_COUNTER_PWM1] = COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_counter_pwm1_p, 0,
+            RK3576_CLKSEL_CON(74), 11, 3, MFLAGS,
+            RK3576_CLKGATE_CON(20), 9, GFLAGS),
+    [SAI_SCLKIN_FREQ] = COMPOSITE_NODIV(SAI_SCLKIN_FREQ, "sai_sclkin_freq", sai_sclkin_freq_p, 0,
+            RK3576_CLKSEL_CON(75), 0, 3, MFLAGS,
+            RK3576_CLKGATE_CON(20), 10, GFLAGS),
+    [SAI_SCLKIN_COUNTER] = COMPOSITE_NODIV(SAI_SCLKIN_COUNTER, "sai_sclkin_counter", sai_sclkin_freq_p, 0,
+            RK3576_CLKSEL_CON(75), 3, 3, MFLAGS,
+            RK3576_CLKGATE_CON(20), 11, GFLAGS),
+    [CLK_I3C0] = COMPOSITE(CLK_I3C0, "clk_i3c0", gpll_cpll_aupll_spll_p, 0,
+            RK3576_CLKSEL_CON(78), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(20), 12, GFLAGS),
+    [CLK_I3C1] = COMPOSITE(CLK_I3C1, "clk_i3c1", gpll_cpll_aupll_spll_p, 0,
+            RK3576_CLKSEL_CON(78), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(20), 13, GFLAGS),
+    [PCLK_CSIDPHY1] = GATE(PCLK_CSIDPHY1, "pclk_csidphy1", "pclk_bus_root", 0,
+            RK3576_CLKGATE_CON(40), 2, GFLAGS),
+    [PCLK_DDR_ROOT] = COMPOSITE(PCLK_DDR_ROOT, "pclk_ddr_root", gpll_cpll_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(76), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(21), 0, GFLAGS),
+    [PCLK_DDR_MON_CH0] = GATE(PCLK_DDR_MON_CH0, "pclk_ddr_mon_ch0", "pclk_ddr_root", 0,
+            RK3576_CLKGATE_CON(21), 1, GFLAGS),
+    [HCLK_DDR_ROOT] = COMPOSITE(HCLK_DDR_ROOT, "hclk_ddr_root", gpll_cpll_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3576_CLKSEL_CON(77), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(22), 11, GFLAGS),
+    [FCLK_DDR_CM0_CORE] = GATE(FCLK_DDR_CM0_CORE, "fclk_ddr_cm0_core", "hclk_ddr_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKGATE_CON(22), 15, GFLAGS),
+    [CLK_DDR_TIMER_ROOT] = COMPOSITE_NODIV(CLK_DDR_TIMER_ROOT, "clk_ddr_timer_root", mux_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(77), 6, 1, MFLAGS,
+            RK3576_CLKGATE_CON(23), 3, GFLAGS),
+    [CLK_DDR_TIMER0] = GATE(CLK_DDR_TIMER0, "clk_ddr_timer0", "clk_ddr_timer_root", 0,
+            RK3576_CLKGATE_CON(23), 4, GFLAGS),
+    [CLK_DDR_TIMER1] = GATE(CLK_DDR_TIMER1, "clk_ddr_timer1", "clk_ddr_timer_root", 0,
+            RK3576_CLKGATE_CON(23), 5, GFLAGS),
+    [TCLK_WDT_DDR] = GATE(TCLK_WDT_DDR, "tclk_wdt_ddr", "xin24m", 0,
+            RK3576_CLKGATE_CON(23), 6, GFLAGS),
+    [PCLK_WDT] = GATE(PCLK_WDT, "pclk_wdt", "pclk_ddr_root", 0,
+            RK3576_CLKGATE_CON(23), 7, GFLAGS),
+    [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_ddr_root", 0,
+            RK3576_CLKGATE_CON(23), 8, GFLAGS),
+    [CLK_DDR_CM0_RTC] = COMPOSITE(CLK_DDR_CM0_RTC, "clk_ddr_cm0_rtc", mux_24m_32k_p, 0,
+            RK3576_CLKSEL_CON(77), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CLKGATE_CON(23), 10, GFLAGS),
+    [ACLK_RKNN0] = GATE(ACLK_RKNN0, "aclk_rknn0", "clk_rknn_dsu0", 0,
+            RK3576_CLKGATE_CON(28), 9, GFLAGS),
+    [ACLK_RKNN1] = GATE(ACLK_RKNN1, "aclk_rknn1", "clk_rknn_dsu0", 0,
+            RK3576_CLKGATE_CON(29), 0, GFLAGS),
+    [HCLK_RKNN_ROOT] = COMPOSITE_NODIV(HCLK_RKNN_ROOT, "hclk_rknn_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(86), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(31), 4, GFLAGS),
+    [CLK_RKNN_DSU0] = COMPOSITE(CLK_RKNN_DSU0, "clk_rknn_dsu0", gpll_cpll_aupll_spll_p, 0,
+            RK3576_CLKSEL_CON(86), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(31), 5, GFLAGS),
+    [PCLK_NPUTOP_ROOT] = COMPOSITE_NODIV(PCLK_NPUTOP_ROOT, "pclk_nputop_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(87), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(31), 8, GFLAGS),
+    [PCLK_NPU_TIMER] = GATE(PCLK_NPU_TIMER, "pclk_npu_timer", "pclk_nputop_root", 0,
+            RK3576_CLKGATE_CON(31), 10, GFLAGS),
+    [CLK_NPUTIMER_ROOT] = COMPOSITE_NODIV(CLK_NPUTIMER_ROOT, "clk_nputimer_root", mux_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(87), 2, 1, MFLAGS,
+            RK3576_CLKGATE_CON(31), 11, GFLAGS),
+    [CLK_NPUTIMER0] = GATE(CLK_NPUTIMER0, "clk_nputimer0", "clk_nputimer_root", 0,
+            RK3576_CLKGATE_CON(31), 12, GFLAGS),
+    [CLK_NPUTIMER1] = GATE(CLK_NPUTIMER1, "clk_nputimer1", "clk_nputimer_root", 0,
+            RK3576_CLKGATE_CON(31), 13, GFLAGS),
+    [PCLK_NPU_WDT] = GATE(PCLK_NPU_WDT, "pclk_npu_wdt", "pclk_nputop_root", 0,
+            RK3576_CLKGATE_CON(31), 14, GFLAGS),
+    [TCLK_NPU_WDT] = GATE(TCLK_NPU_WDT, "tclk_npu_wdt", "xin24m", 0,
+            RK3576_CLKGATE_CON(31), 15, GFLAGS),
+    [ACLK_RKNN_CBUF] = GATE(ACLK_RKNN_CBUF, "aclk_rknn_cbuf", "clk_rknn_dsu0", 0,
+            RK3576_CLKGATE_CON(32), 0, GFLAGS),
+    [HCLK_NPU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_NPU_CM0_ROOT, "hclk_npu_cm0_root", mux_400m_200m_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(87), 3, 2, MFLAGS,
+            RK3576_CLKGATE_CON(32), 5, GFLAGS),
+    [FCLK_NPU_CM0_CORE] = GATE(FCLK_NPU_CM0_CORE, "fclk_npu_cm0_core", "hclk_npu_cm0_root", 0,
+            RK3576_CLKGATE_CON(32), 7, GFLAGS),
+    [CLK_NPU_CM0_RTC] = COMPOSITE(CLK_NPU_CM0_RTC, "clk_npu_cm0_rtc", mux_24m_32k_p, 0,
+            RK3576_CLKSEL_CON(87), 10, 1, MFLAGS, 5, 5, DFLAGS,
+            RK3576_CLKGATE_CON(32), 9, GFLAGS),
+    [HCLK_RKNN_CBUF] = GATE(HCLK_RKNN_CBUF, "hclk_rknn_cbuf", "hclk_rknn_root", 0,
+            RK3576_CLKGATE_CON(32), 12, GFLAGS),
+    [HCLK_NVM_ROOT] = COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(88), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(33), 0, GFLAGS),
+    [ACLK_NVM_ROOT] = COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(88), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(33), 1, GFLAGS),
+    [SCLK_FSPI_X2] = COMPOSITE(SCLK_FSPI_X2, "sclk_fspi_x2", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(89), 6, 2, MFLAGS, 0, 6, DFLAGS,
+            RK3576_CLKGATE_CON(33), 6, GFLAGS),
+    [HCLK_FSPI] = GATE(HCLK_FSPI, "hclk_fspi", "hclk_nvm_root", 0,
+            RK3576_CLKGATE_CON(33), 7, GFLAGS),
+    [CCLK_SRC_EMMC] = COMPOSITE(CCLK_SRC_EMMC, "cclk_src_emmc", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(89), 14, 2, MFLAGS, 8, 6, DFLAGS,
+            RK3576_CLKGATE_CON(33), 8, GFLAGS),
+    [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_nvm_root", 0,
+            RK3576_CLKGATE_CON(33), 9, GFLAGS),
+    [ACLK_EMMC] = GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0,
+            RK3576_CLKGATE_CON(33), 10, GFLAGS),
+    [BCLK_EMMC] = COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(90), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(33), 11, GFLAGS),
+    [TCLK_EMMC] = GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0,
+            RK3576_CLKGATE_CON(33), 12, GFLAGS),
+    [PCLK_PHP_ROOT] = COMPOSITE_NODIV(PCLK_PHP_ROOT, "pclk_php_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(92), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(34), 0, GFLAGS),
+    [ACLK_PHP_ROOT] = COMPOSITE(ACLK_PHP_ROOT, "aclk_php_root", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(92), 9, 1, MFLAGS, 4, 5, DFLAGS,
+            RK3576_CLKGATE_CON(34), 7, GFLAGS),
+    [PCLK_PCIE0] = GATE(PCLK_PCIE0, "pclk_pcie0", "pclk_php_root", 0,
+            RK3576_CLKGATE_CON(34), 13, GFLAGS),
+    [CLK_PCIE0_AUX] = GATE(CLK_PCIE0_AUX, "clk_pcie0_aux", "xin24m", 0,
+            RK3576_CLKGATE_CON(34), 14, GFLAGS),
+    [ACLK_PCIE0_MST] = GATE(ACLK_PCIE0_MST, "aclk_pcie0_mst", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(34), 15, GFLAGS),
+    [ACLK_PCIE0_SLV] = GATE(ACLK_PCIE0_SLV, "aclk_pcie0_slv", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(35), 0, GFLAGS),
+    [ACLK_PCIE0_DBI] = GATE(ACLK_PCIE0_DBI, "aclk_pcie0_dbi", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(35), 1, GFLAGS),
+    [ACLK_USB3OTG1] = GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(35), 3, GFLAGS),
+    [CLK_REF_USB3OTG1] = GATE(CLK_REF_USB3OTG1, "clk_ref_usb3otg1", "xin24m", 0,
+            RK3576_CLKGATE_CON(35), 4, GFLAGS),
+    [CLK_SUSPEND_USB3OTG1] = GATE(CLK_SUSPEND_USB3OTG1, "clk_suspend_usb3otg1", "xin24m", 0,
+            RK3576_CLKGATE_CON(35), 5, GFLAGS),
+    [ACLK_MMU0] = GATE(ACLK_MMU0, "aclk_mmu0", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(35), 11, GFLAGS),
+    [ACLK_SLV_MMU0] = GATE(ACLK_SLV_MMU0, "aclk_slv_mmu0", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(35), 13, GFLAGS),
+    [ACLK_MMU1] = GATE(ACLK_MMU1, "aclk_mmu1", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(35), 14, GFLAGS),
+    [ACLK_SLV_MMU1] = GATE(ACLK_SLV_MMU1, "aclk_slv_mmu1", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(36), 0, GFLAGS),
+    [PCLK_PCIE1] = GATE(PCLK_PCIE1, "pclk_pcie1", "pclk_php_root", 0,
+            RK3576_CLKGATE_CON(36), 7, GFLAGS),
+    [CLK_PCIE1_AUX] = GATE(CLK_PCIE1_AUX, "clk_pcie1_aux", "xin24m", 0,
+            RK3576_CLKGATE_CON(36), 8, GFLAGS),
+    [ACLK_PCIE1_MST] = GATE(ACLK_PCIE1_MST, "aclk_pcie1_mst", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(36), 9, GFLAGS),
+    [ACLK_PCIE1_SLV] = GATE(ACLK_PCIE1_SLV, "aclk_pcie1_slv", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(36), 10, GFLAGS),
+    [ACLK_PCIE1_DBI] = GATE(ACLK_PCIE1_DBI, "aclk_pcie1_dbi", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(36), 11, GFLAGS),
+    [CLK_RXOOB0] = COMPOSITE(CLK_RXOOB0, "clk_rxoob0", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(93), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3576_CLKGATE_CON(37), 0, GFLAGS),
+    [CLK_RXOOB1] = COMPOSITE(CLK_RXOOB1, "clk_rxoob1", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(93), 15, 1, MFLAGS, 8, 7, DFLAGS,
+            RK3576_CLKGATE_CON(37), 1, GFLAGS),
+    [CLK_PMALIVE0] = GATE(CLK_PMALIVE0, "clk_pmalive0", "xin24m", RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKGATE_CON(37), 2, GFLAGS),
+    [CLK_PMALIVE1] = GATE(CLK_PMALIVE1, "clk_pmalive1", "xin24m", RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKGATE_CON(37), 3, GFLAGS),
+    [ACLK_SATA0] = GATE(ACLK_SATA0, "aclk_sata0", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(37), 4, GFLAGS),
+    [ACLK_SATA1] = GATE(ACLK_SATA1, "aclk_sata1", "aclk_php_root", 0,
+            RK3576_CLKGATE_CON(37), 5, GFLAGS),
+    [HCLK_SDGMAC_ROOT] = COMPOSITE_NODIV(HCLK_SDGMAC_ROOT, "hclk_sdgmac_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(103), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(42), 0, GFLAGS),
+    [ACLK_SDGMAC_ROOT] = COMPOSITE(ACLK_SDGMAC_ROOT, "aclk_sdgmac_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(103), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(42), 1, GFLAGS),
+    [PCLK_SDGMAC_ROOT] = COMPOSITE_NODIV(PCLK_SDGMAC_ROOT, "pclk_sdgmac_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(103), 8, 2, MFLAGS,
+            RK3576_CLKGATE_CON(42), 2, GFLAGS),
+    [ACLK_GMAC0] = GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(42), 7, GFLAGS),
+    [ACLK_GMAC1] = GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(42), 8, GFLAGS),
+    [PCLK_GMAC0] = GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(42), 9, GFLAGS),
+    [PCLK_GMAC1] = GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(42), 10, GFLAGS),
+    [CCLK_SRC_SDIO] = COMPOSITE(CCLK_SRC_SDIO, "cclk_src_sdio", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(104), 6, 2, MFLAGS, 0, 6, DFLAGS,
+            RK3576_CLKGATE_CON(42), 11, GFLAGS),
+    [HCLK_SDIO] = GATE(HCLK_SDIO, "hclk_sdio", "hclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(42), 12, GFLAGS),
+    [CLK_GMAC1_PTP_REF] = GATE(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", "clk_gmac1_ptp_ref_src", 0,
+            RK3576_CLKGATE_CON(42), 13, GFLAGS),
+    [CLK_GMAC0_PTP_REF] = GATE(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", "clk_gmac0_ptp_ref_src", 0,
+            RK3576_CLKGATE_CON(42), 14, GFLAGS),
+    [CLK_GMAC1_PTP_REF_SRC] = COMPOSITE(CLK_GMAC1_PTP_REF_SRC, "clk_gmac1_ptp_ref_src", clk_gmac1_ptp_ref_src_p, 0,
+            RK3576_CLKSEL_CON(104), 13, 2, MFLAGS, 8, 5, DFLAGS,
+            RK3576_CLKGATE_CON(42), 15, GFLAGS),
+    [CLK_GMAC0_PTP_REF_SRC] = COMPOSITE(CLK_GMAC0_PTP_REF_SRC, "clk_gmac0_ptp_ref_src", clk_gmac0_ptp_ref_src_p, 0,
+            RK3576_CLKSEL_CON(105), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(43), 0, GFLAGS),
+    [CCLK_SRC_SDMMC0] = COMPOSITE(CCLK_SRC_SDMMC0, "cclk_src_sdmmc0", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(105), 13, 2, MFLAGS, 7, 6, DFLAGS,
+            RK3576_CLKGATE_CON(43), 1, GFLAGS),
+    [HCLK_SDMMC0] = GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(43), 2, GFLAGS),
+    [SCLK_FSPI1_X2] = COMPOSITE(SCLK_FSPI1_X2, "sclk_fspi1_x2", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(106), 6, 2, MFLAGS, 0, 6, DFLAGS,
+            RK3576_CLKGATE_CON(43), 3, GFLAGS),
+    [HCLK_FSPI1] = GATE(HCLK_FSPI1, "hclk_fspi1", "hclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(43), 4, GFLAGS),
+    [ACLK_DSMC_ROOT] = COMPOSITE(ACLK_DSMC_ROOT, "aclk_dsmc_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(106), 13, 1, MFLAGS, 8, 5, DFLAGS,
+            RK3576_CLKGATE_CON(43), 5, GFLAGS),
+    [ACLK_DSMC] = GATE(ACLK_DSMC, "aclk_dsmc", "aclk_dsmc_root", 0,
+            RK3576_CLKGATE_CON(43), 7, GFLAGS),
+    [PCLK_DSMC] = GATE(PCLK_DSMC, "pclk_dsmc", "pclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(43), 8, GFLAGS),
+    [CLK_DSMC_SYS] = COMPOSITE(CLK_DSMC_SYS, "clk_dsmc_sys", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(107), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(43), 9, GFLAGS),
+    [HCLK_HSGPIO] = GATE(HCLK_HSGPIO, "hclk_hsgpio", "hclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(43), 10, GFLAGS),
+    [CLK_HSGPIO_TX] = COMPOSITE(CLK_HSGPIO_TX, "clk_hsgpio_tx", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(107), 11, 2, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(43), 11, GFLAGS),
+    [CLK_HSGPIO_RX] = COMPOSITE(CLK_HSGPIO_RX, "clk_hsgpio_rx", gpll_cpll_24m_p, 0,
+            RK3576_CLKSEL_CON(108), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(43), 12, GFLAGS),
+    [ACLK_HSGPIO] = GATE(ACLK_HSGPIO, "aclk_hsgpio", "aclk_sdgmac_root", 0,
+            RK3576_CLKGATE_CON(43), 13, GFLAGS),
+    [PCLK_PHPPHY_ROOT] = GATE(PCLK_PHPPHY_ROOT, "pclk_phpphy_root", "pclk_bus_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_PHP_CLKGATE_CON(0), 2, GFLAGS),
+    [PCLK_PCIE2_COMBOPHY0] = GATE(PCLK_PCIE2_COMBOPHY0, "pclk_pcie2_combophy0", "pclk_phpphy_root", 0,
+            RK3576_PHP_CLKGATE_CON(0), 5, GFLAGS),
+    [PCLK_PCIE2_COMBOPHY1] = GATE(PCLK_PCIE2_COMBOPHY1, "pclk_pcie2_combophy1", "pclk_phpphy_root", 0,
+            RK3576_PHP_CLKGATE_CON(0), 7, GFLAGS),
+    [CLK_PCIE_100M_SRC] = COMPOSITE_NOMUX(CLK_PCIE_100M_SRC, "clk_pcie_100m_src", "ppll", 0,
+            RK3576_PHP_CLKSEL_CON(0), 2, 5, DFLAGS,
+            RK3576_PHP_CLKGATE_CON(1), 1, GFLAGS),
+    [CLK_PCIE_100M_NDUTY_SRC] = COMPOSITE_NOMUX(CLK_PCIE_100M_NDUTY_SRC, "clk_pcie_100m_nduty_src", "ppll", 0,
+            RK3576_PHP_CLKSEL_CON(0), 7, 5, DFLAGS,
+            RK3576_PHP_CLKGATE_CON(1), 2, GFLAGS),
+    [CLK_REF_PCIE0_PHY] = COMPOSITE_NODIV(CLK_REF_PCIE0_PHY, "clk_ref_pcie0_phy", clk_ref_pcie0_phy_p, 0,
+            RK3576_PHP_CLKSEL_CON(0), 12, 2, MFLAGS,
+            RK3576_PHP_CLKGATE_CON(1), 5, GFLAGS),
+    [CLK_REF_PCIE1_PHY] = COMPOSITE_NODIV(CLK_REF_PCIE1_PHY, "clk_ref_pcie1_phy", clk_ref_pcie0_phy_p, 0,
+            RK3576_PHP_CLKSEL_CON(0), 14, 2, MFLAGS,
+            RK3576_PHP_CLKGATE_CON(1), 8, GFLAGS),
+    [CLK_REF_MPHY_26M] = COMPOSITE_NOMUX(CLK_REF_MPHY_26M, "clk_ref_mphy_26m", "ppll", RT_CLK_F_IS_CRITICAL,
+            RK3576_PHP_CLKSEL_CON(1), 0, 8, DFLAGS,
+            RK3576_PHP_CLKGATE_CON(1), 9, GFLAGS),
+    [HCLK_RKVDEC_ROOT] = COMPOSITE_NODIV(HCLK_RKVDEC_ROOT, "hclk_rkvdec_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(110), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(45), 0, GFLAGS),
+    [ACLK_RKVDEC_ROOT] = COMPOSITE(ACLK_RKVDEC_ROOT, "aclk_rkvdec_root", gpll_cpll_aupll_spll_p, 0,
+            RK3576_CLKSEL_CON(110), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(45), 1, GFLAGS),
+    [HCLK_RKVDEC] = GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_root", 0,
+            RK3576_CLKGATE_CON(45), 3, GFLAGS),
+    [CLK_RKVDEC_HEVC_CA] = COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_lpll_bpll_p, 0,
+            RK3576_CLKSEL_CON(111), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(45), 8, GFLAGS),
+    [CLK_RKVDEC_CORE] = GATE(CLK_RKVDEC_CORE, "clk_rkvdec_core", "aclk_rkvdec_root", 0,
+            RK3576_CLKGATE_CON(45), 9, GFLAGS),
+    [ACLK_UFS_ROOT] = COMPOSITE(ACLK_UFS_ROOT, "aclk_ufs_root", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(115), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(47), 0, GFLAGS),
+    [ACLK_USB_ROOT] = COMPOSITE(ACLK_USB_ROOT, "aclk_usb_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(115), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(47), 1, GFLAGS),
+    [PCLK_USB_ROOT] = COMPOSITE_NODIV(PCLK_USB_ROOT, "pclk_usb_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(115), 12, 2, MFLAGS,
+            RK3576_CLKGATE_CON(47), 2, GFLAGS),
+    [ACLK_USB3OTG0] = GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb_root", 0,
+            RK3576_CLKGATE_CON(47), 5, GFLAGS),
+    [CLK_REF_USB3OTG0] = GATE(CLK_REF_USB3OTG0, "clk_ref_usb3otg0", "xin24m", 0,
+            RK3576_CLKGATE_CON(47), 6, GFLAGS),
+    [CLK_SUSPEND_USB3OTG0] = GATE(CLK_SUSPEND_USB3OTG0, "clk_suspend_usb3otg0", "xin24m", 0,
+            RK3576_CLKGATE_CON(47), 7, GFLAGS),
+    [ACLK_MMU2] = GATE(ACLK_MMU2, "aclk_mmu2", "aclk_usb_root", 0,
+            RK3576_CLKGATE_CON(47), 12, GFLAGS),
+    [ACLK_SLV_MMU2] = GATE(ACLK_SLV_MMU2, "aclk_slv_mmu2", "aclk_usb_root", 0,
+            RK3576_CLKGATE_CON(47), 13, GFLAGS),
+    [ACLK_UFS_SYS] = GATE(ACLK_UFS_SYS, "aclk_ufs_sys", "aclk_ufs_root", 0,
+            RK3576_CLKGATE_CON(47), 15, GFLAGS),
+    [ACLK_VPU_ROOT] = COMPOSITE(ACLK_VPU_ROOT, "aclk_vpu_root", gpll_spll_cpll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(118), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(49), 0, GFLAGS),
+    [ACLK_VPU_MID_ROOT] = COMPOSITE_NODIV(ACLK_VPU_MID_ROOT, "aclk_vpu_mid_root", mux_600m_400m_300m_24m_p, 0,
+            RK3576_CLKSEL_CON(118), 8, 2, MFLAGS,
+            RK3576_CLKGATE_CON(49), 1, GFLAGS),
+    [HCLK_VPU_ROOT] = COMPOSITE_NODIV(HCLK_VPU_ROOT, "hclk_vpu_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(118), 10, 2, MFLAGS,
+            RK3576_CLKGATE_CON(49), 2, GFLAGS),
+    [ACLK_JPEG_ROOT] = COMPOSITE(ACLK_JPEG_ROOT, "aclk_jpeg_root", gpll_cpll_aupll_spll_p, 0,
+            RK3576_CLKSEL_CON(119), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(49), 3, GFLAGS),
+    [ACLK_VPU_LOW_ROOT] = COMPOSITE_NODIV(ACLK_VPU_LOW_ROOT, "aclk_vpu_low_root", mux_400m_200m_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(119), 7, 2, MFLAGS,
+            RK3576_CLKGATE_CON(49), 4, GFLAGS),
+    [HCLK_RGA2E_0] = GATE(HCLK_RGA2E_0, "hclk_rga2e_0", "hclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(49), 13, GFLAGS),
+    [ACLK_RGA2E_0] = GATE(ACLK_RGA2E_0, "aclk_rga2e_0", "aclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(49), 14, GFLAGS),
+    [CLK_CORE_RGA2E_0] = COMPOSITE(CLK_CORE_RGA2E_0, "clk_core_rga2e_0", gpll_spll_cpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(120), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(49), 15, GFLAGS),
+    [ACLK_JPEG] = GATE(ACLK_JPEG, "aclk_jpeg", "aclk_jpeg_root", 0,
+            RK3576_CLKGATE_CON(50), 0, GFLAGS),
+    [HCLK_JPEG] = GATE(HCLK_JPEG, "hclk_jpeg", "hclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(50), 1, GFLAGS),
+    [HCLK_VDPP] = GATE(HCLK_VDPP, "hclk_vdpp", "hclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(50), 2, GFLAGS),
+    [ACLK_VDPP] = GATE(ACLK_VDPP, "aclk_vdpp", "aclk_vpu_mid_root", 0,
+            RK3576_CLKGATE_CON(50), 3, GFLAGS),
+    [CLK_CORE_VDPP] = COMPOSITE(CLK_CORE_VDPP, "clk_core_vdpp", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(120), 13, 1, MFLAGS, 8, 5, DFLAGS,
+            RK3576_CLKGATE_CON(50), 4, GFLAGS),
+    [HCLK_RGA2E_1] = GATE(HCLK_RGA2E_1, "hclk_rga2e_1", "hclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(50), 5, GFLAGS),
+    [ACLK_RGA2E_1] = GATE(ACLK_RGA2E_1, "aclk_rga2e_1", "aclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(50), 6, GFLAGS),
+    [CLK_CORE_RGA2E_1] = COMPOSITE(CLK_CORE_RGA2E_1, "clk_core_rga2e_1", gpll_spll_cpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(121), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(50), 7, GFLAGS),
+    [DCLK_EBC_FRAC_SRC] = COMPOSITE_FRAC(DCLK_EBC_FRAC_SRC, "dclk_ebc_frac_src", "dclk_ebc_frac_src_p", 0,
+            RK3576_CLKSEL_CON(122), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3576_CLKGATE_CON(50), 9, GFLAGS),
+    [HCLK_EBC] = GATE(ACLK_EBC, "aclk_ebc", "aclk_vpu_low_root", 0,
+            RK3576_CLKGATE_CON(50), 11, GFLAGS),
+    [ACLK_EBC] = GATE(HCLK_EBC, "hclk_ebc", "hclk_vpu_root", 0,
+            RK3576_CLKGATE_CON(50), 10, GFLAGS),
+    [DCLK_EBC] = COMPOSITE(DCLK_EBC, "dclk_ebc", dclk_ebc_p, 0,
+            RK3576_CLKSEL_CON(123), 12, 3, MFLAGS, 3, 9, DFLAGS,
+            RK3576_CLKGATE_CON(50), 12, GFLAGS),
+    [HCLK_VEPU0_ROOT] = COMPOSITE_NODIV(HCLK_VEPU0_ROOT, "hclk_vepu0_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(124), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(51), 0, GFLAGS),
+    [ACLK_VEPU0_ROOT] = COMPOSITE(ACLK_VEPU0_ROOT, "aclk_vepu0_root", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(124), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3576_CLKGATE_CON(51), 1, GFLAGS),
+    [HCLK_VEPU0] = GATE(HCLK_VEPU0, "hclk_vepu0", "hclk_vepu0_root", 0,
+            RK3576_CLKGATE_CON(51), 4, GFLAGS),
+    [ACLK_VEPU0] = GATE(ACLK_VEPU0, "aclk_vepu0", "aclk_vepu0_root", 0,
+            RK3576_CLKGATE_CON(51), 5, GFLAGS),
+    [CLK_VEPU0_CORE] = COMPOSITE(CLK_VEPU0_CORE, "clk_vepu0_core", gpll_cpll_spll_lpll_bpll_p, 0,
+            RK3576_CLKSEL_CON(124), 13, 3, MFLAGS, 8, 5, DFLAGS,
+            RK3576_CLKGATE_CON(51), 6, GFLAGS),
+    [ACLK_VI_ROOT] = COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_spll_isppvtpll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(128), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(53), 0, GFLAGS),
+    [HCLK_VI_ROOT] = COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", hclk_vi_root_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(128), 8, 2, MFLAGS,
+            RK3576_CLKGATE_CON(53), 1, GFLAGS),
+    [PCLK_VI_ROOT] = COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(128), 10, 2, MFLAGS,
+            RK3576_CLKGATE_CON(53), 2, GFLAGS),
+    [DCLK_VICAP] = COMPOSITE(DCLK_VICAP, "dclk_vicap", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(129), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(53), 6, GFLAGS),
+    [ACLK_VICAP] = GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0,
+            RK3576_CLKGATE_CON(53), 7, GFLAGS),
+    [HCLK_VICAP] = GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0,
+            RK3576_CLKGATE_CON(53), 8, GFLAGS),
+    [CLK_ISP_CORE] = COMPOSITE(CLK_ISP_CORE, "clk_isp_core", gpll_spll_isppvtpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(129), 11, 3, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(53), 9, GFLAGS),
+    [CLK_ISP_CORE_MARVIN] = GATE(CLK_ISP_CORE_MARVIN, "clk_isp_core_marvin", "clk_isp_core", 0,
+            RK3576_CLKGATE_CON(53), 10, GFLAGS),
+    [CLK_ISP_CORE_VICAP] = GATE(CLK_ISP_CORE_VICAP, "clk_isp_core_vicap", "clk_isp_core", 0,
+            RK3576_CLKGATE_CON(53), 11, GFLAGS),
+    [ACLK_ISP] = GATE(ACLK_ISP, "aclk_isp", "aclk_vi_root", 0,
+            RK3576_CLKGATE_CON(53), 12, GFLAGS),
+    [HCLK_ISP] = GATE(HCLK_ISP, "hclk_isp", "hclk_vi_root", 0,
+            RK3576_CLKGATE_CON(53), 13, GFLAGS),
+    [ACLK_VPSS] = GATE(ACLK_VPSS, "aclk_vpss", "aclk_vi_root", 0,
+            RK3576_CLKGATE_CON(53), 15, GFLAGS),
+    [HCLK_VPSS] = GATE(HCLK_VPSS, "hclk_vpss", "hclk_vi_root", 0,
+            RK3576_CLKGATE_CON(54), 0, GFLAGS),
+    [CLK_CORE_VPSS] = GATE(CLK_CORE_VPSS, "clk_core_vpss", "clk_isp_core", 0,
+            RK3576_CLKGATE_CON(54), 1, GFLAGS),
+    [PCLK_CSI_HOST_0] = GATE(PCLK_CSI_HOST_0, "pclk_csi_host_0", "pclk_vi_root", 0,
+            RK3576_CLKGATE_CON(54), 4, GFLAGS),
+    [PCLK_CSI_HOST_1] = GATE(PCLK_CSI_HOST_1, "pclk_csi_host_1", "pclk_vi_root", 0,
+            RK3576_CLKGATE_CON(54), 5, GFLAGS),
+    [PCLK_CSI_HOST_2] = GATE(PCLK_CSI_HOST_2, "pclk_csi_host_2", "pclk_vi_root", 0,
+            RK3576_CLKGATE_CON(54), 6, GFLAGS),
+    [PCLK_CSI_HOST_3] = GATE(PCLK_CSI_HOST_3, "pclk_csi_host_3", "pclk_vi_root", 0,
+            RK3576_CLKGATE_CON(54), 7, GFLAGS),
+    [PCLK_CSI_HOST_4] = GATE(PCLK_CSI_HOST_4, "pclk_csi_host_4", "pclk_vi_root", 0,
+            RK3576_CLKGATE_CON(54), 8, GFLAGS),
+    [ICLK_CSIHOST01] = COMPOSITE_NODIV(ICLK_CSIHOST01, "iclk_csihost01", mux_400m_200m_100m_24m_p, 0,
+            RK3576_CLKSEL_CON(130), 7, 2, MFLAGS,
+            RK3576_CLKGATE_CON(54), 10, GFLAGS),
+    [ICLK_CSIHOST0] = GATE(ICLK_CSIHOST0, "iclk_csihost0", "iclk_csihost01", 0,
+            RK3576_CLKGATE_CON(54), 11, GFLAGS),
+    [ACLK_VI_ROOT_INTER] = COMPOSITE_NOMUX(ACLK_VI_ROOT_INTER, "aclk_vi_root_inter", "aclk_vi_root", 0,
+            RK3576_CLKSEL_CON(130), 10, 3, DFLAGS,
+            RK3576_CLKGATE_CON(54), 13, GFLAGS),
+    [CLK_VICAP_I0CLK] = GATE(CLK_VICAP_I0CLK, "clk_vicap_i0clk", "clk_csihost0_clkdata_i", 0,
+            RK3576_CLKGATE_CON(59), 1, GFLAGS),
+    [CLK_VICAP_I1CLK] = GATE(CLK_VICAP_I1CLK, "clk_vicap_i1clk", "clk_csihost1_clkdata_i", 0,
+            RK3576_CLKGATE_CON(59), 2, GFLAGS),
+    [CLK_VICAP_I2CLK] = GATE(CLK_VICAP_I2CLK, "clk_vicap_i2clk", "clk_csihost2_clkdata_i", 0,
+            RK3576_CLKGATE_CON(59), 3, GFLAGS),
+    [CLK_VICAP_I3CLK] = GATE(CLK_VICAP_I3CLK, "clk_vicap_i3clk", "clk_csihost3_clkdata_i", 0,
+            RK3576_CLKGATE_CON(59), 4, GFLAGS),
+    [CLK_VICAP_I4CLK] = GATE(CLK_VICAP_I4CLK, "clk_vicap_i4clk", "clk_csihost4_clkdata_i", 0,
+            RK3576_CLKGATE_CON(59), 5, GFLAGS),
+    [ACLK_VOP_ROOT] = COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_aupll_spll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(144), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(61), 0, GFLAGS),
+    [HCLK_VOP_ROOT] = COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(144), 10, 2, MFLAGS,
+            RK3576_CLKGATE_CON(61), 2, GFLAGS),
+    [PCLK_VOP_ROOT] = COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(144), 12, 2, MFLAGS,
+            RK3576_CLKGATE_CON(61), 3, GFLAGS),
+    [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", 0,
+            RK3576_CLKGATE_CON(61), 8, GFLAGS),
+    [ACLK_VOP] = GATE(ACLK_VOP, "aclk_vop", "aclk_vop_root", 0,
+            RK3576_CLKGATE_CON(61), 9, GFLAGS),
+    [DCLK_VP0_SRC] = COMPOSITE(DCLK_VP0_SRC, "dclk_vp0_src", gpll_cpll_vpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(145), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(61), 10, GFLAGS),
+    [DCLK_VP1_SRC] = COMPOSITE(DCLK_VP1_SRC, "dclk_vp1_src", gpll_cpll_vpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(146), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(61), 11, GFLAGS),
+    [DCLK_VP2_SRC] = COMPOSITE(DCLK_VP2_SRC, "dclk_vp2_src", gpll_cpll_vpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(147), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(61), 12, GFLAGS),
+    [DCLK_VP0] = COMPOSITE_NODIV(DCLK_VP0, "dclk_vp0", dclk_vp0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(147), 11, 1, MFLAGS,
+            RK3576_CLKGATE_CON(61), 13, GFLAGS),
+    [DCLK_VP1] = COMPOSITE_NODIV(DCLK_VP1, "dclk_vp1", dclk_vp1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(147), 12, 1, MFLAGS,
+            RK3576_CLKGATE_CON(62), 0, GFLAGS),
+    [DCLK_VP2] = COMPOSITE_NODIV(DCLK_VP2, "dclk_vp2", dclk_vp2_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(147), 13, 1, MFLAGS,
+            RK3576_CLKGATE_CON(62), 1, GFLAGS),
+    [ACLK_VO0_ROOT] = COMPOSITE(ACLK_VO0_ROOT, "aclk_vo0_root", gpll_cpll_lpll_bpll_p, 0,
+            RK3576_CLKSEL_CON(149), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(63), 0, GFLAGS),
+    [HCLK_VO0_ROOT] = COMPOSITE_NODIV(HCLK_VO0_ROOT, "hclk_vo0_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(149), 7, 2, MFLAGS,
+            RK3576_CLKGATE_CON(63), 1, GFLAGS),
+    [PCLK_VO0_ROOT] = COMPOSITE_NODIV(PCLK_VO0_ROOT, "pclk_vo0_root", mux_150m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(149), 11, 2, MFLAGS,
+            RK3576_CLKGATE_CON(63), 3, GFLAGS),
+    [ACLK_HDCP0] = GATE(ACLK_HDCP0, "aclk_hdcp0", "aclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(63), 12, GFLAGS),
+    [HCLK_HDCP0] = GATE(HCLK_HDCP0, "hclk_hdcp0", "hclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(63), 13, GFLAGS),
+    [PCLK_HDCP0] = GATE(PCLK_HDCP0, "pclk_hdcp0", "pclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(63), 14, GFLAGS),
+    [CLK_TRNG0_SKP] = GATE(CLK_TRNG0_SKP, "clk_trng0_skp", "aclk_hdcp0", 0,
+            RK3576_CLKGATE_CON(64), 4, GFLAGS),
+    [PCLK_DSIHOST0] = GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(64), 5, GFLAGS),
+    [CLK_DSIHOST0] = COMPOSITE(CLK_DSIHOST0, "clk_dsihost0", gpll_cpll_spll_vpll_bpll_lpll_p, 0,
+            RK3576_CLKSEL_CON(151), 7, 3, MFLAGS, 0, 7, DFLAGS,
+            RK3576_CLKGATE_CON(64), 6, GFLAGS),
+    [PCLK_HDMITX0] = GATE(PCLK_HDMITX0, "pclk_hdmitx0", "pclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(64), 7, GFLAGS),
+    [CLK_HDMITX0_EARC] = COMPOSITE(CLK_HDMITX0_EARC, "clk_hdmitx0_earc", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(151), 15, 1, MFLAGS, 10, 5, DFLAGS,
+            RK3576_CLKGATE_CON(64), 8, GFLAGS),
+    [CLK_HDMITX0_REF] = GATE(CLK_HDMITX0_REF, "clk_hdmitx0_ref", "aclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(64), 9, GFLAGS),
+    [PCLK_EDP0] = GATE(PCLK_EDP0, "pclk_edp0", "pclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(64), 13, GFLAGS),
+    [CLK_EDP0_24M] = GATE(CLK_EDP0_24M, "clk_edp0_24m", "xin24m", 0,
+            RK3576_CLKGATE_CON(64), 14, GFLAGS),
+    [CLK_EDP0_200M] = COMPOSITE_NODIV(CLK_EDP0_200M, "clk_edp0_200m", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(152), 1, 2, MFLAGS,
+            RK3576_CLKGATE_CON(64), 15, GFLAGS),
+    [MCLK_SAI5_8CH_SRC] = COMPOSITE(MCLK_SAI5_8CH_SRC, "mclk_sai5_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(154), 10, 3, MFLAGS, 2, 8, DFLAGS,
+            RK3576_CLKGATE_CON(65), 3, GFLAGS),
+    [MCLK_SAI5_8CH] = COMPOSITE_NODIV(MCLK_SAI5_8CH, "mclk_sai5_8ch", mclk_sai5_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(154), 13, 1, MFLAGS,
+            RK3576_CLKGATE_CON(65), 4, GFLAGS),
+    [HCLK_SAI5_8CH] = GATE(HCLK_SAI5_8CH, "hclk_sai5_8ch", "hclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(65), 5, GFLAGS),
+    [MCLK_SAI6_8CH_SRC] = COMPOSITE(MCLK_SAI6_8CH_SRC, "mclk_sai6_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(155), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(65), 7, GFLAGS),
+    [MCLK_SAI6_8CH] = COMPOSITE_NODIV(MCLK_SAI6_8CH, "mclk_sai6_8ch", mclk_sai6_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(155), 11, 1, MFLAGS,
+            RK3576_CLKGATE_CON(65), 8, GFLAGS),
+    [HCLK_SAI6_8CH] = GATE(HCLK_SAI6_8CH, "hclk_sai6_8ch", "hclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(65), 9, GFLAGS),
+    [HCLK_SPDIF_TX2] = GATE(HCLK_SPDIF_TX2, "hclk_spdif_tx2", "hclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(65), 10, GFLAGS),
+    [MCLK_SPDIF_TX2] = COMPOSITE(MCLK_SPDIF_TX2, "mclk_spdif_tx2", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(156), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(65), 13, GFLAGS),
+    [HCLK_SPDIF_RX2] = GATE(HCLK_SPDIF_RX2, "hclk_spdif_rx2", "hclk_vo0_root", 0,
+            RK3576_CLKGATE_CON(65), 14, GFLAGS),
+    [MCLK_SPDIF_RX2] = COMPOSITE(MCLK_SPDIF_RX2, "mclk_spdif_rx2", gpll_cpll_aupll_p, 0,
+            RK3576_CLKSEL_CON(156), 13, 2, MFLAGS, 8, 5, DFLAGS,
+            RK3576_CLKGATE_CON(65), 15, GFLAGS),
+    [HCLK_SAI8_8CH] = GATE(HCLK_SAI8_8CH, "hclk_sai8_8ch", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(66), 0, GFLAGS),
+    [MCLK_SAI8_8CH_SRC] = COMPOSITE(MCLK_SAI8_8CH_SRC, "mclk_sai8_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(157), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(66), 1, GFLAGS),
+    [MCLK_SAI8_8CH] = COMPOSITE_NODIV(MCLK_SAI8_8CH, "mclk_sai8_8ch", mclk_sai8_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(157), 11, 1, MFLAGS,
+            RK3576_CLKGATE_CON(66), 2, GFLAGS),
+    [ACLK_VO1_ROOT] = COMPOSITE(ACLK_VO1_ROOT, "aclk_vo1_root", gpll_cpll_lpll_bpll_p, 0,
+            RK3576_CLKSEL_CON(158), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(67), 1, GFLAGS),
+    [HCLK_VO1_ROOT] = COMPOSITE_NODIV(HCLK_VO1_ROOT, "hclk_vo1_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(158), 7, 2, MFLAGS,
+            RK3576_CLKGATE_CON(67), 2, GFLAGS),
+    [PCLK_VO1_ROOT] = COMPOSITE_NODIV(PCLK_VO1_ROOT, "pclk_vo1_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(158), 9, 2, MFLAGS,
+            RK3576_CLKGATE_CON(67), 3, GFLAGS),
+    [MCLK_SAI7_8CH_SRC] = COMPOSITE(MCLK_SAI7_8CH_SRC, "mclk_sai7_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(159), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(67), 8, GFLAGS),
+    [MCLK_SAI7_8CH] = COMPOSITE_NODIV(MCLK_SAI7_8CH, "mclk_sai7_8ch", mclk_sai7_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(159), 11, 1, MFLAGS,
+            RK3576_CLKGATE_CON(67), 9, GFLAGS),
+    [HCLK_SAI7_8CH] = GATE(HCLK_SAI7_8CH, "hclk_sai7_8ch", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(67), 10, GFLAGS),
+    [HCLK_SPDIF_TX3] = GATE(HCLK_SPDIF_TX3, "hclk_spdif_tx3", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(67), 11, GFLAGS),
+    [HCLK_SPDIF_TX4] = GATE(HCLK_SPDIF_TX4, "hclk_spdif_tx4", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(67), 12, GFLAGS),
+    [HCLK_SPDIF_TX5] = GATE(HCLK_SPDIF_TX5, "hclk_spdif_tx5", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(67), 13, GFLAGS),
+    [MCLK_SPDIF_TX3] = COMPOSITE(MCLK_SPDIF_TX3, "mclk_spdif_tx3", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(160), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(67), 14, GFLAGS),
+    [CLK_AUX16MHZ_0] = COMPOSITE_NOMUX(CLK_AUX16MHZ_0, "clk_aux16mhz_0", "gpll", 0,
+            RK3576_CLKSEL_CON(161), 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(67), 15, GFLAGS),
+    [ACLK_DP0] = GATE(ACLK_DP0, "aclk_dp0", "aclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(68), 0, GFLAGS),
+    [PCLK_DP0] = GATE(PCLK_DP0, "pclk_dp0", "pclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(68), 1, GFLAGS),
+    [ACLK_HDCP1] = GATE(ACLK_HDCP1, "aclk_hdcp1", "aclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(68), 4, GFLAGS),
+    [HCLK_HDCP1] = GATE(HCLK_HDCP1, "hclk_hdcp1", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(68), 5, GFLAGS),
+    [PCLK_HDCP1] = GATE(PCLK_HDCP1, "pclk_hdcp1", "pclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(68), 6, GFLAGS),
+    [CLK_TRNG1_SKP] = GATE(CLK_TRNG1_SKP, "clk_trng1_skp", "aclk_hdcp1", 0,
+            RK3576_CLKGATE_CON(68), 7, GFLAGS),
+    [HCLK_SAI9_8CH] = GATE(HCLK_SAI9_8CH, "hclk_sai9_8ch", "hclk_vo1_root", 0,
+            RK3576_CLKGATE_CON(68), 9, GFLAGS),
+    [MCLK_SAI9_8CH_SRC] = COMPOSITE(MCLK_SAI9_8CH_SRC, "mclk_sai9_8ch_src", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(162), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(68), 10, GFLAGS),
+    [MCLK_SAI9_8CH] = COMPOSITE_NODIV(MCLK_SAI9_8CH, "mclk_sai9_8ch", mclk_sai9_8ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_CLKSEL_CON(162), 11, 1, MFLAGS,
+            RK3576_CLKGATE_CON(68), 11, GFLAGS),
+    [MCLK_SPDIF_TX4] = COMPOSITE(MCLK_SPDIF_TX4, "mclk_spdif_tx4", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(163), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(68), 12, GFLAGS),
+    [MCLK_SPDIF_TX5] = COMPOSITE(MCLK_SPDIF_TX5, "mclk_spdif_tx5", audio_frac_int_p, 0,
+            RK3576_CLKSEL_CON(164), 8, 3, MFLAGS, 0, 8, DFLAGS,
+            RK3576_CLKGATE_CON(68), 13, GFLAGS),
+    [CLK_GPU_SRC_PRE] = COMPOSITE(CLK_GPU_SRC_PRE, "clk_gpu_src_pre", gpll_cpll_aupll_spll_lpll_p, 0,
+            RK3576_CLKSEL_CON(165), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(69), 1, GFLAGS),
+    [CLK_GPU] = GATE(CLK_GPU, "clk_gpu", "clk_gpu_src_pre", 0,
+            RK3576_CLKGATE_CON(69), 3, GFLAGS),
+    [PCLK_GPU_ROOT] = COMPOSITE_NODIV(PCLK_GPU_ROOT, "pclk_gpu_root", mux_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(166), 10, 2, MFLAGS,
+            RK3576_CLKGATE_CON(69), 8, GFLAGS),
+    [ACLK_CENTER_ROOT] = COMPOSITE_DIV_OFFSET(ACLK_CENTER_ROOT, "aclk_center_root", gpll_cpll_spll_aupll_bpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(168), 5, 3, MFLAGS,
+            RK3576_CLKSEL_CON(167), 9, 5, DFLAGS,
+            RK3576_CLKGATE_CON(72), 0, GFLAGS),
+    [ACLK_CENTER_LOW_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", mux_500m_250m_100m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(168), 8, 2, MFLAGS,
+            RK3576_CLKGATE_CON(72), 1, GFLAGS),
+    [HCLK_CENTER_ROOT] = COMPOSITE_NODIV(HCLK_CENTER_ROOT, "hclk_center_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(168), 10, 2, MFLAGS,
+            RK3576_CLKGATE_CON(72), 2, GFLAGS),
+    [PCLK_CENTER_ROOT] = COMPOSITE_NODIV(PCLK_CENTER_ROOT, "pclk_center_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(168), 12, 2, MFLAGS,
+            RK3576_CLKGATE_CON(72), 3, GFLAGS),
+    [ACLK_DMA2DDR] = GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_center_root", RT_CLK_F_IGNORE_UNUSED,
+            RK3576_CLKGATE_CON(72), 5, GFLAGS),
+    [ACLK_DDR_SHAREMEM] = GATE(ACLK_DDR_SHAREMEM, "aclk_ddr_sharemem", "aclk_center_low_root", RT_CLK_F_IGNORE_UNUSED,
+            RK3576_CLKGATE_CON(72), 6, GFLAGS),
+    [PCLK_DMA2DDR] = GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_center_root", RT_CLK_F_IGNORE_UNUSED,
+            RK3576_CLKGATE_CON(72), 10, GFLAGS),
+    [PCLK_SHAREMEM] = GATE(PCLK_SHAREMEM, "pclk_sharemem", "pclk_center_root", RT_CLK_F_IGNORE_UNUSED,
+            RK3576_CLKGATE_CON(72), 11, GFLAGS),
+    [HCLK_VEPU1_ROOT] = COMPOSITE_NODIV(HCLK_VEPU1_ROOT, "hclk_vepu1_root", mux_200m_100m_50m_24m_p, 0,
+            RK3576_CLKSEL_CON(178), 0, 2, MFLAGS,
+            RK3576_CLKGATE_CON(78), 0, GFLAGS),
+    [ACLK_VEPU1_ROOT] = COMPOSITE(ACLK_VEPU1_ROOT, "aclk_vepu1_root", gpll_cpll_p, 0,
+            RK3576_CLKSEL_CON(180), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(79), 0, GFLAGS),
+    [HCLK_VEPU1] = GATE(HCLK_VEPU1, "hclk_vepu1", "hclk_vepu1_root", 0,
+            RK3576_CLKGATE_CON(79), 3, GFLAGS),
+    [ACLK_VEPU1] = GATE(ACLK_VEPU1, "aclk_vepu1", "aclk_vepu1_root", 0,
+            RK3576_CLKGATE_CON(79), 4, GFLAGS),
+    [CLK_VEPU1_CORE] = COMPOSITE(CLK_VEPU1_CORE, "clk_vepu1_core", gpll_cpll_spll_lpll_bpll_p, 0,
+            RK3576_CLKSEL_CON(180), 11, 3, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(79), 5, GFLAGS),
+    [PCLK_MIPI_DCPHY] = GATE(PCLK_MIPI_DCPHY, "pclk_mipi_dcphy", "pclk_pmuphy_root", 0,
+            RK3576_PMU_CLKGATE_CON(0), 2, GFLAGS),
+    [PCLK_CSIDPHY] = GATE(PCLK_CSIDPHY, "pclk_csidphy", "pclk_pmuphy_root", 0,
+            RK3576_PMU_CLKGATE_CON(0), 8, GFLAGS),
+    [PCLK_USBDPPHY] = GATE(PCLK_USBDPPHY, "pclk_usbdpphy", "pclk_pmuphy_root", 0,
+            RK3576_PMU_CLKGATE_CON(0), 12, GFLAGS),
+    [CLK_PMUPHY_REF_SRC] = COMPOSITE_NOMUX(CLK_PMUPHY_REF_SRC, "clk_pmuphy_ref_src", "cpll", 0,
+            RK3576_PMU_CLKSEL_CON(0), 0, 5, DFLAGS,
+            RK3576_PMU_CLKGATE_CON(0), 13, GFLAGS),
+    [CLK_USBDP_COMBO_PHY_IMMORTAL] = GATE(CLK_USBDP_COMBO_PHY_IMMORTAL, "clk_usbdp_combo_phy_immortal", "xin24m", 0,
+            RK3576_PMU_CLKGATE_CON(0), 15, GFLAGS),
+    [CLK_HDMITXHPD] = GATE(CLK_HDMITXHPD, "clk_hdmitxhpd", "xin24m", 0,
+            RK3576_PMU_CLKGATE_CON(1), 13, GFLAGS),
+    [PCLK_MPHY] = GATE(PCLK_MPHY, "pclk_mphy", "pclk_pmuphy_root", 0,
+            RK3576_PMU_CLKGATE_CON(2), 0, GFLAGS),
+    [CLK_REF_OSC_MPHY] = MUX(CLK_REF_OSC_MPHY, "clk_ref_osc_mphy", clk_ref_osc_mphy_p, 0,
+            RK3576_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
+    [CLK_REF_UFS_CLKOUT] = GATE(CLK_REF_UFS_CLKOUT, "clk_ref_ufs_clkout", "clk_ref_osc_mphy", 0,
+            RK3576_PMU_CLKGATE_CON(2), 5, GFLAGS),
+    [HCLK_PMU1_ROOT] = COMPOSITE_NODIV(HCLK_PMU1_ROOT, "hclk_pmu1_root", mux_pmu200m_pmu100m_pmu50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKSEL_CON(4), 0, 2, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(3), 0, GFLAGS),
+    [HCLK_PMU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_PMU_CM0_ROOT, "hclk_pmu_cm0_root", mux_pmu200m_pmu100m_pmu50m_24m_p, 0,
+            RK3576_PMU_CLKSEL_CON(4), 2, 2, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(3), 1, GFLAGS),
+    [CLK_200M_PMU_SRC] = GATE(CLK_200M_PMU_SRC, "clk_200m_pmu_src", "clk_gpll_div6", 0,
+            RK3576_PMU_CLKGATE_CON(3), 2, GFLAGS),
+    [CLK_100M_PMU_SRC] = COMPOSITE_NOMUX(CLK_100M_PMU_SRC, "clk_100m_pmu_src", "cpll", 0,
+            RK3576_PMU_CLKSEL_CON(4), 4, 5, DFLAGS,
+            RK3576_PMU_CLKGATE_CON(3), 3, GFLAGS),
+    [CLK_50M_PMU_SRC] = FACTOR_GATE(CLK_50M_PMU_SRC, "clk_50m_pmu_src", "clk_100m_pmu_src", 0, 1, 2,
+            RK3576_PMU_CLKGATE_CON(3), 4, GFLAGS),
+    [FCLK_PMU_CM0_CORE] = GATE(FCLK_PMU_CM0_CORE, "fclk_pmu_cm0_core", "hclk_pmu_cm0_root", 0,
+            RK3576_PMU_CLKGATE_CON(3), 12, GFLAGS),
+    [CLK_PMU_CM0_RTC] = COMPOSITE(CLK_PMU_CM0_RTC, "clk_pmu_cm0_rtc", mux_24m_32k_p, 0,
+            RK3576_PMU_CLKSEL_CON(4), 14, 1, MFLAGS, 9, 5, DFLAGS,
+            RK3576_PMU_CLKGATE_CON(3), 14, GFLAGS),
+    [PCLK_PMU1] = GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu1_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKGATE_CON(3), 15, GFLAGS),
+    [CLK_PMU1] = GATE(CLK_PMU1, "clk_pmu1", "xin24m", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKGATE_CON(4), 2, GFLAGS),
+    [PCLK_PMU1WDT] = GATE(PCLK_PMU1WDT, "pclk_pmu1wdt", "pclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(4), 5, GFLAGS),
+    [TCLK_PMU1WDT] = COMPOSITE_NODIV(TCLK_PMU1WDT, "tclk_pmu1wdt", mux_24m_32k_p, 0,
+            RK3576_PMU_CLKSEL_CON(4), 15, 1, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(4), 6, GFLAGS),
+    [PCLK_PMUTIMER] = GATE(PCLK_PMUTIMER, "pclk_pmutimer", "pclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(4), 7, GFLAGS),
+    [CLK_PMUTIMER_ROOT] = COMPOSITE_NODIV(CLK_PMUTIMER_ROOT, "clk_pmutimer_root", mux_pmu100m_24m_32k_p, 0,
+            RK3576_PMU_CLKSEL_CON(5), 0, 2, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(4), 8, GFLAGS),
+    [CLK_PMUTIMER0] = GATE(CLK_PMUTIMER0, "clk_pmutimer0", "clk_pmutimer_root", 0,
+            RK3576_PMU_CLKGATE_CON(4), 9, GFLAGS),
+    [CLK_PMUTIMER1] = GATE(CLK_PMUTIMER1, "clk_pmutimer1", "clk_pmutimer_root", 0,
+            RK3576_PMU_CLKGATE_CON(4), 10, GFLAGS),
+    [PCLK_PMU1PWM] = GATE(PCLK_PMU1PWM, "pclk_pmu1pwm", "pclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(4), 11, GFLAGS),
+    [CLK_PMU1PWM] = COMPOSITE_NODIV(CLK_PMU1PWM, "clk_pmu1pwm", mux_pmu100m_pmu50m_24m_p, 0,
+            RK3576_PMU_CLKSEL_CON(5), 2, 2, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(4), 12, GFLAGS),
+    [CLK_PMU1PWM_OSC] = GATE(CLK_PMU1PWM_OSC, "clk_pmu1pwm_osc", "xin24m", 0,
+            RK3576_PMU_CLKGATE_CON(4), 13, GFLAGS),
+    [PCLK_PMUPHY_ROOT] = GATE(PCLK_PMUPHY_ROOT, "pclk_pmuphy_root", "pclk_pmu1_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKGATE_CON(5), 0, GFLAGS),
+    [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(5), 1, GFLAGS),
+    [CLK_I2C0] = COMPOSITE_NODIV(CLK_I2C0, "clk_i2c0", mux_pmu200m_pmu100m_pmu50m_24m_p, 0,
+            RK3576_PMU_CLKSEL_CON(6), 7, 2, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(5), 2, GFLAGS),
+    [SCLK_UART1] = COMPOSITE_NODIV(SCLK_UART1, "sclk_uart1", uart1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3576_PMU_CLKSEL_CON(8), 0, 1, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(5), 5, GFLAGS),
+    [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(5), 6, GFLAGS),
+    [CLK_PMU1PWM_RC] = GATE(CLK_PMU1PWM_RC, "clk_pmu1pwm_rc", "clk_pvtm_clkout", 0,
+            RK3576_PMU_CLKGATE_CON(5), 7, GFLAGS),
+    [CLK_PDM0] = GATE(CLK_PDM0, "clk_pdm0", "clk_pdm0_src_top", 0,
+            RK3576_PMU_CLKGATE_CON(5), 13, GFLAGS),
+    [HCLK_PDM0] = GATE(HCLK_PDM0, "hclk_pdm0", "hclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(5), 15, GFLAGS),
+    [MCLK_PDM0] = GATE(MCLK_PDM0, "mclk_pdm0", "mclk_pdm0_src_top", 0,
+            RK3576_PMU_CLKGATE_CON(6), 0, GFLAGS),
+    [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_pmu1_root", 0,
+            RK3576_PMU_CLKGATE_CON(6), 1, GFLAGS),
+    [CLK_PDM0_OUT] = GATE(CLK_PDM0_OUT, "clk_pdm0_out", "clk_pdm0", 0,
+            RK3576_PMU_CLKGATE_CON(6), 8, GFLAGS),
+    [CLK_HPTIMER_SRC] = COMPOSITE(CLK_HPTIMER_SRC, "clk_hptimer_src", cpll_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKSEL_CON(11), 6, 1, MFLAGS, 1, 5, DFLAGS,
+            RK3576_PMU_CLKGATE_CON(6), 10, GFLAGS),
+    [PCLK_PMU0_ROOT] = COMPOSITE_NODIV(PCLK_PMU0_ROOT, "pclk_pmu0_root", mux_pmu100m_pmu50m_24m_p, 0,
+            RK3576_PMU_CLKSEL_CON(20), 0, 2, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(7), 0, GFLAGS),
+    [PCLK_PMU0] = GATE(PCLK_PMU0, "pclk_pmu0", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKGATE_CON(7), 3, GFLAGS),
+    [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu0_root", 0,
+            RK3576_PMU_CLKGATE_CON(7), 6, GFLAGS),
+    [DBCLK_GPIO0] = COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", mux_24m_32k_p, 0,
+            RK3576_PMU_CLKSEL_CON(20), 2, 1, MFLAGS,
+            RK3576_PMU_CLKGATE_CON(7), 7, GFLAGS),
+    [CLK_OSC0_PMU1] = GATE(CLK_OSC0_PMU1, "clk_osc0_pmu1", "xin24m", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKGATE_CON(7), 8, GFLAGS),
+    [PCLK_PMU1_ROOT] = GATE(PCLK_PMU1_ROOT, "pclk_pmu1_root", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKGATE_CON(7), 9, GFLAGS),
+    [XIN_OSC0_DIV] = COMPOSITE_FRAC(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", RT_CLK_F_IS_CRITICAL,
+            RK3576_PMU_CLKSEL_CON(21), 0,
+            RK3576_PMU_CLKGATE_CON(7), 11, GFLAGS),
+    [PCLK_CCI_ROOT] = COMPOSITE(PCLK_CCI_ROOT, "pclk_cci_root", mux_24m_ccipvtpll_gpll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CCI_CLKSEL_CON(4), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CCI_CLKGATE_CON(1), 10, GFLAGS),
+    [ACLK_CCI_ROOT] = COMPOSITE(ACLK_CCI_ROOT, "aclk_cci_root", mux_24m_ccipvtpll_gpll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CCI_CLKSEL_CON(4), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3576_CCI_CLKGATE_CON(1), 11, GFLAGS),
+    [HCLK_VO0VOP_CHANNEL] = COMPOSITE_NODIV(HCLK_VO0VOP_CHANNEL, "hclk_vo0vop_channel", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(19), 6, 2, MFLAGS,
+            RK3576_CLKGATE_CON(2), 0, GFLAGS),
+    [ACLK_VO0VOP_CHANNEL] = COMPOSITE(ACLK_VO0VOP_CHANNEL, "aclk_vo0vop_channel", gpll_cpll_lpll_bpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(19), 12, 2, MFLAGS, 8, 4, DFLAGS,
+            RK3576_CLKGATE_CON(2), 1, GFLAGS),
+    [ACLK_TOP_MID] = COMPOSITE(ACLK_TOP_MID, "aclk_top_mid", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(10), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3576_CLKGATE_CON(1), 6, GFLAGS),
+    [ACLK_SECURE_HIGH] = COMPOSITE(ACLK_SECURE_HIGH, "aclk_secure_high", gpll_spll_aupll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_CLKSEL_CON(10), 11, 3, MFLAGS, 6, 5, DFLAGS,
+            RK3576_CLKGATE_CON(1), 7, GFLAGS),
+    [CLK_USBPHY_REF_SRC] = MUXGRF(CLK_USBPHY_REF_SRC, "clk_usbphy_ref_src", clk_usbphy_ref_src_p, 0,
+            RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS),
+    [CLK_PHY_REF_SRC] = MUXGRF(CLK_PHY_REF_SRC, "clk_phy_ref_src", clk_phy_ref_src_p, 0,
+            RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS),
+    [CLK_CPLL_REF_SRC] = MUXGRF(CLK_CPLL_REF_SRC, "clk_cpll_ref_src", clk_cpll_ref_src_p, 0,
+            RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS),
+    [CLK_AUPLL_REF_SRC] = MUXGRF(CLK_AUPLL_REF_SRC, "clk_aupll_ref_src", clk_aupll_ref_src_p, 0,
+            RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS),
+    [PCLK_SECURE_NS] = COMPOSITE_NODIV(PCLK_SECURE_NS, "pclk_secure_ns", mux_116m_58m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_SECURE_NS_CLKSEL_CON(0), 4, 2, MFLAGS,
+            RK3576_SECURE_NS_CLKGATE_CON(0), 2, GFLAGS),
+    [HCLK_SECURE_NS] = COMPOSITE_NODIV(HCLK_SECURE_NS, "hclk_secure_ns", mux_175m_116m_58m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_SECURE_NS_CLKSEL_CON(0), 2, 2, MFLAGS,
+            RK3576_SECURE_NS_CLKGATE_CON(0), 1, GFLAGS),
+    [ACLK_SECURE_NS] = COMPOSITE_NODIV(ACLK_SECURE_NS, "aclk_secure_ns", mux_350m_175m_116m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3576_SECURE_NS_CLKSEL_CON(0), 0, 2, MFLAGS,
+            RK3576_SECURE_NS_CLKGATE_CON(0), 0, GFLAGS),
+    [PCLK_OTPC_NS] = GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_secure_ns", 0,
+            RK3576_SECURE_NS_CLKGATE_CON(0), 8, GFLAGS),
+    [HCLK_CRYPTO_NS] = GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_ns", 0,
+            RK3576_SECURE_NS_CLKGATE_CON(0), 3, GFLAGS),
+    [HCLK_TRNG_NS] = GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_s", 0,
+            RK3576_NON_SECURE_GATING_CON00, 13, GFLAGS),
+    [CLK_OTPC_NS] = GATE(CLK_OTPC_NS, "clk_otpc_ns", "xin24m", 0,
+            RK3576_SECURE_NS_CLKGATE_CON(0), 9, GFLAGS),
+    [ACLK_CRYPTO_NS] = GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_s", 0,
+            RK3576_NON_SECURE_GATING_CON00, 14, GFLAGS),
+    [CLK_PKA_CRYPTO_NS] = GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto_s", 0,
+            RK3576_NON_SECURE_GATING_CON00, 1, GFLAGS),
+    [ACLK_RKVDEC_ROOT_BAK] = COMPOSITE(ACLK_RKVDEC_ROOT_BAK, "aclk_rkvdec_root_bak", cpll_vpll_lpll_bpll_p, 0,
+            RK3576_CLKSEL_CON(110), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3576_CLKGATE_CON(45), 2, GFLAGS),
+    [CLK_AUDIO_FRAC_0_SRC] = MUX(CLK_AUDIO_FRAC_0_SRC, "clk_audio_frac_0_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(13), 0, 2, MFLAGS),
+    [CLK_AUDIO_FRAC_1_SRC] = MUX(CLK_AUDIO_FRAC_1_SRC, "clk_audio_frac_1_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(15), 0, 2, MFLAGS),
+    [CLK_AUDIO_FRAC_2_SRC] = MUX(CLK_AUDIO_FRAC_2_SRC, "clk_audio_frac_2_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(17), 0, 2, MFLAGS),
+    [CLK_AUDIO_FRAC_3_SRC] = MUX(CLK_AUDIO_FRAC_3_SRC, "clk_audio_frac_3_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(19), 0, 2, MFLAGS),
+    [PCLK_HDPTX_APB] = GATE(PCLK_HDPTX_APB, "pclk_hdptx_apb", "pclk_pmuphy_root", 0,
+            RK3576_PMU_CLKGATE_CON(0), 1, GFLAGS),
+    [PCLK_DDR_MON_CH1] = GATE(PCLK_DDR_MON_CH1, "pclk_ddr_mon_ch1", "pclk_ddr_root", 0,
+            RK3576_CLKGATE_CON(21), 14, GFLAGS),
+
+    FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+    FACTOR(0, "clk_spll_div12", "spll", 0, 1, 12),
+    FACTOR(0, "clk_spll_div6", "spll", 0, 1, 6),
+    FACTOR(0, "clk_spll_div4", "spll", 0, 1, 4),
+    FACTOR(0, "lpll_div2", "lpll", 0, 1, 2),
+    FACTOR(0, "bpll_div4", "bpll", 0, 1, 4),
+    MUX(0, "clk_uart_frac_0_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(22), 0, 2, MFLAGS),
+    MUX(0, "clk_uart_frac_1_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(24), 0, 2, MFLAGS),
+    MUX(0, "clk_uart_frac_2_src", gpll_cpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(26), 0, 2, MFLAGS),
+    MUX(0, "dclk_ebc_frac_src_p", gpll_cpll_vpll_aupll_24m_p, 0,
+            RK3576_CLKSEL_CON(123), 0, 3, MFLAGS),
+};
+
+static rt_err_t clk_rk3576_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_device *dev = &pdev->parent;
+    struct clk_rk3576_cru *cru = rt_calloc(1, sizeof(*cru));
+
+    if (!cru)
+    {
+        return -RT_ENOMEM;
+    }
+
+    cru->provider.reg_base = rt_dm_dev_iomap(dev, 0);
+
+    if (!cru->provider.reg_base)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf");
+    cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf");
+
+    cru->clk_parent.dev = dev;
+    cru->clk_parent.cells = rk3576_clk_cells;
+    cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3576_clk_cells);
+
+    rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rt_clk_register(&cru->clk_parent)))
+    {
+        goto _fail;
+    }
+
+    rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL,
+        cru->provider.reg_base + RK3576_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK)))
+    {
+        goto _clk_unregister;
+    }
+
+    rockchip_register_restart_notifier(&cru->provider, RK3576_GLB_SRST_FST, RT_NULL);
+
+    return RT_EOK;
+
+_clk_unregister:
+    rt_clk_unregister(&cru->clk_parent);
+
+_fail:
+    if (cru->provider.reg_base)
+    {
+        rt_iounmap(cru->provider.reg_base);
+    }
+
+    rt_free(cru);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id clk_rk3576_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3576-cru", },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver clk_rk3576_driver =
+{
+    .name = "clk-rk3576",
+    .ids = clk_rk3576_ofw_ids,
+
+    .probe = clk_rk3576_probe,
+};
+
+static int clk_rk3576_register(void)
+{
+    rt_platform_driver_register(&clk_rk3576_driver);
+
+    return 0;
+}
+INIT_SUBSYS_EXPORT(clk_rk3576_register);

+ 2166 - 0
bsp/rockchip/dm/clk/clk-rk3588.c

@@ -0,0 +1,2166 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include "clk-rk-composite.h"
+#include "clk-rk-cpu.h"
+#include "clk-rk-divider.h"
+#include "clk-rk-factor.h"
+#include "clk-rk-fraction-divider.h"
+#include "clk-rk-gate.h"
+#include "clk-rk.h"
+#include "clk-rk-half-divider.h"
+#include "clk-rk-mmc-phase.h"
+#include "clk-rk-muxgrf.h"
+#include "clk-rk-mux.h"
+#include "clk-rk-pll.h"
+
+#define DBG_TAG "clk.rk3588"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <dt-bindings/clock/rk3588-cru.h>
+
+#define RK3588_GRF_SOC_STATUS0                  0x600
+#define RK3588_PHYREF_ALT_GATE                  0xc38
+#define RK3588_FRAC_MAX_PRATE                   1500000000
+#define RK3588_DCLK_MAX_PRATE                   594000000
+
+#define RK3588_PHP_CRU_BASE                     0x8000
+#define RK3588_PMU_CRU_BASE                     0x30000
+#define RK3588_BIGCORE0_CRU_BASE                0x50000
+#define RK3588_BIGCORE1_CRU_BASE                0x52000
+#define RK3588_DSU_CRU_BASE                     0x58000
+
+#define RK3588_PLL_CON(x)                       ((x) * 0x4)
+#define RK3588_MODE_CON0                        0x280
+#define RK3588_B0_PLL_MODE_CON0                 (RK3588_BIGCORE0_CRU_BASE + 0x280)
+#define RK3588_B1_PLL_MODE_CON0                 (RK3588_BIGCORE1_CRU_BASE + 0x280)
+#define RK3588_LPLL_MODE_CON0                   (RK3588_DSU_CRU_BASE + 0x280)
+#define RK3588_CLKSEL_CON(x)                    ((x) * 0x4 + 0x300)
+#define RK3588_CLKGATE_CON(x)                   ((x) * 0x4 + 0x800)
+#define RK3588_SOFTRST_CON(x)                   ((x) * 0x4 + 0xa00)
+#define RK3588_GLB_CNT_TH                       0xc00
+#define RK3588_GLB_SRST_FST                     0xc08
+#define RK3588_GLB_SRST_SND                     0xc0c
+#define RK3588_GLB_RST_CON                      0xc10
+#define RK3588_GLB_RST_ST                       0xc04
+#define RK3588_SDIO_CON0                        0xc24
+#define RK3588_SDIO_CON1                        0xc28
+#define RK3588_SDMMC_CON0                       0xc30
+#define RK3588_SDMMC_CON1                       0xc34
+
+#define RK3588_PHP_CLKGATE_CON(x)               ((x) * 0x4 + RK3588_PHP_CRU_BASE + 0x800)
+#define RK3588_PHP_SOFTRST_CON(x)               ((x) * 0x4 + RK3588_PHP_CRU_BASE + 0xa00)
+
+#define RK3588_PMU_PLL_CON(x)                   ((x) * 0x4 + RK3588_PHP_CRU_BASE)
+#define RK3588_PMU_CLKSEL_CON(x)                ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x300)
+#define RK3588_PMU_CLKGATE_CON(x)               ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x800)
+#define RK3588_PMU_SOFTRST_CON(x)               ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0xa00)
+
+#define RK3588_B0_PLL_CON(x)                    ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE)
+#define RK3588_BIGCORE0_CLKSEL_CON(x)           ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x300)
+#define RK3588_BIGCORE0_CLKGATE_CON(x)          ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x800)
+#define RK3588_BIGCORE0_SOFTRST_CON(x)          ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0xa00)
+#define RK3588_B1_PLL_CON(x)                    ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE)
+#define RK3588_BIGCORE1_CLKSEL_CON(x)           ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x300)
+#define RK3588_BIGCORE1_CLKGATE_CON(x)          ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x800)
+#define RK3588_BIGCORE1_SOFTRST_CON(x)          ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0xa00)
+#define RK3588_LPLL_CON(x)                      ((x) * 0x4 + RK3588_DSU_CRU_BASE)
+#define RK3588_DSU_CLKSEL_CON(x)                ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x300)
+#define RK3588_DSU_CLKGATE_CON(x)               ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x800)
+#define RK3588_DSU_SOFTRST_CON(x)               ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0xa00)
+
+#define RK3588_CLK_CORE_B0_SEL_CLEAN_MASK       0x3
+#define RK3588_CLK_CORE_B0_SEL_CLEAN_SHIFT      13
+#define RK3588_CLK_CORE_B1_SEL_CLEAN_MASK       0x3
+#define RK3588_CLK_CORE_B1_SEL_CLEAN_SHIFT      5
+#define RK3588_CLK_CORE_B0_GPLL_DIV_MASK        0x1f
+#define RK3588_CLK_CORE_B0_GPLL_DIV_SHIFT       1
+#define RK3588_CLK_CORE_L_SEL_CLEAN_MASK        0x3
+#define RK3588_CLK_CORE_L1_SEL_CLEAN_SHIFT      12
+#define RK3588_CLK_CORE_L0_SEL_CLEAN_SHIFT      5
+#define RK3588_CLK_DSU_SEL_DF_MASK              0x1
+#define RK3588_CLK_DSU_SEL_DF_SHIFT             15
+#define RK3588_CLK_DSU_DF_SRC_MASK              0x3
+#define RK3588_CLK_DSU_DF_SRC_SHIFT             12
+#define RK3588_CLK_DSU_DF_DIV_MASK              0x1f
+#define RK3588_CLK_DSU_DF_DIV_SHIFT             7
+#define RK3588_ACLKM_DSU_DIV_MASK               0x1f
+#define RK3588_ACLKM_DSU_DIV_SHIFT              1
+#define RK3588_ACLKS_DSU_DIV_MASK               0x1f
+#define RK3588_ACLKS_DSU_DIV_SHIFT              6
+#define RK3588_ACLKMP_DSU_DIV_MASK              0x1f
+#define RK3588_ACLKMP_DSU_DIV_SHIFT             11
+#define RK3588_PERIPH_DSU_DIV_MASK              0x1f
+#define RK3588_PERIPH_DSU_DIV_SHIFT             0
+#define RK3588_ATCLK_DSU_DIV_MASK               0x1f
+#define RK3588_ATCLK_DSU_DIV_SHIFT              0
+#define RK3588_GICCLK_DSU_DIV_MASK              0x1f
+#define RK3588_GICCLK_DSU_DIV_SHIFT             5
+
+struct clk_rk3588_cru
+{
+    struct rt_clk_node clk_parent;
+    struct rt_reset_controller rstc_parent;
+
+    struct rockchip_clk_provider provider;
+};
+
+static struct rockchip_pll_rate_table rk3588_pll_rates[] =
+{
+    /* _mhz, _p, _m, _s, _k */
+    RK3588_PLL_RATE(2520000000, 2, 210, 0, 0),
+    RK3588_PLL_RATE(2496000000, 2, 208, 0, 0),
+    RK3588_PLL_RATE(2472000000, 2, 206, 0, 0),
+    RK3588_PLL_RATE(2448000000, 2, 204, 0, 0),
+    RK3588_PLL_RATE(2424000000, 2, 202, 0, 0),
+    RK3588_PLL_RATE(2400000000, 2, 200, 0, 0),
+    RK3588_PLL_RATE(2376000000, 2, 198, 0, 0),
+    RK3588_PLL_RATE(2352000000, 2, 196, 0, 0),
+    RK3588_PLL_RATE(2328000000, 2, 194, 0, 0),
+    RK3588_PLL_RATE(2304000000, 2, 192, 0, 0),
+    RK3588_PLL_RATE(2280000000, 2, 190, 0, 0),
+    RK3588_PLL_RATE(2256000000, 2, 376, 1, 0),
+    RK3588_PLL_RATE(2232000000, 2, 372, 1, 0),
+    RK3588_PLL_RATE(2208000000, 2, 368, 1, 0),
+    RK3588_PLL_RATE(2184000000, 2, 364, 1, 0),
+    RK3588_PLL_RATE(2160000000, 2, 360, 1, 0),
+    RK3588_PLL_RATE(2136000000, 2, 356, 1, 0),
+    RK3588_PLL_RATE(2112000000, 2, 352, 1, 0),
+    RK3588_PLL_RATE(2088000000, 2, 348, 1, 0),
+    RK3588_PLL_RATE(2064000000, 2, 344, 1, 0),
+    RK3588_PLL_RATE(2040000000, 2, 340, 1, 0),
+    RK3588_PLL_RATE(2016000000, 2, 336, 1, 0),
+    RK3588_PLL_RATE(1992000000, 2, 332, 1, 0),
+    RK3588_PLL_RATE(1968000000, 2, 328, 1, 0),
+    RK3588_PLL_RATE(1944000000, 2, 324, 1, 0),
+    RK3588_PLL_RATE(1920000000, 2, 320, 1, 0),
+    RK3588_PLL_RATE(1896000000, 2, 316, 1, 0),
+    RK3588_PLL_RATE(1872000000, 2, 312, 1, 0),
+    RK3588_PLL_RATE(1848000000, 2, 308, 1, 0),
+    RK3588_PLL_RATE(1824000000, 2, 304, 1, 0),
+    RK3588_PLL_RATE(1800000000, 2, 300, 1, 0),
+    RK3588_PLL_RATE(1776000000, 2, 296, 1, 0),
+    RK3588_PLL_RATE(1752000000, 2, 292, 1, 0),
+    RK3588_PLL_RATE(1728000000, 2, 288, 1, 0),
+    RK3588_PLL_RATE(1704000000, 2, 284, 1, 0),
+    RK3588_PLL_RATE(1680000000, 2, 280, 1, 0),
+    RK3588_PLL_RATE(1656000000, 2, 276, 1, 0),
+    RK3588_PLL_RATE(1632000000, 2, 272, 1, 0),
+    RK3588_PLL_RATE(1608000000, 2, 268, 1, 0),
+    RK3588_PLL_RATE(1584000000, 2, 264, 1, 0),
+    RK3588_PLL_RATE(1560000000, 2, 260, 1, 0),
+    RK3588_PLL_RATE(1536000000, 2, 256, 1, 0),
+    RK3588_PLL_RATE(1512000000, 2, 252, 1, 0),
+    RK3588_PLL_RATE(1488000000, 2, 248, 1, 0),
+    RK3588_PLL_RATE(1464000000, 2, 244, 1, 0),
+    RK3588_PLL_RATE(1440000000, 2, 240, 1, 0),
+    RK3588_PLL_RATE(1416000000, 2, 236, 1, 0),
+    RK3588_PLL_RATE(1392000000, 2, 232, 1, 0),
+    RK3588_PLL_RATE(1320000000, 2, 220, 1, 0),
+    RK3588_PLL_RATE(1200000000, 2, 200, 1, 0),
+    RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
+    RK3588_PLL_RATE(1186814000, 2, 198, 1, 52581),
+    RK3588_PLL_RATE(1186812000, 2, 198, 1, 52559),
+    RK3588_PLL_RATE(1109000000, 3, 554, 2, 32767),
+    RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
+    RK3588_PLL_RATE(1051000000, 3, 525, 2, 32767),
+    RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
+    RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
+    RK3588_PLL_RATE(983040000, 4, 655, 2, 23592),
+    RK3588_PLL_RATE(955520000, 3, 478, 2, 49807),
+    RK3588_PLL_RATE(903168000, 6, 903, 2, 11009),
+    RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
+    RK3588_PLL_RATE(816000000, 2, 272, 2, 0),
+    RK3588_PLL_RATE(786432000, 2, 262, 2, 9437),
+    RK3588_PLL_RATE(786000000, 1, 131, 2, 0),
+    RK3588_PLL_RATE(785560000, 3, 393, 2, 51119),
+    RK3588_PLL_RATE(773000000, 2, 258, 2, 43690),
+    RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
+    RK3588_PLL_RATE(697000000, 2, 232, 2, 21845),
+    RK3588_PLL_RATE(604800000, 1, 101, 2, 52428),
+    RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
+    RK3588_PLL_RATE(594000000, 1, 99, 2, 0),
+    RK3588_PLL_RATE(408000000, 2, 272, 3, 0),
+    RK3588_PLL_RATE(312000000, 2, 208, 3, 0),
+    RK3588_PLL_RATE(266580000, 1, 178, 4, 47185),
+    RK3588_PLL_RATE(216000000, 2, 288, 4, 0),
+    RK3588_PLL_RATE(96000000, 2, 256, 5, 0),
+    { /* sentinel */ },
+};
+
+#define RK3588_CORE_B0_SEL(_apllcore)                                   \
+{                                                                       \
+    .reg = RK3588_BIGCORE0_CLKSEL_CON(0),                               \
+    .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B0_SEL_CLEAN_MASK,  \
+                    RK3588_CLK_CORE_B0_SEL_CLEAN_SHIFT) |               \
+            HIWORD_UPDATE(0, RK3588_CLK_CORE_B0_GPLL_DIV_MASK,          \
+                    RK3588_CLK_CORE_B0_GPLL_DIV_SHIFT),                 \
+}
+
+#define RK3588_CORE_B1_SEL(_apllcore)                                   \
+{                                                                       \
+    .reg = RK3588_BIGCORE0_CLKSEL_CON(1),                               \
+    .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B1_SEL_CLEAN_MASK,  \
+                    RK3588_CLK_CORE_B1_SEL_CLEAN_SHIFT),                \
+}
+
+#define RK3588_CORE_B2_SEL(_apllcore)                                   \
+{                                                                       \
+    .reg = RK3588_BIGCORE1_CLKSEL_CON(0),                               \
+    .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B0_SEL_CLEAN_MASK,  \
+                    RK3588_CLK_CORE_B0_SEL_CLEAN_SHIFT) |               \
+            HIWORD_UPDATE(0, RK3588_CLK_CORE_B0_GPLL_DIV_MASK,          \
+                    RK3588_CLK_CORE_B0_GPLL_DIV_SHIFT),                 \
+}
+
+#define RK3588_CORE_B3_SEL(_apllcore)                                   \
+{                                                                       \
+    .reg = RK3588_BIGCORE1_CLKSEL_CON(1),                               \
+    .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B1_SEL_CLEAN_MASK,  \
+                    RK3588_CLK_CORE_B1_SEL_CLEAN_SHIFT),                \
+}
+
+#define RK3588_CORE_L_SEL0(_offs, _apllcore)                            \
+{                                                                       \
+    .reg = RK3588_DSU_CLKSEL_CON(6 + _offs),                            \
+    .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_L_SEL_CLEAN_MASK,   \
+                    RK3588_CLK_CORE_L0_SEL_CLEAN_SHIFT) |               \
+            HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_L_SEL_CLEAN_MASK,  \
+                    RK3588_CLK_CORE_L1_SEL_CLEAN_SHIFT),                \
+}
+
+#define RK3588_CORE_L_SEL1(_seldsu, _divdsu)                        \
+{                                                                   \
+    .reg = RK3588_DSU_CLKSEL_CON(0),                                \
+    .val = HIWORD_UPDATE(_seldsu, RK3588_CLK_DSU_DF_SRC_MASK,       \
+                    RK3588_CLK_DSU_DF_SRC_SHIFT) |                  \
+            HIWORD_UPDATE(_divdsu - 1, RK3588_CLK_DSU_DF_DIV_MASK,  \
+                    RK3588_CLK_DSU_DF_DIV_SHIFT),                   \
+}
+
+#define RK3588_CORE_L_SEL2(_aclkm, _aclkmp, _aclks)                 \
+{                                                                   \
+    .reg = RK3588_DSU_CLKSEL_CON(1),                                \
+    .val = HIWORD_UPDATE(_aclkm - 1, RK3588_ACLKM_DSU_DIV_MASK,     \
+                    RK3588_ACLKM_DSU_DIV_SHIFT) |                   \
+            HIWORD_UPDATE(_aclkmp - 1, RK3588_ACLKMP_DSU_DIV_MASK,  \
+                    RK3588_ACLKMP_DSU_DIV_SHIFT) |                  \
+            HIWORD_UPDATE(_aclks - 1, RK3588_ACLKS_DSU_DIV_MASK,    \
+                    RK3588_ACLKS_DSU_DIV_SHIFT),                    \
+}
+
+#define RK3588_CORE_L_SEL3(_periph)                                 \
+{                                                                   \
+    .reg = RK3588_DSU_CLKSEL_CON(2),                                \
+    .val = HIWORD_UPDATE(_periph - 1, RK3588_PERIPH_DSU_DIV_MASK,   \
+                    RK3588_PERIPH_DSU_DIV_SHIFT),                   \
+}
+
+#define RK3588_CORE_L_SEL4(_gicclk, _atclk)                         \
+{                                                                   \
+    .reg = RK3588_DSU_CLKSEL_CON(3),                                \
+    .val = HIWORD_UPDATE(_gicclk - 1, RK3588_GICCLK_DSU_DIV_MASK,   \
+                    RK3588_GICCLK_DSU_DIV_SHIFT) |                  \
+            HIWORD_UPDATE(_atclk - 1, RK3588_ATCLK_DSU_DIV_MASK,    \
+                    RK3588_ATCLK_DSU_DIV_SHIFT),                    \
+}
+
+#define RK3588_CPUB01CLK_RATE(_prate, _apllcore) \
+{                                       \
+    .prate = _prate##U,                 \
+    .pre_muxs =                         \
+    {                                   \
+        RK3588_CORE_B0_SEL(0),          \
+        RK3588_CORE_B1_SEL(0),          \
+    },                                  \
+    .post_muxs =                        \
+    {                                   \
+        RK3588_CORE_B0_SEL(_apllcore),  \
+        RK3588_CORE_B1_SEL(_apllcore),  \
+    },                                  \
+}
+
+#define RK3588_CPUB23CLK_RATE(_prate, _apllcore) \
+{                                       \
+    .prate = _prate##U,                 \
+    .pre_muxs =                         \
+    {                                   \
+        RK3588_CORE_B2_SEL(0),          \
+        RK3588_CORE_B3_SEL(0),          \
+    },                                  \
+    .post_muxs =                        \
+    {                                   \
+        RK3588_CORE_B2_SEL(_apllcore),  \
+        RK3588_CORE_B3_SEL(_apllcore),  \
+    },                                  \
+    }
+
+#define RK3588_CPULCLK_RATE(_prate, _apllcore, _seldsu, _divdsu) \
+{                                               \
+    .prate = _prate##U,                         \
+    .pre_muxs =                                 \
+    {                                           \
+        RK3588_CORE_L_SEL0(0, 0),               \
+        RK3588_CORE_L_SEL0(1, 0),               \
+        RK3588_CORE_L_SEL1(3, 2),               \
+        RK3588_CORE_L_SEL2(2, 3, 3),            \
+        RK3588_CORE_L_SEL3(4),                  \
+        RK3588_CORE_L_SEL4(4, 4),               \
+    },                                          \
+    .post_muxs =                                \
+    {                                           \
+        RK3588_CORE_L_SEL0(0, _apllcore),       \
+        RK3588_CORE_L_SEL0(1, _apllcore),       \
+        RK3588_CORE_L_SEL1(_seldsu, _divdsu),   \
+    },                                          \
+}
+
+static struct rockchip_cpu_clk_rate_table rk3588_cpub0clk_rates[] =
+{
+    RK3588_CPUB01CLK_RATE(2496000000, 1),
+    RK3588_CPUB01CLK_RATE(2400000000, 1),
+    RK3588_CPUB01CLK_RATE(2304000000, 1),
+    RK3588_CPUB01CLK_RATE(2208000000, 1),
+    RK3588_CPUB01CLK_RATE(2184000000, 1),
+    RK3588_CPUB01CLK_RATE(2088000000, 1),
+    RK3588_CPUB01CLK_RATE(2040000000, 1),
+    RK3588_CPUB01CLK_RATE(2016000000, 1),
+    RK3588_CPUB01CLK_RATE(1992000000, 1),
+    RK3588_CPUB01CLK_RATE(1896000000, 1),
+    RK3588_CPUB01CLK_RATE(1800000000, 1),
+    RK3588_CPUB01CLK_RATE(1704000000, 0),
+    RK3588_CPUB01CLK_RATE(1608000000, 0),
+    RK3588_CPUB01CLK_RATE(1584000000, 0),
+    RK3588_CPUB01CLK_RATE(1560000000, 0),
+    RK3588_CPUB01CLK_RATE(1536000000, 0),
+    RK3588_CPUB01CLK_RATE(1512000000, 0),
+    RK3588_CPUB01CLK_RATE(1488000000, 0),
+    RK3588_CPUB01CLK_RATE(1464000000, 0),
+    RK3588_CPUB01CLK_RATE(1440000000, 0),
+    RK3588_CPUB01CLK_RATE(1416000000, 0),
+    RK3588_CPUB01CLK_RATE(1392000000, 0),
+    RK3588_CPUB01CLK_RATE(1368000000, 0),
+    RK3588_CPUB01CLK_RATE(1344000000, 0),
+    RK3588_CPUB01CLK_RATE(1320000000, 0),
+    RK3588_CPUB01CLK_RATE(1296000000, 0),
+    RK3588_CPUB01CLK_RATE(1272000000, 0),
+    RK3588_CPUB01CLK_RATE(1248000000, 0),
+    RK3588_CPUB01CLK_RATE(1224000000, 0),
+    RK3588_CPUB01CLK_RATE(1200000000, 0),
+    RK3588_CPUB01CLK_RATE(1104000000, 0),
+    RK3588_CPUB01CLK_RATE(1008000000, 0),
+    RK3588_CPUB01CLK_RATE(912000000, 0),
+    RK3588_CPUB01CLK_RATE(816000000, 0),
+    RK3588_CPUB01CLK_RATE(696000000, 0),
+    RK3588_CPUB01CLK_RATE(600000000, 0),
+    RK3588_CPUB01CLK_RATE(408000000, 0),
+    RK3588_CPUB01CLK_RATE(312000000, 0),
+    RK3588_CPUB01CLK_RATE(216000000, 0),
+    RK3588_CPUB01CLK_RATE(96000000, 0),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3588_cpub0clk_data =
+{
+    .core_reg[0] = RK3588_BIGCORE0_CLKSEL_CON(0),
+    .div_core_shift[0] = 8,
+    .div_core_mask[0] = 0x1f,
+    .core_reg[1] = RK3588_BIGCORE0_CLKSEL_CON(1),
+    .div_core_shift[1] = 0,
+    .div_core_mask[1] = 0x1f,
+    .num_cores = 2,
+    .mux_core_alt = 1,
+    .mux_core_main = 2,
+    .mux_core_shift = 6,
+    .mux_core_mask = 0x3,
+};
+
+static struct rockchip_cpu_clk_rate_table rk3588_cpub1clk_rates[] =
+{
+    RK3588_CPUB23CLK_RATE(2496000000, 1),
+    RK3588_CPUB23CLK_RATE(2400000000, 1),
+    RK3588_CPUB23CLK_RATE(2304000000, 1),
+    RK3588_CPUB23CLK_RATE(2208000000, 1),
+    RK3588_CPUB23CLK_RATE(2184000000, 1),
+    RK3588_CPUB23CLK_RATE(2088000000, 1),
+    RK3588_CPUB23CLK_RATE(2040000000, 1),
+    RK3588_CPUB23CLK_RATE(2016000000, 1),
+    RK3588_CPUB23CLK_RATE(1992000000, 1),
+    RK3588_CPUB23CLK_RATE(1896000000, 1),
+    RK3588_CPUB23CLK_RATE(1800000000, 1),
+    RK3588_CPUB23CLK_RATE(1704000000, 0),
+    RK3588_CPUB23CLK_RATE(1608000000, 0),
+    RK3588_CPUB23CLK_RATE(1584000000, 0),
+    RK3588_CPUB23CLK_RATE(1560000000, 0),
+    RK3588_CPUB23CLK_RATE(1536000000, 0),
+    RK3588_CPUB23CLK_RATE(1512000000, 0),
+    RK3588_CPUB23CLK_RATE(1488000000, 0),
+    RK3588_CPUB23CLK_RATE(1464000000, 0),
+    RK3588_CPUB23CLK_RATE(1440000000, 0),
+    RK3588_CPUB23CLK_RATE(1416000000, 0),
+    RK3588_CPUB23CLK_RATE(1392000000, 0),
+    RK3588_CPUB23CLK_RATE(1368000000, 0),
+    RK3588_CPUB23CLK_RATE(1344000000, 0),
+    RK3588_CPUB23CLK_RATE(1320000000, 0),
+    RK3588_CPUB23CLK_RATE(1296000000, 0),
+    RK3588_CPUB23CLK_RATE(1272000000, 0),
+    RK3588_CPUB23CLK_RATE(1248000000, 0),
+    RK3588_CPUB23CLK_RATE(1224000000, 0),
+    RK3588_CPUB23CLK_RATE(1200000000, 0),
+    RK3588_CPUB23CLK_RATE(1104000000, 0),
+    RK3588_CPUB23CLK_RATE(1008000000, 0),
+    RK3588_CPUB23CLK_RATE(912000000, 0),
+    RK3588_CPUB23CLK_RATE(816000000, 0),
+    RK3588_CPUB23CLK_RATE(696000000, 0),
+    RK3588_CPUB23CLK_RATE(600000000, 0),
+    RK3588_CPUB23CLK_RATE(408000000, 0),
+    RK3588_CPUB23CLK_RATE(312000000, 0),
+    RK3588_CPUB23CLK_RATE(216000000, 0),
+    RK3588_CPUB23CLK_RATE(96000000, 0),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3588_cpub1clk_data =
+{
+    .core_reg[0] = RK3588_BIGCORE1_CLKSEL_CON(0),
+    .div_core_shift[0] = 8,
+    .div_core_mask[0] = 0x1f,
+    .core_reg[1] = RK3588_BIGCORE1_CLKSEL_CON(1),
+    .div_core_shift[1] = 0,
+    .div_core_mask[1] = 0x1f,
+    .num_cores = 2,
+    .mux_core_alt = 1,
+    .mux_core_main = 2,
+    .mux_core_shift = 6,
+    .mux_core_mask = 0x3,
+};
+
+static struct rockchip_cpu_clk_rate_table rk3588_cpulclk_rates[] =
+{
+    RK3588_CPULCLK_RATE(2208000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(2184000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(2088000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(2040000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(2016000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(1992000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(1896000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(1800000000, 1, 3, 1),
+    RK3588_CPULCLK_RATE(1704000000, 0, 3, 1),
+    RK3588_CPULCLK_RATE(1608000000, 0, 3, 1),
+    RK3588_CPULCLK_RATE(1584000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1560000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1536000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1512000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1488000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1464000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1440000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1416000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1392000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1368000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1344000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1320000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1296000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1272000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1248000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1224000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1200000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1104000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(1008000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(912000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(816000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(696000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(600000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(408000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(312000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(216000000, 0, 2, 1),
+    RK3588_CPULCLK_RATE(96000000, 0, 2, 1),
+};
+
+static const struct rockchip_cpu_clk_reg_data rk3588_cpulclk_data =
+{
+    .core_reg[0] = RK3588_DSU_CLKSEL_CON(6),
+    .div_core_shift[0] = 0,
+    .div_core_mask[0] = 0x1f,
+    .core_reg[1] = RK3588_DSU_CLKSEL_CON(6),
+    .div_core_shift[1] = 7,
+    .div_core_mask[1] = 0x1f,
+    .core_reg[2] = RK3588_DSU_CLKSEL_CON(7),
+    .div_core_shift[2] = 0,
+    .div_core_mask[2] = 0x1f,
+    .core_reg[3] = RK3588_DSU_CLKSEL_CON(7),
+    .div_core_shift[3] = 7,
+    .div_core_mask[3] = 0x1f,
+    .num_cores = 4,
+    .mux_core_reg = RK3588_DSU_CLKSEL_CON(5),
+    .mux_core_alt = 1,
+    .mux_core_main = 2,
+    .mux_core_shift = 14,
+    .mux_core_mask = 0x3,
+};
+
+PNAMES(mux_pll_p)                       = { "xin24m", "xin32k" };
+PNAMES(b0pll_b1pll_lpll_gpll_p)         = { "b0pll", "b1pll", "lpll", "gpll" };
+PNAMES(gpll_24m_p)                      = { "gpll", "xin24m" };
+PNAMES(gpll_aupll_p)                    = { "gpll", "aupll" };
+PNAMES(gpll_lpll_p)                     = { "gpll", "lpll" };
+PNAMES(gpll_cpll_p)                     = { "gpll", "cpll" };
+PNAMES(gpll_spll_p)                     = { "gpll", "spll" };
+PNAMES(gpll_cpll_24m_p)                 = { "gpll", "cpll", "xin24m"};
+PNAMES(gpll_cpll_aupll_p)               = { "gpll", "cpll", "aupll"};
+PNAMES(gpll_cpll_npll_p)                = { "gpll", "cpll", "npll"};
+PNAMES(gpll_cpll_npll_v0pll_p)          = { "gpll", "cpll", "npll", "v0pll"};
+PNAMES(gpll_cpll_24m_spll_p)            = { "gpll", "cpll", "xin24m", "spll" };
+PNAMES(gpll_cpll_aupll_spll_p)          = { "gpll", "cpll", "aupll", "spll" };
+PNAMES(gpll_cpll_aupll_npll_p)          = { "gpll", "cpll", "aupll", "npll" };
+PNAMES(gpll_cpll_v0pll_aupll_p)         = { "gpll", "cpll", "v0pll", "aupll" };
+PNAMES(gpll_cpll_v0pll_spll_p)          = { "gpll", "cpll", "v0pll", "spll" };
+PNAMES(gpll_cpll_aupll_npll_spll_p)     = { "gpll", "cpll", "aupll", "npll", "spll" };
+PNAMES(gpll_cpll_dmyaupll_npll_spll_p)  = { "gpll", "cpll", "dummy_aupll", "npll", "spll" };
+PNAMES(gpll_cpll_npll_aupll_spll_p)     = { "gpll", "cpll", "npll", "aupll", "spll" };
+PNAMES(gpll_cpll_npll_1000m_p)          = { "gpll", "cpll", "npll", "clk_1000m_src" };
+PNAMES(mux_24m_spll_gpll_cpll_p)        = { "xin24m", "spll", "gpll", "cpll" };
+PNAMES(mux_24m_32k_p)                   = { "xin24m", "xin32k" };
+PNAMES(mux_24m_100m_p)                  = { "xin24m", "clk_100m_src" };
+PNAMES(mux_200m_100m_p)                 = { "clk_200m_src", "clk_100m_src" };
+PNAMES(mux_100m_50m_24m_p)              = { "clk_100m_src", "clk_50m_src", "xin24m" };
+PNAMES(mux_150m_50m_24m_p)              = { "clk_150m_src", "clk_50m_src", "xin24m" };
+PNAMES(mux_150m_100m_24m_p)             = { "clk_150m_src", "clk_100m_src", "xin24m" };
+PNAMES(mux_200m_150m_24m_p)             = { "clk_200m_src", "clk_150m_src", "xin24m" };
+PNAMES(mux_150m_100m_50m_24m_p)         = { "clk_150m_src", "clk_100m_src", "clk_50m_src", "xin24m" };
+PNAMES(mux_200m_100m_50m_24m_p)         = { "clk_200m_src", "clk_100m_src", "clk_50m_src", "xin24m" };
+PNAMES(mux_300m_200m_100m_24m_p)        = { "clk_300m_src", "clk_200m_src", "clk_100m_src", "xin24m" };
+PNAMES(mux_700m_400m_200m_24m_p)        = { "clk_700m_src", "clk_400m_src", "clk_200m_src", "xin24m" };
+PNAMES(mux_500m_250m_100m_24m_p)        = { "clk_500m_src", "clk_250m_src", "clk_100m_src", "xin24m" };
+PNAMES(mux_500m_300m_100m_24m_p)        = { "clk_500m_src", "clk_300m_src", "clk_100m_src", "xin24m" };
+PNAMES(mux_400m_200m_100m_24m_p)        = { "clk_400m_src", "clk_200m_src", "clk_100m_src", "xin24m" };
+PNAMES(clk_i2s2_2ch_p)                  = { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "i2s2_mclkin", "xin12m" };
+PNAMES(i2s2_2ch_mclkout_p)              = { "mclk_i2s2_2ch", "xin12m" };
+PNAMES(clk_i2s3_2ch_p)                  = { "clk_i2s3_2ch_src", "clk_i2s3_2ch_frac", "i2s3_mclkin", "xin12m" };
+PNAMES(i2s3_2ch_mclkout_p)              = { "mclk_i2s3_2ch", "xin12m" };
+PNAMES(clk_i2s0_8ch_tx_p)               = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin12m" };
+PNAMES(clk_i2s0_8ch_rx_p)               = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin12m" };
+PNAMES(i2s0_8ch_mclkout_p)              = { "mclk_i2s0_8ch_tx", "mclk_i2s0_8ch_rx", "xin12m" };
+PNAMES(clk_i2s1_8ch_tx_p)               = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "i2s1_mclkin", "xin12m" };
+PNAMES(clk_i2s1_8ch_rx_p)               = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "i2s1_mclkin", "xin12m" };
+PNAMES(i2s1_8ch_mclkout_p)              = { "mclk_i2s1_8ch_tx", "mclk_i2s1_8ch_rx", "xin12m" };
+PNAMES(clk_i2s4_8ch_tx_p)               = { "clk_i2s4_8ch_tx_src", "clk_i2s4_8ch_tx_frac", "i2s4_mclkin", "xin12m" };
+PNAMES(clk_i2s5_8ch_tx_p)               = { "clk_i2s5_8ch_tx_src", "clk_i2s5_8ch_tx_frac", "i2s5_mclkin", "xin12m" };
+PNAMES(clk_i2s6_8ch_tx_p)               = { "clk_i2s6_8ch_tx_src", "clk_i2s6_8ch_tx_frac", "i2s6_mclkin", "xin12m" };
+PNAMES(clk_i2s6_8ch_rx_p)               = { "clk_i2s6_8ch_rx_src", "clk_i2s6_8ch_rx_frac", "i2s6_mclkin", "xin12m" };
+PNAMES(i2s6_8ch_mclkout_p)              = { "mclk_i2s6_8ch_tx", "mclk_i2s6_8ch_rx", "xin12m" };
+PNAMES(clk_i2s7_8ch_rx_p)               = { "clk_i2s7_8ch_rx_src", "clk_i2s7_8ch_rx_frac", "i2s7_mclkin", "xin12m" };
+PNAMES(clk_i2s8_8ch_tx_p)               = { "clk_i2s8_8ch_tx_src", "clk_i2s8_8ch_tx_frac", "i2s8_mclkin", "xin12m" };
+PNAMES(clk_i2s9_8ch_rx_p)               = { "clk_i2s9_8ch_rx_src", "clk_i2s9_8ch_rx_frac", "i2s9_mclkin", "xin12m" };
+PNAMES(clk_i2s10_8ch_rx_p)              = { "clk_i2s10_8ch_rx_src", "clk_i2s10_8ch_rx_frac", "i2s10_mclkin", "xin12m" };
+PNAMES(clk_spdif0_p)                    = { "clk_spdif0_src", "clk_spdif0_frac", "xin12m" };
+PNAMES(clk_spdif1_p)                    = { "clk_spdif1_src", "clk_spdif1_frac", "xin12m" };
+PNAMES(clk_spdif2_dp0_p)                = { "clk_spdif2_dp0_src", "clk_spdif2_dp0_frac", "xin12m" };
+PNAMES(clk_spdif3_p)                    = { "clk_spdif3_src", "clk_spdif3_frac", "xin12m" };
+PNAMES(clk_spdif4_p)                    = { "clk_spdif4_src", "clk_spdif4_frac", "xin12m" };
+PNAMES(clk_spdif5_dp1_p)                = { "clk_spdif5_dp1_src", "clk_spdif5_dp1_frac", "xin12m" };
+PNAMES(clk_uart0_p)                     = { "clk_uart0_src", "clk_uart0_frac", "xin24m" };
+PNAMES(clk_uart1_p)                     = { "clk_uart1_src", "clk_uart1_frac", "xin24m" };
+PNAMES(clk_uart2_p)                     = { "clk_uart2_src", "clk_uart2_frac", "xin24m" };
+PNAMES(clk_uart3_p)                     = { "clk_uart3_src", "clk_uart3_frac", "xin24m" };
+PNAMES(clk_uart4_p)                     = { "clk_uart4_src", "clk_uart4_frac", "xin24m" };
+PNAMES(clk_uart5_p)                     = { "clk_uart5_src", "clk_uart5_frac", "xin24m" };
+PNAMES(clk_uart6_p)                     = { "clk_uart6_src", "clk_uart6_frac", "xin24m" };
+PNAMES(clk_uart7_p)                     = { "clk_uart7_src", "clk_uart7_frac", "xin24m" };
+PNAMES(clk_uart8_p)                     = { "clk_uart8_src", "clk_uart8_frac", "xin24m" };
+PNAMES(clk_uart9_p)                     = { "clk_uart9_src", "clk_uart9_frac", "xin24m" };
+PNAMES(clk_gmac0_ptp_ref_p)             = { "cpll", "clk_gmac0_ptpref_io" };
+PNAMES(clk_gmac1_ptp_ref_p)             = { "cpll", "clk_gmac1_ptpref_io" };
+PNAMES(clk_hdmirx_aud_p)                = { "clk_hdmirx_aud_src", "clk_hdmirx_aud_frac" };
+PNAMES(aclk_hdcp1_root_p)               = { "gpll", "cpll", "clk_hdmitrx_refsrc" };
+PNAMES(aclk_vop_sub_src_p)              = { "aclk_vop_root", "aclk_vop_div2_src" };
+PNAMES(dclk_vop0_p)                     = { "dclk_vop0_src", "clk_hdmiphy_pixel0", "clk_hdmiphy_pixel1" };
+PNAMES(dclk_vop1_p)                     = { "dclk_vop1_src", "clk_hdmiphy_pixel0", "clk_hdmiphy_pixel1" };
+PNAMES(dclk_vop2_p)                     = { "dclk_vop2_src", "clk_hdmiphy_pixel0", "clk_hdmiphy_pixel1" };
+PNAMES(pmu_200m_100m_p)                 = { "clk_pmu1_200m_src", "clk_pmu1_100m_src" };
+PNAMES(pmu_300m_24m_p)                  = { "clk_300m_src", "xin24m" };
+PNAMES(pmu_400m_24m_p)                  = { "clk_400m_src", "xin24m" };
+PNAMES(pmu_100m_50m_24m_src_p)          = { "clk_pmu1_100m_src", "clk_pmu1_50m_src", "xin24m" };
+PNAMES(pmu_24m_32k_100m_src_p)          = { "xin24m", "xin32k", "clk_pmu1_100m_src" };
+PNAMES(hclk_pmu1_root_p)                = { "clk_pmu1_200m_src", "clk_pmu1_100m_src", "clk_pmu1_50m_src", "xin24m" };
+PNAMES(hclk_pmu_cm0_root_p)             = { "clk_pmu1_400m_src", "clk_pmu1_200m_src", "clk_pmu1_100m_src", "xin24m" };
+PNAMES(mclk_pdm0_p)                     = { "clk_pmu1_300m_src", "clk_pmu1_200m_src" };
+PNAMES(mux_24m_ppll_spll_p)             = { "xin24m", "ppll", "spll" };
+PNAMES(mux_24m_ppll_p)                  = { "xin24m", "ppll" };
+PNAMES(clk_ref_pipe_phy0_p)             = { "clk_ref_pipe_phy0_osc_src", "clk_ref_pipe_phy0_pll_src" };
+PNAMES(clk_ref_pipe_phy1_p)             = { "clk_ref_pipe_phy1_osc_src", "clk_ref_pipe_phy1_pll_src" };
+PNAMES(clk_ref_pipe_phy2_p)             = { "clk_ref_pipe_phy2_osc_src", "clk_ref_pipe_phy2_pll_src" };
+
+#define MFLAGS CLK_MUX_HIWORD_MASK
+#define DFLAGS CLK_DIVIDER_HIWORD_MASK
+#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
+
+static struct rockchip_pll_clk_cell rk3588_pll_b0pll =
+    PLL_RAW(pll_type_rk3588_core, PLL_B0PLL, "b0pll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_B0_PLL_CON(0), RK3588_B0_PLL_MODE_CON0,
+            0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_b1pll =
+    PLL_RAW(pll_type_rk3588_core, PLL_B1PLL, "b1pll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_B1_PLL_CON(8), RK3588_B1_PLL_MODE_CON0,
+            0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_lpll =
+    PLL_RAW(pll_type_rk3588_core, PLL_LPLL, "lpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_LPLL_CON(16), RK3588_LPLL_MODE_CON0,
+            0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_v0pll =
+    PLL_RAW(pll_type_rk3588, PLL_V0PLL, "v0pll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3588_PLL_CON(88), RK3588_MODE_CON0,
+            4, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_aupll =
+    PLL_RAW(pll_type_rk3588, PLL_AUPLL, "aupll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3588_PLL_CON(96), RK3588_MODE_CON0,
+            6, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_cpll =
+    PLL_RAW(pll_type_rk3588, PLL_CPLL, "cpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_PLL_CON(104), RK3588_MODE_CON0,
+            8, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_gpll =
+    PLL_RAW(pll_type_rk3588, PLL_GPLL, "gpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_PLL_CON(112), RK3588_MODE_CON0,
+            2, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_npll =
+    PLL_RAW(pll_type_rk3588, PLL_NPLL, "npll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3588_PLL_CON(120), RK3588_MODE_CON0,
+            0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates);
+static struct rockchip_pll_clk_cell rk3588_pll_ppll =
+    PLL_RAW(pll_type_rk3588_core, PLL_PPLL, "ppll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_PMU_PLL_CON(128), RK3588_MODE_CON0,
+            10, 15,RK3588_GRF_SOC_STATUS0,  0, rk3588_pll_rates);
+
+static struct rockchip_clk_cell rk3588_i2s0_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(26), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s0_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(28), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s1_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", clk_i2s1_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_PMU_CLKSEL_CON(7), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s1_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", clk_i2s1_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_PMU_CLKSEL_CON(9), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s2_2ch_fracmux =
+    MUX_RAW(CLK_I2S2_2CH, "clk_i2s2_2ch", clk_i2s2_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(30), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s3_2ch_fracmux =
+    MUX_RAW(CLK_I2S3_2CH, "clk_i2s3_2ch", clk_i2s3_2ch_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(32), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s4_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S4_8CH_TX, "clk_i2s4_8ch_tx", clk_i2s4_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(120), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s5_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S5_8CH_TX, "clk_i2s5_8ch_tx", clk_i2s5_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_CLKSEL_CON(142), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s6_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S6_8CH_TX, "clk_i2s6_8ch_tx", clk_i2s6_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_CLKSEL_CON(146), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s6_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S6_8CH_RX, "clk_i2s6_8ch_rx", clk_i2s6_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_CLKSEL_CON(148), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s7_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S7_8CH_RX, "clk_i2s7_8ch_rx", clk_i2s7_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_CLKSEL_CON(131), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s8_8ch_tx_fracmux =
+    MUX_RAW(CLK_I2S8_8CH_TX, "clk_i2s8_8ch_tx", clk_i2s8_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(122), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s9_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S9_8CH_RX, "clk_i2s9_8ch_rx", clk_i2s9_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+             RK3588_CLKSEL_CON(155), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_i2s10_8ch_rx_fracmux =
+    MUX_RAW(CLK_I2S10_8CH_RX, "clk_i2s10_8ch_rx", clk_i2s10_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(157), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_spdif0_fracmux =
+    MUX_RAW(CLK_SPDIF0, "clk_spdif0", clk_spdif0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(34), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_spdif1_fracmux =
+    MUX_RAW(CLK_SPDIF1, "clk_spdif1", clk_spdif1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(36), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_spdif2_dp0_fracmux =
+    MUX_RAW(CLK_SPDIF2_DP0, "clk_spdif2_dp0", clk_spdif2_dp0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(124), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_spdif3_fracmux =
+    MUX_RAW(CLK_SPDIF3, "clk_spdif3", clk_spdif3_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(150), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_spdif4_fracmux =
+    MUX_RAW(CLK_SPDIF4, "clk_spdif4", clk_spdif4_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(152), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_spdif5_dp1_fracmux =
+    MUX_RAW(CLK_SPDIF5_DP1, "clk_spdif5_dp1", clk_spdif5_dp1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(126), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST);
+
+static struct rockchip_clk_cell rk3588_uart0_fracmux =
+    MUX_RAW(CLK_UART0, "clk_uart0", clk_uart0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_PMU_CLKSEL_CON(5), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart1_fracmux =
+    MUX_RAW(CLK_UART1, "clk_uart1", clk_uart1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(43), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart2_fracmux =
+    MUX_RAW(CLK_UART2, "clk_uart2", clk_uart2_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(45), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart3_fracmux =
+    MUX_RAW(CLK_UART3, "clk_uart3", clk_uart3_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(47), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart4_fracmux =
+    MUX_RAW(CLK_UART4, "clk_uart4", clk_uart4_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(49), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart5_fracmux =
+    MUX_RAW(CLK_UART5, "clk_uart5", clk_uart5_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(51), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart6_fracmux =
+    MUX_RAW(CLK_UART6, "clk_uart6", clk_uart6_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(53), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart7_fracmux =
+    MUX_RAW(CLK_UART7, "clk_uart7", clk_uart7_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(55), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart8_fracmux =
+    MUX_RAW(CLK_UART8, "clk_uart8", clk_uart8_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(57), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_uart9_fracmux =
+    MUX_RAW(CLK_UART9, "clk_uart9", clk_uart9_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(59), 0, 2, MFLAGS);
+
+static struct rockchip_clk_cell rk3588_hdmirx_aud_fracmux =
+    MUX_RAW(CLK_HDMIRX_AUD_P_MUX, "clk_hdmirx_aud_mux", clk_hdmirx_aud_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(140), 0, 1, MFLAGS);
+
+static struct rt_clk_cell *rk3588_clk_cells[] =
+{
+    [PLL_B0PLL] = &rk3588_pll_b0pll.rk_cell.cell,
+    [PLL_B1PLL] = &rk3588_pll_b1pll.rk_cell.cell,
+    [PLL_LPLL] = &rk3588_pll_lpll.rk_cell.cell,
+    [PLL_V0PLL] = &rk3588_pll_v0pll.rk_cell.cell,
+    [PLL_AUPLL] = &rk3588_pll_aupll.rk_cell.cell,
+    [PLL_CPLL] = &rk3588_pll_cpll.rk_cell.cell,
+    [PLL_GPLL] = &rk3588_pll_gpll.rk_cell.cell,
+    [PLL_NPLL] = &rk3588_pll_npll.rk_cell.cell,
+    [PLL_PPLL] = &rk3588_pll_ppll.rk_cell.cell,
+    [ARMCLK_L] = CPU(ARMCLK_L, "armclk_l", &rk3588_pll_lpll.rk_cell, &rk3588_pll_gpll.rk_cell,
+            rk3588_cpulclk_rates, RT_ARRAY_SIZE(rk3588_cpulclk_rates), &rk3588_cpulclk_data),
+    [ARMCLK_B01] = CPU(ARMCLK_B01, "armclk_b01", &rk3588_pll_b0pll.rk_cell, &rk3588_pll_gpll.rk_cell,
+            rk3588_cpub0clk_rates, RT_ARRAY_SIZE(rk3588_cpub0clk_rates), &rk3588_cpub0clk_data),
+    [ARMCLK_B23] = CPU(ARMCLK_B23, "armclk_b23", &rk3588_pll_b1pll.rk_cell, &rk3588_pll_gpll.rk_cell,
+            rk3588_cpub1clk_rates, RT_ARRAY_SIZE(rk3588_cpub1clk_rates), &rk3588_cpub1clk_data),
+    [PCLK_BIGCORE0_ROOT] = COMPOSITE_NODIV(PCLK_BIGCORE0_ROOT, "pclk_bigcore0_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_BIGCORE0_CLKSEL_CON(2), 0, 2, MFLAGS,
+            RK3588_BIGCORE0_CLKGATE_CON(0), 14, GFLAGS),
+    [PCLK_BIGCORE0_PVTM] = GATE(PCLK_BIGCORE0_PVTM, "pclk_bigcore0_pvtm", "pclk_bigcore0_root", 0, RK3588_BIGCORE0_CLKGATE_CON(1), 0, GFLAGS),
+    [PCLK_BIGCORE1_ROOT] = COMPOSITE_NODIV(PCLK_BIGCORE1_ROOT, "pclk_bigcore1_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_BIGCORE1_CLKSEL_CON(2), 0, 2, MFLAGS,
+            RK3588_BIGCORE1_CLKGATE_CON(0), 14, GFLAGS),
+    [PCLK_BIGCORE1_PVTM] = GATE(PCLK_BIGCORE1_PVTM, "pclk_bigcore1_pvtm", "pclk_bigcore1_root", 0, RK3588_BIGCORE1_CLKGATE_CON(1), 0, GFLAGS),
+    [PCLK_DSU_S_ROOT] = COMPOSITE_NODIV(PCLK_DSU_S_ROOT, "pclk_dsu_s_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(4), 11, 2, MFLAGS,
+            RK3588_DSU_CLKGATE_CON(2), 2, GFLAGS),
+    [PCLK_DSU_ROOT] = COMPOSITE(PCLK_DSU_ROOT, "pclk_dsu_root", b0pll_b1pll_lpll_gpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(4), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_DSU_CLKGATE_CON(1), 3, GFLAGS),
+    [PCLK_DSU_NS_ROOT] = COMPOSITE_NODIV(PCLK_DSU_NS_ROOT, "pclk_dsu_ns_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(4), 7, 2, MFLAGS,
+            RK3588_DSU_CLKGATE_CON(1), 4, GFLAGS),
+    [PCLK_LITCORE_PVTM] = GATE(PCLK_LITCORE_PVTM, "pclk_litcore_pvtm", "pclk_dsu_ns_root", 0, RK3588_DSU_CLKGATE_CON(2), 6, GFLAGS),
+    [PCLK_DBG] = GATE(PCLK_DBG, "pclk_dbg", "pclk_dsu_root", RT_CLK_F_IS_CRITICAL, RK3588_DSU_CLKGATE_CON(1), 7, GFLAGS),
+    [PCLK_DSU] = GATE(PCLK_DSU, "pclk_dsu", "pclk_dsu_root", RT_CLK_F_IS_CRITICAL, RK3588_DSU_CLKGATE_CON(1), 6, GFLAGS),
+    [PCLK_S_DAPLITE] = GATE(PCLK_S_DAPLITE, "pclk_s_daplite", "pclk_dsu_ns_root", RT_CLK_F_IGNORE_UNUSED, RK3588_DSU_CLKGATE_CON(1), 8, GFLAGS),
+    [PCLK_M_DAPLITE] = GATE(PCLK_M_DAPLITE, "pclk_m_daplite", "pclk_dsu_root", RT_CLK_F_IGNORE_UNUSED, RK3588_DSU_CLKGATE_CON(1), 9, GFLAGS),
+    [HCLK_I2S2_2CH] = GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_audio_root", 0, RK3588_CLKGATE_CON(7), 12, GFLAGS),
+    [HCLK_I2S3_2CH] = GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_audio_root", 0, RK3588_CLKGATE_CON(7), 13, GFLAGS),
+    [CLK_I2S2_2CH_SRC] = COMPOSITE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(28), 9, 1, MFLAGS, 4, 5, DFLAGS,
+            RK3588_CLKGATE_CON(7), 14, GFLAGS),
+    [CLK_I2S2_2CH_FRAC] = COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(29), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(7), 15, GFLAGS,
+            &rk3588_i2s2_2ch_fracmux),
+    [CLK_I2S2_2CH] = &rk3588_i2s2_2ch_fracmux.cell,
+    [MCLK_I2S2_2CH] = GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 0, RK3588_CLKGATE_CON(8), 0, GFLAGS),
+    [I2S2_2CH_MCLKOUT] = MUX(I2S2_2CH_MCLKOUT, "i2s2_2ch_mclkout", i2s2_2ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(30), 2, 1, MFLAGS),
+    [CLK_DAC_ACDCDIG] = GATE(CLK_DAC_ACDCDIG, "clk_dac_acdcdig", "mclk_i2s3_2ch", 0, RK3588_CLKGATE_CON(8), 4, GFLAGS),
+    [CLK_I2S3_2CH_SRC] = COMPOSITE(CLK_I2S3_2CH_SRC, "clk_i2s3_2ch_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(30), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(8), 1, GFLAGS),
+    [CLK_I2S3_2CH_FRAC] = COMPOSITE_FRACMUX(CLK_I2S3_2CH_FRAC, "clk_i2s3_2ch_frac", "clk_i2s3_2ch_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(31), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(8), 2, GFLAGS,
+            &rk3588_i2s3_2ch_fracmux),
+    [CLK_I2S3_2CH] = &rk3588_i2s3_2ch_fracmux.cell,
+    [MCLK_I2S3_2CH] = GATE(MCLK_I2S3_2CH, "mclk_i2s3_2ch", "clk_i2s3_2ch", 0, RK3588_CLKGATE_CON(8), 3, GFLAGS),
+    [I2S3_2CH_MCLKOUT] = MUX(I2S3_2CH_MCLKOUT, "i2s3_2ch_mclkout", i2s3_2ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(32), 2, 1, MFLAGS),
+    [PCLK_ACDCDIG] = GATE(PCLK_ACDCDIG, "pclk_acdcdig", "pclk_audio_root", 0, RK3588_CLKGATE_CON(7), 11, GFLAGS),
+    [HCLK_I2S0_8CH] = GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio_root", 0, RK3588_CLKGATE_CON(7), 4, GFLAGS),
+    [CLK_I2S0_8CH_TX_SRC] = COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(24), 9, 1, MFLAGS, 4, 5, DFLAGS,
+            RK3588_CLKGATE_CON(7), 5, GFLAGS),
+    [CLK_I2S0_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(25), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(7), 6, GFLAGS,
+            &rk3588_i2s0_8ch_tx_fracmux),
+    [MCLK_I2S0_8CH_TX] = GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0, RK3588_CLKGATE_CON(7), 7, GFLAGS),
+    [CLK_I2S0_8CH_TX] = &rk3588_i2s0_8ch_tx_fracmux.cell,
+    [CLK_I2S0_8CH_RX_SRC] = COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(26), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(7), 8, GFLAGS),
+    [CLK_I2S0_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(27), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(7), 9, GFLAGS,
+            &rk3588_i2s0_8ch_rx_fracmux),
+    [MCLK_I2S0_8CH_RX] = GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0, RK3588_CLKGATE_CON(7), 10, GFLAGS),
+    [CLK_I2S0_8CH_RX] = &rk3588_i2s0_8ch_rx_fracmux.cell,
+    [I2S0_8CH_MCLKOUT] = MUX(I2S0_8CH_MCLKOUT, "i2s0_8ch_mclkout", i2s0_8ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(28), 2, 2, MFLAGS),
+    [HCLK_PDM1] = GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0, RK3588_CLKGATE_CON(9), 6, GFLAGS),
+    [MCLK_PDM1] = COMPOSITE(MCLK_PDM1, "mclk_pdm1", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(36), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(9), 7, GFLAGS),
+    [HCLK_AUDIO_ROOT] = COMPOSITE_NODIV(HCLK_AUDIO_ROOT, "hclk_audio_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(24), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(7), 0, GFLAGS),
+    [PCLK_AUDIO_ROOT] = COMPOSITE_NODIV(PCLK_AUDIO_ROOT, "pclk_audio_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(24), 2, 2, MFLAGS,
+            RK3588_CLKGATE_CON(7), 1, GFLAGS),
+    [HCLK_SPDIF0] = GATE(HCLK_SPDIF0, "hclk_spdif0", "hclk_audio_root", 0, RK3588_CLKGATE_CON(8), 14, GFLAGS),
+    [CLK_SPDIF0_SRC] = COMPOSITE(CLK_SPDIF0_SRC, "clk_spdif0_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(32), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(8), 15, GFLAGS),
+    [CLK_SPDIF0_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF0_FRAC, "clk_spdif0_frac", "clk_spdif0_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(33), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(9), 0, GFLAGS,
+            &rk3588_spdif0_fracmux),
+    [MCLK_SPDIF0] = GATE(MCLK_SPDIF0, "mclk_spdif0", "clk_spdif0", 0, RK3588_CLKGATE_CON(9), 1, GFLAGS),
+    [CLK_SPDIF0] = &rk3588_spdif0_fracmux.cell,
+    [CLK_SPDIF1] = &rk3588_spdif1_fracmux.cell,
+    [HCLK_SPDIF1] = GATE(HCLK_SPDIF1, "hclk_spdif1", "hclk_audio_root", 0, RK3588_CLKGATE_CON(9), 2, GFLAGS),
+    [CLK_SPDIF1_SRC] = COMPOSITE(CLK_SPDIF1_SRC, "clk_spdif1_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(34), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(9), 3, GFLAGS),
+    [CLK_SPDIF1_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF1_FRAC, "clk_spdif1_frac", "clk_spdif1_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(35), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(9), 4, GFLAGS,
+            &rk3588_spdif1_fracmux),
+    [MCLK_SPDIF1] = GATE(MCLK_SPDIF1, "mclk_spdif1", "clk_spdif1", 0, RK3588_CLKGATE_CON(9), 5, GFLAGS),
+    [ACLK_AV1_ROOT] = COMPOSITE(ACLK_AV1_ROOT, "aclk_av1_root", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(163), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(68), 0, GFLAGS),
+    [ACLK_AV1] = GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0, RK3588_CLKGATE_CON(68), 2, GFLAGS),
+    [PCLK_AV1_ROOT] = COMPOSITE_NODIV(PCLK_AV1_ROOT, "pclk_av1_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(163), 7, 2, MFLAGS,
+            RK3588_CLKGATE_CON(68), 3, GFLAGS),
+    [PCLK_AV1] = GATE(PCLK_AV1, "pclk_av1", "pclk_av1_pre", 0, RK3588_CLKGATE_CON(68), 5, GFLAGS),
+    [PCLK_MAILBOX0] = GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 11, GFLAGS),
+    [PCLK_MAILBOX1] = GATE(PCLK_MAILBOX1, "pclk_mailbox1", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 12, GFLAGS),
+    [PCLK_MAILBOX2] = GATE(PCLK_MAILBOX2, "pclk_mailbox2", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 13, GFLAGS),
+    [PCLK_PMU2] = GATE(PCLK_PMU2, "pclk_pmu2", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(19), 3, GFLAGS),
+    [PCLK_PMUCM0_INTMUX] = GATE(PCLK_PMUCM0_INTMUX, "pclk_pmucm0_intmux", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(19), 4, GFLAGS),
+    [PCLK_DDRCM0_INTMUX] = GATE(PCLK_DDRCM0_INTMUX, "pclk_ddrcm0_intmux", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(19), 5, GFLAGS),
+    [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 3, GFLAGS),
+    [CLK_PWM1] = COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 12, 2, MFLAGS,
+            RK3588_CLKGATE_CON(15), 4, GFLAGS),
+    [CLK_PWM1_CAPTURE] = GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 0, RK3588_CLKGATE_CON(15), 5, GFLAGS),
+    [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 6, GFLAGS),
+    [CLK_PWM2] = COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 14, 2, MFLAGS,
+            RK3588_CLKGATE_CON(15), 7, GFLAGS),
+    [CLK_PWM2_CAPTURE] = GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 0, RK3588_CLKGATE_CON(15), 8, GFLAGS),
+    [PCLK_PWM3] = GATE(PCLK_PWM3, "pclk_pwm3", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 9, GFLAGS),
+    [CLK_PWM3] = COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(60), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(15), 10, GFLAGS),
+    [CLK_PWM3_CAPTURE] = GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 0, RK3588_CLKGATE_CON(15), 11, GFLAGS),
+    [PCLK_BUSTIMER0] = GATE(PCLK_BUSTIMER0, "pclk_bustimer0", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 12, GFLAGS),
+    [PCLK_BUSTIMER1] = GATE(PCLK_BUSTIMER1, "pclk_bustimer1", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 13, GFLAGS),
+    [CLK_BUS_TIMER_ROOT] = COMPOSITE_NODIV(CLK_BUS_TIMER_ROOT, "clk_bus_timer_root", mux_24m_100m_p, 0,
+            RK3588_CLKSEL_CON(60), 2, 1, MFLAGS,
+            RK3588_CLKGATE_CON(15), 14, GFLAGS),
+    [CLK_BUSTIMER0] = GATE(CLK_BUSTIMER0, "clk_bustimer0", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(15), 15, GFLAGS),
+    [CLK_BUSTIMER1] = GATE(CLK_BUSTIMER1, "clk_bustimer1", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 0, GFLAGS),
+    [CLK_BUSTIMER2] = GATE(CLK_BUSTIMER2, "clk_bustimer2", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 1, GFLAGS),
+    [CLK_BUSTIMER3] = GATE(CLK_BUSTIMER3, "clk_bustimer3", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 2, GFLAGS),
+    [CLK_BUSTIMER4] = GATE(CLK_BUSTIMER4, "clk_bustimer4", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 3, GFLAGS),
+    [CLK_BUSTIMER5] = GATE(CLK_BUSTIMER5, "clk_bustimer5", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 4, GFLAGS),
+    [CLK_BUSTIMER6] = GATE(CLK_BUSTIMER6, "clk_bustimer6", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 5, GFLAGS),
+    [CLK_BUSTIMER7] = GATE(CLK_BUSTIMER7, "clk_bustimer7", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 6, GFLAGS),
+    [CLK_BUSTIMER8] = GATE(CLK_BUSTIMER8, "clk_bustimer8", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 7, GFLAGS),
+    [CLK_BUSTIMER9] = GATE(CLK_BUSTIMER9, "clk_bustimer9", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 8, GFLAGS),
+    [CLK_BUSTIMER10] = GATE(CLK_BUSTIMER10, "clk_bustimer10", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 9, GFLAGS),
+    [CLK_BUSTIMER11] = GATE(CLK_BUSTIMER11, "clk_bustimer11", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 10, GFLAGS),
+    [PCLK_WDT0] = GATE(PCLK_WDT0, "pclk_wdt0", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 0, GFLAGS),
+    [TCLK_WDT0] = GATE(TCLK_WDT0, "tclk_wdt0", "xin24m", 0, RK3588_CLKGATE_CON(15), 1, GFLAGS),
+    [PCLK_CAN0] = GATE(PCLK_CAN0, "pclk_can0", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 8, GFLAGS),
+    [CLK_CAN0] = COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(39), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(11), 9, GFLAGS),
+    [PCLK_CAN1] = GATE(PCLK_CAN1, "pclk_can1", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 10, GFLAGS),
+    [CLK_CAN1] = COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(39), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(11), 11, GFLAGS),
+    [PCLK_CAN2] = GATE(PCLK_CAN2, "pclk_can2", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 12, GFLAGS),
+    [CLK_CAN2] = COMPOSITE(CLK_CAN2, "clk_can2", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(40), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(11), 13, GFLAGS),
+    [ACLK_DECOM] = GATE(ACLK_DECOM, "aclk_decom", "aclk_bus_root", 0, RK3588_CLKGATE_CON(17), 6, GFLAGS),
+    [PCLK_DECOM] = GATE(PCLK_DECOM, "pclk_decom", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 7, GFLAGS),
+    [DCLK_DECOM] = COMPOSITE(DCLK_DECOM, "dclk_decom", gpll_spll_p, 0,
+            RK3588_CLKSEL_CON(62), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(17), 8, GFLAGS),
+    [ACLK_DMAC0] = GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0, RK3588_CLKGATE_CON(10), 5, GFLAGS),
+    [ACLK_DMAC1] = GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0, RK3588_CLKGATE_CON(10), 6, GFLAGS),
+    [ACLK_DMAC2] = GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_bus_root", 0, RK3588_CLKGATE_CON(10), 7, GFLAGS),
+    [ACLK_BUS_ROOT] = COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(10), 0, GFLAGS),
+    [ACLK_GIC] = GATE(ACLK_GIC, "aclk_gic", "aclk_bus_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(10), 3, GFLAGS),
+    [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 14, GFLAGS),
+    [DBCLK_GPIO1] = COMPOSITE(DBCLK_GPIO1, "dbclk_gpio1", mux_24m_32k_p, 0,
+            RK3588_CLKSEL_CON(60), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(16), 15, GFLAGS),
+    [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 0, GFLAGS),
+    [DBCLK_GPIO2] = COMPOSITE(DBCLK_GPIO2, "dbclk_gpio2", mux_24m_32k_p, 0,
+            RK3588_CLKSEL_CON(60), 14, 1, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(17), 1, GFLAGS),
+    [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 2, GFLAGS),
+    [DBCLK_GPIO3] = COMPOSITE(DBCLK_GPIO3, "dbclk_gpio3", mux_24m_32k_p, 0,
+            RK3588_CLKSEL_CON(61), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(17), 3, GFLAGS),
+    [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 4, GFLAGS),
+    [DBCLK_GPIO4] = COMPOSITE(DBCLK_GPIO4, "dbclk_gpio4", mux_24m_32k_p, 0,
+            RK3588_CLKSEL_CON(61), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(17), 5, GFLAGS),
+    [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 8, GFLAGS),
+    [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 9, GFLAGS),
+    [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 10, GFLAGS),
+    [PCLK_I2C4] = GATE(PCLK_I2C4, "pclk_i2c4", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 11, GFLAGS),
+    [PCLK_I2C5] = GATE(PCLK_I2C5, "pclk_i2c5", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 12, GFLAGS),
+    [PCLK_I2C6] = GATE(PCLK_I2C6, "pclk_i2c6", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 13, GFLAGS),
+    [PCLK_I2C7] = GATE(PCLK_I2C7, "pclk_i2c7", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 14, GFLAGS),
+    [PCLK_I2C8] = GATE(PCLK_I2C8, "pclk_i2c8", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 15, GFLAGS),
+    [CLK_I2C1] = COMPOSITE_NODIV(CLK_I2C1, "clk_i2c1", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 6, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 0, GFLAGS),
+    [CLK_I2C2] = COMPOSITE_NODIV(CLK_I2C2, "clk_i2c2", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 7, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 1, GFLAGS),
+    [CLK_I2C3] = COMPOSITE_NODIV(CLK_I2C3, "clk_i2c3", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 8, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 2, GFLAGS),
+    [CLK_I2C4] = COMPOSITE_NODIV(CLK_I2C4, "clk_i2c4", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 9, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 3, GFLAGS),
+    [CLK_I2C5] = COMPOSITE_NODIV(CLK_I2C5, "clk_i2c5", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 10, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 4, GFLAGS),
+    [CLK_I2C6] = COMPOSITE_NODIV(CLK_I2C6, "clk_i2c6", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 11, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 5, GFLAGS),
+    [CLK_I2C7] = COMPOSITE_NODIV(CLK_I2C7, "clk_i2c7", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 12, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 6, GFLAGS),
+    [CLK_I2C8] = COMPOSITE_NODIV(CLK_I2C8, "clk_i2c8", mux_200m_100m_p, 0,
+            RK3588_CLKSEL_CON(38), 13, 1, MFLAGS,
+            RK3588_CLKGATE_CON(11), 7, GFLAGS),
+    [PCLK_OTPC_NS] = GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_top_root", 0, RK3588_CLKGATE_CON(18), 9, GFLAGS),
+    [CLK_OTPC_NS] = GATE(CLK_OTPC_NS, "clk_otpc_ns", "xin24m", 0, RK3588_CLKGATE_CON(18), 10, GFLAGS),
+    [CLK_OTPC_AUTO_RD_G] = GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0, RK3588_CLKGATE_CON(18), 12, GFLAGS),
+    [CLK_OTP_PHY_G] = GATE(CLK_OTP_PHY_G, "clk_otp_phy_g", "xin24m", 0, RK3588_CLKGATE_CON(18), 13, GFLAGS),
+    [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 14, GFLAGS),
+    [CLK_SARADC] = COMPOSITE(CLK_SARADC, "clk_saradc", gpll_24m_p, 0,
+            RK3588_CLKSEL_CON(40), 14, 1, MFLAGS, 6, 8, DFLAGS,
+            RK3588_CLKGATE_CON(11), 15, GFLAGS),
+    [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 6, GFLAGS),
+    [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 7, GFLAGS),
+    [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 8, GFLAGS),
+    [PCLK_SPI3] = GATE(PCLK_SPI3, "pclk_spi3", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 9, GFLAGS),
+    [PCLK_SPI4] = GATE(PCLK_SPI4, "pclk_spi4", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 10, GFLAGS),
+    [CLK_SPI0] = COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_150m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 2, 2, MFLAGS,
+            RK3588_CLKGATE_CON(14), 11, GFLAGS),
+    [CLK_SPI1] = COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_150m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 4, 2, MFLAGS,
+            RK3588_CLKGATE_CON(14), 12, GFLAGS),
+    [CLK_SPI2] = COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_150m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 6, 2, MFLAGS,
+            RK3588_CLKGATE_CON(14), 13, GFLAGS),
+    [CLK_SPI3] = COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", mux_200m_150m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 8, 2, MFLAGS,
+            RK3588_CLKGATE_CON(14), 14, GFLAGS),
+    [CLK_SPI4] = COMPOSITE_NODIV(CLK_SPI4, "clk_spi4", mux_200m_150m_24m_p, 0,
+            RK3588_CLKSEL_CON(59), 10, 2, MFLAGS,
+            RK3588_CLKGATE_CON(14), 15, GFLAGS),
+    [ACLK_SPINLOCK] = GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_bus_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(18), 6, GFLAGS),
+    [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 0, GFLAGS),
+    [CLK_TSADC] = COMPOSITE(CLK_TSADC, "clk_tsadc", gpll_24m_p, 0,
+            RK3588_CLKSEL_CON(41), 8, 1, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(12), 1, GFLAGS),
+    [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 2, GFLAGS),
+    [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 3, GFLAGS),
+    [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 4, GFLAGS),
+    [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 5, GFLAGS),
+    [PCLK_UART5] = GATE(PCLK_UART5, "pclk_uart5", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 6, GFLAGS),
+    [PCLK_UART6] = GATE(PCLK_UART6, "pclk_uart6", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 7, GFLAGS),
+    [PCLK_UART7] = GATE(PCLK_UART7, "pclk_uart7", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 8, GFLAGS),
+    [PCLK_UART8] = GATE(PCLK_UART8, "pclk_uart8", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 9, GFLAGS),
+    [PCLK_UART9] = GATE(PCLK_UART9, "pclk_uart9", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 10, GFLAGS),
+    [CLK_UART1_SRC] =COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(41), 14, 1, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(12), 11, GFLAGS),
+    [CLK_UART1_FRAC] =COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(42), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(12), 12, GFLAGS,
+            &rk3588_uart1_fracmux),
+    [CLK_UART1] = &rk3588_uart1_fracmux.cell,
+    [SCLK_UART1] = GATE(SCLK_UART1, "sclk_uart1", "clk_uart1", 0, RK3588_CLKGATE_CON(12), 13, GFLAGS),
+    [CLK_UART2_SRC] = COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(43), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(12), 14, GFLAGS),
+    [CLK_UART2_FRAC] = COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(44), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(12), 15, GFLAGS,
+            &rk3588_uart2_fracmux),
+    [CLK_UART2] = &rk3588_uart2_fracmux.cell,
+    [SCLK_UART2] = GATE(SCLK_UART2, "sclk_uart2", "clk_uart2", 0, RK3588_CLKGATE_CON(13), 0, GFLAGS),
+    [CLK_UART3_SRC] = COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(45), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(13), 1, GFLAGS),
+    [CLK_UART3_FRAC] = COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(46), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(13), 2, GFLAGS,
+            &rk3588_uart3_fracmux),
+    [CLK_UART3] = &rk3588_uart3_fracmux.cell,
+    [SCLK_UART3] = GATE(SCLK_UART3, "sclk_uart3", "clk_uart3", 0, RK3588_CLKGATE_CON(13), 3, GFLAGS),
+    [CLK_UART4_SRC] = COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(47), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(13), 4, GFLAGS),
+    [CLK_UART4_FRAC] = COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(48), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(13), 5, GFLAGS,
+            &rk3588_uart4_fracmux),
+    [CLK_UART4] = &rk3588_uart4_fracmux.cell,
+    [SCLK_UART4] = GATE(SCLK_UART4, "sclk_uart4", "clk_uart4", 0, RK3588_CLKGATE_CON(13), 6, GFLAGS),
+    [CLK_UART5_SRC] = COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(49), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(13), 7, GFLAGS),
+    [CLK_UART5_FRAC] = COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(50), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(13), 8, GFLAGS,
+            &rk3588_uart5_fracmux),
+    [CLK_UART5] = &rk3588_uart5_fracmux.cell,
+    [SCLK_UART5] = GATE(SCLK_UART5, "sclk_uart5", "clk_uart5", 0, RK3588_CLKGATE_CON(13), 9, GFLAGS),
+    [CLK_UART6_SRC] = COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(51), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(13), 10, GFLAGS),
+    [CLK_UART6_FRAC] = COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(52), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(13), 11, GFLAGS,
+            &rk3588_uart6_fracmux),
+    [CLK_UART6] = &rk3588_uart6_fracmux.cell,
+    [SCLK_UART6] = GATE(SCLK_UART6, "sclk_uart6", "clk_uart6", 0, RK3588_CLKGATE_CON(13), 12, GFLAGS),
+    [CLK_UART7_SRC] = COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(53), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(13), 13, GFLAGS),
+    [CLK_UART7_FRAC] = COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(54), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(13), 14, GFLAGS,
+            &rk3588_uart7_fracmux),
+    [CLK_UART7] = &rk3588_uart7_fracmux.cell,
+    [SCLK_UART7] = GATE(SCLK_UART7, "sclk_uart7", "clk_uart7", 0, RK3588_CLKGATE_CON(13), 15, GFLAGS),
+    [CLK_UART8_SRC] = COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(55), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(14), 0, GFLAGS),
+    [CLK_UART8_FRAC] = COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(56), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(14), 1, GFLAGS,
+            &rk3588_uart8_fracmux),
+    [CLK_UART8] = &rk3588_uart8_fracmux.cell,
+    [SCLK_UART8] = GATE(SCLK_UART8, "sclk_uart8", "clk_uart8", 0, RK3588_CLKGATE_CON(14), 2, GFLAGS),
+    [CLK_UART9_SRC] = COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(57), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(14), 3, GFLAGS),
+    [CLK_UART9_FRAC] = COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(58), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_CLKGATE_CON(14), 4, GFLAGS,
+            &rk3588_uart9_fracmux),
+    [CLK_UART9] = &rk3588_uart9_fracmux.cell,
+    [SCLK_UART9] = GATE(SCLK_UART9, "sclk_uart9", "clk_uart9", 0, RK3588_CLKGATE_CON(14), 5, GFLAGS),
+    [ACLK_CENTER_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_ROOT, "aclk_center_root", mux_700m_400m_200m_24m_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(165), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(69), 0, GFLAGS),
+    [ACLK_CENTER_LOW_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", mux_500m_250m_100m_24m_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(165), 2, 2, MFLAGS,
+            RK3588_CLKGATE_CON(69), 1, GFLAGS),
+    [HCLK_CENTER_ROOT] = COMPOSITE_NODIV(HCLK_CENTER_ROOT, "hclk_center_root", mux_400m_200m_100m_24m_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(165), 4, 2, MFLAGS,
+            RK3588_CLKGATE_CON(69), 2, GFLAGS),
+    [PCLK_CENTER_ROOT] = COMPOSITE_NODIV(PCLK_CENTER_ROOT, "pclk_center_root", mux_200m_100m_50m_24m_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(165), 6, 2, MFLAGS | CLK_MUX_READ_ONLY,
+            RK3588_CLKGATE_CON(69), 3, GFLAGS),
+    [ACLK_DMA2DDR] = GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(69), 5, GFLAGS),
+    [ACLK_DDR_SHAREMEM] = GATE(ACLK_DDR_SHAREMEM, "aclk_ddr_sharemem", "aclk_center_low_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(69), 6, GFLAGS),
+    [ACLK_CENTER_S200_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_S200_ROOT, "aclk_center_s200_root", mux_200m_100m_50m_24m_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(165), 8, 2, MFLAGS,
+            RK3588_CLKGATE_CON(69), 8, GFLAGS),
+    [ACLK_CENTER_S400_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_S400_ROOT, "aclk_center_s400_root", mux_400m_200m_100m_24m_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(165), 10, 2, MFLAGS,
+            RK3588_CLKGATE_CON(69), 9, GFLAGS),
+    [FCLK_DDR_CM0_CORE] = GATE(FCLK_DDR_CM0_CORE, "fclk_ddr_cm0_core", "hclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(69), 14, GFLAGS),
+    [CLK_DDR_TIMER_ROOT] = COMPOSITE_NODIV(CLK_DDR_TIMER_ROOT, "clk_ddr_timer_root", mux_24m_100m_p, RT_CLK_F_IGNORE_UNUSED,
+            RK3588_CLKSEL_CON(165), 12, 1, MFLAGS,
+            RK3588_CLKGATE_CON(69), 15, GFLAGS),
+    [CLK_DDR_TIMER0] = GATE(CLK_DDR_TIMER0, "clk_ddr_timer0", "clk_ddr_timer_root", 0, RK3588_CLKGATE_CON(70), 0, GFLAGS),
+    [CLK_DDR_TIMER1] = GATE(CLK_DDR_TIMER1, "clk_ddr_timer1", "clk_ddr_timer_root", 0, RK3588_CLKGATE_CON(70), 1, GFLAGS),
+    [TCLK_WDT_DDR] = GATE(TCLK_WDT_DDR, "tclk_wdt_ddr", "xin24m", 0, RK3588_CLKGATE_CON(70), 2, GFLAGS),
+    [CLK_DDR_CM0_RTC] = COMPOSITE(CLK_DDR_CM0_RTC, "clk_ddr_cm0_rtc", mux_24m_32k_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(166), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(70), 4, GFLAGS),
+    [PCLK_WDT] = GATE(PCLK_WDT, "pclk_wdt", "pclk_center_root", 0, RK3588_CLKGATE_CON(70), 7, GFLAGS),
+    [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_center_root", 0, RK3588_CLKGATE_CON(70), 8, GFLAGS),
+    [PCLK_DMA2DDR] = GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(70), 9, GFLAGS),
+    [PCLK_SHAREMEM] = GATE(PCLK_SHAREMEM, "pclk_sharemem", "pclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(70), 10, GFLAGS),
+    [CLK_50M_SRC] = COMPOSITE(CLK_50M_SRC, "clk_50m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 0, GFLAGS),
+    [CLK_100M_SRC] = COMPOSITE(CLK_100M_SRC, "clk_100m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(0), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 1, GFLAGS),
+    [CLK_150M_SRC] = COMPOSITE(CLK_150M_SRC, "clk_150m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 2, GFLAGS),
+    [CLK_200M_SRC] = COMPOSITE(CLK_200M_SRC, "clk_200m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(1), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 3, GFLAGS),
+    [CLK_250M_SRC] = COMPOSITE(CLK_250M_SRC, "clk_250m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 4, GFLAGS),
+    [CLK_300M_SRC] = COMPOSITE(CLK_300M_SRC, "clk_300m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(2), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 5, GFLAGS),
+    [CLK_350M_SRC] = COMPOSITE(CLK_350M_SRC, "clk_350m_src", gpll_spll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(3), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 6, GFLAGS),
+    [CLK_400M_SRC] = COMPOSITE(CLK_400M_SRC, "clk_400m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(3), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 7, GFLAGS),
+    [CLK_450M_SRC] = COMPOSITE_HALFDIV(CLK_450M_SRC, "clk_450m_src", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(4), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 8, GFLAGS),
+    [CLK_500M_SRC] = COMPOSITE(CLK_500M_SRC, "clk_500m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(4), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 9, GFLAGS),
+    [CLK_600M_SRC] = COMPOSITE(CLK_600M_SRC, "clk_600m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(5), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 10, GFLAGS),
+    [CLK_650M_SRC] = COMPOSITE(CLK_650M_SRC, "clk_650m_src", gpll_lpll_p, 0,
+            RK3588_CLKSEL_CON(5), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 11, GFLAGS),
+    [CLK_700M_SRC] = COMPOSITE(CLK_700M_SRC, "clk_700m_src", gpll_spll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(6), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 12, GFLAGS),
+    [CLK_800M_SRC] = COMPOSITE(CLK_800M_SRC, "clk_800m_src", gpll_aupll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(6), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 13, GFLAGS),
+    [CLK_1000M_SRC] = COMPOSITE_HALFDIV(CLK_1000M_SRC, "clk_1000m_src", gpll_cpll_npll_v0pll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(7), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 14, GFLAGS),
+    [CLK_1200M_SRC] = COMPOSITE(CLK_1200M_SRC, "clk_1200m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(7), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(0), 15, GFLAGS),
+    [ACLK_TOP_M300_ROOT] = COMPOSITE_NODIV(ACLK_TOP_M300_ROOT, "aclk_top_m300_root", mux_300m_200m_100m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(9), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(1), 10, GFLAGS),
+    [ACLK_TOP_M500_ROOT] = COMPOSITE_NODIV(ACLK_TOP_M500_ROOT, "aclk_top_m500_root", mux_500m_300m_100m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(9), 2, 2, MFLAGS,
+            RK3588_CLKGATE_CON(1), 11, GFLAGS),
+    [ACLK_TOP_M400_ROOT] = COMPOSITE_NODIV(ACLK_TOP_M400_ROOT, "aclk_top_m400_root", mux_400m_200m_100m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(9), 4, 2, MFLAGS,
+            RK3588_CLKGATE_CON(1), 12, GFLAGS),
+    [ACLK_TOP_S200_ROOT] = COMPOSITE_NODIV(ACLK_TOP_S200_ROOT, "aclk_top_s200_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(9), 6, 2, MFLAGS,
+            RK3588_CLKGATE_CON(1), 13, GFLAGS),
+    [ACLK_TOP_S400_ROOT] = COMPOSITE_NODIV(ACLK_TOP_S400_ROOT, "aclk_top_s400_root", mux_400m_200m_100m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(9), 8, 2, MFLAGS,
+            RK3588_CLKGATE_CON(1), 14, GFLAGS),
+    [CLK_MIPI_CAMARAOUT_M0] = COMPOSITE(CLK_MIPI_CAMARAOUT_M0, "clk_mipi_camaraout_m0", mux_24m_spll_gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(5), 9, GFLAGS),
+    [CLK_MIPI_CAMARAOUT_M1] = COMPOSITE(CLK_MIPI_CAMARAOUT_M1, "clk_mipi_camaraout_m1", mux_24m_spll_gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(19), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(5), 10, GFLAGS),
+    [CLK_MIPI_CAMARAOUT_M2] = COMPOSITE(CLK_MIPI_CAMARAOUT_M2, "clk_mipi_camaraout_m2", mux_24m_spll_gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(20), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(5), 11, GFLAGS),
+    [CLK_MIPI_CAMARAOUT_M3] = COMPOSITE(CLK_MIPI_CAMARAOUT_M3, "clk_mipi_camaraout_m3", mux_24m_spll_gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(21), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(5), 12, GFLAGS),
+    [CLK_MIPI_CAMARAOUT_M4] = COMPOSITE(CLK_MIPI_CAMARAOUT_M4, "clk_mipi_camaraout_m4", mux_24m_spll_gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(22), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(5), 13, GFLAGS),
+    [MCLK_GMAC0_OUT] = COMPOSITE(MCLK_GMAC0_OUT, "mclk_gmac0_out", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(15), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(5), 3, GFLAGS),
+    [REFCLKO25M_ETH0_OUT] = COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(15), 15, 1, MFLAGS, 8, 7, DFLAGS,
+            RK3588_CLKGATE_CON(5), 4, GFLAGS),
+    [REFCLKO25M_ETH1_OUT] = COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(16), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(5), 5, GFLAGS),
+    [CLK_CIFOUT_OUT] = COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0,
+            RK3588_CLKSEL_CON(17), 8, 2, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(5), 6, GFLAGS),
+    [PCLK_MIPI_DCPHY0] = GATE(PCLK_MIPI_DCPHY0, "pclk_mipi_dcphy0", "pclk_top_root", 0, RK3588_CLKGATE_CON(3), 14, GFLAGS),
+    [PCLK_MIPI_DCPHY1] = GATE(PCLK_MIPI_DCPHY1, "pclk_mipi_dcphy1", "pclk_top_root", 0, RK3588_CLKGATE_CON(4), 3, GFLAGS),
+    [PCLK_CSIPHY0] = GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_top_root", 0, RK3588_CLKGATE_CON(1), 6, GFLAGS),
+    [PCLK_CSIPHY1] = GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_top_root", 0, RK3588_CLKGATE_CON(1), 8, GFLAGS),
+    [ACLK_TOP_ROOT] = COMPOSITE(ACLK_TOP_ROOT, "aclk_top_root", gpll_cpll_aupll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(8), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(1), 0, GFLAGS),
+    [PCLK_TOP_ROOT] = COMPOSITE_NODIV(PCLK_TOP_ROOT, "pclk_top_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(8), 7, 2, MFLAGS,
+            RK3588_CLKGATE_CON(1), 1, GFLAGS),
+    [ACLK_LOW_TOP_ROOT] = COMPOSITE(ACLK_LOW_TOP_ROOT, "aclk_low_top_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(8), 14, 1, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(1), 2, GFLAGS),
+    [PCLK_CRU] = GATE(PCLK_CRU, "pclk_cru", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(5), 0, GFLAGS),
+    [CLK_GPU_SRC] = COMPOSITE(CLK_GPU_SRC, "clk_gpu_src", gpll_cpll_aupll_npll_spll_p, 0,
+            RK3588_CLKSEL_CON(158), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(66), 1, GFLAGS),
+    [CLK_GPU] = GATE(CLK_GPU, "clk_gpu", "clk_gpu_src", 0, RK3588_CLKGATE_CON(66), 4, GFLAGS),
+    [CLK_GPU_COREGROUP] = GATE(CLK_GPU_COREGROUP, "clk_gpu_coregroup", "clk_gpu_src", 0, RK3588_CLKGATE_CON(66), 6, GFLAGS),
+    [CLK_GPU_STACKS] = COMPOSITE_NOMUX(CLK_GPU_STACKS, "clk_gpu_stacks", "clk_gpu_src", 0,
+            RK3588_CLKSEL_CON(159), 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(66), 7, GFLAGS),
+    [CLK_GPU_PVTM] = GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 0, RK3588_CLKGATE_CON(67), 0, GFLAGS),
+    [CLK_CORE_GPU_PVTM] = GATE(CLK_CORE_GPU_PVTM, "clk_core_gpu_pvtm", "clk_gpu_src", 0, RK3588_CLKGATE_CON(67), 1, GFLAGS),
+    [ACLK_ISP1_ROOT] = COMPOSITE(ACLK_ISP1_ROOT, "aclk_isp1_root", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(67), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(26), 0, GFLAGS),
+    [HCLK_ISP1_ROOT] = COMPOSITE_NODIV(HCLK_ISP1_ROOT, "hclk_isp1_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(67), 7, 2, MFLAGS,
+            RK3588_CLKGATE_CON(26), 1, GFLAGS),
+    [CLK_ISP1_CORE] = COMPOSITE(CLK_ISP1_CORE, "clk_isp1_core", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(67), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(26), 2, GFLAGS),
+    [CLK_ISP1_CORE_MARVIN] = GATE(CLK_ISP1_CORE_MARVIN, "clk_isp1_core_marvin", "clk_isp1_core", 0, RK3588_CLKGATE_CON(26), 3, GFLAGS),
+    [CLK_ISP1_CORE_VICAP] = GATE(CLK_ISP1_CORE_VICAP, "clk_isp1_core_vicap", "clk_isp1_core", 0, RK3588_CLKGATE_CON(26), 4, GFLAGS),
+    [ACLK_ISP1] = GATE(ACLK_ISP1, "aclk_isp1", "aclk_isp1_pre", 0, RK3588_CLKGATE_CON(26), 5, GFLAGS),
+    [HCLK_ISP1] = GATE(HCLK_ISP1, "hclk_isp1", "hclk_isp1_pre", 0, RK3588_CLKGATE_CON(26), 7, GFLAGS),
+    [ACLK_NPU1] = GATE(ACLK_NPU1, "aclk_npu1", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(27), 0, GFLAGS),
+    [HCLK_NPU1] = GATE(HCLK_NPU1, "hclk_npu1", "hclk_npu_root", 0, RK3588_CLKGATE_CON(27), 2, GFLAGS),
+    [ACLK_NPU2] = GATE(ACLK_NPU2, "aclk_npu2", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(28), 0, GFLAGS),
+    [HCLK_NPU2] = GATE(HCLK_NPU2, "hclk_npu2", "hclk_npu_root", 0, RK3588_CLKGATE_CON(28), 2, GFLAGS),
+    [HCLK_NPU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_NPU_CM0_ROOT, "hclk_npu_cm0_root", mux_400m_200m_100m_24m_p, 0,
+            RK3588_CLKSEL_CON(74), 5, 2, MFLAGS,
+            RK3588_CLKGATE_CON(30), 1, GFLAGS),
+    [FCLK_NPU_CM0_CORE] = GATE(FCLK_NPU_CM0_CORE, "fclk_npu_cm0_core", "hclk_npu_cm0_root", 0, RK3588_CLKGATE_CON(30), 3, GFLAGS),
+    [CLK_NPU_CM0_RTC] = COMPOSITE(CLK_NPU_CM0_RTC, "clk_npu_cm0_rtc", mux_24m_32k_p, 0,
+            RK3588_CLKSEL_CON(74), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(30), 5, GFLAGS),
+    [PCLK_NPU_PVTM] = GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_root", 0, RK3588_CLKGATE_CON(29), 12, GFLAGS),
+    [PCLK_NPU_GRF] = GATE(PCLK_NPU_GRF, "pclk_npu_grf", "pclk_npu_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(29), 13, GFLAGS),
+    [CLK_NPU_PVTM] = GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 0, RK3588_CLKGATE_CON(29), 14, GFLAGS),
+    [CLK_CORE_NPU_PVTM] = GATE(CLK_CORE_NPU_PVTM, "clk_core_npu_pvtm", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(29), 15, GFLAGS),
+    [ACLK_NPU0] = GATE(ACLK_NPU0, "aclk_npu0", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(30), 6, GFLAGS),
+    [HCLK_NPU0] = GATE(HCLK_NPU0, "hclk_npu0", "hclk_npu_root", 0, RK3588_CLKGATE_CON(30), 8, GFLAGS),
+    [HCLK_NPU_ROOT] = COMPOSITE_NODIV(HCLK_NPU_ROOT, "hclk_npu_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(73), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(29), 0, GFLAGS),
+    [CLK_NPU_DSU0] = COMPOSITE(CLK_NPU_DSU0, "clk_npu_dsu0", gpll_cpll_aupll_npll_spll_p, 0,
+            RK3588_CLKSEL_CON(73), 7, 3, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(29), 1, GFLAGS),
+    [PCLK_NPU_ROOT] = COMPOSITE_NODIV(PCLK_NPU_ROOT, "pclk_npu_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(74), 1, 2, MFLAGS,
+            RK3588_CLKGATE_CON(29), 4, GFLAGS),
+    [PCLK_NPU_TIMER] = GATE(PCLK_NPU_TIMER, "pclk_npu_timer", "pclk_npu_root", 0, RK3588_CLKGATE_CON(29), 6, GFLAGS),
+    [CLK_NPUTIMER_ROOT] = COMPOSITE_NODIV(CLK_NPUTIMER_ROOT, "clk_nputimer_root", mux_24m_100m_p, 0,
+            RK3588_CLKSEL_CON(74), 3, 1, MFLAGS,
+            RK3588_CLKGATE_CON(29), 7, GFLAGS),
+    [CLK_NPUTIMER0] = GATE(CLK_NPUTIMER0, "clk_nputimer0", "clk_nputimer_root", 0, RK3588_CLKGATE_CON(29), 8, GFLAGS),
+    [CLK_NPUTIMER1] = GATE(CLK_NPUTIMER1, "clk_nputimer1", "clk_nputimer_root", 0, RK3588_CLKGATE_CON(29), 9, GFLAGS),
+    [PCLK_NPU_WDT] = GATE(PCLK_NPU_WDT, "pclk_npu_wdt", "pclk_npu_root", 0, RK3588_CLKGATE_CON(29), 10, GFLAGS),
+    [TCLK_NPU_WDT] = GATE(TCLK_NPU_WDT, "tclk_npu_wdt", "xin24m", 0, RK3588_CLKGATE_CON(29), 11, GFLAGS),
+    [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_nvm", 0, RK3588_CLKGATE_CON(31), 4, GFLAGS),
+    [ACLK_EMMC] = GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0, RK3588_CLKGATE_CON(31), 5, GFLAGS),
+    [CCLK_EMMC] = COMPOSITE(CCLK_EMMC, "cclk_emmc", gpll_cpll_24m_p, 0,
+            RK3588_CLKSEL_CON(77), 14, 2, MFLAGS, 8, 6, DFLAGS,
+            RK3588_CLKGATE_CON(31), 6, GFLAGS),
+    [BCLK_EMMC] = COMPOSITE(BCLK_EMMC, "bclk_emmc", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(78), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(31), 7, GFLAGS),
+    [TMCLK_EMMC] = GATE(TMCLK_EMMC, "tmclk_emmc", "xin24m", 0, RK3588_CLKGATE_CON(31), 8, GFLAGS),
+    [SCLK_SFC] = COMPOSITE(SCLK_SFC, "sclk_sfc", gpll_cpll_24m_p, 0,
+            RK3588_CLKSEL_CON(78), 12, 2, MFLAGS, 6, 6, DFLAGS,
+            RK3588_CLKGATE_CON(31), 9, GFLAGS),
+    [HCLK_SFC] = GATE(HCLK_SFC, "hclk_sfc", "hclk_nvm", 0, RK3588_CLKGATE_CON(31), 10, GFLAGS),
+    [HCLK_SFC_XIP] = GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_nvm", 0, RK3588_CLKGATE_CON(31), 11, GFLAGS),
+    [HCLK_NVM_ROOT] = COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(77), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(31), 0, GFLAGS),
+    [ACLK_NVM_ROOT] = COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(77), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(31), 1, GFLAGS),
+    [CLK_GMAC0_PTP_REF] = COMPOSITE(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", clk_gmac0_ptp_ref_p, 0,
+            RK3588_CLKSEL_CON(81), 6, 1, MFLAGS, 0, 6, DFLAGS,
+            RK3588_CLKGATE_CON(34), 10, GFLAGS),
+    [CLK_GMAC1_PTP_REF] = COMPOSITE(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", clk_gmac1_ptp_ref_p, 0,
+            RK3588_CLKSEL_CON(81), 13, 1, MFLAGS, 7, 6, DFLAGS,
+            RK3588_CLKGATE_CON(34), 11, GFLAGS),
+    [CLK_GMAC_125M] = COMPOSITE(CLK_GMAC_125M, "clk_gmac_125m", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(83), 15, 1, MFLAGS, 8, 7, DFLAGS,
+            RK3588_CLKGATE_CON(35), 5, GFLAGS),
+    [CLK_GMAC_50M] = COMPOSITE(CLK_GMAC_50M, "clk_gmac_50m", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(84), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(35), 6, GFLAGS),
+    [ACLK_PHP_GIC_ITS] = GATE(ACLK_PHP_GIC_ITS, "aclk_php_gic_its", "aclk_pcie_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(34), 6, GFLAGS),
+    [ACLK_MMU_PCIE] = GATE(ACLK_MMU_PCIE, "aclk_mmu_pcie", "aclk_pcie_bridge", 0, RK3588_CLKGATE_CON(34), 7, GFLAGS),
+    [ACLK_MMU_PHP] = GATE(ACLK_MMU_PHP, "aclk_mmu_php", "aclk_php_root", 0, RK3588_CLKGATE_CON(34), 8, GFLAGS),
+    [ACLK_PCIE_4L_DBI] = GATE(ACLK_PCIE_4L_DBI, "aclk_pcie_4l_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(32), 13, GFLAGS),
+    [ACLK_PCIE_2L_DBI] = GATE(ACLK_PCIE_2L_DBI, "aclk_pcie_2l_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(32), 14, GFLAGS),
+    [ACLK_PCIE_1L0_DBI] = GATE(ACLK_PCIE_1L0_DBI, "aclk_pcie_1l0_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(32), 15, GFLAGS),
+    [ACLK_PCIE_1L1_DBI] = GATE(ACLK_PCIE_1L1_DBI, "aclk_pcie_1l1_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 0, GFLAGS),
+    [ACLK_PCIE_1L2_DBI] = GATE(ACLK_PCIE_1L2_DBI, "aclk_pcie_1l2_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 1, GFLAGS),
+    [ACLK_PCIE_4L_MSTR] = GATE(ACLK_PCIE_4L_MSTR, "aclk_pcie_4l_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 2, GFLAGS),
+    [ACLK_PCIE_2L_MSTR] = GATE(ACLK_PCIE_2L_MSTR, "aclk_pcie_2l_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 3, GFLAGS),
+    [ACLK_PCIE_1L0_MSTR] = GATE(ACLK_PCIE_1L0_MSTR, "aclk_pcie_1l0_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 4, GFLAGS),
+    [ACLK_PCIE_1L1_MSTR] = GATE(ACLK_PCIE_1L1_MSTR, "aclk_pcie_1l1_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 5, GFLAGS),
+    [ACLK_PCIE_1L2_MSTR] = GATE(ACLK_PCIE_1L2_MSTR, "aclk_pcie_1l2_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 6, GFLAGS),
+    [ACLK_PCIE_4L_SLV] = GATE(ACLK_PCIE_4L_SLV, "aclk_pcie_4l_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 7, GFLAGS),
+    [ACLK_PCIE_2L_SLV] = GATE(ACLK_PCIE_2L_SLV, "aclk_pcie_2l_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 8, GFLAGS),
+    [ACLK_PCIE_1L0_SLV] = GATE(ACLK_PCIE_1L0_SLV, "aclk_pcie_1l0_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 9, GFLAGS),
+    [ACLK_PCIE_1L1_SLV] = GATE(ACLK_PCIE_1L1_SLV, "aclk_pcie_1l1_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 10, GFLAGS),
+    [ACLK_PCIE_1L2_SLV] = GATE(ACLK_PCIE_1L2_SLV, "aclk_pcie_1l2_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 11, GFLAGS),
+    [PCLK_PCIE_4L] = GATE(PCLK_PCIE_4L, "pclk_pcie_4l", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 12, GFLAGS),
+    [PCLK_PCIE_2L] = GATE(PCLK_PCIE_2L, "pclk_pcie_2l", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 13, GFLAGS),
+    [PCLK_PCIE_1L0] = GATE(PCLK_PCIE_1L0, "pclk_pcie_1l0", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 14, GFLAGS),
+    [PCLK_PCIE_1L1] = GATE(PCLK_PCIE_1L1, "pclk_pcie_1l1", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 15, GFLAGS),
+    [PCLK_PCIE_1L2] = GATE(PCLK_PCIE_1L2, "pclk_pcie_1l2", "pclk_php_root", 0, RK3588_CLKGATE_CON(34), 0, GFLAGS),
+    [CLK_PCIE_AUX0] = GATE(CLK_PCIE_AUX0, "clk_pcie_aux0", "xin24m", 0, RK3588_CLKGATE_CON(34), 1, GFLAGS),
+    [CLK_PCIE_AUX1] = GATE(CLK_PCIE_AUX1, "clk_pcie_aux1", "xin24m", 0, RK3588_CLKGATE_CON(34), 2, GFLAGS),
+    [CLK_PCIE_AUX2] = GATE(CLK_PCIE_AUX2, "clk_pcie_aux2", "xin24m", 0, RK3588_CLKGATE_CON(34), 3, GFLAGS),
+    [CLK_PCIE_AUX3] = GATE(CLK_PCIE_AUX3, "clk_pcie_aux3", "xin24m", 0, RK3588_CLKGATE_CON(34), 4, GFLAGS),
+    [CLK_PCIE_AUX4] = GATE(CLK_PCIE_AUX4, "clk_pcie_aux4", "xin24m", 0, RK3588_CLKGATE_CON(34), 5, GFLAGS),
+    [CLK_PIPEPHY0_REF] = GATE(CLK_PIPEPHY0_REF, "clk_pipephy0_ref", "xin24m", 0, RK3588_CLKGATE_CON(37), 0, GFLAGS),
+    [CLK_PIPEPHY1_REF] = GATE(CLK_PIPEPHY1_REF, "clk_pipephy1_ref", "xin24m", 0, RK3588_CLKGATE_CON(37), 1, GFLAGS),
+    [CLK_PIPEPHY2_REF] = GATE(CLK_PIPEPHY2_REF, "clk_pipephy2_ref", "xin24m", 0, RK3588_CLKGATE_CON(37), 2, GFLAGS),
+    [PCLK_PHP_ROOT] = COMPOSITE_NODIV(PCLK_PHP_ROOT, "pclk_php_root", mux_150m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(80), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(32), 0, GFLAGS),
+    [PCLK_GMAC0] = GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php_root", 0, RK3588_CLKGATE_CON(32), 3, GFLAGS),
+    [PCLK_GMAC1] = GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_php_root", 0, RK3588_CLKGATE_CON(32), 4, GFLAGS),
+    [ACLK_PCIE_ROOT] = COMPOSITE(ACLK_PCIE_ROOT, "aclk_pcie_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(80), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(32), 6, GFLAGS),
+    [ACLK_PHP_ROOT] = COMPOSITE(ACLK_PHP_ROOT, "aclk_php_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(80), 13, 1, MFLAGS, 8, 5, DFLAGS,
+            RK3588_CLKGATE_CON(32), 7, GFLAGS),
+    [ACLK_PCIE_BRIDGE] = GATE(ACLK_PCIE_BRIDGE, "aclk_pcie_bridge", "aclk_pcie_root", 0, RK3588_CLKGATE_CON(32), 8, GFLAGS),
+    [ACLK_GMAC0] = GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(32), 10, GFLAGS),
+    [ACLK_GMAC1] = GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(32), 11, GFLAGS),
+    [CLK_PMALIVE0] = GATE(CLK_PMALIVE0, "clk_pmalive0", "xin24m", 0, RK3588_CLKGATE_CON(37), 4, GFLAGS),
+    [CLK_PMALIVE1] = GATE(CLK_PMALIVE1, "clk_pmalive1", "xin24m", 0, RK3588_CLKGATE_CON(37), 5, GFLAGS),
+    [CLK_PMALIVE2] = GATE(CLK_PMALIVE2, "clk_pmalive2", "xin24m", 0, RK3588_CLKGATE_CON(37), 6, GFLAGS),
+    [ACLK_SATA0] = GATE(ACLK_SATA0, "aclk_sata0", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(37), 7, GFLAGS),
+    [ACLK_SATA1] = GATE(ACLK_SATA1, "aclk_sata1", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(37), 8, GFLAGS),
+    [ACLK_SATA2] = GATE(ACLK_SATA2, "aclk_sata2", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(37), 9, GFLAGS),
+    [CLK_RXOOB0] = COMPOSITE(CLK_RXOOB0, "clk_rxoob0", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(82), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(37), 10, GFLAGS),
+    [CLK_RXOOB1] = COMPOSITE(CLK_RXOOB1, "clk_rxoob1", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(82), 15, 1, MFLAGS, 8, 7, DFLAGS,
+            RK3588_CLKGATE_CON(37), 11, GFLAGS),
+    [CLK_RXOOB2] = COMPOSITE(CLK_RXOOB2, "clk_rxoob2", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(83), 7, 1, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(37), 12, GFLAGS),
+    [ACLK_USB3OTG2] = GATE(ACLK_USB3OTG2, "aclk_usb3otg2", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(35), 7, GFLAGS),
+    [SUSPEND_CLK_USB3OTG2] = GATE(SUSPEND_CLK_USB3OTG2, "suspend_clk_usb3otg2", "xin24m", 0, RK3588_CLKGATE_CON(35), 8, GFLAGS),
+    [REF_CLK_USB3OTG2] = GATE(REF_CLK_USB3OTG2, "ref_clk_usb3otg2", "xin24m", 0, RK3588_CLKGATE_CON(35), 9, GFLAGS),
+    [CLK_UTMI_OTG2] = COMPOSITE(CLK_UTMI_OTG2, "clk_utmi_otg2", mux_150m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(84), 12, 2, MFLAGS, 8, 4, DFLAGS,
+            RK3588_CLKGATE_CON(35), 10, GFLAGS),
+    [CLK_PIPEPHY0_PIPE_G] = GATE(CLK_PIPEPHY0_PIPE_G, "clk_pipephy0_pipe_g", "clk_pipephy0_pipe_i", 0, RK3588_CLKGATE_CON(38), 3, GFLAGS),
+    [CLK_PIPEPHY1_PIPE_G] = GATE(CLK_PIPEPHY1_PIPE_G, "clk_pipephy1_pipe_g", "clk_pipephy1_pipe_i", 0, RK3588_CLKGATE_CON(38), 4, GFLAGS),
+    [CLK_PIPEPHY2_PIPE_G] = GATE(CLK_PIPEPHY2_PIPE_G, "clk_pipephy2_pipe_g", "clk_pipephy2_pipe_i", 0, RK3588_CLKGATE_CON(38), 5, GFLAGS),
+    [CLK_PIPEPHY0_PIPE_ASIC_G] = GATE(CLK_PIPEPHY0_PIPE_ASIC_G, "clk_pipephy0_pipe_asic_g", "clk_pipephy0_pipe_i", 0, RK3588_CLKGATE_CON(38), 6, GFLAGS),
+    [CLK_PIPEPHY1_PIPE_ASIC_G] = GATE(CLK_PIPEPHY1_PIPE_ASIC_G, "clk_pipephy1_pipe_asic_g", "clk_pipephy1_pipe_i", 0, RK3588_CLKGATE_CON(38), 7, GFLAGS),
+    [CLK_PIPEPHY2_PIPE_ASIC_G] = GATE(CLK_PIPEPHY2_PIPE_ASIC_G, "clk_pipephy2_pipe_asic_g", "clk_pipephy2_pipe_i", 0, RK3588_CLKGATE_CON(38), 8, GFLAGS),
+    [CLK_PIPEPHY2_PIPE_U3_G] = GATE(CLK_PIPEPHY2_PIPE_U3_G, "clk_pipephy2_pipe_u3_g", "clk_pipephy2_pipe_i", 0, RK3588_CLKGATE_CON(38), 9, GFLAGS),
+    [CLK_PCIE1L2_PIPE] = GATE(CLK_PCIE1L2_PIPE, "clk_pcie1l2_pipe", "clk_pipephy0_pipe_g", 0, RK3588_CLKGATE_CON(38), 13, GFLAGS),
+    [CLK_PCIE4L_PIPE] = GATE(CLK_PCIE4L_PIPE, "clk_pcie4l_pipe", "clk_pipe30phy_pipe0_i", 0, RK3588_CLKGATE_CON(39), 0, GFLAGS),
+    [CLK_PCIE2L_PIPE] = GATE(CLK_PCIE2L_PIPE, "clk_pcie2l_pipe", "clk_pipe30phy_pipe2_i", 0, RK3588_CLKGATE_CON(39), 1, GFLAGS),
+    [PCLK_PCIE_COMBO_PIPE_PHY0] =  GATE(PCLK_PCIE_COMBO_PIPE_PHY0, "pclk_pcie_combo_pipe_phy0", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 5, GFLAGS),
+    [PCLK_PCIE_COMBO_PIPE_PHY1] =  GATE(PCLK_PCIE_COMBO_PIPE_PHY1, "pclk_pcie_combo_pipe_phy1", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 6, GFLAGS),
+    [PCLK_PCIE_COMBO_PIPE_PHY2] =  GATE(PCLK_PCIE_COMBO_PIPE_PHY2, "pclk_pcie_combo_pipe_phy2", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 7, GFLAGS),
+    [PCLK_PCIE_COMBO_PIPE_PHY] =  GATE(PCLK_PCIE_COMBO_PIPE_PHY, "pclk_pcie_combo_pipe_phy", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 8, GFLAGS),
+    [HCLK_RGA3_1] = GATE(HCLK_RGA3_1, "hclk_rga3_1", "hclk_rga3_root", 0, RK3588_CLKGATE_CON(76), 4, GFLAGS),
+    [ACLK_RGA3_1] = GATE(ACLK_RGA3_1, "aclk_rga3_1", "aclk_rga3_root", 0, RK3588_CLKGATE_CON(76), 5, GFLAGS),
+    [CLK_RGA3_1_CORE] = COMPOSITE(CLK_RGA3_1_CORE, "clk_rga3_1_core", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(174), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(76), 6, GFLAGS),
+    [ACLK_RGA3_ROOT] = COMPOSITE(ACLK_RGA3_ROOT, "aclk_rga3_root", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(174), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(76), 0, GFLAGS),
+    [HCLK_RGA3_ROOT] = COMPOSITE_NODIV(HCLK_RGA3_ROOT, "hclk_rga3_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(174), 7, 2, MFLAGS,
+            RK3588_CLKGATE_CON(76), 1, GFLAGS),
+    [ACLK_RKVDEC_CCU] = COMPOSITE(ACLK_RKVDEC_CCU, "aclk_rkvdec_ccu", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(89), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(40), 2, GFLAGS),
+    [HCLK_RKVDEC0] = GATE(HCLK_RKVDEC0, "hclk_rkvdec0", "hclk_rkvdec0_pre", 0, RK3588_CLKGATE_CON(40), 3, GFLAGS),
+    [ACLK_RKVDEC0] = GATE(ACLK_RKVDEC0, "aclk_rkvdec0", "aclk_rkvdec0_pre", 0, RK3588_CLKGATE_CON(40), 4, GFLAGS),
+    [CLK_RKVDEC0_CA] = COMPOSITE(CLK_RKVDEC0_CA, "clk_rkvdec0_ca", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(90), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(40), 7, GFLAGS),
+    [CLK_RKVDEC0_HEVC_CA] = COMPOSITE(CLK_RKVDEC0_HEVC_CA, "clk_rkvdec0_hevc_ca", gpll_cpll_npll_1000m_p, 0,
+            RK3588_CLKSEL_CON(90), 11, 2, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(40), 8, GFLAGS),
+    [CLK_RKVDEC0_CORE] = COMPOSITE(CLK_RKVDEC0_CORE, "clk_rkvdec0_core", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(91), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(40), 9, GFLAGS),
+    [HCLK_RKVDEC1] = GATE(HCLK_RKVDEC1, "hclk_rkvdec1", "hclk_rkvdec1_pre", 0, RK3588_CLKGATE_CON(41), 2, GFLAGS),
+    [ACLK_RKVDEC1] = GATE(ACLK_RKVDEC1, "aclk_rkvdec1", "aclk_rkvdec1_pre", 0, RK3588_CLKGATE_CON(41), 3, GFLAGS),
+    [CLK_RKVDEC1_CA] = COMPOSITE(CLK_RKVDEC1_CA, "clk_rkvdec1_ca", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(93), 14, 1, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(41), 6, GFLAGS),
+    [CLK_RKVDEC1_HEVC_CA] = COMPOSITE(CLK_RKVDEC1_HEVC_CA, "clk_rkvdec1_hevc_ca", gpll_cpll_npll_1000m_p, 0,
+            RK3588_CLKSEL_CON(94), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(41), 7, GFLAGS),
+    [CLK_RKVDEC1_CORE] = COMPOSITE(CLK_RKVDEC1_CORE, "clk_rkvdec1_core", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(94), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(41), 8, GFLAGS),
+    [HCLK_SDIO] = GATE(HCLK_SDIO, "hclk_sdio", "hclk_sdio_pre", 0, RK3588_CLKGATE_CON(75), 2, GFLAGS),
+    [CCLK_SRC_SDIO] = COMPOSITE(CCLK_SRC_SDIO, "cclk_src_sdio", gpll_cpll_24m_p, 0,
+            RK3588_CLKSEL_CON(172), 8, 2, MFLAGS, 2, 6, DFLAGS,
+            RK3588_CLKGATE_CON(75), 3, GFLAGS),
+    [ACLK_USB_ROOT] = COMPOSITE(ACLK_USB_ROOT, "aclk_usb_root", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(96), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(42), 0, GFLAGS),
+    [HCLK_USB_ROOT] = COMPOSITE_NODIV(HCLK_USB_ROOT, "hclk_usb_root", mux_150m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(96), 6, 2, MFLAGS,
+            RK3588_CLKGATE_CON(42), 1, GFLAGS),
+    [HCLK_HOST0] = GATE(HCLK_HOST0, "hclk_host0", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 10, GFLAGS),
+    [HCLK_HOST_ARB0] = GATE(HCLK_HOST_ARB0, "hclk_host_arb0", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 11, GFLAGS),
+    [HCLK_HOST1] = GATE(HCLK_HOST1, "hclk_host1", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 12, GFLAGS),
+    [HCLK_HOST_ARB1] = GATE(HCLK_HOST_ARB1, "hclk_host_arb1", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 13, GFLAGS),
+    [ACLK_USB3OTG0] = GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb", 0, RK3588_CLKGATE_CON(42), 4, GFLAGS),
+    [SUSPEND_CLK_USB3OTG0] = GATE(SUSPEND_CLK_USB3OTG0, "suspend_clk_usb3otg0", "xin24m", 0, RK3588_CLKGATE_CON(42), 5, GFLAGS),
+    [REF_CLK_USB3OTG0] = GATE(REF_CLK_USB3OTG0, "ref_clk_usb3otg0", "xin24m", 0, RK3588_CLKGATE_CON(42), 6, GFLAGS),
+    [ACLK_USB3OTG1] = GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb", 0, RK3588_CLKGATE_CON(42), 7, GFLAGS),
+    [SUSPEND_CLK_USB3OTG1] = GATE(SUSPEND_CLK_USB3OTG1, "suspend_clk_usb3otg1", "xin24m", 0, RK3588_CLKGATE_CON(42), 8, GFLAGS),
+    [REF_CLK_USB3OTG1] = GATE(REF_CLK_USB3OTG1, "ref_clk_usb3otg1", "xin24m", 0, RK3588_CLKGATE_CON(42), 9, GFLAGS),
+    [HCLK_IEP2P0] = GATE(HCLK_IEP2P0, "hclk_iep2p0", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 4, GFLAGS),
+    [ACLK_IEP2P0] = GATE(ACLK_IEP2P0, "aclk_iep2p0", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(45), 5, GFLAGS),
+    [CLK_IEP2P0_CORE] = COMPOSITE(CLK_IEP2P0_CORE, "clk_iep2p0_core", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(99), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(45), 6, GFLAGS),
+    [ACLK_JPEG_ENCODER0] = GATE(ACLK_JPEG_ENCODER0, "aclk_jpeg_encoder0", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 10, GFLAGS),
+    [HCLK_JPEG_ENCODER0] = GATE(HCLK_JPEG_ENCODER0, "hclk_jpeg_encoder0", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 11, GFLAGS),
+    [ACLK_JPEG_ENCODER1] = GATE(ACLK_JPEG_ENCODER1, "aclk_jpeg_encoder1", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 12, GFLAGS),
+    [HCLK_JPEG_ENCODER1] = GATE(HCLK_JPEG_ENCODER1, "hclk_jpeg_encoder1", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 13, GFLAGS),
+    [ACLK_JPEG_ENCODER2] = GATE(ACLK_JPEG_ENCODER2, "aclk_jpeg_encoder2", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 14, GFLAGS),
+    [HCLK_JPEG_ENCODER2] = GATE(HCLK_JPEG_ENCODER2, "hclk_jpeg_encoder2", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 15, GFLAGS),
+    [ACLK_JPEG_ENCODER3] = GATE(ACLK_JPEG_ENCODER3, "aclk_jpeg_encoder3", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(45), 0, GFLAGS),
+    [HCLK_JPEG_ENCODER3] = GATE(HCLK_JPEG_ENCODER3, "hclk_jpeg_encoder3", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 1, GFLAGS),
+    [ACLK_JPEG_DECODER] = GATE(ACLK_JPEG_DECODER, "aclk_jpeg_decoder", "aclk_jpeg_decoder_pre", 0, RK3588_CLKGATE_CON(45), 2, GFLAGS),
+    [HCLK_JPEG_DECODER] = GATE(HCLK_JPEG_DECODER, "hclk_jpeg_decoder", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 3, GFLAGS),
+    [HCLK_RGA2] = GATE(HCLK_RGA2, "hclk_rga2", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 7, GFLAGS),
+    [ACLK_RGA2] = GATE(ACLK_RGA2, "aclk_rga2", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 8, GFLAGS),
+    [CLK_RGA2_CORE] = COMPOSITE(CLK_RGA2_CORE, "clk_rga2_core", gpll_cpll_npll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(100), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(45), 9, GFLAGS),
+    [HCLK_RGA3_0] = GATE(HCLK_RGA3_0, "hclk_rga3_0", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 10, GFLAGS),
+    [ACLK_RGA3_0] = GATE(ACLK_RGA3_0, "aclk_rga3_0", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 11, GFLAGS),
+    [CLK_RGA3_0_CORE] = COMPOSITE(CLK_RGA3_0_CORE, "clk_rga3_0_core", gpll_cpll_npll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(100), 13, 3, MFLAGS, 8, 5, DFLAGS,
+            RK3588_CLKGATE_CON(45), 12, GFLAGS),
+    [ACLK_VDPU_ROOT] = COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(98), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(44), 0, GFLAGS),
+    [ACLK_VDPU_LOW_ROOT] = COMPOSITE_NODIV(ACLK_VDPU_LOW_ROOT, "aclk_vdpu_low_root", mux_400m_200m_100m_24m_p, 0,
+            RK3588_CLKSEL_CON(98), 7, 2, MFLAGS,
+            RK3588_CLKGATE_CON(44), 1, GFLAGS),
+    [HCLK_VDPU_ROOT] = COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(98), 9, 2, MFLAGS,
+            RK3588_CLKGATE_CON(44), 2, GFLAGS),
+    [ACLK_JPEG_DECODER_ROOT] = COMPOSITE(ACLK_JPEG_DECODER_ROOT, "aclk_jpeg_decoder_root", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(99), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(44), 3, GFLAGS),
+    [ACLK_VPU] = GATE(ACLK_VPU, "aclk_vpu", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 8, GFLAGS),
+    [HCLK_VPU] = GATE(HCLK_VPU, "hclk_vpu", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 9, GFLAGS),
+    [HCLK_RKVENC0_ROOT] = COMPOSITE_NODIV(HCLK_RKVENC0_ROOT, "hclk_rkvenc0_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(102), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(47), 0, GFLAGS),
+    [ACLK_RKVENC0_ROOT] = COMPOSITE(ACLK_RKVENC0_ROOT, "aclk_rkvenc0_root", gpll_cpll_npll_p, 0,
+            RK3588_CLKSEL_CON(102), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(47), 1, GFLAGS),
+    [HCLK_RKVENC0] = GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", 0, RK3588_CLKGATE_CON(47), 4, GFLAGS),
+    [ACLK_RKVENC0] = GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0, RK3588_CLKGATE_CON(47), 5, GFLAGS),
+    [CLK_RKVENC0_CORE] = COMPOSITE(CLK_RKVENC0_CORE, "clk_rkvenc0_core", gpll_cpll_aupll_npll_p, 0,
+            RK3588_CLKSEL_CON(102), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(47), 6, GFLAGS),
+    [HCLK_RKVENC1_ROOT] = COMPOSITE_NODIV(HCLK_RKVENC1_ROOT, "hclk_rkvenc1_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(104), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(48), 0, GFLAGS),
+    [ACLK_RKVENC1_ROOT] = COMPOSITE(ACLK_RKVENC1_ROOT, "aclk_rkvenc1_root", gpll_cpll_npll_p, 0,
+            RK3588_CLKSEL_CON(104), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(48), 1, GFLAGS),
+    [HCLK_RKVENC1] = GATE(HCLK_RKVENC1, "hclk_rkvenc1", "hclk_rkvenc1_pre", 0, RK3588_CLKGATE_CON(48), 4, GFLAGS),
+    [ACLK_RKVENC1] = GATE(ACLK_RKVENC1, "aclk_rkvenc1", "aclk_rkvenc1_pre", 0, RK3588_CLKGATE_CON(48), 5, GFLAGS),
+    [CLK_RKVENC1_CORE] = COMPOSITE(CLK_RKVENC1_CORE, "clk_rkvenc1_core", gpll_cpll_aupll_npll_p, 0,
+            RK3588_CLKSEL_CON(104), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(48), 6, GFLAGS),
+    [ICLK_CSIHOST01] = COMPOSITE_NODIV(ICLK_CSIHOST01, "iclk_csihost01", mux_400m_200m_100m_24m_p, 0,
+            RK3588_CLKSEL_CON(108), 14, 2, MFLAGS,
+            RK3588_CLKGATE_CON(51), 10, GFLAGS),
+    [ICLK_CSIHOST0] = GATE(ICLK_CSIHOST0, "iclk_csihost0", "iclk_csihost01", 0, RK3588_CLKGATE_CON(51), 11, GFLAGS),
+    [ICLK_CSIHOST1] = GATE(ICLK_CSIHOST1, "iclk_csihost1", "iclk_csihost01", 0, RK3588_CLKGATE_CON(51), 12, GFLAGS),
+    [PCLK_CSI_HOST_0] = GATE(PCLK_CSI_HOST_0, "pclk_csi_host_0", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 4, GFLAGS),
+    [PCLK_CSI_HOST_1] = GATE(PCLK_CSI_HOST_1, "pclk_csi_host_1", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 5, GFLAGS),
+    [PCLK_CSI_HOST_2] = GATE(PCLK_CSI_HOST_2, "pclk_csi_host_2", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 6, GFLAGS),
+    [PCLK_CSI_HOST_3] = GATE(PCLK_CSI_HOST_3, "pclk_csi_host_3", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 7, GFLAGS),
+    [PCLK_CSI_HOST_4] = GATE(PCLK_CSI_HOST_4, "pclk_csi_host_4", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 8, GFLAGS),
+    [PCLK_CSI_HOST_5] = GATE(PCLK_CSI_HOST_5, "pclk_csi_host_5", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 9, GFLAGS),
+    [ACLK_FISHEYE0] = GATE(ACLK_FISHEYE0, "aclk_fisheye0", "aclk_vi_root", 0, RK3588_CLKGATE_CON(49), 14, GFLAGS),
+    [HCLK_FISHEYE0] = GATE(HCLK_FISHEYE0, "hclk_fisheye0", "hclk_vi_root", 0, RK3588_CLKGATE_CON(49), 15, GFLAGS),
+    [CLK_FISHEYE0_CORE] = COMPOSITE(CLK_FISHEYE0_CORE, "clk_fisheye0_core", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(108), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(50), 0, GFLAGS),
+    [ACLK_FISHEYE1] = GATE(ACLK_FISHEYE1, "aclk_fisheye1", "aclk_vi_root", 0, RK3588_CLKGATE_CON(50), 1, GFLAGS),
+    [HCLK_FISHEYE1] = GATE(HCLK_FISHEYE1, "hclk_fisheye1", "hclk_vi_root", 0, RK3588_CLKGATE_CON(50), 2, GFLAGS),
+    [CLK_FISHEYE1_CORE] = COMPOSITE(CLK_FISHEYE1_CORE, "clk_fisheye1_core", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(108), 12, 2, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(50), 3, GFLAGS),
+    [CLK_ISP0_CORE] = COMPOSITE(CLK_ISP0_CORE, "clk_isp0_core", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(107), 11, 2, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(49), 9, GFLAGS),
+    [CLK_ISP0_CORE_MARVIN] = GATE(CLK_ISP0_CORE_MARVIN, "clk_isp0_core_marvin", "clk_isp0_core", 0, RK3588_CLKGATE_CON(49), 10, GFLAGS),
+    [CLK_ISP0_CORE_VICAP] = GATE(CLK_ISP0_CORE_VICAP, "clk_isp0_core_vicap", "clk_isp0_core", 0, RK3588_CLKGATE_CON(49), 11, GFLAGS),
+    [ACLK_ISP0] = GATE(ACLK_ISP0, "aclk_isp0", "aclk_vi_root", 0, RK3588_CLKGATE_CON(49), 12, GFLAGS),
+    [HCLK_ISP0] = GATE(HCLK_ISP0, "hclk_isp0", "hclk_vi_root", 0, RK3588_CLKGATE_CON(49), 13, GFLAGS),
+    [ACLK_VI_ROOT] = COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(106), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(49), 0, GFLAGS),
+    [HCLK_VI_ROOT] = COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(106), 8, 2, MFLAGS,
+            RK3588_CLKGATE_CON(49), 1, GFLAGS),
+    [PCLK_VI_ROOT] = COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(106), 10, 2, MFLAGS,
+            RK3588_CLKGATE_CON(49), 2, GFLAGS),
+    [DCLK_VICAP] = COMPOSITE(DCLK_VICAP, "dclk_vicap", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(107), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(49), 6, GFLAGS),
+    [ACLK_VICAP] = GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0, RK3588_CLKGATE_CON(49), 7, GFLAGS),
+    [HCLK_VICAP] = GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0, RK3588_CLKGATE_CON(49), 8, GFLAGS),
+    [PCLK_DP0] = GATE(PCLK_DP0, "pclk_dp0", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 4, GFLAGS),
+    [PCLK_DP1] = GATE(PCLK_DP1, "pclk_dp1", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 5, GFLAGS),
+    [PCLK_S_DP0] = GATE(PCLK_S_DP0, "pclk_s_dp0", "pclk_vo0_s_root", 0, RK3588_CLKGATE_CON(56), 6, GFLAGS),
+    [PCLK_S_DP1] = GATE(PCLK_S_DP1, "pclk_s_dp1", "pclk_vo0_s_root", 0, RK3588_CLKGATE_CON(56), 7, GFLAGS),
+    [CLK_DP0] = GATE(CLK_DP0, "clk_dp0", "aclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 8, GFLAGS),
+    [CLK_DP1] = GATE(CLK_DP1, "clk_dp1", "aclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 9, GFLAGS),
+    [HCLK_HDCP_KEY0] = GATE(HCLK_HDCP_KEY0, "hclk_hdcp_key0", "hclk_vo0_s_root", 0, RK3588_CLKGATE_CON(55), 11, GFLAGS),
+    [ACLK_HDCP0] = GATE(ACLK_HDCP0, "aclk_hdcp0", "aclk_hdcp0_pre", 0, RK3588_CLKGATE_CON(55), 12, GFLAGS),
+    [HCLK_HDCP0] = GATE(HCLK_HDCP0, "hclk_hdcp0", "hclk_vo0", 0, RK3588_CLKGATE_CON(55), 13, GFLAGS),
+    [PCLK_HDCP0] = GATE(PCLK_HDCP0, "pclk_hdcp0", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(55), 14, GFLAGS),
+    [HCLK_I2S4_8CH] = GATE(HCLK_I2S4_8CH, "hclk_i2s4_8ch", "hclk_vo0", 0, RK3588_CLKGATE_CON(56), 10, GFLAGS),
+    [ACLK_TRNG0] = GATE(ACLK_TRNG0, "aclk_trng0", "aclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 0, GFLAGS),
+    [PCLK_TRNG0] = GATE(PCLK_TRNG0, "pclk_trng0", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 1, GFLAGS),
+    [ACLK_VO0_ROOT] = COMPOSITE(ACLK_VO0_ROOT, "aclk_vo0_root", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(116), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(55), 0, GFLAGS),
+    [HCLK_VO0_ROOT] = COMPOSITE_NODIV(HCLK_VO0_ROOT, "hclk_vo0_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(116), 6, 2, MFLAGS,
+            RK3588_CLKGATE_CON(55), 1, GFLAGS),
+    [HCLK_VO0_S_ROOT] = COMPOSITE_NODIV(HCLK_VO0_S_ROOT, "hclk_vo0_s_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(116), 8, 2, MFLAGS,
+            RK3588_CLKGATE_CON(55), 2, GFLAGS),
+    [PCLK_VO0_ROOT] = COMPOSITE_NODIV(PCLK_VO0_ROOT, "pclk_vo0_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(116), 10, 2, MFLAGS,
+            RK3588_CLKGATE_CON(55), 3, GFLAGS),
+    [PCLK_VO0_S_ROOT] = COMPOSITE_NODIV(PCLK_VO0_S_ROOT, "pclk_vo0_s_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(116), 12, 2, MFLAGS,
+            RK3588_CLKGATE_CON(55), 4, GFLAGS),
+    [PCLK_VO0GRF] = GATE(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS),
+    [CLK_I2S4_8CH_TX_SRC] = COMPOSITE(CLK_I2S4_8CH_TX_SRC, "clk_i2s4_8ch_tx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(118), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(56), 11, GFLAGS),
+    [CLK_I2S4_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S4_8CH_TX_FRAC, "clk_i2s4_8ch_tx_frac", "clk_i2s4_8ch_tx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(119), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(56), 12, GFLAGS,
+            &rk3588_i2s4_8ch_tx_fracmux),
+    [MCLK_I2S4_8CH_TX] = GATE(MCLK_I2S4_8CH_TX, "mclk_i2s4_8ch_tx", "clk_i2s4_8ch_tx", 0, RK3588_CLKGATE_CON(56), 13, GFLAGS),
+    [CLK_I2S4_8CH_TX] = &rk3588_i2s4_8ch_tx_fracmux.cell,
+    [HCLK_I2S8_8CH] = GATE(HCLK_I2S8_8CH, "hclk_i2s8_8ch", "hclk_vo0", 0, RK3588_CLKGATE_CON(56), 14, GFLAGS),
+    [CLK_I2S8_8CH_TX_SRC] = COMPOSITE(CLK_I2S8_8CH_TX_SRC, "clk_i2s8_8ch_tx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(120), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(56), 15, GFLAGS),
+    [CLK_I2S8_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S8_8CH_TX_FRAC, "clk_i2s8_8ch_tx_frac", "clk_i2s8_8ch_tx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(121), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(57), 0, GFLAGS,
+            &rk3588_i2s8_8ch_tx_fracmux),
+    [MCLK_I2S8_8CH_TX] = GATE(MCLK_I2S8_8CH_TX, "mclk_i2s8_8ch_tx", "clk_i2s8_8ch_tx", 0, RK3588_CLKGATE_CON(57), 1, GFLAGS),
+    [CLK_I2S8_8CH_TX] = &rk3588_i2s8_8ch_tx_fracmux.cell,
+    [HCLK_SPDIF2_DP0] = GATE(HCLK_SPDIF2_DP0, "hclk_spdif2_dp0", "hclk_vo0", 0, RK3588_CLKGATE_CON(57), 2, GFLAGS),
+    [CLK_SPDIF2_DP0_SRC] = COMPOSITE(CLK_SPDIF2_DP0_SRC, "clk_spdif2_dp0_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(122), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(57), 3, GFLAGS),
+    [CLK_SPDIF2_DP0_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF2_DP0_FRAC, "clk_spdif2_dp0_frac", "clk_spdif2_dp0_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(123), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(57), 4, GFLAGS,
+            &rk3588_spdif2_dp0_fracmux),
+    [MCLK_SPDIF2_DP0] = GATE(MCLK_SPDIF2_DP0, "mclk_spdif2_dp0", "clk_spdif2_dp0", 0, RK3588_CLKGATE_CON(57), 5, GFLAGS),
+    [CLK_SPDIF2_DP0] = &rk3588_spdif2_dp0_fracmux.cell,
+    [MCLK_SPDIF2] = GATE(MCLK_SPDIF2, "mclk_spdif2", "clk_spdif2_dp0", 0, RK3588_CLKGATE_CON(57), 6, GFLAGS),
+    [HCLK_SPDIF5_DP1] = GATE(HCLK_SPDIF5_DP1, "hclk_spdif5_dp1", "hclk_vo0", 0, RK3588_CLKGATE_CON(57), 7, GFLAGS),
+    [CLK_SPDIF5_DP1_SRC] = COMPOSITE(CLK_SPDIF5_DP1_SRC, "clk_spdif5_dp1_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(124), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(57), 8, GFLAGS),
+    [CLK_SPDIF5_DP1_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF5_DP1_FRAC, "clk_spdif5_dp1_frac", "clk_spdif5_dp1_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(125), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(57), 9, GFLAGS,
+            &rk3588_spdif5_dp1_fracmux),
+    [MCLK_SPDIF5_DP1] = GATE(MCLK_SPDIF5_DP1, "mclk_spdif5_dp1", "clk_spdif5_dp1", 0, RK3588_CLKGATE_CON(57), 10, GFLAGS),
+    [CLK_SPDIF5_DP1] = &rk3588_spdif5_dp1_fracmux.cell,
+    [MCLK_SPDIF5] = GATE(MCLK_SPDIF5, "mclk_spdif5", "clk_spdif5_dp1", 0, RK3588_CLKGATE_CON(57), 11, GFLAGS),
+    [PCLK_EDP0] = GATE(PCLK_EDP0, "pclk_edp0", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(62), 0, GFLAGS),
+    [CLK_EDP0_24M] = GATE(CLK_EDP0_24M, "clk_edp0_24m", "xin24m", 0, RK3588_CLKGATE_CON(62), 1, GFLAGS),
+    [CLK_EDP0_200M] = COMPOSITE_NODIV(CLK_EDP0_200M, "clk_edp0_200m", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(140), 1, 2, MFLAGS,
+            RK3588_CLKGATE_CON(62), 2, GFLAGS),
+    [PCLK_EDP1] = GATE(PCLK_EDP1, "pclk_edp1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(62), 3, GFLAGS),
+    [CLK_EDP1_24M] = GATE(CLK_EDP1_24M, "clk_edp1_24m", "xin24m", 0, RK3588_CLKGATE_CON(62), 4, GFLAGS),
+    [CLK_EDP1_200M] = COMPOSITE_NODIV(CLK_EDP1_200M, "clk_edp1_200m", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(140), 3, 2, MFLAGS,
+            RK3588_CLKGATE_CON(62), 5, GFLAGS),
+    [HCLK_HDCP_KEY1] = GATE(HCLK_HDCP_KEY1, "hclk_hdcp_key1", "hclk_vo1_s_root", 0, RK3588_CLKGATE_CON(60), 4, GFLAGS),
+    [ACLK_HDCP1] = GATE(ACLK_HDCP1, "aclk_hdcp1", "aclk_hdcp1_pre", 0, RK3588_CLKGATE_CON(60), 5, GFLAGS),
+    [HCLK_HDCP1] = GATE(HCLK_HDCP1, "hclk_hdcp1", "hclk_vo1", 0, RK3588_CLKGATE_CON(60), 6, GFLAGS),
+    [PCLK_HDCP1] = GATE(PCLK_HDCP1, "pclk_hdcp1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(60), 7, GFLAGS),
+    [ACLK_HDMIRX] = GATE(ACLK_HDMIRX, "aclk_hdmirx", "aclk_hdmirx_root", 0, RK3588_CLKGATE_CON(61), 9, GFLAGS),
+    [PCLK_HDMIRX] = GATE(PCLK_HDMIRX, "pclk_hdmirx", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(61), 10, GFLAGS),
+    [CLK_HDMIRX_REF] = GATE(CLK_HDMIRX_REF, "clk_hdmirx_ref", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(61), 11, GFLAGS),
+    [CLK_HDMIRX_AUD_SRC] = COMPOSITE(CLK_HDMIRX_AUD_SRC, "clk_hdmirx_aud_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(138), 8, 1, MFLAGS, 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(61), 12, GFLAGS),
+    [CLK_HDMIRX_AUD_FRAC] = COMPOSITE_FRACMUX(CLK_HDMIRX_AUD_FRAC, "clk_hdmirx_aud_frac", "clk_hdmirx_aud_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(139), 0,
+            RK3588_CLKGATE_CON(61), 13, GFLAGS,
+            &rk3588_hdmirx_aud_fracmux),
+    [CLK_HDMIRX_AUD] = GATE(CLK_HDMIRX_AUD, "clk_hdmirx_aud", "clk_hdmirx_aud_mux", 0, RK3588_CLKGATE_CON(61), 14, GFLAGS),
+    [CLK_HDMIRX_AUD_P_MUX] = &rk3588_hdmirx_aud_fracmux.cell,
+    [PCLK_HDMITX0] = GATE(PCLK_HDMITX0, "pclk_hdmitx0", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(60), 11, GFLAGS),
+    [CLK_HDMITX0_EARC] = COMPOSITE(CLK_HDMITX0_EARC, "clk_hdmitx0_earc", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(133), 6, 1, MFLAGS, 1, 5, DFLAGS,
+            RK3588_CLKGATE_CON(60), 15, GFLAGS),
+    [CLK_HDMITX0_REF] = GATE(CLK_HDMITX0_REF, "clk_hdmitx0_ref", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(61), 0, GFLAGS),
+    [PCLK_HDMITX1] = GATE(PCLK_HDMITX1, "pclk_hdmitx1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(61), 2, GFLAGS),
+    [CLK_HDMITX1_EARC] = COMPOSITE(CLK_HDMITX1_EARC, "clk_hdmitx1_earc", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(136), 6, 1, MFLAGS, 1, 5, DFLAGS,
+            RK3588_CLKGATE_CON(61), 6, GFLAGS),
+    [CLK_HDMITX1_REF] = GATE(CLK_HDMITX1_REF, "clk_hdmitx1_ref", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(61), 7, GFLAGS),
+    [CLK_HDMITRX_REFSRC] = COMPOSITE_HALFDIV(CLK_HDMITRX_REFSRC, "clk_hdmitrx_refsrc", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(157), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(65), 9, GFLAGS),
+    [ACLK_TRNG1] = GATE(ACLK_TRNG1, "aclk_trng1", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(60), 9, GFLAGS),
+    [PCLK_TRNG1] = GATE(PCLK_TRNG1, "pclk_trng1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(60), 10, GFLAGS),
+    [ACLK_HDCP1_ROOT] = COMPOSITE(ACLK_HDCP1_ROOT, "aclk_hdcp1_root", aclk_hdcp1_root_p, 0,
+            RK3588_CLKSEL_CON(128), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(59), 0, GFLAGS),
+    [ACLK_HDMIRX_ROOT] = COMPOSITE(ACLK_HDMIRX_ROOT, "aclk_hdmirx_root", gpll_cpll_p, 0,
+            RK3588_CLKSEL_CON(128), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(59), 1, GFLAGS),
+    [HCLK_VO1_ROOT] = COMPOSITE_NODIV(HCLK_VO1_ROOT, "hclk_vo1_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(128), 13, 2, MFLAGS,
+            RK3588_CLKGATE_CON(59), 2, GFLAGS),
+    [HCLK_VO1_S_ROOT] = COMPOSITE_NODIV(HCLK_VO1_S_ROOT, "hclk_vo1_s_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(129), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(59), 3, GFLAGS),
+    [PCLK_VO1_ROOT] = COMPOSITE_NODIV(PCLK_VO1_ROOT, "pclk_vo1_root", mux_150m_100m_24m_p, 0,
+            RK3588_CLKSEL_CON(129), 2, 2, MFLAGS,
+            RK3588_CLKGATE_CON(59), 4, GFLAGS),
+    [PCLK_VO1_S_ROOT] = COMPOSITE_NODIV(PCLK_VO1_S_ROOT, "pclk_vo1_s_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(129), 4, 2, MFLAGS,
+            RK3588_CLKGATE_CON(59), 5, GFLAGS),
+    [PCLK_S_EDP0] = GATE(PCLK_S_EDP0, "pclk_s_edp0", "pclk_vo1_s_root", 0, RK3588_CLKGATE_CON(59), 14, GFLAGS),
+    [PCLK_S_EDP1] = GATE(PCLK_S_EDP1, "pclk_s_edp1", "pclk_vo1_s_root", 0, RK3588_CLKGATE_CON(59), 15, GFLAGS),
+    [PCLK_S_HDMIRX] = GATE(PCLK_S_HDMIRX, "pclk_s_hdmirx", "pclk_vo1_s_root", 0, RK3588_CLKGATE_CON(65), 8, GFLAGS),
+    [HCLK_I2S10_8CH] = GATE(HCLK_I2S10_8CH, "hclk_i2s10_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(65), 4, GFLAGS),
+    [CLK_I2S10_8CH_RX_SRC] = COMPOSITE(CLK_I2S10_8CH_RX_SRC, "clk_i2s10_8ch_rx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(155), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(65), 5, GFLAGS),
+    [CLK_I2S10_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S10_8CH_RX_FRAC, "clk_i2s10_8ch_rx_frac", "clk_i2s10_8ch_rx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(156), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(65), 6, GFLAGS,
+            &rk3588_i2s10_8ch_rx_fracmux),
+    [CLK_I2S10_8CH_RX] = &rk3588_i2s10_8ch_rx_fracmux.cell,
+    [MCLK_I2S10_8CH_RX] = GATE(MCLK_I2S10_8CH_RX, "mclk_i2s10_8ch_rx", "clk_i2s10_8ch_rx", 0, RK3588_CLKGATE_CON(65), 7, GFLAGS),
+    [HCLK_I2S7_8CH] = GATE(HCLK_I2S7_8CH, "hclk_i2s7_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(60), 0, GFLAGS),
+    [CLK_I2S7_8CH_RX_SRC] = COMPOSITE(CLK_I2S7_8CH_RX_SRC, "clk_i2s7_8ch_rx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(129), 11, 1, MFLAGS, 6, 5, DFLAGS,
+            RK3588_CLKGATE_CON(60), 1, GFLAGS),
+    [CLK_I2S7_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S7_8CH_RX_FRAC, "clk_i2s7_8ch_rx_frac", "clk_i2s7_8ch_rx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(130), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(60), 2, GFLAGS,
+            &rk3588_i2s7_8ch_rx_fracmux),
+    [CLK_I2S7_8CH_RX] = &rk3588_i2s7_8ch_rx_fracmux.cell,
+    [MCLK_I2S7_8CH_RX] = GATE(MCLK_I2S7_8CH_RX, "mclk_i2s7_8ch_rx", "clk_i2s7_8ch_rx", 0, RK3588_CLKGATE_CON(60), 3, GFLAGS),
+    [HCLK_I2S9_8CH] = GATE(HCLK_I2S9_8CH, "hclk_i2s9_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(65), 0, GFLAGS),
+    [CLK_I2S9_8CH_RX_SRC] = COMPOSITE(CLK_I2S9_8CH_RX_SRC, "clk_i2s9_8ch_rx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(153), 12, 1, MFLAGS, 7, 5, DFLAGS,
+            RK3588_CLKGATE_CON(65), 1, GFLAGS),
+    [CLK_I2S9_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S9_8CH_RX_FRAC, "clk_i2s9_8ch_rx_frac", "clk_i2s9_8ch_rx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(154), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(65), 2, GFLAGS,
+            &rk3588_i2s9_8ch_rx_fracmux),
+    [CLK_I2S9_8CH_RX] = &rk3588_i2s9_8ch_rx_fracmux.cell,
+    [MCLK_I2S9_8CH_RX] = GATE(MCLK_I2S9_8CH_RX, "mclk_i2s9_8ch_rx", "clk_i2s9_8ch_rx", 0, RK3588_CLKGATE_CON(65), 3, GFLAGS),
+    [CLK_I2S5_8CH_TX_SRC] = COMPOSITE(CLK_I2S5_8CH_TX_SRC, "clk_i2s5_8ch_tx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(140), 10, 1, MFLAGS, 5, 5, DFLAGS,
+            RK3588_CLKGATE_CON(62), 6, GFLAGS),
+    [CLK_I2S5_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S5_8CH_TX_FRAC, "clk_i2s5_8ch_tx_frac", "clk_i2s5_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(141), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(62), 7, GFLAGS,
+            &rk3588_i2s5_8ch_tx_fracmux),
+    [CLK_I2S5_8CH_TX] = &rk3588_i2s5_8ch_tx_fracmux.cell,
+    [MCLK_I2S5_8CH_TX] = GATE(MCLK_I2S5_8CH_TX, "mclk_i2s5_8ch_tx", "clk_i2s5_8ch_tx", 0, RK3588_CLKGATE_CON(62), 8, GFLAGS),
+    [HCLK_I2S5_8CH] = GATE(HCLK_I2S5_8CH, "hclk_i2s5_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(62), 12, GFLAGS),
+    [CLK_I2S6_8CH_TX_SRC] = COMPOSITE(CLK_I2S6_8CH_TX_SRC, "clk_i2s6_8ch_tx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(144), 8, 1, MFLAGS, 3, 5, DFLAGS,
+            RK3588_CLKGATE_CON(62), 13, GFLAGS),
+    [CLK_I2S6_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S6_8CH_TX_FRAC, "clk_i2s6_8ch_tx_frac", "clk_i2s6_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(145), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(62), 14, GFLAGS,
+            &rk3588_i2s6_8ch_tx_fracmux),
+    [CLK_I2S6_8CH_TX] = &rk3588_i2s6_8ch_tx_fracmux.cell,
+    [MCLK_I2S6_8CH_TX] = GATE(MCLK_I2S6_8CH_TX, "mclk_i2s6_8ch_tx", "clk_i2s6_8ch_tx", 0, RK3588_CLKGATE_CON(62), 15, GFLAGS),
+    [CLK_I2S6_8CH_RX_SRC] = COMPOSITE(CLK_I2S6_8CH_RX_SRC, "clk_i2s6_8ch_rx_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(146), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(63), 0, GFLAGS),
+    [CLK_I2S6_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S6_8CH_RX_FRAC, "clk_i2s6_8ch_rx_frac", "clk_i2s6_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(147), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(63), 1, GFLAGS,
+            &rk3588_i2s6_8ch_rx_fracmux),
+    [CLK_I2S6_8CH_RX] = &rk3588_i2s6_8ch_rx_fracmux.cell,
+    [MCLK_I2S6_8CH_RX] = GATE(MCLK_I2S6_8CH_RX, "mclk_i2s6_8ch_rx", "clk_i2s6_8ch_rx", 0, RK3588_CLKGATE_CON(63), 2, GFLAGS),
+    [I2S6_8CH_MCLKOUT] = MUX(I2S6_8CH_MCLKOUT, "i2s6_8ch_mclkout", i2s6_8ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(148), 2, 2, MFLAGS),
+    [HCLK_I2S6_8CH] = GATE(HCLK_I2S6_8CH, "hclk_i2s6_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 3, GFLAGS),
+    [HCLK_SPDIF3] = GATE(HCLK_SPDIF3, "hclk_spdif3", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 4, GFLAGS),
+    [CLK_SPDIF3_SRC] = COMPOSITE(CLK_SPDIF3_SRC, "clk_spdif3_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(148), 9, 1, MFLAGS, 4, 5, DFLAGS,
+            RK3588_CLKGATE_CON(63), 5, GFLAGS),
+    [CLK_SPDIF3_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF3_FRAC, "clk_spdif3_frac", "clk_spdif3_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(149), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(63), 6, GFLAGS,
+            &rk3588_spdif3_fracmux),
+    [CLK_SPDIF3] = &rk3588_spdif3_fracmux.cell,
+    [MCLK_SPDIF3] = GATE(MCLK_SPDIF3, "mclk_spdif3", "clk_spdif3", 0, RK3588_CLKGATE_CON(63), 7, GFLAGS),
+    [HCLK_SPDIF4] = GATE(HCLK_SPDIF4, "hclk_spdif4", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 8, GFLAGS),
+    [CLK_SPDIF4_SRC] = COMPOSITE(CLK_SPDIF4_SRC, "clk_spdif4_src", gpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(150), 7, 1, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(63), 9, GFLAGS),
+    [CLK_SPDIF4_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF4_FRAC, "clk_spdif4_frac", "clk_spdif4_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(151), CLK_MUX_ROUND_CLOSEST,
+            RK3588_CLKGATE_CON(63), 10, GFLAGS,
+            &rk3588_spdif4_fracmux),
+    [CLK_SPDIF4] = &rk3588_spdif4_fracmux.cell,
+    [MCLK_SPDIF4] = GATE(MCLK_SPDIF4, "mclk_spdif4", "clk_spdif4", 0, RK3588_CLKGATE_CON(63), 11, GFLAGS),
+    [HCLK_SPDIFRX0] = GATE(HCLK_SPDIFRX0, "hclk_spdifrx0", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 12, GFLAGS),
+    [MCLK_SPDIFRX0] = COMPOSITE(MCLK_SPDIFRX0, "mclk_spdifrx0", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(152), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(63), 13, GFLAGS),
+    [HCLK_SPDIFRX1] = GATE(HCLK_SPDIFRX1, "hclk_spdifrx1", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 14, GFLAGS),
+    [MCLK_SPDIFRX1] = COMPOSITE(MCLK_SPDIFRX1, "mclk_spdifrx1", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(152), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(63), 15, GFLAGS),
+    [HCLK_SPDIFRX2] = GATE(HCLK_SPDIFRX2, "hclk_spdifrx2", "hclk_vo1", 0, RK3588_CLKGATE_CON(64), 0, GFLAGS),
+    [MCLK_SPDIFRX2] = COMPOSITE(MCLK_SPDIFRX2, "mclk_spdifrx2", gpll_cpll_aupll_p, 0,
+            RK3588_CLKSEL_CON(153), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(64), 1, GFLAGS),
+    [ACLK_VO1USB_TOP_ROOT] = COMPOSITE(ACLK_VO1USB_TOP_ROOT, "aclk_vo1usb_top_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(170), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(74), 0, GFLAGS),
+    [HCLK_VO1USB_TOP_ROOT] = COMPOSITE_NODIV(HCLK_VO1USB_TOP_ROOT, "hclk_vo1usb_top_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_CLKSEL_CON(170), 6, 2, MFLAGS,
+            RK3588_CLKGATE_CON(74), 2, GFLAGS),
+    [CLK_HDMIHDP0] = GATE(CLK_HDMIHDP0, "clk_hdmihdp0", "xin24m", 0, RK3588_CLKGATE_CON(73), 12, GFLAGS),
+    [CLK_HDMIHDP1] = GATE(CLK_HDMIHDP1, "clk_hdmihdp1", "xin24m", 0, RK3588_CLKGATE_CON(73), 13, GFLAGS),
+    [PCLK_HDPTX0] = GATE(PCLK_HDPTX0, "pclk_hdptx0", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 5, GFLAGS),
+    [PCLK_HDPTX1] = GATE(PCLK_HDPTX1, "pclk_hdptx1", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 6, GFLAGS),
+    [PCLK_USBDPPHY0] = GATE(PCLK_USBDPPHY0, "pclk_usbdpphy0", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 2, GFLAGS),
+    [PCLK_USBDPPHY1] = GATE(PCLK_USBDPPHY1, "pclk_usbdpphy1", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 4, GFLAGS),
+    [ACLK_VOP_ROOT] = COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_dmyaupll_npll_spll_p, 0,
+            RK3588_CLKSEL_CON(110), 5, 3, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(52), 0, GFLAGS),
+    [ACLK_VOP_LOW_ROOT] = COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, 0,
+            RK3588_CLKSEL_CON(110), 8, 2, MFLAGS,
+            RK3588_CLKGATE_CON(52), 1, GFLAGS),
+    [HCLK_VOP_ROOT] = COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(110), 10, 2, MFLAGS,
+            RK3588_CLKGATE_CON(52), 2, GFLAGS),
+    [PCLK_VOP_ROOT] = COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(110), 12, 2, MFLAGS,
+            RK3588_CLKGATE_CON(52), 3, GFLAGS),
+    [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", 0, RK3588_CLKGATE_CON(52), 8, GFLAGS),
+    [ACLK_VOP] = COMPOSITE_NODIV(ACLK_VOP, "aclk_vop", aclk_vop_sub_src_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(115), 9, 1, MFLAGS,
+            RK3588_CLKGATE_CON(52), 9, GFLAGS),
+    [DCLK_VOP0_SRC] = COMPOSITE(DCLK_VOP0_SRC, "dclk_vop0_src", gpll_cpll_v0pll_aupll_p, 0,
+            RK3588_CLKSEL_CON(111), 7, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(52), 10, GFLAGS),
+    [DCLK_VOP1_SRC] = COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, 0,
+            RK3588_CLKSEL_CON(111), 14, 2, MFLAGS, 9, 5, DFLAGS,
+            RK3588_CLKGATE_CON(52), 11, GFLAGS),
+    [DCLK_VOP2_SRC] = COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, 0,
+            RK3588_CLKSEL_CON(112), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_CLKGATE_CON(52), 12, GFLAGS),
+    [DCLK_VOP0] = COMPOSITE_NODIV(DCLK_VOP0, "dclk_vop0", dclk_vop0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(112), 7, 2, MFLAGS,
+            RK3588_CLKGATE_CON(52), 13, GFLAGS),
+    [DCLK_VOP1] = COMPOSITE_NODIV(DCLK_VOP1, "dclk_vop1", dclk_vop1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(112), 9, 2, MFLAGS,
+            RK3588_CLKGATE_CON(53), 0, GFLAGS),
+    [DCLK_VOP2] = COMPOSITE_NODIV(DCLK_VOP2, "dclk_vop2", dclk_vop2_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(112), 11, 2, MFLAGS,
+            RK3588_CLKGATE_CON(53), 1, GFLAGS),
+    [DCLK_VOP3] = COMPOSITE(DCLK_VOP3, "dclk_vop3", gpll_cpll_v0pll_aupll_p, 0,
+            RK3588_CLKSEL_CON(113), 7, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(53), 2, GFLAGS),
+    [PCLK_DSIHOST0] = GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vop_root", 0, RK3588_CLKGATE_CON(53), 4, GFLAGS),
+    [PCLK_DSIHOST1] = GATE(PCLK_DSIHOST1, "pclk_dsihost1", "pclk_vop_root", 0, RK3588_CLKGATE_CON(53), 5, GFLAGS),
+    [CLK_DSIHOST0] = COMPOSITE(CLK_DSIHOST0, "clk_dsihost0", gpll_cpll_v0pll_spll_p, 0,
+            RK3588_CLKSEL_CON(114), 7, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(53), 6, GFLAGS),
+    [CLK_DSIHOST1] = COMPOSITE(CLK_DSIHOST1, "clk_dsihost1", gpll_cpll_v0pll_spll_p, 0,
+            RK3588_CLKSEL_CON(115), 7, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3588_CLKGATE_CON(53), 7, GFLAGS),
+    [CLK_VOP_PMU] = GATE(CLK_VOP_PMU, "clk_vop_pmu", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(53), 8, GFLAGS),
+    [ACLK_VOP_DOBY] = GATE(ACLK_VOP_DOBY, "aclk_vop_doby", "aclk_vop_root", 0, RK3588_CLKGATE_CON(53), 10, GFLAGS),
+    [ACLK_VOP_DIV2_SRC] = FACTOR(ACLK_VOP_DIV2_SRC, "aclk_vop_div2_src", "aclk_vop_root", 0, 1, 2),
+    [CLK_USBDP_PHY0_IMMORTAL] = GATE(CLK_USBDP_PHY0_IMMORTAL, "clk_usbdp_phy0_immortal", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(2), 8, GFLAGS),
+    [CLK_USBDP_PHY1_IMMORTAL] = GATE(CLK_USBDP_PHY1_IMMORTAL, "clk_usbdp_phy1_immortal", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(2), 15, GFLAGS),
+    [CLK_PMU0] = GATE(CLK_PMU0, "clk_pmu0", "xin24m", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 1, GFLAGS),
+    [PCLK_PMU0] = GATE(PCLK_PMU0, "pclk_pmu0", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 2, GFLAGS),
+    [PCLK_PMU0IOC] = GATE(PCLK_PMU0IOC, "pclk_pmu0ioc", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 4, GFLAGS),
+    [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(5), 5, GFLAGS),
+    [DBCLK_GPIO0] = COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", mux_24m_32k_p, 0,
+            RK3588_PMU_CLKSEL_CON(17), 0, 1, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(5), 6, GFLAGS),
+    [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(2), 1, GFLAGS),
+    [CLK_I2C0] = COMPOSITE_NODIV(CLK_I2C0, "clk_i2c0", pmu_200m_100m_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(3), 6, 1, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(2), 2, GFLAGS),
+    [HCLK_I2S1_8CH] = GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_pmu1_root", 0, RK3588_PMU_CLKGATE_CON(2), 7, GFLAGS),
+    [CLK_I2S1_8CH_TX_SRC] = COMPOSITE_NOMUX(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", "cpll", 0,
+            RK3588_PMU_CLKSEL_CON(5), 2, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(2), 8, GFLAGS),
+    [CLK_I2S1_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_PMU_CLKSEL_CON(6), CLK_MUX_ROUND_CLOSEST,
+            RK3588_PMU_CLKGATE_CON(2), 9, GFLAGS,
+            &rk3588_i2s1_8ch_tx_fracmux),
+    [CLK_I2S1_8CH_TX] = &rk3588_i2s1_8ch_tx_fracmux.cell,
+    [MCLK_I2S1_8CH_TX] = GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 0, RK3588_PMU_CLKGATE_CON(2), 10, GFLAGS),
+    [CLK_I2S1_8CH_RX_SRC] = COMPOSITE_NOMUX(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", "cpll", 0,
+            RK3588_PMU_CLKSEL_CON(7), 2, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(2), 11, GFLAGS),
+    [CLK_I2S1_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src",
+            RT_CLK_F_SET_RATE_PARENT,
+            RK3588_PMU_CLKSEL_CON(8), CLK_MUX_ROUND_CLOSEST,
+            RK3588_PMU_CLKGATE_CON(2), 12, GFLAGS,
+            &rk3588_i2s1_8ch_rx_fracmux),
+    [CLK_I2S1_8CH_RX] = &rk3588_i2s1_8ch_rx_fracmux.cell,
+    [MCLK_I2S1_8CH_RX] = GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 0, RK3588_PMU_CLKGATE_CON(2), 13, GFLAGS),
+    [I2S1_8CH_MCLKOUT] = MUX(I2S1_8CH_MCLKOUT, "i2s1_8ch_mclkout", i2s1_8ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_PMU_CLKSEL_CON(9), 2, 2, MFLAGS),
+    [CLK_PMU1_50M_SRC] = COMPOSITE_NOMUX(CLK_PMU1_50M_SRC, "clk_pmu1_50m_src", "clk_pmu1_400m_src", 0,
+            RK3588_PMU_CLKSEL_CON(0), 0, 4, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 0, GFLAGS),
+    [CLK_PMU1_100M_SRC] = COMPOSITE_NOMUX(CLK_PMU1_100M_SRC, "clk_pmu1_100m_src", "clk_pmu1_400m_src", 0,
+            RK3588_PMU_CLKSEL_CON(0), 4, 3, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 1, GFLAGS),
+    [CLK_PMU1_200M_SRC] = COMPOSITE_NOMUX(CLK_PMU1_200M_SRC, "clk_pmu1_200m_src", "clk_pmu1_400m_src", 0,
+            RK3588_PMU_CLKSEL_CON(0), 7, 3, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 2, GFLAGS),
+    [CLK_PMU1_300M_SRC] = COMPOSITE(CLK_PMU1_300M_SRC, "clk_pmu1_300m_src", pmu_300m_24m_p, 0,
+            RK3588_PMU_CLKSEL_CON(0), 15, 1, MFLAGS, 10, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 3, GFLAGS),
+    [CLK_PMU1_400M_SRC] = COMPOSITE(CLK_PMU1_400M_SRC, "clk_pmu1_400m_src", pmu_400m_24m_p, 0,
+            RK3588_PMU_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 4, GFLAGS),
+    [HCLK_PMU1_ROOT] = COMPOSITE_NODIV(HCLK_PMU1_ROOT, "hclk_pmu1_root", hclk_pmu1_root_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(1), 6, 2, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 5, GFLAGS),
+    [PCLK_PMU1_ROOT] = COMPOSITE_NODIV(PCLK_PMU1_ROOT, "pclk_pmu1_root", pmu_100m_50m_24m_src_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(1), 8, 2, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 7, GFLAGS),
+    [PCLK_PMU0_ROOT] = GATE(PCLK_PMU0_ROOT, "pclk_pmu0_root", "pclk_pmu1_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 0, GFLAGS),
+    [HCLK_PMU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_PMU_CM0_ROOT, "hclk_pmu_cm0_root", hclk_pmu_cm0_root_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(1), 10, 2, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 8, GFLAGS),
+    [PCLK_PMU1] = GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(1), 0, GFLAGS),
+    [CLK_DDR_FAIL_SAFE] = GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu0", RT_CLK_F_IGNORE_UNUSED, RK3588_PMU_CLKGATE_CON(1), 1, GFLAGS),
+    [CLK_PMU1] = GATE(CLK_PMU1, "clk_pmu1", "clk_pmu0", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(1), 3, GFLAGS),
+    [HCLK_PDM0] = GATE(HCLK_PDM0, "hclk_pdm0", "hclk_pmu1_root", 0, RK3588_PMU_CLKGATE_CON(2), 14, GFLAGS),
+    [MCLK_PDM0] = COMPOSITE_NODIV(MCLK_PDM0, "mclk_pdm0", mclk_pdm0_p, 0,
+            RK3588_PMU_CLKSEL_CON(9), 4, 1, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(2), 15, GFLAGS),
+    [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_pmu1_root", 0, RK3588_PMU_CLKGATE_CON(3), 0, GFLAGS),
+    [FCLK_PMU_CM0_CORE] = GATE(FCLK_PMU_CM0_CORE, "fclk_pmu_cm0_core", "hclk_pmu_cm0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(0), 13, GFLAGS),
+    [CLK_PMU_CM0_RTC] = COMPOSITE(CLK_PMU_CM0_RTC, "clk_pmu_cm0_rtc", mux_24m_32k_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(0), 15, GFLAGS),
+    [PCLK_PMU1_IOC] = GATE(PCLK_PMU1_IOC, "pclk_pmu1_ioc", "pclk_pmu0_root", RT_CLK_F_IGNORE_UNUSED, RK3588_PMU_CLKGATE_CON(1), 5, GFLAGS),
+    [PCLK_PMU1PWM] = GATE(PCLK_PMU1PWM, "pclk_pmu1pwm", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(1), 12, GFLAGS),
+    [CLK_PMU1PWM] = COMPOSITE_NODIV(CLK_PMU1PWM, "clk_pmu1pwm", pmu_100m_50m_24m_src_p, 0,
+            RK3588_PMU_CLKSEL_CON(2), 9, 2, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(1), 13, GFLAGS),
+    [CLK_PMU1PWM_CAPTURE] = GATE(CLK_PMU1PWM_CAPTURE, "clk_pmu1pwm_capture", "xin24m", 0, RK3588_PMU_CLKGATE_CON(1), 14, GFLAGS),
+    [PCLK_PMU1TIMER] = GATE(PCLK_PMU1TIMER, "pclk_pmu1timer", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(1), 8, GFLAGS),
+    [CLK_PMU1TIMER_ROOT] = COMPOSITE_NODIV(CLK_PMU1TIMER_ROOT, "clk_pmu1timer_root", pmu_24m_32k_100m_src_p, 0,
+            RK3588_PMU_CLKSEL_CON(2), 7, 2, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(1), 9, GFLAGS),
+    [CLK_PMU1TIMER0] = GATE(CLK_PMU1TIMER0, "clk_pmu1timer0", "clk_pmu1timer_root", 0, RK3588_PMU_CLKGATE_CON(1), 10, GFLAGS),
+    [CLK_PMU1TIMER1] = GATE(CLK_PMU1TIMER1, "clk_pmu1timer1", "clk_pmu1timer_root", 0, RK3588_PMU_CLKGATE_CON(1), 11, GFLAGS),
+    [CLK_UART0_SRC] = COMPOSITE_NOMUX(CLK_UART0_SRC, "clk_uart0_src", "cpll", 0,
+            RK3588_PMU_CLKSEL_CON(3), 7, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(2), 3, GFLAGS),
+    [CLK_UART0_FRAC] = COMPOSITE_FRACMUX(CLK_UART0_FRAC, "clk_uart0_frac", "clk_uart0_src", RT_CLK_F_SET_RATE_PARENT,
+            RK3588_PMU_CLKSEL_CON(4), CLK_FRAC_DIVIDER_NO_LIMIT,
+            RK3588_PMU_CLKGATE_CON(2), 4, GFLAGS,
+            &rk3588_uart0_fracmux),
+    [CLK_UART0] = &rk3588_uart0_fracmux.cell,
+    [SCLK_UART0] = GATE(SCLK_UART0, "sclk_uart0", "clk_uart0", 0, RK3588_PMU_CLKGATE_CON(2), 5, GFLAGS),
+    [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(2), 6, GFLAGS),
+    [PCLK_PMU1WDT] = GATE(PCLK_PMU1WDT, "pclk_pmu1wdt", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(1), 6, GFLAGS),
+    [TCLK_PMU1WDT] = COMPOSITE_NODIV(TCLK_PMU1WDT, "tclk_pmu1wdt", mux_24m_32k_p, 0,
+            RK3588_PMU_CLKSEL_CON(2), 6, 1, MFLAGS,
+            RK3588_PMU_CLKGATE_CON(1), 7, GFLAGS),
+    [CLK_CR_PARA] = COMPOSITE(CLK_CR_PARA, "clk_cr_para", mux_24m_ppll_spll_p, 0,
+            RK3588_PMU_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(4), 11, GFLAGS),
+    [CLK_USB2PHY_HDPTXRXPHY_REF] = COMPOSITE(CLK_USB2PHY_HDPTXRXPHY_REF, "clk_usb2phy_hdptxrxphy_ref", mux_24m_ppll_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(14), 14, 1, MFLAGS, 9, 5, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(4), 7, GFLAGS),
+    [CLK_USBDPPHY_MIPIDCPPHY_REF] = COMPOSITE(CLK_USBDPPHY_MIPIDCPPHY_REF, "clk_usbdpphy_mipidcpphy_ref", mux_24m_ppll_spll_p,
+            RT_CLK_F_IS_CRITICAL,
+            RK3588_PMU_CLKSEL_CON(14), 7, 2, MFLAGS, 0, 7, DFLAGS,
+            RK3588_PMU_CLKGATE_CON(4), 3, GFLAGS),
+    [CLK_REF_PIPE_PHY0_OSC_SRC] = GATE(CLK_REF_PIPE_PHY0_OSC_SRC, "clk_ref_pipe_phy0_osc_src", "xin24m", 0, RK3588_CLKGATE_CON(77), 0, GFLAGS),
+    [CLK_REF_PIPE_PHY1_OSC_SRC] = GATE(CLK_REF_PIPE_PHY1_OSC_SRC, "clk_ref_pipe_phy1_osc_src", "xin24m", 0, RK3588_CLKGATE_CON(77), 1, GFLAGS),
+    [CLK_REF_PIPE_PHY2_OSC_SRC] = GATE(CLK_REF_PIPE_PHY2_OSC_SRC, "clk_ref_pipe_phy2_osc_src", "xin24m", 0, RK3588_CLKGATE_CON(77), 2, GFLAGS),
+    [CLK_REF_PIPE_PHY0_PLL_SRC] = COMPOSITE_NOMUX(CLK_REF_PIPE_PHY0_PLL_SRC, "clk_ref_pipe_phy0_pll_src", "ppll", 0,
+            RK3588_CLKSEL_CON(176), 0, 6, DFLAGS,
+            RK3588_CLKGATE_CON(77), 3, GFLAGS),
+    [CLK_REF_PIPE_PHY1_PLL_SRC] = COMPOSITE_NOMUX(CLK_REF_PIPE_PHY1_PLL_SRC, "clk_ref_pipe_phy1_pll_src", "ppll", 0,
+            RK3588_CLKSEL_CON(176), 6, 6, DFLAGS,
+            RK3588_CLKGATE_CON(77), 4, GFLAGS),
+    [CLK_REF_PIPE_PHY2_PLL_SRC] = COMPOSITE_NOMUX(CLK_REF_PIPE_PHY2_PLL_SRC, "clk_ref_pipe_phy2_pll_src", "ppll", 0,
+            RK3588_CLKSEL_CON(177), 0, 6, DFLAGS,
+            RK3588_CLKGATE_CON(77), 5, GFLAGS),
+    [CLK_REF_PIPE_PHY0] = MUX(CLK_REF_PIPE_PHY0, "clk_ref_pipe_phy0", clk_ref_pipe_phy0_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(177), 6, 1, MFLAGS),
+    [CLK_REF_PIPE_PHY1] = MUX(CLK_REF_PIPE_PHY1, "clk_ref_pipe_phy1", clk_ref_pipe_phy1_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(177), 7, 1, MFLAGS),
+    [CLK_REF_PIPE_PHY2] = MUX(CLK_REF_PIPE_PHY2, "clk_ref_pipe_phy2", clk_ref_pipe_phy2_p, RT_CLK_F_SET_RATE_PARENT,
+            RK3588_CLKSEL_CON(177), 8, 1, MFLAGS),
+    [SCLK_SDIO_DRV] = MMC(SCLK_SDIO_DRV, "sdio_drv", "cclk_src_sdio", RK3588_SDIO_CON0, 1),
+    [SCLK_SDIO_SAMPLE] = MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "cclk_src_sdio", RK3588_SDIO_CON1, 1),
+    [SCLK_SDMMC_DRV] = MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "scmi_cclk_sd", RK3588_SDMMC_CON0, 1),
+    [SCLK_SDMMC_SAMPLE] = MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "scmi_cclk_sd", RK3588_SDMMC_CON1, 1),
+    [CLK_PCIE1L0_PIPE] = GATE(CLK_PCIE1L0_PIPE, "clk_pcie1l0_pipe", "clk_pipephy1_pipe_g", 0, RK3588_CLKGATE_CON(38), 14, GFLAGS),
+    [CLK_PCIE1L1_PIPE] = GATE(CLK_PCIE1L1_PIPE, "clk_pcie1l1_pipe", "clk_pipephy2_pipe_g", 0, RK3588_CLKGATE_CON(38), 15, GFLAGS),
+    [CLK_BIGCORE0_PVTM] = GATE(CLK_BIGCORE0_PVTM, "clk_bigcore0_pvtm", "xin24m", 0, RK3588_BIGCORE0_CLKGATE_CON(0), 12, GFLAGS),
+    [CLK_CORE_BIGCORE0_PVTM] = GATE(CLK_CORE_BIGCORE0_PVTM, "clk_core_bigcore0_pvtm", "armclk_b01", 0, RK3588_BIGCORE0_CLKGATE_CON(0), 13, GFLAGS),
+    [CLK_BIGCORE1_PVTM] = GATE(CLK_BIGCORE1_PVTM, "clk_bigcore1_pvtm", "xin24m", 0, RK3588_BIGCORE1_CLKGATE_CON(0), 12, GFLAGS),
+    [CLK_CORE_BIGCORE1_PVTM] = GATE(CLK_CORE_BIGCORE1_PVTM, "clk_core_bigcore1_pvtm", "armclk_b23", 0, RK3588_BIGCORE1_CLKGATE_CON(0), 13, GFLAGS),
+    [CLK_LITCORE_PVTM] = GATE(CLK_LITCORE_PVTM, "clk_litcore_pvtm", "xin24m", 0, RK3588_DSU_CLKGATE_CON(2), 0, GFLAGS),
+    [CLK_CORE_LITCORE_PVTM] = GATE(CLK_CORE_LITCORE_PVTM, "clk_core_litcore_pvtm", "armclk_l", 0, RK3588_DSU_CLKGATE_CON(2), 1, GFLAGS),
+    [CLK_AUX16M_0] = COMPOSITE_NOMUX(CLK_AUX16M_0, "clk_aux16m_0", "gpll", 0,
+            RK3588_CLKSEL_CON(117), 0, 8, DFLAGS,
+            RK3588_CLKGATE_CON(56), 2, GFLAGS),
+    [CLK_AUX16M_1] = COMPOSITE_NOMUX(CLK_AUX16M_1, "clk_aux16m_1", "gpll", 0,
+            RK3588_CLKSEL_CON(117), 8, 8, DFLAGS,
+            RK3588_CLKGATE_CON(56), 3, GFLAGS),
+    [CLK_PHY0_REF_ALT_P] = GATE(CLK_PHY0_REF_ALT_P, "clk_phy0_ref_alt_p", "ppll", 0, RK3588_PHYREF_ALT_GATE, 0, GFLAGS),
+    [CLK_PHY0_REF_ALT_M] = GATE(CLK_PHY0_REF_ALT_M, "clk_phy0_ref_alt_m", "ppll", 0, RK3588_PHYREF_ALT_GATE, 1, GFLAGS),
+    [CLK_PHY1_REF_ALT_P] = GATE(CLK_PHY1_REF_ALT_P, "clk_phy1_ref_alt_p", "ppll", 0, RK3588_PHYREF_ALT_GATE, 2, GFLAGS),
+    [CLK_PHY1_REF_ALT_M] = GATE(CLK_PHY1_REF_ALT_M, "clk_phy1_ref_alt_m", "ppll", 0, RK3588_PHYREF_ALT_GATE, 3, GFLAGS),
+    [PCLK_DDR_MON_CH0] = GATE(PCLK_DDR_MON_CH0, "pclk_ddr_mon_ch0", "pclk_center_root", 0, RK3588_CLKGATE_CON(20), 1, GFLAGS),
+    [PCLK_DDR_MON_CH1] = GATE(PCLK_DDR_MON_CH1, "pclk_ddr_mon_ch1", "pclk_center_root", 0, RK3588_CLKGATE_CON(20), 14, GFLAGS),
+    [PCLK_DDR_MON_CH2] = GATE(PCLK_DDR_MON_CH2, "pclk_ddr_mon_ch2", "pclk_center_root", 0, RK3588_CLKGATE_CON(23), 1, GFLAGS),
+    [PCLK_DDR_MON_CH3] = GATE(PCLK_DDR_MON_CH3, "pclk_ddr_mon_ch3", "pclk_center_root", 0, RK3588_CLKGATE_CON(23), 14, GFLAGS),
+
+    FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
+    COMPOSITE(0, "sclk_dsu", b0pll_b1pll_lpll_gpll_p, RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(0), 12, 2, MFLAGS, 0, 5, DFLAGS,
+            RK3588_DSU_CLKGATE_CON(0), 4, GFLAGS),
+    COMPOSITE_NOMUX(0, "atclk_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(1), 0, GFLAGS),
+    COMPOSITE_NOMUX(0, "gicclk_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(3), 5, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(1), 1, GFLAGS),
+    COMPOSITE_NOMUX(0, "aclkmp_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(1), 11, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(0), 12, GFLAGS),
+    COMPOSITE_NOMUX(0, "aclkm_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(1), 1, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(0), 8, GFLAGS),
+    COMPOSITE_NOMUX(0, "aclks_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(1), 6, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(0), 9, GFLAGS),
+    COMPOSITE_NOMUX(0, "periph_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(2), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(0), 13, GFLAGS),
+    COMPOSITE_NOMUX(0, "cntclk_dsu", "periph_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(2), 5, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(0), 14, GFLAGS),
+    COMPOSITE_NOMUX(0, "tsclk_dsu", "periph_dsu", RT_CLK_F_IS_CRITICAL,
+            RK3588_DSU_CLKSEL_CON(2), 10, 5, DFLAGS | CLK_DIVIDER_READ_ONLY,
+            RK3588_DSU_CLKGATE_CON(0), 15, GFLAGS),
+    COMPOSITE_NODIV(0, "hclk_rkvdec0_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(89), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(40), 0, GFLAGS),
+    COMPOSITE(0, "aclk_rkvdec0_root", gpll_cpll_aupll_spll_p, 0,
+            RK3588_CLKSEL_CON(89), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(40), 1, GFLAGS),
+    COMPOSITE_NODIV(0, "hclk_rkvdec1_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(93), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(41), 0, GFLAGS),
+    COMPOSITE(0, "aclk_rkvdec1_root", gpll_cpll_aupll_npll_p, 0,
+            RK3588_CLKSEL_CON(93), 7, 2, MFLAGS, 2, 5, DFLAGS,
+            RK3588_CLKGATE_CON(41), 1, GFLAGS),
+    COMPOSITE_NODIV(0, "hclk_sdio_root", mux_200m_100m_50m_24m_p, 0,
+            RK3588_CLKSEL_CON(172), 0, 2, MFLAGS,
+            RK3588_CLKGATE_CON(75), 0, GFLAGS),
+    GATE(0, "pclk_vo1grf", "pclk_vo1_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS),
+};
+
+static rt_err_t clk_rk3588_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_device *dev = &pdev->parent;
+    struct clk_rk3588_cru *cru = rt_calloc(1, sizeof(*cru));
+
+    if (!cru)
+    {
+        return -RT_ENOMEM;
+    }
+
+    cru->provider.reg_base = rt_dm_dev_iomap(dev, 0);
+
+    if (!cru->provider.reg_base)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf");
+    cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf");
+
+    cru->clk_parent.dev = dev;
+    cru->clk_parent.cells = rk3588_clk_cells;
+    cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3588_clk_cells);
+
+    rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rt_clk_register(&cru->clk_parent)))
+    {
+        goto _fail;
+    }
+
+    rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr);
+
+    if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL,
+        cru->provider.reg_base + RK3588_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK)))
+    {
+        goto _clk_unregister;
+    }
+
+    rockchip_register_restart_notifier(&cru->provider, RK3588_GLB_SRST_FST, RT_NULL);
+
+    return RT_EOK;
+
+_clk_unregister:
+    rt_clk_unregister(&cru->clk_parent);
+
+_fail:
+    if (cru->provider.reg_base)
+    {
+        rt_iounmap(cru->provider.reg_base);
+    }
+
+    rt_free(cru);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id clk_rk3588_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3588-cru", },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver clk_rk3588_driver =
+{
+    .name = "clk-rk3588",
+    .ids = clk_rk3588_ofw_ids,
+
+    .probe = clk_rk3588_probe,
+};
+
+static int clk_rk3588_register(void)
+{
+    rt_platform_driver_register(&clk_rk3588_driver);
+
+    return 0;
+}
+INIT_SUBSYS_EXPORT(clk_rk3588_register);

+ 203 - 0
bsp/rockchip/dm/clk/clk-rk8xx-clkout.c

@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "clk.rk8xx"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "rk8xx.h"
+
+struct rk8xx_clkout
+{
+    struct rt_clk_node parent;
+
+    struct rk8xx *rk8xx;
+};
+
+#define raw_to_rk8xx_clkout(raw) rt_container_of(raw, struct rk8xx_clkout, parent)
+
+static rt_ubase_t rk808_clkout_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate)
+{
+    return 32768;
+}
+
+static const struct rt_clk_ops rk808_clkout1_ops =
+{
+    .recalc_rate = rk808_clkout_recalc_rate,
+};
+
+static rt_err_t rk808_clkout2_enable(struct rt_clk_cell *cell, rt_bool_t enable)
+{
+    struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np);
+
+    return rk8xx_update_bits(clkout->rk8xx, RK808_CLK32OUT_REG,
+            CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0);
+}
+
+static rt_err_t rk808_clkout2_prepare(struct rt_clk_cell *cell)
+{
+    return rk808_clkout2_enable(cell, RT_TRUE);
+}
+
+static void rk808_clkout2_unprepare(struct rt_clk_cell *cell)
+{
+    rk808_clkout2_enable(cell, RT_FALSE);
+}
+
+static rt_bool_t rk808_clkout2_is_prepared(struct rt_clk_cell *cell)
+{
+    rt_uint32_t val;
+    struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np);
+
+    val = rk8xx_read(clkout->rk8xx, RK808_CLK32OUT_REG);
+
+    if ((rt_err_t)val < 0)
+    {
+        return RT_FALSE;
+    }
+
+    return !!(val & CLK32KOUT2_EN);
+}
+
+static const struct rt_clk_ops rk808_clkout2_ops =
+{
+    .prepare = rk808_clkout2_prepare,
+    .unprepare = rk808_clkout2_unprepare,
+    .is_prepared = rk808_clkout2_is_prepared,
+    .recalc_rate = rk808_clkout_recalc_rate,
+};
+
+static rt_err_t rk817_clkout2_enable(struct rt_clk_cell *cell, rt_bool_t enable)
+{
+    struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np);
+
+    return rk8xx_update_bits(clkout->rk8xx, RK817_SYS_CFG(1),
+            RK817_CLK32KOUT2_EN, enable ? RK817_CLK32KOUT2_EN : 0);
+}
+
+static rt_err_t rk817_clkout2_prepare(struct rt_clk_cell *cell)
+{
+    return rk817_clkout2_enable(cell, RT_TRUE);
+}
+
+static void rk817_clkout2_unprepare(struct rt_clk_cell *cell)
+{
+    rk817_clkout2_enable(cell, RT_FALSE);
+}
+
+static rt_bool_t rk817_clkout2_is_prepared(struct rt_clk_cell *cell)
+{
+    rt_uint32_t val;
+    struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np);
+
+    val = rk8xx_read(clkout->rk8xx, RK817_SYS_CFG(1));
+
+    if ((rt_err_t)val < 0)
+    {
+        return RT_FALSE;
+    }
+
+    return !!(val & RK817_CLK32KOUT2_EN);
+}
+
+static const struct rt_clk_ops rk817_clkout2_ops =
+{
+    .prepare = rk817_clkout2_prepare,
+    .unprepare = rk817_clkout2_unprepare,
+    .is_prepared = rk817_clkout2_is_prepared,
+    .recalc_rate = rk808_clkout_recalc_rate,
+};
+
+static struct rt_clk_cell *rk8xx_clkout_cell[] =
+{
+    &(struct rt_clk_cell) { .name = "rk808-clkout1" },
+    &(struct rt_clk_cell) { .name = "rk808-clkout2" },
+};
+
+static rt_err_t rk8xx_clkout_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_clk_cell *cell;
+    struct rt_device *dev = &pdev->parent;
+    struct rk8xx *rk8xx = pdev->priv;
+    struct rk8xx_clkout *clkout = rt_calloc(1, sizeof(*clkout));
+
+    if (!clkout)
+    {
+        return -RT_ENOMEM;
+    }
+
+    clkout->rk8xx = rk8xx;
+
+    /* clkout1 */
+    cell = rk8xx_clkout_cell[0];
+    cell->ops = &rk808_clkout1_ops;
+    rt_dm_dev_prop_read_string_index(dev, "clock-output-names", 0, &cell->name);
+
+    /* clkout2 */
+    cell = rk8xx_clkout_cell[1];
+    switch (rk8xx->variant)
+    {
+    case RK809_ID:
+    case RK817_ID:
+        cell->ops = &rk817_clkout2_ops;
+        break;
+
+    /*
+     * For the default case, it match the following PMIC type.
+     * RK805_ID
+     * RK808_ID
+     * RK818_ID
+     */
+    default:
+        cell->ops = &rk808_clkout2_ops;
+        break;
+    }
+    rt_dm_dev_prop_read_string_index(dev, "clock-output-names", 1, &cell->name);
+
+    if (rt_dm_dev_prop_read_bool(dev, "rockchip,clk-32k-always-on"))
+    {
+        cell->flags |= RT_CLK_F_IS_CRITICAL;
+    }
+
+    clkout->parent.dev = dev;
+    clkout->parent.cells = rk8xx_clkout_cell;
+    clkout->parent.cells_nr = RT_ARRAY_SIZE(rk8xx_clkout_cell);
+
+    if ((err = rt_clk_register(&clkout->parent)))
+    {
+        goto _fail;
+    }
+
+    return RT_EOK;
+
+_fail:
+    rt_free(clkout);
+
+    return err;
+}
+
+static struct rt_platform_driver rk8xx_clkout_driver =
+{
+    .name = "rk8xx-clkout",
+    .probe = rk8xx_clkout_probe,
+};
+
+static int rk8xx_clkout_register(void)
+{
+    rt_platform_driver_register(&rk8xx_clkout_driver);
+
+    return 0;
+}
+INIT_SUBSYS_EXPORT(rk8xx_clkout_register);

+ 31 - 18
bsp/rockchip/rk3500/driver/clk/softrst.c → bsp/rockchip/dm/clk/softrst.c

@@ -1,15 +1,19 @@
 /*
- * Copyright (c) 2006-2024 RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  *
  * Change Logs:
  * Date           Author       Notes
- * 2022-11-26     GuEe-GUI     first version
+ * 2022-3-08      GuEe-GUI     the first version
  */
 
+#include "clk-rk.h"
+
 struct rockchip_softrst
 {
+    const int *lut;
+
     void *regs;
     int num_per_reg;
     rt_uint8_t flags;
@@ -19,11 +23,16 @@ struct rockchip_softrst
 
 static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc)
 {
-    int bank, offset;
+    int id = rstc->id, bank, offset;
     struct rockchip_softrst *softrst = rstc->rstcer->priv;
 
-    bank = rstc->id / softrst->num_per_reg;
-    offset = rstc->id % softrst->num_per_reg;
+    if (softrst->lut)
+    {
+        id = softrst->lut[id];
+    }
+
+    bank = id / softrst->num_per_reg;
+    offset = id % softrst->num_per_reg;
 
     if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
     {
@@ -47,15 +56,20 @@ static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc)
 
 static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc)
 {
-    int bank, offset;
+    int id = rstc->id, bank, offset;
     struct rockchip_softrst *softrst = rstc->rstcer->priv;
 
-    bank = rstc->id / softrst->num_per_reg;
-    offset = rstc->id % softrst->num_per_reg;
+    if (softrst->lut)
+    {
+        id = softrst->lut[id];
+    }
+
+    bank = id / softrst->num_per_reg;
+    offset = id % softrst->num_per_reg;
 
     if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
     {
-        HWREG32(softrst->regs + (bank * 4)) = (RT_BIT(offset) << 16);
+        HWREG32(softrst->regs + (bank * 4)) = RT_BIT(offset) << 16;
     }
     else
     {
@@ -75,12 +89,12 @@ static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc)
 
 static const struct rt_reset_control_ops rockchip_softrst_ops =
 {
-    .assert     = rockchip_softrst_assert,
-    .deassert   = rockchip_softrst_deassert,
+    .assert = rockchip_softrst_assert,
+    .deassert = rockchip_softrst_deassert,
 };
 
-static rt_err_t rk_register_softrst(struct rt_reset_controller *rstcer,
-        struct rt_ofw_node *np, void *regs, rt_uint8_t flags)
+rt_err_t rockchip_register_softrst(struct rt_reset_controller *rstcer,
+        struct rt_ofw_node *np, const int *lookup_table, void *regs, rt_uint8_t flags)
 {
     rt_err_t err;
     struct rockchip_softrst *softrst = rt_calloc(1, sizeof(*softrst));
@@ -90,16 +104,15 @@ static rt_err_t rk_register_softrst(struct rt_reset_controller *rstcer,
         return -RT_ENOMEM;
     }
 
-    rstcer->priv = softrst;
-
-    rt_spin_lock_init(&softrst->lock);
-
+    softrst->lut = lookup_table;
     softrst->regs = regs;
     softrst->flags = flags;
     softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16 : 32;
 
-    rstcer->ofw_node = np;
+    rt_spin_lock_init(&softrst->lock);
+    rstcer->priv = softrst;
     rstcer->ops = &rockchip_softrst_ops;
+    rstcer->ofw_node = np;
 
     if ((err = rt_reset_controller_register(rstcer)))
     {

+ 5 - 0
bsp/rockchip/dm/hwcrypto/Kconfig

@@ -0,0 +1,5 @@
+config RT_HWCRYPTO_RNG_ROCKCHIP
+    bool "Rockchip Random Number Generator support"
+    depends on RT_HWCRYPTO_USING_RNG
+    depends on RT_USING_RESET
+    default n

+ 5 - 6
bsp/rockchip/rk3500/driver/uart8250/SConscript → bsp/rockchip/dm/hwcrypto/SConscript

@@ -1,13 +1,12 @@
 from building import *
 
 cwd     = GetCurrentDir()
-CPPPATH = [cwd]
+src     = []
+CPPPATH = [cwd + '/../include']
 
-src     = ['core.c', 'early.c']
-
-if GetDepend(['RT_SERIAL_8250']):
-    src += ['8250-dw.c']
-    src += ['fiq-debugger.c']
+if GetDepend(['RT_HWCRYPTO_RNG_ROCKCHIP']):
+    src += ['hw-rng-rockchip.c']
 
 group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
 Return('group')

+ 565 - 0
bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c

@@ -0,0 +1,565 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "rng.rockchip"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "rockchip.h"
+
+#define ROCKCHIP_AUTOSUSPEND_DELAY      100
+#define ROCKCHIP_POLL_PERIOD_US         100
+#define ROCKCHIP_POLL_TIMEOUT_US        50000
+#define RK_MAX_RNG_BYTE                 (32)
+
+/* start of CRYPTO V1 register define */
+#define CRYPTO_V1_CTRL                  0x0008
+#define CRYPTO_V1_RNG_START             RT_BIT(8)
+#define CRYPTO_V1_RNG_FLUSH             RT_BIT(9)
+
+#define CRYPTO_V1_TRNG_CTRL             0x0200
+#define CRYPTO_V1_OSC_ENABLE            RT_BIT(16)
+#define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x)
+
+#define CRYPTO_V1_TRNG_DOUT_0           0x0204
+/* end of CRYPTO V1 register define */
+
+/* start of CRYPTO V2 register define */
+#define CRYPTO_V2_RNG_DEFAULT_OFFSET    0x0400
+#define CRYPTO_V2_RNG_CTL               0x0
+#define CRYPTO_V2_RNG_64_BIT_LEN        ((0x00) << (4))
+#define CRYPTO_V2_RNG_128_BIT_LEN       ((0x01) << (4))
+#define CRYPTO_V2_RNG_192_BIT_LEN       ((0x02) << (4))
+#define CRYPTO_V2_RNG_256_BIT_LEN       ((0x03) << (4))
+#define CRYPTO_V2_RNG_FATESY_SOC_RING   ((0x00) << (2))
+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 ((0x01) << (2))
+#define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 ((0x02) << (2))
+#define CRYPTO_V2_RNG_SLOWEST_SOC_RING  ((0x03) << (2))
+#define CRYPTO_V2_RNG_ENABLE            RT_BIT(1)
+#define CRYPTO_V2_RNG_START             RT_BIT(0)
+#define CRYPTO_V2_RNG_SAMPLE_CNT        0x0004
+#define CRYPTO_V2_RNG_DOUT_0            0x0010
+/* end of CRYPTO V2 register define */
+
+/* start of TRNG_V1 register define */
+/* TRNG is no longer subordinate to the Crypto module */
+#define TRNG_V1_CTRL                    0x0000
+#define TRNG_V1_CTRL_NOP                ((0x00) << (0))
+#define TRNG_V1_CTRL_RAND               ((0x01) << (0))
+#define TRNG_V1_CTRL_SEED               ((0x02) << (0))
+
+#define TRNG_V1_STAT                    0x0004
+#define TRNG_V1_STAT_SEEDED             RT_BIT(9)
+#define TRNG_V1_STAT_GENERATING         RT_BIT(30)
+#define TRNG_V1_STAT_RESEEDING          RT_BIT(31)
+
+#define TRNG_V1_MODE                    0x0008
+#define TRNG_V1_MODE_128_BIT            ((0x00) << (3))
+#define TRNG_V1_MODE_256_BIT            ((0x01) << (3))
+
+#define TRNG_V1_IE                      0x0010
+#define TRNG_V1_IE_GLBL_EN              RT_BIT(31)
+#define TRNG_V1_IE_SEED_DONE_EN         RT_BIT(1)
+#define TRNG_V1_IE_RAND_RDY_EN          RT_BIT(0)
+
+#define TRNG_V1_ISTAT                   0x0014
+#define TRNG_V1_ISTAT_RAND_RDY          RT_BIT(0)
+
+/* RAND0 ~ RAND7 */
+#define TRNG_V1_RAND0                   0x0020
+#define TRNG_V1_RAND7                   0x003C
+
+#define TRNG_V1_AUTO_RQSTS              0x0060
+
+#define TRNG_V1_VERSION                 0x00F0
+#define TRNG_v1_VERSION_CODE            0x46bc
+/* end of TRNG_V1 register define */
+
+struct rockchip_rng;
+
+struct rockchip_rng_soc_data
+{
+    rt_uint32_t default_offset;
+
+    rt_err_t (*init)(struct rockchip_rng *rk_rng);
+    rt_uint32_t (*read)(struct rockchip_rng *rk_rng, void *buf, rt_size_t max, rt_bool_t wait);
+};
+
+struct rockchip_rng
+{
+    struct rt_hwcrypto_device parent;
+
+    void *regs;
+
+    struct rt_clk_array *clk_arr;
+    struct rt_reset_control *rstc;
+
+    const struct rockchip_rng_soc_data *soc_data;
+};
+
+#define raw_to_rockchip_rng(raw) rt_container_of(raw, struct rockchip_rng, parent)
+
+static void rockchip_rng_writel(struct rockchip_rng *rk_rng, rt_uint32_t val, int offset)
+{
+    HWREG32(rk_rng->regs + offset) = val;
+}
+
+static rt_uint32_t rockchip_rng_readl(struct rockchip_rng *rk_rng, int offset)
+{
+    return HWREG32(rk_rng->regs + offset);
+}
+
+static void rockchip_rng_read_regs(struct rockchip_rng *rk_rng, rt_uint32_t offset,
+        void *buf, rt_size_t size)
+{
+    rt_uint32_t *data = buf;
+
+    for (int i = 0; i < size; i += 4, ++offset)
+    {
+        data[i] = rt_be32_to_cpu(rockchip_rng_readl(rk_rng, offset));
+    }
+}
+
+static rt_uint32_t rockchip_crypto_v1_read(struct rockchip_rng *rk_rng, void *buf,
+        rt_size_t max, rt_bool_t wait)
+{
+    rt_tick_t start;
+    rt_uint32_t res = 0, reg_ctrl = 0;
+    int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
+
+    /* enable osc_ring to get entropy, sample period is set as 100 */
+    reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100);
+    rockchip_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL);
+
+    reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0);
+
+    rockchip_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL);
+
+    start = rt_tick_get();
+
+    while (rockchip_rng_readl(rk_rng, CRYPTO_V1_CTRL) & CRYPTO_V1_RNG_START)
+    {
+        rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
+
+        if ((rt_tick_get() - start) > timeout)
+        {
+            goto _time_out;
+        }
+
+        rt_hw_cpu_relax();
+    }
+
+    res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE);
+
+    rockchip_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, res);
+
+_time_out:
+    /* close TRNG */
+    rockchip_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0), CRYPTO_V1_CTRL);
+
+    return res;
+}
+
+static rt_uint32_t rockchip_crypto_v2_read(struct rockchip_rng *rk_rng, void *buf,
+        rt_size_t max, rt_bool_t wait)
+{
+    rt_tick_t start;
+    rt_uint32_t res = 0, reg_ctrl = 0;
+    int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
+
+    /* enable osc_ring to get entropy, sample period is set as 100 */
+    rockchip_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT);
+
+    reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN;
+    reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0;
+    reg_ctrl |= CRYPTO_V2_RNG_ENABLE;
+    reg_ctrl |= CRYPTO_V2_RNG_START;
+
+    rockchip_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), CRYPTO_V2_RNG_CTL);
+
+    start = rt_tick_get();
+
+    while (rockchip_rng_readl(rk_rng, CRYPTO_V2_RNG_CTL) & CRYPTO_V2_RNG_START)
+    {
+        rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
+
+        if ((rt_tick_get() - start) > timeout)
+        {
+            goto _time_out;
+        }
+
+        rt_hw_cpu_relax();
+    }
+
+    res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE);
+
+    rockchip_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, res);
+
+_time_out:
+    /* close TRNG */
+    rockchip_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL);
+
+    return res;
+}
+
+static rt_err_t rockchip_trng_v1_init(struct rockchip_rng *rk_rng)
+{
+    rt_uint32_t auto_reseed_cnt = 1000;
+    rt_uint32_t reg_ctrl, status, version;
+
+    version = rockchip_rng_readl(rk_rng, TRNG_V1_VERSION);
+
+    if (version != TRNG_v1_VERSION_CODE)
+    {
+        LOG_E("Wrong trng version, expected = %08x, actual = %08x",
+                TRNG_V1_VERSION, version);
+
+        return -RT_EIO;
+    }
+
+    status = rockchip_rng_readl(rk_rng, TRNG_V1_STAT);
+
+    /* TRNG should wait RAND_RDY triggered if it is busy or not seeded */
+    if (!(status & TRNG_V1_STAT_SEEDED) || (status & TRNG_V1_STAT_GENERATING) ||
+        (status & TRNG_V1_STAT_RESEEDING))
+    {
+        rt_tick_t start;
+        rt_uint32_t mask = TRNG_V1_STAT_SEEDED | TRNG_V1_STAT_GENERATING |
+                TRNG_V1_STAT_RESEEDING;
+        int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
+
+        rt_hw_us_delay(10);
+
+        /* wait for GENERATING and RESEEDING flag to clear */
+        start = rt_tick_get();
+
+        while ((rockchip_rng_readl(rk_rng, TRNG_V1_STAT) & mask) != TRNG_V1_STAT_SEEDED)
+        {
+            rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
+
+            if ((rt_tick_get() - start) > timeout)
+            {
+                break;
+            }
+
+            rt_hw_cpu_relax();
+        }
+    }
+
+    /* clear ISTAT flag because trng may auto reseeding when power on */
+    reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT);
+    rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
+
+    /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */
+    rockchip_rng_writel(rk_rng, auto_reseed_cnt, TRNG_V1_AUTO_RQSTS);
+
+    return RT_EOK;
+}
+
+static rt_uint32_t rockchip_trng_v1_read(struct rockchip_rng *rk_rng, void *buf,
+        rt_size_t max, rt_bool_t wait)
+{
+    rt_uint32_t res = 0, reg_ctrl = 0;
+
+    /* clear ISTAT anyway */
+    reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT);
+    rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
+
+    /* generate 256bit random */
+    rockchip_rng_writel(rk_rng, TRNG_V1_MODE_256_BIT, TRNG_V1_MODE);
+    rockchip_rng_writel(rk_rng, TRNG_V1_CTRL_RAND, TRNG_V1_CTRL);
+
+    /*
+     * Generate2 56 bit random data will cost 1024 clock cycles.
+     * Estimated at 150M RNG module frequency, it takes 6.7 microseconds.
+     */
+    rt_hw_us_delay(10);
+    reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT);
+
+    if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY))
+    {
+        rt_tick_t start = rt_tick_get();
+        int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000);
+
+        /* wait RAND_RDY triggered */
+        while (!(rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT) & TRNG_V1_ISTAT_RAND_RDY))
+        {
+            rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US);
+
+            if ((rt_tick_get() - start) > timeout)
+            {
+                goto _time_out;
+            }
+
+            rt_hw_cpu_relax();
+        }
+    }
+
+    res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE);
+
+    rockchip_rng_read_regs(rk_rng, TRNG_V1_RAND0, buf, res);
+
+    /* clear all status flag */
+    rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT);
+_time_out:
+    /* close TRNG */
+    rockchip_rng_writel(rk_rng, TRNG_V1_CTRL_NOP, TRNG_V1_CTRL);
+
+    return res;
+}
+
+static rt_uint32_t rockchip_rng_read(struct rockchip_rng *rk_rng, void *buf,
+        rt_size_t max, rt_bool_t wait)
+{
+    rt_uint32_t res;
+    int read_len = 0;
+
+    if (!rk_rng->soc_data->read)
+    {
+        return 0;
+    }
+
+    res = 0;
+
+    while (max > res)
+    {
+        read_len = rk_rng->soc_data->read(rk_rng, buf + res, max - res, wait);
+
+        if (read_len < 0)
+        {
+            res = read_len;
+
+            break;
+        }
+        res += read_len;
+    }
+
+    return res;
+}
+
+static rt_uint32_t rockchip_rng_rand(struct hwcrypto_rng *ctx)
+{
+    rt_uint32_t rand;
+    struct rockchip_rng *rk_rng = raw_to_rockchip_rng(ctx->parent.device);
+
+    if (rockchip_rng_read(rk_rng, &rand, sizeof(rand), RT_TRUE) != sizeof(rand))
+    {
+        return 0;
+    }
+
+    return rand;
+}
+
+static const struct hwcrypto_rng_ops rng_ops =
+{
+    .update = rockchip_rng_rand,
+};
+
+static rt_err_t rockchip_rng_create(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_err_t res = RT_EOK;
+    struct hwcrypto_rng *rng;
+
+    switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK)
+    {
+    case HWCRYPTO_TYPE_RNG:
+        ctx->contex = RT_NULL;
+
+        rng = rt_container_of(ctx, struct hwcrypto_rng, parent);
+        rng->ops = &rng_ops;
+        break;
+
+    default:
+        res = -RT_ENOSYS;
+        break;
+    }
+
+    return res;
+}
+
+static void rockchip_rng_destroy(struct rt_hwcrypto_ctx *ctx)
+{
+    rt_free(ctx->contex);
+}
+
+static rt_err_t rockchip_rng_copy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src)
+{
+    rt_err_t err = RT_EOK;
+
+    switch (src->type & HWCRYPTO_MAIN_TYPE_MASK)
+    {
+    case HWCRYPTO_TYPE_RNG:
+        break;
+    default:
+        err = -RT_ENOSYS;
+        break;
+    }
+
+    return err;
+}
+
+static void rockchip_rng_reset(struct rt_hwcrypto_ctx *ctx)
+{
+}
+
+static const struct rt_hwcrypto_ops rockchip_rng_ops =
+{
+    .create = rockchip_rng_create,
+    .destroy = rockchip_rng_destroy,
+    .copy = rockchip_rng_copy,
+    .reset = rockchip_rng_reset,
+};
+
+static void rockchip_rng_free(struct rockchip_rng *rk_rng)
+{
+    if (!rk_rng->regs)
+    {
+        rt_iounmap(rk_rng->regs);
+    }
+
+    if (!rt_is_err_or_null(rk_rng->rstc))
+    {
+        rt_reset_control_assert(rk_rng->rstc);
+        rt_reset_control_put(rk_rng->rstc);
+    }
+
+    if (!rt_is_err_or_null(rk_rng->clk_arr))
+    {
+        rt_clk_array_disable_unprepare(rk_rng->clk_arr);
+        rt_clk_array_put(rk_rng->clk_arr);
+    }
+
+    rt_free(rk_rng);
+}
+
+static rt_err_t rockchip_rng_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err = RT_EOK;
+    struct rt_device *dev = &pdev->parent;
+    struct rockchip_rng *rk_rng = rt_calloc(1, sizeof(*rk_rng));
+
+    if (!rk_rng)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk_rng->soc_data = pdev->id->data;
+
+    rk_rng->regs = rt_dm_dev_iomap(dev, 0);
+
+    if (!rk_rng->regs)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    rk_rng->rstc = rt_reset_control_get_by_name(dev, "reset");
+
+    if (rt_is_err(rk_rng->rstc))
+    {
+        err = rt_ptr_err(rk_rng->rstc);
+        goto _fail;
+    }
+
+    if (rk_rng->rstc)
+    {
+        rt_reset_control_assert(rk_rng->rstc);
+        rt_hw_us_delay(10);
+        rt_reset_control_deassert(rk_rng->rstc);
+    }
+
+    rk_rng->clk_arr = rt_clk_get_array(dev);
+
+    if (rt_is_err(rk_rng->clk_arr))
+    {
+        err = rt_ptr_err(rk_rng->clk_arr);
+        goto _fail;
+    }
+
+    rt_clk_array_prepare_enable(rk_rng->clk_arr);
+
+    if (rk_rng->soc_data->init)
+    {
+        err = rk_rng->soc_data->init(rk_rng);
+    }
+
+    if (err)
+    {
+        goto _fail;
+    }
+
+    dev->user_data = rk_rng;
+
+    rk_rng->parent.ops = &rockchip_rng_ops;
+
+    if ((err = rt_hwcrypto_register(&rk_rng->parent, "hwrng")))
+    {
+        goto _fail;
+    }
+
+    return RT_EOK;
+
+_fail:
+    rockchip_rng_free(rk_rng);
+
+    return err;
+}
+
+static rt_err_t rockchip_rng_remove(struct rt_platform_device *pdev)
+{
+    struct rockchip_rng *rk_rng = pdev->parent.user_data;
+
+    rt_device_unregister(&rk_rng->parent.parent);
+
+    rockchip_rng_free(rk_rng);
+
+    return RT_EOK;
+}
+
+static const struct rockchip_rng_soc_data rk_crypto_v1_soc_data =
+{
+    .default_offset = 0,
+    .read = rockchip_crypto_v1_read,
+};
+
+static const struct rockchip_rng_soc_data rk_crypto_v2_soc_data =
+{
+    .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET,
+    .read = rockchip_crypto_v2_read,
+};
+
+static const struct rockchip_rng_soc_data rk_trng_v1_soc_data =
+{
+    .default_offset = 0,
+    .init = rockchip_trng_v1_init,
+    .read = rockchip_trng_v1_read,
+};
+
+static const struct rt_ofw_node_id rockchip_rng_ofw_ids[] =
+{
+    { .compatible = "rockchip,cryptov1-rng", .data = &rk_crypto_v1_soc_data, },
+    { .compatible = "rockchip,cryptov2-rng", .data = &rk_crypto_v2_soc_data, },
+    { .compatible = "rockchip,trngv1", .data = &rk_trng_v1_soc_data, },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_rng_driver =
+{
+    .name = "rockchip-rng",
+    .ids = rockchip_rng_ofw_ids,
+
+    .probe = rockchip_rng_probe,
+    .remove = rockchip_rng_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rockchip_rng_driver);

+ 3 - 0
bsp/rockchip/dm/hwspinlock/Kconfig

@@ -0,0 +1,3 @@
+config RT_HWSPINLOCK_ROCKCHIP
+    bool "Rockchip Hardware Spinlock device"
+    default n

+ 12 - 0
bsp/rockchip/dm/hwspinlock/SConscript

@@ -0,0 +1,12 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/hwspinlock']
+
+if GetDepend(['RT_HWSPINLOCK_ROCKCHIP']):
+    src += ['hwspinlock-rockchip.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 135 - 0
bsp/rockchip/dm/hwspinlock/hwspinlock-rockchip.c

@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-09-23     GuEe-GUI     first version
+ */
+
+#include "hwspinlock_dm.h"
+
+#define HWSPINLOCK_NUMBER           64
+#define HWSPINLOCK_STATUS_OFFSET(x) (0x4 * (x))
+#define HWSPINLOCK_OWNER_ID         0x1
+
+struct rockchip_hwspinlock
+{
+    struct rt_hwspinlock_bank parent;
+
+    void *regs;
+};
+
+static rt_err_t rockchip_hwspinlock_trylock(struct rt_hwspinlock *hwlock)
+{
+    void *lock_regs = hwlock->priv;
+
+    HWREG32(lock_regs) = HWSPINLOCK_OWNER_ID;
+
+    /*
+     * Get only first 4bits and compare to HWSPINLOCK_OWNER_ID:
+     *  when 4bits is 0, 4bits can be written with new value.
+     *  when 4bits is not 0, 4bits cannot be written.
+     *  when write data is 0x0000, 4bits clean to 0.
+     */
+
+    return ((HWREG32(lock_regs) & 0xf) == HWSPINLOCK_OWNER_ID);
+}
+
+static void rockchip_hwspinlock_unlock(struct rt_hwspinlock *hwlock)
+{
+    void *lock_regs = hwlock->priv;
+
+    HWREG32(lock_regs) = 0;
+}
+
+static const struct rt_hwspinlock_ops rk_hwspinlock_ops =
+{
+    .trylock = rockchip_hwspinlock_trylock,
+    .unlock = rockchip_hwspinlock_unlock,
+};
+
+static rt_err_t rockchip_hwspinlock_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_hwspinlock *hwlock;
+    struct rt_hwspinlock_bank *bank;
+    struct rt_device *dev = &pdev->parent;
+    struct rockchip_hwspinlock *rk_hwspinlock;
+
+    rk_hwspinlock = hwspinlock_bank_alloc(rk_hwspinlock, HWSPINLOCK_NUMBER);
+
+    if (!rk_hwspinlock)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk_hwspinlock->regs = rt_dm_dev_iomap(dev, 0);
+
+    if (!rk_hwspinlock->regs)
+    {
+        err = -RT_EIO;
+
+        goto _fail;
+    }
+
+    bank = &rk_hwspinlock->parent;
+    hwlock = &bank->locks[0];
+
+    for (int i = 0; i < HWSPINLOCK_NUMBER; ++i, ++hwlock)
+    {
+        hwlock->priv = rk_hwspinlock->regs + HWSPINLOCK_STATUS_OFFSET(i);
+    }
+
+    bank->dev = dev;
+    bank->ops = &rk_hwspinlock_ops;
+    bank->locks_nr = HWSPINLOCK_NUMBER;
+
+    if ((err = rt_hwspinlock_bank_register(bank)))
+    {
+        goto _fail;
+    }
+
+    dev->user_data = rk_hwspinlock;
+
+    return RT_EOK;
+
+_fail:
+    if (rk_hwspinlock->regs)
+    {
+        rt_iounmap(rk_hwspinlock->regs);
+    }
+    rt_free(rk_hwspinlock);
+
+    return err;
+}
+
+static rt_err_t rockchip_hwspinlock_remove(struct rt_platform_device *pdev)
+{
+    struct rockchip_hwspinlock *rk_hwspinlock = pdev->parent.user_data;
+
+    rt_hwspinlock_bank_unregister(&rk_hwspinlock->parent);
+
+    rt_iounmap(rk_hwspinlock->regs);
+
+    rt_free(rk_hwspinlock);
+
+    return RT_EOK;
+}
+
+static const struct rt_ofw_node_id rockchip_hwspinlock_ofw_ids[] =
+{
+    { .compatible = "rockchip,hwspinlock" },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_hwspinlock_driver =
+{
+    .name = "hwspinlock-rockchip",
+    .ids = rockchip_hwspinlock_ofw_ids,
+
+    .probe = rockchip_hwspinlock_probe,
+    .remove = rockchip_hwspinlock_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rockchip_hwspinlock_driver);

+ 0 - 2
bsp/rockchip/rk3500/driver/hwtimer/Kconfig → bsp/rockchip/dm/hwtimer/Kconfig

@@ -1,5 +1,3 @@
 config RT_HWTIMER_ROCKCHIP
     bool "RockChip Timer"
-    depends on RT_USING_DM
-    depends on RT_USING_HWTIMER
     default n

+ 3 - 4
bsp/rockchip/rk3500/driver/hwtimer/SConscript → bsp/rockchip/dm/hwtimer/SConscript

@@ -1,9 +1,8 @@
 from building import *
 
-cwd = GetCurrentDir()
-CPPPATH = [cwd]
-
-src = []
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include']
 
 if GetDepend(['RT_HWTIMER_ROCKCHIP']):
     src += ['hwtimer-rockchip_timer.c']

+ 58 - 122
bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c → bsp/rockchip/dm/hwtimer/hwtimer-rockchip_timer.c

@@ -8,30 +8,17 @@
  * 2022-12-06     GuEe-GUI     first version
  */
 
-#define DBG_TAG "drv.rk_timer"
-#define DBG_LVL DBG_INFO
-#include <rtdbg.h>
-
 #include <rthw.h>
 #include <rtthread.h>
 #include <rtdevice.h>
 
-#ifdef RT_USING_KTIME
-#include <ktime.h>
-#endif
-
-#define HZ      100
-#define KHZ     1000
-#define MHZ     1000000
-#define OSC_HZ  (24 * MHZ)
-
-#define TIMER_LOAD_COUNT0       0x00
-#define TIMER_LOAD_COUNT1       0x04
-#define TIMER_CURRENT_VALUE0    0x08
-#define TIMER_CURRENT_VALUE1    0x0c
-#define TIMER_CONTROL_REG3288   0x10
-#define TIMER_CONTROL_REG3399   0x1c
-#define TIMER_INT_STATUS        0x18
+#define TIMER_LOAD_COUNT0               0x00
+#define TIMER_LOAD_COUNT1               0x04
+#define TIMER_CURRENT_VALUE0            0x08
+#define TIMER_CURRENT_VALUE1            0x0c
+#define TIMER_CONTROL_REG3288           0x10
+#define TIMER_CONTROL_REG3399           0x1c
+#define TIMER_INT_STATUS                0x18
 
 #define TIMER_DISABLE                   0x0
 #define TIMER_ENABLE                    0x1
@@ -39,6 +26,8 @@
 #define TIMER_MODE_USER_DEFINED_COUNT   (1 << 1)
 #define TIMER_INT_UNMASK                (1 << 2)
 
+#define HZ                              100
+
 struct rk_timer
 {
     struct rt_hwtimer_device parent;
@@ -55,17 +44,7 @@ struct rk_timer
 
     struct rt_hwtimer_info info;
 };
-#ifdef RT_USING_KTIME
-struct hrt_timer
-{
-    struct rk_timer *timer;
-    uint64_t cnt;
-    void (*outcb)(void *param);
-    void *param;
-};
-static struct hrt_timer _timer0 = {0};
-static struct rt_spinlock  _spinlock;
-#endif
+
 #define raw_to_rk_timer(raw) rt_container_of(raw, struct rk_timer, parent)
 
 struct rk_timer_data
@@ -200,26 +179,34 @@ const static struct rt_hwtimer_ops rk_timer_ops =
 
 static void rk_timer_isr(int irqno, void *param)
 {
-    struct hrt_timer *timer = &_timer0;
-    struct rk_timer *time = timer->timer;
+    struct rk_timer *rk_timer = (struct rk_timer *)param;
 
-    rk_timer_interrupt_clear(time);
+    rk_timer_interrupt_clear(rk_timer);
 
-    rt_ktime_hrtimer_process();
+    if (rk_timer->status)
+    {
+        rt_device_hwtimer_isr(&rk_timer->parent);
+    }
 }
 
-void rt_ktime_hrtimer_bind(rt_bitmap_t *affinity)
+static void rk_timer_free(struct rk_timer *timer)
 {
-    struct rk_timer *timer = _timer0.timer;
+    if (timer->base)
+    {
+        rt_iounmap(timer->base);
+    }
 
-    if (rt_pic_irq_set_affinity(timer->irq, affinity) == -RT_ENOSYS)
+    if (!rt_is_err_or_null(timer->pclk))
     {
-        LOG_E("timer irq affinity init fail\n");
+        rt_clk_put(timer->pclk);
     }
-    else
+
+    if (!rt_is_err_or_null(timer->clk))
     {
-        LOG_D("timer irq(%d) binding done\n", timer->irq);
+        rt_clk_put(timer->clk);
     }
+
+    rt_free(timer);
 }
 
 static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
@@ -229,24 +216,22 @@ static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
     struct rt_device *dev = &pdev->parent;
     struct rk_timer *timer = rt_calloc(1, sizeof(*timer));
     const struct rk_timer_data *timer_data = pdev->id->data;
+
     if (!timer)
     {
         return -RT_ENOMEM;
     }
-#ifdef RT_USING_KTIME
-    _timer0.timer = timer;
-    rt_spin_lock_init(&_spinlock);
-#endif
-    if (!(timer->pclk = rt_clk_get_by_name(dev, "pclk")))
+
+    if (rt_is_err(timer->pclk = rt_clk_get_by_name(dev, "pclk")))
     {
-        err = -RT_EIO;
+        err = rt_ptr_err(timer->pclk);
 
         goto _fail;
     }
 
-    if (!(timer->clk = rt_clk_get_by_name(dev, "timer")))
+    if (rt_is_err(timer->clk = rt_clk_get_by_name(dev, "timer")))
     {
-        err = -RT_EIO;
+        err = rt_ptr_err(timer->clk);
 
         goto _fail;
     }
@@ -260,6 +245,8 @@ static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
         goto _fail;
     }
 
+    dev->user_data = timer;
+
     timer->ctrl = timer->base + timer_data->ctrl_reg;
 
     rt_clk_enable(timer->pclk);
@@ -276,44 +263,37 @@ static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
     timer->info.maxfreq = timer->freq;
     timer->info.minfreq = timer->freq;
     timer->info.maxcnt = 0xffffffff;
-    timer->info.cntmode = HWTIMER_CNTMODE_DW;
+    timer->info.cntmode = HWTIMER_CNTMODE_UP;
 
     rt_dm_dev_set_name_auto(&timer->parent.parent, "timer");
     dev_name = rt_dm_dev_get_name(&timer->parent.parent);
 
     rt_device_hwtimer_register(&timer->parent, dev_name, RT_NULL);
+    rt_hw_interrupt_install(timer->irq, rk_timer_isr, timer, dev_name);
+    rt_hw_interrupt_umask(timer->irq);
 
-    RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = { 0 };
-    rt_bitmap_set_bit(affinity, RT_CPUS_NR - 1);
-    rt_ktime_hrtimer_bind(affinity);
+    return RT_EOK;
 
-    rt_pic_attach_irq(timer->irq, rk_timer_isr, timer, dev_name, RT_IRQ_F_NONE);
-    rt_pic_irq_unmask(timer->irq);
-
-#if KTIMER_BIND_CPU
-    RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = {0};
-    rt_bitmap_set_bit(affinity, 1);
-    rt_pic_irq_set_affinity(timer->irq, affinity);
-#endif
+_fail:
+    rk_timer_free(timer);
 
     return err;
+}
 
-_fail:
-    if (timer->base)
-    {
-        rt_iounmap(timer->base);
-    }
-    if (timer->pclk)
-    {
-        rt_clk_put(timer->pclk);
-    }
-    if (timer->clk)
-    {
-        rt_clk_put(timer->clk);
-    }
-    rt_free(timer);
+static rt_err_t rk_timer_remove(struct rt_platform_device *pdev)
+{
+    struct rk_timer *timer = pdev->parent.user_data;
 
-    return err;
+    rt_hw_interrupt_mask(timer->irq);
+    rt_pic_detach_irq(timer->irq, timer);
+
+    rk_timer_stop(&timer->parent);
+
+    rt_device_unregister(&timer->parent.parent);
+
+    rk_timer_free(timer);
+
+    return RT_EOK;
 }
 
 static const struct rk_timer_data rk3288_timer_data =
@@ -326,44 +306,6 @@ static const struct rk_timer_data rk3399_timer_data =
     .ctrl_reg = TIMER_CONTROL_REG3399,
 };
 
-#ifdef RT_USING_KTIME
-
-uint64_t rt_ktime_hrtimer_getfrq(void)
-{
-    return (24 * 1000 * 1000UL);
-}
-
-uint64_t rt_ktime_hrtimer_getres(void)
-{
-    return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / (24 * 1000 * 1000UL);
-}
-
-/**
- * @brief set the timeout function for hrtimer framework
- *
- * @warning application should not call this API directly
- *
- * @param cnt the count of timer dealy
- * @return rt_err_t 0 forever
- */
-rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt)
-{
-    struct hrt_timer *timer = &_timer0;
-    struct rk_timer *time = timer->timer;
-
-    timer->cnt = cnt;
-
-    if (cnt)
-    {
-        rk_timer_disable(time);
-        rk_timer_update_counter(cnt, time);
-        rk_timer_enable(time, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
-    }
-
-    return 0;
-}
-#endif
-
 static const struct rt_ofw_node_id rk_timer_ofw_ids[] =
 {
     { .compatible = "rockchip,rk3288-timer", .data = &rk3288_timer_data },
@@ -377,12 +319,6 @@ static struct rt_platform_driver rk_timer_driver =
     .ids = rk_timer_ofw_ids,
 
     .probe = rk_timer_probe,
+    .remove = rk_timer_remove,
 };
-
-static int rk_timer_drv_register(void)
-{
-    rt_platform_driver_register(&rk_timer_driver);
-
-    return 0;
-}
-INIT_PLATFORM_EXPORT(rk_timer_drv_register);
+RT_PLATFORM_DRIVER_EXPORT(rk_timer_driver);

+ 5 - 0
bsp/rockchip/dm/i2c/Kconfig

@@ -0,0 +1,5 @@
+config RT_I2C_RK3X
+    bool "Rockchip RK3xxx I2C adapter"
+    depends on RT_MFD_SYSCON
+    depends on RT_USING_PINCTRL
+    default n

+ 12 - 0
bsp/rockchip/dm/i2c/SConscript

@@ -0,0 +1,12 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include']
+
+if GetDepend('RT_I2C_RK3X'):
+    src += ['i2c-rk3x.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 1375 - 0
bsp/rockchip/dm/i2c/i2c-rk3x.c

@@ -0,0 +1,1375 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "i2c.rk3x"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <drivers/dev_i2c_dm.h>
+
+/* Register Map */
+#define REG_CON                 0x00 /* control register */
+#define REG_CLKDIV              0x04 /* clock divisor register */
+#define REG_MRXADDR             0x08 /* slave address for REGISTER_TX */
+#define REG_MRXRADDR            0x0c /* slave register address for REGISTER_TX */
+#define REG_MTXCNT              0x10 /* number of bytes to be transmitted */
+#define REG_MRXCNT              0x14 /* number of bytes to be received */
+#define REG_IEN                 0x18 /* interrupt enable */
+#define REG_IPD                 0x1c /* interrupt pending */
+#define REG_FCNT                0x20 /* finished count */
+
+/* Data buffer offsets */
+#define TXBUFFER_BASE           0x100
+#define RXBUFFER_BASE           0x200
+
+/* REG_CON bits */
+#define REG_CON_EN              RT_BIT(0)
+
+enum
+{
+    REG_CON_MOD_TX = 0,      /* transmit data */
+    REG_CON_MOD_REGISTER_TX, /* select register and restart */
+    REG_CON_MOD_RX,          /* receive data */
+    REG_CON_MOD_REGISTER_RX, /* broken: transmits read addr AND writes register addr */
+};
+
+#define REG_CON_MOD(mod)        ((mod) << 1)
+#define REG_CON_MOD_MASK        (RT_BIT(1) | RT_BIT(2))
+#define REG_CON_START           RT_BIT(3)
+#define REG_CON_STOP            RT_BIT(4)
+#define REG_CON_LASTACK         RT_BIT(5) /* 1: send NACK after last received byte */
+#define REG_CON_ACTACK          RT_BIT(6) /* 1: stop if NACK is received */
+
+#define REG_CON_TUNING_MASK     RT_GENMASK_ULL(15, 8)
+
+#define REG_CON_SDA_CFG(cfg)    ((cfg) << 8)
+#define REG_CON_STA_CFG(cfg)    ((cfg) << 12)
+#define REG_CON_STO_CFG(cfg)    ((cfg) << 14)
+
+/* REG_MRXADDR bits */
+#define REG_MRXADDR_VALID(x)    RT_BIT(24 + (x)) /* [x*8+7:x*8] of MRX[R]ADDR valid */
+
+/* REG_IEN/REG_IPD bits */
+#define REG_INT_BTF             RT_BIT(0) /* a byte was transmitted */
+#define REG_INT_BRF             RT_BIT(1) /* a byte was received */
+#define REG_INT_MBTF            RT_BIT(2) /* master data transmit finished */
+#define REG_INT_MBRF            RT_BIT(3) /* master data receive finished */
+#define REG_INT_START           RT_BIT(4) /* START condition generated */
+#define REG_INT_STOP            RT_BIT(5) /* STOP condition generated */
+#define REG_INT_NAKRCV          RT_BIT(6) /* NACK received */
+#define REG_INT_ALL             0x7f
+
+/* Constants */
+#define WAIT_TIMEOUT            1000 /* ms */
+#define DEFAULT_SCL_RATE        (100 * 1000) /* Hz */
+
+/* I2C specification values for various modes */
+struct i2c_spec_values
+{
+    rt_ubase_t min_hold_start_ns;   /* min hold time (repeated) START condition */
+    rt_ubase_t min_low_ns;          /* min LOW period of the SCL clock */
+    rt_ubase_t min_high_ns;         /* min HIGH period of the SCL cloc */
+    rt_ubase_t min_setup_start_ns;  /* min set-up time for a repeated START conditio */
+    rt_ubase_t max_data_hold_ns;    /* max data hold time */
+    rt_ubase_t min_data_setup_ns;   /* min data set-up time */
+    rt_ubase_t min_setup_stop_ns;   /* min set-up time for STOP condition */
+    rt_ubase_t min_hold_buffer_ns;  /* min bus free time between a STOP and */
+};
+
+static const struct i2c_spec_values standard_mode_spec =
+{
+    .min_hold_start_ns = 4000,
+    .min_low_ns = 4700,
+    .min_high_ns = 4000,
+    .min_setup_start_ns = 4700,
+    .max_data_hold_ns = 3450,
+    .min_data_setup_ns = 250,
+    .min_setup_stop_ns = 4000,
+    .min_hold_buffer_ns = 4700,
+};
+
+static const struct i2c_spec_values fast_mode_spec =
+{
+    .min_hold_start_ns = 600,
+    .min_low_ns = 1300,
+    .min_high_ns = 600,
+    .min_setup_start_ns = 600,
+    .max_data_hold_ns = 900,
+    .min_data_setup_ns = 100,
+    .min_setup_stop_ns = 600,
+    .min_hold_buffer_ns = 1300,
+};
+
+static const struct i2c_spec_values fast_mode_plus_spec =
+{
+    .min_hold_start_ns = 260,
+    .min_low_ns = 500,
+    .min_high_ns = 260,
+    .min_setup_start_ns = 260,
+    .max_data_hold_ns = 400,
+    .min_data_setup_ns = 50,
+    .min_setup_stop_ns = 260,
+    .min_hold_buffer_ns = 500,
+};
+
+/*
+ * Calculated V1 timings, setup/hold start time and setup stop time for v1's
+ * calc_timings, the tuning should all be 0 for old hardware anyone using v0's
+ * calc_timings.
+ */
+struct rk3x_i2c_calced_timings
+{
+    rt_ubase_t div_low;     /* Divider output for low */
+    rt_ubase_t div_high;    /* Divider output for high */
+    rt_uint32_t tuning;     /* Used to adjust setup/hold data time */
+};
+
+enum rk3x_i2c_state
+{
+    STATE_IDLE,
+    STATE_START,
+    STATE_READ,
+    STATE_WRITE,
+    STATE_STOP
+};
+
+struct rk3x_i2c_soc_data
+{
+    int grf_offset;
+    rt_err_t (*calc_timings)(rt_ubase_t, struct i2c_timings *,
+            struct rk3x_i2c_calced_timings *);
+};
+
+struct rk3x_i2c
+{
+    struct rt_i2c_bus_device parent;
+
+    const struct rk3x_i2c_soc_data *soc_data;
+
+    int irq;
+    void *regs;
+
+    struct rt_clk *clk;
+    struct rt_clk *pclk;
+    struct rt_clk_notifier clk_notifier;
+
+    struct i2c_timings timings;
+
+    struct rt_spinlock lock;
+    struct rt_completion done;
+
+    struct rt_i2c_msg *msg;
+    rt_uint8_t addr;
+    rt_uint32_t mode;
+    rt_bool_t is_last_msg;
+
+    enum rk3x_i2c_state state;
+    rt_uint32_t processed;
+    rt_err_t error;
+};
+
+#define raw_to_rk3x_i2c(raw) rt_container_of(raw, struct rk3x_i2c, parent)
+
+rt_inline void i2c_writel(struct rk3x_i2c *i2c, rt_uint32_t value, int offset)
+{
+    HWREG32(i2c->regs + offset) = value;
+}
+
+rt_inline rt_uint32_t i2c_readl(struct rk3x_i2c *i2c, int offset)
+{
+    return HWREG32(i2c->regs + offset);
+}
+
+/* Reset all interrupt pending bits */
+rt_inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c)
+{
+    i2c_writel(i2c, REG_INT_ALL, REG_IPD);
+}
+
+/* Generate a START condition, which triggers a REG_INT_START interrupt */
+static void rk3x_i2c_start(struct rk3x_i2c *i2c)
+{
+    rt_uint32_t val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK;
+
+    i2c_writel(i2c, REG_INT_START, REG_IEN);
+
+    /* enable adapter with correct mode, send START condition */
+    val |= REG_CON_EN | REG_CON_MOD(i2c->mode) | REG_CON_START;
+
+    /* if we want to react to NACK, set ACTACK bit */
+    if (!(i2c->msg->flags & RT_I2C_IGNORE_NACK))
+    {
+        val |= REG_CON_ACTACK;
+    }
+
+    i2c_writel(i2c, val, REG_CON);
+}
+
+/* Generate a STOP condition, which triggers a REG_INT_STOP interrupt */
+static void rk3x_i2c_stop(struct rk3x_i2c *i2c, rt_err_t error)
+{
+    rt_uint32_t ctrl;
+
+    i2c->processed = 0;
+    i2c->msg = RT_NULL;
+    i2c->error = error;
+
+    if (i2c->is_last_msg)
+    {
+        /* Enable stop interrupt */
+        i2c_writel(i2c, REG_INT_STOP, REG_IEN);
+
+        i2c->state = STATE_STOP;
+
+        ctrl = i2c_readl(i2c, REG_CON);
+        ctrl |= REG_CON_STOP;
+        i2c_writel(i2c, ctrl, REG_CON);
+    }
+    else
+    {
+        /* Signal rk3x_i2c_xfer to start the next message. */
+        i2c->state = STATE_IDLE;
+
+        /*
+         * The HW is actually not capable of REPEATED START. But we can
+         * get the intended effect by resetting its internal state
+         * and issuing an ordinary START.
+         */
+        ctrl = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK;
+        i2c_writel(i2c, ctrl, REG_CON);
+
+        /* signal that we are finished with the current msg */
+        rt_completion_done(&i2c->done);
+    }
+}
+
+/* Setup a read according to i2c->msg */
+static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c)
+{
+    rt_uint32_t con, len = i2c->msg->len - i2c->processed;
+
+    con = i2c_readl(i2c, REG_CON);
+
+    /*
+     * The hw can read up to 32 bytes at a time. If we need more than one
+     * chunk, send an ACK after the last byte of the current chunk.
+     */
+    if (len > 32)
+    {
+        len = 32;
+        con &= ~REG_CON_LASTACK;
+    }
+    else
+    {
+        con |= REG_CON_LASTACK;
+    }
+
+    /* make sure we are in plain RX mode if we read a second chunk */
+    if (i2c->processed != 0)
+    {
+        con &= ~REG_CON_MOD_MASK;
+        con |= REG_CON_MOD(REG_CON_MOD_RX);
+    }
+
+    i2c_writel(i2c, con, REG_CON);
+    i2c_writel(i2c, len, REG_MRXCNT);
+}
+
+/* Fill the transmit buffer with data from i2c->msg */
+static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c)
+{
+    rt_uint32_t cnt = 0;
+
+    for (int i = 0; i < 8; ++i)
+    {
+        rt_uint32_t val = 0;
+
+        for (int j = 0; j < 4; ++j)
+        {
+            rt_uint8_t byte;
+
+            if ((i2c->processed == i2c->msg->len) && (cnt != 0))
+            {
+                break;
+            }
+
+            if (i2c->processed == 0 && cnt == 0)
+            {
+                byte = (i2c->addr & 0x7f) << 1;
+            }
+            else
+            {
+                byte = i2c->msg->buf[i2c->processed++];
+            }
+
+            val |= byte << (j * 8);
+            cnt++;
+        }
+
+        i2c_writel(i2c, val, TXBUFFER_BASE + 4 * i);
+
+        if (i2c->processed == i2c->msg->len)
+        {
+            break;
+        }
+    }
+
+    i2c_writel(i2c, cnt, REG_MTXCNT);
+}
+
+/* IRQ handlers for individual states */
+static void rk3x_i2c_handle_start(struct rk3x_i2c *i2c, rt_uint32_t ipd)
+{
+    if (!(ipd & REG_INT_START))
+    {
+        rk3x_i2c_stop(i2c, -RT_EIO);
+        LOG_W("Unexpected irq in START: 0x%x", ipd);
+        rk3x_i2c_clean_ipd(i2c);
+
+        return;
+    }
+
+    /* ack interrupt */
+    i2c_writel(i2c, REG_INT_START, REG_IPD);
+
+    /* disable start bit */
+    i2c_writel(i2c, i2c_readl(i2c, REG_CON) & ~REG_CON_START, REG_CON);
+
+    /* enable appropriate interrupts and transition */
+    if (i2c->mode == REG_CON_MOD_TX)
+    {
+        i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN);
+        i2c->state = STATE_WRITE;
+        rk3x_i2c_fill_transmit_buf(i2c);
+    }
+    else
+    {
+        /* in any other case, we are going to be reading. */
+        i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN);
+        i2c->state = STATE_READ;
+        rk3x_i2c_prepare_read(i2c);
+    }
+}
+
+static void rk3x_i2c_handle_write(struct rk3x_i2c *i2c, rt_uint32_t ipd)
+{
+    if (!(ipd & REG_INT_MBTF))
+    {
+        rk3x_i2c_stop(i2c, -RT_EIO);
+        LOG_E("Unexpected irq in WRITE: 0x%x", ipd);
+        rk3x_i2c_clean_ipd(i2c);
+
+        return;
+    }
+
+    /* ack interrupt */
+    i2c_writel(i2c, REG_INT_MBTF, REG_IPD);
+
+    /* are we finished? */
+    if (i2c->processed == i2c->msg->len)
+    {
+        rk3x_i2c_stop(i2c, i2c->error);
+    }
+    else
+    {
+        rk3x_i2c_fill_transmit_buf(i2c);
+    }
+}
+
+static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd)
+{
+    rt_uint32_t val = 0, len = i2c->msg->len - i2c->processed;
+
+    /* we only care for MBRF here. */
+    if (!(ipd & REG_INT_MBRF))
+    {
+        return;
+    }
+
+    /* ack interrupt (read also produces a spurious START flag, clear it too) */
+    i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD);
+
+    /* Can only handle a maximum of 32 bytes at a time */
+    if (len > 32)
+    {
+        len = 32;
+    }
+
+    /* read the data from receive buffer */
+    for (int i = 0; i < len; ++i)
+    {
+        rt_uint8_t byte;
+
+        if (i % 4 == 0)
+        {
+            val = i2c_readl(i2c, RXBUFFER_BASE + (i / 4) * 4);
+        }
+
+        byte = (val >> ((i % 4) * 8)) & 0xff;
+        i2c->msg->buf[i2c->processed++] = byte;
+    }
+
+    /* are we finished? */
+    if (i2c->processed == i2c->msg->len)
+    {
+        rk3x_i2c_stop(i2c, i2c->error);
+    }
+    else
+    {
+        rk3x_i2c_prepare_read(i2c);
+    }
+}
+
+static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, rt_uint32_t ipd)
+{
+    rt_uint32_t con;
+
+    if (!(ipd & REG_INT_STOP))
+    {
+        rk3x_i2c_stop(i2c, -RT_EIO);
+        LOG_E("Unexpected irq in STOP: 0x%x", ipd);
+        rk3x_i2c_clean_ipd(i2c);
+
+        return;
+    }
+
+    /* ack interrupt */
+    i2c_writel(i2c, REG_INT_STOP, REG_IPD);
+
+    /* disable STOP bit */
+    con = i2c_readl(i2c, REG_CON);
+    con &= ~REG_CON_STOP;
+    i2c_writel(i2c, con, REG_CON);
+
+    i2c->state = STATE_IDLE;
+
+    /* signal rk3x_i2c_xfer that we are finished */
+    rt_completion_done(&i2c->done);
+}
+
+static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, rt_ubase_t clk_rate)
+{
+    rt_err_t err;
+    rt_ubase_t level;
+    rt_uint32_t val;
+    struct rk3x_i2c_calced_timings calc;
+    struct i2c_timings *timings = &i2c->timings;
+
+    if ((err = i2c->soc_data->calc_timings(clk_rate, timings, &calc)))
+    {
+        LOG_W("Could not reach SCL freq %u", timings->bus_freq_hz);
+    }
+
+    rt_clk_enable(i2c->pclk);
+
+    level = rt_spin_lock_irqsave(&i2c->lock);
+
+    val = i2c_readl(i2c, REG_CON);
+    val &= ~REG_CON_TUNING_MASK;
+    val |= calc.tuning;
+    i2c_writel(i2c, val, REG_CON);
+    i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff), REG_CLKDIV);
+
+    rt_spin_unlock_irqrestore(&i2c->lock, level);
+
+    rt_clk_disable(i2c->pclk);
+}
+
+static rt_err_t rk3x_i2c_clk_notifier(struct rt_clk_notifier *notifier,
+        rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate)
+{
+    struct rk3x_i2c_calced_timings calc;
+    struct rk3x_i2c *i2c = rt_container_of(notifier, struct rk3x_i2c, clk_notifier);
+
+    switch (msg)
+    {
+    case RT_CLK_MSG_PRE_RATE_CHANGE:
+        /*
+         * Try the calculation (but don't store the result) ahead of
+         * time to see if we need to block the clock change.  Timings
+         * shouldn't actually take effect until rk3x_i2c_adapt_div().
+         */
+        if (i2c->soc_data->calc_timings(new_rate, &i2c->timings, &calc) != 0)
+        {
+            return -RT_EIO;
+        }
+
+        /* scale up */
+        if (new_rate > old_rate)
+        {
+            rk3x_i2c_adapt_div(i2c, new_rate);
+        }
+        break;
+
+    case RT_CLK_MSG_POST_RATE_CHANGE:
+        /* scale down */
+        if (new_rate < old_rate)
+        {
+            rk3x_i2c_adapt_div(i2c, new_rate);
+        }
+        break;
+
+    case RT_CLK_MSG_ABORT_RATE_CHANGE:
+        /* scale up */
+        if (new_rate > old_rate)
+        {
+            rk3x_i2c_adapt_div(i2c, old_rate);
+        }
+        break;
+
+    default:
+        break;
+    }
+
+    return RT_EOK;
+}
+
+static const struct i2c_spec_values *rk3x_i2c_get_spec(rt_uint32_t speed)
+{
+    if (speed <= I2C_MAX_STANDARD_MODE_FREQ)
+    {
+        return &standard_mode_spec;
+    }
+    else if (speed <= I2C_MAX_FAST_MODE_FREQ)
+    {
+        return &fast_mode_spec;
+    }
+    else
+    {
+        return &fast_mode_plus_spec;
+    }
+}
+
+/**
+ * rk3x_i2c_v0_calc_timings - Calculate divider values for desired SCL frequency
+ * @clk_rate: I2C input clock rate
+ * @t: Known I2C timing information
+ * @t_calc: Caculated rk3x private timings that would be written into regs
+ *
+ * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case
+ * a best-effort divider value is returned in divs. If the target rate is
+ * too high, we silently use the highest possible rate.
+ */
+static rt_err_t rk3x_i2c_v0_calc_timings(rt_ubase_t clk_rate,
+        struct i2c_timings *t, struct rk3x_i2c_calced_timings *t_calc)
+{
+    rt_err_t err = RT_EOK;
+    rt_ubase_t min_low_ns, min_high_ns;
+    rt_ubase_t max_low_ns, min_total_ns;
+    rt_ubase_t clk_rate_khz, scl_rate_khz;
+    rt_ubase_t min_low_div, min_high_div;
+    rt_ubase_t max_low_div;
+    rt_ubase_t min_div_for_hold, min_total_div;
+    rt_ubase_t extra_div, extra_low_div, ideal_low_div;
+    rt_ubase_t data_hold_buffer_ns = 50;
+    const struct i2c_spec_values *spec;
+
+    /* Only support standard-mode and fast-mode */
+    if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ)
+    {
+        t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
+    }
+
+    /* prevent scl_rate_khz from becoming 0 */
+    if (t->bus_freq_hz < 1000)
+    {
+        t->bus_freq_hz = 1000;
+    }
+
+    /*
+     * min_low_ns:  The minimum number of ns we need to hold low to
+     *      meet I2C specification, should include fall time.
+     * min_high_ns: The minimum number of ns we need to hold high to
+     *      meet I2C specification, should include rise time.
+     * max_low_ns:  The maximum number of ns we can hold low to meet
+     *      I2C specification.
+     *
+     * Note: max_low_ns should be (maximum data hold time * 2 - buffer)
+     *   This is because the i2c host on Rockchip holds the data line
+     *   for half the low time.
+     */
+    spec = rk3x_i2c_get_spec(t->bus_freq_hz);
+    min_high_ns = t->scl_rise_ns + spec->min_high_ns;
+
+    /*
+     * Timings for repeated start:
+     * - controller appears to drop SDA at .875x (7/8) programmed clk high.
+     * - controller appears to keep SCL high for 2x programmed clk high.
+     *
+     * We need to account for those rules in picking our "high" time so
+     * we meet tSU;STA and tHD;STA times.
+     */
+    min_high_ns = rt_max(min_high_ns, RT_DIV_ROUND_UP(
+            (t->scl_rise_ns + spec->min_setup_start_ns) * 1000, 875));
+    min_high_ns = rt_max(min_high_ns, RT_DIV_ROUND_UP(
+            (t->scl_rise_ns + spec->min_setup_start_ns + t->sda_fall_ns +
+            spec->min_high_ns), 2));
+
+    min_low_ns = t->scl_fall_ns + spec->min_low_ns;
+    max_low_ns =  spec->max_data_hold_ns * 2 - data_hold_buffer_ns;
+    min_total_ns = min_low_ns + min_high_ns;
+
+    /* Adjust to avoid overflow */
+    clk_rate_khz = RT_DIV_ROUND_UP(clk_rate, 1000);
+    scl_rate_khz = t->bus_freq_hz / 1000;
+
+    /*
+     * We need the total div to be >= this number
+     * so we don't clock too fast.
+     */
+    min_total_div = RT_DIV_ROUND_UP(clk_rate_khz, scl_rate_khz * 8);
+
+    /* These are the min dividers needed for min hold times. */
+    min_low_div = RT_DIV_ROUND_UP(clk_rate_khz * min_low_ns, 8 * 1000000);
+    min_high_div = RT_DIV_ROUND_UP(clk_rate_khz * min_high_ns, 8 * 1000000);
+    min_div_for_hold = (min_low_div + min_high_div);
+
+    /*
+     * This is the maximum divider so we don't go over the maximum.
+     * We don't round up here (we round down) since this is a maximum.
+     */
+    max_low_div = clk_rate_khz * max_low_ns / (8 * 1000000);
+
+    if (min_low_div > max_low_div)
+    {
+        max_low_div = min_low_div;
+    }
+
+    if (min_div_for_hold > min_total_div)
+    {
+        /* Time needed to meet hold requirements is important. Just use that. */
+        t_calc->div_low = min_low_div;
+        t_calc->div_high = min_high_div;
+    }
+    else
+    {
+        /*
+         * We've got to distribute some time among the low and high
+         * so we don't run too fast.
+         */
+        extra_div = min_total_div - min_div_for_hold;
+
+        /*
+         * We'll try to split things up perfectly evenly,
+         * biasing slightly towards having a higher div
+         * for low (spend more time low).
+         */
+        ideal_low_div = RT_DIV_ROUND_UP(clk_rate_khz * min_low_ns,
+                scl_rate_khz * 8 * min_total_ns);
+
+        /* Don't allow it to go over the maximum */
+        if (ideal_low_div > max_low_div)
+        {
+            ideal_low_div = max_low_div;
+        }
+
+        /* Handle when the ideal low div is going to take up more than we have. */
+        if (ideal_low_div > min_low_div + extra_div)
+        {
+            ideal_low_div = min_low_div + extra_div;
+        }
+
+        /* Give low the "ideal" and give high whatever extra is left */
+        extra_low_div = ideal_low_div - min_low_div;
+        t_calc->div_low = ideal_low_div;
+        t_calc->div_high = min_high_div + (extra_div - extra_low_div);
+    }
+
+    /*
+     * Adjust to the fact that the hardware has an implicit "+1".
+     * NOTE: Above calculations always produce div_low > 0 and div_high > 0.
+     */
+    --t_calc->div_low;
+    --t_calc->div_high;
+
+    /* Give the tuning value 0, that would not update con register */
+    t_calc->tuning = 0;
+
+    /* Maximum divider supported by hw is 0xffff */
+    if (t_calc->div_low > 0xffff)
+    {
+        t_calc->div_low = 0xffff;
+        err = -RT_EINVAL;
+    }
+
+    if (t_calc->div_high > 0xffff)
+    {
+        t_calc->div_high = 0xffff;
+        err = -RT_EINVAL;
+    }
+
+    return err;
+}
+
+/**
+ * rk3x_i2c_v1_calc_timings - Calculate timing values for desired SCL frequency
+ * @clk_rate: I2C input clock rate
+ * @t: Known I2C timing information
+ * @t_calc: Caculated rk3x private timings that would be written into regs
+ *
+ * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case
+ * a best-effort divider value is returned in divs. If the target rate is
+ * too high, we silently use the highest possible rate.
+ * The following formulas are v1's method to calculate timings.
+ *
+ * l = divl + 1;
+ * h = divh + 1;
+ * s = sda_update_config + 1;
+ * u = start_setup_config + 1;
+ * p = stop_setup_config + 1;
+ * T = Tclk_i2c;
+ *
+ * tHigh = 8 * h * T;
+ * tLow = 8 * l * T;
+ *
+ * tHD;sda = (l * s + 1) * T;
+ * tSU;sda = [(8 - s) * l + 1] * T;
+ * tI2C = 8 * (l + h) * T;
+ *
+ * tSU;sta = (8h * u + 1) * T;
+ * tHD;sta = [8h * (u + 1) - 1] * T;
+ * tSU;sto = (8h * p + 1) * T;
+ */
+static rt_err_t rk3x_i2c_v1_calc_timings(rt_ubase_t clk_rate,
+        struct i2c_timings *t, struct rk3x_i2c_calced_timings *t_calc)
+{
+    rt_err_t err = 0;
+    rt_ubase_t min_low_ns, min_high_ns;
+    rt_ubase_t min_setup_start_ns, min_setup_data_ns;
+    rt_ubase_t min_setup_stop_ns, max_hold_data_ns;
+    rt_ubase_t clk_rate_khz, scl_rate_khz;
+    rt_ubase_t min_low_div, min_high_div;
+    rt_ubase_t min_div_for_hold, min_total_div;
+    rt_ubase_t extra_div, extra_low_div;
+    rt_ubase_t sda_update_cfg, stp_sta_cfg, stp_sto_cfg;
+    const struct i2c_spec_values *spec;
+
+    /* Support standard-mode, fast-mode and fast-mode plus */
+    if (t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ)
+    {
+        t->bus_freq_hz = I2C_MAX_FAST_MODE_PLUS_FREQ;
+    }
+
+    /* prevent scl_rate_khz from becoming 0 */
+    if (t->bus_freq_hz < 1000)
+    {
+        t->bus_freq_hz = 1000;
+    }
+
+    /*
+     * min_low_ns: The minimum number of ns we need to hold low to
+     *         meet I2C specification, should include fall time.
+     * min_high_ns: The minimum number of ns we need to hold high to
+     *          meet I2C specification, should include rise time.
+     */
+    spec = rk3x_i2c_get_spec(t->bus_freq_hz);
+
+    /* calculate min-divh and min-divl */
+    clk_rate_khz = RT_DIV_ROUND_UP(clk_rate, 1000);
+    scl_rate_khz = t->bus_freq_hz / 1000;
+    min_total_div = RT_DIV_ROUND_UP(clk_rate_khz, scl_rate_khz * 8);
+
+    min_high_ns = t->scl_rise_ns + spec->min_high_ns;
+    min_high_div = RT_DIV_ROUND_UP(clk_rate_khz * min_high_ns, 8 * 1000000);
+
+    min_low_ns = t->scl_fall_ns + spec->min_low_ns;
+    min_low_div = RT_DIV_ROUND_UP(clk_rate_khz * min_low_ns, 8 * 1000000);
+
+    /*
+     * Final divh and divl must be greater than 0, otherwise the
+     * hardware would not output the i2c clk.
+     */
+    min_high_div = (min_high_div < 1) ? 2 : min_high_div;
+    min_low_div = (min_low_div < 1) ? 2 : min_low_div;
+
+    /* These are the min dividers needed for min hold times. */
+    min_div_for_hold = (min_low_div + min_high_div);
+
+    /*
+     * This is the maximum divider so we don't go over the maximum.
+     * We don't round up here (we round down) since this is a maximum.
+     */
+    if (min_div_for_hold >= min_total_div)
+    {
+        /*
+         * Time needed to meet hold requirements is important.
+         * Just use that.
+         */
+        t_calc->div_low = min_low_div;
+        t_calc->div_high = min_high_div;
+    }
+    else
+    {
+        /*
+         * We've got to distribute some time among the low and high
+         * so we don't run too fast.
+         * We'll try to split things up by the scale of min_low_div and
+         * min_high_div, biasing slightly towards having a higher div
+         * for low (spend more time low).
+         */
+        extra_div = min_total_div - min_div_for_hold;
+        extra_low_div = RT_DIV_ROUND_UP(min_low_div * extra_div, min_div_for_hold);
+
+        t_calc->div_low = min_low_div + extra_low_div;
+        t_calc->div_high = min_high_div + (extra_div - extra_low_div);
+    }
+
+    /*
+     * calculate sda data hold count by the rules, data_upd_st:3
+     * is a appropriate value to reduce calculated times.
+     */
+    for (sda_update_cfg = 3; sda_update_cfg > 0; --sda_update_cfg)
+    {
+        max_hold_data_ns =  RT_DIV_ROUND_UP((sda_update_cfg
+                * (t_calc->div_low) + 1) * 1000000, clk_rate_khz);
+        min_setup_data_ns =  RT_DIV_ROUND_UP(((8 - sda_update_cfg)
+                * (t_calc->div_low) + 1) * 1000000, clk_rate_khz);
+
+        if (max_hold_data_ns < spec->max_data_hold_ns &&
+            min_setup_data_ns > spec->min_data_setup_ns)
+        {
+            break;
+        }
+    }
+
+    /* calculate setup start config */
+    min_setup_start_ns = t->scl_rise_ns + spec->min_setup_start_ns;
+    stp_sta_cfg = RT_DIV_ROUND_UP(clk_rate_khz * min_setup_start_ns - 1000000,
+            8 * 1000000 * (t_calc->div_high));
+
+    /* calculate setup stop config */
+    min_setup_stop_ns = t->scl_rise_ns + spec->min_setup_stop_ns;
+    stp_sto_cfg = RT_DIV_ROUND_UP(clk_rate_khz * min_setup_stop_ns - 1000000,
+            8 * 1000000 * (t_calc->div_high));
+
+    t_calc->tuning = REG_CON_SDA_CFG(--sda_update_cfg) |
+            REG_CON_STA_CFG(--stp_sta_cfg) | REG_CON_STO_CFG(--stp_sto_cfg);
+
+    --t_calc->div_low;
+    --t_calc->div_high;
+
+    /* Maximum divider supported by hw is 0xffff */
+    if (t_calc->div_low > 0xffff)
+    {
+        t_calc->div_low = 0xffff;
+        err = -RT_EINVAL;
+    }
+
+    if (t_calc->div_high > 0xffff)
+    {
+        t_calc->div_high = 0xffff;
+        err = -RT_EINVAL;
+    }
+
+    return err;
+}
+
+/* Setup I2C registers for an I2C operation specified by msgs, num */
+static rt_ssize_t rk3x_i2c_setup(struct rk3x_i2c *i2c, struct rt_i2c_msg *msgs,
+        int num)
+{
+    rt_ssize_t res = 0;
+    rt_uint32_t addr = (msgs[0].addr & 0x7f) << 1;
+
+    /*
+     * The I2C adapter can issue a small (len < 4) write packet before
+     * reading. This speeds up SMBus-style register reads.
+     * The MRXADDR/MRXRADDR hold the slave address and the slave register
+     * address in this case.
+     */
+
+    if (num >= 2 && msgs[0].len < 4 &&
+        !(msgs[0].flags & RT_I2C_RD) && (msgs[1].flags & RT_I2C_RD))
+    {
+        rt_uint32_t reg_addr = 0;
+
+        LOG_D("Combined write/read from addr 0x%x", addr >> 1);
+
+        /* Fill MRXRADDR with the register address(es) */
+        for (int i = 0; i < msgs[0].len; ++i)
+        {
+            reg_addr |= msgs[0].buf[i] << (i * 8);
+            reg_addr |= REG_MRXADDR_VALID(i);
+        }
+
+        /* msgs[0] is handled by hw. */
+        i2c->msg = &msgs[1];
+        i2c->mode = REG_CON_MOD_REGISTER_TX;
+
+        i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), REG_MRXADDR);
+        i2c_writel(i2c, reg_addr, REG_MRXRADDR);
+
+        res = 2;
+    }
+    else
+    {
+        /* We'll have to do it the boring way and process the msgs one-by-one. */
+        if (msgs[0].flags & RT_I2C_RD)
+        {
+            /* set read bit */
+            addr |= 1;
+
+            /*
+             * We have to transmit the slave addr first. Use
+             * MOD_REGISTER_TX for that purpose.
+             */
+            i2c->mode = REG_CON_MOD_REGISTER_TX;
+            i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), REG_MRXADDR);
+            i2c_writel(i2c, 0, REG_MRXRADDR);
+        }
+        else
+        {
+            i2c->mode = REG_CON_MOD_TX;
+        }
+
+        i2c->msg = &msgs[0];
+
+        res = 1;
+    }
+
+    i2c->addr = msgs[0].addr;
+    i2c->state = STATE_START;
+    i2c->processed = 0;
+    i2c->error = RT_EOK;
+
+    rk3x_i2c_clean_ipd(i2c);
+
+    return res;
+}
+
+static rt_ssize_t rk3x_i2c_master_xfer(struct rt_i2c_bus_device *bus,
+        struct rt_i2c_msg msgs[], rt_uint32_t num)
+{
+    rt_ssize_t res = 0;
+    rt_uint32_t val;
+    rt_ubase_t level;
+    rt_err_t timeout_err;
+    struct rk3x_i2c *i2c = raw_to_rk3x_i2c(bus);
+
+    level = rt_spin_lock_irqsave(&i2c->lock);
+
+    rt_clk_enable(i2c->clk);
+    rt_clk_enable(i2c->pclk);
+
+    i2c->is_last_msg = RT_FALSE;
+
+    /* Process msgs */
+    for (int i = 0; i < num; i += res)
+    {
+        res = rk3x_i2c_setup(i2c, msgs + i, num - i);
+
+        if (res < 0)
+        {
+            LOG_E("%s setup failed", rt_dm_dev_get_name(&i2c->parent.parent));
+
+            break;
+        }
+
+        if (i + res >= num)
+        {
+            i2c->is_last_msg = RT_TRUE;
+        }
+
+        rt_spin_unlock_irqrestore(&i2c->lock, level);
+
+        rk3x_i2c_start(i2c);
+
+        timeout_err = rt_completion_wait(&i2c->done, rt_tick_from_millisecond(WAIT_TIMEOUT));
+
+        level = rt_spin_lock_irqsave(&i2c->lock);
+
+        if (timeout_err)
+        {
+            LOG_E("timeout, ipd: 0x%02x, state: %d", i2c_readl(i2c, REG_IPD), i2c->state);
+
+            /* Force a STOP condition without interrupt */
+            i2c_writel(i2c, 0, REG_IEN);
+            val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK;
+            val |= REG_CON_EN | REG_CON_STOP;
+            i2c_writel(i2c, val, REG_CON);
+
+            i2c->state = STATE_IDLE;
+
+            res = timeout_err;
+            break;
+        }
+
+        if (i2c->error)
+        {
+            res = i2c->error;
+
+            break;
+        }
+    }
+
+    rt_clk_disable(i2c->pclk);
+    rt_clk_disable(i2c->clk);
+
+    rt_spin_unlock_irqrestore(&i2c->lock, level);
+
+    return res < 0 ? res : num;
+}
+
+const static struct rt_i2c_bus_device_ops rk3x_i2c_ops =
+{
+    .master_xfer = rk3x_i2c_master_xfer,
+};
+
+static void rk3x_i2c_isr(int irqno, void *param)
+{
+    rt_uint32_t ipd;
+    struct rk3x_i2c *i2c = param;
+
+    rt_spin_lock(&i2c->lock);
+
+    ipd = i2c_readl(i2c, REG_IPD);
+
+    if (i2c->state == STATE_IDLE)
+    {
+        LOG_W("IRQ in STATE_IDLE, ipd = 0x%x", ipd);
+        rk3x_i2c_clean_ipd(i2c);
+
+        goto _out;
+    }
+
+    LOG_D("IRQ: state %d, ipd: %x", i2c->state, ipd);
+
+    /* Clean interrupt bits we don't care about */
+    ipd &= ~(REG_INT_BRF | REG_INT_BTF);
+
+    if (ipd & REG_INT_NAKRCV)
+    {
+        /*
+         * We got a NACK in the last operation. Depending on whether
+         * IGNORE_NAK is set, we have to stop the operation and report
+         * an error.
+         */
+        i2c_writel(i2c, REG_INT_NAKRCV, REG_IPD);
+
+        ipd &= ~REG_INT_NAKRCV;
+
+        if (!(i2c->msg->flags & RT_I2C_IGNORE_NACK))
+        {
+            LOG_E("Flags error");
+
+            rk3x_i2c_stop(i2c, -RT_EIO);
+        }
+    }
+
+    /* is there anything left to handle? */
+    if ((ipd & REG_INT_ALL) == 0)
+    {
+        goto _out;
+    }
+
+    switch (i2c->state)
+    {
+    case STATE_START:
+        rk3x_i2c_handle_start(i2c, ipd);
+        break;
+
+    case STATE_WRITE:
+        rk3x_i2c_handle_write(i2c, ipd);
+        break;
+
+    case STATE_READ:
+        rk3x_i2c_handle_read(i2c, ipd);
+        break;
+
+    case STATE_STOP:
+        rk3x_i2c_handle_stop(i2c, ipd);
+        break;
+
+    case STATE_IDLE:
+        break;
+    }
+
+_out:
+    rt_spin_unlock(&i2c->lock);
+}
+
+static void rk3x_i2c_free(struct rk3x_i2c *i2c)
+{
+    if (i2c->regs)
+    {
+        rt_iounmap(i2c->regs);
+    }
+
+    if (!rt_is_err_or_null(i2c->clk))
+    {
+        rt_clk_unprepare(i2c->clk);
+        rt_clk_put(i2c->clk);
+    }
+
+    if (!rt_is_err_or_null(i2c->pclk))
+    {
+        if (!rt_is_err_or_null(i2c->clk) && i2c->pclk != i2c->clk)
+        {
+            rt_clk_unprepare(i2c->pclk);
+            rt_clk_put(i2c->pclk);
+        }
+    }
+
+    if (i2c->clk_notifier.callback)
+    {
+        rt_clk_notifier_unregister(i2c->clk, &i2c->clk_notifier);
+    }
+
+    rt_free(i2c);
+}
+
+static rt_err_t rk3x_i2c_probe(struct rt_platform_device *pdev)
+{
+    int id = -1;
+    rt_err_t err;
+    const char *dev_name;
+    struct rt_device *dev = &pdev->parent;
+    struct rk3x_i2c *i2c = rt_calloc(1, sizeof(*i2c));
+
+    if (!i2c)
+    {
+        return -RT_ENOMEM;
+    }
+
+    i2c->soc_data = pdev->id->data;
+    i2c_timings_ofw_parse(dev->ofw_node, &i2c->timings, RT_TRUE);
+
+    i2c->regs = rt_dm_dev_iomap(dev, 0);
+
+    if (!i2c->regs)
+    {
+        err = -RT_EIO;
+
+        goto _fail;
+    }
+
+    i2c->irq = rt_dm_dev_get_irq(dev, 0);
+
+    if (i2c->irq < 0)
+    {
+        err = i2c->irq;
+
+        goto _fail;
+    }
+
+    if (i2c->soc_data->grf_offset >= 0)
+    {
+        rt_uint32_t value;
+        struct rt_syscon *grf;
+        struct rt_ofw_node *np = dev->ofw_node;
+
+        id = pdev->dev_id;
+
+        if (id < 0)
+        {
+            err = -RT_EINVAL;
+            LOG_E("alias id not found");
+
+            goto _fail;
+        }
+
+        grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,grf");
+
+        if (!grf)
+        {
+            err = -RT_EIO;
+            LOG_E("I2C%d %s not found", id, "rockchip,grf");
+
+            goto _fail;
+        }
+
+        /* 27+i: write mask, 11+i: value */
+        value = RT_BIT(27 + id) | RT_BIT(11 + id);
+
+        if ((err = rt_syscon_write(grf, i2c->soc_data->grf_offset, value)))
+        {
+            LOG_E("Could not write to GRF: %s", rt_strerror(err));
+
+            goto _fail;
+        }
+    }
+
+    if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings)
+    {
+        i2c->clk = rt_clk_get_by_index(dev, 0);
+        i2c->pclk = i2c->clk;
+    }
+    else
+    {
+        i2c->clk = rt_clk_get_by_name(dev, "i2c");
+        i2c->pclk = rt_clk_get_by_name(dev, "pclk");
+    }
+
+    if (rt_is_err(i2c->clk))
+    {
+        err = rt_ptr_err(i2c->clk);
+
+        goto _fail;
+    }
+
+    if ((err = rt_clk_prepare(i2c->clk)))
+    {
+        goto _fail;
+    }
+
+    if (rt_is_err(i2c->pclk))
+    {
+        err = rt_ptr_err(i2c->pclk);
+
+        goto _fail;
+    }
+
+    if ((err = rt_clk_prepare(i2c->pclk)))
+    {
+        goto _fail;
+    }
+
+    i2c->clk_notifier.callback = rk3x_i2c_clk_notifier;
+    if ((err = rt_clk_notifier_register(i2c->clk, &i2c->clk_notifier)))
+    {
+        goto _fail;
+    }
+
+    if ((err = rt_clk_enable(i2c->clk)))
+    {
+        LOG_E("Can't enable bus clk: %s", rt_strerror(err));
+
+        goto _fail;
+    }
+
+    rk3x_i2c_adapt_div(i2c, rt_clk_get_rate(i2c->clk));
+    rt_clk_disable(i2c->clk);
+
+    rt_spin_lock_init(&i2c->lock);
+    rt_completion_init(&i2c->done);
+
+    if (id >= 0)
+    {
+        rt_dm_dev_set_name(&i2c->parent.parent, "i2c%u", id);
+    }
+    else
+    {
+        rt_dm_dev_set_name_auto(&i2c->parent.parent, "i2c");
+    }
+    dev_name = rt_dm_dev_get_name(&i2c->parent.parent);
+
+    rt_hw_interrupt_install(i2c->irq, rk3x_i2c_isr, i2c, dev_name);
+    rt_hw_interrupt_umask(i2c->irq);
+
+    dev->user_data = i2c;
+
+    i2c->parent.ops = &rk3x_i2c_ops;
+    i2c->parent.parent.ofw_node = dev->ofw_node;
+
+    rt_dm_dev_bind_fwdata(dev, RT_NULL, i2c);
+
+    if ((err = rt_i2c_bus_device_register(&i2c->parent, dev_name)))
+    {
+        goto _free_irq;
+    }
+
+    return RT_EOK;
+
+_free_irq:
+    rt_dm_dev_unbind_fwdata(dev, RT_NULL);
+
+    rt_hw_interrupt_mask(i2c->irq);
+    rt_pic_detach_irq(i2c->irq, i2c);
+
+_fail:
+    rk3x_i2c_free(i2c);
+
+    return err;
+}
+
+static rt_err_t rk3x_i2c_remove(struct rt_platform_device *pdev)
+{
+    struct rt_device *dev = &pdev->parent;
+    struct rk3x_i2c *i2c = dev->user_data;
+
+    rt_dm_dev_unbind_fwdata(dev, RT_NULL);
+
+    rt_hw_interrupt_mask(i2c->irq);
+    rt_pic_detach_irq(i2c->irq, i2c);
+
+    rt_device_unregister(&i2c->parent.parent);
+
+    rk3x_i2c_free(i2c);
+
+    return RT_EOK;
+}
+
+static const struct rk3x_i2c_soc_data rv1108_soc_data =
+{
+    .grf_offset = -1,
+    .calc_timings = rk3x_i2c_v1_calc_timings,
+};
+
+static const struct rk3x_i2c_soc_data rv1126_soc_data =
+{
+    .grf_offset = 0x118,
+    .calc_timings = rk3x_i2c_v1_calc_timings,
+};
+
+static const struct rk3x_i2c_soc_data rk3066_soc_data =
+{
+    .grf_offset = 0x154,
+    .calc_timings = rk3x_i2c_v0_calc_timings,
+};
+
+static const struct rk3x_i2c_soc_data rk3188_soc_data =
+{
+    .grf_offset = 0x0a4,
+    .calc_timings = rk3x_i2c_v0_calc_timings,
+};
+
+static const struct rk3x_i2c_soc_data rk3228_soc_data =
+{
+    .grf_offset = -1,
+    .calc_timings = rk3x_i2c_v0_calc_timings,
+};
+
+static const struct rk3x_i2c_soc_data rk3288_soc_data =
+{
+    .grf_offset = -1,
+    .calc_timings = rk3x_i2c_v0_calc_timings,
+};
+
+static const struct rk3x_i2c_soc_data rk3399_soc_data =
+{
+    .grf_offset = -1,
+    .calc_timings = rk3x_i2c_v1_calc_timings,
+};
+
+static const struct rt_ofw_node_id rk3x_i2c_ofw_ids[] =
+{
+    { .compatible = "rockchip,rv1108-i2c", .data = &rv1108_soc_data },
+    { .compatible = "rockchip,rv1126-i2c", .data = &rv1126_soc_data },
+    { .compatible = "rockchip,rk3066-i2c", .data = &rk3066_soc_data },
+    { .compatible = "rockchip,rk3188-i2c", .data = &rk3188_soc_data },
+    { .compatible = "rockchip,rk3228-i2c", .data = &rk3228_soc_data },
+    { .compatible = "rockchip,rk3288-i2c", .data = &rk3288_soc_data },
+    { .compatible = "rockchip,rk3399-i2c", .data = &rk3399_soc_data },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rk3x_i2c_driver =
+{
+    .name = "rk3x-i2c",
+    .ids = rk3x_i2c_ofw_ids,
+
+    .probe = rk3x_i2c_probe,
+    .remove = rk3x_i2c_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rk3x_i2c_driver);

+ 387 - 0
bsp/rockchip/dm/include/dt-bindings/clock/rk3308-cru.h

@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3308_H__
+#define __DT_BINDINGS_CLK_ROCKCHIP_RK3308_H__
+
+/* core clocks */
+#define PLL_APLL                1
+#define PLL_DPLL                2
+#define PLL_VPLL0               3
+#define PLL_VPLL1               4
+#define ARMCLK                  5
+
+/* sclk (special clocks) */
+#define USB480M                 14
+#define SCLK_RTC32K             15
+#define SCLK_PVTM_CORE          16
+#define SCLK_UART0              17
+#define SCLK_UART1              18
+#define SCLK_UART2              19
+#define SCLK_UART3              20
+#define SCLK_UART4              21
+#define SCLK_I2C0               22
+#define SCLK_I2C1               23
+#define SCLK_I2C2               24
+#define SCLK_I2C3               25
+#define SCLK_PWM0               26
+#define SCLK_SPI0               27
+#define SCLK_SPI1               28
+#define SCLK_SPI2               29
+#define SCLK_TIMER0             30
+#define SCLK_TIMER1             31
+#define SCLK_TIMER2             32
+#define SCLK_TIMER3             33
+#define SCLK_TIMER4             34
+#define SCLK_TIMER5             35
+#define SCLK_TSADC              36
+#define SCLK_SARADC             37
+#define SCLK_OTP                38
+#define SCLK_OTP_USR            39
+#define SCLK_CPU_BOOST          40
+#define SCLK_CRYPTO             41
+#define SCLK_CRYPTO_APK         42
+#define SCLK_NANDC_DIV          43
+#define SCLK_NANDC_DIV50        44
+#define SCLK_NANDC              45
+#define SCLK_SDMMC_DIV          46
+#define SCLK_SDMMC_DIV50        47
+#define SCLK_SDMMC              48
+#define SCLK_SDMMC_DRV          49
+#define SCLK_SDMMC_SAMPLE       50
+#define SCLK_SDIO_DIV           51
+#define SCLK_SDIO_DIV50         52
+#define SCLK_SDIO               53
+#define SCLK_SDIO_DRV           54
+#define SCLK_SDIO_SAMPLE        55
+#define SCLK_EMMC_DIV           56
+#define SCLK_EMMC_DIV50         57
+#define SCLK_EMMC               58
+#define SCLK_EMMC_DRV           59
+#define SCLK_EMMC_SAMPLE        60
+#define SCLK_SFC                61
+#define SCLK_OTG_ADP            62
+#define SCLK_MAC_SRC            63
+#define SCLK_MAC                64
+#define SCLK_MAC_REF            65
+#define SCLK_MAC_RX_TX          66
+#define SCLK_MAC_RMII           67
+#define SCLK_DDR_MON_TIMER      68
+#define SCLK_DDR_MON            69
+#define SCLK_DDRCLK             70
+#define SCLK_PMU                71
+#define SCLK_USBPHY_REF         72
+#define SCLK_WIFI               73
+#define SCLK_PVTM_PMU           74
+#define SCLK_PDM                75
+#define SCLK_I2S0_8CH_TX        76
+#define SCLK_I2S0_8CH_TX_OUT    77
+#define SCLK_I2S0_8CH_RX        78
+#define SCLK_I2S0_8CH_RX_OUT    79
+#define SCLK_I2S1_8CH_TX        80
+#define SCLK_I2S1_8CH_TX_OUT    81
+#define SCLK_I2S1_8CH_RX        82
+#define SCLK_I2S1_8CH_RX_OUT    83
+#define SCLK_I2S2_8CH_TX        84
+#define SCLK_I2S2_8CH_TX_OUT    85
+#define SCLK_I2S2_8CH_RX        86
+#define SCLK_I2S2_8CH_RX_OUT    87
+#define SCLK_I2S3_8CH_TX        88
+#define SCLK_I2S3_8CH_TX_OUT    89
+#define SCLK_I2S3_8CH_RX        90
+#define SCLK_I2S3_8CH_RX_OUT    91
+#define SCLK_I2S0_2CH           92
+#define SCLK_I2S0_2CH_OUT       93
+#define SCLK_I2S1_2CH           94
+#define SCLK_I2S1_2CH_OUT       95
+#define SCLK_SPDIF_TX_DIV       96
+#define SCLK_SPDIF_TX_DIV50     97
+#define SCLK_SPDIF_TX           98
+#define SCLK_SPDIF_RX_DIV       99
+#define SCLK_SPDIF_RX_DIV50     100
+#define SCLK_SPDIF_RX           101
+#define SCLK_I2S0_8CH_TX_MUX    102
+#define SCLK_I2S0_8CH_RX_MUX    103
+#define SCLK_I2S1_8CH_TX_MUX    104
+#define SCLK_I2S1_8CH_RX_MUX    105
+#define SCLK_I2S2_8CH_TX_MUX    106
+#define SCLK_I2S2_8CH_RX_MUX    107
+#define SCLK_I2S3_8CH_TX_MUX    108
+#define SCLK_I2S3_8CH_RX_MUX    109
+#define SCLK_I2S0_8CH_TX_SRC    110
+#define SCLK_I2S0_8CH_RX_SRC    111
+#define SCLK_I2S1_8CH_TX_SRC    112
+#define SCLK_I2S1_8CH_RX_SRC    113
+#define SCLK_I2S2_8CH_TX_SRC    114
+#define SCLK_I2S2_8CH_RX_SRC    115
+#define SCLK_I2S3_8CH_TX_SRC    116
+#define SCLK_I2S3_8CH_RX_SRC    117
+#define SCLK_I2S0_2CH_SRC       118
+#define SCLK_I2S1_2CH_SRC       119
+#define SCLK_PWM1               120
+#define SCLK_PWM2               121
+#define SCLK_OWIRE              122
+
+/* dclk */
+#define DCLK_VOP                125
+
+/* aclk */
+#define ACLK_BUS_SRC            130
+#define ACLK_BUS                131
+#define ACLK_PERI_SRC           132
+#define ACLK_PERI               133
+#define ACLK_MAC                134
+#define ACLK_CRYPTO             135
+#define ACLK_VOP                136
+#define ACLK_GIC                137
+#define ACLK_DMAC0              138
+#define ACLK_DMAC1              139
+
+/* hclk */
+#define HCLK_BUS                150
+#define HCLK_PERI               151
+#define HCLK_AUDIO              152
+#define HCLK_NANDC              153
+#define HCLK_SDMMC              154
+#define HCLK_SDIO               155
+#define HCLK_EMMC               156
+#define HCLK_SFC                157
+#define HCLK_OTG                158
+#define HCLK_HOST               159
+#define HCLK_HOST_ARB           160
+#define HCLK_PDM                161
+#define HCLK_SPDIFTX            162
+#define HCLK_SPDIFRX            163
+#define HCLK_I2S0_8CH           164
+#define HCLK_I2S1_8CH           165
+#define HCLK_I2S2_8CH           166
+#define HCLK_I2S3_8CH           167
+#define HCLK_I2S0_2CH           168
+#define HCLK_I2S1_2CH           169
+#define HCLK_VAD                170
+#define HCLK_CRYPTO             171
+#define HCLK_VOP                172
+
+/* pclk */
+#define PCLK_BUS                190
+#define PCLK_DDR                191
+#define PCLK_PERI               192
+#define PCLK_PMU                193
+#define PCLK_AUDIO              194
+#define PCLK_MAC                195
+#define PCLK_ACODEC             196
+#define PCLK_UART0              197
+#define PCLK_UART1              198
+#define PCLK_UART2              199
+#define PCLK_UART3              200
+#define PCLK_UART4              201
+#define PCLK_I2C0               202
+#define PCLK_I2C1               203
+#define PCLK_I2C2               204
+#define PCLK_I2C3               205
+#define PCLK_PWM0               206
+#define PCLK_SPI0               207
+#define PCLK_SPI1               208
+#define PCLK_SPI2               209
+#define PCLK_SARADC             210
+#define PCLK_TSADC              211
+#define PCLK_TIMER              212
+#define PCLK_OTP_NS             213
+#define PCLK_WDT                214
+#define PCLK_GPIO0              215
+#define PCLK_GPIO1              216
+#define PCLK_GPIO2              217
+#define PCLK_GPIO3              218
+#define PCLK_GPIO4              219
+#define PCLK_SGRF               220
+#define PCLK_GRF                221
+#define PCLK_USBSD_DET          222
+#define PCLK_DDR_UPCTL          223
+#define PCLK_DDR_MON            224
+#define PCLK_DDRPHY             225
+#define PCLK_DDR_STDBY          226
+#define PCLK_USB_GRF            227
+#define PCLK_CRU                228
+#define PCLK_OTP_PHY            229
+#define PCLK_CPU_BOOST          230
+#define PCLK_PWM1               231
+#define PCLK_PWM2               232
+#define PCLK_CAN                233
+#define PCLK_OWIRE              234
+
+#define CLK_NR_CLKS             (PCLK_OWIRE + 1)
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_CORE0_PO           0
+#define SRST_CORE1_PO           1
+#define SRST_CORE2_PO           2
+#define SRST_CORE3_PO           3
+#define SRST_CORE0              4
+#define SRST_CORE1              5
+#define SRST_CORE2              6
+#define SRST_CORE3              7
+#define SRST_CORE0_DBG          8
+#define SRST_CORE1_DBG          9
+#define SRST_CORE2_DBG          10
+#define SRST_CORE3_DBG          11
+#define SRST_TOPDBG             12
+#define SRST_CORE_NOC           13
+#define SRST_STRC_A             14
+#define SRST_L2C                15
+
+/* cru_softrst_con1 */
+#define SRST_DAP                16
+#define SRST_CORE_PVTM          17
+#define SRST_CORE_PRF           18
+#define SRST_CORE_GRF           19
+#define SRST_DDRUPCTL           20
+#define SRST_DDRUPCTL_P         22
+#define SRST_MSCH               23
+#define SRST_DDRMON_P           25
+#define SRST_DDRSTDBY_P         26
+#define SRST_DDRSTDBY           27
+#define SRST_DDRPHY             28
+#define SRST_DDRPHY_DIV         29
+#define SRST_DDRPHY_P           30
+
+/* cru_softrst_con2 */
+#define SRST_BUS_NIU_H          32
+#define SRST_USB_NIU_P          33
+#define SRST_CRYPTO_A           34
+#define SRST_CRYPTO_H           35
+#define SRST_CRYPTO             36
+#define SRST_CRYPTO_APK         37
+#define SRST_VOP_A              38
+#define SRST_VOP_H              39
+#define SRST_VOP_D              40
+#define SRST_INTMEM_A           41
+#define SRST_ROM_H              42
+#define SRST_GIC_A              43
+#define SRST_UART0_P            44
+#define SRST_UART0              45
+#define SRST_UART1_P            46
+#define SRST_UART1              47
+
+/* cru_softrst_con3 */
+#define SRST_UART2_P            48
+#define SRST_UART2              49
+#define SRST_UART3_P            50
+#define SRST_UART3              51
+#define SRST_UART4_P            52
+#define SRST_UART4              53
+#define SRST_I2C0_P             54
+#define SRST_I2C0               55
+#define SRST_I2C1_P             56
+#define SRST_I2C1               57
+#define SRST_I2C2_P             58
+#define SRST_I2C2               59
+#define SRST_I2C3_P             60
+#define SRST_I2C3               61
+#define SRST_PWM0_P             62
+#define SRST_PWM0               63
+
+/* cru_softrst_con4 */
+#define SRST_SPI0_P             64
+#define SRST_SPI0               65
+#define SRST_SPI1_P             66
+#define SRST_SPI1               67
+#define SRST_SPI2_P             68
+#define SRST_SPI2               69
+#define SRST_SARADC_P           70
+#define SRST_TSADC_P            71
+#define SRST_TSADC              72
+#define SRST_TIMER0_P           73
+#define SRST_TIMER0             74
+#define SRST_TIMER1             75
+#define SRST_TIMER2             76
+#define SRST_TIMER3             77
+#define SRST_TIMER4             78
+#define SRST_TIMER5             79
+
+/* cru_softrst_con5 */
+#define SRST_OTP_NS_P           80
+#define SRST_OTP_NS_SBPI        81
+#define SRST_OTP_NS_USR         82
+#define SRST_OTP_PHY_P          83
+#define SRST_OTP_PHY            84
+#define SRST_GPIO0_P            86
+#define SRST_GPIO1_P            87
+#define SRST_GPIO2_P            88
+#define SRST_GPIO3_P            89
+#define SRST_GPIO4_P            90
+#define SRST_GRF_P              91
+#define SRST_USBSD_DET_P        92
+#define SRST_PMU                93
+#define SRST_PMU_PVTM           94
+#define SRST_USB_GRF_P          95
+
+/* cru_softrst_con6 */
+#define SRST_CPU_BOOST          96
+#define SRST_CPU_BOOST_P        97
+#define SRST_PWM1_P             98
+#define SRST_PWM1               99
+#define SRST_PWM2_P             100
+#define SRST_PWM2               101
+#define SRST_PERI_NIU_A         104
+#define SRST_PERI_NIU_H         105
+#define SRST_PERI_NIU_p         106
+#define SRST_USB2OTG_H          107
+#define SRST_USB2OTG            108
+#define SRST_USB2OTG_ADP        109
+#define SRST_USB2HOST_H         110
+#define SRST_USB2HOST_ARB_H     111
+
+/* cru_softrst_con7 */
+#define SRST_USB2HOST_AUX_H     112
+#define SRST_USB2HOST_EHCI      113
+#define SRST_USB2HOST           114
+#define SRST_USBPHYPOR          115
+#define SRST_UTMI0              116
+#define SRST_UTMI1              117
+#define SRST_SDIO_H             118
+#define SRST_EMMC_H             119
+#define SRST_SFC_H              120
+#define SRST_SFC                121
+#define SRST_SD_H               122
+#define SRST_NANDC_H            123
+#define SRST_NANDC_N            124
+#define SRST_MAC_A              125
+#define SRST_CAN_P              126
+#define SRST_OWIRE_P            127
+
+/* cru_softrst_con8 */
+#define SRST_AUDIO_NIU_H        128
+#define SRST_AUDIO_NIU_P        129
+#define SRST_PDM_H              130
+#define SRST_PDM_M              131
+#define SRST_SPDIFTX_H          132
+#define SRST_SPDIFTX_M          133
+#define SRST_SPDIFRX_H          134
+#define SRST_SPDIFRX_M          135
+#define SRST_I2S0_8CH_H         136
+#define SRST_I2S0_8CH_TX_M      137
+#define SRST_I2S0_8CH_RX_M      138
+#define SRST_I2S1_8CH_H         139
+#define SRST_I2S1_8CH_TX_M      140
+#define SRST_I2S1_8CH_RX_M      141
+#define SRST_I2S2_8CH_H         142
+#define SRST_I2S2_8CH_TX_M      143
+
+/* cru_softrst_con9 */
+#define SRST_I2S2_8CH_RX_M      144
+#define SRST_I2S3_8CH_H         145
+#define SRST_I2S3_8CH_TX_M      146
+#define SRST_I2S3_8CH_RX_M      147
+#define SRST_I2S0_2CH_H         148
+#define SRST_I2S0_2CH_M         149
+#define SRST_I2S1_2CH_H         150
+#define SRST_I2S1_2CH_M         151
+#define SRST_VAD_H              152
+#define SRST_ACODEC_P           153
+
+#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3308_H__ */

+ 7 - 1
bsp/rockchip/rk3500/driver/clk/rk3568-cru.h → bsp/rockchip/dm/include/dt-bindings/clock/rk3568-cru.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2024 RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -479,6 +479,12 @@
 #define CPLL_25M                416
 #define CPLL_100M               417
 #define SCLK_DDRCLK             418
+#define I2S1_MCLKOUT			419
+#define I2S3_MCLKOUT			420
+#define I2S1_MCLK_RX_IOE		421
+#define I2S1_MCLK_TX_IOE		422
+#define I2S2_MCLK_IOE			423
+#define I2S3_MCLK_IOE			424
 
 #define PCLK_CORE_PVTM          450
 

+ 1151 - 0
bsp/rockchip/dm/include/dt-bindings/clock/rk3576-cru.h

@@ -0,0 +1,1151 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3576_H__
+#define __DT_BINDINGS_CLK_ROCKCHIP_RK3576_H__
+
+/* cru-clocks indices */
+
+/* cru plls */
+#define PLL_BPLL                        1
+#define PLL_LPLL                        3
+#define PLL_VPLL                        4
+#define PLL_AUPLL                       5
+#define PLL_CPLL                        6
+#define PLL_GPLL                        7
+#define PLL_PPLL                        9
+#define ARMCLK_L                        10
+#define ARMCLK_B                        11
+
+/* cru clocks */
+#define CLK_CPLL_DIV20                  15
+#define CLK_CPLL_DIV10                  16
+#define CLK_GPLL_DIV8                   17
+#define CLK_GPLL_DIV6                   18
+#define CLK_CPLL_DIV4                   19
+#define CLK_GPLL_DIV4                   20
+#define CLK_SPLL_DIV2                   21
+#define CLK_GPLL_DIV3                   22
+#define CLK_CPLL_DIV2                   23
+#define CLK_GPLL_DIV2                   24
+#define CLK_SPLL_DIV1                   25
+#define PCLK_TOP_ROOT                   26
+#define ACLK_TOP                        27
+#define HCLK_TOP                        28
+#define CLK_AUDIO_FRAC_0                29
+#define CLK_AUDIO_FRAC_1                30
+#define CLK_AUDIO_FRAC_2                31
+#define CLK_AUDIO_FRAC_3                32
+#define CLK_UART_FRAC_0                 33
+#define CLK_UART_FRAC_1                 34
+#define CLK_UART_FRAC_2                 35
+#define CLK_UART1_SRC_TOP               36
+#define CLK_AUDIO_INT_0                 37
+#define CLK_AUDIO_INT_1                 38
+#define CLK_AUDIO_INT_2                 39
+#define CLK_PDM0_SRC_TOP                40
+#define CLK_PDM1_OUT                    41
+#define CLK_GMAC0_125M_SRC              42
+#define CLK_GMAC1_125M_SRC              43
+#define LCLK_ASRC_SRC_0                 44
+#define LCLK_ASRC_SRC_1                 45
+#define REF_CLK0_OUT_PLL                46
+#define REF_CLK1_OUT_PLL                47
+#define REF_CLK2_OUT_PLL                48
+#define REFCLKO25M_GMAC0_OUT            49
+#define REFCLKO25M_GMAC1_OUT            50
+#define CLK_CIFOUT_OUT                  51
+#define CLK_GMAC0_RMII_CRU              52
+#define CLK_GMAC1_RMII_CRU              53
+#define CLK_OTPC_AUTO_RD_G              54
+#define CLK_OTP_PHY_G                   55
+#define CLK_MIPI_CAMERAOUT_M0           56
+#define CLK_MIPI_CAMERAOUT_M1           57
+#define CLK_MIPI_CAMERAOUT_M2           58
+#define MCLK_PDM0_SRC_TOP               59
+#define HCLK_AUDIO_ROOT                 60
+#define HCLK_ASRC_2CH_0                 61
+#define HCLK_ASRC_2CH_1                 62
+#define HCLK_ASRC_4CH_0                 63
+#define HCLK_ASRC_4CH_1                 64
+#define CLK_ASRC_2CH_0                  65
+#define CLK_ASRC_2CH_1                  66
+#define CLK_ASRC_4CH_0                  67
+#define CLK_ASRC_4CH_1                  68
+#define MCLK_SAI0_8CH_SRC               69
+#define MCLK_SAI0_8CH                   70
+#define HCLK_SAI0_8CH                   71
+#define HCLK_SPDIF_RX0                  72
+#define MCLK_SPDIF_RX0                  73
+#define HCLK_SPDIF_RX1                  74
+#define MCLK_SPDIF_RX1                  75
+#define MCLK_SAI1_8CH_SRC               76
+#define MCLK_SAI1_8CH                   77
+#define HCLK_SAI1_8CH                   78
+#define MCLK_SAI2_2CH_SRC               79
+#define MCLK_SAI2_2CH                   80
+#define HCLK_SAI2_2CH                   81
+#define MCLK_SAI3_2CH_SRC               82
+#define MCLK_SAI3_2CH                   83
+#define HCLK_SAI3_2CH                   84
+#define MCLK_SAI4_2CH_SRC               85
+#define MCLK_SAI4_2CH                   86
+#define HCLK_SAI4_2CH                   87
+#define HCLK_ACDCDIG_DSM                88
+#define MCLK_ACDCDIG_DSM                89
+#define CLK_PDM1                        90
+#define HCLK_PDM1                       91
+#define MCLK_PDM1                       92
+#define HCLK_SPDIF_TX0                  93
+#define MCLK_SPDIF_TX0                  94
+#define HCLK_SPDIF_TX1                  95
+#define MCLK_SPDIF_TX1                  96
+#define CLK_SAI1_MCLKOUT                97
+#define CLK_SAI2_MCLKOUT                98
+#define CLK_SAI3_MCLKOUT                99
+#define CLK_SAI4_MCLKOUT                100
+#define CLK_SAI0_MCLKOUT                101
+#define HCLK_BUS_ROOT                   102
+#define PCLK_BUS_ROOT                   103
+#define ACLK_BUS_ROOT                   104
+#define HCLK_CAN0                       105
+#define CLK_CAN0                        106
+#define HCLK_CAN1                       107
+#define CLK_CAN1                        108
+#define CLK_KEY_SHIFT                   109
+#define PCLK_I2C1                       110
+#define PCLK_I2C2                       111
+#define PCLK_I2C3                       112
+#define PCLK_I2C4                       113
+#define PCLK_I2C5                       114
+#define PCLK_I2C6                       115
+#define PCLK_I2C7                       116
+#define PCLK_I2C8                       117
+#define PCLK_I2C9                       118
+#define PCLK_WDT_BUSMCU                 119
+#define TCLK_WDT_BUSMCU                 120
+#define ACLK_GIC                        121
+#define CLK_I2C1                        122
+#define CLK_I2C2                        123
+#define CLK_I2C3                        124
+#define CLK_I2C4                        125
+#define CLK_I2C5                        126
+#define CLK_I2C6                        127
+#define CLK_I2C7                        128
+#define CLK_I2C8                        129
+#define CLK_I2C9                        130
+#define PCLK_SARADC                     131
+#define CLK_SARADC                      132
+#define PCLK_TSADC                      133
+#define CLK_TSADC                       134
+#define PCLK_UART0                      135
+#define PCLK_UART2                      136
+#define PCLK_UART3                      137
+#define PCLK_UART4                      138
+#define PCLK_UART5                      139
+#define PCLK_UART6                      140
+#define PCLK_UART7                      141
+#define PCLK_UART8                      142
+#define PCLK_UART9                      143
+#define PCLK_UART10                     144
+#define PCLK_UART11                     145
+#define SCLK_UART0                      146
+#define SCLK_UART2                      147
+#define SCLK_UART3                      148
+#define SCLK_UART4                      149
+#define SCLK_UART5                      150
+#define SCLK_UART6                      151
+#define SCLK_UART7                      152
+#define SCLK_UART8                      153
+#define SCLK_UART9                      154
+#define SCLK_UART10                     155
+#define SCLK_UART11                     156
+#define PCLK_SPI0                       157
+#define PCLK_SPI1                       158
+#define PCLK_SPI2                       159
+#define PCLK_SPI3                       160
+#define PCLK_SPI4                       161
+#define CLK_SPI0                        162
+#define CLK_SPI1                        163
+#define CLK_SPI2                        164
+#define CLK_SPI3                        165
+#define CLK_SPI4                        166
+#define PCLK_WDT0                       167
+#define TCLK_WDT0                       168
+#define PCLK_PWM1                       169
+#define CLK_PWM1                        170
+#define CLK_OSC_PWM1                    171
+#define CLK_RC_PWM1                     172
+#define PCLK_BUSTIMER0                  173
+#define PCLK_BUSTIMER1                  174
+#define CLK_TIMER0_ROOT                 175
+#define CLK_TIMER0                      176
+#define CLK_TIMER1                      177
+#define CLK_TIMER2                      178
+#define CLK_TIMER3                      179
+#define CLK_TIMER4                      180
+#define CLK_TIMER5                      181
+#define PCLK_MAILBOX0                   182
+#define PCLK_GPIO1                      183
+#define DBCLK_GPIO1                     184
+#define PCLK_GPIO2                      185
+#define DBCLK_GPIO2                     186
+#define PCLK_GPIO3                      187
+#define DBCLK_GPIO3                     188
+#define PCLK_GPIO4                      189
+#define DBCLK_GPIO4                     190
+#define ACLK_DECOM                      191
+#define PCLK_DECOM                      192
+#define DCLK_DECOM                      193
+#define CLK_TIMER1_ROOT                 194
+#define CLK_TIMER6                      195
+#define CLK_TIMER7                      196
+#define CLK_TIMER8                      197
+#define CLK_TIMER9                      198
+#define CLK_TIMER10                     199
+#define CLK_TIMER11                     200
+#define ACLK_DMAC0                      201
+#define ACLK_DMAC1                      202
+#define ACLK_DMAC2                      203
+#define ACLK_SPINLOCK                   204
+#define HCLK_I3C0                       205
+#define HCLK_I3C1                       206
+#define HCLK_BUS_CM0_ROOT               207
+#define FCLK_BUS_CM0_CORE               208
+#define CLK_BUS_CM0_RTC                 209
+#define PCLK_PMU2                       210
+#define PCLK_PWM2                       211
+#define CLK_PWM2                        212
+#define CLK_RC_PWM2                     213
+#define CLK_OSC_PWM2                    214
+#define CLK_FREQ_PWM1                   215
+#define CLK_COUNTER_PWM1                216
+#define SAI_SCLKIN_FREQ                 217
+#define SAI_SCLKIN_COUNTER              218
+#define CLK_I3C0                        219
+#define CLK_I3C1                        220
+#define PCLK_CSIDPHY1                   221
+#define PCLK_DDR_ROOT                   222
+#define PCLK_DDR_MON_CH0                223
+#define TMCLK_DDR_MON_CH0               224
+#define ACLK_DDR_ROOT                   225
+#define HCLK_DDR_ROOT                   226
+#define FCLK_DDR_CM0_CORE               227
+#define CLK_DDR_TIMER_ROOT              228
+#define CLK_DDR_TIMER0                  229
+#define CLK_DDR_TIMER1                  230
+#define TCLK_WDT_DDR                    231
+#define PCLK_WDT                        232
+#define PCLK_TIMER                      233
+#define CLK_DDR_CM0_RTC                 234
+#define ACLK_RKNN0                      235
+#define ACLK_RKNN1                      236
+#define HCLK_RKNN_ROOT                  237
+#define CLK_RKNN_DSU0                   238
+#define PCLK_NPUTOP_ROOT                239
+#define PCLK_NPU_TIMER                  240
+#define CLK_NPUTIMER_ROOT               241
+#define CLK_NPUTIMER0                   242
+#define CLK_NPUTIMER1                   243
+#define PCLK_NPU_WDT                    244
+#define TCLK_NPU_WDT                    245
+#define ACLK_RKNN_CBUF                  246
+#define HCLK_NPU_CM0_ROOT               247
+#define FCLK_NPU_CM0_CORE               248
+#define CLK_NPU_CM0_RTC                 249
+#define HCLK_RKNN_CBUF                  250
+#define HCLK_NVM_ROOT                   251
+#define ACLK_NVM_ROOT                   252
+#define SCLK_FSPI_X2                    253
+#define HCLK_FSPI                       254
+#define CCLK_SRC_EMMC                   255
+#define HCLK_EMMC                       256
+#define ACLK_EMMC                       257
+#define BCLK_EMMC                       258
+#define TCLK_EMMC                       259
+#define PCLK_PHP_ROOT                   260
+#define ACLK_PHP_ROOT                   261
+#define PCLK_PCIE0                      262
+#define CLK_PCIE0_AUX                   263
+#define ACLK_PCIE0_MST                  264
+#define ACLK_PCIE0_SLV                  265
+#define ACLK_PCIE0_DBI                  266
+#define ACLK_USB3OTG1                   267
+#define CLK_REF_USB3OTG1                268
+#define CLK_SUSPEND_USB3OTG1            269
+#define ACLK_MMU0                       270
+#define ACLK_SLV_MMU0                   271
+#define ACLK_MMU1                       272
+#define ACLK_SLV_MMU1                   273
+#define PCLK_PCIE1                      275
+#define CLK_PCIE1_AUX                   276
+#define ACLK_PCIE1_MST                  277
+#define ACLK_PCIE1_SLV                  278
+#define ACLK_PCIE1_DBI                  279
+#define CLK_RXOOB0                      280
+#define CLK_RXOOB1                      281
+#define CLK_PMALIVE0                    282
+#define CLK_PMALIVE1                    283
+#define ACLK_SATA0                      284
+#define ACLK_SATA1                      285
+#define CLK_USB3OTG1_PIPE_PCLK          286
+#define CLK_USB3OTG1_UTMI               287
+#define CLK_USB3OTG0_PIPE_PCLK          288
+#define CLK_USB3OTG0_UTMI               289
+#define HCLK_SDGMAC_ROOT                290
+#define ACLK_SDGMAC_ROOT                291
+#define PCLK_SDGMAC_ROOT                292
+#define ACLK_GMAC0                      293
+#define ACLK_GMAC1                      294
+#define PCLK_GMAC0                      295
+#define PCLK_GMAC1                      296
+#define CCLK_SRC_SDIO                   297
+#define HCLK_SDIO                       298
+#define CLK_GMAC1_PTP_REF               299
+#define CLK_GMAC0_PTP_REF               300
+#define CLK_GMAC1_PTP_REF_SRC           301
+#define CLK_GMAC0_PTP_REF_SRC           302
+#define CCLK_SRC_SDMMC0                 303
+#define HCLK_SDMMC0                     304
+#define SCLK_FSPI1_X2                   305
+#define HCLK_FSPI1                      306
+#define ACLK_DSMC_ROOT                  307
+#define ACLK_DSMC                       308
+#define PCLK_DSMC                       309
+#define CLK_DSMC_SYS                    310
+#define HCLK_HSGPIO                     311
+#define CLK_HSGPIO_TX                   312
+#define CLK_HSGPIO_RX                   313
+#define ACLK_HSGPIO                     314
+#define PCLK_PHPPHY_ROOT                315
+#define PCLK_PCIE2_COMBOPHY0            316
+#define PCLK_PCIE2_COMBOPHY1            317
+#define CLK_PCIE_100M_SRC               318
+#define CLK_PCIE_100M_NDUTY_SRC         319
+#define CLK_REF_PCIE0_PHY               320
+#define CLK_REF_PCIE1_PHY               321
+#define CLK_REF_MPHY_26M                322
+#define HCLK_RKVDEC_ROOT                323
+#define ACLK_RKVDEC_ROOT                324
+#define HCLK_RKVDEC                     325
+#define CLK_RKVDEC_HEVC_CA              326
+#define CLK_RKVDEC_CORE                 327
+#define ACLK_UFS_ROOT                   328
+#define ACLK_USB_ROOT                   329
+#define PCLK_USB_ROOT                   330
+#define ACLK_USB3OTG0                   331
+#define CLK_REF_USB3OTG0                332
+#define CLK_SUSPEND_USB3OTG0            333
+#define ACLK_MMU2                       334
+#define ACLK_SLV_MMU2                   335
+#define ACLK_UFS_SYS                    336
+#define ACLK_VPU_ROOT                   337
+#define ACLK_VPU_MID_ROOT               338
+#define HCLK_VPU_ROOT                   339
+#define ACLK_JPEG_ROOT                  340
+#define ACLK_VPU_LOW_ROOT               341
+#define HCLK_RGA2E_0                    342
+#define ACLK_RGA2E_0                    343
+#define CLK_CORE_RGA2E_0                344
+#define ACLK_JPEG                       345
+#define HCLK_JPEG                       346
+#define HCLK_VDPP                       347
+#define ACLK_VDPP                       348
+#define CLK_CORE_VDPP                   349
+#define HCLK_RGA2E_1                    350
+#define ACLK_RGA2E_1                    351
+#define CLK_CORE_RGA2E_1                352
+#define DCLK_EBC_FRAC_SRC               353
+#define HCLK_EBC                        354
+#define ACLK_EBC                        355
+#define DCLK_EBC                        356
+#define HCLK_VEPU0_ROOT                 357
+#define ACLK_VEPU0_ROOT                 358
+#define HCLK_VEPU0                      359
+#define ACLK_VEPU0                      360
+#define CLK_VEPU0_CORE                  361
+#define ACLK_VI_ROOT                    362
+#define HCLK_VI_ROOT                    363
+#define PCLK_VI_ROOT                    364
+#define DCLK_VICAP                      365
+#define ACLK_VICAP                      366
+#define HCLK_VICAP                      367
+#define CLK_ISP_CORE                    368
+#define CLK_ISP_CORE_MARVIN             369
+#define CLK_ISP_CORE_VICAP              370
+#define ACLK_ISP                        371
+#define HCLK_ISP                        372
+#define ACLK_VPSS                       373
+#define HCLK_VPSS                       374
+#define CLK_CORE_VPSS                   375
+#define PCLK_CSI_HOST_0                 376
+#define PCLK_CSI_HOST_1                 377
+#define PCLK_CSI_HOST_2                 378
+#define PCLK_CSI_HOST_3                 379
+#define PCLK_CSI_HOST_4                 380
+#define ICLK_CSIHOST01                  381
+#define ICLK_CSIHOST0                   382
+#define CLK_ISP_PVTPLL_SRC              383
+#define ACLK_VI_ROOT_INTER              384
+#define CLK_VICAP_I0CLK                 385
+#define CLK_VICAP_I1CLK                 386
+#define CLK_VICAP_I2CLK                 387
+#define CLK_VICAP_I3CLK                 388
+#define CLK_VICAP_I4CLK                 389
+#define ACLK_VOP_ROOT                   390
+#define HCLK_VOP_ROOT                   391
+#define PCLK_VOP_ROOT                   392
+#define HCLK_VOP                        393
+#define ACLK_VOP                        394
+#define DCLK_VP0_SRC                    395
+#define DCLK_VP1_SRC                    396
+#define DCLK_VP2_SRC                    397
+#define DCLK_VP0                        398
+#define DCLK_VP1                        400
+#define DCLK_VP2                        401
+#define PCLK_VOPGRF                     402
+#define ACLK_VO0_ROOT                   403
+#define HCLK_VO0_ROOT                   404
+#define PCLK_VO0_ROOT                   405
+#define PCLK_VO0_GRF                    406
+#define ACLK_HDCP0                      407
+#define HCLK_HDCP0                      408
+#define PCLK_HDCP0                      409
+#define CLK_TRNG0_SKP                   410
+#define PCLK_DSIHOST0                   411
+#define CLK_DSIHOST0                    412
+#define PCLK_HDMITX0                    413
+#define CLK_HDMITX0_EARC                414
+#define CLK_HDMITX0_REF                 415
+#define PCLK_EDP0                       416
+#define CLK_EDP0_24M                    417
+#define CLK_EDP0_200M                   418
+#define MCLK_SAI5_8CH_SRC               419
+#define MCLK_SAI5_8CH                   420
+#define HCLK_SAI5_8CH                   421
+#define MCLK_SAI6_8CH_SRC               422
+#define MCLK_SAI6_8CH                   423
+#define HCLK_SAI6_8CH                   424
+#define HCLK_SPDIF_TX2                  425
+#define MCLK_SPDIF_TX2                  426
+#define HCLK_SPDIF_RX2                  427
+#define MCLK_SPDIF_RX2                  428
+#define HCLK_SAI8_8CH                   429
+#define MCLK_SAI8_8CH_SRC               430
+#define MCLK_SAI8_8CH                   431
+#define ACLK_VO1_ROOT                   432
+#define HCLK_VO1_ROOT                   433
+#define PCLK_VO1_ROOT                   434
+#define MCLK_SAI7_8CH_SRC               435
+#define MCLK_SAI7_8CH                   436
+#define HCLK_SAI7_8CH                   437
+#define HCLK_SPDIF_TX3                  438
+#define HCLK_SPDIF_TX4                  439
+#define HCLK_SPDIF_TX5                  440
+#define MCLK_SPDIF_TX3                  441
+#define CLK_AUX16MHZ_0                  442
+#define ACLK_DP0                        443
+#define PCLK_DP0                        444
+#define PCLK_VO1_GRF                    445
+#define ACLK_HDCP1                      446
+#define HCLK_HDCP1                      447
+#define PCLK_HDCP1                      448
+#define CLK_TRNG1_SKP                   449
+#define HCLK_SAI9_8CH                   450
+#define MCLK_SAI9_8CH_SRC               451
+#define MCLK_SAI9_8CH                   452
+#define MCLK_SPDIF_TX4                  453
+#define MCLK_SPDIF_TX5                  454
+#define CLK_GPU_SRC_PRE                 455
+#define CLK_GPU                         456
+#define PCLK_GPU_ROOT                   457
+#define ACLK_CENTER_ROOT                458
+#define ACLK_CENTER_LOW_ROOT            459
+#define HCLK_CENTER_ROOT                460
+#define PCLK_CENTER_ROOT                461
+#define ACLK_DMA2DDR                    462
+#define ACLK_DDR_SHAREMEM               463
+#define PCLK_DMA2DDR                    464
+#define PCLK_SHAREMEM                   465
+#define HCLK_VEPU1_ROOT                 466
+#define ACLK_VEPU1_ROOT                 467
+#define HCLK_VEPU1                      468
+#define ACLK_VEPU1                      469
+#define CLK_VEPU1_CORE                  470
+#define CLK_JDBCK_DAP                   471
+#define PCLK_MIPI_DCPHY                 472
+#define CLK_32K_USB2DEBUG               473
+#define PCLK_CSIDPHY                    474
+#define PCLK_USBDPPHY                   475
+#define CLK_PMUPHY_REF_SRC              476
+#define CLK_USBDP_COMBO_PHY_IMMORTAL    477
+#define CLK_HDMITXHPD                   478
+#define PCLK_MPHY                       479
+#define CLK_REF_OSC_MPHY                480
+#define CLK_REF_UFS_CLKOUT              481
+#define HCLK_PMU1_ROOT                  482
+#define HCLK_PMU_CM0_ROOT               483
+#define CLK_200M_PMU_SRC                484
+#define CLK_100M_PMU_SRC                485
+#define CLK_50M_PMU_SRC                 486
+#define FCLK_PMU_CM0_CORE               487
+#define CLK_PMU_CM0_RTC                 488
+#define PCLK_PMU1                       489
+#define CLK_PMU1                        490
+#define PCLK_PMU1WDT                    491
+#define TCLK_PMU1WDT                    492
+#define PCLK_PMUTIMER                   493
+#define CLK_PMUTIMER_ROOT               494
+#define CLK_PMUTIMER0                   495
+#define CLK_PMUTIMER1                   496
+#define PCLK_PMU1PWM                    497
+#define CLK_PMU1PWM                     498
+#define CLK_PMU1PWM_OSC                 499
+#define PCLK_PMUPHY_ROOT                500
+#define PCLK_I2C0                       501
+#define CLK_I2C0                        502
+#define SCLK_UART1                      503
+#define PCLK_UART1                      504
+#define CLK_PMU1PWM_RC                  505
+#define CLK_PDM0                        506
+#define HCLK_PDM0                       507
+#define MCLK_PDM0                       508
+#define HCLK_VAD                        509
+#define CLK_OSCCHK_PVTM                 510
+#define CLK_PDM0_OUT                    511
+#define CLK_HPTIMER_SRC                 512
+#define PCLK_PMU0_ROOT                  516
+#define PCLK_PMU0                       517
+#define PCLK_GPIO0                      518
+#define DBCLK_GPIO0                     519
+#define CLK_OSC0_PMU1                   520
+#define PCLK_PMU1_ROOT                  521
+#define XIN_OSC0_DIV                    522
+#define ACLK_USB                        523
+#define ACLK_UFS                        524
+#define ACLK_SDGMAC                     525
+#define HCLK_SDGMAC                     526
+#define PCLK_SDGMAC                     527
+#define HCLK_VO1                        528
+#define HCLK_VO0                        529
+#define PCLK_CCI_ROOT                   532
+#define ACLK_CCI_ROOT                   533
+#define HCLK_VO0VOP_CHANNEL             534
+#define ACLK_VO0VOP_CHANNEL             535
+#define ACLK_TOP_MID                    536
+#define ACLK_SECURE_HIGH                537
+#define CLK_USBPHY_REF_SRC              538
+#define CLK_PHY_REF_SRC                 539
+#define CLK_CPLL_REF_SRC                540
+#define CLK_AUPLL_REF_SRC               541
+#define PCLK_SECURE_NS                  542
+#define HCLK_SECURE_NS                  543
+#define ACLK_SECURE_NS                  544
+#define PCLK_OTPC_NS                    545
+#define HCLK_CRYPTO_NS                  546
+#define HCLK_TRNG_NS                    547
+#define CLK_OTPC_NS                     548
+#define SCLK_DSU                        549
+#define SCLK_DDR                        550
+#define ACLK_CRYPTO_NS                  551
+#define CLK_PKA_CRYPTO_NS               552
+#define ACLK_RKVDEC_ROOT_BAK            553
+#define CLK_AUDIO_FRAC_0_SRC            554
+#define CLK_AUDIO_FRAC_1_SRC            555
+#define CLK_AUDIO_FRAC_2_SRC            556
+#define CLK_AUDIO_FRAC_3_SRC            557
+#define PCLK_HDPTX_APB                  558
+#define PCLK_DDR_MON_CH1                559
+
+/* secure clk */
+#define CLK_STIMER0_ROOT                600
+#define CLK_STIMER1_ROOT                601
+#define PCLK_SECURE_S                   602
+#define HCLK_SECURE_S                   603
+#define ACLK_SECURE_S                   604
+#define CLK_PKA_CRYPTO_S                605
+#define HCLK_VO1_S                      606
+#define PCLK_VO1_S                      607
+#define HCLK_VO0_S                      608
+#define PCLK_VO0_S                      609
+#define PCLK_KLAD                       610
+#define HCLK_CRYPTO_S                   611
+#define HCLK_KLAD                       612
+#define ACLK_CRYPTO_S                   613
+#define HCLK_TRNG_S                     614
+#define PCLK_OTPC_S                     615
+#define CLK_OTPC_S                      616
+#define PCLK_WDT_S                      617
+#define TCLK_WDT_S                      618
+#define PCLK_HDCP0_TRNG                 619
+#define PCLK_HDCP1_TRNG                 620
+#define HCLK_HDCP_KEY0                  621
+#define HCLK_HDCP_KEY1                  622
+#define PCLK_EDP_S                      623
+#define ACLK_KLAD                       624
+
+#define CLK_NR_CLKS                     (ACLK_KLAD + 1)
+
+/********Name=SOFTRST_CON01,Offset=0xA04********/
+#define SRST_A_TOP_BIU                  19
+#define SRST_P_TOP_BIU                  21
+#define SRST_A_TOP_MID_BIU              22
+#define SRST_A_SECURE_HIGH_BIU          23
+#define SRST_H_TOP_BIU                  30
+/********Name=SOFTRST_CON02,Offset=0xA08********/
+#define SRST_H_VO0VOP_CHANNEL_BIU       32
+#define SRST_A_VO0VOP_CHANNEL_BIU       33
+/********Name=SOFTRST_CON06,Offset=0xA18********/
+#define SRST_BISRINTF                   98
+/********Name=SOFTRST_CON07,Offset=0xA1C********/
+#define SRST_H_AUDIO_BIU                114
+#define SRST_H_ASRC_2CH_0               115
+#define SRST_H_ASRC_2CH_1               116
+#define SRST_H_ASRC_4CH_0               117
+#define SRST_H_ASRC_4CH_1               118
+#define SRST_ASRC_2CH_0                 119
+#define SRST_ASRC_2CH_1                 120
+#define SRST_ASRC_4CH_0                 121
+#define SRST_ASRC_4CH_1                 122
+#define SRST_M_SAI0_8CH                 124
+#define SRST_H_SAI0_8CH                 125
+#define SRST_H_SPDIF_RX0                126
+#define SRST_M_SPDIF_RX0                127
+/********Name=SOFTRST_CON08,Offset=0xA20********/
+#define SRST_H_SPDIF_RX1                128
+#define SRST_M_SPDIF_RX1                129
+#define SRST_M_SAI1_8CH                 133
+#define SRST_H_SAI1_8CH                 134
+#define SRST_M_SAI2_2CH                 136
+#define SRST_H_SAI2_2CH                 138
+#define SRST_M_SAI3_2CH                 140
+#define SRST_H_SAI3_2CH                 142
+/********Name=SOFTRST_CON09,Offset=0xA24********/
+#define SRST_M_SAI4_2CH                 144
+#define SRST_H_SAI4_2CH                 146
+#define SRST_H_ACDCDIG_DSM              147
+#define SRST_M_ACDCDIG_DSM              148
+#define SRST_PDM1                       149
+#define SRST_H_PDM1                     151
+#define SRST_M_PDM1                     152
+#define SRST_H_SPDIF_TX0                153
+#define SRST_M_SPDIF_TX0                154
+#define SRST_H_SPDIF_TX1                155
+#define SRST_M_SPDIF_TX1                156
+/********Name=SOFTRST_CON11,Offset=0xA2C********/
+#define SRST_A_BUS_BIU                  179
+#define SRST_P_BUS_BIU                  180
+#define SRST_P_CRU                      181
+#define SRST_H_CAN0                     182
+#define SRST_CAN0                       183
+#define SRST_H_CAN1                     184
+#define SRST_CAN1                       185
+#define SRST_P_INTMUX2BUS               188
+#define SRST_P_VCCIO_IOC                189
+#define SRST_H_BUS_BIU                  190
+#define SRST_KEY_SHIFT                  191
+/********Name=SOFTRST_CON12,Offset=0xA30********/
+#define SRST_P_I2C1                     192
+#define SRST_P_I2C2                     193
+#define SRST_P_I2C3                     194
+#define SRST_P_I2C4                     195
+#define SRST_P_I2C5                     196
+#define SRST_P_I2C6                     197
+#define SRST_P_I2C7                     198
+#define SRST_P_I2C8                     199
+#define SRST_P_I2C9                     200
+#define SRST_P_WDT_BUSMCU               201
+#define SRST_T_WDT_BUSMCU               202
+#define SRST_A_GIC                      203
+#define SRST_I2C1                       204
+#define SRST_I2C2                       205
+#define SRST_I2C3                       206
+#define SRST_I2C4                       207
+/********Name=SOFTRST_CON13,Offset=0xA34********/
+#define SRST_I2C5                       208
+#define SRST_I2C6                       209
+#define SRST_I2C7                       210
+#define SRST_I2C8                       211
+#define SRST_I2C9                       212
+#define SRST_P_SARADC                   214
+#define SRST_SARADC                     215
+#define SRST_P_TSADC                    216
+#define SRST_TSADC                      217
+#define SRST_P_UART0                    218
+#define SRST_P_UART2                    219
+#define SRST_P_UART3                    220
+#define SRST_P_UART4                    221
+#define SRST_P_UART5                    222
+#define SRST_P_UART6                    223
+/********Name=SOFTRST_CON14,Offset=0xA38********/
+#define SRST_P_UART7                    224
+#define SRST_P_UART8                    225
+#define SRST_P_UART9                    226
+#define SRST_P_UART10                   227
+#define SRST_P_UART11                   228
+#define SRST_S_UART0                    229
+#define SRST_S_UART2                    230
+#define SRST_S_UART3                    233
+#define SRST_S_UART4                    236
+#define SRST_S_UART5                    239
+/********Name=SOFTRST_CON15,Offset=0xA3C********/
+#define SRST_S_UART6                    242
+#define SRST_S_UART7                    245
+#define SRST_S_UART8                    248
+#define SRST_S_UART9                    249
+#define SRST_S_UART10                   250
+#define SRST_S_UART11                   251
+#define SRST_P_SPI0                     253
+#define SRST_P_SPI1                     254
+#define SRST_P_SPI2                     255
+/********Name=SOFTRST_CON16,Offset=0xA40********/
+#define SRST_P_SPI3                     256
+#define SRST_P_SPI4                     257
+#define SRST_SPI0                       258
+#define SRST_SPI1                       259
+#define SRST_SPI2                       260
+#define SRST_SPI3                       261
+#define SRST_SPI4                       262
+#define SRST_P_WDT0                     263
+#define SRST_T_WDT0                     264
+#define SRST_P_SYS_GRF                  265
+#define SRST_P_PWM1                     266
+#define SRST_PWM1                       267
+
+/********Name=SOFTRST_CON17,Offset=0xA44********/
+#define SRST_P_BUSTIMER0                275
+#define SRST_P_BUSTIMER1                276
+#define SRST_TIMER0                     278
+#define SRST_TIMER1                     279
+#define SRST_TIMER2                     280
+#define SRST_TIMER3                     281
+#define SRST_TIMER4                     282
+#define SRST_TIMER5                     283
+#define SRST_P_BUSIOC                   284
+#define SRST_P_MAILBOX0                 285
+#define SRST_P_GPIO1                    287
+/********Name=SOFTRST_CON18,Offset=0xA48********/
+#define SRST_GPIO1                      288
+#define SRST_P_GPIO2                    289
+#define SRST_GPIO2                      290
+#define SRST_P_GPIO3                    291
+#define SRST_GPIO3                      292
+#define SRST_P_GPIO4                    293
+#define SRST_GPIO4                      294
+#define SRST_A_DECOM                    295
+#define SRST_P_DECOM                    296
+#define SRST_D_DECOM                    297
+#define SRST_TIMER6                     299
+#define SRST_TIMER7                     300
+#define SRST_TIMER8                     301
+#define SRST_TIMER9                     302
+#define SRST_TIMER10                    303
+/********Name=SOFTRST_CON19,Offset=0xA4C********/
+#define SRST_TIMER11                    304
+#define SRST_A_DMAC0                    305
+#define SRST_A_DMAC1                    306
+#define SRST_A_DMAC2                    307
+#define SRST_A_SPINLOCK                 308
+#define SRST_REF_PVTPLL_BUS             309
+#define SRST_H_I3C0                     311
+#define SRST_H_I3C1                     313
+#define SRST_H_BUS_CM0_BIU              315
+#define SRST_F_BUS_CM0_CORE             316
+#define SRST_T_BUS_CM0_JTAG             317
+/********Name=SOFTRST_CON20,Offset=0xA50********/
+#define SRST_P_INTMUX2PMU               320
+#define SRST_P_INTMUX2DDR               321
+#define SRST_P_PVTPLL_BUS               323
+#define SRST_P_PWM2                     324
+#define SRST_PWM2                       325
+#define SRST_FREQ_PWM1                  328
+#define SRST_COUNTER_PWM1               329
+#define SRST_I3C0                       332
+#define SRST_I3C1                       333
+/********Name=SOFTRST_CON21,Offset=0xA54********/
+#define SRST_P_DDR_MON_CH0              337
+#define SRST_P_DDR_BIU                  338
+#define SRST_P_DDR_UPCTL_CH0            339
+#define SRST_TM_DDR_MON_CH0             340
+#define SRST_A_DDR_BIU                  341
+#define SRST_DFI_CH0                    342
+#define SRST_DDR_MON_CH0                346
+#define SRST_P_DDR_HWLP_CH0             349
+#define SRST_P_DDR_MON_CH1              350
+#define SRST_P_DDR_HWLP_CH1             351
+/********Name=SOFTRST_CON22,Offset=0xA58********/
+#define SRST_P_DDR_UPCTL_CH1            352
+#define SRST_TM_DDR_MON_CH1             353
+#define SRST_DFI_CH1                    354
+#define SRST_A_DDR01_MSCH0              355
+#define SRST_A_DDR01_MSCH1              356
+#define SRST_DDR_MON_CH1                358
+#define SRST_DDR_SCRAMBLE_CH0           361
+#define SRST_DDR_SCRAMBLE_CH1           362
+#define SRST_P_AHB2APB                  364
+#define SRST_H_AHB2APB                  365
+#define SRST_H_DDR_BIU                  366
+#define SRST_F_DDR_CM0_CORE             367
+/********Name=SOFTRST_CON23,Offset=0xA5C********/
+#define SRST_P_DDR01_MSCH0              369
+#define SRST_P_DDR01_MSCH1              370
+#define SRST_DDR_TIMER0                 372
+#define SRST_DDR_TIMER1                 373
+#define SRST_T_WDT_DDR                  374
+#define SRST_P_WDT                      375
+#define SRST_P_TIMER                    376
+#define SRST_T_DDR_CM0_JTAG             377
+#define SRST_P_DDR_GRF                  379
+/********Name=SOFTRST_CON25,Offset=0xA64********/
+#define SRST_DDR_UPCTL_CH0              401
+#define SRST_A_DDR_UPCTL_0_CH0          402
+#define SRST_A_DDR_UPCTL_1_CH0          403
+#define SRST_A_DDR_UPCTL_2_CH0          404
+#define SRST_A_DDR_UPCTL_3_CH0          405
+#define SRST_A_DDR_UPCTL_4_CH0          406
+/********Name=SOFTRST_CON26,Offset=0xA68********/
+#define SRST_DDR_UPCTL_CH1              417
+#define SRST_A_DDR_UPCTL_0_CH1          418
+#define SRST_A_DDR_UPCTL_1_CH1          419
+#define SRST_A_DDR_UPCTL_2_CH1          420
+#define SRST_A_DDR_UPCTL_3_CH1          421
+#define SRST_A_DDR_UPCTL_4_CH1          422
+/********Name=SOFTRST_CON27,Offset=0xA6C********/
+#define SRST_REF_PVTPLL_DDR             432
+#define SRST_P_PVTPLL_DDR               433
+
+/********Name=SOFTRST_CON28,Offset=0xA70********/
+#define SRST_A_RKNN0                    457
+#define SRST_A_RKNN0_BIU                459
+#define SRST_L_RKNN0_BIU                460
+/********Name=SOFTRST_CON29,Offset=0xA74********/
+#define SRST_A_RKNN1                    464
+#define SRST_A_RKNN1_BIU                466
+#define SRST_L_RKNN1_BIU                467
+/********Name=SOFTRST_CON31,Offset=0xA7C********/
+#define SRST_NPU_DAP                    496
+#define SRST_L_NPUSUBSYS_BIU            497
+#define SRST_P_NPUTOP_BIU               505
+#define SRST_P_NPU_TIMER                506
+#define SRST_NPUTIMER0                  508
+#define SRST_NPUTIMER1                  509
+#define SRST_P_NPU_WDT                  510
+#define SRST_T_NPU_WDT                  511
+/********Name=SOFTRST_CON32,Offset=0xA80********/
+#define SRST_A_RKNN_CBUF                512
+#define SRST_A_RVCORE0                  513
+#define SRST_P_NPU_GRF                  514
+#define SRST_P_PVTPLL_NPU               515
+#define SRST_NPU_PVTPLL                 516
+#define SRST_H_NPU_CM0_BIU              518
+#define SRST_F_NPU_CM0_CORE             519
+#define SRST_T_NPU_CM0_JTAG             520
+#define SRST_A_RKNNTOP_BIU              523
+#define SRST_H_RKNN_CBUF                524
+#define SRST_H_RKNNTOP_BIU              525
+/********Name=SOFTRST_CON33,Offset=0xA84********/
+#define SRST_H_NVM_BIU                  530
+#define SRST_A_NVM_BIU                  531
+#define SRST_S_FSPI                     534
+#define SRST_H_FSPI                     535
+#define SRST_C_EMMC                     536
+#define SRST_H_EMMC                     537
+#define SRST_A_EMMC                     538
+#define SRST_B_EMMC                     539
+#define SRST_T_EMMC                     540
+/********Name=SOFTRST_CON34,Offset=0xA88********/
+#define SRST_P_GRF                      545
+#define SRST_P_PHP_BIU                  549
+#define SRST_A_PHP_BIU                  553
+#define SRST_P_PCIE0                    557
+#define SRST_PCIE0_POWER_UP             559
+/********Name=SOFTRST_CON35,Offset=0xA8C********/
+#define SRST_A_USB3OTG1                 563
+#define SRST_A_MMU0                     571
+#define SRST_A_SLV_MMU0                 573
+#define SRST_A_MMU1                     574
+/********Name=SOFTRST_CON36,Offset=0xA90********/
+#define SRST_A_SLV_MMU1                 576
+#define SRST_P_PCIE1                    583
+#define SRST_PCIE1_POWER_UP             585
+/********Name=SOFTRST_CON37,Offset=0xA94********/
+#define SRST_RXOOB0                     592
+#define SRST_RXOOB1                     593
+#define SRST_PMALIVE0                   594
+#define SRST_PMALIVE1                   595
+#define SRST_A_SATA0                    596
+#define SRST_A_SATA1                    597
+#define SRST_ASIC1                      598
+#define SRST_ASIC0                      599
+/********Name=SOFTRST_CON40,Offset=0xAA0********/
+#define SRST_P_CSIDPHY1                 642
+#define SRST_SCAN_CSIDPHY1              643
+/********Name=SOFTRST_CON42,Offset=0xAA8********/
+#define SRST_P_SDGMAC_GRF               675
+#define SRST_P_SDGMAC_BIU               676
+#define SRST_A_SDGMAC_BIU               677
+#define SRST_H_SDGMAC_BIU               678
+#define SRST_A_GMAC0                    679
+#define SRST_A_GMAC1                    680
+#define SRST_P_GMAC0                    681
+#define SRST_P_GMAC1                    682
+#define SRST_H_SDIO                     684
+/********Name=SOFTRST_CON43,Offset=0xAAC********/
+#define SRST_H_SDMMC0                   690
+#define SRST_S_FSPI1                    691
+#define SRST_H_FSPI1                    692
+#define SRST_A_DSMC_BIU                 694
+#define SRST_A_DSMC                     695
+#define SRST_P_DSMC                     696
+#define SRST_H_HSGPIO                   698
+#define SRST_HSGPIO                     699
+#define SRST_A_HSGPIO                   701
+/********Name=SOFTRST_CON45,Offset=0xAB4********/
+#define SRST_H_RKVDEC                   723
+#define SRST_H_RKVDEC_BIU               725
+#define SRST_A_RKVDEC_BIU               726
+#define SRST_RKVDEC_HEVC_CA             728
+#define SRST_RKVDEC_CORE                729
+/********Name=SOFTRST_CON47,Offset=0xABC********/
+#define SRST_A_USB_BIU                  755
+#define SRST_P_USBUFS_BIU               756
+#define SRST_A_USB3OTG0                 757
+#define SRST_A_UFS_BIU                  762
+#define SRST_A_MMU2                     764
+#define SRST_A_SLV_MMU2                 765
+#define SRST_A_UFS_SYS                  767
+/********Name=SOFTRST_CON48,Offset=0xAC0********/
+#define SRST_A_UFS                      768
+#define SRST_P_USBUFS_GRF               769
+#define SRST_P_UFS_GRF                  770
+/********Name=SOFTRST_CON49,Offset=0xAC4********/
+#define SRST_H_VPU_BIU                  790
+#define SRST_A_JPEG_BIU                 791
+#define SRST_A_RGA_BIU                  794
+#define SRST_A_VDPP_BIU                 795
+#define SRST_A_EBC_BIU                  796
+#define SRST_H_RGA2E_0                  797
+#define SRST_A_RGA2E_0                  798
+#define SRST_CORE_RGA2E_0               799
+/********Name=SOFTRST_CON50,Offset=0xAC8********/
+#define SRST_A_JPEG                     800
+#define SRST_H_JPEG                     801
+#define SRST_H_VDPP                     802
+#define SRST_A_VDPP                     803
+#define SRST_CORE_VDPP                  804
+#define SRST_H_RGA2E_1                  805
+#define SRST_A_RGA2E_1                  806
+#define SRST_CORE_RGA2E_1               807
+#define SRST_H_EBC                      810
+#define SRST_A_EBC                      811
+#define SRST_D_EBC                      812
+/********Name=SOFTRST_CON51,Offset=0xACC********/
+#define SRST_H_VEPU0_BIU                818
+#define SRST_A_VEPU0_BIU                819
+#define SRST_H_VEPU0                    820
+#define SRST_A_VEPU0                    821
+#define SRST_VEPU0_CORE                 822
+/********Name=SOFTRST_CON53,Offset=0xAD4********/
+#define SRST_A_VI_BIU                   851
+#define SRST_H_VI_BIU                   852
+#define SRST_P_VI_BIU                   853
+#define SRST_D_VICAP                    854
+#define SRST_A_VICAP                    855
+#define SRST_H_VICAP                    856
+#define SRST_ISP0                       858
+#define SRST_ISP0_VICAP                 859
+/********Name=SOFTRST_CON54,Offset=0xAD8********/
+#define SRST_CORE_VPSS                  865
+#define SRST_P_CSI_HOST_0               868
+#define SRST_P_CSI_HOST_1               869
+#define SRST_P_CSI_HOST_2               870
+#define SRST_P_CSI_HOST_3               871
+#define SRST_P_CSI_HOST_4               872
+/********Name=SOFTRST_CON59,Offset=0xAEC********/
+#define SRST_CIFIN                      944
+#define SRST_VICAP_I0CLK                945
+#define SRST_VICAP_I1CLK                946
+#define SRST_VICAP_I2CLK                947
+#define SRST_VICAP_I3CLK                948
+#define SRST_VICAP_I4CLK                949
+/********Name=SOFTRST_CON61,Offset=0xAF4********/
+#define SRST_A_VOP_BIU                  980
+#define SRST_A_VOP2_BIU                 981
+#define SRST_H_VOP_BIU                  982
+#define SRST_P_VOP_BIU                  983
+#define SRST_H_VOP                      984
+#define SRST_A_VOP                      985
+#define SRST_D_VP0                      989
+/********Name=SOFTRST_CON62,Offset=0xAF8********/
+#define SRST_D_VP1                      992
+#define SRST_D_VP2                      993
+#define SRST_P_VOP2_BIU                 994
+#define SRST_P_VOPGRF                   995
+/********Name=SOFTRST_CON63,Offset=0xAFC********/
+#define SRST_H_VO0_BIU                  1013
+#define SRST_P_VO0_BIU                  1015
+#define SRST_A_HDCP0_BIU                1017
+#define SRST_P_VO0_GRF                  1018
+#define SRST_A_HDCP0                    1020
+#define SRST_H_HDCP0                    1021
+#define SRST_HDCP0                      1022
+/********Name=SOFTRST_CON64,Offset=0xB00********/
+#define SRST_P_DSIHOST0                 1029
+#define SRST_DSIHOST0                   1030
+#define SRST_P_HDMITX0                  1031
+#define SRST_HDMITX0_REF                1033
+#define SRST_P_EDP0                     1037
+#define SRST_EDP0_24M                   1038
+/********Name=SOFTRST_CON65,Offset=0xB04********/
+#define SRST_M_SAI5_8CH                 1044
+#define SRST_H_SAI5_8CH                 1045
+#define SRST_M_SAI6_8CH                 1048
+#define SRST_H_SAI6_8CH                 1049
+#define SRST_H_SPDIF_TX2                1050
+#define SRST_M_SPDIF_TX2                1053
+#define SRST_H_SPDIF_RX2                1054
+#define SRST_M_SPDIF_RX2                1055
+/********Name=SOFTRST_CON66,Offset=0xB08********/
+#define SRST_H_SAI8_8CH                 1056
+#define SRST_M_SAI8_8CH                 1058
+/********Name=SOFTRST_CON67,Offset=0xB0C********/
+#define SRST_H_VO1_BIU                  1077
+#define SRST_P_VO1_BIU                  1078
+#define SRST_M_SAI7_8CH                 1081
+#define SRST_H_SAI7_8CH                 1082
+#define SRST_H_SPDIF_TX3                1083
+#define SRST_H_SPDIF_TX4                1084
+#define SRST_H_SPDIF_TX5                1085
+#define SRST_M_SPDIF_TX3                1086
+/********Name=SOFTRST_CON68,Offset=0xB10********/
+#define SRST_DP0                        1088
+#define SRST_P_VO1_GRF                  1090
+#define SRST_A_HDCP1_BIU                1091
+#define SRST_A_HDCP1                    1092
+#define SRST_H_HDCP1                    1093
+#define SRST_HDCP1                      1094
+#define SRST_H_SAI9_8CH                 1097
+#define SRST_M_SAI9_8CH                 1099
+#define SRST_M_SPDIF_TX4                1100
+#define SRST_M_SPDIF_TX5                1101
+/********Name=SOFTRST_CON69,Offset=0xB14********/
+#define SRST_GPU                        1107
+#define SRST_A_S_GPU_BIU                1110
+#define SRST_A_M0_GPU_BIU               1111
+#define SRST_P_GPU_BIU                  1113
+#define SRST_P_GPU_GRF                  1117
+#define SRST_GPU_PVTPLL                 1118
+#define SRST_P_PVTPLL_GPU               1119
+/********Name=SOFTRST_CON72,Offset=0xB20********/
+#define SRST_A_CENTER_BIU               1156
+#define SRST_A_DMA2DDR                  1157
+#define SRST_A_DDR_SHAREMEM             1158
+#define SRST_A_DDR_SHAREMEM_BIU         1159
+#define SRST_H_CENTER_BIU               1160
+#define SRST_P_CENTER_GRF               1161
+#define SRST_P_DMA2DDR                  1162
+#define SRST_P_SHAREMEM                 1163
+#define SRST_P_CENTER_BIU               1164
+/********Name=SOFTRST_CON75,Offset=0xB2C********/
+#define SRST_LINKSYM_HDMITXPHY0         1201
+/********Name=SOFTRST_CON78,Offset=0xB38********/
+#define SRST_DP0_PIXELCLK               1249
+#define SRST_PHY_DP0_TX                 1250
+#define SRST_DP1_PIXELCLK               1251
+#define SRST_DP2_PIXELCLK               1252
+/********Name=SOFTRST_CON79,Offset=0xB3C********/
+#define SRST_H_VEPU1_BIU                1265
+#define SRST_A_VEPU1_BIU                1266
+#define SRST_H_VEPU1                    1267
+#define SRST_A_VEPU1                    1268
+#define SRST_VEPU1_CORE                 1269
+
+/********Name=PHPPHYSOFTRST_CON00,Offset=0x8A00********/
+#define SRST_P_PHPPHY_CRU               131073
+#define SRST_P_APB2ASB_SLV_CHIP_TOP     131075
+#define SRST_P_PCIE2_COMBOPHY0          131077
+#define SRST_P_PCIE2_COMBOPHY0_GRF      131078
+#define SRST_P_PCIE2_COMBOPHY1          131079
+#define SRST_P_PCIE2_COMBOPHY1_GRF      131080
+/********Name=PHPPHYSOFTRST_CON01,Offset=0x8A04********/
+#define SRST_PCIE0_PIPE_PHY             131093
+#define SRST_PCIE1_PIPE_PHY             131096
+
+/********Name=SECURENSSOFTRST_CON00,Offset=0x10A00********/
+#define SRST_H_CRYPTO_NS                262147
+#define SRST_H_TRNG_NS                  262148
+#define SRST_P_OTPC_NS                  262152
+#define SRST_OTPC_NS                    262153
+
+/********Name=PMU1SOFTRST_CON00,Offset=0x20A00********/
+#define SRST_P_HDPTX_GRF                524288
+#define SRST_P_HDPTX_APB                524289
+#define SRST_P_MIPI_DCPHY               524290
+#define SRST_P_DCPHY_GRF                524291
+#define SRST_P_BOT0_APB2ASB             524292
+#define SRST_P_BOT1_APB2ASB             524293
+#define SRST_USB2DEBUG                  524294
+#define SRST_P_CSIPHY_GRF               524295
+#define SRST_P_CSIPHY                   524296
+#define SRST_P_USBPHY_GRF_0             524297
+#define SRST_P_USBPHY_GRF_1             524298
+#define SRST_P_USBDP_GRF                524299
+#define SRST_P_USBDPPHY                 524300
+#define SRST_USBDP_COMBO_PHY_INIT 524303
+/********Name=PMU1SOFTRST_CON01,Offset=0x20A04********/
+#define SRST_USBDP_COMBO_PHY_CMN        524304
+#define SRST_USBDP_COMBO_PHY_LANE       524305
+#define SRST_USBDP_COMBO_PHY_PCS        524306
+#define SRST_M_MIPI_DCPHY               524307
+#define SRST_S_MIPI_DCPHY               524308
+#define SRST_SCAN_CSIPHY                524309
+#define SRST_P_VCCIO6_IOC               524310
+#define SRST_OTGPHY_0                   524311
+#define SRST_OTGPHY_1                   524312
+#define SRST_HDPTX_INIT                 524313
+#define SRST_HDPTX_CMN                  524314
+#define SRST_HDPTX_LANE                 524315
+#define SRST_HDMITXHPD                  524317
+/********Name=PMU1SOFTRST_CON02,Offset=0x20A08********/
+#define SRST_MPHY_INIT                  524320
+#define SRST_P_MPHY_GRF                 524321
+#define SRST_P_VCCIO7_IOC               524323
+/********Name=PMU1SOFTRST_CON03,Offset=0x20A0C********/
+#define SRST_H_PMU1_BIU                 524345
+#define SRST_P_PMU1_NIU                 524346
+#define SRST_H_PMU_CM0_BIU              524347
+#define SRST_PMU_CM0_CORE               524348
+#define SRST_PMU_CM0_JTAG               524349
+/********Name=PMU1SOFTRST_CON04,Offset=0x20A10********/
+#define SRST_P_CRU_PMU1                 524353
+#define SRST_P_PMU1_GRF                 524355
+#define SRST_P_PMU1_IOC                 524356
+#define SRST_P_PMU1WDT                  524357
+#define SRST_T_PMU1WDT                  524358
+#define SRST_P_PMUTIMER                 524359
+#define SRST_PMUTIMER0                  524361
+#define SRST_PMUTIMER1                  524362
+#define SRST_P_PMU1PWM                  524363
+#define SRST_PMU1PWM                    524364
+/********Name=PMU1SOFTRST_CON05,Offset=0x20A14********/
+#define SRST_P_I2C0                     524369
+#define SRST_I2C0                       524371
+#define SRST_S_UART1                    525373
+#define SRST_P_UART1                    525374
+#define SRST_PDM0                       524381
+#define SRST_H_PDM0                     524383
+/********Name=PMU1SOFTRST_CON06,Offset=0xA18********/
+#define SRST_M_PDM0                     524384
+#define SRST_H_VAD                      524385
+/********Name=PMU1SOFTRST_CON07,Offset=0x20A1C********/
+#define SRST_P_PMU0GRF                  524404
+#define SRST_P_PMU0IOC                  524405
+#define SRST_P_GPIO0                    524406
+#define SRST_DB_GPIO0                   524407
+
+#define SRST_NR_RSTS                    (SRST_DB_GPIO0 + 1)
+
+#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3576_H__ */

+ 8 - 4
bsp/rockchip/rk3500/driver/clk/rk3588-cru.h → bsp/rockchip/dm/include/dt-bindings/clock/rk3588-cru.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006-2024 RT-Thread Development Team
+ * Copyright (c) 2006-2022, RT-Thread Development Team
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -229,7 +229,7 @@
 #define CLK_DDR_TIMER0                  226
 #define CLK_DDR_TIMER1                  227
 #define TCLK_WDT_DDR                    228
-#define CLK_DDR_CM0_RTC                 228
+#define CLK_DDR_CM0_RTC                 229
 #define PCLK_WDT                        230
 #define PCLK_TIMER                      231
 #define PCLK_DMA2DDR                    232
@@ -631,7 +631,7 @@
 #define CLK_DSIHOST1                    635
 #define CLK_VOP_PMU                     636
 #define ACLK_VOP_DOBY                   637
-#define ACLK_VOP_SUB_SRC                638
+#define ACLK_VOP_DIV2_SRC               638
 #define CLK_USBDP_PHY0_IMMORTAL         639
 #define CLK_USBDP_PHY1_IMMORTAL         640
 #define CLK_PMU0                        641
@@ -713,8 +713,12 @@
 #define CLK_PHY0_REF_ALT_M              719
 #define CLK_PHY1_REF_ALT_P              720
 #define CLK_PHY1_REF_ALT_M              721
+#define PCLK_DDR_MON_CH0                722
+#define PCLK_DDR_MON_CH1                723
+#define PCLK_DDR_MON_CH2                724
+#define PCLK_DDR_MON_CH3                725
 
-#define CLK_NR_CLKS                     (CLK_PHY1_REF_ALT_M + 1)
+#define CLK_NR_CLKS                     (PCLK_DDR_MON_CH3 + 1)
 
 /********Name=SOFTRST_CON01,Offset=0xA04********/
 #define SRST_A_TOP_BIU                  19

+ 22 - 0
bsp/rockchip/dm/include/dt-bindings/phye/phye-snps-pcie3.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_PHYE_SNPS_PCIE3_H__
+#define __DT_BINDINGS_PHYE_SNPS_PCIE3_H__
+
+/*
+ * pcie30_phy_mode[2:0]
+ * bit2: aggregation
+ * bit1: bifurcation for port 1
+ * bit0: bifurcation for port 0
+ */
+#define PHYE_MODE_PCIE_AGGREGATION 	4   /* PCIe3x4 */
+#define PHYE_MODE_PCIE_NANBNB      	0   /* P1:PCIe3x2  +  P0:PCIe3x2 */
+#define PHYE_MODE_PCIE_NANBBI      	1   /* P1:PCIe3x2  +  P0:PCIe3x1*2 */
+#define PHYE_MODE_PCIE_NABINB      	2   /* P1:PCIe3x1*2 + P0:PCIe3x2 */
+#define PHYE_MODE_PCIE_NABIBI      	3   /* P1:PCIe3x1*2 + P0:PCIe3x1*2 */
+
+#endif /* __DT_BINDINGS_PHYE_SNPS_PCIE3_H__ */

+ 232 - 0
bsp/rockchip/dm/include/dt-bindings/pinctrl/rockchip.h

@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_PINCTRL_ROCKCHIP_H__
+#define __DT_BINDINGS_PINCTRL_ROCKCHIP_H__
+
+#define RK_GPIO0 0
+#define RK_GPIO1 1
+#define RK_GPIO2 2
+#define RK_GPIO3 3
+#define RK_GPIO4 4
+
+#define RK_PA0 0
+#define RK_PA1 1
+#define RK_PA2 2
+#define RK_PA3 3
+#define RK_PA4 4
+#define RK_PA5 5
+#define RK_PA6 6
+#define RK_PA7 7
+#define RK_PB0 8
+#define RK_PB1 9
+#define RK_PB2 10
+#define RK_PB3 11
+#define RK_PB4 12
+#define RK_PB5 13
+#define RK_PB6 14
+#define RK_PB7 15
+#define RK_PC0 16
+#define RK_PC1 17
+#define RK_PC2 18
+#define RK_PC3 19
+#define RK_PC4 20
+#define RK_PC5 21
+#define RK_PC6 22
+#define RK_PC7 23
+#define RK_PD0 24
+#define RK_PD1 25
+#define RK_PD2 26
+#define RK_PD3 27
+#define RK_PD4 28
+#define RK_PD5 29
+#define RK_PD6 30
+#define RK_PD7 31
+
+#define RK_FUNC_GPIO 0
+#define RK_FUNC_0    0
+#define RK_FUNC_1    1
+#define RK_FUNC_2    2
+#define RK_FUNC_3    3
+#define RK_FUNC_4    4
+#define RK_FUNC_5    5
+#define RK_FUNC_6    6
+#define RK_FUNC_7    7
+#define RK_FUNC_8    8
+#define RK_FUNC_9    9
+#define RK_FUNC_10   10
+#define RK_FUNC_11   11
+#define RK_FUNC_12   12
+#define RK_FUNC_13   13
+#define RK_FUNC_14   14
+#define RK_FUNC_15   15
+
+#define RK_GPIO0_A0 0
+#define RK_GPIO0_A1 1
+#define RK_GPIO0_A2 2
+#define RK_GPIO0_A3 3
+#define RK_GPIO0_A4 4
+#define RK_GPIO0_A5 5
+#define RK_GPIO0_A6 6
+#define RK_GPIO0_A7 7
+#define RK_GPIO0_B0 8
+#define RK_GPIO0_B1 9
+#define RK_GPIO0_B2 10
+#define RK_GPIO0_B3 11
+#define RK_GPIO0_B4 12
+#define RK_GPIO0_B5 13
+#define RK_GPIO0_B6 14
+#define RK_GPIO0_B7 15
+#define RK_GPIO0_C0 16
+#define RK_GPIO0_C1 17
+#define RK_GPIO0_C2 18
+#define RK_GPIO0_C3 19
+#define RK_GPIO0_C4 20
+#define RK_GPIO0_C5 21
+#define RK_GPIO0_C6 22
+#define RK_GPIO0_C7 23
+#define RK_GPIO0_D0 24
+#define RK_GPIO0_D1 25
+#define RK_GPIO0_D2 26
+#define RK_GPIO0_D3 27
+#define RK_GPIO0_D4 28
+#define RK_GPIO0_D5 29
+#define RK_GPIO0_D6 30
+#define RK_GPIO0_D7 31
+
+#define RK_GPIO1_A0 32
+#define RK_GPIO1_A1 33
+#define RK_GPIO1_A2 34
+#define RK_GPIO1_A3 35
+#define RK_GPIO1_A4 36
+#define RK_GPIO1_A5 37
+#define RK_GPIO1_A6 38
+#define RK_GPIO1_A7 39
+#define RK_GPIO1_B0 40
+#define RK_GPIO1_B1 41
+#define RK_GPIO1_B2 42
+#define RK_GPIO1_B3 43
+#define RK_GPIO1_B4 44
+#define RK_GPIO1_B5 45
+#define RK_GPIO1_B6 46
+#define RK_GPIO1_B7 47
+#define RK_GPIO1_C0 48
+#define RK_GPIO1_C1 49
+#define RK_GPIO1_C2 50
+#define RK_GPIO1_C3 51
+#define RK_GPIO1_C4 52
+#define RK_GPIO1_C5 53
+#define RK_GPIO1_C6 54
+#define RK_GPIO1_C7 55
+#define RK_GPIO1_D0 56
+#define RK_GPIO1_D1 57
+#define RK_GPIO1_D2 58
+#define RK_GPIO1_D3 59
+#define RK_GPIO1_D4 60
+#define RK_GPIO1_D5 61
+#define RK_GPIO1_D6 62
+#define RK_GPIO1_D7 63
+
+#define RK_GPIO2_A0 64
+#define RK_GPIO2_A1 65
+#define RK_GPIO2_A2 66
+#define RK_GPIO2_A3 67
+#define RK_GPIO2_A4 68
+#define RK_GPIO2_A5 69
+#define RK_GPIO2_A6 70
+#define RK_GPIO2_A7 71
+#define RK_GPIO2_B0 72
+#define RK_GPIO2_B1 73
+#define RK_GPIO2_B2 74
+#define RK_GPIO2_B3 75
+#define RK_GPIO2_B4 76
+#define RK_GPIO2_B5 77
+#define RK_GPIO2_B6 78
+#define RK_GPIO2_B7 79
+#define RK_GPIO2_C0 80
+#define RK_GPIO2_C1 81
+#define RK_GPIO2_C2 82
+#define RK_GPIO2_C3 83
+#define RK_GPIO2_C4 84
+#define RK_GPIO2_C5 85
+#define RK_GPIO2_C6 86
+#define RK_GPIO2_C7 87
+#define RK_GPIO2_D0 88
+#define RK_GPIO2_D1 89
+#define RK_GPIO2_D2 90
+#define RK_GPIO2_D3 91
+#define RK_GPIO2_D4 92
+#define RK_GPIO2_D5 93
+#define RK_GPIO2_D6 94
+#define RK_GPIO2_D7 95
+
+#define RK_GPIO3_A0 96
+#define RK_GPIO3_A1 97
+#define RK_GPIO3_A2 98
+#define RK_GPIO3_A3 99
+#define RK_GPIO3_A4 100
+#define RK_GPIO3_A5 101
+#define RK_GPIO3_A6 102
+#define RK_GPIO3_A7 103
+#define RK_GPIO3_B0 104
+#define RK_GPIO3_B1 105
+#define RK_GPIO3_B2 106
+#define RK_GPIO3_B3 107
+#define RK_GPIO3_B4 108
+#define RK_GPIO3_B5 109
+#define RK_GPIO3_B6 110
+#define RK_GPIO3_B7 111
+#define RK_GPIO3_C0 112
+#define RK_GPIO3_C1 113
+#define RK_GPIO3_C2 114
+#define RK_GPIO3_C3 115
+#define RK_GPIO3_C4 116
+#define RK_GPIO3_C5 117
+#define RK_GPIO3_C6 118
+#define RK_GPIO3_C7 119
+#define RK_GPIO3_D0 120
+#define RK_GPIO3_D1 121
+#define RK_GPIO3_D2 122
+#define RK_GPIO3_D3 123
+#define RK_GPIO3_D4 124
+#define RK_GPIO3_D5 125
+#define RK_GPIO3_D6 126
+#define RK_GPIO3_D7 127
+
+#define RK_GPIO4_A0 128
+#define RK_GPIO4_A1 129
+#define RK_GPIO4_A2 130
+#define RK_GPIO4_A3 131
+#define RK_GPIO4_A4 132
+#define RK_GPIO4_A5 133
+#define RK_GPIO4_A6 134
+#define RK_GPIO4_A7 135
+#define RK_GPIO4_B0 136
+#define RK_GPIO4_B1 137
+#define RK_GPIO4_B2 138
+#define RK_GPIO4_B3 139
+#define RK_GPIO4_B4 140
+#define RK_GPIO4_B5 141
+#define RK_GPIO4_B6 142
+#define RK_GPIO4_B7 143
+#define RK_GPIO4_C0 144
+#define RK_GPIO4_C1 145
+#define RK_GPIO4_C2 146
+#define RK_GPIO4_C3 147
+#define RK_GPIO4_C4 148
+#define RK_GPIO4_C5 149
+#define RK_GPIO4_C6 150
+#define RK_GPIO4_C7 151
+#define RK_GPIO4_D0 152
+#define RK_GPIO4_D1 153
+#define RK_GPIO4_D2 154
+#define RK_GPIO4_D3 155
+#define RK_GPIO4_D4 156
+#define RK_GPIO4_D5 157
+#define RK_GPIO4_D6 158
+#define RK_GPIO4_D7 159
+
+#endif /* __DT_BINDINGS_PINCTRL_ROCKCHIP_H__ */

+ 32 - 0
bsp/rockchip/dm/include/dt-bindings/power/px30-power.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__
+#define __DT_BINDINGS_POWER_PX30_POWER_H__
+
+/* VD_CORE */
+#define PX30_PD_A35_0       0
+#define PX30_PD_A35_1       1
+#define PX30_PD_A35_2       2
+#define PX30_PD_A35_3       3
+#define PX30_PD_SCU         4
+
+/* VD_LOGIC */
+#define PX30_PD_USB         5
+#define PX30_PD_DDR         6
+#define PX30_PD_SDCARD      7
+#define PX30_PD_CRYPTO      8
+#define PX30_PD_GMAC        9
+#define PX30_PD_MMC_NAND    10
+#define PX30_PD_VPU         11
+#define PX30_PD_VO          12
+#define PX30_PD_VI          13
+#define PX30_PD_GPU         14
+
+/* VD_PMU */
+#define PX30_PD_PMU         15
+
+#endif /* __DT_BINDINGS_POWER_PX30_POWER_H__ */

+ 25 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk1808-power.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK1808_POWER_H__
+#define __DT_BINDINGS_POWER_RK1808_POWER_H__
+
+/* VD_CORE */
+#define RK1808_PD_A35_0		0
+#define RK1808_PD_A35_1		1
+#define RK1808_PD_SCU		2
+#define RK1808_VD_CORE		3
+
+/* VD_NPU */
+#define RK1808_VD_NPU		4
+
+/* VD_LOGIC */
+#define RK1808_PD_DDR		5
+#define RK1808_PD_PCIE		6
+#define RK1808_PD_VPU		7
+#define RK1808_PD_VIO		8
+
+#endif /* __DT_BINDINGS_POWER_RK1808_POWER_H__ */

+ 18 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3036-power.h

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3036_POWER_H__
+#define __DT_BINDINGS_POWER_RK3036_POWER_H__
+
+#define RK3036_PD_MSCH  0
+#define RK3036_PD_CORE  1
+#define RK3036_PD_PERI  2
+#define RK3036_PD_VIO   3
+#define RK3036_PD_VPU   4
+#define RK3036_PD_GPU   5
+#define RK3036_PD_SYS   6
+
+#endif /* __DT_BINDINGS_POWER_RK3036_POWER_H__ */

+ 27 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3066-power.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__
+#define __DT_BINDINGS_POWER_RK3066_POWER_H__
+
+/* VD_CORE */
+#define RK3066_PD_A9_0  0
+#define RK3066_PD_A9_1  1
+#define RK3066_PD_DBG   4
+#define RK3066_PD_SCU   5
+
+/* VD_LOGIC */
+#define RK3066_PD_VIDEO 6
+#define RK3066_PD_VIO   7
+#define RK3066_PD_GPU   8
+#define RK3066_PD_PERI  9
+#define RK3066_PD_CPU   10
+#define RK3066_PD_ALIVE 11
+
+/* VD_PMU */
+#define RK3066_PD_RTC   12
+
+#endif /* __DT_BINDINGS_POWER_RK3066_POWER_H__ */

+ 19 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3128-power.h

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3128_POWER_H__
+#define __DT_BINDINGS_POWER_RK3128_POWER_H__
+
+/* VD_CORE */
+#define RK3128_PD_CORE  0
+
+/* VD_LOGIC */
+#define RK3128_PD_VIO   1
+#define RK3128_PD_VIDEO 2
+#define RK3128_PD_GPU   3
+#define RK3128_PD_MSCH  4
+
+#endif /* __DT_BINDINGS_POWER_RK3128_POWER_H__ */

+ 29 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3188-power.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3188_POWER_H__
+#define __DT_BINDINGS_POWER_RK3188_POWER_H__
+
+/* VD_CORE */
+#define RK3188_PD_A9_0  0
+#define RK3188_PD_A9_1  1
+#define RK3188_PD_A9_2  2
+#define RK3188_PD_A9_3  3
+#define RK3188_PD_DBG   4
+#define RK3188_PD_SCU   5
+
+/* VD_LOGIC */
+#define RK3188_PD_VIDEO 6
+#define RK3188_PD_VIO   7
+#define RK3188_PD_GPU   8
+#define RK3188_PD_PERI  9
+#define RK3188_PD_CPU   10
+#define RK3188_PD_ALIVE 11
+
+/* VD_PMU */
+#define RK3188_PD_RTC   12
+
+#endif /* __DT_BINDINGS_POWER_RK3188_POWER_H__ */

+ 22 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3228-power.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3228_POWER_H__
+#define __DT_BINDINGS_POWER_RK3228_POWER_H__
+
+#define RK3228_PD_CORE      0
+#define RK3228_PD_MSCH      1
+#define RK3228_PD_BUS       2
+#define RK3228_PD_SYS       3
+#define RK3228_PD_VIO       4
+#define RK3228_PD_VOP       5
+#define RK3228_PD_VPU       6
+#define RK3228_PD_RKVDEC    7
+#define RK3228_PD_GPU       8
+#define RK3228_PD_PERI      9
+#define RK3228_PD_GMAC      10
+
+#endif /* __DT_BINDINGS_POWER_RK3228_POWER_H__ */

+ 33 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3288-power.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3288_POWER_H__
+#define __DT_BINDINGS_POWER_RK3288_POWER_H__
+
+/* VD_CORE */
+#define RK3288_PD_A17_0 0
+#define RK3288_PD_A17_1 1
+#define RK3288_PD_A17_2 2
+#define RK3288_PD_A17_3 3
+#define RK3288_PD_SCU   4
+#define RK3288_PD_DEBUG 5
+#define RK3288_PD_MEM   6
+
+/* VD_LOGIC */
+#define RK3288_PD_BUS   7
+#define RK3288_PD_PERI  8
+#define RK3288_PD_VIO   9
+#define RK3288_PD_ALIVE 10
+#define RK3288_PD_HEVC  11
+#define RK3288_PD_VIDEO 12
+
+/* VD_GPU */
+#define RK3288_PD_GPU   13
+
+/* VD_PMU */
+#define RK3288_PD_PMU   14
+
+#endif /* __DT_BINDINGS_POWER_RK3288_POWER_H__ */

+ 21 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3328-power.h

@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3328_POWER_H__
+#define __DT_BINDINGS_POWER_RK3328_POWER_H__
+
+#define RK3328_PD_CORE      0
+#define RK3328_PD_GPU       1
+#define RK3328_PD_BUS       2
+#define RK3328_PD_MSCH      3
+#define RK3328_PD_PERI      4
+#define RK3328_PD_VIDEO     5
+#define RK3328_PD_HEVC      6
+#define RK3328_PD_SYS       7
+#define RK3328_PD_VPU       8
+#define RK3328_PD_VIO       9
+
+#endif /* __DT_BINDINGS_POWER_RK3328_POWER_H__ */

+ 30 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3366-power.h

@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3366_POWER_H__
+#define __DT_BINDINGS_POWER_RK3366_POWER_H__
+
+/* VD_CORE */
+#define RK3366_PD_A53_0     0
+#define RK3366_PD_A53_1     1
+#define RK3366_PD_A53_2     2
+#define RK3366_PD_A53_3     3
+
+/* VD_LOGIC */
+#define RK3366_PD_BUS       4
+#define RK3366_PD_PERI      5
+#define RK3366_PD_VIO       6
+#define RK3366_PD_VIDEO     7
+#define RK3366_PD_RKVDEC    8
+#define RK3366_PD_WIFIBT    9
+#define RK3366_PD_VPU       10
+#define RK3366_PD_GPU       11
+#define RK3366_PD_ALIVE     12
+
+/* VD_PMU */
+#define RK3366_PD_PMU       13
+
+#endif /* __DT_BINDINGS_POWER_RK3366_POWER_H__ */

+ 34 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3368-power.h

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3368_POWER_H__
+#define __DT_BINDINGS_POWER_RK3368_POWER_H__
+
+/* VD_CORE */
+#define RK3368_PD_A53_L0    0
+#define RK3368_PD_A53_L1    1
+#define RK3368_PD_A53_L2    2
+#define RK3368_PD_A53_L3    3
+#define RK3368_PD_SCU_L     4
+#define RK3368_PD_A53_B0    5
+#define RK3368_PD_A53_B1    6
+#define RK3368_PD_A53_B2    7
+#define RK3368_PD_A53_B3    8
+#define RK3368_PD_SCU_B     9
+
+/* VD_LOGIC */
+#define RK3368_PD_BUS       10
+#define RK3368_PD_PERI      11
+#define RK3368_PD_VIO       12
+#define RK3368_PD_ALIVE     13
+#define RK3368_PD_VIDEO     14
+#define RK3368_PD_GPU_0     15
+#define RK3368_PD_GPU_1     16
+
+/* VD_PMU */
+#define RK3368_PD_PMU       17
+
+#endif /* __DT_BINDINGS_POWER_RK3368_POWER_H__ */

+ 59 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3399-power.h

@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3399_POWER_H__
+#define __DT_BINDINGS_POWER_RK3399_POWER_H__
+
+/* VD_CORE_L */
+#define RK3399_PD_A53_L0    0
+#define RK3399_PD_A53_L1    1
+#define RK3399_PD_A53_L2    2
+#define RK3399_PD_A53_L3    3
+#define RK3399_PD_SCU_L     4
+
+/* VD_CORE_B */
+#define RK3399_PD_A72_B0    5
+#define RK3399_PD_A72_B1    6
+#define RK3399_PD_SCU_B     7
+
+/* VD_LOGIC */
+#define RK3399_PD_TCPD0     8
+#define RK3399_PD_TCPD1     9
+#define RK3399_PD_CCI       10
+#define RK3399_PD_CCI0      11
+#define RK3399_PD_CCI1      12
+#define RK3399_PD_PERILP    13
+#define RK3399_PD_PERIHP    14
+#define RK3399_PD_VIO       15
+#define RK3399_PD_VO        16
+#define RK3399_PD_VOPB      17
+#define RK3399_PD_VOPL      18
+#define RK3399_PD_ISP0      19
+#define RK3399_PD_ISP1      20
+#define RK3399_PD_HDCP      21
+#define RK3399_PD_GMAC      22
+#define RK3399_PD_EMMC      23
+#define RK3399_PD_USB3      24
+#define RK3399_PD_EDP       25
+#define RK3399_PD_GIC       26
+#define RK3399_PD_SD        27
+#define RK3399_PD_SDIOAUDIO 28
+#define RK3399_PD_ALIVE     29
+
+/* VD_CENTER */
+#define RK3399_PD_CENTER    30
+#define RK3399_PD_VCODEC    31
+#define RK3399_PD_VDU       32
+#define RK3399_PD_RGA       33
+#define RK3399_PD_IEP       34
+
+/* VD_GPU */
+#define RK3399_PD_GPU       35
+
+/* VD_PMU */
+#define RK3399_PD_PMU       36
+
+#endif /* __DT_BINDINGS_POWER_RK3399_POWER_H__ */

+ 23 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3528-power.h

@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3528_POWER_H__
+#define __DT_BINDINGS_POWER_RK3528_POWER_H__
+
+/*
+ * RK3528 idle id Summary.
+ */
+#define RK3528_PD_PMU       0
+#define RK3528_PD_BUS       1
+#define RK3528_PD_DDR       2
+#define RK3528_PD_MSCH      3
+#define RK3528_PD_GPU       4
+#define RK3528_PD_RKVDEC    5
+#define RK3528_PD_RKVENC    6
+#define RK3528_PD_VO        7
+#define RK3528_PD_VPU       8
+
+#endif /* __DT_BINDINGS_POWER_RK3528_POWER_H__ */

+ 37 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3562-power.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3562_POWER_H__
+#define __DT_BINDINGS_POWER_RK3562_POWER_H__
+
+/* VD_CORE */
+#define RK3562_PD_CPU_0         0
+#define RK3562_PD_CPU_1         1
+#define RK3562_PD_CPU_2         2
+#define RK3562_PD_CPU_3         3
+#define RK3562_PD_CORE_ALIVE    4
+
+/* VD_PMU */
+#define RK3562_PD_PMU           5
+#define RK3562_PD_PMU_ALIVE     6
+
+/* VD_NPU */
+#define RK3562_PD_NPU           7
+
+/* VD_GPU */
+#define RK3562_PD_GPU           8
+
+/* VD_LOGIC */
+#define RK3562_PD_DDR           9
+#define RK3562_PD_VEPU          10
+#define RK3562_PD_VDPU          11
+#define RK3562_PD_VI            12
+#define RK3562_PD_VO            13
+#define RK3562_PD_RGA           14
+#define RK3562_PD_PHP           15
+#define RK3562_PD_LOGIC_ALIVE   16
+
+#endif /* __DT_BINDINGS_POWER_RK3562_POWER_H__ */

+ 37 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3568-power.h

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3568_POWER_H__
+#define __DT_BINDINGS_POWER_RK3568_POWER_H__
+
+/* VD_CORE */
+#define RK3568_PD_CPU_0         0
+#define RK3568_PD_CPU_1         1
+#define RK3568_PD_CPU_2         2
+#define RK3568_PD_CPU_3         3
+#define RK3568_PD_CORE_ALIVE    4
+
+/* VD_PMU */
+#define RK3568_PD_PMU           5
+
+/* VD_NPU */
+#define RK3568_PD_NPU           6
+
+/* VD_GPU */
+#define RK3568_PD_GPU           7
+
+/* VD_LOGIC */
+#define RK3568_PD_VI            8
+#define RK3568_PD_VO            9
+#define RK3568_PD_RGA           10
+#define RK3568_PD_VPU           11
+#define RK3568_PD_CENTER        12
+#define RK3568_PD_RKVDEC        13
+#define RK3568_PD_RKVENC        14
+#define RK3568_PD_PIPE          15
+#define RK3568_PD_LOGIC_ALIVE   16
+
+#endif /* __DT_BINDINGS_POWER_RK3568_POWER_H__ */

+ 35 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3576-power.h

@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006-2024, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3576_POWER_H__
+#define __DT_BINDINGS_POWER_RK3576_POWER_H__
+
+/* VD_NPU */
+#define RK3576_PD_NPU           0
+#define RK3576_PD_NPUTOP        1
+#define RK3576_PD_NPU0          2
+#define RK3576_PD_NPU1          3
+
+/* VD_GPU */
+#define RK3576_PD_GPU           4
+
+/* VD_LOGIC */
+#define RK3576_PD_NVM           5
+#define RK3576_PD_SDGMAC        6
+#define RK3576_PD_USB           7
+#define RK3576_PD_PHP           8
+#define RK3576_PD_SUBPHP        9
+#define RK3576_PD_AUDIO         10
+#define RK3576_PD_VEPU0         11
+#define RK3576_PD_VEPU1         12
+#define RK3576_PD_VPU           13
+#define RK3576_PD_VDEC          14
+#define RK3576_PD_VI            15
+#define RK3576_PD_VO0           16
+#define RK3576_PD_VO1           17
+#define RK3576_PD_VOP           18
+
+#endif /* __DT_BINDINGS_POWER_RK3576_POWER_H__ */

+ 74 - 0
bsp/rockchip/dm/include/dt-bindings/power/rk3588-power.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RK3588_POWER_H__
+#define __DT_BINDINGS_POWER_RK3588_POWER_H__
+
+/* VD_LITDSU */
+#define RK3588_PD_CPU_0     0
+#define RK3588_PD_CPU_1     1
+#define RK3588_PD_CPU_2     2
+#define RK3588_PD_CPU_3     3
+
+/* VD_BIGCORE0 */
+#define RK3588_PD_CPU_4     4
+#define RK3588_PD_CPU_5     5
+
+/* VD_BIGCORE1 */
+#define RK3588_PD_CPU_6     6
+#define RK3588_PD_CPU_7     7
+
+/* VD_NPU */
+#define RK3588_PD_NPU       8
+#define RK3588_PD_NPUTOP    9
+#define RK3588_PD_NPU1      10
+#define RK3588_PD_NPU2      11
+
+/* VD_GPU */
+#define RK3588_PD_GPU       12
+
+/* VD_VCODEC */
+#define RK3588_PD_VCODEC    13
+#define RK3588_PD_RKVDEC0   14
+#define RK3588_PD_RKVDEC1   15
+#define RK3588_PD_VENC0     16
+#define RK3588_PD_VENC1     17
+
+/* VD_DD01 */
+#define RK3588_PD_DDR01     18
+
+/* VD_DD23 */
+#define RK3588_PD_DDR23     19
+
+/* VD_LOGIC */
+#define RK3588_PD_CENTER    20
+#define RK3588_PD_VDPU      21
+#define RK3588_PD_RGA30     22
+#define RK3588_PD_AV1       23
+#define RK3588_PD_VOP       24
+#define RK3588_PD_VO0       25
+#define RK3588_PD_VO1       26
+#define RK3588_PD_VI        27
+#define RK3588_PD_ISP1      28
+#define RK3588_PD_FEC       29
+#define RK3588_PD_RGA31     30
+#define RK3588_PD_USB       31
+#define RK3588_PD_PHP       32
+#define RK3588_PD_GMAC      33
+#define RK3588_PD_PCIE      34
+#define RK3588_PD_NVM       35
+#define RK3588_PD_NVM0      36
+#define RK3588_PD_SDIO      37
+#define RK3588_PD_AUDIO     38
+#define RK3588_PD_SECURE    39
+#define RK3588_PD_SDMMC     40
+#define RK3588_PD_CRYPTO    41
+#define RK3588_PD_BUS       42
+
+/* VD_PMU */
+#define RK3588_PD_PMU1      43
+
+#endif /* __DT_BINDINGS_POWER_RK3588_POWER_H__ */

+ 39 - 0
bsp/rockchip/dm/include/dt-bindings/power/rv1126-power.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_POWER_RV1126_POWER_H__
+#define __DT_BINDINGS_POWER_RV1126_POWER_H__
+
+/* VD_CORE */
+#define RV1126_PD_CPU_0         0
+#define RV1126_PD_CPU_1         1
+#define RV1126_PD_CPU_2         2
+#define RV1126_PD_CPU_3         3
+#define RV1126_PD_CORE_ALIVE    4
+
+/* VD_PMU */
+#define RV1126_PD_PMU           5
+#define RV1126_PD_PMU_ALIVE     6
+
+/* VD_NPU */
+#define RV1126_PD_NPU           7
+
+/* VD_VEPU */
+#define RV1126_PD_VEPU          8
+
+/* VD_LOGIC */
+#define RV1126_PD_VI            9
+#define RV1126_PD_VO            10
+#define RV1126_PD_ISPP          11
+#define RV1126_PD_VDPU          12
+#define RV1126_PD_CRYPTO        13
+#define RV1126_PD_DDR           14
+#define RV1126_PD_NVM           15
+#define RV1126_PD_SDIO          16
+#define RV1126_PD_USB           17
+#define RV1126_PD_LOGIC_ALIVE   18
+
+#endif /* __DT_BINDINGS_POWER_RK3036_POWER_H__ */

+ 40 - 0
bsp/rockchip/dm/include/hw-decompress.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-21     GuEe-GUI     first version
+ */
+
+#ifndef __HW_DECOMPRESS_H__
+#define __HW_DECOMPRESS_H__
+
+#include <sys/ioctl.h>
+
+#define HW_DECOMPRESS_NAME  "hw_decom"
+
+enum hw_decompress_mod
+{
+    HW_DECOMPRESS_LZ4_MOD,
+    HW_DECOMPRESS_GZIP_MOD,
+    HW_DECOMPRESS_ZLIB_MOD,
+    HW_DECOMPRESS_MAX_MOD,
+};
+
+/* Input of RK_DECOM_USER */
+struct hw_decompress_param
+{
+    uint32_t mode;
+    uint32_t dst_max_size;
+    uint64_t src;
+    uint64_t dst;
+    uint64_t decom_data_len;
+};
+
+#define HW_DECOMPRESS_IOC_MAGIC 'D'
+
+#define HW_DECOMPRESS_REQ       _IOWR(HW_DECOMPRESS_IOC_MAGIC, 0, struct hw_decompress_param)
+
+#endif /* __HW_DECOMPRESS_H__ */

+ 183 - 0
bsp/rockchip/dm/include/pinctrl-rockchip.h

@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __ROCKCHIP_PINCTRL_H__
+#define __ROCKCHIP_PINCTRL_H__
+
+#include <rthw.h>
+#include <rtdef.h>
+
+#include <rockchip.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+
+#define ROCKCHIP_PULL_BITS_PER_PIN  2
+#define ROCKCHIP_PULL_PINS_PER_REG  8
+#define ROCKCHIP_PULL_BANK_STRIDE   16
+#define ROCKCHIP_DRV_BITS_PER_PIN   2
+#define ROCKCHIP_DRV_PINS_PER_REG   8
+#define ROCKCHIP_DRV_BANK_STRIDE    16
+#define ROCKCHIP_DRV_3BITS_PER_PIN  3
+
+enum rockchip_pin_drv_type
+{
+    DRV_TYPE_IO_DEFAULT = 0,
+    DRV_TYPE_IO_1V8_OR_3V0,
+    DRV_TYPE_IO_1V8_ONLY,
+    DRV_TYPE_IO_1V8_3V0_AUTO,
+    DRV_TYPE_IO_3V3_ONLY,
+    DRV_TYPE_MAX
+};
+
+enum rockchip_pin_pull_type
+{
+    PULL_TYPE_IO_DEFAULT = 0,
+    PULL_TYPE_IO_1V8_ONLY,
+    PULL_TYPE_IO_1 = 1,
+    PULL_TYPE_MAX
+};
+
+enum rockchip_pinctrl_type
+{
+    RK3308,
+    RK3568,
+    RK3588,
+};
+
+struct rockchip_gpio_regs
+{
+    rt_uint32_t port_dr;        /* Data register */
+    rt_uint32_t port_ddr;       /* Data direction register */
+    rt_uint32_t int_en;         /* Interrupt enable */
+    rt_uint32_t int_mask;       /* Interrupt mask */
+    rt_uint32_t int_type;       /* Interrupt trigger type, such as high, low, edge trriger type. */
+    rt_uint32_t int_polarity;   /* Interrupt polarity enable register */
+    rt_uint32_t int_bothedge;   /* Interrupt bothedge enable register */
+    rt_uint32_t int_status;     /* Interrupt status register */
+    rt_uint32_t int_rawstatus;  /* Int_status = int_rawstatus & int_mask */
+    rt_uint32_t debounce;       /* Enable debounce for interrupt signal */
+    rt_uint32_t dbclk_div_en;   /* Enable divider for debounce clock */
+    rt_uint32_t dbclk_div_con;  /* Setting for divider of debounce clock */
+    rt_uint32_t port_eoi;       /* End of interrupt of the port */
+    rt_uint32_t ext_port;       /* Port data from external */
+    rt_uint32_t version_id;     /* Controller version register */
+};
+
+struct rockchip_iomux
+{
+    int type;
+    int offset;
+};
+
+struct rockchip_drv
+{
+    enum rockchip_pin_drv_type drv_type;
+    int offset;
+};
+
+struct rockchip_pin_data
+{
+    struct rt_syscon *regmap_base;
+    struct rt_syscon *regmap_pmu;
+    rt_size_t reg_size;
+
+    struct rockchip_pin_ctrl *pinctrl;
+};
+
+struct rockchip_pin_bank
+{
+    struct rt_device_pin parent;
+
+    const char *name;
+
+    int irq;
+    void *reg_base;
+    struct rt_clk *clk;
+    struct rt_clk *db_clk;
+
+    rt_uint8_t nr_pins;
+    rt_uint8_t bank_num;
+    rt_uint32_t gpio_type;
+    rt_uint32_t mask_cache;
+    rt_uint32_t toggle_edge_mode;
+    struct rockchip_pin_data *drvdata;
+    const struct rockchip_gpio_regs *gpio_regs;
+
+    struct rockchip_iomux iomux[4];
+    struct rockchip_drv drv[4];
+    enum rockchip_pin_pull_type pull_type[4];
+    struct rt_spinlock spinlock;
+
+    rt_uint32_t route_mask;
+    rt_uint32_t recalced_mask;
+};
+
+#define raw_pin_to_bank(raw)    rt_container_of(raw, struct rockchip_pin_bank, parent)
+
+struct rockchip_mux_recalced_data
+{
+    rt_uint8_t num;
+    rt_uint8_t pin;
+    rt_uint32_t reg;
+    rt_uint8_t bit;
+    rt_uint8_t mask;
+};
+
+enum rockchip_mux_route_location
+{
+    ROCKCHIP_ROUTE_SAME = 0,
+    ROCKCHIP_ROUTE_PMU,
+    ROCKCHIP_ROUTE_GRF,
+};
+
+struct rockchip_mux_route_data
+{
+    rt_uint8_t bank_num;
+    rt_uint8_t pin;
+    rt_uint8_t func;
+    enum rockchip_mux_route_location route_location;
+    rt_uint32_t route_offset;
+    rt_uint32_t route_val;
+};
+
+struct rockchip_pin_ctrl
+{
+    char *label;
+    enum rockchip_pinctrl_type type;
+
+    struct rockchip_pin_bank *pin_banks;
+    rt_uint32_t banks_nr;
+    rt_uint32_t pins_nr;
+
+    int grf_mux_offset;
+    int pmu_mux_offset;
+    int grf_drv_offset;
+    int pmu_drv_offset;
+
+    struct rockchip_mux_recalced_data *iomux_recalced;
+    rt_uint32_t niomux_recalced;
+
+    struct rockchip_mux_route_data *iomux_routes;
+    rt_uint32_t niomux_routes;
+
+    rt_err_t (*set_mux)(struct rockchip_pin_bank *pin_bank, int pin, int mux);
+    rt_err_t (*set_pull)(struct rockchip_pin_bank *pin_bank, int pin, int pull);
+    rt_err_t (*set_drive)(struct rockchip_pin_bank *pin_bank, int pin, int strength);
+    rt_err_t (*set_schmitt)(struct rockchip_pin_bank *pin_bank, int pin, int enable);
+};
+
+struct rockchip_pinctrl_device
+{
+    struct rt_device_pin parent;
+
+    struct rockchip_pin_data drvdata;
+    struct rockchip_pin_ctrl *pinctrl;
+};
+
+#endif /* __ROCKCHIP_PINCTRL_H__ */

+ 912 - 0
bsp/rockchip/dm/include/rk8xx.h

@@ -0,0 +1,912 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#ifndef __RK8XX_H__
+#define __RK8XX_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+/* CONFIG REGISTER */
+#define RK805_VB_MON_REG                0x21
+#define RK805_THERMAL_REG               0x22
+
+/* POWER CHANNELS ENABLE REGISTER */
+#define RK805_DCDC_EN_REG               0x23
+#define RK805_SLP_DCDC_EN_REG           0x25
+#define RK805_SLP_LDO_EN_REG            0x26
+#define RK805_LDO_EN_REG                0x27
+
+/* BUCK AND LDO CONFIG REGISTER */
+#define RK805_BUCK_LDO_SLP_LP_EN_REG    0x2a
+#define RK805_BUCK1_CONFIG_REG          0x2e
+#define RK805_BUCK1_ON_VSEL_REG         0x2f
+#define RK805_BUCK1_SLP_VSEL_REG        0x30
+#define RK805_BUCK2_CONFIG_REG          0x32
+#define RK805_BUCK2_ON_VSEL_REG         0x33
+#define RK805_BUCK2_SLP_VSEL_REG        0x34
+#define RK805_BUCK3_CONFIG_REG          0x36
+#define RK805_BUCK4_CONFIG_REG          0x37
+#define RK805_BUCK4_ON_VSEL_REG         0x38
+#define RK805_BUCK4_SLP_VSEL_REG        0x39
+#define RK805_LDO1_ON_VSEL_REG          0x3b
+#define RK805_LDO1_SLP_VSEL_REG         0x3c
+#define RK805_LDO2_ON_VSEL_REG          0x3d
+#define RK805_LDO2_SLP_VSEL_REG         0x3e
+#define RK805_LDO3_ON_VSEL_REG          0x3f
+#define RK805_LDO3_SLP_VSEL_REG         0x40
+
+/* INTERRUPT REGISTER */
+#define RK805_PWRON_LP_INT_TIME_REG     0x47
+#define RK805_PWRON_DB_REG              0x48
+#define RK805_DEV_CTRL_REG              0x4b
+#define RK805_INT_STS_REG               0x4c
+#define RK805_INT_STS_MSK_REG           0x4d
+#define RK805_GPIO_IO_POL_REG           0x50
+#define RK805_OUT_REG                   0x52
+#define RK805_ON_SOURCE_REG             0xae
+#define RK805_OFF_SOURCE_REG            0xaf
+
+#define RK805_NUM_REGULATORS            7
+
+#define RK805_PWRON_FALL_RISE_INT_EN    0x0
+#define RK805_PWRON_FALL_RISE_INT_MSK   0x81
+
+#define RK805_BUCK1_2_ILMAX_2500MA      0x0
+#define RK805_BUCK1_2_ILMAX_3000MA      0x1
+#define RK805_BUCK1_2_ILMAX_3500MA      0x2
+#define RK805_BUCK1_2_ILMAX_4000MA      0x3
+
+#define RK805_BUCK3_ILMAX_1500MA        0x0
+#define RK805_BUCK3_ILMAX_2000MA        0x1
+#define RK805_BUCK3_ILMAX_2500MA        0x2
+#define RK805_BUCK3_ILMAX_3000MA        0x3
+
+#define RK805_BUCK4_ILMAX_2000MA        0x0
+#define RK805_BUCK4_ILMAX_2500MA        0x1
+#define RK805_BUCK4_ILMAX_3000MA        0x2
+#define RK805_BUCK4_ILMAX_3500MA        0x3
+
+/* RK805 IRQ Definitions */
+#define RK805_IRQ_PWRON_RISE            0
+#define RK805_IRQ_VB_LOW                1
+#define RK805_IRQ_PWRON                 2
+#define RK805_IRQ_PWRON_LP              3
+#define RK805_IRQ_HOTDIE                4
+#define RK805_IRQ_RTC_ALARM             5
+#define RK805_IRQ_RTC_PERIOD            6
+#define RK805_IRQ_PWRON_FALL            7
+
+#define RK805_IRQ_PWRON_RISE_MSK        RT_BIT(0)
+#define RK805_IRQ_VB_LOW_MSK            RT_BIT(1)
+#define RK805_IRQ_PWRON_MSK             RT_BIT(2)
+#define RK805_IRQ_PWRON_LP_MSK          RT_BIT(3)
+#define RK805_IRQ_HOTDIE_MSK            RT_BIT(4)
+#define RK805_IRQ_RTC_ALARM_MSK         RT_BIT(5)
+#define RK805_IRQ_RTC_PERIOD_MSK        RT_BIT(6)
+#define RK805_IRQ_PWRON_FALL_MSK        RT_BIT(7)
+
+#define RK805_PWR_RISE_INT_STATUS       RT_BIT(0)
+#define RK805_VB_LOW_INT_STATUS         RT_BIT(1)
+#define RK805_PWRON_INT_STATUS          RT_BIT(2)
+#define RK805_PWRON_LP_INT_STATUS       RT_BIT(3)
+#define RK805_HOTDIE_INT_STATUS         RT_BIT(4)
+#define RK805_ALARM_INT_STATUS          RT_BIT(5)
+#define RK805_PERIOD_INT_STATUS         RT_BIT(6)
+#define RK805_PWR_FALL_INT_STATUS       RT_BIT(7)
+
+#define RK805_BUCK1_2_ILMAX_MASK        (3 << 6)
+#define RK805_BUCK3_4_ILMAX_MASK        (3 << 3)
+#define RK805_RTC_PERIOD_INT_MASK       (1 << 6)
+#define RK805_RTC_ALARM_INT_MASK        (1 << 5)
+#define RK805_INT_ALARM_EN              (1 << 3)
+#define RK805_INT_TIMER_EN              (1 << 2)
+
+#define RK806_POWER_EN0                 0x0
+#define RK806_POWER_EN1                 0x1
+#define RK806_POWER_EN2                 0x2
+#define RK806_POWER_EN3                 0x3
+#define RK806_POWER_EN4                 0x4
+#define RK806_POWER_EN5                 0x5
+#define RK806_POWER_SLP_EN0             0x6
+#define RK806_POWER_SLP_EN1             0x7
+#define RK806_POWER_SLP_EN2             0x8
+#define RK806_POWER_DISCHRG_EN0         0x9
+#define RK806_POWER_DISCHRG_EN1         0xa
+#define RK806_POWER_DISCHRG_EN2         0xb
+#define RK806_BUCK_FB_CONFIG            0xc
+#define RK806_SLP_LP_CONFIG             0xd
+#define RK806_POWER_FPWM_EN0            0xe
+#define RK806_POWER_FPWM_EN1            0xf
+#define RK806_BUCK1_CONFIG              0x10
+#define RK806_BUCK2_CONFIG              0x11
+#define RK806_BUCK3_CONFIG              0x12
+#define RK806_BUCK4_CONFIG              0x13
+#define RK806_BUCK5_CONFIG              0x14
+#define RK806_BUCK6_CONFIG              0x15
+#define RK806_BUCK7_CONFIG              0x16
+#define RK806_BUCK8_CONFIG              0x17
+#define RK806_BUCK9_CONFIG              0x18
+#define RK806_BUCK10_CONFIG             0x19
+#define RK806_BUCK1_ON_VSEL             0x1a
+#define RK806_BUCK2_ON_VSEL             0x1b
+#define RK806_BUCK3_ON_VSEL             0x1c
+#define RK806_BUCK4_ON_VSEL             0x1d
+#define RK806_BUCK5_ON_VSEL             0x1e
+#define RK806_BUCK6_ON_VSEL             0x1f
+#define RK806_BUCK7_ON_VSEL             0x20
+#define RK806_BUCK8_ON_VSEL             0x21
+#define RK806_BUCK9_ON_VSEL             0x22
+#define RK806_BUCK10_ON_VSEL            0x23
+#define RK806_BUCK1_SLP_VSEL            0x24
+#define RK806_BUCK2_SLP_VSEL            0x25
+#define RK806_BUCK3_SLP_VSEL            0x26
+#define RK806_BUCK4_SLP_VSEL            0x27
+#define RK806_BUCK5_SLP_VSEL            0x28
+#define RK806_BUCK6_SLP_VSEL            0x29
+#define RK806_BUCK7_SLP_VSEL            0x2a
+#define RK806_BUCK8_SLP_VSEL            0x2b
+#define RK806_BUCK9_SLP_VSEL            0x2d
+#define RK806_BUCK10_SLP_VSEL           0x2e
+#define RK806_BUCK_DEBUG1               0x30
+#define RK806_BUCK_DEBUG2               0x31
+#define RK806_BUCK_DEBUG3               0x32
+#define RK806_BUCK_DEBUG4               0x33
+#define RK806_BUCK_DEBUG5               0x34
+#define RK806_BUCK_DEBUG6               0x35
+#define RK806_BUCK_DEBUG7               0x36
+#define RK806_BUCK_DEBUG8               0x37
+#define RK806_BUCK_DEBUG9               0x38
+#define RK806_BUCK_DEBUG10              0x39
+#define RK806_BUCK_DEBUG11              0x3a
+#define RK806_BUCK_DEBUG12              0x3b
+#define RK806_BUCK_DEBUG13              0x3c
+#define RK806_BUCK_DEBUG14              0x3d
+#define RK806_BUCK_DEBUG15              0x3e
+#define RK806_BUCK_DEBUG16              0x3f
+#define RK806_BUCK_DEBUG17              0x40
+#define RK806_BUCK_DEBUG18              0x41
+#define RK806_NLDO_IMAX                 0x42
+#define RK806_NLDO1_ON_VSEL             0x43
+#define RK806_NLDO2_ON_VSEL             0x44
+#define RK806_NLDO3_ON_VSEL             0x45
+#define RK806_NLDO4_ON_VSEL             0x46
+#define RK806_NLDO5_ON_VSEL             0x47
+#define RK806_NLDO1_SLP_VSEL            0x48
+#define RK806_NLDO2_SLP_VSEL            0x49
+#define RK806_NLDO3_SLP_VSEL            0x4a
+#define RK806_NLDO4_SLP_VSEL            0x4b
+#define RK806_NLDO5_SLP_VSEL            0x4c
+#define RK806_PLDO_IMAX                 0x4d
+#define RK806_PLDO1_ON_VSEL             0x4e
+#define RK806_PLDO2_ON_VSEL             0x4f
+#define RK806_PLDO3_ON_VSEL             0x50
+#define RK806_PLDO4_ON_VSEL             0x51
+#define RK806_PLDO5_ON_VSEL             0x52
+#define RK806_PLDO6_ON_VSEL             0x53
+#define RK806_PLDO1_SLP_VSEL            0x54
+#define RK806_PLDO2_SLP_VSEL            0x55
+#define RK806_PLDO3_SLP_VSEL            0x56
+#define RK806_PLDO4_SLP_VSEL            0x57
+#define RK806_PLDO5_SLP_VSEL            0x58
+#define RK806_PLDO6_SLP_VSEL            0x59
+#define RK806_CHIP_NAME                 0x5a
+#define RK806_CHIP_VER                  0x5b
+#define RK806_OTP_VER                   0x5c
+#define RK806_SYS_STS                   0x5d
+#define RK806_SYS_CFG0                  0x5e
+#define RK806_SYS_CFG1                  0x5f
+#define RK806_SYS_OPTION                0x61
+#define RK806_SLEEP_CONFIG0             0x62
+#define RK806_SLEEP_CONFIG1             0x63
+#define RK806_SLEEP_CTR_SEL0            0x64
+#define RK806_SLEEP_CTR_SEL1            0x65
+#define RK806_SLEEP_CTR_SEL2            0x66
+#define RK806_SLEEP_CTR_SEL3            0x67
+#define RK806_SLEEP_CTR_SEL4            0x68
+#define RK806_SLEEP_CTR_SEL5            0x69
+#define RK806_DVS_CTRL_SEL0             0x6a
+#define RK806_DVS_CTRL_SEL1             0x6b
+#define RK806_DVS_CTRL_SEL2             0x6c
+#define RK806_DVS_CTRL_SEL3             0x6d
+#define RK806_DVS_CTRL_SEL4             0x6e
+#define RK806_DVS_CTRL_SEL5             0x6f
+#define RK806_DVS_START_CTRL            0x70
+#define RK806_SLEEP_GPIO                0x71
+#define RK806_SYS_CFG3                  0x72
+#define RK806_WDT                       0x73
+#define RK806_ON_SOURCE                 0x74
+#define RK806_OFF_SOURCE                0x75
+#define RK806_PWRON_KEY                 0x76
+#define RK806_INT_STS0                  0x77
+#define RK806_INT_MSK0                  0x78
+#define RK806_INT_STS1                  0x79
+#define RK806_INT_MSK1                  0x7a
+#define RK806_GPIO_INT_CONFIG           0x7b
+#define RK806_DATA_REG0                 0x7c
+#define RK806_DATA_REG1                 0x7d
+#define RK806_DATA_REG2                 0x7e
+#define RK806_DATA_REG3                 0x7f
+#define RK806_DATA_REG4                 0x80
+#define RK806_DATA_REG5                 0x81
+#define RK806_DATA_REG6                 0x82
+#define RK806_DATA_REG7                 0x83
+#define RK806_DATA_REG8                 0x84
+#define RK806_DATA_REG9                 0x85
+#define RK806_DATA_REG10                0x86
+#define RK806_DATA_REG11                0x87
+#define RK806_DATA_REG12                0x88
+#define RK806_DATA_REG13                0x89
+#define RK806_DATA_REG14                0x8a
+#define RK806_DATA_REG15                0x8b
+#define RK806_TM_REG                    0x8c
+#define RK806_OTP_EN_REG                0x8d
+#define RK806_FUNC_OTP_EN_REG           0x8e
+#define RK806_TEST_REG1                 0x8f
+#define RK806_TEST_REG2                 0x90
+#define RK806_TEST_REG3                 0x91
+#define RK806_TEST_REG4                 0x92
+#define RK806_TEST_REG5                 0x93
+#define RK806_BUCK_VSEL_OTP_REG0        0x94
+#define RK806_BUCK_VSEL_OTP_REG1        0x95
+#define RK806_BUCK_VSEL_OTP_REG2        0x96
+#define RK806_BUCK_VSEL_OTP_REG3        0x97
+#define RK806_BUCK_VSEL_OTP_REG4        0x98
+#define RK806_BUCK_VSEL_OTP_REG5        0x99
+#define RK806_BUCK_VSEL_OTP_REG6        0x9a
+#define RK806_BUCK_VSEL_OTP_REG7        0x9b
+#define RK806_BUCK_VSEL_OTP_REG8        0x9c
+#define RK806_BUCK_VSEL_OTP_REG9        0x9d
+#define RK806_NLDO1_VSEL_OTP_REG0       0x9e
+#define RK806_NLDO1_VSEL_OTP_REG1       0x9f
+#define RK806_NLDO1_VSEL_OTP_REG2       0xa0
+#define RK806_NLDO1_VSEL_OTP_REG3       0xa1
+#define RK806_NLDO1_VSEL_OTP_REG4       0xa2
+#define RK806_PLDO_VSEL_OTP_REG0        0xa3
+#define RK806_PLDO_VSEL_OTP_REG1        0xa4
+#define RK806_PLDO_VSEL_OTP_REG2        0xa5
+#define RK806_PLDO_VSEL_OTP_REG3        0xa6
+#define RK806_PLDO_VSEL_OTP_REG4        0xa7
+#define RK806_PLDO_VSEL_OTP_REG5        0xa8
+#define RK806_BUCK_EN_OTP_REG1          0xa9
+#define RK806_NLDO_EN_OTP_REG1          0xaa
+#define RK806_PLDO_EN_OTP_REG1          0xab
+#define RK806_BUCK_FB_RES_OTP_REG1      0xac
+#define RK806_OTP_RESEV_REG0            0xad
+#define RK806_OTP_RESEV_REG1            0xae
+#define RK806_OTP_RESEV_REG2            0xaf
+#define RK806_OTP_RESEV_REG3            0xb0
+#define RK806_OTP_RESEV_REG4            0xb1
+#define RK806_BUCK_SEQ_REG0             0xb2
+#define RK806_BUCK_SEQ_REG1             0xb3
+#define RK806_BUCK_SEQ_REG2             0xb4
+#define RK806_BUCK_SEQ_REG3             0xb5
+#define RK806_BUCK_SEQ_REG4             0xb6
+#define RK806_BUCK_SEQ_REG5             0xb7
+#define RK806_BUCK_SEQ_REG6             0xb8
+#define RK806_BUCK_SEQ_REG7             0xb9
+#define RK806_BUCK_SEQ_REG8             0xba
+#define RK806_BUCK_SEQ_REG9             0xbb
+#define RK806_BUCK_SEQ_REG10            0xbc
+#define RK806_BUCK_SEQ_REG11            0xbd
+#define RK806_BUCK_SEQ_REG12            0xbe
+#define RK806_BUCK_SEQ_REG13            0xbf
+#define RK806_BUCK_SEQ_REG14            0xc0
+#define RK806_BUCK_SEQ_REG15            0xc1
+#define RK806_BUCK_SEQ_REG16            0xc2
+#define RK806_BUCK_SEQ_REG17            0xc3
+#define RK806_HK_TRIM_REG1              0xc4
+#define RK806_HK_TRIM_REG2              0xc5
+#define RK806_BUCK_REF_TRIM_REG1        0xc6
+#define RK806_BUCK_REF_TRIM_REG2        0xc7
+#define RK806_BUCK_REF_TRIM_REG3        0xc8
+#define RK806_BUCK_REF_TRIM_REG4        0xc9
+#define RK806_BUCK_REF_TRIM_REG5        0xca
+#define RK806_BUCK_OSC_TRIM_REG1        0xcb
+#define RK806_BUCK_OSC_TRIM_REG2        0xcc
+#define RK806_BUCK_OSC_TRIM_REG3        0xcd
+#define RK806_BUCK_OSC_TRIM_REG4        0xce
+#define RK806_BUCK_OSC_TRIM_REG5        0xcf
+#define RK806_BUCK_TRIM_ZCDIOS_REG1     0xd0
+#define RK806_BUCK_TRIM_ZCDIOS_REG2     0xd1
+#define RK806_NLDO_TRIM_REG1            0xd2
+#define RK806_NLDO_TRIM_REG2            0xd3
+#define RK806_NLDO_TRIM_REG3            0xd4
+#define RK806_PLDO_TRIM_REG1            0xd5
+#define RK806_PLDO_TRIM_REG2            0xd6
+#define RK806_PLDO_TRIM_REG3            0xd7
+#define RK806_TRIM_ICOMP_REG1           0xd8
+#define RK806_TRIM_ICOMP_REG2           0xd9
+#define RK806_EFUSE_CONTROL_REGH        0xda
+#define RK806_FUSE_PROG_REG             0xdb
+#define RK806_MAIN_FSM_STS_REG          0xdd
+#define RK806_FSM_REG                   0xde
+#define RK806_TOP_RESEV_OFFR            0xec
+#define RK806_TOP_RESEV_POR             0xed
+#define RK806_BUCK_VRSN_REG1            0xee
+#define RK806_BUCK_VRSN_REG2            0xef
+#define RK806_NLDO_RLOAD_SEL_REG1       0xf0
+#define RK806_PLDO_RLOAD_SEL_REG1       0xf1
+#define RK806_PLDO_RLOAD_SEL_REG2       0xf2
+#define RK806_BUCK_CMIN_MX_REG1         0xf3
+#define RK806_BUCK_CMIN_MX_REG2         0xf4
+#define RK806_BUCK_FREQ_SET_REG1        0xf5
+#define RK806_BUCK_FREQ_SET_REG2        0xf6
+#define RK806_BUCK_RS_MEABS_REG1        0xf7
+#define RK806_BUCK_RS_MEABS_REG2        0xf8
+#define RK806_BUCK_RS_ZDLEB_REG1        0xf9
+#define RK806_BUCK_RS_ZDLEB_REG2        0xfa
+#define RK806_BUCK_RSERVE_REG1          0xfb
+#define RK806_BUCK_RSERVE_REG2          0xfc
+#define RK806_BUCK_RSERVE_REG3          0xfd
+#define RK806_BUCK_RSERVE_REG4          0xfe
+#define RK806_BUCK_RSERVE_REG5          0xff
+
+#define RK806_WDT_ACT                   RT_BIT(4)
+#define RK806_WDT_ACT_SEND_IRQ          0
+#define RK806_WDT_ACT_RESTART           1
+#define RK806_WDT_EN                    RT_BIT(3)
+#define RK806_WDT_SET                   RT_GENMASK(2, 0)
+
+/* INT_STS Register field definitions */
+#define RK806_INT_STS_PWRON_FALL        RT_BIT(0)
+#define RK806_INT_STS_PWRON_RISE        RT_BIT(1)
+#define RK806_INT_STS_PWRON             RT_BIT(2)
+#define RK806_INT_STS_PWRON_LP          RT_BIT(3)
+#define RK806_INT_STS_HOTDIE            RT_BIT(4)
+#define RK806_INT_STS_VDC_RISE          RT_BIT(5)
+#define RK806_INT_STS_VDC_FALL          RT_BIT(6)
+#define RK806_INT_STS_VB_LO             RT_BIT(7)
+#define RK806_INT_STS_REV0              RT_BIT(0)
+#define RK806_INT_STS_REV1              RT_BIT(1)
+#define RK806_INT_STS_REV2              RT_BIT(2)
+#define RK806_INT_STS_CRC_ERROR         RT_BIT(3)
+#define RK806_INT_STS_SLP3_GPIO         RT_BIT(4)
+#define RK806_INT_STS_SLP2_GPIO         RT_BIT(5)
+#define RK806_INT_STS_SLP1_GPIO         RT_BIT(6)
+#define RK806_INT_STS_WDT               RT_BIT(7)
+
+#define RK806_INT_POL_MSK               RT_BIT(1)
+#define RK806_INT_POL_H                 RT_BIT(1)
+#define RK806_INT_POL_L                 0
+
+#define RK806_SLAVE_RESTART_FUN_MSK     RT_BIT(1)
+#define RK806_SLAVE_RESTART_FUN_EN      RT_BIT(1)
+#define RK806_SLAVE_RESTART_FUN_OFF     0
+
+#define RK806_SYS_ENB2_2M_MSK           RT_BIT(1)
+#define RK806_SYS_ENB2_2M_EN            RT_BIT(1)
+#define RK806_SYS_ENB2_2M_OFF           0
+
+#define RK806_CMD_READ                  0
+#define RK806_CMD_WRITE                 RT_BIT(7)
+#define RK806_CMD_CRC_EN                RT_BIT(6)
+#define RK806_CMD_CRC_DIS               0
+#define RK806_CMD_LEN_MSK               0x0f
+#define RK806_REG_H                     0x00
+
+/* RK806 INT_STS0 registers */
+#define RK806_IRQ_PWRON_FALL            0
+#define RK806_IRQ_PWRON_RISE            1
+#define RK806_IRQ_PWRON                 2
+#define RK806_IRQ_PWRON_LP              3
+#define RK806_IRQ_HOTDIE                4
+#define RK806_IRQ_VDC_RISE              5
+#define RK806_IRQ_VDC_FALL              6
+#define RK806_IRQ_VB_LO                 7
+
+/* RK806 INT_STS0 registers */
+#define RK806_IRQ_REV0                  8
+#define RK806_IRQ_REV1                  9
+#define RK806_IRQ_REV2                  10
+#define RK806_IRQ_CRC_ERROR             11
+#define RK806_IRQ_SLP3_GPIO             12
+#define RK806_IRQ_SLP2_GPIO             13
+#define RK806_IRQ_SLP1_GPIO             14
+#define RK806_IRQ_WDT                   15
+
+#define RK808_SECONDS_REG               0x00
+#define RK808_MINUTES_REG               0x01
+#define RK808_HOURS_REG                 0x02
+#define RK808_DAYS_REG                  0x03
+#define RK808_MONTHS_REG                0x04
+#define RK808_YEARS_REG                 0x05
+#define RK808_WEEKS_REG                 0x06
+#define RK808_ALARM_SECONDS_REG         0x08
+#define RK808_ALARM_MINUTES_REG         0x09
+#define RK808_ALARM_HOURS_REG           0x0a
+#define RK808_ALARM_DAYS_REG            0x0b
+#define RK808_ALARM_MONTHS_REG          0x0c
+#define RK808_ALARM_YEARS_REG           0x0d
+#define RK808_RTC_CTRL_REG              0x10
+#define RK808_RTC_STATUS_REG            0x11
+#define RK808_RTC_INT_REG               0x12
+#define RK808_RTC_COMP_LSB_REG          0x13
+#define RK808_RTC_COMP_MSB_REG          0x14
+#define RK808_ID_MSB                    0x17
+#define RK808_ID_LSB                    0x18
+#define RK808_CLK32OUT_REG              0x20
+#define RK808_VB_MON_REG                0x21
+#define RK808_THERMAL_REG               0x22
+#define RK808_DCDC_EN_REG               0x23
+#define RK808_LDO_EN_REG                0x24
+#define RK808_SLEEP_SET_OFF_REG1        0x25
+#define RK808_SLEEP_SET_OFF_REG2        0x26
+#define RK808_DCDC_UV_STS_REG           0x27
+#define RK808_DCDC_UV_ACT_REG           0x28
+#define RK808_LDO_UV_STS_REG            0x29
+#define RK808_LDO_UV_ACT_REG            0x2a
+#define RK808_DCDC_PG_REG               0x2b
+#define RK808_LDO_PG_REG                0x2c
+#define RK808_VOUT_MON_TDB_REG          0x2d
+#define RK808_BUCK1_CONFIG_REG          0x2e
+#define RK808_BUCK1_ON_VSEL_REG         0x2f
+#define RK808_BUCK1_SLP_VSEL_REG        0x30
+#define RK808_BUCK1_DVS_VSEL_REG        0x31
+#define RK808_BUCK2_CONFIG_REG          0x32
+#define RK808_BUCK2_ON_VSEL_REG         0x33
+#define RK808_BUCK2_SLP_VSEL_REG        0x34
+#define RK808_BUCK2_DVS_VSEL_REG        0x35
+#define RK808_BUCK3_CONFIG_REG          0x36
+#define RK808_BUCK4_CONFIG_REG          0x37
+#define RK808_BUCK4_ON_VSEL_REG         0x38
+#define RK808_BUCK4_SLP_VSEL_REG        0x39
+#define RK808_BOOST_CONFIG_REG          0x3a
+#define RK808_LDO1_ON_VSEL_REG          0x3b
+#define RK808_LDO1_SLP_VSEL_REG         0x3c
+#define RK808_LDO2_ON_VSEL_REG          0x3d
+#define RK808_LDO2_SLP_VSEL_REG         0x3e
+#define RK808_LDO3_ON_VSEL_REG          0x3f
+#define RK808_LDO3_SLP_VSEL_REG         0x40
+#define RK808_LDO4_ON_VSEL_REG          0x41
+#define RK808_LDO4_SLP_VSEL_REG         0x42
+#define RK808_LDO5_ON_VSEL_REG          0x43
+#define RK808_LDO5_SLP_VSEL_REG         0x44
+#define RK808_LDO6_ON_VSEL_REG          0x45
+#define RK808_LDO6_SLP_VSEL_REG         0x46
+#define RK808_LDO7_ON_VSEL_REG          0x47
+#define RK808_LDO7_SLP_VSEL_REG         0x48
+#define RK808_LDO8_ON_VSEL_REG          0x49
+#define RK808_LDO8_SLP_VSEL_REG         0x4a
+#define RK808_DEVCTRL_REG               0x4b
+#define RK808_INT_STS_REG1              0x4c
+#define RK808_INT_STS_MSK_REG1          0x4d
+#define RK808_INT_STS_REG2              0x4e
+#define RK808_INT_STS_MSK_REG2          0x4f
+#define RK808_IO_POL_REG                0x50
+
+/* RK808 IRQ Definitions */
+#define RK808_IRQ_VOUT_LO               0
+#define RK808_IRQ_VB_LO                 1
+#define RK808_IRQ_PWRON                 2
+#define RK808_IRQ_PWRON_LP              3
+#define RK808_IRQ_HOTDIE                4
+#define RK808_IRQ_RTC_ALARM             5
+#define RK808_IRQ_RTC_PERIOD            6
+#define RK808_IRQ_PLUG_IN_INT           7
+#define RK808_IRQ_PLUG_OUT_INT          8
+#define RK808_NUM_IRQ                   9
+
+#define RK808_IRQ_VOUT_LO_MSK           RT_BIT(0)
+#define RK808_IRQ_VB_LO_MSK             RT_BIT(1)
+#define RK808_IRQ_PWRON_MSK             RT_BIT(2)
+#define RK808_IRQ_PWRON_LP_MSK          RT_BIT(3)
+#define RK808_IRQ_HOTDIE_MSK            RT_BIT(4)
+#define RK808_IRQ_RTC_ALARM_MSK         RT_BIT(5)
+#define RK808_IRQ_RTC_PERIOD_MSK        RT_BIT(6)
+#define RK808_IRQ_PLUG_IN_INT_MSK       RT_BIT(0)
+#define RK808_IRQ_PLUG_OUT_INT_MSK      RT_BIT(1)
+
+#define RK809_BUCK5_CONFIG(i)           (RK817_BOOST_OTG_CFG + (i) * 1)
+
+#define RK817_SECONDS_REG               0x00
+#define RK817_MINUTES_REG               0x01
+#define RK817_HOURS_REG                 0x02
+#define RK817_DAYS_REG                  0x03
+#define RK817_MONTHS_REG                0x04
+#define RK817_YEARS_REG                 0x05
+#define RK817_WEEKS_REG                 0x06
+#define RK817_ALARM_SECONDS_REG         0x07
+#define RK817_ALARM_MINUTES_REG         0x08
+#define RK817_ALARM_HOURS_REG           0x09
+#define RK817_ALARM_DAYS_REG            0x0a
+#define RK817_ALARM_MONTHS_REG          0x0b
+#define RK817_ALARM_YEARS_REG           0x0c
+#define RK817_RTC_CTRL_REG              0xd
+#define RK817_RTC_STATUS_REG            0xe
+#define RK817_RTC_INT_REG               0xf
+#define RK817_RTC_COMP_LSB_REG          0x10
+#define RK817_RTC_COMP_MSB_REG          0x11
+
+/* RK817 Codec Registers */
+#define RK817_CODEC_DTOP_VUCTL          0x12
+#define RK817_CODEC_DTOP_VUCTIME        0x13
+#define RK817_CODEC_DTOP_LPT_SRST       0x14
+#define RK817_CODEC_DTOP_DIGEN_CLKE     0x15
+#define RK817_CODEC_AREF_RTCFG0         0x16
+#define RK817_CODEC_AREF_RTCFG1         0x17
+#define RK817_CODEC_AADC_CFG0           0x18
+#define RK817_CODEC_AADC_CFG1           0x19
+#define RK817_CODEC_DADC_VOLL           0x1a
+#define RK817_CODEC_DADC_VOLR           0x1b
+#define RK817_CODEC_DADC_SR_ACL0        0x1e
+#define RK817_CODEC_DADC_ALC1           0x1f
+#define RK817_CODEC_DADC_ALC2           0x20
+#define RK817_CODEC_DADC_NG             0x21
+#define RK817_CODEC_DADC_HPF            0x22
+#define RK817_CODEC_DADC_RVOLL          0x23
+#define RK817_CODEC_DADC_RVOLR          0x24
+#define RK817_CODEC_AMIC_CFG0           0x27
+#define RK817_CODEC_AMIC_CFG1           0x28
+#define RK817_CODEC_DMIC_PGA_GAIN       0x29
+#define RK817_CODEC_DMIC_LMT1           0x2a
+#define RK817_CODEC_DMIC_LMT2           0x2b
+#define RK817_CODEC_DMIC_NG1            0x2c
+#define RK817_CODEC_DMIC_NG2            0x2d
+#define RK817_CODEC_ADAC_CFG0           0x2e
+#define RK817_CODEC_ADAC_CFG1           0x2f
+#define RK817_CODEC_DDAC_POPD_DACST     0x30
+#define RK817_CODEC_DDAC_VOLL           0x31
+#define RK817_CODEC_DDAC_VOLR           0x32
+#define RK817_CODEC_DDAC_SR_LMT0        0x35
+#define RK817_CODEC_DDAC_LMT1           0x36
+#define RK817_CODEC_DDAC_LMT2           0x37
+#define RK817_CODEC_DDAC_MUTE_MIXCTL    0x38
+#define RK817_CODEC_DDAC_RVOLL          0x39
+#define RK817_CODEC_DDAC_RVOLR          0x3a
+#define RK817_CODEC_AHP_ANTI0           0x3b
+#define RK817_CODEC_AHP_ANTI1           0x3c
+#define RK817_CODEC_AHP_CFG0            0x3d
+#define RK817_CODEC_AHP_CFG1            0x3e
+#define RK817_CODEC_AHP_CP              0x3f
+#define RK817_CODEC_ACLASSD_CFG1        0x40
+#define RK817_CODEC_ACLASSD_CFG2        0x41
+#define RK817_CODEC_APLL_CFG0           0x42
+#define RK817_CODEC_APLL_CFG1           0x43
+#define RK817_CODEC_APLL_CFG2           0x44
+#define RK817_CODEC_APLL_CFG3           0x45
+#define RK817_CODEC_APLL_CFG4           0x46
+#define RK817_CODEC_APLL_CFG5           0x47
+#define RK817_CODEC_DI2S_CKM            0x48
+#define RK817_CODEC_DI2S_RSD            0x49
+#define RK817_CODEC_DI2S_RXCR1          0x4a
+#define RK817_CODEC_DI2S_RXCR2          0x4b
+#define RK817_CODEC_DI2S_RXCMD_TSD      0x4c
+#define RK817_CODEC_DI2S_TXCR1          0x4d
+#define RK817_CODEC_DI2S_TXCR2          0x4e
+#define RK817_CODEC_DI2S_TXCR3_TXCMD    0x4f
+
+#define RK817_POWER_EN_REG(i)           (0xb1 + (i))
+#define RK817_POWER_SLP_EN_REG(i)       (0xb5 + (i))
+
+#define RK817_POWER_CONFIG              (0xb9)
+
+#define RK817_BUCK_CONFIG_REG(i)        (0xba + (i) * 3)
+
+#define RK817_BUCK1_ON_VSEL_REG         0xbb
+#define RK817_BUCK1_SLP_VSEL_REG        0xbc
+
+#define RK817_BUCK2_CONFIG_REG          0xbd
+#define RK817_BUCK2_ON_VSEL_REG         0xbe
+#define RK817_BUCK2_SLP_VSEL_REG        0xbf
+
+#define RK817_BUCK3_CONFIG_REG          0xc0
+#define RK817_BUCK3_ON_VSEL_REG         0xc1
+#define RK817_BUCK3_SLP_VSEL_REG        0xc2
+
+#define RK817_BUCK4_CONFIG_REG          0xc3
+#define RK817_BUCK4_ON_VSEL_REG         0xc4
+#define RK817_BUCK4_SLP_VSEL_REG        0xc5
+
+#define RK817_LDO_ON_VSEL_REG(idx)      (0xcc + (idx) * 2)
+#define RK817_BOOST_OTG_CFG             (0xde)
+
+#define RK817_HOTDIE_TEMP_MSK           (0x3 << 4)
+#define RK817_HOTDIE_85                 (0x0 << 4)
+#define RK817_HOTDIE_95                 (0x1 << 4)
+#define RK817_HOTDIE_105                (0x2 << 4)
+#define RK817_HOTDIE_115                (0x3 << 4)
+
+#define RK817_TSD_TEMP_MSK              RT_BIT(6)
+#define RK817_TSD_140                   0
+#define RK817_TSD_160                   RT_BIT(6)
+
+#define RK817_INT_POL_MSK               RT_BIT(1)
+#define RK817_INT_POL_H                 RT_BIT(1)
+#define RK817_INT_POL_L                 0
+
+enum rk817_reg_id
+{
+    RK817_ID_DCDC1 = 0,
+    RK817_ID_DCDC2,
+    RK817_ID_DCDC3,
+    RK817_ID_DCDC4,
+    RK817_ID_LDO1,
+    RK817_ID_LDO2,
+    RK817_ID_LDO3,
+    RK817_ID_LDO4,
+    RK817_ID_LDO5,
+    RK817_ID_LDO6,
+    RK817_ID_LDO7,
+    RK817_ID_LDO8,
+    RK817_ID_LDO9,
+    RK817_ID_BOOST,
+    RK817_ID_BOOST_OTG_SW,
+    RK817_NUM_REGULATORS
+};
+
+#define RK817_SYS_CFG(i)                ((i) + 0xf1)
+
+#define RK817_CLK32KOUT2_EN             RT_BIT(7)
+
+#define RK817_SLPPIN_FUNC_MSK           (0x3 << 3)
+#define SLPPIN_NULL_FUN                 (0x0 << 3)
+#define SLPPIN_SLP_FUN                  (0x1 << 3)
+#define SLPPIN_DN_FUN                   (0x2 << 3)
+#define SLPPIN_RST_FUN                  (0x3 << 3)
+
+#define RK817_RST_FUNC_MSK              (0x3 << 6)
+#define RK817_RST_FUNC_SFT              (6)
+#define RK817_RST_FUNC_CNT              (3)
+#define RK817_RST_FUNC_DEV              (0) /* reset the dev */
+#define RK817_RST_FUNC_REG              (0x1 << 6) /* reset the reg only */
+
+/* INTERRUPT REGISTER */
+#define RK817_INT_STS_REG0              0xf8
+#define RK817_INT_STS_MSK_REG0          0xf9
+#define RK817_INT_STS_REG1              0xfa
+#define RK817_INT_STS_MSK_REG1          0xfb
+#define RK817_INT_STS_REG2              0xfc
+#define RK817_INT_STS_MSK_REG2          0xfd
+#define RK817_GPIO_INT_CFG              0xfe
+
+/* IRQ Definitions */
+#define RK817_IRQ_PWRON_FALL            0
+#define RK817_IRQ_PWRON_RISE            1
+#define RK817_IRQ_PWRON                 2
+#define RK817_IRQ_PWMON_LP              3
+#define RK817_IRQ_HOTDIE                4
+#define RK817_IRQ_RTC_ALARM             5
+#define RK817_IRQ_RTC_PERIOD            6
+#define RK817_IRQ_VB_LO                 7
+#define RK817_IRQ_PLUG_IN               8
+#define RK817_IRQ_PLUG_OUT              9
+#define RK817_IRQ_CHRG_TERM             10
+#define RK817_IRQ_CHRG_TIME             11
+#define RK817_IRQ_CHRG_TS               12
+#define RK817_IRQ_USB_OV                13
+#define RK817_IRQ_CHRG_IN_CLMP          14
+#define RK817_IRQ_BAT_DIS_ILIM          15
+#define RK817_IRQ_GATE_GPIO             16
+#define RK817_IRQ_TS_GPIO               17
+#define RK817_IRQ_CODEC_PD              18
+#define RK817_IRQ_CODEC_PO              19
+#define RK817_IRQ_CLASSD_MUTE_DONE      20
+#define RK817_IRQ_CLASSD_OCP            21
+#define RK817_IRQ_BAT_OVP               22
+#define RK817_IRQ_CHRG_BAT_HI           23
+
+#define RK818_DCDC1                     0
+#define RK818_LDO1                      4
+#define RK818_NUM_REGULATORS            17
+
+enum rk818_reg
+{
+    RK818_ID_DCDC1,
+    RK818_ID_DCDC2,
+    RK818_ID_DCDC3,
+    RK818_ID_DCDC4,
+    RK818_ID_BOOST,
+    RK818_ID_LDO1,
+    RK818_ID_LDO2,
+    RK818_ID_LDO3,
+    RK818_ID_LDO4,
+    RK818_ID_LDO5,
+    RK818_ID_LDO6,
+    RK818_ID_LDO7,
+    RK818_ID_LDO8,
+    RK818_ID_LDO9,
+    RK818_ID_SWITCH,
+    RK818_ID_HDMI_SWITCH,
+    RK818_ID_OTG_SWITCH,
+};
+
+#define RK818_DCDC_EN_REG               0x23
+#define RK818_LDO_EN_REG                0x24
+#define RK818_SLEEP_SET_OFF_REG1        0x25
+#define RK818_SLEEP_SET_OFF_REG2        0x26
+#define RK818_DCDC_UV_STS_REG           0x27
+#define RK818_DCDC_UV_ACT_REG           0x28
+#define RK818_LDO_UV_STS_REG            0x29
+#define RK818_LDO_UV_ACT_REG            0x2a
+#define RK818_DCDC_PG_REG               0x2b
+#define RK818_LDO_PG_REG                0x2c
+#define RK818_VOUT_MON_TDB_REG          0x2d
+#define RK818_BUCK1_CONFIG_REG          0x2e
+#define RK818_BUCK1_ON_VSEL_REG         0x2f
+#define RK818_BUCK1_SLP_VSEL_REG        0x30
+#define RK818_BUCK2_CONFIG_REG          0x32
+#define RK818_BUCK2_ON_VSEL_REG         0x33
+#define RK818_BUCK2_SLP_VSEL_REG        0x34
+#define RK818_BUCK3_CONFIG_REG          0x36
+#define RK818_BUCK4_CONFIG_REG          0x37
+#define RK818_BUCK4_ON_VSEL_REG         0x38
+#define RK818_BUCK4_SLP_VSEL_REG        0x39
+#define RK818_BOOST_CONFIG_REG          0x3a
+#define RK818_LDO1_ON_VSEL_REG          0x3b
+#define RK818_LDO1_SLP_VSEL_REG         0x3c
+#define RK818_LDO2_ON_VSEL_REG          0x3d
+#define RK818_LDO2_SLP_VSEL_REG         0x3e
+#define RK818_LDO3_ON_VSEL_REG          0x3f
+#define RK818_LDO3_SLP_VSEL_REG         0x40
+#define RK818_LDO4_ON_VSEL_REG          0x41
+#define RK818_LDO4_SLP_VSEL_REG         0x42
+#define RK818_LDO5_ON_VSEL_REG          0x43
+#define RK818_LDO5_SLP_VSEL_REG         0x44
+#define RK818_LDO6_ON_VSEL_REG          0x45
+#define RK818_LDO6_SLP_VSEL_REG         0x46
+#define RK818_LDO7_ON_VSEL_REG          0x47
+#define RK818_LDO7_SLP_VSEL_REG         0x48
+#define RK818_LDO8_ON_VSEL_REG          0x49
+#define RK818_LDO8_SLP_VSEL_REG         0x4a
+#define RK818_BOOST_LDO9_ON_VSEL_REG    0x54
+#define RK818_BOOST_LDO9_SLP_VSEL_REG   0x55
+#define RK818_DEVCTRL_REG               0x4b
+#define RK818_INT_STS_REG1              0X4c
+#define RK818_INT_STS_MSK_REG1          0x4d
+#define RK818_INT_STS_REG2              0x4e
+#define RK818_INT_STS_MSK_REG2          0x4f
+#define RK818_IO_POL_REG                0x50
+#define RK818_H5V_EN_REG                0x52
+#define RK818_SLEEP_SET_OFF_REG3        0x53
+#define RK818_BOOST_LDO9_ON_VSEL_REG    0x54
+#define RK818_BOOST_LDO9_SLP_VSEL_REG   0x55
+#define RK818_BOOST_CTRL_REG            0x56
+#define RK818_DCDC_ILMAX                0x90
+#define RK818_USB_CTRL_REG              0xa1
+
+#define RK818_H5V_EN                    RT_BIT(0)
+#define RK818_REF_RDY_CTRL              RT_BIT(1)
+#define RK818_USB_ILIM_SEL_MASK         0xf
+#define RK818_USB_ILMIN_2000MA          0x7
+#define RK818_USB_CHG_SD_VSEL_MASK      0x70
+
+/* RK818 IRQ Definitions */
+#define RK818_IRQ_VOUT_LO               0
+#define RK818_IRQ_VB_LO                 1
+#define RK818_IRQ_PWRON                 2
+#define RK818_IRQ_PWRON_LP              3
+#define RK818_IRQ_HOTDIE                4
+#define RK818_IRQ_RTC_ALARM             5
+#define RK818_IRQ_RTC_PERIOD            6
+#define RK818_IRQ_USB_OV                7
+#define RK818_IRQ_PLUG_IN               8
+#define RK818_IRQ_PLUG_OUT              9
+#define RK818_IRQ_CHG_OK                10
+#define RK818_IRQ_CHG_TE                11
+#define RK818_IRQ_CHG_TS1               12
+#define RK818_IRQ_TS2                   13
+#define RK818_IRQ_CHG_CVTLIM            14
+#define RK818_IRQ_DISCHG_ILIM           15
+
+#define RK818_IRQ_VOUT_LO_MSK           RT_BIT(0)
+#define RK818_IRQ_VB_LO_MSK             RT_BIT(1)
+#define RK818_IRQ_PWRON_MSK             RT_BIT(2)
+#define RK818_IRQ_PWRON_LP_MSK          RT_BIT(3)
+#define RK818_IRQ_HOTDIE_MSK            RT_BIT(4)
+#define RK818_IRQ_RTC_ALARM_MSK         RT_BIT(5)
+#define RK818_IRQ_RTC_PERIOD_MSK        RT_BIT(6)
+#define RK818_IRQ_USB_OV_MSK            RT_BIT(7)
+#define RK818_IRQ_PLUG_IN_MSK           RT_BIT(0)
+#define RK818_IRQ_PLUG_OUT_MSK          RT_BIT(1)
+#define RK818_IRQ_CHG_OK_MSK            RT_BIT(2)
+#define RK818_IRQ_CHG_TE_MSK            RT_BIT(3)
+#define RK818_IRQ_CHG_TS1_MSK           RT_BIT(4)
+#define RK818_IRQ_TS2_MSK               RT_BIT(5)
+#define RK818_IRQ_CHG_CVTLIM_MSK        RT_BIT(6)
+#define RK818_IRQ_DISCHG_ILIM_MSK       RT_BIT(7)
+#define RK818_NUM_IRQ                   16
+
+#define BUCK_ILMIN_MASK                 (7 << 0)
+#define BOOST_ILMIN_MASK                (7 << 0)
+#define BUCK1_RATE_MASK                 (3 << 3)
+#define BUCK2_RATE_MASK                 (3 << 3)
+#define MASK_ALL                        0xff
+
+#define BUCK_UV_ACT_MASK                0x0f
+#define BUCK_UV_ACT_DISABLE             0
+
+#define SWITCH2_EN                      RT_BIT(6)
+#define SWITCH1_EN                      RT_BIT(5)
+#define DEV_OFF_RST                     RT_BIT(3)
+#define DEV_RST                         RT_BIT(2)
+#define DEV_OFF                         RT_BIT(0)
+#define RTC_STOP                        RT_BIT(0)
+
+#define VB_LO_ACT                       RT_BIT(4)
+#define VB_LO_SEL_3500MV                (7 << 0)
+
+#define VOUT_LO_INT                     RT_BIT(0)
+#define CLK32KOUT2_EN                   RT_BIT(0)
+
+#define TEMP115C                        0x0c
+#define TEMP_HOTDIE_MSK                 0x0c
+#define SLP_SD_MSK                      (0x3 << 2)
+#define SHUTDOWN_FUN                    (0x2 << 2)
+#define SLEEP_FUN                       (0x1 << 2)
+#define RK8XX_ID_MSK                    0xfff0
+#define PWM_MODE_MSK                    RT_BIT(7)
+#define FPWM_MODE                       RT_BIT(7)
+#define AUTO_PWM_MODE                   0
+
+#define BUCK_ILMIN_50MA                 0
+#define BUCK_ILMIN_100MA                1
+#define BUCK_ILMIN_150MA                2
+#define BUCK_ILMIN_200MA                3
+#define BUCK_ILMIN_250MA                4
+#define BUCK_ILMIN_300MA                5
+#define BUCK_ILMIN_350MA                6
+#define BUCK_ILMIN_400MA                7
+
+#define BOOST_ILMIN_75MA                0
+#define BOOST_ILMIN_100MA               1
+#define BOOST_ILMIN_125MA               2
+#define BOOST_ILMIN_150MA               3
+#define BOOST_ILMIN_175MA               4
+#define BOOST_ILMIN_200MA               5
+#define BOOST_ILMIN_225MA               6
+#define BOOST_ILMIN_250MA               7
+
+enum
+{
+    RK805_ID = 0x8050,
+    RK806_ID = 0x8060,
+    RK808_ID = 0x0000,
+    RK809_ID = 0x8090,
+    RK817_ID = 0x8170,
+    RK818_ID = 0x8180,
+};
+
+struct rk8xx
+{
+    int variant;
+
+    int irq;
+    struct rt_device *dev;
+
+    rt_uint32_t (*read)(struct rk8xx *, rt_uint16_t reg);
+    rt_err_t (*write)(struct rk8xx *, rt_uint16_t reg, rt_uint8_t data);
+    rt_err_t (*update_bits)(struct rk8xx *, rt_uint16_t reg, rt_uint8_t mask,
+            rt_uint8_t data);
+};
+
+#define rk8xx_to_i2c_client(rk8xx) rt_container_of((rk8xx)->dev, struct rt_i2c_client, parent)
+#define rk8xx_to_spi_device(rk8xx) rt_container_of((rk8xx)->dev, struct rt_spi_device, parent)
+
+rt_inline rt_uint32_t rk8xx_read(struct rk8xx *rk8xx, rt_uint16_t reg)
+{
+    return rk8xx->read(rk8xx, reg);
+}
+
+rt_inline rt_err_t rk8xx_write(struct rk8xx *rk8xx, rt_uint16_t reg, rt_uint8_t data)
+{
+    return rk8xx->write(rk8xx, reg, data);
+}
+
+rt_inline rt_err_t rk8xx_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg,
+        rt_uint8_t mask, rt_uint8_t data)
+{
+    return rk8xx->update_bits(rk8xx, reg, mask, data);
+}
+
+rt_err_t rk8xx_probe(struct rk8xx *rk8xx);
+rt_err_t rk8xx_shutdown(struct rk8xx *rk8xx);
+
+#endif /* __RK8XX_H__ */

+ 86 - 0
bsp/rockchip/dm/include/rockchip.h

@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#ifndef __ROCKCHIP_H__
+#define __ROCKCHIP_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <dt-bindings/size.h>
+
+#define rk_clrsetreg(addr, clr, set)    HWREG32(addr) = (((clr) | (set)) << 16 | (set))
+#define rk_clrreg(addr, clr)            HWREG32(addr) = ((clr) << 16)
+#define rk_setreg(addr, set)            HWREG32(addr) = ((set) << 16 | (set))
+
+#define HIWORD_UPDATE(val, mask, shift) ((val) << (shift) | (mask) << ((shift) + 16))
+
+#define readx_poll_timeout(OP, ADDR, VAL, COND, DELAY_US, TIMEOUT_US) \
+({                                                      \
+    rt_uint64_t timeout_us = (TIMEOUT_US);              \
+    rt_int64_t left_ns = timeout_us * 1000L;            \
+    rt_ubase_t delay_us = (DELAY_US);                   \
+    rt_uint64_t delay_ns = delay_us * 1000L;            \
+    for (;;)                                            \
+    {                                                   \
+        (VAL) = OP(ADDR);                               \
+        if (COND)                                       \
+        {                                               \
+            break;                                      \
+        }                                               \
+        if (timeout_us && left_ns < 0)                  \
+        {                                               \
+            (VAL) = OP(ADDR);                           \
+            break;                                      \
+        }                                               \
+        if (delay_us)                                   \
+        {                                               \
+            rt_hw_us_delay(delay_us);                   \
+            if (timeout_us)                             \
+            {                                           \
+                left_ns -= delay_ns;                    \
+            }                                           \
+        }                                               \
+        rt_hw_cpu_relax();                              \
+        if (timeout_us)                                 \
+        {                                               \
+            --left_ns;                                  \
+        }                                               \
+    }                                                   \
+    (COND) ? RT_EOK : -RT_ETIMEOUT;                     \
+})
+
+#define readl_poll_timeout(ADDR, VAL, COND, DELAY_US, TIMEOUT_US) \
+        readx_poll_timeout(HWREG32, ADDR, VAL, COND, DELAY_US, TIMEOUT_US)
+
+#define is_aligned(x, a)    (((x) & ((typeof(x))(a) - 1)) == 0)
+
+rt_inline int fls(int x)
+{
+    return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
+}
+
+rt_inline int fls_long(unsigned long x)
+{
+    return x ? sizeof(x) * 8 - __builtin_clzl(x) : 0;
+}
+
+rt_inline int __roundup_pow_of_two(rt_uint32_t x)
+{
+    return 1UL << fls(x - 1);
+}
+
+rt_inline int __rounddown_pow_of_two(rt_uint32_t x)
+{
+    return (1UL << fls(x - 1)) / 2;
+}
+
+#endif /* __ROCKCHIP_H__ */

+ 13 - 0
bsp/rockchip/dm/input/SConscript

@@ -0,0 +1,13 @@
+import os
+from building import *
+
+cwd = GetCurrentDir()
+objs = []
+list = os.listdir(cwd)
+
+for d in list:
+    path = os.path.join(cwd, d)
+    if os.path.isfile(os.path.join(path, 'SConscript')):
+        objs = objs + SConscript(os.path.join(d, 'SConscript'))
+
+Return('objs')

+ 5 - 0
bsp/rockchip/dm/input/misc/Kconfig

@@ -0,0 +1,5 @@
+config RT_INPUT_MISC_PWRKEY_RK8XX
+    bool "Rockchip RK805/RK806/RK817 PMIC power key support"
+    depends on RT_INPUT_MISC
+    depends on RT_MFD_RK8XX
+    default n

+ 13 - 0
bsp/rockchip/dm/input/misc/SConscript

@@ -0,0 +1,13 @@
+from building import *
+
+group = []
+src = []
+cwd = GetCurrentDir()
+CPPPATH = [cwd + '/../../include']
+
+if GetDepend(['RT_INPUT_MISC_PWRKEY_RK8XX']):
+    src += ['pwrkey-rk8xx.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 115 - 0
bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c

@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+struct rk8xx_pwrkey
+{
+    struct rt_input_device parent;
+
+    int fall_irq, rise_irq;
+};
+
+static void rk8xx_pwrkey_fall_isr(int irqno, void *param)
+{
+    struct rk8xx_pwrkey *pwr = param;
+
+    rt_interrupt_enter();
+
+    rt_input_report_key(&pwr->parent, KEY_POWER, 1);
+    rt_input_sync(&pwr->parent);
+
+    rt_interrupt_leave();
+}
+
+static void rk8xx_pwrkey_rise_isr(int irqno, void *param)
+{
+    struct rk8xx_pwrkey *pwr = param;
+
+    rt_interrupt_enter();
+
+    rt_input_report_key(&pwr->parent, KEY_POWER, 0);
+    rt_input_sync(&pwr->parent);
+
+    rt_interrupt_leave();
+}
+
+static rt_err_t rk8xx_pwrkey_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_device *dev = &pdev->parent;
+    struct rk8xx_pwrkey *pwr = rt_calloc(1, sizeof(*pwr));
+
+    if (!pwr)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if ((pwr->fall_irq = rt_dm_dev_get_irq(dev, 0)) < 0)
+    {
+        err = pwr->fall_irq;
+        goto _fail;
+    }
+
+    if ((pwr->rise_irq = rt_dm_dev_get_irq(dev, 1)) < 0)
+    {
+        err = pwr->rise_irq;
+        goto _fail;
+    }
+
+    rt_input_set_capability(&pwr->parent, EV_KEY, KEY_POWER);
+
+    if ((err = rt_input_device_register(&pwr->parent)))
+    {
+        goto _fail;
+    }
+
+    dev->user_data = pwr;
+
+    rt_hw_interrupt_install(pwr->fall_irq, rk8xx_pwrkey_fall_isr, pwr, "pwrkey-rk8xx-fall");
+    rt_hw_interrupt_umask(pwr->fall_irq);
+
+    rt_hw_interrupt_install(pwr->rise_irq, rk8xx_pwrkey_rise_isr, pwr, "pwrkey-rk8xx-rise");
+    rt_hw_interrupt_umask(pwr->rise_irq);
+
+    return RT_EOK;
+
+_fail:
+    rt_free(pwr);
+
+    return err;
+}
+
+static rt_err_t rk8xx_pwrkey_remove(struct rt_platform_device *pdev)
+{
+    struct rk8xx_pwrkey *pwr = pdev->parent.user_data;
+
+    rt_hw_interrupt_mask(pwr->fall_irq);
+    rt_pic_detach_irq(pwr->fall_irq, pwr);
+
+    rt_hw_interrupt_mask(pwr->rise_irq);
+    rt_pic_detach_irq(pwr->rise_irq, pwr);
+
+    rt_input_device_unregister(&pwr->parent);
+
+    rt_free(pwr);
+
+    return RT_EOK;
+}
+
+static struct rt_platform_driver rk8xx_pwrkey_driver =
+{
+    .name = "rk8xx-pwrkey",
+    .probe = rk8xx_pwrkey_probe,
+    .remove = rk8xx_pwrkey_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rk8xx_pwrkey_driver);

+ 3 - 0
bsp/rockchip/dm/mailbox/Kconfig

@@ -0,0 +1,3 @@
+config RT_MBOX_ROCKCHIP
+    bool "Rockchip Soc Integrated Mailbox Support"
+    default n

+ 12 - 0
bsp/rockchip/dm/mailbox/SConscript

@@ -0,0 +1,12 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include']
+
+if GetDepend(['RT_MBOX_ROCKCHIP']):
+    src += ['mailbox-rockchip.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 575 - 0
bsp/rockchip/dm/mailbox/mailbox-rockchip.c

@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-09-23     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "mailbox.rockchip"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#define MAILBOX_A2B_INTEN               0x00
+#define MAILBOX_A2B_STATUS              0x04
+#define MAILBOX_A2B_CMD(x)              (0x08 + (x) * 8)
+#define MAILBOX_A2B_DAT(x)              (0x0c + (x) * 8)
+
+#define MAILBOX_B2A_INTEN               0x28
+#define MAILBOX_B2A_STATUS              0x2C
+#define MAILBOX_B2A_CMD(x)              (0x30 + (x) * 8)
+#define MAILBOX_B2A_DAT(x)              (0x34 + (x) * 8)
+
+#define MAILBOX_V2_A2B_INTEN            MAILBOX_A2B_INTEN
+#define MAILBOX_V2_A2B_STATUS           MAILBOX_A2B_STATUS
+#define MAILBOX_V2_A2B_CMD              0x08
+#define MAILBOX_V2_A2B_DAT              0x0c
+
+#define MAILBOX_V2_B2A_INTEN            0x10
+#define MAILBOX_V2_B2A_STATUS           0x14
+#define MAILBOX_V2_B2A_CMD              0x18
+#define MAILBOX_V2_B2A_DAT              0x1c
+
+#define MAILBOX_V2_TRIGGER_SHIFT        8
+#define MAILBOX_V2_TRIGGER_MASK         RT_BIT(8)
+
+#define MAILBOX_V2_INTEN_TX_DONE        RT_BIT(0)
+#define MAILBOX_V2_INTEN_RX_DONE        RT_BIT(1)
+#define MAILBOX_V2_INTEN_RX_DONE_SHIFT  1
+
+#define MAILBOX_V2_STATUS_TX_DONE       RT_BIT(0)
+#define MAILBOX_V2_STATUS_RX_DONE       RT_BIT(1)
+#define MAILBOX_V2_STATUS_MASK          RT_GENMASK(1, 0)
+
+#define MAILBOX_POLLING_MS              5 /* default polling interval 5ms */
+#define BIT_WRITEABLE_SHIFT             16
+
+struct rockchip_mbox;
+
+struct rockchip_mbox_reg
+{
+    rt_uint32_t tx_int;
+    rt_uint32_t tx_sts;
+    rt_uint32_t tx_cmd;
+    rt_uint32_t tx_dat;
+    rt_uint32_t rx_int;
+    rt_uint32_t rx_sts;
+    rt_uint32_t rx_cmd;
+    rt_uint32_t rx_dat;
+};
+
+struct rockchip_mbox_msg
+{
+    rt_uint32_t cmd;
+    rt_uint32_t data;
+};
+
+struct rockchip_mbox_soc_data
+{
+    int num_chans;
+    struct rockchip_mbox_reg reg_a2b;
+    struct rockchip_mbox_reg reg_b2a;
+    const struct rt_mbox_controller_ops *ops;
+    void (*isr)(int irqno, void *param);
+    void (*thread_isr)(void *param);
+};
+
+struct rockchip_mbox_chan
+{
+    int idx;
+    int irq;
+    struct rockchip_mbox_msg *msg;
+    struct rockchip_mbox *rk_mbox;
+};
+
+struct rockchip_mbox
+{
+    struct rt_mbox_controller parent;
+
+    void *regs;
+    struct rt_clk *pclk;
+    struct rt_thread *irq_thread;
+    const struct rockchip_mbox_reg *reg;
+
+    rt_uint32_t buf_size;
+    rt_bool_t txdone_irq;
+    rt_bool_t trigger_method;
+    struct rockchip_mbox_chan chans[];
+};
+
+#define raw_to_rockchip_mbox(raw) rt_container_of(raw, struct rockchip_mbox, parent)
+
+rt_inline rt_uint32_t rockchip_mbox_readl(struct rockchip_mbox *rk_mbox, int offset)
+{
+    return HWREG32(rk_mbox->regs + offset);
+}
+
+rt_inline void rockchip_mbox_writel(struct rockchip_mbox *rk_mbox, int offset,
+        rt_uint32_t value)
+{
+    HWREG32(rk_mbox->regs + offset) = value;
+}
+
+static rt_err_t rockchip_mbox_request(struct rt_mbox_chan *chan)
+{
+    int idx;
+    rt_uint32_t value;
+    struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl);
+
+    idx = chan - rk_mbox->parent.chans;
+
+    /* Enable the corresponding B2A interrupts */
+    value = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_INTEN);
+    value |= RT_BIT(idx);
+    rockchip_mbox_writel(rk_mbox, MAILBOX_B2A_INTEN, value);
+
+    return RT_EOK;
+}
+
+static void rockchip_mbox_release(struct rt_mbox_chan *chan)
+{
+    int idx;
+    rt_uint32_t value;
+    struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl);
+
+    idx = chan - rk_mbox->parent.chans;
+
+    /* Disable the corresponding B2A interrupts */
+    value = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_INTEN);
+    value &= ~RT_BIT(idx);
+    rockchip_mbox_writel(rk_mbox, MAILBOX_B2A_INTEN, value);
+
+    rk_mbox->chans[idx].msg = RT_NULL;
+}
+
+static rt_err_t rockchip_mbox_send(struct rt_mbox_chan *chan, const void *data)
+{
+    int idx;
+    struct rockchip_mbox_msg *msg = (void *)data;
+    struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl);
+
+    idx = chan - rk_mbox->parent.chans;
+
+    if (rockchip_mbox_readl(rk_mbox, MAILBOX_A2B_STATUS) & RT_BIT(idx))
+    {
+        LOG_E("The mailbox channel(%d) is busy", idx);
+
+        return -RT_EBUSY;
+    }
+
+    rk_mbox->chans[idx].msg = msg;
+
+    rockchip_mbox_writel(rk_mbox, MAILBOX_A2B_CMD(idx), msg->cmd);
+    rockchip_mbox_writel(rk_mbox, MAILBOX_A2B_DAT(idx), msg->data);
+
+    return RT_EOK;
+}
+
+static const struct rt_mbox_controller_ops rockchip_mbox_ops =
+{
+    .request = rockchip_mbox_request,
+    .release = rockchip_mbox_release,
+    .send = rockchip_mbox_send,
+};
+
+static void rockchip_mbox_thread_isr(void *param)
+{
+    struct rockchip_mbox_msg *msg;
+    struct rockchip_mbox *rk_mbox = param;
+
+    while (RT_TRUE)
+    {
+        rt_thread_suspend(rk_mbox->irq_thread);
+        rt_schedule();
+
+        for (int idx = 0; idx < rk_mbox->parent.num_chans; ++idx)
+        {
+            msg = rk_mbox->chans[idx].msg;
+
+            if (!msg)
+            {
+                LOG_E("Chan[%d]: B2A message is NULL", idx);
+
+                break;
+            }
+
+            rt_mbox_recv(&rk_mbox->parent.chans[idx], msg);
+            rk_mbox->chans[idx].msg = RT_NULL;
+        }
+    }
+}
+
+static void rockchip_mbox_isr(int irqno, void *param)
+{
+    rt_uint32_t status;
+    struct rockchip_mbox_msg *msg;
+    struct rockchip_mbox *rk_mbox = param;
+
+    status = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_STATUS);
+
+    for (int idx = 0; idx < rk_mbox->parent.num_chans; ++idx)
+    {
+        if ((status & RT_BIT(idx)) && (irqno == rk_mbox->chans[idx].irq))
+        {
+            msg = rk_mbox->chans[idx].msg;
+            msg->cmd = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_CMD(idx));
+            msg->data = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_DAT(idx));
+
+            /* Clear mbox interrupt */
+            rockchip_mbox_writel(rk_mbox, MAILBOX_B2A_STATUS, RT_BIT(idx));
+
+            rt_thread_resume(rk_mbox->irq_thread);
+
+            break;
+        }
+    }
+}
+
+static rt_err_t rockchip_mbox_v2_request(struct rt_mbox_chan *chan)
+{
+    struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl);
+
+    /* Set the TX interrupt trigger method */
+    rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_int,
+            (1U << (BIT_WRITEABLE_SHIFT + MAILBOX_V2_TRIGGER_SHIFT) |
+                    rk_mbox->trigger_method << MAILBOX_V2_TRIGGER_SHIFT));
+
+    /* Enable the tx_done interrupt */
+    rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int,
+            (1U << BIT_WRITEABLE_SHIFT | MAILBOX_V2_INTEN_TX_DONE));
+
+    /* Enable the rx_done interrupt */
+    if (rk_mbox->txdone_irq)
+    {
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int,
+                (1U << (BIT_WRITEABLE_SHIFT + MAILBOX_V2_INTEN_RX_DONE_SHIFT) |
+                        MAILBOX_V2_INTEN_RX_DONE));
+    }
+
+    return RT_EOK;
+}
+
+static void rockchip_mbox_v2_release(struct rt_mbox_chan *chan)
+{
+    struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl);
+
+    /* Disable the tx_done interrupt */
+    rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int, 1U << BIT_WRITEABLE_SHIFT);
+
+    /* Disable the rx_done interrupt */
+    if (rk_mbox->txdone_irq)
+    {
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int,
+                1U << (BIT_WRITEABLE_SHIFT + MAILBOX_V2_INTEN_RX_DONE_SHIFT));
+    }
+}
+
+static rt_err_t rockchip_mbox_v2_send(struct rt_mbox_chan *chan, const void *data)
+{
+    struct rockchip_mbox_msg *msg = (void *)data;
+    struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl);
+
+    if (rockchip_mbox_readl(rk_mbox, rk_mbox->reg->tx_sts) & MAILBOX_V2_STATUS_TX_DONE)
+    {
+        LOG_E("The mailbox channel(%d) is busy", 0);
+
+        return -RT_EBUSY;
+    }
+
+    rk_mbox->chans[0].msg = msg;
+
+    if (rk_mbox->trigger_method)
+    {
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_cmd, msg->cmd);
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_dat, msg->data);
+    }
+    else
+    {
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_cmd, msg->cmd);
+    }
+
+    return RT_EOK;
+}
+
+static const struct rt_mbox_controller_ops rockchip_mbox_v2_ops =
+{
+    .request = rockchip_mbox_v2_request,
+    .release = rockchip_mbox_v2_release,
+    .send = rockchip_mbox_v2_send,
+};
+
+static void rockchip_mbox_v2_thread_isr(void *param)
+{
+    struct rockchip_mbox_msg *msg;
+    struct rockchip_mbox *rk_mbox = param;
+
+    while (RT_TRUE)
+    {
+        rt_thread_suspend(rk_mbox->irq_thread);
+        rt_schedule();
+
+        msg = rk_mbox->chans[0].msg;
+
+        if (!msg)
+        {
+            LOG_E("Chan[%d]: B2A message is NULL", 0);
+
+            continue;
+        }
+
+        rt_mbox_recv(&rk_mbox->parent.chans[0], msg);
+        rk_mbox->chans[0].msg = RT_NULL;
+    }
+}
+
+static void rockchip_mbox_v2_isr(int irqno, void *param)
+{
+    rt_uint32_t status;
+    struct rockchip_mbox_msg *msg;
+    struct rockchip_mbox *rk_mbox = param;
+
+    status = rockchip_mbox_readl(rk_mbox, rk_mbox->reg->rx_sts);
+
+    if (!(status & MAILBOX_V2_STATUS_MASK))
+    {
+        return;
+    }
+
+    if (status & MAILBOX_V2_STATUS_TX_DONE)
+    {
+        msg = rk_mbox->chans[0].msg;
+
+        /* Get cmd/data from the channel */
+        msg->cmd = rockchip_mbox_readl(rk_mbox, rk_mbox->reg->rx_cmd);
+        msg->data = rockchip_mbox_readl(rk_mbox, rk_mbox->reg->rx_dat);
+
+        /* Clear the tx_done interrupt */
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_sts, MAILBOX_V2_STATUS_TX_DONE);
+
+        rt_thread_resume(rk_mbox->irq_thread);
+    }
+
+    if (status & MAILBOX_V2_STATUS_RX_DONE)
+    {
+        if (rk_mbox->txdone_irq)
+        {
+            rt_mbox_send_done(&rk_mbox->parent.chans[0], 0);
+        }
+
+        /* Clear the rx_done interrupt */
+        rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_sts, MAILBOX_V2_STATUS_RX_DONE);
+    }
+}
+
+static void rockchip_mbox_free_resource(struct rockchip_mbox *rk_mbox)
+{
+    if (rk_mbox->regs)
+    {
+        rt_iounmap(rk_mbox->regs);
+    }
+
+    if (!rt_is_err_or_null(rk_mbox->pclk))
+    {
+        rt_clk_disable_unprepare(rk_mbox->pclk);
+        rt_clk_put(rk_mbox->pclk);
+    }
+
+    if (rk_mbox->irq_thread)
+    {
+        rt_thread_delete(rk_mbox->irq_thread);
+    }
+
+    rt_free(rk_mbox);
+}
+
+static rt_err_t rockchip_mbox_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    char chan_name[RT_NAME_MAX];
+    rt_uint64_t io_addr, io_size;
+    struct rockchip_mbox *rk_mbox;
+    struct rockchip_mbox_chan *chan;
+    struct rt_device *dev = &pdev->parent;
+    const struct rockchip_mbox_soc_data *soc_data = pdev->id->data;
+
+    rk_mbox = rt_calloc(1, sizeof(*rk_mbox) +
+            soc_data->num_chans * sizeof(struct rockchip_mbox_chan));
+
+    if (!rk_mbox)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if (rt_dm_dev_prop_read_bool(dev, "rockchip,tx-direction-b2a"))
+    {
+        rk_mbox->reg = &soc_data->reg_b2a;
+    }
+    else
+    {
+        rk_mbox->reg = &soc_data->reg_a2b;
+    }
+
+    if (rt_dm_dev_prop_read_bool(dev, "rockchip,txdone-ack"))
+    {
+        rk_mbox->txdone_irq = RT_FALSE;
+    }
+    else if (rt_dm_dev_prop_read_bool(dev, "rockchip,txdone-irq"))
+    {
+        rk_mbox->txdone_irq = RT_TRUE;
+    }
+
+    rk_mbox->trigger_method = !rt_dm_dev_prop_read_bool(dev, "rockchip,enable-cmd-trigger");
+
+    if ((err = rt_dm_dev_get_address(dev, 0, &io_addr, &io_size)))
+    {
+        goto _fail;
+    }
+
+    rk_mbox->regs = rt_ioremap((void *)io_addr, (size_t)io_size);
+
+    if (!rk_mbox->regs)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    rk_mbox->pclk = rt_clk_get_by_name(dev, "pclk_mailbox");
+
+    if (rt_is_err(rk_mbox->pclk))
+    {
+        err = rt_ptr_err(rk_mbox->pclk);
+
+        goto _fail;
+    }
+
+    if ((err = rt_clk_prepare_enable(rk_mbox->pclk)))
+    {
+        goto _fail;
+    }
+
+    rk_mbox->irq_thread = rt_thread_create("rk_mbox", soc_data->thread_isr,
+            rk_mbox, DM_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 2, 10);
+
+    if (!rk_mbox->irq_thread)
+    {
+        LOG_E("Create Mailbox IRQ thread fail");
+        goto _fail;
+    }
+
+    rt_thread_startup(rk_mbox->irq_thread);
+
+    chan = &rk_mbox->chans[0];
+
+    for (int i = 0; i < soc_data->num_chans; ++i, ++chan)
+    {
+        int irq = rt_dm_dev_get_irq(dev, i);
+
+        if (irq < 0)
+        {
+            err = irq;
+
+            goto _fail;
+        }
+
+        rt_snprintf(chan_name, sizeof(chan_name), "rk_mbox-%d", i);
+
+        rt_hw_interrupt_install(irq, soc_data->isr, rk_mbox, chan_name);
+        rt_hw_interrupt_umask(irq);
+
+        chan->idx = i;
+        chan->irq = irq;
+        chan->rk_mbox = rk_mbox;
+    }
+
+    rk_mbox->buf_size = io_size / (soc_data->num_chans * 2);
+
+    dev->user_data = rk_mbox;
+
+    rk_mbox->parent.dev = dev;
+    rk_mbox->parent.num_chans = soc_data->num_chans;
+    rk_mbox->parent.ops = soc_data->ops;
+
+    if ((err = rt_mbox_controller_register(&rk_mbox->parent)))
+    {
+        goto _fail;
+    }
+
+    return RT_EOK;
+
+_fail:
+    rockchip_mbox_free_resource(rk_mbox);
+
+    return err;
+}
+
+static rt_err_t rockchip_mbox_remove(struct rt_platform_device *pdev)
+{
+    struct rockchip_mbox_chan *chan;
+    struct rockchip_mbox *rk_mbox = pdev->parent.user_data;
+
+    chan = &rk_mbox->chans[0];
+
+    for (int i = 0; i < rk_mbox->parent.num_chans; ++i, ++chan)
+    {
+        rt_hw_interrupt_mask(chan->irq);
+        rt_pic_detach_irq(chan->irq, rk_mbox);
+    }
+
+    rt_mbox_controller_unregister(&rk_mbox->parent);
+
+    rockchip_mbox_free_resource(rk_mbox);
+
+    return RT_EOK;
+}
+
+static const struct rockchip_mbox_soc_data rk3368_data =
+{
+    .num_chans = 4,
+    .ops = &rockchip_mbox_ops,
+    .isr = rockchip_mbox_isr,
+    .thread_isr = rockchip_mbox_thread_isr,
+};
+
+static const struct rockchip_mbox_soc_data rk3576_data =
+{
+    .num_chans = 1,
+    .reg_a2b =
+    {
+        MAILBOX_V2_A2B_INTEN, MAILBOX_V2_A2B_STATUS,
+        MAILBOX_V2_A2B_CMD, MAILBOX_V2_A2B_DAT,
+        MAILBOX_V2_B2A_INTEN, MAILBOX_V2_B2A_STATUS,
+        MAILBOX_V2_B2A_CMD, MAILBOX_V2_B2A_DAT
+    },
+    .reg_b2a =
+    {
+        MAILBOX_V2_B2A_INTEN, MAILBOX_V2_B2A_STATUS,
+        MAILBOX_V2_B2A_CMD, MAILBOX_V2_B2A_DAT,
+        MAILBOX_V2_A2B_INTEN, MAILBOX_V2_A2B_STATUS,
+        MAILBOX_V2_A2B_CMD, MAILBOX_V2_A2B_DAT
+    },
+    .ops = &rockchip_mbox_v2_ops,
+    .isr = rockchip_mbox_v2_isr,
+    .thread_isr = rockchip_mbox_v2_thread_isr,
+};
+
+static const struct rt_ofw_node_id rockchip_mbox_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_data },
+    { .compatible = "rockchip,rk3576-mailbox", .data = &rk3576_data },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_mbox_driver =
+{
+    .name = "mailbox-rockchip",
+    .ids = rockchip_mbox_ofw_ids,
+
+    .probe = rockchip_mbox_probe,
+    .remove = rockchip_mbox_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rockchip_mbox_driver);

+ 19 - 0
bsp/rockchip/dm/mfd/Kconfig

@@ -0,0 +1,19 @@
+config RT_MFD_RK8XX
+    bool
+    depends on RT_USING_PIC
+
+config RT_MFD_RK8XX_I2C
+    bool "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip"
+    depends on RT_USING_OFW
+    depends on RT_USING_I2C
+    select RT_MFD_RK8XX
+    select RT_MFD_SYSCON
+    default n
+
+config RT_MFD_RK8XX_SPI
+    bool "Rockchip RK806 Power Management Chip"
+    depends on RT_USING_OFW
+    depends on RT_USING_SPI
+    select RT_MFD_RK8XX
+    select RT_MFD_SYSCON
+    default n

+ 18 - 0
bsp/rockchip/dm/mfd/SConscript

@@ -0,0 +1,18 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include']
+
+if GetDepend(['RT_MFD_RK8XX']):
+    src += ['rk8xx.c']
+
+    if GetDepend(['RT_MFD_RK8XX_I2C']):
+        src += ['rk8xx-i2c.c']
+
+    if GetDepend(['RT_MFD_RK8XX_SPI']):
+        src += ['rk8xx-spi.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [], CPPPATH = CPPPATH)
+
+Return('group')

+ 187 - 0
bsp/rockchip/dm/mfd/rk8xx-i2c.c

@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "mfd.rk8xx-i2c"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "rk8xx.h"
+
+struct rk8xx_i2c_soc_data
+{
+    int variant;
+};
+
+static rt_uint32_t rk8xx_i2c_read(struct rk8xx *rk8xx, rt_uint16_t reg)
+{
+    rt_uint8_t data = 0;
+    rt_uint8_t send_buf[2];
+    struct rt_i2c_msg msg[2];
+    struct rt_i2c_client *client = rk8xx_to_i2c_client(rk8xx);
+
+    send_buf[0] = (reg & 0xff);
+
+    msg[0].addr  = client->client_addr;
+    msg[0].flags = RT_I2C_WR;
+    msg[0].len   = 1;
+    msg[0].buf   = send_buf;
+
+    msg[1].addr  = client->client_addr;
+    msg[1].flags = RT_I2C_RD;
+    msg[1].len   = 1;
+    msg[1].buf   = &data;
+
+    if (rt_i2c_transfer(client->bus, msg, 2) == 2)
+    {
+        return data;
+    }
+    else
+    {
+        return (rt_uint32_t)-RT_ERROR;
+    }
+}
+
+static rt_err_t rk8xx_i2c_write(struct rk8xx *rk8xx, rt_uint16_t reg,
+        rt_uint8_t data)
+{
+    rt_uint8_t send_buf[2];
+    struct rt_i2c_msg msg;
+    struct rt_i2c_client *client = rk8xx_to_i2c_client(rk8xx);
+
+    send_buf[0] = reg & 0xff;
+    send_buf[1] = data;
+
+    msg.addr = client->client_addr;
+    msg.flags = RT_I2C_WR;
+    msg.len = 2;
+    msg.buf = send_buf;
+
+    if (rt_i2c_transfer(client->bus, &msg, 1) == 1)
+    {
+        return RT_EOK;
+    }
+    else
+    {
+        return -RT_ERROR;
+    }
+}
+
+static rt_err_t rk8xx_i2c_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg,
+        rt_uint8_t mask, rt_uint8_t data)
+{
+    rt_uint32_t old, tmp;
+
+    old = rk8xx_i2c_read(rk8xx, reg);
+
+    if (old < 0)
+    {
+        return old;
+    }
+
+    tmp = old & ~mask;
+    tmp |= (data & mask);
+
+    return rk8xx_i2c_write(rk8xx, reg, tmp);
+}
+
+static rt_err_t rk8xx_i2c_probe(struct rt_i2c_client *client)
+{
+    rt_err_t err;
+    const struct rk8xx_i2c_soc_data *soc_data;
+    struct rk8xx *rk8xx = rt_calloc(1, sizeof(*rk8xx));
+
+    if (!rk8xx)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk8xx->irq = rt_dm_dev_get_irq(&client->parent, 0);
+
+    if (rk8xx->irq < 0)
+    {
+        err = rk8xx->irq;
+        goto _fail;
+    }
+
+    soc_data = client->ofw_id->data;
+    client->parent.user_data = rk8xx;
+
+    rk8xx->variant = soc_data->variant;
+    rk8xx->dev = &client->parent;
+    rk8xx->read = rk8xx_i2c_read;
+    rk8xx->write = rk8xx_i2c_write;
+    rk8xx->update_bits = rk8xx_i2c_update_bits;
+
+    if ((err = rk8xx_probe(rk8xx)))
+    {
+        goto _fail;
+    }
+
+    return RT_EOK;
+
+_fail:
+    rt_free(rk8xx);
+
+    return err;
+}
+
+static rt_err_t rk8xx_i2c_shutdown(struct rt_i2c_client *client)
+{
+    struct rk8xx *rk8xx = client->parent.user_data;
+
+    return rk8xx_shutdown(rk8xx);
+}
+
+static const struct rk8xx_i2c_soc_data rk805_data =
+{
+    .variant = RK805_ID,
+};
+
+static const struct rk8xx_i2c_soc_data rk808_data =
+{
+    .variant = RK808_ID,
+};
+
+static const struct rk8xx_i2c_soc_data rk809_data =
+{
+    .variant = RK809_ID,
+};
+
+static const struct rk8xx_i2c_soc_data rk817_data =
+{
+    .variant = RK817_ID,
+};
+
+static const struct rk8xx_i2c_soc_data rk818_data =
+{
+    .variant = RK818_ID,
+};
+
+static const struct rt_ofw_node_id rk8xx_i2c_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk805", .data = &rk805_data },
+    { .compatible = "rockchip,rk808", .data = &rk808_data },
+    { .compatible = "rockchip,rk809", .data = &rk809_data },
+    { .compatible = "rockchip,rk817", .data = &rk817_data },
+    { .compatible = "rockchip,rk818", .data = &rk818_data },
+    { /* sentinel */ },
+};
+
+static struct rt_i2c_driver rk8xx_i2c_driver =
+{
+    .ofw_ids = rk8xx_i2c_ofw_ids,
+
+    .probe = rk8xx_i2c_probe,
+    .shutdown = rk8xx_i2c_shutdown,
+};
+RT_I2C_DRIVER_EXPORT(rk8xx_i2c_driver);

+ 148 - 0
bsp/rockchip/dm/mfd/rk8xx-spi.c

@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "mfd.rk8xx-spi"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "rk8xx.h"
+
+#define RK806_CMD_PACKAGE(CMD, LEN) \
+        (RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (LEN & RK806_CMD_LEN_MSK))
+
+/*
+ * Format of SPI commands (3 data packages: CMD, REG_L, REG_H)
+ *  CMD R/W[7]: R=0, W=1
+ *  CMD CRC_EN[6]: Enable=1, Disable=0
+ *  CMD Len[3:0]:
+ *      case 1: CRC_EN=1
+ *          The length of data written or read is noted in Len[3:0].
+ *          The host or slave computer transmits CRC data at the position of len+1.
+ *      case 2: CRC_EN=0
+ *          The data transmission takes no advantage of the length.
+ *          The addresses of registers of slave computer self-increase within the interval of 0~255.
+ *
+ *  REG_L[7:0]: The address of the target register is low-8 bit.
+ *  REG_H[15:8]: The address of the target register is high-8 bit.
+ */
+
+static rt_uint32_t rk8xx_spi_read(struct rk8xx *rk8xx, rt_uint16_t reg)
+{
+    rt_err_t err;
+    rt_uint8_t data = 0, package[3];
+    struct rt_spi_device *spi_dev = rk8xx_to_spi_device(rk8xx);
+
+    package[0] = RK806_CMD_PACKAGE(READ, sizeof(data));
+    package[1] = reg & 0xff;
+    package[2] = (reg >> 8) & 0xff;
+
+    err = rt_spi_send_then_recv(spi_dev, package, sizeof(package),
+            &data, sizeof(data));
+
+    return !err ? data : (rt_uint32_t)err;
+}
+
+static rt_err_t rk8xx_spi_write(struct rk8xx *rk8xx, rt_uint16_t reg,
+        rt_uint8_t data)
+{
+    rt_ssize_t res;
+    rt_uint8_t package[4];
+    struct rt_spi_device *spi_dev = rk8xx_to_spi_device(rk8xx);
+
+    package[0] = RK806_CMD_PACKAGE(WRITE, sizeof(data));
+    package[1] = reg & 0xff;
+    package[2] = (reg >> 8) & 0xff;
+    package[3] = data;
+
+    res = rt_spi_transfer(spi_dev, package, RT_NULL, sizeof(package));
+
+    return res > 0 ? RT_EOK : (res == 0 ? -RT_EIO : res);
+}
+
+static rt_err_t rk8xx_spi_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg,
+        rt_uint8_t mask, rt_uint8_t data)
+{
+    rt_uint32_t old, tmp;
+
+    old = rk8xx_spi_read(rk8xx, reg);
+
+    if ((rt_err_t)old < 0)
+    {
+        return old;
+    }
+
+    tmp = old & ~mask;
+    tmp |= (data & mask);
+
+    return rk8xx_spi_write(rk8xx, reg, tmp);
+}
+
+static rt_err_t rk8xx_spi_probe(struct rt_spi_device *spi_dev)
+{
+    rt_err_t err;
+    struct rk8xx *rk8xx = rt_calloc(1, sizeof(*rk8xx));
+
+    if (!rk8xx)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk8xx->irq = rt_dm_dev_get_irq(&spi_dev->parent, 0);
+
+    if (rk8xx->irq < 0)
+    {
+        err = rk8xx->irq;
+        goto _fail;
+    }
+
+    rk8xx->variant = RK806_ID;
+    rk8xx->dev = &spi_dev->parent;
+    rk8xx->read = rk8xx_spi_read;
+    rk8xx->write = rk8xx_spi_write;
+    rk8xx->update_bits = rk8xx_spi_update_bits;
+
+    if ((err = rk8xx_probe(rk8xx)))
+    {
+        goto _fail;
+    }
+
+    rt_dm_dev_set_name(&spi_dev->parent, "pmic");
+
+    return RT_EOK;
+
+_fail:
+    rt_free(rk8xx);
+
+    return err;
+}
+
+static const struct rt_spi_device_id rk8xx_spi_ids[] =
+{
+    { .name = "rk806" },
+    { /* sentinel */ },
+};
+
+static const struct rt_ofw_node_id rk8xx_spi_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk806" },
+    { /* sentinel */ },
+};
+
+static struct rt_spi_driver rk8xx_spi_driver =
+{
+    .ids = rk8xx_spi_ids,
+    .ofw_ids = rk8xx_spi_ofw_ids,
+
+    .probe = rk8xx_spi_probe,
+};
+RT_SPI_DRIVER_EXPORT(rk8xx_spi_driver);

+ 1088 - 0
bsp/rockchip/dm/mfd/rk8xx.c

@@ -0,0 +1,1088 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#define DBG_TAG "mfd.rk8xx"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "rk8xx.h"
+
+struct rk8xx_reg_data
+{
+    int addr;
+    int mask;
+    int value;
+};
+
+struct rk8xx_endpoint
+{
+    const char *name;
+    const char *ofw_name;
+    const char *ofw_compatible;
+
+    int irqs_nr;
+    const int *irqs_list;
+};
+
+struct rk8xx_irq_map
+{
+    rt_uint32_t reg_offset;
+    rt_uint32_t mask;
+};
+
+#define RK8XX_IRQ_REG(IRQ, OFF, MASK) \
+    [IRQ] = { .reg_offset = (OFF), .mask = (MASK) }
+
+#define RK8XX_IRQ_REG_LINE(ID, REG_BITS) \
+    [ID] = { .reg_offset = (ID) / (REG_BITS), .mask = RT_BIT((ID) % (REG_BITS)), }
+
+struct rk8xx_irqchip
+{
+    struct rt_pic parent;
+
+    struct rk8xx *rk8xx;
+
+#define RK8XX_IRQCHIP_NUM_REGS_MAX 3
+    int num_regs;
+    int reg_stride;
+    int mask_base;
+    int status_base;
+    int ack_base;
+
+    int irqs_nr;
+    const struct rk8xx_irq_map *irqs_map;
+
+    struct rt_thread *irq_thread;
+};
+
+#define raw_to_rk8xx_irqchip(raw) rt_container_of(raw, struct rk8xx_irqchip, parent)
+
+struct rk8xx_power
+{
+    struct rt_device parent;
+
+    struct rk8xx *rk8xx;
+};
+
+#define raw_to_rk8xx_power(raw) rt_container_of(raw, struct rk8xx_power, parent)
+
+static void rk8xx_irq_mask(struct rt_pic_irq *pirq)
+{
+    rt_uint16_t base;
+    struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pirq->pic);
+    const struct rk8xx_irq_map *irq_map = &rk8xx_ic->irqs_map[pirq->hwirq];
+
+    base = rk8xx_ic->mask_base + (irq_map->reg_offset / rk8xx_ic->reg_stride);
+
+    rk8xx_update_bits(rk8xx_ic->rk8xx, base, irq_map->mask, irq_map->mask);
+}
+
+static void rk8xx_irq_unmask(struct rt_pic_irq *pirq)
+{
+    rt_uint16_t base;
+    struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pirq->pic);
+    const struct rk8xx_irq_map *irq_map = &rk8xx_ic->irqs_map[pirq->hwirq];
+
+    base = rk8xx_ic->mask_base + (irq_map->reg_offset / rk8xx_ic->reg_stride);
+
+    rk8xx_update_bits(rk8xx_ic->rk8xx, base, irq_map->mask, 0);
+}
+
+static int rk8xx_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
+{
+    int irq = -1;
+    struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq);
+
+    if (pirq)
+    {
+        struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pic);
+
+        irq = rt_pic_config_irq(pic, hwirq, hwirq);
+        pirq->mode = mode;
+        rt_pic_cascade(pirq, rk8xx_ic->rk8xx->irq);
+    }
+
+    return irq;
+}
+
+static rt_err_t rk8xx_irq_parse(struct rt_pic *pic, struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq)
+{
+    struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pic);
+
+    if (args->args_count != 1)
+    {
+        return -RT_EINVAL;
+    }
+
+    out_pirq->mode = rt_pic_irq_get_triger_mode(rk8xx_ic->rk8xx->irq);
+    out_pirq->hwirq = args->args[0];
+
+    return RT_EOK;
+}
+
+const static struct rt_pic_ops rk8xx_irq_ops =
+{
+    .name = "RK8XX",
+    .irq_mask = rk8xx_irq_mask,
+    .irq_unmask = rk8xx_irq_unmask,
+    .irq_map = rk8xx_irq_map,
+    .irq_parse = rk8xx_irq_parse,
+};
+
+static void rk8xx_pmic_thread_isr(void *param)
+{
+    rt_uint32_t status[RK8XX_IRQCHIP_NUM_REGS_MAX];
+    rt_uint16_t base, reg;
+    struct rk8xx *rk8xx;
+    struct rt_pic_irq *pirq;
+    struct rk8xx_irqchip *rk8xx_ic = param;
+
+    rk8xx = rk8xx_ic->rk8xx;
+
+    while (RT_TRUE)
+    {
+        rt_thread_suspend(rk8xx_ic->irq_thread);
+        rt_schedule();
+
+        base = rk8xx_ic->status_base;
+        rt_memset(status, 0, sizeof(status));
+
+        for (int i = 0; i < rk8xx_ic->num_regs; ++i)
+        {
+            reg = base + i * rk8xx_ic->reg_stride;
+            status[i] = rk8xx_read(rk8xx, reg);
+
+            if ((rt_err_t)status[i] < 0)
+            {
+                LOG_E("Read IRQ status failed error = %s", rt_strerror(status[i]));
+
+                goto _end;
+            }
+        }
+
+        base = rk8xx_ic->ack_base;
+
+        for (int i = 0; i < rk8xx_ic->num_regs; ++i)
+        {
+            rt_err_t err;
+
+            reg = base + i * rk8xx_ic->reg_stride;
+            err = rk8xx_write(rk8xx, reg, status[i]);
+
+            if (err)
+            {
+                LOG_E("ACK IRQ failed error = %s", rt_strerror(err));
+
+                goto _end;
+            }
+        }
+
+        for (int i = 0; i < rk8xx_ic->irqs_nr; ++i)
+        {
+            base = rk8xx_ic->irqs_map[i].reg_offset / rk8xx_ic->reg_stride;
+
+            if (status[base] & rk8xx_ic->irqs_map[i].mask)
+            {
+                pirq = rt_pic_find_irq(&rk8xx_ic->parent, i);
+
+                if (pirq && pirq->pic)
+                {
+                    rt_pic_handle_isr(pirq);
+                }
+            }
+        }
+    _end:
+        rt_hw_interrupt_umask(rk8xx->irq);
+    }
+}
+
+static void rk8xx_pmic_isr(int irqno, void *param)
+{
+    struct rk8xx_irqchip *rk8xx_ic = param;
+
+    rt_hw_interrupt_mask(rk8xx_ic->rk8xx->irq);
+
+    rt_thread_resume(rk8xx_ic->irq_thread);
+}
+
+static const struct rk8xx_irq_map rk805_irqs[] =
+{
+    RK8XX_IRQ_REG(RK805_IRQ_PWRON_RISE, 0, RK805_IRQ_PWRON_RISE_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_VB_LOW, 0, RK805_IRQ_VB_LOW_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_PWRON, 0, RK805_IRQ_PWRON_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_PWRON_LP, 0, RK805_IRQ_PWRON_LP_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_HOTDIE, 0, RK805_IRQ_HOTDIE_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_RTC_ALARM, 0, RK805_IRQ_RTC_ALARM_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_RTC_PERIOD, 0, RK805_IRQ_RTC_PERIOD_MSK),
+    RK8XX_IRQ_REG(RK805_IRQ_PWRON_FALL, 0, RK805_IRQ_PWRON_FALL_MSK),
+};
+
+static const struct rk8xx_irq_map rk806_irqs[] =
+{
+    /* INT_STS0 IRQs */
+    RK8XX_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL),
+    RK8XX_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE),
+    RK8XX_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON),
+    RK8XX_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP),
+    RK8XX_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE),
+    RK8XX_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE),
+    RK8XX_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL),
+    RK8XX_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO),
+    /* INT_STS1 IRQs */
+    RK8XX_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0),
+    RK8XX_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1),
+    RK8XX_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2),
+    RK8XX_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR),
+    RK8XX_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO),
+    RK8XX_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO),
+    RK8XX_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO),
+    RK8XX_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT),
+};
+
+static const struct rk8xx_irq_map rk808_irqs[] =
+{
+    /* INT_STS */
+    RK8XX_IRQ_REG(RK808_IRQ_VOUT_LO, 0, RK808_IRQ_VOUT_LO_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_VB_LO, 0, RK808_IRQ_VB_LO_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_PWRON, 0, RK808_IRQ_PWRON_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_PWRON_LP, 0, RK808_IRQ_PWRON_LP_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_HOTDIE, 0, RK808_IRQ_HOTDIE_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_RTC_ALARM, 0, RK808_IRQ_RTC_ALARM_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_RTC_PERIOD, 0, RK808_IRQ_RTC_PERIOD_MSK),
+    /* INT_STS2 */
+    RK8XX_IRQ_REG(RK808_IRQ_PLUG_IN_INT, 1, RK808_IRQ_PLUG_IN_INT_MSK),
+    RK8XX_IRQ_REG(RK808_IRQ_PLUG_OUT_INT, 1, RK808_IRQ_PLUG_OUT_INT_MSK),
+};
+
+static const struct rk8xx_irq_map rk818_irqs[] =
+{
+    /* INT_STS */
+    RK8XX_IRQ_REG(RK818_IRQ_VOUT_LO, 0, RK818_IRQ_VOUT_LO_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_VB_LO, 0, RK818_IRQ_VB_LO_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_PWRON, 0, RK818_IRQ_PWRON_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_PWRON_LP, 0, RK818_IRQ_PWRON_LP_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_HOTDIE, 0, RK818_IRQ_HOTDIE_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_RTC_ALARM, 0, RK818_IRQ_RTC_ALARM_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_RTC_PERIOD, 0, RK818_IRQ_RTC_PERIOD_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_USB_OV, 0, RK818_IRQ_USB_OV_MSK),
+    /* INT_STS2 */
+    RK8XX_IRQ_REG(RK818_IRQ_PLUG_IN, 1, RK818_IRQ_PLUG_IN_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_PLUG_OUT, 1, RK818_IRQ_PLUG_OUT_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_CHG_OK, 1, RK818_IRQ_CHG_OK_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_CHG_TE, 1, RK818_IRQ_CHG_TE_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_CHG_TS1, 1, RK818_IRQ_CHG_TS1_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_TS2, 1, RK818_IRQ_TS2_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_CHG_CVTLIM, 1, RK818_IRQ_CHG_CVTLIM_MSK),
+    RK8XX_IRQ_REG(RK818_IRQ_DISCHG_ILIM, 1, RK818_IRQ_DISCHG_ILIM_MSK),
+};
+
+static const struct rk8xx_irq_map rk817_irqs[] =
+{
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_PWRON_FALL, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_PWRON_RISE, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_PWRON, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_PWMON_LP, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_HOTDIE, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_RTC_ALARM, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_RTC_PERIOD, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_VB_LO, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_PLUG_IN, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_PLUG_OUT, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_TERM, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_TIME, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_TS, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_USB_OV, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_IN_CLMP, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_BAT_DIS_ILIM, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_GATE_GPIO, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_TS_GPIO, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CODEC_PD, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CODEC_PO, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CLASSD_MUTE_DONE, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CLASSD_OCP, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_BAT_OVP, 8),
+    RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_BAT_HI, 8)
+};
+
+static const int rk808_rtc_irqs[] =
+{
+    RK808_IRQ_RTC_ALARM,
+};
+
+static const int rk817_rtc_irqs[] =
+{
+    RK817_IRQ_RTC_ALARM,
+};
+
+static const int rk805_pwrkey_irqs[] =
+{
+    RK805_IRQ_PWRON_RISE,
+    RK805_IRQ_PWRON_FALL,
+};
+
+static const int rk806_pwrkey_irqs[] =
+{
+    RK806_IRQ_PWRON_FALL,
+    RK806_IRQ_PWRON_RISE,
+};
+
+static const int rk817_pwrkey_irqs[] =
+{
+    RK817_IRQ_PWRON_RISE,
+    RK817_IRQ_PWRON_FALL,
+};
+
+static const int rk817_battery_irqs[] =
+{
+    RK817_IRQ_VB_LO,
+};
+
+static const int rk818_battery_irqs[] =
+{
+    RK818_IRQ_VB_LO,
+};
+
+static const int rk805_charger_irqs[] =
+{
+    RK805_IRQ_VB_LOW,
+};
+
+static const int rk817_charger_irqs[] =
+{
+    RK817_IRQ_PLUG_IN,
+    RK817_IRQ_PLUG_OUT,
+};
+
+static const int rk818_charger_irqs[] =
+{
+    RK818_IRQ_PLUG_IN,
+    RK818_IRQ_PLUG_OUT,
+};
+
+static const int rk817_codec_irqs[] =
+{
+    RK817_IRQ_CODEC_PD,
+    RK817_IRQ_CODEC_PO,
+};
+
+static const int rk806_watchdog_irqs[] =
+{
+    RK806_IRQ_WDT,
+};
+
+static const struct rk8xx_reg_data rk805_pre_init_regs[] =
+{
+    { RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK, RK805_BUCK1_2_ILMAX_4000MA },
+    { RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK, RK805_BUCK1_2_ILMAX_4000MA },
+    { RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK, RK805_BUCK3_ILMAX_3000MA },
+    { RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK, RK805_BUCK4_ILMAX_3500MA },
+    { RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA },
+    { RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C },
+};
+
+static const struct rk8xx_reg_data rk806_pre_init_regs[] =
+{
+    { RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L },
+    { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN },
+    { RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN },
+};
+
+static const struct rk8xx_reg_data rk808_pre_init_regs[] =
+{
+    { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
+    { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
+    { RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
+    { RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK, BUCK_ILMIN_200MA },
+    { RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_200MA },
+    { RK808_DCDC_UV_ACT_REG, BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
+    { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | VB_LO_SEL_3500MV },
+};
+
+static const struct rk8xx_reg_data rk817_pre_init_regs[] =
+{
+    {RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP},
+    /* Codec specific registers */
+    { RK817_CODEC_DTOP_VUCTL, MASK_ALL, 0x03 },
+    { RK817_CODEC_DTOP_VUCTIME, MASK_ALL, 0x00 },
+    { RK817_CODEC_DTOP_LPT_SRST, MASK_ALL, 0x00 },
+    { RK817_CODEC_DTOP_DIGEN_CLKE, MASK_ALL, 0x00 },
+    /* from vendor driver, CODEC_AREF_RTCFG0 not defined in data sheet */
+    { RK817_CODEC_AREF_RTCFG0, MASK_ALL, 0x00 },
+    { RK817_CODEC_AREF_RTCFG1, MASK_ALL, 0x06 },
+    { RK817_CODEC_AADC_CFG0, MASK_ALL, 0xc8 },
+    /* from vendor driver, CODEC_AADC_CFG1 not defined in data sheet */
+    { RK817_CODEC_AADC_CFG1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_VOLL, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_VOLR, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_SR_ACL0, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_ALC1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_ALC2, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_NG, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_HPF, MASK_ALL, 0x00 },
+    { RK817_CODEC_DADC_RVOLL, MASK_ALL, 0xff },
+    { RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
+    { RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
+    { RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
+    { RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
+    /* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
+    { RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
+    { RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
+    { RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
+    { RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
+    { RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
+    { RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff },
+    { RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 },
+    { RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 },
+    { RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 },
+    /* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */
+    { RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 },
+    { RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 },
+    { RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 },
+    { RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 },
+    { RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 },
+    { RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff },
+    { RK817_CODEC_DDAC_RVOLR, MASK_ALL, 0xff },
+    { RK817_CODEC_AHP_ANTI0, MASK_ALL, 0x00 },
+    { RK817_CODEC_AHP_ANTI1, MASK_ALL, 0x00 },
+    { RK817_CODEC_AHP_CFG0, MASK_ALL, 0xe0 },
+    { RK817_CODEC_AHP_CFG1, MASK_ALL, 0x1f },
+    { RK817_CODEC_AHP_CP, MASK_ALL, 0x09 },
+    { RK817_CODEC_ACLASSD_CFG1, MASK_ALL, 0x69 },
+    { RK817_CODEC_ACLASSD_CFG2, MASK_ALL, 0x44 },
+    { RK817_CODEC_APLL_CFG0, MASK_ALL, 0x04 },
+    { RK817_CODEC_APLL_CFG1, MASK_ALL, 0x00 },
+    { RK817_CODEC_APLL_CFG2, MASK_ALL, 0x30 },
+    { RK817_CODEC_APLL_CFG3, MASK_ALL, 0x19 },
+    { RK817_CODEC_APLL_CFG4, MASK_ALL, 0x65 },
+    { RK817_CODEC_APLL_CFG5, MASK_ALL, 0x01 },
+    { RK817_CODEC_DI2S_CKM, MASK_ALL, 0x01 },
+    { RK817_CODEC_DI2S_RSD, MASK_ALL, 0x00 },
+    { RK817_CODEC_DI2S_RXCR1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DI2S_RXCR2, MASK_ALL, 0x17 },
+    { RK817_CODEC_DI2S_RXCMD_TSD, MASK_ALL, 0x00 },
+    { RK817_CODEC_DI2S_TXCR1, MASK_ALL, 0x00 },
+    { RK817_CODEC_DI2S_TXCR2, MASK_ALL, 0x17 },
+    { RK817_CODEC_DI2S_TXCR3_TXCMD, MASK_ALL, 0x00 },
+    { RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L},
+    { RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK, RK817_HOTDIE_105 | RK817_TSD_140},
+};
+
+static const struct rk8xx_reg_data rk818_pre_init_regs[] = {
+    /* improve efficiency */
+    { RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_250MA },
+    { RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_250MA },
+    { RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
+    { RK818_USB_CTRL_REG, RK818_USB_ILIM_SEL_MASK, RK818_USB_ILMIN_2000MA },
+    /* close charger when usb lower then 3.4V */
+    { RK818_USB_CTRL_REG, RK818_USB_CHG_SD_VSEL_MASK, (0x7 << 4) },
+    /* no action when vref */
+    { RK818_H5V_EN_REG, RT_BIT(1), RK818_REF_RDY_CTRL },
+    /* enable HDMI 5V */
+    { RK818_H5V_EN_REG, RT_BIT(0), RK818_H5V_EN },
+    { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | VB_LO_SEL_3500MV },
+};
+
+static const struct rk8xx_endpoint rk805_eps[] =
+{
+    { .name = "rk8xx-clkout", },
+    { .name = "rk8xx-pinctrl", .ofw_name = "pinctrl_rk8xx" },
+    { .name = "rk8xx-regulator", .ofw_name = "regulators" },
+    {
+        .name = "rk8xx-rtc",
+        .irqs_nr = RT_ARRAY_SIZE(rk808_rtc_irqs),
+        .irqs_list = rk808_rtc_irqs,
+    },
+    {
+        .name = "rk8xx-pwrkey",
+        .ofw_name = "pwrkey",
+        .irqs_nr = RT_ARRAY_SIZE(rk805_pwrkey_irqs),
+        .irqs_list = rk805_pwrkey_irqs,
+    },
+    {
+        .name = "rk8xx-battery",
+        .ofw_name = "battery",
+        .irqs_nr = RT_ARRAY_SIZE(rk805_charger_irqs),
+        .irqs_list = rk805_charger_irqs,
+    },
+};
+
+static const struct rk8xx_endpoint rk806_eps[] =
+{
+    { .name = "rk8xx-pinctrl", .ofw_name = "pinctrl_rk806" },
+    { .name = "rk8xx-regulator", .ofw_name = "regulators" },
+    {
+        .name = "rk8xx-pwrkey",
+        .ofw_name = "pwrkey",
+        .irqs_nr = RT_ARRAY_SIZE(rk806_pwrkey_irqs),
+        .irqs_list = rk806_pwrkey_irqs,
+    },
+    {
+        .name = "rk8xx-watchdog",
+        .irqs_nr = RT_ARRAY_SIZE(rk806_watchdog_irqs),
+        .irqs_list = rk806_watchdog_irqs,
+    },
+};
+
+static const struct rk8xx_endpoint rk808_eps[] =
+{
+    { .name = "rk8xx-clkout", },
+    { .name = "rk8xx-regulator", .ofw_name = "regulators" },
+    {
+        .name = "rk8xx-rtc",
+        .irqs_nr = RT_ARRAY_SIZE(rk808_rtc_irqs),
+        .irqs_list = rk808_rtc_irqs,
+    },
+};
+
+static const struct rk8xx_endpoint rk817_eps[] =
+{
+    { .name = "rk8xx-clkout", },
+    { .name = "rk8xx-regulator", .ofw_name = "regulators" },
+    {
+        .name = "rk8xx-rtc",
+        .irqs_nr = RT_ARRAY_SIZE(rk817_rtc_irqs),
+        .irqs_list = rk817_rtc_irqs,
+    },
+    {
+        .name = "rk8xx-pwrkey",
+        .ofw_name = "pwrkey",
+        .irqs_nr = RT_ARRAY_SIZE(rk817_pwrkey_irqs),
+        .irqs_list = rk817_pwrkey_irqs,
+    },
+    {
+        .name = "rk8xx-battery",
+        .ofw_name = "battery",
+        .ofw_compatible = "rk817,battery",
+        .irqs_nr = RT_ARRAY_SIZE(rk817_battery_irqs),
+        .irqs_list = rk817_battery_irqs,
+    },
+    {
+        .name = "rk8xx-charger",
+        .ofw_name = "charger",
+        .ofw_compatible = "rk817,charger",
+        .irqs_nr = RT_ARRAY_SIZE(rk817_charger_irqs),
+        .irqs_list = rk817_charger_irqs,
+    },
+    {
+        .name = "rk8xx-codec",
+        .ofw_name = "codec",
+        .ofw_compatible = "rockchip,rk817-codec",
+        .irqs_nr = RT_ARRAY_SIZE(rk817_codec_irqs),
+        .irqs_list = rk817_codec_irqs,
+    },
+};
+
+static const struct rk8xx_endpoint rk818_eps[] =
+{
+    { .name = "rk8xx-clkout", },
+    { .name = "rk8xx-regulator", .ofw_name = "regulators" },
+    {
+        .name = "rk8xx-battery",
+        .ofw_name = "battery",
+        .ofw_compatible = "rk818-battery",
+        .irqs_nr = RT_ARRAY_SIZE(rk818_battery_irqs),
+        .irqs_list = rk818_battery_irqs,
+    },
+    {
+        .name = "rk8xx-charger",
+        .ofw_name = "charger",
+        .irqs_nr = RT_ARRAY_SIZE(rk818_charger_irqs),
+        .irqs_list = rk818_charger_irqs,
+    },
+    {
+        .name = "rk8xx-rtc",
+        .irqs_nr = RT_ARRAY_SIZE(rk808_rtc_irqs),
+        .irqs_list = rk808_rtc_irqs,
+    },
+};
+
+static rt_err_t rk8xx_power_off(struct rt_device *dev)
+{
+    rt_uint32_t reg, bit;
+    struct rk8xx_power *rk8xx_power = raw_to_rk8xx_power(dev);
+    struct rk8xx *rk8xx = rk8xx_power->rk8xx;
+
+    switch (rk8xx->variant)
+    {
+    case RK805_ID:
+        reg = RK805_DEV_CTRL_REG;
+        bit = DEV_OFF;
+        break;
+
+    case RK806_ID:
+        reg = RK806_SYS_CFG3;
+        bit = DEV_OFF;
+        break;
+
+    case RK808_ID:
+        reg = RK808_DEVCTRL_REG,
+        bit = DEV_OFF_RST;
+        break;
+
+    case RK809_ID:
+    case RK817_ID:
+        reg = RK817_SYS_CFG(3);
+        bit = DEV_OFF;
+        break;
+
+    case RK818_ID:
+        reg = RK818_DEVCTRL_REG;
+        bit = DEV_OFF;
+        break;
+
+    default:
+        return -RT_EEMPTY;
+    }
+
+    return rk8xx_update_bits(rk8xx, reg, bit, bit);
+}
+
+static rt_err_t rk8xx_restart(struct rt_device *dev)
+{
+    rt_uint32_t reg, bit;
+    struct rk8xx_power *rk8xx_power = raw_to_rk8xx_power(dev);
+    struct rk8xx *rk8xx = rk8xx_power->rk8xx;
+
+    switch (rk8xx->variant)
+    {
+    case RK806_ID:
+        reg = RK806_SYS_CFG3;
+        bit = DEV_RST;
+        break;
+
+    case RK809_ID:
+    case RK817_ID:
+        reg = RK817_SYS_CFG(3);
+        bit = DEV_RST;
+        break;
+
+    default:
+        return -RT_EEMPTY;
+    }
+
+    return rk8xx_update_bits(rk8xx, reg, bit, bit);
+}
+
+static rt_err_t create_rk8xx_platform_device(rt_bus_t platform_bus,
+        struct rk8xx *rk8xx,
+        const char *name,
+        void *ofw_node)
+{
+    rt_err_t err;
+    struct rt_platform_device *pdev = rt_platform_device_alloc(name);
+
+    if (!pdev)
+    {
+        return -RT_ENOMEM;
+    }
+
+    pdev->parent.ofw_node = ofw_node;
+    pdev->priv = rk8xx;
+
+    err = rt_bus_add_device(platform_bus, &pdev->parent);
+
+    if (err && err != -RT_ENOSYS)
+    {
+        LOG_E("Add RK8XX - %s error = %s", name, rt_strerror(err));
+    }
+
+    return err;
+}
+
+static rt_err_t rk8xx_ofw_bind_irq(struct rk8xx_irqchip *rk8xx_ic,
+        struct rt_ofw_node *dev_np,
+        struct rt_ofw_node *np,
+        const struct rk8xx_endpoint *ep)
+{
+    /*
+     *  ic: rk8xx-interrupt-controller {
+     *      #interrupt-cells = <1>;
+     *
+     *      rk8xx-endpoint0 {
+     *          interrupts-extended = <&ic 0>;
+     *      }
+     *
+     *      rk8xx-endpoint1 {
+     *          interrupts-extended = <&ic 1>, <&ic 2>;
+     *      }
+     *  }
+     */
+    rt_err_t err;
+    fdt32_t *values;
+    rt_size_t irq_list_size;
+    static fdt32_t irq_cell;
+    static struct rt_ofw_node *ic_np = RT_NULL;
+
+    if (!ic_np)
+    {
+        ic_np = rt_ofw_append_child(dev_np, "rk8xx-interrupt-controller");
+
+        if (!ic_np)
+        {
+            return -RT_ENOSYS;
+        }
+
+        irq_cell = cpu_to_fdt32(1);
+        err = rt_ofw_append_prop(ic_np, "#interrupt-cells", sizeof(fdt32_t), &irq_cell);
+
+        if (err)
+        {
+            return err;
+        }
+
+        rt_ofw_data(ic_np) = &rk8xx_ic->parent;
+    }
+
+    irq_list_size = sizeof(fdt32_t) * 2 * ep->irqs_nr;
+    values = rt_malloc(irq_list_size);
+
+    if (!values)
+    {
+        return -RT_ENOMEM;
+    }
+
+    for (int i = 0; i < ep->irqs_nr; ++i)
+    {
+        values[i * 2] = cpu_to_fdt32(ic_np->phandle);
+        values[i * 2 + 1] = cpu_to_fdt32(ep->irqs_list[i]);
+    }
+
+    if ((err = rt_ofw_append_prop(np, "interrupts-extended", irq_list_size, values)))
+    {
+        rt_free(values);
+    }
+
+    return err;
+}
+
+rt_err_t rk8xx_shutdown(struct rk8xx *rk8xx)
+{
+    rt_err_t err;
+
+    switch (rk8xx->variant)
+    {
+    case RK805_ID:
+        err = rk8xx_update_bits(rk8xx, RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SHUTDOWN_FUN);
+        break;
+
+    case RK809_ID:
+    case RK817_ID:
+        err = rk8xx_update_bits(rk8xx, RK817_SYS_CFG(3), RK817_SLPPIN_FUNC_MSK, SLPPIN_DN_FUN);
+        break;
+
+    default:
+        return RT_EOK;
+    }
+
+    if (err)
+    {
+        LOG_W("Cannot switch to power down function");
+    }
+
+    return err;
+}
+
+rt_err_t rk8xx_probe(struct rk8xx *rk8xx)
+{
+    rt_err_t err;
+    rt_bool_t iomux_retry;
+    rt_bus_t platform_bus;
+    int rk8xx_ep_nr, pre_init_regs_nr;
+    struct rt_ofw_node *np, *dev_np;
+    struct rk8xx_irqchip *rk8xx_ic;
+    const struct rk8xx_endpoint *rk8xx_ep;
+    const struct rk8xx_reg_data *pre_init_regs;
+
+    if (!rk8xx)
+    {
+        return -RT_EINVAL;
+    }
+
+    platform_bus = rt_bus_find_by_name("platform");
+
+    if (!platform_bus)
+    {
+        return -RT_EIO;
+    }
+
+    dev_np = rk8xx->dev->ofw_node;
+
+    rk8xx_ic = rt_calloc(1, sizeof(*rk8xx_ic));
+
+    if (!rk8xx_ic)
+    {
+        return -RT_ENOMEM;
+    }
+
+    switch (rk8xx->variant)
+    {
+    case RK805_ID:
+        rk8xx_ic->num_regs = 1;
+        rk8xx_ic->status_base = RK805_INT_STS_REG;
+        rk8xx_ic->mask_base = RK805_INT_STS_MSK_REG;
+        rk8xx_ic->ack_base = RK805_INT_STS_REG;
+        rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk805_irqs);
+        rk8xx_ic->irqs_map = rk805_irqs;
+
+        rk8xx_ep = rk805_eps;
+        rk8xx_ep_nr = RT_ARRAY_SIZE(rk805_eps);
+
+        pre_init_regs = rk805_pre_init_regs;
+        pre_init_regs_nr = RT_ARRAY_SIZE(rk805_pre_init_regs);
+        break;
+
+    case RK806_ID:
+        rk8xx_ic->num_regs = 2;
+        rk8xx_ic->reg_stride = 2;
+        rk8xx_ic->mask_base = RK806_INT_MSK0;
+        rk8xx_ic->status_base = RK806_INT_STS0;
+        rk8xx_ic->ack_base = RK806_INT_STS0;
+        rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk806_irqs);
+        rk8xx_ic->irqs_map = rk806_irqs;
+
+        rk8xx_ep = rk806_eps;
+        rk8xx_ep_nr = RT_ARRAY_SIZE(rk806_eps);
+
+        pre_init_regs = rk806_pre_init_regs;
+        pre_init_regs_nr = RT_ARRAY_SIZE(rk806_pre_init_regs);
+        break;
+
+    case RK808_ID:
+        rk8xx_ic->num_regs = 2;
+        rk8xx_ic->reg_stride = 2;
+        rk8xx_ic->status_base = RK808_INT_STS_REG1;
+        rk8xx_ic->mask_base = RK808_INT_STS_MSK_REG1;
+        rk8xx_ic->ack_base = RK808_INT_STS_REG1;
+        rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk808_irqs);
+        rk8xx_ic->irqs_map = rk808_irqs;
+
+        rk8xx_ep = rk808_eps;
+        rk8xx_ep_nr = RT_ARRAY_SIZE(rk808_eps);
+
+        pre_init_regs = rk808_pre_init_regs;
+        pre_init_regs_nr = RT_ARRAY_SIZE(rk808_pre_init_regs);
+        break;
+
+    case RK809_ID:
+    case RK817_ID:
+        rk8xx_ic->num_regs = 3;
+        rk8xx_ic->reg_stride = 2;
+        rk8xx_ic->status_base = RK817_INT_STS_REG0;
+        rk8xx_ic->mask_base = RK817_INT_STS_MSK_REG0;
+        rk8xx_ic->ack_base = RK817_INT_STS_REG0;
+        rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk817_irqs);
+        rk8xx_ic->irqs_map = rk817_irqs;
+
+        rk8xx_ep = rk817_eps;
+        rk8xx_ep_nr = RT_ARRAY_SIZE(rk817_eps);
+
+        pre_init_regs = rk817_pre_init_regs;
+        pre_init_regs_nr = RT_ARRAY_SIZE(rk817_pre_init_regs);
+        break;
+
+    case RK818_ID:
+        rk8xx_ic->num_regs = 2;
+        rk8xx_ic->reg_stride = 2;
+        rk8xx_ic->status_base = RK818_INT_STS_REG1;
+        rk8xx_ic->mask_base = RK818_INT_STS_MSK_REG1;
+        rk8xx_ic->ack_base = RK818_INT_STS_REG1;
+        rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk818_irqs);
+        rk8xx_ic->irqs_map = rk818_irqs;
+
+        rk8xx_ep = rk818_eps;
+        rk8xx_ep_nr = RT_ARRAY_SIZE(rk818_eps);
+
+        pre_init_regs = rk818_pre_init_regs;
+        pre_init_regs_nr = RT_ARRAY_SIZE(rk818_pre_init_regs);
+        break;
+
+    default:
+        LOG_E("Unsupported RK8XX ID %u", rk8xx->variant);
+        return -RT_EINVAL;
+    }
+
+    RT_ASSERT(rk8xx_ic->num_regs <= RK8XX_IRQCHIP_NUM_REGS_MAX);
+
+    rk8xx_ic->rk8xx = rk8xx;
+    rk8xx_ic->parent.priv_data = rk8xx_ic;
+    rk8xx_ic->parent.ops = &rk8xx_irq_ops;
+
+    err = rt_pic_linear_irq(&rk8xx_ic->parent, rk8xx_ic->irqs_nr);
+
+    if (err)
+    {
+        LOG_E("Init RK8XX IRQ chip failed error = %s", rt_strerror(err));
+
+        return err;
+    }
+
+    rt_pic_user_extends(&rk8xx_ic->parent);
+
+    /* Clear all interrupts */
+    for (int i = 0; i < rk8xx_ic->num_regs; ++i)
+    {
+        rk8xx_write(rk8xx, rk8xx_ic->ack_base + i * rk8xx_ic->reg_stride, 0xff);
+    }
+
+    for (int i = 0; i < pre_init_regs_nr; ++i)
+    {
+        err = rk8xx_update_bits(rk8xx, pre_init_regs[i].addr,
+                pre_init_regs[i].mask, pre_init_regs[i].value);
+
+        if (err)
+        {
+            LOG_E("Write to %x fail", pre_init_regs[i].addr);
+            goto _fail;
+        }
+    }
+
+    rt_pic_user_extends(&rk8xx_ic->parent);
+
+    iomux_retry = rt_pin_ctrl_confs_apply_by_name(rk8xx->dev, RT_NULL) < 0;
+
+    if (rt_ofw_prop_read_bool(dev_np, "rockchip,system-power-controller"))
+    {
+        struct rt_device *dev;
+        struct rk8xx_power *rk8xx_power = rt_calloc(1, sizeof(*rk8xx_power));
+
+        if (!rk8xx_power)
+        {
+            err = -RT_ENOMEM;
+            goto _fail;
+        }
+
+        dev = &rk8xx_power->parent;
+        rt_dm_dev_set_name(dev, "rk-sys-pm");
+        rk8xx_power->rk8xx = rk8xx;
+
+        err = rt_dm_power_off_handler(dev, RT_DM_POWER_OFF_MODE_SHUTDOWN,
+                RT_DM_POWER_OFF_PRIO_PLATFORM, &rk8xx_power_off);
+
+        if (err)
+        {
+            LOG_E("Add %s failed", "shutdown");
+        }
+
+        err = rt_dm_power_off_handler(dev, RT_DM_POWER_OFF_MODE_RESET,
+                RT_DM_POWER_OFF_PRIO_PLATFORM, &rk8xx_restart);
+
+        if (err)
+        {
+            LOG_E("Add %s failed", "reset");
+        }
+    }
+
+    for (int i = 0; i < rk8xx_ep_nr; ++i, ++rk8xx_ep)
+    {
+        np = RT_NULL;
+
+        if (rk8xx_ep->ofw_name)
+        {
+            if (!(np = rt_ofw_get_child_by_tag(dev_np, rk8xx_ep->ofw_name)))
+            {
+                if (rk8xx_ep->ofw_compatible)
+                {
+                    np = rt_ofw_get_child_by_compatible(dev_np, rk8xx_ep->ofw_compatible);
+                }
+
+                if (!np)
+                {
+                    LOG_D("%s not found", rk8xx_ep->ofw_name);
+
+                    continue;
+                }
+            }
+
+            if (!rt_ofw_node_is_available(np))
+            {
+                continue;
+            }
+        }
+
+        if (rk8xx_ep->irqs_nr)
+        {
+            if (!np && !(np = rt_ofw_append_child(dev_np, rk8xx_ep->name)))
+            {
+                continue;
+            }
+
+            err = rk8xx_ofw_bind_irq(rk8xx_ic, dev_np, np, rk8xx_ep);
+
+            if (err == -RT_ENOMEM)
+            {
+                goto _out_put;
+            }
+        }
+
+        if (!rt_strcmp(rk8xx_ep->name, "rk8xx-clkout"))
+        {
+            np = rt_ofw_node_get(dev_np);
+        }
+
+        err = create_rk8xx_platform_device(platform_bus, rk8xx, rk8xx_ep->name, np);
+
+    _out_put:
+        rt_ofw_node_put(np);
+
+        if (err == -RT_ENOMEM)
+        {
+            goto _fail;
+        }
+    }
+
+    if (iomux_retry)
+    {
+        if ((err = rt_pin_ctrl_confs_apply_by_name(rk8xx->dev, RT_NULL)))
+        {
+            LOG_W("Pinctrl apply error = %s", rt_strerror(err));
+        }
+    }
+
+    rk8xx_ic->irq_thread = rt_thread_create("rk8xx-pmic", &rk8xx_pmic_thread_isr,
+            rk8xx_ic, DM_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 2, 10);
+
+    if (!rk8xx_ic->irq_thread)
+    {
+        goto _not_irq_conf;
+    }
+
+    rt_thread_startup(rk8xx_ic->irq_thread);
+
+    rt_hw_interrupt_install(rk8xx->irq, &rk8xx_pmic_isr, rk8xx_ic, "rk8xx-pmic");
+    rt_hw_interrupt_umask(rk8xx->irq);
+
+_not_irq_conf:
+    return RT_EOK;
+
+_fail:
+    rt_pic_cancel_irq(&rk8xx_ic->parent);
+
+    return err;
+}

+ 3 - 0
bsp/rockchip/dm/nvmem/Kconfig

@@ -0,0 +1,3 @@
+config RT_NVMEM_ROCKCHIP_OTP
+    bool "Rockchip OTP controller support"
+    default n

+ 12 - 0
bsp/rockchip/dm/nvmem/SConscript

@@ -0,0 +1,12 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = []
+CPPPATH = [cwd + '/../include']
+
+if GetDepend(['RT_NVMEM_ROCKCHIP_OTP']):
+    src += ['nvmem-rockchip-otp.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 1037 - 0
bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c

@@ -0,0 +1,1037 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-02-25     GuEe-GUI     the first version
+ */
+
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <bitmap.h>
+
+#define DBG_TAG "nvmem.rockchip.otp"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+/* OTP Register Offsets */
+#define OTPC_SBPI_CTRL                  0x0020
+#define OTPC_SBPI_CMD_VALID_PRE         0x0024
+#define OTPC_SBPI_CS_VALID_PRE          0x0028
+#define OTPC_SBPI_STATUS                0x002C
+#define OTPC_USER_CTRL                  0x0100
+#define OTPC_USER_ADDR                  0x0104
+#define OTPC_USER_ENABLE                0x0108
+#define OTPC_USER_QP                    0x0120
+#define OTPC_USER_Q                     0x0124
+#define OTPC_INT_STATUS                 0x0304
+#define OTPC_SBPI_CMD0_OFFSET           0x1000
+#define OTPC_SBPI_CMD1_OFFSET           0x1004
+
+#define OTPC_MODE_CTRL                  0x2000
+#define OTPC_IRQ_ST                     0x2008
+#define OTPC_ACCESS_ADDR                0x200c
+#define OTPC_RD_DATA                    0x2010
+#define OTPC_REPR_RD_TRANS_NUM          0x2020
+
+#define OTPC_DEEP_STANDBY               0x0
+#define OTPC_STANDBY                    0x1
+#define OTPC_ACTIVE                     0x2
+#define OTPC_READ_ACCESS                0x3
+#define OTPC_TRANS_NUM                  0x1
+#define OTPC_RDM_IRQ_ST                 RT_BIT(0)
+#define OTPC_STB2ACT_IRQ_ST             RT_BIT(7)
+#define OTPC_DP2STB_IRQ_ST              RT_BIT(8)
+#define OTPC_ACT2STB_IRQ_ST             RT_BIT(9)
+#define OTPC_STB2DP_IRQ_ST              RT_BIT(10)
+#define PX30S_NBYTES                    4
+#define PX30S_NO_SECURE_OFFSET          224
+
+/* OTP Register bits and masks */
+#define OTPC_USER_ADDR_MASK             RT_GENMASK(31, 16)
+#define OTPC_USE_USER                   RT_BIT(0)
+#define OTPC_USE_USER_MASK              RT_GENMASK(16, 16)
+#define OTPC_USER_FSM_ENABLE            RT_BIT(0)
+#define OTPC_USER_FSM_ENABLE_MASK       RT_GENMASK(16, 16)
+#define OTPC_LOCK                       RT_BIT(0)
+#define OTPC_LOCK_MASK                  RT_GENMASK(16, 16)
+#define OTPC_SBPI_DONE                  RT_BIT(1)
+#define OTPC_USER_DONE                  RT_BIT(2)
+
+#define SBPI_DAP_ADDR                   0x02
+#define SBPI_DAP_ADDR_SHIFT             8
+#define SBPI_DAP_ADDR_MASK              RT_GENMASK(31, 24)
+#define SBPI_CMD_VALID_MASK             RT_GENMASK(31, 16)
+#define SBPI_DAP_CMD_WRF                0xc0
+#define SBPI_DAP_REG_ECC                0x3a
+#define SBPI_ECC_ENABLE                 0x00
+#define SBPI_ECC_DISABLE                0x09
+#define SBPI_ENABLE                     RT_BIT(0)
+#define SBPI_ENABLE_MASK                RT_GENMASK(16, 16)
+
+#define OTPC_TIMEOUT                    10000
+#define OTPC_TIMEOUT_PROG               100000
+#define RK3568_NBYTES                   2
+
+#define RK3576_NO_SECURE_OFFSET         0x1c0
+
+#define RK3588_OTPC_AUTO_CTRL           0x04
+#define RK3588_OTPC_AUTO_EN             0x08
+#define RK3588_OTPC_INT_ST              0x84
+#define RK3588_OTPC_DOUT0               0x20
+#define RK3588_NO_SECURE_OFFSET         0x300
+#define RK3588_NBYTES                   4
+#define RK3588_BURST_NUM                1
+#define RK3588_BURST_SHIFT              8
+#define RK3588_ADDR_SHIFT               16
+#define RK3588_AUTO_EN                  RT_BIT(0)
+#define RK3588_RD_DONE                  RT_BIT(1)
+
+#define RV1126_OTP_NVM_CEB              0x00
+#define RV1126_OTP_NVM_RSTB             0x04
+#define RV1126_OTP_NVM_ST               0x18
+#define RV1126_OTP_NVM_RADDR            0x1c
+#define RV1126_OTP_NVM_RSTART           0x20
+#define RV1126_OTP_NVM_RDATA            0x24
+#define RV1126_OTP_NVM_TRWH             0x28
+#define RV1126_OTP_READ_ST              0x30
+#define RV1126_OTP_NVM_PRADDR           0x34
+#define RV1126_OTP_NVM_PRLEN            0x38
+#define RV1126_OTP_NVM_PRDATA           0x3c
+#define RV1126_OTP_NVM_FAILTIME         0x40
+#define RV1126_OTP_NVM_PRSTART          0x44
+#define RV1126_OTP_NVM_PRSTATE          0x48
+
+/*
+ * +----------+------------------+--------------------------+
+ * | TYPE     | RANGE(byte)      | NOTE                     |
+ * +----------+------------------+--------------------------+
+ * | system   | 0x000 ~ 0x0ff    | system info, read only   |
+ * +----------+------------------+--------------------------+
+ * | oem      | 0x100 ~ 0x1ef    | for customized           |
+ * +----------+------------------+--------------------------+
+ * | reserved | 0x1f0 ~ 0x1f7    | future extension         |
+ * +----------+------------------+--------------------------+
+ * | wp       | 0x1f8 ~ 0x1ff    | write protection for oem |
+ * +----------+------------------+--------------------------+
+ *
+ * +-----+    +------------------+
+ * | wp  | -- | wp for oem range |
+ * +-----+    +------------------+
+ * | 1f8 |    | 0x100 ~ 0x11f    |
+ * +-----+    +------------------+
+ * | 1f9 |    | 0x120 ~ 0x13f    |
+ * +-----+    +------------------+
+ * | 1fa |    | 0x140 ~ 0x15f    |
+ * +-----+    +------------------+
+ * | 1fb |    | 0x160 ~ 0x17f    |
+ * +-----+    +------------------+
+ * | 1fc |    | 0x180 ~ 0x19f    |
+ * +-----+    +------------------+
+ * | 1fd |    | 0x1a0 ~ 0x1bf    |
+ * +-----+    +------------------+
+ * | 1fe |    | 0x1c0 ~ 0x1df    |
+ * +-----+    +------------------+
+ * | 1ff |    | 0x1e0 ~ 0x1ef    |
+ * +-----+    +------------------+
+ */
+#define RV1126_OTP_OEM_OFFSET           0x100
+#define RV1126_OTP_OEM_SIZE             0xf0
+#define RV1126_OTP_WP_OFFSET            0x1f8
+#define RV1126_OTP_WP_SIZE              0x8
+
+/* each bit mask 32 bits in OTP NVM */
+#define ROCKCHIP_OTP_WP_MASK_NBITS      64
+
+#define OFFSET_IS_ALIGNED(x, a)         (((x) & ((typeof(x))(a) - 1)) == 0)
+
+struct rockchip_otp;
+
+struct rockchip_otp_data
+{
+    int size;
+    int ns_offset;
+
+    rt_ssize_t (*read)(struct rockchip_otp *, int offset, void *buf, rt_size_t bytes);
+    rt_ssize_t (*write)(struct rockchip_otp *, int offset, void *buf, rt_size_t bytes);
+    rt_err_t (*init)(struct rockchip_otp *);
+};
+
+struct rockchip_otp
+{
+    struct rt_nvmem_device parent;
+    void *regs;
+
+    rt_bool_t was_written;
+    struct rt_clk_array *clk_arr;
+    struct rt_reset_control *rstc;
+    const struct rockchip_otp_data *soc_data;
+
+    struct rt_mutex mutex;
+    RT_BITMAP_DECLARE(wp_mask, ROCKCHIP_OTP_WP_MASK_NBITS);
+};
+
+#define raw_to_rockchip_otp(raw) rt_container_of(raw, struct rockchip_otp, parent)
+
+#define readl_poll_timeout(ADDR, VAL, COND, DELAY_US, TIMEOUT_US) \
+({                                                      \
+    rt_uint64_t timeout_us = (TIMEOUT_US);              \
+    rt_int64_t left_ns = timeout_us * 1000L;            \
+    rt_ubase_t delay_us = (DELAY_US);                   \
+    rt_uint64_t delay_ns = delay_us * 1000L;            \
+    for (;;)                                            \
+    {                                                   \
+        (VAL) = HWREG32(ADDR);                          \
+        if (COND)                                       \
+        {                                               \
+            break;                                      \
+        }                                               \
+        if (timeout_us && left_ns < 0)                  \
+        {                                               \
+            (VAL) = HWREG32(ADDR);                      \
+            break;                                      \
+        }                                               \
+        if (delay_us)                                   \
+        {                                               \
+            rt_hw_us_delay(delay_us);                   \
+            if (timeout_us)                             \
+            {                                           \
+                left_ns -= delay_ns;                    \
+            }                                           \
+        }                                               \
+        rt_hw_cpu_relax();                              \
+        if (timeout_us)                                 \
+        {                                               \
+            --left_ns;                                  \
+        }                                               \
+    }                                                   \
+    (COND) ? RT_EOK : -RT_ETIMEOUT;                     \
+})
+
+static rt_err_t rockchip_otp_reset(struct rockchip_otp *rk_otp)
+{
+    rt_err_t err;
+
+    if ((err = rt_reset_control_assert(rk_otp->rstc)))
+    {
+        LOG_E("Failed to assert otp phy error = %s", rt_strerror(err));
+        return err;
+    }
+
+    rt_hw_us_delay(2);
+
+    if ((err = rt_reset_control_deassert(rk_otp->rstc)))
+    {
+        LOG_E("Failed to deassert otp phy error = %s", rt_strerror(err));
+        return err;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t px30_otp_wait_status(struct rockchip_otp *rk_otp, rt_uint32_t flag)
+{
+    rt_err_t err;
+    rt_uint32_t status = 0;
+
+    err = readl_poll_timeout(rk_otp->regs + OTPC_INT_STATUS, status,
+            (status & flag), 1, OTPC_TIMEOUT);
+
+    if (err)
+    {
+        return err;
+    }
+
+    /* Clean int status */
+    HWREG32(rk_otp->regs + OTPC_INT_STATUS) = flag;
+
+    return RT_EOK;
+}
+
+static rt_err_t px30_otp_ecc_enable(struct rockchip_otp *rk_otp, rt_bool_t enable)
+{
+    rt_err_t err;
+
+    HWREG32(rk_otp->regs + OTPC_SBPI_CTRL) = SBPI_DAP_ADDR_MASK |
+            (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT);
+    HWREG32(rk_otp->regs + OTPC_SBPI_CMD_VALID_PRE) = SBPI_CMD_VALID_MASK | 0x1;
+    HWREG32(rk_otp->regs + OTPC_SBPI_CMD0_OFFSET) =
+            SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC;
+
+    HWREG32(rk_otp->regs + OTPC_SBPI_CMD1_OFFSET) =
+            enable ? SBPI_ECC_ENABLE : SBPI_ECC_DISABLE;
+    HWREG32(rk_otp->regs + OTPC_SBPI_CTRL) = SBPI_ENABLE_MASK | SBPI_ENABLE;
+
+    if ((err = px30_otp_wait_status(rk_otp, OTPC_SBPI_DONE)) < 0)
+    {
+        LOG_E("Timeout during ecc_enable");
+    }
+
+    return err;
+}
+
+static rt_ssize_t px30_otp_read(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res;
+    rt_uint8_t *buf = val;
+
+    if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0)
+    {
+        LOG_E("Failed to prepare/enable clks");
+
+        return res;
+    }
+
+    if ((res = rockchip_otp_reset(rk_otp)))
+    {
+        LOG_E("Failed to reset otp phy");
+
+        goto _disable_clks;
+    }
+
+    if ((res = px30_otp_ecc_enable(rk_otp, RT_FALSE)) < 0)
+    {
+        LOG_E("Enable ECC error = %s", rt_strerror(res));
+
+        goto _disable_clks;
+    }
+
+    HWREG32(rk_otp->regs + OTPC_USER_CTRL) = OTPC_USE_USER | OTPC_USE_USER_MASK;
+    rt_hw_us_delay(5);
+
+    for (int i = 0; i < bytes; ++i)
+    {
+        HWREG32(rk_otp->regs + OTPC_USER_ADDR) = offset++ | OTPC_USER_ADDR_MASK;
+        HWREG32(rk_otp->regs + OTPC_USER_ENABLE) =
+                OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK;
+
+        if ((res = px30_otp_wait_status(rk_otp, OTPC_USER_DONE)) < 0)
+        {
+            LOG_E("Timeout during read setup");
+
+            goto _read_end;
+        }
+
+        *buf++ = HWREG8(rk_otp->regs + OTPC_USER_Q);
+    }
+
+_read_end:
+    HWREG32(rk_otp->regs + OTPC_USER_CTRL) = 0x0 | OTPC_USE_USER_MASK;
+
+_disable_clks:
+    rt_clk_array_disable_unprepare(rk_otp->clk_arr);
+
+    return bytes;
+}
+
+static rt_err_t px30s_otp_wait_status(struct rockchip_otp *rk_otp, rt_uint32_t flag)
+{
+    rt_err_t err;
+    rt_uint32_t status = 0;
+
+    err = readl_poll_timeout(rk_otp->regs + OTPC_IRQ_ST, status,
+            (status & flag), 1, OTPC_TIMEOUT);
+
+    if (err)
+    {
+        return err;
+    }
+
+    /* clean int status */
+    HWREG32(rk_otp->regs + OTPC_IRQ_ST) = flag;
+
+    return RT_EOK;
+}
+
+static rt_err_t px30s_otp_active(struct rockchip_otp *rk_otp)
+{
+    rt_uint32_t mode;
+    rt_err_t err = RT_EOK;
+
+    mode = HWREG32(rk_otp->regs + OTPC_MODE_CTRL);
+
+    switch (mode)
+    {
+    case OTPC_DEEP_STANDBY:
+        HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_STANDBY;
+
+        if ((err = px30s_otp_wait_status(rk_otp, OTPC_DP2STB_IRQ_ST)) < 0)
+        {
+            LOG_E("Timeout during wait dp2stb");
+
+            return err;
+        }
+
+    /* Fallthrough */
+    case OTPC_STANDBY:
+        HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_ACTIVE;
+
+        if ((err = px30s_otp_wait_status(rk_otp, OTPC_STB2ACT_IRQ_ST)) < 0)
+        {
+            LOG_E("Timeout during wait stb2act");
+
+            return err;
+        }
+
+        break;
+
+    default:
+        break;
+    }
+
+    return err;
+}
+
+static rt_err_t px30s_otp_standby(struct rockchip_otp *rk_otp)
+{
+    rt_uint32_t mode;
+    rt_err_t err = RT_EOK;
+
+    mode = HWREG32(rk_otp->regs + OTPC_MODE_CTRL);
+
+    switch (mode)
+    {
+    case OTPC_ACTIVE:
+        HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_STANDBY;
+
+        if ((err = px30s_otp_wait_status(rk_otp, OTPC_ACT2STB_IRQ_ST)) < 0)
+        {
+            LOG_E("Timeout during wait act2stb");
+
+            return err;
+        }
+
+    /* Fallthrough */
+    case OTPC_STANDBY:
+        HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_DEEP_STANDBY;
+
+        if ((err = px30s_otp_wait_status(rk_otp, OTPC_STB2DP_IRQ_ST)) < 0)
+        {
+            LOG_E("Timeout during wait stb2dp");
+
+            return err;
+        }
+
+        break;
+
+    default:
+        break;
+    }
+
+    return err;
+}
+
+static rt_ssize_t px30s_otp_read(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res;
+    rt_uint8_t *buf;
+    rt_uint32_t out_value;
+    int addr_start, addr_end, addr_offset, addr_len;
+
+    if (offset >= rk_otp->soc_data->size)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if (offset + bytes > rk_otp->soc_data->size)
+    {
+        bytes = rk_otp->soc_data->size - offset;
+    }
+
+    if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0)
+    {
+        LOG_E("Failed to prepare/enable clks");
+
+        return res;
+    }
+
+    if ((res = rockchip_otp_reset(rk_otp)))
+    {
+        LOG_E("Failed to reset otp phy");
+
+        goto _disable_clks;
+    }
+
+    if ((res = px30s_otp_active(rk_otp)))
+    {
+        goto _disable_clks;
+    }
+
+    addr_start = rt_rounddown(offset, PX30S_NBYTES) / PX30S_NBYTES;
+    addr_end = rt_roundup(offset + bytes, PX30S_NBYTES) / PX30S_NBYTES;
+    addr_offset = offset % PX30S_NBYTES;
+    addr_len = addr_end - addr_start;
+    addr_start += PX30S_NO_SECURE_OFFSET;
+
+    buf = rt_calloc(PX30S_NBYTES, addr_len * sizeof(*buf));
+    if (!buf)
+    {
+        res = -RT_ENOMEM;
+        goto _read_end;
+    }
+
+    for (int i = 0; addr_len--; i += PX30S_NBYTES)
+    {
+        HWREG32(rk_otp->regs + OTPC_REPR_RD_TRANS_NUM) = OTPC_TRANS_NUM;
+        HWREG32(rk_otp->regs + OTPC_ACCESS_ADDR) = addr_start++;
+        HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_READ_ACCESS;
+
+        if ((res = px30s_otp_wait_status(rk_otp, OTPC_RDM_IRQ_ST)) < 0)
+        {
+            LOG_E("timeout during wait rd");
+
+            goto _read_end;
+        }
+
+        out_value = HWREG32(rk_otp->regs + OTPC_RD_DATA);
+        rt_memcpy(&buf[i], &out_value, PX30S_NBYTES);
+    }
+
+    rt_memcpy(val, buf + addr_offset, (rt_uint32_t)bytes);
+    res = bytes;
+
+_read_end:
+    rt_free(buf);
+    px30s_otp_standby(rk_otp);
+
+_disable_clks:
+    rt_clk_array_disable_unprepare(rk_otp->clk_arr);
+
+    return res;
+}
+
+static rt_ssize_t rk3568_otp_read(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res;
+    rt_uint8_t *buf;
+    rt_uint32_t otp_qp, out_value;
+    int addr_start, addr_end, addr_offset, addr_len;
+
+    addr_start = rt_rounddown(offset, RK3568_NBYTES) / RK3568_NBYTES;
+    addr_end = rt_roundup(offset + bytes, RK3568_NBYTES) / RK3568_NBYTES;
+    addr_offset = offset % RK3568_NBYTES;
+    addr_len = addr_end - addr_start;
+
+    buf = rt_calloc(RK3568_NBYTES, addr_len * sizeof(*buf));
+    if (!buf)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0)
+    {
+        LOG_E("Failed to prepare/enable clks");
+        goto _out_free;
+    }
+
+    if ((res = rockchip_otp_reset(rk_otp)))
+    {
+        LOG_E("failed to reset otp phy");
+
+        goto _disable_clks;
+    }
+
+    if ((res = px30_otp_ecc_enable(rk_otp, RT_TRUE)) < 0)
+    {
+        LOG_E("Enable ECC error = %s", rt_strerror(res));
+
+        goto _disable_clks;
+    }
+
+    HWREG32(rk_otp->regs + OTPC_USER_CTRL) = OTPC_USE_USER | OTPC_USE_USER_MASK;
+
+    rt_hw_us_delay(5);
+
+    for (int i = 0; addr_len--; i += RK3568_NBYTES)
+    {
+        HWREG32(rk_otp->regs + OTPC_USER_ADDR) =
+                addr_start++ | OTPC_USER_ADDR_MASK;
+        HWREG32(rk_otp->regs + OTPC_USER_ENABLE) =
+                OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK;
+
+        if ((res = px30_otp_wait_status(rk_otp, OTPC_USER_DONE)) < 0)
+        {
+            LOG_E("Timeout during read setup");
+
+            goto _read_end;
+        }
+
+        otp_qp = HWREG32(rk_otp->regs + OTPC_USER_QP);
+
+        if (((otp_qp & 0xc0) == 0xc0) || (otp_qp & 0x20))
+        {
+            res = -RT_EIO;
+            LOG_E("ECC check error during read setup");
+
+            goto _read_end;
+        }
+
+        out_value = HWREG32(rk_otp->regs + OTPC_USER_Q);
+        rt_memcpy(&buf[i], &out_value, RK3568_NBYTES);
+    }
+
+    rt_memcpy(val, buf + addr_offset, bytes);
+    res = bytes;
+
+_read_end:
+    HWREG32(rk_otp->regs + OTPC_USER_CTRL) = 0x0 | OTPC_USE_USER_MASK;
+
+_disable_clks:
+
+    rt_clk_array_disable_unprepare(rk_otp->clk_arr);
+_out_free:
+    rt_free(buf);
+
+    return res;
+}
+
+static rt_err_t rk3588_otp_wait_status(struct rockchip_otp *rk_otp,
+        rt_uint32_t flag)
+{
+    rt_err_t err;
+    rt_uint32_t status = 0;
+
+    err = readl_poll_timeout(rk_otp->regs + RK3588_OTPC_INT_ST, status,
+            (status & flag), 1, OTPC_TIMEOUT);
+
+    if (err)
+    {
+        return err;
+    }
+
+    /* clean int status */
+    HWREG32(rk_otp->regs + RK3588_OTPC_INT_ST) = flag;
+
+    return RT_EOK;
+}
+
+static rt_ssize_t rk3588_otp_read(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res = 0;
+    rt_uint8_t *buf;
+    rt_uint32_t out_value;
+    int addr_start, addr_end, addr_offset, addr_len;
+
+    if (offset >= rk_otp->soc_data->size)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if (offset + bytes > rk_otp->soc_data->size)
+    {
+        bytes = rk_otp->soc_data->size - offset;
+    }
+
+    addr_start = rt_rounddown(offset, RK3588_NBYTES) / RK3588_NBYTES;
+    addr_end = rt_roundup(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
+    addr_offset = offset % RK3588_NBYTES;
+    addr_len = addr_end - addr_start;
+    addr_start += rk_otp->soc_data->ns_offset;
+
+    buf = rt_calloc(RK3588_NBYTES, addr_len * sizeof(*buf));
+    if (!buf)
+    {
+        return -RT_ENOMEM;
+    }
+
+    if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0)
+    {
+        LOG_E("Failed to prepare/enable clks");
+
+        goto _out_free;
+    }
+
+    for (int i = 0; addr_len--; i += RK3588_NBYTES, ++addr_start)
+    {
+        HWREG32(rk_otp->regs + RK3588_OTPC_AUTO_CTRL) =
+                (addr_start << RK3588_ADDR_SHIFT) |
+                    (RK3588_BURST_NUM << RK3588_BURST_SHIFT);
+        HWREG32(rk_otp->regs + RK3588_OTPC_AUTO_EN) = RK3588_AUTO_EN;
+
+        if ((res = rk3588_otp_wait_status(rk_otp, RK3588_RD_DONE)) < 0)
+        {
+            LOG_E("Timeout during read setup");
+
+            goto _read_end;
+        }
+
+        out_value = HWREG32(rk_otp->regs + RK3588_OTPC_DOUT0);
+        rt_memcpy(&buf[i], &out_value, RK3588_NBYTES);
+    }
+
+   rt_memcpy(val, buf + addr_offset, bytes);
+   res = bytes;
+
+_read_end:
+    rt_clk_array_disable_unprepare(rk_otp->clk_arr);
+
+_out_free:
+    rt_free(buf);
+
+    return res;
+}
+
+static rt_err_t rv1126_otp_init(struct rockchip_otp *rk_otp)
+{
+    rt_err_t err;
+    rt_uint32_t status = 0;
+
+    HWREG32(rk_otp->regs + RV1126_OTP_NVM_CEB) = 0x0;
+    err = readl_poll_timeout(rk_otp->regs + RV1126_OTP_NVM_ST, status,
+            status & 0x1, 1, OTPC_TIMEOUT);
+
+    if (err < 0)
+    {
+        LOG_E("Timeout during set ceb");
+
+        return err;
+    }
+
+    HWREG32(rk_otp->regs + RV1126_OTP_NVM_RSTB) = 0x1;
+    err = readl_poll_timeout(rk_otp->regs + RV1126_OTP_NVM_ST, status,
+            status & 0x4, 1, OTPC_TIMEOUT);
+
+    if (err < 0)
+    {
+        LOG_E("Timeout during set rstb");
+
+        return err;
+    }
+
+    return RT_EOK;
+}
+
+static rt_ssize_t rv1126_otp_read(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res;
+    rt_uint8_t *buf = val;
+    rt_uint32_t status = 0;
+
+    for (int i = 0; i < bytes; ++i)
+    {
+        HWREG32(rk_otp->regs + RV1126_OTP_NVM_RADDR) = offset++;
+        HWREG32(rk_otp->regs + RV1126_OTP_NVM_RSTART) = 0x1;
+
+        res = readl_poll_timeout(rk_otp->regs + RV1126_OTP_READ_ST,
+                status, status == 0, 1, OTPC_TIMEOUT);
+
+        if (res < 0)
+        {
+            LOG_E("Timeout during read setup");
+
+            return res;
+        }
+
+        *buf++ = HWREG8(rk_otp->regs + RV1126_OTP_NVM_RDATA);
+    }
+
+    return bytes;
+}
+
+static rt_err_t rv1126_otp_prog(struct rockchip_otp *rk_otp,
+        rt_uint32_t bit_offset, rt_uint32_t data, rt_uint32_t bit_len)
+{
+    rt_err_t err;
+    rt_uint32_t status = 0;
+
+    if (!data)
+    {
+        return RT_EOK;
+    }
+
+    HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRADDR) = bit_offset;
+    HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRLEN) = bit_len - 1;
+    HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRDATA) = data;
+    HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRSTART) = 1;
+
+    /* Wait max 100 ms */
+    err = readl_poll_timeout(rk_otp->regs + RV1126_OTP_NVM_PRSTATE,
+            status, status == 0, 1, OTPC_TIMEOUT_PROG);
+
+    if (err)
+    {
+        LOG_E("Timeout during prog");
+    }
+
+    return err;
+}
+
+static rt_ssize_t rv1126_otp_write(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res;
+    rt_uint8_t *buf = val, val_r, val_w;
+
+    for (int i = 0; i < bytes; ++i)
+    {
+        if ((res = rv1126_otp_read(rk_otp, offset, &val_r, 1)))
+        {
+            return res;
+        }
+
+        val_w = *buf & (~val_r);
+
+        if ((res = rv1126_otp_prog(rk_otp, offset * 8, val_w, 8)))
+        {
+            return res;
+        }
+
+        ++buf;
+        ++offset;
+    }
+
+    return bytes;
+}
+
+static rt_ssize_t rv1126_otp_wp(struct rockchip_otp *rk_otp, int offset,
+        rt_size_t bytes)
+{
+    int nbits = bytes / 4;
+    rt_uint32_t bit_idx = (offset - RV1126_OTP_OEM_OFFSET) / 4;
+
+    for (int i = 0; i < nbits; ++i)
+    {
+        rt_bitmap_set_bit(rk_otp->wp_mask, bit_idx + i);
+    }
+
+    return rv1126_otp_write(rk_otp, RV1126_OTP_WP_OFFSET, rk_otp->wp_mask,
+            RV1126_OTP_WP_SIZE);
+}
+
+static rt_ssize_t rv1126_otp_oem_write(struct rockchip_otp *rk_otp, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res;
+
+    if (offset < RV1126_OTP_OEM_OFFSET ||
+        offset > (RV1126_OTP_OEM_OFFSET + RV1126_OTP_OEM_SIZE - 1) ||
+        bytes > RV1126_OTP_OEM_SIZE ||
+        (offset + bytes) > (RV1126_OTP_OEM_OFFSET + RV1126_OTP_OEM_SIZE))
+    {
+        return -RT_EINVAL;
+    }
+
+    if (!OFFSET_IS_ALIGNED(offset, 4) || !OFFSET_IS_ALIGNED(bytes, 4))
+    {
+        return -RT_EINVAL;
+    }
+
+    if (!(res = rv1126_otp_write(rk_otp, offset, val, bytes)))
+    {
+        res = rv1126_otp_wp(rk_otp, offset, bytes);
+    }
+
+    return res;
+}
+
+static rt_ssize_t rockchip_otp_read(struct rt_nvmem_device *ndev, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res = -RT_EINVAL;
+    struct rockchip_otp *rk_otp = raw_to_rockchip_otp(ndev);
+
+    rt_mutex_take(&rk_otp->mutex, RT_WAITING_FOREVER);
+
+    if (rk_otp->soc_data && rk_otp->soc_data->read)
+    {
+        res = rk_otp->soc_data->read(rk_otp, offset, val, bytes);
+    }
+
+    rt_mutex_release(&rk_otp->mutex);
+
+    return res;
+}
+
+static rt_ssize_t rockchip_otp_write(struct rt_nvmem_device *ndev, int offset,
+        void *val, rt_size_t bytes)
+{
+    rt_ssize_t res = -RT_EINVAL;
+    struct rockchip_otp *rk_otp = raw_to_rockchip_otp(ndev);
+
+    rt_mutex_take(&rk_otp->mutex, RT_WAITING_FOREVER);
+
+    if (!rk_otp->was_written && rk_otp->soc_data && rk_otp->soc_data->write)
+    {
+        res = rk_otp->soc_data->write(rk_otp, offset, val, bytes);
+    }
+
+    rt_mutex_release(&rk_otp->mutex);
+
+    return res;
+}
+
+static const struct rockchip_otp_data px30_data =
+{
+    .size = 0x40,
+    .read = px30_otp_read,
+};
+
+static const struct rockchip_otp_data px30s_data =
+{
+    .size = 0x80,
+    .read = px30s_otp_read,
+};
+
+static const struct rockchip_otp_data rk3568_data =
+{
+    .size = 0x80,
+    .read = rk3568_otp_read,
+};
+
+static const struct rockchip_otp_data rk3576_data =
+{
+    .size = 0x100,
+    .ns_offset = RK3576_NO_SECURE_OFFSET,
+    .read = rk3588_otp_read,
+};
+
+static const struct rockchip_otp_data rk3588_data =
+{
+    .size = 0x400,
+    .ns_offset = RK3588_NO_SECURE_OFFSET,
+    .read = rk3588_otp_read,
+};
+
+static const struct rockchip_otp_data rv1106_data =
+{
+    .size = 0x80,
+    .read = rk3568_otp_read,
+};
+
+static const struct rockchip_otp_data rv1126_data =
+{
+    .size = 0x200,
+    .init = rv1126_otp_init,
+    .read = rv1126_otp_read,
+    .write = rv1126_otp_oem_write,
+};
+
+static rt_err_t rockchip_otp_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rt_nvmem_device *nvmem;
+    struct rt_device *dev = &pdev->parent;
+    const struct rockchip_otp_data *soc_data = pdev->id->data;
+    struct rockchip_otp *rk_otp = rt_calloc(1, sizeof(*rk_otp));
+
+    if (!rk_otp)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rk_otp->regs = rt_dm_dev_iomap(dev, 0);
+
+    if (!rk_otp->regs)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    rk_otp->clk_arr = rt_clk_get_array(dev);
+
+    if (rt_is_err(rk_otp->clk_arr))
+    {
+        err = rt_ptr_err(rk_otp->clk_arr);
+        goto _fail;
+    }
+
+    rk_otp->rstc = rt_reset_control_get_array(dev);
+
+    if (rt_is_err(rk_otp->rstc))
+    {
+        err = rt_ptr_err(rk_otp->rstc);
+        goto _fail;
+    }
+
+    if (soc_data->init)
+    {
+        if ((err = soc_data->init(rk_otp)))
+        {
+            goto _fail;
+        }
+    }
+
+    dev->user_data = rk_otp;
+
+    rk_otp->soc_data = soc_data;
+    nvmem = &rk_otp->parent;
+
+    nvmem->parent.ofw_node = dev->ofw_node;
+    nvmem->reg_read = rockchip_otp_read,
+    nvmem->reg_write = rockchip_otp_write,
+    nvmem->size = soc_data->size;
+    nvmem->read_only = soc_data->write == RT_NULL;
+    nvmem->stride = 1;
+    nvmem->word_size = 1;
+
+    if ((err = rt_nvmem_device_register(nvmem)))
+    {
+        goto _fail;
+    }
+
+    rt_mutex_init(&rk_otp->mutex, "rockchip-otp", RT_IPC_FLAG_PRIO);
+
+    return RT_EOK;
+
+_fail:
+    if (rk_otp->regs)
+    {
+        rt_iounmap(rk_otp->regs);
+    }
+
+    if (!rt_is_err_or_null(rk_otp->clk_arr))
+    {
+        rt_clk_array_put(rk_otp->clk_arr);
+    }
+
+    rt_free(rk_otp);
+
+    return err;
+}
+
+static rt_err_t rockchip_otp_remove(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    struct rockchip_otp *rk_otp = pdev->parent.user_data;
+
+    err = rt_nvmem_device_unregister(&rk_otp->parent);
+
+    rt_iounmap(rk_otp->regs);
+    rt_clk_array_put(rk_otp->clk_arr);
+
+    rt_free(rk_otp);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id rockchip_otp_ofw_ids[] =
+{
+    { .compatible = "rockchip,px30-otp", .data = &px30_data, },
+    { .compatible = "rockchip,px30s-otp", .data = &px30s_data, },
+    { .compatible = "rockchip,rk3308-otp", .data = &px30_data, },
+    { .compatible = "rockchip,rk3308bs-otp", .data = &px30s_data, },
+    { .compatible = "rockchip,rk3568-otp", .data = &rk3568_data, },
+    { .compatible = "rockchip,rk3576-otp", .data = &rk3576_data, },
+    { .compatible = "rockchip,rk3588-otp", .data = &rk3588_data, },
+    { .compatible = "rockchip,rv1106-otp", .data = &rv1106_data, },
+    { .compatible = "rockchip,rv1126-otp", .data = &rv1126_data, },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_otp_driver =
+{
+    .name = "nvmem-rockchip-otp",
+    .ids = rockchip_otp_ofw_ids,
+
+    .probe = rockchip_otp_probe,
+    .remove = rockchip_otp_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rockchip_otp_driver);

+ 11 - 0
bsp/rockchip/dm/pci/Kconfig

@@ -0,0 +1,11 @@
+config RT_PCI_DW_ROCKCHIP
+    bool "Rockchip DesignWare PCIe"
+    depends on RT_PCI_DW
+    depends on RT_USING_PIN
+    depends on RT_USING_PINCTRL
+    depends on RT_USING_PHYE
+    depends on RT_USING_RESET
+    depends on RT_USING_REGULATOR
+    select RT_PCI_DW_HOST
+    select RT_PCI_DW_EP
+    default n

+ 15 - 0
bsp/rockchip/dm/pci/SConscript

@@ -0,0 +1,15 @@
+from building import *
+
+group = []
+
+cwd = GetCurrentDir()
+CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/pci', cwd + '/../../../../components/drivers/pci/host/dw']
+
+src = []
+
+if GetDepend(['RT_PCI_DW_ROCKCHIP']):
+    src += ['pcie-dw-rockchip.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 1645 - 0
bsp/rockchip/dm/pci/pcie-dw-rockchip.c

@@ -0,0 +1,1645 @@
+/*
+ * Copyright (c) 2006-2023, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-09-23     GuEe-GUI     first version
+ */
+
+#define DBG_TAG "pci.dw.rockchip"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "pcie-dw.h"
+#include "rockchip.h"
+
+#define PCIE_DMA_OFFSET                     0x380000
+
+#define PCIE_DMA_CTRL_OFF                   0x8
+#define PCIE_DMA_WR_ENB                     0xc
+#define PCIE_DMA_WR_CTRL_LO                 0x200
+#define PCIE_DMA_WR_CTRL_HI                 0x204
+#define PCIE_DMA_WR_XFERSIZE                0x208
+#define PCIE_DMA_WR_SAR_PTR_LO              0x20c
+#define PCIE_DMA_WR_SAR_PTR_HI              0x210
+#define PCIE_DMA_WR_DAR_PTR_LO              0x214
+#define PCIE_DMA_WR_DAR_PTR_HI              0x218
+#define PCIE_DMA_WR_WEILO                   0x18
+#define PCIE_DMA_WR_WEIHI                   0x1c
+#define PCIE_DMA_WR_DOORBELL                0x10
+#define PCIE_DMA_WR_INT_STATUS              0x4c
+#define PCIE_DMA_WR_INT_MASK                0x54
+#define PCIE_DMA_WR_INT_CLEAR               0x58
+
+#define PCIE_DMA_RD_ENB                     0x2c
+#define PCIE_DMA_RD_CTRL_LO                 0x300
+#define PCIE_DMA_RD_CTRL_HI                 0x304
+#define PCIE_DMA_RD_XFERSIZE                0x308
+#define PCIE_DMA_RD_SAR_PTR_LO              0x30c
+#define PCIE_DMA_RD_SAR_PTR_HI              0x310
+#define PCIE_DMA_RD_DAR_PTR_LO              0x314
+#define PCIE_DMA_RD_DAR_PTR_HI              0x318
+#define PCIE_DMA_RD_WEILO                   0x38
+#define PCIE_DMA_RD_WEIHI                   0x3c
+#define PCIE_DMA_RD_DOORBELL                0x30
+#define PCIE_DMA_RD_INT_STATUS              0xa0
+#define PCIE_DMA_RD_INT_MASK                0xa8
+#define PCIE_DMA_RD_INT_CLEAR               0xac
+
+#define PCIE_DMA_CHANEL_MAX_NUM             2
+
+/* Parameters for the waiting for iATU enabled routine */
+#define LINK_WAIT_IATU_MIN                  9000
+#define LINK_WAIT_IATU_MAX                  10000
+
+#define PCIE_DIRECT_SPEED_CHANGE            (0x1 << 17)
+
+#define PCIE_TYPE0_STATUS_COMMAND_REG       0x4
+#define PCIE_TYPE0_BAR0_REG                 0x10
+
+#define PCIE_CAP_LINK_CONTROL2_LINK_STATUS  0xa0
+
+#define PCIE_CLIENT_INTR_STATUS_MSG_RX      0x04
+#define PME_TO_ACK                          (RT_BIT(9) | RT_BIT(25))
+#define PCIE_CLIENT_INTR_STATUS_LEGACY      0x08
+#define PCIE_CLIENT_INTR_STATUS_MISC        0x10
+#define PCIE_CLIENT_INTR_MASK_LEGACY        0x1c
+#define UNMASK_ALL_LEGACY_INT               0xffff0000
+#define MASK_LEGACY_INT(x)                  (0x00110011 << (x))
+#define UNMASK_LEGACY_INT(x)                (0x00110000 << (x))
+#define PCIE_CLIENT_INTR_MASK               0x24
+#define PCIE_CLIENT_POWER                   0x2c
+#define READY_ENTER_L23                     RT_BIT(3)
+#define PCIE_CLIENT_MSG_GEN                 0x34
+#define PME_TURN_OFF                        (RT_BIT(4) | RT_BIT(20))
+#define PCIE_CLIENT_GENERAL_DEBUG           0x104
+#define PCIE_CLIENT_HOT_RESET_CTRL          0x180
+#define PCIE_LTSSM_APP_DLY1_EN              RT_BIT(0)
+#define PCIE_LTSSM_APP_DLY2_EN              RT_BIT(1)
+#define PCIE_LTSSM_APP_DLY1_DONE            RT_BIT(2)
+#define PCIE_LTSSM_APP_DLY2_DONE            RT_BIT(3)
+#define PCIE_LTSSM_ENABLE_ENHANCE           RT_BIT(4)
+#define PCIE_CLIENT_LTSSM_STATUS            0x300
+#define SMLH_LINKUP                         RT_BIT(16)
+#define RDLH_LINKUP                         RT_BIT(17)
+#define PCIE_CLIENT_CDM_RASDES_TBA_INFO_CMN 0x154
+#define PCIE_CLIENT_DBG_FIFO_MODE_CON       0x310
+#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0     0x320
+#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1     0x324
+#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0     0x328
+#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1     0x32c
+#define PCIE_CLIENT_DBG_FIFO_STATUS         0x350
+#define PCIE_CLIENT_DBG_TRANSITION_DATA     0xffff0000
+#define PCIE_CLIENT_DBF_EN                  0xffff0007
+
+#define PCIE_PHY_LINKUP                     RT_BIT(0)
+#define PCIE_DATA_LINKUP                    RT_BIT(1)
+
+#define PCIE_TYPE0_HDR_DBI2_OFFSET          0x100000
+#define PCIE_SB_BAR0_MASK_REG               0x100010
+
+#define PCIE_PL_ORDER_RULE_CTRL_OFF         0x8b4
+#define RK_PCIE_L2_TMOUT_US                 5000
+#define RK_PCIE_HOTRESET_TMOUT_US           10000
+#define RK_PCIE_ENUM_HW_RETRYIES            2
+
+enum rockchip_pcie_ltssm_code
+{
+    S_L0        = 0x11,
+    S_L0S       = 0x12,
+    S_L1_IDLE   = 0x14,
+    S_L2_IDLE   = 0x15,
+    S_MAX       = 0x1f,
+};
+
+enum rockchip_pcie_soc_type
+{
+    SOC_TYPE_ALL = 0,
+    SOC_TYPE_RK1808,
+};
+
+struct rockchip_pcie_soc_data
+{
+    enum rockchip_pcie_soc_type type;
+    enum dw_pcie_device_mode mode;
+    rt_uint32_t msi_vector_num;
+};
+
+struct rockchip_pcie
+{
+    struct dw_pcie pci;
+
+    void *apb_base;
+
+    enum rt_phye_mode phy_mode;
+    enum rt_phye_mode phy_submode;
+
+    struct rt_phye *phy;
+    struct rt_clk_array *clk_arr;
+    struct rt_reset_control *rstc;
+    struct rt_regulator *vpcie3v3;
+
+    struct rt_syscon *usb_pcie_grf;
+    struct rt_syscon *pmu_grf;
+
+    rt_base_t rst_pin;
+    rt_uint8_t rst_active_val;
+
+    rt_base_t prsnt_pin;
+    rt_uint8_t prsnt_active_val;
+    rt_uint32_t perst_inactive_ms;
+
+    rt_uint64_t mem_start;
+    rt_uint64_t mem_size;
+
+    rt_uint32_t msi_vector_num;
+    rt_uint32_t comp_prst[2];
+
+    rt_bool_t in_suspend;
+    rt_bool_t skip_scan_in_resume;
+    rt_bool_t is_signal_test;
+    rt_bool_t bifurcation;
+    rt_bool_t supports_clkreq;
+    struct rt_work hot_rst_work;
+
+    int intx_irq;
+    rt_uint32_t intx;
+    struct rt_ofw_node *intx_np;
+    struct rt_pic intx_pic;
+
+    const struct rockchip_pcie_soc_data *soc_data;
+};
+
+#define to_rockchip_pcie(dw_pcie) rt_container_of(dw_pcie, struct rockchip_pcie, pci)
+
+rt_inline rt_uint32_t rockchip_pcie_readl_apb(struct rockchip_pcie *rk_pcie,
+        int offset)
+{
+    return HWREG32(rk_pcie->apb_base + offset);
+}
+
+rt_inline void rockchip_pcie_writel_apb(struct rockchip_pcie *rk_pcie,
+        int offset, rt_uint32_t val)
+{
+    HWREG32(rk_pcie->apb_base + offset) = val;
+}
+
+rt_inline void rockchip_pcie_link_status_clear(struct rockchip_pcie *rk_pcie)
+{
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG, 0x0);
+}
+
+rt_inline void rockchip_pcie_disable_ltssm(struct rockchip_pcie *rk_pcie)
+{
+    rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xc0008);
+}
+
+rt_inline void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rk_pcie)
+{
+    rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xc000c);
+}
+
+rt_inline rt_bool_t rockchip_pcie_udma_enabled(struct rockchip_pcie *rk_pcie)
+{
+    return dw_pcie_readl_dbi(&rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_CTRL_OFF);
+}
+
+static void rockchip_pcie_intx_irq_mask(struct rt_pic_irq *pirq)
+{
+    struct rockchip_pcie *rk_pcie = pirq->pic->priv_data;
+
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY,
+            MASK_LEGACY_INT(pirq->hwirq));
+}
+
+static void rockchip_pcie_intx_irq_unmask(struct rt_pic_irq *pirq)
+{
+    struct rockchip_pcie *rk_pcie = pirq->pic->priv_data;
+
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY,
+            UNMASK_LEGACY_INT(pirq->hwirq));
+}
+
+static int rockchip_pcie_intx_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
+{
+    int irq;
+    struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq);
+
+    if (pirq)
+    {
+        if (pirq->irq >= 0)
+        {
+            irq = pirq->irq;
+        }
+        else
+        {
+            irq = rt_pic_config_irq(pic, hwirq, hwirq);
+            rt_pic_irq_set_triger_mode(irq, RT_IRQ_MODE_LEVEL_HIGH);
+        }
+    }
+    else
+    {
+        irq = -1;
+    }
+
+    return irq;
+}
+
+static rt_err_t rockchip_pcie_intx_irq_parse(struct rt_pic *pic,
+        struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq)
+{
+    rt_err_t err = RT_EOK;
+
+    if (args->args_count == 1)
+    {
+        out_pirq->hwirq = args->args[0];
+        out_pirq->mode = RT_IRQ_MODE_LEVEL_HIGH;
+    }
+    else
+    {
+        err = -RT_EINVAL;
+    }
+
+    return err;
+}
+
+const static struct rt_pic_ops rockchip_intx_ops =
+{
+    .name = "DWPCI-RK-INTx",
+    .irq_mask = rockchip_pcie_intx_irq_mask,
+    .irq_unmask = rockchip_pcie_intx_irq_unmask,
+    .irq_map = rockchip_pcie_intx_irq_map,
+    .irq_parse = rockchip_pcie_intx_irq_parse,
+};
+
+static void rockchip_pcie_sys_isr(int irqno, void *param)
+{
+    rt_uint32_t reg;
+    struct rockchip_pcie *rk_pcie = param;
+
+    /* DMA ISR */
+    LOG_D("%s: DMA %s status = %x", rt_dm_dev_get_name(rk_pcie->dev), "WR",
+            dw_pcie_readl_dbi(&rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS));
+
+    LOG_D("%s: DMA %s status = %x", rt_dm_dev_get_name(rk_pcie->dev), "RD",
+            dw_pcie_readl_dbi(&rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS));
+
+    /* MISC ISR */
+    reg = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC);
+
+    if (reg & RT_BIT(2))
+    {
+        rt_work_submit(&rk_pcie->hot_rst_work, 0);
+    }
+
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC, reg);
+}
+
+static void rockchip_pcie_legacy_isr(int irqno, void *param)
+{
+    rt_uint32_t ints;
+    struct rt_pic_irq *pirq;
+    struct rockchip_pcie *rk_pcie = param;
+
+    ints = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_LEGACY);
+
+    for (int pin = 0; ints && pin < RT_PCI_INTX_PIN_MAX; ++pin, ints >>= 1)
+    {
+        if ((ints & 1))
+        {
+            pirq = rt_pic_find_irq(&rk_pcie->intx_pic, pin);
+
+            rt_pic_handle_isr(pirq);
+        }
+    }
+}
+
+static void rockchip_pcie_hot_rst_work(struct rt_work *work, void *work_data)
+{
+    rt_err_t err;
+    rt_uint32_t val, status;
+    struct rockchip_pcie *rk_pcie = work_data;
+
+    val = dw_pcie_readl_dbi(&rk_pcie->pci, PCIR_COMMAND);
+    val &= 0xffff0000;
+    val |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN;
+    dw_pcie_writel_dbi(&rk_pcie->pci, PCIR_COMMAND, val);
+
+    if (rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN)
+    {
+        err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS,
+                status, ((status & 0x3f) == 0), 100, RK_PCIE_HOTRESET_TMOUT_US);
+        if (err)
+        {
+            LOG_E("Wait for detect quiet timeout");
+        }
+
+        rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL,
+                (PCIE_LTSSM_APP_DLY2_DONE) | ((PCIE_LTSSM_APP_DLY2_DONE) << 16));
+    }
+}
+
+rt_inline rt_err_t rockchip_pcie_enable_power(struct rockchip_pcie *rk_pcie)
+{
+    rt_err_t err = RT_EOK;
+
+    if (rk_pcie->vpcie3v3)
+    {
+        err = rt_regulator_set_voltage(rk_pcie->vpcie3v3, 3300000, 3300000);
+        err |= rt_regulator_enable(rk_pcie->vpcie3v3);
+    }
+
+    return err;
+}
+
+rt_inline rt_err_t rockchip_pcie_disable_power(struct rockchip_pcie *rk_pcie)
+{
+    if (rk_pcie->vpcie3v3)
+    {
+        return rt_regulator_disable(rk_pcie->vpcie3v3);
+    }
+
+    return RT_EOK;
+}
+
+static void rockchip_pcie_fast_link_setup(struct rockchip_pcie *rk_pcie)
+{
+    rt_uint32_t val;
+
+    /* LTSSM EN ctrl mode */
+    val = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL);
+    val |= (PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) |
+            ((PCIE_LTSSM_APP_DLY2_EN | PCIE_LTSSM_ENABLE_ENHANCE) << 16);
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, val);
+}
+
+static rt_err_t rockchip_pcie_establish_link_raw(struct rockchip_pcie *rk_pcie)
+{
+    rt_uint32_t ltssm;
+    rt_bool_t std_rc = rk_pcie->soc_data->mode == DW_PCIE_RC_TYPE;
+    struct dw_pcie *pci = &rk_pcie->pci;
+
+    /*
+     * For standard RC, even if the link has been setup by firmware,
+     * we still need to reset link as we need to remove all resource info
+     * from devices, for instance BAR, as it wasn't assigned by kernel.
+     */
+    if (dw_pcie_link_up(pci) && !std_rc)
+    {
+        LOG_E("Link is already up");
+        return RT_EOK;
+    }
+
+    for (int hw_retries = 0; hw_retries < RK_PCIE_ENUM_HW_RETRYIES; ++hw_retries)
+    {
+        /* Rest the device */
+        rt_pin_write(rk_pcie->rst_pin, !rk_pcie->rst_active_val);
+
+        rockchip_pcie_disable_ltssm(rk_pcie);
+        rockchip_pcie_link_status_clear(rk_pcie);
+
+        if (rk_pcie->soc_data->type != SOC_TYPE_RK1808)
+        {
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0,
+                    PCIE_CLIENT_DBG_TRANSITION_DATA);
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1,
+                    PCIE_CLIENT_DBG_TRANSITION_DATA);
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0,
+                    PCIE_CLIENT_DBG_TRANSITION_DATA);
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1,
+                    PCIE_CLIENT_DBG_TRANSITION_DATA);
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_MODE_CON,
+                    PCIE_CLIENT_DBF_EN);
+        }
+
+        /* Enable client reset or link down interrupt */
+        rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000);
+
+        /* Enable LTSSM */
+        rockchip_pcie_enable_ltssm(rk_pcie);
+
+        /*
+         * In resume routine, function devices' resume function must be late
+         * after controllers'. Some devices, such as Wi-Fi,
+         * need special IO setting before finishing training.
+         * So there must be timeout here. These kinds of devices need rescan
+         * devices by its driver when used. So no need to waste time waiting
+         * for training pass.
+         */
+        if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume)
+        {
+            /*
+             * Check WiFi power status here.
+             * If down, active the RST pin and return.
+             */
+        }
+
+        /*
+         * PCIe requires the refclk to be stable for 100µs prior to releasing
+         * PERST and T_PVPERL (Power stable to PERST# inactive) should be a
+         * minimum of 100ms.  See table 2-4 in section 2.6.2 AC, the PCI Express
+         * Card Electromechanical Specification 3.0.
+         * So 100ms in total is the min requuirement here.
+         * We add a 200ms by default for sake of hoping everthings work fine.
+         * If it doesn't, Add more in DT node by add rockchip,perst-inactive-ms.
+         */
+        rt_thread_mdelay(rk_pcie->perst_inactive_ms);
+        rt_pin_write(rk_pcie->rst_pin, rk_pcie->rst_active_val);
+
+        /* Link is always up stably after 1ms. */
+        rt_thread_mdelay(2);
+
+        for (int retries = 0; retries < 100; ++retries)
+        {
+            if (dw_pcie_link_up(pci))
+            {
+                /*
+                 * We may be here in case of L0 in Gen1. But if EP is capable
+                 * of Gen2 or Gen3, Gen switch may happen just in this time, but
+                 * we keep on accessing devices in unstable link status. Given
+                 * that LTSSM max timeout is 24ms per period, we can wait a bit
+                 * more for Gen switch.
+                 */
+                rt_thread_mdelay(50);
+
+                /* In case link drop after linkup, double check it */
+                if (dw_pcie_link_up(pci))
+                {
+                    LOG_I("PCIe Link up, LTSSM is 0x%x",
+                            rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
+
+                    return RT_EOK;
+                }
+            }
+
+            if (!(retries % 20))
+            {
+                LOG_I("PCIe Linking... LTSSM is 0x%x",
+                        rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS));
+            }
+            rt_thread_mdelay(20);
+        }
+
+        /*
+         * In response to the situation where PCIe peripherals cannot be
+         * enumerated due tosignal abnormalities, reset PERST# and reset
+         * the peripheral power supply, then restart the enumeration.
+         */
+        ltssm = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS);
+        LOG_E("PCIe Link Fail, LTSSM is 0x%x", ltssm);
+
+        if (ltssm >= 3 && !rk_pcie->is_signal_test)
+        {
+            rockchip_pcie_disable_power(rk_pcie);
+            rt_thread_mdelay(1000);
+            rockchip_pcie_enable_power(rk_pcie);
+        }
+        else
+        {
+            break;
+        }
+    }
+
+    return rk_pcie->is_signal_test == RT_TRUE ? 0 : -RT_EINVAL;
+}
+
+rt_inline void rockchip_pcie_set_mode(struct rockchip_pcie *rk_pcie)
+{
+    switch (rk_pcie->soc_data->mode)
+    {
+    case DW_PCIE_EP_TYPE:
+        rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xf00000);
+
+        break;
+
+    case DW_PCIE_RC_TYPE:
+        if (rk_pcie->supports_clkreq)
+        {
+            /* Application is ready to have reference clock removed */
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_POWER, 0x00010001);
+        }
+        else
+        {
+            /* Pull down CLKREQ# to assert the connecting CLOCK_GEN OE */
+            rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_POWER, 0x30011000);
+            /* Disable ASPM L1SS here */
+        }
+
+        rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xf00040);
+
+        /*
+         * Disable order rule for CPL can't pass halted P queue.
+         * Need to check producer-consumer model. Just for RK1808 platform.
+         */
+        if (rk_pcie->soc_data->type == SOC_TYPE_RK1808)
+        {
+            dw_pcie_writel_dbi(&rk_pcie->pci, PCIE_PL_ORDER_RULE_CTRL_OFF, 0xff00);
+        }
+        break;
+
+    default:
+        break;
+    }
+}
+
+static rt_err_t rockchip_pcie_reset_grant_ctrl(struct rockchip_pcie *rk_pcie,
+        rt_bool_t enable)
+{
+    rt_uint32_t val = (0x1 << 18);
+
+    if (enable)
+    {
+        val |= (0x1 << 2);
+    }
+
+    return rt_syscon_write(rk_pcie->usb_pcie_grf, 0x0, val);
+}
+
+static void rockchip_pcie_ep_reset_bar(struct rockchip_pcie *rk_pcie,
+        int bar_idx, rt_ubase_t flags)
+{
+    rt_uint32_t reg = PCIR_BAR(bar_idx);
+
+    dw_pcie_writel_dbi(&rk_pcie->pci, reg, 0x0);
+
+    if (flags & PCIM_BAR_MEM_TYPE_64)
+    {
+        dw_pcie_writel_dbi(&rk_pcie->pci, reg + 4, 0x0);
+    }
+}
+
+static rt_err_t rockchip_pcie_ep_inbound_atu(struct rockchip_pcie *rk_pcie,
+        int bar_idx, rt_ubase_t cpu_addr, enum dw_pcie_aspace_type aspace_type)
+{
+    rt_err_t err;
+    rt_uint32_t free_win;
+    rt_uint8_t func_no = 0x0;
+    struct dw_pcie_ep *ep = &rk_pcie->pci.endpoint;
+
+    if (rk_pcie->in_suspend)
+    {
+        free_win = ep->bar_to_atu[bar_idx];
+    }
+    else
+    {
+        free_win = rt_bitmap_next_clear_bit(ep->ib_window_map, 0, ep->num_ib_windows);
+
+        if (free_win >= ep->num_ib_windows)
+        {
+            LOG_E("No free inbound window");
+            return -RT_EINVAL;
+        }
+    }
+
+    if ((err = dw_pcie_prog_inbound_atu(&rk_pcie->pci, func_no, free_win,
+            bar_idx, cpu_addr, aspace_type)))
+    {
+        LOG_E("Failed to program IB window");
+        return err;
+    }
+
+    if (rk_pcie->in_suspend)
+    {
+        return RT_EOK;
+    }
+
+    ep->bar_to_atu[bar_idx] = free_win;
+    rt_bitmap_set_bit(ep->ib_window_map, free_win);
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_pcie_ep_outbound_atu(struct rockchip_pcie *rk_pcie,
+        rt_ubase_t phys_addr, rt_uint64_t pci_addr, rt_size_t size)
+{
+    rt_uint32_t free_win;
+    struct dw_pcie_ep *ep = &rk_pcie->pci.endpoint;
+
+    if (rk_pcie->in_suspend)
+    {
+        free_win = rt_bitmap_next_set_bit(ep->ob_window_map, 0, ep->num_ob_windows);
+    }
+    else
+    {
+        free_win = rt_bitmap_next_clear_bit(ep->ob_window_map, 0, ep->num_ob_windows);
+
+        if (free_win >= ep->num_ob_windows)
+        {
+            LOG_E("No free outbound window");
+            return -RT_EINVAL;
+        }
+    }
+
+    dw_pcie_prog_outbound_atu(&rk_pcie->pci, free_win, PCIE_ATU_TYPE_MEM,
+            phys_addr, pci_addr, size);
+
+    if (rk_pcie->in_suspend)
+    {
+        return RT_EOK;
+    }
+
+    ep->outbound_addr[free_win] = phys_addr;
+    rt_bitmap_set_bit(ep->ob_window_map, free_win);
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_pcie_ep_atu_init(struct rockchip_pcie *rk_pcie)
+{
+    rt_err_t err;
+
+    for (int bar = 0; bar < PCI_STD_NUM_BARS; ++bar)
+    {
+        rockchip_pcie_ep_reset_bar(rk_pcie, bar, 0);
+    }
+
+    if ((err = rockchip_pcie_ep_inbound_atu(rk_pcie, 0, rk_pcie->mem_start,
+            DW_PCIE_ASPACE_MEM)))
+    {
+        return err;
+    }
+
+    if ((err = rockchip_pcie_ep_outbound_atu(rk_pcie, 0x0, 0x0, 2UL * SIZE_GB)))
+    {
+        return err;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_pcie_establish_link(struct dw_pcie *pci)
+{
+    struct rockchip_pcie *rk_pcie = rt_container_of(pci, struct rockchip_pcie, pci);
+
+    return rockchip_pcie_establish_link_raw(rk_pcie);
+}
+
+static const struct dw_pcie_ops dw_pcie_ops =
+{
+    .start_link = rockchip_pcie_establish_link,
+};
+
+static rt_err_t rockchip_pcie_host_init(struct dw_pcie_port *port)
+{
+    rt_err_t err;
+    struct dw_pcie *pci = to_dw_pcie_from_port(port);
+    struct rockchip_pcie *rk_pcie = rt_container_of(pci, struct rockchip_pcie, pci);
+
+    dw_pcie_setup_rc(port);
+
+    dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE);
+
+    /* Disable BAR0 BAR1 */
+    dw_pcie_writel_dbi2(pci, PCIR_BAR(0), 0);
+    dw_pcie_writel_dbi2(pci, PCIR_BAR(1), 0);
+
+    dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE);
+
+    err = rockchip_pcie_establish_link_raw(rk_pcie);
+
+    if (port->msi_irq > 0)
+    {
+        dw_pcie_msi_init(port);
+    }
+
+    return err;
+}
+
+static rt_err_t rockchip_pcie_msi_host_init(struct dw_pcie_port *port)
+{
+    return RT_EOK;
+}
+
+static void rockchip_pcie_set_irq_count(struct dw_pcie_port *port)
+{
+    struct dw_pcie *pci = to_dw_pcie_from_port(port);
+    struct rockchip_pcie *rk_pcie = rt_container_of(pci, struct rockchip_pcie, pci);
+
+    port->irq_count = rk_pcie->msi_vector_num;
+}
+
+static struct dw_pcie_host_ops rockchip_pcie_port_ops[] =
+{
+    [0] =   /* Normal */
+    {
+        .host_init = rockchip_pcie_host_init,
+    },
+    [1] =   /* MSI */
+    {
+        .host_init = rockchip_pcie_host_init,
+        .msi_host_init = rockchip_pcie_msi_host_init,
+    },
+    [2] =   /* No MSI */
+    {
+        .host_init = rockchip_pcie_host_init,
+        .set_irq_count = rockchip_pcie_set_irq_count,
+    },
+};
+
+static rt_err_t rockchip_pcie_add_port(struct rockchip_pcie *rk_pcie)
+{
+    rt_err_t err;
+    struct dw_pcie *pci = &rk_pcie->pci;
+    struct dw_pcie_port *port = &pci->port;
+
+    port->ops = &rockchip_pcie_port_ops[0];
+#ifdef RT_USING_MSI
+    if ((port->msi_irq = rt_dm_dev_get_irq_by_name(dev, "msi")) < 0)
+    {
+        port->ops = &rockchip_pcie_port_ops[1];
+    }
+    else
+    {
+        port->ops = &rockchip_pcie_port_ops[2];
+    }
+#endif
+
+    if ((err = dw_pcie_host_init(port)))
+    {
+        LOG_E("Init HOST error = %s", rt_strerror(err));
+        return err;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_pcie_ep_raise_irq(struct dw_pcie_ep *ep,
+        rt_uint8_t func_no, enum rt_pci_ep_irq type, unsigned irq)
+{
+    switch (type)
+    {
+    case RT_PCI_EP_IRQ_LEGACY:
+        return dw_pcie_ep_raise_legacy_irq(ep, func_no);
+
+    case RT_PCI_EP_IRQ_MSI:
+        return dw_pcie_ep_raise_msi_irq(ep, func_no, irq);
+
+    case RT_PCI_EP_IRQ_MSIX:
+        return dw_pcie_ep_raise_msix_irq(ep, func_no, irq);
+
+    default:
+        LOG_E("Unknown IRQ type = %d", type);
+    }
+
+    return RT_EOK;
+}
+
+static struct dw_pcie_ep_ops rockchip_pcie_ep_ops =
+{
+    .raise_irq = rockchip_pcie_ep_raise_irq,
+};
+
+static rt_err_t rockchip_pcie_ep_set_bar_flag(struct rockchip_pcie *rk_pcie,
+        int bar_idx, rt_ubase_t flags)
+{
+    rt_uint32_t reg = PCIR_BAR(bar_idx);
+    struct dw_pcie *pci = &rk_pcie->pci;
+
+    /* Disabled the upper 32bits BAR to make a 64bits bar pair */
+    if (flags & PCIM_BAR_MEM_TYPE_64)
+    {
+        dw_pcie_writel_dbi2(pci, reg + 4, 0);
+    }
+
+    dw_pcie_writel_dbi(pci, reg, flags);
+
+    if (flags & PCIM_BAR_MEM_TYPE_64)
+    {
+        dw_pcie_writel_dbi(pci, reg + 4, 0);
+    }
+
+    return 0;
+}
+
+static void rockchip_pcie_ep_setup_top(struct rockchip_pcie *rk_pcie)
+{
+    struct dw_pcie *pci = &rk_pcie->pci;
+
+    /* Enable client write and read interrupt */
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xc000000);
+    /* Enable core write interrupt */
+    dw_pcie_writel_dbi(pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, 0x0);
+    /* Enable core read interrupt */
+    dw_pcie_writel_dbi(pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, 0x0);
+}
+
+static void rockchip_pcie_ep_setup_bottom(struct rockchip_pcie *rk_pcie)
+{
+    int resbar_base;
+    struct dw_pcie *pci = &rk_pcie->pci;
+
+    /* Enable bus master and memory space */
+    dw_pcie_writel_dbi(pci, PCIE_TYPE0_STATUS_COMMAND_REG, 0x6);
+
+    resbar_base = dw_pcie_find_ext_capability(pci, PCIZ_RESIZE_BAR);
+    if (!resbar_base)
+    {
+        LOG_W("Resbar CAP not found");
+    }
+    else
+    {
+        /*
+         * Resize:
+         * BAR0 to support 512GB
+         * BAR1 to support 8M
+         * BAR2~5 to support 64M
+         */
+        dw_pcie_writel_dbi(pci, resbar_base + 0x4, 0xfffff0);
+        dw_pcie_writel_dbi(pci, resbar_base + 0x8, 0x13c0);
+        dw_pcie_writel_dbi(pci, resbar_base + 0xc, 0xfffff0);
+        dw_pcie_writel_dbi(pci, resbar_base + 0x10, 0x3c0);
+
+        for (int bar = 2; bar < PCI_STD_NUM_BARS; ++bar)
+        {
+            dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0);
+            dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x6c0);
+        }
+
+        /* Set flags */
+        rockchip_pcie_ep_set_bar_flag(rk_pcie, 0, PCIM_BAR_MEM_TYPE_32);
+        rockchip_pcie_ep_set_bar_flag(rk_pcie, 1, PCIM_BAR_MEM_TYPE_32);
+        rockchip_pcie_ep_set_bar_flag(rk_pcie, 2, PCIM_BAR_MEM_PREFETCH | PCIM_BAR_MEM_TYPE_64);
+        rockchip_pcie_ep_set_bar_flag(rk_pcie, 3, PCIM_BAR_MEM_PREFETCH | PCIM_BAR_MEM_TYPE_64);
+    }
+
+    /* Device id and class id needed for request bar address */
+    dw_pcie_writew_dbi(pci, PCIR_DEVICE, 0x356a);
+    dw_pcie_writew_dbi(pci, PCIR_SUBCLASS, 0x0580);
+
+    /* Set shadow BAR0 */
+    if (rk_pcie->soc_data->type == SOC_TYPE_RK1808)
+    {
+        dw_pcie_writel_dbi(pci, PCIE_SB_BAR0_MASK_REG, rk_pcie->mem_size - 1);
+    }
+}
+
+static rt_err_t rockchip_pcie_add_endpoint(struct rockchip_pcie *rk_pcie)
+{
+    rt_err_t err;
+    struct dw_pcie *pci = &rk_pcie->pci;
+    struct rt_ofw_node *np = rk_pcie->pci.dev->ofw_node, *mem_np;
+
+    if (!(mem_np = rt_ofw_parse_phandle(np, "memory-region", 0)))
+    {
+        LOG_E("%s: Missing '%s'", rt_ofw_node_full_name(np), "memory-region");
+        return -RT_EINVAL;
+    }
+
+    if ((err = rt_ofw_get_address(mem_np, 0, &rk_pcie->mem_start, &rk_pcie->mem_size)))
+    {
+        LOG_E("%s: Missing '%s'", rt_ofw_node_full_name(mem_np), "reg");
+        return -RT_EINVAL;
+    }
+
+    pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET;
+    pci->user_speed = PCIE_DIRECT_SPEED_CHANGE;
+    pci->endpoint.ops = &rockchip_pcie_ep_ops;
+
+    rockchip_pcie_ep_setup_top(rk_pcie);
+
+    if ((err = dw_pcie_ep_init(&pci->endpoint)))
+    {
+        LOG_E("Init EP error = %s", rt_strerror(err));
+        return err;
+    }
+
+    rockchip_pcie_ep_setup_bottom(rk_pcie);
+
+    if ((err = rockchip_pcie_ep_atu_init(rk_pcie)))
+    {
+        LOG_E("Init EP ATU error = %s", rt_strerror(err));
+        return err;
+    }
+
+    if ((err = rockchip_pcie_establish_link_raw(rk_pcie)))
+    {
+        LOG_E("Establish pcie link error = %s", rt_strerror(err));
+        return err;
+    }
+
+    if (!rockchip_pcie_udma_enabled(rk_pcie))
+    {
+        goto _end;
+    }
+
+    /* Init uDMA here */
+
+_end:
+    return RT_EOK;
+}
+
+#ifdef RT_USING_PM
+static int rockchip_dw_pcie_pm_suspend(const struct rt_device *device, rt_uint8_t mode)
+{
+    rt_err_t err;
+    rt_uint32_t status;
+    struct rockchip_pcie *rk_pcie = device->user_data;
+    struct dw_pcie *pci = &rk_pcie->pci;
+
+    /*
+     * This is as per PCI Express Base r5.0 r1.0 May 22-2019,
+     * 5.2 Link State Power Management (Page #440).
+     *
+     * L2/L3 Ready entry negotiations happen while in the L0 state.
+     * L2/L3 Ready are entered only after the negotiation completes.
+     *
+     * The following example sequence illustrates the multi-step Link state
+     * transition process leading up to entering a system sleep state:
+     * 1. System software directs all Functions of
+     *    a Downstream component to D3Hot.
+     * 2. The Downstream component then initiates the transition of the
+     *    Link to L1 as required.
+     * 3. System software then causes the Root Complex to broadcast the
+     *    PME_TURN_OFF Message in preparation for removing the main power source.
+     * 4. This Message causes the subject Link to transition back to L0
+     *    in order to send it and to enable the Downstream component to
+     *    respond with PME_TO_Ack.
+     * 5. After sending the PME_TO_Ack, the Downstream component initiates the
+     *    L2/L3 Ready transition protocol.
+     */
+
+    /* 1. All sub-devices are in D3hot by PCIe stack */
+    dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE);
+
+    rockchip_pcie_link_status_clear(rk_pcie);
+
+    /*
+     * Wlan devices will be shutdown from function driver now, so doing L2 here
+     * must fail. Skip L2 routine.
+     */
+    if (rk_pcie->skip_scan_in_resume)
+    {
+        /* Check WiFi power state here. If down, goto the label "_no_l2" */
+    }
+
+    /* 2. Broadcast PME_Turn_Off Message */
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_MSG_GEN, PME_TURN_OFF);
+    err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_MSG_GEN,
+            status, !(status & RT_BIT(4)), 20, RK_PCIE_L2_TMOUT_US);
+    if (err)
+    {
+        LOG_E("Failed to send PME_TURN_OFF");
+        goto _no_l2;
+    }
+
+    /* 3. Wait for PME_TO_Ack */
+    err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_INTR_STATUS_MSG_RX,
+            status, status & RT_BIT(9), 20, RK_PCIE_L2_TMOUT_US);
+    if (err)
+    {
+        LOG_E("Failed to receive PME_TO_ACK");
+        goto _no_l2;
+    }
+
+    /* 4. Clear PME_TO_Ack and Wait for ready to enter L23 message */
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MSG_RX, PME_TO_ACK);
+    err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_POWER,
+            status, status & READY_ENTER_L23, 20, RK_PCIE_L2_TMOUT_US);
+    if (err)
+    {
+        LOG_E("Failed to ready to enter L23");
+        goto _no_l2;
+    }
+
+    /* 5. Check we are in L2 */
+    err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS,
+            status, ((status & S_MAX) == S_L2_IDLE), 20, RK_PCIE_L2_TMOUT_US);
+    if (err)
+    {
+        LOG_E("Link isn't in L2 idle");
+    }
+
+_no_l2:
+    rockchip_pcie_disable_ltssm(rk_pcie);
+
+    /* make sure assert phy success */
+    rt_hw_us_delay(250);
+
+    rt_phye_power_off(rk_pcie->phy);
+    rt_phye_exit(rk_pcie->phy);
+
+    rk_pcie->intx = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY);
+
+    rt_clk_array_disable_unprepare(rk_pcie->clk_arr);
+
+    rk_pcie->in_suspend = RT_TRUE;
+
+    rt_pin_write(rk_pcie->rst_pin, !rk_pcie->rst_active_val);
+
+    return rockchip_pcie_disable_power(rk_pcie);
+}
+
+static void rockchip_dw_pcie_pm_resume(const struct rt_device *device, rt_uint8_t mode)
+{
+    rt_err_t err;
+    rt_bool_t std_rc;
+    struct rockchip_pcie *rk_pcie = device->user_data;
+    struct dw_pcie *pci = &rk_pcie->pci;
+
+    std_rc = rk_pcie->soc_data->mode == DW_PCIE_RC_TYPE;
+
+    rt_reset_control_assert(rk_pcie->rstc);
+    rt_hw_us_delay(10);
+    rt_reset_control_deassert(rk_pcie->rstc);
+
+    if ((err = rockchip_pcie_enable_power(rk_pcie)))
+    {
+        LOG_E("Enable PCIe power error = %s", rt_strerror(err));
+        return;
+    }
+
+    if ((err = rt_clk_array_prepare_enable(rk_pcie->clk_arr)))
+    {
+        LOG_E("Prepare enable PCIe clks error = %s", rt_strerror(err));
+        return;
+    }
+
+    if ((err = rt_phye_set_mode(rk_pcie->phy, rk_pcie->phy_mode, rk_pcie->phy_submode)))
+    {
+        LOG_E("Set PHY to mode %s error = %s",
+                (rk_pcie->phy_submode == RT_PHYE_MODE_PCIE_RC) ? "RC" : "EP",
+                rt_strerror(err));
+        return;
+    }
+
+    if ((err = rt_phye_init(rk_pcie->phy)))
+    {
+        LOG_E("Init PHY error = %s", rt_strerror(err));
+        return;
+    }
+
+    rt_phye_power_on(rk_pcie->phy);
+
+    dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE);
+
+    if (rk_pcie->soc_data->type == SOC_TYPE_RK1808)
+    {
+        /* Release link reset grant */
+        if (rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_TRUE))
+        {
+            return;
+        }
+    }
+    else
+    {
+        rockchip_pcie_fast_link_setup(rk_pcie);
+    }
+
+    /* Set PCIe mode */
+    rockchip_pcie_set_mode(rk_pcie);
+
+    if (std_rc)
+    {
+        dw_pcie_setup_rc(&pci->port);
+    }
+
+    rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY,
+            rk_pcie->intx | 0xffff0000);
+
+    if ((err = rockchip_pcie_establish_link_raw(rk_pcie)))
+    {
+        LOG_E("Establish PCIe link error = %s", rt_strerror(err));
+        goto _err;
+    }
+
+    if (std_rc)
+    {
+        goto _std_rc_done;
+    }
+
+    if ((err = rockchip_pcie_ep_atu_init(rk_pcie)))
+    {
+        LOG_E("Init EP device error = %s", rt_strerror(err));
+        goto _err;
+    }
+
+    rockchip_pcie_ep_setup_top(rk_pcie);
+    dw_pcie_setup(pci);
+    rockchip_pcie_ep_setup_bottom(rk_pcie);
+
+    rk_pcie->in_suspend = RT_FALSE;
+
+_std_rc_done:
+    dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE);
+    /* hold link reset grant after link-up */
+    if (rk_pcie->soc_data->type == SOC_TYPE_RK1808)
+    {
+        if ((err = rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_FALSE)))
+        {
+            goto _err;
+        }
+    }
+
+    if (pci->port.msi_irq > 0)
+    {
+        dw_pcie_msi_init(&pci->port);
+    }
+
+    return;
+
+_err:
+    rockchip_pcie_disable_power(rk_pcie);
+}
+
+static const struct rt_device_pm_ops rockchip_dw_pcie_pm_ops =
+{
+    .suspend = rockchip_dw_pcie_pm_suspend,
+    .resume = rockchip_dw_pcie_pm_resume,
+};
+#endif /* RT_USING_PM */
+
+static rt_err_t rockchip_pcie_phy_init(struct rockchip_pcie *rk_pcie)
+{
+    rt_err_t err;
+    struct rt_device *dev = rk_pcie->pci.dev;
+
+    rk_pcie->phy = rt_phye_get_by_name(dev, "pcie-phy");
+    if (rt_is_err(rk_pcie->phy))
+    {
+        LOG_E("Missing PHY");
+        return rt_ptr_err(rk_pcie->phy);
+    }
+
+    switch (rk_pcie->soc_data->mode)
+    {
+    case DW_PCIE_RC_TYPE:
+        rk_pcie->phy_mode = RT_PHYE_MODE_PCIE;
+        rk_pcie->phy_submode = RT_PHYE_MODE_PCIE_RC;
+        break;
+
+    case DW_PCIE_EP_TYPE:
+        rk_pcie->phy_mode = RT_PHYE_MODE_PCIE;
+        rk_pcie->phy_submode = RT_PHYE_MODE_PCIE_EP;
+        break;
+
+    default:
+        break;
+    }
+
+    if ((err = rt_phye_set_mode(rk_pcie->phy, rk_pcie->phy_mode, rk_pcie->phy_submode)))
+    {
+        LOG_E("Fail to set PHY to mode %s",
+                (rk_pcie->phy_submode == RT_PHYE_MODE_PCIE_RC) ? "RC" : "EP");
+
+        rk_pcie->phy = RT_NULL;
+        return err;
+    }
+
+    if (rk_pcie->bifurcation)
+    {
+        rt_phye_set_mode(rk_pcie->phy, rk_pcie->phy_mode, RT_PHYE_MODE_PCIE_BIFURCATION);
+    }
+
+    if ((err = rt_phye_init(rk_pcie->phy)))
+    {
+        LOG_E("Init PHY fail");
+
+        rk_pcie->phy = RT_NULL;
+        return err;
+    }
+
+    rt_phye_power_on(rk_pcie->phy);
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_pcie_fixup_rk1808(struct rockchip_pcie *rk_pcie)
+{
+    rt_err_t err;
+    struct rt_ofw_node *np = rk_pcie->pci.dev->ofw_node;
+
+    rk_pcie->usb_pcie_grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,usbpciegrf");
+    if (!rk_pcie->usb_pcie_grf)
+    {
+        LOG_E("Failed to find %s regmap", "usb_pcie_grf");
+        return -RT_EIO;
+    }
+
+    rk_pcie->pmu_grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,pmugrf");
+    if (!rk_pcie->pmu_grf)
+    {
+        LOG_E("Failed to find %s regmap", "pmugrf");
+        return -RT_EIO;
+    }
+
+    /* Workaround for pcie, switch to PCIe_PRSTNm0 */
+    if ((err = rt_syscon_write(rk_pcie->pmu_grf, 0x100, 0x01000100)))
+    {
+        return err;
+    }
+
+    if ((err = rt_syscon_write(rk_pcie->pmu_grf, 0x0, 0x0c000000)))
+    {
+        return err;
+    }
+
+    /* Release link reset grant */
+    return rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_TRUE);
+}
+
+static void rockchip_pcie_free(struct rockchip_pcie *rk_pcie)
+{
+    if (rk_pcie->pci.dbi_base)
+    {
+        rt_iounmap(rk_pcie->pci.dbi_base);
+    }
+
+    if (rk_pcie->apb_base)
+    {
+        rt_iounmap(rk_pcie->apb_base);
+    }
+
+    if (!rt_is_err_or_null(rk_pcie->clk_arr))
+    {
+        rt_clk_array_disable_unprepare(rk_pcie->clk_arr);
+        rt_clk_array_put(rk_pcie->clk_arr);
+    }
+
+    if (!rt_is_err_or_null(rk_pcie->rstc))
+    {
+        rt_reset_control_assert(rk_pcie->rstc);
+        rt_reset_control_put(rk_pcie->rstc);
+    }
+
+    if (!rt_is_err_or_null(rk_pcie->phy))
+    {
+        rt_phye_power_off(rk_pcie->phy);
+        rt_phye_exit(rk_pcie->phy);
+        rt_phye_put(rk_pcie->phy);
+    }
+
+    if (!rt_is_err_or_null(rk_pcie->vpcie3v3))
+    {
+        rt_regulator_disable(rk_pcie->vpcie3v3);
+    }
+
+    rt_free(rk_pcie);
+}
+
+static void rockchip_pcie_free_irq(struct rockchip_pcie *rk_pcie)
+{
+    if (rk_pcie->intx_np)
+    {
+        rt_ofw_data(rk_pcie->intx_np) = RT_NULL;
+
+        rt_pic_cancel_irq(&rk_pcie->intx_pic);
+
+        rt_hw_interrupt_mask(rk_pcie->intx_irq);
+        rt_pic_detach_irq(rk_pcie->intx_irq, rk_pcie);
+    }
+
+    rt_hw_interrupt_mask(rk_pcie->pci.port.sys_irq);
+    rt_pic_detach_irq(rk_pcie->pci.port.sys_irq, rk_pcie);
+}
+
+static rt_err_t rockchip_pcie_dw_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    rt_uint32_t val;
+    rt_uint8_t pmode;
+    struct dw_pcie *pci;
+    struct dw_pcie_port *port;
+    struct rt_device *dev = &pdev->parent;
+    struct rt_ofw_node *np = dev->ofw_node, *intx_np;
+    struct rockchip_pcie *rk_pcie = rt_calloc(1, sizeof(*rk_pcie));
+
+    if (!rk_pcie)
+    {
+        return -RT_EINVAL;
+    }
+
+    rk_pcie->soc_data = pdev->id->data;
+    rk_pcie->intx_irq = -RT_EEMPTY;
+
+    pci = &rk_pcie->pci;
+    pci->dev = dev;
+    pci->ops = &dw_pcie_ops;
+    pci->priv = rk_pcie;
+
+    port = &pci->port;
+    port->irq_count = rk_pcie->soc_data->msi_vector_num;
+
+    rk_pcie->bifurcation = rt_dm_dev_prop_read_bool(dev, "rockchip,bifurcation");
+
+    pci->dbi_base = rt_dm_dev_iomap_by_name(dev, "pcie-dbi");
+    if (!pci->dbi_base)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+    pci->dbi_base2 = pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET;
+
+    rk_pcie->apb_base = rt_dm_dev_iomap_by_name(dev, "pcie-apb");
+    if (!rk_pcie->apb_base)
+    {
+        err = -RT_EIO;
+        goto _fail;
+    }
+
+    rk_pcie->rst_pin = rt_pin_get_named_pin(dev, "reset", 0,
+            RT_NULL, &rk_pcie->rst_active_val);
+    if (rk_pcie->rst_pin < 0 && rk_pcie->rst_pin != PIN_NONE)
+    {
+        err = (rt_err_t)rk_pcie->rst_pin;
+        goto _fail;
+    }
+
+    rk_pcie->prsnt_pin = rt_pin_get_named_pin(dev, "prsnt", 0,
+            &pmode, &rk_pcie->prsnt_active_val);
+    if (rk_pcie->prsnt_pin >= 0)
+    {
+        rt_pin_mode(rk_pcie->prsnt_pin, pmode);
+
+        if (rt_pin_read(rk_pcie->prsnt_pin) != rk_pcie->prsnt_active_val)
+        {
+            /* No device */
+            err = -RT_EINVAL;
+            goto _fail;
+        }
+    }
+    else if (rk_pcie->prsnt_pin != PIN_NONE)
+    {
+        LOG_I("Invalid prsnt-gpios");
+    }
+
+    rt_pin_write(rk_pcie->rst_pin, !rk_pcie->rst_active_val);
+    rt_pin_mode(rk_pcie->rst_pin, PIN_MODE_OUTPUT);
+
+    if (rt_dm_dev_prop_read_u32(dev, "rockchip,perst-inactive-ms",
+            &rk_pcie->perst_inactive_ms))
+    {
+        rk_pcie->perst_inactive_ms = 200;
+    }
+
+    rk_pcie->supports_clkreq = rt_dm_dev_prop_read_bool(dev, "supports-clkreq");
+
+    rk_pcie->vpcie3v3 = rt_regulator_get(dev, "vpcie3v3");
+
+    if (rt_is_err(rk_pcie->vpcie3v3))
+    {
+        err = rt_ptr_err(rk_pcie->vpcie3v3);
+        goto _fail;
+    }
+
+    if ((err = rockchip_pcie_enable_power(rk_pcie)))
+    {
+        goto _fail;
+    }
+
+    if ((err = rockchip_pcie_phy_init(rk_pcie)))
+    {
+        goto _fail;
+    }
+
+    rk_pcie->rstc = rt_reset_control_get_array(dev);
+
+    if (rt_is_err(rk_pcie->rstc))
+    {
+        err = rt_ptr_err(rk_pcie->rstc);
+        goto _fail;
+    }
+    rt_reset_control_deassert(rk_pcie->rstc);
+
+    rk_pcie->clk_arr = rt_clk_get_array(dev);
+
+    if (rt_is_err(rk_pcie->clk_arr))
+    {
+        err = rt_ptr_err(rk_pcie->clk_arr);
+        goto _fail;
+    }
+
+    if ((err = rt_clk_array_prepare_enable(rk_pcie->clk_arr)))
+    {
+        goto _fail;
+    }
+
+    dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE);
+
+    if (rk_pcie->soc_data->type == SOC_TYPE_RK1808)
+    {
+        if ((err = rockchip_pcie_fixup_rk1808(rk_pcie)))
+        {
+            goto _fail;
+        }
+    }
+    else
+    {
+        rockchip_pcie_fast_link_setup(rk_pcie);
+    }
+
+    rockchip_pcie_set_mode(rk_pcie);
+
+    /* Force into loopback master mode */
+    if (rt_dm_dev_prop_read_bool(dev, "rockchip,lpbk-master"))
+    {
+        val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL);
+        val |= PORT_LINK_LPBK_ENABLE;
+        dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val);
+        rk_pcie->is_signal_test = RT_TRUE;
+    }
+
+    /*
+     * Force into compliance mode
+     * comp_prst is a two dimensional array of which the first element
+     * stands for speed mode, and the second one is preset value encoding:
+     *  [0] 0->SMA tool control the signal switch,
+     *      1/2/3 is for manual Gen setting
+     *  [1] transmitter setting for manual Gen setting,
+     *      valid only if [0] isn't zero.
+     */
+    if (rt_dm_dev_prop_read_u32_array_index(dev, "rockchip,compliance-mode",
+            0, 2, rk_pcie->comp_prst) > 0)
+    {
+        if (!rk_pcie->comp_prst[0])
+        {
+            LOG_I("Auto compliance mode for SMA tool");
+        }
+        else
+        {
+            LOG_I("Compliance mode for soldered board Gen%d, P%d",
+                    rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]);
+
+            val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS);
+            val |= RT_BIT(4) | rk_pcie->comp_prst[0] | (rk_pcie->comp_prst[1] << 12);
+            dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val);
+        }
+        rk_pcie->is_signal_test = RT_TRUE;
+    }
+
+    /* Skip waiting for training to pass in system PM routine */
+    if (rt_dm_dev_prop_read_bool(dev, "rockchip,skip-scan-in-resume"))
+    {
+        rk_pcie->skip_scan_in_resume = RT_TRUE;
+    }
+
+    port->sys_irq = rt_dm_dev_get_irq_by_name(dev, "sys");
+
+    if (port->sys_irq < 0)
+    {
+        err = port->sys_irq;
+        goto _fail;
+    }
+
+    rk_pcie->intx_irq = rt_dm_dev_get_irq_by_name(dev, "legacy");
+
+    if (rk_pcie->intx_irq >= 0)
+    {
+        /* Legacy (INTx) init */
+        if (!(intx_np = rt_ofw_get_child_by_tag(np, "legacy-interrupt-controller")))
+        {
+            LOG_E("INTx ofw node not found");
+
+            err = -RT_EIO;
+            goto _fail;
+        }
+
+        rk_pcie->intx_np = intx_np;
+        rk_pcie->intx_pic.priv_data = rk_pcie;
+        rk_pcie->intx_pic.ops = &rockchip_intx_ops;
+        rt_pic_linear_irq(&rk_pcie->intx_pic, RT_PCI_INTX_PIN_MAX);
+        rt_pic_user_extends(&rk_pcie->intx_pic);
+        rt_ofw_data(intx_np) = &rk_pcie->intx_pic;
+        rt_ofw_node_put(intx_np);
+
+        rt_hw_interrupt_install(rk_pcie->intx_irq, rockchip_pcie_legacy_isr, rk_pcie, "rk-pcie-legacy");
+        rt_hw_interrupt_umask(rk_pcie->intx_irq);
+    }
+    else
+    {
+        LOG_D("Missing legacy IRQ");
+    }
+
+    rt_hw_interrupt_install(port->sys_irq, rockchip_pcie_sys_isr, rk_pcie, "rk-pcie-sys");
+    rt_hw_interrupt_umask(port->sys_irq);
+
+    rt_work_init(&rk_pcie->hot_rst_work, rockchip_pcie_hot_rst_work, rk_pcie);
+
+    switch (rk_pcie->soc_data->mode)
+    {
+    case DW_PCIE_RC_TYPE:
+        err = rockchip_pcie_add_port(rk_pcie);
+        break;
+
+    case DW_PCIE_EP_TYPE:
+        err = rockchip_pcie_add_endpoint(rk_pcie);
+        break;
+
+    default:
+        /* It's impossible */
+        RT_ASSERT(0);
+        break;
+    }
+
+    if (rk_pcie->is_signal_test)
+    {
+        goto _end;
+    }
+
+    if (err)
+    {
+        goto _free_irq;
+    }
+
+    if (rk_pcie->soc_data->type == SOC_TYPE_RK1808)
+    {
+        /* Hold link reset grant after link-up */
+        if ((err = rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_FALSE)))
+        {
+            goto _free_irq;
+        }
+    }
+
+_end:
+    dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE);
+
+#ifdef RT_USING_PM
+    rt_pm_device_register(dev, &rockchip_dw_pcie_pm_ops);
+#endif
+
+    dev->user_data = rk_pcie;
+
+    return RT_EOK;
+
+_free_irq:
+    rockchip_pcie_free_irq(rk_pcie);
+
+_fail:
+    rockchip_pcie_free(rk_pcie);
+
+    return err;
+}
+
+static rt_err_t rockchip_pcie_dw_remove(struct rt_platform_device *pdev)
+{
+    struct rockchip_pcie *rk_pcie = pdev->parent.user_data;
+
+#ifdef RT_USING_PM
+    rt_pm_device_unregister(&pdev->parent);
+#endif
+
+    if (rk_pcie->pci.port.bridge)
+    {
+        rt_pci_host_bridge_remove(rk_pcie->pci.port.bridge);
+    }
+    dw_pcie_host_free(&rk_pcie->pci.port);
+
+    rockchip_pcie_free_irq(rk_pcie);
+
+    rockchip_pcie_free(rk_pcie);
+
+    return RT_EOK;
+}
+
+static const struct rockchip_pcie_soc_data rk_pcie_rc_soc_data =
+{
+    .mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct rockchip_pcie_soc_data rk_pcie_ep_soc_data =
+{
+    .mode = DW_PCIE_EP_TYPE,
+};
+
+static const struct rockchip_pcie_soc_data rk1808_pcie_rc_soc_data =
+{
+    .type = SOC_TYPE_RK1808,
+    .mode = DW_PCIE_RC_TYPE,
+};
+
+static const struct rockchip_pcie_soc_data rk1808_pcie_ep_soc_data =
+{
+    .type = SOC_TYPE_RK1808,
+    .mode = DW_PCIE_EP_TYPE,
+};
+
+static const struct rockchip_pcie_soc_data rk3528_pcie_rc_soc_data =
+{
+    .mode = DW_PCIE_RC_TYPE,
+    .msi_vector_num = 8,
+};
+
+static const struct rt_ofw_node_id rockchip_pcie_dw_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk1808-pcie",     .data = &rk1808_pcie_rc_soc_data, },
+    { .compatible = "rockchip,rk1808-pcie-ep",  .data = &rk1808_pcie_ep_soc_data, },
+    { .compatible = "rockchip,rk3528-pcie",     .data = &rk3528_pcie_rc_soc_data, },
+    { .compatible = "rockchip,rk3562-pcie",     .data = &rk3528_pcie_rc_soc_data, },
+    { .compatible = "rockchip,rk3568-pcie",     .data = &rk_pcie_rc_soc_data, },
+    { .compatible = "rockchip,rk3568-pcie-ep",  .data = &rk_pcie_ep_soc_data, },
+    { .compatible = "rockchip,rk3576-pcie",     .data = &rk3528_pcie_rc_soc_data, },
+    { .compatible = "rockchip,rk3588-pcie",     .data = &rk_pcie_rc_soc_data, },
+    { .compatible = "rockchip,rk3588-pcie-ep",  .data = &rk_pcie_ep_soc_data, },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_pcie_dw_driver =
+{
+    .name = "dw-pcie-rockchip",
+    .ids = rockchip_pcie_dw_ofw_ids,
+
+    .probe = rockchip_pcie_dw_probe,
+    .remove = rockchip_pcie_dw_remove,
+};
+RT_PLATFORM_DRIVER_EXPORT(rockchip_pcie_dw_driver);

Неке датотеке нису приказане због велике количине промена