浏览代码

[dm2.0] add new bsp for rk platform

zhujiale 6 月之前
父节点
当前提交
1572a44055
共有 42 个文件被更改,包括 17198 次插入0 次删除
  1. 1492 0
      bsp/rockchip/rk3500/.config
  2. 31 0
      bsp/rockchip/rk3500/Kconfig
  3. 75 0
      bsp/rockchip/rk3500/README.md
  4. 14 0
      bsp/rockchip/rk3500/SConscript
  5. 29 0
      bsp/rockchip/rk3500/SConstruct
  6. 14 0
      bsp/rockchip/rk3500/applications/SConscript
  7. 18 0
      bsp/rockchip/rk3500/applications/main.c
  8. 7 0
      bsp/rockchip/rk3500/driver/Kconfig
  9. 19 0
      bsp/rockchip/rk3500/driver/SConscript
  10. 37 0
      bsp/rockchip/rk3500/driver/board.c
  11. 25 0
      bsp/rockchip/rk3500/driver/board.h
  12. 15 0
      bsp/rockchip/rk3500/driver/clk/Kconfig
  13. 16 0
      bsp/rockchip/rk3500/driver/clk/SConscript
  14. 123 0
      bsp/rockchip/rk3500/driver/clk/clk-mmc-phase.c
  15. 403 0
      bsp/rockchip/rk3500/driver/clk/clk-pll-rk3568.c
  16. 727 0
      bsp/rockchip/rk3500/driver/clk/clk-pll-rk3588.c
  17. 4800 0
      bsp/rockchip/rk3500/driver/clk/clk-rk3568.c
  18. 117 0
      bsp/rockchip/rk3500/driver/clk/clk-rk3568.h
  19. 3286 0
      bsp/rockchip/rk3500/driver/clk/clk-rk3588.c
  20. 152 0
      bsp/rockchip/rk3500/driver/clk/clk-rk3588.h
  21. 926 0
      bsp/rockchip/rk3500/driver/clk/rk3568-cru.h
  22. 1497 0
      bsp/rockchip/rk3500/driver/clk/rk3588-cru.h
  23. 110 0
      bsp/rockchip/rk3500/driver/clk/softrst.c
  24. 5 0
      bsp/rockchip/rk3500/driver/hwtimer/Kconfig
  25. 13 0
      bsp/rockchip/rk3500/driver/hwtimer/SConscript
  26. 393 0
      bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c
  27. 5 0
      bsp/rockchip/rk3500/driver/reset/Kconfig
  28. 13 0
      bsp/rockchip/rk3500/driver/reset/SConscript
  29. 429 0
      bsp/rockchip/rk3500/driver/reset/reset.c
  30. 92 0
      bsp/rockchip/rk3500/driver/reset/reset.h
  31. 22 0
      bsp/rockchip/rk3500/driver/rockchip.h
  32. 341 0
      bsp/rockchip/rk3500/driver/uart8250/8250-dw.c
  33. 74 0
      bsp/rockchip/rk3500/driver/uart8250/8250.h
  34. 3 0
      bsp/rockchip/rk3500/driver/uart8250/Kconfig
  35. 13 0
      bsp/rockchip/rk3500/driver/uart8250/SConscript
  36. 303 0
      bsp/rockchip/rk3500/driver/uart8250/core.c
  37. 162 0
      bsp/rockchip/rk3500/driver/uart8250/early.c
  38. 378 0
      bsp/rockchip/rk3500/driver/uart8250/fiq-debugger.c
  39. 365 0
      bsp/rockchip/rk3500/driver/uart8250/regs.h
  40. 29 0
      bsp/rockchip/rk3500/driver/uart8250/serial_dm.h
  41. 568 0
      bsp/rockchip/rk3500/rtconfig.h
  42. 57 0
      bsp/rockchip/rk3500/rtconfig.py

+ 1492 - 0
bsp/rockchip/rk3500/.config

@@ -0,0 +1,1492 @@
+
+#
+# RT-Thread Kernel
+#
+CONFIG_RT_NAME_MAX=8
+# CONFIG_RT_USING_ARCH_DATA_TYPE is not set
+CONFIG_RT_USING_SMART=y
+# CONFIG_RT_USING_NANO is not set
+# CONFIG_RT_USING_AMP is not set
+CONFIG_RT_USING_SMP=y
+CONFIG_RT_CPUS_NR=4
+CONFIG_RT_ALIGN_SIZE=8
+# CONFIG_RT_THREAD_PRIORITY_8 is not set
+CONFIG_RT_THREAD_PRIORITY_32=y
+# CONFIG_RT_THREAD_PRIORITY_256 is not set
+CONFIG_RT_THREAD_PRIORITY_MAX=32
+CONFIG_RT_TICK_PER_SECOND=1000
+CONFIG_RT_USING_HOOK=y
+CONFIG_RT_HOOK_USING_FUNC_PTR=y
+CONFIG_RT_USING_HOOKLIST=y
+CONFIG_RT_USING_IDLE_HOOK=y
+CONFIG_RT_IDLE_HOOK_LIST_SIZE=4
+CONFIG_IDLE_THREAD_STACK_SIZE=16384
+CONFIG_SYSTEM_THREAD_STACK_SIZE=16384
+CONFIG_RT_USING_TIMER_SOFT=y
+CONFIG_RT_TIMER_THREAD_PRIO=4
+CONFIG_RT_TIMER_THREAD_STACK_SIZE=32768
+CONFIG_RT_USING_TIMER_ALL_SOFT=y
+CONFIG_RT_USING_CPU_USAGE_TRACER=y
+
+#
+# kservice optimization
+#
+# CONFIG_RT_USING_TINY_FFS is not set
+# end of kservice optimization
+
+#
+# klibc optimization
+#
+# CONFIG_RT_KLIBC_USING_STDLIB is not set
+# CONFIG_RT_KLIBC_USING_TINY_SIZE is not set
+CONFIG_RT_KLIBC_USING_PRINTF_LONGLONG=y
+# end of klibc optimization
+
+CONFIG_RT_USING_DEBUG=y
+# CONFIG_RT_DEBUGING_ASSERT is not set
+CONFIG_RT_DEBUGING_COLOR=y
+# CONFIG_RT_DEBUGING_CONTEXT is not set
+# CONFIG_RT_DEBUGING_AUTO_INIT is not set
+# CONFIG_RT_DEBUGING_PAGE_LEAK is not set
+# CONFIG_RT_DEBUGING_SPINLOCK is not set
+# CONFIG_RT_DEBUGING_CRITICAL is not set
+# CONFIG_RT_USING_OVERFLOW_CHECK is not set
+
+#
+# Inter-Thread communication
+#
+CONFIG_RT_USING_SEMAPHORE=y
+CONFIG_RT_USING_MUTEX=y
+CONFIG_RT_USING_EVENT=y
+CONFIG_RT_USING_MAILBOX=y
+CONFIG_RT_USING_MESSAGEQUEUE=y
+CONFIG_RT_USING_MESSAGEQUEUE_PRIORITY=y
+# CONFIG_RT_USING_SIGNALS is not set
+# end of Inter-Thread communication
+
+#
+# Memory Management
+#
+CONFIG_RT_PAGE_MAX_ORDER=11
+# CONFIG_RT_USING_MEMPOOL is not set
+# CONFIG_RT_USING_SMALL_MEM is not set
+CONFIG_RT_USING_SLAB=y
+CONFIG_RT_USING_MEMHEAP=y
+CONFIG_RT_MEMHEAP_FAST_MODE=y
+# CONFIG_RT_MEMHEAP_BEST_MODE is not set
+# CONFIG_RT_USING_SMALL_MEM_AS_HEAP is not set
+CONFIG_RT_USING_MEMHEAP_AS_HEAP=y
+CONFIG_RT_USING_MEMHEAP_AUTO_BINDING=y
+# CONFIG_RT_USING_SLAB_AS_HEAP is not set
+# CONFIG_RT_USING_USERHEAP is not set
+# CONFIG_RT_USING_NOHEAP is not set
+# CONFIG_RT_USING_MEMTRACE is not set
+# CONFIG_RT_USING_HEAP_ISR is not set
+CONFIG_RT_USING_HEAP=y
+# end of Memory Management
+
+CONFIG_RT_USING_DEVICE=y
+CONFIG_RT_USING_DEVICE_OPS=y
+# CONFIG_RT_USING_INTERRUPT_INFO is not set
+CONFIG_RT_USING_THREADSAFE_PRINTF=y
+CONFIG_RT_USING_CONSOLE=y
+CONFIG_RT_CONSOLEBUF_SIZE=1024
+CONFIG_RT_CONSOLE_DEVICE_NAME="uart2"
+CONFIG_RT_VER_NUM=0x50200
+CONFIG_RT_USING_STDC_ATOMIC=y
+CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32
+# end of RT-Thread Kernel
+
+#
+# AArch64 Architecture Configuration
+#
+CONFIG_ARCH_TEXT_OFFSET=0x00480000
+CONFIG_ARCH_RAM_OFFSET=0x200000
+CONFIG_ARCH_SECONDARY_CPU_STACK_SIZE=16384
+CONFIG_ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
+CONFIG_ARCH_USING_GENERIC_CPUID=y
+CONFIG_ARCH_HEAP_SIZE=0x4000000
+CONFIG_ARCH_INIT_PAGE_SIZE=0x200000
+# end of AArch64 Architecture Configuration
+
+CONFIG_ARCH_CPU_64BIT=y
+CONFIG_RT_USING_CACHE=y
+CONFIG_ARCH_ARM_BOOTWITH_FLUSH_CACHE=y
+CONFIG_RT_USING_CPU_FFS=y
+CONFIG_ARCH_MM_MMU=y
+CONFIG_ARCH_ARM=y
+CONFIG_ARCH_ARM_MMU=y
+CONFIG_KERNEL_VADDR_START=0xffff000000000000
+CONFIG_ARCH_ARMV8=y
+CONFIG_ARCH_USING_HW_THREAD_SELF=y
+CONFIG_ARCH_USING_IRQ_CTX_LIST=y
+
+#
+# RT-Thread Components
+#
+CONFIG_RT_USING_COMPONENTS_INIT=y
+CONFIG_RT_USING_USER_MAIN=y
+CONFIG_RT_MAIN_THREAD_STACK_SIZE=16384
+CONFIG_RT_MAIN_THREAD_PRIORITY=10
+# CONFIG_RT_USING_LEGACY is not set
+CONFIG_RT_USING_MSH=y
+CONFIG_RT_USING_FINSH=y
+CONFIG_FINSH_USING_MSH=y
+CONFIG_FINSH_THREAD_NAME="tshell"
+CONFIG_FINSH_THREAD_PRIORITY=20
+CONFIG_FINSH_THREAD_STACK_SIZE=16384
+CONFIG_FINSH_USING_HISTORY=y
+CONFIG_FINSH_HISTORY_LINES=5
+CONFIG_FINSH_USING_SYMTAB=y
+CONFIG_FINSH_CMD_SIZE=80
+CONFIG_MSH_USING_BUILT_IN_COMMANDS=y
+CONFIG_FINSH_USING_DESCRIPTION=y
+# CONFIG_FINSH_ECHO_DISABLE_DEFAULT is not set
+# CONFIG_FINSH_USING_AUTH is not set
+CONFIG_FINSH_ARG_MAX=10
+CONFIG_FINSH_USING_OPTION_COMPLETION=y
+
+#
+# DFS: device virtual file system
+#
+CONFIG_RT_USING_DFS=y
+CONFIG_DFS_USING_POSIX=y
+CONFIG_DFS_USING_WORKDIR=y
+CONFIG_DFS_FD_MAX=512
+CONFIG_RT_USING_DFS_V2=y
+# CONFIG_RT_USING_DFS_ELMFAT is not set
+CONFIG_RT_USING_DFS_DEVFS=y
+# CONFIG_RT_USING_DFS_ROMFS is not set
+CONFIG_RT_USING_DFS_PTYFS=y
+CONFIG_RT_USING_DFS_CROMFS=y
+CONFIG_RT_USING_DFS_TMPFS=y
+CONFIG_RT_USING_DFS_MQUEUE=y
+CONFIG_RT_USING_PAGECACHE=y
+
+#
+# page cache config
+#
+CONFIG_RT_PAGECACHE_COUNT=128
+CONFIG_RT_PAGECACHE_ASPACE_COUNT=32
+CONFIG_RT_PAGECACHE_PRELOAD=4
+CONFIG_RT_PAGECACHE_HASH_NR=180
+CONFIG_RT_PAGECACHE_GC_WORK_LEVEL=90
+CONFIG_RT_PAGECACHE_GC_STOP_LEVEL=70
+# end of page cache config
+# end of DFS: device virtual file system
+
+# CONFIG_RT_USING_FAL is not set
+
+#
+# Device Drivers
+#
+CONFIG_RT_USING_DM=y
+CONFIG_RT_USING_DEV_BUS=y
+CONFIG_RT_USING_DEVICE_IPC=y
+CONFIG_RT_UNAMED_PIPE_NUMBER=64
+CONFIG_RT_USING_SYSTEM_WORKQUEUE=y
+CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=16384
+CONFIG_RT_SYSTEM_WORKQUEUE_PRIORITY=23
+CONFIG_RT_USING_SERIAL=y
+CONFIG_RT_USING_SERIAL_V1=y
+# CONFIG_RT_USING_SERIAL_V2 is not set
+# CONFIG_RT_SERIAL_USING_DMA is not set
+CONFIG_RT_SERIAL_RB_BUFSZ=64
+# CONFIG_RT_USING_CAN is not set
+# CONFIG_RT_USING_CPUTIME is not set
+# CONFIG_RT_USING_I2C is not set
+# CONFIG_RT_USING_PHY is not set
+# CONFIG_RT_USING_ADC is not set
+# CONFIG_RT_USING_DAC is not set
+CONFIG_RT_USING_NULL=y
+CONFIG_RT_USING_ZERO=y
+CONFIG_RT_USING_RANDOM=y
+# CONFIG_RT_USING_PWM is not set
+# CONFIG_RT_USING_PULSE_ENCODER is not set
+# CONFIG_RT_USING_INPUT_CAPTURE is not set
+# CONFIG_RT_USING_MTD_NOR is not set
+# CONFIG_RT_USING_MTD_NAND is not set
+# CONFIG_RT_USING_PM is not set
+CONFIG_RT_USING_RTC=y
+# CONFIG_RT_USING_ALARM is not set
+CONFIG_RT_USING_SOFT_RTC=y
+CONFIG_RT_USING_SDIO=y
+CONFIG_RT_SDIO_STACK_SIZE=16384
+CONFIG_RT_SDIO_THREAD_PRIORITY=15
+CONFIG_RT_MMCSD_STACK_SIZE=16384
+CONFIG_RT_MMCSD_THREAD_PREORITY=22
+CONFIG_RT_MMCSD_MAX_PARTITION=16
+# CONFIG_RT_SDIO_DEBUG is not set
+# CONFIG_RT_USING_SPI is not set
+# CONFIG_RT_USING_WDT is not set
+# CONFIG_RT_USING_AUDIO is not set
+# CONFIG_RT_USING_SENSOR is not set
+# CONFIG_RT_USING_TOUCH is not set
+# CONFIG_RT_USING_LCD is not set
+# CONFIG_RT_USING_HWCRYPTO is not set
+# CONFIG_RT_USING_WIFI is not set
+# CONFIG_RT_USING_VIRTIO is not set
+CONFIG_RT_USING_OFW=y
+# CONFIG_RT_USING_BUILTIN_FDT is not set
+CONFIG_RT_FDT_EARLYCON_MSG_SIZE=128
+CONFIG_RT_USING_OFW_BUS_RANGES_NUMBER=8
+# CONFIG_RT_USING_PCI is not set
+CONFIG_RT_USING_PIC=y
+CONFIG_MAX_HANDLERS=1024
+# CONFIG_RT_PIC_ARM_GIC is not set
+CONFIG_RT_PIC_ARM_GIC_V3=y
+CONFIG_RT_USING_PIN=y
+CONFIG_RT_USING_PINCTRL=y
+CONFIG_RT_USING_KTIME=y
+CONFIG_RT_USING_CLK=y
+CONFIG_RT_USING_HWTIMER=y
+CONFIG_RT_HWTIMER_ARM_ARCH=y
+# CONFIG_RT_USING_CHERRYUSB is not set
+# end of Device Drivers
+
+#
+# C/C++ and POSIX layer
+#
+
+#
+# ISO-ANSI C layer
+#
+
+#
+# Timezone and Daylight Saving Time
+#
+# CONFIG_RT_LIBC_USING_FULL_TZ_DST is not set
+CONFIG_RT_LIBC_USING_LIGHT_TZ_DST=y
+CONFIG_RT_LIBC_TZ_DEFAULT_HOUR=8
+CONFIG_RT_LIBC_TZ_DEFAULT_MIN=0
+CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0
+# end of Timezone and Daylight Saving Time
+# end of ISO-ANSI C layer
+
+#
+# POSIX (Portable Operating System Interface) layer
+#
+CONFIG_RT_USING_POSIX_FS=y
+CONFIG_RT_USING_POSIX_DEVIO=y
+CONFIG_RT_USING_POSIX_STDIO=y
+CONFIG_RT_USING_POSIX_POLL=y
+CONFIG_RT_USING_POSIX_SELECT=y
+CONFIG_RT_USING_POSIX_EVENTFD=y
+CONFIG_RT_USING_POSIX_EPOLL=y
+CONFIG_RT_USING_POSIX_SIGNALFD=y
+CONFIG_RT_SIGNALFD_MAX_NUM=10
+CONFIG_RT_USING_POSIX_TIMERFD=y
+CONFIG_RT_USING_POSIX_SOCKET=y
+CONFIG_RT_USING_POSIX_TERMIOS=y
+# CONFIG_RT_USING_POSIX_AIO is not set
+CONFIG_RT_USING_POSIX_MMAN=y
+CONFIG_RT_USING_POSIX_DELAY=y
+CONFIG_RT_USING_POSIX_CLOCK=y
+CONFIG_RT_USING_POSIX_TIMER=y
+# CONFIG_RT_USING_PTHREADS is not set
+# CONFIG_RT_USING_MODULE is not set
+
+#
+# Interprocess Communication (IPC)
+#
+CONFIG_RT_USING_POSIX_PIPE=y
+CONFIG_RT_USING_POSIX_PIPE_SIZE=2048
+CONFIG_RT_USING_POSIX_MESSAGE_QUEUE=y
+# CONFIG_RT_USING_POSIX_MESSAGE_SEMAPHORE is not set
+
+#
+# Socket is in the 'Network' category
+#
+# end of Interprocess Communication (IPC)
+# end of POSIX (Portable Operating System Interface) layer
+
+# CONFIG_RT_USING_CPLUSPLUS is not set
+# end of C/C++ and POSIX layer
+
+#
+# Network
+#
+CONFIG_RT_USING_SAL=y
+CONFIG_SAL_INTERNET_CHECK=y
+
+#
+# Docking with protocol stacks
+#
+CONFIG_SAL_USING_LWIP=y
+# CONFIG_SAL_USING_AT is not set
+# CONFIG_SAL_USING_TLS is not set
+# end of Docking with protocol stacks
+
+CONFIG_SAL_USING_POSIX=y
+CONFIG_RT_USING_NETDEV=y
+CONFIG_NETDEV_USING_IFCONFIG=y
+CONFIG_NETDEV_USING_PING=y
+CONFIG_NETDEV_USING_NETSTAT=y
+CONFIG_NETDEV_USING_AUTO_DEFAULT=y
+# CONFIG_NETDEV_USING_LINK_STATUS_CALLBACK is not set
+# CONFIG_NETDEV_USING_IPV6 is not set
+CONFIG_NETDEV_IPV4=1
+CONFIG_NETDEV_IPV6=0
+CONFIG_RT_USING_LWIP=y
+# CONFIG_RT_USING_LWIP_LOCAL_VERSION is not set
+# CONFIG_RT_USING_LWIP141 is not set
+# CONFIG_RT_USING_LWIP203 is not set
+CONFIG_RT_USING_LWIP212=y
+# CONFIG_RT_USING_LWIP_LATEST is not set
+CONFIG_RT_USING_LWIP_VER_NUM=0x20102
+# CONFIG_RT_USING_LWIP_IPV6 is not set
+CONFIG_RT_LWIP_MEM_ALIGNMENT=8
+CONFIG_RT_LWIP_IGMP=y
+CONFIG_RT_LWIP_ICMP=y
+# CONFIG_RT_LWIP_SNMP is not set
+CONFIG_RT_LWIP_DNS=y
+CONFIG_RT_LWIP_DHCP=y
+CONFIG_IP_SOF_BROADCAST=1
+CONFIG_IP_SOF_BROADCAST_RECV=1
+
+#
+# Static IPv4 Address
+#
+CONFIG_RT_LWIP_IPADDR="192.168.1.30"
+CONFIG_RT_LWIP_GWADDR="192.168.1.1"
+CONFIG_RT_LWIP_MSKADDR="255.255.255.0"
+# end of Static IPv4 Address
+
+CONFIG_RT_LWIP_UDP=y
+CONFIG_RT_LWIP_TCP=y
+CONFIG_RT_LWIP_RAW=y
+# CONFIG_RT_LWIP_PPP is not set
+CONFIG_RT_MEMP_NUM_NETCONN=64
+CONFIG_RT_LWIP_PBUF_NUM=320
+CONFIG_RT_LWIP_RAW_PCB_NUM=32
+CONFIG_RT_LWIP_UDP_PCB_NUM=32
+CONFIG_RT_LWIP_TCP_PCB_NUM=64
+CONFIG_RT_LWIP_TCP_SEG_NUM=480
+CONFIG_RT_LWIP_TCP_SND_BUF=65535
+CONFIG_RT_LWIP_TCP_WND=49512
+CONFIG_RT_LWIP_TCPTHREAD_PRIORITY=8
+CONFIG_RT_LWIP_TCPTHREAD_MBOX_SIZE=256
+CONFIG_RT_LWIP_TCPTHREAD_STACKSIZE=65536
+# CONFIG_LWIP_NO_RX_THREAD is not set
+CONFIG_LWIP_NO_TX_THREAD=y
+CONFIG_RT_LWIP_ETHTHREAD_PRIORITY=9
+CONFIG_RT_LWIP_ETHTHREAD_STACKSIZE=16384
+CONFIG_RT_LWIP_ETHTHREAD_MBOX_SIZE=256
+# CONFIG_RT_LWIP_REASSEMBLY_FRAG is not set
+CONFIG_LWIP_NETIF_STATUS_CALLBACK=1
+CONFIG_LWIP_NETIF_LINK_CALLBACK=1
+CONFIG_RT_LWIP_NETIF_NAMESIZE=6
+CONFIG_SO_REUSE=1
+CONFIG_LWIP_SO_RCVTIMEO=1
+CONFIG_LWIP_SO_SNDTIMEO=1
+CONFIG_LWIP_SO_RCVBUF=1
+CONFIG_LWIP_SO_LINGER=0
+CONFIG_RT_LWIP_NETIF_LOOPBACK=y
+CONFIG_LWIP_NETIF_LOOPBACK=1
+# CONFIG_RT_LWIP_STATS is not set
+CONFIG_RT_LWIP_USING_HW_CHECKSUM=y
+CONFIG_RT_LWIP_USING_PING=y
+# CONFIG_LWIP_USING_DHCPD is not set
+# CONFIG_RT_LWIP_DEBUG is not set
+# CONFIG_RT_USING_AT is not set
+# end of Network
+
+#
+# Memory protection
+#
+# CONFIG_RT_USING_MEM_PROTECTION is not set
+# CONFIG_RT_USING_HW_STACK_GUARD is not set
+# end of Memory protection
+
+#
+# Utilities
+#
+# CONFIG_RT_USING_RYM is not set
+# CONFIG_RT_USING_ULOG is not set
+CONFIG_RT_USING_UTEST=y
+CONFIG_UTEST_THR_STACK_SIZE=32768
+CONFIG_UTEST_THR_PRIORITY=20
+# CONFIG_RT_USING_VAR_EXPORT is not set
+CONFIG_RT_USING_RESOURCE_ID=y
+CONFIG_RT_USING_ADT=y
+CONFIG_RT_USING_ADT_AVL=y
+CONFIG_RT_USING_ADT_BITMAP=y
+CONFIG_RT_USING_ADT_HASHMAP=y
+CONFIG_RT_USING_ADT_REF=y
+# CONFIG_RT_USING_RT_LINK is not set
+# end of Utilities
+
+# CONFIG_RT_USING_VBUS is not set
+CONFIG_RT_USING_LWP=y
+CONFIG_LWP_DEBUG=y
+CONFIG_LWP_DEBUG_INIT=y
+CONFIG_RT_LWP_MAX_NR=128
+CONFIG_LWP_TASK_STACK_SIZE=32768
+CONFIG_RT_CH_MSG_MAX_NR=1024
+CONFIG_LWP_TID_MAX_NR=128
+CONFIG_RT_LWP_SHM_MAX_NR=64
+CONFIG_RT_USING_LDSO=y
+# CONFIG_ELF_DEBUG_ENABLE is not set
+# CONFIG_ELF_LOAD_RANDOMIZE is not set
+CONFIG_LWP_USING_TERMINAL=y
+CONFIG_LWP_PTY_MAX_PARIS_LIMIT=64
+CONFIG_RT_USING_VDSO=y
+
+#
+# Memory management
+#
+CONFIG_RT_USING_MEMBLOCK=y
+CONFIG_RT_INIT_MEMORY_REGIONS=128
+# end of Memory management
+
+#
+# Using USB legacy version
+#
+# CONFIG_RT_USING_USB_HOST is not set
+# CONFIG_RT_USING_USB_DEVICE is not set
+# end of Using USB legacy version
+
+# CONFIG_RT_USING_FDT is not set
+# end of RT-Thread Components
+
+#
+# RT-Thread Utestcases
+#
+CONFIG_RT_USING_UTESTCASES=y
+
+#
+# Utest Self Testcase
+#
+# CONFIG_UTEST_SELF_PASS_TC is not set
+# end of Utest Self Testcase
+
+#
+# Kernel Testcase
+#
+# CONFIG_UTEST_MEMHEAP_TC is not set
+# CONFIG_UTEST_SLAB_TC is not set
+# CONFIG_UTEST_IRQ_TC is not set
+# CONFIG_UTEST_SEMAPHORE_TC is not set
+# CONFIG_UTEST_EVENT_TC is not set
+# CONFIG_UTEST_TIMER_TC is not set
+# CONFIG_UTEST_MESSAGEQUEUE_TC is not set
+# CONFIG_UTEST_SIGNAL_TC is not set
+# CONFIG_UTEST_MUTEX_TC is not set
+# CONFIG_UTEST_MAILBOX_TC is not set
+# CONFIG_UTEST_THREAD_TC is not set
+# CONFIG_UTEST_DEVICE_TC is not set
+# CONFIG_UTEST_ATOMIC_TC is not set
+# CONFIG_UTEST_HOOKLIST_TC is not set
+# CONFIG_UTEST_MTSAFE_KPRINT_TC is not set
+# CONFIG_UTEST_SCHEDULER_TC is not set
+
+#
+# Kernel SMP Testcase
+#
+# CONFIG_UTEST_SMP_AFFFINITY_TC is not set
+# CONFIG_UTEST_SMP_ASSIGNED_IDLE_CORE_TC is not set
+# CONFIG_UTEST_SMP_INTERRUPT_PRI_TC is not set
+# CONFIG_UTEST_SMP_SPINLOCK_TC is not set
+# CONFIG_UTEST_SMP_THREAD_PREEMPTION_TC is not set
+# end of Kernel SMP Testcase
+# end of Kernel Testcase
+
+#
+# CPP11 Testcase
+#
+# CONFIG_UTEST_CPP11_THREAD_TC is not set
+# end of CPP11 Testcase
+
+#
+# Utest Serial Testcase
+#
+# CONFIG_UTEST_SERIAL_TC is not set
+# end of Utest Serial Testcase
+
+#
+# Utest IPC Testcase
+#
+# CONFIG_UTEST_COMPLETION_TC is not set
+# end of Utest IPC Testcase
+
+#
+# RTT Posix Testcase
+#
+# CONFIG_RTT_POSIX_TESTCASE is not set
+# end of RTT Posix Testcase
+
+#
+# Memory Management Subsytem Testcase
+#
+# CONFIG_UTEST_MM_API_TC is not set
+# CONFIG_UTEST_MM_LWP_TC is not set
+# end of Memory Management Subsytem Testcase
+
+#
+# Tmpfs Testcase
+#
+# CONFIG_UTEST_TMPFS_CP is not set
+# end of Tmpfs Testcase
+
+#
+# SMP-Call Testcase
+#
+CONFIG_UTEST_SMP_CALL_FUNC=y
+# end of SMP-Call Testcase
+# end of RT-Thread Utestcases
+
+#
+# RT-Thread online packages
+#
+
+#
+# IoT - internet of things
+#
+# CONFIG_PKG_USING_LORAWAN_DRIVER is not set
+# CONFIG_PKG_USING_PAHOMQTT is not set
+# CONFIG_PKG_USING_UMQTT is not set
+# CONFIG_PKG_USING_WEBCLIENT is not set
+# CONFIG_PKG_USING_WEBNET is not set
+# CONFIG_PKG_USING_MONGOOSE is not set
+# CONFIG_PKG_USING_MYMQTT is not set
+# CONFIG_PKG_USING_KAWAII_MQTT is not set
+# CONFIG_PKG_USING_BC28_MQTT is not set
+# CONFIG_PKG_USING_WEBTERMINAL is not set
+# CONFIG_PKG_USING_FREEMODBUS is not set
+# CONFIG_PKG_USING_NANOPB is not set
+
+#
+# Wi-Fi
+#
+
+#
+# Marvell WiFi
+#
+# CONFIG_PKG_USING_WLANMARVELL is not set
+# end of Marvell WiFi
+
+#
+# Wiced WiFi
+#
+# CONFIG_PKG_USING_WLAN_WICED is not set
+# end of Wiced WiFi
+
+# CONFIG_PKG_USING_RW007 is not set
+
+#
+# CYW43012 WiFi
+#
+# CONFIG_PKG_USING_WLAN_CYW43012 is not set
+# end of CYW43012 WiFi
+
+#
+# BL808 WiFi
+#
+# CONFIG_PKG_USING_WLAN_BL808 is not set
+# end of BL808 WiFi
+
+#
+# CYW43439 WiFi
+#
+# CONFIG_PKG_USING_WLAN_CYW43439 is not set
+# end of CYW43439 WiFi
+# end of Wi-Fi
+
+# CONFIG_PKG_USING_COAP is not set
+# CONFIG_PKG_USING_NOPOLL is not set
+# CONFIG_PKG_USING_NETUTILS is not set
+# CONFIG_PKG_USING_CMUX is not set
+# CONFIG_PKG_USING_PPP_DEVICE is not set
+# CONFIG_PKG_USING_AT_DEVICE is not set
+# CONFIG_PKG_USING_ATSRV_SOCKET is not set
+# CONFIG_PKG_USING_WIZNET is not set
+# CONFIG_PKG_USING_ZB_COORDINATOR is not set
+
+#
+# IoT Cloud
+#
+# CONFIG_PKG_USING_ONENET is not set
+# CONFIG_PKG_USING_GAGENT_CLOUD is not set
+# CONFIG_PKG_USING_ALI_IOTKIT is not set
+# CONFIG_PKG_USING_AZURE is not set
+# CONFIG_PKG_USING_TENCENT_IOT_EXPLORER is not set
+# CONFIG_PKG_USING_JIOT-C-SDK is not set
+# CONFIG_PKG_USING_UCLOUD_IOT_SDK is not set
+# CONFIG_PKG_USING_JOYLINK is not set
+# CONFIG_PKG_USING_IOTSHARP_SDK is not set
+# end of IoT Cloud
+
+# CONFIG_PKG_USING_NIMBLE is not set
+# CONFIG_PKG_USING_LLSYNC_SDK_ADAPTER is not set
+# CONFIG_PKG_USING_OTA_DOWNLOADER is not set
+# CONFIG_PKG_USING_IPMSG is not set
+# CONFIG_PKG_USING_LSSDP is not set
+# CONFIG_PKG_USING_AIRKISS_OPEN is not set
+# CONFIG_PKG_USING_LIBRWS is not set
+# CONFIG_PKG_USING_TCPSERVER is not set
+# CONFIG_PKG_USING_PROTOBUF_C is not set
+# CONFIG_PKG_USING_DLT645 is not set
+# CONFIG_PKG_USING_QXWZ is not set
+# CONFIG_PKG_USING_SMTP_CLIENT is not set
+# CONFIG_PKG_USING_ABUP_FOTA is not set
+# CONFIG_PKG_USING_LIBCURL2RTT is not set
+# CONFIG_PKG_USING_CAPNP is not set
+# CONFIG_PKG_USING_AGILE_TELNET is not set
+# CONFIG_PKG_USING_NMEALIB is not set
+# CONFIG_PKG_USING_PDULIB is not set
+# CONFIG_PKG_USING_BTSTACK is not set
+# CONFIG_PKG_USING_BT_CYW43012 is not set
+# CONFIG_PKG_USING_CYW43XX is not set
+# CONFIG_PKG_USING_LORAWAN_ED_STACK is not set
+# CONFIG_PKG_USING_WAYZ_IOTKIT is not set
+# CONFIG_PKG_USING_MAVLINK is not set
+# CONFIG_PKG_USING_BSAL is not set
+# CONFIG_PKG_USING_AGILE_MODBUS is not set
+# CONFIG_PKG_USING_AGILE_FTP is not set
+# CONFIG_PKG_USING_EMBEDDEDPROTO is not set
+# CONFIG_PKG_USING_RT_LINK_HW is not set
+# CONFIG_PKG_USING_RYANMQTT is not set
+# CONFIG_PKG_USING_RYANW5500 is not set
+# CONFIG_PKG_USING_LORA_PKT_FWD is not set
+# CONFIG_PKG_USING_LORA_GW_DRIVER_LIB is not set
+# CONFIG_PKG_USING_LORA_PKT_SNIFFER is not set
+# CONFIG_PKG_USING_HM is not set
+# CONFIG_PKG_USING_SMALL_MODBUS is not set
+# CONFIG_PKG_USING_NET_SERVER is not set
+# CONFIG_PKG_USING_ZFTP is not set
+# CONFIG_PKG_USING_WOL is not set
+# CONFIG_PKG_USING_ZEPHYR_POLLING is not set
+# CONFIG_PKG_USING_MATTER_ADAPTATION_LAYER is not set
+# CONFIG_PKG_USING_LHC_MODBUS is not set
+# CONFIG_PKG_USING_QMODBUS is not set
+# end of IoT - internet of things
+
+#
+# security packages
+#
+# CONFIG_PKG_USING_MBEDTLS is not set
+# CONFIG_PKG_USING_LIBSODIUM is not set
+# CONFIG_PKG_USING_LIBHYDROGEN is not set
+# CONFIG_PKG_USING_TINYCRYPT is not set
+# CONFIG_PKG_USING_TFM is not set
+# CONFIG_PKG_USING_YD_CRYPTO is not set
+# end of security packages
+
+#
+# language packages
+#
+
+#
+# JSON: JavaScript Object Notation, a lightweight data-interchange format
+#
+# CONFIG_PKG_USING_CJSON is not set
+# CONFIG_PKG_USING_LJSON is not set
+# CONFIG_PKG_USING_RT_CJSON_TOOLS is not set
+# CONFIG_PKG_USING_RAPIDJSON is not set
+# CONFIG_PKG_USING_JSMN is not set
+# CONFIG_PKG_USING_AGILE_JSMN is not set
+# CONFIG_PKG_USING_PARSON is not set
+# end of JSON: JavaScript Object Notation, a lightweight data-interchange format
+
+#
+# XML: Extensible Markup Language
+#
+# CONFIG_PKG_USING_SIMPLE_XML is not set
+# CONFIG_PKG_USING_EZXML is not set
+# end of XML: Extensible Markup Language
+
+# CONFIG_PKG_USING_LUATOS_SOC is not set
+# CONFIG_PKG_USING_LUA is not set
+# CONFIG_PKG_USING_JERRYSCRIPT is not set
+# CONFIG_PKG_USING_MICROPYTHON is not set
+# CONFIG_PKG_USING_PIKASCRIPT is not set
+# CONFIG_PKG_USING_RTT_RUST is not set
+# end of language packages
+
+#
+# multimedia packages
+#
+
+#
+# LVGL: powerful and easy-to-use embedded GUI library
+#
+# CONFIG_PKG_USING_LVGL is not set
+# CONFIG_PKG_USING_LV_MUSIC_DEMO is not set
+# CONFIG_PKG_USING_GUI_GUIDER_DEMO is not set
+# end of LVGL: powerful and easy-to-use embedded GUI library
+
+#
+# u8g2: a monochrome graphic library
+#
+# CONFIG_PKG_USING_U8G2_OFFICIAL is not set
+# CONFIG_PKG_USING_U8G2 is not set
+# end of u8g2: a monochrome graphic library
+
+# CONFIG_PKG_USING_OPENMV is not set
+# CONFIG_PKG_USING_MUPDF is not set
+# CONFIG_PKG_USING_STEMWIN is not set
+# CONFIG_PKG_USING_WAVPLAYER is not set
+# CONFIG_PKG_USING_TJPGD is not set
+# CONFIG_PKG_USING_PDFGEN is not set
+# CONFIG_PKG_USING_HELIX is not set
+# CONFIG_PKG_USING_AZUREGUIX is not set
+# CONFIG_PKG_USING_TOUCHGFX2RTT is not set
+# CONFIG_PKG_USING_NUEMWIN is not set
+# CONFIG_PKG_USING_MP3PLAYER is not set
+# CONFIG_PKG_USING_TINYJPEG is not set
+# CONFIG_PKG_USING_UGUI is not set
+# CONFIG_PKG_USING_MCURSES is not set
+# CONFIG_PKG_USING_TERMBOX is not set
+# CONFIG_PKG_USING_VT100 is not set
+# CONFIG_PKG_USING_QRCODE is not set
+# CONFIG_PKG_USING_GUIENGINE is not set
+# CONFIG_PKG_USING_3GPP_AMRNB is not set
+# end of multimedia packages
+
+#
+# tools packages
+#
+# CONFIG_PKG_USING_CMBACKTRACE is not set
+# CONFIG_PKG_USING_EASYFLASH is not set
+# CONFIG_PKG_USING_EASYLOGGER is not set
+# CONFIG_PKG_USING_SYSTEMVIEW is not set
+# CONFIG_PKG_USING_SEGGER_RTT is not set
+# CONFIG_PKG_USING_RTT_AUTO_EXE_CMD is not set
+# CONFIG_PKG_USING_RDB is not set
+# CONFIG_PKG_USING_ULOG_EASYFLASH is not set
+# CONFIG_PKG_USING_LOGMGR is not set
+# CONFIG_PKG_USING_ADBD is not set
+# CONFIG_PKG_USING_COREMARK is not set
+# CONFIG_PKG_USING_DHRYSTONE is not set
+# CONFIG_PKG_USING_MEMORYPERF is not set
+# CONFIG_PKG_USING_NR_MICRO_SHELL is not set
+# CONFIG_PKG_USING_CHINESE_FONT_LIBRARY is not set
+# CONFIG_PKG_USING_LUNAR_CALENDAR is not set
+# CONFIG_PKG_USING_BS8116A is not set
+# CONFIG_PKG_USING_GPS_RMC is not set
+# CONFIG_PKG_USING_URLENCODE is not set
+# CONFIG_PKG_USING_UMCN is not set
+# CONFIG_PKG_USING_LWRB2RTT is not set
+# CONFIG_PKG_USING_CPU_USAGE is not set
+# CONFIG_PKG_USING_GBK2UTF8 is not set
+# CONFIG_PKG_USING_VCONSOLE is not set
+# CONFIG_PKG_USING_KDB is not set
+# CONFIG_PKG_USING_WAMR is not set
+# CONFIG_PKG_USING_MICRO_XRCE_DDS_CLIENT is not set
+# CONFIG_PKG_USING_LWLOG is not set
+# CONFIG_PKG_USING_ANV_TRACE is not set
+# CONFIG_PKG_USING_ANV_MEMLEAK is not set
+# CONFIG_PKG_USING_ANV_TESTSUIT is not set
+# CONFIG_PKG_USING_ANV_BENCH is not set
+# CONFIG_PKG_USING_DEVMEM is not set
+# CONFIG_PKG_USING_REGEX is not set
+# CONFIG_PKG_USING_MEM_SANDBOX is not set
+# CONFIG_PKG_USING_SOLAR_TERMS is not set
+# CONFIG_PKG_USING_GAN_ZHI is not set
+# CONFIG_PKG_USING_FDT is not set
+# CONFIG_PKG_USING_CBOX is not set
+# CONFIG_PKG_USING_SNOWFLAKE is not set
+# CONFIG_PKG_USING_HASH_MATCH is not set
+# CONFIG_PKG_USING_ARMV7M_DWT_TOOL is not set
+# CONFIG_PKG_USING_VOFA_PLUS is not set
+# CONFIG_PKG_USING_ZDEBUG is not set
+# end of tools packages
+
+#
+# system packages
+#
+
+#
+# enhanced kernel services
+#
+# CONFIG_PKG_USING_RT_MEMCPY_CM is not set
+# CONFIG_PKG_USING_RT_KPRINTF_THREADSAFE is not set
+# CONFIG_PKG_USING_RT_VSNPRINTF_FULL is not set
+# end of enhanced kernel services
+
+#
+# acceleration: Assembly language or algorithmic acceleration packages
+#
+# CONFIG_PKG_USING_QFPLIB_M0_FULL is not set
+# CONFIG_PKG_USING_QFPLIB_M0_TINY is not set
+# CONFIG_PKG_USING_QFPLIB_M3 is not set
+# end of acceleration: Assembly language or algorithmic acceleration packages
+
+#
+# CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
+#
+# CONFIG_PKG_USING_CMSIS_5 is not set
+# CONFIG_PKG_USING_CMSIS_CORE is not set
+# CONFIG_PKG_USING_CMSIS_DSP is not set
+# CONFIG_PKG_USING_CMSIS_NN is not set
+# CONFIG_PKG_USING_CMSIS_RTOS1 is not set
+# CONFIG_PKG_USING_CMSIS_RTOS2 is not set
+# end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard
+
+#
+# Micrium: Micrium software products porting for RT-Thread
+#
+# CONFIG_PKG_USING_UCOSIII_WRAPPER is not set
+# CONFIG_PKG_USING_UCOSII_WRAPPER is not set
+# CONFIG_PKG_USING_UC_CRC is not set
+# CONFIG_PKG_USING_UC_CLK is not set
+# CONFIG_PKG_USING_UC_COMMON is not set
+# CONFIG_PKG_USING_UC_MODBUS is not set
+# end of Micrium: Micrium software products porting for RT-Thread
+
+# CONFIG_PKG_USING_FREERTOS_WRAPPER is not set
+# CONFIG_PKG_USING_LITEOS_SDK is not set
+# CONFIG_PKG_USING_TZ_DATABASE is not set
+# CONFIG_PKG_USING_CAIRO is not set
+# CONFIG_PKG_USING_PIXMAN is not set
+# CONFIG_PKG_USING_PARTITION is not set
+# CONFIG_PKG_USING_PERF_COUNTER is not set
+# CONFIG_PKG_USING_FILEX is not set
+# CONFIG_PKG_USING_LEVELX is not set
+# CONFIG_PKG_USING_FLASHDB is not set
+# CONFIG_PKG_USING_SQLITE is not set
+# CONFIG_PKG_USING_RTI is not set
+# CONFIG_PKG_USING_DFS_YAFFS is not set
+# CONFIG_PKG_USING_LITTLEFS is not set
+# CONFIG_PKG_USING_DFS_JFFS2 is not set
+# CONFIG_PKG_USING_DFS_UFFS is not set
+# CONFIG_PKG_USING_LWEXT4 is not set
+# CONFIG_PKG_USING_THREAD_POOL is not set
+# CONFIG_PKG_USING_ROBOTS is not set
+# CONFIG_PKG_USING_EV is not set
+# CONFIG_PKG_USING_SYSWATCH is not set
+# CONFIG_PKG_USING_SYS_LOAD_MONITOR is not set
+# CONFIG_PKG_USING_PLCCORE is not set
+# CONFIG_PKG_USING_RAMDISK is not set
+# CONFIG_PKG_USING_MININI is not set
+# CONFIG_PKG_USING_QBOOT is not set
+# CONFIG_PKG_USING_PPOOL is not set
+# CONFIG_PKG_USING_OPENAMP is not set
+# CONFIG_PKG_USING_RPMSG_LITE is not set
+# CONFIG_PKG_USING_LPM is not set
+# CONFIG_PKG_USING_TLSF is not set
+# CONFIG_PKG_USING_EVENT_RECORDER is not set
+# CONFIG_PKG_USING_ARM_2D is not set
+# CONFIG_PKG_USING_MCUBOOT is not set
+# CONFIG_PKG_USING_TINYUSB is not set
+# CONFIG_PKG_USING_CHERRYUSB is not set
+# CONFIG_PKG_USING_KMULTI_RTIMER is not set
+# CONFIG_PKG_USING_TFDB is not set
+# CONFIG_PKG_USING_QPC is not set
+# CONFIG_PKG_USING_AGILE_UPGRADE is not set
+# CONFIG_PKG_USING_FLASH_BLOB is not set
+# CONFIG_PKG_USING_MLIBC is not set
+# CONFIG_PKG_USING_TASK_MSG_BUS is not set
+# CONFIG_PKG_USING_SFDB is not set
+# CONFIG_PKG_USING_RTP is not set
+# CONFIG_PKG_USING_REB is not set
+# CONFIG_PKG_USING_R_RHEALSTONE is not set
+# end of system packages
+
+#
+# peripheral libraries and drivers
+#
+
+#
+# HAL & SDK Drivers
+#
+
+#
+# STM32 HAL & SDK Drivers
+#
+# CONFIG_PKG_USING_STM32L4_HAL_DRIVER is not set
+# CONFIG_PKG_USING_STM32L4_CMSIS_DRIVER is not set
+# CONFIG_PKG_USING_STM32WB55_SDK is not set
+# CONFIG_PKG_USING_STM32_SDIO is not set
+# end of STM32 HAL & SDK Drivers
+
+# CONFIG_PKG_USING_BLUETRUM_SDK is not set
+# CONFIG_PKG_USING_EMBARC_BSP is not set
+# CONFIG_PKG_USING_ESP_IDF is not set
+
+#
+# Kendryte SDK
+#
+# CONFIG_PKG_USING_K210_SDK is not set
+# CONFIG_PKG_USING_KENDRYTE_SDK is not set
+# end of Kendryte SDK
+
+# CONFIG_PKG_USING_NRF5X_SDK is not set
+# CONFIG_PKG_USING_NRFX is not set
+# CONFIG_PKG_USING_RASPBERRYPI_PICO_SDK is not set
+# end of HAL & SDK Drivers
+
+#
+# sensors drivers
+#
+# CONFIG_PKG_USING_LSM6DSM is not set
+# CONFIG_PKG_USING_LSM6DSL is not set
+# CONFIG_PKG_USING_LPS22HB is not set
+# CONFIG_PKG_USING_HTS221 is not set
+# CONFIG_PKG_USING_LSM303AGR is not set
+# CONFIG_PKG_USING_BME280 is not set
+# CONFIG_PKG_USING_BME680 is not set
+# CONFIG_PKG_USING_BMA400 is not set
+# CONFIG_PKG_USING_BMI160_BMX160 is not set
+# CONFIG_PKG_USING_SPL0601 is not set
+# CONFIG_PKG_USING_MS5805 is not set
+# CONFIG_PKG_USING_DA270 is not set
+# CONFIG_PKG_USING_DF220 is not set
+# CONFIG_PKG_USING_HSHCAL001 is not set
+# CONFIG_PKG_USING_BH1750 is not set
+# CONFIG_PKG_USING_MPU6XXX is not set
+# CONFIG_PKG_USING_AHT10 is not set
+# CONFIG_PKG_USING_AP3216C is not set
+# CONFIG_PKG_USING_TSL4531 is not set
+# CONFIG_PKG_USING_DS18B20 is not set
+# CONFIG_PKG_USING_DHT11 is not set
+# CONFIG_PKG_USING_DHTXX is not set
+# CONFIG_PKG_USING_GY271 is not set
+# CONFIG_PKG_USING_GP2Y10 is not set
+# CONFIG_PKG_USING_SGP30 is not set
+# CONFIG_PKG_USING_HDC1000 is not set
+# CONFIG_PKG_USING_BMP180 is not set
+# CONFIG_PKG_USING_BMP280 is not set
+# CONFIG_PKG_USING_SHTC1 is not set
+# CONFIG_PKG_USING_BMI088 is not set
+# CONFIG_PKG_USING_HMC5883 is not set
+# CONFIG_PKG_USING_MAX6675 is not set
+# CONFIG_PKG_USING_TMP1075 is not set
+# CONFIG_PKG_USING_SR04 is not set
+# CONFIG_PKG_USING_CCS811 is not set
+# CONFIG_PKG_USING_PMSXX is not set
+# CONFIG_PKG_USING_RT3020 is not set
+# CONFIG_PKG_USING_MLX90632 is not set
+# CONFIG_PKG_USING_MLX90393 is not set
+# CONFIG_PKG_USING_MLX90392 is not set
+# CONFIG_PKG_USING_MLX90397 is not set
+# CONFIG_PKG_USING_MS5611 is not set
+# CONFIG_PKG_USING_MAX31865 is not set
+# CONFIG_PKG_USING_VL53L0X is not set
+# CONFIG_PKG_USING_INA260 is not set
+# CONFIG_PKG_USING_MAX30102 is not set
+# CONFIG_PKG_USING_INA226 is not set
+# CONFIG_PKG_USING_LIS2DH12 is not set
+# CONFIG_PKG_USING_HS300X is not set
+# CONFIG_PKG_USING_ZMOD4410 is not set
+# CONFIG_PKG_USING_ISL29035 is not set
+# CONFIG_PKG_USING_MMC3680KJ is not set
+# CONFIG_PKG_USING_QMP6989 is not set
+# CONFIG_PKG_USING_BALANCE is not set
+# CONFIG_PKG_USING_SHT2X is not set
+# CONFIG_PKG_USING_SHT3X is not set
+# CONFIG_PKG_USING_SHT4X is not set
+# CONFIG_PKG_USING_AD7746 is not set
+# CONFIG_PKG_USING_ADT74XX is not set
+# CONFIG_PKG_USING_MAX17048 is not set
+# CONFIG_PKG_USING_AS7341 is not set
+# CONFIG_PKG_USING_CW2015 is not set
+# CONFIG_PKG_USING_ICM20608 is not set
+# CONFIG_PKG_USING_PAJ7620 is not set
+# CONFIG_PKG_USING_STHS34PF80 is not set
+# end of sensors drivers
+
+#
+# touch drivers
+#
+# CONFIG_PKG_USING_GT9147 is not set
+# CONFIG_PKG_USING_GT1151 is not set
+# CONFIG_PKG_USING_GT917S is not set
+# CONFIG_PKG_USING_GT911 is not set
+# CONFIG_PKG_USING_FT6206 is not set
+# CONFIG_PKG_USING_FT5426 is not set
+# CONFIG_PKG_USING_FT6236 is not set
+# CONFIG_PKG_USING_XPT2046_TOUCH is not set
+# CONFIG_PKG_USING_CST816X is not set
+# CONFIG_PKG_USING_CST812T is not set
+# end of touch drivers
+
+# CONFIG_PKG_USING_REALTEK_AMEBA is not set
+# CONFIG_PKG_USING_BUTTON is not set
+# CONFIG_PKG_USING_PCF8574 is not set
+# CONFIG_PKG_USING_SX12XX is not set
+# CONFIG_PKG_USING_SIGNAL_LED is not set
+# CONFIG_PKG_USING_LEDBLINK is not set
+# CONFIG_PKG_USING_LITTLED is not set
+# CONFIG_PKG_USING_LKDGUI is not set
+# CONFIG_PKG_USING_INFRARED is not set
+# CONFIG_PKG_USING_MULTI_INFRARED is not set
+# CONFIG_PKG_USING_AGILE_BUTTON is not set
+# CONFIG_PKG_USING_AGILE_LED is not set
+# CONFIG_PKG_USING_AT24CXX is not set
+# CONFIG_PKG_USING_MOTIONDRIVER2RTT is not set
+# CONFIG_PKG_USING_PCA9685 is not set
+# CONFIG_PKG_USING_ILI9341 is not set
+# CONFIG_PKG_USING_I2C_TOOLS is not set
+# CONFIG_PKG_USING_NRF24L01 is not set
+# CONFIG_PKG_USING_RPLIDAR is not set
+# CONFIG_PKG_USING_AS608 is not set
+# CONFIG_PKG_USING_RC522 is not set
+# CONFIG_PKG_USING_WS2812B is not set
+# CONFIG_PKG_USING_EXTERN_RTC_DRIVERS is not set
+# CONFIG_PKG_USING_MULTI_RTIMER is not set
+# CONFIG_PKG_USING_MAX7219 is not set
+# CONFIG_PKG_USING_BEEP is not set
+# CONFIG_PKG_USING_EASYBLINK is not set
+# CONFIG_PKG_USING_PMS_SERIES is not set
+# CONFIG_PKG_USING_CAN_YMODEM is not set
+# CONFIG_PKG_USING_LORA_RADIO_DRIVER is not set
+# CONFIG_PKG_USING_QLED is not set
+# CONFIG_PKG_USING_AGILE_CONSOLE is not set
+# CONFIG_PKG_USING_LD3320 is not set
+# CONFIG_PKG_USING_WK2124 is not set
+# CONFIG_PKG_USING_LY68L6400 is not set
+# CONFIG_PKG_USING_DM9051 is not set
+# CONFIG_PKG_USING_SSD1306 is not set
+# CONFIG_PKG_USING_QKEY is not set
+# CONFIG_PKG_USING_RS485 is not set
+# CONFIG_PKG_USING_RS232 is not set
+# CONFIG_PKG_USING_NES is not set
+# CONFIG_PKG_USING_VIRTUAL_SENSOR is not set
+# CONFIG_PKG_USING_VDEVICE is not set
+# CONFIG_PKG_USING_SGM706 is not set
+# CONFIG_PKG_USING_RDA58XX is not set
+# CONFIG_PKG_USING_LIBNFC is not set
+# CONFIG_PKG_USING_MFOC is not set
+# CONFIG_PKG_USING_TMC51XX is not set
+# CONFIG_PKG_USING_TCA9534 is not set
+# CONFIG_PKG_USING_KOBUKI is not set
+# CONFIG_PKG_USING_ROSSERIAL is not set
+# CONFIG_PKG_USING_MICRO_ROS is not set
+# CONFIG_PKG_USING_MCP23008 is not set
+# CONFIG_PKG_USING_MISAKA_AT24CXX is not set
+# CONFIG_PKG_USING_MISAKA_RGB_BLING is not set
+# CONFIG_PKG_USING_LORA_MODEM_DRIVER is not set
+# CONFIG_PKG_USING_SOFT_SERIAL is not set
+# CONFIG_PKG_USING_MB85RS16 is not set
+# CONFIG_PKG_USING_RFM300 is not set
+# CONFIG_PKG_USING_IO_INPUT_FILTER is not set
+# CONFIG_PKG_USING_LRF_NV7LIDAR is not set
+# CONFIG_PKG_USING_AIP650 is not set
+# CONFIG_PKG_USING_FINGERPRINT is not set
+# CONFIG_PKG_USING_BT_ECB02C is not set
+# CONFIG_PKG_USING_UAT is not set
+# CONFIG_PKG_USING_ST7789 is not set
+# CONFIG_PKG_USING_VS1003 is not set
+# CONFIG_PKG_USING_X9555 is not set
+# CONFIG_PKG_USING_SYSTEM_RUN_LED is not set
+# CONFIG_PKG_USING_BT_MX01 is not set
+# CONFIG_PKG_USING_RGPOWER is not set
+# CONFIG_PKG_USING_SPI_TOOLS is not set
+# end of peripheral libraries and drivers
+
+#
+# AI packages
+#
+# CONFIG_PKG_USING_LIBANN is not set
+# CONFIG_PKG_USING_NNOM is not set
+# CONFIG_PKG_USING_ONNX_BACKEND is not set
+# CONFIG_PKG_USING_ONNX_PARSER is not set
+# CONFIG_PKG_USING_TENSORFLOWLITEMICRO is not set
+# CONFIG_PKG_USING_ELAPACK is not set
+# CONFIG_PKG_USING_ULAPACK is not set
+# CONFIG_PKG_USING_QUEST is not set
+# CONFIG_PKG_USING_NAXOS is not set
+# CONFIG_PKG_USING_NCNN is not set
+# CONFIG_PKG_USING_R_TINYMAIX is not set
+# end of AI packages
+
+#
+# Signal Processing and Control Algorithm Packages
+#
+# CONFIG_PKG_USING_FIRE_PID_CURVE is not set
+# CONFIG_PKG_USING_QPID is not set
+# CONFIG_PKG_USING_UKAL is not set
+# CONFIG_PKG_USING_DIGITALCTRL is not set
+# CONFIG_PKG_USING_KISSFFT is not set
+# end of Signal Processing and Control Algorithm Packages
+
+#
+# miscellaneous packages
+#
+
+#
+# project laboratory
+#
+# end of project laboratory
+
+#
+# samples: kernel and components samples
+#
+# CONFIG_PKG_USING_KERNEL_SAMPLES is not set
+# CONFIG_PKG_USING_FILESYSTEM_SAMPLES is not set
+# CONFIG_PKG_USING_NETWORK_SAMPLES is not set
+# CONFIG_PKG_USING_PERIPHERAL_SAMPLES is not set
+# end of samples: kernel and components samples
+
+#
+# entertainment: terminal games and other interesting software packages
+#
+# CONFIG_PKG_USING_CMATRIX is not set
+# CONFIG_PKG_USING_SL is not set
+# CONFIG_PKG_USING_CAL is not set
+# CONFIG_PKG_USING_ACLOCK is not set
+# CONFIG_PKG_USING_THREES is not set
+# CONFIG_PKG_USING_2048 is not set
+# CONFIG_PKG_USING_SNAKE is not set
+# CONFIG_PKG_USING_TETRIS is not set
+# CONFIG_PKG_USING_DONUT is not set
+# CONFIG_PKG_USING_COWSAY is not set
+# CONFIG_PKG_USING_MORSE is not set
+# end of entertainment: terminal games and other interesting software packages
+
+# CONFIG_PKG_USING_LIBCSV is not set
+# CONFIG_PKG_USING_OPTPARSE is not set
+# CONFIG_PKG_USING_FASTLZ is not set
+# CONFIG_PKG_USING_MINILZO is not set
+# CONFIG_PKG_USING_QUICKLZ is not set
+# CONFIG_PKG_USING_LZMA is not set
+# CONFIG_PKG_USING_RALARAM is not set
+# CONFIG_PKG_USING_MULTIBUTTON is not set
+# CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set
+# CONFIG_PKG_USING_CANFESTIVAL is not set
+CONFIG_PKG_USING_ZLIB=y
+CONFIG_PKG_ZLIB_PATH="/packages/misc/zlib"
+# CONFIG_ZLIB_USING_SAMPLE is not set
+# CONFIG_PKG_USING_ZLIB_V100 is not set
+# CONFIG_PKG_USING_ZLIB_V123 is not set
+CONFIG_PKG_USING_ZLIB_LATEST_VERSION=y
+CONFIG_PKG_ZLIB_VER="latest"
+# CONFIG_PKG_USING_MINIZIP is not set
+# CONFIG_PKG_USING_HEATSHRINK is not set
+# CONFIG_PKG_USING_DSTR is not set
+# CONFIG_PKG_USING_TINYFRAME is not set
+# CONFIG_PKG_USING_KENDRYTE_DEMO is not set
+# CONFIG_PKG_USING_UPACKER is not set
+# CONFIG_PKG_USING_UPARAM is not set
+# CONFIG_PKG_USING_HELLO is not set
+# CONFIG_PKG_USING_VI is not set
+# CONFIG_PKG_USING_KI is not set
+# CONFIG_PKG_USING_ARMv7M_DWT is not set
+# CONFIG_PKG_USING_CRCLIB is not set
+# CONFIG_PKG_USING_LWGPS is not set
+# CONFIG_PKG_USING_STATE_MACHINE is not set
+# CONFIG_PKG_USING_DESIGN_PATTERN is not set
+# CONFIG_PKG_USING_CONTROLLER is not set
+# CONFIG_PKG_USING_PHASE_LOCKED_LOOP is not set
+# CONFIG_PKG_USING_MFBD is not set
+# CONFIG_PKG_USING_SLCAN2RTT is not set
+# CONFIG_PKG_USING_SOEM is not set
+# CONFIG_PKG_USING_QPARAM is not set
+# CONFIG_PKG_USING_CorevMCU_CLI is not set
+# end of miscellaneous packages
+
+#
+# Arduino libraries
+#
+# CONFIG_PKG_USING_RTDUINO is not set
+
+#
+# Projects and Demos
+#
+# CONFIG_PKG_USING_ARDUINO_MSGQ_C_CPP_DEMO is not set
+# CONFIG_PKG_USING_ARDUINO_SKETCH_LOADER_DEMO is not set
+# CONFIG_PKG_USING_ARDUINO_ULTRASOUND_RADAR is not set
+# CONFIG_PKG_USING_ARDUINO_NINEINONE_SENSOR_SHIELD is not set
+# CONFIG_PKG_USING_ARDUINO_SENSOR_KIT is not set
+# CONFIG_PKG_USING_ARDUINO_MATLAB_SUPPORT is not set
+# end of Projects and Demos
+
+#
+# Sensors
+#
+# CONFIG_PKG_USING_ARDUINO_SENSOR_DEVICE_DRIVERS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SENSORLAB is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL375 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL53L1X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VL6180X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31855 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31865 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX31856 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX6675 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90614 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS1 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AHTX0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM9DS0 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADT7410 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME680 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9808 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4728 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA219 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR390 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM6DS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO055 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MAX1704X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMC56X3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90393 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90395 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ICM20X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DPS310 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTS221 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT4X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADXL343 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS726X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AMG88XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2320 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AM2315 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LTR329_LTR303 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP085_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP183_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BMP3XX is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MS8607 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MLX90640 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MMA8451 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MSA301 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BNO08X_RVC is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS2MDL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303DLH_MAG is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LC709203F is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CAP1188 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_CCS811 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_NAU7802 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS331 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS2X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LPS35HW is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LSM303_ACCEL is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_LIS3DH is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8591 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPL3115A2 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPR121 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPRLS is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MPU6050 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCT2075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PM25AQI is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_EMC2101 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXAS21002C is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SCD30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_FXOS8700 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HMC5883_UNIFIED is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP30 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP006 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TLA202X is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCS34725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI7021 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SGP40 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SHTC3 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU21DF is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AS7341 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_HTU31D is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_INA260 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP007_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_L3GD20 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TMP117 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSC2007 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TSL2591_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VCNL4040 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML6075 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_VEML7700 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LIS3DHTR is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DHT is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL335 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ADXL345 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BME280 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP280 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_H3LIS331DL is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MMA7660 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_TSL2561 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_PAJ7620 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_VL53L0X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_ITG3200 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SHT31 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HP20X is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_DRV2605L is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BBM150 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HMC5883L is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LSM303DLH is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_TCS3414CS is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MP503 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_BMP085 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HIGHTEMP is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_VEML6070 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SI1145 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_SHT35 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_AT42QT1070 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LSM6DS3 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HDC1000 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_HM3301 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_MCP9600 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LTC2941 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_LDC1612 is not set
+# CONFIG_PKG_USING_ARDUINO_CAPACITIVESENSOR is not set
+# CONFIG_PKG_USING_ARDUINO_JARZEBSKI_MPU6050 is not set
+# end of Sensors
+
+#
+# Display
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_GFX_LIBRARY is not set
+# CONFIG_PKG_USING_ARDUINO_U8G2 is not set
+# CONFIG_PKG_USING_ARDUINO_TFT_ESPI is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ST7735 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SSD1306 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ILI9341 is not set
+# CONFIG_PKG_USING_SEEED_TM1637 is not set
+# end of Display
+
+#
+# Timing
+#
+# CONFIG_PKG_USING_ARDUINO_RTCLIB is not set
+# CONFIG_PKG_USING_ARDUINO_MSTIMER2 is not set
+# CONFIG_PKG_USING_ARDUINO_TICKER is not set
+# CONFIG_PKG_USING_ARDUINO_TASKSCHEDULER is not set
+# end of Timing
+
+#
+# Data Processing
+#
+# CONFIG_PKG_USING_ARDUINO_KALMANFILTER is not set
+# CONFIG_PKG_USING_ARDUINO_ARDUINOJSON is not set
+# CONFIG_PKG_USING_ARDUINO_TENSORFLOW_LITE_MICRO is not set
+# CONFIG_PKG_USING_ARDUINO_RUNNINGMEDIAN is not set
+# end of Data Processing
+
+#
+# Data Storage
+#
+
+#
+# Communication
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PN532 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI4713 is not set
+# end of Communication
+
+#
+# Device Control
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCF8574 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_PCA9685 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TPA2016 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DRV2605 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS1841 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_DS3502 is not set
+# CONFIG_PKG_USING_ARDUINO_SEEED_PCF85063TP is not set
+# end of Device Control
+
+#
+# Other
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MFRC630 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_SI5351 is not set
+# end of Other
+
+#
+# Signal IO
+#
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BUSIO is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_TCA8418 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP23017 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_ADS1X15 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_AW9523 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP3008 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_MCP4725 is not set
+# CONFIG_PKG_USING_ARDUINO_ADAFRUIT_BD3491FS is not set
+# end of Signal IO
+
+#
+# Uncategorized
+#
+# end of Arduino libraries
+# end of RT-Thread online packages
+
+#
+# Privated Packages of RealThread
+#
+# CONFIG_PKG_USING_CODEC is not set
+# CONFIG_PKG_USING_PLAYER is not set
+# CONFIG_PKG_USING_MPLAYER is not set
+# CONFIG_PKG_USING_PERSIMMON_SRC is not set
+# CONFIG_PKG_USING_JS_PERSIMMON is not set
+# CONFIG_PKG_USING_JERRYSCRIPT_WIN32 is not set
+
+#
+# Network Utilities
+#
+# CONFIG_PKG_USING_MDNS is not set
+# CONFIG_PKG_USING_UPNP is not set
+# end of Network Utilities
+
+# CONFIG_PKG_USING_WICED is not set
+# CONFIG_PKG_USING_CLOUDSDK is not set
+# CONFIG_PKG_USING_POWER_MANAGER is not set
+# CONFIG_PKG_USING_RT_OTA is not set
+# CONFIG_PKG_USING_RTINSIGHT is not set
+# CONFIG_PKG_USING_SMARTCONFIG is not set
+# CONFIG_PKG_USING_RTX is not set
+# CONFIG_RT_USING_TESTCASE is not set
+# CONFIG_PKG_USING_NGHTTP2 is not set
+# CONFIG_PKG_USING_AVS is not set
+# CONFIG_PKG_USING_ALI_LINKKIT is not set
+# CONFIG_PKG_USING_STS is not set
+# CONFIG_PKG_USING_DLMS is not set
+# CONFIG_PKG_USING_AUDIO_FRAMEWORK is not set
+# CONFIG_PKG_USING_ZBAR is not set
+# CONFIG_PKG_USING_MCF is not set
+# CONFIG_PKG_USING_URPC is not set
+# CONFIG_PKG_USING_DCM is not set
+# CONFIG_PKG_USING_EMQ is not set
+# CONFIG_PKG_USING_CFGM is not set
+# CONFIG_PKG_USING_RT_CMSIS_DAP is not set
+# CONFIG_PKG_USING_SMODULE is not set
+# CONFIG_PKG_USING_SNFD is not set
+# CONFIG_PKG_USING_UDBD is not set
+# CONFIG_PKG_USING_BENCHMARK is not set
+# CONFIG_PKG_USING_UBJSON is not set
+# CONFIG_PKG_USING_DATATYPE is not set
+# CONFIG_PKG_USING_FASTFS is not set
+# CONFIG_PKG_USING_RIL is not set
+# CONFIG_PKG_USING_WATCH_DCM_SVC is not set
+# CONFIG_PKG_USING_WATCH_APP_FWK is not set
+# CONFIG_PKG_USING_GUI_TEST is not set
+# CONFIG_PKG_USING_PMEM is not set
+# CONFIG_PKG_USING_LWRDP is not set
+# CONFIG_PKG_USING_MASAN is not set
+# CONFIG_PKG_USING_BSDIFF_LIB is not set
+# CONFIG_PKG_USING_PRC_DIFF is not set
+
+#
+# RT-Thread Smart
+#
+# CONFIG_PKG_USING_UKERNEL is not set
+# end of RT-Thread Smart
+
+# CONFIG_PKG_USING_TRACE_AGENT is not set
+# CONFIG_PKG_USING_DLOG is not set
+# CONFIG_PKG_USING_EXT4 is not set
+# end of Privated Packages of RealThread
+
+#
+# RT-Thread rockchip RK3500 drivers
+#
+CONFIG_RT_CLK_ROCKCHIP=y
+CONFIG_RT_CLK_ROCKCHIP_RK3568=y
+CONFIG_RT_CLK_ROCKCHIP_RK3588=y
+CONFIG_RT_SERIAL_8250=y
+CONFIG_RT_USING_RESET=y
+CONFIG_RT_HWTIMER_ROCKCHIP=y
+# end of RT-Thread rockchip RK3500 drivers
+
+CONFIG_SOC_RK3568=y

+ 31 - 0
bsp/rockchip/rk3500/Kconfig

@@ -0,0 +1,31 @@
+mainmenu "RT-Thread Project Configuration"
+
+config BSP_DIR
+    string
+    option env="BSP_ROOT"
+    default "."
+
+config RTT_DIR
+    string
+    option env="RTT_ROOT"
+    default "../../.."
+
+config PKGS_DIR
+    string
+    option env="PKGS_ROOT"
+    default "packages"
+
+source "$RTT_DIR/Kconfig"
+source "$PKGS_DIR/Kconfig"
+source "$BSP_DIR/driver/Kconfig"
+
+config SOC_RK3568
+    bool
+    select ARCH_ARMV8
+    select ARCH_CPU_64BIT
+    select RT_USING_CACHE
+    select RT_USING_COMPONENTS_INIT
+    select RT_USING_USER_MAIN
+    select ARCH_ARM_BOOTWITH_FLUSH_CACHE
+    default y
+

+ 75 - 0
bsp/rockchip/rk3500/README.md

@@ -0,0 +1,75 @@
+
+
+
+
+# RK3568 BSP Introduction
+
+[中文页]() | English
+
+## 1. Introduction
+
+RK3568 is a general-purpose SOC, quad-core 64-bit Cortex-A55 processor, with 22nm lithography process, has frequency up to 2.0GHz and Mali G52 GPU, support 4K decoding and 1080P encoding. Support mangy interfaces such as SATA/PCIE/USB3.0, an 0.8T NPU for lightweight AI applications. Support dual Gigabit Ethernet ports, LPDDR4 memory, etc.
+
+This project ported RT-Thread on RK3568, you can use the RADXA ROCK 3A version of the RK3568 in low-priced, which can even replace the Raspberry Pi 4B.
+
+## 2. Compiling
+
+Usage ARM Developer GNU ToolChain, it support Linux and Windows:
+
+```plaintext
+https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/
+```
+
+
+
+Download the `xxx-aarch64-none-elf` of x86_64 hosted platform, set the `RTT_EXEC_PATH` is system environment after decompress the binary.
+
+Enter directory `rt-thread/bsp/qemu-virt64-aarch64` and input:
+
+```plaintext
+scons
+```
+
+
+
+## 3. Execution
+
+RK3568 has different Kernel install methods according to different boardsit, recommend to install into the SD card: ([Official](https://wiki.t-firefly.com/en/ROC-RK3568-PC/hardware_doc.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/install/microSD)).
+
+After install Kernel, storage the `rtthread.bin` to EFI partition (the second partition), and add this line in the front of `boot.cmd` in this partition:
+
+```shell
+fatload mmc 1:1 0x208000 /rtthread.bin;dcache flush;go 0x208000
+```
+
+
+
+After modifying the script, build a binary script `boot.scr ` in this partition:
+
+```shell
+# Install the uboot-mkimage package on Linux, or use MSYS2 to install the u-boot-tools package on Windows
+mkimage -C none -A arm -T script -d boot.cmd boot.scr
+```
+
+
+
+According to different boards, the serial port can support up to UART0~9, this project uses UART2 ([Official](https://wiki.t-firefly.com/en/ROC-RK3568-PC/debug.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/dev/serial-console)) by default, the baud rate is 1500000, please make sure that the serial port used supports this baud rate.
+
+```plaintext
+heap: [0x002663f0 - 0x042663f0]
+
+ \ | /
+- RT -     Thread Operating System
+ / | \     4.1.0 build Mar 19 2022 17:17:29
+ 2006 - 2022 Copyright by RT-Thread team
+Hi, this is RT-Thread!!
+msh />
+```
+
+
+
+## 4. Condition
+
+| Driver | Condition | Remark  |
+| ------ | --------- | ------- |
+| UART   | Support   | UART0~9 |

+ 14 - 0
bsp/rockchip/rk3500/SConscript

@@ -0,0 +1,14 @@
+# for module compiling
+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')

+ 29 - 0
bsp/rockchip/rk3500/SConstruct

@@ -0,0 +1,29 @@
+import os
+import sys
+import rtconfig
+
+from rtconfig import RTT_ROOT
+
+sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
+from building import *
+
+TARGET = 'rtthread.' + rtconfig.TARGET_EXT
+
+DefaultEnvironment(tools=[])
+env = Environment(tools = ['mingw'],
+    AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
+    CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS,
+    CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
+    AR = rtconfig.AR, ARFLAGS = '-rc',
+    LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
+env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
+env['ASCOM'] = env['ASPPCOM']
+
+Export('RTT_ROOT')
+Export('rtconfig')
+
+# prepare building environment
+objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
+
+# make a building
+DoBuilding(TARGET, objs)

+ 14 - 0
bsp/rockchip/rk3500/applications/SConscript

@@ -0,0 +1,14 @@
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c') + Glob('*.cpp')
+CPPPATH = [cwd]
+
+group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
+
+list = os.listdir(cwd)
+for item in list:
+    if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
+        group += SConscript(os.path.join(item, 'SConscript'))
+
+Return('group')

+ 18 - 0
bsp/rockchip/rk3500/applications/main.c

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#include <rtthread.h>
+
+int main(int argc, char** argv)
+{
+    rt_kprintf("Hi, this is RT-Thread!!\n");
+
+    return 0;
+}

+ 7 - 0
bsp/rockchip/rk3500/driver/Kconfig

@@ -0,0 +1,7 @@
+menu "RT-Thread rockchip RK3500 drivers"
+
+source "$BSP_DIR/driver/clk/Kconfig"
+source "$BSP_DIR/driver/uart8250/Kconfig"
+source "$BSP_DIR/driver/reset/Kconfig"
+source "$BSP_DIR/driver/hwtimer/Kconfig"
+endmenu

+ 19 - 0
bsp/rockchip/rk3500/driver/SConscript

@@ -0,0 +1,19 @@
+# RT-Thread building script for component
+
+from building import *
+
+cwd     = GetCurrentDir()
+src     = Glob('*.c')
+list    = os.listdir(cwd)
+CPPPATH = [cwd]
+objs    = []
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
+
+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'))
+objs = objs + group
+
+Return('objs')

+ 37 - 0
bsp/rockchip/rk3500/driver/board.c

@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+#include <setup.h>
+#include <board.h>
+#include <psci.h>
+
+void rt_hw_board_init(void)
+{
+#if RT_VER_NUM < 0x50200
+    rt_fdt_commit_memregion_early(&(rt_region_t)
+    {
+        .name = "memheap",
+        .start = (rt_size_t)rt_kmem_v2p(HEAP_BEGIN),
+        .end = (rt_size_t)rt_kmem_v2p(HEAP_END),
+    }, RT_TRUE);
+#endif
+    rt_hw_common_setup();
+}
+
+void reboot(void)
+{
+    psci_system_reboot();
+}
+MSH_CMD_EXPORT(reboot, reboot...);
+
+void rt_hw_cpu_shutdown(void)
+{
+    psci_system_off();
+}
+MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_shutdown, shutdown, shutdown...);

+ 25 - 0
bsp/rockchip/rk3500/driver/board.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2017-5-30      Bernard      the first version
+ */
+
+#ifndef __BOARD_H__
+#define __BOARD_H__
+
+#include <rtdef.h>
+
+extern unsigned char __bss_start;
+extern unsigned char __bss_end;
+
+#define HEAP_BEGIN  (void *)&__bss_end
+#define HEAP_END    ((void *)HEAP_BEGIN + 64 * 1024 * 1024)
+
+
+void rt_hw_board_init(void);
+
+#endif /* __BOARD_H__ */

+ 15 - 0
bsp/rockchip/rk3500/driver/clk/Kconfig

@@ -0,0 +1,15 @@
+menuconfig RT_CLK_ROCKCHIP
+    bool "Rockchip clock controller common"
+    select RT_USING_OFW
+    select RT_USING_RESET
+    default n
+
+config RT_CLK_ROCKCHIP_RK3568
+    bool "Rockchip RK3568 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

+ 16 - 0
bsp/rockchip/rk3500/driver/clk/SConscript

@@ -0,0 +1,16 @@
+from building import *
+
+cwd = GetCurrentDir()
+CPPPATH = [cwd]
+
+src = []
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK3568']):
+    src += ['clk-rk3568.c']
+
+if GetDepend(['RT_CLK_ROCKCHIP_RK3588']):
+    src += ['clk-rk3588.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 123 - 0
bsp/rockchip/rk3500/driver/clk/clk-mmc-phase.c

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 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
+#define ROCKCHIP_MMC_DELAYNUM_MASK      (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET)
+/*
+ * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to
+ * simplify calculations. So 45degs could be anywhere between 33deg and 57.8deg.
+ */
+#define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60
+
+#define PSECS_PER_SEC 1000000000000LL
+
+#define RK3288_MMC_CLKGEN_DIV 2
+
+rt_inline rt_ubase_t rk_clk_mmc_recalc(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)
+{
+    rt_uint32_t raw_value, delay;
+    rt_uint8_t nineties, remainder, delay_num;
+
+    /*
+     * The below calculation is based on the output clock from
+     * MMC host to the card, which expects the phase clock inherits
+     * the clock rate from its parent, namely the output clock
+     * provider of MMC host. However, things may go wrong if
+     * (1) It is orphan.
+     * (2) It is assigned to the wrong parent.
+     *
+     * This check help debug the case (1), which seems to be the
+     * most likely problem we often face and which makes it difficult
+     * for people to debug unstable mmc tuning results.
+     */
+    if (!rate)
+    {
+        LOG_E("Invalid CLK rate in phase setting");
+
+        return -RT_EINVAL;
+    }
+
+    nineties = degrees / 90;
+    remainder = (degrees % 90);
+
+    /*
+     * Due to the inexact nature of the "fine" delay, we might
+     * actually go non-monotonic.  We don't go _too_ monotonic
+     * though, so we should be OK.  Here are options of how we may
+     * work:
+     *
+     * Ideally we end up with:
+     *   1.0, 2.0, ..., 69.0, 70.0, ...,  89.0, 90.0
+     *
+     * On one extreme (if delay is actually 44ps):
+     *   .73, 1.5, ..., 50.6, 51.3, ...,  65.3, 90.0
+     * The other (if delay is actually 77ps):
+     *   1.3, 2.6, ..., 88.6. 89.8, ..., 114.0, 90
+     *
+     * It's possible we might make a delay that is up to 25
+     * degrees off from what we think we're making.  That's OK
+     * though because we should be REALLY far from any bad range.
+     */
+
+    /*
+     * Convert to delay; do a little extra work to make sure we
+     * don't overflow 32-bit / 64-bit numbers.
+     */
+    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_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);
+
+    return RT_EOK;
+}
+
+static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift)
+{
+    rt_uint16_t degrees;
+    rt_uint32_t raw_value, delay_num = 0;
+
+    /* Constant signal, no measurable phase shift */
+    if (!rate)
+    {
+        return 0;
+    }
+
+    raw_value = HWREG32(reg) >> 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);
+
+        delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK);
+        delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET;
+        degrees += RT_DIV_ROUND_CLOSEST(delay_num * factor, 1000000);
+    }
+
+    return degrees % 360;
+}

+ 403 - 0
bsp/rockchip/rk3500/driver/clk/clk-pll-rk3568.c

@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-3-08      GuEe-GUI     the first version
+ */
+
+/* Define pll mode */
+#define RKCLK_PLL_MODE_SLOW     0
+#define RKCLK_PLL_MODE_NORMAL   1
+#define RKCLK_PLL_MODE_DEEP     2
+
+/* Only support RK3036 type CLK */
+#define PLLCON0_FBDIV_MASK      0xfff
+#define PLLCON0_FBDIV_SHIFT     0
+#define PLLCON0_POSTDIV1_MASK   (0x7 << 12)
+#define PLLCON0_POSTDIV1_SHIFT  12
+#define PLLCON1_LOCK_STATUS     (1 << 10)
+#define PLLCON1_REFDIV_MASK     0x3f
+#define PLLCON1_REFDIV_SHIFT    0
+#define PLLCON1_POSTDIV2_MASK   (0x7 << 6)
+#define PLLCON1_POSTDIV2_SHIFT  6
+#define PLLCON1_DSMPD_MASK      (0x1 << 12)
+#define PLLCON1_DSMPD_SHIFT     12
+#define PLLCON2_FRAC_MASK       0xffffff
+#define PLLCON2_FRAC_SHIFT      0
+#define PLLCON1_PWRDOWN_SHIT    13
+#define PLLCON1_PWRDOWN         (1 << PLLCON1_PWRDOWN_SHIT)
+
+#define MIN_FOUTVCO_FREQ        (800 * MHZ)
+#define MAX_FOUTVCO_FREQ        (2000 * MHZ)
+
+static struct rk_pll_rate_table auto_table;
+
+static int 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
+ */
+static 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;
+}
+
+/*
+ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
+ * Formulas also embedded within the Fractional PLL Verilog model:
+ * If DSMPD = 1 (DSM is disabled, "integer mode")
+ * FOUTVCO = FREF / REFDIV * FBDIV
+ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
+ * Where:
+ * FOUTVCO = Fractional PLL non-divided output frequency
+ * FOUTPOSTDIV = Fractional PLL divided output frequency
+ *               (output of second post divider)
+ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
+ * REFDIV = Fractional PLL input reference clock divider
+ * FBDIV = Integer value programmed into feedback divide
+ */
+
+static int rk_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 0;
+                }
+            }
+        }
+    }
+    else
+    {
+        *postdiv1 = 1;
+        *postdiv2 = 1;
+    }
+    return 0;
+}
+
+static struct rk_pll_rate_table *rk_pll_clk_set_by_auto(rt_ubase_t fin_hz, rt_ubase_t fout_hz)
+{
+    struct rk_pll_rate_table *rate_table = &auto_table;
+    rt_uint32_t foutvco = fout_hz;
+    rt_ubase_t fin_64, frac_64;
+    rt_uint32_t f_frac, postdiv1, postdiv2;
+    rt_ubase_t clk_gcd = 0;
+
+    if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+    {
+        return RT_NULL;
+    }
+
+    rk_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 = gcd(fin_hz, foutvco);
+        rate_table->refdiv = fin_hz / clk_gcd;
+        rate_table->fbdiv = foutvco / clk_gcd;
+
+        rate_table->frac = 0;
+    }
+    else
+    {
+        clk_gcd = 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;
+        fin_64 = fin_64 / rate_table->refdiv;
+        frac_64 = f_frac << 24;
+        frac_64 = frac_64 / fin_64;
+        rate_table->frac = frac_64;
+
+        if (rate_table->frac > 0)
+        {
+            rate_table->dsmpd = 0;
+        }
+    }
+    return rate_table;
+}
+
+static const struct rk_pll_rate_table *rk_get_pll_settings(struct rk_pll_clock *pll, rt_ubase_t rate)
+{
+    struct rk_pll_rate_table *rate_table = pll->rate_table;
+
+    while (rate_table->rate)
+    {
+        if (rate_table->rate == rate)
+        {
+            break;
+        }
+        ++rate_table;
+    }
+
+    if (rate_table->rate != rate)
+    {
+        return rk_pll_clk_set_by_auto(24 * MHZ, rate);
+    }
+    else
+    {
+        return rate_table;
+    }
+}
+
+static rt_ubase_t rk_pll_get_rate(struct rk_pll_clock *pll, void *base);
+
+static int rk_pll_set_rate(struct rk_pll_clock *pll, void *base, rt_ubase_t drate)
+{
+    const struct rk_pll_rate_table *rate;
+
+    if (rk_pll_get_rate(pll, base) == drate)
+    {
+        return 0;
+    }
+
+    pll->mode_mask = PLL_MODE_MASK;
+    rate = rk_get_pll_settings(pll, drate);
+
+    if (!rate)
+    {
+        return -RT_ERROR;
+    }
+
+    /*
+     * When power on or changing PLL setting, we must force PLL into slow mode
+     * to ensure output stable clock.
+     */
+    rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_SLOW << pll->mode_shift);
+
+    /* Power down */
+    rk_setreg(base + pll->con_offset + 0x4, 1 << PLLCON1_PWRDOWN_SHIT);
+
+    rk_clrsetreg(base + pll->con_offset, (PLLCON0_POSTDIV1_MASK | PLLCON0_FBDIV_MASK),
+            (rate->postdiv1 << PLLCON0_POSTDIV1_SHIFT) |rate->fbdiv);
+    rk_clrsetreg(base + pll->con_offset + 0x4, (PLLCON1_POSTDIV2_MASK | PLLCON1_REFDIV_MASK),
+            (rate->postdiv2 << PLLCON1_POSTDIV2_SHIFT | rate->refdiv << PLLCON1_REFDIV_SHIFT));
+
+    if (!rate->dsmpd)
+    {
+        rt_uint32_t val;
+
+        rk_clrsetreg(base + pll->con_offset + 0x4, PLLCON1_DSMPD_MASK,
+                rate->dsmpd << PLLCON1_DSMPD_SHIFT);
+
+        val = HWREG32(base + pll->con_offset + 0x8) & (~PLLCON2_FRAC_MASK);
+        HWREG32(base + pll->con_offset + 0x8) = val | (rate->frac << PLLCON2_FRAC_SHIFT);
+    }
+
+    /* Power Up */
+    rk_clrreg(base + pll->con_offset + 0x4, 1 << PLLCON1_PWRDOWN_SHIT);
+
+    /* Waiting for pll lock */
+    while (!(HWREG32(base + pll->con_offset + 0x4) & (1 << pll->lock_shift)))
+    {
+    }
+
+    rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
+
+    return 0;
+}
+
+static rt_ubase_t rk_pll_get_rate(struct rk_pll_clock *pll, void *base)
+{
+    rt_uint32_t refdiv, fbdiv, postdiv1, postdiv2, dsmpd, frac;
+    rt_uint32_t con = 0, shift, mask;
+    rt_ubase_t rate;
+
+    pll->mode_mask = PLL_MODE_MASK;
+
+    con = HWREG32(base + pll->mode_offset);
+    shift = pll->mode_shift;
+    mask = pll->mode_mask << shift;
+
+    switch ((con & mask) >> shift)
+    {
+    case RKCLK_PLL_MODE_SLOW:
+        return OSC_HZ;
+    case RKCLK_PLL_MODE_NORMAL:
+        /* normal mode */
+        con = HWREG32(base + pll->con_offset);
+        postdiv1 = (con & PLLCON0_POSTDIV1_MASK) >> PLLCON0_POSTDIV1_SHIFT;
+        fbdiv = (con & PLLCON0_FBDIV_MASK) >> PLLCON0_FBDIV_SHIFT;
+        con = HWREG32(base + pll->con_offset + 0x4);
+        postdiv2 = (con & PLLCON1_POSTDIV2_MASK) >> PLLCON1_POSTDIV2_SHIFT;
+        refdiv = (con & PLLCON1_REFDIV_MASK) >> PLLCON1_REFDIV_SHIFT;
+        dsmpd = (con & PLLCON1_DSMPD_MASK) >> PLLCON1_DSMPD_SHIFT;
+        con = HWREG32(base + pll->con_offset + 0x8);
+        frac = (con & PLLCON2_FRAC_MASK) >> PLLCON2_FRAC_SHIFT;
+        rate = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+
+        if (dsmpd == 0)
+        {
+            rt_uint64_t frac_rate = OSC_HZ * (rt_uint64_t)frac;
+
+            rt_do_div(frac_rate, refdiv);
+            frac_rate >>= 24;
+            rt_do_div(frac_rate, postdiv1);
+            rt_do_div(frac_rate, postdiv1);
+            rate += frac_rate;
+        }
+        return rate;
+    case RKCLK_PLL_MODE_DEEP:
+    default:
+        return 32768;
+    }
+}
+
+static const struct rk_cpu_rate_table *rk_get_cpu_settings(struct rk_cpu_rate_table *cpu_table, rt_ubase_t rate)
+{
+    struct rk_cpu_rate_table *ps = cpu_table;
+
+    while (ps->rate)
+    {
+        if (ps->rate == rate)
+        {
+            break;
+        }
+        ++ps;
+    }
+    if (ps->rate != rate)
+    {
+        return RT_NULL;
+    }
+    else
+    {
+        return ps;
+    }
+}
+
+static rt_base_t rk_clk_pll_round_rate(const struct rk_pll_rate_table *pll_rates,
+        rt_size_t rate_count, rt_ubase_t drate, rt_ubase_t *prate)
+{
+    int i;
+
+    /* Assumming rate_table is in descending order */
+    for (i = 0; i < rate_count; i++)
+    {
+        if (drate >= pll_rates[i].rate)
+        {
+            return pll_rates[i].rate;
+        }
+    }
+
+    /* return minimum supported value */
+    return pll_rates[i - 1].rate;
+}
+
+static void rk_clk_set_default_rates(struct rt_clk *clk,
+        rt_err_t (*clk_set_rate)(struct rt_clk *, rt_ubase_t, rt_ubase_t), int id)
+{
+    rt_uint32_t rate;
+    struct rt_ofw_cell_args clk_args;
+    struct rt_ofw_node *np = clk->fw_node;
+    const char *rate_propname = "assigned-clock-rates";
+
+    if (!rt_ofw_prop_read_bool(np, rate_propname))
+    {
+        return;
+    }
+
+    for (int i = 0; ; ++i)
+    {
+        if (rt_ofw_parse_phandle_cells(np, "assigned-clocks", "#clock-cells", i, &clk_args))
+        {
+            break;
+        }
+
+        rt_ofw_node_put(clk_args.data);
+
+        if (clk_args.args[0] != id)
+        {
+            continue;
+        }
+
+        if (!rt_ofw_prop_read_u32_index(np, rate_propname, i, &rate))
+        {
+            clk_set_rate(clk, rate, 0);
+        }
+
+        break;
+    }
+}

+ 727 - 0
bsp/rockchip/rk3500/driver/clk/clk-pll-rk3588.c

@@ -0,0 +1,727 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-11-03     zmshahaha    the first version
+ */
+
+#define PLL_MODE_MASK               0x3
+#define PLL_RK3328_MODE_MASK            0x1
+
+/* Define pll mode */
+#define RKCLK_PLL_MODE_SLOW     0
+#define RKCLK_PLL_MODE_NORMAL   1
+#define RKCLK_PLL_MODE_DEEP     2
+
+/* Only support RK3036 type CLK */
+#define RK3036_PLLCON0_FBDIV_MASK      0xfff
+#define RK3036_PLLCON0_FBDIV_SHIFT     0
+#define RK3036_PLLCON0_POSTDIV1_MASK   (0x7 << 12)
+#define RK3036_PLLCON0_POSTDIV1_SHIFT  12
+#define RK3036_PLLCON1_LOCK_STATUS     (1 << 10)
+#define RK3036_PLLCON1_REFDIV_MASK     0x3f
+#define RK3036_PLLCON1_REFDIV_SHIFT    0
+#define RK3036_PLLCON1_POSTDIV2_MASK   (0x7 << 6)
+#define RK3036_PLLCON1_POSTDIV2_SHIFT  6
+#define RK3036_PLLCON1_DSMPD_MASK      (0x1 << 12)
+#define RK3036_PLLCON1_DSMPD_SHIFT     12
+#define RK3036_PLLCON2_FRAC_MASK       0xffffff
+#define RK3036_PLLCON2_FRAC_SHIFT      0
+#define RK3036_PLLCON1_PWRDOWN_SHIT    13
+#define RK3036_PLLCON1_PWRDOWN         (1 << RK3036_PLLCON1_PWRDOWN_SHIT)
+
+#define VCO_MAX_HZ      (3200UL * MHZ)
+#define VCO_MIN_HZ      (800UL * MHZ)
+#define OUTPUT_MAX_HZ       (3200UL * MHZ)
+#define OUTPUT_MIN_HZ       (24UL * MHZ)
+#define MIN_FOUTVCO_FREQ    (800UL * MHZ)
+#define MAX_FOUTVCO_FREQ    (2000UL * MHZ)
+
+#define RK3588_VCO_MIN_HZ   (2250UL * MHZ)
+#define RK3588_VCO_MAX_HZ   (4500UL * MHZ)
+#define RK3588_FOUT_MIN_HZ  (37UL * MHZ)
+#define RK3588_FOUT_MAX_HZ  (4500UL * MHZ)
+
+#define RK3588_PLLCON(i)        ((i) * 0x4)
+#define RK3588_PLLCON0_M_MASK       (0x3ff << 0)
+#define RK3588_PLLCON0_M_SHIFT      0
+#define RK3588_PLLCON1_P_MASK       (0x3f << 0)
+#define RK3588_PLLCON1_P_SHIFT      0
+#define RK3588_PLLCON1_S_MASK       (0x7 << 6)
+#define RK3588_PLLCON1_S_SHIFT      6
+#define RK3588_PLLCON2_K_MASK       0xffff
+#define RK3588_PLLCON2_K_SHIFT      0
+#define RK3588_PLLCON1_PWRDOWN      (1 << 13)
+#define RK3588_PLLCON6_LOCK_STATUS  (1 << 15)
+#define RK3588_B0PLL_CLKSEL_CON(i)  ((i) * 0x4 + 0x50000 + 0x300)
+#define RK3588_B1PLL_CLKSEL_CON(i)  ((i) * 0x4 + 0x52000 + 0x300)
+#define RK3588_LPLL_CLKSEL_CON(i)   ((i) * 0x4 + 0x58000 + 0x300)
+#define RK3588_CORE_DIV_MASK        0x1f
+#define RK3588_CORE_L02_DIV_SHIFT   0
+#define RK3588_CORE_L13_DIV_SHIFT   7
+#define RK3588_CORE_B02_DIV_SHIFT   8
+#define RK3588_CORE_B13_DIV_SHIFT   0
+
+static struct rk_pll_rate_table auto_table;
+
+static int 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;
+}
+
+/*
+ * How to calculate the PLL(from TRM V0.3 Part 1 Page 63):
+ * Formulas also embedded within the Fractional PLL Verilog model:
+ * If DSMPD = 1 (DSM is disabled, "integer mode")
+ * FOUTVCO = FREF / REFDIV * FBDIV
+ * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2
+ * Where:
+ * FOUTVCO = Fractional PLL non-divided output frequency
+ * FOUTPOSTDIV = Fractional PLL divided output frequency
+ *               (output of second post divider)
+ * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input)
+ * REFDIV = Fractional PLL input reference clock divider
+ * FBDIV = Integer value programmed into feedback divide
+ */
+
+static int rk_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 0;
+                }
+            }
+        }
+    }
+    else
+    {
+        *postdiv1 = 1;
+        *postdiv2 = 1;
+    }
+    return 0;
+}
+
+static struct rk_pll_rate_table *rk_pll_clk_set_by_auto(rt_ubase_t fin_hz, rt_ubase_t fout_hz)
+{
+    struct rk_pll_rate_table *rate_table = &auto_table;
+    rt_uint32_t foutvco = fout_hz;
+    rt_ubase_t fin_64, frac_64;
+    rt_uint32_t f_frac, postdiv1, postdiv2;
+    rt_ubase_t clk_gcd = 0;
+
+    if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+    {
+        return RT_NULL;
+    }
+
+    rk_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 = gcd(fin_hz, foutvco);
+        rate_table->refdiv = fin_hz / clk_gcd;
+        rate_table->fbdiv = foutvco / clk_gcd;
+
+        rate_table->frac = 0;
+    }
+    else
+    {
+        clk_gcd = 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;
+        fin_64 = fin_64 / rate_table->refdiv;
+        frac_64 = f_frac << 24;
+        frac_64 = frac_64 / fin_64;
+        rate_table->frac = frac_64;
+
+        if (rate_table->frac > 0)
+        {
+            rate_table->dsmpd = 0;
+        }
+    }
+    return rate_table;
+}
+
+static struct rk_pll_rate_table *
+rk3588_pll_clk_set_by_auto(rt_ubase_t fin_hz,
+               rt_ubase_t fout_hz)
+{
+    struct rk_pll_rate_table *rate_table = &auto_table;
+    rt_uint32_t p, m, s;
+    rt_ubase_t fvco, fref, fout, ffrac;
+
+    if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz)
+        return NULL;
+
+    if (fout_hz > RK3588_FOUT_MAX_HZ || fout_hz < RK3588_FOUT_MIN_HZ)
+        return NULL;
+
+    if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz)
+    {
+        for (s = 0; s <= 6; s++)
+        {
+            fvco = fout_hz << s;
+            if (fvco < RK3588_VCO_MIN_HZ ||
+                fvco > RK3588_VCO_MAX_HZ)
+                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;
+                    }
+                }
+            }
+        }
+        LOG_E("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
+    } else {
+        for (s = 0; s <= 6; s++)
+        {
+            fvco = fout_hz << s;
+            if (fvco < RK3588_VCO_MIN_HZ ||
+                fvco > RK3588_VCO_MAX_HZ)
+                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))
+                    {
+                        rate_table->p = p;
+                        rate_table->m = m;
+                        rate_table->s = s;
+                        fref = fin_hz / p;
+                        ffrac = fvco - (m * fref);
+                        fout = ffrac * 65536;
+                        rate_table->k = fout / fref;
+                        return rate_table;
+                    }
+                }
+            }
+        }
+        LOG_E("CANNOT FIND Fout by auto,fout = %lu\n", fout_hz);
+    }
+    return NULL;
+}
+
+static const struct rk_pll_rate_table *rk_get_pll_settings(struct rk_pll_clock *pll, rt_ubase_t rate)
+{
+    struct rk_pll_rate_table *rate_table = pll->rate_table;
+
+    while (rate_table->rate)
+    {
+        if (rate_table->rate == rate)
+        {
+            break;
+        }
+        ++rate_table;
+    }
+
+    if (rate_table->rate != rate)
+    {
+        if (pll->type == pll_rk3588)
+            return rk3588_pll_clk_set_by_auto(24 * MHZ, rate);
+        else
+            return rk_pll_clk_set_by_auto(24 * MHZ, rate);
+    }
+    else
+    {
+        return rate_table;
+    }
+}
+
+static int rk3036_pll_set_rate(struct rk_pll_clock *pll, void *base, rt_ubase_t pll_id, rt_ubase_t drate)
+{
+    const struct rk_pll_rate_table *rate;
+
+    rate = rk_get_pll_settings(pll, drate);
+
+    if (!rate)
+    {
+        return -RT_ERROR;
+    }
+
+    /*
+     * When power on or changing PLL setting, we must force PLL into slow mode
+     * to ensure output stable clock.
+     */
+    rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_SLOW << pll->mode_shift);
+
+    /* Power down */
+    rk_setreg(base + pll->con_offset + 0x4, 1 << RK3036_PLLCON1_PWRDOWN_SHIT);
+
+    rk_clrsetreg(base + pll->con_offset, (RK3036_PLLCON0_POSTDIV1_MASK | RK3036_PLLCON0_FBDIV_MASK),
+            (rate->postdiv1 << RK3036_PLLCON0_POSTDIV1_SHIFT) |rate->fbdiv);
+    rk_clrsetreg(base + pll->con_offset + 0x4, (RK3036_PLLCON1_POSTDIV2_MASK | RK3036_PLLCON1_REFDIV_MASK),
+            (rate->postdiv2 << RK3036_PLLCON1_POSTDIV2_SHIFT | rate->refdiv << RK3036_PLLCON1_REFDIV_SHIFT));
+
+    if (!rate->dsmpd)
+    {
+        rt_uint32_t val;
+
+        rk_clrsetreg(base + pll->con_offset + 0x4, RK3036_PLLCON1_DSMPD_MASK,
+                rate->dsmpd << RK3036_PLLCON1_DSMPD_SHIFT);
+
+        val = HWREG32(base + pll->con_offset + 0x8) & (~RK3036_PLLCON2_FRAC_MASK);
+        HWREG32(base + pll->con_offset + 0x8) = val | (rate->frac << RK3036_PLLCON2_FRAC_SHIFT);
+    }
+
+    /* Power Up */
+    rk_clrreg(base + pll->con_offset + 0x4, 1 << RK3036_PLLCON1_PWRDOWN_SHIT);
+
+    /* Waiting for pll lock */
+    while (!(HWREG32(base + pll->con_offset + 0x4) & (1 << pll->lock_shift)))
+    {
+    }
+
+    rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
+
+    return 0;
+}
+
+static rt_ubase_t rk3036_pll_get_rate(struct rk_pll_clock *pll, void *base, rt_ubase_t pll_id)
+{
+    rt_uint32_t refdiv, fbdiv, postdiv1, postdiv2, dsmpd, frac;
+    rt_uint32_t con = 0, shift, mask;
+    rt_ubase_t rate;
+
+    pll->mode_mask = PLL_MODE_MASK;
+
+    con = HWREG32(base + pll->mode_offset);
+    shift = pll->mode_shift;
+    mask = pll->mode_mask << shift;
+
+    switch ((con & mask) >> shift)
+    {
+    case RKCLK_PLL_MODE_SLOW:
+        return OSC_HZ;
+    case RKCLK_PLL_MODE_NORMAL:
+        /* normal mode */
+        con = HWREG32(base + pll->con_offset);
+        postdiv1 = (con & RK3036_PLLCON0_POSTDIV1_MASK) >> RK3036_PLLCON0_POSTDIV1_SHIFT;
+        fbdiv = (con & RK3036_PLLCON0_FBDIV_MASK) >> RK3036_PLLCON0_FBDIV_SHIFT;
+        con = HWREG32(base + pll->con_offset + 0x4);
+        postdiv2 = (con & RK3036_PLLCON1_POSTDIV2_MASK) >> RK3036_PLLCON1_POSTDIV2_SHIFT;
+        refdiv = (con & RK3036_PLLCON1_REFDIV_MASK) >> RK3036_PLLCON1_REFDIV_SHIFT;
+        dsmpd = (con & RK3036_PLLCON1_DSMPD_MASK) >> RK3036_PLLCON1_DSMPD_SHIFT;
+        con = HWREG32(base + pll->con_offset + 0x8);
+        frac = (con & RK3036_PLLCON2_FRAC_MASK) >> RK3036_PLLCON2_FRAC_SHIFT;
+        rate = (24 * fbdiv / (refdiv * postdiv1 * postdiv2)) * 1000000;
+
+        if (dsmpd == 0)
+        {
+            rt_uint64_t frac_rate = OSC_HZ * (rt_uint64_t)frac;
+
+            rt_do_div(frac_rate, refdiv);
+            frac_rate >>= 24;
+            rt_do_div(frac_rate, postdiv1);
+            rt_do_div(frac_rate, postdiv1);
+            rate += frac_rate;
+        }
+        return rate;
+    case RKCLK_PLL_MODE_DEEP:
+    default:
+        return 32768;
+    }
+}
+
+static int rk3588_pll_set_rate(struct rk_pll_clock *pll,
+                   void *base, rt_ubase_t pll_id,
+                   rt_ubase_t drate)
+{
+    const struct rk_pll_rate_table *rate;
+
+    rate = rk_get_pll_settings(pll, drate);
+    if (!rate)
+    {
+        LOG_D("%s unsupported rate\n", __func__);
+        return -RT_EINVAL;
+    }
+
+    LOG_D("%s: rate settings for %lu p: %d, m: %d, s: %d, k: %d\n",
+          __func__, rate->rate, rate->p, rate->m, rate->s, rate->k);
+
+    /*
+     * When power on or changing PLL setting,
+     * we must force PLL into slow mode to ensure output stable clock.
+     */
+    if (pll_id == 3)
+        rk_clrsetreg(base + 0x84c, 0x1 << 1, 0x1 << 1);
+
+    rk_clrsetreg(base + pll->mode_offset,
+             pll->mode_mask << pll->mode_shift,
+             RKCLK_PLL_MODE_SLOW << pll->mode_shift);
+    if (pll_id == 0)
+        rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
+                 pll->mode_mask << 6,
+                 RKCLK_PLL_MODE_SLOW << 6);
+    else if (pll_id == 1)
+        rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
+                 pll->mode_mask << 6,
+                 RKCLK_PLL_MODE_SLOW << 6);
+    else if (pll_id == 2)
+        rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(5),
+                 pll->mode_mask << 14,
+                 RKCLK_PLL_MODE_SLOW << 14);
+
+    /* Power down */
+    rk_setreg(base + pll->con_offset + RK3588_PLLCON(1),
+          RK3588_PLLCON1_PWRDOWN);
+
+    rk_clrsetreg(base + pll->con_offset,
+             RK3588_PLLCON0_M_MASK,
+             (rate->m << RK3588_PLLCON0_M_SHIFT));
+    rk_clrsetreg(base + pll->con_offset + RK3588_PLLCON(1),
+             (RK3588_PLLCON1_P_MASK |
+             RK3588_PLLCON1_S_MASK),
+             (rate->p << RK3588_PLLCON1_P_SHIFT |
+             rate->s << RK3588_PLLCON1_S_SHIFT));
+    if (rate->k)
+    {
+        rk_clrsetreg(base + pll->con_offset + RK3588_PLLCON(2),
+                 RK3588_PLLCON2_K_MASK,
+                 rate->k << RK3588_PLLCON2_K_SHIFT);
+    }
+    /* Power up */
+    rk_clrreg(base + pll->con_offset + RK3588_PLLCON(1),
+          RK3588_PLLCON1_PWRDOWN);
+
+    /* waiting for pll lock */
+    while (!(HWREG32(base + pll->con_offset + RK3588_PLLCON(6)) &
+        RK3588_PLLCON6_LOCK_STATUS))
+    {
+    }
+
+    rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift,
+             RKCLK_PLL_MODE_NORMAL << pll->mode_shift);
+    if (pll_id == 0)
+    {
+        rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
+                 pll->mode_mask << 6,
+                 2 << 6);
+        rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(0),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_B02_DIV_SHIFT,
+                 0 << RK3588_CORE_B02_DIV_SHIFT);
+        rk_clrsetreg(base + RK3588_B0PLL_CLKSEL_CON(1),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_B13_DIV_SHIFT,
+                 0 << RK3588_CORE_B13_DIV_SHIFT);
+    } else if (pll_id == 1)
+    {
+        rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
+                 pll->mode_mask << 6,
+                 2 << 6);
+        rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(0),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_B02_DIV_SHIFT,
+                 0 << RK3588_CORE_B02_DIV_SHIFT);
+        rk_clrsetreg(base + RK3588_B1PLL_CLKSEL_CON(1),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_B13_DIV_SHIFT,
+                 0 << RK3588_CORE_B13_DIV_SHIFT);
+    } else if (pll_id == 2)
+    {
+        rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(5),
+                 pll->mode_mask << 14,
+                 2 << 14);
+        rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(6),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_L13_DIV_SHIFT,
+                 0 << RK3588_CORE_L13_DIV_SHIFT);
+        rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(6),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_L02_DIV_SHIFT,
+                 0 << RK3588_CORE_L02_DIV_SHIFT);
+        rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(7),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_L13_DIV_SHIFT,
+                 0 << RK3588_CORE_L13_DIV_SHIFT);
+        rk_clrsetreg(base + RK3588_LPLL_CLKSEL_CON(7),
+                 RK3588_CORE_DIV_MASK << RK3588_CORE_L02_DIV_SHIFT,
+                 0 << RK3588_CORE_L02_DIV_SHIFT);
+    }
+
+    if (pll_id == 3)
+        rk_clrsetreg(base + 0x84c, 0x1 << 1, 0);
+
+    LOG_D("PLL at %p: con0=%x con1= %x con2= %x mode= %x\n",
+          pll, HWREG32(base + pll->con_offset),
+          HWREG32(base + pll->con_offset + 0x4),
+          HWREG32(base + pll->con_offset + 0x8),
+          HWREG32(base + pll->mode_offset));
+
+    return 0;
+}
+
+static rt_ubase_t rk3588_pll_get_rate(struct rk_pll_clock *pll,
+                 void *base, rt_ubase_t pll_id)
+{
+    rt_uint32_t m, p, s, k;
+    rt_uint32_t con = 0, shift, mode;
+    rt_uint64_t rate, postdiv;
+
+    con = HWREG32(base + pll->mode_offset);
+    shift = pll->mode_shift;
+    if (pll_id == 8)
+        mode = RKCLK_PLL_MODE_NORMAL;
+    else
+        mode = (con & (pll->mode_mask << shift)) >> shift;
+    switch (mode)
+    {
+    case RKCLK_PLL_MODE_SLOW:
+        return OSC_HZ;
+    case RKCLK_PLL_MODE_NORMAL:
+        /* normal mode */
+        con = HWREG32(base + pll->con_offset);
+        m = (con & RK3588_PLLCON0_M_MASK) >>
+               RK3588_PLLCON0_M_SHIFT;
+        con = HWREG32(base + pll->con_offset + RK3588_PLLCON(1));
+        p = (con & RK3588_PLLCON1_P_MASK) >>
+               RK3036_PLLCON0_FBDIV_SHIFT;
+        s = (con & RK3588_PLLCON1_S_MASK) >>
+             RK3588_PLLCON1_S_SHIFT;
+        con = HWREG32(base + pll->con_offset + RK3588_PLLCON(2));
+        k = (con & RK3588_PLLCON2_K_MASK) >>
+            RK3588_PLLCON2_K_SHIFT;
+
+        rate = OSC_HZ / p;
+        rate *= m;
+        if (k)
+        {
+            /* fractional mode */
+            rt_uint64_t frac_rate64 = OSC_HZ * k;
+
+            postdiv = p * 65536;
+            rt_do_div(frac_rate64, postdiv);
+            rate += frac_rate64;
+        }
+        rate = rate >> s;
+        return rate;
+    case RKCLK_PLL_MODE_DEEP:
+    default:
+        return 32768;
+    }
+}
+
+rt_ubase_t rk_pll_get_rate(struct rk_pll_clock *pll,
+                void *base,
+                rt_ubase_t pll_id)
+{
+    rt_ubase_t rate = 0;
+
+    switch (pll->type)
+    {
+    case pll_rk3036:
+        pll->mode_mask = PLL_MODE_MASK;
+        rate = rk3036_pll_get_rate(pll, base, pll_id);
+        break;
+    case pll_rk3328:
+        pll->mode_mask = PLL_RK3328_MODE_MASK;
+        rate = rk3036_pll_get_rate(pll, base, pll_id);
+        break;
+    case pll_rk3588:
+        pll->mode_mask = PLL_MODE_MASK;
+        rate = rk3588_pll_get_rate(pll, base, pll_id);
+        break;
+    default:
+        LOG_D("%s: Unknown pll type for pll clk %ld\n",
+               __func__, pll_id);
+    }
+    return rate;
+}
+
+int rk_pll_set_rate(struct rk_pll_clock *pll,
+              void *base, rt_ubase_t pll_id,
+              rt_ubase_t drate)
+{
+    int ret = 0;
+
+    if (rk_pll_get_rate(pll, base, pll_id) == drate)
+        return 0;
+
+    switch (pll->type)
+    {
+    case pll_rk3036:
+        pll->mode_mask = PLL_MODE_MASK;
+        ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
+        break;
+    case pll_rk3328:
+        pll->mode_mask = PLL_RK3328_MODE_MASK;
+        ret = rk3036_pll_set_rate(pll, base, pll_id, drate);
+        break;
+    case pll_rk3588:
+        pll->mode_mask = PLL_MODE_MASK;
+        ret = rk3588_pll_set_rate(pll, base, pll_id, drate);
+        break;
+    default:
+        LOG_D("%s: Unknown pll type for pll clk %ld\n",
+               __func__, pll_id);
+    }
+    return ret;
+}
+
+const struct rk_cpu_rate_table *rk_get_cpu_settings(struct rk_cpu_rate_table *cpu_table, rt_ubase_t rate)
+{
+    struct rk_cpu_rate_table *ps = cpu_table;
+
+    while (ps->rate)
+    {
+        if (ps->rate == rate)
+        {
+            break;
+        }
+        ++ps;
+    }
+    if (ps->rate != rate)
+    {
+        return RT_NULL;
+    }
+    else
+    {
+        return ps;
+    }
+}
+
+rt_base_t rk_clk_pll_round_rate(const struct rk_pll_rate_table *pll_rates,
+        rt_size_t rate_count, rt_ubase_t drate, rt_ubase_t *prate)
+{
+    int i;
+
+    /* Assumming rate_table is in descending order */
+    for (i = 0; i < rate_count; i++)
+    {
+        if (drate >= pll_rates[i].rate)
+        {
+            return pll_rates[i].rate;
+        }
+    }
+
+    /* return minimum supported value */
+    return pll_rates[i - 1].rate;
+}
+
+void rk_clk_set_default_rates(struct rt_clk *clk,
+        rt_err_t (*clk_set_rate)(struct rt_clk *, rt_ubase_t, rt_ubase_t), int id)
+{
+    rt_uint32_t rate;
+    struct rt_ofw_cell_args clk_args;
+    struct rt_ofw_node *np = clk->fw_node;
+    const char *rate_propname = "assigned-clock-rates";
+
+    if (!rt_ofw_prop_read_bool(np, rate_propname))
+    {
+        return;
+    }
+
+    for (int i = 0; ; ++i)
+    {
+        if (rt_ofw_parse_phandle_cells(np, "assigned-clocks", "#clock-cells", i, &clk_args))
+        {
+            break;
+        }
+
+        rt_ofw_node_put(clk_args.data);
+
+        if (clk_args.args[0] != id)
+        {
+            continue;
+        }
+
+        if (!rt_ofw_prop_read_u32_index(np, rate_propname, i, &rate))
+        {
+            clk_set_rate(clk, rate, 0);
+        }
+
+        break;
+    }
+}

+ 4800 - 0
bsp/rockchip/rk3500/driver/clk/clk-rk3568.c

@@ -0,0 +1,4800 @@
+/*
+ * Copyright (c) 2006-2024 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-rk3568.h"
+
+#define DBG_TAG "clk.rk3568"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include "rk3568-cru.h"
+
+#define APLL_HZ (816 * MHZ)
+#define GPLL_HZ (1188 * MHZ)
+#define CPLL_HZ (1000 * MHZ)
+#define PPLL_HZ (100 * MHZ)
+
+#define rt_abs(x)                       \
+({                                      \
+    long ret;                           \
+    if (sizeof(x) == sizeof(long))      \
+    {                                   \
+        long __x = (x);                 \
+        ret = (__x < 0) ? -__x : __x;   \
+    }                                   \
+    else                                \
+    {                                   \
+        int __x = (x);                  \
+        ret = (__x < 0) ? -__x : __x;   \
+    }                                   \
+    ret;                                \
+})
+
+struct rk_pll
+{
+    rt_uint32_t con0;
+    rt_uint32_t con1;
+    rt_uint32_t con2;
+    rt_uint32_t con3;
+    rt_uint32_t con4;
+    rt_uint32_t reserved0[3];
+};
+
+struct rk_pmucru
+{
+    struct rk_pll pll[2];
+    rt_uint32_t reserved0[16];
+    rt_uint32_t mode_con00;
+    rt_uint32_t reserved1[31];
+    rt_uint32_t pmu_clksel_con[10];
+    rt_uint32_t reserved2[22];
+    rt_uint32_t pmu_clkgate_con[3];
+    rt_uint32_t reserved3[29];
+    rt_uint32_t pmu_softrst_con[1];
+};
+
+struct rk_cru
+{
+    struct rk_pll pll[6];
+    rt_uint32_t mode_con00;
+    rt_uint32_t misc_con[3];
+    rt_uint32_t glb_cnt_th;
+    rt_uint32_t glb_srst_fst;
+    rt_uint32_t glb_srsr_snd;
+    rt_uint32_t glb_rst_con;
+    rt_uint32_t glb_rst_st;
+    rt_uint32_t reserved0[7];
+    rt_uint32_t clksel_con[85];
+    rt_uint32_t reserved1[43];
+    rt_uint32_t clkgate_con[36];
+    rt_uint32_t reserved2[28];
+    rt_uint32_t softrst_con[30];
+    rt_uint32_t reserved3[2];
+    rt_uint32_t ssgtbl[32];
+    rt_uint32_t reserved4[32];
+    rt_uint32_t sdmmc0_con[2];
+    rt_uint32_t sdmmc1_con[2];
+    rt_uint32_t sdmmc2_con[2];
+    rt_uint32_t emmc_con[2];
+};
+
+struct rk_pmuclk_priv
+{
+    struct rk_pmucru *pmucru;
+    rt_ubase_t ppll_hz;
+    rt_ubase_t hpll_hz;
+};
+
+struct rk_clk_priv
+{
+    struct rk_cru *cru;
+    rt_ubase_t ppll_hz;
+    rt_ubase_t hpll_hz;
+    rt_ubase_t gpll_hz;
+    rt_ubase_t cpll_hz;
+    rt_ubase_t npll_hz;
+    rt_ubase_t vpll_hz;
+    rt_ubase_t armclk_hz;
+    rt_ubase_t armclk_enter_hz;
+    rt_ubase_t armclk_init_hz;
+    rt_bool_t sync_kernel;
+    rt_bool_t set_armclk_rate;
+};
+
+struct rk_clk_platform_data
+{
+    rt_uint32_t id;
+    void *base;
+};
+
+enum rk_clk_type
+{
+    rk_clk_type_clk,
+    rk_clk_type_pmuclk,
+};
+
+struct rk_clk
+{
+    struct rt_reset_controller_clk_node parent;
+
+    void *base;
+    enum rk_clk_type type;
+
+    union
+    {
+        struct rk_clk_priv clk_info;
+        struct rk_pmuclk_priv pmuclk_info;
+    };
+
+    struct rk_clk_platform_data pdata[];
+};
+
+#define raw_to_rk_clk(raw) rt_container_of(raw, struct rk_clk, parent)
+
+#define PMU_MODE                0x80
+#define PMU_PLL_CON(x)          ((x) * 0x4)
+#define PLL_CON(x)              ((x) * 0x4)
+#define MODE_CON                0xc0
+
+enum pmu_plls
+{
+    ppll, hpll,
+};
+
+enum plls
+{
+    apll, dpll, gpll, cpll, npll, vpll,
+};
+
+enum
+{
+    /* CRU_PMU_CLK_SEL0_CON */
+    RTC32K_SEL_SHIFT                = 6,
+    RTC32K_SEL_MASK                 = 0x3 << RTC32K_SEL_SHIFT,
+    RTC32K_SEL_PMUPVTM              = 0,
+    RTC32K_SEL_OSC1_32K,
+    RTC32K_SEL_OSC0_DIV32K,
+
+    /* CRU_PMU_CLK_SEL1_CON */
+    RTC32K_FRAC_NUMERATOR_SHIFT     = 16,
+    RTC32K_FRAC_NUMERATOR_MASK      = 0xffff << 16,
+    RTC32K_FRAC_DENOMINATOR_SHIFT   = 0,
+    RTC32K_FRAC_DENOMINATOR_MASK    = 0xffff,
+
+    /* CRU_PMU_CLK_SEL2_CON */
+    PCLK_PDPMU_SEL_SHIFT            = 15,
+    PCLK_PDPMU_SEL_MASK             = 1 << PCLK_PDPMU_SEL_SHIFT,
+    PCLK_PDPMU_SEL_PPLL             = 0,
+    PCLK_PDPMU_SEL_GPLL,
+    PCLK_PDPMU_DIV_SHIFT            = 0,
+    PCLK_PDPMU_DIV_MASK             = 0x1f,
+
+    /* CRU_PMU_CLK_SEL3_CON */
+    CLK_I2C0_DIV_SHIFT              = 0,
+    CLK_I2C0_DIV_MASK               = 0x7f,
+
+    /* PMUCRU_PMUCLKSEL_CON04 */
+    CLK_UART0_SEL_SHIFT             = 10,
+    CLK_UART0_SEL_MASK              = 0x3 << CLK_UART0_SEL_SHIFT,
+    CLK_UART0_SEL_DIV               = 0,
+    CLK_UART0_SEL_FRACDIV,
+    CLK_UART0_SEL_XIN24M,
+    CLK_UART0_DIV_SEL_SHIFT         = 8,
+    CLK_UART0_DIV_SEL_MASK          = 0x3 << CLK_UART0_DIV_SEL_SHIFT,
+    CLK_UART0_SRC_SEL_PPLL          = 0,
+    CLK_UART0_SRC_SEL_480M,
+    CLK_UART0_SRC_SEL_CPLL,
+    CLK_UART0_SRC_SEL_GPLL,
+    CLK_UART0_DIV_DIV_SHIFT         = 0,
+    CLK_UART0_DIV_DIV_MASK          = 0x3f << CLK_UART0_DIV_DIV_SHIFT,
+
+    /* PMUCRU_PMUCLKSEL_CON05 */
+    CLK_UART0_FRAC_NUMERATOR_SHIFT  = 16,
+    CLK_UART0_FRAC_NUMERATOR_MASK   = 0xffff << 16,
+    CLK_UART0_FRAC_DENOMINATOR_SHIFT= 0,
+    CLK_UART0_FRAC_DENOMINATOR_MASK = 0xffff,
+
+    /* PMUCRU_PMUCLKSEL_CON09 */
+    CLK_PCIE_PHY2_REF_SEL_SHIFT     = 11,
+    CLK_PCIE_PHY2_REF_SEL_MASK      = 1 << CLK_PCIE_PHY2_REF_SEL_SHIFT,
+    CLK_PCIE_PHY1_REF_SEL_SHIFT     = 7,
+    CLK_PCIE_PHY1_REF_SEL_MASK      = 1 << CLK_PCIE_PHY1_REF_SEL_SHIFT,
+    CLK_PCIE_PHY0_REF_SEL_SHIFT     = 3,
+    CLK_PCIE_PHY0_REF_SEL_MASK      = 1 << CLK_PCIE_PHY0_REF_SEL_SHIFT,
+    CLK_PCIE_PHY_REF_SEL_24M        = 0,
+    CLK_PCIE_PHY_REF_SEL_PPLL,
+    CLK_PCIE_PHY2_PLL_DIV_SHIFT     = 8,
+    CLK_PCIE_PHY2_PLL_DIV_MASK      = 7 << CLK_PCIE_PHY2_PLL_DIV_SHIFT,
+    CLK_PCIE_PHY1_PLL_DIV_SHIFT     = 4,
+    CLK_PCIE_PHY1_PLL_DIV_MASK      = 7 << CLK_PCIE_PHY1_PLL_DIV_SHIFT,
+    CLK_PCIE_PHY0_PLL_DIV_SHIFT     = 0,
+    CLK_PCIE_PHY0_PLL_DIV_MASK      = 7 << CLK_PCIE_PHY0_PLL_DIV_SHIFT,
+
+    /* CRU_PMU_CLK_SEL6_CON */
+    CLK_PWM0_SEL_SHIFT              = 7,
+    CLK_PWM0_SEL_MASK               = 1 << CLK_PWM0_SEL_SHIFT,
+    CLK_PWM0_SEL_XIN24M             = 0,
+    CLK_PWM0_SEL_PPLL,
+    CLK_PWM0_DIV_SHIFT              = 0,
+    CLK_PWM0_DIV_MASK               = 0x7f,
+
+    /* CRU_CLK_SEL0_CON */
+    CLK_CORE_PRE_SEL_SHIFT          = 7,
+    CLK_CORE_PRE_SEL_MASK           = 1 << CLK_CORE_PRE_SEL_SHIFT,
+    CLK_CORE_PRE_SEL_SRC            = 0,
+    CLK_CORE_PRE_SEL_APLL,
+
+    /* CRU_CLK_SEL2_CON */
+    SCLK_CORE_PRE_SEL_SHIFT         = 15,
+    SCLK_CORE_PRE_SEL_MASK          = 1 << SCLK_CORE_PRE_SEL_SHIFT,
+    SCLK_CORE_PRE_SEL_SRC           = 0,
+    SCLK_CORE_PRE_SEL_NPLL,
+    SCLK_CORE_SRC_SEL_SHIFT         = 8,
+    SCLK_CORE_SRC_SEL_MASK          = 3 << SCLK_CORE_SRC_SEL_SHIFT,
+    SCLK_CORE_SRC_SEL_APLL          = 0,
+    SCLK_CORE_SRC_SEL_GPLL,
+    SCLK_CORE_SRC_SEL_NPLL,
+    SCLK_CORE_SRC_DIV_SHIFT         = 0,
+    SCLK_CORE_SRC_DIV_MASK          = 0x1f << SCLK_CORE_SRC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL3_CON */
+    GICCLK_CORE_DIV_SHIFT           = 8,
+    GICCLK_CORE_DIV_MASK            = 0x1f << GICCLK_CORE_DIV_SHIFT,
+    ATCLK_CORE_DIV_SHIFT            = 0,
+    ATCLK_CORE_DIV_MASK             = 0x1f << ATCLK_CORE_DIV_SHIFT,
+
+    /* CRU_CLK_SEL4_CON */
+    PERIPHCLK_CORE_PRE_DIV_SHIFT    = 8,
+    PERIPHCLK_CORE_PRE_DIV_MASK     = 0x1f << PERIPHCLK_CORE_PRE_DIV_SHIFT,
+    PCLK_CORE_PRE_DIV_SHIFT         = 0,
+    PCLK_CORE_PRE_DIV_MASK          = 0x1f << PCLK_CORE_PRE_DIV_SHIFT,
+
+    /* CRU_CLK_SEL5_CON */
+    ACLK_CORE_NIU2BUS_SEL_SHIFT     = 14,
+    ACLK_CORE_NIU2BUS_SEL_MASK      = 0x3 << ACLK_CORE_NIU2BUS_SEL_SHIFT,
+    ACLK_CORE_NDFT_DIV_SHIFT        = 8,
+    ACLK_CORE_NDFT_DIV_MASK         = 0x1f << ACLK_CORE_NDFT_DIV_SHIFT,
+
+    /* CRU_CLK_SEL10_CON */
+    HCLK_PERIMID_SEL_SHIFT          = 6,
+    HCLK_PERIMID_SEL_MASK           = 3 << HCLK_PERIMID_SEL_SHIFT,
+    HCLK_PERIMID_SEL_150M           = 0,
+    HCLK_PERIMID_SEL_100M,
+    HCLK_PERIMID_SEL_75M,
+    HCLK_PERIMID_SEL_24M,
+    ACLK_PERIMID_SEL_SHIFT          = 4,
+    ACLK_PERIMID_SEL_MASK           = 3 << ACLK_PERIMID_SEL_SHIFT,
+    ACLK_PERIMID_SEL_300M           = 0,
+    ACLK_PERIMID_SEL_200M,
+    ACLK_PERIMID_SEL_100M,
+    ACLK_PERIMID_SEL_24M,
+
+    /* CRU_CLK_SEL27_CON */
+    CLK_CRYPTO_PKA_SEL_SHIFT        = 6,
+    CLK_CRYPTO_PKA_SEL_MASK         = 3 << CLK_CRYPTO_PKA_SEL_SHIFT,
+    CLK_CRYPTO_PKA_SEL_300M         = 0,
+    CLK_CRYPTO_PKA_SEL_200M,
+    CLK_CRYPTO_PKA_SEL_100M,
+    CLK_CRYPTO_CORE_SEL_SHIFT       = 4,
+    CLK_CRYPTO_CORE_SEL_MASK        = 3 << CLK_CRYPTO_CORE_SEL_SHIFT,
+    CLK_CRYPTO_CORE_SEL_200M        = 0,
+    CLK_CRYPTO_CORE_SEL_150M,
+    CLK_CRYPTO_CORE_SEL_100M,
+    HCLK_SECURE_FLASH_SEL_SHIFT     = 2,
+    HCLK_SECURE_FLASH_SEL_MASK      = 3 << HCLK_SECURE_FLASH_SEL_SHIFT,
+    HCLK_SECURE_FLASH_SEL_150M      = 0,
+    HCLK_SECURE_FLASH_SEL_100M,
+    HCLK_SECURE_FLASH_SEL_75M,
+    HCLK_SECURE_FLASH_SEL_24M,
+    ACLK_SECURE_FLASH_SEL_SHIFT     = 0,
+    ACLK_SECURE_FLASH_SEL_MASK      = 3 << ACLK_SECURE_FLASH_SEL_SHIFT,
+    ACLK_SECURE_FLASH_SEL_200M      = 0,
+    ACLK_SECURE_FLASH_SEL_150M,
+    ACLK_SECURE_FLASH_SEL_100M,
+    ACLK_SECURE_FLASH_SEL_24M,
+
+    /* CRU_CLK_SEL28_CON */
+    CCLK_EMMC_SEL_SHIFT             = 12,
+    CCLK_EMMC_SEL_MASK              = 7 << CCLK_EMMC_SEL_SHIFT,
+    CCLK_EMMC_SEL_24M               = 0,
+    CCLK_EMMC_SEL_200M,
+    CCLK_EMMC_SEL_150M,
+    CCLK_EMMC_SEL_100M,
+    CCLK_EMMC_SEL_50M,
+    CCLK_EMMC_SEL_375K,
+    BCLK_EMMC_SEL_SHIFT             = 8,
+    BCLK_EMMC_SEL_MASK              = 3 << BCLK_EMMC_SEL_SHIFT,
+    BCLK_EMMC_SEL_200M              = 0,
+    BCLK_EMMC_SEL_150M,
+    BCLK_EMMC_SEL_125M,
+    SCLK_SFC_SEL_SHIFT              = 4,
+    SCLK_SFC_SEL_MASK               = 7 << SCLK_SFC_SEL_SHIFT,
+    SCLK_SFC_SEL_24M                = 0,
+    SCLK_SFC_SEL_50M,
+    SCLK_SFC_SEL_75M,
+    SCLK_SFC_SEL_100M,
+    SCLK_SFC_SEL_125M,
+    SCLK_SFC_SEL_150M,
+    NCLK_NANDC_SEL_SHIFT            = 0,
+    NCLK_NANDC_SEL_MASK             = 3 << NCLK_NANDC_SEL_SHIFT,
+    NCLK_NANDC_SEL_200M             = 0,
+    NCLK_NANDC_SEL_150M,
+    NCLK_NANDC_SEL_100M,
+    NCLK_NANDC_SEL_24M,
+
+    /* CRU_CLK_SEL30_CON */
+    CLK_SDMMC1_SEL_SHIFT            = 12,
+    CLK_SDMMC1_SEL_MASK             = 7 << CLK_SDMMC1_SEL_SHIFT,
+    CLK_SDMMC0_SEL_SHIFT            = 8,
+    CLK_SDMMC0_SEL_MASK             = 7 << CLK_SDMMC0_SEL_SHIFT,
+    CLK_SDMMC_SEL_24M               = 0,
+    CLK_SDMMC_SEL_400M,
+    CLK_SDMMC_SEL_300M,
+    CLK_SDMMC_SEL_100M,
+    CLK_SDMMC_SEL_50M,
+    CLK_SDMMC_SEL_750K,
+
+    /* CRU_CLK_SEL31_CON */
+    CLK_MAC0_OUT_SEL_SHIFT          = 14,
+    CLK_MAC0_OUT_SEL_MASK           = 3 << CLK_MAC0_OUT_SEL_SHIFT,
+    CLK_MAC0_OUT_SEL_125M           = 0,
+    CLK_MAC0_OUT_SEL_50M,
+    CLK_MAC0_OUT_SEL_25M,
+    CLK_MAC0_OUT_SEL_24M,
+    CLK_GMAC0_PTP_REF_SEL_SHIFT     = 12,
+    CLK_GMAC0_PTP_REF_SEL_MASK      = 3 << CLK_GMAC0_PTP_REF_SEL_SHIFT,
+    CLK_GMAC0_PTP_REF_SEL_62_5M     = 0,
+    CLK_GMAC0_PTP_REF_SEL_100M,
+    CLK_GMAC0_PTP_REF_SEL_50M,
+    CLK_GMAC0_PTP_REF_SEL_24M,
+    CLK_MAC0_2TOP_SEL_SHIFT         = 8,
+    CLK_MAC0_2TOP_SEL_MASK          = 3 << CLK_MAC0_2TOP_SEL_SHIFT,
+    CLK_MAC0_2TOP_SEL_125M          = 0,
+    CLK_MAC0_2TOP_SEL_50M,
+    CLK_MAC0_2TOP_SEL_25M,
+    CLK_MAC0_2TOP_SEL_PPLL,
+    RGMII0_CLK_SEL_SHIFT            = 4,
+    RGMII0_CLK_SEL_MASK             = 3 << RGMII0_CLK_SEL_SHIFT,
+    RGMII0_CLK_SEL_125M             = 0,
+    RGMII0_CLK_SEL_125M_1,
+    RGMII0_CLK_SEL_2_5M,
+    RGMII0_CLK_SEL_25M,
+    RMII0_CLK_SEL_SHIFT             = 3,
+    RMII0_CLK_SEL_MASK              = 1 << RMII0_CLK_SEL_SHIFT,
+    RMII0_CLK_SEL_2_5M              = 0,
+    RMII0_CLK_SEL_25M,
+    RMII0_EXTCLK_SEL_SHIFT          = 2,
+    RMII0_EXTCLK_SEL_MASK           = 1 << RMII0_EXTCLK_SEL_SHIFT,
+    RMII0_EXTCLK_SEL_MAC0_TOP       = 0,
+    RMII0_EXTCLK_SEL_IO,
+    RMII0_MODE_SHIFT                = 0,
+    RMII0_MODE_MASK                 = 3 << RMII0_MODE_SHIFT,
+    RMII0_MODE_SEL_RGMII            = 0,
+    RMII0_MODE_SEL_RMII,
+    RMII0_MODE_SEL_GMII,
+
+    /* CRU_CLK_SEL32_CON */
+    CLK_SDMMC2_SEL_SHIFT            = 8,
+    CLK_SDMMC2_SEL_MASK             = 7 << CLK_SDMMC2_SEL_SHIFT,
+
+    /* CRU_CLK_SEL38_CON */
+    ACLK_VOP_PRE_SEL_SHIFT          = 6,
+    ACLK_VOP_PRE_SEL_MASK           = 3 << ACLK_VOP_PRE_SEL_SHIFT,
+    ACLK_VOP_PRE_SEL_CPLL           = 0,
+    ACLK_VOP_PRE_SEL_GPLL,
+    ACLK_VOP_PRE_SEL_HPLL,
+    ACLK_VOP_PRE_SEL_VPLL,
+    ACLK_VOP_PRE_DIV_SHIFT          = 0,
+    ACLK_VOP_PRE_DIV_MASK           = 0x1f << ACLK_VOP_PRE_DIV_SHIFT,
+
+    /* CRU_CLK_SEL39_CON */
+    DCLK0_VOP_SEL_SHIFT             = 10,
+    DCLK0_VOP_SEL_MASK              = 3 << DCLK0_VOP_SEL_SHIFT,
+    DCLK_VOP_SEL_HPLL               = 0,
+    DCLK_VOP_SEL_VPLL,
+    DCLK_VOP_SEL_GPLL,
+    DCLK_VOP_SEL_CPLL,
+    DCLK0_VOP_DIV_SHIFT             = 0,
+    DCLK0_VOP_DIV_MASK              = 0xff << DCLK0_VOP_DIV_SHIFT,
+
+    /* CRU_CLK_SEL40_CON */
+    DCLK1_VOP_SEL_SHIFT             = 10,
+    DCLK1_VOP_SEL_MASK              = 3 << DCLK1_VOP_SEL_SHIFT,
+    DCLK1_VOP_DIV_SHIFT             = 0,
+    DCLK1_VOP_DIV_MASK              = 0xff << DCLK1_VOP_DIV_SHIFT,
+
+    /* CRU_CLK_SEL41_CON */
+    DCLK2_VOP_SEL_SHIFT             = 10,
+    DCLK2_VOP_SEL_MASK              = 3 << DCLK2_VOP_SEL_SHIFT,
+    DCLK2_VOP_DIV_SHIFT             = 0,
+    DCLK2_VOP_DIV_MASK              = 0xff << DCLK2_VOP_DIV_SHIFT,
+
+    /* CRU_CLK_SEL43_CON */
+    DCLK_EBC_SEL_SHIFT              = 6,
+    DCLK_EBC_SEL_MASK               = 3 << DCLK_EBC_SEL_SHIFT,
+    DCLK_EBC_SEL_GPLL_400M          = 0,
+    DCLK_EBC_SEL_CPLL_333M,
+    DCLK_EBC_SEL_GPLL_200M,
+
+    /* CRU_CLK_SEL47_CON */
+    ACLK_RKVDEC_SEL_SHIFT           = 7,
+    ACLK_RKVDEC_SEL_MASK            = 1 << ACLK_RKVDEC_SEL_SHIFT,
+    ACLK_RKVDEC_SEL_GPLL            = 0,
+    ACLK_RKVDEC_SEL_CPLL,
+    ACLK_RKVDEC_DIV_SHIFT           = 0,
+    ACLK_RKVDEC_DIV_MASK            = 0x1f << ACLK_RKVDEC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL49_CON */
+    CLK_RKVDEC_CORE_SEL_SHIFT       = 14,
+    CLK_RKVDEC_CORE_SEL_MASK        = 0x3 << CLK_RKVDEC_CORE_SEL_SHIFT,
+    CLK_RKVDEC_CORE_SEL_GPLL        = 0,
+    CLK_RKVDEC_CORE_SEL_CPLL,
+    CLK_RKVDEC_CORE_SEL_NPLL,
+    CLK_RKVDEC_CORE_SEL_VPLL,
+    CLK_RKVDEC_CORE_DIV_SHIFT       = 8,
+    CLK_RKVDEC_CORE_DIV_MASK        = 0x1f << CLK_RKVDEC_CORE_DIV_SHIFT,
+
+    /* CRU_CLK_SEL50_CON */
+    PCLK_BUS_SEL_SHIFT              = 4,
+    PCLK_BUS_SEL_MASK               = 3 << PCLK_BUS_SEL_SHIFT,
+    PCLK_BUS_SEL_100M               = 0,
+    PCLK_BUS_SEL_75M,
+    PCLK_BUS_SEL_50M,
+    PCLK_BUS_SEL_24M,
+    ACLK_BUS_SEL_SHIFT              = 0,
+    ACLK_BUS_SEL_MASK               = 3 << ACLK_BUS_SEL_SHIFT,
+    ACLK_BUS_SEL_200M               = 0,
+    ACLK_BUS_SEL_150M,
+    ACLK_BUS_SEL_100M,
+    ACLK_BUS_SEL_24M,
+
+    /* CRU_CLK_SEL51_CON */
+    CLK_TSADC_DIV_SHIFT             = 8,
+    CLK_TSADC_DIV_MASK              = 0x7f << CLK_TSADC_DIV_SHIFT,
+    CLK_TSADC_TSEN_SEL_SHIFT        = 4,
+    CLK_TSADC_TSEN_SEL_MASK         = 0x3 << CLK_TSADC_TSEN_SEL_SHIFT,
+    CLK_TSADC_TSEN_SEL_24M          = 0,
+    CLK_TSADC_TSEN_SEL_100M,
+    CLK_TSADC_TSEN_SEL_CPLL_100M,
+    CLK_TSADC_TSEN_DIV_SHIFT        = 0,
+    CLK_TSADC_TSEN_DIV_MASK         = 0x7 << CLK_TSADC_TSEN_DIV_SHIFT,
+
+    /* CRU_CLK_SEL52_CON */
+    CLK_UART_SEL_SHIFT              = 12,
+    CLK_UART_SEL_MASK               = 0x3 << CLK_UART_SEL_SHIFT,
+    CLK_UART_SEL_SRC                = 0,
+    CLK_UART_SEL_FRAC,
+    CLK_UART_SEL_XIN24M,
+    CLK_UART_SRC_SEL_SHIFT          = 8,
+    CLK_UART_SRC_SEL_MASK           = 0x3 << CLK_UART_SRC_SEL_SHIFT,
+    CLK_UART_SRC_SEL_GPLL           = 0,
+    CLK_UART_SRC_SEL_CPLL,
+    CLK_UART_SRC_SEL_480M,
+    CLK_UART_SRC_DIV_SHIFT          = 0,
+    CLK_UART_SRC_DIV_MASK           = 0x3f << CLK_UART_SRC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL53_CON */
+    CLK_UART_FRAC_NUMERATOR_SHIFT   = 16,
+    CLK_UART_FRAC_NUMERATOR_MASK    = 0xffff << 16,
+    CLK_UART_FRAC_DENOMINATOR_SHIFT = 0,
+    CLK_UART_FRAC_DENOMINATOR_MASK  = 0xffff,
+
+    /* CRU_CLK_SEL71_CON */
+    CLK_I2C_SEL_SHIFT               = 8,
+    CLK_I2C_SEL_MASK                = 3 << CLK_I2C_SEL_SHIFT,
+    CLK_I2C_SEL_200M                = 0,
+    CLK_I2C_SEL_100M,
+    CLK_I2C_SEL_24M,
+    CLK_I2C_SEL_CPLL_100M,
+
+    /* CRU_CLK_SEL72_CON */
+    CLK_PWM3_SEL_SHIFT              = 12,
+    CLK_PWM3_SEL_MASK               = 3 << CLK_PWM3_SEL_SHIFT,
+    CLK_PWM2_SEL_SHIFT              = 10,
+    CLK_PWM2_SEL_MASK               = 3 << CLK_PWM2_SEL_SHIFT,
+    CLK_PWM1_SEL_SHIFT              = 8,
+    CLK_PWM1_SEL_MASK               = 3 << CLK_PWM1_SEL_SHIFT,
+    CLK_PWM_SEL_100M                = 0,
+    CLK_PWM_SEL_24M,
+    CLK_PWM_SEL_CPLL_100M,
+    CLK_SPI3_SEL_SHIFT              = 6,
+    CLK_SPI3_SEL_MASK               = 3 << CLK_SPI3_SEL_SHIFT,
+    CLK_SPI2_SEL_SHIFT              = 4,
+    CLK_SPI2_SEL_MASK               = 3 << CLK_SPI2_SEL_SHIFT,
+    CLK_SPI1_SEL_SHIFT              = 2,
+    CLK_SPI1_SEL_MASK               = 3 << CLK_SPI1_SEL_SHIFT,
+    CLK_SPI0_SEL_SHIFT              = 0,
+    CLK_SPI0_SEL_MASK               = 3 << CLK_SPI0_SEL_SHIFT,
+    CLK_SPI_SEL_200M                = 0,
+    CLK_SPI_SEL_24M,
+    CLK_SPI_SEL_CPLL_100M,
+
+    /* CRU_CLK_SEL73_CON */
+    PCLK_TOP_SEL_SHIFT              = 12,
+    PCLK_TOP_SEL_MASK               = 3 << PCLK_TOP_SEL_SHIFT,
+    PCLK_TOP_SEL_100M               = 0,
+    PCLK_TOP_SEL_75M,
+    PCLK_TOP_SEL_50M,
+    PCLK_TOP_SEL_24M,
+    HCLK_TOP_SEL_SHIFT              = 8,
+    HCLK_TOP_SEL_MASK               = 3 << HCLK_TOP_SEL_SHIFT,
+    HCLK_TOP_SEL_150M               = 0,
+    HCLK_TOP_SEL_100M,
+    HCLK_TOP_SEL_75M,
+    HCLK_TOP_SEL_24M,
+    ACLK_TOP_LOW_SEL_SHIFT          = 4,
+    ACLK_TOP_LOW_SEL_MASK           = 3 << ACLK_TOP_LOW_SEL_SHIFT,
+    ACLK_TOP_LOW_SEL_400M           = 0,
+    ACLK_TOP_LOW_SEL_300M,
+    ACLK_TOP_LOW_SEL_200M,
+    ACLK_TOP_LOW_SEL_24M,
+    ACLK_TOP_HIGH_SEL_SHIFT         = 0,
+    ACLK_TOP_HIGH_SEL_MASK          = 3 << ACLK_TOP_HIGH_SEL_SHIFT,
+    ACLK_TOP_HIGH_SEL_500M          = 0,
+    ACLK_TOP_HIGH_SEL_400M,
+    ACLK_TOP_HIGH_SEL_300M,
+    ACLK_TOP_HIGH_SEL_24M,
+
+    /* CRU_CLK_SEL78_CON */
+    CPLL_500M_DIV_SHIFT             = 8,
+    CPLL_500M_DIV_MASK              = 0x1f << CPLL_500M_DIV_SHIFT,
+
+    /* CRU_CLK_SEL79_CON */
+    CPLL_250M_DIV_SHIFT             = 8,
+    CPLL_250M_DIV_MASK              = 0x1f << CPLL_250M_DIV_SHIFT,
+    CPLL_333M_DIV_SHIFT             = 0,
+    CPLL_333M_DIV_MASK              = 0x1f << CPLL_333M_DIV_SHIFT,
+
+    /* CRU_CLK_SEL80_CON */
+    CPLL_62P5M_DIV_SHIFT            = 8,
+    CPLL_62P5M_DIV_MASK             = 0x1f << CPLL_62P5M_DIV_SHIFT,
+    CPLL_125M_DIV_SHIFT             = 0,
+    CPLL_125M_DIV_MASK              = 0x1f << CPLL_125M_DIV_SHIFT,
+
+    /* CRU_CLK_SEL81_CON */
+    CPLL_25M_DIV_SHIFT              = 8,
+    CPLL_25M_DIV_MASK               = 0x1f << CPLL_25M_DIV_SHIFT,
+    CPLL_50M_DIV_SHIFT              = 0,
+    CPLL_50M_DIV_MASK               = 0x1f << CPLL_50M_DIV_SHIFT,
+
+    /* CRU_CLK_SEL82_CON */
+    CPLL_100M_DIV_SHIFT             = 0,
+    CPLL_100M_DIV_MASK              = 0x1f << CPLL_100M_DIV_SHIFT,
+};
+
+static struct rk_cpu_rate_table cpu_rates[] =
+{
+    CPUCLK_RATE(1800000000, 1, 7),
+    CPUCLK_RATE(1704000000, 1, 7),
+    CPUCLK_RATE(1608000000, 1, 5),
+    CPUCLK_RATE(1584000000, 1, 5),
+    CPUCLK_RATE(1560000000, 1, 5),
+    CPUCLK_RATE(1536000000, 1, 5),
+    CPUCLK_RATE(1512000000, 1, 5),
+    CPUCLK_RATE(1488000000, 1, 5),
+    CPUCLK_RATE(1464000000, 1, 5),
+    CPUCLK_RATE(1440000000, 1, 5),
+    CPUCLK_RATE(1416000000, 1, 5),
+    CPUCLK_RATE(1392000000, 1, 5),
+    CPUCLK_RATE(1368000000, 1, 5),
+    CPUCLK_RATE(1344000000, 1, 5),
+    CPUCLK_RATE(1320000000, 1, 5),
+    CPUCLK_RATE(1296000000, 1, 5),
+    CPUCLK_RATE(1272000000, 1, 5),
+    CPUCLK_RATE(1248000000, 1, 5),
+    CPUCLK_RATE(1224000000, 1, 5),
+    CPUCLK_RATE(1200000000, 1, 3),
+    CPUCLK_RATE(1104000000, 1, 3),
+    CPUCLK_RATE(1008000000, 1, 3),
+    CPUCLK_RATE(912000000,  1, 3),
+    CPUCLK_RATE(816000000,  1, 3),
+    CPUCLK_RATE(696000000,  1, 3),
+    CPUCLK_RATE(600000000,  1, 3),
+    CPUCLK_RATE(408000000,  1, 3),
+    CPUCLK_RATE(312000000,  1, 3),
+    CPUCLK_RATE(216000000,  1, 3),
+    CPUCLK_RATE(96000000,   1, 3),
+    { /* sentinel */ },
+};
+
+static struct rk_pll_rate_table pll_rates[] =
+{
+    /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
+    PLL_RATE(2208000000, 1,  92, 1, 1, 1, 0),
+    PLL_RATE(2184000000, 1,  91, 1, 1, 1, 0),
+    PLL_RATE(2160000000, 1,  90, 1, 1, 1, 0),
+    PLL_RATE(2088000000, 1,  87, 1, 1, 1, 0),
+    PLL_RATE(2064000000, 1,  86, 1, 1, 1, 0),
+    PLL_RATE(2040000000, 1,  85, 1, 1, 1, 0),
+    PLL_RATE(2016000000, 1,  84, 1, 1, 1, 0),
+    PLL_RATE(1992000000, 1,  83, 1, 1, 1, 0),
+    PLL_RATE(1920000000, 1,  80, 1, 1, 1, 0),
+    PLL_RATE(1896000000, 1,  79, 1, 1, 1, 0),
+    PLL_RATE(1800000000, 1,  75, 1, 1, 1, 0),
+    PLL_RATE(1704000000, 1,  71, 1, 1, 1, 0),
+    PLL_RATE(1608000000, 1,  67, 1, 1, 1, 0),
+    PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0),
+    PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0),
+    PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0),
+    PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0),
+    PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0),
+    PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0),
+    PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0),
+    PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0),
+    PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0),
+    PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0),
+    PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0),
+    PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0),
+    PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0),
+    PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0),
+    PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0),
+    PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0),
+    PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0),
+    PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0),
+    PLL_RATE(1188000000, 1,  99, 2, 1, 1, 0),
+    PLL_RATE(1104000000, 1,  92, 2, 1, 1, 0),
+    PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0),
+    PLL_RATE(1008000000, 1,  84, 2, 1, 1, 0),
+    PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0),
+    PLL_RATE(912000000,  1,  76, 2, 1, 1, 0),
+    PLL_RATE(816000000,  1,  68, 2, 1, 1, 0),
+    PLL_RATE(800000000,  3, 200, 2, 1, 1, 0),
+    PLL_RATE(700000000,  3, 350, 4, 1, 1, 0),
+    PLL_RATE(696000000,  1, 116, 4, 1, 1, 0),
+    PLL_RATE(600000000,  1, 100, 4, 1, 1, 0),
+    PLL_RATE(594000000,  1,  99, 4, 1, 1, 0),
+    PLL_RATE(500000000,  1, 125, 6, 1, 1, 0),
+    PLL_RATE(408000000,  1,  68, 2, 2, 1, 0),
+    PLL_RATE(312000000,  1,  78, 6, 1, 1, 0),
+    PLL_RATE(297000000,  2,  99, 4, 1, 1, 0),
+    PLL_RATE(241500000,  2, 161, 4, 2, 1, 0),
+    PLL_RATE(216000000,  1,  72, 4, 2, 1, 0),
+    PLL_RATE(200000000,  1, 100, 3, 4, 1, 0),
+    PLL_RATE(148500000,  1,  99, 4, 4, 1, 0),
+    PLL_RATE(135000000,  2,  45, 4, 1, 1, 0),
+    PLL_RATE(119000000,  3, 119, 4, 2, 1, 0),
+    PLL_RATE(108000000,  2,  45, 5, 1, 1, 0),
+    PLL_RATE(100000000,  1, 150, 6, 6, 1, 0),
+    PLL_RATE(96000000,   1,  96, 6, 4, 1, 0),
+    PLL_RATE(78750000,   1,  96, 6, 4, 1, 0),
+    PLL_RATE(74250000,   2,  99, 4, 4, 1, 0),
+    { /* sentinel */ },
+};
+
+static struct rk_pll_clock pmu_pll_clks[] =
+{
+    [ppll] = PLL(PLL_PPLL, PMU_PLL_CON(0), PMU_MODE, 0, 10, 0, pll_rates),
+    [hpll] = PLL(PLL_HPLL, PMU_PLL_CON(16), PMU_MODE, 2, 10, 0, pll_rates),
+};
+
+static struct rk_pll_clock pll_clks[] =
+{
+    [apll] = PLL(PLL_APLL, PLL_CON(0),  MODE_CON,  0, 10, 0, pll_rates),
+    [dpll] = PLL(PLL_DPLL, PLL_CON(8),  MODE_CON,  2, 10, 0, RT_NULL),
+    [gpll] = PLL(PLL_HPLL, PLL_CON(16), MODE_CON,  6, 10, 0, pll_rates),
+    [cpll] = PLL(PLL_CPLL, PLL_CON(24), MODE_CON,  4, 10, 0, pll_rates),
+    [npll] = PLL(PLL_NPLL, PLL_CON(32), MODE_CON, 10, 10, 0, pll_rates),
+    [vpll] = PLL(PLL_VPLL, PLL_CON(40), MODE_CON, 12, 10, 0, pll_rates),
+};
+
+static struct rk_clk_gate clk_gates[] =
+{
+    /* CRU_GATE_CON00 */
+    /* CRU_GATE_CON01 */
+    GATE(PCLK_CORE_PVTM, "pclk_core_pvtm", "pclk_core_pre", 1, 9),
+    GATE(CLK_CORE_PVTM, "clk_core_pvtm", "xin24m", 1, 10),
+    GATE(CLK_CORE_PVTM_CORE, "clk_core_pvtm_core", "armclk", 1, 11),
+    GATE(CLK_CORE_PVTPLL, "clk_core_pvtpll", "armclk", 1, 12),
+    /* CRU_GATE_CON02 */
+    GATE(CLK_GPU_SRC, "clk_gpu_src", "clk_gpu_pre_c", 2, 0),
+    GATE(PCLK_GPU_PRE, "pclk_gpu_pre", "pclk_gpu_pre_div", 2, 2),
+    GATE(CLK_GPU, "clk_gpu", "clk_gpu_pre_c", 2, 3),
+    GATE(PCLK_GPU_PVTM, "pclk_gpu_pvtm", "pclk_gpu_pre", 2, 6),
+    GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 2, 7),
+    GATE(CLK_GPU_PVTM_CORE, "clk_gpu_pvtm_core", "clk_gpu_src", 2, 8),
+    GATE(CLK_GPU_PVTPLL, "clk_gpu_pvtpll", "clk_gpu_src", 2, 9),
+    GATE(ACLK_GPU_PRE, "aclk_gpu_pre", "aclk_gpu_pre_div", 2, 11),
+    /* CRU_GATE_CON03 */
+    GATE(CLK_NPU_SRC, "clk_npu_src", "clk_npu_src_c", 3, 0),
+    GATE(CLK_NPU_NP5, "clk_npu_np5", "clk_npu_np5_c", 3, 1),
+    GATE(HCLK_NPU_PRE, "hclk_npu_pre", "hclk_npu_pre_div", 3, 2),
+    GATE(PCLK_NPU_PRE, "pclk_npu_pre", "pclk_npu_pre_div", 3, 3),
+    GATE(ACLK_NPU_PRE, "aclk_npu_pre", "clk_npu", 3, 4),
+    GATE(ACLK_NPU, "aclk_npu", "aclk_npu_pre", 3, 7),
+    GATE(HCLK_NPU, "hclk_npu", "hclk_npu_pre", 3, 8),
+    GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_pre", 3, 9),
+    GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 3, 10),
+    GATE(CLK_NPU_PVTM_CORE, "clk_npu_pvtm_core", "clk_npu_pre_ndft", 3, 11),
+    GATE(CLK_NPU_PVTPLL, "clk_npu_pvtpll", "clk_npu_pre_ndft", 3, 12),
+    /* CRU_GATE_CON04 */
+    GATE(CLK_DDRPHY1X_SRC, "clk_ddrphy1x_src", "clk_ddrphy1x_src_c", 4, 0),
+    GATE(CLK_MSCH, "clk_msch", "clk_msch_div", 4, 2),
+    GATE(CLK24_DDRMON, "clk24_ddrmon", "xin24m", 4, 15),
+    /* CRU_GATE_CON05 */
+    GATE(ACLK_GIC_AUDIO, "aclk_gic_audio", "aclk_gic_audio_sel", 5, 0),
+    GATE(HCLK_GIC_AUDIO, "hclk_gic_audio", "hclk_gic_audio_sel", 5, 1),
+    GATE(ACLK_GIC600, "aclk_gic600", "aclk_gic_audio", 5, 4),
+    GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_gic_audio", 5, 7),
+    GATE(HCLK_SDMMC_BUFFER, "hclk_sdmmc_buffer", "hclk_gic_audio", 5, 8),
+    GATE(DCLK_SDMMC_BUFFER, "dclk_sdmmc_buffer", "dclk_sdmmc_buffer_sel", 5, 9),
+    GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_gic_audio", 5, 10),
+    GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_gic_audio", 5, 11),
+    GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_gic_audio", 5, 12),
+    GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_gic_audio", 5, 13),
+    GATE(HCLK_PDM, "hclk_pdm", "hclk_gic_audio", 5, 14),
+    GATE(MCLK_PDM, "mclk_pdm", "mclk_pdm_sel", 5, 15),
+    /* CRU_GATE_CON06 */
+    GATE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_src_c", 6, 0),
+    GATE(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_frac_div", 6, 1),
+    GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 6, 2),
+    GATE(I2S0_MCLKOUT_TX, "i2s0_mclkout_tx", "i2s0_mclkout_tx_sel", 6, 3),
+    GATE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_src_c", 6, 4),
+    GATE(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_frac_div", 6, 5),
+    GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 6, 6),
+    GATE(I2S0_MCLKOUT_RX, "i2s0_mclkout_rx", "i2s0_mclkout_rx_sel", 6, 7),
+    GATE(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_src_c", 6, 8),
+    GATE(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_frac_div", 6, 9),
+    GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 6, 10),
+    GATE(I2S1_MCLKOUT_TX, "i2s1_mclkout_tx", "i2s1_mclkout_tx_sel", 6, 11),
+    GATE(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_src_c", 6, 12),
+    GATE(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_frac_div", 6, 13),
+    GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 6, 14),
+    GATE(I2S1_MCLKOUT_RX, "i2s1_mclkout_rx", "i2s1_mclkout_rx_sel", 6, 15),
+    /* CRU_GATE_CON07 */
+    GATE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", "clk_i2s2_2ch_src_c", 7, 0),
+    GATE(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_frac_div", 7, 1),
+    GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 7, 2),
+    GATE(I2S2_MCLKOUT, "i2s2_mclkout", "i2s2_mclkout_sel", 7, 3),
+    GATE(CLK_I2S3_2CH_TX, "clk_i2s3_2ch_tx_src", "clk_i2s3_2ch_tx_src_c", 7, 4),
+    GATE(CLK_I2S3_2CH_TX_FRAC, "clk_i2s3_2ch_tx_frac", "clk_i2s3_2ch_tx_frac_div", 7, 5),
+    GATE(MCLK_I2S3_2CH_TX, "mclk_i2s3_2ch_tx", "clk_i2s3_2ch_tx", 7, 6),
+    GATE(I2S3_MCLKOUT_TX, "i2s3_mclkout_tx", "i2s3_mclkout_tx_sel", 7, 7),
+    GATE(CLK_I2S3_2CH_RX, "clk_i2s3_2ch_rx_src", "clk_i2s3_2ch_rx_src_div", 7, 8),
+    GATE(CLK_I2S3_2CH_RX_FRAC, "clk_i2s3_2ch_rx_frac", "clk_i2s3_2ch_rx_frac_div", 7, 9),
+    GATE(MCLK_I2S3_2CH_RX, "mclk_i2s3_2ch_rx", "clk_i2s3_2ch_rx", 7, 10),
+    GATE(I2S3_MCLKOUT_RX, "i2s3_mclkout_rx", "i2s3_mclkout_rx_sel", 7, 11),
+    GATE(HCLK_VAD, "hclk_vad", "hclk_gic_audio", 7, 12),
+    GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_gic_audio", 7, 13),
+    GATE(MCLK_SPDIF_8CH_SRC, "mclk_spdif_8ch_src", "mclk_spdif_8ch_src_c", 7, 14),
+    GATE(MCLK_SPDIF_8CH_FRAC, "mclk_spdif_8ch_frac", "mclk_spdif_8ch_frac_div", 7, 15),
+    /* CRU_GATE_CON08 */
+    GATE(HCLK_AUDPWM, "hclk_audpwm", "hclk_gic_audio", 8, 0),
+    GATE(SCLK_AUDPWM_SRC, "sclk_audpwm_src", "sclk_audpwm_src_c", 8, 1),
+    GATE(SCLK_AUDPWM_FRAC, "sclk_audpwm_frac", "sclk_audpwm_frac_frac", 8, 2),
+    GATE(HCLK_ACDCDIG, "hclk_acdcdig", "hclk_gic_audio", 8, 3),
+    GATE(CLK_ACDCDIG_I2C, "clk_acdcdig_i2c", "clk_acdcdig_i2c_sel", 8, 4),
+    GATE(CLK_ACDCDIG_DAC, "clk_acdcdig_dac", "mclk_i2s3_2ch_tx", 8, 5),
+    GATE(CLK_ACDCDIG_ADC, "clk_acdcdig_adc", "mclk_i2s3_2ch_rx", 8, 6),
+    GATE(ACLK_SECURE_FLASH, "aclk_secure_flash", "aclk_secure_flash_sel", 8, 7),
+    GATE(HCLK_SECURE_FLASH, "hclk_secure_flash", "hclk_secure_flash_sel", 8, 8),
+    GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_flash", 8, 11),
+    GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_flash", 8, 12),
+    GATE(CLK_CRYPTO_NS_CORE, "clk_crypto_ns_core", "clk_crypto_ns_core_sel", 8, 13),
+    GATE(CLK_CRYPTO_NS_PKA, "clk_crypto_ns_pka", "clk_crypto_ns_pka_sel", 8, 14),
+    GATE(CLK_CRYPTO_NS_RNG, "clk_crypto_ns_rng", "hclk_secure_flash", 8, 15),
+    /* CRU_GATE_CON09 */
+    GATE(HCLK_NANDC, "hclk_nandc", "hclk_secure_flash", 9, 0),
+    GATE(NCLK_NANDC, "nclk_nandc", "nclk_nandc_sel", 9, 1),
+    GATE(HCLK_SFC, "hclk_sfc", "hclk_secure_flash", 9, 2),
+    GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_secure_flash", 9, 3),
+    GATE(SCLK_SFC, "sclk_sfc", "sclk_sfc_sel", 9, 4),
+    GATE(ACLK_EMMC, "aclk_emmc", "aclk_secure_flash", 9, 5),
+    GATE(HCLK_EMMC, "hclk_emmc", "hclk_secure_flash", 9, 6),
+    GATE(BCLK_EMMC, "bclk_emmc", "bclk_emmc_sel", 9, 7),
+    GATE(CCLK_EMMC, "cclk_emmc", "cclk_emmc_sel", 9, 8),
+    GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 9, 9),
+    GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_flash", 9, 10),
+    GATE(CLK_TRNG_NS, "clk_trng_ns", "hclk_secure_flash", 9, 11),
+    /* CRU_GATE_CON10 */
+    GATE(ACLK_PIPE, "aclk_pipe", "aclk_pipe_sel", 10, 0),
+    GATE(PCLK_PIPE, "pclk_pipe", "pclk_pipe_div", 10, 1),
+    GATE(CLK_XPCS_EEE, "clk_xpcs_eee", "clk_xpcs_eee_sel", 10, 4),
+    GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_pipe", 10, 8),
+    GATE(CLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 10, 9),
+    GATE(CLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", "clk_usb3otg0_suspend_sel", 10, 10),
+    GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_pipe", 10, 12),
+    GATE(CLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 10, 13),
+    GATE(CLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", "clk_usb3otg1_suspend_sel", 10, 14),
+    /* CRU_GATE_CON11 */
+    GATE(ACLK_SATA0, "aclk_sata0", "aclk_pipe", 11, 0),
+    GATE(CLK_SATA0_PMALIVE, "clk_sata0_pmalive", "clk_gpll_div_20m", 11, 1),
+    GATE(CLK_SATA0_RXOOB, "clk_sata0_rxoob", "clk_cpll_div_50m", 11, 2),
+    GATE(ACLK_SATA1, "aclk_sata1", "aclk_pipe", 11, 4),
+    GATE(CLK_SATA1_PMALIVE, "clk_sata1_pmalive", "clk_gpll_div_20m", 11, 5),
+    GATE(CLK_SATA1_RXOOB, "clk_sata1_rxoob", "clk_cpll_div_50m", 11, 6),
+    GATE(ACLK_SATA2, "aclk_sata2", "aclk_pipe", 11, 8),
+    GATE(CLK_SATA2_PMALIVE, "clk_sata2_pmalive", "clk_gpll_div_20m", 11, 9),
+    GATE(CLK_SATA2_RXOOB, "clk_sata2_rxoob", "clk_cpll_div_50m", 11, 10),
+    /* CRU_GATE_CON12 */
+    GATE(ACLK_PCIE20_MST, "aclk_pcie20_mst", "aclk_pipe", 12, 0),
+    GATE(ACLK_PCIE20_SLV, "aclk_pcie20_slv", "aclk_pipe", 12, 1),
+    GATE(ACLK_PCIE20_DBI, "aclk_pcie20_dbi", "aclk_pipe", 12, 2),
+    GATE(PCLK_PCIE20, "pclk_pcie20", "pclk_pipe", 12, 3),
+    GATE(CLK_PCIE20_AUX_NDFT, "clk_pcie20_aux_ndft", "xin24m", 12, 4),
+    GATE(ACLK_PCIE30X1_MST, "aclk_pcie30x1_mst", "aclk_pipe", 12, 8),
+    GATE(ACLK_PCIE30X1_SLV, "aclk_pcie30x1_slv", "aclk_pipe", 12, 9),
+    GATE(ACLK_PCIE30X1_DBI, "aclk_pcie30x1_dbi", "aclk_pipe", 12, 10),
+    GATE(PCLK_PCIE30X1, "pclk_pcie30x1", "pclk_pipe", 12, 11),
+    GATE(CLK_PCIE30X1_AUX_NDFT, "clk_pcie30x1_aux_ndft", "xin24m", 12, 12),
+    /* CRU_GATE_CON13 */
+    GATE(ACLK_PCIE30X2_MST, "aclk_pcie30x2_mst", "aclk_pipe", 13, 0),
+    GATE(ACLK_PCIE30X2_SLV, "aclk_pcie30x2_slv", "aclk_pipe", 13, 1),
+    GATE(ACLK_PCIE30X2_DBI, "aclk_pcie30x2_dbi", "aclk_pipe", 13, 2),
+    GATE(PCLK_PCIE30X2, "pclk_pcie30x2", "pclk_pipe", 13, 3),
+    GATE(CLK_PCIE30X2_AUX_NDFT, "clk_pcie30x2_aux_ndft", "xin24m", 13, 4),
+    GATE(PCLK_XPCS, "pclk_xpcs", "pclk_pipe", 13, 6),
+    /* CRU_GATE_CON14 */
+    GATE(ACLK_PERIMID, "aclk_perimid", "aclk_perimid_sel", 14, 0),
+    GATE(HCLK_PERIMID, "hclk_perimid", "hclk_perimid_sel", 14, 1),
+    GATE(ACLK_PHP, "aclk_php", "aclk_php_sel", 14, 8),
+    GATE(HCLK_PHP, "hclk_php", "hclk_php_sel", 14, 9),
+    GATE(PCLK_PHP, "pclk_php", "pclk_php_div", 14, 10),
+    /* CRU_GATE_CON15 */
+    GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_php", 15, 0),
+    GATE(CLK_SDMMC0, "clk_sdmmc0", "clk_sdmmc0_sel", 15, 1),
+    GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_php", 15, 2),
+    GATE(CLK_SDMMC1, "clk_sdmmc1", "clk_sdmmc1_sel", 15, 3),
+    GATE(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", "clk_gmac0_ptp_ref_sel", 15, 4),
+    GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_php", 15, 5),
+    GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php", 15, 6),
+    GATE(CLK_MAC0_2TOP, "clk_mac0_2top", "clk_mac0_2top_sel", 15, 7),
+    GATE(CLK_MAC0_OUT, "clk_mac0_out", "clk_mac0_out_sel", 15, 8),
+    GATE(CLK_MAC0_REFOUT, "clk_mac0_refout", "clk_mac0_2top", 15, 12),
+    /* CRU_GATE_CON16 */
+    GATE(ACLK_USB, "aclk_usb", "aclk_usb_sel", 16, 0),
+    GATE(HCLK_USB, "hclk_usb", "hclk_usb_sel", 16, 1),
+    GATE(PCLK_USB, "pclk_usb", "pclk_usb_div", 16, 2),
+    GATE(HCLK_USB2HOST0, "hclk_usb2host0", "hclk_usb", 16, 12),
+    GATE(HCLK_USB2HOST0_ARB, "hclk_usb2host0_arb", "hclk_usb", 16, 13),
+    GATE(HCLK_USB2HOST1, "hclk_usb2host1", "hclk_usb", 16, 14),
+    GATE(HCLK_USB2HOST1_ARB, "hclk_usb2host1_arb", "hclk_usb", 16, 15),
+    /* CRU_GATE_CON17 */
+    GATE(HCLK_SDMMC2, "hclk_sdmmc2", "hclk_usb", 17, 0),
+    GATE(CLK_SDMMC2, "clk_sdmmc2", "clk_sdmmc2_sel", 17, 1),
+    GATE(CLK_GMAC1_PTP_REF, "clK_gmac1_ptp_ref", "clk_gmac1_ptp_ref_sel", 17, 2),
+    GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_usb", 17, 3),
+    GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_usb", 17, 4),
+    GATE(CLK_MAC1_2TOP, "clk_mac1_2top", "clk_mac1_2top_sel", 17, 5),
+    GATE(CLK_MAC1_OUT, "clk_mac1_out", "clk_mac1_out_sel", 17, 6),
+    GATE(CLK_MAC1_REFOUT, "clk_mac1_refout", "clk_mac1_2top", 17, 10),
+    /* CRU_GATE_CON18 */
+    GATE(ACLK_VI, "aclk_vi", "aclk_vi_sel", 18, 0),
+    GATE(HCLK_VI, "hclk_vi", "hclk_vi_div", 18, 1),
+    GATE(PCLK_VI, "pclk_vi", "pclk_vi_div", 18, 2),
+    GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi", 18, 9),
+    GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi", 18, 10),
+    GATE(DCLK_VICAP, "dclk_vicap", "dclk_vicap1_sel", 18, 11),
+    /* CRU_GATE_CON19 */
+    GATE(ACLK_ISP, "aclk_isp", "aclk_vi", 19, 0),
+    GATE(HCLK_ISP, "hclk_isp", "hclk_vi", 19, 1),
+    GATE(CLK_ISP, "clk_isp", "clk_isp_c", 19, 2),
+    GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi", 19, 4),
+    GATE(CLK_CIF_OUT, "clk_cif_out", "clk_cif_out_c", 19, 8),
+    GATE(CLK_CAM0_OUT, "clk_cam0_out", "clk_cam0_out_c", 19, 9),
+    GATE(CLK_CAM1_OUT, "clk_cam1_out", "clk_cam1_out_c", 19, 9),
+    /* CRU_GATE_CON20 */
+    GATE(ACLK_VO, "aclk_vo", "aclk_vo_sel", 20, 0),
+    GATE(HCLK_VO, "hclk_vo", "hclk_vo_div", 20, 1),
+    GATE(PCLK_VO, "pclk_vo", "pclk_vo_div", 20, 2),
+    GATE(ACLK_VOP_PRE, "aclk_vop_pre", "aclk_vop_pre_c", 20, 6),
+    GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 20, 8),
+    GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 20, 9),
+    GATE(DCLK_VOP0, "dclk_vop0", "dclk_vop0_c", 20, 10),
+    GATE(DCLK_VOP1, "dclk_vop1", "dclk_vop1_c", 20, 11),
+    GATE(DCLK_VOP2, "dclk_vop2", "dclk_vop2_c", 20, 12),
+    GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 20, 13),
+    /* CRU_GATE_CON21 */
+    GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vo", 21, 0),
+    GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vo", 21, 1),
+    GATE(PCLK_HDCP, "pclk_hdcp", "pclk_vo", 21, 2),
+    GATE(PCLK_HDMI_HOST, "pclk_hdmi_host", "pclk_vo", 21, 3),
+    GATE(CLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 21, 4),
+    GATE(CLK_HDMI_CEC, "clk_hdmi_cec", "clk_rtc_32k", 21, 5),
+    GATE(PCLK_DSITX_0, "pclk_dsitx_0", "pclk_vo", 21, 6),
+    GATE(PCLK_DSITX_1, "pclk_dsitx_1", "pclk_vo", 21, 7),
+    GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_vo", 21, 8),
+    GATE(CLK_EDP_200M, "clk_edp_200m", "clk_edp_200m_sel", 21, 9),
+    /* CRU_GATE_CON22 */
+    GATE(ACLK_VPU_PRE, "aclk_vpu_pre", "aclk_vpu_pre_c", 22, 0),
+    GATE(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre_c", 22, 1),
+    GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 22, 4),
+    GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 22, 5),
+    GATE(PCLK_RGA_PRE, "pclk_rga_pre", "pclk_rga_pre_div", 22, 12),
+    GATE(PCLK_EINK, "pclk_eink", "pclk_rga_pre", 22, 14),
+    GATE(HCLK_EINK, "hclk_eink", "hclk_rga_pre", 22, 15),
+    /* CRU_GATE_CON23 */
+    GATE(ACLK_RGA_PRE, "aclk_rga_pre", "aclk_rga_pre_sel", 23, 0),
+    GATE(HCLK_RGA_PRE, "hclk_rga_pre", "hclk_rga_pre_div", 23, 1),
+    GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 23, 4),
+    GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 23, 5),
+    GATE(CLK_RGA_CORE, "clk_rga_core", "clk_rga_core_sel", 23, 6),
+    GATE(ACLK_IEP, "aclk_iep", "aclk_rga_pre", 23, 7),
+    GATE(HCLK_IEP, "hclk_iep", "hclk_rga_pre", 23, 8),
+    GATE(CLK_IEP_CORE, "clk_iep_core", "clk_iep_core_sel", 23, 9),
+    GATE(HCLK_EBC, "hclk_ebc", "hclk_rga_pre", 23, 10),
+    GATE(DCLK_EBC, "dclk_ebc", "dclk_ebc_sel", 23, 11),
+    GATE(ACLK_JDEC, "aclk_jdec", "aclk_rga_pre", 23, 12),
+    GATE(HCLK_JDEC, "hclk_jdec", "hclk_rga_pre", 23, 13),
+    GATE(ACLK_JENC, "aclk_jenc", "aclk_rga_pre", 23, 14),
+    GATE(HCLK_JENC, "hclk_jenc", "hclk_rga_pre", 23, 15),
+    /* CRU_GATE_CON24 */
+    GATE(ACLK_RKVENC_PRE, "aclk_rkvenc_pre", "aclk_rkvenc_pre_c", 24, 0),
+    GATE(HCLK_RKVENC_PRE, "hclk_rkvenc_pre", "hclk_rkvenc_pre_div", 24, 1),
+    GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 24, 6),
+    GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 24, 7),
+    GATE(CLK_RKVENC_CORE, "clk_rkvenc_core", "clk_rkvenc_core_c", 24, 8),
+    GATE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", "aclk_rkvdec_pre_c", 25, 0),
+    /* CRU_GATE_CON25 */
+    GATE(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "hclk_rkvdec_pre_div", 25, 1),
+    GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 25, 4),
+    GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 25, 5),
+    GATE(CLK_RKVDEC_CA, "clk_rkvdec_ca", "clk_rkvdec_ca_c", 25, 6),
+    GATE(CLK_RKVDEC_CORE, "clk_rkvdec_core", "clk_rkvdec_core_c", 25, 7),
+    GATE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", "clk_rkvdec_hevc_ca_c", 25, 8),
+    /* CRU_GATE_CON26 */
+    GATE(ACLK_BUS, "aclk_bus", "aclk_bus_sel", 26, 0),
+    GATE(PCLK_BUS, "pclk_bus", "pclk_bus_sel", 26, 1),
+    GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 26, 4),
+    GATE(CLK_TSADC_TSEN, "clk_tsadc_tsen", "clk_tsadc_tsen_c", 26, 5),
+    GATE(CLK_TSADC, "clk_tsadc", "clk_tsadc_div", 26, 6),
+    GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 26, 7),
+    GATE(CLK_SARADC, "clk_saradc", "xin24m", 26, 8),
+    GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "hclk_secure_flash", 26, 9),
+    GATE(CLK_OTPC_NS_SBPI, "clk_otpc_ns_sbpi", "xin24m", 26, 10),
+    GATE(CLK_OTPC_NS_USR, "clk_otpc_ns_usr", "xin_osc0_half", 26, 11),
+    GATE(PCLK_SCR, "pclk_scr", "pclk_bus", 26, 12),
+    GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus", 26, 13),
+    GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 26, 14),
+    /* CRU_GATE_CON27 */
+    GATE(PCLK_CAN0, "pclk_can0", "pclk_bus", 27, 5),
+    GATE(CLK_CAN0, "clk_can0", "clk_can0_c", 27, 6),
+    GATE(PCLK_CAN1, "pclk_can1", "pclk_bus", 27, 7),
+    GATE(CLK_CAN1, "clk_can1", "clk_can1_c", 27, 8),
+    GATE(PCLK_CAN2, "pclk_can2", "pclk_bus", 27, 9),
+    GATE(CLK_CAN2, "clk_can2", "clk_can2_c", 27, 10),
+    GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 27, 12),
+    GATE(CLK_UART1_SRC, "clk_uart1_src", "clk_uart1_src_c", 27, 13),
+    GATE(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_frac_frac", 27, 14),
+    GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_sel", 27, 15),
+    /* CRU_GATE_CON28 */
+    GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 28, 0),
+    GATE(CLK_UART2_SRC, "clk_uart2_src", "clk_uart2_src_c", 28, 1),
+    GATE(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_frac_frac", 28, 2),
+    GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_sel", 28, 3),
+    GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 28, 4),
+    GATE(CLK_UART3_SRC, "clk_uart3_src", "clk_uart3_src_c", 28, 5),
+    GATE(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_frac_frac", 28, 6),
+    GATE(SCLK_UART3, "sclk_uart3", "sclk_uart3_sel", 28, 7),
+    GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 28, 8),
+    GATE(CLK_UART4_SRC, "clk_uart4_src", "clk_uart4_src_c", 28, 9),
+    GATE(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_frac_frac", 28, 10),
+    GATE(SCLK_UART4, "sclk_uart4", "sclk_uart4_sel", 28, 11),
+    GATE(PCLK_UART5, "pclk_uart5", "pclk_bus", 28, 12),
+    GATE(CLK_UART5_SRC, "clk_uart5_src", "clk_uart5_src_c", 28, 13),
+    GATE(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_frac_frac", 28, 14),
+    GATE(SCLK_UART5, "sclk_uart5", "sclk_uart5_sel", 28, 15),
+    /* CRU_GATE_CON29 */
+    GATE(PCLK_UART6, "pclk_uart6", "pclk_bus", 29, 0),
+    GATE(CLK_UART6_SRC, "clk_uart6_src", "clk_uart6_src_c", 29, 1),
+    GATE(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_frac_frac", 29, 2),
+    GATE(SCLK_UART6, "sclk_uart6", "sclk_uart6_sel", 29, 3),
+    GATE(PCLK_UART7, "pclk_uart7", "pclk_bus", 29, 4),
+    GATE(CLK_UART7_SRC, "clk_uart7_src", "clk_uart7_src_c", 29, 5),
+    GATE(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_frac_frac", 29, 6),
+    GATE(SCLK_UART7, "sclk_uart7", "sclk_uart7_sel", 29, 7),
+    GATE(PCLK_UART8, "pclk_uart8", "pclk_bus", 29, 8),
+    GATE(CLK_UART8_SRC, "clk_uart8_src", "clk_uart8_src_c", 29, 9),
+    GATE(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_frac_frac", 29, 10),
+    GATE(SCLK_UART8, "sclk_uart8", "sclk_uart8_sel", 29, 11),
+    GATE(PCLK_UART9, "pclk_uart9", "pclk_bus", 29, 12),
+    GATE(CLK_UART9_SRC, "clk_uart9_src", "clk_uart9_src_c", 29, 13),
+    GATE(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_frac_frac", 29, 14),
+    GATE(SCLK_UART9, "sclk_uart9", "sclk_uart9_sel", 29, 15),
+    /* CRU_GATE_CON30 */
+    GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 30, 0),
+    GATE(CLK_I2C1, "clk_i2c1", "clk_i2c", 30, 1),
+    GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 30, 2),
+    GATE(CLK_I2C2, "clk_i2c2", "clk_i2c", 30, 3),
+    GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 30, 4),
+    GATE(CLK_I2C3, "clk_i2c3", "clk_i2c", 30, 5),
+    GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus", 30, 6),
+    GATE(CLK_I2C4, "clk_i2c4", "clk_i2c", 30, 7),
+    GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus", 30, 8),
+    GATE(CLK_I2C5, "clk_i2c5", "clk_i2c", 30, 9),
+    GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 30, 10),
+    GATE(CLK_SPI0, "clk_spi0", "clk_spi0_sel", 30, 11),
+    GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 30, 12),
+    GATE(CLK_SPI1, "clk_spi1", "clk_spi1_sel", 30, 13),
+    GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 30, 14),
+    GATE(CLK_SPI2, "clk_spi2", "clk_spi2_sel", 30, 15),
+    /* CRU_GATE_CON31 */
+    GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus", 31, 0),
+    GATE(CLK_SPI3, "clk_spi3", "clk_spi3_sel", 31, 1),
+    GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 31, 2),
+    GATE(DBCLK_GPIO1, "dbclk_gpio1", "dbclk_gpio", 31, 3),
+    GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 31, 4),
+    GATE(DBCLK_GPIO2, "dbclk_gpio2", "dbclk_gpio", 31, 5),
+    GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 31, 6),
+    GATE(DBCLK_GPIO3, "dbclk_gpio3", "dbclk_gpio", 31, 7),
+    GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 31, 8),
+    GATE(DBCLK_GPIO4, "dbclk_gpio4", "dbclk_gpio", 31, 9),
+    GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 31, 10),
+    GATE(CLK_PWM1, "clk_pwm1", "clk_pwm1_sel", 31, 11),
+    GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 31, 12),
+    GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", 31, 13),
+    GATE(CLK_PWM2, "clk_pwm2", "clk_pwm2_sel", 31, 14),
+    GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 31, 15),
+    /* CRU_GATE_CON32 */
+    GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus", 32, 0),
+    GATE(CLK_PWM3, "clk_pwm3", "clk_pwm3_sel", 32, 1),
+    GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 32, 2),
+    GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 32, 3),
+    GATE(CLK_TIMER0, "clk_timer0", "xin24m", 32, 4),
+    GATE(CLK_TIMER1, "clk_timer1", "xin24m", 32, 5),
+    GATE(CLK_TIMER2, "clk_timer2", "xin24m", 32, 6),
+    GATE(CLK_TIMER3, "clk_timer3", "xin24m", 32, 7),
+    GATE(CLK_TIMER4, "clk_timer4", "xin24m", 32, 8),
+    GATE(CLK_TIMER5, "clk_timer5", "xin24m", 32, 9),
+    GATE(CLK_I2C, "clk_i2c", "clk_i2c_sel", 32, 10),
+    GATE(DBCLK_GPIO, "dbclk_gpio", "dbclk_gpio_sel", 32, 11),
+    GATE(ACLK_MCU, "aclk_mcu", "aclk_bus", 32, 13),
+    GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus", 32, 14),
+    GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus", 32, 15),
+    /* CRU_GATE_CON33 */
+    GATE(ACLK_TOP_HIGH, "aclk_top_high", "aclk_top_high_sel", 33, 0),
+    GATE(ACLK_TOP_LOW, "aclk_top_low", "aclk_top_low_sel", 33, 1),
+    GATE(HCLK_TOP, "hclk_top", "hclk_top_sel", 33, 2),
+    GATE(PCLK_TOP, "pclk_top", "pclk_top_sel", 33, 3),
+    GATE(PCLK_PCIE30PHY, "pclk_pcie30phy", "pclk_top", 33, 8),
+    GATE(CLK_OPTC_ARB, "clk_optc_arb", "clk_optc_arb_sel", 33, 9),
+    GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top", 33, 13),
+    GATE(PCLK_MIPIDSIPHY0, "pclk_mipidsiphy0", "pclk_top", 33, 14),
+    GATE(PCLK_MIPIDSIPHY1, "pclk_mipidsiphy1", "pclk_top", 33, 15),
+    /* CRU_GATE_CON34 */
+    GATE(PCLK_PIPEPHY0, "pclk_pipephy0", "pclk_top", 34, 4),
+    GATE(PCLK_PIPEPHY1, "pclk_pipephy1", "pclk_top", 34, 5),
+    GATE(PCLK_PIPEPHY2, "pclk_pipephy2", "pclk_top", 34, 6),
+    GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_top", 34, 11),
+    GATE(CLK_CPU_BOOST, "clk_cpu_boost", "xin24m", 34, 12),
+    GATE(PCLK_OTPPHY, "pclk_otpphy", "pclk_top", 34, 13),
+    GATE(PCLK_EDPPHY_GRF, "pclk_edpphy_grf", "pclk_top", 34, 14),
+    /* CRU_GATE_CON35 */
+    GATE(CPLL_500M, "clk_cpll_div_500m", "clk_cpll_div_500m_div", 35, 7),
+    GATE(CPLL_333M, "clk_cpll_div_333m", "clk_cpll_div_333m_div", 35, 8),
+    GATE(CPLL_250M, "clk_cpll_div_250m", "clk_cpll_div_250m_div", 35, 9),
+    GATE(CPLL_125M, "clk_cpll_div_125m", "clk_cpll_div_125m_div", 35, 10),
+    GATE(CPLL_100M, "clk_cpll_div_100m", "clk_cpll_div_100m_div", 35, 11),
+    GATE(CPLL_62P5M, "clk_cpll_div_62P5m", "clk_cpll_div_62P5m_div", 35, 12),
+    GATE(CPLL_50M, "clk_cpll_div_50m", "clk_cpll_div_50m_div", 35, 13),
+    GATE(CPLL_25M, "clk_cpll_div_25m", "clk_cpll_div_25m_div", 35, 14),
+};
+
+static struct rk_clk_gate pmu_clk_gates[] =
+{
+    /* PMUCRU_PMUGATE_CON00 */
+    GATE(XIN_OSC0_DIV, "xin_osc0_div", "xin_osc0_div_div", 0, 0),
+    GATE(CLK_RTC_32K, "clk_rtc_32k", "clk_rtc_32k_mux", 0, 1),
+    GATE(PCLK_PDPMU, "pclk_pdpmu", "pclk_pdpmu_pre", 0, 2),
+    GATE(PCLK_PMU, "pclk_pmu", "pclk_pdpmu", 0, 6),
+    GATE(CLK_PMU, "clk_pmu", "xin24m", 0, 7),
+    /* PMUCRU_PMUGATE_CON01 */
+    GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pdpmu", 1, 0),
+    GATE(CLK_I2C0, "clk_i2c0", "clk_i2c0_div", 1, 1),
+    GATE(PCLK_UART0, "pclk_uart0", "pclk_pdpmu", 1, 2),
+    GATE(CLK_UART0_DIV, "sclk_uart0_div", "sclk_uart0_div_div", 1, 3),
+    GATE(CLK_UART0_FRAC, "sclk_uart0_frac", "sclk_uart0_frac_div", 1, 4),
+    GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_mux", 1, 5),
+    GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pdpmu", 1, 6),
+    GATE(CLK_PWM0, "clk_pwm0", "clk_pwm0_div", 1, 7),
+    GATE(CLK_CAPTURE_PWM0_NDFT, "clk_capture_pwm0_ndft", "xin24m", 1, 8),
+    GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pdpmu", 1, 9),
+    GATE(DBCLK_GPIO0, "dbclk_gpio0", "dbclk_gpio0_sel", 1, 10),
+    GATE(PCLK_PMUPVTM, "pclk_pmupvtm", "pclk_pdpmu", 1, 11),
+    GATE(CLK_PMUPVTM, "clk_pmupvtm", "xin24m", 1, 12),
+    GATE(CLK_CORE_PMUPVTM, "clk_core_pmupvtm", "xin24m", 1, 13),
+    /* PMUCRU_PMUGATE_CON02 */
+    GATE(CLK_REF24M, "clk_ref24m", "clk_ref24m_div", 2, 0),
+    GATE(XIN_OSC0_USBPHY0_G, "xin_osc0_usbphy0_g", "xin24m", 2, 1),
+    GATE(XIN_OSC0_USBPHY1_G, "xin_osc0_usbphy1_g", "xin24m", 2, 2),
+    GATE(XIN_OSC0_MIPIDSIPHY0_G, "xin_osc0_mipidsiphy0_g", "xin24m", 2, 3),
+    GATE(XIN_OSC0_MIPIDSIPHY1_G, "xin_osc0_mipidsiphy1_g", "xin24m", 2, 4),
+    GATE(CLK_WIFI_DIV, "clk_wifi_div", "clk_wifi_div_div", 2, 5),
+    GATE(CLK_WIFI_OSC0, "clk_wifi_osc0", "xin24m", 2, 6),
+    GATE(CLK_PCIEPHY0_DIV, "clk_pciephy0_div", "clk_pciephy0_div_div", 2, 7),
+    GATE(CLK_PCIEPHY0_OSC0, "clk_pciephy0_osc0", "xin24m", 2, 8),
+    GATE(CLK_PCIEPHY1_DIV, "clk_pciephy1_div", "clk_pciephy1_div_div", 2, 9),
+    GATE(CLK_PCIEPHY1_OSC0, "clk_pciephy1_osc0", "xin24m", 2, 10),
+    GATE(CLK_PCIEPHY2_DIV, "clk_pciephy2_div", "clk_pciephy2_div_div", 2, 11),
+    GATE(CLK_PCIEPHY2_OSC0, "clk_pciephy2_osc0", "xin24m", 2, 12),
+    GATE(CLK_PCIE30PHY_REF_M, "clk_pcie30phy_ref_m", "ppll_ph0", 2, 13),
+    GATE(CLK_PCIE30PHY_REF_N, "clk_pcie30phy_ref_n", "ppll_ph180", 2, 14),
+    GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 2, 15),
+};
+
+#define PLL_MODE_MASK   0x1
+#include "clk-pll-rk3568.c"
+#include "clk-mmc-phase.c"
+#include "softrst.c"
+
+static struct rk_pmuclk_priv *find_pmu(void)
+{
+    struct rk_pmuclk_priv *pmu_priv = RT_NULL;
+    const char *compatible = "rockchip,rk3568-pmucru";
+    struct rt_ofw_node *np = rt_ofw_find_node_by_compatible(RT_NULL, compatible);
+
+    if (np)
+    {
+        struct rk_clk *rk_clk = rt_ofw_data(np);
+
+        pmu_priv = &rk_clk->pmuclk_info;
+        rt_ofw_node_put(np);
+    }
+    else
+    {
+        LOG_E("Find pmucru %s fail", compatible);
+    }
+
+    return pmu_priv;
+}
+
+static rt_ubase_t pmu_pll_set_rate(rt_ubase_t pll_id, rt_ubase_t rate)
+{
+    struct rk_pmuclk_priv *pmu_priv = find_pmu();
+
+    if (pmu_priv)
+    {
+        rk_pll_set_rate(&pmu_pll_clks[pll_id], pmu_priv->pmucru, rate);
+    }
+
+    return 0;
+}
+
+static rt_ubase_t pmu_pll_get_rate(rt_ubase_t pll_id)
+{
+    struct rk_pmuclk_priv *pmu_priv = find_pmu();
+
+    if (pmu_priv)
+    {
+        return rk_pll_get_rate(&pmu_pll_clks[pll_id], &pmu_priv->pmucru);
+    }
+
+    return 0;
+}
+
+static rt_ubase_t rtc32k_get_pmuclk(struct rk_pmuclk_priv *priv)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_ubase_t m, n;
+    rt_uint32_t fracdiv;
+
+    fracdiv = HWREG32(&pmucru->pmu_clksel_con[1]);
+    m = fracdiv & RTC32K_FRAC_NUMERATOR_MASK;
+    m >>= RTC32K_FRAC_NUMERATOR_SHIFT;
+    n = fracdiv & RTC32K_FRAC_DENOMINATOR_MASK;
+    n >>= RTC32K_FRAC_DENOMINATOR_SHIFT;
+
+    return OSC_HZ * m / n;
+}
+
+static rt_ubase_t rtc32k_set_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_ubase_t m, n, val;
+
+    rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK, RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
+
+    rational_best_approximation(rate, OSC_HZ, RT_GENMASK(16 - 1, 0), RT_GENMASK(16 - 1, 0), &m, &n);
+    val = m << RTC32K_FRAC_NUMERATOR_SHIFT | n;
+    HWREG32(&pmucru->pmu_clksel_con[1]) = val;
+
+    return rtc32k_get_pmuclk(priv);
+}
+
+static rt_ubase_t uart_get_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_uint32_t reg, con, fracdiv, div, src, p_src, p_rate;
+    rt_ubase_t m, n;
+
+    switch (clk_id)
+    {
+    case SCLK_UART0:
+        reg = 4;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    con = HWREG32(&pmucru->pmu_clksel_con[reg]);
+    src = (con & CLK_UART0_SEL_MASK) >> CLK_UART0_SEL_SHIFT;
+    div = (con & CLK_UART0_DIV_DIV_MASK) >> CLK_UART0_DIV_DIV_SHIFT;
+    p_src = (con & CLK_UART0_DIV_SEL_MASK) >> CLK_UART0_DIV_SEL_SHIFT;
+
+    if (p_src == CLK_UART0_SRC_SEL_PPLL)
+    {
+        p_rate = priv->ppll_hz;
+    }
+    else if (p_src == CLK_UART0_SRC_SEL_GPLL)
+    {
+        p_rate = priv->hpll_hz;
+    }
+    else
+    {
+        p_rate = 480000000;
+    }
+    if (src == CLK_UART0_SEL_DIV)
+    {
+        return DIV_TO_RATE(p_rate, div);
+    }
+    else if (src == CLK_UART0_SEL_FRACDIV)
+    {
+        fracdiv = HWREG32(&pmucru->pmu_clksel_con[reg + 1]);
+        n = fracdiv & CLK_UART0_FRAC_NUMERATOR_MASK;
+        n >>= CLK_UART0_FRAC_NUMERATOR_SHIFT;
+        m = fracdiv & CLK_UART0_FRAC_DENOMINATOR_MASK;
+        m >>= CLK_UART0_FRAC_DENOMINATOR_SHIFT;
+        return DIV_TO_RATE(p_rate, div) * n / m;
+    }
+    else
+    {
+        return OSC_HZ;
+    }
+}
+
+static rt_ubase_t uart_set_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_uint32_t reg, clk_src, uart_src, div;
+    rt_ubase_t m = 0, n = 0, val;
+
+    if (priv->ppll_hz % rate == 0)
+    {
+        clk_src = CLK_UART0_SRC_SEL_PPLL;
+        uart_src = CLK_UART0_SEL_DIV;
+        div = RT_DIV_ROUND_UP(priv->ppll_hz, rate);
+    }
+    else if (priv->hpll_hz % rate == 0)
+    {
+        clk_src = CLK_UART0_SRC_SEL_GPLL;
+        uart_src = CLK_UART0_SEL_DIV;
+        div = RT_DIV_ROUND_UP(priv->hpll_hz, rate);
+    }
+    else if (rate == OSC_HZ)
+    {
+        clk_src = CLK_UART0_SRC_SEL_GPLL;
+        uart_src = CLK_UART0_SEL_XIN24M;
+        div = 2;
+    }
+
+    switch (clk_id)
+    {
+    case SCLK_UART0:
+        reg = 4;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&pmucru->pmu_clksel_con[reg], CLK_UART0_SEL_MASK | CLK_UART0_DIV_SEL_MASK | CLK_UART0_DIV_DIV_MASK,
+            (clk_src << CLK_UART0_DIV_SEL_SHIFT) | (uart_src << CLK_UART0_SEL_SHIFT) |
+            ((div - 1) << CLK_UART0_DIV_DIV_SHIFT));
+    if (m && n)
+    {
+        val = m << CLK_UART0_FRAC_NUMERATOR_SHIFT | n;
+        HWREG32(&pmucru->pmu_clksel_con[reg + 1]) = val;
+    }
+
+    return uart_get_pmuclk(priv, clk_id);
+}
+
+static rt_ubase_t i2c_get_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_uint32_t div, con;
+
+    switch (clk_id)
+    {
+    case CLK_I2C0:
+        con = HWREG32(&pmucru->pmu_clksel_con[3]);
+        div = (con & CLK_I2C0_DIV_MASK) >> CLK_I2C0_DIV_SHIFT;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return DIV_TO_RATE(priv->ppll_hz, div);
+}
+
+static rt_ubase_t i2c_set_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    int src_clk_div;
+
+    src_clk_div = RT_DIV_ROUND_UP(priv->ppll_hz, rate);
+    RT_ASSERT(src_clk_div - 1 <= 127);
+
+    switch (clk_id)
+    {
+    case CLK_I2C0:
+        rk_clrsetreg(&pmucru->pmu_clksel_con[3], CLK_I2C0_DIV_MASK, (src_clk_div - 1) << CLK_I2C0_DIV_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return i2c_get_pmuclk(priv, clk_id);
+}
+
+static rt_ubase_t pwm_get_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_uint32_t div, sel, con, parent;
+
+    switch (clk_id)
+    {
+    case CLK_PWM0:
+        con = HWREG32(&pmucru->pmu_clksel_con[6]);
+        sel = (con & CLK_PWM0_SEL_MASK) >> CLK_PWM0_SEL_SHIFT;
+        div = (con & CLK_PWM0_DIV_MASK) >> CLK_PWM0_DIV_SHIFT;
+        if (sel == CLK_PWM0_SEL_XIN24M)
+        {
+            parent = OSC_HZ;
+        }
+        else
+        {
+            parent = priv->ppll_hz;
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return DIV_TO_RATE(parent, div);
+}
+
+static rt_ubase_t pwm_set_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    int src_clk_div;
+
+    switch (clk_id)
+    {
+    case CLK_PWM0:
+        if (rate == OSC_HZ)
+        {
+            rk_clrsetreg(&pmucru->pmu_clksel_con[6], CLK_PWM0_SEL_MASK | CLK_PWM0_DIV_MASK,
+                    (CLK_PWM0_SEL_XIN24M << CLK_PWM0_SEL_SHIFT) | 0 << CLK_PWM0_SEL_SHIFT);
+        }
+        else
+        {
+            src_clk_div = RT_DIV_ROUND_UP(priv->ppll_hz, rate);
+            RT_ASSERT(src_clk_div - 1 <= 127);
+            rk_clrsetreg(&pmucru->pmu_clksel_con[6], CLK_PWM0_DIV_MASK | CLK_PWM0_DIV_MASK,
+                    (CLK_PWM0_SEL_PPLL << CLK_PWM0_SEL_SHIFT) | (src_clk_div - 1) << CLK_PWM0_DIV_SHIFT);
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return pwm_get_pmuclk(priv, clk_id);
+}
+
+static int armclk_set_clk(struct rk_clk_priv *priv, rt_ubase_t hz)
+{
+    struct rk_cru *cru = priv->cru;
+    const struct rk_cpu_rate_table *rate;
+    rt_ubase_t old_rate;
+
+    rate = rk_get_cpu_settings(cpu_rates, hz);
+    if (!rate)
+    {
+        LOG_E("Unsupport rate %u", hz);
+
+        return -RT_ENOSYS;
+    }
+
+    LOG_I("set cpu_freq to %lu", hz);
+
+    rk_clrsetreg(&cru->clksel_con[0], CLK_CORE_PRE_SEL_MASK, (CLK_CORE_PRE_SEL_SRC << CLK_CORE_PRE_SEL_SHIFT));
+    rk_clrsetreg(&cru->clksel_con[2],
+            SCLK_CORE_PRE_SEL_MASK | SCLK_CORE_SRC_SEL_MASK | SCLK_CORE_SRC_DIV_MASK,
+            (SCLK_CORE_PRE_SEL_SRC << SCLK_CORE_PRE_SEL_SHIFT) |
+            (SCLK_CORE_SRC_SEL_APLL <<SCLK_CORE_SRC_SEL_SHIFT) |
+            (1 << SCLK_CORE_SRC_DIV_SHIFT));
+
+    /*
+     * set up dependent divisors for DBG and ACLK clocks.
+     */
+    old_rate = rk_pll_get_rate(&pll_clks[apll], &priv->cru);
+    if (old_rate > hz)
+    {
+        if (rk_pll_set_rate(&pll_clks[apll], priv->cru, hz))
+        {
+            LOG_E("cpu_rate adjust error");
+            return -RT_ENOSYS;
+        }
+        rk_clrsetreg(&cru->clksel_con[3], GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
+                rate->pclk_div << GICCLK_CORE_DIV_SHIFT | rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
+        rk_clrsetreg(&cru->clksel_con[4], PERIPHCLK_CORE_PRE_DIV_MASK | PCLK_CORE_PRE_DIV_MASK,
+                rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
+        rk_clrsetreg(&cru->clksel_con[5], ACLK_CORE_NDFT_DIV_MASK, rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
+    }
+    else if (old_rate < hz)
+    {
+        rk_clrsetreg(&cru->clksel_con[3], GICCLK_CORE_DIV_MASK | ATCLK_CORE_DIV_MASK,
+                rate->pclk_div << GICCLK_CORE_DIV_SHIFT | rate->pclk_div << ATCLK_CORE_DIV_SHIFT);
+        rk_clrsetreg(&cru->clksel_con[4], PERIPHCLK_CORE_PRE_DIV_MASK | PCLK_CORE_PRE_DIV_MASK,
+                rate->pclk_div << PCLK_CORE_PRE_DIV_SHIFT | rate->pclk_div << PERIPHCLK_CORE_PRE_DIV_SHIFT);
+        rk_clrsetreg(&cru->clksel_con[5], ACLK_CORE_NDFT_DIV_MASK, rate->aclk_div << ACLK_CORE_NDFT_DIV_SHIFT);
+
+        if (rk_pll_set_rate(&pll_clks[apll], priv->cru, hz))
+        {
+            LOG_E("cpu_rate adjust error");
+            return -RT_ENOSYS;
+        }
+    }
+
+    return 0;
+}
+
+static rt_ubase_t cpll_div_get_rate(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    int div, mask, shift, con;
+
+    switch (clk_id)
+    {
+    case CPLL_500M:
+        con = 78;
+        mask = CPLL_500M_DIV_MASK;
+        shift = CPLL_500M_DIV_SHIFT;
+        break;
+    case CPLL_333M:
+        con = 79;
+        mask = CPLL_333M_DIV_MASK;
+        shift = CPLL_333M_DIV_SHIFT;
+        break;
+    case CPLL_250M:
+        con = 79;
+        mask = CPLL_250M_DIV_MASK;
+        shift = CPLL_250M_DIV_SHIFT;
+        break;
+    case CPLL_125M:
+        con = 80;
+        mask = CPLL_125M_DIV_MASK;
+        shift = CPLL_125M_DIV_SHIFT;
+        break;
+    case CPLL_100M:
+        con = 82;
+        mask = CPLL_100M_DIV_MASK;
+        shift = CPLL_100M_DIV_SHIFT;
+        break;
+    case CPLL_62P5M:
+        con = 80;
+        mask = CPLL_62P5M_DIV_MASK;
+        shift = CPLL_62P5M_DIV_SHIFT;
+        break;
+    case CPLL_50M:
+        con = 81;
+        mask = CPLL_50M_DIV_MASK;
+        shift = CPLL_50M_DIV_SHIFT;
+        break;
+    case CPLL_25M:
+        con = 81;
+        mask = CPLL_25M_DIV_MASK;
+        shift = CPLL_25M_DIV_SHIFT;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    div = (HWREG32(&cru->clksel_con[con]) & mask) >> shift;
+    return DIV_TO_RATE(priv->cpll_hz, div);
+}
+
+static rt_ubase_t cpll_div_set_rate(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int div, mask, shift, con;
+
+    switch (clk_id)
+    {
+    case CPLL_500M:
+        con = 78;
+        mask = CPLL_500M_DIV_MASK;
+        shift = CPLL_500M_DIV_SHIFT;
+        break;
+    case CPLL_333M:
+        con = 79;
+        mask = CPLL_333M_DIV_MASK;
+        shift = CPLL_333M_DIV_SHIFT;
+        break;
+    case CPLL_250M:
+        con = 79;
+        mask = CPLL_250M_DIV_MASK;
+        shift = CPLL_250M_DIV_SHIFT;
+        break;
+    case CPLL_125M:
+        con = 80;
+        mask = CPLL_125M_DIV_MASK;
+        shift = CPLL_125M_DIV_SHIFT;
+        break;
+    case CPLL_100M:
+        con = 82;
+        mask = CPLL_100M_DIV_MASK;
+        shift = CPLL_100M_DIV_SHIFT;
+        break;
+    case CPLL_62P5M:
+        con = 80;
+        mask = CPLL_62P5M_DIV_MASK;
+        shift = CPLL_62P5M_DIV_SHIFT;
+        break;
+    case CPLL_50M:
+        con = 81;
+        mask = CPLL_50M_DIV_MASK;
+        shift = CPLL_50M_DIV_SHIFT;
+        break;
+    case CPLL_25M:
+        con = 81;
+        mask = CPLL_25M_DIV_MASK;
+        shift = CPLL_25M_DIV_SHIFT;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+    RT_ASSERT(div - 1 <= 31);
+    rk_clrsetreg(&cru->clksel_con[con], mask, (div - 1) << shift);
+
+    return cpll_div_get_rate(priv, clk_id);
+}
+
+static rt_ubase_t bus_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con, sel, rate;
+
+    switch (clk_id)
+    {
+    case ACLK_BUS:
+        con = HWREG32(&cru->clksel_con[50]);
+        sel = (con & ACLK_BUS_SEL_MASK) >> ACLK_BUS_SEL_SHIFT;
+
+        if (sel == ACLK_BUS_SEL_200M)
+        {
+            rate = 200 * MHZ;
+        }
+        else if (sel == ACLK_BUS_SEL_150M)
+        {
+            rate = 150 * MHZ;
+        }
+        else if (sel == ACLK_BUS_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    case PCLK_BUS:
+    case PCLK_WDT_NS:
+        con = HWREG32(&cru->clksel_con[50]);
+        sel = (con & PCLK_BUS_SEL_MASK) >> PCLK_BUS_SEL_SHIFT;
+        if (sel == PCLK_BUS_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else if (sel == PCLK_BUS_SEL_75M)
+        {
+            rate = 75 * MHZ;
+        }
+        else if (sel == PCLK_BUS_SEL_50M)
+        {
+            rate = 50 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t bus_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (clk_id)
+    {
+    case ACLK_BUS:
+        if (rate == 200 * MHZ)
+        {
+            src_clk = ACLK_BUS_SEL_200M;
+        }
+        else if (rate == 150 * MHZ)
+        {
+            src_clk = ACLK_BUS_SEL_150M;
+        }
+        else if (rate == 100 * MHZ)
+        {
+            src_clk = ACLK_BUS_SEL_100M;
+        }
+        else
+        {
+            src_clk = ACLK_BUS_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[50], ACLK_BUS_SEL_MASK, src_clk << ACLK_BUS_SEL_SHIFT);
+        break;
+    case PCLK_BUS:
+    case PCLK_WDT_NS:
+        if (rate == 100 * MHZ)
+        {
+            src_clk = PCLK_BUS_SEL_100M;
+        }
+        else if (rate == 75 * MHZ)
+        {
+            src_clk = PCLK_BUS_SEL_75M;
+        }
+        else if (rate == 50 * MHZ)
+        {
+            src_clk = PCLK_BUS_SEL_50M;
+        }
+        else
+        {
+            src_clk = PCLK_BUS_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[50], PCLK_BUS_SEL_MASK, src_clk << PCLK_BUS_SEL_SHIFT);
+        break;
+
+    default:
+        return -RT_ENOSYS;
+    }
+
+    return bus_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t perimid_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con, sel, rate;
+
+    switch (clk_id)
+    {
+    case ACLK_PERIMID:
+        con = HWREG32(&cru->clksel_con[10]);
+        sel = (con & ACLK_PERIMID_SEL_MASK) >> ACLK_PERIMID_SEL_SHIFT;
+        if (sel == ACLK_PERIMID_SEL_300M)
+        {
+            rate = 300 * MHZ;
+        }
+        else if (sel == ACLK_PERIMID_SEL_200M)
+        {
+            rate = 200 * MHZ;
+        }
+        else if (sel == ACLK_PERIMID_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    case HCLK_PERIMID:
+        con = HWREG32(&cru->clksel_con[10]);
+        sel = (con & HCLK_PERIMID_SEL_MASK) >> HCLK_PERIMID_SEL_SHIFT;
+        if (sel == HCLK_PERIMID_SEL_150M)
+        {
+            rate = 150 * MHZ;
+        }
+        else if (sel == HCLK_PERIMID_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else if (sel == HCLK_PERIMID_SEL_75M)
+        {
+            rate = 75 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t perimid_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (clk_id)
+    {
+    case ACLK_PERIMID:
+        if (rate == 300 * MHZ)
+        {
+            src_clk = ACLK_PERIMID_SEL_300M;
+        }
+        else if (rate == 200 * MHZ)
+        {
+            src_clk = ACLK_PERIMID_SEL_200M;
+        }
+        else if (rate == 100 * MHZ)
+        {
+            src_clk = ACLK_PERIMID_SEL_100M;
+        }
+        else
+        {
+            src_clk = ACLK_PERIMID_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[10], ACLK_PERIMID_SEL_MASK, src_clk << ACLK_PERIMID_SEL_SHIFT);
+        break;
+    case HCLK_PERIMID:
+        if (rate == 150 * MHZ)
+        {
+            src_clk = HCLK_PERIMID_SEL_150M;
+        }
+        else if (rate == 100 * MHZ)
+        {
+            src_clk = HCLK_PERIMID_SEL_100M;
+        }
+        else if (rate == 75 * MHZ)
+        {
+            src_clk = HCLK_PERIMID_SEL_75M;
+        }
+        else
+        {
+            src_clk = HCLK_PERIMID_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[10], HCLK_PERIMID_SEL_MASK, src_clk << HCLK_PERIMID_SEL_SHIFT);
+        break;
+
+    default:
+        return -RT_ENOSYS;
+    }
+
+    return perimid_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t top_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con, sel, rate;
+
+    switch (clk_id)
+    {
+    case ACLK_TOP_HIGH:
+        con = HWREG32(&cru->clksel_con[73]);
+        sel = (con & ACLK_TOP_HIGH_SEL_MASK) >> ACLK_TOP_HIGH_SEL_SHIFT;
+        if (sel == ACLK_TOP_HIGH_SEL_500M)
+        {
+            rate = 500 * MHZ;
+        }
+        else if (sel == ACLK_TOP_HIGH_SEL_400M)
+        {
+            rate = 400 * MHZ;
+        }
+        else if (sel == ACLK_TOP_HIGH_SEL_300M)
+        {
+            rate = 300 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    case ACLK_TOP_LOW:
+        con = HWREG32(&cru->clksel_con[73]);
+        sel = (con & ACLK_TOP_LOW_SEL_MASK) >> ACLK_TOP_LOW_SEL_SHIFT;
+        if (sel == ACLK_TOP_LOW_SEL_400M)
+        {
+            rate = 400 * MHZ;
+        }
+        else if (sel == ACLK_TOP_LOW_SEL_300M)
+        {
+            rate = 300 * MHZ;
+        }
+        else if (sel == ACLK_TOP_LOW_SEL_200M)
+        {
+            rate = 200 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    case HCLK_TOP:
+        con = HWREG32(&cru->clksel_con[73]);
+        sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT;
+        if (sel == HCLK_TOP_SEL_150M)
+        {
+            rate = 150 * MHZ;
+        }
+        else if (sel == HCLK_TOP_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else if (sel == HCLK_TOP_SEL_75M)
+        {
+            rate = 75 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    case PCLK_TOP:
+        con = HWREG32(&cru->clksel_con[73]);
+        sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT;
+        if (sel == PCLK_TOP_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else if (sel == PCLK_TOP_SEL_75M)
+        {
+            rate = 75 * MHZ;
+        }
+        else if (sel == PCLK_TOP_SEL_50M)
+        {
+            rate = 50 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t top_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (clk_id)
+    {
+    case ACLK_TOP_HIGH:
+        if (rate == 500 * MHZ)
+        {
+            src_clk = ACLK_TOP_HIGH_SEL_500M;
+        }
+        else if (rate == 400 * MHZ)
+        {
+            src_clk = ACLK_TOP_HIGH_SEL_400M;
+        }
+        else if (rate == 300 * MHZ)
+        {
+            src_clk = ACLK_TOP_HIGH_SEL_300M;
+        }
+        else
+        {
+            src_clk = ACLK_TOP_HIGH_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[73], ACLK_TOP_HIGH_SEL_MASK, src_clk << ACLK_TOP_HIGH_SEL_SHIFT);
+        break;
+    case ACLK_TOP_LOW:
+        if (rate == 400 * MHZ)
+        {
+            src_clk = ACLK_TOP_LOW_SEL_400M;
+        }
+        else if (rate == 300 * MHZ)
+        {
+            src_clk = ACLK_TOP_LOW_SEL_300M;
+        }
+        else if (rate == 200 * MHZ)
+        {
+            src_clk = ACLK_TOP_LOW_SEL_200M;
+        }
+        else
+        {
+            src_clk = ACLK_TOP_LOW_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[73], ACLK_TOP_LOW_SEL_MASK, src_clk << ACLK_TOP_LOW_SEL_SHIFT);
+        break;
+    case HCLK_TOP:
+        if (rate == 150 * MHZ)
+        {
+            src_clk = HCLK_TOP_SEL_150M;
+        }
+        else if (rate == 100 * MHZ)
+        {
+            src_clk = HCLK_TOP_SEL_100M;
+        }
+        else if (rate == 75 * MHZ)
+        {
+            src_clk = HCLK_TOP_SEL_75M;
+        }
+        else
+        {
+            src_clk = HCLK_TOP_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[73], HCLK_TOP_SEL_MASK, src_clk << HCLK_TOP_SEL_SHIFT);
+        break;
+    case PCLK_TOP:
+        if (rate == 100 * MHZ)
+        {
+            src_clk = PCLK_TOP_SEL_100M;
+        }
+        else if (rate == 75 * MHZ)
+        {
+            src_clk = PCLK_TOP_SEL_75M;
+        }
+        else if (rate == 50 * MHZ)
+        {
+            src_clk = PCLK_TOP_SEL_50M;
+        }
+        else
+        {
+            src_clk = PCLK_TOP_SEL_24M;
+        }
+        rk_clrsetreg(&cru->clksel_con[73], PCLK_TOP_SEL_MASK, src_clk << PCLK_TOP_SEL_SHIFT);
+        break;
+
+    default:
+        return -RT_ENOSYS;
+    }
+
+    return top_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t i2c_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+    rt_ubase_t rate;
+
+    switch (clk_id)
+    {
+    case CLK_I2C1:
+    case CLK_I2C2:
+    case CLK_I2C3:
+    case CLK_I2C4:
+    case CLK_I2C5:
+        con = HWREG32(&cru->clksel_con[71]);
+        sel = (con & CLK_I2C_SEL_MASK) >> CLK_I2C_SEL_SHIFT;
+        if (sel == CLK_I2C_SEL_200M)
+        {
+            rate = 200 * MHZ;
+        }
+        else if (sel == CLK_I2C_SEL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else if (sel == CLK_I2C_SEL_CPLL_100M)
+        {
+            rate = 100 * MHZ;
+        }
+        else
+        {
+            rate = OSC_HZ;
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t i2c_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    if (rate == 200 * MHZ)
+    {
+        src_clk = CLK_I2C_SEL_200M;
+    }
+    else if (rate == 100 * MHZ)
+    {
+        src_clk = CLK_I2C_SEL_100M;
+    }
+    else
+    {
+        src_clk = CLK_I2C_SEL_24M;
+    }
+
+    switch (clk_id)
+    {
+    case CLK_I2C1:
+    case CLK_I2C2:
+    case CLK_I2C3:
+    case CLK_I2C4:
+    case CLK_I2C5:
+        rk_clrsetreg(&cru->clksel_con[71], CLK_I2C_SEL_MASK, src_clk << CLK_I2C_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return i2c_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t spi_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[72]);
+
+    switch (clk_id)
+    {
+    case CLK_SPI0:
+        sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
+        break;
+    case CLK_SPI1:
+        sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
+        break;
+    case CLK_SPI2:
+        sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
+        break;
+    case CLK_SPI3:
+        sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    switch (sel)
+    {
+    case CLK_SPI_SEL_200M:
+        return 200 * MHZ;
+    case CLK_SPI_SEL_24M:
+        return OSC_HZ;
+    case CLK_SPI_SEL_CPLL_100M:
+        return 100 * MHZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t spi_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    if (rate == 200 * MHZ)
+    {
+        src_clk = CLK_SPI_SEL_200M;
+    }
+    else if (rate == 100 * MHZ)
+    {
+        src_clk = CLK_SPI_SEL_CPLL_100M;
+    }
+    else
+    {
+        src_clk = CLK_SPI_SEL_24M;
+    }
+
+    switch (clk_id)
+    {
+    case CLK_SPI0:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_SPI0_SEL_MASK, src_clk << CLK_SPI0_SEL_SHIFT);
+        break;
+    case CLK_SPI1:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_SPI1_SEL_MASK, src_clk << CLK_SPI1_SEL_SHIFT);
+        break;
+    case CLK_SPI2:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_SPI2_SEL_MASK, src_clk << CLK_SPI2_SEL_SHIFT);
+        break;
+    case CLK_SPI3:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_SPI3_SEL_MASK, src_clk << CLK_SPI3_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return spi_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t pwm_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[72]);
+
+    switch (clk_id)
+    {
+    case CLK_PWM1:
+        sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
+        break;
+    case CLK_PWM2:
+        sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
+        break;
+    case CLK_PWM3:
+        sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    switch (sel)
+    {
+    case CLK_PWM_SEL_100M:
+        return 100 * MHZ;
+    case CLK_PWM_SEL_24M:
+        return OSC_HZ;
+    case CLK_PWM_SEL_CPLL_100M:
+        return 100 * MHZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t pwm_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    if (rate == 100 * MHZ)
+    {
+        src_clk = CLK_PWM_SEL_100M;
+    }
+    else
+    {
+        src_clk = CLK_PWM_SEL_24M;
+    }
+
+    switch (clk_id)
+    {
+    case CLK_PWM1:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_PWM1_SEL_MASK, src_clk << CLK_PWM1_SEL_SHIFT);
+        break;
+    case CLK_PWM2:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_PWM2_SEL_MASK, src_clk << CLK_PWM2_SEL_SHIFT);
+        break;
+    case CLK_PWM3:
+        rk_clrsetreg(&cru->clksel_con[72], CLK_PWM3_SEL_MASK, src_clk << CLK_PWM3_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return pwm_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t adc_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t div, sel, con, prate;
+
+    switch (clk_id)
+    {
+    case CLK_SARADC:
+        return OSC_HZ;
+    case CLK_TSADC_TSEN:
+        con = HWREG32(&cru->clksel_con[51]);
+        div = (con & CLK_TSADC_TSEN_DIV_MASK) >> CLK_TSADC_TSEN_DIV_SHIFT;
+        sel = (con & CLK_TSADC_TSEN_SEL_MASK) >> CLK_TSADC_TSEN_SEL_SHIFT;
+        if (sel == CLK_TSADC_TSEN_SEL_24M)
+        {
+            prate = OSC_HZ;
+        }
+        else
+        {
+            prate = 100 * MHZ;
+        }
+        return DIV_TO_RATE(prate, div);
+    case CLK_TSADC:
+        con = HWREG32(&cru->clksel_con[51]);
+        div = (con & CLK_TSADC_DIV_MASK) >> CLK_TSADC_DIV_SHIFT;
+        prate = adc_get_clk(priv, CLK_TSADC_TSEN);
+        return DIV_TO_RATE(prate, div);
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t adc_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk_div;
+    rt_ubase_t prate = 0;
+
+    switch (clk_id)
+    {
+    case CLK_SARADC:
+        return OSC_HZ;
+    case CLK_TSADC_TSEN:
+        if (!(OSC_HZ % rate))
+        {
+            src_clk_div = RT_DIV_ROUND_UP(OSC_HZ, rate);
+            RT_ASSERT(src_clk_div - 1 <= 7);
+            rk_clrsetreg(&cru->clksel_con[51], CLK_TSADC_TSEN_SEL_MASK | CLK_TSADC_TSEN_DIV_MASK,
+                    (CLK_TSADC_TSEN_SEL_24M << CLK_TSADC_TSEN_SEL_SHIFT) |
+                    (src_clk_div - 1) << CLK_TSADC_TSEN_DIV_SHIFT);
+        }
+        else
+        {
+            src_clk_div = RT_DIV_ROUND_UP(100 * MHZ, rate);
+            RT_ASSERT(src_clk_div - 1 <= 7);
+            rk_clrsetreg(&cru->clksel_con[51], CLK_TSADC_TSEN_SEL_MASK | CLK_TSADC_TSEN_DIV_MASK,
+                    (CLK_TSADC_TSEN_SEL_100M << CLK_TSADC_TSEN_SEL_SHIFT) |
+                    (src_clk_div - 1) << CLK_TSADC_TSEN_DIV_SHIFT);
+        }
+        break;
+    case CLK_TSADC:
+            prate = adc_get_clk(priv, CLK_TSADC_TSEN);
+            src_clk_div = RT_DIV_ROUND_UP(prate, rate);
+            RT_ASSERT(src_clk_div - 1 <= 128);
+            rk_clrsetreg(&cru->clksel_con[51], CLK_TSADC_DIV_MASK, (src_clk_div - 1) << CLK_TSADC_DIV_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+    return adc_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t crypto_get_rate(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    switch (clk_id)
+    {
+    case ACLK_SECURE_FLASH:
+    case ACLK_CRYPTO_NS:
+        con = HWREG32(&cru->clksel_con[27]);
+        sel = (con & ACLK_SECURE_FLASH_SEL_MASK) >> ACLK_SECURE_FLASH_SEL_SHIFT;
+        if (sel == ACLK_SECURE_FLASH_SEL_200M)
+        {
+            return 200 * MHZ;
+        }
+        else if (sel == ACLK_SECURE_FLASH_SEL_150M)
+        {
+            return 150 * MHZ;
+        }
+        else if (sel == ACLK_SECURE_FLASH_SEL_100M)
+        {
+            return 100 * MHZ;
+        }
+        else
+        {
+            return 24 * MHZ;
+        }
+    case HCLK_SECURE_FLASH:
+    case HCLK_CRYPTO_NS:
+    case CLK_CRYPTO_NS_RNG:
+        con = HWREG32(&cru->clksel_con[27]);
+        sel = (con & HCLK_SECURE_FLASH_SEL_MASK) >> HCLK_SECURE_FLASH_SEL_SHIFT;
+        if (sel == HCLK_SECURE_FLASH_SEL_150M)
+        {
+            return 150 * MHZ;
+        }
+        else if (sel == HCLK_SECURE_FLASH_SEL_100M)
+        {
+            return 100 * MHZ;
+        }
+        else if (sel == HCLK_SECURE_FLASH_SEL_75M)
+        {
+            return 75 * MHZ;
+        }
+        else
+        {
+            return 24 * MHZ;
+        }
+    case CLK_CRYPTO_NS_CORE:
+        con = HWREG32(&cru->clksel_con[27]);
+        sel = (con & CLK_CRYPTO_CORE_SEL_MASK) >> CLK_CRYPTO_CORE_SEL_SHIFT;
+        if (sel == CLK_CRYPTO_CORE_SEL_200M)
+        {
+            return 200 * MHZ;
+        }
+        else if (sel == CLK_CRYPTO_CORE_SEL_150M)
+        {
+            return 150 * MHZ;
+        }
+        else
+        {
+            return 100 * MHZ;
+        }
+    case CLK_CRYPTO_NS_PKA:
+        con = HWREG32(&cru->clksel_con[27]);
+        sel = (con & CLK_CRYPTO_PKA_SEL_MASK) >> CLK_CRYPTO_PKA_SEL_SHIFT;
+        if (sel == CLK_CRYPTO_PKA_SEL_300M)
+        {
+            return 300 * MHZ;
+        }
+        else if (sel == CLK_CRYPTO_PKA_SEL_200M)
+        {
+            return 200 * MHZ;
+        }
+        else
+        {
+            return 100 * MHZ;
+        }
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t crypto_set_rate(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t src_clk, mask, shift;
+
+    switch (clk_id)
+    {
+    case ACLK_SECURE_FLASH:
+    case ACLK_CRYPTO_NS:
+        mask = ACLK_SECURE_FLASH_SEL_MASK;
+        shift = ACLK_SECURE_FLASH_SEL_SHIFT;
+        if (rate == 200 * MHZ)
+        {
+            src_clk = ACLK_SECURE_FLASH_SEL_200M;
+        }
+        else if (rate == 150 * MHZ)
+        {
+            src_clk = ACLK_SECURE_FLASH_SEL_150M;
+        }
+        else if (rate == 100 * MHZ)
+        {
+            src_clk = ACLK_SECURE_FLASH_SEL_100M;
+        }
+        else
+        {
+            src_clk = ACLK_SECURE_FLASH_SEL_24M;
+        }
+        break;
+    case HCLK_SECURE_FLASH:
+    case HCLK_CRYPTO_NS:
+    case CLK_CRYPTO_NS_RNG:
+        mask = HCLK_SECURE_FLASH_SEL_MASK;
+        shift = HCLK_SECURE_FLASH_SEL_SHIFT;
+        if (rate == 150 * MHZ)
+        {
+            src_clk = HCLK_SECURE_FLASH_SEL_150M;
+        }
+        else if (rate == 100 * MHZ)
+        {
+            src_clk = HCLK_SECURE_FLASH_SEL_100M;
+        }
+        else if (rate == 75 * MHZ)
+        {
+            src_clk = HCLK_SECURE_FLASH_SEL_75M;
+        }
+        else
+        {
+            src_clk = HCLK_SECURE_FLASH_SEL_24M;
+        }
+        break;
+    case CLK_CRYPTO_NS_CORE:
+        mask = CLK_CRYPTO_CORE_SEL_MASK;
+        shift = CLK_CRYPTO_CORE_SEL_SHIFT;
+        if (rate == 200 * MHZ)
+        {
+            src_clk = CLK_CRYPTO_CORE_SEL_200M;
+        }
+        else if (rate == 150 * MHZ)
+        {
+            src_clk = CLK_CRYPTO_CORE_SEL_150M;
+        }
+        else
+        {
+            src_clk = CLK_CRYPTO_CORE_SEL_100M;
+        }
+        break;
+    case CLK_CRYPTO_NS_PKA:
+        mask = CLK_CRYPTO_PKA_SEL_MASK;
+        shift = CLK_CRYPTO_PKA_SEL_SHIFT;
+        if (rate == 300 * MHZ)
+        {
+            src_clk = CLK_CRYPTO_PKA_SEL_300M;
+        }
+        else if (rate == 200 * MHZ)
+        {
+            src_clk = CLK_CRYPTO_PKA_SEL_200M;
+        }
+        else
+        {
+            src_clk = CLK_CRYPTO_PKA_SEL_100M;
+        }
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[27], mask, src_clk << shift);
+
+    return crypto_get_rate(priv, clk_id);
+}
+
+static rt_ubase_t sdmmc_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    switch (clk_id)
+    {
+    case HCLK_SDMMC0:
+    case CLK_SDMMC0:
+        con = HWREG32(&cru->clksel_con[30]);
+        sel = (con & CLK_SDMMC0_SEL_MASK) >> CLK_SDMMC0_SEL_SHIFT;
+        break;
+    case CLK_SDMMC1:
+        con = HWREG32(&cru->clksel_con[30]);
+        sel = (con & CLK_SDMMC1_SEL_MASK) >> CLK_SDMMC1_SEL_SHIFT;
+        break;
+    case CLK_SDMMC2:
+        con = HWREG32(&cru->clksel_con[32]);
+        sel = (con & CLK_SDMMC2_SEL_MASK) >> CLK_SDMMC2_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    switch (sel)
+    {
+    case CLK_SDMMC_SEL_24M:
+        return OSC_HZ;
+    case CLK_SDMMC_SEL_400M:
+        return 400 * MHZ;
+    case CLK_SDMMC_SEL_300M:
+        return 300 * MHZ;
+    case CLK_SDMMC_SEL_100M:
+        return 100 * MHZ;
+    case CLK_SDMMC_SEL_50M:
+        return 50 * MHZ;
+    case CLK_SDMMC_SEL_750K:
+        return 750 * KHZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t sdmmc_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case OSC_HZ:
+        src_clk = CLK_SDMMC_SEL_24M;
+        break;
+    case 400 * MHZ:
+        src_clk = CLK_SDMMC_SEL_400M;
+        break;
+    case 300 * MHZ:
+        src_clk = CLK_SDMMC_SEL_300M;
+        break;
+    case 100 * MHZ:
+        src_clk = CLK_SDMMC_SEL_100M;
+        break;
+    case 52 * MHZ:
+    case 50 * MHZ:
+        src_clk = CLK_SDMMC_SEL_50M;
+        break;
+    case 750 * KHZ:
+    case 400 * KHZ:
+        src_clk = CLK_SDMMC_SEL_750K;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    switch (clk_id)
+    {
+    case HCLK_SDMMC0:
+    case CLK_SDMMC0:
+        rk_clrsetreg(&cru->clksel_con[30], CLK_SDMMC0_SEL_MASK, src_clk << CLK_SDMMC0_SEL_SHIFT);
+        break;
+    case CLK_SDMMC1:
+        rk_clrsetreg(&cru->clksel_con[30], CLK_SDMMC1_SEL_MASK, src_clk << CLK_SDMMC1_SEL_SHIFT);
+        break;
+    case CLK_SDMMC2:
+        rk_clrsetreg(&cru->clksel_con[32], CLK_SDMMC2_SEL_MASK, src_clk << CLK_SDMMC2_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return sdmmc_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t sfc_get_clk(struct rk_clk_priv *priv)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[28]);
+    sel = (con & SCLK_SFC_SEL_MASK) >> SCLK_SFC_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case SCLK_SFC_SEL_24M:
+        return OSC_HZ;
+    case SCLK_SFC_SEL_50M:
+        return 50 * MHZ;
+    case SCLK_SFC_SEL_75M:
+        return 75 * MHZ;
+    case SCLK_SFC_SEL_100M:
+        return 100 * MHZ;
+    case SCLK_SFC_SEL_125M:
+        return 125 * MHZ;
+    case SCLK_SFC_SEL_150M:
+        return 150 * KHZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t sfc_set_clk(struct rk_clk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case OSC_HZ:
+        src_clk = SCLK_SFC_SEL_24M;
+        break;
+    case 50 * MHZ:
+        src_clk = SCLK_SFC_SEL_50M;
+        break;
+    case 75 * MHZ:
+        src_clk = SCLK_SFC_SEL_75M;
+        break;
+    case 100 * MHZ:
+        src_clk = SCLK_SFC_SEL_100M;
+        break;
+    case 125 * MHZ:
+        src_clk = SCLK_SFC_SEL_125M;
+        break;
+    case 150 * KHZ:
+        src_clk = SCLK_SFC_SEL_150M;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[28], SCLK_SFC_SEL_MASK, src_clk << SCLK_SFC_SEL_SHIFT);
+
+    return sfc_get_clk(priv);
+}
+
+static rt_ubase_t nand_get_clk(struct rk_clk_priv *priv)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[28]);
+    sel = (con & NCLK_NANDC_SEL_MASK) >> NCLK_NANDC_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case NCLK_NANDC_SEL_200M:
+        return 200 * MHZ;
+    case NCLK_NANDC_SEL_150M:
+        return 150 * MHZ;
+    case NCLK_NANDC_SEL_100M:
+        return 100 * MHZ;
+    case NCLK_NANDC_SEL_24M:
+        return OSC_HZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t nand_set_clk(struct rk_clk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case OSC_HZ:
+        src_clk = NCLK_NANDC_SEL_24M;
+        break;
+    case 100 * MHZ:
+        src_clk = NCLK_NANDC_SEL_100M;
+        break;
+    case 150 * MHZ:
+        src_clk = NCLK_NANDC_SEL_150M;
+        break;
+    case 200 * MHZ:
+        src_clk = NCLK_NANDC_SEL_200M;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[28], NCLK_NANDC_SEL_MASK, src_clk << NCLK_NANDC_SEL_SHIFT);
+
+    return nand_get_clk(priv);
+}
+
+static rt_ubase_t emmc_get_clk(struct rk_clk_priv *priv)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[28]);
+    sel = (con & CCLK_EMMC_SEL_MASK) >> CCLK_EMMC_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case CCLK_EMMC_SEL_200M:
+        return 200 * MHZ;
+    case CCLK_EMMC_SEL_150M:
+        return 150 * MHZ;
+    case CCLK_EMMC_SEL_100M:
+        return 100 * MHZ;
+    case CCLK_EMMC_SEL_50M:
+        return 50 * MHZ;
+    case CCLK_EMMC_SEL_375K:
+        return 375 * KHZ;
+    case CCLK_EMMC_SEL_24M:
+        return OSC_HZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t emmc_set_clk(struct rk_clk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case OSC_HZ:
+        src_clk = CCLK_EMMC_SEL_24M;
+        break;
+    case 52 * MHZ:
+    case 50 * MHZ:
+        src_clk = CCLK_EMMC_SEL_50M;
+        break;
+    case 100 * MHZ:
+        src_clk = CCLK_EMMC_SEL_100M;
+        break;
+    case 150 * MHZ:
+        src_clk = CCLK_EMMC_SEL_150M;
+        break;
+    case 200 * MHZ:
+        src_clk = CCLK_EMMC_SEL_200M;
+        break;
+    case 400 * KHZ:
+    case 375 * KHZ:
+        src_clk = CCLK_EMMC_SEL_375K;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[28], CCLK_EMMC_SEL_MASK, src_clk << CCLK_EMMC_SEL_SHIFT);
+
+    return emmc_get_clk(priv);
+}
+
+static rt_ubase_t emmc_get_bclk(struct rk_clk_priv *priv)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[28]);
+    sel = (con & BCLK_EMMC_SEL_MASK) >> BCLK_EMMC_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case BCLK_EMMC_SEL_200M:
+        return 200 * MHZ;
+    case BCLK_EMMC_SEL_150M:
+        return 150 * MHZ;
+    case BCLK_EMMC_SEL_125M:
+        return 125 * MHZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t emmc_set_bclk(struct rk_clk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case 200 * MHZ:
+        src_clk = BCLK_EMMC_SEL_200M;
+        break;
+    case 150 * MHZ:
+        src_clk = BCLK_EMMC_SEL_150M;
+        break;
+    case 125 * MHZ:
+        src_clk = BCLK_EMMC_SEL_125M;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[28], BCLK_EMMC_SEL_MASK, src_clk << BCLK_EMMC_SEL_SHIFT);
+
+    return emmc_get_bclk(priv);
+}
+
+static rt_ubase_t aclk_vop_get_clk(struct rk_clk_priv *priv)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t div, sel, con, parent;
+
+    con = HWREG32(&cru->clksel_con[38]);
+    div = (con & ACLK_VOP_PRE_DIV_MASK) >> ACLK_VOP_PRE_DIV_SHIFT;
+    sel = (con & ACLK_VOP_PRE_SEL_MASK) >> ACLK_VOP_PRE_SEL_SHIFT;
+
+    if (sel == ACLK_VOP_PRE_SEL_GPLL)
+    {
+        parent = priv->gpll_hz;
+    }
+    else if (sel == ACLK_VOP_PRE_SEL_CPLL)
+    {
+        parent = priv->cpll_hz;
+    }
+    else if (sel == ACLK_VOP_PRE_SEL_VPLL)
+    {
+        parent = priv->vpll_hz;
+    }
+    else
+    {
+        parent = priv->hpll_hz;
+    }
+
+    return DIV_TO_RATE(parent, div);
+}
+
+static rt_ubase_t aclk_vop_set_clk(struct rk_clk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk_div, src_clk_mux;
+
+    if ((priv->cpll_hz % rate) == 0)
+    {
+        src_clk_div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+        src_clk_mux = ACLK_VOP_PRE_SEL_CPLL;
+    }
+    else
+    {
+        src_clk_div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        src_clk_mux = ACLK_VOP_PRE_SEL_GPLL;
+    }
+
+    RT_ASSERT(src_clk_div - 1 <= 31);
+    rk_clrsetreg(&cru->clksel_con[38], ACLK_VOP_PRE_SEL_MASK | ACLK_VOP_PRE_DIV_MASK,
+            src_clk_mux << ACLK_VOP_PRE_SEL_SHIFT | (src_clk_div - 1) << ACLK_VOP_PRE_DIV_SHIFT);
+
+    return aclk_vop_get_clk(priv);
+}
+
+static rt_ubase_t dclk_vop_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t conid, div, sel, con, parent;
+
+    switch (clk_id)
+    {
+    case DCLK_VOP0:
+        conid = 39;
+        break;
+    case DCLK_VOP1:
+        conid = 40;
+        break;
+    case DCLK_VOP2:
+        conid = 41;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    con = HWREG32(&cru->clksel_con[conid]);
+    div = (con & DCLK0_VOP_DIV_MASK) >> DCLK0_VOP_DIV_SHIFT;
+    sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
+
+    if (sel == DCLK_VOP_SEL_HPLL)
+    {
+        parent = pmu_pll_get_rate(hpll);
+    }
+    else if (sel == DCLK_VOP_SEL_VPLL)
+    {
+        parent = rk_pll_get_rate(&pll_clks[vpll], &priv->cru);
+    }
+    else if (sel == DCLK_VOP_SEL_GPLL)
+    {
+        parent = priv->gpll_hz;
+    }
+    else if (sel == DCLK_VOP_SEL_CPLL)
+    {
+        parent = priv->cpll_hz;
+    }
+    else
+    {
+        return -RT_ERROR;
+    }
+
+    return DIV_TO_RATE(parent, div);
+}
+
+#define VOP_PLL_LIMIT_FREQ 600000000
+
+static rt_ubase_t dclk_vop_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_ubase_t pll_rate, now, best_rate = 0;
+    rt_uint32_t i, conid, con, sel, div, best_div = 0, best_sel = 0;
+
+    switch (clk_id)
+    {
+    case DCLK_VOP0:
+        conid = 39;
+        break;
+    case DCLK_VOP1:
+        conid = 40;
+        break;
+    case DCLK_VOP2:
+        conid = 41;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    con = HWREG32(&cru->clksel_con[conid]);
+    sel = (con & DCLK0_VOP_SEL_MASK) >> DCLK0_VOP_SEL_SHIFT;
+
+    if (sel == DCLK_VOP_SEL_HPLL)
+    {
+        div = 1;
+        rk_clrsetreg(&cru->clksel_con[conid], DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
+                (DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT) | ((div - 1) << DCLK0_VOP_DIV_SHIFT));
+        pmu_pll_set_rate(hpll, div * rate);
+    }
+    else if (sel == DCLK_VOP_SEL_VPLL)
+    {
+        div = RT_DIV_ROUND_UP(VOP_PLL_LIMIT_FREQ, rate);
+        rk_clrsetreg(&cru->clksel_con[conid], DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
+                (DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT) | ((div - 1) << DCLK0_VOP_DIV_SHIFT));
+        rk_pll_set_rate(&pll_clks[vpll], priv->cru, div * rate);
+    }
+    else
+    {
+        for (i = 0; i <= DCLK_VOP_SEL_CPLL; i++)
+        {
+            switch (i)
+            {
+            case DCLK_VOP_SEL_GPLL:
+                pll_rate = priv->gpll_hz;
+                break;
+            case DCLK_VOP_SEL_CPLL:
+                pll_rate = priv->cpll_hz;
+                break;
+            default:
+                return -RT_ENOSYS;
+            }
+
+            div = RT_DIV_ROUND_UP(pll_rate, rate);
+
+            if (div > 255)
+            {
+                continue;
+            }
+
+            now = pll_rate / div;
+
+            if (rt_abs(rate - now) < rt_abs(rate - best_rate))
+            {
+                best_rate = now;
+                best_div = div;
+                best_sel = i;
+            }
+        }
+
+        if (best_rate)
+        {
+            rk_clrsetreg(&cru->clksel_con[conid], DCLK0_VOP_DIV_MASK | DCLK0_VOP_SEL_MASK,
+                    best_sel << DCLK0_VOP_SEL_SHIFT | (best_div - 1) << DCLK0_VOP_DIV_SHIFT);
+        }
+        else
+        {
+            return -RT_ENOSYS;
+        }
+    }
+    return dclk_vop_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t gmac_src_get_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[31 + mac_id * 2]);
+    sel = (con & CLK_MAC0_2TOP_SEL_MASK) >> CLK_MAC0_2TOP_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case CLK_MAC0_2TOP_SEL_125M:
+        return 125 * MHZ;
+    case CLK_MAC0_2TOP_SEL_50M:
+        return 50 * MHZ;
+    case CLK_MAC0_2TOP_SEL_25M:
+        return 25 * MHZ;
+    case CLK_MAC0_2TOP_SEL_PPLL:
+        return pmu_pll_get_rate(hpll);
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t gmac_src_set_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case 125 * MHZ:
+        src_clk = CLK_MAC0_2TOP_SEL_125M;
+        break;
+    case 50 * MHZ:
+        src_clk = CLK_MAC0_2TOP_SEL_50M;
+        break;
+    case 25 * MHZ:
+        src_clk = CLK_MAC0_2TOP_SEL_25M;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], CLK_MAC0_2TOP_SEL_MASK, src_clk << CLK_MAC0_2TOP_SEL_SHIFT);
+
+    return gmac_src_get_clk(priv, mac_id);
+}
+
+static rt_ubase_t gmac_out_get_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[31 + mac_id * 2]);
+    sel = (con & CLK_MAC0_OUT_SEL_MASK) >> CLK_MAC0_OUT_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case CLK_MAC0_OUT_SEL_125M:
+        return 125 * MHZ;
+    case CLK_MAC0_OUT_SEL_50M:
+        return 50 * MHZ;
+    case CLK_MAC0_OUT_SEL_25M:
+        return 25 * MHZ;
+    case CLK_MAC0_OUT_SEL_24M:
+        return OSC_HZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t gmac_out_set_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case 125 * MHZ:
+        src_clk = CLK_MAC0_OUT_SEL_125M;
+        break;
+    case 50 * MHZ:
+        src_clk = CLK_MAC0_OUT_SEL_50M;
+        break;
+    case 25 * MHZ:
+        src_clk = CLK_MAC0_OUT_SEL_25M;
+        break;
+    case 24 * MHZ:
+        src_clk = CLK_MAC0_OUT_SEL_24M;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], CLK_MAC0_OUT_SEL_MASK, src_clk << CLK_MAC0_OUT_SEL_SHIFT);
+
+    return gmac_out_get_clk(priv, mac_id);
+}
+
+static rt_ubase_t gmac_ptp_ref_get_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[31 + mac_id * 2]);
+    sel = (con & CLK_GMAC0_PTP_REF_SEL_MASK) >> CLK_GMAC0_PTP_REF_SEL_SHIFT;
+
+    switch (sel)
+    {
+    case CLK_GMAC0_PTP_REF_SEL_62_5M:
+        return 62500 * KHZ;
+    case CLK_GMAC0_PTP_REF_SEL_100M:
+        return 100 * MHZ;
+    case CLK_GMAC0_PTP_REF_SEL_50M:
+        return 50 * MHZ;
+    case CLK_GMAC0_PTP_REF_SEL_24M:
+        return OSC_HZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t gmac_ptp_ref_set_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (rate)
+    {
+    case 62500 * KHZ:
+        src_clk = CLK_GMAC0_PTP_REF_SEL_62_5M;
+        break;
+    case 100 * MHZ:
+        src_clk = CLK_GMAC0_PTP_REF_SEL_100M;
+        break;
+    case 50 * MHZ:
+        src_clk = CLK_GMAC0_PTP_REF_SEL_50M;
+        break;
+    case 24 * MHZ:
+        src_clk = CLK_GMAC0_PTP_REF_SEL_24M;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], CLK_GMAC0_PTP_REF_SEL_MASK, src_clk << CLK_GMAC0_PTP_REF_SEL_SHIFT);
+
+    return gmac_ptp_ref_get_clk(priv, mac_id);
+}
+
+static rt_ubase_t gmac_tx_rx_set_clk(struct rk_clk_priv *priv, rt_ubase_t mac_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con, sel, div_sel;
+
+    con = HWREG32(&cru->clksel_con[31 + mac_id * 2]);
+    sel = (con & RMII0_MODE_MASK) >> RMII0_MODE_SHIFT;
+
+    if (sel == RMII0_MODE_SEL_RGMII)
+    {
+        if (rate == 2500000)
+        {
+            div_sel = RGMII0_CLK_SEL_2_5M;
+        }
+        else if (rate == 25000000)
+        {
+            div_sel = RGMII0_CLK_SEL_25M;
+        }
+        else
+        {
+            div_sel = RGMII0_CLK_SEL_125M;
+        }
+        rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], RGMII0_CLK_SEL_MASK, div_sel << RGMII0_CLK_SEL_SHIFT);
+    }
+    else if (sel == RMII0_MODE_SEL_RMII)
+    {
+        if (rate == 2500000)
+        {
+            div_sel = RMII0_CLK_SEL_2_5M;
+        }
+        else
+        {
+            div_sel = RMII0_CLK_SEL_25M;
+        }
+        rk_clrsetreg(&cru->clksel_con[31 + mac_id * 2], RMII0_CLK_SEL_MASK, div_sel << RMII0_CLK_SEL_SHIFT);
+    }
+
+    return 0;
+}
+
+static rt_ubase_t ebc_get_clk(struct rk_clk_priv *priv)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con, div, p_rate;
+
+    con = HWREG32(&cru->clksel_con[79]);
+    div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT;
+    p_rate = DIV_TO_RATE(priv->cpll_hz, div);
+
+    con = HWREG32(&cru->clksel_con[43]);
+    div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT;
+
+    switch (div)
+    {
+    case DCLK_EBC_SEL_GPLL_400M:
+        return 400 * MHZ;
+    case DCLK_EBC_SEL_CPLL_333M:
+        return p_rate;
+    case DCLK_EBC_SEL_GPLL_200M:
+        return 200 * MHZ;
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t ebc_set_clk(struct rk_clk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk_div;
+
+    src_clk_div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+    RT_ASSERT(src_clk_div - 1 <= 31);
+    rk_clrsetreg(&cru->clksel_con[79], CPLL_333M_DIV_MASK, (src_clk_div - 1) << CPLL_333M_DIV_SHIFT);
+    rk_clrsetreg(&cru->clksel_con[43], DCLK_EBC_SEL_MASK, DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT);
+
+    return ebc_get_clk(priv);
+}
+
+static rt_ubase_t rkvdec_get_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con, div, src, p_rate;
+
+    switch (clk_id)
+    {
+    case ACLK_RKVDEC_PRE:
+    case ACLK_RKVDEC:
+        con = HWREG32(&cru->clksel_con[47]);
+        src = (con & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
+        div = (con & ACLK_RKVDEC_DIV_MASK) >> ACLK_RKVDEC_DIV_SHIFT;
+
+        if (src == ACLK_RKVDEC_SEL_CPLL)
+        {
+            p_rate = priv->cpll_hz;
+        }
+        else
+        {
+            p_rate = priv->gpll_hz;
+        }
+        return DIV_TO_RATE(p_rate, div);
+    case CLK_RKVDEC_CORE:
+        con = HWREG32(&cru->clksel_con[49]);
+        src = (con & CLK_RKVDEC_CORE_SEL_MASK) >> CLK_RKVDEC_CORE_SEL_SHIFT;
+        div = (con & CLK_RKVDEC_CORE_DIV_MASK) >> CLK_RKVDEC_CORE_DIV_SHIFT;
+
+        if (src == CLK_RKVDEC_CORE_SEL_CPLL)
+        {
+            p_rate = priv->cpll_hz;
+        }
+        else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
+        {
+            p_rate = priv->npll_hz;
+        }
+        else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
+        {
+            p_rate = priv->vpll_hz;
+        }
+        else
+        {
+            p_rate = priv->gpll_hz;
+        }
+        return DIV_TO_RATE(p_rate, div);
+    default:
+        return -RT_ERROR;
+    }
+}
+
+static rt_ubase_t rkvdec_set_clk(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    int src_clk_div, src, p_rate;
+
+    switch (clk_id)
+    {
+    case ACLK_RKVDEC_PRE:
+    case ACLK_RKVDEC:
+        src = (HWREG32(&cru->clksel_con[47]) & ACLK_RKVDEC_SEL_MASK) >> ACLK_RKVDEC_SEL_SHIFT;
+        if (src == ACLK_RKVDEC_SEL_CPLL)
+        {
+            p_rate = priv->cpll_hz;
+        }
+        else
+        {
+            p_rate = priv->gpll_hz;
+        }
+        src_clk_div = RT_DIV_ROUND_UP(p_rate, rate);
+        RT_ASSERT(src_clk_div - 1 <= 31);
+        rk_clrsetreg(&cru->clksel_con[47], ACLK_RKVDEC_SEL_MASK | ACLK_RKVDEC_DIV_MASK,
+                (src << ACLK_RKVDEC_SEL_SHIFT) | (src_clk_div - 1) << ACLK_RKVDEC_DIV_SHIFT);
+        break;
+    case CLK_RKVDEC_CORE:
+        src = (HWREG32(&cru->clksel_con[49]) & CLK_RKVDEC_CORE_SEL_MASK) >> CLK_RKVDEC_CORE_SEL_SHIFT;
+        if (src == CLK_RKVDEC_CORE_SEL_CPLL)
+        {
+            p_rate = priv->cpll_hz;
+        }
+        else if (src == CLK_RKVDEC_CORE_SEL_NPLL)
+        {
+            p_rate = priv->npll_hz;
+        }
+        else if (src == CLK_RKVDEC_CORE_SEL_VPLL)
+        {
+            p_rate = priv->vpll_hz;
+        }
+        else
+        {
+            p_rate = priv->gpll_hz;
+        }
+        src_clk_div = RT_DIV_ROUND_UP(p_rate, rate);
+        RT_ASSERT(src_clk_div - 1 <= 31);
+        rk_clrsetreg(&cru->clksel_con[49], CLK_RKVDEC_CORE_SEL_MASK | CLK_RKVDEC_CORE_DIV_MASK,
+                (src << CLK_RKVDEC_CORE_SEL_SHIFT) | (src_clk_div - 1) << CLK_RKVDEC_CORE_DIV_SHIFT);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rkvdec_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t uart_get_rate(struct rk_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t reg, con, fracdiv, div, src, p_src, p_rate;
+    rt_ubase_t m, n;
+
+    switch (clk_id)
+    {
+    case SCLK_UART1:
+        reg = 52;
+        break;
+    case SCLK_UART2:
+        reg = 54;
+        break;
+    case SCLK_UART3:
+        reg = 56;
+        break;
+    case SCLK_UART4:
+        reg = 58;
+        break;
+    case SCLK_UART5:
+        reg = 60;
+        break;
+    case SCLK_UART6:
+        reg = 62;
+        break;
+    case SCLK_UART7:
+        reg = 64;
+        break;
+    case SCLK_UART8:
+        reg = 66;
+        break;
+    case SCLK_UART9:
+        reg = 68;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    con = HWREG32(&cru->clksel_con[reg]);
+    src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
+    div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
+    p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
+
+    if (p_src == CLK_UART_SRC_SEL_GPLL)
+    {
+        p_rate = priv->gpll_hz;
+    }
+    else if (p_src == CLK_UART_SRC_SEL_CPLL)
+    {
+        p_rate = priv->cpll_hz;
+    }
+    else
+    {
+        p_rate = 480000000;
+    }
+    if (src == CLK_UART_SEL_SRC)
+    {
+        return DIV_TO_RATE(p_rate, div);
+    }
+    else if (src == CLK_UART_SEL_FRAC)
+    {
+        fracdiv = HWREG32(&cru->clksel_con[reg + 1]);
+        n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
+        n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
+        m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
+        m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
+        return DIV_TO_RATE(p_rate, div) * n / m;
+    }
+    else
+    {
+        return OSC_HZ;
+    }
+}
+
+static rt_ubase_t uart_set_rate(struct rk_clk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t reg, clk_src, uart_src, div;
+    rt_ubase_t m = 0, n = 0, val;
+
+    if (priv->gpll_hz % rate == 0)
+    {
+        clk_src = CLK_UART_SRC_SEL_GPLL;
+        uart_src = CLK_UART_SEL_SRC;
+        div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+    }
+    else if (priv->cpll_hz % rate == 0)
+    {
+        clk_src = CLK_UART_SRC_SEL_CPLL;
+        uart_src = CLK_UART_SEL_SRC;
+        div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+    }
+    else if (rate == OSC_HZ)
+    {
+        clk_src = CLK_UART_SRC_SEL_GPLL;
+        uart_src = CLK_UART_SEL_XIN24M;
+        div = 2;
+    }
+    else
+    {
+        clk_src = CLK_UART_SRC_SEL_GPLL;
+        uart_src = CLK_UART_SEL_FRAC;
+        div = 2;
+        rational_best_approximation(rate, priv->gpll_hz / div, RT_GENMASK(16 - 1, 0), RT_GENMASK(16 - 1, 0), &m, &n);
+    }
+
+    switch (clk_id)
+    {
+    case SCLK_UART1:
+        reg = 52;
+        break;
+    case SCLK_UART2:
+        reg = 54;
+        break;
+    case SCLK_UART3:
+        reg = 56;
+        break;
+    case SCLK_UART4:
+        reg = 58;
+        break;
+    case SCLK_UART5:
+        reg = 60;
+        break;
+    case SCLK_UART6:
+        reg = 62;
+        break;
+    case SCLK_UART7:
+        reg = 64;
+        break;
+    case SCLK_UART8:
+        reg = 66;
+        break;
+    case SCLK_UART9:
+        reg = 68;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+    rk_clrsetreg(&cru->clksel_con[reg], CLK_UART_SEL_MASK | CLK_UART_SRC_SEL_MASK | CLK_UART_SRC_DIV_MASK,
+            (clk_src << CLK_UART_SRC_SEL_SHIFT) | (uart_src << CLK_UART_SEL_SHIFT) |
+            ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
+    if (m && n)
+    {
+        val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
+        HWREG32(&cru->clksel_con[reg + 1]) = val;
+    }
+
+    return uart_get_rate(priv, clk_id);
+}
+
+static rt_ubase_t pmu_get_pmuclk(struct rk_pmuclk_priv *priv)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    rt_uint32_t div, con, sel, parent;
+
+    con = HWREG32(&pmucru->pmu_clksel_con[2]);
+    sel = (con & PCLK_PDPMU_SEL_MASK) >> PCLK_PDPMU_SEL_SHIFT;
+    div = (con & PCLK_PDPMU_DIV_MASK) >> PCLK_PDPMU_DIV_SHIFT;
+
+    if (sel)
+    {
+        parent = GPLL_HZ;
+    }
+    else
+    {
+        parent = priv->ppll_hz;
+    }
+
+    return DIV_TO_RATE(parent, div);
+}
+
+static rt_ubase_t pmu_set_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t rate)
+{
+    struct rk_pmucru *pmucru = priv->pmucru;
+    int src_clk_div;
+
+    src_clk_div = RT_DIV_ROUND_UP(priv->ppll_hz, rate);
+    RT_ASSERT(src_clk_div - 1 <= 31);
+
+    rk_clrsetreg(&pmucru->pmu_clksel_con[2], PCLK_PDPMU_DIV_MASK | PCLK_PDPMU_SEL_MASK,
+            (PCLK_PDPMU_SEL_PPLL << PCLK_PDPMU_SEL_SHIFT) | ((src_clk_div - 1) << PCLK_PDPMU_DIV_SHIFT));
+
+    return pmu_get_pmuclk(priv);
+}
+
+static rt_ubase_t pciephy_ref_get_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id)
+{
+    rt_uint32_t con, div, src;
+    struct rk_pmucru *pmucru = priv->pmucru;
+
+    switch (clk_id)
+    {
+    case CLK_PCIEPHY0_REF:
+        con = HWREG32(&pmucru->pmu_clksel_con[9]);
+        src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
+        con = HWREG32(&pmucru->pmu_clksel_con[9]);
+        div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
+        break;
+    case CLK_PCIEPHY1_REF:
+        con = HWREG32(&pmucru->pmu_clksel_con[9]);
+        src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
+        con = HWREG32(&pmucru->pmu_clksel_con[9]);
+        div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
+        break;
+    case CLK_PCIEPHY2_REF:
+        con = HWREG32(&pmucru->pmu_clksel_con[9]);
+        src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
+        con = HWREG32(&pmucru->pmu_clksel_con[9]);
+        div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
+        break;
+    }
+
+    if (src == CLK_PCIE_PHY_REF_SEL_PPLL)
+    {
+        return DIV_TO_RATE(priv->ppll_hz, div);
+    }
+    else
+    {
+        return OSC_HZ;
+    }
+}
+
+static rt_ubase_t pciephy_ref_set_pmuclk(struct rk_pmuclk_priv *priv, rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    rt_uint32_t clk_src, div;
+    struct rk_pmucru *pmucru = priv->pmucru;
+
+    if (rate == OSC_HZ)
+    {
+        clk_src = CLK_PCIE_PHY_REF_SEL_24M;
+        div = 1;
+    }
+    else
+    {
+        clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
+        div = RT_DIV_ROUND_UP(priv->ppll_hz, rate);
+    }
+
+    switch (clk_id)
+    {
+    case CLK_PCIEPHY0_REF:
+        rk_clrsetreg(&pmucru->pmu_clksel_con[9], CLK_PCIE_PHY0_REF_SEL_MASK,
+                (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
+        rk_clrsetreg(&pmucru->pmu_clksel_con[9], CLK_PCIE_PHY0_PLL_DIV_MASK,
+                ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
+        break;
+    case CLK_PCIEPHY1_REF:
+        rk_clrsetreg(&pmucru->pmu_clksel_con[9], CLK_PCIE_PHY1_REF_SEL_MASK,
+                (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
+        rk_clrsetreg(&pmucru->pmu_clksel_con[9], CLK_PCIE_PHY1_PLL_DIV_MASK,
+                ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
+        break;
+    case CLK_PCIEPHY2_REF:
+        rk_clrsetreg(&pmucru->pmu_clksel_con[9], CLK_PCIE_PHY2_REF_SEL_MASK,
+                (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT));
+        rk_clrsetreg(&pmucru->pmu_clksel_con[9], CLK_PCIE_PHY2_PLL_DIV_MASK,
+                ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
+        break;
+    default:
+        return -RT_EINVAL;
+    }
+
+    return pciephy_ref_get_pmuclk(priv, clk_id);
+}
+
+static rt_ubase_t rk_pmuclk_type_get_rate(struct rk_clk_platform_data *pdata,
+        struct rk_clk *rk_clk)
+{
+    struct rk_pmuclk_priv *priv = &rk_clk->pmuclk_info;
+    rt_ubase_t rate = 0;
+
+    if (!priv->ppll_hz)
+    {
+        return -RT_ERROR;
+    }
+
+    switch (pdata->id)
+    {
+    case PLL_PPLL:
+        rate = rk_pll_get_rate(&pmu_pll_clks[ppll], &priv->pmucru);
+        break;
+    case PLL_HPLL:
+        rate = rk_pll_get_rate(&pmu_pll_clks[hpll], &priv->pmucru);
+        break;
+    case CLK_RTC_32K:
+    case CLK_RTC32K_FRAC:
+        rate = rtc32k_get_pmuclk(priv);
+        break;
+    case SCLK_UART0:
+        rate = uart_get_pmuclk(priv, pdata->id);
+        break;
+    case CLK_I2C0:
+        rate = i2c_get_pmuclk(priv, pdata->id);
+        break;
+    case CLK_PWM0:
+        rate = pwm_get_pmuclk(priv, pdata->id);
+        break;
+    case PCLK_PMU:
+        rate = pmu_get_pmuclk(priv);
+        break;
+    case CLK_PCIEPHY0_REF:
+    case CLK_PCIEPHY1_REF:
+    case CLK_PCIEPHY2_REF:
+        rate = pciephy_ref_get_pmuclk(priv, pdata->id);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t rk_pmuclk_set_rate(struct rk_clk_platform_data *pdata,
+        struct rk_clk *rk_clk, rt_ubase_t rate)
+{
+    struct rk_pmuclk_priv *priv = &rk_clk->pmuclk_info;
+    rt_ubase_t res = 0;
+
+    if (!priv->ppll_hz)
+    {
+        return -RT_ERROR;
+    }
+
+    switch (pdata->id)
+    {
+    case PLL_PPLL:
+        res = rk_pll_set_rate(&pmu_pll_clks[ppll], priv->pmucru, rate);
+        priv->ppll_hz = rk_pll_get_rate(&pmu_pll_clks[ppll], &priv->pmucru);
+        break;
+    case PLL_HPLL:
+        res = rk_pll_set_rate(&pmu_pll_clks[hpll], priv->pmucru, rate);
+        priv->hpll_hz = rk_pll_get_rate(&pmu_pll_clks[hpll], &priv->pmucru);
+        break;
+    case CLK_RTC_32K:
+    case CLK_RTC32K_FRAC:
+        res = rtc32k_set_pmuclk(priv, rate);
+        break;
+    case SCLK_UART0:
+        res = uart_set_pmuclk(priv, pdata->id, rate);
+        break;
+    case CLK_I2C0:
+        res = i2c_set_pmuclk(priv, pdata->id, rate);
+        break;
+    case CLK_PWM0:
+        res = pwm_set_pmuclk(priv, pdata->id, rate);
+        break;
+    case PCLK_PMU:
+        res = pmu_set_pmuclk(priv, rate);
+        break;
+    case CLK_PCIEPHY0_REF:
+    case CLK_PCIEPHY1_REF:
+    case CLK_PCIEPHY2_REF:
+        res = pciephy_ref_set_pmuclk(priv, pdata->id, rate);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return res;
+}
+
+static rt_ubase_t rk_clk_type_get_rate(struct rk_clk_platform_data *pdata,
+        struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    rt_ubase_t rate = 0;
+
+    if (!priv->gpll_hz)
+    {
+        return -RT_ERROR;
+    }
+
+    switch (pdata->id)
+    {
+    case PLL_APLL:
+    case ARMCLK:
+        rate = rk_pll_get_rate(&pll_clks[apll], &priv->cru);
+        break;
+    case PLL_CPLL:
+        rate = rk_pll_get_rate(&pll_clks[cpll], &priv->cru);
+        break;
+    case PLL_GPLL:
+        rate = rk_pll_get_rate(&pll_clks[gpll], &priv->cru);
+        break;
+    case PLL_NPLL:
+        rate = rk_pll_get_rate(&pll_clks[npll], &priv->cru);
+        break;
+    case PLL_VPLL:
+        rate = rk_pll_get_rate(&pll_clks[vpll], &priv->cru);
+        break;
+    case PLL_DPLL:
+        rate = rk_pll_get_rate(&pll_clks[dpll], &priv->cru);
+        break;
+    case ACLK_BUS:
+    case PCLK_BUS:
+    case PCLK_WDT_NS:
+        rate = bus_get_clk(priv, pdata->id);
+        break;
+    case ACLK_PERIMID:
+    case HCLK_PERIMID:
+        rate = perimid_get_clk(priv, pdata->id);
+        break;
+    case ACLK_TOP_HIGH:
+    case ACLK_TOP_LOW:
+    case HCLK_TOP:
+    case PCLK_TOP:
+        rate = top_get_clk(priv, pdata->id);
+        break;
+    case CLK_I2C1:
+    case CLK_I2C2:
+    case CLK_I2C3:
+    case CLK_I2C4:
+    case CLK_I2C5:
+        rate = i2c_get_clk(priv, pdata->id);
+        break;
+    case CLK_SPI0:
+    case CLK_SPI1:
+    case CLK_SPI2:
+    case CLK_SPI3:
+        rate = spi_get_clk(priv, pdata->id);
+        break;
+    case CLK_PWM1:
+    case CLK_PWM2:
+    case CLK_PWM3:
+        rate = pwm_get_clk(priv, pdata->id);
+        break;
+    case CLK_SARADC:
+    case CLK_TSADC_TSEN:
+    case CLK_TSADC:
+        rate = adc_get_clk(priv, pdata->id);
+        break;
+    case HCLK_SDMMC0:
+    case CLK_SDMMC0:
+    case CLK_SDMMC1:
+    case CLK_SDMMC2:
+        rate = sdmmc_get_clk(priv, pdata->id);
+        break;
+    case SCLK_SFC:
+        rate = sfc_get_clk(priv);
+        break;
+    case NCLK_NANDC:
+        rate = nand_get_clk(priv);
+        break;
+    case CCLK_EMMC:
+        rate = emmc_get_clk(priv);
+        break;
+    case BCLK_EMMC:
+        rate = emmc_get_bclk(priv);
+        break;
+    case ACLK_VOP:
+        rate = aclk_vop_get_clk(priv);
+        break;
+    case DCLK_VOP0:
+    case DCLK_VOP1:
+    case DCLK_VOP2:
+        rate = dclk_vop_get_clk(priv, pdata->id);
+        break;
+    case SCLK_GMAC0:
+    case CLK_MAC0_2TOP:
+    case CLK_MAC0_REFOUT:
+        rate = gmac_src_get_clk(priv, 0);
+        break;
+    case CLK_MAC0_OUT:
+        rate = gmac_out_get_clk(priv, 0);
+        break;
+    case CLK_GMAC0_PTP_REF:
+        rate = gmac_ptp_ref_get_clk(priv, 0);
+        break;
+    case SCLK_GMAC1:
+    case CLK_MAC1_2TOP:
+    case CLK_MAC1_REFOUT:
+        rate = gmac_src_get_clk(priv, 1);
+        break;
+    case CLK_MAC1_OUT:
+        rate = gmac_out_get_clk(priv, 1);
+        break;
+    case CLK_GMAC1_PTP_REF:
+        rate = gmac_ptp_ref_get_clk(priv, 1);
+        break;
+    case DCLK_EBC:
+        rate = ebc_get_clk(priv);
+        break;
+    case ACLK_RKVDEC_PRE:
+    case ACLK_RKVDEC:
+    case CLK_RKVDEC_CORE:
+        rate = rkvdec_get_clk(priv, pdata->id);
+        break;
+    case TCLK_WDT_NS:
+        rate = OSC_HZ;
+        break;
+    case SCLK_UART1:
+    case SCLK_UART2:
+    case SCLK_UART3:
+    case SCLK_UART4:
+    case SCLK_UART5:
+    case SCLK_UART6:
+    case SCLK_UART7:
+    case SCLK_UART8:
+    case SCLK_UART9:
+        rate = uart_get_rate(priv, pdata->id);
+        break;
+    case ACLK_SECURE_FLASH:
+    case ACLK_CRYPTO_NS:
+    case HCLK_SECURE_FLASH:
+    case HCLK_CRYPTO_NS:
+    case CLK_CRYPTO_NS_RNG:
+    case CLK_CRYPTO_NS_CORE:
+    case CLK_CRYPTO_NS_PKA:
+        rate = crypto_get_rate(priv, pdata->id);
+        break;
+    case CPLL_500M:
+    case CPLL_333M:
+    case CPLL_250M:
+    case CPLL_125M:
+    case CPLL_100M:
+    case CPLL_62P5M:
+    case CPLL_50M:
+    case CPLL_25M:
+        rate = cpll_div_get_rate(priv, pdata->id);
+        break;
+    case CLK_TIMER0:
+    case CLK_TIMER1:
+    case CLK_TIMER2:
+    case CLK_TIMER3:
+    case CLK_TIMER4:
+    case CLK_TIMER5:
+        rate = OSC_HZ;
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return rate;
+};
+
+static rt_ubase_t rk_clk_set_rate(struct rk_clk_platform_data *pdata,
+        struct rk_clk *rk_clk, rt_ubase_t rate)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    rt_ubase_t res = 0;
+
+    if (!priv->gpll_hz)
+    {
+        return -RT_ERROR;
+    }
+
+    switch (pdata->id)
+    {
+    case PLL_APLL:
+    case ARMCLK:
+        if (priv->armclk_hz)
+        {
+            armclk_set_clk(priv, rate);
+        }
+        priv->armclk_hz = rate;
+        break;
+    case PLL_CPLL:
+        res = rk_pll_set_rate(&pll_clks[cpll], priv->cru, rate);
+        priv->cpll_hz = rk_pll_get_rate(&pll_clks[cpll], &priv->cru);
+        break;
+    case PLL_GPLL:
+        res = rk_pll_set_rate(&pll_clks[gpll], priv->cru, rate);
+        priv->gpll_hz = rk_pll_get_rate(&pll_clks[gpll], &priv->cru);
+        break;
+    case PLL_NPLL:
+        res = rk_pll_set_rate(&pll_clks[npll], priv->cru, rate);
+        break;
+    case PLL_VPLL:
+        res = rk_pll_set_rate(&pll_clks[vpll], priv->cru, rate);
+        priv->vpll_hz = rk_pll_get_rate(&pll_clks[vpll], &priv->cru);
+        break;
+    case ACLK_BUS:
+    case PCLK_BUS:
+    case PCLK_WDT_NS:
+        res = bus_set_clk(priv, pdata->id, rate);
+        break;
+    case ACLK_PERIMID:
+    case HCLK_PERIMID:
+        res = perimid_set_clk(priv, pdata->id, rate);
+        break;
+    case ACLK_TOP_HIGH:
+    case ACLK_TOP_LOW:
+    case HCLK_TOP:
+    case PCLK_TOP:
+        res = top_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_I2C1:
+    case CLK_I2C2:
+    case CLK_I2C3:
+    case CLK_I2C4:
+    case CLK_I2C5:
+        res = i2c_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_SPI0:
+    case CLK_SPI1:
+    case CLK_SPI2:
+    case CLK_SPI3:
+        res = spi_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_PWM1:
+    case CLK_PWM2:
+    case CLK_PWM3:
+        res = pwm_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_SARADC:
+    case CLK_TSADC_TSEN:
+    case CLK_TSADC:
+        res = adc_set_clk(priv, pdata->id, rate);
+        break;
+    case HCLK_SDMMC0:
+    case CLK_SDMMC0:
+    case CLK_SDMMC1:
+    case CLK_SDMMC2:
+        res = sdmmc_set_clk(priv, pdata->id, rate);
+        break;
+    case SCLK_SFC:
+        res = sfc_set_clk(priv, rate);
+        break;
+    case NCLK_NANDC:
+        res = nand_set_clk(priv, rate);
+        break;
+    case CCLK_EMMC:
+        res = emmc_set_clk(priv, rate);
+        break;
+    case BCLK_EMMC:
+        res = emmc_set_bclk(priv, rate);
+        break;
+    case ACLK_VOP:
+        res = aclk_vop_set_clk(priv, rate);
+        break;
+    case DCLK_VOP0:
+    case DCLK_VOP1:
+    case DCLK_VOP2:
+        res = dclk_vop_set_clk(priv, pdata->id, rate);
+        break;
+    case SCLK_GMAC0:
+    case CLK_MAC0_2TOP:
+    case CLK_MAC0_REFOUT:
+        res = gmac_src_set_clk(priv, 0, rate);
+        break;
+    case CLK_MAC0_OUT:
+        res = gmac_out_set_clk(priv, 0, rate);
+        break;
+    case SCLK_GMAC0_RX_TX:
+        res = gmac_tx_rx_set_clk(priv, 0, rate);
+        break;
+    case CLK_GMAC0_PTP_REF:
+        res = gmac_ptp_ref_set_clk(priv, 0, rate);
+        break;
+    case SCLK_GMAC1:
+    case CLK_MAC1_2TOP:
+    case CLK_MAC1_REFOUT:
+        res = gmac_src_set_clk(priv, 1, rate);
+        break;
+    case CLK_MAC1_OUT:
+        res = gmac_out_set_clk(priv, 1, rate);
+        break;
+    case SCLK_GMAC1_RX_TX:
+        res = gmac_tx_rx_set_clk(priv, 1, rate);
+        break;
+    case CLK_GMAC1_PTP_REF:
+        res = gmac_ptp_ref_set_clk(priv, 1, rate);
+        break;
+    case DCLK_EBC:
+        res = ebc_set_clk(priv, rate);
+        break;
+    case ACLK_RKVDEC_PRE:
+    case ACLK_RKVDEC:
+    case CLK_RKVDEC_CORE:
+        res = rkvdec_set_clk(priv, pdata->id, rate);
+        break;
+    case TCLK_WDT_NS:
+        res = OSC_HZ;
+        break;
+    case SCLK_UART1:
+    case SCLK_UART2:
+    case SCLK_UART3:
+    case SCLK_UART4:
+    case SCLK_UART5:
+    case SCLK_UART6:
+    case SCLK_UART7:
+    case SCLK_UART8:
+    case SCLK_UART9:
+        res = uart_set_rate(priv, pdata->id, rate);
+        break;
+    case ACLK_SECURE_FLASH:
+    case ACLK_CRYPTO_NS:
+    case HCLK_SECURE_FLASH:
+    case HCLK_CRYPTO_NS:
+    case CLK_CRYPTO_NS_RNG:
+    case CLK_CRYPTO_NS_CORE:
+    case CLK_CRYPTO_NS_PKA:
+        res = crypto_set_rate(priv, pdata->id, rate);
+        break;
+    case CPLL_500M:
+    case CPLL_333M:
+    case CPLL_250M:
+    case CPLL_125M:
+    case CPLL_100M:
+    case CPLL_62P5M:
+    case CPLL_50M:
+    case CPLL_25M:
+        res = cpll_div_set_rate(priv, pdata->id, rate);
+        break;
+    default:
+        return -RT_ERROR;
+    }
+
+    return res;
+};
+
+static rt_uint32_t rk_clk_get_rate(struct rk_clk_platform_data *pdata,
+    struct rk_clk *rk_clk)
+{
+    rt_uint32_t rate = 0;
+
+    if (rk_clk->type == rk_clk_type_clk)
+    {
+        rate = rk_clk_type_get_rate(pdata, rk_clk);
+    }
+    else if (rk_clk->type == rk_clk_type_pmuclk)
+    {
+        rate = rk_pmuclk_type_get_rate(pdata, rk_clk);
+    }
+
+    return rate;
+}
+
+static rt_err_t rk_clk_wait_lock(struct rk_clk_platform_data *pdata)
+{
+    rt_err_t err = RT_EOK;
+    rt_uint32_t count = 0, pllcon;
+
+    /*
+     * Lock time typical 250, max 500 input clock cycles @24MHz, So define a
+     * very safe maximum of 1000us, meaning 24000 cycles.
+     */
+    do {
+        pllcon = HWREG32(pdata->base + PLL_CON(1));
+        rt_hw_us_delay(100);
+        ++count;
+    } while (pllcon & PLLCON1_LOCK_STATUS && count < 10);
+
+    if (count >= 10)
+    {
+        err = -RT_ETIMEOUT;
+    }
+
+    return err;
+}
+
+static rt_err_t rtc32k_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_pmuclk_priv *priv = &rk_clk->pmuclk_info;
+    struct rk_pmucru *pmucru = priv->pmucru;
+
+    if (ppdata->id == CLK_RTC32K_FRAC)
+    {
+        rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
+                RTC32K_SEL_OSC0_DIV32K << RTC32K_SEL_SHIFT);
+    }
+    else
+    {
+        rk_clrsetreg(&pmucru->pmu_clksel_con[0], RTC32K_SEL_MASK,
+                RTC32K_SEL_OSC1_32K << RTC32K_SEL_SHIFT);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rk_pmuclk_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    switch (pdata->id)
+    {
+    case CLK_RTC_32K:
+        return rtc32k_set_parent(pdata, ppdata, rk_clk);
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t gmac0_src_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+
+    if (ppdata->id == CLK_MAC0_2TOP)
+    {
+        rk_clrsetreg(&cru->clksel_con[31], RMII0_EXTCLK_SEL_MASK,
+                RMII0_EXTCLK_SEL_MAC0_TOP << RMII0_EXTCLK_SEL_SHIFT);
+    }
+    else
+    {
+        rk_clrsetreg(&cru->clksel_con[31], RMII0_EXTCLK_SEL_MASK,
+                RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t gmac1_src_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+
+    if (ppdata->id == CLK_MAC1_2TOP)
+    {
+        rk_clrsetreg(&cru->clksel_con[33], RMII0_EXTCLK_SEL_MASK,
+                RMII0_EXTCLK_SEL_MAC0_TOP << RMII0_EXTCLK_SEL_SHIFT);
+    }
+    else
+    {
+        rk_clrsetreg(&cru->clksel_con[33], RMII0_EXTCLK_SEL_MASK,
+                RMII0_EXTCLK_SEL_IO << RMII0_EXTCLK_SEL_SHIFT);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t gmac0_tx_rx_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+
+    if (ppdata->id == SCLK_GMAC0_RGMII_SPEED)
+    {
+        rk_clrsetreg(&cru->clksel_con[31], RMII0_MODE_MASK,
+                RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
+    }
+    else if (ppdata->id == SCLK_GMAC0_RMII_SPEED)
+    {
+        rk_clrsetreg(&cru->clksel_con[31], RMII0_MODE_MASK,
+                RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
+    }
+    else
+    {
+        rk_clrsetreg(&cru->clksel_con[31], RMII0_MODE_MASK,
+                RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t gmac1_tx_rx_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+
+    if (ppdata->id == SCLK_GMAC1_RGMII_SPEED)
+    {
+        rk_clrsetreg(&cru->clksel_con[33], RMII0_MODE_MASK,
+                RMII0_MODE_SEL_RGMII << RMII0_MODE_SHIFT);
+    }
+    else if (ppdata->id == SCLK_GMAC1_RMII_SPEED)
+    {
+        rk_clrsetreg(&cru->clksel_con[33], RMII0_MODE_MASK,
+                RMII0_MODE_SEL_RMII << RMII0_MODE_SHIFT);
+    }
+    else
+    {
+        rk_clrsetreg(&cru->clksel_con[33], RMII0_MODE_MASK,
+                RMII0_MODE_SEL_GMII << RMII0_MODE_SHIFT);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t dclk_vop_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con_id;
+
+    switch (pdata->id)
+    {
+    case DCLK_VOP0:
+        con_id = 39;
+        break;
+
+    case DCLK_VOP1:
+        con_id = 40;
+        break;
+
+    case DCLK_VOP2:
+        con_id = 41;
+        break;
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    if (ppdata->id == PLL_VPLL)
+    {
+        rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
+                DCLK_VOP_SEL_VPLL << DCLK0_VOP_SEL_SHIFT);
+    }
+    else
+    {
+        rk_clrsetreg(&cru->clksel_con[con_id], DCLK0_VOP_SEL_MASK,
+                DCLK_VOP_SEL_HPLL << DCLK0_VOP_SEL_SHIFT);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rkvdec_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+    rt_uint32_t con_id, mask, shift;
+
+    switch (pdata->id)
+    {
+    case ACLK_RKVDEC_PRE:
+        con_id = 47;
+        mask = ACLK_RKVDEC_SEL_MASK;
+        shift = ACLK_RKVDEC_SEL_SHIFT;
+        break;
+
+    case CLK_RKVDEC_CORE:
+        con_id = 49;
+        mask = CLK_RKVDEC_CORE_SEL_MASK;
+        shift = CLK_RKVDEC_CORE_SEL_SHIFT;
+        break;
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    if (ppdata->id == PLL_CPLL)
+    {
+        rk_clrsetreg(&cru->clksel_con[con_id], mask,
+                ACLK_RKVDEC_SEL_CPLL << shift);
+    }
+    else
+    {
+        rk_clrsetreg(&cru->clksel_con[con_id], mask,
+                ACLK_RKVDEC_SEL_GPLL << shift);
+    }
+
+    return RT_EOK;
+}
+
+static int rk_clk_set_parent(struct rk_clk_platform_data *pdata,
+        struct rk_clk_platform_data *ppdata, struct rk_clk *rk_clk)
+{
+    switch (pdata->id)
+    {
+    case SCLK_GMAC0:
+        return gmac0_src_set_parent(pdata, ppdata, rk_clk);
+
+    case SCLK_GMAC1:
+        return gmac1_src_set_parent(pdata, ppdata, rk_clk);
+
+    case SCLK_GMAC0_RX_TX:
+        return gmac0_tx_rx_set_parent(pdata, ppdata, rk_clk);
+
+    case SCLK_GMAC1_RX_TX:
+        return gmac1_tx_rx_set_parent(pdata, ppdata, rk_clk);
+
+    case DCLK_VOP0:
+    case DCLK_VOP1:
+    case DCLK_VOP2:
+        return dclk_vop_set_parent(pdata, ppdata, rk_clk);
+
+    case ACLK_RKVDEC_PRE:
+    case CLK_RKVDEC_CORE:
+        return rkvdec_set_parent(pdata, ppdata, rk_clk);
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t mmc_set_phase(struct rk_clk_platform_data *pdata,
+        struct rk_clk *rk_clk, rt_uint32_t degrees)
+{
+    void *reg;
+    rt_ubase_t rate;
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+
+    rate = rk_clk_get_rate(pdata, rk_clk);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDMMC0_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_SDMMC0_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+
+    case SCLK_SDMMC1_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_SDMMC1_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+
+    case SCLK_SDMMC2_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_SDMMC2_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+
+    case SCLK_EMMC_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_EMMC_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+    }
+
+    return rk_clk_mmc_set_phase(rate, reg, 1, degrees);
+}
+
+static rt_base_t mmc_get_phase(struct rk_clk_platform_data *pdata,
+        struct rk_clk *rk_clk)
+{
+    void *reg;
+    rt_ubase_t rate;
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    struct rk_cru *cru = priv->cru;
+
+    rate = rk_clk_get_rate(pdata, rk_clk);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDMMC0_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_SDMMC0_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+
+    case SCLK_SDMMC1_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_SDMMC1_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+
+    case SCLK_SDMMC2_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_SDMMC2_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+
+    case SCLK_EMMC_DRV:
+        reg = &cru->emmc_con[0];
+        break;
+
+    case SCLK_EMMC_SAMPLE:
+        reg = &cru->emmc_con[1];
+        break;
+    }
+
+    return rk_clk_mmc_get_phase(rate, reg, 1);
+}
+
+static rt_err_t rk3568_clk_init(struct rt_clk *clk, void *fw_data)
+{
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rt_ofw_cell_args *args = fw_data;
+    struct rk_clk_platform_data *pdata;
+    rt_uint32_t clk_id = args->args[0];
+    rt_ubase_t reg_base;
+
+    pdata = &rk_clk->pdata[clk_id];
+
+    if (rk_clk->type == rk_clk_type_pmuclk)
+    {
+        reg_base = (rt_ubase_t)rk_clk->pmuclk_info.pmucru;
+
+        switch (clk_id)
+        {
+        case PLL_PPLL:
+            reg_base += pmu_pll_clks[ppll].con_offset;
+            break;
+        case PLL_HPLL:
+            reg_base += pmu_pll_clks[hpll].con_offset;
+            break;
+        default:
+            reg_base = RT_NULL;
+            break;
+        }
+    }
+    else if (rk_clk->type == rk_clk_type_clk)
+    {
+        reg_base = (rt_ubase_t)rk_clk->clk_info.cru;
+
+        switch (clk_id)
+        {
+        case PLL_APLL:
+        case ARMCLK:
+            reg_base += pll_clks[apll].con_offset;
+            break;
+        case PLL_CPLL:
+            reg_base += pll_clks[cpll].con_offset;
+            break;
+        case PLL_GPLL:
+            reg_base += pll_clks[gpll].con_offset;
+            break;
+        case PLL_NPLL:
+            reg_base += pll_clks[npll].con_offset;
+            break;
+        case PLL_VPLL:
+            reg_base += pll_clks[vpll].con_offset;
+            break;
+        case PLL_DPLL:
+            reg_base += pll_clks[dpll].con_offset;
+            break;
+        default:
+            reg_base = RT_NULL;
+            break;
+        }
+    }
+    else
+    {
+        LOG_E("Unknow type of rk clk = %d", rk_clk->type);
+        RT_ASSERT(0);
+    }
+
+    pdata->id = clk_id;
+    pdata->base = (void *)reg_base;
+
+    clk->rate = rk_clk_get_rate(pdata, rk_clk);
+    clk->priv = pdata;
+
+    rk_clk_set_default_rates(clk, clk->clk_np->ops->set_rate, clk_id);
+
+    return RT_EOK;
+}
+
+static rt_err_t rk3568_clk_enable(struct rt_clk *clk)
+{
+    struct rk_clk_platform_data *pdata = clk->priv;
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rk_cru *cru = rk_clk->clk_info.cru;
+    struct rk_pmucru *pmucru = rk_clk->pmuclk_info.pmucru;
+
+    if (pdata->base)
+    {
+        HWREG32(pdata->base + PLL_CON(1)) = HIWORD_UPDATE(0, PLLCON1_PWRDOWN, 0);
+
+        rk_clk_wait_lock(pdata);
+    }
+    else
+    {
+        void *con_regs;
+        struct rk_clk_gate *gate;
+
+        if (rk_clk->type == rk_clk_type_clk)
+        {
+            gate = &clk_gates[pdata->id];
+            con_regs = &cru->clkgate_con[gate->con_idx];
+        }
+        else if (rk_clk->type == rk_clk_type_pmuclk)
+        {
+            gate = &pmu_clk_gates[pdata->id];
+            con_regs = &pmucru->pmu_clkgate_con[gate->con_idx];
+        }
+        else
+        {
+            return -RT_EINVAL;
+        }
+
+        rk_clrreg(con_regs, RT_BIT(gate->con_bit));
+    }
+
+    return RT_EOK;
+}
+
+static void rk3568_clk_disable(struct rt_clk *clk)
+{
+    struct rk_clk_platform_data *pdata = clk->priv;
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rk_cru *cru = rk_clk->clk_info.cru;
+    struct rk_pmucru *pmucru = rk_clk->pmuclk_info.pmucru;
+
+    if (pdata->base)
+    {
+        HWREG32(pdata->base + PLL_CON(1)) = HIWORD_UPDATE(PLLCON1_PWRDOWN, PLLCON1_PWRDOWN, 0);
+    }
+    else
+    {
+        void *con_regs;
+        struct rk_clk_gate *gate;
+
+        if (rk_clk->type == rk_clk_type_clk)
+        {
+            gate = &clk_gates[pdata->id];
+            con_regs = &cru->clkgate_con[gate->con_idx];
+        }
+        else if (rk_clk->type == rk_clk_type_pmuclk)
+        {
+            gate = &pmu_clk_gates[pdata->id];
+            con_regs = &pmucru->pmu_clkgate_con[gate->con_idx];
+        }
+        else
+        {
+            return;
+        }
+
+        rk_setreg(con_regs, RT_BIT(gate->con_bit));
+    }
+}
+
+static rt_bool_t rk3568_clk_is_enabled(struct rt_clk *clk)
+{
+    struct rk_clk_platform_data *pdata = clk->priv;
+
+    if (pdata->base)
+    {
+        rt_uint32_t pllcon = HWREG32(pdata->base + PLL_CON(1));
+
+        return !(pllcon & PLLCON1_PWRDOWN);
+    }
+
+    return RT_TRUE;
+}
+
+static rt_err_t rk3568_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate, rt_ubase_t parent_rate)
+{
+    rt_ubase_t res_rate;
+    struct rk_clk_platform_data *pdata = clk->priv;
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+
+    if (rk_clk->type == rk_clk_type_clk)
+    {
+        res_rate = rk_clk_set_rate(pdata, rk_clk, rate);
+
+        if ((rt_base_t)res_rate > 0)
+        {
+            clk->rate = res_rate;
+        }
+    }
+    else if (rk_clk->type == rk_clk_type_pmuclk)
+    {
+        res_rate = rk_pmuclk_set_rate(pdata, rk_clk, rate);
+
+        if ((rt_base_t)res_rate > 0)
+        {
+            clk->rate = res_rate;
+        }
+    }
+    else
+    {
+        return -RT_EINVAL;
+    }
+
+    return (rt_ubase_t)res_rate > 0 ? RT_EOK : (rt_err_t)res_rate;
+}
+
+static rt_err_t rk3568_clk_set_parent(struct rt_clk *clk, struct rt_clk *parent)
+{
+    rt_err_t err;
+    struct rk_clk_platform_data *pdata = clk->priv, *ppdata = parent->priv;
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rk_clk *rk_clk_parent = raw_to_rk_clk(clk->clk_np);
+
+    if (rk_clk->type != rk_clk_parent->type)
+    {
+        return -RT_EINVAL;
+    }
+
+    if (rk_clk->type == rk_clk_type_clk)
+    {
+        err = rk_clk_set_parent(pdata, ppdata, rk_clk);
+    }
+    else if (rk_clk->type == rk_clk_type_pmuclk)
+    {
+        err = rk_pmuclk_set_parent(pdata, ppdata, rk_clk);
+    }
+    else
+    {
+        return -RT_EINVAL;
+    }
+
+    return err;
+}
+
+static rt_err_t rk3568_clk_set_phase(struct rt_clk *clk, int degrees)
+{
+    rt_err_t res;
+    struct rk_clk_platform_data *pdata = clk->priv;
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDMMC0_DRV:
+    case SCLK_SDMMC0_SAMPLE:
+    case SCLK_SDMMC1_DRV:
+    case SCLK_SDMMC1_SAMPLE:
+    case SCLK_SDMMC2_DRV:
+    case SCLK_SDMMC2_SAMPLE:
+    case SCLK_EMMC_DRV:
+    case SCLK_EMMC_SAMPLE:
+        res = mmc_set_phase(pdata, rk_clk, degrees);
+        break;
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return res;
+}
+
+static rt_base_t rk3568_clk_get_phase(struct rt_clk *clk)
+{
+    rt_base_t res;
+    struct rk_clk_platform_data *pdata = clk->priv;
+    struct rk_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDMMC0_DRV:
+    case SCLK_SDMMC0_SAMPLE:
+    case SCLK_SDMMC1_DRV:
+    case SCLK_SDMMC1_SAMPLE:
+    case SCLK_SDMMC2_DRV:
+    case SCLK_SDMMC2_SAMPLE:
+    case SCLK_EMMC_DRV:
+    case SCLK_EMMC_SAMPLE:
+        res = mmc_get_phase(pdata, rk_clk);
+        break;
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return res;
+}
+
+static rt_base_t rk3568_clk_round_rate(struct rt_clk *clk, rt_ubase_t drate,
+        rt_ubase_t *prate)
+{
+    return rk_clk_pll_round_rate(pll_rates, RT_ARRAY_SIZE(pll_rates), drate, prate);
+}
+
+static const struct rt_clk_ops rk3568_clk_ops =
+{
+    .init = rk3568_clk_init,
+    .enable = rk3568_clk_enable,
+    .disable = rk3568_clk_disable,
+    .is_enabled = rk3568_clk_is_enabled,
+    .set_rate = rk3568_clk_set_rate,
+    .set_parent = rk3568_clk_set_parent,
+    .set_phase = rk3568_clk_set_phase,
+    .get_phase = rk3568_clk_get_phase,
+    .round_rate = rk3568_clk_round_rate,
+};
+
+static void rk3568_clk_type_init(struct rk_clk *rk_clk, struct rt_ofw_node *np)
+{
+    rt_ubase_t cpu_freq = APLL_HZ;
+    struct rk_clk_priv *priv = &rk_clk->clk_info;
+    const char *rockchip_cpu_freq = rt_ofw_bootargs_select("rockchip.cpu_freq=", 0);
+
+    priv->cru = (struct rk_cru *)rk_clk->base;
+
+    if (!priv->armclk_enter_hz)
+    {
+        priv->armclk_enter_hz = rk_pll_get_rate(&pll_clks[apll], &priv->cru);
+        priv->armclk_init_hz = priv->armclk_enter_hz;
+    }
+
+    if (rockchip_cpu_freq)
+    {
+        cpu_freq = atol(rockchip_cpu_freq);
+    }
+    else
+    {
+        cpu_freq = 1800000000;
+    }
+
+    if (!armclk_set_clk(priv, cpu_freq))
+    {
+        priv->armclk_init_hz = cpu_freq;
+    }
+
+    if (priv->cpll_hz != CPLL_HZ)
+    {
+        if (!rk_pll_set_rate(&pll_clks[cpll], priv->cru, CPLL_HZ))
+        {
+            priv->cpll_hz = CPLL_HZ;
+        }
+    }
+
+    if (priv->gpll_hz != GPLL_HZ)
+    {
+        if (!rk_pll_set_rate(&pll_clks[gpll], priv->cru, GPLL_HZ))
+        {
+            priv->gpll_hz = GPLL_HZ;
+        }
+    }
+
+    priv->ppll_hz = pmu_pll_get_rate(ppll);
+    priv->hpll_hz = pmu_pll_get_rate(hpll);
+}
+
+static void rk3568_pmu_clk_type_init(struct rk_clk *rk_clk, struct rt_ofw_node *np)
+{
+    struct rk_pmuclk_priv *priv = &rk_clk->pmuclk_info;
+    priv->pmucru = (struct rk_pmucru *)rk_clk->base;
+
+    if (priv->ppll_hz != PPLL_HZ)
+    {
+        if (!rk_pll_set_rate(&pmu_pll_clks[ppll], priv->pmucru, PPLL_HZ))
+        {
+            priv->ppll_hz = PPLL_HZ;
+        }
+    }
+
+    /* Ungate PCIe30phy refclk_m and refclk_n */
+    rk_clrsetreg(&priv->pmucru->pmu_clkgate_con[2], 0x3 << 13, 0 << 13);
+}
+
+static rt_err_t clk_rk3568_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    rt_size_t data_size = 0;
+    struct rk_clk *rk_clk;
+    struct rt_ofw_node *np = pdev->parent.ofw_node;
+    enum rk_clk_type type = (rt_ubase_t)pdev->id->data;
+
+    if (type == rk_clk_type_clk)
+    {
+        data_size = CLK_NR_CLKS;
+    }
+    else if (type == rk_clk_type_pmuclk)
+    {
+        data_size = CLKPMU_NR_CLKS;
+    }
+
+    data_size *= sizeof(struct rk_clk_platform_data);
+    rk_clk = rt_malloc(sizeof(*rk_clk) + data_size);
+
+    if (rk_clk)
+    {
+        void *softrst_regs = RT_NULL;
+        rt_memset(&rk_clk->parent, 0, sizeof(rk_clk->parent));
+
+        rk_clk->base = rt_ofw_iomap(np, 0);
+
+        if (!rk_clk->base)
+        {
+            err = -RT_EIO;
+            goto _fail;
+        }
+
+        if (type == rk_clk_type_clk)
+        {
+            rk_clk->type = rk_clk_type_clk;
+
+            rk3568_clk_type_init(rk_clk, np);
+            softrst_regs = &rk_clk->clk_info.cru->softrst_con;
+        }
+        else if (type == rk_clk_type_pmuclk)
+        {
+            rk_clk->type = rk_clk_type_pmuclk;
+
+            rk3568_pmu_clk_type_init(rk_clk, np);
+            softrst_regs = &rk_clk->pmuclk_info.pmucru->pmu_softrst_con;
+        }
+
+        rk_clk->parent.parent.ops = &rk3568_clk_ops;
+
+        if ((err = rt_clk_register(&rk_clk->parent.parent, RT_NULL)))
+        {
+            goto _fail;
+        }
+
+        if ((err = rk_register_softrst(&rk_clk->parent.rstcer, np,
+                softrst_regs, ROCKCHIP_SOFTRST_HIWORD_MASK)))
+        {
+            goto _fail;
+        }
+
+        rt_ofw_data(np) = &rk_clk->parent;
+    }
+    else
+    {
+        err = -RT_ENOMEM;
+    }
+
+    return err;
+
+_fail:
+    if (rk_clk->base)
+    {
+        rt_iounmap(rk_clk->base);
+    }
+
+    rt_free(rk_clk);
+
+    return err;
+}
+
+static const struct rt_ofw_node_id clk_rk3568_ofw_ids[] =
+{
+    { .compatible = "rockchip,rk3568-cru", .data = (void *)rk_clk_type_clk },
+    { .compatible = "rockchip,rk3568-pmucru", .data = (void *)rk_clk_type_pmuclk },
+    { /* 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);

+ 117 - 0
bsp/rockchip/rk3500/driver/clk/clk-rk3568.h

@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2006-2024 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_CLK3568_H__
+#define __ROCKCHIP_CLK3568_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "reset/reset.h"
+#include <stdlib.h>
+#include "../rockchip.h"
+
+#define HZ      100
+#define KHZ     1000
+#define MHZ     1000000
+#define OSC_HZ  (24 * MHZ)
+
+struct rk_cpu_rate_table
+{
+    rt_ubase_t rate;
+    rt_uint32_t aclk_div;
+    rt_uint32_t pclk_div;
+};
+
+struct rk_pll_rate_table
+{
+    rt_ubase_t rate;
+    rt_uint32_t nr;
+    rt_uint32_t nf;
+    rt_uint32_t no;
+    rt_uint32_t nb;
+
+    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 rk_pll_clock
+{
+    rt_uint32_t id;
+    rt_uint32_t con_offset;
+    rt_uint32_t mode_offset;
+    rt_uint32_t mode_shift;
+    rt_uint32_t lock_shift;
+    rt_uint32_t pll_flags;
+    struct rk_pll_rate_table *rate_table;
+    rt_uint32_t mode_mask;
+};
+
+struct rk_clk_gate
+{
+    const char *name;
+    const char *parent_name;
+
+    int con_idx;
+    int con_bit;
+};
+
+#define GATE(_id, _name,    \
+_pname, _con_idx, _con_bit) \
+[_id] =                     \
+{                           \
+    .name = _name,          \
+    .parent_name = _pname,  \
+    .con_idx = _con_idx,    \
+    .con_bit = _con_bit,    \
+}
+
+
+#define CPUCLK_RATE(_rate,  \
+    _aclk_div, _pclk_div)   \
+{                           \
+    .rate     = _rate##U,   \
+    .aclk_div = _aclk_div,  \
+    .pclk_div = _pclk_div,  \
+}
+
+#define 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 PLL(_id, _con, _mode, _mshift,  \
+    _lshift, _pflags, _rtable)          \
+{                                       \
+    .id          = _id,                 \
+    .con_offset  = _con,                \
+    .mode_offset = _mode,               \
+    .mode_shift  = _mshift,             \
+    .lock_shift  = _lshift,             \
+    .pll_flags   = _pflags,             \
+    .rate_table  = _rtable,             \
+}
+
+#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+
+#define ROCKCHIP_SOFTRST_HIWORD_MASK    RT_BIT(0)
+
+#endif /* __ROCKCHIP_CLK3568_H__ */

+ 3286 - 0
bsp/rockchip/rk3500/driver/clk/clk-rk3588.c

@@ -0,0 +1,3286 @@
+#include "clk-rk3588.h"
+#define DBG_TAG "clk.rk3588"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+#include <mm_aspace.h>
+#include "rk3588-cru.h"
+#define raw_to_rk_clk(raw) rt_container_of(raw, struct rk3588_clk, parent)
+#define MHz     1000000
+#define KHz     1000
+
+#define CPU_PVTPLL_HZ   (1008 * MHz)
+#define LPLL_HZ     (816 * MHz)
+#define GPLL_HZ     (1188 * MHz)
+#define CPLL_HZ     (1500 * MHz)
+#define NPLL_HZ         (850 * MHz)
+#define PPLL_HZ     (1100 * MHz)
+
+/* RK3588 pll id */
+enum rk3588_pll_id {
+    B0PLL,
+    B1PLL,
+    LPLL,
+    CPLL,
+    GPLL,
+    NPLL,
+    V0PLL,
+    AUPLL,
+    PPLL,
+    PLL_COUNT,
+};
+
+struct rk3588_clk_info {
+    unsigned long id;
+    char *name;
+    rt_bool_t is_cru;
+};
+
+struct rk3588_pll {
+    unsigned int con0;
+    unsigned int con1;
+    unsigned int con2;
+    unsigned int con3;
+    unsigned int con4;
+    unsigned int reserved0[3];
+};
+struct rk3588_cru {
+    struct rk3588_pll pll[18];                                                                          /*144*/
+    unsigned int reserved0[16];/* Address Offset: 0x0240 */                                             /*160*/
+    unsigned int mode_con00;/* Address Offset: 0x0280 */                                                /*161*/
+    unsigned int reserved1[31];/* Address Offset: 0x0284 */                                             /*192*/
+    unsigned int clksel_con[178]; /* Address Offset: 0x0300 */                                          /*370*/
+    unsigned int reserved2[142];/* Address Offset: 0x05c8 */                                            /*512*/
+    unsigned int clkgate_con[78];/* Address Offset: 0x0800 */                                           /*590*/
+    unsigned int reserved3[50];/* Address Offset: 0x0938 */                                             /*640*/
+    unsigned int softrst_con[78];/* Address Offset: 0xa00 */ /* for convenient of softrst register      //718*/
+    unsigned int reserved4[50];/* Address Offset: 0x0b38 */                                             /*768*/
+    unsigned int glb_cnt_th;/* Address Offset: 0x0c00 */
+    unsigned int glb_rst_st;/* Address Offset: 0x0c04 */
+    unsigned int glb_srst_fst;/* Address Offset: 0x0c08 */
+    unsigned int glb_srsr_snd; /* Address Offset: 0x0c0c */
+    unsigned int glb_rst_con;/* Address Offset: 0x0c10 */
+    unsigned int reserved5[4];/* Address Offset: 0x0c14 */
+    unsigned int sdio_con[2];/* Address Offset: 0x0c24 */
+    unsigned int reserved7;/* Address Offset: 0x0c2c */
+    unsigned int sdmmc_con[2];/* Address Offset: 0x0c30 */
+    unsigned int reserved8[48562];/* Address Offset: 0x0c38 */
+    unsigned int pmuclksel_con[21]; /* Address Offset: 0x0100 */
+    unsigned int reserved9[299];/* Address Offset: 0x0c38 */
+    unsigned int pmuclkgate_con[9]; /* Address Offset: 0x0100 */
+};
+
+struct rk3588_clk_priv {
+    struct rk3588_cru *cru;
+
+    rt_ubase_t ppll_hz;
+    rt_ubase_t gpll_hz;
+    rt_ubase_t cpll_hz;
+    rt_ubase_t npll_hz;
+    rt_ubase_t v0pll_hz;
+    rt_ubase_t aupll_hz;
+    rt_ubase_t armclk_hz;
+    rt_ubase_t armclk_enter_hz;
+    rt_ubase_t armclk_init_hz;
+    rt_bool_t sync_kernel;
+    rt_bool_t set_armclk_rate;
+};
+struct rk3588_clk_platform_data
+{
+    rt_uint32_t id;
+    void *base;
+};
+struct rk3588_clk
+{
+    struct rt_reset_controller_clk_node parent;
+
+    void *base;
+
+    struct rk3588_clk_priv clk_info;
+
+    struct rk3588_clk_platform_data pdata[];
+};
+struct pll_rate_table {
+    unsigned long rate;
+    unsigned int m;
+    unsigned int p;
+    unsigned int s;
+    unsigned int k;
+};
+
+#define RK3588_PLL_CON(x)       ((x) * 0x4)
+#define RK3588_MODE_CON         0x280
+
+#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_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_B0_PLL_MODE_CON      (RK3588_BIGCORE0_CRU_BASE + 0x280)
+#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_B1_PLL_MODE_CON      (RK3588_BIGCORE1_CRU_BASE + 0x280)
+#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_LPLL_MODE_CON        (RK3588_DSU_CRU_BASE + 0x280)
+#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)
+
+enum {
+    /* CRU_CLK_SEL8_CON */
+    ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT     = 14,
+    ACLK_LOW_TOP_ROOT_SRC_SEL_MASK      = 1 << ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT,
+    ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL      = 0,
+    ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL,
+    ACLK_LOW_TOP_ROOT_DIV_SHIFT     = 9,
+    ACLK_LOW_TOP_ROOT_DIV_MASK      = 0x1f << ACLK_LOW_TOP_ROOT_DIV_SHIFT,
+    PCLK_TOP_ROOT_SEL_SHIFT         = 7,
+    PCLK_TOP_ROOT_SEL_MASK          = 3 << PCLK_TOP_ROOT_SEL_SHIFT,
+    PCLK_TOP_ROOT_SEL_100M          = 0,
+    PCLK_TOP_ROOT_SEL_50M,
+    PCLK_TOP_ROOT_SEL_24M,
+    ACLK_TOP_ROOT_SRC_SEL_SHIFT     = 5,
+    ACLK_TOP_ROOT_SRC_SEL_MASK      = 3 << ACLK_TOP_ROOT_SRC_SEL_SHIFT,
+    ACLK_TOP_ROOT_SRC_SEL_GPLL      = 0,
+    ACLK_TOP_ROOT_SRC_SEL_CPLL,
+    ACLK_TOP_ROOT_SRC_SEL_AUPLL,
+    ACLK_TOP_ROOT_DIV_SHIFT         = 0,
+    ACLK_TOP_ROOT_DIV_MASK          = 0x1f << ACLK_TOP_ROOT_DIV_SHIFT,
+
+    /* CRU_CLK_SEL9_CON */
+    ACLK_TOP_S400_SEL_SHIFT         = 8,
+    ACLK_TOP_S400_SEL_MASK          = 3 << ACLK_TOP_S400_SEL_SHIFT,
+    ACLK_TOP_S400_SEL_400M          = 0,
+    ACLK_TOP_S400_SEL_200M,
+    ACLK_TOP_S200_SEL_SHIFT         = 6,
+    ACLK_TOP_S200_SEL_MASK          = 3 << ACLK_TOP_S200_SEL_SHIFT,
+    ACLK_TOP_S200_SEL_200M          = 0,
+    ACLK_TOP_S200_SEL_100M,
+
+    /* CRU_CLK_SEL38_CON */
+    CLK_I2C8_SEL_SHIFT          = 13,
+    CLK_I2C8_SEL_MASK           = 1 << CLK_I2C8_SEL_SHIFT,
+    CLK_I2C7_SEL_SHIFT          = 12,
+    CLK_I2C7_SEL_MASK           = 1 << CLK_I2C7_SEL_SHIFT,
+    CLK_I2C6_SEL_SHIFT          = 11,
+    CLK_I2C6_SEL_MASK           = 1 << CLK_I2C6_SEL_SHIFT,
+    CLK_I2C5_SEL_SHIFT          = 10,
+    CLK_I2C5_SEL_MASK           = 1 << CLK_I2C5_SEL_SHIFT,
+    CLK_I2C4_SEL_SHIFT          = 9,
+    CLK_I2C4_SEL_MASK           = 1 << CLK_I2C4_SEL_SHIFT,
+    CLK_I2C3_SEL_SHIFT          = 8,
+    CLK_I2C3_SEL_MASK           = 1 << CLK_I2C3_SEL_SHIFT,
+    CLK_I2C2_SEL_SHIFT          = 7,
+    CLK_I2C2_SEL_MASK           = 1 << CLK_I2C2_SEL_SHIFT,
+    CLK_I2C1_SEL_SHIFT          = 6,
+    CLK_I2C1_SEL_MASK           = 1 << CLK_I2C1_SEL_SHIFT,
+    ACLK_BUS_ROOT_SEL_SHIFT         = 5,
+    ACLK_BUS_ROOT_SEL_MASK          = 3 << ACLK_BUS_ROOT_SEL_SHIFT,
+    ACLK_BUS_ROOT_SEL_GPLL          = 0,
+    ACLK_BUS_ROOT_SEL_CPLL,
+    ACLK_BUS_ROOT_DIV_SHIFT         = 0,
+    ACLK_BUS_ROOT_DIV_MASK          = 0x1f << ACLK_BUS_ROOT_DIV_SHIFT,
+
+    /* CRU_CLK_SEL40_CON */
+    CLK_SARADC_SEL_SHIFT            = 14,
+    CLK_SARADC_SEL_MASK         = 0x1 << CLK_SARADC_SEL_SHIFT,
+    CLK_SARADC_SEL_GPLL         = 0,
+    CLK_SARADC_SEL_24M,
+    CLK_SARADC_DIV_SHIFT            = 6,
+    CLK_SARADC_DIV_MASK         = 0xff << CLK_SARADC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL41_CON */
+    CLK_UART_SRC_SEL_SHIFT          = 14,
+    CLK_UART_SRC_SEL_MASK           = 0x1 << CLK_UART_SRC_SEL_SHIFT,
+    CLK_UART_SRC_SEL_GPLL           = 0,
+    CLK_UART_SRC_SEL_CPLL,
+    CLK_UART_SRC_DIV_SHIFT          = 9,
+    CLK_UART_SRC_DIV_MASK           = 0x1f << CLK_UART_SRC_DIV_SHIFT,
+    CLK_TSADC_SEL_SHIFT         = 8,
+    CLK_TSADC_SEL_MASK          = 0x1 << CLK_TSADC_SEL_SHIFT,
+    CLK_TSADC_SEL_GPLL          = 0,
+    CLK_TSADC_SEL_24M,
+    CLK_TSADC_DIV_SHIFT         = 0,
+    CLK_TSADC_DIV_MASK          = 0xff << CLK_TSADC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL42_CON */
+    CLK_UART_FRAC_NUMERATOR_SHIFT       = 16,
+    CLK_UART_FRAC_NUMERATOR_MASK        = 0xffff << 16,
+    CLK_UART_FRAC_DENOMINATOR_SHIFT     = 0,
+    CLK_UART_FRAC_DENOMINATOR_MASK      = 0xffff,
+
+    /* CRU_CLK_SEL43_CON */
+    CLK_UART_SEL_SHIFT          = 0,
+    CLK_UART_SEL_MASK           = 0x3 << CLK_UART_SEL_SHIFT,
+    CLK_UART_SEL_SRC            = 0,
+    CLK_UART_SEL_FRAC,
+    CLK_UART_SEL_XIN24M,
+
+    /* CRU_CLK_SEL59_CON */
+    CLK_PWM2_SEL_SHIFT          = 14,
+    CLK_PWM2_SEL_MASK           = 3 << CLK_PWM2_SEL_SHIFT,
+    CLK_PWM1_SEL_SHIFT          = 12,
+    CLK_PWM1_SEL_MASK           = 3 << CLK_PWM1_SEL_SHIFT,
+    CLK_SPI4_SEL_SHIFT          = 10,
+    CLK_SPI4_SEL_MASK           = 3 << CLK_SPI4_SEL_SHIFT,
+    CLK_SPI3_SEL_SHIFT          = 8,
+    CLK_SPI3_SEL_MASK           = 3 << CLK_SPI3_SEL_SHIFT,
+    CLK_SPI2_SEL_SHIFT          = 6,
+    CLK_SPI2_SEL_MASK           = 3 << CLK_SPI2_SEL_SHIFT,
+    CLK_SPI1_SEL_SHIFT          = 4,
+    CLK_SPI1_SEL_MASK           = 3 << CLK_SPI1_SEL_SHIFT,
+    CLK_SPI0_SEL_SHIFT          = 2,
+    CLK_SPI0_SEL_MASK           = 3 << CLK_SPI0_SEL_SHIFT,
+    CLK_SPI_SEL_200M            = 0,
+    CLK_SPI_SEL_150M,
+    CLK_SPI_SEL_24M,
+
+    /* CRU_CLK_SEL60_CON */
+    CLK_PWM3_SEL_SHIFT          = 0,
+    CLK_PWM3_SEL_MASK           = 3 << CLK_PWM3_SEL_SHIFT,
+    CLK_PWM_SEL_100M            = 0,
+    CLK_PWM_SEL_50M,
+    CLK_PWM_SEL_24M,
+
+    /* CRU_CLK_SEL62_CON */
+    DCLK_DECOM_SEL_SHIFT            = 5,
+    DCLK_DECOM_SEL_MASK         = 1 << DCLK_DECOM_SEL_SHIFT,
+    DCLK_DECOM_SEL_GPLL         = 0,
+    DCLK_DECOM_SEL_SPLL,
+    DCLK_DECOM_DIV_SHIFT            = 0,
+    DCLK_DECOM_DIV_MASK         = 0x1F << DCLK_DECOM_DIV_SHIFT,
+
+    /* CRU_CLK_SEL77_CON */
+    CCLK_EMMC_SEL_SHIFT         = 14,
+    CCLK_EMMC_SEL_MASK          = 3 << CCLK_EMMC_SEL_SHIFT,
+    CCLK_EMMC_SEL_GPLL          = 0,
+    CCLK_EMMC_SEL_CPLL,
+    CCLK_EMMC_SEL_24M,
+    CCLK_EMMC_DIV_SHIFT         = 8,
+    CCLK_EMMC_DIV_MASK          = 0x3f << CCLK_EMMC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL78_CON */
+    SCLK_SFC_SEL_SHIFT          = 12,
+    SCLK_SFC_SEL_MASK           = 3 << SCLK_SFC_SEL_SHIFT,
+    SCLK_SFC_SEL_GPLL           = 0,
+    SCLK_SFC_SEL_CPLL,
+    SCLK_SFC_SEL_24M,
+    SCLK_SFC_DIV_SHIFT          = 6,
+    SCLK_SFC_DIV_MASK           = 0x3f << SCLK_SFC_DIV_SHIFT,
+    BCLK_EMMC_SEL_SHIFT         = 5,
+    BCLK_EMMC_SEL_MASK          = 1 << BCLK_EMMC_SEL_SHIFT,
+    BCLK_EMMC_SEL_GPLL          = 0,
+    BCLK_EMMC_SEL_CPLL,
+    BCLK_EMMC_DIV_SHIFT         = 0,
+    BCLK_EMMC_DIV_MASK          = 0x1f << BCLK_EMMC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL81_CON */
+    CLK_GMAC1_PTP_SEL_SHIFT         = 13,
+    CLK_GMAC1_PTP_SEL_MASK          = 1 << CLK_GMAC1_PTP_SEL_SHIFT,
+    CLK_GMAC1_PTP_SEL_CPLL          = 0,
+    CLK_GMAC1_PTP_DIV_SHIFT         = 7,
+    CLK_GMAC1_PTP_DIV_MASK          = 0x3f << CLK_GMAC1_PTP_DIV_SHIFT,
+    CLK_GMAC0_PTP_SEL_SHIFT         = 6,
+    CLK_GMAC0_PTP_SEL_MASK          = 1 << CLK_GMAC0_PTP_SEL_SHIFT,
+    CLK_GMAC0_PTP_SEL_CPLL          = 0,
+    CLK_GMAC0_PTP_DIV_SHIFT         = 0,
+    CLK_GMAC0_PTP_DIV_MASK          = 0x3f << CLK_GMAC0_PTP_DIV_SHIFT,
+
+    /* CRU_CLK_SEL83_CON */
+    CLK_GMAC_125M_SEL_SHIFT         = 15,
+    CLK_GMAC_125M_SEL_MASK          = 1 << CLK_GMAC_125M_SEL_SHIFT,
+    CLK_GMAC_125M_SEL_GPLL          = 0,
+    CLK_GMAC_125M_SEL_CPLL,
+    CLK_GMAC_125M_DIV_SHIFT         = 8,
+    CLK_GMAC_125M_DIV_MASK          = 0x7f << CLK_GMAC_125M_DIV_SHIFT,
+
+    /* CRU_CLK_SEL84_CON */
+    CLK_GMAC_50M_SEL_SHIFT          = 7,
+    CLK_GMAC_50M_SEL_MASK           = 1 << CLK_GMAC_50M_SEL_SHIFT,
+    CLK_GMAC_50M_SEL_GPLL           = 0,
+    CLK_GMAC_50M_SEL_CPLL,
+    CLK_GMAC_50M_DIV_SHIFT          = 0,
+    CLK_GMAC_50M_DIV_MASK           = 0x7f << CLK_GMAC_50M_DIV_SHIFT,
+
+    /* CRU_CLK_SEL110_CON */
+    HCLK_VOP_ROOT_SEL_SHIFT         = 10,
+    HCLK_VOP_ROOT_SEL_MASK          = 3 << HCLK_VOP_ROOT_SEL_SHIFT,
+    HCLK_VOP_ROOT_SEL_200M          = 0,
+    HCLK_VOP_ROOT_SEL_100M,
+    HCLK_VOP_ROOT_SEL_50M,
+    HCLK_VOP_ROOT_SEL_24M,
+    ACLK_VOP_LOW_ROOT_SEL_SHIFT     = 8,
+    ACLK_VOP_LOW_ROOT_SEL_MASK      = 3 << ACLK_VOP_LOW_ROOT_SEL_SHIFT,
+    ACLK_VOP_LOW_ROOT_SEL_400M      = 0,
+    ACLK_VOP_LOW_ROOT_SEL_200M,
+    ACLK_VOP_LOW_ROOT_SEL_100M,
+    ACLK_VOP_LOW_ROOT_SEL_24M,
+    ACLK_VOP_ROOT_SEL_SHIFT         = 5,
+    ACLK_VOP_ROOT_SEL_MASK          = 7 << ACLK_VOP_ROOT_SEL_SHIFT,
+    ACLK_VOP_ROOT_SEL_GPLL          = 0,
+    ACLK_VOP_ROOT_SEL_CPLL,
+    ACLK_VOP_ROOT_SEL_AUPLL,
+    ACLK_VOP_ROOT_SEL_NPLL,
+    ACLK_VOP_ROOT_SEL_SPLL,
+    ACLK_VOP_ROOT_DIV_SHIFT         = 0,
+    ACLK_VOP_ROOT_DIV_MASK          = 0x1f << ACLK_VOP_ROOT_DIV_SHIFT,
+
+    /* CRU_CLK_SEL111_CON */
+    DCLK1_VOP_SRC_SEL_SHIFT         = 14,
+    DCLK1_VOP_SRC_SEL_MASK          = 3 << DCLK1_VOP_SRC_SEL_SHIFT,
+    DCLK1_VOP_SRC_DIV_SHIFT         = 9,
+    DCLK1_VOP_SRC_DIV_MASK          = 0x1f << DCLK1_VOP_SRC_DIV_SHIFT,
+    DCLK0_VOP_SRC_SEL_SHIFT         = 7,
+    DCLK0_VOP_SRC_SEL_MASK          = 3 << DCLK0_VOP_SRC_SEL_SHIFT,
+    DCLK_VOP_SRC_SEL_GPLL           = 0,
+    DCLK_VOP_SRC_SEL_CPLL,
+    DCLK_VOP_SRC_SEL_V0PLL,
+    DCLK_VOP_SRC_SEL_AUPLL,
+    DCLK0_VOP_SRC_DIV_SHIFT         = 0,
+    DCLK0_VOP_SRC_DIV_MASK          = 0x7f << DCLK0_VOP_SRC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL112_CON */
+    DCLK2_VOP_SEL_SHIFT         = 11,
+    DCLK2_VOP_SEL_MASK          = 3 << DCLK2_VOP_SEL_SHIFT,
+    DCLK1_VOP_SEL_SHIFT         = 9,
+    DCLK1_VOP_SEL_MASK          = 3 << DCLK1_VOP_SEL_SHIFT,
+    DCLK0_VOP_SEL_SHIFT         = 7,
+    DCLK0_VOP_SEL_MASK          = 3 << DCLK0_VOP_SEL_SHIFT,
+    DCLK2_VOP_SRC_SEL_SHIFT         = 5,
+    DCLK2_VOP_SRC_SEL_MASK          = 3 << DCLK2_VOP_SRC_SEL_SHIFT,
+    DCLK2_VOP_SRC_DIV_SHIFT         = 0,
+    DCLK2_VOP_SRC_DIV_MASK          = 0x1f << DCLK2_VOP_SRC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL113_CON */
+    DCLK3_VOP_SRC_SEL_SHIFT         = 7,
+    DCLK3_VOP_SRC_SEL_MASK          = 3 << DCLK3_VOP_SRC_SEL_SHIFT,
+    DCLK3_VOP_SRC_DIV_SHIFT         = 0,
+    DCLK3_VOP_SRC_DIV_MASK          = 0x7f << DCLK3_VOP_SRC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL117_CON */
+    CLK_AUX16MHZ_1_DIV_SHIFT        = 8,
+    CLK_AUX16MHZ_1_DIV_MASK         = 0xff << CLK_AUX16MHZ_1_DIV_SHIFT,
+    CLK_AUX16MHZ_0_DIV_SHIFT        = 0,
+    CLK_AUX16MHZ_0_DIV_MASK         = 0xff << CLK_AUX16MHZ_0_DIV_SHIFT,
+
+    /* CRU_CLK_SEL165_CON */
+    PCLK_CENTER_ROOT_SEL_SHIFT      = 6,
+    PCLK_CENTER_ROOT_SEL_MASK       = 3 << PCLK_CENTER_ROOT_SEL_SHIFT,
+    PCLK_CENTER_ROOT_SEL_200M       = 0,
+    PCLK_CENTER_ROOT_SEL_100M,
+    PCLK_CENTER_ROOT_SEL_50M,
+    PCLK_CENTER_ROOT_SEL_24M,
+    HCLK_CENTER_ROOT_SEL_SHIFT      = 4,
+    HCLK_CENTER_ROOT_SEL_MASK       = 3 << HCLK_CENTER_ROOT_SEL_SHIFT,
+    HCLK_CENTER_ROOT_SEL_400M       = 0,
+    HCLK_CENTER_ROOT_SEL_200M,
+    HCLK_CENTER_ROOT_SEL_100M,
+    HCLK_CENTER_ROOT_SEL_24M,
+    ACLK_CENTER_LOW_ROOT_SEL_SHIFT      = 2,
+    ACLK_CENTER_LOW_ROOT_SEL_MASK       = 3 << ACLK_CENTER_LOW_ROOT_SEL_SHIFT,
+    ACLK_CENTER_LOW_ROOT_SEL_500M       = 0,
+    ACLK_CENTER_LOW_ROOT_SEL_250M,
+    ACLK_CENTER_LOW_ROOT_SEL_100M,
+    ACLK_CENTER_LOW_ROOT_SEL_24M,
+    ACLK_CENTER_ROOT_SEL_SHIFT      = 0,
+    ACLK_CENTER_ROOT_SEL_MASK       = 3 << ACLK_CENTER_ROOT_SEL_SHIFT,
+    ACLK_CENTER_ROOT_SEL_700M       = 0,
+    ACLK_CENTER_ROOT_SEL_400M,
+    ACLK_CENTER_ROOT_SEL_200M,
+    ACLK_CENTER_ROOT_SEL_24M,
+
+    /* CRU_CLK_SEL172_CON */
+    CCLK_SDIO_SRC_SEL_SHIFT         = 8,
+    CCLK_SDIO_SRC_SEL_MASK          = 3 << CCLK_SDIO_SRC_SEL_SHIFT,
+    CCLK_SDIO_SRC_SEL_GPLL          = 0,
+    CCLK_SDIO_SRC_SEL_CPLL,
+    CCLK_SDIO_SRC_SEL_24M,
+    CCLK_SDIO_SRC_DIV_SHIFT         = 2,
+    CCLK_SDIO_SRC_DIV_MASK          = 0x3f << CCLK_SDIO_SRC_DIV_SHIFT,
+
+    /* CRU_CLK_SEL176_CON */
+    CLK_PCIE_PHY1_PLL_DIV_SHIFT     = 6,
+    CLK_PCIE_PHY1_PLL_DIV_MASK      = 0x3f << CLK_PCIE_PHY1_PLL_DIV_SHIFT,
+    CLK_PCIE_PHY0_PLL_DIV_SHIFT     = 0,
+    CLK_PCIE_PHY0_PLL_DIV_MASK      = 0x3f << CLK_PCIE_PHY0_PLL_DIV_SHIFT,
+
+    /* CRU_CLK_SEL177_CON */
+    CLK_PCIE_PHY2_REF_SEL_SHIFT     = 8,
+    CLK_PCIE_PHY2_REF_SEL_MASK      = 1 << CLK_PCIE_PHY2_REF_SEL_SHIFT,
+    CLK_PCIE_PHY1_REF_SEL_SHIFT     = 7,
+    CLK_PCIE_PHY1_REF_SEL_MASK      = 1 << CLK_PCIE_PHY1_REF_SEL_SHIFT,
+    CLK_PCIE_PHY0_REF_SEL_SHIFT     = 6,
+    CLK_PCIE_PHY0_REF_SEL_MASK      = 1 << CLK_PCIE_PHY0_REF_SEL_SHIFT,
+    CLK_PCIE_PHY_REF_SEL_24M        = 0,
+    CLK_PCIE_PHY_REF_SEL_PPLL,
+    CLK_PCIE_PHY2_PLL_DIV_SHIFT     = 0,
+    CLK_PCIE_PHY2_PLL_DIV_MASK      = 0x3f << CLK_PCIE_PHY2_PLL_DIV_SHIFT,
+
+    /* PMUCRU_CLK_SEL2_CON */
+    CLK_PMU1PWM_SEL_SHIFT           = 9,
+    CLK_PMU1PWM_SEL_MASK            = 3 << CLK_PMU1PWM_SEL_SHIFT,
+
+    /* PMUCRU_CLK_SEL3_CON */
+    CLK_I2C0_SEL_SHIFT          = 6,
+    CLK_I2C0_SEL_MASK           = 1 << CLK_I2C0_SEL_SHIFT,
+    CLK_I2C_SEL_200M            = 0,
+    CLK_I2C_SEL_100M,
+};
+
+static struct rk_pll_rate_table rk3588_pll_rates[] = {
+    /* _mhz, _p, _m, _s, _k */
+    RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
+    RK3588_PLL_RATE(1200000000, 2, 200, 1, 0),
+    RK3588_PLL_RATE(1188000000, 2, 198, 1, 0),
+    RK3588_PLL_RATE(1100000000, 3, 550, 2, 0),
+    RK3588_PLL_RATE(1008000000, 2, 336, 2, 0),
+    RK3588_PLL_RATE(1000000000, 3, 500, 2, 0),
+    RK3588_PLL_RATE(900000000, 2, 300, 2, 0),
+    RK3588_PLL_RATE(850000000, 3, 425, 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(742500000, 4, 495, 2, 0),
+    RK3588_PLL_RATE(722534400, 8, 963, 2, 24850),
+    RK3588_PLL_RATE(600000000, 2, 200, 2, 0),
+    RK3588_PLL_RATE(594000000, 2, 198, 2, 0),
+    RK3588_PLL_RATE(200000000, 3, 400, 4, 0),
+    RK3588_PLL_RATE(100000000, 3, 400, 5, 0),
+    { /* sentinel */ },
+};
+
+static struct rk_pll_clock rk3588_pll_clks[] = {
+    [B0PLL] = PLL(pll_rk3588, PLL_B0PLL, RK3588_B0_PLL_CON(0),
+              RK3588_B0_PLL_MODE_CON, 0, 15, 0,
+              rk3588_pll_rates),
+    [B1PLL] = PLL(pll_rk3588, PLL_B1PLL, RK3588_B1_PLL_CON(8),
+              RK3588_B1_PLL_MODE_CON, 0, 15, 0,
+              rk3588_pll_rates),
+    [LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3588_LPLL_CON(16),
+             RK3588_LPLL_MODE_CON, 0, 15, 0, rk3588_pll_rates),
+    [V0PLL] = PLL(pll_rk3588, PLL_V0PLL, RK3588_PLL_CON(88),
+              RK3588_MODE_CON0, 4, 15, 0, rk3588_pll_rates),
+    [AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3588_PLL_CON(96),
+              RK3588_MODE_CON0, 6, 15, 0, rk3588_pll_rates),
+    [CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3588_PLL_CON(104),
+             RK3588_MODE_CON0, 8, 15, 0, rk3588_pll_rates),
+    [GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3588_PLL_CON(112),
+             RK3588_MODE_CON0, 2, 15, 0, rk3588_pll_rates),
+    [NPLL] = PLL(pll_rk3588, PLL_NPLL, RK3588_PLL_CON(120),
+             RK3588_MODE_CON0, 0, 15, 0, rk3588_pll_rates),
+    [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3588_PMU_PLL_CON(128),
+             RK3588_MODE_CON0, 10, 15, 0, rk3588_pll_rates),
+};
+struct rk3588_clk_gate
+{
+    const char *name;
+    const char *parent_name;
+
+    int offset;
+    int con_bit;
+};
+#undef GATE
+#define GATE(_id, _name,    \
+_pname, _offset, _con_bit) \
+[_id] =                     \
+{                           \
+    .name = _name,          \
+    .parent_name = _pname,  \
+    .offset = _offset,    \
+    .con_bit = _con_bit,    \
+}
+static struct rk3588_clk_gate clk_gates[] =
+{
+    /*
+     * CRU Clock-Architecture
+     */
+    /* fixed */
+
+    /* top */
+    GATE(PCLK_MIPI_DCPHY0, "pclk_mipi_dcphy0", "pclk_top_root", RK3588_CLKGATE_CON(3), 14),
+    GATE(PCLK_MIPI_DCPHY1, "pclk_mipi_dcphy1", "pclk_top_root", RK3588_CLKGATE_CON(4), 3),
+    GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_top_root", RK3588_CLKGATE_CON(1), 6),
+    GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_top_root", RK3588_CLKGATE_CON(1), 8),
+    GATE(PCLK_CRU, "pclk_cru", "pclk_top_root", RK3588_CLKGATE_CON(5), 0),
+
+    /* bigcore0 */
+    GATE(PCLK_BIGCORE0_PVTM, "pclk_bigcore0_pvtm", "pclk_bigcore0_root", RK3588_BIGCORE0_CLKGATE_CON(1), 0),
+    GATE(CLK_BIGCORE0_PVTM, "clk_bigcore0_pvtm", "xin24m", RK3588_BIGCORE0_CLKGATE_CON(0), 12),
+    GATE(CLK_CORE_BIGCORE0_PVTM, "clk_core_bigcore0_pvtm", "armclk_b01", RK3588_BIGCORE0_CLKGATE_CON(0), 13),
+
+    /* bigcore1 */
+    GATE(PCLK_BIGCORE1_PVTM, "pclk_bigcore1_pvtm", "pclk_bigcore1_root", RK3588_BIGCORE1_CLKGATE_CON(1), 0),
+    GATE(CLK_BIGCORE1_PVTM, "clk_bigcore1_pvtm", "xin24m", RK3588_BIGCORE1_CLKGATE_CON(0), 12),
+    GATE(CLK_CORE_BIGCORE1_PVTM, "clk_core_bigcore1_pvtm", "armclk_b23", RK3588_BIGCORE1_CLKGATE_CON(0), 13),
+
+    /* dsu */
+    GATE(PCLK_LITCORE_PVTM, "pclk_litcore_pvtm", "pclk_dsu_ns_root", RK3588_DSU_CLKGATE_CON(2), 6),
+    GATE(PCLK_DBG, "pclk_dbg", "pclk_dsu_root", RK3588_DSU_CLKGATE_CON(1), 7),
+    GATE(PCLK_DSU, "pclk_dsu", "pclk_dsu_root", RK3588_DSU_CLKGATE_CON(1), 6),
+    GATE(PCLK_S_DAPLITE, "pclk_s_daplite", "pclk_dsu_ns_root", RK3588_DSU_CLKGATE_CON(1), 8),
+    GATE(PCLK_M_DAPLITE, "pclk_m_daplite", "pclk_dsu_root", RK3588_DSU_CLKGATE_CON(1), 9),
+    GATE(CLK_LITCORE_PVTM, "clk_litcore_pvtm", "xin24m", RK3588_DSU_CLKGATE_CON(2), 0),
+    GATE(CLK_CORE_LITCORE_PVTM, "clk_core_litcore_pvtm", "armclk_l", RK3588_DSU_CLKGATE_CON(2), 1),
+
+    /* audio */
+    GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_audio_root", RK3588_CLKGATE_CON(7), 12),
+    GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_audio_root", RK3588_CLKGATE_CON(7), 13),
+    GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", RK3588_CLKGATE_CON(8), 0),
+    GATE(MCLK_I2S3_2CH, "mclk_i2s3_2ch", "clk_i2s3_2ch", RK3588_CLKGATE_CON(8), 3),
+    GATE(CLK_DAC_ACDCDIG, "clk_dac_acdcdig", "mclk_i2s3_2ch", RK3588_CLKGATE_CON(8), 4),
+    GATE(PCLK_ACDCDIG, "pclk_acdcdig", "pclk_audio_root", RK3588_CLKGATE_CON(7), 11),
+    GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio_root", RK3588_CLKGATE_CON(7), 4),
+
+    GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", RK3588_CLKGATE_CON(7), 7),
+
+    GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", RK3588_CLKGATE_CON(7), 10),
+
+    GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", RK3588_CLKGATE_CON(9), 6),
+
+    GATE(HCLK_SPDIF0, "hclk_spdif0", "hclk_audio_root", RK3588_CLKGATE_CON(8), 14),
+    GATE(MCLK_SPDIF0, "mclk_spdif0", "clk_spdif0", RK3588_CLKGATE_CON(9), 1),
+
+    GATE(HCLK_SPDIF1, "hclk_spdif1", "hclk_audio_root", RK3588_CLKGATE_CON(9), 2),
+    GATE(MCLK_SPDIF1, "mclk_spdif1", "clk_spdif1", RK3588_CLKGATE_CON(9), 5),
+
+    /* bus */
+    GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_top_root", RK3588_CLKGATE_CON(16), 11),
+    GATE(PCLK_MAILBOX1, "pclk_mailbox1", "pclk_top_root", RK3588_CLKGATE_CON(16), 12),
+    GATE(PCLK_MAILBOX2, "pclk_mailbox2", "pclk_top_root", RK3588_CLKGATE_CON(16), 13),
+    GATE(PCLK_PMU2, "pclk_pmu2", "pclk_top_root", RK3588_CLKGATE_CON(19), 3),
+    GATE(PCLK_PMUCM0_INTMUX, "pclk_pmucm0_intmux", "pclk_top_root", RK3588_CLKGATE_CON(19), 4),
+    GATE(PCLK_DDRCM0_INTMUX, "pclk_ddrcm0_intmux", "pclk_top_root", RK3588_CLKGATE_CON(19), 5),
+
+    GATE(PCLK_PWM1, "pclk_pwm1", "pclk_top_root", RK3588_CLKGATE_CON(15), 3),
+    GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", RK3588_CLKGATE_CON(15), 5),
+    GATE(PCLK_PWM2, "pclk_pwm2", "pclk_top_root", RK3588_CLKGATE_CON(15), 6),
+    GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", RK3588_CLKGATE_CON(15), 8),
+    GATE(PCLK_PWM3, "pclk_pwm3", "pclk_top_root", RK3588_CLKGATE_CON(15), 9),
+    GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", RK3588_CLKGATE_CON(15), 11),
+
+    GATE(PCLK_BUSTIMER0, "pclk_bustimer0", "pclk_top_root", RK3588_CLKGATE_CON(15), 12),
+    GATE(PCLK_BUSTIMER1, "pclk_bustimer1", "pclk_top_root", RK3588_CLKGATE_CON(15), 13),
+    GATE(CLK_BUSTIMER0, "clk_bustimer0", "clk_bus_timer_root", RK3588_CLKGATE_CON(15), 15),
+    GATE(CLK_BUSTIMER1, "clk_bustimer1", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 0),
+    GATE(CLK_BUSTIMER2, "clk_bustimer2", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 1),
+    GATE(CLK_BUSTIMER3, "clk_bustimer3", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 2),
+    GATE(CLK_BUSTIMER4, "clk_bustimer4", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 3),
+    GATE(CLK_BUSTIMER5, "clk_bustimer5", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 4),
+    GATE(CLK_BUSTIMER6, "clk_bustimer6", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 5),
+    GATE(CLK_BUSTIMER7, "clk_bustimer7", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 6),
+    GATE(CLK_BUSTIMER8, "clk_bustimer8", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 7),
+    GATE(CLK_BUSTIMER9, "clk_bustimer9", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 8),
+    GATE(CLK_BUSTIMER10, "clk_bustimer10", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 9),
+    GATE(CLK_BUSTIMER11, "clk_bustimer11", "clk_bus_timer_root", RK3588_CLKGATE_CON(16), 10),
+
+    GATE(PCLK_WDT0, "pclk_wdt0", "pclk_top_root", RK3588_CLKGATE_CON(15), 0),
+    GATE(TCLK_WDT0, "tclk_wdt0", "xin24m", RK3588_CLKGATE_CON(15), 1),
+
+    GATE(PCLK_CAN0, "pclk_can0", "pclk_top_root", RK3588_CLKGATE_CON(11), 8),
+    GATE(CLK_CAN0, "clk_can0", "gpll_cpll_p", RK3588_CLKGATE_CON(11), 9),
+    GATE(PCLK_CAN1, "pclk_can1", "pclk_top_root", RK3588_CLKGATE_CON(11), 10),
+    GATE(CLK_CAN1, "clk_can1", "gpll_cpll_p", RK3588_CLKGATE_CON(11), 11),
+    GATE(PCLK_CAN2, "pclk_can2", "pclk_top_root", RK3588_CLKGATE_CON(11), 12),
+    GATE(CLK_CAN2, "clk_can2", "gpll_cpll_p", RK3588_CLKGATE_CON(11), 13),
+
+    GATE(ACLK_DECOM, "aclk_decom", "aclk_bus_root", RK3588_CLKGATE_CON(17), 6),
+    GATE(PCLK_DECOM, "pclk_decom", "pclk_top_root", RK3588_CLKGATE_CON(17), 7),
+    GATE(DCLK_DECOM, "dclk_decom", "gpll_spll_p", RK3588_CLKGATE_CON(17), 8),
+    GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", RK3588_CLKGATE_CON(10), 5),
+    GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", RK3588_CLKGATE_CON(10), 6),
+    GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_bus_root", RK3588_CLKGATE_CON(10), 7),
+    GATE(ACLK_GIC, "aclk_gic", "aclk_bus_root", RK3588_CLKGATE_CON(10), 3),
+
+    GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_top_root", RK3588_CLKGATE_CON(16), 14),
+    GATE(DBCLK_GPIO1, "dbclk_gpio1", "mux_24m_32k_p", RK3588_CLKGATE_CON(16), 15),
+    GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_top_root", RK3588_CLKGATE_CON(17), 0),
+    GATE(DBCLK_GPIO2, "dbclk_gpio2", "mux_24m_32k_p", RK3588_CLKGATE_CON(17), 1),
+    GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_top_root", RK3588_CLKGATE_CON(17), 2),
+    GATE(DBCLK_GPIO3, "dbclk_gpio3", "mux_24m_32k_p", RK3588_CLKGATE_CON(17), 3),
+    GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_top_root", RK3588_CLKGATE_CON(17), 4),
+    GATE(DBCLK_GPIO4, "dbclk_gpio4", "mux_24m_32k_p", RK3588_CLKGATE_CON(17), 5),
+
+    GATE(PCLK_I2C1, "pclk_i2c1", "pclk_top_root", RK3588_CLKGATE_CON(10), 8),
+    GATE(PCLK_I2C2, "pclk_i2c2", "pclk_top_root", RK3588_CLKGATE_CON(10), 9),
+    GATE(PCLK_I2C3, "pclk_i2c3", "pclk_top_root", RK3588_CLKGATE_CON(10), 10),
+    GATE(PCLK_I2C4, "pclk_i2c4", "pclk_top_root", RK3588_CLKGATE_CON(10), 11),
+    GATE(PCLK_I2C5, "pclk_i2c5", "pclk_top_root", RK3588_CLKGATE_CON(10), 12),
+    GATE(PCLK_I2C6, "pclk_i2c6", "pclk_top_root", RK3588_CLKGATE_CON(10), 13),
+    GATE(PCLK_I2C7, "pclk_i2c7", "pclk_top_root", RK3588_CLKGATE_CON(10), 14),
+    GATE(PCLK_I2C8, "pclk_i2c8", "pclk_top_root", RK3588_CLKGATE_CON(10), 15),
+    GATE(CLK_I2C1, "clk_i2c1", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 0),
+    GATE(CLK_I2C2, "clk_i2c2", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 1),
+    GATE(CLK_I2C3, "clk_i2c3", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 2),
+    GATE(CLK_I2C4, "clk_i2c4", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 3),
+    GATE(CLK_I2C5, "clk_i2c5", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 4),
+    GATE(CLK_I2C6, "clk_i2c6", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 5),
+    GATE(CLK_I2C7, "clk_i2c7", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 6),
+    GATE(CLK_I2C8, "clk_i2c8", "mux_200m_100m_p", RK3588_CLKGATE_CON(11), 7),
+
+    GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_top_root", RK3588_CLKGATE_CON(18), 9),
+    GATE(CLK_OTPC_NS, "clk_otpc_ns", "xin24m", RK3588_CLKGATE_CON(18), 10),
+    GATE(CLK_OTPC_ARB, "clk_otpc_arb", "xin24m", RK3588_CLKGATE_CON(18), 11),
+    GATE(CLK_OTP_PHY_G, "clk_otp_phy_g", "xin24m", RK3588_CLKGATE_CON(18), 13),
+    GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", RK3588_CLKGATE_CON(18), 12),
+
+    GATE(PCLK_SARADC, "pclk_saradc", "pclk_top_root", RK3588_CLKGATE_CON(11), 14),
+    GATE(CLK_SARADC, "clk_saradc", "gpll_24m_p", RK3588_CLKGATE_CON(11), 15),
+
+    GATE(PCLK_SPI0, "pclk_spi0", "pclk_top_root", RK3588_CLKGATE_CON(14), 6),
+    GATE(PCLK_SPI1, "pclk_spi1", "pclk_top_root", RK3588_CLKGATE_CON(14), 7),
+    GATE(PCLK_SPI2, "pclk_spi2", "pclk_top_root", RK3588_CLKGATE_CON(14), 8),
+    GATE(PCLK_SPI3, "pclk_spi3", "pclk_top_root", RK3588_CLKGATE_CON(14), 9),
+    GATE(PCLK_SPI4, "pclk_spi4", "pclk_top_root", RK3588_CLKGATE_CON(14), 10),
+    GATE(CLK_SPI0, "clk_spi0", "mux_200m_150m_24m_p", RK3588_CLKGATE_CON(14), 11),
+    GATE(CLK_SPI1, "clk_spi1", "mux_200m_150m_24m_p", RK3588_CLKGATE_CON(14), 12),
+    GATE(CLK_SPI2, "clk_spi2", "mux_200m_150m_24m_p", RK3588_CLKGATE_CON(14), 13),
+    GATE(CLK_SPI3, "clk_spi3", "mux_200m_150m_24m_p", RK3588_CLKGATE_CON(14), 14),
+    GATE(CLK_SPI4, "clk_spi4", "mux_200m_150m_24m_p", RK3588_CLKGATE_CON(14), 15),
+
+    GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_bus_root", RK3588_CLKGATE_CON(18), 6),
+    GATE(PCLK_TSADC, "pclk_tsadc", "pclk_top_root", RK3588_CLKGATE_CON(12), 0),
+    GATE(CLK_TSADC, "clk_tsadc", "gpll_24m_p", RK3588_CLKGATE_CON(12), 1),
+
+    GATE(PCLK_UART1, "pclk_uart1", "pclk_top_root", RK3588_CLKGATE_CON(12), 2),
+    GATE(PCLK_UART2, "pclk_uart2", "pclk_top_root", RK3588_CLKGATE_CON(12), 3),
+    GATE(PCLK_UART3, "pclk_uart3", "pclk_top_root", RK3588_CLKGATE_CON(12), 4),
+    GATE(PCLK_UART4, "pclk_uart4", "pclk_top_root", RK3588_CLKGATE_CON(12), 5),
+    GATE(PCLK_UART5, "pclk_uart5", "pclk_top_root", RK3588_CLKGATE_CON(12), 6),
+    GATE(PCLK_UART6, "pclk_uart6", "pclk_top_root", RK3588_CLKGATE_CON(12), 7),
+    GATE(PCLK_UART7, "pclk_uart7", "pclk_top_root", RK3588_CLKGATE_CON(12), 8),
+    GATE(PCLK_UART8, "pclk_uart8", "pclk_top_root", RK3588_CLKGATE_CON(12), 9),
+    GATE(PCLK_UART9, "pclk_uart9", "pclk_top_root", RK3588_CLKGATE_CON(12), 10),
+
+    GATE(CLK_UART1_SRC, "clk_uart1_src", "gpll_cpll_p", RK3588_CLKGATE_CON(12), 11),
+    GATE(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", RK3588_CLKGATE_CON(12), 12),
+    GATE(SCLK_UART1, "sclk_uart1", "clk_uart1", RK3588_CLKGATE_CON(12), 13),
+    GATE(CLK_UART2_SRC, "clk_uart2_src", "gpll_cpll_p", RK3588_CLKGATE_CON(12), 14),
+    GATE(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", RK3588_CLKGATE_CON(12), 15),
+    GATE(SCLK_UART2, "sclk_uart2", "clk_uart2", RK3588_CLKGATE_CON(13), 0),
+    GATE(CLK_UART3_SRC, "clk_uart3_src", "gpll_cpll_p", RK3588_CLKGATE_CON(13), 1),
+    GATE(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", RK3588_CLKGATE_CON(13), 2),
+    GATE(SCLK_UART3, "sclk_uart3", "clk_uart3", RK3588_CLKGATE_CON(13), 3),
+    GATE(CLK_UART4_SRC, "clk_uart4_src", "gpll_cpll_p", RK3588_CLKGATE_CON(13), 4),
+    GATE(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", RK3588_CLKGATE_CON(13), 5),
+    GATE(SCLK_UART4, "sclk_uart4", "clk_uart4", RK3588_CLKGATE_CON(13), 6),
+    GATE(CLK_UART5_SRC, "clk_uart5_src", "gpll_cpll_p", RK3588_CLKGATE_CON(13), 7),
+    GATE(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", RK3588_CLKGATE_CON(13), 8),
+    GATE(SCLK_UART5, "sclk_uart5", "clk_uart5", RK3588_CLKGATE_CON(13), 9),
+    GATE(CLK_UART6_SRC, "clk_uart6_src", "gpll_cpll_p", RK3588_CLKGATE_CON(13), 10),
+    GATE(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", RK3588_CLKGATE_CON(13), 11),
+    GATE(SCLK_UART6, "sclk_uart6", "clk_uart6", RK3588_CLKGATE_CON(13), 12),
+    GATE(CLK_UART7_SRC, "clk_uart7_src", "gpll_cpll_p", RK3588_CLKGATE_CON(13), 13),
+    GATE(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", RK3588_CLKGATE_CON(13), 14),
+    GATE(SCLK_UART7, "sclk_uart7", "clk_uart7", RK3588_CLKGATE_CON(13), 15),
+    GATE(CLK_UART8_SRC, "clk_uart8_src", "gpll_cpll_p", RK3588_CLKGATE_CON(14), 0),
+    GATE(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", RK3588_CLKGATE_CON(14), 1),
+    GATE(SCLK_UART8, "sclk_uart8", "clk_uart8", RK3588_CLKGATE_CON(14), 2),
+    GATE(CLK_UART9_SRC, "clk_uart9_src", "gpll_cpll_p", RK3588_CLKGATE_CON(14), 3),
+    GATE(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", RK3588_CLKGATE_CON(14), 4),
+    GATE(SCLK_UART9, "sclk_uart9", "clk_uart9", RK3588_CLKGATE_CON(14), 5),
+
+    /* center */
+    GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_center_root", RK3588_CLKGATE_CON(69), 5),
+    GATE(ACLK_DDR_SHAREMEM, "aclk_ddr_sharemem", "aclk_center_low_root", RK3588_CLKGATE_CON(69), 6),
+    GATE(FCLK_DDR_CM0_CORE, "fclk_ddr_cm0_core", "hclk_center_root", RK3588_CLKGATE_CON(69), 14),
+    GATE(CLK_DDR_TIMER0, "clk_ddr_timer0", "clk_ddr_timer_root", RK3588_CLKGATE_CON(70), 0),
+    GATE(CLK_DDR_TIMER1, "clk_ddr_timer1", "clk_ddr_timer_root", RK3588_CLKGATE_CON(70), 1),
+    GATE(TCLK_WDT_DDR, "tclk_wdt_ddr", "xin24m", RK3588_CLKGATE_CON(70), 2),
+    GATE(PCLK_WDT, "pclk_wdt", "pclk_center_root", RK3588_CLKGATE_CON(70), 7),
+    GATE(PCLK_TIMER, "pclk_timer", "pclk_center_root", RK3588_CLKGATE_CON(70), 8),
+    GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_center_root", RK3588_CLKGATE_CON(70), 9),
+    GATE(PCLK_SHAREMEM, "pclk_sharemem", "pclk_center_root", RK3588_CLKGATE_CON(70), 10),
+
+    /* gpu */
+    GATE(CLK_GPU, "clk_gpu", "clk_gpu_src", RK3588_CLKGATE_CON(66), 4),
+    GATE(CLK_GPU_COREGROUP, "clk_gpu_coregroup", "clk_gpu_src", RK3588_CLKGATE_CON(66), 6),
+    GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", RK3588_CLKGATE_CON(67), 0),
+    GATE(CLK_CORE_GPU_PVTM, "clk_core_gpu_pvtm", "clk_gpu_src", RK3588_CLKGATE_CON(67), 1),
+
+    /* isp1 */
+    GATE(CLK_ISP1_CORE_MARVIN, "clk_isp1_core_marvin", "clk_isp1_core", RK3588_CLKGATE_CON(26), 3),
+    GATE(CLK_ISP1_CORE_VICAP, "clk_isp1_core_vicap", "clk_isp1_core", RK3588_CLKGATE_CON(26), 4),
+
+    /* npu */
+    GATE(ACLK_NPU1, "aclk_npu1", "clk_npu_dsu0", RK3588_CLKGATE_CON(27), 0),
+    GATE(HCLK_NPU1, "hclk_npu1", "hclk_npu_root", RK3588_CLKGATE_CON(27), 2),
+    GATE(ACLK_NPU2, "aclk_npu2", "clk_npu_dsu0", RK3588_CLKGATE_CON(28), 0),
+    GATE(HCLK_NPU2, "hclk_npu2", "hclk_npu_root", RK3588_CLKGATE_CON(28), 2),
+    GATE(FCLK_NPU_CM0_CORE, "fclk_npu_cm0_core", "hclk_npu_cm0_root", RK3588_CLKGATE_CON(30), 3),
+    GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_root", RK3588_CLKGATE_CON(29), 12),
+    GATE(PCLK_NPU_GRF, "pclk_npu_grf", "pclk_npu_root", RK3588_CLKGATE_CON(29), 13),
+    GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", RK3588_CLKGATE_CON(29), 14),
+    GATE(CLK_CORE_NPU_PVTM, "clk_core_npu_pvtm", "clk_npu_dsu0", RK3588_CLKGATE_CON(29), 15),
+    GATE(ACLK_NPU0, "aclk_npu0", "clk_npu_dsu0", RK3588_CLKGATE_CON(30), 6),
+    GATE(HCLK_NPU0, "hclk_npu0", "hclk_npu_root", RK3588_CLKGATE_CON(30), 8),
+    GATE(PCLK_NPU_TIMER, "pclk_npu_timer", "pclk_npu_root", RK3588_CLKGATE_CON(29), 6),
+    GATE(CLK_NPUTIMER0, "clk_nputimer0", "clk_nputimer_root", RK3588_CLKGATE_CON(29), 8),
+    GATE(CLK_NPUTIMER1, "clk_nputimer1", "clk_nputimer_root", RK3588_CLKGATE_CON(29), 9),
+    GATE(PCLK_NPU_WDT, "pclk_npu_wdt", "pclk_npu_root", RK3588_CLKGATE_CON(29), 10),
+    GATE(TCLK_NPU_WDT, "tclk_npu_wdt", "xin24m", RK3588_CLKGATE_CON(29), 11),
+
+    /* nvm */
+    GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", RK3588_CLKGATE_CON(31), 5),
+    GATE(TMCLK_EMMC, "tmclk_emmc", "xin24m", RK3588_CLKGATE_CON(31), 8),
+
+
+    /* php */
+    GATE(ACLK_PHP_GIC_ITS, "aclk_php_gic_its", "aclk_pcie_root", RK3588_CLKGATE_CON(34), 6),
+    GATE(ACLK_PCIE_BRIDGE, "aclk_pcie_bridge", "aclk_pcie_root", RK3588_CLKGATE_CON(32), 8),
+    GATE(ACLK_MMU_PCIE, "aclk_mmu_pcie", "aclk_pcie_bridge", RK3588_CLKGATE_CON(34), 7),
+    GATE(ACLK_MMU_PHP, "aclk_mmu_php", "aclk_php_root", RK3588_CLKGATE_CON(34), 8),
+    GATE(ACLK_PCIE_4L_DBI, "aclk_pcie_4l_dbi", "aclk_php_root", RK3588_CLKGATE_CON(32), 13),
+    GATE(ACLK_PCIE_2L_DBI, "aclk_pcie_2l_dbi", "aclk_php_root", RK3588_CLKGATE_CON(32), 14),
+    GATE(ACLK_PCIE_1L0_DBI, "aclk_pcie_1l0_dbi", "aclk_php_root", RK3588_CLKGATE_CON(32), 15),
+    GATE(ACLK_PCIE_1L1_DBI, "aclk_pcie_1l1_dbi", "aclk_php_root", RK3588_CLKGATE_CON(33), 0),
+    GATE(ACLK_PCIE_1L2_DBI, "aclk_pcie_1l2_dbi", "aclk_php_root", RK3588_CLKGATE_CON(33), 1),
+    GATE(ACLK_PCIE_4L_MSTR, "aclk_pcie_4l_mstr", "aclk_mmu_pcie", RK3588_CLKGATE_CON(33), 2),
+    GATE(ACLK_PCIE_2L_MSTR, "aclk_pcie_2l_mstr", "aclk_mmu_pcie", RK3588_CLKGATE_CON(33), 3),
+    GATE(ACLK_PCIE_1L0_MSTR, "aclk_pcie_1l0_mstr", "aclk_mmu_pcie", RK3588_CLKGATE_CON(33), 4),
+    GATE(ACLK_PCIE_1L1_MSTR, "aclk_pcie_1l1_mstr", "aclk_mmu_pcie", RK3588_CLKGATE_CON(33), 5),
+    GATE(ACLK_PCIE_1L2_MSTR, "aclk_pcie_1l2_mstr", "aclk_mmu_pcie", RK3588_CLKGATE_CON(33), 6),
+    GATE(ACLK_PCIE_4L_SLV, "aclk_pcie_4l_slv", "aclk_php_root", RK3588_CLKGATE_CON(33), 7),
+    GATE(ACLK_PCIE_2L_SLV, "aclk_pcie_2l_slv", "aclk_php_root", RK3588_CLKGATE_CON(33), 8),
+    GATE(ACLK_PCIE_1L0_SLV, "aclk_pcie_1l0_slv", "aclk_php_root", RK3588_CLKGATE_CON(33), 9),
+    GATE(ACLK_PCIE_1L1_SLV, "aclk_pcie_1l1_slv", "aclk_php_root", RK3588_CLKGATE_CON(33), 10),
+    GATE(ACLK_PCIE_1L2_SLV, "aclk_pcie_1l2_slv", "aclk_php_root", RK3588_CLKGATE_CON(33), 11),
+    GATE(PCLK_PCIE_4L, "pclk_pcie_4l", "pclk_php_root", RK3588_CLKGATE_CON(33), 12),
+    GATE(PCLK_PCIE_2L, "pclk_pcie_2l", "pclk_php_root", RK3588_CLKGATE_CON(33), 13),
+    GATE(PCLK_PCIE_1L0, "pclk_pcie_1l0", "pclk_php_root", RK3588_CLKGATE_CON(33), 14),
+    GATE(PCLK_PCIE_1L1, "pclk_pcie_1l1", "pclk_php_root", RK3588_CLKGATE_CON(33), 15),
+    GATE(PCLK_PCIE_1L2, "pclk_pcie_1l2", "pclk_php_root", RK3588_CLKGATE_CON(34), 0),
+    GATE(CLK_PCIE_AUX0, "clk_pcie_aux0", "xin24m", RK3588_CLKGATE_CON(34), 1),
+    GATE(CLK_PCIE_AUX1, "clk_pcie_aux1", "xin24m", RK3588_CLKGATE_CON(34), 2),
+    GATE(CLK_PCIE_AUX2, "clk_pcie_aux2", "xin24m", RK3588_CLKGATE_CON(34), 3),
+    GATE(CLK_PCIE_AUX3, "clk_pcie_aux3", "xin24m", RK3588_CLKGATE_CON(34), 4),
+    GATE(CLK_PCIE_AUX4, "clk_pcie_aux4", "xin24m", RK3588_CLKGATE_CON(34), 5),
+    GATE(CLK_PIPEPHY0_REF, "clk_pipephy0_ref", "xin24m", RK3588_CLKGATE_CON(37), 0),
+    GATE(CLK_PIPEPHY1_REF, "clk_pipephy1_ref", "xin24m", RK3588_CLKGATE_CON(37), 1),
+    GATE(CLK_PIPEPHY2_REF, "clk_pipephy2_ref", "xin24m", RK3588_CLKGATE_CON(37), 2),
+    GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php_root", RK3588_CLKGATE_CON(32), 3),
+    GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_php_root", RK3588_CLKGATE_CON(32), 4),
+    GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_mmu_php", RK3588_CLKGATE_CON(32), 10),
+    GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_mmu_php", RK3588_CLKGATE_CON(32), 11),
+    GATE(CLK_PMALIVE0, "clk_pmalive0", "xin24m", RK3588_CLKGATE_CON(37), 4),
+    GATE(CLK_PMALIVE1, "clk_pmalive1", "xin24m", RK3588_CLKGATE_CON(37), 5),
+    GATE(CLK_PMALIVE2, "clk_pmalive2", "xin24m", RK3588_CLKGATE_CON(37), 6),
+    GATE(ACLK_SATA0, "aclk_sata0", "aclk_mmu_php", RK3588_CLKGATE_CON(37), 7),
+    GATE(ACLK_SATA1, "aclk_sata1", "aclk_mmu_php", RK3588_CLKGATE_CON(37), 8),
+    GATE(ACLK_SATA2, "aclk_sata2", "aclk_mmu_php", RK3588_CLKGATE_CON(37), 9),
+    GATE(ACLK_USB3OTG2, "aclk_usb3otg2", "aclk_mmu_php", RK3588_CLKGATE_CON(35), 7),
+    GATE(SUSPEND_CLK_USB3OTG2, "suspend_clk_usb3otg2", "xin24m", RK3588_CLKGATE_CON(35), 8),
+    GATE(REF_CLK_USB3OTG2, "ref_clk_usb3otg2", "xin24m", RK3588_CLKGATE_CON(35), 9),
+    GATE(PCLK_PCIE_COMBO_PIPE_PHY0, "pclk_pcie_combo_pipe_phy0", "pclk_top_root", RK3588_PHP_CLKGATE_CON(0), 5),
+    GATE(PCLK_PCIE_COMBO_PIPE_PHY1, "pclk_pcie_combo_pipe_phy1", "pclk_top_root", RK3588_PHP_CLKGATE_CON(0), 6),
+    GATE(PCLK_PCIE_COMBO_PIPE_PHY2, "pclk_pcie_combo_pipe_phy2", "pclk_top_root", RK3588_PHP_CLKGATE_CON(0), 7),
+    GATE(PCLK_PCIE_COMBO_PIPE_PHY, "pclk_pcie_combo_pipe_phy", "pclk_top_root", RK3588_PHP_CLKGATE_CON(0), 8),
+
+    /* rga */
+    GATE(HCLK_RGA3_1, "hclk_rga3_1", "hclk_rga3_root", RK3588_CLKGATE_CON(76), 4),
+    GATE(ACLK_RGA3_1, "aclk_rga3_1", "aclk_rga3_root", RK3588_CLKGATE_CON(76), 5),
+
+    /* vdec */
+    GATE(SUSPEND_CLK_USB3OTG0, "suspend_clk_usb3otg0", "xin24m", RK3588_CLKGATE_CON(42), 5),
+    GATE(REF_CLK_USB3OTG0, "ref_clk_usb3otg0", "xin24m", RK3588_CLKGATE_CON(42), 6),
+    GATE(SUSPEND_CLK_USB3OTG1, "suspend_clk_usb3otg1", "xin24m", RK3588_CLKGATE_CON(42), 8),
+    GATE(REF_CLK_USB3OTG1, "ref_clk_usb3otg1", "xin24m", RK3588_CLKGATE_CON(42), 9),
+
+    /* vdpu */
+    GATE(HCLK_IEP2P0, "hclk_iep2p0", "hclk_vdpu_root", RK3588_CLKGATE_CON(45), 4),
+    GATE(HCLK_JPEG_ENCODER0, "hclk_jpeg_encoder0", "hclk_vdpu_root", RK3588_CLKGATE_CON(44), 11),
+    GATE(HCLK_JPEG_ENCODER1, "hclk_jpeg_encoder1", "hclk_vdpu_root", RK3588_CLKGATE_CON(44), 13),
+    GATE(HCLK_JPEG_ENCODER2, "hclk_jpeg_encoder2", "hclk_vdpu_root", RK3588_CLKGATE_CON(44), 15),
+    GATE(HCLK_JPEG_ENCODER3, "hclk_jpeg_encoder3", "hclk_vdpu_root", RK3588_CLKGATE_CON(45), 1),
+    GATE(HCLK_JPEG_DECODER, "hclk_jpeg_decoder", "hclk_vdpu_root", RK3588_CLKGATE_CON(45), 3),
+    GATE(HCLK_RGA2, "hclk_rga2", "hclk_vdpu_root", RK3588_CLKGATE_CON(45), 7),
+    GATE(ACLK_RGA2, "aclk_rga2", "aclk_vdpu_root", RK3588_CLKGATE_CON(45), 8),
+    GATE(HCLK_RGA3_0, "hclk_rga3_0", "hclk_vdpu_root", RK3588_CLKGATE_CON(45), 10),
+    GATE(ACLK_RGA3_0, "aclk_rga3_0", "aclk_vdpu_root", RK3588_CLKGATE_CON(45), 11),
+    GATE(HCLK_VPU, "hclk_vpu", "hclk_vdpu_root", RK3588_CLKGATE_CON(44), 9),
+
+    /* venc */
+    GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", RK3588_CLKGATE_CON(47), 4),
+    GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", RK3588_CLKGATE_CON(47), 5),
+
+    /* vi */
+    GATE(ICLK_CSIHOST0, "iclk_csihost0", "iclk_csihost01", RK3588_CLKGATE_CON(51), 11),
+    GATE(ICLK_CSIHOST1, "iclk_csihost1", "iclk_csihost01", RK3588_CLKGATE_CON(51), 12),
+    GATE(PCLK_CSI_HOST_0, "pclk_csi_host_0", "pclk_vi_root", RK3588_CLKGATE_CON(50), 4),
+    GATE(PCLK_CSI_HOST_1, "pclk_csi_host_1", "pclk_vi_root", RK3588_CLKGATE_CON(50), 5),
+    GATE(PCLK_CSI_HOST_2, "pclk_csi_host_2", "pclk_vi_root", RK3588_CLKGATE_CON(50), 6),
+    GATE(PCLK_CSI_HOST_3, "pclk_csi_host_3", "pclk_vi_root", RK3588_CLKGATE_CON(50), 7),
+    GATE(PCLK_CSI_HOST_4, "pclk_csi_host_4", "pclk_vi_root", RK3588_CLKGATE_CON(50), 8),
+    GATE(PCLK_CSI_HOST_5, "pclk_csi_host_5", "pclk_vi_root", RK3588_CLKGATE_CON(50), 9),
+    GATE(ACLK_FISHEYE0, "aclk_fisheye0", "aclk_vi_root", RK3588_CLKGATE_CON(49), 14),
+    GATE(HCLK_FISHEYE0, "hclk_fisheye0", "hclk_vi_root", RK3588_CLKGATE_CON(49), 15),
+    GATE(ACLK_FISHEYE1, "aclk_fisheye1", "aclk_vi_root", RK3588_CLKGATE_CON(50), 1),
+    GATE(HCLK_FISHEYE1, "hclk_fisheye1", "hclk_vi_root", RK3588_CLKGATE_CON(50), 2),
+    GATE(CLK_ISP0_CORE_MARVIN, "clk_isp0_core_marvin", "clk_isp0_core", RK3588_CLKGATE_CON(49), 10),
+    GATE(CLK_ISP0_CORE_VICAP, "clk_isp0_core_vicap", "clk_isp0_core", RK3588_CLKGATE_CON(49), 11),
+    GATE(ACLK_ISP0, "aclk_isp0", "aclk_vi_root", RK3588_CLKGATE_CON(49), 12),
+    GATE(HCLK_ISP0, "hclk_isp0", "hclk_vi_root", RK3588_CLKGATE_CON(49), 13),
+    GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", RK3588_CLKGATE_CON(49), 7),
+    GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", RK3588_CLKGATE_CON(49), 8),
+
+    /* vo0 */
+    GATE(PCLK_DP0, "pclk_dp0", "pclk_vo0_root", RK3588_CLKGATE_CON(56), 4),
+    GATE(PCLK_DP1, "pclk_dp1", "pclk_vo0_root", RK3588_CLKGATE_CON(56), 5),
+    GATE(PCLK_S_DP0, "pclk_s_dp0", "pclk_vo0_s_root", RK3588_CLKGATE_CON(56), 6),
+    GATE(PCLK_S_DP1, "pclk_s_dp1", "pclk_vo0_s_root", RK3588_CLKGATE_CON(56), 7),
+    GATE(CLK_DP0, "clk_dp0", "aclk_vo0_root", RK3588_CLKGATE_CON(56), 8),
+    GATE(CLK_DP1, "clk_dp1", "aclk_vo0_root", RK3588_CLKGATE_CON(56), 9),
+    GATE(HCLK_HDCP_KEY0, "hclk_hdcp_key0", "hclk_vo0_s_root", RK3588_CLKGATE_CON(55), 11),
+    GATE(PCLK_HDCP0, "pclk_hdcp0", "pclk_vo0_root", RK3588_CLKGATE_CON(55), 14),
+    GATE(ACLK_TRNG0, "aclk_trng0", "aclk_vo0_root", RK3588_CLKGATE_CON(56), 0),
+    GATE(PCLK_TRNG0, "pclk_trng0", "pclk_vo0_root", RK3588_CLKGATE_CON(56), 1),
+    GATE(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", RK3588_CLKGATE_CON(55), 10),
+    GATE(MCLK_I2S4_8CH_TX, "mclk_i2s4_8ch_tx", "clk_i2s4_8ch_tx", RK3588_CLKGATE_CON(56), 13),
+    GATE(MCLK_I2S8_8CH_TX, "mclk_i2s8_8ch_tx", "clk_i2s8_8ch_tx", RK3588_CLKGATE_CON(57), 1),
+    GATE(MCLK_SPDIF2_DP0, "mclk_spdif2_dp0", "clk_spdif2_dp0", RK3588_CLKGATE_CON(57), 5),
+    GATE(MCLK_SPDIF2, "mclk_spdif2", "clk_spdif2_dp0", RK3588_CLKGATE_CON(57), 6),
+    GATE(MCLK_SPDIF5_DP1, "mclk_spdif5_dp1", "clk_spdif5_dp1", RK3588_CLKGATE_CON(57), 10),
+    GATE(MCLK_SPDIF5, "mclk_spdif5", "clk_spdif5_dp1", RK3588_CLKGATE_CON(57), 11),
+
+    /* vo1 */
+    GATE(PCLK_EDP0, "pclk_edp0", "pclk_vo1_root", RK3588_CLKGATE_CON(62), 0),
+    GATE(CLK_EDP0_24M, "clk_edp0_24m", "xin24m", RK3588_CLKGATE_CON(62), 1),
+    GATE(PCLK_EDP1, "pclk_edp1", "pclk_vo1_root", RK3588_CLKGATE_CON(62), 3),
+    GATE(CLK_EDP1_24M, "clk_edp1_24m", "xin24m", RK3588_CLKGATE_CON(62), 4),
+    GATE(HCLK_HDCP_KEY1, "hclk_hdcp_key1", "hclk_vo1_s_root", RK3588_CLKGATE_CON(60), 4),
+    GATE(PCLK_HDCP1, "pclk_hdcp1", "pclk_vo1_root", RK3588_CLKGATE_CON(60), 7),
+    GATE(ACLK_HDMIRX, "aclk_hdmirx", "aclk_hdmirx_root", RK3588_CLKGATE_CON(61), 9),
+    GATE(PCLK_HDMIRX, "pclk_hdmirx", "pclk_vo1_root", RK3588_CLKGATE_CON(61), 10),
+    GATE(CLK_HDMIRX_REF, "clk_hdmirx_ref", "aclk_hdcp1_root", RK3588_CLKGATE_CON(61), 11),
+    GATE(CLK_HDMIRX_AUD, "clk_hdmirx_aud", "clk_hdmirx_aud_mux", RK3588_CLKGATE_CON(61), 14),
+    GATE(PCLK_HDMITX0, "pclk_hdmitx0", "pclk_vo1_root", RK3588_CLKGATE_CON(60), 11),
+    GATE(CLK_HDMITX0_REF, "clk_hdmitx0_ref", "aclk_hdcp1_root", RK3588_CLKGATE_CON(61), 0),
+    GATE(PCLK_HDMITX1, "pclk_hdmitx1", "pclk_vo1_root", RK3588_CLKGATE_CON(61), 2),
+    GATE(CLK_HDMITX1_REF, "clk_hdmitx1_ref", "aclk_hdcp1_root", RK3588_CLKGATE_CON(61), 7),
+    GATE(ACLK_TRNG1, "aclk_trng1", "aclk_hdcp1_root", RK3588_CLKGATE_CON(60), 9),
+    GATE(PCLK_TRNG1, "pclk_trng1", "pclk_vo1_root", RK3588_CLKGATE_CON(60), 10),
+    GATE(0, "pclk_vo1grf", "pclk_vo1_root", RK3588_CLKGATE_CON(59), 12),
+    GATE(PCLK_S_EDP0, "pclk_s_edp0", "pclk_vo1_s_root", RK3588_CLKGATE_CON(59), 14),
+    GATE(PCLK_S_EDP1, "pclk_s_edp1", "pclk_vo1_s_root", RK3588_CLKGATE_CON(59), 15),
+    GATE(PCLK_S_HDMIRX, "pclk_s_hdmirx", "pclk_vo1_s_root", RK3588_CLKGATE_CON(65), 8),
+    GATE(MCLK_I2S10_8CH_RX, "mclk_i2s10_8ch_rx", "clk_i2s10_8ch_rx", RK3588_CLKGATE_CON(65), 7),
+    GATE(MCLK_I2S7_8CH_RX, "mclk_i2s7_8ch_rx", "clk_i2s7_8ch_rx", RK3588_CLKGATE_CON(60), 3),
+    GATE(MCLK_I2S9_8CH_RX, "mclk_i2s9_8ch_rx", "clk_i2s9_8ch_rx", RK3588_CLKGATE_CON(65), 3),
+    GATE(MCLK_I2S5_8CH_TX, "mclk_i2s5_8ch_tx", "clk_i2s5_8ch_tx", RK3588_CLKGATE_CON(62), 8),
+    GATE(MCLK_I2S6_8CH_TX, "mclk_i2s6_8ch_tx", "clk_i2s6_8ch_tx", RK3588_CLKGATE_CON(62), 15),
+    GATE(MCLK_I2S6_8CH_RX, "mclk_i2s6_8ch_rx", "clk_i2s6_8ch_rx", RK3588_CLKGATE_CON(63), 2),
+    GATE(MCLK_SPDIF3, "mclk_spdif3", "clk_spdif3", RK3588_CLKGATE_CON(63), 7),
+    GATE(MCLK_SPDIF4, "mclk_spdif4", "clk_spdif4", RK3588_CLKGATE_CON(63), 11),
+    GATE(CLK_HDMIHDP0, "clk_hdmihdp0", "xin24m", RK3588_CLKGATE_CON(73), 12),
+    GATE(CLK_HDMIHDP1, "clk_hdmihdp1", "xin24m", RK3588_CLKGATE_CON(73), 13),
+    GATE(PCLK_HDPTX0, "pclk_hdptx0", "pclk_top_root", RK3588_CLKGATE_CON(72), 5),
+    GATE(PCLK_HDPTX1, "pclk_hdptx1", "pclk_top_root", RK3588_CLKGATE_CON(72), 6),
+    GATE(PCLK_USBDPPHY0, "pclk_usbdpphy0", "pclk_top_root", RK3588_CLKGATE_CON(72), 2),
+    GATE(PCLK_USBDPPHY1, "pclk_usbdpphy1", "pclk_top_root", RK3588_CLKGATE_CON(72), 4),
+    GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", RK3588_CLKGATE_CON(52), 8),
+    GATE(ACLK_VOP, "aclk_vop", "aclk_vop_sub_src", RK3588_CLKGATE_CON(52), 9),
+    GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vop_root", RK3588_CLKGATE_CON(53), 4),
+    GATE(PCLK_DSIHOST1, "pclk_dsihost1", "pclk_vop_root", RK3588_CLKGATE_CON(53), 5),
+    GATE(CLK_VOP_PMU, "clk_vop_pmu", "xin24m", RK3588_CLKGATE_CON(53), 8),
+    GATE(ACLK_VOP_DOBY, "aclk_vop_doby", "aclk_vop_root", RK3588_CLKGATE_CON(53), 10),
+    GATE(CLK_USBDP_PHY0_IMMORTAL, "clk_usbdp_phy0_immortal", "xin24m", RK3588_CLKGATE_CON(2), 8),
+    GATE(CLK_USBDP_PHY1_IMMORTAL, "clk_usbdp_phy1_immortal", "xin24m", RK3588_CLKGATE_CON(2), 15),
+
+    GATE(CLK_REF_PIPE_PHY0_OSC_SRC, "clk_ref_pipe_phy0_osc_src", "xin24m", RK3588_CLKGATE_CON(77), 0),
+    GATE(CLK_REF_PIPE_PHY1_OSC_SRC, "clk_ref_pipe_phy1_osc_src", "xin24m", RK3588_CLKGATE_CON(77), 1),
+    GATE(CLK_REF_PIPE_PHY2_OSC_SRC, "clk_ref_pipe_phy2_osc_src", "xin24m", RK3588_CLKGATE_CON(77), 2),
+
+    /* pmu */
+    GATE(PCLK_PMU0_ROOT, "pclk_pmu0_root", "pclk_pmu1_root", RK3588_PMU_CLKGATE_CON(5), 0),
+    GATE(CLK_PMU0, "clk_pmu0", "xin24m", RK3588_PMU_CLKGATE_CON(5), 1),
+    GATE(PCLK_PMU0, "pclk_pmu0", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(5), 2),
+    GATE(PCLK_PMU0IOC, "pclk_pmu0ioc", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(5), 4),
+    GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(5), 5),
+    GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(2), 1),
+    GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_pmu1_root", RK3588_PMU_CLKGATE_CON(2), 7),
+    GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", RK3588_PMU_CLKGATE_CON(2), 10),
+    GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", RK3588_PMU_CLKGATE_CON(2), 13),
+    GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(1), 0),
+    GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu0", RK3588_PMU_CLKGATE_CON(1), 1),
+    GATE(CLK_PMU1, "clk_pmu1", "clk_pmu0", RK3588_PMU_CLKGATE_CON(1), 3),
+    GATE(HCLK_PDM0, "hclk_pdm0", "hclk_pmu1_root", RK3588_PMU_CLKGATE_CON(2), 14),
+    GATE(HCLK_VAD, "hclk_vad", "hclk_pmu1_root", RK3588_PMU_CLKGATE_CON(3), 0),
+    GATE(FCLK_PMU_CM0_CORE, "fclk_pmu_cm0_core", "hclk_pmu_cm0_root", RK3588_PMU_CLKGATE_CON(0), 13),
+    GATE(PCLK_PMU1_IOC, "pclk_pmu1_ioc", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(1), 5),
+    GATE(PCLK_PMU1PWM, "pclk_pmu1pwm", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(1), 12),
+    GATE(CLK_PMU1PWM_CAPTURE, "clk_pmu1pwm_capture", "xin24m", RK3588_PMU_CLKGATE_CON(1), 14),
+    GATE(PCLK_PMU1TIMER, "pclk_pmu1timer", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(1), 8),
+    GATE(CLK_PMU1TIMER0, "clk_pmu1timer0", "clk_pmu1timer_root", RK3588_PMU_CLKGATE_CON(1), 10),
+    GATE(CLK_PMU1TIMER1, "clk_pmu1timer1", "clk_pmu1timer_root", RK3588_PMU_CLKGATE_CON(1), 11),
+    GATE(SCLK_UART0, "sclk_uart0", "clk_uart0", RK3588_PMU_CLKGATE_CON(2), 5),
+    GATE(PCLK_UART0, "pclk_uart0", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(2), 6),
+    GATE(PCLK_PMU1WDT, "pclk_pmu1wdt", "pclk_pmu0_root", RK3588_PMU_CLKGATE_CON(1), 6),
+#define RK3588_PHYREF_ALT_GATE      0xc38
+    GATE(CLK_PHY0_REF_ALT_P, "clk_phy0_ref_alt_p", "ppll", RK3588_PHYREF_ALT_GATE, 0),
+    GATE(CLK_PHY0_REF_ALT_M, "clk_phy0_ref_alt_m", "ppll", RK3588_PHYREF_ALT_GATE, 1),
+    GATE(CLK_PHY1_REF_ALT_P, "clk_phy1_ref_alt_p", "ppll", RK3588_PHYREF_ALT_GATE, 2),
+    GATE(CLK_PHY1_REF_ALT_M, "clk_phy1_ref_alt_m", "ppll", RK3588_PHYREF_ALT_GATE, 3),
+
+    GATE(HCLK_SPDIFRX0, "hclk_spdifrx0", "hclk_vo1", RK3588_CLKGATE_CON(63), 12),
+    GATE(HCLK_SPDIFRX1, "hclk_spdifrx1", "hclk_vo1", RK3588_CLKGATE_CON(63), 14),
+    GATE(HCLK_SPDIFRX2, "hclk_spdifrx2", "hclk_vo1", RK3588_CLKGATE_CON(64), 0),
+    GATE(HCLK_SPDIF4, "hclk_spdif4", "hclk_vo1", RK3588_CLKGATE_CON(63), 8),
+    GATE(HCLK_SPDIF3, "hclk_spdif3", "hclk_vo1", RK3588_CLKGATE_CON(63), 4),
+    GATE(HCLK_I2S6_8CH, "hclk_i2s6_8ch", "hclk_vo1", RK3588_CLKGATE_CON(63), 3),
+    GATE(HCLK_I2S5_8CH, "hclk_i2s5_8ch", "hclk_vo1", RK3588_CLKGATE_CON(62), 12),
+    GATE(HCLK_I2S9_8CH, "hclk_i2s9_8ch", "hclk_vo1", RK3588_CLKGATE_CON(65), 0),
+    GATE(HCLK_I2S7_8CH, "hclk_i2s7_8ch", "hclk_vo1", RK3588_CLKGATE_CON(60), 0),
+    GATE(HCLK_I2S10_8CH, "hclk_i2s10_8ch", "hclk_vo1", RK3588_CLKGATE_CON(65), 4),
+    GATE(ACLK_HDCP1, "aclk_hdcp1", "aclk_hdcp1_pre", RK3588_CLKGATE_CON(60), 5),
+    GATE(HCLK_HDCP1, "hclk_hdcp1", "hclk_vo1", RK3588_CLKGATE_CON(60), 6),
+    GATE(HCLK_SPDIF5_DP1, "hclk_spdif5_dp1", "hclk_vo0", RK3588_CLKGATE_CON(57), 7),
+    GATE(HCLK_SPDIF2_DP0, "hclk_spdif2_dp0", "hclk_vo0", RK3588_CLKGATE_CON(57), 2),
+    GATE(HCLK_I2S8_8CH, "hclk_i2s8_8ch", "hclk_vo0", RK3588_CLKGATE_CON(56), 14),
+    GATE(HCLK_I2S4_8CH, "hclk_i2s4_8ch", "hclk_vo0", RK3588_CLKGATE_CON(56), 10),
+    GATE(ACLK_HDCP0, "aclk_hdcp0", "aclk_hdcp0_pre", RK3588_CLKGATE_CON(55), 12),
+    GATE(HCLK_HDCP0, "hclk_hdcp0", "hclk_vo0", RK3588_CLKGATE_CON(55), 13),
+    GATE(HCLK_RKVENC1, "hclk_rkvenc1", "hclk_rkvenc1_pre", RK3588_CLKGATE_CON(48), 4),
+    GATE(ACLK_RKVENC1, "aclk_rkvenc1", "aclk_rkvenc1_pre", RK3588_CLKGATE_CON(48), 5),
+    GATE(ACLK_VPU, "aclk_vpu", "aclk_vdpu_low_pre", RK3588_CLKGATE_CON(44), 8),
+    GATE(ACLK_IEP2P0, "aclk_iep2p0", "aclk_vdpu_low_pre", RK3588_CLKGATE_CON(45), 5),
+    GATE(ACLK_JPEG_ENCODER0, "aclk_jpeg_encoder0", "aclk_vdpu_low_pre", RK3588_CLKGATE_CON(44), 10),
+    GATE(ACLK_JPEG_ENCODER1, "aclk_jpeg_encoder1", "aclk_vdpu_low_pre", RK3588_CLKGATE_CON(44), 12),
+    GATE(ACLK_JPEG_ENCODER2, "aclk_jpeg_encoder2", "aclk_vdpu_low_pre", RK3588_CLKGATE_CON(44), 14),
+    GATE(ACLK_JPEG_ENCODER3, "aclk_jpeg_encoder3", "aclk_vdpu_low_pre", RK3588_CLKGATE_CON(45), 0),
+    GATE(ACLK_JPEG_DECODER, "aclk_jpeg_decoder", "aclk_jpeg_decoder_pre", RK3588_CLKGATE_CON(45), 2),
+    GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb", RK3588_CLKGATE_CON(42), 7),
+    GATE(HCLK_HOST0, "hclk_host0", "hclk_usb", RK3588_CLKGATE_CON(42), 10),
+    GATE(HCLK_HOST_ARB0, "hclk_host_arb0", "hclk_usb", RK3588_CLKGATE_CON(42), 11),
+    GATE(HCLK_HOST1, "hclk_host1", "hclk_usb", RK3588_CLKGATE_CON(42), 12),
+    GATE(HCLK_HOST_ARB1, "hclk_host_arb1", "hclk_usb", RK3588_CLKGATE_CON(42), 13),
+    GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb", RK3588_CLKGATE_CON(42), 4),
+    GATE(HCLK_SDIO, "hclk_sdio", "hclk_sdio_pre", RK3588_CLKGATE_CON(75), 2),
+    GATE(HCLK_RKVDEC1, "hclk_rkvdec1", "hclk_rkvdec1_pre", RK3588_CLKGATE_CON(41), 2),
+    GATE(ACLK_RKVDEC1, "aclk_rkvdec1", "aclk_rkvdec1_pre", RK3588_CLKGATE_CON(41), 3),
+    GATE(HCLK_RKVDEC0, "hclk_rkvdec0", "hclk_rkvdec0_pre", RK3588_CLKGATE_CON(40), 3),
+    GATE(ACLK_RKVDEC0, "aclk_rkvdec0", "aclk_rkvdec0_pre", RK3588_CLKGATE_CON(40), 4),
+    GATE(CLK_PCIE4L_PIPE, "clk_pcie4l_pipe", "clk_pipe30phy_pipe0_i", RK3588_CLKGATE_CON(39), 0),
+    GATE(CLK_PCIE2L_PIPE, "clk_pcie2l_pipe", "clk_pipe30phy_pipe2_i", RK3588_CLKGATE_CON(39), 1),
+    GATE(CLK_PIPEPHY0_PIPE_G, "clk_pipephy0_pipe_g", "clk_pipephy0_pipe_i", RK3588_CLKGATE_CON(38), 3),
+    GATE(CLK_PIPEPHY1_PIPE_G, "clk_pipephy1_pipe_g", "clk_pipephy1_pipe_i", RK3588_CLKGATE_CON(38), 4),
+    GATE(CLK_PIPEPHY2_PIPE_G, "clk_pipephy2_pipe_g", "clk_pipephy2_pipe_i", RK3588_CLKGATE_CON(38), 5),
+    GATE(CLK_PIPEPHY0_PIPE_ASIC_G, "clk_pipephy0_pipe_asic_g", "clk_pipephy0_pipe_i", RK3588_CLKGATE_CON(38), 6),
+    GATE(CLK_PIPEPHY1_PIPE_ASIC_G, "clk_pipephy1_pipe_asic_g", "clk_pipephy1_pipe_i", RK3588_CLKGATE_CON(38), 7),
+    GATE(CLK_PIPEPHY2_PIPE_ASIC_G, "clk_pipephy2_pipe_asic_g", "clk_pipephy2_pipe_i", RK3588_CLKGATE_CON(38), 8),
+    GATE(CLK_PIPEPHY2_PIPE_U3_G, "clk_pipephy2_pipe_u3_g", "clk_pipephy2_pipe_i", RK3588_CLKGATE_CON(38), 9),
+    GATE(CLK_PCIE1L2_PIPE, "clk_pcie1l2_pipe", "clk_pipephy0_pipe_g", RK3588_CLKGATE_CON(38), 13),
+    GATE(CLK_PCIE1L0_PIPE, "clk_pcie1l0_pipe", "clk_pipephy1_pipe_g", RK3588_CLKGATE_CON(38), 14),
+    GATE(CLK_PCIE1L1_PIPE, "clk_pcie1l1_pipe", "clk_pipephy2_pipe_g", RK3588_CLKGATE_CON(38), 15),
+    GATE(HCLK_SFC, "hclk_sfc", "hclk_nvm", RK3588_CLKGATE_CON(31), 10),
+    GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_nvm", RK3588_CLKGATE_CON(31), 11),
+    GATE(HCLK_EMMC, "hclk_emmc", "hclk_nvm", RK3588_CLKGATE_CON(31), 4),
+    GATE(ACLK_ISP1, "aclk_isp1", "aclk_isp1_pre", RK3588_CLKGATE_CON(26), 5),
+    GATE(HCLK_ISP1, "hclk_isp1", "hclk_isp1_pre", RK3588_CLKGATE_CON(26), 7),
+    GATE(PCLK_AV1, "pclk_av1", "pclk_av1_pre", RK3588_CLKGATE_CON(68), 5),
+    GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", RK3588_CLKGATE_CON(68), 2),
+/*
+    GATE(ACLK_ISP1_PRE, "aclk_isp1_pre", "aclk_isp1_root", RK3588_CLKGATE_CON(26), 6),
+    GATE(HCLK_ISP1_PRE, "hclk_isp1_pre", "hclk_isp1_root", RK3588_CLKGATE_CON(26), 8),
+    GATE(HCLK_NVM, "hclk_nvm", "hclk_nvm_root", RK3588_CLKGATE_CON(31), 2),
+    GATE(ACLK_USB, "aclk_usb", "aclk_usb_root", RK3588_CLKGATE_CON(42), 2),
+    GATE(HCLK_USB, "hclk_usb", "hclk_usb_root", RK3588_CLKGATE_CON(42), 3),
+    GATE(ACLK_JPEG_DECODER_PRE, "aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", RK3588_CLKGATE_CON(44), 7),
+    GATE(ACLK_VDPU_LOW_PRE, "aclk_vdpu_low_pre", "aclk_vdpu_low_root", RK3588_CLKGATE_CON(44), 5),
+    GATE(ACLK_RKVENC1_PRE, "aclk_rkvenc1_pre", "aclk_rkvenc1_root", RK3588_CLKGATE_CON(48), 3),
+    GATE(HCLK_RKVENC1_PRE, "hclk_rkvenc1_pre", "hclk_rkvenc1_root", RK3588_CLKGATE_CON(48), 2),
+    GATE(HCLK_RKVDEC0_PRE, "hclk_rkvdec0_pre", "hclk_rkvdec0_root", RK3588_CLKGATE_CON(40), 5),
+    GATE(ACLK_RKVDEC0_PRE, "aclk_rkvdec0_pre", "aclk_rkvdec0_root", RK3588_CLKGATE_CON(40), 6),
+    GATE(HCLK_RKVDEC1_PRE, "hclk_rkvdec1_pre", "hclk_rkvdec1_root", RK3588_CLKGATE_CON(41), 4),
+    GATE(ACLK_RKVDEC1_PRE, "aclk_rkvdec1_pre", "aclk_rkvdec1_root", RK3588_CLKGATE_CON(41), 5),
+    GATE(ACLK_HDCP0_PRE, "aclk_hdcp0_pre", "aclk_vo0_root", RK3588_CLKGATE_CON(55), 9),
+    GATE(HCLK_VO0, "hclk_vo0", "hclk_vo0_root", RK3588_CLKGATE_CON(55), 5),
+    GATE(ACLK_HDCP1_PRE, "aclk_hdcp1_pre", "aclk_hdcp1_root", RK3588_CLKGATE_CON(59), 6),
+    GATE(HCLK_VO1, "hclk_vo1", "hclk_vo1_root", RK3588_CLKGATE_CON(59), 9),
+    GATE(ACLK_AV1_PRE, "aclk_av1_pre", "aclk_av1_root", RK3588_CLKGATE_CON(68), 1),
+    GATE(PCLK_AV1_PRE, "pclk_av1_pre", "pclk_av1_root", RK3588_CLKGATE_CON(68), 4),
+    GATE(HCLK_SDIO_PRE, "hclk_sdio_pre", "hclk_sdio_root", RK3588_CLKGATE_CON(75), 1),
+*/
+};
+
+#include "clk-pll-rk3588.c"
+#include "clk-mmc-phase.c"
+#include "softrst.c"
+
+static rt_ubase_t rk3588_center_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t con, sel, rate;
+
+    switch (clk_id)
+    {
+    case ACLK_CENTER_ROOT:
+        con = HWREG32(&cru->clksel_con[165]);
+        sel = (con & ACLK_CENTER_ROOT_SEL_MASK) >>
+              ACLK_CENTER_ROOT_SEL_SHIFT;
+        if (sel == ACLK_CENTER_ROOT_SEL_700M)
+            rate = 702 * MHz;
+        else if (sel == ACLK_CENTER_ROOT_SEL_400M)
+            rate = 396 * MHz;
+        else if (sel == ACLK_CENTER_ROOT_SEL_200M)
+            rate = 200 * MHz;
+        else
+            rate = OSC_HZ;
+        break;
+    case ACLK_CENTER_LOW_ROOT:
+        con = HWREG32(&cru->clksel_con[165]);
+        sel = (con & ACLK_CENTER_LOW_ROOT_SEL_MASK) >>
+              ACLK_CENTER_LOW_ROOT_SEL_SHIFT;
+        if (sel == ACLK_CENTER_LOW_ROOT_SEL_500M)
+            rate = 500 * MHz;
+        else if (sel == ACLK_CENTER_LOW_ROOT_SEL_250M)
+            rate = 250 * MHz;
+        else if (sel == ACLK_CENTER_LOW_ROOT_SEL_100M)
+            rate = 100 * MHz;
+        else
+            rate = OSC_HZ;
+        break;
+    case HCLK_CENTER_ROOT:
+        con = HWREG32(&cru->clksel_con[165]);
+        sel = (con & HCLK_CENTER_ROOT_SEL_MASK) >>
+              HCLK_CENTER_ROOT_SEL_SHIFT;
+        if (sel == HCLK_CENTER_ROOT_SEL_400M)
+            rate = 396 * MHz;
+        else if (sel == HCLK_CENTER_ROOT_SEL_200M)
+            rate = 200 * MHz;
+        else if (sel == HCLK_CENTER_ROOT_SEL_100M)
+            rate = 100 * MHz;
+        else
+            rate = OSC_HZ;
+        break;
+    case PCLK_CENTER_ROOT:
+        con = HWREG32(&cru->clksel_con[165]);
+        sel = (con & PCLK_CENTER_ROOT_SEL_MASK) >>
+              PCLK_CENTER_ROOT_SEL_SHIFT;
+        if (sel == PCLK_CENTER_ROOT_SEL_200M)
+            rate = 200 * MHz;
+        else if (sel == PCLK_CENTER_ROOT_SEL_100M)
+            rate = 100 * MHz;
+        else if (sel == PCLK_CENTER_ROOT_SEL_50M)
+            rate = 50 * MHz;
+        else
+            rate = OSC_HZ;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t rk3588_center_set_clk(struct rk3588_clk_priv *priv,
+                   rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk;
+
+    switch (clk_id)
+    {
+    case ACLK_CENTER_ROOT:
+        if (rate >= 700 * MHz)
+            src_clk = ACLK_CENTER_ROOT_SEL_700M;
+        else if (rate >= 396 * MHz)
+            src_clk = ACLK_CENTER_ROOT_SEL_400M;
+        else if (rate >= 200 * MHz)
+            src_clk = ACLK_CENTER_ROOT_SEL_200M;
+        else
+            src_clk = ACLK_CENTER_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[165],
+                 ACLK_CENTER_ROOT_SEL_MASK,
+                 src_clk << ACLK_CENTER_ROOT_SEL_SHIFT);
+        break;
+    case ACLK_CENTER_LOW_ROOT:
+        if (rate >= 500 * MHz)
+            src_clk = ACLK_CENTER_LOW_ROOT_SEL_500M;
+        else if (rate >= 250 * MHz)
+            src_clk = ACLK_CENTER_LOW_ROOT_SEL_250M;
+        else if (rate >= 99 * MHz)
+            src_clk = ACLK_CENTER_LOW_ROOT_SEL_100M;
+        else
+            src_clk = ACLK_CENTER_LOW_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[165],
+                 ACLK_CENTER_LOW_ROOT_SEL_MASK,
+                 src_clk << ACLK_CENTER_LOW_ROOT_SEL_SHIFT);
+        break;
+    case HCLK_CENTER_ROOT:
+        if (rate >= 396 * MHz)
+            src_clk = HCLK_CENTER_ROOT_SEL_400M;
+        else if (rate >= 198 * MHz)
+            src_clk = HCLK_CENTER_ROOT_SEL_200M;
+        else if (rate >= 99 * MHz)
+            src_clk = HCLK_CENTER_ROOT_SEL_100M;
+        else
+            src_clk = HCLK_CENTER_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[165],
+                 HCLK_CENTER_ROOT_SEL_MASK,
+                 src_clk << HCLK_CENTER_ROOT_SEL_SHIFT);
+        break;
+    case PCLK_CENTER_ROOT:
+        if (rate >= 198 * MHz)
+            src_clk = PCLK_CENTER_ROOT_SEL_200M;
+        else if (rate >= 99 * MHz)
+            src_clk = PCLK_CENTER_ROOT_SEL_100M;
+        else if (rate >= 50 * MHz)
+            src_clk = PCLK_CENTER_ROOT_SEL_50M;
+        else
+            src_clk = PCLK_CENTER_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[165],
+                 PCLK_CENTER_ROOT_SEL_MASK,
+                 src_clk << PCLK_CENTER_ROOT_SEL_SHIFT);
+        break;
+    default:
+        LOG_D("do not support this center freq\n");
+        return -RT_EINVAL;
+    }
+
+    return rk3588_center_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_top_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t con, sel, div, rate, prate;
+
+    switch (clk_id)
+    {
+    case ACLK_TOP_ROOT:
+        con = HWREG32(&cru->clksel_con[8]);
+        div = (con & ACLK_TOP_ROOT_DIV_MASK) >>
+              ACLK_TOP_ROOT_DIV_SHIFT;
+        sel = (con & ACLK_TOP_ROOT_SRC_SEL_MASK) >>
+              ACLK_TOP_ROOT_SRC_SEL_SHIFT;
+        if (sel == ACLK_TOP_ROOT_SRC_SEL_CPLL)
+            prate = priv->cpll_hz;
+        else
+            prate = priv->gpll_hz;
+        return DIV_TO_RATE(prate, div);
+    case ACLK_LOW_TOP_ROOT:
+        con = HWREG32(&cru->clksel_con[8]);
+        div = (con & ACLK_LOW_TOP_ROOT_DIV_MASK) >>
+              ACLK_LOW_TOP_ROOT_DIV_SHIFT;
+        sel = (con & ACLK_LOW_TOP_ROOT_SRC_SEL_MASK) >>
+              ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT;
+        if (sel == ACLK_LOW_TOP_ROOT_SRC_SEL_CPLL)
+            prate = priv->cpll_hz;
+        else
+            prate = priv->gpll_hz;
+        return DIV_TO_RATE(prate, div);
+    case PCLK_TOP_ROOT:
+        con = HWREG32(&cru->clksel_con[8]);
+        sel = (con & PCLK_TOP_ROOT_SEL_MASK) >> PCLK_TOP_ROOT_SEL_SHIFT;
+        if (sel == PCLK_TOP_ROOT_SEL_100M)
+            rate = 100 * MHz;
+        else if (sel == PCLK_TOP_ROOT_SEL_50M)
+            rate = 50 * MHz;
+        else
+            rate = OSC_HZ;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rate;
+}
+
+static rt_ubase_t rk3588_top_set_clk(struct rk3588_clk_priv *priv,
+                rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk, src_clk_div;
+
+    switch (clk_id)
+    {
+    case ACLK_TOP_ROOT:
+        if (!(priv->cpll_hz % rate))
+        {
+            src_clk = ACLK_TOP_ROOT_SRC_SEL_CPLL;
+            src_clk_div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+        } else {
+            src_clk = ACLK_TOP_ROOT_SRC_SEL_GPLL;
+            src_clk_div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        }
+        RT_ASSERT(src_clk_div - 1 <= 31);
+        rk_clrsetreg(&cru->clksel_con[8],
+                 ACLK_TOP_ROOT_DIV_MASK |
+                 ACLK_TOP_ROOT_SRC_SEL_MASK,
+                 (src_clk <<
+                  ACLK_TOP_ROOT_SRC_SEL_SHIFT) |
+                 (src_clk_div - 1) << ACLK_TOP_ROOT_DIV_SHIFT);
+        break;
+    case ACLK_LOW_TOP_ROOT:
+        src_clk_div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        RT_ASSERT(src_clk_div - 1 <= 31);
+        rk_clrsetreg(&cru->clksel_con[8],
+                 ACLK_LOW_TOP_ROOT_DIV_MASK |
+                 ACLK_LOW_TOP_ROOT_SRC_SEL_MASK,
+                 (ACLK_LOW_TOP_ROOT_SRC_SEL_GPLL <<
+                  ACLK_LOW_TOP_ROOT_SRC_SEL_SHIFT) |
+                 (src_clk_div - 1) << ACLK_LOW_TOP_ROOT_DIV_SHIFT);
+        break;
+    case PCLK_TOP_ROOT:
+        if (rate == 100 * MHz)
+            src_clk = PCLK_TOP_ROOT_SEL_100M;
+        else if (rate == 50 * MHz)
+            src_clk = PCLK_TOP_ROOT_SEL_50M;
+        else
+            src_clk = PCLK_TOP_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[8],
+                 PCLK_TOP_ROOT_SEL_MASK,
+                 src_clk << PCLK_TOP_ROOT_SEL_SHIFT);
+        break;
+    default:
+        LOG_D("do not support this top freq\n");
+        return -RT_EINVAL;
+    }
+
+    return rk3588_top_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_i2c_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+    rt_ubase_t rate;
+
+    switch (clk_id)
+    {
+    case CLK_I2C0:
+        con = HWREG32(&cru->pmuclksel_con[3]);
+        sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT;
+        break;
+    case CLK_I2C1:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT;
+        break;
+    case CLK_I2C2:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT;
+        break;
+    case CLK_I2C3:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT;
+        break;
+    case CLK_I2C4:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT;
+        break;
+    case CLK_I2C5:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT;
+        break;
+    case CLK_I2C6:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT;
+        break;
+    case CLK_I2C7:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT;
+        break;
+    case CLK_I2C8:
+        con = HWREG32(&cru->clksel_con[38]);
+        sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+    if (sel == CLK_I2C_SEL_200M)
+        rate = 200 * MHz;
+    else
+        rate = 100 * MHz;
+
+    return rate;
+}
+
+static rt_ubase_t rk3588_i2c_set_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id,
+                rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk;
+
+    if (rate >= 198 * MHz)
+        src_clk = CLK_I2C_SEL_200M;
+    else
+        src_clk = CLK_I2C_SEL_100M;
+
+    switch (clk_id)
+    {
+    case CLK_I2C0:
+        rk_clrsetreg(&cru->pmuclksel_con[3], CLK_I2C0_SEL_MASK,
+                 src_clk << CLK_I2C0_SEL_SHIFT);
+        break;
+    case CLK_I2C1:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C1_SEL_MASK,
+                 src_clk << CLK_I2C1_SEL_SHIFT);
+        break;
+    case CLK_I2C2:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C2_SEL_MASK,
+                 src_clk << CLK_I2C2_SEL_SHIFT);
+        break;
+    case CLK_I2C3:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C3_SEL_MASK,
+                 src_clk << CLK_I2C3_SEL_SHIFT);
+        break;
+    case CLK_I2C4:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C4_SEL_MASK,
+                 src_clk << CLK_I2C4_SEL_SHIFT);
+        break;
+    case CLK_I2C5:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C5_SEL_MASK,
+                 src_clk << CLK_I2C5_SEL_SHIFT);
+        break;
+    case CLK_I2C6:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C6_SEL_MASK,
+                 src_clk << CLK_I2C6_SEL_SHIFT);
+        break;
+    case CLK_I2C7:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C7_SEL_MASK,
+                 src_clk << CLK_I2C7_SEL_SHIFT);
+        break;
+    case CLK_I2C8:
+        rk_clrsetreg(&cru->clksel_con[38], CLK_I2C8_SEL_MASK,
+                 src_clk << CLK_I2C8_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_i2c_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_spi_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    con = HWREG32(&cru->clksel_con[59]);
+
+    switch (clk_id)
+    {
+    case CLK_SPI0:
+        sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT;
+        break;
+    case CLK_SPI1:
+        sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT;
+        break;
+    case CLK_SPI2:
+        sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT;
+        break;
+    case CLK_SPI3:
+        sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT;
+        break;
+    case CLK_SPI4:
+        sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    switch (sel)
+    {
+    case CLK_SPI_SEL_200M:
+        return 200 * MHz;
+    case CLK_SPI_SEL_150M:
+        return 150 * MHz;
+    case CLK_SPI_SEL_24M:
+        return OSC_HZ;
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_spi_set_clk(struct rk3588_clk_priv *priv,
+                rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk;
+
+    if (rate >= 198 * MHz)
+        src_clk = CLK_SPI_SEL_200M;
+    else if (rate >= 140 * MHz)
+        src_clk = CLK_SPI_SEL_150M;
+    else
+        src_clk = CLK_SPI_SEL_24M;
+
+    switch (clk_id)
+    {
+    case CLK_SPI0:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_SPI0_SEL_MASK,
+                 src_clk << CLK_SPI0_SEL_SHIFT);
+        break;
+    case CLK_SPI1:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_SPI1_SEL_MASK,
+                 src_clk << CLK_SPI1_SEL_SHIFT);
+        break;
+    case CLK_SPI2:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_SPI2_SEL_MASK,
+                 src_clk << CLK_SPI2_SEL_SHIFT);
+        break;
+    case CLK_SPI3:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_SPI3_SEL_MASK,
+                 src_clk << CLK_SPI3_SEL_SHIFT);
+        break;
+    case CLK_SPI4:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_SPI4_SEL_MASK,
+                 src_clk << CLK_SPI4_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_spi_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_pwm_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t sel, con;
+
+    switch (clk_id)
+    {
+    case CLK_PWM1:
+        con = HWREG32(&cru->clksel_con[59]);
+        sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT;
+        break;
+    case CLK_PWM2:
+        con = HWREG32(&cru->clksel_con[59]);
+        sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT;
+        break;
+    case CLK_PWM3:
+        con = HWREG32(&cru->clksel_con[60]);
+        sel = (con & CLK_PWM3_SEL_MASK) >> CLK_PWM3_SEL_SHIFT;
+        break;
+    case CLK_PMU1PWM:
+        con = HWREG32(&cru->pmuclksel_con[2]);
+        sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    switch (sel)
+    {
+    case CLK_PWM_SEL_100M:
+        return 100 * MHz;
+    case CLK_PWM_SEL_50M:
+        return 50 * MHz;
+    case CLK_PWM_SEL_24M:
+        return OSC_HZ;
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_pwm_set_clk(struct rk3588_clk_priv *priv,
+                rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk;
+
+    if (rate >= 99 * MHz)
+        src_clk = CLK_PWM_SEL_100M;
+    else if (rate >= 50 * MHz)
+        src_clk = CLK_PWM_SEL_50M;
+    else
+        src_clk = CLK_PWM_SEL_24M;
+
+    switch (clk_id)
+    {
+    case CLK_PWM1:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_PWM1_SEL_MASK,
+                 src_clk << CLK_PWM1_SEL_SHIFT);
+        break;
+    case CLK_PWM2:
+        rk_clrsetreg(&cru->clksel_con[59],
+                 CLK_PWM2_SEL_MASK,
+                 src_clk << CLK_PWM2_SEL_SHIFT);
+        break;
+    case CLK_PWM3:
+        rk_clrsetreg(&cru->clksel_con[60],
+                 CLK_PWM3_SEL_MASK,
+                 src_clk << CLK_PWM3_SEL_SHIFT);
+        break;
+    case CLK_PMU1PWM:
+        rk_clrsetreg(&cru->pmuclksel_con[2],
+                 CLK_PMU1PWM_SEL_MASK,
+                 src_clk << CLK_PMU1PWM_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_pwm_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_adc_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t div, sel, con, prate;
+
+    switch (clk_id)
+    {
+    case CLK_SARADC:
+        con = HWREG32(&cru->clksel_con[40]);
+        div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT;
+        sel = (con & CLK_SARADC_SEL_MASK) >>
+              CLK_SARADC_SEL_SHIFT;
+        if (sel == CLK_SARADC_SEL_24M)
+            prate = OSC_HZ;
+        else
+            prate = priv->gpll_hz;
+        return DIV_TO_RATE(prate, div);
+    case CLK_TSADC:
+        con = HWREG32(&cru->clksel_con[41]);
+        div = (con & CLK_TSADC_DIV_MASK) >>
+              CLK_TSADC_DIV_SHIFT;
+        sel = (con & CLK_TSADC_SEL_MASK) >>
+              CLK_TSADC_SEL_SHIFT;
+        if (sel == CLK_TSADC_SEL_24M)
+            prate = OSC_HZ;
+        else
+            prate = 100 * MHz;
+        return DIV_TO_RATE(prate, div);
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_adc_set_clk(struct rk3588_clk_priv *priv,
+                rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk_div;
+
+    switch (clk_id)
+    {
+    case CLK_SARADC:
+        if (!(OSC_HZ % rate))
+        {
+            src_clk_div = RT_DIV_ROUND_UP(OSC_HZ, rate);
+            RT_ASSERT(src_clk_div - 1 <= 255);
+            rk_clrsetreg(&cru->clksel_con[40],
+                     CLK_SARADC_SEL_MASK |
+                     CLK_SARADC_DIV_MASK,
+                     (CLK_SARADC_SEL_24M <<
+                      CLK_SARADC_SEL_SHIFT) |
+                     (src_clk_div - 1) <<
+                     CLK_SARADC_DIV_SHIFT);
+        } else {
+            src_clk_div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+            RT_ASSERT(src_clk_div - 1 <= 255);
+            rk_clrsetreg(&cru->clksel_con[40],
+                     CLK_SARADC_SEL_MASK |
+                     CLK_SARADC_DIV_MASK,
+                     (CLK_SARADC_SEL_GPLL <<
+                      CLK_SARADC_SEL_SHIFT) |
+                     (src_clk_div - 1) <<
+                     CLK_SARADC_DIV_SHIFT);
+        }
+        break;
+    case CLK_TSADC:
+        if (!(OSC_HZ % rate))
+        {
+            src_clk_div = RT_DIV_ROUND_UP(OSC_HZ, rate);
+            RT_ASSERT(src_clk_div - 1 <= 255);
+            rk_clrsetreg(&cru->clksel_con[41],
+                     CLK_TSADC_SEL_MASK |
+                     CLK_TSADC_DIV_MASK,
+                     (CLK_TSADC_SEL_24M <<
+                      CLK_TSADC_SEL_SHIFT) |
+                     (src_clk_div - 1) <<
+                     CLK_TSADC_DIV_SHIFT);
+        } else {
+            src_clk_div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+            RT_ASSERT(src_clk_div - 1 <= 7);
+            rk_clrsetreg(&cru->clksel_con[41],
+                     CLK_TSADC_SEL_MASK |
+                     CLK_TSADC_DIV_MASK,
+                     (CLK_TSADC_SEL_GPLL <<
+                      CLK_TSADC_SEL_SHIFT) |
+                     (src_clk_div - 1) <<
+                     CLK_TSADC_DIV_SHIFT);
+        }
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+    return rk3588_adc_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_mmc_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t sel, con, div, prate;
+
+    switch (clk_id)
+    {
+    case CCLK_SRC_SDIO:
+        con = HWREG32(&cru->clksel_con[172]);
+        div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT;
+        sel = (con & CCLK_SDIO_SRC_SEL_MASK) >>
+              CCLK_SDIO_SRC_SEL_SHIFT;
+        if (sel == CCLK_SDIO_SRC_SEL_GPLL)
+            prate = priv->gpll_hz;
+        else if (sel == CCLK_SDIO_SRC_SEL_CPLL)
+            prate = priv->cpll_hz;
+        else
+            prate = OSC_HZ;
+        return DIV_TO_RATE(prate, div);
+    case CCLK_EMMC:
+        con = HWREG32(&cru->clksel_con[77]);
+        div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT;
+        sel = (con & CCLK_EMMC_SEL_MASK) >>
+              CCLK_EMMC_SEL_SHIFT;
+        if (sel == CCLK_EMMC_SEL_GPLL)
+            prate = priv->gpll_hz;
+        else if (sel == CCLK_EMMC_SEL_CPLL)
+            prate = priv->cpll_hz;
+        else
+            prate = OSC_HZ;
+        return DIV_TO_RATE(prate, div);
+    case BCLK_EMMC:
+        con = HWREG32(&cru->clksel_con[78]);
+        div = (con & BCLK_EMMC_DIV_MASK) >> BCLK_EMMC_DIV_SHIFT;
+        sel = (con & BCLK_EMMC_SEL_MASK) >>
+              BCLK_EMMC_SEL_SHIFT;
+        if (sel == CCLK_EMMC_SEL_CPLL)
+            prate = priv->cpll_hz;
+        else
+            prate = priv->gpll_hz;
+        return DIV_TO_RATE(prate, div);
+    case SCLK_SFC:
+        con = HWREG32(&cru->clksel_con[78]);
+        div = (con & SCLK_SFC_DIV_MASK) >> SCLK_SFC_DIV_SHIFT;
+        sel = (con & SCLK_SFC_SEL_MASK) >>
+              SCLK_SFC_SEL_SHIFT;
+        if (sel == SCLK_SFC_SEL_GPLL)
+            prate = priv->gpll_hz;
+        else if (sel == SCLK_SFC_SEL_CPLL)
+            prate = priv->cpll_hz;
+        else
+            prate = OSC_HZ;
+        return DIV_TO_RATE(prate, div);
+    case DCLK_DECOM:
+        con = HWREG32(&cru->clksel_con[62]);
+        div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT;
+        sel = (con & DCLK_DECOM_SEL_MASK) >>
+              DCLK_DECOM_SEL_SHIFT;
+        if (sel == DCLK_DECOM_SEL_SPLL)
+            prate = 702 * MHz;
+        else
+            prate = priv->gpll_hz;
+        return DIV_TO_RATE(prate, div);
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_mmc_set_clk(struct rk3588_clk_priv *priv,
+                rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk, div;
+    /*rt_min_t(rt_ubase_t, 48 * MHZ, rate);*/
+    switch (clk_id)
+    {
+    case CCLK_SRC_SDIO:
+    case CCLK_EMMC:
+    case SCLK_SFC:
+        if (!(OSC_HZ % rate))
+        {
+            src_clk = SCLK_SFC_SEL_24M;
+            div = RT_DIV_ROUND_UP(OSC_HZ, rate);
+        } else if (!(priv->cpll_hz % rate))
+        {
+            src_clk = SCLK_SFC_SEL_CPLL;
+            div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+        } else {
+            src_clk = SCLK_SFC_SEL_GPLL;
+            div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        }
+        break;
+    case BCLK_EMMC:
+        if (!(priv->cpll_hz % rate))
+        {
+            src_clk = CCLK_EMMC_SEL_CPLL;
+            div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+        } else {
+            src_clk = CCLK_EMMC_SEL_GPLL;
+            div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        }
+        break;
+    case DCLK_DECOM:
+        if (!(702 * MHz % rate))
+        {
+            src_clk = DCLK_DECOM_SEL_SPLL;
+            div = RT_DIV_ROUND_UP(702 * MHz, rate);
+        } else {
+            src_clk = DCLK_DECOM_SEL_GPLL;
+            div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        }
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    switch (clk_id)
+    {
+    case CCLK_SRC_SDIO:
+        rk_clrsetreg(&cru->clksel_con[172],
+                 CCLK_SDIO_SRC_SEL_MASK |
+                 CCLK_SDIO_SRC_DIV_MASK,
+                 (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) |
+                 (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT);
+        break;
+    case CCLK_EMMC:
+        rk_clrsetreg(&cru->clksel_con[77],
+                 CCLK_EMMC_SEL_MASK |
+                 CCLK_EMMC_DIV_MASK,
+                 (src_clk << CCLK_EMMC_SEL_SHIFT) |
+                 (div - 1) << CCLK_EMMC_DIV_SHIFT);
+        break;
+    case BCLK_EMMC:
+        rk_clrsetreg(&cru->clksel_con[78],
+                 BCLK_EMMC_DIV_MASK |
+                 BCLK_EMMC_SEL_MASK,
+                 (src_clk << BCLK_EMMC_SEL_SHIFT) |
+                 (div - 1) << BCLK_EMMC_DIV_SHIFT);
+        break;
+    case SCLK_SFC:
+        rk_clrsetreg(&cru->clksel_con[78],
+                 SCLK_SFC_DIV_MASK |
+                 SCLK_SFC_SEL_MASK,
+                 (src_clk << SCLK_SFC_SEL_SHIFT) |
+                 (div - 1) << SCLK_SFC_DIV_SHIFT);
+        break;
+    case DCLK_DECOM:
+        rk_clrsetreg(&cru->clksel_con[62],
+                 DCLK_DECOM_DIV_MASK |
+                 DCLK_DECOM_SEL_MASK,
+                 (src_clk << DCLK_DECOM_SEL_SHIFT) |
+                 (div - 1) << DCLK_DECOM_DIV_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_mmc_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_aux16m_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t div, con, parent;
+
+    parent = priv->gpll_hz;
+    con = HWREG32(&cru->clksel_con[117]);
+
+    switch (clk_id)
+    {
+    case CLK_AUX16M_0:
+        div = (con & CLK_AUX16MHZ_0_DIV_MASK) >> CLK_AUX16MHZ_0_DIV_SHIFT;
+        return DIV_TO_RATE(parent, div);
+    case CLK_AUX16M_1:
+        div = (con & CLK_AUX16MHZ_1_DIV_MASK) >> CLK_AUX16MHZ_1_DIV_SHIFT;
+        return DIV_TO_RATE(parent, div);
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_aux16m_set_clk(struct rk3588_clk_priv *priv,
+                   rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t div;
+
+    if (!priv->gpll_hz)
+    {
+        LOG_D("%s gpll=%lu\n", __func__, priv->gpll_hz);
+        return -RT_ENOENT;
+    }
+
+    div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+
+    switch (clk_id)
+    {
+    case CLK_AUX16M_0:
+        rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_0_DIV_MASK,
+                 (div - 1) << CLK_AUX16MHZ_0_DIV_SHIFT);
+        break;
+    case CLK_AUX16M_1:
+        rk_clrsetreg(&cru->clksel_con[117], CLK_AUX16MHZ_1_DIV_MASK,
+                 (div - 1) << CLK_AUX16MHZ_1_DIV_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_aux16m_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_aclk_vop_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t div, sel, con, parent;
+
+    switch (clk_id)
+    {
+    case ACLK_VOP_ROOT:
+    case ACLK_VOP:
+        con = HWREG32(&cru->clksel_con[110]);
+        div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT;
+        sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT;
+        if (sel == ACLK_VOP_ROOT_SEL_GPLL)
+            parent = priv->gpll_hz;
+        else if (sel == ACLK_VOP_ROOT_SEL_CPLL)
+            parent = priv->cpll_hz;
+        else if (sel == ACLK_VOP_ROOT_SEL_AUPLL)
+            parent = priv->aupll_hz;
+        else if (sel == ACLK_VOP_ROOT_SEL_NPLL)
+            parent = priv->npll_hz;
+        else
+            parent = 702 * MHz;
+        return DIV_TO_RATE(parent, div);
+    case ACLK_VOP_LOW_ROOT:
+        con = HWREG32(&cru->clksel_con[110]);
+        sel = (con & ACLK_VOP_LOW_ROOT_SEL_MASK) >>
+              ACLK_VOP_LOW_ROOT_SEL_SHIFT;
+        if (sel == ACLK_VOP_LOW_ROOT_SEL_400M)
+            return 396 * MHz;
+        else if (sel == ACLK_VOP_LOW_ROOT_SEL_200M)
+            return 200 * MHz;
+        else if (sel == ACLK_VOP_LOW_ROOT_SEL_100M)
+            return 100 * MHz;
+        else
+            return OSC_HZ;
+    case HCLK_VOP_ROOT:
+        con = HWREG32(&cru->clksel_con[110]);
+        sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT;
+        if (sel == HCLK_VOP_ROOT_SEL_200M)
+            return 200 * MHz;
+        else if (sel == HCLK_VOP_ROOT_SEL_100M)
+            return 100 * MHz;
+        else if (sel == HCLK_VOP_ROOT_SEL_50M)
+            return 50 * MHz;
+        else
+            return OSC_HZ;
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_aclk_vop_set_clk(struct rk3588_clk_priv *priv,
+                     rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int src_clk, div;
+
+    switch (clk_id)
+    {
+    case ACLK_VOP_ROOT:
+    case ACLK_VOP:
+        if (rate >= 850 * MHz)
+        {
+            src_clk = ACLK_VOP_ROOT_SEL_NPLL;
+            div = 1;
+        } else if (rate >= 750 * MHz)
+        {
+            src_clk = ACLK_VOP_ROOT_SEL_CPLL;
+            div = 2;
+        } else if (rate >= 700 * MHz)
+        {
+            src_clk = ACLK_VOP_ROOT_SEL_SPLL;
+            div = 1;
+        } else if (!(priv->cpll_hz % rate))
+        {
+            src_clk = ACLK_VOP_ROOT_SEL_CPLL;
+            div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+        } else {
+            src_clk = ACLK_VOP_ROOT_SEL_GPLL;
+            div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+        }
+        rk_clrsetreg(&cru->clksel_con[110],
+                 ACLK_VOP_ROOT_DIV_MASK |
+                 ACLK_VOP_ROOT_SEL_MASK,
+                 (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) |
+                 (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT);
+        break;
+    case ACLK_VOP_LOW_ROOT:
+        if (rate == 400 * MHz || rate == 396 * MHz)
+            src_clk = ACLK_VOP_LOW_ROOT_SEL_400M;
+        else if (rate == 200 * MHz)
+            src_clk = ACLK_VOP_LOW_ROOT_SEL_200M;
+        else if (rate == 100 * MHz)
+            src_clk = ACLK_VOP_LOW_ROOT_SEL_100M;
+        else
+            src_clk = ACLK_VOP_LOW_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[110],
+                 ACLK_VOP_LOW_ROOT_SEL_MASK,
+                 src_clk << ACLK_VOP_LOW_ROOT_SEL_SHIFT);
+        break;
+    case HCLK_VOP_ROOT:
+        if (rate == 200 * MHz)
+            src_clk = HCLK_VOP_ROOT_SEL_200M;
+        else if (rate == 100 * MHz)
+            src_clk = HCLK_VOP_ROOT_SEL_100M;
+        else if (rate == 50 * MHz)
+            src_clk = HCLK_VOP_ROOT_SEL_50M;
+        else
+            src_clk = HCLK_VOP_ROOT_SEL_24M;
+        rk_clrsetreg(&cru->clksel_con[110],
+                 HCLK_VOP_ROOT_SEL_MASK,
+                 src_clk << HCLK_VOP_ROOT_SEL_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_aclk_vop_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_dclk_vop_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t div, sel, con, parent;
+
+    switch (clk_id)
+    {
+    case DCLK_VOP0:
+    case DCLK_VOP0_SRC:
+        con = HWREG32(&cru->clksel_con[111]);
+        div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT;
+        sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
+        break;
+    case DCLK_VOP1:
+    case DCLK_VOP1_SRC:
+        con = HWREG32(&cru->clksel_con[111]);
+        div = (con & DCLK1_VOP_SRC_DIV_MASK) >> DCLK1_VOP_SRC_DIV_SHIFT;
+        sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
+        break;
+    case DCLK_VOP2:
+    case DCLK_VOP2_SRC:
+        con = HWREG32(&cru->clksel_con[112]);
+        div = (con & DCLK2_VOP_SRC_DIV_MASK) >> DCLK2_VOP_SRC_DIV_SHIFT;
+        sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
+        break;
+    case DCLK_VOP3:
+        con = HWREG32(&cru->clksel_con[113]);
+        div = (con & DCLK3_VOP_SRC_DIV_MASK) >> DCLK3_VOP_SRC_DIV_SHIFT;
+        sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    if (sel == DCLK_VOP_SRC_SEL_AUPLL)
+        parent = priv->aupll_hz;
+    else if (sel == DCLK_VOP_SRC_SEL_V0PLL)
+        parent = rk_pll_get_rate(&rk3588_pll_clks[V0PLL],
+                           priv->cru, V0PLL);
+    else if (sel == DCLK_VOP_SRC_SEL_GPLL)
+        parent = priv->gpll_hz;
+    else
+        parent = priv->cpll_hz;
+
+    return DIV_TO_RATE(parent, div);
+}
+
+#define RK3588_VOP_PLL_LIMIT_FREQ 600000000
+
+static rt_ubase_t rk3588_dclk_vop_set_clk(struct rk3588_clk_priv *priv,
+                     rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_ubase_t pll_rate, now, best_rate = 0;
+    rt_uint32_t i, conid, con, sel, div, best_div = 0, best_sel = 0;
+    rt_uint32_t mask, div_shift, sel_shift;
+
+    switch (clk_id)
+    {
+    case DCLK_VOP0:
+    case DCLK_VOP0_SRC:
+        conid = 111;
+        con = HWREG32(&cru->clksel_con[111]);
+        sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT;
+        mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK;
+        div_shift = DCLK0_VOP_SRC_DIV_SHIFT;
+        sel_shift = DCLK0_VOP_SRC_SEL_SHIFT;
+        break;
+    case DCLK_VOP1:
+    case DCLK_VOP1_SRC:
+        conid = 111;
+        con = HWREG32(&cru->clksel_con[111]);
+        sel = (con & DCLK1_VOP_SRC_SEL_MASK) >> DCLK1_VOP_SRC_SEL_SHIFT;
+        mask = DCLK1_VOP_SRC_SEL_MASK | DCLK1_VOP_SRC_DIV_MASK;
+        div_shift = DCLK1_VOP_SRC_DIV_SHIFT;
+        sel_shift = DCLK1_VOP_SRC_SEL_SHIFT;
+        break;
+    case DCLK_VOP2:
+    case DCLK_VOP2_SRC:
+        conid = 112;
+        con = HWREG32(&cru->clksel_con[112]);
+        sel = (con & DCLK2_VOP_SRC_SEL_MASK) >> DCLK2_VOP_SRC_SEL_SHIFT;
+        mask = DCLK2_VOP_SRC_SEL_MASK | DCLK2_VOP_SRC_DIV_MASK;
+        div_shift = DCLK2_VOP_SRC_DIV_SHIFT;
+        sel_shift = DCLK2_VOP_SRC_SEL_SHIFT;
+        break;
+    case DCLK_VOP3:
+        conid = 113;
+        con = HWREG32(&cru->clksel_con[113]);
+        sel = (con & DCLK3_VOP_SRC_SEL_MASK) >> DCLK3_VOP_SRC_SEL_SHIFT;
+        mask = DCLK3_VOP_SRC_SEL_MASK | DCLK3_VOP_SRC_DIV_MASK;
+        div_shift = DCLK3_VOP_SRC_DIV_SHIFT;
+        sel_shift = DCLK3_VOP_SRC_SEL_SHIFT;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    if (sel == DCLK_VOP_SRC_SEL_V0PLL)
+    {
+        pll_rate = rk_pll_get_rate(&rk3588_pll_clks[V0PLL],
+                         priv->cru, V0PLL);
+        if (pll_rate >= RK3588_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0)
+        {
+            div = RT_DIV_ROUND_UP(pll_rate, rate);
+            rk_clrsetreg(&cru->clksel_con[conid],
+                     mask,
+                     DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
+                     ((div - 1) << div_shift));
+        } else {
+            div = RT_DIV_ROUND_UP(RK3588_VOP_PLL_LIMIT_FREQ, rate);
+            rk_clrsetreg(&cru->clksel_con[conid],
+                     mask,
+                     DCLK_VOP_SRC_SEL_V0PLL << sel_shift |
+                     ((div - 1) << div_shift));
+            rk_pll_set_rate(&rk3588_pll_clks[V0PLL],
+                          priv->cru, V0PLL, div * rate);
+        }
+    } else {
+        for (i = 0; i <= DCLK_VOP_SRC_SEL_AUPLL; i++)
+        {
+            switch (i)
+            {
+            case DCLK_VOP_SRC_SEL_GPLL:
+                pll_rate = priv->gpll_hz;
+                break;
+            case DCLK_VOP_SRC_SEL_CPLL:
+                pll_rate = priv->cpll_hz;
+                break;
+            case DCLK_VOP_SRC_SEL_AUPLL:
+                pll_rate = priv->aupll_hz;
+                break;
+            case DCLK_VOP_SRC_SEL_V0PLL:
+                pll_rate = 0;
+                break;
+            default:
+                LOG_D("do not support this vop pll sel\n");
+                return -RT_EINVAL;
+            }
+
+            div = RT_DIV_ROUND_UP(pll_rate, rate);
+            if (div > 255)
+                continue;
+            now = pll_rate / div;
+            if (abs(rate - now) < abs(rate - best_rate))
+            {
+                best_rate = now;
+                best_div = div;
+                best_sel = i;
+            }
+            LOG_D("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n",
+                  pll_rate, best_rate, best_div, best_sel);
+        }
+
+        if (best_rate)
+        {
+            rk_clrsetreg(&cru->clksel_con[conid],
+                     mask,
+                     best_sel << sel_shift |
+                     (best_div - 1) << div_shift);
+        } else {
+            LOG_D("do not support this vop freq %lu\n", rate);
+            return -RT_EINVAL;
+        }
+    }
+    return rk3588_dclk_vop_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_gmac_get_clk(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t con, div;
+
+    switch (clk_id)
+    {
+    case CLK_GMAC0_PTP_REF:
+        con = HWREG32(&cru->clksel_con[81]);
+        div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT;
+        return DIV_TO_RATE(priv->cpll_hz, div);
+    case CLK_GMAC1_PTP_REF:
+        con = HWREG32(&cru->clksel_con[81]);
+        div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC1_PTP_DIV_SHIFT;
+        return DIV_TO_RATE(priv->cpll_hz, div);
+    case CLK_GMAC_125M:
+        con = HWREG32(&cru->clksel_con[83]);
+        div = (con & CLK_GMAC_125M_DIV_MASK) >> CLK_GMAC_125M_DIV_SHIFT;
+        return DIV_TO_RATE(priv->cpll_hz, div);
+    case CLK_GMAC_50M:
+        con = HWREG32(&cru->clksel_con[84]);
+        div = (con & CLK_GMAC_50M_DIV_MASK) >> CLK_GMAC_50M_DIV_SHIFT;
+        return DIV_TO_RATE(priv->cpll_hz, div);
+    default:
+        return -RT_ENOENT;
+    }
+}
+
+static rt_ubase_t rk3588_gmac_set_clk(struct rk3588_clk_priv *priv,
+                 rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    int div;
+
+    div = RT_DIV_ROUND_UP(priv->cpll_hz, rate);
+
+    switch (clk_id)
+    {
+    case CLK_GMAC0_PTP_REF:
+        rk_clrsetreg(&cru->clksel_con[81],
+                 CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK,
+                 CLK_GMAC0_PTP_SEL_CPLL << CLK_GMAC0_PTP_SEL_SHIFT |
+                 (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT);
+        break;
+    case CLK_GMAC1_PTP_REF:
+        rk_clrsetreg(&cru->clksel_con[81],
+                 CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK,
+                 CLK_GMAC1_PTP_SEL_CPLL << CLK_GMAC1_PTP_SEL_SHIFT |
+                 (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT);
+        break;
+
+    case CLK_GMAC_125M:
+        rk_clrsetreg(&cru->clksel_con[83],
+                 CLK_GMAC_125M_DIV_MASK | CLK_GMAC_125M_SEL_MASK,
+                 CLK_GMAC_125M_SEL_CPLL << CLK_GMAC_125M_SEL_SHIFT |
+                 (div - 1) << CLK_GMAC_125M_DIV_SHIFT);
+        break;
+    case CLK_GMAC_50M:
+        rk_clrsetreg(&cru->clksel_con[84],
+                 CLK_GMAC_50M_DIV_MASK | CLK_GMAC_50M_SEL_MASK,
+                 CLK_GMAC_50M_SEL_CPLL << CLK_GMAC_50M_SEL_SHIFT |
+                 (div - 1) << CLK_GMAC_50M_DIV_SHIFT);
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_gmac_get_clk(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_uart_get_rate(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t reg, con, fracdiv, div, src, p_src, p_rate;
+    unsigned long m, n;
+
+    switch (clk_id)
+    {
+    case SCLK_UART1:
+        reg = 41;
+        break;
+    case SCLK_UART2:
+        reg = 43;
+        break;
+    case SCLK_UART3:
+        reg = 45;
+        break;
+    case SCLK_UART4:
+        reg = 47;
+        break;
+    case SCLK_UART5:
+        reg = 49;
+        break;
+    case SCLK_UART6:
+        reg = 51;
+        break;
+    case SCLK_UART7:
+        reg = 53;
+        break;
+    case SCLK_UART8:
+        reg = 55;
+        break;
+    case SCLK_UART9:
+        reg = 57;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+    con = HWREG32(&cru->clksel_con[reg + 2]);
+    src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT;
+    con = HWREG32(&cru->clksel_con[reg]);
+    div = (con & CLK_UART_SRC_DIV_MASK) >> CLK_UART_SRC_DIV_SHIFT;
+    p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT;
+    if (p_src == CLK_UART_SRC_SEL_GPLL)
+        p_rate = priv->gpll_hz;
+    else
+        p_rate = priv->cpll_hz;
+
+    if (src == CLK_UART_SEL_SRC)
+    {
+        return DIV_TO_RATE(p_rate, div);
+    } else if (src == CLK_UART_SEL_FRAC)
+    {
+        fracdiv = HWREG32(&cru->clksel_con[reg + 1]);
+        n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK;
+        n >>= CLK_UART_FRAC_NUMERATOR_SHIFT;
+        m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK;
+        m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT;
+        return DIV_TO_RATE(p_rate, div) * n / m;
+    } else {
+        return OSC_HZ;
+    }
+}
+
+static rt_ubase_t rk3588_uart_set_rate(struct rk3588_clk_priv *priv,
+                  rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t reg, clk_src, uart_src, div;
+    unsigned long m = 0, n = 0, val;
+
+    if (priv->gpll_hz % rate == 0)
+    {
+        clk_src = CLK_UART_SRC_SEL_GPLL;
+        uart_src = CLK_UART_SEL_SRC;
+        div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+    } else if (priv->cpll_hz % rate == 0)
+    {
+        clk_src = CLK_UART_SRC_SEL_CPLL;
+        uart_src = CLK_UART_SEL_SRC;
+        div = RT_DIV_ROUND_UP(priv->gpll_hz, rate);
+    } else if (rate == OSC_HZ)
+    {
+        clk_src = CLK_UART_SRC_SEL_GPLL;
+        uart_src = CLK_UART_SEL_XIN24M;
+        div = 2;
+    } else {
+        clk_src = CLK_UART_SRC_SEL_GPLL;
+        uart_src = CLK_UART_SEL_FRAC;
+        div = 2;
+        rational_best_approximation(rate, priv->gpll_hz / div,
+                        RT_GENMASK(16 - 1, 0),
+                        RT_GENMASK(16 - 1, 0),
+                        &m, &n);
+    }
+
+    switch (clk_id)
+    {
+    case SCLK_UART1:
+        reg = 41;
+        break;
+    case SCLK_UART2:
+        reg = 43;
+        break;
+    case SCLK_UART3:
+        reg = 45;
+        break;
+    case SCLK_UART4:
+        reg = 47;
+        break;
+    case SCLK_UART5:
+        reg = 49;
+        break;
+    case SCLK_UART6:
+        reg = 51;
+        break;
+    case SCLK_UART7:
+        reg = 53;
+        break;
+    case SCLK_UART8:
+        reg = 55;
+        break;
+    case SCLK_UART9:
+        reg = 57;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+    rk_clrsetreg(&cru->clksel_con[reg],
+             CLK_UART_SRC_SEL_MASK |
+             CLK_UART_SRC_DIV_MASK,
+             (clk_src << CLK_UART_SRC_SEL_SHIFT) |
+             ((div - 1) << CLK_UART_SRC_DIV_SHIFT));
+    rk_clrsetreg(&cru->clksel_con[reg + 2],
+             CLK_UART_SEL_MASK,
+             (uart_src << CLK_UART_SEL_SHIFT));
+    if (m && n)
+    {
+        val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n;
+        HWREG32(&cru->clksel_con[reg + 1]) = val;
+    }
+
+    return rk3588_uart_get_rate(priv, clk_id);
+}
+
+static rt_ubase_t rk3588_pciephy_get_rate(struct rk3588_clk_priv *priv, rt_ubase_t clk_id)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t con, div, src;
+
+    switch (clk_id)
+    {
+    case CLK_REF_PIPE_PHY0:
+        con = HWREG32(&cru->clksel_con[177]);
+        src = (con & CLK_PCIE_PHY0_REF_SEL_MASK) >> CLK_PCIE_PHY0_REF_SEL_SHIFT;
+        con = HWREG32(&cru->clksel_con[176]);
+        div = (con & CLK_PCIE_PHY0_PLL_DIV_MASK) >> CLK_PCIE_PHY0_PLL_DIV_SHIFT;
+        break;
+    case CLK_REF_PIPE_PHY1:
+        con = HWREG32(&cru->clksel_con[177]);
+        src = (con & CLK_PCIE_PHY1_REF_SEL_MASK) >> CLK_PCIE_PHY1_REF_SEL_SHIFT;
+        con = HWREG32(&cru->clksel_con[176]);
+        div = (con & CLK_PCIE_PHY1_PLL_DIV_MASK) >> CLK_PCIE_PHY1_PLL_DIV_SHIFT;
+        break;
+    case CLK_REF_PIPE_PHY2:
+        con = HWREG32(&cru->clksel_con[177]);
+        src = (con & CLK_PCIE_PHY2_REF_SEL_MASK) >> CLK_PCIE_PHY2_REF_SEL_SHIFT;
+        div = (con & CLK_PCIE_PHY2_PLL_DIV_MASK) >> CLK_PCIE_PHY2_PLL_DIV_SHIFT;
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    if (src == CLK_PCIE_PHY_REF_SEL_PPLL)
+    {
+        return DIV_TO_RATE(priv->ppll_hz, div);
+    } else {
+        return OSC_HZ;
+    }
+}
+
+static rt_ubase_t rk3588_pciephy_set_rate(struct rk3588_clk_priv *priv,
+                  rt_ubase_t clk_id, rt_ubase_t rate)
+{
+    struct rk3588_cru *cru = priv->cru;
+    rt_uint32_t clk_src, div;
+
+    if (rate == OSC_HZ)
+    {
+        clk_src = CLK_PCIE_PHY_REF_SEL_24M;
+        div = 1;
+    } else {
+        clk_src = CLK_PCIE_PHY_REF_SEL_PPLL;
+        div = RT_DIV_ROUND_UP(priv->ppll_hz, rate);
+    }
+
+    switch (clk_id)
+    {
+    case CLK_REF_PIPE_PHY0:
+        rk_clrsetreg(&cru->clksel_con[177],
+             CLK_PCIE_PHY0_REF_SEL_MASK,
+             (clk_src << CLK_PCIE_PHY0_REF_SEL_SHIFT));
+        rk_clrsetreg(&cru->clksel_con[176],
+             CLK_PCIE_PHY0_PLL_DIV_MASK,
+             ((div - 1) << CLK_PCIE_PHY0_PLL_DIV_SHIFT));
+        break;
+    case CLK_REF_PIPE_PHY1:
+        rk_clrsetreg(&cru->clksel_con[177],
+             CLK_PCIE_PHY1_REF_SEL_MASK,
+             (clk_src << CLK_PCIE_PHY1_REF_SEL_SHIFT));
+        rk_clrsetreg(&cru->clksel_con[176],
+             CLK_PCIE_PHY1_PLL_DIV_MASK,
+             ((div - 1) << CLK_PCIE_PHY1_PLL_DIV_SHIFT));
+        break;
+    case CLK_REF_PIPE_PHY2:
+        rk_clrsetreg(&cru->clksel_con[177],
+             CLK_PCIE_PHY2_REF_SEL_MASK |
+             CLK_PCIE_PHY2_PLL_DIV_MASK,
+             (clk_src << CLK_PCIE_PHY2_REF_SEL_SHIFT) |
+             ((div - 1) << CLK_PCIE_PHY2_PLL_DIV_SHIFT));
+        break;
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rk3588_pciephy_get_rate(priv, clk_id);
+}
+
+static rt_ubase_t rk_clk_get_rate(struct rk3588_clk_platform_data *pdata,
+        struct rk3588_clk *rk_clk)
+{
+    struct rk3588_clk_priv *priv = &rk_clk->clk_info;
+    rt_ubase_t rate = 0;
+
+    if (!priv->gpll_hz)
+    {
+        return -RT_ERROR;
+    }
+    if (!priv->ppll_hz)
+    {
+        priv->ppll_hz = rk_pll_get_rate(&rk3588_pll_clks[PPLL],
+                              priv->cru, PPLL);
+    }
+    switch (pdata->id)
+    {
+    case PLL_B0PLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[B0PLL], &priv->cru, B0PLL);
+        break;
+    case PLL_B1PLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[B1PLL], &priv->cru, B1PLL);
+        break;
+    case PLL_LPLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[LPLL], &priv->cru, LPLL);
+        break;
+    case PLL_V0PLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[V0PLL], &priv->cru, V0PLL);
+        break;
+    case PLL_AUPLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[AUPLL], &priv->cru, AUPLL);
+        break;
+    case PLL_CPLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[CPLL], &priv->cru, CPLL);
+        break;
+    case PLL_GPLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[GPLL], &priv->cru, GPLL);
+        break;
+    case PLL_NPLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[NPLL], &priv->cru, NPLL);
+        break;
+    case PLL_PPLL:
+        rate = rk_pll_get_rate(&rk3588_pll_clks[PPLL], &priv->cru, PPLL);
+        break;
+    case ACLK_CENTER_ROOT:
+    case PCLK_CENTER_ROOT:
+    case HCLK_CENTER_ROOT:
+    case ACLK_CENTER_LOW_ROOT:
+        rate = rk3588_center_get_clk(priv, pdata->id);
+        break;
+    case ACLK_TOP_ROOT:
+    case PCLK_TOP_ROOT:
+    case ACLK_LOW_TOP_ROOT:
+        rate = rk3588_top_get_clk(priv, pdata->id);
+        break;
+    case CLK_I2C0:
+    case CLK_I2C1:
+    case CLK_I2C2:
+    case CLK_I2C3:
+    case CLK_I2C4:
+    case CLK_I2C5:
+    case CLK_I2C6:
+    case CLK_I2C7:
+    case CLK_I2C8:
+        rate = rk3588_i2c_get_clk(priv, pdata->id);
+        break;
+    case CLK_SPI0:
+    case CLK_SPI1:
+    case CLK_SPI2:
+    case CLK_SPI3:
+    case CLK_SPI4:
+        rate = rk3588_spi_get_clk(priv, pdata->id);
+        break;
+    case CLK_PWM1:
+    case CLK_PWM2:
+    case CLK_PWM3:
+    case CLK_PMU1PWM:
+        rate = rk3588_pwm_get_clk(priv, pdata->id);
+        break;
+    case CLK_SARADC:
+    case CLK_TSADC:
+        rate = rk3588_adc_get_clk(priv, pdata->id);
+        break;
+    case CCLK_SRC_SDIO:
+    case CCLK_EMMC:
+    case BCLK_EMMC:
+    case SCLK_SFC:
+    case DCLK_DECOM:
+        rate = rk3588_mmc_get_clk(priv, pdata->id);
+        break;
+    case TCLK_WDT0:
+        rate = OSC_HZ;
+        break;
+#ifndef CONFIG_SPL_BUILD
+    case CLK_AUX16M_0:
+    case CLK_AUX16M_1:
+        rk3588_aux16m_get_clk(priv, pdata->id);
+        break;
+    case ACLK_VOP_ROOT:
+    case ACLK_VOP:
+    case ACLK_VOP_LOW_ROOT:
+    case HCLK_VOP_ROOT:
+        rate = rk3588_aclk_vop_get_clk(priv, pdata->id);
+        break;
+    case DCLK_VOP0:
+    case DCLK_VOP0_SRC:
+    case DCLK_VOP1:
+    case DCLK_VOP1_SRC:
+    case DCLK_VOP2:
+    case DCLK_VOP2_SRC:
+    case DCLK_VOP3:
+        rate = rk3588_dclk_vop_get_clk(priv, pdata->id);
+        break;
+    case CLK_GMAC0_PTP_REF:
+    case CLK_GMAC1_PTP_REF:
+    case CLK_GMAC_125M:
+    case CLK_GMAC_50M:
+        rate = rk3588_gmac_get_clk(priv, pdata->id);
+        break;
+    case SCLK_UART1:
+    case SCLK_UART2:
+    case SCLK_UART3:
+    case SCLK_UART4:
+    case SCLK_UART5:
+    case SCLK_UART6:
+    case SCLK_UART7:
+    case SCLK_UART8:
+    case SCLK_UART9:
+        rate = rk3588_uart_get_rate(priv, pdata->id);
+        break;
+    case CLK_REF_PIPE_PHY0:
+    case CLK_REF_PIPE_PHY1:
+    case CLK_REF_PIPE_PHY2:
+        rate = rk3588_pciephy_get_rate(priv, pdata->id);
+        break;
+#endif
+    default:
+        return -RT_ENOENT;
+    }
+
+    return rate;
+};
+
+static rt_err_t mmc_set_phase(struct rk3588_clk_platform_data *pdata,
+        struct rk3588_clk *rk_clk, rt_uint32_t degrees)
+{
+    void *reg;
+    rt_ubase_t rate;
+    struct rk3588_clk_priv *priv = &rk_clk->clk_info;
+    struct rk3588_cru *cru = priv->cru;
+
+    rate = rk_clk_get_rate(pdata, rk_clk);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDIO_DRV:
+        reg = &cru->sdio_con[0];
+        break;
+
+    case SCLK_SDIO_SAMPLE:
+        reg = &cru->sdio_con[1];
+        break;
+
+    case SCLK_SDMMC_DRV:
+        reg = &cru->sdmmc_con[0];
+        break;
+
+    case SCLK_SDMMC_SAMPLE:
+        reg = &cru->sdmmc_con[1];
+        break;
+    }
+
+    return rk_clk_mmc_set_phase(rate, reg, 1, degrees);
+}
+
+static rt_base_t mmc_get_phase(struct rk3588_clk_platform_data *pdata,
+        struct rk3588_clk *rk_clk)
+{
+    void *reg;
+    rt_ubase_t rate;
+    struct rk3588_clk_priv *priv = &rk_clk->clk_info;
+    struct rk3588_cru *cru = priv->cru;
+
+    rate = rk_clk_get_rate(pdata, rk_clk);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDIO_DRV:
+        reg = &cru->sdio_con[0];
+        break;
+
+    case SCLK_SDIO_SAMPLE:
+        reg = &cru->sdio_con[1];
+        break;
+
+    case SCLK_SDMMC_DRV:
+        reg = &cru->sdmmc_con[0];
+        break;
+
+    case SCLK_SDMMC_SAMPLE:
+        reg = &cru->sdmmc_con[1];
+        break;
+    }
+
+    return rk_clk_mmc_get_phase(rate, reg, 1);
+}
+
+static rt_err_t rk3588_clk_init(struct rt_clk *clk, void *fw_data)
+{
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rt_ofw_cell_args *args = fw_data;
+    struct rk3588_clk_platform_data *pdata;
+    rt_uint32_t clk_id = args->args[0];
+    rt_ubase_t reg_base;
+
+    pdata = &rk_clk->pdata[clk_id];
+
+    reg_base = (rt_ubase_t)rk_clk->clk_info.cru;
+
+    switch (clk_id)
+    {
+    case PLL_B0PLL:
+        reg_base += rk3588_pll_clks[B0PLL].con_offset;
+        break;
+    case PLL_B1PLL:
+        reg_base += rk3588_pll_clks[B1PLL].con_offset;
+        break;
+    case PLL_LPLL:
+        reg_base += rk3588_pll_clks[LPLL].con_offset;
+        break;
+    case PLL_V0PLL:
+        reg_base += rk3588_pll_clks[V0PLL].con_offset;
+        break;
+    case PLL_AUPLL:
+        reg_base += rk3588_pll_clks[AUPLL].con_offset;
+        break;
+    case PLL_CPLL:
+        reg_base += rk3588_pll_clks[CPLL].con_offset;
+        break;
+    case PLL_GPLL:
+        reg_base += rk3588_pll_clks[GPLL].con_offset;
+        break;
+    case PLL_NPLL:
+        reg_base += rk3588_pll_clks[NPLL].con_offset;
+        break;
+    case PLL_PPLL:
+        reg_base += rk3588_pll_clks[PPLL].con_offset;
+        break;
+    default:
+        reg_base = RT_NULL;
+        break;
+    }
+
+    pdata->id = clk_id;
+    pdata->base = (void *)reg_base;
+
+    clk->rate = rk_clk_get_rate(pdata, rk_clk);
+    clk->priv = pdata;
+
+    rk_clk_set_default_rates(clk, clk->clk_np->ops->set_rate, clk_id);
+
+    return RT_EOK;
+}
+
+static rt_err_t rk_clk_wait_lock(struct rk3588_clk_platform_data *pdata)
+{
+    rt_err_t err = RT_EOK;
+    rt_uint32_t count = 0, pllcon;
+
+    /*
+     * Lock time typical 250, max 500 input clock cycles @24MHz, So define a
+     * very safe maximum of 1000us, meaning 24000 cycles.
+     */
+    do {
+        pllcon = HWREG32(pdata->base + 6*4);
+        ++count;
+    } while (pllcon & RK3588_PLLCON6_LOCK_STATUS && count < 10);
+
+    if (count >= 10)
+    {
+        err = -RT_ETIMEOUT;
+    }
+
+    return err;
+}
+
+static rt_err_t rk3588_clk_enable(struct rt_clk *clk)
+{
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rk3588_cru *cru = rk_clk->clk_info.cru;
+
+    if (pdata->base)
+    {
+        #define PLL_CON(x)              ((x) * 0x4)
+        HWREG32(pdata->base + PLL_CON(6)) = HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0);
+
+        rk_clk_wait_lock(pdata);
+    }
+    else
+    {
+        void *con_regs;
+        struct rk3588_clk_gate *gate;
+
+            gate = &clk_gates[pdata->id];
+            con_regs = (void*)cru + gate->offset;
+
+        rk_clrreg(con_regs, RT_BIT(gate->con_bit));
+    }
+
+    return RT_EOK;
+}
+
+
+static void rk3588_clk_disable(struct rt_clk *clk)
+{
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rk3588_cru *cru = rk_clk->clk_info.cru;
+
+    if (pdata->base)
+    {
+        HWREG32(pdata->base + PLL_CON(1)) = HIWORD_UPDATE(RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0);
+    }
+    else
+    {
+        void *con_regs;
+        struct rk3588_clk_gate *gate;
+
+            gate = &clk_gates[pdata->id];
+            con_regs = (void*)cru + gate->offset;
+
+        rk_setreg(con_regs, RT_BIT(gate->con_bit));
+    }
+
+}
+
+static rt_bool_t rk3588_clk_is_enabled(struct rt_clk *clk)
+{
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+
+    if (pdata->base)
+    {
+        rt_uint32_t pllcon = HWREG32(pdata->base + PLL_CON(1));
+
+        return !(pllcon & RK3588_PLLCON1_PWRDOWN);
+    }
+
+    return RT_TRUE;
+}
+
+static rt_err_t rk3588_clk_set_rate(struct rt_clk *clk, rt_ubase_t rate, rt_ubase_t prate)
+{
+    rt_ubase_t ret = 0;
+    rt_ubase_t res_rate;
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    struct rk3588_clk_priv *priv = &rk_clk->clk_info;
+
+    if (!priv->gpll_hz)
+    {
+        LOG_D("%s gpll=%lu\n", __func__, priv->gpll_hz);
+        return -RT_ENOENT;
+    }
+
+    if (!priv->ppll_hz)
+    {
+        priv->ppll_hz = rk_pll_get_rate(&rk3588_pll_clks[PPLL],
+                              priv->cru, PPLL);
+    }
+
+    switch (pdata->id)
+    {
+    case PLL_CPLL:
+        res_rate = rk_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
+                        CPLL, rate);
+        priv->cpll_hz = rk_pll_get_rate(&rk3588_pll_clks[CPLL],
+                              priv->cru, CPLL);
+        break;
+    case PLL_GPLL:
+        res_rate = rk_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
+                        GPLL, rate);
+        priv->gpll_hz = rk_pll_get_rate(&rk3588_pll_clks[GPLL],
+                              priv->cru, GPLL);
+        break;
+    case PLL_NPLL:
+        res_rate = rk_pll_set_rate(&rk3588_pll_clks[NPLL], priv->cru,
+                        NPLL, rate);
+        break;
+    case PLL_V0PLL:
+        res_rate = rk_pll_set_rate(&rk3588_pll_clks[V0PLL], priv->cru,
+                        V0PLL, rate);
+        priv->v0pll_hz = rk_pll_get_rate(&rk3588_pll_clks[V0PLL],
+                               priv->cru, V0PLL);
+        break;
+    case PLL_AUPLL:
+        res_rate = rk_pll_set_rate(&rk3588_pll_clks[AUPLL], priv->cru,
+                        AUPLL, rate);
+        priv->aupll_hz = rk_pll_get_rate(&rk3588_pll_clks[AUPLL],
+                               priv->cru, AUPLL);
+        break;
+    case PLL_PPLL:
+        res_rate = rk_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
+                        PPLL, rate);
+        priv->ppll_hz = rk_pll_get_rate(&rk3588_pll_clks[PPLL],
+                              priv->cru, PPLL);
+        break;
+    case ACLK_CENTER_ROOT:
+    case PCLK_CENTER_ROOT:
+    case HCLK_CENTER_ROOT:
+    case ACLK_CENTER_LOW_ROOT:
+        res_rate = rk3588_center_set_clk(priv, pdata->id, rate);
+        break;
+    case ACLK_TOP_ROOT:
+    case PCLK_TOP_ROOT:
+    case ACLK_LOW_TOP_ROOT:
+        res_rate = rk3588_top_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_I2C0:
+    case CLK_I2C1:
+    case CLK_I2C2:
+    case CLK_I2C3:
+    case CLK_I2C4:
+    case CLK_I2C5:
+    case CLK_I2C6:
+    case CLK_I2C7:
+    case CLK_I2C8:
+        res_rate = rk3588_i2c_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_SPI0:
+    case CLK_SPI1:
+    case CLK_SPI2:
+    case CLK_SPI3:
+    case CLK_SPI4:
+        res_rate = rk3588_spi_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_PWM1:
+    case CLK_PWM2:
+    case CLK_PWM3:
+    case CLK_PMU1PWM:
+        res_rate = rk3588_pwm_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_SARADC:
+    case CLK_TSADC:
+        res_rate = rk3588_adc_set_clk(priv, pdata->id, rate);
+        break;
+    case CCLK_SRC_SDIO:
+    case CCLK_EMMC:
+    case BCLK_EMMC:
+    case SCLK_SFC:
+    case DCLK_DECOM:
+        res_rate = rk3588_mmc_set_clk(priv, pdata->id, rate);
+        break;
+    case TCLK_WDT0:
+        res_rate = OSC_HZ;
+        break;
+#ifndef CONFIG_SPL_BUILD
+    case CLK_AUX16M_0:
+    case CLK_AUX16M_1:
+        rk3588_aux16m_set_clk(priv, pdata->id, rate);
+        break;
+    case ACLK_VOP_ROOT:
+    case ACLK_VOP:
+    case ACLK_VOP_LOW_ROOT:
+    case HCLK_VOP_ROOT:
+        res_rate = rk3588_aclk_vop_set_clk(priv, pdata->id, rate);
+        break;
+    case DCLK_VOP0:
+    case DCLK_VOP0_SRC:
+    case DCLK_VOP1:
+    case DCLK_VOP1_SRC:
+    case DCLK_VOP2:
+    case DCLK_VOP2_SRC:
+    case DCLK_VOP3:
+        res_rate = rk3588_dclk_vop_set_clk(priv, pdata->id, rate);
+        break;
+    case CLK_GMAC0_PTP_REF:
+    case CLK_GMAC1_PTP_REF:
+    case CLK_GMAC_125M:
+    case CLK_GMAC_50M:
+        res_rate = rk3588_gmac_set_clk(priv, pdata->id, rate);
+        break;
+    case SCLK_UART1:
+    case SCLK_UART2:
+    case SCLK_UART3:
+    case SCLK_UART4:
+    case SCLK_UART5:
+    case SCLK_UART6:
+    case SCLK_UART7:
+    case SCLK_UART8:
+    case SCLK_UART9:
+        res_rate = rk3588_uart_set_rate(priv, pdata->id, rate);
+        break;
+    case CLK_REF_PIPE_PHY0:
+    case CLK_REF_PIPE_PHY1:
+    case CLK_REF_PIPE_PHY2:
+        res_rate = rk3588_pciephy_set_rate(priv, pdata->id, rate);
+        break;
+#endif
+    default:
+        return -RT_ENOENT;
+    }
+
+    if ((rt_base_t)res_rate > 0)
+    {
+        clk->rate = res_rate;
+    }
+    else
+    {
+        ret = (rt_ubase_t)res_rate > 0 ? RT_EOK : (rt_err_t)res_rate;
+    }
+
+    return ret;
+};
+
+static int  rk3588_dclk_vop_set_parent(struct rt_clk *clk,
+                             struct rt_clk *parent)
+{
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    struct rk3588_clk_platform_data *ppdata = parent->priv;
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+    /*struct rk3588_clk_priv *priv = &rk_clk->clk_info;*/
+    struct rk3588_cru *cru = rk_clk->clk_info.cru;
+
+    rt_uint32_t sel;
+    const char *clock_dev_name = parent->dev_id;
+
+    if (ppdata->id == PLL_V0PLL)
+        sel = 2;
+    else if (ppdata->id == PLL_GPLL)
+        sel = 0;
+    else if (ppdata->id == PLL_CPLL)
+        sel = 1;
+    else
+        sel = 3;
+
+    switch (pdata->id)
+    {
+    case DCLK_VOP0_SRC:
+        rk_clrsetreg(&cru->clksel_con[111], DCLK0_VOP_SRC_SEL_MASK,
+                 sel << DCLK0_VOP_SRC_SEL_SHIFT);
+        break;
+    case DCLK_VOP1_SRC:
+        rk_clrsetreg(&cru->clksel_con[111], DCLK1_VOP_SRC_SEL_MASK,
+                 sel << DCLK1_VOP_SRC_SEL_SHIFT);
+        break;
+    case DCLK_VOP2_SRC:
+        rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SRC_SEL_MASK,
+                 sel << DCLK2_VOP_SRC_SEL_SHIFT);
+        break;
+    case DCLK_VOP3:
+        rk_clrsetreg(&cru->clksel_con[113], DCLK3_VOP_SRC_SEL_MASK,
+                 sel << DCLK3_VOP_SRC_SEL_SHIFT);
+        break;
+    case DCLK_VOP0:
+        if (!rt_strcmp(clock_dev_name, "hdmiphypll_clk0"))
+            sel = 1;
+        else if (!rt_strcmp(clock_dev_name, "hdmiphypll_clk1"))
+            sel = 2;
+        else
+            sel = 0;
+        rk_clrsetreg(&cru->clksel_con[112], DCLK0_VOP_SEL_MASK,
+                 sel << DCLK0_VOP_SEL_SHIFT);
+        break;
+    case DCLK_VOP1:
+        if (!rt_strcmp(clock_dev_name, "hdmiphypll_clk0"))
+            sel = 1;
+        else if (!rt_strcmp(clock_dev_name, "hdmiphypll_clk1"))
+            sel = 2;
+        else
+            sel = 0;
+        rk_clrsetreg(&cru->clksel_con[112], DCLK1_VOP_SEL_MASK,
+                 sel << DCLK1_VOP_SEL_SHIFT);
+        break;
+    case DCLK_VOP2:
+        if (!rt_strcmp(clock_dev_name, "hdmiphypll_clk0"))
+            sel = 1;
+        else if (!rt_strcmp(clock_dev_name, "hdmiphypll_clk1"))
+            sel = 2;
+        else
+            sel = 0;
+        rk_clrsetreg(&cru->clksel_con[112], DCLK2_VOP_SEL_MASK,
+                 sel << DCLK2_VOP_SEL_SHIFT);
+        break;
+    default:
+        return -RT_EINVAL;
+    }
+    return 0;
+}
+
+static rt_err_t rk3588_clk_set_parent(struct rt_clk *clk, struct rt_clk *parent)
+{
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    switch (pdata->id)
+    {
+    case DCLK_VOP0_SRC:
+    case DCLK_VOP1_SRC:
+    case DCLK_VOP2_SRC:
+    case DCLK_VOP0:
+    case DCLK_VOP1:
+    case DCLK_VOP2:
+    case DCLK_VOP3:
+        return rk3588_dclk_vop_set_parent(clk, parent);
+    default:
+        return -RT_ENOENT;
+    }
+
+    return 0;
+}
+
+static rt_err_t rk3588_clk_set_phase(struct rt_clk *clk, int degrees)
+{
+    rt_err_t res;
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDIO_DRV:
+    case SCLK_SDIO_SAMPLE:
+    case SCLK_SDMMC_DRV:
+    case SCLK_SDMMC_SAMPLE:
+        res = mmc_set_phase(pdata, rk_clk, degrees);
+        break;
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return res;
+}
+
+static rt_base_t rk3588_clk_get_phase(struct rt_clk *clk)
+{
+    rt_base_t res;
+    struct rk3588_clk_platform_data *pdata = clk->priv;
+    struct rk3588_clk *rk_clk = raw_to_rk_clk(clk->clk_np);
+
+    switch (pdata->id)
+    {
+    case SCLK_SDIO_DRV:
+    case SCLK_SDIO_SAMPLE:
+    case SCLK_SDMMC_DRV:
+    case SCLK_SDMMC_SAMPLE:
+        res = mmc_get_phase(pdata, rk_clk);
+        break;
+
+    default:
+        return -RT_EINVAL;
+    }
+
+    return res;
+}
+
+static rt_base_t rk3588_clk_round_rate(struct rt_clk *clk, rt_ubase_t drate,
+        rt_ubase_t *prate)
+{
+    return rk_clk_pll_round_rate(rk3588_pll_rates, RT_ARRAY_SIZE(rk3588_pll_rates), drate, prate);
+}
+
+static const struct rt_clk_ops rk3588_clk_ops =
+{
+    .init = rk3588_clk_init,
+    .enable = rk3588_clk_enable,
+    .disable = rk3588_clk_disable,
+    .is_enabled = rk3588_clk_is_enabled,
+    .set_rate = rk3588_clk_set_rate,
+    .set_parent = rk3588_clk_set_parent,
+    .set_phase = rk3588_clk_set_phase,
+    .get_phase = rk3588_clk_get_phase,
+    .round_rate = rk3588_clk_round_rate,
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+static void rk3588_cru_init(struct rk3588_clk *rk_clk, struct rt_ofw_node *np)
+{
+    rt_int32_t ret, div;
+
+    struct rk3588_clk_priv *priv = &rk_clk->clk_info;
+
+div = RT_DIV_ROUND_UP(GPLL_HZ, 300 * MHz);
+priv->cru = (struct rk3588_cru *)rk_clk->base;
+    rk_clrsetreg(&priv->cru->clksel_con[38],
+             ACLK_BUS_ROOT_SEL_MASK |
+             ACLK_BUS_ROOT_DIV_MASK,
+             div << ACLK_BUS_ROOT_DIV_SHIFT);
+
+
+    if (priv->cpll_hz != CPLL_HZ)
+    {
+        ret = rk_pll_set_rate(&rk3588_pll_clks[CPLL], priv->cru,
+                        CPLL, CPLL_HZ);
+        if (!ret)
+            priv->cpll_hz = CPLL_HZ;
+    }
+    if (priv->gpll_hz != GPLL_HZ)
+    {
+        ret = rk_pll_set_rate(&rk3588_pll_clks[GPLL], priv->cru,
+                        GPLL, GPLL_HZ);
+        if (!ret)
+            priv->gpll_hz = GPLL_HZ;
+    }
+
+    if (priv->ppll_hz != PPLL_HZ)
+    {
+        ret = rk_pll_set_rate(&rk3588_pll_clks[PPLL], priv->cru,
+                        PPLL, PPLL_HZ);
+        priv->ppll_hz = rk_pll_get_rate(&rk3588_pll_clks[PPLL],
+                              priv->cru, PPLL);
+    }
+    rk_clrsetreg(&priv->cru->clksel_con[9],
+             ACLK_TOP_S400_SEL_MASK |
+             ACLK_TOP_S200_SEL_MASK,
+             (ACLK_TOP_S400_SEL_400M << ACLK_TOP_S400_SEL_SHIFT) |
+             (ACLK_TOP_S200_SEL_200M << ACLK_TOP_S200_SEL_SHIFT));
+}
+static rt_err_t clk_rk3588_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    rt_size_t data_size = CLK_NR_CLKS * sizeof(struct rk3588_clk_platform_data);
+    struct rk3588_clk *rk_clk;
+    struct rt_ofw_node *np = pdev->parent.ofw_node;
+
+    rk_clk = rt_malloc(sizeof(*rk_clk) + data_size);
+
+    if (rk_clk)
+    {
+        void *softrst_regs = RT_NULL;
+        rt_memset(&rk_clk->parent, 0, sizeof(rk_clk->parent));
+
+        rk_clk->base = rt_ofw_iomap(np, 0);
+/*rt_kprintf("base %p\n", rk_clk->base);*/
+        if (!rk_clk->base)
+        {
+            err = -RT_EIO;
+            goto _fail;
+        }
+
+
+            rk3588_cru_init(rk_clk, np);
+            softrst_regs = &rk_clk->clk_info.cru->softrst_con;
+
+
+        rk_clk->parent.parent.ops = &rk3588_clk_ops;
+
+        if ((err = rt_clk_register(&rk_clk->parent.parent, RT_NULL)))
+        {
+            goto _fail;
+        }
+
+        if ((err = rk_register_softrst(&rk_clk->parent.rstcer, np,
+                softrst_regs, ROCKCHIP_SOFTRST_HIWORD_MASK)))
+        {
+            goto _fail;
+        }
+
+        rt_ofw_data(np) = &rk_clk->parent;
+    }
+    else
+    {
+        err = -RT_ENOMEM;
+    }
+
+    return err;
+
+_fail:
+    if (rk_clk->base)
+    {
+        rt_iounmap(rk_clk->base);
+    }
+
+    rt_free(rk_clk);
+
+    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);

+ 152 - 0
bsp/rockchip/rk3500/driver/clk/clk-rk3588.h

@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2006-2024 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_CLK_H__
+#define __ROCKCHIP_CLK_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include "reset/reset.h"
+#include <stdlib.h>
+#include "../rockchip.h"
+
+#define HZ      100
+#define KHZ     1000
+#define MHZ     1000000
+#define OSC_HZ  (24 * MHZ)
+
+struct rk_cpu_rate_table
+{
+    rt_ubase_t rate;
+    rt_uint32_t aclk_div;
+    rt_uint32_t pclk_div;
+};
+
+struct rk_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;
+        };
+    };
+};
+
+enum rk_pll_type {
+    pll_rk3036,
+    pll_rk3066,
+    pll_rk3328,
+    pll_rk3366,
+    pll_rk3399,
+    pll_rk3588,
+};
+
+typedef rt_uint32_t rk_pll_type_t;
+
+struct rk_pll_clock
+{
+    rt_uint32_t id;
+    rt_uint32_t con_offset;
+    rt_uint32_t mode_offset;
+    rt_uint32_t mode_shift;
+    rt_uint32_t lock_shift;
+    rk_pll_type_t type;
+    rt_uint32_t pll_flags;
+    struct rk_pll_rate_table *rate_table;
+    rt_uint32_t mode_mask;
+};
+struct rk_clk_gate
+{
+    const char *name;
+    const char *parent_name;
+
+    int con_idx;
+    int con_bit;
+};
+
+#define GATE(_id, _name,    \
+_pname, _con_idx, _con_bit) \
+[_id] =                     \
+{                           \
+    .name = _name,          \
+    .parent_name = _pname,  \
+    .con_idx = _con_idx,    \
+    .con_bit = _con_bit,    \
+}
+
+
+#define CPUCLK_RATE(_rate,  \
+    _aclk_div, _pclk_div)   \
+{                           \
+    .rate     = _rate##U,   \
+    .aclk_div = _aclk_div,  \
+    .pclk_div = _pclk_div,  \
+}
+
+#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,                        \
+}
+
+#define PLL(_type, _id, _con, _mode, _mshift,  \
+    _lshift, _pflags, _rtable)          \
+{                                       \
+    .type        = _type,               \
+    .id          = _id,                 \
+    .con_offset  = _con,                \
+    .mode_offset = _mode,               \
+    .mode_shift  = _mshift,             \
+    .lock_shift  = _lshift,             \
+    .pll_flags   = _pflags,             \
+    .rate_table  = _rtable,             \
+}
+
+#define DIV_TO_RATE(input_rate, div)    ((input_rate) / ((div) + 1))
+
+#define ROCKCHIP_SOFTRST_HIWORD_MASK    RT_BIT(0)
+
+#endif /* __ROCKCHIP_CLK_H__ */

+ 926 - 0
bsp/rockchip/rk3500/driver/clk/rk3568-cru.h

@@ -0,0 +1,926 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3568_H__
+#define __DT_BINDINGS_CLK_ROCKCHIP_RK3568_H__
+
+/* pmucru-clocks indices */
+
+/* pmucru plls */
+#define PLL_PPLL                1
+#define PLL_HPLL                2
+
+/* pmucru clocks */
+#define XIN_OSC0_DIV            4
+#define CLK_RTC_32K             5
+#define CLK_PMU                 6
+#define CLK_I2C0                7
+#define CLK_RTC32K_FRAC         8
+#define CLK_UART0_DIV           9
+#define CLK_UART0_FRAC          10
+#define SCLK_UART0              11
+#define DBCLK_GPIO0             12
+#define CLK_PWM0                13
+#define CLK_CAPTURE_PWM0_NDFT   14
+#define CLK_PMUPVTM             15
+#define CLK_CORE_PMUPVTM        16
+#define CLK_REF24M              17
+#define XIN_OSC0_USBPHY0_G      18
+#define CLK_USBPHY0_REF         19
+#define XIN_OSC0_USBPHY1_G      20
+#define CLK_USBPHY1_REF         21
+#define XIN_OSC0_MIPIDSIPHY0_G  22
+#define CLK_MIPIDSIPHY0_REF     23
+#define XIN_OSC0_MIPIDSIPHY1_G  24
+#define CLK_MIPIDSIPHY1_REF     25
+#define CLK_WIFI_DIV            26
+#define CLK_WIFI_OSC0           27
+#define CLK_WIFI                28
+#define CLK_PCIEPHY0_DIV        29
+#define CLK_PCIEPHY0_OSC0       30
+#define CLK_PCIEPHY0_REF        31
+#define CLK_PCIEPHY1_DIV        32
+#define CLK_PCIEPHY1_OSC0       33
+#define CLK_PCIEPHY1_REF        34
+#define CLK_PCIEPHY2_DIV        35
+#define CLK_PCIEPHY2_OSC0       36
+#define CLK_PCIEPHY2_REF        37
+#define CLK_PCIE30PHY_REF_M     38
+#define CLK_PCIE30PHY_REF_N     39
+#define CLK_HDMI_REF            40
+#define XIN_OSC0_EDPPHY_G       41
+#define PCLK_PDPMU              42
+#define PCLK_PMU                43
+#define PCLK_UART0              44
+#define PCLK_I2C0               45
+#define PCLK_GPIO0              46
+#define PCLK_PMUPVTM            47
+#define PCLK_PWM0               48
+#define CLK_PDPMU               49
+#define SCLK_32K_IOE            50
+
+#define CLKPMU_NR_CLKS          (SCLK_32K_IOE + 1)
+
+/* cru-clocks indices */
+
+/* cru plls */
+#define PLL_APLL                1
+#define PLL_DPLL                2
+#define PLL_CPLL                3
+#define PLL_GPLL                4
+#define PLL_VPLL                5
+#define PLL_NPLL                6
+
+/* cru clocks */
+#define CPLL_333M               9
+#define ARMCLK                  10
+#define USB480M                 11
+#define ACLK_CORE_NIU2BUS       18
+#define CLK_CORE_PVTM           19
+#define CLK_CORE_PVTM_CORE      20
+#define CLK_CORE_PVTPLL         21
+#define CLK_GPU_SRC             22
+#define CLK_GPU_PRE_NDFT        23
+#define CLK_GPU_PRE_MUX         24
+#define ACLK_GPU_PRE            25
+#define PCLK_GPU_PRE            26
+#define CLK_GPU                 27
+#define CLK_GPU_NP5             28
+#define PCLK_GPU_PVTM           29
+#define CLK_GPU_PVTM            30
+#define CLK_GPU_PVTM_CORE       31
+#define CLK_GPU_PVTPLL          32
+#define CLK_NPU_SRC             33
+#define CLK_NPU_PRE_NDFT        34
+#define CLK_NPU                 35
+#define CLK_NPU_NP5             36
+#define HCLK_NPU_PRE            37
+#define PCLK_NPU_PRE            38
+#define ACLK_NPU_PRE            39
+#define ACLK_NPU                40
+#define HCLK_NPU                41
+#define PCLK_NPU_PVTM           42
+#define CLK_NPU_PVTM            43
+#define CLK_NPU_PVTM_CORE       44
+#define CLK_NPU_PVTPLL          45
+#define CLK_DDRPHY1X_SRC        46
+#define CLK_DDRPHY1X_HWFFC_SRC  47
+#define CLK_DDR1X               48
+#define CLK_MSCH                49
+#define CLK24_DDRMON            50
+#define ACLK_GIC_AUDIO          51
+#define HCLK_GIC_AUDIO          52
+#define HCLK_SDMMC_BUFFER       53
+#define DCLK_SDMMC_BUFFER       54
+#define ACLK_GIC600             55
+#define ACLK_SPINLOCK           56
+#define HCLK_I2S0_8CH           57
+#define HCLK_I2S1_8CH           58
+#define HCLK_I2S2_2CH           59
+#define HCLK_I2S3_2CH           60
+#define CLK_I2S0_8CH_TX_SRC     61
+#define CLK_I2S0_8CH_TX_FRAC    62
+#define MCLK_I2S0_8CH_TX        63
+#define I2S0_MCLKOUT_TX         64
+#define CLK_I2S0_8CH_RX_SRC     65
+#define CLK_I2S0_8CH_RX_FRAC    66
+#define MCLK_I2S0_8CH_RX        67
+#define I2S0_MCLKOUT_RX         68
+#define CLK_I2S1_8CH_TX_SRC     69
+#define CLK_I2S1_8CH_TX_FRAC    70
+#define MCLK_I2S1_8CH_TX        71
+#define I2S1_MCLKOUT_TX         72
+#define CLK_I2S1_8CH_RX_SRC     73
+#define CLK_I2S1_8CH_RX_FRAC    74
+#define MCLK_I2S1_8CH_RX        75
+#define I2S1_MCLKOUT_RX         76
+#define CLK_I2S2_2CH_SRC        77
+#define CLK_I2S2_2CH_FRAC       78
+#define MCLK_I2S2_2CH           79
+#define I2S2_MCLKOUT            80
+#define CLK_I2S3_2CH_TX_SRC     81
+#define CLK_I2S3_2CH_TX_FRAC    82
+#define MCLK_I2S3_2CH_TX        83
+#define I2S3_MCLKOUT_TX         84
+#define CLK_I2S3_2CH_RX_SRC     85
+#define CLK_I2S3_2CH_RX_FRAC    86
+#define MCLK_I2S3_2CH_RX        87
+#define I2S3_MCLKOUT_RX         88
+#define HCLK_PDM                89
+#define MCLK_PDM                90
+#define HCLK_VAD                91
+#define HCLK_SPDIF_8CH          92
+#define MCLK_SPDIF_8CH_SRC      93
+#define MCLK_SPDIF_8CH_FRAC     94
+#define MCLK_SPDIF_8CH          95
+#define HCLK_AUDPWM             96
+#define SCLK_AUDPWM_SRC         97
+#define SCLK_AUDPWM_FRAC        98
+#define SCLK_AUDPWM             99
+#define HCLK_ACDCDIG            100
+#define CLK_ACDCDIG_I2C         101
+#define CLK_ACDCDIG_DAC         102
+#define CLK_ACDCDIG_ADC         103
+#define ACLK_SECURE_FLASH       104
+#define HCLK_SECURE_FLASH       105
+#define ACLK_CRYPTO_NS          106
+#define HCLK_CRYPTO_NS          107
+#define CLK_CRYPTO_NS_CORE      108
+#define CLK_CRYPTO_NS_PKA       109
+#define CLK_CRYPTO_NS_RNG       110
+#define HCLK_TRNG_NS            111
+#define CLK_TRNG_NS             112
+#define PCLK_OTPC_NS            113
+#define CLK_OTPC_NS_SBPI        114
+#define CLK_OTPC_NS_USR         115
+#define HCLK_NANDC              116
+#define NCLK_NANDC              117
+#define HCLK_SFC                118
+#define HCLK_SFC_XIP            119
+#define SCLK_SFC                120
+#define ACLK_EMMC               121
+#define HCLK_EMMC               122
+#define BCLK_EMMC               123
+#define CCLK_EMMC               124
+#define TCLK_EMMC               125
+#define ACLK_PIPE               126
+#define PCLK_PIPE               127
+#define PCLK_PIPE_GRF           128
+#define ACLK_PCIE20_MST         129
+#define ACLK_PCIE20_SLV         130
+#define ACLK_PCIE20_DBI         131
+#define PCLK_PCIE20             132
+#define CLK_PCIE20_AUX_NDFT     133
+#define CLK_PCIE20_AUX_DFT      134
+#define CLK_PCIE20_PIPE_DFT     135
+#define ACLK_PCIE30X1_MST       136
+#define ACLK_PCIE30X1_SLV       137
+#define ACLK_PCIE30X1_DBI       138
+#define PCLK_PCIE30X1           139
+#define CLK_PCIE30X1_AUX_NDFT   140
+#define CLK_PCIE30X1_AUX_DFT    141
+#define CLK_PCIE30X1_PIPE_DFT   142
+#define ACLK_PCIE30X2_MST       143
+#define ACLK_PCIE30X2_SLV       144
+#define ACLK_PCIE30X2_DBI       145
+#define PCLK_PCIE30X2           146
+#define CLK_PCIE30X2_AUX_NDFT   147
+#define CLK_PCIE30X2_AUX_DFT    148
+#define CLK_PCIE30X2_PIPE_DFT   149
+#define ACLK_SATA0              150
+#define CLK_SATA0_PMALIVE       151
+#define CLK_SATA0_RXOOB         152
+#define CLK_SATA0_PIPE_NDFT     153
+#define CLK_SATA0_PIPE_DFT      154
+#define ACLK_SATA1              155
+#define CLK_SATA1_PMALIVE       156
+#define CLK_SATA1_RXOOB         157
+#define CLK_SATA1_PIPE_NDFT     158
+#define CLK_SATA1_PIPE_DFT      159
+#define ACLK_SATA2              160
+#define CLK_SATA2_PMALIVE       161
+#define CLK_SATA2_RXOOB         162
+#define CLK_SATA2_PIPE_NDFT     163
+#define CLK_SATA2_PIPE_DFT      164
+#define ACLK_USB3OTG0           165
+#define CLK_USB3OTG0_REF        166
+#define CLK_USB3OTG0_SUSPEND    167
+#define ACLK_USB3OTG1           168
+#define CLK_USB3OTG1_REF        169
+#define CLK_USB3OTG1_SUSPEND    170
+#define CLK_XPCS_EEE            171
+#define PCLK_XPCS               172
+#define ACLK_PHP                173
+#define HCLK_PHP                174
+#define PCLK_PHP                175
+#define HCLK_SDMMC0             176
+#define CLK_SDMMC0              177
+#define HCLK_SDMMC1             178
+#define CLK_SDMMC1              179
+#define ACLK_GMAC0              180
+#define PCLK_GMAC0              181
+#define CLK_MAC0_2TOP           182
+#define CLK_MAC0_OUT            183
+#define CLK_MAC0_REFOUT         184
+#define CLK_GMAC0_PTP_REF       185
+#define ACLK_USB                186
+#define HCLK_USB                187
+#define PCLK_USB                188
+#define HCLK_USB2HOST0          189
+#define HCLK_USB2HOST0_ARB      190
+#define HCLK_USB2HOST1          191
+#define HCLK_USB2HOST1_ARB      192
+#define HCLK_SDMMC2             193
+#define CLK_SDMMC2              194
+#define ACLK_GMAC1              195
+#define PCLK_GMAC1              196
+#define CLK_MAC1_2TOP           197
+#define CLK_MAC1_OUT            198
+#define CLK_MAC1_REFOUT         199
+#define CLK_GMAC1_PTP_REF       200
+#define ACLK_PERIMID            201
+#define HCLK_PERIMID            202
+#define ACLK_VI                 203
+#define HCLK_VI                 204
+#define PCLK_VI                 205
+#define ACLK_VICAP              206
+#define HCLK_VICAP              207
+#define DCLK_VICAP              208
+#define ICLK_VICAP_G            209
+#define ACLK_ISP                210
+#define HCLK_ISP                211
+#define CLK_ISP                 212
+#define PCLK_CSI2HOST1          213
+#define CLK_CIF_OUT             214
+#define CLK_CAM0_OUT            215
+#define CLK_CAM1_OUT            216
+#define ACLK_VO                 217
+#define HCLK_VO                 218
+#define PCLK_VO                 219
+#define ACLK_VOP_PRE            220
+#define ACLK_VOP                221
+#define HCLK_VOP                222
+#define DCLK_VOP0               223
+#define DCLK_VOP1               224
+#define DCLK_VOP2               225
+#define CLK_VOP_PWM             226
+#define ACLK_HDCP               227
+#define HCLK_HDCP               228
+#define PCLK_HDCP               229
+#define PCLK_HDMI_HOST          230
+#define CLK_HDMI_SFR            231
+#define PCLK_DSITX_0            232
+#define PCLK_DSITX_1            233
+#define PCLK_EDP_CTRL           234
+#define CLK_EDP_200M            235
+#define ACLK_VPU_PRE            236
+#define HCLK_VPU_PRE            237
+#define ACLK_VPU                238
+#define HCLK_VPU                239
+#define ACLK_RGA_PRE            240
+#define HCLK_RGA_PRE            241
+#define PCLK_RGA_PRE            242
+#define ACLK_RGA                243
+#define HCLK_RGA                244
+#define CLK_RGA_CORE            245
+#define ACLK_IEP                246
+#define HCLK_IEP                247
+#define CLK_IEP_CORE            248
+#define HCLK_EBC                249
+#define DCLK_EBC                250
+#define ACLK_JDEC               251
+#define HCLK_JDEC               252
+#define ACLK_JENC               253
+#define HCLK_JENC               254
+#define PCLK_EINK               255
+#define HCLK_EINK               256
+#define ACLK_RKVENC_PRE         257
+#define HCLK_RKVENC_PRE         258
+#define ACLK_RKVENC             259
+#define HCLK_RKVENC             260
+#define CLK_RKVENC_CORE         261
+#define ACLK_RKVDEC_PRE         262
+#define HCLK_RKVDEC_PRE         263
+#define ACLK_RKVDEC             264
+#define HCLK_RKVDEC             265
+#define CLK_RKVDEC_CA           266
+#define CLK_RKVDEC_CORE         267
+#define CLK_RKVDEC_HEVC_CA      268
+#define ACLK_BUS                269
+#define PCLK_BUS                270
+#define PCLK_TSADC              271
+#define CLK_TSADC_TSEN          272
+#define CLK_TSADC               273
+#define PCLK_SARADC             274
+#define CLK_SARADC              275
+#define PCLK_SCR                276
+#define PCLK_WDT_NS             277
+#define TCLK_WDT_NS             278
+#define ACLK_DMAC0              279
+#define ACLK_DMAC1              280
+#define ACLK_MCU                281
+#define PCLK_INTMUX             282
+#define PCLK_MAILBOX            283
+#define PCLK_UART1              284
+#define CLK_UART1_SRC           285
+#define CLK_UART1_FRAC          286
+#define SCLK_UART1              287
+#define PCLK_UART2              288
+#define CLK_UART2_SRC           289
+#define CLK_UART2_FRAC          290
+#define SCLK_UART2              291
+#define PCLK_UART3              292
+#define CLK_UART3_SRC           293
+#define CLK_UART3_FRAC          294
+#define SCLK_UART3              295
+#define PCLK_UART4              296
+#define CLK_UART4_SRC           297
+#define CLK_UART4_FRAC          298
+#define SCLK_UART4              299
+#define PCLK_UART5              300
+#define CLK_UART5_SRC           301
+#define CLK_UART5_FRAC          302
+#define SCLK_UART5              303
+#define PCLK_UART6              304
+#define CLK_UART6_SRC           305
+#define CLK_UART6_FRAC          306
+#define SCLK_UART6              307
+#define PCLK_UART7              308
+#define CLK_UART7_SRC           309
+#define CLK_UART7_FRAC          310
+#define SCLK_UART7              311
+#define PCLK_UART8              312
+#define CLK_UART8_SRC           313
+#define CLK_UART8_FRAC          314
+#define SCLK_UART8              315
+#define PCLK_UART9              316
+#define CLK_UART9_SRC           317
+#define CLK_UART9_FRAC          318
+#define SCLK_UART9              319
+#define PCLK_CAN0               320
+#define CLK_CAN0                321
+#define PCLK_CAN1               322
+#define CLK_CAN1                323
+#define PCLK_CAN2               324
+#define CLK_CAN2                325
+#define CLK_I2C                 326
+#define PCLK_I2C1               327
+#define CLK_I2C1                328
+#define PCLK_I2C2               329
+#define CLK_I2C2                330
+#define PCLK_I2C3               331
+#define CLK_I2C3                332
+#define PCLK_I2C4               333
+#define CLK_I2C4                334
+#define PCLK_I2C5               335
+#define CLK_I2C5                336
+#define PCLK_SPI0               337
+#define CLK_SPI0                338
+#define PCLK_SPI1               339
+#define CLK_SPI1                340
+#define PCLK_SPI2               341
+#define CLK_SPI2                342
+#define PCLK_SPI3               343
+#define CLK_SPI3                344
+#define PCLK_PWM1               345
+#define CLK_PWM1                346
+#define CLK_PWM1_CAPTURE        347
+#define PCLK_PWM2               348
+#define CLK_PWM2                349
+#define CLK_PWM2_CAPTURE        350
+#define PCLK_PWM3               351
+#define CLK_PWM3                352
+#define CLK_PWM3_CAPTURE        353
+#define DBCLK_GPIO              354
+#define PCLK_GPIO1              355
+#define DBCLK_GPIO1             356
+#define PCLK_GPIO2              357
+#define DBCLK_GPIO2             358
+#define PCLK_GPIO3              359
+#define DBCLK_GPIO3             360
+#define PCLK_GPIO4              361
+#define DBCLK_GPIO4             362
+#define OCC_SCAN_CLK_GPIO       363
+#define PCLK_TIMER              364
+#define CLK_TIMER0              365
+#define CLK_TIMER1              366
+#define CLK_TIMER2              367
+#define CLK_TIMER3              368
+#define CLK_TIMER4              369
+#define CLK_TIMER5              370
+#define ACLK_TOP_HIGH           371
+#define ACLK_TOP_LOW            372
+#define HCLK_TOP                373
+#define PCLK_TOP                374
+#define PCLK_PCIE30PHY          375
+#define CLK_OPTC_ARB            376
+#define PCLK_MIPICSIPHY         377
+#define PCLK_MIPIDSIPHY0        378
+#define PCLK_MIPIDSIPHY1        379
+#define PCLK_PIPEPHY0           380
+#define PCLK_PIPEPHY1           381
+#define PCLK_PIPEPHY2           382
+#define PCLK_CPU_BOOST          383
+#define CLK_CPU_BOOST           384
+#define PCLK_OTPPHY             385
+#define SCLK_GMAC0              386
+#define SCLK_GMAC0_RGMII_SPEED  387
+#define SCLK_GMAC0_RMII_SPEED   388
+#define SCLK_GMAC0_RX_TX        389
+#define SCLK_GMAC1              390
+#define SCLK_GMAC1_RGMII_SPEED  391
+#define SCLK_GMAC1_RMII_SPEED   392
+#define SCLK_GMAC1_RX_TX        393
+#define SCLK_SDMMC0_DRV         394
+#define SCLK_SDMMC0_SAMPLE      395
+#define SCLK_SDMMC1_DRV         396
+#define SCLK_SDMMC1_SAMPLE      397
+#define SCLK_SDMMC2_DRV         398
+#define SCLK_SDMMC2_SAMPLE      399
+#define SCLK_EMMC_DRV           400
+#define SCLK_EMMC_SAMPLE        401
+#define PCLK_EDPPHY_GRF         402
+#define CLK_HDMI_CEC            403
+#define CLK_I2S0_8CH_TX         404
+#define CLK_I2S0_8CH_RX         405
+#define CLK_I2S1_8CH_TX         406
+#define CLK_I2S1_8CH_RX         407
+#define CLK_I2S2_2CH            408
+#define CLK_I2S3_2CH_TX         409
+#define CLK_I2S3_2CH_RX         410
+#define CPLL_500M               411
+#define CPLL_250M               412
+#define CPLL_125M               413
+#define CPLL_62P5M              414
+#define CPLL_50M                415
+#define CPLL_25M                416
+#define CPLL_100M               417
+#define SCLK_DDRCLK             418
+
+#define PCLK_CORE_PVTM          450
+
+#define CLK_NR_CLKS             (PCLK_CORE_PVTM + 1)
+
+/* pmu soft-reset indices */
+/* pmucru_softrst_con0 */
+#define SRST_P_PDPMU_NIU        0
+#define SRST_P_PMUCRU           1
+#define SRST_P_PMUGRF           2
+#define SRST_P_I2C0             3
+#define SRST_I2C0               4
+#define SRST_P_UART0            5
+#define SRST_S_UART0            6
+#define SRST_P_PWM0             7
+#define SRST_PWM0               8
+#define SRST_P_GPIO0            9
+#define SRST_GPIO0              10
+#define SRST_P_PMUPVTM          11
+#define SRST_PMUPVTM            12
+
+/* soft-reset indices */
+
+/* cru_softrst_con0 */
+#define SRST_NCORERESET0        0
+#define SRST_NCORERESET1        1
+#define SRST_NCORERESET2        2
+#define SRST_NCORERESET3        3
+#define SRST_NCPUPORESET0       4
+#define SRST_NCPUPORESET1       5
+#define SRST_NCPUPORESET2       6
+#define SRST_NCPUPORESET3       7
+#define SRST_NSRESET            8
+#define SRST_NSPORESET          9
+#define SRST_NATRESET           10
+#define SRST_NGICRESET          11
+#define SRST_NPRESET            12
+#define SRST_NPERIPHRESET       13
+
+/* cru_softrst_con1 */
+#define SRST_A_CORE_NIU2DDR     16
+#define SRST_A_CORE_NIU2BUS     17
+#define SRST_P_DBG_NIU          18
+#define SRST_P_DBG              19
+#define SRST_P_DBG_DAPLITE      20
+#define SRST_DAP                21
+#define SRST_A_ADB400_CORE2GIC  22
+#define SRST_A_ADB400_GIC2CORE  23
+#define SRST_P_CORE_GRF         24
+#define SRST_P_CORE_PVTM        25
+#define SRST_CORE_PVTM          26
+#define SRST_CORE_PVTPLL        27
+
+/* cru_softrst_con2 */
+#define SRST_GPU                32
+#define SRST_A_GPU_NIU          33
+#define SRST_P_GPU_NIU          34
+#define SRST_P_GPU_PVTM         35
+#define SRST_GPU_PVTM           36
+#define SRST_GPU_PVTPLL         37
+#define SRST_A_NPU_NIU          40
+#define SRST_H_NPU_NIU          41
+#define SRST_P_NPU_NIU          42
+#define SRST_A_NPU              43
+#define SRST_H_NPU              44
+#define SRST_P_NPU_PVTM         45
+#define SRST_NPU_PVTM           46
+#define SRST_NPU_PVTPLL         47
+
+/* cru_softrst_con3 */
+#define SRST_A_MSCH             51
+#define SRST_HWFFC_CTRL         52
+#define SRST_DDR_ALWAYSON       53
+#define SRST_A_DDRSPLIT         54
+#define SRST_DDRDFI_CTL         55
+#define SRST_A_DMA2DDR          57
+
+/* cru_softrst_con4 */
+#define SRST_A_PERIMID_NIU      64
+#define SRST_H_PERIMID_NIU      65
+#define SRST_A_GIC_AUDIO_NIU    66
+#define SRST_H_GIC_AUDIO_NIU    67
+#define SRST_A_GIC600           68
+#define SRST_A_GIC600_DEBUG     69
+#define SRST_A_GICADB_CORE2GIC  70
+#define SRST_A_GICADB_GIC2CORE  71
+#define SRST_A_SPINLOCK         72
+#define SRST_H_SDMMC_BUFFER     73
+#define SRST_D_SDMMC_BUFFER     74
+#define SRST_H_I2S0_8CH         75
+#define SRST_H_I2S1_8CH         76
+#define SRST_H_I2S2_2CH         77
+#define SRST_H_I2S3_2CH         78
+
+/* cru_softrst_con5 */
+#define SRST_M_I2S0_8CH_TX      80
+#define SRST_M_I2S0_8CH_RX      81
+#define SRST_M_I2S1_8CH_TX      82
+#define SRST_M_I2S1_8CH_RX      83
+#define SRST_M_I2S2_2CH         84
+#define SRST_M_I2S3_2CH_TX      85
+#define SRST_M_I2S3_2CH_RX      86
+#define SRST_H_PDM              87
+#define SRST_M_PDM              88
+#define SRST_H_VAD              89
+#define SRST_H_SPDIF_8CH        90
+#define SRST_M_SPDIF_8CH        91
+#define SRST_H_AUDPWM           92
+#define SRST_S_AUDPWM           93
+#define SRST_H_ACDCDIG          94
+#define SRST_ACDCDIG            95
+
+/* cru_softrst_con6 */
+#define SRST_A_SECURE_FLASH_NIU 96
+#define SRST_H_SECURE_FLASH_NIU 97
+#define SRST_A_CRYPTO_NS        103
+#define SRST_H_CRYPTO_NS        104
+#define SRST_CRYPTO_NS_CORE     105
+#define SRST_CRYPTO_NS_PKA      106
+#define SRST_CRYPTO_NS_RNG      107
+#define SRST_H_TRNG_NS          108
+#define SRST_TRNG_NS            109
+
+/* cru_softrst_con7 */
+#define SRST_H_NANDC            112
+#define SRST_N_NANDC            113
+#define SRST_H_SFC              114
+#define SRST_H_SFC_XIP          115
+#define SRST_S_SFC              116
+#define SRST_A_EMMC             117
+#define SRST_H_EMMC             118
+#define SRST_B_EMMC             119
+#define SRST_C_EMMC             120
+#define SRST_T_EMMC             121
+
+/* cru_softrst_con8 */
+#define SRST_A_PIPE_NIU         128
+#define SRST_P_PIPE_NIU         130
+#define SRST_P_PIPE_GRF         133
+#define SRST_A_SATA0            134
+#define SRST_SATA0_PIPE         135
+#define SRST_SATA0_PMALIVE      136
+#define SRST_SATA0_RXOOB        137
+#define SRST_A_SATA1            138
+#define SRST_SATA1_PIPE         139
+#define SRST_SATA1_PMALIVE      140
+#define SRST_SATA1_RXOOB        141
+
+/* cru_softrst_con9 */
+#define SRST_A_SATA2            144
+#define SRST_SATA2_PIPE         145
+#define SRST_SATA2_PMALIVE      146
+#define SRST_SATA2_RXOOB        147
+#define SRST_USB3OTG0           148
+#define SRST_USB3OTG1           149
+#define SRST_XPCS               150
+#define SRST_XPCS_TX_DIV10      151
+#define SRST_XPCS_RX_DIV10      152
+#define SRST_XPCS_XGXS_RX       153
+
+/* cru_softrst_con10 */
+#define SRST_P_PCIE20           160
+#define SRST_PCIE20_POWERUP     161
+#define SRST_MSTR_ARESET_PCIE20 162
+#define SRST_SLV_ARESET_PCIE20  163
+#define SRST_DBI_ARESET_PCIE20  164
+#define SRST_BRESET_PCIE20      165
+#define SRST_PERST_PCIE20       166
+#define SRST_CORE_RST_PCIE20    167
+#define SRST_NSTICKY_RST_PCIE20 168
+#define SRST_STICKY_RST_PCIE20  169
+#define SRST_PWR_RST_PCIE20     170
+
+/* cru_softrst_con11 */
+#define SRST_P_PCIE30X1         176
+#define SRST_PCIE30X1_POWERUP   177
+#define SRST_M_ARESET_PCIE30X1  178
+#define SRST_S_ARESET_PCIE30X1  179
+#define SRST_D_ARESET_PCIE30X1  180
+#define SRST_BRESET_PCIE30X1    181
+#define SRST_PERST_PCIE30X1     182
+#define SRST_CORE_RST_PCIE30X1  183
+#define SRST_NSTC_RST_PCIE30X1  184
+#define SRST_STC_RST_PCIE30X1   185
+#define SRST_PWR_RST_PCIE30X1   186
+
+/* cru_softrst_con12 */
+#define SRST_P_PCIE30X2         192
+#define SRST_PCIE30X2_POWERUP   193
+#define SRST_M_ARESET_PCIE30X2  194
+#define SRST_S_ARESET_PCIE30X2  195
+#define SRST_D_ARESET_PCIE30X2  196
+#define SRST_BRESET_PCIE30X2    197
+#define SRST_PERST_PCIE30X2     198
+#define SRST_CORE_RST_PCIE30X2  199
+#define SRST_NSTC_RST_PCIE30X2  200
+#define SRST_STC_RST_PCIE30X2   201
+#define SRST_PWR_RST_PCIE30X2   202
+
+/* cru_softrst_con13 */
+#define SRST_A_PHP_NIU          208
+#define SRST_H_PHP_NIU          209
+#define SRST_P_PHP_NIU          210
+#define SRST_H_SDMMC0           211
+#define SRST_SDMMC0             212
+#define SRST_H_SDMMC1           213
+#define SRST_SDMMC1             214
+#define SRST_A_GMAC0            215
+#define SRST_GMAC0_TIMESTAMP    216
+
+/* cru_softrst_con14 */
+#define SRST_A_USB_NIU          224
+#define SRST_H_USB_NIU          225
+#define SRST_P_USB_NIU          226
+#define SRST_P_USB_GRF          227
+#define SRST_H_USB2HOST0        228
+#define SRST_H_USB2HOST0_ARB    229
+#define SRST_USB2HOST0_UTMI     230
+#define SRST_H_USB2HOST1        231
+#define SRST_H_USB2HOST1_ARB    232
+#define SRST_USB2HOST1_UTMI     233
+#define SRST_H_SDMMC2           234
+#define SRST_SDMMC2             235
+#define SRST_A_GMAC1            236
+#define SRST_GMAC1_TIMESTAMP    237
+
+/* cru_softrst_con15 */
+#define SRST_A_VI_NIU           240
+#define SRST_H_VI_NIU           241
+#define SRST_P_VI_NIU           242
+#define SRST_A_VICAP            247
+#define SRST_H_VICAP            248
+#define SRST_D_VICAP            249
+#define SRST_I_VICAP            250
+#define SRST_P_VICAP            251
+#define SRST_H_ISP              252
+#define SRST_ISP                253
+#define SRST_P_CSI2HOST1        255
+
+/* cru_softrst_con16 */
+#define SRST_A_VO_NIU           256
+#define SRST_H_VO_NIU           257
+#define SRST_P_VO_NIU           258
+#define SRST_A_VOP_NIU          259
+#define SRST_A_VOP              260
+#define SRST_H_VOP              261
+#define SRST_VOP0               262
+#define SRST_VOP1               263
+#define SRST_VOP2               264
+#define SRST_VOP_PWM            265
+#define SRST_A_HDCP             266
+#define SRST_H_HDCP             267
+#define SRST_P_HDCP             268
+#define SRST_P_HDMI_HOST        270
+#define SRST_HDMI_HOST          271
+
+/* cru_softrst_con17 */
+#define SRST_P_DSITX_0          272
+#define SRST_P_DSITX_1          273
+#define SRST_P_EDP_CTRL         274
+#define SRST_EDP_24M            275
+#define SRST_A_VPU_NIU          280
+#define SRST_H_VPU_NIU          281
+#define SRST_A_VPU              282
+#define SRST_H_VPU              283
+#define SRST_H_EINK             286
+#define SRST_P_EINK             287
+
+/* cru_softrst_con18 */
+#define SRST_A_RGA_NIU          288
+#define SRST_H_RGA_NIU          289
+#define SRST_P_RGA_NIU          290
+#define SRST_A_RGA              292
+#define SRST_H_RGA              293
+#define SRST_RGA_CORE           294
+#define SRST_A_IEP              295
+#define SRST_H_IEP              296
+#define SRST_IEP_CORE           297
+#define SRST_H_EBC              298
+#define SRST_D_EBC              299
+#define SRST_A_JDEC             300
+#define SRST_H_JDEC             301
+#define SRST_A_JENC             302
+#define SRST_H_JENC             303
+
+/* cru_softrst_con19 */
+#define SRST_A_VENC_NIU         304
+#define SRST_H_VENC_NIU         305
+#define SRST_A_RKVENC           307
+#define SRST_H_RKVENC           308
+#define SRST_RKVENC_CORE        309
+
+/* cru_softrst_con20 */
+#define SRST_A_RKVDEC_NIU       320
+#define SRST_H_RKVDEC_NIU       321
+#define SRST_A_RKVDEC           322
+#define SRST_H_RKVDEC           323
+#define SRST_RKVDEC_CA          324
+#define SRST_RKVDEC_CORE        325
+#define SRST_RKVDEC_HEVC_CA     326
+
+/* cru_softrst_con21 */
+#define SRST_A_BUS_NIU          336
+#define SRST_P_BUS_NIU          338
+#define SRST_P_CAN0             340
+#define SRST_CAN0               341
+#define SRST_P_CAN1             342
+#define SRST_CAN1               343
+#define SRST_P_CAN2             344
+#define SRST_CAN2               345
+#define SRST_P_GPIO1            346
+#define SRST_GPIO1              347
+#define SRST_P_GPIO2            348
+#define SRST_GPIO2              349
+#define SRST_P_GPIO3            350
+#define SRST_GPIO3              351
+
+/* cru_softrst_con22 */
+#define SRST_P_GPIO4            352
+#define SRST_GPIO4              353
+#define SRST_P_I2C1             354
+#define SRST_I2C1               355
+#define SRST_P_I2C2             356
+#define SRST_I2C2               357
+#define SRST_P_I2C3             358
+#define SRST_I2C3               359
+#define SRST_P_I2C4             360
+#define SRST_I2C4               361
+#define SRST_P_I2C5             362
+#define SRST_I2C5               363
+#define SRST_P_OTPC_NS          364
+#define SRST_OTPC_NS_SBPI       365
+#define SRST_OTPC_NS_USR        366
+
+/* cru_softrst_con23 */
+#define SRST_P_PWM1             368
+#define SRST_PWM1               369
+#define SRST_P_PWM2             370
+#define SRST_PWM2               371
+#define SRST_P_PWM3             372
+#define SRST_PWM3               373
+#define SRST_P_SPI0             374
+#define SRST_SPI0               375
+#define SRST_P_SPI1             376
+#define SRST_SPI1               377
+#define SRST_P_SPI2             378
+#define SRST_SPI2               379
+#define SRST_P_SPI3             380
+#define SRST_SPI3               381
+
+/* cru_softrst_con24 */
+#define SRST_P_SARADC           384
+#define SRST_P_TSADC            385
+#define SRST_TSADC              386
+#define SRST_P_TIMER            387
+#define SRST_TIMER0             388
+#define SRST_TIMER1             389
+#define SRST_TIMER2             390
+#define SRST_TIMER3             391
+#define SRST_TIMER4             392
+#define SRST_TIMER5             393
+#define SRST_P_UART1            394
+#define SRST_S_UART1            395
+
+/* cru_softrst_con25 */
+#define SRST_P_UART2            400
+#define SRST_S_UART2            401
+#define SRST_P_UART3            402
+#define SRST_S_UART3            403
+#define SRST_P_UART4            404
+#define SRST_S_UART4            405
+#define SRST_P_UART5            406
+#define SRST_S_UART5            407
+#define SRST_P_UART6            408
+#define SRST_S_UART6            409
+#define SRST_P_UART7            410
+#define SRST_S_UART7            411
+#define SRST_P_UART8            412
+#define SRST_S_UART8            413
+#define SRST_P_UART9            414
+#define SRST_S_UART9            415
+
+/* cru_softrst_con26 */
+#define SRST_P_GRF 416
+#define SRST_P_GRF_VCCIO12      417
+#define SRST_P_GRF_VCCIO34      418
+#define SRST_P_GRF_VCCIO567     419
+#define SRST_P_SCR              420
+#define SRST_P_WDT_NS           421
+#define SRST_T_WDT_NS           422
+#define SRST_P_DFT2APB          423
+#define SRST_A_MCU              426
+#define SRST_P_INTMUX           427
+#define SRST_P_MAILBOX          428
+
+/* cru_softrst_con27 */
+#define SRST_A_TOP_HIGH_NIU     432
+#define SRST_A_TOP_LOW_NIU      433
+#define SRST_H_TOP_NIU          434
+#define SRST_P_TOP_NIU          435
+#define SRST_P_TOP_CRU          438
+#define SRST_P_DDRPHY           439
+#define SRST_DDRPHY             440
+#define SRST_P_MIPICSIPHY       442
+#define SRST_P_MIPIDSIPHY0      443
+#define SRST_P_MIPIDSIPHY1      444
+#define SRST_P_PCIE30PHY        445
+#define SRST_PCIE30PHY          446
+#define SRST_P_PCIE30PHY_GRF    447
+
+/* cru_softrst_con28 */
+#define SRST_P_APB2ASB_LEFT     448
+#define SRST_P_APB2ASB_BOTTOM   449
+#define SRST_P_ASB2APB_LEFT     450
+#define SRST_P_ASB2APB_BOTTOM   451
+#define SRST_P_PIPEPHY0         452
+#define SRST_PIPEPHY0           453
+#define SRST_P_PIPEPHY1         454
+#define SRST_PIPEPHY1           455
+#define SRST_P_PIPEPHY2         456
+#define SRST_PIPEPHY2           457
+#define SRST_P_USB2PHY0_GRF     458
+#define SRST_P_USB2PHY1_GRF     459
+#define SRST_P_CPU_BOOST        460
+#define SRST_CPU_BOOST          461
+#define SRST_P_OTPPHY           462
+#define SRST_OTPPHY             463
+
+/* cru_softrst_con29 */
+#define SRST_USB2PHY0_POR       464
+#define SRST_USB2PHY0_USB3OTG0  465
+#define SRST_USB2PHY0_USB3OTG1  466
+#define SRST_USB2PHY1_POR       467
+#define SRST_USB2PHY1_USB2HOST0 468
+#define SRST_USB2PHY1_USB2HOST1 469
+#define SRST_P_EDPPHY_GRF       470
+#define SRST_TSADCPHY           471
+#define SRST_GMAC0_DELAYLINE    472
+#define SRST_GMAC1_DELAYLINE    473
+#define SRST_OTPC_ARB           474
+#define SRST_P_PIPEPHY0_GRF     475
+#define SRST_P_PIPEPHY1_GRF     476
+#define SRST_P_PIPEPHY2_GRF     477
+
+#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3568_H__ */

+ 1497 - 0
bsp/rockchip/rk3500/driver/clk/rk3588-cru.h

@@ -0,0 +1,1497 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3588_H__
+#define __DT_BINDINGS_CLK_ROCKCHIP_RK3588_H__
+
+/* cru-clocks indices */
+
+/* cru plls */
+#define PLL_B0PLL                       1
+#define PLL_B1PLL                       2
+#define PLL_LPLL                        3
+#define PLL_V0PLL                       4
+#define PLL_AUPLL                       5
+#define PLL_CPLL                        6
+#define PLL_GPLL                        7
+#define PLL_NPLL                        8
+#define PLL_PPLL                        9
+#define ARMCLK_L                        10
+#define ARMCLK_B01                      11
+#define ARMCLK_B23                      12
+
+/* cru clocks */
+#define PCLK_BIGCORE0_ROOT              20
+#define PCLK_BIGCORE0_PVTM              21
+#define PCLK_BIGCORE1_ROOT              22
+#define PCLK_BIGCORE1_PVTM              23
+#define PCLK_DSU_S_ROOT                 24
+#define PCLK_DSU_ROOT                   25
+#define PCLK_DSU_NS_ROOT                26
+#define PCLK_LITCORE_PVTM               27
+#define PCLK_DBG                        28
+#define PCLK_DSU                        29
+#define PCLK_S_DAPLITE                  30
+#define PCLK_M_DAPLITE                  31
+#define MBIST_MCLK_PDM1                 32
+#define MBIST_CLK_ACDCDIG               33
+#define HCLK_I2S2_2CH                   34
+#define HCLK_I2S3_2CH                   35
+#define CLK_I2S2_2CH_SRC                36
+#define CLK_I2S2_2CH_FRAC               37
+#define CLK_I2S2_2CH                    38
+#define MCLK_I2S2_2CH                   39
+#define I2S2_2CH_MCLKOUT                40
+#define CLK_DAC_ACDCDIG                 41
+#define CLK_I2S3_2CH_SRC                42
+#define CLK_I2S3_2CH_FRAC               43
+#define CLK_I2S3_2CH                    44
+#define MCLK_I2S3_2CH                   45
+#define I2S3_2CH_MCLKOUT                46
+#define PCLK_ACDCDIG                    47
+#define HCLK_I2S0_8CH                   48
+#define CLK_I2S0_8CH_TX_SRC             49
+#define CLK_I2S0_8CH_TX_FRAC            50
+#define MCLK_I2S0_8CH_TX                51
+#define CLK_I2S0_8CH_TX                 52
+#define CLK_I2S0_8CH_RX_SRC             53
+#define CLK_I2S0_8CH_RX_FRAC            54
+#define MCLK_I2S0_8CH_RX                55
+#define CLK_I2S0_8CH_RX                 56
+#define I2S0_8CH_MCLKOUT                57
+#define HCLK_PDM1                       58
+#define MCLK_PDM1                       59
+#define HCLK_AUDIO_ROOT                 60
+#define PCLK_AUDIO_ROOT                 61
+#define HCLK_SPDIF0                     62
+#define CLK_SPDIF0_SRC                  63
+#define CLK_SPDIF0_FRAC                 64
+#define MCLK_SPDIF0                     65
+#define CLK_SPDIF0                      66
+#define CLK_SPDIF1                      67
+#define HCLK_SPDIF1                     68
+#define CLK_SPDIF1_SRC                  69
+#define CLK_SPDIF1_FRAC                 70
+#define MCLK_SPDIF1                     71
+#define ACLK_AV1_ROOT                   72
+#define ACLK_AV1                        73
+#define PCLK_AV1_ROOT                   74
+#define PCLK_AV1                        75
+#define PCLK_MAILBOX0                   76
+#define PCLK_MAILBOX1                   77
+#define PCLK_MAILBOX2                   78
+#define PCLK_PMU2                       79
+#define PCLK_PMUCM0_INTMUX              80
+#define PCLK_DDRCM0_INTMUX              81
+#define PCLK_TOP                        82
+#define PCLK_PWM1                       83
+#define CLK_PWM1                        84
+#define CLK_PWM1_CAPTURE                85
+#define PCLK_PWM2                       86
+#define CLK_PWM2                        87
+#define CLK_PWM2_CAPTURE                88
+#define PCLK_PWM3                       89
+#define CLK_PWM3                        90
+#define CLK_PWM3_CAPTURE                91
+#define PCLK_BUSTIMER0                  92
+#define PCLK_BUSTIMER1                  93
+#define CLK_BUS_TIMER_ROOT              94
+#define CLK_BUSTIMER0                   95
+#define CLK_BUSTIMER1                   96
+#define CLK_BUSTIMER2                   97
+#define CLK_BUSTIMER3                   98
+#define CLK_BUSTIMER4                   99
+#define CLK_BUSTIMER5                   100
+#define CLK_BUSTIMER6                   101
+#define CLK_BUSTIMER7                   102
+#define CLK_BUSTIMER8                   103
+#define CLK_BUSTIMER9                   104
+#define CLK_BUSTIMER10                  105
+#define CLK_BUSTIMER11                  106
+#define PCLK_WDT0                       107
+#define TCLK_WDT0                       108
+#define PCLK_CAN0                       111
+#define CLK_CAN0                        112
+#define PCLK_CAN1                       113
+#define CLK_CAN1                        114
+#define PCLK_CAN2                       115
+#define CLK_CAN2                        116
+#define ACLK_DECOM                      117
+#define PCLK_DECOM                      118
+#define DCLK_DECOM                      119
+#define ACLK_DMAC0                      120
+#define ACLK_DMAC1                      121
+#define ACLK_DMAC2                      122
+#define ACLK_BUS_ROOT                   123
+#define ACLK_GIC                        124
+#define PCLK_GPIO1                      125
+#define DBCLK_GPIO1                     126
+#define PCLK_GPIO2                      127
+#define DBCLK_GPIO2                     128
+#define PCLK_GPIO3                      129
+#define DBCLK_GPIO3                     130
+#define PCLK_GPIO4                      131
+#define DBCLK_GPIO4                     132
+#define PCLK_I2C1                       133
+#define PCLK_I2C2                       134
+#define PCLK_I2C3                       135
+#define PCLK_I2C4                       136
+#define PCLK_I2C5                       137
+#define PCLK_I2C6                       138
+#define PCLK_I2C7                       139
+#define PCLK_I2C8                       140
+#define CLK_I2C1                        141
+#define CLK_I2C2                        142
+#define CLK_I2C3                        143
+#define CLK_I2C4                        144
+#define CLK_I2C5                        145
+#define CLK_I2C6                        146
+#define CLK_I2C7                        147
+#define CLK_I2C8                        148
+#define PCLK_OTPC_NS                    149
+#define CLK_OTPC_NS                     150
+#define CLK_OTPC_ARB                    151
+#define CLK_OTPC_AUTO_RD_G              152
+#define CLK_OTP_PHY_G                   153
+#define PCLK_SARADC                     156
+#define CLK_SARADC                      157
+#define PCLK_SPI0                       158
+#define PCLK_SPI1                       159
+#define PCLK_SPI2                       160
+#define PCLK_SPI3                       161
+#define PCLK_SPI4                       162
+#define CLK_SPI0                        163
+#define CLK_SPI1                        164
+#define CLK_SPI2                        165
+#define CLK_SPI3                        166
+#define CLK_SPI4                        167
+#define ACLK_SPINLOCK                   168
+#define PCLK_TSADC                      169
+#define CLK_TSADC                       170
+#define PCLK_UART1                      171
+#define PCLK_UART2                      172
+#define PCLK_UART3                      173
+#define PCLK_UART4                      174
+#define PCLK_UART5                      175
+#define PCLK_UART6                      176
+#define PCLK_UART7                      177
+#define PCLK_UART8                      178
+#define PCLK_UART9                      179
+#define CLK_UART1_SRC                   180
+#define CLK_UART1_FRAC                  181
+#define CLK_UART1                       182
+#define SCLK_UART1                      183
+#define CLK_UART2_SRC                   184
+#define CLK_UART2_FRAC                  185
+#define CLK_UART2                       186
+#define SCLK_UART2                      187
+#define CLK_UART3_SRC                   188
+#define CLK_UART3_FRAC                  189
+#define CLK_UART3                       190
+#define SCLK_UART3                      191
+#define CLK_UART4_SRC                   192
+#define CLK_UART4_FRAC                  193
+#define CLK_UART4                       194
+#define SCLK_UART4                      195
+#define CLK_UART5_SRC                   196
+#define CLK_UART5_FRAC                  197
+#define CLK_UART5                       198
+#define SCLK_UART5                      199
+#define CLK_UART6_SRC                   200
+#define CLK_UART6_FRAC                  201
+#define CLK_UART6                       202
+#define SCLK_UART6                      203
+#define CLK_UART7_SRC                   204
+#define CLK_UART7_FRAC                  205
+#define CLK_UART7                       206
+#define SCLK_UART7                      207
+#define CLK_UART8_SRC                   208
+#define CLK_UART8_FRAC                  209
+#define CLK_UART8                       210
+#define SCLK_UART8                      211
+#define CLK_UART9_SRC                   212
+#define CLK_UART9_FRAC                  213
+#define CLK_UART9                       214
+#define SCLK_UART9                      215
+#define ACLK_CENTER_ROOT                216
+#define ACLK_CENTER_LOW_ROOT            217
+#define HCLK_CENTER_ROOT                218
+#define PCLK_CENTER_ROOT                219
+#define ACLK_DMA2DDR                    220
+#define ACLK_DDR_SHAREMEM               221
+#define ACLK_CENTER_S200_ROOT           222
+#define ACLK_CENTER_S400_ROOT           223
+#define FCLK_DDR_CM0_CORE               224
+#define CLK_DDR_TIMER_ROOT              225
+#define CLK_DDR_TIMER0                  226
+#define CLK_DDR_TIMER1                  227
+#define TCLK_WDT_DDR                    228
+#define CLK_DDR_CM0_RTC                 228
+#define PCLK_WDT                        230
+#define PCLK_TIMER                      231
+#define PCLK_DMA2DDR                    232
+#define PCLK_SHAREMEM                   233
+#define CLK_50M_SRC                     234
+#define CLK_100M_SRC                    235
+#define CLK_150M_SRC                    236
+#define CLK_200M_SRC                    237
+#define CLK_250M_SRC                    238
+#define CLK_300M_SRC                    239
+#define CLK_350M_SRC                    240
+#define CLK_400M_SRC                    241
+#define CLK_450M_SRC                    242
+#define CLK_500M_SRC                    243
+#define CLK_600M_SRC                    244
+#define CLK_650M_SRC                    245
+#define CLK_700M_SRC                    246
+#define CLK_800M_SRC                    247
+#define CLK_1000M_SRC                   248
+#define CLK_1200M_SRC                   249
+#define ACLK_TOP_M300_ROOT              250
+#define ACLK_TOP_M500_ROOT              251
+#define ACLK_TOP_M400_ROOT              252
+#define ACLK_TOP_S200_ROOT              253
+#define ACLK_TOP_S400_ROOT              254
+#define CLK_MIPI_CAMARAOUT_M0           255
+#define CLK_MIPI_CAMARAOUT_M1           256
+#define CLK_MIPI_CAMARAOUT_M2           257
+#define CLK_MIPI_CAMARAOUT_M3           258
+#define CLK_MIPI_CAMARAOUT_M4           259
+#define MCLK_GMAC0_OUT                  260
+#define REFCLKO25M_ETH0_OUT             261
+#define REFCLKO25M_ETH1_OUT             262
+#define CLK_CIFOUT_OUT                  263
+#define PCLK_MIPI_DCPHY0                264
+#define PCLK_MIPI_DCPHY1                265
+#define PCLK_CSIPHY0                    268
+#define PCLK_CSIPHY1                    269
+#define ACLK_TOP_ROOT                   270
+#define PCLK_TOP_ROOT                   271
+#define ACLK_LOW_TOP_ROOT               272
+#define PCLK_CRU                        273
+#define PCLK_GPU_ROOT                   274
+#define CLK_GPU_SRC                     275
+#define CLK_GPU                         276
+#define CLK_GPU_COREGROUP               277
+#define CLK_GPU_STACKS                  278
+#define PCLK_GPU_PVTM                   279
+#define CLK_GPU_PVTM                    280
+#define CLK_CORE_GPU_PVTM               281
+#define PCLK_GPU_GRF                    282
+#define ACLK_ISP1_ROOT                  283
+#define HCLK_ISP1_ROOT                  284
+#define CLK_ISP1_CORE                   285
+#define CLK_ISP1_CORE_MARVIN            286
+#define CLK_ISP1_CORE_VICAP             287
+#define ACLK_ISP1                       288
+#define HCLK_ISP1                       289
+#define ACLK_NPU1                       290
+#define HCLK_NPU1                       291
+#define ACLK_NPU2                       292
+#define HCLK_NPU2                       293
+#define HCLK_NPU_CM0_ROOT               294
+#define FCLK_NPU_CM0_CORE               295
+#define CLK_NPU_CM0_RTC                 296
+#define PCLK_NPU_PVTM                   297
+#define PCLK_NPU_GRF                    298
+#define CLK_NPU_PVTM                    299
+#define CLK_CORE_NPU_PVTM               300
+#define ACLK_NPU0                       301
+#define HCLK_NPU0                       302
+#define HCLK_NPU_ROOT                   303
+#define CLK_NPU_DSU0                    304
+#define PCLK_NPU_ROOT                   305
+#define PCLK_NPU_TIMER                  306
+#define CLK_NPUTIMER_ROOT               307
+#define CLK_NPUTIMER0                   308
+#define CLK_NPUTIMER1                   309
+#define PCLK_NPU_WDT                    310
+#define TCLK_NPU_WDT                    311
+#define HCLK_EMMC                       312
+#define ACLK_EMMC                       313
+#define CCLK_EMMC                       314
+#define BCLK_EMMC                       315
+#define TMCLK_EMMC                      316
+#define SCLK_SFC                        317
+#define HCLK_SFC                        318
+#define HCLK_SFC_XIP                    319
+#define HCLK_NVM_ROOT                   320
+#define ACLK_NVM_ROOT                   321
+#define CLK_GMAC0_PTP_REF               322
+#define CLK_GMAC1_PTP_REF               323
+#define CLK_GMAC_125M                   324
+#define CLK_GMAC_50M                    325
+#define ACLK_PHP_GIC_ITS                326
+#define ACLK_MMU_PCIE                   327
+#define ACLK_MMU_PHP                    328
+#define ACLK_PCIE_4L_DBI                329
+#define ACLK_PCIE_2L_DBI                330
+#define ACLK_PCIE_1L0_DBI               331
+#define ACLK_PCIE_1L1_DBI               332
+#define ACLK_PCIE_1L2_DBI               333
+#define ACLK_PCIE_4L_MSTR               334
+#define ACLK_PCIE_2L_MSTR               335
+#define ACLK_PCIE_1L0_MSTR              336
+#define ACLK_PCIE_1L1_MSTR              337
+#define ACLK_PCIE_1L2_MSTR              338
+#define ACLK_PCIE_4L_SLV                339
+#define ACLK_PCIE_2L_SLV                340
+#define ACLK_PCIE_1L0_SLV               341
+#define ACLK_PCIE_1L1_SLV               342
+#define ACLK_PCIE_1L2_SLV               343
+#define PCLK_PCIE_4L                    344
+#define PCLK_PCIE_2L                    345
+#define PCLK_PCIE_1L0                   347
+#define PCLK_PCIE_1L1                   348
+#define PCLK_PCIE_1L2                   349
+#define CLK_PCIE_AUX0                   350
+#define CLK_PCIE_AUX1                   351
+#define CLK_PCIE_AUX2                   352
+#define CLK_PCIE_AUX3                   353
+#define CLK_PCIE_AUX4                   354
+#define CLK_PIPEPHY0_REF                355
+#define CLK_PIPEPHY1_REF                356
+#define CLK_PIPEPHY2_REF                357
+#define PCLK_PHP_ROOT                   358
+#define PCLK_GMAC0                      359
+#define PCLK_GMAC1                      360
+#define ACLK_PCIE_ROOT                  361
+#define ACLK_PHP_ROOT                   362
+#define ACLK_PCIE_BRIDGE                363
+#define ACLK_GMAC0                      364
+#define ACLK_GMAC1                      365
+#define CLK_PMALIVE0                    366
+#define CLK_PMALIVE1                    367
+#define CLK_PMALIVE2                    368
+#define ACLK_SATA0                      369
+#define ACLK_SATA1                      370
+#define ACLK_SATA2                      371
+#define CLK_RXOOB0                      372
+#define CLK_RXOOB1                      373
+#define CLK_RXOOB2                      374
+#define ACLK_USB3OTG2                   375
+#define SUSPEND_CLK_USB3OTG2            376
+#define REF_CLK_USB3OTG2                377
+#define CLK_UTMI_OTG2                   378
+#define CLK_PIPEPHY0_PIPE_G             379
+#define CLK_PIPEPHY1_PIPE_G             380
+#define CLK_PIPEPHY2_PIPE_G             381
+#define CLK_PIPEPHY0_PIPE_ASIC_G        382
+#define CLK_PIPEPHY1_PIPE_ASIC_G        383
+#define CLK_PIPEPHY2_PIPE_ASIC_G        384
+#define CLK_PIPEPHY2_PIPE_U3_G          385
+#define CLK_PCIE1L2_PIPE                386
+#define CLK_PCIE4L_PIPE                 387
+#define CLK_PCIE2L_PIPE                 388
+#define PCLK_PCIE_COMBO_PIPE_PHY0       389
+#define PCLK_PCIE_COMBO_PIPE_PHY1       390
+#define PCLK_PCIE_COMBO_PIPE_PHY2       391
+#define PCLK_PCIE_COMBO_PIPE_PHY        392
+#define HCLK_RGA3_1                     393
+#define ACLK_RGA3_1                     394
+#define CLK_RGA3_1_CORE                 395
+#define ACLK_RGA3_ROOT                  396
+#define HCLK_RGA3_ROOT                  397
+#define ACLK_RKVDEC_CCU                 398
+#define HCLK_RKVDEC0                    399
+#define ACLK_RKVDEC0                    400
+#define CLK_RKVDEC0_CA                  401
+#define CLK_RKVDEC0_HEVC_CA             402
+#define CLK_RKVDEC0_CORE                403
+#define HCLK_RKVDEC1                    404
+#define ACLK_RKVDEC1                    405
+#define CLK_RKVDEC1_CA                  406
+#define CLK_RKVDEC1_HEVC_CA             407
+#define CLK_RKVDEC1_CORE                408
+#define HCLK_SDIO                       409
+#define CCLK_SRC_SDIO                   410
+#define ACLK_USB_ROOT                   411
+#define HCLK_USB_ROOT                   412
+#define HCLK_HOST0                      413
+#define HCLK_HOST_ARB0                  414
+#define HCLK_HOST1                      415
+#define HCLK_HOST_ARB1                  416
+#define ACLK_USB3OTG0                   417
+#define SUSPEND_CLK_USB3OTG0            418
+#define REF_CLK_USB3OTG0                419
+#define ACLK_USB3OTG1                   420
+#define SUSPEND_CLK_USB3OTG1            421
+#define REF_CLK_USB3OTG1                422
+#define UTMI_OHCI_CLK48_HOST0           423
+#define UTMI_OHCI_CLK48_HOST1           424
+#define HCLK_IEP2P0                     425
+#define ACLK_IEP2P0                     426
+#define CLK_IEP2P0_CORE                 427
+#define ACLK_JPEG_ENCODER0              428
+#define HCLK_JPEG_ENCODER0              429
+#define ACLK_JPEG_ENCODER1              430
+#define HCLK_JPEG_ENCODER1              431
+#define ACLK_JPEG_ENCODER2              432
+#define HCLK_JPEG_ENCODER2              433
+#define ACLK_JPEG_ENCODER3              434
+#define HCLK_JPEG_ENCODER3              435
+#define ACLK_JPEG_DECODER               436
+#define HCLK_JPEG_DECODER               437
+#define HCLK_RGA2                       438
+#define ACLK_RGA2                       439
+#define CLK_RGA2_CORE                   440
+#define HCLK_RGA3_0                     441
+#define ACLK_RGA3_0                     442
+#define CLK_RGA3_0_CORE                 443
+#define ACLK_VDPU_ROOT                  444
+#define ACLK_VDPU_LOW_ROOT              445
+#define HCLK_VDPU_ROOT                  446
+#define ACLK_JPEG_DECODER_ROOT          447
+#define ACLK_VPU                        448
+#define HCLK_VPU                        449
+#define HCLK_RKVENC0_ROOT               450
+#define ACLK_RKVENC0_ROOT               451
+#define HCLK_RKVENC0                    452
+#define ACLK_RKVENC0                    453
+#define CLK_RKVENC0_CORE                454
+#define HCLK_RKVENC1_ROOT               455
+#define ACLK_RKVENC1_ROOT               456
+#define HCLK_RKVENC1                    457
+#define ACLK_RKVENC1                    458
+#define CLK_RKVENC1_CORE                459
+#define ICLK_CSIHOST01                  460
+#define ICLK_CSIHOST0                   461
+#define ICLK_CSIHOST1                   462
+#define PCLK_CSI_HOST_0                 463
+#define PCLK_CSI_HOST_1                 464
+#define PCLK_CSI_HOST_2                 465
+#define PCLK_CSI_HOST_3                 466
+#define PCLK_CSI_HOST_4                 467
+#define PCLK_CSI_HOST_5                 468
+#define ACLK_FISHEYE0                   469
+#define HCLK_FISHEYE0                   470
+#define CLK_FISHEYE0_CORE               471
+#define ACLK_FISHEYE1                   472
+#define HCLK_FISHEYE1                   473
+#define CLK_FISHEYE1_CORE               474
+#define CLK_ISP0_CORE                   475
+#define CLK_ISP0_CORE_MARVIN            476
+#define CLK_ISP0_CORE_VICAP             477
+#define ACLK_ISP0                       478
+#define HCLK_ISP0                       479
+#define ACLK_VI_ROOT                    480
+#define HCLK_VI_ROOT                    481
+#define PCLK_VI_ROOT                    482
+#define DCLK_VICAP                      483
+#define ACLK_VICAP                      484
+#define HCLK_VICAP                      485
+#define PCLK_DP0                        486
+#define PCLK_DP1                        487
+#define PCLK_S_DP0                      488
+#define PCLK_S_DP1                      489
+#define CLK_DP0                         490
+#define CLK_DP1                         491
+#define HCLK_HDCP_KEY0                  492
+#define ACLK_HDCP0                      493
+#define HCLK_HDCP0                      494
+#define PCLK_HDCP0                      495
+#define HCLK_I2S4_8CH                   496
+#define ACLK_TRNG0                      497
+#define PCLK_TRNG0                      498
+#define ACLK_VO0_ROOT                   499
+#define HCLK_VO0_ROOT                   500
+#define HCLK_VO0_S_ROOT                 501
+#define PCLK_VO0_ROOT                   502
+#define PCLK_VO0_S_ROOT                 503
+#define PCLK_VO0GRF                     504
+#define CLK_I2S4_8CH_TX_SRC             505
+#define CLK_I2S4_8CH_TX_FRAC            506
+#define MCLK_I2S4_8CH_TX                507
+#define CLK_I2S4_8CH_TX                 508
+#define HCLK_I2S8_8CH                   510
+#define CLK_I2S8_8CH_TX_SRC             511
+#define CLK_I2S8_8CH_TX_FRAC            512
+#define MCLK_I2S8_8CH_TX                513
+#define CLK_I2S8_8CH_TX                 514
+#define HCLK_SPDIF2_DP0                 516
+#define CLK_SPDIF2_DP0_SRC              517
+#define CLK_SPDIF2_DP0_FRAC             518
+#define MCLK_SPDIF2_DP0                 519
+#define CLK_SPDIF2_DP0                  520
+#define MCLK_SPDIF2                     521
+#define HCLK_SPDIF5_DP1                 522
+#define CLK_SPDIF5_DP1_SRC              523
+#define CLK_SPDIF5_DP1_FRAC             524
+#define MCLK_SPDIF5_DP1                 525
+#define CLK_SPDIF5_DP1                  526
+#define MCLK_SPDIF5                     527
+#define PCLK_EDP0                       528
+#define CLK_EDP0_24M                    529
+#define CLK_EDP0_200M                   530
+#define PCLK_EDP1                       531
+#define CLK_EDP1_24M                    532
+#define CLK_EDP1_200M                   533
+#define HCLK_HDCP_KEY1                  534
+#define ACLK_HDCP1                      535
+#define HCLK_HDCP1                      536
+#define PCLK_HDCP1                      537
+#define ACLK_HDMIRX                     538
+#define PCLK_HDMIRX                     539
+#define CLK_HDMIRX_REF                  540
+#define CLK_HDMIRX_AUD_SRC              541
+#define CLK_HDMIRX_AUD_FRAC             542
+#define CLK_HDMIRX_AUD                  543
+#define CLK_HDMIRX_AUD_P_MUX            544
+#define PCLK_HDMITX0                    545
+#define CLK_HDMITX0_EARC                546
+#define CLK_HDMITX0_REF                 547
+#define PCLK_HDMITX1                    548
+#define CLK_HDMITX1_EARC                549
+#define CLK_HDMITX1_REF                 550
+#define CLK_HDMITRX_REFSRC              551
+#define ACLK_TRNG1                      552
+#define PCLK_TRNG1                      553
+#define ACLK_HDCP1_ROOT                 554
+#define ACLK_HDMIRX_ROOT                555
+#define HCLK_VO1_ROOT                   556
+#define HCLK_VO1_S_ROOT                 557
+#define PCLK_VO1_ROOT                   558
+#define PCLK_VO1_S_ROOT                 559
+#define PCLK_S_EDP0                     560
+#define PCLK_S_EDP1                     561
+#define PCLK_S_HDMIRX                   562
+#define HCLK_I2S10_8CH                  563
+#define CLK_I2S10_8CH_RX_SRC            564
+#define CLK_I2S10_8CH_RX_FRAC           565
+#define CLK_I2S10_8CH_RX                566
+#define MCLK_I2S10_8CH_RX               567
+#define HCLK_I2S7_8CH                   568
+#define CLK_I2S7_8CH_RX_SRC             569
+#define CLK_I2S7_8CH_RX_FRAC            570
+#define CLK_I2S7_8CH_RX                 571
+#define MCLK_I2S7_8CH_RX                572
+#define HCLK_I2S9_8CH                   574
+#define CLK_I2S9_8CH_RX_SRC             575
+#define CLK_I2S9_8CH_RX_FRAC            576
+#define CLK_I2S9_8CH_RX                 577
+#define MCLK_I2S9_8CH_RX                578
+#define CLK_I2S5_8CH_TX_SRC             579
+#define CLK_I2S5_8CH_TX_FRAC            580
+#define CLK_I2S5_8CH_TX                 581
+#define MCLK_I2S5_8CH_TX                582
+#define HCLK_I2S5_8CH                   584
+#define CLK_I2S6_8CH_TX_SRC             585
+#define CLK_I2S6_8CH_TX_FRAC            586
+#define CLK_I2S6_8CH_TX                 587
+#define MCLK_I2S6_8CH_TX                588
+#define CLK_I2S6_8CH_RX_SRC             589
+#define CLK_I2S6_8CH_RX_FRAC            590
+#define CLK_I2S6_8CH_RX                 591
+#define MCLK_I2S6_8CH_RX                592
+#define I2S6_8CH_MCLKOUT                593
+#define HCLK_I2S6_8CH                   594
+#define HCLK_SPDIF3                     595
+#define CLK_SPDIF3_SRC                  596
+#define CLK_SPDIF3_FRAC                 597
+#define CLK_SPDIF3                      598
+#define MCLK_SPDIF3                     599
+#define HCLK_SPDIF4                     600
+#define CLK_SPDIF4_SRC                  601
+#define CLK_SPDIF4_FRAC                 602
+#define CLK_SPDIF4                      603
+#define MCLK_SPDIF4                     604
+#define HCLK_SPDIFRX0                   605
+#define MCLK_SPDIFRX0                   606
+#define HCLK_SPDIFRX1                   607
+#define MCLK_SPDIFRX1                   608
+#define HCLK_SPDIFRX2                   609
+#define MCLK_SPDIFRX2                   610
+#define ACLK_VO1USB_TOP_ROOT            611
+#define HCLK_VO1USB_TOP_ROOT            612
+#define CLK_HDMIHDP0                    613
+#define CLK_HDMIHDP1                    614
+#define PCLK_HDPTX0                     615
+#define PCLK_HDPTX1                     616
+#define PCLK_USBDPPHY0                  617
+#define PCLK_USBDPPHY1                  618
+#define ACLK_VOP_ROOT                   619
+#define ACLK_VOP_LOW_ROOT               620
+#define HCLK_VOP_ROOT                   621
+#define PCLK_VOP_ROOT                   622
+#define HCLK_VOP                        623
+#define ACLK_VOP                        624
+#define DCLK_VOP0_SRC                   625
+#define DCLK_VOP1_SRC                   626
+#define DCLK_VOP2_SRC                   627
+#define DCLK_VOP0                       628
+#define DCLK_VOP1                       629
+#define DCLK_VOP2                       630
+#define DCLK_VOP3                       631
+#define PCLK_DSIHOST0                   632
+#define PCLK_DSIHOST1                   633
+#define CLK_DSIHOST0                    634
+#define CLK_DSIHOST1                    635
+#define CLK_VOP_PMU                     636
+#define ACLK_VOP_DOBY                   637
+#define ACLK_VOP_SUB_SRC                638
+#define CLK_USBDP_PHY0_IMMORTAL         639
+#define CLK_USBDP_PHY1_IMMORTAL         640
+#define CLK_PMU0                        641
+#define PCLK_PMU0                       642
+#define PCLK_PMU0IOC                    643
+#define PCLK_GPIO0                      644
+#define DBCLK_GPIO0                     645
+#define PCLK_I2C0                       646
+#define CLK_I2C0                        647
+#define HCLK_I2S1_8CH                   648
+#define CLK_I2S1_8CH_TX_SRC             649
+#define CLK_I2S1_8CH_TX_FRAC            650
+#define CLK_I2S1_8CH_TX                 651
+#define MCLK_I2S1_8CH_TX                652
+#define CLK_I2S1_8CH_RX_SRC             653
+#define CLK_I2S1_8CH_RX_FRAC            654
+#define CLK_I2S1_8CH_RX                 655
+#define MCLK_I2S1_8CH_RX                656
+#define I2S1_8CH_MCLKOUT                657
+#define CLK_PMU1_50M_SRC                658
+#define CLK_PMU1_100M_SRC               659
+#define CLK_PMU1_200M_SRC               660
+#define CLK_PMU1_300M_SRC               661
+#define CLK_PMU1_400M_SRC               662
+#define HCLK_PMU1_ROOT                  663
+#define PCLK_PMU1_ROOT                  664
+#define PCLK_PMU0_ROOT                  665
+#define HCLK_PMU_CM0_ROOT               666
+#define PCLK_PMU1                       667
+#define CLK_DDR_FAIL_SAFE               668
+#define CLK_PMU1                        669
+#define HCLK_PDM0                       670
+#define MCLK_PDM0                       671
+#define HCLK_VAD                        672
+#define FCLK_PMU_CM0_CORE               673
+#define CLK_PMU_CM0_RTC                 674
+#define PCLK_PMU1_IOC                   675
+#define PCLK_PMU1PWM                    676
+#define CLK_PMU1PWM                     677
+#define CLK_PMU1PWM_CAPTURE             678
+#define PCLK_PMU1TIMER                  679
+#define CLK_PMU1TIMER_ROOT              680
+#define CLK_PMU1TIMER0                  681
+#define CLK_PMU1TIMER1                  682
+#define CLK_UART0_SRC                   683
+#define CLK_UART0_FRAC                  684
+#define CLK_UART0                       685
+#define SCLK_UART0                      686
+#define PCLK_UART0                      687
+#define PCLK_PMU1WDT                    688
+#define TCLK_PMU1WDT                    689
+#define CLK_CR_PARA                     690
+#define CLK_USB2PHY_HDPTXRXPHY_REF      693
+#define CLK_USBDPPHY_MIPIDCPPHY_REF     694
+#define CLK_REF_PIPE_PHY0_OSC_SRC       695
+#define CLK_REF_PIPE_PHY1_OSC_SRC       696
+#define CLK_REF_PIPE_PHY2_OSC_SRC       697
+#define CLK_REF_PIPE_PHY0_PLL_SRC       698
+#define CLK_REF_PIPE_PHY1_PLL_SRC       699
+#define CLK_REF_PIPE_PHY2_PLL_SRC       700
+#define CLK_REF_PIPE_PHY0               701
+#define CLK_REF_PIPE_PHY1               702
+#define CLK_REF_PIPE_PHY2               703
+#define SCLK_SDIO_DRV                   704
+#define SCLK_SDIO_SAMPLE                705
+#define SCLK_SDMMC_DRV                  706
+#define SCLK_SDMMC_SAMPLE               707
+#define CLK_PCIE1L0_PIPE                708
+#define CLK_PCIE1L1_PIPE                709
+#define CLK_BIGCORE0_PVTM               710
+#define CLK_CORE_BIGCORE0_PVTM          711
+#define CLK_BIGCORE1_PVTM               712
+#define CLK_CORE_BIGCORE1_PVTM          713
+#define CLK_LITCORE_PVTM                714
+#define CLK_CORE_LITCORE_PVTM           715
+#define CLK_AUX16M_0                    716
+#define CLK_AUX16M_1                    717
+#define CLK_PHY0_REF_ALT_P              718
+#define CLK_PHY0_REF_ALT_M              719
+#define CLK_PHY1_REF_ALT_P              720
+#define CLK_PHY1_REF_ALT_M              721
+
+#define CLK_NR_CLKS                     (CLK_PHY1_REF_ALT_M + 1)
+
+/********Name=SOFTRST_CON01,Offset=0xA04********/
+#define SRST_A_TOP_BIU                  19
+#define SRST_P_TOP_BIU                  20
+#define SRST_P_CSIPHY0                  22
+#define SRST_CSIPHY0                    23
+#define SRST_P_CSIPHY1                  24
+#define SRST_CSIPHY1                    25
+#define SRST_A_TOP_M500_BIU             31
+/********Name=SOFTRST_CON02,Offset=0xA08********/
+#define SRST_A_TOP_M400_BIU             32
+#define SRST_A_TOP_S200_BIU             33
+#define SRST_A_TOP_S400_BIU             34
+#define SRST_A_TOP_M300_BIU             35
+#define SRST_USBDP_COMBO_PHY0_INIT      40
+#define SRST_USBDP_COMBO_PHY0_CMN       41
+#define SRST_USBDP_COMBO_PHY0_LANE      42
+#define SRST_USBDP_COMBO_PHY0_PCS       43
+#define SRST_USBDP_COMBO_PHY1_INIT      47
+/********Name=SOFTRST_CON03,Offset=0xA0C********/
+#define SRST_USBDP_COMBO_PHY1_CMN       48
+#define SRST_USBDP_COMBO_PHY1_LANE      49
+#define SRST_USBDP_COMBO_PHY1_PCS       50
+#define SRST_DCPHY0                     59
+#define SRST_P_MIPI_DCPHY0              62
+#define SRST_P_MIPI_DCPHY0_GRF          63
+/********Name=SOFTRST_CON04,Offset=0xA10********/
+#define SRST_DCPHY1                     64
+#define SRST_P_MIPI_DCPHY1              67
+#define SRST_P_MIPI_DCPHY1_GRF          68
+#define SRST_P_APB2ASB_SLV_CDPHY        69
+#define SRST_P_APB2ASB_SLV_CSIPHY       70
+#define SRST_P_APB2ASB_SLV_VCCIO3_5     71
+#define SRST_P_APB2ASB_SLV_VCCIO6       72
+#define SRST_P_APB2ASB_SLV_EMMCIO       73
+#define SRST_P_APB2ASB_SLV_IOC_TOP      74
+#define SRST_P_APB2ASB_SLV_IOC_RIGHT    75
+/********Name=SOFTRST_CON05,Offset=0xA14********/
+#define SRST_P_CRU                      80
+#define SRST_A_CHANNEL_SECURE2VO1USB    87
+#define SRST_A_CHANNEL_SECURE2CENTER    88
+#define SRST_H_CHANNEL_SECURE2VO1USB    94
+#define SRST_H_CHANNEL_SECURE2CENTER    95
+/********Name=SOFTRST_CON06,Offset=0xA18********/
+#define SRST_P_CHANNEL_SECURE2VO1USB    96
+#define SRST_P_CHANNEL_SECURE2CENTER    97
+/********Name=SOFTRST_CON07,Offset=0xA1C********/
+#define SRST_H_AUDIO_BIU                114
+#define SRST_P_AUDIO_BIU                115
+#define SRST_H_I2S0_8CH                 116
+#define SRST_M_I2S0_8CH_TX              119
+#define SRST_M_I2S0_8CH_RX              122
+#define SRST_P_ACDCDIG                  123
+#define SRST_H_I2S2_2CH                 124
+#define SRST_H_I2S3_2CH                 125
+/********Name=SOFTRST_CON08,Offset=0xA20********/
+#define SRST_M_I2S2_2CH                 128
+#define SRST_M_I2S3_2CH                 131
+#define SRST_DAC_ACDCDIG                132
+#define SRST_H_SPDIF0                   142
+/********Name=SOFTRST_CON09,Offset=0xA24********/
+#define SRST_M_SPDIF0                   145
+#define SRST_H_SPDIF1                   146
+#define SRST_M_SPDIF1                   149
+#define SRST_H_PDM1                     150
+#define SRST_PDM1                       151
+/********Name=SOFTRST_CON10,Offset=0xA28********/
+#define SRST_A_BUS_BIU                  161
+#define SRST_P_BUS_BIU                  162
+#define SRST_A_GIC                      163
+#define SRST_A_GIC_DBG                  164
+#define SRST_A_DMAC0                    165
+#define SRST_A_DMAC1                    166
+#define SRST_A_DMAC2                    167
+#define SRST_P_I2C1                     168
+#define SRST_P_I2C2                     169
+#define SRST_P_I2C3                     170
+#define SRST_P_I2C4                     171
+#define SRST_P_I2C5                     172
+#define SRST_P_I2C6                     173
+#define SRST_P_I2C7                     174
+#define SRST_P_I2C8                     175
+/********Name=SOFTRST_CON11,Offset=0xA2C********/
+#define SRST_I2C1                       176
+#define SRST_I2C2                       177
+#define SRST_I2C3                       178
+#define SRST_I2C4                       179
+#define SRST_I2C5                       180
+#define SRST_I2C6                       181
+#define SRST_I2C7                       182
+#define SRST_I2C8                       183
+#define SRST_P_CAN0                     184
+#define SRST_CAN0                       185
+#define SRST_P_CAN1                     186
+#define SRST_CAN1                       187
+#define SRST_P_CAN2                     188
+#define SRST_CAN2                       189
+#define SRST_P_SARADC                   190
+/********Name=SOFTRST_CON12,Offset=0xA30********/
+#define SRST_P_TSADC                    192
+#define SRST_TSADC                      193
+#define SRST_P_UART1                    194
+#define SRST_P_UART2                    195
+#define SRST_P_UART3                    196
+#define SRST_P_UART4                    197
+#define SRST_P_UART5                    198
+#define SRST_P_UART6                    199
+#define SRST_P_UART7                    200
+#define SRST_P_UART8                    201
+#define SRST_P_UART9                    202
+#define SRST_S_UART1                    205
+/********Name=SOFTRST_CON13,Offset=0xA34********/
+#define SRST_S_UART2                    208
+#define SRST_S_UART3                    211
+#define SRST_S_UART4                    214
+#define SRST_S_UART5                    217
+#define SRST_S_UART6                    220
+#define SRST_S_UART7                    223
+/********Name=SOFTRST_CON14,Offset=0xA38********/
+#define SRST_S_UART8                    226
+#define SRST_S_UART9                    229
+#define SRST_P_SPI0                     230
+#define SRST_P_SPI1                     231
+#define SRST_P_SPI2                     232
+#define SRST_P_SPI3                     233
+#define SRST_P_SPI4                     234
+#define SRST_SPI0                       235
+#define SRST_SPI1                       236
+#define SRST_SPI2                       237
+#define SRST_SPI3                       238
+#define SRST_SPI4                       239
+/********Name=SOFTRST_CON15,Offset=0xA3C********/
+#define SRST_P_WDT0                     240
+#define SRST_T_WDT0                     241
+#define SRST_P_SYS_GRF                  242
+#define SRST_P_PWM1                     243
+#define SRST_PWM1                       244
+#define SRST_P_PWM2                     246
+#define SRST_PWM2                       247
+#define SRST_P_PWM3                     249
+#define SRST_PWM3                       250
+#define SRST_P_BUSTIMER0                252
+#define SRST_P_BUSTIMER1                253
+#define SRST_BUSTIMER0                  255
+/********Name=SOFTRST_CON16,Offset=0xA40********/
+#define SRST_BUSTIMER1                  256
+#define SRST_BUSTIMER2                  257
+#define SRST_BUSTIMER3                  258
+#define SRST_BUSTIMER4                  259
+#define SRST_BUSTIMER5                  260
+#define SRST_BUSTIMER6                  261
+#define SRST_BUSTIMER7                  262
+#define SRST_BUSTIMER8                  263
+#define SRST_BUSTIMER9                  264
+#define SRST_BUSTIMER10                 265
+#define SRST_BUSTIMER11                 266
+#define SRST_P_MAILBOX0                 267
+#define SRST_P_MAILBOX1                 268
+#define SRST_P_MAILBOX2                 269
+#define SRST_P_GPIO1                    270
+#define SRST_GPIO1                      271
+/********Name=SOFTRST_CON17,Offset=0xA44********/
+#define SRST_P_GPIO2                    272
+#define SRST_GPIO2                      273
+#define SRST_P_GPIO3                    274
+#define SRST_GPIO3                      275
+#define SRST_P_GPIO4                    276
+#define SRST_GPIO4                      277
+#define SRST_A_DECOM                    278
+#define SRST_P_DECOM                    279
+#define SRST_D_DECOM                    280
+#define SRST_P_TOP                      281
+#define SRST_A_GICADB_GIC2CORE_BUS      283
+#define SRST_P_DFT2APB                  284
+#define SRST_P_APB2ASB_MST_TOP          285
+#define SRST_P_APB2ASB_MST_CDPHY        286
+#define SRST_P_APB2ASB_MST_BOT_RIGHT    287
+/********Name=SOFTRST_CON18,Offset=0xA48********/
+#define SRST_P_APB2ASB_MST_IOC_TOP      288
+#define SRST_P_APB2ASB_MST_IOC_RIGHT    289
+#define SRST_P_APB2ASB_MST_CSIPHY       290
+#define SRST_P_APB2ASB_MST_VCCIO3_5     291
+#define SRST_P_APB2ASB_MST_VCCIO6       292
+#define SRST_P_APB2ASB_MST_EMMCIO       293
+#define SRST_A_SPINLOCK                 294
+#define SRST_P_OTPC_NS                  297
+#define SRST_OTPC_NS                    298
+#define SRST_OTPC_ARB                   299
+/********Name=SOFTRST_CON19,Offset=0xA4C********/
+#define SRST_P_BUSIOC                   304
+#define SRST_P_PMUCM0_INTMUX            308
+#define SRST_P_DDRCM0_INTMUX            309
+/********Name=SOFTRST_CON20,Offset=0xA50********/
+#define SRST_P_DDR_DFICTL_CH0           320
+#define SRST_P_DDR_MON_CH0              321
+#define SRST_P_DDR_STANDBY_CH0          322
+#define SRST_P_DDR_UPCTL_CH0            323
+#define SRST_TM_DDR_MON_CH0             324
+#define SRST_P_DDR_GRF_CH01             325
+#define SRST_DFI_CH0                    326
+#define SRST_SBR_CH0                    327
+#define SRST_DDR_UPCTL_CH0              328
+#define SRST_DDR_DFICTL_CH0             329
+#define SRST_DDR_MON_CH0                330
+#define SRST_DDR_STANDBY_CH0            331
+#define SRST_A_DDR_UPCTL_CH0            332
+#define SRST_P_DDR_DFICTL_CH1           333
+#define SRST_P_DDR_MON_CH1              334
+#define SRST_P_DDR_STANDBY_CH1          335
+/********Name=SOFTRST_CON21,Offset=0xA54********/
+#define SRST_P_DDR_UPCTL_CH1            336
+#define SRST_TM_DDR_MON_CH1             337
+#define SRST_DFI_CH1                    338
+#define SRST_SBR_CH1                    339
+#define SRST_DDR_UPCTL_CH1              340
+#define SRST_DDR_DFICTL_CH1             341
+#define SRST_DDR_MON_CH1                342
+#define SRST_DDR_STANDBY_CH1            343
+#define SRST_A_DDR_UPCTL_CH1            344
+#define SRST_A_DDR01_MSCH0              349
+#define SRST_A_DDR01_RS_MSCH0           350
+#define SRST_A_DDR01_FRS_MSCH0          351
+/********Name=SOFTRST_CON22,Offset=0xA58********/
+#define SRST_A_DDR01_SCRAMBLE0          352
+#define SRST_A_DDR01_FRS_SCRAMBLE0      353
+#define SRST_A_DDR01_MSCH1              354
+#define SRST_A_DDR01_RS_MSCH1           355
+#define SRST_A_DDR01_FRS_MSCH1          356
+#define SRST_A_DDR01_SCRAMBLE1          357
+#define SRST_A_DDR01_FRS_SCRAMBLE1      358
+#define SRST_P_DDR01_MSCH0              359
+#define SRST_P_DDR01_MSCH1              360
+/********Name=SOFTRST_CON23,Offset=0xA5C********/
+#define SRST_P_DDR_DFICTL_CH2           368
+#define SRST_P_DDR_MON_CH2              369
+#define SRST_P_DDR_STANDBY_CH2          370
+#define SRST_P_DDR_UPCTL_CH2            371
+#define SRST_TM_DDR_MON_CH2             372
+#define SRST_P_DDR_GRF_CH23             373
+#define SRST_DFI_CH2                    374
+#define SRST_SBR_CH2                    375
+#define SRST_DDR_UPCTL_CH2              376
+#define SRST_DDR_DFICTL_CH2             377
+#define SRST_DDR_MON_CH2                378
+#define SRST_DDR_STANDBY_CH2            379
+#define SRST_A_DDR_UPCTL_CH2            380
+#define SRST_P_DDR_DFICTL_CH3           381
+#define SRST_P_DDR_MON_CH3              382
+#define SRST_P_DDR_STANDBY_CH3          383
+/********Name=SOFTRST_CON24,Offset=0xA60********/
+#define SRST_P_DDR_UPCTL_CH3            384
+#define SRST_TM_DDR_MON_CH3             385
+#define SRST_DFI_CH3                    386
+#define SRST_SBR_CH3                    387
+#define SRST_DDR_UPCTL_CH3              388
+#define SRST_DDR_DFICTL_CH3             389
+#define SRST_DDR_MON_CH3                390
+#define SRST_DDR_STANDBY_CH3            391
+#define SRST_A_DDR_UPCTL_CH3            392
+#define SRST_A_DDR23_MSCH2              397
+#define SRST_A_DDR23_RS_MSCH2           398
+#define SRST_A_DDR23_FRS_MSCH2          399
+/********Name=SOFTRST_CON25,Offset=0xA64********/
+#define SRST_A_DDR23_SCRAMBLE2          400
+#define SRST_A_DDR23_FRS_SCRAMBLE2      401
+#define SRST_A_DDR23_MSCH3              402
+#define SRST_A_DDR23_RS_MSCH3           403
+#define SRST_A_DDR23_FRS_MSCH3          404
+#define SRST_A_DDR23_SCRAMBLE3          405
+#define SRST_A_DDR23_FRS_SCRAMBLE3      406
+#define SRST_P_DDR23_MSCH2              407
+#define SRST_P_DDR23_MSCH3              408
+/********Name=SOFTRST_CON26,Offset=0xA68********/
+#define SRST_ISP1                       419
+#define SRST_ISP1_VICAP                 420
+#define SRST_A_ISP1_BIU                 422
+#define SRST_H_ISP1_BIU                 424
+/********Name=SOFTRST_CON27,Offset=0xA6C********/
+#define SRST_A_RKNN1                    432
+#define SRST_A_RKNN1_BIU                433
+#define SRST_H_RKNN1                    434
+#define SRST_H_RKNN1_BIU                435
+/********Name=SOFTRST_CON28,Offset=0xA70********/
+#define SRST_A_RKNN2                    448
+#define SRST_A_RKNN2_BIU                449
+#define SRST_H_RKNN2                    450
+#define SRST_H_RKNN2_BIU                451
+/********Name=SOFTRST_CON29,Offset=0xA74********/
+#define SRST_A_RKNN_DSU0                467
+#define SRST_P_NPUTOP_BIU               469
+#define SRST_P_NPU_TIMER                470
+#define SRST_NPUTIMER0                  472
+#define SRST_NPUTIMER1                  473
+#define SRST_P_NPU_WDT                  474
+#define SRST_T_NPU_WDT                  475
+#define SRST_P_NPU_PVTM                 476
+#define SRST_P_NPU_GRF                  477
+#define SRST_NPU_PVTM                   478
+/********Name=SOFTRST_CON30,Offset=0xA78********/
+#define SRST_NPU_PVTPLL                 480
+#define SRST_H_NPU_CM0_BIU              482
+#define SRST_F_NPU_CM0_CORE             483
+#define SRST_T_NPU_CM0_JTAG             484
+#define SRST_A_RKNN0                    486
+#define SRST_A_RKNN0_BIU                487
+#define SRST_H_RKNN0                    488
+#define SRST_H_RKNN0_BIU                489
+/********Name=SOFTRST_CON31,Offset=0xA7C********/
+#define SRST_H_NVM_BIU                  498
+#define SRST_A_NVM_BIU                  499
+#define SRST_H_EMMC                     500
+#define SRST_A_EMMC                     501
+#define SRST_C_EMMC                     502
+#define SRST_B_EMMC                     503
+#define SRST_T_EMMC                     504
+#define SRST_S_SFC                      505
+#define SRST_H_SFC                      506
+#define SRST_H_SFC_XIP                  507
+/********Name=SOFTRST_CON32,Offset=0xA80********/
+#define SRST_P_GRF                      513
+#define SRST_P_DEC_BIU                  514
+#define SRST_P_PHP_BIU                  517
+#define SRST_A_PCIE_GRIDGE              520
+#define SRST_A_PHP_BIU                  521
+#define SRST_A_GMAC0                    522
+#define SRST_A_GMAC1                    523
+#define SRST_A_PCIE_BIU                 524
+#define SRST_PCIE0_POWER_UP             525
+#define SRST_PCIE1_POWER_UP             526
+#define SRST_PCIE2_POWER_UP             527
+/********Name=SOFTRST_CON33,Offset=0xA84********/
+#define SRST_PCIE3_POWER_UP             528
+#define SRST_PCIE4_POWER_UP             529
+#define SRST_P_PCIE0                    540
+#define SRST_P_PCIE1                    541
+#define SRST_P_PCIE2                    542
+#define SRST_P_PCIE3                    543
+/********Name=SOFTRST_CON34,Offset=0xA88********/
+#define SRST_P_PCIE4                    544
+#define SRST_A_PHP_GIC_ITS              550
+#define SRST_A_MMU_PCIE                 551
+#define SRST_A_MMU_PHP                  552
+#define SRST_A_MMU_BIU                  553
+/********Name=SOFTRST_CON35,Offset=0xA8C********/
+#define SRST_A_USB3OTG2                 567
+/********Name=SOFTRST_CON37,Offset=0xA94********/
+#define SRST_PMALIVE0                   596
+#define SRST_PMALIVE1                   597
+#define SRST_PMALIVE2                   598
+#define SRST_A_SATA0                    599
+#define SRST_A_SATA1                    600
+#define SRST_A_SATA2                    601
+#define SRST_RXOOB0                     602
+#define SRST_RXOOB1                     603
+#define SRST_RXOOB2                     604
+#define SRST_ASIC0                      605
+#define SRST_ASIC1                      606
+#define SRST_ASIC2                      607
+/********Name=SOFTRST_CON40,Offset=0xAA0********/
+#define SRST_A_RKVDEC_CCU               642
+#define SRST_H_RKVDEC0                  643
+#define SRST_A_RKVDEC0                  644
+#define SRST_H_RKVDEC0_BIU              645
+#define SRST_A_RKVDEC0_BIU              646
+#define SRST_RKVDEC0_CA                 647
+#define SRST_RKVDEC0_HEVC_CA            648
+#define SRST_RKVDEC0_CORE               649
+/********Name=SOFTRST_CON41,Offset=0xAA4********/
+#define SRST_H_RKVDEC1                  658
+#define SRST_A_RKVDEC1                  659
+#define SRST_H_RKVDEC1_BIU              660
+#define SRST_A_RKVDEC1_BIU              661
+#define SRST_RKVDEC1_CA                 662
+#define SRST_RKVDEC1_HEVC_CA            663
+#define SRST_RKVDEC1_CORE               664
+/********Name=SOFTRST_CON42,Offset=0xAA8********/
+#define SRST_A_USB_BIU                  674
+#define SRST_H_USB_BIU                  675
+#define SRST_A_USB3OTG0                 676
+#define SRST_A_USB3OTG1                 679
+#define SRST_H_HOST0                    682
+#define SRST_H_HOST_ARB0                683
+#define SRST_H_HOST1                    684
+#define SRST_H_HOST_ARB1                685
+#define SRST_A_USB_GRF                  686
+#define SRST_C_USB2P0_HOST0             687
+/********Name=SOFTRST_CON43,Offset=0xAAC********/
+#define SRST_C_USB2P0_HOST1             688
+#define SRST_HOST_UTMI0                 689
+#define SRST_HOST_UTMI1                 690
+/********Name=SOFTRST_CON44,Offset=0xAB0********/
+#define SRST_A_VDPU_BIU                 708
+#define SRST_A_VDPU_LOW_BIU             709
+#define SRST_H_VDPU_BIU                 710
+#define SRST_A_JPEG_DECODER_BIU         711
+#define SRST_A_VPU                      712
+#define SRST_H_VPU                      713
+#define SRST_A_JPEG_ENCODER0            714
+#define SRST_H_JPEG_ENCODER0            715
+#define SRST_A_JPEG_ENCODER1            716
+#define SRST_H_JPEG_ENCODER1            717
+#define SRST_A_JPEG_ENCODER2            718
+#define SRST_H_JPEG_ENCODER2            719
+/********Name=SOFTRST_CON45,Offset=0xAB4********/
+#define SRST_A_JPEG_ENCODER3            720
+#define SRST_H_JPEG_ENCODER3            721
+#define SRST_A_JPEG_DECODER             722
+#define SRST_H_JPEG_DECODER             723
+#define SRST_H_IEP2P0                   724
+#define SRST_A_IEP2P0                   725
+#define SRST_IEP2P0_CORE                726
+#define SRST_H_RGA2                     727
+#define SRST_A_RGA2                     728
+#define SRST_RGA2_CORE                  729
+#define SRST_H_RGA3_0                   730
+#define SRST_A_RGA3_0                   731
+#define SRST_RGA3_0_CORE                732
+/********Name=SOFTRST_CON47,Offset=0xABC********/
+#define SRST_H_RKVENC0_BIU              754
+#define SRST_A_RKVENC0_BIU              755
+#define SRST_H_RKVENC0                  756
+#define SRST_A_RKVENC0                  757
+#define SRST_RKVENC0_CORE               758
+/********Name=SOFTRST_CON48,Offset=0xAC0********/
+#define SRST_H_RKVENC1_BIU              770
+#define SRST_A_RKVENC1_BIU              771
+#define SRST_H_RKVENC1                  772
+#define SRST_A_RKVENC1                  773
+#define SRST_RKVENC1_CORE               774
+/********Name=SOFTRST_CON49,Offset=0xAC4********/
+#define SRST_A_VI_BIU                   787
+#define SRST_H_VI_BIU                   788
+#define SRST_P_VI_BIU                   789
+#define SRST_D_VICAP                    790
+#define SRST_A_VICAP                    791
+#define SRST_H_VICAP                    792
+#define SRST_ISP0                       794
+#define SRST_ISP0_VICAP                 795
+/********Name=SOFTRST_CON50,Offset=0xAC8********/
+#define SRST_FISHEYE0                   800
+#define SRST_FISHEYE1                   803
+#define SRST_P_CSI_HOST_0               804
+#define SRST_P_CSI_HOST_1               805
+#define SRST_P_CSI_HOST_2               806
+#define SRST_P_CSI_HOST_3               807
+#define SRST_P_CSI_HOST_4               808
+#define SRST_P_CSI_HOST_5               809
+/********Name=SOFTRST_CON51,Offset=0xACC********/
+#define SRST_CSIHOST0_VICAP             820
+#define SRST_CSIHOST1_VICAP             821
+#define SRST_CSIHOST2_VICAP             822
+#define SRST_CSIHOST3_VICAP             823
+#define SRST_CSIHOST4_VICAP             824
+#define SRST_CSIHOST5_VICAP             825
+#define SRST_CIFIN                      829
+/********Name=SOFTRST_CON52,Offset=0xAD0********/
+#define SRST_A_VOP_BIU                  836
+#define SRST_A_VOP_LOW_BIU              837
+#define SRST_H_VOP_BIU                  838
+#define SRST_P_VOP_BIU                  839
+#define SRST_H_VOP                      840
+#define SRST_A_VOP                      841
+#define SRST_D_VOP0                     845
+#define SRST_D_VOP2HDMI_BRIDGE0         846
+#define SRST_D_VOP2HDMI_BRIDGE1         847
+/********Name=SOFTRST_CON53,Offset=0xAD4********/
+#define SRST_D_VOP1                     848
+#define SRST_D_VOP2                     849
+#define SRST_D_VOP3                     850
+#define SRST_P_VOPGRF                   851
+#define SRST_P_DSIHOST0                 852
+#define SRST_P_DSIHOST1                 853
+#define SRST_DSIHOST0                   854
+#define SRST_DSIHOST1                   855
+#define SRST_VOP_PMU                    856
+#define SRST_P_VOP_CHANNEL_BIU          857
+/********Name=SOFTRST_CON55,Offset=0xADC********/
+#define SRST_H_VO0_BIU                  885
+#define SRST_H_VO0_S_BIU                886
+#define SRST_P_VO0_BIU                  887
+#define SRST_P_VO0_S_BIU                888
+#define SRST_A_HDCP0_BIU                889
+#define SRST_P_VO0GRF                   890
+#define SRST_H_HDCP_KEY0                891
+#define SRST_A_HDCP0                    892
+#define SRST_H_HDCP0                    893
+#define SRST_HDCP0                      895
+/********Name=SOFTRST_CON56,Offset=0xAE0********/
+#define SRST_P_TRNG0                    897
+#define SRST_DP0                        904
+#define SRST_DP1                        905
+#define SRST_H_I2S4_8CH                 906
+#define SRST_M_I2S4_8CH_TX              909
+#define SRST_H_I2S8_8CH                 910
+/********Name=SOFTRST_CON57,Offset=0xAE4********/
+#define SRST_M_I2S8_8CH_TX              913
+#define SRST_H_SPDIF2_DP0               914
+#define SRST_M_SPDIF2_DP0               918
+#define SRST_H_SPDIF5_DP1               919
+#define SRST_M_SPDIF5_DP1               923
+/********Name=SOFTRST_CON59,Offset=0xAEC********/
+#define SRST_A_HDCP1_BIU                950
+#define SRST_A_HDMIRX_BIU               951
+#define SRST_A_VO1_BIU                  952
+#define SRST_H_VOP1_BIU                 953
+#define SRST_H_VOP1_S_BIU               954
+#define SRST_P_VOP1_BIU                 955
+#define SRST_P_VO1GRF                   956
+#define SRST_P_VO1_S_BIU                957
+/********Name=SOFTRST_CON60,Offset=0xAF0********/
+#define SRST_H_I2S7_8CH                 960
+#define SRST_M_I2S7_8CH_RX              963
+#define SRST_H_HDCP_KEY1                964
+#define SRST_A_HDCP1                    965
+#define SRST_H_HDCP1                    966
+#define SRST_HDCP1                      968
+#define SRST_P_TRNG1                    970
+#define SRST_P_HDMITX0                  971
+/********Name=SOFTRST_CON61,Offset=0xAF4********/
+#define SRST_HDMITX0_REF                976
+#define SRST_P_HDMITX1                  978
+#define SRST_HDMITX1_REF                983
+#define SRST_A_HDMIRX                   985
+#define SRST_P_HDMIRX                   986
+#define SRST_HDMIRX_REF                 987
+/********Name=SOFTRST_CON62,Offset=0xAF8********/
+#define SRST_P_EDP0                     992
+#define SRST_EDP0_24M                   993
+#define SRST_P_EDP1                     995
+#define SRST_EDP1_24M                   996
+#define SRST_M_I2S5_8CH_TX              1000
+#define SRST_H_I2S5_8CH                 1004
+#define SRST_M_I2S6_8CH_TX              1007
+/********Name=SOFTRST_CON63,Offset=0xAFC********/
+#define SRST_M_I2S6_8CH_RX              1010
+#define SRST_H_I2S6_8CH                 1011
+#define SRST_H_SPDIF3                   1012
+#define SRST_M_SPDIF3                   1015
+#define SRST_H_SPDIF4                   1016
+#define SRST_M_SPDIF4                   1019
+#define SRST_H_SPDIFRX0                 1020
+#define SRST_M_SPDIFRX0                 1021
+#define SRST_H_SPDIFRX1                 1022
+#define SRST_M_SPDIFRX1                 1023
+/********Name=SOFTRST_CON64,Offset=0xB00********/
+#define SRST_H_SPDIFRX2                 1024
+#define SRST_M_SPDIFRX2                 1025
+#define SRST_LINKSYM_HDMITXPHY0         1036
+#define SRST_LINKSYM_HDMITXPHY1         1037
+#define SRST_VO1_BRIDGE0                1038
+#define SRST_VO1_BRIDGE1                1039
+/********Name=SOFTRST_CON65,Offset=0xB04********/
+#define SRST_H_I2S9_8CH                 1040
+#define SRST_M_I2S9_8CH_RX              1043
+#define SRST_H_I2S10_8CH                1044
+#define SRST_M_I2S10_8CH_RX             1047
+#define SRST_P_S_HDMIRX                 1048
+/********Name=SOFTRST_CON66,Offset=0xB08********/
+#define SRST_GPU                        1060
+#define SRST_SYS_GPU                    1061
+#define SRST_A_S_GPU_BIU                1064
+#define SRST_A_M0_GPU_BIU               1065
+#define SRST_A_M1_GPU_BIU               1066
+#define SRST_A_M2_GPU_BIU               1067
+#define SRST_A_M3_GPU_BIU               1068
+#define SRST_P_GPU_BIU                  1070
+#define SRST_P_GPU_PVTM                 1071
+/********Name=SOFTRST_CON67,Offset=0xB0C********/
+#define SRST_GPU_PVTM                   1072
+#define SRST_P_GPU_GRF                  1074
+#define SRST_GPU_PVTPLL                 1075
+#define SRST_GPU_JTAG                   1076
+/********Name=SOFTRST_CON68,Offset=0xB10********/
+#define SRST_A_AV1_BIU                  1089
+#define SRST_A_AV1                      1090
+#define SRST_P_AV1_BIU                  1092
+#define SRST_P_AV1                      1093
+/********Name=SOFTRST_CON69,Offset=0xB14********/
+#define SRST_A_DDR_BIU                  1108
+#define SRST_A_DMA2DDR                  1109
+#define SRST_A_DDR_SHAREMEM             1110
+#define SRST_A_DDR_SHAREMEM_BIU         1111
+#define SRST_A_CENTER_S200_BIU          1114
+#define SRST_A_CENTER_S400_BIU          1115
+#define SRST_H_AHB2APB                  1116
+#define SRST_H_CENTER_BIU               1117
+#define SRST_F_DDR_CM0_CORE             1118
+/********Name=SOFTRST_CON70,Offset=0xB18********/
+#define SRST_DDR_TIMER0                 1120
+#define SRST_DDR_TIMER1                 1121
+#define SRST_T_WDT_DDR                  1122
+#define SRST_T_DDR_CM0_JTAG             1123
+#define SRST_P_CENTER_GRF               1125
+#define SRST_P_AHB2APB                  1126
+#define SRST_P_WDT                      1127
+#define SRST_P_TIMER                    1128
+#define SRST_P_DMA2DDR                  1129
+#define SRST_P_SHAREMEM                 1130
+#define SRST_P_CENTER_BIU               1131
+#define SRST_P_CENTER_CHANNEL_BIU       1132
+/********Name=SOFTRST_CON72,Offset=0xB20********/
+#define SRST_P_USBDPGRF0                1153
+#define SRST_P_USBDPPHY0                1154
+#define SRST_P_USBDPGRF1                1155
+#define SRST_P_USBDPPHY1                1156
+#define SRST_P_HDPTX0                   1157
+#define SRST_P_HDPTX1                   1158
+#define SRST_P_APB2ASB_SLV_BOT_RIGHT    1159
+#define SRST_P_USB2PHY_U3_0_GRF0        1160
+#define SRST_P_USB2PHY_U3_1_GRF0        1161
+#define SRST_P_USB2PHY_U2_0_GRF0        1162
+#define SRST_P_USB2PHY_U2_1_GRF0        1163
+#define SRST_HDPTX0_ROPLL               1164
+#define SRST_HDPTX0_LCPLL               1165
+#define SRST_HDPTX0                     1166
+#define SRST_HDPTX1_ROPLL               1167
+/********Name=SOFTRST_CON73,Offset=0xB24********/
+#define SRST_HDPTX1_LCPLL               1168
+#define SRST_HDPTX1                     1169
+#define SRST_HDPTX0_HDMIRXPHY_SET       1170
+#define SRST_USBDP_COMBO_PHY0           1171
+#define SRST_USBDP_COMBO_PHY0_LCPLL     1172
+#define SRST_USBDP_COMBO_PHY0_ROPLL     1173
+#define SRST_USBDP_COMBO_PHY0_PCS_HS    1174
+#define SRST_USBDP_COMBO_PHY1           1175
+#define SRST_USBDP_COMBO_PHY1_LCPLL     1176
+#define SRST_USBDP_COMBO_PHY1_ROPLL     1177
+#define SRST_USBDP_COMBO_PHY1_PCS_HS    1178
+#define SRST_HDMIHDP0                   1180
+#define SRST_HDMIHDP1                   1181
+/********Name=SOFTRST_CON74,Offset=0xB28********/
+#define SRST_A_VO1USB_TOP_BIU           1185
+#define SRST_H_VO1USB_TOP_BIU           1187
+/********Name=SOFTRST_CON75,Offset=0xB2C********/
+#define SRST_H_SDIO_BIU                 1201
+#define SRST_H_SDIO                     1202
+#define SRST_SDIO                       1203
+/********Name=SOFTRST_CON76,Offset=0xB30********/
+#define SRST_H_RGA3_BIU                 1218
+#define SRST_A_RGA3_BIU                 1219
+#define SRST_H_RGA3_1                   1220
+#define SRST_A_RGA3_1                   1221
+#define SRST_RGA3_1_CORE                1222
+/********Name=SOFTRST_CON77,Offset=0xB34********/
+#define SRST_REF_PIPE_PHY0              1238
+#define SRST_REF_PIPE_PHY1              1239
+#define SRST_REF_PIPE_PHY2              1240
+
+/********Name=PHPTOPSOFTRST_CON0,Offset=0x8A00********/
+#define SRST_P_PHPTOP_CRU               131073
+#define SRST_P_PCIE2_GRF0               131074
+#define SRST_P_PCIE2_GRF1               131075
+#define SRST_P_PCIE2_GRF2               131076
+#define SRST_P_PCIE2_PHY0               131077
+#define SRST_P_PCIE2_PHY1               131078
+#define SRST_P_PCIE2_PHY2               131079
+#define SRST_P_PCIE3_PHY                131080
+#define SRST_P_APB2ASB_SLV_CHIP_TOP     131081
+#define SRST_PCIE30_PHY                 131082
+
+/********Name=PMU1SOFTRST_CON00,Offset=0x30A00********/
+#define SRST_H_PMU1_BIU                 786442
+#define SRST_P_PMU1_BIU                 786443
+#define SRST_H_PMU_CM0_BIU              786444
+#define SRST_F_PMU_CM0_CORE             786445
+#define SRST_T_PMU1_CM0_JTAG            786446
+
+/********Name=PMU1SOFTRST_CON01,Offset=0x30A04********/
+#define SRST_DDR_FAIL_SAFE              786449
+#define SRST_P_CRU_PMU1                 786450
+#define SRST_P_PMU1_GRF                 786452
+#define SRST_P_PMU1_IOC                 786453
+#define SRST_P_PMU1WDT                  786454
+#define SRST_T_PMU1WDT                  786455
+#define SRST_P_PMU1TIMER                786456
+#define SRST_PMU1TIMER0                 786458
+#define SRST_PMU1TIMER1                 786459
+#define SRST_P_PMU1PWM                  786460
+#define SRST_PMU1PWM                    786461
+
+/********Name=PMU1SOFTRST_CON02,Offset=0x30A08********/
+#define SRST_P_I2C0                     786465
+#define SRST_I2C0                       786466
+#define SRST_S_UART0                    786469
+#define SRST_P_UART0                    786470
+#define SRST_H_I2S1_8CH                 786471
+#define SRST_M_I2S1_8CH_TX              786474
+#define SRST_M_I2S1_8CH_RX              786477
+#define SRST_H_PDM0                     786478
+#define SRST_PDM0                       786479
+
+/********Name=PMU1SOFTRST_CON03,Offset=0x30A0C********/
+#define SRST_H_VAD                      786480
+#define SRST_HDPTX0_INIT                786491
+#define SRST_HDPTX0_CMN                 786492
+#define SRST_HDPTX0_LANE                786493
+#define SRST_HDPTX1_INIT                786495
+
+/********Name=PMU1SOFTRST_CON04,Offset=0x30A10********/
+#define SRST_HDPTX1_CMN                 786496
+#define SRST_HDPTX1_LANE                786497
+#define SRST_M_MIPI_DCPHY0              786499
+#define SRST_S_MIPI_DCPHY0              786500
+#define SRST_M_MIPI_DCPHY1              786501
+#define SRST_S_MIPI_DCPHY1              786502
+#define SRST_OTGPHY_U3_0                786503
+#define SRST_OTGPHY_U3_1                786504
+#define SRST_OTGPHY_U2_0                786505
+#define SRST_OTGPHY_U2_1                786506
+
+/********Name=PMU1SOFTRST_CON05,Offset=0x30A14********/
+#define SRST_P_PMU0GRF                  786515
+#define SRST_P_PMU0IOC                  786516
+#define SRST_P_GPIO0                    786517
+#define SRST_GPIO0                      786518
+
+/* scmi-clocks indices */
+
+#define SCMI_CLK_CPUL                   0
+#define SCMI_CLK_DSU                    1
+#define SCMI_CLK_CPUB01                 2
+#define SCMI_CLK_CPUB23                 3
+#define SCMI_CLK_DDR                    4
+#define SCMI_CLK_GPU                    5
+#define SCMI_CLK_NPU                    6
+#define SCMI_CLK_SBUS                   7
+#define SCMI_PCLK_SBUS                  8
+#define SCMI_CCLK_SD                    9
+#define SCMI_DCLK_SD                    10
+#define SCMI_ACLK_SECURE_NS             11
+#define SCMI_HCLK_SECURE_NS             12
+#define SCMI_TCLK_WDT                   13
+#define SCMI_KEYLADDER_CORE             14
+#define SCMI_KEYLADDER_RNG              15
+#define SCMI_ACLK_SECURE_S              16
+#define SCMI_HCLK_SECURE_S              17
+#define SCMI_PCLK_SECURE_S              18
+#define SCMI_CRYPTO_RNG                 19
+#define SCMI_CRYPTO_CORE                20
+#define SCMI_CRYPTO_PKA                 21
+#define SCMI_SPLL                       22
+#define SCMI_HCLK_SD                    23
+
+/********Name=SECURE_SOFTRST_CON00,Offset=0xA00********/
+#define SRST_A_SECURE_NS_BIU            10
+#define SRST_H_SECURE_NS_BIU            11
+#define SRST_A_SECURE_S_BIU             12
+#define SRST_H_SECURE_S_BIU             13
+#define SRST_P_SECURE_S_BIU             14
+#define SRST_CRYPTO_CORE                15
+/********Name=SECURE_SOFTRST_CON01,Offset=0xA04********/
+#define SRST_CRYPTO_PKA                 16
+#define SRST_CRYPTO_RNG                 17
+#define SRST_A_CRYPTO                   18
+#define SRST_H_CRYPTO                   19
+#define SRST_KEYLADDER_CORE             25
+#define SRST_KEYLADDER_RNG              26
+#define SRST_A_KEYLADDER                27
+#define SRST_H_KEYLADDER                28
+#define SRST_P_OTPC_S                   29
+#define SRST_OTPC_S                     30
+#define SRST_WDT_S                      31
+/********Name=SECURE_SOFTRST_CON02,Offset=0xA08********/
+#define SRST_T_WDT_S                    32
+#define SRST_H_BOOTROM                  33
+#define SRST_A_DCF                      34
+#define SRST_P_DCF                      35
+#define SRST_H_BOOTROM_NS               37
+#define SRST_P_KEYLADDER                46
+#define SRST_H_TRNG_S                   47
+/********Name=SECURE_SOFTRST_CON03,Offset=0xA0C********/
+#define SRST_H_TRNG_NS                  48
+#define SRST_D_SDMMC_BUFFER             49
+#define SRST_H_SDMMC                    50
+#define SRST_H_SDMMC_BUFFER             51
+#define SRST_SDMMC                      52
+#define SRST_P_TRNG_CHK                 53
+#define SRST_TRNG_S                     54
+
+#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3588_H__ */

+ 110 - 0
bsp/rockchip/rk3500/driver/clk/softrst.c

@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+struct rockchip_softrst
+{
+    void *regs;
+    int num_per_reg;
+    rt_uint8_t flags;
+
+    struct rt_spinlock lock;
+};
+
+static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc)
+{
+    int 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->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
+    {
+        HWREG32(softrst->regs + (bank * 4)) = RT_BIT(offset) | (RT_BIT(offset) << 16);
+    }
+    else
+    {
+        rt_uint32_t reg;
+        rt_ubase_t level;
+
+        level = rt_spin_lock_irqsave(&softrst->lock);
+
+        reg = HWREG32(softrst->regs + (bank * 4));
+        HWREG32(softrst->regs + (bank * 4)) = reg | RT_BIT(offset);
+
+        rt_spin_unlock_irqrestore(&softrst->lock, level);
+    }
+
+    return RT_EOK;
+}
+
+static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc)
+{
+    int 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->flags & ROCKCHIP_SOFTRST_HIWORD_MASK)
+    {
+        HWREG32(softrst->regs + (bank * 4)) = (RT_BIT(offset) << 16);
+    }
+    else
+    {
+        rt_uint32_t reg;
+        rt_ubase_t level;
+
+        level = rt_spin_lock_irqsave(&softrst->lock);
+
+        reg = HWREG32(softrst->regs + (bank * 4));
+        HWREG32(softrst->regs + (bank * 4)) = reg & ~RT_BIT(offset);
+
+        rt_spin_unlock_irqrestore(&softrst->lock, level);
+    }
+
+    return RT_EOK;
+}
+
+static const struct rt_reset_control_ops rockchip_softrst_ops =
+{
+    .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 err;
+    struct rockchip_softrst *softrst = rt_calloc(1, sizeof(*softrst));
+
+    if (!softrst)
+    {
+        return -RT_ENOMEM;
+    }
+
+    rstcer->priv = softrst;
+
+    rt_spin_lock_init(&softrst->lock);
+
+    softrst->regs = regs;
+    softrst->flags = flags;
+    softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16 : 32;
+
+    rstcer->ofw_node = np;
+    rstcer->ops = &rockchip_softrst_ops;
+
+    if ((err = rt_reset_controller_register(rstcer)))
+    {
+        rt_free(softrst);
+    }
+
+    return err;
+}

+ 5 - 0
bsp/rockchip/rk3500/driver/hwtimer/Kconfig

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

+ 13 - 0
bsp/rockchip/rk3500/driver/hwtimer/SConscript

@@ -0,0 +1,13 @@
+from building import *
+
+cwd = GetCurrentDir()
+CPPPATH = [cwd]
+
+src = []
+
+if GetDepend(['RT_HWTIMER_ROCKCHIP']):
+    src += ['hwtimer-rockchip_timer.c']
+
+group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 393 - 0
bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c

@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 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_DISABLE                   0x0
+#define TIMER_ENABLE                    0x1
+#define TIMER_MODE_FREE_RUNNING         (0 << 1)
+#define TIMER_MODE_USER_DEFINED_COUNT   (1 << 1)
+#define TIMER_INT_UNMASK                (1 << 2)
+
+struct rk_timer
+{
+    struct rt_hwtimer_device parent;
+
+    void *base;
+    void *ctrl;
+    struct rt_clk *clk;
+    struct rt_clk *pclk;
+
+    int irq;
+    rt_uint32_t freq;
+    rt_uint32_t cycle;
+    rt_bool_t status;
+
+    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
+{
+    rt_uint32_t ctrl_reg;
+};
+
+rt_inline void rk_timer_disable(struct rk_timer *timer)
+{
+    HWREG32(timer->ctrl) = TIMER_DISABLE;
+}
+
+rt_inline void rk_timer_enable(struct rk_timer *timer, rt_uint32_t flags)
+{
+    HWREG32(timer->ctrl) = TIMER_ENABLE | flags;
+}
+
+rt_inline rt_uint32_t rk_timer_current_value(struct rk_timer *timer)
+{
+    return HWREG32(timer->base + TIMER_CURRENT_VALUE0);
+}
+
+static void rk_timer_update_counter(unsigned long cycles, struct rk_timer *timer)
+{
+    HWREG32(timer->base + TIMER_LOAD_COUNT0) = cycles;
+    HWREG32(timer->base + TIMER_LOAD_COUNT1) = 0;
+}
+
+static void rk_timer_interrupt_clear(struct rk_timer *timer)
+{
+    HWREG32(timer->base + TIMER_INT_STATUS) = 1;
+}
+
+static void rk_timer_init(struct rt_hwtimer_device *timer, rt_uint32_t state)
+{
+}
+
+static rt_err_t rk_timer_start(struct rt_hwtimer_device *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
+{
+    rt_err_t err = RT_EOK;
+    struct rk_timer *rk_timer = raw_to_rk_timer(timer);
+
+    switch (mode)
+    {
+    case HWTIMER_MODE_ONESHOT:
+        rk_timer_disable(rk_timer);
+        rk_timer_update_counter(cnt, rk_timer);
+        rk_timer_enable(rk_timer, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK);
+        break;
+
+    case HWTIMER_MODE_PERIOD:
+        rk_timer_disable(rk_timer);
+        rk_timer_update_counter(rk_timer->freq / HZ - 1, rk_timer);
+        rk_timer_enable(rk_timer, TIMER_MODE_FREE_RUNNING | TIMER_INT_UNMASK);
+        break;
+
+    default:
+        err = -RT_EINVAL;
+        break;
+    }
+
+    if (!err)
+    {
+        rk_timer->cycle = cnt;
+        rk_timer->status = RT_TRUE;
+    }
+
+    return err;
+}
+
+static void rk_timer_stop(struct rt_hwtimer_device *timer)
+{
+    struct rk_timer *rk_timer = raw_to_rk_timer(timer);
+
+    rk_timer->status = RT_FALSE;
+    rk_timer_disable(rk_timer);
+}
+
+static rt_uint32_t rk_timer_count_get(struct rt_hwtimer_device *timer)
+{
+    struct rk_timer *rk_timer = raw_to_rk_timer(timer);
+
+    return rk_timer_current_value(rk_timer);
+}
+
+static rt_err_t rk_timer_ctrl(struct rt_hwtimer_device *timer, rt_uint32_t cmd, void *args)
+{
+    rt_err_t err = RT_EOK;
+    struct rk_timer *rk_timer = raw_to_rk_timer(timer);
+
+    switch (cmd)
+    {
+    case HWTIMER_CTRL_FREQ_SET:
+        err = -RT_ENOSYS;
+        break;
+
+    case HWTIMER_CTRL_STOP:
+        rk_timer_stop(timer);
+        break;
+
+    case HWTIMER_CTRL_INFO_GET:
+        if (args)
+        {
+            rt_memcpy(args, &rk_timer->info, sizeof(rk_timer->info));
+        }
+        else
+        {
+            err = -RT_ERROR;
+        }
+        break;
+
+    case HWTIMER_CTRL_MODE_SET:
+        err = rk_timer_start(timer, rk_timer->cycle, (rt_hwtimer_mode_t)args);
+        break;
+
+    default:
+        err = -RT_EINVAL;
+        break;
+    }
+
+    return err;
+}
+
+const static struct rt_hwtimer_ops rk_timer_ops =
+{
+    .init = rk_timer_init,
+    .start = rk_timer_start,
+    .stop = rk_timer_stop,
+    .count_get = rk_timer_count_get,
+    .control = rk_timer_ctrl,
+};
+
+static void rk_timer_isr(int irqno, void *param)
+{
+    struct hrt_timer *timer = &_timer0;
+    struct rk_timer *time = timer->timer;
+
+    rk_timer_interrupt_clear(time);
+
+    rt_ktime_hrtimer_process();
+}
+
+void rt_ktime_hrtimer_bind(rt_bitmap_t *affinity)
+{
+    struct rk_timer *timer = _timer0.timer;
+
+    if (rt_pic_irq_set_affinity(timer->irq, affinity) == -RT_ENOSYS)
+    {
+        LOG_E("timer irq affinity init fail\n");
+    }
+    else
+    {
+        LOG_D("timer irq(%d) binding done\n", timer->irq);
+    }
+}
+
+static rt_err_t rk_timer_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err = RT_EOK;
+    const char *dev_name;
+    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")))
+    {
+        err = -RT_EIO;
+
+        goto _fail;
+    }
+
+    if (!(timer->clk = rt_clk_get_by_name(dev, "timer")))
+    {
+        err = -RT_EIO;
+
+        goto _fail;
+    }
+
+    timer->base = rt_dm_dev_iomap(dev, 0);
+
+    if (!timer->base)
+    {
+        err = -RT_EIO;
+
+        goto _fail;
+    }
+
+    timer->ctrl = timer->base + timer_data->ctrl_reg;
+
+    rt_clk_enable(timer->pclk);
+    rt_clk_enable(timer->clk);
+    timer->freq = rt_clk_get_rate(timer->clk);
+    timer->irq = rt_dm_dev_get_irq(dev, 0);
+
+    rk_timer_interrupt_clear(timer);
+    rk_timer_disable(timer);
+
+    timer->parent.ops = &rk_timer_ops;
+    timer->parent.info = &timer->info;
+
+    timer->info.maxfreq = timer->freq;
+    timer->info.minfreq = timer->freq;
+    timer->info.maxcnt = 0xffffffff;
+    timer->info.cntmode = HWTIMER_CNTMODE_DW;
+
+    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_BITMAP_DECLARE(affinity, RT_CPUS_NR) = { 0 };
+    rt_bitmap_set_bit(affinity, RT_CPUS_NR - 1);
+    rt_ktime_hrtimer_bind(affinity);
+
+    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
+
+    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);
+
+    return err;
+}
+
+static const struct rk_timer_data rk3288_timer_data =
+{
+    .ctrl_reg = TIMER_CONTROL_REG3288,
+};
+
+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);
+}
+
+uint64_t rt_ktime_hrtimer_getcnt(void)
+{
+    return rk_timer_current_value(_timer0.timer);
+}
+
+/**
+ * @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 },
+    { .compatible = "rockchip,rk3399-timer", .data = &rk3399_timer_data },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rk_timer_driver =
+{
+    .name = "hwtimer-rockchip",
+    .ids = rk_timer_ofw_ids,
+
+    .probe = rk_timer_probe,
+};
+
+static int rk_timer_drv_register(void)
+{
+    rt_platform_driver_register(&rk_timer_driver);
+
+    return 0;
+}
+INIT_DRIVER_EARLY_EXPORT(rk_timer_drv_register);

+ 5 - 0
bsp/rockchip/rk3500/driver/reset/Kconfig

@@ -0,0 +1,5 @@
+config RT_USING_RESET
+    bool "Using Reset Controller support"
+    depends on RT_USING_DM
+    select RT_USING_OFW
+    default n

+ 13 - 0
bsp/rockchip/rk3500/driver/reset/SConscript

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

+ 429 - 0
bsp/rockchip/rk3500/driver/reset/reset.c

@@ -0,0 +1,429 @@
+/*
+ * Copyright (c) 2006-2024 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 <rtservice.h>
+
+#define DBG_TAG "rtdm.reset"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+
+#include <drivers/ofw.h>
+#include "reset.h"
+
+struct reset_control_array
+{
+    struct rt_reset_control captain;
+
+    rt_size_t count;
+    struct rt_reset_control *rstcs[];
+};
+
+#define reset_control_to_array(rstc) rt_container_of(rstc, struct reset_control_array, captain)
+
+static struct rt_spinlock _rstcer_lock = { 0 };
+static rt_list_t _rstcer_nodes = RT_LIST_OBJECT_INIT(_rstcer_nodes);
+
+rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer)
+{
+    rt_ubase_t level;
+
+    if (!rstcer)
+    {
+        return -RT_EINVAL;
+    }
+
+    rt_list_init(&rstcer->list);
+    rt_list_init(&rstcer->rstc_nodes);
+    rt_spin_lock_init(&rstcer->spinlock);
+
+    level = rt_spin_lock_irqsave(&_rstcer_lock);
+
+    rt_list_insert_after(&_rstcer_nodes, &rstcer->list);
+
+    rt_spin_unlock_irqrestore(&_rstcer_lock, level);
+
+    if (rstcer->ofw_node)
+    {
+        if (!rt_ofw_data(rstcer->ofw_node))
+        {
+            rt_ofw_data(rstcer->ofw_node) = rstcer;
+        }
+    }
+
+    return RT_EOK;
+}
+
+rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer)
+{
+    if (rstcer)
+    {
+        rt_spin_lock(&_rstcer_lock);
+
+        rt_list_remove(&rstcer->list);
+
+        rt_spin_unlock(&_rstcer_lock);
+
+        return RT_EOK;
+    }
+
+    return -RT_EINVAL;
+}
+
+rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc)
+{
+    rt_err_t err;
+
+    if (!rstc)
+    {
+        return -RT_EINVAL;
+    }
+
+    if (rstc->rstcer->ops->reset)
+    {
+        if ((err = rstc->rstcer->ops->reset(rstc)))
+        {
+            return err;
+        }
+    }
+
+    if (rstc->is_array)
+    {
+        struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
+
+        for (int i = 0; i < rstc_arr->count; ++i)
+        {
+            if ((err = rt_reset_control_reset(rstc_arr->rstcs[i])))
+            {
+                return err;
+            }
+        }
+    }
+
+    return RT_EOK;
+}
+
+rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc)
+{
+    rt_err_t err;
+
+    if (!rstc)
+    {
+        return -RT_EINVAL;
+    }
+
+    if (rstc->deassert && rstc->rstcer->ops->assert)
+    {
+        if ((err = rstc->rstcer->ops->assert(rstc)))
+        {
+            return err;
+        }
+
+        rstc->deassert = RT_FALSE;
+    }
+
+    if (rstc->is_array)
+    {
+        struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
+
+        for (int i = 0; i < rstc_arr->count; ++i)
+        {
+            if ((err = rt_reset_control_assert(rstc_arr->rstcs[i])))
+            {
+                if (rstc->rstcer->ops->deassert)
+                {
+                    rstc->rstcer->ops->deassert(rstc);
+
+                    rstc->deassert = RT_TRUE;
+                }
+
+                while (i --> 0)
+                {
+                    rt_reset_control_deassert(rstc_arr->rstcs[i]);
+                }
+
+                return err;
+            }
+        }
+    }
+
+    return RT_EOK;
+}
+
+rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc)
+{
+    rt_err_t err;
+
+    if (!rstc)
+    {
+        return -RT_EINVAL;
+    }
+
+    if (!rstc->deassert && rstc->rstcer->ops->deassert)
+    {
+        if ((err = rstc->rstcer->ops->deassert(rstc)))
+        {
+            return err;
+        }
+
+        rstc->deassert = RT_TRUE;
+    }
+
+    if (rstc->is_array)
+    {
+        struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
+
+        for (int i = 0; i < rstc_arr->count; ++i)
+        {
+            if ((err = rt_reset_control_deassert(rstc_arr->rstcs[i])))
+            {
+                if (rstc->rstcer->ops->assert)
+                {
+                    rstc->rstcer->ops->assert(rstc);
+
+                    rstc->deassert = RT_FALSE;
+                }
+
+                while (i --> 0)
+                {
+                    rt_reset_control_assert(rstc_arr->rstcs[i]);
+                }
+
+                return err;
+            }
+        }
+    }
+
+    return RT_EOK;
+}
+
+int rt_reset_control_status(struct rt_reset_control *rstc)
+{
+    if (!rstc)
+    {
+        return -RT_EINVAL;
+    }
+
+    if (rstc->rstcer->ops->status)
+    {
+        return rstc->rstcer->ops->status(rstc);
+    }
+
+    return -RT_ENOSYS;
+}
+
+static void reset_free(struct rt_reset_control *rstc)
+{
+    if (rstc->is_array)
+    {
+        struct reset_control_array *rstc_arr = reset_control_to_array(rstc);
+
+        for (int i = 0; i < rstc_arr->count; ++i)
+        {
+            rt_reset_control_put(rstc_arr->rstcs[i]);
+        }
+    }
+
+    rt_free(rstc);
+}
+
+struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev)
+{
+    return rt_ofw_get_reset_control_array(dev->ofw_node);
+}
+
+struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index)
+{
+    return rt_ofw_get_reset_control_by_index(dev->ofw_node, index);
+}
+
+struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name)
+{
+    return rt_ofw_get_reset_control_by_name(dev->ofw_node, name);
+}
+
+void rt_reset_control_put(struct rt_reset_control *rstc)
+{
+    struct rt_reset_controller *rstcer;
+
+    if (!rstc)
+    {
+        return;
+    }
+
+    rstcer = rstc->rstcer;
+
+    rt_spin_lock(&rstcer->spinlock);
+
+    rt_list_remove(&rstc->list);
+
+    rt_spin_unlock(&rstcer->spinlock);
+
+    reset_free(rstc);
+}
+
+static struct rt_reset_control *ofw_get_reset_control(struct rt_ofw_node *np, int index,
+        const char *name, rt_bool_t is_array)
+{
+    struct rt_reset_control *rstc;
+    struct rt_ofw_cell_args reset_args = {};
+    struct rt_reset_controller *rstcer = RT_NULL;
+
+    if (is_array)
+    {
+        rt_size_t rstc_nr;
+        struct reset_control_array *rstc_arr;
+
+        rstc_nr = rt_ofw_count_phandle_cells(np, "resets", "#reset-cells");
+
+        if (!rstc_nr)
+        {
+            return RT_NULL;
+        }
+
+        rstc_arr = rt_calloc(1, sizeof(*rstc_arr) + sizeof(struct rt_reset_control *) * rstc_nr);
+
+        if (!rstc_arr)
+        {
+            LOG_E("No memory to create %s[%d] reset control",
+                    rt_ofw_node_full_name(np), index);
+
+            return RT_NULL;
+        }
+
+        rstc_arr->count = rstc_nr - 1;
+
+        for (int i = 0; i < rstc_arr->count; ++i)
+        {
+            rstc_arr->rstcs[i] = ofw_get_reset_control(np, i + 1, RT_NULL, RT_FALSE);
+
+            if (!rstc_arr->rstcs[i])
+            {
+                while (i --> 0)
+                {
+                    rt_reset_control_put(rstc_arr->rstcs[i]);
+                }
+
+                rt_free(rstc_arr);
+                rstc_arr = RT_NULL;
+
+                return RT_NULL;
+            }
+        }
+
+        rstc = &rstc_arr->captain;
+        rstc->is_array = RT_TRUE;
+    }
+    else
+    {
+        rstc = rt_calloc(1, sizeof(*rstc));
+
+        if (!rstc)
+        {
+            LOG_E("No memory to create %s[%d] reset control",
+                    rt_ofw_node_full_name(np), index);
+
+            return RT_NULL;
+        }
+    }
+
+    if (!rt_ofw_parse_phandle_cells(np, "resets", "#reset-cells", index, &reset_args))
+    {
+        void *rt_data = rt_ofw_data(reset_args.data);
+
+        if (rt_data)
+        {
+            /* check is clk */
+            if (rt_ofw_prop_read_bool(reset_args.data, "#clock-cells"))
+            {
+                struct rt_reset_controller_clk_node *rstcer_clk = rt_data;
+
+                rstcer = &rstcer_clk->rstcer;
+            }
+            else
+            {
+                rstcer = rt_data;
+            }
+        }
+
+        rt_ofw_node_put(reset_args.data);
+    }
+
+    if (!rstcer)
+    {
+        goto _fail;
+    }
+
+    if (!name && rt_ofw_prop_read_bool(np, "reset-names"))
+    {
+        rt_ofw_prop_read_string_index(np, "reset-names", index, &name);
+    }
+
+    rstc->con_id = name;
+    rstc->rstcer = rstcer;
+
+    if (rstcer->ops->ofw_parse)
+    {
+        rt_err_t err = rstcer->ops->ofw_parse(rstc, &reset_args);
+
+        if (err)
+        {
+            LOG_E("Parse %s reset control error = %s",
+                    rt_ofw_node_full_name(np), rt_strerror(err));
+
+            goto _fail;
+        }
+    }
+
+    rstc->id = reset_args.args[0];
+
+    rt_list_init(&rstc->list);
+
+    rt_spin_lock(&rstcer->spinlock);
+
+    rt_list_insert_after(&rstcer->rstc_nodes, &rstc->list);
+
+    rt_spin_unlock(&rstcer->spinlock);
+
+    return rstc;
+
+_fail:
+    if (rstc && !rstc->is_array)
+    {
+        rt_free(rstc);
+    }
+
+    return RT_NULL;
+}
+
+struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np)
+{
+    return ofw_get_reset_control(np, 0, RT_NULL, RT_TRUE);
+}
+
+struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index)
+{
+    return ofw_get_reset_control(np, index, RT_NULL, RT_FALSE);
+}
+
+struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name)
+{
+    if (np)
+    {
+        int index = rt_ofw_prop_index_of_string(np, "reset-names", name);
+
+        if (index >= 0)
+        {
+            return ofw_get_reset_control(np, index, name, RT_FALSE);
+        }
+    }
+
+    return RT_NULL;
+}

+ 92 - 0
bsp/rockchip/rk3500/driver/reset/reset.h

@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-26     GuEe-GUI     first version
+ */
+
+#ifndef __RESET_H__
+#define __RESET_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <drivers/ofw.h>
+#include <drivers/clk.h>
+
+struct rt_reset_control_ops;
+
+struct rt_reset_controller
+{
+    rt_list_t list;
+    rt_list_t rstc_nodes;
+
+    const char *name;
+    const struct rt_reset_control_ops *ops;
+
+    struct rt_ofw_node *ofw_node;
+    void *priv;
+
+    struct rt_spinlock spinlock;
+};
+
+/*
+ * It seems that most reset controllers are coupled to CLK.
+ * So we need a generic extends object.
+ */
+struct rt_reset_controller_clk_node
+{
+    struct rt_clk_node parent;
+
+    struct rt_reset_controller rstcer;
+};
+
+struct rt_reset_control
+{
+    rt_list_t list;
+
+    struct rt_reset_controller *rstcer;
+
+    int id;
+    const char *con_id;
+    rt_bool_t is_array;
+    rt_bool_t deassert;
+
+    void *priv;
+};
+
+struct rt_reset_control_ops
+{
+    /*
+     * rt_ofw_cell_args return:
+     *  args[0] = rstc.id
+     */
+    rt_err_t    (*ofw_parse)(struct rt_reset_control *, struct rt_ofw_cell_args *args);
+    /* API */
+    rt_err_t    (*reset)(struct rt_reset_control *rstc);
+    rt_err_t    (*assert)(struct rt_reset_control *rstc);
+    rt_err_t    (*deassert)(struct rt_reset_control *rstc);
+    int         (*status)(struct rt_reset_control *rstc);
+};
+
+rt_err_t rt_reset_controller_register(struct rt_reset_controller *rstcer);
+rt_err_t rt_reset_controller_unregister(struct rt_reset_controller *rstcer);
+
+rt_err_t rt_reset_control_reset(struct rt_reset_control *rstc);
+rt_err_t rt_reset_control_assert(struct rt_reset_control *rstc);
+rt_err_t rt_reset_control_deassert(struct rt_reset_control *rstc);
+int rt_reset_control_status(struct rt_reset_control *rstc);
+
+rt_ssize_t rt_reset_control_get_count(struct rt_device *dev);
+struct rt_reset_control *rt_reset_control_get_array(struct rt_device *dev);
+struct rt_reset_control *rt_reset_control_get_by_index(struct rt_device *dev, int index);
+struct rt_reset_control *rt_reset_control_get_by_name(struct rt_device *dev, const char *name);
+void rt_reset_control_put(struct rt_reset_control *rstc);
+
+struct rt_reset_control *rt_ofw_get_reset_control_array(struct rt_ofw_node *np);
+struct rt_reset_control *rt_ofw_get_reset_control_by_index(struct rt_ofw_node *np, int index);
+struct rt_reset_control *rt_ofw_get_reset_control_by_name(struct rt_ofw_node *np, const char *name);
+
+#endif /* __RESET_H__ */

+ 22 - 0
bsp/rockchip/rk3500/driver/rockchip.h

@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2006-2024 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>
+
+#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))
+
+#endif /* __ROCKCHIP_H__ */

+ 341 - 0
bsp/rockchip/rk3500/driver/uart8250/8250-dw.c

@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-22     GuEe-GUI     first version
+ */
+
+/*
+ * The Synopsys DesignWare 8250 has an extra feature whereby it detects if the
+ * LCR is written whilst busy. If it is, then a busy detect interrupt is
+ * raised, the LCR needs to be rewritten and the uart status register read.
+ */
+
+#include <rtthread.h>
+
+#include "8250.h"
+
+/* Offsets for the DesignWare specific registers */
+#define DW_UART_USR         0x1f    /* UART Status Register */
+#define DW_UART_DMASA       0xa8    /* DMA Software Ack */
+
+#define OCTEON_UART_USR     0x27    /* UART Status Register */
+
+#define RZN1_UART_TDMACR    0x10c   /* DMA Control Register Transmit Mode */
+#define RZN1_UART_RDMACR    0x110   /* DMA Control Register Receive Mode */
+
+/* DesignWare specific register fields */
+#define DW_UART_MCR_SIRE    RT_BIT(6)
+
+/* Renesas specific register fields */
+#define RZN1_UART_xDMACR_DMA_EN         RT_BIT(0)
+#define RZN1_UART_xDMACR_1_WORD_BURST   (0 << 1)
+#define RZN1_UART_xDMACR_4_WORD_BURST   (1 << 1)
+#define RZN1_UART_xDMACR_8_WORD_BURST   (2 << 1)
+#define RZN1_UART_xDMACR_BLK_SZ(x)      ((x) << 3)
+
+/* Quirks */
+#define DW_UART_QUIRK_OCTEON            RT_BIT(0)
+#define DW_UART_QUIRK_ARMADA_38X        RT_BIT(1)
+#define DW_UART_QUIRK_SKIP_SET_RATE     RT_BIT(2)
+#define DW_UART_QUIRK_IS_DMA_FC         RT_BIT(3)
+
+struct dw8250_platform_data
+{
+    rt_uint8_t usr_reg;
+    rt_uint32_t cpr_val;
+    rt_uint32_t quirks;
+};
+
+struct dw8250
+{
+    struct serial8250 parent;
+    struct rt_spinlock spinlock;
+
+    struct rt_clk *pclk;
+
+    rt_bool_t uart_16550_compatible;
+    struct dw8250_platform_data *platform_data;
+};
+
+#define to_dw8250(serial8250) rt_container_of(serial8250, struct dw8250, parent)
+
+static void dw8250_check_lcr(struct serial8250 *serial, int value)
+{
+    void *offset = (void *)(serial->base + (UART_LCR << serial->regshift));
+    int tries = 1000;
+
+    /* Make sure LCR write wasn't ignored */
+    while (tries--)
+    {
+        rt_uint32_t lcr = serial->serial_in(serial, UART_LCR);
+
+        if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR))
+        {
+            break;
+        }
+
+        serial->serial_out(serial, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+        serial->serial_in(serial, UART_RX);
+
+        if (serial->iotype == PORT_MMIO32)
+        {
+            HWREG32(offset) = value;
+        }
+        else if (serial->iotype == PORT_MMIO32BE)
+        {
+            HWREG32(offset) = rt_cpu_to_be32(value);
+        }
+        else
+        {
+            HWREG8(offset) = value;
+        }
+    }
+}
+
+static void dw8250_serial_out32(struct serial8250 *serial, int offset, int value)
+{
+    struct dw8250 *dw8250 = to_dw8250(serial);
+
+    HWREG32(serial->base + (offset << serial->regshift)) = value;
+
+    if (offset == UART_LCR && !dw8250->uart_16550_compatible)
+    {
+        dw8250_check_lcr(serial, value);
+    }
+}
+
+static rt_uint32_t dw8250_serial_in32(struct serial8250 *serial, int offset)
+{
+    return HWREG32(serial->base + (offset << serial->regshift));
+}
+
+static rt_err_t dw8250_isr(struct serial8250 *serial, int irq)
+{
+    unsigned int iir, status;
+    struct dw8250 *dw8250 = to_dw8250(serial);
+
+    iir = serial8250_in(serial, UART_IIR);
+
+    /*
+     * If don't do this in non-DMA mode then the "RX TIMEOUT" interrupt will
+     * fire forever.
+     */
+    if ((iir & 0x3f) == UART_IIR_RX_TIMEOUT)
+    {
+        rt_base_t level = rt_spin_lock_irqsave(&dw8250->spinlock);
+
+        status = serial8250_in(serial, UART_LSR);
+
+        if (!(status & (UART_LSR_DR | UART_LSR_BI)))
+        {
+            serial8250_in(serial, UART_RX);
+        }
+
+        rt_spin_unlock_irqrestore(&dw8250->spinlock, level);
+    }
+
+    if (!(iir & UART_IIR_NO_INT))
+    {
+        rt_hw_serial_isr(&serial->parent, RT_SERIAL_EVENT_RX_IND);
+    }
+
+    if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY)
+    {
+        /* Clear the USR */
+        serial8250_in(serial, dw8250->platform_data->usr_reg);
+    }
+
+    return RT_EOK;
+}
+
+static void dw8250_free_resource(struct dw8250 *dw8250)
+{
+    struct serial8250 *serial = &dw8250->parent;
+
+    if (serial->base)
+    {
+        rt_iounmap(serial->base);
+    }
+
+    if (serial->clk)
+    {
+        rt_clk_disable_unprepare(serial->clk);
+        rt_clk_put(serial->clk);
+    }
+
+    if (dw8250->pclk)
+    {
+        rt_clk_disable_unprepare(dw8250->pclk);
+        rt_clk_put(dw8250->pclk);
+    }
+
+    rt_free(dw8250);
+}
+
+static void dw8250_remove(struct serial8250 *serial)
+{
+    struct dw8250 *dw8250 = to_dw8250(serial);
+
+    dw8250_free_resource(dw8250);
+}
+
+static rt_err_t dw8250_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err;
+    rt_uint32_t val;
+    struct serial8250 *serial;
+    struct rt_device *dev = &pdev->parent;
+    struct dw8250 *dw8250 = serial8250_alloc(dw8250);
+    struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
+
+    if (!dw8250)
+    {
+        return -RT_ENOMEM;
+    }
+
+    serial = &dw8250->parent;
+    serial->base = rt_dm_dev_iomap(dev, 0);
+
+    if (!serial->base)
+    {
+        err = -RT_EIO;
+
+        goto _free_res;
+    }
+
+    serial->irq = rt_dm_dev_get_irq(dev, 0);
+
+    if (serial->irq < 0)
+    {
+        err = serial->irq;
+
+        goto _free_res;
+    }
+
+    serial->clk = rt_clk_get_by_name(dev, "baudclk");
+    dw8250->pclk = rt_clk_get_by_name(dev, "apb_pclk");
+
+    if (!serial->clk)
+    {
+        if ((err = rt_dm_dev_prop_read_u32(dev, "clock-frequency", &serial->freq)))
+        {
+            goto _free_res;
+        }
+    }
+    else
+    {
+        if ((err = rt_clk_prepare_enable(serial->clk)))
+        {
+            goto _free_res;
+        }
+
+        serial->freq = rt_clk_get_rate(serial->clk);
+    }
+
+    if (!dw8250->pclk)
+    {
+        err = -RT_EIO;
+
+        goto _free_res;
+    }
+
+    if ((err = rt_clk_prepare_enable(dw8250->pclk)))
+    {
+        goto _free_res;
+    }
+
+    rt_dm_dev_prop_read_u32(dev, "reg-shift", &serial->regshift);
+
+    if (!rt_dm_dev_prop_read_u32(dev, "reg-io-width", &val) && val == 4)
+    {
+        serial->iotype = PORT_MMIO32;
+        serial->serial_in = &dw8250_serial_in32;
+        serial->serial_out = &dw8250_serial_out32;
+    }
+
+    dw8250->uart_16550_compatible = rt_dm_dev_prop_read_bool(dev, "snps,uart-16550-compatible");
+    dw8250->platform_data = (struct dw8250_platform_data *)pdev->id->data;
+
+    rt_dm_dev_bind_fwdata(&serial->parent.parent, pdev->parent.ofw_node, &serial->parent);
+
+    serial = &dw8250->parent;
+    serial->parent.ops = &serial8250_uart_ops;
+    serial->parent.config = config;
+    serial->handle_irq = &dw8250_isr;
+    serial->remove = &dw8250_remove;
+    serial->data = dw8250;
+
+    rt_spin_lock_init(&dw8250->spinlock);
+
+    if ((err = serial8250_setup(serial)))
+    {
+        goto _free_res;
+    }
+
+    return RT_EOK;
+
+_free_res:
+    dw8250_free_resource(dw8250);
+
+    return err;
+}
+
+static const struct dw8250_platform_data dw8250_dw_apb =
+{
+    .usr_reg = DW_UART_USR,
+};
+
+static const struct dw8250_platform_data dw8250_octeon_3860_data =
+{
+    .usr_reg = OCTEON_UART_USR,
+    .quirks = DW_UART_QUIRK_OCTEON,
+};
+
+static const struct dw8250_platform_data dw8250_armada_38x_data =
+{
+    .usr_reg = DW_UART_USR,
+    .quirks = DW_UART_QUIRK_ARMADA_38X,
+};
+
+static const struct dw8250_platform_data dw8250_renesas_rzn1_data =
+{
+    .usr_reg = DW_UART_USR,
+    .cpr_val = 0x00012f32,
+    .quirks = DW_UART_QUIRK_IS_DMA_FC,
+};
+
+static const struct dw8250_platform_data dw8250_starfive_jh7100_data =
+{
+    .usr_reg = DW_UART_USR,
+    .quirks = DW_UART_QUIRK_SKIP_SET_RATE,
+};
+
+static const struct rt_ofw_node_id dw8250_ofw_ids[] =
+{
+    { .type = "ttyS", .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
+    { .type = "ttyS", .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
+    { .type = "ttyS", .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
+    { .type = "ttyS", .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
+    { .type = "ttyS", .compatible = "starfive,jh7100-uart", .data = &dw8250_starfive_jh7100_data },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver dw8250_driver =
+{
+    .name = "dw-apb-uart",
+    .ids = dw8250_ofw_ids,
+
+    .probe = dw8250_probe,
+};
+
+static int dw8250_drv_register(void)
+{
+    rt_platform_driver_register(&dw8250_driver);
+
+    return 0;
+}
+INIT_DRIVER_EARLY_EXPORT(dw8250_drv_register);

+ 74 - 0
bsp/rockchip/rk3500/driver/uart8250/8250.h

@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-16     GuEe-GUI     first version
+ */
+
+#ifndef __SERIAL_8250_H__
+#define __SERIAL_8250_H__
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <ioremap.h>
+#include "regs.h"
+#include "serial_dm.h"
+
+enum
+{
+    PORT_IO,
+    PORT_MMIO,
+    PORT_MMIO16,
+    PORT_MMIO32,
+    PORT_MMIO32BE,
+};
+
+struct serial8250
+{
+    struct rt_serial_device parent;
+    struct rt_clk *clk;
+
+    int irq;
+    void *base;
+    rt_size_t size;
+    rt_uint32_t freq;       /* frequency */
+    rt_uint32_t regshift;   /* reg offset shift */
+    rt_uint8_t iotype;      /* io access style */
+
+    struct rt_spinlock spinlock;
+
+    rt_uint32_t (*serial_in)(struct serial8250 *, int offset);
+    void (*serial_out)(struct serial8250 *, int offset, int value);
+    rt_err_t (*handle_irq)(struct serial8250 *, int irq);
+
+    /* Free all resource (and parent) by child */
+    void (*remove)(struct serial8250 *);
+    void *data;
+};
+
+#define serial8250_alloc(obj) rt_calloc(1, sizeof(typeof(*obj)))
+#define raw_to_serial8250(raw_serial) rt_container_of(raw_serial, struct serial8250, parent)
+
+rt_err_t serial8250_config(struct serial8250 *serial, const char *options);
+rt_err_t serial8250_setup(struct serial8250 *serial);
+rt_err_t serial8250_remove(struct serial8250 *serial);
+
+rt_uint32_t serial8250_in(struct serial8250 *serial, int offset);
+void serial8250_out(struct serial8250 *serial, int offset, int value);
+
+rt_err_t serial8250_uart_configure(struct rt_serial_device *raw_serial, struct serial_configure *cfg);
+rt_err_t serial8250_uart_control(struct rt_serial_device *raw_serial, int cmd, void *arg);
+int serial8250_uart_putc(struct rt_serial_device *raw_serial, char c);
+int serial8250_uart_getc(struct rt_serial_device *raw_serial);
+
+int serial8250_early_putc(struct rt_serial_device *raw_serial, char c);
+rt_err_t serial8250_early_fdt_setup(struct serial8250 *serial, struct rt_fdt_earlycon *con, const char *options);
+
+extern struct serial8250 early_serial8250;
+extern const struct rt_uart_ops serial8250_uart_ops;
+
+#endif /* __SERIAL_8250_H__ */

+ 3 - 0
bsp/rockchip/rk3500/driver/uart8250/Kconfig

@@ -0,0 +1,3 @@
+config RT_SERIAL_8250
+    bool "8250 Serila Family"
+    default n

+ 13 - 0
bsp/rockchip/rk3500/driver/uart8250/SConscript

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

+ 303 - 0
bsp/rockchip/rk3500/driver/uart8250/core.c

@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-16     GuEe-GUI     first version
+ */
+
+#include "8250.h"
+
+rt_err_t serial8250_config(struct serial8250 *serial, const char *options)
+{
+    rt_err_t ret = -RT_EINVAL;
+
+    if (serial)
+    {
+        char *arg;
+        rt_bool_t has_iotype = RT_FALSE;
+
+        /*
+         *  uart8250,io,<addr>[,options]
+         *  uart8250,mmio,<addr>[,options]
+         *  uart8250,mmio16,<addr>[,options]
+         *  uart8250,mmio32,<addr>[,options]
+         *  uart8250,mmio32be,<addr>[,options]
+         *  uart8250,0x<addr>[,options]
+         */
+        serial_for_each_args(arg, options)
+        {
+            if (!rt_strcmp(arg, "uart8250"))
+            {
+                ret = RT_EOK;
+                continue;
+            }
+            /* user call error */
+            if (ret)
+            {
+                break;
+            }
+            if (!rt_strncmp(arg, "0x", 2))
+            {
+                serial->base = serial_base_from_args(arg);
+                continue;
+            }
+            if (!has_iotype)
+            {
+                const struct
+                {
+                    char *param;
+                    int type;
+                } iotype_table[] =
+                {
+                    { "io", PORT_IO },
+                    { "mmio", PORT_MMIO },
+                    { "mmio16", PORT_MMIO16 },
+                    { "mmio32", PORT_MMIO32 },
+                    { "mmio32be", PORT_MMIO32BE },
+                };
+
+                serial->iotype = PORT_MMIO32;
+
+                for (int i = 0; i < RT_ARRAY_SIZE(iotype_table); ++i)
+                {
+                    if (!rt_strcmp(arg, iotype_table[i].param))
+                    {
+                        serial->iotype = iotype_table[i].type;
+                        break;
+                    }
+                }
+
+                has_iotype = RT_TRUE;
+                continue;
+            }
+
+            serial->parent.config = serial_cfg_from_args(arg);
+        }
+
+        if (!serial->size)
+        {
+            serial->size = 0x1000;
+        }
+    }
+
+    return ret;
+}
+
+static void serial8250_isr(int irqno, void *param)
+{
+    struct serial8250 *serial = (struct serial8250 *)param;
+
+    if (serial->handle_irq)
+    {
+        serial->handle_irq(serial, irqno);
+    }
+    else
+    {
+        rt_hw_serial_isr(&serial->parent, RT_SERIAL_EVENT_RX_IND);
+    }
+}
+
+rt_err_t serial8250_setup(struct serial8250 *serial)
+{
+    rt_err_t ret = RT_EOK;
+    const char *uart_name;
+    char dev_name[RT_NAME_MAX];
+
+    if (serial)
+    {
+        rt_spin_lock_init(&serial->spinlock);
+
+        serial->serial_in = serial->serial_in ? : &serial8250_in;
+        serial->serial_out = serial->serial_out ? : &serial8250_out;
+
+        serial_dev_set_name(&serial->parent);
+        uart_name = rt_dm_dev_get_name(&serial->parent.parent);
+
+        rt_hw_serial_register(&serial->parent, uart_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, serial->data);
+
+        rt_snprintf(dev_name, sizeof(dev_name), "%s-8250", uart_name);
+        rt_pic_attach_irq(serial->irq, serial8250_isr, serial, dev_name, RT_IRQ_F_NONE);
+    }
+    else
+    {
+        ret = -RT_EINVAL;
+    }
+
+    return ret;
+}
+
+rt_err_t serial8250_remove(struct serial8250 *serial)
+{
+    rt_err_t err;
+
+    rt_iounmap((void *)serial->base);
+    serial->base = RT_NULL;
+
+    rt_pic_irq_mask(serial->irq);
+    rt_pic_detach_irq(serial->irq, serial);
+
+    err = rt_device_unregister(&serial->parent.parent);
+
+    if (!err && serial->remove)
+    {
+        serial->remove(serial);
+    }
+
+    return err;
+}
+
+rt_uint32_t serial8250_in(struct serial8250 *serial, int offset)
+{
+    rt_uint32_t ret = 0;
+    offset <<= serial->regshift;
+
+    switch (serial->iotype)
+    {
+    case PORT_MMIO:
+        ret = HWREG8(serial->base + offset);
+        break;
+    case PORT_MMIO16:
+        ret = HWREG16(serial->base + offset);
+        break;
+    case PORT_MMIO32:
+        ret = HWREG32(serial->base + offset);
+        break;
+    case PORT_MMIO32BE:
+        ret = rt_cpu_to_be32(HWREG32(serial->base + offset));
+        break;
+#ifdef ARCH_SUPPORT_PIO
+    case PORT_IO:
+        ret = inb(serial->base + offset, value);
+        break;
+#endif
+    default:
+        break;
+    }
+
+    return ret;
+}
+
+void serial8250_out(struct serial8250 *serial, int offset, int value)
+{
+    offset <<= serial->regshift;
+
+    switch (serial->iotype)
+    {
+    case PORT_MMIO:
+        HWREG8(serial->base + offset) = value;
+        break;
+    case PORT_MMIO16:
+        HWREG16(serial->base + offset) = value;
+        break;
+    case PORT_MMIO32:
+        HWREG32(serial->base + offset) = value;
+        break;
+    case PORT_MMIO32BE:
+        HWREG32(serial->base + offset) = rt_cpu_to_be32(value);
+        break;
+#ifdef ARCH_SUPPORT_PIO
+    case PORT_IO:
+        outb(serial->base + offset, value);
+        break;
+#endif
+    default:
+        break;
+    }
+}
+
+rt_err_t serial8250_uart_configure(struct rt_serial_device *raw_serial, struct serial_configure *cfg)
+{
+    rt_err_t err = RT_EOK;
+    struct serial8250 *serial = raw_to_serial8250(raw_serial);
+
+    /* Disable interrupt */
+    serial->serial_out(serial, UART_IER, !UART_IER_RDI);
+
+    /* Enable FIFO, Clear FIFO*/
+    serial->serial_out(serial, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
+
+    /* DTR + RTS */
+    serial->serial_out(serial, UART_MCR, UART_MCR_DTR | UART_MCR_RTS);
+
+    if (serial->freq)
+    {
+        rt_uint32_t wlen = cfg->data_bits - DATA_BITS_5 + UART_LCR_WLEN5;
+        rt_uint32_t divisor = serial->freq / 16 / cfg->baud_rate;
+
+        /* Enable access DLL & DLH */
+        serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) | UART_LCR_DLAB);
+        serial->serial_out(serial, UART_DLL, (divisor & 0xff));
+        serial->serial_out(serial, UART_DLM, (divisor >> 8) & 0xff);
+        /* Clear DLAB bit */
+        serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) & (~UART_LCR_DLAB));
+
+        serial->serial_out(serial, UART_LCR, (serial->serial_in(serial, UART_LCR) & (~wlen)) | wlen);
+        serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) & (~UART_LCR_STOP));
+        serial->serial_out(serial, UART_LCR, serial->serial_in(serial, UART_LCR) & (~UART_LCR_PARITY));
+    }
+
+    serial->serial_out(serial, UART_IER, UART_IER_RDI);
+
+    return err;
+}
+
+rt_err_t serial8250_uart_control(struct rt_serial_device *raw_serial, int cmd, void *arg)
+{
+    rt_err_t err = RT_EOK;
+    struct serial8250 *serial = raw_to_serial8250(raw_serial);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+        /* disable rx irq */
+        serial->serial_out(serial, UART_IER, !UART_IER_RDI);
+        rt_pic_irq_mask(serial->irq);
+        break;
+
+    case RT_DEVICE_CTRL_SET_INT:
+        /* enable rx irq */
+        serial->serial_out(serial, UART_IER, UART_IER_RDI);
+        rt_pic_irq_unmask(serial->irq);
+        break;
+    }
+
+    return err;
+}
+
+int serial8250_uart_putc(struct rt_serial_device *raw_serial, char c)
+{
+    struct serial8250 *serial = raw_to_serial8250(raw_serial);
+
+    while (!(serial->serial_in(serial, UART_LSR) & 0x20))
+    {
+        rt_hw_cpu_relax();
+    }
+
+    serial->serial_out(serial, UART_TX, c);
+
+    return 1;
+}
+
+int serial8250_uart_getc(struct rt_serial_device *raw_serial)
+{
+    int ch = -1;
+    struct serial8250 *serial = raw_to_serial8250(raw_serial);
+
+    if ((serial->serial_in(serial, UART_LSR) & 0x1))
+    {
+        ch = serial->serial_in(serial, UART_RX) & 0xff;
+    }
+
+    return ch;
+}
+
+const struct rt_uart_ops serial8250_uart_ops =
+{
+    .configure = serial8250_uart_configure,
+    .control = serial8250_uart_control,
+    .putc = serial8250_uart_putc,
+    .getc = serial8250_uart_getc,
+};

+ 162 - 0
bsp/rockchip/rk3500/driver/uart8250/early.c

@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-16     GuEe-GUI     first version
+ */
+
+#include "8250.h"
+
+struct serial8250 early_serial8250 = { 0 };
+
+static rt_uint32_t serial8250_early_in(struct serial8250 *serial, int offset)
+{
+    return serial8250_in(serial, offset);
+}
+
+static void serial8250_early_out(struct serial8250 *serial, int offset, int value)
+{
+    serial8250_out(serial, offset, value);
+}
+
+int serial8250_early_putc(struct rt_serial_device *raw_serial, char c)
+{
+    if (raw_serial)
+    {
+        /* FIFO and shifting register empty */
+        const int uart_lsr_both_empty = (UART_LSR_TEMT | UART_LSR_THRE);
+        struct serial8250 *serial = rt_container_of(raw_serial, struct serial8250, parent);
+
+        serial8250_early_out(serial, UART_TX, c);
+
+        while ((serial8250_early_in(serial, UART_LSR) & uart_lsr_both_empty) != uart_lsr_both_empty)
+        {
+            rt_hw_cpu_relax();
+        }
+    }
+
+    return 1;
+}
+
+static void init_serial(struct serial8250 *serial)
+{
+    unsigned char c;
+    rt_uint32_t ier, divisor;
+
+    serial8250_early_out(serial, UART_LCR, 0x3);    /* 8n1 */
+    ier = serial8250_early_in(serial, UART_IER);
+    serial8250_early_out(serial, UART_IER, ier & UART_IER_UUE); /* no interrupt */
+    serial8250_early_out(serial, UART_FCR, 0);      /* no fifo */
+    serial8250_early_out(serial, UART_MCR, 0x3);    /* DTR + RTS */
+
+    if (serial->freq)
+    {
+        divisor = RT_DIV_ROUND_CLOSEST(serial->freq, 16 * serial->parent.config.baud_rate);
+        c = serial8250_early_in(serial, UART_LCR);
+        serial8250_early_out(serial, UART_LCR, c | UART_LCR_DLAB);
+        serial8250_early_out(serial, UART_DLL, divisor & 0xff);
+        serial8250_early_out(serial, UART_DLM, (divisor >> 8) & 0xff);
+        serial8250_early_out(serial, UART_LCR, c & ~UART_LCR_DLAB);
+    }
+}
+
+static void serial8250_early_kick(struct rt_fdt_earlycon *con, int why)
+{
+    struct serial8250 *serial = raw_to_serial8250(con->data);
+
+    switch (why)
+    {
+    case FDT_EARLYCON_KICK_UPDATE:
+        serial->base = rt_ioremap((void *)con->mmio, con->size);
+        break;
+
+    case FDT_EARLYCON_KICK_COMPLETED:
+        rt_iounmap(serial->base);
+        break;
+
+    default:
+        break;
+    }
+}
+
+rt_err_t serial8250_early_fdt_setup(struct serial8250 *serial, struct rt_fdt_earlycon *con, const char *options)
+{
+    rt_err_t ret = RT_EOK;
+
+    if (!serial->base && con)
+    {
+        serial8250_config(serial, options);
+        con->mmio = (rt_ubase_t)serial->base;
+        con->size = serial->size;
+    }
+
+    if (serial->base && con)
+    {
+        serial->base = rt_ioremap_early((void *)serial->base, serial->size);
+    }
+
+    if (serial->base && con)
+    {
+        con->console_putc = (typeof(con->console_putc))&serial8250_early_putc;
+        con->console_kick = serial8250_early_kick;
+        con->data = &serial->parent;
+
+        if (!serial->parent.config.baud_rate)
+        {
+            /* assume the device was initialized, only mask interrupts */
+            rt_uint32_t ier = serial8250_early_in(serial, UART_IER);
+            serial8250_early_out(serial, UART_IER, ier & UART_IER_UUE);
+        }
+        else
+        {
+            init_serial(serial);
+        }
+    }
+    else
+    {
+        ret = -RT_ERROR;
+    }
+
+    return ret;
+}
+
+static void common_init(struct serial8250 *serial, struct rt_fdt_earlycon *con)
+{
+    serial->base = (void *)con->mmio;
+    serial->size = con->size;
+    serial->iotype = PORT_MMIO32;
+}
+
+static rt_err_t common_early_setup(struct rt_fdt_earlycon *con, const char *options)
+{
+    struct serial8250 *serial = &early_serial8250;
+
+    common_init(serial, con);
+    serial->regshift = 2;
+    fdt_getprop_u32(con->fdt, con->nodeoffset, "reg-shift", &serial->regshift, RT_NULL);
+
+    return serial8250_early_fdt_setup(serial, con, options);
+}
+RT_FDT_EARLYCON_EXPORT(bcm2835aux, "uart8250", "brcm,bcm2835-aux-uart", common_early_setup);
+RT_FDT_EARLYCON_EXPORT(tegra20, "uart8250", "nvidia,tegra20-uart", common_early_setup);
+RT_FDT_EARLYCON_EXPORT(dw8250, "uart8250", "snps,dw-apb-uart", common_early_setup);
+RT_FDT_EARLYCON_EXPORT(ns16550a, "uart8250", "ns16550a", common_early_setup);
+RT_FDT_EARLYCON_EXPORT(ns16550, "uart8250", "ns16550", common_early_setup);
+
+#ifdef RT_USING_8250_OMAP
+static rt_err_t omap8250_early_setup(struct rt_fdt_earlycon *con, const char *options)
+{
+    struct serial8250 *serial = &early_serial8250;
+
+    common_init(serial, con);
+    serial->regshift = 2;
+
+    return serial8250_early_fdt_setup(serial, con, options);
+}
+RT_FDT_EARLYCON_EXPORT(omap8250, "uart8250", "ti,omap2-uart", omap8250_early_setup);
+RT_FDT_EARLYCON_EXPORT(omap8250, "uart8250", "ti,omap3-uart", omap8250_early_setup);
+RT_FDT_EARLYCON_EXPORT(omap8250, "uart8250", "ti,omap4-uart", omap8250_early_setup);
+#endif /* RT_USING_8250_OMAP */

+ 378 - 0
bsp/rockchip/rk3500/driver/uart8250/fiq-debugger.c

@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-21     GuEe-GUI     first version
+ */
+
+#include <rthw.h>
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <ioremap.h>
+#include <cpuport.h>
+
+#include "regs.h"
+#include "serial_dm.h"
+
+#define UART_USR                    0x1f /* In: UART Status Register */
+#define UART_USR_RX_FIFO_FULL       0x10 /* Receive FIFO full */
+#define UART_USR_RX_FIFO_NOT_EMPTY  0x08 /* Receive FIFO not empty */
+#define UART_USR_TX_FIFO_EMPTY      0x04 /* Transmit FIFO empty */
+#define UART_USR_TX_FIFO_NOT_FULL   0x02 /* Transmit FIFO not full */
+#define UART_USR_BUSY               0x01 /* UART busy indicator */
+#define UART_SRR                    0x22 /* software reset register */
+
+#define FIQ_DEBUGGER_NO_CHAR        -1
+#define FIQ_DEBUGGER_BREAK          -2
+
+struct rockchip_fiq_debugger
+{
+    struct rt_serial_device parent;
+
+    int irq;
+    int baudrate;
+    void *debug_port_base;
+    rt_bool_t break_seen;
+};
+
+#define raw_to_fiq_debugger(raw) rt_container_of(raw, struct rockchip_fiq_debugger, parent)
+
+rt_inline void rockchip_fiq_write(struct rockchip_fiq_debugger *t, rt_uint32_t val, int off)
+{
+    HWREG32(t->debug_port_base + off * 4) = val;
+}
+
+rt_inline rt_uint32_t rockchip_fiq_read(struct rockchip_fiq_debugger *t, int off)
+{
+    return HWREG32(t->debug_port_base + off * 4);
+}
+
+rt_inline rt_uint32_t rockchip_fiq_read_lsr(struct rockchip_fiq_debugger *t)
+{
+    rt_uint32_t ret = rockchip_fiq_read(t, UART_LSR);
+
+    if (ret & UART_LSR_BI)
+    {
+        t->break_seen = true;
+    }
+
+    return ret;
+}
+
+static void fiq_debugger_isr(int irqno, void *param)
+{
+    rt_uint32_t usr;
+    struct rt_serial_device *serial = (struct rt_serial_device*)param;
+    struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
+
+    usr = rockchip_fiq_read(t, UART_USR);
+
+    if ((usr & UART_USR_RX_FIFO_NOT_EMPTY) == UART_USR_RX_FIFO_NOT_EMPTY)
+    {
+        rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
+    }
+
+    if ((usr & UART_USR_BUSY) == UART_USR_BUSY)
+    {
+        /* Clear the USR */
+        (void)rockchip_fiq_read(t, UART_USR);
+    }
+}
+
+static rt_err_t fiq_debugger_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
+{
+    int dll = 0, dlm = 0;
+    rt_uint32_t count = 10000;
+    struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
+
+    if (rockchip_fiq_read(t, UART_LSR) & UART_LSR_DR)
+    {
+        (void)rockchip_fiq_read(t, UART_RX);
+    }
+
+    while (!(rockchip_fiq_read(t, UART_LSR) & UART_LSR_TEMT) && count--)
+    {
+        rt_hw_us_delay(10);
+    }
+
+    switch (t->baudrate)
+    {
+    case 1500000:
+        dll = 0x1;
+        break;
+    case 115200:
+    default:
+        dll = 0xd;
+        break;
+    }
+    /* reset uart */
+    rockchip_fiq_write(t, (1 << 1) | (1 << 2), UART_SRR);
+    rt_hw_us_delay(10);
+    /* set uart to loop back mode */
+    rockchip_fiq_write(t, 0x10, UART_MCR);
+
+    rockchip_fiq_write(t, 0x83, UART_LCR);
+    /* set baud rate */
+    rockchip_fiq_write(t, dll, UART_DLL);
+    rockchip_fiq_write(t, dlm, UART_DLM);
+    rockchip_fiq_write(t, 0x03, UART_LCR);
+
+    /* enable rx interrupt */
+    rockchip_fiq_write(t, UART_IER_RDI, UART_IER);
+
+    /*
+     * interrupt on every character when received, but we can enable fifo for TX
+     * I found that if we enable the RX fifo, some problem may vanish such as
+     * when you continuously input characters in the command line the uart irq
+     * may be disable because of the uart irq is served when CPU is at IRQ
+     * exception, but it is found unregistered, so it is disable.
+     */
+    rockchip_fiq_write(t, 0x01, UART_FCR);
+
+    /* disbale loop back mode */
+    rockchip_fiq_write(t, 0x0, UART_MCR);
+
+    return RT_EOK;
+}
+
+static rt_err_t fiq_debugger_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
+{
+    struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
+
+    switch (cmd)
+    {
+    case RT_DEVICE_CTRL_CLR_INT:
+        rt_pic_irq_mask(t->irq);
+        break;
+
+    case RT_DEVICE_CTRL_SET_INT:
+        rt_pic_irq_unmask(t->irq);
+        break;
+    }
+
+    return RT_EOK;
+}
+
+static int fiq_debugger_uart_putc(struct rt_serial_device *serial, char c)
+{
+    struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
+    rt_uint32_t count = 10000;
+
+    while (!(rockchip_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) && count--)
+    {
+        rt_hw_cpu_relax();
+    }
+
+    rockchip_fiq_write(t, c, UART_TX);
+
+    return 1;
+}
+
+static int fiq_debugger_uart_getc(struct rt_serial_device *serial)
+{
+    int ch = FIQ_DEBUGGER_NO_CHAR;
+    rt_uint32_t lsr, temp;
+    static rt_uint32_t n = 0;
+    static char buf[32] = {};
+    struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial);
+
+    /* Clear uart interrupt status */
+    rockchip_fiq_read(t, UART_USR);
+    lsr = rockchip_fiq_read_lsr(t);
+
+    if (lsr & UART_LSR_DR)
+    {
+        temp = rockchip_fiq_read(t, UART_RX);
+        buf[n & 0x1f] = temp;
+        n++;
+
+        if (temp == 'q' && n > 2)
+        {
+            if ((buf[(n - 2) & 0x1f] == 'i') && (buf[(n - 3) & 0x1f] == 'f'))
+            {
+                ch = FIQ_DEBUGGER_BREAK;
+            }
+            else
+            {
+                ch = temp;
+            }
+        }
+        else
+        {
+            ch = temp;
+        }
+    }
+
+    return ch;
+}
+
+static const struct rt_uart_ops fiq_debugger_uart_ops =
+{
+    .configure = fiq_debugger_uart_configure,
+    .control = fiq_debugger_uart_control,
+    .putc = fiq_debugger_uart_putc,
+    .getc = fiq_debugger_uart_getc,
+};
+
+struct rockchip_fiq_debugger *rk_serial_debug_init(void *base, rt_ubase_t paddr,
+    int irq, int signal_irq, int wakeup_irq, rt_uint32_t baudrate)
+{
+    struct rockchip_fiq_debugger *t = rt_calloc(1, sizeof(*t));
+
+    if (t)
+    {
+        const char *name;
+
+        t->parent.ops = &fiq_debugger_uart_ops;
+        t->parent.config = (struct serial_configure)RT_SERIAL_CONFIG_DEFAULT;
+        t->parent.config.baud_rate = baudrate;
+        t->irq = irq;
+        t->baudrate = baudrate;
+        t->debug_port_base = base;
+        t->break_seen = RT_FALSE;
+
+        serial_dev_set_name(&t->parent);
+        name = rt_dm_dev_get_name(&t->parent.parent);
+
+        rt_hw_serial_register(&t->parent, name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, t);
+        rt_pic_attach_irq(t->irq, fiq_debugger_isr, &t->parent, name, RT_IRQ_F_NONE);
+    }
+
+    return t;
+}
+
+static rt_err_t rockchip_fiq_debugger_probe(struct rt_platform_device *pdev)
+{
+    rt_err_t err = RT_EOK;
+    void *base;
+    rt_uint64_t regs[2];
+    struct rt_clk *clk, *pclk;
+    rt_bool_t found = RT_FALSE;
+    char dev_name[RT_NAME_MAX];
+    int irq, signal_irq = -1;
+    rt_uint32_t serial_id, baudrate = 0, irq_mode = 0, wake_irq = -1;
+    struct rt_ofw_node *np = pdev->parent.ofw_node;
+
+    if (rt_ofw_prop_read_u32(np, "rockchip,serial-id", &serial_id) || serial_id == -1)
+    {
+        return -RT_EINVAL;
+    }
+
+    if (rt_ofw_prop_read_u32(np, "rockchip,irq-mode-enable", &irq_mode))
+    {
+        irq_mode = -1;
+    }
+
+    if (irq_mode == 1)
+    {
+        signal_irq = -1;
+    }
+    else if (!(signal_irq = rt_ofw_get_irq(np, 0)))
+    {
+        return -RT_EINVAL;
+    }
+
+    if (rt_ofw_prop_read_u32(np, "rockchip,wake-irq", &wake_irq))
+    {
+        wake_irq = -1;
+    }
+
+    if (rt_ofw_prop_read_u32(np, "rockchip,baudrate", &baudrate))
+    {
+        baudrate = 1500000;
+    }
+
+    rt_snprintf(dev_name, RT_NAME_MAX, "serial%d", serial_id);
+
+    np = RT_NULL;
+
+    do {
+        np = rt_ofw_find_node_by_tag(np, "serial");
+
+        if (np && rt_ofw_get_alias_id(np, "serial") == serial_id)
+        {
+            found = RT_TRUE;
+            break;
+        }
+    } while(np);
+
+    if (!found)
+    {
+        return -RT_EINVAL;
+    }
+
+    rt_memset(regs, 0, sizeof(regs));
+    rt_ofw_get_address_array(np, 1, regs);
+
+    pclk = rt_ofw_get_clk_by_name(np, "apb_pclk");
+    clk = rt_ofw_get_clk_by_name(np, "baudclk");
+
+    if (!pclk || !clk)
+    {
+        err = -RT_ERROR;
+        goto _fail;
+    }
+
+    rt_clk_enable(clk);
+    rt_clk_enable(pclk);
+
+    if ((irq = rt_ofw_get_irq(np, 0)) < 0)
+    {
+        err = -RT_ERROR;
+        goto _fail;
+    }
+
+    if ((base = rt_ioremap((void *)regs[0], regs[1])))
+    {
+        struct rockchip_fiq_debugger *t = rk_serial_debug_init(base,
+            (rt_ubase_t)regs[0], irq, signal_irq, wake_irq, baudrate);
+
+        if (t)
+        {
+            rt_dm_dev_bind_fwdata(&t->parent.parent, pdev->parent.ofw_node, &t->parent);
+        }
+    }
+
+    return err;
+
+_fail:
+    if (clk)
+    {
+        rt_clk_disable(clk);
+        rt_clk_put(clk);
+    }
+
+    if (pclk)
+    {
+        rt_clk_disable(pclk);
+        rt_clk_put(pclk);
+    }
+
+    return err;
+}
+
+static const struct rt_ofw_node_id rockchip_fiq_debugger_ofw_ids[] =
+{
+    { .type = "ttyFIQ", .compatible = "rockchip,fiq-debugger" },
+    { /* sentinel */ }
+};
+
+static struct rt_platform_driver rockchip_fiq_debugger_driver =
+{
+    .name = "rockchip-fiq-debugger",
+    .ids = rockchip_fiq_debugger_ofw_ids,
+
+    .probe = rockchip_fiq_debugger_probe,
+};
+
+static int rockchip_fiq_debugger_drv_register(void)
+{
+    rt_platform_driver_register(&rockchip_fiq_debugger_driver);
+
+    return 0;
+}
+INIT_DRIVER_EARLY_EXPORT(rockchip_fiq_debugger_drv_register);

+ 365 - 0
bsp/rockchip/rk3500/driver/uart8250/regs.h

@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+#ifndef __SERIAL_8250_REGS_H__
+#define __SERIAL_8250_REGS_H__
+
+/*
+ * DLAB=0
+ */
+#define UART_RX                 0    /* In:  Receive buffer */
+#define UART_TX                 0    /* Out: Transmit buffer */
+
+#define UART_IER                1    /* Out: Interrupt Enable Register */
+#define UART_IER_MSI            0x08 /* Enable Modem status interrupt */
+#define UART_IER_RLSI           0x04 /* Enable receiver line status interrupt */
+#define UART_IER_THRI           0x02 /* Enable Transmitter holding register int. */
+#define UART_IER_RDI            0x01 /* Enable receiver data interrupt */
+/*
+ * Sleep mode for ST16650 and TI16750.  For the ST16650, EFR[4]=1
+ */
+#define UART_IERX_SLEEP         0x10 /* Enable sleep mode */
+
+#define UART_IIR                2    /* In:  Interrupt ID Register */
+#define UART_IIR_NO_INT         0x01 /* No interrupts pending */
+#define UART_IIR_ID             0x0e /* Mask for the interrupt ID */
+#define UART_IIR_MSI            0x00 /* Modem status interrupt */
+#define UART_IIR_THRI           0x02 /* Transmitter holding register empty */
+#define UART_IIR_RDI            0x04 /* Receiver data interrupt */
+#define UART_IIR_RLSI           0x06 /* Receiver line status interrupt */
+
+#define UART_IIR_BUSY           0x07 /* DesignWare APB Busy Detect */
+
+#define UART_IIR_RX_TIMEOUT     0x0c /* OMAP RX Timeout interrupt */
+#define UART_IIR_XOFF           0x10 /* OMAP XOFF/Special Character */
+#define UART_IIR_CTS_RTS_DSR    0x20 /* OMAP CTS/RTS/DSR Change */
+
+#define UART_FCR                2    /* Out: FIFO Control Register */
+#define UART_FCR_ENABLE_FIFO    0x01 /* Enable the FIFO */
+#define UART_FCR_CLEAR_RCVR     0x02 /* Clear the RCVR FIFO */
+#define UART_FCR_CLEAR_XMIT     0x04 /* Clear the XMIT FIFO */
+#define UART_FCR_DMA_SELECT     0x08 /* For DMA applications */
+/*
+ * Note: The FIFO trigger levels are chip specific:
+ *      RX:76 = 00  01  10  11  TX:54 = 00  01  10  11
+ * PC16550D:     1   4   8  14          xx  xx  xx  xx
+ * TI16C550A:    1   4   8  14          xx  xx  xx  xx
+ * TI16C550C:    1   4   8  14          xx  xx  xx  xx
+ * ST16C550:     1   4   8  14          xx  xx  xx  xx
+ * ST16C650:     8  16  24  28          16   8  24  30  PORT_16650V2
+ * NS16C552:     1   4   8  14          xx  xx  xx  xx
+ * ST16C654:     8  16  56  60           8  16  32  56  PORT_16654
+ * TI16C750:     1  16  32  56          xx  xx  xx  xx  PORT_16750
+ * TI16C752:     8  16  56  60           8  16  32  56
+ * OX16C950:    16  32 112 120          16  32  64 112  PORT_16C950
+ * Tegra:        1   4   8  14          16   8   4   1  PORT_TEGRA
+ */
+#define UART_FCR_R_TRIG_00      0x00
+#define UART_FCR_R_TRIG_01      0x40
+#define UART_FCR_R_TRIG_10      0x80
+#define UART_FCR_R_TRIG_11      0xc0
+#define UART_FCR_T_TRIG_00      0x00
+#define UART_FCR_T_TRIG_01      0x10
+#define UART_FCR_T_TRIG_10      0x20
+#define UART_FCR_T_TRIG_11      0x30
+
+#define UART_FCR_TRIGGER_MASK   0xC0 /* Mask for the FIFO trigger range */
+#define UART_FCR_TRIGGER_1      0x00 /* Mask for trigger set at 1 */
+#define UART_FCR_TRIGGER_4      0x40 /* Mask for trigger set at 4 */
+#define UART_FCR_TRIGGER_8      0x80 /* Mask for trigger set at 8 */
+#define UART_FCR_TRIGGER_14     0xC0 /* Mask for trigger set at 14 */
+/* 16650 definitions */
+#define UART_FCR6_R_TRIGGER_8   0x00 /* Mask for receive trigger set at 1 */
+#define UART_FCR6_R_TRIGGER_16  0x40 /* Mask for receive trigger set at 4 */
+#define UART_FCR6_R_TRIGGER_24  0x80 /* Mask for receive trigger set at 8 */
+#define UART_FCR6_R_TRIGGER_28  0xC0 /* Mask for receive trigger set at 14 */
+#define UART_FCR6_T_TRIGGER_16  0x00 /* Mask for transmit trigger set at 16 */
+#define UART_FCR6_T_TRIGGER_8   0x10 /* Mask for transmit trigger set at 8 */
+#define UART_FCR6_T_TRIGGER_24  0x20 /* Mask for transmit trigger set at 24 */
+#define UART_FCR6_T_TRIGGER_30  0x30 /* Mask for transmit trigger set at 30 */
+#define UART_FCR7_64BYTE        0x20 /* Go into 64 byte mode (TI16C750 and some Freescale UARTs) */
+
+#define UART_FCR_R_TRIG_SHIFT       6
+#define UART_FCR_R_TRIG_BITS(x)     (((x) & UART_FCR_TRIGGER_MASK) >> UART_FCR_R_TRIG_SHIFT)
+#define UART_FCR_R_TRIG_MAX_STATE   4
+
+#define UART_LCR                    3 /* Out: Line Control Register */
+/*
+ * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting
+ * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits.
+ */
+#define UART_LCR_DLAB           0x80 /* Divisor latch access bit */
+#define UART_LCR_SBC            0x40 /* Set break control */
+#define UART_LCR_SPAR           0x20 /* Stick parity (?) */
+#define UART_LCR_EPAR           0x10 /* Even parity select */
+#define UART_LCR_PARITY         0x08 /* Parity Enable */
+#define UART_LCR_STOP           0x04 /* Stop bits: 0=1 bit, 1=2 bits */
+#define UART_LCR_WLEN5          0x00 /* Wordlength: 5 bits */
+#define UART_LCR_WLEN6          0x01 /* Wordlength: 6 bits */
+#define UART_LCR_WLEN7          0x02 /* Wordlength: 7 bits */
+#define UART_LCR_WLEN8          0x03 /* Wordlength: 8 bits */
+
+/*
+ * Access to some registers depends on register access / configuration mode.
+ */
+#define UART_LCR_CONF_MODE_A    UART_LCR_DLAB   /* Configutation mode A */
+#define UART_LCR_CONF_MODE_B    0xBF            /* Configutation mode B */
+
+#define UART_MCR                4    /* Out: Modem Control Register */
+#define UART_MCR_CLKSEL         0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */
+#define UART_MCR_TCRTLR         0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */
+#define UART_MCR_XONANY         0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */
+#define UART_MCR_AFE            0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */
+#define UART_MCR_LOOP           0x10 /* Enable loopback test mode */
+#define UART_MCR_OUT2           0x08 /* Out2 complement */
+#define UART_MCR_OUT1           0x04 /* Out1 complement */
+#define UART_MCR_RTS            0x02 /* RTS complement */
+#define UART_MCR_DTR            0x01 /* DTR complement */
+
+#define UART_LSR                5    /* In:  Line Status Register */
+#define UART_LSR_FIFOE          0x80 /* Fifo error */
+#define UART_LSR_TEMT           0x40 /* Transmitter empty */
+#define UART_LSR_THRE           0x20 /* Transmit-hold-register empty */
+#define UART_LSR_BI             0x10 /* Break interrupt indicator */
+#define UART_LSR_FE             0x08 /* Frame error indicator */
+#define UART_LSR_PE             0x04 /* Parity error indicator */
+#define UART_LSR_OE             0x02 /* Overrun error indicator */
+#define UART_LSR_DR             0x01 /* Receiver data ready */
+#define UART_LSR_BRK_ERROR_BITS (UART_LSR_BI|UART_LSR_FE|UART_LSR_PE|UART_LSR_OE)
+
+#define UART_MSR                6    /* In:  Modem Status Register */
+#define UART_MSR_DCD            0x80 /* Data Carrier Detect */
+#define UART_MSR_RI             0x40 /* Ring Indicator */
+#define UART_MSR_DSR            0x20 /* Data Set Ready */
+#define UART_MSR_CTS            0x10 /* Clear to Send */
+#define UART_MSR_DDCD           0x08 /* Delta DCD */
+#define UART_MSR_TERI           0x04 /* Trailing edge ring indicator */
+#define UART_MSR_DDSR           0x02 /* Delta DSR */
+#define UART_MSR_DCTS           0x01 /* Delta CTS */
+#define UART_MSR_ANY_DELTA      (UART_MSR_DDCD|UART_MSR_TERI|UART_MSR_DDSR|UART_MSR_DCTS)
+
+#define UART_SCR                7    /* I/O: Scratch Register */
+
+/*
+ * DLAB=1
+ */
+#define UART_DLL                0       /* Out: Divisor Latch Low */
+#define UART_DLM                1       /* Out: Divisor Latch High */
+#define UART_DIV_MAX            0xFFFF  /* Max divisor value */
+
+/*
+ * LCR=0xBF (or DLAB=1 for 16C660)
+ */
+#define UART_EFR                2    /* I/O: Extended Features Register */
+#define UART_XR_EFR             9    /* I/O: Extended Features Register (XR17D15x) */
+#define UART_EFR_CTS            0x80 /* CTS flow control */
+#define UART_EFR_RTS            0x40 /* RTS flow control */
+#define UART_EFR_SCD            0x20 /* Special character detect */
+#define UART_EFR_ECB            0x10 /* Enhanced control bit */
+/*
+ * the low four bits control software flow control
+ */
+
+/*
+ * LCR=0xBF, TI16C752, ST16650, ST16650A, ST16654
+ */
+#define UART_XON1               4    /* I/O: Xon character 1 */
+#define UART_XON2               5    /* I/O: Xon character 2 */
+#define UART_XOFF1              6    /* I/O: Xoff character 1 */
+#define UART_XOFF2              7    /* I/O: Xoff character 2 */
+
+/*
+ * EFR[4]=1 MCR[6]=1, TI16C752
+ */
+#define UART_TI752_TCR          6    /* I/O: transmission control register */
+#define UART_TI752_TLR          7    /* I/O: trigger level register */
+
+/*
+ * LCR=0xBF, XR16C85x
+ */
+#define UART_TRG                0   /* FCTR bit 7 selects Rx or Tx In: Fifo count Out: Fifo custom trigger levels */
+/*
+ * These are the definitions for the Programmable Trigger Register
+ */
+#define UART_TRG_1              0x01
+#define UART_TRG_4              0x04
+#define UART_TRG_8              0x08
+#define UART_TRG_16             0x10
+#define UART_TRG_32             0x20
+#define UART_TRG_64             0x40
+#define UART_TRG_96             0x60
+#define UART_TRG_120            0x78
+#define UART_TRG_128            0x80
+
+#define UART_FCTR               1    /* Feature Control Register */
+#define UART_FCTR_RTS_NODELAY   0x00 /* RTS flow control delay */
+#define UART_FCTR_RTS_4DELAY    0x01
+#define UART_FCTR_RTS_6DELAY    0x02
+#define UART_FCTR_RTS_8DELAY    0x03
+#define UART_FCTR_IRDA          0x04 /* IrDa data encode select */
+#define UART_FCTR_TX_INT        0x08 /* Tx interrupt type select */
+#define UART_FCTR_TRGA          0x00 /* Tx/Rx 550 trigger table select */
+#define UART_FCTR_TRGB          0x10 /* Tx/Rx 650 trigger table select */
+#define UART_FCTR_TRGC          0x20 /* Tx/Rx 654 trigger table select */
+#define UART_FCTR_TRGD          0x30 /* Tx/Rx 850 programmable trigger select */
+#define UART_FCTR_SCR_SWAP      0x40 /* Scratch pad register swap */
+#define UART_FCTR_RX            0x00 /* Programmable trigger mode select */
+#define UART_FCTR_TX            0x80 /* Programmable trigger mode select */
+
+/*
+ * LCR=0xBF, FCTR[6]=1
+ */
+#define UART_EMSR               7    /* Extended Mode Select Register */
+#define UART_EMSR_FIFO_COUNT    0x01 /* Rx/Tx select */
+#define UART_EMSR_ALT_COUNT     0x02 /* Alternating count select */
+
+/*
+ * The Intel XScale on-chip UARTs define these bits
+ */
+#define UART_IER_DMAE           0x80 /* DMA Requests Enable */
+#define UART_IER_UUE            0x40 /* UART Unit Enable */
+#define UART_IER_NRZE           0x20 /* NRZ coding Enable */
+#define UART_IER_RTOIE          0x10 /* Receiver Time Out Interrupt Enable */
+
+#define UART_IIR_TOD            0x08 /* Character Timeout Indication Detected */
+
+#define UART_FCR_PXAR1          0x00 /* receive FIFO threshold = 1 */
+#define UART_FCR_PXAR8          0x40 /* receive FIFO threshold = 8 */
+#define UART_FCR_PXAR16         0x80 /* receive FIFO threshold = 16 */
+#define UART_FCR_PXAR32         0xc0 /* receive FIFO threshold = 32 */
+
+/*
+ * These register definitions are for the 16C950
+ */
+#define UART_ASR                0x01 /* Additional Status Register */
+#define UART_RFL                0x03 /* Receiver FIFO level */
+#define UART_TFL                0x04 /* Transmitter FIFO level */
+#define UART_ICR                0x05 /* Index Control Register */
+
+/* The 16950 ICR registers */
+#define UART_ACR                0x00 /* Additional Control Register */
+#define UART_CPR                0x01 /* Clock Prescalar Register */
+#define UART_TCR                0x02 /* Times Clock Register */
+#define UART_CKS                0x03 /* Clock Select Register */
+#define UART_TTL                0x04 /* Transmitter Interrupt Trigger Level */
+#define UART_RTL                0x05 /* Receiver Interrupt Trigger Level */
+#define UART_FCL                0x06 /* Flow Control Level Lower */
+#define UART_FCH                0x07 /* Flow Control Level Higher */
+#define UART_ID1                0x08 /* ID #1 */
+#define UART_ID2                0x09 /* ID #2 */
+#define UART_ID3                0x0A /* ID #3 */
+#define UART_REV                0x0B /* Revision */
+#define UART_CSR                0x0C /* Channel Software Reset */
+#define UART_NMR                0x0D /* Nine-bit Mode Register */
+#define UART_CTR                0xFF
+
+/*
+ * The 16C950 Additional Control Register
+ */
+#define UART_ACR_RXDIS          0x01 /* Receiver disable */
+#define UART_ACR_TXDIS          0x02 /* Transmitter disable */
+#define UART_ACR_DSRFC          0x04 /* DSR Flow Control */
+#define UART_ACR_TLENB          0x20 /* 950 trigger levels enable */
+#define UART_ACR_ICRRD          0x40 /* ICR Read enable */
+#define UART_ACR_ASREN          0x80 /* Additional status enable */
+
+/*
+ * These definitions are for the RSA-DV II/S card, from
+ *
+ * Kiyokazu SUTO <suto@ks-and-ks.ne.jp>
+ */
+
+#define UART_RSA_BASE                   (-8)
+
+#define UART_RSA_MSR                    ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */
+
+#define UART_RSA_MSR_SWAP               (1 << 0) /* Swap low/high 8 bytes in I/O port addr */
+#define UART_RSA_MSR_FIFO               (1 << 2) /* Enable the external FIFO */
+#define UART_RSA_MSR_FLOW               (1 << 3) /* Enable the auto RTS/CTS flow control */
+#define UART_RSA_MSR_ITYP               (1 << 4) /* Level (1) / Edge triger (0) */
+
+#define UART_RSA_IER                    ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */
+
+#define UART_RSA_IER_Rx_FIFO_H          (1 << 0) /* Enable Rx FIFO half full int. */
+#define UART_RSA_IER_Tx_FIFO_H          (1 << 1) /* Enable Tx FIFO half full int. */
+#define UART_RSA_IER_Tx_FIFO_E          (1 << 2) /* Enable Tx FIFO empty int. */
+#define UART_RSA_IER_Rx_TOUT            (1 << 3) /* Enable char receive timeout int */
+#define UART_RSA_IER_TIMER              (1 << 4) /* Enable timer interrupt */
+
+#define UART_RSA_SRR                    ((UART_RSA_BASE) + 2) /* IN: Status Read Register */
+
+#define UART_RSA_SRR_Tx_FIFO_NEMP       (1 << 0) /* Tx FIFO is not empty (1) */
+#define UART_RSA_SRR_Tx_FIFO_NHFL       (1 << 1) /* Tx FIFO is not half full (1) */
+#define UART_RSA_SRR_Tx_FIFO_NFUL       (1 << 2) /* Tx FIFO is not full (1) */
+#define UART_RSA_SRR_Rx_FIFO_NEMP       (1 << 3) /* Rx FIFO is not empty (1) */
+#define UART_RSA_SRR_Rx_FIFO_NHFL       (1 << 4) /* Rx FIFO is not half full (1) */
+#define UART_RSA_SRR_Rx_FIFO_NFUL       (1 << 5) /* Rx FIFO is not full (1) */
+#define UART_RSA_SRR_Rx_TOUT            (1 << 6) /* Character reception timeout occurred (1) */
+#define UART_RSA_SRR_TIMER              (1 << 7) /* Timer interrupt occurred */
+
+#define UART_RSA_FRR                    ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */
+
+#define UART_RSA_TIVSR                  ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */
+
+#define UART_RSA_TCR                    ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */
+
+#define UART_RSA_TCR_SWITCH             (1 << 0) /* Timer on */
+
+/*
+ * The RSA DSV/II board has two fixed clock frequencies.  One is the
+ * standard rate, and the other is 8 times faster.
+ */
+#define SERIAL_RSA_BAUD_BASE            (921600)
+#define SERIAL_RSA_BAUD_BASE_LO         (SERIAL_RSA_BAUD_BASE / 8)
+
+/* Extra registers for TI DA8xx/66AK2x */
+#define UART_DA830_PWREMU_MGMT          12
+
+/* PWREMU_MGMT register bits */
+#define UART_DA830_PWREMU_MGMT_FREE     (1 << 0)  /* Free-running mode */
+#define UART_DA830_PWREMU_MGMT_URRST    (1 << 13) /* Receiver reset/enable */
+#define UART_DA830_PWREMU_MGMT_UTRST    (1 << 14) /* Transmitter reset/enable */
+
+/*
+ * Extra serial register definitions for the internal UARTs
+ * in TI OMAP processors.
+ */
+#define OMAP1_UART1_BASE                0xfffb0000
+#define OMAP1_UART2_BASE                0xfffb0800
+#define OMAP1_UART3_BASE                0xfffb9800
+#define UART_OMAP_MDR1                  0x08    /* Mode definition register */
+#define UART_OMAP_MDR2                  0x09    /* Mode definition register 2 */
+#define UART_OMAP_SCR                   0x10    /* Supplementary control register */
+#define UART_OMAP_SSR                   0x11    /* Supplementary status register */
+#define UART_OMAP_EBLR                  0x12    /* BOF length register */
+#define UART_OMAP_OSC_12M_SEL           0x13    /* OMAP1510 12MHz osc select */
+#define UART_OMAP_MVER                  0x14    /* Module version register */
+#define UART_OMAP_SYSC                  0x15    /* System configuration register */
+#define UART_OMAP_SYSS                  0x16    /* System status register */
+#define UART_OMAP_WER                   0x17    /* Wake-up enable register */
+#define UART_OMAP_TX_LVL                0x1a    /* TX FIFO level register */
+
+/*
+ * These are the definitions for the MDR1 register
+ */
+#define UART_OMAP_MDR1_16X_MODE         0x00    /* UART 16x mode */
+#define UART_OMAP_MDR1_SIR_MODE         0x01    /* SIR mode */
+#define UART_OMAP_MDR1_16X_ABAUD_MODE   0x02    /* UART 16x auto-baud */
+#define UART_OMAP_MDR1_13X_MODE         0x03    /* UART 13x mode */
+#define UART_OMAP_MDR1_MIR_MODE         0x04    /* MIR mode */
+#define UART_OMAP_MDR1_FIR_MODE         0x05    /* FIR mode */
+#define UART_OMAP_MDR1_CIR_MODE         0x06    /* CIR mode */
+#define UART_OMAP_MDR1_DISABLE          0x07    /* Disable (default state) */
+
+/*
+ * These are definitions for the Altera ALTR_16550_F32/F64/F128
+ * Normalized from 0x100 to 0x40 because of shift by 2 (32 bit regs).
+ */
+#define UART_ALTR_AFR                   0x40    /* Additional Features Register */
+#define UART_ALTR_EN_TXFIFO_LW          0x01    /* Enable the TX FIFO Low Watermark */
+#define UART_ALTR_TX_LOW                0x41    /* Tx FIFO Low Watermark */
+
+#endif /* __SERIAL_8250_REGS_H__ */

+ 29 - 0
bsp/rockchip/rk3500/driver/uart8250/serial_dm.h

@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2006-2024 RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2022-11-16     GuEe-GUI     first version
+ */
+
+#ifndef __SERIAL_DM_H__
+#define __SERIAL_DM_H__
+
+#include <rtthread.h>
+#include <rtdevice.h>
+#include <posix/string.h>
+
+int serial_dev_set_name(struct rt_serial_device *sdev);
+
+void *serial_base_from_args(char *str);
+struct serial_configure serial_cfg_from_args(char *str);
+
+#define serial_for_each_args(arg, args)                                 \
+    for (char *context = (arg = (typeof(arg))args, (void *)RT_NULL),    \
+        *context_end = strchrnul((char *)args, ' ');                 \
+         (arg = strtok_r(arg, ",", &context)) && arg < context_end;     \
+         arg = RT_NULL)
+
+#endif /* __SERIAL_DM_H__ */

+ 568 - 0
bsp/rockchip/rk3500/rtconfig.h

@@ -0,0 +1,568 @@
+#ifndef RT_CONFIG_H__
+#define RT_CONFIG_H__
+
+/* RT-Thread Kernel */
+
+#define RT_NAME_MAX 8
+#define RT_USING_SMART
+#define RT_USING_SMP
+#define RT_CPUS_NR 4
+#define RT_ALIGN_SIZE 8
+#define RT_THREAD_PRIORITY_32
+#define RT_THREAD_PRIORITY_MAX 32
+#define RT_TICK_PER_SECOND 1000
+#define RT_USING_HOOK
+#define RT_HOOK_USING_FUNC_PTR
+#define RT_USING_HOOKLIST
+#define RT_USING_IDLE_HOOK
+#define RT_IDLE_HOOK_LIST_SIZE 4
+#define IDLE_THREAD_STACK_SIZE 16384
+#define SYSTEM_THREAD_STACK_SIZE 16384
+#define RT_USING_TIMER_SOFT
+#define RT_TIMER_THREAD_PRIO 4
+#define RT_TIMER_THREAD_STACK_SIZE 32768
+#define RT_USING_TIMER_ALL_SOFT
+#define RT_USING_CPU_USAGE_TRACER
+
+/* kservice optimization */
+
+/* end of kservice optimization */
+
+/* klibc optimization */
+
+#define RT_KLIBC_USING_PRINTF_LONGLONG
+/* end of klibc optimization */
+#define RT_USING_DEBUG
+#define RT_DEBUGING_COLOR
+
+/* Inter-Thread communication */
+
+#define RT_USING_SEMAPHORE
+#define RT_USING_MUTEX
+#define RT_USING_EVENT
+#define RT_USING_MAILBOX
+#define RT_USING_MESSAGEQUEUE
+#define RT_USING_MESSAGEQUEUE_PRIORITY
+/* end of Inter-Thread communication */
+
+/* Memory Management */
+
+#define RT_PAGE_MAX_ORDER 11
+#define RT_USING_SLAB
+#define RT_USING_MEMHEAP
+#define RT_MEMHEAP_FAST_MODE
+#define RT_USING_MEMHEAP_AS_HEAP
+#define RT_USING_MEMHEAP_AUTO_BINDING
+#define RT_USING_HEAP
+/* end of Memory Management */
+#define RT_USING_DEVICE
+#define RT_USING_DEVICE_OPS
+#define RT_USING_THREADSAFE_PRINTF
+#define RT_USING_CONSOLE
+#define RT_CONSOLEBUF_SIZE 1024
+#define RT_CONSOLE_DEVICE_NAME "uart2"
+#define RT_VER_NUM 0x50200
+#define RT_USING_STDC_ATOMIC
+#define RT_BACKTRACE_LEVEL_MAX_NR 32
+/* end of RT-Thread Kernel */
+
+/* AArch64 Architecture Configuration */
+
+#define ARCH_TEXT_OFFSET 0x00480000
+#define ARCH_RAM_OFFSET 0x200000
+#define ARCH_SECONDARY_CPU_STACK_SIZE 16384
+#define ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS
+#define ARCH_USING_GENERIC_CPUID
+#define ARCH_HEAP_SIZE 0x4000000
+#define ARCH_INIT_PAGE_SIZE 0x200000
+/* end of AArch64 Architecture Configuration */
+#define ARCH_CPU_64BIT
+#define RT_USING_CACHE
+#define ARCH_ARM_BOOTWITH_FLUSH_CACHE
+#define RT_USING_CPU_FFS
+#define ARCH_MM_MMU
+#define ARCH_ARM
+#define ARCH_ARM_MMU
+#define KERNEL_VADDR_START 0xffff000000000000
+#define ARCH_ARMV8
+#define ARCH_USING_HW_THREAD_SELF
+#define ARCH_USING_IRQ_CTX_LIST
+
+/* RT-Thread Components */
+
+#define RT_USING_COMPONENTS_INIT
+#define RT_USING_USER_MAIN
+#define RT_MAIN_THREAD_STACK_SIZE 16384
+#define RT_MAIN_THREAD_PRIORITY 10
+#define RT_USING_MSH
+#define RT_USING_FINSH
+#define FINSH_USING_MSH
+#define FINSH_THREAD_NAME "tshell"
+#define FINSH_THREAD_PRIORITY 20
+#define FINSH_THREAD_STACK_SIZE 16384
+#define FINSH_USING_HISTORY
+#define FINSH_HISTORY_LINES 5
+#define FINSH_USING_SYMTAB
+#define FINSH_CMD_SIZE 80
+#define MSH_USING_BUILT_IN_COMMANDS
+#define FINSH_USING_DESCRIPTION
+#define FINSH_ARG_MAX 10
+#define FINSH_USING_OPTION_COMPLETION
+
+/* DFS: device virtual file system */
+
+#define RT_USING_DFS
+#define DFS_USING_POSIX
+#define DFS_USING_WORKDIR
+#define DFS_FD_MAX 512
+#define RT_USING_DFS_V2
+#define RT_USING_DFS_DEVFS
+#define RT_USING_DFS_PTYFS
+#define RT_USING_DFS_CROMFS
+#define RT_USING_DFS_TMPFS
+#define RT_USING_DFS_MQUEUE
+#define RT_USING_PAGECACHE
+
+/* page cache config */
+
+#define RT_PAGECACHE_COUNT 128
+#define RT_PAGECACHE_ASPACE_COUNT 32
+#define RT_PAGECACHE_PRELOAD 4
+#define RT_PAGECACHE_HASH_NR 180
+#define RT_PAGECACHE_GC_WORK_LEVEL 90
+#define RT_PAGECACHE_GC_STOP_LEVEL 70
+/* end of page cache config */
+/* end of DFS: device virtual file system */
+
+/* Device Drivers */
+
+#define RT_USING_DM
+#define RT_USING_DEV_BUS
+#define RT_USING_DEVICE_IPC
+#define RT_UNAMED_PIPE_NUMBER 64
+#define RT_USING_SYSTEM_WORKQUEUE
+#define RT_SYSTEM_WORKQUEUE_STACKSIZE 16384
+#define RT_SYSTEM_WORKQUEUE_PRIORITY 23
+#define RT_USING_SERIAL
+#define RT_USING_SERIAL_V1
+#define RT_SERIAL_RB_BUFSZ 64
+#define RT_USING_NULL
+#define RT_USING_ZERO
+#define RT_USING_RANDOM
+#define RT_USING_RTC
+#define RT_USING_SOFT_RTC
+#define RT_USING_SDIO
+#define RT_SDIO_STACK_SIZE 16384
+#define RT_SDIO_THREAD_PRIORITY 15
+#define RT_MMCSD_STACK_SIZE 16384
+#define RT_MMCSD_THREAD_PREORITY 22
+#define RT_MMCSD_MAX_PARTITION 16
+#define RT_USING_OFW
+#define RT_FDT_EARLYCON_MSG_SIZE 128
+#define RT_USING_OFW_BUS_RANGES_NUMBER 8
+#define RT_USING_PIC
+#define MAX_HANDLERS 1024
+#define RT_PIC_ARM_GIC_V3
+#define RT_USING_PIN
+#define RT_USING_PINCTRL
+#define RT_USING_KTIME
+#define RT_USING_CLK
+#define RT_USING_HWTIMER
+#define RT_HWTIMER_ARM_ARCH
+/* end of Device Drivers */
+
+/* C/C++ and POSIX layer */
+
+/* ISO-ANSI C layer */
+
+/* Timezone and Daylight Saving Time */
+
+#define RT_LIBC_USING_LIGHT_TZ_DST
+#define RT_LIBC_TZ_DEFAULT_HOUR 8
+#define RT_LIBC_TZ_DEFAULT_MIN 0
+#define RT_LIBC_TZ_DEFAULT_SEC 0
+/* end of Timezone and Daylight Saving Time */
+/* end of ISO-ANSI C layer */
+
+/* POSIX (Portable Operating System Interface) layer */
+
+#define RT_USING_POSIX_FS
+#define RT_USING_POSIX_DEVIO
+#define RT_USING_POSIX_STDIO
+#define RT_USING_POSIX_POLL
+#define RT_USING_POSIX_SELECT
+#define RT_USING_POSIX_EVENTFD
+#define RT_USING_POSIX_EPOLL
+#define RT_USING_POSIX_SIGNALFD
+#define RT_SIGNALFD_MAX_NUM 10
+#define RT_USING_POSIX_TIMERFD
+#define RT_USING_POSIX_SOCKET
+#define RT_USING_POSIX_TERMIOS
+#define RT_USING_POSIX_MMAN
+#define RT_USING_POSIX_DELAY
+#define RT_USING_POSIX_CLOCK
+#define RT_USING_POSIX_TIMER
+
+/* Interprocess Communication (IPC) */
+
+#define RT_USING_POSIX_PIPE
+#define RT_USING_POSIX_PIPE_SIZE 2048
+#define RT_USING_POSIX_MESSAGE_QUEUE
+
+/* Socket is in the 'Network' category */
+
+/* end of Interprocess Communication (IPC) */
+/* end of POSIX (Portable Operating System Interface) layer */
+/* end of C/C++ and POSIX layer */
+
+/* Network */
+
+#define RT_USING_SAL
+#define SAL_INTERNET_CHECK
+
+/* Docking with protocol stacks */
+
+#define SAL_USING_LWIP
+/* end of Docking with protocol stacks */
+#define SAL_USING_POSIX
+#define RT_USING_NETDEV
+#define NETDEV_USING_IFCONFIG
+#define NETDEV_USING_PING
+#define NETDEV_USING_NETSTAT
+#define NETDEV_USING_AUTO_DEFAULT
+#define NETDEV_IPV4 1
+#define NETDEV_IPV6 0
+#define RT_USING_LWIP
+#define RT_USING_LWIP212
+#define RT_USING_LWIP_VER_NUM 0x20102
+#define RT_LWIP_MEM_ALIGNMENT 8
+#define RT_LWIP_IGMP
+#define RT_LWIP_ICMP
+#define RT_LWIP_DNS
+#define RT_LWIP_DHCP
+#define IP_SOF_BROADCAST 1
+#define IP_SOF_BROADCAST_RECV 1
+
+/* Static IPv4 Address */
+
+#define RT_LWIP_IPADDR "192.168.1.30"
+#define RT_LWIP_GWADDR "192.168.1.1"
+#define RT_LWIP_MSKADDR "255.255.255.0"
+/* end of Static IPv4 Address */
+#define RT_LWIP_UDP
+#define RT_LWIP_TCP
+#define RT_LWIP_RAW
+#define RT_MEMP_NUM_NETCONN 64
+#define RT_LWIP_PBUF_NUM 320
+#define RT_LWIP_RAW_PCB_NUM 32
+#define RT_LWIP_UDP_PCB_NUM 32
+#define RT_LWIP_TCP_PCB_NUM 64
+#define RT_LWIP_TCP_SEG_NUM 480
+#define RT_LWIP_TCP_SND_BUF 65535
+#define RT_LWIP_TCP_WND 49512
+#define RT_LWIP_TCPTHREAD_PRIORITY 8
+#define RT_LWIP_TCPTHREAD_MBOX_SIZE 256
+#define RT_LWIP_TCPTHREAD_STACKSIZE 65536
+#define LWIP_NO_TX_THREAD
+#define RT_LWIP_ETHTHREAD_PRIORITY 9
+#define RT_LWIP_ETHTHREAD_STACKSIZE 16384
+#define RT_LWIP_ETHTHREAD_MBOX_SIZE 256
+#define LWIP_NETIF_STATUS_CALLBACK 1
+#define LWIP_NETIF_LINK_CALLBACK 1
+#define RT_LWIP_NETIF_NAMESIZE 6
+#define SO_REUSE 1
+#define LWIP_SO_RCVTIMEO 1
+#define LWIP_SO_SNDTIMEO 1
+#define LWIP_SO_RCVBUF 1
+#define LWIP_SO_LINGER 0
+#define RT_LWIP_NETIF_LOOPBACK
+#define LWIP_NETIF_LOOPBACK 1
+#define RT_LWIP_USING_HW_CHECKSUM
+#define RT_LWIP_USING_PING
+/* end of Network */
+
+/* Memory protection */
+
+/* end of Memory protection */
+
+/* Utilities */
+
+#define RT_USING_UTEST
+#define UTEST_THR_STACK_SIZE 32768
+#define UTEST_THR_PRIORITY 20
+#define RT_USING_RESOURCE_ID
+#define RT_USING_ADT
+#define RT_USING_ADT_AVL
+#define RT_USING_ADT_BITMAP
+#define RT_USING_ADT_HASHMAP
+#define RT_USING_ADT_REF
+/* end of Utilities */
+#define RT_USING_LWP
+#define LWP_DEBUG
+#define LWP_DEBUG_INIT
+#define RT_LWP_MAX_NR 128
+#define LWP_TASK_STACK_SIZE 32768
+#define RT_CH_MSG_MAX_NR 1024
+#define LWP_TID_MAX_NR 128
+#define RT_LWP_SHM_MAX_NR 64
+#define RT_USING_LDSO
+#define LWP_USING_TERMINAL
+#define LWP_PTY_MAX_PARIS_LIMIT 64
+#define RT_USING_VDSO
+
+/* Memory management */
+
+#define RT_USING_MEMBLOCK
+#define RT_INIT_MEMORY_REGIONS 128
+/* end of Memory management */
+
+/* Using USB legacy version */
+
+/* end of Using USB legacy version */
+/* end of RT-Thread Components */
+
+/* RT-Thread Utestcases */
+
+#define RT_USING_UTESTCASES
+
+/* Utest Self Testcase */
+
+/* end of Utest Self Testcase */
+
+/* Kernel Testcase */
+
+
+/* Kernel SMP Testcase */
+
+/* end of Kernel SMP Testcase */
+/* end of Kernel Testcase */
+
+/* CPP11 Testcase */
+
+/* end of CPP11 Testcase */
+
+/* Utest Serial Testcase */
+
+/* end of Utest Serial Testcase */
+
+/* Utest IPC Testcase */
+
+/* end of Utest IPC Testcase */
+
+/* RTT Posix Testcase */
+
+/* end of RTT Posix Testcase */
+
+/* Memory Management Subsytem Testcase */
+
+/* end of Memory Management Subsytem Testcase */
+
+/* Tmpfs Testcase */
+
+/* end of Tmpfs Testcase */
+
+/* SMP-Call Testcase */
+
+#define UTEST_SMP_CALL_FUNC
+/* end of SMP-Call Testcase */
+/* end of RT-Thread Utestcases */
+
+/* RT-Thread online packages */
+
+/* IoT - internet of things */
+
+
+/* Wi-Fi */
+
+/* Marvell WiFi */
+
+/* end of Marvell WiFi */
+
+/* Wiced WiFi */
+
+/* end of Wiced WiFi */
+
+/* CYW43012 WiFi */
+
+/* end of CYW43012 WiFi */
+
+/* BL808 WiFi */
+
+/* end of BL808 WiFi */
+
+/* CYW43439 WiFi */
+
+/* end of CYW43439 WiFi */
+/* end of Wi-Fi */
+
+/* IoT Cloud */
+
+/* end of IoT Cloud */
+/* end of IoT - internet of things */
+
+/* security packages */
+
+/* end of security packages */
+
+/* language packages */
+
+/* JSON: JavaScript Object Notation, a lightweight data-interchange format */
+
+/* end of JSON: JavaScript Object Notation, a lightweight data-interchange format */
+
+/* XML: Extensible Markup Language */
+
+/* end of XML: Extensible Markup Language */
+/* end of language packages */
+
+/* multimedia packages */
+
+/* LVGL: powerful and easy-to-use embedded GUI library */
+
+/* end of LVGL: powerful and easy-to-use embedded GUI library */
+
+/* u8g2: a monochrome graphic library */
+
+/* end of u8g2: a monochrome graphic library */
+/* end of multimedia packages */
+
+/* tools packages */
+
+/* end of tools packages */
+
+/* system packages */
+
+/* enhanced kernel services */
+
+/* end of enhanced kernel services */
+
+/* acceleration: Assembly language or algorithmic acceleration packages */
+
+/* end of acceleration: Assembly language or algorithmic acceleration packages */
+
+/* CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
+
+/* end of CMSIS: ARM Cortex-M Microcontroller Software Interface Standard */
+
+/* Micrium: Micrium software products porting for RT-Thread */
+
+/* end of Micrium: Micrium software products porting for RT-Thread */
+/* end of system packages */
+
+/* peripheral libraries and drivers */
+
+/* HAL & SDK Drivers */
+
+/* STM32 HAL & SDK Drivers */
+
+/* end of STM32 HAL & SDK Drivers */
+
+/* Kendryte SDK */
+
+/* end of Kendryte SDK */
+/* end of HAL & SDK Drivers */
+
+/* sensors drivers */
+
+/* end of sensors drivers */
+
+/* touch drivers */
+
+/* end of touch drivers */
+/* end of peripheral libraries and drivers */
+
+/* AI packages */
+
+/* end of AI packages */
+
+/* Signal Processing and Control Algorithm Packages */
+
+/* end of Signal Processing and Control Algorithm Packages */
+
+/* miscellaneous packages */
+
+/* project laboratory */
+
+/* end of project laboratory */
+
+/* samples: kernel and components samples */
+
+/* end of samples: kernel and components samples */
+
+/* entertainment: terminal games and other interesting software packages */
+
+/* end of entertainment: terminal games and other interesting software packages */
+#define PKG_USING_ZLIB
+#define PKG_USING_ZLIB_LATEST_VERSION
+/* end of miscellaneous packages */
+
+/* Arduino libraries */
+
+
+/* Projects and Demos */
+
+/* end of Projects and Demos */
+
+/* Sensors */
+
+/* end of Sensors */
+
+/* Display */
+
+/* end of Display */
+
+/* Timing */
+
+/* end of Timing */
+
+/* Data Processing */
+
+/* end of Data Processing */
+
+/* Data Storage */
+
+/* Communication */
+
+/* end of Communication */
+
+/* Device Control */
+
+/* end of Device Control */
+
+/* Other */
+
+/* end of Other */
+
+/* Signal IO */
+
+/* end of Signal IO */
+
+/* Uncategorized */
+
+/* end of Arduino libraries */
+/* end of RT-Thread online packages */
+
+/* Privated Packages of RealThread */
+
+
+/* Network Utilities */
+
+/* end of Network Utilities */
+
+/* RT-Thread Smart */
+
+/* end of RT-Thread Smart */
+/* end of Privated Packages of RealThread */
+
+/* RT-Thread rockchip RK3500 drivers */
+
+#define RT_CLK_ROCKCHIP
+#define RT_CLK_ROCKCHIP_RK3568
+#define RT_CLK_ROCKCHIP_RK3588
+#define RT_SERIAL_8250
+#define RT_USING_RESET
+#define RT_HWTIMER_ROCKCHIP
+/* end of RT-Thread rockchip RK3500 drivers */
+#define SOC_RK3568
+
+#endif

+ 57 - 0
bsp/rockchip/rk3500/rtconfig.py

@@ -0,0 +1,57 @@
+import os
+
+# toolchains options
+ARCH        ='aarch64'
+CPU         ='cortex-a'
+CROSS_TOOL  ='gcc'
+
+if os.getenv('RTT_ROOT'):
+    RTT_ROOT = os.getenv('RTT_ROOT')
+else:
+    RTT_ROOT = os.path.join(os.getcwd(), '..', '..', '..')
+
+if os.getenv('RTT_CC'):
+    CROSS_TOOL = os.getenv('RTT_CC')
+
+PLATFORM    = 'gcc'
+EXEC_PATH   = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/'
+
+EXEC_PATH   = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
+
+BUILD = 'release'
+
+if PLATFORM == 'gcc':
+    # toolchains
+    PREFIX  = os.getenv('RTT_CC_PREFIX') or 'aarch64-none-elf-'
+    CC      = PREFIX + 'gcc'
+    CXX     = PREFIX + 'g++'
+    CPP     = PREFIX + 'cpp'
+    AS      = PREFIX + 'gcc'
+    AR      = PREFIX + 'ar'
+    LINK    = PREFIX + 'gcc'
+    TARGET_EXT = 'elf'
+    SIZE    = PREFIX + 'size'
+    OBJDUMP = PREFIX + 'objdump'
+    OBJCPY  = PREFIX + 'objcopy'
+
+    DEVICE = ' -g -march=armv8.2-a -mtune=cortex-a55 -fdiagnostics-color=always'
+    CPPFLAGS= ' -E -P -x assembler-with-cpp'
+    CFLAGS = DEVICE + ' -Wall -Wno-cpp'
+    AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__'
+    LFLAGS  = DEVICE + ' -nostartfiles -Wl,--no-warn-rwx-segments -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds'
+    CPATH   = ''
+    LPATH   = ''
+
+    if BUILD == 'debug':
+        CFLAGS += ' -O0 -ggdb'
+        CPPFLAGS += ' -O0 -ggdb'
+        AFLAGS += ' -ggdb'
+    else:
+        CFLAGS += ' -O2 -ggdb'
+        CPPFLAGS += ' -O2 -ggdb'
+
+    CXXFLAGS = CFLAGS
+
+DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtt.asm\n'
+POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
+POST_ACTION += 'md5sum rtthread.bin\n'