From 2092760d652ad676d7b0c17e416f5091afac1a0e Mon Sep 17 00:00:00 2001 From: GuEe-GUI <2991707448@qq.com> Date: Mon, 5 Jan 2026 17:19:12 +0800 Subject: [PATCH] [bsp][rockchip] Port to DM RK3588/RK3576/RK356x/RK3308 Signed-off-by: GuEe-GUI <2991707448@qq.com> --- bsp/README.md | 26 +- bsp/rockchip/dm/Kconfig | 24 + bsp/rockchip/{rk3568 => dm}/SConscript | 3 +- bsp/rockchip/dm/adc/Kconfig | 6 + bsp/rockchip/dm/adc/SConscript | 14 + bsp/rockchip/dm/adc/adc-rockchip_saradc.c | 527 ++ bsp/rockchip/dm/can/Kconfig | 7 + bsp/rockchip/dm/can/SConscript | 12 + bsp/rockchip/dm/can/canfd-rockchip.c | 1061 +++ bsp/rockchip/dm/clk/Kconfig | 36 + bsp/rockchip/dm/clk/SConscript | 33 + bsp/rockchip/dm/clk/clk-link.c | 210 + bsp/rockchip/dm/clk/clk-rk-composite.c | 51 + bsp/rockchip/dm/clk/clk-rk-composite.h | 191 + bsp/rockchip/dm/clk/clk-rk-cpu.c | 278 + bsp/rockchip/dm/clk/clk-rk-cpu.h | 87 + bsp/rockchip/dm/clk/clk-rk-divider.c | 595 ++ bsp/rockchip/dm/clk/clk-rk-divider.h | 52 + bsp/rockchip/dm/clk/clk-rk-factor.c | 61 + bsp/rockchip/dm/clk/clk-rk-factor.h | 63 + bsp/rockchip/dm/clk/clk-rk-fraction-divider.c | 370 + bsp/rockchip/dm/clk/clk-rk-fraction-divider.h | 95 + bsp/rockchip/dm/clk/clk-rk-gate.c | 109 + bsp/rockchip/dm/clk/clk-rk-gate.h | 32 + bsp/rockchip/dm/clk/clk-rk-half-divider.c | 182 + bsp/rockchip/dm/clk/clk-rk-half-divider.h | 126 + .../clk/clk-rk-mmc-phase.c} | 87 +- bsp/rockchip/dm/clk/clk-rk-mmc-phase.h | 48 + bsp/rockchip/dm/clk/clk-rk-mux.c | 159 + bsp/rockchip/dm/clk/clk-rk-mux.h | 57 + bsp/rockchip/dm/clk/clk-rk-muxgrf.c | 85 + bsp/rockchip/dm/clk/clk-rk-muxgrf.h | 50 + bsp/rockchip/dm/clk/clk-rk-pll.c | 1546 ++++ bsp/rockchip/dm/clk/clk-rk-pll.h | 144 + bsp/rockchip/dm/clk/clk-rk.c | 169 + bsp/rockchip/dm/clk/clk-rk.h | 107 + bsp/rockchip/dm/clk/clk-rk3308.c | 950 ++ bsp/rockchip/dm/clk/clk-rk3568.c | 1488 +++ bsp/rockchip/dm/clk/clk-rk3576.c | 1839 ++++ bsp/rockchip/dm/clk/clk-rk3588.c | 2166 +++++ bsp/rockchip/dm/clk/clk-rk8xx-clkout.c | 203 + .../{rk3500/driver => dm}/clk/softrst.c | 49 +- bsp/rockchip/dm/hwcrypto/Kconfig | 5 + .../uart8250 => dm/hwcrypto}/SConscript | 11 +- bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c | 565 ++ bsp/rockchip/dm/hwspinlock/Kconfig | 3 + bsp/rockchip/dm/hwspinlock/SConscript | 12 + .../dm/hwspinlock/hwspinlock-rockchip.c | 135 + .../{rk3500/driver => dm}/hwtimer/Kconfig | 2 - .../{rk3500/driver => dm}/hwtimer/SConscript | 7 +- .../hwtimer/hwtimer-rockchip_timer.c | 180 +- bsp/rockchip/dm/i2c/Kconfig | 5 + bsp/rockchip/dm/i2c/SConscript | 12 + bsp/rockchip/dm/i2c/i2c-rk3x.c | 1375 +++ .../dm/include/dt-bindings/clock/rk3308-cru.h | 387 + .../include/dt-bindings/clock}/rk3568-cru.h | 8 +- .../dm/include/dt-bindings/clock/rk3576-cru.h | 1151 +++ .../include/dt-bindings/clock}/rk3588-cru.h | 12 +- .../dt-bindings/phye/phye-snps-pcie3.h | 22 + .../dm/include/dt-bindings/pinctrl/rockchip.h | 232 + .../dm/include/dt-bindings/power/px30-power.h | 32 + .../include/dt-bindings/power/rk1808-power.h | 25 + .../include/dt-bindings/power/rk3036-power.h | 18 + .../include/dt-bindings/power/rk3066-power.h | 27 + .../include/dt-bindings/power/rk3128-power.h | 19 + .../include/dt-bindings/power/rk3188-power.h | 29 + .../include/dt-bindings/power/rk3228-power.h | 22 + .../include/dt-bindings/power/rk3288-power.h | 33 + .../include/dt-bindings/power/rk3328-power.h | 21 + .../include/dt-bindings/power/rk3366-power.h | 30 + .../include/dt-bindings/power/rk3368-power.h | 34 + .../include/dt-bindings/power/rk3399-power.h | 59 + .../include/dt-bindings/power/rk3528-power.h | 23 + .../include/dt-bindings/power/rk3562-power.h | 37 + .../include/dt-bindings/power/rk3568-power.h | 37 + .../include/dt-bindings/power/rk3576-power.h | 35 + .../include/dt-bindings/power/rk3588-power.h | 74 + .../include/dt-bindings/power/rv1126-power.h | 39 + bsp/rockchip/dm/include/hw-decompress.h | 40 + bsp/rockchip/dm/include/pinctrl-rockchip.h | 183 + bsp/rockchip/dm/include/rk8xx.h | 912 ++ bsp/rockchip/dm/include/rockchip.h | 86 + bsp/rockchip/dm/input/SConscript | 13 + bsp/rockchip/dm/input/misc/Kconfig | 5 + bsp/rockchip/dm/input/misc/SConscript | 13 + bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c | 115 + bsp/rockchip/dm/mailbox/Kconfig | 3 + bsp/rockchip/dm/mailbox/SConscript | 12 + bsp/rockchip/dm/mailbox/mailbox-rockchip.c | 575 ++ bsp/rockchip/dm/mfd/Kconfig | 19 + bsp/rockchip/dm/mfd/SConscript | 18 + bsp/rockchip/dm/mfd/rk8xx-i2c.c | 187 + bsp/rockchip/dm/mfd/rk8xx-spi.c | 148 + bsp/rockchip/dm/mfd/rk8xx.c | 1088 +++ bsp/rockchip/dm/nvmem/Kconfig | 3 + bsp/rockchip/dm/nvmem/SConscript | 12 + bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c | 1037 +++ bsp/rockchip/dm/pci/Kconfig | 11 + bsp/rockchip/dm/pci/SConscript | 15 + bsp/rockchip/dm/pci/pcie-dw-rockchip.c | 1645 ++++ bsp/rockchip/dm/phye/Kconfig | 9 + bsp/rockchip/dm/phye/SConscript | 15 + bsp/rockchip/dm/phye/phye-naneng-combphy.c | 1482 +++ bsp/rockchip/dm/phye/phye-snps-pcie3.c | 432 + bsp/rockchip/dm/phye/phye-snps-pcie3.fw | 8192 +++++++++++++++++ bsp/rockchip/dm/pin/Kconfig | 4 + bsp/rockchip/dm/pin/SConscript | 13 + bsp/rockchip/dm/pin/pin-rockchip.c | 596 ++ bsp/rockchip/dm/pinctrl/Kconfig | 11 + bsp/rockchip/dm/pinctrl/SConscript | 16 + bsp/rockchip/dm/pinctrl/pinctrl-rk8xx.c | 392 + bsp/rockchip/dm/pinctrl/pinctrl-rockchip.c | 1763 ++++ bsp/rockchip/dm/pmdomain/Kconfig | 6 + bsp/rockchip/dm/pmdomain/SConscript | 12 + bsp/rockchip/dm/pmdomain/pm-domain-rockchip.c | 1878 ++++ bsp/rockchip/dm/pwm/Kconfig | 5 + bsp/rockchip/dm/pwm/SConscript | 14 + bsp/rockchip/dm/pwm/pwm-rockchip.c | 613 ++ bsp/rockchip/dm/regulator/Kconfig | 5 + bsp/rockchip/dm/regulator/SConscript | 12 + bsp/rockchip/dm/regulator/regulator-rk8xx.c | 1236 +++ bsp/rockchip/dm/rtc/Kconfig | 7 + bsp/rockchip/dm/rtc/SConscript | 16 + bsp/rockchip/dm/rtc/rtc-rk8xx.c | 424 + bsp/rockchip/dm/rtc/rtc-rk_timer.c | 397 + bsp/rockchip/dm/sdio/Kconfig | 5 + bsp/rockchip/dm/sdio/SConscript | 12 + bsp/rockchip/dm/sdio/sdio-dw_rockchip.c | 461 + bsp/rockchip/dm/soc/Kconfig | 19 + bsp/rockchip/dm/soc/SConscript | 22 + .../driver/uart8250 => dm/soc}/fiq-debugger.c | 27 +- bsp/rockchip/dm/soc/grf.c | 311 + bsp/rockchip/dm/soc/hw-decompress.c | 392 + bsp/rockchip/dm/soc/io-domain.c | 698 ++ bsp/rockchip/dm/spi/Kconfig | 18 + bsp/rockchip/dm/spi/SConscript | 16 + bsp/rockchip/dm/spi/spi-rockchip-sfc.c | 1004 ++ bsp/rockchip/dm/spi/spi-rockchip.c | 1295 +++ bsp/rockchip/dm/thermal/Kconfig | 6 + bsp/rockchip/dm/thermal/SConscript | 13 + .../dm/thermal/thermal-rockchip_tsadc.c | 1695 ++++ bsp/rockchip/dm/watchdog/Kconfig | 3 + bsp/rockchip/dm/watchdog/SConscript | 13 + bsp/rockchip/dm/watchdog/watchdog-rk8xx.c | 188 + bsp/rockchip/{rk3568 => rk3300}/.config | 348 +- bsp/rockchip/{rk3568 => rk3300}/Kconfig | 12 +- bsp/rockchip/rk3300/README.md | 55 + bsp/rockchip/rk3300/README_ZH.md | 56 + bsp/rockchip/rk3300/SConscript | 16 + bsp/rockchip/{rk3568 => rk3300}/SConstruct | 0 .../applications/SConscript | 0 bsp/rockchip/rk3300/applications/main.c | 31 + .../{rk3568 => rk3300}/driver/SConscript | 0 .../drv_uart.h => rk3300/driver/board.c} | 13 +- .../main.c => rk3300/driver/board.h} | 10 +- bsp/rockchip/{rk3568 => rk3300}/rtconfig.h | 195 +- bsp/rockchip/{rk3568 => rk3300}/rtconfig.py | 9 +- bsp/rockchip/rk3500/.config | 67 +- bsp/rockchip/rk3500/Kconfig | 29 +- bsp/rockchip/rk3500/README.md | 74 +- bsp/rockchip/rk3500/README_ZH.md | 65 +- bsp/rockchip/rk3500/SConscript | 2 + bsp/rockchip/rk3500/driver/Kconfig | 6 - bsp/rockchip/rk3500/driver/board.c | 23 +- bsp/rockchip/rk3500/driver/board.h | 9 - bsp/rockchip/rk3500/driver/clk/Kconfig | 15 - bsp/rockchip/rk3500/driver/clk/SConscript | 16 - .../rk3500/driver/clk/clk-pll-rk3568.c | 403 - .../rk3500/driver/clk/clk-pll-rk3588.c | 727 -- bsp/rockchip/rk3500/driver/clk/clk-rk3568.c | 4791 ---------- bsp/rockchip/rk3500/driver/clk/clk-rk3568.h | 116 - bsp/rockchip/rk3500/driver/clk/clk-rk3588.c | 3292 ------- bsp/rockchip/rk3500/driver/clk/clk-rk3588.h | 151 - bsp/rockchip/rk3500/driver/rockchip.h | 22 - bsp/rockchip/rk3500/driver/uart8250/8250-dw.c | 341 - bsp/rockchip/rk3500/driver/uart8250/8250.h | 74 - bsp/rockchip/rk3500/driver/uart8250/Kconfig | 3 - bsp/rockchip/rk3500/driver/uart8250/core.c | 303 - bsp/rockchip/rk3500/driver/uart8250/early.c | 162 - bsp/rockchip/rk3500/driver/uart8250/regs.h | 365 - .../rk3500/driver/uart8250/serial_dm.h | 29 - bsp/rockchip/rk3500/rtconfig.h | 36 +- bsp/rockchip/rk3500/rtconfig.py | 4 +- bsp/rockchip/rk3568/README.md | 55 - bsp/rockchip/rk3568/README_zh.md | 58 - bsp/rockchip/rk3568/driver/Kconfig | 59 - bsp/rockchip/rk3568/driver/board.c | 179 - bsp/rockchip/rk3568/driver/board.h | 27 - bsp/rockchip/rk3568/driver/drv_uart.c | 366 - bsp/rockchip/rk3568/driver/rk3568.h | 122 - bsp/rockchip/rk3568/link.lds | 146 - 191 files changed, 48516 insertions(+), 12370 deletions(-) create mode 100755 bsp/rockchip/dm/Kconfig rename bsp/rockchip/{rk3568 => dm}/SConscript (84%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/adc/Kconfig create mode 100755 bsp/rockchip/dm/adc/SConscript create mode 100755 bsp/rockchip/dm/adc/adc-rockchip_saradc.c create mode 100755 bsp/rockchip/dm/can/Kconfig create mode 100755 bsp/rockchip/dm/can/SConscript create mode 100755 bsp/rockchip/dm/can/canfd-rockchip.c create mode 100755 bsp/rockchip/dm/clk/Kconfig create mode 100755 bsp/rockchip/dm/clk/SConscript create mode 100755 bsp/rockchip/dm/clk/clk-link.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-composite.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-composite.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-cpu.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-cpu.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-divider.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-divider.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-factor.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-factor.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-fraction-divider.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-fraction-divider.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-gate.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-gate.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-half-divider.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-half-divider.h rename bsp/rockchip/{rk3500/driver/clk/clk-mmc-phase.c => dm/clk/clk-rk-mmc-phase.c} (54%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/clk/clk-rk-mmc-phase.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-mux.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-mux.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-muxgrf.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-muxgrf.h create mode 100755 bsp/rockchip/dm/clk/clk-rk-pll.c create mode 100755 bsp/rockchip/dm/clk/clk-rk-pll.h create mode 100755 bsp/rockchip/dm/clk/clk-rk.c create mode 100755 bsp/rockchip/dm/clk/clk-rk.h create mode 100755 bsp/rockchip/dm/clk/clk-rk3308.c create mode 100755 bsp/rockchip/dm/clk/clk-rk3568.c create mode 100755 bsp/rockchip/dm/clk/clk-rk3576.c create mode 100755 bsp/rockchip/dm/clk/clk-rk3588.c create mode 100755 bsp/rockchip/dm/clk/clk-rk8xx-clkout.c rename bsp/rockchip/{rk3500/driver => dm}/clk/softrst.c (69%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/hwcrypto/Kconfig rename bsp/rockchip/{rk3500/driver/uart8250 => dm/hwcrypto}/SConscript (51%) create mode 100755 bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c create mode 100755 bsp/rockchip/dm/hwspinlock/Kconfig create mode 100755 bsp/rockchip/dm/hwspinlock/SConscript create mode 100755 bsp/rockchip/dm/hwspinlock/hwspinlock-rockchip.c rename bsp/rockchip/{rk3500/driver => dm}/hwtimer/Kconfig (53%) rename bsp/rockchip/{rk3500/driver => dm}/hwtimer/SConscript (73%) mode change 100644 => 100755 rename bsp/rockchip/{rk3500/driver => dm}/hwtimer/hwtimer-rockchip_timer.c (67%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/i2c/Kconfig create mode 100755 bsp/rockchip/dm/i2c/SConscript create mode 100755 bsp/rockchip/dm/i2c/i2c-rk3x.c create mode 100755 bsp/rockchip/dm/include/dt-bindings/clock/rk3308-cru.h rename bsp/rockchip/{rk3500/driver/clk => dm/include/dt-bindings/clock}/rk3568-cru.h (99%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/include/dt-bindings/clock/rk3576-cru.h rename bsp/rockchip/{rk3500/driver/clk => dm/include/dt-bindings/clock}/rk3588-cru.h (99%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/include/dt-bindings/phye/phye-snps-pcie3.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/pinctrl/rockchip.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/px30-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk1808-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3036-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3066-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3128-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3188-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3228-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3288-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3328-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3366-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3368-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3399-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3528-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3562-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3568-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3576-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rk3588-power.h create mode 100755 bsp/rockchip/dm/include/dt-bindings/power/rv1126-power.h create mode 100755 bsp/rockchip/dm/include/hw-decompress.h create mode 100755 bsp/rockchip/dm/include/pinctrl-rockchip.h create mode 100755 bsp/rockchip/dm/include/rk8xx.h create mode 100755 bsp/rockchip/dm/include/rockchip.h create mode 100755 bsp/rockchip/dm/input/SConscript create mode 100755 bsp/rockchip/dm/input/misc/Kconfig create mode 100755 bsp/rockchip/dm/input/misc/SConscript create mode 100755 bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c create mode 100755 bsp/rockchip/dm/mailbox/Kconfig create mode 100755 bsp/rockchip/dm/mailbox/SConscript create mode 100755 bsp/rockchip/dm/mailbox/mailbox-rockchip.c create mode 100755 bsp/rockchip/dm/mfd/Kconfig create mode 100755 bsp/rockchip/dm/mfd/SConscript create mode 100755 bsp/rockchip/dm/mfd/rk8xx-i2c.c create mode 100755 bsp/rockchip/dm/mfd/rk8xx-spi.c create mode 100755 bsp/rockchip/dm/mfd/rk8xx.c create mode 100755 bsp/rockchip/dm/nvmem/Kconfig create mode 100755 bsp/rockchip/dm/nvmem/SConscript create mode 100755 bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c create mode 100755 bsp/rockchip/dm/pci/Kconfig create mode 100755 bsp/rockchip/dm/pci/SConscript create mode 100755 bsp/rockchip/dm/pci/pcie-dw-rockchip.c create mode 100755 bsp/rockchip/dm/phye/Kconfig create mode 100755 bsp/rockchip/dm/phye/SConscript create mode 100755 bsp/rockchip/dm/phye/phye-naneng-combphy.c create mode 100755 bsp/rockchip/dm/phye/phye-snps-pcie3.c create mode 100755 bsp/rockchip/dm/phye/phye-snps-pcie3.fw create mode 100755 bsp/rockchip/dm/pin/Kconfig create mode 100755 bsp/rockchip/dm/pin/SConscript create mode 100755 bsp/rockchip/dm/pin/pin-rockchip.c create mode 100755 bsp/rockchip/dm/pinctrl/Kconfig create mode 100755 bsp/rockchip/dm/pinctrl/SConscript create mode 100755 bsp/rockchip/dm/pinctrl/pinctrl-rk8xx.c create mode 100755 bsp/rockchip/dm/pinctrl/pinctrl-rockchip.c create mode 100755 bsp/rockchip/dm/pmdomain/Kconfig create mode 100755 bsp/rockchip/dm/pmdomain/SConscript create mode 100755 bsp/rockchip/dm/pmdomain/pm-domain-rockchip.c create mode 100755 bsp/rockchip/dm/pwm/Kconfig create mode 100755 bsp/rockchip/dm/pwm/SConscript create mode 100755 bsp/rockchip/dm/pwm/pwm-rockchip.c create mode 100755 bsp/rockchip/dm/regulator/Kconfig create mode 100755 bsp/rockchip/dm/regulator/SConscript create mode 100755 bsp/rockchip/dm/regulator/regulator-rk8xx.c create mode 100755 bsp/rockchip/dm/rtc/Kconfig create mode 100755 bsp/rockchip/dm/rtc/SConscript create mode 100755 bsp/rockchip/dm/rtc/rtc-rk8xx.c create mode 100755 bsp/rockchip/dm/rtc/rtc-rk_timer.c create mode 100755 bsp/rockchip/dm/sdio/Kconfig create mode 100755 bsp/rockchip/dm/sdio/SConscript create mode 100755 bsp/rockchip/dm/sdio/sdio-dw_rockchip.c create mode 100755 bsp/rockchip/dm/soc/Kconfig create mode 100755 bsp/rockchip/dm/soc/SConscript rename bsp/rockchip/{rk3500/driver/uart8250 => dm/soc}/fiq-debugger.c (94%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/dm/soc/grf.c create mode 100755 bsp/rockchip/dm/soc/hw-decompress.c create mode 100755 bsp/rockchip/dm/soc/io-domain.c create mode 100755 bsp/rockchip/dm/spi/Kconfig create mode 100755 bsp/rockchip/dm/spi/SConscript create mode 100755 bsp/rockchip/dm/spi/spi-rockchip-sfc.c create mode 100755 bsp/rockchip/dm/spi/spi-rockchip.c create mode 100755 bsp/rockchip/dm/thermal/Kconfig create mode 100755 bsp/rockchip/dm/thermal/SConscript create mode 100755 bsp/rockchip/dm/thermal/thermal-rockchip_tsadc.c create mode 100755 bsp/rockchip/dm/watchdog/Kconfig create mode 100755 bsp/rockchip/dm/watchdog/SConscript create mode 100755 bsp/rockchip/dm/watchdog/watchdog-rk8xx.c rename bsp/rockchip/{rk3568 => rk3300}/.config (85%) rename bsp/rockchip/{rk3568 => rk3300}/Kconfig (63%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/rk3300/README.md create mode 100755 bsp/rockchip/rk3300/README_ZH.md create mode 100755 bsp/rockchip/rk3300/SConscript rename bsp/rockchip/{rk3568 => rk3300}/SConstruct (100%) mode change 100644 => 100755 rename bsp/rockchip/{rk3568 => rk3300}/applications/SConscript (100%) mode change 100644 => 100755 create mode 100755 bsp/rockchip/rk3300/applications/main.c rename bsp/rockchip/{rk3568 => rk3300}/driver/SConscript (100%) mode change 100644 => 100755 rename bsp/rockchip/{rk3568/driver/drv_uart.h => rk3300/driver/board.c} (51%) mode change 100644 => 100755 rename bsp/rockchip/{rk3568/applications/main.c => rk3300/driver/board.h} (64%) mode change 100644 => 100755 rename bsp/rockchip/{rk3568 => rk3300}/rtconfig.h (66%) mode change 100644 => 100755 rename bsp/rockchip/{rk3568 => rk3300}/rtconfig.py (76%) mode change 100644 => 100755 delete mode 100644 bsp/rockchip/rk3500/driver/Kconfig delete mode 100644 bsp/rockchip/rk3500/driver/clk/Kconfig delete mode 100644 bsp/rockchip/rk3500/driver/clk/SConscript delete mode 100644 bsp/rockchip/rk3500/driver/clk/clk-pll-rk3568.c delete mode 100644 bsp/rockchip/rk3500/driver/clk/clk-pll-rk3588.c delete mode 100644 bsp/rockchip/rk3500/driver/clk/clk-rk3568.c delete mode 100644 bsp/rockchip/rk3500/driver/clk/clk-rk3568.h delete mode 100644 bsp/rockchip/rk3500/driver/clk/clk-rk3588.c delete mode 100644 bsp/rockchip/rk3500/driver/clk/clk-rk3588.h delete mode 100644 bsp/rockchip/rk3500/driver/rockchip.h delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/8250-dw.c delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/8250.h delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/Kconfig delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/core.c delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/early.c delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/regs.h delete mode 100644 bsp/rockchip/rk3500/driver/uart8250/serial_dm.h delete mode 100644 bsp/rockchip/rk3568/README.md delete mode 100644 bsp/rockchip/rk3568/README_zh.md delete mode 100644 bsp/rockchip/rk3568/driver/Kconfig delete mode 100644 bsp/rockchip/rk3568/driver/board.c delete mode 100644 bsp/rockchip/rk3568/driver/board.h delete mode 100644 bsp/rockchip/rk3568/driver/drv_uart.c delete mode 100644 bsp/rockchip/rk3568/driver/rk3568.h delete mode 100644 bsp/rockchip/rk3568/link.lds diff --git a/bsp/README.md b/bsp/README.md index a36d8209dc3..018b3701684 100644 --- a/bsp/README.md +++ b/bsp/README.md @@ -342,11 +342,11 @@ This document is based on the RT-Thread mainline repository and categorizes the #### 🟡 Rockchip -| BSP Name | GPIO | UART | ADC | I2C | SPI | WDT | -|----------|------|------|-----|-----|-----|-----| -| [rk2108](rockchip/rk2108) | - | ✅ | - | - | - | - | -| [rk3500](rockchip/rk3500) | - | ✅ | - | - | - | - | -| [rk3568](rockchip/rk3568) | - | ✅ | - | - | - | - | +| BSP Name | GPIO | UART | ADC | I2C | SPI | WDT | HWTimer | PWM | RTC | SDIO | CAN | PCI | +|----------|------|------|-----|-----|-----|-----|---------|-----|-----|------|-----|------| +| [rk2108](rockchip/rk2108) | - | ✅ | - | - | - | - | - | - | - | - | - | - | +| [rk3300](rockchip/rk3300) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | +| [rk3500](rockchip/rk3500) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | #### 🟡 APM32 @@ -417,22 +417,22 @@ This document is based on the RT-Thread mainline repository and categorizes the | [swm320-mini](synwit/swm320-mini) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | [swm341-mini](synwit/swm341-mini) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -#### ⚪ N32G452xx +#### ⚪ N32G452xx | BSP Name | GPIO | UART | ADC | CAN | DAC | Flash | HWTimer | I2C | PWM | RTC | SDIO | SPI | WDT | |----------|------|------|-----|-----|-----|-------|---------|-----|-----|-----|------|-----|-----| | [n32g452xx-mini-system](n32g452xx/n32g452xx-mini-system) | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | ✅ | - | ✅ | ✅ | ✅ | -#### ⚪ W60x +#### ⚪ W60x | BSP Name | GPIO | UART | ADC | Crypto | Flash | HWTimer | WDT | PWM | I2C | SPI | |----------|------|------|-----|--------|-------|---------|-----|-----|-----|-----| | [w60x](w60x) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -#### ⚪ Allwinner Tina +#### ⚪ Allwinner Tina | BSP Name | GPIO | UART | SPI | SDIO | |----------|------|------|-----|------| | [allwinner_tina](allwinner_tina) | ✅ | ✅ | ✅ | ✅ | -#### ⚪ HC321136 +#### ⚪ HC321136 | BSP Name | GPIO | UART | I2C | |----------|------|------|-----| | [hc321136](hc32/hc321136) | ✅ | ✅ | ✅ | @@ -442,7 +442,7 @@ This document is based on the RT-Thread mainline repository and categorizes the |----------|------|------| | [hc321196](hc32/hc321196) | ✅ | ✅ | -#### ⚪ Amebaz +#### ⚪ Amebaz | BSP Name | GPIO | UART | WLAN | |----------|------|------|------| | [amebaz](amebaz) | - | ✅ | ✅ | @@ -839,17 +839,17 @@ This document is based on the RT-Thread mainline repository and categorizes the |----------|------|------|-----|-------|---------|------|-----|-----|------|----------|-----| | [ab32vg1-ab-prougen](bluetrum/ab32vg1-ab-prougen) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -#### ⚪ Core-V-MCU +#### ⚪ Core-V-MCU | BSP Name | UART | |----------|------| | [core-v-cv32e40p](core-v-mcu/core-v-cv32e40p) | ✅ | -#### ⚪ HiFive1 +#### ⚪ HiFive1 | BSP Name | GPIO | UART | |----------|------|------| | [hifive1](hifive1) | ✅ | ✅ | -#### ⚪ Sparkfun-RedV +#### ⚪ Sparkfun-RedV | BSP Name | GPIO | UART | ADC | I2C | SPI | WDT | Timer | PWM | RTC | |----------|------|------|-----|-----|-----|-----|-------|-----|-----| | [sparkfun-redv](sparkfun-redv) | ✅ | ✅ | - | - | - | - | ✅ | - | - | diff --git a/bsp/rockchip/dm/Kconfig b/bsp/rockchip/dm/Kconfig new file mode 100755 index 00000000000..53eca977c9d --- /dev/null +++ b/bsp/rockchip/dm/Kconfig @@ -0,0 +1,24 @@ +SOC_DM_ADC_DIR = $(SOC_DM_DIR)/adc +SOC_DM_CAN_DIR = $(SOC_DM_DIR)/can +SOC_DM_CLK_DIR = $(SOC_DM_DIR)/clk +SOC_DM_HWCRYPTO_DIR = $(SOC_DM_DIR)/hwcrypto +SOC_DM_HWSPINLOCK_DIR = $(SOC_DM_DIR)/hwspinlock +SOC_DM_HWTIMER_DIR = $(SOC_DM_DIR)/hwtimer +SOC_DM_I2C_DIR = $(SOC_DM_DIR)/i2c +SOC_DM_INPUT_MISC_DIR = $(SOC_DM_DIR)/input/misc +SOC_DM_MBOX_DIR = $(SOC_DM_DIR)/mailbox +SOC_DM_MFD_DIR = $(SOC_DM_DIR)/mfd +SOC_DM_NVMEM_DIR = $(SOC_DM_DIR)/nvmem +SOC_DM_PCI_DIR = $(SOC_DM_DIR)/pci +SOC_DM_PHYE_DIR = $(SOC_DM_DIR)/phye +SOC_DM_PIN_DIR = $(SOC_DM_DIR)/pin +SOC_DM_PINCTRL_DIR = $(SOC_DM_DIR)/pinctrl +SOC_DM_PMDOMAIN_DIR = $(SOC_DM_DIR)/pmdomain +SOC_DM_PWM_DIR = $(SOC_DM_DIR)/pwm +SOC_DM_REGULATOR_DIR = $(SOC_DM_DIR)/regulator +SOC_DM_RTC_DIR = $(SOC_DM_DIR)/rtc +SOC_DM_SDIO_DIR = $(SOC_DM_DIR)/sdio +SOC_DM_SOC_DIR = $(SOC_DM_DIR)/soc +SOC_DM_SPI_DIR = $(SOC_DM_DIR)/spi +SOC_DM_THERMAL_DIR = $(SOC_DM_DIR)/thermal +SOC_DM_WDT_DIR = $(SOC_DM_DIR)/watchdog diff --git a/bsp/rockchip/rk3568/SConscript b/bsp/rockchip/dm/SConscript old mode 100644 new mode 100755 similarity index 84% rename from bsp/rockchip/rk3568/SConscript rename to bsp/rockchip/dm/SConscript index 744d8d78214..3d15055d62d --- a/bsp/rockchip/rk3568/SConscript +++ b/bsp/rockchip/dm/SConscript @@ -1,8 +1,7 @@ -# for module compiling import os from building import * -cwd = GetCurrentDir() +cwd = GetCurrentDir() objs = [] list = os.listdir(cwd) diff --git a/bsp/rockchip/dm/adc/Kconfig b/bsp/rockchip/dm/adc/Kconfig new file mode 100755 index 00000000000..0de59b767c8 --- /dev/null +++ b/bsp/rockchip/dm/adc/Kconfig @@ -0,0 +1,6 @@ +config RT_ADC_ROCKCHIP_SARADC + bool "Rockchip SARADC driver" + depends on RT_USING_ADC + depends on RT_USING_RESET + depends on RT_USING_REGULATOR + default n diff --git a/bsp/rockchip/dm/adc/SConscript b/bsp/rockchip/dm/adc/SConscript new file mode 100755 index 00000000000..a0779ce337d --- /dev/null +++ b/bsp/rockchip/dm/adc/SConscript @@ -0,0 +1,14 @@ +from building import * + +group = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +src = [] + +if GetDepend(['RT_USING_ADC']): + src += ['adc-rockchip_saradc.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/adc/adc-rockchip_saradc.c b/bsp/rockchip/dm/adc/adc-rockchip_saradc.c new file mode 100755 index 00000000000..953b706f24d --- /dev/null +++ b/bsp/rockchip/dm/adc/adc-rockchip_saradc.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +#define SARADC_DATA 0x00 + +#define SARADC_STAS 0x04 +#define SARADC_STAS_BUSY RT_BIT(0) + +#define SARADC_CTRL 0x08 +#define SARADC_CTRL_IRQ_STATUS RT_BIT(6) +#define SARADC_CTRL_IRQ_ENABLE RT_BIT(5) +#define SARADC_CTRL_POWER_CTRL RT_BIT(3) +#define SARADC_CTRL_CHN_MASK 0x7 + +#define SARADC_DLY_PU_SOC 0x0c +#define SARADC_DLY_PU_SOC_MASK 0x3f + +#define SARADC_TIMEOUT rt_tick_from_millisecond(100) +#define SARADC_MAX_CHANNELS 8 + +/* v2 registers */ +#define SARADC2_CONV_CON 0x000 +#define SARADC_T_PD_SOC 0x004 +#define SARADC_T_DAS_SOC 0x00c +#define SARADC2_END_INT_EN 0x104 +#define SARADC2_ST_CON 0x108 +#define SARADC2_STATUS 0x10c +#define SARADC2_END_INT_ST 0x110 +#define SARADC2_DATA_BASE 0x120 + +#define SARADC2_EN_END_INT RT_BIT(0) +#define SARADC2_START RT_BIT(4) +#define SARADC2_SINGLE_MODE RT_BIT(5) + +#define SARADC2_CONV_CHANNELS RT_GENMASK(15, 0) + +struct saradc_channel +{ + int channel; + int scan_index; + + struct + { + char sign; + rt_uint8_t realbits; + rt_uint8_t storagebits; + rt_uint8_t repeat; + } scan_type; + + rt_base_t info_mask_separate; + rt_base_t info_mask_shared_by_type; + + const char *datasheet_name; +}; + +struct rockchip_saradc; + +struct rockchip_saradc_soc_data +{ + const struct saradc_channel *channels; + int num_channels; + + rt_ubase_t clk_rate; + void (*start)(struct rockchip_saradc *rk_saradc, int chn); + int (*read)(struct rockchip_saradc *rk_saradc); + void (*power_down)(struct rockchip_saradc *rk_saradc); +}; + +struct rockchip_saradc +{ + struct rt_adc_device parent; + + int irq; + void *regs; + struct rt_clk *clk; + struct rt_clk *pclk; + struct rt_regulator *vref; + struct rt_reset_control *rstc; + + const struct rockchip_saradc_soc_data *soc_data; + + rt_uint16_t last_val; + struct saradc_channel *last_chan; + + struct rt_mutex lock; + struct rt_completion completion; +}; + +#define raw_to_rockchip_saradc(raw) rt_container_of(raw, struct rockchip_saradc, parent) + +#define SARADC_CHANNEL(INDEX, ID, RES) \ +{ \ + .channel = INDEX, \ + .info_mask_separate = RT_BIT(0), \ + .info_mask_shared_by_type = RT_BIT(2), \ + .datasheet_name = ID, \ + .scan_index = INDEX, \ + .scan_type = \ + { \ + .sign = 'u', \ + .realbits = RES, \ + .storagebits = 16, \ + }, \ +} + +static void rockchip_saradc_start_v1(struct rockchip_saradc *rk_saradc, int chn) +{ + /* 8 clock periods as delay between power up and start cmd */ + HWREG32(rk_saradc->regs + SARADC_DLY_PU_SOC) = 8; + /* Select the channel to be used and trigger conversion */ + HWREG32(rk_saradc->regs + SARADC_CTRL) = SARADC_CTRL_POWER_CTRL | + (chn & SARADC_CTRL_CHN_MASK) | SARADC_CTRL_IRQ_ENABLE; +} + +static void rockchip_saradc_reset_controller(struct rockchip_saradc *rk_saradc); + +static void rockchip_saradc_start_v2(struct rockchip_saradc *rk_saradc, int chn) +{ + int val; + + if (rk_saradc->rstc) + { + rockchip_saradc_reset_controller(rk_saradc); + } + + HWREG32(rk_saradc->regs + SARADC_T_DAS_SOC) = 0xc; + HWREG32(rk_saradc->regs + SARADC_T_PD_SOC) = 0x20; + + val = RT_FIELD_PREP(SARADC2_EN_END_INT, 1); + val |= val << 16; + HWREG32(rk_saradc->regs + SARADC2_END_INT_EN) = val; + + val = RT_FIELD_PREP(SARADC2_START, 1) | + RT_FIELD_PREP(SARADC2_SINGLE_MODE, 1) | + RT_FIELD_PREP(SARADC2_CONV_CHANNELS, chn); + val |= val << 16; + HWREG32(rk_saradc->regs + SARADC2_CONV_CON) = val; +} + +static int rockchip_saradc_read_v1(struct rockchip_saradc *rk_saradc) +{ + return HWREG32(rk_saradc->regs + SARADC_DATA); +} + +static int rockchip_saradc_read_v2(struct rockchip_saradc *rk_saradc) +{ + int offset; + + /* Clear irq */ + HWREG32(rk_saradc->regs + SARADC2_END_INT_ST) = 0x1; + + offset = SARADC2_DATA_BASE + rk_saradc->last_chan->channel * 0x4; + + return HWREG32(rk_saradc->regs + offset); +} + +static void rockchip_saradc_power_down_v1(struct rockchip_saradc *rk_saradc) +{ + HWREG32(rk_saradc->regs + SARADC_CTRL) = 0; +} + +static const struct saradc_channel rockchip_saradc_channels[] = +{ + SARADC_CHANNEL(0, "adc0", 10), + SARADC_CHANNEL(1, "adc1", 10), + SARADC_CHANNEL(2, "adc2", 10), +}; + +static const struct rockchip_saradc_soc_data saradc_data = +{ + .channels = rockchip_saradc_channels, + .num_channels = RT_ARRAY_SIZE(rockchip_saradc_channels), + .clk_rate = 1000000, + .start = rockchip_saradc_start_v1, + .read = rockchip_saradc_read_v1, + .power_down = rockchip_saradc_power_down_v1, +}; + +static const struct saradc_channel rk3066_tsadc_channels[] = +{ + SARADC_CHANNEL(0, "adc0", 12), + SARADC_CHANNEL(1, "adc1", 12), +}; + +static const struct rockchip_saradc_soc_data rk3066_tsadc_data = +{ + .channels = rk3066_tsadc_channels, + .num_channels = RT_ARRAY_SIZE(rk3066_tsadc_channels), + .clk_rate = 50000, + .start = rockchip_saradc_start_v1, + .read = rockchip_saradc_read_v1, + .power_down = rockchip_saradc_power_down_v1, +}; + +static const struct saradc_channel rk3399_saradc_channels[] = +{ + SARADC_CHANNEL(0, "adc0", 10), + SARADC_CHANNEL(1, "adc1", 10), + SARADC_CHANNEL(2, "adc2", 10), + SARADC_CHANNEL(3, "adc3", 10), + SARADC_CHANNEL(4, "adc4", 10), + SARADC_CHANNEL(5, "adc5", 10), +}; + +static const struct rockchip_saradc_soc_data rk3399_saradc_data = +{ + .channels = rk3399_saradc_channels, + .num_channels = RT_ARRAY_SIZE(rk3399_saradc_channels), + .clk_rate = 1000000, + .start = rockchip_saradc_start_v1, + .read = rockchip_saradc_read_v1, + .power_down = rockchip_saradc_power_down_v1, +}; + +static const struct saradc_channel rk3568_saradc_channels[] = +{ + SARADC_CHANNEL(0, "adc0", 10), + SARADC_CHANNEL(1, "adc1", 10), + SARADC_CHANNEL(2, "adc2", 10), + SARADC_CHANNEL(3, "adc3", 10), + SARADC_CHANNEL(4, "adc4", 10), + SARADC_CHANNEL(5, "adc5", 10), + SARADC_CHANNEL(6, "adc6", 10), + SARADC_CHANNEL(7, "adc7", 10), +}; + +static const struct rockchip_saradc_soc_data rk3568_saradc_data = +{ + .channels = rk3568_saradc_channels, + .num_channels = RT_ARRAY_SIZE(rk3568_saradc_channels), + .clk_rate = 1000000, + .start = rockchip_saradc_start_v1, + .read = rockchip_saradc_read_v1, + .power_down = rockchip_saradc_power_down_v1, +}; + +static const struct saradc_channel rk3588_saradc_channels[] = +{ + SARADC_CHANNEL(0, "adc0", 12), + SARADC_CHANNEL(1, "adc1", 12), + SARADC_CHANNEL(2, "adc2", 12), + SARADC_CHANNEL(3, "adc3", 12), + SARADC_CHANNEL(4, "adc4", 12), + SARADC_CHANNEL(5, "adc5", 12), + SARADC_CHANNEL(6, "adc6", 12), + SARADC_CHANNEL(7, "adc7", 12), +}; + +static const struct rockchip_saradc_soc_data rk3588_saradc_data = +{ + .channels = rk3588_saradc_channels, + .num_channels = RT_ARRAY_SIZE(rk3588_saradc_channels), + .clk_rate = 1000000, + .start = rockchip_saradc_start_v2, + .read = rockchip_saradc_read_v2, +}; + +static void rockchip_saradc_start(struct rockchip_saradc *rk_saradc, int chn) +{ + rk_saradc->soc_data->start(rk_saradc, chn); +} + +static int rockchip_saradc_read(struct rockchip_saradc *rk_saradc) +{ + return rk_saradc->soc_data->read(rk_saradc); +} + +static void rockchip_saradc_power_down(struct rockchip_saradc *rk_saradc) +{ + if (rk_saradc->soc_data->power_down) + { + rk_saradc->soc_data->power_down(rk_saradc); + } +} + +static rt_err_t rockchip_saradc_enabled(struct rt_adc_device *adc, rt_int8_t channel, rt_bool_t enabled) +{ + return RT_EOK; +} + +static rt_err_t rockchip_saradc_convert(struct rt_adc_device *adc, rt_int8_t channel, rt_uint32_t *value) +{ + rt_err_t err = RT_EOK; + struct rockchip_saradc *rk_saradc = raw_to_rockchip_saradc(adc); + + rt_mutex_take(&rk_saradc->lock, RT_WAITING_FOREVER); + + rk_saradc->last_chan = (struct saradc_channel *)&rk_saradc->soc_data->channels[channel]; + rockchip_saradc_start(rk_saradc, channel); + + /* Select the channel to be used and trigger conversion */ + HWREG32(rk_saradc->regs + SARADC_CTRL) =SARADC_CTRL_POWER_CTRL | + (channel & SARADC_CTRL_CHN_MASK) | SARADC_CTRL_IRQ_ENABLE; + + /* Delay 100ms */ + if (!(err = rt_completion_wait(&rk_saradc->completion, SARADC_TIMEOUT))) + { + *value = rk_saradc->last_val; + } + + rt_mutex_release(&rk_saradc->lock); + + return err; +} + +static const struct rt_adc_ops rockchip_saradc_ops = +{ + .enabled = rockchip_saradc_enabled, + .convert = rockchip_saradc_convert, +}; + +static void rockchip_saradc_isr(int irqno, void *param) +{ + struct rockchip_saradc *rk_saradc = (struct rockchip_saradc *)param; + + /* Read value */ + rk_saradc->last_val = rockchip_saradc_read(rk_saradc); + rk_saradc->last_val &= RT_GENMASK(rk_saradc->last_chan->scan_type.realbits - 1, 0); + + rockchip_saradc_power_down(rk_saradc); + + rt_completion_done(&rk_saradc->completion); +} + +static void rockchip_saradc_reset_controller(struct rockchip_saradc *rk_saradc) +{ + rt_reset_control_assert(rk_saradc->rstc); + rt_hw_us_delay(15); + rt_reset_control_deassert(rk_saradc->rstc); +} + +static void rockchip_saradc_free(struct rockchip_saradc *rk_saradc) +{ + if (rk_saradc->regs) + { + rt_iounmap(rk_saradc->regs); + } + + if (!rt_is_err_or_null(rk_saradc->rstc)) + { + rt_reset_control_put(rk_saradc->rstc); + } + + if (!rt_is_err_or_null(rk_saradc->vref)) + { + rt_regulator_disable(rk_saradc->vref); + } + + if (!rt_is_err_or_null(rk_saradc->clk)) + { + rt_clk_disable(rk_saradc->clk); + rt_clk_put(rk_saradc->clk); + } + + if (!rt_is_err_or_null(rk_saradc->pclk)) + { + rt_clk_disable(rk_saradc->pclk); + rt_clk_put(rk_saradc->pclk); + } + + rt_free(rk_saradc); +} + +static rt_err_t rockchip_saradc_probe(struct rt_platform_device *pdev) +{ + rt_err_t err = RT_EOK; + const char *dev_name; + struct rt_device *dev = &pdev->parent; + const struct rockchip_saradc_soc_data *soc_data = pdev->id->data; + struct rockchip_saradc *rk_saradc = rt_calloc(1, sizeof(*rk_saradc)); + + if (!rk_saradc) + { + return -RT_ENOMEM; + } + + rk_saradc->soc_data = soc_data; + rk_saradc->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_saradc->regs) + { + err = -RT_EIO; + goto _free_res; + } + + rk_saradc->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_saradc->irq < 0) + { + err = rk_saradc->irq; + goto _free_res; + } + + rk_saradc->vref = rt_regulator_get(dev, "vref"); + + if (rt_is_err(rk_saradc->vref)) + { + err = rt_ptr_err(rk_saradc->vref); + goto _free_res; + } + + rk_saradc->rstc = rt_reset_control_get_by_name(dev, "saradc-apb"); + + if (rt_is_err(rk_saradc->rstc)) + { + err = rt_ptr_err(rk_saradc->rstc); + goto _free_res; + } + + if (rk_saradc->rstc) + { + rockchip_saradc_reset_controller(rk_saradc); + } + + rk_saradc->pclk = rt_clk_get_by_name(dev, "apb_pclk"); + + if (rt_is_err(rk_saradc->pclk)) + { + err = rt_ptr_err(rk_saradc->pclk); + goto _free_res; + } + + if ((err = rt_clk_enable(rk_saradc->pclk))) + { + goto _free_res; + } + + rk_saradc->clk = rt_clk_get_by_name(dev, "saradc"); + + if (rt_is_err(rk_saradc->clk)) + { + err = rt_ptr_err(rk_saradc->clk); + goto _free_res; + } + + if ((err = rt_clk_enable(rk_saradc->clk))) + { + goto _free_res; + } + + if ((err = rt_clk_set_rate(rk_saradc->clk, soc_data->clk_rate))) + { + goto _free_res; + } + + if ((err = rt_regulator_enable(rk_saradc->vref))) + { + goto _free_res; + } + + dev->user_data = rk_saradc; + + rt_dm_dev_set_name_auto(&rk_saradc->parent.parent, "saradc"); + dev_name = rt_dm_dev_get_name(&rk_saradc->parent.parent); + + rt_mutex_init(&rk_saradc->lock, dev_name, RT_IPC_FLAG_PRIO); + rt_completion_init(&rk_saradc->completion); + + rt_hw_adc_register(&rk_saradc->parent, dev_name, &rockchip_saradc_ops, rk_saradc); + rt_hw_interrupt_install(rk_saradc->irq, rockchip_saradc_isr, rk_saradc, dev_name); + rt_hw_interrupt_umask(rk_saradc->irq); + + rt_dm_dev_bind_fwdata(dev, RT_NULL, rk_saradc); + + return RT_EOK; + +_free_res: + rockchip_saradc_free(rk_saradc); + + return err; +} + +static rt_err_t rockchip_saradc_remove(struct rt_platform_device *pdev) +{ + struct rt_device *dev = &pdev->parent; + struct rockchip_saradc *rk_saradc = dev->user_data; + + rt_dm_dev_unbind_fwdata(dev, RT_NULL); + + rt_hw_interrupt_mask(rk_saradc->irq); + rt_pic_detach_irq(rk_saradc->irq, rk_saradc); + + rt_device_unregister(&rk_saradc->parent.parent); + + rockchip_saradc_free(rk_saradc); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_saradc_ofw_ids[] = +{ + { .compatible = "rockchip,saradc", .data = &saradc_data }, + { .compatible = "rockchip,rk3066-tsadc", .data = &rk3066_tsadc_data }, + { .compatible = "rockchip,rk3399-saradc", .data = &rk3399_saradc_data }, + { .compatible = "rockchip,rk3568-saradc", .data = &rk3568_saradc_data }, + { .compatible = "rockchip,rk3588-saradc", .data = &rk3588_saradc_data, }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_saradc_driver = +{ + .name = "rockchip-saradc", + .ids = rockchip_saradc_ofw_ids, + + .probe = rockchip_saradc_probe, + .remove = rockchip_saradc_remove, +}; + +static int rockchip_saradc_register(void) +{ + /* If the regulator is a i2c device, saradc should init later */ + rt_platform_driver_register(&rockchip_saradc_driver); + + return 0; +} +INIT_COMPONENT_EXPORT(rockchip_saradc_register); diff --git a/bsp/rockchip/dm/can/Kconfig b/bsp/rockchip/dm/can/Kconfig new file mode 100755 index 00000000000..138def8647f --- /dev/null +++ b/bsp/rockchip/dm/can/Kconfig @@ -0,0 +1,7 @@ +config RT_CAN_CANFD_ROCKCHIP + bool "Rockchip CANFD controller" + depends on RT_CAN_USING_CANFD + depends on RT_USING_RESET + select RT_USING_DEVICE_IPC + select RT_USING_SYSTEM_WORKQUEUE + default n diff --git a/bsp/rockchip/dm/can/SConscript b/bsp/rockchip/dm/can/SConscript new file mode 100755 index 00000000000..2404af6ccc7 --- /dev/null +++ b/bsp/rockchip/dm/can/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/can'] + +if GetDepend(['RT_CAN_CANFD_ROCKCHIP']): + src += ['canfd-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/can/canfd-rockchip.c b/bsp/rockchip/dm/can/canfd-rockchip.c new file mode 100755 index 00000000000..b8f72fc6354 --- /dev/null +++ b/bsp/rockchip/dm/can/canfd-rockchip.c @@ -0,0 +1,1061 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#include "can_dm.h" + +#define DBG_TAG "canfd.rockchip" +#define DBG_LVL DBG_INFO +#include + +#define CAN_MODE 0x00 +#define CAN_CMD 0x04 +#define CAN_STATE 0x08 +#define CAN_INT 0x0c +#define CAN_INT_MASK 0x10 +#define CAN_LOSTARB_CODE 0x28 +#define CAN_ERR_CODE 0x2c +#define CAN_RX_ERR_CNT 0x34 +#define CAN_TX_ERR_CNT 0x38 +#define CAN_IDCODE 0x3c +#define CAN_IDMASK 0x40 +#define CAN_TX_CHECK_FIC 0x50 +#define CAN_NBTP 0x100 +#define CAN_DBTP 0x104 +#define CAN_TDCR 0x108 +#define CAN_TSCC 0x10c +#define CAN_TSCV 0x110 +#define CAN_TXEFC 0x114 +#define CAN_RXFC 0x118 +#define CAN_AFC 0x11c +#define CAN_IDCODE0 0x120 +#define CAN_IDMASK0 0x124 +#define CAN_IDCODE1 0x128 +#define CAN_IDMASK1 0x12c +#define CAN_IDCODE2 0x130 +#define CAN_IDMASK2 0x134 +#define CAN_IDCODE3 0x138 +#define CAN_IDMASK3 0x13c +#define CAN_IDCODE4 0x140 +#define CAN_IDMASK4 0x144 +#define CAN_TXFIC 0x200 +#define CAN_TXID 0x204 +#define CAN_TXDAT0 0x208 +#define CAN_TXDAT1 0x20c +#define CAN_TXDAT2 0x210 +#define CAN_TXDAT3 0x214 +#define CAN_TXDAT4 0x218 +#define CAN_TXDAT5 0x21c +#define CAN_TXDAT6 0x220 +#define CAN_TXDAT7 0x224 +#define CAN_TXDAT8 0x228 +#define CAN_TXDAT9 0x22c +#define CAN_TXDAT10 0x230 +#define CAN_TXDAT11 0x234 +#define CAN_TXDAT12 0x238 +#define CAN_TXDAT13 0x23c +#define CAN_TXDAT14 0x240 +#define CAN_TXDAT15 0x244 +#define CAN_RXFIC 0x300 +#define CAN_RXID 0x304 +#define CAN_RXTS 0x308 +#define CAN_RXDAT0 0x30c +#define CAN_RXDAT1 0x310 +#define CAN_RXDAT2 0x314 +#define CAN_RXDAT3 0x318 +#define CAN_RXDAT4 0x31c +#define CAN_RXDAT5 0x320 +#define CAN_RXDAT6 0x324 +#define CAN_RXDAT7 0x328 +#define CAN_RXDAT8 0x32c +#define CAN_RXDAT9 0x330 +#define CAN_RXDAT10 0x334 +#define CAN_RXDAT11 0x338 +#define CAN_RXDAT12 0x33c +#define CAN_RXDAT13 0x340 +#define CAN_RXDAT14 0x344 +#define CAN_RXDAT15 0x348 +#define CAN_RXFRD 0x400 +#define CAN_TXEFRD 0x500 + +enum +{ + ROCKCHIP_CANFD_MODE = 0, + ROCKCHIP_CAN_MODE, + ROCKCHIP_RK3568_CAN_MODE, + ROCKCHIP_RK3568_CAN_MODE_V2, +}; + +#define DATE_LENGTH_12_BYTE 0x9 +#define DATE_LENGTH_16_BYTE 0xa +#define DATE_LENGTH_20_BYTE 0xb +#define DATE_LENGTH_24_BYTE 0xc +#define DATE_LENGTH_32_BYTE 0xd +#define DATE_LENGTH_48_BYTE 0xe +#define DATE_LENGTH_64_BYTE 0xf + +#define CAN_TX0_REQ RT_BIT(0) +#define CAN_TX1_REQ RT_BIT(1) +#define CAN_TX_REQ_FULL ((CAN_TX0_REQ) | (CAN_TX1_REQ)) + +#define MODE_FDOE RT_BIT(15) +#define MODE_BRSD RT_BIT(13) +#define MODE_SPACE_RX RT_BIT(12) +#define MODE_AUTO_RETX RT_BIT(10) +#define MODE_RXSORT RT_BIT(7) +#define MODE_TXORDER RT_BIT(6) +#define MODE_RXSTX RT_BIT(5) +#define MODE_LBACK RT_BIT(4) +#define MODE_SILENT RT_BIT(3) +#define MODE_SELF_TEST RT_BIT(2) +#define MODE_SLEEP RT_BIT(1) +#define RESET_MODE 0 +#define WORK_MODE RT_BIT(0) + +#define RX_FINISH_INT RT_BIT(0) +#define TX_FINISH_INT RT_BIT(1) +#define ERR_WARN_INT RT_BIT(2) +#define RX_BUF_OV_INT RT_BIT(3) +#define PASSIVE_ERR_INT RT_BIT(4) +#define TX_LOSTARB_INT RT_BIT(5) +#define BUS_ERR_INT RT_BIT(6) +#define RX_FIFO_FULL_INT RT_BIT(7) +#define RX_FIFO_OV_INT RT_BIT(8) +#define BUS_OFF_INT RT_BIT(9) +#define BUS_OFF_RECOVERY_INT RT_BIT(10) +#define TSC_OV_INT RT_BIT(11) +#define TXE_FIFO_OV_INT RT_BIT(12) +#define TXE_FIFO_FULL_INT RT_BIT(13) +#define WAKEUP_INT RT_BIT(14) + +#define ERR_TYPE_MASK RT_GENMASK(28, 26) +#define ERR_TYPE_SHIFT 26 +#define BIT_ERR 0 +#define STUFF_ERR 1 +#define FORM_ERR 2 +#define ACK_ERR 3 +#define CRC_ERR 4 +#define ERR_DIR_RX RT_BIT(25) +#define ERR_LOC_MASK RT_GENMASK(15, 0) + +/* Nominal Bit Timing & Prescaler Register (NBTP) */ +#define NBTP_MODE_3_SAMPLES RT_BIT(31) +#define NBTP_NSJW_SHIFT 24 +#define NBTP_NSJW_MASK (0x7f << NBTP_NSJW_SHIFT) +#define NBTP_NBRP_SHIFT 16 +#define NBTP_NBRP_MASK (0xff << NBTP_NBRP_SHIFT) +#define NBTP_NTSEG2_SHIFT 8 +#define NBTP_NTSEG2_MASK (0x7f << NBTP_NTSEG2_SHIFT) +#define NBTP_NTSEG1_SHIFT 0 +#define NBTP_NTSEG1_MASK (0x7f << NBTP_NTSEG1_SHIFT) + +/* Data Bit Timing & Prescaler Register (DBTP) */ +#define DBTP_MODE_3_SAMPLES RT_BIT(21) +#define DBTP_DSJW_SHIFT 17 +#define DBTP_DSJW_MASK (0xf << DBTP_DSJW_SHIFT) +#define DBTP_DBRP_SHIFT 9 +#define DBTP_DBRP_MASK (0xff << DBTP_DBRP_SHIFT) +#define DBTP_DTSEG2_SHIFT 5 +#define DBTP_DTSEG2_MASK (0xf << DBTP_DTSEG2_SHIFT) +#define DBTP_DTSEG1_SHIFT 0 +#define DBTP_DTSEG1_MASK (0x1f << DBTP_DTSEG1_SHIFT) + +/* Transmitter Delay Compensation Register (TDCR) */ +#define TDCR_TDCO_SHIFT 1 +#define TDCR_TDCO_MASK (0x3f << TDCR_TDCO_SHIFT) +#define TDCR_TDC_ENABLE RT_BIT(0) + +#define TX_FD_ENABLE RT_BIT(5) +#define TX_FD_BRS_ENABLE RT_BIT(4) + +#define FIFO_ENABLE RT_BIT(0) +#define RX_FIFO_CNT0_SHIFT 4 +#define RX_FIFO_CNT0_MASK (0x7 << RX_FIFO_CNT0_SHIFT) +#define RX_FIFO_CNT1_SHIFT 5 +#define RX_FIFO_CNT1_MASK (0x7 << RX_FIFO_CNT1_SHIFT) +#define RX_FIFO_COUNT_MAX (RT_GENMASK(7, 5) >> RX_FIFO_CNT1_SHIFT) +#define RX_FIFO_ERR_IDX RX_FIFO_COUNT_MAX + +#define FORMAT_SHIFT 7 +#define FORMAT_MASK (0x1 << FORMAT_SHIFT) +#define RTR_SHIFT 6 +#define RTR_MASK (0x1 << RTR_SHIFT) +#define FDF_SHIFT 5 +#define FDF_MASK (0x1 << FDF_SHIFT) +#define BRS_SHIFT 4 +#define BRS_MASK (0x1 << BRS_SHIFT) +#define TDC_SHIFT 1 +#define TDC_MASK (0x3f << TDC_SHIFT) +#define DLC_SHIFT 0 +#define DLC_MASK (0xf << DLC_SHIFT) + +#define CAN_RF_SIZE 0x48 +#define CAN_TEF_SIZE 0x8 +#define CAN_TXEFRD_OFFSET(n) (CAN_TXEFRD + CAN_TEF_SIZE * (n)) +#define CAN_RXFRD_OFFSET(n) (CAN_RXFRD + CAN_RF_SIZE * (n)) + +#define CAN_RX_FILTER_MASK 0x1fffffff +#define NOACK_ERR_FLAG 0xc200800 +#define CAN_BUSOFF_FLAG 0x20 +#define NSEC_PER_USEC 1000L + +struct rockchip_canfd +{ + struct rt_can_device parent; + + int irq; + void *regs; + rt_ubase_t mode; + rt_bool_t txtorx; + rt_uint32_t tx_invalid[4]; + rt_uint32_t rx_fifo_shift; + rt_uint32_t rx_fifo_mask; + rt_uint32_t delay_time_ms; + + struct rt_can_msg rx_msg[RX_FIFO_COUNT_MAX + 1], tx_msg; + + struct rt_clk_array *clk_arr; + struct rt_reset_control *rstc; + + struct rt_work tx_err_work; +}; + +#define raw_to_rockchip_canfd(raw) rt_container_of(raw, struct rockchip_canfd, parent) + +#define READ_POLL_TIMEOUT_ATOMIC(OP, VAL, COND, DELAY_US, \ + TIMEOUT_US, DELAY_BEFORE_READ, ARGS...) \ +({ \ + rt_uint64_t timeout_us = (TIMEOUT_US); \ + rt_int64_t left_ns = timeout_us * NSEC_PER_USEC; \ + rt_ubase_t delay_us = (DELAY_US); \ + rt_uint64_t delay_ns = delay_us * NSEC_PER_USEC; \ + if (DELAY_BEFORE_READ && delay_us) \ + { \ + rt_hw_us_delay(delay_us); \ + if (timeout_us) \ + { \ + left_ns -= delay_ns; \ + } \ + } \ + for (;;) \ + { \ + (VAL) = OP(ARGS); \ + if (COND) \ + { \ + break; \ + } \ + if (timeout_us && left_ns < 0) \ + { \ + (VAL) = OP(ARGS); \ + break; \ + } \ + if (delay_us) \ + { \ + rt_hw_us_delay(delay_us); \ + if (timeout_us) \ + { \ + left_ns -= delay_ns; \ + } \ + } \ + rt_hw_cpu_relax(); \ + if (timeout_us) \ + { \ + --left_ns; \ + } \ + } \ + (COND) ? 0 : -RT_ETIMEOUT; \ +}) + +static const struct rt_can_bit_timing rockchip_canfd_bittiming_const = +{ + .prescaler = 256, + .num_seg1 = 128, + .num_seg2 = 128, + .num_sjw = 128, + .num_sspoff = 2, +}; + +static const struct rt_can_bit_timing rockchip_canfd_data_bittiming_const = +{ + .prescaler = 256, + .num_seg1 = 32, + .num_seg2 = 16, + .num_sjw = 16, + .num_sspoff = 2, +}; + +rt_inline rt_uint32_t rockchip_canfd_read(struct rockchip_canfd *rk_canfd, + int offset) +{ + return HWREG32(rk_canfd->regs + offset); +} + +rt_inline void rockchip_canfd_write(struct rockchip_canfd *rk_canfd, + int offset, rt_uint32_t val) +{ + HWREG32(rk_canfd->regs + offset) = val; +} + +static rt_err_t set_reset_mode(struct rockchip_canfd *rk_canfd) +{ + rt_reset_control_assert(rk_canfd->rstc); + rt_hw_us_delay(2); + rt_reset_control_deassert(rk_canfd->rstc); + + rockchip_canfd_write(rk_canfd, CAN_MODE, 0); + + return RT_EOK; +} + +static rt_err_t set_normal_mode(struct rockchip_canfd *rk_canfd) +{ + rt_uint32_t val; + + val = rockchip_canfd_read(rk_canfd, CAN_MODE); + val |= WORK_MODE; + rockchip_canfd_write(rk_canfd, CAN_MODE, val); + + return RT_EOK; +} + +static int rockchip_canfd_get_rx_fifo_cnt(struct rockchip_canfd *rk_canfd) +{ + int quota = 0; + + if (READ_POLL_TIMEOUT_ATOMIC(rockchip_canfd_read, quota, + (quota & rk_canfd->rx_fifo_mask) >> rk_canfd->rx_fifo_shift, + 0, 500000, false, rk_canfd, CAN_RXFC)) + { + LOG_D("%s get fifo cnt failed", + rt_dm_dev_get_name(&rk_canfd.parent.parent)); + } + + quota = (quota & rk_canfd->rx_fifo_mask) >> rk_canfd->rx_fifo_shift; + + return quota; +} + +static void rockchip_canfd_tx_err_delay_work(struct rt_work *work, void *work_data) +{ + rt_uint32_t mode, err_code; + struct rockchip_canfd *rk_canfd = work_data; + + mode = rockchip_canfd_read(rk_canfd, CAN_MODE); + err_code = rockchip_canfd_read(rk_canfd, CAN_ERR_CODE); + + if ((err_code & NOACK_ERR_FLAG) == NOACK_ERR_FLAG) + { + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_SPACE_RX); + rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX0_REQ); + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_SPACE_RX)); + + rt_work_submit(&rk_canfd->tx_err_work, + rt_tick_from_millisecond(rk_canfd->delay_time_ms)); + } + else + { + rockchip_canfd_write(rk_canfd, CAN_MODE, 0); + rockchip_canfd_write(rk_canfd, CAN_MODE, mode); + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_SPACE_RX); + rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX0_REQ); + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_SPACE_RX)); + + rt_work_submit(&rk_canfd->tx_err_work, + rt_tick_from_millisecond(rk_canfd->delay_time_ms)); + } +} + +static rt_err_t rockchip_canfd_configure(struct rt_can_device *can, + struct can_configure *conf) +{ + rt_uint32_t val, reg_btp; + rt_uint16_t brp, sjw, tseg1, tseg2; + struct rockchip_canfd *rk_canfd = raw_to_rockchip_canfd(can); + struct rt_can_bit_timing *bt = &rk_canfd->parent.config.can_timing; + struct rt_can_bit_timing *dbt = &rk_canfd->parent.config.canfd_timing; + + set_reset_mode(rk_canfd); + + rockchip_canfd_write(rk_canfd, CAN_INT_MASK, 0); + + /* RECEIVING FILTER, accept all */ + rockchip_canfd_write(rk_canfd, CAN_IDCODE, 0); + rockchip_canfd_write(rk_canfd, CAN_IDMASK, CAN_RX_FILTER_MASK); + rockchip_canfd_write(rk_canfd, CAN_IDCODE0, 0); + rockchip_canfd_write(rk_canfd, CAN_IDMASK0, CAN_RX_FILTER_MASK); + rockchip_canfd_write(rk_canfd, CAN_IDCODE1, 0); + rockchip_canfd_write(rk_canfd, CAN_IDMASK1, CAN_RX_FILTER_MASK); + rockchip_canfd_write(rk_canfd, CAN_IDCODE2, 0); + rockchip_canfd_write(rk_canfd, CAN_IDMASK2, CAN_RX_FILTER_MASK); + rockchip_canfd_write(rk_canfd, CAN_IDCODE3, 0); + rockchip_canfd_write(rk_canfd, CAN_IDMASK3, CAN_RX_FILTER_MASK); + rockchip_canfd_write(rk_canfd, CAN_IDCODE4, 0); + rockchip_canfd_write(rk_canfd, CAN_IDMASK4, CAN_RX_FILTER_MASK); + + /* Set mode */ + val = rockchip_canfd_read(rk_canfd, CAN_MODE); + + /* RX fifo enable */ + rockchip_canfd_write(rk_canfd, CAN_RXFC, + rockchip_canfd_read(rk_canfd, CAN_RXFC) | FIFO_ENABLE); + + val |= MODE_FDOE; + + /* Mode */ + if (conf->mode & RT_CAN_MODE_LISTEN) + { + val |= MODE_SILENT; + } + + if (conf->mode & RT_CAN_MODE_LOOPBACK) + { + val |= MODE_SELF_TEST | MODE_LBACK; + } + + rockchip_canfd_write(rk_canfd, CAN_MODE, val); + + /* Set bittiming */ + brp = (bt->prescaler >> 1) - 1; + sjw = bt->num_sjw ? bt->num_sjw - 1 : 0; + tseg1 = bt->num_seg1; + tseg2 = bt->num_seg2; + reg_btp = (brp << NBTP_NBRP_SHIFT) | (sjw << NBTP_NSJW_SHIFT) | + (tseg1 << NBTP_NTSEG1_SHIFT) | (tseg2 << NBTP_NTSEG2_SHIFT); + + rockchip_canfd_write(rk_canfd, CAN_NBTP, reg_btp); + + if (rk_canfd->parent.config.mode == RT_CAN_MODE_NORMAL) + { + rt_uint32_t baud_rate_fd = rk_canfd->parent.config.baud_rate_fd; + + brp = (dbt->prescaler >> 1) - 1; + sjw = dbt->num_sjw ? dbt->num_sjw - 1 : 0; + tseg1 = dbt->num_seg1; + tseg2 = dbt->num_seg2; + + if (baud_rate_fd > 2200000) + { + rt_uint32_t tdco; + + tdco = (rk_canfd->parent.config.baud_rate / baud_rate_fd) * 2 / 3; + + /* Max valid TDCO value is 63 */ + if (tdco > 63) + { + tdco = 63; + } + + rockchip_canfd_write(rk_canfd, CAN_TDCR, + (tdco << TDC_SHIFT) | TDCR_TDC_ENABLE); + } + + reg_btp = (brp << DBTP_DBRP_SHIFT) | (sjw << DBTP_DSJW_SHIFT) | + (tseg1 << DBTP_DTSEG1_SHIFT) | (tseg2 << DBTP_DTSEG2_SHIFT); + + rockchip_canfd_write(rk_canfd, CAN_DBTP, reg_btp); + } + + if (conf->baud_rate > 200000) + { + rk_canfd->delay_time_ms = 1; + } + else if (conf->baud_rate > 50000) + { + rk_canfd->delay_time_ms = 5; + } + else + { + rk_canfd->delay_time_ms = 20; + } + + set_normal_mode(rk_canfd); + + return RT_EOK; +} + +static rt_err_t rockchip_canfd_control(struct rt_can_device *can, int cmd, void *args) +{ + struct rt_can_bit_timing_config *timing; + + switch (cmd) + { + case RT_CAN_CMD_SET_MODE: + switch ((rt_base_t)args) + { + case RT_CAN_MODE_NORMAL: + case RT_CAN_MODE_LISTEN: + case RT_CAN_MODE_LOOPBACK: + case RT_CAN_MODE_LOOPBACKANLISTEN: + can->config.mode = (rt_uint32_t)(rt_base_t)args; + break; + + default: + return -RT_ENOSYS; + } + break; + + case RT_CAN_CMD_SET_BAUD: + can->config.baud_rate = (rt_uint32_t)(rt_base_t)args; + break; + + case RT_CAN_CMD_GET_STATUS: + rt_memcpy(args, &can->status, sizeof(can->status)); + return RT_EOK; + + case RT_CAN_CMD_SET_CANFD: + can->config.enable_canfd = (rt_ubase_t)args; + break; + + case RT_CAN_CMD_SET_BAUD_FD: + can->config.baud_rate_fd = (rt_ubase_t)args; + break; + + case RT_CAN_CMD_SET_BITTIMING: + timing = args; + + if (!timing || timing->count < 1 || timing->count > 2) + { + return -RT_EINVAL; + } + + if (timing->count) + { + rt_memcpy(&can->config.can_timing, &timing->items[0], + sizeof(&timing->items[0])); + } + + if (timing->count == 2) + { + rt_memcpy(&can->config.canfd_timing, &timing->items[1], + sizeof(&timing->items[1])); + } + break; + + default: + return -RT_ENOSYS; + } + + if (can->config.enable_canfd) + { + rockchip_canfd_configure(can, &can->config); + } + + return RT_EOK; +} + +static rt_err_t rockchip_canfd_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t boxno) +{ + rt_uint32_t id, dlc, cmd; + struct rt_can_msg *tx_msg; + struct rockchip_canfd *rk_canfd = raw_to_rockchip_canfd(can); + + tx_msg = &rk_canfd->tx_msg; + rt_memcpy(tx_msg, buf, sizeof(*tx_msg)); + + if (rockchip_canfd_read(rk_canfd, CAN_CMD) & CAN_TX0_REQ) + { + cmd = CAN_TX1_REQ; + } + else + { + cmd = CAN_TX0_REQ; + } + + if (tx_msg->id & CAN_EFF_FLAG) + { + /* Extended CAN ID format */ + id = tx_msg->id & CAN_EFF_MASK; + dlc = (can_len2dlc(tx_msg->len) & DLC_MASK) | FORMAT_MASK; + } + else + { + /* Standard CAN ID format */ + id = tx_msg->id & CAN_SFF_MASK; + dlc = can_len2dlc(tx_msg->len) & DLC_MASK; + } + + if (tx_msg->id & CAN_RTR_FLAG) + { + dlc |= RTR_MASK; + } + + if (can->config.mode == RT_CAN_MODE_NORMAL && tx_msg->len <= CANFD_MAX_DLEN) + { + dlc |= TX_FD_ENABLE; + } + + if (tx_msg->ide) + { + dlc |= FORMAT_MASK; + } + + if (tx_msg->rtr) + { + dlc |= RTR_MASK; + } + + if (rk_canfd->txtorx && rk_canfd->mode <= ROCKCHIP_RK3568_CAN_MODE && + tx_msg->id & CAN_EFF_FLAG) + { + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_RXSTX); + } + else + { + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_RXSTX)); + } + + if (!rk_canfd->txtorx && rk_canfd->mode <= ROCKCHIP_RK3568_CAN_MODE && + tx_msg->id & CAN_EFF_FLAG) + { + /* + * Two frames are sent consecutively. + * Before the first frame is tx finished, + * the register of the second frame is configured. + * Don't be interrupted in the middle. + */ + rt_ubase_t level; + static struct rt_spinlock pe_lock = {}; + + level = rt_spin_lock_irqsave(&pe_lock); + + rockchip_canfd_write(rk_canfd, CAN_TXID, rk_canfd->tx_invalid[1]); + rockchip_canfd_write(rk_canfd, CAN_TXFIC, rk_canfd->tx_invalid[0]); + rockchip_canfd_write(rk_canfd, CAN_TXDAT0, rk_canfd->tx_invalid[2]); + rockchip_canfd_write(rk_canfd, CAN_TXDAT1, rk_canfd->tx_invalid[3]); + rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX0_REQ); + rockchip_canfd_write(rk_canfd, CAN_TXID, id); + rockchip_canfd_write(rk_canfd, CAN_TXFIC, dlc); + + for (int i = 0; i < tx_msg->len; i += 4) + { + rockchip_canfd_write(rk_canfd, CAN_TXDAT0 + i, + *(rt_uint32_t *)(tx_msg->data + i)); + } + + rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX1_REQ); + + rt_spin_unlock_irqrestore(&pe_lock, level); + + return RT_EOK; + } + + rockchip_canfd_write(rk_canfd, CAN_TXID, id); + rockchip_canfd_write(rk_canfd, CAN_TXFIC, dlc); + + for (int i = 0; i < tx_msg->len; i += 4) + { + rockchip_canfd_write(rk_canfd, CAN_TXDAT0 + i, + *(rt_uint32_t *)(tx_msg->data + i)); + } + + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) | MODE_SPACE_RX); + rockchip_canfd_write(rk_canfd, CAN_CMD, cmd); + rockchip_canfd_write(rk_canfd, CAN_MODE, + rockchip_canfd_read(rk_canfd, CAN_MODE) & (~MODE_SPACE_RX)); + + rt_work_submit(&rk_canfd->tx_err_work, + rt_tick_from_millisecond(rk_canfd->delay_time_ms)); + + return RT_EOK; +} + +static rt_err_t rockchip_canfd_recvmsg(struct rt_can_device *can, void *buf, rt_uint32_t boxno) +{ + struct rockchip_canfd *rk_canfd = raw_to_rockchip_canfd(can); + + rt_memcpy(buf, &rk_canfd->rx_msg[boxno], sizeof(rk_canfd->rx_msg[boxno])); + + return RT_EOK; +} + +static const struct rt_can_ops rockchip_canfd_ops = +{ + .configure = rockchip_canfd_configure, + .control = rockchip_canfd_control, + .sendmsg = rockchip_canfd_sendmsg, + .recvmsg = rockchip_canfd_recvmsg, +}; + +static rt_uint32_t rockchip_canfd_rx(struct rockchip_canfd *rk_canfd, int boxno) +{ + struct rt_can_msg *rx_msg = &rk_canfd->rx_msg[boxno]; + rt_uint32_t id_rockchip_canfd, dlc, tx_id, ts, data[16] = { 0 }; + + dlc = rockchip_canfd_read(rk_canfd, CAN_RXFRD); + id_rockchip_canfd = rockchip_canfd_read(rk_canfd, CAN_RXFRD); + ts = rockchip_canfd_read(rk_canfd, CAN_RXFRD); + + for (int i = 0; i < RT_ARRAY_SIZE(data); ++i) + { + data[i] = rockchip_canfd_read(rk_canfd, CAN_RXFRD); + } + + if (rk_canfd->mode >= ROCKCHIP_CAN_MODE) + { + if (!dlc && !id_rockchip_canfd) + { + return 1; + } + + if (rk_canfd->txtorx) + { + if (rockchip_canfd_read(rk_canfd, CAN_TX_CHECK_FIC) & FORMAT_MASK) + { + tx_id = rockchip_canfd_read(rk_canfd, CAN_TXID) & CAN_SFF_MASK; + + if (id_rockchip_canfd == tx_id && !(dlc & FORMAT_MASK)) + { + rockchip_canfd_write(rk_canfd, CAN_TX_CHECK_FIC, + ts | CAN_TX0_REQ); + + return 1; + } + } + } + } + + if (dlc & FDF_MASK) + { + rx_msg->len = can_dlc2len(dlc & DLC_MASK); + } + else + { + rx_msg->len = can_get_dlc(dlc & DLC_MASK); + } + + rx_msg->id = id_rockchip_canfd; + + if (dlc & FORMAT_MASK) + { + rx_msg->id |= CAN_EFF_FLAG; + } + + if (dlc & RTR_MASK) + { + rx_msg->id |= CAN_RTR_FLAG; + } + + rx_msg->ide = (dlc & FORMAT_MASK) >> FORMAT_SHIFT; + rx_msg->rtr = (dlc & RTR_MASK) >> RTR_SHIFT; + + if (!(rx_msg->id & CAN_RTR_FLAG)) + { + for (int i = 0; i < rx_msg->len; i += 4) + { + *(rt_uint32_t *)(rx_msg->data + i) = data[i / 4]; + } + } + + return 1; +} + +static rt_err_t rockchip_canfd_err(struct rockchip_canfd *rk_canfd, rt_uint8_t ints) +{ + rt_uint32_t sta_reg; + struct rt_can_device *can = &rk_canfd->parent; + + can->status.rcverrcnt = rockchip_canfd_read(rk_canfd, CAN_RX_ERR_CNT); + can->status.snderrcnt = rockchip_canfd_read(rk_canfd, CAN_TX_ERR_CNT); + sta_reg = rockchip_canfd_read(rk_canfd, CAN_STATE); + + if (ints & BUS_OFF_INT) + { + can->status.errcode = BUSOFF; + } + else if (ints & ERR_WARN_INT) + { + can->status.errcode = ERRWARNING; + } + else if (ints & PASSIVE_ERR_INT) + { + can->status.errcode = ERRPASSIVE; + } + + if (can->status.errcode >= BUSOFF || + (sta_reg & CAN_BUSOFF_FLAG) == CAN_BUSOFF_FLAG) + { + rt_work_cancel(&rk_canfd->tx_err_work); + + /* Stop */ + set_reset_mode(rk_canfd); + /* Disable all interrupts */ + rockchip_canfd_write(rk_canfd, CAN_INT_MASK, 0xffff); + + /* Start */ + rockchip_canfd_configure(&rk_canfd->parent, &can->config); + } + + return RT_EOK; +} + +static void rockchip_canfd_isr(int irqno, void *param) +{ + rt_uint32_t ints, dlc, quota, work_done = 0; + struct rockchip_canfd *rk_canfd = param; + const rt_uint32_t err_ints = ERR_WARN_INT | RX_BUF_OV_INT | PASSIVE_ERR_INT | + TX_LOSTARB_INT | BUS_ERR_INT | BUS_OFF_INT; + + ints = rockchip_canfd_read(rk_canfd, CAN_INT); + + if (ints & TX_FINISH_INT) + { + rt_work_cancel(&rk_canfd->tx_err_work); + dlc = rockchip_canfd_read(rk_canfd, CAN_TXFIC); + + if (rk_canfd->txtorx && rk_canfd->mode <= ROCKCHIP_RK3568_CAN_MODE && + dlc & FORMAT_MASK) + { + rockchip_canfd_write(rk_canfd, CAN_TX_CHECK_FIC, FORMAT_MASK); + quota = rockchip_canfd_get_rx_fifo_cnt(rk_canfd); + + for (int boxno = 0; work_done < quota; ++boxno) + { + work_done += rockchip_canfd_rx(rk_canfd, boxno); + rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_TX_DONE | (boxno << 8)); + } + + if (rockchip_canfd_read(rk_canfd, CAN_TX_CHECK_FIC) & CAN_TX0_REQ) + { + rockchip_canfd_write(rk_canfd, CAN_CMD, CAN_TX1_REQ); + } + rockchip_canfd_write(rk_canfd, CAN_TX_CHECK_FIC, 0); + } + else + { + rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_TX_DONE); + } + + if (READ_POLL_TIMEOUT_ATOMIC(rockchip_canfd_read, quota, + !(quota & 0x3), 0, 5000000, false, rk_canfd, CAN_CMD)) + { + LOG_E("%s: Wait tx req timeout", + rt_dm_dev_get_name(&rk_canfd->parent.parent)); + } + + rockchip_canfd_write(rk_canfd, CAN_CMD, 0); + } + + if (ints & RX_FINISH_INT) + { + if (rk_canfd->mode == ROCKCHIP_RK3568_CAN_MODE_V2) + { + rockchip_canfd_write(rk_canfd, CAN_INT_MASK, 0x1); + } + else + { + work_done = 0; + quota = (rockchip_canfd_read(rk_canfd, CAN_RXFC) & + rk_canfd->rx_fifo_mask) >> rk_canfd->rx_fifo_shift; + + for (int boxno = 0; work_done < quota; ++boxno) + { + work_done += rockchip_canfd_rx(rk_canfd, boxno); + rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_RX_IND | (boxno << 8)); + } + } + + } + + if (ints & (RX_FIFO_FULL_INT | RX_FIFO_OV_INT)) + { + rt_hw_can_isr(&rk_canfd->parent, RT_CAN_EVENT_RXOF_IND); + rockchip_canfd_rx(rk_canfd, RX_FIFO_ERR_IDX); + } + + if (ints & err_ints) + { + rockchip_canfd_err(rk_canfd, ints); + rockchip_canfd_rx(rk_canfd, RX_FIFO_ERR_IDX); + } + + rockchip_canfd_write(rk_canfd, CAN_INT, ints); +} + +static void rockchip_canfd_free(struct rockchip_canfd *rk_canfd) +{ + if (rk_canfd->regs) + { + rt_iounmap(rk_canfd->regs); + } + + if (!rt_is_err_or_null(rk_canfd->clk_arr)) + { + rt_clk_array_put(rk_canfd->clk_arr); + } + + if (!rt_is_err_or_null(rk_canfd->rstc)) + { + rt_reset_control_put(rk_canfd->rstc); + } + + rt_free(rk_canfd); +} + +static rt_err_t rockchip_canfd_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + const char *dev_name; + struct rt_can_device *can; + struct can_configure *conf; + struct rt_device *dev = &pdev->parent; + struct rockchip_canfd *rk_canfd = rt_calloc(1, sizeof(*rk_canfd)); + + if (!rk_canfd) + { + return -RT_ENOMEM; + } + + rk_canfd->mode = (rt_ubase_t)pdev->id->data; + rk_canfd->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_canfd->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_canfd->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_canfd->irq < 0) + { + err = rk_canfd->irq; + goto _fail; + } + + rk_canfd->clk_arr = rt_clk_get_array(dev); + + if (rt_is_err(rk_canfd->clk_arr)) + { + err = rt_ptr_err(rk_canfd->clk_arr); + goto _fail; + } + + rk_canfd->rstc = rt_reset_control_get_array(dev); + + if (rt_is_err(rk_canfd->rstc)) + { + err = rt_ptr_err(rk_canfd->rstc); + goto _fail; + } + +#ifdef RT_USING_OFW + /* RockChip CPU version = 3 */ + if ((rt_ofw_machine_is_compatible("rockchip,rk3566") || + rt_ofw_machine_is_compatible("rockchip,rk3568"))) + { + rk_canfd->mode = ROCKCHIP_RK3568_CAN_MODE_V2; + } +#endif + + can = &rk_canfd->parent; + conf = &can->config; + + conf->baud_rate = rt_clk_get_rate(rk_canfd->clk_arr->clks[0]); + conf->msgboxsz = 1; + conf->sndboxnumber = 1; + conf->mode = RT_CAN_MODE_NORMAL; + conf->ticks = 50; +#ifdef RT_CAN_USING_HDR + conf->maxhdr = 4; +#endif + conf->use_bit_timing = 1; + rt_memcpy(&conf->can_timing, &rockchip_canfd_bittiming_const, sizeof(conf->can_timing)); + + if (rk_canfd->mode == ROCKCHIP_CAN_MODE) + { + rk_canfd->rx_fifo_shift = RX_FIFO_CNT1_SHIFT; + rk_canfd->rx_fifo_mask = RX_FIFO_CNT1_MASK; + } + else + { + if (rk_canfd->mode == ROCKCHIP_CANFD_MODE) + { + rt_memcpy(&conf->canfd_timing, &rockchip_canfd_data_bittiming_const, + sizeof(conf->canfd_timing)); + } + + rk_canfd->rx_fifo_shift = RX_FIFO_CNT0_SHIFT; + rk_canfd->rx_fifo_mask = RX_FIFO_CNT0_MASK; + } + + if (rt_dm_dev_prop_read_u32_array_index(dev, "rockchip,tx-invalid-info", + 0, 4, rk_canfd->tx_invalid) < 0) + { + rk_canfd->txtorx = RT_TRUE; + } + + if (rk_canfd->mode == ROCKCHIP_RK3568_CAN_MODE_V2) + { + rk_canfd->txtorx = RT_FALSE; + } + + dev->user_data = rk_canfd; + + rt_work_init(&rk_canfd->tx_err_work, rockchip_canfd_tx_err_delay_work, rk_canfd); + + rt_dm_dev_set_name_auto(&can->parent, "can"); + dev_name = rt_dm_dev_get_name(&can->parent); + + rt_hw_interrupt_install(rk_canfd->irq, rockchip_canfd_isr, rk_canfd, dev_name); + rt_hw_interrupt_umask(rk_canfd->irq); + + if ((err = rt_hw_can_register(can, dev_name, &rockchip_canfd_ops, rk_canfd))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rockchip_canfd_free(rk_canfd); + + return err; +} + +static rt_err_t rockchip_canfd_remove(struct rt_platform_device *pdev) +{ + struct rockchip_canfd *rk_canfd = pdev->parent.user_data; + + rt_hw_interrupt_mask(rk_canfd->irq); + rt_pic_detach_irq(rk_canfd->irq, rk_canfd); + + rt_device_unregister(&rk_canfd->parent.parent); + + rockchip_canfd_free(rk_canfd); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_canfd_ofw_ids[] = +{ + { .compatible = "rockchip,canfd-1.0", .data = (void *)ROCKCHIP_CANFD_MODE }, + { .compatible = "rockchip,can-2.0", .data = (void *)ROCKCHIP_CAN_MODE }, + { .compatible = "rockchip,rk3568-can-2.0", .data = (void *)ROCKCHIP_RK3568_CAN_MODE }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_canfd_driver = +{ + .name = "canfd-rockchip", + .ids = rockchip_canfd_ofw_ids, + + .probe = rockchip_canfd_probe, + .remove = rockchip_canfd_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_canfd_driver); diff --git a/bsp/rockchip/dm/clk/Kconfig b/bsp/rockchip/dm/clk/Kconfig new file mode 100755 index 00000000000..cb56f669cc1 --- /dev/null +++ b/bsp/rockchip/dm/clk/Kconfig @@ -0,0 +1,36 @@ +menuconfig RT_CLK_ROCKCHIP_RK8XX_CLKOUT + bool "Clock driver for RK805/RK808/RK809/RK817/RK818" + depends on RT_MFD_RK8XX + depends on RT_USING_OFW + default n + +menuconfig RT_CLK_ROCKCHIP_LINK + bool "Rockchip link clock controller" + depends on RT_USING_OFW + default y + +menuconfig RT_CLK_ROCKCHIP + bool "Rockchip clock controller common" + depends on RT_USING_OFW + depends on RT_USING_RESET + default y + +config RT_CLK_ROCKCHIP_RK3308 + bool "Rockchip RK3308 clock controller support" + depends on RT_CLK_ROCKCHIP + default n + +config RT_CLK_ROCKCHIP_RK3568 + bool "Rockchip RK3568 clock controller support" + depends on RT_CLK_ROCKCHIP + default n + +config RT_CLK_ROCKCHIP_RK3576 + bool "Rockchip RK3576 clock controller support" + depends on RT_CLK_ROCKCHIP + default n + +config RT_CLK_ROCKCHIP_RK3588 + bool "Rockchip RK3588 clock controller support" + depends on RT_CLK_ROCKCHIP + default n diff --git a/bsp/rockchip/dm/clk/SConscript b/bsp/rockchip/dm/clk/SConscript new file mode 100755 index 00000000000..5b25e43f474 --- /dev/null +++ b/bsp/rockchip/dm/clk/SConscript @@ -0,0 +1,33 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_CLK_ROCKCHIP_LINK']): + src += ['clk-link.c'] + +if GetDepend(['RT_CLK_ROCKCHIP_RK8XX_CLKOUT']): + src += ['clk-rk8xx-clkout.c'] + +if GetDepend(['RT_CLK_ROCKCHIP']): + src += ['clk-rk-cpu.c', 'clk-rk-composite.c', 'clk-rk-divider.c', 'clk-rk-factor.c', + 'clk-rk-fraction-divider.c', 'clk-rk-gate.c', 'clk-rk-mmc-phase.c', + 'clk-rk-mux.c', 'clk-rk-muxgrf.c', 'clk-rk-pll.c', 'clk-rk-half-divider.c', + 'clk-rk.c', 'softrst.c'] + +if GetDepend(['RT_CLK_ROCKCHIP_RK3308']): + src += ['clk-rk3308.c'] + +if GetDepend(['RT_CLK_ROCKCHIP_RK3568']): + src += ['clk-rk3568.c'] + +if GetDepend(['RT_CLK_ROCKCHIP_RK3576']): + src += ['clk-rk3576.c'] + +if GetDepend(['RT_CLK_ROCKCHIP_RK3588']): + src += ['clk-rk3588.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/clk/clk-link.c b/bsp/rockchip/dm/clk/clk-link.c new file mode 100755 index 00000000000..f2b0a1cc339 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-link.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include + +#define DBG_TAG "clk.link" +#define DBG_LVL DBG_INFO +#include + +struct rockchip_link_data +{ + rt_size_t cells_nr; + struct rt_clk_cell **cells; +}; + +struct rockchip_link_cell +{ + struct rt_clk_cell cell; + rt_uint32_t bit_idx; +}; + +#define cell_to_rockchip_link_cell(cell) rt_container_of(cell, struct rockchip_link_cell, cell) + +struct rockchip_link_clk +{ + struct rt_clk_node parent; + + void *base; +}; + +#define raw_to_rockchip_link_clk(raw) rt_container_of(raw, struct rockchip_link_clk, parent) + +static void clk_gate_endisable(struct rt_clk_cell *cell, int enable) +{ + rt_uint32_t reg; + int set = 1 ^ enable; + struct rockchip_link_cell *link_cell = cell_to_rockchip_link_cell(cell); + struct rockchip_link_clk *link_clk = raw_to_rockchip_link_clk(cell->clk_np); + + reg = RT_BIT(link_cell->bit_idx + 16); + + if (set) + { + reg |= RT_BIT(link_cell->bit_idx); + } + + HWREG32(link_clk->base) = reg; +} + +static rt_err_t rockchip_link_clk_enable(struct rt_clk_cell *cell) +{ + clk_gate_endisable(cell, 1); + + return RT_EOK; +} + +static void rockchip_link_clk_disable(struct rt_clk_cell *cell) +{ + clk_gate_endisable(cell, 0); +} + +static rt_bool_t rockchip_link_clk_is_enabled(struct rt_clk_cell *cell) +{ + rt_uint32_t reg; + struct rockchip_link_cell *link_cell = cell_to_rockchip_link_cell(cell); + struct rockchip_link_clk *link_clk = raw_to_rockchip_link_clk(cell->clk_np); + + reg = HWREG32(link_clk->base); + reg ^= RT_BIT(link_cell->bit_idx); + reg &= RT_BIT(link_cell->bit_idx); + + return !!reg; +} + +const struct rt_clk_ops clk_gate_ops = +{ + .enable = rockchip_link_clk_enable, + .disable = rockchip_link_clk_disable, + .is_enabled = rockchip_link_clk_is_enabled, +}; + +#define GATE_LINK(_name, _pname, _bit_idx) \ +(void *)&(struct rockchip_link_cell) \ +{ \ + .cell.name = _name, \ + .cell.parents_nr = 1, \ + .cell.parent_name = _pname, \ + .cell.ops = &clk_gate_ops, \ + .cell.flags = RT_CLK_F_SET_RATE_PARENT, \ + .bit_idx = _bit_idx, \ +} + +static struct rt_clk_cell *rk3562_clk_cells[] = +{ + GATE_LINK("aclk_rga_jdec", "aclk_rga_pre", 3), + GATE_LINK("aclk_vdpu", "aclk_vdpu_pre", 5), + GATE_LINK("aclk_vepu", "aclk_vepu_pre", 3), + GATE_LINK("aclk_vi_isp", "aclk_vi", 3), + GATE_LINK("aclk_vo", "aclk_vo_pre", 3), + GATE_LINK("hclk_vepu", "hclk_vepu_pre", 4), +}; + +static const struct rockchip_link_data rk3562_clk_data = +{ + .cells = rk3562_clk_cells, + .cells_nr = RT_ARRAY_SIZE(rk3562_clk_cells), +}; + +static struct rt_clk_cell *rk3588_clk_cells[] = +{ + GATE_LINK("aclk_isp1_pre", "aclk_isp1_root", 6), + GATE_LINK("hclk_isp1_pre", "hclk_isp1_root", 8), + GATE_LINK("hclk_nvm", "hclk_nvm_root", 2), + GATE_LINK("aclk_usb", "aclk_usb_root", 2), + GATE_LINK("hclk_usb", "hclk_usb_root", 3), + GATE_LINK("aclk_jpeg_decoder_pre", "aclk_jpeg_decoder_root", 7), + GATE_LINK("aclk_vdpu_low_pre", "aclk_vdpu_low_root", 5), + GATE_LINK("aclk_rkvenc1_pre", "aclk_rkvenc1_root", 3), + GATE_LINK("hclk_rkvenc1_pre", "hclk_rkvenc1_root", 2), + GATE_LINK("hclk_rkvdec0_pre", "hclk_rkvdec0_root", 5), + GATE_LINK("aclk_rkvdec0_pre", "aclk_rkvdec0_root", 6), + GATE_LINK("hclk_rkvdec1_pre", "hclk_rkvdec1_root", 4), + GATE_LINK("aclk_rkvdec1_pre", "aclk_rkvdec1_root", 5), + GATE_LINK("aclk_hdcp0_pre", "aclk_vo0_root", 9), + GATE_LINK("hclk_vo0", "hclk_vo0_root", 5), + GATE_LINK("aclk_hdcp1_pre", "aclk_hdcp1_root", 6), + GATE_LINK("hclk_vo1", "hclk_vo1_root", 9), + GATE_LINK("aclk_av1_pre", "aclk_av1_root", 1), + GATE_LINK("pclk_av1_pre", "pclk_av1_root", 4), + GATE_LINK("hclk_sdio_pre", "hclk_sdio_root", 1), + GATE_LINK("pclk_vo0_grf", "pclk_vo0_root", 10), + GATE_LINK("pclk_vo1_grf", "pclk_vo1_root", 12), +}; + +static const struct rockchip_link_data rk3588_clk_data = +{ + .cells = rk3588_clk_cells, + .cells_nr = RT_ARRAY_SIZE(rk3588_clk_cells), +}; + +static rt_err_t rockchip_clk_link_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + const struct rockchip_link_data *clk_data = pdev->id->data; + struct rockchip_link_clk *link_clk = rt_calloc(1, sizeof(*link_clk)); + + if (!link_clk) + { + return -RT_ENOMEM; + } + + if (!(link_clk->base = rt_dm_dev_iomap(dev, 0))) + { + err = -RT_EIO; + goto _fail; + } + + link_clk->parent.dev = dev; + link_clk->parent.cells = clk_data->cells; + link_clk->parent.cells_nr = clk_data->cells_nr; + + if ((err = rt_clk_register(&link_clk->parent))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + if (link_clk->base) + { + rt_iounmap(link_clk->base); + } + + rt_free(link_clk); + + return err; +} + +static const struct rt_ofw_node_id rockchip_clk_link_ofw_ids[] = +{ + { .compatible = "rockchip,rk3562-clock-gate-link", .data = &rk3562_clk_data }, + { .compatible = "rockchip,rk3588-clock-gate-link", .data = &rk3588_clk_data }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_clk_link_driver = +{ + .name = "clk-link", + .ids = rockchip_clk_link_ofw_ids, + + .probe = rockchip_clk_link_probe, +}; + +static int rockchip_clk_link_register(void) +{ + rt_platform_driver_register(&rockchip_clk_link_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(rockchip_clk_link_register); diff --git a/bsp/rockchip/dm/clk/clk-rk-composite.c b/bsp/rockchip/dm/clk/clk-rk-composite.c new file mode 100755 index 00000000000..e5e209d8605 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-composite.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-composite.h" +#include "clk-rk-divider.h" +#include "clk-rk-gate.h" +#include "clk-rk-mux.h" + +void rockchip_composite_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_composite_clk_cell *composite_cell = cell_to_rockchip_composite_cell(&rk_cell->cell); + + rk_cell->cell.ops = &composite_cell->ops; + + if (rk_cell->cell.parents_nr > 1) + { + rockchip_mux_clk_cell_init(rk_cell); + + composite_cell->ops.get_parent = rockchip_mux_clk_ops.get_parent; + + if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY))) + { + composite_cell->ops.set_parent = rockchip_mux_clk_ops.set_parent; + } + } + + if (rk_cell->gate_offset >= 0) + { + composite_cell->ops.enable = rockchip_gate_clk_ops.enable; + composite_cell->ops.disable = rockchip_gate_clk_ops.disable; + composite_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled; + } + + if (rk_cell->div_width > 0) + { + composite_cell->ops.recalc_rate = clk_divider_ops.recalc_rate; + composite_cell->ops.round_rate = clk_divider_ops.round_rate; + + if (!((rk_cell->div_flags & CLK_DIVIDER_READ_ONLY))) + { + composite_cell->ops.set_rate = clk_divider_ops.set_rate; + } + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-composite.h b/bsp/rockchip/dm/clk/clk-rk-composite.h new file mode 100755 index 00000000000..cbbd016fb3b --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-composite.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_COMPOSITE_H__ +#define __CLK_RK_COMPOSITE_H__ + +#include "clk-rk.h" + +struct rockchip_composite_clk_cell +{ + struct rockchip_clk_cell rk_cell; + + struct rt_clk_ops ops; +}; + +#define COMPOSITE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df, go, gs, gf) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_MUXTBL(_id, cname, pnames, f, mo, ms, mw, mf, mt, ds, dw, df, go, gs, gf) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.mux_table = mt, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_DIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, mf, do, ds, dw, df, go, gs, gf) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_offset = do, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_NOMUX(_id, cname, pname, f, mo, ds, dw, df, go, gs, gf) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_NOMUX_DIVTBL(_id, cname, pname, f, mo, ds, dw, df, dt, go, gs, gf) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.div_table = dt, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_NODIV(_id, cname, pnames, f, mo, ms, mw, mf, go, gs, gf) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_NOGATE(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = -1, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +#define COMPOSITE_NOGATE_DIVTBL(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df, dt) \ +(void *)&(struct rockchip_composite_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.div_table = dt, \ + .rk_cell.gate_offset = -1, \ + .rk_cell.init = rockchip_composite_clk_cell_init, \ +} + +rt_inline struct rockchip_composite_clk_cell *cell_to_rockchip_composite_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_composite_clk_cell, rk_cell); +} + +void rockchip_composite_clk_cell_init(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_COMPOSITE_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-cpu.c b/bsp/rockchip/dm/clk/clk-rk-cpu.c new file mode 100755 index 00000000000..03d3964c104 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-cpu.c @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-cpu.h" + +static rt_ubase_t rockchip_cpu_clk_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate) +{ + void *base; + rt_uint32_t clksel0; + struct rockchip_cpu_clk_cell *cpu_clk_cell = cell_to_rockchip_cpu_cell(cell); + const struct rockchip_cpu_clk_reg_data *reg_data = cpu_clk_cell->reg_data; + + base = cpu_clk_cell->rk_cell.provider->reg_base; + + clksel0 = HWREG32(base + reg_data->core_reg[0]); + clksel0 >>= reg_data->div_core_shift[0]; + clksel0 &= reg_data->div_core_mask[0]; + + return parent_rate / (clksel0 + 1); +} + +const struct rt_clk_ops rockchip_cpu_clk_ops = +{ + .recalc_rate = rockchip_cpu_clk_recalc_rate, +}; + +static const struct rockchip_cpu_clk_rate_table *rockchip_get_cpu_clk_settings( + struct rockchip_cpu_clk_cell *cpu_clk_cell, rt_ubase_t rate) +{ + const struct rockchip_cpu_clk_rate_table *rate_table = cpu_clk_cell->rate_table; + + for (int i = 0; i < cpu_clk_cell->rate_count; ++i) + { + if (rate == rate_table[i].prate) + { + return &rate_table[i]; + } + } + + return RT_NULL; +} + +static void rockchip_cpu_clk_set_dividers(struct rockchip_cpu_clk_cell *cpu_clk_cell, + const struct rockchip_cpu_clk_rate_table *rate) +{ + void *base = cpu_clk_cell->rk_cell.provider->reg_base; + + /* Alternate parent is active now. set the dividers */ + for (int i = 0; i < RT_ARRAY_SIZE(rate->divs); ++i) + { + const struct rockchip_cpu_clk_clksel *clksel = &rate->divs[i]; + + if (!clksel->reg) + { + continue; + } + + HWREG32(base + clksel->reg) = clksel->val; + } +} + +static void rockchip_cpu_clk_set_pre_muxs(struct rockchip_cpu_clk_cell *cpu_clk_cell, + const struct rockchip_cpu_clk_rate_table *rate) +{ + void *base = cpu_clk_cell->rk_cell.provider->reg_base; + + /* Alternate parent is active now. set the pre_muxs */ + for (int i = 0; i < RT_ARRAY_SIZE(rate->pre_muxs); ++i) + { + const struct rockchip_cpu_clk_clksel *clksel = &rate->pre_muxs[i]; + + if (!clksel->reg) + { + break; + } + + HWREG32(base + clksel->reg) = clksel->val; + } +} + +static void rockchip_cpu_clk_set_post_muxs(struct rockchip_cpu_clk_cell *cpu_clk_cell, + const struct rockchip_cpu_clk_rate_table *rate) +{ + void *base = cpu_clk_cell->rk_cell.provider->reg_base; + + /* Alternate parent is active now. set the muxs */ + for (int i = 0; i < RT_ARRAY_SIZE(rate->post_muxs); ++i) + { + const struct rockchip_cpu_clk_clksel *clksel = &rate->post_muxs[i]; + + if (!clksel->reg) + { + break; + } + + HWREG32(base + clksel->reg) = clksel->val; + } +} + +static int rockchip_cpu_clk_pre_rate_change(struct rockchip_cpu_clk_cell *cpu_clk_cell, + rt_ubase_t old_rate, rt_ubase_t new_rate) +{ + rt_ubase_t alt_prate, alt_div; + void *base = cpu_clk_cell->rk_cell.provider->reg_base; + const struct rockchip_cpu_clk_reg_data *reg_data = cpu_clk_cell->reg_data; + const struct rockchip_cpu_clk_rate_table *rate; + + /* Check validity of the new rate */ + if (!(rate = rockchip_get_cpu_clk_settings(cpu_clk_cell, new_rate))) + { + return -RT_EINVAL; + } + + alt_prate = rt_clk_cell_get_rate(&cpu_clk_cell->rk_cell_alt_parent->cell); + + /* + * If the old parent clock speed is less than the clock speed + * of the alternate parent, then it should be ensured that at no point + * the armclk speed is more than the old_rate until the dividers are + * set. + */ + if (alt_prate > old_rate) + { + /* Calculate dividers */ + alt_div = RT_DIV_ROUND_UP(alt_prate, old_rate) - 1; + + if (alt_div > reg_data->div_core_mask[0]) + { + alt_div = reg_data->div_core_mask[0]; + } + + /* + * Change parents and add dividers in a single transaction. + * + * NOTE: we do this in a single transaction so we're never + * dividing the primary parent by the extra dividers that were + * needed for the alt. + */ + + for (int i = 0; i < reg_data->num_cores; ++i) + { + HWREG32(base + reg_data->core_reg[i]) = HIWORD_UPDATE( + alt_div, + reg_data->div_core_mask[i], + reg_data->div_core_shift[i]); + } + } + + rockchip_cpu_clk_set_pre_muxs(cpu_clk_cell, rate); + + /* select alternate parent */ + if (reg_data->mux_core_reg) + { + HWREG32(base + reg_data->mux_core_reg) = HIWORD_UPDATE( + reg_data->mux_core_alt, + reg_data->mux_core_mask, + reg_data->mux_core_shift); + } + else + { + HWREG32(base + reg_data->core_reg[0]) = HIWORD_UPDATE( + reg_data->mux_core_alt, + reg_data->mux_core_mask, + reg_data->mux_core_shift); + } + + return RT_EOK; +} + +static rt_err_t rockchip_cpu_clk_post_rate_change(struct rockchip_cpu_clk_cell *cpu_clk_cell, + rt_ubase_t old_rate, rt_ubase_t new_rate) +{ + void *base = cpu_clk_cell->rk_cell.provider->reg_base; + const struct rockchip_cpu_clk_rate_table *rate; + const struct rockchip_cpu_clk_reg_data *reg_data = cpu_clk_cell->reg_data; + + if (!(rate = rockchip_get_cpu_clk_settings(cpu_clk_cell, new_rate))) + { + return -RT_EINVAL; + } + + if (old_rate < new_rate) + { + rockchip_cpu_clk_set_dividers(cpu_clk_cell, rate); + } + + /* + * post-rate change event, re-mux to primary parent and remove dividers. + * + * NOTE: we do this in a single transaction so we're never dividing the + * primary parent by the extra dividers that were needed for the alt. + */ + + if (reg_data->mux_core_reg) + { + HWREG32(base + reg_data->mux_core_reg) = HIWORD_UPDATE( + reg_data->mux_core_main, + reg_data->mux_core_mask, + reg_data->mux_core_shift); + } + else + { + HWREG32(base + reg_data->core_reg[0]) = HIWORD_UPDATE( + reg_data->mux_core_main, + reg_data->mux_core_mask, + reg_data->mux_core_shift); + } + + rockchip_cpu_clk_set_post_muxs(cpu_clk_cell, rate); + + /* Remove dividers */ + for (int i = 0; i < reg_data->num_cores; ++i) + { + HWREG32(base + reg_data->core_reg[i]) = HIWORD_UPDATE( + 0, + reg_data->div_core_mask[i], + reg_data->div_core_shift[i]); + } + + if (old_rate > new_rate) + { + rockchip_cpu_clk_set_dividers(cpu_clk_cell, rate); + } + + return RT_EOK; +} + +static rt_err_t rockchip_cpu_clk_notify(struct rt_clk_notifier *notifier, + rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate) +{ + rt_err_t err = RT_EOK; + struct rockchip_cpu_clk_cell *cpu_cell; + + cpu_cell = rt_container_of(notifier, struct rockchip_cpu_clk_cell, notifier); + + if (msg == RT_CLK_MSG_PRE_RATE_CHANGE) + { + err = rockchip_cpu_clk_pre_rate_change(cpu_cell, old_rate, new_rate); + } + else if (msg == RT_CLK_MSG_POST_RATE_CHANGE) + { + err = rockchip_cpu_clk_post_rate_change(cpu_cell, old_rate, new_rate); + } + + return err; +} + +void rockchip_cpu_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_cpu_clk_cell *cpu_clk_cell = cell_to_rockchip_cpu_cell(&rk_cell->cell); + + rk_cell->cell.parents_nr = 1; + rk_cell->cell.parent_name = cpu_clk_cell->rk_cell_parent->cell.name; + + if (cpu_clk_cell->rate_count > 0) + { + rk_cell->cell.flags |= RT_CLK_F_SET_RATE_PARENT; + } +} + +void rockchip_cpu_clk_cell_setup(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_cpu_clk_cell *cpu_clk_cell = cell_to_rockchip_cpu_cell(&rk_cell->cell); + + rt_clk_prepare_enable(rt_clk_cell_get_clk(&cpu_clk_cell->rk_cell_alt_parent->cell, RT_NULL)); + + cpu_clk_cell->notifier.callback = rockchip_cpu_clk_notify; + + rt_clk_notifier_register(rt_clk_cell_get_clk(&cpu_clk_cell->rk_cell_parent->cell, RT_NULL), + &cpu_clk_cell->notifier); +} diff --git a/bsp/rockchip/dm/clk/clk-rk-cpu.h b/bsp/rockchip/dm/clk/clk-rk-cpu.h new file mode 100755 index 00000000000..72da45e3b44 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-cpu.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_CPU_H__ +#define __CLK_RK_CPU_H__ + +#include "clk-rk.h" + +#define ROCKCHIP_CPUCLK_NUM_DIVIDERS 6 +#define ROCKCHIP_CPUCLK_MAX_CORES 4 + +struct rockchip_cpu_clk_clksel +{ + int reg; + rt_uint32_t val; +}; + +struct rockchip_cpu_clk_rate_table +{ + rt_ubase_t prate; + struct rockchip_cpu_clk_clksel divs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; + struct rockchip_cpu_clk_clksel pre_muxs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; + struct rockchip_cpu_clk_clksel post_muxs[ROCKCHIP_CPUCLK_NUM_DIVIDERS]; +}; + +struct rockchip_cpu_clk_reg_data +{ + int core_reg[ROCKCHIP_CPUCLK_MAX_CORES]; + rt_uint8_t div_core_shift[ROCKCHIP_CPUCLK_MAX_CORES]; + rt_uint32_t div_core_mask[ROCKCHIP_CPUCLK_MAX_CORES]; + int num_cores; + int mux_core_reg; + rt_uint8_t mux_core_alt; + rt_uint8_t mux_core_main; + rt_uint8_t mux_core_shift; + rt_uint32_t mux_core_mask; + const char *pll_name; +}; + +struct rockchip_cpu_clk_cell +{ + struct rockchip_clk_cell rk_cell; + struct rockchip_clk_cell *rk_cell_parent, *rk_cell_alt_parent; + + int rate_count; + const struct rockchip_cpu_clk_rate_table *rate_table; + const struct rockchip_cpu_clk_reg_data *reg_data; + + struct rt_clk_notifier notifier; +}; + +#define CPU(_id, cname, parent, alt_parent, _rates, _nrates, _reg_data) \ +(void *)&(struct rockchip_cpu_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.ops = &rockchip_cpu_clk_ops, \ + .rk_cell.cell.flags = RT_CLK_F_GET_RATE_NOCACHE, \ + .rk_cell.id = _id, \ + .rk_cell.init = rockchip_cpu_clk_cell_init, \ + .rk_cell.setup = rockchip_cpu_clk_cell_setup, \ + .rk_cell_parent = parent, \ + .rk_cell_alt_parent = alt_parent, \ + .rate_count = _nrates, \ + .rate_table = _rates, \ + .reg_data = _reg_data, \ +} + +extern const struct rt_clk_ops rockchip_cpu_clk_ops; + +rt_inline struct rockchip_cpu_clk_cell *cell_to_rockchip_cpu_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_cpu_clk_cell, rk_cell); +} + +void rockchip_cpu_clk_cell_init(struct rockchip_clk_cell *rk_cell); +void rockchip_cpu_clk_cell_setup(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_cpu_H__ */ \ No newline at end of file diff --git a/bsp/rockchip/dm/clk/clk-rk-divider.c b/bsp/rockchip/dm/clk/clk-rk-divider.c new file mode 100755 index 00000000000..cb622b8a211 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-divider.c @@ -0,0 +1,595 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-divider.h" + +struct clk_rate_request +{ + rt_ubase_t rate; + rt_ubase_t best_parent_rate; + struct rt_clk_cell *best_parent_cell; +}; + +#define clk_div_mask(width) ((1 << (width)) - 1) + +rt_inline rt_uint32_t clk_div_readl(struct rockchip_clk_cell *rk_cell) +{ + void *base = rk_cell->provider->reg_base; + + base += rk_cell->div_offset ? : rk_cell->muxdiv_offset; + + if (rk_cell->div_flags & CLK_DIVIDER_BIG_ENDIAN) + { + return rt_be32_to_cpu(HWREG32(base)); + } + + return HWREG32(base); +} + +rt_inline void clk_div_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val) +{ + void *base = rk_cell->provider->reg_base; + + base += rk_cell->div_offset ? : rk_cell->muxdiv_offset; + + if (rk_cell->div_flags & CLK_DIVIDER_BIG_ENDIAN) + { + HWREG32(base) = rt_cpu_to_be32(val); + } + else + { + HWREG32(base) = val; + } +} + +static rt_uint32_t _get_table_maxdiv(const struct clk_div_table *table, rt_uint8_t width) +{ + rt_uint32_t maxdiv = 0, mask = clk_div_mask(width); + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->div > maxdiv && clkt->val <= mask) + { + maxdiv = clkt->div; + } + } + return maxdiv; +} + +static rt_uint32_t _get_table_mindiv(const struct clk_div_table *table) +{ + rt_uint32_t mindiv = RT_UINT32_MAX; + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->div < mindiv) + { + mindiv = clkt->div; + } + } + return mindiv; +} + +static rt_uint32_t _get_maxdiv(const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags) +{ + if (flags & CLK_DIVIDER_ONE_BASED) + { + return clk_div_mask(width); + } + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + return 1 << clk_div_mask(width); + } + if (table) + { + return _get_table_maxdiv(table, width); + } + + return clk_div_mask(width) + 1; +} + +static rt_uint32_t _get_table_div(const struct clk_div_table *table, rt_uint32_t val) +{ + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->val == val) + { + return clkt->div; + } + } + + return 0; +} + +static rt_uint32_t _get_div(const struct clk_div_table *table, + rt_uint32_t val, rt_ubase_t flags, rt_uint8_t width) +{ + if (flags & CLK_DIVIDER_ONE_BASED) + { + return val; + } + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + return 1 << val; + } + if (flags & CLK_DIVIDER_MAX_AT_ZERO) + { + return val ? val : clk_div_mask(width) + 1; + } + if (table) + { + return _get_table_div(table, val); + } + return val + 1; +} + +static rt_uint32_t _get_table_val(const struct clk_div_table *table, rt_uint32_t div) +{ + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->div == div) + { + return clkt->val; + } + } + + return 0; +} + +static rt_uint32_t _get_val(const struct clk_div_table *table, + rt_uint32_t div, rt_ubase_t flags, rt_uint8_t width) +{ + if (flags & CLK_DIVIDER_ONE_BASED) + { + return div; + } + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + return __rt_ffs(div) - 1; + } + if (flags & CLK_DIVIDER_MAX_AT_ZERO) + { + return (div == clk_div_mask(width) + 1) ? 0 : div; + } + if (table) + { + return _get_table_val(table, div); + } + return div - 1; +} + +static int _round_up_table(const struct clk_div_table *table, int div) +{ + int up = RT_UINT32_MAX >> 1; + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->div == div) + { + return clkt->div; + } + else if (clkt->div < div) + { + continue; + } + + if (clkt->div - div < up - div) + { + up = clkt->div; + } + } + + return up; +} + +static int _round_down_table(const struct clk_div_table *table, int div) +{ + int down = _get_table_mindiv(table); + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->div == div) + { + return clkt->div; + } + else if (clkt->div > div) + { + continue; + } + + if (div - clkt->div < div - down) + { + down = clkt->div; + } + } + + return down; +} + +static int _div_round_up(const struct clk_div_table *table, + rt_ubase_t parent_rate, rt_ubase_t rate, rt_ubase_t flags) +{ + int div = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, rate); + + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + div = __roundup_pow_of_two(div); + } + if (table) + { + div = _round_up_table(table, div); + } + + return div; +} + +static int _div_round_closest(const struct clk_div_table *table, + rt_ubase_t parent_rate, rt_ubase_t rate, rt_ubase_t flags) +{ + int up, down; + rt_ubase_t up_rate, down_rate; + + up = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, rate); + down = parent_rate / rate; + + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + up = __roundup_pow_of_two(up); + down = __rounddown_pow_of_two(down); + } + else if (table) + { + up = _round_up_table(table, up); + down = _round_down_table(table, down); + } + + up_rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, up); + down_rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, down); + + return (rate - up_rate) <= (down_rate - rate) ? up : down; +} + +static int _div_round(const struct clk_div_table *table, + rt_ubase_t parent_rate, rt_ubase_t rate, rt_ubase_t flags) +{ + if (flags & CLK_DIVIDER_ROUND_CLOSEST) + { + return _div_round_closest(table, parent_rate, rate, flags); + } + + return _div_round_up(table, parent_rate, rate, flags); +} + +static rt_bool_t _is_best_div(rt_ubase_t rate, rt_ubase_t now, rt_ubase_t best, rt_ubase_t flags) +{ + if (flags & CLK_DIVIDER_ROUND_CLOSEST) + { + return rt_abs(rate - now) < rt_abs(rate - best); + } + + return now <= rate && now > best; +} + +static int _next_div(const struct clk_div_table *table, int div, rt_ubase_t flags) +{ + ++div; + + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + return __roundup_pow_of_two(div); + } + if (table) + { + return _round_up_table(table, div); + } + + return div; +} + +static int clk_divider_bestdiv(struct rt_clk_cell *cell, struct rt_clk_cell *parent, + rt_ubase_t rate, rt_ubase_t *best_parent_rate, + const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags) +{ + int bestdiv = 0; + rt_ubase_t parent_rate, best = 0, now, maxdiv, parent_rate_saved = *best_parent_rate; + + if (!rate) + { + rate = 1; + } + + maxdiv = _get_maxdiv(table, width, flags); + + if (!(cell->flags & RT_CLK_F_SET_RATE_PARENT)) + { + parent_rate = *best_parent_rate; + bestdiv = _div_round(table, parent_rate, rate, flags); + bestdiv = bestdiv == 0 ? 1 : bestdiv; + bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; + return bestdiv; + } + + /* + * The maximum divider we can use without overflowing + * rt_ubase_t in rate * i below + */ + maxdiv = rt_min((~0UL) / rate, maxdiv); + + for (int i = _next_div(table, 0, flags); i <= maxdiv; i = _next_div(table, i, flags)) + { + if (rate * i == parent_rate_saved) + { + /* + * It's the most ideal case if the requested rate can be + * divided from parent clock without needing to change + * parent rate, so return the divider immediately. + */ + *best_parent_rate = parent_rate_saved; + return i; + } + + parent_rate = rt_clk_cell_round_rate(parent, rate * i); + now = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, i); + + if (_is_best_div(rate, now, best, flags)) + { + bestdiv = i; + best = now; + *best_parent_rate = parent_rate; + } + } + + if (!bestdiv) + { + bestdiv = _get_maxdiv(table, width, flags); + *best_parent_rate = rt_clk_cell_round_rate(parent, 1); + } + + return bestdiv; +} + +rt_inline rt_bool_t is_power_of_2(rt_ubase_t n) +{ + return (n != 0 && ((n & (n - 1)) == 0)); +} + +static rt_bool_t _is_valid_table_div(const struct clk_div_table *table, rt_uint32_t div) +{ + const struct clk_div_table *clkt; + + for (clkt = table; clkt->div; ++clkt) + { + if (clkt->div == div) + { + return RT_TRUE; + } + } + return RT_FALSE; +} + +static rt_bool_t _is_valid_div(const struct clk_div_table *table, rt_uint32_t div, rt_ubase_t flags) +{ + if (flags & CLK_DIVIDER_POWER_OF_TWO) + { + return is_power_of_2(div); + } + + if (table) + { + return _is_valid_table_div(table, div); + } + + return RT_TRUE; +} + +static int divider_get_val(rt_ubase_t rate, rt_ubase_t parent_rate, + const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags) +{ + rt_uint32_t div, value; + + div = RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, rate); + + if (!_is_valid_div(table, div, flags)) + { + return -RT_EINVAL; + } + + value = _get_val(table, div, flags, width); + + return rt_min_t(rt_uint32_t, value, clk_div_mask(width)); +} + +static int divider_determine_rate(struct rt_clk_cell *cell, struct clk_rate_request *req, + const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags) +{ + int div; + + div = clk_divider_bestdiv(cell, req->best_parent_cell, req->rate, + &req->best_parent_rate, table, width, flags); + + req->rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)req->best_parent_rate, div); + + return 0; +} + +static int divider_ro_determine_rate(struct rt_clk_cell *cell, struct clk_rate_request *req, + const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags, rt_uint32_t val) +{ + int div; + + div = _get_div(table, val, flags, width); + + /* Even a read-only clock can propagate a rate change */ + if (cell->flags & RT_CLK_F_SET_RATE_PARENT) + { + if (!req->best_parent_cell) + { + return -RT_EINVAL; + } + + req->best_parent_rate = rt_clk_cell_round_rate(req->best_parent_cell, req->rate * div); + } + + req->rate = RT_DIV_ROUND_UP_ULL((rt_uint64_t)req->best_parent_rate, div); + + return 0; +} + +static long divider_round_rate_parent(struct rt_clk_cell *cell, struct rt_clk_cell *parent, + rt_ubase_t rate, rt_ubase_t *prate, + const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags) +{ + int ret; + struct clk_rate_request req; + + req.rate = rate; + req.best_parent_rate = *prate; + req.best_parent_cell = parent; + + if ((ret = divider_determine_rate(cell, &req, table, width, flags))) + { + return ret; + } + + *prate = req.best_parent_rate; + + return req.rate; +} + +static long divider_ro_round_rate_parent(struct rt_clk_cell *cell, struct rt_clk_cell *parent, + rt_ubase_t rate, rt_ubase_t *prate, + const struct clk_div_table *table, rt_uint8_t width, rt_ubase_t flags, rt_uint32_t val) +{ + int ret; + struct clk_rate_request req; + + req.rate = rate; + req.best_parent_rate = *prate; + req.best_parent_cell = parent; + + if ((ret = divider_ro_determine_rate(cell, &req, table, width, flags, val))) + { + return ret; + } + + *prate = req.best_parent_rate; + + return req.rate; +} + +static rt_ubase_t divider_recalc_rate(rt_ubase_t parent_rate, rt_uint32_t val, + const struct clk_div_table *table, rt_ubase_t flags, rt_ubase_t width) +{ + rt_uint32_t div = _get_div(table, val, flags, width); + + if (!div) + { + return parent_rate; + } + + return RT_DIV_ROUND_UP_ULL((rt_uint64_t)parent_rate, div); +} + +static rt_ubase_t clk_divider_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate) +{ + rt_uint32_t val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + val = clk_div_readl(rk_cell) >> rk_cell->div_shift; + val &= clk_div_mask(rk_cell->div_width); + + return divider_recalc_rate(parent_rate, val, + rk_cell->div_table, rk_cell->div_flags, rk_cell->div_width); +} + +static rt_base_t clk_divider_round_rate(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t *prate) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + if (rk_cell->div_flags & CLK_DIVIDER_READ_ONLY) + { + rt_uint32_t val; + + val = clk_div_readl(rk_cell) >> rk_cell->div_shift; + val &= clk_div_mask(rk_cell->div_width); + + return divider_ro_round_rate_parent(cell, rt_clk_cell_get_parent(cell), + rate, prate, rk_cell->div_table, + rk_cell->div_width, rk_cell->div_flags, val); + } + + return divider_round_rate_parent(cell, rt_clk_cell_get_parent(cell), + rate, prate, rk_cell->div_table, + rk_cell->div_width, rk_cell->div_flags); +} + +static rt_err_t clk_divider_set_rate(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t parent_rate) +{ + int value; + rt_uint32_t val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + value = divider_get_val(rate, parent_rate, + rk_cell->div_table, rk_cell->div_width, rk_cell->div_flags); + + if (value < 0) + { + return value; + } + + if (rk_cell->div_flags & CLK_DIVIDER_HIWORD_MASK) + { + val = clk_div_mask(rk_cell->div_width) << (rk_cell->div_shift + 16); + } + else + { + val = clk_div_readl(rk_cell); + val &= ~(clk_div_mask(rk_cell->div_width) << rk_cell->div_shift); + } + val |= (rt_uint32_t)value << rk_cell->div_shift; + clk_div_writel(rk_cell, val); + + return 0; +} + +const struct rt_clk_ops clk_divider_ops = +{ + .recalc_rate = clk_divider_recalc_rate, + .round_rate = clk_divider_round_rate, + .set_rate = clk_divider_set_rate, +}; + +const struct rt_clk_ops clk_divider_ro_ops = +{ + .recalc_rate = clk_divider_recalc_rate, + .round_rate = clk_divider_round_rate, +}; + +void rockchip_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + if (rk_cell->div_flags & CLK_DIVIDER_READ_ONLY) + { + rk_cell->cell.ops = &clk_divider_ro_ops; + } + else + { + rk_cell->cell.ops = &clk_divider_ops; + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-divider.h b/bsp/rockchip/dm/clk/clk-rk-divider.h new file mode 100755 index 00000000000..5bf25094c86 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-divider.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_DIVIDER_H__ +#define __CLK_RK_DIVIDER_H__ + +#include "clk-rk.h" + +#define DIV(_id, cname, pname, f, o, s, w, df) \ +(void *)&(struct rockchip_clk_cell) \ +{ \ + .cell.name = cname, \ + .cell.parent_name = pname, \ + .cell.parents_nr = 1, \ + .cell.flags = f, \ + .id = _id, \ + .muxdiv_offset = o, \ + .div_shift = s, \ + .div_width = w, \ + .div_flags = df, \ + .gate_offset = -1, \ + .init = rockchip_divider_clk_cell_init, \ +} + +#define DIVTBL(_id, cname, pname, f, o, s, w, df, dt) \ +(void *)&(struct rockchip_clk_cell) \ +{ \ + .cell.name = cname, \ + .cell.parent_name = pname, \ + .cell.parents_nr = 1, \ + .cell.flags = f, \ + .id = _id, \ + .muxdiv_offset = o, \ + .div_shift = s, \ + .div_width = w, \ + .div_flags = df, \ + .div_table = dt, \ + .init = rockchip_divider_clk_cell_init, \ +} + +extern const struct rt_clk_ops clk_divider_ops, clk_divider_ro_ops; + +void rockchip_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_DIVIDER_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-factor.c b/bsp/rockchip/dm/clk/clk-rk-factor.c new file mode 100755 index 00000000000..eba11882009 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-factor.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-factor.h" +#include "clk-rk-gate.h" + +static rt_ubase_t clk_factor_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate) +{ + rt_uint64_t rate; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + rate = (rt_uint64_t)parent_rate * rk_cell->div_shift; + rt_do_div(rate, rk_cell->div_width); + + return (rt_ubase_t)rate; +} + +static rt_base_t clk_factor_round_rate(struct rt_clk_cell *cell, rt_ubase_t rate, rt_ubase_t *prate) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + if (cell->flags & RT_CLK_F_SET_RATE_PARENT) + { + rt_ubase_t best_parent; + + best_parent = (rate / rk_cell->div_shift) * rk_cell->div_width; + *prate = rt_clk_cell_round_rate(rt_clk_cell_get_parent(cell), best_parent); + } + + return (*prate / rk_cell->div_width) * rk_cell->div_shift; +} + +static rt_err_t clk_factor_set_rate(struct rt_clk_cell *cell, rt_ubase_t rate, rt_ubase_t parent_rate) +{ + return RT_EOK; +} + +void rockchip_factor_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_factor_clk_cell *factor_cell = cell_to_rockchip_factor_clk_cell(&rk_cell->cell); + + rk_cell->cell.ops = &factor_cell->ops; + + factor_cell->ops.recalc_rate = clk_factor_recalc_rate; + factor_cell->ops.round_rate = clk_factor_round_rate; + factor_cell->ops.set_rate = clk_factor_set_rate; + + if (rk_cell->gate_offset >= 0) + { + factor_cell->ops.enable = rockchip_gate_clk_ops.enable; + factor_cell->ops.disable = rockchip_gate_clk_ops.disable; + factor_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled; + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-factor.h b/bsp/rockchip/dm/clk/clk-rk-factor.h new file mode 100755 index 00000000000..18fc3c17a5d --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-factor.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_FACTOR_H__ +#define __CLK_RK_FACTOR_H__ + +#include "clk-rk.h" + +struct rockchip_factor_clk_cell +{ + struct rockchip_clk_cell rk_cell; + + struct rt_clk_ops ops; +}; + +#define FACTOR(_id, cname, pname, f, fm, fd) \ +(void *)&(struct rockchip_factor_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.div_shift = fm, \ + .rk_cell.div_width = fd, \ + .rk_cell.init = rockchip_factor_clk_cell_init, \ +} + +#define FACTOR_GATE(_id, cname, pname, f, fm, fd, go, gb, gf) \ +(void *)&(struct rockchip_factor_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.div_shift = fm, \ + .rk_cell.div_width = fd, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gb, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_factor_clk_cell_init, \ +} + +#define SGRF_GATE(_id, cname, pname) FACTOR(_id, cname, pname, 0, 1, 1) + +rt_inline struct rockchip_factor_clk_cell *cell_to_rockchip_factor_clk_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_factor_clk_cell, rk_cell); +} + +void rockchip_factor_clk_cell_init(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_FACTOR_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-fraction-divider.c b/bsp/rockchip/dm/clk/clk-rk-fraction-divider.c new file mode 100755 index 00000000000..4e632446274 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-fraction-divider.c @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-fraction-divider.h" +#include "clk-rk-mux.h" +#include "clk-rk-gate.h" + +struct u32_fract +{ + rt_uint32_t numerator; + rt_uint32_t denominator; +}; + +#define CLK_FD_MSHIFT 16 +#define CLK_FD_MWIDTH 16 +#define CLK_FD_NSHIFT 0 +#define CLK_FD_NWIDTH 16 + +rt_inline rt_uint32_t clk_fd_readl(struct rockchip_clk_cell *rk_cell) +{ + void *base = rk_cell->provider->reg_base; + + if (rk_cell->div_flags & CLK_FRAC_DIVIDER_BIG_ENDIAN) + { + return rt_be32_to_cpu(HWREG32(base + rk_cell->muxdiv_offset)); + } + + return HWREG32(base + rk_cell->muxdiv_offset); +} + +rt_inline void clk_fd_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val) +{ + void *base = rk_cell->provider->reg_base; + + if (rk_cell->div_flags & CLK_FRAC_DIVIDER_BIG_ENDIAN) + { + HWREG32(base + rk_cell->muxdiv_offset) = rt_cpu_to_be32(val); + } + else + { + HWREG32(base + rk_cell->muxdiv_offset) = val; + } +} + +static void clk_fd_get_div(struct rt_clk_cell *cell, struct u32_fract *fract) +{ + rt_ubase_t m, n; + rt_uint32_t val, mmask, nmask; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + val = clk_fd_readl(rk_cell); + + mmask = RT_GENMASK(CLK_FD_MWIDTH - 1, 0) << CLK_FD_MSHIFT; + nmask = RT_GENMASK(CLK_FD_NWIDTH - 1, 0) << CLK_FD_NSHIFT; + + m = (val & mmask) >> CLK_FD_MSHIFT; + n = (val & nmask) >> CLK_FD_NSHIFT; + + if (rk_cell->div_flags & CLK_FRAC_DIVIDER_ZERO_BASED) + { + ++m; + ++n; + } + + fract->numerator = m; + fract->denominator = n; +} + +static rt_ubase_t clk_fd_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate) +{ + rt_uint64_t ret; + struct u32_fract fract; + + clk_fd_get_div(cell, &fract); + + if (!fract.numerator || !fract.denominator) + { + return parent_rate; + } + + ret = (rt_uint64_t)parent_rate * fract.numerator; + rt_do_div(ret, fract.denominator); + + return ret; +} + +static void clk_fractional_divider_general_approximation(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t *parent_rate, rt_ubase_t *m, rt_ubase_t *n) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + /* + * Get rate closer to *parent_rate to guarantee there is no overflow + * for m and n. In the result it will be the nearest rate left shifted + * by (scale - CLK_FD_NWIDTH) bits. + * + * For the detailed explanation see the top comment in this file. + */ + if (rk_cell->div_flags & CLK_FRAC_DIVIDER_POWER_OF_TWO_PS) + { + rt_ubase_t scale = fls_long(*parent_rate / rate - 1); + + if (scale > CLK_FD_NWIDTH) + { + rate <<= scale - CLK_FD_NWIDTH; + } + } + + rational_best_approximation(rate, *parent_rate, + RT_GENMASK(CLK_FD_MWIDTH - 1, 0), RT_GENMASK(CLK_FD_NWIDTH - 1, 0), m, n); +} + +/* + * fractional divider must set that denominator is 20 times larger than + * numerator to generate precise clock frequency. + */ +static void rockchip_fractional_approximation(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t *parent_rate, rt_ubase_t *m, rt_ubase_t *n) +{ + struct rt_clk_cell *p_parent; + rt_ubase_t p_rate, p_parent_rate; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + if (rate == 0) + { + *m = 0; + *n = 1; + return; + } + + p_rate = rt_clk_cell_get_rate(rt_clk_cell_get_parent(cell)); + + if (rate * 20 > p_rate && p_rate % rate != 0) + { + p_parent = rt_clk_cell_get_parent(rt_clk_cell_get_parent(cell)); + + if (!p_parent) + { + *parent_rate = p_rate; + } + else + { + p_parent_rate = rt_clk_cell_get_rate(p_parent); + *parent_rate = p_parent_rate; + } + + if (*parent_rate == 0) + { + *m = 0; + *n = 1; + return; + } + + if (*parent_rate < rate * 20) + { + /* + * Fractional frequency divider to do + * integer frequency divider does not need 20 times the limit. + */ + if (!(*parent_rate % rate)) + { + *m = 1; + *n = *parent_rate / rate; + return; + } + else if (!(rk_cell->div_flags & CLK_FRAC_DIVIDER_NO_LIMIT)) + { + *m = 0; + *n = 1; + return; + } + } + } + + rk_cell->div_flags |= CLK_FRAC_DIVIDER_POWER_OF_TWO_PS; + + clk_fractional_divider_general_approximation(cell, rate, parent_rate, m, n); +} + +static rt_base_t clk_fd_round_rate(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t *parent_rate) +{ + rt_ubase_t m, n; + rt_uint64_t ret; + + if (!rate || rate >= *parent_rate) + { + return *parent_rate; + } + + rockchip_fractional_approximation(cell, rate, parent_rate, &m, &n); + + ret = (rt_uint64_t)*parent_rate * m; + rt_do_div(ret, n); + + return ret; +} + +static rt_err_t clk_fd_set_rate(struct rt_clk_cell *cell, rt_ubase_t rate, rt_ubase_t parent_rate) +{ + rt_ubase_t m, n; + rt_uint32_t mmask, nmask, val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + rational_best_approximation(rate, parent_rate, + RT_GENMASK(CLK_FD_MWIDTH - 1, 0), RT_GENMASK(CLK_FD_NWIDTH - 1, 0), &m, &n); + + if (rk_cell->div_flags & CLK_FRAC_DIVIDER_ZERO_BASED) + { + --m; + --n; + } + + mmask = RT_GENMASK(CLK_FD_MWIDTH - 1, 0) << CLK_FD_MSHIFT; + nmask = RT_GENMASK(CLK_FD_NWIDTH - 1, 0) << CLK_FD_NSHIFT; + + /* + * When compensation the fractional divider, + * the [1:0] bits of the numerator register are omitted, + * which will lead to a large deviation in the result. + * Therefore, it is required that the numerator must + * be greater than 4. + * + * Note that there are some exceptions here: + * If there is an even frac div, we need to keep the original + * numerator(<4) and denominator. Otherwise, it may cause the + * issue that the duty ratio is not 50%. + */ + if (m < 4 && m != 0) + { + if (n % 2 == 0) + { + val = 1; + } + else + { + val = RT_DIV_ROUND_UP(4, m); + } + + n *= val; + m *= val; + + if (n > nmask) + { + n = nmask; + } + } + + mmask = RT_GENMASK(CLK_FD_MWIDTH - 1, 0) << CLK_FD_MSHIFT; + nmask = RT_GENMASK(CLK_FD_NWIDTH - 1, 0) << CLK_FD_NSHIFT; + + val = clk_fd_readl(rk_cell); + val &= ~(mmask | nmask); + val |= (m << CLK_FD_MSHIFT) | (n << CLK_FD_NSHIFT); + clk_fd_writel(rk_cell, val); + + return RT_EOK; +} + +static rt_err_t rockchip_clk_frac_notify(struct rt_clk_notifier *notifier, + rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate) +{ + struct rt_clk_cell *cell; + struct rockchip_fraction_divider_clk_cell *fraction_divider_cell; + + fraction_divider_cell = rt_container_of(notifier, struct rockchip_fraction_divider_clk_cell, notifier); + cell = &fraction_divider_cell->rk_cell_child->cell; + + if (msg == RT_CLK_MSG_PRE_RATE_CHANGE) + { + fraction_divider_cell->rate_change_idx = cell->ops->get_parent(cell); + + if (fraction_divider_cell->rate_change_idx != fraction_divider_cell->mux_frac_idx) + { + cell->ops->set_parent(cell, fraction_divider_cell->mux_frac_idx); + fraction_divider_cell->rate_change_remuxed = 1; + } + } + else if (msg == RT_CLK_MSG_POST_RATE_CHANGE) + { + /* + * The RT_CLK_MSG_POST_RATE_CHANGE notifier runs directly after the + * divider clock is set in clk_change_rate, so we'll have + * remuxed back to the original parent before clk_change_rate + * reaches the mux itself. + */ + if (fraction_divider_cell->rate_change_remuxed) + { + cell->ops->set_parent(cell, fraction_divider_cell->rate_change_idx); + fraction_divider_cell->rate_change_remuxed = 0; + } + } + + return RT_EOK; +} + +static int match_string(const char * const *array, size_t n, const char *string) +{ + for (int index = 0; index < n; ++index) + { + const char *item = array[index]; + + if (!item) + { + break; + } + if (!rt_strcmp(item, string)) + { + return index; + } + } + + return -RT_EINVAL; +} + +void rockchip_fraction_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_fraction_divider_clk_cell *fraction_divider_cell = cell_to_rockchip_fraction_divider_clk_cell(&rk_cell->cell); + + rk_cell->cell.ops = &fraction_divider_cell->ops; + rk_cell->cell.flags |= RT_CLK_F_SET_RATE_UNGATE; + + if (fraction_divider_cell->rk_cell_child) + { + struct rockchip_clk_cell *rk_cell_child = fraction_divider_cell->rk_cell_child; + struct rt_clk_cell *cell = &rk_cell_child->cell; + + rk_cell_child->cell.flags |= RT_CLK_F_SET_RATE_PARENT; + + fraction_divider_cell->mux_frac_idx = match_string(cell->parent_names, cell->parents_nr, + rk_cell->cell.name); + + rockchip_mux_clk_cell_init(rk_cell); + + fraction_divider_cell->ops.get_parent = rockchip_mux_clk_ops.get_parent; + fraction_divider_cell->ops.set_parent = rockchip_mux_clk_ops.set_parent; + } + + if (rk_cell->gate_offset >= 0) + { + fraction_divider_cell->ops.enable = rockchip_gate_clk_ops.enable; + fraction_divider_cell->ops.disable = rockchip_gate_clk_ops.disable; + fraction_divider_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled; + } + + fraction_divider_cell->ops.recalc_rate = clk_fd_recalc_rate; + fraction_divider_cell->ops.round_rate = clk_fd_round_rate; + fraction_divider_cell->ops.set_rate = clk_fd_set_rate; +} + +void rockchip_fraction_divider_clk_cell_setup(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_fraction_divider_clk_cell *fraction_divider_cell = cell_to_rockchip_fraction_divider_clk_cell(&rk_cell->cell); + struct rockchip_clk_cell *rk_cell_child = fraction_divider_cell->rk_cell_child; + + if (fraction_divider_cell->mux_frac_idx >= 0) + { + fraction_divider_cell->notifier.callback = rockchip_clk_frac_notify; + + rt_clk_notifier_register(rt_clk_cell_get_clk(&rk_cell_child->cell, RT_NULL), + &fraction_divider_cell->notifier); + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-fraction-divider.h b/bsp/rockchip/dm/clk/clk-rk-fraction-divider.h new file mode 100755 index 00000000000..4ee303b4045 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-fraction-divider.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_FRACTION_DIVIDER_H__ +#define __CLK_RK_FRACTION_DIVIDER_H__ + +#include "clk-rk.h" + +struct rockchip_fraction_divider_clk_cell +{ + struct rockchip_clk_cell rk_cell; + + struct rt_clk_ops ops; + struct rockchip_clk_cell *rk_cell_child; + + int mux_frac_idx; + int rate_change_idx; + int rate_change_remuxed; + struct rt_clk_notifier notifier; +}; + +#define COMPOSITE_FRAC(_id, cname, pname, f, mo, df, go, gs, gf)\ +(void *)&(struct rockchip_fraction_divider_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.div_shift = 16, \ + .rk_cell.div_width = 16, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_fraction_divider_clk_cell_init, \ +} + +#define COMPOSITE_FRACMUX(_id, cname, pname, f, mo, df, go, gs, gf, ch) \ +(void *)&(struct rockchip_fraction_divider_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.div_shift = 16, \ + .rk_cell.div_width = 16, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_fraction_divider_clk_cell_init, \ + .rk_cell.setup = rockchip_fraction_divider_clk_cell_setup, \ + .rk_cell_child = ch, \ +} + +#define COMPOSITE_FRACMUX_NOGATE(_id, cname, pname, f, mo, df, ch) \ +(void *)&(struct rockchip_fraction_divider_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.div_shift = 16, \ + .rk_cell.div_width = 16, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = -1, \ + .rk_cell.init = rockchip_fraction_divider_clk_cell_init, \ + .rk_cell.setup = rockchip_fraction_divider_clk_cell_setup, \ + .rk_cell_child = ch, \ +} + +rt_inline struct rockchip_fraction_divider_clk_cell *cell_to_rockchip_fraction_divider_clk_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_fraction_divider_clk_cell, rk_cell); +} + +void rockchip_fraction_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell); +void rockchip_fraction_divider_clk_cell_setup(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_FRACTION_DIVIDER_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-gate.c b/bsp/rockchip/dm/clk/clk-rk-gate.c new file mode 100755 index 00000000000..7846b71ac99 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-gate.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-gate.h" + +rt_inline rt_uint32_t clk_gate_readl(struct rockchip_clk_cell *rk_cell) +{ + void *base = rk_cell->provider->reg_base; + + if (rk_cell->gate_flags & CLK_GATE_BIG_ENDIAN) + { + return rt_be32_to_cpu(HWREG32(base + rk_cell->gate_offset)); + } + + return HWREG32(base + rk_cell->gate_offset); +} + +rt_inline void clk_gate_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val) +{ + void *base = rk_cell->provider->reg_base; + + if (rk_cell->gate_flags & CLK_GATE_BIG_ENDIAN) + { + HWREG32(base + rk_cell->gate_offset) = rt_cpu_to_be32(val); + } + else + { + HWREG32(base + rk_cell->gate_offset) = val; + } +} + +static void clk_gate_endisable(struct rt_clk_cell *cell, int enable) +{ + int set; + rt_uint32_t reg; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + set = rk_cell->gate_flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; + set ^= enable; + + if (rk_cell->gate_flags & CLK_GATE_HIWORD_MASK) + { + reg = RT_BIT(rk_cell->gate_shift + 16); + + if (set) + { + reg |= RT_BIT(rk_cell->gate_shift); + } + } + else + { + reg = clk_gate_readl(rk_cell); + + if (set) + { + reg |= RT_BIT(rk_cell->gate_shift); + } + else + { + reg &= ~RT_BIT(rk_cell->gate_shift); + } + } + + clk_gate_writel(rk_cell, reg); +} + +static rt_err_t rockchip_gate_clk_enable(struct rt_clk_cell *cell) +{ + clk_gate_endisable(cell, 1); + + return RT_EOK; +} + +static void rockchip_gate_clk_disable(struct rt_clk_cell *cell) +{ + clk_gate_endisable(cell, 0); +} + +static rt_bool_t rockchip_gate_clk_is_enabled(struct rt_clk_cell *cell) +{ + rt_uint32_t reg; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + reg = clk_gate_readl(rk_cell); + + /* If a set bit disables this clk, flip it before masking */ + if (rk_cell->gate_flags & CLK_GATE_SET_TO_DISABLE) + { + reg ^= RT_BIT(rk_cell->gate_shift); + } + + reg &= RT_BIT(rk_cell->gate_shift); + + return !!reg; +} + +const struct rt_clk_ops rockchip_gate_clk_ops = +{ + .enable = rockchip_gate_clk_enable, + .disable = rockchip_gate_clk_disable, + .is_enabled = rockchip_gate_clk_is_enabled, +}; diff --git a/bsp/rockchip/dm/clk/clk-rk-gate.h b/bsp/rockchip/dm/clk/clk-rk-gate.h new file mode 100755 index 00000000000..4683218a7db --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-gate.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_GATE_H__ +#define __CLK_RK_GATE_H__ + +#include "clk-rk.h" + +#define GATE(_id, cname, pname, f, o, b, gf) \ +(void *)&(struct rockchip_clk_cell) \ +{ \ + .cell.name = cname, \ + .cell.ops = &rockchip_gate_clk_ops, \ + .cell.parent_name = pname, \ + .cell.parents_nr = 1, \ + .cell.flags = f | RT_CLK_F_SET_RATE_PARENT, \ + .id = _id, \ + .gate_offset = o, \ + .gate_shift = b, \ + .gate_flags = gf, \ +} + +extern const struct rt_clk_ops rockchip_gate_clk_ops; + +#endif /* __CLK_RK_GATE_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-half-divider.c b/bsp/rockchip/dm/clk/clk-rk-half-divider.c new file mode 100755 index 00000000000..43238dd8129 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-half-divider.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-half-divider.h" +#include "clk-rk-gate.h" +#include "clk-rk-mux.h" + +#define clk_div_mask(width) ((1 << (width)) - 1) + +static rt_bool_t _is_best_half_div(rt_ubase_t rate, rt_ubase_t now, + rt_ubase_t best, rt_ubase_t flags) +{ + if (flags & CLK_DIVIDER_ROUND_CLOSEST) + { + return rt_abs(rate - now) <= rt_abs(rate - best); + } + + return now <= rate && now >= best; +} + +rt_inline rt_uint32_t clk_div_readl(struct rockchip_clk_cell *rk_cell) +{ + return HWREG32(rk_cell->provider->reg_base + (rk_cell->div_offset ? : rk_cell->muxdiv_offset)); +} + +rt_inline void clk_div_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val) +{ + HWREG32(rk_cell->provider->reg_base + (rk_cell->div_offset ? : rk_cell->muxdiv_offset)) = val; +} + +static rt_ubase_t clk_div_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate) +{ + rt_uint32_t val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + val = clk_div_readl(rk_cell) >> rk_cell->div_shift; + val &= clk_div_mask(rk_cell->div_width); + val = val * 2 + 3; + + return RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), val); +} + +static int clk_div_bestdiv(struct rt_clk_cell *cell, rt_ubase_t rate, + rt_ubase_t *best_parent_rate, rt_uint8_t width, rt_ubase_t flags) +{ + rt_uint32_t bestdiv = 0; + rt_bool_t is_bestdiv = RT_FALSE; + rt_ubase_t parent_rate, best = 0, now, maxdiv; + + if (!rate) + { + rate = 1; + } + + maxdiv = clk_div_mask(width); + + if (!(cell->flags & RT_CLK_F_SET_RATE_PARENT)) + { + parent_rate = *best_parent_rate; + bestdiv = RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), rate); + + if (bestdiv < 3) + { + bestdiv = 0; + } + else + { + bestdiv = RT_DIV_ROUND_UP(bestdiv - 3, 2); + } + + bestdiv = bestdiv > maxdiv ? maxdiv : bestdiv; + + return bestdiv; + } + + /* + * The maximum divider we can use without overflowing + * rt_ubase_t in rate * i below + */ + maxdiv = rt_min((~0UL) / rate, maxdiv); + + for (int i = 0; i <= maxdiv; ++i) + { + parent_rate = rt_clk_cell_round_rate(rt_clk_cell_get_parent(cell), + ((rt_uint64_t)rate * (i * 2 + 3)) / 2); + now = RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), (i * 2 + 3)); + + if (_is_best_half_div(rate, now, best, flags)) + { + is_bestdiv = RT_TRUE; + bestdiv = i; + best = now; + *best_parent_rate = parent_rate; + } + } + + if (!is_bestdiv) + { + bestdiv = clk_div_mask(width); + *best_parent_rate = rt_clk_cell_round_rate(rt_clk_cell_get_parent(cell), 1); + } + + return bestdiv; +} + +static rt_base_t clk_div_round_rate(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t *prate) +{ + int div; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + div = clk_div_bestdiv(cell, rate, prate, rk_cell->div_width, rk_cell->div_flags); + + return RT_DIV_ROUND_UP_ULL(((rt_uint64_t)*prate * 2), div * 2 + 3); +} + +static rt_err_t clk_div_set_rate(struct rt_clk_cell *cell, + rt_ubase_t rate, rt_ubase_t parent_rate) +{ + rt_uint32_t value, val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + value = RT_DIV_ROUND_UP_ULL(((rt_uint64_t)parent_rate * 2), rate); + value = RT_DIV_ROUND_UP(value - 3, 2); + value = rt_min_t(rt_uint32_t, value, clk_div_mask(rk_cell->div_width)); + + if (rk_cell->div_flags & CLK_DIVIDER_HIWORD_MASK) + { + val = clk_div_mask(rk_cell->div_width) << (rk_cell->div_shift + 16); + } + else + { + val = clk_div_readl(rk_cell); + val &= ~(clk_div_mask(rk_cell->div_width) << rk_cell->div_shift); + } + + val |= value << rk_cell->div_shift; + clk_div_writel(rk_cell, val); + + return RT_EOK; +} + +void rockchip_half_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_half_divider_clk_cell *half_divider_cell = cell_to_rockchip_half_divider_clk_cell(&rk_cell->cell); + + rk_cell->cell.ops = &half_divider_cell->ops; + + if (rk_cell->cell.parents_nr > 1) + { + rockchip_mux_clk_cell_init(rk_cell); + + half_divider_cell->ops.get_parent = rockchip_mux_clk_ops.get_parent; + + if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY))) + { + half_divider_cell->ops.set_parent = rockchip_mux_clk_ops.set_parent; + } + } + + if (rk_cell->gate_offset >= 0) + { + half_divider_cell->ops.enable = rockchip_gate_clk_ops.enable; + half_divider_cell->ops.disable = rockchip_gate_clk_ops.disable; + half_divider_cell->ops.is_enabled = rockchip_gate_clk_ops.is_enabled; + half_divider_cell->ops.recalc_rate = clk_div_recalc_rate; + half_divider_cell->ops.round_rate = clk_div_round_rate; + half_divider_cell->ops.set_rate = clk_div_set_rate; + } + + if (rk_cell->div_width > 0) + { + half_divider_cell->ops.set_rate = clk_div_set_rate; + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-half-divider.h b/bsp/rockchip/dm/clk/clk-rk-half-divider.h new file mode 100755 index 00000000000..2f801867e24 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-half-divider.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_HALF_DIVIDER_H__ +#define __CLK_RK_HALF_DIVIDER_H__ + +#include "clk-rk.h" + +struct rockchip_half_divider_clk_cell +{ + struct rockchip_clk_cell rk_cell; + + struct rt_clk_ops ops; +}; + +#define COMPOSITE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df, go, gs, gf) \ +(void *)&(struct rockchip_half_divider_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_half_divider_clk_cell_init,\ +} + +#define COMPOSITE_HALFDIV_OFFSET(_id, cname, pnames, f, mo, ms, mw, mf, do, ds, dw, df, go, gs, gf) \ +(void *)&(struct rockchip_half_divider_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_offset = do, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_half_divider_clk_cell_init,\ +} + +#define COMPOSITE_NOGATE_HALFDIV(_id, cname, pnames, f, mo, ms, mw, mf, ds, dw, df) \ +(void *)&(struct rockchip_half_divider_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_names = pnames, \ + .rk_cell.cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.mux_shift = ms, \ + .rk_cell.mux_width = mw, \ + .rk_cell.mux_flags = mf, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = -1, \ + .rk_cell.init = rockchip_half_divider_clk_cell_init,\ +} + +#define COMPOSITE_NOMUX_HALFDIV(_id, cname, pname, f, mo, ds, dw, df, go, gs, gf) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = mo, \ + .rk_cell.div_shift = ds, \ + .rk_cell.div_width = dw, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = go, \ + .rk_cell.gate_shift = gs, \ + .rk_cell.gate_flags = gf, \ + .rk_cell.init = rockchip_half_divider_clk_cell_init,\ +} + +#define DIV_HALF(_id, cname, pname, f, o, s, w, df) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.cell.flags = f, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = o, \ + .rk_cell.div_shift = s, \ + .rk_cell.div_width = w, \ + .rk_cell.div_flags = df, \ + .rk_cell.gate_offset = -1, \ + .rk_cell.init = rockchip_half_divider_clk_cell_init,\ +} + +rt_inline struct rockchip_half_divider_clk_cell *cell_to_rockchip_half_divider_clk_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_half_divider_clk_cell, rk_cell); +} + +void rockchip_half_divider_clk_cell_init(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_HALF_DIVIDER_H__ */ diff --git a/bsp/rockchip/rk3500/driver/clk/clk-mmc-phase.c b/bsp/rockchip/dm/clk/clk-rk-mmc-phase.c old mode 100644 new mode 100755 similarity index 54% rename from bsp/rockchip/rk3500/driver/clk/clk-mmc-phase.c rename to bsp/rockchip/dm/clk/clk-rk-mmc-phase.c index a27c921cc6a..111d8c089ad --- a/bsp/rockchip/rk3500/driver/clk/clk-mmc-phase.c +++ b/bsp/rockchip/dm/clk/clk-rk-mmc-phase.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -8,10 +8,11 @@ * 2022-3-08 GuEe-GUI the first version */ -#define ROCKCHIP_MMC_DELAY_SEL RT_BIT(11) -#define ROCKCHIP_MMC_DEGREE_OFFSET 1 -#define ROCKCHIP_MMC_DEGREE_MASK (0x3 << ROCKCHIP_MMC_DEGREE_OFFSET) -#define ROCKCHIP_MMC_DELAYNUM_OFFSET 3 +#include "clk-rk-mmc-phase.h" + +#define ROCKCHIP_MMC_DELAY_SEL RT_BIT(10) +#define ROCKCHIP_MMC_DEGREE_MASK 0x3 +#define ROCKCHIP_MMC_DELAYNUM_OFFSET 2 #define ROCKCHIP_MMC_DELAYNUM_MASK (0xff << ROCKCHIP_MMC_DELAYNUM_OFFSET) /* * Each fine delay is between 44ps-77ps. Assume each fine delay is 60ps to @@ -19,20 +20,24 @@ */ #define ROCKCHIP_MMC_DELAY_ELEMENT_PSEC 60 -#define PSECS_PER_SEC 1000000000000LL +#define PSECS_PER_SEC 1000000000000LL -#define RK3288_MMC_CLKGEN_DIV 2 +#define RK3288_MMC_CLKGEN_DIV 2 -rt_inline rt_ubase_t rk_clk_mmc_recalc(rt_ubase_t parent_rate) +static rt_ubase_t rockchip_mmc_recalc(struct rt_clk_cell *cell, rt_ubase_t parent_rate) { return parent_rate / RK3288_MMC_CLKGEN_DIV; } -static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift, - int degrees) +static rt_err_t rockchip_mmc_set_phase(struct rt_clk_cell *cell, int degrees) { + rt_ubase_t rate; rt_uint32_t raw_value, delay; rt_uint8_t nineties, remainder, delay_num; + struct rockchip_mmc_clk_cell *mmc_cell = cell_to_rockchip_mmc_clk_cell(cell); + struct rockchip_clk_cell *rk_cell = &mmc_cell->rk_cell; + + rate = rt_clk_cell_get_rate(cell); /* * The below calculation is based on the output clock from @@ -48,8 +53,6 @@ static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift, */ if (!rate) { - LOG_E("Invalid CLK rate in phase setting"); - return -RT_EINVAL; } @@ -81,23 +84,30 @@ static rt_err_t rk_clk_mmc_set_phase(rt_ubase_t rate, void *reg, int shift, */ delay = 10000000; /* PSECS_PER_SEC / 10000 / 10 */ delay *= remainder; - delay = RT_DIV_ROUND_CLOSEST(delay, (rate / 1000) * 36 * - (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); + delay = RT_DIV_ROUND_CLOSEST(delay, + (rate / 1000) * 36 * (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10)); delay_num = (rt_uint8_t)rt_min_t(rt_uint32_t, delay, 255); raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0; raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET; raw_value |= nineties; - HWREG32(reg) = HIWORD_UPDATE(raw_value, 0x07ff, shift); + + HWREG32(rk_cell->provider->reg_base + rk_cell->muxdiv_offset) = + HIWORD_UPDATE(raw_value, 0x07ff, rk_cell->div_shift); return RT_EOK; } -static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift) +static rt_base_t rockchip_mmc_get_phase(struct rt_clk_cell *cell) { + rt_ubase_t rate; rt_uint16_t degrees; rt_uint32_t raw_value, delay_num = 0; + struct rockchip_mmc_clk_cell *mmc_cell = cell_to_rockchip_mmc_clk_cell(cell); + struct rockchip_clk_cell *rk_cell = &mmc_cell->rk_cell; + + rate = rt_clk_cell_get_rate(cell); /* Constant signal, no measurable phase shift */ if (!rate) @@ -105,14 +115,14 @@ static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift) return 0; } - raw_value = HWREG32(reg) >> shift; + raw_value = HWREG32(rk_cell->provider->reg_base + rk_cell->muxdiv_offset) >> rk_cell->div_shift; + degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90; if (raw_value & ROCKCHIP_MMC_DELAY_SEL) { /* degrees/delaynum * 1000000 */ - rt_ubase_t factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * - 36 * (rate / 10000); + rt_ubase_t factor = (ROCKCHIP_MMC_DELAY_ELEMENT_PSEC / 10) * 36 * (rate / 10000); delay_num = (raw_value & ROCKCHIP_MMC_DELAYNUM_MASK); delay_num >>= ROCKCHIP_MMC_DELAYNUM_OFFSET; @@ -121,3 +131,42 @@ static rt_base_t rk_clk_mmc_get_phase(rt_ubase_t rate, void *reg, int shift) return degrees % 360; } + +const struct rt_clk_ops rockchip_mmc_clk_ops = +{ + .recalc_rate = rockchip_mmc_recalc, + .set_phase = rockchip_mmc_set_phase, + .get_phase = rockchip_mmc_get_phase, +}; + +static rt_err_t rockchip_mmc_clk_rate_notify(struct rt_clk_notifier *notifier, + rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate) +{ + struct rockchip_mmc_clk_cell *mmc_cell = rt_container_of(notifier, struct rockchip_mmc_clk_cell, notifier); + + if (old_rate <= new_rate) + { + return RT_EOK; + } + + if (msg == RT_CLK_MSG_PRE_RATE_CHANGE) + { + mmc_cell->cached_phase = rockchip_mmc_get_phase(&mmc_cell->rk_cell.cell); + } + else if (mmc_cell->cached_phase != -RT_EINVAL && msg == RT_CLK_MSG_POST_RATE_CHANGE) + { + rockchip_mmc_set_phase(&mmc_cell->rk_cell.cell, mmc_cell->cached_phase); + } + + return RT_EOK; +} + +void rockchip_mmc_clk_cell_setup(struct rockchip_clk_cell *rk_cell) +{ + struct rt_clk_cell *cell = &rk_cell->cell; + struct rockchip_mmc_clk_cell *mmc_cell = cell_to_rockchip_mmc_clk_cell(cell); + + mmc_cell->notifier.callback = rockchip_mmc_clk_rate_notify; + + rt_clk_notifier_register(rt_clk_cell_get_clk(cell, RT_NULL), &mmc_cell->notifier); +} diff --git a/bsp/rockchip/dm/clk/clk-rk-mmc-phase.h b/bsp/rockchip/dm/clk/clk-rk-mmc-phase.h new file mode 100755 index 00000000000..b5ccec2a605 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-mmc-phase.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_MMC_PHASE_H__ +#define __CLK_RK_MMC_PHASE_H__ + +#include "clk-rk.h" + +struct rockchip_mmc_clk_cell +{ + struct rockchip_clk_cell rk_cell; + + int cached_phase; + struct rt_clk_notifier notifier; +}; + +#define MMC(_id, cname, pname, offset, shift) \ +(void *)&(struct rockchip_mmc_clk_cell) \ +{ \ + .rk_cell.cell.name = cname, \ + .rk_cell.cell.ops = &rockchip_mmc_clk_ops, \ + .rk_cell.cell.parent_name = pname, \ + .rk_cell.cell.parents_nr = 1, \ + .rk_cell.id = _id, \ + .rk_cell.muxdiv_offset = offset, \ + .rk_cell.div_shift = shift, \ + .rk_cell.setup = rockchip_mmc_clk_cell_setup, \ +} + +extern const struct rt_clk_ops rockchip_mmc_clk_ops; + +rt_inline struct rockchip_mmc_clk_cell *cell_to_rockchip_mmc_clk_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_mmc_clk_cell, rk_cell); +} + +void rockchip_mmc_clk_cell_setup(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_MMC_PHASE_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-mux.c b/bsp/rockchip/dm/clk/clk-rk-mux.c new file mode 100755 index 00000000000..be7f2de026b --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-mux.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-mux.h" + +rt_inline rt_uint32_t clk_mux_readl(struct rockchip_clk_cell *rk_cell) +{ + void *base = rk_cell->provider->reg_base; + + if (rk_cell->mux_flags & CLK_MUX_BIG_ENDIAN) + { + return rt_be32_to_cpu(HWREG32(base + rk_cell->muxdiv_offset)); + } + + return HWREG32(base + rk_cell->muxdiv_offset); +} + +rt_inline void clk_mux_writel(struct rockchip_clk_cell *rk_cell, rt_uint32_t val) +{ + void *base = rk_cell->provider->reg_base; + + if (rk_cell->mux_flags & CLK_MUX_BIG_ENDIAN) + { + HWREG32(base + rk_cell->muxdiv_offset) = rt_cpu_to_be32(val); + } + else + { + HWREG32(base + rk_cell->muxdiv_offset) = val; + } +} + +static int clk_mux_val_to_index(struct rt_clk_cell *cell, + const rt_uint32_t *table, rt_uint32_t flags, rt_uint32_t val) +{ + int num_parents = cell->parents_nr; + + if (table) + { + for (int i = 0; i < num_parents; ++i) + { + if (table[i] == val) + { + return i; + } + } + + return -RT_EINVAL; + } + + if (val && (flags & CLK_MUX_INDEX_BIT)) + { + val = __rt_ffs(val) - 1; + } + + if (val && (flags & CLK_MUX_INDEX_ONE)) + { + --val; + } + + if (val >= num_parents) + { + return -RT_EINVAL; + } + + return val; +} + +static rt_uint32_t clk_mux_index_to_val(const rt_uint32_t *table, rt_uint32_t flags, rt_uint8_t index) +{ + rt_uint32_t val = index; + + if (table) + { + val = table[index]; + } + else + { + if (flags & CLK_MUX_INDEX_BIT) + { + val = 1 << index; + } + + if (flags & CLK_MUX_INDEX_ONE) + { + val++; + } + } + + return val; +} + +static rt_err_t rockchip_mux_clk_set_parent(struct rt_clk_cell *cell, rt_uint8_t index) +{ + rt_uint32_t val, reg; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + val = clk_mux_index_to_val(rk_cell->mux_table, rk_cell->mux_flags, index); + + if (rk_cell->mux_flags & CLK_MUX_HIWORD_MASK) + { + reg = rk_cell->mux_mask << (rk_cell->mux_shift + 16); + } + else + { + reg = clk_mux_readl(rk_cell); + reg &= ~(rk_cell->mux_mask << rk_cell->mux_shift); + } + val = val << rk_cell->mux_shift; + reg |= val; + clk_mux_writel(rk_cell, reg); + + return RT_EOK; +} + +static rt_uint8_t rockchip_mux_clk_get_parent(struct rt_clk_cell *cell) +{ + rt_uint32_t val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + val = clk_mux_readl(rk_cell) >> rk_cell->mux_shift; + val &= rk_cell->mux_mask; + + return clk_mux_val_to_index(cell, rk_cell->mux_table, rk_cell->mux_flags, val); +} + +const struct rt_clk_ops rockchip_mux_clk_ops = +{ + .set_parent = rockchip_mux_clk_set_parent, + .get_parent = rockchip_mux_clk_get_parent, +}; + +const struct rt_clk_ops rockchip_mux_ro_clk_ops = +{ + .get_parent = rockchip_mux_clk_get_parent, +}; + +void rockchip_mux_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + rk_cell->mux_mask = RT_BIT(rk_cell->mux_width) - 1; + + if (!rk_cell->cell.ops) + { + if (!((rk_cell->mux_flags & CLK_MUX_READ_ONLY))) + { + rk_cell->cell.ops = &rockchip_mux_clk_ops; + } + else + { + rk_cell->cell.ops = &rockchip_mux_ro_clk_ops; + } + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-mux.h b/bsp/rockchip/dm/clk/clk-rk-mux.h new file mode 100755 index 00000000000..0ed8bd10026 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-mux.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_MUX_H__ +#define __CLK_RK_MUX_H__ + +#include "clk-rk.h" + +#define MUX_RAW(_id, cname, pnames, f, o, s, w, mf) \ +{ \ + .cell.name = cname, \ + .cell.parent_names = pnames, \ + .cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .cell.flags = f, \ + .id = _id, \ + .muxdiv_offset = o, \ + .mux_shift = s, \ + .mux_width = w, \ + .mux_flags = mf, \ + .gate_offset = -1, \ + .init = rockchip_mux_clk_cell_init, \ +} + +#define MUX(_id, cname, pnames, f, o, s, w, mf) \ + (void *)&(struct rockchip_clk_cell)MUX_RAW(_id, cname, pnames, f, o, s, w, mf) + +#define MUXTBL_RAW(_id, cname, pnames, f, o, s, w, mf, mt) \ +{ \ + .cell.name = cname, \ + .cell.parent_names = pname, \ + .cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .cell.flags = f, \ + .id = _id, \ + .muxdiv_offset = o, \ + .mux_shift = s, \ + .mux_width = w, \ + .mux_flags = mf, \ + .gate_offset = -1, \ + .mux_table = mt, \ + .init = rockchip_mux_clk_cell_init, \ +} + +#define MUXTBL(_id, cname, pnames, f, o, s, w, mf, mt) \ + (void *)&(struct rockchip_clk_cell)MUXTBL_RAW(_id, cname, pnames, f, o, s, w, mf, mt) + +extern const struct rt_clk_ops rockchip_mux_clk_ops, rockchip_mux_ro_clk_ops; + +void rockchip_mux_clk_cell_init(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_MUX_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-muxgrf.c b/bsp/rockchip/dm/clk/clk-rk-muxgrf.c new file mode 100755 index 00000000000..795b46a6165 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-muxgrf.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-muxgrf.h" + +static rt_err_t rockchip_muxgrf_set_parent_common(struct rt_clk_cell *cell, struct rt_syscon *grf, + rt_uint8_t index) +{ + rt_uint32_t mask, val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + mask = RT_GENMASK(rk_cell->mux_width + rk_cell->mux_shift - 1, rk_cell->mux_shift); + + val = index; + val <<= rk_cell->mux_shift; + + if (rk_cell->mux_flags & CLK_MUX_HIWORD_MASK) + { + return rt_syscon_write(grf, rk_cell->muxdiv_offset, val | (mask << 16)); + } + + return rt_syscon_update_bits(grf, rk_cell->muxdiv_offset, mask, val); +} + +static rt_uint8_t rockchip_muxgrf_get_parent_common(struct rt_clk_cell *cell, struct rt_syscon *grf) +{ + rt_uint32_t mask, val; + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + mask = RT_GENMASK(rk_cell->mux_width - 1, 0); + + rt_syscon_read(grf, rk_cell->muxdiv_offset, &val); + + val >>= rk_cell->mux_shift; + val &= mask; + + return val; +} + +static rt_err_t rockchip_muxgrf_set_parent(struct rt_clk_cell *cell, rt_uint8_t index) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rockchip_muxgrf_set_parent_common(cell, rk_cell->provider->grf, index); +} + +static rt_uint8_t rockchip_muxgrf_get_parent(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rockchip_muxgrf_get_parent_common(cell, rk_cell->provider->grf); +} + +const struct rt_clk_ops rockchip_muxgrf_clk_ops = +{ + .set_parent = rockchip_muxgrf_set_parent, + .get_parent = rockchip_muxgrf_get_parent, +}; + +static rt_err_t rockchip_muxpmugrf_set_parent(struct rt_clk_cell *cell, rt_uint8_t index) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rockchip_muxgrf_set_parent_common(cell, rk_cell->provider->pmugrf, index); +} + +static rt_uint8_t rockchip_muxpmugrf_get_parent(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rockchip_muxgrf_get_parent_common(cell, rk_cell->provider->pmugrf); +} + +const struct rt_clk_ops rockchip_muxpmugrf_clk_ops = +{ + .set_parent = rockchip_muxpmugrf_set_parent, + .get_parent = rockchip_muxpmugrf_get_parent, +}; diff --git a/bsp/rockchip/dm/clk/clk-rk-muxgrf.h b/bsp/rockchip/dm/clk/clk-rk-muxgrf.h new file mode 100755 index 00000000000..5b7b388d0b9 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-muxgrf.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_MUXGRF_H__ +#define __CLK_RK_MUXGRF_H__ + +#include "clk-rk.h" + +#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \ +(void *)&(struct rockchip_clk_cell) \ +{ \ + .cell.name = cname, \ + .cell.ops = &rockchip_muxgrf_clk_ops, \ + .cell.parent_names = pnames, \ + .cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .cell.flags = f, \ + .id = _id, \ + .muxdiv_offset = o, \ + .mux_shift = s, \ + .mux_width = w, \ + .mux_flags = mf, \ + .gate_offset = -1, \ +} + +#define MUXPMUGRF(_id, cname, pnames, f, o, s, w, mf) \ +(void *)&(struct rockchip_clk_cell) \ +{ \ + .cell.name = cname, \ + .cell.ops = &rockchip_muxpmugrf_clk_ops, \ + .cell.parent_names = pnames, \ + .cell.parents_nr = RT_ARRAY_SIZE(pnames), \ + .cell.flags = f, \ + .id = _id, \ + .muxdiv_offset = o, \ + .mux_shift = s, \ + .mux_width = w, \ + .mux_flags = mf, \ + .gate_offset = -1, \ +} + +extern const struct rt_clk_ops rockchip_muxgrf_clk_ops, rockchip_muxpmugrf_clk_ops; + +#endif /* __CLK_RK_MUXGRF_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk-pll.c b/bsp/rockchip/dm/clk/clk-rk-pll.c new file mode 100755 index 00000000000..c42a460e7c3 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-pll.c @@ -0,0 +1,1546 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-pll.h" +#include "clk-rk-mux.h" + +#define PLL_MODE_MASK 0x3 +#define PLL_MODE_SLOW 0x0 +#define PLL_MODE_NORM 0x1 +#define PLL_MODE_DEEP 0x2 +#define PLL_RK3328_MODE_MASK 0x1 + +#define MHZ (1000UL * 1000UL) +#define KHZ (1000UL) + +/* CLK_PLL_TYPE_RK3066_AUTO type ops */ +#define PLL_FREF_MIN (269 * KHZ) +#define PLL_FREF_MAX (2200 * MHZ) + +#define PLL_FVCO_MIN (440 * MHZ) +#define PLL_FVCO_MAX (2200 * MHZ) + +#define PLL_FOUT_MIN (27500 * KHZ) +#define PLL_FOUT_MAX (2200 * MHZ) + +#define PLL_NF_MAX (4096) +#define PLL_NR_MAX (64) +#define PLL_NO_MAX (16) + +/* CLK_PLL_TYPE_RK3036/3366/3399_AUTO type ops */ +#define MIN_FOUTVCO_FREQ (800 * MHZ) +#define MAX_FOUTVCO_FREQ (2000 * MHZ) + +static struct rockchip_pll_rate_table auto_table; + +static void rockchip_pll_clk_set_postdiv(rt_ubase_t fout_hz, + rt_uint32_t *postdiv1, rt_uint32_t *postdiv2, rt_uint32_t *foutvco) +{ + rt_ubase_t freq; + + if (fout_hz < MIN_FOUTVCO_FREQ) + { + for (*postdiv1 = 1; *postdiv1 <= 7; (*postdiv1)++) + { + for (*postdiv2 = 1; *postdiv2 <= 7; (*postdiv2)++) + { + freq = fout_hz * (*postdiv1) * (*postdiv2); + + if (freq >= MIN_FOUTVCO_FREQ && freq <= MAX_FOUTVCO_FREQ) + { + *foutvco = freq; + return; + } + } + } + } + else + { + *postdiv1 = 1; + *postdiv2 = 1; + } +} + +static struct rockchip_pll_rate_table *rockchip_pll_clk_set_by_auto( + rt_ubase_t fin_hz, rt_ubase_t fout_hz) +{ + rt_ubase_t clk_gcd = 0; + rt_uint64_t fin_64, frac_64; + rt_uint32_t foutvco = fout_hz, f_frac, postdiv1, postdiv2; + struct rockchip_pll_rate_table *rate_table = &auto_table; + + if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz) + { + return RT_NULL; + } + + rockchip_pll_clk_set_postdiv(fout_hz, &postdiv1, &postdiv2, &foutvco); + rate_table->postdiv1 = postdiv1; + rate_table->postdiv2 = postdiv2; + rate_table->dsmpd = 1; + + if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) + { + fin_hz /= MHZ; + foutvco /= MHZ; + clk_gcd = rockchip_gcd(fin_hz, foutvco); + rate_table->refdiv = fin_hz / clk_gcd; + rate_table->fbdiv = foutvco / clk_gcd; + + rate_table->frac = 0; + } + else + { + clk_gcd = rockchip_gcd(fin_hz / MHZ, foutvco / MHZ); + rate_table->refdiv = fin_hz / MHZ / clk_gcd; + rate_table->fbdiv = foutvco / MHZ / clk_gcd; + + rate_table->frac = 0; + + f_frac = (foutvco % MHZ); + fin_64 = fin_hz; + rt_do_div(fin_64, (rt_uint64_t)rate_table->refdiv); + frac_64 = (rt_uint64_t)f_frac << 24; + rt_do_div(frac_64, fin_64); + rate_table->frac = (rt_uint32_t)frac_64; + if (rate_table->frac > 0) + { + rate_table->dsmpd = 0; + } + } + + return rate_table; +} + +static void *rockchip_pll_base(struct rockchip_pll_clk_cell *pll_clk_cell) +{ + return pll_clk_cell->rk_cell.provider->reg_base + pll_clk_cell->con_offset; +} + +static struct rockchip_pll_rate_table * rockchip_rk3066_pll_clk_set_by_auto( + rt_ubase_t fin_hz, rt_ubase_t fout_hz) +{ + rt_ubase_t clk_gcd = 0; + rt_uint64_t fref, fvco, fout; + rt_uint32_t nr, nf, no, nonr, nr_out, nf_out, no_out, n, numerator, denominator; + struct rockchip_pll_rate_table *rate_table = &auto_table; + + nr_out = PLL_NR_MAX + 1; + no_out = 0; + nf_out = 0; + + if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz) + { + return RT_NULL; + } + + clk_gcd = rockchip_gcd(fin_hz, fout_hz); + + numerator = fout_hz / clk_gcd; + denominator = fin_hz / clk_gcd; + + for (n = 1;; ++n) + { + nf = numerator * n; + nonr = denominator * n; + + if (nf > PLL_NF_MAX || nonr > (PLL_NO_MAX * PLL_NR_MAX)) + { + break; + } + + for (no = 1; no <= PLL_NO_MAX; ++no) + { + if (!(no == 1 || !(no % 2))) + { + continue; + } + + if (nonr % no) + { + continue; + } + nr = nonr / no; + + if (nr > PLL_NR_MAX) + { + continue; + } + + fref = fin_hz / nr; + if (fref < PLL_FREF_MIN || fref > PLL_FREF_MAX) + { + continue; + } + + fvco = fref * nf; + if (fvco < PLL_FVCO_MIN || fvco > PLL_FVCO_MAX) + { + continue; + } + + fout = fvco / no; + if (fout < PLL_FOUT_MIN || fout > PLL_FOUT_MAX) + { + continue; + } + + /* select the best from all available PLL settings */ + if ((no > no_out) || ((no == no_out) && (nr < nr_out))) + { + nr_out = nr; + nf_out = nf; + no_out = no; + } + } + } + + /* output the best PLL setting */ + if ((nr_out <= PLL_NR_MAX) && (no_out > 0)) + { + rate_table->nr = nr_out; + rate_table->nf = nf_out; + rate_table->no = no_out; + } + else + { + return RT_NULL; + } + + return rate_table; +} + +static rt_uint32_t rockchip_rk3588_pll_frac_get( + rt_uint32_t m, rt_uint32_t p, rt_uint32_t s, rt_uint64_t fin_hz, rt_uint64_t fvco) +{ + rt_uint32_t k = 0; + rt_uint64_t fref, fout, ffrac; + + fref = fin_hz / p; + ffrac = fvco - (m * fref); + fout = ffrac * 65536; + k = fout / fref; + + if (k > 32767) + { + fref = fin_hz / p; + ffrac = ((m + 1) * fref) - fvco; + fout = ffrac * 65536; + k = ((fout * 10 / fref) + 7) / 10; + + if (k > 32767) + { + k = 0; + } + else + { + k = ~k + 1; + } + } + return k; +} + +static struct rockchip_pll_rate_table *rockchip_rk3588_pll_frac_by_auto( + rt_ubase_t fin_hz, rt_ubase_t fout_hz) +{ + rt_uint32_t p, m, s, k; + rt_uint64_t fvco, fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ; + struct rockchip_pll_rate_table *rate_table = &auto_table; + + for (s = 0; s <= 6; ++s) + { + fvco = (rt_uint64_t)fout_hz << s; + + if (fvco < fvco_min || fvco > fvco_max) + { + continue; + } + for (p = 1; p <= 4; ++p) + { + for (m = 64; m <= 1023; ++m) + { + if ((fvco >= m * fin_hz / p) && (fvco < (m + 1) * fin_hz / p)) + { + k = rockchip_rk3588_pll_frac_get(m, p, s, (rt_uint64_t)fin_hz, fvco); + + if (!k) + { + continue; + } + + rate_table->p = p; + rate_table->s = s; + rate_table->k = k; + + if (k > 32767) + { + rate_table->m = m + 1; + } + else + { + rate_table->m = m; + } + + return rate_table; + } + } + } + } + + return RT_NULL; +} + +static struct rockchip_pll_rate_table *rockchip_rk3588_pll_clk_set_by_auto( + rt_ubase_t fin_hz, rt_ubase_t fout_hz) +{ + rt_uint32_t p, m, s; + rt_uint64_t fvco, fout_min = 37 * MHZ, fout_max = 4500 * MHZ; + rt_uint64_t fvco_min = 2250 * MHZ, fvco_max = 4500 * MHZ; + struct rockchip_pll_rate_table *rate_table = &auto_table; + + if (fin_hz == 0 || fout_hz == 0 || fout_hz == fin_hz) + { + return RT_NULL; + } + + if (fout_hz > fout_max || fout_hz < fout_min) + { + return RT_NULL; + } + + if (fin_hz / MHZ * MHZ == fin_hz && fout_hz / MHZ * MHZ == fout_hz) + { + for (s = 0; s <= 6; ++s) + { + fvco = (rt_uint64_t)fout_hz << s; + + if (fvco < fvco_min || fvco > fvco_max) + { + continue; + } + + for (p = 2; p <= 4; ++p) + { + for (m = 64; m <= 1023; ++m) + { + if (fvco == m * fin_hz / p) + { + rate_table->p = p; + rate_table->m = m; + rate_table->s = s; + rate_table->k = 0; + + return rate_table; + } + } + } + } + } + else + { + if ((rate_table = rockchip_rk3588_pll_frac_by_auto(fin_hz, fout_hz))) + { + return rate_table; + } + } + + return RT_NULL; +} + +static const struct rockchip_pll_rate_table *rockchip_get_pll_settings( + struct rockchip_pll_clk_cell *pll_clk_cell, rt_ubase_t rate) +{ + const struct rockchip_pll_rate_table *rate_table = pll_clk_cell->rate_table; + + for (int i = 0; i < rate_table[i].rate; ++i) + { + if (rate == rate_table[i].rate) + { + if (i < pll_clk_cell->sel) + { + pll_clk_cell->scaling = rate; + + return &rate_table[pll_clk_cell->sel]; + } + pll_clk_cell->scaling = 0; + + return &rate_table[i]; + } + } + pll_clk_cell->scaling = 0; + + if (pll_clk_cell->type == pll_type_rk3066) + { + return rockchip_rk3066_pll_clk_set_by_auto(24 * MHZ, rate); + } + else if (pll_clk_cell->type == pll_type_rk3588 || pll_clk_cell->type == pll_type_rk3588_core) + { + return rockchip_rk3588_pll_clk_set_by_auto(24 * MHZ, rate); + } + else + { + return rockchip_pll_clk_set_by_auto(24 * MHZ, rate); + } +} + +static rt_base_t rockchip_pll_round_rate(struct rt_clk_cell *cell, + rt_ubase_t drate, rt_ubase_t *prate) +{ + return drate; +} + +#define LINK_GRF(grf, off) grf, off + +static rt_uint32_t grf_read(struct rt_syscon *grf, int offset) +{ + rt_uint32_t val; + + rt_syscon_read(grf, offset, &val); + + return val; +} + +/* + * Wait for the pll to reach the locked state. + * The calling set_rate function is responsible for making sure the + * grf regmap is available. + */ +static rt_err_t rockchip_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell) +{ + rt_uint32_t val; + struct rt_syscon *grf = pll_clk_cell->rk_cell.provider->grf; + + return readx_poll_timeout(grf_read, + LINK_GRF(grf, pll_clk_cell->grf_lock_offset), + val, + val & RT_BIT(pll_clk_cell->lock_shift), + 0, 1000); +} + +static rt_err_t rockchip_pll_set_parent(struct rt_clk_cell *cell, rt_uint8_t index) +{ + return rockchip_mux_clk_ops.set_parent(cell, index); +} + +static rt_uint8_t rockchip_pll_get_parent(struct rt_clk_cell *cell) +{ + return rockchip_mux_clk_ops.get_parent(cell); +} + +/* + * PLL used in RK3036 + */ + +#define RK3036_PLLCON(i) (i * 0x4) +#define RK3036_PLLCON0_FBDIV_MASK 0xfff +#define RK3036_PLLCON0_FBDIV_SHIFT 0 +#define RK3036_PLLCON0_POSTDIV1_MASK 0x7 +#define RK3036_PLLCON0_POSTDIV1_SHIFT 12 +#define RK3036_PLLCON1_REFDIV_MASK 0x3f +#define RK3036_PLLCON1_REFDIV_SHIFT 0 +#define RK3036_PLLCON1_POSTDIV2_MASK 0x7 +#define RK3036_PLLCON1_POSTDIV2_SHIFT 6 +#define RK3036_PLLCON1_LOCK_STATUS RT_BIT(10) +#define RK3036_PLLCON1_DSMPD_MASK 0x1 +#define RK3036_PLLCON1_DSMPD_SHIFT 12 +#define RK3036_PLLCON1_PWRDOWN RT_BIT(13) +#define RK3036_PLLCON1_PLLPDSEL RT_BIT(15) +#define RK3036_PLLCON2_FRAC_MASK 0xffffff +#define RK3036_PLLCON2_FRAC_SHIFT 0 + +static rt_err_t rockchip_rk3036_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell) +{ + void *base; + rt_uint32_t pllcon; + + base = rockchip_pll_base(pll_clk_cell); + + /* + * Lock time typical 250, max 500 input clock cycles @24MHz + * So define a very safe maximum of 1000us, meaning 24000 cycles. + */ + return readl_poll_timeout(base + RK3036_PLLCON(1), + pllcon, + pllcon & RK3036_PLLCON1_LOCK_STATUS, + 0, 1000); +} + + +static rt_err_t rockchip_rk3036_pll_enable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + + HWREG32(base + RK3036_PLLCON(1)) = HIWORD_UPDATE(0, RK3036_PLLCON1_PWRDOWN, 0); + rockchip_rk3036_pll_wait_lock(pll_clk_cell); + + rockchip_mux_clk_ops.set_parent(cell, PLL_MODE_NORM); + + return RT_EOK; +} + +static void rockchip_rk3036_pll_disable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + rockchip_mux_clk_ops.set_parent(cell, PLL_MODE_SLOW); + + base = rockchip_pll_base(pll_clk_cell); + + HWREG32(base + RK3036_PLLCON(1)) = HIWORD_UPDATE( + RK3036_PLLCON1_PWRDOWN, RK3036_PLLCON1_PWRDOWN, 0); +} + +static rt_bool_t rockchip_rk3036_pll_is_enabled(struct rt_clk_cell *cell) +{ + void *base; + rt_uint32_t pllcon; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + pllcon = HWREG32(base + RK3036_PLLCON(1)); + + return !(pllcon & RK3036_PLLCON1_PWRDOWN); +} + +static void rockchip_rk3036_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell, + struct rockchip_pll_rate_table *rate) +{ + rt_uint32_t pllcon; + void *base = rockchip_pll_base(pll_clk_cell); + + pllcon = HWREG32(base + RK3036_PLLCON(0)); + rate->fbdiv = ((pllcon >> RK3036_PLLCON0_FBDIV_SHIFT) & RK3036_PLLCON0_FBDIV_MASK); + rate->postdiv1 = ((pllcon >> RK3036_PLLCON0_POSTDIV1_SHIFT) & RK3036_PLLCON0_POSTDIV1_MASK); + + pllcon = HWREG32(base + RK3036_PLLCON(1)); + rate->refdiv = ((pllcon >> RK3036_PLLCON1_REFDIV_SHIFT) & RK3036_PLLCON1_REFDIV_MASK); + rate->postdiv2 = ((pllcon >> RK3036_PLLCON1_POSTDIV2_SHIFT) & RK3036_PLLCON1_POSTDIV2_MASK); + rate->dsmpd = ((pllcon >> RK3036_PLLCON1_DSMPD_SHIFT) & RK3036_PLLCON1_DSMPD_MASK); + + pllcon = HWREG32(base + RK3036_PLLCON(2)); + rate->frac = ((pllcon >> RK3036_PLLCON2_FRAC_SHIFT) & RK3036_PLLCON2_FRAC_MASK); +} + +static rt_ubase_t rockchip_rk3036_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate) +{ + rt_uint64_t rate64 = prate, frac_rate64 = prate; + struct rockchip_pll_rate_table cur; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + if (pll_clk_cell->sel && pll_clk_cell->scaling) + { + return pll_clk_cell->scaling; + } + + rockchip_rk3036_pll_get_params(pll_clk_cell, &cur); + + rate64 *= cur.fbdiv; + rt_do_div(rate64, cur.refdiv); + + if (cur.dsmpd == 0) + { + /* Fractional mode */ + frac_rate64 *= cur.frac; + + rt_do_div(frac_rate64, cur.refdiv); + rate64 += frac_rate64 >> 24; + } + + rt_do_div(rate64, cur.postdiv1); + rt_do_div(rate64, cur.postdiv2); + + return (rt_ubase_t)rate64; +} + +static rt_err_t rockchip_rk3036_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell, + const struct rockchip_pll_rate_table *rate) +{ + void *base; + rt_err_t err; + rt_uint32_t pllcon; + int rate_change_remuxed = 0, cur_parent; + struct rockchip_pll_rate_table cur; + + rockchip_rk3036_pll_get_params(pll_clk_cell, &cur); + cur.rate = 0; + + if (!(pll_clk_cell->flags & ROCKCHIP_PLL_FIXED_MODE)) + { + cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell); + + if (cur_parent == PLL_MODE_NORM) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW); + rate_change_remuxed = 1; + } + } + + base = rockchip_pll_base(pll_clk_cell); + + /* Update pll values */ + HWREG32(base + RK3036_PLLCON(0)) = + HIWORD_UPDATE(rate->fbdiv, RK3036_PLLCON0_FBDIV_MASK, RK3036_PLLCON0_FBDIV_SHIFT) | + HIWORD_UPDATE(rate->postdiv1, RK3036_PLLCON0_POSTDIV1_MASK, RK3036_PLLCON0_POSTDIV1_SHIFT); + + HWREG32(base + RK3036_PLLCON(1)) = + HIWORD_UPDATE(rate->refdiv, RK3036_PLLCON1_REFDIV_MASK, RK3036_PLLCON1_REFDIV_SHIFT) | + HIWORD_UPDATE(rate->postdiv2, RK3036_PLLCON1_POSTDIV2_MASK, RK3036_PLLCON1_POSTDIV2_SHIFT) | + HIWORD_UPDATE(rate->dsmpd, RK3036_PLLCON1_DSMPD_MASK, RK3036_PLLCON1_DSMPD_SHIFT); + + /* GPLL CON2 is not HIWORD_MASK */ + pllcon = HWREG32(base + RK3036_PLLCON(2)); + pllcon &= ~(RK3036_PLLCON2_FRAC_MASK << RK3036_PLLCON2_FRAC_SHIFT); + pllcon |= rate->frac << RK3036_PLLCON2_FRAC_SHIFT; + HWREG32(base + RK3036_PLLCON(2)) = pllcon; + + /* Wait for the pll to lock */ + if ((err = rockchip_rk3036_pll_wait_lock(pll_clk_cell))) + { + rockchip_rk3036_pll_set_params(pll_clk_cell, &cur); + } + + if (rate_change_remuxed) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM); + } + + return err; +} + +static rt_err_t rockchip_rk3036_pll_set_rate(struct rt_clk_cell *cell, + rt_ubase_t drate, rt_ubase_t prate) +{ + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + /* Get required rate settings from table */ + if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate))) + { + return -RT_EINVAL; + } + + return rockchip_rk3036_pll_set_params(pll_clk_cell, rate); +} + +static const struct rt_clk_ops rockchip_rk3036_pll_clk_norate_ops = +{ + .enable = rockchip_rk3036_pll_enable, + .disable = rockchip_rk3036_pll_disable, + .is_enabled = rockchip_rk3036_pll_is_enabled, + .recalc_rate = rockchip_rk3036_pll_recalc_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static const struct rt_clk_ops rockchip_rk3036_pll_clk_ops = +{ + .enable = rockchip_rk3036_pll_enable, + .disable = rockchip_rk3036_pll_disable, + .is_enabled = rockchip_rk3036_pll_is_enabled, + .recalc_rate = rockchip_rk3036_pll_recalc_rate, + .round_rate = rockchip_pll_round_rate, + .set_rate = rockchip_rk3036_pll_set_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static void rockchip_rk3036_pll_init(struct rt_clk_cell *cell) +{ + rt_ubase_t drate; + struct rockchip_pll_rate_table cur; + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + if (!(pll_clk_cell->flags & ROCKCHIP_PLL_SYNC_RATE)) + { + return; + } + + drate = rt_clk_cell_get_rate(cell); + rate = rockchip_get_pll_settings(pll_clk_cell, drate); + + /* when no rate setting for the current rate, rely on clk_set_rate */ + if (!rate) + { + return; + } + + rockchip_rk3036_pll_get_params(pll_clk_cell, &cur); + + if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || + rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 || + rate->dsmpd != cur.dsmpd || (!cur.dsmpd && (rate->frac != cur.frac))) + { + if (!rt_clk_cell_get_parent(cell)) + { + return; + } + + rockchip_rk3036_pll_set_params(pll_clk_cell, rate); + } +} + +/* + * PLL used in RK3066, RK3188 and RK3288 + */ + +#define RK3066_PLL_RESET_DELAY(nr) ((nr * 500) / 24 + 1) + +#define RK3066_PLLCON(i) (i * 0x4) +#define RK3066_PLLCON0_OD_MASK 0xf +#define RK3066_PLLCON0_OD_SHIFT 0 +#define RK3066_PLLCON0_NR_MASK 0x3f +#define RK3066_PLLCON0_NR_SHIFT 8 +#define RK3066_PLLCON1_NF_MASK 0x1fff +#define RK3066_PLLCON1_NF_SHIFT 0 +#define RK3066_PLLCON2_NB_MASK 0xfff +#define RK3066_PLLCON2_NB_SHIFT 0 +#define RK3066_PLLCON3_RESET (1 << 5) +#define RK3066_PLLCON3_PWRDOWN (1 << 1) +#define RK3066_PLLCON3_BYPASS (1 << 0) + +static rt_err_t rockchip_rk3066_pll_enable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + + HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE(0, RK3066_PLLCON3_PWRDOWN, 0); + rockchip_pll_wait_lock(pll_clk_cell); + + return RT_EOK; +} + +static void rockchip_rk3066_pll_disable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + + HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE( + RK3066_PLLCON3_PWRDOWN, RK3066_PLLCON3_PWRDOWN, 0); +} + +static rt_bool_t rockchip_rk3066_pll_is_enabled(struct rt_clk_cell *cell) +{ + void *base; + rt_uint32_t pllcon; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + pllcon = HWREG32(base + RK3066_PLLCON(3)); + + return !(pllcon & RK3066_PLLCON3_PWRDOWN); +} + +static void rockchip_rk3066_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell, + struct rockchip_pll_rate_table *rate) +{ + rt_uint32_t pllcon; + void *base = rockchip_pll_base(pll_clk_cell); + + pllcon = HWREG32(base + RK3066_PLLCON(0)); + rate->nr = ((pllcon >> RK3066_PLLCON0_NR_SHIFT) & RK3066_PLLCON0_NR_MASK) + 1; + rate->no = ((pllcon >> RK3066_PLLCON0_OD_SHIFT) & RK3066_PLLCON0_OD_MASK) + 1; + + pllcon = HWREG32(base + RK3066_PLLCON(1)); + rate->nf = ((pllcon >> RK3066_PLLCON1_NF_SHIFT) & RK3066_PLLCON1_NF_MASK) + 1; + + pllcon = HWREG32(base + RK3066_PLLCON(2)); + rate->nb = ((pllcon >> RK3066_PLLCON2_NB_SHIFT) & RK3066_PLLCON2_NB_MASK) + 1; +} + +static rt_ubase_t rockchip_rk3066_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate) +{ + void *base; + rt_uint32_t pllcon; + rt_uint64_t rate64 = prate; + struct rockchip_pll_rate_table cur; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + + pllcon = HWREG32(base + RK3066_PLLCON(3)); + if (pllcon & RK3066_PLLCON3_BYPASS) + { + return prate; + } + + if (pll_clk_cell->sel && pll_clk_cell->scaling) + { + return pll_clk_cell->scaling; + } + + rockchip_rk3066_pll_get_params(pll_clk_cell, &cur); + + rate64 *= cur.nf; + rt_do_div(rate64, cur.nr); + rt_do_div(rate64, cur.no); + + return (rt_ubase_t)rate64; +} + +static rt_err_t rockchip_rk3066_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell, + const struct rockchip_pll_rate_table *rate) +{ + void *base; + rt_err_t err; + int rate_change_remuxed = 0, cur_parent; + struct rockchip_pll_rate_table cur; + + rockchip_rk3066_pll_get_params(pll_clk_cell, &cur); + cur.rate = 0; + + cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell); + if (cur_parent == PLL_MODE_NORM) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW); + rate_change_remuxed = 1; + } + + base = rockchip_pll_base(pll_clk_cell); + + /* Enter reset mode */ + HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE( + RK3066_PLLCON3_RESET, RK3066_PLLCON3_RESET, 0); + + /* Update pll values */ + HWREG32(base + RK3066_PLLCON(0)) = + HIWORD_UPDATE(rate->nr - 1, RK3066_PLLCON0_NR_MASK, RK3066_PLLCON0_NR_SHIFT) | + HIWORD_UPDATE(rate->no - 1, RK3066_PLLCON0_OD_MASK, RK3066_PLLCON0_OD_SHIFT); + + HWREG32(base + RK3066_PLLCON(1)) = HIWORD_UPDATE( + rate->nf - 1, RK3066_PLLCON1_NF_MASK, RK3066_PLLCON1_NF_SHIFT); + HWREG32(base + RK3066_PLLCON(2)) = HIWORD_UPDATE( + rate->nb - 1, RK3066_PLLCON2_NB_MASK, RK3066_PLLCON2_NB_SHIFT); + + /* Leave reset and wait the reset_delay */ + HWREG32(base + RK3066_PLLCON(3)) = HIWORD_UPDATE(0, RK3066_PLLCON3_RESET, 0); + rt_hw_us_delay(RK3066_PLL_RESET_DELAY(rate->nr)); + + /* Wait for the pll to lock */ + if ((err = rockchip_pll_wait_lock(pll_clk_cell))) + { + rockchip_rk3066_pll_set_params(pll_clk_cell, &cur); + } + + if (rate_change_remuxed) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM); + } + + return err; +} + +static rt_err_t rockchip_rk3066_pll_set_rate(struct rt_clk_cell *cell, + rt_ubase_t drate, rt_ubase_t prate) +{ + rt_err_t err; + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + rockchip_rk3066_pll_recalc_rate(cell, prate); + + /* Get required rate settings from table */ + if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate))) + { + return -RT_EINVAL; + } + + if ((err = rockchip_rk3066_pll_set_params(pll_clk_cell, rate))) + { + pll_clk_cell->scaling = 0; + } + + return err; +} + +static const struct rt_clk_ops rockchip_rk3066_pll_clk_norate_ops = +{ + .enable = rockchip_rk3066_pll_enable, + .disable = rockchip_rk3066_pll_disable, + .is_enabled = rockchip_rk3066_pll_is_enabled, + .recalc_rate = rockchip_rk3066_pll_recalc_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static const struct rt_clk_ops rockchip_rk3066_pll_clk_ops = +{ + .enable = rockchip_rk3066_pll_enable, + .disable = rockchip_rk3066_pll_disable, + .is_enabled = rockchip_rk3066_pll_is_enabled, + .recalc_rate = rockchip_rk3066_pll_recalc_rate, + .round_rate = rockchip_pll_round_rate, + .set_rate = rockchip_rk3066_pll_set_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static void rockchip_rk3066_pll_init(struct rt_clk_cell *cell) +{ + rt_ubase_t drate; + struct rockchip_pll_rate_table cur; + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + if (!(pll_clk_cell->flags & ROCKCHIP_PLL_SYNC_RATE)) + { + return; + } + + drate = rt_clk_cell_get_rate(cell); + + /* when no rate setting for the current rate, rely on clk_set_rate */ + if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate))) + { + return; + } + + rockchip_rk3066_pll_get_params(pll_clk_cell, &cur); + + if (rate->nr != cur.nr || rate->no != cur.no || + rate->nf != cur.nf || rate->nb != cur.nb) + { + rockchip_rk3066_pll_set_params(pll_clk_cell, rate); + } +} + +/* + * PLL used in RK3399 + */ + +#define RK3399_PLLCON(i) (i * 0x4) +#define RK3399_PLLCON0_FBDIV_MASK 0xfff +#define RK3399_PLLCON0_FBDIV_SHIFT 0 +#define RK3399_PLLCON1_REFDIV_MASK 0x3f +#define RK3399_PLLCON1_REFDIV_SHIFT 0 +#define RK3399_PLLCON1_POSTDIV1_MASK 0x7 +#define RK3399_PLLCON1_POSTDIV1_SHIFT 8 +#define RK3399_PLLCON1_POSTDIV2_MASK 0x7 +#define RK3399_PLLCON1_POSTDIV2_SHIFT 12 +#define RK3399_PLLCON2_FRAC_MASK 0xffffff +#define RK3399_PLLCON2_FRAC_SHIFT 0 +#define RK3399_PLLCON2_LOCK_STATUS RT_BIT(31) +#define RK3399_PLLCON3_PWRDOWN RT_BIT(0) +#define RK3399_PLLCON3_DSMPD_MASK 0x1 +#define RK3399_PLLCON3_DSMPD_SHIFT 3 + +static rt_err_t rockchip_rk3399_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell) +{ + void *base; + rt_uint32_t pllcon; + + base = rockchip_pll_base(pll_clk_cell); + + /* + * Lock time typical 250, max 500 input clock cycles @24MHz + * So define a very safe maximum of 1000us, meaning 24000 cycles. + */ + return readl_poll_timeout(base + RK3399_PLLCON(2), + pllcon, + pllcon & RK3399_PLLCON2_LOCK_STATUS, + 0, 1000); +} + +static rt_err_t rockchip_rk3399_pll_enable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0); + rockchip_rk3399_pll_wait_lock(pll_clk_cell); + + return RT_EOK; +} + +static void rockchip_rk3399_pll_disable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE( + RK3399_PLLCON3_PWRDOWN, RK3399_PLLCON3_PWRDOWN, 0); +} + +static rt_bool_t rockchip_rk3399_pll_is_enabled(struct rt_clk_cell *cell) +{ + void *base; + rt_uint32_t pllcon; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + pllcon = HWREG32(base + RK3399_PLLCON(3)); + + return !(pllcon & RK3399_PLLCON3_PWRDOWN); +} + +static void rockchip_rk3399_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell, + struct rockchip_pll_rate_table *rate) +{ + rt_uint32_t pllcon; + void *base = rockchip_pll_base(pll_clk_cell); + + pllcon = HWREG32(base + RK3399_PLLCON(0)); + rate->fbdiv = ((pllcon >> RK3399_PLLCON0_FBDIV_SHIFT) & RK3399_PLLCON0_FBDIV_MASK); + + pllcon = HWREG32(base + RK3399_PLLCON(1)); + rate->refdiv = ((pllcon >> RK3399_PLLCON1_REFDIV_SHIFT) & RK3399_PLLCON1_REFDIV_MASK); + rate->postdiv1 = ((pllcon >> RK3399_PLLCON1_POSTDIV1_SHIFT) & RK3399_PLLCON1_POSTDIV1_MASK); + rate->postdiv2 = ((pllcon >> RK3399_PLLCON1_POSTDIV2_SHIFT) & RK3399_PLLCON1_POSTDIV2_MASK); + + pllcon = HWREG32(base + RK3399_PLLCON(2)); + rate->frac = ((pllcon >> RK3399_PLLCON2_FRAC_SHIFT) & RK3399_PLLCON2_FRAC_MASK); + + pllcon = HWREG32(base + RK3399_PLLCON(3)); + rate->dsmpd = ((pllcon >> RK3399_PLLCON3_DSMPD_SHIFT) & RK3399_PLLCON3_DSMPD_MASK); +} + +static rt_ubase_t rockchip_rk3399_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate) +{ + rt_uint64_t rate64 = prate; + struct rockchip_pll_rate_table cur; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + if (pll_clk_cell->sel && pll_clk_cell->scaling) + { + return pll_clk_cell->scaling; + } + + rockchip_rk3399_pll_get_params(pll_clk_cell, &cur); + + rate64 *= cur.fbdiv; + rt_do_div(rate64, cur.refdiv); + + if (cur.dsmpd == 0) + { + /* Fractional mode */ + rt_uint64_t frac_rate64 = prate * cur.frac; + + rt_do_div(frac_rate64, cur.refdiv); + rate64 += frac_rate64 >> 24; + } + + rt_do_div(rate64, cur.postdiv1); + rt_do_div(rate64, cur.postdiv2); + + return (rt_ubase_t)rate64; +} + +static rt_err_t rockchip_rk3399_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell, + const struct rockchip_pll_rate_table *rate) +{ + rt_err_t err; + rt_uint32_t pllcon; + int rate_change_remuxed = 0, cur_parent; + void *base = rockchip_pll_base(pll_clk_cell); + struct rockchip_pll_rate_table cur; + + rockchip_rk3399_pll_get_params(pll_clk_cell, &cur); + cur.rate = 0; + + cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell); + + if (cur_parent == PLL_MODE_NORM) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW); + rate_change_remuxed = 1; + } + + /* Set pll power down */ + HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE( + RK3399_PLLCON3_PWRDOWN, RK3399_PLLCON3_PWRDOWN, 0); + + /* Update pll values */ + HWREG32(base + RK3399_PLLCON(0)) = HIWORD_UPDATE( + rate->fbdiv, RK3399_PLLCON0_FBDIV_MASK, RK3399_PLLCON0_FBDIV_SHIFT); + + HWREG32(base + RK3399_PLLCON(1)) = + HIWORD_UPDATE(rate->refdiv, RK3399_PLLCON1_REFDIV_MASK, RK3399_PLLCON1_REFDIV_SHIFT) | + HIWORD_UPDATE(rate->postdiv1, RK3399_PLLCON1_POSTDIV1_MASK, RK3399_PLLCON1_POSTDIV1_SHIFT) | + HIWORD_UPDATE(rate->postdiv2, RK3399_PLLCON1_POSTDIV2_MASK, RK3399_PLLCON1_POSTDIV2_SHIFT); + + /* xPLL CON2 is not HIWORD_MASK */ + pllcon = HWREG32(base + RK3399_PLLCON(2)); + pllcon &= ~(RK3399_PLLCON2_FRAC_MASK << RK3399_PLLCON2_FRAC_SHIFT); + pllcon |= rate->frac << RK3399_PLLCON2_FRAC_SHIFT; + HWREG32(base + RK3399_PLLCON(2)) = pllcon; + + HWREG32(base + RK3399_PLLCON(3)) = + HIWORD_UPDATE(rate->dsmpd, RK3399_PLLCON3_DSMPD_MASK, RK3399_PLLCON3_DSMPD_SHIFT); + + /* Set pll power up */ + HWREG32(base + RK3399_PLLCON(3)) = HIWORD_UPDATE(0, RK3399_PLLCON3_PWRDOWN, 0); + + /* Wait for the pll to lock */ + if ((err = rockchip_rk3399_pll_wait_lock(pll_clk_cell))) + { + rockchip_rk3399_pll_set_params(pll_clk_cell, &cur); + } + + if (rate_change_remuxed) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM); + } + + return err; +} + +static rt_err_t rockchip_rk3399_pll_set_rate(struct rt_clk_cell *cell, + rt_ubase_t drate, rt_ubase_t prate) +{ + rt_err_t err; + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + rockchip_rk3399_pll_recalc_rate(cell, prate); + + /* Get required rate settings from table */ + if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate))) + { + return -RT_EINVAL; + } + + if ((err = rockchip_rk3399_pll_set_params(pll_clk_cell, rate))) + { + pll_clk_cell->scaling = 0; + } + + return err; +} + +static const struct rt_clk_ops rockchip_rk3399_pll_clk_norate_ops = +{ + .enable = rockchip_rk3399_pll_enable, + .disable = rockchip_rk3399_pll_disable, + .is_enabled = rockchip_rk3399_pll_is_enabled, + .recalc_rate = rockchip_rk3399_pll_recalc_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static const struct rt_clk_ops rockchip_rk3399_pll_clk_ops = +{ + .enable = rockchip_rk3399_pll_enable, + .disable = rockchip_rk3399_pll_disable, + .is_enabled = rockchip_rk3399_pll_is_enabled, + .recalc_rate = rockchip_rk3399_pll_recalc_rate, + .round_rate = rockchip_pll_round_rate, + .set_rate = rockchip_rk3399_pll_set_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static void rockchip_rk3399_pll_init(struct rt_clk_cell *cell) +{ + rt_ubase_t drate; + struct rockchip_pll_rate_table cur; + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + if (!(pll_clk_cell->flags & ROCKCHIP_PLL_SYNC_RATE)) + { + return; + } + + drate = rt_clk_cell_get_rate(cell); + rate = rockchip_get_pll_settings(pll_clk_cell, drate); + + /* When no rate setting for the current rate, rely on clk_set_rate */ + if (!rate) + { + return; + } + + rockchip_rk3399_pll_get_params(pll_clk_cell, &cur); + + if (rate->fbdiv != cur.fbdiv || rate->postdiv1 != cur.postdiv1 || + rate->refdiv != cur.refdiv || rate->postdiv2 != cur.postdiv2 || + rate->dsmpd != cur.dsmpd || + (!cur.dsmpd && (rate->frac != cur.frac))) + { + if (!rt_clk_cell_get_parent(cell)) + { + return; + } + + rockchip_rk3399_pll_set_params(pll_clk_cell, rate); + } +} + +/* + * PLL used in RK3588 + */ +#define RK3588_PLLCON(i) (i * 0x4) +#define RK3588_PLLCON0_M_MASK 0x3ff +#define RK3588_PLLCON0_M_SHIFT 0 +#define RK3588_PLLCON1_P_MASK 0x3f +#define RK3588_PLLCON1_P_SHIFT 0 +#define RK3588_PLLCON1_S_MASK 0x7 +#define RK3588_PLLCON1_S_SHIFT 6 +#define RK3588_PLLCON2_K_MASK 0xffff +#define RK3588_PLLCON2_K_SHIFT 0 +#define RK3588_PLLCON1_PWRDOWN RT_BIT(13) +#define RK3588_PLLCON6_LOCK_STATUS RT_BIT(15) + +static rt_err_t rockchip_rk3588_pll_wait_lock(struct rockchip_pll_clk_cell *pll_clk_cell) +{ + void *base; + rt_uint32_t pllcon; + + base = rockchip_pll_base(pll_clk_cell); + + /* + * Lock time typical 250, max 500 input clock cycles @24MHz + * So define a very safe maximum of 1000us, meaning 24000 cycles. + */ + return readl_poll_timeout(base + RK3588_PLLCON(6), + pllcon, + pllcon & RK3588_PLLCON6_LOCK_STATUS, + 0, 1000); +} + +static rt_err_t rockchip_rk3588_pll_enable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + + HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0); + + rockchip_rk3588_pll_wait_lock(pll_clk_cell); + + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM); + + return RT_EOK; +} + +static void rockchip_rk3588_pll_disable(struct rt_clk_cell *cell) +{ + void *base; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW); + + HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE( + RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0); +} + +static rt_bool_t rockchip_rk3588_pll_is_enabled(struct rt_clk_cell *cell) +{ + void *base; + rt_uint32_t pllcon; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + base = rockchip_pll_base(pll_clk_cell); + pllcon = HWREG32(base + RK3588_PLLCON(1)); + + return !(pllcon & RK3588_PLLCON1_PWRDOWN); +} + +static void rockchip_rk3588_pll_get_params(struct rockchip_pll_clk_cell *pll_clk_cell, + struct rockchip_pll_rate_table *rate) +{ + rt_uint32_t pllcon; + void *base = rockchip_pll_base(pll_clk_cell); + + pllcon = HWREG32(base + RK3588_PLLCON(0)); + rate->m = ((pllcon >> RK3588_PLLCON0_M_SHIFT) & RK3588_PLLCON0_M_MASK); + + pllcon = HWREG32(base + RK3588_PLLCON(1)); + rate->p = ((pllcon >> RK3588_PLLCON1_P_SHIFT) & RK3588_PLLCON1_P_MASK); + rate->s = ((pllcon >> RK3588_PLLCON1_S_SHIFT) & RK3588_PLLCON1_S_MASK); + + pllcon = HWREG32(base + RK3588_PLLCON(2)); + rate->k = ((pllcon >> RK3588_PLLCON2_K_SHIFT) & RK3588_PLLCON2_K_MASK); +} + +static rt_ubase_t rockchip_rk3588_pll_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t prate) +{ + rt_uint64_t rate64 = prate, postdiv; + struct rockchip_pll_rate_table cur; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + if (pll_clk_cell->sel && pll_clk_cell->scaling) + { + return pll_clk_cell->scaling; + } + + rockchip_rk3588_pll_get_params(pll_clk_cell, &cur); + + if (cur.p == 0) + { + return prate; + } + + rate64 *= cur.m; + rt_do_div(rate64, cur.p); + + if (cur.k & RT_BIT(15)) + { + /* Fractional mode */ + rt_uint64_t frac_rate64; + + cur.k = (~(cur.k - 1)) & RK3588_PLLCON2_K_MASK; + frac_rate64 = prate * cur.k; + postdiv = cur.p; + postdiv *= 65536; + rt_do_div(frac_rate64, postdiv); + rate64 -= frac_rate64; + } + else + { + /* Fractional mode */ + rt_uint64_t frac_rate64 = prate * cur.k; + + postdiv = cur.p; + postdiv *= 65536; + rt_do_div(frac_rate64, postdiv); + rate64 += frac_rate64; + } + rate64 = rate64 >> cur.s; + + if (pll_clk_cell->type == pll_type_rk3588_ddr) + { + return (rt_ubase_t)rate64 * 2; + } + + return (rt_ubase_t)rate64; +} + +static rt_base_t rockchip_rk3588_pll_round_rate(struct rt_clk_cell *cell, + rt_ubase_t drate, rt_ubase_t *prate) +{ + if ((drate < 37 * MHZ) || (drate > 4500 * MHZ)) + { + return -RT_EINVAL; + } + + return drate; +} + +static rt_err_t rockchip_rk3588_pll_set_params(struct rockchip_pll_clk_cell *pll_clk_cell, + const struct rockchip_pll_rate_table *rate) +{ + rt_err_t err; + void *base = rockchip_pll_base(pll_clk_cell); + int rate_change_remuxed = 0, cur_parent; + struct rockchip_pll_rate_table cur; + + rockchip_rk3588_pll_get_params(pll_clk_cell, &cur); + cur.rate = 0; + + if (pll_clk_cell->type == pll_type_rk3588) + { + cur_parent = rockchip_mux_clk_ops.get_parent(&pll_clk_cell->rk_cell.cell); + + if (cur_parent == PLL_MODE_NORM) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_SLOW); + rate_change_remuxed = 1; + } + } + + /* Set pll power down */ + HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE( + RK3588_PLLCON1_PWRDOWN, RK3588_PLLCON1_PWRDOWN, 0); + + /* Update pll values */ + HWREG32(base + RK3588_PLLCON(0)) = HIWORD_UPDATE( + rate->m, RK3588_PLLCON0_M_MASK, RK3588_PLLCON0_M_SHIFT); + + HWREG32(base + RK3588_PLLCON(1)) = + HIWORD_UPDATE(rate->p, RK3588_PLLCON1_P_MASK, RK3588_PLLCON1_P_SHIFT) | + HIWORD_UPDATE(rate->s, RK3588_PLLCON1_S_MASK, RK3588_PLLCON1_S_SHIFT); + + HWREG32(base + RK3588_PLLCON(2)) = HIWORD_UPDATE( + rate->k, RK3588_PLLCON2_K_MASK, RK3588_PLLCON2_K_SHIFT); + + /* Set pll power up */ + HWREG32(base + RK3588_PLLCON(1)) = HIWORD_UPDATE(0, RK3588_PLLCON1_PWRDOWN, 0); + + /* Wait for the pll to lock */ + if ((err = rockchip_rk3588_pll_wait_lock(pll_clk_cell))) + { + rockchip_rk3588_pll_set_params(pll_clk_cell, &cur); + } + + if ((pll_clk_cell->type == pll_type_rk3588) && rate_change_remuxed) + { + rockchip_mux_clk_ops.set_parent(&pll_clk_cell->rk_cell.cell, PLL_MODE_NORM); + } + + return err; +} + +static rt_err_t rockchip_rk3588_pll_set_rate(struct rt_clk_cell *cell, + rt_ubase_t drate, rt_ubase_t prate) +{ + rt_err_t err; + const struct rockchip_pll_rate_table *rate; + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(cell); + + rockchip_rk3588_pll_recalc_rate(cell, prate); + + /* Get required rate settings from table */ + if (!(rate = rockchip_get_pll_settings(pll_clk_cell, drate))) + { + return -RT_EINVAL; + } + + if ((err = rockchip_rk3588_pll_set_params(pll_clk_cell, rate))) + { + pll_clk_cell->scaling = 0; + } + + return err; +} + +static const struct rt_clk_ops rockchip_rk3588_pll_clk_norate_ops = +{ + .enable = rockchip_rk3588_pll_enable, + .disable = rockchip_rk3588_pll_disable, + .is_enabled = rockchip_rk3588_pll_is_enabled, + .recalc_rate = rockchip_rk3588_pll_recalc_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +static const struct rt_clk_ops rockchip_rk3588_pll_clk_ops = +{ + .enable = rockchip_rk3588_pll_enable, + .disable = rockchip_rk3588_pll_disable, + .is_enabled = rockchip_rk3588_pll_is_enabled, + .recalc_rate = rockchip_rk3588_pll_recalc_rate, + .round_rate = rockchip_rk3588_pll_round_rate, + .set_rate = rockchip_rk3588_pll_set_rate, + .set_parent = rockchip_pll_set_parent, + .get_parent = rockchip_pll_get_parent, +}; + +void rockchip_pll_clk_cell_init(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(&rk_cell->cell); + + rk_cell->muxdiv_offset = pll_clk_cell->mode_offset; + rk_cell->mux_shift = pll_clk_cell->mode_shift; + + if (pll_clk_cell->type == pll_type_rk3328) + { + rk_cell->mux_mask = PLL_RK3328_MODE_MASK; + } + else + { + rk_cell->mux_mask = PLL_MODE_MASK; + } + + rk_cell->mux_flags |= CLK_MUX_HIWORD_MASK; + + rk_cell->cell.ops = &rockchip_mux_clk_ops; + + switch (pll_clk_cell->type) + { + case pll_type_rk3036: + case pll_type_rk3328: + if (!pll_clk_cell->rate_table) + { + rk_cell->cell.ops = &rockchip_rk3036_pll_clk_norate_ops; + } + else + { + rk_cell->cell.ops = &rockchip_rk3036_pll_clk_ops; + } + break; + case pll_type_rk3066: + if (!pll_clk_cell->rate_table || !rk_cell->provider->grf) + { + rk_cell->cell.ops = &rockchip_rk3066_pll_clk_norate_ops; + } + else + { + rk_cell->cell.ops = &rockchip_rk3066_pll_clk_ops; + } + break; + case pll_type_rk3399: + if (!pll_clk_cell->rate_table) + { + rk_cell->cell.ops = &rockchip_rk3399_pll_clk_norate_ops; + } + else + { + rk_cell->cell.ops = &rockchip_rk3399_pll_clk_ops; + } + break; + case pll_type_rk3588: + case pll_type_rk3588_core: + case pll_type_rk3588_ddr: + if (!pll_clk_cell->rate_table) + { + rk_cell->cell.ops = &rockchip_rk3588_pll_clk_norate_ops; + } + else + { + rk_cell->cell.ops = &rockchip_rk3588_pll_clk_ops; + } + goto _set_falgs_done; + default: + break; + } + + if (!(pll_clk_cell->flags & ROCKCHIP_PLL_ALLOW_POWER_DOWN)) + { + /* Keep all plls untouched for now */ + rk_cell->cell.flags |= RT_CLK_F_IGNORE_UNUSED; + } + +_set_falgs_done: + return; +} + +void rockchip_pll_clk_cell_setup(struct rockchip_clk_cell *rk_cell) +{ + struct rockchip_pll_clk_cell *pll_clk_cell = cell_to_rockchip_pll_clk_cell(&rk_cell->cell); + + switch (pll_clk_cell->type) + { + case pll_type_rk3036: + case pll_type_rk3328: + if (pll_clk_cell->rate_table) + { + rockchip_rk3036_pll_init(&rk_cell->cell); + } + break; + case pll_type_rk3066: + if (pll_clk_cell->rate_table && rk_cell->provider->grf) + { + rockchip_rk3066_pll_init(&rk_cell->cell); + } + break; + case pll_type_rk3399: + if (pll_clk_cell->rate_table) + { + rockchip_rk3399_pll_init(&rk_cell->cell); + } + break; + default: + break; + } +} diff --git a/bsp/rockchip/dm/clk/clk-rk-pll.h b/bsp/rockchip/dm/clk/clk-rk-pll.h new file mode 100755 index 00000000000..5d718889cb5 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk-pll.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_PLL_H__ +#define __CLK_RK_PLL_H__ + +#include "clk-rk.h" + +enum rockchip_pll_type +{ + pll_type_rk3036, + pll_type_rk3066, + pll_type_rk3328, + pll_type_rk3399, + pll_type_rk3588, + pll_type_rk3588_core, + pll_type_rk3588_ddr, +}; + +struct rockchip_pll_rate_table +{ + rt_ubase_t rate; + union + { + struct + { + /* For RK3066 */ + rt_uint32_t nr; + rt_uint32_t nf; + rt_uint32_t no; + rt_uint32_t nb; + }; + struct + { + /* For RK3036/RK3399 */ + rt_uint32_t fbdiv; + rt_uint32_t postdiv1; + rt_uint32_t refdiv; + rt_uint32_t postdiv2; + rt_uint32_t dsmpd; + rt_uint32_t frac; + }; + struct + { + /* For RK3588 */ + rt_uint32_t m; + rt_uint32_t p; + rt_uint32_t s; + rt_uint32_t k; + }; + }; +}; + +#define RK3066_PLL_RATE(_rate, _nr, _nf, _no) \ +{ \ + .rate = _rate##U, \ + .nr = _nr, \ + .nf = _nf, \ + .no = _no, \ + .nb = ((_nf) < 2) ? 1 : (_nf) >> 1, \ +} + +#define RK3036_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac) \ +{ \ + .rate = _rate##U, \ + .fbdiv = _fbdiv, \ + .postdiv1 = _postdiv1, \ + .refdiv = _refdiv, \ + .postdiv2 = _postdiv2, \ + .dsmpd = _dsmpd, \ + .frac = _frac, \ +} + +#define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \ +{ \ + .rate = _rate##U, \ + .p = _p, \ + .m = _m, \ + .s = _s, \ + .k = _k, \ +} + +struct rockchip_pll_clk_cell +{ + struct rockchip_clk_cell rk_cell; + + enum rockchip_pll_type type; + + int con_offset; + int mode_offset; + int mode_shift; + int lock_shift; + int grf_lock_offset; + + int sel; + rt_ubase_t scaling; + +#define ROCKCHIP_PLL_SYNC_RATE RT_BIT(0) +#define ROCKCHIP_PLL_FIXED_MODE RT_BIT(1) +#define ROCKCHIP_PLL_ALLOW_POWER_DOWN RT_BIT(2) + rt_uint8_t flags; + struct rockchip_pll_rate_table *rate_table; +}; + +#define PLL_RAW(_type, _id, _name, _pnames, _pnames_nr, _flags, _con, _mode, _mshift, _lshift, _glock, _pflags, _rtable) \ +{ \ + .rk_cell.cell.name = _name, \ + .rk_cell.cell.parent_names = (void *)_pnames, \ + .rk_cell.cell.parents_nr = _pnames_nr, \ + .rk_cell.cell.flags = RT_CLK_F_GET_RATE_NOCACHE | _flags, \ + .rk_cell.id = _id, \ + .rk_cell.init = rockchip_pll_clk_cell_init, \ + .rk_cell.setup = rockchip_pll_clk_cell_setup, \ + .type = _type, \ + .con_offset = _con, \ + .mode_offset = _mode, \ + .mode_shift = _mshift, \ + .lock_shift = _lshift, \ + .grf_lock_offset = _glock, \ + .flags = _pflags, \ + .rate_table = _rtable, \ +} + +#define PLL(_type, _id, _name, _pnames, _pnames_nr, _flags, _con, _mode, _mshift, _lshift, _glock, _pflags, _rtable) \ + (void *)&(struct rockchip_pll_clk_cell)PLL_RAW(_type, _id, _name, _pnames, _pnames_nr, _flags, _con, _mode, _mshift, _lshift, _glock, _pflags, _rtable) + +rt_inline struct rockchip_pll_clk_cell *cell_to_rockchip_pll_clk_cell(struct rt_clk_cell *cell) +{ + struct rockchip_clk_cell *rk_cell = cell_to_rockchip_clk_cell(cell); + + return rt_container_of(rk_cell, struct rockchip_pll_clk_cell, rk_cell); +} + +void rockchip_pll_clk_cell_init(struct rockchip_clk_cell *rk_cell); +void rockchip_pll_clk_cell_setup(struct rockchip_clk_cell *rk_cell); + +#endif /* __CLK_RK_PLL_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk.c b/bsp/rockchip/dm/clk/clk-rk.c new file mode 100755 index 00000000000..9ba970f076c --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk.c @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk.h" + +int rockchip_gcd(int m, int n) +{ + while (m > 0) + { + if (n > m) + { + int t = m; + m = n; + n = t; + } + m -= n; + } + + return n; +} + +/* + * rational_best_approximation(31415, 10000, + * (1 << 8) - 1, (1 << 5) - 1, &n, &d); + * + * you may look at given_numerator as a fixed point number, + * with the fractional part size described in given_denominator. + * + * for theoretical background, see: + * http://en.wikipedia.org/wiki/Continued_fraction + */ +void rational_best_approximation(rt_ubase_t given_numerator, + rt_ubase_t given_denominator, + rt_ubase_t max_numerator, + rt_ubase_t max_denominator, + rt_ubase_t *best_numerator, + rt_ubase_t *best_denominator) +{ + rt_ubase_t n, d, n0, d0, n1, d1; + + n = given_numerator; + d = given_denominator; + n0 = 0; + d1 = 0; + n1 = 1; + d0 = 1; + + for (;;) + { + rt_ubase_t t, a; + + if (n1 > max_numerator || d1 > max_denominator) + { + n1 = n0; + d1 = d0; + break; + } + if (d == 0) + { + break; + } + t = d; + a = n / d; + d = n % d; + n = t; + t = n0 + a * n1; + n0 = n1; + n1 = t; + t = d0 + a * d1; + d0 = d1; + d1 = t; + } + *best_numerator = n1; + *best_denominator = d1; +} + +void rockchip_clk_init(struct rockchip_clk_provider *provider, + struct rt_clk_cell **cells, rt_size_t cells_nr) +{ + for (rt_size_t i = 0; i < cells_nr; ++i) + { + struct rt_clk_cell *cell = cells[i]; + struct rockchip_clk_cell *rk_cell; + + if (!cell) + { + continue; + } + + rk_cell = cell_to_rockchip_clk_cell(cell); + rk_cell->provider = provider; + + if (rk_cell->init) + { + rk_cell->init(rk_cell); + } + } +} + +void rockchip_clk_setup(struct rockchip_clk_provider *provider, + struct rt_clk_cell **cells, rt_size_t cells_nr) +{ + for (rt_size_t i = 0; i < cells_nr; ++i) + { + struct rt_clk_cell *cell = cells[i]; + struct rockchip_clk_cell *rk_cell; + + if (!cell) + { + continue; + } + + rk_cell = cell_to_rockchip_clk_cell(cell); + + if (rk_cell->setup) + { + rk_cell->setup(rk_cell); + } + } +} + +struct rockchip_restart +{ + struct rt_device parent; + + rt_uint32_t reg; + struct rockchip_clk_provider *provider; + void (*callback)(struct rockchip_clk_provider *provider); +}; + +static rt_err_t rockchip_restart_handler(struct rt_device *dev) +{ + struct rockchip_restart *rdev = rt_container_of(dev, struct rockchip_restart, parent); + + if (rdev->callback) + { + rdev->callback(rdev->provider); + } + + HWREG32(rdev->provider->reg_base + rdev->reg) = 0xfdb9; + + return RT_EOK; +} + +void rockchip_register_restart_notifier(struct rockchip_clk_provider *provider, + rt_uint32_t reg, void (*callback)(struct rockchip_clk_provider *provider)) +{ + struct rockchip_restart *rdev = rt_calloc(1, sizeof(*rdev)); + + if (!rdev) + { + return; + } + + rdev->reg = reg; + rdev->provider = provider; + rdev->callback = callback; + rt_dm_dev_set_name(&rdev->parent, "RK-CLK"); + + rt_dm_power_off_handler(&rdev->parent, RT_DM_POWER_OFF_MODE_RESET, + RT_DM_POWER_OFF_PRIO_PLATFORM, rockchip_restart_handler); +} diff --git a/bsp/rockchip/dm/clk/clk-rk.h b/bsp/rockchip/dm/clk/clk-rk.h new file mode 100755 index 00000000000..a65e42bc665 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __CLK_RK_H__ +#define __CLK_RK_H__ + +#include + +struct rockchip_clk_provider +{ + void *reg_base; + struct rt_syscon *grf; + struct rt_syscon *pmugrf; +}; + +struct clk_div_table +{ + rt_uint32_t val; + rt_uint32_t div; +}; + +struct rockchip_clk_cell +{ + struct rt_clk_cell cell; + + int id; + + int muxdiv_offset; + rt_uint8_t mux_shift; + rt_uint8_t mux_width; +#define CLK_MUX_INDEX_ONE RT_BIT(0) +#define CLK_MUX_INDEX_BIT RT_BIT(1) +#define CLK_MUX_HIWORD_MASK RT_BIT(2) +#define CLK_MUX_READ_ONLY RT_BIT(3) +#define CLK_MUX_ROUND_CLOSEST RT_BIT(4) +#define CLK_MUX_BIG_ENDIAN RT_BIT(5) + rt_uint8_t mux_flags; + rt_uint32_t mux_mask; + rt_uint32_t *mux_table; + + int div_offset; + rt_uint8_t div_shift; + rt_uint8_t div_width; +#define CLK_DIVIDER_ONE_BASED RT_BIT(0) +#define CLK_DIVIDER_POWER_OF_TWO RT_BIT(1) +#define CLK_DIVIDER_ALLOW_ZERO RT_BIT(2) +#define CLK_DIVIDER_HIWORD_MASK RT_BIT(3) +#define CLK_DIVIDER_ROUND_CLOSEST RT_BIT(4) +#define CLK_DIVIDER_READ_ONLY RT_BIT(5) +#define CLK_DIVIDER_MAX_AT_ZERO RT_BIT(6) +#define CLK_DIVIDER_BIG_ENDIAN RT_BIT(7) + +#define CLK_FRAC_DIVIDER_ZERO_BASED RT_BIT(0) +#define CLK_FRAC_DIVIDER_BIG_ENDIAN RT_BIT(1) +#define CLK_FRAC_DIVIDER_POWER_OF_TWO_PS RT_BIT(2) +#define CLK_FRAC_DIVIDER_NO_LIMIT RT_BIT(3) + rt_uint8_t div_flags; + struct clk_div_table *div_table; + + int gate_offset; + rt_uint8_t gate_shift; +#define CLK_GATE_SET_TO_DISABLE RT_BIT(0) +#define CLK_GATE_HIWORD_MASK RT_BIT(1) +#define CLK_GATE_BIG_ENDIAN RT_BIT(2) + rt_uint8_t gate_flags; + + struct rockchip_clk_provider *provider; + void (*init)(struct rockchip_clk_cell *cell); + void (*setup)(struct rockchip_clk_cell *cell); +}; + +#define cell_to_rockchip_clk_cell(cell) rt_container_of(cell, struct rockchip_clk_cell, cell) + +#define PNAME(x) static const char *const x +#define PNAMES(x) PNAME(x)[] + +void rational_best_approximation(rt_ubase_t given_numerator, + rt_ubase_t given_denominator, + rt_ubase_t max_numerator, + rt_ubase_t max_denominator, + rt_ubase_t *best_numerator, + rt_ubase_t *best_denominator); + +#define ROCKCHIP_SOFTRST_HIWORD_MASK RT_BIT(0) + +int rockchip_gcd(int m, int n); + +void rockchip_clk_init(struct rockchip_clk_provider *provider, + struct rt_clk_cell **cells, rt_size_t cells_nr); + +void rockchip_clk_setup(struct rockchip_clk_provider *provider, + struct rt_clk_cell **cells, rt_size_t cells_nr); + +rt_err_t rockchip_register_softrst(struct rt_reset_controller *rstcer, + struct rt_ofw_node *np, const int *lookup_table, void *regs, rt_uint8_t flags); + +void rockchip_register_restart_notifier(struct rockchip_clk_provider *provider, + rt_uint32_t reg, void (*callback)(struct rockchip_clk_provider *provider)); + +#endif /* __CLK_RK_H__ */ diff --git a/bsp/rockchip/dm/clk/clk-rk3308.c b/bsp/rockchip/dm/clk/clk-rk3308.c new file mode 100755 index 00000000000..dcce0cbb5fa --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk3308.c @@ -0,0 +1,950 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-composite.h" +#include "clk-rk-cpu.h" +#include "clk-rk-divider.h" +#include "clk-rk-factor.h" +#include "clk-rk-fraction-divider.h" +#include "clk-rk-gate.h" +#include "clk-rk.h" +#include "clk-rk-half-divider.h" +#include "clk-rk-mmc-phase.h" +#include "clk-rk-muxgrf.h" +#include "clk-rk-mux.h" +#include "clk-rk-pll.h" + +#define DBG_TAG "clk.rk3308" +#define DBG_LVL DBG_INFO +#include + +#include + +#define RK3308_PLL_CON(x) ((x) * 0x4) +#define RK3308_CLKSEL_CON(x) ((x) * 0x4 + 0x100) +#define RK3308_CLKGATE_CON(x) ((x) * 0x4 + 0x300) +#define RK3308_GLB_SRST_FST 0xb8 +#define RK3308_SOFTRST_CON(x) ((x) * 0x4 + 0x400) +#define RK3308_MODE_CON 0xa0 +#define RK3308_SDMMC_CON0 0x480 +#define RK3308_SDMMC_CON1 0x484 +#define RK3308_SDIO_CON0 0x488 +#define RK3308_SDIO_CON1 0x48c +#define RK3308_EMMC_CON0 0x490 +#define RK3308_EMMC_CON1 0x494 +#define RK3308_GRF_SOC_STATUS0 0x380 + +#define RK3308_DIV_ACLKM_MASK 0x7 +#define RK3308_DIV_ACLKM_SHIFT 12 +#define RK3308_DIV_PCLK_DBG_MASK 0xf +#define RK3308_DIV_PCLK_DBG_SHIFT 8 + +struct clk_rk3308_cru +{ + struct rt_clk_node clk_parent; + struct rt_reset_controller rstc_parent; + + struct rockchip_clk_provider provider; +}; + +static struct rockchip_pll_rate_table rk3308_pll_rates[] = +{ + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1584000000, 1, 66, 1, 1, 1, 0), + RK3036_PLL_RATE(1560000000, 1, 65, 1, 1, 1, 0), + RK3036_PLL_RATE(1536000000, 1, 64, 1, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(1488000000, 1, 62, 1, 1, 1, 0), + RK3036_PLL_RATE(1464000000, 1, 61, 1, 1, 1, 0), + RK3036_PLL_RATE(1440000000, 1, 60, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(1392000000, 1, 58, 1, 1, 1, 0), + RK3036_PLL_RATE(1368000000, 1, 57, 1, 1, 1, 0), + RK3036_PLL_RATE(1344000000, 1, 56, 1, 1, 1, 0), + RK3036_PLL_RATE(1320000000, 1, 55, 1, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(1272000000, 1, 53, 1, 1, 1, 0), + RK3036_PLL_RATE(1248000000, 1, 52, 1, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 2, 99, 1, 1, 1, 0), + RK3036_PLL_RATE(1104000000, 1, 46, 1, 1, 1, 0), + RK3036_PLL_RATE(1100000000, 12, 550, 1, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 6, 500, 2, 1, 1, 0), + RK3036_PLL_RATE(984000000, 1, 82, 2, 1, 1, 0), + RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0), + RK3036_PLL_RATE(936000000, 1, 78, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(900000000, 4, 300, 2, 1, 1, 0), + RK3036_PLL_RATE(888000000, 1, 74, 2, 1, 1, 0), + RK3036_PLL_RATE(864000000, 1, 72, 2, 1, 1, 0), + RK3036_PLL_RATE(840000000, 1, 70, 2, 1, 1, 0), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 6, 400, 2, 1, 1, 0), + RK3036_PLL_RATE(700000000, 6, 350, 2, 1, 1, 0), + RK3036_PLL_RATE(696000000, 1, 58, 2, 1, 1, 0), + RK3036_PLL_RATE(624000000, 1, 52, 2, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 75, 3, 1, 1, 0), + RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(504000000, 1, 63, 3, 1, 1, 0), + RK3036_PLL_RATE(500000000, 6, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 52, 2, 2, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(96000000, 1, 64, 4, 4, 1, 0), + { /* sentinel */ }, +}; + +#define RK3308_CLKSEL0(_aclk_core, _pclk_dbg) \ +{ \ + .reg = RK3308_CLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_aclk_core, RK3308_DIV_ACLKM_MASK, \ + RK3308_DIV_ACLKM_SHIFT) | \ + HIWORD_UPDATE(_pclk_dbg, RK3308_DIV_PCLK_DBG_MASK, \ + RK3308_DIV_PCLK_DBG_SHIFT), \ +} + +#define RK3308_CPUCLK_RATE(_prate, _aclk_core, _pclk_dbg) \ +{ \ + .prate = _prate, \ + .divs = \ + { \ + RK3308_CLKSEL0(_aclk_core, _pclk_dbg), \ + }, \ +} + +static struct rockchip_cpu_clk_rate_table rk3308_cpu_clk_rates[] = +{ + RK3308_CPUCLK_RATE(1608000000, 1, 7), + RK3308_CPUCLK_RATE(1512000000, 1, 7), + RK3308_CPUCLK_RATE(1488000000, 1, 5), + RK3308_CPUCLK_RATE(1416000000, 1, 5), + RK3308_CPUCLK_RATE(1392000000, 1, 5), + RK3308_CPUCLK_RATE(1296000000, 1, 5), + RK3308_CPUCLK_RATE(1200000000, 1, 5), + RK3308_CPUCLK_RATE(1104000000, 1, 5), + RK3308_CPUCLK_RATE(1008000000, 1, 5), + RK3308_CPUCLK_RATE(912000000, 1, 5), + RK3308_CPUCLK_RATE(816000000, 1, 3), + RK3308_CPUCLK_RATE(696000000, 1, 3), + RK3308_CPUCLK_RATE(600000000, 1, 3), + RK3308_CPUCLK_RATE(408000000, 1, 1), + RK3308_CPUCLK_RATE(312000000, 1, 1), + RK3308_CPUCLK_RATE(216000000, 1, 1), + RK3308_CPUCLK_RATE(96000000, 1, 1), +}; + +static const struct rockchip_cpu_clk_reg_data rk3308_cpu_clk_data = +{ + .core_reg[0] = RK3308_CLKSEL_CON(0), + .div_core_shift[0] = 0, + .div_core_mask[0] = 0xf, + .num_cores = 1, + .mux_core_alt = 1, + .mux_core_main = 0, + .mux_core_shift = 6, + .mux_core_mask = 0x3, +}; + +PNAME(mux_pll_p) = "xin24m"; +PNAMES(mux_usb480m_p) = { "xin24m", "usb480m_phy", "clk_rtc32k" }; +PNAMES(mux_dpll_vpll0_p) = { "dpll", "vpll0" }; +PNAMES(mux_dpll_vpll0_xin24m_p) = { "dpll", "vpll0", "xin24m" }; +PNAMES(mux_dpll_vpll0_vpll1_p) = { "dpll", "vpll0", "vpll1" }; +PNAMES(mux_dpll_vpll0_vpll1_xin24m_p) = { "dpll", "vpll0", "vpll1", "xin24m" }; +PNAMES(mux_vpll0_vpll1_p) = { "vpll0", "vpll1" }; +PNAMES(mux_vpll0_vpll1_xin24m_p) = { "vpll0", "vpll1", "xin24m" }; +PNAMES(mux_uart0_p) = { "clk_uart0_src", "dummy", "clk_uart0_frac" }; +PNAMES(mux_uart1_p) = { "clk_uart1_src", "dummy", "clk_uart1_frac" }; +PNAMES(mux_uart2_p) = { "clk_uart2_src", "dummy", "clk_uart2_frac" }; +PNAMES(mux_uart3_p) = { "clk_uart3_src", "dummy", "clk_uart3_frac" }; +PNAMES(mux_uart4_p) = { "clk_uart4_src", "dummy", "clk_uart4_frac" }; +PNAMES(mux_dclk_vop_p) = { "dclk_vop_src", "dclk_vop_frac", "xin24m" }; +PNAMES(mux_nandc_p) = { "clk_nandc_div", "clk_nandc_div50" }; +PNAMES(mux_sdmmc_p) = { "clk_sdmmc_div", "clk_sdmmc_div50" }; +PNAMES(mux_sdio_p) = { "clk_sdio_div", "clk_sdio_div50" }; +PNAMES(mux_emmc_p) = { "clk_emmc_div", "clk_emmc_div50" }; +PNAMES(mux_mac_p) = { "clk_mac_src", "mac_clkin" }; +PNAMES(mux_mac_rmii_sel_p) = { "clk_mac_rx_tx_div20", "clk_mac_rx_tx_div2" }; +PNAMES(mux_ddrstdby_p) = { "clk_ddrphy1x_out", "clk_ddr_stdby_div4" }; +PNAMES(mux_rtc32k_p) = { "xin32k", "clk_pvtm_32k", "clk_rtc32k_frac", "clk_rtc32k_div" }; +PNAMES(mux_usbphy_ref_p) = { "xin24m", "clk_usbphy_ref_src" }; +PNAMES(mux_wifi_src_p) = { "clk_wifi_dpll", "clk_wifi_vpll0" }; +PNAMES(mux_wifi_p) = { "clk_wifi_osc", "clk_wifi_src" }; +PNAMES(mux_pdm_p) = { "clk_pdm_src", "clk_pdm_frac" }; +PNAMES(mux_i2s0_8ch_tx_p) = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "mclk_i2s0_8ch_in" }; +PNAMES(mux_i2s0_8ch_tx_rx_p) = { "clk_i2s0_8ch_tx_mux", "clk_i2s0_8ch_rx_mux"}; +PNAMES(mux_i2s0_8ch_tx_out_p) = { "clk_i2s0_8ch_tx", "xin12m" }; +PNAMES(mux_i2s0_8ch_rx_p) = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "mclk_i2s0_8ch_in" }; +PNAMES(mux_i2s0_8ch_rx_tx_p) = { "clk_i2s0_8ch_rx_mux", "clk_i2s0_8ch_tx_mux"}; +PNAMES(mux_i2s1_8ch_tx_p) = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "mclk_i2s1_8ch_in" }; +PNAMES(mux_i2s1_8ch_tx_rx_p) = { "clk_i2s1_8ch_tx_mux", "clk_i2s1_8ch_rx_mux"}; +PNAMES(mux_i2s1_8ch_tx_out_p) = { "clk_i2s1_8ch_tx", "xin12m" }; +PNAMES(mux_i2s1_8ch_rx_p) = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "mclk_i2s1_8ch_in" }; +PNAMES(mux_i2s1_8ch_rx_tx_p) = { "clk_i2s1_8ch_rx_mux", "clk_i2s1_8ch_tx_mux"}; +PNAMES(mux_i2s2_8ch_tx_p) = { "clk_i2s2_8ch_tx_src", "clk_i2s2_8ch_tx_frac", "mclk_i2s2_8ch_in" }; +PNAMES(mux_i2s2_8ch_tx_rx_p) = { "clk_i2s2_8ch_tx_mux", "clk_i2s2_8ch_rx_mux"}; +PNAMES(mux_i2s2_8ch_tx_out_p) = { "clk_i2s2_8ch_tx", "xin12m" }; +PNAMES(mux_i2s2_8ch_rx_p) = { "clk_i2s2_8ch_rx_src", "clk_i2s2_8ch_rx_frac", "mclk_i2s2_8ch_in" }; +PNAMES(mux_i2s2_8ch_rx_tx_p) = { "clk_i2s2_8ch_rx_mux", "clk_i2s2_8ch_tx_mux"}; +PNAMES(mux_i2s3_8ch_tx_p) = { "clk_i2s3_8ch_tx_src", "clk_i2s3_8ch_tx_frac", "mclk_i2s3_8ch_in" }; +PNAMES(mux_i2s3_8ch_tx_rx_p) = { "clk_i2s3_8ch_tx_mux", "clk_i2s3_8ch_rx_mux"}; +PNAMES(mux_i2s3_8ch_tx_out_p) = { "clk_i2s3_8ch_tx", "xin12m" }; +PNAMES(mux_i2s3_8ch_rx_p) = { "clk_i2s3_8ch_rx_src", "clk_i2s3_8ch_rx_frac", "mclk_i2s3_8ch_in" }; +PNAMES(mux_i2s3_8ch_rx_tx_p) = { "clk_i2s3_8ch_rx_mux", "clk_i2s3_8ch_tx_mux"}; +PNAMES(mux_i2s0_2ch_p) = { "clk_i2s0_2ch_src", "clk_i2s0_2ch_frac", "mclk_i2s0_2ch_in" }; +PNAMES(mux_i2s0_2ch_out_p) = { "clk_i2s0_2ch", "xin12m" }; +PNAMES(mux_i2s1_2ch_p) = { "clk_i2s1_2ch_src", "clk_i2s1_2ch_frac", "mclk_i2s1_2ch_in"}; +PNAMES(mux_i2s1_2ch_out_p) = { "clk_i2s1_2ch", "xin12m" }; +PNAMES(mux_spdif_tx_src_p) = { "clk_spdif_tx_div", "clk_spdif_tx_div50" }; +PNAMES(mux_spdif_tx_p) = { "clk_spdif_tx_src", "clk_spdif_tx_frac", "mclk_i2s0_2ch_in" }; +PNAMES(mux_spdif_rx_src_p) = { "clk_spdif_rx_div", "clk_spdif_rx_div50" }; +PNAMES(mux_spdif_rx_p) = { "clk_spdif_rx_src", "clk_spdif_rx_frac" }; +PNAMES(mux_uart_src_p) = { "usb480m", "xin24m", "dpll", "vpll0", "vpll1" }; +static rt_uint32_t uart_src_mux_idx[] = { 3, 4, 0, 1, 2 }; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_pll_clk_cell rk3308_pll_apll = + PLL_RAW(pll_type_rk3328, PLL_APLL, "apll", mux_pll_p, 1, 0, RK3308_PLL_CON(0), RK3308_MODE_CON, + 0, 0, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates); +static struct rockchip_pll_clk_cell rk3308_pll_dpll = + PLL_RAW(pll_type_rk3328, PLL_DPLL, "dpll", mux_pll_p, 1, 0, RK3308_PLL_CON(8), RK3308_MODE_CON, + 2, 1, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates); +static struct rockchip_pll_clk_cell rk3308_pll_vpll0 = + PLL_RAW(pll_type_rk3328, PLL_VPLL0, "vpll0", mux_pll_p, 1, 0, RK3308_PLL_CON(16), RK3308_MODE_CON, + 4, 2, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates); +static struct rockchip_pll_clk_cell rk3308_pll_vpll1 = + PLL_RAW(pll_type_rk3328, PLL_VPLL1, "vpll1", mux_pll_p, 1, 0, RK3308_PLL_CON(24), RK3308_MODE_CON, + 6, 3, RK3308_GRF_SOC_STATUS0, 0, rk3308_pll_rates); + +static struct rockchip_clk_cell rk3308_uart0_fracmux = + MUX_RAW(0, "clk_uart0_mux", mux_uart0_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(11), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_uart1_fracmux = + MUX_RAW(0, "clk_uart1_mux", mux_uart1_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(14), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_uart2_fracmux = + MUX_RAW(0, "clk_uart2_mux", mux_uart2_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(17), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_uart3_fracmux = + MUX_RAW(0, "clk_uart3_mux", mux_uart3_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(20), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_uart4_fracmux = + MUX_RAW(0, "clk_uart4_mux", mux_uart4_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(23), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_dclk_vop_fracmux = + MUX_RAW(0, "dclk_vop_mux", mux_dclk_vop_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(8), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_rtc32k_fracmux = + MUX_RAW(SCLK_RTC32K, "clk_rtc32k", mux_rtc32k_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(2), 8, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_pdm_fracmux = + MUX_RAW(0, "clk_pdm_mux", mux_pdm_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(46), 15, 1, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s0_8ch_tx_fracmux = + MUX_RAW(SCLK_I2S0_8CH_TX_MUX, "clk_i2s0_8ch_tx_mux", mux_i2s0_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(52), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s0_8ch_rx_fracmux = + MUX_RAW(SCLK_I2S0_8CH_RX_MUX, "clk_i2s0_8ch_rx_mux", mux_i2s0_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(54), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s1_8ch_tx_fracmux = + MUX_RAW(SCLK_I2S1_8CH_TX_MUX, "clk_i2s1_8ch_tx_mux", mux_i2s1_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(56), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s1_8ch_rx_fracmux = + MUX_RAW(SCLK_I2S1_8CH_RX_MUX, "clk_i2s1_8ch_rx_mux", mux_i2s1_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(58), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s2_8ch_tx_fracmux = + MUX_RAW(SCLK_I2S2_8CH_TX_MUX, "clk_i2s2_8ch_tx_mux", mux_i2s2_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(60), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s2_8ch_rx_fracmux = + MUX_RAW(SCLK_I2S2_8CH_RX_MUX, "clk_i2s2_8ch_rx_mux", mux_i2s2_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(62), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s3_8ch_tx_fracmux = + MUX_RAW(SCLK_I2S3_8CH_TX_MUX, "clk_i2s3_8ch_tx_mux", mux_i2s3_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(64), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s3_8ch_rx_fracmux = + MUX_RAW(SCLK_I2S3_8CH_RX_MUX, "clk_i2s3_8ch_rx_mux", mux_i2s3_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(66), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s0_2ch_fracmux = + MUX_RAW(0, "clk_i2s0_2ch_mux", mux_i2s0_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(68), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_i2s1_2ch_fracmux = + MUX_RAW(0, "clk_i2s1_2ch_mux", mux_i2s1_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(70), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_spdif_tx_fracmux = + MUX_RAW(0, "clk_spdif_tx_mux", mux_spdif_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(48), 14, 2, MFLAGS); + +static struct rockchip_clk_cell rk3308_spdif_rx_fracmux = + MUX_RAW(0, "clk_spdif_rx_mux", mux_spdif_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(50), 15, 1, MFLAGS); + +static struct rt_clk_cell *rk3308_clk_cells[] = +{ + [PLL_APLL] = &rk3308_pll_apll.rk_cell.cell, + [PLL_DPLL] = &rk3308_pll_dpll.rk_cell.cell, + [PLL_VPLL0] = &rk3308_pll_vpll0.rk_cell.cell, + [PLL_VPLL1] = &rk3308_pll_vpll1.rk_cell.cell, + [ARMCLK] = CPU(ARMCLK, "armclk", &rk3308_pll_apll.rk_cell, &rk3308_pll_vpll0.rk_cell, + rk3308_cpu_clk_rates, RT_ARRAY_SIZE(rk3308_cpu_clk_rates), &rk3308_cpu_clk_data), + [USB480M] = MUX(USB480M, "usb480m", mux_usb480m_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_MODE_CON, 8, 2, MFLAGS), + [SCLK_RTC32K] = &rk3308_rtc32k_fracmux.cell, + [SCLK_PVTM_CORE] = GATE(SCLK_PVTM_CORE, "clk_pvtm_core", "xin24m", 0, + RK3308_CLKGATE_CON(0), 4, GFLAGS), + [SCLK_UART0] = GATE(SCLK_UART0, "clk_uart0", "clk_uart0_mux", 0, + RK3308_CLKGATE_CON(1), 12, GFLAGS), + [SCLK_UART1] = GATE(SCLK_UART1, "clk_uart1", "clk_uart1_mux", 0, + RK3308_CLKGATE_CON(2), 0, GFLAGS), + [SCLK_UART2] = GATE(SCLK_UART2, "clk_uart2", "clk_uart2_mux", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKGATE_CON(2), 4, GFLAGS), + [SCLK_UART3] = GATE(SCLK_UART3, "clk_uart3", "clk_uart3_mux", 0, + RK3308_CLKGATE_CON(2), 8, GFLAGS), + [SCLK_UART4] = GATE(SCLK_UART4, "clk_uart4", "clk_uart4_mux", 0, + RK3308_CLKGATE_CON(2), 12, GFLAGS), + [SCLK_I2C0] = COMPOSITE(SCLK_I2C0, "clk_i2c0", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(25), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(2), 13, GFLAGS), + [SCLK_I2C1] = COMPOSITE(SCLK_I2C1, "clk_i2c1", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(26), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(2), 14, GFLAGS), + [SCLK_I2C2] = COMPOSITE(SCLK_I2C2, "clk_i2c2", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(27), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(2), 15, GFLAGS), + [SCLK_I2C3] =COMPOSITE(SCLK_I2C3, "clk_i2c3", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(28), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(3), 0, GFLAGS), + [SCLK_PWM0] = COMPOSITE(SCLK_PWM0, "clk_pwm0", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(29), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(3), 1, GFLAGS), + [SCLK_SPI0] = COMPOSITE(SCLK_SPI0, "clk_spi0", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(30), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(3), 2, GFLAGS), + [SCLK_SPI1] = COMPOSITE(SCLK_SPI1, "clk_spi1", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(31), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(3), 3, GFLAGS), + [SCLK_SPI2] = COMPOSITE(SCLK_SPI2, "clk_spi2", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(32), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(3), 4, GFLAGS), + [SCLK_TIMER0] = GATE(SCLK_TIMER0, "sclk_timer0", "xin24m", 0, RK3308_CLKGATE_CON(3), 10, GFLAGS), + [SCLK_TIMER1] = GATE(SCLK_TIMER1, "sclk_timer1", "xin24m", 0, RK3308_CLKGATE_CON(3), 11, GFLAGS), + [SCLK_TIMER2] = GATE(SCLK_TIMER2, "sclk_timer2", "xin24m", 0, RK3308_CLKGATE_CON(3), 12, GFLAGS), + [SCLK_TIMER3] = GATE(SCLK_TIMER3, "sclk_timer3", "xin24m", 0, RK3308_CLKGATE_CON(3), 13, GFLAGS), + [SCLK_TIMER4] = GATE(SCLK_TIMER4, "sclk_timer4", "xin24m", 0, RK3308_CLKGATE_CON(3), 14, GFLAGS), + [SCLK_TIMER5] = GATE(SCLK_TIMER5, "sclk_timer5", "xin24m", 0, RK3308_CLKGATE_CON(3), 15, GFLAGS), + [SCLK_TSADC] = COMPOSITE_NOMUX(SCLK_TSADC, "clk_tsadc", "xin24m", 0, + RK3308_CLKSEL_CON(33), 0, 11, DFLAGS, + RK3308_CLKGATE_CON(3), 5, GFLAGS), + [SCLK_SARADC] = COMPOSITE_NOMUX(SCLK_SARADC, "clk_saradc", "xin24m", 0, + RK3308_CLKSEL_CON(34), 0, 11, DFLAGS, + RK3308_CLKGATE_CON(3), 6, GFLAGS), + [SCLK_OTP] = COMPOSITE_NOMUX(SCLK_OTP, "clk_otp", "xin24m", 0, + RK3308_CLKSEL_CON(35), 0, 4, DFLAGS, + RK3308_CLKGATE_CON(3), 7, GFLAGS), + [SCLK_OTP_USR] = COMPOSITE_NOMUX(SCLK_OTP_USR, "clk_otp_usr", "clk_otp", 0, + RK3308_CLKSEL_CON(35), 4, 2, DFLAGS, + RK3308_CLKGATE_CON(3), 8, GFLAGS), + [SCLK_CPU_BOOST] = GATE(SCLK_CPU_BOOST, "clk_cpu_boost", "xin24m", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(3), 9, GFLAGS), + [SCLK_CRYPTO] = COMPOSITE(SCLK_CRYPTO, "clk_crypto", mux_dpll_vpll0_vpll1_p, 0, + RK3308_CLKSEL_CON(7), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 4, GFLAGS), + [SCLK_CRYPTO_APK] = COMPOSITE(SCLK_CRYPTO_APK, "clk_crypto_apk", mux_dpll_vpll0_vpll1_p, 0, + RK3308_CLKSEL_CON(7), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 5, GFLAGS), + [SCLK_NANDC_DIV] = COMPOSITE(SCLK_NANDC_DIV, "clk_nandc_div", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(8), 4, GFLAGS), + [SCLK_NANDC_DIV50] = COMPOSITE(SCLK_NANDC_DIV50, "clk_nandc_div50", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(8), 4, GFLAGS), + [SCLK_NANDC] = COMPOSITE_NODIV(SCLK_NANDC, "clk_nandc", mux_nandc_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(38), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(8), 5, GFLAGS), + [SCLK_SDMMC_DIV] = COMPOSITE(SCLK_SDMMC_DIV, "clk_sdmmc_div", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(39), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(8), 6, GFLAGS), + [SCLK_SDMMC_DIV50] = COMPOSITE(SCLK_SDMMC_DIV50, "clk_sdmmc_div50", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(39), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(8), 6, GFLAGS), + [SCLK_SDMMC] =COMPOSITE_NODIV(SCLK_SDMMC, "clk_sdmmc", mux_sdmmc_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(39), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(8), 7, GFLAGS), + [SCLK_SDMMC_DRV] = MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", RK3308_SDMMC_CON0, 1), + [SCLK_SDMMC_SAMPLE] = MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", RK3308_SDMMC_CON1, 1), + [SCLK_SDIO_DIV] = COMPOSITE(SCLK_SDIO_DIV, "clk_sdio_div", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(40), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(8), 8, GFLAGS), + [SCLK_SDIO_DIV50] = COMPOSITE(SCLK_SDIO_DIV50, "clk_sdio_div50", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(40), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(8), 8, GFLAGS), + [SCLK_SDIO] = COMPOSITE_NODIV(SCLK_SDIO, "clk_sdio", mux_sdio_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(40), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(8), 9, GFLAGS), + [SCLK_SDIO_DRV] = MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", RK3308_SDIO_CON0, 1), + [SCLK_SDIO_SAMPLE] = MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", RK3308_SDIO_CON1, 1), + [SCLK_EMMC_DIV] = COMPOSITE(SCLK_EMMC_DIV, "clk_emmc_div", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(41), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(8), 10, GFLAGS), + [SCLK_EMMC_DIV50] = COMPOSITE(SCLK_EMMC_DIV50, "clk_emmc_div50", mux_dpll_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(41), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(8), 10, GFLAGS), + [SCLK_EMMC] = COMPOSITE_NODIV(SCLK_EMMC, "clk_emmc", mux_emmc_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(41), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(8), 11, GFLAGS), + [SCLK_EMMC_DRV] = MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", RK3308_EMMC_CON0, 1), + [SCLK_EMMC_SAMPLE] = MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", RK3308_EMMC_CON1, 1), + [SCLK_SFC] = COMPOSITE(SCLK_SFC, "clk_sfc", mux_dpll_vpll0_vpll1_p, 0, + RK3308_CLKSEL_CON(42), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(8), 12, GFLAGS), + [SCLK_OTG_ADP] = GATE(SCLK_OTG_ADP, "clk_otg_adp", "clk_rtc32k", 0, + RK3308_CLKGATE_CON(8), 13, GFLAGS), + [SCLK_MAC_SRC] = COMPOSITE(SCLK_MAC_SRC, "clk_mac_src", mux_dpll_vpll0_vpll1_p, 0, + RK3308_CLKSEL_CON(43), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(8), 14, GFLAGS), + [SCLK_MAC] = MUX(SCLK_MAC, "clk_mac", mux_mac_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(43), 14, 1, MFLAGS), + [SCLK_MAC_REF] = GATE(SCLK_MAC_REF, "clk_mac_ref", "clk_mac", 0, + RK3308_CLKGATE_CON(9), 1, GFLAGS), + [SCLK_MAC_RX_TX] = GATE(SCLK_MAC_RX_TX, "clk_mac_rx_tx", "clk_mac", 0, + RK3308_CLKGATE_CON(9), 0, GFLAGS), + [SCLK_MAC_RMII] = MUX(SCLK_MAC_RMII, "clk_mac_rmii_sel", mux_mac_rmii_sel_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(43), 15, 1, MFLAGS), + [SCLK_DDRCLK] = COMPOSITE(SCLK_DDRCLK, "clk_ddrphy4x_src", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 3, DFLAGS, + RK3308_CLKGATE_CON(0), 10, GFLAGS), + [SCLK_PMU] = GATE(SCLK_PMU, "clk_pmu", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 6, GFLAGS), + [SCLK_USBPHY_REF] = COMPOSITE_NODIV(SCLK_USBPHY_REF, "clk_usbphy_ref", mux_usbphy_ref_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(72), 7, 1, MFLAGS, + RK3308_CLKGATE_CON(4), 8, GFLAGS), + [SCLK_WIFI] = COMPOSITE_NODIV(SCLK_WIFI, "clk_wifi", mux_wifi_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(44), 7, 1, MFLAGS, + RK3308_CLKGATE_CON(4), 1, GFLAGS), + [SCLK_PVTM_PMU] = GATE(SCLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0, + RK3308_CLKGATE_CON(4), 4, GFLAGS), + [SCLK_PDM] = GATE(SCLK_PDM, "clk_pdm", "clk_pdm_mux", 0, + RK3308_CLKGATE_CON(10), 5, GFLAGS), + [SCLK_I2S0_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", mux_i2s0_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(52), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(10), 14, GFLAGS), + [SCLK_I2S0_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S0_8CH_TX_OUT, "clk_i2s0_8ch_tx_out", mux_i2s0_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(52), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(10), 15, GFLAGS), + [SCLK_I2S0_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", mux_i2s0_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(54), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(11), 2, GFLAGS), + [SCLK_I2S0_8CH_RX_OUT] = GATE(SCLK_I2S0_8CH_RX_OUT, "clk_i2s0_8ch_rx_out", "clk_i2s0_8ch_rx", 0, + RK3308_CLKGATE_CON(11), 3, GFLAGS), + [SCLK_I2S1_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", mux_i2s1_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(56), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(11), 6, GFLAGS), + [SCLK_I2S1_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S1_8CH_TX_OUT, "clk_i2s1_8ch_tx_out", mux_i2s1_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(56), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(11), 7, GFLAGS), + [SCLK_I2S1_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", mux_i2s1_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(58), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(11), 10, GFLAGS), + [SCLK_I2S1_8CH_RX_OUT] = GATE(SCLK_I2S1_8CH_RX_OUT, "clk_i2s1_8ch_rx_out", "clk_i2s1_8ch_rx", 0, + RK3308_CLKGATE_CON(11), 11, GFLAGS), + [SCLK_I2S2_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S2_8CH_TX, "clk_i2s2_8ch_tx", mux_i2s2_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(60), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(11), 14, GFLAGS), + [SCLK_I2S2_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S2_8CH_TX_OUT, "clk_i2s2_8ch_tx_out", mux_i2s2_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(60), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(11), 15, GFLAGS), + [SCLK_I2S2_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S2_8CH_RX, "clk_i2s2_8ch_rx", mux_i2s2_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(62), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(12), 2, GFLAGS), + [SCLK_I2S2_8CH_RX_OUT] = GATE(SCLK_I2S2_8CH_RX_OUT, "clk_i2s2_8ch_rx_out", "clk_i2s2_8ch_rx", 0, + RK3308_CLKGATE_CON(12), 3, GFLAGS), + [SCLK_I2S3_8CH_TX] = COMPOSITE_NODIV(SCLK_I2S3_8CH_TX, "clk_i2s3_8ch_tx", mux_i2s3_8ch_tx_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(64), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(12), 6, GFLAGS), + [SCLK_I2S3_8CH_TX_OUT] = COMPOSITE_NODIV(SCLK_I2S3_8CH_TX_OUT, "clk_i2s3_8ch_tx_out", mux_i2s3_8ch_tx_out_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(64), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(12), 7, GFLAGS), + [SCLK_I2S3_8CH_RX] = COMPOSITE_NODIV(SCLK_I2S3_8CH_RX, "clk_i2s3_8ch_rx", mux_i2s3_8ch_rx_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(66), 12, 1, MFLAGS, + RK3308_CLKGATE_CON(12), 10, GFLAGS), + [SCLK_I2S3_8CH_RX_OUT] = GATE(SCLK_I2S3_8CH_RX_OUT, "clk_i2s3_8ch_rx_out", "clk_i2s3_8ch_rx", 0, + RK3308_CLKGATE_CON(12), 11, GFLAGS), + [SCLK_I2S0_2CH] = GATE(SCLK_I2S0_2CH, "clk_i2s0_2ch", "clk_i2s0_2ch_mux", 0, + RK3308_CLKGATE_CON(12), 14, GFLAGS), + [SCLK_I2S0_2CH_OUT] = COMPOSITE_NODIV(SCLK_I2S0_2CH_OUT, "clk_i2s0_2ch_out", mux_i2s0_2ch_out_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(68), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(12), 15, GFLAGS), + [SCLK_I2S1_2CH] = GATE(SCLK_I2S1_2CH, "clk_i2s1_2ch", "clk_i2s1_2ch_mux", 0, + RK3308_CLKGATE_CON(13), 2, GFLAGS), + [SCLK_I2S1_2CH_OUT] = COMPOSITE_NODIV(SCLK_I2S1_2CH_OUT, "clk_i2s1_2ch_out", mux_i2s1_2ch_out_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(70), 15, 1, MFLAGS, + RK3308_CLKGATE_CON(13), 3, GFLAGS), + [SCLK_SPDIF_TX_DIV] = COMPOSITE(SCLK_SPDIF_TX_DIV, "clk_spdif_tx_div", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(10), 6, GFLAGS), + [SCLK_SPDIF_TX_DIV50] = COMPOSITE(SCLK_SPDIF_TX_DIV50, "clk_spdif_tx_div50", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(48), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(10), 6, GFLAGS), + [SCLK_SPDIF_TX] = GATE(SCLK_SPDIF_TX, "clk_spdif_tx", "clk_spdif_tx_mux", 0, + RK3308_CLKGATE_CON(10), 8, GFLAGS), + [SCLK_SPDIF_RX_DIV] = COMPOSITE(SCLK_SPDIF_RX_DIV, "clk_spdif_rx_div", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(10), 9, GFLAGS), + [SCLK_SPDIF_RX_DIV50] = COMPOSITE(SCLK_SPDIF_RX_DIV50, "clk_spdif_rx_div50", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(50), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(10), 9, GFLAGS), + [SCLK_SPDIF_RX] = GATE(SCLK_SPDIF_RX, "clk_spdif_rx", "clk_spdif_rx_mux", 0, + RK3308_CLKGATE_CON(10), 11, GFLAGS), + [SCLK_I2S0_8CH_TX_MUX] = &rk3308_i2s0_8ch_tx_fracmux.cell, + [SCLK_I2S0_8CH_RX_MUX] = &rk3308_i2s0_8ch_rx_fracmux.cell, + [SCLK_I2S1_8CH_TX_MUX] = &rk3308_i2s1_8ch_tx_fracmux.cell, + [SCLK_I2S1_8CH_RX_MUX] = &rk3308_i2s1_8ch_rx_fracmux.cell, + [SCLK_I2S2_8CH_TX_MUX] = &rk3308_i2s2_8ch_tx_fracmux.cell, + [SCLK_I2S2_8CH_RX_MUX] = &rk3308_i2s2_8ch_rx_fracmux.cell, + [SCLK_I2S3_8CH_TX_MUX] = &rk3308_i2s3_8ch_tx_fracmux.cell, + [SCLK_I2S3_8CH_RX_MUX] = &rk3308_i2s3_8ch_rx_fracmux.cell, + [SCLK_I2S0_8CH_TX_SRC] = COMPOSITE(SCLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(52), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(10), 12, GFLAGS), + [SCLK_I2S0_8CH_RX_SRC] = COMPOSITE(SCLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(54), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(11), 0, GFLAGS), + [SCLK_I2S1_8CH_TX_SRC] = COMPOSITE(SCLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(56), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(11), 4, GFLAGS), + [SCLK_I2S1_8CH_RX_SRC] = COMPOSITE(SCLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(58), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(11), 8, GFLAGS), + [SCLK_I2S2_8CH_TX_SRC] = COMPOSITE(SCLK_I2S2_8CH_TX_SRC, "clk_i2s2_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(60), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(11), 12, GFLAGS), + [SCLK_I2S2_8CH_RX_SRC] = COMPOSITE(SCLK_I2S2_8CH_RX_SRC, "clk_i2s2_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(62), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(12), 0, GFLAGS), + [SCLK_I2S3_8CH_TX_SRC] = COMPOSITE(SCLK_I2S3_8CH_TX_SRC, "clk_i2s3_8ch_tx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(64), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(12), 4, GFLAGS), + [SCLK_I2S3_8CH_RX_SRC] = COMPOSITE(SCLK_I2S3_8CH_RX_SRC, "clk_i2s3_8ch_rx_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(66), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(12), 8, GFLAGS), + [SCLK_I2S0_2CH_SRC] = COMPOSITE(SCLK_I2S0_2CH_SRC, "clk_i2s0_2ch_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(68), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(12), 12, GFLAGS), + [SCLK_I2S1_2CH_SRC] = COMPOSITE(SCLK_I2S1_2CH_SRC, "clk_i2s1_2ch_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(70), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(13), 0, GFLAGS), + [SCLK_PWM1] = COMPOSITE(SCLK_PWM1, "clk_pwm1", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(74), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(15), 0, GFLAGS), + [SCLK_PWM2] = COMPOSITE(SCLK_PWM2, "clk_pwm2", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(75), 14, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(15), 1, GFLAGS), + [SCLK_OWIRE] = COMPOSITE(SCLK_OWIRE, "clk_owire", mux_dpll_vpll0_xin24m_p, 0, + RK3308_CLKSEL_CON(44), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3308_CLKGATE_CON(8), 15, GFLAGS), + [DCLK_VOP] = GATE(DCLK_VOP, "dclk_vop", "dclk_vop_mux", 0, + RK3308_CLKGATE_CON(1), 8, GFLAGS), + [ACLK_BUS_SRC] = COMPOSITE_NODIV(ACLK_BUS_SRC, "clk_bus_src", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(5), 6, 2, MFLAGS, + RK3308_CLKGATE_CON(1), 0, GFLAGS), + [ACLK_BUS] = COMPOSITE_NOMUX(ACLK_BUS, "aclk_bus", "clk_bus_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(5), 0, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 1, GFLAGS), + [ACLK_PERI_SRC] = COMPOSITE_NODIV(ACLK_PERI_SRC, "clk_peri_src", mux_dpll_vpll0_vpll1_p, RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(36), 6, 2, MFLAGS, + RK3308_CLKGATE_CON(8), 0, GFLAGS), + [ACLK_PERI] = COMPOSITE_NOMUX(ACLK_PERI, "aclk_peri", "clk_peri_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(36), 0, 5, DFLAGS, + RK3308_CLKGATE_CON(8), 1, GFLAGS), + [ACLK_MAC] = GATE(ACLK_MAC, "aclk_mac", "aclk_peri", 0, RK3308_CLKGATE_CON(9), 4, GFLAGS), + [ACLK_CRYPTO] = GATE(ACLK_CRYPTO, "aclk_crypto", "aclk_bus", 0, RK3308_CLKGATE_CON(5), 2, GFLAGS), + [ACLK_VOP] = GATE(ACLK_VOP, "aclk_vop", "aclk_bus", 0, RK3308_CLKGATE_CON(5), 3, GFLAGS), + [ACLK_GIC] = GATE(ACLK_GIC, "aclk_gic", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 4, GFLAGS), + [ACLK_DMAC0] = SGRF_GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus"), + [ACLK_DMAC1] = SGRF_GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus"), + [HCLK_BUS] = COMPOSITE_NOMUX(HCLK_BUS, "hclk_bus", "clk_bus_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(6), 0, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 2, GFLAGS), + [HCLK_PERI] = COMPOSITE_NOMUX(HCLK_PERI, "hclk_peri", "clk_peri_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(37), 0, 5, DFLAGS, + RK3308_CLKGATE_CON(8), 2, GFLAGS), + [HCLK_AUDIO] = COMPOSITE_NOMUX(HCLK_AUDIO, "hclk_audio", "clk_audio_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(45), 0, 5, DFLAGS, + RK3308_CLKGATE_CON(10), 1, GFLAGS), + [HCLK_NANDC] = GATE(HCLK_NANDC, "hclk_nandc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 6, GFLAGS), + [HCLK_SDMMC] = GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 7, GFLAGS), + [HCLK_SDIO] = GATE(HCLK_SDIO, "hclk_sdio", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 8, GFLAGS), + [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 9, GFLAGS), + [HCLK_SFC] = GATE(HCLK_SFC, "hclk_sfc", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 10, GFLAGS), + [HCLK_OTG] = GATE(HCLK_OTG, "hclk_otg", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 11, GFLAGS), + [HCLK_HOST] = GATE(HCLK_HOST, "hclk_host", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 12, GFLAGS), + [HCLK_HOST_ARB] = GATE(HCLK_HOST_ARB, "hclk_host_arb", "hclk_peri", 0, RK3308_CLKGATE_CON(9), 13, GFLAGS), + [HCLK_PDM] = GATE(HCLK_PDM, "hclk_pdm", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 1, GFLAGS), + [HCLK_SPDIFTX] = GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 2, GFLAGS), + [HCLK_SPDIFRX] = GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 3, GFLAGS), + [HCLK_I2S0_8CH] = GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 4, GFLAGS), + [HCLK_I2S1_8CH] = GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 5, GFLAGS), + [HCLK_I2S2_8CH] = GATE(HCLK_I2S2_8CH, "hclk_i2s2_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 6, GFLAGS), + [HCLK_I2S3_8CH] = GATE(HCLK_I2S3_8CH, "hclk_i2s3_8ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 7, GFLAGS), + [HCLK_I2S0_2CH] = GATE(HCLK_I2S0_2CH, "hclk_i2s0_2ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 8, GFLAGS), + [HCLK_I2S1_2CH] = GATE(HCLK_I2S1_2CH, "hclk_i2s1_2ch", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 9, GFLAGS), + [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_audio", 0, RK3308_CLKGATE_CON(14), 10, GFLAGS), + [HCLK_CRYPTO] = GATE(HCLK_CRYPTO, "hclk_crypto", "hclk_bus", 0, RK3308_CLKGATE_CON(5), 7, GFLAGS), + [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_bus", 0, RK3308_CLKGATE_CON(5), 8, GFLAGS), + [PCLK_BUS] = COMPOSITE_NOMUX(PCLK_BUS, "pclk_bus", "clk_bus_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(6), 8, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 3, GFLAGS), + [PCLK_DDR] = GATE(PCLK_DDR, "pclk_ddr", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 15, GFLAGS), + [PCLK_PERI] = COMPOSITE_NOMUX(PCLK_PERI, "pclk_peri", "clk_peri_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(37), 8, 5, DFLAGS, + RK3308_CLKGATE_CON(8), 3, GFLAGS), + [PCLK_PMU] = GATE(PCLK_PMU, "pclk_pmu", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 5, GFLAGS), + [PCLK_AUDIO] = COMPOSITE_NOMUX(PCLK_AUDIO, "pclk_audio", "clk_audio_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(45), 8, 5, DFLAGS, + RK3308_CLKGATE_CON(10), 2, GFLAGS), + [PCLK_MAC] = GATE(PCLK_MAC, "pclk_mac", "pclk_peri", 0, RK3308_CLKGATE_CON(9), 15, GFLAGS), + [PCLK_ACODEC] = GATE(PCLK_ACODEC, "pclk_acodec", "pclk_audio", 0, RK3308_CLKGATE_CON(14), 12, GFLAGS), + [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 10, GFLAGS), + [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 11, GFLAGS), + [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 12, GFLAGS), + [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 13, GFLAGS), + [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 14, GFLAGS), + [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_bus", 0, RK3308_CLKGATE_CON(5), 15, GFLAGS), + [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 0, GFLAGS), + [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 1, GFLAGS), + [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 2, GFLAGS), + [PCLK_PWM0] = GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 3, GFLAGS), + [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 4, GFLAGS), + [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 5, GFLAGS), + [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 6, GFLAGS), + [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 7, GFLAGS), + [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 8, GFLAGS), + [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 9, GFLAGS), + [PCLK_OTP_NS] = GATE(PCLK_OTP_NS, "pclk_otp_ns", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 10, GFLAGS), + [PCLK_WDT] = SGRF_GATE(PCLK_WDT, "pclk_wdt", "pclk_bus"), + [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 12, GFLAGS), + [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 13, GFLAGS), + [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 14, GFLAGS), + [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0, RK3308_CLKGATE_CON(6), 15, GFLAGS), + [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 0, RK3308_CLKGATE_CON(7), 0, GFLAGS), + [PCLK_SGRF] = GATE(PCLK_SGRF, "pclk_sgrf", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 1, GFLAGS), + [PCLK_GRF] = GATE(PCLK_GRF, "pclk_grf", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 2, GFLAGS), + [PCLK_USBSD_DET] = GATE(PCLK_USBSD_DET, "pclk_usbsd_det", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 3, GFLAGS), + [PCLK_DDR_UPCTL] = GATE(PCLK_DDR_UPCTL, "pclk_ddr_upctl", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 4, GFLAGS), + [PCLK_DDR_MON] = GATE(PCLK_DDR_MON, "pclk_ddr_mon", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 5, GFLAGS), + [PCLK_DDRPHY] = GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 6, GFLAGS), + [PCLK_DDR_STDBY] = GATE(PCLK_DDR_STDBY, "pclk_ddr_stdby", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 7, GFLAGS), + [PCLK_USB_GRF] = GATE(PCLK_USB_GRF, "pclk_usb_grf", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 8, GFLAGS), + [PCLK_CRU] = GATE(PCLK_CRU, "pclk_cru", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 9, GFLAGS), + [PCLK_OTP_PHY] = GATE(PCLK_OTP_PHY, "pclk_otp_phy", "pclk_bus", 0, RK3308_CLKGATE_CON(7), 10, GFLAGS), + [PCLK_CPU_BOOST] = GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 11, GFLAGS), + [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 12, GFLAGS), + [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 13, GFLAGS), + [PCLK_CAN] = GATE(PCLK_CAN, "pclk_can", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 14, GFLAGS), + [PCLK_OWIRE] = GATE(PCLK_OWIRE, "pclk_owire", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(7), 15, GFLAGS), + + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + GATE(0, "apll_core", "apll", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(0), 0, GFLAGS), + GATE(0, "vpll0_core", "vpll0", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(0), 0, GFLAGS), + GATE(0, "vpll1_core", "vpll1", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(0), 0, GFLAGS), + COMPOSITE_NOMUX(0, "pclk_core_dbg", "armclk", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(0), 8, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3308_CLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NOMUX(0, "aclk_core", "armclk", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(0), 12, 3, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3308_CLKGATE_CON(0), 1, GFLAGS), + GATE(0, "clk_jtag", "jtag_clkin", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_MUXTBL(0, "clk_uart0_src", mux_uart_src_p, 0, + RK3308_CLKSEL_CON(10), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 9, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart0_frac", "clk_uart0_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(12), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3308_CLKGATE_CON(1), 11, GFLAGS, + &rk3308_uart0_fracmux), + COMPOSITE_MUXTBL(0, "clk_uart1_src", mux_uart_src_p, 0, + RK3308_CLKSEL_CON(13), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(1), 13, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart1_frac", "clk_uart1_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(15), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3308_CLKGATE_CON(1), 15, GFLAGS, + &rk3308_uart1_fracmux), + COMPOSITE_MUXTBL(0, "clk_uart2_src", mux_uart_src_p, 0, + RK3308_CLKSEL_CON(16), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(2), 1, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart2_frac", "clk_uart2_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(18), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3308_CLKGATE_CON(2), 3, GFLAGS, + &rk3308_uart2_fracmux), + COMPOSITE_MUXTBL(0, "clk_uart3_src", mux_uart_src_p, 0, + RK3308_CLKSEL_CON(19), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart3_frac", "clk_uart3_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(21), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3308_CLKGATE_CON(2), 7, GFLAGS, + &rk3308_uart3_fracmux), + COMPOSITE_MUXTBL(0, "clk_uart4_src", mux_uart_src_p, 0, + RK3308_CLKSEL_CON(22), 13, 3, MFLAGS, uart_src_mux_idx, 0, 5, DFLAGS, + RK3308_CLKGATE_CON(2), 9, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_uart4_frac", "clk_uart4_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(24), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3308_CLKGATE_CON(2), 11, GFLAGS, + &rk3308_uart4_fracmux), + COMPOSITE(0, "dclk_vop_src", mux_dpll_vpll0_vpll1_p, 0, + RK3308_CLKSEL_CON(8), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3308_CLKGATE_CON(1), 6, GFLAGS), + COMPOSITE_FRACMUX(0, "dclk_vop_frac", "dclk_vop_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(9), 0, + RK3308_CLKGATE_CON(1), 7, GFLAGS, + &rk3308_dclk_vop_fracmux), + + &rk3308_uart0_fracmux.cell, + &rk3308_uart1_fracmux.cell, + &rk3308_uart2_fracmux.cell, + &rk3308_uart3_fracmux.cell, + &rk3308_uart4_fracmux.cell, + &rk3308_dclk_vop_fracmux.cell, + &rk3308_pdm_fracmux.cell, + &rk3308_i2s0_2ch_fracmux.cell, + &rk3308_i2s1_2ch_fracmux.cell, + &rk3308_spdif_tx_fracmux.cell, + &rk3308_spdif_rx_fracmux.cell, + + FACTOR(0, "clk_mac_rx_tx_div2", "clk_mac_rx_tx", 0, 1, 2), + FACTOR(0, "clk_mac_rx_tx_div20", "clk_mac_rx_tx", 0, 1, 20), + GATE(0, "clk_ddr_mon_timer", "xin24m", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(0), 12, GFLAGS), + GATE(0, "clk_ddr_mon", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 10, GFLAGS), + GATE(0, "clk_ddr_upctrl", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 11, GFLAGS), + GATE(0, "clk_ddr_msch", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 12, GFLAGS), + GATE(0, "clk_ddr_msch_peribus", "clk_ddrphy1x_out", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKGATE_CON(4), 13, GFLAGS), + GATE(0, "clk_ddrphy4x", "clk_ddrphy4x_src", RT_CLK_F_IS_CRITICAL, + RK3308_CLKGATE_CON(0), 11, GFLAGS), + FACTOR_GATE(0, "clk_ddr_stdby_div4", "clk_ddrphy4x", RT_CLK_F_IGNORE_UNUSED, 1, 4, + RK3308_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_NODIV(0, "clk_ddrstdby", mux_ddrstdby_p, RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(1), 8, 1, MFLAGS, + RK3308_CLKGATE_CON(4), 14, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_rtc32k_frac", "xin24m", RT_CLK_F_IGNORE_UNUSED, + RK3308_CLKSEL_CON(3), 0, + RK3308_CLKGATE_CON(4), 3, GFLAGS, + &rk3308_rtc32k_fracmux), + MUX(0, "clk_rtc32k_div_src", mux_vpll0_vpll1_p, 0, + RK3308_CLKSEL_CON(2), 10, 1, MFLAGS), + COMPOSITE_NOMUX(0, "clk_rtc32k_div", "clk_rtc32k_div_src", RT_CLK_F_IGNORE_UNUSED | RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(4), 0, 16, DFLAGS, + RK3308_CLKGATE_CON(4), 2, GFLAGS), + COMPOSITE(0, "clk_usbphy_ref_src", mux_dpll_vpll0_p, 0, + RK3308_CLKSEL_CON(72), 6, 1, MFLAGS, 0, 6, DFLAGS, + RK3308_CLKGATE_CON(4), 7, GFLAGS), + GATE(0, "clk_wifi_dpll", "dpll", 0, + RK3308_CLKGATE_CON(15), 2, GFLAGS), + GATE(0, "clk_wifi_vpll0", "vpll0", 0, + RK3308_CLKGATE_CON(15), 3, GFLAGS), + GATE(0, "clk_wifi_osc", "xin24m", 0, + RK3308_CLKGATE_CON(15), 4, GFLAGS), + COMPOSITE(0, "clk_wifi_src", mux_wifi_src_p, 0, + RK3308_CLKSEL_CON(44), 6, 1, MFLAGS, 0, 6, DFLAGS, + RK3308_CLKGATE_CON(4), 0, GFLAGS), + COMPOSITE_NODIV(0, "clk_audio_src", mux_vpll0_vpll1_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3308_CLKSEL_CON(45), 6, 2, MFLAGS, + RK3308_CLKGATE_CON(10), 0, GFLAGS), + COMPOSITE(0, "clk_pdm_src", mux_vpll0_vpll1_xin24m_p, 0, + RK3308_CLKSEL_CON(46), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3308_CLKGATE_CON(10), 3, GFLAGS), + COMPOSITE_FRACMUX(0, "clk_pdm_frac", "clk_pdm_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(47), 0, + RK3308_CLKGATE_CON(10), 4, GFLAGS, + &rk3308_pdm_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(53), 0, + RK3308_CLKGATE_CON(10), 13, GFLAGS, + &rk3308_i2s0_8ch_tx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(55), 0, + RK3308_CLKGATE_CON(11), 1, GFLAGS, + &rk3308_i2s0_8ch_rx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(57), 0, + RK3308_CLKGATE_CON(11), 5, GFLAGS, + &rk3308_i2s1_8ch_tx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(59), 0, + RK3308_CLKGATE_CON(11), 9, GFLAGS, + &rk3308_i2s1_8ch_rx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s2_8ch_tx_frac", "clk_i2s2_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(61), 0, + RK3308_CLKGATE_CON(11), 13, GFLAGS, + &rk3308_i2s2_8ch_tx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s2_8ch_rx_frac", "clk_i2s2_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(63), 0, + RK3308_CLKGATE_CON(12), 1, GFLAGS, + &rk3308_i2s2_8ch_rx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s3_8ch_tx_frac", "clk_i2s3_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(65), 0, + RK3308_CLKGATE_CON(12), 5, GFLAGS, + &rk3308_i2s3_8ch_tx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s3_8ch_rx_frac", "clk_i2s3_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(67), 0, + RK3308_CLKGATE_CON(12), 9, GFLAGS, + &rk3308_i2s3_8ch_rx_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s0_2ch_frac", "clk_i2s0_2ch_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(69), 0, + RK3308_CLKGATE_CON(12), 13, GFLAGS, + &rk3308_i2s0_2ch_fracmux), + COMPOSITE_FRACMUX(0, "clk_i2s1_2ch_frac", "clk_i2s1_2ch_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(71), 0, + RK3308_CLKGATE_CON(13), 1, GFLAGS, + &rk3308_i2s1_2ch_fracmux), + MUX(0, "clk_spdif_tx_src", mux_spdif_tx_src_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(48), 12, 1, MFLAGS), + COMPOSITE_FRACMUX(0, "clk_spdif_tx_frac", "clk_spdif_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(49), 0, + RK3308_CLKGATE_CON(10), 7, GFLAGS, + &rk3308_spdif_tx_fracmux), + MUX(0, "clk_spdif_rx_src", mux_spdif_rx_src_p, RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(50), 14, 1, MFLAGS), + COMPOSITE_FRACMUX(0, "clk_spdif_rx_frac", "clk_spdif_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(51), 0, + RK3308_CLKGATE_CON(10), 10, GFLAGS, + &rk3308_spdif_rx_fracmux), + GATE(0, "aclk_core_niu", "aclk_core", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 5, GFLAGS), + GATE(0, "pclk_core_dbg_niu", "aclk_core", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 6, GFLAGS), + GATE(0, "pclk_core_dbg_daplite", "pclk_core_dbg", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 7, GFLAGS), + GATE(0, "aclk_core_perf", "pclk_core_dbg", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 8, GFLAGS), + GATE(0, "pclk_core_grf", "pclk_core_dbg", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(0), 9, GFLAGS), + GATE(0, "aclk_peri_niu", "aclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 2, GFLAGS), + GATE(0, "aclk_peribus_niu", "aclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 3, GFLAGS), + GATE(0, "hclk_peri_niu", "hclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 5, GFLAGS), + GATE(0, "pclk_peri_niu", "pclk_peri", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(9), 14, GFLAGS), + GATE(0, "hclk_audio_niu", "hclk_audio", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(14), 0, GFLAGS), + GATE(0, "pclk_audio_niu", "pclk_audio", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(14), 11, GFLAGS), + GATE(0, "aclk_bus_niu", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 0, GFLAGS), + GATE(0, "aclk_intmem", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 1, GFLAGS), + GATE(0, "hclk_bus_niu", "hclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 5, GFLAGS), + GATE(0, "hclk_rom", "hclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 6, GFLAGS), + GATE(0, "pclk_bus_niu", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3308_CLKGATE_CON(5), 9, GFLAGS), + COMPOSITE_FRACMUX(0, "dclk_vop_frac", "dclk_vop_src", RT_CLK_F_SET_RATE_PARENT, + RK3308_CLKSEL_CON(9), 0, + RK3308_CLKGATE_CON(1), 7, GFLAGS, + &rk3308_dclk_vop_fracmux), +}; + +static rt_err_t clk_rk3308_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + struct clk_rk3308_cru *cru = rt_calloc(1, sizeof(*cru)); + + if (!cru) + { + return -RT_ENOMEM; + } + + cru->provider.reg_base = rt_dm_dev_iomap(dev, 0); + + if (!cru->provider.reg_base) + { + err = -RT_EIO; + goto _fail; + } + + cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf"); + cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf"); + + cru->clk_parent.dev = dev; + cru->clk_parent.cells = rk3308_clk_cells; + cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3308_clk_cells); + + rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rt_clk_register(&cru->clk_parent))) + { + goto _fail; + } + + rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL, + cru->provider.reg_base + RK3308_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK))) + { + goto _clk_unregister; + } + + rockchip_register_restart_notifier(&cru->provider, RK3308_GLB_SRST_FST, RT_NULL); + + return RT_EOK; + +_clk_unregister: + rt_clk_unregister(&cru->clk_parent); + +_fail: + if (cru->provider.reg_base) + { + rt_iounmap(cru->provider.reg_base); + } + + rt_free(cru); + + return err; +} + +static const struct rt_ofw_node_id clk_rk3308_ofw_ids[] = +{ + { .compatible = "rockchip,rk3308-cru", }, + { /* sentinel */ } +}; + +static struct rt_platform_driver clk_rk3308_driver = +{ + .name = "clk-rk3308", + .ids = clk_rk3308_ofw_ids, + + .probe = clk_rk3308_probe, +}; + +static int clk_rk3308_register(void) +{ + rt_platform_driver_register(&clk_rk3308_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(clk_rk3308_register); diff --git a/bsp/rockchip/dm/clk/clk-rk3568.c b/bsp/rockchip/dm/clk/clk-rk3568.c new file mode 100755 index 00000000000..90ca38fe5c1 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk3568.c @@ -0,0 +1,1488 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-composite.h" +#include "clk-rk-cpu.h" +#include "clk-rk-divider.h" +#include "clk-rk-factor.h" +#include "clk-rk-fraction-divider.h" +#include "clk-rk-gate.h" +#include "clk-rk.h" +#include "clk-rk-half-divider.h" +#include "clk-rk-mmc-phase.h" +#include "clk-rk-muxgrf.h" +#include "clk-rk-mux.h" +#include "clk-rk-pll.h" + +#define DBG_TAG "clk.rk3568" +#define DBG_LVL DBG_INFO +#include + +#include + +#define RK3568_PLL_CON(x) ((x) * 0x4) +#define RK3568_MODE_CON0 0xc0 +#define RK3568_MISC_CON0 0xc4 +#define RK3568_MISC_CON1 0xc8 +#define RK3568_MISC_CON2 0xcc +#define RK3568_GLB_CNT_TH 0xd0 +#define RK3568_GLB_SRST_FST 0xd4 +#define RK3568_GLB_SRST_SND 0xd8 +#define RK3568_GLB_RST_CON 0xdc +#define RK3568_GLB_RST_ST 0xe0 +#define RK3568_CLKSEL_CON(x) ((x) * 0x4 + 0x100) +#define RK3568_CLKGATE_CON(x) ((x) * 0x4 + 0x300) +#define RK3568_SOFTRST_CON(x) ((x) * 0x4 + 0x400) +#define RK3568_SDMMC0_CON0 0x580 +#define RK3568_SDMMC0_CON1 0x584 +#define RK3568_SDMMC1_CON0 0x588 +#define RK3568_SDMMC1_CON1 0x58c +#define RK3568_SDMMC2_CON0 0x590 +#define RK3568_SDMMC2_CON1 0x594 +#define RK3568_EMMC_CON0 0x598 +#define RK3568_EMMC_CON1 0x59c + +#define RK3568_PMU_PLL_CON(x) ((x) * 0x4) +#define RK3568_PMU_MODE_CON0 0x80 +#define RK3568_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x100) +#define RK3568_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x180) +#define RK3568_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x200) + +#define RK3568_GRF_SOC_CON1 0x504 +#define RK3568_GRF_SOC_CON2 0x508 +#define RK3568_GRF_SOC_STATUS0 0x580 +#define RK3568_PMU_GRF_SOC_CON0 0x100 + +#define RK3568_FRAC_MAX_PRATE 1000000000 +#define RK3568_SPDIF_FRAC_MAX_PRATE 600000000 +#define RK3568_UART_FRAC_MAX_PRATE 600000000 +#define RK3568_DCLK_PARENT_MAX_PRATE 600000000 + +#define RK3568_DIV_ATCLK_CORE_MASK 0x1f +#define RK3568_DIV_ATCLK_CORE_SHIFT 0 +#define RK3568_DIV_GICCLK_CORE_MASK 0x1f +#define RK3568_DIV_GICCLK_CORE_SHIFT 8 +#define RK3568_DIV_PCLK_CORE_MASK 0x1f +#define RK3568_DIV_PCLK_CORE_SHIFT 0 +#define RK3568_DIV_PERIPHCLK_CORE_MASK 0x1f +#define RK3568_DIV_PERIPHCLK_CORE_SHIFT 8 +#define RK3568_DIV_ACLK_CORE_MASK 0x1f +#define RK3568_DIV_ACLK_CORE_SHIFT 8 + +#define RK3568_DIV_SCLK_CORE_MASK 0xf +#define RK3568_DIV_SCLK_CORE_SHIFT 0 +#define RK3568_MUX_SCLK_CORE_MASK 0x3 +#define RK3568_MUX_SCLK_CORE_SHIFT 8 +#define RK3568_MUX_SCLK_CORE_NPLL_MASK 0x1 +#define RK3568_MUX_SCLK_CORE_NPLL_SHIFT 15 +#define RK3568_MUX_CLK_CORE_APLL_MASK 0x1 +#define RK3568_MUX_CLK_CORE_APLL_SHIFT 7 +#define RK3568_MUX_CLK_PVTPLL_MASK 0x1 +#define RK3568_MUX_CLK_PVTPLL_SHIFT 15 + +struct clk_rk3568_cru +{ + struct rt_clk_node clk_parent; + struct rt_reset_controller rstc_parent; + + struct rockchip_clk_provider provider; +}; + +static struct rockchip_pll_rate_table rk3568_pll_rates[] = +{ + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + RK3036_PLL_RATE(2208000000, 1, 92, 1, 1, 1, 0), + RK3036_PLL_RATE(2184000000, 1, 91, 1, 1, 1, 0), + RK3036_PLL_RATE(2160000000, 1, 90, 1, 1, 1, 0), + RK3036_PLL_RATE(2088000000, 1, 87, 1, 1, 1, 0), + RK3036_PLL_RATE(2064000000, 1, 86, 1, 1, 1, 0), + RK3036_PLL_RATE(2040000000, 1, 85, 1, 1, 1, 0), + RK3036_PLL_RATE(2016000000, 1, 84, 1, 1, 1, 0), + RK3036_PLL_RATE(1992000000, 1, 83, 1, 1, 1, 0), + RK3036_PLL_RATE(1920000000, 1, 80, 1, 1, 1, 0), + RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0), + RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0), + RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0), + RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0), + RK3036_PLL_RATE(1600000000, 3, 200, 1, 1, 1, 0), + RK3036_PLL_RATE(1584000000, 1, 132, 2, 1, 1, 0), + RK3036_PLL_RATE(1560000000, 1, 130, 2, 1, 1, 0), + RK3036_PLL_RATE(1536000000, 1, 128, 2, 1, 1, 0), + RK3036_PLL_RATE(1512000000, 1, 126, 2, 1, 1, 0), + RK3036_PLL_RATE(1488000000, 1, 124, 2, 1, 1, 0), + RK3036_PLL_RATE(1464000000, 1, 122, 2, 1, 1, 0), + RK3036_PLL_RATE(1440000000, 1, 120, 2, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 118, 2, 1, 1, 0), + RK3036_PLL_RATE(1400000000, 3, 350, 2, 1, 1, 0), + RK3036_PLL_RATE(1392000000, 1, 116, 2, 1, 1, 0), + RK3036_PLL_RATE(1368000000, 1, 114, 2, 1, 1, 0), + RK3036_PLL_RATE(1344000000, 1, 112, 2, 1, 1, 0), + RK3036_PLL_RATE(1320000000, 1, 110, 2, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 108, 2, 1, 1, 0), + RK3036_PLL_RATE(1272000000, 1, 106, 2, 1, 1, 0), + RK3036_PLL_RATE(1248000000, 1, 104, 2, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 100, 2, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), + RK3036_PLL_RATE(1104000000, 1, 92, 2, 1, 1, 0), + RK3036_PLL_RATE(1100000000, 3, 275, 2, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 3, 250, 2, 1, 1, 0), + RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0), + RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0), + RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0), + RK3036_PLL_RATE(700000000, 3, 350, 4, 1, 1, 0), + RK3036_PLL_RATE(696000000, 1, 116, 4, 1, 1, 0), + RK3036_PLL_RATE(600000000, 1, 100, 4, 1, 1, 0), + RK3036_PLL_RATE(594000000, 1, 99, 4, 1, 1, 0), + RK3036_PLL_RATE(500000000, 1, 125, 6, 1, 1, 0), + RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0), + RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0), + RK3036_PLL_RATE(297000000, 1, 99, 4, 2, 1, 0), + RK3036_PLL_RATE(292500000, 1, 195, 4, 4, 1, 0), + RK3036_PLL_RATE(241500000, 1, 161, 4, 4, 1, 0), + RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0), + RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0), + RK3036_PLL_RATE(135000000, 1, 45, 4, 2, 1, 0), + RK3036_PLL_RATE(119000000, 3, 119, 4, 2, 1, 0), + RK3036_PLL_RATE(108000000, 1, 45, 5, 2, 1, 0), + RK3036_PLL_RATE(101000000, 1, 101, 6, 4, 1, 0), + RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0), + RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0), + RK3036_PLL_RATE(78750000, 4, 315, 6, 4, 1, 0), + RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0), + { /* sentinel */ }, +}; + +#define RK3568_CLKSEL1(_sclk_core) \ +{ \ + .reg = RK3568_CLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_NPLL_MASK, \ + RK3568_MUX_SCLK_CORE_NPLL_SHIFT) | \ + HIWORD_UPDATE(_sclk_core, RK3568_MUX_SCLK_CORE_MASK, \ + RK3568_MUX_SCLK_CORE_SHIFT) | \ + HIWORD_UPDATE(1, RK3568_DIV_SCLK_CORE_MASK, \ + RK3568_DIV_SCLK_CORE_SHIFT), \ +} + +#define RK3568_CLKSEL2(_aclk_core) \ +{ \ + .reg = RK3568_CLKSEL_CON(5), \ + .val = HIWORD_UPDATE(_aclk_core, RK3568_DIV_ACLK_CORE_MASK, \ + RK3568_DIV_ACLK_CORE_SHIFT), \ +} + +#define RK3568_CLKSEL3(_atclk_core, _gic_core) \ +{ \ + .reg = RK3568_CLKSEL_CON(3), \ + .val = HIWORD_UPDATE(_atclk_core, RK3568_DIV_ATCLK_CORE_MASK, \ + RK3568_DIV_ATCLK_CORE_SHIFT) | \ + HIWORD_UPDATE(_gic_core, RK3568_DIV_GICCLK_CORE_MASK, \ + RK3568_DIV_GICCLK_CORE_SHIFT), \ +} + +#define RK3568_CLKSEL4(_pclk_core, _periph_core) \ +{ \ + .reg = RK3568_CLKSEL_CON(4), \ + .val = HIWORD_UPDATE(_pclk_core, RK3568_DIV_PCLK_CORE_MASK, \ + RK3568_DIV_PCLK_CORE_SHIFT) | \ + HIWORD_UPDATE(_periph_core, RK3568_DIV_PERIPHCLK_CORE_MASK, \ + RK3568_DIV_PERIPHCLK_CORE_SHIFT), \ +} + +#define RK3568_CPUCLK_RATE(_prate, _sclk, _acore, _atcore, _gicclk, _pclk, _periph) \ +{ \ + .prate = _prate##U, \ + .divs = \ + { \ + RK3568_CLKSEL1(_sclk), \ + RK3568_CLKSEL2(_acore), \ + RK3568_CLKSEL3(_atcore, _gicclk), \ + RK3568_CLKSEL4(_pclk, _periph), \ + }, \ +} + +static struct rockchip_cpu_clk_rate_table rk3568_cpu_clk_rates[] = +{ + RK3568_CPUCLK_RATE(1800000000, 0, 1, 7, 7, 7, 7), + RK3568_CPUCLK_RATE(1704000000, 0, 1, 7, 7, 7, 7), + RK3568_CPUCLK_RATE(1608000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1584000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1560000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1536000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1512000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1488000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1464000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1440000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1416000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1392000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1368000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1344000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1320000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1296000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1272000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1248000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1224000000, 0, 1, 5, 5, 5, 5), + RK3568_CPUCLK_RATE(1200000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(1104000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(1008000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(912000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(816000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(696000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(600000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(408000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(312000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(216000000, 0, 1, 3, 3, 3, 3), + RK3568_CPUCLK_RATE(96000000, 0, 1, 3, 3, 3, 3), +}; + +static const struct rockchip_cpu_clk_reg_data rk3568_cpu_clk_data = +{ + .core_reg[0] = RK3568_CLKSEL_CON(0), + .div_core_shift[0] = 0, + .div_core_mask[0] = 0x1f, + .core_reg[1] = RK3568_CLKSEL_CON(0), + .div_core_shift[1] = 8, + .div_core_mask[1] = 0x1f, + .core_reg[2] = RK3568_CLKSEL_CON(1), + .div_core_shift[2] = 0, + .div_core_mask[2] = 0x1f, + .core_reg[3] = RK3568_CLKSEL_CON(1), + .div_core_shift[3] = 8, + .div_core_mask[3] = 0x1f, + .num_cores = 4, + .mux_core_alt = 1, + .mux_core_main = 0, + .mux_core_shift = 6, + .mux_core_mask = 0x1, +}; + +PNAME(mux_pll_p) = "xin24m"; +PNAMES(mux_usb480m_p) = { "xin24m", "usb480m_phy", "clk_rtc_32k" }; +PNAMES(clk_i2s0_8ch_tx_p) = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin_osc0_half" }; +PNAMES(clk_i2s0_8ch_rx_p) = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin_osc0_half" }; +PNAMES(clk_i2s1_8ch_tx_p) = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "i2s1_mclkin", "xin_osc0_half" }; +PNAMES(clk_i2s1_8ch_rx_p) = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "i2s1_mclkin", "xin_osc0_half" }; +PNAMES(clk_i2s2_2ch_p) = { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "i2s2_mclkin", "xin_osc0_half "}; +PNAMES(clk_i2s3_2ch_tx_p) = { "clk_i2s3_2ch_tx_src", "clk_i2s3_2ch_tx_frac", "i2s3_mclkin", "xin_osc0_half" }; +PNAMES(clk_i2s3_2ch_rx_p) = { "clk_i2s3_2ch_rx_src", "clk_i2s3_2ch_rx_frac", "i2s3_mclkin", "xin_osc0_half" }; +PNAMES(mclk_spdif_8ch_p) = { "mclk_spdif_8ch_src", "mclk_spdif_8ch_frac" }; +PNAMES(sclk_audpwm_p) = { "sclk_audpwm_src", "sclk_audpwm_frac" }; +PNAMES(sclk_uart1_p) = { "clk_uart1_src", "clk_uart1_frac", "xin24m" }; +PNAMES(sclk_uart2_p) = { "clk_uart2_src", "clk_uart2_frac", "xin24m" }; +PNAMES(sclk_uart3_p) = { "clk_uart3_src", "clk_uart3_frac", "xin24m" }; +PNAMES(sclk_uart4_p) = { "clk_uart4_src", "clk_uart4_frac", "xin24m" }; +PNAMES(sclk_uart5_p) = { "clk_uart5_src", "clk_uart5_frac", "xin24m" }; +PNAMES(sclk_uart6_p) = { "clk_uart6_src", "clk_uart6_frac", "xin24m" }; +PNAMES(sclk_uart7_p) = { "clk_uart7_src", "clk_uart7_frac", "xin24m" }; +PNAMES(sclk_uart8_p) = { "clk_uart8_src", "clk_uart8_frac", "xin24m" }; +PNAMES(sclk_uart9_p) = { "clk_uart9_src", "clk_uart9_frac", "xin24m" }; +PNAMES(sclk_uart0_p) = { "sclk_uart0_div", "sclk_uart0_frac", "xin24m" }; +PNAMES(clk_rtc32k_pmu_p) = { "clk_32k_pvtm", "xin32k", "clk_rtc32k_frac" }; +PNAMES(mpll_gpll_cpll_npll_p) = { "mpll", "gpll", "cpll", "npll" }; +PNAMES(gpll_cpll_npll_p) = { "gpll", "cpll", "npll" }; +PNAMES(npll_gpll_p) = { "npll", "gpll" }; +PNAMES(cpll_gpll_p) = { "cpll", "gpll" }; +PNAMES(gpll_cpll_p) = { "gpll", "cpll" }; +PNAMES(gpll_cpll_npll_vpll_p) = { "gpll", "cpll", "npll", "vpll" }; +PNAMES(apll_gpll_npll_p) = { "apll", "gpll", "npll" }; +PNAMES(sclk_core_pre_p) = { "sclk_core_src", "npll" }; +PNAMES(gpll150_gpll100_gpll75_xin24m_p) = { "gpll_150m", "gpll_100m", "gpll_75m", "xin24m" }; +PNAMES(clk_gpu_pre_mux_p) = { "clk_gpu_src", "gpu_pvtpll_out" }; +PNAMES(clk_npu_pre_ndft_p) = { "clk_npu_src", "clk_npu_np5"}; +PNAMES(clk_npu_p) = { "clk_npu_pre_ndft", "npu_pvtpll_out" }; +PNAMES(dpll_gpll_cpll_p) = { "dpll", "gpll", "cpll" }; +PNAMES(clk_ddr1x_p) = { "clk_ddrphy1x_src", "dpll" }; +PNAMES(gpll200_gpll150_gpll100_xin24m_p) = { "gpll_200m", "gpll_150m", "gpll_100m", "xin24m" }; +PNAMES(gpll100_gpll75_gpll50_p) = { "gpll_100m", "gpll_75m", "cpll_50m" }; +PNAMES(i2s0_mclkout_tx_p) = { "mclk_i2s0_8ch_tx", "xin_osc0_half" }; +PNAMES(i2s0_mclkout_rx_p) = { "mclk_i2s0_8ch_rx", "xin_osc0_half" }; +PNAMES(i2s1_mclkout_tx_p) = { "mclk_i2s1_8ch_tx", "xin_osc0_half" }; +PNAMES(i2s1_mclkout_rx_p) = { "mclk_i2s1_8ch_rx", "xin_osc0_half" }; +PNAMES(i2s2_mclkout_p) = { "mclk_i2s2_2ch", "xin_osc0_half" }; +PNAMES(i2s3_mclkout_tx_p) = { "mclk_i2s3_2ch_tx", "xin_osc0_half" }; +PNAMES(i2s3_mclkout_rx_p) = { "mclk_i2s3_2ch_rx", "xin_osc0_half" }; +PNAMES(mclk_pdm_p) = { "gpll_300m", "cpll_250m", "gpll_200m", "gpll_100m" }; +PNAMES(clk_i2c_p) = { "gpll_200m", "gpll_100m", "xin24m", "cpll_100m" }; +PNAMES(gpll200_gpll150_gpll100_p) = { "gpll_200m", "gpll_150m", "gpll_100m" }; +PNAMES(gpll300_gpll200_gpll100_p) = { "gpll_300m", "gpll_200m", "gpll_100m" }; +PNAMES(clk_nandc_p) = { "gpll_200m", "gpll_150m", "cpll_100m", "xin24m" }; +PNAMES(sclk_sfc_p) = { "xin24m", "cpll_50m", "gpll_75m", "gpll_100m", "cpll_125m", "gpll_150m" }; +PNAMES(gpll200_gpll150_cpll125_p) = { "gpll_200m", "gpll_150m", "cpll_125m" }; +PNAMES(cclk_emmc_p) = { "xin24m", "gpll_200m", "gpll_150m", "cpll_100m", "cpll_50m", "clk_osc0_div_375k" }; +PNAMES(aclk_pipe_p) = { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" }; +PNAMES(gpll200_cpll125_p) = { "gpll_200m", "cpll_125m" }; +PNAMES(gpll300_gpll200_gpll100_xin24m_p) = { "gpll_300m", "gpll_200m", "gpll_100m", "xin24m" }; +PNAMES(clk_sdmmc_p) = { "xin24m", "gpll_400m", "gpll_300m", "cpll_100m", "cpll_50m", "clk_osc0_div_750k" }; +PNAMES(cpll125_cpll50_cpll25_xin24m_p) = { "cpll_125m", "cpll_50m", "cpll_25m", "xin24m" }; +PNAMES(clk_gmac_ptp_p) = { "cpll_62p5", "gpll_100m", "cpll_50m", "xin24m" }; +PNAMES(cpll333_gpll300_gpll200_p) = { "cpll_333m", "gpll_300m", "gpll_200m" }; +PNAMES(cpll_gpll_hpll_p) = { "cpll", "gpll", "hpll" }; +PNAMES(gpll_usb480m_xin24m_p) = { "gpll", "usb480m", "xin24m", "xin24m" }; +PNAMES(gpll300_cpll250_gpll100_xin24m_p) = { "gpll_300m", "cpll_250m", "gpll_100m", "xin24m" }; +PNAMES(cpll_gpll_hpll_vpll_p) = { "cpll", "gpll", "hpll", "vpll" }; +PNAMES(hpll_vpll_gpll_cpll_p) = { "hpll", "vpll", "gpll", "cpll" }; +PNAMES(gpll400_cpll333_gpll200_p) = { "gpll_400m", "cpll_333m", "gpll_200m" }; +PNAMES(gpll100_gpll75_cpll50_xin24m_p) = { "gpll_100m", "gpll_75m", "cpll_50m", "xin24m" }; +PNAMES(xin24m_gpll100_cpll100_p) = { "xin24m", "gpll_100m", "cpll_100m" }; +PNAMES(gpll_cpll_usb480m_p) = { "gpll", "cpll", "usb480m" }; +PNAMES(gpll100_xin24m_cpll100_p) = { "gpll_100m", "xin24m", "cpll_100m" }; +PNAMES(gpll200_xin24m_cpll100_p) = { "gpll_200m", "xin24m", "cpll_100m" }; +PNAMES(xin24m_32k_p) = { "xin24m", "clk_rtc_32k" }; +PNAMES(cpll500_gpll400_gpll300_xin24m_p) = { "cpll_500m", "gpll_400m", "gpll_300m", "xin24m" }; +PNAMES(gpll400_gpll300_gpll200_xin24m_p) = { "gpll_400m", "gpll_300m", "gpll_200m", "xin24m" }; +PNAMES(xin24m_cpll100_p) = { "xin24m", "cpll_100m" }; +PNAMES(ppll_usb480m_cpll_gpll_p) = { "ppll", "usb480m", "cpll", "gpll"}; +PNAMES(clk_usbphy0_ref_p) = { "clk_ref24m", "xin_osc0_usbphy0_g" }; +PNAMES(clk_usbphy1_ref_p) = { "clk_ref24m", "xin_osc0_usbphy1_g" }; +PNAMES(clk_mipidsiphy0_ref_p) = { "clk_ref24m", "xin_osc0_mipidsiphy0_g" }; +PNAMES(clk_mipidsiphy1_ref_p) = { "clk_ref24m", "xin_osc0_mipidsiphy1_g" }; +PNAMES(clk_wifi_p) = { "clk_wifi_osc0", "clk_wifi_div" }; +PNAMES(clk_pciephy0_ref_p) = { "clk_pciephy0_osc0", "clk_pciephy0_div" }; +PNAMES(clk_pciephy1_ref_p) = { "clk_pciephy1_osc0", "clk_pciephy1_div" }; +PNAMES(clk_pciephy2_ref_p) = { "clk_pciephy2_osc0", "clk_pciephy2_div" }; +PNAMES(mux_gmac0_p) = { "clk_mac0_2top", "gmac0_clkin" }; +PNAMES(mux_gmac0_rgmii_speed_p) = { "clk_gmac0", "clk_gmac0", "clk_gmac0_tx_div50", "clk_gmac0_tx_div5" }; +PNAMES(mux_gmac0_rmii_speed_p) = { "clk_gmac0_rx_div20", "clk_gmac0_rx_div2" }; +PNAMES(mux_gmac0_rx_tx_p) = { "clk_gmac0_rgmii_speed", "clk_gmac0_rmii_speed", "clk_gmac0_xpcs_mii" }; +PNAMES(mux_gmac1_p) = { "clk_mac1_2top", "gmac1_clkin" }; +PNAMES(mux_gmac1_rgmii_speed_p) = { "clk_gmac1", "clk_gmac1", "clk_gmac1_tx_div50", "clk_gmac1_tx_div5" }; +PNAMES(mux_gmac1_rmii_speed_p) = { "clk_gmac1_rx_div20", "clk_gmac1_rx_div2" }; +PNAMES(mux_gmac1_rx_tx_p) = { "clk_gmac1_rgmii_speed", "clk_gmac1_rmii_speed", "clk_gmac1_xpcs_mii" }; +PNAMES(clk_hdmi_ref_p) = { "hpll", "hpll_ph0" }; +PNAMES(clk_pdpmu_p) = { "ppll", "gpll" }; +PNAMES(clk_mac_2top_p) = { "cpll_125m", "cpll_50m", "cpll_25m", "ppll" }; +PNAMES(clk_pwm0_p) = { "xin24m", "clk_pdpmu" }; +PNAMES(aclk_rkvdec_pre_p) = { "gpll", "cpll" }; +PNAMES(clk_rkvdec_core_p) = { "gpll", "cpll" }; +PNAMES(clk_32k_ioe_p) = { "clk_rtc_32k", "xin32k" }; +PNAMES(i2s1_mclkout_p) = { "i2s1_mclkout_rx", "i2s1_mclkout_tx" }; +PNAMES(i2s3_mclkout_p) = { "i2s3_mclkout_rx", "i2s3_mclkout_tx" }; +PNAMES(i2s1_mclk_rx_ioe_p) = { "i2s1_mclkin_rx", "i2s1_mclkout_rx" }; +PNAMES(i2s1_mclk_tx_ioe_p) = { "i2s1_mclkin_tx", "i2s1_mclkout_tx" }; +PNAMES(i2s2_mclk_ioe_p) = { "i2s2_mclkin", "i2s2_mclkout" }; +PNAMES(i2s3_mclk_ioe_p) = { "i2s3_mclkin", "i2s3_mclkout" }; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_pll_clk_cell rk3568_pmu_pll_ppll = + PLL_RAW(pll_type_rk3328, PLL_PPLL, "ppll", mux_pll_p, 1, 0, RK3568_PMU_PLL_CON(0), RK3568_PMU_MODE_CON0, + 0, 4, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); +static struct rockchip_pll_clk_cell rk3568_pmu_pll_hpll = + PLL_RAW(pll_type_rk3328, PLL_HPLL, "hpll", mux_pll_p, 1, 0, RK3568_PMU_PLL_CON(16), RK3568_PMU_MODE_CON0, + 2, 7, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); + +static struct rockchip_pll_clk_cell rk3568_pll_apll = + PLL_RAW(pll_type_rk3328, PLL_APLL, "apll", mux_pll_p, 1, 0, RK3568_PLL_CON(0), RK3568_MODE_CON0, + 0, 0, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); +static struct rockchip_pll_clk_cell rk3568_pll_dpll = + PLL_RAW(pll_type_rk3328, PLL_DPLL, "dpll", mux_pll_p, 1, 0, RK3568_PLL_CON(8), RK3568_MODE_CON0, + 2, 1, RK3568_GRF_SOC_STATUS0, 0, RT_NULL); +static struct rockchip_pll_clk_cell rk3568_pll_cpll = + PLL_RAW(pll_type_rk3328, PLL_CPLL, "cpll", mux_pll_p, 1, 0, RK3568_PLL_CON(24), RK3568_MODE_CON0, + 4, 2, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); +static struct rockchip_pll_clk_cell rk3568_pll_gpll = + PLL_RAW(pll_type_rk3328, PLL_GPLL, "gpll", mux_pll_p, 1, 0, RK3568_PLL_CON(16), RK3568_MODE_CON0, + 6, 3, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); +static struct rockchip_pll_clk_cell rk3568_pll_npll = + PLL_RAW(pll_type_rk3328, PLL_NPLL, "npll", mux_pll_p, 1, RT_CLK_F_IS_CRITICAL, RK3568_PLL_CON(32), RK3568_MODE_CON0, + 10, 5, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); +static struct rockchip_pll_clk_cell rk3568_pll_vpll = + PLL_RAW(pll_type_rk3328, PLL_VPLL, "vpll", mux_pll_p, 1, 0, RK3568_PLL_CON(40), RK3568_MODE_CON0, + 12, 6, RK3568_GRF_SOC_STATUS0, 0, rk3568_pll_rates); + +static struct rockchip_clk_cell rk3568_i2s0_8ch_tx_fracmux = + MUX_RAW(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(11), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_i2s0_8ch_rx_fracmux = + MUX_RAW(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(13), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_i2s1_8ch_tx_fracmux = + MUX_RAW(CLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", clk_i2s1_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(15), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_i2s1_8ch_rx_fracmux = + MUX_RAW(CLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", clk_i2s1_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(17), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_i2s2_2ch_fracmux = + MUX_RAW(CLK_I2S2_2CH, "clk_i2s2_2ch", clk_i2s2_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(19), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_i2s3_2ch_tx_fracmux = + MUX_RAW(CLK_I2S3_2CH_TX, "clk_i2s3_2ch_tx", clk_i2s3_2ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(21), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_i2s3_2ch_rx_fracmux = + MUX_RAW(CLK_I2S3_2CH_RX, "clk_i2s3_2ch_rx", clk_i2s3_2ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(83), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_spdif_8ch_fracmux = + MUX_RAW(MCLK_SPDIF_8CH, "mclk_spdif_8ch", mclk_spdif_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(23), 15, 1, MFLAGS); + +static struct rockchip_clk_cell rk3568_audpwm_fracmux = + MUX_RAW(SCLK_AUDPWM, "sclk_audpwm", sclk_audpwm_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(25), 15, 1, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart1_fracmux = + MUX_RAW(0, "sclk_uart1_mux", sclk_uart1_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(52), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart2_fracmux = + MUX_RAW(0, "sclk_uart2_mux", sclk_uart2_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(54), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart3_fracmux = + MUX_RAW(0, "sclk_uart3_mux", sclk_uart3_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(56), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart4_fracmux = + MUX_RAW(0, "sclk_uart4_mux", sclk_uart4_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(58), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart5_fracmux = + MUX_RAW(0, "sclk_uart5_mux", sclk_uart5_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(60), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart6_fracmux = + MUX_RAW(0, "sclk_uart6_mux", sclk_uart6_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(62), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart7_fracmux = + MUX_RAW(0, "sclk_uart7_mux", sclk_uart7_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(64), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart8_fracmux = + MUX_RAW(0, "sclk_uart8_mux", sclk_uart8_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(66), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart9_fracmux = + MUX_RAW(0, "sclk_uart9_mux", sclk_uart9_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(68), 12, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_uart0_fracmux = + MUX_RAW(0, "sclk_uart0_mux", sclk_uart0_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(4), 10, 2, MFLAGS); + +static struct rockchip_clk_cell rk3568_rtc32k_pmu_fracmux = + MUX_RAW(CLK_RTC_32K, "clk_rtc_32k", clk_rtc32k_pmu_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(0), 6, 2, MFLAGS); + +static struct rt_clk_cell *rk3568_clk_pmu_cells[] = +{ + [PLL_PPLL] = &rk3568_pmu_pll_ppll.rk_cell.cell, + [PLL_HPLL] = &rk3568_pmu_pll_hpll.rk_cell.cell, + [XIN_OSC0_DIV] = COMPOSITE_NOMUX(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", RT_CLK_F_IGNORE_UNUSED, + RK3568_PMU_CLKSEL_CON(0), 0, 5, DFLAGS, + RK3568_PMU_CLKGATE_CON(0), 0, GFLAGS), + [CLK_RTC_32K] = &rk3568_rtc32k_pmu_fracmux.cell, + [CLK_PMU] = GATE(CLK_PMU, "clk_pmu", "xin24m", RT_CLK_F_IS_CRITICAL, RK3568_PMU_CLKGATE_CON(0), 7, GFLAGS), + [CLK_I2C0] = COMPOSITE_NOMUX(CLK_I2C0, "clk_i2c0", "clk_pdpmu", 0, + RK3568_PMU_CLKSEL_CON(3), 0, 7, DFLAGS, + RK3568_PMU_CLKGATE_CON(1), 1, GFLAGS), + [CLK_RTC32K_FRAC] = COMPOSITE_FRACMUX(CLK_RTC32K_FRAC, "clk_rtc32k_frac", "xin24m", RT_CLK_F_IGNORE_UNUSED, + RK3568_PMU_CLKSEL_CON(1), 0, + RK3568_PMU_CLKGATE_CON(0), 1, GFLAGS, + &rk3568_rtc32k_pmu_fracmux), + [CLK_UART0_DIV] = COMPOSITE(CLK_UART0_DIV, "sclk_uart0_div", ppll_usb480m_cpll_gpll_p, 0, + RK3568_PMU_CLKSEL_CON(4), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_PMU_CLKGATE_CON(1), 3, GFLAGS), + [CLK_UART0_FRAC] = COMPOSITE_FRACMUX(CLK_UART0_FRAC, "sclk_uart0_frac", "sclk_uart0_div", RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(5), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_PMU_CLKGATE_CON(1), 4, GFLAGS, + &rk3568_uart0_fracmux), + [SCLK_UART0] = GATE(SCLK_UART0, "sclk_uart0", "sclk_uart0_mux", 0, RK3568_PMU_CLKGATE_CON(1), 5, GFLAGS), + [DBCLK_GPIO0] = COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", xin24m_32k_p, 0, + RK3568_PMU_CLKSEL_CON(6), 15, 1, MFLAGS, + RK3568_PMU_CLKGATE_CON(1), 10, GFLAGS), + [CLK_PWM0] = COMPOSITE(CLK_PWM0, "clk_pwm0", clk_pwm0_p, 0, + RK3568_PMU_CLKSEL_CON(6), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3568_PMU_CLKGATE_CON(1), 7, GFLAGS), + [CLK_CAPTURE_PWM0_NDFT] = GATE(CLK_CAPTURE_PWM0_NDFT, "clk_capture_pwm0_ndft", "xin24m", 0, RK3568_PMU_CLKGATE_CON(1), 8, GFLAGS), + [CLK_PMUPVTM] = GATE(CLK_PMUPVTM, "clk_pmupvtm", "xin24m", 0, RK3568_PMU_CLKGATE_CON(1), 12, GFLAGS), + [CLK_CORE_PMUPVTM] = GATE(CLK_CORE_PMUPVTM, "clk_core_pmupvtm", "xin24m", 0, RK3568_PMU_CLKGATE_CON(1), 13, GFLAGS), + [CLK_REF24M] = COMPOSITE_NOMUX(CLK_REF24M, "clk_ref24m", "clk_pdpmu", 0, + RK3568_PMU_CLKSEL_CON(7), 0, 6, DFLAGS, + RK3568_PMU_CLKGATE_CON(2), 0, GFLAGS), + [XIN_OSC0_USBPHY0_G] = GATE(XIN_OSC0_USBPHY0_G, "xin_osc0_usbphy0_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 1, GFLAGS), + [CLK_USBPHY0_REF] = MUX(CLK_USBPHY0_REF, "clk_usbphy0_ref", clk_usbphy0_ref_p, 0, + RK3568_PMU_CLKSEL_CON(8), 0, 1, MFLAGS), + [XIN_OSC0_USBPHY1_G] = GATE(XIN_OSC0_USBPHY1_G, "xin_osc0_usbphy1_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 2, GFLAGS), + [CLK_USBPHY1_REF] = MUX(CLK_USBPHY1_REF, "clk_usbphy1_ref", clk_usbphy1_ref_p, 0, + RK3568_PMU_CLKSEL_CON(8), 1, 1, MFLAGS), + [XIN_OSC0_MIPIDSIPHY0_G] = GATE(XIN_OSC0_MIPIDSIPHY0_G, "xin_osc0_mipidsiphy0_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 3, GFLAGS), + [CLK_MIPIDSIPHY0_REF] = MUX(CLK_MIPIDSIPHY0_REF, "clk_mipidsiphy0_ref", clk_mipidsiphy0_ref_p, 0, + RK3568_PMU_CLKSEL_CON(8), 2, 1, MFLAGS), + [XIN_OSC0_MIPIDSIPHY1_G] = GATE(XIN_OSC0_MIPIDSIPHY1_G, "xin_osc0_mipidsiphy1_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 4, GFLAGS), + [CLK_MIPIDSIPHY1_REF] = MUX(CLK_MIPIDSIPHY1_REF, "clk_mipidsiphy1_ref", clk_mipidsiphy1_ref_p, 0, + RK3568_PMU_CLKSEL_CON(8), 3, 1, MFLAGS), + [CLK_WIFI_DIV] = COMPOSITE_NOMUX(CLK_WIFI_DIV, "clk_wifi_div", "clk_pdpmu", 0, + RK3568_PMU_CLKSEL_CON(8), 8, 6, DFLAGS, + RK3568_PMU_CLKGATE_CON(2), 5, GFLAGS), + [CLK_WIFI_OSC0] = GATE(CLK_WIFI_OSC0, "clk_wifi_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 6, GFLAGS), + [CLK_WIFI] = MUX(CLK_WIFI, "clk_wifi", clk_wifi_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(8), 15, 1, MFLAGS), + [CLK_PCIEPHY0_DIV] = COMPOSITE_NOMUX(CLK_PCIEPHY0_DIV, "clk_pciephy0_div", "ppll_ph0", 0, + RK3568_PMU_CLKSEL_CON(9), 0, 3, DFLAGS, + RK3568_PMU_CLKGATE_CON(2), 7, GFLAGS), + [CLK_PCIEPHY0_OSC0] = GATE(CLK_PCIEPHY0_OSC0, "clk_pciephy0_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 8, GFLAGS), + [CLK_PCIEPHY0_REF] = MUX(CLK_PCIEPHY0_REF, "clk_pciephy0_ref", clk_pciephy0_ref_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(9), 3, 1, MFLAGS), + [CLK_PCIEPHY1_DIV] = COMPOSITE_NOMUX(CLK_PCIEPHY1_DIV, "clk_pciephy1_div", "ppll_ph0", 0, + RK3568_PMU_CLKSEL_CON(9), 4, 3, DFLAGS, + RK3568_PMU_CLKGATE_CON(2), 9, GFLAGS), + [CLK_PCIEPHY1_OSC0] = GATE(CLK_PCIEPHY1_OSC0, "clk_pciephy1_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 10, GFLAGS), + [CLK_PCIEPHY1_REF] = MUX(CLK_PCIEPHY1_REF, "clk_pciephy1_ref", clk_pciephy1_ref_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(9), 7, 1, MFLAGS), + [CLK_PCIEPHY2_DIV] = COMPOSITE_NOMUX(CLK_PCIEPHY2_DIV, "clk_pciephy2_div", "ppll_ph0", 0, + RK3568_PMU_CLKSEL_CON(9), 8, 3, DFLAGS, + RK3568_PMU_CLKGATE_CON(2), 11, GFLAGS), + [CLK_PCIEPHY2_OSC0] = GATE(CLK_PCIEPHY2_OSC0, "clk_pciephy2_osc0", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 12, GFLAGS), + [CLK_PCIEPHY2_REF] = MUX(CLK_PCIEPHY2_REF, "clk_pciephy2_ref", clk_pciephy2_ref_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_PMU_CLKSEL_CON(9), 11, 1, MFLAGS), + [CLK_PCIE30PHY_REF_M] = GATE(CLK_PCIE30PHY_REF_M, "clk_pcie30phy_ref_m", "ppll_ph0", 0, RK3568_PMU_CLKGATE_CON(2), 13, GFLAGS), + [CLK_PCIE30PHY_REF_N] = GATE(CLK_PCIE30PHY_REF_N, "clk_pcie30phy_ref_n", "ppll_ph180", 0, RK3568_PMU_CLKGATE_CON(2), 14, GFLAGS), + [CLK_HDMI_REF] = MUX(CLK_HDMI_REF, "clk_hdmi_ref", clk_hdmi_ref_p, 0, + RK3568_PMU_CLKSEL_CON(8), 7, 1, MFLAGS), + [XIN_OSC0_EDPPHY_G] = GATE(XIN_OSC0_EDPPHY_G, "xin_osc0_edpphy_g", "xin24m", 0, RK3568_PMU_CLKGATE_CON(2), 15, GFLAGS), + [PCLK_PDPMU] = COMPOSITE_NOMUX(PCLK_PDPMU, "pclk_pdpmu", "clk_pdpmu", RT_CLK_F_IS_CRITICAL, + RK3568_PMU_CLKSEL_CON(2), 0, 5, DFLAGS, + RK3568_PMU_CLKGATE_CON(0), 2, GFLAGS), + [PCLK_PMU] = GATE(PCLK_PMU, "pclk_pmu", "pclk_pdpmu", RT_CLK_F_IS_CRITICAL, RK3568_PMU_CLKGATE_CON(0), 6, GFLAGS), + [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 2, GFLAGS), + [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 0, GFLAGS), + [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 9, GFLAGS), + [PCLK_PMUPVTM] = GATE(PCLK_PMUPVTM, "pclk_pmupvtm", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 11, GFLAGS), + [PCLK_PWM0] = GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pdpmu", 0, RK3568_PMU_CLKGATE_CON(1), 6, GFLAGS), + [CLK_PDPMU] = MUX(CLK_PDPMU, "clk_pdpmu", clk_pdpmu_p, 0, + RK3568_PMU_CLKSEL_CON(2), 15, 1, MFLAGS), + [SCLK_32K_IOE] = MUXPMUGRF(SCLK_32K_IOE, "clk_32k_ioe", clk_32k_ioe_p, 0, + RK3568_PMU_GRF_SOC_CON0, 0, 1, MFLAGS), + + &rk3568_uart0_fracmux.cell, + + FACTOR(0, "ppll_ph0", "ppll", 0, 1, 2), + FACTOR(0, "ppll_ph180", "ppll", 0, 1, 2), + FACTOR(0, "hpll_ph0", "hpll", 0, 1, 2), +}; + +static struct rt_clk_cell *rk3568_clk_cells[] = +{ + [PLL_APLL] = &rk3568_pll_apll.rk_cell.cell, + [PLL_DPLL] = &rk3568_pll_dpll.rk_cell.cell, + [PLL_CPLL] = &rk3568_pll_cpll.rk_cell.cell, + [PLL_GPLL] = &rk3568_pll_gpll.rk_cell.cell, + [PLL_VPLL] = &rk3568_pll_npll.rk_cell.cell, + [PLL_NPLL] = &rk3568_pll_vpll.rk_cell.cell, + [CPLL_333M] = COMPOSITE_NOMUX(CPLL_333M, "cpll_333m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(79), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 8, GFLAGS), + [ARMCLK] = CPU(ARMCLK, "armclk", &rk3568_pll_apll.rk_cell, &rk3568_pll_gpll.rk_cell, + rk3568_cpu_clk_rates, RT_ARRAY_SIZE(rk3568_cpu_clk_rates), &rk3568_cpu_clk_data), + [USB480M] = MUX(USB480M, "usb480m", mux_usb480m_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_MODE_CON0, 14, 2, MFLAGS), + [ACLK_CORE_NIU2BUS] = COMPOSITE_NODIV(ACLK_CORE_NIU2BUS, "aclk_core_niu2bus", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(5), 14, 2, MFLAGS, + RK3568_CLKGATE_CON(1), 2, GFLAGS), + [CLK_CORE_PVTM] = GATE(CLK_CORE_PVTM, "clk_core_pvtm", "xin24m", 0, RK3568_CLKGATE_CON(1), 10, GFLAGS), + [CLK_CORE_PVTM_CORE] = GATE(CLK_CORE_PVTM_CORE, "clk_core_pvtm_core", "armclk", 0, RK3568_CLKGATE_CON(1), 11, GFLAGS), + [CLK_CORE_PVTPLL] = GATE(CLK_CORE_PVTPLL, "clk_core_pvtpll", "armclk", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(1), 12, GFLAGS), + [CLK_GPU_SRC] = COMPOSITE(CLK_GPU_SRC, "clk_gpu_src", mpll_gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(6), 6, 2, MFLAGS | CLK_MUX_READ_ONLY, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(2), 0, GFLAGS), + [CLK_GPU_PRE_MUX] = MUX(CLK_GPU_PRE_MUX, "clk_gpu_pre_mux", clk_gpu_pre_mux_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(6), 11, 1, MFLAGS | CLK_MUX_READ_ONLY), + [ACLK_GPU_PRE] = DIV(ACLK_GPU_PRE, "aclk_gpu_pre", "clk_gpu_pre_mux", 0, + RK3568_CLKSEL_CON(6), 8, 2, DFLAGS), + [PCLK_GPU_PRE] = DIV(PCLK_GPU_PRE, "pclk_gpu_pre", "clk_gpu_pre_mux", 0, + RK3568_CLKSEL_CON(6), 12, 4, DFLAGS), + [CLK_GPU] = GATE(CLK_GPU, "clk_gpu", "clk_gpu_pre_mux", 0, RK3568_CLKGATE_CON(2), 3, GFLAGS), + [PCLK_GPU_PVTM] = GATE(PCLK_GPU_PVTM, "pclk_gpu_pvtm", "pclk_gpu_pre", 0, RK3568_CLKGATE_CON(2), 6, GFLAGS), + [CLK_GPU_PVTM] = GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 0, RK3568_CLKGATE_CON(2), 7, GFLAGS), + [CLK_GPU_PVTM_CORE] = GATE(CLK_GPU_PVTM_CORE, "clk_gpu_pvtm_core", "clk_gpu_src", 0, RK3568_CLKGATE_CON(2), 8, GFLAGS), + [CLK_GPU_PVTPLL] = GATE(CLK_GPU_PVTPLL, "clk_gpu_pvtpll", "clk_gpu_src", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(2), 9, GFLAGS), + [CLK_NPU_SRC] = COMPOSITE(CLK_NPU_SRC, "clk_npu_src", npll_gpll_p, 0, + RK3568_CLKSEL_CON(7), 6, 1, MFLAGS, 0, 4, DFLAGS, + RK3568_CLKGATE_CON(3), 0, GFLAGS), + [CLK_NPU_PRE_NDFT] = MUX(CLK_NPU_PRE_NDFT, "clk_npu_pre_ndft", clk_npu_pre_ndft_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(7), 8, 1, MFLAGS), + [CLK_NPU] = MUX(CLK_NPU, "clk_npu", clk_npu_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(7), 15, 1, MFLAGS), + [CLK_NPU_NP5] = COMPOSITE_HALFDIV(CLK_NPU_NP5, "clk_npu_np5", npll_gpll_p, 0, + RK3568_CLKSEL_CON(7), 7, 1, MFLAGS, 4, 2, DFLAGS, + RK3568_CLKGATE_CON(3), 1, GFLAGS), + [HCLK_NPU_PRE] = COMPOSITE_NOMUX(HCLK_NPU_PRE, "hclk_npu_pre", "clk_npu", 0, + RK3568_CLKSEL_CON(8), 0, 4, DFLAGS, + RK3568_CLKGATE_CON(3), 2, GFLAGS), + [PCLK_NPU_PRE] = COMPOSITE_NOMUX(PCLK_NPU_PRE, "pclk_npu_pre", "clk_npu", 0, + RK3568_CLKSEL_CON(8), 4, 4, DFLAGS, + RK3568_CLKGATE_CON(3), 3, GFLAGS), + [ACLK_NPU_PRE] = GATE(ACLK_NPU_PRE, "aclk_npu_pre", "clk_npu", 0, RK3568_CLKGATE_CON(3), 4, GFLAGS), + [ACLK_NPU] = GATE(ACLK_NPU, "aclk_npu", "aclk_npu_pre", 0, RK3568_CLKGATE_CON(3), 7, GFLAGS), + [HCLK_NPU] = GATE(HCLK_NPU, "hclk_npu", "hclk_npu_pre", 0, RK3568_CLKGATE_CON(3), 8, GFLAGS), + [PCLK_NPU_PVTM] = GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_pre", 0, RK3568_CLKGATE_CON(3), 9, GFLAGS), + [CLK_NPU_PVTM] = GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 0, RK3568_CLKGATE_CON(3), 10, GFLAGS), + [CLK_NPU_PVTM_CORE] = GATE(CLK_NPU_PVTM_CORE, "clk_npu_pvtm_core", "clk_npu_pre_ndft", 0, RK3568_CLKGATE_CON(3), 11, GFLAGS), + [CLK_NPU_PVTPLL] = GATE(CLK_NPU_PVTPLL, "clk_npu_pvtpll", "clk_npu_pre_ndft", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(3), 12, GFLAGS), + [CLK_DDRPHY1X_SRC] = COMPOSITE(CLK_DDRPHY1X_SRC, "clk_ddrphy1x_src", dpll_gpll_cpll_p, RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(4), 0, GFLAGS), + [CLK_DDR1X] = MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(9), 15, 1, MFLAGS), + [CLK_MSCH] = COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(10), 0, 2, DFLAGS, + RK3568_CLKGATE_CON(4), 2, GFLAGS), + [CLK24_DDRMON] = GATE(CLK24_DDRMON, "clk24_ddrmon", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(4), 15, GFLAGS), + [ACLK_GIC_AUDIO] = COMPOSITE_NODIV(ACLK_GIC_AUDIO, "aclk_gic_audio", gpll200_gpll150_gpll100_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(10), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(5), 0, GFLAGS), + [HCLK_GIC_AUDIO] = COMPOSITE_NODIV(HCLK_GIC_AUDIO, "hclk_gic_audio", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(10), 10, 2, MFLAGS, + RK3568_CLKGATE_CON(5), 1, GFLAGS), + [HCLK_SDMMC_BUFFER] = GATE(HCLK_SDMMC_BUFFER, "hclk_sdmmc_buffer", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 8, GFLAGS), + [DCLK_SDMMC_BUFFER] = COMPOSITE_NODIV(DCLK_SDMMC_BUFFER, "dclk_sdmmc_buffer", gpll100_gpll75_gpll50_p, 0, + RK3568_CLKSEL_CON(10), 12, 2, MFLAGS, + RK3568_CLKGATE_CON(5), 9, GFLAGS), + [ACLK_GIC600] = GATE(ACLK_GIC600, "aclk_gic600", "aclk_gic_audio", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(5), 4, GFLAGS), + [ACLK_SPINLOCK] = GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_gic_audio", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(5), 7, GFLAGS), + [HCLK_I2S0_8CH] = GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 10, GFLAGS), + [HCLK_I2S1_8CH] = GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 11, GFLAGS), + [HCLK_I2S2_2CH] = GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 12, GFLAGS), + [HCLK_I2S3_2CH] = GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 13, GFLAGS), + [CLK_I2S0_8CH_TX_SRC] = COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(11), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(6), 0, GFLAGS), + [CLK_I2S0_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(12), 0, + RK3568_CLKGATE_CON(6), 1, GFLAGS, + &rk3568_i2s0_8ch_tx_fracmux), + [MCLK_I2S0_8CH_TX] = GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0, RK3568_CLKGATE_CON(6), 2, GFLAGS), + [I2S0_MCLKOUT_TX] = COMPOSITE_NODIV(I2S0_MCLKOUT_TX, "i2s0_mclkout_tx", i2s0_mclkout_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(11), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(6), 3, GFLAGS), + [CLK_I2S0_8CH_RX_SRC] = COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(13), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(6), 4, GFLAGS), + [CLK_I2S0_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(14), 0, + RK3568_CLKGATE_CON(6), 5, GFLAGS, + &rk3568_i2s0_8ch_rx_fracmux), + [MCLK_I2S0_8CH_RX] = GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0, RK3568_CLKGATE_CON(6), 6, GFLAGS), + [I2S0_MCLKOUT_RX] = COMPOSITE_NODIV(I2S0_MCLKOUT_RX, "i2s0_mclkout_rx", i2s0_mclkout_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(13), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(6), 7, GFLAGS), + [CLK_I2S1_8CH_TX_SRC] = COMPOSITE(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(15), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(6), 8, GFLAGS), + [CLK_I2S1_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(16), 0, + RK3568_CLKGATE_CON(6), 9, GFLAGS, + &rk3568_i2s1_8ch_tx_fracmux), + [MCLK_I2S1_8CH_TX] = GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 0, RK3568_CLKGATE_CON(6), 10, GFLAGS), + [I2S1_MCLKOUT_TX] = COMPOSITE_NODIV(I2S1_MCLKOUT_TX, "i2s1_mclkout_tx", i2s1_mclkout_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(15), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(6), 11, GFLAGS), + [CLK_I2S1_8CH_RX_SRC] = COMPOSITE(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(17), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(6), 12, GFLAGS), + [CLK_I2S1_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(18), 0, + RK3568_CLKGATE_CON(6), 13, GFLAGS, + &rk3568_i2s1_8ch_rx_fracmux), + [MCLK_I2S1_8CH_RX] = GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 0, RK3568_CLKGATE_CON(6), 14, GFLAGS), + [I2S1_MCLKOUT_RX] = COMPOSITE_NODIV(I2S1_MCLKOUT_RX, "i2s1_mclkout_rx", i2s1_mclkout_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(17), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(6), 15, GFLAGS), + [CLK_I2S2_2CH_SRC] = COMPOSITE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(19), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(7), 0, GFLAGS), + [CLK_I2S2_2CH_FRAC] = COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(20), 0, + RK3568_CLKGATE_CON(7), 1, GFLAGS, + &rk3568_i2s2_2ch_fracmux), + [MCLK_I2S2_2CH] = GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 0, RK3568_CLKGATE_CON(7), 2, GFLAGS), + [I2S2_MCLKOUT] = COMPOSITE_NODIV(I2S2_MCLKOUT, "i2s2_mclkout", i2s2_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(19), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(7), 3, GFLAGS), + [CLK_I2S3_2CH_TX_SRC] = COMPOSITE(CLK_I2S3_2CH_TX_SRC, "clk_i2s3_2ch_tx_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(21), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(7), 4, GFLAGS), + [CLK_I2S3_2CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S3_2CH_TX_FRAC, "clk_i2s3_2ch_tx_frac", "clk_i2s3_2ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(22), 0, + RK3568_CLKGATE_CON(7), 5, GFLAGS, + &rk3568_i2s3_2ch_tx_fracmux), + [MCLK_I2S3_2CH_TX] = GATE(MCLK_I2S3_2CH_TX, "mclk_i2s3_2ch_tx", "clk_i2s3_2ch_tx", 0, RK3568_CLKGATE_CON(7), 6, GFLAGS), + [I2S3_MCLKOUT_TX] = COMPOSITE_NODIV(I2S3_MCLKOUT_TX, "i2s3_mclkout_tx", i2s3_mclkout_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(21), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(7), 7, GFLAGS), + [CLK_I2S3_2CH_RX_SRC] = COMPOSITE(CLK_I2S3_2CH_RX_SRC, "clk_i2s3_2ch_rx_src", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(83), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(7), 8, GFLAGS), + [CLK_I2S3_2CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S3_2CH_RX_FRAC, "clk_i2s3_2ch_rx_frac", "clk_i2s3_2ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(84), 0, + RK3568_CLKGATE_CON(7), 9, GFLAGS, + &rk3568_i2s3_2ch_rx_fracmux), + [MCLK_I2S3_2CH_RX] = GATE(MCLK_I2S3_2CH_RX, "mclk_i2s3_2ch_rx", "clk_i2s3_2ch_rx", 0, RK3568_CLKGATE_CON(7), 10, GFLAGS), + [I2S3_MCLKOUT_RX] = COMPOSITE_NODIV(I2S3_MCLKOUT_RX, "i2s3_mclkout_rx", i2s3_mclkout_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(83), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(7), 11, GFLAGS), + [HCLK_PDM] = GATE(HCLK_PDM, "hclk_pdm", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(5), 14, GFLAGS), + [MCLK_PDM] = COMPOSITE_NODIV(MCLK_PDM, "mclk_pdm", mclk_pdm_p, 0, + RK3568_CLKSEL_CON(23), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(5), 15, GFLAGS), + [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(7), 12, GFLAGS), + [HCLK_SPDIF_8CH] = GATE(HCLK_SPDIF_8CH, "hclk_spdif_8ch", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(7), 13, GFLAGS), + [MCLK_SPDIF_8CH_SRC] = COMPOSITE(MCLK_SPDIF_8CH_SRC, "mclk_spdif_8ch_src", cpll_gpll_p, 0, + RK3568_CLKSEL_CON(23), 14, 1, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(7), 14, GFLAGS), + [MCLK_SPDIF_8CH_FRAC] = COMPOSITE_FRACMUX(MCLK_SPDIF_8CH_FRAC, "mclk_spdif_8ch_frac", "mclk_spdif_8ch_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(24), 0, + RK3568_CLKGATE_CON(7), 15, GFLAGS, + &rk3568_spdif_8ch_fracmux), + [MCLK_SPDIF_8CH] = &rk3568_spdif_8ch_fracmux.cell, + [HCLK_AUDPWM] = GATE(HCLK_AUDPWM, "hclk_audpwm", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(8), 0, GFLAGS), + [SCLK_AUDPWM_SRC] = COMPOSITE(SCLK_AUDPWM_SRC, "sclk_audpwm_src", gpll_cpll_p, 0, + RK3568_CLKSEL_CON(25), 14, 1, MFLAGS, 0, 6, DFLAGS, + RK3568_CLKGATE_CON(8), 1, GFLAGS), + [SCLK_AUDPWM_FRAC] = COMPOSITE_FRACMUX(SCLK_AUDPWM_FRAC, "sclk_audpwm_frac", "sclk_audpwm_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(26), 0, + RK3568_CLKGATE_CON(8), 2, GFLAGS, + &rk3568_audpwm_fracmux), + [SCLK_AUDPWM] = &rk3568_audpwm_fracmux.cell, + [HCLK_ACDCDIG] = GATE(HCLK_ACDCDIG, "hclk_acdcdig", "hclk_gic_audio", 0, RK3568_CLKGATE_CON(8), 3, GFLAGS), + [CLK_ACDCDIG_I2C] = COMPOSITE_NODIV(CLK_ACDCDIG_I2C, "clk_acdcdig_i2c", clk_i2c_p, 0, + RK3568_CLKSEL_CON(23), 10, 2, MFLAGS, + RK3568_CLKGATE_CON(8), 4, GFLAGS), + [CLK_ACDCDIG_DAC] = GATE(CLK_ACDCDIG_DAC, "clk_acdcdig_dac", "mclk_i2s3_2ch_tx", 0, RK3568_CLKGATE_CON(8), 5, GFLAGS), + [CLK_ACDCDIG_ADC] = GATE(CLK_ACDCDIG_ADC, "clk_acdcdig_adc", "mclk_i2s3_2ch_rx", 0, RK3568_CLKGATE_CON(8), 6, GFLAGS), + [ACLK_SECURE_FLASH] = COMPOSITE_NODIV(ACLK_SECURE_FLASH, "aclk_secure_flash", gpll200_gpll150_gpll100_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(27), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(8), 7, GFLAGS), + [HCLK_SECURE_FLASH] = COMPOSITE_NODIV(HCLK_SECURE_FLASH, "hclk_secure_flash", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(27), 2, 2, MFLAGS, + RK3568_CLKGATE_CON(8), 8, GFLAGS), + [ACLK_CRYPTO_NS] = GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_flash", 0, RK3568_CLKGATE_CON(8), 11, GFLAGS), + [HCLK_CRYPTO_NS] = GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(8), 12, GFLAGS), + [CLK_CRYPTO_NS_CORE] = COMPOSITE_NODIV(CLK_CRYPTO_NS_CORE, "clk_crypto_ns_core", gpll200_gpll150_gpll100_p, 0, + RK3568_CLKSEL_CON(27), 4, 2, MFLAGS, + RK3568_CLKGATE_CON(8), 13, GFLAGS), + [CLK_CRYPTO_NS_PKA] = COMPOSITE_NODIV(CLK_CRYPTO_NS_PKA, "clk_crypto_ns_pka", gpll300_gpll200_gpll100_p, 0, + RK3568_CLKSEL_CON(27), 6, 2, MFLAGS, + RK3568_CLKGATE_CON(8), 14, GFLAGS), + [CLK_CRYPTO_NS_RNG] = GATE(CLK_CRYPTO_NS_RNG, "clk_crypto_ns_rng", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(8), 15, GFLAGS), + [HCLK_TRNG_NS] =GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_flash", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(9), 10, GFLAGS), + [CLK_TRNG_NS] = GATE(CLK_TRNG_NS, "clk_trng_ns", "hclk_secure_flash", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(9), 11, GFLAGS), + [PCLK_OTPC_NS] = GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(26), 9, GFLAGS), + [CLK_OTPC_NS_SBPI] = GATE(CLK_OTPC_NS_SBPI, "clk_otpc_ns_sbpi", "xin24m", 0, RK3568_CLKGATE_CON(26), 10, GFLAGS), + [CLK_OTPC_NS_USR] = GATE(CLK_OTPC_NS_USR, "clk_otpc_ns_usr", "xin_osc0_half", 0, RK3568_CLKGATE_CON(26), 11, GFLAGS), + [HCLK_NANDC] = GATE(HCLK_NANDC, "hclk_nandc", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 0, GFLAGS), + [NCLK_NANDC] = COMPOSITE_NODIV(NCLK_NANDC, "nclk_nandc", clk_nandc_p, 0, + RK3568_CLKSEL_CON(28), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(9), 1, GFLAGS), + + [HCLK_SFC] = GATE(HCLK_SFC, "hclk_sfc", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 2, GFLAGS), + [HCLK_SFC_XIP] = GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 3, GFLAGS), + [SCLK_SFC] = COMPOSITE_NODIV(SCLK_SFC, "sclk_sfc", sclk_sfc_p, 0, + RK3568_CLKSEL_CON(28), 4, 3, MFLAGS, + RK3568_CLKGATE_CON(9), 4, GFLAGS), + [ACLK_EMMC] = GATE(ACLK_EMMC, "aclk_emmc", "aclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 5, GFLAGS), + [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_secure_flash", 0, RK3568_CLKGATE_CON(9), 6, GFLAGS), + [BCLK_EMMC] = COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", gpll200_gpll150_cpll125_p, 0, + RK3568_CLKSEL_CON(28), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(9), 7, GFLAGS), + [CCLK_EMMC] = COMPOSITE_NODIV(CCLK_EMMC, "cclk_emmc", cclk_emmc_p, 0, + RK3568_CLKSEL_CON(28), 12, 3, MFLAGS, + RK3568_CLKGATE_CON(9), 8, GFLAGS), + [TCLK_EMMC] =GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0, RK3568_CLKGATE_CON(9), 9, GFLAGS), + [ACLK_PIPE] = COMPOSITE_NODIV(ACLK_PIPE, "aclk_pipe", aclk_pipe_p, 0, + RK3568_CLKSEL_CON(29), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(10), 0, GFLAGS), + [PCLK_PIPE] = COMPOSITE_NOMUX(PCLK_PIPE, "pclk_pipe", "aclk_pipe", 0, + RK3568_CLKSEL_CON(29), 4, 4, DFLAGS, + RK3568_CLKGATE_CON(10), 1, GFLAGS), + [ACLK_PCIE20_MST] = GATE(ACLK_PCIE20_MST, "aclk_pcie20_mst", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 0, GFLAGS), + [ACLK_PCIE20_SLV] = GATE(ACLK_PCIE20_SLV, "aclk_pcie20_slv", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 1, GFLAGS), + [ACLK_PCIE20_DBI] = GATE(ACLK_PCIE20_DBI, "aclk_pcie20_dbi", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 2, GFLAGS), + [PCLK_PCIE20] = GATE(PCLK_PCIE20, "pclk_pcie20", "pclk_pipe", 0, RK3568_CLKGATE_CON(12), 3, GFLAGS), + [CLK_PCIE20_AUX_NDFT] = GATE(CLK_PCIE20_AUX_NDFT, "clk_pcie20_aux_ndft", "xin24m", 0, RK3568_CLKGATE_CON(12), 4, GFLAGS), + [ACLK_PCIE30X1_MST] = GATE(ACLK_PCIE30X1_MST, "aclk_pcie30x1_mst", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 8, GFLAGS), + [ACLK_PCIE30X1_SLV] = GATE(ACLK_PCIE30X1_SLV, "aclk_pcie30x1_slv", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 9, GFLAGS), + [ACLK_PCIE30X1_DBI] = GATE(ACLK_PCIE30X1_DBI, "aclk_pcie30x1_dbi", "aclk_pipe", 0, RK3568_CLKGATE_CON(12), 10, GFLAGS), + [PCLK_PCIE30X1] = GATE(PCLK_PCIE30X1, "pclk_pcie30x1", "pclk_pipe", 0, RK3568_CLKGATE_CON(12), 11, GFLAGS), + [CLK_PCIE30X1_AUX_NDFT] = GATE(CLK_PCIE30X1_AUX_NDFT, "clk_pcie30x1_aux_ndft", "xin24m", 0, RK3568_CLKGATE_CON(12), 12, GFLAGS), + [ACLK_PCIE30X2_MST] = GATE(ACLK_PCIE30X2_MST, "aclk_pcie30x2_mst", "aclk_pipe", 0, RK3568_CLKGATE_CON(13), 0, GFLAGS), + [ACLK_PCIE30X2_SLV] = GATE(ACLK_PCIE30X2_SLV, "aclk_pcie30x2_slv", "aclk_pipe", 0, RK3568_CLKGATE_CON(13), 1, GFLAGS), + [ACLK_PCIE30X2_DBI] = GATE(ACLK_PCIE30X2_DBI, "aclk_pcie30x2_dbi", "aclk_pipe", 0, RK3568_CLKGATE_CON(13), 2, GFLAGS), + [PCLK_PCIE30X2] = GATE(PCLK_PCIE30X2, "pclk_pcie30x2", "pclk_pipe", 0, RK3568_CLKGATE_CON(13), 3, GFLAGS), + [CLK_PCIE30X2_AUX_NDFT] = GATE(CLK_PCIE30X2_AUX_NDFT, "clk_pcie30x2_aux_ndft", "xin24m", 0, RK3568_CLKGATE_CON(13), 4, GFLAGS), + [ACLK_SATA0] = GATE(ACLK_SATA0, "aclk_sata0", "aclk_pipe", 0, RK3568_CLKGATE_CON(11), 0, GFLAGS), + [CLK_SATA0_PMALIVE] = GATE(CLK_SATA0_PMALIVE, "clk_sata0_pmalive", "gpll_20m", 0, RK3568_CLKGATE_CON(11), 1, GFLAGS), + [CLK_SATA0_RXOOB] = GATE(CLK_SATA0_RXOOB, "clk_sata0_rxoob", "cpll_50m", 0, RK3568_CLKGATE_CON(11), 2, GFLAGS), + [ACLK_SATA1] = GATE(ACLK_SATA1, "aclk_sata1", "aclk_pipe", 0, RK3568_CLKGATE_CON(11), 4, GFLAGS), + [CLK_SATA1_PMALIVE] = GATE(CLK_SATA1_PMALIVE, "clk_sata1_pmalive", "gpll_20m", 0, RK3568_CLKGATE_CON(11), 5, GFLAGS), + [CLK_SATA1_RXOOB] = GATE(CLK_SATA1_RXOOB, "clk_sata1_rxoob", "cpll_50m", 0, RK3568_CLKGATE_CON(11), 6, GFLAGS), + [ACLK_SATA2] = GATE(ACLK_SATA2, "aclk_sata2", "aclk_pipe", 0, RK3568_CLKGATE_CON(11), 8, GFLAGS), + [CLK_SATA2_PMALIVE] = GATE(CLK_SATA2_PMALIVE, "clk_sata2_pmalive", "gpll_20m", 0, RK3568_CLKGATE_CON(11), 9, GFLAGS), + [CLK_SATA2_RXOOB] = GATE(CLK_SATA2_RXOOB, "clk_sata2_rxoob", "cpll_50m", 0, RK3568_CLKGATE_CON(11), 10, GFLAGS), + [ACLK_USB3OTG0] = GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_pipe", 0, RK3568_CLKGATE_CON(10), 8, GFLAGS), + [CLK_USB3OTG0_REF] = GATE(CLK_USB3OTG0_REF, "clk_usb3otg0_ref", "xin24m", 0, RK3568_CLKGATE_CON(10), 9, GFLAGS), + [CLK_USB3OTG0_SUSPEND] = COMPOSITE_NODIV(CLK_USB3OTG0_SUSPEND, "clk_usb3otg0_suspend", xin24m_32k_p, 0, + RK3568_CLKSEL_CON(29), 8, 1, MFLAGS, + RK3568_CLKGATE_CON(10), 10, GFLAGS), + [ACLK_USB3OTG1] = GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_pipe", 0, RK3568_CLKGATE_CON(10), 12, GFLAGS), + [CLK_USB3OTG1_REF] = GATE(CLK_USB3OTG1_REF, "clk_usb3otg1_ref", "xin24m", 0, RK3568_CLKGATE_CON(10), 13, GFLAGS), + [CLK_USB3OTG1_SUSPEND] = COMPOSITE_NODIV(CLK_USB3OTG1_SUSPEND, "clk_usb3otg1_suspend", xin24m_32k_p, 0, + RK3568_CLKSEL_CON(29), 9, 1, MFLAGS, + RK3568_CLKGATE_CON(10), 14, GFLAGS), + [CLK_XPCS_EEE] = COMPOSITE_NODIV(CLK_XPCS_EEE, "clk_xpcs_eee", gpll200_cpll125_p, 0, + RK3568_CLKSEL_CON(29), 13, 1, MFLAGS, + RK3568_CLKGATE_CON(10), 4, GFLAGS), + [PCLK_XPCS] = GATE(PCLK_XPCS, "pclk_xpcs", "pclk_pipe", 0, RK3568_CLKGATE_CON(13), 6, GFLAGS), + [ACLK_PHP] = COMPOSITE_NODIV(ACLK_PHP, "aclk_php", gpll300_gpll200_gpll100_xin24m_p, 0, + RK3568_CLKSEL_CON(30), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(14), 8, GFLAGS), + [HCLK_PHP] = COMPOSITE_NODIV(HCLK_PHP, "hclk_php", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(30), 2, 2, MFLAGS, + RK3568_CLKGATE_CON(14), 9, GFLAGS), + [PCLK_PHP] = COMPOSITE_NOMUX(PCLK_PHP, "pclk_php", "aclk_php", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(30), 4, 4, DFLAGS, + RK3568_CLKGATE_CON(14), 10, GFLAGS), + [HCLK_SDMMC0] = GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_php", 0, RK3568_CLKGATE_CON(15), 0, GFLAGS), + [CLK_SDMMC0] = COMPOSITE_NODIV(CLK_SDMMC0, "clk_sdmmc0", clk_sdmmc_p, 0, + RK3568_CLKSEL_CON(30), 8, 3, MFLAGS, + RK3568_CLKGATE_CON(15), 1, GFLAGS), + [HCLK_SDMMC1] = GATE(HCLK_SDMMC1, "hclk_sdmmc1", "hclk_php", 0, RK3568_CLKGATE_CON(15), 2, GFLAGS), + [CLK_SDMMC1] = COMPOSITE_NODIV(CLK_SDMMC1, "clk_sdmmc1", clk_sdmmc_p, 0, + RK3568_CLKSEL_CON(30), 12, 3, MFLAGS, + RK3568_CLKGATE_CON(15), 3, GFLAGS), + [ACLK_GMAC0] = GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_php", 0, RK3568_CLKGATE_CON(15), 5, GFLAGS), + [PCLK_GMAC0] = GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php", 0, RK3568_CLKGATE_CON(15), 6, GFLAGS), + [CLK_MAC0_2TOP] = COMPOSITE_NODIV(CLK_MAC0_2TOP, "clk_mac0_2top", clk_mac_2top_p, 0, + RK3568_CLKSEL_CON(31), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(15), 7, GFLAGS), + [CLK_MAC0_OUT] = COMPOSITE_NODIV(CLK_MAC0_OUT, "clk_mac0_out", cpll125_cpll50_cpll25_xin24m_p, 0, + RK3568_CLKSEL_CON(31), 14, 2, MFLAGS, + RK3568_CLKGATE_CON(15), 8, GFLAGS), + [CLK_MAC0_REFOUT] = GATE(CLK_MAC0_REFOUT, "clk_mac0_refout", "clk_mac0_2top", 0, RK3568_CLKGATE_CON(15), 12, GFLAGS), + [CLK_GMAC0_PTP_REF] = COMPOSITE_NODIV(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", clk_gmac_ptp_p, 0, + RK3568_CLKSEL_CON(31), 12, 2, MFLAGS, + RK3568_CLKGATE_CON(15), 4, GFLAGS), + [ACLK_USB] = COMPOSITE_NODIV(ACLK_USB, "aclk_usb", gpll300_gpll200_gpll100_xin24m_p, 0, + RK3568_CLKSEL_CON(32), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(16), 0, GFLAGS), + [HCLK_USB] = COMPOSITE_NODIV(HCLK_USB, "hclk_usb", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(32), 2, 2, MFLAGS, + RK3568_CLKGATE_CON(16), 1, GFLAGS), + [PCLK_USB] = COMPOSITE_NOMUX(PCLK_USB, "pclk_usb", "aclk_usb", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(32), 4, 4, DFLAGS, + RK3568_CLKGATE_CON(16), 2, GFLAGS), + [HCLK_USB2HOST0] = GATE(HCLK_USB2HOST0, "hclk_usb2host0", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 12, GFLAGS), + [HCLK_USB2HOST0_ARB] = GATE(HCLK_USB2HOST0_ARB, "hclk_usb2host0_arb", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 13, GFLAGS), + [HCLK_USB2HOST1] = GATE(HCLK_USB2HOST1, "hclk_usb2host1", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 14, GFLAGS), + [HCLK_USB2HOST1_ARB] = GATE(HCLK_USB2HOST1_ARB, "hclk_usb2host1_arb", "hclk_usb", 0, RK3568_CLKGATE_CON(16), 15, GFLAGS), + [HCLK_SDMMC2] = GATE(HCLK_SDMMC2, "hclk_sdmmc2", "hclk_usb", 0, RK3568_CLKGATE_CON(17), 0, GFLAGS), + [CLK_SDMMC2] = COMPOSITE_NODIV(CLK_SDMMC2, "clk_sdmmc2", clk_sdmmc_p, 0, + RK3568_CLKSEL_CON(32), 8, 3, MFLAGS, + RK3568_CLKGATE_CON(17), 1, GFLAGS), + [ACLK_GMAC1] = GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_usb", 0, RK3568_CLKGATE_CON(17), 3, GFLAGS), + [PCLK_GMAC1] = GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_usb", 0, RK3568_CLKGATE_CON(17), 4, GFLAGS), + [CLK_MAC1_2TOP] = COMPOSITE_NODIV(CLK_MAC1_2TOP, "clk_mac1_2top", clk_mac_2top_p, 0, + RK3568_CLKSEL_CON(33), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(17), 5, GFLAGS), + [CLK_MAC1_OUT] = COMPOSITE_NODIV(CLK_MAC1_OUT, "clk_mac1_out", cpll125_cpll50_cpll25_xin24m_p, 0, + RK3568_CLKSEL_CON(33), 14, 2, MFLAGS, + RK3568_CLKGATE_CON(17), 6, GFLAGS), + [CLK_MAC1_REFOUT] = GATE(CLK_MAC1_REFOUT, "clk_mac1_refout", "clk_mac1_2top", 0, RK3568_CLKGATE_CON(17), 10, GFLAGS), + [CLK_GMAC1_PTP_REF] = COMPOSITE_NODIV(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", clk_gmac_ptp_p, 0, + RK3568_CLKSEL_CON(33), 12, 2, MFLAGS, + RK3568_CLKGATE_CON(17), 2, GFLAGS), + [ACLK_PERIMID] = COMPOSITE_NODIV(ACLK_PERIMID, "aclk_perimid", gpll300_gpll200_gpll100_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(10), 4, 2, MFLAGS, + RK3568_CLKGATE_CON(14), 0, GFLAGS), + [HCLK_PERIMID] = COMPOSITE_NODIV(HCLK_PERIMID, "hclk_perimid", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(10), 6, 2, MFLAGS, + RK3568_CLKGATE_CON(14), 1, GFLAGS), + [ACLK_VI] = COMPOSITE_NODIV(ACLK_VI, "aclk_vi", gpll400_gpll300_gpll200_xin24m_p, 0, + RK3568_CLKSEL_CON(34), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(18), 0, GFLAGS), + [HCLK_VI] = COMPOSITE_NOMUX(HCLK_VI, "hclk_vi", "aclk_vi", 0, + RK3568_CLKSEL_CON(34), 4, 4, DFLAGS, + RK3568_CLKGATE_CON(18), 1, GFLAGS), + [PCLK_VI] = COMPOSITE_NOMUX(PCLK_VI, "pclk_vi", "aclk_vi", 0, + RK3568_CLKSEL_CON(34), 8, 4, DFLAGS, + RK3568_CLKGATE_CON(18), 2, GFLAGS), + [ACLK_VICAP] = GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi", 0, RK3568_CLKGATE_CON(18), 9, GFLAGS), + [HCLK_VICAP] = GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi", 0, RK3568_CLKGATE_CON(18), 10, GFLAGS), + [DCLK_VICAP] = COMPOSITE_NODIV(DCLK_VICAP, "dclk_vicap", cpll333_gpll300_gpll200_p, 0, + RK3568_CLKSEL_CON(34), 14, 2, MFLAGS, + RK3568_CLKGATE_CON(18), 11, GFLAGS), + [ICLK_VICAP_G] = GATE(ICLK_VICAP_G, "iclk_vicap_g", "iclk_vicap", 0, RK3568_CLKGATE_CON(18), 13, GFLAGS), + [ACLK_ISP] = GATE(ACLK_ISP, "aclk_isp", "aclk_vi", 0, RK3568_CLKGATE_CON(19), 0, GFLAGS), + [HCLK_ISP] = GATE(HCLK_ISP, "hclk_isp", "hclk_vi", 0, RK3568_CLKGATE_CON(19), 1, GFLAGS), + [CLK_ISP] = COMPOSITE(CLK_ISP, "clk_isp", cpll_gpll_hpll_p, 0, + RK3568_CLKSEL_CON(35), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(19), 2, GFLAGS), + [PCLK_CSI2HOST1] =GATE(PCLK_CSI2HOST1, "pclk_csi2host1", "pclk_vi", 0, RK3568_CLKGATE_CON(19), 4, GFLAGS), + [CLK_CIF_OUT] = COMPOSITE(CLK_CIF_OUT, "clk_cif_out", gpll_usb480m_xin24m_p, 0, + RK3568_CLKSEL_CON(35), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3568_CLKGATE_CON(19), 8, GFLAGS), + [CLK_CAM0_OUT] = COMPOSITE(CLK_CAM0_OUT, "clk_cam0_out", gpll_usb480m_xin24m_p, 0, + RK3568_CLKSEL_CON(36), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3568_CLKGATE_CON(19), 9, GFLAGS), + [CLK_CAM1_OUT] = COMPOSITE(CLK_CAM1_OUT, "clk_cam1_out", gpll_usb480m_xin24m_p, 0, + RK3568_CLKSEL_CON(36), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3568_CLKGATE_CON(19), 10, GFLAGS), + [ACLK_VO] = COMPOSITE_NODIV(ACLK_VO, "aclk_vo", gpll300_cpll250_gpll100_xin24m_p, 0, + RK3568_CLKSEL_CON(37), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(20), 0, GFLAGS), + [HCLK_VO] = COMPOSITE_NOMUX(HCLK_VO, "hclk_vo", "aclk_vo", 0, + RK3568_CLKSEL_CON(37), 8, 4, DFLAGS, + RK3568_CLKGATE_CON(20), 1, GFLAGS), + [PCLK_VO] = COMPOSITE_NOMUX(PCLK_VO, "pclk_vo", "aclk_vo", 0, + RK3568_CLKSEL_CON(37), 12, 4, DFLAGS, + RK3568_CLKGATE_CON(20), 2, GFLAGS), + [ACLK_VOP_PRE] = COMPOSITE(ACLK_VOP_PRE, "aclk_vop_pre", cpll_gpll_hpll_vpll_p, 0, + RK3568_CLKSEL_CON(38), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(20), 6, GFLAGS), + [ACLK_VOP] = GATE(ACLK_VOP, "aclk_vop", "aclk_vop_pre", 0, RK3568_CLKGATE_CON(20), 8, GFLAGS), + [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_vo", 0, RK3568_CLKGATE_CON(20), 9, GFLAGS), + [DCLK_VOP0] = COMPOSITE(DCLK_VOP0, "dclk_vop0", hpll_vpll_gpll_cpll_p, 0, + RK3568_CLKSEL_CON(39), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3568_CLKGATE_CON(20), 10, GFLAGS), + [DCLK_VOP1] = COMPOSITE(DCLK_VOP1, "dclk_vop1", hpll_vpll_gpll_cpll_p, 0, + RK3568_CLKSEL_CON(40), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3568_CLKGATE_CON(20), 11, GFLAGS), + [DCLK_VOP2] = COMPOSITE(DCLK_VOP2, "dclk_vop2", hpll_vpll_gpll_cpll_p, 0, + RK3568_CLKSEL_CON(41), 10, 2, MFLAGS, 0, 8, DFLAGS, + RK3568_CLKGATE_CON(20), 12, GFLAGS), + [CLK_VOP_PWM] = GATE(CLK_VOP_PWM, "clk_vop_pwm", "xin24m", 0, RK3568_CLKGATE_CON(20), 13, GFLAGS), + [ACLK_HDCP] = GATE(ACLK_HDCP, "aclk_hdcp", "aclk_vo", 0, RK3568_CLKGATE_CON(21), 0, GFLAGS), + [HCLK_HDCP] = GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vo", 0, RK3568_CLKGATE_CON(21), 1, GFLAGS), + [PCLK_HDCP] = GATE(PCLK_HDCP, "pclk_hdcp", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 2, GFLAGS), + [PCLK_HDMI_HOST] = GATE(PCLK_HDMI_HOST, "pclk_hdmi_host", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 3, GFLAGS), + [CLK_HDMI_SFR] = GATE(CLK_HDMI_SFR, "clk_hdmi_sfr", "xin24m", 0, RK3568_CLKGATE_CON(21), 4, GFLAGS), + [PCLK_DSITX_0] = GATE(PCLK_DSITX_0, "pclk_dsitx_0", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 6, GFLAGS), + [PCLK_DSITX_1] = GATE(PCLK_DSITX_1, "pclk_dsitx_1", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 7, GFLAGS), + [PCLK_EDP_CTRL] = GATE(PCLK_EDP_CTRL, "pclk_edp_ctrl", "pclk_vo", 0, RK3568_CLKGATE_CON(21), 8, GFLAGS), + [CLK_EDP_200M] = COMPOSITE_NODIV(CLK_EDP_200M, "clk_edp_200m", gpll200_gpll150_cpll125_p, 0, + RK3568_CLKSEL_CON(38), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(21), 9, GFLAGS), + [ACLK_VPU_PRE] = COMPOSITE(ACLK_VPU_PRE, "aclk_vpu_pre", gpll_cpll_p, 0, + RK3568_CLKSEL_CON(42), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(22), 0, GFLAGS), + [HCLK_VPU_PRE] =COMPOSITE_NOMUX(HCLK_VPU_PRE, "hclk_vpu_pre", "aclk_vpu_pre", 0, + RK3568_CLKSEL_CON(42), 8, 4, DFLAGS, + RK3568_CLKGATE_CON(22), 1, GFLAGS), + [ACLK_VPU] = GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_pre", 0, RK3568_CLKGATE_CON(22), 4, GFLAGS), + [HCLK_VPU] = GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_pre", 0, RK3568_CLKGATE_CON(22), 5, GFLAGS), + [ACLK_RGA_PRE] = COMPOSITE_NODIV(ACLK_RGA_PRE, "aclk_rga_pre", gpll300_cpll250_gpll100_xin24m_p, 0, + RK3568_CLKSEL_CON(43), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(23), 0, GFLAGS), + [HCLK_RGA_PRE] = COMPOSITE_NOMUX(HCLK_RGA_PRE, "hclk_rga_pre", "aclk_rga_pre", 0, + RK3568_CLKSEL_CON(43), 8, 4, DFLAGS, + RK3568_CLKGATE_CON(23), 1, GFLAGS), + [PCLK_RGA_PRE] = COMPOSITE_NOMUX(PCLK_RGA_PRE, "pclk_rga_pre", "aclk_rga_pre", 0, + RK3568_CLKSEL_CON(43), 12, 4, DFLAGS, + RK3568_CLKGATE_CON(22), 12, GFLAGS), + [ACLK_RGA] = GATE(ACLK_RGA, "aclk_rga", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 4, GFLAGS), + [HCLK_RGA] = GATE(HCLK_RGA, "hclk_rga", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 5, GFLAGS), + [CLK_RGA_CORE] = COMPOSITE_NODIV(CLK_RGA_CORE, "clk_rga_core", gpll300_gpll200_gpll100_p, 0, + RK3568_CLKSEL_CON(43), 2, 2, MFLAGS, + RK3568_CLKGATE_CON(23), 6, GFLAGS), + [ACLK_IEP] = GATE(ACLK_IEP, "aclk_iep", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 7, GFLAGS), + [HCLK_IEP] = GATE(HCLK_IEP, "hclk_iep", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 8, GFLAGS), + [CLK_IEP_CORE] = COMPOSITE_NODIV(CLK_IEP_CORE, "clk_iep_core", gpll300_gpll200_gpll100_p, 0, + RK3568_CLKSEL_CON(43), 4, 2, MFLAGS, + RK3568_CLKGATE_CON(23), 9, GFLAGS), + [HCLK_EBC] = GATE(HCLK_EBC, "hclk_ebc", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 10, GFLAGS), + [DCLK_EBC] = COMPOSITE_NODIV(DCLK_EBC, "dclk_ebc", gpll400_cpll333_gpll200_p, 0, + RK3568_CLKSEL_CON(43), 6, 2, MFLAGS, + RK3568_CLKGATE_CON(23), 11, GFLAGS), + [ACLK_JDEC] = GATE(ACLK_JDEC, "aclk_jdec", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 12, GFLAGS), + [HCLK_JDEC] = GATE(HCLK_JDEC, "hclk_jdec", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 13, GFLAGS), + [ACLK_JENC] = GATE(ACLK_JENC, "aclk_jenc", "aclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 14, GFLAGS), + [HCLK_JENC] = GATE(HCLK_JENC, "hclk_jenc", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(23), 15, GFLAGS), + [PCLK_EINK] = GATE(PCLK_EINK, "pclk_eink", "pclk_rga_pre", 0, RK3568_CLKGATE_CON(22), 14, GFLAGS), + [HCLK_EINK] = GATE(HCLK_EINK, "hclk_eink", "hclk_rga_pre", 0, RK3568_CLKGATE_CON(22), 15, GFLAGS), + [ACLK_RKVENC_PRE] = COMPOSITE(ACLK_RKVENC_PRE, "aclk_rkvenc_pre", gpll_cpll_npll_p, 0, + RK3568_CLKSEL_CON(44), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(24), 0, GFLAGS), + [HCLK_RKVENC_PRE] = COMPOSITE_NOMUX(HCLK_RKVENC_PRE, "hclk_rkvenc_pre", "aclk_rkvenc_pre", 0, + RK3568_CLKSEL_CON(44), 8, 4, DFLAGS, + RK3568_CLKGATE_CON(24), 1, GFLAGS), + [ACLK_RKVENC] = GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_pre", 0, RK3568_CLKGATE_CON(24), 6, GFLAGS), + [HCLK_RKVENC] = GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_pre", 0, RK3568_CLKGATE_CON(24), 7, GFLAGS), + [CLK_RKVENC_CORE] = COMPOSITE(CLK_RKVENC_CORE, "clk_rkvenc_core", gpll_cpll_npll_vpll_p, 0, + RK3568_CLKSEL_CON(45), 14, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(24), 8, GFLAGS), + [ACLK_RKVDEC_PRE] = COMPOSITE(ACLK_RKVDEC_PRE, "aclk_rkvdec_pre", aclk_rkvdec_pre_p, 0, + RK3568_CLKSEL_CON(47), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(25), 0, GFLAGS), + [HCLK_RKVDEC_PRE] = COMPOSITE_NOMUX(HCLK_RKVDEC_PRE, "hclk_rkvdec_pre", "aclk_rkvdec_pre", 0, + RK3568_CLKSEL_CON(47), 8, 4, DFLAGS, + RK3568_CLKGATE_CON(25), 1, GFLAGS), + [ACLK_RKVDEC] = GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pre", 0, RK3568_CLKGATE_CON(25), 4, GFLAGS), + [HCLK_RKVDEC] = GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_pre", 0, RK3568_CLKGATE_CON(25), 5, GFLAGS), + [CLK_RKVDEC_CA] = COMPOSITE(CLK_RKVDEC_CA, "clk_rkvdec_ca", gpll_cpll_npll_vpll_p, 0, + RK3568_CLKSEL_CON(48), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(25), 6, GFLAGS), + [CLK_RKVDEC_CORE] = COMPOSITE(CLK_RKVDEC_CORE, "clk_rkvdec_core", clk_rkvdec_core_p, 0, + RK3568_CLKSEL_CON(49), 14, 2, MFLAGS, 8, 5, DFLAGS, + RK3568_CLKGATE_CON(25), 7, GFLAGS), + [CLK_RKVDEC_HEVC_CA] = COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_npll_vpll_p, 0, + RK3568_CLKSEL_CON(49), 6, 2, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(25), 8, GFLAGS), + [ACLK_BUS] = COMPOSITE_NODIV(ACLK_BUS, "aclk_bus", gpll200_gpll150_gpll100_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(50), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(26), 0, GFLAGS), + [PCLK_BUS] = COMPOSITE_NODIV(PCLK_BUS, "pclk_bus", gpll100_gpll75_cpll50_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(50), 4, 2, MFLAGS, + RK3568_CLKGATE_CON(26), 1, GFLAGS), + [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus", 0, RK3568_CLKGATE_CON(26), 4, GFLAGS), + [CLK_TSADC_TSEN] = COMPOSITE(CLK_TSADC_TSEN, "clk_tsadc_tsen", xin24m_gpll100_cpll100_p, 0, + RK3568_CLKSEL_CON(51), 4, 2, MFLAGS, 0, 3, DFLAGS, + RK3568_CLKGATE_CON(26), 5, GFLAGS), + [CLK_TSADC] = COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "clk_tsadc_tsen", 0, + RK3568_CLKSEL_CON(51), 8, 7, DFLAGS, + RK3568_CLKGATE_CON(26), 6, GFLAGS), + [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus", 0, RK3568_CLKGATE_CON(26), 7, GFLAGS), + [CLK_SARADC] = GATE(CLK_SARADC, "clk_saradc", "xin24m", 0, RK3568_CLKGATE_CON(26), 8, GFLAGS), + [PCLK_SCR] = GATE(PCLK_SCR, "pclk_scr", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(26), 12, GFLAGS), + [PCLK_WDT_NS] = GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus", 0, RK3568_CLKGATE_CON(26), 13, GFLAGS), + [TCLK_WDT_NS] = GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0, RK3568_CLKGATE_CON(26), 14, GFLAGS), + [ACLK_MCU] = GATE(ACLK_MCU, "aclk_mcu", "aclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(32), 13, GFLAGS), + [PCLK_INTMUX] = GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus", RT_CLK_F_IGNORE_UNUSED, RK3568_CLKGATE_CON(32), 14, GFLAGS), + [PCLK_MAILBOX] = GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus", 0, RK3568_CLKGATE_CON(32), 15, GFLAGS), + [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 12, GFLAGS), + [CLK_UART1_SRC] = COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(52), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(27), 13, GFLAGS), + [CLK_UART1_FRAC] = COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(53), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(27), 14, GFLAGS, + &rk3568_uart1_fracmux), + [SCLK_UART1] = GATE(SCLK_UART1, "sclk_uart1", "sclk_uart1_mux", 0, RK3568_CLKGATE_CON(27), 15, GFLAGS), + [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 0, GFLAGS), + [CLK_UART2_SRC] = COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(54), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(28), 1, GFLAGS), + [CLK_UART2_FRAC] = COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(55), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(28), 2, GFLAGS, + &rk3568_uart2_fracmux), + [SCLK_UART2] = GATE(SCLK_UART2, "sclk_uart2", "sclk_uart2_mux", 0, RK3568_CLKGATE_CON(28), 3, GFLAGS), + [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 4, GFLAGS), + [CLK_UART3_SRC] = COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(56), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(28), 5, GFLAGS), + [CLK_UART3_FRAC] = COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(57), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(28), 6, GFLAGS, + &rk3568_uart3_fracmux), + [SCLK_UART3] = GATE(SCLK_UART3, "sclk_uart3", "sclk_uart3_mux", 0, RK3568_CLKGATE_CON(28), 7, GFLAGS), + [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 8, GFLAGS), + [CLK_UART4_SRC] = COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(58), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(28), 9, GFLAGS), + [CLK_UART4_FRAC] = COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(59), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(28), 10, GFLAGS, + &rk3568_uart4_fracmux), + [SCLK_UART4] = GATE(SCLK_UART4, "sclk_uart4", "sclk_uart4_mux", 0, RK3568_CLKGATE_CON(28), 11, GFLAGS), + [PCLK_UART5] = GATE(PCLK_UART5, "pclk_uart5", "pclk_bus", 0, RK3568_CLKGATE_CON(28), 12, GFLAGS), + [CLK_UART5_SRC] = COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(60), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(28), 13, GFLAGS), + [CLK_UART5_FRAC] = COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(61), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(28), 14, GFLAGS, + &rk3568_uart5_fracmux), + [SCLK_UART5] = GATE(SCLK_UART5, "sclk_uart5", "sclk_uart5_mux", 0, RK3568_CLKGATE_CON(28), 15, GFLAGS), + [PCLK_UART6] =GATE(PCLK_UART6, "pclk_uart6", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 0, GFLAGS), + [CLK_UART6_SRC] = COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(62), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(29), 1, GFLAGS), + [CLK_UART6_FRAC] = COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(63), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(29), 2, GFLAGS, + &rk3568_uart6_fracmux), + [SCLK_UART6] = GATE(SCLK_UART6, "sclk_uart6", "sclk_uart6_mux", 0, RK3568_CLKGATE_CON(29), 3, GFLAGS), + [PCLK_UART7] = GATE(PCLK_UART7, "pclk_uart7", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 4, GFLAGS), + [CLK_UART7_SRC] = COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(64), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(29), 5, GFLAGS), + [CLK_UART7_FRAC] = COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(65), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(29), 6, GFLAGS, + &rk3568_uart7_fracmux), + [SCLK_UART7] = GATE(SCLK_UART7, "sclk_uart7", "sclk_uart7_mux", 0, RK3568_CLKGATE_CON(29), 7, GFLAGS), + [PCLK_UART8] = GATE(PCLK_UART8, "pclk_uart8", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 8, GFLAGS), + [CLK_UART8_SRC] = COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(66), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(29), 9, GFLAGS), + [CLK_UART8_FRAC] = COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(67), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(29), 10, GFLAGS, + &rk3568_uart8_fracmux), + [SCLK_UART8] = GATE(SCLK_UART8, "sclk_uart8", "sclk_uart8_mux", 0, RK3568_CLKGATE_CON(29), 11, GFLAGS), + [PCLK_UART9] =GATE(PCLK_UART9, "pclk_uart9", "pclk_bus", 0, RK3568_CLKGATE_CON(29), 12, GFLAGS), + [CLK_UART9_SRC] =COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_usb480m_p, 0, + RK3568_CLKSEL_CON(68), 8, 2, MFLAGS, 0, 7, DFLAGS, + RK3568_CLKGATE_CON(29), 13, GFLAGS), + [CLK_UART9_FRAC] =COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(69), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3568_CLKGATE_CON(29), 14, GFLAGS, + &rk3568_uart9_fracmux), + [SCLK_UART9] =GATE(SCLK_UART9, "sclk_uart9", "sclk_uart9_mux", 0, RK3568_CLKGATE_CON(29), 15, GFLAGS), + [PCLK_CAN0] =GATE(PCLK_CAN0, "pclk_can0", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 5, GFLAGS), + [CLK_CAN0] =COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0, + RK3568_CLKSEL_CON(70), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(27), 6, GFLAGS), + [PCLK_CAN1] = GATE(PCLK_CAN1, "pclk_can1", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 7, GFLAGS), + [CLK_CAN1] = COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0, + RK3568_CLKSEL_CON(70), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3568_CLKGATE_CON(27), 8, GFLAGS), + [PCLK_CAN2] = GATE(PCLK_CAN2, "pclk_can2", "pclk_bus", 0, RK3568_CLKGATE_CON(27), 9, GFLAGS), + [CLK_CAN2] = COMPOSITE(CLK_CAN2, "clk_can2", gpll_cpll_p, 0, + RK3568_CLKSEL_CON(71), 7, 1, MFLAGS, 0, 5, DFLAGS, + RK3568_CLKGATE_CON(27), 10, GFLAGS), + [CLK_I2C] = COMPOSITE_NODIV(CLK_I2C, "clk_i2c", clk_i2c_p, 0, + RK3568_CLKSEL_CON(71), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(32), 10, GFLAGS), + [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 0, GFLAGS), + [CLK_I2C1] = GATE(CLK_I2C1, "clk_i2c1", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 1, GFLAGS), + [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 2, GFLAGS), + [CLK_I2C2] = GATE(CLK_I2C2, "clk_i2c2", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 3, GFLAGS), + [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 4, GFLAGS), + [CLK_I2C3] = GATE(CLK_I2C3, "clk_i2c3", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 5, GFLAGS), + [PCLK_I2C4] = GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 6, GFLAGS), + [CLK_I2C4] = GATE(CLK_I2C4, "clk_i2c4", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 7, GFLAGS), + [PCLK_I2C5] = GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 8, GFLAGS), + [CLK_I2C5] = GATE(CLK_I2C5, "clk_i2c5", "clk_i2c", 0, RK3568_CLKGATE_CON(30), 9, GFLAGS), + [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 10, GFLAGS), + [CLK_SPI0] = COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", gpll200_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 0, 1, MFLAGS, + RK3568_CLKGATE_CON(30), 11, GFLAGS), + [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 12, GFLAGS), + [CLK_SPI1] = COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", gpll200_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 2, 1, MFLAGS, + RK3568_CLKGATE_CON(30), 13, GFLAGS), + [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus", 0, RK3568_CLKGATE_CON(30), 14, GFLAGS), + [CLK_SPI2] = COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", gpll200_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 4, 1, MFLAGS, + RK3568_CLKGATE_CON(30), 15, GFLAGS), + [PCLK_SPI3] = GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 0, GFLAGS), + [CLK_SPI3] = COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", gpll200_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 6, 1, MFLAGS, RK3568_CLKGATE_CON(31), 1, GFLAGS), + [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 10, GFLAGS), + [CLK_PWM1] = COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", gpll100_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(31), 11, GFLAGS), + [CLK_PWM1_CAPTURE] = GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 0, RK3568_CLKGATE_CON(31), 12, GFLAGS), + [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 13, GFLAGS), + [CLK_PWM2] = COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", gpll100_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 10, 2, MFLAGS, + RK3568_CLKGATE_CON(31), 14, GFLAGS), + [CLK_PWM2_CAPTURE] = GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 0, RK3568_CLKGATE_CON(31), 15, GFLAGS), + [PCLK_PWM3] = GATE(PCLK_PWM3, "pclk_pwm3", "pclk_bus", 0, RK3568_CLKGATE_CON(32), 0, GFLAGS), + [CLK_PWM3] = COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", gpll100_xin24m_cpll100_p, 0, + RK3568_CLKSEL_CON(72), 12, 2, MFLAGS, + RK3568_CLKGATE_CON(32), 1, GFLAGS), + [CLK_PWM3_CAPTURE] = GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 0, RK3568_CLKGATE_CON(32), 2, GFLAGS), + [DBCLK_GPIO] = COMPOSITE_NODIV(DBCLK_GPIO, "dbclk_gpio", xin24m_32k_p, 0, + RK3568_CLKSEL_CON(72), 14, 1, MFLAGS, + RK3568_CLKGATE_CON(32), 11, GFLAGS), + [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 2, GFLAGS), + [DBCLK_GPIO1] = GATE(DBCLK_GPIO1, "dbclk_gpio1", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 3, GFLAGS), + [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 4, GFLAGS), + [DBCLK_GPIO2] = GATE(DBCLK_GPIO2, "dbclk_gpio2", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 5, GFLAGS), + [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 6, GFLAGS), + [DBCLK_GPIO3] = GATE(DBCLK_GPIO3, "dbclk_gpio3", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 7, GFLAGS), + [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus", 0, RK3568_CLKGATE_CON(31), 8, GFLAGS), + [DBCLK_GPIO4] = GATE(DBCLK_GPIO4, "dbclk_gpio4", "dbclk_gpio", 0, RK3568_CLKGATE_CON(31), 9, GFLAGS), + [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_bus", 0, RK3568_CLKGATE_CON(32), 3, GFLAGS), + [CLK_TIMER0] = GATE(CLK_TIMER0, "clk_timer0", "xin24m", 0, RK3568_CLKGATE_CON(32), 4, GFLAGS), + [CLK_TIMER1] = GATE(CLK_TIMER1, "clk_timer1", "xin24m", 0, RK3568_CLKGATE_CON(32), 5, GFLAGS), + [CLK_TIMER2] = GATE(CLK_TIMER2, "clk_timer2", "xin24m", 0, RK3568_CLKGATE_CON(32), 6, GFLAGS), + [CLK_TIMER3] = GATE(CLK_TIMER3, "clk_timer3", "xin24m", 0, RK3568_CLKGATE_CON(32), 7, GFLAGS), + [CLK_TIMER4] = GATE(CLK_TIMER4, "clk_timer4", "xin24m", 0, RK3568_CLKGATE_CON(32), 8, GFLAGS), + [CLK_TIMER5] = GATE(CLK_TIMER5, "clk_timer5", "xin24m", 0, RK3568_CLKGATE_CON(32), 9, GFLAGS), + [ACLK_TOP_HIGH] = COMPOSITE_NODIV(ACLK_TOP_HIGH, "aclk_top_high", cpll500_gpll400_gpll300_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(73), 0, 2, MFLAGS, + RK3568_CLKGATE_CON(33), 0, GFLAGS), + [ACLK_TOP_LOW] = COMPOSITE_NODIV(ACLK_TOP_LOW, "aclk_top_low", gpll400_gpll300_gpll200_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(73), 4, 2, MFLAGS, + RK3568_CLKGATE_CON(33), 1, GFLAGS), + [HCLK_TOP] = COMPOSITE_NODIV(HCLK_TOP, "hclk_top", gpll150_gpll100_gpll75_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(73), 8, 2, MFLAGS, + RK3568_CLKGATE_CON(33), 2, GFLAGS), + [PCLK_TOP] = COMPOSITE_NODIV(PCLK_TOP, "pclk_top", gpll100_gpll75_cpll50_xin24m_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(73), 12, 2, MFLAGS, + RK3568_CLKGATE_CON(33), 3, GFLAGS), + [PCLK_PCIE30PHY] = GATE(PCLK_PCIE30PHY, "pclk_pcie30phy", "pclk_top", 0, RK3568_CLKGATE_CON(33), 8, GFLAGS), + [CLK_OPTC_ARB] = COMPOSITE_NODIV(CLK_OPTC_ARB, "clk_optc_arb", xin24m_cpll100_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(73), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(33), 9, GFLAGS), + [PCLK_MIPICSIPHY] = GATE(PCLK_MIPICSIPHY, "pclk_mipicsiphy", "pclk_top", 0, RK3568_CLKGATE_CON(33), 13, GFLAGS), + [PCLK_MIPIDSIPHY0] = GATE(PCLK_MIPIDSIPHY0, "pclk_mipidsiphy0", "pclk_top", 0, RK3568_CLKGATE_CON(33), 14, GFLAGS), + [PCLK_MIPIDSIPHY1] = GATE(PCLK_MIPIDSIPHY1, "pclk_mipidsiphy1", "pclk_top", 0, RK3568_CLKGATE_CON(33), 15, GFLAGS), + [PCLK_PIPEPHY0] = GATE(PCLK_PIPEPHY0, "pclk_pipephy0", "pclk_top", 0, RK3568_CLKGATE_CON(34), 4, GFLAGS), + [PCLK_PIPEPHY1] = GATE(PCLK_PIPEPHY1, "pclk_pipephy1", "pclk_top", 0, RK3568_CLKGATE_CON(34), 5, GFLAGS), + [PCLK_PIPEPHY2] = GATE(PCLK_PIPEPHY2, "pclk_pipephy2", "pclk_top", 0, RK3568_CLKGATE_CON(34), 6, GFLAGS), + [PCLK_CPU_BOOST] = GATE(PCLK_CPU_BOOST, "pclk_cpu_boost", "pclk_top", 0, RK3568_CLKGATE_CON(34), 11, GFLAGS), + [CLK_CPU_BOOST] = GATE(CLK_CPU_BOOST, "clk_cpu_boost", "xin24m", 0, RK3568_CLKGATE_CON(34), 12, GFLAGS), + [PCLK_OTPPHY] = GATE(PCLK_OTPPHY, "pclk_otpphy", "pclk_top", 0, RK3568_CLKGATE_CON(34), 13, GFLAGS), + [SCLK_GMAC0] = MUX(SCLK_GMAC0, "clk_gmac0", mux_gmac0_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(31), 2, 1, MFLAGS), + [SCLK_GMAC0_RGMII_SPEED] = MUX(SCLK_GMAC0_RGMII_SPEED, "clk_gmac0_rgmii_speed", mux_gmac0_rgmii_speed_p, 0, + RK3568_CLKSEL_CON(31), 4, 2, MFLAGS), + [SCLK_GMAC0_RMII_SPEED] = MUX(SCLK_GMAC0_RMII_SPEED, "clk_gmac0_rmii_speed", mux_gmac0_rmii_speed_p, 0, + RK3568_CLKSEL_CON(31), 3, 1, MFLAGS), + [SCLK_GMAC0_RX_TX] = MUX(SCLK_GMAC0_RX_TX, "clk_gmac0_rx_tx", mux_gmac0_rx_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(31), 0, 2, MFLAGS), + [SCLK_GMAC1] = MUX(SCLK_GMAC1, "clk_gmac1", mux_gmac1_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(33), 2, 1, MFLAGS), + [SCLK_GMAC1_RGMII_SPEED] = MUX(SCLK_GMAC1_RGMII_SPEED, "clk_gmac1_rgmii_speed", mux_gmac1_rgmii_speed_p, 0, + RK3568_CLKSEL_CON(33), 4, 2, MFLAGS), + [SCLK_GMAC1_RMII_SPEED] = MUX(SCLK_GMAC1_RMII_SPEED, "clk_gmac1_rmii_speed", mux_gmac1_rmii_speed_p, 0, + RK3568_CLKSEL_CON(33), 3, 1, MFLAGS), + [SCLK_GMAC1_RX_TX] = MUX(SCLK_GMAC1_RX_TX, "clk_gmac1_rx_tx", mux_gmac1_rx_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_CLKSEL_CON(33), 0, 2, MFLAGS), + [SCLK_SDMMC0_DRV] = MMC(SCLK_SDMMC0_DRV, "sdmmc0_drv", "clk_sdmmc0", RK3568_SDMMC0_CON0, 1), + [SCLK_SDMMC0_SAMPLE] = MMC(SCLK_SDMMC0_SAMPLE, "sdmmc0_sample", "clk_sdmmc0", RK3568_SDMMC0_CON1, 1), + [SCLK_SDMMC1_DRV] = MMC(SCLK_SDMMC1_DRV, "sdmmc1_drv", "clk_sdmmc1", RK3568_SDMMC1_CON0, 1), + [SCLK_SDMMC1_SAMPLE] = MMC(SCLK_SDMMC1_SAMPLE, "sdmmc1_sample", "clk_sdmmc1", RK3568_SDMMC1_CON1, 1), + [SCLK_SDMMC2_DRV] = MMC(SCLK_SDMMC2_DRV, "sdmmc2_drv", "clk_sdmmc2", RK3568_SDMMC2_CON0, 1), + [SCLK_SDMMC2_SAMPLE] = MMC(SCLK_SDMMC2_SAMPLE, "sdmmc2_sample", "clk_sdmmc2", RK3568_SDMMC2_CON1, 1), + [SCLK_EMMC_DRV] = MMC(SCLK_EMMC_DRV, "emmc_drv", "cclk_emmc", RK3568_EMMC_CON0, 1), + [SCLK_EMMC_SAMPLE] = MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "cclk_emmc", RK3568_EMMC_CON1, 1), + [PCLK_EDPPHY_GRF] = GATE(PCLK_EDPPHY_GRF, "pclk_edpphy_grf", "pclk_top", 0, RK3568_CLKGATE_CON(34), 14, GFLAGS), + [CLK_HDMI_CEC] = GATE(CLK_HDMI_CEC, "clk_hdmi_cec", "clk_rtc_32k", 0, RK3568_CLKGATE_CON(21), 5, GFLAGS), + [CLK_I2S0_8CH_TX] = &rk3568_i2s0_8ch_tx_fracmux.cell, + [CLK_I2S0_8CH_RX] = &rk3568_i2s0_8ch_rx_fracmux.cell, + [CLK_I2S1_8CH_TX] = &rk3568_i2s1_8ch_tx_fracmux.cell, + [CLK_I2S1_8CH_RX] = &rk3568_i2s1_8ch_rx_fracmux.cell, + [CLK_I2S2_2CH] = &rk3568_i2s2_2ch_fracmux.cell, + [CLK_I2S3_2CH_TX] = &rk3568_i2s3_2ch_tx_fracmux.cell, + [CLK_I2S3_2CH_RX] = &rk3568_i2s3_2ch_rx_fracmux.cell, + [CPLL_500M] = COMPOSITE_NOMUX(CPLL_500M, "cpll_500m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(78), 8, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 7, GFLAGS), + [CPLL_250M] = COMPOSITE_NOMUX(CPLL_250M, "cpll_250m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(79), 8, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 9, GFLAGS), + [CPLL_125M] = COMPOSITE_NOMUX(CPLL_125M, "cpll_125m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(80), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 10, GFLAGS), + [CPLL_62P5M] = COMPOSITE_NOMUX(CPLL_62P5M, "cpll_62p5", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(80), 8, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 12, GFLAGS), + [CPLL_50M] = COMPOSITE_NOMUX(CPLL_50M, "cpll_50m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(81), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 13, GFLAGS), + [CPLL_25M] = COMPOSITE_NOMUX(CPLL_25M, "cpll_25m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(81), 8, 6, DFLAGS, + RK3568_CLKGATE_CON(35), 14, GFLAGS), + [CPLL_100M] = COMPOSITE_NOMUX(CPLL_100M, "cpll_100m", "cpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(82), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 11, GFLAGS), + [I2S1_MCLKOUT] = MUXGRF(I2S1_MCLKOUT, "i2s1_mclkout", i2s1_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_GRF_SOC_CON1, 5, 1, MFLAGS), + [I2S3_MCLKOUT] = MUXGRF(I2S3_MCLKOUT, "i2s3_mclkout", i2s3_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3568_GRF_SOC_CON2, 15, 1, MFLAGS), + [I2S1_MCLK_RX_IOE] = MUXGRF(I2S1_MCLK_RX_IOE, "i2s1_mclk_rx_ioe", i2s1_mclk_rx_ioe_p, 0, + RK3568_GRF_SOC_CON2, 0, 1, MFLAGS), + [I2S1_MCLK_TX_IOE] = MUXGRF(I2S1_MCLK_TX_IOE, "i2s1_mclk_tx_ioe", i2s1_mclk_tx_ioe_p, 0, + RK3568_GRF_SOC_CON2, 1, 1, MFLAGS), + [I2S2_MCLK_IOE] = MUXGRF(I2S2_MCLK_IOE, "i2s2_mclk_ioe", i2s2_mclk_ioe_p, 0, + RK3568_GRF_SOC_CON2, 2, 1, MFLAGS), + [I2S3_MCLK_IOE] = MUXGRF(I2S3_MCLK_IOE, "i2s3_mclk_ioe", i2s3_mclk_ioe_p, 0, + RK3568_GRF_SOC_CON2, 3, 1, MFLAGS), + [PCLK_CORE_PVTM] = GATE(PCLK_CORE_PVTM, "pclk_core_pvtm", "pclk_core_pre", 0, RK3568_CLKGATE_CON(1), 9, GFLAGS), + + &rk3568_uart1_fracmux.cell, + &rk3568_uart2_fracmux.cell, + &rk3568_uart3_fracmux.cell, + &rk3568_uart4_fracmux.cell, + &rk3568_uart5_fracmux.cell, + &rk3568_uart6_fracmux.cell, + &rk3568_uart7_fracmux.cell, + &rk3568_uart8_fracmux.cell, + &rk3568_uart9_fracmux.cell, + + COMPOSITE_NOMUX(0, "gpll_400m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(75), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 0, GFLAGS), + COMPOSITE_NOMUX(0, "gpll_300m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(75), 8, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 1, GFLAGS), + COMPOSITE_NOMUX(0, "gpll_200m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(76), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 2, GFLAGS), + COMPOSITE_NOMUX(0, "gpll_150m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(76), 8, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 3, GFLAGS), + COMPOSITE_NOMUX(0, "gpll_100m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(77), 0, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 4, GFLAGS), + COMPOSITE_NOMUX(0, "gpll_75m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(77), 8, 5, DFLAGS, + RK3568_CLKGATE_CON(35), 5, GFLAGS), + COMPOSITE_NOMUX(0, "gpll_20m", "gpll", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(78), 0, 6, DFLAGS, + RK3568_CLKGATE_CON(35), 6, GFLAGS), + COMPOSITE_NOMUX(0, "clk_osc0_div_750k", "xin24m", RT_CLK_F_IGNORE_UNUSED, + RK3568_CLKSEL_CON(82), 8, 6, DFLAGS, + RK3568_CLKGATE_CON(35), 15, GFLAGS), + FACTOR(0, "clk_osc0_div_375k", "clk_osc0_div_750k", 0, 1, 2), + FACTOR(0, "xin_osc0_half", "xin24m", 0, 1, 2), + COMPOSITE(0, "sclk_core_src", apll_gpll_npll_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(2), 8, 2, MFLAGS, 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE_NODIV(0, "sclk_core", sclk_core_pre_p, RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(2), 15, 1, MFLAGS, + RK3568_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NOMUX(0, "atclk_core", "armclk", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(0, "gicclk_core", "armclk", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(3), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_NOMUX(0, "pclk_core_pre", "armclk", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(4), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NOMUX(0, "periphclk_core_pre", "armclk", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(4), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 11, GFLAGS), + COMPOSITE_NOMUX(0, "tsclk_core", "periphclk_core_pre", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(5), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 14, GFLAGS), + COMPOSITE_NOMUX(0, "cntclk_core", "periphclk_core_pre", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(5), 4, 4, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_NOMUX(0, "aclk_core", "sclk_core", RT_CLK_F_IS_CRITICAL, + RK3568_CLKSEL_CON(5), 8, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3568_CLKGATE_CON(1), 0, GFLAGS), + FACTOR(0, "clk_gmac0_tx_div5", "clk_gmac0", 0, 1, 5), + FACTOR(0, "clk_gmac0_tx_div50", "clk_gmac0", 0, 1, 50), + FACTOR(0, "clk_gmac0_rx_div2", "clk_gmac0", 0, 1, 2), + FACTOR(0, "clk_gmac0_rx_div20", "clk_gmac0", 0, 1, 20), + FACTOR(0, "clk_gmac1_tx_div5", "clk_gmac1", 0, 1, 5), + FACTOR(0, "clk_gmac1_tx_div50", "clk_gmac1", 0, 1, 50), + FACTOR(0, "clk_gmac1_rx_div2", "clk_gmac1", 0, 1, 2), + FACTOR(0, "clk_gmac1_rx_div20", "clk_gmac1", 0, 1, 20), +}; + +static rt_err_t clk_rk3568_cru_init(struct clk_rk3568_cru *cru) +{ + cru->clk_parent.cells = rk3568_clk_cells; + cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3568_clk_cells); + + return RT_EOK; +} + +static rt_err_t clk_rk3568_pmucru_init(struct clk_rk3568_cru *cru) +{ + cru->clk_parent.cells = rk3568_clk_pmu_cells; + cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3568_clk_pmu_cells); + + return RT_EOK; +} + +static rt_err_t clk_rk3568_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + struct clk_rk3568_cru *cru = rt_calloc(1, sizeof(*cru)); + rt_err_t (*init)(struct clk_rk3568_cru *cru) = (void *)pdev->id->data; + + if (!cru) + { + return -RT_ENOMEM; + } + + cru->provider.reg_base = rt_dm_dev_iomap(dev, 0); + + if (!cru->provider.reg_base) + { + err = -RT_EIO; + goto _fail; + } + + cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf"); + cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf"); + + cru->clk_parent.dev = dev; + + if ((err = init(cru))) + { + goto _fail; + } + + rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rt_clk_register(&cru->clk_parent))) + { + goto _fail; + } + + rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL, + cru->provider.reg_base + RK3568_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK))) + { + goto _clk_unregister; + } + + rockchip_register_restart_notifier(&cru->provider, RK3568_GLB_SRST_FST, RT_NULL); + + return RT_EOK; + +_clk_unregister: + rt_clk_unregister(&cru->clk_parent); + +_fail: + if (cru->provider.reg_base) + { + rt_iounmap(cru->provider.reg_base); + } + + rt_free(cru); + + return err; +} + +static const struct rt_ofw_node_id clk_rk3568_ofw_ids[] = +{ + { .compatible = "rockchip,rk3568-cru", .data = (void *)clk_rk3568_cru_init }, + { .compatible = "rockchip,rk3568-pmucru", .data = (void *)clk_rk3568_pmucru_init }, + { /* sentinel */ } +}; + +static struct rt_platform_driver clk_rk3568_driver = +{ + .name = "clk-rk3568", + .ids = clk_rk3568_ofw_ids, + + .probe = clk_rk3568_probe, +}; + +static int clk_rk3568_register(void) +{ + rt_platform_driver_register(&clk_rk3568_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(clk_rk3568_register); diff --git a/bsp/rockchip/dm/clk/clk-rk3576.c b/bsp/rockchip/dm/clk/clk-rk3576.c new file mode 100755 index 00000000000..b5853ff3eae --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk3576.c @@ -0,0 +1,1839 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-composite.h" +#include "clk-rk-cpu.h" +#include "clk-rk-divider.h" +#include "clk-rk-factor.h" +#include "clk-rk-fraction-divider.h" +#include "clk-rk-gate.h" +#include "clk-rk.h" +#include "clk-rk-half-divider.h" +#include "clk-rk-mmc-phase.h" +#include "clk-rk-muxgrf.h" +#include "clk-rk-mux.h" +#include "clk-rk-pll.h" + +#define DBG_TAG "clk.rk3576" +#define DBG_LVL DBG_INFO +#include + +#include + +#define RK3576_GRF_SOC_STATUS0 0x600 +#define RK3576_PMU0_GRF_OSC_CON6 0x18 + +#define RK3576_PHP_CRU_BASE 0x8000 +#define RK3576_SECURE_NS_CRU_BASE 0x10000 +#define RK3576_PMU_CRU_BASE 0x20000 +#define RK3576_BIGCORE_CRU_BASE 0x38000 +#define RK3576_LITCORE_CRU_BASE 0x40000 +#define RK3576_CCI_CRU_BASE 0x48000 + +#define RK3576_PLL_CON(x) ((x) * 0x4) +#define RK3576_MODE_CON0 0x280 +#define RK3576_BPLL_MODE_CON0 (RK3576_BIGCORE_CRU_BASE + 0x280) +#define RK3576_LPLL_MODE_CON0 (RK3576_LITCORE_CRU_BASE + 0x280) +#define RK3576_PPLL_MODE_CON0 (RK3576_PHP_CRU_BASE + 0x280) +#define RK3576_CLKSEL_CON(x) ((x) * 0x4 + 0x300) +#define RK3576_CLKGATE_CON(x) ((x) * 0x4 + 0x800) +#define RK3576_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) +#define RK3576_GLB_CNT_TH 0xc00 +#define RK3576_GLB_SRST_FST 0xc08 +#define RK3576_GLB_SRST_SND 0xc0c +#define RK3576_GLB_RST_CON 0xc10 +#define RK3576_GLB_RST_ST 0xc04 +#define RK3576_SDIO_CON0 0xc24 +#define RK3576_SDIO_CON1 0xc28 +#define RK3576_SDMMC_CON0 0xc30 +#define RK3576_SDMMC_CON1 0xc34 + +#define RK3576_PHP_CLKSEL_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0x300) +#define RK3576_PHP_CLKGATE_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0x800) +#define RK3576_PHP_SOFTRST_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0xa00) + +#define RK3576_PMU_PLL_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE) +#define RK3576_PMU_CLKSEL_CON(x) ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0x300) +#define RK3576_PMU_CLKGATE_CON(x) ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0x800) +#define RK3576_PMU_SOFTRST_CON(x) ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0xa00) + +#define RK3576_SECURE_NS_CLKSEL_CON(x) ((x) * 0x4 + RK3576_SECURE_NS_CRU_BASE + 0x300) +#define RK3576_SECURE_NS_CLKGATE_CON(x) ((x) * 0x4 + RK3576_SECURE_NS_CRU_BASE + 0x800) +#define RK3576_SECURE_NS_SOFTRST_CON(x) ((x) * 0x4 + RK3576_SECURE_NS_CRU_BASE + 0xa00) + +#define RK3576_CCI_CLKSEL_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0x300) +#define RK3576_CCI_CLKGATE_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0x800) +#define RK3576_CCI_SOFTRST_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0xa00) + +#define RK3576_BPLL_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE) +#define RK3576_BIGCORE_CLKSEL_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0x300) +#define RK3576_BIGCORE_CLKGATE_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0x800) +#define RK3576_BIGCORE_SOFTRST_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0xa00) +#define RK3576_LPLL_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE) +#define RK3576_LITCORE_CLKSEL_CON(x) ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0x300) +#define RK3576_LITCORE_CLKGATE_CON(x) ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0x800) +#define RK3576_LITCORE_SOFTRST_CON(x) ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0xa00) +#define RK3576_NON_SECURE_GATING_CON00 0xc48 + +#define RK3576_ACLK_M_BIGCORE_DIV_MASK 0x1f +#define RK3576_ACLK_M_BIGCORE_DIV_SHIFT 0 +#define RK3576_ACLK_M_LITCORE_DIV_MASK 0x1f +#define RK3576_ACLK_M_LITCORE_DIV_SHIFT 8 +#define RK3576_PCLK_DBG_LITCORE_DIV_MASK 0x1f +#define RK3576_PCLK_DBG_LITCORE_DIV_SHIFT 0 +#define RK3576_ACLK_CCI_DIV_MASK 0x1f +#define RK3576_ACLK_CCI_DIV_SHIFT 7 +#define RK3576_ACLK_CCI_MUX_MASK 0x3 +#define RK3576_ACLK_CCI_MUX_SHIFT 12 + +struct clk_rk3576_cru +{ + struct rt_clk_node clk_parent; + struct rt_reset_controller rstc_parent; + + struct rockchip_clk_provider provider; +}; + +static struct rockchip_pll_rate_table rk3576_pll_rates[] = +{ + /* _mhz, _p, _m, _s, _k */ + RK3588_PLL_RATE(2520000000, 2, 210, 0, 0), + RK3588_PLL_RATE(2496000000, 2, 208, 0, 0), + RK3588_PLL_RATE(2472000000, 2, 206, 0, 0), + RK3588_PLL_RATE(2448000000, 2, 204, 0, 0), + RK3588_PLL_RATE(2424000000, 2, 202, 0, 0), + RK3588_PLL_RATE(2400000000, 2, 200, 0, 0), + RK3588_PLL_RATE(2376000000, 2, 198, 0, 0), + RK3588_PLL_RATE(2352000000, 2, 196, 0, 0), + RK3588_PLL_RATE(2328000000, 2, 194, 0, 0), + RK3588_PLL_RATE(2304000000, 2, 192, 0, 0), + RK3588_PLL_RATE(2280000000, 2, 190, 0, 0), + RK3588_PLL_RATE(2256000000, 2, 376, 1, 0), + RK3588_PLL_RATE(2232000000, 2, 372, 1, 0), + RK3588_PLL_RATE(2208000000, 2, 368, 1, 0), + RK3588_PLL_RATE(2184000000, 2, 364, 1, 0), + RK3588_PLL_RATE(2160000000, 2, 360, 1, 0), + RK3588_PLL_RATE(2136000000, 2, 356, 1, 0), + RK3588_PLL_RATE(2112000000, 2, 352, 1, 0), + RK3588_PLL_RATE(2088000000, 2, 348, 1, 0), + RK3588_PLL_RATE(2064000000, 2, 344, 1, 0), + RK3588_PLL_RATE(2040000000, 2, 340, 1, 0), + RK3588_PLL_RATE(2016000000, 2, 336, 1, 0), + RK3588_PLL_RATE(1992000000, 2, 332, 1, 0), + RK3588_PLL_RATE(1968000000, 2, 328, 1, 0), + RK3588_PLL_RATE(1944000000, 2, 324, 1, 0), + RK3588_PLL_RATE(1920000000, 2, 320, 1, 0), + RK3588_PLL_RATE(1896000000, 2, 316, 1, 0), + RK3588_PLL_RATE(1872000000, 2, 312, 1, 0), + RK3588_PLL_RATE(1848000000, 2, 308, 1, 0), + RK3588_PLL_RATE(1824000000, 2, 304, 1, 0), + RK3588_PLL_RATE(1800000000, 2, 300, 1, 0), + RK3588_PLL_RATE(1776000000, 2, 296, 1, 0), + RK3588_PLL_RATE(1752000000, 2, 292, 1, 0), + RK3588_PLL_RATE(1728000000, 2, 288, 1, 0), + RK3588_PLL_RATE(1704000000, 2, 284, 1, 0), + RK3588_PLL_RATE(1680000000, 2, 280, 1, 0), + RK3588_PLL_RATE(1656000000, 2, 276, 1, 0), + RK3588_PLL_RATE(1632000000, 2, 272, 1, 0), + RK3588_PLL_RATE(1608000000, 2, 268, 1, 0), + RK3588_PLL_RATE(1584000000, 2, 264, 1, 0), + RK3588_PLL_RATE(1560000000, 2, 260, 1, 0), + RK3588_PLL_RATE(1536000000, 2, 256, 1, 0), + RK3588_PLL_RATE(1512000000, 2, 252, 1, 0), + RK3588_PLL_RATE(1488000000, 2, 248, 1, 0), + RK3588_PLL_RATE(1464000000, 2, 244, 1, 0), + RK3588_PLL_RATE(1440000000, 2, 240, 1, 0), + RK3588_PLL_RATE(1416000000, 2, 236, 1, 0), + RK3588_PLL_RATE(1392000000, 2, 232, 1, 0), + RK3588_PLL_RATE(1320000000, 2, 220, 1, 0), + RK3588_PLL_RATE(1200000000, 2, 200, 1, 0), + RK3588_PLL_RATE(1188000000, 2, 198, 1, 0), + RK3588_PLL_RATE(1186814000, 2, 198, 1, 52581), + RK3588_PLL_RATE(1186812000, 2, 198, 1, 52559), + RK3588_PLL_RATE(1109000000, 3, 554, 2, 32767), + RK3588_PLL_RATE(1100000000, 3, 550, 2, 0), + RK3588_PLL_RATE(1051000000, 3, 525, 2, 32767), + RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), + RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), + RK3588_PLL_RATE(983040000, 4, 655, 2, 23592), + RK3588_PLL_RATE(955520000, 3, 477, 2, 49806), + RK3588_PLL_RATE(903168000, 6, 903, 2, 11009), + RK3588_PLL_RATE(900000000, 2, 300, 2, 0), + RK3588_PLL_RATE(816000000, 2, 272, 2, 0), + RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), + RK3588_PLL_RATE(786000000, 1, 131, 2, 0), + RK3588_PLL_RATE(785560000, 3, 392, 2, 51117), + RK3588_PLL_RATE(773000000, 2, 258, 2, 43690), + RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), + RK3588_PLL_RATE(697000000, 2, 232, 2, 21845), + RK3588_PLL_RATE(610400000, 3, 305, 2, 13107), + RK3588_PLL_RATE(604800000, 1, 101, 2, 52428), + RK3588_PLL_RATE(600000000, 2, 200, 2, 0), + RK3588_PLL_RATE(594000000, 2, 198, 2, 0), + RK3588_PLL_RATE(408000000, 2, 272, 3, 0), + RK3588_PLL_RATE(312000000, 2, 208, 3, 0), + RK3588_PLL_RATE(266580000, 1, 178, 4, 47185), + RK3588_PLL_RATE(216000000, 2, 288, 4, 0), + RK3588_PLL_RATE(96000000, 2, 256, 5, 0), + { /* sentinel */ }, +}; + +static struct rockchip_pll_rate_table rk3576_ppll_rates[] = +{ + /* _mhz, _p, _m, _s, _k */ + RK3588_PLL_RATE(1300000000, 3, 325, 2, 0), + { /* sentinel */ }, +}; + +#define RK3576_BIGCORE_CLKSEL2(_amcore) \ +{ \ + .reg = RK3576_BIGCORE_CLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_amcore - 1, RK3576_ACLK_M_BIGCORE_DIV_MASK, \ + RK3576_ACLK_M_BIGCORE_DIV_SHIFT), \ +} + +#define RK3576_LITCORE_CLKSEL1(_amcore) \ +{ \ + .reg = RK3576_LITCORE_CLKSEL_CON(1), \ + .val = HIWORD_UPDATE(_amcore - 1, RK3576_ACLK_M_LITCORE_DIV_MASK, \ + RK3576_ACLK_M_LITCORE_DIV_SHIFT), \ +} + +#define RK3576_LITCORE_CLKSEL2(_pclkdbg) \ +{ \ + .reg = RK3576_LITCORE_CLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_pclkdbg - 1, RK3576_PCLK_DBG_LITCORE_DIV_MASK,\ + RK3576_PCLK_DBG_LITCORE_DIV_SHIFT), \ +} + +#define RK3576_CCI_CLKSEL4(_ccisel, _div) \ +{ \ + .reg = RK3576_CCI_CLKSEL_CON(4), \ + .val = HIWORD_UPDATE(_ccisel, RK3576_ACLK_CCI_MUX_MASK, \ + RK3576_ACLK_CCI_MUX_SHIFT) | \ + HIWORD_UPDATE(_div - 1, RK3576_ACLK_CCI_DIV_MASK, \ + RK3576_ACLK_CCI_DIV_SHIFT), \ +} + +#define RK3576_CPUBCLK_RATE(_prate, _amcore) \ +{ \ + .prate = _prate##U, \ + .divs = \ + { \ + RK3576_BIGCORE_CLKSEL2(_amcore), \ + }, \ +} + +#define RK3576_CPULCLK_RATE(_prate, _amcore, _pclkdbg, _ccisel) \ +{ \ + .prate = _prate##U, \ + .divs = \ + { \ + RK3576_LITCORE_CLKSEL1(_amcore), \ + RK3576_LITCORE_CLKSEL2(_pclkdbg), \ + }, \ + .pre_muxs = \ + { \ + RK3576_CCI_CLKSEL4(2, 2), \ + }, \ + .post_muxs = \ + { \ + RK3576_CCI_CLKSEL4(_ccisel, 2), \ + }, \ +} + +static struct rockchip_cpu_clk_rate_table rk3576_cpubclk_rates[] = +{ + RK3576_CPUBCLK_RATE(2496000000, 2), + RK3576_CPUBCLK_RATE(2400000000, 2), + RK3576_CPUBCLK_RATE(2304000000, 2), + RK3576_CPUBCLK_RATE(2208000000, 2), + RK3576_CPUBCLK_RATE(2184000000, 2), + RK3576_CPUBCLK_RATE(2088000000, 2), + RK3576_CPUBCLK_RATE(2040000000, 2), + RK3576_CPUBCLK_RATE(2016000000, 2), + RK3576_CPUBCLK_RATE(1992000000, 2), + RK3576_CPUBCLK_RATE(1896000000, 2), + RK3576_CPUBCLK_RATE(1800000000, 2), + RK3576_CPUBCLK_RATE(1704000000, 2), + RK3576_CPUBCLK_RATE(1608000000, 2), + RK3576_CPUBCLK_RATE(1584000000, 2), + RK3576_CPUBCLK_RATE(1560000000, 2), + RK3576_CPUBCLK_RATE(1536000000, 2), + RK3576_CPUBCLK_RATE(1512000000, 2), + RK3576_CPUBCLK_RATE(1488000000, 2), + RK3576_CPUBCLK_RATE(1464000000, 2), + RK3576_CPUBCLK_RATE(1440000000, 2), + RK3576_CPUBCLK_RATE(1416000000, 2), + RK3576_CPUBCLK_RATE(1392000000, 2), + RK3576_CPUBCLK_RATE(1368000000, 2), + RK3576_CPUBCLK_RATE(1344000000, 2), + RK3576_CPUBCLK_RATE(1320000000, 2), + RK3576_CPUBCLK_RATE(1296000000, 2), + RK3576_CPUBCLK_RATE(1272000000, 2), + RK3576_CPUBCLK_RATE(1248000000, 2), + RK3576_CPUBCLK_RATE(1224000000, 2), + RK3576_CPUBCLK_RATE(1200000000, 2), + RK3576_CPUBCLK_RATE(1104000000, 2), + RK3576_CPUBCLK_RATE(1008000000, 2), + RK3576_CPUBCLK_RATE(912000000, 2), + RK3576_CPUBCLK_RATE(816000000, 2), + RK3576_CPUBCLK_RATE(696000000, 2), + RK3576_CPUBCLK_RATE(600000000, 2), + RK3576_CPUBCLK_RATE(408000000, 2), + RK3576_CPUBCLK_RATE(312000000, 2), + RK3576_CPUBCLK_RATE(216000000, 2), + RK3576_CPUBCLK_RATE(96000000, 2), +}; + +static const struct rockchip_cpu_clk_reg_data rk3576_cpubclk_data = +{ + .core_reg[0] = RK3576_BIGCORE_CLKSEL_CON(1), + .div_core_shift[0] = 7, + .div_core_mask[0] = 0x1f, + .num_cores = 1, + .mux_core_alt = 1, + .mux_core_main = 0, + .mux_core_shift = 12, + .mux_core_mask = 0x3, +}; + +static struct rockchip_cpu_clk_rate_table rk3576_cpulclk_rates[] = +{ + RK3576_CPULCLK_RATE(2400000000, 2, 6, 3), + RK3576_CPULCLK_RATE(2304000000, 2, 6, 3), + RK3576_CPULCLK_RATE(2208000000, 2, 6, 3), + RK3576_CPULCLK_RATE(2184000000, 2, 6, 3), + RK3576_CPULCLK_RATE(2088000000, 2, 6, 3), + RK3576_CPULCLK_RATE(2040000000, 2, 6, 3), + RK3576_CPULCLK_RATE(2016000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1992000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1896000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1800000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1704000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1608000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1584000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1560000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1536000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1512000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1488000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1464000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1440000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1416000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1392000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1368000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1344000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1320000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1296000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1272000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1248000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1224000000, 2, 6, 3), + RK3576_CPULCLK_RATE(1200000000, 2, 6, 2), + RK3576_CPULCLK_RATE(1104000000, 2, 6, 2), + RK3576_CPULCLK_RATE(1008000000, 2, 6, 2), + RK3576_CPULCLK_RATE(912000000, 2, 6, 2), + RK3576_CPULCLK_RATE(816000000, 2, 6, 2), + RK3576_CPULCLK_RATE(696000000, 2, 6, 2), + RK3576_CPULCLK_RATE(600000000, 2, 6, 2), + RK3576_CPULCLK_RATE(408000000, 2, 6, 2), + RK3576_CPULCLK_RATE(312000000, 2, 6, 2), + RK3576_CPULCLK_RATE(216000000, 2, 6, 2), + RK3576_CPULCLK_RATE(96000000, 2, 6, 2), +}; + +static const struct rockchip_cpu_clk_reg_data rk3576_cpulclk_data = +{ + .core_reg[0] = RK3576_LITCORE_CLKSEL_CON(0), + .div_core_shift[0] = 7, + .div_core_mask[0] = 0x1f, + .num_cores = 1, + .mux_core_alt = 1, + .mux_core_main = 0, + .mux_core_shift = 12, + .mux_core_mask = 0x3, +}; + +PNAMES(mux_pll_p) = { "xin24m", "xin32k" }; +PNAMES(mux_24m_32k_p) = { "xin24m", "xin_osc0_div" }; +PNAMES(gpll_24m_p) = { "gpll", "xin24m" }; +PNAMES(cpll_24m_p) = { "cpll", "xin24m" }; +PNAMES(gpll_cpll_p) = { "gpll", "cpll" }; +PNAMES(gpll_spll_p) = { "gpll", "spll" }; +PNAMES(gpll_cpll_aupll_p) = { "gpll", "cpll", "aupll" }; +PNAMES(gpll_cpll_24m_p) = { "gpll", "cpll", "xin24m" }; +PNAMES(gpll_cpll_24m_spll_p) = { "gpll", "cpll", "xin24m", "spll" }; +PNAMES(gpll_cpll_aupll_24m_p) = { "gpll", "cpll", "aupll", "xin24m" }; +PNAMES(gpll_cpll_aupll_spll_p) = { "gpll", "cpll", "aupll", "spll" }; +PNAMES(gpll_cpll_aupll_spll_lpll_p) = { "gpll", "cpll", "aupll", "spll", "lpll_dummy" }; +PNAMES(gpll_cpll_spll_bpll_p) = { "gpll", "cpll", "spll", "bpll_dummy" }; +PNAMES(gpll_cpll_lpll_bpll_p) = { "gpll", "cpll", "lpll_dummy", "bpll_dummy" }; +PNAMES(gpll_spll_cpll_bpll_lpll_p) = { "gpll", "spll", "cpll", "bpll_dummy", "lpll_dummy" }; +PNAMES(gpll_cpll_vpll_aupll_24m_p) = { "gpll", "cpll", "vpll", "aupll", "xin24m" }; +PNAMES(gpll_cpll_spll_aupll_bpll_p) = { "gpll", "cpll", "spll", "aupll", "bpll_dummy" }; +PNAMES(gpll_cpll_spll_bpll_lpll_p) = { "gpll", "cpll", "spll", "bpll_dummy", "lpll_dummy" }; +PNAMES(gpll_cpll_spll_lpll_bpll_p) = { "gpll", "cpll", "spll", "lpll_dummy", "bpll_dummy" }; +PNAMES(gpll_cpll_vpll_bpll_lpll_p) = { "gpll", "cpll", "vpll", "bpll_dummy", "lpll_dummy" }; +PNAMES(gpll_spll_aupll_bpll_lpll_p) = { "gpll", "spll", "aupll", "bpll_dummy", "lpll_dummy" }; +PNAMES(gpll_spll_isppvtpll_bpll_lpll_p) = { "gpll", "spll", "isp_pvtpll", "bpll_dummy", "lpll_dummy" }; +PNAMES(gpll_cpll_spll_aupll_lpll_24m_p) = { "gpll", "cpll", "spll", "aupll", "lpll_dummy", "xin24m" }; +PNAMES(gpll_cpll_spll_vpll_bpll_lpll_p) = { "gpll", "cpll", "spll", "vpll", "bpll_dummy", "lpll_dummy" }; +PNAMES(cpll_vpll_lpll_bpll_p) = { "cpll", "vpll", "lpll_dummy", "bpll_dummy" }; +PNAMES(mux_24m_ccipvtpll_gpll_lpll_p) = { "xin24m", "cci_pvtpll", "gpll", "lpll" }; +PNAMES(mux_24m_spll_gpll_cpll_p) = {"xin24m", "spll", "gpll", "cpll" }; +PNAMES(audio_frac_int_p) = { "xin24m", "clk_audio_frac_0", "clk_audio_frac_1", "clk_audio_frac_2", "clk_audio_frac_3", "clk_audio_int_0", "clk_audio_int_1", "clk_audio_int_2" }; +PNAMES(audio_frac_p) = { "clk_audio_frac_0", "clk_audio_frac_1", "clk_audio_frac_2", "clk_audio_frac_3" }; +PNAMES(mux_100m_24m_p) = { "clk_cpll_div10", "xin24m" }; +PNAMES(mux_100m_50m_24m_p) = { "clk_cpll_div10", "clk_cpll_div20", "xin24m" }; +PNAMES(mux_100m_24m_lclk0_p) = { "clk_cpll_div10", "xin24m", "lclk_asrc_src_0" }; +PNAMES(mux_100m_24m_lclk1_p) = { "clk_cpll_div10", "xin24m", "lclk_asrc_src_1" }; +PNAMES(mux_150m_100m_50m_24m_p) = { "clk_gpll_div8", "clk_cpll_div10", "clk_cpll_div20", "xin24m" }; +PNAMES(mux_200m_100m_50m_24m_p) = { "clk_gpll_div6", "clk_cpll_div10", "clk_cpll_div20", "xin24m" }; +PNAMES(mux_400m_200m_100m_24m_p) = { "clk_gpll_div3", "clk_gpll_div6", "clk_cpll_div10", "xin24m" }; +PNAMES(mux_500m_250m_100m_24m_p) = { "clk_cpll_div2", "clk_cpll_div4", "clk_cpll_div10", "xin24m" }; +PNAMES(mux_600m_400m_300m_24m_p) = { "clk_gpll_div2", "clk_gpll_div3", "clk_gpll_div4", "xin24m" }; +PNAMES(mux_350m_175m_116m_24m_p) = { "clk_spll_div2", "clk_spll_div4", "clk_spll_div6", "xin24m" }; +PNAMES(mux_175m_116m_58m_24m_p) = { "clk_spll_div4", "clk_spll_div6", "clk_spll_div12", "xin24m" }; +PNAMES(mux_116m_58m_24m_p) = { "clk_spll_div6", "clk_spll_div12", "xin24m" }; +PNAMES(mclk_sai0_8ch_p) = { "mclk_sai0_8ch_src", "sai0_mclkin", "sai1_mclkin" }; +PNAMES(mclk_sai1_8ch_p) = { "mclk_sai1_8ch_src", "sai1_mclkin" }; +PNAMES(mclk_sai2_2ch_p) = { "mclk_sai2_2ch_src", "sai2_mclkin", "sai1_mclkin" }; +PNAMES(mclk_sai3_2ch_p) = { "mclk_sai3_2ch_src", "sai3_mclkin", "sai1_mclkin" }; +PNAMES(mclk_sai4_2ch_p) = { "mclk_sai4_2ch_src", "sai4_mclkin", "sai1_mclkin" }; +PNAMES(mclk_sai5_8ch_p) = { "mclk_sai5_8ch_src", "sai1_mclkin" }; +PNAMES(mclk_sai6_8ch_p) = { "mclk_sai6_8ch_src", "sai1_mclkin" }; +PNAMES(mclk_sai7_8ch_p) = { "mclk_sai7_8ch_src", "sai1_mclkin" }; +PNAMES(mclk_sai8_8ch_p) = { "mclk_sai8_8ch_src", "sai1_mclkin" }; +PNAMES(mclk_sai9_8ch_p) = { "mclk_sai9_8ch_src", "sai1_mclkin" }; +PNAMES(uart1_p) = { "clk_uart1_src_top", "xin24m" }; +PNAMES(clk_gmac1_ptp_ref_src_p) = { "gpll", "cpll", "gmac1_ptp_refclk_in" }; +PNAMES(clk_gmac0_ptp_ref_src_p) = { "gpll", "cpll", "gmac0_ptp_refclk_in" }; +PNAMES(dclk_ebc_p) = { "gpll", "cpll", "vpll", "aupll", "lpll_dummy", "dclk_ebc_frac", "xin24m" }; +PNAMES(dclk_vp0_p) = { "dclk_vp0_src", "clk_hdmiphy_pixel0" }; +PNAMES(dclk_vp1_p) = { "dclk_vp1_src", "clk_hdmiphy_pixel0" }; +PNAMES(dclk_vp2_p) = { "dclk_vp2_src", "clk_hdmiphy_pixel0" }; +PNAMES(clk_uart_p) = { "gpll", "cpll", "aupll", "xin24m", "clk_uart_frac_0", "clk_uart_frac_1", "clk_uart_frac_2"}; +PNAMES(clk_freq_pwm1_p) = { "sai0_mclkin", "sai1_mclkin", "sai2_mclkin", "sai3_mclkin", "sai4_mclkin", "sai_sclkin_freq"}; +PNAMES(clk_counter_pwm1_p) = { "sai0_mclkin", "sai1_mclkin", "sai2_mclkin", "sai3_mclkin", "sai4_mclkin", "sai_sclkin_counter"}; +PNAMES(sai_sclkin_freq_p) = { "sai0_sclk_in", "sai1_sclk_in", "sai2_sclk_in", "sai3_sclk_in", "sai4_sclk_in"}; +PNAMES(clk_ref_pcie0_phy_p) = { "clk_pcie_100m_src", "clk_pcie_100m_nduty_src", "xin24m"}; +PNAMES(hclk_vi_root_p) = { "clk_gpll_div6", "clk_cpll_div10", "aclk_vi_root_inter", "xin24m"}; +PNAMES(clk_ref_osc_mphy_p) = { "xin24m", "clk_gpio_mphy_i", "clk_ref_mphy_26m"}; +PNAMES(mux_pmu200m_pmu100m_pmu50m_24m_p) = { "clk_200m_pmu_src", "clk_100m_pmu_src", "clk_50m_pmu_src", "xin24m" }; +PNAMES(mux_pmu100m_pmu50m_24m_p) = { "clk_100m_pmu_src", "clk_50m_pmu_src", "xin24m" }; +PNAMES(mux_pmu100m_24m_32k_p) = { "clk_100m_pmu_src", "xin24m", "xin_osc0_div" }; +PNAMES(clk_phy_ref_src_p) = { "xin24m", "clk_pmuphy_ref_src" }; +PNAMES(clk_usbphy_ref_src_p) = { "usbphy0_24m", "usbphy1_24m" }; +PNAMES(clk_cpll_ref_src_p) = { "xin24m", "clk_usbphy_ref_src" }; +PNAMES(clk_aupll_ref_src_p) = { "xin24m", "clk_aupll_ref_io" }; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_pll_clk_cell rk3576_pll_bpll = + PLL_RAW(pll_type_rk3588_core, PLL_BPLL, "bpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_PLL_CON(0), RK3576_BPLL_MODE_CON0, + 0, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates); +static struct rockchip_pll_clk_cell rk3576_pll_lpll = + PLL_RAW(pll_type_rk3588_core, PLL_LPLL, "lpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_LPLL_CON(16), RK3576_LPLL_MODE_CON0, + 0, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates); +static struct rockchip_pll_clk_cell rk3576_pll_vpll = + PLL_RAW(pll_type_rk3588, PLL_VPLL, "vpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_PLL_CON(88), RK3576_MODE_CON0, + 4, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates); +static struct rockchip_pll_clk_cell rk3576_pll_aupll = + PLL_RAW(pll_type_rk3588, PLL_AUPLL, "aupll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3576_PLL_CON(96), RK3576_MODE_CON0, + 6, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates); +static struct rockchip_pll_clk_cell rk3576_pll_cpll = + PLL_RAW(pll_type_rk3588, PLL_CPLL, "cpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3576_PLL_CON(104), RK3576_MODE_CON0, + 8, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates); +static struct rockchip_pll_clk_cell rk3576_pll_gpll = + PLL_RAW(pll_type_rk3588, PLL_GPLL, "gpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3576_PLL_CON(112), RK3576_MODE_CON0, + 2, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_pll_rates); +static struct rockchip_pll_clk_cell rk3576_pll_ppll = + PLL_RAW(pll_type_rk3588_ddr, PLL_PPLL, "ppll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3576_PMU_PLL_CON(128), RK3576_MODE_CON0, + 10, 15, RK3576_GRF_SOC_STATUS0, 0, rk3576_ppll_rates); + +static struct rt_clk_cell *rk3576_clk_cells[] = +{ + [PLL_BPLL] = &rk3576_pll_bpll.rk_cell.cell, + [PLL_LPLL] = &rk3576_pll_lpll.rk_cell.cell, + [PLL_VPLL] = &rk3576_pll_vpll.rk_cell.cell, + [PLL_AUPLL] = &rk3576_pll_aupll.rk_cell.cell, + [PLL_CPLL] = &rk3576_pll_cpll.rk_cell.cell, + [PLL_GPLL] = &rk3576_pll_gpll.rk_cell.cell, + [PLL_PPLL] = &rk3576_pll_ppll.rk_cell.cell, + [ARMCLK_L] = CPU(ARMCLK_L, "armclk_l", &rk3576_pll_lpll.rk_cell, &rk3576_pll_gpll.rk_cell, + rk3576_cpulclk_rates, RT_ARRAY_SIZE(rk3576_cpulclk_rates), &rk3576_cpulclk_data), + [ARMCLK_B] = CPU(ARMCLK_B, "armclk_b", &rk3576_pll_bpll.rk_cell, &rk3576_pll_gpll.rk_cell, + rk3576_cpubclk_rates, RT_ARRAY_SIZE(rk3576_cpubclk_rates), &rk3576_cpubclk_data), + [CLK_CPLL_DIV20] = COMPOSITE(CLK_CPLL_DIV20, "clk_cpll_div20", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 0, GFLAGS), + [CLK_CPLL_DIV10] = COMPOSITE(CLK_CPLL_DIV10, "clk_cpll_div10", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(0), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 1, GFLAGS), + [CLK_GPLL_DIV8] = COMPOSITE(CLK_GPLL_DIV8, "clk_gpll_div8", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 2, GFLAGS), + [CLK_GPLL_DIV6] = COMPOSITE(CLK_GPLL_DIV6, "clk_gpll_div6", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(1), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 3, GFLAGS), + [CLK_CPLL_DIV4] = COMPOSITE(CLK_CPLL_DIV4, "clk_cpll_div4", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 4, GFLAGS), + [CLK_GPLL_DIV4] = COMPOSITE(CLK_GPLL_DIV4, "clk_gpll_div4", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(2), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 5, GFLAGS), + [CLK_SPLL_DIV2] = COMPOSITE(CLK_SPLL_DIV2, "clk_spll_div2", gpll_cpll_spll_bpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(3), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 6, GFLAGS), + [CLK_GPLL_DIV3] = COMPOSITE(CLK_GPLL_DIV3, "clk_gpll_div3", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(3), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 7, GFLAGS), + [CLK_CPLL_DIV2] = COMPOSITE(CLK_CPLL_DIV2, "clk_cpll_div2", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(4), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 9, GFLAGS), + [CLK_GPLL_DIV2] = COMPOSITE(CLK_GPLL_DIV2, "clk_gpll_div2", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(5), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 10, GFLAGS), + [CLK_SPLL_DIV1] = COMPOSITE(CLK_SPLL_DIV1, "clk_spll_div1", gpll_cpll_spll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(6), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(0), 12, GFLAGS), + [PCLK_TOP_ROOT] = COMPOSITE_NODIV(PCLK_TOP_ROOT, "pclk_top_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(8), 7, 2, MFLAGS, + RK3576_CLKGATE_CON(1), 1, GFLAGS), + [ACLK_TOP] = COMPOSITE(ACLK_TOP, "aclk_top", gpll_cpll_aupll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(9), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(1), 3, GFLAGS), + [HCLK_TOP] = COMPOSITE_NODIV(HCLK_TOP, "hclk_top", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(19), 2, 2, MFLAGS, + RK3576_CLKGATE_CON(1), 14, GFLAGS), + [CLK_AUDIO_FRAC_0] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_0, "clk_audio_frac_0", "clk_audio_frac_0_src", 0, + RK3576_CLKSEL_CON(12), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(1), 10, GFLAGS), + [CLK_AUDIO_FRAC_1] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_1, "clk_audio_frac_1", "clk_audio_frac_1_src", 0, + RK3576_CLKSEL_CON(14), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(1), 11, GFLAGS), + [CLK_AUDIO_FRAC_2] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_2, "clk_audio_frac_2", "clk_audio_frac_2_src", 0, + RK3576_CLKSEL_CON(16), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(1), 12, GFLAGS), + [CLK_AUDIO_FRAC_3] = COMPOSITE_FRAC(CLK_AUDIO_FRAC_3, "clk_audio_frac_3", "clk_audio_frac_3_src", 0, + RK3576_CLKSEL_CON(18), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(1), 13, GFLAGS), + [CLK_UART_FRAC_0] = COMPOSITE_FRAC(CLK_UART_FRAC_0, "clk_uart_frac_0", "clk_uart_frac_0_src", 0, + RK3576_CLKSEL_CON(21), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(2), 5, GFLAGS), + [CLK_UART_FRAC_1] = COMPOSITE_FRAC(CLK_UART_FRAC_1, "clk_uart_frac_1", "clk_uart_frac_1_src", 0, + RK3576_CLKSEL_CON(23), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(2), 6, GFLAGS), + [CLK_UART_FRAC_2] = COMPOSITE_FRAC(CLK_UART_FRAC_2, "clk_uart_frac_2", "clk_uart_frac_2_src", 0, + RK3576_CLKSEL_CON(25), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(2), 7, GFLAGS), + [CLK_UART1_SRC_TOP] = COMPOSITE(CLK_UART1_SRC_TOP, "clk_uart1_src_top", clk_uart_p, 0, + RK3576_CLKSEL_CON(27), 13, 3, MFLAGS, 5, 8, DFLAGS, + RK3576_CLKGATE_CON(2), 13, GFLAGS), + [CLK_AUDIO_INT_0] = COMPOSITE_NOMUX(CLK_AUDIO_INT_0, "clk_audio_int_0", "gpll", 0, + RK3576_CLKSEL_CON(28), 0, 5, DFLAGS, + RK3576_CLKGATE_CON(2), 14, GFLAGS), + [CLK_AUDIO_INT_1] = COMPOSITE_NOMUX(CLK_AUDIO_INT_1, "clk_audio_int_1", "cpll", 0, + RK3576_CLKSEL_CON(28), 5, 5, DFLAGS, + RK3576_CLKGATE_CON(2), 15, GFLAGS), + [CLK_AUDIO_INT_2] = COMPOSITE_NOMUX(CLK_AUDIO_INT_2, "clk_audio_int_2", "aupll", 0, + RK3576_CLKSEL_CON(28), 10, 5, DFLAGS, + RK3576_CLKGATE_CON(3), 0, GFLAGS), + [CLK_PDM0_SRC_TOP] = COMPOSITE(CLK_PDM0_SRC_TOP, "clk_pdm0_src_top", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(29), 9, 3, MFLAGS, 0, 9, DFLAGS, + RK3576_CLKGATE_CON(3), 2, GFLAGS), + [CLK_PDM1_OUT] = GATE(CLK_PDM1_OUT, "clk_pdm1_out", "clk_pdm1", 0, + RK3576_CLKGATE_CON(3), 5, GFLAGS), + [CLK_GMAC0_125M_SRC] = COMPOSITE_NOMUX(CLK_GMAC0_125M_SRC, "clk_gmac0_125m_src", "cpll", 0, + RK3576_CLKSEL_CON(30), 10, 5, DFLAGS, + RK3576_CLKGATE_CON(3), 6, GFLAGS), + [CLK_GMAC1_125M_SRC] = COMPOSITE_NOMUX(CLK_GMAC1_125M_SRC, "clk_gmac1_125m_src", "cpll", 0, + RK3576_CLKSEL_CON(31), 0, 5, DFLAGS, + RK3576_CLKGATE_CON(3), 7, GFLAGS), + [LCLK_ASRC_SRC_0] = COMPOSITE(LCLK_ASRC_SRC_0, "lclk_asrc_src_0", audio_frac_p, 0, + RK3576_CLKSEL_CON(31), 10, 2, MFLAGS, 5, 5, DFLAGS, + RK3576_CLKGATE_CON(3), 10, GFLAGS), + [LCLK_ASRC_SRC_1] = COMPOSITE(LCLK_ASRC_SRC_1, "lclk_asrc_src_1", audio_frac_p, 0, + RK3576_CLKSEL_CON(32), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(3), 11, GFLAGS), + [REF_CLK0_OUT_PLL] = COMPOSITE(REF_CLK0_OUT_PLL, "ref_clk0_out_pll", gpll_cpll_spll_aupll_lpll_24m_p, 0, + RK3576_CLKSEL_CON(33), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(4), 1, GFLAGS), + [REF_CLK1_OUT_PLL] = COMPOSITE(REF_CLK1_OUT_PLL, "ref_clk1_out_pll", gpll_cpll_spll_aupll_lpll_24m_p, 0, + RK3576_CLKSEL_CON(34), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(4), 2, GFLAGS), + [REF_CLK2_OUT_PLL] = COMPOSITE(REF_CLK2_OUT_PLL, "ref_clk2_out_pll", gpll_cpll_spll_aupll_lpll_24m_p, 0, + RK3576_CLKSEL_CON(35), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(4), 3, GFLAGS), + [REFCLKO25M_GMAC0_OUT] = COMPOSITE(REFCLKO25M_GMAC0_OUT, "refclko25m_gmac0_out", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(36), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3576_CLKGATE_CON(5), 10, GFLAGS), + [REFCLKO25M_GMAC1_OUT] = COMPOSITE(REFCLKO25M_GMAC1_OUT, "refclko25m_gmac1_out", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(36), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3576_CLKGATE_CON(5), 11, GFLAGS), + [CLK_CIFOUT_OUT] = COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0, + RK3576_CLKSEL_CON(37), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(5), 12, GFLAGS), + [CLK_GMAC0_RMII_CRU] = GATE(CLK_GMAC0_RMII_CRU, "clk_gmac0_rmii_cru", "clk_cpll_div20", 0, + RK3576_CLKGATE_CON(5), 13, GFLAGS), + [CLK_GMAC1_RMII_CRU] = GATE(CLK_GMAC1_RMII_CRU, "clk_gmac1_rmii_cru", "clk_cpll_div20", 0, + RK3576_CLKGATE_CON(5), 14, GFLAGS), + [CLK_OTPC_AUTO_RD_G] = GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0, + RK3576_CLKGATE_CON(5), 15, GFLAGS), + [CLK_MIPI_CAMERAOUT_M0] = COMPOSITE(CLK_MIPI_CAMERAOUT_M0, "clk_mipi_cameraout_m0", mux_24m_spll_gpll_cpll_p, 0, + RK3576_CLKSEL_CON(38), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(6), 3, GFLAGS), + [CLK_MIPI_CAMERAOUT_M1] = COMPOSITE(CLK_MIPI_CAMERAOUT_M1, "clk_mipi_cameraout_m1", mux_24m_spll_gpll_cpll_p, 0, + RK3576_CLKSEL_CON(39), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(6), 4, GFLAGS), + [CLK_MIPI_CAMERAOUT_M2] = COMPOSITE(CLK_MIPI_CAMERAOUT_M2, "clk_mipi_cameraout_m2", mux_24m_spll_gpll_cpll_p, 0, + RK3576_CLKSEL_CON(40), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(6), 5, GFLAGS), + [MCLK_PDM0_SRC_TOP] = COMPOSITE(MCLK_PDM0_SRC_TOP, "mclk_pdm0_src_top", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(41), 7, 3, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(6), 8, GFLAGS), + [HCLK_AUDIO_ROOT] = COMPOSITE_NODIV(HCLK_AUDIO_ROOT, "hclk_audio_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(42), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(7), 1, GFLAGS), + [HCLK_ASRC_2CH_0] = GATE(HCLK_ASRC_2CH_0, "hclk_asrc_2ch_0", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(7), 3, GFLAGS), + [HCLK_ASRC_2CH_1] = GATE(HCLK_ASRC_2CH_1, "hclk_asrc_2ch_1", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(7), 4, GFLAGS), + [HCLK_ASRC_4CH_0] = GATE(HCLK_ASRC_4CH_0, "hclk_asrc_4ch_0", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(7), 5, GFLAGS), + [HCLK_ASRC_4CH_1] = GATE(HCLK_ASRC_4CH_1, "hclk_asrc_4ch_1", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(7), 6, GFLAGS), + [CLK_ASRC_2CH_0] = COMPOSITE(CLK_ASRC_2CH_0, "clk_asrc_2ch_0", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(42), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(7), 7, GFLAGS), + [CLK_ASRC_2CH_1] = COMPOSITE(CLK_ASRC_2CH_1, "clk_asrc_2ch_1", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(42), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3576_CLKGATE_CON(7), 8, GFLAGS), + [CLK_ASRC_4CH_0] = COMPOSITE(CLK_ASRC_4CH_0, "clk_asrc_4ch_0", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(43), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(7), 9, GFLAGS), + [CLK_ASRC_4CH_1] = COMPOSITE(CLK_ASRC_4CH_1, "clk_asrc_4ch_1", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(43), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(7), 10, GFLAGS), + [MCLK_SAI0_8CH_SRC] = COMPOSITE(MCLK_SAI0_8CH_SRC, "mclk_sai0_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(44), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(7), 11, GFLAGS), + [MCLK_SAI0_8CH] = COMPOSITE_NODIV(MCLK_SAI0_8CH, "mclk_sai0_8ch", mclk_sai0_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(44), 11, 2, MFLAGS, + RK3576_CLKGATE_CON(7), 12, GFLAGS), + [HCLK_SAI0_8CH] = GATE(HCLK_SAI0_8CH, "hclk_sai0_8ch", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(7), 13, GFLAGS), + [HCLK_SPDIF_RX0] = GATE(HCLK_SPDIF_RX0, "hclk_spdif_rx0", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(7), 14, GFLAGS), + [MCLK_SPDIF_RX0] = COMPOSITE(MCLK_SPDIF_RX0, "mclk_spdif_rx0", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(45), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(7), 15, GFLAGS), + [HCLK_SPDIF_RX1] = GATE(HCLK_SPDIF_RX1, "hclk_spdif_rx1", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(8), 0, GFLAGS), + [MCLK_SPDIF_RX1] = COMPOSITE(MCLK_SPDIF_RX1, "mclk_spdif_rx1", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(45), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(8), 1, GFLAGS), + [MCLK_SAI1_8CH_SRC] = COMPOSITE(MCLK_SAI1_8CH_SRC, "mclk_sai1_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(46), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(8), 4, GFLAGS), + [MCLK_SAI1_8CH] = COMPOSITE_NODIV(MCLK_SAI1_8CH, "mclk_sai1_8ch", mclk_sai1_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(46), 11, 1, MFLAGS, + RK3576_CLKGATE_CON(8), 5, GFLAGS), + [HCLK_SAI1_8CH] = GATE(HCLK_SAI1_8CH, "hclk_sai1_8ch", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(8), 6, GFLAGS), + [MCLK_SAI2_2CH_SRC] = COMPOSITE(MCLK_SAI2_2CH_SRC, "mclk_sai2_2ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(47), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(8), 7, GFLAGS), + [MCLK_SAI2_2CH] = COMPOSITE_NODIV(MCLK_SAI2_2CH, "mclk_sai2_2ch", mclk_sai2_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(47), 11, 2, MFLAGS, + RK3576_CLKGATE_CON(8), 8, GFLAGS), + [HCLK_SAI2_2CH] = GATE(HCLK_SAI2_2CH, "hclk_sai2_2ch", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(8), 10, GFLAGS), + [MCLK_SAI3_2CH_SRC] = COMPOSITE(MCLK_SAI3_2CH_SRC, "mclk_sai3_2ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(48), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(8), 11, GFLAGS), + [MCLK_SAI3_2CH] = COMPOSITE_NODIV(MCLK_SAI3_2CH, "mclk_sai3_2ch", mclk_sai3_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(48), 11, 2, MFLAGS, + RK3576_CLKGATE_CON(8), 12, GFLAGS), + [HCLK_SAI3_2CH] = GATE(HCLK_SAI3_2CH, "hclk_sai3_2ch", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(8), 14, GFLAGS), + [MCLK_SAI4_2CH_SRC] = COMPOSITE(MCLK_SAI4_2CH_SRC, "mclk_sai4_2ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(49), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(8), 15, GFLAGS), + [MCLK_SAI4_2CH] = COMPOSITE_NODIV(MCLK_SAI4_2CH, "mclk_sai4_2ch", mclk_sai4_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(49), 11, 2, MFLAGS, + RK3576_CLKGATE_CON(9), 0, GFLAGS), + [HCLK_SAI4_2CH] = GATE(HCLK_SAI4_2CH, "hclk_sai4_2ch", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(9), 2, GFLAGS), + [HCLK_ACDCDIG_DSM] = GATE(HCLK_ACDCDIG_DSM, "hclk_acdcdig_dsm", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(9), 3, GFLAGS), + [MCLK_ACDCDIG_DSM] = GATE(MCLK_ACDCDIG_DSM, "mclk_acdcdig_dsm", "mclk_sai4_2ch", 0, + RK3576_CLKGATE_CON(9), 4, GFLAGS), + [CLK_PDM1] = COMPOSITE(CLK_PDM1, "clk_pdm1", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(50), 9, 3, MFLAGS, 0, 9, DFLAGS, + RK3576_CLKGATE_CON(9), 5, GFLAGS), + [HCLK_PDM1] = GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(9), 7, GFLAGS), + [MCLK_PDM1] = COMPOSITE(MCLK_PDM1, "mclk_pdm1", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(51), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(9), 8, GFLAGS), + [HCLK_SPDIF_TX0] = GATE(HCLK_SPDIF_TX0, "hclk_spdif_tx0", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(9), 9, GFLAGS), + [MCLK_SPDIF_TX0] = COMPOSITE(MCLK_SPDIF_TX0, "mclk_spdif_tx0", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(52), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(9), 10, GFLAGS), + [HCLK_SPDIF_TX1] = GATE(HCLK_SPDIF_TX1, "hclk_spdif_tx1", "hclk_audio_root", 0, + RK3576_CLKGATE_CON(9), 11, GFLAGS), + [MCLK_SPDIF_TX1] = COMPOSITE(MCLK_SPDIF_TX1, "mclk_spdif_tx1", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(53), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(9), 12, GFLAGS), + [CLK_SAI1_MCLKOUT] = GATE(CLK_SAI1_MCLKOUT, "clk_sai1_mclkout", "mclk_sai1_8ch", 0, + RK3576_CLKGATE_CON(9), 13, GFLAGS), + [CLK_SAI2_MCLKOUT] = GATE(CLK_SAI2_MCLKOUT, "clk_sai2_mclkout", "mclk_sai2_2ch", 0, + RK3576_CLKGATE_CON(9), 14, GFLAGS), + [CLK_SAI3_MCLKOUT] = GATE(CLK_SAI3_MCLKOUT, "clk_sai3_mclkout", "mclk_sai3_2ch", 0, + RK3576_CLKGATE_CON(9), 15, GFLAGS), + [CLK_SAI4_MCLKOUT] = GATE(CLK_SAI4_MCLKOUT, "clk_sai4_mclkout", "mclk_sai4_2ch", 0, + RK3576_CLKGATE_CON(10), 0, GFLAGS), + [CLK_SAI0_MCLKOUT] = GATE(CLK_SAI0_MCLKOUT, "clk_sai0_mclkout", "mclk_sai0_8ch", 0, + RK3576_CLKGATE_CON(10), 1, GFLAGS), + [HCLK_BUS_ROOT] = COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(55), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(11), 0, GFLAGS), + [PCLK_BUS_ROOT] = COMPOSITE_NODIV(PCLK_BUS_ROOT, "pclk_bus_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(55), 2, 2, MFLAGS, + RK3576_CLKGATE_CON(11), 1, GFLAGS), + [ACLK_BUS_ROOT] = COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(55), 9, 1, MFLAGS, 4, 5, DFLAGS, + RK3576_CLKGATE_CON(11), 2, GFLAGS), + [HCLK_CAN0] = GATE(HCLK_CAN0, "hclk_can0", "hclk_bus_root", 0, + RK3576_CLKGATE_CON(11), 6, GFLAGS), + [CLK_CAN0] = COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(56), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(11), 7, GFLAGS), + [HCLK_CAN1] = GATE(HCLK_CAN1, "hclk_can1", "hclk_bus_root", 0, + RK3576_CLKGATE_CON(11), 8, GFLAGS), + [CLK_CAN1] = COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(56), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(11), 9, GFLAGS), + [CLK_KEY_SHIFT] = GATE(CLK_KEY_SHIFT, "clk_key_shift", "xin24m", RT_CLK_F_IS_CRITICAL, + RK3576_CLKGATE_CON(11), 15, GFLAGS), + [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 0, GFLAGS), + [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 1, GFLAGS), + [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 2, GFLAGS), + [PCLK_I2C4] = GATE(PCLK_I2C4, "pclk_i2c4", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 3, GFLAGS), + [PCLK_I2C5] = GATE(PCLK_I2C5, "pclk_i2c5", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 4, GFLAGS), + [PCLK_I2C6] = GATE(PCLK_I2C6, "pclk_i2c6", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 5, GFLAGS), + [PCLK_I2C7] = GATE(PCLK_I2C7, "pclk_i2c7", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 6, GFLAGS), + [PCLK_I2C8] = GATE(PCLK_I2C8, "pclk_i2c8", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 7, GFLAGS), + [PCLK_I2C9] = GATE(PCLK_I2C9, "pclk_i2c9", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 8, GFLAGS), + [PCLK_WDT_BUSMCU] = GATE(PCLK_WDT_BUSMCU, "pclk_wdt_busmcu", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(12), 9, GFLAGS), + [TCLK_WDT_BUSMCU] = GATE(TCLK_WDT_BUSMCU, "tclk_wdt_busmcu", "xin24m", 0, + RK3576_CLKGATE_CON(12), 10, GFLAGS), + [ACLK_GIC] = GATE(ACLK_GIC, "aclk_gic", "aclk_bus_root", RT_CLK_F_IS_CRITICAL, + RK3576_CLKGATE_CON(12), 11, GFLAGS), + [CLK_I2C1] = COMPOSITE_NODIV(CLK_I2C1, "clk_i2c1", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(12), 12, GFLAGS), + [CLK_I2C2] = COMPOSITE_NODIV(CLK_I2C2, "clk_i2c2", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 2, 2, MFLAGS, + RK3576_CLKGATE_CON(12), 13, GFLAGS), + [CLK_I2C3] = COMPOSITE_NODIV(CLK_I2C3, "clk_i2c3", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 4, 2, MFLAGS, + RK3576_CLKGATE_CON(12), 14, GFLAGS), + [CLK_I2C4] = COMPOSITE_NODIV(CLK_I2C4, "clk_i2c4", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 6, 2, MFLAGS, + RK3576_CLKGATE_CON(12), 15, GFLAGS), + [CLK_I2C5] = COMPOSITE_NODIV(CLK_I2C5, "clk_i2c5", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 8, 2, MFLAGS, + RK3576_CLKGATE_CON(13), 0, GFLAGS), + [CLK_I2C6] = COMPOSITE_NODIV(CLK_I2C6, "clk_i2c6", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 10, 2, MFLAGS, + RK3576_CLKGATE_CON(13), 1, GFLAGS), + [CLK_I2C7] = COMPOSITE_NODIV(CLK_I2C7, "clk_i2c7", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 12, 2, MFLAGS, + RK3576_CLKGATE_CON(13), 2, GFLAGS), + [CLK_I2C8] = COMPOSITE_NODIV(CLK_I2C8, "clk_i2c8", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(57), 14, 2, MFLAGS, + RK3576_CLKGATE_CON(13), 3, GFLAGS), + [CLK_I2C9] = COMPOSITE_NODIV(CLK_I2C9, "clk_i2c9", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(58), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(13), 4, GFLAGS), + [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 6, GFLAGS), + [CLK_SARADC] = COMPOSITE(CLK_SARADC, "clk_saradc", gpll_24m_p, 0, + RK3576_CLKSEL_CON(58), 12, 1, MFLAGS, 4, 8, DFLAGS, + RK3576_CLKGATE_CON(13), 7, GFLAGS), + [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 8, GFLAGS), + [CLK_TSADC] = COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m", 0, + RK3576_CLKSEL_CON(59), 0, 8, DFLAGS, + RK3576_CLKGATE_CON(13), 9, GFLAGS), + [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 10, GFLAGS), + [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 11, GFLAGS), + [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 12, GFLAGS), + [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 13, GFLAGS), + [PCLK_UART5] = GATE(PCLK_UART5, "pclk_uart5", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 14, GFLAGS), + [PCLK_UART6] = GATE(PCLK_UART6, "pclk_uart6", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(13), 15, GFLAGS), + [PCLK_UART7] = GATE(PCLK_UART7, "pclk_uart7", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(14), 0, GFLAGS), + [PCLK_UART8] = GATE(PCLK_UART8, "pclk_uart8", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(14), 1, GFLAGS), + [PCLK_UART9] = GATE(PCLK_UART9, "pclk_uart9", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(14), 2, GFLAGS), + [PCLK_UART10] = GATE(PCLK_UART10, "pclk_uart10", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(14), 3, GFLAGS), + [PCLK_UART11] = GATE(PCLK_UART11, "pclk_uart11", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(14), 4, GFLAGS), + [SCLK_UART0] = COMPOSITE(SCLK_UART0, "sclk_uart0", clk_uart_p, 0, + RK3576_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(14), 5, GFLAGS), + [SCLK_UART2] = COMPOSITE(SCLK_UART2, "sclk_uart2", clk_uart_p, 0, + RK3576_CLKSEL_CON(61), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(14), 6, GFLAGS), + [SCLK_UART3] = COMPOSITE(SCLK_UART3, "sclk_uart3", clk_uart_p, 0, + RK3576_CLKSEL_CON(62), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(14), 9, GFLAGS), + [SCLK_UART4] = COMPOSITE(SCLK_UART4, "sclk_uart4", clk_uart_p, 0, + RK3576_CLKSEL_CON(63), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(14), 12, GFLAGS), + [SCLK_UART5] = COMPOSITE(SCLK_UART5, "sclk_uart5", clk_uart_p, 0, + RK3576_CLKSEL_CON(64), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(14), 15, GFLAGS), + [SCLK_UART6] = COMPOSITE(SCLK_UART6, "sclk_uart6", clk_uart_p, 0, + RK3576_CLKSEL_CON(65), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(15), 2, GFLAGS), + [SCLK_UART7] = COMPOSITE(SCLK_UART7, "sclk_uart7", clk_uart_p, 0, + RK3576_CLKSEL_CON(66), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(15), 5, GFLAGS), + [SCLK_UART8] = COMPOSITE(SCLK_UART8, "sclk_uart8", clk_uart_p, 0, + RK3576_CLKSEL_CON(67), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(15), 8, GFLAGS), + [SCLK_UART9] = COMPOSITE(SCLK_UART9, "sclk_uart9", clk_uart_p, 0, + RK3576_CLKSEL_CON(68), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(15), 9, GFLAGS), + [SCLK_UART10] = COMPOSITE(SCLK_UART10, "sclk_uart10", clk_uart_p, 0, + RK3576_CLKSEL_CON(69), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(15), 10, GFLAGS), + [SCLK_UART11] = COMPOSITE(SCLK_UART11, "sclk_uart11", clk_uart_p, 0, + RK3576_CLKSEL_CON(70), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(15), 11, GFLAGS), + [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(15), 13, GFLAGS), + [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(15), 14, GFLAGS), + [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(15), 15, GFLAGS), + [PCLK_SPI3] = GATE(PCLK_SPI3, "pclk_spi3", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(16), 0, GFLAGS), + [PCLK_SPI4] = GATE(PCLK_SPI4, "pclk_spi4", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(16), 1, GFLAGS), + [CLK_SPI0] = COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(70), 13, 2, MFLAGS, + RK3576_CLKGATE_CON(16), 2, GFLAGS), + [CLK_SPI1] = COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(71), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(16), 3, GFLAGS), + [CLK_SPI2] = COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(71), 2, 2, MFLAGS, + RK3576_CLKGATE_CON(16), 4, GFLAGS), + [CLK_SPI3] = COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(71), 4, 2, MFLAGS, + RK3576_CLKGATE_CON(16), 5, GFLAGS), + [CLK_SPI4] = COMPOSITE_NODIV(CLK_SPI4, "clk_spi4", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(71), 6, 2, MFLAGS, + RK3576_CLKGATE_CON(16), 6, GFLAGS), + [PCLK_WDT0] = GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(16), 7, GFLAGS), + [TCLK_WDT0] = GATE(TCLK_WDT0, "tclk_wdt0", "xin24m", 0, + RK3576_CLKGATE_CON(16), 8, GFLAGS), + [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(16), 10, GFLAGS), + [CLK_PWM1] = COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(71), 8, 2, MFLAGS, + RK3576_CLKGATE_CON(16), 11, GFLAGS), + [CLK_OSC_PWM1] = GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0, + RK3576_CLKGATE_CON(16), 13, GFLAGS), + [CLK_RC_PWM1] = GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_pvtm_clkout", 0, + RK3576_CLKGATE_CON(16), 15, GFLAGS), + [PCLK_BUSTIMER0] = GATE(PCLK_BUSTIMER0, "pclk_bustimer0", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(17), 3, GFLAGS), + [PCLK_BUSTIMER1] = GATE(PCLK_BUSTIMER1, "pclk_bustimer1", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(17), 4, GFLAGS), + [CLK_TIMER0_ROOT] = COMPOSITE_NODIV(CLK_TIMER0_ROOT, "clk_timer0_root", mux_100m_24m_p, 0, + RK3576_CLKSEL_CON(71), 14, 1, MFLAGS, + RK3576_CLKGATE_CON(17), 5, GFLAGS), + [CLK_TIMER0] = GATE(CLK_TIMER0, "clk_timer0", "clk_timer0_root", 0, + RK3576_CLKGATE_CON(17), 6, GFLAGS), + [CLK_TIMER1] = GATE(CLK_TIMER1, "clk_timer1", "clk_timer0_root", 0, + RK3576_CLKGATE_CON(17), 7, GFLAGS), + [CLK_TIMER2] = GATE(CLK_TIMER2, "clk_timer2", "clk_timer0_root", 0, + RK3576_CLKGATE_CON(17), 8, GFLAGS), + [CLK_TIMER3] = GATE(CLK_TIMER3, "clk_timer3", "clk_timer0_root", 0, + RK3576_CLKGATE_CON(17), 9, GFLAGS), + [CLK_TIMER4] = GATE(CLK_TIMER4, "clk_timer4", "clk_timer0_root", 0, + RK3576_CLKGATE_CON(17), 10, GFLAGS), + [CLK_TIMER5] = GATE(CLK_TIMER5, "clk_timer5", "clk_timer0_root", 0, + RK3576_CLKGATE_CON(17), 11, GFLAGS), + [PCLK_MAILBOX0] = GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(17), 13, GFLAGS), + [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(17), 15, GFLAGS), + [DBCLK_GPIO1] = GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0, + RK3576_CLKGATE_CON(18), 0, GFLAGS), + [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(18), 1, GFLAGS), + [DBCLK_GPIO2] = GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0, + RK3576_CLKGATE_CON(18), 2, GFLAGS), + [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(18), 3, GFLAGS), + [DBCLK_GPIO3] = GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0, + RK3576_CLKGATE_CON(18), 4, GFLAGS), + [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(18), 5, GFLAGS), + [DBCLK_GPIO4] = GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0, + RK3576_CLKGATE_CON(18), 6, GFLAGS), + [ACLK_DECOM] = GATE(ACLK_DECOM, "aclk_decom", "aclk_bus_root", 0, + RK3576_CLKGATE_CON(18), 7, GFLAGS), + [PCLK_DECOM] = GATE(PCLK_DECOM, "pclk_decom", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(18), 8, GFLAGS), + [DCLK_DECOM] = COMPOSITE(DCLK_DECOM, "dclk_decom", gpll_spll_p, 0, + RK3576_CLKSEL_CON(72), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(18), 9, GFLAGS), + [CLK_TIMER1_ROOT] = COMPOSITE_NODIV(CLK_TIMER1_ROOT, "clk_timer1_root", mux_100m_24m_p, 0, + RK3576_CLKSEL_CON(72), 6, 1, MFLAGS, + RK3576_CLKGATE_CON(18), 10, GFLAGS), + [CLK_TIMER6] = GATE(CLK_TIMER6, "clk_timer6", "clk_timer1_root", 0, + RK3576_CLKGATE_CON(18), 11, GFLAGS), + [CLK_TIMER7] = COMPOSITE(CLK_TIMER7, "clk_timer7", mux_100m_24m_lclk0_p, 0, + RK3576_CLKSEL_CON(72), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(18), 12, GFLAGS), + [CLK_TIMER8] = COMPOSITE(CLK_TIMER8, "clk_timer8", mux_100m_24m_lclk1_p, 0, + RK3576_CLKSEL_CON(73), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(18), 13, GFLAGS), + [CLK_TIMER9] = GATE(CLK_TIMER9, "clk_timer9", "clk_timer1_root", 0, + RK3576_CLKGATE_CON(18), 14, GFLAGS), + [CLK_TIMER10] = GATE(CLK_TIMER10, "clk_timer10", "clk_timer1_root", 0, + RK3576_CLKGATE_CON(18), 15, GFLAGS), + [CLK_TIMER11] = GATE(CLK_TIMER11, "clk_timer11", "clk_timer1_root", 0, + RK3576_CLKGATE_CON(19), 0, GFLAGS), + [ACLK_DMAC0] = GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0, + RK3576_CLKGATE_CON(19), 1, GFLAGS), + [ACLK_DMAC1] = GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0, + RK3576_CLKGATE_CON(19), 2, GFLAGS), + [ACLK_DMAC2] = GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_bus_root", 0, + RK3576_CLKGATE_CON(19), 3, GFLAGS), + [ACLK_SPINLOCK] = GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_bus_root", 0, + RK3576_CLKGATE_CON(19), 4, GFLAGS), + [HCLK_I3C0] = GATE(HCLK_I3C0, "hclk_i3c0", "hclk_bus_root", 0, + RK3576_CLKGATE_CON(19), 7, GFLAGS), + [HCLK_I3C1] = GATE(HCLK_I3C1, "hclk_i3c1", "hclk_bus_root", 0, + RK3576_CLKGATE_CON(19), 9, GFLAGS), + [HCLK_BUS_CM0_ROOT] = COMPOSITE_NODIV(HCLK_BUS_CM0_ROOT, "hclk_bus_cm0_root", mux_400m_200m_100m_24m_p, 0, + RK3576_CLKSEL_CON(73), 13, 2, MFLAGS, + RK3576_CLKGATE_CON(19), 10, GFLAGS), + [FCLK_BUS_CM0_CORE] = GATE(FCLK_BUS_CM0_CORE, "fclk_bus_cm0_core", "hclk_bus_cm0_root", 0, + RK3576_CLKGATE_CON(19), 12, GFLAGS), + [CLK_BUS_CM0_RTC] = COMPOSITE(CLK_BUS_CM0_RTC, "clk_bus_cm0_rtc", mux_24m_32k_p, 0, + RK3576_CLKSEL_CON(74), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(19), 14, GFLAGS), + [PCLK_PMU2] = GATE(PCLK_PMU2, "pclk_pmu2", "pclk_bus_root", RT_CLK_F_IS_CRITICAL, + RK3576_CLKGATE_CON(19), 15, GFLAGS), + [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(20), 4, GFLAGS), + [CLK_PWM2] = COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(74), 6, 2, MFLAGS, + RK3576_CLKGATE_CON(20), 5, GFLAGS), + [CLK_RC_PWM2] = GATE(CLK_RC_PWM2, "clk_rc_pwm2", "clk_pvtm_clkout", 0, + RK3576_CLKGATE_CON(20), 6, GFLAGS), + [CLK_OSC_PWM2] = GATE(CLK_OSC_PWM2, "clk_osc_pwm2", "xin24m", 0, + RK3576_CLKGATE_CON(20), 7, GFLAGS), + [CLK_FREQ_PWM1] = COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_freq_pwm1_p, 0, + RK3576_CLKSEL_CON(74), 8, 3, MFLAGS, + RK3576_CLKGATE_CON(20), 8, GFLAGS), + [CLK_COUNTER_PWM1] = COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_counter_pwm1_p, 0, + RK3576_CLKSEL_CON(74), 11, 3, MFLAGS, + RK3576_CLKGATE_CON(20), 9, GFLAGS), + [SAI_SCLKIN_FREQ] = COMPOSITE_NODIV(SAI_SCLKIN_FREQ, "sai_sclkin_freq", sai_sclkin_freq_p, 0, + RK3576_CLKSEL_CON(75), 0, 3, MFLAGS, + RK3576_CLKGATE_CON(20), 10, GFLAGS), + [SAI_SCLKIN_COUNTER] = COMPOSITE_NODIV(SAI_SCLKIN_COUNTER, "sai_sclkin_counter", sai_sclkin_freq_p, 0, + RK3576_CLKSEL_CON(75), 3, 3, MFLAGS, + RK3576_CLKGATE_CON(20), 11, GFLAGS), + [CLK_I3C0] = COMPOSITE(CLK_I3C0, "clk_i3c0", gpll_cpll_aupll_spll_p, 0, + RK3576_CLKSEL_CON(78), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(20), 12, GFLAGS), + [CLK_I3C1] = COMPOSITE(CLK_I3C1, "clk_i3c1", gpll_cpll_aupll_spll_p, 0, + RK3576_CLKSEL_CON(78), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(20), 13, GFLAGS), + [PCLK_CSIDPHY1] = GATE(PCLK_CSIDPHY1, "pclk_csidphy1", "pclk_bus_root", 0, + RK3576_CLKGATE_CON(40), 2, GFLAGS), + [PCLK_DDR_ROOT] = COMPOSITE(PCLK_DDR_ROOT, "pclk_ddr_root", gpll_cpll_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(76), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(21), 0, GFLAGS), + [PCLK_DDR_MON_CH0] = GATE(PCLK_DDR_MON_CH0, "pclk_ddr_mon_ch0", "pclk_ddr_root", 0, + RK3576_CLKGATE_CON(21), 1, GFLAGS), + [HCLK_DDR_ROOT] = COMPOSITE(HCLK_DDR_ROOT, "hclk_ddr_root", gpll_cpll_p, RT_CLK_F_IGNORE_UNUSED, + RK3576_CLKSEL_CON(77), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(22), 11, GFLAGS), + [FCLK_DDR_CM0_CORE] = GATE(FCLK_DDR_CM0_CORE, "fclk_ddr_cm0_core", "hclk_ddr_root", RT_CLK_F_IS_CRITICAL, + RK3576_CLKGATE_CON(22), 15, GFLAGS), + [CLK_DDR_TIMER_ROOT] = COMPOSITE_NODIV(CLK_DDR_TIMER_ROOT, "clk_ddr_timer_root", mux_100m_24m_p, 0, + RK3576_CLKSEL_CON(77), 6, 1, MFLAGS, + RK3576_CLKGATE_CON(23), 3, GFLAGS), + [CLK_DDR_TIMER0] = GATE(CLK_DDR_TIMER0, "clk_ddr_timer0", "clk_ddr_timer_root", 0, + RK3576_CLKGATE_CON(23), 4, GFLAGS), + [CLK_DDR_TIMER1] = GATE(CLK_DDR_TIMER1, "clk_ddr_timer1", "clk_ddr_timer_root", 0, + RK3576_CLKGATE_CON(23), 5, GFLAGS), + [TCLK_WDT_DDR] = GATE(TCLK_WDT_DDR, "tclk_wdt_ddr", "xin24m", 0, + RK3576_CLKGATE_CON(23), 6, GFLAGS), + [PCLK_WDT] = GATE(PCLK_WDT, "pclk_wdt", "pclk_ddr_root", 0, + RK3576_CLKGATE_CON(23), 7, GFLAGS), + [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_ddr_root", 0, + RK3576_CLKGATE_CON(23), 8, GFLAGS), + [CLK_DDR_CM0_RTC] = COMPOSITE(CLK_DDR_CM0_RTC, "clk_ddr_cm0_rtc", mux_24m_32k_p, 0, + RK3576_CLKSEL_CON(77), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3576_CLKGATE_CON(23), 10, GFLAGS), + [ACLK_RKNN0] = GATE(ACLK_RKNN0, "aclk_rknn0", "clk_rknn_dsu0", 0, + RK3576_CLKGATE_CON(28), 9, GFLAGS), + [ACLK_RKNN1] = GATE(ACLK_RKNN1, "aclk_rknn1", "clk_rknn_dsu0", 0, + RK3576_CLKGATE_CON(29), 0, GFLAGS), + [HCLK_RKNN_ROOT] = COMPOSITE_NODIV(HCLK_RKNN_ROOT, "hclk_rknn_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(86), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(31), 4, GFLAGS), + [CLK_RKNN_DSU0] = COMPOSITE(CLK_RKNN_DSU0, "clk_rknn_dsu0", gpll_cpll_aupll_spll_p, 0, + RK3576_CLKSEL_CON(86), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(31), 5, GFLAGS), + [PCLK_NPUTOP_ROOT] = COMPOSITE_NODIV(PCLK_NPUTOP_ROOT, "pclk_nputop_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(87), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(31), 8, GFLAGS), + [PCLK_NPU_TIMER] = GATE(PCLK_NPU_TIMER, "pclk_npu_timer", "pclk_nputop_root", 0, + RK3576_CLKGATE_CON(31), 10, GFLAGS), + [CLK_NPUTIMER_ROOT] = COMPOSITE_NODIV(CLK_NPUTIMER_ROOT, "clk_nputimer_root", mux_100m_24m_p, 0, + RK3576_CLKSEL_CON(87), 2, 1, MFLAGS, + RK3576_CLKGATE_CON(31), 11, GFLAGS), + [CLK_NPUTIMER0] = GATE(CLK_NPUTIMER0, "clk_nputimer0", "clk_nputimer_root", 0, + RK3576_CLKGATE_CON(31), 12, GFLAGS), + [CLK_NPUTIMER1] = GATE(CLK_NPUTIMER1, "clk_nputimer1", "clk_nputimer_root", 0, + RK3576_CLKGATE_CON(31), 13, GFLAGS), + [PCLK_NPU_WDT] = GATE(PCLK_NPU_WDT, "pclk_npu_wdt", "pclk_nputop_root", 0, + RK3576_CLKGATE_CON(31), 14, GFLAGS), + [TCLK_NPU_WDT] = GATE(TCLK_NPU_WDT, "tclk_npu_wdt", "xin24m", 0, + RK3576_CLKGATE_CON(31), 15, GFLAGS), + [ACLK_RKNN_CBUF] = GATE(ACLK_RKNN_CBUF, "aclk_rknn_cbuf", "clk_rknn_dsu0", 0, + RK3576_CLKGATE_CON(32), 0, GFLAGS), + [HCLK_NPU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_NPU_CM0_ROOT, "hclk_npu_cm0_root", mux_400m_200m_100m_24m_p, 0, + RK3576_CLKSEL_CON(87), 3, 2, MFLAGS, + RK3576_CLKGATE_CON(32), 5, GFLAGS), + [FCLK_NPU_CM0_CORE] = GATE(FCLK_NPU_CM0_CORE, "fclk_npu_cm0_core", "hclk_npu_cm0_root", 0, + RK3576_CLKGATE_CON(32), 7, GFLAGS), + [CLK_NPU_CM0_RTC] = COMPOSITE(CLK_NPU_CM0_RTC, "clk_npu_cm0_rtc", mux_24m_32k_p, 0, + RK3576_CLKSEL_CON(87), 10, 1, MFLAGS, 5, 5, DFLAGS, + RK3576_CLKGATE_CON(32), 9, GFLAGS), + [HCLK_RKNN_CBUF] = GATE(HCLK_RKNN_CBUF, "hclk_rknn_cbuf", "hclk_rknn_root", 0, + RK3576_CLKGATE_CON(32), 12, GFLAGS), + [HCLK_NVM_ROOT] = COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(88), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(33), 0, GFLAGS), + [ACLK_NVM_ROOT] = COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(88), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(33), 1, GFLAGS), + [SCLK_FSPI_X2] = COMPOSITE(SCLK_FSPI_X2, "sclk_fspi_x2", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(89), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3576_CLKGATE_CON(33), 6, GFLAGS), + [HCLK_FSPI] = GATE(HCLK_FSPI, "hclk_fspi", "hclk_nvm_root", 0, + RK3576_CLKGATE_CON(33), 7, GFLAGS), + [CCLK_SRC_EMMC] = COMPOSITE(CCLK_SRC_EMMC, "cclk_src_emmc", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(89), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3576_CLKGATE_CON(33), 8, GFLAGS), + [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_nvm_root", 0, + RK3576_CLKGATE_CON(33), 9, GFLAGS), + [ACLK_EMMC] = GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0, + RK3576_CLKGATE_CON(33), 10, GFLAGS), + [BCLK_EMMC] = COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(90), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(33), 11, GFLAGS), + [TCLK_EMMC] = GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0, + RK3576_CLKGATE_CON(33), 12, GFLAGS), + [PCLK_PHP_ROOT] = COMPOSITE_NODIV(PCLK_PHP_ROOT, "pclk_php_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(92), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(34), 0, GFLAGS), + [ACLK_PHP_ROOT] = COMPOSITE(ACLK_PHP_ROOT, "aclk_php_root", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(92), 9, 1, MFLAGS, 4, 5, DFLAGS, + RK3576_CLKGATE_CON(34), 7, GFLAGS), + [PCLK_PCIE0] = GATE(PCLK_PCIE0, "pclk_pcie0", "pclk_php_root", 0, + RK3576_CLKGATE_CON(34), 13, GFLAGS), + [CLK_PCIE0_AUX] = GATE(CLK_PCIE0_AUX, "clk_pcie0_aux", "xin24m", 0, + RK3576_CLKGATE_CON(34), 14, GFLAGS), + [ACLK_PCIE0_MST] = GATE(ACLK_PCIE0_MST, "aclk_pcie0_mst", "aclk_php_root", 0, + RK3576_CLKGATE_CON(34), 15, GFLAGS), + [ACLK_PCIE0_SLV] = GATE(ACLK_PCIE0_SLV, "aclk_pcie0_slv", "aclk_php_root", 0, + RK3576_CLKGATE_CON(35), 0, GFLAGS), + [ACLK_PCIE0_DBI] = GATE(ACLK_PCIE0_DBI, "aclk_pcie0_dbi", "aclk_php_root", 0, + RK3576_CLKGATE_CON(35), 1, GFLAGS), + [ACLK_USB3OTG1] = GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_php_root", 0, + RK3576_CLKGATE_CON(35), 3, GFLAGS), + [CLK_REF_USB3OTG1] = GATE(CLK_REF_USB3OTG1, "clk_ref_usb3otg1", "xin24m", 0, + RK3576_CLKGATE_CON(35), 4, GFLAGS), + [CLK_SUSPEND_USB3OTG1] = GATE(CLK_SUSPEND_USB3OTG1, "clk_suspend_usb3otg1", "xin24m", 0, + RK3576_CLKGATE_CON(35), 5, GFLAGS), + [ACLK_MMU0] = GATE(ACLK_MMU0, "aclk_mmu0", "aclk_php_root", 0, + RK3576_CLKGATE_CON(35), 11, GFLAGS), + [ACLK_SLV_MMU0] = GATE(ACLK_SLV_MMU0, "aclk_slv_mmu0", "aclk_php_root", 0, + RK3576_CLKGATE_CON(35), 13, GFLAGS), + [ACLK_MMU1] = GATE(ACLK_MMU1, "aclk_mmu1", "aclk_php_root", 0, + RK3576_CLKGATE_CON(35), 14, GFLAGS), + [ACLK_SLV_MMU1] = GATE(ACLK_SLV_MMU1, "aclk_slv_mmu1", "aclk_php_root", 0, + RK3576_CLKGATE_CON(36), 0, GFLAGS), + [PCLK_PCIE1] = GATE(PCLK_PCIE1, "pclk_pcie1", "pclk_php_root", 0, + RK3576_CLKGATE_CON(36), 7, GFLAGS), + [CLK_PCIE1_AUX] = GATE(CLK_PCIE1_AUX, "clk_pcie1_aux", "xin24m", 0, + RK3576_CLKGATE_CON(36), 8, GFLAGS), + [ACLK_PCIE1_MST] = GATE(ACLK_PCIE1_MST, "aclk_pcie1_mst", "aclk_php_root", 0, + RK3576_CLKGATE_CON(36), 9, GFLAGS), + [ACLK_PCIE1_SLV] = GATE(ACLK_PCIE1_SLV, "aclk_pcie1_slv", "aclk_php_root", 0, + RK3576_CLKGATE_CON(36), 10, GFLAGS), + [ACLK_PCIE1_DBI] = GATE(ACLK_PCIE1_DBI, "aclk_pcie1_dbi", "aclk_php_root", 0, + RK3576_CLKGATE_CON(36), 11, GFLAGS), + [CLK_RXOOB0] = COMPOSITE(CLK_RXOOB0, "clk_rxoob0", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(93), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3576_CLKGATE_CON(37), 0, GFLAGS), + [CLK_RXOOB1] = COMPOSITE(CLK_RXOOB1, "clk_rxoob1", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(93), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3576_CLKGATE_CON(37), 1, GFLAGS), + [CLK_PMALIVE0] = GATE(CLK_PMALIVE0, "clk_pmalive0", "xin24m", RT_CLK_F_IS_CRITICAL, + RK3576_CLKGATE_CON(37), 2, GFLAGS), + [CLK_PMALIVE1] = GATE(CLK_PMALIVE1, "clk_pmalive1", "xin24m", RT_CLK_F_IS_CRITICAL, + RK3576_CLKGATE_CON(37), 3, GFLAGS), + [ACLK_SATA0] = GATE(ACLK_SATA0, "aclk_sata0", "aclk_php_root", 0, + RK3576_CLKGATE_CON(37), 4, GFLAGS), + [ACLK_SATA1] = GATE(ACLK_SATA1, "aclk_sata1", "aclk_php_root", 0, + RK3576_CLKGATE_CON(37), 5, GFLAGS), + [HCLK_SDGMAC_ROOT] = COMPOSITE_NODIV(HCLK_SDGMAC_ROOT, "hclk_sdgmac_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(103), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(42), 0, GFLAGS), + [ACLK_SDGMAC_ROOT] = COMPOSITE(ACLK_SDGMAC_ROOT, "aclk_sdgmac_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(103), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(42), 1, GFLAGS), + [PCLK_SDGMAC_ROOT] = COMPOSITE_NODIV(PCLK_SDGMAC_ROOT, "pclk_sdgmac_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(103), 8, 2, MFLAGS, + RK3576_CLKGATE_CON(42), 2, GFLAGS), + [ACLK_GMAC0] = GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(42), 7, GFLAGS), + [ACLK_GMAC1] = GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(42), 8, GFLAGS), + [PCLK_GMAC0] = GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(42), 9, GFLAGS), + [PCLK_GMAC1] = GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(42), 10, GFLAGS), + [CCLK_SRC_SDIO] = COMPOSITE(CCLK_SRC_SDIO, "cclk_src_sdio", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(104), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3576_CLKGATE_CON(42), 11, GFLAGS), + [HCLK_SDIO] = GATE(HCLK_SDIO, "hclk_sdio", "hclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(42), 12, GFLAGS), + [CLK_GMAC1_PTP_REF] = GATE(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", "clk_gmac1_ptp_ref_src", 0, + RK3576_CLKGATE_CON(42), 13, GFLAGS), + [CLK_GMAC0_PTP_REF] = GATE(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", "clk_gmac0_ptp_ref_src", 0, + RK3576_CLKGATE_CON(42), 14, GFLAGS), + [CLK_GMAC1_PTP_REF_SRC] = COMPOSITE(CLK_GMAC1_PTP_REF_SRC, "clk_gmac1_ptp_ref_src", clk_gmac1_ptp_ref_src_p, 0, + RK3576_CLKSEL_CON(104), 13, 2, MFLAGS, 8, 5, DFLAGS, + RK3576_CLKGATE_CON(42), 15, GFLAGS), + [CLK_GMAC0_PTP_REF_SRC] = COMPOSITE(CLK_GMAC0_PTP_REF_SRC, "clk_gmac0_ptp_ref_src", clk_gmac0_ptp_ref_src_p, 0, + RK3576_CLKSEL_CON(105), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(43), 0, GFLAGS), + [CCLK_SRC_SDMMC0] = COMPOSITE(CCLK_SRC_SDMMC0, "cclk_src_sdmmc0", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(105), 13, 2, MFLAGS, 7, 6, DFLAGS, + RK3576_CLKGATE_CON(43), 1, GFLAGS), + [HCLK_SDMMC0] = GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(43), 2, GFLAGS), + [SCLK_FSPI1_X2] = COMPOSITE(SCLK_FSPI1_X2, "sclk_fspi1_x2", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(106), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3576_CLKGATE_CON(43), 3, GFLAGS), + [HCLK_FSPI1] = GATE(HCLK_FSPI1, "hclk_fspi1", "hclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(43), 4, GFLAGS), + [ACLK_DSMC_ROOT] = COMPOSITE(ACLK_DSMC_ROOT, "aclk_dsmc_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(106), 13, 1, MFLAGS, 8, 5, DFLAGS, + RK3576_CLKGATE_CON(43), 5, GFLAGS), + [ACLK_DSMC] = GATE(ACLK_DSMC, "aclk_dsmc", "aclk_dsmc_root", 0, + RK3576_CLKGATE_CON(43), 7, GFLAGS), + [PCLK_DSMC] = GATE(PCLK_DSMC, "pclk_dsmc", "pclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(43), 8, GFLAGS), + [CLK_DSMC_SYS] = COMPOSITE(CLK_DSMC_SYS, "clk_dsmc_sys", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(107), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(43), 9, GFLAGS), + [HCLK_HSGPIO] = GATE(HCLK_HSGPIO, "hclk_hsgpio", "hclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(43), 10, GFLAGS), + [CLK_HSGPIO_TX] = COMPOSITE(CLK_HSGPIO_TX, "clk_hsgpio_tx", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(107), 11, 2, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(43), 11, GFLAGS), + [CLK_HSGPIO_RX] = COMPOSITE(CLK_HSGPIO_RX, "clk_hsgpio_rx", gpll_cpll_24m_p, 0, + RK3576_CLKSEL_CON(108), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(43), 12, GFLAGS), + [ACLK_HSGPIO] = GATE(ACLK_HSGPIO, "aclk_hsgpio", "aclk_sdgmac_root", 0, + RK3576_CLKGATE_CON(43), 13, GFLAGS), + [PCLK_PHPPHY_ROOT] = GATE(PCLK_PHPPHY_ROOT, "pclk_phpphy_root", "pclk_bus_root", RT_CLK_F_IS_CRITICAL, + RK3576_PHP_CLKGATE_CON(0), 2, GFLAGS), + [PCLK_PCIE2_COMBOPHY0] = GATE(PCLK_PCIE2_COMBOPHY0, "pclk_pcie2_combophy0", "pclk_phpphy_root", 0, + RK3576_PHP_CLKGATE_CON(0), 5, GFLAGS), + [PCLK_PCIE2_COMBOPHY1] = GATE(PCLK_PCIE2_COMBOPHY1, "pclk_pcie2_combophy1", "pclk_phpphy_root", 0, + RK3576_PHP_CLKGATE_CON(0), 7, GFLAGS), + [CLK_PCIE_100M_SRC] = COMPOSITE_NOMUX(CLK_PCIE_100M_SRC, "clk_pcie_100m_src", "ppll", 0, + RK3576_PHP_CLKSEL_CON(0), 2, 5, DFLAGS, + RK3576_PHP_CLKGATE_CON(1), 1, GFLAGS), + [CLK_PCIE_100M_NDUTY_SRC] = COMPOSITE_NOMUX(CLK_PCIE_100M_NDUTY_SRC, "clk_pcie_100m_nduty_src", "ppll", 0, + RK3576_PHP_CLKSEL_CON(0), 7, 5, DFLAGS, + RK3576_PHP_CLKGATE_CON(1), 2, GFLAGS), + [CLK_REF_PCIE0_PHY] = COMPOSITE_NODIV(CLK_REF_PCIE0_PHY, "clk_ref_pcie0_phy", clk_ref_pcie0_phy_p, 0, + RK3576_PHP_CLKSEL_CON(0), 12, 2, MFLAGS, + RK3576_PHP_CLKGATE_CON(1), 5, GFLAGS), + [CLK_REF_PCIE1_PHY] = COMPOSITE_NODIV(CLK_REF_PCIE1_PHY, "clk_ref_pcie1_phy", clk_ref_pcie0_phy_p, 0, + RK3576_PHP_CLKSEL_CON(0), 14, 2, MFLAGS, + RK3576_PHP_CLKGATE_CON(1), 8, GFLAGS), + [CLK_REF_MPHY_26M] = COMPOSITE_NOMUX(CLK_REF_MPHY_26M, "clk_ref_mphy_26m", "ppll", RT_CLK_F_IS_CRITICAL, + RK3576_PHP_CLKSEL_CON(1), 0, 8, DFLAGS, + RK3576_PHP_CLKGATE_CON(1), 9, GFLAGS), + [HCLK_RKVDEC_ROOT] = COMPOSITE_NODIV(HCLK_RKVDEC_ROOT, "hclk_rkvdec_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(110), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(45), 0, GFLAGS), + [ACLK_RKVDEC_ROOT] = COMPOSITE(ACLK_RKVDEC_ROOT, "aclk_rkvdec_root", gpll_cpll_aupll_spll_p, 0, + RK3576_CLKSEL_CON(110), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(45), 1, GFLAGS), + [HCLK_RKVDEC] = GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_root", 0, + RK3576_CLKGATE_CON(45), 3, GFLAGS), + [CLK_RKVDEC_HEVC_CA] = COMPOSITE(CLK_RKVDEC_HEVC_CA, "clk_rkvdec_hevc_ca", gpll_cpll_lpll_bpll_p, 0, + RK3576_CLKSEL_CON(111), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(45), 8, GFLAGS), + [CLK_RKVDEC_CORE] = GATE(CLK_RKVDEC_CORE, "clk_rkvdec_core", "aclk_rkvdec_root", 0, + RK3576_CLKGATE_CON(45), 9, GFLAGS), + [ACLK_UFS_ROOT] = COMPOSITE(ACLK_UFS_ROOT, "aclk_ufs_root", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(115), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(47), 0, GFLAGS), + [ACLK_USB_ROOT] = COMPOSITE(ACLK_USB_ROOT, "aclk_usb_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(115), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(47), 1, GFLAGS), + [PCLK_USB_ROOT] = COMPOSITE_NODIV(PCLK_USB_ROOT, "pclk_usb_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(115), 12, 2, MFLAGS, + RK3576_CLKGATE_CON(47), 2, GFLAGS), + [ACLK_USB3OTG0] = GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb_root", 0, + RK3576_CLKGATE_CON(47), 5, GFLAGS), + [CLK_REF_USB3OTG0] = GATE(CLK_REF_USB3OTG0, "clk_ref_usb3otg0", "xin24m", 0, + RK3576_CLKGATE_CON(47), 6, GFLAGS), + [CLK_SUSPEND_USB3OTG0] = GATE(CLK_SUSPEND_USB3OTG0, "clk_suspend_usb3otg0", "xin24m", 0, + RK3576_CLKGATE_CON(47), 7, GFLAGS), + [ACLK_MMU2] = GATE(ACLK_MMU2, "aclk_mmu2", "aclk_usb_root", 0, + RK3576_CLKGATE_CON(47), 12, GFLAGS), + [ACLK_SLV_MMU2] = GATE(ACLK_SLV_MMU2, "aclk_slv_mmu2", "aclk_usb_root", 0, + RK3576_CLKGATE_CON(47), 13, GFLAGS), + [ACLK_UFS_SYS] = GATE(ACLK_UFS_SYS, "aclk_ufs_sys", "aclk_ufs_root", 0, + RK3576_CLKGATE_CON(47), 15, GFLAGS), + [ACLK_VPU_ROOT] = COMPOSITE(ACLK_VPU_ROOT, "aclk_vpu_root", gpll_spll_cpll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(118), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(49), 0, GFLAGS), + [ACLK_VPU_MID_ROOT] = COMPOSITE_NODIV(ACLK_VPU_MID_ROOT, "aclk_vpu_mid_root", mux_600m_400m_300m_24m_p, 0, + RK3576_CLKSEL_CON(118), 8, 2, MFLAGS, + RK3576_CLKGATE_CON(49), 1, GFLAGS), + [HCLK_VPU_ROOT] = COMPOSITE_NODIV(HCLK_VPU_ROOT, "hclk_vpu_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(118), 10, 2, MFLAGS, + RK3576_CLKGATE_CON(49), 2, GFLAGS), + [ACLK_JPEG_ROOT] = COMPOSITE(ACLK_JPEG_ROOT, "aclk_jpeg_root", gpll_cpll_aupll_spll_p, 0, + RK3576_CLKSEL_CON(119), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(49), 3, GFLAGS), + [ACLK_VPU_LOW_ROOT] = COMPOSITE_NODIV(ACLK_VPU_LOW_ROOT, "aclk_vpu_low_root", mux_400m_200m_100m_24m_p, 0, + RK3576_CLKSEL_CON(119), 7, 2, MFLAGS, + RK3576_CLKGATE_CON(49), 4, GFLAGS), + [HCLK_RGA2E_0] = GATE(HCLK_RGA2E_0, "hclk_rga2e_0", "hclk_vpu_root", 0, + RK3576_CLKGATE_CON(49), 13, GFLAGS), + [ACLK_RGA2E_0] = GATE(ACLK_RGA2E_0, "aclk_rga2e_0", "aclk_vpu_root", 0, + RK3576_CLKGATE_CON(49), 14, GFLAGS), + [CLK_CORE_RGA2E_0] = COMPOSITE(CLK_CORE_RGA2E_0, "clk_core_rga2e_0", gpll_spll_cpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(120), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(49), 15, GFLAGS), + [ACLK_JPEG] = GATE(ACLK_JPEG, "aclk_jpeg", "aclk_jpeg_root", 0, + RK3576_CLKGATE_CON(50), 0, GFLAGS), + [HCLK_JPEG] = GATE(HCLK_JPEG, "hclk_jpeg", "hclk_vpu_root", 0, + RK3576_CLKGATE_CON(50), 1, GFLAGS), + [HCLK_VDPP] = GATE(HCLK_VDPP, "hclk_vdpp", "hclk_vpu_root", 0, + RK3576_CLKGATE_CON(50), 2, GFLAGS), + [ACLK_VDPP] = GATE(ACLK_VDPP, "aclk_vdpp", "aclk_vpu_mid_root", 0, + RK3576_CLKGATE_CON(50), 3, GFLAGS), + [CLK_CORE_VDPP] = COMPOSITE(CLK_CORE_VDPP, "clk_core_vdpp", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(120), 13, 1, MFLAGS, 8, 5, DFLAGS, + RK3576_CLKGATE_CON(50), 4, GFLAGS), + [HCLK_RGA2E_1] = GATE(HCLK_RGA2E_1, "hclk_rga2e_1", "hclk_vpu_root", 0, + RK3576_CLKGATE_CON(50), 5, GFLAGS), + [ACLK_RGA2E_1] = GATE(ACLK_RGA2E_1, "aclk_rga2e_1", "aclk_vpu_root", 0, + RK3576_CLKGATE_CON(50), 6, GFLAGS), + [CLK_CORE_RGA2E_1] = COMPOSITE(CLK_CORE_RGA2E_1, "clk_core_rga2e_1", gpll_spll_cpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(121), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(50), 7, GFLAGS), + [DCLK_EBC_FRAC_SRC] = COMPOSITE_FRAC(DCLK_EBC_FRAC_SRC, "dclk_ebc_frac_src", "dclk_ebc_frac_src_p", 0, + RK3576_CLKSEL_CON(122), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3576_CLKGATE_CON(50), 9, GFLAGS), + [HCLK_EBC] = GATE(ACLK_EBC, "aclk_ebc", "aclk_vpu_low_root", 0, + RK3576_CLKGATE_CON(50), 11, GFLAGS), + [ACLK_EBC] = GATE(HCLK_EBC, "hclk_ebc", "hclk_vpu_root", 0, + RK3576_CLKGATE_CON(50), 10, GFLAGS), + [DCLK_EBC] = COMPOSITE(DCLK_EBC, "dclk_ebc", dclk_ebc_p, 0, + RK3576_CLKSEL_CON(123), 12, 3, MFLAGS, 3, 9, DFLAGS, + RK3576_CLKGATE_CON(50), 12, GFLAGS), + [HCLK_VEPU0_ROOT] = COMPOSITE_NODIV(HCLK_VEPU0_ROOT, "hclk_vepu0_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(124), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(51), 0, GFLAGS), + [ACLK_VEPU0_ROOT] = COMPOSITE(ACLK_VEPU0_ROOT, "aclk_vepu0_root", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(124), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3576_CLKGATE_CON(51), 1, GFLAGS), + [HCLK_VEPU0] = GATE(HCLK_VEPU0, "hclk_vepu0", "hclk_vepu0_root", 0, + RK3576_CLKGATE_CON(51), 4, GFLAGS), + [ACLK_VEPU0] = GATE(ACLK_VEPU0, "aclk_vepu0", "aclk_vepu0_root", 0, + RK3576_CLKGATE_CON(51), 5, GFLAGS), + [CLK_VEPU0_CORE] = COMPOSITE(CLK_VEPU0_CORE, "clk_vepu0_core", gpll_cpll_spll_lpll_bpll_p, 0, + RK3576_CLKSEL_CON(124), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK3576_CLKGATE_CON(51), 6, GFLAGS), + [ACLK_VI_ROOT] = COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_spll_isppvtpll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(128), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(53), 0, GFLAGS), + [HCLK_VI_ROOT] = COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", hclk_vi_root_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(128), 8, 2, MFLAGS, + RK3576_CLKGATE_CON(53), 1, GFLAGS), + [PCLK_VI_ROOT] = COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(128), 10, 2, MFLAGS, + RK3576_CLKGATE_CON(53), 2, GFLAGS), + [DCLK_VICAP] = COMPOSITE(DCLK_VICAP, "dclk_vicap", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(129), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(53), 6, GFLAGS), + [ACLK_VICAP] = GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0, + RK3576_CLKGATE_CON(53), 7, GFLAGS), + [HCLK_VICAP] = GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0, + RK3576_CLKGATE_CON(53), 8, GFLAGS), + [CLK_ISP_CORE] = COMPOSITE(CLK_ISP_CORE, "clk_isp_core", gpll_spll_isppvtpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(129), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(53), 9, GFLAGS), + [CLK_ISP_CORE_MARVIN] = GATE(CLK_ISP_CORE_MARVIN, "clk_isp_core_marvin", "clk_isp_core", 0, + RK3576_CLKGATE_CON(53), 10, GFLAGS), + [CLK_ISP_CORE_VICAP] = GATE(CLK_ISP_CORE_VICAP, "clk_isp_core_vicap", "clk_isp_core", 0, + RK3576_CLKGATE_CON(53), 11, GFLAGS), + [ACLK_ISP] = GATE(ACLK_ISP, "aclk_isp", "aclk_vi_root", 0, + RK3576_CLKGATE_CON(53), 12, GFLAGS), + [HCLK_ISP] = GATE(HCLK_ISP, "hclk_isp", "hclk_vi_root", 0, + RK3576_CLKGATE_CON(53), 13, GFLAGS), + [ACLK_VPSS] = GATE(ACLK_VPSS, "aclk_vpss", "aclk_vi_root", 0, + RK3576_CLKGATE_CON(53), 15, GFLAGS), + [HCLK_VPSS] = GATE(HCLK_VPSS, "hclk_vpss", "hclk_vi_root", 0, + RK3576_CLKGATE_CON(54), 0, GFLAGS), + [CLK_CORE_VPSS] = GATE(CLK_CORE_VPSS, "clk_core_vpss", "clk_isp_core", 0, + RK3576_CLKGATE_CON(54), 1, GFLAGS), + [PCLK_CSI_HOST_0] = GATE(PCLK_CSI_HOST_0, "pclk_csi_host_0", "pclk_vi_root", 0, + RK3576_CLKGATE_CON(54), 4, GFLAGS), + [PCLK_CSI_HOST_1] = GATE(PCLK_CSI_HOST_1, "pclk_csi_host_1", "pclk_vi_root", 0, + RK3576_CLKGATE_CON(54), 5, GFLAGS), + [PCLK_CSI_HOST_2] = GATE(PCLK_CSI_HOST_2, "pclk_csi_host_2", "pclk_vi_root", 0, + RK3576_CLKGATE_CON(54), 6, GFLAGS), + [PCLK_CSI_HOST_3] = GATE(PCLK_CSI_HOST_3, "pclk_csi_host_3", "pclk_vi_root", 0, + RK3576_CLKGATE_CON(54), 7, GFLAGS), + [PCLK_CSI_HOST_4] = GATE(PCLK_CSI_HOST_4, "pclk_csi_host_4", "pclk_vi_root", 0, + RK3576_CLKGATE_CON(54), 8, GFLAGS), + [ICLK_CSIHOST01] = COMPOSITE_NODIV(ICLK_CSIHOST01, "iclk_csihost01", mux_400m_200m_100m_24m_p, 0, + RK3576_CLKSEL_CON(130), 7, 2, MFLAGS, + RK3576_CLKGATE_CON(54), 10, GFLAGS), + [ICLK_CSIHOST0] = GATE(ICLK_CSIHOST0, "iclk_csihost0", "iclk_csihost01", 0, + RK3576_CLKGATE_CON(54), 11, GFLAGS), + [ACLK_VI_ROOT_INTER] = COMPOSITE_NOMUX(ACLK_VI_ROOT_INTER, "aclk_vi_root_inter", "aclk_vi_root", 0, + RK3576_CLKSEL_CON(130), 10, 3, DFLAGS, + RK3576_CLKGATE_CON(54), 13, GFLAGS), + [CLK_VICAP_I0CLK] = GATE(CLK_VICAP_I0CLK, "clk_vicap_i0clk", "clk_csihost0_clkdata_i", 0, + RK3576_CLKGATE_CON(59), 1, GFLAGS), + [CLK_VICAP_I1CLK] = GATE(CLK_VICAP_I1CLK, "clk_vicap_i1clk", "clk_csihost1_clkdata_i", 0, + RK3576_CLKGATE_CON(59), 2, GFLAGS), + [CLK_VICAP_I2CLK] = GATE(CLK_VICAP_I2CLK, "clk_vicap_i2clk", "clk_csihost2_clkdata_i", 0, + RK3576_CLKGATE_CON(59), 3, GFLAGS), + [CLK_VICAP_I3CLK] = GATE(CLK_VICAP_I3CLK, "clk_vicap_i3clk", "clk_csihost3_clkdata_i", 0, + RK3576_CLKGATE_CON(59), 4, GFLAGS), + [CLK_VICAP_I4CLK] = GATE(CLK_VICAP_I4CLK, "clk_vicap_i4clk", "clk_csihost4_clkdata_i", 0, + RK3576_CLKGATE_CON(59), 5, GFLAGS), + [ACLK_VOP_ROOT] = COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_aupll_spll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(144), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(61), 0, GFLAGS), + [HCLK_VOP_ROOT] = COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(144), 10, 2, MFLAGS, + RK3576_CLKGATE_CON(61), 2, GFLAGS), + [PCLK_VOP_ROOT] = COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(144), 12, 2, MFLAGS, + RK3576_CLKGATE_CON(61), 3, GFLAGS), + [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", 0, + RK3576_CLKGATE_CON(61), 8, GFLAGS), + [ACLK_VOP] = GATE(ACLK_VOP, "aclk_vop", "aclk_vop_root", 0, + RK3576_CLKGATE_CON(61), 9, GFLAGS), + [DCLK_VP0_SRC] = COMPOSITE(DCLK_VP0_SRC, "dclk_vp0_src", gpll_cpll_vpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(145), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(61), 10, GFLAGS), + [DCLK_VP1_SRC] = COMPOSITE(DCLK_VP1_SRC, "dclk_vp1_src", gpll_cpll_vpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(146), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(61), 11, GFLAGS), + [DCLK_VP2_SRC] = COMPOSITE(DCLK_VP2_SRC, "dclk_vp2_src", gpll_cpll_vpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(147), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(61), 12, GFLAGS), + [DCLK_VP0] = COMPOSITE_NODIV(DCLK_VP0, "dclk_vp0", dclk_vp0_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(147), 11, 1, MFLAGS, + RK3576_CLKGATE_CON(61), 13, GFLAGS), + [DCLK_VP1] = COMPOSITE_NODIV(DCLK_VP1, "dclk_vp1", dclk_vp1_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(147), 12, 1, MFLAGS, + RK3576_CLKGATE_CON(62), 0, GFLAGS), + [DCLK_VP2] = COMPOSITE_NODIV(DCLK_VP2, "dclk_vp2", dclk_vp2_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(147), 13, 1, MFLAGS, + RK3576_CLKGATE_CON(62), 1, GFLAGS), + [ACLK_VO0_ROOT] = COMPOSITE(ACLK_VO0_ROOT, "aclk_vo0_root", gpll_cpll_lpll_bpll_p, 0, + RK3576_CLKSEL_CON(149), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(63), 0, GFLAGS), + [HCLK_VO0_ROOT] = COMPOSITE_NODIV(HCLK_VO0_ROOT, "hclk_vo0_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(149), 7, 2, MFLAGS, + RK3576_CLKGATE_CON(63), 1, GFLAGS), + [PCLK_VO0_ROOT] = COMPOSITE_NODIV(PCLK_VO0_ROOT, "pclk_vo0_root", mux_150m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(149), 11, 2, MFLAGS, + RK3576_CLKGATE_CON(63), 3, GFLAGS), + [ACLK_HDCP0] = GATE(ACLK_HDCP0, "aclk_hdcp0", "aclk_vo0_root", 0, + RK3576_CLKGATE_CON(63), 12, GFLAGS), + [HCLK_HDCP0] = GATE(HCLK_HDCP0, "hclk_hdcp0", "hclk_vo0_root", 0, + RK3576_CLKGATE_CON(63), 13, GFLAGS), + [PCLK_HDCP0] = GATE(PCLK_HDCP0, "pclk_hdcp0", "pclk_vo0_root", 0, + RK3576_CLKGATE_CON(63), 14, GFLAGS), + [CLK_TRNG0_SKP] = GATE(CLK_TRNG0_SKP, "clk_trng0_skp", "aclk_hdcp0", 0, + RK3576_CLKGATE_CON(64), 4, GFLAGS), + [PCLK_DSIHOST0] = GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vo0_root", 0, + RK3576_CLKGATE_CON(64), 5, GFLAGS), + [CLK_DSIHOST0] = COMPOSITE(CLK_DSIHOST0, "clk_dsihost0", gpll_cpll_spll_vpll_bpll_lpll_p, 0, + RK3576_CLKSEL_CON(151), 7, 3, MFLAGS, 0, 7, DFLAGS, + RK3576_CLKGATE_CON(64), 6, GFLAGS), + [PCLK_HDMITX0] = GATE(PCLK_HDMITX0, "pclk_hdmitx0", "pclk_vo0_root", 0, + RK3576_CLKGATE_CON(64), 7, GFLAGS), + [CLK_HDMITX0_EARC] = COMPOSITE(CLK_HDMITX0_EARC, "clk_hdmitx0_earc", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(151), 15, 1, MFLAGS, 10, 5, DFLAGS, + RK3576_CLKGATE_CON(64), 8, GFLAGS), + [CLK_HDMITX0_REF] = GATE(CLK_HDMITX0_REF, "clk_hdmitx0_ref", "aclk_vo0_root", 0, + RK3576_CLKGATE_CON(64), 9, GFLAGS), + [PCLK_EDP0] = GATE(PCLK_EDP0, "pclk_edp0", "pclk_vo0_root", 0, + RK3576_CLKGATE_CON(64), 13, GFLAGS), + [CLK_EDP0_24M] = GATE(CLK_EDP0_24M, "clk_edp0_24m", "xin24m", 0, + RK3576_CLKGATE_CON(64), 14, GFLAGS), + [CLK_EDP0_200M] = COMPOSITE_NODIV(CLK_EDP0_200M, "clk_edp0_200m", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(152), 1, 2, MFLAGS, + RK3576_CLKGATE_CON(64), 15, GFLAGS), + [MCLK_SAI5_8CH_SRC] = COMPOSITE(MCLK_SAI5_8CH_SRC, "mclk_sai5_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(154), 10, 3, MFLAGS, 2, 8, DFLAGS, + RK3576_CLKGATE_CON(65), 3, GFLAGS), + [MCLK_SAI5_8CH] = COMPOSITE_NODIV(MCLK_SAI5_8CH, "mclk_sai5_8ch", mclk_sai5_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(154), 13, 1, MFLAGS, + RK3576_CLKGATE_CON(65), 4, GFLAGS), + [HCLK_SAI5_8CH] = GATE(HCLK_SAI5_8CH, "hclk_sai5_8ch", "hclk_vo0_root", 0, + RK3576_CLKGATE_CON(65), 5, GFLAGS), + [MCLK_SAI6_8CH_SRC] = COMPOSITE(MCLK_SAI6_8CH_SRC, "mclk_sai6_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(155), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(65), 7, GFLAGS), + [MCLK_SAI6_8CH] = COMPOSITE_NODIV(MCLK_SAI6_8CH, "mclk_sai6_8ch", mclk_sai6_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(155), 11, 1, MFLAGS, + RK3576_CLKGATE_CON(65), 8, GFLAGS), + [HCLK_SAI6_8CH] = GATE(HCLK_SAI6_8CH, "hclk_sai6_8ch", "hclk_vo0_root", 0, + RK3576_CLKGATE_CON(65), 9, GFLAGS), + [HCLK_SPDIF_TX2] = GATE(HCLK_SPDIF_TX2, "hclk_spdif_tx2", "hclk_vo0_root", 0, + RK3576_CLKGATE_CON(65), 10, GFLAGS), + [MCLK_SPDIF_TX2] = COMPOSITE(MCLK_SPDIF_TX2, "mclk_spdif_tx2", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(156), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(65), 13, GFLAGS), + [HCLK_SPDIF_RX2] = GATE(HCLK_SPDIF_RX2, "hclk_spdif_rx2", "hclk_vo0_root", 0, + RK3576_CLKGATE_CON(65), 14, GFLAGS), + [MCLK_SPDIF_RX2] = COMPOSITE(MCLK_SPDIF_RX2, "mclk_spdif_rx2", gpll_cpll_aupll_p, 0, + RK3576_CLKSEL_CON(156), 13, 2, MFLAGS, 8, 5, DFLAGS, + RK3576_CLKGATE_CON(65), 15, GFLAGS), + [HCLK_SAI8_8CH] = GATE(HCLK_SAI8_8CH, "hclk_sai8_8ch", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(66), 0, GFLAGS), + [MCLK_SAI8_8CH_SRC] = COMPOSITE(MCLK_SAI8_8CH_SRC, "mclk_sai8_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(157), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(66), 1, GFLAGS), + [MCLK_SAI8_8CH] = COMPOSITE_NODIV(MCLK_SAI8_8CH, "mclk_sai8_8ch", mclk_sai8_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(157), 11, 1, MFLAGS, + RK3576_CLKGATE_CON(66), 2, GFLAGS), + [ACLK_VO1_ROOT] = COMPOSITE(ACLK_VO1_ROOT, "aclk_vo1_root", gpll_cpll_lpll_bpll_p, 0, + RK3576_CLKSEL_CON(158), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(67), 1, GFLAGS), + [HCLK_VO1_ROOT] = COMPOSITE_NODIV(HCLK_VO1_ROOT, "hclk_vo1_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(158), 7, 2, MFLAGS, + RK3576_CLKGATE_CON(67), 2, GFLAGS), + [PCLK_VO1_ROOT] = COMPOSITE_NODIV(PCLK_VO1_ROOT, "pclk_vo1_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(158), 9, 2, MFLAGS, + RK3576_CLKGATE_CON(67), 3, GFLAGS), + [MCLK_SAI7_8CH_SRC] = COMPOSITE(MCLK_SAI7_8CH_SRC, "mclk_sai7_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(159), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(67), 8, GFLAGS), + [MCLK_SAI7_8CH] = COMPOSITE_NODIV(MCLK_SAI7_8CH, "mclk_sai7_8ch", mclk_sai7_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(159), 11, 1, MFLAGS, + RK3576_CLKGATE_CON(67), 9, GFLAGS), + [HCLK_SAI7_8CH] = GATE(HCLK_SAI7_8CH, "hclk_sai7_8ch", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(67), 10, GFLAGS), + [HCLK_SPDIF_TX3] = GATE(HCLK_SPDIF_TX3, "hclk_spdif_tx3", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(67), 11, GFLAGS), + [HCLK_SPDIF_TX4] = GATE(HCLK_SPDIF_TX4, "hclk_spdif_tx4", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(67), 12, GFLAGS), + [HCLK_SPDIF_TX5] = GATE(HCLK_SPDIF_TX5, "hclk_spdif_tx5", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(67), 13, GFLAGS), + [MCLK_SPDIF_TX3] = COMPOSITE(MCLK_SPDIF_TX3, "mclk_spdif_tx3", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(160), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(67), 14, GFLAGS), + [CLK_AUX16MHZ_0] = COMPOSITE_NOMUX(CLK_AUX16MHZ_0, "clk_aux16mhz_0", "gpll", 0, + RK3576_CLKSEL_CON(161), 0, 8, DFLAGS, + RK3576_CLKGATE_CON(67), 15, GFLAGS), + [ACLK_DP0] = GATE(ACLK_DP0, "aclk_dp0", "aclk_vo1_root", 0, + RK3576_CLKGATE_CON(68), 0, GFLAGS), + [PCLK_DP0] = GATE(PCLK_DP0, "pclk_dp0", "pclk_vo1_root", 0, + RK3576_CLKGATE_CON(68), 1, GFLAGS), + [ACLK_HDCP1] = GATE(ACLK_HDCP1, "aclk_hdcp1", "aclk_vo1_root", 0, + RK3576_CLKGATE_CON(68), 4, GFLAGS), + [HCLK_HDCP1] = GATE(HCLK_HDCP1, "hclk_hdcp1", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(68), 5, GFLAGS), + [PCLK_HDCP1] = GATE(PCLK_HDCP1, "pclk_hdcp1", "pclk_vo1_root", 0, + RK3576_CLKGATE_CON(68), 6, GFLAGS), + [CLK_TRNG1_SKP] = GATE(CLK_TRNG1_SKP, "clk_trng1_skp", "aclk_hdcp1", 0, + RK3576_CLKGATE_CON(68), 7, GFLAGS), + [HCLK_SAI9_8CH] = GATE(HCLK_SAI9_8CH, "hclk_sai9_8ch", "hclk_vo1_root", 0, + RK3576_CLKGATE_CON(68), 9, GFLAGS), + [MCLK_SAI9_8CH_SRC] = COMPOSITE(MCLK_SAI9_8CH_SRC, "mclk_sai9_8ch_src", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(162), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(68), 10, GFLAGS), + [MCLK_SAI9_8CH] = COMPOSITE_NODIV(MCLK_SAI9_8CH, "mclk_sai9_8ch", mclk_sai9_8ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_CLKSEL_CON(162), 11, 1, MFLAGS, + RK3576_CLKGATE_CON(68), 11, GFLAGS), + [MCLK_SPDIF_TX4] = COMPOSITE(MCLK_SPDIF_TX4, "mclk_spdif_tx4", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(163), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(68), 12, GFLAGS), + [MCLK_SPDIF_TX5] = COMPOSITE(MCLK_SPDIF_TX5, "mclk_spdif_tx5", audio_frac_int_p, 0, + RK3576_CLKSEL_CON(164), 8, 3, MFLAGS, 0, 8, DFLAGS, + RK3576_CLKGATE_CON(68), 13, GFLAGS), + [CLK_GPU_SRC_PRE] = COMPOSITE(CLK_GPU_SRC_PRE, "clk_gpu_src_pre", gpll_cpll_aupll_spll_lpll_p, 0, + RK3576_CLKSEL_CON(165), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(69), 1, GFLAGS), + [CLK_GPU] = GATE(CLK_GPU, "clk_gpu", "clk_gpu_src_pre", 0, + RK3576_CLKGATE_CON(69), 3, GFLAGS), + [PCLK_GPU_ROOT] = COMPOSITE_NODIV(PCLK_GPU_ROOT, "pclk_gpu_root", mux_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(166), 10, 2, MFLAGS, + RK3576_CLKGATE_CON(69), 8, GFLAGS), + [ACLK_CENTER_ROOT] = COMPOSITE_DIV_OFFSET(ACLK_CENTER_ROOT, "aclk_center_root", gpll_cpll_spll_aupll_bpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(168), 5, 3, MFLAGS, + RK3576_CLKSEL_CON(167), 9, 5, DFLAGS, + RK3576_CLKGATE_CON(72), 0, GFLAGS), + [ACLK_CENTER_LOW_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", mux_500m_250m_100m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(168), 8, 2, MFLAGS, + RK3576_CLKGATE_CON(72), 1, GFLAGS), + [HCLK_CENTER_ROOT] = COMPOSITE_NODIV(HCLK_CENTER_ROOT, "hclk_center_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(168), 10, 2, MFLAGS, + RK3576_CLKGATE_CON(72), 2, GFLAGS), + [PCLK_CENTER_ROOT] = COMPOSITE_NODIV(PCLK_CENTER_ROOT, "pclk_center_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(168), 12, 2, MFLAGS, + RK3576_CLKGATE_CON(72), 3, GFLAGS), + [ACLK_DMA2DDR] = GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_center_root", RT_CLK_F_IGNORE_UNUSED, + RK3576_CLKGATE_CON(72), 5, GFLAGS), + [ACLK_DDR_SHAREMEM] = GATE(ACLK_DDR_SHAREMEM, "aclk_ddr_sharemem", "aclk_center_low_root", RT_CLK_F_IGNORE_UNUSED, + RK3576_CLKGATE_CON(72), 6, GFLAGS), + [PCLK_DMA2DDR] = GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_center_root", RT_CLK_F_IGNORE_UNUSED, + RK3576_CLKGATE_CON(72), 10, GFLAGS), + [PCLK_SHAREMEM] = GATE(PCLK_SHAREMEM, "pclk_sharemem", "pclk_center_root", RT_CLK_F_IGNORE_UNUSED, + RK3576_CLKGATE_CON(72), 11, GFLAGS), + [HCLK_VEPU1_ROOT] = COMPOSITE_NODIV(HCLK_VEPU1_ROOT, "hclk_vepu1_root", mux_200m_100m_50m_24m_p, 0, + RK3576_CLKSEL_CON(178), 0, 2, MFLAGS, + RK3576_CLKGATE_CON(78), 0, GFLAGS), + [ACLK_VEPU1_ROOT] = COMPOSITE(ACLK_VEPU1_ROOT, "aclk_vepu1_root", gpll_cpll_p, 0, + RK3576_CLKSEL_CON(180), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(79), 0, GFLAGS), + [HCLK_VEPU1] = GATE(HCLK_VEPU1, "hclk_vepu1", "hclk_vepu1_root", 0, + RK3576_CLKGATE_CON(79), 3, GFLAGS), + [ACLK_VEPU1] = GATE(ACLK_VEPU1, "aclk_vepu1", "aclk_vepu1_root", 0, + RK3576_CLKGATE_CON(79), 4, GFLAGS), + [CLK_VEPU1_CORE] = COMPOSITE(CLK_VEPU1_CORE, "clk_vepu1_core", gpll_cpll_spll_lpll_bpll_p, 0, + RK3576_CLKSEL_CON(180), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(79), 5, GFLAGS), + [PCLK_MIPI_DCPHY] = GATE(PCLK_MIPI_DCPHY, "pclk_mipi_dcphy", "pclk_pmuphy_root", 0, + RK3576_PMU_CLKGATE_CON(0), 2, GFLAGS), + [PCLK_CSIDPHY] = GATE(PCLK_CSIDPHY, "pclk_csidphy", "pclk_pmuphy_root", 0, + RK3576_PMU_CLKGATE_CON(0), 8, GFLAGS), + [PCLK_USBDPPHY] = GATE(PCLK_USBDPPHY, "pclk_usbdpphy", "pclk_pmuphy_root", 0, + RK3576_PMU_CLKGATE_CON(0), 12, GFLAGS), + [CLK_PMUPHY_REF_SRC] = COMPOSITE_NOMUX(CLK_PMUPHY_REF_SRC, "clk_pmuphy_ref_src", "cpll", 0, + RK3576_PMU_CLKSEL_CON(0), 0, 5, DFLAGS, + RK3576_PMU_CLKGATE_CON(0), 13, GFLAGS), + [CLK_USBDP_COMBO_PHY_IMMORTAL] = GATE(CLK_USBDP_COMBO_PHY_IMMORTAL, "clk_usbdp_combo_phy_immortal", "xin24m", 0, + RK3576_PMU_CLKGATE_CON(0), 15, GFLAGS), + [CLK_HDMITXHPD] = GATE(CLK_HDMITXHPD, "clk_hdmitxhpd", "xin24m", 0, + RK3576_PMU_CLKGATE_CON(1), 13, GFLAGS), + [PCLK_MPHY] = GATE(PCLK_MPHY, "pclk_mphy", "pclk_pmuphy_root", 0, + RK3576_PMU_CLKGATE_CON(2), 0, GFLAGS), + [CLK_REF_OSC_MPHY] = MUX(CLK_REF_OSC_MPHY, "clk_ref_osc_mphy", clk_ref_osc_mphy_p, 0, + RK3576_PMU_CLKSEL_CON(3), 0, 2, MFLAGS), + [CLK_REF_UFS_CLKOUT] = GATE(CLK_REF_UFS_CLKOUT, "clk_ref_ufs_clkout", "clk_ref_osc_mphy", 0, + RK3576_PMU_CLKGATE_CON(2), 5, GFLAGS), + [HCLK_PMU1_ROOT] = COMPOSITE_NODIV(HCLK_PMU1_ROOT, "hclk_pmu1_root", mux_pmu200m_pmu100m_pmu50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKSEL_CON(4), 0, 2, MFLAGS, + RK3576_PMU_CLKGATE_CON(3), 0, GFLAGS), + [HCLK_PMU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_PMU_CM0_ROOT, "hclk_pmu_cm0_root", mux_pmu200m_pmu100m_pmu50m_24m_p, 0, + RK3576_PMU_CLKSEL_CON(4), 2, 2, MFLAGS, + RK3576_PMU_CLKGATE_CON(3), 1, GFLAGS), + [CLK_200M_PMU_SRC] = GATE(CLK_200M_PMU_SRC, "clk_200m_pmu_src", "clk_gpll_div6", 0, + RK3576_PMU_CLKGATE_CON(3), 2, GFLAGS), + [CLK_100M_PMU_SRC] = COMPOSITE_NOMUX(CLK_100M_PMU_SRC, "clk_100m_pmu_src", "cpll", 0, + RK3576_PMU_CLKSEL_CON(4), 4, 5, DFLAGS, + RK3576_PMU_CLKGATE_CON(3), 3, GFLAGS), + [CLK_50M_PMU_SRC] = FACTOR_GATE(CLK_50M_PMU_SRC, "clk_50m_pmu_src", "clk_100m_pmu_src", 0, 1, 2, + RK3576_PMU_CLKGATE_CON(3), 4, GFLAGS), + [FCLK_PMU_CM0_CORE] = GATE(FCLK_PMU_CM0_CORE, "fclk_pmu_cm0_core", "hclk_pmu_cm0_root", 0, + RK3576_PMU_CLKGATE_CON(3), 12, GFLAGS), + [CLK_PMU_CM0_RTC] = COMPOSITE(CLK_PMU_CM0_RTC, "clk_pmu_cm0_rtc", mux_24m_32k_p, 0, + RK3576_PMU_CLKSEL_CON(4), 14, 1, MFLAGS, 9, 5, DFLAGS, + RK3576_PMU_CLKGATE_CON(3), 14, GFLAGS), + [PCLK_PMU1] = GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu1_root", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKGATE_CON(3), 15, GFLAGS), + [CLK_PMU1] = GATE(CLK_PMU1, "clk_pmu1", "xin24m", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKGATE_CON(4), 2, GFLAGS), + [PCLK_PMU1WDT] = GATE(PCLK_PMU1WDT, "pclk_pmu1wdt", "pclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(4), 5, GFLAGS), + [TCLK_PMU1WDT] = COMPOSITE_NODIV(TCLK_PMU1WDT, "tclk_pmu1wdt", mux_24m_32k_p, 0, + RK3576_PMU_CLKSEL_CON(4), 15, 1, MFLAGS, + RK3576_PMU_CLKGATE_CON(4), 6, GFLAGS), + [PCLK_PMUTIMER] = GATE(PCLK_PMUTIMER, "pclk_pmutimer", "pclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(4), 7, GFLAGS), + [CLK_PMUTIMER_ROOT] = COMPOSITE_NODIV(CLK_PMUTIMER_ROOT, "clk_pmutimer_root", mux_pmu100m_24m_32k_p, 0, + RK3576_PMU_CLKSEL_CON(5), 0, 2, MFLAGS, + RK3576_PMU_CLKGATE_CON(4), 8, GFLAGS), + [CLK_PMUTIMER0] = GATE(CLK_PMUTIMER0, "clk_pmutimer0", "clk_pmutimer_root", 0, + RK3576_PMU_CLKGATE_CON(4), 9, GFLAGS), + [CLK_PMUTIMER1] = GATE(CLK_PMUTIMER1, "clk_pmutimer1", "clk_pmutimer_root", 0, + RK3576_PMU_CLKGATE_CON(4), 10, GFLAGS), + [PCLK_PMU1PWM] = GATE(PCLK_PMU1PWM, "pclk_pmu1pwm", "pclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(4), 11, GFLAGS), + [CLK_PMU1PWM] = COMPOSITE_NODIV(CLK_PMU1PWM, "clk_pmu1pwm", mux_pmu100m_pmu50m_24m_p, 0, + RK3576_PMU_CLKSEL_CON(5), 2, 2, MFLAGS, + RK3576_PMU_CLKGATE_CON(4), 12, GFLAGS), + [CLK_PMU1PWM_OSC] = GATE(CLK_PMU1PWM_OSC, "clk_pmu1pwm_osc", "xin24m", 0, + RK3576_PMU_CLKGATE_CON(4), 13, GFLAGS), + [PCLK_PMUPHY_ROOT] = GATE(PCLK_PMUPHY_ROOT, "pclk_pmuphy_root", "pclk_pmu1_root", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKGATE_CON(5), 0, GFLAGS), + [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(5), 1, GFLAGS), + [CLK_I2C0] = COMPOSITE_NODIV(CLK_I2C0, "clk_i2c0", mux_pmu200m_pmu100m_pmu50m_24m_p, 0, + RK3576_PMU_CLKSEL_CON(6), 7, 2, MFLAGS, + RK3576_PMU_CLKGATE_CON(5), 2, GFLAGS), + [SCLK_UART1] = COMPOSITE_NODIV(SCLK_UART1, "sclk_uart1", uart1_p, RT_CLK_F_SET_RATE_PARENT, + RK3576_PMU_CLKSEL_CON(8), 0, 1, MFLAGS, + RK3576_PMU_CLKGATE_CON(5), 5, GFLAGS), + [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(5), 6, GFLAGS), + [CLK_PMU1PWM_RC] = GATE(CLK_PMU1PWM_RC, "clk_pmu1pwm_rc", "clk_pvtm_clkout", 0, + RK3576_PMU_CLKGATE_CON(5), 7, GFLAGS), + [CLK_PDM0] = GATE(CLK_PDM0, "clk_pdm0", "clk_pdm0_src_top", 0, + RK3576_PMU_CLKGATE_CON(5), 13, GFLAGS), + [HCLK_PDM0] = GATE(HCLK_PDM0, "hclk_pdm0", "hclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(5), 15, GFLAGS), + [MCLK_PDM0] = GATE(MCLK_PDM0, "mclk_pdm0", "mclk_pdm0_src_top", 0, + RK3576_PMU_CLKGATE_CON(6), 0, GFLAGS), + [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_pmu1_root", 0, + RK3576_PMU_CLKGATE_CON(6), 1, GFLAGS), + [CLK_PDM0_OUT] = GATE(CLK_PDM0_OUT, "clk_pdm0_out", "clk_pdm0", 0, + RK3576_PMU_CLKGATE_CON(6), 8, GFLAGS), + [CLK_HPTIMER_SRC] = COMPOSITE(CLK_HPTIMER_SRC, "clk_hptimer_src", cpll_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKSEL_CON(11), 6, 1, MFLAGS, 1, 5, DFLAGS, + RK3576_PMU_CLKGATE_CON(6), 10, GFLAGS), + [PCLK_PMU0_ROOT] = COMPOSITE_NODIV(PCLK_PMU0_ROOT, "pclk_pmu0_root", mux_pmu100m_pmu50m_24m_p, 0, + RK3576_PMU_CLKSEL_CON(20), 0, 2, MFLAGS, + RK3576_PMU_CLKGATE_CON(7), 0, GFLAGS), + [PCLK_PMU0] = GATE(PCLK_PMU0, "pclk_pmu0", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKGATE_CON(7), 3, GFLAGS), + [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu0_root", 0, + RK3576_PMU_CLKGATE_CON(7), 6, GFLAGS), + [DBCLK_GPIO0] = COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", mux_24m_32k_p, 0, + RK3576_PMU_CLKSEL_CON(20), 2, 1, MFLAGS, + RK3576_PMU_CLKGATE_CON(7), 7, GFLAGS), + [CLK_OSC0_PMU1] = GATE(CLK_OSC0_PMU1, "clk_osc0_pmu1", "xin24m", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKGATE_CON(7), 8, GFLAGS), + [PCLK_PMU1_ROOT] = GATE(PCLK_PMU1_ROOT, "pclk_pmu1_root", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKGATE_CON(7), 9, GFLAGS), + [XIN_OSC0_DIV] = COMPOSITE_FRAC(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", RT_CLK_F_IS_CRITICAL, + RK3576_PMU_CLKSEL_CON(21), 0, + RK3576_PMU_CLKGATE_CON(7), 11, GFLAGS), + [PCLK_CCI_ROOT] = COMPOSITE(PCLK_CCI_ROOT, "pclk_cci_root", mux_24m_ccipvtpll_gpll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CCI_CLKSEL_CON(4), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3576_CCI_CLKGATE_CON(1), 10, GFLAGS), + [ACLK_CCI_ROOT] = COMPOSITE(ACLK_CCI_ROOT, "aclk_cci_root", mux_24m_ccipvtpll_gpll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CCI_CLKSEL_CON(4), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3576_CCI_CLKGATE_CON(1), 11, GFLAGS), + [HCLK_VO0VOP_CHANNEL] = COMPOSITE_NODIV(HCLK_VO0VOP_CHANNEL, "hclk_vo0vop_channel", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(19), 6, 2, MFLAGS, + RK3576_CLKGATE_CON(2), 0, GFLAGS), + [ACLK_VO0VOP_CHANNEL] = COMPOSITE(ACLK_VO0VOP_CHANNEL, "aclk_vo0vop_channel", gpll_cpll_lpll_bpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(19), 12, 2, MFLAGS, 8, 4, DFLAGS, + RK3576_CLKGATE_CON(2), 1, GFLAGS), + [ACLK_TOP_MID] = COMPOSITE(ACLK_TOP_MID, "aclk_top_mid", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(10), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3576_CLKGATE_CON(1), 6, GFLAGS), + [ACLK_SECURE_HIGH] = COMPOSITE(ACLK_SECURE_HIGH, "aclk_secure_high", gpll_spll_aupll_bpll_lpll_p, RT_CLK_F_IS_CRITICAL, + RK3576_CLKSEL_CON(10), 11, 3, MFLAGS, 6, 5, DFLAGS, + RK3576_CLKGATE_CON(1), 7, GFLAGS), + [CLK_USBPHY_REF_SRC] = MUXGRF(CLK_USBPHY_REF_SRC, "clk_usbphy_ref_src", clk_usbphy_ref_src_p, 0, + RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS), + [CLK_PHY_REF_SRC] = MUXGRF(CLK_PHY_REF_SRC, "clk_phy_ref_src", clk_phy_ref_src_p, 0, + RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS), + [CLK_CPLL_REF_SRC] = MUXGRF(CLK_CPLL_REF_SRC, "clk_cpll_ref_src", clk_cpll_ref_src_p, 0, + RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS), + [CLK_AUPLL_REF_SRC] = MUXGRF(CLK_AUPLL_REF_SRC, "clk_aupll_ref_src", clk_aupll_ref_src_p, 0, + RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS), + [PCLK_SECURE_NS] = COMPOSITE_NODIV(PCLK_SECURE_NS, "pclk_secure_ns", mux_116m_58m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_SECURE_NS_CLKSEL_CON(0), 4, 2, MFLAGS, + RK3576_SECURE_NS_CLKGATE_CON(0), 2, GFLAGS), + [HCLK_SECURE_NS] = COMPOSITE_NODIV(HCLK_SECURE_NS, "hclk_secure_ns", mux_175m_116m_58m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_SECURE_NS_CLKSEL_CON(0), 2, 2, MFLAGS, + RK3576_SECURE_NS_CLKGATE_CON(0), 1, GFLAGS), + [ACLK_SECURE_NS] = COMPOSITE_NODIV(ACLK_SECURE_NS, "aclk_secure_ns", mux_350m_175m_116m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3576_SECURE_NS_CLKSEL_CON(0), 0, 2, MFLAGS, + RK3576_SECURE_NS_CLKGATE_CON(0), 0, GFLAGS), + [PCLK_OTPC_NS] = GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_secure_ns", 0, + RK3576_SECURE_NS_CLKGATE_CON(0), 8, GFLAGS), + [HCLK_CRYPTO_NS] = GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_secure_ns", 0, + RK3576_SECURE_NS_CLKGATE_CON(0), 3, GFLAGS), + [HCLK_TRNG_NS] = GATE(HCLK_TRNG_NS, "hclk_trng_ns", "hclk_secure_s", 0, + RK3576_NON_SECURE_GATING_CON00, 13, GFLAGS), + [CLK_OTPC_NS] = GATE(CLK_OTPC_NS, "clk_otpc_ns", "xin24m", 0, + RK3576_SECURE_NS_CLKGATE_CON(0), 9, GFLAGS), + [ACLK_CRYPTO_NS] = GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_secure_s", 0, + RK3576_NON_SECURE_GATING_CON00, 14, GFLAGS), + [CLK_PKA_CRYPTO_NS] = GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto_s", 0, + RK3576_NON_SECURE_GATING_CON00, 1, GFLAGS), + [ACLK_RKVDEC_ROOT_BAK] = COMPOSITE(ACLK_RKVDEC_ROOT_BAK, "aclk_rkvdec_root_bak", cpll_vpll_lpll_bpll_p, 0, + RK3576_CLKSEL_CON(110), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3576_CLKGATE_CON(45), 2, GFLAGS), + [CLK_AUDIO_FRAC_0_SRC] = MUX(CLK_AUDIO_FRAC_0_SRC, "clk_audio_frac_0_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(13), 0, 2, MFLAGS), + [CLK_AUDIO_FRAC_1_SRC] = MUX(CLK_AUDIO_FRAC_1_SRC, "clk_audio_frac_1_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(15), 0, 2, MFLAGS), + [CLK_AUDIO_FRAC_2_SRC] = MUX(CLK_AUDIO_FRAC_2_SRC, "clk_audio_frac_2_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(17), 0, 2, MFLAGS), + [CLK_AUDIO_FRAC_3_SRC] = MUX(CLK_AUDIO_FRAC_3_SRC, "clk_audio_frac_3_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(19), 0, 2, MFLAGS), + [PCLK_HDPTX_APB] = GATE(PCLK_HDPTX_APB, "pclk_hdptx_apb", "pclk_pmuphy_root", 0, + RK3576_PMU_CLKGATE_CON(0), 1, GFLAGS), + [PCLK_DDR_MON_CH1] = GATE(PCLK_DDR_MON_CH1, "pclk_ddr_mon_ch1", "pclk_ddr_root", 0, + RK3576_CLKGATE_CON(21), 14, GFLAGS), + + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + FACTOR(0, "clk_spll_div12", "spll", 0, 1, 12), + FACTOR(0, "clk_spll_div6", "spll", 0, 1, 6), + FACTOR(0, "clk_spll_div4", "spll", 0, 1, 4), + FACTOR(0, "lpll_div2", "lpll", 0, 1, 2), + FACTOR(0, "bpll_div4", "bpll", 0, 1, 4), + MUX(0, "clk_uart_frac_0_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(22), 0, 2, MFLAGS), + MUX(0, "clk_uart_frac_1_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(24), 0, 2, MFLAGS), + MUX(0, "clk_uart_frac_2_src", gpll_cpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(26), 0, 2, MFLAGS), + MUX(0, "dclk_ebc_frac_src_p", gpll_cpll_vpll_aupll_24m_p, 0, + RK3576_CLKSEL_CON(123), 0, 3, MFLAGS), +}; + +static rt_err_t clk_rk3576_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + struct clk_rk3576_cru *cru = rt_calloc(1, sizeof(*cru)); + + if (!cru) + { + return -RT_ENOMEM; + } + + cru->provider.reg_base = rt_dm_dev_iomap(dev, 0); + + if (!cru->provider.reg_base) + { + err = -RT_EIO; + goto _fail; + } + + cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf"); + cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf"); + + cru->clk_parent.dev = dev; + cru->clk_parent.cells = rk3576_clk_cells; + cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3576_clk_cells); + + rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rt_clk_register(&cru->clk_parent))) + { + goto _fail; + } + + rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL, + cru->provider.reg_base + RK3576_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK))) + { + goto _clk_unregister; + } + + rockchip_register_restart_notifier(&cru->provider, RK3576_GLB_SRST_FST, RT_NULL); + + return RT_EOK; + +_clk_unregister: + rt_clk_unregister(&cru->clk_parent); + +_fail: + if (cru->provider.reg_base) + { + rt_iounmap(cru->provider.reg_base); + } + + rt_free(cru); + + return err; +} + +static const struct rt_ofw_node_id clk_rk3576_ofw_ids[] = +{ + { .compatible = "rockchip,rk3576-cru", }, + { /* sentinel */ } +}; + +static struct rt_platform_driver clk_rk3576_driver = +{ + .name = "clk-rk3576", + .ids = clk_rk3576_ofw_ids, + + .probe = clk_rk3576_probe, +}; + +static int clk_rk3576_register(void) +{ + rt_platform_driver_register(&clk_rk3576_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(clk_rk3576_register); diff --git a/bsp/rockchip/dm/clk/clk-rk3588.c b/bsp/rockchip/dm/clk/clk-rk3588.c new file mode 100755 index 00000000000..14a6005f40d --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk3588.c @@ -0,0 +1,2166 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "clk-rk-composite.h" +#include "clk-rk-cpu.h" +#include "clk-rk-divider.h" +#include "clk-rk-factor.h" +#include "clk-rk-fraction-divider.h" +#include "clk-rk-gate.h" +#include "clk-rk.h" +#include "clk-rk-half-divider.h" +#include "clk-rk-mmc-phase.h" +#include "clk-rk-muxgrf.h" +#include "clk-rk-mux.h" +#include "clk-rk-pll.h" + +#define DBG_TAG "clk.rk3588" +#define DBG_LVL DBG_INFO +#include + +#include + +#define RK3588_GRF_SOC_STATUS0 0x600 +#define RK3588_PHYREF_ALT_GATE 0xc38 +#define RK3588_FRAC_MAX_PRATE 1500000000 +#define RK3588_DCLK_MAX_PRATE 594000000 + +#define RK3588_PHP_CRU_BASE 0x8000 +#define RK3588_PMU_CRU_BASE 0x30000 +#define RK3588_BIGCORE0_CRU_BASE 0x50000 +#define RK3588_BIGCORE1_CRU_BASE 0x52000 +#define RK3588_DSU_CRU_BASE 0x58000 + +#define RK3588_PLL_CON(x) ((x) * 0x4) +#define RK3588_MODE_CON0 0x280 +#define RK3588_B0_PLL_MODE_CON0 (RK3588_BIGCORE0_CRU_BASE + 0x280) +#define RK3588_B1_PLL_MODE_CON0 (RK3588_BIGCORE1_CRU_BASE + 0x280) +#define RK3588_LPLL_MODE_CON0 (RK3588_DSU_CRU_BASE + 0x280) +#define RK3588_CLKSEL_CON(x) ((x) * 0x4 + 0x300) +#define RK3588_CLKGATE_CON(x) ((x) * 0x4 + 0x800) +#define RK3588_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) +#define RK3588_GLB_CNT_TH 0xc00 +#define RK3588_GLB_SRST_FST 0xc08 +#define RK3588_GLB_SRST_SND 0xc0c +#define RK3588_GLB_RST_CON 0xc10 +#define RK3588_GLB_RST_ST 0xc04 +#define RK3588_SDIO_CON0 0xc24 +#define RK3588_SDIO_CON1 0xc28 +#define RK3588_SDMMC_CON0 0xc30 +#define RK3588_SDMMC_CON1 0xc34 + +#define RK3588_PHP_CLKGATE_CON(x) ((x) * 0x4 + RK3588_PHP_CRU_BASE + 0x800) +#define RK3588_PHP_SOFTRST_CON(x) ((x) * 0x4 + RK3588_PHP_CRU_BASE + 0xa00) + +#define RK3588_PMU_PLL_CON(x) ((x) * 0x4 + RK3588_PHP_CRU_BASE) +#define RK3588_PMU_CLKSEL_CON(x) ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x300) +#define RK3588_PMU_CLKGATE_CON(x) ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0x800) +#define RK3588_PMU_SOFTRST_CON(x) ((x) * 0x4 + RK3588_PMU_CRU_BASE + 0xa00) + +#define RK3588_B0_PLL_CON(x) ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE) +#define RK3588_BIGCORE0_CLKSEL_CON(x) ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x300) +#define RK3588_BIGCORE0_CLKGATE_CON(x) ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0x800) +#define RK3588_BIGCORE0_SOFTRST_CON(x) ((x) * 0x4 + RK3588_BIGCORE0_CRU_BASE + 0xa00) +#define RK3588_B1_PLL_CON(x) ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE) +#define RK3588_BIGCORE1_CLKSEL_CON(x) ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x300) +#define RK3588_BIGCORE1_CLKGATE_CON(x) ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0x800) +#define RK3588_BIGCORE1_SOFTRST_CON(x) ((x) * 0x4 + RK3588_BIGCORE1_CRU_BASE + 0xa00) +#define RK3588_LPLL_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE) +#define RK3588_DSU_CLKSEL_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x300) +#define RK3588_DSU_CLKGATE_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0x800) +#define RK3588_DSU_SOFTRST_CON(x) ((x) * 0x4 + RK3588_DSU_CRU_BASE + 0xa00) + +#define RK3588_CLK_CORE_B0_SEL_CLEAN_MASK 0x3 +#define RK3588_CLK_CORE_B0_SEL_CLEAN_SHIFT 13 +#define RK3588_CLK_CORE_B1_SEL_CLEAN_MASK 0x3 +#define RK3588_CLK_CORE_B1_SEL_CLEAN_SHIFT 5 +#define RK3588_CLK_CORE_B0_GPLL_DIV_MASK 0x1f +#define RK3588_CLK_CORE_B0_GPLL_DIV_SHIFT 1 +#define RK3588_CLK_CORE_L_SEL_CLEAN_MASK 0x3 +#define RK3588_CLK_CORE_L1_SEL_CLEAN_SHIFT 12 +#define RK3588_CLK_CORE_L0_SEL_CLEAN_SHIFT 5 +#define RK3588_CLK_DSU_SEL_DF_MASK 0x1 +#define RK3588_CLK_DSU_SEL_DF_SHIFT 15 +#define RK3588_CLK_DSU_DF_SRC_MASK 0x3 +#define RK3588_CLK_DSU_DF_SRC_SHIFT 12 +#define RK3588_CLK_DSU_DF_DIV_MASK 0x1f +#define RK3588_CLK_DSU_DF_DIV_SHIFT 7 +#define RK3588_ACLKM_DSU_DIV_MASK 0x1f +#define RK3588_ACLKM_DSU_DIV_SHIFT 1 +#define RK3588_ACLKS_DSU_DIV_MASK 0x1f +#define RK3588_ACLKS_DSU_DIV_SHIFT 6 +#define RK3588_ACLKMP_DSU_DIV_MASK 0x1f +#define RK3588_ACLKMP_DSU_DIV_SHIFT 11 +#define RK3588_PERIPH_DSU_DIV_MASK 0x1f +#define RK3588_PERIPH_DSU_DIV_SHIFT 0 +#define RK3588_ATCLK_DSU_DIV_MASK 0x1f +#define RK3588_ATCLK_DSU_DIV_SHIFT 0 +#define RK3588_GICCLK_DSU_DIV_MASK 0x1f +#define RK3588_GICCLK_DSU_DIV_SHIFT 5 + +struct clk_rk3588_cru +{ + struct rt_clk_node clk_parent; + struct rt_reset_controller rstc_parent; + + struct rockchip_clk_provider provider; +}; + +static struct rockchip_pll_rate_table rk3588_pll_rates[] = +{ + /* _mhz, _p, _m, _s, _k */ + RK3588_PLL_RATE(2520000000, 2, 210, 0, 0), + RK3588_PLL_RATE(2496000000, 2, 208, 0, 0), + RK3588_PLL_RATE(2472000000, 2, 206, 0, 0), + RK3588_PLL_RATE(2448000000, 2, 204, 0, 0), + RK3588_PLL_RATE(2424000000, 2, 202, 0, 0), + RK3588_PLL_RATE(2400000000, 2, 200, 0, 0), + RK3588_PLL_RATE(2376000000, 2, 198, 0, 0), + RK3588_PLL_RATE(2352000000, 2, 196, 0, 0), + RK3588_PLL_RATE(2328000000, 2, 194, 0, 0), + RK3588_PLL_RATE(2304000000, 2, 192, 0, 0), + RK3588_PLL_RATE(2280000000, 2, 190, 0, 0), + RK3588_PLL_RATE(2256000000, 2, 376, 1, 0), + RK3588_PLL_RATE(2232000000, 2, 372, 1, 0), + RK3588_PLL_RATE(2208000000, 2, 368, 1, 0), + RK3588_PLL_RATE(2184000000, 2, 364, 1, 0), + RK3588_PLL_RATE(2160000000, 2, 360, 1, 0), + RK3588_PLL_RATE(2136000000, 2, 356, 1, 0), + RK3588_PLL_RATE(2112000000, 2, 352, 1, 0), + RK3588_PLL_RATE(2088000000, 2, 348, 1, 0), + RK3588_PLL_RATE(2064000000, 2, 344, 1, 0), + RK3588_PLL_RATE(2040000000, 2, 340, 1, 0), + RK3588_PLL_RATE(2016000000, 2, 336, 1, 0), + RK3588_PLL_RATE(1992000000, 2, 332, 1, 0), + RK3588_PLL_RATE(1968000000, 2, 328, 1, 0), + RK3588_PLL_RATE(1944000000, 2, 324, 1, 0), + RK3588_PLL_RATE(1920000000, 2, 320, 1, 0), + RK3588_PLL_RATE(1896000000, 2, 316, 1, 0), + RK3588_PLL_RATE(1872000000, 2, 312, 1, 0), + RK3588_PLL_RATE(1848000000, 2, 308, 1, 0), + RK3588_PLL_RATE(1824000000, 2, 304, 1, 0), + RK3588_PLL_RATE(1800000000, 2, 300, 1, 0), + RK3588_PLL_RATE(1776000000, 2, 296, 1, 0), + RK3588_PLL_RATE(1752000000, 2, 292, 1, 0), + RK3588_PLL_RATE(1728000000, 2, 288, 1, 0), + RK3588_PLL_RATE(1704000000, 2, 284, 1, 0), + RK3588_PLL_RATE(1680000000, 2, 280, 1, 0), + RK3588_PLL_RATE(1656000000, 2, 276, 1, 0), + RK3588_PLL_RATE(1632000000, 2, 272, 1, 0), + RK3588_PLL_RATE(1608000000, 2, 268, 1, 0), + RK3588_PLL_RATE(1584000000, 2, 264, 1, 0), + RK3588_PLL_RATE(1560000000, 2, 260, 1, 0), + RK3588_PLL_RATE(1536000000, 2, 256, 1, 0), + RK3588_PLL_RATE(1512000000, 2, 252, 1, 0), + RK3588_PLL_RATE(1488000000, 2, 248, 1, 0), + RK3588_PLL_RATE(1464000000, 2, 244, 1, 0), + RK3588_PLL_RATE(1440000000, 2, 240, 1, 0), + RK3588_PLL_RATE(1416000000, 2, 236, 1, 0), + RK3588_PLL_RATE(1392000000, 2, 232, 1, 0), + RK3588_PLL_RATE(1320000000, 2, 220, 1, 0), + RK3588_PLL_RATE(1200000000, 2, 200, 1, 0), + RK3588_PLL_RATE(1188000000, 2, 198, 1, 0), + RK3588_PLL_RATE(1186814000, 2, 198, 1, 52581), + RK3588_PLL_RATE(1186812000, 2, 198, 1, 52559), + RK3588_PLL_RATE(1109000000, 3, 554, 2, 32767), + RK3588_PLL_RATE(1100000000, 3, 550, 2, 0), + RK3588_PLL_RATE(1051000000, 3, 525, 2, 32767), + RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), + RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), + RK3588_PLL_RATE(983040000, 4, 655, 2, 23592), + RK3588_PLL_RATE(955520000, 3, 478, 2, 49807), + RK3588_PLL_RATE(903168000, 6, 903, 2, 11009), + RK3588_PLL_RATE(900000000, 2, 300, 2, 0), + RK3588_PLL_RATE(816000000, 2, 272, 2, 0), + RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), + RK3588_PLL_RATE(786000000, 1, 131, 2, 0), + RK3588_PLL_RATE(785560000, 3, 393, 2, 51119), + RK3588_PLL_RATE(773000000, 2, 258, 2, 43690), + RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), + RK3588_PLL_RATE(697000000, 2, 232, 2, 21845), + RK3588_PLL_RATE(604800000, 1, 101, 2, 52428), + RK3588_PLL_RATE(600000000, 2, 200, 2, 0), + RK3588_PLL_RATE(594000000, 1, 99, 2, 0), + RK3588_PLL_RATE(408000000, 2, 272, 3, 0), + RK3588_PLL_RATE(312000000, 2, 208, 3, 0), + RK3588_PLL_RATE(266580000, 1, 178, 4, 47185), + RK3588_PLL_RATE(216000000, 2, 288, 4, 0), + RK3588_PLL_RATE(96000000, 2, 256, 5, 0), + { /* sentinel */ }, +}; + +#define RK3588_CORE_B0_SEL(_apllcore) \ +{ \ + .reg = RK3588_BIGCORE0_CLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B0_SEL_CLEAN_MASK, \ + RK3588_CLK_CORE_B0_SEL_CLEAN_SHIFT) | \ + HIWORD_UPDATE(0, RK3588_CLK_CORE_B0_GPLL_DIV_MASK, \ + RK3588_CLK_CORE_B0_GPLL_DIV_SHIFT), \ +} + +#define RK3588_CORE_B1_SEL(_apllcore) \ +{ \ + .reg = RK3588_BIGCORE0_CLKSEL_CON(1), \ + .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B1_SEL_CLEAN_MASK, \ + RK3588_CLK_CORE_B1_SEL_CLEAN_SHIFT), \ +} + +#define RK3588_CORE_B2_SEL(_apllcore) \ +{ \ + .reg = RK3588_BIGCORE1_CLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B0_SEL_CLEAN_MASK, \ + RK3588_CLK_CORE_B0_SEL_CLEAN_SHIFT) | \ + HIWORD_UPDATE(0, RK3588_CLK_CORE_B0_GPLL_DIV_MASK, \ + RK3588_CLK_CORE_B0_GPLL_DIV_SHIFT), \ +} + +#define RK3588_CORE_B3_SEL(_apllcore) \ +{ \ + .reg = RK3588_BIGCORE1_CLKSEL_CON(1), \ + .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_B1_SEL_CLEAN_MASK, \ + RK3588_CLK_CORE_B1_SEL_CLEAN_SHIFT), \ +} + +#define RK3588_CORE_L_SEL0(_offs, _apllcore) \ +{ \ + .reg = RK3588_DSU_CLKSEL_CON(6 + _offs), \ + .val = HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_L_SEL_CLEAN_MASK, \ + RK3588_CLK_CORE_L0_SEL_CLEAN_SHIFT) | \ + HIWORD_UPDATE(_apllcore, RK3588_CLK_CORE_L_SEL_CLEAN_MASK, \ + RK3588_CLK_CORE_L1_SEL_CLEAN_SHIFT), \ +} + +#define RK3588_CORE_L_SEL1(_seldsu, _divdsu) \ +{ \ + .reg = RK3588_DSU_CLKSEL_CON(0), \ + .val = HIWORD_UPDATE(_seldsu, RK3588_CLK_DSU_DF_SRC_MASK, \ + RK3588_CLK_DSU_DF_SRC_SHIFT) | \ + HIWORD_UPDATE(_divdsu - 1, RK3588_CLK_DSU_DF_DIV_MASK, \ + RK3588_CLK_DSU_DF_DIV_SHIFT), \ +} + +#define RK3588_CORE_L_SEL2(_aclkm, _aclkmp, _aclks) \ +{ \ + .reg = RK3588_DSU_CLKSEL_CON(1), \ + .val = HIWORD_UPDATE(_aclkm - 1, RK3588_ACLKM_DSU_DIV_MASK, \ + RK3588_ACLKM_DSU_DIV_SHIFT) | \ + HIWORD_UPDATE(_aclkmp - 1, RK3588_ACLKMP_DSU_DIV_MASK, \ + RK3588_ACLKMP_DSU_DIV_SHIFT) | \ + HIWORD_UPDATE(_aclks - 1, RK3588_ACLKS_DSU_DIV_MASK, \ + RK3588_ACLKS_DSU_DIV_SHIFT), \ +} + +#define RK3588_CORE_L_SEL3(_periph) \ +{ \ + .reg = RK3588_DSU_CLKSEL_CON(2), \ + .val = HIWORD_UPDATE(_periph - 1, RK3588_PERIPH_DSU_DIV_MASK, \ + RK3588_PERIPH_DSU_DIV_SHIFT), \ +} + +#define RK3588_CORE_L_SEL4(_gicclk, _atclk) \ +{ \ + .reg = RK3588_DSU_CLKSEL_CON(3), \ + .val = HIWORD_UPDATE(_gicclk - 1, RK3588_GICCLK_DSU_DIV_MASK, \ + RK3588_GICCLK_DSU_DIV_SHIFT) | \ + HIWORD_UPDATE(_atclk - 1, RK3588_ATCLK_DSU_DIV_MASK, \ + RK3588_ATCLK_DSU_DIV_SHIFT), \ +} + +#define RK3588_CPUB01CLK_RATE(_prate, _apllcore) \ +{ \ + .prate = _prate##U, \ + .pre_muxs = \ + { \ + RK3588_CORE_B0_SEL(0), \ + RK3588_CORE_B1_SEL(0), \ + }, \ + .post_muxs = \ + { \ + RK3588_CORE_B0_SEL(_apllcore), \ + RK3588_CORE_B1_SEL(_apllcore), \ + }, \ +} + +#define RK3588_CPUB23CLK_RATE(_prate, _apllcore) \ +{ \ + .prate = _prate##U, \ + .pre_muxs = \ + { \ + RK3588_CORE_B2_SEL(0), \ + RK3588_CORE_B3_SEL(0), \ + }, \ + .post_muxs = \ + { \ + RK3588_CORE_B2_SEL(_apllcore), \ + RK3588_CORE_B3_SEL(_apllcore), \ + }, \ + } + +#define RK3588_CPULCLK_RATE(_prate, _apllcore, _seldsu, _divdsu) \ +{ \ + .prate = _prate##U, \ + .pre_muxs = \ + { \ + RK3588_CORE_L_SEL0(0, 0), \ + RK3588_CORE_L_SEL0(1, 0), \ + RK3588_CORE_L_SEL1(3, 2), \ + RK3588_CORE_L_SEL2(2, 3, 3), \ + RK3588_CORE_L_SEL3(4), \ + RK3588_CORE_L_SEL4(4, 4), \ + }, \ + .post_muxs = \ + { \ + RK3588_CORE_L_SEL0(0, _apllcore), \ + RK3588_CORE_L_SEL0(1, _apllcore), \ + RK3588_CORE_L_SEL1(_seldsu, _divdsu), \ + }, \ +} + +static struct rockchip_cpu_clk_rate_table rk3588_cpub0clk_rates[] = +{ + RK3588_CPUB01CLK_RATE(2496000000, 1), + RK3588_CPUB01CLK_RATE(2400000000, 1), + RK3588_CPUB01CLK_RATE(2304000000, 1), + RK3588_CPUB01CLK_RATE(2208000000, 1), + RK3588_CPUB01CLK_RATE(2184000000, 1), + RK3588_CPUB01CLK_RATE(2088000000, 1), + RK3588_CPUB01CLK_RATE(2040000000, 1), + RK3588_CPUB01CLK_RATE(2016000000, 1), + RK3588_CPUB01CLK_RATE(1992000000, 1), + RK3588_CPUB01CLK_RATE(1896000000, 1), + RK3588_CPUB01CLK_RATE(1800000000, 1), + RK3588_CPUB01CLK_RATE(1704000000, 0), + RK3588_CPUB01CLK_RATE(1608000000, 0), + RK3588_CPUB01CLK_RATE(1584000000, 0), + RK3588_CPUB01CLK_RATE(1560000000, 0), + RK3588_CPUB01CLK_RATE(1536000000, 0), + RK3588_CPUB01CLK_RATE(1512000000, 0), + RK3588_CPUB01CLK_RATE(1488000000, 0), + RK3588_CPUB01CLK_RATE(1464000000, 0), + RK3588_CPUB01CLK_RATE(1440000000, 0), + RK3588_CPUB01CLK_RATE(1416000000, 0), + RK3588_CPUB01CLK_RATE(1392000000, 0), + RK3588_CPUB01CLK_RATE(1368000000, 0), + RK3588_CPUB01CLK_RATE(1344000000, 0), + RK3588_CPUB01CLK_RATE(1320000000, 0), + RK3588_CPUB01CLK_RATE(1296000000, 0), + RK3588_CPUB01CLK_RATE(1272000000, 0), + RK3588_CPUB01CLK_RATE(1248000000, 0), + RK3588_CPUB01CLK_RATE(1224000000, 0), + RK3588_CPUB01CLK_RATE(1200000000, 0), + RK3588_CPUB01CLK_RATE(1104000000, 0), + RK3588_CPUB01CLK_RATE(1008000000, 0), + RK3588_CPUB01CLK_RATE(912000000, 0), + RK3588_CPUB01CLK_RATE(816000000, 0), + RK3588_CPUB01CLK_RATE(696000000, 0), + RK3588_CPUB01CLK_RATE(600000000, 0), + RK3588_CPUB01CLK_RATE(408000000, 0), + RK3588_CPUB01CLK_RATE(312000000, 0), + RK3588_CPUB01CLK_RATE(216000000, 0), + RK3588_CPUB01CLK_RATE(96000000, 0), +}; + +static const struct rockchip_cpu_clk_reg_data rk3588_cpub0clk_data = +{ + .core_reg[0] = RK3588_BIGCORE0_CLKSEL_CON(0), + .div_core_shift[0] = 8, + .div_core_mask[0] = 0x1f, + .core_reg[1] = RK3588_BIGCORE0_CLKSEL_CON(1), + .div_core_shift[1] = 0, + .div_core_mask[1] = 0x1f, + .num_cores = 2, + .mux_core_alt = 1, + .mux_core_main = 2, + .mux_core_shift = 6, + .mux_core_mask = 0x3, +}; + +static struct rockchip_cpu_clk_rate_table rk3588_cpub1clk_rates[] = +{ + RK3588_CPUB23CLK_RATE(2496000000, 1), + RK3588_CPUB23CLK_RATE(2400000000, 1), + RK3588_CPUB23CLK_RATE(2304000000, 1), + RK3588_CPUB23CLK_RATE(2208000000, 1), + RK3588_CPUB23CLK_RATE(2184000000, 1), + RK3588_CPUB23CLK_RATE(2088000000, 1), + RK3588_CPUB23CLK_RATE(2040000000, 1), + RK3588_CPUB23CLK_RATE(2016000000, 1), + RK3588_CPUB23CLK_RATE(1992000000, 1), + RK3588_CPUB23CLK_RATE(1896000000, 1), + RK3588_CPUB23CLK_RATE(1800000000, 1), + RK3588_CPUB23CLK_RATE(1704000000, 0), + RK3588_CPUB23CLK_RATE(1608000000, 0), + RK3588_CPUB23CLK_RATE(1584000000, 0), + RK3588_CPUB23CLK_RATE(1560000000, 0), + RK3588_CPUB23CLK_RATE(1536000000, 0), + RK3588_CPUB23CLK_RATE(1512000000, 0), + RK3588_CPUB23CLK_RATE(1488000000, 0), + RK3588_CPUB23CLK_RATE(1464000000, 0), + RK3588_CPUB23CLK_RATE(1440000000, 0), + RK3588_CPUB23CLK_RATE(1416000000, 0), + RK3588_CPUB23CLK_RATE(1392000000, 0), + RK3588_CPUB23CLK_RATE(1368000000, 0), + RK3588_CPUB23CLK_RATE(1344000000, 0), + RK3588_CPUB23CLK_RATE(1320000000, 0), + RK3588_CPUB23CLK_RATE(1296000000, 0), + RK3588_CPUB23CLK_RATE(1272000000, 0), + RK3588_CPUB23CLK_RATE(1248000000, 0), + RK3588_CPUB23CLK_RATE(1224000000, 0), + RK3588_CPUB23CLK_RATE(1200000000, 0), + RK3588_CPUB23CLK_RATE(1104000000, 0), + RK3588_CPUB23CLK_RATE(1008000000, 0), + RK3588_CPUB23CLK_RATE(912000000, 0), + RK3588_CPUB23CLK_RATE(816000000, 0), + RK3588_CPUB23CLK_RATE(696000000, 0), + RK3588_CPUB23CLK_RATE(600000000, 0), + RK3588_CPUB23CLK_RATE(408000000, 0), + RK3588_CPUB23CLK_RATE(312000000, 0), + RK3588_CPUB23CLK_RATE(216000000, 0), + RK3588_CPUB23CLK_RATE(96000000, 0), +}; + +static const struct rockchip_cpu_clk_reg_data rk3588_cpub1clk_data = +{ + .core_reg[0] = RK3588_BIGCORE1_CLKSEL_CON(0), + .div_core_shift[0] = 8, + .div_core_mask[0] = 0x1f, + .core_reg[1] = RK3588_BIGCORE1_CLKSEL_CON(1), + .div_core_shift[1] = 0, + .div_core_mask[1] = 0x1f, + .num_cores = 2, + .mux_core_alt = 1, + .mux_core_main = 2, + .mux_core_shift = 6, + .mux_core_mask = 0x3, +}; + +static struct rockchip_cpu_clk_rate_table rk3588_cpulclk_rates[] = +{ + RK3588_CPULCLK_RATE(2208000000, 1, 3, 1), + RK3588_CPULCLK_RATE(2184000000, 1, 3, 1), + RK3588_CPULCLK_RATE(2088000000, 1, 3, 1), + RK3588_CPULCLK_RATE(2040000000, 1, 3, 1), + RK3588_CPULCLK_RATE(2016000000, 1, 3, 1), + RK3588_CPULCLK_RATE(1992000000, 1, 3, 1), + RK3588_CPULCLK_RATE(1896000000, 1, 3, 1), + RK3588_CPULCLK_RATE(1800000000, 1, 3, 1), + RK3588_CPULCLK_RATE(1704000000, 0, 3, 1), + RK3588_CPULCLK_RATE(1608000000, 0, 3, 1), + RK3588_CPULCLK_RATE(1584000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1560000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1536000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1512000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1488000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1464000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1440000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1416000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1392000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1368000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1344000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1320000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1296000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1272000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1248000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1224000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1200000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1104000000, 0, 2, 1), + RK3588_CPULCLK_RATE(1008000000, 0, 2, 1), + RK3588_CPULCLK_RATE(912000000, 0, 2, 1), + RK3588_CPULCLK_RATE(816000000, 0, 2, 1), + RK3588_CPULCLK_RATE(696000000, 0, 2, 1), + RK3588_CPULCLK_RATE(600000000, 0, 2, 1), + RK3588_CPULCLK_RATE(408000000, 0, 2, 1), + RK3588_CPULCLK_RATE(312000000, 0, 2, 1), + RK3588_CPULCLK_RATE(216000000, 0, 2, 1), + RK3588_CPULCLK_RATE(96000000, 0, 2, 1), +}; + +static const struct rockchip_cpu_clk_reg_data rk3588_cpulclk_data = +{ + .core_reg[0] = RK3588_DSU_CLKSEL_CON(6), + .div_core_shift[0] = 0, + .div_core_mask[0] = 0x1f, + .core_reg[1] = RK3588_DSU_CLKSEL_CON(6), + .div_core_shift[1] = 7, + .div_core_mask[1] = 0x1f, + .core_reg[2] = RK3588_DSU_CLKSEL_CON(7), + .div_core_shift[2] = 0, + .div_core_mask[2] = 0x1f, + .core_reg[3] = RK3588_DSU_CLKSEL_CON(7), + .div_core_shift[3] = 7, + .div_core_mask[3] = 0x1f, + .num_cores = 4, + .mux_core_reg = RK3588_DSU_CLKSEL_CON(5), + .mux_core_alt = 1, + .mux_core_main = 2, + .mux_core_shift = 14, + .mux_core_mask = 0x3, +}; + +PNAMES(mux_pll_p) = { "xin24m", "xin32k" }; +PNAMES(b0pll_b1pll_lpll_gpll_p) = { "b0pll", "b1pll", "lpll", "gpll" }; +PNAMES(gpll_24m_p) = { "gpll", "xin24m" }; +PNAMES(gpll_aupll_p) = { "gpll", "aupll" }; +PNAMES(gpll_lpll_p) = { "gpll", "lpll" }; +PNAMES(gpll_cpll_p) = { "gpll", "cpll" }; +PNAMES(gpll_spll_p) = { "gpll", "spll" }; +PNAMES(gpll_cpll_24m_p) = { "gpll", "cpll", "xin24m"}; +PNAMES(gpll_cpll_aupll_p) = { "gpll", "cpll", "aupll"}; +PNAMES(gpll_cpll_npll_p) = { "gpll", "cpll", "npll"}; +PNAMES(gpll_cpll_npll_v0pll_p) = { "gpll", "cpll", "npll", "v0pll"}; +PNAMES(gpll_cpll_24m_spll_p) = { "gpll", "cpll", "xin24m", "spll" }; +PNAMES(gpll_cpll_aupll_spll_p) = { "gpll", "cpll", "aupll", "spll" }; +PNAMES(gpll_cpll_aupll_npll_p) = { "gpll", "cpll", "aupll", "npll" }; +PNAMES(gpll_cpll_v0pll_aupll_p) = { "gpll", "cpll", "v0pll", "aupll" }; +PNAMES(gpll_cpll_v0pll_spll_p) = { "gpll", "cpll", "v0pll", "spll" }; +PNAMES(gpll_cpll_aupll_npll_spll_p) = { "gpll", "cpll", "aupll", "npll", "spll" }; +PNAMES(gpll_cpll_dmyaupll_npll_spll_p) = { "gpll", "cpll", "dummy_aupll", "npll", "spll" }; +PNAMES(gpll_cpll_npll_aupll_spll_p) = { "gpll", "cpll", "npll", "aupll", "spll" }; +PNAMES(gpll_cpll_npll_1000m_p) = { "gpll", "cpll", "npll", "clk_1000m_src" }; +PNAMES(mux_24m_spll_gpll_cpll_p) = { "xin24m", "spll", "gpll", "cpll" }; +PNAMES(mux_24m_32k_p) = { "xin24m", "xin32k" }; +PNAMES(mux_24m_100m_p) = { "xin24m", "clk_100m_src" }; +PNAMES(mux_200m_100m_p) = { "clk_200m_src", "clk_100m_src" }; +PNAMES(mux_100m_50m_24m_p) = { "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAMES(mux_150m_50m_24m_p) = { "clk_150m_src", "clk_50m_src", "xin24m" }; +PNAMES(mux_150m_100m_24m_p) = { "clk_150m_src", "clk_100m_src", "xin24m" }; +PNAMES(mux_200m_150m_24m_p) = { "clk_200m_src", "clk_150m_src", "xin24m" }; +PNAMES(mux_150m_100m_50m_24m_p) = { "clk_150m_src", "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAMES(mux_200m_100m_50m_24m_p) = { "clk_200m_src", "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAMES(mux_300m_200m_100m_24m_p) = { "clk_300m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAMES(mux_700m_400m_200m_24m_p) = { "clk_700m_src", "clk_400m_src", "clk_200m_src", "xin24m" }; +PNAMES(mux_500m_250m_100m_24m_p) = { "clk_500m_src", "clk_250m_src", "clk_100m_src", "xin24m" }; +PNAMES(mux_500m_300m_100m_24m_p) = { "clk_500m_src", "clk_300m_src", "clk_100m_src", "xin24m" }; +PNAMES(mux_400m_200m_100m_24m_p) = { "clk_400m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAMES(clk_i2s2_2ch_p) = { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "i2s2_mclkin", "xin12m" }; +PNAMES(i2s2_2ch_mclkout_p) = { "mclk_i2s2_2ch", "xin12m" }; +PNAMES(clk_i2s3_2ch_p) = { "clk_i2s3_2ch_src", "clk_i2s3_2ch_frac", "i2s3_mclkin", "xin12m" }; +PNAMES(i2s3_2ch_mclkout_p) = { "mclk_i2s3_2ch", "xin12m" }; +PNAMES(clk_i2s0_8ch_tx_p) = { "clk_i2s0_8ch_tx_src", "clk_i2s0_8ch_tx_frac", "i2s0_mclkin", "xin12m" }; +PNAMES(clk_i2s0_8ch_rx_p) = { "clk_i2s0_8ch_rx_src", "clk_i2s0_8ch_rx_frac", "i2s0_mclkin", "xin12m" }; +PNAMES(i2s0_8ch_mclkout_p) = { "mclk_i2s0_8ch_tx", "mclk_i2s0_8ch_rx", "xin12m" }; +PNAMES(clk_i2s1_8ch_tx_p) = { "clk_i2s1_8ch_tx_src", "clk_i2s1_8ch_tx_frac", "i2s1_mclkin", "xin12m" }; +PNAMES(clk_i2s1_8ch_rx_p) = { "clk_i2s1_8ch_rx_src", "clk_i2s1_8ch_rx_frac", "i2s1_mclkin", "xin12m" }; +PNAMES(i2s1_8ch_mclkout_p) = { "mclk_i2s1_8ch_tx", "mclk_i2s1_8ch_rx", "xin12m" }; +PNAMES(clk_i2s4_8ch_tx_p) = { "clk_i2s4_8ch_tx_src", "clk_i2s4_8ch_tx_frac", "i2s4_mclkin", "xin12m" }; +PNAMES(clk_i2s5_8ch_tx_p) = { "clk_i2s5_8ch_tx_src", "clk_i2s5_8ch_tx_frac", "i2s5_mclkin", "xin12m" }; +PNAMES(clk_i2s6_8ch_tx_p) = { "clk_i2s6_8ch_tx_src", "clk_i2s6_8ch_tx_frac", "i2s6_mclkin", "xin12m" }; +PNAMES(clk_i2s6_8ch_rx_p) = { "clk_i2s6_8ch_rx_src", "clk_i2s6_8ch_rx_frac", "i2s6_mclkin", "xin12m" }; +PNAMES(i2s6_8ch_mclkout_p) = { "mclk_i2s6_8ch_tx", "mclk_i2s6_8ch_rx", "xin12m" }; +PNAMES(clk_i2s7_8ch_rx_p) = { "clk_i2s7_8ch_rx_src", "clk_i2s7_8ch_rx_frac", "i2s7_mclkin", "xin12m" }; +PNAMES(clk_i2s8_8ch_tx_p) = { "clk_i2s8_8ch_tx_src", "clk_i2s8_8ch_tx_frac", "i2s8_mclkin", "xin12m" }; +PNAMES(clk_i2s9_8ch_rx_p) = { "clk_i2s9_8ch_rx_src", "clk_i2s9_8ch_rx_frac", "i2s9_mclkin", "xin12m" }; +PNAMES(clk_i2s10_8ch_rx_p) = { "clk_i2s10_8ch_rx_src", "clk_i2s10_8ch_rx_frac", "i2s10_mclkin", "xin12m" }; +PNAMES(clk_spdif0_p) = { "clk_spdif0_src", "clk_spdif0_frac", "xin12m" }; +PNAMES(clk_spdif1_p) = { "clk_spdif1_src", "clk_spdif1_frac", "xin12m" }; +PNAMES(clk_spdif2_dp0_p) = { "clk_spdif2_dp0_src", "clk_spdif2_dp0_frac", "xin12m" }; +PNAMES(clk_spdif3_p) = { "clk_spdif3_src", "clk_spdif3_frac", "xin12m" }; +PNAMES(clk_spdif4_p) = { "clk_spdif4_src", "clk_spdif4_frac", "xin12m" }; +PNAMES(clk_spdif5_dp1_p) = { "clk_spdif5_dp1_src", "clk_spdif5_dp1_frac", "xin12m" }; +PNAMES(clk_uart0_p) = { "clk_uart0_src", "clk_uart0_frac", "xin24m" }; +PNAMES(clk_uart1_p) = { "clk_uart1_src", "clk_uart1_frac", "xin24m" }; +PNAMES(clk_uart2_p) = { "clk_uart2_src", "clk_uart2_frac", "xin24m" }; +PNAMES(clk_uart3_p) = { "clk_uart3_src", "clk_uart3_frac", "xin24m" }; +PNAMES(clk_uart4_p) = { "clk_uart4_src", "clk_uart4_frac", "xin24m" }; +PNAMES(clk_uart5_p) = { "clk_uart5_src", "clk_uart5_frac", "xin24m" }; +PNAMES(clk_uart6_p) = { "clk_uart6_src", "clk_uart6_frac", "xin24m" }; +PNAMES(clk_uart7_p) = { "clk_uart7_src", "clk_uart7_frac", "xin24m" }; +PNAMES(clk_uart8_p) = { "clk_uart8_src", "clk_uart8_frac", "xin24m" }; +PNAMES(clk_uart9_p) = { "clk_uart9_src", "clk_uart9_frac", "xin24m" }; +PNAMES(clk_gmac0_ptp_ref_p) = { "cpll", "clk_gmac0_ptpref_io" }; +PNAMES(clk_gmac1_ptp_ref_p) = { "cpll", "clk_gmac1_ptpref_io" }; +PNAMES(clk_hdmirx_aud_p) = { "clk_hdmirx_aud_src", "clk_hdmirx_aud_frac" }; +PNAMES(aclk_hdcp1_root_p) = { "gpll", "cpll", "clk_hdmitrx_refsrc" }; +PNAMES(aclk_vop_sub_src_p) = { "aclk_vop_root", "aclk_vop_div2_src" }; +PNAMES(dclk_vop0_p) = { "dclk_vop0_src", "clk_hdmiphy_pixel0", "clk_hdmiphy_pixel1" }; +PNAMES(dclk_vop1_p) = { "dclk_vop1_src", "clk_hdmiphy_pixel0", "clk_hdmiphy_pixel1" }; +PNAMES(dclk_vop2_p) = { "dclk_vop2_src", "clk_hdmiphy_pixel0", "clk_hdmiphy_pixel1" }; +PNAMES(pmu_200m_100m_p) = { "clk_pmu1_200m_src", "clk_pmu1_100m_src" }; +PNAMES(pmu_300m_24m_p) = { "clk_300m_src", "xin24m" }; +PNAMES(pmu_400m_24m_p) = { "clk_400m_src", "xin24m" }; +PNAMES(pmu_100m_50m_24m_src_p) = { "clk_pmu1_100m_src", "clk_pmu1_50m_src", "xin24m" }; +PNAMES(pmu_24m_32k_100m_src_p) = { "xin24m", "xin32k", "clk_pmu1_100m_src" }; +PNAMES(hclk_pmu1_root_p) = { "clk_pmu1_200m_src", "clk_pmu1_100m_src", "clk_pmu1_50m_src", "xin24m" }; +PNAMES(hclk_pmu_cm0_root_p) = { "clk_pmu1_400m_src", "clk_pmu1_200m_src", "clk_pmu1_100m_src", "xin24m" }; +PNAMES(mclk_pdm0_p) = { "clk_pmu1_300m_src", "clk_pmu1_200m_src" }; +PNAMES(mux_24m_ppll_spll_p) = { "xin24m", "ppll", "spll" }; +PNAMES(mux_24m_ppll_p) = { "xin24m", "ppll" }; +PNAMES(clk_ref_pipe_phy0_p) = { "clk_ref_pipe_phy0_osc_src", "clk_ref_pipe_phy0_pll_src" }; +PNAMES(clk_ref_pipe_phy1_p) = { "clk_ref_pipe_phy1_osc_src", "clk_ref_pipe_phy1_pll_src" }; +PNAMES(clk_ref_pipe_phy2_p) = { "clk_ref_pipe_phy2_osc_src", "clk_ref_pipe_phy2_pll_src" }; + +#define MFLAGS CLK_MUX_HIWORD_MASK +#define DFLAGS CLK_DIVIDER_HIWORD_MASK +#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE) + +static struct rockchip_pll_clk_cell rk3588_pll_b0pll = + PLL_RAW(pll_type_rk3588_core, PLL_B0PLL, "b0pll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_B0_PLL_CON(0), RK3588_B0_PLL_MODE_CON0, + 0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_b1pll = + PLL_RAW(pll_type_rk3588_core, PLL_B1PLL, "b1pll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_B1_PLL_CON(8), RK3588_B1_PLL_MODE_CON0, + 0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_lpll = + PLL_RAW(pll_type_rk3588_core, PLL_LPLL, "lpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_LPLL_CON(16), RK3588_LPLL_MODE_CON0, + 0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_v0pll = + PLL_RAW(pll_type_rk3588, PLL_V0PLL, "v0pll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3588_PLL_CON(88), RK3588_MODE_CON0, + 4, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_aupll = + PLL_RAW(pll_type_rk3588, PLL_AUPLL, "aupll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3588_PLL_CON(96), RK3588_MODE_CON0, + 6, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_cpll = + PLL_RAW(pll_type_rk3588, PLL_CPLL, "cpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_PLL_CON(104), RK3588_MODE_CON0, + 8, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_gpll = + PLL_RAW(pll_type_rk3588, PLL_GPLL, "gpll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_PLL_CON(112), RK3588_MODE_CON0, + 2, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_npll = + PLL_RAW(pll_type_rk3588, PLL_NPLL, "npll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), 0, RK3588_PLL_CON(120), RK3588_MODE_CON0, + 0, 15, RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); +static struct rockchip_pll_clk_cell rk3588_pll_ppll = + PLL_RAW(pll_type_rk3588_core, PLL_PPLL, "ppll", mux_pll_p, RT_ARRAY_SIZE(mux_pll_p), RT_CLK_F_IGNORE_UNUSED, RK3588_PMU_PLL_CON(128), RK3588_MODE_CON0, + 10, 15,RK3588_GRF_SOC_STATUS0, 0, rk3588_pll_rates); + +static struct rockchip_clk_cell rk3588_i2s0_8ch_tx_fracmux = + MUX_RAW(CLK_I2S0_8CH_TX, "clk_i2s0_8ch_tx", clk_i2s0_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(26), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s0_8ch_rx_fracmux = + MUX_RAW(CLK_I2S0_8CH_RX, "clk_i2s0_8ch_rx", clk_i2s0_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(28), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s1_8ch_tx_fracmux = + MUX_RAW(CLK_I2S1_8CH_TX, "clk_i2s1_8ch_tx", clk_i2s1_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(7), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s1_8ch_rx_fracmux = + MUX_RAW(CLK_I2S1_8CH_RX, "clk_i2s1_8ch_rx", clk_i2s1_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(9), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s2_2ch_fracmux = + MUX_RAW(CLK_I2S2_2CH, "clk_i2s2_2ch", clk_i2s2_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(30), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s3_2ch_fracmux = + MUX_RAW(CLK_I2S3_2CH, "clk_i2s3_2ch", clk_i2s3_2ch_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(32), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s4_8ch_tx_fracmux = + MUX_RAW(CLK_I2S4_8CH_TX, "clk_i2s4_8ch_tx", clk_i2s4_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(120), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s5_8ch_tx_fracmux = + MUX_RAW(CLK_I2S5_8CH_TX, "clk_i2s5_8ch_tx", clk_i2s5_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(142), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s6_8ch_tx_fracmux = + MUX_RAW(CLK_I2S6_8CH_TX, "clk_i2s6_8ch_tx", clk_i2s6_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(146), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s6_8ch_rx_fracmux = + MUX_RAW(CLK_I2S6_8CH_RX, "clk_i2s6_8ch_rx", clk_i2s6_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(148), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s7_8ch_rx_fracmux = + MUX_RAW(CLK_I2S7_8CH_RX, "clk_i2s7_8ch_rx", clk_i2s7_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(131), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s8_8ch_tx_fracmux = + MUX_RAW(CLK_I2S8_8CH_TX, "clk_i2s8_8ch_tx", clk_i2s8_8ch_tx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(122), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s9_8ch_rx_fracmux = + MUX_RAW(CLK_I2S9_8CH_RX, "clk_i2s9_8ch_rx", clk_i2s9_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(155), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_i2s10_8ch_rx_fracmux = + MUX_RAW(CLK_I2S10_8CH_RX, "clk_i2s10_8ch_rx", clk_i2s10_8ch_rx_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(157), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_spdif0_fracmux = + MUX_RAW(CLK_SPDIF0, "clk_spdif0", clk_spdif0_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(34), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_spdif1_fracmux = + MUX_RAW(CLK_SPDIF1, "clk_spdif1", clk_spdif1_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(36), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_spdif2_dp0_fracmux = + MUX_RAW(CLK_SPDIF2_DP0, "clk_spdif2_dp0", clk_spdif2_dp0_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(124), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_spdif3_fracmux = + MUX_RAW(CLK_SPDIF3, "clk_spdif3", clk_spdif3_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(150), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_spdif4_fracmux = + MUX_RAW(CLK_SPDIF4, "clk_spdif4", clk_spdif4_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(152), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_spdif5_dp1_fracmux = + MUX_RAW(CLK_SPDIF5_DP1, "clk_spdif5_dp1", clk_spdif5_dp1_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(126), 0, 2, MFLAGS | CLK_MUX_ROUND_CLOSEST); + +static struct rockchip_clk_cell rk3588_uart0_fracmux = + MUX_RAW(CLK_UART0, "clk_uart0", clk_uart0_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(5), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart1_fracmux = + MUX_RAW(CLK_UART1, "clk_uart1", clk_uart1_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(43), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart2_fracmux = + MUX_RAW(CLK_UART2, "clk_uart2", clk_uart2_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(45), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart3_fracmux = + MUX_RAW(CLK_UART3, "clk_uart3", clk_uart3_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(47), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart4_fracmux = + MUX_RAW(CLK_UART4, "clk_uart4", clk_uart4_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(49), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart5_fracmux = + MUX_RAW(CLK_UART5, "clk_uart5", clk_uart5_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(51), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart6_fracmux = + MUX_RAW(CLK_UART6, "clk_uart6", clk_uart6_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(53), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart7_fracmux = + MUX_RAW(CLK_UART7, "clk_uart7", clk_uart7_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(55), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart8_fracmux = + MUX_RAW(CLK_UART8, "clk_uart8", clk_uart8_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(57), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_uart9_fracmux = + MUX_RAW(CLK_UART9, "clk_uart9", clk_uart9_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(59), 0, 2, MFLAGS); + +static struct rockchip_clk_cell rk3588_hdmirx_aud_fracmux = + MUX_RAW(CLK_HDMIRX_AUD_P_MUX, "clk_hdmirx_aud_mux", clk_hdmirx_aud_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(140), 0, 1, MFLAGS); + +static struct rt_clk_cell *rk3588_clk_cells[] = +{ + [PLL_B0PLL] = &rk3588_pll_b0pll.rk_cell.cell, + [PLL_B1PLL] = &rk3588_pll_b1pll.rk_cell.cell, + [PLL_LPLL] = &rk3588_pll_lpll.rk_cell.cell, + [PLL_V0PLL] = &rk3588_pll_v0pll.rk_cell.cell, + [PLL_AUPLL] = &rk3588_pll_aupll.rk_cell.cell, + [PLL_CPLL] = &rk3588_pll_cpll.rk_cell.cell, + [PLL_GPLL] = &rk3588_pll_gpll.rk_cell.cell, + [PLL_NPLL] = &rk3588_pll_npll.rk_cell.cell, + [PLL_PPLL] = &rk3588_pll_ppll.rk_cell.cell, + [ARMCLK_L] = CPU(ARMCLK_L, "armclk_l", &rk3588_pll_lpll.rk_cell, &rk3588_pll_gpll.rk_cell, + rk3588_cpulclk_rates, RT_ARRAY_SIZE(rk3588_cpulclk_rates), &rk3588_cpulclk_data), + [ARMCLK_B01] = CPU(ARMCLK_B01, "armclk_b01", &rk3588_pll_b0pll.rk_cell, &rk3588_pll_gpll.rk_cell, + rk3588_cpub0clk_rates, RT_ARRAY_SIZE(rk3588_cpub0clk_rates), &rk3588_cpub0clk_data), + [ARMCLK_B23] = CPU(ARMCLK_B23, "armclk_b23", &rk3588_pll_b1pll.rk_cell, &rk3588_pll_gpll.rk_cell, + rk3588_cpub1clk_rates, RT_ARRAY_SIZE(rk3588_cpub1clk_rates), &rk3588_cpub1clk_data), + [PCLK_BIGCORE0_ROOT] = COMPOSITE_NODIV(PCLK_BIGCORE0_ROOT, "pclk_bigcore0_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_BIGCORE0_CLKSEL_CON(2), 0, 2, MFLAGS, + RK3588_BIGCORE0_CLKGATE_CON(0), 14, GFLAGS), + [PCLK_BIGCORE0_PVTM] = GATE(PCLK_BIGCORE0_PVTM, "pclk_bigcore0_pvtm", "pclk_bigcore0_root", 0, RK3588_BIGCORE0_CLKGATE_CON(1), 0, GFLAGS), + [PCLK_BIGCORE1_ROOT] = COMPOSITE_NODIV(PCLK_BIGCORE1_ROOT, "pclk_bigcore1_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_BIGCORE1_CLKSEL_CON(2), 0, 2, MFLAGS, + RK3588_BIGCORE1_CLKGATE_CON(0), 14, GFLAGS), + [PCLK_BIGCORE1_PVTM] = GATE(PCLK_BIGCORE1_PVTM, "pclk_bigcore1_pvtm", "pclk_bigcore1_root", 0, RK3588_BIGCORE1_CLKGATE_CON(1), 0, GFLAGS), + [PCLK_DSU_S_ROOT] = COMPOSITE_NODIV(PCLK_DSU_S_ROOT, "pclk_dsu_s_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(4), 11, 2, MFLAGS, + RK3588_DSU_CLKGATE_CON(2), 2, GFLAGS), + [PCLK_DSU_ROOT] = COMPOSITE(PCLK_DSU_ROOT, "pclk_dsu_root", b0pll_b1pll_lpll_gpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(4), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_DSU_CLKGATE_CON(1), 3, GFLAGS), + [PCLK_DSU_NS_ROOT] = COMPOSITE_NODIV(PCLK_DSU_NS_ROOT, "pclk_dsu_ns_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(4), 7, 2, MFLAGS, + RK3588_DSU_CLKGATE_CON(1), 4, GFLAGS), + [PCLK_LITCORE_PVTM] = GATE(PCLK_LITCORE_PVTM, "pclk_litcore_pvtm", "pclk_dsu_ns_root", 0, RK3588_DSU_CLKGATE_CON(2), 6, GFLAGS), + [PCLK_DBG] = GATE(PCLK_DBG, "pclk_dbg", "pclk_dsu_root", RT_CLK_F_IS_CRITICAL, RK3588_DSU_CLKGATE_CON(1), 7, GFLAGS), + [PCLK_DSU] = GATE(PCLK_DSU, "pclk_dsu", "pclk_dsu_root", RT_CLK_F_IS_CRITICAL, RK3588_DSU_CLKGATE_CON(1), 6, GFLAGS), + [PCLK_S_DAPLITE] = GATE(PCLK_S_DAPLITE, "pclk_s_daplite", "pclk_dsu_ns_root", RT_CLK_F_IGNORE_UNUSED, RK3588_DSU_CLKGATE_CON(1), 8, GFLAGS), + [PCLK_M_DAPLITE] = GATE(PCLK_M_DAPLITE, "pclk_m_daplite", "pclk_dsu_root", RT_CLK_F_IGNORE_UNUSED, RK3588_DSU_CLKGATE_CON(1), 9, GFLAGS), + [HCLK_I2S2_2CH] = GATE(HCLK_I2S2_2CH, "hclk_i2s2_2ch", "hclk_audio_root", 0, RK3588_CLKGATE_CON(7), 12, GFLAGS), + [HCLK_I2S3_2CH] = GATE(HCLK_I2S3_2CH, "hclk_i2s3_2ch", "hclk_audio_root", 0, RK3588_CLKGATE_CON(7), 13, GFLAGS), + [CLK_I2S2_2CH_SRC] = COMPOSITE(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(28), 9, 1, MFLAGS, 4, 5, DFLAGS, + RK3588_CLKGATE_CON(7), 14, GFLAGS), + [CLK_I2S2_2CH_FRAC] = COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(29), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(7), 15, GFLAGS, + &rk3588_i2s2_2ch_fracmux), + [CLK_I2S2_2CH] = &rk3588_i2s2_2ch_fracmux.cell, + [MCLK_I2S2_2CH] = GATE(MCLK_I2S2_2CH, "mclk_i2s2_2ch", "clk_i2s2_2ch", 0, RK3588_CLKGATE_CON(8), 0, GFLAGS), + [I2S2_2CH_MCLKOUT] = MUX(I2S2_2CH_MCLKOUT, "i2s2_2ch_mclkout", i2s2_2ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(30), 2, 1, MFLAGS), + [CLK_DAC_ACDCDIG] = GATE(CLK_DAC_ACDCDIG, "clk_dac_acdcdig", "mclk_i2s3_2ch", 0, RK3588_CLKGATE_CON(8), 4, GFLAGS), + [CLK_I2S3_2CH_SRC] = COMPOSITE(CLK_I2S3_2CH_SRC, "clk_i2s3_2ch_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(30), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(8), 1, GFLAGS), + [CLK_I2S3_2CH_FRAC] = COMPOSITE_FRACMUX(CLK_I2S3_2CH_FRAC, "clk_i2s3_2ch_frac", "clk_i2s3_2ch_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(31), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(8), 2, GFLAGS, + &rk3588_i2s3_2ch_fracmux), + [CLK_I2S3_2CH] = &rk3588_i2s3_2ch_fracmux.cell, + [MCLK_I2S3_2CH] = GATE(MCLK_I2S3_2CH, "mclk_i2s3_2ch", "clk_i2s3_2ch", 0, RK3588_CLKGATE_CON(8), 3, GFLAGS), + [I2S3_2CH_MCLKOUT] = MUX(I2S3_2CH_MCLKOUT, "i2s3_2ch_mclkout", i2s3_2ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(32), 2, 1, MFLAGS), + [PCLK_ACDCDIG] = GATE(PCLK_ACDCDIG, "pclk_acdcdig", "pclk_audio_root", 0, RK3588_CLKGATE_CON(7), 11, GFLAGS), + [HCLK_I2S0_8CH] = GATE(HCLK_I2S0_8CH, "hclk_i2s0_8ch", "hclk_audio_root", 0, RK3588_CLKGATE_CON(7), 4, GFLAGS), + [CLK_I2S0_8CH_TX_SRC] = COMPOSITE(CLK_I2S0_8CH_TX_SRC, "clk_i2s0_8ch_tx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(24), 9, 1, MFLAGS, 4, 5, DFLAGS, + RK3588_CLKGATE_CON(7), 5, GFLAGS), + [CLK_I2S0_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_TX_FRAC, "clk_i2s0_8ch_tx_frac", "clk_i2s0_8ch_tx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(25), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(7), 6, GFLAGS, + &rk3588_i2s0_8ch_tx_fracmux), + [MCLK_I2S0_8CH_TX] = GATE(MCLK_I2S0_8CH_TX, "mclk_i2s0_8ch_tx", "clk_i2s0_8ch_tx", 0, RK3588_CLKGATE_CON(7), 7, GFLAGS), + [CLK_I2S0_8CH_TX] = &rk3588_i2s0_8ch_tx_fracmux.cell, + [CLK_I2S0_8CH_RX_SRC] = COMPOSITE(CLK_I2S0_8CH_RX_SRC, "clk_i2s0_8ch_rx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(26), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(7), 8, GFLAGS), + [CLK_I2S0_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S0_8CH_RX_FRAC, "clk_i2s0_8ch_rx_frac", "clk_i2s0_8ch_rx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(27), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(7), 9, GFLAGS, + &rk3588_i2s0_8ch_rx_fracmux), + [MCLK_I2S0_8CH_RX] = GATE(MCLK_I2S0_8CH_RX, "mclk_i2s0_8ch_rx", "clk_i2s0_8ch_rx", 0, RK3588_CLKGATE_CON(7), 10, GFLAGS), + [CLK_I2S0_8CH_RX] = &rk3588_i2s0_8ch_rx_fracmux.cell, + [I2S0_8CH_MCLKOUT] = MUX(I2S0_8CH_MCLKOUT, "i2s0_8ch_mclkout", i2s0_8ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(28), 2, 2, MFLAGS), + [HCLK_PDM1] = GATE(HCLK_PDM1, "hclk_pdm1", "hclk_audio_root", 0, RK3588_CLKGATE_CON(9), 6, GFLAGS), + [MCLK_PDM1] = COMPOSITE(MCLK_PDM1, "mclk_pdm1", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(36), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(9), 7, GFLAGS), + [HCLK_AUDIO_ROOT] = COMPOSITE_NODIV(HCLK_AUDIO_ROOT, "hclk_audio_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(24), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(7), 0, GFLAGS), + [PCLK_AUDIO_ROOT] = COMPOSITE_NODIV(PCLK_AUDIO_ROOT, "pclk_audio_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(24), 2, 2, MFLAGS, + RK3588_CLKGATE_CON(7), 1, GFLAGS), + [HCLK_SPDIF0] = GATE(HCLK_SPDIF0, "hclk_spdif0", "hclk_audio_root", 0, RK3588_CLKGATE_CON(8), 14, GFLAGS), + [CLK_SPDIF0_SRC] = COMPOSITE(CLK_SPDIF0_SRC, "clk_spdif0_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(32), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(8), 15, GFLAGS), + [CLK_SPDIF0_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF0_FRAC, "clk_spdif0_frac", "clk_spdif0_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(33), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(9), 0, GFLAGS, + &rk3588_spdif0_fracmux), + [MCLK_SPDIF0] = GATE(MCLK_SPDIF0, "mclk_spdif0", "clk_spdif0", 0, RK3588_CLKGATE_CON(9), 1, GFLAGS), + [CLK_SPDIF0] = &rk3588_spdif0_fracmux.cell, + [CLK_SPDIF1] = &rk3588_spdif1_fracmux.cell, + [HCLK_SPDIF1] = GATE(HCLK_SPDIF1, "hclk_spdif1", "hclk_audio_root", 0, RK3588_CLKGATE_CON(9), 2, GFLAGS), + [CLK_SPDIF1_SRC] = COMPOSITE(CLK_SPDIF1_SRC, "clk_spdif1_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(34), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(9), 3, GFLAGS), + [CLK_SPDIF1_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF1_FRAC, "clk_spdif1_frac", "clk_spdif1_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(35), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(9), 4, GFLAGS, + &rk3588_spdif1_fracmux), + [MCLK_SPDIF1] = GATE(MCLK_SPDIF1, "mclk_spdif1", "clk_spdif1", 0, RK3588_CLKGATE_CON(9), 5, GFLAGS), + [ACLK_AV1_ROOT] = COMPOSITE(ACLK_AV1_ROOT, "aclk_av1_root", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(163), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(68), 0, GFLAGS), + [ACLK_AV1] = GATE(ACLK_AV1, "aclk_av1", "aclk_av1_pre", 0, RK3588_CLKGATE_CON(68), 2, GFLAGS), + [PCLK_AV1_ROOT] = COMPOSITE_NODIV(PCLK_AV1_ROOT, "pclk_av1_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(163), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(68), 3, GFLAGS), + [PCLK_AV1] = GATE(PCLK_AV1, "pclk_av1", "pclk_av1_pre", 0, RK3588_CLKGATE_CON(68), 5, GFLAGS), + [PCLK_MAILBOX0] = GATE(PCLK_MAILBOX0, "pclk_mailbox0", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 11, GFLAGS), + [PCLK_MAILBOX1] = GATE(PCLK_MAILBOX1, "pclk_mailbox1", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 12, GFLAGS), + [PCLK_MAILBOX2] = GATE(PCLK_MAILBOX2, "pclk_mailbox2", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 13, GFLAGS), + [PCLK_PMU2] = GATE(PCLK_PMU2, "pclk_pmu2", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(19), 3, GFLAGS), + [PCLK_PMUCM0_INTMUX] = GATE(PCLK_PMUCM0_INTMUX, "pclk_pmucm0_intmux", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(19), 4, GFLAGS), + [PCLK_DDRCM0_INTMUX] = GATE(PCLK_DDRCM0_INTMUX, "pclk_ddrcm0_intmux", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(19), 5, GFLAGS), + [PCLK_PWM1] = GATE(PCLK_PWM1, "pclk_pwm1", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 3, GFLAGS), + [CLK_PWM1] = COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(59), 12, 2, MFLAGS, + RK3588_CLKGATE_CON(15), 4, GFLAGS), + [CLK_PWM1_CAPTURE] = GATE(CLK_PWM1_CAPTURE, "clk_pwm1_capture", "xin24m", 0, RK3588_CLKGATE_CON(15), 5, GFLAGS), + [PCLK_PWM2] = GATE(PCLK_PWM2, "pclk_pwm2", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 6, GFLAGS), + [CLK_PWM2] = COMPOSITE_NODIV(CLK_PWM2, "clk_pwm2", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(59), 14, 2, MFLAGS, + RK3588_CLKGATE_CON(15), 7, GFLAGS), + [CLK_PWM2_CAPTURE] = GATE(CLK_PWM2_CAPTURE, "clk_pwm2_capture", "xin24m", 0, RK3588_CLKGATE_CON(15), 8, GFLAGS), + [PCLK_PWM3] = GATE(PCLK_PWM3, "pclk_pwm3", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 9, GFLAGS), + [CLK_PWM3] = COMPOSITE_NODIV(CLK_PWM3, "clk_pwm3", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(60), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(15), 10, GFLAGS), + [CLK_PWM3_CAPTURE] = GATE(CLK_PWM3_CAPTURE, "clk_pwm3_capture", "xin24m", 0, RK3588_CLKGATE_CON(15), 11, GFLAGS), + [PCLK_BUSTIMER0] = GATE(PCLK_BUSTIMER0, "pclk_bustimer0", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 12, GFLAGS), + [PCLK_BUSTIMER1] = GATE(PCLK_BUSTIMER1, "pclk_bustimer1", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 13, GFLAGS), + [CLK_BUS_TIMER_ROOT] = COMPOSITE_NODIV(CLK_BUS_TIMER_ROOT, "clk_bus_timer_root", mux_24m_100m_p, 0, + RK3588_CLKSEL_CON(60), 2, 1, MFLAGS, + RK3588_CLKGATE_CON(15), 14, GFLAGS), + [CLK_BUSTIMER0] = GATE(CLK_BUSTIMER0, "clk_bustimer0", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(15), 15, GFLAGS), + [CLK_BUSTIMER1] = GATE(CLK_BUSTIMER1, "clk_bustimer1", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 0, GFLAGS), + [CLK_BUSTIMER2] = GATE(CLK_BUSTIMER2, "clk_bustimer2", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 1, GFLAGS), + [CLK_BUSTIMER3] = GATE(CLK_BUSTIMER3, "clk_bustimer3", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 2, GFLAGS), + [CLK_BUSTIMER4] = GATE(CLK_BUSTIMER4, "clk_bustimer4", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 3, GFLAGS), + [CLK_BUSTIMER5] = GATE(CLK_BUSTIMER5, "clk_bustimer5", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 4, GFLAGS), + [CLK_BUSTIMER6] = GATE(CLK_BUSTIMER6, "clk_bustimer6", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 5, GFLAGS), + [CLK_BUSTIMER7] = GATE(CLK_BUSTIMER7, "clk_bustimer7", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 6, GFLAGS), + [CLK_BUSTIMER8] = GATE(CLK_BUSTIMER8, "clk_bustimer8", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 7, GFLAGS), + [CLK_BUSTIMER9] = GATE(CLK_BUSTIMER9, "clk_bustimer9", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 8, GFLAGS), + [CLK_BUSTIMER10] = GATE(CLK_BUSTIMER10, "clk_bustimer10", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 9, GFLAGS), + [CLK_BUSTIMER11] = GATE(CLK_BUSTIMER11, "clk_bustimer11", "clk_bus_timer_root", 0, RK3588_CLKGATE_CON(16), 10, GFLAGS), + [PCLK_WDT0] = GATE(PCLK_WDT0, "pclk_wdt0", "pclk_top_root", 0, RK3588_CLKGATE_CON(15), 0, GFLAGS), + [TCLK_WDT0] = GATE(TCLK_WDT0, "tclk_wdt0", "xin24m", 0, RK3588_CLKGATE_CON(15), 1, GFLAGS), + [PCLK_CAN0] = GATE(PCLK_CAN0, "pclk_can0", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 8, GFLAGS), + [CLK_CAN0] = COMPOSITE(CLK_CAN0, "clk_can0", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(39), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(11), 9, GFLAGS), + [PCLK_CAN1] = GATE(PCLK_CAN1, "pclk_can1", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 10, GFLAGS), + [CLK_CAN1] = COMPOSITE(CLK_CAN1, "clk_can1", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(39), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(11), 11, GFLAGS), + [PCLK_CAN2] = GATE(PCLK_CAN2, "pclk_can2", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 12, GFLAGS), + [CLK_CAN2] = COMPOSITE(CLK_CAN2, "clk_can2", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(40), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(11), 13, GFLAGS), + [ACLK_DECOM] = GATE(ACLK_DECOM, "aclk_decom", "aclk_bus_root", 0, RK3588_CLKGATE_CON(17), 6, GFLAGS), + [PCLK_DECOM] = GATE(PCLK_DECOM, "pclk_decom", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 7, GFLAGS), + [DCLK_DECOM] = COMPOSITE(DCLK_DECOM, "dclk_decom", gpll_spll_p, 0, + RK3588_CLKSEL_CON(62), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(17), 8, GFLAGS), + [ACLK_DMAC0] = GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0, RK3588_CLKGATE_CON(10), 5, GFLAGS), + [ACLK_DMAC1] = GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0, RK3588_CLKGATE_CON(10), 6, GFLAGS), + [ACLK_DMAC2] = GATE(ACLK_DMAC2, "aclk_dmac2", "aclk_bus_root", 0, RK3588_CLKGATE_CON(10), 7, GFLAGS), + [ACLK_BUS_ROOT] = COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(38), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(10), 0, GFLAGS), + [ACLK_GIC] = GATE(ACLK_GIC, "aclk_gic", "aclk_bus_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(10), 3, GFLAGS), + [PCLK_GPIO1] = GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_top_root", 0, RK3588_CLKGATE_CON(16), 14, GFLAGS), + [DBCLK_GPIO1] = COMPOSITE(DBCLK_GPIO1, "dbclk_gpio1", mux_24m_32k_p, 0, + RK3588_CLKSEL_CON(60), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(16), 15, GFLAGS), + [PCLK_GPIO2] = GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 0, GFLAGS), + [DBCLK_GPIO2] = COMPOSITE(DBCLK_GPIO2, "dbclk_gpio2", mux_24m_32k_p, 0, + RK3588_CLKSEL_CON(60), 14, 1, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(17), 1, GFLAGS), + [PCLK_GPIO3] = GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 2, GFLAGS), + [DBCLK_GPIO3] = COMPOSITE(DBCLK_GPIO3, "dbclk_gpio3", mux_24m_32k_p, 0, + RK3588_CLKSEL_CON(61), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(17), 3, GFLAGS), + [PCLK_GPIO4] = GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_top_root", 0, RK3588_CLKGATE_CON(17), 4, GFLAGS), + [DBCLK_GPIO4] = COMPOSITE(DBCLK_GPIO4, "dbclk_gpio4", mux_24m_32k_p, 0, + RK3588_CLKSEL_CON(61), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(17), 5, GFLAGS), + [PCLK_I2C1] = GATE(PCLK_I2C1, "pclk_i2c1", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 8, GFLAGS), + [PCLK_I2C2] = GATE(PCLK_I2C2, "pclk_i2c2", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 9, GFLAGS), + [PCLK_I2C3] = GATE(PCLK_I2C3, "pclk_i2c3", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 10, GFLAGS), + [PCLK_I2C4] = GATE(PCLK_I2C4, "pclk_i2c4", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 11, GFLAGS), + [PCLK_I2C5] = GATE(PCLK_I2C5, "pclk_i2c5", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 12, GFLAGS), + [PCLK_I2C6] = GATE(PCLK_I2C6, "pclk_i2c6", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 13, GFLAGS), + [PCLK_I2C7] = GATE(PCLK_I2C7, "pclk_i2c7", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 14, GFLAGS), + [PCLK_I2C8] = GATE(PCLK_I2C8, "pclk_i2c8", "pclk_top_root", 0, RK3588_CLKGATE_CON(10), 15, GFLAGS), + [CLK_I2C1] = COMPOSITE_NODIV(CLK_I2C1, "clk_i2c1", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 6, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 0, GFLAGS), + [CLK_I2C2] = COMPOSITE_NODIV(CLK_I2C2, "clk_i2c2", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 7, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 1, GFLAGS), + [CLK_I2C3] = COMPOSITE_NODIV(CLK_I2C3, "clk_i2c3", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 8, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 2, GFLAGS), + [CLK_I2C4] = COMPOSITE_NODIV(CLK_I2C4, "clk_i2c4", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 9, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 3, GFLAGS), + [CLK_I2C5] = COMPOSITE_NODIV(CLK_I2C5, "clk_i2c5", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 10, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 4, GFLAGS), + [CLK_I2C6] = COMPOSITE_NODIV(CLK_I2C6, "clk_i2c6", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 11, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 5, GFLAGS), + [CLK_I2C7] = COMPOSITE_NODIV(CLK_I2C7, "clk_i2c7", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 12, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 6, GFLAGS), + [CLK_I2C8] = COMPOSITE_NODIV(CLK_I2C8, "clk_i2c8", mux_200m_100m_p, 0, + RK3588_CLKSEL_CON(38), 13, 1, MFLAGS, + RK3588_CLKGATE_CON(11), 7, GFLAGS), + [PCLK_OTPC_NS] = GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_top_root", 0, RK3588_CLKGATE_CON(18), 9, GFLAGS), + [CLK_OTPC_NS] = GATE(CLK_OTPC_NS, "clk_otpc_ns", "xin24m", 0, RK3588_CLKGATE_CON(18), 10, GFLAGS), + [CLK_OTPC_AUTO_RD_G] = GATE(CLK_OTPC_AUTO_RD_G, "clk_otpc_auto_rd_g", "xin24m", 0, RK3588_CLKGATE_CON(18), 12, GFLAGS), + [CLK_OTP_PHY_G] = GATE(CLK_OTP_PHY_G, "clk_otp_phy_g", "xin24m", 0, RK3588_CLKGATE_CON(18), 13, GFLAGS), + [PCLK_SARADC] = GATE(PCLK_SARADC, "pclk_saradc", "pclk_top_root", 0, RK3588_CLKGATE_CON(11), 14, GFLAGS), + [CLK_SARADC] = COMPOSITE(CLK_SARADC, "clk_saradc", gpll_24m_p, 0, + RK3588_CLKSEL_CON(40), 14, 1, MFLAGS, 6, 8, DFLAGS, + RK3588_CLKGATE_CON(11), 15, GFLAGS), + [PCLK_SPI0] = GATE(PCLK_SPI0, "pclk_spi0", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 6, GFLAGS), + [PCLK_SPI1] = GATE(PCLK_SPI1, "pclk_spi1", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 7, GFLAGS), + [PCLK_SPI2] = GATE(PCLK_SPI2, "pclk_spi2", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 8, GFLAGS), + [PCLK_SPI3] = GATE(PCLK_SPI3, "pclk_spi3", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 9, GFLAGS), + [PCLK_SPI4] = GATE(PCLK_SPI4, "pclk_spi4", "pclk_top_root", 0, RK3588_CLKGATE_CON(14), 10, GFLAGS), + [CLK_SPI0] = COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_150m_24m_p, 0, + RK3588_CLKSEL_CON(59), 2, 2, MFLAGS, + RK3588_CLKGATE_CON(14), 11, GFLAGS), + [CLK_SPI1] = COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_150m_24m_p, 0, + RK3588_CLKSEL_CON(59), 4, 2, MFLAGS, + RK3588_CLKGATE_CON(14), 12, GFLAGS), + [CLK_SPI2] = COMPOSITE_NODIV(CLK_SPI2, "clk_spi2", mux_200m_150m_24m_p, 0, + RK3588_CLKSEL_CON(59), 6, 2, MFLAGS, + RK3588_CLKGATE_CON(14), 13, GFLAGS), + [CLK_SPI3] = COMPOSITE_NODIV(CLK_SPI3, "clk_spi3", mux_200m_150m_24m_p, 0, + RK3588_CLKSEL_CON(59), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(14), 14, GFLAGS), + [CLK_SPI4] = COMPOSITE_NODIV(CLK_SPI4, "clk_spi4", mux_200m_150m_24m_p, 0, + RK3588_CLKSEL_CON(59), 10, 2, MFLAGS, + RK3588_CLKGATE_CON(14), 15, GFLAGS), + [ACLK_SPINLOCK] = GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_bus_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(18), 6, GFLAGS), + [PCLK_TSADC] = GATE(PCLK_TSADC, "pclk_tsadc", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 0, GFLAGS), + [CLK_TSADC] = COMPOSITE(CLK_TSADC, "clk_tsadc", gpll_24m_p, 0, + RK3588_CLKSEL_CON(41), 8, 1, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(12), 1, GFLAGS), + [PCLK_UART1] = GATE(PCLK_UART1, "pclk_uart1", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 2, GFLAGS), + [PCLK_UART2] = GATE(PCLK_UART2, "pclk_uart2", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 3, GFLAGS), + [PCLK_UART3] = GATE(PCLK_UART3, "pclk_uart3", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 4, GFLAGS), + [PCLK_UART4] = GATE(PCLK_UART4, "pclk_uart4", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 5, GFLAGS), + [PCLK_UART5] = GATE(PCLK_UART5, "pclk_uart5", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 6, GFLAGS), + [PCLK_UART6] = GATE(PCLK_UART6, "pclk_uart6", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 7, GFLAGS), + [PCLK_UART7] = GATE(PCLK_UART7, "pclk_uart7", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 8, GFLAGS), + [PCLK_UART8] = GATE(PCLK_UART8, "pclk_uart8", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 9, GFLAGS), + [PCLK_UART9] = GATE(PCLK_UART9, "pclk_uart9", "pclk_top_root", 0, RK3588_CLKGATE_CON(12), 10, GFLAGS), + [CLK_UART1_SRC] =COMPOSITE(CLK_UART1_SRC, "clk_uart1_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(41), 14, 1, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(12), 11, GFLAGS), + [CLK_UART1_FRAC] =COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(42), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(12), 12, GFLAGS, + &rk3588_uart1_fracmux), + [CLK_UART1] = &rk3588_uart1_fracmux.cell, + [SCLK_UART1] = GATE(SCLK_UART1, "sclk_uart1", "clk_uart1", 0, RK3588_CLKGATE_CON(12), 13, GFLAGS), + [CLK_UART2_SRC] = COMPOSITE(CLK_UART2_SRC, "clk_uart2_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(43), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(12), 14, GFLAGS), + [CLK_UART2_FRAC] = COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(44), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(12), 15, GFLAGS, + &rk3588_uart2_fracmux), + [CLK_UART2] = &rk3588_uart2_fracmux.cell, + [SCLK_UART2] = GATE(SCLK_UART2, "sclk_uart2", "clk_uart2", 0, RK3588_CLKGATE_CON(13), 0, GFLAGS), + [CLK_UART3_SRC] = COMPOSITE(CLK_UART3_SRC, "clk_uart3_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(45), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(13), 1, GFLAGS), + [CLK_UART3_FRAC] = COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(46), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(13), 2, GFLAGS, + &rk3588_uart3_fracmux), + [CLK_UART3] = &rk3588_uart3_fracmux.cell, + [SCLK_UART3] = GATE(SCLK_UART3, "sclk_uart3", "clk_uart3", 0, RK3588_CLKGATE_CON(13), 3, GFLAGS), + [CLK_UART4_SRC] = COMPOSITE(CLK_UART4_SRC, "clk_uart4_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(47), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(13), 4, GFLAGS), + [CLK_UART4_FRAC] = COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(48), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(13), 5, GFLAGS, + &rk3588_uart4_fracmux), + [CLK_UART4] = &rk3588_uart4_fracmux.cell, + [SCLK_UART4] = GATE(SCLK_UART4, "sclk_uart4", "clk_uart4", 0, RK3588_CLKGATE_CON(13), 6, GFLAGS), + [CLK_UART5_SRC] = COMPOSITE(CLK_UART5_SRC, "clk_uart5_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(49), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(13), 7, GFLAGS), + [CLK_UART5_FRAC] = COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(50), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(13), 8, GFLAGS, + &rk3588_uart5_fracmux), + [CLK_UART5] = &rk3588_uart5_fracmux.cell, + [SCLK_UART5] = GATE(SCLK_UART5, "sclk_uart5", "clk_uart5", 0, RK3588_CLKGATE_CON(13), 9, GFLAGS), + [CLK_UART6_SRC] = COMPOSITE(CLK_UART6_SRC, "clk_uart6_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(51), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(13), 10, GFLAGS), + [CLK_UART6_FRAC] = COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(52), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(13), 11, GFLAGS, + &rk3588_uart6_fracmux), + [CLK_UART6] = &rk3588_uart6_fracmux.cell, + [SCLK_UART6] = GATE(SCLK_UART6, "sclk_uart6", "clk_uart6", 0, RK3588_CLKGATE_CON(13), 12, GFLAGS), + [CLK_UART7_SRC] = COMPOSITE(CLK_UART7_SRC, "clk_uart7_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(53), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(13), 13, GFLAGS), + [CLK_UART7_FRAC] = COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(54), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(13), 14, GFLAGS, + &rk3588_uart7_fracmux), + [CLK_UART7] = &rk3588_uart7_fracmux.cell, + [SCLK_UART7] = GATE(SCLK_UART7, "sclk_uart7", "clk_uart7", 0, RK3588_CLKGATE_CON(13), 15, GFLAGS), + [CLK_UART8_SRC] = COMPOSITE(CLK_UART8_SRC, "clk_uart8_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(55), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(14), 0, GFLAGS), + [CLK_UART8_FRAC] = COMPOSITE_FRACMUX(CLK_UART8_FRAC, "clk_uart8_frac", "clk_uart8_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(56), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(14), 1, GFLAGS, + &rk3588_uart8_fracmux), + [CLK_UART8] = &rk3588_uart8_fracmux.cell, + [SCLK_UART8] = GATE(SCLK_UART8, "sclk_uart8", "clk_uart8", 0, RK3588_CLKGATE_CON(14), 2, GFLAGS), + [CLK_UART9_SRC] = COMPOSITE(CLK_UART9_SRC, "clk_uart9_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(57), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(14), 3, GFLAGS), + [CLK_UART9_FRAC] = COMPOSITE_FRACMUX(CLK_UART9_FRAC, "clk_uart9_frac", "clk_uart9_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(58), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_CLKGATE_CON(14), 4, GFLAGS, + &rk3588_uart9_fracmux), + [CLK_UART9] = &rk3588_uart9_fracmux.cell, + [SCLK_UART9] = GATE(SCLK_UART9, "sclk_uart9", "clk_uart9", 0, RK3588_CLKGATE_CON(14), 5, GFLAGS), + [ACLK_CENTER_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_ROOT, "aclk_center_root", mux_700m_400m_200m_24m_p, + RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(165), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(69), 0, GFLAGS), + [ACLK_CENTER_LOW_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_LOW_ROOT, "aclk_center_low_root", mux_500m_250m_100m_24m_p, + RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(165), 2, 2, MFLAGS, + RK3588_CLKGATE_CON(69), 1, GFLAGS), + [HCLK_CENTER_ROOT] = COMPOSITE_NODIV(HCLK_CENTER_ROOT, "hclk_center_root", mux_400m_200m_100m_24m_p, + RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(165), 4, 2, MFLAGS, + RK3588_CLKGATE_CON(69), 2, GFLAGS), + [PCLK_CENTER_ROOT] = COMPOSITE_NODIV(PCLK_CENTER_ROOT, "pclk_center_root", mux_200m_100m_50m_24m_p, + RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(165), 6, 2, MFLAGS | CLK_MUX_READ_ONLY, + RK3588_CLKGATE_CON(69), 3, GFLAGS), + [ACLK_DMA2DDR] = GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(69), 5, GFLAGS), + [ACLK_DDR_SHAREMEM] = GATE(ACLK_DDR_SHAREMEM, "aclk_ddr_sharemem", "aclk_center_low_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(69), 6, GFLAGS), + [ACLK_CENTER_S200_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_S200_ROOT, "aclk_center_s200_root", mux_200m_100m_50m_24m_p, + RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(165), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(69), 8, GFLAGS), + [ACLK_CENTER_S400_ROOT] = COMPOSITE_NODIV(ACLK_CENTER_S400_ROOT, "aclk_center_s400_root", mux_400m_200m_100m_24m_p, + RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(165), 10, 2, MFLAGS, + RK3588_CLKGATE_CON(69), 9, GFLAGS), + [FCLK_DDR_CM0_CORE] = GATE(FCLK_DDR_CM0_CORE, "fclk_ddr_cm0_core", "hclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(69), 14, GFLAGS), + [CLK_DDR_TIMER_ROOT] = COMPOSITE_NODIV(CLK_DDR_TIMER_ROOT, "clk_ddr_timer_root", mux_24m_100m_p, RT_CLK_F_IGNORE_UNUSED, + RK3588_CLKSEL_CON(165), 12, 1, MFLAGS, + RK3588_CLKGATE_CON(69), 15, GFLAGS), + [CLK_DDR_TIMER0] = GATE(CLK_DDR_TIMER0, "clk_ddr_timer0", "clk_ddr_timer_root", 0, RK3588_CLKGATE_CON(70), 0, GFLAGS), + [CLK_DDR_TIMER1] = GATE(CLK_DDR_TIMER1, "clk_ddr_timer1", "clk_ddr_timer_root", 0, RK3588_CLKGATE_CON(70), 1, GFLAGS), + [TCLK_WDT_DDR] = GATE(TCLK_WDT_DDR, "tclk_wdt_ddr", "xin24m", 0, RK3588_CLKGATE_CON(70), 2, GFLAGS), + [CLK_DDR_CM0_RTC] = COMPOSITE(CLK_DDR_CM0_RTC, "clk_ddr_cm0_rtc", mux_24m_32k_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(166), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(70), 4, GFLAGS), + [PCLK_WDT] = GATE(PCLK_WDT, "pclk_wdt", "pclk_center_root", 0, RK3588_CLKGATE_CON(70), 7, GFLAGS), + [PCLK_TIMER] = GATE(PCLK_TIMER, "pclk_timer", "pclk_center_root", 0, RK3588_CLKGATE_CON(70), 8, GFLAGS), + [PCLK_DMA2DDR] = GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(70), 9, GFLAGS), + [PCLK_SHAREMEM] = GATE(PCLK_SHAREMEM, "pclk_sharemem", "pclk_center_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(70), 10, GFLAGS), + [CLK_50M_SRC] = COMPOSITE(CLK_50M_SRC, "clk_50m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(0), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 0, GFLAGS), + [CLK_100M_SRC] = COMPOSITE(CLK_100M_SRC, "clk_100m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(0), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 1, GFLAGS), + [CLK_150M_SRC] = COMPOSITE(CLK_150M_SRC, "clk_150m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 2, GFLAGS), + [CLK_200M_SRC] = COMPOSITE(CLK_200M_SRC, "clk_200m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(1), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 3, GFLAGS), + [CLK_250M_SRC] = COMPOSITE(CLK_250M_SRC, "clk_250m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 4, GFLAGS), + [CLK_300M_SRC] = COMPOSITE(CLK_300M_SRC, "clk_300m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(2), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 5, GFLAGS), + [CLK_350M_SRC] = COMPOSITE(CLK_350M_SRC, "clk_350m_src", gpll_spll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(3), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 6, GFLAGS), + [CLK_400M_SRC] = COMPOSITE(CLK_400M_SRC, "clk_400m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(3), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 7, GFLAGS), + [CLK_450M_SRC] = COMPOSITE_HALFDIV(CLK_450M_SRC, "clk_450m_src", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(4), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 8, GFLAGS), + [CLK_500M_SRC] = COMPOSITE(CLK_500M_SRC, "clk_500m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(4), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 9, GFLAGS), + [CLK_600M_SRC] = COMPOSITE(CLK_600M_SRC, "clk_600m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(5), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 10, GFLAGS), + [CLK_650M_SRC] = COMPOSITE(CLK_650M_SRC, "clk_650m_src", gpll_lpll_p, 0, + RK3588_CLKSEL_CON(5), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 11, GFLAGS), + [CLK_700M_SRC] = COMPOSITE(CLK_700M_SRC, "clk_700m_src", gpll_spll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(6), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 12, GFLAGS), + [CLK_800M_SRC] = COMPOSITE(CLK_800M_SRC, "clk_800m_src", gpll_aupll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(6), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 13, GFLAGS), + [CLK_1000M_SRC] = COMPOSITE_HALFDIV(CLK_1000M_SRC, "clk_1000m_src", gpll_cpll_npll_v0pll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(7), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 14, GFLAGS), + [CLK_1200M_SRC] = COMPOSITE(CLK_1200M_SRC, "clk_1200m_src", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(7), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(0), 15, GFLAGS), + [ACLK_TOP_M300_ROOT] = COMPOSITE_NODIV(ACLK_TOP_M300_ROOT, "aclk_top_m300_root", mux_300m_200m_100m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(9), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(1), 10, GFLAGS), + [ACLK_TOP_M500_ROOT] = COMPOSITE_NODIV(ACLK_TOP_M500_ROOT, "aclk_top_m500_root", mux_500m_300m_100m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(9), 2, 2, MFLAGS, + RK3588_CLKGATE_CON(1), 11, GFLAGS), + [ACLK_TOP_M400_ROOT] = COMPOSITE_NODIV(ACLK_TOP_M400_ROOT, "aclk_top_m400_root", mux_400m_200m_100m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(9), 4, 2, MFLAGS, + RK3588_CLKGATE_CON(1), 12, GFLAGS), + [ACLK_TOP_S200_ROOT] = COMPOSITE_NODIV(ACLK_TOP_S200_ROOT, "aclk_top_s200_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(9), 6, 2, MFLAGS, + RK3588_CLKGATE_CON(1), 13, GFLAGS), + [ACLK_TOP_S400_ROOT] = COMPOSITE_NODIV(ACLK_TOP_S400_ROOT, "aclk_top_s400_root", mux_400m_200m_100m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(9), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(1), 14, GFLAGS), + [CLK_MIPI_CAMARAOUT_M0] = COMPOSITE(CLK_MIPI_CAMARAOUT_M0, "clk_mipi_camaraout_m0", mux_24m_spll_gpll_cpll_p, 0, + RK3588_CLKSEL_CON(18), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(5), 9, GFLAGS), + [CLK_MIPI_CAMARAOUT_M1] = COMPOSITE(CLK_MIPI_CAMARAOUT_M1, "clk_mipi_camaraout_m1", mux_24m_spll_gpll_cpll_p, 0, + RK3588_CLKSEL_CON(19), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(5), 10, GFLAGS), + [CLK_MIPI_CAMARAOUT_M2] = COMPOSITE(CLK_MIPI_CAMARAOUT_M2, "clk_mipi_camaraout_m2", mux_24m_spll_gpll_cpll_p, 0, + RK3588_CLKSEL_CON(20), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(5), 11, GFLAGS), + [CLK_MIPI_CAMARAOUT_M3] = COMPOSITE(CLK_MIPI_CAMARAOUT_M3, "clk_mipi_camaraout_m3", mux_24m_spll_gpll_cpll_p, 0, + RK3588_CLKSEL_CON(21), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(5), 12, GFLAGS), + [CLK_MIPI_CAMARAOUT_M4] = COMPOSITE(CLK_MIPI_CAMARAOUT_M4, "clk_mipi_camaraout_m4", mux_24m_spll_gpll_cpll_p, 0, + RK3588_CLKSEL_CON(22), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(5), 13, GFLAGS), + [MCLK_GMAC0_OUT] = COMPOSITE(MCLK_GMAC0_OUT, "mclk_gmac0_out", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(15), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(5), 3, GFLAGS), + [REFCLKO25M_ETH0_OUT] = COMPOSITE(REFCLKO25M_ETH0_OUT, "refclko25m_eth0_out", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(15), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3588_CLKGATE_CON(5), 4, GFLAGS), + [REFCLKO25M_ETH1_OUT] = COMPOSITE(REFCLKO25M_ETH1_OUT, "refclko25m_eth1_out", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(16), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(5), 5, GFLAGS), + [CLK_CIFOUT_OUT] = COMPOSITE(CLK_CIFOUT_OUT, "clk_cifout_out", gpll_cpll_24m_spll_p, 0, + RK3588_CLKSEL_CON(17), 8, 2, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(5), 6, GFLAGS), + [PCLK_MIPI_DCPHY0] = GATE(PCLK_MIPI_DCPHY0, "pclk_mipi_dcphy0", "pclk_top_root", 0, RK3588_CLKGATE_CON(3), 14, GFLAGS), + [PCLK_MIPI_DCPHY1] = GATE(PCLK_MIPI_DCPHY1, "pclk_mipi_dcphy1", "pclk_top_root", 0, RK3588_CLKGATE_CON(4), 3, GFLAGS), + [PCLK_CSIPHY0] = GATE(PCLK_CSIPHY0, "pclk_csiphy0", "pclk_top_root", 0, RK3588_CLKGATE_CON(1), 6, GFLAGS), + [PCLK_CSIPHY1] = GATE(PCLK_CSIPHY1, "pclk_csiphy1", "pclk_top_root", 0, RK3588_CLKGATE_CON(1), 8, GFLAGS), + [ACLK_TOP_ROOT] = COMPOSITE(ACLK_TOP_ROOT, "aclk_top_root", gpll_cpll_aupll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(8), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(1), 0, GFLAGS), + [PCLK_TOP_ROOT] = COMPOSITE_NODIV(PCLK_TOP_ROOT, "pclk_top_root", mux_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(8), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(1), 1, GFLAGS), + [ACLK_LOW_TOP_ROOT] = COMPOSITE(ACLK_LOW_TOP_ROOT, "aclk_low_top_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(8), 14, 1, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(1), 2, GFLAGS), + [PCLK_CRU] = GATE(PCLK_CRU, "pclk_cru", "pclk_top_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(5), 0, GFLAGS), + [CLK_GPU_SRC] = COMPOSITE(CLK_GPU_SRC, "clk_gpu_src", gpll_cpll_aupll_npll_spll_p, 0, + RK3588_CLKSEL_CON(158), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(66), 1, GFLAGS), + [CLK_GPU] = GATE(CLK_GPU, "clk_gpu", "clk_gpu_src", 0, RK3588_CLKGATE_CON(66), 4, GFLAGS), + [CLK_GPU_COREGROUP] = GATE(CLK_GPU_COREGROUP, "clk_gpu_coregroup", "clk_gpu_src", 0, RK3588_CLKGATE_CON(66), 6, GFLAGS), + [CLK_GPU_STACKS] = COMPOSITE_NOMUX(CLK_GPU_STACKS, "clk_gpu_stacks", "clk_gpu_src", 0, + RK3588_CLKSEL_CON(159), 0, 5, DFLAGS, + RK3588_CLKGATE_CON(66), 7, GFLAGS), + [CLK_GPU_PVTM] = GATE(CLK_GPU_PVTM, "clk_gpu_pvtm", "xin24m", 0, RK3588_CLKGATE_CON(67), 0, GFLAGS), + [CLK_CORE_GPU_PVTM] = GATE(CLK_CORE_GPU_PVTM, "clk_core_gpu_pvtm", "clk_gpu_src", 0, RK3588_CLKGATE_CON(67), 1, GFLAGS), + [ACLK_ISP1_ROOT] = COMPOSITE(ACLK_ISP1_ROOT, "aclk_isp1_root", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(67), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(26), 0, GFLAGS), + [HCLK_ISP1_ROOT] = COMPOSITE_NODIV(HCLK_ISP1_ROOT, "hclk_isp1_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(67), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(26), 1, GFLAGS), + [CLK_ISP1_CORE] = COMPOSITE(CLK_ISP1_CORE, "clk_isp1_core", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(67), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(26), 2, GFLAGS), + [CLK_ISP1_CORE_MARVIN] = GATE(CLK_ISP1_CORE_MARVIN, "clk_isp1_core_marvin", "clk_isp1_core", 0, RK3588_CLKGATE_CON(26), 3, GFLAGS), + [CLK_ISP1_CORE_VICAP] = GATE(CLK_ISP1_CORE_VICAP, "clk_isp1_core_vicap", "clk_isp1_core", 0, RK3588_CLKGATE_CON(26), 4, GFLAGS), + [ACLK_ISP1] = GATE(ACLK_ISP1, "aclk_isp1", "aclk_isp1_pre", 0, RK3588_CLKGATE_CON(26), 5, GFLAGS), + [HCLK_ISP1] = GATE(HCLK_ISP1, "hclk_isp1", "hclk_isp1_pre", 0, RK3588_CLKGATE_CON(26), 7, GFLAGS), + [ACLK_NPU1] = GATE(ACLK_NPU1, "aclk_npu1", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(27), 0, GFLAGS), + [HCLK_NPU1] = GATE(HCLK_NPU1, "hclk_npu1", "hclk_npu_root", 0, RK3588_CLKGATE_CON(27), 2, GFLAGS), + [ACLK_NPU2] = GATE(ACLK_NPU2, "aclk_npu2", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(28), 0, GFLAGS), + [HCLK_NPU2] = GATE(HCLK_NPU2, "hclk_npu2", "hclk_npu_root", 0, RK3588_CLKGATE_CON(28), 2, GFLAGS), + [HCLK_NPU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_NPU_CM0_ROOT, "hclk_npu_cm0_root", mux_400m_200m_100m_24m_p, 0, + RK3588_CLKSEL_CON(74), 5, 2, MFLAGS, + RK3588_CLKGATE_CON(30), 1, GFLAGS), + [FCLK_NPU_CM0_CORE] = GATE(FCLK_NPU_CM0_CORE, "fclk_npu_cm0_core", "hclk_npu_cm0_root", 0, RK3588_CLKGATE_CON(30), 3, GFLAGS), + [CLK_NPU_CM0_RTC] = COMPOSITE(CLK_NPU_CM0_RTC, "clk_npu_cm0_rtc", mux_24m_32k_p, 0, + RK3588_CLKSEL_CON(74), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(30), 5, GFLAGS), + [PCLK_NPU_PVTM] = GATE(PCLK_NPU_PVTM, "pclk_npu_pvtm", "pclk_npu_root", 0, RK3588_CLKGATE_CON(29), 12, GFLAGS), + [PCLK_NPU_GRF] = GATE(PCLK_NPU_GRF, "pclk_npu_grf", "pclk_npu_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(29), 13, GFLAGS), + [CLK_NPU_PVTM] = GATE(CLK_NPU_PVTM, "clk_npu_pvtm", "xin24m", 0, RK3588_CLKGATE_CON(29), 14, GFLAGS), + [CLK_CORE_NPU_PVTM] = GATE(CLK_CORE_NPU_PVTM, "clk_core_npu_pvtm", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(29), 15, GFLAGS), + [ACLK_NPU0] = GATE(ACLK_NPU0, "aclk_npu0", "clk_npu_dsu0", 0, RK3588_CLKGATE_CON(30), 6, GFLAGS), + [HCLK_NPU0] = GATE(HCLK_NPU0, "hclk_npu0", "hclk_npu_root", 0, RK3588_CLKGATE_CON(30), 8, GFLAGS), + [HCLK_NPU_ROOT] = COMPOSITE_NODIV(HCLK_NPU_ROOT, "hclk_npu_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(73), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(29), 0, GFLAGS), + [CLK_NPU_DSU0] = COMPOSITE(CLK_NPU_DSU0, "clk_npu_dsu0", gpll_cpll_aupll_npll_spll_p, 0, + RK3588_CLKSEL_CON(73), 7, 3, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(29), 1, GFLAGS), + [PCLK_NPU_ROOT] = COMPOSITE_NODIV(PCLK_NPU_ROOT, "pclk_npu_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(74), 1, 2, MFLAGS, + RK3588_CLKGATE_CON(29), 4, GFLAGS), + [PCLK_NPU_TIMER] = GATE(PCLK_NPU_TIMER, "pclk_npu_timer", "pclk_npu_root", 0, RK3588_CLKGATE_CON(29), 6, GFLAGS), + [CLK_NPUTIMER_ROOT] = COMPOSITE_NODIV(CLK_NPUTIMER_ROOT, "clk_nputimer_root", mux_24m_100m_p, 0, + RK3588_CLKSEL_CON(74), 3, 1, MFLAGS, + RK3588_CLKGATE_CON(29), 7, GFLAGS), + [CLK_NPUTIMER0] = GATE(CLK_NPUTIMER0, "clk_nputimer0", "clk_nputimer_root", 0, RK3588_CLKGATE_CON(29), 8, GFLAGS), + [CLK_NPUTIMER1] = GATE(CLK_NPUTIMER1, "clk_nputimer1", "clk_nputimer_root", 0, RK3588_CLKGATE_CON(29), 9, GFLAGS), + [PCLK_NPU_WDT] = GATE(PCLK_NPU_WDT, "pclk_npu_wdt", "pclk_npu_root", 0, RK3588_CLKGATE_CON(29), 10, GFLAGS), + [TCLK_NPU_WDT] = GATE(TCLK_NPU_WDT, "tclk_npu_wdt", "xin24m", 0, RK3588_CLKGATE_CON(29), 11, GFLAGS), + [HCLK_EMMC] = GATE(HCLK_EMMC, "hclk_emmc", "hclk_nvm", 0, RK3588_CLKGATE_CON(31), 4, GFLAGS), + [ACLK_EMMC] = GATE(ACLK_EMMC, "aclk_emmc", "aclk_nvm_root", 0, RK3588_CLKGATE_CON(31), 5, GFLAGS), + [CCLK_EMMC] = COMPOSITE(CCLK_EMMC, "cclk_emmc", gpll_cpll_24m_p, 0, + RK3588_CLKSEL_CON(77), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3588_CLKGATE_CON(31), 6, GFLAGS), + [BCLK_EMMC] = COMPOSITE(BCLK_EMMC, "bclk_emmc", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(78), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(31), 7, GFLAGS), + [TMCLK_EMMC] = GATE(TMCLK_EMMC, "tmclk_emmc", "xin24m", 0, RK3588_CLKGATE_CON(31), 8, GFLAGS), + [SCLK_SFC] = COMPOSITE(SCLK_SFC, "sclk_sfc", gpll_cpll_24m_p, 0, + RK3588_CLKSEL_CON(78), 12, 2, MFLAGS, 6, 6, DFLAGS, + RK3588_CLKGATE_CON(31), 9, GFLAGS), + [HCLK_SFC] = GATE(HCLK_SFC, "hclk_sfc", "hclk_nvm", 0, RK3588_CLKGATE_CON(31), 10, GFLAGS), + [HCLK_SFC_XIP] = GATE(HCLK_SFC_XIP, "hclk_sfc_xip", "hclk_nvm", 0, RK3588_CLKGATE_CON(31), 11, GFLAGS), + [HCLK_NVM_ROOT] = COMPOSITE_NODIV(HCLK_NVM_ROOT, "hclk_nvm_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(77), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(31), 0, GFLAGS), + [ACLK_NVM_ROOT] = COMPOSITE(ACLK_NVM_ROOT, "aclk_nvm_root", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(77), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(31), 1, GFLAGS), + [CLK_GMAC0_PTP_REF] = COMPOSITE(CLK_GMAC0_PTP_REF, "clk_gmac0_ptp_ref", clk_gmac0_ptp_ref_p, 0, + RK3588_CLKSEL_CON(81), 6, 1, MFLAGS, 0, 6, DFLAGS, + RK3588_CLKGATE_CON(34), 10, GFLAGS), + [CLK_GMAC1_PTP_REF] = COMPOSITE(CLK_GMAC1_PTP_REF, "clk_gmac1_ptp_ref", clk_gmac1_ptp_ref_p, 0, + RK3588_CLKSEL_CON(81), 13, 1, MFLAGS, 7, 6, DFLAGS, + RK3588_CLKGATE_CON(34), 11, GFLAGS), + [CLK_GMAC_125M] = COMPOSITE(CLK_GMAC_125M, "clk_gmac_125m", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(83), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3588_CLKGATE_CON(35), 5, GFLAGS), + [CLK_GMAC_50M] = COMPOSITE(CLK_GMAC_50M, "clk_gmac_50m", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(84), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(35), 6, GFLAGS), + [ACLK_PHP_GIC_ITS] = GATE(ACLK_PHP_GIC_ITS, "aclk_php_gic_its", "aclk_pcie_root", RT_CLK_F_IS_CRITICAL, RK3588_CLKGATE_CON(34), 6, GFLAGS), + [ACLK_MMU_PCIE] = GATE(ACLK_MMU_PCIE, "aclk_mmu_pcie", "aclk_pcie_bridge", 0, RK3588_CLKGATE_CON(34), 7, GFLAGS), + [ACLK_MMU_PHP] = GATE(ACLK_MMU_PHP, "aclk_mmu_php", "aclk_php_root", 0, RK3588_CLKGATE_CON(34), 8, GFLAGS), + [ACLK_PCIE_4L_DBI] = GATE(ACLK_PCIE_4L_DBI, "aclk_pcie_4l_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(32), 13, GFLAGS), + [ACLK_PCIE_2L_DBI] = GATE(ACLK_PCIE_2L_DBI, "aclk_pcie_2l_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(32), 14, GFLAGS), + [ACLK_PCIE_1L0_DBI] = GATE(ACLK_PCIE_1L0_DBI, "aclk_pcie_1l0_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(32), 15, GFLAGS), + [ACLK_PCIE_1L1_DBI] = GATE(ACLK_PCIE_1L1_DBI, "aclk_pcie_1l1_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 0, GFLAGS), + [ACLK_PCIE_1L2_DBI] = GATE(ACLK_PCIE_1L2_DBI, "aclk_pcie_1l2_dbi", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 1, GFLAGS), + [ACLK_PCIE_4L_MSTR] = GATE(ACLK_PCIE_4L_MSTR, "aclk_pcie_4l_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 2, GFLAGS), + [ACLK_PCIE_2L_MSTR] = GATE(ACLK_PCIE_2L_MSTR, "aclk_pcie_2l_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 3, GFLAGS), + [ACLK_PCIE_1L0_MSTR] = GATE(ACLK_PCIE_1L0_MSTR, "aclk_pcie_1l0_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 4, GFLAGS), + [ACLK_PCIE_1L1_MSTR] = GATE(ACLK_PCIE_1L1_MSTR, "aclk_pcie_1l1_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 5, GFLAGS), + [ACLK_PCIE_1L2_MSTR] = GATE(ACLK_PCIE_1L2_MSTR, "aclk_pcie_1l2_mstr", "aclk_mmu_pcie", 0, RK3588_CLKGATE_CON(33), 6, GFLAGS), + [ACLK_PCIE_4L_SLV] = GATE(ACLK_PCIE_4L_SLV, "aclk_pcie_4l_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 7, GFLAGS), + [ACLK_PCIE_2L_SLV] = GATE(ACLK_PCIE_2L_SLV, "aclk_pcie_2l_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 8, GFLAGS), + [ACLK_PCIE_1L0_SLV] = GATE(ACLK_PCIE_1L0_SLV, "aclk_pcie_1l0_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 9, GFLAGS), + [ACLK_PCIE_1L1_SLV] = GATE(ACLK_PCIE_1L1_SLV, "aclk_pcie_1l1_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 10, GFLAGS), + [ACLK_PCIE_1L2_SLV] = GATE(ACLK_PCIE_1L2_SLV, "aclk_pcie_1l2_slv", "aclk_php_root", 0, RK3588_CLKGATE_CON(33), 11, GFLAGS), + [PCLK_PCIE_4L] = GATE(PCLK_PCIE_4L, "pclk_pcie_4l", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 12, GFLAGS), + [PCLK_PCIE_2L] = GATE(PCLK_PCIE_2L, "pclk_pcie_2l", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 13, GFLAGS), + [PCLK_PCIE_1L0] = GATE(PCLK_PCIE_1L0, "pclk_pcie_1l0", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 14, GFLAGS), + [PCLK_PCIE_1L1] = GATE(PCLK_PCIE_1L1, "pclk_pcie_1l1", "pclk_php_root", 0, RK3588_CLKGATE_CON(33), 15, GFLAGS), + [PCLK_PCIE_1L2] = GATE(PCLK_PCIE_1L2, "pclk_pcie_1l2", "pclk_php_root", 0, RK3588_CLKGATE_CON(34), 0, GFLAGS), + [CLK_PCIE_AUX0] = GATE(CLK_PCIE_AUX0, "clk_pcie_aux0", "xin24m", 0, RK3588_CLKGATE_CON(34), 1, GFLAGS), + [CLK_PCIE_AUX1] = GATE(CLK_PCIE_AUX1, "clk_pcie_aux1", "xin24m", 0, RK3588_CLKGATE_CON(34), 2, GFLAGS), + [CLK_PCIE_AUX2] = GATE(CLK_PCIE_AUX2, "clk_pcie_aux2", "xin24m", 0, RK3588_CLKGATE_CON(34), 3, GFLAGS), + [CLK_PCIE_AUX3] = GATE(CLK_PCIE_AUX3, "clk_pcie_aux3", "xin24m", 0, RK3588_CLKGATE_CON(34), 4, GFLAGS), + [CLK_PCIE_AUX4] = GATE(CLK_PCIE_AUX4, "clk_pcie_aux4", "xin24m", 0, RK3588_CLKGATE_CON(34), 5, GFLAGS), + [CLK_PIPEPHY0_REF] = GATE(CLK_PIPEPHY0_REF, "clk_pipephy0_ref", "xin24m", 0, RK3588_CLKGATE_CON(37), 0, GFLAGS), + [CLK_PIPEPHY1_REF] = GATE(CLK_PIPEPHY1_REF, "clk_pipephy1_ref", "xin24m", 0, RK3588_CLKGATE_CON(37), 1, GFLAGS), + [CLK_PIPEPHY2_REF] = GATE(CLK_PIPEPHY2_REF, "clk_pipephy2_ref", "xin24m", 0, RK3588_CLKGATE_CON(37), 2, GFLAGS), + [PCLK_PHP_ROOT] = COMPOSITE_NODIV(PCLK_PHP_ROOT, "pclk_php_root", mux_150m_50m_24m_p, 0, + RK3588_CLKSEL_CON(80), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(32), 0, GFLAGS), + [PCLK_GMAC0] = GATE(PCLK_GMAC0, "pclk_gmac0", "pclk_php_root", 0, RK3588_CLKGATE_CON(32), 3, GFLAGS), + [PCLK_GMAC1] = GATE(PCLK_GMAC1, "pclk_gmac1", "pclk_php_root", 0, RK3588_CLKGATE_CON(32), 4, GFLAGS), + [ACLK_PCIE_ROOT] = COMPOSITE(ACLK_PCIE_ROOT, "aclk_pcie_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(80), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(32), 6, GFLAGS), + [ACLK_PHP_ROOT] = COMPOSITE(ACLK_PHP_ROOT, "aclk_php_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(80), 13, 1, MFLAGS, 8, 5, DFLAGS, + RK3588_CLKGATE_CON(32), 7, GFLAGS), + [ACLK_PCIE_BRIDGE] = GATE(ACLK_PCIE_BRIDGE, "aclk_pcie_bridge", "aclk_pcie_root", 0, RK3588_CLKGATE_CON(32), 8, GFLAGS), + [ACLK_GMAC0] = GATE(ACLK_GMAC0, "aclk_gmac0", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(32), 10, GFLAGS), + [ACLK_GMAC1] = GATE(ACLK_GMAC1, "aclk_gmac1", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(32), 11, GFLAGS), + [CLK_PMALIVE0] = GATE(CLK_PMALIVE0, "clk_pmalive0", "xin24m", 0, RK3588_CLKGATE_CON(37), 4, GFLAGS), + [CLK_PMALIVE1] = GATE(CLK_PMALIVE1, "clk_pmalive1", "xin24m", 0, RK3588_CLKGATE_CON(37), 5, GFLAGS), + [CLK_PMALIVE2] = GATE(CLK_PMALIVE2, "clk_pmalive2", "xin24m", 0, RK3588_CLKGATE_CON(37), 6, GFLAGS), + [ACLK_SATA0] = GATE(ACLK_SATA0, "aclk_sata0", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(37), 7, GFLAGS), + [ACLK_SATA1] = GATE(ACLK_SATA1, "aclk_sata1", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(37), 8, GFLAGS), + [ACLK_SATA2] = GATE(ACLK_SATA2, "aclk_sata2", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(37), 9, GFLAGS), + [CLK_RXOOB0] = COMPOSITE(CLK_RXOOB0, "clk_rxoob0", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(82), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(37), 10, GFLAGS), + [CLK_RXOOB1] = COMPOSITE(CLK_RXOOB1, "clk_rxoob1", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(82), 15, 1, MFLAGS, 8, 7, DFLAGS, + RK3588_CLKGATE_CON(37), 11, GFLAGS), + [CLK_RXOOB2] = COMPOSITE(CLK_RXOOB2, "clk_rxoob2", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(83), 7, 1, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(37), 12, GFLAGS), + [ACLK_USB3OTG2] = GATE(ACLK_USB3OTG2, "aclk_usb3otg2", "aclk_mmu_php", 0, RK3588_CLKGATE_CON(35), 7, GFLAGS), + [SUSPEND_CLK_USB3OTG2] = GATE(SUSPEND_CLK_USB3OTG2, "suspend_clk_usb3otg2", "xin24m", 0, RK3588_CLKGATE_CON(35), 8, GFLAGS), + [REF_CLK_USB3OTG2] = GATE(REF_CLK_USB3OTG2, "ref_clk_usb3otg2", "xin24m", 0, RK3588_CLKGATE_CON(35), 9, GFLAGS), + [CLK_UTMI_OTG2] = COMPOSITE(CLK_UTMI_OTG2, "clk_utmi_otg2", mux_150m_50m_24m_p, 0, + RK3588_CLKSEL_CON(84), 12, 2, MFLAGS, 8, 4, DFLAGS, + RK3588_CLKGATE_CON(35), 10, GFLAGS), + [CLK_PIPEPHY0_PIPE_G] = GATE(CLK_PIPEPHY0_PIPE_G, "clk_pipephy0_pipe_g", "clk_pipephy0_pipe_i", 0, RK3588_CLKGATE_CON(38), 3, GFLAGS), + [CLK_PIPEPHY1_PIPE_G] = GATE(CLK_PIPEPHY1_PIPE_G, "clk_pipephy1_pipe_g", "clk_pipephy1_pipe_i", 0, RK3588_CLKGATE_CON(38), 4, GFLAGS), + [CLK_PIPEPHY2_PIPE_G] = GATE(CLK_PIPEPHY2_PIPE_G, "clk_pipephy2_pipe_g", "clk_pipephy2_pipe_i", 0, RK3588_CLKGATE_CON(38), 5, GFLAGS), + [CLK_PIPEPHY0_PIPE_ASIC_G] = GATE(CLK_PIPEPHY0_PIPE_ASIC_G, "clk_pipephy0_pipe_asic_g", "clk_pipephy0_pipe_i", 0, RK3588_CLKGATE_CON(38), 6, GFLAGS), + [CLK_PIPEPHY1_PIPE_ASIC_G] = GATE(CLK_PIPEPHY1_PIPE_ASIC_G, "clk_pipephy1_pipe_asic_g", "clk_pipephy1_pipe_i", 0, RK3588_CLKGATE_CON(38), 7, GFLAGS), + [CLK_PIPEPHY2_PIPE_ASIC_G] = GATE(CLK_PIPEPHY2_PIPE_ASIC_G, "clk_pipephy2_pipe_asic_g", "clk_pipephy2_pipe_i", 0, RK3588_CLKGATE_CON(38), 8, GFLAGS), + [CLK_PIPEPHY2_PIPE_U3_G] = GATE(CLK_PIPEPHY2_PIPE_U3_G, "clk_pipephy2_pipe_u3_g", "clk_pipephy2_pipe_i", 0, RK3588_CLKGATE_CON(38), 9, GFLAGS), + [CLK_PCIE1L2_PIPE] = GATE(CLK_PCIE1L2_PIPE, "clk_pcie1l2_pipe", "clk_pipephy0_pipe_g", 0, RK3588_CLKGATE_CON(38), 13, GFLAGS), + [CLK_PCIE4L_PIPE] = GATE(CLK_PCIE4L_PIPE, "clk_pcie4l_pipe", "clk_pipe30phy_pipe0_i", 0, RK3588_CLKGATE_CON(39), 0, GFLAGS), + [CLK_PCIE2L_PIPE] = GATE(CLK_PCIE2L_PIPE, "clk_pcie2l_pipe", "clk_pipe30phy_pipe2_i", 0, RK3588_CLKGATE_CON(39), 1, GFLAGS), + [PCLK_PCIE_COMBO_PIPE_PHY0] = GATE(PCLK_PCIE_COMBO_PIPE_PHY0, "pclk_pcie_combo_pipe_phy0", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 5, GFLAGS), + [PCLK_PCIE_COMBO_PIPE_PHY1] = GATE(PCLK_PCIE_COMBO_PIPE_PHY1, "pclk_pcie_combo_pipe_phy1", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 6, GFLAGS), + [PCLK_PCIE_COMBO_PIPE_PHY2] = GATE(PCLK_PCIE_COMBO_PIPE_PHY2, "pclk_pcie_combo_pipe_phy2", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 7, GFLAGS), + [PCLK_PCIE_COMBO_PIPE_PHY] = GATE(PCLK_PCIE_COMBO_PIPE_PHY, "pclk_pcie_combo_pipe_phy", "pclk_top_root", 0, RK3588_PHP_CLKGATE_CON(0), 8, GFLAGS), + [HCLK_RGA3_1] = GATE(HCLK_RGA3_1, "hclk_rga3_1", "hclk_rga3_root", 0, RK3588_CLKGATE_CON(76), 4, GFLAGS), + [ACLK_RGA3_1] = GATE(ACLK_RGA3_1, "aclk_rga3_1", "aclk_rga3_root", 0, RK3588_CLKGATE_CON(76), 5, GFLAGS), + [CLK_RGA3_1_CORE] = COMPOSITE(CLK_RGA3_1_CORE, "clk_rga3_1_core", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(174), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(76), 6, GFLAGS), + [ACLK_RGA3_ROOT] = COMPOSITE(ACLK_RGA3_ROOT, "aclk_rga3_root", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(174), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(76), 0, GFLAGS), + [HCLK_RGA3_ROOT] = COMPOSITE_NODIV(HCLK_RGA3_ROOT, "hclk_rga3_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(174), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(76), 1, GFLAGS), + [ACLK_RKVDEC_CCU] = COMPOSITE(ACLK_RKVDEC_CCU, "aclk_rkvdec_ccu", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(89), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(40), 2, GFLAGS), + [HCLK_RKVDEC0] = GATE(HCLK_RKVDEC0, "hclk_rkvdec0", "hclk_rkvdec0_pre", 0, RK3588_CLKGATE_CON(40), 3, GFLAGS), + [ACLK_RKVDEC0] = GATE(ACLK_RKVDEC0, "aclk_rkvdec0", "aclk_rkvdec0_pre", 0, RK3588_CLKGATE_CON(40), 4, GFLAGS), + [CLK_RKVDEC0_CA] = COMPOSITE(CLK_RKVDEC0_CA, "clk_rkvdec0_ca", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(90), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(40), 7, GFLAGS), + [CLK_RKVDEC0_HEVC_CA] = COMPOSITE(CLK_RKVDEC0_HEVC_CA, "clk_rkvdec0_hevc_ca", gpll_cpll_npll_1000m_p, 0, + RK3588_CLKSEL_CON(90), 11, 2, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(40), 8, GFLAGS), + [CLK_RKVDEC0_CORE] = COMPOSITE(CLK_RKVDEC0_CORE, "clk_rkvdec0_core", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(91), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(40), 9, GFLAGS), + [HCLK_RKVDEC1] = GATE(HCLK_RKVDEC1, "hclk_rkvdec1", "hclk_rkvdec1_pre", 0, RK3588_CLKGATE_CON(41), 2, GFLAGS), + [ACLK_RKVDEC1] = GATE(ACLK_RKVDEC1, "aclk_rkvdec1", "aclk_rkvdec1_pre", 0, RK3588_CLKGATE_CON(41), 3, GFLAGS), + [CLK_RKVDEC1_CA] = COMPOSITE(CLK_RKVDEC1_CA, "clk_rkvdec1_ca", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(93), 14, 1, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(41), 6, GFLAGS), + [CLK_RKVDEC1_HEVC_CA] = COMPOSITE(CLK_RKVDEC1_HEVC_CA, "clk_rkvdec1_hevc_ca", gpll_cpll_npll_1000m_p, 0, + RK3588_CLKSEL_CON(94), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(41), 7, GFLAGS), + [CLK_RKVDEC1_CORE] = COMPOSITE(CLK_RKVDEC1_CORE, "clk_rkvdec1_core", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(94), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(41), 8, GFLAGS), + [HCLK_SDIO] = GATE(HCLK_SDIO, "hclk_sdio", "hclk_sdio_pre", 0, RK3588_CLKGATE_CON(75), 2, GFLAGS), + [CCLK_SRC_SDIO] = COMPOSITE(CCLK_SRC_SDIO, "cclk_src_sdio", gpll_cpll_24m_p, 0, + RK3588_CLKSEL_CON(172), 8, 2, MFLAGS, 2, 6, DFLAGS, + RK3588_CLKGATE_CON(75), 3, GFLAGS), + [ACLK_USB_ROOT] = COMPOSITE(ACLK_USB_ROOT, "aclk_usb_root", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(96), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(42), 0, GFLAGS), + [HCLK_USB_ROOT] = COMPOSITE_NODIV(HCLK_USB_ROOT, "hclk_usb_root", mux_150m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(96), 6, 2, MFLAGS, + RK3588_CLKGATE_CON(42), 1, GFLAGS), + [HCLK_HOST0] = GATE(HCLK_HOST0, "hclk_host0", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 10, GFLAGS), + [HCLK_HOST_ARB0] = GATE(HCLK_HOST_ARB0, "hclk_host_arb0", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 11, GFLAGS), + [HCLK_HOST1] = GATE(HCLK_HOST1, "hclk_host1", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 12, GFLAGS), + [HCLK_HOST_ARB1] = GATE(HCLK_HOST_ARB1, "hclk_host_arb1", "hclk_usb", 0, RK3588_CLKGATE_CON(42), 13, GFLAGS), + [ACLK_USB3OTG0] = GATE(ACLK_USB3OTG0, "aclk_usb3otg0", "aclk_usb", 0, RK3588_CLKGATE_CON(42), 4, GFLAGS), + [SUSPEND_CLK_USB3OTG0] = GATE(SUSPEND_CLK_USB3OTG0, "suspend_clk_usb3otg0", "xin24m", 0, RK3588_CLKGATE_CON(42), 5, GFLAGS), + [REF_CLK_USB3OTG0] = GATE(REF_CLK_USB3OTG0, "ref_clk_usb3otg0", "xin24m", 0, RK3588_CLKGATE_CON(42), 6, GFLAGS), + [ACLK_USB3OTG1] = GATE(ACLK_USB3OTG1, "aclk_usb3otg1", "aclk_usb", 0, RK3588_CLKGATE_CON(42), 7, GFLAGS), + [SUSPEND_CLK_USB3OTG1] = GATE(SUSPEND_CLK_USB3OTG1, "suspend_clk_usb3otg1", "xin24m", 0, RK3588_CLKGATE_CON(42), 8, GFLAGS), + [REF_CLK_USB3OTG1] = GATE(REF_CLK_USB3OTG1, "ref_clk_usb3otg1", "xin24m", 0, RK3588_CLKGATE_CON(42), 9, GFLAGS), + [HCLK_IEP2P0] = GATE(HCLK_IEP2P0, "hclk_iep2p0", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 4, GFLAGS), + [ACLK_IEP2P0] = GATE(ACLK_IEP2P0, "aclk_iep2p0", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(45), 5, GFLAGS), + [CLK_IEP2P0_CORE] = COMPOSITE(CLK_IEP2P0_CORE, "clk_iep2p0_core", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(99), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(45), 6, GFLAGS), + [ACLK_JPEG_ENCODER0] = GATE(ACLK_JPEG_ENCODER0, "aclk_jpeg_encoder0", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 10, GFLAGS), + [HCLK_JPEG_ENCODER0] = GATE(HCLK_JPEG_ENCODER0, "hclk_jpeg_encoder0", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 11, GFLAGS), + [ACLK_JPEG_ENCODER1] = GATE(ACLK_JPEG_ENCODER1, "aclk_jpeg_encoder1", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 12, GFLAGS), + [HCLK_JPEG_ENCODER1] = GATE(HCLK_JPEG_ENCODER1, "hclk_jpeg_encoder1", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 13, GFLAGS), + [ACLK_JPEG_ENCODER2] = GATE(ACLK_JPEG_ENCODER2, "aclk_jpeg_encoder2", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 14, GFLAGS), + [HCLK_JPEG_ENCODER2] = GATE(HCLK_JPEG_ENCODER2, "hclk_jpeg_encoder2", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 15, GFLAGS), + [ACLK_JPEG_ENCODER3] = GATE(ACLK_JPEG_ENCODER3, "aclk_jpeg_encoder3", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(45), 0, GFLAGS), + [HCLK_JPEG_ENCODER3] = GATE(HCLK_JPEG_ENCODER3, "hclk_jpeg_encoder3", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 1, GFLAGS), + [ACLK_JPEG_DECODER] = GATE(ACLK_JPEG_DECODER, "aclk_jpeg_decoder", "aclk_jpeg_decoder_pre", 0, RK3588_CLKGATE_CON(45), 2, GFLAGS), + [HCLK_JPEG_DECODER] = GATE(HCLK_JPEG_DECODER, "hclk_jpeg_decoder", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 3, GFLAGS), + [HCLK_RGA2] = GATE(HCLK_RGA2, "hclk_rga2", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 7, GFLAGS), + [ACLK_RGA2] = GATE(ACLK_RGA2, "aclk_rga2", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 8, GFLAGS), + [CLK_RGA2_CORE] = COMPOSITE(CLK_RGA2_CORE, "clk_rga2_core", gpll_cpll_npll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(100), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(45), 9, GFLAGS), + [HCLK_RGA3_0] = GATE(HCLK_RGA3_0, "hclk_rga3_0", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 10, GFLAGS), + [ACLK_RGA3_0] = GATE(ACLK_RGA3_0, "aclk_rga3_0", "aclk_vdpu_root", 0, RK3588_CLKGATE_CON(45), 11, GFLAGS), + [CLK_RGA3_0_CORE] = COMPOSITE(CLK_RGA3_0_CORE, "clk_rga3_0_core", gpll_cpll_npll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(100), 13, 3, MFLAGS, 8, 5, DFLAGS, + RK3588_CLKGATE_CON(45), 12, GFLAGS), + [ACLK_VDPU_ROOT] = COMPOSITE(ACLK_VDPU_ROOT, "aclk_vdpu_root", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(98), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(44), 0, GFLAGS), + [ACLK_VDPU_LOW_ROOT] = COMPOSITE_NODIV(ACLK_VDPU_LOW_ROOT, "aclk_vdpu_low_root", mux_400m_200m_100m_24m_p, 0, + RK3588_CLKSEL_CON(98), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(44), 1, GFLAGS), + [HCLK_VDPU_ROOT] = COMPOSITE_NODIV(HCLK_VDPU_ROOT, "hclk_vdpu_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(98), 9, 2, MFLAGS, + RK3588_CLKGATE_CON(44), 2, GFLAGS), + [ACLK_JPEG_DECODER_ROOT] = COMPOSITE(ACLK_JPEG_DECODER_ROOT, "aclk_jpeg_decoder_root", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(99), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(44), 3, GFLAGS), + [ACLK_VPU] = GATE(ACLK_VPU, "aclk_vpu", "aclk_vdpu_low_pre", 0, RK3588_CLKGATE_CON(44), 8, GFLAGS), + [HCLK_VPU] = GATE(HCLK_VPU, "hclk_vpu", "hclk_vdpu_root", 0, RK3588_CLKGATE_CON(44), 9, GFLAGS), + [HCLK_RKVENC0_ROOT] = COMPOSITE_NODIV(HCLK_RKVENC0_ROOT, "hclk_rkvenc0_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(102), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(47), 0, GFLAGS), + [ACLK_RKVENC0_ROOT] = COMPOSITE(ACLK_RKVENC0_ROOT, "aclk_rkvenc0_root", gpll_cpll_npll_p, 0, + RK3588_CLKSEL_CON(102), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(47), 1, GFLAGS), + [HCLK_RKVENC0] = GATE(HCLK_RKVENC0, "hclk_rkvenc0", "hclk_rkvenc0_root", 0, RK3588_CLKGATE_CON(47), 4, GFLAGS), + [ACLK_RKVENC0] = GATE(ACLK_RKVENC0, "aclk_rkvenc0", "aclk_rkvenc0_root", 0, RK3588_CLKGATE_CON(47), 5, GFLAGS), + [CLK_RKVENC0_CORE] = COMPOSITE(CLK_RKVENC0_CORE, "clk_rkvenc0_core", gpll_cpll_aupll_npll_p, 0, + RK3588_CLKSEL_CON(102), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(47), 6, GFLAGS), + [HCLK_RKVENC1_ROOT] = COMPOSITE_NODIV(HCLK_RKVENC1_ROOT, "hclk_rkvenc1_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(104), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(48), 0, GFLAGS), + [ACLK_RKVENC1_ROOT] = COMPOSITE(ACLK_RKVENC1_ROOT, "aclk_rkvenc1_root", gpll_cpll_npll_p, 0, + RK3588_CLKSEL_CON(104), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(48), 1, GFLAGS), + [HCLK_RKVENC1] = GATE(HCLK_RKVENC1, "hclk_rkvenc1", "hclk_rkvenc1_pre", 0, RK3588_CLKGATE_CON(48), 4, GFLAGS), + [ACLK_RKVENC1] = GATE(ACLK_RKVENC1, "aclk_rkvenc1", "aclk_rkvenc1_pre", 0, RK3588_CLKGATE_CON(48), 5, GFLAGS), + [CLK_RKVENC1_CORE] = COMPOSITE(CLK_RKVENC1_CORE, "clk_rkvenc1_core", gpll_cpll_aupll_npll_p, 0, + RK3588_CLKSEL_CON(104), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(48), 6, GFLAGS), + [ICLK_CSIHOST01] = COMPOSITE_NODIV(ICLK_CSIHOST01, "iclk_csihost01", mux_400m_200m_100m_24m_p, 0, + RK3588_CLKSEL_CON(108), 14, 2, MFLAGS, + RK3588_CLKGATE_CON(51), 10, GFLAGS), + [ICLK_CSIHOST0] = GATE(ICLK_CSIHOST0, "iclk_csihost0", "iclk_csihost01", 0, RK3588_CLKGATE_CON(51), 11, GFLAGS), + [ICLK_CSIHOST1] = GATE(ICLK_CSIHOST1, "iclk_csihost1", "iclk_csihost01", 0, RK3588_CLKGATE_CON(51), 12, GFLAGS), + [PCLK_CSI_HOST_0] = GATE(PCLK_CSI_HOST_0, "pclk_csi_host_0", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 4, GFLAGS), + [PCLK_CSI_HOST_1] = GATE(PCLK_CSI_HOST_1, "pclk_csi_host_1", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 5, GFLAGS), + [PCLK_CSI_HOST_2] = GATE(PCLK_CSI_HOST_2, "pclk_csi_host_2", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 6, GFLAGS), + [PCLK_CSI_HOST_3] = GATE(PCLK_CSI_HOST_3, "pclk_csi_host_3", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 7, GFLAGS), + [PCLK_CSI_HOST_4] = GATE(PCLK_CSI_HOST_4, "pclk_csi_host_4", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 8, GFLAGS), + [PCLK_CSI_HOST_5] = GATE(PCLK_CSI_HOST_5, "pclk_csi_host_5", "pclk_vi_root", 0, RK3588_CLKGATE_CON(50), 9, GFLAGS), + [ACLK_FISHEYE0] = GATE(ACLK_FISHEYE0, "aclk_fisheye0", "aclk_vi_root", 0, RK3588_CLKGATE_CON(49), 14, GFLAGS), + [HCLK_FISHEYE0] = GATE(HCLK_FISHEYE0, "hclk_fisheye0", "hclk_vi_root", 0, RK3588_CLKGATE_CON(49), 15, GFLAGS), + [CLK_FISHEYE0_CORE] = COMPOSITE(CLK_FISHEYE0_CORE, "clk_fisheye0_core", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(108), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(50), 0, GFLAGS), + [ACLK_FISHEYE1] = GATE(ACLK_FISHEYE1, "aclk_fisheye1", "aclk_vi_root", 0, RK3588_CLKGATE_CON(50), 1, GFLAGS), + [HCLK_FISHEYE1] = GATE(HCLK_FISHEYE1, "hclk_fisheye1", "hclk_vi_root", 0, RK3588_CLKGATE_CON(50), 2, GFLAGS), + [CLK_FISHEYE1_CORE] = COMPOSITE(CLK_FISHEYE1_CORE, "clk_fisheye1_core", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(108), 12, 2, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(50), 3, GFLAGS), + [CLK_ISP0_CORE] = COMPOSITE(CLK_ISP0_CORE, "clk_isp0_core", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(107), 11, 2, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(49), 9, GFLAGS), + [CLK_ISP0_CORE_MARVIN] = GATE(CLK_ISP0_CORE_MARVIN, "clk_isp0_core_marvin", "clk_isp0_core", 0, RK3588_CLKGATE_CON(49), 10, GFLAGS), + [CLK_ISP0_CORE_VICAP] = GATE(CLK_ISP0_CORE_VICAP, "clk_isp0_core_vicap", "clk_isp0_core", 0, RK3588_CLKGATE_CON(49), 11, GFLAGS), + [ACLK_ISP0] = GATE(ACLK_ISP0, "aclk_isp0", "aclk_vi_root", 0, RK3588_CLKGATE_CON(49), 12, GFLAGS), + [HCLK_ISP0] = GATE(HCLK_ISP0, "hclk_isp0", "hclk_vi_root", 0, RK3588_CLKGATE_CON(49), 13, GFLAGS), + [ACLK_VI_ROOT] = COMPOSITE(ACLK_VI_ROOT, "aclk_vi_root", gpll_cpll_npll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(106), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(49), 0, GFLAGS), + [HCLK_VI_ROOT] = COMPOSITE_NODIV(HCLK_VI_ROOT, "hclk_vi_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(106), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(49), 1, GFLAGS), + [PCLK_VI_ROOT] = COMPOSITE_NODIV(PCLK_VI_ROOT, "pclk_vi_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(106), 10, 2, MFLAGS, + RK3588_CLKGATE_CON(49), 2, GFLAGS), + [DCLK_VICAP] = COMPOSITE(DCLK_VICAP, "dclk_vicap", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(107), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(49), 6, GFLAGS), + [ACLK_VICAP] = GATE(ACLK_VICAP, "aclk_vicap", "aclk_vi_root", 0, RK3588_CLKGATE_CON(49), 7, GFLAGS), + [HCLK_VICAP] = GATE(HCLK_VICAP, "hclk_vicap", "hclk_vi_root", 0, RK3588_CLKGATE_CON(49), 8, GFLAGS), + [PCLK_DP0] = GATE(PCLK_DP0, "pclk_dp0", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 4, GFLAGS), + [PCLK_DP1] = GATE(PCLK_DP1, "pclk_dp1", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 5, GFLAGS), + [PCLK_S_DP0] = GATE(PCLK_S_DP0, "pclk_s_dp0", "pclk_vo0_s_root", 0, RK3588_CLKGATE_CON(56), 6, GFLAGS), + [PCLK_S_DP1] = GATE(PCLK_S_DP1, "pclk_s_dp1", "pclk_vo0_s_root", 0, RK3588_CLKGATE_CON(56), 7, GFLAGS), + [CLK_DP0] = GATE(CLK_DP0, "clk_dp0", "aclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 8, GFLAGS), + [CLK_DP1] = GATE(CLK_DP1, "clk_dp1", "aclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 9, GFLAGS), + [HCLK_HDCP_KEY0] = GATE(HCLK_HDCP_KEY0, "hclk_hdcp_key0", "hclk_vo0_s_root", 0, RK3588_CLKGATE_CON(55), 11, GFLAGS), + [ACLK_HDCP0] = GATE(ACLK_HDCP0, "aclk_hdcp0", "aclk_hdcp0_pre", 0, RK3588_CLKGATE_CON(55), 12, GFLAGS), + [HCLK_HDCP0] = GATE(HCLK_HDCP0, "hclk_hdcp0", "hclk_vo0", 0, RK3588_CLKGATE_CON(55), 13, GFLAGS), + [PCLK_HDCP0] = GATE(PCLK_HDCP0, "pclk_hdcp0", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(55), 14, GFLAGS), + [HCLK_I2S4_8CH] = GATE(HCLK_I2S4_8CH, "hclk_i2s4_8ch", "hclk_vo0", 0, RK3588_CLKGATE_CON(56), 10, GFLAGS), + [ACLK_TRNG0] = GATE(ACLK_TRNG0, "aclk_trng0", "aclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 0, GFLAGS), + [PCLK_TRNG0] = GATE(PCLK_TRNG0, "pclk_trng0", "pclk_vo0_root", 0, RK3588_CLKGATE_CON(56), 1, GFLAGS), + [ACLK_VO0_ROOT] = COMPOSITE(ACLK_VO0_ROOT, "aclk_vo0_root", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(116), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(55), 0, GFLAGS), + [HCLK_VO0_ROOT] = COMPOSITE_NODIV(HCLK_VO0_ROOT, "hclk_vo0_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(116), 6, 2, MFLAGS, + RK3588_CLKGATE_CON(55), 1, GFLAGS), + [HCLK_VO0_S_ROOT] = COMPOSITE_NODIV(HCLK_VO0_S_ROOT, "hclk_vo0_s_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(116), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(55), 2, GFLAGS), + [PCLK_VO0_ROOT] = COMPOSITE_NODIV(PCLK_VO0_ROOT, "pclk_vo0_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(116), 10, 2, MFLAGS, + RK3588_CLKGATE_CON(55), 3, GFLAGS), + [PCLK_VO0_S_ROOT] = COMPOSITE_NODIV(PCLK_VO0_S_ROOT, "pclk_vo0_s_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(116), 12, 2, MFLAGS, + RK3588_CLKGATE_CON(55), 4, GFLAGS), + [PCLK_VO0GRF] = GATE(PCLK_VO0GRF, "pclk_vo0grf", "pclk_vo0_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(55), 10, GFLAGS), + [CLK_I2S4_8CH_TX_SRC] = COMPOSITE(CLK_I2S4_8CH_TX_SRC, "clk_i2s4_8ch_tx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(118), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(56), 11, GFLAGS), + [CLK_I2S4_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S4_8CH_TX_FRAC, "clk_i2s4_8ch_tx_frac", "clk_i2s4_8ch_tx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(119), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(56), 12, GFLAGS, + &rk3588_i2s4_8ch_tx_fracmux), + [MCLK_I2S4_8CH_TX] = GATE(MCLK_I2S4_8CH_TX, "mclk_i2s4_8ch_tx", "clk_i2s4_8ch_tx", 0, RK3588_CLKGATE_CON(56), 13, GFLAGS), + [CLK_I2S4_8CH_TX] = &rk3588_i2s4_8ch_tx_fracmux.cell, + [HCLK_I2S8_8CH] = GATE(HCLK_I2S8_8CH, "hclk_i2s8_8ch", "hclk_vo0", 0, RK3588_CLKGATE_CON(56), 14, GFLAGS), + [CLK_I2S8_8CH_TX_SRC] = COMPOSITE(CLK_I2S8_8CH_TX_SRC, "clk_i2s8_8ch_tx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(120), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(56), 15, GFLAGS), + [CLK_I2S8_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S8_8CH_TX_FRAC, "clk_i2s8_8ch_tx_frac", "clk_i2s8_8ch_tx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(121), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(57), 0, GFLAGS, + &rk3588_i2s8_8ch_tx_fracmux), + [MCLK_I2S8_8CH_TX] = GATE(MCLK_I2S8_8CH_TX, "mclk_i2s8_8ch_tx", "clk_i2s8_8ch_tx", 0, RK3588_CLKGATE_CON(57), 1, GFLAGS), + [CLK_I2S8_8CH_TX] = &rk3588_i2s8_8ch_tx_fracmux.cell, + [HCLK_SPDIF2_DP0] = GATE(HCLK_SPDIF2_DP0, "hclk_spdif2_dp0", "hclk_vo0", 0, RK3588_CLKGATE_CON(57), 2, GFLAGS), + [CLK_SPDIF2_DP0_SRC] = COMPOSITE(CLK_SPDIF2_DP0_SRC, "clk_spdif2_dp0_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(122), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(57), 3, GFLAGS), + [CLK_SPDIF2_DP0_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF2_DP0_FRAC, "clk_spdif2_dp0_frac", "clk_spdif2_dp0_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(123), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(57), 4, GFLAGS, + &rk3588_spdif2_dp0_fracmux), + [MCLK_SPDIF2_DP0] = GATE(MCLK_SPDIF2_DP0, "mclk_spdif2_dp0", "clk_spdif2_dp0", 0, RK3588_CLKGATE_CON(57), 5, GFLAGS), + [CLK_SPDIF2_DP0] = &rk3588_spdif2_dp0_fracmux.cell, + [MCLK_SPDIF2] = GATE(MCLK_SPDIF2, "mclk_spdif2", "clk_spdif2_dp0", 0, RK3588_CLKGATE_CON(57), 6, GFLAGS), + [HCLK_SPDIF5_DP1] = GATE(HCLK_SPDIF5_DP1, "hclk_spdif5_dp1", "hclk_vo0", 0, RK3588_CLKGATE_CON(57), 7, GFLAGS), + [CLK_SPDIF5_DP1_SRC] = COMPOSITE(CLK_SPDIF5_DP1_SRC, "clk_spdif5_dp1_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(124), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(57), 8, GFLAGS), + [CLK_SPDIF5_DP1_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF5_DP1_FRAC, "clk_spdif5_dp1_frac", "clk_spdif5_dp1_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(125), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(57), 9, GFLAGS, + &rk3588_spdif5_dp1_fracmux), + [MCLK_SPDIF5_DP1] = GATE(MCLK_SPDIF5_DP1, "mclk_spdif5_dp1", "clk_spdif5_dp1", 0, RK3588_CLKGATE_CON(57), 10, GFLAGS), + [CLK_SPDIF5_DP1] = &rk3588_spdif5_dp1_fracmux.cell, + [MCLK_SPDIF5] = GATE(MCLK_SPDIF5, "mclk_spdif5", "clk_spdif5_dp1", 0, RK3588_CLKGATE_CON(57), 11, GFLAGS), + [PCLK_EDP0] = GATE(PCLK_EDP0, "pclk_edp0", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(62), 0, GFLAGS), + [CLK_EDP0_24M] = GATE(CLK_EDP0_24M, "clk_edp0_24m", "xin24m", 0, RK3588_CLKGATE_CON(62), 1, GFLAGS), + [CLK_EDP0_200M] = COMPOSITE_NODIV(CLK_EDP0_200M, "clk_edp0_200m", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(140), 1, 2, MFLAGS, + RK3588_CLKGATE_CON(62), 2, GFLAGS), + [PCLK_EDP1] = GATE(PCLK_EDP1, "pclk_edp1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(62), 3, GFLAGS), + [CLK_EDP1_24M] = GATE(CLK_EDP1_24M, "clk_edp1_24m", "xin24m", 0, RK3588_CLKGATE_CON(62), 4, GFLAGS), + [CLK_EDP1_200M] = COMPOSITE_NODIV(CLK_EDP1_200M, "clk_edp1_200m", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(140), 3, 2, MFLAGS, + RK3588_CLKGATE_CON(62), 5, GFLAGS), + [HCLK_HDCP_KEY1] = GATE(HCLK_HDCP_KEY1, "hclk_hdcp_key1", "hclk_vo1_s_root", 0, RK3588_CLKGATE_CON(60), 4, GFLAGS), + [ACLK_HDCP1] = GATE(ACLK_HDCP1, "aclk_hdcp1", "aclk_hdcp1_pre", 0, RK3588_CLKGATE_CON(60), 5, GFLAGS), + [HCLK_HDCP1] = GATE(HCLK_HDCP1, "hclk_hdcp1", "hclk_vo1", 0, RK3588_CLKGATE_CON(60), 6, GFLAGS), + [PCLK_HDCP1] = GATE(PCLK_HDCP1, "pclk_hdcp1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(60), 7, GFLAGS), + [ACLK_HDMIRX] = GATE(ACLK_HDMIRX, "aclk_hdmirx", "aclk_hdmirx_root", 0, RK3588_CLKGATE_CON(61), 9, GFLAGS), + [PCLK_HDMIRX] = GATE(PCLK_HDMIRX, "pclk_hdmirx", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(61), 10, GFLAGS), + [CLK_HDMIRX_REF] = GATE(CLK_HDMIRX_REF, "clk_hdmirx_ref", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(61), 11, GFLAGS), + [CLK_HDMIRX_AUD_SRC] = COMPOSITE(CLK_HDMIRX_AUD_SRC, "clk_hdmirx_aud_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(138), 8, 1, MFLAGS, 0, 8, DFLAGS, + RK3588_CLKGATE_CON(61), 12, GFLAGS), + [CLK_HDMIRX_AUD_FRAC] = COMPOSITE_FRACMUX(CLK_HDMIRX_AUD_FRAC, "clk_hdmirx_aud_frac", "clk_hdmirx_aud_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(139), 0, + RK3588_CLKGATE_CON(61), 13, GFLAGS, + &rk3588_hdmirx_aud_fracmux), + [CLK_HDMIRX_AUD] = GATE(CLK_HDMIRX_AUD, "clk_hdmirx_aud", "clk_hdmirx_aud_mux", 0, RK3588_CLKGATE_CON(61), 14, GFLAGS), + [CLK_HDMIRX_AUD_P_MUX] = &rk3588_hdmirx_aud_fracmux.cell, + [PCLK_HDMITX0] = GATE(PCLK_HDMITX0, "pclk_hdmitx0", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(60), 11, GFLAGS), + [CLK_HDMITX0_EARC] = COMPOSITE(CLK_HDMITX0_EARC, "clk_hdmitx0_earc", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(133), 6, 1, MFLAGS, 1, 5, DFLAGS, + RK3588_CLKGATE_CON(60), 15, GFLAGS), + [CLK_HDMITX0_REF] = GATE(CLK_HDMITX0_REF, "clk_hdmitx0_ref", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(61), 0, GFLAGS), + [PCLK_HDMITX1] = GATE(PCLK_HDMITX1, "pclk_hdmitx1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(61), 2, GFLAGS), + [CLK_HDMITX1_EARC] = COMPOSITE(CLK_HDMITX1_EARC, "clk_hdmitx1_earc", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(136), 6, 1, MFLAGS, 1, 5, DFLAGS, + RK3588_CLKGATE_CON(61), 6, GFLAGS), + [CLK_HDMITX1_REF] = GATE(CLK_HDMITX1_REF, "clk_hdmitx1_ref", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(61), 7, GFLAGS), + [CLK_HDMITRX_REFSRC] = COMPOSITE_HALFDIV(CLK_HDMITRX_REFSRC, "clk_hdmitrx_refsrc", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(157), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(65), 9, GFLAGS), + [ACLK_TRNG1] = GATE(ACLK_TRNG1, "aclk_trng1", "aclk_hdcp1_root", 0, RK3588_CLKGATE_CON(60), 9, GFLAGS), + [PCLK_TRNG1] = GATE(PCLK_TRNG1, "pclk_trng1", "pclk_vo1_root", 0, RK3588_CLKGATE_CON(60), 10, GFLAGS), + [ACLK_HDCP1_ROOT] = COMPOSITE(ACLK_HDCP1_ROOT, "aclk_hdcp1_root", aclk_hdcp1_root_p, 0, + RK3588_CLKSEL_CON(128), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(59), 0, GFLAGS), + [ACLK_HDMIRX_ROOT] = COMPOSITE(ACLK_HDMIRX_ROOT, "aclk_hdmirx_root", gpll_cpll_p, 0, + RK3588_CLKSEL_CON(128), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(59), 1, GFLAGS), + [HCLK_VO1_ROOT] = COMPOSITE_NODIV(HCLK_VO1_ROOT, "hclk_vo1_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(128), 13, 2, MFLAGS, + RK3588_CLKGATE_CON(59), 2, GFLAGS), + [HCLK_VO1_S_ROOT] = COMPOSITE_NODIV(HCLK_VO1_S_ROOT, "hclk_vo1_s_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(129), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(59), 3, GFLAGS), + [PCLK_VO1_ROOT] = COMPOSITE_NODIV(PCLK_VO1_ROOT, "pclk_vo1_root", mux_150m_100m_24m_p, 0, + RK3588_CLKSEL_CON(129), 2, 2, MFLAGS, + RK3588_CLKGATE_CON(59), 4, GFLAGS), + [PCLK_VO1_S_ROOT] = COMPOSITE_NODIV(PCLK_VO1_S_ROOT, "pclk_vo1_s_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(129), 4, 2, MFLAGS, + RK3588_CLKGATE_CON(59), 5, GFLAGS), + [PCLK_S_EDP0] = GATE(PCLK_S_EDP0, "pclk_s_edp0", "pclk_vo1_s_root", 0, RK3588_CLKGATE_CON(59), 14, GFLAGS), + [PCLK_S_EDP1] = GATE(PCLK_S_EDP1, "pclk_s_edp1", "pclk_vo1_s_root", 0, RK3588_CLKGATE_CON(59), 15, GFLAGS), + [PCLK_S_HDMIRX] = GATE(PCLK_S_HDMIRX, "pclk_s_hdmirx", "pclk_vo1_s_root", 0, RK3588_CLKGATE_CON(65), 8, GFLAGS), + [HCLK_I2S10_8CH] = GATE(HCLK_I2S10_8CH, "hclk_i2s10_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(65), 4, GFLAGS), + [CLK_I2S10_8CH_RX_SRC] = COMPOSITE(CLK_I2S10_8CH_RX_SRC, "clk_i2s10_8ch_rx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(155), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(65), 5, GFLAGS), + [CLK_I2S10_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S10_8CH_RX_FRAC, "clk_i2s10_8ch_rx_frac", "clk_i2s10_8ch_rx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(156), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(65), 6, GFLAGS, + &rk3588_i2s10_8ch_rx_fracmux), + [CLK_I2S10_8CH_RX] = &rk3588_i2s10_8ch_rx_fracmux.cell, + [MCLK_I2S10_8CH_RX] = GATE(MCLK_I2S10_8CH_RX, "mclk_i2s10_8ch_rx", "clk_i2s10_8ch_rx", 0, RK3588_CLKGATE_CON(65), 7, GFLAGS), + [HCLK_I2S7_8CH] = GATE(HCLK_I2S7_8CH, "hclk_i2s7_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(60), 0, GFLAGS), + [CLK_I2S7_8CH_RX_SRC] = COMPOSITE(CLK_I2S7_8CH_RX_SRC, "clk_i2s7_8ch_rx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(129), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3588_CLKGATE_CON(60), 1, GFLAGS), + [CLK_I2S7_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S7_8CH_RX_FRAC, "clk_i2s7_8ch_rx_frac", "clk_i2s7_8ch_rx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(130), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(60), 2, GFLAGS, + &rk3588_i2s7_8ch_rx_fracmux), + [CLK_I2S7_8CH_RX] = &rk3588_i2s7_8ch_rx_fracmux.cell, + [MCLK_I2S7_8CH_RX] = GATE(MCLK_I2S7_8CH_RX, "mclk_i2s7_8ch_rx", "clk_i2s7_8ch_rx", 0, RK3588_CLKGATE_CON(60), 3, GFLAGS), + [HCLK_I2S9_8CH] = GATE(HCLK_I2S9_8CH, "hclk_i2s9_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(65), 0, GFLAGS), + [CLK_I2S9_8CH_RX_SRC] = COMPOSITE(CLK_I2S9_8CH_RX_SRC, "clk_i2s9_8ch_rx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(153), 12, 1, MFLAGS, 7, 5, DFLAGS, + RK3588_CLKGATE_CON(65), 1, GFLAGS), + [CLK_I2S9_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S9_8CH_RX_FRAC, "clk_i2s9_8ch_rx_frac", "clk_i2s9_8ch_rx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(154), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(65), 2, GFLAGS, + &rk3588_i2s9_8ch_rx_fracmux), + [CLK_I2S9_8CH_RX] = &rk3588_i2s9_8ch_rx_fracmux.cell, + [MCLK_I2S9_8CH_RX] = GATE(MCLK_I2S9_8CH_RX, "mclk_i2s9_8ch_rx", "clk_i2s9_8ch_rx", 0, RK3588_CLKGATE_CON(65), 3, GFLAGS), + [CLK_I2S5_8CH_TX_SRC] = COMPOSITE(CLK_I2S5_8CH_TX_SRC, "clk_i2s5_8ch_tx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(140), 10, 1, MFLAGS, 5, 5, DFLAGS, + RK3588_CLKGATE_CON(62), 6, GFLAGS), + [CLK_I2S5_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S5_8CH_TX_FRAC, "clk_i2s5_8ch_tx_frac", "clk_i2s5_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(141), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(62), 7, GFLAGS, + &rk3588_i2s5_8ch_tx_fracmux), + [CLK_I2S5_8CH_TX] = &rk3588_i2s5_8ch_tx_fracmux.cell, + [MCLK_I2S5_8CH_TX] = GATE(MCLK_I2S5_8CH_TX, "mclk_i2s5_8ch_tx", "clk_i2s5_8ch_tx", 0, RK3588_CLKGATE_CON(62), 8, GFLAGS), + [HCLK_I2S5_8CH] = GATE(HCLK_I2S5_8CH, "hclk_i2s5_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(62), 12, GFLAGS), + [CLK_I2S6_8CH_TX_SRC] = COMPOSITE(CLK_I2S6_8CH_TX_SRC, "clk_i2s6_8ch_tx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(144), 8, 1, MFLAGS, 3, 5, DFLAGS, + RK3588_CLKGATE_CON(62), 13, GFLAGS), + [CLK_I2S6_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S6_8CH_TX_FRAC, "clk_i2s6_8ch_tx_frac", "clk_i2s6_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(145), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(62), 14, GFLAGS, + &rk3588_i2s6_8ch_tx_fracmux), + [CLK_I2S6_8CH_TX] = &rk3588_i2s6_8ch_tx_fracmux.cell, + [MCLK_I2S6_8CH_TX] = GATE(MCLK_I2S6_8CH_TX, "mclk_i2s6_8ch_tx", "clk_i2s6_8ch_tx", 0, RK3588_CLKGATE_CON(62), 15, GFLAGS), + [CLK_I2S6_8CH_RX_SRC] = COMPOSITE(CLK_I2S6_8CH_RX_SRC, "clk_i2s6_8ch_rx_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(146), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(63), 0, GFLAGS), + [CLK_I2S6_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S6_8CH_RX_FRAC, "clk_i2s6_8ch_rx_frac", "clk_i2s6_8ch_rx_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(147), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(63), 1, GFLAGS, + &rk3588_i2s6_8ch_rx_fracmux), + [CLK_I2S6_8CH_RX] = &rk3588_i2s6_8ch_rx_fracmux.cell, + [MCLK_I2S6_8CH_RX] = GATE(MCLK_I2S6_8CH_RX, "mclk_i2s6_8ch_rx", "clk_i2s6_8ch_rx", 0, RK3588_CLKGATE_CON(63), 2, GFLAGS), + [I2S6_8CH_MCLKOUT] = MUX(I2S6_8CH_MCLKOUT, "i2s6_8ch_mclkout", i2s6_8ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(148), 2, 2, MFLAGS), + [HCLK_I2S6_8CH] = GATE(HCLK_I2S6_8CH, "hclk_i2s6_8ch", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 3, GFLAGS), + [HCLK_SPDIF3] = GATE(HCLK_SPDIF3, "hclk_spdif3", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 4, GFLAGS), + [CLK_SPDIF3_SRC] = COMPOSITE(CLK_SPDIF3_SRC, "clk_spdif3_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(148), 9, 1, MFLAGS, 4, 5, DFLAGS, + RK3588_CLKGATE_CON(63), 5, GFLAGS), + [CLK_SPDIF3_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF3_FRAC, "clk_spdif3_frac", "clk_spdif3_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(149), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(63), 6, GFLAGS, + &rk3588_spdif3_fracmux), + [CLK_SPDIF3] = &rk3588_spdif3_fracmux.cell, + [MCLK_SPDIF3] = GATE(MCLK_SPDIF3, "mclk_spdif3", "clk_spdif3", 0, RK3588_CLKGATE_CON(63), 7, GFLAGS), + [HCLK_SPDIF4] = GATE(HCLK_SPDIF4, "hclk_spdif4", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 8, GFLAGS), + [CLK_SPDIF4_SRC] = COMPOSITE(CLK_SPDIF4_SRC, "clk_spdif4_src", gpll_aupll_p, 0, + RK3588_CLKSEL_CON(150), 7, 1, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(63), 9, GFLAGS), + [CLK_SPDIF4_FRAC] = COMPOSITE_FRACMUX(CLK_SPDIF4_FRAC, "clk_spdif4_frac", "clk_spdif4_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(151), CLK_MUX_ROUND_CLOSEST, + RK3588_CLKGATE_CON(63), 10, GFLAGS, + &rk3588_spdif4_fracmux), + [CLK_SPDIF4] = &rk3588_spdif4_fracmux.cell, + [MCLK_SPDIF4] = GATE(MCLK_SPDIF4, "mclk_spdif4", "clk_spdif4", 0, RK3588_CLKGATE_CON(63), 11, GFLAGS), + [HCLK_SPDIFRX0] = GATE(HCLK_SPDIFRX0, "hclk_spdifrx0", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 12, GFLAGS), + [MCLK_SPDIFRX0] = COMPOSITE(MCLK_SPDIFRX0, "mclk_spdifrx0", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(152), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(63), 13, GFLAGS), + [HCLK_SPDIFRX1] = GATE(HCLK_SPDIFRX1, "hclk_spdifrx1", "hclk_vo1", 0, RK3588_CLKGATE_CON(63), 14, GFLAGS), + [MCLK_SPDIFRX1] = COMPOSITE(MCLK_SPDIFRX1, "mclk_spdifrx1", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(152), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(63), 15, GFLAGS), + [HCLK_SPDIFRX2] = GATE(HCLK_SPDIFRX2, "hclk_spdifrx2", "hclk_vo1", 0, RK3588_CLKGATE_CON(64), 0, GFLAGS), + [MCLK_SPDIFRX2] = COMPOSITE(MCLK_SPDIFRX2, "mclk_spdifrx2", gpll_cpll_aupll_p, 0, + RK3588_CLKSEL_CON(153), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(64), 1, GFLAGS), + [ACLK_VO1USB_TOP_ROOT] = COMPOSITE(ACLK_VO1USB_TOP_ROOT, "aclk_vo1usb_top_root", gpll_cpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(170), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(74), 0, GFLAGS), + [HCLK_VO1USB_TOP_ROOT] = COMPOSITE_NODIV(HCLK_VO1USB_TOP_ROOT, "hclk_vo1usb_top_root", mux_200m_100m_50m_24m_p, RT_CLK_F_IS_CRITICAL, + RK3588_CLKSEL_CON(170), 6, 2, MFLAGS, + RK3588_CLKGATE_CON(74), 2, GFLAGS), + [CLK_HDMIHDP0] = GATE(CLK_HDMIHDP0, "clk_hdmihdp0", "xin24m", 0, RK3588_CLKGATE_CON(73), 12, GFLAGS), + [CLK_HDMIHDP1] = GATE(CLK_HDMIHDP1, "clk_hdmihdp1", "xin24m", 0, RK3588_CLKGATE_CON(73), 13, GFLAGS), + [PCLK_HDPTX0] = GATE(PCLK_HDPTX0, "pclk_hdptx0", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 5, GFLAGS), + [PCLK_HDPTX1] = GATE(PCLK_HDPTX1, "pclk_hdptx1", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 6, GFLAGS), + [PCLK_USBDPPHY0] = GATE(PCLK_USBDPPHY0, "pclk_usbdpphy0", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 2, GFLAGS), + [PCLK_USBDPPHY1] = GATE(PCLK_USBDPPHY1, "pclk_usbdpphy1", "pclk_top_root", 0, RK3588_CLKGATE_CON(72), 4, GFLAGS), + [ACLK_VOP_ROOT] = COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", gpll_cpll_dmyaupll_npll_spll_p, 0, + RK3588_CLKSEL_CON(110), 5, 3, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(52), 0, GFLAGS), + [ACLK_VOP_LOW_ROOT] = COMPOSITE_NODIV(ACLK_VOP_LOW_ROOT, "aclk_vop_low_root", mux_400m_200m_100m_24m_p, 0, + RK3588_CLKSEL_CON(110), 8, 2, MFLAGS, + RK3588_CLKGATE_CON(52), 1, GFLAGS), + [HCLK_VOP_ROOT] = COMPOSITE_NODIV(HCLK_VOP_ROOT, "hclk_vop_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(110), 10, 2, MFLAGS, + RK3588_CLKGATE_CON(52), 2, GFLAGS), + [PCLK_VOP_ROOT] = COMPOSITE_NODIV(PCLK_VOP_ROOT, "pclk_vop_root", mux_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(110), 12, 2, MFLAGS, + RK3588_CLKGATE_CON(52), 3, GFLAGS), + [HCLK_VOP] = GATE(HCLK_VOP, "hclk_vop", "hclk_vop_root", 0, RK3588_CLKGATE_CON(52), 8, GFLAGS), + [ACLK_VOP] = COMPOSITE_NODIV(ACLK_VOP, "aclk_vop", aclk_vop_sub_src_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(115), 9, 1, MFLAGS, + RK3588_CLKGATE_CON(52), 9, GFLAGS), + [DCLK_VOP0_SRC] = COMPOSITE(DCLK_VOP0_SRC, "dclk_vop0_src", gpll_cpll_v0pll_aupll_p, 0, + RK3588_CLKSEL_CON(111), 7, 2, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(52), 10, GFLAGS), + [DCLK_VOP1_SRC] = COMPOSITE(DCLK_VOP1_SRC, "dclk_vop1_src", gpll_cpll_v0pll_aupll_p, 0, + RK3588_CLKSEL_CON(111), 14, 2, MFLAGS, 9, 5, DFLAGS, + RK3588_CLKGATE_CON(52), 11, GFLAGS), + [DCLK_VOP2_SRC] = COMPOSITE(DCLK_VOP2_SRC, "dclk_vop2_src", gpll_cpll_v0pll_aupll_p, 0, + RK3588_CLKSEL_CON(112), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_CLKGATE_CON(52), 12, GFLAGS), + [DCLK_VOP0] = COMPOSITE_NODIV(DCLK_VOP0, "dclk_vop0", dclk_vop0_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(112), 7, 2, MFLAGS, + RK3588_CLKGATE_CON(52), 13, GFLAGS), + [DCLK_VOP1] = COMPOSITE_NODIV(DCLK_VOP1, "dclk_vop1", dclk_vop1_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(112), 9, 2, MFLAGS, + RK3588_CLKGATE_CON(53), 0, GFLAGS), + [DCLK_VOP2] = COMPOSITE_NODIV(DCLK_VOP2, "dclk_vop2", dclk_vop2_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(112), 11, 2, MFLAGS, + RK3588_CLKGATE_CON(53), 1, GFLAGS), + [DCLK_VOP3] = COMPOSITE(DCLK_VOP3, "dclk_vop3", gpll_cpll_v0pll_aupll_p, 0, + RK3588_CLKSEL_CON(113), 7, 2, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(53), 2, GFLAGS), + [PCLK_DSIHOST0] = GATE(PCLK_DSIHOST0, "pclk_dsihost0", "pclk_vop_root", 0, RK3588_CLKGATE_CON(53), 4, GFLAGS), + [PCLK_DSIHOST1] = GATE(PCLK_DSIHOST1, "pclk_dsihost1", "pclk_vop_root", 0, RK3588_CLKGATE_CON(53), 5, GFLAGS), + [CLK_DSIHOST0] = COMPOSITE(CLK_DSIHOST0, "clk_dsihost0", gpll_cpll_v0pll_spll_p, 0, + RK3588_CLKSEL_CON(114), 7, 2, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(53), 6, GFLAGS), + [CLK_DSIHOST1] = COMPOSITE(CLK_DSIHOST1, "clk_dsihost1", gpll_cpll_v0pll_spll_p, 0, + RK3588_CLKSEL_CON(115), 7, 2, MFLAGS, 0, 7, DFLAGS, + RK3588_CLKGATE_CON(53), 7, GFLAGS), + [CLK_VOP_PMU] = GATE(CLK_VOP_PMU, "clk_vop_pmu", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(53), 8, GFLAGS), + [ACLK_VOP_DOBY] = GATE(ACLK_VOP_DOBY, "aclk_vop_doby", "aclk_vop_root", 0, RK3588_CLKGATE_CON(53), 10, GFLAGS), + [ACLK_VOP_DIV2_SRC] = FACTOR(ACLK_VOP_DIV2_SRC, "aclk_vop_div2_src", "aclk_vop_root", 0, 1, 2), + [CLK_USBDP_PHY0_IMMORTAL] = GATE(CLK_USBDP_PHY0_IMMORTAL, "clk_usbdp_phy0_immortal", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(2), 8, GFLAGS), + [CLK_USBDP_PHY1_IMMORTAL] = GATE(CLK_USBDP_PHY1_IMMORTAL, "clk_usbdp_phy1_immortal", "xin24m", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(2), 15, GFLAGS), + [CLK_PMU0] = GATE(CLK_PMU0, "clk_pmu0", "xin24m", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 1, GFLAGS), + [PCLK_PMU0] = GATE(PCLK_PMU0, "pclk_pmu0", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 2, GFLAGS), + [PCLK_PMU0IOC] = GATE(PCLK_PMU0IOC, "pclk_pmu0ioc", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 4, GFLAGS), + [PCLK_GPIO0] = GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(5), 5, GFLAGS), + [DBCLK_GPIO0] = COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", mux_24m_32k_p, 0, + RK3588_PMU_CLKSEL_CON(17), 0, 1, MFLAGS, + RK3588_PMU_CLKGATE_CON(5), 6, GFLAGS), + [PCLK_I2C0] = GATE(PCLK_I2C0, "pclk_i2c0", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(2), 1, GFLAGS), + [CLK_I2C0] = COMPOSITE_NODIV(CLK_I2C0, "clk_i2c0", pmu_200m_100m_p, RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(3), 6, 1, MFLAGS, + RK3588_PMU_CLKGATE_CON(2), 2, GFLAGS), + [HCLK_I2S1_8CH] = GATE(HCLK_I2S1_8CH, "hclk_i2s1_8ch", "hclk_pmu1_root", 0, RK3588_PMU_CLKGATE_CON(2), 7, GFLAGS), + [CLK_I2S1_8CH_TX_SRC] = COMPOSITE_NOMUX(CLK_I2S1_8CH_TX_SRC, "clk_i2s1_8ch_tx_src", "cpll", 0, + RK3588_PMU_CLKSEL_CON(5), 2, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(2), 8, GFLAGS), + [CLK_I2S1_8CH_TX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_TX_FRAC, "clk_i2s1_8ch_tx_frac", "clk_i2s1_8ch_tx_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(6), CLK_MUX_ROUND_CLOSEST, + RK3588_PMU_CLKGATE_CON(2), 9, GFLAGS, + &rk3588_i2s1_8ch_tx_fracmux), + [CLK_I2S1_8CH_TX] = &rk3588_i2s1_8ch_tx_fracmux.cell, + [MCLK_I2S1_8CH_TX] = GATE(MCLK_I2S1_8CH_TX, "mclk_i2s1_8ch_tx", "clk_i2s1_8ch_tx", 0, RK3588_PMU_CLKGATE_CON(2), 10, GFLAGS), + [CLK_I2S1_8CH_RX_SRC] = COMPOSITE_NOMUX(CLK_I2S1_8CH_RX_SRC, "clk_i2s1_8ch_rx_src", "cpll", 0, + RK3588_PMU_CLKSEL_CON(7), 2, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(2), 11, GFLAGS), + [CLK_I2S1_8CH_RX_FRAC] = COMPOSITE_FRACMUX(CLK_I2S1_8CH_RX_FRAC, "clk_i2s1_8ch_rx_frac", "clk_i2s1_8ch_rx_src", + RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(8), CLK_MUX_ROUND_CLOSEST, + RK3588_PMU_CLKGATE_CON(2), 12, GFLAGS, + &rk3588_i2s1_8ch_rx_fracmux), + [CLK_I2S1_8CH_RX] = &rk3588_i2s1_8ch_rx_fracmux.cell, + [MCLK_I2S1_8CH_RX] = GATE(MCLK_I2S1_8CH_RX, "mclk_i2s1_8ch_rx", "clk_i2s1_8ch_rx", 0, RK3588_PMU_CLKGATE_CON(2), 13, GFLAGS), + [I2S1_8CH_MCLKOUT] = MUX(I2S1_8CH_MCLKOUT, "i2s1_8ch_mclkout", i2s1_8ch_mclkout_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(9), 2, 2, MFLAGS), + [CLK_PMU1_50M_SRC] = COMPOSITE_NOMUX(CLK_PMU1_50M_SRC, "clk_pmu1_50m_src", "clk_pmu1_400m_src", 0, + RK3588_PMU_CLKSEL_CON(0), 0, 4, DFLAGS, + RK3588_PMU_CLKGATE_CON(0), 0, GFLAGS), + [CLK_PMU1_100M_SRC] = COMPOSITE_NOMUX(CLK_PMU1_100M_SRC, "clk_pmu1_100m_src", "clk_pmu1_400m_src", 0, + RK3588_PMU_CLKSEL_CON(0), 4, 3, DFLAGS, + RK3588_PMU_CLKGATE_CON(0), 1, GFLAGS), + [CLK_PMU1_200M_SRC] = COMPOSITE_NOMUX(CLK_PMU1_200M_SRC, "clk_pmu1_200m_src", "clk_pmu1_400m_src", 0, + RK3588_PMU_CLKSEL_CON(0), 7, 3, DFLAGS, + RK3588_PMU_CLKGATE_CON(0), 2, GFLAGS), + [CLK_PMU1_300M_SRC] = COMPOSITE(CLK_PMU1_300M_SRC, "clk_pmu1_300m_src", pmu_300m_24m_p, 0, + RK3588_PMU_CLKSEL_CON(0), 15, 1, MFLAGS, 10, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(0), 3, GFLAGS), + [CLK_PMU1_400M_SRC] = COMPOSITE(CLK_PMU1_400M_SRC, "clk_pmu1_400m_src", pmu_400m_24m_p, 0, + RK3588_PMU_CLKSEL_CON(1), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(0), 4, GFLAGS), + [HCLK_PMU1_ROOT] = COMPOSITE_NODIV(HCLK_PMU1_ROOT, "hclk_pmu1_root", hclk_pmu1_root_p, RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, + RK3588_PMU_CLKGATE_CON(0), 5, GFLAGS), + [PCLK_PMU1_ROOT] = COMPOSITE_NODIV(PCLK_PMU1_ROOT, "pclk_pmu1_root", pmu_100m_50m_24m_src_p, RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(1), 8, 2, MFLAGS, + RK3588_PMU_CLKGATE_CON(0), 7, GFLAGS), + [PCLK_PMU0_ROOT] = GATE(PCLK_PMU0_ROOT, "pclk_pmu0_root", "pclk_pmu1_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(5), 0, GFLAGS), + [HCLK_PMU_CM0_ROOT] = COMPOSITE_NODIV(HCLK_PMU_CM0_ROOT, "hclk_pmu_cm0_root", hclk_pmu_cm0_root_p, RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(1), 10, 2, MFLAGS, + RK3588_PMU_CLKGATE_CON(0), 8, GFLAGS), + [PCLK_PMU1] = GATE(PCLK_PMU1, "pclk_pmu1", "pclk_pmu0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(1), 0, GFLAGS), + [CLK_DDR_FAIL_SAFE] = GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "clk_pmu0", RT_CLK_F_IGNORE_UNUSED, RK3588_PMU_CLKGATE_CON(1), 1, GFLAGS), + [CLK_PMU1] = GATE(CLK_PMU1, "clk_pmu1", "clk_pmu0", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(1), 3, GFLAGS), + [HCLK_PDM0] = GATE(HCLK_PDM0, "hclk_pdm0", "hclk_pmu1_root", 0, RK3588_PMU_CLKGATE_CON(2), 14, GFLAGS), + [MCLK_PDM0] = COMPOSITE_NODIV(MCLK_PDM0, "mclk_pdm0", mclk_pdm0_p, 0, + RK3588_PMU_CLKSEL_CON(9), 4, 1, MFLAGS, + RK3588_PMU_CLKGATE_CON(2), 15, GFLAGS), + [HCLK_VAD] = GATE(HCLK_VAD, "hclk_vad", "hclk_pmu1_root", 0, RK3588_PMU_CLKGATE_CON(3), 0, GFLAGS), + [FCLK_PMU_CM0_CORE] = GATE(FCLK_PMU_CM0_CORE, "fclk_pmu_cm0_core", "hclk_pmu_cm0_root", RT_CLK_F_IS_CRITICAL, RK3588_PMU_CLKGATE_CON(0), 13, GFLAGS), + [CLK_PMU_CM0_RTC] = COMPOSITE(CLK_PMU_CM0_RTC, "clk_pmu_cm0_rtc", mux_24m_32k_p, RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(2), 5, 1, MFLAGS, 0, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(0), 15, GFLAGS), + [PCLK_PMU1_IOC] = GATE(PCLK_PMU1_IOC, "pclk_pmu1_ioc", "pclk_pmu0_root", RT_CLK_F_IGNORE_UNUSED, RK3588_PMU_CLKGATE_CON(1), 5, GFLAGS), + [PCLK_PMU1PWM] = GATE(PCLK_PMU1PWM, "pclk_pmu1pwm", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(1), 12, GFLAGS), + [CLK_PMU1PWM] = COMPOSITE_NODIV(CLK_PMU1PWM, "clk_pmu1pwm", pmu_100m_50m_24m_src_p, 0, + RK3588_PMU_CLKSEL_CON(2), 9, 2, MFLAGS, + RK3588_PMU_CLKGATE_CON(1), 13, GFLAGS), + [CLK_PMU1PWM_CAPTURE] = GATE(CLK_PMU1PWM_CAPTURE, "clk_pmu1pwm_capture", "xin24m", 0, RK3588_PMU_CLKGATE_CON(1), 14, GFLAGS), + [PCLK_PMU1TIMER] = GATE(PCLK_PMU1TIMER, "pclk_pmu1timer", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(1), 8, GFLAGS), + [CLK_PMU1TIMER_ROOT] = COMPOSITE_NODIV(CLK_PMU1TIMER_ROOT, "clk_pmu1timer_root", pmu_24m_32k_100m_src_p, 0, + RK3588_PMU_CLKSEL_CON(2), 7, 2, MFLAGS, + RK3588_PMU_CLKGATE_CON(1), 9, GFLAGS), + [CLK_PMU1TIMER0] = GATE(CLK_PMU1TIMER0, "clk_pmu1timer0", "clk_pmu1timer_root", 0, RK3588_PMU_CLKGATE_CON(1), 10, GFLAGS), + [CLK_PMU1TIMER1] = GATE(CLK_PMU1TIMER1, "clk_pmu1timer1", "clk_pmu1timer_root", 0, RK3588_PMU_CLKGATE_CON(1), 11, GFLAGS), + [CLK_UART0_SRC] = COMPOSITE_NOMUX(CLK_UART0_SRC, "clk_uart0_src", "cpll", 0, + RK3588_PMU_CLKSEL_CON(3), 7, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(2), 3, GFLAGS), + [CLK_UART0_FRAC] = COMPOSITE_FRACMUX(CLK_UART0_FRAC, "clk_uart0_frac", "clk_uart0_src", RT_CLK_F_SET_RATE_PARENT, + RK3588_PMU_CLKSEL_CON(4), CLK_FRAC_DIVIDER_NO_LIMIT, + RK3588_PMU_CLKGATE_CON(2), 4, GFLAGS, + &rk3588_uart0_fracmux), + [CLK_UART0] = &rk3588_uart0_fracmux.cell, + [SCLK_UART0] = GATE(SCLK_UART0, "sclk_uart0", "clk_uart0", 0, RK3588_PMU_CLKGATE_CON(2), 5, GFLAGS), + [PCLK_UART0] = GATE(PCLK_UART0, "pclk_uart0", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(2), 6, GFLAGS), + [PCLK_PMU1WDT] = GATE(PCLK_PMU1WDT, "pclk_pmu1wdt", "pclk_pmu0_root", 0, RK3588_PMU_CLKGATE_CON(1), 6, GFLAGS), + [TCLK_PMU1WDT] = COMPOSITE_NODIV(TCLK_PMU1WDT, "tclk_pmu1wdt", mux_24m_32k_p, 0, + RK3588_PMU_CLKSEL_CON(2), 6, 1, MFLAGS, + RK3588_PMU_CLKGATE_CON(1), 7, GFLAGS), + [CLK_CR_PARA] = COMPOSITE(CLK_CR_PARA, "clk_cr_para", mux_24m_ppll_spll_p, 0, + RK3588_PMU_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(4), 11, GFLAGS), + [CLK_USB2PHY_HDPTXRXPHY_REF] = COMPOSITE(CLK_USB2PHY_HDPTXRXPHY_REF, "clk_usb2phy_hdptxrxphy_ref", mux_24m_ppll_p, + RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(14), 14, 1, MFLAGS, 9, 5, DFLAGS, + RK3588_PMU_CLKGATE_CON(4), 7, GFLAGS), + [CLK_USBDPPHY_MIPIDCPPHY_REF] = COMPOSITE(CLK_USBDPPHY_MIPIDCPPHY_REF, "clk_usbdpphy_mipidcpphy_ref", mux_24m_ppll_spll_p, + RT_CLK_F_IS_CRITICAL, + RK3588_PMU_CLKSEL_CON(14), 7, 2, MFLAGS, 0, 7, DFLAGS, + RK3588_PMU_CLKGATE_CON(4), 3, GFLAGS), + [CLK_REF_PIPE_PHY0_OSC_SRC] = GATE(CLK_REF_PIPE_PHY0_OSC_SRC, "clk_ref_pipe_phy0_osc_src", "xin24m", 0, RK3588_CLKGATE_CON(77), 0, GFLAGS), + [CLK_REF_PIPE_PHY1_OSC_SRC] = GATE(CLK_REF_PIPE_PHY1_OSC_SRC, "clk_ref_pipe_phy1_osc_src", "xin24m", 0, RK3588_CLKGATE_CON(77), 1, GFLAGS), + [CLK_REF_PIPE_PHY2_OSC_SRC] = GATE(CLK_REF_PIPE_PHY2_OSC_SRC, "clk_ref_pipe_phy2_osc_src", "xin24m", 0, RK3588_CLKGATE_CON(77), 2, GFLAGS), + [CLK_REF_PIPE_PHY0_PLL_SRC] = COMPOSITE_NOMUX(CLK_REF_PIPE_PHY0_PLL_SRC, "clk_ref_pipe_phy0_pll_src", "ppll", 0, + RK3588_CLKSEL_CON(176), 0, 6, DFLAGS, + RK3588_CLKGATE_CON(77), 3, GFLAGS), + [CLK_REF_PIPE_PHY1_PLL_SRC] = COMPOSITE_NOMUX(CLK_REF_PIPE_PHY1_PLL_SRC, "clk_ref_pipe_phy1_pll_src", "ppll", 0, + RK3588_CLKSEL_CON(176), 6, 6, DFLAGS, + RK3588_CLKGATE_CON(77), 4, GFLAGS), + [CLK_REF_PIPE_PHY2_PLL_SRC] = COMPOSITE_NOMUX(CLK_REF_PIPE_PHY2_PLL_SRC, "clk_ref_pipe_phy2_pll_src", "ppll", 0, + RK3588_CLKSEL_CON(177), 0, 6, DFLAGS, + RK3588_CLKGATE_CON(77), 5, GFLAGS), + [CLK_REF_PIPE_PHY0] = MUX(CLK_REF_PIPE_PHY0, "clk_ref_pipe_phy0", clk_ref_pipe_phy0_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(177), 6, 1, MFLAGS), + [CLK_REF_PIPE_PHY1] = MUX(CLK_REF_PIPE_PHY1, "clk_ref_pipe_phy1", clk_ref_pipe_phy1_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(177), 7, 1, MFLAGS), + [CLK_REF_PIPE_PHY2] = MUX(CLK_REF_PIPE_PHY2, "clk_ref_pipe_phy2", clk_ref_pipe_phy2_p, RT_CLK_F_SET_RATE_PARENT, + RK3588_CLKSEL_CON(177), 8, 1, MFLAGS), + [SCLK_SDIO_DRV] = MMC(SCLK_SDIO_DRV, "sdio_drv", "cclk_src_sdio", RK3588_SDIO_CON0, 1), + [SCLK_SDIO_SAMPLE] = MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "cclk_src_sdio", RK3588_SDIO_CON1, 1), + [SCLK_SDMMC_DRV] = MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "scmi_cclk_sd", RK3588_SDMMC_CON0, 1), + [SCLK_SDMMC_SAMPLE] = MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "scmi_cclk_sd", RK3588_SDMMC_CON1, 1), + [CLK_PCIE1L0_PIPE] = GATE(CLK_PCIE1L0_PIPE, "clk_pcie1l0_pipe", "clk_pipephy1_pipe_g", 0, RK3588_CLKGATE_CON(38), 14, GFLAGS), + [CLK_PCIE1L1_PIPE] = GATE(CLK_PCIE1L1_PIPE, "clk_pcie1l1_pipe", "clk_pipephy2_pipe_g", 0, RK3588_CLKGATE_CON(38), 15, GFLAGS), + [CLK_BIGCORE0_PVTM] = GATE(CLK_BIGCORE0_PVTM, "clk_bigcore0_pvtm", "xin24m", 0, RK3588_BIGCORE0_CLKGATE_CON(0), 12, GFLAGS), + [CLK_CORE_BIGCORE0_PVTM] = GATE(CLK_CORE_BIGCORE0_PVTM, "clk_core_bigcore0_pvtm", "armclk_b01", 0, RK3588_BIGCORE0_CLKGATE_CON(0), 13, GFLAGS), + [CLK_BIGCORE1_PVTM] = GATE(CLK_BIGCORE1_PVTM, "clk_bigcore1_pvtm", "xin24m", 0, RK3588_BIGCORE1_CLKGATE_CON(0), 12, GFLAGS), + [CLK_CORE_BIGCORE1_PVTM] = GATE(CLK_CORE_BIGCORE1_PVTM, "clk_core_bigcore1_pvtm", "armclk_b23", 0, RK3588_BIGCORE1_CLKGATE_CON(0), 13, GFLAGS), + [CLK_LITCORE_PVTM] = GATE(CLK_LITCORE_PVTM, "clk_litcore_pvtm", "xin24m", 0, RK3588_DSU_CLKGATE_CON(2), 0, GFLAGS), + [CLK_CORE_LITCORE_PVTM] = GATE(CLK_CORE_LITCORE_PVTM, "clk_core_litcore_pvtm", "armclk_l", 0, RK3588_DSU_CLKGATE_CON(2), 1, GFLAGS), + [CLK_AUX16M_0] = COMPOSITE_NOMUX(CLK_AUX16M_0, "clk_aux16m_0", "gpll", 0, + RK3588_CLKSEL_CON(117), 0, 8, DFLAGS, + RK3588_CLKGATE_CON(56), 2, GFLAGS), + [CLK_AUX16M_1] = COMPOSITE_NOMUX(CLK_AUX16M_1, "clk_aux16m_1", "gpll", 0, + RK3588_CLKSEL_CON(117), 8, 8, DFLAGS, + RK3588_CLKGATE_CON(56), 3, GFLAGS), + [CLK_PHY0_REF_ALT_P] = GATE(CLK_PHY0_REF_ALT_P, "clk_phy0_ref_alt_p", "ppll", 0, RK3588_PHYREF_ALT_GATE, 0, GFLAGS), + [CLK_PHY0_REF_ALT_M] = GATE(CLK_PHY0_REF_ALT_M, "clk_phy0_ref_alt_m", "ppll", 0, RK3588_PHYREF_ALT_GATE, 1, GFLAGS), + [CLK_PHY1_REF_ALT_P] = GATE(CLK_PHY1_REF_ALT_P, "clk_phy1_ref_alt_p", "ppll", 0, RK3588_PHYREF_ALT_GATE, 2, GFLAGS), + [CLK_PHY1_REF_ALT_M] = GATE(CLK_PHY1_REF_ALT_M, "clk_phy1_ref_alt_m", "ppll", 0, RK3588_PHYREF_ALT_GATE, 3, GFLAGS), + [PCLK_DDR_MON_CH0] = GATE(PCLK_DDR_MON_CH0, "pclk_ddr_mon_ch0", "pclk_center_root", 0, RK3588_CLKGATE_CON(20), 1, GFLAGS), + [PCLK_DDR_MON_CH1] = GATE(PCLK_DDR_MON_CH1, "pclk_ddr_mon_ch1", "pclk_center_root", 0, RK3588_CLKGATE_CON(20), 14, GFLAGS), + [PCLK_DDR_MON_CH2] = GATE(PCLK_DDR_MON_CH2, "pclk_ddr_mon_ch2", "pclk_center_root", 0, RK3588_CLKGATE_CON(23), 1, GFLAGS), + [PCLK_DDR_MON_CH3] = GATE(PCLK_DDR_MON_CH3, "pclk_ddr_mon_ch3", "pclk_center_root", 0, RK3588_CLKGATE_CON(23), 14, GFLAGS), + + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + COMPOSITE(0, "sclk_dsu", b0pll_b1pll_lpll_gpll_p, RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(0), 12, 2, MFLAGS, 0, 5, DFLAGS, + RK3588_DSU_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(0, "atclk_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(3), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(1), 0, GFLAGS), + COMPOSITE_NOMUX(0, "gicclk_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(3), 5, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(1), 1, GFLAGS), + COMPOSITE_NOMUX(0, "aclkmp_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(1), 11, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(0), 12, GFLAGS), + COMPOSITE_NOMUX(0, "aclkm_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(1), 1, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(0, "aclks_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(1), 6, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(0), 9, GFLAGS), + COMPOSITE_NOMUX(0, "periph_dsu", "sclk_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(2), 0, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(0), 13, GFLAGS), + COMPOSITE_NOMUX(0, "cntclk_dsu", "periph_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(2), 5, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(0), 14, GFLAGS), + COMPOSITE_NOMUX(0, "tsclk_dsu", "periph_dsu", RT_CLK_F_IS_CRITICAL, + RK3588_DSU_CLKSEL_CON(2), 10, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3588_DSU_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_NODIV(0, "hclk_rkvdec0_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(89), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(40), 0, GFLAGS), + COMPOSITE(0, "aclk_rkvdec0_root", gpll_cpll_aupll_spll_p, 0, + RK3588_CLKSEL_CON(89), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(40), 1, GFLAGS), + COMPOSITE_NODIV(0, "hclk_rkvdec1_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(93), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(41), 0, GFLAGS), + COMPOSITE(0, "aclk_rkvdec1_root", gpll_cpll_aupll_npll_p, 0, + RK3588_CLKSEL_CON(93), 7, 2, MFLAGS, 2, 5, DFLAGS, + RK3588_CLKGATE_CON(41), 1, GFLAGS), + COMPOSITE_NODIV(0, "hclk_sdio_root", mux_200m_100m_50m_24m_p, 0, + RK3588_CLKSEL_CON(172), 0, 2, MFLAGS, + RK3588_CLKGATE_CON(75), 0, GFLAGS), + GATE(0, "pclk_vo1grf", "pclk_vo1_root", RT_CLK_F_IGNORE_UNUSED, RK3588_CLKGATE_CON(59), 12, GFLAGS), +}; + +static rt_err_t clk_rk3588_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + struct clk_rk3588_cru *cru = rt_calloc(1, sizeof(*cru)); + + if (!cru) + { + return -RT_ENOMEM; + } + + cru->provider.reg_base = rt_dm_dev_iomap(dev, 0); + + if (!cru->provider.reg_base) + { + err = -RT_EIO; + goto _fail; + } + + cru->provider.grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,grf"); + cru->provider.pmugrf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pmugrf"); + + cru->clk_parent.dev = dev; + cru->clk_parent.cells = rk3588_clk_cells; + cru->clk_parent.cells_nr = RT_ARRAY_SIZE(rk3588_clk_cells); + + rockchip_clk_init(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rt_clk_register(&cru->clk_parent))) + { + goto _fail; + } + + rockchip_clk_setup(&cru->provider, cru->clk_parent.cells, cru->clk_parent.cells_nr); + + if ((err = rockchip_register_softrst(&cru->rstc_parent, dev->ofw_node, RT_NULL, + cru->provider.reg_base + RK3588_SOFTRST_CON(0), ROCKCHIP_SOFTRST_HIWORD_MASK))) + { + goto _clk_unregister; + } + + rockchip_register_restart_notifier(&cru->provider, RK3588_GLB_SRST_FST, RT_NULL); + + return RT_EOK; + +_clk_unregister: + rt_clk_unregister(&cru->clk_parent); + +_fail: + if (cru->provider.reg_base) + { + rt_iounmap(cru->provider.reg_base); + } + + rt_free(cru); + + return err; +} + +static const struct rt_ofw_node_id clk_rk3588_ofw_ids[] = +{ + { .compatible = "rockchip,rk3588-cru", }, + { /* sentinel */ } +}; + +static struct rt_platform_driver clk_rk3588_driver = +{ + .name = "clk-rk3588", + .ids = clk_rk3588_ofw_ids, + + .probe = clk_rk3588_probe, +}; + +static int clk_rk3588_register(void) +{ + rt_platform_driver_register(&clk_rk3588_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(clk_rk3588_register); diff --git a/bsp/rockchip/dm/clk/clk-rk8xx-clkout.c b/bsp/rockchip/dm/clk/clk-rk8xx-clkout.c new file mode 100755 index 00000000000..db667dcf973 --- /dev/null +++ b/bsp/rockchip/dm/clk/clk-rk8xx-clkout.c @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include +#include + +#define DBG_TAG "clk.rk8xx" +#define DBG_LVL DBG_INFO +#include + +#include "rk8xx.h" + +struct rk8xx_clkout +{ + struct rt_clk_node parent; + + struct rk8xx *rk8xx; +}; + +#define raw_to_rk8xx_clkout(raw) rt_container_of(raw, struct rk8xx_clkout, parent) + +static rt_ubase_t rk808_clkout_recalc_rate(struct rt_clk_cell *cell, rt_ubase_t parent_rate) +{ + return 32768; +} + +static const struct rt_clk_ops rk808_clkout1_ops = +{ + .recalc_rate = rk808_clkout_recalc_rate, +}; + +static rt_err_t rk808_clkout2_enable(struct rt_clk_cell *cell, rt_bool_t enable) +{ + struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np); + + return rk8xx_update_bits(clkout->rk8xx, RK808_CLK32OUT_REG, + CLK32KOUT2_EN, enable ? CLK32KOUT2_EN : 0); +} + +static rt_err_t rk808_clkout2_prepare(struct rt_clk_cell *cell) +{ + return rk808_clkout2_enable(cell, RT_TRUE); +} + +static void rk808_clkout2_unprepare(struct rt_clk_cell *cell) +{ + rk808_clkout2_enable(cell, RT_FALSE); +} + +static rt_bool_t rk808_clkout2_is_prepared(struct rt_clk_cell *cell) +{ + rt_uint32_t val; + struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np); + + val = rk8xx_read(clkout->rk8xx, RK808_CLK32OUT_REG); + + if ((rt_err_t)val < 0) + { + return RT_FALSE; + } + + return !!(val & CLK32KOUT2_EN); +} + +static const struct rt_clk_ops rk808_clkout2_ops = +{ + .prepare = rk808_clkout2_prepare, + .unprepare = rk808_clkout2_unprepare, + .is_prepared = rk808_clkout2_is_prepared, + .recalc_rate = rk808_clkout_recalc_rate, +}; + +static rt_err_t rk817_clkout2_enable(struct rt_clk_cell *cell, rt_bool_t enable) +{ + struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np); + + return rk8xx_update_bits(clkout->rk8xx, RK817_SYS_CFG(1), + RK817_CLK32KOUT2_EN, enable ? RK817_CLK32KOUT2_EN : 0); +} + +static rt_err_t rk817_clkout2_prepare(struct rt_clk_cell *cell) +{ + return rk817_clkout2_enable(cell, RT_TRUE); +} + +static void rk817_clkout2_unprepare(struct rt_clk_cell *cell) +{ + rk817_clkout2_enable(cell, RT_FALSE); +} + +static rt_bool_t rk817_clkout2_is_prepared(struct rt_clk_cell *cell) +{ + rt_uint32_t val; + struct rk8xx_clkout *clkout = raw_to_rk8xx_clkout(cell->clk_np); + + val = rk8xx_read(clkout->rk8xx, RK817_SYS_CFG(1)); + + if ((rt_err_t)val < 0) + { + return RT_FALSE; + } + + return !!(val & RK817_CLK32KOUT2_EN); +} + +static const struct rt_clk_ops rk817_clkout2_ops = +{ + .prepare = rk817_clkout2_prepare, + .unprepare = rk817_clkout2_unprepare, + .is_prepared = rk817_clkout2_is_prepared, + .recalc_rate = rk808_clkout_recalc_rate, +}; + +static struct rt_clk_cell *rk8xx_clkout_cell[] = +{ + &(struct rt_clk_cell) { .name = "rk808-clkout1" }, + &(struct rt_clk_cell) { .name = "rk808-clkout2" }, +}; + +static rt_err_t rk8xx_clkout_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_clk_cell *cell; + struct rt_device *dev = &pdev->parent; + struct rk8xx *rk8xx = pdev->priv; + struct rk8xx_clkout *clkout = rt_calloc(1, sizeof(*clkout)); + + if (!clkout) + { + return -RT_ENOMEM; + } + + clkout->rk8xx = rk8xx; + + /* clkout1 */ + cell = rk8xx_clkout_cell[0]; + cell->ops = &rk808_clkout1_ops; + rt_dm_dev_prop_read_string_index(dev, "clock-output-names", 0, &cell->name); + + /* clkout2 */ + cell = rk8xx_clkout_cell[1]; + switch (rk8xx->variant) + { + case RK809_ID: + case RK817_ID: + cell->ops = &rk817_clkout2_ops; + break; + + /* + * For the default case, it match the following PMIC type. + * RK805_ID + * RK808_ID + * RK818_ID + */ + default: + cell->ops = &rk808_clkout2_ops; + break; + } + rt_dm_dev_prop_read_string_index(dev, "clock-output-names", 1, &cell->name); + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,clk-32k-always-on")) + { + cell->flags |= RT_CLK_F_IS_CRITICAL; + } + + clkout->parent.dev = dev; + clkout->parent.cells = rk8xx_clkout_cell; + clkout->parent.cells_nr = RT_ARRAY_SIZE(rk8xx_clkout_cell); + + if ((err = rt_clk_register(&clkout->parent))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rt_free(clkout); + + return err; +} + +static struct rt_platform_driver rk8xx_clkout_driver = +{ + .name = "rk8xx-clkout", + .probe = rk8xx_clkout_probe, +}; + +static int rk8xx_clkout_register(void) +{ + rt_platform_driver_register(&rk8xx_clkout_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(rk8xx_clkout_register); diff --git a/bsp/rockchip/rk3500/driver/clk/softrst.c b/bsp/rockchip/dm/clk/softrst.c old mode 100644 new mode 100755 similarity index 69% rename from bsp/rockchip/rk3500/driver/clk/softrst.c rename to bsp/rockchip/dm/clk/softrst.c index fc8c2853b27..e5cf4a1bb99 --- a/bsp/rockchip/rk3500/driver/clk/softrst.c +++ b/bsp/rockchip/dm/clk/softrst.c @@ -1,15 +1,19 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes - * 2022-11-26 GuEe-GUI first version + * 2022-3-08 GuEe-GUI the first version */ +#include "clk-rk.h" + struct rockchip_softrst { + const int *lut; + void *regs; int num_per_reg; rt_uint8_t flags; @@ -19,11 +23,16 @@ struct rockchip_softrst static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc) { - int bank, offset; + int id = rstc->id, bank, offset; struct rockchip_softrst *softrst = rstc->rstcer->priv; - bank = rstc->id / softrst->num_per_reg; - offset = rstc->id % softrst->num_per_reg; + if (softrst->lut) + { + id = softrst->lut[id]; + } + + bank = id / softrst->num_per_reg; + offset = id % softrst->num_per_reg; if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) { @@ -47,15 +56,20 @@ static rt_err_t rockchip_softrst_assert(struct rt_reset_control *rstc) static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc) { - int bank, offset; + int id = rstc->id, bank, offset; struct rockchip_softrst *softrst = rstc->rstcer->priv; - bank = rstc->id / softrst->num_per_reg; - offset = rstc->id % softrst->num_per_reg; + if (softrst->lut) + { + id = softrst->lut[id]; + } + + bank = id / softrst->num_per_reg; + offset = id % softrst->num_per_reg; if (softrst->flags & ROCKCHIP_SOFTRST_HIWORD_MASK) { - HWREG32(softrst->regs + (bank * 4)) = (RT_BIT(offset) << 16); + HWREG32(softrst->regs + (bank * 4)) = RT_BIT(offset) << 16; } else { @@ -75,12 +89,12 @@ static rt_err_t rockchip_softrst_deassert(struct rt_reset_control *rstc) static const struct rt_reset_control_ops rockchip_softrst_ops = { - .assert = rockchip_softrst_assert, - .deassert = rockchip_softrst_deassert, + .assert = rockchip_softrst_assert, + .deassert = rockchip_softrst_deassert, }; -static rt_err_t rk_register_softrst(struct rt_reset_controller *rstcer, - struct rt_ofw_node *np, void *regs, rt_uint8_t flags) +rt_err_t rockchip_register_softrst(struct rt_reset_controller *rstcer, + struct rt_ofw_node *np, const int *lookup_table, void *regs, rt_uint8_t flags) { rt_err_t err; struct rockchip_softrst *softrst = rt_calloc(1, sizeof(*softrst)); @@ -90,16 +104,15 @@ static rt_err_t rk_register_softrst(struct rt_reset_controller *rstcer, return -RT_ENOMEM; } - rstcer->priv = softrst; - - rt_spin_lock_init(&softrst->lock); - + softrst->lut = lookup_table; softrst->regs = regs; softrst->flags = flags; softrst->num_per_reg = (flags & ROCKCHIP_SOFTRST_HIWORD_MASK) ? 16 : 32; - rstcer->ofw_node = np; + rt_spin_lock_init(&softrst->lock); + rstcer->priv = softrst; rstcer->ops = &rockchip_softrst_ops; + rstcer->ofw_node = np; if ((err = rt_reset_controller_register(rstcer))) { diff --git a/bsp/rockchip/dm/hwcrypto/Kconfig b/bsp/rockchip/dm/hwcrypto/Kconfig new file mode 100755 index 00000000000..ec89f7a0b97 --- /dev/null +++ b/bsp/rockchip/dm/hwcrypto/Kconfig @@ -0,0 +1,5 @@ +config RT_HWCRYPTO_RNG_ROCKCHIP + bool "Rockchip Random Number Generator support" + depends on RT_HWCRYPTO_USING_RNG + depends on RT_USING_RESET + default n diff --git a/bsp/rockchip/rk3500/driver/uart8250/SConscript b/bsp/rockchip/dm/hwcrypto/SConscript similarity index 51% rename from bsp/rockchip/rk3500/driver/uart8250/SConscript rename to bsp/rockchip/dm/hwcrypto/SConscript index 7f7b94a1474..eabfe3e7f1c 100755 --- a/bsp/rockchip/rk3500/driver/uart8250/SConscript +++ b/bsp/rockchip/dm/hwcrypto/SConscript @@ -1,13 +1,12 @@ from building import * cwd = GetCurrentDir() -CPPPATH = [cwd] +src = [] +CPPPATH = [cwd + '/../include'] -src = ['core.c', 'early.c'] - -if GetDepend(['RT_SERIAL_8250']): - src += ['8250-dw.c'] - src += ['fiq-debugger.c'] +if GetDepend(['RT_HWCRYPTO_RNG_ROCKCHIP']): + src += ['hw-rng-rockchip.c'] group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + Return('group') diff --git a/bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c b/bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c new file mode 100755 index 00000000000..80c2b5dd8a5 --- /dev/null +++ b/bsp/rockchip/dm/hwcrypto/hw-rng-rockchip.c @@ -0,0 +1,565 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +#define DBG_TAG "rng.rockchip" +#define DBG_LVL DBG_INFO +#include + +#include "rockchip.h" + +#define ROCKCHIP_AUTOSUSPEND_DELAY 100 +#define ROCKCHIP_POLL_PERIOD_US 100 +#define ROCKCHIP_POLL_TIMEOUT_US 50000 +#define RK_MAX_RNG_BYTE (32) + +/* start of CRYPTO V1 register define */ +#define CRYPTO_V1_CTRL 0x0008 +#define CRYPTO_V1_RNG_START RT_BIT(8) +#define CRYPTO_V1_RNG_FLUSH RT_BIT(9) + +#define CRYPTO_V1_TRNG_CTRL 0x0200 +#define CRYPTO_V1_OSC_ENABLE RT_BIT(16) +#define CRYPTO_V1_TRNG_SAMPLE_PERIOD(x) (x) + +#define CRYPTO_V1_TRNG_DOUT_0 0x0204 +/* end of CRYPTO V1 register define */ + +/* start of CRYPTO V2 register define */ +#define CRYPTO_V2_RNG_DEFAULT_OFFSET 0x0400 +#define CRYPTO_V2_RNG_CTL 0x0 +#define CRYPTO_V2_RNG_64_BIT_LEN ((0x00) << (4)) +#define CRYPTO_V2_RNG_128_BIT_LEN ((0x01) << (4)) +#define CRYPTO_V2_RNG_192_BIT_LEN ((0x02) << (4)) +#define CRYPTO_V2_RNG_256_BIT_LEN ((0x03) << (4)) +#define CRYPTO_V2_RNG_FATESY_SOC_RING ((0x00) << (2)) +#define CRYPTO_V2_RNG_SLOWER_SOC_RING_0 ((0x01) << (2)) +#define CRYPTO_V2_RNG_SLOWER_SOC_RING_1 ((0x02) << (2)) +#define CRYPTO_V2_RNG_SLOWEST_SOC_RING ((0x03) << (2)) +#define CRYPTO_V2_RNG_ENABLE RT_BIT(1) +#define CRYPTO_V2_RNG_START RT_BIT(0) +#define CRYPTO_V2_RNG_SAMPLE_CNT 0x0004 +#define CRYPTO_V2_RNG_DOUT_0 0x0010 +/* end of CRYPTO V2 register define */ + +/* start of TRNG_V1 register define */ +/* TRNG is no longer subordinate to the Crypto module */ +#define TRNG_V1_CTRL 0x0000 +#define TRNG_V1_CTRL_NOP ((0x00) << (0)) +#define TRNG_V1_CTRL_RAND ((0x01) << (0)) +#define TRNG_V1_CTRL_SEED ((0x02) << (0)) + +#define TRNG_V1_STAT 0x0004 +#define TRNG_V1_STAT_SEEDED RT_BIT(9) +#define TRNG_V1_STAT_GENERATING RT_BIT(30) +#define TRNG_V1_STAT_RESEEDING RT_BIT(31) + +#define TRNG_V1_MODE 0x0008 +#define TRNG_V1_MODE_128_BIT ((0x00) << (3)) +#define TRNG_V1_MODE_256_BIT ((0x01) << (3)) + +#define TRNG_V1_IE 0x0010 +#define TRNG_V1_IE_GLBL_EN RT_BIT(31) +#define TRNG_V1_IE_SEED_DONE_EN RT_BIT(1) +#define TRNG_V1_IE_RAND_RDY_EN RT_BIT(0) + +#define TRNG_V1_ISTAT 0x0014 +#define TRNG_V1_ISTAT_RAND_RDY RT_BIT(0) + +/* RAND0 ~ RAND7 */ +#define TRNG_V1_RAND0 0x0020 +#define TRNG_V1_RAND7 0x003C + +#define TRNG_V1_AUTO_RQSTS 0x0060 + +#define TRNG_V1_VERSION 0x00F0 +#define TRNG_v1_VERSION_CODE 0x46bc +/* end of TRNG_V1 register define */ + +struct rockchip_rng; + +struct rockchip_rng_soc_data +{ + rt_uint32_t default_offset; + + rt_err_t (*init)(struct rockchip_rng *rk_rng); + rt_uint32_t (*read)(struct rockchip_rng *rk_rng, void *buf, rt_size_t max, rt_bool_t wait); +}; + +struct rockchip_rng +{ + struct rt_hwcrypto_device parent; + + void *regs; + + struct rt_clk_array *clk_arr; + struct rt_reset_control *rstc; + + const struct rockchip_rng_soc_data *soc_data; +}; + +#define raw_to_rockchip_rng(raw) rt_container_of(raw, struct rockchip_rng, parent) + +static void rockchip_rng_writel(struct rockchip_rng *rk_rng, rt_uint32_t val, int offset) +{ + HWREG32(rk_rng->regs + offset) = val; +} + +static rt_uint32_t rockchip_rng_readl(struct rockchip_rng *rk_rng, int offset) +{ + return HWREG32(rk_rng->regs + offset); +} + +static void rockchip_rng_read_regs(struct rockchip_rng *rk_rng, rt_uint32_t offset, + void *buf, rt_size_t size) +{ + rt_uint32_t *data = buf; + + for (int i = 0; i < size; i += 4, ++offset) + { + data[i] = rt_be32_to_cpu(rockchip_rng_readl(rk_rng, offset)); + } +} + +static rt_uint32_t rockchip_crypto_v1_read(struct rockchip_rng *rk_rng, void *buf, + rt_size_t max, rt_bool_t wait) +{ + rt_tick_t start; + rt_uint32_t res = 0, reg_ctrl = 0; + int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000); + + /* enable osc_ring to get entropy, sample period is set as 100 */ + reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100); + rockchip_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL); + + reg_ctrl = HIWORD_UPDATE(CRYPTO_V1_RNG_START, CRYPTO_V1_RNG_START, 0); + + rockchip_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL); + + start = rt_tick_get(); + + while (rockchip_rng_readl(rk_rng, CRYPTO_V1_CTRL) & CRYPTO_V1_RNG_START) + { + rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US); + + if ((rt_tick_get() - start) > timeout) + { + goto _time_out; + } + + rt_hw_cpu_relax(); + } + + res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE); + + rockchip_rng_read_regs(rk_rng, CRYPTO_V1_TRNG_DOUT_0, buf, res); + +_time_out: + /* close TRNG */ + rockchip_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0), CRYPTO_V1_CTRL); + + return res; +} + +static rt_uint32_t rockchip_crypto_v2_read(struct rockchip_rng *rk_rng, void *buf, + rt_size_t max, rt_bool_t wait) +{ + rt_tick_t start; + rt_uint32_t res = 0, reg_ctrl = 0; + int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000); + + /* enable osc_ring to get entropy, sample period is set as 100 */ + rockchip_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT); + + reg_ctrl |= CRYPTO_V2_RNG_256_BIT_LEN; + reg_ctrl |= CRYPTO_V2_RNG_SLOWER_SOC_RING_0; + reg_ctrl |= CRYPTO_V2_RNG_ENABLE; + reg_ctrl |= CRYPTO_V2_RNG_START; + + rockchip_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), CRYPTO_V2_RNG_CTL); + + start = rt_tick_get(); + + while (rockchip_rng_readl(rk_rng, CRYPTO_V2_RNG_CTL) & CRYPTO_V2_RNG_START) + { + rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US); + + if ((rt_tick_get() - start) > timeout) + { + goto _time_out; + } + + rt_hw_cpu_relax(); + } + + res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE); + + rockchip_rng_read_regs(rk_rng, CRYPTO_V2_RNG_DOUT_0, buf, res); + +_time_out: + /* close TRNG */ + rockchip_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL); + + return res; +} + +static rt_err_t rockchip_trng_v1_init(struct rockchip_rng *rk_rng) +{ + rt_uint32_t auto_reseed_cnt = 1000; + rt_uint32_t reg_ctrl, status, version; + + version = rockchip_rng_readl(rk_rng, TRNG_V1_VERSION); + + if (version != TRNG_v1_VERSION_CODE) + { + LOG_E("Wrong trng version, expected = %08x, actual = %08x", + TRNG_V1_VERSION, version); + + return -RT_EIO; + } + + status = rockchip_rng_readl(rk_rng, TRNG_V1_STAT); + + /* TRNG should wait RAND_RDY triggered if it is busy or not seeded */ + if (!(status & TRNG_V1_STAT_SEEDED) || (status & TRNG_V1_STAT_GENERATING) || + (status & TRNG_V1_STAT_RESEEDING)) + { + rt_tick_t start; + rt_uint32_t mask = TRNG_V1_STAT_SEEDED | TRNG_V1_STAT_GENERATING | + TRNG_V1_STAT_RESEEDING; + int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000); + + rt_hw_us_delay(10); + + /* wait for GENERATING and RESEEDING flag to clear */ + start = rt_tick_get(); + + while ((rockchip_rng_readl(rk_rng, TRNG_V1_STAT) & mask) != TRNG_V1_STAT_SEEDED) + { + rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US); + + if ((rt_tick_get() - start) > timeout) + { + break; + } + + rt_hw_cpu_relax(); + } + } + + /* clear ISTAT flag because trng may auto reseeding when power on */ + reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT); + rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT); + + /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */ + rockchip_rng_writel(rk_rng, auto_reseed_cnt, TRNG_V1_AUTO_RQSTS); + + return RT_EOK; +} + +static rt_uint32_t rockchip_trng_v1_read(struct rockchip_rng *rk_rng, void *buf, + rt_size_t max, rt_bool_t wait) +{ + rt_uint32_t res = 0, reg_ctrl = 0; + + /* clear ISTAT anyway */ + reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT); + rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT); + + /* generate 256bit random */ + rockchip_rng_writel(rk_rng, TRNG_V1_MODE_256_BIT, TRNG_V1_MODE); + rockchip_rng_writel(rk_rng, TRNG_V1_CTRL_RAND, TRNG_V1_CTRL); + + /* + * Generate2 56 bit random data will cost 1024 clock cycles. + * Estimated at 150M RNG module frequency, it takes 6.7 microseconds. + */ + rt_hw_us_delay(10); + reg_ctrl = rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT); + + if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) + { + rt_tick_t start = rt_tick_get(); + int timeout = rt_tick_from_millisecond(ROCKCHIP_POLL_TIMEOUT_US / 1000); + + /* wait RAND_RDY triggered */ + while (!(rockchip_rng_readl(rk_rng, TRNG_V1_ISTAT) & TRNG_V1_ISTAT_RAND_RDY)) + { + rt_hw_us_delay(ROCKCHIP_POLL_PERIOD_US); + + if ((rt_tick_get() - start) > timeout) + { + goto _time_out; + } + + rt_hw_cpu_relax(); + } + } + + res = rt_min_t(rt_size_t, max, RK_MAX_RNG_BYTE); + + rockchip_rng_read_regs(rk_rng, TRNG_V1_RAND0, buf, res); + + /* clear all status flag */ + rockchip_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT); +_time_out: + /* close TRNG */ + rockchip_rng_writel(rk_rng, TRNG_V1_CTRL_NOP, TRNG_V1_CTRL); + + return res; +} + +static rt_uint32_t rockchip_rng_read(struct rockchip_rng *rk_rng, void *buf, + rt_size_t max, rt_bool_t wait) +{ + rt_uint32_t res; + int read_len = 0; + + if (!rk_rng->soc_data->read) + { + return 0; + } + + res = 0; + + while (max > res) + { + read_len = rk_rng->soc_data->read(rk_rng, buf + res, max - res, wait); + + if (read_len < 0) + { + res = read_len; + + break; + } + res += read_len; + } + + return res; +} + +static rt_uint32_t rockchip_rng_rand(struct hwcrypto_rng *ctx) +{ + rt_uint32_t rand; + struct rockchip_rng *rk_rng = raw_to_rockchip_rng(ctx->parent.device); + + if (rockchip_rng_read(rk_rng, &rand, sizeof(rand), RT_TRUE) != sizeof(rand)) + { + return 0; + } + + return rand; +} + +static const struct hwcrypto_rng_ops rng_ops = +{ + .update = rockchip_rng_rand, +}; + +static rt_err_t rockchip_rng_create(struct rt_hwcrypto_ctx *ctx) +{ + rt_err_t res = RT_EOK; + struct hwcrypto_rng *rng; + + switch (ctx->type & HWCRYPTO_MAIN_TYPE_MASK) + { + case HWCRYPTO_TYPE_RNG: + ctx->contex = RT_NULL; + + rng = rt_container_of(ctx, struct hwcrypto_rng, parent); + rng->ops = &rng_ops; + break; + + default: + res = -RT_ENOSYS; + break; + } + + return res; +} + +static void rockchip_rng_destroy(struct rt_hwcrypto_ctx *ctx) +{ + rt_free(ctx->contex); +} + +static rt_err_t rockchip_rng_copy(struct rt_hwcrypto_ctx *des, const struct rt_hwcrypto_ctx *src) +{ + rt_err_t err = RT_EOK; + + switch (src->type & HWCRYPTO_MAIN_TYPE_MASK) + { + case HWCRYPTO_TYPE_RNG: + break; + default: + err = -RT_ENOSYS; + break; + } + + return err; +} + +static void rockchip_rng_reset(struct rt_hwcrypto_ctx *ctx) +{ +} + +static const struct rt_hwcrypto_ops rockchip_rng_ops = +{ + .create = rockchip_rng_create, + .destroy = rockchip_rng_destroy, + .copy = rockchip_rng_copy, + .reset = rockchip_rng_reset, +}; + +static void rockchip_rng_free(struct rockchip_rng *rk_rng) +{ + if (!rk_rng->regs) + { + rt_iounmap(rk_rng->regs); + } + + if (!rt_is_err_or_null(rk_rng->rstc)) + { + rt_reset_control_assert(rk_rng->rstc); + rt_reset_control_put(rk_rng->rstc); + } + + if (!rt_is_err_or_null(rk_rng->clk_arr)) + { + rt_clk_array_disable_unprepare(rk_rng->clk_arr); + rt_clk_array_put(rk_rng->clk_arr); + } + + rt_free(rk_rng); +} + +static rt_err_t rockchip_rng_probe(struct rt_platform_device *pdev) +{ + rt_err_t err = RT_EOK; + struct rt_device *dev = &pdev->parent; + struct rockchip_rng *rk_rng = rt_calloc(1, sizeof(*rk_rng)); + + if (!rk_rng) + { + return -RT_ENOMEM; + } + + rk_rng->soc_data = pdev->id->data; + + rk_rng->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_rng->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_rng->rstc = rt_reset_control_get_by_name(dev, "reset"); + + if (rt_is_err(rk_rng->rstc)) + { + err = rt_ptr_err(rk_rng->rstc); + goto _fail; + } + + if (rk_rng->rstc) + { + rt_reset_control_assert(rk_rng->rstc); + rt_hw_us_delay(10); + rt_reset_control_deassert(rk_rng->rstc); + } + + rk_rng->clk_arr = rt_clk_get_array(dev); + + if (rt_is_err(rk_rng->clk_arr)) + { + err = rt_ptr_err(rk_rng->clk_arr); + goto _fail; + } + + rt_clk_array_prepare_enable(rk_rng->clk_arr); + + if (rk_rng->soc_data->init) + { + err = rk_rng->soc_data->init(rk_rng); + } + + if (err) + { + goto _fail; + } + + dev->user_data = rk_rng; + + rk_rng->parent.ops = &rockchip_rng_ops; + + if ((err = rt_hwcrypto_register(&rk_rng->parent, "hwrng"))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rockchip_rng_free(rk_rng); + + return err; +} + +static rt_err_t rockchip_rng_remove(struct rt_platform_device *pdev) +{ + struct rockchip_rng *rk_rng = pdev->parent.user_data; + + rt_device_unregister(&rk_rng->parent.parent); + + rockchip_rng_free(rk_rng); + + return RT_EOK; +} + +static const struct rockchip_rng_soc_data rk_crypto_v1_soc_data = +{ + .default_offset = 0, + .read = rockchip_crypto_v1_read, +}; + +static const struct rockchip_rng_soc_data rk_crypto_v2_soc_data = +{ + .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET, + .read = rockchip_crypto_v2_read, +}; + +static const struct rockchip_rng_soc_data rk_trng_v1_soc_data = +{ + .default_offset = 0, + .init = rockchip_trng_v1_init, + .read = rockchip_trng_v1_read, +}; + +static const struct rt_ofw_node_id rockchip_rng_ofw_ids[] = +{ + { .compatible = "rockchip,cryptov1-rng", .data = &rk_crypto_v1_soc_data, }, + { .compatible = "rockchip,cryptov2-rng", .data = &rk_crypto_v2_soc_data, }, + { .compatible = "rockchip,trngv1", .data = &rk_trng_v1_soc_data, }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_rng_driver = +{ + .name = "rockchip-rng", + .ids = rockchip_rng_ofw_ids, + + .probe = rockchip_rng_probe, + .remove = rockchip_rng_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_rng_driver); diff --git a/bsp/rockchip/dm/hwspinlock/Kconfig b/bsp/rockchip/dm/hwspinlock/Kconfig new file mode 100755 index 00000000000..c2c470bf5e8 --- /dev/null +++ b/bsp/rockchip/dm/hwspinlock/Kconfig @@ -0,0 +1,3 @@ +config RT_HWSPINLOCK_ROCKCHIP + bool "Rockchip Hardware Spinlock device" + default n diff --git a/bsp/rockchip/dm/hwspinlock/SConscript b/bsp/rockchip/dm/hwspinlock/SConscript new file mode 100755 index 00000000000..74b9bcb3e4f --- /dev/null +++ b/bsp/rockchip/dm/hwspinlock/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/hwspinlock'] + +if GetDepend(['RT_HWSPINLOCK_ROCKCHIP']): + src += ['hwspinlock-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/hwspinlock/hwspinlock-rockchip.c b/bsp/rockchip/dm/hwspinlock/hwspinlock-rockchip.c new file mode 100755 index 00000000000..505638b4b20 --- /dev/null +++ b/bsp/rockchip/dm/hwspinlock/hwspinlock-rockchip.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#include "hwspinlock_dm.h" + +#define HWSPINLOCK_NUMBER 64 +#define HWSPINLOCK_STATUS_OFFSET(x) (0x4 * (x)) +#define HWSPINLOCK_OWNER_ID 0x1 + +struct rockchip_hwspinlock +{ + struct rt_hwspinlock_bank parent; + + void *regs; +}; + +static rt_err_t rockchip_hwspinlock_trylock(struct rt_hwspinlock *hwlock) +{ + void *lock_regs = hwlock->priv; + + HWREG32(lock_regs) = HWSPINLOCK_OWNER_ID; + + /* + * Get only first 4bits and compare to HWSPINLOCK_OWNER_ID: + * when 4bits is 0, 4bits can be written with new value. + * when 4bits is not 0, 4bits cannot be written. + * when write data is 0x0000, 4bits clean to 0. + */ + + return ((HWREG32(lock_regs) & 0xf) == HWSPINLOCK_OWNER_ID); +} + +static void rockchip_hwspinlock_unlock(struct rt_hwspinlock *hwlock) +{ + void *lock_regs = hwlock->priv; + + HWREG32(lock_regs) = 0; +} + +static const struct rt_hwspinlock_ops rk_hwspinlock_ops = +{ + .trylock = rockchip_hwspinlock_trylock, + .unlock = rockchip_hwspinlock_unlock, +}; + +static rt_err_t rockchip_hwspinlock_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_hwspinlock *hwlock; + struct rt_hwspinlock_bank *bank; + struct rt_device *dev = &pdev->parent; + struct rockchip_hwspinlock *rk_hwspinlock; + + rk_hwspinlock = hwspinlock_bank_alloc(rk_hwspinlock, HWSPINLOCK_NUMBER); + + if (!rk_hwspinlock) + { + return -RT_ENOMEM; + } + + rk_hwspinlock->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_hwspinlock->regs) + { + err = -RT_EIO; + + goto _fail; + } + + bank = &rk_hwspinlock->parent; + hwlock = &bank->locks[0]; + + for (int i = 0; i < HWSPINLOCK_NUMBER; ++i, ++hwlock) + { + hwlock->priv = rk_hwspinlock->regs + HWSPINLOCK_STATUS_OFFSET(i); + } + + bank->dev = dev; + bank->ops = &rk_hwspinlock_ops; + bank->locks_nr = HWSPINLOCK_NUMBER; + + if ((err = rt_hwspinlock_bank_register(bank))) + { + goto _fail; + } + + dev->user_data = rk_hwspinlock; + + return RT_EOK; + +_fail: + if (rk_hwspinlock->regs) + { + rt_iounmap(rk_hwspinlock->regs); + } + rt_free(rk_hwspinlock); + + return err; +} + +static rt_err_t rockchip_hwspinlock_remove(struct rt_platform_device *pdev) +{ + struct rockchip_hwspinlock *rk_hwspinlock = pdev->parent.user_data; + + rt_hwspinlock_bank_unregister(&rk_hwspinlock->parent); + + rt_iounmap(rk_hwspinlock->regs); + + rt_free(rk_hwspinlock); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_hwspinlock_ofw_ids[] = +{ + { .compatible = "rockchip,hwspinlock" }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_hwspinlock_driver = +{ + .name = "hwspinlock-rockchip", + .ids = rockchip_hwspinlock_ofw_ids, + + .probe = rockchip_hwspinlock_probe, + .remove = rockchip_hwspinlock_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_hwspinlock_driver); diff --git a/bsp/rockchip/rk3500/driver/hwtimer/Kconfig b/bsp/rockchip/dm/hwtimer/Kconfig similarity index 53% rename from bsp/rockchip/rk3500/driver/hwtimer/Kconfig rename to bsp/rockchip/dm/hwtimer/Kconfig index 3dfe6bf159b..ee60464d691 100755 --- a/bsp/rockchip/rk3500/driver/hwtimer/Kconfig +++ b/bsp/rockchip/dm/hwtimer/Kconfig @@ -1,5 +1,3 @@ config RT_HWTIMER_ROCKCHIP bool "RockChip Timer" - depends on RT_USING_DM - depends on RT_USING_HWTIMER default n diff --git a/bsp/rockchip/rk3500/driver/hwtimer/SConscript b/bsp/rockchip/dm/hwtimer/SConscript old mode 100644 new mode 100755 similarity index 73% rename from bsp/rockchip/rk3500/driver/hwtimer/SConscript rename to bsp/rockchip/dm/hwtimer/SConscript index 90934983d56..999034bf7f5 --- a/bsp/rockchip/rk3500/driver/hwtimer/SConscript +++ b/bsp/rockchip/dm/hwtimer/SConscript @@ -1,9 +1,8 @@ from building import * -cwd = GetCurrentDir() -CPPPATH = [cwd] - -src = [] +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] if GetDepend(['RT_HWTIMER_ROCKCHIP']): src += ['hwtimer-rockchip_timer.c'] diff --git a/bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c b/bsp/rockchip/dm/hwtimer/hwtimer-rockchip_timer.c old mode 100644 new mode 100755 similarity index 67% rename from bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c rename to bsp/rockchip/dm/hwtimer/hwtimer-rockchip_timer.c index 33ad9cd51bd..ac77ca1f364 --- a/bsp/rockchip/rk3500/driver/hwtimer/hwtimer-rockchip_timer.c +++ b/bsp/rockchip/dm/hwtimer/hwtimer-rockchip_timer.c @@ -8,30 +8,17 @@ * 2022-12-06 GuEe-GUI first version */ -#define DBG_TAG "drv.rk_timer" -#define DBG_LVL DBG_INFO -#include - #include #include #include -#ifdef RT_USING_KTIME -#include -#endif - -#define HZ 100 -#define KHZ 1000 -#define MHZ 1000000 -#define OSC_HZ (24 * MHZ) - -#define TIMER_LOAD_COUNT0 0x00 -#define TIMER_LOAD_COUNT1 0x04 -#define TIMER_CURRENT_VALUE0 0x08 -#define TIMER_CURRENT_VALUE1 0x0c -#define TIMER_CONTROL_REG3288 0x10 -#define TIMER_CONTROL_REG3399 0x1c -#define TIMER_INT_STATUS 0x18 +#define TIMER_LOAD_COUNT0 0x00 +#define TIMER_LOAD_COUNT1 0x04 +#define TIMER_CURRENT_VALUE0 0x08 +#define TIMER_CURRENT_VALUE1 0x0c +#define TIMER_CONTROL_REG3288 0x10 +#define TIMER_CONTROL_REG3399 0x1c +#define TIMER_INT_STATUS 0x18 #define TIMER_DISABLE 0x0 #define TIMER_ENABLE 0x1 @@ -39,6 +26,8 @@ #define TIMER_MODE_USER_DEFINED_COUNT (1 << 1) #define TIMER_INT_UNMASK (1 << 2) +#define HZ 100 + struct rk_timer { struct rt_hwtimer_device parent; @@ -55,17 +44,7 @@ struct rk_timer struct rt_hwtimer_info info; }; -#ifdef RT_USING_KTIME -struct hrt_timer -{ - struct rk_timer *timer; - uint64_t cnt; - void (*outcb)(void *param); - void *param; -}; -static struct hrt_timer _timer0 = {0}; -static struct rt_spinlock _spinlock; -#endif + #define raw_to_rk_timer(raw) rt_container_of(raw, struct rk_timer, parent) struct rk_timer_data @@ -200,26 +179,34 @@ const static struct rt_hwtimer_ops rk_timer_ops = static void rk_timer_isr(int irqno, void *param) { - struct hrt_timer *timer = &_timer0; - struct rk_timer *time = timer->timer; + struct rk_timer *rk_timer = (struct rk_timer *)param; - rk_timer_interrupt_clear(time); + rk_timer_interrupt_clear(rk_timer); - rt_ktime_hrtimer_process(); + if (rk_timer->status) + { + rt_device_hwtimer_isr(&rk_timer->parent); + } } -void rt_ktime_hrtimer_bind(rt_bitmap_t *affinity) +static void rk_timer_free(struct rk_timer *timer) { - struct rk_timer *timer = _timer0.timer; + if (timer->base) + { + rt_iounmap(timer->base); + } - if (rt_pic_irq_set_affinity(timer->irq, affinity) == -RT_ENOSYS) + if (!rt_is_err_or_null(timer->pclk)) { - LOG_E("timer irq affinity init fail\n"); + rt_clk_put(timer->pclk); } - else + + if (!rt_is_err_or_null(timer->clk)) { - LOG_D("timer irq(%d) binding done\n", timer->irq); + rt_clk_put(timer->clk); } + + rt_free(timer); } static rt_err_t rk_timer_probe(struct rt_platform_device *pdev) @@ -229,24 +216,22 @@ static rt_err_t rk_timer_probe(struct rt_platform_device *pdev) struct rt_device *dev = &pdev->parent; struct rk_timer *timer = rt_calloc(1, sizeof(*timer)); const struct rk_timer_data *timer_data = pdev->id->data; + if (!timer) { return -RT_ENOMEM; } -#ifdef RT_USING_KTIME - _timer0.timer = timer; - rt_spin_lock_init(&_spinlock); -#endif - if (!(timer->pclk = rt_clk_get_by_name(dev, "pclk"))) + + if (rt_is_err(timer->pclk = rt_clk_get_by_name(dev, "pclk"))) { - err = -RT_EIO; + err = rt_ptr_err(timer->pclk); goto _fail; } - if (!(timer->clk = rt_clk_get_by_name(dev, "timer"))) + if (rt_is_err(timer->clk = rt_clk_get_by_name(dev, "timer"))) { - err = -RT_EIO; + err = rt_ptr_err(timer->clk); goto _fail; } @@ -260,6 +245,8 @@ static rt_err_t rk_timer_probe(struct rt_platform_device *pdev) goto _fail; } + dev->user_data = timer; + timer->ctrl = timer->base + timer_data->ctrl_reg; rt_clk_enable(timer->pclk); @@ -276,44 +263,37 @@ static rt_err_t rk_timer_probe(struct rt_platform_device *pdev) timer->info.maxfreq = timer->freq; timer->info.minfreq = timer->freq; timer->info.maxcnt = 0xffffffff; - timer->info.cntmode = HWTIMER_CNTMODE_DW; + timer->info.cntmode = HWTIMER_CNTMODE_UP; rt_dm_dev_set_name_auto(&timer->parent.parent, "timer"); dev_name = rt_dm_dev_get_name(&timer->parent.parent); rt_device_hwtimer_register(&timer->parent, dev_name, RT_NULL); + rt_hw_interrupt_install(timer->irq, rk_timer_isr, timer, dev_name); + rt_hw_interrupt_umask(timer->irq); - RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = { 0 }; - rt_bitmap_set_bit(affinity, RT_CPUS_NR - 1); - rt_ktime_hrtimer_bind(affinity); + return RT_EOK; - rt_pic_attach_irq(timer->irq, rk_timer_isr, timer, dev_name, RT_IRQ_F_NONE); - rt_pic_irq_unmask(timer->irq); - -#if KTIMER_BIND_CPU - RT_BITMAP_DECLARE(affinity, RT_CPUS_NR) = {0}; - rt_bitmap_set_bit(affinity, 1); - rt_pic_irq_set_affinity(timer->irq, affinity); -#endif +_fail: + rk_timer_free(timer); return err; +} -_fail: - if (timer->base) - { - rt_iounmap(timer->base); - } - if (timer->pclk) - { - rt_clk_put(timer->pclk); - } - if (timer->clk) - { - rt_clk_put(timer->clk); - } - rt_free(timer); +static rt_err_t rk_timer_remove(struct rt_platform_device *pdev) +{ + struct rk_timer *timer = pdev->parent.user_data; - return err; + rt_hw_interrupt_mask(timer->irq); + rt_pic_detach_irq(timer->irq, timer); + + rk_timer_stop(&timer->parent); + + rt_device_unregister(&timer->parent.parent); + + rk_timer_free(timer); + + return RT_EOK; } static const struct rk_timer_data rk3288_timer_data = @@ -326,44 +306,6 @@ static const struct rk_timer_data rk3399_timer_data = .ctrl_reg = TIMER_CONTROL_REG3399, }; -#ifdef RT_USING_KTIME - -uint64_t rt_ktime_hrtimer_getfrq(void) -{ - return (24 * 1000 * 1000UL); -} - -uint64_t rt_ktime_hrtimer_getres(void) -{ - return ((1000UL * 1000 * 1000) * RT_KTIME_RESMUL) / (24 * 1000 * 1000UL); -} - -/** - * @brief set the timeout function for hrtimer framework - * - * @warning application should not call this API directly - * - * @param cnt the count of timer dealy - * @return rt_err_t 0 forever - */ -rt_err_t rt_ktime_hrtimer_settimeout(unsigned long cnt) -{ - struct hrt_timer *timer = &_timer0; - struct rk_timer *time = timer->timer; - - timer->cnt = cnt; - - if (cnt) - { - rk_timer_disable(time); - rk_timer_update_counter(cnt, time); - rk_timer_enable(time, TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK); - } - - return 0; -} -#endif - static const struct rt_ofw_node_id rk_timer_ofw_ids[] = { { .compatible = "rockchip,rk3288-timer", .data = &rk3288_timer_data }, @@ -377,12 +319,6 @@ static struct rt_platform_driver rk_timer_driver = .ids = rk_timer_ofw_ids, .probe = rk_timer_probe, + .remove = rk_timer_remove, }; - -static int rk_timer_drv_register(void) -{ - rt_platform_driver_register(&rk_timer_driver); - - return 0; -} -INIT_PLATFORM_EXPORT(rk_timer_drv_register); +RT_PLATFORM_DRIVER_EXPORT(rk_timer_driver); diff --git a/bsp/rockchip/dm/i2c/Kconfig b/bsp/rockchip/dm/i2c/Kconfig new file mode 100755 index 00000000000..f33b26db45f --- /dev/null +++ b/bsp/rockchip/dm/i2c/Kconfig @@ -0,0 +1,5 @@ +config RT_I2C_RK3X + bool "Rockchip RK3xxx I2C adapter" + depends on RT_MFD_SYSCON + depends on RT_USING_PINCTRL + default n diff --git a/bsp/rockchip/dm/i2c/SConscript b/bsp/rockchip/dm/i2c/SConscript new file mode 100755 index 00000000000..d4a9495cdfb --- /dev/null +++ b/bsp/rockchip/dm/i2c/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend('RT_I2C_RK3X'): + src += ['i2c-rk3x.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/i2c/i2c-rk3x.c b/bsp/rockchip/dm/i2c/i2c-rk3x.c new file mode 100755 index 00000000000..60918a1e442 --- /dev/null +++ b/bsp/rockchip/dm/i2c/i2c-rk3x.c @@ -0,0 +1,1375 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +#define DBG_TAG "i2c.rk3x" +#define DBG_LVL DBG_INFO +#include + +#include + +/* Register Map */ +#define REG_CON 0x00 /* control register */ +#define REG_CLKDIV 0x04 /* clock divisor register */ +#define REG_MRXADDR 0x08 /* slave address for REGISTER_TX */ +#define REG_MRXRADDR 0x0c /* slave register address for REGISTER_TX */ +#define REG_MTXCNT 0x10 /* number of bytes to be transmitted */ +#define REG_MRXCNT 0x14 /* number of bytes to be received */ +#define REG_IEN 0x18 /* interrupt enable */ +#define REG_IPD 0x1c /* interrupt pending */ +#define REG_FCNT 0x20 /* finished count */ + +/* Data buffer offsets */ +#define TXBUFFER_BASE 0x100 +#define RXBUFFER_BASE 0x200 + +/* REG_CON bits */ +#define REG_CON_EN RT_BIT(0) + +enum +{ + REG_CON_MOD_TX = 0, /* transmit data */ + REG_CON_MOD_REGISTER_TX, /* select register and restart */ + REG_CON_MOD_RX, /* receive data */ + REG_CON_MOD_REGISTER_RX, /* broken: transmits read addr AND writes register addr */ +}; + +#define REG_CON_MOD(mod) ((mod) << 1) +#define REG_CON_MOD_MASK (RT_BIT(1) | RT_BIT(2)) +#define REG_CON_START RT_BIT(3) +#define REG_CON_STOP RT_BIT(4) +#define REG_CON_LASTACK RT_BIT(5) /* 1: send NACK after last received byte */ +#define REG_CON_ACTACK RT_BIT(6) /* 1: stop if NACK is received */ + +#define REG_CON_TUNING_MASK RT_GENMASK_ULL(15, 8) + +#define REG_CON_SDA_CFG(cfg) ((cfg) << 8) +#define REG_CON_STA_CFG(cfg) ((cfg) << 12) +#define REG_CON_STO_CFG(cfg) ((cfg) << 14) + +/* REG_MRXADDR bits */ +#define REG_MRXADDR_VALID(x) RT_BIT(24 + (x)) /* [x*8+7:x*8] of MRX[R]ADDR valid */ + +/* REG_IEN/REG_IPD bits */ +#define REG_INT_BTF RT_BIT(0) /* a byte was transmitted */ +#define REG_INT_BRF RT_BIT(1) /* a byte was received */ +#define REG_INT_MBTF RT_BIT(2) /* master data transmit finished */ +#define REG_INT_MBRF RT_BIT(3) /* master data receive finished */ +#define REG_INT_START RT_BIT(4) /* START condition generated */ +#define REG_INT_STOP RT_BIT(5) /* STOP condition generated */ +#define REG_INT_NAKRCV RT_BIT(6) /* NACK received */ +#define REG_INT_ALL 0x7f + +/* Constants */ +#define WAIT_TIMEOUT 1000 /* ms */ +#define DEFAULT_SCL_RATE (100 * 1000) /* Hz */ + +/* I2C specification values for various modes */ +struct i2c_spec_values +{ + rt_ubase_t min_hold_start_ns; /* min hold time (repeated) START condition */ + rt_ubase_t min_low_ns; /* min LOW period of the SCL clock */ + rt_ubase_t min_high_ns; /* min HIGH period of the SCL cloc */ + rt_ubase_t min_setup_start_ns; /* min set-up time for a repeated START conditio */ + rt_ubase_t max_data_hold_ns; /* max data hold time */ + rt_ubase_t min_data_setup_ns; /* min data set-up time */ + rt_ubase_t min_setup_stop_ns; /* min set-up time for STOP condition */ + rt_ubase_t min_hold_buffer_ns; /* min bus free time between a STOP and */ +}; + +static const struct i2c_spec_values standard_mode_spec = +{ + .min_hold_start_ns = 4000, + .min_low_ns = 4700, + .min_high_ns = 4000, + .min_setup_start_ns = 4700, + .max_data_hold_ns = 3450, + .min_data_setup_ns = 250, + .min_setup_stop_ns = 4000, + .min_hold_buffer_ns = 4700, +}; + +static const struct i2c_spec_values fast_mode_spec = +{ + .min_hold_start_ns = 600, + .min_low_ns = 1300, + .min_high_ns = 600, + .min_setup_start_ns = 600, + .max_data_hold_ns = 900, + .min_data_setup_ns = 100, + .min_setup_stop_ns = 600, + .min_hold_buffer_ns = 1300, +}; + +static const struct i2c_spec_values fast_mode_plus_spec = +{ + .min_hold_start_ns = 260, + .min_low_ns = 500, + .min_high_ns = 260, + .min_setup_start_ns = 260, + .max_data_hold_ns = 400, + .min_data_setup_ns = 50, + .min_setup_stop_ns = 260, + .min_hold_buffer_ns = 500, +}; + +/* + * Calculated V1 timings, setup/hold start time and setup stop time for v1's + * calc_timings, the tuning should all be 0 for old hardware anyone using v0's + * calc_timings. + */ +struct rk3x_i2c_calced_timings +{ + rt_ubase_t div_low; /* Divider output for low */ + rt_ubase_t div_high; /* Divider output for high */ + rt_uint32_t tuning; /* Used to adjust setup/hold data time */ +}; + +enum rk3x_i2c_state +{ + STATE_IDLE, + STATE_START, + STATE_READ, + STATE_WRITE, + STATE_STOP +}; + +struct rk3x_i2c_soc_data +{ + int grf_offset; + rt_err_t (*calc_timings)(rt_ubase_t, struct i2c_timings *, + struct rk3x_i2c_calced_timings *); +}; + +struct rk3x_i2c +{ + struct rt_i2c_bus_device parent; + + const struct rk3x_i2c_soc_data *soc_data; + + int irq; + void *regs; + + struct rt_clk *clk; + struct rt_clk *pclk; + struct rt_clk_notifier clk_notifier; + + struct i2c_timings timings; + + struct rt_spinlock lock; + struct rt_completion done; + + struct rt_i2c_msg *msg; + rt_uint8_t addr; + rt_uint32_t mode; + rt_bool_t is_last_msg; + + enum rk3x_i2c_state state; + rt_uint32_t processed; + rt_err_t error; +}; + +#define raw_to_rk3x_i2c(raw) rt_container_of(raw, struct rk3x_i2c, parent) + +rt_inline void i2c_writel(struct rk3x_i2c *i2c, rt_uint32_t value, int offset) +{ + HWREG32(i2c->regs + offset) = value; +} + +rt_inline rt_uint32_t i2c_readl(struct rk3x_i2c *i2c, int offset) +{ + return HWREG32(i2c->regs + offset); +} + +/* Reset all interrupt pending bits */ +rt_inline void rk3x_i2c_clean_ipd(struct rk3x_i2c *i2c) +{ + i2c_writel(i2c, REG_INT_ALL, REG_IPD); +} + +/* Generate a START condition, which triggers a REG_INT_START interrupt */ +static void rk3x_i2c_start(struct rk3x_i2c *i2c) +{ + rt_uint32_t val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK; + + i2c_writel(i2c, REG_INT_START, REG_IEN); + + /* enable adapter with correct mode, send START condition */ + val |= REG_CON_EN | REG_CON_MOD(i2c->mode) | REG_CON_START; + + /* if we want to react to NACK, set ACTACK bit */ + if (!(i2c->msg->flags & RT_I2C_IGNORE_NACK)) + { + val |= REG_CON_ACTACK; + } + + i2c_writel(i2c, val, REG_CON); +} + +/* Generate a STOP condition, which triggers a REG_INT_STOP interrupt */ +static void rk3x_i2c_stop(struct rk3x_i2c *i2c, rt_err_t error) +{ + rt_uint32_t ctrl; + + i2c->processed = 0; + i2c->msg = RT_NULL; + i2c->error = error; + + if (i2c->is_last_msg) + { + /* Enable stop interrupt */ + i2c_writel(i2c, REG_INT_STOP, REG_IEN); + + i2c->state = STATE_STOP; + + ctrl = i2c_readl(i2c, REG_CON); + ctrl |= REG_CON_STOP; + i2c_writel(i2c, ctrl, REG_CON); + } + else + { + /* Signal rk3x_i2c_xfer to start the next message. */ + i2c->state = STATE_IDLE; + + /* + * The HW is actually not capable of REPEATED START. But we can + * get the intended effect by resetting its internal state + * and issuing an ordinary START. + */ + ctrl = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK; + i2c_writel(i2c, ctrl, REG_CON); + + /* signal that we are finished with the current msg */ + rt_completion_done(&i2c->done); + } +} + +/* Setup a read according to i2c->msg */ +static void rk3x_i2c_prepare_read(struct rk3x_i2c *i2c) +{ + rt_uint32_t con, len = i2c->msg->len - i2c->processed; + + con = i2c_readl(i2c, REG_CON); + + /* + * The hw can read up to 32 bytes at a time. If we need more than one + * chunk, send an ACK after the last byte of the current chunk. + */ + if (len > 32) + { + len = 32; + con &= ~REG_CON_LASTACK; + } + else + { + con |= REG_CON_LASTACK; + } + + /* make sure we are in plain RX mode if we read a second chunk */ + if (i2c->processed != 0) + { + con &= ~REG_CON_MOD_MASK; + con |= REG_CON_MOD(REG_CON_MOD_RX); + } + + i2c_writel(i2c, con, REG_CON); + i2c_writel(i2c, len, REG_MRXCNT); +} + +/* Fill the transmit buffer with data from i2c->msg */ +static void rk3x_i2c_fill_transmit_buf(struct rk3x_i2c *i2c) +{ + rt_uint32_t cnt = 0; + + for (int i = 0; i < 8; ++i) + { + rt_uint32_t val = 0; + + for (int j = 0; j < 4; ++j) + { + rt_uint8_t byte; + + if ((i2c->processed == i2c->msg->len) && (cnt != 0)) + { + break; + } + + if (i2c->processed == 0 && cnt == 0) + { + byte = (i2c->addr & 0x7f) << 1; + } + else + { + byte = i2c->msg->buf[i2c->processed++]; + } + + val |= byte << (j * 8); + cnt++; + } + + i2c_writel(i2c, val, TXBUFFER_BASE + 4 * i); + + if (i2c->processed == i2c->msg->len) + { + break; + } + } + + i2c_writel(i2c, cnt, REG_MTXCNT); +} + +/* IRQ handlers for individual states */ +static void rk3x_i2c_handle_start(struct rk3x_i2c *i2c, rt_uint32_t ipd) +{ + if (!(ipd & REG_INT_START)) + { + rk3x_i2c_stop(i2c, -RT_EIO); + LOG_W("Unexpected irq in START: 0x%x", ipd); + rk3x_i2c_clean_ipd(i2c); + + return; + } + + /* ack interrupt */ + i2c_writel(i2c, REG_INT_START, REG_IPD); + + /* disable start bit */ + i2c_writel(i2c, i2c_readl(i2c, REG_CON) & ~REG_CON_START, REG_CON); + + /* enable appropriate interrupts and transition */ + if (i2c->mode == REG_CON_MOD_TX) + { + i2c_writel(i2c, REG_INT_MBTF | REG_INT_NAKRCV, REG_IEN); + i2c->state = STATE_WRITE; + rk3x_i2c_fill_transmit_buf(i2c); + } + else + { + /* in any other case, we are going to be reading. */ + i2c_writel(i2c, REG_INT_MBRF | REG_INT_NAKRCV, REG_IEN); + i2c->state = STATE_READ; + rk3x_i2c_prepare_read(i2c); + } +} + +static void rk3x_i2c_handle_write(struct rk3x_i2c *i2c, rt_uint32_t ipd) +{ + if (!(ipd & REG_INT_MBTF)) + { + rk3x_i2c_stop(i2c, -RT_EIO); + LOG_E("Unexpected irq in WRITE: 0x%x", ipd); + rk3x_i2c_clean_ipd(i2c); + + return; + } + + /* ack interrupt */ + i2c_writel(i2c, REG_INT_MBTF, REG_IPD); + + /* are we finished? */ + if (i2c->processed == i2c->msg->len) + { + rk3x_i2c_stop(i2c, i2c->error); + } + else + { + rk3x_i2c_fill_transmit_buf(i2c); + } +} + +static void rk3x_i2c_handle_read(struct rk3x_i2c *i2c, unsigned int ipd) +{ + rt_uint32_t val = 0, len = i2c->msg->len - i2c->processed; + + /* we only care for MBRF here. */ + if (!(ipd & REG_INT_MBRF)) + { + return; + } + + /* ack interrupt (read also produces a spurious START flag, clear it too) */ + i2c_writel(i2c, REG_INT_MBRF | REG_INT_START, REG_IPD); + + /* Can only handle a maximum of 32 bytes at a time */ + if (len > 32) + { + len = 32; + } + + /* read the data from receive buffer */ + for (int i = 0; i < len; ++i) + { + rt_uint8_t byte; + + if (i % 4 == 0) + { + val = i2c_readl(i2c, RXBUFFER_BASE + (i / 4) * 4); + } + + byte = (val >> ((i % 4) * 8)) & 0xff; + i2c->msg->buf[i2c->processed++] = byte; + } + + /* are we finished? */ + if (i2c->processed == i2c->msg->len) + { + rk3x_i2c_stop(i2c, i2c->error); + } + else + { + rk3x_i2c_prepare_read(i2c); + } +} + +static void rk3x_i2c_handle_stop(struct rk3x_i2c *i2c, rt_uint32_t ipd) +{ + rt_uint32_t con; + + if (!(ipd & REG_INT_STOP)) + { + rk3x_i2c_stop(i2c, -RT_EIO); + LOG_E("Unexpected irq in STOP: 0x%x", ipd); + rk3x_i2c_clean_ipd(i2c); + + return; + } + + /* ack interrupt */ + i2c_writel(i2c, REG_INT_STOP, REG_IPD); + + /* disable STOP bit */ + con = i2c_readl(i2c, REG_CON); + con &= ~REG_CON_STOP; + i2c_writel(i2c, con, REG_CON); + + i2c->state = STATE_IDLE; + + /* signal rk3x_i2c_xfer that we are finished */ + rt_completion_done(&i2c->done); +} + +static void rk3x_i2c_adapt_div(struct rk3x_i2c *i2c, rt_ubase_t clk_rate) +{ + rt_err_t err; + rt_ubase_t level; + rt_uint32_t val; + struct rk3x_i2c_calced_timings calc; + struct i2c_timings *timings = &i2c->timings; + + if ((err = i2c->soc_data->calc_timings(clk_rate, timings, &calc))) + { + LOG_W("Could not reach SCL freq %u", timings->bus_freq_hz); + } + + rt_clk_enable(i2c->pclk); + + level = rt_spin_lock_irqsave(&i2c->lock); + + val = i2c_readl(i2c, REG_CON); + val &= ~REG_CON_TUNING_MASK; + val |= calc.tuning; + i2c_writel(i2c, val, REG_CON); + i2c_writel(i2c, (calc.div_high << 16) | (calc.div_low & 0xffff), REG_CLKDIV); + + rt_spin_unlock_irqrestore(&i2c->lock, level); + + rt_clk_disable(i2c->pclk); +} + +static rt_err_t rk3x_i2c_clk_notifier(struct rt_clk_notifier *notifier, + rt_ubase_t msg, rt_ubase_t old_rate, rt_ubase_t new_rate) +{ + struct rk3x_i2c_calced_timings calc; + struct rk3x_i2c *i2c = rt_container_of(notifier, struct rk3x_i2c, clk_notifier); + + switch (msg) + { + case RT_CLK_MSG_PRE_RATE_CHANGE: + /* + * Try the calculation (but don't store the result) ahead of + * time to see if we need to block the clock change. Timings + * shouldn't actually take effect until rk3x_i2c_adapt_div(). + */ + if (i2c->soc_data->calc_timings(new_rate, &i2c->timings, &calc) != 0) + { + return -RT_EIO; + } + + /* scale up */ + if (new_rate > old_rate) + { + rk3x_i2c_adapt_div(i2c, new_rate); + } + break; + + case RT_CLK_MSG_POST_RATE_CHANGE: + /* scale down */ + if (new_rate < old_rate) + { + rk3x_i2c_adapt_div(i2c, new_rate); + } + break; + + case RT_CLK_MSG_ABORT_RATE_CHANGE: + /* scale up */ + if (new_rate > old_rate) + { + rk3x_i2c_adapt_div(i2c, old_rate); + } + break; + + default: + break; + } + + return RT_EOK; +} + +static const struct i2c_spec_values *rk3x_i2c_get_spec(rt_uint32_t speed) +{ + if (speed <= I2C_MAX_STANDARD_MODE_FREQ) + { + return &standard_mode_spec; + } + else if (speed <= I2C_MAX_FAST_MODE_FREQ) + { + return &fast_mode_spec; + } + else + { + return &fast_mode_plus_spec; + } +} + +/** + * rk3x_i2c_v0_calc_timings - Calculate divider values for desired SCL frequency + * @clk_rate: I2C input clock rate + * @t: Known I2C timing information + * @t_calc: Caculated rk3x private timings that would be written into regs + * + * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case + * a best-effort divider value is returned in divs. If the target rate is + * too high, we silently use the highest possible rate. + */ +static rt_err_t rk3x_i2c_v0_calc_timings(rt_ubase_t clk_rate, + struct i2c_timings *t, struct rk3x_i2c_calced_timings *t_calc) +{ + rt_err_t err = RT_EOK; + rt_ubase_t min_low_ns, min_high_ns; + rt_ubase_t max_low_ns, min_total_ns; + rt_ubase_t clk_rate_khz, scl_rate_khz; + rt_ubase_t min_low_div, min_high_div; + rt_ubase_t max_low_div; + rt_ubase_t min_div_for_hold, min_total_div; + rt_ubase_t extra_div, extra_low_div, ideal_low_div; + rt_ubase_t data_hold_buffer_ns = 50; + const struct i2c_spec_values *spec; + + /* Only support standard-mode and fast-mode */ + if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ) + { + t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ; + } + + /* prevent scl_rate_khz from becoming 0 */ + if (t->bus_freq_hz < 1000) + { + t->bus_freq_hz = 1000; + } + + /* + * min_low_ns: The minimum number of ns we need to hold low to + * meet I2C specification, should include fall time. + * min_high_ns: The minimum number of ns we need to hold high to + * meet I2C specification, should include rise time. + * max_low_ns: The maximum number of ns we can hold low to meet + * I2C specification. + * + * Note: max_low_ns should be (maximum data hold time * 2 - buffer) + * This is because the i2c host on Rockchip holds the data line + * for half the low time. + */ + spec = rk3x_i2c_get_spec(t->bus_freq_hz); + min_high_ns = t->scl_rise_ns + spec->min_high_ns; + + /* + * Timings for repeated start: + * - controller appears to drop SDA at .875x (7/8) programmed clk high. + * - controller appears to keep SCL high for 2x programmed clk high. + * + * We need to account for those rules in picking our "high" time so + * we meet tSU;STA and tHD;STA times. + */ + min_high_ns = rt_max(min_high_ns, RT_DIV_ROUND_UP( + (t->scl_rise_ns + spec->min_setup_start_ns) * 1000, 875)); + min_high_ns = rt_max(min_high_ns, RT_DIV_ROUND_UP( + (t->scl_rise_ns + spec->min_setup_start_ns + t->sda_fall_ns + + spec->min_high_ns), 2)); + + min_low_ns = t->scl_fall_ns + spec->min_low_ns; + max_low_ns = spec->max_data_hold_ns * 2 - data_hold_buffer_ns; + min_total_ns = min_low_ns + min_high_ns; + + /* Adjust to avoid overflow */ + clk_rate_khz = RT_DIV_ROUND_UP(clk_rate, 1000); + scl_rate_khz = t->bus_freq_hz / 1000; + + /* + * We need the total div to be >= this number + * so we don't clock too fast. + */ + min_total_div = RT_DIV_ROUND_UP(clk_rate_khz, scl_rate_khz * 8); + + /* These are the min dividers needed for min hold times. */ + min_low_div = RT_DIV_ROUND_UP(clk_rate_khz * min_low_ns, 8 * 1000000); + min_high_div = RT_DIV_ROUND_UP(clk_rate_khz * min_high_ns, 8 * 1000000); + min_div_for_hold = (min_low_div + min_high_div); + + /* + * This is the maximum divider so we don't go over the maximum. + * We don't round up here (we round down) since this is a maximum. + */ + max_low_div = clk_rate_khz * max_low_ns / (8 * 1000000); + + if (min_low_div > max_low_div) + { + max_low_div = min_low_div; + } + + if (min_div_for_hold > min_total_div) + { + /* Time needed to meet hold requirements is important. Just use that. */ + t_calc->div_low = min_low_div; + t_calc->div_high = min_high_div; + } + else + { + /* + * We've got to distribute some time among the low and high + * so we don't run too fast. + */ + extra_div = min_total_div - min_div_for_hold; + + /* + * We'll try to split things up perfectly evenly, + * biasing slightly towards having a higher div + * for low (spend more time low). + */ + ideal_low_div = RT_DIV_ROUND_UP(clk_rate_khz * min_low_ns, + scl_rate_khz * 8 * min_total_ns); + + /* Don't allow it to go over the maximum */ + if (ideal_low_div > max_low_div) + { + ideal_low_div = max_low_div; + } + + /* Handle when the ideal low div is going to take up more than we have. */ + if (ideal_low_div > min_low_div + extra_div) + { + ideal_low_div = min_low_div + extra_div; + } + + /* Give low the "ideal" and give high whatever extra is left */ + extra_low_div = ideal_low_div - min_low_div; + t_calc->div_low = ideal_low_div; + t_calc->div_high = min_high_div + (extra_div - extra_low_div); + } + + /* + * Adjust to the fact that the hardware has an implicit "+1". + * NOTE: Above calculations always produce div_low > 0 and div_high > 0. + */ + --t_calc->div_low; + --t_calc->div_high; + + /* Give the tuning value 0, that would not update con register */ + t_calc->tuning = 0; + + /* Maximum divider supported by hw is 0xffff */ + if (t_calc->div_low > 0xffff) + { + t_calc->div_low = 0xffff; + err = -RT_EINVAL; + } + + if (t_calc->div_high > 0xffff) + { + t_calc->div_high = 0xffff; + err = -RT_EINVAL; + } + + return err; +} + +/** + * rk3x_i2c_v1_calc_timings - Calculate timing values for desired SCL frequency + * @clk_rate: I2C input clock rate + * @t: Known I2C timing information + * @t_calc: Caculated rk3x private timings that would be written into regs + * + * Return: %0 on success, -%EINVAL if the goal SCL rate is too slow. In that case + * a best-effort divider value is returned in divs. If the target rate is + * too high, we silently use the highest possible rate. + * The following formulas are v1's method to calculate timings. + * + * l = divl + 1; + * h = divh + 1; + * s = sda_update_config + 1; + * u = start_setup_config + 1; + * p = stop_setup_config + 1; + * T = Tclk_i2c; + * + * tHigh = 8 * h * T; + * tLow = 8 * l * T; + * + * tHD;sda = (l * s + 1) * T; + * tSU;sda = [(8 - s) * l + 1] * T; + * tI2C = 8 * (l + h) * T; + * + * tSU;sta = (8h * u + 1) * T; + * tHD;sta = [8h * (u + 1) - 1] * T; + * tSU;sto = (8h * p + 1) * T; + */ +static rt_err_t rk3x_i2c_v1_calc_timings(rt_ubase_t clk_rate, + struct i2c_timings *t, struct rk3x_i2c_calced_timings *t_calc) +{ + rt_err_t err = 0; + rt_ubase_t min_low_ns, min_high_ns; + rt_ubase_t min_setup_start_ns, min_setup_data_ns; + rt_ubase_t min_setup_stop_ns, max_hold_data_ns; + rt_ubase_t clk_rate_khz, scl_rate_khz; + rt_ubase_t min_low_div, min_high_div; + rt_ubase_t min_div_for_hold, min_total_div; + rt_ubase_t extra_div, extra_low_div; + rt_ubase_t sda_update_cfg, stp_sta_cfg, stp_sto_cfg; + const struct i2c_spec_values *spec; + + /* Support standard-mode, fast-mode and fast-mode plus */ + if (t->bus_freq_hz > I2C_MAX_FAST_MODE_PLUS_FREQ) + { + t->bus_freq_hz = I2C_MAX_FAST_MODE_PLUS_FREQ; + } + + /* prevent scl_rate_khz from becoming 0 */ + if (t->bus_freq_hz < 1000) + { + t->bus_freq_hz = 1000; + } + + /* + * min_low_ns: The minimum number of ns we need to hold low to + * meet I2C specification, should include fall time. + * min_high_ns: The minimum number of ns we need to hold high to + * meet I2C specification, should include rise time. + */ + spec = rk3x_i2c_get_spec(t->bus_freq_hz); + + /* calculate min-divh and min-divl */ + clk_rate_khz = RT_DIV_ROUND_UP(clk_rate, 1000); + scl_rate_khz = t->bus_freq_hz / 1000; + min_total_div = RT_DIV_ROUND_UP(clk_rate_khz, scl_rate_khz * 8); + + min_high_ns = t->scl_rise_ns + spec->min_high_ns; + min_high_div = RT_DIV_ROUND_UP(clk_rate_khz * min_high_ns, 8 * 1000000); + + min_low_ns = t->scl_fall_ns + spec->min_low_ns; + min_low_div = RT_DIV_ROUND_UP(clk_rate_khz * min_low_ns, 8 * 1000000); + + /* + * Final divh and divl must be greater than 0, otherwise the + * hardware would not output the i2c clk. + */ + min_high_div = (min_high_div < 1) ? 2 : min_high_div; + min_low_div = (min_low_div < 1) ? 2 : min_low_div; + + /* These are the min dividers needed for min hold times. */ + min_div_for_hold = (min_low_div + min_high_div); + + /* + * This is the maximum divider so we don't go over the maximum. + * We don't round up here (we round down) since this is a maximum. + */ + if (min_div_for_hold >= min_total_div) + { + /* + * Time needed to meet hold requirements is important. + * Just use that. + */ + t_calc->div_low = min_low_div; + t_calc->div_high = min_high_div; + } + else + { + /* + * We've got to distribute some time among the low and high + * so we don't run too fast. + * We'll try to split things up by the scale of min_low_div and + * min_high_div, biasing slightly towards having a higher div + * for low (spend more time low). + */ + extra_div = min_total_div - min_div_for_hold; + extra_low_div = RT_DIV_ROUND_UP(min_low_div * extra_div, min_div_for_hold); + + t_calc->div_low = min_low_div + extra_low_div; + t_calc->div_high = min_high_div + (extra_div - extra_low_div); + } + + /* + * calculate sda data hold count by the rules, data_upd_st:3 + * is a appropriate value to reduce calculated times. + */ + for (sda_update_cfg = 3; sda_update_cfg > 0; --sda_update_cfg) + { + max_hold_data_ns = RT_DIV_ROUND_UP((sda_update_cfg + * (t_calc->div_low) + 1) * 1000000, clk_rate_khz); + min_setup_data_ns = RT_DIV_ROUND_UP(((8 - sda_update_cfg) + * (t_calc->div_low) + 1) * 1000000, clk_rate_khz); + + if (max_hold_data_ns < spec->max_data_hold_ns && + min_setup_data_ns > spec->min_data_setup_ns) + { + break; + } + } + + /* calculate setup start config */ + min_setup_start_ns = t->scl_rise_ns + spec->min_setup_start_ns; + stp_sta_cfg = RT_DIV_ROUND_UP(clk_rate_khz * min_setup_start_ns - 1000000, + 8 * 1000000 * (t_calc->div_high)); + + /* calculate setup stop config */ + min_setup_stop_ns = t->scl_rise_ns + spec->min_setup_stop_ns; + stp_sto_cfg = RT_DIV_ROUND_UP(clk_rate_khz * min_setup_stop_ns - 1000000, + 8 * 1000000 * (t_calc->div_high)); + + t_calc->tuning = REG_CON_SDA_CFG(--sda_update_cfg) | + REG_CON_STA_CFG(--stp_sta_cfg) | REG_CON_STO_CFG(--stp_sto_cfg); + + --t_calc->div_low; + --t_calc->div_high; + + /* Maximum divider supported by hw is 0xffff */ + if (t_calc->div_low > 0xffff) + { + t_calc->div_low = 0xffff; + err = -RT_EINVAL; + } + + if (t_calc->div_high > 0xffff) + { + t_calc->div_high = 0xffff; + err = -RT_EINVAL; + } + + return err; +} + +/* Setup I2C registers for an I2C operation specified by msgs, num */ +static rt_ssize_t rk3x_i2c_setup(struct rk3x_i2c *i2c, struct rt_i2c_msg *msgs, + int num) +{ + rt_ssize_t res = 0; + rt_uint32_t addr = (msgs[0].addr & 0x7f) << 1; + + /* + * The I2C adapter can issue a small (len < 4) write packet before + * reading. This speeds up SMBus-style register reads. + * The MRXADDR/MRXRADDR hold the slave address and the slave register + * address in this case. + */ + + if (num >= 2 && msgs[0].len < 4 && + !(msgs[0].flags & RT_I2C_RD) && (msgs[1].flags & RT_I2C_RD)) + { + rt_uint32_t reg_addr = 0; + + LOG_D("Combined write/read from addr 0x%x", addr >> 1); + + /* Fill MRXRADDR with the register address(es) */ + for (int i = 0; i < msgs[0].len; ++i) + { + reg_addr |= msgs[0].buf[i] << (i * 8); + reg_addr |= REG_MRXADDR_VALID(i); + } + + /* msgs[0] is handled by hw. */ + i2c->msg = &msgs[1]; + i2c->mode = REG_CON_MOD_REGISTER_TX; + + i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), REG_MRXADDR); + i2c_writel(i2c, reg_addr, REG_MRXRADDR); + + res = 2; + } + else + { + /* We'll have to do it the boring way and process the msgs one-by-one. */ + if (msgs[0].flags & RT_I2C_RD) + { + /* set read bit */ + addr |= 1; + + /* + * We have to transmit the slave addr first. Use + * MOD_REGISTER_TX for that purpose. + */ + i2c->mode = REG_CON_MOD_REGISTER_TX; + i2c_writel(i2c, addr | REG_MRXADDR_VALID(0), REG_MRXADDR); + i2c_writel(i2c, 0, REG_MRXRADDR); + } + else + { + i2c->mode = REG_CON_MOD_TX; + } + + i2c->msg = &msgs[0]; + + res = 1; + } + + i2c->addr = msgs[0].addr; + i2c->state = STATE_START; + i2c->processed = 0; + i2c->error = RT_EOK; + + rk3x_i2c_clean_ipd(i2c); + + return res; +} + +static rt_ssize_t rk3x_i2c_master_xfer(struct rt_i2c_bus_device *bus, + struct rt_i2c_msg msgs[], rt_uint32_t num) +{ + rt_ssize_t res = 0; + rt_uint32_t val; + rt_ubase_t level; + rt_err_t timeout_err; + struct rk3x_i2c *i2c = raw_to_rk3x_i2c(bus); + + level = rt_spin_lock_irqsave(&i2c->lock); + + rt_clk_enable(i2c->clk); + rt_clk_enable(i2c->pclk); + + i2c->is_last_msg = RT_FALSE; + + /* Process msgs */ + for (int i = 0; i < num; i += res) + { + res = rk3x_i2c_setup(i2c, msgs + i, num - i); + + if (res < 0) + { + LOG_E("%s setup failed", rt_dm_dev_get_name(&i2c->parent.parent)); + + break; + } + + if (i + res >= num) + { + i2c->is_last_msg = RT_TRUE; + } + + rt_spin_unlock_irqrestore(&i2c->lock, level); + + rk3x_i2c_start(i2c); + + timeout_err = rt_completion_wait(&i2c->done, rt_tick_from_millisecond(WAIT_TIMEOUT)); + + level = rt_spin_lock_irqsave(&i2c->lock); + + if (timeout_err) + { + LOG_E("timeout, ipd: 0x%02x, state: %d", i2c_readl(i2c, REG_IPD), i2c->state); + + /* Force a STOP condition without interrupt */ + i2c_writel(i2c, 0, REG_IEN); + val = i2c_readl(i2c, REG_CON) & REG_CON_TUNING_MASK; + val |= REG_CON_EN | REG_CON_STOP; + i2c_writel(i2c, val, REG_CON); + + i2c->state = STATE_IDLE; + + res = timeout_err; + break; + } + + if (i2c->error) + { + res = i2c->error; + + break; + } + } + + rt_clk_disable(i2c->pclk); + rt_clk_disable(i2c->clk); + + rt_spin_unlock_irqrestore(&i2c->lock, level); + + return res < 0 ? res : num; +} + +const static struct rt_i2c_bus_device_ops rk3x_i2c_ops = +{ + .master_xfer = rk3x_i2c_master_xfer, +}; + +static void rk3x_i2c_isr(int irqno, void *param) +{ + rt_uint32_t ipd; + struct rk3x_i2c *i2c = param; + + rt_spin_lock(&i2c->lock); + + ipd = i2c_readl(i2c, REG_IPD); + + if (i2c->state == STATE_IDLE) + { + LOG_W("IRQ in STATE_IDLE, ipd = 0x%x", ipd); + rk3x_i2c_clean_ipd(i2c); + + goto _out; + } + + LOG_D("IRQ: state %d, ipd: %x", i2c->state, ipd); + + /* Clean interrupt bits we don't care about */ + ipd &= ~(REG_INT_BRF | REG_INT_BTF); + + if (ipd & REG_INT_NAKRCV) + { + /* + * We got a NACK in the last operation. Depending on whether + * IGNORE_NAK is set, we have to stop the operation and report + * an error. + */ + i2c_writel(i2c, REG_INT_NAKRCV, REG_IPD); + + ipd &= ~REG_INT_NAKRCV; + + if (!(i2c->msg->flags & RT_I2C_IGNORE_NACK)) + { + LOG_E("Flags error"); + + rk3x_i2c_stop(i2c, -RT_EIO); + } + } + + /* is there anything left to handle? */ + if ((ipd & REG_INT_ALL) == 0) + { + goto _out; + } + + switch (i2c->state) + { + case STATE_START: + rk3x_i2c_handle_start(i2c, ipd); + break; + + case STATE_WRITE: + rk3x_i2c_handle_write(i2c, ipd); + break; + + case STATE_READ: + rk3x_i2c_handle_read(i2c, ipd); + break; + + case STATE_STOP: + rk3x_i2c_handle_stop(i2c, ipd); + break; + + case STATE_IDLE: + break; + } + +_out: + rt_spin_unlock(&i2c->lock); +} + +static void rk3x_i2c_free(struct rk3x_i2c *i2c) +{ + if (i2c->regs) + { + rt_iounmap(i2c->regs); + } + + if (!rt_is_err_or_null(i2c->clk)) + { + rt_clk_unprepare(i2c->clk); + rt_clk_put(i2c->clk); + } + + if (!rt_is_err_or_null(i2c->pclk)) + { + if (!rt_is_err_or_null(i2c->clk) && i2c->pclk != i2c->clk) + { + rt_clk_unprepare(i2c->pclk); + rt_clk_put(i2c->pclk); + } + } + + if (i2c->clk_notifier.callback) + { + rt_clk_notifier_unregister(i2c->clk, &i2c->clk_notifier); + } + + rt_free(i2c); +} + +static rt_err_t rk3x_i2c_probe(struct rt_platform_device *pdev) +{ + int id = -1; + rt_err_t err; + const char *dev_name; + struct rt_device *dev = &pdev->parent; + struct rk3x_i2c *i2c = rt_calloc(1, sizeof(*i2c)); + + if (!i2c) + { + return -RT_ENOMEM; + } + + i2c->soc_data = pdev->id->data; + i2c_timings_ofw_parse(dev->ofw_node, &i2c->timings, RT_TRUE); + + i2c->regs = rt_dm_dev_iomap(dev, 0); + + if (!i2c->regs) + { + err = -RT_EIO; + + goto _fail; + } + + i2c->irq = rt_dm_dev_get_irq(dev, 0); + + if (i2c->irq < 0) + { + err = i2c->irq; + + goto _fail; + } + + if (i2c->soc_data->grf_offset >= 0) + { + rt_uint32_t value; + struct rt_syscon *grf; + struct rt_ofw_node *np = dev->ofw_node; + + id = pdev->dev_id; + + if (id < 0) + { + err = -RT_EINVAL; + LOG_E("alias id not found"); + + goto _fail; + } + + grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,grf"); + + if (!grf) + { + err = -RT_EIO; + LOG_E("I2C%d %s not found", id, "rockchip,grf"); + + goto _fail; + } + + /* 27+i: write mask, 11+i: value */ + value = RT_BIT(27 + id) | RT_BIT(11 + id); + + if ((err = rt_syscon_write(grf, i2c->soc_data->grf_offset, value))) + { + LOG_E("Could not write to GRF: %s", rt_strerror(err)); + + goto _fail; + } + } + + if (i2c->soc_data->calc_timings == rk3x_i2c_v0_calc_timings) + { + i2c->clk = rt_clk_get_by_index(dev, 0); + i2c->pclk = i2c->clk; + } + else + { + i2c->clk = rt_clk_get_by_name(dev, "i2c"); + i2c->pclk = rt_clk_get_by_name(dev, "pclk"); + } + + if (rt_is_err(i2c->clk)) + { + err = rt_ptr_err(i2c->clk); + + goto _fail; + } + + if ((err = rt_clk_prepare(i2c->clk))) + { + goto _fail; + } + + if (rt_is_err(i2c->pclk)) + { + err = rt_ptr_err(i2c->pclk); + + goto _fail; + } + + if ((err = rt_clk_prepare(i2c->pclk))) + { + goto _fail; + } + + i2c->clk_notifier.callback = rk3x_i2c_clk_notifier; + if ((err = rt_clk_notifier_register(i2c->clk, &i2c->clk_notifier))) + { + goto _fail; + } + + if ((err = rt_clk_enable(i2c->clk))) + { + LOG_E("Can't enable bus clk: %s", rt_strerror(err)); + + goto _fail; + } + + rk3x_i2c_adapt_div(i2c, rt_clk_get_rate(i2c->clk)); + rt_clk_disable(i2c->clk); + + rt_spin_lock_init(&i2c->lock); + rt_completion_init(&i2c->done); + + if (id >= 0) + { + rt_dm_dev_set_name(&i2c->parent.parent, "i2c%u", id); + } + else + { + rt_dm_dev_set_name_auto(&i2c->parent.parent, "i2c"); + } + dev_name = rt_dm_dev_get_name(&i2c->parent.parent); + + rt_hw_interrupt_install(i2c->irq, rk3x_i2c_isr, i2c, dev_name); + rt_hw_interrupt_umask(i2c->irq); + + dev->user_data = i2c; + + i2c->parent.ops = &rk3x_i2c_ops; + i2c->parent.parent.ofw_node = dev->ofw_node; + + rt_dm_dev_bind_fwdata(dev, RT_NULL, i2c); + + if ((err = rt_i2c_bus_device_register(&i2c->parent, dev_name))) + { + goto _free_irq; + } + + return RT_EOK; + +_free_irq: + rt_dm_dev_unbind_fwdata(dev, RT_NULL); + + rt_hw_interrupt_mask(i2c->irq); + rt_pic_detach_irq(i2c->irq, i2c); + +_fail: + rk3x_i2c_free(i2c); + + return err; +} + +static rt_err_t rk3x_i2c_remove(struct rt_platform_device *pdev) +{ + struct rt_device *dev = &pdev->parent; + struct rk3x_i2c *i2c = dev->user_data; + + rt_dm_dev_unbind_fwdata(dev, RT_NULL); + + rt_hw_interrupt_mask(i2c->irq); + rt_pic_detach_irq(i2c->irq, i2c); + + rt_device_unregister(&i2c->parent.parent); + + rk3x_i2c_free(i2c); + + return RT_EOK; +} + +static const struct rk3x_i2c_soc_data rv1108_soc_data = +{ + .grf_offset = -1, + .calc_timings = rk3x_i2c_v1_calc_timings, +}; + +static const struct rk3x_i2c_soc_data rv1126_soc_data = +{ + .grf_offset = 0x118, + .calc_timings = rk3x_i2c_v1_calc_timings, +}; + +static const struct rk3x_i2c_soc_data rk3066_soc_data = +{ + .grf_offset = 0x154, + .calc_timings = rk3x_i2c_v0_calc_timings, +}; + +static const struct rk3x_i2c_soc_data rk3188_soc_data = +{ + .grf_offset = 0x0a4, + .calc_timings = rk3x_i2c_v0_calc_timings, +}; + +static const struct rk3x_i2c_soc_data rk3228_soc_data = +{ + .grf_offset = -1, + .calc_timings = rk3x_i2c_v0_calc_timings, +}; + +static const struct rk3x_i2c_soc_data rk3288_soc_data = +{ + .grf_offset = -1, + .calc_timings = rk3x_i2c_v0_calc_timings, +}; + +static const struct rk3x_i2c_soc_data rk3399_soc_data = +{ + .grf_offset = -1, + .calc_timings = rk3x_i2c_v1_calc_timings, +}; + +static const struct rt_ofw_node_id rk3x_i2c_ofw_ids[] = +{ + { .compatible = "rockchip,rv1108-i2c", .data = &rv1108_soc_data }, + { .compatible = "rockchip,rv1126-i2c", .data = &rv1126_soc_data }, + { .compatible = "rockchip,rk3066-i2c", .data = &rk3066_soc_data }, + { .compatible = "rockchip,rk3188-i2c", .data = &rk3188_soc_data }, + { .compatible = "rockchip,rk3228-i2c", .data = &rk3228_soc_data }, + { .compatible = "rockchip,rk3288-i2c", .data = &rk3288_soc_data }, + { .compatible = "rockchip,rk3399-i2c", .data = &rk3399_soc_data }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rk3x_i2c_driver = +{ + .name = "rk3x-i2c", + .ids = rk3x_i2c_ofw_ids, + + .probe = rk3x_i2c_probe, + .remove = rk3x_i2c_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rk3x_i2c_driver); diff --git a/bsp/rockchip/dm/include/dt-bindings/clock/rk3308-cru.h b/bsp/rockchip/dm/include/dt-bindings/clock/rk3308-cru.h new file mode 100755 index 00000000000..3967932d2d1 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/clock/rk3308-cru.h @@ -0,0 +1,387 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3308_H__ +#define __DT_BINDINGS_CLK_ROCKCHIP_RK3308_H__ + +/* core clocks */ +#define PLL_APLL 1 +#define PLL_DPLL 2 +#define PLL_VPLL0 3 +#define PLL_VPLL1 4 +#define ARMCLK 5 + +/* sclk (special clocks) */ +#define USB480M 14 +#define SCLK_RTC32K 15 +#define SCLK_PVTM_CORE 16 +#define SCLK_UART0 17 +#define SCLK_UART1 18 +#define SCLK_UART2 19 +#define SCLK_UART3 20 +#define SCLK_UART4 21 +#define SCLK_I2C0 22 +#define SCLK_I2C1 23 +#define SCLK_I2C2 24 +#define SCLK_I2C3 25 +#define SCLK_PWM0 26 +#define SCLK_SPI0 27 +#define SCLK_SPI1 28 +#define SCLK_SPI2 29 +#define SCLK_TIMER0 30 +#define SCLK_TIMER1 31 +#define SCLK_TIMER2 32 +#define SCLK_TIMER3 33 +#define SCLK_TIMER4 34 +#define SCLK_TIMER5 35 +#define SCLK_TSADC 36 +#define SCLK_SARADC 37 +#define SCLK_OTP 38 +#define SCLK_OTP_USR 39 +#define SCLK_CPU_BOOST 40 +#define SCLK_CRYPTO 41 +#define SCLK_CRYPTO_APK 42 +#define SCLK_NANDC_DIV 43 +#define SCLK_NANDC_DIV50 44 +#define SCLK_NANDC 45 +#define SCLK_SDMMC_DIV 46 +#define SCLK_SDMMC_DIV50 47 +#define SCLK_SDMMC 48 +#define SCLK_SDMMC_DRV 49 +#define SCLK_SDMMC_SAMPLE 50 +#define SCLK_SDIO_DIV 51 +#define SCLK_SDIO_DIV50 52 +#define SCLK_SDIO 53 +#define SCLK_SDIO_DRV 54 +#define SCLK_SDIO_SAMPLE 55 +#define SCLK_EMMC_DIV 56 +#define SCLK_EMMC_DIV50 57 +#define SCLK_EMMC 58 +#define SCLK_EMMC_DRV 59 +#define SCLK_EMMC_SAMPLE 60 +#define SCLK_SFC 61 +#define SCLK_OTG_ADP 62 +#define SCLK_MAC_SRC 63 +#define SCLK_MAC 64 +#define SCLK_MAC_REF 65 +#define SCLK_MAC_RX_TX 66 +#define SCLK_MAC_RMII 67 +#define SCLK_DDR_MON_TIMER 68 +#define SCLK_DDR_MON 69 +#define SCLK_DDRCLK 70 +#define SCLK_PMU 71 +#define SCLK_USBPHY_REF 72 +#define SCLK_WIFI 73 +#define SCLK_PVTM_PMU 74 +#define SCLK_PDM 75 +#define SCLK_I2S0_8CH_TX 76 +#define SCLK_I2S0_8CH_TX_OUT 77 +#define SCLK_I2S0_8CH_RX 78 +#define SCLK_I2S0_8CH_RX_OUT 79 +#define SCLK_I2S1_8CH_TX 80 +#define SCLK_I2S1_8CH_TX_OUT 81 +#define SCLK_I2S1_8CH_RX 82 +#define SCLK_I2S1_8CH_RX_OUT 83 +#define SCLK_I2S2_8CH_TX 84 +#define SCLK_I2S2_8CH_TX_OUT 85 +#define SCLK_I2S2_8CH_RX 86 +#define SCLK_I2S2_8CH_RX_OUT 87 +#define SCLK_I2S3_8CH_TX 88 +#define SCLK_I2S3_8CH_TX_OUT 89 +#define SCLK_I2S3_8CH_RX 90 +#define SCLK_I2S3_8CH_RX_OUT 91 +#define SCLK_I2S0_2CH 92 +#define SCLK_I2S0_2CH_OUT 93 +#define SCLK_I2S1_2CH 94 +#define SCLK_I2S1_2CH_OUT 95 +#define SCLK_SPDIF_TX_DIV 96 +#define SCLK_SPDIF_TX_DIV50 97 +#define SCLK_SPDIF_TX 98 +#define SCLK_SPDIF_RX_DIV 99 +#define SCLK_SPDIF_RX_DIV50 100 +#define SCLK_SPDIF_RX 101 +#define SCLK_I2S0_8CH_TX_MUX 102 +#define SCLK_I2S0_8CH_RX_MUX 103 +#define SCLK_I2S1_8CH_TX_MUX 104 +#define SCLK_I2S1_8CH_RX_MUX 105 +#define SCLK_I2S2_8CH_TX_MUX 106 +#define SCLK_I2S2_8CH_RX_MUX 107 +#define SCLK_I2S3_8CH_TX_MUX 108 +#define SCLK_I2S3_8CH_RX_MUX 109 +#define SCLK_I2S0_8CH_TX_SRC 110 +#define SCLK_I2S0_8CH_RX_SRC 111 +#define SCLK_I2S1_8CH_TX_SRC 112 +#define SCLK_I2S1_8CH_RX_SRC 113 +#define SCLK_I2S2_8CH_TX_SRC 114 +#define SCLK_I2S2_8CH_RX_SRC 115 +#define SCLK_I2S3_8CH_TX_SRC 116 +#define SCLK_I2S3_8CH_RX_SRC 117 +#define SCLK_I2S0_2CH_SRC 118 +#define SCLK_I2S1_2CH_SRC 119 +#define SCLK_PWM1 120 +#define SCLK_PWM2 121 +#define SCLK_OWIRE 122 + +/* dclk */ +#define DCLK_VOP 125 + +/* aclk */ +#define ACLK_BUS_SRC 130 +#define ACLK_BUS 131 +#define ACLK_PERI_SRC 132 +#define ACLK_PERI 133 +#define ACLK_MAC 134 +#define ACLK_CRYPTO 135 +#define ACLK_VOP 136 +#define ACLK_GIC 137 +#define ACLK_DMAC0 138 +#define ACLK_DMAC1 139 + +/* hclk */ +#define HCLK_BUS 150 +#define HCLK_PERI 151 +#define HCLK_AUDIO 152 +#define HCLK_NANDC 153 +#define HCLK_SDMMC 154 +#define HCLK_SDIO 155 +#define HCLK_EMMC 156 +#define HCLK_SFC 157 +#define HCLK_OTG 158 +#define HCLK_HOST 159 +#define HCLK_HOST_ARB 160 +#define HCLK_PDM 161 +#define HCLK_SPDIFTX 162 +#define HCLK_SPDIFRX 163 +#define HCLK_I2S0_8CH 164 +#define HCLK_I2S1_8CH 165 +#define HCLK_I2S2_8CH 166 +#define HCLK_I2S3_8CH 167 +#define HCLK_I2S0_2CH 168 +#define HCLK_I2S1_2CH 169 +#define HCLK_VAD 170 +#define HCLK_CRYPTO 171 +#define HCLK_VOP 172 + +/* pclk */ +#define PCLK_BUS 190 +#define PCLK_DDR 191 +#define PCLK_PERI 192 +#define PCLK_PMU 193 +#define PCLK_AUDIO 194 +#define PCLK_MAC 195 +#define PCLK_ACODEC 196 +#define PCLK_UART0 197 +#define PCLK_UART1 198 +#define PCLK_UART2 199 +#define PCLK_UART3 200 +#define PCLK_UART4 201 +#define PCLK_I2C0 202 +#define PCLK_I2C1 203 +#define PCLK_I2C2 204 +#define PCLK_I2C3 205 +#define PCLK_PWM0 206 +#define PCLK_SPI0 207 +#define PCLK_SPI1 208 +#define PCLK_SPI2 209 +#define PCLK_SARADC 210 +#define PCLK_TSADC 211 +#define PCLK_TIMER 212 +#define PCLK_OTP_NS 213 +#define PCLK_WDT 214 +#define PCLK_GPIO0 215 +#define PCLK_GPIO1 216 +#define PCLK_GPIO2 217 +#define PCLK_GPIO3 218 +#define PCLK_GPIO4 219 +#define PCLK_SGRF 220 +#define PCLK_GRF 221 +#define PCLK_USBSD_DET 222 +#define PCLK_DDR_UPCTL 223 +#define PCLK_DDR_MON 224 +#define PCLK_DDRPHY 225 +#define PCLK_DDR_STDBY 226 +#define PCLK_USB_GRF 227 +#define PCLK_CRU 228 +#define PCLK_OTP_PHY 229 +#define PCLK_CPU_BOOST 230 +#define PCLK_PWM1 231 +#define PCLK_PWM2 232 +#define PCLK_CAN 233 +#define PCLK_OWIRE 234 + +#define CLK_NR_CLKS (PCLK_OWIRE + 1) + +/* soft-reset indices */ + +/* cru_softrst_con0 */ +#define SRST_CORE0_PO 0 +#define SRST_CORE1_PO 1 +#define SRST_CORE2_PO 2 +#define SRST_CORE3_PO 3 +#define SRST_CORE0 4 +#define SRST_CORE1 5 +#define SRST_CORE2 6 +#define SRST_CORE3 7 +#define SRST_CORE0_DBG 8 +#define SRST_CORE1_DBG 9 +#define SRST_CORE2_DBG 10 +#define SRST_CORE3_DBG 11 +#define SRST_TOPDBG 12 +#define SRST_CORE_NOC 13 +#define SRST_STRC_A 14 +#define SRST_L2C 15 + +/* cru_softrst_con1 */ +#define SRST_DAP 16 +#define SRST_CORE_PVTM 17 +#define SRST_CORE_PRF 18 +#define SRST_CORE_GRF 19 +#define SRST_DDRUPCTL 20 +#define SRST_DDRUPCTL_P 22 +#define SRST_MSCH 23 +#define SRST_DDRMON_P 25 +#define SRST_DDRSTDBY_P 26 +#define SRST_DDRSTDBY 27 +#define SRST_DDRPHY 28 +#define SRST_DDRPHY_DIV 29 +#define SRST_DDRPHY_P 30 + +/* cru_softrst_con2 */ +#define SRST_BUS_NIU_H 32 +#define SRST_USB_NIU_P 33 +#define SRST_CRYPTO_A 34 +#define SRST_CRYPTO_H 35 +#define SRST_CRYPTO 36 +#define SRST_CRYPTO_APK 37 +#define SRST_VOP_A 38 +#define SRST_VOP_H 39 +#define SRST_VOP_D 40 +#define SRST_INTMEM_A 41 +#define SRST_ROM_H 42 +#define SRST_GIC_A 43 +#define SRST_UART0_P 44 +#define SRST_UART0 45 +#define SRST_UART1_P 46 +#define SRST_UART1 47 + +/* cru_softrst_con3 */ +#define SRST_UART2_P 48 +#define SRST_UART2 49 +#define SRST_UART3_P 50 +#define SRST_UART3 51 +#define SRST_UART4_P 52 +#define SRST_UART4 53 +#define SRST_I2C0_P 54 +#define SRST_I2C0 55 +#define SRST_I2C1_P 56 +#define SRST_I2C1 57 +#define SRST_I2C2_P 58 +#define SRST_I2C2 59 +#define SRST_I2C3_P 60 +#define SRST_I2C3 61 +#define SRST_PWM0_P 62 +#define SRST_PWM0 63 + +/* cru_softrst_con4 */ +#define SRST_SPI0_P 64 +#define SRST_SPI0 65 +#define SRST_SPI1_P 66 +#define SRST_SPI1 67 +#define SRST_SPI2_P 68 +#define SRST_SPI2 69 +#define SRST_SARADC_P 70 +#define SRST_TSADC_P 71 +#define SRST_TSADC 72 +#define SRST_TIMER0_P 73 +#define SRST_TIMER0 74 +#define SRST_TIMER1 75 +#define SRST_TIMER2 76 +#define SRST_TIMER3 77 +#define SRST_TIMER4 78 +#define SRST_TIMER5 79 + +/* cru_softrst_con5 */ +#define SRST_OTP_NS_P 80 +#define SRST_OTP_NS_SBPI 81 +#define SRST_OTP_NS_USR 82 +#define SRST_OTP_PHY_P 83 +#define SRST_OTP_PHY 84 +#define SRST_GPIO0_P 86 +#define SRST_GPIO1_P 87 +#define SRST_GPIO2_P 88 +#define SRST_GPIO3_P 89 +#define SRST_GPIO4_P 90 +#define SRST_GRF_P 91 +#define SRST_USBSD_DET_P 92 +#define SRST_PMU 93 +#define SRST_PMU_PVTM 94 +#define SRST_USB_GRF_P 95 + +/* cru_softrst_con6 */ +#define SRST_CPU_BOOST 96 +#define SRST_CPU_BOOST_P 97 +#define SRST_PWM1_P 98 +#define SRST_PWM1 99 +#define SRST_PWM2_P 100 +#define SRST_PWM2 101 +#define SRST_PERI_NIU_A 104 +#define SRST_PERI_NIU_H 105 +#define SRST_PERI_NIU_p 106 +#define SRST_USB2OTG_H 107 +#define SRST_USB2OTG 108 +#define SRST_USB2OTG_ADP 109 +#define SRST_USB2HOST_H 110 +#define SRST_USB2HOST_ARB_H 111 + +/* cru_softrst_con7 */ +#define SRST_USB2HOST_AUX_H 112 +#define SRST_USB2HOST_EHCI 113 +#define SRST_USB2HOST 114 +#define SRST_USBPHYPOR 115 +#define SRST_UTMI0 116 +#define SRST_UTMI1 117 +#define SRST_SDIO_H 118 +#define SRST_EMMC_H 119 +#define SRST_SFC_H 120 +#define SRST_SFC 121 +#define SRST_SD_H 122 +#define SRST_NANDC_H 123 +#define SRST_NANDC_N 124 +#define SRST_MAC_A 125 +#define SRST_CAN_P 126 +#define SRST_OWIRE_P 127 + +/* cru_softrst_con8 */ +#define SRST_AUDIO_NIU_H 128 +#define SRST_AUDIO_NIU_P 129 +#define SRST_PDM_H 130 +#define SRST_PDM_M 131 +#define SRST_SPDIFTX_H 132 +#define SRST_SPDIFTX_M 133 +#define SRST_SPDIFRX_H 134 +#define SRST_SPDIFRX_M 135 +#define SRST_I2S0_8CH_H 136 +#define SRST_I2S0_8CH_TX_M 137 +#define SRST_I2S0_8CH_RX_M 138 +#define SRST_I2S1_8CH_H 139 +#define SRST_I2S1_8CH_TX_M 140 +#define SRST_I2S1_8CH_RX_M 141 +#define SRST_I2S2_8CH_H 142 +#define SRST_I2S2_8CH_TX_M 143 + +/* cru_softrst_con9 */ +#define SRST_I2S2_8CH_RX_M 144 +#define SRST_I2S3_8CH_H 145 +#define SRST_I2S3_8CH_TX_M 146 +#define SRST_I2S3_8CH_RX_M 147 +#define SRST_I2S0_2CH_H 148 +#define SRST_I2S0_2CH_M 149 +#define SRST_I2S1_2CH_H 150 +#define SRST_I2S1_2CH_M 151 +#define SRST_VAD_H 152 +#define SRST_ACODEC_P 153 + +#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3308_H__ */ diff --git a/bsp/rockchip/rk3500/driver/clk/rk3568-cru.h b/bsp/rockchip/dm/include/dt-bindings/clock/rk3568-cru.h old mode 100644 new mode 100755 similarity index 99% rename from bsp/rockchip/rk3500/driver/clk/rk3568-cru.h rename to bsp/rockchip/dm/include/dt-bindings/clock/rk3568-cru.h index 00f59f71068..0726668d1bb --- a/bsp/rockchip/rk3500/driver/clk/rk3568-cru.h +++ b/bsp/rockchip/dm/include/dt-bindings/clock/rk3568-cru.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 */ @@ -479,6 +479,12 @@ #define CPLL_25M 416 #define CPLL_100M 417 #define SCLK_DDRCLK 418 +#define I2S1_MCLKOUT 419 +#define I2S3_MCLKOUT 420 +#define I2S1_MCLK_RX_IOE 421 +#define I2S1_MCLK_TX_IOE 422 +#define I2S2_MCLK_IOE 423 +#define I2S3_MCLK_IOE 424 #define PCLK_CORE_PVTM 450 diff --git a/bsp/rockchip/dm/include/dt-bindings/clock/rk3576-cru.h b/bsp/rockchip/dm/include/dt-bindings/clock/rk3576-cru.h new file mode 100755 index 00000000000..a686474d0e3 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/clock/rk3576-cru.h @@ -0,0 +1,1151 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_CLK_ROCKCHIP_RK3576_H__ +#define __DT_BINDINGS_CLK_ROCKCHIP_RK3576_H__ + +/* cru-clocks indices */ + +/* cru plls */ +#define PLL_BPLL 1 +#define PLL_LPLL 3 +#define PLL_VPLL 4 +#define PLL_AUPLL 5 +#define PLL_CPLL 6 +#define PLL_GPLL 7 +#define PLL_PPLL 9 +#define ARMCLK_L 10 +#define ARMCLK_B 11 + +/* cru clocks */ +#define CLK_CPLL_DIV20 15 +#define CLK_CPLL_DIV10 16 +#define CLK_GPLL_DIV8 17 +#define CLK_GPLL_DIV6 18 +#define CLK_CPLL_DIV4 19 +#define CLK_GPLL_DIV4 20 +#define CLK_SPLL_DIV2 21 +#define CLK_GPLL_DIV3 22 +#define CLK_CPLL_DIV2 23 +#define CLK_GPLL_DIV2 24 +#define CLK_SPLL_DIV1 25 +#define PCLK_TOP_ROOT 26 +#define ACLK_TOP 27 +#define HCLK_TOP 28 +#define CLK_AUDIO_FRAC_0 29 +#define CLK_AUDIO_FRAC_1 30 +#define CLK_AUDIO_FRAC_2 31 +#define CLK_AUDIO_FRAC_3 32 +#define CLK_UART_FRAC_0 33 +#define CLK_UART_FRAC_1 34 +#define CLK_UART_FRAC_2 35 +#define CLK_UART1_SRC_TOP 36 +#define CLK_AUDIO_INT_0 37 +#define CLK_AUDIO_INT_1 38 +#define CLK_AUDIO_INT_2 39 +#define CLK_PDM0_SRC_TOP 40 +#define CLK_PDM1_OUT 41 +#define CLK_GMAC0_125M_SRC 42 +#define CLK_GMAC1_125M_SRC 43 +#define LCLK_ASRC_SRC_0 44 +#define LCLK_ASRC_SRC_1 45 +#define REF_CLK0_OUT_PLL 46 +#define REF_CLK1_OUT_PLL 47 +#define REF_CLK2_OUT_PLL 48 +#define REFCLKO25M_GMAC0_OUT 49 +#define REFCLKO25M_GMAC1_OUT 50 +#define CLK_CIFOUT_OUT 51 +#define CLK_GMAC0_RMII_CRU 52 +#define CLK_GMAC1_RMII_CRU 53 +#define CLK_OTPC_AUTO_RD_G 54 +#define CLK_OTP_PHY_G 55 +#define CLK_MIPI_CAMERAOUT_M0 56 +#define CLK_MIPI_CAMERAOUT_M1 57 +#define CLK_MIPI_CAMERAOUT_M2 58 +#define MCLK_PDM0_SRC_TOP 59 +#define HCLK_AUDIO_ROOT 60 +#define HCLK_ASRC_2CH_0 61 +#define HCLK_ASRC_2CH_1 62 +#define HCLK_ASRC_4CH_0 63 +#define HCLK_ASRC_4CH_1 64 +#define CLK_ASRC_2CH_0 65 +#define CLK_ASRC_2CH_1 66 +#define CLK_ASRC_4CH_0 67 +#define CLK_ASRC_4CH_1 68 +#define MCLK_SAI0_8CH_SRC 69 +#define MCLK_SAI0_8CH 70 +#define HCLK_SAI0_8CH 71 +#define HCLK_SPDIF_RX0 72 +#define MCLK_SPDIF_RX0 73 +#define HCLK_SPDIF_RX1 74 +#define MCLK_SPDIF_RX1 75 +#define MCLK_SAI1_8CH_SRC 76 +#define MCLK_SAI1_8CH 77 +#define HCLK_SAI1_8CH 78 +#define MCLK_SAI2_2CH_SRC 79 +#define MCLK_SAI2_2CH 80 +#define HCLK_SAI2_2CH 81 +#define MCLK_SAI3_2CH_SRC 82 +#define MCLK_SAI3_2CH 83 +#define HCLK_SAI3_2CH 84 +#define MCLK_SAI4_2CH_SRC 85 +#define MCLK_SAI4_2CH 86 +#define HCLK_SAI4_2CH 87 +#define HCLK_ACDCDIG_DSM 88 +#define MCLK_ACDCDIG_DSM 89 +#define CLK_PDM1 90 +#define HCLK_PDM1 91 +#define MCLK_PDM1 92 +#define HCLK_SPDIF_TX0 93 +#define MCLK_SPDIF_TX0 94 +#define HCLK_SPDIF_TX1 95 +#define MCLK_SPDIF_TX1 96 +#define CLK_SAI1_MCLKOUT 97 +#define CLK_SAI2_MCLKOUT 98 +#define CLK_SAI3_MCLKOUT 99 +#define CLK_SAI4_MCLKOUT 100 +#define CLK_SAI0_MCLKOUT 101 +#define HCLK_BUS_ROOT 102 +#define PCLK_BUS_ROOT 103 +#define ACLK_BUS_ROOT 104 +#define HCLK_CAN0 105 +#define CLK_CAN0 106 +#define HCLK_CAN1 107 +#define CLK_CAN1 108 +#define CLK_KEY_SHIFT 109 +#define PCLK_I2C1 110 +#define PCLK_I2C2 111 +#define PCLK_I2C3 112 +#define PCLK_I2C4 113 +#define PCLK_I2C5 114 +#define PCLK_I2C6 115 +#define PCLK_I2C7 116 +#define PCLK_I2C8 117 +#define PCLK_I2C9 118 +#define PCLK_WDT_BUSMCU 119 +#define TCLK_WDT_BUSMCU 120 +#define ACLK_GIC 121 +#define CLK_I2C1 122 +#define CLK_I2C2 123 +#define CLK_I2C3 124 +#define CLK_I2C4 125 +#define CLK_I2C5 126 +#define CLK_I2C6 127 +#define CLK_I2C7 128 +#define CLK_I2C8 129 +#define CLK_I2C9 130 +#define PCLK_SARADC 131 +#define CLK_SARADC 132 +#define PCLK_TSADC 133 +#define CLK_TSADC 134 +#define PCLK_UART0 135 +#define PCLK_UART2 136 +#define PCLK_UART3 137 +#define PCLK_UART4 138 +#define PCLK_UART5 139 +#define PCLK_UART6 140 +#define PCLK_UART7 141 +#define PCLK_UART8 142 +#define PCLK_UART9 143 +#define PCLK_UART10 144 +#define PCLK_UART11 145 +#define SCLK_UART0 146 +#define SCLK_UART2 147 +#define SCLK_UART3 148 +#define SCLK_UART4 149 +#define SCLK_UART5 150 +#define SCLK_UART6 151 +#define SCLK_UART7 152 +#define SCLK_UART8 153 +#define SCLK_UART9 154 +#define SCLK_UART10 155 +#define SCLK_UART11 156 +#define PCLK_SPI0 157 +#define PCLK_SPI1 158 +#define PCLK_SPI2 159 +#define PCLK_SPI3 160 +#define PCLK_SPI4 161 +#define CLK_SPI0 162 +#define CLK_SPI1 163 +#define CLK_SPI2 164 +#define CLK_SPI3 165 +#define CLK_SPI4 166 +#define PCLK_WDT0 167 +#define TCLK_WDT0 168 +#define PCLK_PWM1 169 +#define CLK_PWM1 170 +#define CLK_OSC_PWM1 171 +#define CLK_RC_PWM1 172 +#define PCLK_BUSTIMER0 173 +#define PCLK_BUSTIMER1 174 +#define CLK_TIMER0_ROOT 175 +#define CLK_TIMER0 176 +#define CLK_TIMER1 177 +#define CLK_TIMER2 178 +#define CLK_TIMER3 179 +#define CLK_TIMER4 180 +#define CLK_TIMER5 181 +#define PCLK_MAILBOX0 182 +#define PCLK_GPIO1 183 +#define DBCLK_GPIO1 184 +#define PCLK_GPIO2 185 +#define DBCLK_GPIO2 186 +#define PCLK_GPIO3 187 +#define DBCLK_GPIO3 188 +#define PCLK_GPIO4 189 +#define DBCLK_GPIO4 190 +#define ACLK_DECOM 191 +#define PCLK_DECOM 192 +#define DCLK_DECOM 193 +#define CLK_TIMER1_ROOT 194 +#define CLK_TIMER6 195 +#define CLK_TIMER7 196 +#define CLK_TIMER8 197 +#define CLK_TIMER9 198 +#define CLK_TIMER10 199 +#define CLK_TIMER11 200 +#define ACLK_DMAC0 201 +#define ACLK_DMAC1 202 +#define ACLK_DMAC2 203 +#define ACLK_SPINLOCK 204 +#define HCLK_I3C0 205 +#define HCLK_I3C1 206 +#define HCLK_BUS_CM0_ROOT 207 +#define FCLK_BUS_CM0_CORE 208 +#define CLK_BUS_CM0_RTC 209 +#define PCLK_PMU2 210 +#define PCLK_PWM2 211 +#define CLK_PWM2 212 +#define CLK_RC_PWM2 213 +#define CLK_OSC_PWM2 214 +#define CLK_FREQ_PWM1 215 +#define CLK_COUNTER_PWM1 216 +#define SAI_SCLKIN_FREQ 217 +#define SAI_SCLKIN_COUNTER 218 +#define CLK_I3C0 219 +#define CLK_I3C1 220 +#define PCLK_CSIDPHY1 221 +#define PCLK_DDR_ROOT 222 +#define PCLK_DDR_MON_CH0 223 +#define TMCLK_DDR_MON_CH0 224 +#define ACLK_DDR_ROOT 225 +#define HCLK_DDR_ROOT 226 +#define FCLK_DDR_CM0_CORE 227 +#define CLK_DDR_TIMER_ROOT 228 +#define CLK_DDR_TIMER0 229 +#define CLK_DDR_TIMER1 230 +#define TCLK_WDT_DDR 231 +#define PCLK_WDT 232 +#define PCLK_TIMER 233 +#define CLK_DDR_CM0_RTC 234 +#define ACLK_RKNN0 235 +#define ACLK_RKNN1 236 +#define HCLK_RKNN_ROOT 237 +#define CLK_RKNN_DSU0 238 +#define PCLK_NPUTOP_ROOT 239 +#define PCLK_NPU_TIMER 240 +#define CLK_NPUTIMER_ROOT 241 +#define CLK_NPUTIMER0 242 +#define CLK_NPUTIMER1 243 +#define PCLK_NPU_WDT 244 +#define TCLK_NPU_WDT 245 +#define ACLK_RKNN_CBUF 246 +#define HCLK_NPU_CM0_ROOT 247 +#define FCLK_NPU_CM0_CORE 248 +#define CLK_NPU_CM0_RTC 249 +#define HCLK_RKNN_CBUF 250 +#define HCLK_NVM_ROOT 251 +#define ACLK_NVM_ROOT 252 +#define SCLK_FSPI_X2 253 +#define HCLK_FSPI 254 +#define CCLK_SRC_EMMC 255 +#define HCLK_EMMC 256 +#define ACLK_EMMC 257 +#define BCLK_EMMC 258 +#define TCLK_EMMC 259 +#define PCLK_PHP_ROOT 260 +#define ACLK_PHP_ROOT 261 +#define PCLK_PCIE0 262 +#define CLK_PCIE0_AUX 263 +#define ACLK_PCIE0_MST 264 +#define ACLK_PCIE0_SLV 265 +#define ACLK_PCIE0_DBI 266 +#define ACLK_USB3OTG1 267 +#define CLK_REF_USB3OTG1 268 +#define CLK_SUSPEND_USB3OTG1 269 +#define ACLK_MMU0 270 +#define ACLK_SLV_MMU0 271 +#define ACLK_MMU1 272 +#define ACLK_SLV_MMU1 273 +#define PCLK_PCIE1 275 +#define CLK_PCIE1_AUX 276 +#define ACLK_PCIE1_MST 277 +#define ACLK_PCIE1_SLV 278 +#define ACLK_PCIE1_DBI 279 +#define CLK_RXOOB0 280 +#define CLK_RXOOB1 281 +#define CLK_PMALIVE0 282 +#define CLK_PMALIVE1 283 +#define ACLK_SATA0 284 +#define ACLK_SATA1 285 +#define CLK_USB3OTG1_PIPE_PCLK 286 +#define CLK_USB3OTG1_UTMI 287 +#define CLK_USB3OTG0_PIPE_PCLK 288 +#define CLK_USB3OTG0_UTMI 289 +#define HCLK_SDGMAC_ROOT 290 +#define ACLK_SDGMAC_ROOT 291 +#define PCLK_SDGMAC_ROOT 292 +#define ACLK_GMAC0 293 +#define ACLK_GMAC1 294 +#define PCLK_GMAC0 295 +#define PCLK_GMAC1 296 +#define CCLK_SRC_SDIO 297 +#define HCLK_SDIO 298 +#define CLK_GMAC1_PTP_REF 299 +#define CLK_GMAC0_PTP_REF 300 +#define CLK_GMAC1_PTP_REF_SRC 301 +#define CLK_GMAC0_PTP_REF_SRC 302 +#define CCLK_SRC_SDMMC0 303 +#define HCLK_SDMMC0 304 +#define SCLK_FSPI1_X2 305 +#define HCLK_FSPI1 306 +#define ACLK_DSMC_ROOT 307 +#define ACLK_DSMC 308 +#define PCLK_DSMC 309 +#define CLK_DSMC_SYS 310 +#define HCLK_HSGPIO 311 +#define CLK_HSGPIO_TX 312 +#define CLK_HSGPIO_RX 313 +#define ACLK_HSGPIO 314 +#define PCLK_PHPPHY_ROOT 315 +#define PCLK_PCIE2_COMBOPHY0 316 +#define PCLK_PCIE2_COMBOPHY1 317 +#define CLK_PCIE_100M_SRC 318 +#define CLK_PCIE_100M_NDUTY_SRC 319 +#define CLK_REF_PCIE0_PHY 320 +#define CLK_REF_PCIE1_PHY 321 +#define CLK_REF_MPHY_26M 322 +#define HCLK_RKVDEC_ROOT 323 +#define ACLK_RKVDEC_ROOT 324 +#define HCLK_RKVDEC 325 +#define CLK_RKVDEC_HEVC_CA 326 +#define CLK_RKVDEC_CORE 327 +#define ACLK_UFS_ROOT 328 +#define ACLK_USB_ROOT 329 +#define PCLK_USB_ROOT 330 +#define ACLK_USB3OTG0 331 +#define CLK_REF_USB3OTG0 332 +#define CLK_SUSPEND_USB3OTG0 333 +#define ACLK_MMU2 334 +#define ACLK_SLV_MMU2 335 +#define ACLK_UFS_SYS 336 +#define ACLK_VPU_ROOT 337 +#define ACLK_VPU_MID_ROOT 338 +#define HCLK_VPU_ROOT 339 +#define ACLK_JPEG_ROOT 340 +#define ACLK_VPU_LOW_ROOT 341 +#define HCLK_RGA2E_0 342 +#define ACLK_RGA2E_0 343 +#define CLK_CORE_RGA2E_0 344 +#define ACLK_JPEG 345 +#define HCLK_JPEG 346 +#define HCLK_VDPP 347 +#define ACLK_VDPP 348 +#define CLK_CORE_VDPP 349 +#define HCLK_RGA2E_1 350 +#define ACLK_RGA2E_1 351 +#define CLK_CORE_RGA2E_1 352 +#define DCLK_EBC_FRAC_SRC 353 +#define HCLK_EBC 354 +#define ACLK_EBC 355 +#define DCLK_EBC 356 +#define HCLK_VEPU0_ROOT 357 +#define ACLK_VEPU0_ROOT 358 +#define HCLK_VEPU0 359 +#define ACLK_VEPU0 360 +#define CLK_VEPU0_CORE 361 +#define ACLK_VI_ROOT 362 +#define HCLK_VI_ROOT 363 +#define PCLK_VI_ROOT 364 +#define DCLK_VICAP 365 +#define ACLK_VICAP 366 +#define HCLK_VICAP 367 +#define CLK_ISP_CORE 368 +#define CLK_ISP_CORE_MARVIN 369 +#define CLK_ISP_CORE_VICAP 370 +#define ACLK_ISP 371 +#define HCLK_ISP 372 +#define ACLK_VPSS 373 +#define HCLK_VPSS 374 +#define CLK_CORE_VPSS 375 +#define PCLK_CSI_HOST_0 376 +#define PCLK_CSI_HOST_1 377 +#define PCLK_CSI_HOST_2 378 +#define PCLK_CSI_HOST_3 379 +#define PCLK_CSI_HOST_4 380 +#define ICLK_CSIHOST01 381 +#define ICLK_CSIHOST0 382 +#define CLK_ISP_PVTPLL_SRC 383 +#define ACLK_VI_ROOT_INTER 384 +#define CLK_VICAP_I0CLK 385 +#define CLK_VICAP_I1CLK 386 +#define CLK_VICAP_I2CLK 387 +#define CLK_VICAP_I3CLK 388 +#define CLK_VICAP_I4CLK 389 +#define ACLK_VOP_ROOT 390 +#define HCLK_VOP_ROOT 391 +#define PCLK_VOP_ROOT 392 +#define HCLK_VOP 393 +#define ACLK_VOP 394 +#define DCLK_VP0_SRC 395 +#define DCLK_VP1_SRC 396 +#define DCLK_VP2_SRC 397 +#define DCLK_VP0 398 +#define DCLK_VP1 400 +#define DCLK_VP2 401 +#define PCLK_VOPGRF 402 +#define ACLK_VO0_ROOT 403 +#define HCLK_VO0_ROOT 404 +#define PCLK_VO0_ROOT 405 +#define PCLK_VO0_GRF 406 +#define ACLK_HDCP0 407 +#define HCLK_HDCP0 408 +#define PCLK_HDCP0 409 +#define CLK_TRNG0_SKP 410 +#define PCLK_DSIHOST0 411 +#define CLK_DSIHOST0 412 +#define PCLK_HDMITX0 413 +#define CLK_HDMITX0_EARC 414 +#define CLK_HDMITX0_REF 415 +#define PCLK_EDP0 416 +#define CLK_EDP0_24M 417 +#define CLK_EDP0_200M 418 +#define MCLK_SAI5_8CH_SRC 419 +#define MCLK_SAI5_8CH 420 +#define HCLK_SAI5_8CH 421 +#define MCLK_SAI6_8CH_SRC 422 +#define MCLK_SAI6_8CH 423 +#define HCLK_SAI6_8CH 424 +#define HCLK_SPDIF_TX2 425 +#define MCLK_SPDIF_TX2 426 +#define HCLK_SPDIF_RX2 427 +#define MCLK_SPDIF_RX2 428 +#define HCLK_SAI8_8CH 429 +#define MCLK_SAI8_8CH_SRC 430 +#define MCLK_SAI8_8CH 431 +#define ACLK_VO1_ROOT 432 +#define HCLK_VO1_ROOT 433 +#define PCLK_VO1_ROOT 434 +#define MCLK_SAI7_8CH_SRC 435 +#define MCLK_SAI7_8CH 436 +#define HCLK_SAI7_8CH 437 +#define HCLK_SPDIF_TX3 438 +#define HCLK_SPDIF_TX4 439 +#define HCLK_SPDIF_TX5 440 +#define MCLK_SPDIF_TX3 441 +#define CLK_AUX16MHZ_0 442 +#define ACLK_DP0 443 +#define PCLK_DP0 444 +#define PCLK_VO1_GRF 445 +#define ACLK_HDCP1 446 +#define HCLK_HDCP1 447 +#define PCLK_HDCP1 448 +#define CLK_TRNG1_SKP 449 +#define HCLK_SAI9_8CH 450 +#define MCLK_SAI9_8CH_SRC 451 +#define MCLK_SAI9_8CH 452 +#define MCLK_SPDIF_TX4 453 +#define MCLK_SPDIF_TX5 454 +#define CLK_GPU_SRC_PRE 455 +#define CLK_GPU 456 +#define PCLK_GPU_ROOT 457 +#define ACLK_CENTER_ROOT 458 +#define ACLK_CENTER_LOW_ROOT 459 +#define HCLK_CENTER_ROOT 460 +#define PCLK_CENTER_ROOT 461 +#define ACLK_DMA2DDR 462 +#define ACLK_DDR_SHAREMEM 463 +#define PCLK_DMA2DDR 464 +#define PCLK_SHAREMEM 465 +#define HCLK_VEPU1_ROOT 466 +#define ACLK_VEPU1_ROOT 467 +#define HCLK_VEPU1 468 +#define ACLK_VEPU1 469 +#define CLK_VEPU1_CORE 470 +#define CLK_JDBCK_DAP 471 +#define PCLK_MIPI_DCPHY 472 +#define CLK_32K_USB2DEBUG 473 +#define PCLK_CSIDPHY 474 +#define PCLK_USBDPPHY 475 +#define CLK_PMUPHY_REF_SRC 476 +#define CLK_USBDP_COMBO_PHY_IMMORTAL 477 +#define CLK_HDMITXHPD 478 +#define PCLK_MPHY 479 +#define CLK_REF_OSC_MPHY 480 +#define CLK_REF_UFS_CLKOUT 481 +#define HCLK_PMU1_ROOT 482 +#define HCLK_PMU_CM0_ROOT 483 +#define CLK_200M_PMU_SRC 484 +#define CLK_100M_PMU_SRC 485 +#define CLK_50M_PMU_SRC 486 +#define FCLK_PMU_CM0_CORE 487 +#define CLK_PMU_CM0_RTC 488 +#define PCLK_PMU1 489 +#define CLK_PMU1 490 +#define PCLK_PMU1WDT 491 +#define TCLK_PMU1WDT 492 +#define PCLK_PMUTIMER 493 +#define CLK_PMUTIMER_ROOT 494 +#define CLK_PMUTIMER0 495 +#define CLK_PMUTIMER1 496 +#define PCLK_PMU1PWM 497 +#define CLK_PMU1PWM 498 +#define CLK_PMU1PWM_OSC 499 +#define PCLK_PMUPHY_ROOT 500 +#define PCLK_I2C0 501 +#define CLK_I2C0 502 +#define SCLK_UART1 503 +#define PCLK_UART1 504 +#define CLK_PMU1PWM_RC 505 +#define CLK_PDM0 506 +#define HCLK_PDM0 507 +#define MCLK_PDM0 508 +#define HCLK_VAD 509 +#define CLK_OSCCHK_PVTM 510 +#define CLK_PDM0_OUT 511 +#define CLK_HPTIMER_SRC 512 +#define PCLK_PMU0_ROOT 516 +#define PCLK_PMU0 517 +#define PCLK_GPIO0 518 +#define DBCLK_GPIO0 519 +#define CLK_OSC0_PMU1 520 +#define PCLK_PMU1_ROOT 521 +#define XIN_OSC0_DIV 522 +#define ACLK_USB 523 +#define ACLK_UFS 524 +#define ACLK_SDGMAC 525 +#define HCLK_SDGMAC 526 +#define PCLK_SDGMAC 527 +#define HCLK_VO1 528 +#define HCLK_VO0 529 +#define PCLK_CCI_ROOT 532 +#define ACLK_CCI_ROOT 533 +#define HCLK_VO0VOP_CHANNEL 534 +#define ACLK_VO0VOP_CHANNEL 535 +#define ACLK_TOP_MID 536 +#define ACLK_SECURE_HIGH 537 +#define CLK_USBPHY_REF_SRC 538 +#define CLK_PHY_REF_SRC 539 +#define CLK_CPLL_REF_SRC 540 +#define CLK_AUPLL_REF_SRC 541 +#define PCLK_SECURE_NS 542 +#define HCLK_SECURE_NS 543 +#define ACLK_SECURE_NS 544 +#define PCLK_OTPC_NS 545 +#define HCLK_CRYPTO_NS 546 +#define HCLK_TRNG_NS 547 +#define CLK_OTPC_NS 548 +#define SCLK_DSU 549 +#define SCLK_DDR 550 +#define ACLK_CRYPTO_NS 551 +#define CLK_PKA_CRYPTO_NS 552 +#define ACLK_RKVDEC_ROOT_BAK 553 +#define CLK_AUDIO_FRAC_0_SRC 554 +#define CLK_AUDIO_FRAC_1_SRC 555 +#define CLK_AUDIO_FRAC_2_SRC 556 +#define CLK_AUDIO_FRAC_3_SRC 557 +#define PCLK_HDPTX_APB 558 +#define PCLK_DDR_MON_CH1 559 + +/* secure clk */ +#define CLK_STIMER0_ROOT 600 +#define CLK_STIMER1_ROOT 601 +#define PCLK_SECURE_S 602 +#define HCLK_SECURE_S 603 +#define ACLK_SECURE_S 604 +#define CLK_PKA_CRYPTO_S 605 +#define HCLK_VO1_S 606 +#define PCLK_VO1_S 607 +#define HCLK_VO0_S 608 +#define PCLK_VO0_S 609 +#define PCLK_KLAD 610 +#define HCLK_CRYPTO_S 611 +#define HCLK_KLAD 612 +#define ACLK_CRYPTO_S 613 +#define HCLK_TRNG_S 614 +#define PCLK_OTPC_S 615 +#define CLK_OTPC_S 616 +#define PCLK_WDT_S 617 +#define TCLK_WDT_S 618 +#define PCLK_HDCP0_TRNG 619 +#define PCLK_HDCP1_TRNG 620 +#define HCLK_HDCP_KEY0 621 +#define HCLK_HDCP_KEY1 622 +#define PCLK_EDP_S 623 +#define ACLK_KLAD 624 + +#define CLK_NR_CLKS (ACLK_KLAD + 1) + +/********Name=SOFTRST_CON01,Offset=0xA04********/ +#define SRST_A_TOP_BIU 19 +#define SRST_P_TOP_BIU 21 +#define SRST_A_TOP_MID_BIU 22 +#define SRST_A_SECURE_HIGH_BIU 23 +#define SRST_H_TOP_BIU 30 +/********Name=SOFTRST_CON02,Offset=0xA08********/ +#define SRST_H_VO0VOP_CHANNEL_BIU 32 +#define SRST_A_VO0VOP_CHANNEL_BIU 33 +/********Name=SOFTRST_CON06,Offset=0xA18********/ +#define SRST_BISRINTF 98 +/********Name=SOFTRST_CON07,Offset=0xA1C********/ +#define SRST_H_AUDIO_BIU 114 +#define SRST_H_ASRC_2CH_0 115 +#define SRST_H_ASRC_2CH_1 116 +#define SRST_H_ASRC_4CH_0 117 +#define SRST_H_ASRC_4CH_1 118 +#define SRST_ASRC_2CH_0 119 +#define SRST_ASRC_2CH_1 120 +#define SRST_ASRC_4CH_0 121 +#define SRST_ASRC_4CH_1 122 +#define SRST_M_SAI0_8CH 124 +#define SRST_H_SAI0_8CH 125 +#define SRST_H_SPDIF_RX0 126 +#define SRST_M_SPDIF_RX0 127 +/********Name=SOFTRST_CON08,Offset=0xA20********/ +#define SRST_H_SPDIF_RX1 128 +#define SRST_M_SPDIF_RX1 129 +#define SRST_M_SAI1_8CH 133 +#define SRST_H_SAI1_8CH 134 +#define SRST_M_SAI2_2CH 136 +#define SRST_H_SAI2_2CH 138 +#define SRST_M_SAI3_2CH 140 +#define SRST_H_SAI3_2CH 142 +/********Name=SOFTRST_CON09,Offset=0xA24********/ +#define SRST_M_SAI4_2CH 144 +#define SRST_H_SAI4_2CH 146 +#define SRST_H_ACDCDIG_DSM 147 +#define SRST_M_ACDCDIG_DSM 148 +#define SRST_PDM1 149 +#define SRST_H_PDM1 151 +#define SRST_M_PDM1 152 +#define SRST_H_SPDIF_TX0 153 +#define SRST_M_SPDIF_TX0 154 +#define SRST_H_SPDIF_TX1 155 +#define SRST_M_SPDIF_TX1 156 +/********Name=SOFTRST_CON11,Offset=0xA2C********/ +#define SRST_A_BUS_BIU 179 +#define SRST_P_BUS_BIU 180 +#define SRST_P_CRU 181 +#define SRST_H_CAN0 182 +#define SRST_CAN0 183 +#define SRST_H_CAN1 184 +#define SRST_CAN1 185 +#define SRST_P_INTMUX2BUS 188 +#define SRST_P_VCCIO_IOC 189 +#define SRST_H_BUS_BIU 190 +#define SRST_KEY_SHIFT 191 +/********Name=SOFTRST_CON12,Offset=0xA30********/ +#define SRST_P_I2C1 192 +#define SRST_P_I2C2 193 +#define SRST_P_I2C3 194 +#define SRST_P_I2C4 195 +#define SRST_P_I2C5 196 +#define SRST_P_I2C6 197 +#define SRST_P_I2C7 198 +#define SRST_P_I2C8 199 +#define SRST_P_I2C9 200 +#define SRST_P_WDT_BUSMCU 201 +#define SRST_T_WDT_BUSMCU 202 +#define SRST_A_GIC 203 +#define SRST_I2C1 204 +#define SRST_I2C2 205 +#define SRST_I2C3 206 +#define SRST_I2C4 207 +/********Name=SOFTRST_CON13,Offset=0xA34********/ +#define SRST_I2C5 208 +#define SRST_I2C6 209 +#define SRST_I2C7 210 +#define SRST_I2C8 211 +#define SRST_I2C9 212 +#define SRST_P_SARADC 214 +#define SRST_SARADC 215 +#define SRST_P_TSADC 216 +#define SRST_TSADC 217 +#define SRST_P_UART0 218 +#define SRST_P_UART2 219 +#define SRST_P_UART3 220 +#define SRST_P_UART4 221 +#define SRST_P_UART5 222 +#define SRST_P_UART6 223 +/********Name=SOFTRST_CON14,Offset=0xA38********/ +#define SRST_P_UART7 224 +#define SRST_P_UART8 225 +#define SRST_P_UART9 226 +#define SRST_P_UART10 227 +#define SRST_P_UART11 228 +#define SRST_S_UART0 229 +#define SRST_S_UART2 230 +#define SRST_S_UART3 233 +#define SRST_S_UART4 236 +#define SRST_S_UART5 239 +/********Name=SOFTRST_CON15,Offset=0xA3C********/ +#define SRST_S_UART6 242 +#define SRST_S_UART7 245 +#define SRST_S_UART8 248 +#define SRST_S_UART9 249 +#define SRST_S_UART10 250 +#define SRST_S_UART11 251 +#define SRST_P_SPI0 253 +#define SRST_P_SPI1 254 +#define SRST_P_SPI2 255 +/********Name=SOFTRST_CON16,Offset=0xA40********/ +#define SRST_P_SPI3 256 +#define SRST_P_SPI4 257 +#define SRST_SPI0 258 +#define SRST_SPI1 259 +#define SRST_SPI2 260 +#define SRST_SPI3 261 +#define SRST_SPI4 262 +#define SRST_P_WDT0 263 +#define SRST_T_WDT0 264 +#define SRST_P_SYS_GRF 265 +#define SRST_P_PWM1 266 +#define SRST_PWM1 267 + +/********Name=SOFTRST_CON17,Offset=0xA44********/ +#define SRST_P_BUSTIMER0 275 +#define SRST_P_BUSTIMER1 276 +#define SRST_TIMER0 278 +#define SRST_TIMER1 279 +#define SRST_TIMER2 280 +#define SRST_TIMER3 281 +#define SRST_TIMER4 282 +#define SRST_TIMER5 283 +#define SRST_P_BUSIOC 284 +#define SRST_P_MAILBOX0 285 +#define SRST_P_GPIO1 287 +/********Name=SOFTRST_CON18,Offset=0xA48********/ +#define SRST_GPIO1 288 +#define SRST_P_GPIO2 289 +#define SRST_GPIO2 290 +#define SRST_P_GPIO3 291 +#define SRST_GPIO3 292 +#define SRST_P_GPIO4 293 +#define SRST_GPIO4 294 +#define SRST_A_DECOM 295 +#define SRST_P_DECOM 296 +#define SRST_D_DECOM 297 +#define SRST_TIMER6 299 +#define SRST_TIMER7 300 +#define SRST_TIMER8 301 +#define SRST_TIMER9 302 +#define SRST_TIMER10 303 +/********Name=SOFTRST_CON19,Offset=0xA4C********/ +#define SRST_TIMER11 304 +#define SRST_A_DMAC0 305 +#define SRST_A_DMAC1 306 +#define SRST_A_DMAC2 307 +#define SRST_A_SPINLOCK 308 +#define SRST_REF_PVTPLL_BUS 309 +#define SRST_H_I3C0 311 +#define SRST_H_I3C1 313 +#define SRST_H_BUS_CM0_BIU 315 +#define SRST_F_BUS_CM0_CORE 316 +#define SRST_T_BUS_CM0_JTAG 317 +/********Name=SOFTRST_CON20,Offset=0xA50********/ +#define SRST_P_INTMUX2PMU 320 +#define SRST_P_INTMUX2DDR 321 +#define SRST_P_PVTPLL_BUS 323 +#define SRST_P_PWM2 324 +#define SRST_PWM2 325 +#define SRST_FREQ_PWM1 328 +#define SRST_COUNTER_PWM1 329 +#define SRST_I3C0 332 +#define SRST_I3C1 333 +/********Name=SOFTRST_CON21,Offset=0xA54********/ +#define SRST_P_DDR_MON_CH0 337 +#define SRST_P_DDR_BIU 338 +#define SRST_P_DDR_UPCTL_CH0 339 +#define SRST_TM_DDR_MON_CH0 340 +#define SRST_A_DDR_BIU 341 +#define SRST_DFI_CH0 342 +#define SRST_DDR_MON_CH0 346 +#define SRST_P_DDR_HWLP_CH0 349 +#define SRST_P_DDR_MON_CH1 350 +#define SRST_P_DDR_HWLP_CH1 351 +/********Name=SOFTRST_CON22,Offset=0xA58********/ +#define SRST_P_DDR_UPCTL_CH1 352 +#define SRST_TM_DDR_MON_CH1 353 +#define SRST_DFI_CH1 354 +#define SRST_A_DDR01_MSCH0 355 +#define SRST_A_DDR01_MSCH1 356 +#define SRST_DDR_MON_CH1 358 +#define SRST_DDR_SCRAMBLE_CH0 361 +#define SRST_DDR_SCRAMBLE_CH1 362 +#define SRST_P_AHB2APB 364 +#define SRST_H_AHB2APB 365 +#define SRST_H_DDR_BIU 366 +#define SRST_F_DDR_CM0_CORE 367 +/********Name=SOFTRST_CON23,Offset=0xA5C********/ +#define SRST_P_DDR01_MSCH0 369 +#define SRST_P_DDR01_MSCH1 370 +#define SRST_DDR_TIMER0 372 +#define SRST_DDR_TIMER1 373 +#define SRST_T_WDT_DDR 374 +#define SRST_P_WDT 375 +#define SRST_P_TIMER 376 +#define SRST_T_DDR_CM0_JTAG 377 +#define SRST_P_DDR_GRF 379 +/********Name=SOFTRST_CON25,Offset=0xA64********/ +#define SRST_DDR_UPCTL_CH0 401 +#define SRST_A_DDR_UPCTL_0_CH0 402 +#define SRST_A_DDR_UPCTL_1_CH0 403 +#define SRST_A_DDR_UPCTL_2_CH0 404 +#define SRST_A_DDR_UPCTL_3_CH0 405 +#define SRST_A_DDR_UPCTL_4_CH0 406 +/********Name=SOFTRST_CON26,Offset=0xA68********/ +#define SRST_DDR_UPCTL_CH1 417 +#define SRST_A_DDR_UPCTL_0_CH1 418 +#define SRST_A_DDR_UPCTL_1_CH1 419 +#define SRST_A_DDR_UPCTL_2_CH1 420 +#define SRST_A_DDR_UPCTL_3_CH1 421 +#define SRST_A_DDR_UPCTL_4_CH1 422 +/********Name=SOFTRST_CON27,Offset=0xA6C********/ +#define SRST_REF_PVTPLL_DDR 432 +#define SRST_P_PVTPLL_DDR 433 + +/********Name=SOFTRST_CON28,Offset=0xA70********/ +#define SRST_A_RKNN0 457 +#define SRST_A_RKNN0_BIU 459 +#define SRST_L_RKNN0_BIU 460 +/********Name=SOFTRST_CON29,Offset=0xA74********/ +#define SRST_A_RKNN1 464 +#define SRST_A_RKNN1_BIU 466 +#define SRST_L_RKNN1_BIU 467 +/********Name=SOFTRST_CON31,Offset=0xA7C********/ +#define SRST_NPU_DAP 496 +#define SRST_L_NPUSUBSYS_BIU 497 +#define SRST_P_NPUTOP_BIU 505 +#define SRST_P_NPU_TIMER 506 +#define SRST_NPUTIMER0 508 +#define SRST_NPUTIMER1 509 +#define SRST_P_NPU_WDT 510 +#define SRST_T_NPU_WDT 511 +/********Name=SOFTRST_CON32,Offset=0xA80********/ +#define SRST_A_RKNN_CBUF 512 +#define SRST_A_RVCORE0 513 +#define SRST_P_NPU_GRF 514 +#define SRST_P_PVTPLL_NPU 515 +#define SRST_NPU_PVTPLL 516 +#define SRST_H_NPU_CM0_BIU 518 +#define SRST_F_NPU_CM0_CORE 519 +#define SRST_T_NPU_CM0_JTAG 520 +#define SRST_A_RKNNTOP_BIU 523 +#define SRST_H_RKNN_CBUF 524 +#define SRST_H_RKNNTOP_BIU 525 +/********Name=SOFTRST_CON33,Offset=0xA84********/ +#define SRST_H_NVM_BIU 530 +#define SRST_A_NVM_BIU 531 +#define SRST_S_FSPI 534 +#define SRST_H_FSPI 535 +#define SRST_C_EMMC 536 +#define SRST_H_EMMC 537 +#define SRST_A_EMMC 538 +#define SRST_B_EMMC 539 +#define SRST_T_EMMC 540 +/********Name=SOFTRST_CON34,Offset=0xA88********/ +#define SRST_P_GRF 545 +#define SRST_P_PHP_BIU 549 +#define SRST_A_PHP_BIU 553 +#define SRST_P_PCIE0 557 +#define SRST_PCIE0_POWER_UP 559 +/********Name=SOFTRST_CON35,Offset=0xA8C********/ +#define SRST_A_USB3OTG1 563 +#define SRST_A_MMU0 571 +#define SRST_A_SLV_MMU0 573 +#define SRST_A_MMU1 574 +/********Name=SOFTRST_CON36,Offset=0xA90********/ +#define SRST_A_SLV_MMU1 576 +#define SRST_P_PCIE1 583 +#define SRST_PCIE1_POWER_UP 585 +/********Name=SOFTRST_CON37,Offset=0xA94********/ +#define SRST_RXOOB0 592 +#define SRST_RXOOB1 593 +#define SRST_PMALIVE0 594 +#define SRST_PMALIVE1 595 +#define SRST_A_SATA0 596 +#define SRST_A_SATA1 597 +#define SRST_ASIC1 598 +#define SRST_ASIC0 599 +/********Name=SOFTRST_CON40,Offset=0xAA0********/ +#define SRST_P_CSIDPHY1 642 +#define SRST_SCAN_CSIDPHY1 643 +/********Name=SOFTRST_CON42,Offset=0xAA8********/ +#define SRST_P_SDGMAC_GRF 675 +#define SRST_P_SDGMAC_BIU 676 +#define SRST_A_SDGMAC_BIU 677 +#define SRST_H_SDGMAC_BIU 678 +#define SRST_A_GMAC0 679 +#define SRST_A_GMAC1 680 +#define SRST_P_GMAC0 681 +#define SRST_P_GMAC1 682 +#define SRST_H_SDIO 684 +/********Name=SOFTRST_CON43,Offset=0xAAC********/ +#define SRST_H_SDMMC0 690 +#define SRST_S_FSPI1 691 +#define SRST_H_FSPI1 692 +#define SRST_A_DSMC_BIU 694 +#define SRST_A_DSMC 695 +#define SRST_P_DSMC 696 +#define SRST_H_HSGPIO 698 +#define SRST_HSGPIO 699 +#define SRST_A_HSGPIO 701 +/********Name=SOFTRST_CON45,Offset=0xAB4********/ +#define SRST_H_RKVDEC 723 +#define SRST_H_RKVDEC_BIU 725 +#define SRST_A_RKVDEC_BIU 726 +#define SRST_RKVDEC_HEVC_CA 728 +#define SRST_RKVDEC_CORE 729 +/********Name=SOFTRST_CON47,Offset=0xABC********/ +#define SRST_A_USB_BIU 755 +#define SRST_P_USBUFS_BIU 756 +#define SRST_A_USB3OTG0 757 +#define SRST_A_UFS_BIU 762 +#define SRST_A_MMU2 764 +#define SRST_A_SLV_MMU2 765 +#define SRST_A_UFS_SYS 767 +/********Name=SOFTRST_CON48,Offset=0xAC0********/ +#define SRST_A_UFS 768 +#define SRST_P_USBUFS_GRF 769 +#define SRST_P_UFS_GRF 770 +/********Name=SOFTRST_CON49,Offset=0xAC4********/ +#define SRST_H_VPU_BIU 790 +#define SRST_A_JPEG_BIU 791 +#define SRST_A_RGA_BIU 794 +#define SRST_A_VDPP_BIU 795 +#define SRST_A_EBC_BIU 796 +#define SRST_H_RGA2E_0 797 +#define SRST_A_RGA2E_0 798 +#define SRST_CORE_RGA2E_0 799 +/********Name=SOFTRST_CON50,Offset=0xAC8********/ +#define SRST_A_JPEG 800 +#define SRST_H_JPEG 801 +#define SRST_H_VDPP 802 +#define SRST_A_VDPP 803 +#define SRST_CORE_VDPP 804 +#define SRST_H_RGA2E_1 805 +#define SRST_A_RGA2E_1 806 +#define SRST_CORE_RGA2E_1 807 +#define SRST_H_EBC 810 +#define SRST_A_EBC 811 +#define SRST_D_EBC 812 +/********Name=SOFTRST_CON51,Offset=0xACC********/ +#define SRST_H_VEPU0_BIU 818 +#define SRST_A_VEPU0_BIU 819 +#define SRST_H_VEPU0 820 +#define SRST_A_VEPU0 821 +#define SRST_VEPU0_CORE 822 +/********Name=SOFTRST_CON53,Offset=0xAD4********/ +#define SRST_A_VI_BIU 851 +#define SRST_H_VI_BIU 852 +#define SRST_P_VI_BIU 853 +#define SRST_D_VICAP 854 +#define SRST_A_VICAP 855 +#define SRST_H_VICAP 856 +#define SRST_ISP0 858 +#define SRST_ISP0_VICAP 859 +/********Name=SOFTRST_CON54,Offset=0xAD8********/ +#define SRST_CORE_VPSS 865 +#define SRST_P_CSI_HOST_0 868 +#define SRST_P_CSI_HOST_1 869 +#define SRST_P_CSI_HOST_2 870 +#define SRST_P_CSI_HOST_3 871 +#define SRST_P_CSI_HOST_4 872 +/********Name=SOFTRST_CON59,Offset=0xAEC********/ +#define SRST_CIFIN 944 +#define SRST_VICAP_I0CLK 945 +#define SRST_VICAP_I1CLK 946 +#define SRST_VICAP_I2CLK 947 +#define SRST_VICAP_I3CLK 948 +#define SRST_VICAP_I4CLK 949 +/********Name=SOFTRST_CON61,Offset=0xAF4********/ +#define SRST_A_VOP_BIU 980 +#define SRST_A_VOP2_BIU 981 +#define SRST_H_VOP_BIU 982 +#define SRST_P_VOP_BIU 983 +#define SRST_H_VOP 984 +#define SRST_A_VOP 985 +#define SRST_D_VP0 989 +/********Name=SOFTRST_CON62,Offset=0xAF8********/ +#define SRST_D_VP1 992 +#define SRST_D_VP2 993 +#define SRST_P_VOP2_BIU 994 +#define SRST_P_VOPGRF 995 +/********Name=SOFTRST_CON63,Offset=0xAFC********/ +#define SRST_H_VO0_BIU 1013 +#define SRST_P_VO0_BIU 1015 +#define SRST_A_HDCP0_BIU 1017 +#define SRST_P_VO0_GRF 1018 +#define SRST_A_HDCP0 1020 +#define SRST_H_HDCP0 1021 +#define SRST_HDCP0 1022 +/********Name=SOFTRST_CON64,Offset=0xB00********/ +#define SRST_P_DSIHOST0 1029 +#define SRST_DSIHOST0 1030 +#define SRST_P_HDMITX0 1031 +#define SRST_HDMITX0_REF 1033 +#define SRST_P_EDP0 1037 +#define SRST_EDP0_24M 1038 +/********Name=SOFTRST_CON65,Offset=0xB04********/ +#define SRST_M_SAI5_8CH 1044 +#define SRST_H_SAI5_8CH 1045 +#define SRST_M_SAI6_8CH 1048 +#define SRST_H_SAI6_8CH 1049 +#define SRST_H_SPDIF_TX2 1050 +#define SRST_M_SPDIF_TX2 1053 +#define SRST_H_SPDIF_RX2 1054 +#define SRST_M_SPDIF_RX2 1055 +/********Name=SOFTRST_CON66,Offset=0xB08********/ +#define SRST_H_SAI8_8CH 1056 +#define SRST_M_SAI8_8CH 1058 +/********Name=SOFTRST_CON67,Offset=0xB0C********/ +#define SRST_H_VO1_BIU 1077 +#define SRST_P_VO1_BIU 1078 +#define SRST_M_SAI7_8CH 1081 +#define SRST_H_SAI7_8CH 1082 +#define SRST_H_SPDIF_TX3 1083 +#define SRST_H_SPDIF_TX4 1084 +#define SRST_H_SPDIF_TX5 1085 +#define SRST_M_SPDIF_TX3 1086 +/********Name=SOFTRST_CON68,Offset=0xB10********/ +#define SRST_DP0 1088 +#define SRST_P_VO1_GRF 1090 +#define SRST_A_HDCP1_BIU 1091 +#define SRST_A_HDCP1 1092 +#define SRST_H_HDCP1 1093 +#define SRST_HDCP1 1094 +#define SRST_H_SAI9_8CH 1097 +#define SRST_M_SAI9_8CH 1099 +#define SRST_M_SPDIF_TX4 1100 +#define SRST_M_SPDIF_TX5 1101 +/********Name=SOFTRST_CON69,Offset=0xB14********/ +#define SRST_GPU 1107 +#define SRST_A_S_GPU_BIU 1110 +#define SRST_A_M0_GPU_BIU 1111 +#define SRST_P_GPU_BIU 1113 +#define SRST_P_GPU_GRF 1117 +#define SRST_GPU_PVTPLL 1118 +#define SRST_P_PVTPLL_GPU 1119 +/********Name=SOFTRST_CON72,Offset=0xB20********/ +#define SRST_A_CENTER_BIU 1156 +#define SRST_A_DMA2DDR 1157 +#define SRST_A_DDR_SHAREMEM 1158 +#define SRST_A_DDR_SHAREMEM_BIU 1159 +#define SRST_H_CENTER_BIU 1160 +#define SRST_P_CENTER_GRF 1161 +#define SRST_P_DMA2DDR 1162 +#define SRST_P_SHAREMEM 1163 +#define SRST_P_CENTER_BIU 1164 +/********Name=SOFTRST_CON75,Offset=0xB2C********/ +#define SRST_LINKSYM_HDMITXPHY0 1201 +/********Name=SOFTRST_CON78,Offset=0xB38********/ +#define SRST_DP0_PIXELCLK 1249 +#define SRST_PHY_DP0_TX 1250 +#define SRST_DP1_PIXELCLK 1251 +#define SRST_DP2_PIXELCLK 1252 +/********Name=SOFTRST_CON79,Offset=0xB3C********/ +#define SRST_H_VEPU1_BIU 1265 +#define SRST_A_VEPU1_BIU 1266 +#define SRST_H_VEPU1 1267 +#define SRST_A_VEPU1 1268 +#define SRST_VEPU1_CORE 1269 + +/********Name=PHPPHYSOFTRST_CON00,Offset=0x8A00********/ +#define SRST_P_PHPPHY_CRU 131073 +#define SRST_P_APB2ASB_SLV_CHIP_TOP 131075 +#define SRST_P_PCIE2_COMBOPHY0 131077 +#define SRST_P_PCIE2_COMBOPHY0_GRF 131078 +#define SRST_P_PCIE2_COMBOPHY1 131079 +#define SRST_P_PCIE2_COMBOPHY1_GRF 131080 +/********Name=PHPPHYSOFTRST_CON01,Offset=0x8A04********/ +#define SRST_PCIE0_PIPE_PHY 131093 +#define SRST_PCIE1_PIPE_PHY 131096 + +/********Name=SECURENSSOFTRST_CON00,Offset=0x10A00********/ +#define SRST_H_CRYPTO_NS 262147 +#define SRST_H_TRNG_NS 262148 +#define SRST_P_OTPC_NS 262152 +#define SRST_OTPC_NS 262153 + +/********Name=PMU1SOFTRST_CON00,Offset=0x20A00********/ +#define SRST_P_HDPTX_GRF 524288 +#define SRST_P_HDPTX_APB 524289 +#define SRST_P_MIPI_DCPHY 524290 +#define SRST_P_DCPHY_GRF 524291 +#define SRST_P_BOT0_APB2ASB 524292 +#define SRST_P_BOT1_APB2ASB 524293 +#define SRST_USB2DEBUG 524294 +#define SRST_P_CSIPHY_GRF 524295 +#define SRST_P_CSIPHY 524296 +#define SRST_P_USBPHY_GRF_0 524297 +#define SRST_P_USBPHY_GRF_1 524298 +#define SRST_P_USBDP_GRF 524299 +#define SRST_P_USBDPPHY 524300 +#define SRST_USBDP_COMBO_PHY_INIT 524303 +/********Name=PMU1SOFTRST_CON01,Offset=0x20A04********/ +#define SRST_USBDP_COMBO_PHY_CMN 524304 +#define SRST_USBDP_COMBO_PHY_LANE 524305 +#define SRST_USBDP_COMBO_PHY_PCS 524306 +#define SRST_M_MIPI_DCPHY 524307 +#define SRST_S_MIPI_DCPHY 524308 +#define SRST_SCAN_CSIPHY 524309 +#define SRST_P_VCCIO6_IOC 524310 +#define SRST_OTGPHY_0 524311 +#define SRST_OTGPHY_1 524312 +#define SRST_HDPTX_INIT 524313 +#define SRST_HDPTX_CMN 524314 +#define SRST_HDPTX_LANE 524315 +#define SRST_HDMITXHPD 524317 +/********Name=PMU1SOFTRST_CON02,Offset=0x20A08********/ +#define SRST_MPHY_INIT 524320 +#define SRST_P_MPHY_GRF 524321 +#define SRST_P_VCCIO7_IOC 524323 +/********Name=PMU1SOFTRST_CON03,Offset=0x20A0C********/ +#define SRST_H_PMU1_BIU 524345 +#define SRST_P_PMU1_NIU 524346 +#define SRST_H_PMU_CM0_BIU 524347 +#define SRST_PMU_CM0_CORE 524348 +#define SRST_PMU_CM0_JTAG 524349 +/********Name=PMU1SOFTRST_CON04,Offset=0x20A10********/ +#define SRST_P_CRU_PMU1 524353 +#define SRST_P_PMU1_GRF 524355 +#define SRST_P_PMU1_IOC 524356 +#define SRST_P_PMU1WDT 524357 +#define SRST_T_PMU1WDT 524358 +#define SRST_P_PMUTIMER 524359 +#define SRST_PMUTIMER0 524361 +#define SRST_PMUTIMER1 524362 +#define SRST_P_PMU1PWM 524363 +#define SRST_PMU1PWM 524364 +/********Name=PMU1SOFTRST_CON05,Offset=0x20A14********/ +#define SRST_P_I2C0 524369 +#define SRST_I2C0 524371 +#define SRST_S_UART1 525373 +#define SRST_P_UART1 525374 +#define SRST_PDM0 524381 +#define SRST_H_PDM0 524383 +/********Name=PMU1SOFTRST_CON06,Offset=0xA18********/ +#define SRST_M_PDM0 524384 +#define SRST_H_VAD 524385 +/********Name=PMU1SOFTRST_CON07,Offset=0x20A1C********/ +#define SRST_P_PMU0GRF 524404 +#define SRST_P_PMU0IOC 524405 +#define SRST_P_GPIO0 524406 +#define SRST_DB_GPIO0 524407 + +#define SRST_NR_RSTS (SRST_DB_GPIO0 + 1) + +#endif /* __DT_BINDINGS_CLK_ROCKCHIP_RK3576_H__ */ diff --git a/bsp/rockchip/rk3500/driver/clk/rk3588-cru.h b/bsp/rockchip/dm/include/dt-bindings/clock/rk3588-cru.h old mode 100644 new mode 100755 similarity index 99% rename from bsp/rockchip/rk3500/driver/clk/rk3588-cru.h rename to bsp/rockchip/dm/include/dt-bindings/clock/rk3588-cru.h index 1982073979d..f2a99d0d364 --- a/bsp/rockchip/rk3500/driver/clk/rk3588-cru.h +++ b/bsp/rockchip/dm/include/dt-bindings/clock/rk3588-cru.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 */ @@ -229,7 +229,7 @@ #define CLK_DDR_TIMER0 226 #define CLK_DDR_TIMER1 227 #define TCLK_WDT_DDR 228 -#define CLK_DDR_CM0_RTC 228 +#define CLK_DDR_CM0_RTC 229 #define PCLK_WDT 230 #define PCLK_TIMER 231 #define PCLK_DMA2DDR 232 @@ -631,7 +631,7 @@ #define CLK_DSIHOST1 635 #define CLK_VOP_PMU 636 #define ACLK_VOP_DOBY 637 -#define ACLK_VOP_SUB_SRC 638 +#define ACLK_VOP_DIV2_SRC 638 #define CLK_USBDP_PHY0_IMMORTAL 639 #define CLK_USBDP_PHY1_IMMORTAL 640 #define CLK_PMU0 641 @@ -713,8 +713,12 @@ #define CLK_PHY0_REF_ALT_M 719 #define CLK_PHY1_REF_ALT_P 720 #define CLK_PHY1_REF_ALT_M 721 +#define PCLK_DDR_MON_CH0 722 +#define PCLK_DDR_MON_CH1 723 +#define PCLK_DDR_MON_CH2 724 +#define PCLK_DDR_MON_CH3 725 -#define CLK_NR_CLKS (CLK_PHY1_REF_ALT_M + 1) +#define CLK_NR_CLKS (PCLK_DDR_MON_CH3 + 1) /********Name=SOFTRST_CON01,Offset=0xA04********/ #define SRST_A_TOP_BIU 19 diff --git a/bsp/rockchip/dm/include/dt-bindings/phye/phye-snps-pcie3.h b/bsp/rockchip/dm/include/dt-bindings/phye/phye-snps-pcie3.h new file mode 100755 index 00000000000..4c4023e20da --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/phye/phye-snps-pcie3.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_PHYE_SNPS_PCIE3_H__ +#define __DT_BINDINGS_PHYE_SNPS_PCIE3_H__ + +/* + * pcie30_phy_mode[2:0] + * bit2: aggregation + * bit1: bifurcation for port 1 + * bit0: bifurcation for port 0 + */ +#define PHYE_MODE_PCIE_AGGREGATION 4 /* PCIe3x4 */ +#define PHYE_MODE_PCIE_NANBNB 0 /* P1:PCIe3x2 + P0:PCIe3x2 */ +#define PHYE_MODE_PCIE_NANBBI 1 /* P1:PCIe3x2 + P0:PCIe3x1*2 */ +#define PHYE_MODE_PCIE_NABINB 2 /* P1:PCIe3x1*2 + P0:PCIe3x2 */ +#define PHYE_MODE_PCIE_NABIBI 3 /* P1:PCIe3x1*2 + P0:PCIe3x1*2 */ + +#endif /* __DT_BINDINGS_PHYE_SNPS_PCIE3_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/pinctrl/rockchip.h b/bsp/rockchip/dm/include/dt-bindings/pinctrl/rockchip.h new file mode 100755 index 00000000000..7cee4123eba --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/pinctrl/rockchip.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_PINCTRL_ROCKCHIP_H__ +#define __DT_BINDINGS_PINCTRL_ROCKCHIP_H__ + +#define RK_GPIO0 0 +#define RK_GPIO1 1 +#define RK_GPIO2 2 +#define RK_GPIO3 3 +#define RK_GPIO4 4 + +#define RK_PA0 0 +#define RK_PA1 1 +#define RK_PA2 2 +#define RK_PA3 3 +#define RK_PA4 4 +#define RK_PA5 5 +#define RK_PA6 6 +#define RK_PA7 7 +#define RK_PB0 8 +#define RK_PB1 9 +#define RK_PB2 10 +#define RK_PB3 11 +#define RK_PB4 12 +#define RK_PB5 13 +#define RK_PB6 14 +#define RK_PB7 15 +#define RK_PC0 16 +#define RK_PC1 17 +#define RK_PC2 18 +#define RK_PC3 19 +#define RK_PC4 20 +#define RK_PC5 21 +#define RK_PC6 22 +#define RK_PC7 23 +#define RK_PD0 24 +#define RK_PD1 25 +#define RK_PD2 26 +#define RK_PD3 27 +#define RK_PD4 28 +#define RK_PD5 29 +#define RK_PD6 30 +#define RK_PD7 31 + +#define RK_FUNC_GPIO 0 +#define RK_FUNC_0 0 +#define RK_FUNC_1 1 +#define RK_FUNC_2 2 +#define RK_FUNC_3 3 +#define RK_FUNC_4 4 +#define RK_FUNC_5 5 +#define RK_FUNC_6 6 +#define RK_FUNC_7 7 +#define RK_FUNC_8 8 +#define RK_FUNC_9 9 +#define RK_FUNC_10 10 +#define RK_FUNC_11 11 +#define RK_FUNC_12 12 +#define RK_FUNC_13 13 +#define RK_FUNC_14 14 +#define RK_FUNC_15 15 + +#define RK_GPIO0_A0 0 +#define RK_GPIO0_A1 1 +#define RK_GPIO0_A2 2 +#define RK_GPIO0_A3 3 +#define RK_GPIO0_A4 4 +#define RK_GPIO0_A5 5 +#define RK_GPIO0_A6 6 +#define RK_GPIO0_A7 7 +#define RK_GPIO0_B0 8 +#define RK_GPIO0_B1 9 +#define RK_GPIO0_B2 10 +#define RK_GPIO0_B3 11 +#define RK_GPIO0_B4 12 +#define RK_GPIO0_B5 13 +#define RK_GPIO0_B6 14 +#define RK_GPIO0_B7 15 +#define RK_GPIO0_C0 16 +#define RK_GPIO0_C1 17 +#define RK_GPIO0_C2 18 +#define RK_GPIO0_C3 19 +#define RK_GPIO0_C4 20 +#define RK_GPIO0_C5 21 +#define RK_GPIO0_C6 22 +#define RK_GPIO0_C7 23 +#define RK_GPIO0_D0 24 +#define RK_GPIO0_D1 25 +#define RK_GPIO0_D2 26 +#define RK_GPIO0_D3 27 +#define RK_GPIO0_D4 28 +#define RK_GPIO0_D5 29 +#define RK_GPIO0_D6 30 +#define RK_GPIO0_D7 31 + +#define RK_GPIO1_A0 32 +#define RK_GPIO1_A1 33 +#define RK_GPIO1_A2 34 +#define RK_GPIO1_A3 35 +#define RK_GPIO1_A4 36 +#define RK_GPIO1_A5 37 +#define RK_GPIO1_A6 38 +#define RK_GPIO1_A7 39 +#define RK_GPIO1_B0 40 +#define RK_GPIO1_B1 41 +#define RK_GPIO1_B2 42 +#define RK_GPIO1_B3 43 +#define RK_GPIO1_B4 44 +#define RK_GPIO1_B5 45 +#define RK_GPIO1_B6 46 +#define RK_GPIO1_B7 47 +#define RK_GPIO1_C0 48 +#define RK_GPIO1_C1 49 +#define RK_GPIO1_C2 50 +#define RK_GPIO1_C3 51 +#define RK_GPIO1_C4 52 +#define RK_GPIO1_C5 53 +#define RK_GPIO1_C6 54 +#define RK_GPIO1_C7 55 +#define RK_GPIO1_D0 56 +#define RK_GPIO1_D1 57 +#define RK_GPIO1_D2 58 +#define RK_GPIO1_D3 59 +#define RK_GPIO1_D4 60 +#define RK_GPIO1_D5 61 +#define RK_GPIO1_D6 62 +#define RK_GPIO1_D7 63 + +#define RK_GPIO2_A0 64 +#define RK_GPIO2_A1 65 +#define RK_GPIO2_A2 66 +#define RK_GPIO2_A3 67 +#define RK_GPIO2_A4 68 +#define RK_GPIO2_A5 69 +#define RK_GPIO2_A6 70 +#define RK_GPIO2_A7 71 +#define RK_GPIO2_B0 72 +#define RK_GPIO2_B1 73 +#define RK_GPIO2_B2 74 +#define RK_GPIO2_B3 75 +#define RK_GPIO2_B4 76 +#define RK_GPIO2_B5 77 +#define RK_GPIO2_B6 78 +#define RK_GPIO2_B7 79 +#define RK_GPIO2_C0 80 +#define RK_GPIO2_C1 81 +#define RK_GPIO2_C2 82 +#define RK_GPIO2_C3 83 +#define RK_GPIO2_C4 84 +#define RK_GPIO2_C5 85 +#define RK_GPIO2_C6 86 +#define RK_GPIO2_C7 87 +#define RK_GPIO2_D0 88 +#define RK_GPIO2_D1 89 +#define RK_GPIO2_D2 90 +#define RK_GPIO2_D3 91 +#define RK_GPIO2_D4 92 +#define RK_GPIO2_D5 93 +#define RK_GPIO2_D6 94 +#define RK_GPIO2_D7 95 + +#define RK_GPIO3_A0 96 +#define RK_GPIO3_A1 97 +#define RK_GPIO3_A2 98 +#define RK_GPIO3_A3 99 +#define RK_GPIO3_A4 100 +#define RK_GPIO3_A5 101 +#define RK_GPIO3_A6 102 +#define RK_GPIO3_A7 103 +#define RK_GPIO3_B0 104 +#define RK_GPIO3_B1 105 +#define RK_GPIO3_B2 106 +#define RK_GPIO3_B3 107 +#define RK_GPIO3_B4 108 +#define RK_GPIO3_B5 109 +#define RK_GPIO3_B6 110 +#define RK_GPIO3_B7 111 +#define RK_GPIO3_C0 112 +#define RK_GPIO3_C1 113 +#define RK_GPIO3_C2 114 +#define RK_GPIO3_C3 115 +#define RK_GPIO3_C4 116 +#define RK_GPIO3_C5 117 +#define RK_GPIO3_C6 118 +#define RK_GPIO3_C7 119 +#define RK_GPIO3_D0 120 +#define RK_GPIO3_D1 121 +#define RK_GPIO3_D2 122 +#define RK_GPIO3_D3 123 +#define RK_GPIO3_D4 124 +#define RK_GPIO3_D5 125 +#define RK_GPIO3_D6 126 +#define RK_GPIO3_D7 127 + +#define RK_GPIO4_A0 128 +#define RK_GPIO4_A1 129 +#define RK_GPIO4_A2 130 +#define RK_GPIO4_A3 131 +#define RK_GPIO4_A4 132 +#define RK_GPIO4_A5 133 +#define RK_GPIO4_A6 134 +#define RK_GPIO4_A7 135 +#define RK_GPIO4_B0 136 +#define RK_GPIO4_B1 137 +#define RK_GPIO4_B2 138 +#define RK_GPIO4_B3 139 +#define RK_GPIO4_B4 140 +#define RK_GPIO4_B5 141 +#define RK_GPIO4_B6 142 +#define RK_GPIO4_B7 143 +#define RK_GPIO4_C0 144 +#define RK_GPIO4_C1 145 +#define RK_GPIO4_C2 146 +#define RK_GPIO4_C3 147 +#define RK_GPIO4_C4 148 +#define RK_GPIO4_C5 149 +#define RK_GPIO4_C6 150 +#define RK_GPIO4_C7 151 +#define RK_GPIO4_D0 152 +#define RK_GPIO4_D1 153 +#define RK_GPIO4_D2 154 +#define RK_GPIO4_D3 155 +#define RK_GPIO4_D4 156 +#define RK_GPIO4_D5 157 +#define RK_GPIO4_D6 158 +#define RK_GPIO4_D7 159 + +#endif /* __DT_BINDINGS_PINCTRL_ROCKCHIP_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/px30-power.h b/bsp/rockchip/dm/include/dt-bindings/power/px30-power.h new file mode 100755 index 00000000000..6ff9080ce9e --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/px30-power.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_PX30_POWER_H__ +#define __DT_BINDINGS_POWER_PX30_POWER_H__ + +/* VD_CORE */ +#define PX30_PD_A35_0 0 +#define PX30_PD_A35_1 1 +#define PX30_PD_A35_2 2 +#define PX30_PD_A35_3 3 +#define PX30_PD_SCU 4 + +/* VD_LOGIC */ +#define PX30_PD_USB 5 +#define PX30_PD_DDR 6 +#define PX30_PD_SDCARD 7 +#define PX30_PD_CRYPTO 8 +#define PX30_PD_GMAC 9 +#define PX30_PD_MMC_NAND 10 +#define PX30_PD_VPU 11 +#define PX30_PD_VO 12 +#define PX30_PD_VI 13 +#define PX30_PD_GPU 14 + +/* VD_PMU */ +#define PX30_PD_PMU 15 + +#endif /* __DT_BINDINGS_POWER_PX30_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk1808-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk1808-power.h new file mode 100755 index 00000000000..8e857b55d2c --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk1808-power.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK1808_POWER_H__ +#define __DT_BINDINGS_POWER_RK1808_POWER_H__ + +/* VD_CORE */ +#define RK1808_PD_A35_0 0 +#define RK1808_PD_A35_1 1 +#define RK1808_PD_SCU 2 +#define RK1808_VD_CORE 3 + +/* VD_NPU */ +#define RK1808_VD_NPU 4 + +/* VD_LOGIC */ +#define RK1808_PD_DDR 5 +#define RK1808_PD_PCIE 6 +#define RK1808_PD_VPU 7 +#define RK1808_PD_VIO 8 + +#endif /* __DT_BINDINGS_POWER_RK1808_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3036-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3036-power.h new file mode 100755 index 00000000000..1163f3760df --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3036-power.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3036_POWER_H__ +#define __DT_BINDINGS_POWER_RK3036_POWER_H__ + +#define RK3036_PD_MSCH 0 +#define RK3036_PD_CORE 1 +#define RK3036_PD_PERI 2 +#define RK3036_PD_VIO 3 +#define RK3036_PD_VPU 4 +#define RK3036_PD_GPU 5 +#define RK3036_PD_SYS 6 + +#endif /* __DT_BINDINGS_POWER_RK3036_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3066-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3066-power.h new file mode 100755 index 00000000000..406681a814f --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3066-power.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3066_POWER_H__ +#define __DT_BINDINGS_POWER_RK3066_POWER_H__ + +/* VD_CORE */ +#define RK3066_PD_A9_0 0 +#define RK3066_PD_A9_1 1 +#define RK3066_PD_DBG 4 +#define RK3066_PD_SCU 5 + +/* VD_LOGIC */ +#define RK3066_PD_VIDEO 6 +#define RK3066_PD_VIO 7 +#define RK3066_PD_GPU 8 +#define RK3066_PD_PERI 9 +#define RK3066_PD_CPU 10 +#define RK3066_PD_ALIVE 11 + +/* VD_PMU */ +#define RK3066_PD_RTC 12 + +#endif /* __DT_BINDINGS_POWER_RK3066_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3128-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3128-power.h new file mode 100755 index 00000000000..88d88da4fb2 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3128-power.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3128_POWER_H__ +#define __DT_BINDINGS_POWER_RK3128_POWER_H__ + +/* VD_CORE */ +#define RK3128_PD_CORE 0 + +/* VD_LOGIC */ +#define RK3128_PD_VIO 1 +#define RK3128_PD_VIDEO 2 +#define RK3128_PD_GPU 3 +#define RK3128_PD_MSCH 4 + +#endif /* __DT_BINDINGS_POWER_RK3128_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3188-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3188-power.h new file mode 100755 index 00000000000..ab7969c510f --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3188-power.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3188_POWER_H__ +#define __DT_BINDINGS_POWER_RK3188_POWER_H__ + +/* VD_CORE */ +#define RK3188_PD_A9_0 0 +#define RK3188_PD_A9_1 1 +#define RK3188_PD_A9_2 2 +#define RK3188_PD_A9_3 3 +#define RK3188_PD_DBG 4 +#define RK3188_PD_SCU 5 + +/* VD_LOGIC */ +#define RK3188_PD_VIDEO 6 +#define RK3188_PD_VIO 7 +#define RK3188_PD_GPU 8 +#define RK3188_PD_PERI 9 +#define RK3188_PD_CPU 10 +#define RK3188_PD_ALIVE 11 + +/* VD_PMU */ +#define RK3188_PD_RTC 12 + +#endif /* __DT_BINDINGS_POWER_RK3188_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3228-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3228-power.h new file mode 100755 index 00000000000..71b0124a087 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3228-power.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3228_POWER_H__ +#define __DT_BINDINGS_POWER_RK3228_POWER_H__ + +#define RK3228_PD_CORE 0 +#define RK3228_PD_MSCH 1 +#define RK3228_PD_BUS 2 +#define RK3228_PD_SYS 3 +#define RK3228_PD_VIO 4 +#define RK3228_PD_VOP 5 +#define RK3228_PD_VPU 6 +#define RK3228_PD_RKVDEC 7 +#define RK3228_PD_GPU 8 +#define RK3228_PD_PERI 9 +#define RK3228_PD_GMAC 10 + +#endif /* __DT_BINDINGS_POWER_RK3228_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3288-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3288-power.h new file mode 100755 index 00000000000..19d6b19ca85 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3288-power.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3288_POWER_H__ +#define __DT_BINDINGS_POWER_RK3288_POWER_H__ + +/* VD_CORE */ +#define RK3288_PD_A17_0 0 +#define RK3288_PD_A17_1 1 +#define RK3288_PD_A17_2 2 +#define RK3288_PD_A17_3 3 +#define RK3288_PD_SCU 4 +#define RK3288_PD_DEBUG 5 +#define RK3288_PD_MEM 6 + +/* VD_LOGIC */ +#define RK3288_PD_BUS 7 +#define RK3288_PD_PERI 8 +#define RK3288_PD_VIO 9 +#define RK3288_PD_ALIVE 10 +#define RK3288_PD_HEVC 11 +#define RK3288_PD_VIDEO 12 + +/* VD_GPU */ +#define RK3288_PD_GPU 13 + +/* VD_PMU */ +#define RK3288_PD_PMU 14 + +#endif /* __DT_BINDINGS_POWER_RK3288_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3328-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3328-power.h new file mode 100755 index 00000000000..df2dab049aa --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3328-power.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3328_POWER_H__ +#define __DT_BINDINGS_POWER_RK3328_POWER_H__ + +#define RK3328_PD_CORE 0 +#define RK3328_PD_GPU 1 +#define RK3328_PD_BUS 2 +#define RK3328_PD_MSCH 3 +#define RK3328_PD_PERI 4 +#define RK3328_PD_VIDEO 5 +#define RK3328_PD_HEVC 6 +#define RK3328_PD_SYS 7 +#define RK3328_PD_VPU 8 +#define RK3328_PD_VIO 9 + +#endif /* __DT_BINDINGS_POWER_RK3328_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3366-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3366-power.h new file mode 100755 index 00000000000..f34f7a974ac --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3366-power.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3366_POWER_H__ +#define __DT_BINDINGS_POWER_RK3366_POWER_H__ + +/* VD_CORE */ +#define RK3366_PD_A53_0 0 +#define RK3366_PD_A53_1 1 +#define RK3366_PD_A53_2 2 +#define RK3366_PD_A53_3 3 + +/* VD_LOGIC */ +#define RK3366_PD_BUS 4 +#define RK3366_PD_PERI 5 +#define RK3366_PD_VIO 6 +#define RK3366_PD_VIDEO 7 +#define RK3366_PD_RKVDEC 8 +#define RK3366_PD_WIFIBT 9 +#define RK3366_PD_VPU 10 +#define RK3366_PD_GPU 11 +#define RK3366_PD_ALIVE 12 + +/* VD_PMU */ +#define RK3366_PD_PMU 13 + +#endif /* __DT_BINDINGS_POWER_RK3366_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3368-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3368-power.h new file mode 100755 index 00000000000..4355fc5629c --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3368-power.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3368_POWER_H__ +#define __DT_BINDINGS_POWER_RK3368_POWER_H__ + +/* VD_CORE */ +#define RK3368_PD_A53_L0 0 +#define RK3368_PD_A53_L1 1 +#define RK3368_PD_A53_L2 2 +#define RK3368_PD_A53_L3 3 +#define RK3368_PD_SCU_L 4 +#define RK3368_PD_A53_B0 5 +#define RK3368_PD_A53_B1 6 +#define RK3368_PD_A53_B2 7 +#define RK3368_PD_A53_B3 8 +#define RK3368_PD_SCU_B 9 + +/* VD_LOGIC */ +#define RK3368_PD_BUS 10 +#define RK3368_PD_PERI 11 +#define RK3368_PD_VIO 12 +#define RK3368_PD_ALIVE 13 +#define RK3368_PD_VIDEO 14 +#define RK3368_PD_GPU_0 15 +#define RK3368_PD_GPU_1 16 + +/* VD_PMU */ +#define RK3368_PD_PMU 17 + +#endif /* __DT_BINDINGS_POWER_RK3368_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3399-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3399-power.h new file mode 100755 index 00000000000..12db7b1530a --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3399-power.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3399_POWER_H__ +#define __DT_BINDINGS_POWER_RK3399_POWER_H__ + +/* VD_CORE_L */ +#define RK3399_PD_A53_L0 0 +#define RK3399_PD_A53_L1 1 +#define RK3399_PD_A53_L2 2 +#define RK3399_PD_A53_L3 3 +#define RK3399_PD_SCU_L 4 + +/* VD_CORE_B */ +#define RK3399_PD_A72_B0 5 +#define RK3399_PD_A72_B1 6 +#define RK3399_PD_SCU_B 7 + +/* VD_LOGIC */ +#define RK3399_PD_TCPD0 8 +#define RK3399_PD_TCPD1 9 +#define RK3399_PD_CCI 10 +#define RK3399_PD_CCI0 11 +#define RK3399_PD_CCI1 12 +#define RK3399_PD_PERILP 13 +#define RK3399_PD_PERIHP 14 +#define RK3399_PD_VIO 15 +#define RK3399_PD_VO 16 +#define RK3399_PD_VOPB 17 +#define RK3399_PD_VOPL 18 +#define RK3399_PD_ISP0 19 +#define RK3399_PD_ISP1 20 +#define RK3399_PD_HDCP 21 +#define RK3399_PD_GMAC 22 +#define RK3399_PD_EMMC 23 +#define RK3399_PD_USB3 24 +#define RK3399_PD_EDP 25 +#define RK3399_PD_GIC 26 +#define RK3399_PD_SD 27 +#define RK3399_PD_SDIOAUDIO 28 +#define RK3399_PD_ALIVE 29 + +/* VD_CENTER */ +#define RK3399_PD_CENTER 30 +#define RK3399_PD_VCODEC 31 +#define RK3399_PD_VDU 32 +#define RK3399_PD_RGA 33 +#define RK3399_PD_IEP 34 + +/* VD_GPU */ +#define RK3399_PD_GPU 35 + +/* VD_PMU */ +#define RK3399_PD_PMU 36 + +#endif /* __DT_BINDINGS_POWER_RK3399_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3528-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3528-power.h new file mode 100755 index 00000000000..e54335583dd --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3528-power.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3528_POWER_H__ +#define __DT_BINDINGS_POWER_RK3528_POWER_H__ + +/* + * RK3528 idle id Summary. + */ +#define RK3528_PD_PMU 0 +#define RK3528_PD_BUS 1 +#define RK3528_PD_DDR 2 +#define RK3528_PD_MSCH 3 +#define RK3528_PD_GPU 4 +#define RK3528_PD_RKVDEC 5 +#define RK3528_PD_RKVENC 6 +#define RK3528_PD_VO 7 +#define RK3528_PD_VPU 8 + +#endif /* __DT_BINDINGS_POWER_RK3528_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3562-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3562-power.h new file mode 100755 index 00000000000..6d13350a52e --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3562-power.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3562_POWER_H__ +#define __DT_BINDINGS_POWER_RK3562_POWER_H__ + +/* VD_CORE */ +#define RK3562_PD_CPU_0 0 +#define RK3562_PD_CPU_1 1 +#define RK3562_PD_CPU_2 2 +#define RK3562_PD_CPU_3 3 +#define RK3562_PD_CORE_ALIVE 4 + +/* VD_PMU */ +#define RK3562_PD_PMU 5 +#define RK3562_PD_PMU_ALIVE 6 + +/* VD_NPU */ +#define RK3562_PD_NPU 7 + +/* VD_GPU */ +#define RK3562_PD_GPU 8 + +/* VD_LOGIC */ +#define RK3562_PD_DDR 9 +#define RK3562_PD_VEPU 10 +#define RK3562_PD_VDPU 11 +#define RK3562_PD_VI 12 +#define RK3562_PD_VO 13 +#define RK3562_PD_RGA 14 +#define RK3562_PD_PHP 15 +#define RK3562_PD_LOGIC_ALIVE 16 + +#endif /* __DT_BINDINGS_POWER_RK3562_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3568-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3568-power.h new file mode 100755 index 00000000000..7d32f6e0a99 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3568-power.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3568_POWER_H__ +#define __DT_BINDINGS_POWER_RK3568_POWER_H__ + +/* VD_CORE */ +#define RK3568_PD_CPU_0 0 +#define RK3568_PD_CPU_1 1 +#define RK3568_PD_CPU_2 2 +#define RK3568_PD_CPU_3 3 +#define RK3568_PD_CORE_ALIVE 4 + +/* VD_PMU */ +#define RK3568_PD_PMU 5 + +/* VD_NPU */ +#define RK3568_PD_NPU 6 + +/* VD_GPU */ +#define RK3568_PD_GPU 7 + +/* VD_LOGIC */ +#define RK3568_PD_VI 8 +#define RK3568_PD_VO 9 +#define RK3568_PD_RGA 10 +#define RK3568_PD_VPU 11 +#define RK3568_PD_CENTER 12 +#define RK3568_PD_RKVDEC 13 +#define RK3568_PD_RKVENC 14 +#define RK3568_PD_PIPE 15 +#define RK3568_PD_LOGIC_ALIVE 16 + +#endif /* __DT_BINDINGS_POWER_RK3568_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3576-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3576-power.h new file mode 100755 index 00000000000..b313433cb40 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3576-power.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2006-2024, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3576_POWER_H__ +#define __DT_BINDINGS_POWER_RK3576_POWER_H__ + +/* VD_NPU */ +#define RK3576_PD_NPU 0 +#define RK3576_PD_NPUTOP 1 +#define RK3576_PD_NPU0 2 +#define RK3576_PD_NPU1 3 + +/* VD_GPU */ +#define RK3576_PD_GPU 4 + +/* VD_LOGIC */ +#define RK3576_PD_NVM 5 +#define RK3576_PD_SDGMAC 6 +#define RK3576_PD_USB 7 +#define RK3576_PD_PHP 8 +#define RK3576_PD_SUBPHP 9 +#define RK3576_PD_AUDIO 10 +#define RK3576_PD_VEPU0 11 +#define RK3576_PD_VEPU1 12 +#define RK3576_PD_VPU 13 +#define RK3576_PD_VDEC 14 +#define RK3576_PD_VI 15 +#define RK3576_PD_VO0 16 +#define RK3576_PD_VO1 17 +#define RK3576_PD_VOP 18 + +#endif /* __DT_BINDINGS_POWER_RK3576_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rk3588-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rk3588-power.h new file mode 100755 index 00000000000..8438b6e66b3 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rk3588-power.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RK3588_POWER_H__ +#define __DT_BINDINGS_POWER_RK3588_POWER_H__ + +/* VD_LITDSU */ +#define RK3588_PD_CPU_0 0 +#define RK3588_PD_CPU_1 1 +#define RK3588_PD_CPU_2 2 +#define RK3588_PD_CPU_3 3 + +/* VD_BIGCORE0 */ +#define RK3588_PD_CPU_4 4 +#define RK3588_PD_CPU_5 5 + +/* VD_BIGCORE1 */ +#define RK3588_PD_CPU_6 6 +#define RK3588_PD_CPU_7 7 + +/* VD_NPU */ +#define RK3588_PD_NPU 8 +#define RK3588_PD_NPUTOP 9 +#define RK3588_PD_NPU1 10 +#define RK3588_PD_NPU2 11 + +/* VD_GPU */ +#define RK3588_PD_GPU 12 + +/* VD_VCODEC */ +#define RK3588_PD_VCODEC 13 +#define RK3588_PD_RKVDEC0 14 +#define RK3588_PD_RKVDEC1 15 +#define RK3588_PD_VENC0 16 +#define RK3588_PD_VENC1 17 + +/* VD_DD01 */ +#define RK3588_PD_DDR01 18 + +/* VD_DD23 */ +#define RK3588_PD_DDR23 19 + +/* VD_LOGIC */ +#define RK3588_PD_CENTER 20 +#define RK3588_PD_VDPU 21 +#define RK3588_PD_RGA30 22 +#define RK3588_PD_AV1 23 +#define RK3588_PD_VOP 24 +#define RK3588_PD_VO0 25 +#define RK3588_PD_VO1 26 +#define RK3588_PD_VI 27 +#define RK3588_PD_ISP1 28 +#define RK3588_PD_FEC 29 +#define RK3588_PD_RGA31 30 +#define RK3588_PD_USB 31 +#define RK3588_PD_PHP 32 +#define RK3588_PD_GMAC 33 +#define RK3588_PD_PCIE 34 +#define RK3588_PD_NVM 35 +#define RK3588_PD_NVM0 36 +#define RK3588_PD_SDIO 37 +#define RK3588_PD_AUDIO 38 +#define RK3588_PD_SECURE 39 +#define RK3588_PD_SDMMC 40 +#define RK3588_PD_CRYPTO 41 +#define RK3588_PD_BUS 42 + +/* VD_PMU */ +#define RK3588_PD_PMU1 43 + +#endif /* __DT_BINDINGS_POWER_RK3588_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/dt-bindings/power/rv1126-power.h b/bsp/rockchip/dm/include/dt-bindings/power/rv1126-power.h new file mode 100755 index 00000000000..eda1d6d71f1 --- /dev/null +++ b/bsp/rockchip/dm/include/dt-bindings/power/rv1126-power.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __DT_BINDINGS_POWER_RV1126_POWER_H__ +#define __DT_BINDINGS_POWER_RV1126_POWER_H__ + +/* VD_CORE */ +#define RV1126_PD_CPU_0 0 +#define RV1126_PD_CPU_1 1 +#define RV1126_PD_CPU_2 2 +#define RV1126_PD_CPU_3 3 +#define RV1126_PD_CORE_ALIVE 4 + +/* VD_PMU */ +#define RV1126_PD_PMU 5 +#define RV1126_PD_PMU_ALIVE 6 + +/* VD_NPU */ +#define RV1126_PD_NPU 7 + +/* VD_VEPU */ +#define RV1126_PD_VEPU 8 + +/* VD_LOGIC */ +#define RV1126_PD_VI 9 +#define RV1126_PD_VO 10 +#define RV1126_PD_ISPP 11 +#define RV1126_PD_VDPU 12 +#define RV1126_PD_CRYPTO 13 +#define RV1126_PD_DDR 14 +#define RV1126_PD_NVM 15 +#define RV1126_PD_SDIO 16 +#define RV1126_PD_USB 17 +#define RV1126_PD_LOGIC_ALIVE 18 + +#endif /* __DT_BINDINGS_POWER_RK3036_POWER_H__ */ diff --git a/bsp/rockchip/dm/include/hw-decompress.h b/bsp/rockchip/dm/include/hw-decompress.h new file mode 100755 index 00000000000..c63c90d1b6f --- /dev/null +++ b/bsp/rockchip/dm/include/hw-decompress.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-21 GuEe-GUI first version + */ + +#ifndef __HW_DECOMPRESS_H__ +#define __HW_DECOMPRESS_H__ + +#include + +#define HW_DECOMPRESS_NAME "hw_decom" + +enum hw_decompress_mod +{ + HW_DECOMPRESS_LZ4_MOD, + HW_DECOMPRESS_GZIP_MOD, + HW_DECOMPRESS_ZLIB_MOD, + HW_DECOMPRESS_MAX_MOD, +}; + +/* Input of RK_DECOM_USER */ +struct hw_decompress_param +{ + uint32_t mode; + uint32_t dst_max_size; + uint64_t src; + uint64_t dst; + uint64_t decom_data_len; +}; + +#define HW_DECOMPRESS_IOC_MAGIC 'D' + +#define HW_DECOMPRESS_REQ _IOWR(HW_DECOMPRESS_IOC_MAGIC, 0, struct hw_decompress_param) + +#endif /* __HW_DECOMPRESS_H__ */ diff --git a/bsp/rockchip/dm/include/pinctrl-rockchip.h b/bsp/rockchip/dm/include/pinctrl-rockchip.h new file mode 100755 index 00000000000..0e008963624 --- /dev/null +++ b/bsp/rockchip/dm/include/pinctrl-rockchip.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __ROCKCHIP_PINCTRL_H__ +#define __ROCKCHIP_PINCTRL_H__ + +#include +#include + +#include +#include + +#define ROCKCHIP_PULL_BITS_PER_PIN 2 +#define ROCKCHIP_PULL_PINS_PER_REG 8 +#define ROCKCHIP_PULL_BANK_STRIDE 16 +#define ROCKCHIP_DRV_BITS_PER_PIN 2 +#define ROCKCHIP_DRV_PINS_PER_REG 8 +#define ROCKCHIP_DRV_BANK_STRIDE 16 +#define ROCKCHIP_DRV_3BITS_PER_PIN 3 + +enum rockchip_pin_drv_type +{ + DRV_TYPE_IO_DEFAULT = 0, + DRV_TYPE_IO_1V8_OR_3V0, + DRV_TYPE_IO_1V8_ONLY, + DRV_TYPE_IO_1V8_3V0_AUTO, + DRV_TYPE_IO_3V3_ONLY, + DRV_TYPE_MAX +}; + +enum rockchip_pin_pull_type +{ + PULL_TYPE_IO_DEFAULT = 0, + PULL_TYPE_IO_1V8_ONLY, + PULL_TYPE_IO_1 = 1, + PULL_TYPE_MAX +}; + +enum rockchip_pinctrl_type +{ + RK3308, + RK3568, + RK3588, +}; + +struct rockchip_gpio_regs +{ + rt_uint32_t port_dr; /* Data register */ + rt_uint32_t port_ddr; /* Data direction register */ + rt_uint32_t int_en; /* Interrupt enable */ + rt_uint32_t int_mask; /* Interrupt mask */ + rt_uint32_t int_type; /* Interrupt trigger type, such as high, low, edge trriger type. */ + rt_uint32_t int_polarity; /* Interrupt polarity enable register */ + rt_uint32_t int_bothedge; /* Interrupt bothedge enable register */ + rt_uint32_t int_status; /* Interrupt status register */ + rt_uint32_t int_rawstatus; /* Int_status = int_rawstatus & int_mask */ + rt_uint32_t debounce; /* Enable debounce for interrupt signal */ + rt_uint32_t dbclk_div_en; /* Enable divider for debounce clock */ + rt_uint32_t dbclk_div_con; /* Setting for divider of debounce clock */ + rt_uint32_t port_eoi; /* End of interrupt of the port */ + rt_uint32_t ext_port; /* Port data from external */ + rt_uint32_t version_id; /* Controller version register */ +}; + +struct rockchip_iomux +{ + int type; + int offset; +}; + +struct rockchip_drv +{ + enum rockchip_pin_drv_type drv_type; + int offset; +}; + +struct rockchip_pin_data +{ + struct rt_syscon *regmap_base; + struct rt_syscon *regmap_pmu; + rt_size_t reg_size; + + struct rockchip_pin_ctrl *pinctrl; +}; + +struct rockchip_pin_bank +{ + struct rt_device_pin parent; + + const char *name; + + int irq; + void *reg_base; + struct rt_clk *clk; + struct rt_clk *db_clk; + + rt_uint8_t nr_pins; + rt_uint8_t bank_num; + rt_uint32_t gpio_type; + rt_uint32_t mask_cache; + rt_uint32_t toggle_edge_mode; + struct rockchip_pin_data *drvdata; + const struct rockchip_gpio_regs *gpio_regs; + + struct rockchip_iomux iomux[4]; + struct rockchip_drv drv[4]; + enum rockchip_pin_pull_type pull_type[4]; + struct rt_spinlock spinlock; + + rt_uint32_t route_mask; + rt_uint32_t recalced_mask; +}; + +#define raw_pin_to_bank(raw) rt_container_of(raw, struct rockchip_pin_bank, parent) + +struct rockchip_mux_recalced_data +{ + rt_uint8_t num; + rt_uint8_t pin; + rt_uint32_t reg; + rt_uint8_t bit; + rt_uint8_t mask; +}; + +enum rockchip_mux_route_location +{ + ROCKCHIP_ROUTE_SAME = 0, + ROCKCHIP_ROUTE_PMU, + ROCKCHIP_ROUTE_GRF, +}; + +struct rockchip_mux_route_data +{ + rt_uint8_t bank_num; + rt_uint8_t pin; + rt_uint8_t func; + enum rockchip_mux_route_location route_location; + rt_uint32_t route_offset; + rt_uint32_t route_val; +}; + +struct rockchip_pin_ctrl +{ + char *label; + enum rockchip_pinctrl_type type; + + struct rockchip_pin_bank *pin_banks; + rt_uint32_t banks_nr; + rt_uint32_t pins_nr; + + int grf_mux_offset; + int pmu_mux_offset; + int grf_drv_offset; + int pmu_drv_offset; + + struct rockchip_mux_recalced_data *iomux_recalced; + rt_uint32_t niomux_recalced; + + struct rockchip_mux_route_data *iomux_routes; + rt_uint32_t niomux_routes; + + rt_err_t (*set_mux)(struct rockchip_pin_bank *pin_bank, int pin, int mux); + rt_err_t (*set_pull)(struct rockchip_pin_bank *pin_bank, int pin, int pull); + rt_err_t (*set_drive)(struct rockchip_pin_bank *pin_bank, int pin, int strength); + rt_err_t (*set_schmitt)(struct rockchip_pin_bank *pin_bank, int pin, int enable); +}; + +struct rockchip_pinctrl_device +{ + struct rt_device_pin parent; + + struct rockchip_pin_data drvdata; + struct rockchip_pin_ctrl *pinctrl; +}; + +#endif /* __ROCKCHIP_PINCTRL_H__ */ diff --git a/bsp/rockchip/dm/include/rk8xx.h b/bsp/rockchip/dm/include/rk8xx.h new file mode 100755 index 00000000000..609693761d9 --- /dev/null +++ b/bsp/rockchip/dm/include/rk8xx.h @@ -0,0 +1,912 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#ifndef __RK8XX_H__ +#define __RK8XX_H__ + +#include +#include + +/* CONFIG REGISTER */ +#define RK805_VB_MON_REG 0x21 +#define RK805_THERMAL_REG 0x22 + +/* POWER CHANNELS ENABLE REGISTER */ +#define RK805_DCDC_EN_REG 0x23 +#define RK805_SLP_DCDC_EN_REG 0x25 +#define RK805_SLP_LDO_EN_REG 0x26 +#define RK805_LDO_EN_REG 0x27 + +/* BUCK AND LDO CONFIG REGISTER */ +#define RK805_BUCK_LDO_SLP_LP_EN_REG 0x2a +#define RK805_BUCK1_CONFIG_REG 0x2e +#define RK805_BUCK1_ON_VSEL_REG 0x2f +#define RK805_BUCK1_SLP_VSEL_REG 0x30 +#define RK805_BUCK2_CONFIG_REG 0x32 +#define RK805_BUCK2_ON_VSEL_REG 0x33 +#define RK805_BUCK2_SLP_VSEL_REG 0x34 +#define RK805_BUCK3_CONFIG_REG 0x36 +#define RK805_BUCK4_CONFIG_REG 0x37 +#define RK805_BUCK4_ON_VSEL_REG 0x38 +#define RK805_BUCK4_SLP_VSEL_REG 0x39 +#define RK805_LDO1_ON_VSEL_REG 0x3b +#define RK805_LDO1_SLP_VSEL_REG 0x3c +#define RK805_LDO2_ON_VSEL_REG 0x3d +#define RK805_LDO2_SLP_VSEL_REG 0x3e +#define RK805_LDO3_ON_VSEL_REG 0x3f +#define RK805_LDO3_SLP_VSEL_REG 0x40 + +/* INTERRUPT REGISTER */ +#define RK805_PWRON_LP_INT_TIME_REG 0x47 +#define RK805_PWRON_DB_REG 0x48 +#define RK805_DEV_CTRL_REG 0x4b +#define RK805_INT_STS_REG 0x4c +#define RK805_INT_STS_MSK_REG 0x4d +#define RK805_GPIO_IO_POL_REG 0x50 +#define RK805_OUT_REG 0x52 +#define RK805_ON_SOURCE_REG 0xae +#define RK805_OFF_SOURCE_REG 0xaf + +#define RK805_NUM_REGULATORS 7 + +#define RK805_PWRON_FALL_RISE_INT_EN 0x0 +#define RK805_PWRON_FALL_RISE_INT_MSK 0x81 + +#define RK805_BUCK1_2_ILMAX_2500MA 0x0 +#define RK805_BUCK1_2_ILMAX_3000MA 0x1 +#define RK805_BUCK1_2_ILMAX_3500MA 0x2 +#define RK805_BUCK1_2_ILMAX_4000MA 0x3 + +#define RK805_BUCK3_ILMAX_1500MA 0x0 +#define RK805_BUCK3_ILMAX_2000MA 0x1 +#define RK805_BUCK3_ILMAX_2500MA 0x2 +#define RK805_BUCK3_ILMAX_3000MA 0x3 + +#define RK805_BUCK4_ILMAX_2000MA 0x0 +#define RK805_BUCK4_ILMAX_2500MA 0x1 +#define RK805_BUCK4_ILMAX_3000MA 0x2 +#define RK805_BUCK4_ILMAX_3500MA 0x3 + +/* RK805 IRQ Definitions */ +#define RK805_IRQ_PWRON_RISE 0 +#define RK805_IRQ_VB_LOW 1 +#define RK805_IRQ_PWRON 2 +#define RK805_IRQ_PWRON_LP 3 +#define RK805_IRQ_HOTDIE 4 +#define RK805_IRQ_RTC_ALARM 5 +#define RK805_IRQ_RTC_PERIOD 6 +#define RK805_IRQ_PWRON_FALL 7 + +#define RK805_IRQ_PWRON_RISE_MSK RT_BIT(0) +#define RK805_IRQ_VB_LOW_MSK RT_BIT(1) +#define RK805_IRQ_PWRON_MSK RT_BIT(2) +#define RK805_IRQ_PWRON_LP_MSK RT_BIT(3) +#define RK805_IRQ_HOTDIE_MSK RT_BIT(4) +#define RK805_IRQ_RTC_ALARM_MSK RT_BIT(5) +#define RK805_IRQ_RTC_PERIOD_MSK RT_BIT(6) +#define RK805_IRQ_PWRON_FALL_MSK RT_BIT(7) + +#define RK805_PWR_RISE_INT_STATUS RT_BIT(0) +#define RK805_VB_LOW_INT_STATUS RT_BIT(1) +#define RK805_PWRON_INT_STATUS RT_BIT(2) +#define RK805_PWRON_LP_INT_STATUS RT_BIT(3) +#define RK805_HOTDIE_INT_STATUS RT_BIT(4) +#define RK805_ALARM_INT_STATUS RT_BIT(5) +#define RK805_PERIOD_INT_STATUS RT_BIT(6) +#define RK805_PWR_FALL_INT_STATUS RT_BIT(7) + +#define RK805_BUCK1_2_ILMAX_MASK (3 << 6) +#define RK805_BUCK3_4_ILMAX_MASK (3 << 3) +#define RK805_RTC_PERIOD_INT_MASK (1 << 6) +#define RK805_RTC_ALARM_INT_MASK (1 << 5) +#define RK805_INT_ALARM_EN (1 << 3) +#define RK805_INT_TIMER_EN (1 << 2) + +#define RK806_POWER_EN0 0x0 +#define RK806_POWER_EN1 0x1 +#define RK806_POWER_EN2 0x2 +#define RK806_POWER_EN3 0x3 +#define RK806_POWER_EN4 0x4 +#define RK806_POWER_EN5 0x5 +#define RK806_POWER_SLP_EN0 0x6 +#define RK806_POWER_SLP_EN1 0x7 +#define RK806_POWER_SLP_EN2 0x8 +#define RK806_POWER_DISCHRG_EN0 0x9 +#define RK806_POWER_DISCHRG_EN1 0xa +#define RK806_POWER_DISCHRG_EN2 0xb +#define RK806_BUCK_FB_CONFIG 0xc +#define RK806_SLP_LP_CONFIG 0xd +#define RK806_POWER_FPWM_EN0 0xe +#define RK806_POWER_FPWM_EN1 0xf +#define RK806_BUCK1_CONFIG 0x10 +#define RK806_BUCK2_CONFIG 0x11 +#define RK806_BUCK3_CONFIG 0x12 +#define RK806_BUCK4_CONFIG 0x13 +#define RK806_BUCK5_CONFIG 0x14 +#define RK806_BUCK6_CONFIG 0x15 +#define RK806_BUCK7_CONFIG 0x16 +#define RK806_BUCK8_CONFIG 0x17 +#define RK806_BUCK9_CONFIG 0x18 +#define RK806_BUCK10_CONFIG 0x19 +#define RK806_BUCK1_ON_VSEL 0x1a +#define RK806_BUCK2_ON_VSEL 0x1b +#define RK806_BUCK3_ON_VSEL 0x1c +#define RK806_BUCK4_ON_VSEL 0x1d +#define RK806_BUCK5_ON_VSEL 0x1e +#define RK806_BUCK6_ON_VSEL 0x1f +#define RK806_BUCK7_ON_VSEL 0x20 +#define RK806_BUCK8_ON_VSEL 0x21 +#define RK806_BUCK9_ON_VSEL 0x22 +#define RK806_BUCK10_ON_VSEL 0x23 +#define RK806_BUCK1_SLP_VSEL 0x24 +#define RK806_BUCK2_SLP_VSEL 0x25 +#define RK806_BUCK3_SLP_VSEL 0x26 +#define RK806_BUCK4_SLP_VSEL 0x27 +#define RK806_BUCK5_SLP_VSEL 0x28 +#define RK806_BUCK6_SLP_VSEL 0x29 +#define RK806_BUCK7_SLP_VSEL 0x2a +#define RK806_BUCK8_SLP_VSEL 0x2b +#define RK806_BUCK9_SLP_VSEL 0x2d +#define RK806_BUCK10_SLP_VSEL 0x2e +#define RK806_BUCK_DEBUG1 0x30 +#define RK806_BUCK_DEBUG2 0x31 +#define RK806_BUCK_DEBUG3 0x32 +#define RK806_BUCK_DEBUG4 0x33 +#define RK806_BUCK_DEBUG5 0x34 +#define RK806_BUCK_DEBUG6 0x35 +#define RK806_BUCK_DEBUG7 0x36 +#define RK806_BUCK_DEBUG8 0x37 +#define RK806_BUCK_DEBUG9 0x38 +#define RK806_BUCK_DEBUG10 0x39 +#define RK806_BUCK_DEBUG11 0x3a +#define RK806_BUCK_DEBUG12 0x3b +#define RK806_BUCK_DEBUG13 0x3c +#define RK806_BUCK_DEBUG14 0x3d +#define RK806_BUCK_DEBUG15 0x3e +#define RK806_BUCK_DEBUG16 0x3f +#define RK806_BUCK_DEBUG17 0x40 +#define RK806_BUCK_DEBUG18 0x41 +#define RK806_NLDO_IMAX 0x42 +#define RK806_NLDO1_ON_VSEL 0x43 +#define RK806_NLDO2_ON_VSEL 0x44 +#define RK806_NLDO3_ON_VSEL 0x45 +#define RK806_NLDO4_ON_VSEL 0x46 +#define RK806_NLDO5_ON_VSEL 0x47 +#define RK806_NLDO1_SLP_VSEL 0x48 +#define RK806_NLDO2_SLP_VSEL 0x49 +#define RK806_NLDO3_SLP_VSEL 0x4a +#define RK806_NLDO4_SLP_VSEL 0x4b +#define RK806_NLDO5_SLP_VSEL 0x4c +#define RK806_PLDO_IMAX 0x4d +#define RK806_PLDO1_ON_VSEL 0x4e +#define RK806_PLDO2_ON_VSEL 0x4f +#define RK806_PLDO3_ON_VSEL 0x50 +#define RK806_PLDO4_ON_VSEL 0x51 +#define RK806_PLDO5_ON_VSEL 0x52 +#define RK806_PLDO6_ON_VSEL 0x53 +#define RK806_PLDO1_SLP_VSEL 0x54 +#define RK806_PLDO2_SLP_VSEL 0x55 +#define RK806_PLDO3_SLP_VSEL 0x56 +#define RK806_PLDO4_SLP_VSEL 0x57 +#define RK806_PLDO5_SLP_VSEL 0x58 +#define RK806_PLDO6_SLP_VSEL 0x59 +#define RK806_CHIP_NAME 0x5a +#define RK806_CHIP_VER 0x5b +#define RK806_OTP_VER 0x5c +#define RK806_SYS_STS 0x5d +#define RK806_SYS_CFG0 0x5e +#define RK806_SYS_CFG1 0x5f +#define RK806_SYS_OPTION 0x61 +#define RK806_SLEEP_CONFIG0 0x62 +#define RK806_SLEEP_CONFIG1 0x63 +#define RK806_SLEEP_CTR_SEL0 0x64 +#define RK806_SLEEP_CTR_SEL1 0x65 +#define RK806_SLEEP_CTR_SEL2 0x66 +#define RK806_SLEEP_CTR_SEL3 0x67 +#define RK806_SLEEP_CTR_SEL4 0x68 +#define RK806_SLEEP_CTR_SEL5 0x69 +#define RK806_DVS_CTRL_SEL0 0x6a +#define RK806_DVS_CTRL_SEL1 0x6b +#define RK806_DVS_CTRL_SEL2 0x6c +#define RK806_DVS_CTRL_SEL3 0x6d +#define RK806_DVS_CTRL_SEL4 0x6e +#define RK806_DVS_CTRL_SEL5 0x6f +#define RK806_DVS_START_CTRL 0x70 +#define RK806_SLEEP_GPIO 0x71 +#define RK806_SYS_CFG3 0x72 +#define RK806_WDT 0x73 +#define RK806_ON_SOURCE 0x74 +#define RK806_OFF_SOURCE 0x75 +#define RK806_PWRON_KEY 0x76 +#define RK806_INT_STS0 0x77 +#define RK806_INT_MSK0 0x78 +#define RK806_INT_STS1 0x79 +#define RK806_INT_MSK1 0x7a +#define RK806_GPIO_INT_CONFIG 0x7b +#define RK806_DATA_REG0 0x7c +#define RK806_DATA_REG1 0x7d +#define RK806_DATA_REG2 0x7e +#define RK806_DATA_REG3 0x7f +#define RK806_DATA_REG4 0x80 +#define RK806_DATA_REG5 0x81 +#define RK806_DATA_REG6 0x82 +#define RK806_DATA_REG7 0x83 +#define RK806_DATA_REG8 0x84 +#define RK806_DATA_REG9 0x85 +#define RK806_DATA_REG10 0x86 +#define RK806_DATA_REG11 0x87 +#define RK806_DATA_REG12 0x88 +#define RK806_DATA_REG13 0x89 +#define RK806_DATA_REG14 0x8a +#define RK806_DATA_REG15 0x8b +#define RK806_TM_REG 0x8c +#define RK806_OTP_EN_REG 0x8d +#define RK806_FUNC_OTP_EN_REG 0x8e +#define RK806_TEST_REG1 0x8f +#define RK806_TEST_REG2 0x90 +#define RK806_TEST_REG3 0x91 +#define RK806_TEST_REG4 0x92 +#define RK806_TEST_REG5 0x93 +#define RK806_BUCK_VSEL_OTP_REG0 0x94 +#define RK806_BUCK_VSEL_OTP_REG1 0x95 +#define RK806_BUCK_VSEL_OTP_REG2 0x96 +#define RK806_BUCK_VSEL_OTP_REG3 0x97 +#define RK806_BUCK_VSEL_OTP_REG4 0x98 +#define RK806_BUCK_VSEL_OTP_REG5 0x99 +#define RK806_BUCK_VSEL_OTP_REG6 0x9a +#define RK806_BUCK_VSEL_OTP_REG7 0x9b +#define RK806_BUCK_VSEL_OTP_REG8 0x9c +#define RK806_BUCK_VSEL_OTP_REG9 0x9d +#define RK806_NLDO1_VSEL_OTP_REG0 0x9e +#define RK806_NLDO1_VSEL_OTP_REG1 0x9f +#define RK806_NLDO1_VSEL_OTP_REG2 0xa0 +#define RK806_NLDO1_VSEL_OTP_REG3 0xa1 +#define RK806_NLDO1_VSEL_OTP_REG4 0xa2 +#define RK806_PLDO_VSEL_OTP_REG0 0xa3 +#define RK806_PLDO_VSEL_OTP_REG1 0xa4 +#define RK806_PLDO_VSEL_OTP_REG2 0xa5 +#define RK806_PLDO_VSEL_OTP_REG3 0xa6 +#define RK806_PLDO_VSEL_OTP_REG4 0xa7 +#define RK806_PLDO_VSEL_OTP_REG5 0xa8 +#define RK806_BUCK_EN_OTP_REG1 0xa9 +#define RK806_NLDO_EN_OTP_REG1 0xaa +#define RK806_PLDO_EN_OTP_REG1 0xab +#define RK806_BUCK_FB_RES_OTP_REG1 0xac +#define RK806_OTP_RESEV_REG0 0xad +#define RK806_OTP_RESEV_REG1 0xae +#define RK806_OTP_RESEV_REG2 0xaf +#define RK806_OTP_RESEV_REG3 0xb0 +#define RK806_OTP_RESEV_REG4 0xb1 +#define RK806_BUCK_SEQ_REG0 0xb2 +#define RK806_BUCK_SEQ_REG1 0xb3 +#define RK806_BUCK_SEQ_REG2 0xb4 +#define RK806_BUCK_SEQ_REG3 0xb5 +#define RK806_BUCK_SEQ_REG4 0xb6 +#define RK806_BUCK_SEQ_REG5 0xb7 +#define RK806_BUCK_SEQ_REG6 0xb8 +#define RK806_BUCK_SEQ_REG7 0xb9 +#define RK806_BUCK_SEQ_REG8 0xba +#define RK806_BUCK_SEQ_REG9 0xbb +#define RK806_BUCK_SEQ_REG10 0xbc +#define RK806_BUCK_SEQ_REG11 0xbd +#define RK806_BUCK_SEQ_REG12 0xbe +#define RK806_BUCK_SEQ_REG13 0xbf +#define RK806_BUCK_SEQ_REG14 0xc0 +#define RK806_BUCK_SEQ_REG15 0xc1 +#define RK806_BUCK_SEQ_REG16 0xc2 +#define RK806_BUCK_SEQ_REG17 0xc3 +#define RK806_HK_TRIM_REG1 0xc4 +#define RK806_HK_TRIM_REG2 0xc5 +#define RK806_BUCK_REF_TRIM_REG1 0xc6 +#define RK806_BUCK_REF_TRIM_REG2 0xc7 +#define RK806_BUCK_REF_TRIM_REG3 0xc8 +#define RK806_BUCK_REF_TRIM_REG4 0xc9 +#define RK806_BUCK_REF_TRIM_REG5 0xca +#define RK806_BUCK_OSC_TRIM_REG1 0xcb +#define RK806_BUCK_OSC_TRIM_REG2 0xcc +#define RK806_BUCK_OSC_TRIM_REG3 0xcd +#define RK806_BUCK_OSC_TRIM_REG4 0xce +#define RK806_BUCK_OSC_TRIM_REG5 0xcf +#define RK806_BUCK_TRIM_ZCDIOS_REG1 0xd0 +#define RK806_BUCK_TRIM_ZCDIOS_REG2 0xd1 +#define RK806_NLDO_TRIM_REG1 0xd2 +#define RK806_NLDO_TRIM_REG2 0xd3 +#define RK806_NLDO_TRIM_REG3 0xd4 +#define RK806_PLDO_TRIM_REG1 0xd5 +#define RK806_PLDO_TRIM_REG2 0xd6 +#define RK806_PLDO_TRIM_REG3 0xd7 +#define RK806_TRIM_ICOMP_REG1 0xd8 +#define RK806_TRIM_ICOMP_REG2 0xd9 +#define RK806_EFUSE_CONTROL_REGH 0xda +#define RK806_FUSE_PROG_REG 0xdb +#define RK806_MAIN_FSM_STS_REG 0xdd +#define RK806_FSM_REG 0xde +#define RK806_TOP_RESEV_OFFR 0xec +#define RK806_TOP_RESEV_POR 0xed +#define RK806_BUCK_VRSN_REG1 0xee +#define RK806_BUCK_VRSN_REG2 0xef +#define RK806_NLDO_RLOAD_SEL_REG1 0xf0 +#define RK806_PLDO_RLOAD_SEL_REG1 0xf1 +#define RK806_PLDO_RLOAD_SEL_REG2 0xf2 +#define RK806_BUCK_CMIN_MX_REG1 0xf3 +#define RK806_BUCK_CMIN_MX_REG2 0xf4 +#define RK806_BUCK_FREQ_SET_REG1 0xf5 +#define RK806_BUCK_FREQ_SET_REG2 0xf6 +#define RK806_BUCK_RS_MEABS_REG1 0xf7 +#define RK806_BUCK_RS_MEABS_REG2 0xf8 +#define RK806_BUCK_RS_ZDLEB_REG1 0xf9 +#define RK806_BUCK_RS_ZDLEB_REG2 0xfa +#define RK806_BUCK_RSERVE_REG1 0xfb +#define RK806_BUCK_RSERVE_REG2 0xfc +#define RK806_BUCK_RSERVE_REG3 0xfd +#define RK806_BUCK_RSERVE_REG4 0xfe +#define RK806_BUCK_RSERVE_REG5 0xff + +#define RK806_WDT_ACT RT_BIT(4) +#define RK806_WDT_ACT_SEND_IRQ 0 +#define RK806_WDT_ACT_RESTART 1 +#define RK806_WDT_EN RT_BIT(3) +#define RK806_WDT_SET RT_GENMASK(2, 0) + +/* INT_STS Register field definitions */ +#define RK806_INT_STS_PWRON_FALL RT_BIT(0) +#define RK806_INT_STS_PWRON_RISE RT_BIT(1) +#define RK806_INT_STS_PWRON RT_BIT(2) +#define RK806_INT_STS_PWRON_LP RT_BIT(3) +#define RK806_INT_STS_HOTDIE RT_BIT(4) +#define RK806_INT_STS_VDC_RISE RT_BIT(5) +#define RK806_INT_STS_VDC_FALL RT_BIT(6) +#define RK806_INT_STS_VB_LO RT_BIT(7) +#define RK806_INT_STS_REV0 RT_BIT(0) +#define RK806_INT_STS_REV1 RT_BIT(1) +#define RK806_INT_STS_REV2 RT_BIT(2) +#define RK806_INT_STS_CRC_ERROR RT_BIT(3) +#define RK806_INT_STS_SLP3_GPIO RT_BIT(4) +#define RK806_INT_STS_SLP2_GPIO RT_BIT(5) +#define RK806_INT_STS_SLP1_GPIO RT_BIT(6) +#define RK806_INT_STS_WDT RT_BIT(7) + +#define RK806_INT_POL_MSK RT_BIT(1) +#define RK806_INT_POL_H RT_BIT(1) +#define RK806_INT_POL_L 0 + +#define RK806_SLAVE_RESTART_FUN_MSK RT_BIT(1) +#define RK806_SLAVE_RESTART_FUN_EN RT_BIT(1) +#define RK806_SLAVE_RESTART_FUN_OFF 0 + +#define RK806_SYS_ENB2_2M_MSK RT_BIT(1) +#define RK806_SYS_ENB2_2M_EN RT_BIT(1) +#define RK806_SYS_ENB2_2M_OFF 0 + +#define RK806_CMD_READ 0 +#define RK806_CMD_WRITE RT_BIT(7) +#define RK806_CMD_CRC_EN RT_BIT(6) +#define RK806_CMD_CRC_DIS 0 +#define RK806_CMD_LEN_MSK 0x0f +#define RK806_REG_H 0x00 + +/* RK806 INT_STS0 registers */ +#define RK806_IRQ_PWRON_FALL 0 +#define RK806_IRQ_PWRON_RISE 1 +#define RK806_IRQ_PWRON 2 +#define RK806_IRQ_PWRON_LP 3 +#define RK806_IRQ_HOTDIE 4 +#define RK806_IRQ_VDC_RISE 5 +#define RK806_IRQ_VDC_FALL 6 +#define RK806_IRQ_VB_LO 7 + +/* RK806 INT_STS0 registers */ +#define RK806_IRQ_REV0 8 +#define RK806_IRQ_REV1 9 +#define RK806_IRQ_REV2 10 +#define RK806_IRQ_CRC_ERROR 11 +#define RK806_IRQ_SLP3_GPIO 12 +#define RK806_IRQ_SLP2_GPIO 13 +#define RK806_IRQ_SLP1_GPIO 14 +#define RK806_IRQ_WDT 15 + +#define RK808_SECONDS_REG 0x00 +#define RK808_MINUTES_REG 0x01 +#define RK808_HOURS_REG 0x02 +#define RK808_DAYS_REG 0x03 +#define RK808_MONTHS_REG 0x04 +#define RK808_YEARS_REG 0x05 +#define RK808_WEEKS_REG 0x06 +#define RK808_ALARM_SECONDS_REG 0x08 +#define RK808_ALARM_MINUTES_REG 0x09 +#define RK808_ALARM_HOURS_REG 0x0a +#define RK808_ALARM_DAYS_REG 0x0b +#define RK808_ALARM_MONTHS_REG 0x0c +#define RK808_ALARM_YEARS_REG 0x0d +#define RK808_RTC_CTRL_REG 0x10 +#define RK808_RTC_STATUS_REG 0x11 +#define RK808_RTC_INT_REG 0x12 +#define RK808_RTC_COMP_LSB_REG 0x13 +#define RK808_RTC_COMP_MSB_REG 0x14 +#define RK808_ID_MSB 0x17 +#define RK808_ID_LSB 0x18 +#define RK808_CLK32OUT_REG 0x20 +#define RK808_VB_MON_REG 0x21 +#define RK808_THERMAL_REG 0x22 +#define RK808_DCDC_EN_REG 0x23 +#define RK808_LDO_EN_REG 0x24 +#define RK808_SLEEP_SET_OFF_REG1 0x25 +#define RK808_SLEEP_SET_OFF_REG2 0x26 +#define RK808_DCDC_UV_STS_REG 0x27 +#define RK808_DCDC_UV_ACT_REG 0x28 +#define RK808_LDO_UV_STS_REG 0x29 +#define RK808_LDO_UV_ACT_REG 0x2a +#define RK808_DCDC_PG_REG 0x2b +#define RK808_LDO_PG_REG 0x2c +#define RK808_VOUT_MON_TDB_REG 0x2d +#define RK808_BUCK1_CONFIG_REG 0x2e +#define RK808_BUCK1_ON_VSEL_REG 0x2f +#define RK808_BUCK1_SLP_VSEL_REG 0x30 +#define RK808_BUCK1_DVS_VSEL_REG 0x31 +#define RK808_BUCK2_CONFIG_REG 0x32 +#define RK808_BUCK2_ON_VSEL_REG 0x33 +#define RK808_BUCK2_SLP_VSEL_REG 0x34 +#define RK808_BUCK2_DVS_VSEL_REG 0x35 +#define RK808_BUCK3_CONFIG_REG 0x36 +#define RK808_BUCK4_CONFIG_REG 0x37 +#define RK808_BUCK4_ON_VSEL_REG 0x38 +#define RK808_BUCK4_SLP_VSEL_REG 0x39 +#define RK808_BOOST_CONFIG_REG 0x3a +#define RK808_LDO1_ON_VSEL_REG 0x3b +#define RK808_LDO1_SLP_VSEL_REG 0x3c +#define RK808_LDO2_ON_VSEL_REG 0x3d +#define RK808_LDO2_SLP_VSEL_REG 0x3e +#define RK808_LDO3_ON_VSEL_REG 0x3f +#define RK808_LDO3_SLP_VSEL_REG 0x40 +#define RK808_LDO4_ON_VSEL_REG 0x41 +#define RK808_LDO4_SLP_VSEL_REG 0x42 +#define RK808_LDO5_ON_VSEL_REG 0x43 +#define RK808_LDO5_SLP_VSEL_REG 0x44 +#define RK808_LDO6_ON_VSEL_REG 0x45 +#define RK808_LDO6_SLP_VSEL_REG 0x46 +#define RK808_LDO7_ON_VSEL_REG 0x47 +#define RK808_LDO7_SLP_VSEL_REG 0x48 +#define RK808_LDO8_ON_VSEL_REG 0x49 +#define RK808_LDO8_SLP_VSEL_REG 0x4a +#define RK808_DEVCTRL_REG 0x4b +#define RK808_INT_STS_REG1 0x4c +#define RK808_INT_STS_MSK_REG1 0x4d +#define RK808_INT_STS_REG2 0x4e +#define RK808_INT_STS_MSK_REG2 0x4f +#define RK808_IO_POL_REG 0x50 + +/* RK808 IRQ Definitions */ +#define RK808_IRQ_VOUT_LO 0 +#define RK808_IRQ_VB_LO 1 +#define RK808_IRQ_PWRON 2 +#define RK808_IRQ_PWRON_LP 3 +#define RK808_IRQ_HOTDIE 4 +#define RK808_IRQ_RTC_ALARM 5 +#define RK808_IRQ_RTC_PERIOD 6 +#define RK808_IRQ_PLUG_IN_INT 7 +#define RK808_IRQ_PLUG_OUT_INT 8 +#define RK808_NUM_IRQ 9 + +#define RK808_IRQ_VOUT_LO_MSK RT_BIT(0) +#define RK808_IRQ_VB_LO_MSK RT_BIT(1) +#define RK808_IRQ_PWRON_MSK RT_BIT(2) +#define RK808_IRQ_PWRON_LP_MSK RT_BIT(3) +#define RK808_IRQ_HOTDIE_MSK RT_BIT(4) +#define RK808_IRQ_RTC_ALARM_MSK RT_BIT(5) +#define RK808_IRQ_RTC_PERIOD_MSK RT_BIT(6) +#define RK808_IRQ_PLUG_IN_INT_MSK RT_BIT(0) +#define RK808_IRQ_PLUG_OUT_INT_MSK RT_BIT(1) + +#define RK809_BUCK5_CONFIG(i) (RK817_BOOST_OTG_CFG + (i) * 1) + +#define RK817_SECONDS_REG 0x00 +#define RK817_MINUTES_REG 0x01 +#define RK817_HOURS_REG 0x02 +#define RK817_DAYS_REG 0x03 +#define RK817_MONTHS_REG 0x04 +#define RK817_YEARS_REG 0x05 +#define RK817_WEEKS_REG 0x06 +#define RK817_ALARM_SECONDS_REG 0x07 +#define RK817_ALARM_MINUTES_REG 0x08 +#define RK817_ALARM_HOURS_REG 0x09 +#define RK817_ALARM_DAYS_REG 0x0a +#define RK817_ALARM_MONTHS_REG 0x0b +#define RK817_ALARM_YEARS_REG 0x0c +#define RK817_RTC_CTRL_REG 0xd +#define RK817_RTC_STATUS_REG 0xe +#define RK817_RTC_INT_REG 0xf +#define RK817_RTC_COMP_LSB_REG 0x10 +#define RK817_RTC_COMP_MSB_REG 0x11 + +/* RK817 Codec Registers */ +#define RK817_CODEC_DTOP_VUCTL 0x12 +#define RK817_CODEC_DTOP_VUCTIME 0x13 +#define RK817_CODEC_DTOP_LPT_SRST 0x14 +#define RK817_CODEC_DTOP_DIGEN_CLKE 0x15 +#define RK817_CODEC_AREF_RTCFG0 0x16 +#define RK817_CODEC_AREF_RTCFG1 0x17 +#define RK817_CODEC_AADC_CFG0 0x18 +#define RK817_CODEC_AADC_CFG1 0x19 +#define RK817_CODEC_DADC_VOLL 0x1a +#define RK817_CODEC_DADC_VOLR 0x1b +#define RK817_CODEC_DADC_SR_ACL0 0x1e +#define RK817_CODEC_DADC_ALC1 0x1f +#define RK817_CODEC_DADC_ALC2 0x20 +#define RK817_CODEC_DADC_NG 0x21 +#define RK817_CODEC_DADC_HPF 0x22 +#define RK817_CODEC_DADC_RVOLL 0x23 +#define RK817_CODEC_DADC_RVOLR 0x24 +#define RK817_CODEC_AMIC_CFG0 0x27 +#define RK817_CODEC_AMIC_CFG1 0x28 +#define RK817_CODEC_DMIC_PGA_GAIN 0x29 +#define RK817_CODEC_DMIC_LMT1 0x2a +#define RK817_CODEC_DMIC_LMT2 0x2b +#define RK817_CODEC_DMIC_NG1 0x2c +#define RK817_CODEC_DMIC_NG2 0x2d +#define RK817_CODEC_ADAC_CFG0 0x2e +#define RK817_CODEC_ADAC_CFG1 0x2f +#define RK817_CODEC_DDAC_POPD_DACST 0x30 +#define RK817_CODEC_DDAC_VOLL 0x31 +#define RK817_CODEC_DDAC_VOLR 0x32 +#define RK817_CODEC_DDAC_SR_LMT0 0x35 +#define RK817_CODEC_DDAC_LMT1 0x36 +#define RK817_CODEC_DDAC_LMT2 0x37 +#define RK817_CODEC_DDAC_MUTE_MIXCTL 0x38 +#define RK817_CODEC_DDAC_RVOLL 0x39 +#define RK817_CODEC_DDAC_RVOLR 0x3a +#define RK817_CODEC_AHP_ANTI0 0x3b +#define RK817_CODEC_AHP_ANTI1 0x3c +#define RK817_CODEC_AHP_CFG0 0x3d +#define RK817_CODEC_AHP_CFG1 0x3e +#define RK817_CODEC_AHP_CP 0x3f +#define RK817_CODEC_ACLASSD_CFG1 0x40 +#define RK817_CODEC_ACLASSD_CFG2 0x41 +#define RK817_CODEC_APLL_CFG0 0x42 +#define RK817_CODEC_APLL_CFG1 0x43 +#define RK817_CODEC_APLL_CFG2 0x44 +#define RK817_CODEC_APLL_CFG3 0x45 +#define RK817_CODEC_APLL_CFG4 0x46 +#define RK817_CODEC_APLL_CFG5 0x47 +#define RK817_CODEC_DI2S_CKM 0x48 +#define RK817_CODEC_DI2S_RSD 0x49 +#define RK817_CODEC_DI2S_RXCR1 0x4a +#define RK817_CODEC_DI2S_RXCR2 0x4b +#define RK817_CODEC_DI2S_RXCMD_TSD 0x4c +#define RK817_CODEC_DI2S_TXCR1 0x4d +#define RK817_CODEC_DI2S_TXCR2 0x4e +#define RK817_CODEC_DI2S_TXCR3_TXCMD 0x4f + +#define RK817_POWER_EN_REG(i) (0xb1 + (i)) +#define RK817_POWER_SLP_EN_REG(i) (0xb5 + (i)) + +#define RK817_POWER_CONFIG (0xb9) + +#define RK817_BUCK_CONFIG_REG(i) (0xba + (i) * 3) + +#define RK817_BUCK1_ON_VSEL_REG 0xbb +#define RK817_BUCK1_SLP_VSEL_REG 0xbc + +#define RK817_BUCK2_CONFIG_REG 0xbd +#define RK817_BUCK2_ON_VSEL_REG 0xbe +#define RK817_BUCK2_SLP_VSEL_REG 0xbf + +#define RK817_BUCK3_CONFIG_REG 0xc0 +#define RK817_BUCK3_ON_VSEL_REG 0xc1 +#define RK817_BUCK3_SLP_VSEL_REG 0xc2 + +#define RK817_BUCK4_CONFIG_REG 0xc3 +#define RK817_BUCK4_ON_VSEL_REG 0xc4 +#define RK817_BUCK4_SLP_VSEL_REG 0xc5 + +#define RK817_LDO_ON_VSEL_REG(idx) (0xcc + (idx) * 2) +#define RK817_BOOST_OTG_CFG (0xde) + +#define RK817_HOTDIE_TEMP_MSK (0x3 << 4) +#define RK817_HOTDIE_85 (0x0 << 4) +#define RK817_HOTDIE_95 (0x1 << 4) +#define RK817_HOTDIE_105 (0x2 << 4) +#define RK817_HOTDIE_115 (0x3 << 4) + +#define RK817_TSD_TEMP_MSK RT_BIT(6) +#define RK817_TSD_140 0 +#define RK817_TSD_160 RT_BIT(6) + +#define RK817_INT_POL_MSK RT_BIT(1) +#define RK817_INT_POL_H RT_BIT(1) +#define RK817_INT_POL_L 0 + +enum rk817_reg_id +{ + RK817_ID_DCDC1 = 0, + RK817_ID_DCDC2, + RK817_ID_DCDC3, + RK817_ID_DCDC4, + RK817_ID_LDO1, + RK817_ID_LDO2, + RK817_ID_LDO3, + RK817_ID_LDO4, + RK817_ID_LDO5, + RK817_ID_LDO6, + RK817_ID_LDO7, + RK817_ID_LDO8, + RK817_ID_LDO9, + RK817_ID_BOOST, + RK817_ID_BOOST_OTG_SW, + RK817_NUM_REGULATORS +}; + +#define RK817_SYS_CFG(i) ((i) + 0xf1) + +#define RK817_CLK32KOUT2_EN RT_BIT(7) + +#define RK817_SLPPIN_FUNC_MSK (0x3 << 3) +#define SLPPIN_NULL_FUN (0x0 << 3) +#define SLPPIN_SLP_FUN (0x1 << 3) +#define SLPPIN_DN_FUN (0x2 << 3) +#define SLPPIN_RST_FUN (0x3 << 3) + +#define RK817_RST_FUNC_MSK (0x3 << 6) +#define RK817_RST_FUNC_SFT (6) +#define RK817_RST_FUNC_CNT (3) +#define RK817_RST_FUNC_DEV (0) /* reset the dev */ +#define RK817_RST_FUNC_REG (0x1 << 6) /* reset the reg only */ + +/* INTERRUPT REGISTER */ +#define RK817_INT_STS_REG0 0xf8 +#define RK817_INT_STS_MSK_REG0 0xf9 +#define RK817_INT_STS_REG1 0xfa +#define RK817_INT_STS_MSK_REG1 0xfb +#define RK817_INT_STS_REG2 0xfc +#define RK817_INT_STS_MSK_REG2 0xfd +#define RK817_GPIO_INT_CFG 0xfe + +/* IRQ Definitions */ +#define RK817_IRQ_PWRON_FALL 0 +#define RK817_IRQ_PWRON_RISE 1 +#define RK817_IRQ_PWRON 2 +#define RK817_IRQ_PWMON_LP 3 +#define RK817_IRQ_HOTDIE 4 +#define RK817_IRQ_RTC_ALARM 5 +#define RK817_IRQ_RTC_PERIOD 6 +#define RK817_IRQ_VB_LO 7 +#define RK817_IRQ_PLUG_IN 8 +#define RK817_IRQ_PLUG_OUT 9 +#define RK817_IRQ_CHRG_TERM 10 +#define RK817_IRQ_CHRG_TIME 11 +#define RK817_IRQ_CHRG_TS 12 +#define RK817_IRQ_USB_OV 13 +#define RK817_IRQ_CHRG_IN_CLMP 14 +#define RK817_IRQ_BAT_DIS_ILIM 15 +#define RK817_IRQ_GATE_GPIO 16 +#define RK817_IRQ_TS_GPIO 17 +#define RK817_IRQ_CODEC_PD 18 +#define RK817_IRQ_CODEC_PO 19 +#define RK817_IRQ_CLASSD_MUTE_DONE 20 +#define RK817_IRQ_CLASSD_OCP 21 +#define RK817_IRQ_BAT_OVP 22 +#define RK817_IRQ_CHRG_BAT_HI 23 + +#define RK818_DCDC1 0 +#define RK818_LDO1 4 +#define RK818_NUM_REGULATORS 17 + +enum rk818_reg +{ + RK818_ID_DCDC1, + RK818_ID_DCDC2, + RK818_ID_DCDC3, + RK818_ID_DCDC4, + RK818_ID_BOOST, + RK818_ID_LDO1, + RK818_ID_LDO2, + RK818_ID_LDO3, + RK818_ID_LDO4, + RK818_ID_LDO5, + RK818_ID_LDO6, + RK818_ID_LDO7, + RK818_ID_LDO8, + RK818_ID_LDO9, + RK818_ID_SWITCH, + RK818_ID_HDMI_SWITCH, + RK818_ID_OTG_SWITCH, +}; + +#define RK818_DCDC_EN_REG 0x23 +#define RK818_LDO_EN_REG 0x24 +#define RK818_SLEEP_SET_OFF_REG1 0x25 +#define RK818_SLEEP_SET_OFF_REG2 0x26 +#define RK818_DCDC_UV_STS_REG 0x27 +#define RK818_DCDC_UV_ACT_REG 0x28 +#define RK818_LDO_UV_STS_REG 0x29 +#define RK818_LDO_UV_ACT_REG 0x2a +#define RK818_DCDC_PG_REG 0x2b +#define RK818_LDO_PG_REG 0x2c +#define RK818_VOUT_MON_TDB_REG 0x2d +#define RK818_BUCK1_CONFIG_REG 0x2e +#define RK818_BUCK1_ON_VSEL_REG 0x2f +#define RK818_BUCK1_SLP_VSEL_REG 0x30 +#define RK818_BUCK2_CONFIG_REG 0x32 +#define RK818_BUCK2_ON_VSEL_REG 0x33 +#define RK818_BUCK2_SLP_VSEL_REG 0x34 +#define RK818_BUCK3_CONFIG_REG 0x36 +#define RK818_BUCK4_CONFIG_REG 0x37 +#define RK818_BUCK4_ON_VSEL_REG 0x38 +#define RK818_BUCK4_SLP_VSEL_REG 0x39 +#define RK818_BOOST_CONFIG_REG 0x3a +#define RK818_LDO1_ON_VSEL_REG 0x3b +#define RK818_LDO1_SLP_VSEL_REG 0x3c +#define RK818_LDO2_ON_VSEL_REG 0x3d +#define RK818_LDO2_SLP_VSEL_REG 0x3e +#define RK818_LDO3_ON_VSEL_REG 0x3f +#define RK818_LDO3_SLP_VSEL_REG 0x40 +#define RK818_LDO4_ON_VSEL_REG 0x41 +#define RK818_LDO4_SLP_VSEL_REG 0x42 +#define RK818_LDO5_ON_VSEL_REG 0x43 +#define RK818_LDO5_SLP_VSEL_REG 0x44 +#define RK818_LDO6_ON_VSEL_REG 0x45 +#define RK818_LDO6_SLP_VSEL_REG 0x46 +#define RK818_LDO7_ON_VSEL_REG 0x47 +#define RK818_LDO7_SLP_VSEL_REG 0x48 +#define RK818_LDO8_ON_VSEL_REG 0x49 +#define RK818_LDO8_SLP_VSEL_REG 0x4a +#define RK818_BOOST_LDO9_ON_VSEL_REG 0x54 +#define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55 +#define RK818_DEVCTRL_REG 0x4b +#define RK818_INT_STS_REG1 0X4c +#define RK818_INT_STS_MSK_REG1 0x4d +#define RK818_INT_STS_REG2 0x4e +#define RK818_INT_STS_MSK_REG2 0x4f +#define RK818_IO_POL_REG 0x50 +#define RK818_H5V_EN_REG 0x52 +#define RK818_SLEEP_SET_OFF_REG3 0x53 +#define RK818_BOOST_LDO9_ON_VSEL_REG 0x54 +#define RK818_BOOST_LDO9_SLP_VSEL_REG 0x55 +#define RK818_BOOST_CTRL_REG 0x56 +#define RK818_DCDC_ILMAX 0x90 +#define RK818_USB_CTRL_REG 0xa1 + +#define RK818_H5V_EN RT_BIT(0) +#define RK818_REF_RDY_CTRL RT_BIT(1) +#define RK818_USB_ILIM_SEL_MASK 0xf +#define RK818_USB_ILMIN_2000MA 0x7 +#define RK818_USB_CHG_SD_VSEL_MASK 0x70 + +/* RK818 IRQ Definitions */ +#define RK818_IRQ_VOUT_LO 0 +#define RK818_IRQ_VB_LO 1 +#define RK818_IRQ_PWRON 2 +#define RK818_IRQ_PWRON_LP 3 +#define RK818_IRQ_HOTDIE 4 +#define RK818_IRQ_RTC_ALARM 5 +#define RK818_IRQ_RTC_PERIOD 6 +#define RK818_IRQ_USB_OV 7 +#define RK818_IRQ_PLUG_IN 8 +#define RK818_IRQ_PLUG_OUT 9 +#define RK818_IRQ_CHG_OK 10 +#define RK818_IRQ_CHG_TE 11 +#define RK818_IRQ_CHG_TS1 12 +#define RK818_IRQ_TS2 13 +#define RK818_IRQ_CHG_CVTLIM 14 +#define RK818_IRQ_DISCHG_ILIM 15 + +#define RK818_IRQ_VOUT_LO_MSK RT_BIT(0) +#define RK818_IRQ_VB_LO_MSK RT_BIT(1) +#define RK818_IRQ_PWRON_MSK RT_BIT(2) +#define RK818_IRQ_PWRON_LP_MSK RT_BIT(3) +#define RK818_IRQ_HOTDIE_MSK RT_BIT(4) +#define RK818_IRQ_RTC_ALARM_MSK RT_BIT(5) +#define RK818_IRQ_RTC_PERIOD_MSK RT_BIT(6) +#define RK818_IRQ_USB_OV_MSK RT_BIT(7) +#define RK818_IRQ_PLUG_IN_MSK RT_BIT(0) +#define RK818_IRQ_PLUG_OUT_MSK RT_BIT(1) +#define RK818_IRQ_CHG_OK_MSK RT_BIT(2) +#define RK818_IRQ_CHG_TE_MSK RT_BIT(3) +#define RK818_IRQ_CHG_TS1_MSK RT_BIT(4) +#define RK818_IRQ_TS2_MSK RT_BIT(5) +#define RK818_IRQ_CHG_CVTLIM_MSK RT_BIT(6) +#define RK818_IRQ_DISCHG_ILIM_MSK RT_BIT(7) +#define RK818_NUM_IRQ 16 + +#define BUCK_ILMIN_MASK (7 << 0) +#define BOOST_ILMIN_MASK (7 << 0) +#define BUCK1_RATE_MASK (3 << 3) +#define BUCK2_RATE_MASK (3 << 3) +#define MASK_ALL 0xff + +#define BUCK_UV_ACT_MASK 0x0f +#define BUCK_UV_ACT_DISABLE 0 + +#define SWITCH2_EN RT_BIT(6) +#define SWITCH1_EN RT_BIT(5) +#define DEV_OFF_RST RT_BIT(3) +#define DEV_RST RT_BIT(2) +#define DEV_OFF RT_BIT(0) +#define RTC_STOP RT_BIT(0) + +#define VB_LO_ACT RT_BIT(4) +#define VB_LO_SEL_3500MV (7 << 0) + +#define VOUT_LO_INT RT_BIT(0) +#define CLK32KOUT2_EN RT_BIT(0) + +#define TEMP115C 0x0c +#define TEMP_HOTDIE_MSK 0x0c +#define SLP_SD_MSK (0x3 << 2) +#define SHUTDOWN_FUN (0x2 << 2) +#define SLEEP_FUN (0x1 << 2) +#define RK8XX_ID_MSK 0xfff0 +#define PWM_MODE_MSK RT_BIT(7) +#define FPWM_MODE RT_BIT(7) +#define AUTO_PWM_MODE 0 + +#define BUCK_ILMIN_50MA 0 +#define BUCK_ILMIN_100MA 1 +#define BUCK_ILMIN_150MA 2 +#define BUCK_ILMIN_200MA 3 +#define BUCK_ILMIN_250MA 4 +#define BUCK_ILMIN_300MA 5 +#define BUCK_ILMIN_350MA 6 +#define BUCK_ILMIN_400MA 7 + +#define BOOST_ILMIN_75MA 0 +#define BOOST_ILMIN_100MA 1 +#define BOOST_ILMIN_125MA 2 +#define BOOST_ILMIN_150MA 3 +#define BOOST_ILMIN_175MA 4 +#define BOOST_ILMIN_200MA 5 +#define BOOST_ILMIN_225MA 6 +#define BOOST_ILMIN_250MA 7 + +enum +{ + RK805_ID = 0x8050, + RK806_ID = 0x8060, + RK808_ID = 0x0000, + RK809_ID = 0x8090, + RK817_ID = 0x8170, + RK818_ID = 0x8180, +}; + +struct rk8xx +{ + int variant; + + int irq; + struct rt_device *dev; + + rt_uint32_t (*read)(struct rk8xx *, rt_uint16_t reg); + rt_err_t (*write)(struct rk8xx *, rt_uint16_t reg, rt_uint8_t data); + rt_err_t (*update_bits)(struct rk8xx *, rt_uint16_t reg, rt_uint8_t mask, + rt_uint8_t data); +}; + +#define rk8xx_to_i2c_client(rk8xx) rt_container_of((rk8xx)->dev, struct rt_i2c_client, parent) +#define rk8xx_to_spi_device(rk8xx) rt_container_of((rk8xx)->dev, struct rt_spi_device, parent) + +rt_inline rt_uint32_t rk8xx_read(struct rk8xx *rk8xx, rt_uint16_t reg) +{ + return rk8xx->read(rk8xx, reg); +} + +rt_inline rt_err_t rk8xx_write(struct rk8xx *rk8xx, rt_uint16_t reg, rt_uint8_t data) +{ + return rk8xx->write(rk8xx, reg, data); +} + +rt_inline rt_err_t rk8xx_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg, + rt_uint8_t mask, rt_uint8_t data) +{ + return rk8xx->update_bits(rk8xx, reg, mask, data); +} + +rt_err_t rk8xx_probe(struct rk8xx *rk8xx); +rt_err_t rk8xx_shutdown(struct rk8xx *rk8xx); + +#endif /* __RK8XX_H__ */ diff --git a/bsp/rockchip/dm/include/rockchip.h b/bsp/rockchip/dm/include/rockchip.h new file mode 100755 index 00000000000..4564a6b3637 --- /dev/null +++ b/bsp/rockchip/dm/include/rockchip.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#ifndef __ROCKCHIP_H__ +#define __ROCKCHIP_H__ + +#include +#include +#include + +#include + +#define rk_clrsetreg(addr, clr, set) HWREG32(addr) = (((clr) | (set)) << 16 | (set)) +#define rk_clrreg(addr, clr) HWREG32(addr) = ((clr) << 16) +#define rk_setreg(addr, set) HWREG32(addr) = ((set) << 16 | (set)) + +#define HIWORD_UPDATE(val, mask, shift) ((val) << (shift) | (mask) << ((shift) + 16)) + +#define readx_poll_timeout(OP, ADDR, VAL, COND, DELAY_US, TIMEOUT_US) \ +({ \ + rt_uint64_t timeout_us = (TIMEOUT_US); \ + rt_int64_t left_ns = timeout_us * 1000L; \ + rt_ubase_t delay_us = (DELAY_US); \ + rt_uint64_t delay_ns = delay_us * 1000L; \ + for (;;) \ + { \ + (VAL) = OP(ADDR); \ + if (COND) \ + { \ + break; \ + } \ + if (timeout_us && left_ns < 0) \ + { \ + (VAL) = OP(ADDR); \ + break; \ + } \ + if (delay_us) \ + { \ + rt_hw_us_delay(delay_us); \ + if (timeout_us) \ + { \ + left_ns -= delay_ns; \ + } \ + } \ + rt_hw_cpu_relax(); \ + if (timeout_us) \ + { \ + --left_ns; \ + } \ + } \ + (COND) ? RT_EOK : -RT_ETIMEOUT; \ +}) + +#define readl_poll_timeout(ADDR, VAL, COND, DELAY_US, TIMEOUT_US) \ + readx_poll_timeout(HWREG32, ADDR, VAL, COND, DELAY_US, TIMEOUT_US) + +#define is_aligned(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) + +rt_inline int fls(int x) +{ + return x ? sizeof(x) * 8 - __builtin_clz(x) : 0; +} + +rt_inline int fls_long(unsigned long x) +{ + return x ? sizeof(x) * 8 - __builtin_clzl(x) : 0; +} + +rt_inline int __roundup_pow_of_two(rt_uint32_t x) +{ + return 1UL << fls(x - 1); +} + +rt_inline int __rounddown_pow_of_two(rt_uint32_t x) +{ + return (1UL << fls(x - 1)) / 2; +} + +#endif /* __ROCKCHIP_H__ */ \ No newline at end of file diff --git a/bsp/rockchip/dm/input/SConscript b/bsp/rockchip/dm/input/SConscript new file mode 100755 index 00000000000..3d15055d62d --- /dev/null +++ b/bsp/rockchip/dm/input/SConscript @@ -0,0 +1,13 @@ +import os +from building import * + +cwd = GetCurrentDir() +objs = [] +list = os.listdir(cwd) + +for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + objs = objs + SConscript(os.path.join(d, 'SConscript')) + +Return('objs') diff --git a/bsp/rockchip/dm/input/misc/Kconfig b/bsp/rockchip/dm/input/misc/Kconfig new file mode 100755 index 00000000000..28d9cb6570f --- /dev/null +++ b/bsp/rockchip/dm/input/misc/Kconfig @@ -0,0 +1,5 @@ +config RT_INPUT_MISC_PWRKEY_RK8XX + bool "Rockchip RK805/RK806/RK817 PMIC power key support" + depends on RT_INPUT_MISC + depends on RT_MFD_RK8XX + default n diff --git a/bsp/rockchip/dm/input/misc/SConscript b/bsp/rockchip/dm/input/misc/SConscript new file mode 100755 index 00000000000..8dbee537a92 --- /dev/null +++ b/bsp/rockchip/dm/input/misc/SConscript @@ -0,0 +1,13 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../../include'] + +if GetDepend(['RT_INPUT_MISC_PWRKEY_RK8XX']): + src += ['pwrkey-rk8xx.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c b/bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c new file mode 100755 index 00000000000..c2cd7b9dc32 --- /dev/null +++ b/bsp/rockchip/dm/input/misc/pwrkey-rk8xx.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +struct rk8xx_pwrkey +{ + struct rt_input_device parent; + + int fall_irq, rise_irq; +}; + +static void rk8xx_pwrkey_fall_isr(int irqno, void *param) +{ + struct rk8xx_pwrkey *pwr = param; + + rt_interrupt_enter(); + + rt_input_report_key(&pwr->parent, KEY_POWER, 1); + rt_input_sync(&pwr->parent); + + rt_interrupt_leave(); +} + +static void rk8xx_pwrkey_rise_isr(int irqno, void *param) +{ + struct rk8xx_pwrkey *pwr = param; + + rt_interrupt_enter(); + + rt_input_report_key(&pwr->parent, KEY_POWER, 0); + rt_input_sync(&pwr->parent); + + rt_interrupt_leave(); +} + +static rt_err_t rk8xx_pwrkey_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_device *dev = &pdev->parent; + struct rk8xx_pwrkey *pwr = rt_calloc(1, sizeof(*pwr)); + + if (!pwr) + { + return -RT_ENOMEM; + } + + if ((pwr->fall_irq = rt_dm_dev_get_irq(dev, 0)) < 0) + { + err = pwr->fall_irq; + goto _fail; + } + + if ((pwr->rise_irq = rt_dm_dev_get_irq(dev, 1)) < 0) + { + err = pwr->rise_irq; + goto _fail; + } + + rt_input_set_capability(&pwr->parent, EV_KEY, KEY_POWER); + + if ((err = rt_input_device_register(&pwr->parent))) + { + goto _fail; + } + + dev->user_data = pwr; + + rt_hw_interrupt_install(pwr->fall_irq, rk8xx_pwrkey_fall_isr, pwr, "pwrkey-rk8xx-fall"); + rt_hw_interrupt_umask(pwr->fall_irq); + + rt_hw_interrupt_install(pwr->rise_irq, rk8xx_pwrkey_rise_isr, pwr, "pwrkey-rk8xx-rise"); + rt_hw_interrupt_umask(pwr->rise_irq); + + return RT_EOK; + +_fail: + rt_free(pwr); + + return err; +} + +static rt_err_t rk8xx_pwrkey_remove(struct rt_platform_device *pdev) +{ + struct rk8xx_pwrkey *pwr = pdev->parent.user_data; + + rt_hw_interrupt_mask(pwr->fall_irq); + rt_pic_detach_irq(pwr->fall_irq, pwr); + + rt_hw_interrupt_mask(pwr->rise_irq); + rt_pic_detach_irq(pwr->rise_irq, pwr); + + rt_input_device_unregister(&pwr->parent); + + rt_free(pwr); + + return RT_EOK; +} + +static struct rt_platform_driver rk8xx_pwrkey_driver = +{ + .name = "rk8xx-pwrkey", + .probe = rk8xx_pwrkey_probe, + .remove = rk8xx_pwrkey_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rk8xx_pwrkey_driver); diff --git a/bsp/rockchip/dm/mailbox/Kconfig b/bsp/rockchip/dm/mailbox/Kconfig new file mode 100755 index 00000000000..3d20c60da6d --- /dev/null +++ b/bsp/rockchip/dm/mailbox/Kconfig @@ -0,0 +1,3 @@ +config RT_MBOX_ROCKCHIP + bool "Rockchip Soc Integrated Mailbox Support" + default n diff --git a/bsp/rockchip/dm/mailbox/SConscript b/bsp/rockchip/dm/mailbox/SConscript new file mode 100755 index 00000000000..4c892cc5f10 --- /dev/null +++ b/bsp/rockchip/dm/mailbox/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_MBOX_ROCKCHIP']): + src += ['mailbox-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/mailbox/mailbox-rockchip.c b/bsp/rockchip/dm/mailbox/mailbox-rockchip.c new file mode 100755 index 00000000000..bf58a245ef0 --- /dev/null +++ b/bsp/rockchip/dm/mailbox/mailbox-rockchip.c @@ -0,0 +1,575 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "mailbox.rockchip" +#define DBG_LVL DBG_INFO +#include + +#define MAILBOX_A2B_INTEN 0x00 +#define MAILBOX_A2B_STATUS 0x04 +#define MAILBOX_A2B_CMD(x) (0x08 + (x) * 8) +#define MAILBOX_A2B_DAT(x) (0x0c + (x) * 8) + +#define MAILBOX_B2A_INTEN 0x28 +#define MAILBOX_B2A_STATUS 0x2C +#define MAILBOX_B2A_CMD(x) (0x30 + (x) * 8) +#define MAILBOX_B2A_DAT(x) (0x34 + (x) * 8) + +#define MAILBOX_V2_A2B_INTEN MAILBOX_A2B_INTEN +#define MAILBOX_V2_A2B_STATUS MAILBOX_A2B_STATUS +#define MAILBOX_V2_A2B_CMD 0x08 +#define MAILBOX_V2_A2B_DAT 0x0c + +#define MAILBOX_V2_B2A_INTEN 0x10 +#define MAILBOX_V2_B2A_STATUS 0x14 +#define MAILBOX_V2_B2A_CMD 0x18 +#define MAILBOX_V2_B2A_DAT 0x1c + +#define MAILBOX_V2_TRIGGER_SHIFT 8 +#define MAILBOX_V2_TRIGGER_MASK RT_BIT(8) + +#define MAILBOX_V2_INTEN_TX_DONE RT_BIT(0) +#define MAILBOX_V2_INTEN_RX_DONE RT_BIT(1) +#define MAILBOX_V2_INTEN_RX_DONE_SHIFT 1 + +#define MAILBOX_V2_STATUS_TX_DONE RT_BIT(0) +#define MAILBOX_V2_STATUS_RX_DONE RT_BIT(1) +#define MAILBOX_V2_STATUS_MASK RT_GENMASK(1, 0) + +#define MAILBOX_POLLING_MS 5 /* default polling interval 5ms */ +#define BIT_WRITEABLE_SHIFT 16 + +struct rockchip_mbox; + +struct rockchip_mbox_reg +{ + rt_uint32_t tx_int; + rt_uint32_t tx_sts; + rt_uint32_t tx_cmd; + rt_uint32_t tx_dat; + rt_uint32_t rx_int; + rt_uint32_t rx_sts; + rt_uint32_t rx_cmd; + rt_uint32_t rx_dat; +}; + +struct rockchip_mbox_msg +{ + rt_uint32_t cmd; + rt_uint32_t data; +}; + +struct rockchip_mbox_soc_data +{ + int num_chans; + struct rockchip_mbox_reg reg_a2b; + struct rockchip_mbox_reg reg_b2a; + const struct rt_mbox_controller_ops *ops; + void (*isr)(int irqno, void *param); + void (*thread_isr)(void *param); +}; + +struct rockchip_mbox_chan +{ + int idx; + int irq; + struct rockchip_mbox_msg *msg; + struct rockchip_mbox *rk_mbox; +}; + +struct rockchip_mbox +{ + struct rt_mbox_controller parent; + + void *regs; + struct rt_clk *pclk; + struct rt_thread *irq_thread; + const struct rockchip_mbox_reg *reg; + + rt_uint32_t buf_size; + rt_bool_t txdone_irq; + rt_bool_t trigger_method; + struct rockchip_mbox_chan chans[]; +}; + +#define raw_to_rockchip_mbox(raw) rt_container_of(raw, struct rockchip_mbox, parent) + +rt_inline rt_uint32_t rockchip_mbox_readl(struct rockchip_mbox *rk_mbox, int offset) +{ + return HWREG32(rk_mbox->regs + offset); +} + +rt_inline void rockchip_mbox_writel(struct rockchip_mbox *rk_mbox, int offset, + rt_uint32_t value) +{ + HWREG32(rk_mbox->regs + offset) = value; +} + +static rt_err_t rockchip_mbox_request(struct rt_mbox_chan *chan) +{ + int idx; + rt_uint32_t value; + struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl); + + idx = chan - rk_mbox->parent.chans; + + /* Enable the corresponding B2A interrupts */ + value = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_INTEN); + value |= RT_BIT(idx); + rockchip_mbox_writel(rk_mbox, MAILBOX_B2A_INTEN, value); + + return RT_EOK; +} + +static void rockchip_mbox_release(struct rt_mbox_chan *chan) +{ + int idx; + rt_uint32_t value; + struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl); + + idx = chan - rk_mbox->parent.chans; + + /* Disable the corresponding B2A interrupts */ + value = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_INTEN); + value &= ~RT_BIT(idx); + rockchip_mbox_writel(rk_mbox, MAILBOX_B2A_INTEN, value); + + rk_mbox->chans[idx].msg = RT_NULL; +} + +static rt_err_t rockchip_mbox_send(struct rt_mbox_chan *chan, const void *data) +{ + int idx; + struct rockchip_mbox_msg *msg = (void *)data; + struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl); + + idx = chan - rk_mbox->parent.chans; + + if (rockchip_mbox_readl(rk_mbox, MAILBOX_A2B_STATUS) & RT_BIT(idx)) + { + LOG_E("The mailbox channel(%d) is busy", idx); + + return -RT_EBUSY; + } + + rk_mbox->chans[idx].msg = msg; + + rockchip_mbox_writel(rk_mbox, MAILBOX_A2B_CMD(idx), msg->cmd); + rockchip_mbox_writel(rk_mbox, MAILBOX_A2B_DAT(idx), msg->data); + + return RT_EOK; +} + +static const struct rt_mbox_controller_ops rockchip_mbox_ops = +{ + .request = rockchip_mbox_request, + .release = rockchip_mbox_release, + .send = rockchip_mbox_send, +}; + +static void rockchip_mbox_thread_isr(void *param) +{ + struct rockchip_mbox_msg *msg; + struct rockchip_mbox *rk_mbox = param; + + while (RT_TRUE) + { + rt_thread_suspend(rk_mbox->irq_thread); + rt_schedule(); + + for (int idx = 0; idx < rk_mbox->parent.num_chans; ++idx) + { + msg = rk_mbox->chans[idx].msg; + + if (!msg) + { + LOG_E("Chan[%d]: B2A message is NULL", idx); + + break; + } + + rt_mbox_recv(&rk_mbox->parent.chans[idx], msg); + rk_mbox->chans[idx].msg = RT_NULL; + } + } +} + +static void rockchip_mbox_isr(int irqno, void *param) +{ + rt_uint32_t status; + struct rockchip_mbox_msg *msg; + struct rockchip_mbox *rk_mbox = param; + + status = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_STATUS); + + for (int idx = 0; idx < rk_mbox->parent.num_chans; ++idx) + { + if ((status & RT_BIT(idx)) && (irqno == rk_mbox->chans[idx].irq)) + { + msg = rk_mbox->chans[idx].msg; + msg->cmd = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_CMD(idx)); + msg->data = rockchip_mbox_readl(rk_mbox, MAILBOX_B2A_DAT(idx)); + + /* Clear mbox interrupt */ + rockchip_mbox_writel(rk_mbox, MAILBOX_B2A_STATUS, RT_BIT(idx)); + + rt_thread_resume(rk_mbox->irq_thread); + + break; + } + } +} + +static rt_err_t rockchip_mbox_v2_request(struct rt_mbox_chan *chan) +{ + struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl); + + /* Set the TX interrupt trigger method */ + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_int, + (1U << (BIT_WRITEABLE_SHIFT + MAILBOX_V2_TRIGGER_SHIFT) | + rk_mbox->trigger_method << MAILBOX_V2_TRIGGER_SHIFT)); + + /* Enable the tx_done interrupt */ + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int, + (1U << BIT_WRITEABLE_SHIFT | MAILBOX_V2_INTEN_TX_DONE)); + + /* Enable the rx_done interrupt */ + if (rk_mbox->txdone_irq) + { + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int, + (1U << (BIT_WRITEABLE_SHIFT + MAILBOX_V2_INTEN_RX_DONE_SHIFT) | + MAILBOX_V2_INTEN_RX_DONE)); + } + + return RT_EOK; +} + +static void rockchip_mbox_v2_release(struct rt_mbox_chan *chan) +{ + struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl); + + /* Disable the tx_done interrupt */ + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int, 1U << BIT_WRITEABLE_SHIFT); + + /* Disable the rx_done interrupt */ + if (rk_mbox->txdone_irq) + { + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_int, + 1U << (BIT_WRITEABLE_SHIFT + MAILBOX_V2_INTEN_RX_DONE_SHIFT)); + } +} + +static rt_err_t rockchip_mbox_v2_send(struct rt_mbox_chan *chan, const void *data) +{ + struct rockchip_mbox_msg *msg = (void *)data; + struct rockchip_mbox *rk_mbox = raw_to_rockchip_mbox(chan->ctrl); + + if (rockchip_mbox_readl(rk_mbox, rk_mbox->reg->tx_sts) & MAILBOX_V2_STATUS_TX_DONE) + { + LOG_E("The mailbox channel(%d) is busy", 0); + + return -RT_EBUSY; + } + + rk_mbox->chans[0].msg = msg; + + if (rk_mbox->trigger_method) + { + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_cmd, msg->cmd); + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_dat, msg->data); + } + else + { + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->tx_cmd, msg->cmd); + } + + return RT_EOK; +} + +static const struct rt_mbox_controller_ops rockchip_mbox_v2_ops = +{ + .request = rockchip_mbox_v2_request, + .release = rockchip_mbox_v2_release, + .send = rockchip_mbox_v2_send, +}; + +static void rockchip_mbox_v2_thread_isr(void *param) +{ + struct rockchip_mbox_msg *msg; + struct rockchip_mbox *rk_mbox = param; + + while (RT_TRUE) + { + rt_thread_suspend(rk_mbox->irq_thread); + rt_schedule(); + + msg = rk_mbox->chans[0].msg; + + if (!msg) + { + LOG_E("Chan[%d]: B2A message is NULL", 0); + + continue; + } + + rt_mbox_recv(&rk_mbox->parent.chans[0], msg); + rk_mbox->chans[0].msg = RT_NULL; + } +} + +static void rockchip_mbox_v2_isr(int irqno, void *param) +{ + rt_uint32_t status; + struct rockchip_mbox_msg *msg; + struct rockchip_mbox *rk_mbox = param; + + status = rockchip_mbox_readl(rk_mbox, rk_mbox->reg->rx_sts); + + if (!(status & MAILBOX_V2_STATUS_MASK)) + { + return; + } + + if (status & MAILBOX_V2_STATUS_TX_DONE) + { + msg = rk_mbox->chans[0].msg; + + /* Get cmd/data from the channel */ + msg->cmd = rockchip_mbox_readl(rk_mbox, rk_mbox->reg->rx_cmd); + msg->data = rockchip_mbox_readl(rk_mbox, rk_mbox->reg->rx_dat); + + /* Clear the tx_done interrupt */ + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_sts, MAILBOX_V2_STATUS_TX_DONE); + + rt_thread_resume(rk_mbox->irq_thread); + } + + if (status & MAILBOX_V2_STATUS_RX_DONE) + { + if (rk_mbox->txdone_irq) + { + rt_mbox_send_done(&rk_mbox->parent.chans[0], 0); + } + + /* Clear the rx_done interrupt */ + rockchip_mbox_writel(rk_mbox, rk_mbox->reg->rx_sts, MAILBOX_V2_STATUS_RX_DONE); + } +} + +static void rockchip_mbox_free_resource(struct rockchip_mbox *rk_mbox) +{ + if (rk_mbox->regs) + { + rt_iounmap(rk_mbox->regs); + } + + if (!rt_is_err_or_null(rk_mbox->pclk)) + { + rt_clk_disable_unprepare(rk_mbox->pclk); + rt_clk_put(rk_mbox->pclk); + } + + if (rk_mbox->irq_thread) + { + rt_thread_delete(rk_mbox->irq_thread); + } + + rt_free(rk_mbox); +} + +static rt_err_t rockchip_mbox_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + char chan_name[RT_NAME_MAX]; + rt_uint64_t io_addr, io_size; + struct rockchip_mbox *rk_mbox; + struct rockchip_mbox_chan *chan; + struct rt_device *dev = &pdev->parent; + const struct rockchip_mbox_soc_data *soc_data = pdev->id->data; + + rk_mbox = rt_calloc(1, sizeof(*rk_mbox) + + soc_data->num_chans * sizeof(struct rockchip_mbox_chan)); + + if (!rk_mbox) + { + return -RT_ENOMEM; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,tx-direction-b2a")) + { + rk_mbox->reg = &soc_data->reg_b2a; + } + else + { + rk_mbox->reg = &soc_data->reg_a2b; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,txdone-ack")) + { + rk_mbox->txdone_irq = RT_FALSE; + } + else if (rt_dm_dev_prop_read_bool(dev, "rockchip,txdone-irq")) + { + rk_mbox->txdone_irq = RT_TRUE; + } + + rk_mbox->trigger_method = !rt_dm_dev_prop_read_bool(dev, "rockchip,enable-cmd-trigger"); + + if ((err = rt_dm_dev_get_address(dev, 0, &io_addr, &io_size))) + { + goto _fail; + } + + rk_mbox->regs = rt_ioremap((void *)io_addr, (size_t)io_size); + + if (!rk_mbox->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_mbox->pclk = rt_clk_get_by_name(dev, "pclk_mailbox"); + + if (rt_is_err(rk_mbox->pclk)) + { + err = rt_ptr_err(rk_mbox->pclk); + + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_mbox->pclk))) + { + goto _fail; + } + + rk_mbox->irq_thread = rt_thread_create("rk_mbox", soc_data->thread_isr, + rk_mbox, DM_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 2, 10); + + if (!rk_mbox->irq_thread) + { + LOG_E("Create Mailbox IRQ thread fail"); + goto _fail; + } + + rt_thread_startup(rk_mbox->irq_thread); + + chan = &rk_mbox->chans[0]; + + for (int i = 0; i < soc_data->num_chans; ++i, ++chan) + { + int irq = rt_dm_dev_get_irq(dev, i); + + if (irq < 0) + { + err = irq; + + goto _fail; + } + + rt_snprintf(chan_name, sizeof(chan_name), "rk_mbox-%d", i); + + rt_hw_interrupt_install(irq, soc_data->isr, rk_mbox, chan_name); + rt_hw_interrupt_umask(irq); + + chan->idx = i; + chan->irq = irq; + chan->rk_mbox = rk_mbox; + } + + rk_mbox->buf_size = io_size / (soc_data->num_chans * 2); + + dev->user_data = rk_mbox; + + rk_mbox->parent.dev = dev; + rk_mbox->parent.num_chans = soc_data->num_chans; + rk_mbox->parent.ops = soc_data->ops; + + if ((err = rt_mbox_controller_register(&rk_mbox->parent))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rockchip_mbox_free_resource(rk_mbox); + + return err; +} + +static rt_err_t rockchip_mbox_remove(struct rt_platform_device *pdev) +{ + struct rockchip_mbox_chan *chan; + struct rockchip_mbox *rk_mbox = pdev->parent.user_data; + + chan = &rk_mbox->chans[0]; + + for (int i = 0; i < rk_mbox->parent.num_chans; ++i, ++chan) + { + rt_hw_interrupt_mask(chan->irq); + rt_pic_detach_irq(chan->irq, rk_mbox); + } + + rt_mbox_controller_unregister(&rk_mbox->parent); + + rockchip_mbox_free_resource(rk_mbox); + + return RT_EOK; +} + +static const struct rockchip_mbox_soc_data rk3368_data = +{ + .num_chans = 4, + .ops = &rockchip_mbox_ops, + .isr = rockchip_mbox_isr, + .thread_isr = rockchip_mbox_thread_isr, +}; + +static const struct rockchip_mbox_soc_data rk3576_data = +{ + .num_chans = 1, + .reg_a2b = + { + MAILBOX_V2_A2B_INTEN, MAILBOX_V2_A2B_STATUS, + MAILBOX_V2_A2B_CMD, MAILBOX_V2_A2B_DAT, + MAILBOX_V2_B2A_INTEN, MAILBOX_V2_B2A_STATUS, + MAILBOX_V2_B2A_CMD, MAILBOX_V2_B2A_DAT + }, + .reg_b2a = + { + MAILBOX_V2_B2A_INTEN, MAILBOX_V2_B2A_STATUS, + MAILBOX_V2_B2A_CMD, MAILBOX_V2_B2A_DAT, + MAILBOX_V2_A2B_INTEN, MAILBOX_V2_A2B_STATUS, + MAILBOX_V2_A2B_CMD, MAILBOX_V2_A2B_DAT + }, + .ops = &rockchip_mbox_v2_ops, + .isr = rockchip_mbox_v2_isr, + .thread_isr = rockchip_mbox_v2_thread_isr, +}; + +static const struct rt_ofw_node_id rockchip_mbox_ofw_ids[] = +{ + { .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_data }, + { .compatible = "rockchip,rk3576-mailbox", .data = &rk3576_data }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_mbox_driver = +{ + .name = "mailbox-rockchip", + .ids = rockchip_mbox_ofw_ids, + + .probe = rockchip_mbox_probe, + .remove = rockchip_mbox_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_mbox_driver); diff --git a/bsp/rockchip/dm/mfd/Kconfig b/bsp/rockchip/dm/mfd/Kconfig new file mode 100755 index 00000000000..82acebe5156 --- /dev/null +++ b/bsp/rockchip/dm/mfd/Kconfig @@ -0,0 +1,19 @@ +config RT_MFD_RK8XX + bool + depends on RT_USING_PIC + +config RT_MFD_RK8XX_I2C + bool "Rockchip RK805/RK808/RK809/RK817/RK818 Power Management Chip" + depends on RT_USING_OFW + depends on RT_USING_I2C + select RT_MFD_RK8XX + select RT_MFD_SYSCON + default n + +config RT_MFD_RK8XX_SPI + bool "Rockchip RK806 Power Management Chip" + depends on RT_USING_OFW + depends on RT_USING_SPI + select RT_MFD_RK8XX + select RT_MFD_SYSCON + default n diff --git a/bsp/rockchip/dm/mfd/SConscript b/bsp/rockchip/dm/mfd/SConscript new file mode 100755 index 00000000000..ee3e249376f --- /dev/null +++ b/bsp/rockchip/dm/mfd/SConscript @@ -0,0 +1,18 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_MFD_RK8XX']): + src += ['rk8xx.c'] + + if GetDepend(['RT_MFD_RK8XX_I2C']): + src += ['rk8xx-i2c.c'] + + if GetDepend(['RT_MFD_RK8XX_SPI']): + src += ['rk8xx-spi.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/mfd/rk8xx-i2c.c b/bsp/rockchip/dm/mfd/rk8xx-i2c.c new file mode 100755 index 00000000000..17a43d8ab9c --- /dev/null +++ b/bsp/rockchip/dm/mfd/rk8xx-i2c.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "mfd.rk8xx-i2c" +#define DBG_LVL DBG_INFO +#include + +#include "rk8xx.h" + +struct rk8xx_i2c_soc_data +{ + int variant; +}; + +static rt_uint32_t rk8xx_i2c_read(struct rk8xx *rk8xx, rt_uint16_t reg) +{ + rt_uint8_t data = 0; + rt_uint8_t send_buf[2]; + struct rt_i2c_msg msg[2]; + struct rt_i2c_client *client = rk8xx_to_i2c_client(rk8xx); + + send_buf[0] = (reg & 0xff); + + msg[0].addr = client->client_addr; + msg[0].flags = RT_I2C_WR; + msg[0].len = 1; + msg[0].buf = send_buf; + + msg[1].addr = client->client_addr; + msg[1].flags = RT_I2C_RD; + msg[1].len = 1; + msg[1].buf = &data; + + if (rt_i2c_transfer(client->bus, msg, 2) == 2) + { + return data; + } + else + { + return (rt_uint32_t)-RT_ERROR; + } +} + +static rt_err_t rk8xx_i2c_write(struct rk8xx *rk8xx, rt_uint16_t reg, + rt_uint8_t data) +{ + rt_uint8_t send_buf[2]; + struct rt_i2c_msg msg; + struct rt_i2c_client *client = rk8xx_to_i2c_client(rk8xx); + + send_buf[0] = reg & 0xff; + send_buf[1] = data; + + msg.addr = client->client_addr; + msg.flags = RT_I2C_WR; + msg.len = 2; + msg.buf = send_buf; + + if (rt_i2c_transfer(client->bus, &msg, 1) == 1) + { + return RT_EOK; + } + else + { + return -RT_ERROR; + } +} + +static rt_err_t rk8xx_i2c_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg, + rt_uint8_t mask, rt_uint8_t data) +{ + rt_uint32_t old, tmp; + + old = rk8xx_i2c_read(rk8xx, reg); + + if (old < 0) + { + return old; + } + + tmp = old & ~mask; + tmp |= (data & mask); + + return rk8xx_i2c_write(rk8xx, reg, tmp); +} + +static rt_err_t rk8xx_i2c_probe(struct rt_i2c_client *client) +{ + rt_err_t err; + const struct rk8xx_i2c_soc_data *soc_data; + struct rk8xx *rk8xx = rt_calloc(1, sizeof(*rk8xx)); + + if (!rk8xx) + { + return -RT_ENOMEM; + } + + rk8xx->irq = rt_dm_dev_get_irq(&client->parent, 0); + + if (rk8xx->irq < 0) + { + err = rk8xx->irq; + goto _fail; + } + + soc_data = client->ofw_id->data; + client->parent.user_data = rk8xx; + + rk8xx->variant = soc_data->variant; + rk8xx->dev = &client->parent; + rk8xx->read = rk8xx_i2c_read; + rk8xx->write = rk8xx_i2c_write; + rk8xx->update_bits = rk8xx_i2c_update_bits; + + if ((err = rk8xx_probe(rk8xx))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rt_free(rk8xx); + + return err; +} + +static rt_err_t rk8xx_i2c_shutdown(struct rt_i2c_client *client) +{ + struct rk8xx *rk8xx = client->parent.user_data; + + return rk8xx_shutdown(rk8xx); +} + +static const struct rk8xx_i2c_soc_data rk805_data = +{ + .variant = RK805_ID, +}; + +static const struct rk8xx_i2c_soc_data rk808_data = +{ + .variant = RK808_ID, +}; + +static const struct rk8xx_i2c_soc_data rk809_data = +{ + .variant = RK809_ID, +}; + +static const struct rk8xx_i2c_soc_data rk817_data = +{ + .variant = RK817_ID, +}; + +static const struct rk8xx_i2c_soc_data rk818_data = +{ + .variant = RK818_ID, +}; + +static const struct rt_ofw_node_id rk8xx_i2c_ofw_ids[] = +{ + { .compatible = "rockchip,rk805", .data = &rk805_data }, + { .compatible = "rockchip,rk808", .data = &rk808_data }, + { .compatible = "rockchip,rk809", .data = &rk809_data }, + { .compatible = "rockchip,rk817", .data = &rk817_data }, + { .compatible = "rockchip,rk818", .data = &rk818_data }, + { /* sentinel */ }, +}; + +static struct rt_i2c_driver rk8xx_i2c_driver = +{ + .ofw_ids = rk8xx_i2c_ofw_ids, + + .probe = rk8xx_i2c_probe, + .shutdown = rk8xx_i2c_shutdown, +}; +RT_I2C_DRIVER_EXPORT(rk8xx_i2c_driver); diff --git a/bsp/rockchip/dm/mfd/rk8xx-spi.c b/bsp/rockchip/dm/mfd/rk8xx-spi.c new file mode 100755 index 00000000000..85097a2fe8d --- /dev/null +++ b/bsp/rockchip/dm/mfd/rk8xx-spi.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "mfd.rk8xx-spi" +#define DBG_LVL DBG_INFO +#include + +#include "rk8xx.h" + +#define RK806_CMD_PACKAGE(CMD, LEN) \ + (RK806_CMD_##CMD | RK806_CMD_CRC_DIS | (LEN & RK806_CMD_LEN_MSK)) + +/* + * Format of SPI commands (3 data packages: CMD, REG_L, REG_H) + * CMD R/W[7]: R=0, W=1 + * CMD CRC_EN[6]: Enable=1, Disable=0 + * CMD Len[3:0]: + * case 1: CRC_EN=1 + * The length of data written or read is noted in Len[3:0]. + * The host or slave computer transmits CRC data at the position of len+1. + * case 2: CRC_EN=0 + * The data transmission takes no advantage of the length. + * The addresses of registers of slave computer self-increase within the interval of 0~255. + * + * REG_L[7:0]: The address of the target register is low-8 bit. + * REG_H[15:8]: The address of the target register is high-8 bit. + */ + +static rt_uint32_t rk8xx_spi_read(struct rk8xx *rk8xx, rt_uint16_t reg) +{ + rt_err_t err; + rt_uint8_t data = 0, package[3]; + struct rt_spi_device *spi_dev = rk8xx_to_spi_device(rk8xx); + + package[0] = RK806_CMD_PACKAGE(READ, sizeof(data)); + package[1] = reg & 0xff; + package[2] = (reg >> 8) & 0xff; + + err = rt_spi_send_then_recv(spi_dev, package, sizeof(package), + &data, sizeof(data)); + + return !err ? data : (rt_uint32_t)err; +} + +static rt_err_t rk8xx_spi_write(struct rk8xx *rk8xx, rt_uint16_t reg, + rt_uint8_t data) +{ + rt_ssize_t res; + rt_uint8_t package[4]; + struct rt_spi_device *spi_dev = rk8xx_to_spi_device(rk8xx); + + package[0] = RK806_CMD_PACKAGE(WRITE, sizeof(data)); + package[1] = reg & 0xff; + package[2] = (reg >> 8) & 0xff; + package[3] = data; + + res = rt_spi_transfer(spi_dev, package, RT_NULL, sizeof(package)); + + return res > 0 ? RT_EOK : (res == 0 ? -RT_EIO : res); +} + +static rt_err_t rk8xx_spi_update_bits(struct rk8xx *rk8xx, rt_uint16_t reg, + rt_uint8_t mask, rt_uint8_t data) +{ + rt_uint32_t old, tmp; + + old = rk8xx_spi_read(rk8xx, reg); + + if ((rt_err_t)old < 0) + { + return old; + } + + tmp = old & ~mask; + tmp |= (data & mask); + + return rk8xx_spi_write(rk8xx, reg, tmp); +} + +static rt_err_t rk8xx_spi_probe(struct rt_spi_device *spi_dev) +{ + rt_err_t err; + struct rk8xx *rk8xx = rt_calloc(1, sizeof(*rk8xx)); + + if (!rk8xx) + { + return -RT_ENOMEM; + } + + rk8xx->irq = rt_dm_dev_get_irq(&spi_dev->parent, 0); + + if (rk8xx->irq < 0) + { + err = rk8xx->irq; + goto _fail; + } + + rk8xx->variant = RK806_ID; + rk8xx->dev = &spi_dev->parent; + rk8xx->read = rk8xx_spi_read; + rk8xx->write = rk8xx_spi_write; + rk8xx->update_bits = rk8xx_spi_update_bits; + + if ((err = rk8xx_probe(rk8xx))) + { + goto _fail; + } + + rt_dm_dev_set_name(&spi_dev->parent, "pmic"); + + return RT_EOK; + +_fail: + rt_free(rk8xx); + + return err; +} + +static const struct rt_spi_device_id rk8xx_spi_ids[] = +{ + { .name = "rk806" }, + { /* sentinel */ }, +}; + +static const struct rt_ofw_node_id rk8xx_spi_ofw_ids[] = +{ + { .compatible = "rockchip,rk806" }, + { /* sentinel */ }, +}; + +static struct rt_spi_driver rk8xx_spi_driver = +{ + .ids = rk8xx_spi_ids, + .ofw_ids = rk8xx_spi_ofw_ids, + + .probe = rk8xx_spi_probe, +}; +RT_SPI_DRIVER_EXPORT(rk8xx_spi_driver); diff --git a/bsp/rockchip/dm/mfd/rk8xx.c b/bsp/rockchip/dm/mfd/rk8xx.c new file mode 100755 index 00000000000..40655776a3c --- /dev/null +++ b/bsp/rockchip/dm/mfd/rk8xx.c @@ -0,0 +1,1088 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "mfd.rk8xx" +#define DBG_LVL DBG_INFO +#include + +#include "rk8xx.h" + +struct rk8xx_reg_data +{ + int addr; + int mask; + int value; +}; + +struct rk8xx_endpoint +{ + const char *name; + const char *ofw_name; + const char *ofw_compatible; + + int irqs_nr; + const int *irqs_list; +}; + +struct rk8xx_irq_map +{ + rt_uint32_t reg_offset; + rt_uint32_t mask; +}; + +#define RK8XX_IRQ_REG(IRQ, OFF, MASK) \ + [IRQ] = { .reg_offset = (OFF), .mask = (MASK) } + +#define RK8XX_IRQ_REG_LINE(ID, REG_BITS) \ + [ID] = { .reg_offset = (ID) / (REG_BITS), .mask = RT_BIT((ID) % (REG_BITS)), } + +struct rk8xx_irqchip +{ + struct rt_pic parent; + + struct rk8xx *rk8xx; + +#define RK8XX_IRQCHIP_NUM_REGS_MAX 3 + int num_regs; + int reg_stride; + int mask_base; + int status_base; + int ack_base; + + int irqs_nr; + const struct rk8xx_irq_map *irqs_map; + + struct rt_thread *irq_thread; +}; + +#define raw_to_rk8xx_irqchip(raw) rt_container_of(raw, struct rk8xx_irqchip, parent) + +struct rk8xx_power +{ + struct rt_device parent; + + struct rk8xx *rk8xx; +}; + +#define raw_to_rk8xx_power(raw) rt_container_of(raw, struct rk8xx_power, parent) + +static void rk8xx_irq_mask(struct rt_pic_irq *pirq) +{ + rt_uint16_t base; + struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pirq->pic); + const struct rk8xx_irq_map *irq_map = &rk8xx_ic->irqs_map[pirq->hwirq]; + + base = rk8xx_ic->mask_base + (irq_map->reg_offset / rk8xx_ic->reg_stride); + + rk8xx_update_bits(rk8xx_ic->rk8xx, base, irq_map->mask, irq_map->mask); +} + +static void rk8xx_irq_unmask(struct rt_pic_irq *pirq) +{ + rt_uint16_t base; + struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pirq->pic); + const struct rk8xx_irq_map *irq_map = &rk8xx_ic->irqs_map[pirq->hwirq]; + + base = rk8xx_ic->mask_base + (irq_map->reg_offset / rk8xx_ic->reg_stride); + + rk8xx_update_bits(rk8xx_ic->rk8xx, base, irq_map->mask, 0); +} + +static int rk8xx_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode) +{ + int irq = -1; + struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq); + + if (pirq) + { + struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pic); + + irq = rt_pic_config_irq(pic, hwirq, hwirq); + pirq->mode = mode; + rt_pic_cascade(pirq, rk8xx_ic->rk8xx->irq); + } + + return irq; +} + +static rt_err_t rk8xx_irq_parse(struct rt_pic *pic, struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq) +{ + struct rk8xx_irqchip *rk8xx_ic = raw_to_rk8xx_irqchip(pic); + + if (args->args_count != 1) + { + return -RT_EINVAL; + } + + out_pirq->mode = rt_pic_irq_get_triger_mode(rk8xx_ic->rk8xx->irq); + out_pirq->hwirq = args->args[0]; + + return RT_EOK; +} + +const static struct rt_pic_ops rk8xx_irq_ops = +{ + .name = "RK8XX", + .irq_mask = rk8xx_irq_mask, + .irq_unmask = rk8xx_irq_unmask, + .irq_map = rk8xx_irq_map, + .irq_parse = rk8xx_irq_parse, +}; + +static void rk8xx_pmic_thread_isr(void *param) +{ + rt_uint32_t status[RK8XX_IRQCHIP_NUM_REGS_MAX]; + rt_uint16_t base, reg; + struct rk8xx *rk8xx; + struct rt_pic_irq *pirq; + struct rk8xx_irqchip *rk8xx_ic = param; + + rk8xx = rk8xx_ic->rk8xx; + + while (RT_TRUE) + { + rt_thread_suspend(rk8xx_ic->irq_thread); + rt_schedule(); + + base = rk8xx_ic->status_base; + rt_memset(status, 0, sizeof(status)); + + for (int i = 0; i < rk8xx_ic->num_regs; ++i) + { + reg = base + i * rk8xx_ic->reg_stride; + status[i] = rk8xx_read(rk8xx, reg); + + if ((rt_err_t)status[i] < 0) + { + LOG_E("Read IRQ status failed error = %s", rt_strerror(status[i])); + + goto _end; + } + } + + base = rk8xx_ic->ack_base; + + for (int i = 0; i < rk8xx_ic->num_regs; ++i) + { + rt_err_t err; + + reg = base + i * rk8xx_ic->reg_stride; + err = rk8xx_write(rk8xx, reg, status[i]); + + if (err) + { + LOG_E("ACK IRQ failed error = %s", rt_strerror(err)); + + goto _end; + } + } + + for (int i = 0; i < rk8xx_ic->irqs_nr; ++i) + { + base = rk8xx_ic->irqs_map[i].reg_offset / rk8xx_ic->reg_stride; + + if (status[base] & rk8xx_ic->irqs_map[i].mask) + { + pirq = rt_pic_find_irq(&rk8xx_ic->parent, i); + + if (pirq && pirq->pic) + { + rt_pic_handle_isr(pirq); + } + } + } + _end: + rt_hw_interrupt_umask(rk8xx->irq); + } +} + +static void rk8xx_pmic_isr(int irqno, void *param) +{ + struct rk8xx_irqchip *rk8xx_ic = param; + + rt_hw_interrupt_mask(rk8xx_ic->rk8xx->irq); + + rt_thread_resume(rk8xx_ic->irq_thread); +} + +static const struct rk8xx_irq_map rk805_irqs[] = +{ + RK8XX_IRQ_REG(RK805_IRQ_PWRON_RISE, 0, RK805_IRQ_PWRON_RISE_MSK), + RK8XX_IRQ_REG(RK805_IRQ_VB_LOW, 0, RK805_IRQ_VB_LOW_MSK), + RK8XX_IRQ_REG(RK805_IRQ_PWRON, 0, RK805_IRQ_PWRON_MSK), + RK8XX_IRQ_REG(RK805_IRQ_PWRON_LP, 0, RK805_IRQ_PWRON_LP_MSK), + RK8XX_IRQ_REG(RK805_IRQ_HOTDIE, 0, RK805_IRQ_HOTDIE_MSK), + RK8XX_IRQ_REG(RK805_IRQ_RTC_ALARM, 0, RK805_IRQ_RTC_ALARM_MSK), + RK8XX_IRQ_REG(RK805_IRQ_RTC_PERIOD, 0, RK805_IRQ_RTC_PERIOD_MSK), + RK8XX_IRQ_REG(RK805_IRQ_PWRON_FALL, 0, RK805_IRQ_PWRON_FALL_MSK), +}; + +static const struct rk8xx_irq_map rk806_irqs[] = +{ + /* INT_STS0 IRQs */ + RK8XX_IRQ_REG(RK806_IRQ_PWRON_FALL, 0, RK806_INT_STS_PWRON_FALL), + RK8XX_IRQ_REG(RK806_IRQ_PWRON_RISE, 0, RK806_INT_STS_PWRON_RISE), + RK8XX_IRQ_REG(RK806_IRQ_PWRON, 0, RK806_INT_STS_PWRON), + RK8XX_IRQ_REG(RK806_IRQ_PWRON_LP, 0, RK806_INT_STS_PWRON_LP), + RK8XX_IRQ_REG(RK806_IRQ_HOTDIE, 0, RK806_INT_STS_HOTDIE), + RK8XX_IRQ_REG(RK806_IRQ_VDC_RISE, 0, RK806_INT_STS_VDC_RISE), + RK8XX_IRQ_REG(RK806_IRQ_VDC_FALL, 0, RK806_INT_STS_VDC_FALL), + RK8XX_IRQ_REG(RK806_IRQ_VB_LO, 0, RK806_INT_STS_VB_LO), + /* INT_STS1 IRQs */ + RK8XX_IRQ_REG(RK806_IRQ_REV0, 1, RK806_INT_STS_REV0), + RK8XX_IRQ_REG(RK806_IRQ_REV1, 1, RK806_INT_STS_REV1), + RK8XX_IRQ_REG(RK806_IRQ_REV2, 1, RK806_INT_STS_REV2), + RK8XX_IRQ_REG(RK806_IRQ_CRC_ERROR, 1, RK806_INT_STS_CRC_ERROR), + RK8XX_IRQ_REG(RK806_IRQ_SLP3_GPIO, 1, RK806_INT_STS_SLP3_GPIO), + RK8XX_IRQ_REG(RK806_IRQ_SLP2_GPIO, 1, RK806_INT_STS_SLP2_GPIO), + RK8XX_IRQ_REG(RK806_IRQ_SLP1_GPIO, 1, RK806_INT_STS_SLP1_GPIO), + RK8XX_IRQ_REG(RK806_IRQ_WDT, 1, RK806_INT_STS_WDT), +}; + +static const struct rk8xx_irq_map rk808_irqs[] = +{ + /* INT_STS */ + RK8XX_IRQ_REG(RK808_IRQ_VOUT_LO, 0, RK808_IRQ_VOUT_LO_MSK), + RK8XX_IRQ_REG(RK808_IRQ_VB_LO, 0, RK808_IRQ_VB_LO_MSK), + RK8XX_IRQ_REG(RK808_IRQ_PWRON, 0, RK808_IRQ_PWRON_MSK), + RK8XX_IRQ_REG(RK808_IRQ_PWRON_LP, 0, RK808_IRQ_PWRON_LP_MSK), + RK8XX_IRQ_REG(RK808_IRQ_HOTDIE, 0, RK808_IRQ_HOTDIE_MSK), + RK8XX_IRQ_REG(RK808_IRQ_RTC_ALARM, 0, RK808_IRQ_RTC_ALARM_MSK), + RK8XX_IRQ_REG(RK808_IRQ_RTC_PERIOD, 0, RK808_IRQ_RTC_PERIOD_MSK), + /* INT_STS2 */ + RK8XX_IRQ_REG(RK808_IRQ_PLUG_IN_INT, 1, RK808_IRQ_PLUG_IN_INT_MSK), + RK8XX_IRQ_REG(RK808_IRQ_PLUG_OUT_INT, 1, RK808_IRQ_PLUG_OUT_INT_MSK), +}; + +static const struct rk8xx_irq_map rk818_irqs[] = +{ + /* INT_STS */ + RK8XX_IRQ_REG(RK818_IRQ_VOUT_LO, 0, RK818_IRQ_VOUT_LO_MSK), + RK8XX_IRQ_REG(RK818_IRQ_VB_LO, 0, RK818_IRQ_VB_LO_MSK), + RK8XX_IRQ_REG(RK818_IRQ_PWRON, 0, RK818_IRQ_PWRON_MSK), + RK8XX_IRQ_REG(RK818_IRQ_PWRON_LP, 0, RK818_IRQ_PWRON_LP_MSK), + RK8XX_IRQ_REG(RK818_IRQ_HOTDIE, 0, RK818_IRQ_HOTDIE_MSK), + RK8XX_IRQ_REG(RK818_IRQ_RTC_ALARM, 0, RK818_IRQ_RTC_ALARM_MSK), + RK8XX_IRQ_REG(RK818_IRQ_RTC_PERIOD, 0, RK818_IRQ_RTC_PERIOD_MSK), + RK8XX_IRQ_REG(RK818_IRQ_USB_OV, 0, RK818_IRQ_USB_OV_MSK), + /* INT_STS2 */ + RK8XX_IRQ_REG(RK818_IRQ_PLUG_IN, 1, RK818_IRQ_PLUG_IN_MSK), + RK8XX_IRQ_REG(RK818_IRQ_PLUG_OUT, 1, RK818_IRQ_PLUG_OUT_MSK), + RK8XX_IRQ_REG(RK818_IRQ_CHG_OK, 1, RK818_IRQ_CHG_OK_MSK), + RK8XX_IRQ_REG(RK818_IRQ_CHG_TE, 1, RK818_IRQ_CHG_TE_MSK), + RK8XX_IRQ_REG(RK818_IRQ_CHG_TS1, 1, RK818_IRQ_CHG_TS1_MSK), + RK8XX_IRQ_REG(RK818_IRQ_TS2, 1, RK818_IRQ_TS2_MSK), + RK8XX_IRQ_REG(RK818_IRQ_CHG_CVTLIM, 1, RK818_IRQ_CHG_CVTLIM_MSK), + RK8XX_IRQ_REG(RK818_IRQ_DISCHG_ILIM, 1, RK818_IRQ_DISCHG_ILIM_MSK), +}; + +static const struct rk8xx_irq_map rk817_irqs[] = +{ + RK8XX_IRQ_REG_LINE(RK817_IRQ_PWRON_FALL, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_PWRON_RISE, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_PWRON, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_PWMON_LP, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_HOTDIE, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_RTC_ALARM, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_RTC_PERIOD, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_VB_LO, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_PLUG_IN, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_PLUG_OUT, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_TERM, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_TIME, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_TS, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_USB_OV, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_IN_CLMP, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_BAT_DIS_ILIM, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_GATE_GPIO, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_TS_GPIO, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CODEC_PD, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CODEC_PO, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CLASSD_MUTE_DONE, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CLASSD_OCP, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_BAT_OVP, 8), + RK8XX_IRQ_REG_LINE(RK817_IRQ_CHRG_BAT_HI, 8) +}; + +static const int rk808_rtc_irqs[] = +{ + RK808_IRQ_RTC_ALARM, +}; + +static const int rk817_rtc_irqs[] = +{ + RK817_IRQ_RTC_ALARM, +}; + +static const int rk805_pwrkey_irqs[] = +{ + RK805_IRQ_PWRON_RISE, + RK805_IRQ_PWRON_FALL, +}; + +static const int rk806_pwrkey_irqs[] = +{ + RK806_IRQ_PWRON_FALL, + RK806_IRQ_PWRON_RISE, +}; + +static const int rk817_pwrkey_irqs[] = +{ + RK817_IRQ_PWRON_RISE, + RK817_IRQ_PWRON_FALL, +}; + +static const int rk817_battery_irqs[] = +{ + RK817_IRQ_VB_LO, +}; + +static const int rk818_battery_irqs[] = +{ + RK818_IRQ_VB_LO, +}; + +static const int rk805_charger_irqs[] = +{ + RK805_IRQ_VB_LOW, +}; + +static const int rk817_charger_irqs[] = +{ + RK817_IRQ_PLUG_IN, + RK817_IRQ_PLUG_OUT, +}; + +static const int rk818_charger_irqs[] = +{ + RK818_IRQ_PLUG_IN, + RK818_IRQ_PLUG_OUT, +}; + +static const int rk817_codec_irqs[] = +{ + RK817_IRQ_CODEC_PD, + RK817_IRQ_CODEC_PO, +}; + +static const int rk806_watchdog_irqs[] = +{ + RK806_IRQ_WDT, +}; + +static const struct rk8xx_reg_data rk805_pre_init_regs[] = +{ + { RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK, RK805_BUCK1_2_ILMAX_4000MA }, + { RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK, RK805_BUCK1_2_ILMAX_4000MA }, + { RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK, RK805_BUCK3_ILMAX_3000MA }, + { RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK, RK805_BUCK4_ILMAX_3500MA }, + { RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA }, + { RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C }, +}; + +static const struct rk8xx_reg_data rk806_pre_init_regs[] = +{ + { RK806_GPIO_INT_CONFIG, RK806_INT_POL_MSK, RK806_INT_POL_L }, + { RK806_SYS_CFG3, RK806_SLAVE_RESTART_FUN_MSK, RK806_SLAVE_RESTART_FUN_EN }, + { RK806_SYS_OPTION, RK806_SYS_ENB2_2M_MSK, RK806_SYS_ENB2_2M_EN }, +}; + +static const struct rk8xx_reg_data rk808_pre_init_regs[] = +{ + { RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA }, + { RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA }, + { RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA }, + { RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK, BUCK_ILMIN_200MA }, + { RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_200MA }, + { RK808_DCDC_UV_ACT_REG, BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE}, + { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | VB_LO_SEL_3500MV }, +}; + +static const struct rk8xx_reg_data rk817_pre_init_regs[] = +{ + {RK817_RTC_CTRL_REG, RTC_STOP, RTC_STOP}, + /* Codec specific registers */ + { RK817_CODEC_DTOP_VUCTL, MASK_ALL, 0x03 }, + { RK817_CODEC_DTOP_VUCTIME, MASK_ALL, 0x00 }, + { RK817_CODEC_DTOP_LPT_SRST, MASK_ALL, 0x00 }, + { RK817_CODEC_DTOP_DIGEN_CLKE, MASK_ALL, 0x00 }, + /* from vendor driver, CODEC_AREF_RTCFG0 not defined in data sheet */ + { RK817_CODEC_AREF_RTCFG0, MASK_ALL, 0x00 }, + { RK817_CODEC_AREF_RTCFG1, MASK_ALL, 0x06 }, + { RK817_CODEC_AADC_CFG0, MASK_ALL, 0xc8 }, + /* from vendor driver, CODEC_AADC_CFG1 not defined in data sheet */ + { RK817_CODEC_AADC_CFG1, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_VOLL, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_VOLR, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_SR_ACL0, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_ALC1, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_ALC2, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_NG, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_HPF, MASK_ALL, 0x00 }, + { RK817_CODEC_DADC_RVOLL, MASK_ALL, 0xff }, + { RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff }, + { RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 }, + { RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 }, + { RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 }, + /* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */ + { RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 }, + { RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 }, + { RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 }, + { RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 }, + { RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff }, + { RK817_CODEC_DADC_RVOLR, MASK_ALL, 0xff }, + { RK817_CODEC_AMIC_CFG0, MASK_ALL, 0x70 }, + { RK817_CODEC_AMIC_CFG1, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_PGA_GAIN, MASK_ALL, 0x66 }, + { RK817_CODEC_DMIC_LMT1, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_LMT2, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_NG1, MASK_ALL, 0x00 }, + { RK817_CODEC_DMIC_NG2, MASK_ALL, 0x00 }, + /* from vendor driver, CODEC_ADAC_CFG0 not defined in data sheet */ + { RK817_CODEC_ADAC_CFG0, MASK_ALL, 0x00 }, + { RK817_CODEC_ADAC_CFG1, MASK_ALL, 0x07 }, + { RK817_CODEC_DDAC_POPD_DACST, MASK_ALL, 0x82 }, + { RK817_CODEC_DDAC_VOLL, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_VOLR, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_SR_LMT0, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_LMT1, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_LMT2, MASK_ALL, 0x00 }, + { RK817_CODEC_DDAC_MUTE_MIXCTL, MASK_ALL, 0xa0 }, + { RK817_CODEC_DDAC_RVOLL, MASK_ALL, 0xff }, + { RK817_CODEC_DDAC_RVOLR, MASK_ALL, 0xff }, + { RK817_CODEC_AHP_ANTI0, MASK_ALL, 0x00 }, + { RK817_CODEC_AHP_ANTI1, MASK_ALL, 0x00 }, + { RK817_CODEC_AHP_CFG0, MASK_ALL, 0xe0 }, + { RK817_CODEC_AHP_CFG1, MASK_ALL, 0x1f }, + { RK817_CODEC_AHP_CP, MASK_ALL, 0x09 }, + { RK817_CODEC_ACLASSD_CFG1, MASK_ALL, 0x69 }, + { RK817_CODEC_ACLASSD_CFG2, MASK_ALL, 0x44 }, + { RK817_CODEC_APLL_CFG0, MASK_ALL, 0x04 }, + { RK817_CODEC_APLL_CFG1, MASK_ALL, 0x00 }, + { RK817_CODEC_APLL_CFG2, MASK_ALL, 0x30 }, + { RK817_CODEC_APLL_CFG3, MASK_ALL, 0x19 }, + { RK817_CODEC_APLL_CFG4, MASK_ALL, 0x65 }, + { RK817_CODEC_APLL_CFG5, MASK_ALL, 0x01 }, + { RK817_CODEC_DI2S_CKM, MASK_ALL, 0x01 }, + { RK817_CODEC_DI2S_RSD, MASK_ALL, 0x00 }, + { RK817_CODEC_DI2S_RXCR1, MASK_ALL, 0x00 }, + { RK817_CODEC_DI2S_RXCR2, MASK_ALL, 0x17 }, + { RK817_CODEC_DI2S_RXCMD_TSD, MASK_ALL, 0x00 }, + { RK817_CODEC_DI2S_TXCR1, MASK_ALL, 0x00 }, + { RK817_CODEC_DI2S_TXCR2, MASK_ALL, 0x17 }, + { RK817_CODEC_DI2S_TXCR3_TXCMD, MASK_ALL, 0x00 }, + { RK817_GPIO_INT_CFG, RK817_INT_POL_MSK, RK817_INT_POL_L}, + { RK817_SYS_CFG(1), RK817_HOTDIE_TEMP_MSK | RK817_TSD_TEMP_MSK, RK817_HOTDIE_105 | RK817_TSD_140}, +}; + +static const struct rk8xx_reg_data rk818_pre_init_regs[] = { + /* improve efficiency */ + { RK818_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_250MA }, + { RK818_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_250MA }, + { RK818_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA }, + { RK818_USB_CTRL_REG, RK818_USB_ILIM_SEL_MASK, RK818_USB_ILMIN_2000MA }, + /* close charger when usb lower then 3.4V */ + { RK818_USB_CTRL_REG, RK818_USB_CHG_SD_VSEL_MASK, (0x7 << 4) }, + /* no action when vref */ + { RK818_H5V_EN_REG, RT_BIT(1), RK818_REF_RDY_CTRL }, + /* enable HDMI 5V */ + { RK818_H5V_EN_REG, RT_BIT(0), RK818_H5V_EN }, + { RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT | VB_LO_SEL_3500MV }, +}; + +static const struct rk8xx_endpoint rk805_eps[] = +{ + { .name = "rk8xx-clkout", }, + { .name = "rk8xx-pinctrl", .ofw_name = "pinctrl_rk8xx" }, + { .name = "rk8xx-regulator", .ofw_name = "regulators" }, + { + .name = "rk8xx-rtc", + .irqs_nr = RT_ARRAY_SIZE(rk808_rtc_irqs), + .irqs_list = rk808_rtc_irqs, + }, + { + .name = "rk8xx-pwrkey", + .ofw_name = "pwrkey", + .irqs_nr = RT_ARRAY_SIZE(rk805_pwrkey_irqs), + .irqs_list = rk805_pwrkey_irqs, + }, + { + .name = "rk8xx-battery", + .ofw_name = "battery", + .irqs_nr = RT_ARRAY_SIZE(rk805_charger_irqs), + .irqs_list = rk805_charger_irqs, + }, +}; + +static const struct rk8xx_endpoint rk806_eps[] = +{ + { .name = "rk8xx-pinctrl", .ofw_name = "pinctrl_rk806" }, + { .name = "rk8xx-regulator", .ofw_name = "regulators" }, + { + .name = "rk8xx-pwrkey", + .ofw_name = "pwrkey", + .irqs_nr = RT_ARRAY_SIZE(rk806_pwrkey_irqs), + .irqs_list = rk806_pwrkey_irqs, + }, + { + .name = "rk8xx-watchdog", + .irqs_nr = RT_ARRAY_SIZE(rk806_watchdog_irqs), + .irqs_list = rk806_watchdog_irqs, + }, +}; + +static const struct rk8xx_endpoint rk808_eps[] = +{ + { .name = "rk8xx-clkout", }, + { .name = "rk8xx-regulator", .ofw_name = "regulators" }, + { + .name = "rk8xx-rtc", + .irqs_nr = RT_ARRAY_SIZE(rk808_rtc_irqs), + .irqs_list = rk808_rtc_irqs, + }, +}; + +static const struct rk8xx_endpoint rk817_eps[] = +{ + { .name = "rk8xx-clkout", }, + { .name = "rk8xx-regulator", .ofw_name = "regulators" }, + { + .name = "rk8xx-rtc", + .irqs_nr = RT_ARRAY_SIZE(rk817_rtc_irqs), + .irqs_list = rk817_rtc_irqs, + }, + { + .name = "rk8xx-pwrkey", + .ofw_name = "pwrkey", + .irqs_nr = RT_ARRAY_SIZE(rk817_pwrkey_irqs), + .irqs_list = rk817_pwrkey_irqs, + }, + { + .name = "rk8xx-battery", + .ofw_name = "battery", + .ofw_compatible = "rk817,battery", + .irqs_nr = RT_ARRAY_SIZE(rk817_battery_irqs), + .irqs_list = rk817_battery_irqs, + }, + { + .name = "rk8xx-charger", + .ofw_name = "charger", + .ofw_compatible = "rk817,charger", + .irqs_nr = RT_ARRAY_SIZE(rk817_charger_irqs), + .irqs_list = rk817_charger_irqs, + }, + { + .name = "rk8xx-codec", + .ofw_name = "codec", + .ofw_compatible = "rockchip,rk817-codec", + .irqs_nr = RT_ARRAY_SIZE(rk817_codec_irqs), + .irqs_list = rk817_codec_irqs, + }, +}; + +static const struct rk8xx_endpoint rk818_eps[] = +{ + { .name = "rk8xx-clkout", }, + { .name = "rk8xx-regulator", .ofw_name = "regulators" }, + { + .name = "rk8xx-battery", + .ofw_name = "battery", + .ofw_compatible = "rk818-battery", + .irqs_nr = RT_ARRAY_SIZE(rk818_battery_irqs), + .irqs_list = rk818_battery_irqs, + }, + { + .name = "rk8xx-charger", + .ofw_name = "charger", + .irqs_nr = RT_ARRAY_SIZE(rk818_charger_irqs), + .irqs_list = rk818_charger_irqs, + }, + { + .name = "rk8xx-rtc", + .irqs_nr = RT_ARRAY_SIZE(rk808_rtc_irqs), + .irqs_list = rk808_rtc_irqs, + }, +}; + +static rt_err_t rk8xx_power_off(struct rt_device *dev) +{ + rt_uint32_t reg, bit; + struct rk8xx_power *rk8xx_power = raw_to_rk8xx_power(dev); + struct rk8xx *rk8xx = rk8xx_power->rk8xx; + + switch (rk8xx->variant) + { + case RK805_ID: + reg = RK805_DEV_CTRL_REG; + bit = DEV_OFF; + break; + + case RK806_ID: + reg = RK806_SYS_CFG3; + bit = DEV_OFF; + break; + + case RK808_ID: + reg = RK808_DEVCTRL_REG, + bit = DEV_OFF_RST; + break; + + case RK809_ID: + case RK817_ID: + reg = RK817_SYS_CFG(3); + bit = DEV_OFF; + break; + + case RK818_ID: + reg = RK818_DEVCTRL_REG; + bit = DEV_OFF; + break; + + default: + return -RT_EEMPTY; + } + + return rk8xx_update_bits(rk8xx, reg, bit, bit); +} + +static rt_err_t rk8xx_restart(struct rt_device *dev) +{ + rt_uint32_t reg, bit; + struct rk8xx_power *rk8xx_power = raw_to_rk8xx_power(dev); + struct rk8xx *rk8xx = rk8xx_power->rk8xx; + + switch (rk8xx->variant) + { + case RK806_ID: + reg = RK806_SYS_CFG3; + bit = DEV_RST; + break; + + case RK809_ID: + case RK817_ID: + reg = RK817_SYS_CFG(3); + bit = DEV_RST; + break; + + default: + return -RT_EEMPTY; + } + + return rk8xx_update_bits(rk8xx, reg, bit, bit); +} + +static rt_err_t create_rk8xx_platform_device(rt_bus_t platform_bus, + struct rk8xx *rk8xx, + const char *name, + void *ofw_node) +{ + rt_err_t err; + struct rt_platform_device *pdev = rt_platform_device_alloc(name); + + if (!pdev) + { + return -RT_ENOMEM; + } + + pdev->parent.ofw_node = ofw_node; + pdev->priv = rk8xx; + + err = rt_bus_add_device(platform_bus, &pdev->parent); + + if (err && err != -RT_ENOSYS) + { + LOG_E("Add RK8XX - %s error = %s", name, rt_strerror(err)); + } + + return err; +} + +static rt_err_t rk8xx_ofw_bind_irq(struct rk8xx_irqchip *rk8xx_ic, + struct rt_ofw_node *dev_np, + struct rt_ofw_node *np, + const struct rk8xx_endpoint *ep) +{ + /* + * ic: rk8xx-interrupt-controller { + * #interrupt-cells = <1>; + * + * rk8xx-endpoint0 { + * interrupts-extended = <&ic 0>; + * } + * + * rk8xx-endpoint1 { + * interrupts-extended = <&ic 1>, <&ic 2>; + * } + * } + */ + rt_err_t err; + fdt32_t *values; + rt_size_t irq_list_size; + static fdt32_t irq_cell; + static struct rt_ofw_node *ic_np = RT_NULL; + + if (!ic_np) + { + ic_np = rt_ofw_append_child(dev_np, "rk8xx-interrupt-controller"); + + if (!ic_np) + { + return -RT_ENOSYS; + } + + irq_cell = cpu_to_fdt32(1); + err = rt_ofw_append_prop(ic_np, "#interrupt-cells", sizeof(fdt32_t), &irq_cell); + + if (err) + { + return err; + } + + rt_ofw_data(ic_np) = &rk8xx_ic->parent; + } + + irq_list_size = sizeof(fdt32_t) * 2 * ep->irqs_nr; + values = rt_malloc(irq_list_size); + + if (!values) + { + return -RT_ENOMEM; + } + + for (int i = 0; i < ep->irqs_nr; ++i) + { + values[i * 2] = cpu_to_fdt32(ic_np->phandle); + values[i * 2 + 1] = cpu_to_fdt32(ep->irqs_list[i]); + } + + if ((err = rt_ofw_append_prop(np, "interrupts-extended", irq_list_size, values))) + { + rt_free(values); + } + + return err; +} + +rt_err_t rk8xx_shutdown(struct rk8xx *rk8xx) +{ + rt_err_t err; + + switch (rk8xx->variant) + { + case RK805_ID: + err = rk8xx_update_bits(rk8xx, RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SHUTDOWN_FUN); + break; + + case RK809_ID: + case RK817_ID: + err = rk8xx_update_bits(rk8xx, RK817_SYS_CFG(3), RK817_SLPPIN_FUNC_MSK, SLPPIN_DN_FUN); + break; + + default: + return RT_EOK; + } + + if (err) + { + LOG_W("Cannot switch to power down function"); + } + + return err; +} + +rt_err_t rk8xx_probe(struct rk8xx *rk8xx) +{ + rt_err_t err; + rt_bool_t iomux_retry; + rt_bus_t platform_bus; + int rk8xx_ep_nr, pre_init_regs_nr; + struct rt_ofw_node *np, *dev_np; + struct rk8xx_irqchip *rk8xx_ic; + const struct rk8xx_endpoint *rk8xx_ep; + const struct rk8xx_reg_data *pre_init_regs; + + if (!rk8xx) + { + return -RT_EINVAL; + } + + platform_bus = rt_bus_find_by_name("platform"); + + if (!platform_bus) + { + return -RT_EIO; + } + + dev_np = rk8xx->dev->ofw_node; + + rk8xx_ic = rt_calloc(1, sizeof(*rk8xx_ic)); + + if (!rk8xx_ic) + { + return -RT_ENOMEM; + } + + switch (rk8xx->variant) + { + case RK805_ID: + rk8xx_ic->num_regs = 1; + rk8xx_ic->status_base = RK805_INT_STS_REG; + rk8xx_ic->mask_base = RK805_INT_STS_MSK_REG; + rk8xx_ic->ack_base = RK805_INT_STS_REG; + rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk805_irqs); + rk8xx_ic->irqs_map = rk805_irqs; + + rk8xx_ep = rk805_eps; + rk8xx_ep_nr = RT_ARRAY_SIZE(rk805_eps); + + pre_init_regs = rk805_pre_init_regs; + pre_init_regs_nr = RT_ARRAY_SIZE(rk805_pre_init_regs); + break; + + case RK806_ID: + rk8xx_ic->num_regs = 2; + rk8xx_ic->reg_stride = 2; + rk8xx_ic->mask_base = RK806_INT_MSK0; + rk8xx_ic->status_base = RK806_INT_STS0; + rk8xx_ic->ack_base = RK806_INT_STS0; + rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk806_irqs); + rk8xx_ic->irqs_map = rk806_irqs; + + rk8xx_ep = rk806_eps; + rk8xx_ep_nr = RT_ARRAY_SIZE(rk806_eps); + + pre_init_regs = rk806_pre_init_regs; + pre_init_regs_nr = RT_ARRAY_SIZE(rk806_pre_init_regs); + break; + + case RK808_ID: + rk8xx_ic->num_regs = 2; + rk8xx_ic->reg_stride = 2; + rk8xx_ic->status_base = RK808_INT_STS_REG1; + rk8xx_ic->mask_base = RK808_INT_STS_MSK_REG1; + rk8xx_ic->ack_base = RK808_INT_STS_REG1; + rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk808_irqs); + rk8xx_ic->irqs_map = rk808_irqs; + + rk8xx_ep = rk808_eps; + rk8xx_ep_nr = RT_ARRAY_SIZE(rk808_eps); + + pre_init_regs = rk808_pre_init_regs; + pre_init_regs_nr = RT_ARRAY_SIZE(rk808_pre_init_regs); + break; + + case RK809_ID: + case RK817_ID: + rk8xx_ic->num_regs = 3; + rk8xx_ic->reg_stride = 2; + rk8xx_ic->status_base = RK817_INT_STS_REG0; + rk8xx_ic->mask_base = RK817_INT_STS_MSK_REG0; + rk8xx_ic->ack_base = RK817_INT_STS_REG0; + rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk817_irqs); + rk8xx_ic->irqs_map = rk817_irqs; + + rk8xx_ep = rk817_eps; + rk8xx_ep_nr = RT_ARRAY_SIZE(rk817_eps); + + pre_init_regs = rk817_pre_init_regs; + pre_init_regs_nr = RT_ARRAY_SIZE(rk817_pre_init_regs); + break; + + case RK818_ID: + rk8xx_ic->num_regs = 2; + rk8xx_ic->reg_stride = 2; + rk8xx_ic->status_base = RK818_INT_STS_REG1; + rk8xx_ic->mask_base = RK818_INT_STS_MSK_REG1; + rk8xx_ic->ack_base = RK818_INT_STS_REG1; + rk8xx_ic->irqs_nr = RT_ARRAY_SIZE(rk818_irqs); + rk8xx_ic->irqs_map = rk818_irqs; + + rk8xx_ep = rk818_eps; + rk8xx_ep_nr = RT_ARRAY_SIZE(rk818_eps); + + pre_init_regs = rk818_pre_init_regs; + pre_init_regs_nr = RT_ARRAY_SIZE(rk818_pre_init_regs); + break; + + default: + LOG_E("Unsupported RK8XX ID %u", rk8xx->variant); + return -RT_EINVAL; + } + + RT_ASSERT(rk8xx_ic->num_regs <= RK8XX_IRQCHIP_NUM_REGS_MAX); + + rk8xx_ic->rk8xx = rk8xx; + rk8xx_ic->parent.priv_data = rk8xx_ic; + rk8xx_ic->parent.ops = &rk8xx_irq_ops; + + err = rt_pic_linear_irq(&rk8xx_ic->parent, rk8xx_ic->irqs_nr); + + if (err) + { + LOG_E("Init RK8XX IRQ chip failed error = %s", rt_strerror(err)); + + return err; + } + + rt_pic_user_extends(&rk8xx_ic->parent); + + /* Clear all interrupts */ + for (int i = 0; i < rk8xx_ic->num_regs; ++i) + { + rk8xx_write(rk8xx, rk8xx_ic->ack_base + i * rk8xx_ic->reg_stride, 0xff); + } + + for (int i = 0; i < pre_init_regs_nr; ++i) + { + err = rk8xx_update_bits(rk8xx, pre_init_regs[i].addr, + pre_init_regs[i].mask, pre_init_regs[i].value); + + if (err) + { + LOG_E("Write to %x fail", pre_init_regs[i].addr); + goto _fail; + } + } + + rt_pic_user_extends(&rk8xx_ic->parent); + + iomux_retry = rt_pin_ctrl_confs_apply_by_name(rk8xx->dev, RT_NULL) < 0; + + if (rt_ofw_prop_read_bool(dev_np, "rockchip,system-power-controller")) + { + struct rt_device *dev; + struct rk8xx_power *rk8xx_power = rt_calloc(1, sizeof(*rk8xx_power)); + + if (!rk8xx_power) + { + err = -RT_ENOMEM; + goto _fail; + } + + dev = &rk8xx_power->parent; + rt_dm_dev_set_name(dev, "rk-sys-pm"); + rk8xx_power->rk8xx = rk8xx; + + err = rt_dm_power_off_handler(dev, RT_DM_POWER_OFF_MODE_SHUTDOWN, + RT_DM_POWER_OFF_PRIO_PLATFORM, &rk8xx_power_off); + + if (err) + { + LOG_E("Add %s failed", "shutdown"); + } + + err = rt_dm_power_off_handler(dev, RT_DM_POWER_OFF_MODE_RESET, + RT_DM_POWER_OFF_PRIO_PLATFORM, &rk8xx_restart); + + if (err) + { + LOG_E("Add %s failed", "reset"); + } + } + + for (int i = 0; i < rk8xx_ep_nr; ++i, ++rk8xx_ep) + { + np = RT_NULL; + + if (rk8xx_ep->ofw_name) + { + if (!(np = rt_ofw_get_child_by_tag(dev_np, rk8xx_ep->ofw_name))) + { + if (rk8xx_ep->ofw_compatible) + { + np = rt_ofw_get_child_by_compatible(dev_np, rk8xx_ep->ofw_compatible); + } + + if (!np) + { + LOG_D("%s not found", rk8xx_ep->ofw_name); + + continue; + } + } + + if (!rt_ofw_node_is_available(np)) + { + continue; + } + } + + if (rk8xx_ep->irqs_nr) + { + if (!np && !(np = rt_ofw_append_child(dev_np, rk8xx_ep->name))) + { + continue; + } + + err = rk8xx_ofw_bind_irq(rk8xx_ic, dev_np, np, rk8xx_ep); + + if (err == -RT_ENOMEM) + { + goto _out_put; + } + } + + if (!rt_strcmp(rk8xx_ep->name, "rk8xx-clkout")) + { + np = rt_ofw_node_get(dev_np); + } + + err = create_rk8xx_platform_device(platform_bus, rk8xx, rk8xx_ep->name, np); + + _out_put: + rt_ofw_node_put(np); + + if (err == -RT_ENOMEM) + { + goto _fail; + } + } + + if (iomux_retry) + { + if ((err = rt_pin_ctrl_confs_apply_by_name(rk8xx->dev, RT_NULL))) + { + LOG_W("Pinctrl apply error = %s", rt_strerror(err)); + } + } + + rk8xx_ic->irq_thread = rt_thread_create("rk8xx-pmic", &rk8xx_pmic_thread_isr, + rk8xx_ic, DM_THREAD_STACK_SIZE, RT_THREAD_PRIORITY_MAX / 2, 10); + + if (!rk8xx_ic->irq_thread) + { + goto _not_irq_conf; + } + + rt_thread_startup(rk8xx_ic->irq_thread); + + rt_hw_interrupt_install(rk8xx->irq, &rk8xx_pmic_isr, rk8xx_ic, "rk8xx-pmic"); + rt_hw_interrupt_umask(rk8xx->irq); + +_not_irq_conf: + return RT_EOK; + +_fail: + rt_pic_cancel_irq(&rk8xx_ic->parent); + + return err; +} diff --git a/bsp/rockchip/dm/nvmem/Kconfig b/bsp/rockchip/dm/nvmem/Kconfig new file mode 100755 index 00000000000..de7d2c48be9 --- /dev/null +++ b/bsp/rockchip/dm/nvmem/Kconfig @@ -0,0 +1,3 @@ +config RT_NVMEM_ROCKCHIP_OTP + bool "Rockchip OTP controller support" + default n diff --git a/bsp/rockchip/dm/nvmem/SConscript b/bsp/rockchip/dm/nvmem/SConscript new file mode 100755 index 00000000000..ac87bd6787c --- /dev/null +++ b/bsp/rockchip/dm/nvmem/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_NVMEM_ROCKCHIP_OTP']): + src += ['nvmem-rockchip-otp.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c b/bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c new file mode 100755 index 00000000000..e879582ce92 --- /dev/null +++ b/bsp/rockchip/dm/nvmem/nvmem-rockchip-otp.c @@ -0,0 +1,1037 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-02-25 GuEe-GUI the first version + */ + +#include +#include + +#include + +#define DBG_TAG "nvmem.rockchip.otp" +#define DBG_LVL DBG_INFO +#include + +/* OTP Register Offsets */ +#define OTPC_SBPI_CTRL 0x0020 +#define OTPC_SBPI_CMD_VALID_PRE 0x0024 +#define OTPC_SBPI_CS_VALID_PRE 0x0028 +#define OTPC_SBPI_STATUS 0x002C +#define OTPC_USER_CTRL 0x0100 +#define OTPC_USER_ADDR 0x0104 +#define OTPC_USER_ENABLE 0x0108 +#define OTPC_USER_QP 0x0120 +#define OTPC_USER_Q 0x0124 +#define OTPC_INT_STATUS 0x0304 +#define OTPC_SBPI_CMD0_OFFSET 0x1000 +#define OTPC_SBPI_CMD1_OFFSET 0x1004 + +#define OTPC_MODE_CTRL 0x2000 +#define OTPC_IRQ_ST 0x2008 +#define OTPC_ACCESS_ADDR 0x200c +#define OTPC_RD_DATA 0x2010 +#define OTPC_REPR_RD_TRANS_NUM 0x2020 + +#define OTPC_DEEP_STANDBY 0x0 +#define OTPC_STANDBY 0x1 +#define OTPC_ACTIVE 0x2 +#define OTPC_READ_ACCESS 0x3 +#define OTPC_TRANS_NUM 0x1 +#define OTPC_RDM_IRQ_ST RT_BIT(0) +#define OTPC_STB2ACT_IRQ_ST RT_BIT(7) +#define OTPC_DP2STB_IRQ_ST RT_BIT(8) +#define OTPC_ACT2STB_IRQ_ST RT_BIT(9) +#define OTPC_STB2DP_IRQ_ST RT_BIT(10) +#define PX30S_NBYTES 4 +#define PX30S_NO_SECURE_OFFSET 224 + +/* OTP Register bits and masks */ +#define OTPC_USER_ADDR_MASK RT_GENMASK(31, 16) +#define OTPC_USE_USER RT_BIT(0) +#define OTPC_USE_USER_MASK RT_GENMASK(16, 16) +#define OTPC_USER_FSM_ENABLE RT_BIT(0) +#define OTPC_USER_FSM_ENABLE_MASK RT_GENMASK(16, 16) +#define OTPC_LOCK RT_BIT(0) +#define OTPC_LOCK_MASK RT_GENMASK(16, 16) +#define OTPC_SBPI_DONE RT_BIT(1) +#define OTPC_USER_DONE RT_BIT(2) + +#define SBPI_DAP_ADDR 0x02 +#define SBPI_DAP_ADDR_SHIFT 8 +#define SBPI_DAP_ADDR_MASK RT_GENMASK(31, 24) +#define SBPI_CMD_VALID_MASK RT_GENMASK(31, 16) +#define SBPI_DAP_CMD_WRF 0xc0 +#define SBPI_DAP_REG_ECC 0x3a +#define SBPI_ECC_ENABLE 0x00 +#define SBPI_ECC_DISABLE 0x09 +#define SBPI_ENABLE RT_BIT(0) +#define SBPI_ENABLE_MASK RT_GENMASK(16, 16) + +#define OTPC_TIMEOUT 10000 +#define OTPC_TIMEOUT_PROG 100000 +#define RK3568_NBYTES 2 + +#define RK3576_NO_SECURE_OFFSET 0x1c0 + +#define RK3588_OTPC_AUTO_CTRL 0x04 +#define RK3588_OTPC_AUTO_EN 0x08 +#define RK3588_OTPC_INT_ST 0x84 +#define RK3588_OTPC_DOUT0 0x20 +#define RK3588_NO_SECURE_OFFSET 0x300 +#define RK3588_NBYTES 4 +#define RK3588_BURST_NUM 1 +#define RK3588_BURST_SHIFT 8 +#define RK3588_ADDR_SHIFT 16 +#define RK3588_AUTO_EN RT_BIT(0) +#define RK3588_RD_DONE RT_BIT(1) + +#define RV1126_OTP_NVM_CEB 0x00 +#define RV1126_OTP_NVM_RSTB 0x04 +#define RV1126_OTP_NVM_ST 0x18 +#define RV1126_OTP_NVM_RADDR 0x1c +#define RV1126_OTP_NVM_RSTART 0x20 +#define RV1126_OTP_NVM_RDATA 0x24 +#define RV1126_OTP_NVM_TRWH 0x28 +#define RV1126_OTP_READ_ST 0x30 +#define RV1126_OTP_NVM_PRADDR 0x34 +#define RV1126_OTP_NVM_PRLEN 0x38 +#define RV1126_OTP_NVM_PRDATA 0x3c +#define RV1126_OTP_NVM_FAILTIME 0x40 +#define RV1126_OTP_NVM_PRSTART 0x44 +#define RV1126_OTP_NVM_PRSTATE 0x48 + +/* + * +----------+------------------+--------------------------+ + * | TYPE | RANGE(byte) | NOTE | + * +----------+------------------+--------------------------+ + * | system | 0x000 ~ 0x0ff | system info, read only | + * +----------+------------------+--------------------------+ + * | oem | 0x100 ~ 0x1ef | for customized | + * +----------+------------------+--------------------------+ + * | reserved | 0x1f0 ~ 0x1f7 | future extension | + * +----------+------------------+--------------------------+ + * | wp | 0x1f8 ~ 0x1ff | write protection for oem | + * +----------+------------------+--------------------------+ + * + * +-----+ +------------------+ + * | wp | -- | wp for oem range | + * +-----+ +------------------+ + * | 1f8 | | 0x100 ~ 0x11f | + * +-----+ +------------------+ + * | 1f9 | | 0x120 ~ 0x13f | + * +-----+ +------------------+ + * | 1fa | | 0x140 ~ 0x15f | + * +-----+ +------------------+ + * | 1fb | | 0x160 ~ 0x17f | + * +-----+ +------------------+ + * | 1fc | | 0x180 ~ 0x19f | + * +-----+ +------------------+ + * | 1fd | | 0x1a0 ~ 0x1bf | + * +-----+ +------------------+ + * | 1fe | | 0x1c0 ~ 0x1df | + * +-----+ +------------------+ + * | 1ff | | 0x1e0 ~ 0x1ef | + * +-----+ +------------------+ + */ +#define RV1126_OTP_OEM_OFFSET 0x100 +#define RV1126_OTP_OEM_SIZE 0xf0 +#define RV1126_OTP_WP_OFFSET 0x1f8 +#define RV1126_OTP_WP_SIZE 0x8 + +/* each bit mask 32 bits in OTP NVM */ +#define ROCKCHIP_OTP_WP_MASK_NBITS 64 + +#define OFFSET_IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) + +struct rockchip_otp; + +struct rockchip_otp_data +{ + int size; + int ns_offset; + + rt_ssize_t (*read)(struct rockchip_otp *, int offset, void *buf, rt_size_t bytes); + rt_ssize_t (*write)(struct rockchip_otp *, int offset, void *buf, rt_size_t bytes); + rt_err_t (*init)(struct rockchip_otp *); +}; + +struct rockchip_otp +{ + struct rt_nvmem_device parent; + void *regs; + + rt_bool_t was_written; + struct rt_clk_array *clk_arr; + struct rt_reset_control *rstc; + const struct rockchip_otp_data *soc_data; + + struct rt_mutex mutex; + RT_BITMAP_DECLARE(wp_mask, ROCKCHIP_OTP_WP_MASK_NBITS); +}; + +#define raw_to_rockchip_otp(raw) rt_container_of(raw, struct rockchip_otp, parent) + +#define readl_poll_timeout(ADDR, VAL, COND, DELAY_US, TIMEOUT_US) \ +({ \ + rt_uint64_t timeout_us = (TIMEOUT_US); \ + rt_int64_t left_ns = timeout_us * 1000L; \ + rt_ubase_t delay_us = (DELAY_US); \ + rt_uint64_t delay_ns = delay_us * 1000L; \ + for (;;) \ + { \ + (VAL) = HWREG32(ADDR); \ + if (COND) \ + { \ + break; \ + } \ + if (timeout_us && left_ns < 0) \ + { \ + (VAL) = HWREG32(ADDR); \ + break; \ + } \ + if (delay_us) \ + { \ + rt_hw_us_delay(delay_us); \ + if (timeout_us) \ + { \ + left_ns -= delay_ns; \ + } \ + } \ + rt_hw_cpu_relax(); \ + if (timeout_us) \ + { \ + --left_ns; \ + } \ + } \ + (COND) ? RT_EOK : -RT_ETIMEOUT; \ +}) + +static rt_err_t rockchip_otp_reset(struct rockchip_otp *rk_otp) +{ + rt_err_t err; + + if ((err = rt_reset_control_assert(rk_otp->rstc))) + { + LOG_E("Failed to assert otp phy error = %s", rt_strerror(err)); + return err; + } + + rt_hw_us_delay(2); + + if ((err = rt_reset_control_deassert(rk_otp->rstc))) + { + LOG_E("Failed to deassert otp phy error = %s", rt_strerror(err)); + return err; + } + + return RT_EOK; +} + +static rt_err_t px30_otp_wait_status(struct rockchip_otp *rk_otp, rt_uint32_t flag) +{ + rt_err_t err; + rt_uint32_t status = 0; + + err = readl_poll_timeout(rk_otp->regs + OTPC_INT_STATUS, status, + (status & flag), 1, OTPC_TIMEOUT); + + if (err) + { + return err; + } + + /* Clean int status */ + HWREG32(rk_otp->regs + OTPC_INT_STATUS) = flag; + + return RT_EOK; +} + +static rt_err_t px30_otp_ecc_enable(struct rockchip_otp *rk_otp, rt_bool_t enable) +{ + rt_err_t err; + + HWREG32(rk_otp->regs + OTPC_SBPI_CTRL) = SBPI_DAP_ADDR_MASK | + (SBPI_DAP_ADDR << SBPI_DAP_ADDR_SHIFT); + HWREG32(rk_otp->regs + OTPC_SBPI_CMD_VALID_PRE) = SBPI_CMD_VALID_MASK | 0x1; + HWREG32(rk_otp->regs + OTPC_SBPI_CMD0_OFFSET) = + SBPI_DAP_CMD_WRF | SBPI_DAP_REG_ECC; + + HWREG32(rk_otp->regs + OTPC_SBPI_CMD1_OFFSET) = + enable ? SBPI_ECC_ENABLE : SBPI_ECC_DISABLE; + HWREG32(rk_otp->regs + OTPC_SBPI_CTRL) = SBPI_ENABLE_MASK | SBPI_ENABLE; + + if ((err = px30_otp_wait_status(rk_otp, OTPC_SBPI_DONE)) < 0) + { + LOG_E("Timeout during ecc_enable"); + } + + return err; +} + +static rt_ssize_t px30_otp_read(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res; + rt_uint8_t *buf = val; + + if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0) + { + LOG_E("Failed to prepare/enable clks"); + + return res; + } + + if ((res = rockchip_otp_reset(rk_otp))) + { + LOG_E("Failed to reset otp phy"); + + goto _disable_clks; + } + + if ((res = px30_otp_ecc_enable(rk_otp, RT_FALSE)) < 0) + { + LOG_E("Enable ECC error = %s", rt_strerror(res)); + + goto _disable_clks; + } + + HWREG32(rk_otp->regs + OTPC_USER_CTRL) = OTPC_USE_USER | OTPC_USE_USER_MASK; + rt_hw_us_delay(5); + + for (int i = 0; i < bytes; ++i) + { + HWREG32(rk_otp->regs + OTPC_USER_ADDR) = offset++ | OTPC_USER_ADDR_MASK; + HWREG32(rk_otp->regs + OTPC_USER_ENABLE) = + OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK; + + if ((res = px30_otp_wait_status(rk_otp, OTPC_USER_DONE)) < 0) + { + LOG_E("Timeout during read setup"); + + goto _read_end; + } + + *buf++ = HWREG8(rk_otp->regs + OTPC_USER_Q); + } + +_read_end: + HWREG32(rk_otp->regs + OTPC_USER_CTRL) = 0x0 | OTPC_USE_USER_MASK; + +_disable_clks: + rt_clk_array_disable_unprepare(rk_otp->clk_arr); + + return bytes; +} + +static rt_err_t px30s_otp_wait_status(struct rockchip_otp *rk_otp, rt_uint32_t flag) +{ + rt_err_t err; + rt_uint32_t status = 0; + + err = readl_poll_timeout(rk_otp->regs + OTPC_IRQ_ST, status, + (status & flag), 1, OTPC_TIMEOUT); + + if (err) + { + return err; + } + + /* clean int status */ + HWREG32(rk_otp->regs + OTPC_IRQ_ST) = flag; + + return RT_EOK; +} + +static rt_err_t px30s_otp_active(struct rockchip_otp *rk_otp) +{ + rt_uint32_t mode; + rt_err_t err = RT_EOK; + + mode = HWREG32(rk_otp->regs + OTPC_MODE_CTRL); + + switch (mode) + { + case OTPC_DEEP_STANDBY: + HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_STANDBY; + + if ((err = px30s_otp_wait_status(rk_otp, OTPC_DP2STB_IRQ_ST)) < 0) + { + LOG_E("Timeout during wait dp2stb"); + + return err; + } + + /* Fallthrough */ + case OTPC_STANDBY: + HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_ACTIVE; + + if ((err = px30s_otp_wait_status(rk_otp, OTPC_STB2ACT_IRQ_ST)) < 0) + { + LOG_E("Timeout during wait stb2act"); + + return err; + } + + break; + + default: + break; + } + + return err; +} + +static rt_err_t px30s_otp_standby(struct rockchip_otp *rk_otp) +{ + rt_uint32_t mode; + rt_err_t err = RT_EOK; + + mode = HWREG32(rk_otp->regs + OTPC_MODE_CTRL); + + switch (mode) + { + case OTPC_ACTIVE: + HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_STANDBY; + + if ((err = px30s_otp_wait_status(rk_otp, OTPC_ACT2STB_IRQ_ST)) < 0) + { + LOG_E("Timeout during wait act2stb"); + + return err; + } + + /* Fallthrough */ + case OTPC_STANDBY: + HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_DEEP_STANDBY; + + if ((err = px30s_otp_wait_status(rk_otp, OTPC_STB2DP_IRQ_ST)) < 0) + { + LOG_E("Timeout during wait stb2dp"); + + return err; + } + + break; + + default: + break; + } + + return err; +} + +static rt_ssize_t px30s_otp_read(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res; + rt_uint8_t *buf; + rt_uint32_t out_value; + int addr_start, addr_end, addr_offset, addr_len; + + if (offset >= rk_otp->soc_data->size) + { + return -RT_ENOMEM; + } + + if (offset + bytes > rk_otp->soc_data->size) + { + bytes = rk_otp->soc_data->size - offset; + } + + if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0) + { + LOG_E("Failed to prepare/enable clks"); + + return res; + } + + if ((res = rockchip_otp_reset(rk_otp))) + { + LOG_E("Failed to reset otp phy"); + + goto _disable_clks; + } + + if ((res = px30s_otp_active(rk_otp))) + { + goto _disable_clks; + } + + addr_start = rt_rounddown(offset, PX30S_NBYTES) / PX30S_NBYTES; + addr_end = rt_roundup(offset + bytes, PX30S_NBYTES) / PX30S_NBYTES; + addr_offset = offset % PX30S_NBYTES; + addr_len = addr_end - addr_start; + addr_start += PX30S_NO_SECURE_OFFSET; + + buf = rt_calloc(PX30S_NBYTES, addr_len * sizeof(*buf)); + if (!buf) + { + res = -RT_ENOMEM; + goto _read_end; + } + + for (int i = 0; addr_len--; i += PX30S_NBYTES) + { + HWREG32(rk_otp->regs + OTPC_REPR_RD_TRANS_NUM) = OTPC_TRANS_NUM; + HWREG32(rk_otp->regs + OTPC_ACCESS_ADDR) = addr_start++; + HWREG32(rk_otp->regs + OTPC_MODE_CTRL) = OTPC_READ_ACCESS; + + if ((res = px30s_otp_wait_status(rk_otp, OTPC_RDM_IRQ_ST)) < 0) + { + LOG_E("timeout during wait rd"); + + goto _read_end; + } + + out_value = HWREG32(rk_otp->regs + OTPC_RD_DATA); + rt_memcpy(&buf[i], &out_value, PX30S_NBYTES); + } + + rt_memcpy(val, buf + addr_offset, (rt_uint32_t)bytes); + res = bytes; + +_read_end: + rt_free(buf); + px30s_otp_standby(rk_otp); + +_disable_clks: + rt_clk_array_disable_unprepare(rk_otp->clk_arr); + + return res; +} + +static rt_ssize_t rk3568_otp_read(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res; + rt_uint8_t *buf; + rt_uint32_t otp_qp, out_value; + int addr_start, addr_end, addr_offset, addr_len; + + addr_start = rt_rounddown(offset, RK3568_NBYTES) / RK3568_NBYTES; + addr_end = rt_roundup(offset + bytes, RK3568_NBYTES) / RK3568_NBYTES; + addr_offset = offset % RK3568_NBYTES; + addr_len = addr_end - addr_start; + + buf = rt_calloc(RK3568_NBYTES, addr_len * sizeof(*buf)); + if (!buf) + { + return -RT_ENOMEM; + } + + if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0) + { + LOG_E("Failed to prepare/enable clks"); + goto _out_free; + } + + if ((res = rockchip_otp_reset(rk_otp))) + { + LOG_E("failed to reset otp phy"); + + goto _disable_clks; + } + + if ((res = px30_otp_ecc_enable(rk_otp, RT_TRUE)) < 0) + { + LOG_E("Enable ECC error = %s", rt_strerror(res)); + + goto _disable_clks; + } + + HWREG32(rk_otp->regs + OTPC_USER_CTRL) = OTPC_USE_USER | OTPC_USE_USER_MASK; + + rt_hw_us_delay(5); + + for (int i = 0; addr_len--; i += RK3568_NBYTES) + { + HWREG32(rk_otp->regs + OTPC_USER_ADDR) = + addr_start++ | OTPC_USER_ADDR_MASK; + HWREG32(rk_otp->regs + OTPC_USER_ENABLE) = + OTPC_USER_FSM_ENABLE | OTPC_USER_FSM_ENABLE_MASK; + + if ((res = px30_otp_wait_status(rk_otp, OTPC_USER_DONE)) < 0) + { + LOG_E("Timeout during read setup"); + + goto _read_end; + } + + otp_qp = HWREG32(rk_otp->regs + OTPC_USER_QP); + + if (((otp_qp & 0xc0) == 0xc0) || (otp_qp & 0x20)) + { + res = -RT_EIO; + LOG_E("ECC check error during read setup"); + + goto _read_end; + } + + out_value = HWREG32(rk_otp->regs + OTPC_USER_Q); + rt_memcpy(&buf[i], &out_value, RK3568_NBYTES); + } + + rt_memcpy(val, buf + addr_offset, bytes); + res = bytes; + +_read_end: + HWREG32(rk_otp->regs + OTPC_USER_CTRL) = 0x0 | OTPC_USE_USER_MASK; + +_disable_clks: + + rt_clk_array_disable_unprepare(rk_otp->clk_arr); +_out_free: + rt_free(buf); + + return res; +} + +static rt_err_t rk3588_otp_wait_status(struct rockchip_otp *rk_otp, + rt_uint32_t flag) +{ + rt_err_t err; + rt_uint32_t status = 0; + + err = readl_poll_timeout(rk_otp->regs + RK3588_OTPC_INT_ST, status, + (status & flag), 1, OTPC_TIMEOUT); + + if (err) + { + return err; + } + + /* clean int status */ + HWREG32(rk_otp->regs + RK3588_OTPC_INT_ST) = flag; + + return RT_EOK; +} + +static rt_ssize_t rk3588_otp_read(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res = 0; + rt_uint8_t *buf; + rt_uint32_t out_value; + int addr_start, addr_end, addr_offset, addr_len; + + if (offset >= rk_otp->soc_data->size) + { + return -RT_ENOMEM; + } + + if (offset + bytes > rk_otp->soc_data->size) + { + bytes = rk_otp->soc_data->size - offset; + } + + addr_start = rt_rounddown(offset, RK3588_NBYTES) / RK3588_NBYTES; + addr_end = rt_roundup(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES; + addr_offset = offset % RK3588_NBYTES; + addr_len = addr_end - addr_start; + addr_start += rk_otp->soc_data->ns_offset; + + buf = rt_calloc(RK3588_NBYTES, addr_len * sizeof(*buf)); + if (!buf) + { + return -RT_ENOMEM; + } + + if ((res = rt_clk_array_prepare_enable(rk_otp->clk_arr)) < 0) + { + LOG_E("Failed to prepare/enable clks"); + + goto _out_free; + } + + for (int i = 0; addr_len--; i += RK3588_NBYTES, ++addr_start) + { + HWREG32(rk_otp->regs + RK3588_OTPC_AUTO_CTRL) = + (addr_start << RK3588_ADDR_SHIFT) | + (RK3588_BURST_NUM << RK3588_BURST_SHIFT); + HWREG32(rk_otp->regs + RK3588_OTPC_AUTO_EN) = RK3588_AUTO_EN; + + if ((res = rk3588_otp_wait_status(rk_otp, RK3588_RD_DONE)) < 0) + { + LOG_E("Timeout during read setup"); + + goto _read_end; + } + + out_value = HWREG32(rk_otp->regs + RK3588_OTPC_DOUT0); + rt_memcpy(&buf[i], &out_value, RK3588_NBYTES); + } + + rt_memcpy(val, buf + addr_offset, bytes); + res = bytes; + +_read_end: + rt_clk_array_disable_unprepare(rk_otp->clk_arr); + +_out_free: + rt_free(buf); + + return res; +} + +static rt_err_t rv1126_otp_init(struct rockchip_otp *rk_otp) +{ + rt_err_t err; + rt_uint32_t status = 0; + + HWREG32(rk_otp->regs + RV1126_OTP_NVM_CEB) = 0x0; + err = readl_poll_timeout(rk_otp->regs + RV1126_OTP_NVM_ST, status, + status & 0x1, 1, OTPC_TIMEOUT); + + if (err < 0) + { + LOG_E("Timeout during set ceb"); + + return err; + } + + HWREG32(rk_otp->regs + RV1126_OTP_NVM_RSTB) = 0x1; + err = readl_poll_timeout(rk_otp->regs + RV1126_OTP_NVM_ST, status, + status & 0x4, 1, OTPC_TIMEOUT); + + if (err < 0) + { + LOG_E("Timeout during set rstb"); + + return err; + } + + return RT_EOK; +} + +static rt_ssize_t rv1126_otp_read(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res; + rt_uint8_t *buf = val; + rt_uint32_t status = 0; + + for (int i = 0; i < bytes; ++i) + { + HWREG32(rk_otp->regs + RV1126_OTP_NVM_RADDR) = offset++; + HWREG32(rk_otp->regs + RV1126_OTP_NVM_RSTART) = 0x1; + + res = readl_poll_timeout(rk_otp->regs + RV1126_OTP_READ_ST, + status, status == 0, 1, OTPC_TIMEOUT); + + if (res < 0) + { + LOG_E("Timeout during read setup"); + + return res; + } + + *buf++ = HWREG8(rk_otp->regs + RV1126_OTP_NVM_RDATA); + } + + return bytes; +} + +static rt_err_t rv1126_otp_prog(struct rockchip_otp *rk_otp, + rt_uint32_t bit_offset, rt_uint32_t data, rt_uint32_t bit_len) +{ + rt_err_t err; + rt_uint32_t status = 0; + + if (!data) + { + return RT_EOK; + } + + HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRADDR) = bit_offset; + HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRLEN) = bit_len - 1; + HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRDATA) = data; + HWREG32(rk_otp->regs + RV1126_OTP_NVM_PRSTART) = 1; + + /* Wait max 100 ms */ + err = readl_poll_timeout(rk_otp->regs + RV1126_OTP_NVM_PRSTATE, + status, status == 0, 1, OTPC_TIMEOUT_PROG); + + if (err) + { + LOG_E("Timeout during prog"); + } + + return err; +} + +static rt_ssize_t rv1126_otp_write(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res; + rt_uint8_t *buf = val, val_r, val_w; + + for (int i = 0; i < bytes; ++i) + { + if ((res = rv1126_otp_read(rk_otp, offset, &val_r, 1))) + { + return res; + } + + val_w = *buf & (~val_r); + + if ((res = rv1126_otp_prog(rk_otp, offset * 8, val_w, 8))) + { + return res; + } + + ++buf; + ++offset; + } + + return bytes; +} + +static rt_ssize_t rv1126_otp_wp(struct rockchip_otp *rk_otp, int offset, + rt_size_t bytes) +{ + int nbits = bytes / 4; + rt_uint32_t bit_idx = (offset - RV1126_OTP_OEM_OFFSET) / 4; + + for (int i = 0; i < nbits; ++i) + { + rt_bitmap_set_bit(rk_otp->wp_mask, bit_idx + i); + } + + return rv1126_otp_write(rk_otp, RV1126_OTP_WP_OFFSET, rk_otp->wp_mask, + RV1126_OTP_WP_SIZE); +} + +static rt_ssize_t rv1126_otp_oem_write(struct rockchip_otp *rk_otp, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res; + + if (offset < RV1126_OTP_OEM_OFFSET || + offset > (RV1126_OTP_OEM_OFFSET + RV1126_OTP_OEM_SIZE - 1) || + bytes > RV1126_OTP_OEM_SIZE || + (offset + bytes) > (RV1126_OTP_OEM_OFFSET + RV1126_OTP_OEM_SIZE)) + { + return -RT_EINVAL; + } + + if (!OFFSET_IS_ALIGNED(offset, 4) || !OFFSET_IS_ALIGNED(bytes, 4)) + { + return -RT_EINVAL; + } + + if (!(res = rv1126_otp_write(rk_otp, offset, val, bytes))) + { + res = rv1126_otp_wp(rk_otp, offset, bytes); + } + + return res; +} + +static rt_ssize_t rockchip_otp_read(struct rt_nvmem_device *ndev, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res = -RT_EINVAL; + struct rockchip_otp *rk_otp = raw_to_rockchip_otp(ndev); + + rt_mutex_take(&rk_otp->mutex, RT_WAITING_FOREVER); + + if (rk_otp->soc_data && rk_otp->soc_data->read) + { + res = rk_otp->soc_data->read(rk_otp, offset, val, bytes); + } + + rt_mutex_release(&rk_otp->mutex); + + return res; +} + +static rt_ssize_t rockchip_otp_write(struct rt_nvmem_device *ndev, int offset, + void *val, rt_size_t bytes) +{ + rt_ssize_t res = -RT_EINVAL; + struct rockchip_otp *rk_otp = raw_to_rockchip_otp(ndev); + + rt_mutex_take(&rk_otp->mutex, RT_WAITING_FOREVER); + + if (!rk_otp->was_written && rk_otp->soc_data && rk_otp->soc_data->write) + { + res = rk_otp->soc_data->write(rk_otp, offset, val, bytes); + } + + rt_mutex_release(&rk_otp->mutex); + + return res; +} + +static const struct rockchip_otp_data px30_data = +{ + .size = 0x40, + .read = px30_otp_read, +}; + +static const struct rockchip_otp_data px30s_data = +{ + .size = 0x80, + .read = px30s_otp_read, +}; + +static const struct rockchip_otp_data rk3568_data = +{ + .size = 0x80, + .read = rk3568_otp_read, +}; + +static const struct rockchip_otp_data rk3576_data = +{ + .size = 0x100, + .ns_offset = RK3576_NO_SECURE_OFFSET, + .read = rk3588_otp_read, +}; + +static const struct rockchip_otp_data rk3588_data = +{ + .size = 0x400, + .ns_offset = RK3588_NO_SECURE_OFFSET, + .read = rk3588_otp_read, +}; + +static const struct rockchip_otp_data rv1106_data = +{ + .size = 0x80, + .read = rk3568_otp_read, +}; + +static const struct rockchip_otp_data rv1126_data = +{ + .size = 0x200, + .init = rv1126_otp_init, + .read = rv1126_otp_read, + .write = rv1126_otp_oem_write, +}; + +static rt_err_t rockchip_otp_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_nvmem_device *nvmem; + struct rt_device *dev = &pdev->parent; + const struct rockchip_otp_data *soc_data = pdev->id->data; + struct rockchip_otp *rk_otp = rt_calloc(1, sizeof(*rk_otp)); + + if (!rk_otp) + { + return -RT_ENOMEM; + } + + rk_otp->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_otp->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_otp->clk_arr = rt_clk_get_array(dev); + + if (rt_is_err(rk_otp->clk_arr)) + { + err = rt_ptr_err(rk_otp->clk_arr); + goto _fail; + } + + rk_otp->rstc = rt_reset_control_get_array(dev); + + if (rt_is_err(rk_otp->rstc)) + { + err = rt_ptr_err(rk_otp->rstc); + goto _fail; + } + + if (soc_data->init) + { + if ((err = soc_data->init(rk_otp))) + { + goto _fail; + } + } + + dev->user_data = rk_otp; + + rk_otp->soc_data = soc_data; + nvmem = &rk_otp->parent; + + nvmem->parent.ofw_node = dev->ofw_node; + nvmem->reg_read = rockchip_otp_read, + nvmem->reg_write = rockchip_otp_write, + nvmem->size = soc_data->size; + nvmem->read_only = soc_data->write == RT_NULL; + nvmem->stride = 1; + nvmem->word_size = 1; + + if ((err = rt_nvmem_device_register(nvmem))) + { + goto _fail; + } + + rt_mutex_init(&rk_otp->mutex, "rockchip-otp", RT_IPC_FLAG_PRIO); + + return RT_EOK; + +_fail: + if (rk_otp->regs) + { + rt_iounmap(rk_otp->regs); + } + + if (!rt_is_err_or_null(rk_otp->clk_arr)) + { + rt_clk_array_put(rk_otp->clk_arr); + } + + rt_free(rk_otp); + + return err; +} + +static rt_err_t rockchip_otp_remove(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rockchip_otp *rk_otp = pdev->parent.user_data; + + err = rt_nvmem_device_unregister(&rk_otp->parent); + + rt_iounmap(rk_otp->regs); + rt_clk_array_put(rk_otp->clk_arr); + + rt_free(rk_otp); + + return err; +} + +static const struct rt_ofw_node_id rockchip_otp_ofw_ids[] = +{ + { .compatible = "rockchip,px30-otp", .data = &px30_data, }, + { .compatible = "rockchip,px30s-otp", .data = &px30s_data, }, + { .compatible = "rockchip,rk3308-otp", .data = &px30_data, }, + { .compatible = "rockchip,rk3308bs-otp", .data = &px30s_data, }, + { .compatible = "rockchip,rk3568-otp", .data = &rk3568_data, }, + { .compatible = "rockchip,rk3576-otp", .data = &rk3576_data, }, + { .compatible = "rockchip,rk3588-otp", .data = &rk3588_data, }, + { .compatible = "rockchip,rv1106-otp", .data = &rv1106_data, }, + { .compatible = "rockchip,rv1126-otp", .data = &rv1126_data, }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_otp_driver = +{ + .name = "nvmem-rockchip-otp", + .ids = rockchip_otp_ofw_ids, + + .probe = rockchip_otp_probe, + .remove = rockchip_otp_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_otp_driver); diff --git a/bsp/rockchip/dm/pci/Kconfig b/bsp/rockchip/dm/pci/Kconfig new file mode 100755 index 00000000000..761b844e482 --- /dev/null +++ b/bsp/rockchip/dm/pci/Kconfig @@ -0,0 +1,11 @@ +config RT_PCI_DW_ROCKCHIP + bool "Rockchip DesignWare PCIe" + depends on RT_PCI_DW + depends on RT_USING_PIN + depends on RT_USING_PINCTRL + depends on RT_USING_PHYE + depends on RT_USING_RESET + depends on RT_USING_REGULATOR + select RT_PCI_DW_HOST + select RT_PCI_DW_EP + default n diff --git a/bsp/rockchip/dm/pci/SConscript b/bsp/rockchip/dm/pci/SConscript new file mode 100755 index 00000000000..3e0e8ed40d6 --- /dev/null +++ b/bsp/rockchip/dm/pci/SConscript @@ -0,0 +1,15 @@ +from building import * + +group = [] + +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/pci', cwd + '/../../../../components/drivers/pci/host/dw'] + +src = [] + +if GetDepend(['RT_PCI_DW_ROCKCHIP']): + src += ['pcie-dw-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/pci/pcie-dw-rockchip.c b/bsp/rockchip/dm/pci/pcie-dw-rockchip.c new file mode 100755 index 00000000000..76078d31222 --- /dev/null +++ b/bsp/rockchip/dm/pci/pcie-dw-rockchip.c @@ -0,0 +1,1645 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-09-23 GuEe-GUI first version + */ + +#define DBG_TAG "pci.dw.rockchip" +#define DBG_LVL DBG_INFO +#include + +#include "pcie-dw.h" +#include "rockchip.h" + +#define PCIE_DMA_OFFSET 0x380000 + +#define PCIE_DMA_CTRL_OFF 0x8 +#define PCIE_DMA_WR_ENB 0xc +#define PCIE_DMA_WR_CTRL_LO 0x200 +#define PCIE_DMA_WR_CTRL_HI 0x204 +#define PCIE_DMA_WR_XFERSIZE 0x208 +#define PCIE_DMA_WR_SAR_PTR_LO 0x20c +#define PCIE_DMA_WR_SAR_PTR_HI 0x210 +#define PCIE_DMA_WR_DAR_PTR_LO 0x214 +#define PCIE_DMA_WR_DAR_PTR_HI 0x218 +#define PCIE_DMA_WR_WEILO 0x18 +#define PCIE_DMA_WR_WEIHI 0x1c +#define PCIE_DMA_WR_DOORBELL 0x10 +#define PCIE_DMA_WR_INT_STATUS 0x4c +#define PCIE_DMA_WR_INT_MASK 0x54 +#define PCIE_DMA_WR_INT_CLEAR 0x58 + +#define PCIE_DMA_RD_ENB 0x2c +#define PCIE_DMA_RD_CTRL_LO 0x300 +#define PCIE_DMA_RD_CTRL_HI 0x304 +#define PCIE_DMA_RD_XFERSIZE 0x308 +#define PCIE_DMA_RD_SAR_PTR_LO 0x30c +#define PCIE_DMA_RD_SAR_PTR_HI 0x310 +#define PCIE_DMA_RD_DAR_PTR_LO 0x314 +#define PCIE_DMA_RD_DAR_PTR_HI 0x318 +#define PCIE_DMA_RD_WEILO 0x38 +#define PCIE_DMA_RD_WEIHI 0x3c +#define PCIE_DMA_RD_DOORBELL 0x30 +#define PCIE_DMA_RD_INT_STATUS 0xa0 +#define PCIE_DMA_RD_INT_MASK 0xa8 +#define PCIE_DMA_RD_INT_CLEAR 0xac + +#define PCIE_DMA_CHANEL_MAX_NUM 2 + +/* Parameters for the waiting for iATU enabled routine */ +#define LINK_WAIT_IATU_MIN 9000 +#define LINK_WAIT_IATU_MAX 10000 + +#define PCIE_DIRECT_SPEED_CHANGE (0x1 << 17) + +#define PCIE_TYPE0_STATUS_COMMAND_REG 0x4 +#define PCIE_TYPE0_BAR0_REG 0x10 + +#define PCIE_CAP_LINK_CONTROL2_LINK_STATUS 0xa0 + +#define PCIE_CLIENT_INTR_STATUS_MSG_RX 0x04 +#define PME_TO_ACK (RT_BIT(9) | RT_BIT(25)) +#define PCIE_CLIENT_INTR_STATUS_LEGACY 0x08 +#define PCIE_CLIENT_INTR_STATUS_MISC 0x10 +#define PCIE_CLIENT_INTR_MASK_LEGACY 0x1c +#define UNMASK_ALL_LEGACY_INT 0xffff0000 +#define MASK_LEGACY_INT(x) (0x00110011 << (x)) +#define UNMASK_LEGACY_INT(x) (0x00110000 << (x)) +#define PCIE_CLIENT_INTR_MASK 0x24 +#define PCIE_CLIENT_POWER 0x2c +#define READY_ENTER_L23 RT_BIT(3) +#define PCIE_CLIENT_MSG_GEN 0x34 +#define PME_TURN_OFF (RT_BIT(4) | RT_BIT(20)) +#define PCIE_CLIENT_GENERAL_DEBUG 0x104 +#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 +#define PCIE_LTSSM_APP_DLY1_EN RT_BIT(0) +#define PCIE_LTSSM_APP_DLY2_EN RT_BIT(1) +#define PCIE_LTSSM_APP_DLY1_DONE RT_BIT(2) +#define PCIE_LTSSM_APP_DLY2_DONE RT_BIT(3) +#define PCIE_LTSSM_ENABLE_ENHANCE RT_BIT(4) +#define PCIE_CLIENT_LTSSM_STATUS 0x300 +#define SMLH_LINKUP RT_BIT(16) +#define RDLH_LINKUP RT_BIT(17) +#define PCIE_CLIENT_CDM_RASDES_TBA_INFO_CMN 0x154 +#define PCIE_CLIENT_DBG_FIFO_MODE_CON 0x310 +#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0 0x320 +#define PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1 0x324 +#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0 0x328 +#define PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1 0x32c +#define PCIE_CLIENT_DBG_FIFO_STATUS 0x350 +#define PCIE_CLIENT_DBG_TRANSITION_DATA 0xffff0000 +#define PCIE_CLIENT_DBF_EN 0xffff0007 + +#define PCIE_PHY_LINKUP RT_BIT(0) +#define PCIE_DATA_LINKUP RT_BIT(1) + +#define PCIE_TYPE0_HDR_DBI2_OFFSET 0x100000 +#define PCIE_SB_BAR0_MASK_REG 0x100010 + +#define PCIE_PL_ORDER_RULE_CTRL_OFF 0x8b4 +#define RK_PCIE_L2_TMOUT_US 5000 +#define RK_PCIE_HOTRESET_TMOUT_US 10000 +#define RK_PCIE_ENUM_HW_RETRYIES 2 + +enum rockchip_pcie_ltssm_code +{ + S_L0 = 0x11, + S_L0S = 0x12, + S_L1_IDLE = 0x14, + S_L2_IDLE = 0x15, + S_MAX = 0x1f, +}; + +enum rockchip_pcie_soc_type +{ + SOC_TYPE_ALL = 0, + SOC_TYPE_RK1808, +}; + +struct rockchip_pcie_soc_data +{ + enum rockchip_pcie_soc_type type; + enum dw_pcie_device_mode mode; + rt_uint32_t msi_vector_num; +}; + +struct rockchip_pcie +{ + struct dw_pcie pci; + + void *apb_base; + + enum rt_phye_mode phy_mode; + enum rt_phye_mode phy_submode; + + struct rt_phye *phy; + struct rt_clk_array *clk_arr; + struct rt_reset_control *rstc; + struct rt_regulator *vpcie3v3; + + struct rt_syscon *usb_pcie_grf; + struct rt_syscon *pmu_grf; + + rt_base_t rst_pin; + rt_uint8_t rst_active_val; + + rt_base_t prsnt_pin; + rt_uint8_t prsnt_active_val; + rt_uint32_t perst_inactive_ms; + + rt_uint64_t mem_start; + rt_uint64_t mem_size; + + rt_uint32_t msi_vector_num; + rt_uint32_t comp_prst[2]; + + rt_bool_t in_suspend; + rt_bool_t skip_scan_in_resume; + rt_bool_t is_signal_test; + rt_bool_t bifurcation; + rt_bool_t supports_clkreq; + struct rt_work hot_rst_work; + + int intx_irq; + rt_uint32_t intx; + struct rt_ofw_node *intx_np; + struct rt_pic intx_pic; + + const struct rockchip_pcie_soc_data *soc_data; +}; + +#define to_rockchip_pcie(dw_pcie) rt_container_of(dw_pcie, struct rockchip_pcie, pci) + +rt_inline rt_uint32_t rockchip_pcie_readl_apb(struct rockchip_pcie *rk_pcie, + int offset) +{ + return HWREG32(rk_pcie->apb_base + offset); +} + +rt_inline void rockchip_pcie_writel_apb(struct rockchip_pcie *rk_pcie, + int offset, rt_uint32_t val) +{ + HWREG32(rk_pcie->apb_base + offset) = val; +} + +rt_inline void rockchip_pcie_link_status_clear(struct rockchip_pcie *rk_pcie) +{ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG, 0x0); +} + +rt_inline void rockchip_pcie_disable_ltssm(struct rockchip_pcie *rk_pcie) +{ + rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xc0008); +} + +rt_inline void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rk_pcie) +{ + rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xc000c); +} + +rt_inline rt_bool_t rockchip_pcie_udma_enabled(struct rockchip_pcie *rk_pcie) +{ + return dw_pcie_readl_dbi(&rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_CTRL_OFF); +} + +static void rockchip_pcie_intx_irq_mask(struct rt_pic_irq *pirq) +{ + struct rockchip_pcie *rk_pcie = pirq->pic->priv_data; + + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + MASK_LEGACY_INT(pirq->hwirq)); +} + +static void rockchip_pcie_intx_irq_unmask(struct rt_pic_irq *pirq) +{ + struct rockchip_pcie *rk_pcie = pirq->pic->priv_data; + + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + UNMASK_LEGACY_INT(pirq->hwirq)); +} + +static int rockchip_pcie_intx_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode) +{ + int irq; + struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq); + + if (pirq) + { + if (pirq->irq >= 0) + { + irq = pirq->irq; + } + else + { + irq = rt_pic_config_irq(pic, hwirq, hwirq); + rt_pic_irq_set_triger_mode(irq, RT_IRQ_MODE_LEVEL_HIGH); + } + } + else + { + irq = -1; + } + + return irq; +} + +static rt_err_t rockchip_pcie_intx_irq_parse(struct rt_pic *pic, + struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq) +{ + rt_err_t err = RT_EOK; + + if (args->args_count == 1) + { + out_pirq->hwirq = args->args[0]; + out_pirq->mode = RT_IRQ_MODE_LEVEL_HIGH; + } + else + { + err = -RT_EINVAL; + } + + return err; +} + +const static struct rt_pic_ops rockchip_intx_ops = +{ + .name = "DWPCI-RK-INTx", + .irq_mask = rockchip_pcie_intx_irq_mask, + .irq_unmask = rockchip_pcie_intx_irq_unmask, + .irq_map = rockchip_pcie_intx_irq_map, + .irq_parse = rockchip_pcie_intx_irq_parse, +}; + +static void rockchip_pcie_sys_isr(int irqno, void *param) +{ + rt_uint32_t reg; + struct rockchip_pcie *rk_pcie = param; + + /* DMA ISR */ + LOG_D("%s: DMA %s status = %x", rt_dm_dev_get_name(rk_pcie->dev), "WR", + dw_pcie_readl_dbi(&rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS)); + + LOG_D("%s: DMA %s status = %x", rt_dm_dev_get_name(rk_pcie->dev), "RD", + dw_pcie_readl_dbi(&rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_STATUS)); + + /* MISC ISR */ + reg = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC); + + if (reg & RT_BIT(2)) + { + rt_work_submit(&rk_pcie->hot_rst_work, 0); + } + + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC, reg); +} + +static void rockchip_pcie_legacy_isr(int irqno, void *param) +{ + rt_uint32_t ints; + struct rt_pic_irq *pirq; + struct rockchip_pcie *rk_pcie = param; + + ints = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_LEGACY); + + for (int pin = 0; ints && pin < RT_PCI_INTX_PIN_MAX; ++pin, ints >>= 1) + { + if ((ints & 1)) + { + pirq = rt_pic_find_irq(&rk_pcie->intx_pic, pin); + + rt_pic_handle_isr(pirq); + } + } +} + +static void rockchip_pcie_hot_rst_work(struct rt_work *work, void *work_data) +{ + rt_err_t err; + rt_uint32_t val, status; + struct rockchip_pcie *rk_pcie = work_data; + + val = dw_pcie_readl_dbi(&rk_pcie->pci, PCIR_COMMAND); + val &= 0xffff0000; + val |= PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_SERRESPEN; + dw_pcie_writel_dbi(&rk_pcie->pci, PCIR_COMMAND, val); + + if (rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN) + { + err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS, + status, ((status & 0x3f) == 0), 100, RK_PCIE_HOTRESET_TMOUT_US); + if (err) + { + LOG_E("Wait for detect quiet timeout"); + } + + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, + (PCIE_LTSSM_APP_DLY2_DONE) | ((PCIE_LTSSM_APP_DLY2_DONE) << 16)); + } +} + +rt_inline rt_err_t rockchip_pcie_enable_power(struct rockchip_pcie *rk_pcie) +{ + rt_err_t err = RT_EOK; + + if (rk_pcie->vpcie3v3) + { + err = rt_regulator_set_voltage(rk_pcie->vpcie3v3, 3300000, 3300000); + err |= rt_regulator_enable(rk_pcie->vpcie3v3); + } + + return err; +} + +rt_inline rt_err_t rockchip_pcie_disable_power(struct rockchip_pcie *rk_pcie) +{ + if (rk_pcie->vpcie3v3) + { + return rt_regulator_disable(rk_pcie->vpcie3v3); + } + + return RT_EOK; +} + +static void rockchip_pcie_fast_link_setup(struct rockchip_pcie *rk_pcie) +{ + rt_uint32_t val; + + /* LTSSM EN ctrl mode */ + val = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL); + val |= (PCIE_LTSSM_ENABLE_ENHANCE | PCIE_LTSSM_APP_DLY2_EN) | + ((PCIE_LTSSM_APP_DLY2_EN | PCIE_LTSSM_ENABLE_ENHANCE) << 16); + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, val); +} + +static rt_err_t rockchip_pcie_establish_link_raw(struct rockchip_pcie *rk_pcie) +{ + rt_uint32_t ltssm; + rt_bool_t std_rc = rk_pcie->soc_data->mode == DW_PCIE_RC_TYPE; + struct dw_pcie *pci = &rk_pcie->pci; + + /* + * For standard RC, even if the link has been setup by firmware, + * we still need to reset link as we need to remove all resource info + * from devices, for instance BAR, as it wasn't assigned by kernel. + */ + if (dw_pcie_link_up(pci) && !std_rc) + { + LOG_E("Link is already up"); + return RT_EOK; + } + + for (int hw_retries = 0; hw_retries < RK_PCIE_ENUM_HW_RETRYIES; ++hw_retries) + { + /* Rest the device */ + rt_pin_write(rk_pcie->rst_pin, !rk_pcie->rst_active_val); + + rockchip_pcie_disable_ltssm(rk_pcie); + rockchip_pcie_link_status_clear(rk_pcie); + + if (rk_pcie->soc_data->type != SOC_TYPE_RK1808) + { + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_MODE_CON, + PCIE_CLIENT_DBF_EN); + } + + /* Enable client reset or link down interrupt */ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000); + + /* Enable LTSSM */ + rockchip_pcie_enable_ltssm(rk_pcie); + + /* + * In resume routine, function devices' resume function must be late + * after controllers'. Some devices, such as Wi-Fi, + * need special IO setting before finishing training. + * So there must be timeout here. These kinds of devices need rescan + * devices by its driver when used. So no need to waste time waiting + * for training pass. + */ + if (rk_pcie->in_suspend && rk_pcie->skip_scan_in_resume) + { + /* + * Check WiFi power status here. + * If down, active the RST pin and return. + */ + } + + /* + * PCIe requires the refclk to be stable for 100µs prior to releasing + * PERST and T_PVPERL (Power stable to PERST# inactive) should be a + * minimum of 100ms. See table 2-4 in section 2.6.2 AC, the PCI Express + * Card Electromechanical Specification 3.0. + * So 100ms in total is the min requuirement here. + * We add a 200ms by default for sake of hoping everthings work fine. + * If it doesn't, Add more in DT node by add rockchip,perst-inactive-ms. + */ + rt_thread_mdelay(rk_pcie->perst_inactive_ms); + rt_pin_write(rk_pcie->rst_pin, rk_pcie->rst_active_val); + + /* Link is always up stably after 1ms. */ + rt_thread_mdelay(2); + + for (int retries = 0; retries < 100; ++retries) + { + if (dw_pcie_link_up(pci)) + { + /* + * We may be here in case of L0 in Gen1. But if EP is capable + * of Gen2 or Gen3, Gen switch may happen just in this time, but + * we keep on accessing devices in unstable link status. Given + * that LTSSM max timeout is 24ms per period, we can wait a bit + * more for Gen switch. + */ + rt_thread_mdelay(50); + + /* In case link drop after linkup, double check it */ + if (dw_pcie_link_up(pci)) + { + LOG_I("PCIe Link up, LTSSM is 0x%x", + rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); + + return RT_EOK; + } + } + + if (!(retries % 20)) + { + LOG_I("PCIe Linking... LTSSM is 0x%x", + rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); + } + rt_thread_mdelay(20); + } + + /* + * In response to the situation where PCIe peripherals cannot be + * enumerated due tosignal abnormalities, reset PERST# and reset + * the peripheral power supply, then restart the enumeration. + */ + ltssm = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS); + LOG_E("PCIe Link Fail, LTSSM is 0x%x", ltssm); + + if (ltssm >= 3 && !rk_pcie->is_signal_test) + { + rockchip_pcie_disable_power(rk_pcie); + rt_thread_mdelay(1000); + rockchip_pcie_enable_power(rk_pcie); + } + else + { + break; + } + } + + return rk_pcie->is_signal_test == RT_TRUE ? 0 : -RT_EINVAL; +} + +rt_inline void rockchip_pcie_set_mode(struct rockchip_pcie *rk_pcie) +{ + switch (rk_pcie->soc_data->mode) + { + case DW_PCIE_EP_TYPE: + rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xf00000); + + break; + + case DW_PCIE_RC_TYPE: + if (rk_pcie->supports_clkreq) + { + /* Application is ready to have reference clock removed */ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_POWER, 0x00010001); + } + else + { + /* Pull down CLKREQ# to assert the connecting CLOCK_GEN OE */ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_POWER, 0x30011000); + /* Disable ASPM L1SS here */ + } + + rockchip_pcie_writel_apb(rk_pcie, 0x0, 0xf00040); + + /* + * Disable order rule for CPL can't pass halted P queue. + * Need to check producer-consumer model. Just for RK1808 platform. + */ + if (rk_pcie->soc_data->type == SOC_TYPE_RK1808) + { + dw_pcie_writel_dbi(&rk_pcie->pci, PCIE_PL_ORDER_RULE_CTRL_OFF, 0xff00); + } + break; + + default: + break; + } +} + +static rt_err_t rockchip_pcie_reset_grant_ctrl(struct rockchip_pcie *rk_pcie, + rt_bool_t enable) +{ + rt_uint32_t val = (0x1 << 18); + + if (enable) + { + val |= (0x1 << 2); + } + + return rt_syscon_write(rk_pcie->usb_pcie_grf, 0x0, val); +} + +static void rockchip_pcie_ep_reset_bar(struct rockchip_pcie *rk_pcie, + int bar_idx, rt_ubase_t flags) +{ + rt_uint32_t reg = PCIR_BAR(bar_idx); + + dw_pcie_writel_dbi(&rk_pcie->pci, reg, 0x0); + + if (flags & PCIM_BAR_MEM_TYPE_64) + { + dw_pcie_writel_dbi(&rk_pcie->pci, reg + 4, 0x0); + } +} + +static rt_err_t rockchip_pcie_ep_inbound_atu(struct rockchip_pcie *rk_pcie, + int bar_idx, rt_ubase_t cpu_addr, enum dw_pcie_aspace_type aspace_type) +{ + rt_err_t err; + rt_uint32_t free_win; + rt_uint8_t func_no = 0x0; + struct dw_pcie_ep *ep = &rk_pcie->pci.endpoint; + + if (rk_pcie->in_suspend) + { + free_win = ep->bar_to_atu[bar_idx]; + } + else + { + free_win = rt_bitmap_next_clear_bit(ep->ib_window_map, 0, ep->num_ib_windows); + + if (free_win >= ep->num_ib_windows) + { + LOG_E("No free inbound window"); + return -RT_EINVAL; + } + } + + if ((err = dw_pcie_prog_inbound_atu(&rk_pcie->pci, func_no, free_win, + bar_idx, cpu_addr, aspace_type))) + { + LOG_E("Failed to program IB window"); + return err; + } + + if (rk_pcie->in_suspend) + { + return RT_EOK; + } + + ep->bar_to_atu[bar_idx] = free_win; + rt_bitmap_set_bit(ep->ib_window_map, free_win); + + return RT_EOK; +} + +static rt_err_t rockchip_pcie_ep_outbound_atu(struct rockchip_pcie *rk_pcie, + rt_ubase_t phys_addr, rt_uint64_t pci_addr, rt_size_t size) +{ + rt_uint32_t free_win; + struct dw_pcie_ep *ep = &rk_pcie->pci.endpoint; + + if (rk_pcie->in_suspend) + { + free_win = rt_bitmap_next_set_bit(ep->ob_window_map, 0, ep->num_ob_windows); + } + else + { + free_win = rt_bitmap_next_clear_bit(ep->ob_window_map, 0, ep->num_ob_windows); + + if (free_win >= ep->num_ob_windows) + { + LOG_E("No free outbound window"); + return -RT_EINVAL; + } + } + + dw_pcie_prog_outbound_atu(&rk_pcie->pci, free_win, PCIE_ATU_TYPE_MEM, + phys_addr, pci_addr, size); + + if (rk_pcie->in_suspend) + { + return RT_EOK; + } + + ep->outbound_addr[free_win] = phys_addr; + rt_bitmap_set_bit(ep->ob_window_map, free_win); + + return RT_EOK; +} + +static rt_err_t rockchip_pcie_ep_atu_init(struct rockchip_pcie *rk_pcie) +{ + rt_err_t err; + + for (int bar = 0; bar < PCI_STD_NUM_BARS; ++bar) + { + rockchip_pcie_ep_reset_bar(rk_pcie, bar, 0); + } + + if ((err = rockchip_pcie_ep_inbound_atu(rk_pcie, 0, rk_pcie->mem_start, + DW_PCIE_ASPACE_MEM))) + { + return err; + } + + if ((err = rockchip_pcie_ep_outbound_atu(rk_pcie, 0x0, 0x0, 2UL * SIZE_GB))) + { + return err; + } + + return RT_EOK; +} + +static rt_err_t rockchip_pcie_establish_link(struct dw_pcie *pci) +{ + struct rockchip_pcie *rk_pcie = rt_container_of(pci, struct rockchip_pcie, pci); + + return rockchip_pcie_establish_link_raw(rk_pcie); +} + +static const struct dw_pcie_ops dw_pcie_ops = +{ + .start_link = rockchip_pcie_establish_link, +}; + +static rt_err_t rockchip_pcie_host_init(struct dw_pcie_port *port) +{ + rt_err_t err; + struct dw_pcie *pci = to_dw_pcie_from_port(port); + struct rockchip_pcie *rk_pcie = rt_container_of(pci, struct rockchip_pcie, pci); + + dw_pcie_setup_rc(port); + + dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); + + /* Disable BAR0 BAR1 */ + dw_pcie_writel_dbi2(pci, PCIR_BAR(0), 0); + dw_pcie_writel_dbi2(pci, PCIR_BAR(1), 0); + + dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); + + err = rockchip_pcie_establish_link_raw(rk_pcie); + + if (port->msi_irq > 0) + { + dw_pcie_msi_init(port); + } + + return err; +} + +static rt_err_t rockchip_pcie_msi_host_init(struct dw_pcie_port *port) +{ + return RT_EOK; +} + +static void rockchip_pcie_set_irq_count(struct dw_pcie_port *port) +{ + struct dw_pcie *pci = to_dw_pcie_from_port(port); + struct rockchip_pcie *rk_pcie = rt_container_of(pci, struct rockchip_pcie, pci); + + port->irq_count = rk_pcie->msi_vector_num; +} + +static struct dw_pcie_host_ops rockchip_pcie_port_ops[] = +{ + [0] = /* Normal */ + { + .host_init = rockchip_pcie_host_init, + }, + [1] = /* MSI */ + { + .host_init = rockchip_pcie_host_init, + .msi_host_init = rockchip_pcie_msi_host_init, + }, + [2] = /* No MSI */ + { + .host_init = rockchip_pcie_host_init, + .set_irq_count = rockchip_pcie_set_irq_count, + }, +}; + +static rt_err_t rockchip_pcie_add_port(struct rockchip_pcie *rk_pcie) +{ + rt_err_t err; + struct dw_pcie *pci = &rk_pcie->pci; + struct dw_pcie_port *port = &pci->port; + + port->ops = &rockchip_pcie_port_ops[0]; +#ifdef RT_USING_MSI + if ((port->msi_irq = rt_dm_dev_get_irq_by_name(dev, "msi")) < 0) + { + port->ops = &rockchip_pcie_port_ops[1]; + } + else + { + port->ops = &rockchip_pcie_port_ops[2]; + } +#endif + + if ((err = dw_pcie_host_init(port))) + { + LOG_E("Init HOST error = %s", rt_strerror(err)); + return err; + } + + return RT_EOK; +} + +static rt_err_t rockchip_pcie_ep_raise_irq(struct dw_pcie_ep *ep, + rt_uint8_t func_no, enum rt_pci_ep_irq type, unsigned irq) +{ + switch (type) + { + case RT_PCI_EP_IRQ_LEGACY: + return dw_pcie_ep_raise_legacy_irq(ep, func_no); + + case RT_PCI_EP_IRQ_MSI: + return dw_pcie_ep_raise_msi_irq(ep, func_no, irq); + + case RT_PCI_EP_IRQ_MSIX: + return dw_pcie_ep_raise_msix_irq(ep, func_no, irq); + + default: + LOG_E("Unknown IRQ type = %d", type); + } + + return RT_EOK; +} + +static struct dw_pcie_ep_ops rockchip_pcie_ep_ops = +{ + .raise_irq = rockchip_pcie_ep_raise_irq, +}; + +static rt_err_t rockchip_pcie_ep_set_bar_flag(struct rockchip_pcie *rk_pcie, + int bar_idx, rt_ubase_t flags) +{ + rt_uint32_t reg = PCIR_BAR(bar_idx); + struct dw_pcie *pci = &rk_pcie->pci; + + /* Disabled the upper 32bits BAR to make a 64bits bar pair */ + if (flags & PCIM_BAR_MEM_TYPE_64) + { + dw_pcie_writel_dbi2(pci, reg + 4, 0); + } + + dw_pcie_writel_dbi(pci, reg, flags); + + if (flags & PCIM_BAR_MEM_TYPE_64) + { + dw_pcie_writel_dbi(pci, reg + 4, 0); + } + + return 0; +} + +static void rockchip_pcie_ep_setup_top(struct rockchip_pcie *rk_pcie) +{ + struct dw_pcie *pci = &rk_pcie->pci; + + /* Enable client write and read interrupt */ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xc000000); + /* Enable core write interrupt */ + dw_pcie_writel_dbi(pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, 0x0); + /* Enable core read interrupt */ + dw_pcie_writel_dbi(pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, 0x0); +} + +static void rockchip_pcie_ep_setup_bottom(struct rockchip_pcie *rk_pcie) +{ + int resbar_base; + struct dw_pcie *pci = &rk_pcie->pci; + + /* Enable bus master and memory space */ + dw_pcie_writel_dbi(pci, PCIE_TYPE0_STATUS_COMMAND_REG, 0x6); + + resbar_base = dw_pcie_find_ext_capability(pci, PCIZ_RESIZE_BAR); + if (!resbar_base) + { + LOG_W("Resbar CAP not found"); + } + else + { + /* + * Resize: + * BAR0 to support 512GB + * BAR1 to support 8M + * BAR2~5 to support 64M + */ + dw_pcie_writel_dbi(pci, resbar_base + 0x4, 0xfffff0); + dw_pcie_writel_dbi(pci, resbar_base + 0x8, 0x13c0); + dw_pcie_writel_dbi(pci, resbar_base + 0xc, 0xfffff0); + dw_pcie_writel_dbi(pci, resbar_base + 0x10, 0x3c0); + + for (int bar = 2; bar < PCI_STD_NUM_BARS; ++bar) + { + dw_pcie_writel_dbi(pci, resbar_base + 0x4 + bar * 0x8, 0xfffff0); + dw_pcie_writel_dbi(pci, resbar_base + 0x8 + bar * 0x8, 0x6c0); + } + + /* Set flags */ + rockchip_pcie_ep_set_bar_flag(rk_pcie, 0, PCIM_BAR_MEM_TYPE_32); + rockchip_pcie_ep_set_bar_flag(rk_pcie, 1, PCIM_BAR_MEM_TYPE_32); + rockchip_pcie_ep_set_bar_flag(rk_pcie, 2, PCIM_BAR_MEM_PREFETCH | PCIM_BAR_MEM_TYPE_64); + rockchip_pcie_ep_set_bar_flag(rk_pcie, 3, PCIM_BAR_MEM_PREFETCH | PCIM_BAR_MEM_TYPE_64); + } + + /* Device id and class id needed for request bar address */ + dw_pcie_writew_dbi(pci, PCIR_DEVICE, 0x356a); + dw_pcie_writew_dbi(pci, PCIR_SUBCLASS, 0x0580); + + /* Set shadow BAR0 */ + if (rk_pcie->soc_data->type == SOC_TYPE_RK1808) + { + dw_pcie_writel_dbi(pci, PCIE_SB_BAR0_MASK_REG, rk_pcie->mem_size - 1); + } +} + +static rt_err_t rockchip_pcie_add_endpoint(struct rockchip_pcie *rk_pcie) +{ + rt_err_t err; + struct dw_pcie *pci = &rk_pcie->pci; + struct rt_ofw_node *np = rk_pcie->pci.dev->ofw_node, *mem_np; + + if (!(mem_np = rt_ofw_parse_phandle(np, "memory-region", 0))) + { + LOG_E("%s: Missing '%s'", rt_ofw_node_full_name(np), "memory-region"); + return -RT_EINVAL; + } + + if ((err = rt_ofw_get_address(mem_np, 0, &rk_pcie->mem_start, &rk_pcie->mem_size))) + { + LOG_E("%s: Missing '%s'", rt_ofw_node_full_name(mem_np), "reg"); + return -RT_EINVAL; + } + + pci->atu_base = pci->dbi_base + DEFAULT_DBI_ATU_OFFSET; + pci->user_speed = PCIE_DIRECT_SPEED_CHANGE; + pci->endpoint.ops = &rockchip_pcie_ep_ops; + + rockchip_pcie_ep_setup_top(rk_pcie); + + if ((err = dw_pcie_ep_init(&pci->endpoint))) + { + LOG_E("Init EP error = %s", rt_strerror(err)); + return err; + } + + rockchip_pcie_ep_setup_bottom(rk_pcie); + + if ((err = rockchip_pcie_ep_atu_init(rk_pcie))) + { + LOG_E("Init EP ATU error = %s", rt_strerror(err)); + return err; + } + + if ((err = rockchip_pcie_establish_link_raw(rk_pcie))) + { + LOG_E("Establish pcie link error = %s", rt_strerror(err)); + return err; + } + + if (!rockchip_pcie_udma_enabled(rk_pcie)) + { + goto _end; + } + + /* Init uDMA here */ + +_end: + return RT_EOK; +} + +#ifdef RT_USING_PM +static int rockchip_dw_pcie_pm_suspend(const struct rt_device *device, rt_uint8_t mode) +{ + rt_err_t err; + rt_uint32_t status; + struct rockchip_pcie *rk_pcie = device->user_data; + struct dw_pcie *pci = &rk_pcie->pci; + + /* + * This is as per PCI Express Base r5.0 r1.0 May 22-2019, + * 5.2 Link State Power Management (Page #440). + * + * L2/L3 Ready entry negotiations happen while in the L0 state. + * L2/L3 Ready are entered only after the negotiation completes. + * + * The following example sequence illustrates the multi-step Link state + * transition process leading up to entering a system sleep state: + * 1. System software directs all Functions of + * a Downstream component to D3Hot. + * 2. The Downstream component then initiates the transition of the + * Link to L1 as required. + * 3. System software then causes the Root Complex to broadcast the + * PME_TURN_OFF Message in preparation for removing the main power source. + * 4. This Message causes the subject Link to transition back to L0 + * in order to send it and to enable the Downstream component to + * respond with PME_TO_Ack. + * 5. After sending the PME_TO_Ack, the Downstream component initiates the + * L2/L3 Ready transition protocol. + */ + + /* 1. All sub-devices are in D3hot by PCIe stack */ + dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); + + rockchip_pcie_link_status_clear(rk_pcie); + + /* + * Wlan devices will be shutdown from function driver now, so doing L2 here + * must fail. Skip L2 routine. + */ + if (rk_pcie->skip_scan_in_resume) + { + /* Check WiFi power state here. If down, goto the label "_no_l2" */ + } + + /* 2. Broadcast PME_Turn_Off Message */ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_MSG_GEN, PME_TURN_OFF); + err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_MSG_GEN, + status, !(status & RT_BIT(4)), 20, RK_PCIE_L2_TMOUT_US); + if (err) + { + LOG_E("Failed to send PME_TURN_OFF"); + goto _no_l2; + } + + /* 3. Wait for PME_TO_Ack */ + err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_INTR_STATUS_MSG_RX, + status, status & RT_BIT(9), 20, RK_PCIE_L2_TMOUT_US); + if (err) + { + LOG_E("Failed to receive PME_TO_ACK"); + goto _no_l2; + } + + /* 4. Clear PME_TO_Ack and Wait for ready to enter L23 message */ + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MSG_RX, PME_TO_ACK); + err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_POWER, + status, status & READY_ENTER_L23, 20, RK_PCIE_L2_TMOUT_US); + if (err) + { + LOG_E("Failed to ready to enter L23"); + goto _no_l2; + } + + /* 5. Check we are in L2 */ + err = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS, + status, ((status & S_MAX) == S_L2_IDLE), 20, RK_PCIE_L2_TMOUT_US); + if (err) + { + LOG_E("Link isn't in L2 idle"); + } + +_no_l2: + rockchip_pcie_disable_ltssm(rk_pcie); + + /* make sure assert phy success */ + rt_hw_us_delay(250); + + rt_phye_power_off(rk_pcie->phy); + rt_phye_exit(rk_pcie->phy); + + rk_pcie->intx = rockchip_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY); + + rt_clk_array_disable_unprepare(rk_pcie->clk_arr); + + rk_pcie->in_suspend = RT_TRUE; + + rt_pin_write(rk_pcie->rst_pin, !rk_pcie->rst_active_val); + + return rockchip_pcie_disable_power(rk_pcie); +} + +static void rockchip_dw_pcie_pm_resume(const struct rt_device *device, rt_uint8_t mode) +{ + rt_err_t err; + rt_bool_t std_rc; + struct rockchip_pcie *rk_pcie = device->user_data; + struct dw_pcie *pci = &rk_pcie->pci; + + std_rc = rk_pcie->soc_data->mode == DW_PCIE_RC_TYPE; + + rt_reset_control_assert(rk_pcie->rstc); + rt_hw_us_delay(10); + rt_reset_control_deassert(rk_pcie->rstc); + + if ((err = rockchip_pcie_enable_power(rk_pcie))) + { + LOG_E("Enable PCIe power error = %s", rt_strerror(err)); + return; + } + + if ((err = rt_clk_array_prepare_enable(rk_pcie->clk_arr))) + { + LOG_E("Prepare enable PCIe clks error = %s", rt_strerror(err)); + return; + } + + if ((err = rt_phye_set_mode(rk_pcie->phy, rk_pcie->phy_mode, rk_pcie->phy_submode))) + { + LOG_E("Set PHY to mode %s error = %s", + (rk_pcie->phy_submode == RT_PHYE_MODE_PCIE_RC) ? "RC" : "EP", + rt_strerror(err)); + return; + } + + if ((err = rt_phye_init(rk_pcie->phy))) + { + LOG_E("Init PHY error = %s", rt_strerror(err)); + return; + } + + rt_phye_power_on(rk_pcie->phy); + + dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); + + if (rk_pcie->soc_data->type == SOC_TYPE_RK1808) + { + /* Release link reset grant */ + if (rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_TRUE)) + { + return; + } + } + else + { + rockchip_pcie_fast_link_setup(rk_pcie); + } + + /* Set PCIe mode */ + rockchip_pcie_set_mode(rk_pcie); + + if (std_rc) + { + dw_pcie_setup_rc(&pci->port); + } + + rockchip_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + rk_pcie->intx | 0xffff0000); + + if ((err = rockchip_pcie_establish_link_raw(rk_pcie))) + { + LOG_E("Establish PCIe link error = %s", rt_strerror(err)); + goto _err; + } + + if (std_rc) + { + goto _std_rc_done; + } + + if ((err = rockchip_pcie_ep_atu_init(rk_pcie))) + { + LOG_E("Init EP device error = %s", rt_strerror(err)); + goto _err; + } + + rockchip_pcie_ep_setup_top(rk_pcie); + dw_pcie_setup(pci); + rockchip_pcie_ep_setup_bottom(rk_pcie); + + rk_pcie->in_suspend = RT_FALSE; + +_std_rc_done: + dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); + /* hold link reset grant after link-up */ + if (rk_pcie->soc_data->type == SOC_TYPE_RK1808) + { + if ((err = rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_FALSE))) + { + goto _err; + } + } + + if (pci->port.msi_irq > 0) + { + dw_pcie_msi_init(&pci->port); + } + + return; + +_err: + rockchip_pcie_disable_power(rk_pcie); +} + +static const struct rt_device_pm_ops rockchip_dw_pcie_pm_ops = +{ + .suspend = rockchip_dw_pcie_pm_suspend, + .resume = rockchip_dw_pcie_pm_resume, +}; +#endif /* RT_USING_PM */ + +static rt_err_t rockchip_pcie_phy_init(struct rockchip_pcie *rk_pcie) +{ + rt_err_t err; + struct rt_device *dev = rk_pcie->pci.dev; + + rk_pcie->phy = rt_phye_get_by_name(dev, "pcie-phy"); + if (rt_is_err(rk_pcie->phy)) + { + LOG_E("Missing PHY"); + return rt_ptr_err(rk_pcie->phy); + } + + switch (rk_pcie->soc_data->mode) + { + case DW_PCIE_RC_TYPE: + rk_pcie->phy_mode = RT_PHYE_MODE_PCIE; + rk_pcie->phy_submode = RT_PHYE_MODE_PCIE_RC; + break; + + case DW_PCIE_EP_TYPE: + rk_pcie->phy_mode = RT_PHYE_MODE_PCIE; + rk_pcie->phy_submode = RT_PHYE_MODE_PCIE_EP; + break; + + default: + break; + } + + if ((err = rt_phye_set_mode(rk_pcie->phy, rk_pcie->phy_mode, rk_pcie->phy_submode))) + { + LOG_E("Fail to set PHY to mode %s", + (rk_pcie->phy_submode == RT_PHYE_MODE_PCIE_RC) ? "RC" : "EP"); + + rk_pcie->phy = RT_NULL; + return err; + } + + if (rk_pcie->bifurcation) + { + rt_phye_set_mode(rk_pcie->phy, rk_pcie->phy_mode, RT_PHYE_MODE_PCIE_BIFURCATION); + } + + if ((err = rt_phye_init(rk_pcie->phy))) + { + LOG_E("Init PHY fail"); + + rk_pcie->phy = RT_NULL; + return err; + } + + rt_phye_power_on(rk_pcie->phy); + + return RT_EOK; +} + +static rt_err_t rockchip_pcie_fixup_rk1808(struct rockchip_pcie *rk_pcie) +{ + rt_err_t err; + struct rt_ofw_node *np = rk_pcie->pci.dev->ofw_node; + + rk_pcie->usb_pcie_grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,usbpciegrf"); + if (!rk_pcie->usb_pcie_grf) + { + LOG_E("Failed to find %s regmap", "usb_pcie_grf"); + return -RT_EIO; + } + + rk_pcie->pmu_grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,pmugrf"); + if (!rk_pcie->pmu_grf) + { + LOG_E("Failed to find %s regmap", "pmugrf"); + return -RT_EIO; + } + + /* Workaround for pcie, switch to PCIe_PRSTNm0 */ + if ((err = rt_syscon_write(rk_pcie->pmu_grf, 0x100, 0x01000100))) + { + return err; + } + + if ((err = rt_syscon_write(rk_pcie->pmu_grf, 0x0, 0x0c000000))) + { + return err; + } + + /* Release link reset grant */ + return rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_TRUE); +} + +static void rockchip_pcie_free(struct rockchip_pcie *rk_pcie) +{ + if (rk_pcie->pci.dbi_base) + { + rt_iounmap(rk_pcie->pci.dbi_base); + } + + if (rk_pcie->apb_base) + { + rt_iounmap(rk_pcie->apb_base); + } + + if (!rt_is_err_or_null(rk_pcie->clk_arr)) + { + rt_clk_array_disable_unprepare(rk_pcie->clk_arr); + rt_clk_array_put(rk_pcie->clk_arr); + } + + if (!rt_is_err_or_null(rk_pcie->rstc)) + { + rt_reset_control_assert(rk_pcie->rstc); + rt_reset_control_put(rk_pcie->rstc); + } + + if (!rt_is_err_or_null(rk_pcie->phy)) + { + rt_phye_power_off(rk_pcie->phy); + rt_phye_exit(rk_pcie->phy); + rt_phye_put(rk_pcie->phy); + } + + if (!rt_is_err_or_null(rk_pcie->vpcie3v3)) + { + rt_regulator_disable(rk_pcie->vpcie3v3); + } + + rt_free(rk_pcie); +} + +static void rockchip_pcie_free_irq(struct rockchip_pcie *rk_pcie) +{ + if (rk_pcie->intx_np) + { + rt_ofw_data(rk_pcie->intx_np) = RT_NULL; + + rt_pic_cancel_irq(&rk_pcie->intx_pic); + + rt_hw_interrupt_mask(rk_pcie->intx_irq); + rt_pic_detach_irq(rk_pcie->intx_irq, rk_pcie); + } + + rt_hw_interrupt_mask(rk_pcie->pci.port.sys_irq); + rt_pic_detach_irq(rk_pcie->pci.port.sys_irq, rk_pcie); +} + +static rt_err_t rockchip_pcie_dw_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + rt_uint32_t val; + rt_uint8_t pmode; + struct dw_pcie *pci; + struct dw_pcie_port *port; + struct rt_device *dev = &pdev->parent; + struct rt_ofw_node *np = dev->ofw_node, *intx_np; + struct rockchip_pcie *rk_pcie = rt_calloc(1, sizeof(*rk_pcie)); + + if (!rk_pcie) + { + return -RT_EINVAL; + } + + rk_pcie->soc_data = pdev->id->data; + rk_pcie->intx_irq = -RT_EEMPTY; + + pci = &rk_pcie->pci; + pci->dev = dev; + pci->ops = &dw_pcie_ops; + pci->priv = rk_pcie; + + port = &pci->port; + port->irq_count = rk_pcie->soc_data->msi_vector_num; + + rk_pcie->bifurcation = rt_dm_dev_prop_read_bool(dev, "rockchip,bifurcation"); + + pci->dbi_base = rt_dm_dev_iomap_by_name(dev, "pcie-dbi"); + if (!pci->dbi_base) + { + err = -RT_EIO; + goto _fail; + } + pci->dbi_base2 = pci->dbi_base + PCIE_TYPE0_HDR_DBI2_OFFSET; + + rk_pcie->apb_base = rt_dm_dev_iomap_by_name(dev, "pcie-apb"); + if (!rk_pcie->apb_base) + { + err = -RT_EIO; + goto _fail; + } + + rk_pcie->rst_pin = rt_pin_get_named_pin(dev, "reset", 0, + RT_NULL, &rk_pcie->rst_active_val); + if (rk_pcie->rst_pin < 0 && rk_pcie->rst_pin != PIN_NONE) + { + err = (rt_err_t)rk_pcie->rst_pin; + goto _fail; + } + + rk_pcie->prsnt_pin = rt_pin_get_named_pin(dev, "prsnt", 0, + &pmode, &rk_pcie->prsnt_active_val); + if (rk_pcie->prsnt_pin >= 0) + { + rt_pin_mode(rk_pcie->prsnt_pin, pmode); + + if (rt_pin_read(rk_pcie->prsnt_pin) != rk_pcie->prsnt_active_val) + { + /* No device */ + err = -RT_EINVAL; + goto _fail; + } + } + else if (rk_pcie->prsnt_pin != PIN_NONE) + { + LOG_I("Invalid prsnt-gpios"); + } + + rt_pin_write(rk_pcie->rst_pin, !rk_pcie->rst_active_val); + rt_pin_mode(rk_pcie->rst_pin, PIN_MODE_OUTPUT); + + if (rt_dm_dev_prop_read_u32(dev, "rockchip,perst-inactive-ms", + &rk_pcie->perst_inactive_ms)) + { + rk_pcie->perst_inactive_ms = 200; + } + + rk_pcie->supports_clkreq = rt_dm_dev_prop_read_bool(dev, "supports-clkreq"); + + rk_pcie->vpcie3v3 = rt_regulator_get(dev, "vpcie3v3"); + + if (rt_is_err(rk_pcie->vpcie3v3)) + { + err = rt_ptr_err(rk_pcie->vpcie3v3); + goto _fail; + } + + if ((err = rockchip_pcie_enable_power(rk_pcie))) + { + goto _fail; + } + + if ((err = rockchip_pcie_phy_init(rk_pcie))) + { + goto _fail; + } + + rk_pcie->rstc = rt_reset_control_get_array(dev); + + if (rt_is_err(rk_pcie->rstc)) + { + err = rt_ptr_err(rk_pcie->rstc); + goto _fail; + } + rt_reset_control_deassert(rk_pcie->rstc); + + rk_pcie->clk_arr = rt_clk_get_array(dev); + + if (rt_is_err(rk_pcie->clk_arr)) + { + err = rt_ptr_err(rk_pcie->clk_arr); + goto _fail; + } + + if ((err = rt_clk_array_prepare_enable(rk_pcie->clk_arr))) + { + goto _fail; + } + + dw_pcie_dbi_ro_writable_enable(pci, RT_TRUE); + + if (rk_pcie->soc_data->type == SOC_TYPE_RK1808) + { + if ((err = rockchip_pcie_fixup_rk1808(rk_pcie))) + { + goto _fail; + } + } + else + { + rockchip_pcie_fast_link_setup(rk_pcie); + } + + rockchip_pcie_set_mode(rk_pcie); + + /* Force into loopback master mode */ + if (rt_dm_dev_prop_read_bool(dev, "rockchip,lpbk-master")) + { + val = dw_pcie_readl_dbi(pci, PCIE_PORT_LINK_CONTROL); + val |= PORT_LINK_LPBK_ENABLE; + dw_pcie_writel_dbi(pci, PCIE_PORT_LINK_CONTROL, val); + rk_pcie->is_signal_test = RT_TRUE; + } + + /* + * Force into compliance mode + * comp_prst is a two dimensional array of which the first element + * stands for speed mode, and the second one is preset value encoding: + * [0] 0->SMA tool control the signal switch, + * 1/2/3 is for manual Gen setting + * [1] transmitter setting for manual Gen setting, + * valid only if [0] isn't zero. + */ + if (rt_dm_dev_prop_read_u32_array_index(dev, "rockchip,compliance-mode", + 0, 2, rk_pcie->comp_prst) > 0) + { + if (!rk_pcie->comp_prst[0]) + { + LOG_I("Auto compliance mode for SMA tool"); + } + else + { + LOG_I("Compliance mode for soldered board Gen%d, P%d", + rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]); + + val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); + val |= RT_BIT(4) | rk_pcie->comp_prst[0] | (rk_pcie->comp_prst[1] << 12); + dw_pcie_writel_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS, val); + } + rk_pcie->is_signal_test = RT_TRUE; + } + + /* Skip waiting for training to pass in system PM routine */ + if (rt_dm_dev_prop_read_bool(dev, "rockchip,skip-scan-in-resume")) + { + rk_pcie->skip_scan_in_resume = RT_TRUE; + } + + port->sys_irq = rt_dm_dev_get_irq_by_name(dev, "sys"); + + if (port->sys_irq < 0) + { + err = port->sys_irq; + goto _fail; + } + + rk_pcie->intx_irq = rt_dm_dev_get_irq_by_name(dev, "legacy"); + + if (rk_pcie->intx_irq >= 0) + { + /* Legacy (INTx) init */ + if (!(intx_np = rt_ofw_get_child_by_tag(np, "legacy-interrupt-controller"))) + { + LOG_E("INTx ofw node not found"); + + err = -RT_EIO; + goto _fail; + } + + rk_pcie->intx_np = intx_np; + rk_pcie->intx_pic.priv_data = rk_pcie; + rk_pcie->intx_pic.ops = &rockchip_intx_ops; + rt_pic_linear_irq(&rk_pcie->intx_pic, RT_PCI_INTX_PIN_MAX); + rt_pic_user_extends(&rk_pcie->intx_pic); + rt_ofw_data(intx_np) = &rk_pcie->intx_pic; + rt_ofw_node_put(intx_np); + + rt_hw_interrupt_install(rk_pcie->intx_irq, rockchip_pcie_legacy_isr, rk_pcie, "rk-pcie-legacy"); + rt_hw_interrupt_umask(rk_pcie->intx_irq); + } + else + { + LOG_D("Missing legacy IRQ"); + } + + rt_hw_interrupt_install(port->sys_irq, rockchip_pcie_sys_isr, rk_pcie, "rk-pcie-sys"); + rt_hw_interrupt_umask(port->sys_irq); + + rt_work_init(&rk_pcie->hot_rst_work, rockchip_pcie_hot_rst_work, rk_pcie); + + switch (rk_pcie->soc_data->mode) + { + case DW_PCIE_RC_TYPE: + err = rockchip_pcie_add_port(rk_pcie); + break; + + case DW_PCIE_EP_TYPE: + err = rockchip_pcie_add_endpoint(rk_pcie); + break; + + default: + /* It's impossible */ + RT_ASSERT(0); + break; + } + + if (rk_pcie->is_signal_test) + { + goto _end; + } + + if (err) + { + goto _free_irq; + } + + if (rk_pcie->soc_data->type == SOC_TYPE_RK1808) + { + /* Hold link reset grant after link-up */ + if ((err = rockchip_pcie_reset_grant_ctrl(rk_pcie, RT_FALSE))) + { + goto _free_irq; + } + } + +_end: + dw_pcie_dbi_ro_writable_enable(pci, RT_FALSE); + +#ifdef RT_USING_PM + rt_pm_device_register(dev, &rockchip_dw_pcie_pm_ops); +#endif + + dev->user_data = rk_pcie; + + return RT_EOK; + +_free_irq: + rockchip_pcie_free_irq(rk_pcie); + +_fail: + rockchip_pcie_free(rk_pcie); + + return err; +} + +static rt_err_t rockchip_pcie_dw_remove(struct rt_platform_device *pdev) +{ + struct rockchip_pcie *rk_pcie = pdev->parent.user_data; + +#ifdef RT_USING_PM + rt_pm_device_unregister(&pdev->parent); +#endif + + if (rk_pcie->pci.port.bridge) + { + rt_pci_host_bridge_remove(rk_pcie->pci.port.bridge); + } + dw_pcie_host_free(&rk_pcie->pci.port); + + rockchip_pcie_free_irq(rk_pcie); + + rockchip_pcie_free(rk_pcie); + + return RT_EOK; +} + +static const struct rockchip_pcie_soc_data rk_pcie_rc_soc_data = +{ + .mode = DW_PCIE_RC_TYPE, +}; + +static const struct rockchip_pcie_soc_data rk_pcie_ep_soc_data = +{ + .mode = DW_PCIE_EP_TYPE, +}; + +static const struct rockchip_pcie_soc_data rk1808_pcie_rc_soc_data = +{ + .type = SOC_TYPE_RK1808, + .mode = DW_PCIE_RC_TYPE, +}; + +static const struct rockchip_pcie_soc_data rk1808_pcie_ep_soc_data = +{ + .type = SOC_TYPE_RK1808, + .mode = DW_PCIE_EP_TYPE, +}; + +static const struct rockchip_pcie_soc_data rk3528_pcie_rc_soc_data = +{ + .mode = DW_PCIE_RC_TYPE, + .msi_vector_num = 8, +}; + +static const struct rt_ofw_node_id rockchip_pcie_dw_ofw_ids[] = +{ + { .compatible = "rockchip,rk1808-pcie", .data = &rk1808_pcie_rc_soc_data, }, + { .compatible = "rockchip,rk1808-pcie-ep", .data = &rk1808_pcie_ep_soc_data, }, + { .compatible = "rockchip,rk3528-pcie", .data = &rk3528_pcie_rc_soc_data, }, + { .compatible = "rockchip,rk3562-pcie", .data = &rk3528_pcie_rc_soc_data, }, + { .compatible = "rockchip,rk3568-pcie", .data = &rk_pcie_rc_soc_data, }, + { .compatible = "rockchip,rk3568-pcie-ep", .data = &rk_pcie_ep_soc_data, }, + { .compatible = "rockchip,rk3576-pcie", .data = &rk3528_pcie_rc_soc_data, }, + { .compatible = "rockchip,rk3588-pcie", .data = &rk_pcie_rc_soc_data, }, + { .compatible = "rockchip,rk3588-pcie-ep", .data = &rk_pcie_ep_soc_data, }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_pcie_dw_driver = +{ + .name = "dw-pcie-rockchip", + .ids = rockchip_pcie_dw_ofw_ids, + + .probe = rockchip_pcie_dw_probe, + .remove = rockchip_pcie_dw_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_pcie_dw_driver); diff --git a/bsp/rockchip/dm/phye/Kconfig b/bsp/rockchip/dm/phye/Kconfig new file mode 100755 index 00000000000..ca7dc5d84c2 --- /dev/null +++ b/bsp/rockchip/dm/phye/Kconfig @@ -0,0 +1,9 @@ +config RT_PHYE_ROCKCHIP_NANENG_COMBO + bool "NANENG COMBO PHY Driver" + depends on RT_MFD_SYSCON + default n + +config RT_PHYE_ROCKCHIP_SNPS_PCIE3 + bool "Snps PCIe3 PHY Driver" + depends on RT_MFD_SYSCON + default n diff --git a/bsp/rockchip/dm/phye/SConscript b/bsp/rockchip/dm/phye/SConscript new file mode 100755 index 00000000000..0a1836d4787 --- /dev/null +++ b/bsp/rockchip/dm/phye/SConscript @@ -0,0 +1,15 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_PHYE_ROCKCHIP_NANENG_COMBO']): + src += ['phye-naneng-combphy.c'] + +if GetDepend(['RT_PHYE_ROCKCHIP_SNPS_PCIE3']): + src += ['phye-snps-pcie3.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/phye/phye-naneng-combphy.c b/bsp/rockchip/dm/phye/phye-naneng-combphy.c new file mode 100755 index 00000000000..e5d0163ce45 --- /dev/null +++ b/bsp/rockchip/dm/phye/phye-naneng-combphy.c @@ -0,0 +1,1482 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-10-24 GuEe-GUI first version + */ + +#include +#include +#include + +#include + +#define DBG_TAG "phye.rockchip.naneng-combphy" +#define DBG_LVL DBG_INFO +#include + +#define BIT_WRITEABLE_SHIFT 16 +#define BIT_FLUSH 0xffffffff + +struct rockchip_combphy; + +struct combphy_reg +{ + rt_uint32_t offset; + rt_uint16_t bitend; + rt_uint16_t bitstart; + rt_uint16_t disable; + rt_uint16_t enable; +}; + +struct rockchip_combphy_grfcfg +{ + struct combphy_reg pcie_mode_set; + struct combphy_reg usb_mode_set; + struct combphy_reg sgmii_mode_set; + struct combphy_reg qsgmii_mode_set; + struct combphy_reg pipe_rxterm_set; + struct combphy_reg pipe_txelec_set; + struct combphy_reg pipe_txcomp_set; + struct combphy_reg pipe_clk_24m; + struct combphy_reg pipe_clk_25m; + struct combphy_reg pipe_clk_100m; + struct combphy_reg pipe_phymode_sel; + struct combphy_reg pipe_rate_sel; + struct combphy_reg pipe_rxterm_sel; + struct combphy_reg pipe_txelec_sel; + struct combphy_reg pipe_txcomp_sel; + struct combphy_reg pipe_clk_ext; + struct combphy_reg pipe_sel_usb; + struct combphy_reg pipe_sel_qsgmii; + struct combphy_reg pipe_phy_status; + struct combphy_reg con0_for_pcie; + struct combphy_reg con1_for_pcie; + struct combphy_reg con2_for_pcie; + struct combphy_reg con3_for_pcie; + struct combphy_reg con0_for_sata; + struct combphy_reg con1_for_sata; + struct combphy_reg con2_for_sata; + struct combphy_reg con3_for_sata; + struct combphy_reg pipe_con0_for_sata; + struct combphy_reg pipe_con1_for_sata; + struct combphy_reg pipe_sgmii_mac_sel; + struct combphy_reg pipe_xpcs_phy_ready; + struct combphy_reg u3otg0_port_en; + struct combphy_reg u3otg1_port_en; + struct combphy_reg pipe_phy_grf_reset; +}; + +struct rockchip_combphy_cfg +{ + rt_bool_t force_det_out; /* Tx detect Rx errata */ + const struct rockchip_combphy_grfcfg *grfcfg; + rt_err_t (*combphy_cfg)(struct rockchip_combphy *rk_cphy); +}; + +struct rockchip_combphy +{ + struct rt_phye parent; + + void *regs; + rt_uint8_t type; + + struct rt_syscon *pipe_grf; + struct rt_syscon *phy_grf; + struct rt_reset_control *apb_rstc; + struct rt_reset_control *phy_rstc; + struct rt_clk *refclk; + struct rt_clk_array *clk_arr; + const struct rockchip_combphy_cfg *cfg; + const struct rockchip_combphy_grfcfg *grfcfg; +}; + +#define raw_to_rockchip_combphy(raw) rt_container_of(raw, struct rockchip_combphy, parent) + +static void rockchip_combphy_updatel(struct rockchip_combphy *rk_cphy, + rt_uint32_t mask, rt_uint32_t val, int offset) +{ + rt_uint32_t tmp; + + tmp = HWREG32(rk_cphy->regs + offset); + tmp = (tmp & (~mask)) | val; + HWREG32(rk_cphy->regs + offset) = tmp; +} + +static rt_err_t rockchip_combphy_param_write(struct rt_syscon *regmap, + const struct combphy_reg *reg, rt_bool_t en) +{ + rt_uint32_t val, mask, tmp; + + tmp = en ? reg->enable : reg->disable; + mask = RT_GENMASK(reg->bitend, reg->bitstart); + val = (tmp << reg->bitstart) | (mask << BIT_WRITEABLE_SHIFT); + + return rt_syscon_write(regmap, reg->offset, val); +} + +static rt_uint32_t rockchip_combphy_is_ready(struct rockchip_combphy *rk_cphy) +{ + rt_uint32_t mask, val; + const struct rockchip_combphy_grfcfg *grfcfg = rk_cphy->cfg->grfcfg; + + mask = RT_GENMASK(grfcfg->pipe_phy_status.bitend, grfcfg->pipe_phy_status.bitstart); + + rt_syscon_read(rk_cphy->phy_grf, grfcfg->pipe_phy_status.offset, &val); + val = (val & mask) >> grfcfg->pipe_phy_status.bitstart; + + return val; +} + +/* Platfrom configure */ +static rt_err_t rk3528_combphy_cfg(struct rockchip_combphy *rk_cphy) +{ + rt_ubase_t rate; + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_grfcfg *grfcfg = rk_cphy->cfg->grfcfg; + + switch (rk_cphy->type) + { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x18); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_pcie, RT_TRUE); + break; + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x18); + + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(17, 17), 0x01 << 17, 0x200); + + /* Set slow slew rate control for PI */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(2, 0), 0x07, 0x204); + + /* Set CDR phase path with 2x gain */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 5), 0x01 << 5, 0x204); + + /* Set Rx squelch input filler bandwidth */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(2, 0), 0x06, 0x20c); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txcomp_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txelec_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->usb_mode_set, RT_TRUE); + break; + + default: + LOG_E("Incompatible PHY type"); + return -RT_EINVAL; + } + + rate = rt_clk_get_rate(rk_cphy->refclk); + + switch (rate) + { + case 24000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_24m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_USB3) + { + /* Set ssc_cnt[10:0]=00101111101 & 31.5KHz */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(10, 0), 0x17d, 0x100); + } + else if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* tx_trim[14]=1, Enable the counting clock of the rterm detect */ + rockchip_combphy_updatel(rk_cphy, 0, 1 << 14, 0x218); + } + break; + + case 100000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_100m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(12, 10), 0x2 << 10, 0x18); + + /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000, swing 650mv */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x570804f0, 0x18); + } + break; + + default: + LOG_E("Unsupported rate: %lu", rate); + return -RT_EINVAL; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,ext-refclk")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_ext, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 100000000) + { + /* + * PLL charge pump current adjust = 111 + * PLL LPF R1 adjust = 1001 + * PLL KVCO adjust = 000 (min) + * PLL KVCO fine tuning signals = 01 + */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(2, 0), RT_BIT(29) | (0x7 << 4 | 0x9 << 7), 0x108); + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(12, 10), 0x2 << 10, 0x18); + } + } + + if (rk_cphy->type == PHY_TYPE_PCIE) + { + if (rt_dm_dev_prop_read_bool(dev, "rockchip,enable-ssc")) + { + rockchip_combphy_updatel(rk_cphy, 0, RT_BIT(20), 0x100); + } + } + + return RT_EOK; +} + +static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = +{ + /* pipe-phy-grf */ + .pcie_mode_set = { 0x48000, 5, 0, 0x0000, 0x0011 }, + .usb_mode_set = { 0x48000, 5, 0, 0x0000, 0x0004 }, + .pipe_rxterm_set = { 0x48000, 12, 12, 0x0000, 0x0001 }, + .pipe_txelec_set = { 0x48004, 1, 1, 0x0000, 0x0001 }, + .pipe_txcomp_set = { 0x48004, 4, 4, 0x0000, 0x0001 }, + .pipe_clk_24m = { 0x48004, 14, 13, 0x0000, 0x0000 }, + .pipe_clk_100m = { 0x48004, 14, 13, 0x0000, 0x0002 }, + .pipe_rxterm_sel = { 0x48008, 8, 8, 0x0000, 0x0001 }, + .pipe_txelec_sel = { 0x48008, 12, 12, 0x0000, 0x0001 }, + .pipe_txcomp_sel = { 0x48008, 15, 15, 0x0000, 0x0001 }, + .pipe_clk_ext = { 0x4800c, 9, 8, 0x0002, 0x0001 }, + .pipe_phy_status = { 0x48034, 6, 6, 0x0001, 0x0000 }, + .con0_for_pcie = { 0x48000, 15, 0, 0x0000, 0x0110 }, + .con1_for_pcie = { 0x48004, 15, 0, 0x0000, 0x0000 }, + .con2_for_pcie = { 0x48008, 15, 0, 0x0000, 0x0101 }, + .con3_for_pcie = { 0x4800c, 15, 0, 0x0000, 0x0200 }, + /* pipe-grf */ + .u3otg0_port_en = { 0x40044, 15, 0, 0x0181, 0x1100 }, +}; + +static const struct rockchip_combphy_cfg rk3528_combphy_cfgs = +{ + .grfcfg = &rk3528_combphy_grfcfgs, + .combphy_cfg = rk3528_combphy_cfg, +}; + +static rt_err_t rk3562_combphy_cfg(struct rockchip_combphy *rk_cphy) +{ + rt_ubase_t rate; + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_grfcfg *grfcfg = rk_cphy->cfg->grfcfg; + + switch (rk_cphy->type) + { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x7c); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_pcie, RT_TRUE); + break; + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x7c); + + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(0, 0), 0x01, 0x38); + + /* Set PLL KVCO fine tuning signals */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x2 << 2, 0x80); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x4, 0x2c); + + /* Set PLL input clock divider 1/2 */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x14); + + /* Set PLL loop divider */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x32, 0x44); + + /* Set PLL KVCO to min and set PLL charge pump current to max */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0xf0, 0x28); + + /* Set Rx squelch input filler bandwidth */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x0e, 0x50); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_sel_usb, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txcomp_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txelec_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->usb_mode_set, RT_TRUE); + break; + + default: + LOG_E("Incompatible PHY type"); + return -RT_EINVAL; + } + + rate = rt_clk_get_rate(rk_cphy->refclk); + + switch (rate) + { + case 24000000: + if (rk_cphy->type == PHY_TYPE_USB3) + { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x38); + + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 0), 0x5f, 0x3c); + } + break; + + case 25000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_25m, RT_TRUE); + break; + + case 100000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_100m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x2 << 2, 0x80); + + /* Enable controlling random jitter, aka RMJ */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x4, 0x2c); + + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x14); + + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x32, 0x44); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0xf0, 0x28); + + /* CKDRV output swing adjust to 650mv */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 1), 0xb << 1, 0x34); + } + break; + + default: + LOG_E("Unsupported rate: %lu", rate); + return -RT_EINVAL; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,ext-refclk")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_ext, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 100000000) + { + rockchip_combphy_updatel(rk_cphy, 0, 0x3 << 4 | 0x1 << 7, 0x30); + + rockchip_combphy_updatel(rk_cphy, 0, 0x1, 0x34); + } + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,enable-ssc")) + { + rockchip_combphy_updatel(rk_cphy, 0, RT_BIT(4), 0x1c); + } + + return RT_EOK; +} + +static const struct rockchip_combphy_grfcfg rk3562_combphy_grfcfgs = +{ + /* pipe-phy-grf */ + .pcie_mode_set = { 0x0000, 5, 0, 0x0000, 0x0011 }, + .usb_mode_set = { 0x0000, 5, 0, 0x0000, 0x0004 }, + .pipe_rxterm_set = { 0x0000, 12, 12, 0x0000, 0x0001 }, + .pipe_txelec_set = { 0x0004, 1, 1, 0x0000, 0x0001 }, + .pipe_txcomp_set = { 0x0004, 4, 4, 0x0000, 0x0001 }, + .pipe_clk_25m = { 0x0004, 14, 13, 0x0000, 0x0001 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x0000, 0x0002 }, + .pipe_phymode_sel = { 0x0008, 1, 1, 0x0000, 0x0001 }, + .pipe_rate_sel = { 0x0008, 2, 2, 0x0000, 0x0001 }, + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x0000, 0x0001 }, + .pipe_txelec_sel = { 0x0008, 12, 12, 0x0000, 0x0001 }, + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x0000, 0x0001 }, + .pipe_clk_ext = { 0x000c, 9, 8, 0x0002, 0x0001 }, + .pipe_sel_usb = { 0x000c, 14, 13, 0x0000, 0x0001 }, + .pipe_phy_status = { 0x0034, 6, 6, 0x0001, 0x0000 }, + .con0_for_pcie = { 0x0000, 15, 0, 0x0000, 0x1000 }, + .con1_for_pcie = { 0x0004, 15, 0, 0x0000, 0x0000 }, + .con2_for_pcie = { 0x0008, 15, 0, 0x0000, 0x0101 }, + .con3_for_pcie = { 0x000c, 15, 0, 0x0000, 0x0200 }, + .pipe_phy_grf_reset = { 0x0014, 1, 0, 0x0003, 0x0001 }, + /* peri-grf */ + .u3otg0_port_en = { 0x0094, 15, 0, 0x0181, 0x1100 }, +}; + +static const struct rockchip_combphy_cfg rk3562_combphy_cfgs = +{ + .grfcfg = &rk3562_combphy_grfcfgs, + .combphy_cfg = rk3562_combphy_cfg, + .force_det_out = RT_TRUE, +}; + +static rt_err_t rk3568_combphy_cfg(struct rockchip_combphy *rk_cphy) +{ + rt_ubase_t rate; + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_grfcfg *grfcfg = rk_cphy->cfg->grfcfg; + + switch (rk_cphy->type) + { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x7c); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_pcie, RT_TRUE); + break; + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x7c); + + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(0, 0), 0x01, 0x38); + + /* Set PLL KVCO fine tuning signals */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x2 << 2, 128); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x4, 0x2c); + + /* Set PLL input clock divider 1/2 */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x14); + + /* Set PLL loop divider */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x32, 0x44); + + /* Set PLL KVCO to min and set PLL charge pump current to max */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0xf0, 0x28); + + /* Set Rx squelch input filler bandwidth */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x0e, 0x50); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_sel_usb, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txcomp_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txelec_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->usb_mode_set, RT_TRUE); + break; + + case PHY_TYPE_SATA: + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x41, 0x38); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x8f, 0x18); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_con0_for_sata, RT_TRUE); + break; + + case PHY_TYPE_SGMII: + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_xpcs_phy_ready, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_phymode_sel, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_sel_qsgmii, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->sgmii_mode_set, RT_TRUE); + break; + + case PHY_TYPE_QSGMII: + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_xpcs_phy_ready, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_phymode_sel, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_rate_sel, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_sel_qsgmii, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->qsgmii_mode_set, RT_TRUE); + break; + + default: + LOG_E("Incompatible PHY type"); + return -RT_EINVAL; + } + + rate = rt_clk_get_rate(rk_cphy->refclk); + + switch (rate) + { + case 24000000: + if (rk_cphy->type == PHY_TYPE_USB3 || rk_cphy->type == PHY_TYPE_SATA) + { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x38); + + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 0), 0x5f, 0x3c); + } + break; + + case 25000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_25m, RT_TRUE); + break; + + case 100000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_100m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x2 << 2, 0x80); + + /* Enable controlling random jitter, aka RMJ */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x4, 0x2c); + + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x14); + + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x32, 0x44); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0xf0, 0x28); + } + else if (rk_cphy->type == PHY_TYPE_SATA) + { + /* Downward spread spectrum +500ppm */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 4), 0x5 << 4, 0x7c); + } + break; + + default: + LOG_E("Unsupported rate: %lu", rate); + return -RT_EINVAL; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,ext-refclk")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_ext, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 100000000) + { + rockchip_combphy_updatel(rk_cphy, 0, 0x3 << 4 | 0x1 << 7, 0x30); + + rockchip_combphy_updatel(rk_cphy, 0, 0x1, 0x34); + } + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,enable-ssc")) + { + rockchip_combphy_updatel(rk_cphy, 0, RT_BIT(4), 0x1c); + } + + return RT_EOK; +} + +static const struct rockchip_combphy_grfcfg rk3568_combphy_grfcfgs = +{ + /* pipe-phy-grf */ + .pcie_mode_set = { 0x0000, 5, 0, 0x0000, 0x0011 }, + .usb_mode_set = { 0x0000, 5, 0, 0x0000, 0x0004 }, + .sgmii_mode_set = { 0x0000, 5, 0, 0x0000, 0x0001 }, + .qsgmii_mode_set = { 0x0000, 5, 0, 0x0000, 0x0021 }, + .pipe_rxterm_set = { 0x0000, 12, 12, 0x0000, 0x0001 }, + .pipe_txelec_set = { 0x0004, 1, 1, 0x0000, 0x0001 }, + .pipe_txcomp_set = { 0x0004, 4, 4, 0x0000, 0x0001 }, + .pipe_clk_25m = { 0x0004, 14, 13, 0x0000, 0x0001 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x0000, 0x0002 }, + .pipe_phymode_sel = { 0x0008, 1, 1, 0x0000, 0x0001 }, + .pipe_rate_sel = { 0x0008, 2, 2, 0x0000, 0x0001 }, + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x0000, 0x0001 }, + .pipe_txelec_sel = { 0x0008, 12, 12, 0x0000, 0x0001 }, + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x0000, 0x0001 }, + .pipe_clk_ext = { 0x000c, 9, 8, 0x0002, 0x0001 }, + .pipe_sel_usb = { 0x000c, 14, 13, 0x0000, 0x0001 }, + .pipe_sel_qsgmii = { 0x000c, 15, 13, 0x0000, 0x0007 }, + .pipe_phy_status = { 0x0034, 6, 6, 0x0001, 0x0000 }, + .con0_for_pcie = { 0x0000, 15, 0, 0x0000, 0x1000 }, + .con1_for_pcie = { 0x0004, 15, 0, 0x0000, 0x0000 }, + .con2_for_pcie = { 0x0008, 15, 0, 0x0000, 0x0101 }, + .con3_for_pcie = { 0x000c, 15, 0, 0x0000, 0x0200 }, + .con0_for_sata = { 0x0000, 15, 0, 0x0000, 0x0119 }, + .con1_for_sata = { 0x0004, 15, 0, 0x0000, 0x0040 }, + .con2_for_sata = { 0x0008, 15, 0, 0x0000, 0x80c3 }, + .con3_for_sata = { 0x000c, 15, 0, 0x0000, 0x4407 }, + /* pipe-grf */ + .pipe_con0_for_sata = { 0x0000, 15, 0, 0x0000, 0x2220 }, + .pipe_sgmii_mac_sel = { 0x0040, 1, 1, 0x0000, 0x0001 }, + .pipe_xpcs_phy_ready = { 0x0040, 2, 2, 0x0000, 0x0001 }, + .u3otg0_port_en = { 0x0104, 15, 0, 0x0181, 0x1100 }, + .u3otg1_port_en = { 0x0144, 15, 0, 0x0181, 0x1100 }, +}; + +static const struct rockchip_combphy_cfg rk3568_combphy_cfgs = +{ + .grfcfg = &rk3568_combphy_grfcfgs, + .combphy_cfg = rk3568_combphy_cfg, + .force_det_out = RT_TRUE, +}; + +static rt_err_t rk3576_combphy_cfg(struct rockchip_combphy *rk_cphy) +{ + rt_ubase_t rate; + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_grfcfg *grfcfg = rk_cphy->cfg->grfcfg; + + switch (rk_cphy->type) + { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), RT_BIT(4), 0x7c); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_pcie, RT_TRUE); + break; + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), RT_BIT(4), 0x7c); + + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(0, 0), RT_BIT(0), 0x38); + + /* Set PLL KVCO fine tuning signals */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), RT_BIT(3), 0x80); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ + HWREG32(rk_cphy->regs + (0xb << 2)) = 0x4; + + /* Set PLL input clock divider 1/2 */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), RT_BIT(6), 0x14); + + /* Set PLL loop divider */ + HWREG32(rk_cphy->regs + (0x11 << 2)) = 0x32; + + /* Set PLL KVCO to min and set PLL charge pump current to max */ + HWREG32(rk_cphy->regs + (0xa << 2)) = 0xf0; + + /* Set Rx squelch input filler bandwidth */ + HWREG32(rk_cphy->regs + (0x14 << 2)) = 0x0d; + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txcomp_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txelec_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->usb_mode_set, RT_TRUE); + break; + + case PHY_TYPE_SATA: + /* Enable adaptive CTLE for SATA Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(0, 0), RT_BIT(0), 0x38); + + /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ + HWREG32(rk_cphy->regs + (0x06 << 2)) = 0x8f; + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_con0_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_con1_for_sata, RT_TRUE); + break; + + default: + LOG_E("Incompatible PHY type"); + return -RT_EINVAL; + } + + rate = rt_clk_get_rate(rk_cphy->refclk); + + switch (rate) + { + case 24000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_24m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_USB3 || rk_cphy->type == PHY_TYPE_SATA) + { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), RT_BIT(6), 0xe << 2); + + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 0), 0x5f, 0xf << 2); + } + else if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x4 << 2, 0x20 << 2); + + /* Set up rx_trim */ + HWREG32(rk_cphy->regs + (0x1b << 2)) = 0x0; + + /* Set up su_trim: T0_1 */ + HWREG32(rk_cphy->regs + (0xa << 2)) = 0x90; + HWREG32(rk_cphy->regs + (0xb << 2)) = 0x02; + HWREG32(rk_cphy->regs + (0xd << 2)) = 0x57; + + HWREG32(rk_cphy->regs + (0xf << 2)) = 0x5f; + } + break; + + case 25000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_25m, RT_TRUE); + break; + + case 100000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_100m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* gate_tx_pck_sel length select work for L1SS */ + HWREG32(rk_cphy->regs + 0x74) = 0xc0; + + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x4 << 2, 0x20 << 2); + + /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ + HWREG32(rk_cphy->regs + (0x1b << 2)) = 0x4c; + + /* Set up su_trim: T3_P1 650mv */ + HWREG32(rk_cphy->regs + (0xa << 2)) = 0x90; + HWREG32(rk_cphy->regs + (0xb << 2)) = 0x43; + HWREG32(rk_cphy->regs + (0xc << 2)) = 0x88; + HWREG32(rk_cphy->regs + (0xd << 2)) = 0x56; + } + else if (rk_cphy->type == PHY_TYPE_SATA) + { + /* downward spread spectrum +500ppm */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 4), 0x50, 0x1f << 2); + + /* ssc ppm adjust to 3500ppm */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(3, 0), 0x7, 0x9 << 2); + } + break; + + default: + LOG_E("Unsupported rate: %lu", rate); + return -RT_EINVAL; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,ext-refclk")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_ext, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 100000000) + { + HWREG32(rk_cphy->regs + (0x20 << 2)) = 0x10; + + HWREG32(rk_cphy->regs + (0x1b << 2)) = 0x0c; + + /* Set up su_trim: T3_P1 650mv */ + HWREG32(rk_cphy->regs + (0xa << 2)) = 0x90; + HWREG32(rk_cphy->regs + (0xb << 2)) = 0x43; + HWREG32(rk_cphy->regs + (0xc << 2)) = 0x88; + HWREG32(rk_cphy->regs + (0xd << 2)) = 0x56; + } + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,enable-ssc")) + { + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 4), RT_BIT(4), 0x7 << 2); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 24000000) + { + /* Xin24M T0_1 650mV */ + HWREG32(rk_cphy->regs + (0x10 << 2)) = 0x00; + HWREG32(rk_cphy->regs + (0x11 << 2)) = 0x32; + HWREG32(rk_cphy->regs + (0x1b << 2)) = 0x00; + HWREG32(rk_cphy->regs + (0x0a << 2)) = 0x90; + HWREG32(rk_cphy->regs + (0x0b << 2)) = 0x02; + HWREG32(rk_cphy->regs + (0x0c << 2)) = 0x08; + HWREG32(rk_cphy->regs + (0x0d << 2)) = 0x57; + HWREG32(rk_cphy->regs + (0x0e << 2)) = 0x40; + HWREG32(rk_cphy->regs + (0x0f << 2)) = 0x5f; + HWREG32(rk_cphy->regs + (0x20 << 2)) = 0x10; + } + } + + return RT_EOK; +} + +static const struct rockchip_combphy_grfcfg rk3576_combphy_grfcfgs = +{ + /* pipe-phy-grf */ + .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x11 }, + .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x04 }, + .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x01 }, + .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x01 }, + .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x01 }, + .pipe_clk_24m = { 0x0004, 14, 13, 0x00, 0x00 }, + .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x01 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x02 }, + .pipe_phymode_sel = { 0x0008, 1, 1, 0x00, 0x01 }, + .pipe_rate_sel = { 0x0008, 2, 2, 0x00, 0x01 }, + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x01 }, + .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x01 }, + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x01 }, + .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x01 }, + .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x00 }, + .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, + .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, + .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, + .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, + .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 }, + .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 }, + .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 }, + .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 }, + .pipe_phy_grf_reset = { 0x0014, 1, 0, 0x3, 0x1 }, + /* php-grf */ + .pipe_con0_for_sata = { 0x001c, 2, 0, 0x00, 0x2 }, + .pipe_con1_for_sata = { 0x0020, 2, 0, 0x00, 0x2 }, + .u3otg1_port_en = { 0x0038, 15, 0, 0x0189, 0x1100 }, +}; + +static const struct rockchip_combphy_cfg rk3576_combphy_cfgs = +{ + .grfcfg = &rk3576_combphy_grfcfgs, + .combphy_cfg = rk3576_combphy_cfg, + .force_det_out = RT_TRUE, +}; + +static rt_err_t rk3588_combphy_cfg(struct rockchip_combphy *rk_cphy) +{ + rt_ubase_t rate; + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_grfcfg *grfcfg = rk_cphy->cfg->grfcfg; + + switch (rk_cphy->type) + { + case PHY_TYPE_PCIE: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x7c); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_pcie, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_pcie, RT_TRUE); + break; + + case PHY_TYPE_USB3: + /* Set SSC downward spread spectrum */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(5, 4), 0x1 << 4, 0x7c); + + /* Enable adaptive CTLE for USB3.0 Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(0, 0), 0x01, 0x38); + + /* Set PLL KVCO fine tuning signals */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x2 << 2, 0x80); + + /* Set PLL LPF R1 to su_trim[10:7]=1001 */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x4, 0x2c); + + /* Set PLL input clock divider 1/2 */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x14); + + /* Set PLL loop divider */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x32, 0x44); + + /* Set PLL KVCO to min and set PLL charge pump current to max */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0xf0, 0x28); + + /* Set Rx squelch input filler bandwidth */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x0d, 0x50); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txcomp_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_txelec_sel, RT_FALSE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->usb_mode_set, RT_TRUE); + break; + + case PHY_TYPE_SATA: + /* Enable adaptive CTLE for SATA Rx */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(0, 0), 0x1, 0x38); + + /* Set tx_rterm = 50 ohm and rx_rterm = 43.5 ohm */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x8f, 0x18); + + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con0_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con1_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con2_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->con3_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_con0_for_sata, RT_TRUE); + rockchip_combphy_param_write(rk_cphy->pipe_grf, &grfcfg->pipe_con1_for_sata, RT_TRUE); + break; + + case PHY_TYPE_SGMII: + case PHY_TYPE_QSGMII: + default: + LOG_E("Incompatible PHY type"); + return -RT_EINVAL; + } + + rate = rt_clk_get_rate(rk_cphy->refclk); + + switch (rate) + { + case 24000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_24m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_USB3 || rk_cphy->type == PHY_TYPE_SATA) + { + /* Set ssc_cnt[9:0]=0101111101 & 31.5KHz */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 6), 0x1 << 6, 0x38); + + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 0), 0x5f, 0x3c); + } + else if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x4 << 2, 0x80); + + /* Set up rx_trim */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x0, 0x6c); + + /* Set up su_trim: T0_1 */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x90, 0x28); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x02, 0x2c); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x57, 0x34); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x5f, 0x3c); + } + break; + case 25000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_25m, RT_TRUE); + break; + + case 100000000: + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_100m, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE) + { + /* gate_tx_pck_sel length select work for L1SS */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0xc0, 0x74); + + /* PLL KVCO tuning fine */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(4, 2), 0x4 << 2, 0x80); + + /* Set up rx_trim: PLL LPF C1 85pf R1 1.25kohm */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x4c, 0x6c); + + /* Set up su_trim: T3_P1 650mv */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x90, 0x28); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x43, 0x2c); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x88, 0x30); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x56, 0x34); + } + else if (rk_cphy->type == PHY_TYPE_SATA) + { + /* downward spread spectrum +500ppm */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(7, 4), 0x5 << 4, 0x7c); + + /* ssc ppm adjust to 3500ppm */ + rockchip_combphy_updatel(rk_cphy, RT_GENMASK(3, 0), 0x7, 0x24); + } + break; + + default: + LOG_E("Unsupported rate: %lu", rate); + return -RT_EINVAL; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,ext-refclk")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, &grfcfg->pipe_clk_ext, RT_TRUE); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 100000000) + { + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x10, 0x80); + + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x0c, 0x6c); + + /* Set up su_trim: T3_P1 650mv */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x90, 0x28); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x43, 0x2c); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x88, 0x30); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x56, 0x34); + } + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,enable-ssc")) + { + rockchip_combphy_updatel(rk_cphy, 0, RT_BIT(4), 0x1c); + + if (rk_cphy->type == PHY_TYPE_PCIE && rate == 24000000) + { + /* Xin24M T0_1 650mV */ + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x00, 0x40); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x32, 0x44); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x00, 0x6c); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x90, 0x28); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x02, 0x2c); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x08, 0x30); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x57, 0x34); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x40, 0x38); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x5f, 0x3c); + rockchip_combphy_updatel(rk_cphy, BIT_FLUSH, 0x10, 0x80); + } + } + + return RT_EOK; +} + +static const struct rockchip_combphy_grfcfg rk3588_combphy_grfcfgs = +{ + /* pipe-phy-grf */ + .pcie_mode_set = { 0x0000, 5, 0, 0x00, 0x0011 }, + .usb_mode_set = { 0x0000, 5, 0, 0x00, 0x0004 }, + .pipe_rxterm_set = { 0x0000, 12, 12, 0x00, 0x0001 }, + .pipe_txelec_set = { 0x0004, 1, 1, 0x00, 0x0001 }, + .pipe_txcomp_set = { 0x0004, 4, 4, 0x00, 0x0001 }, + .pipe_clk_24m = { 0x0004, 14, 13, 0x00, 0x0000 }, + .pipe_clk_25m = { 0x0004, 14, 13, 0x00, 0x0001 }, + .pipe_clk_100m = { 0x0004, 14, 13, 0x00, 0x0002 }, + .pipe_rxterm_sel = { 0x0008, 8, 8, 0x00, 0x0001 }, + .pipe_txelec_sel = { 0x0008, 12, 12, 0x00, 0x0001 }, + .pipe_txcomp_sel = { 0x0008, 15, 15, 0x00, 0x0001 }, + .pipe_clk_ext = { 0x000c, 9, 8, 0x02, 0x0001 }, + .pipe_phy_status = { 0x0034, 6, 6, 0x01, 0x0000 }, + .con0_for_pcie = { 0x0000, 15, 0, 0x00, 0x1000 }, + .con1_for_pcie = { 0x0004, 15, 0, 0x00, 0x0000 }, + .con2_for_pcie = { 0x0008, 15, 0, 0x00, 0x0101 }, + .con3_for_pcie = { 0x000c, 15, 0, 0x00, 0x0200 }, + .con0_for_sata = { 0x0000, 15, 0, 0x00, 0x0129 }, + .con1_for_sata = { 0x0004, 15, 0, 0x00, 0x0000 }, + .con2_for_sata = { 0x0008, 15, 0, 0x00, 0x80c1 }, + .con3_for_sata = { 0x000c, 15, 0, 0x00, 0x0407 }, + /* pipe-grf */ + .pipe_con0_for_sata = { 0x0000, 11, 5, 0x00, 0x0022 }, + .pipe_con1_for_sata = { 0x0004, 2, 0, 0x00, 0x0002 }, +}; + +static const struct rockchip_combphy_cfg rk3588_combphy_cfgs = +{ + .grfcfg = &rk3588_combphy_grfcfgs, + .combphy_cfg = rk3588_combphy_cfg, + .force_det_out = RT_TRUE, +}; + +static rt_err_t rockchip_combphy_pcie_init(struct rockchip_combphy *rk_cphy) +{ + rt_err_t err = RT_EOK; + + if (rk_cphy->cfg->combphy_cfg) + { + if ((err = rk_cphy->cfg->combphy_cfg(rk_cphy))) + { + LOG_E("Failed to init PHY for %s", "PCIe"); + + return err; + } + } + + if (rk_cphy->cfg->force_det_out) + { + rockchip_combphy_updatel(rk_cphy, 0, RT_BIT(5), 0x19 << 2); + } + + return err; +} + +static rt_err_t rockchip_combphy_usb3_init(struct rockchip_combphy *rk_cphy) +{ + rt_err_t err = RT_EOK; + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_cfg *phy_cfg = rk_cphy->cfg; + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,dis-u3otg0-port")) + { + err = rockchip_combphy_param_write(rk_cphy->pipe_grf, + &phy_cfg->grfcfg->u3otg0_port_en, RT_FALSE); + + return err; + } + else if (rt_dm_dev_prop_read_bool(dev, "rockchip,dis-u3otg1-port")) + { + err = rockchip_combphy_param_write(rk_cphy->pipe_grf, + &phy_cfg->grfcfg->u3otg1_port_en, RT_FALSE); + + if (rt_ofw_node_is_compatible(dev->ofw_node, "rockchip,rk3576-naneng-combphy")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, + &phy_cfg->grfcfg->usb_mode_set, RT_TRUE); + } + + return err; + } + + if (rk_cphy->cfg->combphy_cfg) + { + if ((err = rk_cphy->cfg->combphy_cfg(rk_cphy))) + { + LOG_E("Failed to init PHY for %s", "USB3"); + } + } + + return err; +} + +static rt_err_t rockchip_combphy_sata_init(struct rockchip_combphy *rk_cphy) +{ + rt_err_t err = RT_EOK; + + if (rk_cphy->cfg->combphy_cfg) + { + if ((err = rk_cphy->cfg->combphy_cfg(rk_cphy))) + { + LOG_E("Failed to init PHY for %s", "SATA"); + } + } + + return err; +} + +static rt_err_t rockchip_combphy_sgmii_init(struct rockchip_combphy *rk_cphy) +{ + rt_err_t err = RT_EOK; + + if (rk_cphy->cfg->combphy_cfg) + { + if ((err = rk_cphy->cfg->combphy_cfg(rk_cphy))) + { + LOG_E("Failed to init PHY for %s", "SGMII"); + } + } + + return err; +} + +static rt_err_t rockchip_combphy_qsgmii_init(struct rockchip_combphy *rk_cphy) +{ + rt_err_t err = RT_EOK; + + if (rk_cphy->cfg->combphy_cfg) + { + if ((err = rk_cphy->cfg->combphy_cfg(rk_cphy))) + { + LOG_E("Failed to init PHY for %s", "QSGMII"); + } + } + + return err; +} + +static rt_err_t rockchip_combphy_init(struct rt_phye *phy) +{ + rt_err_t err; + struct rockchip_combphy *rk_cphy = raw_to_rockchip_combphy(phy); + struct rt_device *dev = rk_cphy->parent.dev; + const struct rockchip_combphy_grfcfg *cfg = rk_cphy->cfg->grfcfg; + + if ((err = rt_clk_array_prepare_enable(rk_cphy->clk_arr))) + { + LOG_E("Failed to enable clks error = %s", rt_strerror(err)); + + return -RT_EIO; + } + + switch (rk_cphy->type) + { + case PHY_TYPE_PCIE: + err = rockchip_combphy_pcie_init(rk_cphy); + break; + case PHY_TYPE_USB3: + err = rockchip_combphy_usb3_init(rk_cphy); + break; + case PHY_TYPE_SATA: + err = rockchip_combphy_sata_init(rk_cphy); + break; + case PHY_TYPE_SGMII: + err = rockchip_combphy_sgmii_init(rk_cphy); + break; + case PHY_TYPE_QSGMII: + err = rockchip_combphy_qsgmii_init(rk_cphy); + break; + + default: + LOG_E("Incompatible PHY type"); + err = -RT_EINVAL; + break; + } + + if (err) + { + LOG_E("Failed to init PHY for type %d", rk_cphy->type); + + goto _out_clk; + } + + if ((err = rt_reset_control_deassert(rk_cphy->phy_rstc))) + { + goto _out_clk; + } + + if (rk_cphy->grfcfg->pipe_phy_grf_reset.enable) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, + &rk_cphy->grfcfg->pipe_phy_grf_reset, RT_FALSE); + } + + if (rk_cphy->type == PHY_TYPE_USB3 && + !rt_dm_dev_prop_read_bool(dev, "rockchip,dis-u3otg0-port") && + !rt_dm_dev_prop_read_bool(dev, "rockchip,dis-u3otg1-port")) + { + rt_uint32_t val; + rt_int32_t timeout_us = 1000; + + for (; timeout_us > 0; timeout_us -= 10) + { + val = rockchip_combphy_is_ready(rk_cphy); + + if (val == cfg->pipe_phy_status.enable) + { + break; + } + + rt_hw_us_delay(10); + rt_hw_cpu_relax(); + } + + if (timeout_us <= 0) + { + LOG_W("Wait PHY status ready timeout"); + } + } + + return RT_EOK; + +_out_clk: + rt_clk_array_disable_unprepare(rk_cphy->clk_arr); + + return -RT_EIO; +} + +static rt_err_t rockchip_combphy_exit(struct rt_phye *phy) +{ + struct rockchip_combphy *rk_cphy = raw_to_rockchip_combphy(phy); + + if (rk_cphy->grfcfg->pipe_phy_grf_reset.enable) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, + &rk_cphy->grfcfg->pipe_phy_grf_reset, RT_TRUE); + } + + rt_clk_array_disable_unprepare(rk_cphy->clk_arr); + rt_reset_control_assert(rk_cphy->phy_rstc); + + return RT_EOK; +} + +static rt_err_t rockchip_combphy_ofw_parse(struct rt_phye *phy, + struct rt_ofw_cell_args *phy_args) +{ + struct rockchip_combphy *rk_cphy = raw_to_rockchip_combphy(phy); + + if (phy_args->args_count != 1) + { + LOG_E("Invalid number of arguments"); + + return -RT_EINVAL; + } + + if (rk_cphy->type != PHY_NONE && rk_cphy->type != phy_args->args[0]) + { + LOG_W("PHY select type %d from type %d", + phy_args->args[0], rk_cphy->type); + } + + rk_cphy->type = phy_args->args[0]; + + return RT_EOK; +} + +static const struct rt_phye_ops rochchip_combphy_ops = +{ + .init = rockchip_combphy_init, + .exit = rockchip_combphy_exit, + .ofw_parse = rockchip_combphy_ofw_parse, +}; + +static void rockchip_combphy_free(struct rockchip_combphy *rk_cphy) +{ + if (rk_cphy->regs) + { + rt_iounmap(rk_cphy->regs); + } + + if (!rt_is_err_or_null(rk_cphy->clk_arr)) + { + rt_clk_array_put(rk_cphy->clk_arr); + } + + if (!rt_is_err_or_null(rk_cphy->apb_rstc)) + { + rt_reset_control_put(rk_cphy->apb_rstc); + } + + if (!rt_is_err_or_null(rk_cphy->phy_rstc)) + { + rt_reset_control_put(rk_cphy->phy_rstc); + } + + rt_free(rk_cphy); +} + +static rt_err_t rockchip_combphy_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + rt_int32_t mac_id; + rt_uint32_t values[4]; + struct rt_phye *phy; + struct rt_device *dev = &pdev->parent; + struct rockchip_combphy *rk_cphy = rt_calloc(1, sizeof(*rk_cphy)); + const struct rockchip_combphy_cfg *phy_cfg; + + if (!rk_cphy) + { + return -RT_ENOMEM; + } + + phy_cfg = pdev->id->data; + rk_cphy->type = PHY_NONE; + rk_cphy->cfg = phy_cfg; + rk_cphy->grfcfg = phy_cfg->grfcfg; + + rk_cphy->regs = rt_dm_dev_iomap(dev, 0); + if (!rk_cphy->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_cphy->clk_arr = rt_clk_get_array(dev); + if (rt_is_err(rk_cphy->clk_arr)) + { + err = rt_ptr_err(rk_cphy->clk_arr); + goto _fail; + } + + for (int i = rk_cphy->clk_arr->count - 1; i >= 0; --i) + { + if (!rt_strncmp(rk_cphy->clk_arr->clks[i]->con_id, "refclk", 6)) + { + rk_cphy->refclk = rk_cphy->clk_arr->clks[i]; + } + } + + if (!rk_cphy->refclk) + { + err = -RT_EINVAL; + goto _fail; + } + + rk_cphy->pipe_grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pipe-grf"); + if (!rk_cphy->pipe_grf) + { + err = -RT_EIO; + goto _fail; + } + + rk_cphy->phy_grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pipe-phy-grf"); + if (!rk_cphy->phy_grf) + { + err = -RT_EIO; + goto _fail; + } + + if (rt_dm_dev_prop_read_bool(dev, "rockchip,dis-u3otg0-port")) + { + rockchip_combphy_param_write(rk_cphy->pipe_grf, + &phy_cfg->grfcfg->u3otg0_port_en, RT_FALSE); + } + else if (rt_dm_dev_prop_read_bool(dev, "rockchip,dis-u3otg1-port")) + { + rockchip_combphy_param_write(rk_cphy->pipe_grf, + &phy_cfg->grfcfg->u3otg1_port_en, RT_FALSE); + + if (rt_ofw_node_is_compatible(dev->ofw_node, "rockchip,rk3576-naneng-combphy")) + { + rockchip_combphy_param_write(rk_cphy->phy_grf, + &phy_cfg->grfcfg->usb_mode_set, RT_TRUE); + } + } + + if (!rt_dm_dev_prop_read_s32(dev, "rockchip,sgmii-mac-sel", &mac_id) && mac_id > 0) + { + rockchip_combphy_param_write(rk_cphy->pipe_grf, + &phy_cfg->grfcfg->pipe_sgmii_mac_sel, RT_TRUE); + } + + if (rt_dm_dev_prop_read_u32_array_index(dev, "rockchip,pcie1ln-sel-bits", + 0, RT_ARRAY_SIZE(values), values) > 0) + { + rt_syscon_write(rk_cphy->pipe_grf, values[0], + (RT_GENMASK(values[2], values[1]) << 16) | (values[3] << values[1])); + } + + rk_cphy->apb_rstc = rt_reset_control_get_by_name(dev, "combphy-apb"); + if (rt_is_err(rk_cphy->apb_rstc)) + { + err = rt_ptr_err(rk_cphy->apb_rstc); + goto _fail; + } + + rk_cphy->phy_rstc = rt_reset_control_get_by_name(dev, "combphy"); + if (rt_is_err(rk_cphy->phy_rstc)) + { + err = rt_ptr_err(rk_cphy->phy_rstc); + goto _fail; + } + + err = rt_reset_control_assert(rk_cphy->phy_rstc); + if (err) + { + goto _fail; + } + + dev->user_data = rk_cphy; + + phy = &rk_cphy->parent; + phy->dev = dev; + phy->ops = &rochchip_combphy_ops; + + if ((err = rt_phye_register(phy))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rockchip_combphy_free(rk_cphy); + + return err; +} + +static rt_err_t rockchip_combphy_remove(struct rt_platform_device *pdev) +{ + struct rt_device *dev = &pdev->parent; + struct rockchip_combphy *rk_cphy = dev->user_data; + + rt_phye_unregister(&rk_cphy->parent); + + rockchip_combphy_free(rk_cphy); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_combphy_ofw_ids[] = +{ + { .compatible = "rockchip,rk3528-naneng-combphy", .data = &rk3528_combphy_cfgs }, + { .compatible = "rockchip,rk3562-naneng-combphy", .data = &rk3562_combphy_cfgs }, + { .compatible = "rockchip,rk3568-naneng-combphy", .data = &rk3568_combphy_cfgs }, + { .compatible = "rockchip,rk3576-naneng-combphy", .data = &rk3576_combphy_cfgs }, + { .compatible = "rockchip,rk3588-naneng-combphy", .data = &rk3588_combphy_cfgs }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_combphy_driver = +{ + .name = "phy-rockchip-naneng-combphy", + .ids = rockchip_combphy_ofw_ids, + + .probe = rockchip_combphy_probe, + .remove = rockchip_combphy_remove, +}; + +static int rockchip_combphy_drv_register(void) +{ + rt_platform_driver_register(&rockchip_combphy_driver); + + return 0; +} +INIT_PLATFORM_EXPORT(rockchip_combphy_drv_register); diff --git a/bsp/rockchip/dm/phye/phye-snps-pcie3.c b/bsp/rockchip/dm/phye/phye-snps-pcie3.c new file mode 100755 index 00000000000..f6d5313e15c --- /dev/null +++ b/bsp/rockchip/dm/phye/phye-snps-pcie3.c @@ -0,0 +1,432 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-10-24 GuEe-GUI first version + */ + +#include +#include +#include + +#include + +#define DBG_TAG "phye.rockchip.snps-pcie3" +#define DBG_LVL DBG_INFO +#include + +#define GRF_ENABLE_SHIFT 16 +#define GRF_ENABLE (0x7 << GRF_ENABLE_SHIFT) +#define GRF_ENABLE_OPS(v, m, reg) ((((v) ? (m) : 0) << (reg)) | ((m) << (GRF_ENABLE_SHIFT + (reg)))) + +struct rockchip_pcie3_phy_soc_data; + +struct rockchip_pcie3_phy +{ + struct rt_phye parent; + + void *regs; + /* mode: RC, EP */ + int mode; + /* pcie30_phymode: Aggregation, Bifurcation */ + int pcie30_phymode; + rt_bool_t is_bifurcation; + + struct rt_syscon *phy_grf; + struct rt_syscon *pipe_grf; + struct rt_reset_control *rstc; + struct rt_clk_array *clk_arr; + + const struct rockchip_pcie3_phy_soc_data *soc_data; +}; + +#define raw_to_rockchip_pcie3_phy(raw) rt_container_of(raw, struct rockchip_pcie3_phy, parent) + +struct rockchip_pcie3_phy_soc_data +{ + rt_err_t (*phy_init)(struct rockchip_pcie3_phy *); +}; + +static const rt_uint16_t phy_fw[] = +{ +#include "phye-snps-pcie3.fw" +}; + +/* Register for RK3568 */ +#define RK3568_GRF_PCIE30PHY_CON1 0x4 +#define RK3568_GRF_PCIE30PHY_CON4 0x10 +#define RK3568_GRF_PCIE30PHY_CON6 0x18 +#define RK3568_GRF_PCIE30PHY_CON9 0x24 +#define RK3568_GRF_PCIE30PHY_DA_OCM GRF_ENABLE_OPS(RT_TRUE, 1, 15) +#define RK3568_GRF_PCIE30PHY_STATUS0 0x80 +#define RK3568_GRF_PCIE30PHY_WR_EN (0xf << GRF_ENABLE_SHIFT) +#define RK3568_SRAM_ACCESS(v, m) GRF_ENABLE_OPS(v, m, 8) +#define RK3568_SRAM_BYPASS(v, m) GRF_ENABLE_OPS(v, m, 13) +#define RK3568_SRAM_LD(v, m) GRF_ENABLE_OPS(v, m, 14) +#define RK3568_SRAM_INIT_DONE(reg) (reg & RT_BIT(14)) +#define RK3568_BIFURCATION_LANE_0_1 RT_BIT(0) + +static rt_err_t rockchip_p3phy_rk3568_init(struct rockchip_pcie3_phy *rk_p3phy) +{ + rt_err_t err; + rt_uint32_t reg = 0, timeout_us; + + /* Deassert PCIe PMA output clamp mode */ + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON9, + RK3568_GRF_PCIE30PHY_DA_OCM); + + if (rk_p3phy->is_bifurcation) + { + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON6, + RK3568_GRF_PCIE30PHY_WR_EN | RK3568_BIFURCATION_LANE_0_1); + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON1, + RK3568_GRF_PCIE30PHY_DA_OCM); + } + else + { + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON6, + RK3568_GRF_PCIE30PHY_WR_EN & ~RK3568_BIFURCATION_LANE_0_1); + } + + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON4, + RK3568_SRAM_LD(RT_FALSE, 1)); + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON4, + RK3568_SRAM_BYPASS(RT_FALSE, 1)); + + rt_reset_control_deassert(rk_p3phy->rstc); + rt_hw_us_delay(5); + + timeout_us = 500; + while (timeout_us --> 0) + { + err = rt_syscon_read(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_STATUS0, ®); + + if (err || RK3568_SRAM_INIT_DONE(reg)) + { + break; + } + + rt_hw_us_delay(1); + rt_hw_cpu_relax(); + + err = -RT_ETIMEOUT; + } + + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON9, + RK3568_SRAM_ACCESS(RT_TRUE, 3)); + + for (int i = 0; i < RT_ARRAY_SIZE(phy_fw); ++i) + { + HWREG32(rk_p3phy->regs + (i << 2)) = phy_fw[i]; + } + + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON9, + RK3568_SRAM_ACCESS(RT_FALSE, 3)); + + rt_syscon_write(rk_p3phy->phy_grf, RK3568_GRF_PCIE30PHY_CON4, + RK3568_SRAM_LD(RT_TRUE, 1)); + + rt_hw_us_delay(10); + + return err; +} + +static const struct rockchip_pcie3_phy_soc_data rk3568_data = +{ + .phy_init = rockchip_p3phy_rk3568_init, +}; + +/* Register for RK3588 */ +#define PHP_GRF_PCIESEL_CON 0x100 +#define RK3588_PCIE3PHY_GRF_CMN_CON0 0x0 +#define RK3588_PCIE3PHY_GRF_DA_OCM GRF_ENABLE_OPS(RT_TRUE, 1, 8) +#define RK3588_PCIE3PHY_GRF_MODE_SHIFT 0x7 +#define RK3588_PCIE3PHY_GRF_PHY0_STATUS1 0x904 +#define RK3588_PCIE3PHY_GRF_PHY1_STATUS1 0xa04 +#define RK3588_SRAM_INIT_DONE(reg) (reg & RT_BIT(0)) + +#define RK3588_BIFURCATION_LANE_0_1 RT_BIT(0) +#define RK3588_BIFURCATION_LANE_2_3 RT_BIT(1) +#define RK3588_LANE_AGGREGATION RT_BIT(2) + +static rt_err_t rockchip_p3phy_rk3588_init(struct rockchip_pcie3_phy *rk_p3phy) +{ + rt_uint32_t reg = 0, timeout_us; + rt_err_t err, err_res = RT_EOK; + + /* Deassert PCIe PMA output clamp mode */ + rt_syscon_write(rk_p3phy->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, + RK3588_PCIE3PHY_GRF_DA_OCM); + + rt_reset_control_deassert(rk_p3phy->rstc); + + timeout_us = 500; + while (timeout_us --> 0) + { + err = rt_syscon_read(rk_p3phy->phy_grf, RK3588_PCIE3PHY_GRF_PHY0_STATUS1, ®); + + if (err || RK3588_SRAM_INIT_DONE(reg)) + { + break; + } + + rt_hw_us_delay(1); + rt_hw_cpu_relax(); + + err = -RT_ETIMEOUT; + } + err_res |= err; + + timeout_us = 500; + while (timeout_us --> 0) + { + err = rt_syscon_read(rk_p3phy->phy_grf, RK3588_PCIE3PHY_GRF_PHY1_STATUS1, ®); + + if (err || RK3588_SRAM_INIT_DONE(reg)) + { + break; + } + + rt_hw_us_delay(1); + rt_hw_cpu_relax(); + + err = -RT_ETIMEOUT; + } + err_res |= err; + + if (err_res) + { + LOG_E("%s: lock failed 0x%x, check input refclk and power supply", + rt_dm_dev_get_name(rk_p3phy->parent.dev), reg); + } + + return err_res; +} + +static const struct rockchip_pcie3_phy_soc_data rk3588_data = +{ + .phy_init = rockchip_p3phy_rk3588_init, +}; + +static rt_err_t rockchip_pcie3_phy_init(struct rt_phye *phy) +{ + rt_err_t err; + struct rockchip_pcie3_phy *rk_p3phy = raw_to_rockchip_pcie3_phy(phy); + + if ((err = rt_clk_array_prepare_enable(rk_p3phy->clk_arr))) + { + LOG_E("Enable PCIe bulk clks erros = %s", rt_strerror(err)); + + return err; + } + + rt_reset_control_assert(rk_p3phy->rstc); + rt_hw_us_delay(1); + + if (rk_p3phy->soc_data->phy_init && + (err = rk_p3phy->soc_data->phy_init(rk_p3phy))) + { + rt_clk_array_disable_unprepare(rk_p3phy->clk_arr); + + LOG_E("Init PCIe PHY erros = %s", rt_strerror(err)); + + return RT_EOK; + } + + return err; +} + +static rt_err_t rockchip_pcie3_phy_exit(struct rt_phye *phy) +{ + struct rockchip_pcie3_phy *rk_p3phy = raw_to_rockchip_pcie3_phy(phy); + + rt_clk_array_disable_unprepare(rk_p3phy->clk_arr); + rt_reset_control_assert(rk_p3phy->rstc); + + return RT_EOK; +} + +static rt_err_t rockchip_p3phy_set_mode(struct rt_phye *phy, + enum rt_phye_mode mode, int submode) +{ + struct rockchip_pcie3_phy *rk_p3phy = raw_to_rockchip_pcie3_phy(phy); + + switch (submode) + { + case RT_PHYE_MODE_PCIE_RC: + case RT_PHYE_MODE_PCIE_EP: + rk_p3phy->mode = submode; + break; + + case RT_PHYE_MODE_PCIE_BIFURCATION: + rk_p3phy->is_bifurcation = RT_TRUE; + break; + + default: + return -RT_EINVAL; + } + + return RT_EOK; +} + +static const struct rt_phye_ops rockchip_pcie3_phy_ops = +{ + .init = rockchip_pcie3_phy_init, + .exit = rockchip_pcie3_phy_exit, + .set_mode = rockchip_p3phy_set_mode, +}; + +static void rockchip_pcie3_phy_free(struct rockchip_pcie3_phy *rk_p3phy) +{ + if (rk_p3phy->regs) + { + rt_iounmap(rk_p3phy->regs); + } + + if (!rt_is_err_or_null(rk_p3phy->clk_arr)) + { + rt_clk_array_put(rk_p3phy->clk_arr); + } + + if (!rt_is_err_or_null(rk_p3phy->rstc)) + { + rt_reset_control_put(rk_p3phy->rstc); + } + + rt_free(rk_p3phy); +} + +static rt_err_t rockchip_pcie3_phy_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + rt_uint32_t val; + struct rt_phye *phy; + struct rt_device *dev = &pdev->parent; + struct rockchip_pcie3_phy *rk_p3phy = rt_calloc(1, sizeof(*rk_p3phy)); + + if (!rk_p3phy) + { + return -RT_ENOMEM; + } + + rk_p3phy->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_p3phy->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_p3phy->phy_grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,phy-grf"); + + if (!rk_p3phy->phy_grf) + { + err = -RT_EIO; + goto _fail; + } + + rk_p3phy->pipe_grf = rt_syscon_find_by_ofw_phandle(dev->ofw_node, "rockchip,pipe-grf"); + + if (!rk_p3phy->pipe_grf && rt_dm_dev_prop_read_bool(dev, "rockchip,pipe-grf")) + { + err = -RT_EIO; + goto _fail; + } + + rk_p3phy->rstc = rt_reset_control_get_by_name(dev, "phy"); + + if (rt_is_err(rk_p3phy->rstc)) + { + err = rt_ptr_err(rk_p3phy->rstc); + goto _fail; + } + + rk_p3phy->clk_arr = rt_clk_get_array(dev); + + if (rt_is_err(rk_p3phy->clk_arr)) + { + err = rt_ptr_err(rk_p3phy->clk_arr); + goto _fail; + } + + if (!rt_dm_dev_prop_read_u32(dev, "rockchip,pcie30-phymode", &val) && val <= 4) + { + rk_p3phy->pcie30_phymode = val; + } + else + { + rk_p3phy->pcie30_phymode = PHYE_MODE_PCIE_AGGREGATION; + } + + rt_syscon_write(rk_p3phy->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, + GRF_ENABLE | rk_p3phy->pcie30_phymode); + + if (rk_p3phy->pipe_grf) + { + rt_uint32_t reg = rk_p3phy->pcie30_phymode & 3; + + if (reg) + { + rt_syscon_write(rk_p3phy->pipe_grf, PHP_GRF_PCIESEL_CON, + (reg << GRF_ENABLE_SHIFT) | reg); + } + } + + rk_p3phy->soc_data = pdev->id->data; + dev->user_data = rk_p3phy; + + phy = &rk_p3phy->parent; + phy->dev = dev; + phy->ops = &rockchip_pcie3_phy_ops; + + if ((err = rt_phye_register(phy))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rockchip_pcie3_phy_free(rk_p3phy); + + return err; +} + +static rt_err_t rockchip_pcie3_phy_remove(struct rt_platform_device *pdev) +{ + struct rt_device *dev = &pdev->parent; + struct rockchip_pcie3_phy *rk_p3phy = dev->user_data; + + rt_phye_unregister(&rk_p3phy->parent); + + rockchip_pcie3_phy_free(rk_p3phy); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_pcie3_phy_ofw_ids[] = +{ + { .compatible = "rockchip,rk3568-pcie3-phy", .data = &rk3568_data }, + { .compatible = "rockchip,rk3588-pcie3-phy", .data = &rk3588_data }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_pcie3_phy_driver = +{ + .name = "phy-rockchip-snps-pcie3", + .ids = rockchip_pcie3_phy_ofw_ids, + + .probe = rockchip_pcie3_phy_probe, + .remove = rockchip_pcie3_phy_remove, +}; + +static int rockchip_pcie3_phy_drv_register(void) +{ + rt_platform_driver_register(&rockchip_pcie3_phy_driver); + + return 0; +} +INIT_PLATFORM_EXPORT(rockchip_pcie3_phy_drv_register); diff --git a/bsp/rockchip/dm/phye/phye-snps-pcie3.fw b/bsp/rockchip/dm/phye/phye-snps-pcie3.fw new file mode 100755 index 00000000000..6331c993140 --- /dev/null +++ b/bsp/rockchip/dm/phye/phye-snps-pcie3.fw @@ -0,0 +1,8192 @@ +0x081d, +0xffff, +0x33af, +0x33ae, +0x0c4f, +0xd10d, +0x0d0f, +0xd306, +0x0c8f, +0xdb06, +0x33af, +0xd38d, +0x01ac, +0x2000, +0x0c1e, +0x014a, +0x2800, +0x1b80, +0xa0b2, +0x0806, +0x0016, +0x8cc7, +0xd1ae, +0x0c2e, +0x1b75, +0x33ae, +0xa01c, +0x8026, +0x0c2f, +0xd375, +0x33af, +0x1b81, +0xa022, +0x8026, +0x0d8f, +0x03a6, +0x0003, +0x33af, +0x0c6f, +0xdba6, +0x33af, +0x0c4f, +0xd10d, +0x33af, +0x0d8f, +0xdba6, +0x33af, +0x1b81, +0xa032, +0x8048, +0xdb87, +0x038d, +0x0020, +0xd310, +0x080f, +0x0020, +0xd106, +0x33af, +0xdb8b, +0xdb8c, +0x1b0f, +0xa03a, +0x0807, +0x0044, +0x33fe, +0x0c01, +0x0c3f, +0x80ba, +0x0c4f, +0xd30e, +0x33af, +0xd38d, +0x1b82, +0xa04b, +0x8061, +0xdb88, +0x080f, +0x0020, +0xd106, +0x33af, +0x1b8e, +0xa053, +0x8061, +0x1ba7, +0xa056, +0x8053, +0x0807, +0x005c, +0x33fe, +0x0c01, +0x0c3f, +0x80ba, +0xdb8f, +0x0c2e, +0x1b09, +0xa05d, +0x33ae, +0x1b86, +0xa07b, +0x1b85, +0xa0a7, +0x080e, +0x0200, +0x1bf6, +0x33ae, +0xa074, +0x1b5e, +0xa06d, +0x8077, +0x0c4e, +0x1bf6, +0x33ae, +0xa077, +0x0806, +0x0000, +0x89a4, +0x0c4f, +0xdbf6, +0x33af, +0x1b2f, +0xa07a, +0x89df, +0x8000, +0x080f, +0x0020, +0xd106, +0x33af, +0x0807, +0x0085, +0x33fe, +0x0c01, +0x0c3f, +0x80ba, +0xd35e, +0x038d, +0x0020, +0xd10d, +0x010d, +0x0002, +0x0c8f, +0xdb06, +0x33af, +0x0d0f, +0xdb06, +0x33af, +0x0c2e, +0x1919, +0xa095, +0x8092, +0x33ae, +0x0c8f, +0xd306, +0x33af, +0x0c2e, +0x1919, +0xa09d, +0x33ae, +0x0d0f, +0xd306, +0x33af, +0xd10d, +0xd38d, +0xdb10, +0xdb8c, +0xdb8b, +0xd310, +0x8000, +0xdb8b, +0xd35e, +0x0806, +0x0000, +0x1b28, +0xa995, +0x0806, +0x0000, +0x038d, +0x0020, +0x86f1, +0xd380, +0x1b59, +0xa19e, +0x80c8, +0x0c4f, +0xd3f6, +0x33af, +0x080e, +0x01fc, +0x1bf6, +0x33ae, +0xa0c3, +0x080f, +0x01fc, +0x03f6, +0x0032, +0x33af, +0x0806, +0x0157, +0x1b27, +0xa641, +0x822b, +0x0367, +0x003f, +0x0368, +0x0c09, +0x0369, +0x7928, +0xd36a, +0x036b, +0x007f, +0x036c, +0x0c13, +0x036d, +0x7803, +0xd36e, +0x037c, +0x003f, +0x037d, +0x0c01, +0x037e, +0x7818, +0xd37f, +0x03e0, +0x007f, +0x03e1, +0x0c2f, +0x03e2, +0x7828, +0x03e3, +0x36dc, +0x03e4, +0x007f, +0x03e5, +0x0c09, +0x03e6, +0x7818, +0x03e7, +0x124a, +0x080e, +0xff00, +0x191e, +0x33ae, +0x080f, +0x00ff, +0x291d, +0x0ccf, +0xd11d, +0x080f, +0x0100, +0xd91d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x0349, +0x0017, +0x0353, +0x0017, +0x1b4a, +0x29b4, +0xd9b8, +0x0229, +0x1060, +0x022a, +0x0e24, +0x080e, +0x4000, +0x1b09, +0xa108, +0x0c2e, +0x1b02, +0xa10c, +0x33ae, +0xd317, +0x1b29, +0xa115, +0x705e, +0x8115, +0x1b2d, +0xa118, +0x811a, +0x014b, +0x2dab, +0x1b2e, +0xa11d, +0x811f, +0x014c, +0x004b, +0x1b2a, +0xa123, +0x0125, +0x065a, +0x1b2b, +0xa126, +0x8128, +0x0127, +0x0d07, +0x0063, +0x7f00, +0x0073, +0x7f00, +0x1a28, +0xa145, +0xda28, +0x1b29, +0xa137, +0x0060, +0x0008, +0x0070, +0x0008, +0xdba8, +0x8140, +0x0c2f, +0xd881, +0x080f, +0xffff, +0xdba8, +0x0061, +0x0018, +0x0071, +0x0018, +0x0301, +0x0f05, +0x03a0, +0x0007, +0x8147, +0x0301, +0x0f05, +0x1b2c, +0xa14c, +0x0144, +0x0100, +0x8152, +0x080f, +0x0200, +0xd944, +0x33af, +0x0145, +0x6db4, +0x0306, +0x0006, +0x1b0f, +0xa154, +0x80b6, +0x0305, +0x000c, +0x0306, +0x0007, +0x0317, +0x0003, +0x0306, +0x0006, +0x1b0f, +0xa15f, +0x0306, +0x0004, +0xdb87, +0x1a28, +0x5c6d, +0xa168, +0x816e, +0x13a3, +0x5cec, +0xa168, +0x0228, +0x0003, +0x816e, +0x0c2e, +0x1a11, +0x33ae, +0xa177, +0x1867, +0x080c, +0x0100, +0x518d, +0x2b54, +0x0c4e, +0x1a11, +0x33ae, +0xa180, +0x1877, +0x080c, +0x0100, +0x518d, +0x2b55, +0x1867, +0x2868, +0x1877, +0x2878, +0x1886, +0x2b56, +0x1888, +0x2b58, +0x1887, +0x2b57, +0x0060, +0x0018, +0x0070, +0x0018, +0xda12, +0xd3a0, +0xd3a8, +0xdb59, +0x7005, +0x0c4f, +0xd081, +0x080f, +0xffff, +0x0c8f, +0xd303, +0x33af, +0x0c4f, +0xd30e, +0x33af, +0x8000, +0x1b54, +0x2868, +0x1b55, +0x2878, +0x705e, +0x1b2d, +0xa1a6, +0x81a8, +0x014b, +0x2dab, +0x1b2e, +0xa1ab, +0x81ad, +0x014c, +0x004b, +0x1b29, +0xa1b0, +0x81b8, +0x0c2f, +0xd881, +0x080f, +0xffff, +0x0061, +0x0018, +0x0071, +0x0018, +0x1b56, +0x2883, +0x1b58, +0x2885, +0x1b57, +0x2884, +0x0301, +0x0f05, +0xd9ae, +0x01ad, +0x0080, +0xd1af, +0xd9b6, +0x1b40, +0x29ad, +0xd9af, +0xd9b6, +0x1b41, +0x29ad, +0x01af, +0x0002, +0xd9b6, +0x1b42, +0x29ad, +0x01af, +0x0003, +0xd9b6, +0x1b45, +0x29ad, +0x01af, +0x0014, +0xd9b6, +0x1b46, +0x29ad, +0x01af, +0x0015, +0xd9b6, +0x01a8, +0x0140, +0x1b4b, +0x2973, +0x1b4c, +0x2974, +0x1b51, +0x2979, +0x1b4d, +0x2975, +0x1b4e, +0x2976, +0x1b52, +0x297a, +0x1bf2, +0x5c6d, +0xa1f1, +0x0c4f, +0xd9ba, +0x33af, +0x0c8e, +0x1b24, +0x33ae, +0xa1f6, +0x81f9, +0x0c2f, +0xd9ba, +0x33af, +0x1b4f, +0x080f, +0xff00, +0x297f, +0x080f, +0xffff, +0x1b50, +0x080f, +0x00ff, +0x297f, +0x080f, +0xffff, +0x1b4a, +0x29b4, +0xd9b8, +0xd1ae, +0xd1a8, +0x018e, +0x0019, +0x0305, +0x000c, +0xd306, +0x1b0f, +0xa20f, +0x1b2c, +0xa214, +0x821a, +0x080f, +0x0200, +0xd944, +0x33af, +0x0145, +0x6db4, +0x1b04, +0xa21a, +0x1b2a, +0xa220, +0x0125, +0x065a, +0x1b2b, +0xa223, +0x8225, +0x0127, +0x0d07, +0xda12, +0x0229, +0x1060, +0x022a, +0xe24 , +0x8193, +0x01a8, +0x0140, +0x0100, +0x0004, +0x018e, +0x0019, +0xd9ae, +0xd9b6, +0x01b0, +0x0b37, +0x01b1, +0x00fa, +0xd9b7, +0x0180, +0x03ff, +0xd981, +0xd182, +0xd183, +0x0184, +0x4000, +0x0185, +0x2408, +0x1b31, +0xa254, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0xa060, +0xd9af, +0x0340, +0x0080, +0x0800, +0x0340, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0254, +0x0c03, +0x864b, +0x1b31, +0xa268, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0xa080, +0x01af, +0x0002, +0x0341, +0x0080, +0x0800, +0x0341, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0268, +0x0c03, +0x864b, +0x01b1, +0x0062, +0xd9b7, +0x1b31, +0xa27e, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0xa080, +0xd9af, +0x0340, +0x0080, +0x0800, +0x0340, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x027e, +0x0c03, +0x864b, +0x1b31, +0xa292, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0xa0c0, +0x01af, +0x0003, +0x0342, +0x0080, +0x0800, +0x0342, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0292, +0x0c03, +0x864b, +0x080e, +0xf800, +0x1b0c, +0x31a1, +0x080e, +0x07ff, +0x1b0c, +0x31a2, +0xd11d, +0x0cee, +0x1b0d, +0x31a3, +0x33ae, +0x304d, +0x080f, +0x07ff, +0x29b0, +0x33af, +0x302d, +0x080f, +0x00f8, +0x29b1, +0x33af, +0x306d, +0x0cef, +0x29b1, +0x33af, +0xd9b7, +0x0c2e, +0x1bf6, +0x33ae, +0xa2cd, +0x0180, +0x03ff, +0xd981, +0xd182, +0xd183, +0x0184, +0x4000, +0x0185, +0x2408, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0xb080, +0x01af, +0x0002, +0x03f7, +0x0080, +0x0800, +0x03f7, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x02cd, +0x0c03, +0x864b, +0x0c8e, +0x1bf4, +0x33ae, +0xa2ec, +0x0180, +0x03ff, +0xd981, +0xd182, +0xd183, +0x0184, +0x4000, +0x0185, +0x2408, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0xb0c0, +0x01af, +0x0003, +0x03ec, +0x0080, +0x0800, +0x03ec, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x02ec, +0x0c03, +0x864b, +0x01b3, +0x0177, +0xd3f2, +0x0c2e, +0x1bf4, +0x33ae, +0xa313, +0x0180, +0x01ff, +0x0181, +0xaaaa, +0x0182, +0x2800, +0xd183, +0x0184, +0x6c00, +0x0185, +0x2408, +0x0807, +0x0301, +0x8dc7, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0016, +0x0179, +0x0080, +0x0800, +0x0179, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0313, +0x0c23, +0x864b, +0x0800, +0x0179, +0x3801, +0x0802, +0x003f, +0x0803, +0x00c0, +0x5461, +0xb31f, +0x5422, +0xb31f, +0x8329, +0x0c4e, +0x19ba, +0x33ae, +0xa329, +0x1b33, +0xa329, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x0c2e, +0x1bf4, +0x33ae, +0xa34d, +0x0180, +0x01ff, +0x0181, +0x5555, +0x0182, +0x1400, +0xd183, +0x0184, +0x6c00, +0x0185, +0x2408, +0x0807, +0x033b, +0x8e5b, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0018, +0x017a, +0x0080, +0x0800, +0x017a, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x034d, +0x0c23, +0x864b, +0x0800, +0x017a, +0x3801, +0x0802, +0x003f, +0x0803, +0x00c0, +0x5461, +0xb359, +0x5422, +0xb359, +0x8363, +0x0c4e, +0x19ba, +0x33ae, +0xa363, +0x1b33, +0xa363, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x080e, +0x0400, +0x1b6f, +0x33ae, +0xa38d, +0x0c4e, +0x19ba, +0x33ae, +0xa38b, +0x0800, +0x009b, +0x1979, +0x31a1, +0x197a, +0x31a2, +0x5420, +0xb375, +0x8379, +0x5440, +0xb379, +0xdbf2, +0x838d, +0x5420, +0xb381, +0x5440, +0xb37e, +0x8381, +0x03f2, +0x0002, +0x838d, +0x5420, +0xb38d, +0x5440, +0xb38d, +0x03f2, +0x0003, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x03f2, +0x0003, +0x1bf2, +0x5c6d, +0xa395, +0x03ed, +0x0025, +0x03ee, +0x0025, +0x8399, +0x03ed, +0x0037, +0x03ee, +0x0037, +0x1b32, +0xa3bb, +0x0180, +0x01ff, +0x0181, +0xaaaa, +0x0182, +0x2800, +0xd183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x03a9, +0x8d7d, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0010, +0x0173, +0x0080, +0x0800, +0x0173, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x03bb, +0x0c23, +0x864b, +0x0800, +0x0173, +0x3801, +0x0802, +0x003f, +0x0803, +0x00c0, +0x5423, +0xb3c5, +0x83c7, +0x5441, +0xb3d1, +0x0c4e, +0x19ba, +0x33ae, +0xa3d1, +0x1b33, +0xa3d1, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x1b32, +0xa3f3, +0x0180, +0x01ff, +0x0181, +0xaaaa, +0x0182, +0x2800, +0xd183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x03e1, +0x8da1, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0011, +0x0174, +0x0080, +0x0800, +0x0174, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x03f3, +0x0c23, +0x864b, +0x0800, +0x0174, +0x3801, +0x0802, +0x003f, +0x0803, +0x00c0, +0x5423, +0xb3fd, +0x83ff, +0x5441, +0xb409, +0x0c4e, +0x19ba, +0x33ae, +0xa409, +0x1b33, +0xa409, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x1b32, +0xa42b, +0x0180, +0x01ff, +0x0181, +0x5555, +0x0182, +0x1400, +0xd183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x0419, +0x8e11, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0012, +0x0175, +0x0080, +0x0800, +0x0175, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x042b, +0x0c23, +0x864b, +0x0800, +0x0175, +0x3801, +0x0802, +0x003f, +0x0803, +0x00c0, +0x5423, +0xb435, +0x8437, +0x5441, +0xb441, +0x0c4e, +0x19ba, +0x33ae, +0xa441, +0x1b33, +0xa441, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x1b32, +0xa463, +0x0180, +0x01ff, +0x0181, +0x5555, +0x0182, +0x1400, +0xd183, +0x0184, +0x7000, +0x0185, +0x2408, +0x0807, +0x0451, +0x8e35, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0013, +0x0176, +0x0080, +0x0800, +0x0176, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0463, +0x0c23, +0x864b, +0x0800, +0x0176, +0x3801, +0x0802, +0x003f, +0x0803, +0x00c0, +0x5423, +0xb46d, +0x846f, +0x5441, +0xb479, +0x0c4e, +0x19ba, +0x33ae, +0xa479, +0x1b33, +0xa479, +0x0c4f, +0xd9ba, +0x33af, +0x82ef, +0x0c8f, +0xd324, +0x33af, +0x1b3d, +0xa49e, +0x0180, +0x01ff, +0x0181, +0xaaaa, +0x0182, +0x2800, +0xd183, +0x0184, +0x6800, +0x0185, +0x2408, +0x0807, +0x048c, +0x8dec, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0014, +0x0345, +0x0080, +0x0800, +0x0345, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x049e, +0x0c23, +0x864b, +0x1b3d, +0xa4c0, +0x0180, +0x01ff, +0x0181, +0x5555, +0x0182, +0x1400, +0xd183, +0x0184, +0x6800, +0x0185, +0x2408, +0x0807, +0x04ae, +0x8e80, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0015, +0x0346, +0x0080, +0x0800, +0x0346, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x04c0, +0x0c23, +0x864b, +0x1b3e, +0xa4dd, +0x0800, +0x00fb, +0x1b45, +0x31a1, +0x1b46, +0x31a2, +0x5401, +0xb4d2, +0x5402, +0xb4d2, +0x0c80, +0x5420, +0xb4d2, +0x5440, +0xb4d2, +0x84dd, +0x0c2e, +0x19ba, +0x33ae, +0xa4dd, +0x0c8f, +0xdb24, +0x33af, +0x0c2f, +0xd9ba, +0x33af, +0x847c, +0x0c4e, +0x1bf4, +0x33ae, +0xa508, +0x0180, +0x01ff, +0x0181, +0xaaaa, +0x0182, +0x2800, +0xd183, +0x0184, +0x7000, +0x0185, +0x2408, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0010, +0x0807, +0x04f6, +0x8ea5, +0x01a8, +0x0100, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0010, +0x034f, +0x0080, +0x0800, +0x034f, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0508, +0x0c23, +0x864b, +0x1b4f, +0x080f, +0xff00, +0x297f, +0x080f, +0xffff, +0x0c4e, +0x1bf4, +0x33ae, +0xa539, +0x0180, +0x01ff, +0x0181, +0x5555, +0x0182, +0x1400, +0xd183, +0x0184, +0x7000, +0x0185, +0x2408, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0012, +0x0807, +0x0527, +0x8ec9, +0x01a8, +0x0100, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0012, +0x0350, +0x0080, +0x0800, +0x0350, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0539, +0x0c23, +0x864b, +0x1b50, +0x080f, +0x00ff, +0x297f, +0x080f, +0xffff, +0x0c2e, +0x1b6f, +0x33ae, +0xa5cf, +0x0cee, +0x1b0c, +0x33ae, +0x0800, +0x0080, +0x51a0, +0x080f, +0x07ff, +0x29b0, +0x33af, +0xd9b7, +0x0800, +0x0080, +0x1bed, +0x51a0, +0x2969, +0x31a0, +0x01af, +0x0016, +0x21ad, +0xd9b6, +0x0180, +0x03ff, +0xd981, +0xd182, +0xd183, +0x0184, +0x4000, +0x0185, +0x2408, +0x01a8, +0x0100, +0xd1b5, +0x01ac, +0x9346, +0x01af, +0x001b, +0x03fc, +0x0080, +0x0800, +0x03fc, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0573, +0x0c23, +0x864b, +0x01a8, +0x0100, +0xd1b5, +0x01ac, +0x90da, +0x01af, +0x0003, +0x03fd, +0x0080, +0x0800, +0x03fd, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x0585, +0x0c03, +0x864b, +0x0180, +0x01ff, +0x0181, +0xaaaa, +0x0182, +0x2800, +0xd183, +0x0184, +0x6c00, +0x0185, +0x2408, +0x0807, +0x0593, +0x8dc7, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0016, +0x03ed, +0x0080, +0x0800, +0x03ed, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x05a5, +0x0c23, +0x864b, +0x0180, +0x01ff, +0x0181, +0x5555, +0x0182, +0x1400, +0xd183, +0x0184, +0x6c00, +0x0185, +0x2408, +0x0807, +0x05b3, +0x8e5b, +0x01a8, +0x0140, +0xd1b5, +0x01ac, +0x3000, +0x01af, +0x0018, +0x03ee, +0x0080, +0x0800, +0x03ee, +0x01ad, +0x0080, +0xd9b6, +0x0807, +0x05c5, +0x0c23, +0x864b, +0x1bee, +0x31a0, +0x1bed, +0x31a1, +0x197a, +0x55a0, +0x2bee, +0x1979, +0x55a1, +0x2bed, +0x080e, +0x07f8, +0x1b0c, +0x33ae, +0x080f, +0x07f8, +0x29b0, +0x33af, +0xd9b7, +0x080f, +0x0800, +0xd1b0, +0x33af, +0xd9b7, +0x01a8, +0x0140, +0x1973, +0x29ad, +0x01af, +0x0010, +0xd9b6, +0x1974, +0x29ad, +0x01af, +0x0011, +0xd9b6, +0x1979, +0x29ad, +0x01af, +0x0016, +0xd9b6, +0x1b45, +0x29ad, +0x01af, +0x0014, +0xd9b6, +0x1975, +0x29ad, +0x01af, +0x0012, +0xd9b6, +0x1976, +0x29ad, +0x01af, +0x0013, +0xd9b6, +0x197a, +0x29ad, +0x01af, +0x0018, +0xd9b6, +0x1b46, +0x29ad, +0x01af, +0x0015, +0xd9b6, +0x1973, +0x2b4b, +0x1974, +0x2b4c, +0x1979, +0x2b51, +0x080f, +0xff00, +0x2bef, +0x080f, +0x00ff, +0x2bef, +0x33af, +0x1975, +0x2b4d, +0x1976, +0x2b4e, +0x197a, +0x2b52, +0x080f, +0xff00, +0x2bf0, +0x080f, +0x00ff, +0x2bf0, +0x33af, +0x01a8, +0x0100, +0x1b4f, +0x29ad, +0x01af, +0x0010, +0xd9b6, +0x1b50, +0x29ad, +0x01af, +0x0012, +0xd9b6, +0x1b41, +0x29ad, +0x01af, +0x0002, +0xd9b6, +0x1b42, +0x29ad, +0x01af, +0x0003, +0xd9b6, +0x33fe, +0x0c3f, +0x804b, +0xd1ac, +0x01b3, +0x0077, +0xd100, +0xd1a8, +0xd1ae, +0x8646, +0x33fe, +0x0c3f, +0x804d, +0xd1a8, +0xd9b6, +0x080f, +0x0400, +0xd185, +0x33af, +0x9006, +0x0804, +0x0040, +0x5c03, +0xa650, +0x8653, +0x0ce1, +0x7080, +0x8655, +0x0cc1, +0x7080, +0x6660, +0x0c42, +0x5443, +0xb65b, +0x6260, +0x8678, +0xa669, +0x080e, +0x7fff, +0x198a, +0x33ae, +0x31a2, +0x4022, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x426d, +0x55a2, +0x8678, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x31a2, +0x4022, +0x426d, +0x55a2, +0x31a2, +0x080e, +0x7fff, +0x198a, +0x33ae, +0x402d, +0x544d, +0xb680, +0x0c02, +0x55a2, +0x31a5, +0x380d, +0x3802, +0x548d, +0x8686, +0x31a5, +0x3802, +0xa684, +0x8691, +0x380d, +0x508d, +0x35a0, +0x29ad, +0xd9b6, +0x5c03, +0xa68e, +0x0c37, +0x700f, +0x8693, +0x0c17, +0x700f, +0x8693, +0x31a5, +0x3802, +0x4224, +0x5c21, +0xa655, +0x0c81, +0x6660, +0x0c44, +0x5483, +0xb69d, +0x6260, +0x86ba, +0xa6ab, +0x080e, +0x7fff, +0x198a, +0x33ae, +0x31a4, +0x4024, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x426d, +0x55a4, +0x86ba, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x31a4, +0x4024, +0x426d, +0x55a4, +0x31a4, +0x080e, +0x7fff, +0x198a, +0x33ae, +0x402d, +0x548d, +0x31a4, +0xb6cd, +0x0c04, +0x55a4, +0x31a4, +0x54a4, +0xb6c3, +0x3085, +0x3802, +0x32ed, +0xa6c8, +0x380d, +0x5c2d, +0x86ca, +0x380d, +0x5c4d, +0x31a4, +0xb6db, +0x86ef, +0x54a4, +0xb6d1, +0x3085, +0x3802, +0x32ed, +0xa6d6, +0x380d, +0x582d, +0x86d8, +0x380d, +0x584d, +0x31a4, +0x430d, +0xa6ef, +0x5c21, +0xa6e4, +0x3804, +0x5482, +0xa6e1, +0x86ef, +0x3440, +0x304d, +0x86e6, +0x3480, +0x308d, +0x29ad, +0xd9b6, +0x5c03, +0xa6ec, +0x700f, +0x86ed, +0x700f, +0x5c01, +0xa697, +0x33df, +0x9007, +0x1b36, +0xa709, +0xd35e, +0x038d, +0x0030, +0xd10d, +0x010d, +0x0002, +0x0306, +0x000c, +0x0c2e, +0x1919, +0x33ae, +0xa700, +0x86fb, +0x0306, +0x0008, +0x0c2e, +0x1919, +0x33ae, +0xa702, +0x0305, +0x000c, +0xd10d, +0x038d, +0x0030, +0x1b38, +0xa711, +0x080f, +0x0080, +0xd37b, +0x33af, +0xd38d, +0x1b38, +0xa716, +0x0c6c, +0x871e, +0x1b34, +0xa71d, +0x080e, +0x01e0, +0x131c, +0x33ae, +0x871e, +0x0c0c, +0x33fe, +0x0c3f, +0x8946, +0x1b49, +0x2b47, +0x038d, +0x0030, +0xd1a8, +0xd161, +0x0162, +0x0042, +0x0163, +0x0060, +0xd164, +0xd165, +0x0167, +0x21a2, +0x1bee, +0x2bcd, +0x1bed, +0x2bcc, +0x13cd, +0x1b52, +0x518d, +0x31ac, +0x430d, +0xa73b, +0x318d, +0x873d, +0x080d, +0x00ff, +0x31a1, +0x080f, +0xff00, +0x2969, +0x33af, +0x13cc, +0x1b51, +0x518d, +0x31ac, +0x430d, +0xa74a, +0x318d, +0x874c, +0x080d, +0x00ff, +0x31a1, +0x080f, +0x00ff, +0x2969, +0x33af, +0x0181, +0xffff, +0x0182, +0x3c02, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x1b67, +0x2980, +0x1b68, +0x2960, +0x1b69, +0x2966, +0x1b6a, +0x2968, +0x1b36, +0xa76b, +0x0807, +0x076a, +0x33fe, +0x0c1f, +0x89c5, +0x6c00, +0xd162, +0x0163, +0x001f, +0x0182, +0x3c23, +0x0183, +0x0087, +0x0184, +0x7068, +0x0185, +0x247c, +0x1b6b, +0x2980, +0x1b6c, +0x2960, +0x1b6d, +0x2966, +0x1b6e, +0x2968, +0x1b36, +0xa781, +0x6c00, +0x0182, +0x3c02, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x0162, +0x0042, +0x0163, +0x0060, +0x0167, +0x39c0, +0x1b7c, +0x2980, +0x1b7d, +0x2960, +0x1b7e, +0x2966, +0x1b7f, +0x2968, +0x1b36, +0xa7e0, +0x0807, +0x079e, +0x33fe, +0x0c1f, +0x89c5, +0x6c00, +0x080e, +0x4000, +0x1b6f, +0x33ae, +0xa7e0, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x5ced, +0xb7e0, +0x0180, +0x01ff, +0x080f, +0x03e0, +0x0182, +0x0002, +0x33af, +0x6620, +0xb7b4, +0x87e0, +0xa7b6, +0x87e0, +0x080f, +0x3fff, +0xd160, +0x33af, +0x080f, +0x0038, +0x0166, +0x0005, +0x33af, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x402d, +0x31a0, +0x080e, +0x003f, +0x196c, +0x33ae, +0xa7cc, +0x5820, +0x87cd, +0x5840, +0x31a0, +0x080f, +0x7c00, +0x2167, +0x080f, +0x03e0, +0x2167, +0x33af, +0x1169, +0x3181, +0x080f, +0x1000, +0xd166, +0x33af, +0x0169, +0xffff, +0x6c00, +0x302d, +0x2969, +0x1969, +0x2bf7, +0x080e, +0x0020, +0x1b6f, +0x33ae, +0xa7ea, +0x33fe, +0x0c3f, +0x8ba3, +0x080f, +0x7c00, +0xd3f6, +0x33af, +0xd3f8, +0xd3f9, +0xd3fa, +0x080e, +0x8000, +0x1bf6, +0x33ae, +0xa891, +0x0cc0, +0x0d61, +0x0c22, +0x0c23, +0x0804, +0x00f5, +0x0807, +0x0801, +0x33fe, +0x0c3f, +0x89e6, +0x31b8, +0x080f, +0xff00, +0x2bf8, +0x33af, +0x0cc0, +0x0d61, +0x0c22, +0x0c23, +0x0804, +0x00f5, +0x0807, +0x0811, +0x33fe, +0x0c3f, +0x8a57, +0x31b9, +0x080f, +0x00ff, +0x2bf8, +0x33af, +0x0c40, +0x0d61, +0x0c22, +0x0c23, +0x0804, +0x00f5, +0x0807, +0x0821, +0x33fe, +0x0c3f, +0x89e6, +0x31ba, +0x080f, +0xff00, +0x2bf9, +0x33af, +0x0c40, +0x0d61, +0x0c22, +0x0c23, +0x0804, +0x00f5, +0x0807, +0x0831, +0x33fe, +0x0c3f, +0x8a57, +0x31bb, +0x080f, +0x00ff, +0x2bf9, +0x33af, +0x0807, +0x083b, +0x33fe, +0x0c3f, +0x8ac8, +0x080e, +0x0400, +0x1bf6, +0x33ae, +0xa841, +0x8891, +0x080e, +0x6000, +0x1bf6, +0x33ae, +0x5c2d, +0xa848, +0x8868, +0x0cc0, +0x0c61, +0x0d02, +0x0c03, +0x0804, +0x00ff, +0x0807, +0x0853, +0x33fe, +0x0c3f, +0x89e6, +0x31b8, +0x080f, +0xff00, +0x2bfa, +0x33af, +0x0c80, +0x0d61, +0x0d02, +0x0c03, +0x0c04, +0x0807, +0x0862, +0x33fe, +0x0c3f, +0x89e6, +0x31ba, +0x080f, +0x00ff, +0x2bfa, +0x33af, +0x8887, +0x0cc0, +0x0c61, +0x0d02, +0x0c03, +0x0804, +0x00ff, +0x0807, +0x0873, +0x33fe, +0x0c3f, +0x8a57, +0x31b9, +0x080f, +0xff00, +0x2bfa, +0x33af, +0x0c80, +0x0d61, +0x0d02, +0x0c03, +0x0c04, +0x0807, +0x0882, +0x33fe, +0x0c3f, +0x8a57, +0x31bb, +0x080f, +0x00ff, +0x2bfa, +0x33af, +0x0807, +0x088c, +0x33fe, +0x0c3f, +0x8b11, +0x0807, +0x0891, +0x33fe, +0x0c3f, +0x8b34, +0x080e, +0x0400, +0x1bf6, +0x33ae, +0xa8e9, +0x0181, +0xffff, +0x0182, +0x3c06, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x247e, +0x0161, +0x0009, +0x0162, +0x00c2, +0x0163, +0x7f80, +0xd164, +0xd165, +0x0167, +0x21a2, +0x1bf7, +0x2969, +0x1be0, +0x2980, +0x1be1, +0x2960, +0x1be2, +0x2966, +0x1be3, +0x2968, +0x1b37, +0xa8e9, +0x0807, +0x08bb, +0x33fe, +0x0c1f, +0x89c5, +0x6c00, +0x080e, +0xff00, +0x197b, +0x33ae, +0x31a1, +0x080e, +0x4000, +0x1963, +0x33ae, +0xa8c7, +0x88d0, +0x0807, +0x08ca, +0x8d52, +0x31a2, +0xa8ce, +0x5461, +0x88cf, +0x5061, +0x31a1, +0x1351, +0x302d, +0x558d, +0x2bcc, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x31a1, +0x080e, +0x4000, +0x1963, +0x33ae, +0xa8df, +0x88e5, +0x304d, +0xa8e3, +0x5461, +0x88e4, +0x5061, +0x31a1, +0x1352, +0x302d, +0x558d, +0x2bcd, +0x33fe, +0x0c3f, +0x86cb, +0x0182, +0x3c06, +0x0183, +0x0800, +0x0185, +0x247e, +0x0163, +0x7f80, +0x1be4, +0x2980, +0x1be5, +0x2960, +0x1be6, +0x2966, +0x1be7, +0x2968, +0x080e, +0x0400, +0x1bf6, +0x33ae, +0xa902, +0x891d, +0x080f, +0x0f80, +0x0163, +0x001e, +0x33af, +0x080e, +0x0800, +0x1bf6, +0x33ae, +0xa912, +0x080e, +0x1000, +0x1bf6, +0x33ae, +0xa918, +0x891d, +0x080f, +0x03e0, +0x0182, +0x0002, +0x33af, +0x891d, +0x080f, +0x03e0, +0x0182, +0x0006, +0x33af, +0x1b37, +0xa962, +0x13cd, +0x410c, +0x1bcc, +0x518d, +0x31a1, +0x1352, +0x410c, +0x502c, +0x31a2, +0x1352, +0x410c, +0x502c, +0x31a2, +0x1351, +0x504c, +0x2969, +0x0807, +0x0934, +0x33fe, +0x0c1f, +0x89c5, +0x6c00, +0x080e, +0xff00, +0x197b, +0x33ae, +0x31a1, +0x080e, +0x4000, +0x1963, +0x33ae, +0xa940, +0x8949, +0x0807, +0x0943, +0x8d52, +0x31a2, +0xa947, +0x5461, +0x8948, +0x5061, +0x31a1, +0x1351, +0x302d, +0x558d, +0x2bcc, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x31a1, +0x080e, +0x4000, +0x1963, +0x33ae, +0xa958, +0x895e, +0x304d, +0xa95c, +0x5461, +0x895d, +0x5061, +0x31a1, +0x1352, +0x302d, +0x558d, +0x2bcd, +0x080e, +0x0020, +0x1b6f, +0x33ae, +0xa96a, +0x33fe, +0x0c3f, +0x8c25, +0x080e, +0x0020, +0x1b6f, +0x33ae, +0xa976, +0x33fe, +0x0c3f, +0x8d47, +0x2bcb, +0x13cb, +0x3180, +0x2311, +0x33fe, +0x0c3f, +0x80f0, +0x038d, +0x0030, +0xdb5e, +0x1b38, +0xa982, +0x080f, +0x0080, +0xdb7b, +0x33af, +0xd10d, +0x010d, +0x0002, +0x0306, +0x000c, +0x0c2e, +0x1919, +0x33ae, +0xa98c, +0x8987, +0xd306, +0x0c2e, +0x1919, +0x33ae, +0xa98d, +0x0305, +0x000c, +0xd10d, +0x8998, +0x038d, +0x0030, +0xdb5e, +0xd38d, +0xdb10, +0x1b86, +0xa99d, +0x899a, +0xd310, +0xdb8c, +0x080f, +0x0400, +0xd185, +0x33af, +0x9006, +0x038d, +0x0029, +0x1bc5, +0xa9a9, +0x89be, +0x1b5e, +0xa9ac, +0x89be, +0x0d0e, +0x1913, +0x33ae, +0xa9ac, +0x080e, +0x01fc, +0x1bf6, +0x33ae, +0x31b7, +0xaa12, +0x89bb, +0x0c2d, +0x55b7, +0x31b7, +0xaa1c, +0x0c4f, +0xdbf6, +0x33af, +0x080f, +0x0400, +0xd185, +0x33af, +0x8a77, +0x0167, +0x21a2, +0x1b33, +0xa9dd, +0x0c21, +0x0c42, +0x13f2, +0x542c, +0xa9d4, +0x0181, +0xaaaa, +0x080f, +0x3c00, +0x0182, +0x000a, +0x33af, +0x89dd, +0x544c, +0xa9dd, +0x0181, +0x5555, +0x080f, +0x3c00, +0x0182, +0x0005, +0x33af, +0x33df, +0x9007, +0x038d, +0x0029, +0x1bc5, +0xa9e6, +0x1bc6, +0xa9e6, +0x8a09, +0x7fff, +0x0d0e, +0x1913, +0x33ae, +0xa9e7, +0x1bc5, +0xa9ee, +0x89f1, +0x0806, +0x09f1, +0x8a0f, +0x1bc6, +0xa9f4, +0x8a09, +0x1bf1, +0x31bc, +0x2bcc, +0x430d, +0x2bcd, +0x0806, +0x0a03, +0x080e, +0x0020, +0x1bf3, +0x33ae, +0xaa03, +0x33fe, +0x0c3f, +0x82bd, +0x0806, +0x0a08, +0x1b30, +0xaa08, +0x8ab4, +0x8eed, +0xd38d, +0x080f, +0x0400, +0xd185, +0x33af, +0x807a, +0x1b59, +0xaa12, +0x8a09, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x0180, +0x7d00, +0xd981, +0xd182, +0xd183, +0xd184, +0x0185, +0x2408, +0x01ac, +0xa080, +0x01af, +0x0002, +0x0800, +0x0341, +0x0c01, +0x0c62, +0xd9ae, +0x0807, +0x0a32, +0x1b3a, +0xaa32, +0x8a82, +0x01ac, +0xa0c0, +0x01af, +0x0003, +0x0800, +0x0342, +0x0c01, +0x0c62, +0x0807, +0x0a3f, +0x1b3a, +0xaa3f, +0x8a82, +0x0c4e, +0x1bf6, +0x33ae, +0xaa45, +0x1b5e, +0xa9b7, +0x01ac, +0x2000, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1446, +0x0183, +0x010d, +0x0184, +0x2800, +0x0185, +0x6410, +0xd1ac, +0x01af, +0x0014, +0x0800, +0x0345, +0x0c21, +0x0c62, +0x0807, +0x0a5f, +0x1b39, +0xaa5f, +0x8a82, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2846, +0x0183, +0x010d, +0x0184, +0x2800, +0x0185, +0x6410, +0xd1ac, +0x01af, +0x0015, +0x0800, +0x0346, +0x0c21, +0x0c62, +0x0807, +0x0a77, +0x1b39, +0xaa77, +0x8a82, +0xd1ae, +0xd1ac, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x9006, +0x380d, +0x29ad, +0xd9b6, +0x7080, +0x667c, +0x302d, +0xaa8f, +0x080e, +0x7fff, +0x198a, +0x1186, +0x33ae, +0x8a94, +0x080e, +0x7fff, +0x198b, +0x1186, +0x33ae, +0x402d, +0x31a3, +0x3184, +0x3185, +0x304d, +0xaa9b, +0x8a9e, +0x4225, +0x5c22, +0x8a98, +0x5085, +0x546d, +0xbaa2, +0x8aab, +0x54a4, +0x55a3, +0xbaa6, +0x8aa7, +0x9007, +0x5e20, +0xbab0, +0x3580, +0x9007, +0x5a20, +0x31a2, +0x430d, +0xaaa9, +0x304d, +0x29ad, +0xd9b6, +0x700f, +0x9007, +0x1b5e, +0xaab7, +0x8a09, +0x080e, +0x8000, +0x1beb, +0x33ae, +0xab44, +0x0180, +0x7d00, +0x0181, +0xffff, +0x0182, +0x3c23, +0x0183, +0x0087, +0x0184, +0x3068, +0x0185, +0x647c, +0xd160, +0xd161, +0xd162, +0x0163, +0x001f, +0x0164, +0x000a, +0xd165, +0x0166, +0x7800, +0x0167, +0x21a2, +0xd168, +0x0169, +0xb7b7, +0x0d0c, +0x080e, +0x03e0, +0x196d, +0x33ae, +0x55ac, +0xab42, +0x0180, +0x1964, +0x6620, +0x0c00, +0x0c01, +0x080e, +0x7fff, +0x1186, +0x33ae, +0x080d, +0x0100, +0x518d, +0x31ac, +0x0c2e, +0x1963, +0x33ae, +0xaaf0, +0x8af8, +0x080e, +0x7fff, +0x1989, +0x33ae, +0x500d, +0x31a0, +0x5181, +0x31a1, +0x0c4e, +0x1963, +0x33ae, +0xaafd, +0x8b05, +0x080e, +0x7fff, +0x198a, +0x33ae, +0x500d, +0x31a0, +0x5181, +0x31a1, +0x0c8e, +0x1963, +0x33ae, +0xab0a, +0x8b12, +0x080e, +0x7fff, +0x198b, +0x33ae, +0x500d, +0x31a0, +0x5181, +0x31a1, +0x0d0e, +0x1963, +0x33ae, +0xab17, +0x8b1f, +0x080e, +0x7fff, +0x198c, +0x33ae, +0x500d, +0x31a0, +0x5181, +0x31a1, +0x0e0e, +0x1963, +0x33ae, +0xab24, +0x8b2c, +0x080e, +0x7fff, +0x198d, +0x33ae, +0x500d, +0x31a0, +0x5181, +0x31a1, +0x422d, +0x540d, +0xbb44, +0x080f, +0x03ff, +0x0182, +0x0084, +0x33af, +0x0c2f, +0xd183, +0x33af, +0x080f, +0x0020, +0xd184, +0x33af, +0x0fef, +0xd963, +0x33af, +0x0180, +0x7d00, +0x6c00, +0x8b44, +0xbb44, +0x6c00, +0x13ee, +0x319a, +0x410c, +0x1bed, +0x31bb, +0x518d, +0x31bc, +0x1b3c, +0xac2c, +0x0180, +0x07ff, +0x0181, +0xffff, +0x0182, +0x3c06, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0c07, +0xd161, +0x0162, +0x0042, +0x0163, +0x3000, +0xd164, +0xd165, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x0807, +0x0b6c, +0x33fe, +0x0c1f, +0x89c5, +0x0fef, +0x0182, +0x0002, +0x33af, +0x1352, +0x1bee, +0x518d, +0x31ac, +0x430d, +0xab78, +0x318d, +0x8b7a, +0x080d, +0x00ff, +0x31a1, +0x080f, +0xff00, +0x2969, +0x33af, +0x1351, +0x1bed, +0x518d, +0x31ac, +0x430d, +0xab87, +0x318d, +0x8b89, +0x080d, +0x00ff, +0x31a1, +0x080f, +0x00ff, +0x2969, +0x33af, +0x6c00, +0x1351, +0x080e, +0xff00, +0x197b, +0x33ae, +0x558d, +0xbb98, +0x0c1b, +0x8b99, +0x31bb, +0x1352, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x558d, +0xbba2, +0x0c1a, +0x8ba3, +0x31ba, +0x0180, +0x7d00, +0x0181, +0xffff, +0x0182, +0x3c02, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0xd160, +0xd161, +0x0162, +0x0042, +0x0163, +0x0060, +0x0164, +0x00d0, +0xd165, +0x0166, +0x7800, +0x0167, +0x21a2, +0xd168, +0x13cd, +0x1b52, +0x518d, +0x31ac, +0x430d, +0xabc5, +0x318d, +0x8bc7, +0x080d, +0x00ff, +0x31a1, +0x080f, +0xff00, +0x2969, +0x33af, +0x13cc, +0x1b51, +0x518d, +0x31ac, +0x430d, +0xabd4, +0x318d, +0x8bd6, +0x080d, +0x00ff, +0x31a1, +0x080f, +0x00ff, +0x2969, +0x33af, +0x0807, +0x0be0, +0x33fe, +0x0c1f, +0x89c5, +0xd160, +0x080f, +0x0038, +0x0166, +0x0005, +0x080f, +0x1000, +0xd166, +0x080f, +0x0e00, +0x0166, +0x0004, +0x33af, +0x1bed, +0x31a2, +0x545b, +0xbc0e, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x402d, +0x31a0, +0x080e, +0x003f, +0x196c, +0x33ae, +0xabfe, +0x5820, +0x8bff, +0x5840, +0x31a0, +0x0dc4, +0x5404, +0xbc04, +0x0dc0, +0x080f, +0x7c00, +0x2167, +0x080f, +0x03e0, +0x2167, +0x33af, +0x0169, +0xffff, +0x8c2b, +0x1bed, +0x590d, +0x576d, +0xbc2c, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x402d, +0x31a0, +0x080e, +0x003f, +0x196c, +0x33ae, +0xac21, +0x5c20, +0xbc20, +0x0c0d, +0x31a0, +0x080f, +0x7c00, +0x2167, +0x080f, +0x03e0, +0x2167, +0x0fef, +0x2167, +0x33af, +0xd169, +0x6c00, +0x1b3b, +0xac7e, +0x0180, +0x07ff, +0x0181, +0xffff, +0x0182, +0x3c06, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0c07, +0xd161, +0x0162, +0x0042, +0x0163, +0x3000, +0xd164, +0xd165, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x1352, +0x519a, +0x31ac, +0x430d, +0xac4f, +0x318d, +0x8c51, +0x080d, +0x00ff, +0x31a1, +0x080f, +0xff00, +0x2969, +0x33af, +0x1351, +0x519b, +0x31ac, +0x430d, +0xac5d, +0x318d, +0x8c5f, +0x080d, +0x00ff, +0x31a1, +0x080f, +0x00ff, +0x2969, +0x33af, +0x0807, +0x0c69, +0x33fe, +0x0c1f, +0x89c5, +0x6c00, +0x1351, +0x080e, +0xff00, +0x197b, +0x33ae, +0x558d, +0xbc73, +0x0c1b, +0x8c74, +0x31bb, +0x1352, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x558d, +0xbc7d, +0x0c1a, +0x8c7e, +0x31ba, +0x080e, +0x0040, +0x1bf3, +0x33ae, +0xacb2, +0x0180, +0x7d00, +0x0181, +0xffff, +0x0182, +0x3c06, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x647c, +0xd160, +0x0161, +0x0009, +0x0162, +0x0042, +0x0163, +0x0f00, +0x0164, +0xa000, +0x0165, +0x0999, +0x0166, +0x7800, +0x0167, +0x21a2, +0xd168, +0x334c, +0x410c, +0x336d, +0x518d, +0x31bc, +0x1352, +0x410c, +0x3381, +0x502c, +0x31a2, +0x1351, +0x504c, +0x2969, +0x0807, +0x0cb1, +0x33fe, +0x0c1f, +0x89c5, +0x6c00, +0x196b, +0x2b5a, +0x196d, +0x2b5c, +0x196c, +0x2b5b, +0x196e, +0x2b5d, +0x196f, +0x2b60, +0x1970, +0x2b61, +0x1971, +0x2b62, +0x1972, +0x2b63, +0x8cc3, +0x33fe, +0x0c3f, +0x8000, +0x9006, +0x080e, +0x3000, +0x1913, +0x080e, +0xffff, +0xacce, +0x9006, +0x19b3, +0x0800, +0x0077, +0x540d, +0xacd4, +0x8d51, +0xd9ae, +0x01af, +0x0010, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x034b, +0x3c40, +0x0807, +0x0ce1, +0x8d52, +0x0807, +0x0ce5, +0x0c04, +0x8d64, +0x01af, +0x0012, +0x0800, +0x0348, +0x0801, +0x0348, +0x0802, +0x034d, +0x3c40, +0x0807, +0x0cf1, +0x8d52, +0x0807, +0x0cf5, +0x0c04, +0x8d64, +0x01af, +0x0011, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x034c, +0x3c40, +0x0807, +0x0d01, +0x8d52, +0x0807, +0x0d05, +0x0c24, +0x8d64, +0x01af, +0x0013, +0x0800, +0x0348, +0x0801, +0x0348, +0x0802, +0x034e, +0x3c40, +0x0807, +0x0d11, +0x8d52, +0x0807, +0x0d15, +0x0c24, +0x8d64, +0x19b3, +0x31a4, +0x0805, +0x01ee, +0x54a4, +0xad1c, +0x8d3f, +0x0805, +0x01cc, +0x54a4, +0xad21, +0x8d41, +0x0805, +0x0144, +0x54a4, +0xad26, +0x8d43, +0x0805, +0x0188, +0x54a4, +0xad2b, +0x8d46, +0x0805, +0x0100, +0x54a4, +0xad30, +0x8d48, +0x0805, +0x0111, +0x54a4, +0xad35, +0x8d4a, +0x0805, +0x0155, +0x54a4, +0xad3a, +0x8d4c, +0x0805, +0x0177, +0x54a4, +0xad4e, +0x8d4e, +0x01b3, +0x01cc, +0x01b3, +0x0144, +0x01b3, +0x0155, +0x8d4c, +0x01b3, +0x0100, +0x01b3, +0x0111, +0x01b3, +0x0155, +0x01b3, +0x0177, +0x01b3, +0x0077, +0xd1ae, +0x9006, +0x080e, +0x1fe0, +0x196e, +0x33ae, +0x31a3, +0x080e, +0x1000, +0x196e, +0x33ae, +0x31a4, +0xad5e, +0x8d62, +0x080d, +0x0100, +0x546d, +0x31a3, +0x308d, +0x9007, +0xad68, +0x308d, +0xad72, +0x8d6b, +0x308d, +0xad6b, +0x8d72, +0x3805, +0x5065, +0x31a4, +0x430d, +0xad79, +0x308d, +0x8d76, +0x3805, +0x5465, +0xbd76, +0x8d79, +0x3c02, +0x35a1, +0x8d7a, +0x384d, +0x29ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0011, +0xd1ad, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0xd1ad, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0013, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0xd1ad, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0xd1ad, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0013, +0xd1ad, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0011, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0xd1ad, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0x01ad, +0x0080, +0xd9b6, +0x9007, +0x01af, +0x0010, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0011, +0xd1ad, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0xd1ad, +0xd9b6, +0x01af, +0x0013, +0xd1ad, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x01af, +0x0010, +0xd1ad, +0xd9b6, +0x01af, +0x0011, +0xd1ad, +0xd9b6, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0014, +0xd1ad, +0xd9b6, +0x01af, +0x0012, +0x01ad, +0x0080, +0xd9b6, +0x01af, +0x0013, +0xd1ad, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0015, +0xd1ad, +0xd9b6, +0x9007, +0x0c4e, +0x1b24, +0x33ae, +0xaef2, +0x8f27, +0x038d, +0x0029, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x0c2e, +0x1b24, +0x33ae, +0xaf10, +0xd9ae, +0x01af, +0x0016, +0xd1ad, +0xd9b6, +0x01af, +0x0018, +0x01ad, +0x00ff, +0xd9b6, +0x0c2f, +0xdb24, +0x33af, +0x8f1d, +0xd9ae, +0x01af, +0x0016, +0x01ad, +0x00ff, +0xd9b6, +0x01af, +0x0018, +0xd1ad, +0xd9b6, +0x0c2f, +0xd324, +0x33af, +0xd1ae, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0xd38d, +0x8a09, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2802, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0c1f, +0xd161, +0x0162, +0x0042, +0x0163, +0x3000, +0xd164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x0169, +0xb7b7, +0x6e00, +0x197b, +0x430d, +0x31ba, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2802, +0x0183, +0x0800, +0x0184, +0x3060, +0x0185, +0x6402, +0x0160, +0x0c1f, +0xd161, +0xd162, +0x0163, +0x3000, +0xd164, +0x0165, +0xb000, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x0169, +0x4949, +0x6e00, +0x197b, +0x430d, +0x55ba, +0xb043, +0x0c0d, +0x080f, +0x00ff, +0x2be9, +0x33ae, +0x8d47, +0x2bca, +0x33df, +0x8cc6, +0x01a8, +0x0140, +0xd9b5, +0x01ac, +0xa200, +0x0180, +0x03ff, +0xd981, +0xd182, +0xd183, +0x0184, +0x4000, +0x0185, +0x2408, +0x0800, +0x0349, +0x0802, +0x034a, +0x0803, +0x01b4, +0x080e, +0x01e0, +0x1b1c, +0x33ae, +0x31a4, +0x0eed, +0x35a0, +0x3c43, +0xd9b8, +0x0816, +0x006b, +0x8071, +0xd1b5, +0x33df, +0x1b27, +0xa070, +0x863a, +0x8644, +0x7080, +0x1b27, +0xa084, +0x1b35, +0xa084, +0x0801, +0x0022, +0x3805, +0x0dcd, +0x54ad, +0xa07d, +0x8081, +0x5e20, +0x3c43, +0xd9b8, +0x8078, +0x6670, +0xb084, +0x80af, +0x380d, +0x2b53, +0x1b34, +0xa0ae, +0x308d, +0xa08b, +0x80ae, +0x3805, +0x0ced, +0x54ad, +0xa090, +0x80a3, +0x0ded, +0x54ad, +0xa094, +0x80a3, +0x0eed, +0x54ad, +0xa098, +0x80a3, +0x0fed, +0x54ad, +0xa09c, +0x80a3, +0x080d, +0x0027, +0x54ad, +0xa0a1, +0x80a3, +0x5c24, +0x31a4, +0x5a20, +0x3805, +0x0818, +0x002f, +0x54b8, +0xb0ab, +0x5e20, +0x80ae, +0x3c43, +0xd9b8, +0x8088, +0x9016, +0x5a20, +0x55a1, +0xb0b6, +0x3580, +0x318d, +0x2b53, +0x8084, +0x3c43, +0xd9b8, +0x700f, +0x8081, +0x0800, +0x0349, +0x0802, +0x034a, +0x0803, +0x01b4, +0x302d, +0xa0c4, +0x13c9, +0x80c5, +0x308c, +0x80cb, +0x3c43, +0xd9b8, +0xd1b5, +0x33df, +0x9007, +0x3804, +0x5584, +0xb0e0, +0x548c, +0x31a4, +0x0801, +0x002f, +0x308d, +0xa0d5, +0x80df, +0x5c24, +0x31a4, +0x5a20, +0x3805, +0x54a1, +0xb0dc, +0x80df, +0x3c43, +0xd9b8, +0x80d2, +0x80c6, +0x31a4, +0x0c01, +0x308d, +0xa0e5, +0x80ef, +0x5c24, +0x31a4, +0x5e20, +0x3805, +0x5425, +0xb0ec, +0x80ef, +0x3c43, +0xd9b8, +0x80e2, +0x80c6, +0x0e0e, +0x1b6f, +0x33ae, +0xa275, +0x0180, +0x03ff, +0x0181, +0xffff, +0x0182, +0x3c46, +0xd183, +0x0184, +0x7020, +0x0185, +0x2404, +0x0160, +0x0c10, +0x0161, +0x0009, +0x0162, +0x00c2, +0xd163, +0xd164, +0xd165, +0x0166, +0x792b, +0x0167, +0x21a2, +0x0168, +0x4925, +0xd169, +0x1b33, +0xa127, +0x0c21, +0x0c42, +0x13f2, +0x542c, +0xa11e, +0x0181, +0xaaaa, +0x080f, +0x3c00, +0x0182, +0x000a, +0x33af, +0x8127, +0x544c, +0xa127, +0x0181, +0x5555, +0x080f, +0x3c00, +0x0182, +0x0005, +0x33af, +0x080e, +0x8000, +0x1963, +0x33ae, +0xa131, +0x080e, +0x0fe0, +0x116e, +0x33ae, +0x8135, +0x080e, +0x0fc0, +0x116e, +0x33ae, +0x3184, +0x080e, +0x1000, +0x116e, +0x33ae, +0x3185, +0x13cc, +0x3181, +0x1351, +0x502c, +0x31ac, +0x0c23, +0x5465, +0xb148, +0x548c, +0x31a2, +0xb15c, +0x0c02, +0x815c, +0x080e, +0x8000, +0x1963, +0x33ae, +0xa150, +0x0803, +0x0080, +0x8152, +0x0803, +0x0040, +0x548c, +0x506d, +0x31a2, +0x0803, +0x0100, +0x546d, +0xb15a, +0x815c, +0x0802, +0x00ff, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x4102, +0x4302, +0x304d, +0xd9ae, +0x29ad, +0x01af, +0x0016, +0xd9b6, +0x13cd, +0x3181, +0x1352, +0x502c, +0x31ac, +0x0c23, +0x5465, +0xb17b, +0x548c, +0x31a2, +0xb18f, +0x0c02, +0x818f, +0x080e, +0x8000, +0x1963, +0x33ae, +0xa183, +0x0803, +0x0080, +0x8185, +0x0803, +0x0040, +0x548c, +0x506d, +0x31a2, +0x0803, +0x0100, +0x546d, +0xb18d, +0x818f, +0x0802, +0x00ff, +0x4102, +0x4302, +0x304d, +0x29ad, +0x01af, +0x0018, +0xd9b6, +0xd1ae, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x6647, +0x080e, +0x7fff, +0x1989, +0x33ae, +0x402d, +0x31a3, +0x080e, +0x7fff, +0x1986, +0x31a2, +0x31a4, +0x31ac, +0x080e, +0x01e0, +0x1b76, +0x33ae, +0xa1b2, +0x81b5, +0x422c, +0x5c2d, +0x81b0, +0x3181, +0x4282, +0x0c05, +0x0dee, +0x1b76, +0x33ae, +0x31b7, +0xa1be, +0x81c3, +0x5045, +0x31a5, +0x5c37, +0x31b7, +0x81bc, +0x0e0e, +0x1b76, +0x33ae, +0xa1ca, +0x50a4, +0x31a2, +0x81cc, +0x54a4, +0x31a2, +0x5022, +0x546d, +0xb1d0, +0x81d6, +0x5422, +0xb1d3, +0x81db, +0x55a3, +0xb1db, +0x81d8, +0xdb12, +0x81dc, +0x0312, +0x0002, +0x81dc, +0xd312, +0x080e, +0x0038, +0x1b77, +0x33ae, +0x31ac, +0x0cee, +0x1b77, +0x33ae, +0x31a0, +0x080e, +0x00f0, +0x1b78, +0x33ae, +0x31a1, +0x0dee, +0x1b78, +0x33ae, +0x31a2, +0x080e, +0x00e0, +0x196b, +0x33ae, +0x31a3, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x31a4, +0x4024, +0x080e, +0x003f, +0x196c, +0x33ae, +0xa1ff, +0x8201, +0x5824, +0x31a4, +0x546c, +0xb206, +0x5444, +0xb206, +0x820b, +0x5403, +0xb210, +0x5481, +0xb210, +0x820e, +0x0313, +0x0002, +0x8211, +0xdb13, +0x8211, +0xd313, +0x080e, +0x03e0, +0x1379, +0x33ae, +0x3180, +0x0fee, +0x1379, +0x33ae, +0x3181, +0x080e, +0x7f00, +0x137a, +0x33ae, +0x3184, +0x080e, +0x8000, +0x137a, +0x33ae, +0x3197, +0x080e, +0x007f, +0x137a, +0x33ae, +0x3185, +0x080e, +0x0080, +0x137a, +0x33ae, +0x3198, +0x080e, +0x03e0, +0x116d, +0x33ae, +0x3182, +0x0807, +0x0236, +0x82ab, +0x5440, +0xb239, +0x8272, +0x332d, +0xa241, +0x32ed, +0xa240, +0x5464, +0xb247, +0x8272, +0x8272, +0x32ed, +0xa244, +0x8247, +0x5483, +0xb247, +0x8272, +0x5422, +0xb24a, +0x826f, +0x332d, +0xa251, +0x330d, +0xa257, +0x54a3, +0xb257, +0x826f, +0x330d, +0xa254, +0x826f, +0x5465, +0xb257, +0x826f, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x5ced, +0xa274, +0x1bed, +0x5c8d, +0x31ac, +0x1bcc, +0x55ac, +0xa264, +0x8266, +0xb26f, +0x8266, +0x1bee, +0x5c8d, +0x31ac, +0x1bcd, +0x55ac, +0xa26d, +0x8274, +0xb26f, +0x8274, +0x0314, +0x0002, +0x8275, +0xdb14, +0x8275, +0xd314, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x1b51, +0x1352, +0x3180, +0xd9ae, +0x29ad, +0x01af, +0x0016, +0xd9b6, +0x21ad, +0x01af, +0x0018, +0xd9b6, +0xd1ae, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x196b, +0x2b5a, +0x196d, +0x2b5c, +0x196c, +0x2b5b, +0x196e, +0x2b5d, +0x196f, +0x2b60, +0x1970, +0x2b61, +0x1971, +0x2b62, +0x1972, +0x2b63, +0x13cd, +0x410c, +0x1bcc, +0x518d, +0x2bf1, +0x33df, +0x8979, +0x080e, +0x1fe0, +0x196e, +0x33ae, +0x31a3, +0x080e, +0x1000, +0x196e, +0x33ae, +0x31b9, +0xa2b7, +0x82bb, +0x080d, +0x0100, +0x546d, +0x31a3, +0x332d, +0x9007, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x01b3, +0x0177, +0xd9ae, +0x82fb, +0x01b3, +0x0155, +0x01b3, +0x0144, +0x01b3, +0x01cc, +0x01b3, +0x01ee, +0x83da, +0x01b3, +0x01cc, +0x01b3, +0x0144, +0x01b3, +0x0155, +0x01b3, +0x0177, +0x84ab, +0x01b3, +0x0155, +0x01b3, +0x0111, +0x01b3, +0x0100, +0x01b3, +0x0188, +0x859d, +0x01b3, +0x0100, +0x01b3, +0x0111, +0x01b3, +0x0155, +0x01b3, +0x0177, +0x01b3, +0x0077, +0xd1ae, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x0c1f, +0x9006, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x28c6, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0016, +0xd9b6, +0x0807, +0x0313, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2886, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0016, +0xd9b6, +0x0807, +0x032d, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x0330, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x31a1, +0x080e, +0x00ff, +0x13ef, +0x33ae, +0x3180, +0x2179, +0x2348, +0x5581, +0x43ed, +0x31b8, +0x080d, +0x00ff, +0x542d, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x0179, +0x30ad, +0x0807, +0x034c, +0x0c04, +0x86b5, +0x080e, +0x00ff, +0x1bef, +0x33ae, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0358, +0x866e, +0x1b48, +0x080f, +0x00ff, +0x2bef, +0x33af, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0179, +0x0807, +0x0366, +0x868a, +0x0807, +0x036a, +0x0c04, +0x869c, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x14c6, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0018, +0xd9b6, +0x0807, +0x0382, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1486, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0018, +0xd9b6, +0x0807, +0x039c, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x039f, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x31a1, +0x080e, +0x00ff, +0x13f0, +0x33ae, +0x3180, +0x217a, +0x2348, +0x5581, +0x43ed, +0x31b8, +0x080d, +0x00ff, +0x542d, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x017a, +0x30ad, +0x0807, +0x03bb, +0x0c04, +0x86b5, +0x080e, +0x00ff, +0x1bf0, +0x33ae, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x03c7, +0x866e, +0x1b48, +0x080f, +0x00ff, +0x2bf0, +0x33af, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x017a, +0x0807, +0x03d5, +0x868a, +0x0807, +0x03d9, +0x0c04, +0x869c, +0x82cb, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x28c6, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0010, +0xd9b6, +0x0807, +0x03f2, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2886, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0010, +0xd9b6, +0x0807, +0x040c, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x040f, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x134b, +0x3180, +0x2173, +0x2348, +0x558d, +0x43ed, +0x31b8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00ff, +0x55a1, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x0173, +0x30ad, +0x0807, +0x042a, +0x0c04, +0x86b5, +0x1b4b, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0433, +0x866e, +0x1b48, +0x2b4b, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0173, +0x0807, +0x043e, +0x868a, +0x0807, +0x0442, +0x0c04, +0x869c, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x14c6, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0012, +0xd9b6, +0x0807, +0x045a, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1486, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0012, +0xd9b6, +0x0807, +0x0474, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x0477, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x134d, +0x3180, +0x2175, +0x2348, +0x558d, +0x43ed, +0x31b8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00ff, +0x55a1, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x0175, +0x30ad, +0x0807, +0x0492, +0x0c04, +0x86b5, +0x1b4d, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x049b, +0x866e, +0x1b48, +0x2b4d, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0175, +0x0807, +0x04a6, +0x868a, +0x0807, +0x04aa, +0x0c04, +0x869c, +0x82d4, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2846, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0016, +0xd9b6, +0x0807, +0x04c3, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2806, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0016, +0xd9b6, +0x0807, +0x04dd, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x04e0, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x080e, +0xff00, +0x13ef, +0x33ae, +0x3180, +0x2179, +0x2348, +0x558d, +0x43ed, +0x31b8, +0x080d, +0x00ff, +0x542d, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x0179, +0x30ad, +0x0807, +0x04fb, +0x0c24, +0x86b5, +0x080e, +0xff00, +0x1bef, +0x33ae, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0507, +0x866e, +0x1b48, +0x080f, +0xff00, +0x2bef, +0x33af, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0179, +0x0807, +0x0515, +0x868a, +0x0807, +0x0519, +0x0c24, +0x869c, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1446, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0018, +0xd9b6, +0x0807, +0x0531, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1406, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0018, +0xd9b6, +0x0807, +0x054b, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x054e, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x31a1, +0x080e, +0xff00, +0x13f0, +0x33ae, +0x3180, +0x217a, +0x2348, +0x5581, +0x43ed, +0x31b8, +0x080d, +0x00ff, +0x542d, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x017a, +0x30ad, +0x0807, +0x056a, +0x0c24, +0x86b5, +0x080e, +0xff00, +0x1bf0, +0x33ae, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x0576, +0x866e, +0x1b48, +0x080f, +0xff00, +0x2bf0, +0x33af, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x017a, +0x0807, +0x0584, +0x868a, +0x0807, +0x0588, +0x0c24, +0x869c, +0x080e, +0xff00, +0x1bef, +0x080e, +0x00ff, +0x13ef, +0x33ae, +0x518d, +0x422d, +0x2b51, +0x080e, +0xff00, +0x1bf0, +0x080e, +0x00ff, +0x13f0, +0x33ae, +0x518d, +0x422d, +0x2b52, +0x82dd, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2846, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0011, +0xd9b6, +0x0807, +0x05b5, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0xaaaa, +0x0182, +0x2806, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0011, +0xd9b6, +0x0807, +0x05cf, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x05d2, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x134c, +0x3180, +0x2174, +0x2348, +0x558d, +0x43ed, +0x31b8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00ff, +0x55a1, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x0174, +0x30ad, +0x0807, +0x05ed, +0x0c24, +0x86b5, +0x1b4c, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x05f6, +0x866e, +0x1b48, +0x2b4c, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0174, +0x0807, +0x0601, +0x868a, +0x0807, +0x0605, +0x0c24, +0x869c, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1446, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0013, +0xd9b6, +0x0807, +0x061d, +0x33fe, +0x0c1f, +0x0c63, +0x864b, +0x19ad, +0x2b47, +0x0180, +0x7d00, +0x0181, +0x5555, +0x0182, +0x1406, +0xd183, +0x0184, +0x2c00, +0x0185, +0x6408, +0x0800, +0x01ad, +0x01ad, +0x0080, +0x01af, +0x0013, +0xd9b6, +0x0807, +0x0637, +0x33fe, +0x0c1f, +0x0c43, +0x864b, +0x0807, +0x063a, +0x868a, +0x31a5, +0x0801, +0x0020, +0x5023, +0x134e, +0x3180, +0x2176, +0x2348, +0x558d, +0x43ed, +0x31b8, +0x0801, +0x0020, +0x5061, +0x0801, +0x00ff, +0x55a1, +0x55ac, +0x43ed, +0x31b9, +0x0800, +0x0176, +0x30ad, +0x0807, +0x0655, +0x0c24, +0x86b5, +0x1b4e, +0x2b48, +0x0800, +0x0348, +0x0801, +0x0347, +0x0807, +0x065e, +0x866e, +0x1b48, +0x2b4e, +0x0800, +0x0348, +0x0801, +0x0347, +0x0802, +0x0176, +0x0807, +0x0669, +0x868a, +0x0807, +0x066d, +0x0c24, +0x869c, +0x82e6, +0x19ad, +0x31a4, +0x3825, +0x5085, +0x31a5, +0x4225, +0x3c01, +0x338d, +0x55a5, +0xb67b, +0x330d, +0xa67e, +0x8689, +0xa682, +0x380d, +0x8689, +0x5e20, +0xb689, +0x3580, +0x8689, +0x332d, +0xa685, +0x8689, +0x5a20, +0x31a2, +0x430d, +0xa680, +0x9007, +0x080e, +0x1fe0, +0x196e, +0x33ae, +0x31a3, +0x080e, +0x1000, +0x196e, +0x33ae, +0x31a4, +0xa696, +0x869a, +0x080d, +0x0100, +0x546d, +0x31a3, +0x308d, +0x9007, +0xa6a0, +0x308d, +0xa6aa, +0x86a3, +0x308d, +0xa6a3, +0x86aa, +0x3805, +0x5065, +0x31a4, +0x430d, +0xa6b1, +0x308d, +0x86ae, +0x3805, +0x5465, +0xb6ae, +0x86b1, +0x3c02, +0x35a1, +0x86b2, +0x384d, +0x29ad, +0xd9b6, +0x9007, +0xa6b9, +0x308d, +0xa6c3, +0x86bc, +0x308d, +0xa6bc, +0x86c3, +0x3805, +0x5065, +0x31a4, +0x430d, +0xa6c9, +0x308d, +0x86c7, +0x3805, +0x5465, +0xb6c7, +0x86c9, +0x31bc, +0x86ca, +0x30bc, +0x9007, +0x0180, +0x00ff, +0x0181, +0xaaaa, +0x0182, +0x2806, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x0160, +0x0c07, +0xd161, +0x0162, +0x00c6, +0x0163, +0x1000, +0xd164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x1b38, +0xa712, +0x1bcc, +0x31a1, +0x1b51, +0x502d, +0x31a1, +0x0807, +0x06f0, +0x8df4, +0xa6f3, +0x5061, +0x86f4, +0x5461, +0xb6f6, +0x86fe, +0x31a1, +0x430d, +0xa6fb, +0x302d, +0x86ff, +0x080d, +0x00ff, +0x86ff, +0x0c0d, +0x080f, +0x00ff, +0x2969, +0x33af, +0x1bcd, +0x31a1, +0x1b52, +0x502d, +0x31a1, +0x080f, +0xff00, +0x2969, +0x33af, +0x6c00, +0x080e, +0xff00, +0x197b, +0x33ae, +0x31b8, +0x0180, +0x00ff, +0x0162, +0x0084, +0x0165, +0xb000, +0x1b38, +0xa73b, +0x1b51, +0x31a1, +0x13cc, +0x0807, +0x0720, +0x8df4, +0xa724, +0x5061, +0x558d, +0x8726, +0x506c, +0x55a1, +0x31a1, +0xb729, +0x8730, +0x430d, +0xa72d, +0x302d, +0x8731, +0x080d, +0x00ff, +0x8731, +0x0c0d, +0x080f, +0x00ff, +0x2969, +0x33af, +0x6c00, +0x080e, +0xff00, +0x197b, +0x33ae, +0x31b9, +0x0180, +0x00ff, +0x0181, +0x5555, +0x0182, +0x1406, +0x0162, +0x00c6, +0x0163, +0x2000, +0x0165, +0x3000, +0x080f, +0x03ff, +0xd960, +0x33af, +0x1b38, +0xa759, +0x1352, +0x1b51, +0x55b8, +0x518d, +0x410d, +0x2969, +0x6c00, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x31ba, +0x0180, +0x00ff, +0x0162, +0x0084, +0x0165, +0xb000, +0x080f, +0x03ff, +0xd960, +0x33af, +0x1b38, +0xa793, +0x1352, +0x1b51, +0x55b9, +0x51ac, +0x410d, +0x2969, +0x6c00, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x31bb, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x5738, +0x424d, +0x532d, +0xd9ae, +0x29ad, +0x01af, +0x0016, +0xd9b6, +0x577a, +0x424d, +0x536d, +0x29ad, +0x01af, +0x0018, +0xd9b6, +0xd1ae, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x0180, +0x01ff, +0x0181, +0xffff, +0x0182, +0x3c86, +0xd183, +0x0160, +0x0c10, +0x0161, +0x0009, +0x0162, +0x00c2, +0xd163, +0xd165, +0x0166, +0x792b, +0x0168, +0x4925, +0x1b38, +0xa82d, +0x0807, +0x07ad, +0x33fe, +0x0c1f, +0x89c5, +0x1959, +0x1959, +0x31b6, +0x0807, +0x07b3, +0x8931, +0x081c, +0x0349, +0x0ea1, +0x0c17, +0x3b85, +0x080d, +0x002f, +0x5c2d, +0x54ad, +0xb7be, +0x87f9, +0x302d, +0xa7c1, +0x87f9, +0x3b85, +0x0ced, +0x54ad, +0xa7c6, +0x87db, +0x0ded, +0x54ad, +0xa7ca, +0x87db, +0x0eed, +0x54ad, +0xa7ce, +0x87db, +0x0fed, +0x54ad, +0xa7d2, +0x87db, +0x080d, +0x0027, +0x54ad, +0xa7d7, +0x87db, +0x5c21, +0x31a1, +0x5837, +0x31b7, +0x5a3c, +0x1b4a, +0x29b4, +0xd9b8, +0x1959, +0x1959, +0x31a2, +0x5444, +0xb7e5, +0x87f9, +0x5462, +0xb7e8, +0x87f9, +0x6620, +0x080e, +0x7fff, +0x1988, +0x33ae, +0x31a2, +0x4022, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x31a5, +0x4025, +0x426d, +0x55a5, +0x55a2, +0xb7b7, +0x32e0, +0x3b81, +0x1b47, +0x55a1, +0xa7ff, +0x8807, +0xb802, +0x5a3c, +0x8803, +0x5e3c, +0x1b4a, +0x29b4, +0xd9b8, +0x87fa, +0x0c17, +0x1959, +0x1959, +0x31a2, +0x5444, +0xb80e, +0x8810, +0x5462, +0xb813, +0x0807, +0x0813, +0x8917, +0x1959, +0x1959, +0x31a2, +0x5444, +0xb81f, +0x5e3c, +0x1b4a, +0x29b4, +0xd9b8, +0x5e3c, +0x5857, +0x8827, +0x5462, +0xb82d, +0x5a3c, +0x1b4a, +0x29b4, +0xd9b8, +0x5a3c, +0x5840, +0x1b4a, +0x29b4, +0xd9b8, +0x0807, +0x082d, +0x8917, +0x0180, +0x01ff, +0x0182, +0x3cc6, +0x1b38, +0xa8bf, +0x0807, +0x0838, +0x33fe, +0x0c1f, +0x89c5, +0x0c2f, +0xdb75, +0x33af, +0x0c6f, +0x010d, +0x0002, +0x33af, +0xd3a6, +0x03a6, +0x000a, +0x5738, +0x424d, +0x55b8, +0xd9ae, +0x29ad, +0x01af, +0x0016, +0xd9b6, +0x577a, +0x424d, +0x55ba, +0x29ad, +0x01af, +0x0018, +0xd9b6, +0xd1ae, +0xd3a6, +0x7000, +0x0c6f, +0xd10d, +0x33af, +0x0c2f, +0xd375, +0x33af, +0x081c, +0x0349, +0x0ea1, +0x3b85, +0x0c0d, +0x582d, +0x55a5, +0xb863, +0x889c, +0x302d, +0xa866, +0x889c, +0x3b85, +0x0d0d, +0x54ad, +0xa86b, +0x8881, +0x0e0d, +0x54ad, +0xa86f, +0x8881, +0x0f0d, +0x54ad, +0xa873, +0x8881, +0x080d, +0x0020, +0x54ad, +0xa878, +0x8881, +0x080d, +0x0028, +0x54ad, +0xa87d, +0x8881, +0x5c21, +0x31a1, +0x5837, +0x31b7, +0x5e3c, +0x1b4a, +0x29b4, +0xd9b8, +0x1959, +0x1959, +0x31a2, +0x5444, +0xb88b, +0x889c, +0x5462, +0xb88e, +0x889c, +0x6620, +0x080e, +0x7fff, +0x1988, +0x33ae, +0x31a2, +0x4022, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x426d, +0x544d, +0xb85d, +0x32ed, +0x300d, +0x080f, +0xff00, +0x2bea, +0x33af, +0x32ed, +0x080f, +0x00ff, +0x2bea, +0x33af, +0x56e0, +0xb8b5, +0x5417, +0x5c2d, +0x422d, +0x31a0, +0x5c6d, +0xb8b3, +0x0c6c, +0x540c, +0x31ac, +0x88b9, +0x0c0c, +0x88be, +0x582d, +0x422d, +0x586d, +0x31ac, +0x5d2d, +0xb8bc, +0x88be, +0x0d2c, +0x88be, +0x8998, +0x1b38, +0xa8d3, +0x3b8d, +0x331c, +0x31b8, +0x2b7b, +0x0807, +0x08c9, +0x32cd, +0x8931, +0x1959, +0x1959, +0x31a2, +0x5482, +0xb8d0, +0x5462, +0xb8d3, +0x0807, +0x08d3, +0x8917, +0x0807, +0x08d6, +0x8df4, +0x31a2, +0xa8e0, +0x573c, +0xb8dc, +0x462d, +0x88dd, +0x422d, +0x532d, +0x546d, +0x88e7, +0x573c, +0xb8e4, +0x462d, +0x88e5, +0x422d, +0x532d, +0x506d, +0x31a1, +0xb8eb, +0x0c0d, +0x88f1, +0x430d, +0xa8ef, +0x302d, +0x88f1, +0x080d, +0x00ff, +0x080f, +0x00ff, +0x2be8, +0x33af, +0x304d, +0xa8ff, +0x577a, +0xb8fb, +0x462d, +0x88fc, +0x422d, +0x536d, +0x546d, +0x8906, +0x577a, +0xb903, +0x462d, +0x8904, +0x422d, +0x536d, +0x506d, +0x31a1, +0xb90a, +0x0c0d, +0x8910, +0x430d, +0xa90e, +0x302d, +0x8910, +0x080d, +0x00ff, +0x080f, +0xff00, +0x2be8, +0x33af, +0x0c1f, +0x33fe, +0x88ec, +0x32cd, +0x2959, +0x080f, +0x0020, +0xd906, +0x33af, +0x0e0f, +0xd106, +0x33af, +0x0c8e, +0x1919, +0x33ae, +0xa920, +0x0e0f, +0xd906, +0x33af, +0x0c8e, +0x1919, +0x33ae, +0xa92c, +0x8927, +0x080f, +0x0020, +0xd106, +0x33af, +0x9007, +0x31a0, +0x0803, +0x1000, +0x546d, +0xb938, +0x0c03, +0x8939, +0x31a3, +0x0804, +0x1000, +0x5080, +0x31a0, +0x0804, +0x4000, +0x55a4, +0xb944, +0x0804, +0x4000, +0x8945, +0x3004, +0x9007, +0x1b53, +0x31a5, +0x3181, +0x302d, +0xa94c, +0x8965, +0x0ced, +0x54ad, +0xa950, +0x8963, +0x0ded, +0x54ad, +0xa954, +0x8963, +0x0eed, +0x54ad, +0xa958, +0x8963, +0x0fed, +0x54ad, +0xa95c, +0x8963, +0x080d, +0x0027, +0x54ad, +0xa961, +0x8963, +0x5c21, +0x31a1, +0x5825, +0x8949, +0x1b49, +0x31a0, +0x54ad, +0xb981, +0x5405, +0x31a1, +0x081c, +0x0349, +0x3b85, +0x080d, +0x002f, +0x5c2d, +0x54ad, +0xb974, +0x897e, +0x302d, +0xa977, +0x897e, +0x5c21, +0x31a1, +0x5a3c, +0x1b4a, +0x29b4, +0xd9b8, +0x896d, +0x0c1f, +0x33fe, +0x8721, +0x54a0, +0x31a1, +0x081c, +0x0349, +0x3b85, +0x0c0d, +0x582d, +0x55a5, +0xb98b, +0x8995, +0x302d, +0xa98e, +0x8995, +0x5c21, +0x31a1, +0x5e3c, +0x1b4a, +0x29b4, +0xd9b8, +0x8985, +0x0c1f, +0x33fe, +0x8721, +0x1b53, +0x31a5, +0x3181, +0x302d, +0xa99e, +0x89b7, +0x0ced, +0x54ad, +0xa9a2, +0x89b5, +0x0ded, +0x54ad, +0xa9a6, +0x89b5, +0x0eed, +0x54ad, +0xa9aa, +0x89b5, +0x0fed, +0x54ad, +0xa9ae, +0x89b5, +0x080d, +0x0027, +0x54ad, +0xa9b3, +0x89b5, +0x5c21, +0x31a1, +0x5825, +0x899b, +0x1b49, +0x31a0, +0x54ad, +0xb9d1, +0x5405, +0x31a1, +0x081c, +0x0349, +0x3b85, +0x080d, +0x002f, +0x5c2d, +0x54ad, +0xb9c6, +0x89d0, +0x302d, +0xa9c9, +0x89d0, +0x5c21, +0x31a1, +0x5a3c, +0x1b4a, +0x29b4, +0xd9b8, +0x89bf, +0x88bf, +0x54a0, +0x31a1, +0x081c, +0x0349, +0x3b85, +0x0c0d, +0x582d, +0x55a5, +0xb9db, +0x89e5, +0x302d, +0xa9de, +0x89e5, +0x5c21, +0x31a1, +0x5e3c, +0x1b4a, +0x29b4, +0xd9b8, +0x89d5, +0x88bf, +0x0180, +0x00ff, +0x0181, +0xaaaa, +0x0182, +0x2806, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x300d, +0x080f, +0x03e0, +0x2982, +0x33af, +0x0fef, +0x0182, +0x0006, +0x33af, +0x080f, +0x0800, +0xd183, +0x33af, +0x0160, +0x0c07, +0xd161, +0x0162, +0x00c6, +0x0163, +0x1000, +0xd164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x302d, +0x080f, +0xf000, +0x2965, +0x33af, +0x304d, +0x080f, +0x03ff, +0x2960, +0x33af, +0x306d, +0xaa4b, +0x300d, +0x5ccd, +0xaa1e, +0x8a21, +0x300d, +0x5c4d, +0xaa33, +0x1b51, +0x13cc, +0x518d, +0x31b7, +0x430d, +0xaa2b, +0x32ed, +0xba2d, +0x0c17, +0x8a2d, +0x0817, +0x00ff, +0x32ed, +0x080f, +0x00ff, +0x2969, +0x33af, +0x8a50, +0x300d, +0x5c8d, +0xaa37, +0x8a39, +0x300d, +0xaa50, +0x1b51, +0x13cc, +0x558d, +0x31b7, +0xba40, +0x0c17, +0x8a45, +0x430d, +0xaa43, +0x8a45, +0x0817, +0x00ff, +0x32ed, +0x080f, +0x00ff, +0x2969, +0x33af, +0x8a50, +0x308d, +0x080f, +0x00ff, +0x2969, +0x33af, +0x6c00, +0x080e, +0xff00, +0x197b, +0x33ae, +0x0c1f, +0x9007, +0x0180, +0x00ff, +0x0181, +0x5555, +0x0182, +0x1406, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x300d, +0x080f, +0x03e0, +0x2982, +0x33af, +0x0fef, +0x0182, +0x0006, +0x33af, +0x080f, +0x0800, +0xd183, +0x33af, +0x0160, +0x0c07, +0xd161, +0x0162, +0x00c6, +0x0163, +0x2000, +0xd164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x302d, +0x080f, +0xf000, +0x2965, +0x33af, +0x304d, +0x080f, +0x03ff, +0x2960, +0x33af, +0x306d, +0xaabc, +0x300d, +0x5ccd, +0xaa8f, +0x8a92, +0x300d, +0x5c4d, +0xaaa4, +0x1b52, +0x13cd, +0x518d, +0x31b7, +0x430d, +0xaa9c, +0x32ed, +0xba9e, +0x0c17, +0x8a9e, +0x0817, +0x00ff, +0x32ed, +0x080f, +0xff00, +0x2969, +0x33af, +0x8ac1, +0x300d, +0x5c8d, +0xaaa8, +0x8aaa, +0x300d, +0xaac1, +0x1b52, +0x13cd, +0x558d, +0x31b7, +0xbab1, +0x0c17, +0x8ab6, +0x430d, +0xaab4, +0x8ab6, +0x0817, +0x00ff, +0x32ed, +0x080f, +0xff00, +0x2969, +0x33af, +0x8ac1, +0x308d, +0x080f, +0xff00, +0x2969, +0x33af, +0x6c00, +0x080e, +0x00ff, +0x197b, +0x33ae, +0x0c1f, +0x9007, +0x0800, +0x00f5, +0x5418, +0xbacf, +0x5419, +0xbacf, +0x8ad5, +0x080f, +0x1c00, +0x03f6, +0x0003, +0x33af, +0x8ae3, +0x541a, +0xbade, +0x541b, +0xbade, +0x080f, +0x1c00, +0xd3f6, +0x33af, +0x8ae3, +0x080f, +0x1c00, +0x03f6, +0x0005, +0x33af, +0x0800, +0x00f5, +0x5418, +0xbaea, +0x541a, +0xbaea, +0x8af3, +0x5419, +0xbaf3, +0x541b, +0xbaf3, +0x080f, +0x6000, +0xdbf6, +0x33af, +0x8b0f, +0x5419, +0xbaf8, +0x541b, +0xbaf8, +0x8b02, +0x5418, +0xbb02, +0x541a, +0xbb02, +0x080f, +0x6000, +0x03f6, +0x0002, +0x33af, +0x8b0f, +0x571a, +0xbb06, +0x3302, +0x8b07, +0x3342, +0x573b, +0xbb0b, +0x3323, +0x8b0c, +0x3363, +0x5443, +0xbafc, +0x8aee, +0x0c1f, +0x9007, +0x080e, +0x6000, +0x1bf6, +0x33ae, +0x5c2d, +0xab1c, +0x1352, +0x5379, +0x422d, +0x558d, +0x8b27, +0x080e, +0x6000, +0x1bf6, +0x33ae, +0x5c4d, +0xab27, +0x1351, +0x5358, +0x422d, +0x558d, +0x8b27, +0xbb2c, +0x410d, +0x430d, +0x31b7, +0x8b32, +0x31b7, +0x430d, +0xab30, +0x8b32, +0x0817, +0x00ff, +0x0c1f, +0x9007, +0x080e, +0x00ff, +0x196b, +0x33ae, +0x42ad, +0x0cef, +0x290b, +0x33af, +0x080e, +0x03e0, +0x196d, +0x33ae, +0x080f, +0xf800, +0x290b, +0x33af, +0x080e, +0x1c00, +0x196d, +0x33ae, +0x0cef, +0x290c, +0x33af, +0x080e, +0x03c0, +0x196c, +0x33ae, +0x31a0, +0x080f, +0x0078, +0x290b, +0x33af, +0x080e, +0x003f, +0x196c, +0x33ae, +0xab5a, +0x8b5c, +0x5820, +0x31a0, +0x300d, +0x080f, +0x0780, +0x290b, +0x33af, +0x32ed, +0x080f, +0x07f8, +0x290c, +0x33af, +0x080e, +0x0fff, +0x196f, +0x33ae, +0x42ad, +0x080f, +0x007f, +0x291a, +0x33af, +0x080e, +0x0fff, +0x1970, +0x33ae, +0x42ad, +0x080f, +0x3f80, +0x291a, +0x33af, +0x080e, +0x0fff, +0x1971, +0x33ae, +0x42ad, +0x080f, +0x007f, +0x291b, +0x33af, +0x080e, +0x0fff, +0x1972, +0x33ae, +0x42ad, +0x080f, +0x3f80, +0x291b, +0x33af, +0x080f, +0x0800, +0xd90c, +0x33af, +0x0c4f, +0xd90d, +0x33af, +0x0306, +0x000c, +0x0c2e, +0x1919, +0x33ae, +0xab98, +0x8b93, +0x0306, +0x0008, +0x080f, +0x0800, +0xd10c, +0x33af, +0x0c4f, +0xd10d, +0x33af, +0x0c1f, +0x9007, +0x080e, +0x0020, +0x1b6f, +0x33ae, +0xabf4, +0x8bf7, +0x1b53, +0x31a1, +0x1b49, +0x31b7, +0x0802, +0x0349, +0x0c25, +0x0807, +0x0bb3, +0x8c0f, +0x0180, +0x003f, +0x0181, +0xaaaa, +0x0182, +0x2802, +0x0183, +0x0800, +0x0184, +0x7060, +0x0185, +0x2402, +0x0807, +0x0bc4, +0x33fe, +0x0c1f, +0x89c5, +0x0160, +0x0c07, +0xd161, +0x0162, +0x0042, +0x0163, +0x3000, +0xd164, +0x0165, +0x3000, +0x0166, +0x7828, +0x0167, +0x21a2, +0xd168, +0x330d, +0x410d, +0x530d, +0x2969, +0x6e00, +0x197b, +0x430d, +0x31ba, +0xd162, +0x0165, +0xb000, +0x332d, +0x410d, +0x532d, +0x2969, +0x6e00, +0x197b, +0x430d, +0x31bb, +0x577a, +0xbbe9, +0x0c0d, +0x080f, +0x00ff, +0x2be9, +0x33ae, +0x32e1, +0x0c05, +0x0802, +0x0349, +0x0807, +0x0bf4, +0x8c0f, +0x33fe, +0x0c1f, +0x87ea, +0x1bf2, +0x5c4d, +0xabfd, +0x1b52, +0x13cd, +0x8bff, +0x1b51, +0x13cc, +0x31a1, +0x518d, +0x31a0, +0x430d, +0xac06, +0x300d, +0x8c08, +0x080d, +0x00ff, +0x31b8, +0x302d, +0x558d, +0xbc0d, +0x0c0d, +0x31b9, +0x8ba9, +0x1b49, +0x31a0, +0x30ad, +0xac18, +0x5401, +0xac16, +0x8c24, +0xbc1d, +0x8c24, +0x5420, +0xac1b, +0x8c24, +0xbc1f, +0x8c24, +0x5a22, +0x8c20, +0x5e22, +0x1b4a, +0x29b4, +0xd9b8, +0x8c0f, +0x9007, +0x080f, +0xff00, +0xd3e9, +0x33af, +0x080e, +0x00ff, +0x13e8, +0x33ae, +0x0d4d, +0x518d, +0x31a2, +0x080e, +0xff00, +0x13e8, +0x33ae, +0x0d4d, +0x518d, +0x31a5, +0x0807, +0x0c3a, +0x8df4, +0xac40, +0x5062, +0x31a2, +0x5065, +0x31a5, +0x8c48, +0x5462, +0x31a2, +0xbc44, +0x0c02, +0x5465, +0x31a5, +0xbc48, +0x0c05, +0x304d, +0x430d, +0xac4c, +0x8c4e, +0x0802, +0x00ff, +0x30ad, +0x430d, +0xac52, +0x8c54, +0x0805, +0x00ff, +0x0807, +0x0c57, +0x8ccb, +0x0800, +0x0349, +0x0802, +0x034a, +0x0803, +0x01b4, +0x3818, +0x0c01, +0x0ca4, +0x0c37, +0x0807, +0x0c64, +0x8d18, +0x080f, +0x03e0, +0x0182, +0x0006, +0x33af, +0x0807, +0x0c6c, +0x8cd9, +0x080e, +0x00ff, +0x13e8, +0x33ae, +0x0d4d, +0x55ac, +0x31a2, +0x080e, +0xff00, +0x13e8, +0x33ae, +0x0d4d, +0x55ac, +0x31a5, +0x0807, +0x0c7d, +0x8df4, +0xac83, +0x5062, +0x31a2, +0x5065, +0x31a5, +0x8c8b, +0x5462, +0x31a2, +0xbc87, +0x0c02, +0x5465, +0x31a5, +0xbc8b, +0x0c05, +0x0c0d, +0x304d, +0x43ed, +0xac96, +0x304d, +0x430d, +0xac93, +0x8c97, +0x0802, +0x00ff, +0x8c97, +0x0c02, +0x30ad, +0x43ed, +0xaca1, +0x30ad, +0x430d, +0xac9e, +0x8ca2, +0x0805, +0x00ff, +0x8ca2, +0x0c05, +0x0807, +0x0ca5, +0x8ccb, +0x0800, +0x0349, +0x0802, +0x034a, +0x0803, +0x01b4, +0x3818, +0x0801, +0x002f, +0x0d44, +0x0c17, +0x0807, +0x0cb3, +0x8d18, +0x080f, +0x03e0, +0x0182, +0x0004, +0x33af, +0x0807, +0x0cbb, +0x8cd9, +0x0800, +0x0349, +0x0802, +0x034a, +0x0803, +0x01b4, +0x3818, +0x0c01, +0x0ca4, +0x0c37, +0x0807, +0x0cc8, +0x8d18, +0x33fe, +0x0c1f, +0x896a, +0xd9ae, +0x01af, +0x0016, +0x304d, +0x29ad, +0xd9b6, +0x01af, +0x0018, +0x30ad, +0x29ad, +0xd9b6, +0x700f, +0xd1ae, +0x9007, +0x080f, +0x7fff, +0x0180, +0x07cf, +0x33af, +0x0181, +0xffff, +0x0fef, +0x0182, +0x0006, +0x080f, +0x4000, +0xd984, +0x080f, +0x1c00, +0x0184, +0x0004, +0x080f, +0x0020, +0xd984, +0x0f0f, +0xd184, +0x33af, +0x080f, +0x03c0, +0xd184, +0x33af, +0x080f, +0x0800, +0xd183, +0x33af, +0x0e81, +0x6660, +0x080e, +0x7fff, +0x198a, +0x33ae, +0x31a2, +0x080e, +0x7fff, +0x1986, +0x33ae, +0x544d, +0x31a2, +0x080e, +0xff00, +0x1be9, +0x33ae, +0x504d, +0x31a2, +0x430d, +0xad0e, +0x8d10, +0x0802, +0x00ff, +0x304d, +0x080f, +0xff00, +0x2be9, +0x33af, +0x5c21, +0xacf9, +0x9007, +0x3805, +0x0ced, +0x52ed, +0x54ad, +0xad1e, +0x8d39, +0x0ded, +0x52ed, +0x54ad, +0xad23, +0x8d39, +0x0eed, +0x52ed, +0x54ad, +0xad28, +0x8d39, +0x0fed, +0x52ed, +0x54ad, +0xad2d, +0x8d39, +0x080d, +0x0027, +0x52ed, +0x54ad, +0xad33, +0x8d39, +0x308d, +0xad36, +0x8d46, +0x5c24, +0x31a4, +0x8d3e, +0x32ed, +0xad3e, +0x308d, +0xad3e, +0x8d46, +0x32ed, +0xad42, +0x5a20, +0x8d43, +0x5e20, +0x3c43, +0xd9b8, +0x8d18, +0x9007, +0x1959, +0x1959, +0x31a1, +0x0800, +0x3000, +0x5401, +0xbd54, +0x0800, +0x1000, +0x5420, +0xbd54, +0x0c25, +0x8d5c, +0x1b5e, +0xad59, +0x0807, +0x0d59, +0x8917, +0x0c05, +0x0c04, +0x8dec, +0x080e, +0x00ff, +0x1be9, +0x33ae, +0x31a0, +0x080e, +0xff00, +0x13ea, +0x080e, +0x00ff, +0x1bea, +0x33ae, +0x51ac, +0xbd6c, +0x0c01, +0x8d73, +0x31a1, +0x0804, +0x002a, +0x55a4, +0xbd73, +0x0801, +0x002a, +0x302d, +0x080f, +0x00ff, +0x2beb, +0x33af, +0x0807, +0x0d7b, +0x8df4, +0xad7e, +0x0c03, +0x8d7f, +0x4223, +0x080e, +0x0fe0, +0x196f, +0x33ae, +0x31a2, +0x0804, +0x0040, +0x5482, +0xbd89, +0x0c0d, +0x31a2, +0x4222, +0x5062, +0x55a0, +0x31a0, +0x0c04, +0x0c2e, +0x1beb, +0xad93, +0x8d96, +0x300d, +0x51a4, +0x31a4, +0x0c4e, +0x1beb, +0xad9a, +0x8d9e, +0x300d, +0x442d, +0x51a4, +0x31a4, +0x0c8e, +0x1beb, +0xada2, +0x8da6, +0x300d, +0x444d, +0x51a4, +0x31a4, +0x0d0e, +0x1beb, +0xadaa, +0x8dae, +0x300d, +0x446d, +0x51a4, +0x31a4, +0x0e0e, +0x1beb, +0xadb2, +0x8db6, +0x300d, +0x448d, +0x51a4, +0x31a4, +0x080e, +0x0020, +0x1beb, +0xadbb, +0x8dbf, +0x300d, +0x44ad, +0x51a4, +0x31a4, +0x33ae, +0x308d, +0x46ad, +0x31a4, +0x080e, +0xff00, +0x1be9, +0x33ae, +0x31a1, +0x1b5e, +0xaddc, +0x0ca0, +0x5401, +0xbdd0, +0x0805, +0x0060, +0x8ddd, +0x0d40, +0x5401, +0xbdd6, +0x0805, +0x0040, +0x8ddd, +0x0de0, +0x5401, +0xbddc, +0x0805, +0x0020, +0x8ddd, +0x0c05, +0x5085, +0x31a4, +0x0c0d, +0x308d, +0x43ed, +0xade4, +0x8de6, +0x0c04, +0x8dec, +0x308d, +0x430d, +0xadea, +0x8dec, +0x0804, +0x00ff, +0x1b5e, +0xadf2, +0x308d, +0x33fe, +0x0c1f, +0x8972, +0x308d, +0x8048, +0x080e, +0x1fe0, +0x196e, +0x33ae, +0x31a3, +0x080e, +0x1000, +0x196e, +0x33ae, +0x31a4, +0xae00, +0x8e04, +0x080d, +0x0100, +0x546d, +0x31a3, +0x308d, +0x9007, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000, +0x0000 diff --git a/bsp/rockchip/dm/pin/Kconfig b/bsp/rockchip/dm/pin/Kconfig new file mode 100755 index 00000000000..725a0de572a --- /dev/null +++ b/bsp/rockchip/dm/pin/Kconfig @@ -0,0 +1,4 @@ +config RT_PIN_ROCKCHIP + bool "Rockchip GPIO support" + depends on RT_USING_OFW + default y diff --git a/bsp/rockchip/dm/pin/SConscript b/bsp/rockchip/dm/pin/SConscript new file mode 100755 index 00000000000..b375f5b91c4 --- /dev/null +++ b/bsp/rockchip/dm/pin/SConscript @@ -0,0 +1,13 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/pin'] + +if GetDepend(['RT_PIN_ROCKCHIP']): + src += ['pin-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/pin/pin-rockchip.c b/bsp/rockchip/dm/pin/pin-rockchip.c new file mode 100755 index 00000000000..a2f12e11c49 --- /dev/null +++ b/bsp/rockchip/dm/pin/pin-rockchip.c @@ -0,0 +1,596 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include +#include + +#include "dev_pin_dm.h" +#include "pinctrl-rockchip.h" + +#define GPIO_TYPE_V1 0 +#define GPIO_TYPE_V2 0x01000c2b +#define GPIO_TYPE_V2_1 0x0101157c + +static const struct rockchip_gpio_regs _gpio_regs_v1 = +{ + .port_dr = 0x00, + .port_ddr = 0x04, + .int_en = 0x30, + .int_mask = 0x34, + .int_type = 0x38, + .int_polarity = 0x3c, + .int_status = 0x40, + .int_rawstatus = 0x44, + .debounce = 0x48, + .port_eoi = 0x4c, + .ext_port = 0x50, +}; + +static const struct rockchip_gpio_regs _gpio_regs_v2 = +{ + .port_dr = 0x00, + .port_ddr = 0x08, + .int_en = 0x10, + .int_mask = 0x18, + .int_type = 0x20, + .int_polarity = 0x28, + .int_bothedge = 0x30, + .int_status = 0x50, + .int_rawstatus = 0x58, + .debounce = 0x38, + .dbclk_div_en = 0x40, + .dbclk_div_con = 0x48, + .port_eoi = 0x60, + .ext_port = 0x70, + .version_id = 0x78, +}; + +rt_inline void gpio_writel_v2(void *base, rt_uint32_t val) +{ + HWREG32(base) = (val & 0xffff) | 0xffff0000U; + HWREG32(base + 0x4) = (val >> 16) | 0xffff0000U; +} + +rt_inline rt_uint32_t gpio_readl_v2(void *base) +{ + return HWREG32(base + 0x4) << 16 | HWREG32(base); +} + +rt_inline void rockchip_gpio_writel(struct rockchip_pin_bank *pin_bank, rt_uint32_t value, int offset) +{ + void *base = pin_bank->reg_base + offset; + + if (pin_bank->gpio_type == GPIO_TYPE_V2) + { + gpio_writel_v2(base, value); + } + else + { + HWREG32(base) = value; + } +} + +rt_inline rt_uint32_t rockchip_gpio_readl(struct rockchip_pin_bank *pin_bank, int offset) +{ + rt_uint32_t value; + void *base = pin_bank->reg_base + offset; + + if (pin_bank->gpio_type == GPIO_TYPE_V2) + { + value = gpio_readl_v2(base); + } + else + { + value = HWREG32(base); + } + + return value; +} + +rt_inline void rockchip_gpio_writel_bit(struct rockchip_pin_bank *pin_bank, + rt_uint32_t bit, rt_uint32_t value, int offset) +{ + rt_uint32_t data; + void *base = pin_bank->reg_base + offset; + + if (pin_bank->gpio_type == GPIO_TYPE_V2) + { + if (value) + { + data = RT_BIT(bit % 16) | RT_BIT(bit % 16 + 16); + } + else + { + data = RT_BIT(bit % 16 + 16); + } + HWREG32(bit >= 16 ? base + 0x4 : base) = data; + } + else + { + data = HWREG32(base); + data &= ~RT_BIT(bit); + + if (value) + { + data |= RT_BIT(bit); + } + HWREG32(base) = data; + } +} + +rt_inline rt_uint32_t rockchip_gpio_readl_bit(struct rockchip_pin_bank *pin_bank, + rt_uint32_t bit, int offset) +{ + rt_uint32_t data; + void *base = pin_bank->reg_base + offset; + + if (pin_bank->gpio_type == GPIO_TYPE_V2) + { + data = HWREG32(bit >= 16 ? base + 0x4 : base); + data >>= bit % 16; + } + else + { + data = HWREG32(base); + data >>= bit; + } + + return data & 1; +} + +static void rk_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) +{ + rt_base_t level; + struct rockchip_pin_bank *pin_bank = raw_pin_to_bank(device); + struct rockchip_pin_ctrl *pinctrl = pin_bank->drvdata->pinctrl; + + switch (mode) + { + case PIN_MODE_OUTPUT: + case PIN_MODE_OUTPUT_OD: + pinctrl->set_mux(pin_bank, pin, RK_FUNC_GPIO); + + level = rt_spin_lock_irqsave(&pin_bank->spinlock); + rockchip_gpio_writel_bit(pin_bank, pin, 1, pin_bank->gpio_regs->port_ddr); + rt_spin_unlock_irqrestore(&pin_bank->spinlock, level); + break; + + case PIN_MODE_INPUT: + case PIN_MODE_INPUT_PULLUP: + case PIN_MODE_INPUT_PULLDOWN: + pinctrl->set_mux(pin_bank, pin, RK_FUNC_GPIO); + + level = rt_spin_lock_irqsave(&pin_bank->spinlock); + rockchip_gpio_writel_bit(pin_bank, pin, 0, pin_bank->gpio_regs->port_ddr); + rt_spin_unlock_irqrestore(&pin_bank->spinlock, level); + break; + + default: + break; + } +} + +static void rk_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value) +{ + struct rockchip_pin_bank *pin_bank = raw_pin_to_bank(device); + + rockchip_gpio_writel_bit(pin_bank, pin, value, pin_bank->gpio_regs->port_dr); +} + +static rt_ssize_t rk_pin_read(struct rt_device *device, rt_base_t pin) +{ + rt_uint32_t data; + struct rockchip_pin_bank *pin_bank = raw_pin_to_bank(device); + + data = HWREG32(pin_bank->reg_base + pin_bank->gpio_regs->ext_port); + data >>= pin; + + return data & 1; +} + +static rt_err_t rk_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled) +{ + rt_base_t level; + struct rockchip_pin_bank *pin_bank = raw_pin_to_bank(device); + + level = rt_spin_lock_irqsave(&pin_bank->spinlock); + + if (enabled) + { + pin_bank->mask_cache &= ~RT_BIT(pin); + } + else + { + pin_bank->mask_cache |= RT_BIT(pin); + } + rockchip_gpio_writel(pin_bank, pin_bank->mask_cache, pin_bank->gpio_regs->int_mask); + + rt_spin_unlock_irqrestore(&pin_bank->spinlock, level); + + return RT_EOK; +} + +static rt_err_t rk_pin_irq_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) +{ + rt_base_t level; + rt_err_t err = RT_EOK; + rt_uint32_t mask, int_level, polarity, data; + struct rockchip_pin_bank *pin_bank = raw_pin_to_bank(device); + const struct rockchip_gpio_regs *reg = pin_bank->gpio_regs; + + level = rt_spin_lock_irqsave(&pin_bank->spinlock); + + rockchip_gpio_writel_bit(pin_bank, pin, 0, reg->port_ddr); + + mask = RT_BIT(pin); + int_level = rockchip_gpio_readl(pin_bank, reg->int_type); + polarity = rockchip_gpio_readl(pin_bank, reg->int_polarity); + + if (mode == PIN_IRQ_MODE_RISING_FALLING) + { + if (pin_bank->gpio_type == GPIO_TYPE_V2) + { + rockchip_gpio_writel_bit(pin_bank, pin, 1, reg->int_bothedge); + goto _end; + } + else + { + pin_bank->toggle_edge_mode |= mask; + int_level &= ~mask; + + /* + * Determine gpio state. If 1 next interrupt should be + * low otherwise high. + */ + data = HWREG32(pin_bank->reg_base + reg->ext_port); + + if (data & mask) + { + polarity &= ~mask; + } + else + { + polarity |= mask; + } + } + } + else + { + if (pin_bank->gpio_type == GPIO_TYPE_V2) + { + rockchip_gpio_writel_bit(pin_bank, pin, 0, reg->int_bothedge); + } + else + { + pin_bank->toggle_edge_mode &= ~mask; + } + + switch (mode) + { + case PIN_IRQ_MODE_RISING: + int_level |= mask; + polarity |= mask; + break; + + case PIN_IRQ_MODE_FALLING: + int_level |= mask; + polarity &= ~mask; + break; + + case PIN_IRQ_MODE_HIGH_LEVEL: + int_level &= ~mask; + polarity |= mask; + break; + + case PIN_IRQ_MODE_LOW_LEVEL: + int_level &= ~mask; + polarity &= ~mask; + break; + + default: + err = -RT_EINVAL; + goto _end; + } + } + + rockchip_gpio_writel(pin_bank, int_level, reg->int_type); + rockchip_gpio_writel(pin_bank, polarity, reg->int_polarity); + +_end: + rt_spin_unlock_irqrestore(&pin_bank->spinlock, level); + + return err; +} + +static rt_err_t rk_pin_debounce(struct rt_device *device, rt_base_t pin, rt_uint32_t debounce) +{ + rt_uint64_t div; + rt_uint32_t cur_div_reg; + rt_bool_t div_debounce_support; + rt_ubase_t level, div_reg, freq, max_debounce; + struct rockchip_pin_bank *pin_bank = raw_pin_to_bank(device); + const struct rockchip_gpio_regs *reg = pin_bank->gpio_regs; + + if (pin_bank->gpio_type == GPIO_TYPE_V2 && !rt_is_err(pin_bank->db_clk)) + { + div_debounce_support = RT_TRUE; + + freq = rt_clk_get_rate(pin_bank->db_clk); + max_debounce = (RT_GENMASK(23, 0) + 1) * 2 * 1000000 / freq; + if (debounce > max_debounce) + { + return -RT_EINVAL; + } + + div = debounce * freq; + div_reg = RT_DIV_ROUND_CLOSEST_ULL(div, 2 * 1000000L) - 1; + } + else + { + div_debounce_support = RT_FALSE; + } + + level = rt_spin_lock_irqsave(&pin_bank->spinlock); + + /* Only the v1 needs to configure div_en and div_con for dbclk */ + if (debounce) + { + if (div_debounce_support) + { + /* Configure the max debounce from consumers */ + cur_div_reg = HWREG32(pin_bank->reg_base + reg->dbclk_div_con); + + if (cur_div_reg < div_reg) + { + HWREG32(pin_bank->reg_base + reg->dbclk_div_con) = div_reg; + } + + rockchip_gpio_writel_bit(pin_bank, pin, 1, reg->dbclk_div_en); + } + + rockchip_gpio_writel_bit(pin_bank, pin, 1, reg->debounce); + } + else + { + if (div_debounce_support) + { + rockchip_gpio_writel_bit(pin_bank, pin, 0, reg->dbclk_div_en); + } + + rockchip_gpio_writel_bit(pin_bank, pin, 0, reg->debounce); + } + + rt_spin_unlock_irqrestore(&pin_bank->spinlock, level); + + /* Enable or disable dbclk at last */ + if (div_debounce_support) + { + if (debounce) + { + rt_clk_prepare_enable(pin_bank->db_clk); + } + else + { + rt_clk_disable_unprepare(pin_bank->db_clk); + } + } + + return RT_EOK; +} + +static rt_ssize_t rk_pin_parse(struct rt_device *device, struct rt_ofw_cell_args *args, rt_uint32_t *flags) +{ + if (flags) + { + *flags = args->args[1]; + } + + return args->args[0]; +} + +static const struct rt_pin_ops rk_pin_ops = +{ + .pin_mode = rk_pin_mode, + .pin_write = rk_pin_write, + .pin_read = rk_pin_read, + .pin_irq_enable = rk_pin_irq_enable, + .pin_irq_mode = rk_pin_irq_mode, + .pin_debounce = rk_pin_debounce, + .pin_parse = rk_pin_parse, +}; + +static void rk_pin_isr(int irqno, void *param) +{ + rt_uint32_t pending; + struct rockchip_pin_bank *pin_bank = param; + + pending = HWREG32(pin_bank->reg_base + pin_bank->gpio_regs->int_status); + + for (rt_ubase_t pin = 0; pin < 32 && pending; ++pin) + { + rt_uint32_t clr = RT_BIT(pin); + + if (!(clr & pending)) + { + continue; + } + + if (clr & pin_bank->toggle_edge_mode) + { + rt_uint32_t data, data_old, polarity; + + data = HWREG32(pin_bank->reg_base + pin_bank->gpio_regs->ext_port); + + do { + rt_ubase_t level = rt_spin_lock_irqsave(&pin_bank->spinlock); + + polarity = HWREG32(pin_bank->reg_base + pin_bank->gpio_regs->int_polarity); + + if (data & clr) + { + polarity &= ~clr; + } + else + { + polarity |= clr; + } + HWREG32(pin_bank->reg_base + pin_bank->gpio_regs->int_polarity) = polarity; + + rt_spin_unlock_irqrestore(&pin_bank->spinlock, level); + + data_old = data; + data = HWREG32(pin_bank->reg_base + pin_bank->gpio_regs->ext_port); + } while ((data & clr) != (data_old & clr)); + } + + pin_pic_handle_isr(&pin_bank->parent, pin); + + rockchip_gpio_writel_bit(pin_bank, pin, 1, pin_bank->gpio_regs->port_eoi); + + /* clear this pin irq */ + pending &= ~clr; + } +} + +static rt_err_t rockchip_gpio_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + int id, version; + const char *name; + struct rockchip_pin_bank *pin_bank; + struct rt_ofw_node *np = pdev->parent.ofw_node; + struct rt_ofw_node *npp = rt_ofw_get_parent(np); + struct rockchip_pinctrl_device *pinctrl_dev = rt_ofw_data(npp); + struct rockchip_pin_ctrl *pinctrl = pinctrl_dev->pinctrl; + + rt_ofw_node_put(npp); + + if ((id = pdev->dev_id) < 0) + { + static int gpio_uid = 0; + + id = gpio_uid++; + } + + pin_bank = &pinctrl->pin_banks[id]; + + pin_bank->reg_base = rt_ofw_iomap(np, 0); + + if (!pin_bank->reg_base) + { + err = -RT_EIO; + goto _out_res; + } + + pin_bank->irq = rt_ofw_get_irq(np, 0); + + if (pin_bank->irq < 0) + { + err = pin_bank->irq; + goto _out_res; + } + + pin_bank->clk = rt_ofw_get_clk(np, 0); + + if (rt_is_err(pin_bank->clk)) + { + err = rt_ptr_err(pin_bank->clk); + goto _out_res; + } + + rt_clk_prepare_enable(pin_bank->clk); + + version = HWREG32(pin_bank->reg_base + _gpio_regs_v2.version_id); + + if (version == GPIO_TYPE_V2 || version == GPIO_TYPE_V2_1) + { + pin_bank->gpio_regs = &_gpio_regs_v2; + pin_bank->gpio_type = GPIO_TYPE_V2; + + pin_bank->db_clk = rt_ofw_get_clk(np, 1); + + if (rt_is_err(pin_bank->db_clk)) + { + err = rt_ptr_err(pin_bank->db_clk); + goto _out_res; + } + + rt_clk_prepare_enable(pin_bank->db_clk); + } + else + { + pin_bank->gpio_regs = &_gpio_regs_v1; + pin_bank->gpio_type = GPIO_TYPE_V1; + } + + rt_dm_dev_set_name_auto(&pin_bank->parent.parent, "gpio"); + name = rt_dm_dev_get_name(&pin_bank->parent.parent); + + rt_hw_interrupt_install(pin_bank->irq, rk_pin_isr, pin_bank, name); + rt_hw_interrupt_umask(pin_bank->irq); + + rockchip_gpio_writel(pin_bank, 0xffffffffU, pin_bank->gpio_regs->int_mask); + rockchip_gpio_writel(pin_bank, 0xffffffffU, pin_bank->gpio_regs->port_eoi); + rockchip_gpio_writel(pin_bank, 0xffffffffU, pin_bank->gpio_regs->int_en); + + pin_bank->mask_cache = 0xffffffffU; + rt_spin_lock_init(&pin_bank->spinlock); + + pin_bank->parent.ops = &rk_pin_ops; + pin_api_init(&pin_bank->parent, 32); + pin_pic_init(&pin_bank->parent, pin_bank->irq); + + rt_ofw_data(np) = &pin_bank->parent; + + return RT_EOK; + +_out_res: + if (pin_bank->reg_base) + { + rt_iounmap(pin_bank->reg_base); + } + + if (rt_is_err_or_null(pin_bank->clk)) + { + rt_clk_disable_unprepare(pin_bank->clk); + rt_clk_put(pin_bank->clk); + } + + if (rt_is_err_or_null(pin_bank->db_clk)) + { + rt_clk_disable_unprepare(pin_bank->db_clk); + rt_clk_put(pin_bank->db_clk); + } + + return err; +} + +static const struct rt_ofw_node_id rockchip_gpio_ofw_ids[] = +{ + { .compatible = "rockchip,gpio-bank" }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_gpio_driver = +{ + .name = "rockchip-gpio", + .ids = rockchip_gpio_ofw_ids, + + .probe = rockchip_gpio_probe, +}; + +static int rockchip_gpio_register(void) +{ + rt_platform_driver_register(&rockchip_gpio_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(rockchip_gpio_register); diff --git a/bsp/rockchip/dm/pinctrl/Kconfig b/bsp/rockchip/dm/pinctrl/Kconfig new file mode 100755 index 00000000000..50783380e80 --- /dev/null +++ b/bsp/rockchip/dm/pinctrl/Kconfig @@ -0,0 +1,11 @@ +config RT_PINCTRL_ROCKCHIP_RK8XX + bool "Pinctrl and GPIO driver for RK805/RK806 PMIC" + depends on RT_USING_PINCTRL + depends on RT_MFD_RK8XX + default n + +config RT_PINCTRL_ROCKCHIP + bool "Rockchip gpio and pinctrl driver" + depends on RT_USING_PINCTRL + depends on RT_MFD_SYSCON + default y diff --git a/bsp/rockchip/dm/pinctrl/SConscript b/bsp/rockchip/dm/pinctrl/SConscript new file mode 100755 index 00000000000..ac9acee7191 --- /dev/null +++ b/bsp/rockchip/dm/pinctrl/SConscript @@ -0,0 +1,16 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_PINCTRL_ROCKCHIP_RK8XX']): + src += ['pinctrl-rk8xx.c'] + +if GetDepend(['RT_PINCTRL_ROCKCHIP']): + src += ['pinctrl-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/pinctrl/pinctrl-rk8xx.c b/bsp/rockchip/dm/pinctrl/pinctrl-rk8xx.c new file mode 100755 index 00000000000..83f3a3f3723 --- /dev/null +++ b/bsp/rockchip/dm/pinctrl/pinctrl-rk8xx.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "pinctrl.rk8xx" +#define DBG_LVL DBG_INFO +#include + +#include "rk8xx.h" + +struct rk8xx_pin +{ + const char *name; +}; + +enum rk8xx_pin_mux +{ + RK805_PINMUX_GPIO = 0, + RK806_PINMUX_FUN0 = 0, + RK806_PINMUX_FUN1, + RK806_PINMUX_FUN2, + RK806_PINMUX_FUN3, + RK806_PINMUX_FUN4, + RK806_PINMUX_FUN5, +}; + +struct rk8xx_pin_function +{ + const char *name; + enum rk8xx_pin_mux mux; +}; + +struct rk8xx_pin_conf +{ + rt_uint8_t reg; + rt_uint8_t fun_reg; + rt_uint8_t fun_msk; + rt_uint8_t dir_msk; + rt_uint8_t val_msk; +}; + +struct rk8xx_pinctrl +{ + struct rt_device_pin parent; + + struct rk8xx *rk8xx; + + int pins_nr; + const struct rk8xx_pin *pins; + + int pin_func_nr; + const struct rk8xx_pin_function *pin_funcs; + + int pin_confs_nr; + const struct rk8xx_pin_conf *pin_confs; +}; + +#define raw_to_rk8xx_pinctrl(raw) rt_container_of(raw, struct rk8xx_pinctrl, parent) + +static void rk8xx_pinctrl_set_direction(struct rk8xx_pinctrl *rk8xx_pl, + rt_base_t pin, rt_bool_t input) +{ + rt_uint32_t val; + const struct rk8xx_pin_conf *pin_conf = &rk8xx_pl->pin_confs[pin]; + + if (!pin_conf->dir_msk) + { + /* Default output */ + return; + } + + val = rk8xx_read(rk8xx_pl->rk8xx, pin_conf->reg); + + if ((rt_err_t)val < 0) + { + LOG_E("Get PIN%d direction failed", pin); + } + + return; +} + +static void rk8xx_pinctrl_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode) +{ + struct rk8xx_pinctrl *rk8xx_pl = raw_to_rk8xx_pinctrl(device); + + switch (mode) + { + case PIN_MODE_OUTPUT: + rk8xx_pinctrl_set_direction(rk8xx_pl, pin, RT_FALSE); + break; + + case PIN_MODE_INPUT: + if (rk8xx_pl->rk8xx->variant != RK805_ID) + { + rk8xx_pinctrl_set_direction(rk8xx_pl, pin, RT_TRUE); + } + break; + + default: + break; + } +} + +static void rk8xx_pinctrl_write(struct rt_device *device, rt_base_t pin, + rt_uint8_t value) +{ + rt_err_t err; + struct rk8xx_pinctrl *rk8xx_pl = raw_to_rk8xx_pinctrl(device); + const struct rk8xx_pin_conf *pin_conf = &rk8xx_pl->pin_confs[pin]; + + err = rk8xx_update_bits(rk8xx_pl->rk8xx, + pin_conf->reg, pin_conf->val_msk, value ? pin_conf->val_msk : 0); + + if (err) + { + LOG_E("Set PIN%d value %d failed", pin, value); + } +} + +static rt_ssize_t rk8xx_pinctrl_read(struct rt_device *device, rt_base_t pin) +{ + int val; + struct rk8xx_pinctrl *rk8xx_pl = raw_to_rk8xx_pinctrl(device); + + val = rk8xx_read(rk8xx_pl->rk8xx, rk8xx_pl->pin_confs[pin].reg); + + if ((rt_err_t)val < 0) + { + LOG_E("Get PIN%d value failed", pin); + + return val; + } + + return !!(val & rk8xx_pl->pin_confs[pin].val_msk); +} + +static rt_ssize_t rk8xx_pin_parse(struct rt_device *device, + struct rt_ofw_cell_args *args, rt_uint32_t *flags) +{ + if (flags) + { + *flags = args->args[1]; + } + + return args->args[0]; +} + +static rt_err_t rk8xx_pinctrl_confs_apply(struct rt_device *device, void *fw_conf_np) +{ + int i; + rt_err_t err; + rt_base_t pin = 0; + enum rk8xx_pin_mux mux = 0; + const char *pin_name, *function; + const struct rk8xx_pin_conf *pin_conf; + struct rt_ofw_node *conf_np = fw_conf_np; + struct rk8xx_pinctrl *rk8xx_pl = raw_to_rk8xx_pinctrl(device); + + if ((err = rt_ofw_prop_read_string(conf_np, "pins", &pin_name))) + { + LOG_E("%s: %s not found", rt_ofw_node_full_name(conf_np), "pins"); + return err; + } + + if ((err = rt_ofw_prop_read_string(conf_np, "function", &function))) + { + LOG_E("%s: %s not found", rt_ofw_node_full_name(conf_np), "function"); + return err; + } + + for (i = 0; i < rk8xx_pl->pins_nr; ++i) + { + if (!rt_strcmp(rk8xx_pl->pins[i].name, pin_name)) + { + break; + } + ++pin; + } + + if (i == rk8xx_pl->pins_nr) + { + return -RT_EINVAL; + } + + for (i = 0; i < rk8xx_pl->pin_func_nr; ++i) + { + if (!rt_strcmp(rk8xx_pl->pin_funcs[i].name, function)) + { + mux = rk8xx_pl->pin_funcs[i].mux; + break; + } + } + + if (i == rk8xx_pl->pin_func_nr) + { + return -RT_EINVAL; + } + + pin_conf = &rk8xx_pl->pin_confs[pin]; + + if (!pin_conf->fun_msk) + { + return RT_EOK; + } + + mux <<= __rt_ffs(pin_conf->fun_msk) - 1; + err = rk8xx_update_bits(rk8xx_pl->rk8xx, + pin_conf->fun_reg, pin_conf->fun_msk, mux); + + if (err) + { + LOG_E("Set PIN%d func%d failed", pin, mux); + } + + return err; +} + +static const struct rt_pin_ops rk8xx_pinctrl_ops = +{ + .pin_mode = rk8xx_pinctrl_mode, + .pin_write = rk8xx_pinctrl_write, + .pin_read = rk8xx_pinctrl_read, + .pin_parse = rk8xx_pin_parse, + .pin_ctrl_confs_apply = rk8xx_pinctrl_confs_apply, +}; + +static const struct rk8xx_pin rk805_pins[] = +{ + { .name = "gpio0", }, + { .name = "gpio1", }, +}; + +static const struct rk8xx_pin_function rk805_gpio_funcs[] = +{ + { .name = "gpio", .mux = RK805_PINMUX_GPIO }, +}; + +#define RK805_GPIO0_VAL_MSK RT_BIT(0) +#define RK805_GPIO1_VAL_MSK RT_BIT(1) + +static const struct rk8xx_pin_conf rk805_gpio_confs[] = +{ + { + .reg = RK805_OUT_REG, + .val_msk = RK805_GPIO0_VAL_MSK, + }, + { + .reg = RK805_OUT_REG, + .val_msk = RK805_GPIO1_VAL_MSK, + }, +}; + +static struct rk8xx_pin rk806_pins[] = +{ + { .name = "gpio_pwrctrl1", }, + { .name = "gpio_pwrctrl2", }, + { .name = "gpio_pwrctrl3", }, +}; + +static const struct rk8xx_pin_function rk806_gpio_funcs[] = +{ + { .name = "pin_fun0", .mux = RK806_PINMUX_FUN0 }, + { .name = "pin_fun1", .mux = RK806_PINMUX_FUN1 }, + { .name = "pin_fun2", .mux = RK806_PINMUX_FUN2 }, + { .name = "pin_fun3", .mux = RK806_PINMUX_FUN3 }, + { .name = "pin_fun4", .mux = RK806_PINMUX_FUN4 }, + { .name = "pin_fun5", .mux = RK806_PINMUX_FUN5 }, +}; + +#define RK806_PWRCTRL1_DR RT_BIT(0) +#define RK806_PWRCTRL2_DR RT_BIT(1) +#define RK806_PWRCTRL3_DR RT_BIT(2) +#define RK806_PWRCTRL1_DATA RT_BIT(4) +#define RK806_PWRCTRL2_DATA RT_BIT(5) +#define RK806_PWRCTRL3_DATA RT_BIT(6) +#define RK806_PWRCTRL1_FUN RT_GENMASK(2, 0) +#define RK806_PWRCTRL2_FUN RT_GENMASK(6, 4) +#define RK806_PWRCTRL3_FUN RT_GENMASK(2, 0) + +static const struct rk8xx_pin_conf rk806_gpio_confs[] = +{ + { + .fun_reg = RK806_SLEEP_CONFIG0, + .fun_msk = RK806_PWRCTRL1_FUN, + .reg = RK806_SLEEP_GPIO, + .val_msk = RK806_PWRCTRL1_DATA, + .dir_msk = RK806_PWRCTRL1_DR, + }, + { + .fun_reg = RK806_SLEEP_CONFIG0, + .fun_msk = RK806_PWRCTRL2_FUN, + .reg = RK806_SLEEP_GPIO, + .val_msk = RK806_PWRCTRL2_DATA, + .dir_msk = RK806_PWRCTRL2_DR, + }, + { + .fun_reg = RK806_SLEEP_CONFIG1, + .fun_msk = RK806_PWRCTRL3_FUN, + .reg = RK806_SLEEP_GPIO, + .val_msk = RK806_PWRCTRL3_DATA, + .dir_msk = RK806_PWRCTRL3_DR, + } +}; + +static rt_err_t rk8xx_pinctrl_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + char *compat; + int pins_nr, pin_func_nr, pin_confs_nr; + const struct rk8xx_pin *pins; + const struct rk8xx_pin_function *pin_funcs; + const struct rk8xx_pin_conf *pin_confs; + struct rk8xx *rk8xx = pdev->priv; + struct rt_ofw_node *np = pdev->parent.ofw_node; + struct rk8xx_pinctrl *rk8xx_pl = rt_calloc(1, sizeof(*rk8xx_pl)); + + if (!rk8xx_pl) + { + return -RT_ENOMEM; + } + + rk8xx_pl->rk8xx = rk8xx; + + switch (rk8xx->variant) + { + case RK805_ID: + compat = "rk805-pinctrl"; + pins_nr = RT_ARRAY_SIZE(rk805_pins); + pins = rk805_pins; + pin_func_nr = RT_ARRAY_SIZE(rk805_gpio_funcs); + pin_funcs = rk805_gpio_funcs; + pin_confs_nr = RT_ARRAY_SIZE(rk805_gpio_confs); + pin_confs = rk805_gpio_confs; + break; + + case RK806_ID: + compat = "rk806-pinctrl"; + pins_nr = RT_ARRAY_SIZE(rk806_pins); + pins = rk806_pins; + pin_func_nr = RT_ARRAY_SIZE(rk806_gpio_funcs); + pin_funcs = rk806_gpio_funcs; + pin_confs_nr = RT_ARRAY_SIZE(rk806_gpio_confs); + pin_confs = rk806_gpio_confs; + break; + + default: + err = -RT_EINVAL; + goto _fail; + } + + rk8xx_pl->parent.ops = &rk8xx_pinctrl_ops; + rk8xx_pl->pins_nr = pins_nr; + rk8xx_pl->pins = pins; + rk8xx_pl->pin_func_nr = pin_func_nr; + rk8xx_pl->pin_funcs = pin_funcs; + rk8xx_pl->pin_confs_nr = pin_confs_nr; + rk8xx_pl->pin_confs = pin_confs; + + if (!rt_ofw_prop_read_bool(np, "compatible")) + { + /* make pinctrl can find that */ + if ((err = rt_ofw_append_prop(np, "compatible", rt_strlen(compat) + 1, compat))) + { + goto _fail; + } + } + + rt_ofw_data(np) = &rk8xx_pl->parent; + + return RT_EOK; + +_fail: + rt_free(rk8xx_pl); + + return err; +} + +static struct rt_platform_driver rk8xx_pinctrl_driver = +{ + .name = "rk8xx-pinctrl", + .probe = rk8xx_pinctrl_probe, +}; +RT_PLATFORM_DRIVER_EXPORT(rk8xx_pinctrl_driver); diff --git a/bsp/rockchip/dm/pinctrl/pinctrl-rockchip.c b/bsp/rockchip/dm/pinctrl/pinctrl-rockchip.c new file mode 100755 index 00000000000..2bb2fede47c --- /dev/null +++ b/bsp/rockchip/dm/pinctrl/pinctrl-rockchip.c @@ -0,0 +1,1763 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include + +#define DBG_TAG "pinctrl.rockchip" +#define DBG_LVL DBG_INFO +#include + +#include "pinctrl-rockchip.h" + +#define WRITE_MASK_VAL(h, l, v) \ + (RT_GENMASK(((h) + 16), ((l) + 16)) | (((v) << (l)) & RT_GENMASK((h), (l)))) + +/* + * Encode variants of iomux registers into a type variable + */ +#define IOMUX_GPIO_ONLY RT_BIT(0) +#define IOMUX_WIDTH_4BIT RT_BIT(1) +#define IOMUX_SOURCE_PMU RT_BIT(2) +#define IOMUX_UNROUTED RT_BIT(3) +#define IOMUX_WIDTH_3BIT RT_BIT(4) +#define IOMUX_WIDTH_2BIT RT_BIT(5) +#define IOMUX_L_SOURCE_PMU RT_BIT(6) + +#define PIN_BANK_IOMUX_FLAGS(ID, PINS, \ + LABEL, IOM0, IOM1, IOM2, IOM3) \ +{ \ + .bank_num = ID, \ + .nr_pins = PINS, \ + .name = LABEL, \ + .iomux = \ + { \ + { .type = IOM0, .offset = -1 }, \ + { .type = IOM1, .offset = -1 }, \ + { .type = IOM2, .offset = -1 }, \ + { .type = IOM3, .offset = -1 }, \ + }, \ +} + +#define PIN_BANK_MUX_ROUTE_FLAGS( \ + ID, PIN, FUNC, REG, VAL, FLAG) \ +{ \ + .bank_num = ID, \ + .pin = PIN, \ + .func = FUNC, \ + .route_offset = REG, \ + .route_val = VAL, \ + .route_location = FLAG, \ +} + +#define PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, \ + PINS, LABEL, IOM0, IOM1, IOM2, IOM3, \ + PULL0, PULL1, PULL2, PULL3) \ +{ \ + .bank_num = ID, \ + .nr_pins = PINS, \ + .name = LABEL, \ + .iomux = \ + { \ + { .type = IOM0, .offset = -1 }, \ + { .type = IOM1, .offset = -1 }, \ + { .type = IOM2, .offset = -1 }, \ + { .type = IOM3, .offset = -1 }, \ + }, \ + .pull_type[0] = PULL0, \ + .pull_type[1] = PULL1, \ + .pull_type[2] = PULL2, \ + .pull_type[3] = PULL3, \ +} + +#define PIN_BANK_IOMUX_FLAGS_OFFSET_PULL_FLAGS( \ + ID, PINS, LABEL, IOM0, IOM1, IOM2, IOM3, \ + OFFSET0, OFFSET1, OFFSET2, OFFSET3, PULL0, \ + PULL1, PULL2, PULL3) \ +{ \ + .bank_num = ID, \ + .nr_pins = PINS, \ + .name = LABEL, \ + .iomux = \ + { \ + { .type = IOM0, .offset = OFFSET0 }, \ + { .type = IOM1, .offset = OFFSET1 }, \ + { .type = IOM2, .offset = OFFSET2 }, \ + { .type = IOM3, .offset = OFFSET3 }, \ + }, \ + .pull_type[0] = PULL0, \ + .pull_type[1] = PULL1, \ + .pull_type[2] = PULL2, \ + .pull_type[3] = PULL3, \ +} + +#define RK_MUXROUTE_SAME(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_SAME) + +#define RK_MUXROUTE_GRF(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_GRF) + +#define RK_MUXROUTE_PMU(ID, PIN, FUNC, REG, VAL) \ + PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROCKCHIP_ROUTE_PMU) + +#define PIN_BANK_FLAGS_IOMUX_PULL(ID, PIN, LABEL, M, P) \ + PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, PIN, LABEL, M, M, M, M, P, P, P, P) + +#define PIN_BANK_OFFSET4(ID, LABEL, OFFSET0, OFFSET1, OFFSET2, OFFSET3) \ + PIN_BANK_IOMUX_FLAGS_OFFSET_PULL_FLAGS(ID, 32, LABEL, \ + IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, \ + IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, \ + OFFSET0, OFFSET1, OFFSET2, OFFSET3, \ + PULL_TYPE_IO_1, PULL_TYPE_IO_1, \ + PULL_TYPE_IO_1, PULL_TYPE_IO_1) + +#define RK_RECALCED_DATA( \ + NUM, PIN, REG, BIT, MASK) \ +{ \ + .num = NUM, \ + .pin = PIN, \ + .reg = REG, \ + .bit = BIT, \ + .mask = MASK, \ +} + +static int rockchip_pull_list[PULL_TYPE_MAX][4] = +{ + { + PIN_CONFIG_BIAS_DISABLE, + PIN_CONFIG_BIAS_PULL_UP, + PIN_CONFIG_BIAS_PULL_DOWN, + PIN_CONFIG_BIAS_BUS_HOLD + }, + { + PIN_CONFIG_BIAS_DISABLE, + PIN_CONFIG_BIAS_PULL_DOWN, + PIN_CONFIG_BIAS_DISABLE, + PIN_CONFIG_BIAS_PULL_UP + }, +}; + +static int rockchip_translate_pull_value(int type, int pull) +{ + int res = -RT_EINVAL; + + for (int i = 0; i < RT_ARRAY_SIZE(rockchip_pull_list[type]); ++i) + { + if (rockchip_pull_list[type][i] == pull) + { + res = i; + break; + } + } + + return res; +} + +static void rockchip_translate_recalced_mux(struct rockchip_pin_bank *pin_bank, + int pin, int *reg, rt_uint8_t *bit, int *mask) +{ + int i; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + struct rockchip_pin_ctrl *pinctrl = drvdata->pinctrl; + struct rockchip_mux_recalced_data *data; + + for (i = 0; i < pinctrl->niomux_recalced; ++i) + { + data = &pinctrl->iomux_recalced[i]; + + if (data->num == pin_bank->bank_num && data->pin == pin) + { + break; + } + } + + if (i >= pinctrl->niomux_recalced) + { + return; + } + + *reg = data->reg; + *mask = data->mask; + *bit = data->bit; +} + +static rt_bool_t rockchip_translate_mux_route(struct rockchip_pin_bank *pin_bank, + int pin, int mux, rt_uint32_t *loc, rt_uint32_t *reg, rt_uint32_t *value) +{ + int i; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + struct rockchip_pin_ctrl *pinctrl = drvdata->pinctrl; + struct rockchip_mux_route_data *data; + + for (i = 0; i < pinctrl->niomux_routes; ++i) + { + data = &pinctrl->iomux_routes[i]; + + if (data->bank_num == pin_bank->bank_num && data->pin == pin && data->func == mux) + { + break; + } + } + + if (i >= pinctrl->niomux_routes) + { + return RT_FALSE; + } + + *loc = data->route_location; + *reg = data->route_offset; + *value = data->route_val; + + return RT_TRUE; +} + +static struct rockchip_mux_route_data rk3308_mux_route_data[] = +{ + RK_MUXROUTE_SAME(0, RK_PC3, 1, 0x314, RT_BIT(16 + 0) | RT_BIT(0)), /* rtc_clk */ + RK_MUXROUTE_SAME(1, RK_PC6, 2, 0x314, RT_BIT(16 + 2) | RT_BIT(16 + 3)), /* uart2_rxm0 */ + RK_MUXROUTE_SAME(4, RK_PD2, 2, 0x314, RT_BIT(16 + 2) | RT_BIT(16 + 3) | RT_BIT(2)), /* uart2_rxm1 */ + RK_MUXROUTE_SAME(0, RK_PB7, 2, 0x608, RT_BIT(16 + 8) | RT_BIT(16 + 9)), /* i2c3_sdam0 */ + RK_MUXROUTE_SAME(3, RK_PB4, 2, 0x608, RT_BIT(16 + 8) | RT_BIT(16 + 9) | RT_BIT(8)), /* i2c3_sdam1 */ + RK_MUXROUTE_SAME(2, RK_PA0, 3, 0x608, RT_BIT(16 + 8) | RT_BIT(16 + 9) | RT_BIT(9)), /* i2c3_sdam2 */ + RK_MUXROUTE_SAME(1, RK_PA3, 2, 0x308, RT_BIT(16 + 3)), /* i2s-8ch-1-sclktxm0 */ + RK_MUXROUTE_SAME(1, RK_PA4, 2, 0x308, RT_BIT(16 + 3)), /* i2s-8ch-1-sclkrxm0 */ + RK_MUXROUTE_SAME(1, RK_PB5, 2, 0x308, RT_BIT(16 + 3) | RT_BIT(3)), /* i2s-8ch-1-sclktxm1 */ + RK_MUXROUTE_SAME(1, RK_PB6, 2, 0x308, RT_BIT(16 + 3) | RT_BIT(3)), /* i2s-8ch-1-sclkrxm1 */ + RK_MUXROUTE_SAME(1, RK_PA4, 3, 0x308, RT_BIT(16 + 12) | RT_BIT(16 + 13)), /* pdm-clkm0 */ + RK_MUXROUTE_SAME(1, RK_PB6, 4, 0x308, RT_BIT(16 + 12) | RT_BIT(16 + 13) | RT_BIT(12)), /* pdm-clkm1 */ + RK_MUXROUTE_SAME(2, RK_PA6, 2, 0x308, RT_BIT(16 + 12) | RT_BIT(16 + 13) | RT_BIT(13)), /* pdm-clkm2 */ + RK_MUXROUTE_SAME(2, RK_PA4, 3, 0x600, RT_BIT(16 + 2) | RT_BIT(2)), /* pdm-clkm-m2 */ + RK_MUXROUTE_SAME(3, RK_PB2, 3, 0x314, RT_BIT(16 + 9)), /* spi1_miso */ + RK_MUXROUTE_SAME(2, RK_PA4, 2, 0x314, RT_BIT(16 + 9) | RT_BIT(9)), /* spi1_miso_m1 */ + RK_MUXROUTE_SAME(0, RK_PB3, 3, 0x314, RT_BIT(16 + 10) | RT_BIT(16 + 11)), /* owire_m0 */ + RK_MUXROUTE_SAME(1, RK_PC6, 7, 0x314, RT_BIT(16 + 10) | RT_BIT(16 + 11) | RT_BIT(10)), /* owire_m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 5, 0x314, RT_BIT(16 + 10) | RT_BIT(16 + 11) | RT_BIT(11)), /* owire_m2 */ + RK_MUXROUTE_SAME(0, RK_PB3, 2, 0x314, RT_BIT(16 + 12) | RT_BIT(16 + 13)), /* can_rxd_m0 */ + RK_MUXROUTE_SAME(1, RK_PC6, 5, 0x314, RT_BIT(16 + 12) | RT_BIT(16 + 13) | RT_BIT(12)), /* can_rxd_m1 */ + RK_MUXROUTE_SAME(2, RK_PA2, 4, 0x314, RT_BIT(16 + 12) | RT_BIT(16 + 13) | RT_BIT(13)), /* can_rxd_m2 */ + RK_MUXROUTE_SAME(1, RK_PC4, 3, 0x314, RT_BIT(16 + 14)), /* mac_rxd0_m0 */ + RK_MUXROUTE_SAME(4, RK_PA2, 2, 0x314, RT_BIT(16 + 14) | RT_BIT(14)), /* mac_rxd0_m1 */ + RK_MUXROUTE_SAME(3, RK_PB4, 4, 0x314, RT_BIT(16 + 15)), /* uart3_rx */ + RK_MUXROUTE_SAME(0, RK_PC1, 3, 0x314, RT_BIT(16 + 15) | RT_BIT(15)), /* uart3_rx_m1 */ +}; + +static struct rockchip_mux_recalced_data rk3308_mux_recalced_data[] = +{ + RK_RECALCED_DATA(1, 14, 0x28, 12, 0xf), /* gpio1b6_sel */ + RK_RECALCED_DATA(1, 15, 0x2c, 0, 0x3), /* gpio1b7_sel */ + RK_RECALCED_DATA(1, 18, 0x30, 4, 0xf), /* gpio1c2_sel */ + RK_RECALCED_DATA(1, 19, 0x30, 8, 0xf), /* gpio1c3_sel */ + RK_RECALCED_DATA(1, 20, 0x30, 12, 0xf), /* gpio1c4_sel */ + RK_RECALCED_DATA(1, 21, 0x34, 0, 0xf), /* gpio1c5_sel */ + RK_RECALCED_DATA(1, 22, 0x34, 4, 0xf), /* gpio1c6_sel */ + RK_RECALCED_DATA(1, 23, 0x34, 8, 0xf), /* gpio1c7_sel */ + RK_RECALCED_DATA(2, 2, 0x40, 4, 0x3), /* gpio2a2_sel */ + RK_RECALCED_DATA(2, 3, 0x40, 6, 0x3), /* gpio2a3_sel */ + RK_RECALCED_DATA(2, 16, 0x50, 0, 0x3), /* gpio2c0_sel */ + RK_RECALCED_DATA(3, 10, 0x68, 4, 0x3), /* gpio3b2_sel */ + RK_RECALCED_DATA(3, 11, 0x68, 6, 0x3), /* gpio3b3_sel */ + RK_RECALCED_DATA(3, 12, 0x68, 8, 0xf), /* gpio3b4_sel */ + RK_RECALCED_DATA(3, 13, 0x68, 12, 0xf), /* gpio3b5_sel */ +}; + +static rt_err_t rk3308_set_mux(struct rockchip_pin_bank *pin_bank, int pin, int mux) +{ + rt_uint8_t bit; + rt_uint32_t data; + int iomux_num = (pin / 8), reg, mask; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if ((pin_bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)) + { + regmap = drvdata->regmap_pmu; + } + else + { + regmap = drvdata->regmap_base; + } + + reg = pin_bank->iomux[iomux_num].offset; + if (pin_bank->iomux[iomux_num].type & IOMUX_WIDTH_4BIT) + { + if ((pin % 8) >= 4) + { + reg += 0x4; + } + bit = (pin % 4) * 4; + mask = 0xf; + } + else + { + bit = (pin % 8) * 2; + mask = 0x3; + } + + if (pin_bank->recalced_mask & RT_BIT(pin)) + { + rockchip_translate_recalced_mux(pin_bank, pin, ®, &bit, &mask); + } + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3308_PULL_OFFSET 0xa0 +#define RK3308_PULL_BITS_PER_PIN 2 +#define RK3308_PULL_PINS_PER_REG 8 +#define RK3308_PULL_BANK_STRIDE 16 + +static rt_err_t rk3308_set_pull(struct rockchip_pin_bank *pin_bank, int pin, int pull) +{ + int reg, pull_value; + rt_uint32_t data; + rt_uint8_t bit, type; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + { + return -RT_ENOSYS; + } + + regmap = drvdata->regmap_base; + reg = RK3308_PULL_OFFSET; + reg += pin_bank->bank_num * RK3308_PULL_BANK_STRIDE; + reg += ((pin / RK3308_PULL_PINS_PER_REG) * 4); + + bit = (pin % RK3308_PULL_PINS_PER_REG); + bit *= RK3308_PULL_BITS_PER_PIN; + + type = pin_bank->pull_type[pin / 8]; + pull_value = rockchip_translate_pull_value(type, pull); + + if (pull_value < 0) + { + LOG_E("Not supported pull = %d, fixup the code or firmware", pull); + + return pull_value; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data |= (pull_value << bit); + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3308_DRV_GRF_OFFSET 0x100 +#define RK3308_DRV_BITS_PER_PIN 2 +#define RK3308_DRV_PINS_PER_REG 8 +#define RK3308_DRV_BANK_STRIDE 16 + +static rt_err_t rk3308_set_drive(struct rockchip_pin_bank *pin_bank, int pin, int strength) +{ + int reg; + rt_uint8_t bit; + rt_uint32_t data; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + regmap = drvdata->regmap_base; + reg = RK3308_DRV_GRF_OFFSET; + reg += pin_bank->bank_num * RK3308_DRV_BANK_STRIDE; + reg += ((pin / RK3308_DRV_PINS_PER_REG) * 4); + + bit = (pin % RK3308_DRV_PINS_PER_REG); + bit *= RK3308_DRV_BITS_PER_PIN; + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (strength << bit); + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3308_SCHMITT_PINS_PER_REG 8 +#define RK3308_SCHMITT_BANK_STRIDE 16 +#define RK3308_SCHMITT_GRF_OFFSET 0x1a0 + +static rt_err_t rk3308_set_schmitt(struct rockchip_pin_bank *pin_bank, int pin, int enable) +{ + int reg; + rt_uint8_t bit; + rt_uint32_t data; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + regmap = drvdata->regmap_base; + reg = RK3308_SCHMITT_GRF_OFFSET; + + reg += pin_bank->bank_num * RK3308_SCHMITT_BANK_STRIDE; + reg += ((pin / RK3308_SCHMITT_PINS_PER_REG) * 4); + bit = pin % RK3308_SCHMITT_PINS_PER_REG; + + /* enable the write to the equivalent lower bits */ + data = RT_BIT(bit + 16) | (enable << bit); + + return rt_syscon_write(regmap, reg, data); +} + +static struct rockchip_pin_bank rk3308_pin_banks[] = +{ + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT, IOMUX_WIDTH_2BIT), +}; + +static struct rockchip_pin_ctrl rk3308_pin_ctrl = +{ + .pin_banks = rk3308_pin_banks, + .banks_nr = RT_ARRAY_SIZE(rk3308_pin_banks), + .label = "RK3308-GPIO", + .type = RK3308, + .grf_mux_offset = 0x0, + .grf_drv_offset = RK3308_DRV_GRF_OFFSET, + .iomux_recalced = rk3308_mux_recalced_data, + .niomux_recalced = RT_ARRAY_SIZE(rk3308_mux_recalced_data), + .iomux_routes = rk3308_mux_route_data, + .niomux_routes = RT_ARRAY_SIZE(rk3308_mux_route_data), + .set_mux = rk3308_set_mux, + .set_pull = rk3308_set_pull, + .set_drive = rk3308_set_drive, + .set_schmitt = rk3308_set_schmitt, +}; + +static struct rockchip_mux_route_data rk3568_mux_route_data[] = +{ + RK_MUXROUTE_PMU(0, RK_PB7, 1, 0x0110, WRITE_MASK_VAL(1, 0, 0)), /* PWM0 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PC7, 2, 0x0110, WRITE_MASK_VAL(1, 0, 1)), /* PWM0 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC0, 1, 0x0110, WRITE_MASK_VAL(3, 2, 0)), /* PWM1 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB5, 4, 0x0110, WRITE_MASK_VAL(3, 2, 1)), /* PWM1 IO mux M1 */ + RK_MUXROUTE_PMU(0, RK_PC1, 1, 0x0110, WRITE_MASK_VAL(5, 4, 0)), /* PWM2 IO mux M0 */ + RK_MUXROUTE_PMU(0, RK_PB6, 4, 0x0110, WRITE_MASK_VAL(5, 4, 1)), /* PWM2 IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PB3, 2, 0x0300, WRITE_MASK_VAL(0, 0, 0)), /* CAN0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 4, 0x0300, WRITE_MASK_VAL(0, 0, 1)), /* CAN0 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 3, 0x0300, WRITE_MASK_VAL(2, 2, 0)), /* CAN1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 3, 0x0300, WRITE_MASK_VAL(2, 2, 1)), /* CAN1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB5, 3, 0x0300, WRITE_MASK_VAL(4, 4, 0)), /* CAN2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB2, 4, 0x0300, WRITE_MASK_VAL(4, 4, 1)), /* CAN2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC4, 1, 0x0300, WRITE_MASK_VAL(6, 6, 0)), /* HPDIN IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PC2, 2, 0x0300, WRITE_MASK_VAL(6, 6, 1)), /* HPDIN IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 3, 0x0300, WRITE_MASK_VAL(8, 8, 0)), /* GMAC1 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PA7, 3, 0x0300, WRITE_MASK_VAL(8, 8, 1)), /* GMAC1 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PD1, 1, 0x0300, WRITE_MASK_VAL(10, 10, 0)), /* HDMITX IO mux M0 */ + RK_MUXROUTE_GRF(0, RK_PC7, 1, 0x0300, WRITE_MASK_VAL(10, 10, 1)), /* HDMITX IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PB6, 1, 0x0300, WRITE_MASK_VAL(14, 14, 0)), /* I2C2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB4, 1, 0x0300, WRITE_MASK_VAL(14, 14, 1)), /* I2C2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA0, 1, 0x0304, WRITE_MASK_VAL(0, 0, 0)), /* I2C3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB6, 4, 0x0304, WRITE_MASK_VAL(0, 0, 1)), /* I2C3 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB2, 1, 0x0304, WRITE_MASK_VAL(2, 2, 0)), /* I2C4 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PB1, 2, 0x0304, WRITE_MASK_VAL(2, 2, 1)), /* I2C4 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB4, 4, 0x0304, WRITE_MASK_VAL(4, 4, 0)), /* I2C5 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PD0, 2, 0x0304, WRITE_MASK_VAL(4, 4, 1)), /* I2C5 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB1, 5, 0x0304, WRITE_MASK_VAL(14, 14, 0)), /* PWM8 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 4, 0x0304, WRITE_MASK_VAL(14, 14, 1)), /* PWM8 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB2, 5, 0x0308, WRITE_MASK_VAL(0, 0, 0)), /* PWM9 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD6, 4, 0x0308, WRITE_MASK_VAL(0, 0, 1)), /* PWM9 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB5, 5, 0x0308, WRITE_MASK_VAL(2, 2, 0)), /* PWM10 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PA1, 2, 0x0308, WRITE_MASK_VAL(2, 2, 1)), /* PWM10 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB6, 5, 0x0308, WRITE_MASK_VAL(4, 4, 0)), /* PWM11 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC0, 3, 0x0308, WRITE_MASK_VAL(4, 4, 1)), /* PWM11 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PB7, 2, 0x0308, WRITE_MASK_VAL(6, 6, 0)), /* PWM12 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(6, 6, 1)), /* PWM12 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC0, 2, 0x0308, WRITE_MASK_VAL(8, 8, 0)), /* PWM13 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC6, 1, 0x0308, WRITE_MASK_VAL(8, 8, 1)), /* PWM13 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 1, 0x0308, WRITE_MASK_VAL(10, 10, 0)), /* PWM14 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 1, 0x0308, WRITE_MASK_VAL(10, 10, 1)), /* PWM14 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC5, 1, 0x0308, WRITE_MASK_VAL(12, 12, 0)), /* PWM15 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC3, 1, 0x0308, WRITE_MASK_VAL(12, 12, 1)), /* PWM15 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PD2, 3, 0x0308, WRITE_MASK_VAL(14, 14, 0)), /* SDMMC2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA5, 5, 0x0308, WRITE_MASK_VAL(14, 14, 1)), /* SDMMC2 IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PB5, 2, 0x030c, WRITE_MASK_VAL(0, 0, 0)), /* SPI0 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD3, 3, 0x030c, WRITE_MASK_VAL(0, 0, 1)), /* SPI0 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB5, 3, 0x030c, WRITE_MASK_VAL(2, 2, 0)), /* SPI1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC3, 3, 0x030c, WRITE_MASK_VAL(2, 2, 1)), /* SPI1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PC1, 4, 0x030c, WRITE_MASK_VAL(4, 4, 0)), /* SPI2 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PA0, 3, 0x030c, WRITE_MASK_VAL(4, 4, 1)), /* SPI2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PB3, 4, 0x030c, WRITE_MASK_VAL(6, 6, 0)), /* SPI3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 2, 0x030c, WRITE_MASK_VAL(6, 6, 1)), /* SPI3 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB4, 2, 0x030c, WRITE_MASK_VAL(8, 8, 0)), /* UART1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 4, 0x030c, WRITE_MASK_VAL(8, 8, 1)), /* UART1 IO mux M1 */ + RK_MUXROUTE_GRF(0, RK_PD1, 1, 0x030c, WRITE_MASK_VAL(10, 10, 0)), /* UART2 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 2, 0x030c, WRITE_MASK_VAL(10, 10, 1)), /* UART2 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA1, 2, 0x030c, WRITE_MASK_VAL(12, 12, 0)), /* UART3 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB7, 4, 0x030c, WRITE_MASK_VAL(12, 12, 1)), /* UART3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA6, 2, 0x030c, WRITE_MASK_VAL(14, 14, 0)), /* UART4 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PB2, 4, 0x030c, WRITE_MASK_VAL(14, 14, 1)), /* UART4 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA2, 3, 0x0310, WRITE_MASK_VAL(0, 0, 0)), /* UART5 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC2, 4, 0x0310, WRITE_MASK_VAL(0, 0, 1)), /* UART5 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA4, 3, 0x0310, WRITE_MASK_VAL(2, 2, 0)), /* UART6 IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PD5, 3, 0x0310, WRITE_MASK_VAL(2, 2, 1)), /* UART6 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PA6, 3, 0x0310, WRITE_MASK_VAL(5, 4, 0)), /* UART7 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC4, 4, 0x0310, WRITE_MASK_VAL(5, 4, 1)), /* UART7 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(5, 4, 2)), /* UART7 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC5, 3, 0x0310, WRITE_MASK_VAL(6, 6, 0)), /* UART8 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD7, 4, 0x0310, WRITE_MASK_VAL(6, 6, 1)), /* UART8 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PB0, 3, 0x0310, WRITE_MASK_VAL(9, 8, 0)), /* UART9 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC5, 4, 0x0310, WRITE_MASK_VAL(9, 8, 1)), /* UART9 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA4, 4, 0x0310, WRITE_MASK_VAL(9, 8, 2)), /* UART9 IO mux M2 */ + RK_MUXROUTE_GRF(1, RK_PA2, 1, 0x0310, WRITE_MASK_VAL(11, 10, 0)), /* I2S1 IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PC6, 4, 0x0310, WRITE_MASK_VAL(11, 10, 1)), /* I2S1 IO mux M1 */ + RK_MUXROUTE_GRF(2, RK_PD0, 5, 0x0310, WRITE_MASK_VAL(11, 10, 2)), /* I2S1 IO mux M2 */ + RK_MUXROUTE_GRF(2, RK_PC1, 1, 0x0310, WRITE_MASK_VAL(12, 12, 0)), /* I2S2 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PB6, 5, 0x0310, WRITE_MASK_VAL(12, 12, 1)), /* I2S2 IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PA2, 4, 0x0310, WRITE_MASK_VAL(14, 14, 0)), /* I2S3 IO mux M0 */ + RK_MUXROUTE_GRF(4, RK_PC2, 5, 0x0310, WRITE_MASK_VAL(14, 14, 1)), /* I2S3 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(1, RK_PA6, 3, 0x0314, WRITE_MASK_VAL(1, 0, 0)), /* PDM IO mux M0 */ + RK_MUXROUTE_GRF(3, RK_PD6, 5, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PA0, 4, 0x0314, WRITE_MASK_VAL(1, 0, 1)), /* PDM IO mux M1 */ + RK_MUXROUTE_GRF(3, RK_PC4, 5, 0x0314, WRITE_MASK_VAL(1, 0, 2)), /* PDM IO mux M2 */ + RK_MUXROUTE_GRF(0, RK_PA5, 3, 0x0314, WRITE_MASK_VAL(3, 2, 0)), /* PCIE20 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 1)), /* PCIE20 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PB0, 4, 0x0314, WRITE_MASK_VAL(3, 2, 2)), /* PCIE20 IO mux M2 */ + RK_MUXROUTE_GRF(0, RK_PA4, 3, 0x0314, WRITE_MASK_VAL(5, 4, 0)), /* PCIE30X1 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD2, 4, 0x0314, WRITE_MASK_VAL(5, 4, 1)), /* PCIE30X1 IO mux M1 */ + RK_MUXROUTE_GRF(1, RK_PA5, 4, 0x0314, WRITE_MASK_VAL(5, 4, 2)), /* PCIE30X1 IO mux M2 */ + RK_MUXROUTE_GRF(0, RK_PA6, 2, 0x0314, WRITE_MASK_VAL(7, 6, 0)), /* PCIE30X2 IO mux M0 */ + RK_MUXROUTE_GRF(2, RK_PD4, 4, 0x0314, WRITE_MASK_VAL(7, 6, 1)), /* PCIE30X2 IO mux M1 */ + RK_MUXROUTE_GRF(4, RK_PC2, 4, 0x0314, WRITE_MASK_VAL(7, 6, 2)), /* PCIE30X2 IO mux M2 */ +}; + +static rt_err_t rk3568_set_mux(struct rockchip_pin_bank *pin_bank, int pin, int mux) +{ + rt_uint8_t bit; + rt_uint32_t data; + rt_uint32_t route_location, route_reg, route_val; + int iomux_num = (pin / 8), reg, mask; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if ((pin_bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)) + { + regmap = drvdata->regmap_pmu; + } + else + { + regmap = drvdata->regmap_base; + } + + reg = pin_bank->iomux[iomux_num].offset; + if ((pin % 8) >= 4) + { + reg += 0x4; + } + bit = (pin % 4) * 4; + mask = 0xf; + + if (pin_bank->route_mask & RT_BIT(pin)) + { + if (rockchip_translate_mux_route(pin_bank, pin, mux, &route_location, + &route_reg, &route_val)) + { + rt_err_t err; + struct rt_syscon *route_regmap; + + /* handle special locations */ + switch (route_location) + { + case ROCKCHIP_ROUTE_PMU: + route_regmap = drvdata->regmap_pmu; + break; + + case ROCKCHIP_ROUTE_GRF: + route_regmap = drvdata->regmap_base; + break; + + default: + route_regmap = regmap; + break; + } + + if ((err = rt_syscon_write(route_regmap, route_reg, route_val))) + { + return err; + } + } + } + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3568_PULL_PMU_OFFSET 0x20 +#define RK3568_PULL_GRF_OFFSET 0x80 +#define RK3568_PULL_BITS_PER_PIN 2 +#define RK3568_PULL_PINS_PER_REG 8 +#define RK3568_PULL_BANK_STRIDE 0x10 + +static rt_err_t rk3568_set_pull(struct rockchip_pin_bank *pin_bank, int pin, int pull) +{ + int reg, pull_value; + rt_uint32_t data; + rt_uint8_t bit, type; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + { + return -RT_ENOSYS; + } + + if (pin_bank->bank_num == 0) + { + regmap = drvdata->regmap_pmu; + reg = RK3568_PULL_PMU_OFFSET; + reg += pin_bank->bank_num * RK3568_PULL_BANK_STRIDE; + } + else + { + regmap = drvdata->regmap_base; + reg = RK3568_PULL_GRF_OFFSET; + reg += (pin_bank->bank_num - 1) * RK3568_PULL_BANK_STRIDE; + } + + reg += ((pin / RK3568_PULL_PINS_PER_REG) * 4); + bit = (pin % RK3568_PULL_PINS_PER_REG); + bit *= RK3568_PULL_BITS_PER_PIN; + + type = pin_bank->pull_type[pin / 8]; + pull_value = rockchip_translate_pull_value(type, pull); + + /* + * pull-up being 1 for everything except the GPIO0_D3-D6, + * where that pull up value becomes 3 + */ + if (pin_bank->bank_num == 0 && pin >= RK_GPIO0_D3 && pin <= RK_GPIO0_D6) + { + if (pull_value == 1) + { + pull_value = 3; + } + } + + if (pull_value < 0) + { + LOG_E("Not supported pull = %d, fixup the code or firmware", pull); + + return pull_value; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data |= (pull_value << bit); + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3568_DRV_PMU_OFFSET 0x70 +#define RK3568_DRV_GRF_OFFSET 0x200 +#define RK3568_DRV_BITS_PER_PIN 8 +#define RK3568_DRV_PINS_PER_REG 2 +#define RK3568_DRV_BANK_STRIDE 0x40 + +#define RK3568_GRF_GPIO1C5_DS 0x840 +#define RK3568_GRF_GPIO2A2_DS 0x844 +#define RK3568_GRF_GPIO2B0_DS 0x848 +#define RK3568_GRF_GPIO3A0_DS 0x84c +#define RK3568_GRF_GPIO3A6_DS 0x850 +#define RK3568_GRF_GPIO4A0_DS 0x854 + +static rt_err_t rk3568_set_drive(struct rockchip_pin_bank *pin_bank, int pin, int strength) +{ + rt_err_t err; + rt_uint8_t bit; + rt_uint32_t data; + int reg, drv = (1 << (strength + 1)) - 1; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if (pin_bank->bank_num == 0) + { + regmap = drvdata->regmap_pmu; + reg = RK3568_DRV_PMU_OFFSET; + } + else + { + regmap = drvdata->regmap_base; + reg = RK3568_DRV_GRF_OFFSET; + reg += (pin_bank->bank_num - 1) * RK3568_DRV_BANK_STRIDE; + } + + reg += ((pin / RK3568_DRV_PINS_PER_REG) * 4); + bit = (pin % RK3568_DRV_PINS_PER_REG); + bit *= RK3568_DRV_BITS_PER_PIN; + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (drv << bit); + + if ((err = rt_syscon_write(regmap, reg, data))) + { + return err; + } + + if (pin_bank->bank_num == RK_GPIO1 && pin == RK_PC5) + { + reg = RK3568_GRF_GPIO1C5_DS; + } + else if (pin_bank->bank_num == RK_GPIO2 && pin == RK_PA2) + { + reg = RK3568_GRF_GPIO2A2_DS; + } + else if (pin_bank->bank_num == RK_GPIO2 && pin == RK_PB0) + { + reg = RK3568_GRF_GPIO2B0_DS; + } + else if (pin_bank->bank_num == RK_GPIO3 && pin == RK_PA0) + { + reg = RK3568_GRF_GPIO3A0_DS; + } + else if (pin_bank->bank_num == RK_GPIO3 && pin == RK_PA6) + { + reg = RK3568_GRF_GPIO3A6_DS; + } + else if (pin_bank->bank_num == RK_GPIO4 && pin == RK_PA0) + { + reg = RK3568_GRF_GPIO4A0_DS; + } + else + { + return RT_EOK; + } + + data = ((1 << RK3568_DRV_BITS_PER_PIN) - 1) << 16; + data |= drv; + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3568_SCHMITT_BITS_PER_PIN 2 +#define RK3568_SCHMITT_PINS_PER_REG 8 +#define RK3568_SCHMITT_BANK_STRIDE 0x10 +#define RK3568_SCHMITT_GRF_OFFSET 0xc0 +#define RK3568_SCHMITT_PMUGRF_OFFSET 0x30 + +static rt_err_t rk3568_set_schmitt(struct rockchip_pin_bank *pin_bank, int pin, int enable) +{ + int reg; + rt_uint8_t bit; + rt_uint32_t data; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if (pin_bank->bank_num == 0) + { + regmap = drvdata->regmap_pmu; + reg = RK3568_SCHMITT_PMUGRF_OFFSET; + } + else + { + regmap = drvdata->regmap_base; + reg = RK3568_SCHMITT_GRF_OFFSET; + reg += (pin_bank->bank_num - 1) * RK3568_SCHMITT_BANK_STRIDE; + } + + reg += ((pin / RK3568_SCHMITT_PINS_PER_REG) * 4); + bit = pin % RK3568_SCHMITT_PINS_PER_REG; + bit *= RK3568_SCHMITT_BITS_PER_PIN; + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3568_SCHMITT_BITS_PER_PIN) - 1) << (bit + 16); + data |= (enable << bit); + + return rt_syscon_write(regmap, reg, data); +} + +static struct rockchip_pin_bank rk3568_pin_banks[] = +{ + PIN_BANK_IOMUX_FLAGS(0, 32, "gpio0", IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, + IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT, IOMUX_SOURCE_PMU | IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT), + PIN_BANK_IOMUX_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT, IOMUX_WIDTH_4BIT), +}; + +static struct rockchip_pin_ctrl rk3568_pin_ctrl = +{ + .pin_banks = rk3568_pin_banks, + .banks_nr = RT_ARRAY_SIZE(rk3568_pin_banks), + .label = "RK3568-GPIO", + .type = RK3568, + .grf_mux_offset = 0x0, + .pmu_mux_offset = 0x0, + .grf_drv_offset = RK3568_DRV_GRF_OFFSET, + .pmu_drv_offset = RK3568_DRV_PMU_OFFSET, + .iomux_routes = rk3568_mux_route_data, + .niomux_routes = RT_ARRAY_SIZE(rk3568_mux_route_data), + .set_mux = rk3568_set_mux, + .set_pull = rk3568_set_pull, + .set_drive = rk3568_set_drive, + .set_schmitt = rk3568_set_schmitt, +}; + +static rt_err_t rk3576_set_mux(struct rockchip_pin_bank *pin_bank, int pin, int mux) +{ + rt_uint8_t bit; + rt_uint32_t data; + int iomux_num = (pin / 8), reg, mask; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + regmap = drvdata->regmap_base; + reg = pin_bank->iomux[iomux_num].offset; + + if ((pin % 8) >= 4) + { + reg += 0x4; + } + + bit = (pin % 4) * 4; + mask = 0xf; + + data = (mask << (bit + 16)); + data |= (mux & mask) << bit; + + if (pin_bank->bank_num == 0 && pin >= RK_PB4 && pin <= RK_PB7) + { + /* GPIO0_IOC_GPIO0B_IOMUX_SEL_H */ + reg += 0x1ff4; + } + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3576_DRV_BITS_PER_PIN 4 +#define RK3576_DRV_PINS_PER_REG 4 +#define RK3576_DRV_GPIO0_AL_OFFSET 0x10 +#define RK3576_DRV_GPIO0_BH_OFFSET 0x2014 +#define RK3576_DRV_GPIO1_OFFSET 0x6020 +#define RK3576_DRV_GPIO2_OFFSET 0x6040 +#define RK3576_DRV_GPIO3_OFFSET 0x6060 +#define RK3576_DRV_GPIO4_AL_OFFSET 0x6080 +#define RK3576_DRV_GPIO4_CL_OFFSET 0xa090 +#define RK3576_DRV_GPIO4_DL_OFFSET 0xb098 + +static rt_err_t rk3576_set_drive(struct rockchip_pin_bank *pin_bank, int pin_num, int strength) +{ + rt_uint8_t bit; + rt_uint32_t data; + int reg, drv = ((strength & RT_BIT(2)) >> 2) | ((strength & RT_BIT(0)) << 2) | (strength & RT_BIT(1)); + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + regmap = drvdata->regmap_base; + + if (pin_bank->bank_num == 0 && pin_num < 12) + { + reg = RK3576_DRV_GPIO0_AL_OFFSET; + } + else if (pin_bank->bank_num == 0) + { + reg = RK3576_DRV_GPIO0_BH_OFFSET - 0xc; + } + else if (pin_bank->bank_num == 1) + { + reg = RK3576_DRV_GPIO1_OFFSET; + } + else if (pin_bank->bank_num == 2) + { + reg = RK3576_DRV_GPIO2_OFFSET; + } + else if (pin_bank->bank_num == 3) + { + reg = RK3576_DRV_GPIO3_OFFSET; + } + else if (pin_bank->bank_num == 4 && pin_num < 16) + { + reg = RK3576_DRV_GPIO4_AL_OFFSET; + } + else if (pin_bank->bank_num == 4 && pin_num < 24) + { + reg = RK3576_DRV_GPIO4_CL_OFFSET - 0x10; + } + else if (pin_bank->bank_num == 4) + { + reg = RK3576_DRV_GPIO4_DL_OFFSET - 0x18; + } + else + { + reg = 0; + LOG_E("Unsupported bank_num %d", pin_bank->bank_num); + } + + reg += ((pin_num / RK3576_DRV_PINS_PER_REG) * 4); + bit = pin_num % RK3576_DRV_PINS_PER_REG; + bit *= RK3576_DRV_BITS_PER_PIN; + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3576_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (drv << bit); + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3576_PULL_BITS_PER_PIN 2 +#define RK3576_PULL_PINS_PER_REG 8 +#define RK3576_PULL_GPIO0_AL_OFFSET 0x20 +#define RK3576_PULL_GPIO0_BH_OFFSET 0x2028 +#define RK3576_PULL_GPIO1_OFFSET 0x6110 +#define RK3576_PULL_GPIO2_OFFSET 0x6120 +#define RK3576_PULL_GPIO3_OFFSET 0x6130 +#define RK3576_PULL_GPIO4_AL_OFFSET 0x6140 +#define RK3576_PULL_GPIO4_CL_OFFSET 0xa148 +#define RK3576_PULL_GPIO4_DL_OFFSET 0xb14c + +static rt_err_t rk3576_set_pull(struct rockchip_pin_bank *pin_bank, int pin_num, int pull) +{ + int reg, pull_value; + rt_uint32_t data; + rt_uint8_t bit, type; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + { + return -RT_ENOSYS; + } + + regmap = drvdata->regmap_base; + + if (pin_bank->bank_num == 0 && pin_num < 12) + { + reg = RK3576_PULL_GPIO0_AL_OFFSET; + } + else if (pin_bank->bank_num == 0) + { + reg = RK3576_PULL_GPIO0_BH_OFFSET - 0x4; + } + else if (pin_bank->bank_num == 1) + { + reg = RK3576_PULL_GPIO1_OFFSET; + } + else if (pin_bank->bank_num == 2) + { + reg = RK3576_PULL_GPIO2_OFFSET; + } + else if (pin_bank->bank_num == 3) + { + reg = RK3576_PULL_GPIO3_OFFSET; + } + else if (pin_bank->bank_num == 4 && pin_num < 16) + { + reg = RK3576_PULL_GPIO4_AL_OFFSET; + } + else if (pin_bank->bank_num == 4 && pin_num < 24) + { + reg = RK3576_PULL_GPIO4_CL_OFFSET - 0x8; + } + else if (pin_bank->bank_num == 4) + { + reg = RK3576_PULL_GPIO4_DL_OFFSET - 0xc; + } + else + { + reg = 0; + LOG_E("Unsupported bank_num %d", pin_bank->bank_num); + } + + reg += ((pin_num / RK3576_PULL_PINS_PER_REG) * 4); + bit = pin_num % RK3576_PULL_PINS_PER_REG; + bit *= RK3576_PULL_BITS_PER_PIN; + + type = pin_bank->pull_type[pin_num / 8]; + pull_value = rockchip_translate_pull_value(type, pull); + + if (pull_value < 0) + { + LOG_E("Not supported pull = %d, fixup the code or firmware", pull); + + return pull_value; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3576_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data |= (pull_value << bit); + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3576_SMT_BITS_PER_PIN 1 +#define RK3576_SMT_PINS_PER_REG 8 +#define RK3576_SMT_GPIO0_AL_OFFSET 0x30 +#define RK3576_SMT_GPIO0_BH_OFFSET 0x2040 +#define RK3576_SMT_GPIO1_OFFSET 0x6210 +#define RK3576_SMT_GPIO2_OFFSET 0x6220 +#define RK3576_SMT_GPIO3_OFFSET 0x6230 +#define RK3576_SMT_GPIO4_AL_OFFSET 0x6240 +#define RK3576_SMT_GPIO4_CL_OFFSET 0xA248 +#define RK3576_SMT_GPIO4_DL_OFFSET 0xB24C + +static rt_err_t rk3576_set_schmitt(struct rockchip_pin_bank *pin_bank, int pin_num, int enable) +{ + int reg; + rt_uint8_t bit; + rt_uint32_t data; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + regmap = drvdata->regmap_base; + + if (pin_bank->bank_num == 0 && pin_num < 12) + { + reg = RK3576_SMT_GPIO0_AL_OFFSET; + } + else if (pin_bank->bank_num == 0) + { + reg = RK3576_SMT_GPIO0_BH_OFFSET - 0x4; + } + else if (pin_bank->bank_num == 1) + { + reg = RK3576_SMT_GPIO1_OFFSET; + } + else if (pin_bank->bank_num == 2) + { + reg = RK3576_SMT_GPIO2_OFFSET; + } + else if (pin_bank->bank_num == 3) + { + reg = RK3576_SMT_GPIO3_OFFSET; + } + else if (pin_bank->bank_num == 4 && pin_num < 16) + { + reg = RK3576_SMT_GPIO4_AL_OFFSET; + } + else if (pin_bank->bank_num == 4 && pin_num < 24) + { + reg = RK3576_SMT_GPIO4_CL_OFFSET - 0x8; + } + else if (pin_bank->bank_num == 4) + { + reg = RK3576_SMT_GPIO4_DL_OFFSET - 0xc; + } + else + { + reg = 0; + LOG_E("Unsupported bank_num %d", pin_bank->bank_num); + } + + reg += ((pin_num / RK3576_SMT_PINS_PER_REG) * 4); + bit = pin_num % RK3576_SMT_PINS_PER_REG; + bit *= RK3576_SMT_BITS_PER_PIN; + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3576_SMT_BITS_PER_PIN) - 1) << (bit + 16); + data |= (enable << bit); + + return rt_syscon_write(regmap, reg, data); +} + +static struct rockchip_pin_bank rk3576_pin_banks[] = +{ + PIN_BANK_OFFSET4(0, "gpio0", 0, 0x8, 0x2004, 0x200C), + PIN_BANK_OFFSET4(1, "gpio1", 0x4020, 0x4028, 0x4030, 0x4038), + PIN_BANK_OFFSET4(2, "gpio2", 0x4040, 0x4048, 0x4050, 0x4058), + PIN_BANK_OFFSET4(3, "gpio3", 0x4060, 0x4068, 0x4070, 0x4078), + PIN_BANK_OFFSET4(4, "gpio4", 0x4080, 0x4088, 0xA390, 0xB398), +}; + +static const struct rockchip_pin_ctrl rk3576_pin_ctrl = +{ + .pin_banks = rk3576_pin_banks, + .banks_nr = RT_ARRAY_SIZE(rk3576_pin_banks), + .pins_nr = 160, + .grf_mux_offset = 0x0, + .set_mux = rk3576_set_mux, + .set_pull = rk3576_set_pull, + .set_drive = rk3576_set_drive, + .set_schmitt = rk3576_set_schmitt, +}; + +static rt_err_t rk3588_set_mux(struct rockchip_pin_bank *pin_bank, int pin, int mux) +{ + rt_err_t err; + rt_uint8_t bit; + rt_uint32_t data; + int iomux_num = (pin / 8), reg, mask; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + regmap = drvdata->regmap_base; + reg = pin_bank->iomux[iomux_num].offset; + if (pin % 8 >= 4) + { + reg += 0x4; + } + bit = (pin % 4) * 4; + mask = 0xf; + + if (pin_bank->bank_num == 0) + { + if (pin >= RK_PB4 && pin <= RK_PD7) + { + rt_uint32_t reg0 = 0; + + if (mux < 8) + { + /* PMU2_IOC_BASE */ + reg0 = reg + 0x4000 - 0xc; + data = mask << (bit + 16); + data |= (mux & mask) << bit; + err = rt_syscon_write(regmap, reg0, data); + + /* BUS_IOC_BASE */ + reg0 = reg + 0x8000; + data = (mask << (bit + 16)); + rt_syscon_write(regmap, reg0, data); + } + else + { + /* PMU2_IOC_BASE */ + reg0 = reg + 0x4000 - 0xc; + data = mask << (bit + 16); + data |= 8 << bit; + err = rt_syscon_write(regmap, reg0, data); + + /* BUS_IOC_BASE */ + reg0 = reg + 0x8000; + data = mask << (bit + 16); + data |= mux << bit; + rt_syscon_write(regmap, reg0, data); + } + } + else + { + data = mask << (bit + 16); + data |= (mux & mask) << bit; + err = rt_syscon_write(regmap, reg, data); + } + + return err; + } + else if (pin_bank->bank_num > 0) + { + /* BUS_IOC_BASE */ + reg += 0x8000; + } + + data = mask << (bit + 16); + data |= (mux & mask) << bit; + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3588_PMU1_IOC_REG 0x0000 +#define RK3588_PMU2_IOC_REG 0x4000 +#define RK3588_BUS_IOC_REG 0x8000 +#define RK3588_VCCIO1_4_IOC_REG 0x9000 +#define RK3588_VCCIO3_5_IOC_REG 0xa000 +#define RK3588_VCCIO2_IOC_REG 0xb000 +#define RK3588_VCCIO6_IOC_REG 0xc000 +#define RK3588_EMMC_IOC_REG 0xd000 + +#define RK3588_PULL_BITS_PER_PIN 2 +#define RK3588_PULL_PINS_PER_REG 8 + +static const rt_uint32_t rk3588_pull_regs[][2] = +{ + { RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0020 }, + { RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0024 }, + { RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0028 }, + { RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x002c }, + { RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0030 }, + { RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0110 }, + { RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0114 }, + { RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0118 }, + { RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x011c }, + { RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0120 }, + { RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0120 }, + { RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0124 }, + { RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0128 }, + { RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x012c }, + { RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0130 }, + { RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0134 }, + { RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0138 }, + { RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x013c }, + { RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0140 }, + { RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0144 }, + { RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0148 }, + { RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0148 }, + { RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x014c }, +}; + +static rt_err_t rk3588_set_pull(struct rockchip_pin_bank *pin_bank, int pin, int pull) +{ + int reg, pull_value; + rt_uint32_t data; + rt_uint8_t bit, type; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) + { + return -RT_ENOSYS; + } + + for (int i = RT_ARRAY_SIZE(rk3588_pull_regs) - 1; i >= 0; --i) + { + if (pin >= rk3588_pull_regs[i][0]) + { + reg = rk3588_pull_regs[i][1]; + reg += ((pin - rk3588_pull_regs[i][0]) / RK3588_PULL_PINS_PER_REG) * 4; + bit = ((pin % 32) % RK3588_PULL_PINS_PER_REG) * RK3588_PULL_BITS_PER_PIN; + + goto _find; + } + } + + return -RT_EINVAL; + +_find: + regmap = drvdata->regmap_base; + + type = pin_bank->pull_type[pin / 8]; + pull_value = rockchip_translate_pull_value(type, pull); + + if (pull_value < 0) + { + LOG_E("Not supported pull = %d, fixup the code or firmware", pull); + + return pull_value; + } + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_PULL_BITS_PER_PIN) - 1) << (bit + 16); + data |= pull_value << bit; + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3588_DRV_BITS_PER_PIN 4 +#define RK3588_DRV_PINS_PER_REG 4 + +static const rt_uint32_t rk3588_drive_regs[][2] = +{ + { RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0010 }, + { RK_GPIO0_A4, RK3588_PMU1_IOC_REG + 0x0014 }, + { RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0018 }, + { RK_GPIO0_B4, RK3588_PMU2_IOC_REG + 0x0014 }, + { RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0018 }, + { RK_GPIO0_C4, RK3588_PMU2_IOC_REG + 0x001c }, + { RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0020 }, + { RK_GPIO0_D4, RK3588_PMU2_IOC_REG + 0x0024 }, + { RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0020 }, + { RK_GPIO1_A4, RK3588_VCCIO1_4_IOC_REG + 0x0024 }, + { RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0028 }, + { RK_GPIO1_B4, RK3588_VCCIO1_4_IOC_REG + 0x002c }, + { RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0030 }, + { RK_GPIO1_C4, RK3588_VCCIO1_4_IOC_REG + 0x0034 }, + { RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x0038 }, + { RK_GPIO1_D4, RK3588_VCCIO1_4_IOC_REG + 0x003c }, + { RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0040 }, + { RK_GPIO2_A4, RK3588_VCCIO3_5_IOC_REG + 0x0044 }, + { RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0048 }, + { RK_GPIO2_B4, RK3588_VCCIO3_5_IOC_REG + 0x004c }, + { RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0050 }, + { RK_GPIO2_C4, RK3588_VCCIO3_5_IOC_REG + 0x0054 }, + { RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x0058 }, + { RK_GPIO2_D4, RK3588_EMMC_IOC_REG + 0x005c }, + { RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0060 }, + { RK_GPIO3_A4, RK3588_VCCIO3_5_IOC_REG + 0x0064 }, + { RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0068 }, + { RK_GPIO3_B4, RK3588_VCCIO3_5_IOC_REG + 0x006c }, + { RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0070 }, + { RK_GPIO3_C4, RK3588_VCCIO3_5_IOC_REG + 0x0074 }, + { RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x0078 }, + { RK_GPIO3_D4, RK3588_VCCIO3_5_IOC_REG + 0x007c }, + { RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0080 }, + { RK_GPIO4_A4, RK3588_VCCIO6_IOC_REG + 0x0084 }, + { RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0088 }, + { RK_GPIO4_B4, RK3588_VCCIO6_IOC_REG + 0x008c }, + { RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0090 }, + { RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0090 }, + { RK_GPIO4_C4, RK3588_VCCIO3_5_IOC_REG + 0x0094 }, + { RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x0098 }, + { RK_GPIO4_D4, RK3588_VCCIO2_IOC_REG + 0x009c }, +}; + +static rt_err_t rk3588_set_drive(struct rockchip_pin_bank *pin_bank, int pin, int strength) +{ + int reg; + rt_uint8_t bit; + rt_uint32_t data; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + for (int i = RT_ARRAY_SIZE(rk3588_drive_regs) - 1; i >= 0; --i) + { + if (pin >= rk3588_drive_regs[i][0]) + { + reg = rk3588_drive_regs[i][1]; + reg += ((pin - rk3588_drive_regs[i][0]) / RK3588_DRV_PINS_PER_REG) * 4; + bit = ((pin % 32) % RK3588_DRV_PINS_PER_REG) * RK3588_DRV_BITS_PER_PIN; + + goto _find; + } + } + + return -RT_EINVAL; + +_find: + regmap = drvdata->regmap_base; + + /* enable the write to the equivalent lower bits */ + data = ((1 << ROCKCHIP_DRV_BITS_PER_PIN) - 1) << (bit + 16); + data |= (strength << bit); + + return rt_syscon_write(regmap, reg, data); +} + +#define RK3588_SMT_BITS_PER_PIN 1 +#define RK3588_SMT_PINS_PER_REG 8 + +static const rt_uint32_t rk3588_schmitt_regs[][2] = +{ + { RK_GPIO0_A0, RK3588_PMU1_IOC_REG + 0x0030 }, + { RK_GPIO0_B0, RK3588_PMU1_IOC_REG + 0x0034 }, + { RK_GPIO0_B5, RK3588_PMU2_IOC_REG + 0x0040 }, + { RK_GPIO0_C0, RK3588_PMU2_IOC_REG + 0x0044 }, + { RK_GPIO0_D0, RK3588_PMU2_IOC_REG + 0x0048 }, + { RK_GPIO1_A0, RK3588_VCCIO1_4_IOC_REG + 0x0210 }, + { RK_GPIO1_B0, RK3588_VCCIO1_4_IOC_REG + 0x0214 }, + { RK_GPIO1_C0, RK3588_VCCIO1_4_IOC_REG + 0x0218 }, + { RK_GPIO1_D0, RK3588_VCCIO1_4_IOC_REG + 0x021c }, + { RK_GPIO2_A0, RK3588_EMMC_IOC_REG + 0x0220 }, + { RK_GPIO2_A6, RK3588_VCCIO3_5_IOC_REG + 0x0220 }, + { RK_GPIO2_B0, RK3588_VCCIO3_5_IOC_REG + 0x0224 }, + { RK_GPIO2_C0, RK3588_VCCIO3_5_IOC_REG + 0x0228 }, + { RK_GPIO2_D0, RK3588_EMMC_IOC_REG + 0x022c }, + { RK_GPIO3_A0, RK3588_VCCIO3_5_IOC_REG + 0x0230 }, + { RK_GPIO3_B0, RK3588_VCCIO3_5_IOC_REG + 0x0234 }, + { RK_GPIO3_C0, RK3588_VCCIO3_5_IOC_REG + 0x0238 }, + { RK_GPIO3_D0, RK3588_VCCIO3_5_IOC_REG + 0x023c }, + { RK_GPIO4_A0, RK3588_VCCIO6_IOC_REG + 0x0240 }, + { RK_GPIO4_B0, RK3588_VCCIO6_IOC_REG + 0x0244 }, + { RK_GPIO4_C0, RK3588_VCCIO6_IOC_REG + 0x0248 }, + { RK_GPIO4_C2, RK3588_VCCIO3_5_IOC_REG + 0x0248 }, + { RK_GPIO4_D0, RK3588_VCCIO2_IOC_REG + 0x024c }, +}; + +static rt_err_t rk3588_set_schmitt(struct rockchip_pin_bank *pin_bank, int pin, int enable) +{ + int reg; + rt_uint8_t bit; + rt_uint32_t data; + struct rt_syscon *regmap; + struct rockchip_pin_data *drvdata = pin_bank->drvdata; + + for (int i = RT_ARRAY_SIZE(rk3588_schmitt_regs) - 1; i >= 0; --i) + { + if (pin >= rk3588_schmitt_regs[i][0]) + { + reg = rk3588_schmitt_regs[i][1]; + reg += ((pin - rk3588_schmitt_regs[i][0]) / RK3588_SMT_PINS_PER_REG) * 4; + bit = ((pin % 32) % RK3588_SMT_PINS_PER_REG) * RK3588_SMT_BITS_PER_PIN; + + goto _find; + } + } + + return -RT_EINVAL; + +_find: + regmap = drvdata->regmap_base; + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3588_SMT_BITS_PER_PIN) - 1) << (bit + 16); + data |= (enable << bit); + + return rt_syscon_write(regmap, reg, data); +} + +static struct rockchip_pin_bank rk3588_pin_banks[] = +{ + PIN_BANK_FLAGS_IOMUX_PULL(0, 32, "gpio0", IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + PIN_BANK_FLAGS_IOMUX_PULL(1, 32, "gpio1", IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + PIN_BANK_FLAGS_IOMUX_PULL(2, 32, "gpio2", IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + PIN_BANK_FLAGS_IOMUX_PULL(3, 32, "gpio3", IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), + PIN_BANK_FLAGS_IOMUX_PULL(4, 32, "gpio4", IOMUX_WIDTH_4BIT, PULL_TYPE_IO_1V8_ONLY), +}; + +static struct rockchip_pin_ctrl rk3588_pin_ctrl = +{ + .pin_banks = rk3588_pin_banks, + .banks_nr = RT_ARRAY_SIZE(rk3588_pin_banks), + .label = "RK3588-GPIO", + .type = RK3588, + .set_mux = rk3588_set_mux, + .set_pull = rk3588_set_pull, + .set_drive = rk3588_set_drive, + .set_schmitt = rk3588_set_schmitt, +}; + +static const struct rt_pin_ctrl_conf_params rockchip_conf_params[] = +{ + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 }, + { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 }, + { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 }, +}; + +static int rockchip_pinconf_prop_name_to_param(const char *propname, rt_uint32_t *default_value) +{ + const struct rt_pin_ctrl_conf_params *params = rockchip_conf_params; + + for (int i = 0; i < RT_ARRAY_SIZE(rockchip_conf_params); ++i, ++params) + { + if (!rt_strcmp(params->propname, propname)) + { + *default_value = params->default_value; + + return params->param; + } + } + + return -RT_ENOSYS; +} + +static rt_err_t rockchip_pinconf_pull_apply(struct rockchip_pin_ctrl *pinctrl, + struct rockchip_pin_bank *pin_bank, rt_uint32_t pin, rt_uint32_t param, rt_uint32_t arg) +{ + rt_err_t err = RT_EOK; + + switch (param) + { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + case PIN_CONFIG_BIAS_BUS_HOLD: + if (pinctrl->set_pull) + { + err = pinctrl->set_pull(pin_bank, pin, param); + } + else + { + err = -RT_ENOSYS; + } + break; + + case PIN_CONFIG_DRIVE_STRENGTH: + if (pinctrl->set_drive) + { + err = pinctrl->set_drive(pin_bank, pin, arg); + } + else + { + err = -RT_ENOSYS; + } + break; + + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: + if (pinctrl->set_schmitt) + { + err = pinctrl->set_schmitt(pin_bank, pin, arg); + } + else + { + err = -RT_ENOSYS; + } + break; + + default: + break; + } + + return err; +} + +static rt_err_t rockchip_pinctrl_confs_apply(struct rt_device *device, void *fw_conf_np) +{ + rt_err_t err = RT_EOK; + const fdt32_t *cell; + int pin, function, param; + rt_uint32_t value, default_value, arg; + struct rt_ofw_prop *prop, *pin_prop; + struct rt_ofw_node *pull_np, *conf_np = fw_conf_np; + struct rockchip_pin_ctrl *pinctrl; + struct rockchip_pin_bank *pin_bank; + struct rockchip_pinctrl_device *pinctrl_dev; + + LOG_D("Pinctrl apply '%s'", rt_ofw_node_full_name(conf_np)); + + pinctrl_dev = rt_container_of(device, struct rockchip_pinctrl_device, parent); + pinctrl = pinctrl_dev->pinctrl; + + rt_ofw_foreach_prop_u32(conf_np, "rockchip,pins", prop, cell, value) + { + /* bank -> pin -> function -> pull */ + pin_bank = &pinctrl->pin_banks[value]; + + cell = rt_ofw_prop_next_u32(prop, cell, &value); + pin = value; + + cell = rt_ofw_prop_next_u32(prop, cell, &value); + function = value; + + cell = rt_ofw_prop_next_u32(prop, cell, &value); + pull_np = rt_ofw_find_node_by_phandle(value); + + if (!pull_np) + { + err = -RT_ERROR; + LOG_E("Firmware ref error in '%s'", rt_ofw_node_full_name(conf_np)); + + break; + } + + if (pinctrl->set_mux) + { + LOG_D("IOMUX from GPIO%d-%c%d to function(%d)", + pin_bank->bank_num, 'A' + (pin % 32) / 8, pin % 8, function); + + err = pinctrl->set_mux(pin_bank, pin, function); + + if (err) + { + break; + } + } + + rt_ofw_foreach_prop(pull_np, pin_prop) + { + if (!rt_strcmp(pin_prop->name, "phandle")) + { + continue; + } + + param = rockchip_pinconf_prop_name_to_param(pin_prop->name, &default_value); + + if (param < 0) + { + err = param; + + break; + } + + if (pin_prop->length < sizeof(*cell)) + { + arg = default_value; + } + else + { + rt_ofw_prop_next_u32(pin_prop, RT_NULL, &arg); + } + + err = rockchip_pinconf_pull_apply(pinctrl, pin_bank, pin, param, arg); + + if (err && err != -RT_ENOSYS) + { + break; + } + } + + rt_ofw_node_put(pull_np); + } + + return err; +} + +static const struct rt_pin_ops rockchip_pinctrl_ops = +{ + .pin_ctrl_confs_apply = rockchip_pinctrl_confs_apply, +}; + +static rt_err_t rockchip_pinctrl_probe(struct rt_platform_device *pdev) +{ + rt_err_t err = RT_EOK; + int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs; + struct rockchip_pin_data *drvdata = RT_NULL; + struct rt_ofw_node *np = pdev->parent.ofw_node; + struct rockchip_pin_ctrl *pinctrl = (typeof(pinctrl))pdev->id->data; + struct rockchip_pin_bank *pin_bank = pinctrl->pin_banks; + struct rockchip_pinctrl_device *pinctrl_dev = rt_malloc(sizeof(*pinctrl_dev)); + + if (!pinctrl_dev) + { + return -RT_ENOMEM; + } + + drvdata = &pinctrl_dev->drvdata; + + if (!(drvdata->regmap_base = rt_syscon_find_by_ofw_phandle(np, "rockchip,grf"))) + { + err = -RT_EIO; + goto _fail; + } + + drvdata->regmap_pmu = rt_syscon_find_by_ofw_phandle(np, "rockchip,pmu"); + drvdata->pinctrl = pinctrl; + + pinctrl_dev->parent.ops = &rockchip_pinctrl_ops; + pinctrl_dev->pinctrl = pinctrl; + pinctrl->pins_nr = 0; + + grf_offs = pinctrl->grf_mux_offset; + pmu_offs = pinctrl->pmu_mux_offset; + drv_pmu_offs = pinctrl->pmu_drv_offset; + drv_grf_offs = pinctrl->grf_drv_offset; + pin_bank = pinctrl->pin_banks; + + for (int i = 0; i < pinctrl->banks_nr; ++i, ++pin_bank) + { + for (int bank_pins = 0, j = 0; j < 4; ++j) + { + int inc; + struct rockchip_drv *drv = &pin_bank->drv[j]; + struct rockchip_iomux *iomux = &pin_bank->iomux[j]; + + if (bank_pins >= pin_bank->nr_pins) + { + break; + } + + /* Preset iomux offset value, set new start value */ + if (iomux->offset >= 0) + { + if ((iomux->type & IOMUX_SOURCE_PMU) || (iomux->type & IOMUX_L_SOURCE_PMU)) + { + pmu_offs = iomux->offset; + } + else + { + grf_offs = iomux->offset; + } + } + else + { + /* Set current iomux offset */ + iomux->offset = ((iomux->type & IOMUX_SOURCE_PMU) || (iomux->type & IOMUX_L_SOURCE_PMU)) ? + pmu_offs : grf_offs; + } + + /* Preset drv offset value, set new start value */ + if (drv->offset >= 0) + { + if (iomux->type & IOMUX_SOURCE_PMU) + { + drv_pmu_offs = drv->offset; + } + else + { + drv_grf_offs = drv->offset; + } + } + else + { + /* Set current drv offset */ + drv->offset = (iomux->type & IOMUX_SOURCE_PMU) ? drv_pmu_offs : drv_grf_offs; + } + + /* + * Increase offset according to iomux width. + * 4bit iomux'es are spread over two registers. + */ + inc = (iomux->type & (IOMUX_WIDTH_4BIT | IOMUX_WIDTH_3BIT | IOMUX_WIDTH_2BIT)) ? 8 : 4; + + /* Preset drv offset value, set new start value */ + if ((iomux->type & IOMUX_SOURCE_PMU) || (iomux->type & IOMUX_L_SOURCE_PMU)) + { + pmu_offs += inc; + } + else + { + grf_offs += inc; + } + + /* + * Increase offset according to drv width. + * 3bit drive-strenth'es are spread over two registers. + */ + inc = ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) || (drv->drv_type == DRV_TYPE_IO_3V3_ONLY)) ? 8 : 4; + + if (iomux->type & IOMUX_SOURCE_PMU) + { + drv_pmu_offs += inc; + } + else + { + drv_grf_offs += inc; + } + + bank_pins += 8; + } + + /* calculate the per-bank recalced_mask */ + for (int pin = 0, j = 0; j < pinctrl->niomux_recalced; ++j) + { + if (pinctrl->iomux_recalced[j].num == pin_bank->bank_num) + { + pin = pinctrl->iomux_recalced[j].pin; + pin_bank->recalced_mask |= RT_BIT(pin); + } + } + + /* calculate the per-bank route_mask */ + for (int pin = 0, j = 0; j < pinctrl->niomux_routes; ++j) + { + if (pinctrl->iomux_routes[j].bank_num == pin_bank->bank_num) + { + pin = pinctrl->iomux_routes[j].pin; + pin_bank->route_mask |= RT_BIT(pin); + } + } + + pin_bank->drvdata = drvdata; + rt_spin_lock_init(&pin_bank->spinlock); + + pinctrl->pins_nr += pin_bank->nr_pins; + } + + rt_ofw_data(np) = &pinctrl_dev->parent; + + return RT_EOK; + +_fail: + rt_free(pinctrl_dev); + + return err; +} + +static const struct rt_ofw_node_id rockchip_pinctrl_ofw_ids[] = +{ + { .compatible = "rockchip,rk3308-pinctrl", .data = &rk3308_pin_ctrl }, + { .compatible = "rockchip,rk3568-pinctrl", .data = &rk3568_pin_ctrl }, + { .compatible = "rockchip,rk3576-pinctrl", .data = &rk3576_pin_ctrl }, + { .compatible = "rockchip,rk3588-pinctrl", .data = &rk3588_pin_ctrl }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_pinctrl_driver = +{ + .name = "pinctrl-rockchip", + .ids = rockchip_pinctrl_ofw_ids, + + .probe = rockchip_pinctrl_probe, +}; + +static int rockchip_pinctrl_register(void) +{ + rt_platform_driver_register(&rockchip_pinctrl_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(rockchip_pinctrl_register); diff --git a/bsp/rockchip/dm/pmdomain/Kconfig b/bsp/rockchip/dm/pmdomain/Kconfig new file mode 100755 index 00000000000..e0eee112b48 --- /dev/null +++ b/bsp/rockchip/dm/pmdomain/Kconfig @@ -0,0 +1,6 @@ +config RT_PMDOMAIN_ROCKCHIP + bool "Rockchip" + depends on RT_MFD_SYSCON + depends on RT_USING_CLK + depends on RT_USING_REGULATOR + default y diff --git a/bsp/rockchip/dm/pmdomain/SConscript b/bsp/rockchip/dm/pmdomain/SConscript new file mode 100755 index 00000000000..477df78e1b6 --- /dev/null +++ b/bsp/rockchip/dm/pmdomain/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_PMDOMAIN_ROCKCHIP']): + src += ['pm-domain-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/pmdomain/pm-domain-rockchip.c b/bsp/rockchip/dm/pmdomain/pm-domain-rockchip.c new file mode 100755 index 00000000000..7567980bad9 --- /dev/null +++ b/bsp/rockchip/dm/pmdomain/pm-domain-rockchip.c @@ -0,0 +1,1878 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-21 GuEe-GUI first version + */ + +#include +#include +#include + +#include + +#define DBG_TAG "pm-domain.rockchip" +#define DBG_LVL DBG_INFO +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct rockchip_domain_info +{ + const char *name; + int pwr_mask; + int status_mask; + int req_mask; + int idle_mask; + int ack_mask; + rt_bool_t active_wakeup; + int pwr_w_mask; + int req_w_mask; + int mem_status_mask; + int repair_status_mask; + int clk_ungate_mask; + int clk_ungate_w_mask; + int mem_num; + rt_bool_t keepon_startup; + rt_bool_t always_on; + rt_uint32_t pwr_offset; + rt_uint32_t mem_offset; + rt_uint32_t req_offset; + rt_uint32_t clk_ungate_offset; + rt_uint32_t delay_us; +}; + +enum soc_type +{ + SOC_TYPE_ALL = 0, + SOC_TYPE_PX30, +}; + +struct rockchip_pmu_info +{ + enum soc_type type; + + rt_uint32_t pwr_offset; + rt_uint32_t status_offset; + rt_uint32_t req_offset; + rt_uint32_t idle_offset; + rt_uint32_t ack_offset; + rt_uint32_t mem_pwr_offset; + rt_uint32_t chain_status_offset; + rt_uint32_t mem_status_offset; + rt_uint32_t repair_status_offset; + rt_uint32_t clk_ungate_offset; + rt_uint32_t mem_sd_offset; + + rt_uint32_t core_pwrcnt_offset; + rt_uint32_t gpu_pwrcnt_offset; + + unsigned int core_power_transition_time; + unsigned int gpu_power_transition_time; + + int num_domains; + const struct rockchip_domain_info *domain_info; +}; + +#define DOMAIN(NAME, PWR, STATUS, REQ, IDLE, ACK, WAKEUP, KEEPON) \ +{ \ + .name = NAME, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ +} + +#define DOMAIN_M(NAME, PWR, STATUS, REQ, IDLE, ACK, WAKEUP, KEEPON) \ +{ \ + .name = NAME, \ + .pwr_w_mask = (PWR) << 16, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .req_w_mask = (REQ) << 16, \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ +} + +#define DOMAIN_M_A(PWR, STATUS, REQ, IDLE, ACK, ALWAYS, WAKEUP, KEEPON) \ +{ \ + .pwr_w_mask = (PWR) << 16, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .req_w_mask = (REQ) << 16, \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .always_on = ALWAYS, \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ +} + +#define DOMAIN_M_C_SD(NAME, PWR, STATUS, REQ, IDLE, ACK, CLK, MEM, WAKEUP, KEEPON) \ +{ \ + .name = NAME, \ + .pwr_w_mask = (PWR) << 16, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .req_w_mask = (REQ) << 16, \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .clk_ungate_mask = (CLK), \ + .clk_ungate_w_mask = (CLK) << 16, \ + .mem_num = (MEM), \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ +} + +#define DOMAIN_M_O(NAME, PWR, STATUS, P_OFFSET, REQ, IDLE, ACK, R_OFFSET, WAKEUP, KEEPON) \ +{ \ + .name = NAME, \ + .pwr_w_mask = (PWR) << 16, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .req_w_mask = (REQ) << 16, \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ + .pwr_offset = P_OFFSET, \ + .req_offset = R_OFFSET, \ +} + +#define DOMAIN_M_O_R(NAME, P_OFF, PWR, STATUS, M_OFF, M_STATUS, R_STATUS, R_OFF, REQ, IDLE, ACK, WAKEUP, KEEPON) \ +{ \ + .name = NAME, \ + .pwr_offset = P_OFF, \ + .pwr_w_mask = (PWR) << 16, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .mem_offset = M_OFF, \ + .mem_status_mask = (M_STATUS), \ + .repair_status_mask = (R_STATUS), \ + .req_offset = R_OFF, \ + .req_w_mask = (REQ) << 16, \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ +} + +#define DOMAIN_M_O_R_G(NAME, P_OFF, PWR, STATUS, R_STATUS, R_OFFSET, REQ, IDLE, ACK, G_MASK, DELAY, WAKEUP, KEEPON) \ +{ \ + .name = NAME, \ + .pwr_offset = P_OFF, \ + .pwr_w_mask = (PWR) << 16, \ + .pwr_mask = (PWR), \ + .status_mask = (STATUS), \ + .mem_status_mask = (R_STATUS), \ + .repair_status_mask = (R_STATUS), \ + .req_offset = R_OFFSET, \ + .req_w_mask = (REQ) << 16, \ + .req_mask = (REQ), \ + .idle_mask = (IDLE), \ + .ack_mask = (ACK), \ + .clk_ungate_offset = R_OFFSET, \ + .clk_ungate_mask = (G_MASK), \ + .clk_ungate_w_mask = (G_MASK) << 16,\ + .delay_us = DELAY, \ + .active_wakeup = WAKEUP, \ + .keepon_startup = KEEPON, \ +} + +#define MAX_QOS_REGS_NUM 5 +#define QOS_PRIORITY 0x08 +#define QOS_MODE 0x0c +#define QOS_BANDWIDTH 0x10 +#define QOS_SATURATION 0x14 +#define QOS_EXTCONTROL 0x18 +#define SHAPING_NBPKTMAX0 0x0 + +struct rockchip_pmu; + +struct rockchip_pm_domain +{ + struct rt_dm_power_domain parent; + + const struct rockchip_domain_info *info; + struct rockchip_pmu *pmu; + struct rt_ofw_node *np; + + int num_qos; + int num_shaping; + struct rt_syscon **qos_regmaps; + struct rt_syscon **shaping_regmaps; + + rt_uint32_t *qos_save_regs[MAX_QOS_REGS_NUM]; + rt_uint32_t *shaping_save_regs; + + rt_bool_t *qos_is_need_init[MAX_QOS_REGS_NUM]; + rt_bool_t *shaping_is_need_init; + + struct rt_clk_array *clk_arr; + + rt_bool_t is_ignore_pwr; + rt_bool_t is_qos_saved; + rt_bool_t is_qos_need_init; + rt_bool_t is_shaping_need_init; + struct rt_regulator *supply; +}; + +#define raw_to_rockchip_pm_domain(raw) rt_container_of(raw, struct rockchip_pm_domain, parent) + +struct rockchip_pmu +{ + struct rt_dm_power_domain_proxy parent; + struct rt_device *dev; + + struct rt_syscon *regmap; + const struct rockchip_pmu_info *info; + + struct rockchip_pm_domain rk_pmdomains[]; +}; + +#define raw_to_rockchip_pmu(raw) rt_container_of(raw, struct rockchip_pmu, parent) + +#define read_uxx_poll_timeout(OP, PD, VAL, COND, DELAY_US, TIMEOUT_US) \ +({ \ + rt_uint64_t timeout_us = TIMEOUT_US; \ + rt_int64_t left_ns = timeout_us * 1000L; \ + rt_ubase_t delay_us = DELAY_US; \ + rt_uint64_t delay_ns = delay_us * 1000L; \ + for (;;) \ + { \ + (VAL) = OP(PD); \ + if (COND) \ + { \ + break; \ + } \ + if (timeout_us && left_ns < 0) \ + { \ + (VAL) = OP(PD); \ + break; \ + } \ + if (delay_us) \ + { \ + rt_hw_us_delay(delay_us); \ + if (timeout_us) \ + { \ + left_ns -= delay_ns; \ + } \ + } \ + rt_hw_cpu_relax(); \ + if (timeout_us) \ + { \ + --left_ns; \ + } \ + } \ + (COND) ? RT_EOK : -RT_ETIMEOUT; \ +}) + +static rt_bool_t rockchip_pmu_domain_is_idle(struct rockchip_pm_domain *rk_domain) +{ + rt_uint32_t val; + struct rockchip_pmu *pmu = rk_domain->pmu; + const struct rockchip_domain_info *domain_info = rk_domain->info; + + rt_syscon_read(pmu->regmap, pmu->info->idle_offset, &val); + + return (val & domain_info->idle_mask) == domain_info->idle_mask; +} + +static rt_uint32_t rockchip_pmu_read_ack(struct rockchip_pmu *pmu) +{ + rt_uint32_t val; + + rt_syscon_read(pmu->regmap, pmu->info->ack_offset, &val); + + return val; +} + +static rt_err_t rockchip_pmu_ungate_clk(struct rockchip_pm_domain *rk_domain, + rt_bool_t ungate) +{ + rt_uint32_t val; + struct rockchip_pmu *pmu = rk_domain->pmu; + const struct rockchip_domain_info *domain_info = rk_domain->info; + + if (!domain_info->clk_ungate_mask) + { + return RT_EOK; + } + + if (!pmu->info->clk_ungate_offset) + { + return RT_EOK; + } + + val = domain_info->clk_ungate_w_mask; + + if (ungate) + { + val |= domain_info->clk_ungate_mask; + } + + rt_syscon_write(pmu->regmap, pmu->info->clk_ungate_offset + domain_info->clk_ungate_offset, val); + + return RT_EOK; +} + +static rt_err_t rockchip_pmu_mem_shut_down(struct rockchip_pm_domain *rk_domain, + rt_bool_t sd) +{ + struct rockchip_pmu *pmu = rk_domain->pmu; + const struct rockchip_domain_info *domain_info = rk_domain->info; + + if (!domain_info->mem_num) + { + return RT_EOK; + } + + if (!pmu->info->mem_sd_offset) + { + return RT_EOK; + } + + for (int i = 0; i < domain_info->mem_num; ++i) + { + rt_syscon_write(pmu->regmap, pmu->info->mem_sd_offset, + ((!!sd) << i) | (1 << (i + 16))); + } + + return RT_EOK; +} + +static rt_err_t rockchip_pmu_set_idle_request(struct rockchip_pm_domain *rk_domain, + rt_bool_t idle) +{ + rt_err_t err; + rt_bool_t is_idle; + rt_uint32_t val, target_ack, domain_req_offset; + struct rockchip_pmu *pmu = rk_domain->pmu; + const struct rockchip_domain_info *domain_info = rk_domain->info; + + domain_req_offset = domain_info->req_offset; + + if (domain_info->req_mask == 0) + { + return RT_EOK; + } + else if (domain_info->req_w_mask) + { + rt_syscon_write(pmu->regmap, pmu->info->req_offset + domain_req_offset, + idle ? (domain_info->req_mask | domain_info->req_w_mask) : + domain_info->req_w_mask); + } + else + { + rt_syscon_update_bits(pmu->regmap, pmu->info->req_offset + domain_req_offset, + domain_info->req_mask, idle ? RT_UINT32_MAX : 0); + } + + rt_hw_wmb(); + + /* Wait util idle_ack = 1 */ + target_ack = idle ? domain_info->ack_mask : 0; + err = read_uxx_poll_timeout(rockchip_pmu_read_ack, pmu, val, + (val & domain_info->ack_mask) == target_ack, 0, 10000); + + if (err) + { + LOG_E("Failed to get ack on domain '%s' = %d", + rt_ofw_node_full_name(rk_domain->np), val); + return err; + } + + err = read_uxx_poll_timeout(rockchip_pmu_domain_is_idle, rk_domain, + is_idle, is_idle == idle, 0, 10000); + if (err) + { + LOG_E("Failed to set idle on domain '%s' = %d", + rt_ofw_node_full_name(rk_domain->np), is_idle); + return err; + } + + return RT_EOK; +} + +static rt_err_t rockchip_pmu_save_shaping(struct rockchip_pm_domain *rk_domain) +{ + for (int i = 0; i < rk_domain->num_shaping; ++i) + { + rt_syscon_read(rk_domain->shaping_regmaps[i], SHAPING_NBPKTMAX0, + &rk_domain->shaping_save_regs[i]); + } + + return RT_EOK; +} + +static rt_err_t rockchip_pmu_restore_shaping(struct rockchip_pm_domain *rk_domain) +{ + for (int i = 0; i < rk_domain->num_shaping; ++i) + { + rt_syscon_write(rk_domain->shaping_regmaps[i], SHAPING_NBPKTMAX0, + rk_domain->shaping_save_regs[i]); + } + + return RT_EOK; +} + +static rt_err_t rockchip_pmu_save_qos(struct rockchip_pm_domain *rk_domain) +{ + for (int i = 0; i < rk_domain->num_qos; ++i) + { + rt_syscon_read(rk_domain->qos_regmaps[i], QOS_PRIORITY, + &rk_domain->qos_save_regs[0][i]); + rt_syscon_read(rk_domain->qos_regmaps[i], QOS_MODE, + &rk_domain->qos_save_regs[1][i]); + rt_syscon_read(rk_domain->qos_regmaps[i], QOS_BANDWIDTH, + &rk_domain->qos_save_regs[2][i]); + rt_syscon_read(rk_domain->qos_regmaps[i], QOS_SATURATION, + &rk_domain->qos_save_regs[3][i]); + rt_syscon_read(rk_domain->qos_regmaps[i], QOS_EXTCONTROL, + &rk_domain->qos_save_regs[4][i]); + } + + return rockchip_pmu_save_shaping(rk_domain); +} + +static rt_err_t rockchip_pmu_restore_qos(struct rockchip_pm_domain *rk_domain) +{ + for (int i = 0; i < rk_domain->num_qos; ++i) + { + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_PRIORITY, + rk_domain->qos_save_regs[0][i]); + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_MODE, + rk_domain->qos_save_regs[1][i]); + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_BANDWIDTH, + rk_domain->qos_save_regs[2][i]); + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_SATURATION, + rk_domain->qos_save_regs[3][i]); + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_EXTCONTROL, + rk_domain->qos_save_regs[4][i]); + } + + return rockchip_pmu_restore_shaping(rk_domain); +} + +static void rockchip_pmu_init_shaping(struct rockchip_pm_domain *rk_domain) +{ + if (!rk_domain->is_shaping_need_init) + { + return; + } + + for (int i = 0; i < rk_domain->num_shaping; ++i) + { + if (rk_domain->shaping_is_need_init[i]) + { + rt_syscon_write(rk_domain->shaping_regmaps[i], SHAPING_NBPKTMAX0, + rk_domain->shaping_save_regs[i]); + } + } + + rt_free(rk_domain->shaping_is_need_init); + rk_domain->shaping_is_need_init = RT_NULL; + rk_domain->is_shaping_need_init = RT_FALSE; +} + +static void rockchip_pmu_init_qos(struct rockchip_pm_domain *rk_domain) +{ + rockchip_pmu_init_shaping(rk_domain); + + if (!rk_domain->is_qos_need_init) + { + return; + } + + for (int i = 0; i < rk_domain->num_qos; ++i) + { + if (rk_domain->qos_is_need_init[0][i]) + { + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_PRIORITY, + rk_domain->qos_save_regs[0][i]); + } + + if (rk_domain->qos_is_need_init[1][i]) + { + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_MODE, + rk_domain->qos_save_regs[1][i]); + } + + if (rk_domain->qos_is_need_init[2][i]) + { + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_BANDWIDTH, + rk_domain->qos_save_regs[2][i]); + } + + if (rk_domain->qos_is_need_init[3][i]) + { + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_SATURATION, + rk_domain->qos_save_regs[3][i]); + } + + if (rk_domain->qos_is_need_init[4][i]) + { + rt_syscon_write(rk_domain->qos_regmaps[i], QOS_EXTCONTROL, + rk_domain->qos_save_regs[4][i]); + } + } + + rt_free(rk_domain->qos_is_need_init[0]); + rk_domain->qos_is_need_init[0] = RT_NULL; + rk_domain->is_qos_need_init = RT_FALSE; +} + +static rt_bool_t rockchip_pmu_domain_is_on(struct rockchip_pm_domain *rk_domain) +{ + rt_uint32_t val; + struct rockchip_pmu *pmu = rk_domain->pmu; + + if (rk_domain->info->repair_status_mask) + { + rt_syscon_read(pmu->regmap, pmu->info->repair_status_offset, &val); + + /* 1'b1: power on, 1'b0: power off */ + return !!(val & rk_domain->info->repair_status_mask); + } + + /* check idle status for idle-only domains */ + if (rk_domain->info->status_mask == 0) + { + return !rockchip_pmu_domain_is_idle(rk_domain); + } + + rt_syscon_read(pmu->regmap, pmu->info->status_offset, &val); + + /* 1'b0: power on, 1'b1: power off */ + return !(val & rk_domain->info->status_mask); +} + +static bool rockchip_pmu_domain_is_mem_on(struct rockchip_pm_domain *rk_domain) +{ + rt_uint32_t val; + struct rockchip_pmu *pmu = rk_domain->pmu; + + rt_syscon_read(pmu->regmap, pmu->info->mem_status_offset + rk_domain->info->mem_offset, &val); + + /* 1'b0: power on, 1'b1: power off */ + return !(val & rk_domain->info->mem_status_mask); +} + +static rt_bool_t rockchip_pmu_domain_is_chain_on(struct rockchip_pm_domain *rk_domain) +{ + rt_uint32_t val; + struct rockchip_pmu *pmu = rk_domain->pmu; + + rt_syscon_read(pmu->regmap, pmu->info->chain_status_offset + rk_domain->info->mem_offset, &val); + + /* 1'b1: power on, 1'b0: power off */ + return val & rk_domain->info->mem_status_mask; +} + +static rt_err_t rockchip_pmu_domain_mem_reset(struct rockchip_pm_domain *rk_domain) +{ + rt_bool_t is_on; + rt_err_t err = 0; + struct rockchip_pmu *pmu = rk_domain->pmu; + + err = read_uxx_poll_timeout(rockchip_pmu_domain_is_chain_on, rk_domain, + is_on, is_on == RT_TRUE, 0, 10000); + + if (err) + { + LOG_E("Failed to get chain status '%s', target_on = %s, is %s", + rt_ofw_node_full_name(rk_domain->np), "1", is_on ? "on" : "off"); + goto _err; + } + + rt_hw_us_delay(60); + + rt_syscon_write(pmu->regmap, pmu->info->mem_pwr_offset + rk_domain->info->pwr_offset, + (rk_domain->info->pwr_mask | rk_domain->info->pwr_w_mask)); + rt_hw_wmb(); + + err = read_uxx_poll_timeout(rockchip_pmu_domain_is_mem_on, rk_domain, + is_on, is_on == RT_FALSE, 0, 10000); + + if (err) + { + LOG_E("Failed to get mem status '%s', target_on = %s, is %s", + rt_ofw_node_full_name(rk_domain->np), "0", is_on ? "on" : "off"); + goto _err; + } + + rt_syscon_write(pmu->regmap, pmu->info->mem_pwr_offset + rk_domain->info->pwr_offset, + rk_domain->info->pwr_w_mask); + rt_hw_wmb(); + + err = read_uxx_poll_timeout(rockchip_pmu_domain_is_mem_on, rk_domain, + is_on, is_on == RT_TRUE, 0, 10000); + + if (err) + { + LOG_E("Failed to get mem status '%s', target_on = %s, is %s", + rt_ofw_node_full_name(rk_domain->np), "1", is_on ? "on" : "off"); + } + +_err: + return err; +} + +static rt_err_t rockchip_do_pmu_set_power_domain(struct rockchip_pm_domain *rk_domain, + rt_bool_t on) +{ + rt_err_t err; + rt_uint32_t pd_pwr_offset; + rt_bool_t is_on, is_mem_on = RT_FALSE; + struct rockchip_pmu *pmu = rk_domain->pmu; + + pd_pwr_offset = rk_domain->info->pwr_offset; + + if (rk_domain->info->pwr_mask == 0) + { + return RT_EOK; + } + + if (on && rk_domain->info->mem_status_mask) + { + is_mem_on = rockchip_pmu_domain_is_mem_on(rk_domain); + } + + if (rk_domain->info->pwr_w_mask) + { + rt_syscon_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, + on ? rk_domain->info->pwr_w_mask : + (rk_domain->info->pwr_mask | rk_domain->info->pwr_w_mask)); + } + else + { + rt_syscon_update_bits(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, + rk_domain->info->pwr_mask, on ? 0 : RT_UINT32_MAX); + } + + rt_hw_wmb(); + + if (is_mem_on && (err = rockchip_pmu_domain_mem_reset(rk_domain))) + { + return err; + } + + if (read_uxx_poll_timeout(rockchip_pmu_domain_is_on, rk_domain, + is_on, is_on == on, 0, 10000)) + { + LOG_E("Failed to set domain '%s', is %s", + rt_ofw_node_full_name(rk_domain->np), is_on ? "on" : "off"); + return -RT_ETIMEOUT; + } + + return RT_EOK; +} + +static rt_err_t rockchip_pm_domain_power(struct rockchip_pm_domain *rk_pmdomain, + rt_bool_t power_on) +{ + rt_err_t err = RT_EOK; + const struct rockchip_pmu_info *pmu_info = rk_pmdomain->pmu->info; + const struct rockchip_domain_info *domain_info = rk_pmdomain->info; + + if (!power_on && pmu_info->type == SOC_TYPE_PX30 && + rt_ofw_machine_is_compatible("rockchip,px30s")) + { + if (domain_info->name && !rt_strcmp(domain_info->name, "gpu")) + { + return RT_EOK; + } + } + + if (rockchip_pmu_domain_is_on(rk_pmdomain) != power_on) + { + if (!rk_pmdomain->supply) + { + rk_pmdomain->supply = rt_regulator_get(rk_pmdomain->pmu->dev, + domain_info->name); + + if (!rk_pmdomain->supply) + { + rk_pmdomain->supply = rt_err_ptr(-RT_ENOSYS); + } + } + + if (power_on && !rt_is_err(rk_pmdomain->supply)) + { + if ((err = rt_regulator_enable(rk_pmdomain->supply))) + { + return err; + } + } + + if (rk_pmdomain->clk_arr) + { + if ((err = rt_clk_array_enable(rk_pmdomain->clk_arr))) + { + LOG_E("Enable clocks error = %s", rt_strerror(err)); + return err; + } + } + rockchip_pmu_ungate_clk(rk_pmdomain, RT_TRUE); + + if (!power_on) + { + rockchip_pmu_save_qos(rk_pmdomain); + rk_pmdomain->is_qos_saved = RT_TRUE; + + /* if powering down, idle request to NIU first */ + if ((err = rockchip_pmu_set_idle_request(rk_pmdomain, RT_TRUE))) + { + goto _out; + } + + rockchip_pmu_mem_shut_down(rk_pmdomain, RT_TRUE); + } + + if ((err = rockchip_do_pmu_set_power_domain(rk_pmdomain, power_on))) + { + goto _out; + } + + if (power_on) + { + rockchip_pmu_mem_shut_down(rk_pmdomain, RT_FALSE); + + /* if powering up, leave idle mode */ + if ((err = rockchip_pmu_set_idle_request(rk_pmdomain, RT_FALSE))) + { + goto _out; + } + + if (domain_info->delay_us) + { + rt_hw_us_delay(domain_info->delay_us); + } + if (rk_pmdomain->is_qos_saved) + { + rockchip_pmu_restore_qos(rk_pmdomain); + } + if (rk_pmdomain->is_qos_need_init || rk_pmdomain->is_shaping_need_init) + { + rockchip_pmu_init_qos(rk_pmdomain); + } + } + + _out: + rockchip_pmu_ungate_clk(rk_pmdomain, RT_FALSE); + + if (rk_pmdomain->clk_arr) + { + rt_clk_array_disable(rk_pmdomain->clk_arr); + } + + if (!power_on && !rt_is_err(rk_pmdomain->supply)) + { + err = rt_regulator_disable(rk_pmdomain->supply); + } + } + + return err; +} + +static rt_err_t rockchip_pd_power_on(struct rt_dm_power_domain *domain) +{ + struct rockchip_pm_domain *rk_pmdomain = raw_to_rockchip_pm_domain(domain); + + if (rk_pmdomain->is_ignore_pwr) + { + return RT_EOK; + } + + return rockchip_pm_domain_power(rk_pmdomain, RT_TRUE); +} + +static rt_err_t rockchip_pd_power_off(struct rt_dm_power_domain *domain) +{ + struct rockchip_pm_domain *rk_pmdomain = raw_to_rockchip_pm_domain(domain); + + if (rk_pmdomain->is_ignore_pwr) + { + return RT_EOK; + } + + return rockchip_pm_domain_power(rk_pmdomain, RT_FALSE); +} + +static rt_err_t rockchip_pm_get_shaping(struct rockchip_pm_domain *rk_domain, + struct rt_ofw_node *np) +{ + struct rt_ofw_node *snp; + + rk_domain->num_shaping = rt_ofw_count_phandle_cells(np, "pm_shaping", RT_NULL); + + if (rk_domain->num_shaping > 0) + { + rk_domain->shaping_regmaps = rt_calloc(rk_domain->num_shaping, + sizeof(*rk_domain->shaping_regmaps)); + + if (!rk_domain->shaping_regmaps) + { + return -RT_ENOMEM; + } + + rk_domain->shaping_save_regs = rt_malloc(sizeof(rt_uint32_t) * + rk_domain->num_shaping); + + if (!rk_domain->shaping_save_regs) + { + return -RT_ENOMEM; + } + + rk_domain->shaping_is_need_init = rt_calloc(rk_domain->num_shaping, + sizeof(rt_bool_t)); + + for (int i = 0; i < rk_domain->num_shaping; ++i) + { + rt_uint32_t val; + + snp = rt_ofw_parse_phandle(np, "pm_shaping", i); + + if (!snp) + { + return -RT_EINVAL; + } + + rk_domain->shaping_regmaps[i] = rt_syscon_find_by_ofw_node(snp); + rt_ofw_node_put(snp); + + if (!rk_domain->shaping_regmaps[i]) + { + return -RT_EINVAL; + } + + if (!rt_ofw_prop_read_u32(snp, "shaping-init", &val)) + { + rk_domain->shaping_save_regs[i] = val; + rk_domain->shaping_is_need_init[i] = RT_TRUE; + rk_domain->is_shaping_need_init = RT_TRUE; + } + } + } + + return RT_EOK; +} + +static void rockchip_pm_qos_init(struct rockchip_pm_domain *rk_domain) +{ + rt_err_t err; + + if (!rk_domain->is_qos_need_init) + { + rt_free(rk_domain->qos_is_need_init[0]); + rk_domain->qos_is_need_init[0] = RT_NULL; + } + + if (!rk_domain->is_shaping_need_init) + { + rt_free(rk_domain->shaping_is_need_init); + rk_domain->shaping_is_need_init = RT_NULL; + } + + if (!rk_domain->is_qos_need_init && !rk_domain->is_shaping_need_init) + { + return; + } + + if (rockchip_pmu_domain_is_on(rk_domain)) + { + if (rk_domain->clk_arr) + { + if ((err = rt_clk_array_enable(rk_domain->clk_arr))) + { + LOG_E("Enable clocks error = %s", rt_strerror(err)); + return; + } + } + + rockchip_pmu_init_qos(rk_domain); + rt_clk_array_disable(rk_domain->clk_arr); + } +} + +static void rockchip_pm_remove_one_domain(struct rockchip_pm_domain *rk_domain) +{ + if (rk_domain->pmu) + { + rt_dm_power_domain_unregister(&rk_domain->parent); + rk_domain->pmu = RT_NULL; + } + + if (rk_domain->qos_save_regs[0]) + { + rt_free(rk_domain->qos_save_regs[0]); + } + + if (rk_domain->qos_is_need_init[0]) + { + rt_free(rk_domain->qos_is_need_init[0]); + } + + if (rk_domain->qos_regmaps) + { + rt_free(rk_domain->qos_regmaps); + rk_domain->qos_regmaps = RT_NULL; + } + + if (rk_domain->clk_arr) + { + rt_clk_array_unprepare(rk_domain->clk_arr); + rt_clk_array_put(rk_domain->clk_arr); + + rk_domain->clk_arr = RT_NULL; + } +} + +static rt_err_t rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, + struct rt_ofw_node *np) +{ + rt_err_t err; + rt_uint32_t idx; + struct rt_dm_power_domain *domain; + struct rockchip_pm_domain *rk_domain; + const struct rockchip_domain_info *domain_info; + + if ((err = rt_ofw_prop_read_u32(np, "reg", &idx))) + { + LOG_E("Failed to read %s domain id (reg) error = %s", + rt_ofw_node_full_name(np), rt_strerror(err)); + return err; + } + + rk_domain = &pmu->rk_pmdomains[idx]; + domain_info = &pmu->info->domain_info[idx]; + + if (domain_info->pwr_mask) + { + rk_domain->is_ignore_pwr = RT_TRUE; + } + + /* RK3588 has domains with two parents (RKVDEC0/RKVDEC1) */ + if (rk_domain->pmu) + { + return RT_EOK; + } + + rk_domain->num_qos = rt_ofw_count_phandle_cells(np, "pm_qos", RT_NULL); + + if (rk_domain->num_qos > 0) + { + rk_domain->qos_regmaps = rt_calloc(rk_domain->num_qos, + sizeof(*rk_domain->qos_regmaps)); + + if (!rk_domain->qos_regmaps) + { + return -RT_ENOMEM; + } + + rk_domain->qos_save_regs[0] = rt_malloc(rk_domain->num_qos * + MAX_QOS_REGS_NUM * sizeof(rt_uint32_t)); + + if (!rk_domain->qos_save_regs[0]) + { + return -RT_ENOMEM; + } + + rk_domain->qos_is_need_init[0] = rt_malloc(rk_domain->num_qos * + MAX_QOS_REGS_NUM * sizeof(rt_bool_t)); + + if (!rk_domain->qos_is_need_init[0]) + { + return -RT_ENOMEM; + } + + for (int i = 1; i < MAX_QOS_REGS_NUM; ++i) + { + rk_domain->qos_save_regs[i] = rk_domain->qos_save_regs[i - 1] + + rk_domain->num_qos; + rk_domain->qos_is_need_init[i] = rk_domain->qos_is_need_init[i - 1] + + rk_domain->num_qos; + } + + for (int i = 0; i < rk_domain->num_qos; ++i) + { + rt_uint32_t val; + struct rt_ofw_node *qos_np = rt_ofw_parse_phandle(np, "pm_qos", i); + + if (!qos_np) + { + err = -RT_EIO; + goto _free; + } + + if (!(rk_domain->qos_regmaps[i] = rt_syscon_find_by_ofw_node(qos_np))) + { + rt_ofw_node_put(qos_np); + err = -RT_EIO; + + goto _free; + } + + if (!rt_ofw_prop_read_u32(qos_np, "priority-init", &val)) + { + rk_domain->qos_save_regs[0][i] = val; + rk_domain->qos_is_need_init[0][i] = RT_TRUE; + rk_domain->is_qos_need_init = RT_TRUE; + } + + if (!rt_ofw_prop_read_u32(qos_np, "mode-init", &val)) + { + rk_domain->qos_save_regs[1][i] = val; + rk_domain->qos_is_need_init[1][i] = RT_TRUE; + rk_domain->is_qos_need_init = RT_TRUE; + } + + if (!rt_ofw_prop_read_u32(qos_np, "bandwidth-init", &val)) + { + rk_domain->qos_save_regs[2][i] = val; + rk_domain->qos_is_need_init[2][i] = RT_TRUE; + rk_domain->is_qos_need_init = RT_TRUE; + } + + if (!rt_ofw_prop_read_u32(qos_np, "saturation-init", &val)) + { + rk_domain->qos_save_regs[3][i] = val; + rk_domain->qos_is_need_init[3][i] = RT_TRUE; + rk_domain->is_qos_need_init = RT_TRUE; + } + + if (!rt_ofw_prop_read_u32(qos_np, "extcontrol-init", &val)) + { + rk_domain->qos_save_regs[4][i] = val; + rk_domain->qos_is_need_init[4][i] = RT_TRUE; + rk_domain->is_qos_need_init = RT_TRUE; + } + + rt_ofw_node_put(qos_np); + } + } + + if ((err = rockchip_pm_get_shaping(rk_domain, np))) + { + goto _free; + } + + rk_domain->clk_arr = rt_ofw_get_clk_array(np); + + if (rt_is_err(rk_domain->clk_arr)) + { + LOG_E("Failed to %s %s CLKs", "read", rt_ofw_node_full_name(np)); + err = rt_ptr_err(rk_domain->clk_arr); + + goto _free; + } + + if ((err = rt_clk_array_prepare(rk_domain->clk_arr))) + { + LOG_E("Failed to %s %s CLKs", "prepare", rt_ofw_node_full_name(np)); + goto _free; + } + + rk_domain->info = domain_info; + rk_domain->pmu = pmu; + rk_domain->np = np; + + if (domain_info->always_on || domain_info->keepon_startup) + { + if (!rockchip_pmu_domain_is_on(rk_domain)) + { + if ((err = rockchip_pm_domain_power(rk_domain, RT_TRUE))) + { + goto _free; + } + } + } + + rockchip_pm_qos_init(rk_domain); + + domain = &rk_domain->parent; + domain->power_off = rockchip_pd_power_off; + domain->power_on = rockchip_pd_power_on; + + if ((err = rt_dm_power_domain_register(domain))) + { + goto _free; + } + + rt_ofw_data(np) = &rk_domain->parent; + + return RT_EOK; + +_free: + rk_domain->info = RT_NULL; + rk_domain->pmu = RT_NULL; + rk_domain->np = RT_NULL; + + rockchip_pm_remove_one_domain(rk_domain); + + return err; +} + +static rt_err_t rockchip_pm_add_subdomain(struct rockchip_pmu *pmu, + struct rt_ofw_node *parent) +{ + rt_err_t err; + rt_uint32_t idx; + struct rt_ofw_node *np; + struct rockchip_pm_domain *child_rk_domain, *parent_rk_domain; + + rt_ofw_foreach_child_node(parent, np) + { + if ((err = rt_ofw_prop_read_u32(parent, "reg", &idx))) + { + LOG_E("Failed to read %s domain id (reg) error = %s", + rt_ofw_node_full_name(parent), rt_strerror(err)); + goto _err; + } + + parent_rk_domain = &pmu->rk_pmdomains[idx]; + + if ((err = rockchip_pm_add_one_domain(pmu, np))) + { + LOG_E("Failed to handle node %s error = %s", + rt_ofw_node_full_name(np), rt_strerror(err)); + goto _err; + } + + if ((err = rt_ofw_prop_read_u32(np, "reg", &idx))) + { + LOG_E("Failed to read %s domain id (reg) error = %s", + rt_ofw_node_full_name(np), rt_strerror(err)); + goto _err; + } + + child_rk_domain = &pmu->rk_pmdomains[idx]; + + if ((err = rt_dm_power_domain_register_child(&parent_rk_domain->parent, + &child_rk_domain->parent))) + { + LOG_E("Failed to handle subdomain node %s error = %s", + rt_ofw_node_full_name(np), rt_strerror(err)); + } + + rockchip_pm_add_subdomain(pmu, np); + } + + return RT_EOK; + +_err: + rt_ofw_node_put(np); + + return err; +} + +static void rockchip_pmdomain_conf_cnt(struct rockchip_pmu *pmu, + rt_uint32_t domain_reg_offset, int count) +{ + /* 1. configure domain power down transition count */ + rt_syscon_write(pmu->regmap, domain_reg_offset, count); + + /* 2. power up count. */ + rt_syscon_write(pmu->regmap, domain_reg_offset + 4, count); +} + +static struct rt_dm_power_domain *rockchip_pm_domain_proxy_ofw_parse( + struct rt_dm_power_domain_proxy *proxy, struct rt_ofw_cell_args *args) +{ + struct rockchip_pmu *pmu = raw_to_rockchip_pmu(proxy); + + return &pmu->rk_pmdomains[args->args[0]].parent; +} + +static rt_err_t rockchip_pmdomain_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rockchip_pmu *pmu; + struct rt_ofw_node *np, *grf_np, *child; + const struct rockchip_pmu_info *pmu_info = pdev->id->data; + + pmu = rt_calloc(1, sizeof(*pmu) + sizeof(pmu->rk_pmdomains[0]) * pmu_info->num_domains); + + if (!pmu) + { + return -RT_ENOMEM; + } + + np = pdev->parent.ofw_node; + grf_np = rt_ofw_get_parent(np); + + pmu->regmap = rt_syscon_find_by_ofw_node(grf_np); + + rt_ofw_node_put(grf_np); + + if (!pmu->regmap) + { + err = -RT_EIO; + + goto _fail; + } + + pmu->info = pmu_info; + pmu->dev = &pdev->parent; + + /* Configure power up and down transition delays for CORE and GPU domains. */ + if (pmu_info->core_power_transition_time) + { + rockchip_pmdomain_conf_cnt(pmu, pmu_info->core_pwrcnt_offset, + pmu_info->core_power_transition_time); + } + + if (pmu_info->gpu_pwrcnt_offset) + { + rockchip_pmdomain_conf_cnt(pmu, pmu_info->gpu_pwrcnt_offset, + pmu_info->gpu_power_transition_time); + } + + rt_ofw_foreach_available_child_node(np, child) + { + if ((err = rockchip_pm_add_one_domain(pmu, child))) + { + LOG_E("Failed to handle node %s error = %s", + rt_ofw_node_full_name(child), rt_strerror(err)); + + rt_ofw_node_put(child); + goto _free_domain; + } + + if ((err = rockchip_pm_add_subdomain(pmu, child))) + { + LOG_E("Failed to handle subdomain node %s error = %s", + rt_ofw_node_full_name(child), rt_strerror(err)); + + rt_ofw_node_put(child); + goto _free_domain; + } + } + + pmu->parent.ofw_parse = rockchip_pm_domain_proxy_ofw_parse; + rt_dm_power_domain_proxy_ofw_bind(&pmu->parent, np); + + return RT_EOK; + +_free_domain: + for (int i = 0; i < pmu_info->num_domains; ++i) + { + struct rockchip_pm_domain *rk_domain; + + rk_domain = raw_to_rockchip_pm_domain(&pmu->rk_pmdomains[i]); + + if (rk_domain->pmu) + { + rockchip_pm_remove_one_domain(rk_domain); + } + } + +_fail: + rt_free(pmu); + + return err; +} + +#define DOMAIN_PX30(name, pwr, status, req, wakeup) DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup, RT_FALSE) +#define DOMAIN_PX30_PROTECT(name, pwr, status, req, wakeup) DOMAIN_M(name, pwr, status, req, (req) << 16, req, wakeup, RT_TRUE) + +static const struct rockchip_domain_info px30_pm_domains[] = +{ + [PX30_PD_USB] = DOMAIN_PX30("usb", RT_BIT(5), RT_BIT(5), RT_BIT(10), RT_FALSE), + [PX30_PD_SDCARD] = DOMAIN_PX30("sdcard", RT_BIT(8), RT_BIT(8), RT_BIT(9), RT_FALSE), + [PX30_PD_GMAC] = DOMAIN_PX30("gmac", RT_BIT(10), RT_BIT(10), RT_BIT(6), RT_FALSE), + [PX30_PD_MMC_NAND] = DOMAIN_PX30("mmc_nand", RT_BIT(11), RT_BIT(11), RT_BIT(5), RT_FALSE), + [PX30_PD_VPU] = DOMAIN_PX30("vpu", RT_BIT(12), RT_BIT(12), RT_BIT(14), RT_FALSE), + [PX30_PD_VO] = DOMAIN_PX30_PROTECT("vo", RT_BIT(13), RT_BIT(13), RT_BIT(7), RT_FALSE), + [PX30_PD_VI] = DOMAIN_PX30_PROTECT("vi", RT_BIT(14), RT_BIT(14), RT_BIT(8), RT_FALSE), + [PX30_PD_GPU] = DOMAIN_PX30("gpu", RT_BIT(15), RT_BIT(15), RT_BIT(2), RT_FALSE), +}; + +static const struct rockchip_pmu_info px30_pmu = +{ + .type = SOC_TYPE_PX30, + .pwr_offset = 0x18, + .status_offset = 0x20, + .req_offset = 0x64, + .idle_offset = 0x6c, + .ack_offset = 0x6c, + + .num_domains = RT_ARRAY_SIZE(px30_pm_domains), + .domain_info = px30_pm_domains, +}; + +static const struct rockchip_domain_info rk1808_pm_domains[] = +{ + [RK1808_VD_NPU] = DOMAIN_PX30("npu", RT_BIT(15), RT_BIT(15), RT_BIT(2), RT_FALSE), + [RK1808_PD_PCIE] = DOMAIN_PX30("pcie", RT_BIT(9), RT_BIT(9), RT_BIT(4), RT_TRUE), + [RK1808_PD_VPU] = DOMAIN_PX30("vpu", RT_BIT(13), RT_BIT(13), RT_BIT(7), RT_FALSE), + [RK1808_PD_VIO] = DOMAIN_PX30_PROTECT("vio", RT_BIT(14), RT_BIT(14), RT_BIT(8), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk1808_pmu = +{ + .pwr_offset = 0x18, + .status_offset = 0x20, + .req_offset = 0x64, + .idle_offset = 0x6c, + .ack_offset = 0x6c, + + .num_domains = RT_ARRAY_SIZE(rk1808_pm_domains), + .domain_info = rk1808_pm_domains, +}; + +#define DOMAIN_RK3036(name, req, ack, idle, wakeup) DOMAIN_M(name, 0, 0, req, idle, ack, wakeup, RT_FALSE) + +static const struct rockchip_domain_info rk3036_pm_domains[] = +{ + [RK3036_PD_MSCH] = DOMAIN_RK3036("msch", RT_BIT(14), RT_BIT(23), RT_BIT(30), RT_TRUE), + [RK3036_PD_CORE] = DOMAIN_RK3036("core", RT_BIT(13), RT_BIT(17), RT_BIT(24), RT_FALSE), + [RK3036_PD_PERI] = DOMAIN_RK3036("peri", RT_BIT(12), RT_BIT(18), RT_BIT(25), RT_FALSE), + [RK3036_PD_VIO] = DOMAIN_RK3036("vio", RT_BIT(11), RT_BIT(19), RT_BIT(26), RT_FALSE), + [RK3036_PD_VPU] = DOMAIN_RK3036("vpu", RT_BIT(10), RT_BIT(20), RT_BIT(27), RT_FALSE), + [RK3036_PD_GPU] = DOMAIN_RK3036("gpu", RT_BIT(9), RT_BIT(21), RT_BIT(28), RT_FALSE), + [RK3036_PD_SYS] = DOMAIN_RK3036("sys", RT_BIT(8), RT_BIT(22), RT_BIT(29), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3036_pmu = +{ + .req_offset = 0x148, + .idle_offset = 0x14c, + .ack_offset = 0x14c, + + .num_domains = RT_ARRAY_SIZE(rk3036_pm_domains), + .domain_info = rk3036_pm_domains, +}; + +static const struct rockchip_domain_info rk3066_pm_domains[] = +{ + [RK3066_PD_GPU] = DOMAIN("gpu", RT_BIT(9), RT_BIT(9), RT_BIT(3), RT_BIT(24), RT_BIT(29), RT_FALSE, RT_FALSE), + [RK3066_PD_VIDEO] = DOMAIN("video", RT_BIT(8), RT_BIT(8), RT_BIT(4), RT_BIT(23), RT_BIT(28), RT_FALSE, RT_FALSE), + [RK3066_PD_VIO] = DOMAIN("vio", RT_BIT(7), RT_BIT(7), RT_BIT(5), RT_BIT(22), RT_BIT(27), RT_FALSE, RT_TRUE), + [RK3066_PD_PERI] = DOMAIN("peri", RT_BIT(6), RT_BIT(6), RT_BIT(2), RT_BIT(25), RT_BIT(30), RT_FALSE, RT_FALSE), + [RK3066_PD_CPU] = DOMAIN("cpu", 0, RT_BIT(5), RT_BIT(1), RT_BIT(26), RT_BIT(31), RT_FALSE, RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3066_pmu = +{ + .pwr_offset = 0x08, + .status_offset = 0x0c, + .req_offset = 0x38, /* PMU_MISC_CON1 */ + .idle_offset = 0x0c, + .ack_offset = 0x0c, + + .num_domains = RT_ARRAY_SIZE(rk3066_pm_domains), + .domain_info = rk3066_pm_domains, +}; + +#define DOMAIN_RK3288(name, pwr, status, req, wakeup) DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup, RT_FALSE) +#define DOMAIN_RK3288_PROTECT(name, pwr, status, req, wakeup) DOMAIN(name, pwr, status, req, req, (req) << 16, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3128_pm_domains[] = +{ + [RK3128_PD_CORE] = DOMAIN_RK3288("core", RT_BIT(0), RT_BIT(0), RT_BIT(4), RT_FALSE), + [RK3128_PD_MSCH] = DOMAIN_RK3288("msch", 0, 0, RT_BIT(6), RT_TRUE), + [RK3128_PD_VIO] = DOMAIN_RK3288_PROTECT("vio", RT_BIT(3), RT_BIT(3), RT_BIT(2), RT_FALSE), + [RK3128_PD_VIDEO] = DOMAIN_RK3288("video", RT_BIT(2), RT_BIT(2), RT_BIT(1), RT_FALSE), + [RK3128_PD_GPU] = DOMAIN_RK3288("gpu", RT_BIT(1), RT_BIT(1), RT_BIT(3), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3128_pmu = +{ + .pwr_offset = 0x04, + .status_offset = 0x08, + .req_offset = 0x0c, + .idle_offset = 0x10, + .ack_offset = 0x10, + + .num_domains = RT_ARRAY_SIZE(rk3128_pm_domains), + .domain_info = rk3128_pm_domains, +}; + +static const struct rockchip_domain_info rk3188_pm_domains[] = +{ + [RK3188_PD_GPU] = DOMAIN("gpu", RT_BIT(9), RT_BIT(9), RT_BIT(3), RT_BIT(24), RT_BIT(29), RT_FALSE, RT_FALSE), + [RK3188_PD_VIDEO] = DOMAIN("video", RT_BIT(8), RT_BIT(8), RT_BIT(4), RT_BIT(23), RT_BIT(28), RT_FALSE, RT_FALSE), + [RK3188_PD_VIO] = DOMAIN("vio", RT_BIT(7), RT_BIT(7), RT_BIT(5), RT_BIT(22), RT_BIT(27), RT_FALSE, RT_FALSE), + [RK3188_PD_PERI] = DOMAIN("peri", RT_BIT(6), RT_BIT(6), RT_BIT(2), RT_BIT(25), RT_BIT(30), RT_FALSE, RT_FALSE), + [RK3188_PD_CPU] = DOMAIN("cpu", RT_BIT(5), RT_BIT(5), RT_BIT(1), RT_BIT(26), RT_BIT(31), RT_FALSE, RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3188_pmu = +{ + .pwr_offset = 0x08, + .status_offset = 0x0c, + .req_offset = 0x38, /* PMU_MISC_CON1 */ + .idle_offset = 0x0c, + .ack_offset = 0x0c, + + .num_domains = RT_ARRAY_SIZE(rk3188_pm_domains), + .domain_info = rk3188_pm_domains, +}; + +static const struct rockchip_domain_info rk3228_pm_domains[] = +{ + [RK3228_PD_CORE] = DOMAIN_RK3036("core", RT_BIT(0), RT_BIT(0), RT_BIT(16), RT_TRUE), + [RK3228_PD_MSCH] = DOMAIN_RK3036("msch", RT_BIT(1), RT_BIT(1), RT_BIT(17), RT_TRUE), + [RK3228_PD_BUS] = DOMAIN_RK3036("bus", RT_BIT(2), RT_BIT(2), RT_BIT(18), RT_TRUE), + [RK3228_PD_SYS] = DOMAIN_RK3036("sys", RT_BIT(3), RT_BIT(3), RT_BIT(19), RT_TRUE), + [RK3228_PD_VIO] = DOMAIN_RK3036("vio", RT_BIT(4), RT_BIT(4), RT_BIT(20), RT_FALSE), + [RK3228_PD_VOP] = DOMAIN_RK3036("vop", RT_BIT(5), RT_BIT(5), RT_BIT(21), RT_FALSE), + [RK3228_PD_VPU] = DOMAIN_RK3036("vpu", RT_BIT(6), RT_BIT(6), RT_BIT(22), RT_FALSE), + [RK3228_PD_RKVDEC] = DOMAIN_RK3036("vdec", RT_BIT(7), RT_BIT(7), RT_BIT(23), RT_FALSE), + [RK3228_PD_GPU] = DOMAIN_RK3036("gpu", RT_BIT(8), RT_BIT(8), RT_BIT(24), RT_FALSE), + [RK3228_PD_PERI] = DOMAIN_RK3036("peri", RT_BIT(9), RT_BIT(9), RT_BIT(25), RT_TRUE), + [RK3228_PD_GMAC] = DOMAIN_RK3036("gmac", RT_BIT(10), RT_BIT(10), RT_BIT(26), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3228_pmu = +{ + .req_offset = 0x40c, + .idle_offset = 0x488, + .ack_offset = 0x488, + + .num_domains = RT_ARRAY_SIZE(rk3228_pm_domains), + .domain_info = rk3228_pm_domains, +}; + +static const struct rockchip_domain_info rk3288_pm_domains[] = +{ + [RK3288_PD_VIO] = DOMAIN_RK3288_PROTECT("vio", RT_BIT(7), RT_BIT(7), RT_BIT(4), RT_FALSE), + [RK3288_PD_HEVC] = DOMAIN_RK3288("hevc", RT_BIT(14), RT_BIT(10), RT_BIT(9), RT_FALSE), + [RK3288_PD_VIDEO] = DOMAIN_RK3288("video", RT_BIT(8), RT_BIT(8), RT_BIT(3), RT_FALSE), + [RK3288_PD_GPU] = DOMAIN_RK3288("gpu", RT_BIT(9), RT_BIT(9), RT_BIT(2), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3288_pmu = +{ + .pwr_offset = 0x08, + .status_offset = 0x0c, + .req_offset = 0x10, + .idle_offset = 0x14, + .ack_offset = 0x14, + + .core_pwrcnt_offset = 0x34, + .gpu_pwrcnt_offset = 0x3c, + + .core_power_transition_time = 24, /* 1us */ + .gpu_power_transition_time = 24, /* 1us */ + + .num_domains = RT_ARRAY_SIZE(rk3288_pm_domains), + .domain_info = rk3288_pm_domains, +}; + +#define DOMAIN_RK3328(name, pwr, status, req, wakeup) DOMAIN_M(name, pwr, pwr, req, (req) << 10, req, wakeup, RT_FALSE) + +static const struct rockchip_domain_info rk3328_pm_domains[] = +{ + [RK3328_PD_CORE] = DOMAIN_RK3328("core", 0, RT_BIT(0), RT_BIT(0), RT_FALSE), + [RK3328_PD_GPU] = DOMAIN_RK3328("gpu", 0, RT_BIT(1), RT_BIT(1), RT_FALSE), + [RK3328_PD_BUS] = DOMAIN_RK3328("bus", 0, RT_BIT(2), RT_BIT(2), RT_TRUE), + [RK3328_PD_MSCH] = DOMAIN_RK3328("msch", 0, RT_BIT(3), RT_BIT(3), RT_TRUE), + [RK3328_PD_PERI] = DOMAIN_RK3328("peri", 0, RT_BIT(4), RT_BIT(4), RT_TRUE), + [RK3328_PD_VIDEO] = DOMAIN_RK3328("video", 0, RT_BIT(5), RT_BIT(5), RT_FALSE), + [RK3328_PD_HEVC] = DOMAIN_RK3328("hevc", 0, RT_BIT(6), RT_BIT(6), RT_FALSE), + [RK3328_PD_VIO] = DOMAIN_RK3328("vio", 0, RT_BIT(8), RT_BIT(8), RT_FALSE), + [RK3328_PD_VPU] = DOMAIN_RK3328("vpu", 0, RT_BIT(9), RT_BIT(9), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3328_pmu = +{ + .req_offset = 0x414, + .idle_offset = 0x484, + .ack_offset = 0x484, + + .num_domains = RT_ARRAY_SIZE(rk3328_pm_domains), + .domain_info = rk3328_pm_domains, +}; + +#define DOMAIN_RK3368(name, pwr, status, req, wakeup) DOMAIN(name, pwr, status, req, (req) << 16, req, wakeup, RT_FALSE) +#define DOMAIN_RK3368_PROTECT(name, pwr, status, req, wakeup) DOMAIN(name, pwr, status, req, (req) << 16, req, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3366_pm_domains[] = +{ + [RK3366_PD_PERI] = DOMAIN_RK3368("peri", RT_BIT(10), RT_BIT(10), RT_BIT(6), RT_TRUE), + [RK3366_PD_VIO] = DOMAIN_RK3368_PROTECT("vio", RT_BIT(14), RT_BIT(14), RT_BIT(8), RT_FALSE), + [RK3366_PD_VIDEO] = DOMAIN_RK3368("video", RT_BIT(13), RT_BIT(13), RT_BIT(7), RT_FALSE), + [RK3366_PD_RKVDEC] = DOMAIN_RK3368("vdec", RT_BIT(11), RT_BIT(11), RT_BIT(7), RT_FALSE), + [RK3366_PD_WIFIBT] = DOMAIN_RK3368("wifibt", RT_BIT(8), RT_BIT(8), RT_BIT(9), RT_FALSE), + [RK3366_PD_VPU] = DOMAIN_RK3368("vpu", RT_BIT(12), RT_BIT(12), RT_BIT(7), RT_FALSE), + [RK3366_PD_GPU] = DOMAIN_RK3368("gpu", RT_BIT(15), RT_BIT(15), RT_BIT(2), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3366_pmu = +{ + .pwr_offset = 0x0c, + .status_offset = 0x10, + .req_offset = 0x3c, + .idle_offset = 0x40, + .ack_offset = 0x40, + + .core_pwrcnt_offset = 0x48, + .gpu_pwrcnt_offset = 0x50, + + .core_power_transition_time = 24, + .gpu_power_transition_time = 24, + + .num_domains = RT_ARRAY_SIZE(rk3366_pm_domains), + .domain_info = rk3366_pm_domains, +}; + +static const struct rockchip_domain_info rk3368_pm_domains[] = +{ + [RK3368_PD_PERI] = DOMAIN_RK3368("peri", RT_BIT(13), RT_BIT(12), RT_BIT(6), RT_TRUE), + [RK3368_PD_VIO] = DOMAIN_RK3368_PROTECT("vio", RT_BIT(15), RT_BIT(14), RT_BIT(8), RT_FALSE), + [RK3368_PD_VIDEO] = DOMAIN_RK3368("video", RT_BIT(14), RT_BIT(13), RT_BIT(7), RT_FALSE), + [RK3368_PD_GPU_0] = DOMAIN_RK3368("gpu_0", RT_BIT(16), RT_BIT(15), RT_BIT(2), RT_FALSE), + [RK3368_PD_GPU_1] = DOMAIN_RK3368("gpu_1", RT_BIT(17), RT_BIT(16), RT_BIT(2), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3368_pmu = +{ + .pwr_offset = 0x0c, + .status_offset = 0x10, + .req_offset = 0x3c, + .idle_offset = 0x40, + .ack_offset = 0x40, + + .core_pwrcnt_offset = 0x48, + .gpu_pwrcnt_offset = 0x50, + + .core_power_transition_time = 24, + .gpu_power_transition_time = 24, + + .num_domains = RT_ARRAY_SIZE(rk3368_pm_domains), + .domain_info = rk3368_pm_domains, +}; + +#define DOMAIN_RK3399(name, pwr, status, req, wakeup) DOMAIN(name, pwr, status, req, req, req, wakeup, RT_FALSE) +#define DOMAIN_RK3399_PROTECT(name, pwr, status, req, wakeup) DOMAIN(name, pwr, status, req, req, req, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3399_pm_domains[] = +{ + [RK3399_PD_TCPD0] = DOMAIN_RK3399("tcpd0", RT_BIT(8), RT_BIT(8), 0, RT_FALSE), + [RK3399_PD_TCPD1] = DOMAIN_RK3399("tcpd1", RT_BIT(9), RT_BIT(9), 0, RT_FALSE), + [RK3399_PD_CCI] = DOMAIN_RK3399("cci", RT_BIT(10), RT_BIT(10), 0, RT_TRUE), + [RK3399_PD_CCI0] = DOMAIN_RK3399("cci0", 0, 0, RT_BIT(15), RT_TRUE), + [RK3399_PD_CCI1] = DOMAIN_RK3399("cci1", 0, 0, RT_BIT(16), RT_TRUE), + [RK3399_PD_PERILP] = DOMAIN_RK3399("perilp", RT_BIT(11), RT_BIT(11), RT_BIT(1), RT_TRUE), + [RK3399_PD_PERIHP] = DOMAIN_RK3399("perihp", RT_BIT(12), RT_BIT(12), RT_BIT(2), RT_TRUE), + [RK3399_PD_CENTER] = DOMAIN_RK3399("center", RT_BIT(13), RT_BIT(13), RT_BIT(14), RT_TRUE), + [RK3399_PD_VIO] = DOMAIN_RK3399_PROTECT("vio", RT_BIT(14), RT_BIT(14), RT_BIT(17), RT_FALSE), + [RK3399_PD_GPU] = DOMAIN_RK3399("gpu", RT_BIT(15), RT_BIT(15), RT_BIT(0), RT_FALSE), + [RK3399_PD_VCODEC] = DOMAIN_RK3399("vcodec", RT_BIT(16), RT_BIT(16), RT_BIT(3), RT_FALSE), + [RK3399_PD_VDU] = DOMAIN_RK3399("vdu", RT_BIT(17), RT_BIT(17), RT_BIT(4), RT_FALSE), + [RK3399_PD_RGA] = DOMAIN_RK3399("rga", RT_BIT(18), RT_BIT(18), RT_BIT(5), RT_FALSE), + [RK3399_PD_IEP] = DOMAIN_RK3399("iep", RT_BIT(19), RT_BIT(19), RT_BIT(6), RT_FALSE), + [RK3399_PD_VO] = DOMAIN_RK3399_PROTECT("vo", RT_BIT(20), RT_BIT(20), 0, RT_FALSE), + [RK3399_PD_VOPB] = DOMAIN_RK3399_PROTECT("vopb", 0, 0, RT_BIT(7), RT_FALSE), + [RK3399_PD_VOPL] = DOMAIN_RK3399_PROTECT("vopl", 0, 0, RT_BIT(8), RT_FALSE), + [RK3399_PD_ISP0] = DOMAIN_RK3399("isp0", RT_BIT(22), RT_BIT(22), RT_BIT(9), RT_FALSE), + [RK3399_PD_ISP1] = DOMAIN_RK3399("isp1", RT_BIT(23), RT_BIT(23), RT_BIT(10), RT_FALSE), + [RK3399_PD_HDCP] = DOMAIN_RK3399_PROTECT("hdcp", RT_BIT(24), RT_BIT(24), RT_BIT(11), RT_FALSE), + [RK3399_PD_GMAC] = DOMAIN_RK3399("gmac", RT_BIT(25), RT_BIT(25), RT_BIT(23), RT_TRUE), + [RK3399_PD_EMMC] = DOMAIN_RK3399("emmc", RT_BIT(26), RT_BIT(26), RT_BIT(24), RT_TRUE), + [RK3399_PD_USB3] = DOMAIN_RK3399("usb3", RT_BIT(27), RT_BIT(27), RT_BIT(12), RT_TRUE), + [RK3399_PD_EDP] = DOMAIN_RK3399_PROTECT("edp", RT_BIT(28), RT_BIT(28), RT_BIT(22), RT_FALSE), + [RK3399_PD_GIC] = DOMAIN_RK3399("gic", RT_BIT(29), RT_BIT(29), RT_BIT(27), RT_TRUE), + [RK3399_PD_SD] = DOMAIN_RK3399("sd", RT_BIT(30), RT_BIT(30), RT_BIT(28), RT_TRUE), + [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399("sdioaudio", RT_BIT(31), RT_BIT(31), RT_BIT(29), RT_TRUE), +}; + +static const struct rockchip_pmu_info rk3399_pmu = +{ + .pwr_offset = 0x14, + .status_offset = 0x18, + .req_offset = 0x60, + .idle_offset = 0x64, + .ack_offset = 0x68, + + /* ARM Trusted Firmware manages power transition times */ + .num_domains = RT_ARRAY_SIZE(rk3399_pm_domains), + .domain_info = rk3399_pm_domains, +}; + +#define DOMAIN_RK3528(pwr, req, always, wakeup) DOMAIN_M_A(pwr, pwr, req, req, req, always, wakeup, RT_FALSE) + +static const struct rockchip_domain_info rk3528_pm_domains[] = +{ + [RK3528_PD_PMU] = DOMAIN_RK3528(0, RT_BIT(0), RT_TRUE, RT_FALSE), + [RK3528_PD_BUS] = DOMAIN_RK3528(0, RT_BIT(1), RT_TRUE, RT_FALSE), + [RK3528_PD_DDR] = DOMAIN_RK3528(0, RT_BIT(2), RT_TRUE, RT_FALSE), + [RK3528_PD_MSCH] = DOMAIN_RK3528(0, RT_BIT(3), RT_TRUE, RT_FALSE), + [RK3528_PD_GPU] = DOMAIN_RK3528(RT_BIT(0), RT_BIT(4), RT_TRUE, RT_FALSE), + [RK3528_PD_RKVDEC] = DOMAIN_RK3528(0, RT_BIT(5), RT_TRUE, RT_FALSE), + [RK3528_PD_RKVENC] = DOMAIN_RK3528(0, RT_BIT(6), RT_TRUE, RT_FALSE), + [RK3528_PD_VO] = DOMAIN_RK3528(0, RT_BIT(7), RT_TRUE, RT_FALSE), + [RK3528_PD_VPU] = DOMAIN_RK3528(0, RT_BIT(8), RT_TRUE, RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3528_pmu = +{ + .pwr_offset = 0x1210, + .status_offset = 0x1230, + .req_offset = 0x1110, + .idle_offset = 0x1128, + .ack_offset = 0x1120, + + .num_domains = RT_ARRAY_SIZE(rk3528_pm_domains), + .domain_info = rk3528_pm_domains, +}; + +#define DOMAIN_RK3562(name, pwr, req, mem, wakeup) DOMAIN_M_C_SD(name, pwr, pwr, req, req, req, req, mem, wakeup, RT_FALSE) +#define DOMAIN_RK3562_PROTECT(name, pwr, req, mem, wakeup) DOMAIN_M_C_SD(name, pwr, pwr, req, req, req, req, mem, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3562_pm_domains[] = +{ + [RK3562_PD_GPU] = DOMAIN_RK3562("gpu", RT_BIT(0), RT_BIT(1), 0, RT_FALSE), + [RK3562_PD_NPU] = DOMAIN_RK3562("npu", RT_BIT(1), RT_BIT(2), 0, RT_FALSE), + [RK3562_PD_VDPU] = DOMAIN_RK3562("vdpu", RT_BIT(2), RT_BIT(6), 0, RT_FALSE), + [RK3562_PD_VEPU] = DOMAIN_RK3562("vepu", RT_BIT(3), RT_BIT(7), 0, RT_FALSE), + [RK3562_PD_RGA] = DOMAIN_RK3562("rga", RT_BIT(4), RT_BIT(5), 0, RT_FALSE), + [RK3562_PD_VI] = DOMAIN_RK3562("vi", RT_BIT(5), RT_BIT(3), 0, RT_FALSE), + [RK3562_PD_VO] = DOMAIN_RK3562_PROTECT("vo", RT_BIT(6), RT_BIT(4), 16, RT_FALSE), + [RK3562_PD_PHP] = DOMAIN_RK3562("php", RT_BIT(7), RT_BIT(8), 0, RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3562_pmu = +{ + .pwr_offset = 0x210, + .status_offset = 0x230, + .req_offset = 0x110, + .idle_offset = 0x128, + .ack_offset = 0x120, + .clk_ungate_offset = 0x140, + .mem_sd_offset = 0x300, + + .num_domains = RT_ARRAY_SIZE(rk3562_pm_domains), + .domain_info = rk3562_pm_domains, +}; + +#define DOMAIN_RK3568(name, pwr, req, wakeup) DOMAIN_M(name, pwr, pwr, req, req, req, wakeup, RT_FALSE) +#define DOMAIN_RK3568_PROTECT(name, pwr, req, wakeup) DOMAIN_M(name, pwr, pwr, req, req, req, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3568_pm_domains[] = +{ + [RK3568_PD_NPU] = DOMAIN_RK3568("npu", RT_BIT(1), RT_BIT(2), RT_FALSE), + [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", RT_BIT(0), RT_BIT(1), RT_FALSE), + [RK3568_PD_VI] = DOMAIN_RK3568("vi", RT_BIT(6), RT_BIT(3), RT_FALSE), + [RK3568_PD_VO] = DOMAIN_RK3568_PROTECT("vo", RT_BIT(7), RT_BIT(4), RT_FALSE), + [RK3568_PD_RGA] = DOMAIN_RK3568("rga", RT_BIT(5), RT_BIT(5), RT_FALSE), + [RK3568_PD_VPU] = DOMAIN_RK3568("vpu", RT_BIT(2), RT_BIT(6), RT_FALSE), + [RK3568_PD_RKVDEC] = DOMAIN_RK3568("vdec", RT_BIT(4), RT_BIT(8), RT_FALSE), + [RK3568_PD_RKVENC] = DOMAIN_RK3568("venc", RT_BIT(3), RT_BIT(7), RT_FALSE), + [RK3568_PD_PIPE] = DOMAIN_RK3568("pipe", RT_BIT(8), RT_BIT(11), RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3568_pmu = +{ + .pwr_offset = 0xa0, + .status_offset = 0x98, + .req_offset = 0x50, + .idle_offset = 0x68, + .ack_offset = 0x60, + + .num_domains = RT_ARRAY_SIZE(rk3568_pm_domains), + .domain_info = rk3568_pm_domains, +}; + +#define DOMAIN_RK3576(name, p_offset, pwr, status, r_status, r_offset, req, idle, g_mask, delay, wakeup) \ + DOMAIN_M_O_R_G(name, p_offset, pwr, status, r_status, r_offset, req, idle, idle, g_mask, delay, wakeup, RT_FALSE) + +#define DOMAIN_RK3576_P(name, p_offset, pwr, status, r_status, r_offset, req, idle, g_mask, delay, wakeup) \ + DOMAIN_M_O_R_G(name, p_offset, pwr, status, r_status, r_offset, req, idle, idle, g_mask, delay, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3576_pm_domains[] = +{ + /* name p_offset pwr status r_status r_offset req idle_st g_mask delay wakeup */ + [RK3576_PD_NPU] = DOMAIN_RK3576("npu", 0x0, RT_BIT(0), RT_BIT(0), 0, 0x0, 0, 0, 0, 0, RT_FALSE), + [RK3576_PD_NVM] = DOMAIN_RK3576("nvm", 0x0, RT_BIT(6), 0, RT_BIT(6), 0x4, RT_BIT(2), RT_BIT(18), RT_BIT(2), 0, RT_FALSE), + [RK3576_PD_SDGMAC] = DOMAIN_RK3576("sdgmac", 0x0, RT_BIT(7), 0, RT_BIT(7), 0x4, RT_BIT(1), RT_BIT(17), 0x6, 0, RT_FALSE), + [RK3576_PD_AUDIO] = DOMAIN_RK3576("audio", 0x0, RT_BIT(8), 0, RT_BIT(8), 0x4, RT_BIT(0), RT_BIT(16), RT_BIT(0), 0, RT_FALSE), + [RK3576_PD_PHP] = DOMAIN_RK3576("php", 0x0, RT_BIT(9), 0, RT_BIT(9), 0x0, RT_BIT(15), RT_BIT(15), RT_BIT(15), 0, RT_FALSE), + [RK3576_PD_SUBPHP] = DOMAIN_RK3576("subphp", 0x0, RT_BIT(10), 0, RT_BIT(10), 0x0, 0, 0, 0, 0, RT_FALSE), + [RK3576_PD_VOP] = DOMAIN_RK3576_P("vop", 0x0, RT_BIT(11), 0, RT_BIT(11), 0x0, 0x6000, 0x6000, 0x6000, 15, RT_FALSE), + [RK3576_PD_VO1] = DOMAIN_RK3576_P("vo1", 0x0, RT_BIT(14), 0, RT_BIT(14), 0x0, RT_BIT(12), RT_BIT(12), 0x7000, 0, RT_FALSE), + [RK3576_PD_VO0] = DOMAIN_RK3576_P("vo0", 0x0, RT_BIT(15), 0, RT_BIT(15), 0x0, RT_BIT(11), RT_BIT(11), 0x6800, 0, RT_FALSE), + [RK3576_PD_USB] = DOMAIN_RK3576("usb", 0x4, RT_BIT(0), 0, RT_BIT(16), 0x0, RT_BIT(10), RT_BIT(10), 0x6400, 0, RT_TRUE), + [RK3576_PD_VI] = DOMAIN_RK3576("vi", 0x4, RT_BIT(1), 0, RT_BIT(17), 0x0, RT_BIT(9), RT_BIT(9), RT_BIT(9), 0, RT_FALSE), + [RK3576_PD_VEPU0] = DOMAIN_RK3576("vepu0", 0x4, RT_BIT(2), 0, RT_BIT(18), 0x0, RT_BIT(7), RT_BIT(7), 0x280, 0, RT_FALSE), + [RK3576_PD_VEPU1] = DOMAIN_RK3576("vepu1", 0x4, RT_BIT(3), 0, RT_BIT(19), 0x0, RT_BIT(8), RT_BIT(8), RT_BIT(8), 0, RT_FALSE), + [RK3576_PD_VDEC] = DOMAIN_RK3576("vdec", 0x4, RT_BIT(4), 0, RT_BIT(20), 0x0, RT_BIT(6), RT_BIT(6), RT_BIT(6), 0, RT_FALSE), + [RK3576_PD_VPU] = DOMAIN_RK3576_P("vpu", 0x4, RT_BIT(5), 0, RT_BIT(21), 0x0, RT_BIT(5), RT_BIT(5), RT_BIT(5), 0, RT_FALSE), + [RK3576_PD_NPUTOP] = DOMAIN_RK3576("nputop", 0x4, RT_BIT(6), 0, RT_BIT(22), 0x0, 0x18, 0x18, 0x18, 15, RT_FALSE), + [RK3576_PD_NPU0] = DOMAIN_RK3576("npu0", 0x4, RT_BIT(7), 0, RT_BIT(23), 0x0, RT_BIT(1), RT_BIT(1), 0x1a, 0, RT_FALSE), + [RK3576_PD_NPU1] = DOMAIN_RK3576("npu1", 0x4, RT_BIT(8), 0, RT_BIT(24), 0x0, RT_BIT(2), RT_BIT(2), 0x1c, 0, RT_FALSE), + [RK3576_PD_GPU] = DOMAIN_RK3576("gpu", 0x4, RT_BIT(9), 0, RT_BIT(25), 0x0, RT_BIT(0), RT_BIT(0), RT_BIT(0), 0, RT_FALSE), +}; + + +static const struct rockchip_pmu_info rk3576_pmu = +{ + .pwr_offset = 0x210, + .status_offset = 0x230, + .chain_status_offset = 0x248, + .mem_status_offset = 0x250, + .mem_pwr_offset = 0x300, + .req_offset = 0x110, + .idle_offset = 0x128, + .ack_offset = 0x120, + .repair_status_offset = 0x570, + .clk_ungate_offset = 0x140, + + .num_domains = RT_ARRAY_SIZE(rk3576_pm_domains), + .domain_info = rk3576_pm_domains, +}; + +#define DOMAIN_RK3588(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup) \ + DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup, RT_FALSE) + +#define DOMAIN_RK3588_P(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, wakeup) \ + DOMAIN_M_O_R(name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, idle, wakeup, RT_TRUE) + +static const struct rockchip_domain_info rk3588_pm_domains[] = +{ + [RK3588_PD_GPU] = DOMAIN_RK3588("gpu", 0x0, RT_BIT(0), 0, 0x0, 0, RT_BIT(1), 0x0, RT_BIT(0), RT_BIT(0), RT_FALSE), + [RK3588_PD_NPU] = DOMAIN_RK3588("npu", 0x0, RT_BIT(1), RT_BIT(1), 0x0, 0, 0, 0x0, 0, 0, RT_FALSE), + [RK3588_PD_VCODEC] = DOMAIN_RK3588("vcodec", 0x0, RT_BIT(2), RT_BIT(2), 0x0, 0, 0, 0x0, 0, 0, RT_FALSE), + [RK3588_PD_NPUTOP] = DOMAIN_RK3588("nputop", 0x0, RT_BIT(3), 0, 0x0, RT_BIT(11), RT_BIT(2), 0x0, RT_BIT(1), RT_BIT(1), RT_FALSE), + [RK3588_PD_NPU1] = DOMAIN_RK3588("npu1", 0x0, RT_BIT(4), 0, 0x0, RT_BIT(12), RT_BIT(3), 0x0, RT_BIT(2), RT_BIT(2), RT_FALSE), + [RK3588_PD_NPU2] = DOMAIN_RK3588("npu2", 0x0, RT_BIT(5), 0, 0x0, RT_BIT(13), RT_BIT(4), 0x0, RT_BIT(3), RT_BIT(3), RT_FALSE), + [RK3588_PD_VENC0] = DOMAIN_RK3588("venc0", 0x0, RT_BIT(6), 0, 0x0, RT_BIT(14), RT_BIT(5), 0x0, RT_BIT(4), RT_BIT(4), RT_FALSE), + [RK3588_PD_VENC1] = DOMAIN_RK3588("venc1", 0x0, RT_BIT(7), 0, 0x0, RT_BIT(15), RT_BIT(6), 0x0, RT_BIT(5), RT_BIT(5), RT_FALSE), + [RK3588_PD_RKVDEC0] = DOMAIN_RK3588("rkvdec0", 0x0, RT_BIT(8), 0, 0x0, RT_BIT(16), RT_BIT(7), 0x0, RT_BIT(6), RT_BIT(6), RT_FALSE), + [RK3588_PD_RKVDEC1] = DOMAIN_RK3588("rkvdec1", 0x0, RT_BIT(9), 0, 0x0, RT_BIT(17), RT_BIT(8), 0x0, RT_BIT(7), RT_BIT(7), RT_FALSE), + [RK3588_PD_VDPU] = DOMAIN_RK3588("vdpu", 0x0, RT_BIT(10), 0, 0x0, RT_BIT(18), RT_BIT(9), 0x0, RT_BIT(8), RT_BIT(8), RT_FALSE), + [RK3588_PD_RGA30] = DOMAIN_RK3588("rga30", 0x0, RT_BIT(11), 0, 0x0, RT_BIT(19), RT_BIT(10), 0x0, 0, 0, RT_FALSE), + [RK3588_PD_AV1] = DOMAIN_RK3588("av1", 0x0, RT_BIT(12), 0, 0x0, RT_BIT(20), RT_BIT(11), 0x0, RT_BIT(9), RT_BIT(9), RT_FALSE), + [RK3588_PD_VI] = DOMAIN_RK3588("vi", 0x0, RT_BIT(13), 0, 0x0, RT_BIT(21), RT_BIT(12), 0x0, RT_BIT(10), RT_BIT(10), RT_FALSE), + [RK3588_PD_FEC] = DOMAIN_RK3588("fec", 0x0, RT_BIT(14), 0, 0x0, RT_BIT(22), RT_BIT(13), 0x0, 0, 0, RT_FALSE), + [RK3588_PD_ISP1] = DOMAIN_RK3588("isp1", 0x0, RT_BIT(15), 0, 0x0, RT_BIT(23), RT_BIT(14), 0x0, RT_BIT(11), RT_BIT(11), RT_FALSE), + [RK3588_PD_RGA31] = DOMAIN_RK3588("rga31", 0x4, RT_BIT(0), 0, 0x0, RT_BIT(24), RT_BIT(15), 0x0, RT_BIT(12), RT_BIT(12), RT_FALSE), + [RK3588_PD_VOP] = DOMAIN_RK3588_P("vop", 0x4, RT_BIT(1), 0, 0x0, RT_BIT(25), RT_BIT(16), 0x0, RT_BIT(13) | RT_BIT(14), RT_BIT(13) | RT_BIT(14), RT_FALSE), + [RK3588_PD_VO0] = DOMAIN_RK3588_P("vo0", 0x4, RT_BIT(2), 0, 0x0, RT_BIT(26), RT_BIT(17), 0x0, RT_BIT(15), RT_BIT(15), RT_FALSE), + [RK3588_PD_VO1] = DOMAIN_RK3588_P("vo1", 0x4, RT_BIT(3), 0, 0x0, RT_BIT(27), RT_BIT(18), 0x4, RT_BIT(0), RT_BIT(16), RT_FALSE), + [RK3588_PD_AUDIO] = DOMAIN_RK3588("audio", 0x4, RT_BIT(4), 0, 0x0, RT_BIT(28), RT_BIT(19), 0x4, RT_BIT(1), RT_BIT(17), RT_FALSE), + [RK3588_PD_PHP] = DOMAIN_RK3588("php", 0x4, RT_BIT(5), 0, 0x0, RT_BIT(29), RT_BIT(20), 0x4, RT_BIT(5), RT_BIT(21), RT_FALSE), + [RK3588_PD_GMAC] = DOMAIN_RK3588("gmac", 0x4, RT_BIT(6), 0, 0x0, RT_BIT(30), RT_BIT(21), 0x0, 0, 0, RT_FALSE), + [RK3588_PD_PCIE] = DOMAIN_RK3588("pcie", 0x4, RT_BIT(7), 0, 0x0, RT_BIT(31), RT_BIT(22), 0x0, 0, 0, RT_TRUE), + [RK3588_PD_NVM] = DOMAIN_RK3588("nvm", 0x4, RT_BIT(8), RT_BIT(24), 0x4, 0, 0, 0x4, RT_BIT(2), RT_BIT(18), RT_FALSE), + [RK3588_PD_NVM0] = DOMAIN_RK3588("nvm0", 0x4, RT_BIT(9), 0, 0x4, RT_BIT(1), RT_BIT(23), 0x0, 0, 0, RT_FALSE), + [RK3588_PD_SDIO] = DOMAIN_RK3588("sdio", 0x4, RT_BIT(10), 0, 0x4, RT_BIT(2), RT_BIT(24), 0x4, RT_BIT(3), RT_BIT(19), RT_FALSE), + [RK3588_PD_USB] = DOMAIN_RK3588("usb", 0x4, RT_BIT(11), 0, 0x4, RT_BIT(3), RT_BIT(25), 0x4, RT_BIT(4), RT_BIT(20), RT_TRUE), + [RK3588_PD_SDMMC] = DOMAIN_RK3588("sdmmc", 0x4, RT_BIT(13), 0, 0x4, RT_BIT(5), RT_BIT(26), 0x0, 0, 0, RT_FALSE), +}; + +static const struct rockchip_pmu_info rk3588_pmu = +{ + .pwr_offset = 0x14c, + .status_offset = 0x180, + .req_offset = 0x10c, + .idle_offset = 0x120, + .ack_offset = 0x118, + .mem_pwr_offset = 0x1a0, + .chain_status_offset = 0x1f0, + .mem_status_offset = 0x1f8, + .repair_status_offset = 0x290, + + .num_domains = RT_ARRAY_SIZE(rk3588_pm_domains), + .domain_info = rk3588_pm_domains, +}; + +#define DOMAIN_RV1126(name, pwr, req, idle, wakeup) DOMAIN_M(name, pwr, pwr, req, idle, idle, wakeup, RT_FALSE) +#define DOMAIN_RV1126_PROTECT(name, pwr, req, idle, wakeup) DOMAIN_M(name, pwr, pwr, req, idle, idle, wakeup, RT_TRUE) +#define DOMAIN_RV1126_O(name, pwr, req, idle, r_offset, wakeup) DOMAIN_M_O(name, pwr, pwr, 0, req, idle, idle, r_offset, wakeup, RT_FALSE) + +static const struct rockchip_domain_info rv1126_pm_domains[] = +{ + [RV1126_PD_CRYPTO] = DOMAIN_RV1126_O("crypto", RT_BIT(10), RT_BIT(4), RT_BIT(20), 0x4, RT_FALSE), + [RV1126_PD_VEPU] = DOMAIN_RV1126("vepu", RT_BIT(2), RT_BIT(9), RT_BIT(9), RT_FALSE), + [RV1126_PD_VI] = DOMAIN_RV1126("vi", RT_BIT(4), RT_BIT(6), RT_BIT(6), RT_FALSE), + [RV1126_PD_VO] = DOMAIN_RV1126_PROTECT("vo", RT_BIT(5), RT_BIT(7), RT_BIT(7), RT_FALSE), + [RV1126_PD_ISPP] = DOMAIN_RV1126("ispp", RT_BIT(1), RT_BIT(8), RT_BIT(8), RT_FALSE), + [RV1126_PD_VDPU] = DOMAIN_RV1126("vdpu", RT_BIT(3), RT_BIT(10), RT_BIT(10), RT_FALSE), + [RV1126_PD_NVM] = DOMAIN_RV1126("nvm", RT_BIT(7), RT_BIT(11), RT_BIT(11), RT_FALSE), + [RV1126_PD_SDIO] = DOMAIN_RV1126("sdio", RT_BIT(8), RT_BIT(13), RT_BIT(13), RT_FALSE), + [RV1126_PD_USB] = DOMAIN_RV1126("usb", RT_BIT(9), RT_BIT(15), RT_BIT(15), RT_FALSE), + [RV1126_PD_NPU] = DOMAIN_RV1126_O("npu", RT_BIT(0), RT_BIT(2), RT_BIT(18), 0x4, RT_FALSE), +}; + +static const struct rockchip_pmu_info rv1126_pmu = +{ + .pwr_offset = 0x110, + .status_offset = 0x108, + .req_offset = 0xc0, + .idle_offset = 0xd8, + .ack_offset = 0xd0, + + .num_domains = RT_ARRAY_SIZE(rv1126_pm_domains), + .domain_info = rv1126_pm_domains, +}; + +static const struct rt_ofw_node_id rockchip_pmdomain_ofw_ids[] = +{ + { .compatible = "rockchip,px30-power-controller", .data = &px30_pmu, }, + { .compatible = "rockchip,rk1808-power-controller", .data = &rk1808_pmu, }, + { .compatible = "rockchip,rk3036-power-controller", .data = &rk3036_pmu, }, + { .compatible = "rockchip,rk3066-power-controller", .data = &rk3066_pmu, }, + { .compatible = "rockchip,rk3128-power-controller", .data = &rk3128_pmu, }, + { .compatible = "rockchip,rk3188-power-controller", .data = &rk3188_pmu, }, + { .compatible = "rockchip,rk3228-power-controller", .data = &rk3228_pmu, }, + { .compatible = "rockchip,rk3288-power-controller", .data = &rk3288_pmu, }, + { .compatible = "rockchip,rk3328-power-controller", .data = &rk3328_pmu, }, + { .compatible = "rockchip,rk3366-power-controller", .data = &rk3366_pmu, }, + { .compatible = "rockchip,rk3368-power-controller", .data = &rk3368_pmu, }, + { .compatible = "rockchip,rk3399-power-controller", .data = &rk3399_pmu, }, + { .compatible = "rockchip,rk3528-power-controller", .data = &rk3528_pmu, }, + { .compatible = "rockchip,rk3562-power-controller", .data = &rk3562_pmu, }, + { .compatible = "rockchip,rk3568-power-controller", .data = &rk3568_pmu, }, + { .compatible = "rockchip,rk3576-power-controller", .data = &rk3576_pmu, }, + { .compatible = "rockchip,rk3588-power-controller", .data = &rk3588_pmu, }, + { .compatible = "rockchip,rv1126-power-controller", .data = &rv1126_pmu, }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_pmdomain_driver = +{ + .name = "rockchip-pmdomain", + .ids = rockchip_pmdomain_ofw_ids, + + .probe = rockchip_pmdomain_probe, +}; + +static int rockchip_pmdomain_drv_register(void) +{ + rt_platform_driver_register(&rockchip_pmdomain_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(rockchip_pmdomain_drv_register); diff --git a/bsp/rockchip/dm/pwm/Kconfig b/bsp/rockchip/dm/pwm/Kconfig new file mode 100755 index 00000000000..d26e4c33512 --- /dev/null +++ b/bsp/rockchip/dm/pwm/Kconfig @@ -0,0 +1,5 @@ +config RT_PWM_ROCKCHIP + bool "Rockchip PWM support" + depends on RT_USING_PWM + depends on RT_USING_PINCTRL + default n diff --git a/bsp/rockchip/dm/pwm/SConscript b/bsp/rockchip/dm/pwm/SConscript new file mode 100755 index 00000000000..943f37192f7 --- /dev/null +++ b/bsp/rockchip/dm/pwm/SConscript @@ -0,0 +1,14 @@ +from building import * + +group = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +src = [] + +if GetDepend(['RT_PWM_ROCKCHIP']): + src += ['pwm-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/pwm/pwm-rockchip.c b/bsp/rockchip/dm/pwm/pwm-rockchip.c new file mode 100755 index 00000000000..223a6c663e8 --- /dev/null +++ b/bsp/rockchip/dm/pwm/pwm-rockchip.c @@ -0,0 +1,613 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +#include "rockchip.h" + +#define PWM_CTRL_TIMER_EN (1 << 0) +#define PWM_CTRL_OUTPUT_EN (1 << 3) + +#define PWM_ENABLE (1 << 0) +#define PWM_CONTINUOUS (1 << 1) +#define PWM_DUTY_POSITIVE (1 << 3) +#define PWM_DUTY_NEGATIVE (0 << 3) +#define PWM_INACTIVE_NEGATIVE (0 << 4) +#define PWM_INACTIVE_POSITIVE (1 << 4) +#define PWM_POLARITY_MASK (PWM_DUTY_POSITIVE | PWM_INACTIVE_POSITIVE) +#define PWM_OUTPUT_LEFT (0 << 5) +#define PWM_LOCK_EN (1 << 6) +#define PWM_LP_DISABLE (0 << 8) + +#define PWM_ENABLE_V4 (3 << 0) +#define PWM_CLK_EN(v) HIWORD_UPDATE(v, 0, 0) +#define PWM_EN(v) HIWORD_UPDATE(v, 1, 1) +#define PWM_CTRL_UPDATE_EN(v) HIWORD_UPDATE(v, 2, 2) + +#define OFFSET 0x18 +#define RPT 0x1c +#define INT_EN 0x74 +#define CAP_LPR_INT_EN(v) HIWORD_UPDATE(v, 0, 0) +#define CAP_HPR_INT_EN(v) HIWORD_UPDATE(v, 1, 1) +#define ONESHOT_END_INT_EN(v) HIWORD_UPDATE(v, 2, 2) +#define RELOAD_INT_EN(v) HIWORD_UPDATE(v, 3, 3) +#define FREQ_INT_EN(v) HIWORD_UPDATE(v, 4, 4) +#define PWR_INT_EN(v) HIWORD_UPDATE(v, 5, 5) +#define IR_TRANS_END_INT_EN(v) HIWORD_UPDATE(v, 6, 6) +#define WAVE_MAX_INT_EN(v) HIWORD_UPDATE(v, 7, 7) +#define WAVE_MIDDLE_INT_EN(v) HIWORD_UPDATE(v, 8, 8) +#define BIPHASIC_INT_EN(v) HIWORD_UPDATE(v, 9, 9) + +#define PWM_MODE(v) HIWORD_UPDATE(v, 0, 1) +#define ONESHOT_MODE 0 +#define CONTINUOUS_MODE 1 +#define CAPTURE_MODE 2 +#define PWM_POLARITY(v) HIWORD_UPDATE(v, 2, 3) +#define DUTY_NEGATIVE (0 << 0) +#define DUTY_POSITIVE (1 << 0) +#define INACTIVE_NEGATIVE (0 << 1) +#define INACTIVE_POSITIVE (1 << 1) +#define PWM_ALIGNED_INVALID(v) HIWORD_UPDATE(v, 5, 5) +#define PWM_IN_SEL(v) HIWORD_UPDATE(v, 6, 8) + +#define NSEC_PER_USEC 1000L +#define USEC_PER_SEC 1000000L +#define NSEC_PER_SEC 1000000000L + +struct rockchip_pwm_regs +{ + rt_ubase_t duty; + rt_ubase_t period; + rt_ubase_t cntr; + rt_ubase_t ctrl; + rt_ubase_t enable; +}; + +struct rockchip_pwm_data +{ + struct rockchip_pwm_regs regs; + + rt_uint32_t main_version; + rt_uint32_t prescaler; + rt_bool_t supports_polarity; + rt_bool_t supports_lock; + rt_uint32_t enable_conf; +}; + +struct rockchip_pwm +{ + struct rt_device_pwm parent; + void *base; + + struct rt_clk *clk; + struct rt_clk *pclk; + + const struct rockchip_pwm_data *data; +}; + +#define raw_to_rockchip_pwm(raw) rt_container_of(raw, struct rockchip_pwm, parent) + +static rt_err_t rockchip_pwm_enable(struct rockchip_pwm *rk_pwm, rt_bool_t enable) +{ + rt_uint32_t enable_conf = rk_pwm->data->enable_conf, val; + + if (enable) + { + rt_err_t err = rt_clk_enable(rk_pwm->clk); + + if (err) + { + return err; + } + } + + val = HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl); + + if (enable) + { + val |= enable_conf; + } + else + { + val &= ~enable_conf; + } + + HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl) = val; + + if (!enable) + { + rt_clk_disable(rk_pwm->clk); + } + else + { + rt_pin_ctrl_confs_apply_by_name(&rk_pwm->parent.parent, "active"); + } + + return RT_EOK; +} + +static void rockchip_pwm_config(struct rockchip_pwm *rk_pwm, struct rt_pwm_configuration *pwm_cfg) +{ + rt_ubase_t period, duty; + rt_uint64_t clk_rate, div; + rt_uint32_t ctrl; + + clk_rate = rt_clk_get_rate(rk_pwm->clk); + + /* + * Since period and duty cycle registers have a width of 32 bits, every + * possible input period can be obtained using the default prescaler value + * for all practical clock rate values. + */ + div = clk_rate * pwm_cfg->period; + period = RT_DIV_ROUND_CLOSEST_ULL(div, rk_pwm->data->prescaler * NSEC_PER_SEC); + + div = clk_rate * pwm_cfg->pulse; + duty = RT_DIV_ROUND_CLOSEST_ULL(div, rk_pwm->data->prescaler * NSEC_PER_SEC); + + /* + * Lock the period and duty of previous configuration, then change the duty + * and period, that would not be effective. + */ + ctrl = HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl); + + if (rk_pwm->data->supports_lock) + { + ctrl |= PWM_LOCK_EN; + HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl) = ctrl; + } + + HWREG32(rk_pwm->base + rk_pwm->data->regs.period) = period; + HWREG32(rk_pwm->base + rk_pwm->data->regs.duty) = duty; + + if (rk_pwm->data->supports_polarity) + { + ctrl &= ~PWM_POLARITY_MASK; + + if (pwm_cfg->complementary) + { + ctrl |= PWM_DUTY_NEGATIVE | PWM_INACTIVE_POSITIVE; + } + else + { + ctrl |= PWM_DUTY_POSITIVE | PWM_INACTIVE_NEGATIVE; + } + } + + /* + * Unlock and set polarity at the same time, the configuration of duty, + * period and polarity would be effective together at next period. + */ + if (rk_pwm->data->supports_lock) + { + ctrl &= ~PWM_LOCK_EN; + } + + HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl) = ctrl; +} + +static rt_err_t rockchip_pwm_get_state(struct rockchip_pwm *rk_pwm, struct rt_pwm_configuration *pwm_cfg) +{ + rt_uint32_t val; + rt_uint64_t tmp; + rt_ubase_t clk_rate; + + clk_rate = rt_clk_get_rate(rk_pwm->clk); + + tmp = HWREG32(rk_pwm->base + rk_pwm->data->regs.period); + tmp *= rk_pwm->data->prescaler * NSEC_PER_SEC; + pwm_cfg->period = RT_DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); + + tmp = HWREG32(rk_pwm->base + rk_pwm->data->regs.duty); + tmp *= rk_pwm->data->prescaler * NSEC_PER_SEC; + pwm_cfg->pulse = RT_DIV_ROUND_CLOSEST_ULL(tmp, clk_rate); + + if (rk_pwm->data->main_version >= 4) + { + val = HWREG32(rk_pwm->base + rk_pwm->data->regs.enable); + } + else + { + val = HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl); + } + + if (rk_pwm->data->supports_polarity && !(val & PWM_DUTY_POSITIVE)) + { + pwm_cfg->complementary = RT_TRUE; + } + else + { + pwm_cfg->complementary = RT_FALSE; + } + + return RT_EOK; +} + +static rt_err_t rockchip_pwm_enable_v4(struct rockchip_pwm *rk_pwm, rt_bool_t enable) +{ + rt_uint32_t delay_us; + struct rt_pwm_configuration pwm_cfg; + + if (enable) + { + rt_err_t err = rt_clk_enable(rk_pwm->clk); + + if (err) + { + return err; + } + } + + HWREG32(rk_pwm->base + rk_pwm->data->regs.enable) = PWM_EN(enable) | PWM_CLK_EN(enable); + + if (!enable) + { + rockchip_pwm_get_state(rk_pwm, &pwm_cfg); + delay_us = RT_DIV_ROUND_UP_ULL(pwm_cfg.period, NSEC_PER_USEC); + rt_hw_us_delay(delay_us); + rt_clk_disable(rk_pwm->clk); + } + else + { + rt_pin_ctrl_confs_apply_by_name(&rk_pwm->parent.parent, "active"); + } + + return RT_EOK; +} + +static void rockchip_pwm_config_v4(struct rockchip_pwm *rk_pwm, struct rt_pwm_configuration *pwm_cfg) +{ + unsigned long period, duty; + rt_uint64_t clk_rate_kHz = rt_clk_get_rate(rk_pwm->clk) / 1000; + rt_uint64_t div = 0; + rt_uint64_t tmp = 0; + + tmp = (rt_uint64_t)rk_pwm->data->prescaler * USEC_PER_SEC; + /* + * Since period and duty cycle registers have a width of 32 + * bits, every possible input period can be obtained using the + * default prescaler value for all practical clock rate values. + */ + div = (rt_uint64_t)clk_rate_kHz * pwm_cfg->period; + period = RT_DIV_ROUND_CLOSEST_ULL(div, tmp); + + div = (rt_uint64_t)clk_rate_kHz * pwm_cfg->pulse; + duty = RT_DIV_ROUND_CLOSEST_ULL(div, tmp); + + HWREG32(rk_pwm->base + rk_pwm->data->regs.period) = period; + HWREG32(rk_pwm->base + rk_pwm->data->regs.duty) = duty; + + if (rk_pwm->data->supports_polarity) + { + if (pwm_cfg->complementary) + { + HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl) = PWM_POLARITY(DUTY_NEGATIVE | INACTIVE_POSITIVE); + } + else + { + HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl) = PWM_POLARITY(DUTY_POSITIVE | INACTIVE_NEGATIVE); + } + } + + HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl) = PWM_MODE(CONTINUOUS_MODE) | PWM_ALIGNED_INVALID(RT_FALSE); + HWREG32(rk_pwm->base + OFFSET) = 0; + + HWREG32(rk_pwm->base + RPT) = 0; + HWREG32(rk_pwm->base + INT_EN) = ONESHOT_END_INT_EN(RT_FALSE); + + HWREG32(rk_pwm->base + rk_pwm->data->regs.enable) = PWM_CTRL_UPDATE_EN(RT_TRUE); +} + +static rt_err_t rockchip_pwm_control(struct rt_device_pwm *pwm, int cmd, void *args) +{ + rt_err_t err = RT_EOK; + struct rockchip_pwm *rk_pwm = raw_to_rockchip_pwm(pwm); + struct rt_pwm_configuration *pwm_cfg = args; + + rt_clk_enable(rk_pwm->pclk); + rt_clk_enable(rk_pwm->clk); + + /* RT_PWM framework have check args */ + switch (cmd) + { + case PWM_CMD_ENABLE: + if (rk_pwm->data->main_version >= 4) + { + err = rockchip_pwm_enable_v4(rk_pwm, RT_TRUE); + } + else + { + err = rockchip_pwm_enable(rk_pwm, RT_TRUE); + } + break; + + case PWM_CMD_DISABLE: + if (rk_pwm->data->main_version >= 4) + { + err = rockchip_pwm_enable_v4(rk_pwm, RT_FALSE); + } + else + { + err = rockchip_pwm_enable(rk_pwm, RT_FALSE); + } + break; + + case PWM_CMD_SET: + case PWM_CMD_SET_PERIOD: + case PWM_CMD_SET_PULSE: + if (rk_pwm->data->main_version >= 4) + { + rockchip_pwm_config_v4(rk_pwm, RT_FALSE); + } + else + { + rockchip_pwm_config(rk_pwm, pwm_cfg); + } + break; + + case PWM_CMD_GET: + err = rockchip_pwm_get_state(rk_pwm, pwm_cfg); + break; + + default: + err = -RT_EINVAL; + break; + } + + rt_clk_disable(rk_pwm->clk); + rt_clk_disable(rk_pwm->pclk); + + return err; +} + +const static struct rt_pwm_ops rockchip_pwm_ops = +{ + .control = rockchip_pwm_control, +}; + +static void rockchip_pwm_free(struct rockchip_pwm *rk_pwm) +{ + if (rk_pwm->base) + { + rt_iounmap(rk_pwm->base); + } + + if (!rt_is_err_or_null(rk_pwm->clk)) + { + rt_clk_disable_unprepare(rk_pwm->clk); + rt_clk_put(rk_pwm->clk); + } + + if (!rt_is_err_or_null(rk_pwm->pclk)) + { + rt_clk_disable_unprepare(rk_pwm->pclk); + rt_clk_put(rk_pwm->pclk); + } + + rt_free(rk_pwm); +} + +static rt_err_t rockchip_pwm_probe(struct rt_platform_device *pdev) +{ + int id; + rt_bool_t enabled; + rt_err_t err = RT_EOK; + rt_uint32_t enable_conf, ctrl; + struct rt_device *dev = &pdev->parent; + struct rockchip_pwm *rk_pwm = rt_calloc(1, sizeof(*rk_pwm)); + const struct rockchip_pwm_data *pdata = pdev->id->data; + + if (!rk_pwm) + { + return -RT_ENOMEM; + } + + rk_pwm->data = pdata; + rk_pwm->base = rt_dm_dev_iomap(dev, 0); + + if (!rk_pwm->base) + { + err = -RT_EIO; + goto _free_res; + } + + rk_pwm->clk = rt_clk_get_by_name(dev, "pwm"); + + if (rt_is_err(rk_pwm->clk)) + { + err = rt_ptr_err(rk_pwm->clk); + goto _free_res; + } + + rk_pwm->pclk = rt_clk_get_by_name(dev, "pclk"); + + if (rt_is_err(rk_pwm->pclk)) + { + err = rt_ptr_err(rk_pwm->pclk); + goto _free_res; + } + + if ((err = rt_clk_prepare_enable(rk_pwm->clk))) + { + goto _free_res; + } + + if ((err = rt_clk_prepare_enable(rk_pwm->pclk))) + { + goto _free_res; + } + + enable_conf = rk_pwm->data->enable_conf; + if (rk_pwm->data->main_version >= 4) + { + ctrl = HWREG32(rk_pwm->base + rk_pwm->data->regs.enable); + } + else + { + ctrl = HWREG32(rk_pwm->base + rk_pwm->data->regs.ctrl); + } + enabled = (ctrl & enable_conf) == enable_conf; + + /* Keep the PWM clk enabled if the PWM appears to be up and running. */ + if (!enabled) + { + rt_clk_enable(rk_pwm->clk); + rt_clk_disable(rk_pwm->clk); + } + + rt_clk_disable(rk_pwm->pclk); + + dev->user_data = rk_pwm; + + rk_pwm->parent.parent.ofw_node = dev->ofw_node; + + if ((id = pdev->dev_id) >= 0) + { + rt_dm_dev_set_name(&rk_pwm->parent.parent, "pwm%u", id); + } + else + { + rt_dm_dev_set_name_auto(&rk_pwm->parent.parent, "pwm"); + } + + rt_device_pwm_register(&rk_pwm->parent, + rt_dm_dev_get_name(&rk_pwm->parent.parent), &rockchip_pwm_ops, rk_pwm); + + rt_dm_dev_bind_fwdata(dev, RT_NULL, rk_pwm); + + /* Sync config */ + rt_pwm_enable(&rk_pwm->parent, 0); + + if (!enabled) + { + rt_pwm_disable(&rk_pwm->parent, 0); + } + + return RT_EOK; + +_free_res: + rockchip_pwm_free(rk_pwm); + + return err; +} + +static rt_err_t rockchip_pwm_remove(struct rt_platform_device *pdev) +{ + struct rt_device *dev = &pdev->parent; + struct rockchip_pwm *rk_pwm = dev->user_data; + + rt_dm_dev_unbind_fwdata(dev, RT_NULL); + + rockchip_pwm_enable(rk_pwm, RT_FALSE); + + rt_device_unregister(&rk_pwm->parent.parent); + + rockchip_pwm_free(rk_pwm); + + return RT_EOK; +} + +static const struct rockchip_pwm_data pwm_data_v1 = +{ + .regs = + { + .duty = 0x04, + .period = 0x08, + .cntr = 0x00, + .ctrl = 0x0c, + }, + .prescaler = 2, + .supports_polarity = RT_FALSE, + .supports_lock = RT_FALSE, + .enable_conf = PWM_CTRL_OUTPUT_EN | PWM_CTRL_TIMER_EN, +}; + +static const struct rockchip_pwm_data pwm_data_v2 = +{ + .regs = + { + .duty = 0x08, + .period = 0x04, + .cntr = 0x00, + .ctrl = 0x0c, + }, + .prescaler = 1, + .supports_polarity = RT_TRUE, + .supports_lock = RT_FALSE, + .enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE | PWM_CONTINUOUS, +}; + +static const struct rockchip_pwm_data pwm_data_vop = +{ + .regs = + { + .duty = 0x08, + .period = 0x04, + .cntr = 0x0c, + .ctrl = 0x00, + }, + .prescaler = 1, + .supports_polarity = RT_TRUE, + .supports_lock = RT_FALSE, + .enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE | PWM_CONTINUOUS, +}; + +static const struct rockchip_pwm_data pwm_data_v3 = +{ + .regs = + { + .duty = 0x08, + .period = 0x04, + .cntr = 0x00, + .ctrl = 0x0c, + }, + .prescaler = 1, + .supports_polarity = RT_TRUE, + .supports_lock = RT_TRUE, + .enable_conf = PWM_OUTPUT_LEFT | PWM_LP_DISABLE | PWM_ENABLE | PWM_CONTINUOUS, +}; + +static const struct rockchip_pwm_data pwm_data_v4 = +{ + .regs = + { + .duty = 0x14, + .period = 0x10, + .enable = 0x4, + .ctrl = 0xc, + }, + .main_version = 0x04, + .prescaler = 1, + .supports_polarity = true, + .supports_lock = true, + .enable_conf = PWM_ENABLE_V4, +}; + +static const struct rt_ofw_node_id rockchip_pwm_ofw_ids[] = +{ + { .compatible = "rockchip,rk2928-pwm", .data = &pwm_data_v1 }, + { .compatible = "rockchip,rk3288-pwm", .data = &pwm_data_v2 }, + { .compatible = "rockchip,vop-pwm", .data = &pwm_data_vop }, + { .compatible = "rockchip,rk3328-pwm", .data = &pwm_data_v3 }, + { .compatible = "rockchip,rk3576-pwm", .data = &pwm_data_v4 }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_pwm_driver = +{ + .name = "rockchip-pwm", + .ids = rockchip_pwm_ofw_ids, + + .probe = rockchip_pwm_probe, + .remove = rockchip_pwm_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_pwm_driver); diff --git a/bsp/rockchip/dm/regulator/Kconfig b/bsp/rockchip/dm/regulator/Kconfig new file mode 100755 index 00000000000..38573ae18a3 --- /dev/null +++ b/bsp/rockchip/dm/regulator/Kconfig @@ -0,0 +1,5 @@ +config RT_REGULATOR_RK8XX + bool "Rockchip RK805/RK808/RK809/RK817/RK818 Power regulators" + depends on RT_MFD_RK8XX + depends on RT_USING_PIN + default y diff --git a/bsp/rockchip/dm/regulator/SConscript b/bsp/rockchip/dm/regulator/SConscript new file mode 100755 index 00000000000..1950e25a341 --- /dev/null +++ b/bsp/rockchip/dm/regulator/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/regulator'] + +if GetDepend(['RT_REGULATOR_RK8XX']): + src += ['regulator-rk8xx.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/regulator/regulator-rk8xx.c b/bsp/rockchip/dm/regulator/regulator-rk8xx.c new file mode 100755 index 00000000000..3a0c6250a46 --- /dev/null +++ b/bsp/rockchip/dm/regulator/regulator-rk8xx.c @@ -0,0 +1,1236 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#define DBG_TAG "regulator.rk8xx" +#define DBG_LVL DBG_INFO +#include + +#include "regulator_dm.h" +#include "rk8xx.h" + +/* Field Definitions */ +#define RK808_BUCK_VSEL_MASK 0x3f +#define RK808_BUCK4_VSEL_MASK 0xf +#define RK808_LDO_VSEL_MASK 0x1f + +#define RK809_BUCK5_VSEL_MASK 0x7 + +#define RK817_LDO_VSEL_MASK 0x7f +#define RK817_BOOST_VSEL_MASK 0x7 +#define RK817_BUCK_VSEL_MASK 0x7f + +#define RK818_BUCK_VSEL_MASK 0x3f +#define RK818_BUCK4_VSEL_MASK 0x1f +#define RK818_LDO_VSEL_MASK 0x1f +#define RK818_LDO3_ON_VSEL_MASK 0xf +#define RK818_BOOST_ON_VSEL_MASK 0xe0 + +#define RK806_DCDC_SLP_REG_OFFSET 0x0a +#define RK806_NLDO_SLP_REG_OFFSET 0x05 +#define RK806_PLDO_SLP_REG_OFFSET 0x06 + +#define RK806_BUCK_SEL_CNT 0xff +#define RK806_LDO_SEL_CNT 0xff + +/* Ramp rate definitions for buck1 / buck2 only */ +#define RK808_RAMP_RATE_OFFSET 3 +#define RK808_RAMP_RATE_MASK (3 << RK808_RAMP_RATE_OFFSET) +#define RK808_RAMP_RATE_2MV_PER_US (0 << RK808_RAMP_RATE_OFFSET) +#define RK808_RAMP_RATE_4MV_PER_US (1 << RK808_RAMP_RATE_OFFSET) +#define RK808_RAMP_RATE_6MV_PER_US (2 << RK808_RAMP_RATE_OFFSET) +#define RK808_RAMP_RATE_10MV_PER_US (3 << RK808_RAMP_RATE_OFFSET) + +#define RK808_DVS2_POL RT_BIT(2) +#define RK808_DVS1_POL RT_BIT(1) + +/* Offset from XXX_ON_VSEL to XXX_SLP_VSEL */ +#define RK808_SLP_REG_OFFSET 1 +/* Offset from XXX_ON_VSEL to XXX_DVS_VSEL */ +#define RK808_DVS_REG_OFFSET 2 +/* max steps for increase voltage of Buck1/2, equal 100mv*/ +#define MAX_STEPS_ONE_TIME 8 +#define MAX_PIN_NR 2 + +#define ENABLE_MASK(id) (RT_BIT(id) | RT_BIT(4 + (id))) +#define DISABLE_VAL(id) (RT_BIT(4 + (id))) + +struct rk8xx_regulator_range +{ + int min; + int min_sel; + int max_sel; + int step; +}; + +#define RK8XX_REGULATOR_RANGE(UVOLT_MIN, MIN_SEL, MAX_SEL, UVOLT_STEP) \ +{ \ + .min = UVOLT_MIN, \ + .min_sel = MIN_SEL, \ + .max_sel = MAX_SEL, \ + .step = UVOLT_STEP, \ +} + +struct rk8xx_regulator_desc +{ + const char *name; + const char *supply_name; + + const struct rt_regulator_ops *ops; + + int voltages_nr; + int uvolt_min; + int uvolt_step; + + int ranges_nr; + const struct rk8xx_regulator_range *ranges; + + rt_uint32_t vsel_reg; + rt_uint32_t vsel_mask; + rt_uint32_t enable_reg; + rt_uint32_t enable_mask; + rt_uint32_t enable_val; + rt_uint32_t disable_val; +}; + +#define RK8XX_REGULATOR_DESC(NAME, SUPPLY_NAME, \ + OPS, \ + VOLTAGES_NR, UVOLT_MIN, UVOLT_STEP, \ + RANGES_NR, RANGES, \ + VSEL_REG, VSEL_MASK, ENABLE_REG, \ + ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) \ +{ \ + .name = NAME, \ + .supply_name = SUPPLY_NAME, \ + .ops = &OPS, \ + .voltages_nr = VOLTAGES_NR, \ + .uvolt_min = UVOLT_MIN, \ + .uvolt_step = UVOLT_STEP, \ + .ranges_nr = RANGES_NR, \ + .ranges = RANGES, \ + .vsel_reg = VSEL_REG, \ + .vsel_mask = VSEL_MASK, \ + .enable_reg = ENABLE_REG, \ + .enable_mask = ENABLE_MASK, \ + .enable_val = ENABLE_VAL, \ + .disable_val = DISABLE_VAL, \ +} + +#define RK8XX_REGULATOR_VOLT(NAME, SUPPLY_NAME, OPS, \ + VOLTAGES_NR, UVOLT_MIN, UVOLT_STEP, \ + VSEL_REG, VSEL_MASK, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) \ + RK8XX_REGULATOR_DESC(NAME, SUPPLY_NAME, OPS, \ + VOLTAGES_NR, UVOLT_MIN, UVOLT_STEP, \ + 0, RT_NULL, \ + VSEL_REG, VSEL_MASK, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) + +#define RK8XX_REGULATOR_VOLT_RANGE(NAME, SUPPLY_NAME, OPS, \ + MIN, MAX, STEP, \ + VSEL_REG, VSEL_MASK, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) \ + RK8XX_REGULATOR_DESC(NAME, SUPPLY_NAME, OPS, \ + (((MAX) - (MIN)) / (STEP) + 1), MIN, STEP, \ + 0, RT_NULL, \ + VSEL_REG, VSEL_MASK, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) + +#define RK8XX_REGULATOR_VOLT_RANGES(NAME, SUPPLY_NAME, OPS, \ + VOLTAGES_NR, RANGES, \ + VSEL_REG, VSEL_MASK, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) \ + RK8XX_REGULATOR_DESC(NAME, SUPPLY_NAME, OPS, \ + VOLTAGES_NR, 0, 0, \ + RT_ARRAY_SIZE(RANGES), RANGES, \ + VSEL_REG, VSEL_MASK, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) + +#define RK8XX_REGULATOR_SWITCH_DESC(NAME, SUPPLY_NAME, OPS, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) \ + RK8XX_REGULATOR_DESC(NAME, SUPPLY_NAME, OPS, \ + 1, 0, 0, \ + 0, RT_NULL, \ + 0, 0, \ + ENABLE_REG, ENABLE_MASK, ENABLE_VAL, DISABLE_VAL) + +struct rk8xx_regulator +{ + struct rt_regulator_node parent; + struct rt_regulator_param param; + + rt_ubase_t pin; + + struct rt_device device; + struct rk8xx *rk8xx; + struct rt_ofw_node *ofw_node; + + const struct rk8xx_regulator_desc *desc; +}; + +#define raw_to_rk8xx_regulator(raw) rt_container_of(raw, struct rk8xx_regulator, parent) + +static int regulator_voltage_from_selector(struct rk8xx_regulator *rk8xx_reg, + int selector) +{ + int uvolt = -1; + const struct rk8xx_regulator_desc *desc = rk8xx_reg->desc; + + if (desc->ranges_nr) + { + const struct rk8xx_regulator_range *range = &desc->ranges[0]; + + for (int i = desc->ranges_nr - 1; i >= 0; --i, ++range) + { + if (range->min_sel <= selector && range->max_sel >= selector) + { + if (range->min_sel > selector || range->max_sel < selector) + { + return -RT_EINVAL; + } + + uvolt = range->min + (selector - range->min_sel) * range->step; + + break; + } + } + } + else if (desc->voltages_nr) + { + if (selector >= desc->voltages_nr) + { + return -RT_EINVAL; + } + + return desc->uvolt_min + (desc->uvolt_step * selector); + } + else + { + LOG_E("Regulator %s-%s voltages info not found", desc->name, desc->supply_name); + } + + return uvolt; +} + +static int regulator_voltage_to_selector_range(struct rk8xx_regulator *rk8xx_reg, + int min_uvolt, int max_uvolt) +{ + int selector = 0, max, uvolt, i; + const struct rk8xx_regulator_range *range; + const struct rk8xx_regulator_desc *desc = rk8xx_reg->desc; + + if (!desc->ranges) + { + return -RT_EINVAL; + } + + for (i = 0; i < desc->ranges_nr; ++i) + { + range = &desc->ranges[i]; + max = range->min + (range->max_sel - range->min_sel) * range->step; + + if (max < min_uvolt) + { + continue; + } + + if (range->min > min_uvolt) + { + selector = range->min_sel; + } + else if (range->step == 0) + { + selector = range->max_sel; + } + else + { + selector = RT_DIV_ROUND_UP(min_uvolt - range->min, range->step) + + range->min_sel; + } + + uvolt = regulator_voltage_from_selector(rk8xx_reg, selector); + + if (uvolt >= min_uvolt && uvolt <= max_uvolt) + { + break; + } + } + + if (i == desc->ranges_nr) + { + return -RT_EINVAL; + } + + return selector; +} + +static int regulator_voltage_to_selector(struct rk8xx_regulator *rk8xx_reg, + int min_uvolt, int max_uvolt) +{ + int selector, uvolt; + + /* Allow uvolt_step to be 0 for fixed voltage */ + if (rk8xx_reg->desc->voltages_nr == 1 && rk8xx_reg->desc->uvolt_step == 0) + { + if (min_uvolt <= rk8xx_reg->desc->uvolt_min && rk8xx_reg->desc->uvolt_min <= max_uvolt) + { + return 0; + } + else + { + return -RT_EINVAL; + } + } + + if (!rk8xx_reg->desc->uvolt_step) + { + return -RT_EINVAL; + } + + if (min_uvolt < rk8xx_reg->desc->uvolt_min) + { + min_uvolt = rk8xx_reg->desc->uvolt_min; + } + + selector = RT_DIV_ROUND_UP(min_uvolt - rk8xx_reg->desc->uvolt_min, rk8xx_reg->desc->uvolt_step); + + if (selector < 0) + { + return selector; + } + + /* Map back into a voltage to verify we're still in bounds */ + uvolt = regulator_voltage_from_selector(rk8xx_reg, selector); + + if (uvolt < min_uvolt || uvolt > max_uvolt) + { + return -RT_EINVAL; + } + + return selector; +} + +static rt_err_t rk8xx_regulator_enable(struct rt_regulator_node *reg_np) +{ + rt_uint32_t val; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + val = rk8xx_reg->desc->enable_val; + + if (!val) + { + val = rk8xx_reg->desc->enable_mask; + } + + return rk8xx_update_bits(rk8xx_reg->rk8xx, rk8xx_reg->desc->enable_reg, + rk8xx_reg->desc->enable_mask, val); +} + +static rt_err_t rk8xx_regulator_disable(struct rt_regulator_node *reg_np) +{ + rt_uint32_t val; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + val = rk8xx_reg->desc->disable_val; + + return rk8xx_update_bits(rk8xx_reg->rk8xx, rk8xx_reg->desc->enable_reg, + rk8xx_reg->desc->enable_mask, val); +} + +static rt_bool_t rk8xx_regulator_is_enabled(struct rt_regulator_node *reg_np) +{ + rt_uint32_t val; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + val = rk8xx_read(rk8xx_reg->rk8xx, rk8xx_reg->desc->enable_reg); + + if ((rt_err_t)val < 0) + { + return RT_FALSE; + } + + val &= rk8xx_reg->desc->enable_mask; + + if (rk8xx_reg->desc->enable_val) + { + return val == rk8xx_reg->desc->enable_val; + } + + return val != 0; +} + +static rt_err_t rk8xx_regulator_set_voltage(struct rt_regulator_node *reg_np, + int min_uvolt, int max_uvolt) +{ + int selector; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + selector = regulator_voltage_to_selector(rk8xx_reg, min_uvolt, max_uvolt); + + if (selector < 0) + { + if (selector == -RT_EINVAL) + { + selector = regulator_voltage_to_selector_range(rk8xx_reg, + min_uvolt, max_uvolt); + + if (selector < 0) + { + return -RT_EINVAL; + } + } + } + + selector <<= __rt_ffs(rk8xx_reg->desc->vsel_mask) - 1; + + return rk8xx_update_bits(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg, + rk8xx_reg->desc->vsel_mask, selector); +} + +static int rk8xx_regulator_get_voltage(struct rt_regulator_node *reg_np) +{ + int uvolt; + rt_uint32_t val; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + val = rk8xx_read(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg); + + if ((rt_err_t)val < 0) + { + return val; + } + + val &= rk8xx_reg->desc->vsel_mask; + val >>= __rt_ffs(rk8xx_reg->desc->vsel_mask) - 1; + + uvolt = regulator_voltage_from_selector(rk8xx_reg, val); + + return uvolt < 0 ? -RT_EINVAL : uvolt; +} + +/* wmsk */ +static rt_bool_t rk8xx_regulator_wmsk_is_enabled(struct rt_regulator_node *reg_np) +{ + rt_uint32_t val; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + val = rk8xx_read(rk8xx_reg->rk8xx, rk8xx_reg->desc->enable_reg); + + if ((rt_err_t)val < 0) + { + return RT_FALSE; + } + + val |= rk8xx_reg->desc->enable_mask & 0xf0; + val &= rk8xx_reg->desc->enable_mask; + + if (rk8xx_reg->desc->enable_val) + { + return val == rk8xx_reg->desc->enable_val; + } + + return val != 0; +} + +/* buck */ +static rt_err_t rk8xx_regulator_buck_set_voltage_no_pin(struct rt_regulator_node *reg_np, + int min_uvolt, int max_uvolt) +{ + rt_err_t err; + int delta_sel, selector; + rt_uint32_t old_sel, tmp, val, mask; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + selector = regulator_voltage_to_selector(rk8xx_reg, min_uvolt, max_uvolt); + + if (selector < 0) + { + if (selector == -RT_EINVAL) + { + selector = regulator_voltage_to_selector_range(rk8xx_reg, + min_uvolt, max_uvolt); + + if (selector < 0) + { + return -RT_EINVAL; + } + } + } + + val = rk8xx_read(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg); + + if ((rt_err_t)val < 0) + { + return (rt_err_t)val; + } + + mask = rk8xx_reg->desc->vsel_mask; + tmp = val & ~mask; + old_sel = val & mask; + old_sel >>= __rt_ffs(mask) - 1; + delta_sel = selector - old_sel; + + while (delta_sel > MAX_STEPS_ONE_TIME) + { + old_sel += MAX_STEPS_ONE_TIME; + val = old_sel << (__rt_ffs(mask) - 1); + val |= tmp; + + rk8xx_write(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg, val); + delta_sel = selector - old_sel; + } + + selector <<= __rt_ffs(mask) - 1; + val = tmp | selector; + err = rk8xx_write(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg, val); + + /* wait 1us to make sure the target voltage to be stable */ + rt_hw_us_delay(1); + + return err; +} + +static rt_err_t rk8xx_regulator_buck_set_voltage(struct rt_regulator_node *reg_np, + int min_uvolt, int max_uvolt) +{ + rt_err_t err; + int selector; + rt_ssize_t gpio_level; + rt_uint32_t reg, old_sel; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + if ((rt_base_t)rk8xx_reg->pin < 0) + { + return rk8xx_regulator_buck_set_voltage_no_pin(reg_np, min_uvolt, max_uvolt); + } + + selector = regulator_voltage_to_selector(rk8xx_reg, min_uvolt, max_uvolt); + + if (selector < 0) + { + if (selector == -RT_EINVAL) + { + selector = regulator_voltage_to_selector_range(rk8xx_reg, + min_uvolt, max_uvolt); + + if (selector < 0) + { + return -RT_EINVAL; + } + } + } + + reg = rk8xx_reg->desc->vsel_reg; + + gpio_level = rt_pin_read(rk8xx_reg->pin); + + if (gpio_level == 0) + { + reg += RK808_DVS_REG_OFFSET; + old_sel = rk8xx_read(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg); + } + else + { + old_sel = rk8xx_read(rk8xx_reg->rk8xx, reg + RK808_DVS_REG_OFFSET); + } + + if ((rt_err_t)old_sel < 0) + { + return -RT_EIO; + } + + selector <<= __rt_ffs(rk8xx_reg->desc->vsel_mask) - 1; + selector |= old_sel & ~rk8xx_reg->desc->vsel_mask; + + err = rk8xx_write(rk8xx_reg->rk8xx, reg, selector); + + if (err) + { + return err; + } + + rt_pin_write(rk8xx_reg->pin, !gpio_level); + + return err; +} + +static int rk8xx_regulator_buck_get_voltage(struct rt_regulator_node *reg_np) +{ + int uvolt; + rt_uint32_t val; + struct rk8xx_regulator *rk8xx_reg = raw_to_rk8xx_regulator(reg_np); + + if ((rt_base_t)rk8xx_reg->pin < 0 || rt_pin_read(rk8xx_reg->pin) == 0) + { + return rk8xx_regulator_get_voltage(reg_np); + } + + val = rk8xx_read(rk8xx_reg->rk8xx, rk8xx_reg->desc->vsel_reg + RK808_DVS_REG_OFFSET); + + if ((rt_err_t)val < 0) + { + return (int)val; + } + + val &= rk8xx_reg->desc->vsel_mask; + val >>= __rt_ffs(rk8xx_reg->desc->vsel_mask) - 1; + + uvolt = regulator_voltage_from_selector(rk8xx_reg, val); + + return uvolt < 0 ? -RT_EINVAL : uvolt; +} + +static const struct rt_regulator_ops rk8xx_regulator_ops = +{ + .enable = rk8xx_regulator_enable, + .disable = rk8xx_regulator_disable, + .is_enabled = rk8xx_regulator_is_enabled, + .set_voltage = rk8xx_regulator_set_voltage, + .get_voltage = rk8xx_regulator_get_voltage, +}; + +static const struct rt_regulator_ops rk8xx_regulator_wmsk_ops = +{ + .enable = rk8xx_regulator_enable, + .disable = rk8xx_regulator_disable, + .is_enabled = rk8xx_regulator_wmsk_is_enabled, + .set_voltage = rk8xx_regulator_set_voltage, + .get_voltage = rk8xx_regulator_get_voltage, +}; + +static const struct rt_regulator_ops rk8xx_regulator_buck_ops = +{ + .enable = rk8xx_regulator_enable, + .disable = rk8xx_regulator_disable, + .is_enabled = rk8xx_regulator_is_enabled, + .set_voltage = rk8xx_regulator_buck_set_voltage, + .get_voltage = rk8xx_regulator_buck_get_voltage, +}; + +static const struct rt_regulator_ops rk8xx_regulator_switch_ops = +{ + .enable = rk8xx_regulator_enable, + .disable = rk8xx_regulator_disable, + .is_enabled = rk8xx_regulator_is_enabled, +}; + +static const struct rt_regulator_ops rk8xx_regulator_switch_wmsk_ops = +{ + .enable = rk8xx_regulator_enable, + .disable = rk8xx_regulator_disable, + .is_enabled = rk8xx_regulator_wmsk_is_enabled, +}; + +static const struct rk8xx_regulator_range rk805_buck_1_2_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(712500, 0, 59, 12500), + RK8XX_REGULATOR_RANGE(1800000, 60, 62, 200000), + RK8XX_REGULATOR_RANGE(2300000, 63, 63, 0), +}; + +static const struct rk8xx_regulator_desc rk805_desc[] = +{ + RK8XX_REGULATOR_DESC("DCDC_REG1", "vcc1", rk8xx_regulator_ops, + 64, 0, 0, + RT_ARRAY_SIZE(rk805_buck_1_2_voltage_ranges), rk805_buck_1_2_voltage_ranges, + RK805_BUCK1_ON_VSEL_REG, RK818_BUCK_VSEL_MASK, + RK805_DCDC_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_DESC("DCDC_REG2", "vcc2", rk8xx_regulator_ops, + 64, 0, 0, + RT_ARRAY_SIZE(rk805_buck_1_2_voltage_ranges), rk805_buck_1_2_voltage_ranges, + RK805_BUCK2_ON_VSEL_REG, RK818_BUCK_VSEL_MASK, + RK805_DCDC_EN_REG, RT_BIT(1), 0, 0), + RK8XX_REGULATOR_SWITCH_DESC("DCDC_REG3", "vcc3", rk8xx_regulator_switch_ops, + RK805_DCDC_EN_REG, RT_BIT(2), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("DCDC_REG4", "vcc4", rk8xx_regulator_ops, + 800000, 3400000, 100000, + RK805_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK, + RK805_DCDC_EN_REG, RT_BIT(3), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG1", "vcc5", rk8xx_regulator_ops, + 800000, 3400000, 100000, + RK805_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK805_LDO_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG2", "vcc5", rk8xx_regulator_ops, + 800000, 3400000, 100000, + RK805_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK805_LDO_EN_REG, RT_BIT(1), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG3", "vcc6", rk8xx_regulator_ops, + 800000, 3400000, 100000, + RK805_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK805_LDO_EN_REG, RT_BIT(2), 0, 0), +}; + +static const struct rk8xx_regulator_range rk806_buck_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(500000, 0, 160, 6250), + RK8XX_REGULATOR_RANGE(1500000, 161, 237, 25000), + RK8XX_REGULATOR_RANGE(3400000, 238, 255, 0), +}; + +static const struct rk8xx_regulator_range rk806_ldo_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(500000, 0, 232, 12500), + RK8XX_REGULATOR_RANGE(3400000, 233, 255, 0), +}; + +static const struct rk8xx_regulator_desc rk806_desc[] = +{ + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG1", "vcc1", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK1_ON_VSEL, 0xff, + RK806_POWER_EN0, ENABLE_MASK(0), ENABLE_MASK(0), DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG2", "vcc2", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK2_ON_VSEL, 0xff, + RK806_POWER_EN0, ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG3", "vcc3", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK3_ON_VSEL, 0xff, + RK806_POWER_EN0, ENABLE_MASK(2), ENABLE_MASK(2), DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG4", "vcc4", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK4_ON_VSEL, 0xff, + RK806_POWER_EN0, ENABLE_MASK(3), ENABLE_MASK(3), DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG5", "vcc5", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK5_ON_VSEL, 0xff, + RK806_POWER_EN1, ENABLE_MASK(0), ENABLE_MASK(0), DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG6", "vcc6", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK6_ON_VSEL, 0xff, + RK806_POWER_EN1, ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG7", "vcc7", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK7_ON_VSEL, 0xff, + RK806_POWER_EN1, ENABLE_MASK(2), ENABLE_MASK(2), DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG8", "vcc8", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK8_ON_VSEL, 0xff, + RK806_POWER_EN1, ENABLE_MASK(3), ENABLE_MASK(3), DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG9", "vcc9", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK9_ON_VSEL, 0xff, + RK806_POWER_EN2, ENABLE_MASK(0), ENABLE_MASK(0), DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGES("DCDC_REG10", "vcc10", rk8xx_regulator_wmsk_ops, + RK806_BUCK_SEL_CNT, rk806_buck_voltage_ranges, + RK806_BUCK10_ON_VSEL, 0xff, + RK806_POWER_EN2, ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + + RK8XX_REGULATOR_VOLT_RANGES("PLDO_REG1", "vcc13", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_NLDO1_ON_VSEL, 0xff, + RK806_POWER_EN3, ENABLE_MASK(0), ENABLE_MASK(0), DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGES("PLDO_REG2", "vcc13", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_NLDO2_ON_VSEL, 0xff, + RK806_POWER_EN3, ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGES("PLDO_REG3", "vcc13", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_NLDO3_ON_VSEL, 0xff, + RK806_POWER_EN3, ENABLE_MASK(2), ENABLE_MASK(2), DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGES("PLDO_REG4", "vcc14", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_NLDO4_ON_VSEL, 0xff, + RK806_POWER_EN3, ENABLE_MASK(3), ENABLE_MASK(3), DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGES("PLDO_REG5", "vcc14", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_NLDO5_ON_VSEL, 0xff, + RK806_POWER_EN5, ENABLE_MASK(2), ENABLE_MASK(2), DISABLE_VAL(2)), + + RK8XX_REGULATOR_VOLT_RANGES("PLDO_REG6", "vcc11", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_PLDO1_ON_VSEL, 0xff, + RK806_POWER_EN4, ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGES("NLDO_REG1", "vcc11", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_PLDO2_ON_VSEL, 0xff, + RK806_POWER_EN4, ENABLE_MASK(2), ENABLE_MASK(2), DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGES("NLDO_REG2", "vcc11", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_PLDO3_ON_VSEL, 0xff, + RK806_POWER_EN4, ENABLE_MASK(3), ENABLE_MASK(3), DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGES("NLDO_REG3", "vcc12", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_PLDO4_ON_VSEL, 0xff, + RK806_POWER_EN5, ENABLE_MASK(0), ENABLE_MASK(0), DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGES("NLDO_REG4", "vcc12", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_PLDO5_ON_VSEL, 0xff, + RK806_POWER_EN5, ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + + RK8XX_REGULATOR_VOLT_RANGES("NLDO_REG5", "vcca", rk8xx_regulator_ops, + RK806_LDO_SEL_CNT, rk806_ldo_voltage_ranges, + RK806_PLDO6_ON_VSEL, 0xff, + RK806_POWER_EN4, ENABLE_MASK(0), ENABLE_MASK(0), DISABLE_VAL(0)), +}; + +static const struct rk8xx_regulator_range rk808_ldo3_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(800000, 0, 13, 100000), + RK8XX_REGULATOR_RANGE(2500000, 15, 15, 0), +}; + +static const struct rk8xx_regulator_desc rk808_desc[] = +{ + RK8XX_REGULATOR_VOLT("DCDC_REG1", "vcc1", rk8xx_regulator_buck_ops, + 64, 712500, 12500, + RK808_BUCK1_ON_VSEL_REG, RK808_BUCK_VSEL_MASK, + RK808_DCDC_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_VOLT("DCDC_REG2", "vcc2", rk8xx_regulator_buck_ops, + 64, 712500, 12500, + RK808_BUCK2_ON_VSEL_REG, RK808_BUCK_VSEL_MASK, + RK808_DCDC_EN_REG, RT_BIT(1), 0, 0), + RK8XX_REGULATOR_SWITCH_DESC("DCDC_REG3", "vcc3", rk8xx_regulator_switch_ops, + RK808_DCDC_EN_REG, RT_BIT(2), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("DCDC_REG4", "vcc4", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK808_BUCK4_ON_VSEL_REG, RK808_BUCK4_VSEL_MASK, + RK808_DCDC_EN_REG, RT_BIT(3), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG1", "vcc6", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK808_LDO1_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG2", "vcc6", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK808_LDO2_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(1), 0, 0), + RK8XX_REGULATOR_DESC("LDO_REG3", "vcc7", rk8xx_regulator_ops, + 16, 0, 0, + RT_ARRAY_SIZE(rk808_ldo3_voltage_ranges), rk808_ldo3_voltage_ranges, + RK808_LDO3_ON_VSEL_REG, RK808_BUCK4_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(2), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG4", "vcc9", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK808_LDO4_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(3), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG5", "vcc9", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK808_LDO5_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(4), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG6", "vcc10", rk8xx_regulator_ops, + 800000, 2500000, 100000, + RK808_LDO6_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(5), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG7", "vcc7", rk8xx_regulator_ops, + 800000, 2500000, 100000, + RK808_LDO7_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(6), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG8", "vcc11", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK808_LDO8_ON_VSEL_REG, RK808_LDO_VSEL_MASK, + RK808_LDO_EN_REG, RT_BIT(7), 0, 0), + + RK8XX_REGULATOR_SWITCH_DESC("SWITCH_REG1", "vcc8", rk8xx_regulator_switch_ops, + RK808_DCDC_EN_REG, RT_BIT(5), 0, 0), + RK8XX_REGULATOR_SWITCH_DESC("SWITCH_REG2", "vcc12", rk8xx_regulator_switch_ops, + RK808_DCDC_EN_REG, RT_BIT(6), 0, 0), +}; + +#define RK817_BUCK1_MIN0 500000 +#define RK817_BUCK1_MAX0 1500000 + +#define RK817_BUCK1_MIN1 1600000 +#define RK817_BUCK1_MAX1 2400000 + +#define RK817_BUCK3_MAX1 3400000 + +#define RK817_BUCK1_STP0 12500 +#define RK817_BUCK1_STP1 100000 + +#define RK817_BUCK1_SEL0 ((RK817_BUCK1_MAX0 - RK817_BUCK1_MIN0) / RK817_BUCK1_STP0) +#define RK817_BUCK1_SEL1 ((RK817_BUCK1_MAX1 - RK817_BUCK1_MIN1) / RK817_BUCK1_STP1) +#define RK817_BUCK3_SEL1 ((RK817_BUCK3_MAX1 - RK817_BUCK1_MIN1) / RK817_BUCK1_STP1) + +#define RK817_BUCK1_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK1_SEL1 + 1) +#define RK817_BUCK3_SEL_CNT (RK817_BUCK1_SEL0 + RK817_BUCK3_SEL1 + 1) + +static const struct rk8xx_regulator_range rk817_buck1_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(RK817_BUCK1_MIN0, 0, RK817_BUCK1_SEL0, RK817_BUCK1_STP0), + RK8XX_REGULATOR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1, RK817_BUCK1_SEL_CNT, RK817_BUCK1_STP1), +}; + +static const struct rk8xx_regulator_range rk817_buck3_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(RK817_BUCK1_MIN0, 0, RK817_BUCK1_SEL0, RK817_BUCK1_STP0), + RK8XX_REGULATOR_RANGE(RK817_BUCK1_MIN1, RK817_BUCK1_SEL0 + 1, RK817_BUCK3_SEL_CNT, RK817_BUCK1_STP1), +}; + +#define RK809_BUCK5_SEL_CNT 8 + +static const struct rk8xx_regulator_range rk809_buck5_voltage_ranges[] = +{ + RK8XX_REGULATOR_RANGE(1500000, 0, 0, 0), + RK8XX_REGULATOR_RANGE(1800000, 1, 3, 200000), + RK8XX_REGULATOR_RANGE(2800000, 4, 5, 200000), + RK8XX_REGULATOR_RANGE(3300000, 6, 7, 300000), +}; + +static const struct rk8xx_regulator_desc rk809_desc[] = +{ + RK8XX_REGULATOR_DESC("DCDC_REG1", "vcc1", rk8xx_regulator_wmsk_ops, + RK817_BUCK1_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck1_voltage_ranges), rk817_buck1_voltage_ranges, + RK817_BUCK1_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC1), ENABLE_MASK(RK817_ID_DCDC1), DISABLE_VAL(RK817_ID_DCDC1)), + RK8XX_REGULATOR_DESC("DCDC_REG2", "vcc2", rk8xx_regulator_wmsk_ops, + RK817_BUCK1_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck1_voltage_ranges), rk817_buck1_voltage_ranges, + RK817_BUCK2_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC2), ENABLE_MASK(RK817_ID_DCDC2), DISABLE_VAL(RK817_ID_DCDC2)), + RK8XX_REGULATOR_DESC("DCDC_REG3", "vcc3", rk8xx_regulator_wmsk_ops, + RK817_BUCK1_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck1_voltage_ranges), rk817_buck1_voltage_ranges, + RK817_BUCK3_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC3), ENABLE_MASK(RK817_ID_DCDC3), DISABLE_VAL(RK817_ID_DCDC3)), + RK8XX_REGULATOR_DESC("DCDC_REG4", "vcc4", rk8xx_regulator_wmsk_ops, + RK817_BUCK3_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck3_voltage_ranges), rk817_buck3_voltage_ranges, + RK817_BUCK4_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC4), ENABLE_MASK(RK817_ID_DCDC4), DISABLE_VAL(RK817_ID_DCDC4)), + + RK8XX_REGULATOR_DESC("DCDC_REG5", "vcc9", rk8xx_regulator_wmsk_ops, + RK809_BUCK5_SEL_CNT, 0, 0, + RT_ARRAY_SIZE(rk809_buck5_voltage_ranges), rk809_buck5_voltage_ranges, + RK809_BUCK5_CONFIG(0), RK809_BUCK5_VSEL_MASK, + RK817_POWER_EN_REG(3), ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG1", "vcc5", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(0), 0, DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG2", "vcc5", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(1), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(1), 0, DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG3", "vcc5", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(2), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(2), 0, DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG4", "vcc6", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(3), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(3), 0, DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG5", "vcc6", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(4), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(0), 0, DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG6", "vcc6", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(5), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(1), 0, DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG7", "vcc7", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(6), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(2), 0, DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG8", "vcc7", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(7), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(3), 0, DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG9", "vcc7", rk8xx_regulator_wmsk_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(3), ENABLE_MASK(0), 0, DISABLE_VAL(0)), + + RK8XX_REGULATOR_SWITCH_DESC("SWITCH_REG1", "vcc9", rk8xx_regulator_switch_wmsk_ops, + RK817_POWER_EN_REG(3), ENABLE_MASK(2), 0, DISABLE_VAL(2)), + RK8XX_REGULATOR_SWITCH_DESC("SWITCH_REG2", "vcc8", rk8xx_regulator_switch_wmsk_ops, + RK817_POWER_EN_REG(3), ENABLE_MASK(3), 0, DISABLE_VAL(3)), +}; + +static const struct rk8xx_regulator_desc rk817_desc[] = +{ + RK8XX_REGULATOR_DESC("DCDC_REG1", "vcc1", rk8xx_regulator_wmsk_ops, + RK817_BUCK1_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck1_voltage_ranges), rk817_buck1_voltage_ranges, + RK817_BUCK1_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC1), ENABLE_MASK(RK817_ID_DCDC1), DISABLE_VAL(RK817_ID_DCDC1)), + RK8XX_REGULATOR_DESC("DCDC_REG2", "vcc2", rk8xx_regulator_wmsk_ops, + RK817_BUCK1_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck1_voltage_ranges), rk817_buck1_voltage_ranges, + RK817_BUCK2_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC2), ENABLE_MASK(RK817_ID_DCDC2), DISABLE_VAL(RK817_ID_DCDC2)), + RK8XX_REGULATOR_DESC("DCDC_REG3", "vcc3", rk8xx_regulator_wmsk_ops, + RK817_BUCK1_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck1_voltage_ranges), rk817_buck1_voltage_ranges, + RK817_BUCK3_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC3), ENABLE_MASK(RK817_ID_DCDC3), DISABLE_VAL(RK817_ID_DCDC3)), + RK8XX_REGULATOR_DESC("DCDC_REG4", "vcc4", rk8xx_regulator_wmsk_ops, + RK817_BUCK3_SEL_CNT + 1, 0, 0, + RT_ARRAY_SIZE(rk817_buck3_voltage_ranges), rk817_buck3_voltage_ranges, + RK817_BUCK4_ON_VSEL_REG, RK817_BUCK_VSEL_MASK, + RK817_POWER_EN_REG(0), ENABLE_MASK(RK817_ID_DCDC4), ENABLE_MASK(RK817_ID_DCDC4), DISABLE_VAL(RK817_ID_DCDC4)), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG1", "vcc5", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(0), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(0), 0, DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG2", "vcc5", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(1), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(1), 0, DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG3", "vcc5", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(2), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(2), 0, DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG4", "vcc6", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(3), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(1), ENABLE_MASK(3), 0, DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG5", "vcc6", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(4), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(0), 0, DISABLE_VAL(0)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG6", "vcc6", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(5), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(1), 0, DISABLE_VAL(1)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG7", "vcc7", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(6), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(2), 0, DISABLE_VAL(2)), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG8", "vcc7", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(7), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(2), ENABLE_MASK(3), 0, DISABLE_VAL(3)), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG9", "vcc7", rk8xx_regulator_ops, + 600000, 3400000, 25000, + RK817_LDO_ON_VSEL_REG(8), RK817_LDO_VSEL_MASK, + RK817_POWER_EN_REG(3), ENABLE_MASK(0), 0, DISABLE_VAL(0)), + + RK8XX_REGULATOR_VOLT_RANGE("BOOST", "vcc8", rk8xx_regulator_wmsk_ops, + 4700000, 5400000, 100000, + RK817_BOOST_OTG_CFG, RK817_BOOST_VSEL_MASK, + RK817_POWER_EN_REG(3), ENABLE_MASK(1), ENABLE_MASK(1), DISABLE_VAL(1)), + RK8XX_REGULATOR_SWITCH_DESC("OTG_SWITCH", "vcc9", rk8xx_regulator_switch_wmsk_ops, + RK817_POWER_EN_REG(3), ENABLE_MASK(2), 0, DISABLE_VAL(2)), +}; + +static const struct rk8xx_regulator_desc rk818_desc[] = +{ + RK8XX_REGULATOR_VOLT("DCDC_REG1", "vcc1", rk8xx_regulator_ops, + 64, 712500, 12500, + RK818_BUCK1_ON_VSEL_REG, RK818_BUCK_VSEL_MASK, + RK818_DCDC_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_VOLT("DCDC_REG2", "vcc2", rk8xx_regulator_ops, + 64, 712500, 12500, + RK818_BUCK2_ON_VSEL_REG, RK818_BUCK_VSEL_MASK, + RK818_DCDC_EN_REG, RT_BIT(1), 0, 0), + RK8XX_REGULATOR_SWITCH_DESC("DCDC_REG3", "vcc3", rk8xx_regulator_switch_ops, + RK818_DCDC_EN_REG, RT_BIT(2), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("DCDC_REG4", "vcc4", rk8xx_regulator_ops, + 1800000, 3600000, 100000, + RK818_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK, + RK818_DCDC_EN_REG, RT_BIT(3), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("DCDC_BOOST", "boost", rk8xx_regulator_ops, + 4700000, 5400000, 100000, + RK818_BOOST_LDO9_ON_VSEL_REG, RK818_BOOST_ON_VSEL_MASK, + RK818_DCDC_EN_REG, RT_BIT(4), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG1", "vcc6", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK818_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG2", "vcc6", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK818_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(1), 0, 0), + RK8XX_REGULATOR_DESC("LDO_REG3", "vcc7", rk8xx_regulator_ops, + 16, 0, 0, + RT_ARRAY_SIZE(rk808_ldo3_voltage_ranges), rk808_ldo3_voltage_ranges, + RK818_LDO3_ON_VSEL_REG, RK818_LDO3_ON_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(2), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG4", "vcc8", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK818_LDO4_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(3), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG5", "vcc7", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK818_LDO5_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(4), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG6", "vcc8", rk8xx_regulator_ops, + 800000, 2500000, 100000, + RK818_LDO6_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(5), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG7", "vcc7", rk8xx_regulator_ops, + 800000, 2500000, 100000, + RK818_LDO7_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(6), 0, 0), + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG8", "vcc8", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK818_LDO8_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_LDO_EN_REG, RT_BIT(7), 0, 0), + + RK8XX_REGULATOR_VOLT_RANGE("LDO_REG9", "vcc9", rk8xx_regulator_ops, + 1800000, 3400000, 100000, + RK818_BOOST_LDO9_ON_VSEL_REG, RK818_LDO_VSEL_MASK, + RK818_DCDC_EN_REG, RT_BIT(5), 0, 0), + + RK8XX_REGULATOR_SWITCH_DESC("SWITCH_REG", "vcc9", rk8xx_regulator_switch_ops, + RK818_DCDC_EN_REG, RT_BIT(6), 0, 0), + RK8XX_REGULATOR_SWITCH_DESC("HDMI_SWITCH", "h_5v", rk8xx_regulator_switch_ops, + RK818_H5V_EN_REG, RT_BIT(0), 0, 0), + RK8XX_REGULATOR_SWITCH_DESC("OTG_SWITCH", "usb", rk8xx_regulator_switch_ops, + RK818_DCDC_EN_REG, RT_BIT(7), 0, 0), +}; + +static rt_err_t append_rk8xx_regulator(struct rk8xx *rk8xx, struct rt_ofw_node *np, + const struct rk8xx_regulator_desc *desc_table, int id) +{ + rt_err_t err = RT_EOK; + struct rt_regulator_node *rgp; + struct rk8xx_regulator *rk8xx_reg; + + rk8xx_reg = rt_calloc(1, sizeof(*rk8xx_reg)); + + if (!rk8xx_reg) + { + return -RT_ENOMEM; + } + + rk8xx_reg->rk8xx = rk8xx; + rk8xx_reg->desc = &desc_table[id]; + + regulator_ofw_parse(np, &rk8xx_reg->param); + + rgp = &rk8xx_reg->parent; + rgp->ops = rk8xx_reg->desc->ops; + rgp->param = &rk8xx_reg->param; + rgp->dev = &rk8xx_reg->device; + + rgp->dev->ofw_node = np; + + if (id < MAX_PIN_NR) + { + rt_uint32_t tmp; + rt_uint8_t mode, value; + + rk8xx_reg->pin = rt_ofw_get_named_pin(rk8xx->dev->ofw_node, + "dvs", id, &mode, &value); + + if ((rt_base_t)rk8xx_reg->pin >= 0) + { + rt_pin_mode(rk8xx_reg->pin, mode); + rt_pin_write(rk8xx_reg->pin, value); + + tmp = id ? RK808_DVS2_POL : RK808_DVS1_POL; + rk8xx_update_bits(rk8xx, RK808_IO_POL_REG, tmp, + rt_pin_read(rk8xx_reg->pin) == PIN_LOW ? 0 : tmp); + } + } + + if ((err = rt_regulator_register(rgp))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rt_free(rk8xx_reg); + + return err; +} + +static rt_err_t rk8xx_regulator_probe(struct rt_platform_device *pdev) +{ + int desc_nr; + rt_err_t err; + struct rk8xx *rk8xx = pdev->priv; + struct rt_ofw_node *np, *regulators_np = pdev->parent.ofw_node; + const struct rk8xx_regulator_desc *desc_table; + + switch (rk8xx->variant) + { + case RK805_ID: + desc_table = rk805_desc; + desc_nr = RT_ARRAY_SIZE(rk805_desc); + break; + + case RK806_ID: + desc_table = rk806_desc; + desc_nr = RT_ARRAY_SIZE(rk806_desc); + break; + + case RK808_ID: + desc_table = rk808_desc; + desc_nr = RT_ARRAY_SIZE(rk808_desc); + break; + + case RK809_ID: + desc_table = rk809_desc; + desc_nr = RT_ARRAY_SIZE(rk809_desc); + break; + + case RK817_ID: + desc_table = rk817_desc; + desc_nr = RT_ARRAY_SIZE(rk817_desc); + break; + + case RK818_ID: + desc_table = rk818_desc; + desc_nr = RT_ARRAY_SIZE(rk818_desc); + break; + + default: + return -RT_ENOSYS; + } + + for (int i = 0; i < desc_nr; ++i) + { + const char *name = desc_table[i].name; + + if (!(np = rt_ofw_get_child_by_tag(regulators_np, name))) + { + continue; + } + + rt_ofw_node_put(np); + + if ((err = append_rk8xx_regulator(rk8xx, np, desc_table, i))) + { + LOG_E("Append RK8XX regulator %s fail error = %s", + rt_ofw_node_full_name(np), rt_strerror(err)); + + if (err == -RT_ENOMEM) + { + return err; + } + } + } + + return RT_EOK; +} + +static struct rt_platform_driver rk8xx_regulator_driver = +{ + .name = "rk8xx-regulator", + .probe = rk8xx_regulator_probe, +}; + +static int rk8xx_regulator_register(void) +{ + rt_platform_driver_register(&rk8xx_regulator_driver); + + return 0; +} +INIT_SUBSYS_EXPORT(rk8xx_regulator_register); diff --git a/bsp/rockchip/dm/rtc/Kconfig b/bsp/rockchip/dm/rtc/Kconfig new file mode 100755 index 00000000000..b3d3a218890 --- /dev/null +++ b/bsp/rockchip/dm/rtc/Kconfig @@ -0,0 +1,7 @@ +config RT_RTC_RK8XX + bool "Rockchip RK805/RK808/RK809/RK817/RK818 RTC" + depends on RT_MFD_RK8XX + +config RT_RTC_RK_TIMER + bool "Rockchip RTC" + default n diff --git a/bsp/rockchip/dm/rtc/SConscript b/bsp/rockchip/dm/rtc/SConscript new file mode 100755 index 00000000000..d6bf3de97eb --- /dev/null +++ b/bsp/rockchip/dm/rtc/SConscript @@ -0,0 +1,16 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/rtc'] + +if GetDepend(['RT_RTC_RK8XX']): + src += ['rtc-rk8xx.c'] + +if GetDepend(['RT_RTC_RK_TIMER']): + src += ['rtc-rk_timer.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/rtc/rtc-rk8xx.c b/bsp/rockchip/dm/rtc/rtc-rk8xx.c new file mode 100755 index 00000000000..b20e87adaff --- /dev/null +++ b/bsp/rockchip/dm/rtc/rtc-rk8xx.c @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "rtc.rk8xx" +#define DBG_LVL DBG_INFO +#include + +#include "rtc_dm.h" +#include "rk8xx.h" + +#define BIT_RTC_CTRL_REG_STOP_RTC_M RT_BIT(0) +#define BIT_RTC_CTRL_REG_RTC_GET_TIME RT_BIT(6) +#define BIT_RTC_CTRL_REG_RTC_READSEL_M RT_BIT(7) +#define BIT_RTC_INTERRUPTS_REG_IT_ALARM_M RT_BIT(3) + +#define RTC_STATUS_MASK 0xfe +#define SECONDS_REG_MSK 0x7f +#define MINUTES_REG_MAK 0x7f +#define HOURS_REG_MSK 0x3f +#define DAYS_REG_MSK 0x3f +#define MONTHS_REG_MSK 0x1f +#define YEARS_REG_MSK 0xff +#define WEEKS_REG_MSK 0x7 + +#define NUM_TIME_REGS (RK808_WEEKS_REG - RK808_SECONDS_REG + 1) +#define NUM_ALARM_REGS (RK808_ALARM_YEARS_REG - RK808_ALARM_SECONDS_REG + 1) + +struct rk_rtc_compat_reg +{ + rt_uint32_t ctrl_reg; + rt_uint32_t status_reg; + rt_uint32_t alarm_seconds_reg; + rt_uint32_t int_reg; + rt_uint32_t seconds_reg; +}; + +struct rk8xx_rtc +{ + struct rt_device parent; + + int irq; + struct rk8xx *rk8xx; + struct rk_rtc_compat_reg *creg; +}; + +#define raw_to_rk8xx_rtc(raw) rt_container_of(raw, struct rk8xx_rtc, parent) + +static rt_err_t rk8xx_rtc_read_time(struct rk8xx_rtc *rk8xx_rtc, time_t *sec) +{ + rt_err_t err; + struct tm tm; + struct rk8xx *rk8xx; + rt_uint32_t ctrl_reg, seconds_reg; + rt_uint8_t rtc_data[NUM_TIME_REGS]; + + rk8xx = rk8xx_rtc->rk8xx; + ctrl_reg = rk8xx_rtc->creg->ctrl_reg; + seconds_reg = rk8xx_rtc->creg->seconds_reg; + + err = rk8xx_update_bits(rk8xx, ctrl_reg, BIT_RTC_CTRL_REG_RTC_GET_TIME, + BIT_RTC_CTRL_REG_RTC_GET_TIME); + + if (err) + { + LOG_E("Update RTC control error = %s", rt_strerror(err)); + + return err; + } + + err = rk8xx_update_bits(rk8xx, ctrl_reg, BIT_RTC_CTRL_REG_RTC_GET_TIME, 0); + + if (err) + { + LOG_E("Update RTC control error = %s", rt_strerror(err)); + + return err; + } + + for (int i = 0; i < RT_ARRAY_SIZE(rtc_data); ++i) + { + rtc_data[i] = rk8xx_read(rk8xx, seconds_reg + i * sizeof(rt_uint8_t)); + } + + tm.tm_sec = rt_bcd2bin(rtc_data[0] & SECONDS_REG_MSK); + tm.tm_min = rt_bcd2bin(rtc_data[1] & MINUTES_REG_MAK); + tm.tm_hour = rt_bcd2bin(rtc_data[2] & HOURS_REG_MSK); + tm.tm_mday = rt_bcd2bin(rtc_data[3] & DAYS_REG_MSK); + tm.tm_mon = (rt_bcd2bin(rtc_data[4] & MONTHS_REG_MSK)) - 1; + tm.tm_year = (rt_bcd2bin(rtc_data[5] & YEARS_REG_MSK)) + 100; + tm.tm_wday = rt_bcd2bin(rtc_data[6] & WEEKS_REG_MSK); + + *sec = mktime(&tm); + + return RT_EOK; +} + +static rt_err_t rk8xx_rtc_set_time(struct rk8xx_rtc *rk8xx_rtc, time_t *sec) +{ + rt_err_t err; + struct tm *tm; + struct rk8xx *rk8xx; + rt_uint32_t ctrl_reg, seconds_reg; + rt_uint8_t rtc_data[NUM_TIME_REGS]; + + rk8xx = rk8xx_rtc->rk8xx; + ctrl_reg = rk8xx_rtc->creg->ctrl_reg; + seconds_reg = rk8xx_rtc->creg->seconds_reg; + + tm = localtime(sec); + rtc_data[0] = rt_bin2bcd(tm->tm_sec); + rtc_data[1] = rt_bin2bcd(tm->tm_min); + rtc_data[2] = rt_bin2bcd(tm->tm_hour); + rtc_data[3] = rt_bin2bcd(tm->tm_mday); + rtc_data[4] = rt_bin2bcd(tm->tm_mon + 1); + rtc_data[5] = rt_bin2bcd(tm->tm_year - 100); + rtc_data[6] = rt_bin2bcd(tm->tm_wday); + + err = rk8xx_update_bits(rk8xx, ctrl_reg, BIT_RTC_CTRL_REG_STOP_RTC_M, + BIT_RTC_CTRL_REG_STOP_RTC_M); + + if (err) + { + LOG_E("Update RTC control error = %s", rt_strerror(err)); + + return err; + } + + for (int i = 0; i < RT_ARRAY_SIZE(rtc_data); ++i) + { + err = rk8xx_write(rk8xx, seconds_reg + i * sizeof(rt_uint8_t), rtc_data[i]); + + if (err) + { + LOG_E("Update RTC time[%d] error = %s", i, rt_strerror(err)); + + return err; + } + } + + err = rk8xx_update_bits(rk8xx, ctrl_reg, BIT_RTC_CTRL_REG_STOP_RTC_M, 0); + + if (err) + { + LOG_E("Update RTC control error = %s", rt_strerror(err)); + + return err; + } + + return RT_EOK; +} + +static void rk8xx_rtc_read_alarm(struct rk8xx_rtc *rk8xx_rtc, + struct rt_rtc_wkalarm *alarm) +{ + struct rk8xx *rk8xx; + rt_uint8_t alrm_data[NUM_ALARM_REGS]; + rt_uint32_t int_reg, alarm_seconds_reg; + + rk8xx = rk8xx_rtc->rk8xx; + int_reg = rk8xx_rtc->creg->int_reg; + alarm_seconds_reg = rk8xx_rtc->creg->alarm_seconds_reg; + + for (int i = 0; i < 3; ++i) + { + alrm_data[i] = rk8xx_read(rk8xx, alarm_seconds_reg + i * sizeof(rt_uint8_t)); + } + + alarm->tm_sec = rt_bcd2bin(alrm_data[0] & SECONDS_REG_MSK); + alarm->tm_min = rt_bcd2bin(alrm_data[1] & MINUTES_REG_MAK); + alarm->tm_hour = rt_bcd2bin(alrm_data[2] & HOURS_REG_MSK); + + alarm->enable = !!(rk8xx_read(rk8xx, int_reg) & BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); +} + +static rt_err_t rk8xx_rtc_set_alarm(struct rk8xx_rtc *rk8xx_rtc, + struct rt_rtc_wkalarm *alarm) +{ + rt_err_t err; + struct rk8xx *rk8xx; + rt_uint32_t int_reg, alarm_seconds_reg; + rt_uint8_t alrm_data[NUM_ALARM_REGS]; + + rk8xx = rk8xx_rtc->rk8xx; + int_reg = rk8xx_rtc->creg->int_reg; + alarm_seconds_reg = rk8xx_rtc->creg->alarm_seconds_reg; + + err = rk8xx_update_bits(rk8xx, int_reg, BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, 0); + + if (err) + { + LOG_E("%s RTC alarm error = %s", "Stop", rt_strerror(err)); + + return err; + } + + alrm_data[0] = rt_bin2bcd(alarm->tm_sec); + alrm_data[1] = rt_bin2bcd(alarm->tm_min); + alrm_data[2] = rt_bin2bcd(alarm->tm_hour); + + for (int i = 0; i < RT_ARRAY_SIZE(alrm_data); ++i) + { + err = rk8xx_write(rk8xx, alarm_seconds_reg + i * sizeof(rt_uint8_t), + alrm_data[i]); + + if (err) + { + LOG_E("Update RTC alarm time[%d] error = %s", i, rt_strerror(err)); + + return err; + } + } + + if (alarm->enable) + { + err = rk8xx_update_bits(rk8xx, int_reg, + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M, + BIT_RTC_INTERRUPTS_REG_IT_ALARM_M); + + if (err) + { + LOG_E("%s RTC alarm error = %s", "Start", rt_strerror(err)); + + return err; + } + } + + return RT_EOK; +} + +static rt_err_t rk8xx_rtc_control(rt_device_t dev, int cmd, void *args) +{ + rt_err_t err = RT_EOK; + struct rk8xx_rtc *rk8xx_rtc = raw_to_rk8xx_rtc(dev); + + if (!args) + { + return -RT_EINVAL; + } + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + err = rk8xx_rtc_read_time(rk8xx_rtc, args); + break; + + case RT_DEVICE_CTRL_RTC_SET_TIME: + err = rk8xx_rtc_set_time(rk8xx_rtc, args); + break; + + case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: + err = rk8xx_rtc_read_time(rk8xx_rtc, (time_t *)&((struct timeval *)args)->tv_sec); + break; + + case RT_DEVICE_CTRL_RTC_SET_TIMEVAL: + err = rk8xx_rtc_set_time(rk8xx_rtc, (time_t *)&((struct timeval *)args)->tv_sec); + break; + + case RT_DEVICE_CTRL_RTC_GET_ALARM: + rk8xx_rtc_read_alarm(rk8xx_rtc, args); + break; + + case RT_DEVICE_CTRL_RTC_SET_ALARM: + rk8xx_rtc_set_alarm(rk8xx_rtc, args); + break; + + default: + err = -RT_EINVAL; + break; + } + + return err; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rk8xx_rtc_ops = +{ + .control = rk8xx_rtc_control, +}; +#endif + +static void rk8xx_rtc_isr(int irqno, void *param) +{ + rt_err_t err; + struct rk8xx_rtc *rk8xx_rtc = param; + + err = rk8xx_write(rk8xx_rtc->rk8xx, rk8xx_rtc->creg->status_reg, + RTC_STATUS_MASK); + + if (err) + { + LOG_E("Update RTC status error = %s", rt_strerror(err)); + return; + } + + rt_alarm_update(&rk8xx_rtc->parent, 1); +} + +static struct rk_rtc_compat_reg rk808_creg = +{ + .ctrl_reg = RK808_RTC_CTRL_REG, + .status_reg = RK808_RTC_STATUS_REG, + .alarm_seconds_reg = RK808_ALARM_SECONDS_REG, + .int_reg = RK808_RTC_INT_REG, + .seconds_reg = RK808_SECONDS_REG, +}; + +static struct rk_rtc_compat_reg rk817_creg = +{ + .ctrl_reg = RK817_RTC_CTRL_REG, + .status_reg = RK817_RTC_STATUS_REG, + .alarm_seconds_reg = RK817_ALARM_SECONDS_REG, + .int_reg = RK817_RTC_INT_REG, + .seconds_reg = RK817_SECONDS_REG, +}; + +static rt_err_t rk8xx_rtc_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + const char *dev_name; + struct rk8xx *rk8xx = pdev->priv; + struct rt_device *dev = &pdev->parent; + struct rk8xx_rtc *rk8xx_rtc = rt_calloc(1, sizeof(*rk8xx_rtc)); + + if (!rk8xx_rtc) + { + return -RT_ENOMEM; + } + + rk8xx_rtc->rk8xx = rk8xx; + + switch (rk8xx->variant) + { + case RK809_ID: + case RK817_ID: + rk8xx_rtc->creg = &rk817_creg; + break; + + default: + rk8xx_rtc->creg = &rk808_creg; + break; + } + + err = rk8xx_update_bits(rk8xx, rk8xx_rtc->creg->ctrl_reg, + BIT_RTC_CTRL_REG_STOP_RTC_M | + BIT_RTC_CTRL_REG_RTC_READSEL_M, + BIT_RTC_CTRL_REG_RTC_READSEL_M); + + if (err) + { + LOG_E("Update RTC control error = %s", rt_strerror(err)); + goto _fail; + } + + err = rk8xx_write(rk8xx, rk8xx_rtc->creg->status_reg, RTC_STATUS_MASK); + + if (err) + { + LOG_E("Write RTC status error = %s", rt_strerror(err)); + goto _fail; + } + + rk8xx_rtc->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk8xx_rtc->irq < 0) + { + err = rk8xx_rtc->irq; + goto _fail; + } + + dev->user_data = rk8xx_rtc; + + rk8xx_rtc->parent.type = RT_Device_Class_RTC; +#ifdef RT_USING_DEVICE_OPS + rk8xx_rtc->parent.ops = &rk8xx_rtc_ops; +#else + rk8xx_rtc->parent.control = rk8xx_rtc_control; +#endif + + rtc_dev_set_name(&rk8xx_rtc->parent); + dev_name = rt_dm_dev_get_name(&rk8xx_rtc->parent); + rt_device_register(&rk8xx_rtc->parent, dev_name, RT_DEVICE_FLAG_RDWR); + + rt_hw_interrupt_install(rk8xx_rtc->irq, rk8xx_rtc_isr, rk8xx_rtc, "rtc-rk8xx"); + rt_hw_interrupt_umask(rk8xx_rtc->irq); + + return RT_EOK; + +_fail: + rt_free(rk8xx_rtc); + + return err; +} + +static rt_err_t rk8xx_rtc_remove(struct rt_platform_device *pdev) +{ + struct rk8xx_rtc *rk8xx_rtc = pdev->parent.user_data; + + rt_hw_interrupt_mask(rk8xx_rtc->irq); + rt_pic_detach_irq(rk8xx_rtc->irq, rk8xx_rtc); + + rt_device_unregister(&rk8xx_rtc->parent); + + rt_free(rk8xx_rtc); + + return RT_EOK; +} + +static struct rt_platform_driver rk8xx_rtc_driver = +{ + .name = "rk8xx-rtc", + .probe = rk8xx_rtc_probe, + .remove = rk8xx_rtc_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rk8xx_rtc_driver); diff --git a/bsp/rockchip/dm/rtc/rtc-rk_timer.c b/bsp/rockchip/dm/rtc/rtc-rk_timer.c new file mode 100755 index 00000000000..87fa49c6a22 --- /dev/null +++ b/bsp/rockchip/dm/rtc/rtc-rk_timer.c @@ -0,0 +1,397 @@ +/* + * 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 + */ + +#include "rtc_dm.h" + +#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_INT_STATUS 0x18 + +#define TIMER_ENABLE RT_BIT(0) +#define TIMER_MODE_USER_DEFINED_COUNT RT_BIT(1) +#define TIMER_INT_UNMASK RT_BIT(2) + +/* Forbid any alarms which would trigger inside the threshold */ +#define TIMER_ALARM_THRESHOLD_MS 10 +#define TIMER_COUNT_MAX ((rt_uint64_t)-1) + +struct rk_timer_rtc_data +{ + int ctrl_reg_offset; +}; + +struct rk_timer_rtc +{ + struct rt_device parent; + + int irq; + void *base; + + struct rt_clk *clk; + struct rt_clk *pclk; + + rt_uint32_t freq; + rt_uint64_t timebase; + rt_bool_t alarm_irq_enabled; + struct rt_rtc_wkalarm wkalarm; + + const struct rk_timer_rtc_data *soc_data; +}; + +#define raw_to_rk_timer_rtc(raw) rt_container_of(raw, struct rk_timer_rtc, parent) + +rt_inline rt_uint64_t tick_to_sec(struct rk_timer_rtc *rk_rtc, rt_uint64_t tick) +{ + rt_do_div(tick, rk_rtc->freq); + + return tick; +} + +rt_inline rt_uint64_t ms_to_tick(struct rk_timer_rtc *rk_rtc, int ms) +{ + return ms * rk_rtc->freq / 1000; +} + +rt_inline rt_uint64_t tick_to_time64(struct rk_timer_rtc *rk_rtc, rt_uint64_t tick) +{ + return tick_to_sec(rk_rtc, tick) + rk_rtc->timebase; +} + +rt_inline rt_uint64_t time64_to_tick(struct rk_timer_rtc *rk_rtc, rt_uint64_t time) +{ + return (time - rk_rtc->timebase) * rk_rtc->freq; +} + +rt_inline void rk_timer_rtc_writel(struct rk_timer_rtc *rk_rtc, int offset, rt_uint32_t value) +{ + HWREG32(rk_rtc->base + offset) = value; +} + +rt_inline rt_uint32_t rk_timer_rtc_readl(struct rk_timer_rtc *rk_rtc, int offset) +{ + return HWREG32(rk_rtc->base + offset); +} + +rt_inline void rk_timer_rtc_writeq(struct rk_timer_rtc *rk_rtc, int offset, rt_uint64_t value) +{ + HWREG32(rk_rtc->base + offset) = value; + HWREG32(rk_rtc->base + offset + 4) = value >> 32; +} + +rt_inline rt_uint64_t rk_timer_rtc_readq(struct rk_timer_rtc *rk_rtc, int offset) +{ + rt_uint32_t val_lo, val_hi, tmp_hi; + + do { + val_hi = HWREG32(rk_rtc->base + offset + 4); + val_lo = HWREG32(rk_rtc->base + offset); + tmp_hi = HWREG32(rk_rtc->base + offset + 4); + } while (val_hi != tmp_hi); + + return ((rt_uint64_t) val_hi << 32) | val_lo; +} + +rt_inline void rk_timer_rtc_irq_clear(struct rk_timer_rtc *rk_rtc) +{ + return rk_timer_rtc_writel(rk_rtc->base, TIMER_INT_STATUS, 1); +} + +rt_inline void rk_timer_rtc_irq_enable(struct rk_timer_rtc *rk_rtc, rt_bool_t enabled) +{ + rt_uint32_t old_val; + + /* Clear any pending irq before enable it */ + if (enabled) + { + rk_timer_rtc_irq_clear(rk_rtc); + } + + old_val = rk_timer_rtc_readl(rk_rtc, rk_rtc->soc_data->ctrl_reg_offset); + old_val &= ~TIMER_INT_UNMASK; + rk_timer_rtc_writel(rk_rtc, rk_rtc->soc_data->ctrl_reg_offset, + old_val | (enabled ? TIMER_INT_UNMASK : 0)); +} + +static void rk_timer_rtc_reset(struct rk_timer_rtc *rk_rtc) +{ + rk_timer_rtc_writel(rk_rtc, rk_rtc->soc_data->ctrl_reg_offset, 0); + + /* Init load count to UINT64_MAX to keep timer running */ + rk_timer_rtc_writeq(rk_rtc, TIMER_LOAD_COUNT0, TIMER_COUNT_MAX); + + /* Clear any pending irq before enable it */ + rk_timer_rtc_irq_clear(rk_rtc); + + /* Enable timer in user-defined count mode with irq unmasked */ + rk_timer_rtc_writel(rk_rtc, rk_rtc->soc_data->ctrl_reg_offset, + TIMER_ENABLE | TIMER_MODE_USER_DEFINED_COUNT | TIMER_INT_UNMASK); +} + +static void rk_timer_rtc_read_time(struct rk_timer_rtc *rk_rtc, time_t *sec) +{ + rt_uint64_t tick; + + tick = rk_timer_rtc_readq(rk_rtc, TIMER_CURRENT_VALUE0); + + *sec = (time_t)tick_to_time64(rk_rtc, tick); +} + +static void rk_timer_rtc_set_time(struct rk_timer_rtc *rk_rtc, time_t *sec) +{ + rk_rtc->timebase = (rt_uint64_t)*sec; + + rk_timer_rtc_reset(rk_rtc); +} + +static void rk_timer_rtc_read_alarm(struct rk_timer_rtc *rk_rtc, + struct rt_rtc_wkalarm *alarm) +{ + *alarm = rk_rtc->wkalarm; + + alarm->enable = rk_rtc->alarm_irq_enabled; +} + +static rt_err_t rk_timer_rtc_set_alarm(struct rk_timer_rtc *rk_rtc, + struct rt_rtc_wkalarm *alarm) +{ + rt_uint64_t alarm_tick, alarm_threshold_tick, cur_tick, time; + + rk_rtc->alarm_irq_enabled = alarm->enable; + + time = alarm->tm_hour * 3600 + alarm->tm_min * 60 + alarm->tm_sec; + alarm_tick = time64_to_tick(rk_rtc, time); + cur_tick = rk_timer_rtc_readq(rk_rtc, TIMER_CURRENT_VALUE0); + + /* Don't set an alarm in the past or about to pass */ + alarm_threshold_tick = ms_to_tick(rk_rtc, TIMER_ALARM_THRESHOLD_MS); + + if (alarm_tick <= (cur_tick + alarm_threshold_tick)) + { + return -RT_ERROR; + } + + /* + * When the current value counts up to the load count, the timer will + * stop and generate an irq. + */ + rk_timer_rtc_writeq(rk_rtc, TIMER_LOAD_COUNT0, alarm_tick); + + return RT_EOK; +} + +static rt_err_t rk_timer_rtc_control(rt_device_t dev, int cmd, void *args) +{ + rt_err_t err = RT_EOK; + struct rk_timer_rtc *rk_rtc = raw_to_rk_timer_rtc(dev); + + if (!args) + { + return -RT_EINVAL; + } + + switch (cmd) + { + case RT_DEVICE_CTRL_RTC_GET_TIME: + rk_timer_rtc_read_time(rk_rtc, args); + break; + + case RT_DEVICE_CTRL_RTC_SET_TIME: + rk_timer_rtc_set_time(rk_rtc, args); + break; + + case RT_DEVICE_CTRL_RTC_GET_TIMEVAL: + rk_timer_rtc_read_time(rk_rtc, (time_t *)&((struct timeval *)args)->tv_sec); + break; + + case RT_DEVICE_CTRL_RTC_SET_TIMEVAL: + rk_timer_rtc_set_time(rk_rtc, (time_t *)&((struct timeval *)args)->tv_sec); + break; + + case RT_DEVICE_CTRL_RTC_GET_ALARM: + rk_timer_rtc_read_alarm(rk_rtc, args); + break; + + case RT_DEVICE_CTRL_RTC_SET_ALARM: + err = rk_timer_rtc_set_alarm(rk_rtc, args); + break; + + default: + err = -RT_EINVAL; + break; + } + + return err; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rk_timer_rtc_ops = +{ + .control = rk_timer_rtc_control, +}; +#endif + +static void rk_timer_rtc_isr(int irqno, void *param) +{ + struct rk_timer_rtc *rk_rtc = param; + + rk_timer_rtc_writeq(rk_rtc, TIMER_LOAD_COUNT0, TIMER_COUNT_MAX); + rk_timer_rtc_writel(rk_rtc, TIMER_INT_STATUS, 1); + + if (rk_rtc->alarm_irq_enabled) + { + rt_alarm_update(&rk_rtc->parent, 1); + } +} + +static void rk_timer_rtc_free(struct rk_timer_rtc *rk_rtc) +{ + if (rk_rtc->base) + { + rt_iounmap(rk_rtc->base); + } + + if (!rt_is_err_or_null(rk_rtc->pclk)) + { + rt_clk_disable_unprepare(rk_rtc->pclk); + rt_clk_put(rk_rtc->pclk); + } + + if (!rt_is_err_or_null(rk_rtc->clk)) + { + rt_clk_disable_unprepare(rk_rtc->clk); + rt_clk_put(rk_rtc->clk); + } + + rt_free(rk_rtc); +} + +static rt_err_t rk_timer_rtc_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + const char *dev_name; + struct rt_device *dev = &pdev->parent; + struct rk_timer_rtc *rk_rtc = rt_calloc(1, sizeof(*rk_rtc)); + + if (!rk_rtc) + { + return -RT_ENOMEM; + } + + rk_rtc->soc_data = pdev->id->data; + + rk_rtc->base = rt_dm_dev_iomap(dev, 0); + + if (!rk_rtc->base) + { + err = -RT_EIO; + + goto _fail; + } + + rk_rtc->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_rtc->irq < 0) + { + err = rk_rtc->irq; + + goto _fail; + } + + rk_rtc->pclk = rt_clk_get_by_name(dev, "pclk"); + + if (rt_is_err(rk_rtc->pclk)) + { + err = rt_ptr_err(rk_rtc->pclk); + + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_rtc->pclk))) + { + goto _fail; + } + + rk_rtc->clk = rt_clk_get_by_name(dev, "timer"); + + if (rt_is_err(rk_rtc->clk)) + { + err = rt_ptr_err(rk_rtc->clk); + + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_rtc->clk))) + { + goto _fail; + } + + rk_rtc->freq = rt_clk_get_rate(rk_rtc->clk); + + dev->user_data = rk_rtc; + + rk_rtc->parent.type = RT_Device_Class_RTC; +#ifdef RT_USING_DEVICE_OPS + rk_rtc->parent.ops = &rk_timer_rtc_ops; +#else + rk_rtc->parent.control = rk_timer_rtc_control; +#endif + + rtc_dev_set_name(&rk_rtc->parent); + dev_name = rt_dm_dev_get_name(&rk_rtc->parent); + rt_device_register(&rk_rtc->parent, dev_name, RT_DEVICE_FLAG_RDWR); + + rt_hw_interrupt_install(rk_rtc->irq, rk_timer_rtc_isr, rk_rtc, "rtc-rockchip"); + rt_hw_interrupt_umask(rk_rtc->irq); + + return RT_EOK; + +_fail: + rk_timer_rtc_free(rk_rtc); + + return err; +} + +static rt_err_t rk_timer_rtc_remove(struct rt_platform_device *pdev) +{ + struct rk_timer_rtc *rk_rtc = pdev->parent.user_data; + + rt_hw_interrupt_mask(rk_rtc->irq); + rt_pic_detach_irq(rk_rtc->irq, rk_rtc); + + rt_device_unregister(&rk_rtc->parent); + + rk_timer_rtc_free(rk_rtc); + + return RT_EOK; +} + +static const struct rk_timer_rtc_data rk3288_timer_rtc_data = +{ + .ctrl_reg_offset = TIMER_CONTROL_REG3288, +}; + +static const struct rt_ofw_node_id rk_timer_rtc_ofw_ids[] = +{ + { .compatible = "rockchip,rk3308-timer-rtc", .data = &rk3288_timer_rtc_data }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rk_timer_rtc_driver = +{ + .name = "rk-timer-rtc", + .ids = rk_timer_rtc_ofw_ids, + + .probe = rk_timer_rtc_probe, + .remove = rk_timer_rtc_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rk_timer_rtc_driver); diff --git a/bsp/rockchip/dm/sdio/Kconfig b/bsp/rockchip/dm/sdio/Kconfig new file mode 100755 index 00000000000..85905c77e62 --- /dev/null +++ b/bsp/rockchip/dm/sdio/Kconfig @@ -0,0 +1,5 @@ +config RT_SDIO_DW_MMC_ROCKCHIP + bool "Rockchip" + depends on RT_SDIO_DW_MMC + depends on RT_USING_OFW + default n diff --git a/bsp/rockchip/dm/sdio/SConscript b/bsp/rockchip/dm/sdio/SConscript new file mode 100755 index 00000000000..968b4d3bafc --- /dev/null +++ b/bsp/rockchip/dm/sdio/SConscript @@ -0,0 +1,12 @@ +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/sdio/host'] + +if GetDepend(['RT_SDIO_DW_MMC_ROCKCHIP']): + src += ['sdio-dw_rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/sdio/sdio-dw_rockchip.c b/bsp/rockchip/dm/sdio/sdio-dw_rockchip.c new file mode 100755 index 00000000000..d4dd68d66c5 --- /dev/null +++ b/bsp/rockchip/dm/sdio/sdio-dw_rockchip.c @@ -0,0 +1,461 @@ +/* + * 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 + */ + +#include "sdio-dw.h" +#include "sdio-dw-platform.h" + +#define DBG_TAG "sdio.dw.rockchip" +#define DBG_LVL DBG_INFO +#include + +#define RK3288_CLKGEN_DIV 2 + +struct phases_range +{ + int start; + int end; +}; + +struct sdio_dw_rockchip_platform_data +{ + struct rt_clk *drv_clk; + struct rt_clk *sample_clk; + + rt_bool_t use_v2_tuning; + int last_degree; + rt_uint32_t freq_min; + + rt_uint32_t default_sample_phase; + rt_uint32_t num_phases; + struct phases_range phases[]; +}; + +static rt_err_t sdio_dw_rockchip_init(struct sdio_dw *sd) +{ + /* It is slot 8 on Rockchip SoCs */ + sd->sdio_id0 = 8; + + if (rt_ofw_node_is_compatible(sd->parent.ofw_node, "rockchip,rk3288-dw-mshc")) + { + sd->bus_hz /= RK3288_CLKGEN_DIV; + } + + return RT_EOK; +} + +static rt_err_t sdio_dw_rk3288_set_iocfg(struct sdio_dw *sd, struct rt_mmcsd_io_cfg *ios) +{ + rt_uint32_t freq, bus_hz; + struct sdio_dw_rockchip_platform_data *pdata = sd->priv; + + if (!ios->clock) + { + return RT_EOK; + } + + /* + * freq: source clock of mmc controller + * bus_hz: card interface clock generated by CLKGEN + * bus_hz = freq / RK3288_CLKGEN_DIV + * ios->clock = (div == 0) ? bus_hz : (bus_hz / (2 * div)) + * + * Note: div can only be 0 or 1, but div must be set to 1 for eMMC + * DDR52 8-bit mode. + */ + if (ios->clock < pdata->freq_min) + { + ios->clock = pdata->freq_min; + sd->slot->clock = ios->clock; + } + + freq = ios->clock * RK3288_CLKGEN_DIV; + + /* + * The clock frequency chosen here affects CLKDIV in the dw_mmc core. + * That can be either 0 or 1, but it must be set to 1 for eMMC DDR52 + * 8-bit mode. It will be set to 0 for all other modes. + */ + if (ios->bus_width == MMCSD_BUS_WIDTH_8 && ios->timing == MMCSD_TIMING_MMC_DDR52) + { + freq *= 2; + } + + rt_clk_set_rate(sd->ciu_clk, freq); + bus_hz = rt_clk_get_rate(sd->ciu_clk) / RK3288_CLKGEN_DIV; + + if (bus_hz != sd->bus_hz) + { + sd->bus_hz = bus_hz; + sd->current_speed = 0; + } + + if (!rt_is_err_or_null(pdata->sample_clk) && ios->timing <= MMCSD_TIMING_SD_HS) + { + rt_clk_set_phase(pdata->sample_clk, pdata->default_sample_phase); + } + + if (!rt_is_err_or_null(pdata->drv_clk)) + { + int phase = 90; + + switch (ios->timing) + { + case MMCSD_TIMING_MMC_DDR52: + /* + * Since clock in rate with MMC_DDR52 is doubled when + * bus width is 8 we need to double the phase offset + * to get the same timings. + */ + if (ios->bus_width == MMCSD_BUS_WIDTH_8) + { + phase = 180; + } + break; + case MMCSD_TIMING_UHS_SDR104: + case MMCSD_TIMING_MMC_HS200: + /* + * In the case of 150 MHz clock (typical max for + * Rockchip SoCs), 90 degree offset will add a delay + * of 1.67 ns. That will meet min hold time of .8 ns + * as long as clock output delay is < .87 ns. On + * SoCs measured this seems to be OK, but it doesn't + * hurt to give margin here, so we use 180. + */ + phase = 180; + break; + } + + rt_clk_set_phase(pdata->drv_clk, phase); + } + + return RT_EOK; +} + +static rt_err_t sdio_dw_rk3288_parse_ofw(struct sdio_dw *sd) +{ + rt_err_t err = RT_EOK; + rt_uint32_t num_phases; + struct rt_ofw_node *np = sd->parent.ofw_node; + struct sdio_dw_rockchip_platform_data *pdata; + + if (rt_ofw_prop_read_u32(np, "rockchip,desired-num-phases", &num_phases)) + { + num_phases = 360; + } + + pdata = rt_malloc(sizeof(*pdata) + sizeof(struct phases_range) * num_phases); + + if (!pdata) + { + return -RT_ENOMEM; + } + + pdata->num_phases = num_phases; + + if (rt_ofw_prop_read_u32(np, "rockchip,default-sample-phase", &pdata->default_sample_phase)) + { + pdata->default_sample_phase = 0; + } + + if (rt_ofw_prop_read_bool(np, "rockchip,use-v2-tuning")) + { + pdata->use_v2_tuning = RT_TRUE; + } + + if (rt_ofw_node_is_compatible(np, "rockchip,rk3568-dw-mshc")) + { + pdata->freq_min = 375000; + } + else + { + pdata->freq_min = 100000; + } + + pdata->drv_clk = rt_ofw_get_clk_by_name(np, "ciu-drive"); + + if (rt_is_err_or_null(pdata->drv_clk)) + { + pdata->drv_clk = rt_ofw_get_clk_by_name(np, "ciu-drv"); + } + + pdata->sample_clk = rt_ofw_get_clk_by_name(np, "ciu-sample"); + + sd->priv = pdata; + + return err; +} + +#define TUNING_ITERATION_TO_PHASE(i, num_phases) \ + (RT_DIV_ROUND_UP((i) * 360, num_phases)) + +static rt_err_t dw_mci_v2_execute_tuning(struct sdio_dw_slot *slot, rt_uint32_t opcode) +{ + int i; + struct rt_mmcsd_host *host = slot->host; + struct sdio_dw_rockchip_platform_data *pdata = slot->sd->priv; + rt_uint32_t degrees[4] = { 0, 90, 180, 270 }, degree; + static rt_bool_t inherit = RT_TRUE; + + if (inherit) + { + inherit = RT_FALSE; + degree = degrees[rt_clk_get_phase(pdata->sample_clk) / 90]; + goto _end; + } + + /* + * v2 only support 4 degrees in theory. + * First we inherit sample phases from firmware, which should + * be able work fine, at least in the first place. + * If retune is needed, we search forward to pick the last + * one phase from degree list and loop around until we get one. + * It's impossible all 4 fixed phase won't be able to work. + */ + for (i = 0; i < RT_ARRAY_SIZE(degrees); ++i) + { + degree = degrees[i] + pdata->last_degree; + degree = degree % 360; + rt_clk_set_phase(pdata->sample_clk, degree); + + if (!mmcsd_send_tuning(host, opcode, RT_NULL)) + { + break; + } + } + + if (i == RT_ARRAY_SIZE(degrees)) + { + LOG_W("All phases bad!"); + + return -RT_EIO; + } + +_end: + LOG_D("Successfully tuned phase to %d", degrees[i]); + pdata->last_degree = degree; + + return 0; +} + +static rt_err_t sdio_dw_rk3288_execute_tuning(struct sdio_dw_slot *slot, + rt_uint32_t opcode) +{ + rt_err_t err = RT_EOK; + rt_bool_t tuning, prev_tuning = 0, first_tuning; + int range_count = 0, longest_range_len = -1, longest_range = -1; + int real_middle_phase, middle_phase; + struct rt_mmcsd_host *host = slot->host; + struct sdio_dw_rockchip_platform_data *pdata = slot->sd->priv; + struct phases_range *ranges = pdata->phases; + + if (rt_is_err_or_null(pdata->sample_clk)) + { + return -RT_EIO; + } + + if (pdata->use_v2_tuning) + { + if (!(err = dw_mci_v2_execute_tuning(slot, opcode))) + { + return RT_EOK; + } + } + + for (int i = 0; i < pdata->num_phases;) + { + rt_clk_set_phase(pdata->sample_clk, + TUNING_ITERATION_TO_PHASE(i, pdata->num_phases)); + + tuning = !mmcsd_send_tuning(host, opcode, RT_NULL); + + if (i == 0) + { + first_tuning = tuning; + } + + if ((!prev_tuning) && tuning) + { + ++range_count; + ranges[range_count - 1].start = i; + } + if (tuning) + { + ranges[range_count - 1].end = i; + ++i; + } + else if (i == pdata->num_phases - 1) + { + /* No extra skipping rules if we're at the end */ + ++i; + } + else + { + /* + * No need to check too close to an invalid one since + * testing bad phases is slow. Skip 20 degrees. + */ + i += RT_DIV_ROUND_UP(20 * pdata->num_phases, 360); + + /* Always test the last one */ + if (i >= pdata->num_phases) + { + i = pdata->num_phases - 1; + } + } + + prev_tuning = tuning; + } + + if (range_count == 0) + { + LOG_W("All phases bad!"); + + return -RT_EIO; + } + + /* wrap around case, merge the end points */ + if (range_count > 1 && first_tuning && tuning) + { + ranges[0].start = ranges[range_count - 1].start; + --range_count; + } + + if (ranges[0].start == 0 && ranges[0].end == pdata->num_phases - 1) + { + rt_clk_set_phase(pdata->sample_clk, pdata->default_sample_phase); + LOG_I("All phases work, using default phase %u", pdata->default_sample_phase); + + return RT_EOK; + } + + /* Find the longest range */ + for (int i = 0; i < range_count; ++i) + { + int len = (ranges[i].end - ranges[i].start + 1); + + if (len < 0) + { + len += pdata->num_phases; + } + + if (longest_range_len < len) + { + longest_range_len = len; + longest_range = i; + } + + LOG_D("%s phase range %d-%d (%d len)", + "Good", + TUNING_ITERATION_TO_PHASE(ranges[i].start, pdata->num_phases), + TUNING_ITERATION_TO_PHASE(ranges[i].end, pdata->num_phases), + len); + } + + LOG_D("%s phase range %d-%d (%d len)", + "Best", + TUNING_ITERATION_TO_PHASE(ranges[longest_range].start, pdata->num_phases), + TUNING_ITERATION_TO_PHASE(ranges[longest_range].end, pdata->num_phases), + longest_range_len); + + middle_phase = ranges[longest_range].start + longest_range_len / 2; + middle_phase %= pdata->num_phases; + real_middle_phase = TUNING_ITERATION_TO_PHASE(middle_phase, pdata->num_phases); + + /* + * Since we cut out 270 ~ 360, the original algorithm + * still rolling ranges before and after 270 together + * in some corner cases, we should adjust it to avoid + * using any middle phase located between 270 and 360. + * By calculatiion, it happends due to the bad phases + * lay between 90 ~ 180. So others are all fine to chose. + * Pick 270 is a better choice in those cases. In case of + * bad phases exceed 180, the middle phase of rollback + * would be bigger than 315, so we chose 360. + */ + if (real_middle_phase > 270) + { + if (real_middle_phase < 315) + { + real_middle_phase = 270; + } + else + { + real_middle_phase = 360; + } + } + + LOG_I("Successfully tuned phase to %d", + TUNING_ITERATION_TO_PHASE(middle_phase, pdata->num_phases)); + + rt_clk_set_phase(pdata->sample_clk, real_middle_phase); + + return err; +} + +static const struct sdio_dw_drv_data rk2928_drv_data = +{ + .init = sdio_dw_rockchip_init, +}; + +static const struct sdio_dw_drv_data rk3288_drv_data = +{ + .init = sdio_dw_rockchip_init, + .set_iocfg = sdio_dw_rk3288_set_iocfg, + .parse_ofw = sdio_dw_rk3288_parse_ofw, + .execute_tuning = sdio_dw_rk3288_execute_tuning, +}; + +static rt_err_t sdio_dw_rockchip_probe(struct rt_platform_device *pdev) +{ + const struct sdio_dw_drv_data *drv_data = pdev->id->data; + + return sdio_dw_platform_register(pdev, drv_data); +} + +static rt_err_t sdio_dw_rockchip_remove(struct rt_platform_device *pdev) +{ + struct sdio_dw *sd = pdev->parent.user_data; + struct sdio_dw_rockchip_platform_data *pdata = sd->priv; + + sdio_dw_remove(sd); + + if (!rt_is_err_or_null(pdata->drv_clk)) + { + rt_clk_put(pdata->drv_clk); + } + + if (!rt_is_err_or_null(pdata->sample_clk)) + { + rt_clk_put(pdata->sample_clk); + } + + rt_iounmap(sd->base); + + rt_free(sd); + + return RT_EOK; +} + +static const struct rt_ofw_node_id sdio_dw_rockchip_ofw_ids[] = +{ + { .compatible = "rockchip,rk2928-dw-mshc", .data = &rk2928_drv_data }, + { .compatible = "rockchip,rk3288-dw-mshc", .data = &rk3288_drv_data }, + { /* sentinel */ } +}; + +static struct rt_platform_driver sdio_dw_rockchip_driver = +{ + .name = "dw-mmc-rockchip", + .ids = sdio_dw_rockchip_ofw_ids, + + .probe = sdio_dw_rockchip_probe, + .remove = sdio_dw_rockchip_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(sdio_dw_rockchip_driver); diff --git a/bsp/rockchip/dm/soc/Kconfig b/bsp/rockchip/dm/soc/Kconfig new file mode 100755 index 00000000000..29229f87422 --- /dev/null +++ b/bsp/rockchip/dm/soc/Kconfig @@ -0,0 +1,19 @@ +config RT_SOC_ROCKCHIP_FIQ_DEBUGGER + bool "FIQ Debugger" + depends on RT_USING_OFW + default y + +config RT_SOC_ROCKCHIP_GRF + bool "General Register Files support" + depends on RT_MFD_SYSCON + default y + +config RT_SOC_ROCKCHIP_HW_DECOMPRESS + bool "HardWare Decompress (LZ4, GZIP, ZLIB)" + default n + +config RT_SOC_ROCKCHIP_IODOMAIN + bool "IO domain support" + depends on RT_MFD_SYSCON + depends on RT_USING_REGULATOR + default y diff --git a/bsp/rockchip/dm/soc/SConscript b/bsp/rockchip/dm/soc/SConscript new file mode 100755 index 00000000000..e3fda61b3f0 --- /dev/null +++ b/bsp/rockchip/dm/soc/SConscript @@ -0,0 +1,22 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include', cwd + '/../../../../components/drivers/serial/device/'] + +if GetDepend(['RT_SOC_ROCKCHIP_FIQ_DEBUGGER']): + src += ['fiq-debugger.c'] + +if GetDepend(['RT_SOC_ROCKCHIP_GRF']): + src += ['grf.c'] + +if GetDepend(['RT_SOC_ROCKCHIP_HW_DECOMPRESS']): + src += ['hw-decompress.c'] + +if GetDepend(['RT_SOC_ROCKCHIP_IODOMAIN']): + src += ['io-domain.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/rk3500/driver/uart8250/fiq-debugger.c b/bsp/rockchip/dm/soc/fiq-debugger.c old mode 100644 new mode 100755 similarity index 94% rename from bsp/rockchip/rk3500/driver/uart8250/fiq-debugger.c rename to bsp/rockchip/dm/soc/fiq-debugger.c index 4cbd803d4f1..379f6b48757 --- a/bsp/rockchip/rk3500/driver/uart8250/fiq-debugger.c +++ b/bsp/rockchip/dm/soc/fiq-debugger.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006-2024 RT-Thread Development Team + * Copyright (c) 2006-2022, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * @@ -11,12 +11,12 @@ #include #include #include +#include #include #include -#include "regs.h" -#include "serial_dm.h" +#include "8250/regs.h" #define UART_USR 0x1f /* In: UART Status Register */ #define UART_USR_RX_FIFO_FULL 0x10 /* Receive FIFO full */ @@ -86,7 +86,7 @@ static void fiq_debugger_isr(int irqno, void *param) 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; + rt_uint32_t baudrate, count = 10000; struct rockchip_fiq_debugger *t = raw_to_fiq_debugger(serial); if (rockchip_fiq_read(t, UART_LSR) & UART_LSR_DR) @@ -99,7 +99,16 @@ static rt_err_t fiq_debugger_uart_configure(struct rt_serial_device *serial, str rt_hw_us_delay(10); } - switch (t->baudrate) + if (cfg->baud_rate == 1500000 || cfg->baud_rate == 115200) + { + baudrate = cfg->baud_rate; + } + else + { + baudrate = t->baudrate; + } + + switch (baudrate) { case 1500000: dll = 0x1; @@ -146,11 +155,11 @@ static rt_err_t fiq_debugger_uart_control(struct rt_serial_device *serial, int c switch (cmd) { case RT_DEVICE_CTRL_CLR_INT: - rt_pic_irq_mask(t->irq); + rt_hw_interrupt_mask(t->irq); break; case RT_DEVICE_CTRL_SET_INT: - rt_pic_irq_unmask(t->irq); + rt_hw_interrupt_umask(t->irq); break; } @@ -164,7 +173,7 @@ static int fiq_debugger_uart_putc(struct rt_serial_device *serial, char c) while (!(rockchip_fiq_read(t, UART_USR) & UART_USR_TX_FIFO_NOT_FULL) && count--) { - rt_hw_cpu_relax(); + rt_hw_us_delay(10); } rockchip_fiq_write(t, c, UART_TX); @@ -239,7 +248,7 @@ struct rockchip_fiq_debugger *rk_serial_debug_init(void *base, rt_ubase_t paddr, 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); + rt_hw_interrupt_install(t->irq, fiq_debugger_isr, &t->parent, name); } return t; diff --git a/bsp/rockchip/dm/soc/grf.c b/bsp/rockchip/dm/soc/grf.c new file mode 100755 index 00000000000..da3bc6dbfa4 --- /dev/null +++ b/bsp/rockchip/dm/soc/grf.c @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-21 GuEe-GUI first version + */ + +#include +#include +#include + +#define DBG_TAG "soc.rockchip.grf" +#define DBG_LVL DBG_INFO +#include + +#include "rockchip.h" + +struct rockchip_grf_value +{ + const char *desc; + rt_uint32_t reg; + rt_uint32_t val; +}; + +struct rockchip_grf_info +{ + const struct rockchip_grf_value *values; + int values_nr; + rt_err_t (*reset)(struct rt_syscon *grf); +}; + +#define PX30_GRF_SOC_CON5 0x414 + +static const struct rockchip_grf_value px30_defaults[] = +{ + /* + * Postponing auto jtag/sdmmc switching by 5 seconds. + * The counter value is calculated based on 24MHz clock. + */ + { "jtag switching delay", PX30_GRF_SOC_CON5, 0x7270E00}, +}; + +static const struct rockchip_grf_info px30_grf = +{ + .values = px30_defaults, + .values_nr = RT_ARRAY_SIZE(px30_defaults), +}; + +#define RK3036_GRF_SOC_CON0 0x140 + +static const struct rockchip_grf_value rk3036_defaults[] = +{ + /* + * Disable auto jtag/sdmmc switching that causes issues with the + * clock-framework and the mmc controllers making them unreliable. + */ + { "jtag switching", RK3036_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 11) }, +}; + +static const struct rockchip_grf_info rk3036_grf = +{ + .values = rk3036_defaults, + .values_nr = RT_ARRAY_SIZE(rk3036_defaults), +}; + +#define RK3128_GRF_SOC_CON0 0x140 + +static const struct rockchip_grf_value rk3128_defaults[] = +{ + { "jtag switching", RK3128_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 8) }, +}; + +static const struct rockchip_grf_info rk3128_grf = +{ + .values = rk3128_defaults, + .values_nr = RT_ARRAY_SIZE(rk3128_defaults), +}; + +#define RK3228_GRF_SOC_CON6 0x418 + +static const struct rockchip_grf_value rk3228_defaults[] = +{ + { "jtag switching", RK3228_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 8) }, +}; + +static const struct rockchip_grf_info rk3228_grf = +{ + .values = rk3228_defaults, + .values_nr = RT_ARRAY_SIZE(rk3228_defaults), +}; + +#define RK3288_GRF_SOC_CON0 0x244 +#define RK3288_GRF_SOC_CON2 0x24c + +static const struct rockchip_grf_value rk3288_defaults[] = +{ + { "jtag switching", RK3288_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 12) }, + { "pwm select", RK3288_GRF_SOC_CON2, HIWORD_UPDATE(1, 1, 0) }, +}; + +static const struct rockchip_grf_info rk3288_grf = +{ + .values = rk3288_defaults, + .values_nr = RT_ARRAY_SIZE(rk3288_defaults), +}; + +#define RK3328_GRF_SOC_CON4 0x410 + +static const struct rockchip_grf_value rk3328_defaults[] = +{ + { "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) }, +}; + +static const struct rockchip_grf_info rk3328_grf = +{ + .values = rk3328_defaults, + .values_nr = RT_ARRAY_SIZE(rk3328_defaults), +}; + +#define RK3308_GRF_SOC_CON3 0x30c +#define RK3308_GRF_SOC_CON13 0x608 + +static const struct rockchip_grf_value rk3308_defaults[] = +{ + { "uart dma mask", RK3308_GRF_SOC_CON3, HIWORD_UPDATE(0, 0x1f, 10) }, + { "uart2 auto switching", RK3308_GRF_SOC_CON13, HIWORD_UPDATE(0, 0x1, 12) }, +}; + +static const struct rockchip_grf_info rk3308_grf = +{ + .values = rk3308_defaults, + .values_nr = RT_ARRAY_SIZE(rk3308_defaults), +}; + +#define RK3368_GRF_SOC_CON15 0x43c + +static const struct rockchip_grf_value rk3368_defaults[] = +{ + { "jtag switching", RK3368_GRF_SOC_CON15, HIWORD_UPDATE(0, 1, 13) }, +}; + +static const struct rockchip_grf_info rk3368_grf = +{ + .values = rk3368_defaults, + .values_nr = RT_ARRAY_SIZE(rk3368_defaults), +}; + +#define RK3399_GRF_SOC_CON7 0xe21c + +static const struct rockchip_grf_value rk3399_defaults[] = +{ + { "jtag switching", RK3399_GRF_SOC_CON7, HIWORD_UPDATE(0, 1, 12) }, +}; + +static const struct rockchip_grf_info rk3399_grf = +{ + .values = rk3399_defaults, + .values_nr = RT_ARRAY_SIZE(rk3399_defaults), +}; + +#define RK3566_GRF_USB3OTG0_CON1 0x0104 + +static const struct rockchip_grf_value rk3566_defaults[] = +{ + { "usb3otg port switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(0, 1, 12) }, + { "usb3otg clock switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 7) }, + { "usb3otg disable usb3", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 0) }, +}; + +static const struct rockchip_grf_info rk3566_pipegrf = +{ + .values = rk3566_defaults, + .values_nr = RT_ARRAY_SIZE(rk3566_defaults), +}; + +static rt_err_t rk3568_edp_phy_grf_reset(struct rt_syscon *grf) +{ + rt_err_t err; + rt_uint32_t status; + + if ((err = rt_syscon_read(grf, 0x0030, &status))) + { + return err; + } + + if (!RT_FIELD_GET(0x1, status)) + { + rt_syscon_write(grf, 0x0028, 0x00070007); + rt_syscon_write(grf, 0x0000, 0x0ff10ff1); + } + + return RT_EOK; +} + +static const struct rockchip_grf_info rk3568_edp_phy_grf = +{ + .reset = rk3568_edp_phy_grf_reset, +}; + +#define RK3588_GRF_SOC_CON6 0x0318 + +static const struct rockchip_grf_value rk3588_defaults[] = +{ + { "jtag switching", RK3588_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 14) }, +}; + +static const struct rockchip_grf_info rk3588_sysgrf = +{ + .values = rk3588_defaults, + .values_nr = RT_ARRAY_SIZE(rk3588_defaults), +}; + +#define DELAY_ONE_SECOND 0x16e3600 + +#define RV1126_GRF1_SDDETFLT_CON 0x10254 +#define RV1126_GRF1_UART2RX_LOW_CON 0x10258 +#define RV1126_GRF1_IOFUNC_CON1 0x10264 +#define RV1126_GRF1_IOFUNC_CON3 0x1026c +#define RV1126_JTAG_GROUP0 0x0 /* mux to sdmmc*/ +#define RV1126_JTAG_GROUP1 0x1 /* mux to uart2 */ +#define FORCE_JTAG_ENABLE 0x1 +#define FORCE_JTAG_DISABLE 0x0 + +static const struct rockchip_grf_value rv1126_defaults[] = +{ + { "jtag group0 force", RV1126_GRF1_IOFUNC_CON3, HIWORD_UPDATE(FORCE_JTAG_DISABLE, 1, 4) }, + { "jtag group1 force", RV1126_GRF1_IOFUNC_CON3, HIWORD_UPDATE(FORCE_JTAG_DISABLE, 1, 5) }, + { "jtag group1 tms low delay", RV1126_GRF1_UART2RX_LOW_CON, DELAY_ONE_SECOND }, + { "switch to jtag groupx", RV1126_GRF1_IOFUNC_CON1, HIWORD_UPDATE(RV1126_JTAG_GROUP0, 1, 15) }, + { "jtag group0 switching delay", RV1126_GRF1_SDDETFLT_CON, DELAY_ONE_SECOND * 5 }, +}; + +static const struct rockchip_grf_info rv1126_grf = +{ + .values = rv1126_defaults, + .values_nr = RT_ARRAY_SIZE(rv1126_defaults), +}; + +static rt_err_t rockchip_grf_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + struct rt_syscon *grf; + struct rt_ofw_node *np = pdev->parent.ofw_node; + const struct rockchip_grf_info *grf_info = pdev->id->data; + + grf = rt_syscon_find_by_ofw_node(np); + + if (!grf) + { + return -RT_EINVAL; + } + + for (int i = 0; i < grf_info->values_nr; ++i) + { + rt_err_t err; + const struct rockchip_grf_value *val = &grf_info->values[i]; + + err = rt_syscon_write(grf, val->reg, val->val); + LOG_D("%s: adjusting %6x to %10x", val->desc, val->reg, val->val); + + if (err) + { + LOG_E("%s: write %6x to %10x fail", val->desc, val->reg, val->val); + } + } + + if (grf_info->reset && (err = grf_info->reset(grf))) + { + return err; + } + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_grf_ofw_ids[] = +{ + { .compatible = "rockchip,px30-grf", .data = &px30_grf, }, + { .compatible = "rockchip,rk3036-grf", .data = &rk3036_grf, }, + { .compatible = "rockchip,rk3128-grf", .data = &rk3128_grf, }, + { .compatible = "rockchip,rk3228-grf", .data = &rk3228_grf, }, + { .compatible = "rockchip,rk3288-grf", .data = &rk3288_grf, }, + { .compatible = "rockchip,rk3308-grf", .data = &rk3308_grf, }, + { .compatible = "rockchip,rk3328-grf", .data = &rk3328_grf, }, + { .compatible = "rockchip,rk3368-grf", .data = &rk3368_grf, }, + { .compatible = "rockchip,rk3399-grf", .data = &rk3399_grf, }, + { .compatible = "rockchip,rk3566-pipe-grf", .data = &rk3566_pipegrf, }, + { .compatible = "rockchip,rk3568-edp-phy-grf", .data = &rk3568_edp_phy_grf, }, + { .compatible = "rockchip,rk3588-sys-grf", .data = &rk3588_sysgrf, }, + { .compatible = "rockchip,rv1126-grf", .data = &rv1126_grf, }, + + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_grf_driver = +{ + .name = "rockchip-grf", + .ids = rockchip_grf_ofw_ids, + + .probe = rockchip_grf_probe, +}; + +static int rockchip_grf_drv_register(void) +{ + rt_platform_driver_register(&rockchip_grf_driver); + + return 0; +} +INIT_PLATFORM_EXPORT(rockchip_grf_drv_register); diff --git a/bsp/rockchip/dm/soc/hw-decompress.c b/bsp/rockchip/dm/soc/hw-decompress.c new file mode 100755 index 00000000000..95d205291bf --- /dev/null +++ b/bsp/rockchip/dm/soc/hw-decompress.c @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-21 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "soc.rockchip.hw-decompress" +#define DBG_LVL DBG_INFO +#include + +#include +#include +#include + +#define DECOM_CTRL 0x0 +#define DECOM_ENR 0x4 +#define DECOM_RADDR 0x8 +#define DECOM_WADDR 0xc +#define DECOM_UDDSL 0x10 +#define DECOM_UDDSH 0x14 +#define DECOM_TXTHR 0x18 +#define DECOM_RXTHR 0x1c +#define DECOM_SLEN 0x20 +#define DECOM_STAT 0x24 +#define DECOM_ISR 0x28 +#define DECOM_IEN 0x2c +#define DECOM_AXI_STAT 0x30 +#define DECOM_TSIZEL 0x34 +#define DECOM_TSIZEH 0x38 +#define DECOM_MGNUM 0x3c +#define DECOM_FRAME 0x40 +#define DECOM_DICTID 0x44 +#define DECOM_CSL 0x48 +#define DECOM_CSH 0x4c +#define DECOM_LMTSL 0x50 +#define DECOM_LMTSH 0x54 + +#define LZ4_HEAD_CSUM_CHECK_EN RT_BIT(1) +#define LZ4_BLOCK_CSUM_CHECK_EN RT_BIT(2) +#define LZ4_CONT_CSUM_CHECK_EN RT_BIT(3) + +#define DSOLIEN RT_BIT(19) +#define ZDICTEIEN RT_BIT(18) +#define GCMEIEN RT_BIT(17) +#define GIDEIEN RT_BIT(16) +#define CCCEIEN RT_BIT(15) +#define BCCEIEN RT_BIT(14) +#define HCCEIEN RT_BIT(13) +#define CSEIEN RT_BIT(12) +#define DICTEIEN RT_BIT(11) +#define VNEIEN RT_BIT(10) +#define WNEIEN RT_BIT(9) +#define RDCEIEN RT_BIT(8) +#define WRCEIEN RT_BIT(7) +#define DISEIEN RT_BIT(6) +#define LENEIEN RT_BIT(5) +#define LITEIEN RT_BIT(4) +#define SQMEIEN RT_BIT(3) +#define SLCIEN RT_BIT(2) +#define HDEIEN RT_BIT(1) +#define DSIEN RT_BIT(0) + +#define DECOM_STOP RT_BIT(0) +#define DECOM_COMPLETE RT_BIT(0) +#define DECOM_GZIP_MODE RT_BIT(4) +#define DECOM_ZLIB_MODE RT_BIT(5) +#define DECOM_DEFLATE_MODE RT_BIT(0) + +#define DECOM_ENABLE 0x1 +#define DECOM_DISABLE 0x0 + +#define DECOM_INT_MASK \ +( \ + DSOLIEN | ZDICTEIEN | GCMEIEN | GIDEIEN | CCCEIEN | BCCEIEN | HCCEIEN | \ + CSEIEN | DICTEIEN | VNEIEN | WNEIEN | RDCEIEN | WRCEIEN | DISEIEN | \ + LENEIEN | LITEIEN | SQMEIEN | SLCIEN | HDEIEN | DSIEN \ +) + +enum rockchip_decompress_mod +{ + LZ4_MOD, + GZIP_MOD, + ZLIB_MOD, + + UNKNOW_MOD, +}; + +struct rockchip_decompress +{ + struct rt_device parent; + + int irq; + void *regs; + + struct rt_clk_array *clk_arr; + struct rt_reset_control *rstc; + + rt_err_t error; + rt_bool_t done; + struct rt_mutex lock; +}; + +#define raw_to_rockchip_decompress(raw) rt_container_of(raw, struct rockchip_decompress, parent) + +rt_inline rt_uint32_t rockchip_decompress_readl(struct rockchip_decompress *rk_decom, int offset) +{ + return HWREG32(rk_decom->regs + offset); +} + +rt_inline void rockchip_decompress_writel(struct rockchip_decompress *rk_decom, int offset, rt_uint32_t value) +{ + HWREG32(rk_decom->regs + offset) = value; +} + +static rt_err_t rockchip_decompress_submit(struct rockchip_decompress *rk_decom, + struct hw_decompress_param *param) +{ + rt_err_t err; + rt_uint32_t irq_status, decom_enr, mod_flags; + + decom_enr = rockchip_decompress_readl(rk_decom, DECOM_ENR); + + if (decom_enr & 0x1) + { + LOG_E("Decompress busy"); + return -RT_EBUSY; + } + + if (rk_decom->rstc) + { + rt_reset_control_assert(rk_decom->rstc); + rt_hw_us_delay(10); + rt_reset_control_deassert(rk_decom->rstc); + } + + irq_status = rockchip_decompress_readl(rk_decom, DECOM_ISR); + + /* clear interrupts */ + if (irq_status) + { + rockchip_decompress_writel(rk_decom, DECOM_ISR, irq_status); + } + + switch (param->mode) + { + case LZ4_MOD: + mod_flags = LZ4_CONT_CSUM_CHECK_EN | LZ4_HEAD_CSUM_CHECK_EN | + LZ4_BLOCK_CSUM_CHECK_EN | LZ4_MOD; + break; + + case GZIP_MOD: + mod_flags = DECOM_DEFLATE_MODE | DECOM_GZIP_MODE; + break; + + case ZLIB_MOD: + mod_flags = DECOM_DEFLATE_MODE | DECOM_ZLIB_MODE; + break; + } + rockchip_decompress_writel(rk_decom, DECOM_CTRL, mod_flags); + + rockchip_decompress_writel(rk_decom, DECOM_RADDR, param->src); + rockchip_decompress_writel(rk_decom, DECOM_WADDR, param->dst); + + rockchip_decompress_writel(rk_decom, DECOM_LMTSL, param->dst_max_size); + rockchip_decompress_writel(rk_decom, DECOM_LMTSH, 0x0); + + rockchip_decompress_writel(rk_decom, DECOM_IEN, DECOM_INT_MASK); + rockchip_decompress_writel(rk_decom, DECOM_ENR, DECOM_ENABLE); + + while (!rk_decom->done) + { + rt_hw_cpu_relax(); + } + err = rk_decom->error; + + rk_decom->error = RT_EOK; + rk_decom->done = RT_FALSE; + + return err; +} + +static rt_err_t rockchip_decompress_control(rt_device_t dev, int cmd, void *args) +{ + rt_err_t err; + struct hw_decompress_param *param; + struct rockchip_decompress *rk_decom = raw_to_rockchip_decompress(dev); + + if (cmd != HW_DECOMPRESS_REQ) + { + return -RT_ENOSYS; + } + + if (!(param = args)) + { + return -RT_EINVAL; + } + + rt_mutex_take(&rk_decom->lock, RT_WAITING_FOREVER); + + switch (param->mode) + { + case HW_DECOMPRESS_LZ4_MOD: + case HW_DECOMPRESS_GZIP_MOD: + case HW_DECOMPRESS_ZLIB_MOD: + break; + default: + err = -RT_ENOSYS; + goto _out_mutex; + } + + err = rockchip_decompress_submit(rk_decom, param); + +_out_mutex: + rt_mutex_release(&rk_decom->lock); + + return err; +} + +#ifdef RT_USING_DEVICE_OPS +const static struct rt_device_ops rockchip_decompress_ops = +{ + .control = rockchip_decompress_control, +}; +#endif + +static void rockchip_decompress_isr(int irqno, void *param) +{ + rt_uint32_t irq_status, decom_status; + struct rockchip_decompress *rk_decom = param; + + irq_status = rockchip_decompress_readl(rk_decom, DECOM_ISR); + /* clear interrupts */ + rockchip_decompress_writel(rk_decom, DECOM_ISR, irq_status); + + if (irq_status & DECOM_STOP) + { + decom_status = rockchip_decompress_readl(rk_decom, DECOM_STAT); + + if (!(decom_status & DECOM_COMPLETE)) + { + LOG_E("Decompress failed: irq_status = 0x%x, decom_status = 0x%x", + irq_status, decom_status); + + rk_decom->error = -RT_EIO; + } + + rk_decom->done = RT_TRUE; + } +} + +static void rockchip_decompress_free(struct rockchip_decompress *rk_decom) +{ + if (rk_decom->regs) + { + rt_iounmap(rk_decom->regs); + } + + if (!rt_is_err_or_null(rk_decom->clk_arr)) + { + rt_clk_array_disable_unprepare(rk_decom->clk_arr); + rt_clk_array_put(rk_decom->clk_arr); + } + + if (!rt_is_err_or_null(rk_decom->rstc)) + { + rt_reset_control_put(rk_decom->rstc); + } + + rt_free(rk_decom); +} + +static rt_err_t rockchip_decompress_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + rt_uint64_t addr, size; + const char *dev_name; + struct rt_device *dev = &pdev->parent; + struct rockchip_decompress *rk_decom = rt_calloc(1, sizeof(*rk_decom)); + + if (!rk_decom) + { + return -RT_ENOMEM; + } + + if ((err = rt_dm_dev_get_address(dev, 0, &addr, &size))) + { + goto _fail; + } + + rk_decom->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_decom->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_decom->clk_arr = rt_clk_get_array(dev); + + if (rt_is_err(rk_decom->clk_arr)) + { + err = rt_ptr_err(rk_decom->clk_arr); + goto _fail; + } + + if ((err = rt_clk_array_prepare_enable(rk_decom->clk_arr))) + { + goto _fail; + } + + rk_decom->rstc = rt_reset_control_get_by_name(dev, "dresetn"); + + if (rt_is_err(rk_decom->rstc)) + { + err = rt_ptr_err(rk_decom->rstc); + goto _fail; + } + + rk_decom->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_decom->irq < 0) + { + err = rk_decom->irq; + goto _fail; + } + + dev->user_data = rk_decom; + + rt_dm_dev_set_name_auto(&rk_decom->parent, "decom"); + dev_name = rt_dm_dev_get_name(&rk_decom->parent); + + rk_decom->parent.type = RT_Device_Class_Char; +#ifdef RT_USING_DEVICE_OPS + rk_decom->parent.ops = &rockchip_decompress_ops; +#else + rk_decom->parent.control = rockchip_decompress_control; +#endif + + if ((err = rt_device_register(&rk_decom->parent, dev_name, RT_DEVICE_FLAG_DEACTIVATE))) + { + goto _fail; + } + + rt_mutex_init(&rk_decom->lock, dev_name, RT_IPC_FLAG_PRIO); + + rt_hw_interrupt_install(rk_decom->irq, rockchip_decompress_isr, rk_decom, "rk-decompress"); + rt_hw_interrupt_umask(rk_decom->irq); + + return RT_EOK; + +_fail: + rockchip_decompress_free(rk_decom); + + return err; +} + +static rt_err_t rockchip_decompress_remove(struct rt_platform_device *pdev) +{ + struct rockchip_decompress *rk_decom = pdev->parent.user_data; + + rt_hw_interrupt_mask(rk_decom->irq); + rt_pic_detach_irq(rk_decom->irq, rk_decom); + + rt_device_unregister(&rk_decom->parent); + + rockchip_decompress_free(rk_decom); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_decompress_ofw_ids[] = +{ + { .compatible = "rockchip,hw-decompress" }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_decompress_driver = +{ + .name = "rockchip-hwdecompress", + .ids = rockchip_decompress_ofw_ids, + + .probe = rockchip_decompress_probe, + .remove = rockchip_decompress_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_decompress_driver); diff --git a/bsp/rockchip/dm/soc/io-domain.c b/bsp/rockchip/dm/soc/io-domain.c new file mode 100755 index 00000000000..67176535166 --- /dev/null +++ b/bsp/rockchip/dm/soc/io-domain.c @@ -0,0 +1,698 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-21 GuEe-GUI first version + */ + +#include +#include +#include + +#define DBG_TAG "soc.rockchip.io-domain" +#define DBG_LVL DBG_INFO +#include + +#define MAX_SUPPLIES 16 + +/* + * The max voltage for 1.8V and 3.3V come from the Rockchip datasheet under + * "Recommended Operating Conditions" for "Digital GPIO". When the typical + * is 3.3V the max is 3.6V. When the typical is 1.8V the max is 1.98V. + * + * They are used like this: + * - If the voltage on a rail is above the "1.8" voltage (1.98V) we'll tell the + * SoC we're at 3.3. + * - If the voltage on a rail is above the "3.3" voltage (3.6V) we'll consider + * that to be an error. + */ +#define MAX_VOLTAGE_1_8 1980000 +#define MAX_VOLTAGE_3_3 3600000 + +struct rockchip_iodomain; + +struct rockchip_iodomain_supply +{ + struct rockchip_iodomain *domain; + struct rt_regulator *reg; + struct rt_regulator_notifier notifier; + int idx; +}; + +struct rockchip_iodomain_soc_data +{ + int grf_offset; + const char *supply_names[MAX_SUPPLIES]; + void (*init)(struct rockchip_iodomain *domain); + rt_err_t (*write)(struct rockchip_iodomain_supply *supply, int uvolt); +}; + +struct rockchip_iodomain +{ + struct rt_device *dev; + struct rt_syscon *grf; + const struct rockchip_iodomain_soc_data *soc_data; + struct rockchip_iodomain_supply supplies[MAX_SUPPLIES]; + + rt_err_t (*write)(struct rockchip_iodomain_supply *supply, int uvolt); +}; + +#define PX30_IO_VSEL 0x180 +#define PX30_IO_VSEL_VCCIO6_SRC RT_BIT(0) +#define PX30_IO_VSEL_VCCIO6_SUPPLY_NUM 1 + +static void px30_iodomain_init(struct rockchip_iodomain *domain) +{ + rt_uint32_t val; + + /* if no VCCIO6 supply we should leave things alone */ + if (!domain->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg) + { + return; + } + + /* set vccio6 iodomain to also use this framework instead of a special gpio. */ + val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16); + + if (rt_syscon_write(domain->grf, PX30_IO_VSEL, val) < 0) + { + LOG_W("Couldn't update %s ctrl", "vccio6"); + } +} + +static const struct rockchip_iodomain_soc_data soc_data_px30 = +{ + .grf_offset = 0x180, + .supply_names = + { + [1] = + "vccio6", + "vccio1", + "vccio2", + "vccio3", + "vccio4", + "vccio5", + "vccio-oscgpi", + }, + .init = px30_iodomain_init, +}; + +static const struct rockchip_iodomain_soc_data soc_data_px30_pmu = +{ + .grf_offset = 0x100, + .supply_names = + { + [14] = + "pmuio1", + "pmuio2", + }, +}; + +/* + * On the rk3188 the io-domains are handled by a shared register with the lower + * 8 bits being still being continuing drive-strength settings. + */ +static const struct rockchip_iodomain_soc_data soc_data_rk3188 = +{ + .grf_offset = 0x104, + .supply_names = + { + [8] = + "ap0", + "ap1", + "cif", + "flash", + "vccio0", + "vccio1", + "lcdc0", + "lcdc1", + }, +}; + +static const struct rockchip_iodomain_soc_data soc_data_rk3228 = +{ + .grf_offset = 0x418, + .supply_names = + { + "vccio1", + "vccio2", + "vccio3", + "vccio4", + }, +}; + +#define RK3288_SOC_CON2 0x24c +#define RK3288_SOC_CON2_FLASH0 RT_BIT(7) +#define RK3288_SOC_FLASH_SUPPLY_NUM 2 + +static void rk3288_iodomain_init(struct rockchip_iodomain *domain) +{ + rt_uint32_t val; + + /* if no flash supply we should leave things alone */ + if (!domain->supplies[RK3288_SOC_FLASH_SUPPLY_NUM].reg) + { + return; + } + + /* set flash0 iodomain to also use this framework instead of a special gpio. */ + val = RK3288_SOC_CON2_FLASH0 | (RK3288_SOC_CON2_FLASH0 << 16); + + if (rt_syscon_write(domain->grf, RK3288_SOC_CON2, val) < 0) + { + LOG_W("Couldn't update %s ctrl", "flash0"); + } +} + +static const struct rockchip_iodomain_soc_data soc_data_rk3288 = +{ + .grf_offset = 0x380, + .supply_names = + { + "lcdc", /* LCDC_VDD */ + "dvp", /* DVPIO_VDD */ + "flash0", /* FLASH0_VDD (emmc) */ + "flash1", /* FLASH1_VDD (sdio1) */ + "wifi", /* APIO3_VDD (sdio0) */ + "bb", /* APIO5_VDD */ + "audio", /* APIO4_VDD */ + "sdcard", /* SDMMC0_VDD (sdmmc) */ + "gpio30", /* APIO1_VDD */ + "gpio1830", /* APIO2_VDD */ + }, + .init = rk3288_iodomain_init, +}; + +#define RK3308_SOC_CON0 0x300 +#define RK3308_SOC_CON0_VCCIO3 RT_BIT(8) +#define RK3308_SOC_VCCIO3_SUPPLY_NUM 3 + +static void rk3308_iodomain_init(struct rockchip_iodomain *domain) +{ + rt_uint32_t val; + + /* if no vccio3 supply we should leave things alone */ + if (!domain->supplies[RK3308_SOC_VCCIO3_SUPPLY_NUM].reg) + { + return; + } + + /* set vccio3 iodomain to also use this framework instead of a special gpio. */ + val = RK3308_SOC_CON0_VCCIO3 | (RK3308_SOC_CON0_VCCIO3 << 16); + + if (rt_syscon_write(domain->grf, RK3308_SOC_CON0, val) < 0) + { + LOG_W("Couldn't update %s ctrl", "vccio3"); + } +} + +static const struct rockchip_iodomain_soc_data soc_data_rk3308 = +{ + .grf_offset = 0x300, + .supply_names = + { + "vccio0", + "vccio1", + "vccio2", + "vccio3", + "vccio4", + "vccio5", + }, + .init = rk3308_iodomain_init, +}; + +#define RK3328_SOC_CON4 0x410 +#define RK3328_SOC_CON4_VCCIO2 RT_BIT(7) +#define RK3328_SOC_VCCIO2_SUPPLY_NUM 1 + +static void rk3328_iodomain_init(struct rockchip_iodomain *domain) +{ + rt_uint32_t val; + + /* if no vccio2 supply we should leave things alone */ + if (!domain->supplies[RK3328_SOC_VCCIO2_SUPPLY_NUM].reg) + { + return; + } + + /* set vccio2 iodomain to also use this framework instead of a special gpio. */ + val = RK3328_SOC_CON4_VCCIO2 | (RK3328_SOC_CON4_VCCIO2 << 16); + + if (rt_syscon_write(domain->grf, RK3328_SOC_CON4, val) < 0) + { + LOG_W("Couldn't update %s ctrl", "vccio2 vsel"); + } +} + +static const struct rockchip_iodomain_soc_data soc_data_rk3328 = +{ + .grf_offset = 0x410, + .supply_names = + { + "vccio1", + "vccio2", + "vccio3", + "vccio4", + "vccio5", + "vccio6", + "pmuio", + }, + .init = rk3328_iodomain_init, +}; + +#define RK3368_SOC_CON15 0x43c +#define RK3368_SOC_CON15_FLASH0 RT_BIT(14) +#define RK3368_SOC_FLASH_SUPPLY_NUM 2 + +static void rk3368_iodomain_init(struct rockchip_iodomain *domain) +{ + rt_uint32_t val; + + /* if no flash supply we should leave things alone */ + if (!domain->supplies[RK3368_SOC_FLASH_SUPPLY_NUM].reg) + { + return; + } + + /* set flash0 iodomain to also use this framework instead of a special gpio. */ + val = RK3368_SOC_CON15_FLASH0 | (RK3368_SOC_CON15_FLASH0 << 16); + + if (rt_syscon_write(domain->grf, RK3368_SOC_CON15, val) < 0) + { + LOG_W("Couldn't update %s ctrl", "flash0"); + } +} + +static const struct rockchip_iodomain_soc_data soc_data_rk3368 = +{ + .grf_offset = 0x900, + .supply_names = + { + RT_NULL, /* Reserved */ + "dvp", /* DVPIO_VDD */ + "flash0", /* FLASH0_VDD (emmc) */ + "wifi", /* APIO2_VDD (sdio0) */ + RT_NULL, + "audio", /* APIO3_VDD */ + "sdcard", /* SDMMC0_VDD (sdmmc) */ + "gpio30", /* APIO1_VDD */ + "gpio1830", /* APIO4_VDD (gpujtag) */ + }, + .init = rk3368_iodomain_init, +}; + +static const struct rockchip_iodomain_soc_data soc_data_rk3368_pmu = +{ + .grf_offset = 0x100, + .supply_names = + { + [4] = + "pmu", /* PMU IO domain*/ + "vop", /* LCDC IO domain*/ + }, +}; + +static const struct rockchip_iodomain_soc_data soc_data_rk3399 = +{ + .grf_offset = 0xe640, + .supply_names = + { + "bt656", /* APIO2_VDD */ + "audio", /* APIO5_VDD */ + "sdmmc", /* SDMMC0_VDD */ + "gpio1830", /* APIO4_VDD */ + }, +}; + +#define RK3399_PMUGRF_CON0 0x180 +#define RK3399_PMUGRF_CON0_VSEL RT_BIT(8) +#define RK3399_PMUGRF_VSEL_SUPPLY_NUM 9 + +static void rk3399_pmu_iodomain_init(struct rockchip_iodomain *domain) +{ + rt_uint32_t val; + + /* if no pmu io supply we should leave things alone */ + if (!domain->supplies[RK3399_PMUGRF_VSEL_SUPPLY_NUM].reg) + { + return; + } + + /* set pmu io iodomain to also use this framework instead of a special gpio. */ + val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16); + + if (rt_syscon_write(domain->grf, RK3399_PMUGRF_CON0, val) < 0) + { + LOG_W("couldn't update %s ctrl", "pmu io iodomain"); + } +} + +static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = +{ + .grf_offset = 0x180, + .supply_names = + { + [9] = + "pmu1830", /* PMUIO2_VDD */ + }, + .init = rk3399_pmu_iodomain_init, +}; + +#define RK3568_PMU_GRF_IO_VSEL0 0x0140 +#define RK3568_PMU_GRF_IO_VSEL1 0x0144 +#define RK3568_PMU_GRF_IO_VSEL2 0x0148 + +static rt_err_t rk3568_iodomain_write(struct rockchip_iodomain_supply *supply, int uvolt) +{ + rt_uint32_t bit, is_3v3 = uvolt > MAX_VOLTAGE_1_8, val0, val1; + struct rockchip_iodomain *domain = supply->domain; + + switch (supply->idx) + { + case 0: /* pmuio1 */ + break; + + case 1: /* pmuio2 */ + bit = supply->idx; + val0 = RT_BIT(16 + bit) | (is_3v3 ? 0 : RT_BIT(bit)); + bit = supply->idx + 4; + val1 = RT_BIT(16 + bit) | (is_3v3 ? RT_BIT(bit) : 0); + + rt_syscon_write(domain->grf, RK3568_PMU_GRF_IO_VSEL2, val0); + rt_syscon_write(domain->grf, RK3568_PMU_GRF_IO_VSEL2, val1); + break; + + case 3: /* vccio2 */ + break; + + case 2: /* vccio1 */ + case 4: /* vccio3 */ + case 5: /* vccio4 */ + case 6: /* vccio5 */ + case 7: /* vccio6 */ + case 8: /* vccio7 */ + bit = supply->idx - 1; + val0 = RT_BIT(16 + bit) | (is_3v3 ? 0 : RT_BIT(bit)); + val1 = RT_BIT(16 + bit) | (is_3v3 ? RT_BIT(bit) : 0); + + rt_syscon_write(domain->grf, RK3568_PMU_GRF_IO_VSEL0, val0); + rt_syscon_write(domain->grf, RK3568_PMU_GRF_IO_VSEL1, val1); + break; + + default: + return -RT_EINVAL; + } + + return 0; +} + +static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = +{ + .grf_offset = 0x140, + .supply_names = + { + "pmuio1", + "pmuio2", + "vccio1", + "vccio2", + "vccio3", + "vccio4", + "vccio5", + "vccio6", + "vccio7", + }, + .write = rk3568_iodomain_write, +}; + +static const struct rockchip_iodomain_soc_data soc_data_rv1108 = +{ + .grf_offset = 0x404, + .supply_names = + { + [11] = + "vccio1", + "vccio2", + "vccio3", + "vccio5", + "vccio6", + }, +}; + +static const struct rockchip_iodomain_soc_data soc_data_rv1108_pmu = +{ + .grf_offset = 0x104, + .supply_names = + { + "pmu", + }, +}; + +static const struct rockchip_iodomain_soc_data soc_data_rv1126_pmu = +{ + .grf_offset = 0x140, + .supply_names = + { + [1] = + "vccio1", + "vccio2", + "vccio3", + "vccio4", + "vccio5", + "vccio6", + "vccio7", + "pmuio0", + "pmuio1", + }, +}; + +static rt_err_t rockchip_iodomain_write(struct rockchip_iodomain_supply *supply, int uvolt) +{ + rt_err_t err; + rt_uint32_t val; + struct rockchip_iodomain *domain = supply->domain; + + /* set value bit */ + val = (uvolt > MAX_VOLTAGE_1_8) ? 0 : 1; + val <<= supply->idx; + /* apply hiword-mask */ + val |= (RT_BIT(supply->idx) << 16); + + if ((err = rt_syscon_write(domain->grf, domain->soc_data->grf_offset, val))) + { + LOG_E("Couldn't write to GRF"); + } + + return err; +} + +static rt_err_t rockchip_iodomain_notify(struct rt_regulator_notifier *notifier, + rt_ubase_t msg, void *data) +{ + int uvolt = 0; + rt_err_t err; + struct rockchip_iodomain_supply *supply; + + supply = rt_container_of(notifier, struct rockchip_iodomain_supply, notifier); + + if (msg == RT_REGULATOR_MSG_VOLTAGE_CHANGE) + { + union rt_regulator_notifier_args *args = data; + + uvolt = rt_max(args->old_uvolt, args->max_uvolt); + } + else if (msg == RT_REGULATOR_MSG_VOLTAGE_CHANGE_ERR) + { + uvolt = (int)(rt_base_t)data; + } + + if (uvolt > MAX_VOLTAGE_3_3) + { + LOG_E("Voltage too high: %d", uvolt); + + if (msg == RT_REGULATOR_MSG_VOLTAGE_CHANGE) + { + return -RT_EIO; + } + } + + err = supply->domain->write(supply, uvolt); + + if (err && msg == RT_REGULATOR_MSG_VOLTAGE_CHANGE) + { + return -RT_EIO; + } + + LOG_D("Setting to %d done", uvolt); + + return err; +} + +static rt_err_t rockchip_iodomain_probe(struct rt_platform_device *pdev) +{ + rt_err_t err = RT_EOK; + struct rt_ofw_node *np, *grf_np; + struct rockchip_iodomain *domain = rt_calloc(1, sizeof(*domain)); + + if (!domain) + { + return -RT_ENOMEM; + } + + domain->dev = &pdev->parent; + domain->soc_data = pdev->id->data; + domain->write = domain->soc_data->write ? : rockchip_iodomain_write; + + np = pdev->parent.ofw_node; + + if ((grf_np = rt_ofw_get_parent(np))) + { + domain->grf = rt_syscon_find_by_ofw_node(grf_np); + rt_ofw_node_put(grf_np); + } + else + { + domain->grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,grf"); + } + + if (!domain->grf) + { + err = -RT_EIO; + + goto _fail; + } + + for (int i = 0; i < MAX_SUPPLIES; ++i) + { + int uvolt; + struct rt_regulator *reg; + struct rockchip_iodomain_supply *supply; + const char *supply_name = domain->soc_data->supply_names[i]; + + if (!supply_name) + { + continue; + } + + supply = &domain->supplies[i]; + reg = rt_regulator_get(domain->dev, supply_name); + + if (rt_is_err(reg)) + { + err = rt_ptr_err(reg); + goto _fail; + } + + if (!reg) + { + continue; + } + + uvolt = rt_regulator_get_voltage(reg); + + if (uvolt < 0) + { + /* Maybe is a switch */ + if (uvolt == -RT_ENOSYS) + { + rt_regulator_put(reg); + continue; + } + + LOG_E("Can't determine voltage: %s", supply_name); + + err = uvolt; + goto _fail; + } + + if (uvolt > MAX_VOLTAGE_3_3) + { + LOG_E("Voltage too high: %d", uvolt); + + err = -RT_EIO; + goto _fail; + } + + supply->idx = i; + supply->domain = domain; + supply->reg = reg; + supply->notifier.callback = rockchip_iodomain_notify; + + if (domain->write(supply, uvolt)) + { + rt_regulator_put(supply->reg); + supply->reg = RT_NULL; + + goto _fail; + } + + if ((err = rt_regulator_notifier_register(supply->reg, &supply->notifier))) + { + rt_regulator_put(supply->reg); + supply->reg = RT_NULL; + + goto _fail; + } + } + + if (domain->soc_data->init) + { + domain->soc_data->init(domain); + } + + return RT_EOK; + +_fail: + for (int i = MAX_SUPPLIES - 1; i >= 0; --i) + { + struct rockchip_iodomain_supply *supply = &domain->supplies[i]; + + if (!rt_is_err_or_null(supply->reg)) + { + rt_regulator_notifier_unregister(supply->reg, &supply->notifier); + rt_regulator_put(supply->reg); + } + } + + rt_free(domain); + + return err; +} + +static const struct rt_ofw_node_id rockchip_iodomain_ofw_ids[] = +{ + { .compatible = "rockchip,px30-io-voltage-domain", .data = &soc_data_px30 }, + { .compatible = "rockchip,px30-pmu-io-voltage-domain", .data = &soc_data_px30_pmu }, + { .compatible = "rockchip,rk3188-io-voltage-domain", .data = &soc_data_rk3188 }, + { .compatible = "rockchip,rk3228-io-voltage-domain", .data = &soc_data_rk3228 }, + { .compatible = "rockchip,rk3288-io-voltage-domain", .data = &soc_data_rk3288 }, + { .compatible = "rockchip,rk3308-io-voltage-domain", .data = &soc_data_rk3308 }, + { .compatible = "rockchip,rk3328-io-voltage-domain", .data = &soc_data_rk3328 }, + { .compatible = "rockchip,rk3368-io-voltage-domain", .data = &soc_data_rk3368 }, + { .compatible = "rockchip,rk3368-pmu-io-voltage-domain", .data = &soc_data_rk3368_pmu }, + { .compatible = "rockchip,rk3399-io-voltage-domain", .data = &soc_data_rk3399 }, + { .compatible = "rockchip,rk3399-pmu-io-voltage-domain", .data = &soc_data_rk3399_pmu }, + { .compatible = "rockchip,rk3568-pmu-io-voltage-domain", .data = &soc_data_rk3568_pmu }, + { .compatible = "rockchip,rv1108-io-voltage-domain", .data = &soc_data_rv1108 }, + { .compatible = "rockchip,rv1108-pmu-io-voltage-domain", .data = &soc_data_rv1108_pmu }, + { .compatible = "rockchip,rv1126-pmu-io-voltage-domain", .data = &soc_data_rv1126_pmu }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_iodomain_driver = +{ + .name = "rockchip-iodomain", + .ids = rockchip_iodomain_ofw_ids, + + .probe = rockchip_iodomain_probe, +}; + +static int rockchip_iodomain_register(void) +{ + rt_platform_driver_register(&rockchip_iodomain_driver); + + return 0; +} +INIT_PREV_EXPORT(rockchip_iodomain_register); diff --git a/bsp/rockchip/dm/spi/Kconfig b/bsp/rockchip/dm/spi/Kconfig new file mode 100755 index 00000000000..322bda3739b --- /dev/null +++ b/bsp/rockchip/dm/spi/Kconfig @@ -0,0 +1,18 @@ +config RT_SPI_ROCKCHIP_SFC + bool "Rockchip Serial Flash Controller (SFC)" + depends on RT_USING_DM + depends on RT_USING_SPI + depends on RT_USING_QSPI + depends on RT_USING_DMA + depends on RT_USING_PIN + depends on RT_USING_PINCTRL + default n + +config RT_SPI_ROCKCHIP + bool "Rockchip SPI controller driver" + depends on RT_USING_DM + depends on RT_USING_SPI + depends on RT_USING_DMA + depends on RT_USING_PIN + depends on RT_USING_PINCTRL + default n diff --git a/bsp/rockchip/dm/spi/SConscript b/bsp/rockchip/dm/spi/SConscript new file mode 100755 index 00000000000..72aa6f98c71 --- /dev/null +++ b/bsp/rockchip/dm/spi/SConscript @@ -0,0 +1,16 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +if GetDepend('RT_SPI_ROCKCHIP_SFC'): + src += ['spi-rockchip-sfc.c'] + +if GetDepend('RT_SPI_ROCKCHIP'): + src += ['spi-rockchip.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/spi/spi-rockchip-sfc.c b/bsp/rockchip/dm/spi/spi-rockchip-sfc.c new file mode 100755 index 00000000000..3b9c6a4f737 --- /dev/null +++ b/bsp/rockchip/dm/spi/spi-rockchip-sfc.c @@ -0,0 +1,1004 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include "dev_spi_dm.h" + +#define DBG_TAG "spi.rockchip.sfc" +#define DBG_LVL DBG_INFO +#include + +#include +#include + +/* System control */ +#define SFC_CTRL 0x0 +#define SFC_CTRL_PHASE_SEL_NEGETIVE RT_BIT(1) +#define SFC_CTRL_CMD_BITS_SHIFT 8 +#define SFC_CTRL_ADDR_BITS_SHIFT 10 +#define SFC_CTRL_DATA_BITS_SHIFT 12 + +/* Interrupt mask */ +#define SFC_IMR 0x4 +#define SFC_IMR_RX_FULL RT_BIT(0) +#define SFC_IMR_RX_UFLOW RT_BIT(1) +#define SFC_IMR_TX_OFLOW RT_BIT(2) +#define SFC_IMR_TX_EMPTY RT_BIT(3) +#define SFC_IMR_TRAN_FINISH RT_BIT(4) +#define SFC_IMR_BUS_ERR RT_BIT(5) +#define SFC_IMR_NSPI_ERR RT_BIT(6) +#define SFC_IMR_DMA RT_BIT(7) + +/* Interrupt clear */ +#define SFC_ICLR 0x8 +#define SFC_ICLR_RX_FULL RT_BIT(0) +#define SFC_ICLR_RX_UFLOW RT_BIT(1) +#define SFC_ICLR_TX_OFLOW RT_BIT(2) +#define SFC_ICLR_TX_EMPTY RT_BIT(3) +#define SFC_ICLR_TRAN_FINISH RT_BIT(4) +#define SFC_ICLR_BUS_ERR RT_BIT(5) +#define SFC_ICLR_NSPI_ERR RT_BIT(6) +#define SFC_ICLR_DMA RT_BIT(7) + +/* FIFO threshold level */ +#define SFC_FTLR 0xc +#define SFC_FTLR_TX_SHIFT 0 +#define SFC_FTLR_TX_MASK 0x1f +#define SFC_FTLR_RX_SHIFT 8 +#define SFC_FTLR_RX_MASK 0x1f + +/* Reset FSM and FIFO */ +#define SFC_RCVR 0x10 +#define SFC_RCVR_RESET RT_BIT(0) + +/* Enhanced mode */ +#define SFC_AX 0x14 + +/* Address Bit number */ +#define SFC_ABIT 0x18 + +/* Interrupt status */ +#define SFC_ISR 0x1c +#define SFC_ISR_RX_FULL_SHIFT RT_BIT(0) +#define SFC_ISR_RX_UFLOW_SHIFT RT_BIT(1) +#define SFC_ISR_TX_OFLOW_SHIFT RT_BIT(2) +#define SFC_ISR_TX_EMPTY_SHIFT RT_BIT(3) +#define SFC_ISR_TX_FINISH_SHIFT RT_BIT(4) +#define SFC_ISR_BUS_ERR_SHIFT RT_BIT(5) +#define SFC_ISR_NSPI_ERR_SHIFT RT_BIT(6) +#define SFC_ISR_DMA_SHIFT RT_BIT(7) + +/* FIFO status */ +#define SFC_FSR 0x20 +#define SFC_FSR_TX_IS_FULL RT_BIT(0) +#define SFC_FSR_TX_IS_EMPTY RT_BIT(1) +#define SFC_FSR_RX_IS_EMPTY RT_BIT(2) +#define SFC_FSR_RX_IS_FULL RT_BIT(3) +#define SFC_FSR_TXLV_MASK RT_GENMASK(12, 8) +#define SFC_FSR_TXLV_SHIFT 8 +#define SFC_FSR_RXLV_MASK RT_GENMASK(20, 16) +#define SFC_FSR_RXLV_SHIFT 16 + +/* FSM status */ +#define SFC_SR 0x24 +#define SFC_SR_IS_IDLE 0x0 +#define SFC_SR_IS_BUSY 0x1 + +/* Raw interrupt status */ +#define SFC_RISR 0x28 +#define SFC_RISR_RX_FULL RT_BIT(0) +#define SFC_RISR_RX_UNDERFLOW RT_BIT(1) +#define SFC_RISR_TX_OVERFLOW RT_BIT(2) +#define SFC_RISR_TX_EMPTY RT_BIT(3) +#define SFC_RISR_TRAN_FINISH RT_BIT(4) +#define SFC_RISR_BUS_ERR RT_BIT(5) +#define SFC_RISR_NSPI_ERR RT_BIT(6) +#define SFC_RISR_DMA RT_BIT(7) + +/* Version */ +#define SFC_VER 0x2c +#define SFC_VER_3 0x3 +#define SFC_VER_4 0x4 +#define SFC_VER_5 0x5 +#define SFC_VER_6 0x6 + +/* Delay line controller resiter */ +#define SFC_DLL_CTRL0 0x3c +#define SFC_DLL_CTRL0_SCLK_SMP_DLL RT_BIT(15) +#define SFC_DLL_CTRL0_DLL_MAX_VER4 0xffU +#define SFC_DLL_CTRL0_DLL_MAX_VER5 0x1ffU + +/* Master trigger */ +#define SFC_DMA_TRIGGER 0x80 +#define SFC_DMA_TRIGGER_START 1 + +/* Src or Dst addr for master */ +#define SFC_DMA_ADDR 0x84 + +/* Length control register extension 32GB */ +#define SFC_LEN_CTRL 0x88 +#define SFC_LEN_CTRL_TRB_SEL 1 +#define SFC_LEN_EXT 0x8c + +/* Command */ +#define SFC_CMD 0x100 +#define SFC_CMD_IDX_SHIFT 0 +#define SFC_CMD_DUMMY_SHIFT 8 +#define SFC_CMD_DIR_SHIFT 12 +#define SFC_CMD_DIR_RD 0 +#define SFC_CMD_DIR_WR 1 +#define SFC_CMD_ADDR_SHIFT 14 +#define SFC_CMD_ADDR_0BITS 0 +#define SFC_CMD_ADDR_24BITS 1 +#define SFC_CMD_ADDR_32BITS 2 +#define SFC_CMD_ADDR_XBITS 3 +#define SFC_CMD_TRAN_BYTES_SHIFT 16 +#define SFC_CMD_CS_SHIFT 30 + +/* Address */ +#define SFC_ADDR 0x104 + +/* Data */ +#define SFC_DATA 0x108 + +/* The controller and documentation reports that it supports up to 4 CS + * devices (0-3), however I have only been able to test a single CS (CS 0) + * due to the configuration of my device. + */ +#define SFC_MAX_CHIPSELECT_NUM 4 + +/* The SFC can transfer max 16KB - 1 at one time + * we set it to 15.5KB here for alignment. + */ +#define SFC_MAX_IOSIZE_VER3 (512 * 31) +#define SFC_MAX_IOSIZE_VER4 (0xffffffffU) + +/* DMA is only enabled for large data transmission */ +#define SFC_DMA_TRANS_THRETHOLD 0x40 + +/* Maximum clock values from datasheet suggest keeping clock value under + * 150MHz. No minimum or average value is suggested. + */ +#define SFC_MAX_SPEED (150 * 1000 * 1000) +#define SFC_DLL_THRESHOLD_RATE (50 * 1000 * 1000) + +#define SFC_DLL_TRANING_STEP 10 /* Training step */ +#define SFC_DLL_TRANING_VALID_WINDOW 80 /* Valid DLL winbow */ + +#define ROCKCHIP_AUTOSUSPEND_DELAY 2000 + +struct rockchip_sfc +{ + struct rt_spi_bus parent; + struct rt_platform_device *pdev; + + struct rt_clk *clk; + struct rt_clk *hclk; + + int irq; + void *regs; + + void *dma_buffer; + rt_ubase_t dma_buffer_phy; + rt_bool_t use_dma; + + rt_uint32_t frequency; + rt_uint32_t max_speed_hz; + rt_uint32_t max_iosize; + rt_uint32_t dll_cells; + rt_uint16_t version; + + struct rt_completion done; +}; + +#define raw_to_rockchip_sfc(raw) rt_container_of(raw, struct rockchip_sfc, parent) + +rt_inline rt_uint32_t rockchip_sfc_readl(struct rockchip_sfc *rk_sfc, int offset) +{ + return HWREG32(rk_sfc->regs + offset); +} + +rt_inline void rockchip_sfc_writel(struct rockchip_sfc *rk_sfc, int offset, rt_uint32_t value) +{ + HWREG32(rk_sfc->regs + offset) = value; +} + +static rt_err_t rockchip_sfc_poll(struct rockchip_sfc *rk_sfc, int offset, + rt_uint32_t flag, rt_bool_t is_set, + rt_uint32_t delay_us, rt_int32_t timeout_us) +{ + if (!delay_us) + { + delay_us = 1; + } + + for (; timeout_us > 0; timeout_us -= delay_us) + { + if (is_set) + { + if (rockchip_sfc_readl(rk_sfc, offset) & flag) + { + return RT_EOK; + } + } + else + { + if (!(rockchip_sfc_readl(rk_sfc, offset) & flag)) + { + return RT_EOK; + } + } + + rt_hw_us_delay(delay_us); + rt_hw_cpu_relax(); + } + + return -RT_ETIMEOUT; +} + +static rt_err_t rockchip_sfc_reset(struct rockchip_sfc *rk_sfc) +{ + rt_err_t err; + + rockchip_sfc_writel(rk_sfc, SFC_RCVR, SFC_RCVR_RESET); + + err = rockchip_sfc_poll(rk_sfc, SFC_RCVR, SFC_RCVR_RESET, RT_FALSE, + 20, 1000000L); + + if (err) + { + LOG_E("SFC reset never finished"); + } + + /* Still need to clear the masked interrupt from RISR */ + rockchip_sfc_writel(rk_sfc, SFC_ICLR, 0xffffffff); + + return err; +} + +static rt_uint16_t rockchip_sfc_get_version(struct rockchip_sfc *rk_sfc) +{ + return (rt_uint16_t)(rockchip_sfc_readl(rk_sfc, SFC_VER) & 0xffff); +} + +static rt_uint32_t rockchip_sfc_get_max_iosize(struct rockchip_sfc *rk_sfc) +{ + return SFC_MAX_IOSIZE_VER3; +} + +static rt_uint32_t rockchip_sfc_get_max_dll_cells(struct rockchip_sfc *rk_sfc) +{ + switch (rockchip_sfc_get_version(rk_sfc)) + { + case SFC_VER_6: + case SFC_VER_5: + return SFC_DLL_CTRL0_DLL_MAX_VER5; + + case SFC_VER_4: + return SFC_DLL_CTRL0_DLL_MAX_VER4; + + default: + return 0; + } +} + +static void rockchip_sfc_set_delay_lines(struct rockchip_sfc *rk_sfc, + rt_uint16_t cells) +{ + rt_uint32_t val = 0; + rt_uint16_t cell_max = (rt_uint16_t)rockchip_sfc_get_max_dll_cells(rk_sfc); + + if (cells > cell_max) + { + cells = cell_max; + } + + if (cells) + { + val = SFC_DLL_CTRL0_SCLK_SMP_DLL | cells; + } + + rockchip_sfc_writel(rk_sfc, SFC_DLL_CTRL0, val); +} + +static void rockchip_sfc_irq_unmask(struct rockchip_sfc *rk_sfc, rt_uint32_t mask) +{ + /* Enable transfer complete interrupt */ + rockchip_sfc_writel(rk_sfc, SFC_IMR, + rockchip_sfc_readl(rk_sfc, SFC_IMR) & (~mask)); +} + +static void rockchip_sfc_irq_mask(struct rockchip_sfc *rk_sfc, rt_uint32_t mask) +{ + /* Disable transfer finish interrupt */ + rockchip_sfc_writel(rk_sfc, SFC_IMR, + rockchip_sfc_readl(rk_sfc, SFC_IMR) | mask); +} + +static rt_err_t rockchip_sfc_init(struct rockchip_sfc *rk_sfc) +{ + rockchip_sfc_writel(rk_sfc, SFC_CTRL, 0); + rockchip_sfc_writel(rk_sfc, SFC_ICLR, 0xffffffff); + + rockchip_sfc_irq_mask(rk_sfc, 0xFFFFFFFF); + + if (rockchip_sfc_get_version(rk_sfc) >= SFC_VER_4) + { + rockchip_sfc_writel(rk_sfc, SFC_LEN_CTRL, SFC_LEN_CTRL_TRB_SEL); + } + + return RT_EOK; +} + +static rt_ssize_t rockchip_sfc_wait_txfifo_ready(struct rockchip_sfc *rk_sfc, + rt_uint32_t timeout_us) +{ + if (rockchip_sfc_poll(rk_sfc, SFC_FSR, SFC_FSR_TXLV_MASK, RT_TRUE, 0, timeout_us)) + { + LOG_D("Wait tx fifo timeout"); + + return -RT_ETIMEOUT; + } + + return (rockchip_sfc_readl(rk_sfc, SFC_FSR) & SFC_FSR_TXLV_MASK) >> SFC_FSR_TXLV_SHIFT; +} + +static rt_ssize_t rockchip_sfc_wait_rxfifo_ready(struct rockchip_sfc *rk_sfc, + rt_uint32_t timeout_us) +{ + if (rockchip_sfc_poll(rk_sfc, SFC_FSR, SFC_FSR_RXLV_MASK, RT_TRUE, 0, timeout_us)) + { + LOG_D("Wait rx fifo timeout"); + + return -RT_ETIMEOUT; + } + + return (rockchip_sfc_readl(rk_sfc, SFC_FSR) & SFC_FSR_RXLV_MASK) >> SFC_FSR_RXLV_SHIFT; +} + +static rt_ssize_t rockchip_sfc_write_fifo(struct rockchip_sfc *rk_sfc, + const rt_uint8_t *buf, int len) +{ + int tx_level; + rt_uint8_t bytes = len & 0x3; + rt_uint32_t dwords, write_words, tmp = 0; + + dwords = len >> 2; + while (dwords) + { + if ((tx_level = rockchip_sfc_wait_txfifo_ready(rk_sfc, 1000)) < 0) + { + return tx_level; + } + + write_words = rt_min_t(rt_uint32_t, tx_level, dwords); + + for (int i = 0; i < write_words; ++i) + { + rockchip_sfc_writel(rk_sfc, SFC_DATA, ((rt_uint32_t *)buf)[i]); + } + + buf += write_words << 2; + dwords -= write_words; + } + + /* write the rest non word aligned bytes */ + if (bytes) + { + if ((tx_level = rockchip_sfc_wait_txfifo_ready(rk_sfc, 1000)) < 0) + { + return tx_level; + } + + rt_memcpy(&tmp, buf, bytes); + rockchip_sfc_writel(rk_sfc, SFC_DATA, tmp); + } + + return len; +} + +static rt_ssize_t rockchip_sfc_read_fifo(struct rockchip_sfc *rk_sfc, + rt_uint8_t *buf, int len) +{ + int rx_level; + rt_uint8_t bytes = len & 0x3; + rt_uint32_t dwords, read_words, tmp = 0; + + /* word aligned access only */ + dwords = len >> 2; + while (dwords) + { + if ((rx_level = rockchip_sfc_wait_rxfifo_ready(rk_sfc, 1000)) < 0) + { + return rx_level; + } + + read_words = rt_min_t(rt_uint32_t, rx_level, dwords); + + for (int i = 0; i < read_words; ++i) + { + ((rt_uint32_t *)buf)[i] = rockchip_sfc_readl(rk_sfc, SFC_DATA); + } + + buf += read_words << 2; + dwords -= read_words; + } + + /* read the rest non word aligned bytes */ + if (bytes) + { + if ((rx_level = rockchip_sfc_wait_rxfifo_ready(rk_sfc, 1000)) < 0) + { + return rx_level; + } + + tmp = rockchip_sfc_readl(rk_sfc, SFC_DATA); + rt_memcpy(buf, &tmp, bytes); + } + + return len; +} + +static rt_size_t rockchip_sfc_fifo_transfer_dma(struct rockchip_sfc *rk_sfc, + rt_ubase_t dma_buf, rt_size_t len) +{ + rockchip_sfc_writel(rk_sfc, SFC_ICLR, 0xffffffff); + rockchip_sfc_writel(rk_sfc, SFC_DMA_ADDR, (rt_uint32_t)dma_buf); + rockchip_sfc_writel(rk_sfc, SFC_DMA_TRIGGER, SFC_DMA_TRIGGER_START); + + return len; +} + +static rt_ssize_t rockchip_sfc_xfer_data_poll(struct rockchip_sfc *rk_sfc, + struct rt_spi_message *xfer) +{ + if (xfer->send_buf) + { + return rockchip_sfc_write_fifo(rk_sfc, xfer->send_buf, xfer->length); + } + else if (xfer->recv_buf) + { + return rockchip_sfc_read_fifo(rk_sfc, xfer->recv_buf, xfer->length); + } + + return -RT_EINVAL; +} + +static rt_ssize_t rockchip_sfc_xfer_data_dma(struct rockchip_sfc *rk_sfc, + struct rt_spi_message *xfer) +{ + rt_ssize_t res = -RT_EINVAL, len = xfer->length; + + if (xfer->send_buf) + { + rt_memcpy(rk_sfc->dma_buffer, xfer->send_buf, len); + + res = rockchip_sfc_fifo_transfer_dma(rk_sfc, rk_sfc->dma_buffer_phy, len); + + if (rt_completion_wait(&rk_sfc->done, rt_tick_from_millisecond(2000))) + { + LOG_E("DMA wait for %s transfer finish timeout", "tx"); + res = -RT_ETIMEOUT; + + goto _out_irq; + } + } + + if (xfer->recv_buf) + { + res = rockchip_sfc_fifo_transfer_dma(rk_sfc, rk_sfc->dma_buffer_phy, len); + + if (rt_completion_wait(&rk_sfc->done, rt_tick_from_millisecond(2000))) + { + LOG_E("DMA wait for %s transfer finish timeout", "rx"); + res = -RT_ETIMEOUT; + } + } + +_out_irq: + rockchip_sfc_irq_mask(rk_sfc, SFC_IMR_DMA); + + if (res > 0 && xfer->recv_buf) + { + rt_memcpy(xfer->recv_buf, rk_sfc->dma_buffer, len); + } + + return res; +} + +static rt_err_t rockchip_sfc_xfer_done(struct rockchip_sfc *rk_sfc, + rt_uint32_t timeout_us) +{ + if (rockchip_sfc_poll(rk_sfc, SFC_SR, SFC_SR_IS_BUSY, RT_FALSE, + 20, timeout_us)) + { + LOG_E("Wait sfc idle timeout"); + rockchip_sfc_reset(rk_sfc); + + return -RT_EIO; + } + + return RT_EOK; +} + +static rt_err_t rockchip_sfc_xfer_setup(struct rockchip_sfc *rk_sfc, + struct rt_spi_device *spi_dev, struct rt_qspi_message *qspi_xfer) +{ + rt_uint32_t ctrl = 0, cmd = 0; + rt_ssize_t len = qspi_xfer->parent.length; + + /* instruction */ + cmd = qspi_xfer->instruction.content; + ctrl |= (qspi_xfer->instruction.qspi_lines >> 1) << SFC_CTRL_CMD_BITS_SHIFT; + + /* address */ + if (qspi_xfer->address.size) + { + if (qspi_xfer->address.size == 4) + { + cmd |= SFC_CMD_ADDR_32BITS << SFC_CMD_ADDR_SHIFT; + } + else if (qspi_xfer->address.size == 3) + { + cmd |= SFC_CMD_ADDR_24BITS << SFC_CMD_ADDR_SHIFT; + } + else + { + cmd |= SFC_CMD_ADDR_XBITS << SFC_CMD_ADDR_SHIFT; + rockchip_sfc_writel(rk_sfc, SFC_ABIT, qspi_xfer->address.size * 8 - 1); + } + + ctrl |= ((qspi_xfer->address.qspi_lines >> 1) << SFC_CTRL_ADDR_BITS_SHIFT); + } + + /* data */ + if (rk_sfc->version >= SFC_VER_4) + { + /* Clear it if no data to transfer */ + rockchip_sfc_writel(rk_sfc, SFC_LEN_EXT, len); + } + else + { + cmd |= len << SFC_CMD_TRAN_BYTES_SHIFT; + } + if (len) + { + if (qspi_xfer->parent.send_buf) + { + cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT; + } + + ctrl |= ((qspi_xfer->qspi_data_lines >> 1) << SFC_CTRL_DATA_BITS_SHIFT); + } + if (!len && qspi_xfer->address.size) + { + cmd |= SFC_CMD_DIR_WR << SFC_CMD_DIR_SHIFT; + } + + /* controller */ + ctrl |= SFC_CTRL_PHASE_SEL_NEGETIVE; + cmd |= spi_dev->chip_select[0] << SFC_CMD_CS_SHIFT; + + rockchip_sfc_writel(rk_sfc, SFC_CTRL, ctrl); + rockchip_sfc_writel(rk_sfc, SFC_CMD, cmd); + + if (qspi_xfer->address.size) + { + rockchip_sfc_writel(rk_sfc, SFC_ADDR, qspi_xfer->address.content); + } + + return RT_EOK; +} + +static void rockchip_sfc_adjust_op_work(struct rt_qspi_message *qspi_xfer) +{ + if (qspi_xfer->alternate_bytes.size && !qspi_xfer->address.size) + { + /* + * SFC not support output DUMMY cycles right after CMD cycles, so + * treat it as ADDR cycles. + */ + qspi_xfer->address.size = qspi_xfer->alternate_bytes.size; + qspi_xfer->address.qspi_lines = qspi_xfer->alternate_bytes.qspi_lines; + qspi_xfer->address.content = 0xffffffff; + + qspi_xfer->alternate_bytes.size = 0; + } +} + +static rt_err_t rockchip_sfc_exec_op_bypass(struct rockchip_sfc *rk_sfc, + struct rt_spi_device *spi_dev, struct rt_qspi_message *qspi_xfer) +{ + rt_uint32_t res, len; + + len = rt_min_t(rt_uint32_t, qspi_xfer->parent.length, rk_sfc->max_iosize); + + rockchip_sfc_adjust_op_work(qspi_xfer); + rockchip_sfc_xfer_setup(rk_sfc, spi_dev, qspi_xfer); + res = rockchip_sfc_xfer_data_poll(rk_sfc, &qspi_xfer->parent); + + if (res != len) + { + LOG_E("xfer data failed ret %d", res); + + return -RT_EIO; + } + + return rockchip_sfc_xfer_done(rk_sfc, 100000); +} + +static void rockchip_sfc_delay_lines_tuning(struct rockchip_sfc *rk_sfc, + struct rt_spi_device *spi_dev) +{ + rt_uint8_t id[3], id_temp[3]; + rt_bool_t dll_valid = RT_FALSE; + rt_uint16_t right, left = 0, step = SFC_DLL_TRANING_STEP; + rt_uint16_t cell_max = (rt_uint16_t)rockchip_sfc_get_max_dll_cells(rk_sfc); + struct rt_qspi_message qspi_xfer = {}; + struct rt_spi_message *xfer = &qspi_xfer.parent; + + rt_clk_set_rate(rk_sfc->clk, SFC_DLL_THRESHOLD_RATE); + + qspi_xfer.instruction.content = 0x9f; + qspi_xfer.qspi_data_lines = 1; + + xfer->recv_buf = &id; + xfer->length = sizeof(id); + xfer->cs_take = 1; + xfer->cs_release = 1; + rockchip_sfc_exec_op_bypass(rk_sfc, spi_dev, &qspi_xfer); + + if ((0xff == id[0] && 0xff == id[1]) || (0x00 == id[0] && 0x00 == id[1])) + { + rt_clk_set_rate(rk_sfc->clk, rk_sfc->max_speed_hz); + + return; + } + + rt_clk_set_rate(rk_sfc->clk, rk_sfc->max_speed_hz); + xfer->recv_buf = &id_temp; + xfer->length = sizeof(id_temp); + + for (right = 0; right <= cell_max; right += step) + { + int res; + + rockchip_sfc_set_delay_lines(rk_sfc, right); + rockchip_sfc_exec_op_bypass(rk_sfc, spi_dev, &qspi_xfer); + + res = rt_memcmp(&id, &id_temp, sizeof(id)); + + if (dll_valid && res) + { + right -= step; + break; + } + + if (!dll_valid && !res) + { + left = right; + } + + if (!res) + { + dll_valid = RT_TRUE; + } + + /* Add cell_max to loop */ + if (right == cell_max) + { + break; + } + if (right + step > cell_max) + { + right = cell_max - step; + } + } + + if (dll_valid && (right - left) >= SFC_DLL_TRANING_VALID_WINDOW) + { + if (left == 0 && right < cell_max) + { + rk_sfc->dll_cells = left + (right - left) * 2 / 5; + } + else + { + rk_sfc->dll_cells = left + (right - left) / 2; + } + } + else + { + rk_sfc->dll_cells = 0; + } + + if (rk_sfc->dll_cells) + { + rockchip_sfc_set_delay_lines(rk_sfc, (rt_uint16_t)rk_sfc->dll_cells); + } + else + { + LOG_E("%d %d dll training failed in %dMHz, reduce the frequency", + left, right, rk_sfc->max_speed_hz); + + rockchip_sfc_set_delay_lines(rk_sfc, 0); + rt_clk_set_rate(rk_sfc->clk, SFC_DLL_THRESHOLD_RATE); + rk_sfc->max_speed_hz = rt_clk_get_rate(rk_sfc->clk); + } +} + +static rt_err_t rockchip_sfc_configure(struct rt_spi_device *device, + struct rt_spi_configuration *conf) +{ + rt_err_t err; + struct rockchip_sfc *rk_sfc = raw_to_rockchip_sfc(device->bus); + + if (conf->max_hz != rk_sfc->frequency) + { + if ((err = rt_clk_set_rate(rk_sfc->clk, rk_sfc->max_speed_hz))) + { + return err; + } + + rk_sfc->frequency = rk_sfc->max_speed_hz; + + if (rockchip_sfc_get_version(rk_sfc) >= SFC_VER_4) + { + if (rt_clk_get_rate(rk_sfc->clk) > SFC_DLL_THRESHOLD_RATE) + { + rockchip_sfc_delay_lines_tuning(rk_sfc, device); + } + else + { + rockchip_sfc_set_delay_lines(rk_sfc, 0); + } + } + } + + return RT_EOK; +} + +static rt_ssize_t rockchip_sfc_xfer(struct rt_spi_device *device, + struct rt_spi_message *xfer) +{ + rt_err_t err; + rt_ssize_t res, len = xfer->length; + struct rockchip_sfc *rk_sfc = raw_to_rockchip_sfc(device->bus); + struct rt_qspi_message *qspi_xfer = rt_container_of(xfer, struct rt_qspi_message, parent); + + rockchip_sfc_adjust_op_work(qspi_xfer); + rockchip_sfc_xfer_setup(rk_sfc, device, qspi_xfer); + + if (qspi_xfer->alternate_bytes.size > 0) + { + rt_uint8_t buf[4]; + rt_size_t size = qspi_xfer->alternate_bytes.size / 8; + + rt_memcpy(buf, &qspi_xfer->alternate_bytes.content, size); + rockchip_sfc_write_fifo(rk_sfc, buf, size); + } + + if (len > 0) + { + if (rk_sfc->use_dma && len >= SFC_DMA_TRANS_THRETHOLD && !(len & 0x3)) + { + rockchip_sfc_irq_unmask(rk_sfc, SFC_IMR_DMA); + res = rockchip_sfc_xfer_data_dma(rk_sfc, xfer); + } + else + { + res = rockchip_sfc_xfer_data_poll(rk_sfc, xfer); + } + + if (res != len) + { + LOG_E("xfer data failed"); + return -RT_EIO; + } + } + + if ((err = rockchip_sfc_xfer_done(rk_sfc, 100000))) + { + res = err; + } + + return res; +} + +static const struct rt_spi_ops rockchip_sfc_ops = +{ + .configure = rockchip_sfc_configure, + .xfer = rockchip_sfc_xfer, +}; + +static void rockchip_sfc_isr(int irqno, void *param) +{ + rt_uint32_t isr; + struct rockchip_sfc *rk_sfc = param; + + isr = rockchip_sfc_readl(rk_sfc, SFC_RISR); + /* Clear interrupt */ + rockchip_sfc_writel(rk_sfc, SFC_ICLR, isr); + + if (isr & SFC_RISR_DMA) + { + rt_completion_done(&rk_sfc->done); + } +} + +static void rockchip_sfc_free(struct rockchip_sfc *rk_sfc) +{ + if (rk_sfc->regs) + { + rt_iounmap(rk_sfc->regs); + } + + if (!rt_is_err_or_null(rk_sfc->clk)) + { + rt_clk_put(rk_sfc->clk); + } + + if (!rt_is_err_or_null(rk_sfc->hclk)) + { + rt_clk_put(rk_sfc->hclk); + } + + if (rk_sfc->dma_buffer) + { + rt_dma_free_coherent(&rk_sfc->pdev->parent, + SFC_MAX_IOSIZE_VER3, rk_sfc->dma_buffer, rk_sfc->dma_buffer_phy); + } + + rt_free(rk_sfc); +} + +static rt_err_t rockchip_sfc_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + const char *bus_name; + struct rt_device *dev = &pdev->parent; + struct rockchip_sfc *rk_sfc = rt_calloc(1, sizeof(*rk_sfc)); + + if (!rk_sfc) + { + return -RT_ENOMEM; + } + + rk_sfc->pdev = pdev; + rk_sfc->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_sfc->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_sfc->clk = rt_clk_get_by_name(dev, "clk_sfc"); + + if (rt_is_err(rk_sfc->clk)) + { + err = rt_ptr_err(rk_sfc->clk); + goto _fail; + } + + rk_sfc->hclk = rt_clk_get_by_name(dev, "hclk_sfc"); + + if (rt_is_err(rk_sfc->hclk)) + { + err = rt_ptr_err(rk_sfc->hclk); + goto _fail; + } + + rk_sfc->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_sfc->irq < 0) + { + err = rk_sfc->irq; + goto _fail; + } + + rk_sfc->use_dma = !rt_dm_dev_prop_read_bool(dev, "rockchip,sfc-no-dma"); + + if (rk_sfc->use_dma) + { + rk_sfc->dma_buffer = rt_dma_alloc_coherent(dev, + SFC_MAX_IOSIZE_VER3, &rk_sfc->dma_buffer_phy); + + if (!rk_sfc->dma_buffer) + { + err = -RT_ENOMEM; + LOG_E("Could not alloc DMA memory witch cache"); + + goto _fail; + } + } + + if ((err = rt_clk_prepare_enable(rk_sfc->hclk))) + { + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_sfc->clk))) + { + goto _fail; + } + +#ifdef RT_USING_OFW + if (rt_ofw_bootargs_select("rockchip.thunder_boot", 0)) + { + if (rockchip_sfc_poll(rk_sfc, SFC_SR, SFC_SR_IS_BUSY, RT_FALSE, 10, 500000)) + { + LOG_E("Wait for SFC idle timeout"); + } + } +#endif + + if ((err = rockchip_sfc_init(rk_sfc))) + { + goto _fail; + } + + rk_sfc->max_iosize = rockchip_sfc_get_max_iosize(rk_sfc); + rk_sfc->version = rockchip_sfc_get_version(rk_sfc); + + rk_sfc->max_speed_hz = SFC_MAX_SPEED; + rk_sfc->parent.num_chipselect = SFC_MAX_CHIPSELECT_NUM; + rt_completion_init(&rk_sfc->done); + + dev->user_data = rk_sfc; + + rk_sfc->parent.parent.ofw_node = dev->ofw_node; + + rt_dm_dev_set_name_auto(&rk_sfc->parent.parent, "qspi"); + bus_name = rt_dm_dev_get_name(&rk_sfc->parent.parent); + + rt_hw_interrupt_install(rk_sfc->irq, rockchip_sfc_isr, rk_sfc, bus_name); + rt_hw_interrupt_umask(rk_sfc->irq); + + if ((err = rt_qspi_bus_register(&rk_sfc->parent, bus_name, &rockchip_sfc_ops))) + { + goto _fail; + } + + return RT_EOK; + +_fail: + rockchip_sfc_free(rk_sfc); + + return err; +} + +static rt_err_t rockchip_sfc_remove(struct rt_platform_device *pdev) +{ + struct rockchip_sfc *rk_sfc = pdev->parent.user_data; + + rt_hw_interrupt_mask(rk_sfc->irq); + rt_pic_detach_irq(rk_sfc->irq, rk_sfc); + + rt_device_unregister(&rk_sfc->parent.parent); + + rockchip_sfc_free(rk_sfc); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_sfc_ofw_ids[] = +{ + { .compatible = "rockchip,sfc", }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_sfc_driver = +{ + .name = "rockchip-sfc", + .ids = rockchip_sfc_ofw_ids, + + .probe = rockchip_sfc_probe, + .remove = rockchip_sfc_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_sfc_driver); diff --git a/bsp/rockchip/dm/spi/spi-rockchip.c b/bsp/rockchip/dm/spi/spi-rockchip.c new file mode 100755 index 00000000000..41499e82206 --- /dev/null +++ b/bsp/rockchip/dm/spi/spi-rockchip.c @@ -0,0 +1,1295 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + * 2023-02-25 GuEe-GUI add DMA support + */ + +#include "dev_spi_dm.h" + +#define DBG_TAG "spi.rockchip" +#define DBG_LVL DBG_INFO +#include + +#include + +#define ROCKCHIP_SPI_CLR_BITS(reg, bits) HWREG32(reg) = HWREG32(reg) & ~(bits) +#define ROCKCHIP_SPI_SET_BITS(reg, bits) HWREG32(reg) = HWREG32(reg) | (bits) + +/* SPI register offsets */ +#define ROCKCHIP_SPI_CTRLR0 0x0000 +#define ROCKCHIP_SPI_CTRLR1 0x0004 +#define ROCKCHIP_SPI_SSIENR 0x0008 +#define ROCKCHIP_SPI_SER 0x000c +#define ROCKCHIP_SPI_BAUDR 0x0010 +#define ROCKCHIP_SPI_TXFTLR 0x0014 +#define ROCKCHIP_SPI_RXFTLR 0x0018 +#define ROCKCHIP_SPI_TXFLR 0x001c +#define ROCKCHIP_SPI_RXFLR 0x0020 +#define ROCKCHIP_SPI_SR 0x0024 +#define ROCKCHIP_SPI_IPR 0x0028 +#define ROCKCHIP_SPI_IMR 0x002c +#define ROCKCHIP_SPI_ISR 0x0030 +#define ROCKCHIP_SPI_RISR 0x0034 +#define ROCKCHIP_SPI_ICR 0x0038 +#define ROCKCHIP_SPI_DMACR 0x003c +#define ROCKCHIP_SPI_DMATDLR 0x0040 +#define ROCKCHIP_SPI_DMARDLR 0x0044 +#define ROCKCHIP_SPI_VERSION 0x0048 +#define ROCKCHIP_SPI_TXDR 0x0400 +#define ROCKCHIP_SPI_RXDR 0x0800 + +/* Bit fields in CTRLR0 */ +#define CR0_DFS_OFFSET 0 +#define CR0_DFS_4BIT 0x0 +#define CR0_DFS_8BIT 0x1 +#define CR0_DFS_16BIT 0x2 + +#define CR0_CFS_OFFSET 2 + +#define CR0_SCPH_OFFSET 6 +#define CR0_SCPH_START_EDGE 0x1 +#define CR0_SCPH_MIDDLE_EDGE 0x0 + +#define CR0_SCPOL_OFFSET 7 +#define CR0_SCPOL_HIGH 0x1 +#define CR0_SCPOL_LOW 0x0 + +#define CR0_CSM_OFFSET 8 +#define CR0_CSM_KEEP 0x0 +/* ss_n be high for half sclk_out cycles */ +#define CR0_CSM_HALF 0X1 +/* ss_n be high for one sclk_out cycle */ +#define CR0_CSM_ONE 0x2 + +/* ss_n to sclk_out delay */ +#define CR0_SSD_OFFSET 10 +/* + * The period between ss_n active and + * sclk_out active is half sclk_out cycles + */ +#define CR0_SSD_HALF 0x0 +/* + * The period between ss_n active and + * sclk_out active is one sclk_out cycle + */ +#define CR0_SSD_ONE 0x1 + +#define CR0_EM_OFFSET 11 +#define CR0_EM_LITTLE 0x0 +#define CR0_EM_BIG 0x1 + +#define CR0_FBM_OFFSET 12 +#define CR0_FBM_MSB 0x0 +#define CR0_FBM_LSB 0x1 + +#define CR0_BHT_OFFSET 13 +#define CR0_BHT_16BIT 0x0 +#define CR0_BHT_8BIT 0x1 + +#define CR0_RSD_OFFSET 14 +#define CR0_RSD_MAX 0x3 + +#define CR0_FRF_OFFSET 16 +#define CR0_FRF_SPI 0x0 +#define CR0_FRF_SSP 0x1 +#define CR0_FRF_MICROWIRE 0x2 + +#define CR0_XFM_OFFSET 18 +#define CR0_XFM_MASK (0x03 << SPI_XFM_OFFSET) +#define CR0_XFM_TR 0x0 +#define CR0_XFM_TO 0x1 +#define CR0_XFM_RO 0x2 + +#define CR0_OPM_OFFSET 20 +#define CR0_OPM_MASTER 0x0 +#define CR0_OPM_SLAVE 0x1 + +#define CR0_SOI_OFFSET 23 + +#define CR0_MTM_OFFSET 0x21 + +/* Bit fields in SER, 2bit */ +#define SER_MASK 0x3 + +/* Bit fields in BAUDR */ +#define BAUDR_SCKDV_MIN 2 +#define BAUDR_SCKDV_MAX 65534 + +/* Bit fields in SR, 6bit */ +#define SR_MASK 0x3f +#define SR_BUSY (1 << 0) +#define SR_TF_FULL (1 << 1) +#define SR_TF_EMPTY (1 << 2) +#define SR_RF_EMPTY (1 << 3) +#define SR_RF_FULL (1 << 4) +#define SR_SLAVE_TX_BUSY (1 << 5) + +/* Bit fields in ISR, IMR, ISR, RISR, 5bit */ +#define INT_MASK 0x1f +#define INT_TF_EMPTY (1 << 0) +#define INT_TF_OVERFLOW (1 << 1) +#define INT_RF_UNDERFLOW (1 << 2) +#define INT_RF_OVERFLOW (1 << 3) +#define INT_RF_FULL (1 << 4) +#define INT_CS_INACTIVE (1 << 6) + +/* Bit fields in ICR, 4bit */ +#define ICR_MASK 0x0f +#define ICR_ALL (1 << 0) +#define ICR_RF_UNDERFLOW (1 << 1) +#define ICR_RF_OVERFLOW (1 << 2) +#define ICR_TF_OVERFLOW (1 << 3) + +/* Bit fields in DMACR */ +#define RF_DMA_EN (1 << 0) +#define TF_DMA_EN (1 << 1) + +/* sclk_out: spi master internal logic in rk3x can support 50Mhz */ +#define MAX_SCLK_OUT 50000000U +/* max sclk of driver strength 4mA */ +#define IO_DRIVER_4MA_MAX_SCLK_OUT 24000000U + +/* + * SPI_CTRLR1 is 16-bits, so we should support lengths of 0xffff + 1. However, + * the controller seems to hang when given 0x10000, so stick with this for now. + */ +#define ROCKCHIP_SPI_MAX_TRANLEN 0xffff + +/* 2 for native cs, 2 for cs-gpio */ +#define ROCKCHIP_SPI_MAX_CS_NUM 4 +#define ROCKCHIP_SPI_VER2_TYPE1 0x05ec0002 +#define ROCKCHIP_SPI_VER2_TYPE2 0x00110002 + +struct rockchip_spi_soc_data +{ + rt_uint32_t max_baud_div_in_cpha; +}; + +struct rockchip_spi +{ + struct rt_spi_bus parent; + + struct rt_clk *spiclk; + struct rt_clk *apb_pclk; + struct rt_clk *sclk_in; + + struct rt_dma_chan *dma_rx; + struct rt_dma_chan *dma_tx; + + int irq; + void *regs; + rt_ubase_t dma_addr_rx; + rt_ubase_t dma_addr_tx; + + rt_uint8_t mode; + + const void *tx; + void *rx; + rt_uint32_t tx_left; + rt_uint32_t rx_left; + rt_uint32_t max_baud_div_in_cpha; + + /* DMA state */ + rt_err_t dma_err; + rt_bool_t is_dma_rx; + rt_bool_t is_dma_tx; + + /* depth of the FIFO buffer */ + rt_uint32_t fifo_len; + /* frequency of spiclk */ + rt_uint32_t freq; + rt_uint32_t speed_hz; + + rt_uint8_t n_bytes; + rt_uint8_t bits_per_word; + rt_uint8_t rsd; + + rt_bool_t cs_asserted[ROCKCHIP_SPI_MAX_CS_NUM]; + + rt_int8_t high_speed_state; + rt_bool_t slave_abort; + rt_bool_t cs_inactive; /* spi slave tansmition stop when cs inactive */ + rt_bool_t cs_high_supported; /* native CS supports active-high polarity */ + + struct rt_spi_message *xfer; + + struct rt_completion done; +}; + +#define raw_to_rockchip_spi(raw) rt_container_of(raw, struct rockchip_spi, parent) + +rt_inline rt_uint32_t rockchip_spi_readl(struct rockchip_spi *rk_spi, int offset) +{ + return HWREG32(rk_spi->regs + offset); +} + +rt_inline void rockchip_spi_writel(struct rockchip_spi *rk_spi, int offset, rt_uint32_t value) +{ + HWREG32(rk_spi->regs + offset) = value; +} + +rt_inline void spi_enable_chip(struct rockchip_spi *rk_spi, rt_bool_t enable) +{ + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_SSIENR, !!enable); +} + +rt_inline void wait_for_tx_idle(struct rockchip_spi *rk_spi, rt_bool_t slave_mode) +{ + rt_tick_t timeout = rt_tick_get() + 5; + + do { + if (slave_mode) + { + if (!(rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_SR) & SR_SLAVE_TX_BUSY) && + !((rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_SR) & SR_BUSY))) + { + return; + } + } + else + { + if (!(rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_SR) & SR_BUSY)) + { + return; + } + } + } while (timeout > rt_tick_get()); + + LOG_W("Controller is in busy state"); +} + +static rt_uint32_t get_fifo_len(struct rockchip_spi *rk_spi) +{ + rt_uint32_t ver = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_VERSION); + + switch (ver) + { + case ROCKCHIP_SPI_VER2_TYPE1: + case ROCKCHIP_SPI_VER2_TYPE2: + return 64; + + default: + return 32; + } +} + +static void rockchip_spi_set_cs(struct rt_spi_device *spi_dev, rt_bool_t enable) +{ + rt_uint32_t en_value; + struct rockchip_spi *rk_spi = raw_to_rockchip_spi(spi_dev->bus); + rt_bool_t cs_asserted = spi_dev->config.mode & RT_SPI_CS_HIGH ? !enable : enable; + + /* Return immediately for no-op */ + if (cs_asserted == rk_spi->cs_asserted[spi_dev->chip_select[0]]) + { + return; + } + + if (spi_dev->cs_pin != PIN_NONE) + { + en_value = 1; + } + else + { + en_value = RT_BIT(spi_dev->chip_select[0]); + } + + if (cs_asserted) + { + ROCKCHIP_SPI_SET_BITS(rk_spi->regs + ROCKCHIP_SPI_SER, en_value); + } + else + { + ROCKCHIP_SPI_CLR_BITS(rk_spi->regs + ROCKCHIP_SPI_SER, en_value); + } + + rk_spi->cs_asserted[spi_dev->chip_select[0]] = cs_asserted; +} + +static void rockchip_spi_pio_writer(struct rockchip_spi *rk_spi) +{ + rt_uint32_t tx_free, words; + + tx_free = rk_spi->fifo_len - rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_TXFLR); + words = rt_min(rk_spi->tx_left, tx_free); + + for (rk_spi->tx_left -= words; words; --words) + { + rt_uint32_t txw; + + if (rk_spi->n_bytes == 1) + { + txw = *(rt_uint8_t *)rk_spi->tx; + } + else + { + txw = *(rt_uint16_t *)rk_spi->tx; + } + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_TXDR, txw); + rk_spi->tx += rk_spi->n_bytes; + } +} + +static void rockchip_spi_pio_reader(struct rockchip_spi *rk_spi) +{ + rt_uint32_t words, rx_left; + + words = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_RXFLR); + rx_left = (rk_spi->rx_left > words) ? rk_spi->rx_left - words : 0; + + /* + * the hardware doesn't allow us to change fifo threshold + * level while spi is enabled, so instead make sure to leave + * enough words in the rx fifo to get the last interrupt + * exactly when all words have been received + */ + if (rx_left) + { + rt_uint32_t ftl = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_RXFTLR) + 1; + + if (rx_left < ftl) + { + rx_left = ftl; + words = rk_spi->rx_left - rx_left; + } + } + + for (rk_spi->rx_left = rx_left; words; --words) + { + rt_uint32_t rxw = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_RXDR); + + if (!rk_spi->rx) + { + continue; + } + + if (rk_spi->n_bytes == 1) + { + *(rt_uint8_t *)rk_spi->rx = (rt_uint8_t)rxw; + } + else + { + *(rt_uint16_t *)rk_spi->rx = (rt_uint16_t)rxw; + } + + rk_spi->rx += rk_spi->n_bytes; + } +} + +static rt_ssize_t rockchip_spi_prepare_irq(struct rockchip_spi *rk_spi, + struct rt_spi_message *xfer) +{ + int cs_flags = 0; + + rk_spi->tx = xfer->send_buf; + rk_spi->rx = xfer->recv_buf; + rk_spi->tx_left = rk_spi->tx ? xfer->length / rk_spi->n_bytes : 0; + rk_spi->rx_left = xfer->length / rk_spi->n_bytes; + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_ICR, 0xffffffff); + + spi_enable_chip(rk_spi, RT_TRUE); + + if (rk_spi->tx_left) + { + rockchip_spi_pio_writer(rk_spi); + } + + if (rk_spi->cs_inactive) + { + cs_flags |= INT_CS_INACTIVE; + } + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_IMR, INT_RF_FULL | cs_flags); + + return xfer->length; +} + +static void rockchip_spi_slave_abort(struct rockchip_spi *rk_spi) +{ + rt_uint32_t rx_fifo_left; + + if (rk_spi->is_dma_rx) + { + rk_spi->dma_err = -RT_EIO; + } + + if (rk_spi->rx) + { + rx_fifo_left = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_RXFLR); + + for (; rx_fifo_left; --rx_fifo_left) + { + rt_uint32_t rxw = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_RXDR); + + if (rk_spi->n_bytes == 1) + { + *(rt_uint8_t *)rk_spi->rx = (rt_uint8_t)rxw; + } + else + { + *(rt_uint16_t *)rk_spi->rx = (rt_uint16_t)rxw; + } + + rk_spi->rx += rk_spi->n_bytes; + } + + rk_spi->xfer->length = (rt_uint32_t)(rk_spi->rx - rk_spi->xfer->recv_buf); + } + + spi_enable_chip(rk_spi, RT_FALSE); + rk_spi->slave_abort = RT_TRUE; + + rt_completion_done(&rk_spi->done); +} + +static rt_uint32_t rockchip_spi_calc_burst_size(rt_uint32_t data_len) +{ + rt_uint32_t i; + + /* burst size: 1, 2, 4, 8 */ + for (i = 1; i < 8; i <<= 1) + { + if (data_len & i) + { + break; + } + } + + return i; +} + +static rt_bool_t rockchip_spi_can_dma(struct rockchip_spi *rk_spi, + struct rt_spi_message *xfer) +{ + rt_size_t bytes_per_word = rk_spi->bits_per_word <= 8 ? 1 : 2; + + if (rk_spi->dma_tx && rk_spi->dma_rx) + { + return xfer->length / bytes_per_word >= rk_spi->fifo_len; + } + + return RT_FALSE; +} + +static void rockchip_spi_dma_rx_done(struct rt_dma_chan *chan, rt_size_t size) +{ + struct rockchip_spi *rk_spi = chan->priv; + + if (rk_spi->is_dma_tx && !rk_spi->slave_abort) + { + return; + } + + if (rk_spi->cs_inactive) + { + HWREG32(rk_spi->regs + ROCKCHIP_SPI_IMR) = 0; + } + + spi_enable_chip(rk_spi, RT_FALSE); + rt_completion_done(&rk_spi->done); +} + +static void rockchip_spi_dma_tx_done(struct rt_dma_chan *chan, rt_size_t size) +{ + struct rockchip_spi *rk_spi = chan->priv; + + if (rk_spi->is_dma_rx && !rk_spi->slave_abort) + { + return; + } + + wait_for_tx_idle(rk_spi, rk_spi->parent.slave); + + spi_enable_chip(rk_spi, RT_FALSE); + rt_completion_done(&rk_spi->done); +} + +static rt_ssize_t rockchip_spi_prepare_dma(struct rockchip_spi *rk_spi, + struct rt_spi_device *spi_dev, struct rt_spi_message *xfer) +{ + rt_err_t err; + + rk_spi->dma_err = RT_EOK; + rk_spi->is_dma_rx = RT_FALSE; + rk_spi->is_dma_tx = RT_FALSE; + + rk_spi->rx = xfer->recv_buf; + rk_spi->tx = xfer->send_buf; + + if (rk_spi->rx) + { + struct rt_dma_slave_config config; + struct rt_dma_slave_transfer transfer; + + rt_memset(&config, 0, sizeof(config)); + + config.direction = RT_DMA_DEV_TO_MEM; + config.src_addr = rk_spi->dma_addr_rx; + config.dst_addr = (rt_ubase_t)rt_kmem_v2p((void *)rk_spi->rx); + config.src_addr_width = rk_spi->n_bytes; + config.src_maxburst = rockchip_spi_calc_burst_size(xfer->length / rk_spi->n_bytes); + + if ((err = rt_dma_chan_config(rk_spi->dma_rx, &config))) + { + LOG_E("Config RX error = %s", rt_strerror(err)); + return err; + } + + rt_memset(&transfer, 0, sizeof(transfer)); + transfer.src_addr = config.src_addr; + transfer.dst_addr = config.dst_addr; + transfer.buffer_len = xfer->length; + + if ((err = rt_dma_prep_single(rk_spi->dma_rx, &transfer))) + { + LOG_E("Prepare RX error = %s", rt_strerror(err)); + return err; + } + } + + if (rk_spi->tx) + { + struct rt_dma_slave_config config; + struct rt_dma_slave_transfer transfer; + + rt_memset(&config, 0, sizeof(config)); + + config.direction = RT_DMA_MEM_TO_DEV; + config.src_addr = rk_spi->dma_addr_tx; + config.dst_addr = (rt_ubase_t)rt_kmem_v2p((void *)rk_spi->tx); + config.dst_addr_width = rk_spi->n_bytes; + config.dst_maxburst = rk_spi->fifo_len / 4; + + if ((err = rt_dma_chan_config(rk_spi->dma_tx, &config))) + { + LOG_E("Config TX error = %s", rt_strerror(err)); + return err; + } + + rt_memset(&transfer, 0, sizeof(transfer)); + transfer.src_addr = config.src_addr; + transfer.dst_addr = config.dst_addr; + transfer.buffer_len = xfer->length; + + if ((err = rt_dma_prep_single(rk_spi->dma_tx, &transfer))) + { + LOG_E("Prepare TX error = %s", rt_strerror(err)); + return err; + } + } + + if (rk_spi->rx) + { + rk_spi->is_dma_rx = RT_TRUE; + rt_dma_chan_start(rk_spi->dma_rx); + } + + if (rk_spi->cs_inactive) + { + HWREG32(rk_spi->regs + ROCKCHIP_SPI_IMR) = INT_CS_INACTIVE; + } + + spi_enable_chip(rk_spi, RT_TRUE); + + if (rk_spi->tx) + { + rk_spi->is_dma_tx = RT_TRUE; + rt_dma_chan_start(rk_spi->dma_tx); + } + + return xfer->length; +} + +static rt_err_t rockchip_spi_config(struct rockchip_spi *rk_spi, + struct rt_spi_device *spi_dev, struct rt_spi_message *xfer, + rt_bool_t use_dma, rt_bool_t slave_mode) +{ + rt_uint32_t cr0, cr1, dmacr = 0, rxftlr; + struct rt_spi_configuration *conf = &spi_dev->config; + + rk_spi->slave_abort = RT_FALSE; + + cr0 = (CR0_BHT_8BIT << CR0_BHT_OFFSET) | /* APB, SPI 8bit write/read */ + (CR0_SSD_ONE << CR0_SSD_OFFSET) | /* One sclk_out cycle */ + (CR0_EM_BIG << CR0_EM_OFFSET) | /* Big endian */ + (CR0_FRF_SPI << CR0_FRF_OFFSET) | /* Motorola SPI */ + (CR0_CSM_KEEP << CR0_CSM_OFFSET) | /* Keep low after every frame */ + (rk_spi->rsd << CR0_RSD_OFFSET); /* Rxd sample delay */ + + if (conf->mode & RT_SPI_CPOL) + { + cr0 |= CR0_SCPOL_HIGH << CR0_SCPOL_OFFSET; + } + + if (conf->mode & RT_SPI_CPHA) + { + cr0 |= CR0_SCPH_START_EDGE << CR0_SCPH_OFFSET; + } + + if (conf->mode & RT_SPI_LSB) + { + cr0 |= CR0_FBM_LSB << CR0_FBM_OFFSET; + } + + if (slave_mode) + { + cr0 |= CR0_OPM_SLAVE << CR0_OPM_OFFSET; + } + + if (conf->mode & RT_SPI_CS_HIGH) + { + cr0 |= RT_BIT(spi_dev->chip_select[0]) << CR0_SOI_OFFSET; + } + + if (xfer->recv_buf && xfer->send_buf) + { + cr0 |= CR0_XFM_TR << CR0_XFM_OFFSET; + } + else if (xfer->recv_buf) + { + cr0 |= CR0_XFM_RO << CR0_XFM_OFFSET; + } + else if (use_dma) + { + cr0 |= CR0_XFM_TO << CR0_XFM_OFFSET; + } + + switch (rk_spi->bits_per_word) + { + case 4: + cr0 |= CR0_DFS_4BIT << CR0_DFS_OFFSET; + cr1 = xfer->length - 1; + break; + + case 8: + cr0 |= CR0_DFS_8BIT << CR0_DFS_OFFSET; + cr1 = xfer->length - 1; + break; + + case 16: + cr0 |= CR0_DFS_16BIT << CR0_DFS_OFFSET; + cr1 = xfer->length / 2 - 1; + break; + + default: + return -RT_EINVAL; + } + + if (use_dma) + { + if (xfer->send_buf) + { + dmacr |= TF_DMA_EN; + } + if (xfer->recv_buf) + { + dmacr |= RF_DMA_EN; + } + } + + /* If speed is larger than IO_DRIVER_4MA_MAX_SCLK_OUT, set higher driver strength. */ + if (rk_spi->high_speed_state >= 0) + { + struct rt_device *dev = &rk_spi->parent.parent; + + if (rk_spi->freq > IO_DRIVER_4MA_MAX_SCLK_OUT) + { + rt_pin_ctrl_confs_apply(dev, rk_spi->high_speed_state); + } + } + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_CTRLR0, cr0); + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_CTRLR1, cr1); + + /* + * unfortunately setting the fifo threshold level to generate an + * interrupt exactly when the fifo is full doesn't seem to work, + * so we need the strict inequality here + */ + if ((xfer->length / rk_spi->n_bytes) < rk_spi->fifo_len) + { + rxftlr = xfer->length / rk_spi->n_bytes - 1; + } + else + { + rxftlr = rk_spi->fifo_len / 2 - 1; + } + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_RXFTLR, rxftlr); + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_DMATDLR, rk_spi->fifo_len / 2 - 1); + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_DMARDLR, + rockchip_spi_calc_burst_size(xfer->length / rk_spi->n_bytes) - 1); + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_DMACR, dmacr); + + if (rk_spi->max_baud_div_in_cpha && conf->max_hz != rk_spi->speed_hz) + { + /* the minimum divisor is 2 */ + if (rk_spi->freq < 2 * conf->max_hz) + { + rt_clk_set_rate(rk_spi->spiclk, 2 * conf->max_hz); + rk_spi->freq = rt_clk_get_rate(rk_spi->spiclk); + } + + if (conf->mode & RT_SPI_CPHA && + RT_DIV_ROUND_UP(rk_spi->freq, conf->max_hz) > rk_spi->max_baud_div_in_cpha) + { + rt_clk_set_rate(rk_spi->spiclk, rk_spi->max_baud_div_in_cpha * conf->max_hz); + rk_spi->freq = rt_clk_get_rate(rk_spi->spiclk); + } + } + + /* + * the hardware only supports an even clock divisor, so + * round divisor = spiclk / speed up to nearest even number + * so that the resulting speed is <= the requested speed + */ + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_BAUDR, + 2 * RT_DIV_ROUND_UP(rk_spi->freq, 2 * conf->max_hz)); + rk_spi->speed_hz = conf->max_hz; + + return RT_EOK; +} + +static rt_err_t rockchip_spi_configure(struct rt_spi_device *spi_dev, + struct rt_spi_configuration *conf) +{ + rt_uint32_t cr0; + rt_uint8_t chip_select = spi_dev->chip_select[0]; + struct rockchip_spi *rk_spi = raw_to_rockchip_spi(spi_dev->bus); + + if (!conf->max_hz) + { + LOG_E("Not max hz in %s", rt_dm_dev_get_name(&spi_dev->parent)); + + return -RT_EINVAL; + } + + if (rk_spi->parent.cs_pins[0] < 0 && conf->mode & RT_SPI_CS_HIGH && !rk_spi->cs_high_supported) + { + LOG_W("None GPIO CS can't be active-high in %s", + rt_dm_dev_get_name(&spi_dev->parent)); + return -RT_EINVAL; + } + + cr0 = rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_CTRLR0); + cr0 &= ~(0x3 << CR0_SCPH_OFFSET); + + if (conf->mode & RT_SPI_CPHA) + { + cr0 |= CR0_SCPH_START_EDGE << CR0_SCPH_OFFSET; + } + + if (conf->mode & RT_SPI_CS_HIGH && chip_select <= 1) + { + cr0 |= RT_BIT(chip_select) << CR0_SOI_OFFSET; + } + else if (chip_select <= 1) + { + cr0 &= ~(RT_BIT(chip_select) << CR0_SOI_OFFSET); + } + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_CTRLR0, cr0); + + return RT_EOK; +} + +static rt_ssize_t rockchip_spi_xfer(struct rt_spi_device *spi_dev, + struct rt_spi_message *xfer) +{ + rt_err_t err; + rt_ssize_t res; + rt_bool_t use_dma; + struct rt_spi_bus *spi_bus = spi_dev->bus; + struct rockchip_spi *rk_spi = raw_to_rockchip_spi(spi_bus); + + if (!xfer->length) + { + rt_completion_done(&rk_spi->done); + + return rk_spi->xfer ? rk_spi->xfer->length : 1; + } + + if (!xfer->send_buf && !xfer->recv_buf) + { + if (xfer->cs_take) + { + rockchip_spi_set_cs(spi_dev, RT_TRUE); + } + + if (xfer->cs_release) + { + rockchip_spi_set_cs(spi_dev, RT_FALSE); + } + + LOG_E("No buffer for transfer"); + + return -RT_EINVAL; + } + + if (xfer->length > ROCKCHIP_SPI_MAX_TRANLEN) + { + LOG_E("Transfer is too long = %u", xfer->length); + + return -RT_EINVAL; + } + + rk_spi->n_bytes = rk_spi->bits_per_word <= 8 ? 1 : 2; + rk_spi->xfer = xfer; + use_dma = rockchip_spi_can_dma(rk_spi, xfer); + + if ((err = rockchip_spi_config(rk_spi, spi_dev, xfer, use_dma, spi_bus->slave))) + { + return err; + } + + if (use_dma) + { + res = rockchip_spi_prepare_dma(rk_spi, spi_dev, xfer); + + rt_completion_wait(&rk_spi->done, RT_WAITING_FOREVER); + + if (rk_spi->is_dma_tx) + { + rt_dma_chan_stop(rk_spi->dma_tx); + } + + if (rk_spi->is_dma_rx) + { + rt_dma_chan_stop(rk_spi->dma_rx); + } + + if (rk_spi->dma_err) + { + res = rk_spi->dma_err; + } + + return res; + } + + if (!spi_bus->slave) + { + rt_uint32_t timeout, div; + + if (xfer->cs_take) + { + rockchip_spi_set_cs(spi_dev, RT_TRUE); + } + + res = rockchip_spi_prepare_irq(rk_spi, xfer); + + div = RT_DIV_ROUND_UP(rk_spi->freq, spi_dev->config.max_hz); + div = (div + 1) & 0xfffe; + timeout = xfer->length * 8 * 1000 / (rk_spi->freq / div) + 100; + + err = rt_completion_wait(&rk_spi->done, rt_tick_from_millisecond(timeout)); + + if (err) + { + res = err; + } + + if (xfer->cs_release) + { + rockchip_spi_set_cs(spi_dev, RT_FALSE); + } + + if (xfer->send_buf && !err) + { + wait_for_tx_idle(rk_spi, spi_bus->slave); + } + } + else + { + res = rockchip_spi_prepare_irq(rk_spi, xfer); + + rt_completion_wait(&rk_spi->done, RT_WAITING_FOREVER); + + if (xfer->send_buf) + { + wait_for_tx_idle(rk_spi, spi_bus->slave); + } + } + + spi_enable_chip(rk_spi, RT_FALSE); + + if (res < 0) + { + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_IMR, 0); + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_ICR, 0xffffffff); + } + + return res; +} + +const static struct rt_spi_ops rockchip_spi_ops = +{ + .configure = rockchip_spi_configure, + .xfer = rockchip_spi_xfer, +}; + +static void rockchip_spi_isr(int irqno, void *param) +{ + struct rockchip_spi *rk_spi = param; + + /* When int_cs_inactive comes, spi slave abort */ + if (rk_spi->cs_inactive && + rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_IMR) & INT_CS_INACTIVE) + { + rockchip_spi_slave_abort(rk_spi); + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_IMR, 0); + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_ICR, 0xffffffff); + + if (rk_spi->is_dma_rx || rk_spi->is_dma_tx) + { + rt_completion_done(&rk_spi->done); + } + + return; + } + + if (rk_spi->tx_left) + { + rockchip_spi_pio_writer(rk_spi); + } + + rockchip_spi_pio_reader(rk_spi); + + if (!rk_spi->rx_left) + { + spi_enable_chip(rk_spi, RT_FALSE); + + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_IMR, 0); + rockchip_spi_writel(rk_spi, ROCKCHIP_SPI_ICR, 0xffffffff); + + rt_completion_done(&rk_spi->done); + } +} + +static void rockchip_spi_free(struct rockchip_spi *rk_spi) +{ + if (rk_spi->regs) + { + rt_iounmap(rk_spi->regs); + } + + if (!rt_is_err_or_null(rk_spi->apb_pclk)) + { + rt_clk_disable_unprepare(rk_spi->apb_pclk); + rt_clk_put(rk_spi->apb_pclk); + } + + if (!rt_is_err_or_null(rk_spi->spiclk)) + { + rt_clk_disable_unprepare(rk_spi->spiclk); + rt_clk_put(rk_spi->spiclk); + } + + if (!rt_is_err_or_null(rk_spi->sclk_in)) + { + rt_clk_disable_unprepare(rk_spi->sclk_in); + rt_clk_put(rk_spi->sclk_in); + } + + if (!rt_is_err_or_null(rk_spi->dma_rx)) + { + rt_dma_chan_release(rk_spi->dma_rx); + } + + if (!rt_is_err_or_null(rk_spi->dma_tx)) + { + rt_dma_chan_release(rk_spi->dma_tx); + } + + rt_free(rk_spi); +} + +static rt_err_t rockchip_spi_probe(struct rt_platform_device *pdev) +{ + int id; + rt_err_t err; + rt_uint32_t nsecs; + rt_bool_t slave_mode; + const char *bus_name; + struct rt_device *dev = &pdev->parent; + struct rockchip_spi *rk_spi = rt_calloc(1, sizeof(*rk_spi)); + const struct rockchip_spi_soc_data *soc_data; + + if (!rk_spi) + { + return -RT_ENOMEM; + } + + rk_spi->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_spi->regs) + { + err = -RT_EIO; + + goto _fail; + } + + rk_spi->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_spi->irq < 0) + { + err = rk_spi->irq; + + goto _fail; + } + + rk_spi->apb_pclk = rt_clk_get_by_name(dev, "apb_pclk"); + + if (rt_is_err(rk_spi->apb_pclk)) + { + err = rt_ptr_err(rk_spi->apb_pclk); + + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_spi->apb_pclk))) + { + goto _fail; + } + + rk_spi->spiclk = rt_clk_get_by_name(dev, "spiclk"); + + if (rt_is_err(rk_spi->spiclk)) + { + err = rt_ptr_err(rk_spi->spiclk); + + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_spi->spiclk))) + { + goto _fail; + } + + if (rt_dm_dev_prop_index_of_string(dev, "clock-names", "sclk_in") >= 0) + { + rk_spi->sclk_in = rt_clk_get_by_name(dev, "sclk_in"); + + if (rt_is_err(rk_spi->sclk_in)) + { + err = rt_ptr_err(rk_spi->sclk_in); + + goto _fail; + } + + if ((err = rt_clk_prepare_enable(rk_spi->sclk_in))) + { + goto _fail; + } + } + + spi_enable_chip(rk_spi, RT_FALSE); + + rk_spi->freq = rt_clk_get_rate(rk_spi->spiclk); + + if (rk_spi->freq < 0) + { + if ((err = rt_dm_dev_prop_read_u32(dev, "clock-frequency", &rk_spi->freq))) + { + LOG_E("Failed to get clock or clock-frequency"); + + goto _fail; + } + } + + if (!rt_dm_dev_prop_read_u32(dev, "rx-sample-delay-ns", &nsecs)) + { + /* rx sample delay is expressed in parent clock cycles (max 3) */ + rt_uint32_t rsd = RT_DIV_ROUND_CLOSEST(nsecs * (rk_spi->freq >> 8), + 1000000000 >> 8); + + if (!rsd) + { + LOG_W("%u Hz are too slow to express %u ns delay", rk_spi->freq, nsecs); + } + else if (rsd > CR0_RSD_MAX) + { + rsd = CR0_RSD_MAX; + LOG_W("%u Hz are too fast to express %u ns delay, clamping at %u ns", + rk_spi->freq, nsecs, CR0_RSD_MAX * 1000000000U / rk_spi->freq); + } + + rk_spi->rsd = rsd; + } + + rk_spi->bits_per_word = 8; + rk_spi->fifo_len = get_fifo_len(rk_spi); + + if (!rk_spi->fifo_len) + { + LOG_E("Failed to get fifo length"); + err = -RT_EINVAL; + + goto _fail; + } + + if ((soc_data = pdev->id->data)) + { + rk_spi->max_baud_div_in_cpha = soc_data->max_baud_div_in_cpha; + } + + slave_mode = rt_dm_dev_prop_read_bool(dev, "spi-slave"); + rk_spi->parent.slave = slave_mode; + + if (!slave_mode) + { + rt_uint32_t num_cs = 1; + + rt_dm_dev_prop_read_u32(dev, "num-cs", &num_cs); + + rk_spi->parent.num_chipselect = num_cs; + } + + rk_spi->dma_rx = rt_dma_chan_request(dev, "rx"); + + if (rt_is_err(rk_spi->dma_rx)) + { + LOG_W("Failed to get %s DMA channel", "RX"); + + rk_spi->dma_rx = RT_NULL; + } + else + { + rk_spi->dma_tx = rt_dma_chan_request(dev, "tx"); + + if (rt_is_err(rk_spi->dma_tx)) + { + LOG_W("Failed to get %s DMA channel", "TX"); + + rk_spi->dma_tx = RT_NULL; + } + } + + if (rk_spi->dma_rx && rk_spi->dma_tx) + { + rt_ubase_t spi_regs_phy = (rt_ubase_t)rt_kmem_v2p(rk_spi->regs); + + rk_spi->dma_rx->callback = rockchip_spi_dma_rx_done; + rk_spi->dma_tx->callback = rockchip_spi_dma_tx_done; + + rk_spi->dma_rx->priv = rk_spi; + rk_spi->dma_tx->priv = rk_spi; + + rk_spi->dma_addr_rx = spi_regs_phy + ROCKCHIP_SPI_TXDR; + rk_spi->dma_addr_tx = spi_regs_phy + ROCKCHIP_SPI_RXDR; + } + + switch (rockchip_spi_readl(rk_spi, ROCKCHIP_SPI_VERSION)) + { + case ROCKCHIP_SPI_VER2_TYPE2: + rk_spi->cs_high_supported = RT_TRUE; + rk_spi->mode |= RT_SPI_CS_HIGH; + if (rk_spi->dma_rx && rk_spi->dma_tx && slave_mode) + { + rk_spi->cs_inactive = RT_TRUE; + } + else + { + rk_spi->cs_inactive = RT_FALSE; + } + break; + + default: + rk_spi->cs_inactive = RT_FALSE; + break; + } + + rk_spi->high_speed_state = rt_pin_ctrl_confs_lookup(dev, "high_speed"); + + rt_pin_ctrl_confs_apply_by_name(dev, RT_NULL); + + rt_completion_init(&rk_spi->done); + + dev->user_data = rk_spi; + + rk_spi->parent.parent.ofw_node = dev->ofw_node; + + if ((id = pdev->dev_id) >= 0) + { + rt_dm_dev_set_name(&rk_spi->parent.parent, "spi%u", id); + } + else + { + rt_dm_dev_set_name_auto(&rk_spi->parent.parent, "spi"); + } + bus_name = rt_dm_dev_get_name(&rk_spi->parent.parent); + + rt_hw_interrupt_install(rk_spi->irq, rockchip_spi_isr, rk_spi, bus_name); + rt_hw_interrupt_umask(rk_spi->irq); + + if ((err = rt_spi_bus_register(&rk_spi->parent, bus_name, &rockchip_spi_ops))) + { + goto _free_irq; + } + + return RT_EOK; + +_free_irq: + rt_hw_interrupt_mask(rk_spi->irq); + rt_pic_detach_irq(rk_spi->irq, rk_spi); + +_fail: + rockchip_spi_free(rk_spi); + + return err; +} + +static rt_err_t rockchip_spi_remove(struct rt_platform_device *pdev) +{ + struct rockchip_spi *rk_spi = pdev->parent.user_data; + + spi_enable_chip(rk_spi, RT_FALSE); + + rt_hw_interrupt_mask(rk_spi->irq); + rt_pic_detach_irq(rk_spi->irq, rk_spi); + + rt_device_unregister(&rk_spi->parent.parent); + + rockchip_spi_free(rk_spi); + + return RT_EOK; +} + +static const struct rockchip_spi_soc_data px30_data = +{ + .max_baud_div_in_cpha = 4, +}; + +static const struct rt_ofw_node_id rockchip_spi_ofw_ids[] = +{ + { .compatible = "rockchip,px30-spi", .data = &px30_data }, + { .compatible = "rockchip,rk3036-spi", }, + { .compatible = "rockchip,rk3066-spi", }, + { .compatible = "rockchip,rk3188-spi", }, + { .compatible = "rockchip,rk3228-spi", }, + { .compatible = "rockchip,rk3288-spi", }, + { .compatible = "rockchip,rk3308-spi", }, + { .compatible = "rockchip,rk3328-spi", }, + { .compatible = "rockchip,rk3368-spi", }, + { .compatible = "rockchip,rk3399-spi", }, + { .compatible = "rockchip,rv1108-spi", }, + { .compatible = "rockchip,rv1126-spi", }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_spi_driver = +{ + .name = "rockchip-spi", + .ids = rockchip_spi_ofw_ids, + + .probe = rockchip_spi_probe, + .remove = rockchip_spi_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_spi_driver); diff --git a/bsp/rockchip/dm/thermal/Kconfig b/bsp/rockchip/dm/thermal/Kconfig new file mode 100755 index 00000000000..1c4efa01f3e --- /dev/null +++ b/bsp/rockchip/dm/thermal/Kconfig @@ -0,0 +1,6 @@ +config RT_THERMAL_ROCKCHIP_TSADC + bool "Rockchip TS-ADC driver" + depends on RT_USING_THERMAL + depends on RT_MFD_SYSCON + depends on RT_USING_RESET + default n diff --git a/bsp/rockchip/dm/thermal/SConscript b/bsp/rockchip/dm/thermal/SConscript new file mode 100755 index 00000000000..8bfae54cc0c --- /dev/null +++ b/bsp/rockchip/dm/thermal/SConscript @@ -0,0 +1,13 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_THERMAL_ROCKCHIP_TSADC']): + src += ['thermal-rockchip_tsadc.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/thermal/thermal-rockchip_tsadc.c b/bsp/rockchip/dm/thermal/thermal-rockchip_tsadc.c new file mode 100755 index 00000000000..4d9252a097e --- /dev/null +++ b/bsp/rockchip/dm/thermal/thermal-rockchip_tsadc.c @@ -0,0 +1,1695 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-3-08 GuEe-GUI the first version + */ + +#include +#include +#include + +#define DBG_TAG "thermal.rk-tsadc" +#define DBG_LVL DBG_INFO +#include + +/* + * TSADC Sensor Register description: + * + * TSADCV2_* are used for RK3288 SoCs, the other chips can reuse it. + * TSADCV3_* are used for newer SoCs than RK3288. (e.g: RK3228, RK3399) + */ +#define TSADCV2_USER_CON 0x00 +#define TSADCV2_AUTO_CON 0x04 +#define TSADCV2_INT_EN 0x08 +#define TSADCV2_INT_PD 0x0c +#define TSADCV3_AUTO_SRC_CON 0x0c +#define TSADCV3_HT_INT_EN 0x14 +#define TSADCV3_HSHUT_GPIO_INT_EN 0x18 +#define TSADCV3_HSHUT_CRU_INT_EN 0x1c +#define TSADCV3_INT_PD 0x24 +#define TSADCV3_HSHUT_PD 0x28 +#define TSADCV2_DATA(chn) (0x20 + (chn) * 0x04) +#define TSADCV2_COMP_INT(chn) (0x30 + (chn) * 0x04) +#define TSADCV2_COMP_SHUT(chn) (0x40 + (chn) * 0x04) +#define TSADCV3_DATA(chn) (0x2c + (chn) * 0x04) +#define TSADCV3_COMP_INT(chn) (0x6c + (chn) * 0x04) +#define TSADCV3_COMP_SHUT(chn) (0x10c + (chn) * 0x04) +#define TSADCV2_HIGHT_INT_DEBOUNCE 0x60 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE 0x64 +#define TSADCV3_HIGHT_INT_DEBOUNCE 0x14c +#define TSADCV3_HIGHT_TSHUT_DEBOUNCE 0x150 +#define TSADCV2_AUTO_PERIOD 0x68 +#define TSADCV2_AUTO_PERIOD_HT 0x6c +#define TSADCV3_AUTO_PERIOD 0x154 +#define TSADCV3_AUTO_PERIOD_HT 0x158 + +#define TSADCV2_AUTO_EN RT_BIT(0) +#define TSADCV2_AUTO_EN_MASK RT_BIT(16) +#define TSADCV2_AUTO_SRC_EN(chn) RT_BIT(4 + (chn)) +#define TSADCV3_AUTO_SRC_EN(chn) RT_BIT(chn) +#define TSADCV3_AUTO_SRC_EN_MASK(chn) RT_BIT(16 + chn) +#define TSADCV2_AUTO_TSHUT_POLARITY_HIGH RT_BIT(8) +#define TSADCV2_AUTO_TSHUT_POLARITY_MASK RT_BIT(24) + +#define TSADCV3_AUTO_Q_SEL_EN RT_BIT(1) + +#define TSADCV2_INT_SRC_EN(chn) RT_BIT(chn) +#define TSADCV2_INT_SRC_EN_MASK(chn) RT_BIT(16 + (chn)) +#define TSADCV2_SHUT_2GPIO_SRC_EN(chn) RT_BIT(4 + (chn)) +#define TSADCV2_SHUT_2CRU_SRC_EN(chn) RT_BIT(8 + (chn)) + +#define TSADCV2_INT_PD_CLEAR_MASK (~RT_BIT(8)) +#define TSADCV3_INT_PD_CLEAR_MASK (~RT_BIT(16)) +#define TSADCV4_INT_PD_CLEAR_MASK 0xffffffff + +#define TSADCV2_DATA_MASK 0xfff +#define TSADCV3_DATA_MASK 0x3ff +#define TSADCV4_DATA_MASK 0x1ff + +#define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 +#define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 +#define TSADCV2_AUTO_PERIOD_TIME 250 /* 250ms */ +#define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* 50ms */ +#define TSADCV3_AUTO_PERIOD_TIME 1875 /* 2.5ms */ +#define TSADCV3_AUTO_PERIOD_HT_TIME 1875 /* 2.5ms */ + +#define TSADCV5_AUTO_PERIOD_TIME 1622 /* 2.5ms */ +#define TSADCV5_AUTO_PERIOD_HT_TIME 1622 /* 2.5ms */ +#define TSADCV6_AUTO_PERIOD_TIME 5000 /* 2.5ms */ +#define TSADCV6_AUTO_PERIOD_HT_TIME 5000 /* 2.5ms */ + +#define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */ +#define TSADCV5_USER_INTER_PD_SOC 0xfc0 /* 97us, at least 90us */ + +#define GRF_SARADC_TESTBIT 0x0e644 +#define GRF_TSADC_TESTBIT_L 0x0e648 +#define GRF_TSADC_TESTBIT_H 0x0e64c + +#define PX30_GRF_SOC_CON2 0x0408 + +#define RK3568_GRF_TSADC_CON 0x0600 +#define RK3568_GRF_TSADC_ANA_REG0 (0x10001 << 0) +#define RK3568_GRF_TSADC_ANA_REG1 (0x10001 << 1) +#define RK3568_GRF_TSADC_ANA_REG2 (0x10001 << 2) +#define RK3568_GRF_TSADC_TSEN (0x10001 << 8) + +#define RK3588_GRF0_TSADC_CON 0x0100 + +#define RK3588_GRF0_TSADC_TRM (0xff0077 << 0) +#define RK3588_GRF0_TSADC_SHUT_2CRU (0x30003 << 10) +#define RK3588_GRF0_TSADC_SHUT_2GPIO (0x70007 << 12) + +#define GRF_SARADC_TESTBIT_ON (0x10001 << 2) +#define GRF_TSADC_TESTBIT_H_ON (0x10001 << 2) +#define GRF_TSADC_VCM_EN_L (0x10001 << 7) +#define GRF_TSADC_VCM_EN_H (0x10001 << 7) + +#define GRF_CON_TSADC_CH_INV (0x10001 << 1) + +#define TEMP_INVALID ((int)(RT_UINT32_MAX >> 1)) +#define TEMP_SCALE 1000 + +/* + * If the temperature over a period of time High, + * the resulting TSHUT gave CRU module,let it reset the entire chip, + * or via GPIO give PMIC. + */ +enum tshut_mode +{ + TSHUT_MODE_CRU = 0, + TSHUT_MODE_OTP, + TSHUT_MODE_GPIO, +}; + +/* The system Temperature Sensors tshut(tshut) polarity */ +enum tshut_polarity +{ + TSHUT_LOW_ACTIVE = 0, + TSHUT_HIGH_ACTIVE, +}; + +/* The conversion table has the adc value and temperature. */ +enum adc_sort_mode +{ + ADC_DECREMENT = 0, /* the adc value is of diminishing.(e.g. rk3288_code_table) */ + ADC_INCREMENT, /* the adc value is incremental.(e.g. rk3368_code_table) */ +}; + +struct chip_tsadc_table +{ + const struct tsadc_table *id; + rt_size_t length; + + rt_uint32_t data_mask; + enum adc_sort_mode mode; +}; + +struct rockchip_tsadc_chip +{ + /* The sensor id of chip correspond to the ADC channel */ + int chn_offset; + int chn_num; + const char * const *chn_name; + + /* The hardware-controlled tshut property */ + int tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; + + /* Chip-wide methods */ + void (*initialize)(struct rt_syscon *grf, void *reg, enum tshut_polarity p); + void (*irq_ack)(void *reg); + void (*control)(void *reg, rt_bool_t on); + + /* Per-sensor methods */ + rt_err_t (*get_temp)(const struct chip_tsadc_table *table, int chn, void *reg, int *temp); + rt_err_t (*set_alarm_temp)(const struct chip_tsadc_table *table, int chn, void *reg, int temp); + rt_err_t (*set_tshut_temp)(const struct chip_tsadc_table *table, int chn, void *reg, int temp); + void (*set_tshut_mode)(int chn, void *reg, enum tshut_mode m); + + /* Per-table methods */ + struct chip_tsadc_table table; +}; + +struct tsadc_table +{ + rt_uint32_t code; /* the value of adc channel */ + int temp; /* the temperature */ +}; + +struct rockchip_tsadc; + +struct rockchip_tsadc_channel +{ + struct rt_thermal_zone_device parent; + + int id; + struct rockchip_tsadc *rk_tsadc; +}; +#define raw_to_rockchip_tsadc_channel(raw) rt_container_of(raw, struct rockchip_tsadc_channel, parent) + +struct rockchip_tsadc +{ + int irq; + void *regs; + struct rt_syscon *grf; + + struct rt_clk *clk; + struct rt_clk *pclk; + + struct rt_reset_control *rstc; + + int tshut_temp; + enum tshut_mode tshut_mode; + enum tshut_polarity tshut_polarity; + + const struct rockchip_tsadc_chip *chip; + struct rockchip_tsadc_channel channels[0]; +}; + +static rt_uint32_t rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table, + int temp) +{ + rt_ubase_t num; + rt_uint32_t denom, error = table->data_mask; + int high = (table->length - 1) - 1, low = 0, mid = (high + low) / 2; + + /* Return mask code data when the temp is over table range */ + if (temp < table->id[low].temp || temp > table->id[high].temp) + { + goto _exit; + } + + while (low <= high) + { + if (temp == table->id[mid].temp) + { + return table->id[mid].code; + } + else if (temp < table->id[mid].temp) + { + high = mid - 1; + } + else + { + low = mid + 1; + } + + mid = (low + high) / 2; + } + + /* + * The conversion code granularity provided by the table. Let's + * assume that the relationship between temperature and + * analog value between 2 table entries is linear and interpolate + * to produce less granular result. + */ + num = rt_abs(table->id[mid + 1].code - table->id[mid].code); + num *= temp - table->id[mid].temp; + denom = table->id[mid + 1].temp - table->id[mid].temp; + + switch (table->mode) + { + case ADC_DECREMENT: + return table->id[mid].code - (num / denom); + + case ADC_INCREMENT: + return table->id[mid].code + (num / denom); + + default: + LOG_E("Temp to Code: unknown table mode: %d", table->mode); + + return error; + } + +_exit: + LOG_E("Temp to Code: invalid temperature, temp = %d error = %d", temp, error); + + return error; +} + +static rt_err_t rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table, + rt_uint32_t code, int *temp) +{ + rt_ubase_t denom; + rt_uint32_t low = 1, high = table->length - 1, mid = (low + high) / 2, num; + + switch (table->mode) + { + case ADC_DECREMENT: + code &= table->data_mask; + + if (code <= table->id[high].code) + { + return -RT_ERROR; + } + + while (low <= high) + { + if (code >= table->id[mid].code && code < table->id[mid - 1].code) + { + break; + } + else if (code < table->id[mid].code) + { + low = mid + 1; + } + else + { + high = mid - 1; + } + + mid = (low + high) / 2; + } + break; + + case ADC_INCREMENT: + code &= table->data_mask; + + if (code < table->id[low].code) + { + return -RT_ERROR; + } + + while (low <= high) + { + if (code <= table->id[mid].code && code > table->id[mid - 1].code) + { + break; + } + else if (code > table->id[mid].code) + { + low = mid + 1; + } + else + { + high = mid - 1; + } + + mid = (low + high) / 2; + } + break; + + default: + LOG_E("Code to Temp: unknown table mode: %d", table->mode); + + return -RT_EINVAL; + } + + /* + * The 5C granularity provided by the table is too much. Let's + * assume that the relationship between sensor readings and + * temperature between 2 table entries is linear and interpolate + * to produce less granular result. + */ + num = table->id[mid].temp - table->id[mid - 1].temp; + num *= rt_abs(table->id[mid - 1].code - code); + denom = rt_abs(table->id[mid - 1].code - table->id[mid].code); + *temp = table->id[mid - 1].temp + (num / denom); + + return 0; +} + +/* + * Initialize TASDC Controller. + * + * (1) Set TSADC_V2_AUTO_PERIOD: + * Configure the interleave between every two accessing of + * TSADC in normal operation. + * + * (2) Set TSADCV2_AUTO_PERIOD_HT: + * Configure the interleave between every two accessing of + * TSADC after the temperature is higher than COM_SHUT or COM_INT. + * + * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE: + * If the temperature is higher than COMP_INT or COMP_SHUT for + * "debounce" times, TSADC controller will generate interrupt or TSHUT. + */ +static void rk_tsadcv2_initialize(struct rt_syscon *grf, void *regs, + enum tshut_polarity tshut_polarity) +{ + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + { + HWREG32(regs + TSADCV2_AUTO_CON) = 0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH; + } + else + { + HWREG32(regs + TSADCV2_AUTO_CON) = 0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH; + } + + HWREG32(regs + TSADCV2_AUTO_PERIOD) = TSADCV2_AUTO_PERIOD_TIME; + HWREG32(regs + TSADCV2_HIGHT_INT_DEBOUNCE) = TSADCV2_HIGHT_INT_DEBOUNCE_COUNT; + HWREG32(regs + TSADCV2_AUTO_PERIOD_HT) = TSADCV2_AUTO_PERIOD_HT_TIME; + HWREG32(regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE) = TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT; +} + +/* + * Initialize TASDC Controller. + * (1) The tsadc control power sequence. + * + * (2) Set TSADC_V2_AUTO_PERIOD: + * Configure the interleave between every two accessing of + * TSADC in normal operation. + * + * (2) Set TSADCV2_AUTO_PERIOD_HT: + * Configure the interleave between every two accessing of + * TSADC after the temperature is higher than COM_SHUT or COM_INT. + * + * (3) Set TSADCV2_HIGH_INT_DEBOUNCE and TSADC_HIGHT_TSHUT_DEBOUNCE: + * If the temperature is higher than COMP_INT or COMP_SHUT for + * "debounce" times, TSADC controller will generate interrupt or TSHUT. + */ +static void rk_tsadcv3_initialize(struct rt_syscon *grf, void *regs, + enum tshut_polarity tshut_polarity) +{ + /* The tsadc control power sequence */ + if (!grf) + { + /* Set interleave value to workround ic time sync issue */ + HWREG32(regs + TSADCV2_USER_CON) = TSADCV2_USER_INTER_PD_SOC; + HWREG32(regs + TSADCV2_AUTO_PERIOD) = TSADCV2_AUTO_PERIOD_TIME; + HWREG32(regs + TSADCV2_HIGHT_INT_DEBOUNCE) = TSADCV2_HIGHT_INT_DEBOUNCE_COUNT; + HWREG32(regs + TSADCV2_AUTO_PERIOD_HT) = TSADCV2_AUTO_PERIOD_HT_TIME; + HWREG32(regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE) = TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT; + + } + else + { + /* Enable the voltage common mode feature */ + rt_syscon_write(grf, GRF_TSADC_TESTBIT_L, GRF_TSADC_VCM_EN_L); + rt_syscon_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_VCM_EN_H); + rt_hw_us_delay(15); + + rt_syscon_write(grf, GRF_SARADC_TESTBIT, GRF_SARADC_TESTBIT_ON); + rt_syscon_write(grf, GRF_TSADC_TESTBIT_H, GRF_TSADC_TESTBIT_H_ON); + rt_hw_us_delay(90); + + HWREG32(regs + TSADCV2_AUTO_PERIOD) = TSADCV3_AUTO_PERIOD_TIME; + HWREG32(regs + TSADCV2_HIGHT_INT_DEBOUNCE) = TSADCV2_HIGHT_INT_DEBOUNCE_COUNT; + HWREG32(regs + TSADCV2_AUTO_PERIOD_HT) = TSADCV3_AUTO_PERIOD_HT_TIME; + HWREG32(regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE) = TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT; + } + + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + { + HWREG32(regs + TSADCV2_AUTO_CON) = 0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH; + } + else + { + HWREG32(regs + TSADCV2_AUTO_CON) = 0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH; + } +} + +static void rk_tsadcv4_initialize(struct rt_syscon *grf, void *regs, + enum tshut_polarity tshut_polarity) +{ + rk_tsadcv2_initialize(grf, regs, tshut_polarity); + + rt_syscon_write(grf, PX30_GRF_SOC_CON2, GRF_CON_TSADC_CH_INV); +} + +static void rk_tsadcv7_initialize(struct rt_syscon *grf, void *regs, + enum tshut_polarity tshut_polarity) +{ + HWREG32(regs + TSADCV2_USER_CON) = TSADCV5_USER_INTER_PD_SOC; + HWREG32(regs + TSADCV2_AUTO_PERIOD) = TSADCV5_AUTO_PERIOD_TIME; + HWREG32(regs + TSADCV2_HIGHT_INT_DEBOUNCE) = TSADCV2_HIGHT_INT_DEBOUNCE_COUNT; + HWREG32(regs + TSADCV2_AUTO_PERIOD_HT) = TSADCV5_AUTO_PERIOD_HT_TIME; + HWREG32(regs + TSADCV2_HIGHT_TSHUT_DEBOUNCE) = TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT; + + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + { + HWREG32(regs + TSADCV2_AUTO_CON) = 0U | TSADCV2_AUTO_TSHUT_POLARITY_HIGH; + } + else + { + HWREG32(regs + TSADCV2_AUTO_CON) = 0U & ~TSADCV2_AUTO_TSHUT_POLARITY_HIGH; + } + + /* The general register file will is optional and might not be available. */ + if (grf) + { + rt_syscon_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN); + rt_hw_us_delay(15); + + rt_syscon_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0); + rt_syscon_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1); + rt_syscon_write(grf, RK3568_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2); + rt_hw_us_delay(100); + } +} + +static void rk_tsadcv8_initialize(struct rt_syscon *grf, void *regs, + enum tshut_polarity tshut_polarity) +{ + HWREG32(regs + TSADCV3_AUTO_PERIOD) = TSADCV6_AUTO_PERIOD_TIME; + HWREG32(regs + TSADCV3_AUTO_PERIOD_HT) = TSADCV6_AUTO_PERIOD_HT_TIME; + HWREG32(regs + TSADCV3_HIGHT_INT_DEBOUNCE) = TSADCV2_HIGHT_INT_DEBOUNCE_COUNT; + HWREG32(regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE) = TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT; + + if (tshut_polarity == TSHUT_HIGH_ACTIVE) + { + HWREG32(regs + TSADCV2_AUTO_CON) = TSADCV2_AUTO_TSHUT_POLARITY_HIGH | + TSADCV2_AUTO_TSHUT_POLARITY_MASK; + } + else + { + HWREG32(regs + TSADCV2_AUTO_CON) = TSADCV2_AUTO_TSHUT_POLARITY_MASK; + } +} + +static void rk_tsadcv2_irq_ack(void *regs) +{ + rt_uint32_t val; + + val = HWREG32(regs + TSADCV2_INT_PD); + HWREG32(regs + TSADCV2_INT_PD) = val & TSADCV2_INT_PD_CLEAR_MASK; +} + +static void rk_tsadcv3_irq_ack(void *regs) +{ + rt_uint32_t val; + + val = HWREG32(regs + TSADCV2_INT_PD); + HWREG32(regs + TSADCV2_INT_PD) = val & TSADCV3_INT_PD_CLEAR_MASK; +} + +static void rk_tsadcv4_irq_ack(void *regs) +{ + rt_uint32_t val; + + val = HWREG32(regs + TSADCV3_INT_PD); + HWREG32(regs + TSADCV3_INT_PD) = val & TSADCV4_INT_PD_CLEAR_MASK; + + val = HWREG32(regs + TSADCV3_HSHUT_PD); + HWREG32(regs + TSADCV3_HSHUT_PD) = val & TSADCV3_INT_PD_CLEAR_MASK; +} + +static void rk_tsadcv2_control(void *regs, rt_bool_t enable) +{ + rt_uint32_t val = HWREG32(regs + TSADCV2_AUTO_CON); + + if (enable) + { + val |= TSADCV2_AUTO_EN; + } + else + { + val &= ~TSADCV2_AUTO_EN; + } + + HWREG32(regs + TSADCV2_AUTO_CON) = val; +} + +/* + * The tsadc controller is enabled or disabled. + * NOTE: TSADC controller works at auto mode, and some SoCs need set the + * tsadc_q_sel bit on TSADCV2_AUTO_CON[1]. The (1024 - tsadc_q) as output + * adc value if setting this bit to enable. + */ +static void rk_tsadcv3_control(void *regs, rt_bool_t enable) +{ + rt_uint32_t val = HWREG32(regs + TSADCV2_AUTO_CON); + + if (enable) + { + val |= TSADCV2_AUTO_EN | TSADCV3_AUTO_Q_SEL_EN; + } + else + { + val &= ~TSADCV2_AUTO_EN; + } + + HWREG32(regs + TSADCV2_AUTO_CON) = val; +} + +static void rk_tsadcv4_control(void *regs, rt_bool_t enable) +{ + rt_uint32_t val; + + if (enable) + { + val = TSADCV2_AUTO_EN | TSADCV2_AUTO_EN_MASK; + } + else + { + val = TSADCV2_AUTO_EN_MASK; + } + + HWREG32(regs + TSADCV2_AUTO_CON) = val; +} + +static rt_err_t rk_tsadcv2_get_temp(const struct chip_tsadc_table *table, + int chn, void *regs, int *temp) +{ + rt_uint32_t val = HWREG32(regs + TSADCV2_DATA(chn)); + + return rk_tsadcv2_code_to_temp(table, val, temp); +} + +static rt_err_t rk_tsadcv4_get_temp(const struct chip_tsadc_table *table, + int chn, void *regs, int *temp) +{ + rt_uint32_t val = HWREG32(regs + TSADCV3_DATA(chn)); + + return rk_tsadcv2_code_to_temp(table, val, temp); +} + +static rt_err_t rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table, + int chn, void *regs, int temp) +{ + rt_uint32_t alarm_value; + rt_uint32_t int_en, int_clr; + + /* + * In some cases, some sensors didn't need the trip points, the + * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm + * in the end, ignore this case and disable the high temperature + * interrupt. + */ + if (temp == TEMP_INVALID) + { + int_clr = HWREG32(regs + TSADCV2_INT_EN); + int_clr &= ~TSADCV2_INT_SRC_EN(chn); + HWREG32(regs + TSADCV2_INT_EN) = int_clr; + + return RT_EOK; + } + + alarm_value = rk_tsadcv2_temp_to_code(table, temp); + + if (alarm_value == table->data_mask) + { + return -RT_EINVAL; + } + + HWREG32(regs + TSADCV2_COMP_INT(chn)) = alarm_value & table->data_mask; + int_en = HWREG32(regs + TSADCV2_INT_EN); + int_en |= TSADCV2_INT_SRC_EN(chn); + HWREG32(regs + TSADCV2_INT_EN) = int_en; + + return RT_EOK; +} + +static rt_err_t rk_tsadcv3_alarm_temp(const struct chip_tsadc_table *table, + int chn, void *regs, int temp) +{ + rt_uint32_t alarm_value; + + /* + * In some cases, some sensors didn't need the trip points, the + * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm + * in the end, ignore this case and disable the high temperature + * interrupt. + */ + if (temp == TEMP_INVALID) + { + HWREG32(regs + TSADCV3_HT_INT_EN) = TSADCV2_INT_SRC_EN_MASK(chn); + + return RT_EOK; + } + + alarm_value = rk_tsadcv2_temp_to_code(table, temp); + + if (alarm_value == table->data_mask) + { + return -RT_EINVAL; + } + + HWREG32(regs + TSADCV3_COMP_INT(chn)) = alarm_value & table->data_mask; + HWREG32(regs + TSADCV3_HT_INT_EN) = + TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + + return RT_EOK; +} + +static rt_err_t rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table, + int chn, void *regs, int temp) +{ + rt_uint32_t val, tshut_value = rk_tsadcv2_temp_to_code(table, temp); + + if (tshut_value == table->data_mask) + { + return -RT_EINVAL; + } + + HWREG32(regs + TSADCV2_COMP_SHUT(chn)) = tshut_value; + val = HWREG32(regs + TSADCV2_AUTO_CON); + HWREG32(regs + TSADCV2_AUTO_CON) = val | TSADCV2_AUTO_SRC_EN(chn); + + return RT_EOK; +} + +static rt_err_t rk_tsadcv3_tshut_temp(const struct chip_tsadc_table *table, + int chn, void *regs, int temp) +{ + rt_uint32_t tshut_value = rk_tsadcv2_temp_to_code(table, temp); + + if (tshut_value == table->data_mask) + { + return -RT_EINVAL; + } + + HWREG32(regs + TSADCV3_COMP_SHUT(chn)) = tshut_value; + HWREG32(regs + TSADCV3_AUTO_SRC_CON) = + TSADCV3_AUTO_SRC_EN(chn) | TSADCV3_AUTO_SRC_EN_MASK(chn); + + return RT_EOK; +} + +static void rk_tsadcv2_tshut_mode(int chn, void *regs, enum tshut_mode mode) +{ + rt_uint32_t val = HWREG32(regs + TSADCV2_INT_EN); + + if (mode == TSHUT_MODE_GPIO) + { + val &= ~TSADCV2_SHUT_2CRU_SRC_EN(chn); + val |= TSADCV2_SHUT_2GPIO_SRC_EN(chn); + } + else + { + val &= ~TSADCV2_SHUT_2GPIO_SRC_EN(chn); + val |= TSADCV2_SHUT_2CRU_SRC_EN(chn); + } + + HWREG32(regs + TSADCV2_INT_EN) = val; +} + +static void rk_tsadcv3_tshut_mode(int chn, void *regs, enum tshut_mode mode) +{ + rt_uint32_t val_gpio, val_cru; + + if (mode == TSHUT_MODE_GPIO) + { + val_gpio = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + val_cru = TSADCV2_INT_SRC_EN_MASK(chn); + } + else + { + val_cru = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + val_gpio = TSADCV2_INT_SRC_EN_MASK(chn); + } + + HWREG32(regs + TSADCV3_HSHUT_GPIO_INT_EN) = val_gpio; + HWREG32(regs + TSADCV3_HSHUT_CRU_INT_EN) = val_cru; +} + +static void rk_tsadcv4_tshut_mode(int chn, void *regs, enum tshut_mode mode) +{ + rt_uint32_t val_gpio, val_cru; + + if (mode == TSHUT_MODE_OTP) + { + val_gpio = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + val_cru = TSADCV2_INT_SRC_EN_MASK(chn); + } + else + { + val_cru = TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn); + val_gpio = TSADCV2_INT_SRC_EN_MASK(chn); + } + + HWREG32(regs + TSADCV3_HSHUT_GPIO_INT_EN) = val_gpio; + HWREG32(regs + TSADCV3_HSHUT_CRU_INT_EN) = val_cru; +} + +static const struct tsadc_table rk3328_code_table[] = +{ + { 0, -40000 }, + { 296, -40000 }, + { 304, -35000 }, + { 313, -30000 }, + { 331, -20000 }, + { 340, -15000 }, + { 349, -10000 }, + { 359, -5000 }, + { 368, 0 }, + { 378, 5000 }, + { 388, 10000 }, + { 398, 15000 }, + { 408, 20000 }, + { 418, 25000 }, + { 429, 30000 }, + { 440, 35000 }, + { 451, 40000 }, + { 462, 45000 }, + { 473, 50000 }, + { 485, 55000 }, + { 496, 60000 }, + { 508, 65000 }, + { 521, 70000 }, + { 533, 75000 }, + { 546, 80000 }, + { 559, 85000 }, + { 572, 90000 }, + { 586, 95000 }, + { 600, 100000 }, + { 614, 105000 }, + { 629, 110000 }, + { 644, 115000 }, + { 659, 120000 }, + { 675, 125000 }, + { TSADCV2_DATA_MASK, 125000 }, +}; + +static const char * const chn_name_common[] = +{ + "CPU", "GPU", +}; + +static const struct rockchip_tsadc_chip px30_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 0, + .chn_num = 2, /* 2 channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv4_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3328_code_table, + .length = RT_ARRAY_SIZE(rk3328_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rv1108_table[] = +{ + { 0, -40000 }, + { 374, -40000 }, + { 382, -35000 }, + { 389, -30000 }, + { 397, -25000 }, + { 405, -20000 }, + { 413, -15000 }, + { 421, -10000 }, + { 429, -5000 }, + { 436, 0 }, + { 444, 5000 }, + { 452, 10000 }, + { 460, 15000 }, + { 468, 20000 }, + { 476, 25000 }, + { 483, 30000 }, + { 491, 35000 }, + { 499, 40000 }, + { 507, 45000 }, + { 515, 50000 }, + { 523, 55000 }, + { 531, 60000 }, + { 539, 65000 }, + { 547, 70000 }, + { 555, 75000 }, + { 562, 80000 }, + { 570, 85000 }, + { 578, 90000 }, + { 586, 95000 }, + { 594, 100000 }, + { 602, 105000 }, + { 610, 110000 }, + { 618, 115000 }, + { 626, 120000 }, + { 634, 125000 }, + { TSADCV2_DATA_MASK, 125000 }, +}; + +static const struct rockchip_tsadc_chip rv1108_tsadc_data = +{ + /* cpu */ + .chn_offset = 0, + .chn_num = 1, /* one channel for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rv1108_table, + .length = RT_ARRAY_SIZE(rv1108_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rk3228_code_table[] = +{ + { 0, -40000 }, + { 588, -40000 }, + { 593, -35000 }, + { 598, -30000 }, + { 603, -25000 }, + { 608, -20000 }, + { 613, -15000 }, + { 618, -10000 }, + { 623, -5000 }, + { 629, 0 }, + { 634, 5000 }, + { 639, 10000 }, + { 644, 15000 }, + { 649, 20000 }, + { 654, 25000 }, + { 660, 30000 }, + { 665, 35000 }, + { 670, 40000 }, + { 675, 45000 }, + { 681, 50000 }, + { 686, 55000 }, + { 691, 60000 }, + { 696, 65000 }, + { 702, 70000 }, + { 707, 75000 }, + { 712, 80000 }, + { 717, 85000 }, + { 723, 90000 }, + { 728, 95000 }, + { 733, 100000 }, + { 738, 105000 }, + { 744, 110000 }, + { 749, 115000 }, + { 754, 120000 }, + { 760, 125000 }, + { TSADCV2_DATA_MASK, 125000 }, +}; + +static const struct rockchip_tsadc_chip rk3228_tsadc_data = +{ + /* cpu */ + .chn_offset = 0, + .chn_num = 1, /* one channel for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3228_code_table, + .length = RT_ARRAY_SIZE(rk3228_code_table), + .data_mask = TSADCV3_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rk3288_code_table[] = +{ + { TSADCV2_DATA_MASK, -40000 }, + { 3800, -40000 }, + { 3792, -35000 }, + { 3783, -30000 }, + { 3774, -25000 }, + { 3765, -20000 }, + { 3756, -15000 }, + { 3747, -10000 }, + { 3737, -5000 }, + { 3728, 0 }, + { 3718, 5000 }, + { 3708, 10000 }, + { 3698, 15000 }, + { 3688, 20000 }, + { 3678, 25000 }, + { 3667, 30000 }, + { 3656, 35000 }, + { 3645, 40000 }, + { 3634, 45000 }, + { 3623, 50000 }, + { 3611, 55000 }, + { 3600, 60000 }, + { 3588, 65000 }, + { 3575, 70000 }, + { 3563, 75000 }, + { 3550, 80000 }, + { 3537, 85000 }, + { 3524, 90000 }, + { 3510, 95000 }, + { 3496, 100000 }, + { 3482, 105000 }, + { 3467, 110000 }, + { 3452, 115000 }, + { 3437, 120000 }, + { 3421, 125000 }, + { 0, 125000 }, +}; + +static const struct rockchip_tsadc_chip rk3288_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 1, + .chn_num = 2, /* two channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv2_irq_ack, + .control = rk_tsadcv2_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3288_code_table, + .length = RT_ARRAY_SIZE(rk3288_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_DECREMENT, + }, +}; + +static const struct rockchip_tsadc_chip rk3308_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 0, + .chn_num = 2, /* two channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3328_code_table, + .length = RT_ARRAY_SIZE(rk3328_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct rockchip_tsadc_chip rk3328_tsadc_data = +{ + /* cpu */ + .chn_offset = 0, + .chn_num = 1, /* one channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_CRU, /* default TSHUT via CRU */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3328_code_table, + .length = RT_ARRAY_SIZE(rk3328_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct rockchip_tsadc_chip rk3366_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 0, + .chn_num = 2, /* two channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv3_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3228_code_table, + .length = RT_ARRAY_SIZE(rk3228_code_table), + .data_mask = TSADCV3_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rk3368_code_table[] = +{ + { 0, -40000 }, + { 106, -40000 }, + { 108, -35000 }, + { 110, -30000 }, + { 112, -25000 }, + { 114, -20000 }, + { 116, -15000 }, + { 118, -10000 }, + { 120, -5000 }, + { 122, 0 }, + { 124, 5000 }, + { 126, 10000 }, + { 128, 15000 }, + { 130, 20000 }, + { 132, 25000 }, + { 134, 30000 }, + { 136, 35000 }, + { 138, 40000 }, + { 140, 45000 }, + { 142, 50000 }, + { 144, 55000 }, + { 146, 60000 }, + { 148, 65000 }, + { 150, 70000 }, + { 152, 75000 }, + { 154, 80000 }, + { 156, 85000 }, + { 158, 90000 }, + { 160, 95000 }, + { 162, 100000 }, + { 163, 105000 }, + { 165, 110000 }, + { 167, 115000 }, + { 169, 120000 }, + { 171, 125000 }, + { TSADCV3_DATA_MASK, 125000 }, +}; + +static const struct rockchip_tsadc_chip rk3368_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 0, + .chn_num = 2, /* two channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv2_initialize, + .irq_ack = rk_tsadcv2_irq_ack, + .control = rk_tsadcv2_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3368_code_table, + .length = RT_ARRAY_SIZE(rk3368_code_table), + .data_mask = TSADCV3_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rk3399_code_table[] = +{ + { 0, -40000 }, + { 402, -40000 }, + { 410, -35000 }, + { 419, -30000 }, + { 427, -25000 }, + { 436, -20000 }, + { 444, -15000 }, + { 453, -10000 }, + { 461, -5000 }, + { 470, 0 }, + { 478, 5000 }, + { 487, 10000 }, + { 496, 15000 }, + { 504, 20000 }, + { 513, 25000 }, + { 521, 30000 }, + { 530, 35000 }, + { 538, 40000 }, + { 547, 45000 }, + { 555, 50000 }, + { 564, 55000 }, + { 573, 60000 }, + { 581, 65000 }, + { 590, 70000 }, + { 599, 75000 }, + { 607, 80000 }, + { 616, 85000 }, + { 624, 90000 }, + { 633, 95000 }, + { 642, 100000 }, + { 650, 105000 }, + { 659, 110000 }, + { 668, 115000 }, + { 677, 120000 }, + { 685, 125000 }, + { TSADCV3_DATA_MASK, 125000 }, +}; + +static const struct rockchip_tsadc_chip rk3399_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 0, + .chn_num = 2, /* two channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv3_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3399_code_table, + .length = RT_ARRAY_SIZE(rk3399_code_table), + .data_mask = TSADCV3_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rk3568_code_table[] = +{ + { 0, -40000 }, + { 1584, -40000 }, + { 1620, -35000 }, + { 1652, -30000 }, + { 1688, -25000 }, + { 1720, -20000 }, + { 1756, -15000 }, + { 1788, -10000 }, + { 1824, -5000 }, + { 1856, 0 }, + { 1892, 5000 }, + { 1924, 10000 }, + { 1956, 15000 }, + { 1992, 20000 }, + { 2024, 25000 }, + { 2060, 30000 }, + { 2092, 35000 }, + { 2128, 40000 }, + { 2160, 45000 }, + { 2196, 50000 }, + { 2228, 55000 }, + { 2264, 60000 }, + { 2300, 65000 }, + { 2332, 70000 }, + { 2368, 75000 }, + { 2400, 80000 }, + { 2436, 85000 }, + { 2468, 90000 }, + { 2500, 95000 }, + { 2536, 100000 }, + { 2572, 105000 }, + { 2604, 110000 }, + { 2636, 115000 }, + { 2672, 120000 }, + { 2704, 125000 }, + { TSADCV2_DATA_MASK, 125000 }, +}; + +static const struct rockchip_tsadc_chip rk3568_tsadc_data = +{ + /* cpu, gpu */ + .chn_offset = 0, + .chn_num = 2, /* two channels for tsadc */ + .chn_name = chn_name_common, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + + .initialize = rk_tsadcv7_initialize, + .irq_ack = rk_tsadcv3_irq_ack, + .control = rk_tsadcv3_control, + .get_temp = rk_tsadcv2_get_temp, + .set_alarm_temp = rk_tsadcv2_alarm_temp, + .set_tshut_temp = rk_tsadcv2_tshut_temp, + .set_tshut_mode = rk_tsadcv2_tshut_mode, + + .table = + { + .id = rk3568_code_table, + .length = RT_ARRAY_SIZE(rk3568_code_table), + .data_mask = TSADCV2_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const struct tsadc_table rk3588_code_table[] = +{ + { 0, -40000 }, + { 215, -40000 }, + { 285, 25000 }, + { 350, 85000 }, + { 395, 125000 }, + { TSADCV4_DATA_MASK, 125000 }, +}; + +static const char * const chn_name_rk3588[] = +{ + "Top", "Big Core0", "Big Core1", "Little Core", "Center", "GPU", "NPU", +}; + +static const struct rockchip_tsadc_chip rk3588_tsadc_data = +{ + /* top, big_core0, big_core1, little_core, center, gpu, npu */ + .chn_offset = 0, + .chn_num = 7, /* seven channels for tsadc */ + .chn_name = chn_name_rk3588, + + .tshut_mode = TSHUT_MODE_GPIO, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + .initialize = rk_tsadcv8_initialize, + .irq_ack = rk_tsadcv4_irq_ack, + .control = rk_tsadcv4_control, + .get_temp = rk_tsadcv4_get_temp, + .set_alarm_temp = rk_tsadcv3_alarm_temp, + .set_tshut_temp = rk_tsadcv3_tshut_temp, + .set_tshut_mode = rk_tsadcv3_tshut_mode, + .table = + { + .id = rk3588_code_table, + .length = RT_ARRAY_SIZE(rk3588_code_table), + .data_mask = TSADCV4_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static const char * const chn_name_rk3576[] = +{ + "Top", "Big Core", "Little Core", "DDR", "NPU", "GPU", +}; + +static const struct rockchip_tsadc_chip rk3576_tsadc_data = +{ + /* top, big_core, little_core, ddr, npu, gpu */ + .chn_num = 6, /* six channels for tsadc */ + .chn_name = chn_name_rk3576, + + .tshut_mode = TSHUT_MODE_OTP, /* default TSHUT via GPIO give PMIC */ + .tshut_polarity = TSHUT_LOW_ACTIVE, /* default TSHUT LOW ACTIVE */ + .tshut_temp = 95000, + .initialize = rk_tsadcv8_initialize, + .irq_ack = rk_tsadcv4_irq_ack, + .control = rk_tsadcv4_control, + .get_temp = rk_tsadcv4_get_temp, + .set_alarm_temp = rk_tsadcv3_alarm_temp, + .set_tshut_temp = rk_tsadcv3_tshut_temp, + .set_tshut_mode = rk_tsadcv4_tshut_mode, + .table = + { + .id = rk3588_code_table, + .length = RT_ARRAY_SIZE(rk3588_code_table), + .data_mask = TSADCV4_DATA_MASK, + .mode = ADC_INCREMENT, + }, +}; + +static rt_err_t rk_tsadc_thermal_zone_get_temp(struct rt_thermal_zone_device *zdev, + int *out_temp) +{ + struct rockchip_tsadc *rk_tsadc; + const struct rockchip_tsadc_chip *chip; + struct rockchip_tsadc_channel *channel = raw_to_rockchip_tsadc_channel(zdev); + + rk_tsadc = channel->rk_tsadc; + chip = rk_tsadc->chip; + + return chip->get_temp(&chip->table, channel->id, rk_tsadc->regs, out_temp); +} + +static rt_err_t rk_tsadc_thermal_zone_set_trips(struct rt_thermal_zone_device *zdev, + int low_temp, int high_temp) +{ + struct rockchip_tsadc *rk_tsadc; + const struct rockchip_tsadc_chip *chip; + struct rockchip_tsadc_channel *channel = raw_to_rockchip_tsadc_channel(zdev); + + rk_tsadc = channel->rk_tsadc; + chip = rk_tsadc->chip; + + LOG_D("Channel[%d]<%s> set trip alarm %d ~ %d", + zdev->zone_id, + chip->chn_name[zdev->zone_id - chip->chn_offset], + low_temp, high_temp); + + return chip->set_alarm_temp(&rk_tsadc->chip->table, channel->id, rk_tsadc->regs, high_temp); +} + +const static struct rt_thermal_zone_ops rk_tsadc_thermal_zone_ops = +{ + .get_temp = rk_tsadc_thermal_zone_get_temp, + .set_trips = rk_tsadc_thermal_zone_set_trips, +}; + +static void rk_tsadc_isr(int irqno, void *param) +{ + struct rockchip_tsadc *rk_tsadc = param; + const struct rockchip_tsadc_chip *chip = rk_tsadc->chip; + + chip->irq_ack(rk_tsadc->regs); + + for (int i = 0; i < chip->chn_num; ++i) + { + struct rockchip_tsadc_channel *channel = &rk_tsadc->channels[i]; + + rt_thermal_zone_device_update(&channel->parent, RT_THERMAL_MSG_EVENT_UNSPECIFIED); + } +} + +static rt_err_t rockchip_tsadc_parse_ofw(struct rt_device *dev, + struct rockchip_tsadc *rk_tsadc) +{ + struct rt_ofw_node *np = dev->ofw_node; + rt_uint32_t shut_temp, tshut_mode, tshut_polarity; + + if (rt_ofw_prop_read_u32(np, "rockchip,hw-tshut-temp", &shut_temp)) + { + rk_tsadc->tshut_temp = rk_tsadc->chip->tshut_temp; + } + else + { + if (shut_temp > TEMP_INVALID) + { + LOG_E("Invalid tshut temperature specified: %d", shut_temp); + + return -RT_EINVAL; + } + + rk_tsadc->tshut_temp = shut_temp; + } + + if (rt_ofw_prop_read_u32(np, "rockchip,hw-tshut-mode", &tshut_mode)) + { + LOG_W("Missing tshut mode property, using default (%s)", + rk_tsadc->chip->tshut_mode == TSHUT_MODE_GPIO ? "gpio" : "cru"); + + rk_tsadc->tshut_mode = rk_tsadc->chip->tshut_mode; + } + else + { + rk_tsadc->tshut_mode = tshut_mode; + } + + if (rk_tsadc->tshut_mode > 1) + { + LOG_E("Invalid tshut mode specified: %d", rk_tsadc->tshut_mode); + + return -RT_EINVAL; + } + + if (rt_ofw_prop_read_u32(np, "rockchip,hw-tshut-polarity", &tshut_polarity)) + { + LOG_W("Missing tshut-polarity property, using default (%s)", + rk_tsadc->chip->tshut_polarity == TSHUT_LOW_ACTIVE ? "low" : "high"); + + rk_tsadc->tshut_polarity = rk_tsadc->chip->tshut_polarity; + } + else + { + rk_tsadc->tshut_polarity = tshut_polarity; + } + + if (rk_tsadc->tshut_polarity > 1) + { + LOG_E("Invalid tshut-polarity specified: %d", rk_tsadc->tshut_polarity); + + return -RT_EINVAL; + } + + rk_tsadc->grf = rt_syscon_find_by_ofw_phandle(np, "rockchip,grf"); + + if (!rk_tsadc->grf) + { + LOG_W("Missing %s property", "rockchip,grf"); + } + + return RT_EOK; +} + +static void rockchip_tsadc_reset_controller(struct rockchip_tsadc *rk_tsadc) +{ + rt_reset_control_assert(rk_tsadc->rstc); + rt_hw_us_delay(15); + rt_reset_control_deassert(rk_tsadc->rstc); +} + +static void rockchip_tsadc_free(struct rockchip_tsadc *rk_tsadc) +{ + if (!rt_is_err_or_null(rk_tsadc->rstc)) + { + rt_reset_control_assert(rk_tsadc->rstc); + rt_reset_control_put(rk_tsadc->rstc); + } + + if (!rt_is_err_or_null(rk_tsadc->clk)) + { + rt_clk_disable(rk_tsadc->clk); + rt_clk_put(rk_tsadc->clk); + } + + if (!rt_is_err_or_null(rk_tsadc->pclk)) + { + rt_clk_disable(rk_tsadc->pclk); + rt_clk_put(rk_tsadc->pclk); + } + + rt_free(rk_tsadc); +} + +static rt_err_t rockchip_tsadc_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + const struct chip_tsadc_table *table; + struct rt_device *dev = &pdev->parent; + const struct rockchip_tsadc_chip *chip = pdev->id->data; + struct rockchip_tsadc *rk_tsadc = rt_calloc(1, sizeof(*rk_tsadc) + + sizeof(rk_tsadc->channels[0]) * chip->chn_num); + + if (!rk_tsadc) + { + return -RT_ENOMEM; + } + + rk_tsadc->chip = chip; + table = &rk_tsadc->chip->table; + rk_tsadc->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk_tsadc->irq < 0) + { + err = rk_tsadc->irq; + goto _fail; + } + + rk_tsadc->regs = rt_dm_dev_iomap(dev, 0); + + if (!rk_tsadc->regs) + { + err = -RT_EIO; + goto _fail; + } + + rk_tsadc->rstc = rt_reset_control_get_array(dev); + + if (rt_is_err(rk_tsadc->rstc)) + { + err = rt_ptr_err(rk_tsadc->rstc); + goto _fail; + } + + rockchip_tsadc_reset_controller(rk_tsadc); + + rk_tsadc->clk = rt_clk_get_by_name(dev, "tsadc"); + + if (rt_is_err(rk_tsadc->clk)) + { + err = rt_ptr_err(rk_tsadc->clk); + goto _fail; + } + + rk_tsadc->pclk = rt_clk_get_by_name(dev, "apb_pclk"); + + if (rt_is_err(rk_tsadc->pclk)) + { + err = rt_ptr_err(rk_tsadc->pclk); + goto _fail; + } + + if ((err = rt_clk_enable(rk_tsadc->clk))) + { + goto _fail; + } + + if ((err = rt_clk_enable(rk_tsadc->pclk))) + { + goto _fail; + } + + if ((err = rockchip_tsadc_parse_ofw(dev, rk_tsadc))) + { + goto _fail; + } + + rk_tsadc->chip->initialize(rk_tsadc->grf, rk_tsadc->regs, rk_tsadc->tshut_polarity); + + for (int i = 0; i < rk_tsadc->chip->chn_num; ++i) + { + struct rockchip_tsadc_channel *channel = &rk_tsadc->channels[i]; + struct rt_thermal_zone_device *tz = &channel->parent; + + tz->zone_id = chip->chn_offset + i; + channel->id = tz->zone_id; + channel->rk_tsadc = rk_tsadc; + + chip->set_tshut_mode(channel->id, rk_tsadc->regs, rk_tsadc->tshut_mode); + chip->set_tshut_temp(table, channel->id, rk_tsadc->regs, rk_tsadc->tshut_temp); + + tz->ops = &rk_tsadc_thermal_zone_ops; + tz->parent.ofw_node = dev->ofw_node; + + rt_dm_dev_set_name(&tz->parent, "tsadc-%s", rk_tsadc->chip->chn_name[i]); + + rt_thermal_zone_device_register(tz); + } + + rk_tsadc->chip->control(rk_tsadc->regs, RT_TRUE); + + rt_hw_interrupt_install(rk_tsadc->irq, rk_tsadc_isr, rk_tsadc, "tsadc"); + rt_hw_interrupt_umask(rk_tsadc->irq); + + dev->user_data = rk_tsadc; + + return RT_EOK; + +_fail: + rockchip_tsadc_free(rk_tsadc); + + return err; +} + +static rt_err_t rockchip_tsadc_remove(struct rt_platform_device *pdev) +{ + struct rockchip_tsadc *rk_tsadc = pdev->parent.user_data; + + for (int i = 0; i < rk_tsadc->chip->chn_num; ++i) + { + struct rockchip_tsadc_channel *channel = &rk_tsadc->channels[i]; + + rt_thermal_zone_device_unregister(&channel->parent); + } + + rockchip_tsadc_free(rk_tsadc); + + return RT_EOK; +} + +static const struct rt_ofw_node_id rockchip_tsadc_ofw_ids[] = +{ + { .compatible = "rockchip,px30-tsadc", .data = &px30_tsadc_data, }, + { .compatible = "rockchip,rv1108-tsadc", .data = &rv1108_tsadc_data, }, + { .compatible = "rockchip,rk3228-tsadc", .data = &rk3228_tsadc_data, }, + { .compatible = "rockchip,rk3288-tsadc", .data = &rk3288_tsadc_data, }, + { .compatible = "rockchip,rk3308-tsadc", .data = &rk3308_tsadc_data, }, + { .compatible = "rockchip,rk3328-tsadc", .data = &rk3328_tsadc_data, }, + { .compatible = "rockchip,rk3366-tsadc", .data = &rk3366_tsadc_data, }, + { .compatible = "rockchip,rk3368-tsadc", .data = &rk3368_tsadc_data, }, + { .compatible = "rockchip,rk3399-tsadc", .data = &rk3399_tsadc_data, }, + { .compatible = "rockchip,rk3568-tsadc", .data = &rk3568_tsadc_data, }, + { .compatible = "rockchip,rk3576-tsadc", .data = &rk3576_tsadc_data, }, + { .compatible = "rockchip,rk3588-tsadc", .data = &rk3588_tsadc_data, }, + { /* sentinel */ } +}; + +static struct rt_platform_driver rockchip_tsadc_driver = +{ + .name = "rockchip-tsadc", + .ids = rockchip_tsadc_ofw_ids, + + .probe = rockchip_tsadc_probe, + .remove = rockchip_tsadc_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rockchip_tsadc_driver); diff --git a/bsp/rockchip/dm/watchdog/Kconfig b/bsp/rockchip/dm/watchdog/Kconfig new file mode 100755 index 00000000000..0a3640d3acb --- /dev/null +++ b/bsp/rockchip/dm/watchdog/Kconfig @@ -0,0 +1,3 @@ +config RT_WDT_RK8XX + bool "Rockchip RK806 watchdog" + depends on RT_MFD_RK8XX diff --git a/bsp/rockchip/dm/watchdog/SConscript b/bsp/rockchip/dm/watchdog/SConscript new file mode 100755 index 00000000000..21e85e3dbe2 --- /dev/null +++ b/bsp/rockchip/dm/watchdog/SConscript @@ -0,0 +1,13 @@ +from building import * + +group = [] +src = [] +cwd = GetCurrentDir() +CPPPATH = [cwd + '/../include'] + +if GetDepend(['RT_WDT_RK8XX']): + src += ['watchdog-rk8xx.c'] + +group = DefineGroup('DeviceDrivers', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/bsp/rockchip/dm/watchdog/watchdog-rk8xx.c b/bsp/rockchip/dm/watchdog/watchdog-rk8xx.c new file mode 100755 index 00000000000..9dc36338b02 --- /dev/null +++ b/bsp/rockchip/dm/watchdog/watchdog-rk8xx.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-11-26 GuEe-GUI first version + */ + +#include +#include + +#define DBG_TAG "wdt.rk8xx" +#define DBG_LVL DBG_INFO +#include + +#include "rk8xx.h" + +struct rk8xx_watchdog +{ + rt_watchdog_t parent; + + int irq; + rt_uint8_t timeout_idx; + struct rk8xx *rk8xx; +}; + +#define raw_to_rk8xx_watchdog(raw) rt_container_of(raw, struct rk8xx_watchdog, parent) + +static const unsigned int time_ms_ranges[] = +{ + [0] = 50, /* 50 ms */ + [1] = 100, /* 100 ms */ + [2] = 500, /* 500 ms */ + [4] = 2 * 1000, /* 2 s */ + [5] = 10 * 1000, /* 10 s */ + [6] = 60 * 1000, /* 1 min */ + [7] = 10 * 60 * 10000, /* 10 min */ +}; + +static rt_err_t rk8xx_watchdog_enable(struct rk8xx_watchdog *rk8xx_wdt, + rt_bool_t enable) +{ + return rk8xx_update_bits(rk8xx_wdt->rk8xx, RK806_WDT, RK806_WDT_EN, !!enable); +} + +static rt_err_t rk8xx_watchdog_keep_alive(struct rk8xx_watchdog *rk8xx_wdt) +{ + rt_err_t err; + /* + * Should to clear the interruption of WDT after set time, + * otherwise the time will advance 1S. + */ + rk8xx_watchdog_enable(rk8xx_wdt, RT_FALSE); + + err = rk8xx_update_bits(rk8xx_wdt->rk8xx, RK806_WDT, RK806_WDT_SET, + rk8xx_wdt->timeout_idx); + + rk8xx_watchdog_enable(rk8xx_wdt, RT_TRUE); + + return err; +} + +static rt_err_t rk8xx_watchdog_init(rt_watchdog_t *wdt) +{ + return RT_EOK; +} + +static rt_err_t rk8xx_watchdog_control(rt_watchdog_t *wdt, int cmd, void *args) +{ + rt_err_t err = RT_EOK; + struct rk8xx_watchdog *rk8xx_wdt = raw_to_rk8xx_watchdog(wdt); + + switch (cmd) + { + case RT_DEVICE_CTRL_WDT_GET_TIMEOUT: + *(rt_uint32_t *)args = time_ms_ranges[rk8xx_wdt->timeout_idx] / 1000; + break; + + case RT_DEVICE_CTRL_WDT_SET_TIMEOUT: + { + rt_uint32_t timeout = *(rt_uint32_t *)args * 1000; + err = -RT_EINVAL; + + for (int i = RT_ARRAY_SIZE(time_ms_ranges) - 1; i >= 0; --i) + { + if (timeout >= time_ms_ranges[i]) + { + rk8xx_wdt->timeout_idx = i; + + err = RT_EOK; + break; + } + } + } + break; + + case RT_DEVICE_CTRL_WDT_KEEPALIVE: + err = rk8xx_watchdog_keep_alive(rk8xx_wdt); + break; + + case RT_DEVICE_CTRL_WDT_START: + err = rk8xx_watchdog_enable(rk8xx_wdt, RT_TRUE); + break; + + case RT_DEVICE_CTRL_WDT_STOP: + err = rk8xx_watchdog_enable(rk8xx_wdt, RT_FALSE); + break; + + default: + err = -RT_EINVAL; + } + + return err; +} + +static const struct rt_watchdog_ops rk8xx_watchdog_ops = +{ + .init = rk8xx_watchdog_init, + .control = rk8xx_watchdog_control, +}; + +static rt_err_t rk8xx_watchdog_probe(struct rt_platform_device *pdev) +{ + rt_err_t err; + const char *dev_name; + struct rk8xx *rk8xx = pdev->priv; + struct rt_device *dev = &pdev->parent; + struct rk8xx_watchdog *rk8xx_wdt = rt_calloc(1, sizeof(*rk8xx_wdt)); + + if (!rk8xx_wdt) + { + return -RT_ENOMEM; + } + + rk8xx_wdt->rk8xx = rk8xx; + + rk8xx_wdt->irq = rt_dm_dev_get_irq(dev, 0); + + if (rk8xx_wdt->irq < 0) + { + err = rk8xx_wdt->irq; + goto _fail; + } + + if ((err = rk8xx_update_bits(rk8xx, RK806_WDT, RK806_WDT_ACT, RK806_WDT_ACT_RESTART))) + { + goto _fail; + } + + dev->user_data = rk8xx_wdt; + + rk8xx_wdt->parent.ops = &rk8xx_watchdog_ops; + + rt_dm_dev_set_name_auto(&rk8xx_wdt->parent.parent, "wdt"); + dev_name = rt_dm_dev_get_name(&rk8xx_wdt->parent.parent); + + rt_hw_watchdog_register(&rk8xx_wdt->parent, dev_name, 0, rk8xx_wdt); + + return RT_EOK; + +_fail: + rt_free(rk8xx_wdt); + + return err; +} + +static rt_err_t rk8xx_watchdog_remove(struct rt_platform_device *pdev) +{ + struct rk8xx_watchdog *rk8xx_wdt = pdev->parent.user_data; + + rk8xx_watchdog_enable(rk8xx_wdt, RT_FALSE); + + rt_device_unregister(&rk8xx_wdt->parent.parent); + + rt_free(rk8xx_wdt); + + return RT_EOK; +} + +static struct rt_platform_driver rk8xx_watchdog_driver = +{ + .name = "rk8xx-watchdog", + .probe = rk8xx_watchdog_probe, + .remove = rk8xx_watchdog_remove, +}; +RT_PLATFORM_DRIVER_EXPORT(rk8xx_watchdog_driver); diff --git a/bsp/rockchip/rk3568/.config b/bsp/rockchip/rk3300/.config similarity index 85% rename from bsp/rockchip/rk3568/.config rename to bsp/rockchip/rk3300/.config index 9ddecd59f09..18e027b3f7c 100644 --- a/bsp/rockchip/rk3568/.config +++ b/bsp/rockchip/rk3300/.config @@ -12,17 +12,7 @@ # # CONFIG_RT_KLIBC_USING_LIBC_VSNPRINTF is not set CONFIG_RT_KLIBC_USING_VSNPRINTF_LONGLONG=y -CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD=y -CONFIG_RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS=y -CONFIG_RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS=y -CONFIG_RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER=y -CONFIG_RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER=y -# CONFIG_RT_KLIBC_USING_VSNPRINTF_MSVC_STYLE_INTEGER_SPECIFIERS is not set -CONFIG_RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE=32 -CONFIG_RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE=32 -CONFIG_RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION=6 -CONFIG_RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL=9 -CONFIG_RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS=4 +# CONFIG_RT_KLIBC_USING_VSNPRINTF_STANDARD is not set # end of rt_vsnprintf options # @@ -116,10 +106,10 @@ CONFIG_RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS=4 # end of rt_strnlen options # end of klibc options -CONFIG_RT_NAME_MAX=12 +CONFIG_RT_NAME_MAX=24 # CONFIG_RT_USING_ARCH_DATA_TYPE is not set # CONFIG_RT_USING_NANO is not set -# CONFIG_RT_USING_SMART is not set +CONFIG_RT_USING_SMART=y # CONFIG_RT_USING_AMP is not set CONFIG_RT_USING_SMP=y CONFIG_RT_CPUS_NR=4 @@ -141,7 +131,7 @@ CONFIG_RT_USING_TIMER_SOFT=y CONFIG_RT_TIMER_THREAD_PRIO=4 CONFIG_RT_TIMER_THREAD_STACK_SIZE=4096 # CONFIG_RT_USING_TIMER_ALL_SOFT is not set -# CONFIG_RT_USING_CPU_USAGE_TRACER is not set +CONFIG_RT_USING_CPU_USAGE_TRACER=y # # kservice options @@ -155,7 +145,7 @@ CONFIG_RT_DEBUGING_COLOR=y CONFIG_RT_DEBUGING_CONTEXT=y # CONFIG_RT_DEBUGING_AUTO_INIT is not set # CONFIG_RT_DEBUGING_SPINLOCK is not set -# CONFIG_RT_DEBUGING_CRITICAL is not set +CONFIG_RT_DEBUGING_CRITICAL=y # CONFIG_RT_USING_CI_ACTION is not set # @@ -191,13 +181,13 @@ CONFIG_RT_USING_HEAP=y CONFIG_RT_USING_DEVICE=y CONFIG_RT_USING_DEVICE_OPS=y -# CONFIG_RT_USING_INTERRUPT_INFO is not set -# CONFIG_RT_USING_THREADSAFE_PRINTF is not set +CONFIG_RT_USING_INTERRUPT_INFO=y +CONFIG_RT_USING_THREADSAFE_PRINTF=y CONFIG_RT_USING_CONSOLE=y -CONFIG_RT_CONSOLEBUF_SIZE=128 +CONFIG_RT_CONSOLEBUF_SIZE=256 CONFIG_RT_CONSOLE_DEVICE_NAME="uart2" -CONFIG_RT_VER_NUM=0x50201 -# CONFIG_RT_USING_STDC_ATOMIC is not set +CONFIG_RT_VER_NUM=0x50300 +CONFIG_RT_USING_STDC_ATOMIC=y CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 # end of RT-Thread Kernel @@ -205,7 +195,7 @@ CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 # AArch64 Architecture Configuration # CONFIG_ARCH_TEXT_OFFSET=0x200000 -CONFIG_ARCH_RAM_OFFSET=0 +CONFIG_ARCH_RAM_OFFSET=0x0 CONFIG_ARCH_SECONDARY_CPU_STACK_SIZE=4096 CONFIG_ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS=y CONFIG_ARCH_USING_GENERIC_CPUID=y @@ -215,17 +205,11 @@ CONFIG_ARCH_INIT_PAGE_SIZE=0x200000 CONFIG_ARCH_CPU_64BIT=y CONFIG_RT_USING_CACHE=y -CONFIG_RT_USING_HW_ATOMIC=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_ARCH_ARM_CORTEX_A=y -CONFIG_RT_NO_USING_GIC=y -CONFIG_ARCH_ARM_CORTEX_A55=y -# CONFIG_ARCH_ARM_SECURE_MODE is not set -# CONFIG_RT_BACKTRACE_FUNCTION_NAME is not set +CONFIG_KERNEL_VADDR_START=0xffff000000000000 CONFIG_ARCH_ARMV8=y CONFIG_ARCH_USING_ASID=y CONFIG_ARCH_USING_HW_THREAD_SELF=y @@ -244,7 +228,7 @@ 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=4096 +CONFIG_FINSH_THREAD_STACK_SIZE=8192 CONFIG_FINSH_USING_HISTORY=y CONFIG_FINSH_HISTORY_LINES=5 # CONFIG_FINSH_USING_WORD_OPERATION is not set @@ -261,7 +245,56 @@ CONFIG_FINSH_USING_OPTION_COMPLETION=y # # DFS: device virtual file system # -# CONFIG_RT_USING_DFS is not set +CONFIG_RT_USING_DFS=y +CONFIG_DFS_USING_POSIX=y +CONFIG_DFS_USING_WORKDIR=y +CONFIG_DFS_FD_MAX=16 +CONFIG_RT_USING_DFS_V2=y +CONFIG_RT_USING_DFS_ELMFAT=y + +# +# elm-chan's FatFs, Generic FAT Filesystem Module +# +CONFIG_RT_DFS_ELM_CODE_PAGE=437 +CONFIG_RT_DFS_ELM_WORD_ACCESS=y +# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set +# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set +CONFIG_RT_DFS_ELM_USE_LFN_3=y +CONFIG_RT_DFS_ELM_USE_LFN=3 +CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y +# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set +# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set +# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set +CONFIG_RT_DFS_ELM_LFN_UNICODE=0 +CONFIG_RT_DFS_ELM_MAX_LFN=255 +CONFIG_RT_DFS_ELM_DRIVES=2 +CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512 +# CONFIG_RT_DFS_ELM_USE_ERASE is not set +CONFIG_RT_DFS_ELM_REENTRANT=y +CONFIG_RT_DFS_ELM_MUTEX_TIMEOUT=3000 +# CONFIG_RT_DFS_ELM_USE_EXFAT is not set +# end of elm-chan's FatFs, Generic FAT Filesystem Module + +CONFIG_RT_USING_DFS_DEVFS=y +# CONFIG_RT_USING_DFS_ROMFS is not set +CONFIG_RT_USING_DFS_PTYFS=y +CONFIG_RT_USING_DFS_PROCFS=y +# CONFIG_RT_USING_DFS_CROMFS is not set +# CONFIG_RT_USING_DFS_TMPFS is not set +CONFIG_RT_USING_DFS_MQUEUE=y +CONFIG_RT_USING_PAGECACHE=y + +# +# page cache config +# +CONFIG_RT_PAGECACHE_COUNT=4096 +CONFIG_RT_PAGECACHE_ASPACE_COUNT=1024 +CONFIG_RT_PAGECACHE_PRELOAD=4 +CONFIG_RT_PAGECACHE_HASH_NR=1024 +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 @@ -270,68 +303,194 @@ CONFIG_FINSH_USING_OPTION_COMPLETION=y # Device Drivers # CONFIG_RT_USING_DM=y -# CONFIG_RT_USING_DEV_BUS is not set +CONFIG_RT_USING_DEV_BUS=y CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_UNAMED_PIPE_NUMBER=64 -# CONFIG_RT_USING_SYSTEM_WORKQUEUE is not set +CONFIG_RT_USING_SYSTEM_WORKQUEUE=y +CONFIG_RT_SYSTEM_WORKQUEUE_STACKSIZE=8192 +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_SERIAL_BYPASS is not set +CONFIG_RT_USING_SERIAL_BYPASS=y +# CONFIG_RT_SERIAL_EARLY_HVC is not set +# CONFIG_RT_SERIAL_PL011 is not set +CONFIG_RT_SERIAL_8250=y +CONFIG_RT_SERIAL_8250_DW=y # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_CPUTIME is not set -# CONFIG_RT_USING_I2C is not set +CONFIG_RT_USING_I2C=y +# CONFIG_RT_I2C_DEBUG is not set +CONFIG_RT_USING_I2C_BITOPS=y +# CONFIG_RT_I2C_BITOPS_DEBUG is not set +# CONFIG_RT_USING_SOFT_I2C is not set +CONFIG_RT_I2C_RK3X=y # CONFIG_RT_USING_PHY is not set # CONFIG_RT_USING_PHY_V2 is not set -# CONFIG_RT_USING_ADC is not set +CONFIG_RT_USING_ADC=y +CONFIG_RT_ADC_ROCKCHIP_SARADC=y # CONFIG_RT_USING_DAC is not set -# CONFIG_RT_USING_NULL is not set -# CONFIG_RT_USING_ZERO is not set -# CONFIG_RT_USING_RANDOM is not set -# CONFIG_RT_USING_PWM is not set +CONFIG_RT_USING_NULL=y +CONFIG_RT_USING_ZERO=y +CONFIG_RT_USING_RANDOM=y +CONFIG_RT_USING_PWM=y +CONFIG_RT_PWM_ROCKCHIP=y # 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=y -CONFIG_PM_TICKLESS_THRESHOLD_TIME=2 -# CONFIG_PM_USING_CUSTOM_CONFIG is not set -# CONFIG_PM_ENABLE_DEBUG is not set -# CONFIG_PM_ENABLE_SUSPEND_SLEEP_MODE is not set -# CONFIG_PM_ENABLE_THRESHOLD_SLEEP_MODE is not set -# CONFIG_RT_USING_RTC is not set -# CONFIG_RT_USING_SDIO is not set -# CONFIG_RT_USING_SPI is not set -# CONFIG_RT_USING_WDT is not set +# CONFIG_RT_USING_PM is not set +CONFIG_RT_USING_RTC=y +CONFIG_RT_USING_ALARM=y +CONFIG_RT_ALARM_STACK_SIZE=4096 +CONFIG_RT_ALARM_TIMESLICE=5 +CONFIG_RT_ALARM_PRIORITY=10 +# CONFIG_RT_ALARM_USING_LOCAL_TIME is not set +# CONFIG_RT_USING_SOFT_RTC is not set +# CONFIG_RT_RTC_DS1302 is not set +# CONFIG_RT_RTC_DS1307 is not set +# CONFIG_RT_RTC_GOLDFISH is not set +# CONFIG_RT_RTC_HYM8563 is not set +# CONFIG_RT_RTC_PCF8523 is not set +# CONFIG_RT_RTC_PCF8563 is not set +# CONFIG_RT_RTC_PL031 is not set +# CONFIG_RT_RTC_RX8010 is not set +CONFIG_RT_RTC_RK_TIMER=y +CONFIG_RT_USING_SDIO=y +CONFIG_RT_SDIO_STACK_SIZE=8192 +CONFIG_RT_SDIO_THREAD_PRIORITY=15 +CONFIG_RT_MMCSD_STACK_SIZE=8192 +CONFIG_RT_MMCSD_THREAD_PRIORITY=22 +CONFIG_RT_MMCSD_MAX_PARTITION=16 +# CONFIG_RT_SDIO_DEBUG is not set +# CONFIG_RT_USING_SDHCI is not set +CONFIG_RT_SDIO_DW_MMC=y +CONFIG_RT_SDIO_DW_MMC_ROCKCHIP=y +CONFIG_RT_USING_SPI=y +CONFIG_RT_USING_SPI_ISR=y +# CONFIG_RT_USING_SPI_BITOPS is not set +# CONFIG_RT_USING_SOFT_SPI is not set +CONFIG_RT_USING_QSPI=y +# CONFIG_RT_USING_SPI_MSD is not set +# CONFIG_RT_USING_SFUD is not set +# CONFIG_RT_USING_ENC28J60 is not set +# CONFIG_RT_USING_SPI_WIFI is not set +CONFIG_RT_SPI_ROCKCHIP_SFC=y +CONFIG_RT_SPI_ROCKCHIP=y +CONFIG_RT_USING_WDT=y +CONFIG_RT_WDT_DW=y # 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_GRAPHIC is not set +CONFIG_RT_USING_HWCRYPTO=y +CONFIG_RT_HWCRYPTO_DEFAULT_NAME="hwcryto" +CONFIG_RT_HWCRYPTO_IV_MAX_SIZE=16 +CONFIG_RT_HWCRYPTO_KEYBIT_MAX_SIZE=256 +# CONFIG_RT_HWCRYPTO_USING_GCM is not set +# CONFIG_RT_HWCRYPTO_USING_AES is not set +# CONFIG_RT_HWCRYPTO_USING_DES is not set +# CONFIG_RT_HWCRYPTO_USING_3DES is not set +# CONFIG_RT_HWCRYPTO_USING_RC4 is not set +# CONFIG_RT_HWCRYPTO_USING_MD5 is not set +# CONFIG_RT_HWCRYPTO_USING_SHA1 is not set +# CONFIG_RT_HWCRYPTO_USING_SHA2 is not set +CONFIG_RT_HWCRYPTO_USING_RNG=y +# CONFIG_RT_HWCRYPTO_USING_CRC is not set +# CONFIG_RT_HWCRYPTO_USING_BIGNUM is not set +CONFIG_RT_HWCRYPTO_RNG_ROCKCHIP=y # CONFIG_RT_USING_WIFI is not set -# CONFIG_RT_USING_LED is not set +CONFIG_RT_USING_LED=y +CONFIG_RT_LED_GPIO=y +# CONFIG_RT_LED_PWM is not set +# CONFIG_RT_LED_SYSCON is not set +# CONFIG_RT_USING_INPUT is not set # CONFIG_RT_USING_MBOX is not set +# CONFIG_RT_USING_HWSPINLOCK is not set # CONFIG_RT_USING_PHYE is not set -# CONFIG_RT_USING_BLK is not set +# CONFIG_RT_USING_ATA is not set +# CONFIG_RT_USING_NVME is not set +CONFIG_RT_USING_BLK=y + +# +# Partition Types +# +CONFIG_RT_BLK_PARTITION_DFS=y +CONFIG_RT_BLK_PARTITION_EFI=y +# end of Partition Types + # CONFIG_RT_USING_SCSI is not set -# CONFIG_RT_USING_REGULATOR is not set -# CONFIG_RT_USING_RESET is not set -# CONFIG_RT_USING_THERMAL is not set +CONFIG_RT_USING_FIRMWARE=y +# CONFIG_RT_FIRMWARE_ARM_SCMI is not set +# CONFIG_RT_USING_HWCACHE is not set +CONFIG_RT_USING_REGULATOR=y +CONFIG_RT_REGULATOR_FIXED=y +CONFIG_RT_REGULATOR_GPIO=y +CONFIG_RT_USING_RESET=y +# CONFIG_RT_RESET_SIMPLE is not set + +# +# Power Management (PM) Domains device drivers +# +# CONFIG_RT_PMDOMAIN_ROCKCHIP is not set +# end of Power Management (PM) Domains device drivers + +CONFIG_RT_USING_POWER_RESET=y +# CONFIG_RT_POWER_RESET_GPIO_POWEROFF is not set +# CONFIG_RT_POWER_RESET_GPIO_RESTART is not set +# CONFIG_RT_POWER_RESET_SYSCON_POWEROFF is not set +# CONFIG_RT_POWER_RESET_SYSCON_REBOOT_MODE is not set +# CONFIG_RT_POWER_RESET_SYSCON_REBOOT is not set +# CONFIG_RT_USING_POWER_SUPPLY is not set +CONFIG_RT_USING_THERMAL=y + +# +# Thermal Sensors Drivers +# +CONFIG_RT_THERMAL_ROCKCHIP_TSADC=y + +# +# Thermal Cool Drivers +# +CONFIG_RT_THERMAL_COOL_PWM_FAN=y # CONFIG_RT_USING_VIRTIO is not set -# CONFIG_RT_USING_DMA is not set -# CONFIG_RT_USING_MFD is not set +# CONFIG_RT_USING_NVMEM is not set +CONFIG_RT_USING_DMA=y +CONFIG_RT_DMA_PL330=y +CONFIG_RT_USING_MFD=y +CONFIG_RT_MFD_SYSCON=y +# CONFIG_RT_MFD_RK8XX_I2C is not set +# CONFIG_RT_MFD_RK8XX_SPI 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_PIC is not set +# CONFIG_RT_USING_PCI is not set +CONFIG_RT_USING_PIC=y +# CONFIG_RT_USING_PIC_STATISTICS is not set +CONFIG_MAX_HANDLERS=512 +CONFIG_RT_PIC_ARM_GIC=y +# CONFIG_RT_PIC_ARM_GIC_V3 is not set +CONFIG_RT_PIC_ARM_GIC_MAX_NR=1 CONFIG_RT_USING_PIN=y -# CONFIG_RT_USING_PINCTRL is not set -# CONFIG_RT_USING_KTIME is not set +# CONFIG_RT_PIN_PL061 is not set +CONFIG_RT_PIN_ROCKCHIP=y +CONFIG_RT_USING_PINCTRL=y +# CONFIG_RT_PINCTRL_SINGLE is not set +CONFIG_RT_PINCTRL_ROCKCHIP=y +CONFIG_RT_USING_KTIME=y CONFIG_RT_USING_CLK=y -# CONFIG_RT_USING_HWTIMER is not set +# CONFIG_RT_CLK_ROCKCHIP_LINK is not set +CONFIG_RT_CLK_ROCKCHIP=y +CONFIG_RT_CLK_ROCKCHIP_RK3308=y +# CONFIG_RT_CLK_ROCKCHIP_RK3568 is not set +# CONFIG_RT_CLK_ROCKCHIP_RK3576 is not set +# CONFIG_RT_CLK_ROCKCHIP_RK3588 is not set +CONFIG_RT_USING_HWTIMER=y +CONFIG_RT_HWTIMER_ARM_ARCH=y +CONFIG_RT_HWTIMER_ROCKCHIP=y # CONFIG_RT_USING_CHERRYUSB is not set # end of Device Drivers @@ -357,10 +516,23 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 # # POSIX (Portable Operating System Interface) layer # -# CONFIG_RT_USING_POSIX_FS is not set -# CONFIG_RT_USING_POSIX_DELAY is not set -# CONFIG_RT_USING_POSIX_CLOCK is not set -# CONFIG_RT_USING_POSIX_TIMER is not set +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 is not set +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 is not set +CONFIG_RT_USING_POSIX_TERMIOS=y +# CONFIG_RT_USING_POSIX_AIO is not set +# CONFIG_RT_USING_POSIX_MMAN is not set +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 @@ -403,7 +575,7 @@ CONFIG_RT_LIBC_TZ_DEFAULT_SEC=0 # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set # CONFIG_RT_USING_VAR_EXPORT is not set -# CONFIG_RT_USING_RESOURCE_ID 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 @@ -412,11 +584,10 @@ CONFIG_RT_USING_ADT_REF=y # CONFIG_RT_USING_RT_LINK is not set # end of Utilities -# CONFIG_RT_USING_VBUS is not set - # # Memory management # +# CONFIG_RT_PAGE_MPR_SIZE_DYNAMIC is not set CONFIG_RT_PAGE_AFFINITY_BLOCK_SIZE=0x1000 CONFIG_RT_PAGE_MAX_ORDER=11 CONFIG_RT_USING_MEMBLOCK=y @@ -431,6 +602,21 @@ CONFIG_RT_INIT_MEMORY_REGIONS=128 # end of Debugging # end of Memory management +CONFIG_RT_USING_LWP=y +# CONFIG_LWP_DEBUG is not set +CONFIG_LWP_USING_RUNTIME=y +CONFIG_RT_LWP_MAX_NR=30 +CONFIG_LWP_TASK_STACK_SIZE=16384 +CONFIG_RT_CH_MSG_MAX_NR=1024 +CONFIG_LWP_TID_MAX_NR=64 +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=32 +CONFIG_RT_USING_VDSO=y + # # Using USB legacy version # @@ -439,6 +625,7 @@ CONFIG_RT_INIT_MEMORY_REGIONS=128 # end of Using USB legacy version # CONFIG_RT_USING_FDT is not set +# CONFIG_RT_USING_RUST is not set # end of RT-Thread Components # @@ -658,7 +845,6 @@ CONFIG_RT_INIT_MEMORY_REGIONS=128 # CONFIG_PKG_USING_VT100 is not set # CONFIG_PKG_USING_QRCODE is not set # CONFIG_PKG_USING_GUIENGINE is not set -# CONFIG_PKG_USING_PERSIMMON is not set # CONFIG_PKG_USING_3GPP_AMRNB is not set # end of multimedia packages @@ -1164,7 +1350,6 @@ CONFIG_RT_INIT_MEMORY_REGIONS=128 # CONFIG_PKG_USING_UKAL is not set # CONFIG_PKG_USING_DIGITALCTRL is not set # CONFIG_PKG_USING_KISSFFT is not set -# CONFIG_PKG_USING_CMSIS_DSP is not set # end of Signal Processing and Control Algorithm Packages # @@ -1475,22 +1660,5 @@ CONFIG_RT_INIT_MEMORY_REGIONS=128 # end of Arduino libraries # end of RT-Thread online packages -CONFIG_SOC_RK3568=y - -# -# Hardware Drivers Config -# -CONFIG_BSP_USING_UART=y -# CONFIG_RT_USING_UART0 is not set -# CONFIG_RT_USING_UART1 is not set -CONFIG_RT_USING_UART2=y -# CONFIG_RT_USING_UART3 is not set -# CONFIG_RT_USING_UART4 is not set -# CONFIG_RT_USING_UART5 is not set -# CONFIG_RT_USING_UART6 is not set -# CONFIG_RT_USING_UART7 is not set -# CONFIG_RT_USING_UART8 is not set -# CONFIG_RT_USING_UART9 is not set -CONFIG_BSP_USING_GIC=y -CONFIG_BSP_USING_GICV3=y -# end of Hardware Drivers Config +CONFIG_SOC_RK3300=y +CONFIG_RT_USING_AMBA_BUS=y diff --git a/bsp/rockchip/rk3568/Kconfig b/bsp/rockchip/rk3300/Kconfig old mode 100644 new mode 100755 similarity index 63% rename from bsp/rockchip/rk3568/Kconfig rename to bsp/rockchip/rk3300/Kconfig index dda6d4b3b79..55f649f61f5 --- a/bsp/rockchip/rk3568/Kconfig +++ b/bsp/rockchip/rk3300/Kconfig @@ -6,17 +6,23 @@ RTT_DIR := ../../.. PKGS_DIR := packages +SOC_DM_DIR := $BSP_DIR/../dm/ + +source "$(SOC_DM_DIR)/Kconfig" source "$(RTT_DIR)/Kconfig" osource "$PKGS_DIR/Kconfig" -config SOC_RK3568 +config SOC_RK3300 bool select ARCH_ARMV8 select ARCH_CPU_64BIT + select ARCH_ARM_MMU select RT_USING_CACHE select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN - select ARCH_ARM_BOOTWITH_FLUSH_CACHE + select RT_USING_STDC_ATOMIC default y -source "$(BSP_DIR)/driver/Kconfig" +config RT_USING_AMBA_BUS + bool + default y diff --git a/bsp/rockchip/rk3300/README.md b/bsp/rockchip/rk3300/README.md new file mode 100755 index 00000000000..a194866383e --- /dev/null +++ b/bsp/rockchip/rk3300/README.md @@ -0,0 +1,55 @@ +# RK3300 BSP Introduction + +[中文页](./README_ZH.md) | English + +## 1. Introduction + +### Product Details + +https://www.rock-chips.com/a/cn/product/RK33xilie/index.html + +### Condition + +| SoC | Condition | Earlycon | +| ------ | ---- | ---- | +| RK3399Pro | - | - | +| RK3326 | - | - | +| RK3308 | Support | earlycon=uart8250,mmio32,0xff0a0000 | +| RK3328 | - | - | +| RK3399 | - | - | + +## 2. Compiling + +Use the RT-Thread Smart dedicated toolchain to compile: + +```plaintext +wget https://github.com/RT-Thread/rt-thread/releases/download/v5.2.0/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu_242520-979be38cba.tar.bz2 + +sudo tar -xf aarch64-linux-musleabi_for_x86_64-pc-linux-gnu_242520-979be38cba.tar.bz2 -C /opt +``` + +After downloading, extract the toolchain to the /opt directory.Then configure your environment variables: + +```plaintext +export RTT_CC="gcc" +export RTT_EXEC_PATH="/opt/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/" +export RTT_CC_PREFIX="aarch64-linux-musleabi-" +export PATH="$RTT_EXEC_PATH:$PATH" +``` + +Navigate to the rt-thread/bsp/rockchip/rk3300 directory and enter: + +```shell +scons --menuconfig +``` + +Select and pull the zlib package in the menu: +![zlib_pack](./figures/zlib_pack.png) + +Then run the following commands to fetch packages and build the project: + +```shell +source ~/.env/tools/scripts/pkgs --update + +scons +``` diff --git a/bsp/rockchip/rk3300/README_ZH.md b/bsp/rockchip/rk3300/README_ZH.md new file mode 100755 index 00000000000..0a5b0033e33 --- /dev/null +++ b/bsp/rockchip/rk3300/README_ZH.md @@ -0,0 +1,56 @@ +# RK3300 BSP 介绍 + +中文页 | [English](./README.md) + +## 1. 介绍 + +### 产品细节 + +https://www.rock-chips.com/a/cn/product/RK33xilie/index.html + +### 支持列表 + +| 驱动 | 支持情况 | Earlycon | +| ------ | ---- | ---- | +| RK3399Pro | - | - | +| RK3326 | - | - | +| RK3308 | 支持 | earlycon=uart8250,mmio32,0xff0a0000 | +| RK3328 | - | - | +| RK3399 | - | - | + +## 2. 编译 + +使用RT-Thread Smart 专用工具链进行编译: + +```plaintext +wget https://github.com/RT-Thread/rt-thread/releases/download/v5.2.0/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu_242520-979be38cba.tar.bz2 + +sudo tar -xf aarch64-linux-musleabi_for_x86_64-pc-linux-gnu_242520-979be38cba.tar.bz2 -C /opt +``` + +将工具链下载后,解压至/opt目录。并设置环境变量 + +```shell +环境变量配置为: +export RTT_CC="gcc" +export RTT_EXEC_PATH="/opt/aarch64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/" +export RTT_CC_PREFIX="aarch64-linux-musleabi-" +export PATH="$RTT_EXEC_PATH:$PATH" +``` + +进入`rt-thread/bsp/rockchip/rk3300`目录下输入: + +```plaintext +scons --menuconfig +``` + +选择并拉取zlib软件包 +![zlib_pack](./figures/zlib_pack.png) + +执行一下命令拉取软件包并编译 + +```shell +source ~/.env/tools/scripts/pkgs --update + +scons +``` diff --git a/bsp/rockchip/rk3300/SConscript b/bsp/rockchip/rk3300/SConscript new file mode 100755 index 00000000000..81ce8df78c0 --- /dev/null +++ b/bsp/rockchip/rk3300/SConscript @@ -0,0 +1,16 @@ +# 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')) + +objs = objs + SConscript(cwd + '/../dm/SConscript', variant_dir = 'dm', duplicate = 0) + +Return('objs') diff --git a/bsp/rockchip/rk3568/SConstruct b/bsp/rockchip/rk3300/SConstruct old mode 100644 new mode 100755 similarity index 100% rename from bsp/rockchip/rk3568/SConstruct rename to bsp/rockchip/rk3300/SConstruct diff --git a/bsp/rockchip/rk3568/applications/SConscript b/bsp/rockchip/rk3300/applications/SConscript old mode 100644 new mode 100755 similarity index 100% rename from bsp/rockchip/rk3568/applications/SConscript rename to bsp/rockchip/rk3300/applications/SConscript diff --git a/bsp/rockchip/rk3300/applications/main.c b/bsp/rockchip/rk3300/applications/main.c new file mode 100755 index 00000000000..27b230e675b --- /dev/null +++ b/bsp/rockchip/rk3300/applications/main.c @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2017-5-30 Bernard the first version + */ + +#include +#include + +int main(int argc, char** argv) +{ + const char *oem; + +#ifdef RT_USING_SMART + oem = "Smart"; +#else + oem = "Thread"; +#endif + + rt_ubase_t level = rt_hw_interrupt_disable(); + + rt_kprintf("Hi, this is RT-%s!!\n", oem); + + rt_hw_interrupt_enable(level); + + return 0; +} diff --git a/bsp/rockchip/rk3568/driver/SConscript b/bsp/rockchip/rk3300/driver/SConscript old mode 100644 new mode 100755 similarity index 100% rename from bsp/rockchip/rk3568/driver/SConscript rename to bsp/rockchip/rk3300/driver/SConscript diff --git a/bsp/rockchip/rk3568/driver/drv_uart.h b/bsp/rockchip/rk3300/driver/board.c old mode 100644 new mode 100755 similarity index 51% rename from bsp/rockchip/rk3568/driver/drv_uart.h rename to bsp/rockchip/rk3300/driver/board.c index acc6ac0ea4b..70c27cbcec2 --- a/bsp/rockchip/rk3568/driver/drv_uart.h +++ b/bsp/rockchip/rk3300/driver/board.c @@ -5,12 +5,13 @@ * * Change Logs: * Date Author Notes - * 2022-3-08 GuEe-GUI the first version + * 2023-02-21 GuEe-GUI the first version */ -#ifndef __DRV_UART_H__ -#define __DRV_UART_H__ +#include +#include -int rt_hw_uart_init(void); - -#endif /* __DRV_UART_H__ */ +void rt_hw_board_init(void) +{ + rt_hw_common_setup(); +} diff --git a/bsp/rockchip/rk3568/applications/main.c b/bsp/rockchip/rk3300/driver/board.h old mode 100644 new mode 100755 similarity index 64% rename from bsp/rockchip/rk3568/applications/main.c rename to bsp/rockchip/rk3300/driver/board.h index 780e49d0918..4691e28742e --- a/bsp/rockchip/rk3568/applications/main.c +++ b/bsp/rockchip/rk3300/driver/board.h @@ -8,11 +8,9 @@ * 2017-5-30 Bernard the first version */ -#include +#ifndef __BOARD_H__ +#define __BOARD_H__ -int main(int argc, char** argv) -{ - rt_kprintf("Hi, this is RT-Thread!!\n"); +void rt_hw_board_init(void); - return 0; -} +#endif /* __BOARD_H__ */ diff --git a/bsp/rockchip/rk3568/rtconfig.h b/bsp/rockchip/rk3300/rtconfig.h old mode 100644 new mode 100755 similarity index 66% rename from bsp/rockchip/rk3568/rtconfig.h rename to bsp/rockchip/rk3300/rtconfig.h index 6c44e3cb29c..bd4d99b39d3 --- a/bsp/rockchip/rk3568/rtconfig.h +++ b/bsp/rockchip/rk3300/rtconfig.h @@ -8,16 +8,6 @@ /* rt_vsnprintf options */ #define RT_KLIBC_USING_VSNPRINTF_LONGLONG -#define RT_KLIBC_USING_VSNPRINTF_STANDARD -#define RT_KLIBC_USING_VSNPRINTF_DECIMAL_SPECIFIERS -#define RT_KLIBC_USING_VSNPRINTF_EXPONENTIAL_SPECIFIERS -#define RT_KLIBC_USING_VSNPRINTF_WRITEBACK_SPECIFIER -#define RT_KLIBC_USING_VSNPRINTF_CHECK_NUL_IN_FORMAT_SPECIFIER -#define RT_KLIBC_USING_VSNPRINTF_INTEGER_BUFFER_SIZE 32 -#define RT_KLIBC_USING_VSNPRINTF_DECIMAL_BUFFER_SIZE 32 -#define RT_KLIBC_USING_VSNPRINTF_FLOAT_PRECISION 6 -#define RT_KLIBC_USING_VSNPRINTF_MAX_INTEGRAL_DIGITS_FOR_DECIMAL 9 -#define RT_KLIBC_USING_VSNPRINTF_LOG10_TAYLOR_TERMS 4 /* end of rt_vsnprintf options */ /* rt_vsscanf options */ @@ -72,7 +62,8 @@ /* end of rt_strnlen options */ /* end of klibc options */ -#define RT_NAME_MAX 12 +#define RT_NAME_MAX 24 +#define RT_USING_SMART #define RT_USING_SMP #define RT_CPUS_NR 4 #define RT_ALIGN_SIZE 8 @@ -89,6 +80,7 @@ #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 4 #define RT_TIMER_THREAD_STACK_SIZE 4096 +#define RT_USING_CPU_USAGE_TRACER /* kservice options */ @@ -97,6 +89,7 @@ #define RT_DEBUGING_ASSERT #define RT_DEBUGING_COLOR #define RT_DEBUGING_CONTEXT +#define RT_DEBUGING_CRITICAL /* Inter-Thread communication */ @@ -119,17 +112,20 @@ /* end of Memory Management */ #define RT_USING_DEVICE #define RT_USING_DEVICE_OPS +#define RT_USING_INTERRUPT_INFO +#define RT_USING_THREADSAFE_PRINTF #define RT_USING_CONSOLE -#define RT_CONSOLEBUF_SIZE 128 +#define RT_CONSOLEBUF_SIZE 256 #define RT_CONSOLE_DEVICE_NAME "uart2" -#define RT_VER_NUM 0x50201 +#define RT_VER_NUM 0x50300 +#define RT_USING_STDC_ATOMIC #define RT_BACKTRACE_LEVEL_MAX_NR 32 /* end of RT-Thread Kernel */ /* AArch64 Architecture Configuration */ #define ARCH_TEXT_OFFSET 0x200000 -#define ARCH_RAM_OFFSET 0 +#define ARCH_RAM_OFFSET 0x0 #define ARCH_SECONDARY_CPU_STACK_SIZE 4096 #define ARCH_HAVE_EFFICIENT_UNALIGNED_ACCESS #define ARCH_USING_GENERIC_CPUID @@ -138,15 +134,11 @@ /* end of AArch64 Architecture Configuration */ #define ARCH_CPU_64BIT #define RT_USING_CACHE -#define RT_USING_HW_ATOMIC -#define ARCH_ARM_BOOTWITH_FLUSH_CACHE #define RT_USING_CPU_FFS #define ARCH_MM_MMU #define ARCH_ARM #define ARCH_ARM_MMU -#define ARCH_ARM_CORTEX_A -#define RT_NO_USING_GIC -#define ARCH_ARM_CORTEX_A55 +#define KERNEL_VADDR_START 0xffff000000000000 #define ARCH_ARMV8 #define ARCH_USING_ASID #define ARCH_USING_HW_THREAD_SELF @@ -163,7 +155,7 @@ #define FINSH_USING_MSH #define FINSH_THREAD_NAME "tshell" #define FINSH_THREAD_PRIORITY 20 -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 8192 #define FINSH_USING_HISTORY #define FINSH_HISTORY_LINES 5 #define FINSH_USING_SYMTAB @@ -175,23 +167,146 @@ /* DFS: device virtual file system */ +#define RT_USING_DFS +#define DFS_USING_POSIX +#define DFS_USING_WORKDIR +#define DFS_FD_MAX 16 +#define RT_USING_DFS_V2 +#define RT_USING_DFS_ELMFAT + +/* elm-chan's FatFs, Generic FAT Filesystem Module */ + +#define RT_DFS_ELM_CODE_PAGE 437 +#define RT_DFS_ELM_WORD_ACCESS +#define RT_DFS_ELM_USE_LFN_3 +#define RT_DFS_ELM_USE_LFN 3 +#define RT_DFS_ELM_LFN_UNICODE_0 +#define RT_DFS_ELM_LFN_UNICODE 0 +#define RT_DFS_ELM_MAX_LFN 255 +#define RT_DFS_ELM_DRIVES 2 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 512 +#define RT_DFS_ELM_REENTRANT +#define RT_DFS_ELM_MUTEX_TIMEOUT 3000 +/* end of elm-chan's FatFs, Generic FAT Filesystem Module */ +#define RT_USING_DFS_DEVFS +#define RT_USING_DFS_PTYFS +#define RT_USING_DFS_PROCFS +#define RT_USING_DFS_MQUEUE +#define RT_USING_PAGECACHE + +/* page cache config */ + +#define RT_PAGECACHE_COUNT 4096 +#define RT_PAGECACHE_ASPACE_COUNT 1024 +#define RT_PAGECACHE_PRELOAD 4 +#define RT_PAGECACHE_HASH_NR 1024 +#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 8192 +#define RT_SYSTEM_WORKQUEUE_PRIORITY 23 #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 #define RT_SERIAL_RB_BUFSZ 64 -#define RT_USING_PM -#define PM_TICKLESS_THRESHOLD_TIME 2 +#define RT_USING_SERIAL_BYPASS +#define RT_SERIAL_8250 +#define RT_SERIAL_8250_DW +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS +#define RT_I2C_RK3X +#define RT_USING_ADC +#define RT_ADC_ROCKCHIP_SARADC +#define RT_USING_NULL +#define RT_USING_ZERO +#define RT_USING_RANDOM +#define RT_USING_PWM +#define RT_PWM_ROCKCHIP +#define RT_USING_RTC +#define RT_USING_ALARM +#define RT_ALARM_STACK_SIZE 4096 +#define RT_ALARM_TIMESLICE 5 +#define RT_ALARM_PRIORITY 10 +#define RT_RTC_RK_TIMER +#define RT_USING_SDIO +#define RT_SDIO_STACK_SIZE 8192 +#define RT_SDIO_THREAD_PRIORITY 15 +#define RT_MMCSD_STACK_SIZE 8192 +#define RT_MMCSD_THREAD_PRIORITY 22 +#define RT_MMCSD_MAX_PARTITION 16 +#define RT_SDIO_DW_MMC +#define RT_SDIO_DW_MMC_ROCKCHIP +#define RT_USING_SPI +#define RT_USING_SPI_ISR +#define RT_USING_QSPI +#define RT_SPI_ROCKCHIP_SFC +#define RT_SPI_ROCKCHIP +#define RT_USING_WDT +#define RT_WDT_DW +#define RT_USING_HWCRYPTO +#define RT_HWCRYPTO_DEFAULT_NAME "hwcryto" +#define RT_HWCRYPTO_IV_MAX_SIZE 16 +#define RT_HWCRYPTO_KEYBIT_MAX_SIZE 256 +#define RT_HWCRYPTO_USING_RNG +#define RT_HWCRYPTO_RNG_ROCKCHIP +#define RT_USING_LED +#define RT_LED_GPIO +#define RT_USING_BLK + +/* Partition Types */ + +#define RT_BLK_PARTITION_DFS +#define RT_BLK_PARTITION_EFI +/* end of Partition Types */ +#define RT_USING_FIRMWARE +#define RT_USING_REGULATOR +#define RT_REGULATOR_FIXED +#define RT_REGULATOR_GPIO +#define RT_USING_RESET + +/* Power Management (PM) Domains device drivers */ + +/* end of Power Management (PM) Domains device drivers */ +#define RT_USING_POWER_RESET +#define RT_USING_THERMAL + +/* Thermal Sensors Drivers */ + +#define RT_THERMAL_ROCKCHIP_TSADC + +/* Thermal Cool Drivers */ + +#define RT_THERMAL_COOL_PWM_FAN +#define RT_USING_DMA +#define RT_DMA_PL330 +#define RT_USING_MFD +#define RT_MFD_SYSCON #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 512 +#define RT_PIC_ARM_GIC +#define RT_PIC_ARM_GIC_MAX_NR 1 #define RT_USING_PIN +#define RT_PIN_ROCKCHIP +#define RT_USING_PINCTRL +#define RT_PINCTRL_ROCKCHIP +#define RT_USING_KTIME #define RT_USING_CLK +#define RT_CLK_ROCKCHIP +#define RT_CLK_ROCKCHIP_RK3308 +#define RT_USING_HWTIMER +#define RT_HWTIMER_ARM_ARCH +#define RT_HWTIMER_ROCKCHIP /* end of Device Drivers */ /* C/C++ and POSIX layer */ @@ -209,6 +324,19 @@ /* 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_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_TERMIOS +#define RT_USING_POSIX_DELAY +#define RT_USING_POSIX_CLOCK +#define RT_USING_POSIX_TIMER /* Interprocess Communication (IPC) */ @@ -229,6 +357,7 @@ /* Utilities */ +#define RT_USING_RESOURCE_ID #define RT_USING_ADT #define RT_USING_ADT_AVL #define RT_USING_ADT_BITMAP @@ -247,6 +376,17 @@ /* end of Debugging */ /* end of Memory management */ +#define RT_USING_LWP +#define LWP_USING_RUNTIME +#define RT_LWP_MAX_NR 30 +#define LWP_TASK_STACK_SIZE 16384 +#define RT_CH_MSG_MAX_NR 1024 +#define LWP_TID_MAX_NR 64 +#define RT_LWP_SHM_MAX_NR 64 +#define RT_USING_LDSO +#define LWP_USING_TERMINAL +#define LWP_PTY_MAX_PARIS_LIMIT 32 +#define RT_USING_VDSO /* Using USB legacy version */ @@ -457,14 +597,7 @@ /* end of Arduino libraries */ /* end of RT-Thread online packages */ -#define SOC_RK3568 - -/* Hardware Drivers Config */ - -#define BSP_USING_UART -#define RT_USING_UART2 -#define BSP_USING_GIC -#define BSP_USING_GICV3 -/* end of Hardware Drivers Config */ +#define SOC_RK3300 +#define RT_USING_AMBA_BUS #endif diff --git a/bsp/rockchip/rk3568/rtconfig.py b/bsp/rockchip/rk3300/rtconfig.py old mode 100644 new mode 100755 similarity index 76% rename from bsp/rockchip/rk3568/rtconfig.py rename to bsp/rockchip/rk3300/rtconfig.py index 78fb406389a..5ae06181dcd --- a/bsp/rockchip/rk3568/rtconfig.py +++ b/bsp/rockchip/rk3300/rtconfig.py @@ -16,8 +16,7 @@ PLATFORM = 'gcc' EXEC_PATH = r'/opt/gcc-arm-8.3-2019.03-x86_64-aarch64-elf/bin/' -if os.getenv('RTT_EXEC_PATH'): - EXEC_PATH = os.getenv('RTT_EXEC_PATH') +EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' BUILD = 'debug' @@ -26,6 +25,7 @@ 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' @@ -34,10 +34,11 @@ OBJDUMP = PREFIX + 'objdump' OBJCPY = PREFIX + 'objcopy' - DEVICE = ' -g -march=armv8-a -mtune=cortex-a53' + DEVICE = ' -g -march=armv8-a -mtune=cortex-a35 -fdiagnostics-color=always' + CPPFLAGS= ' -nostdinc -undef -E -P -x assembler-with-cpp' CFLAGS = DEVICE + ' -Wall -Wno-cpp' AFLAGS = ' -c' + ' -x assembler-with-cpp -D__ASSEMBLY__' - LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' + LFLAGS = DEVICE + ' -nostartfiles -Wl,--no-warn-rwx-segments -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,system_vectors -T link.lds' CPATH = '' LPATH = '' diff --git a/bsp/rockchip/rk3500/.config b/bsp/rockchip/rk3500/.config index 5b5ad0170e8..fed7587c007 100644 --- a/bsp/rockchip/rk3500/.config +++ b/bsp/rockchip/rk3500/.config @@ -197,7 +197,7 @@ 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=0x50201 +CONFIG_RT_VER_NUM=0x50300 CONFIG_RT_USING_STDC_ATOMIC=y CONFIG_RT_BACKTRACE_LEVEL_MAX_NR=32 # end of RT-Thread Kernel @@ -216,7 +216,6 @@ CONFIG_ARCH_INIT_PAGE_SIZE=0x200000 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 @@ -302,6 +301,10 @@ CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_SERIAL_USING_DMA is not set CONFIG_RT_SERIAL_RB_BUFSZ=64 CONFIG_RT_USING_SERIAL_BYPASS=y +# CONFIG_RT_SERIAL_EARLY_HVC is not set +# CONFIG_RT_SERIAL_PL011 is not set +CONFIG_RT_SERIAL_8250=y +# CONFIG_RT_SERIAL_8250_DW is not set # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_CPUTIME is not set # CONFIG_RT_USING_I2C is not set @@ -321,6 +324,9 @@ CONFIG_RT_USING_RANDOM=y CONFIG_RT_USING_RTC=y # CONFIG_RT_USING_ALARM is not set CONFIG_RT_USING_SOFT_RTC=y +# CONFIG_RT_RTC_GOLDFISH is not set +# CONFIG_RT_RTC_PL031 is not set +# CONFIG_RT_RTC_RK_TIMER is not set CONFIG_RT_USING_SDIO=y CONFIG_RT_SDIO_STACK_SIZE=16384 CONFIG_RT_SDIO_THREAD_PRIORITY=15 @@ -334,11 +340,13 @@ CONFIG_RT_MMCSD_MAX_PARTITION=16 # 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_GRAPHIC is not set # CONFIG_RT_USING_HWCRYPTO is not set # CONFIG_RT_USING_WIFI is not set # CONFIG_RT_USING_LED is not set +# CONFIG_RT_USING_INPUT is not set # CONFIG_RT_USING_MBOX is not set +# CONFIG_RT_USING_HWSPINLOCK is not set # CONFIG_RT_USING_PHYE is not set CONFIG_RT_USING_BLK=y @@ -350,13 +358,25 @@ CONFIG_RT_BLK_PARTITION_EFI=y # end of Partition Types # CONFIG_RT_USING_SCSI is not set +# CONFIG_RT_USING_FIRMWARE is not set +# CONFIG_RT_USING_HWCACHE is not set # CONFIG_RT_USING_REGULATOR is not set CONFIG_RT_USING_RESET=y # CONFIG_RT_RESET_SIMPLE is not set + +# +# Power Management (PM) Domains device drivers +# +# end of Power Management (PM) Domains device drivers + +# CONFIG_RT_USING_POWER_RESET is not set +# CONFIG_RT_USING_POWER_SUPPLY is not set # CONFIG_RT_USING_THERMAL is not set # CONFIG_RT_USING_VIRTIO is not set +# CONFIG_RT_USING_NVMEM is not set # CONFIG_RT_USING_DMA is not set -# CONFIG_RT_USING_MFD is not set +CONFIG_RT_USING_MFD=y +CONFIG_RT_MFD_SYSCON=y CONFIG_RT_USING_OFW=y # CONFIG_RT_USING_BUILTIN_FDT is not set CONFIG_RT_FDT_EARLYCON_MSG_SIZE=128 @@ -367,11 +387,22 @@ 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_PIN_PL061 is not set +CONFIG_RT_PIN_ROCKCHIP=y CONFIG_RT_USING_PINCTRL=y +# CONFIG_RT_PINCTRL_SINGLE is not set +CONFIG_RT_PINCTRL_ROCKCHIP=y CONFIG_RT_USING_KTIME=y CONFIG_RT_USING_CLK=y +CONFIG_RT_CLK_ROCKCHIP_LINK=y +CONFIG_RT_CLK_ROCKCHIP=y +# CONFIG_RT_CLK_ROCKCHIP_RK3308 is not set +CONFIG_RT_CLK_ROCKCHIP_RK3568=y +# CONFIG_RT_CLK_ROCKCHIP_RK3576 is not set +CONFIG_RT_CLK_ROCKCHIP_RK3588=y CONFIG_RT_USING_HWTIMER=y CONFIG_RT_HWTIMER_ARM_ARCH=y +CONFIG_RT_HWTIMER_ROCKCHIP=y # CONFIG_RT_USING_CHERRYUSB is not set # end of Device Drivers @@ -551,11 +582,10 @@ CONFIG_RT_USING_ADT_REF=y # CONFIG_RT_USING_RT_LINK is not set # end of Utilities -# CONFIG_RT_USING_VBUS is not set - # # Memory management # +# CONFIG_RT_PAGE_MPR_SIZE_DYNAMIC is not set CONFIG_RT_PAGE_AFFINITY_BLOCK_SIZE=0x1000 CONFIG_RT_PAGE_MAX_ORDER=11 CONFIG_RT_USING_MEMBLOCK=y @@ -594,6 +624,7 @@ CONFIG_RT_USING_VDSO=y # end of Using USB legacy version # CONFIG_RT_USING_FDT is not set +# CONFIG_RT_USING_RUST is not set # end of RT-Thread Components # @@ -676,16 +707,12 @@ CONFIG_RT_UTEST_SMP_CALL_FUNC=y # end of CPP11 # -# LwIP -# -# CONFIG_RT_UTEST_TC_USING_LWIP is not set -# end of LwIP - -# -# Netdev +# Network # +# CONFIG_RT_UTEST_TC_USING_SAL is not set # CONFIG_RT_UTEST_TC_USING_NETDEV is not set -# end of Netdev +# CONFIG_RT_UTEST_TC_USING_LWIP is not set +# end of Network # # Utest Framework @@ -1740,14 +1767,4 @@ CONFIG_PKG_ZLIB_VER="latest" # end of Arduino libraries # end of RT-Thread online packages -# -# 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_HWTIMER_ROCKCHIP=y -# end of RT-Thread rockchip RK3500 drivers - -CONFIG_SOC_RK3568=y +CONFIG_SOC_RK3500=y diff --git a/bsp/rockchip/rk3500/Kconfig b/bsp/rockchip/rk3500/Kconfig index cdb605ecc70..b6c81211415 100644 --- a/bsp/rockchip/rk3500/Kconfig +++ b/bsp/rockchip/rk3500/Kconfig @@ -1,31 +1,24 @@ mainmenu "RT-Thread Project Configuration" -config BSP_DIR - string - option env="BSP_ROOT" - default "." +BSP_DIR := . -config RTT_DIR - string - option env="RTT_ROOT" - default "../../.." +RTT_DIR := ../../.. -config PKGS_DIR - string - option env="PKGS_ROOT" - default "packages" +PKGS_DIR := packages -source "$RTT_DIR/Kconfig" -source "$PKGS_DIR/Kconfig" -source "$BSP_DIR/driver/Kconfig" +SOC_DM_DIR := $BSP_DIR/../dm/ -config SOC_RK3568 +source "$(SOC_DM_DIR)/Kconfig" +source "$(RTT_DIR)/Kconfig" +osource "$PKGS_DIR/Kconfig" + +config SOC_RK3500 bool select ARCH_ARMV8 select ARCH_CPU_64BIT + select ARCH_ARM_MMU select RT_USING_CACHE select RT_USING_COMPONENTS_INIT select RT_USING_USER_MAIN - select ARCH_ARM_BOOTWITH_FLUSH_CACHE + select RT_USING_STDC_ATOMIC default y - diff --git a/bsp/rockchip/rk3500/README.md b/bsp/rockchip/rk3500/README.md index c029891aa4d..33f5c9e60ca 100644 --- a/bsp/rockchip/rk3500/README.md +++ b/bsp/rockchip/rk3500/README.md @@ -1,64 +1,24 @@ -# RK3568 BSP Introduction +# RK3500 BSP Introduction [中文页](./README_ZH.md) | English ## 1. Introduction -### Core Architecture - -- **CPU**: Quad-core 64-bit ARM Cortex-A55 -- **Process Node**: 22nm FinFET -- **Clock Speed**: Up to 1.8GHz (boost) - -### Graphics Subsystem - -- **GPU**: ARM Mali-G52 MP2 - - Graphics APIs: - - OpenGL ES 3.2/2.0/1.1 - - Vulkan 1.1 - - Display Outputs: - - HDMI 2.0b - - eDP 1.3 - - MIPI-DSI (4 lanes) -- **Video Processing**: - - Decoding: 4K@60fps (H.265/H.264/VP9) - - Encoding: 1080P@60fps (H.264/H.265) - -### Memory & Storage - -- **RAM Support**: - - Dual-channel LPDDR4/LPDDR4X - - Max Capacity: 8GB -- **Storage Options**: - - eMMC 5.1 HS400 - - SD 3.0 UHS-I - - Optional SATA III (6Gbps) -- **High-Speed Interfaces**: - - USB 3.0 Type-A/C - - PCIe 2.1 (x1 lane) - -### AI Acceleration - -- **NPU**: 0.8 TOPS INT8 - - Framework Support: - - TensorFlow Lite - - MXNet - - PyTorch Mobile - -### Connectivity - -- **Wired**: - - Dual Gigabit Ethernet (RGMII) -- **Wireless**: - - Expansion via: - - PCIe-based WiFi6 - - USB Bluetooth 5.0 - -### Multimedia I/O - -- **Camera Input**: - - Dual 4-lane MIPI-CSI - - Supports up to 13MP sensors +### Product Details + +https://www.rock-chips.com/a/cn/product/RK35xilie/index.html + +### Condition + +| SoC | Condition | Earlycon | +| ------ | ---- | ---- | +| RK3576 | Support | earlycon=uart8250,mmio32,0x2ad40000 | +| RK3588 | Support | earlycon=uart8250,mmio32,0xfeb50000 | +| RK3562 | - | - | +| RK3568J | Support | earlycon=uart8250,mmio32,0xfe660000 | +| RK3568 | Support | earlycon=uart8250,mmio32,0xfe660000 | +| RK3566 | Support | earlycon=uart8250,mmio32,0xfe660000 | +| RK3506 | - | ## 2. Compiling @@ -98,7 +58,7 @@ scons ## 3. Execution -The RK3566 SoC uses different methods to install the kernel depending on the board.It is recommended to install and boot from an SD card.The following steps take the Orange Pi Compute Module 4 as an example: +The RK3500 SoC uses different methods to install the kernel depending on the board.It is recommended to install and boot from an SD card.The following steps take the Orange Pi Compute Module 4 as an example: Connect the serial port of the development board: ![uart](./figures/uart.png) diff --git a/bsp/rockchip/rk3500/README_ZH.md b/bsp/rockchip/rk3500/README_ZH.md index f09138ccc70..9feff420d9d 100644 --- a/bsp/rockchip/rk3500/README_ZH.md +++ b/bsp/rockchip/rk3500/README_ZH.md @@ -1,61 +1,24 @@ -# RK3566 BSP 介绍 +# RK3500 BSP 介绍 中文页 | [English](./README.md) ## 1. 介绍 -### 核心架构 +### 产品细节 -- **CPU**: 四核 64 位 Cortex-A55 处理器 -- **制程工艺**: 22nm 光刻技术 -- **主频**: 最高 1.8GHz +https://www.rock-chips.com/a/cn/product/RK35xilie/index.html -### 图形处理 +### 支持列表 -- **GPU**: Mali-G52 - - 支持 OpenGL ES 3.2/2.0/1.1 - - 支持 Vulkan 1.1 -- **视频编解码**: - - 4K@60fps 解码 (H.265/H.264/VP9) - - 1080P@60fps 编码 - -### 存储与扩展 - -- **内存支持**: - - LPDDR4/LPDDR4X - - 最高 8GB 容量 -- **存储接口**: - - eMMC 5.1 - - SDIO 3.0 - - SATA 3.0 (可选) -- **高速接口**: - - USB 3.0/2.0 - - PCIe 2.1 (1x lane) - -### AI - -- **NPU**: 0.8TOPS 算力 -- **支持框架**: - - TensorFlow - - MXNet - - PyTorch - -### 网络连接 - -- **有线网络**: - - 双千兆以太网 (RGMII) -- **无线扩展**: - - 支持 WiFi6/蓝牙模块扩展 - -### 多媒体接口 - -- **显示输出**: - - HDMI 2.0 - - eDP 1.3 - - MIPI-DSI -- **摄像头输入**: - - 双 MIPI-CSI - - 支持 4K 图像处理 +| 驱动 | 支持情况 | Earlycon | +| ------ | ---- | ---- | +| RK3576 | 支持 | earlycon=uart8250,mmio32,0x2ad40000 | +| RK3588 | 支持 | earlycon=uart8250,mmio32,0xfeb50000 | +| RK3562 | - | - | +| RK3568J | 支持 | earlycon=uart8250,mmio32,0xfe660000 | +| RK3568 | 支持 | earlycon=uart8250,mmio32,0xfe660000 | +| RK3566 | 支持 | earlycon=uart8250,mmio32,0xfe660000 | +| RK3506 | - | - | ## 2. 编译 @@ -96,7 +59,7 @@ scons ## 3. 运行 -RK3566 根据不同的板卡有不同的内核安装方法,建议安装到 SD 卡中,这里以Orange Pi Compute Module 4举例说明: +RK3500 根据不同的板卡有不同的内核安装方法,建议安装到 SD 卡中,这里以Orange Pi Compute Module 4举例说明: 连接开发板串口: ![uart](./figures/uart.png) diff --git a/bsp/rockchip/rk3500/SConscript b/bsp/rockchip/rk3500/SConscript index 744d8d78214..81ce8df78c0 100644 --- a/bsp/rockchip/rk3500/SConscript +++ b/bsp/rockchip/rk3500/SConscript @@ -11,4 +11,6 @@ for d in list: if os.path.isfile(os.path.join(path, 'SConscript')): objs = objs + SConscript(os.path.join(d, 'SConscript')) +objs = objs + SConscript(cwd + '/../dm/SConscript', variant_dir = 'dm', duplicate = 0) + Return('objs') diff --git a/bsp/rockchip/rk3500/driver/Kconfig b/bsp/rockchip/rk3500/driver/Kconfig deleted file mode 100644 index d0730821614..00000000000 --- a/bsp/rockchip/rk3500/driver/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -menu "RT-Thread rockchip RK3500 drivers" - -source "$BSP_DIR/driver/clk/Kconfig" -source "$BSP_DIR/driver/uart8250/Kconfig" -source "$BSP_DIR/driver/hwtimer/Kconfig" -endmenu diff --git a/bsp/rockchip/rk3500/driver/board.c b/bsp/rockchip/rk3500/driver/board.c index 9d19b8b3961..c4699318823 100644 --- a/bsp/rockchip/rk3500/driver/board.c +++ b/bsp/rockchip/rk3500/driver/board.c @@ -7,31 +7,10 @@ * Date Author Notes * 2022-3-08 GuEe-GUI the first version */ + #include -#include -#include 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...); diff --git a/bsp/rockchip/rk3500/driver/board.h b/bsp/rockchip/rk3500/driver/board.h index 1c02d75a6b9..04d58813d5c 100644 --- a/bsp/rockchip/rk3500/driver/board.h +++ b/bsp/rockchip/rk3500/driver/board.h @@ -11,15 +11,6 @@ #ifndef __BOARD_H__ #define __BOARD_H__ -#include - -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__ */ diff --git a/bsp/rockchip/rk3500/driver/clk/Kconfig b/bsp/rockchip/rk3500/driver/clk/Kconfig deleted file mode 100644 index 15a2b1e99e0..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -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 diff --git a/bsp/rockchip/rk3500/driver/clk/SConscript b/bsp/rockchip/rk3500/driver/clk/SConscript deleted file mode 100644 index 91bb28839db..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/SConscript +++ /dev/null @@ -1,16 +0,0 @@ -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') diff --git a/bsp/rockchip/rk3500/driver/clk/clk-pll-rk3568.c b/bsp/rockchip/rk3500/driver/clk/clk-pll-rk3568.c deleted file mode 100644 index 385f54853b7..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/clk-pll-rk3568.c +++ /dev/null @@ -1,403 +0,0 @@ -/* - * 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; - } -} diff --git a/bsp/rockchip/rk3500/driver/clk/clk-pll-rk3588.c b/bsp/rockchip/rk3500/driver/clk/clk-pll-rk3588.c deleted file mode 100644 index 1b8ad79370f..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/clk-pll-rk3588.c +++ /dev/null @@ -1,727 +0,0 @@ -/* - * 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; - } -} diff --git a/bsp/rockchip/rk3500/driver/clk/clk-rk3568.c b/bsp/rockchip/rk3500/driver/clk/clk-rk3568.c deleted file mode 100644 index 4672e897609..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/clk-rk3568.c +++ /dev/null @@ -1,4791 +0,0 @@ -/* - * 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 - -#include "rk3568-cru.h" - -#define APLL_HZ (816 * MHZ) -#define GPLL_HZ (1188 * MHZ) -#define CPLL_HZ (1000 * MHZ) -#define PPLL_HZ (100 * MHZ) - -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 rt_reset_controller_clk_node -{ - struct rt_clk_node parent; - - struct rt_reset_controller rstcer; -}; - -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 <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); diff --git a/bsp/rockchip/rk3500/driver/clk/clk-rk3568.h b/bsp/rockchip/rk3500/driver/clk/clk-rk3568.h deleted file mode 100644 index 710d3211f6e..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/clk-rk3568.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * 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 -#include -#include -#include -#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__ */ diff --git a/bsp/rockchip/rk3500/driver/clk/clk-rk3588.c b/bsp/rockchip/rk3500/driver/clk/clk-rk3588.c deleted file mode 100644 index a25e2e8d4f2..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/clk-rk3588.c +++ /dev/null @@ -1,3292 +0,0 @@ -#include "clk-rk3588.h" -#define DBG_TAG "clk.rk3588" -#define DBG_LVL DBG_INFO -#include -#include -#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 rt_reset_controller_clk_node -{ - struct rt_clk_node parent; - - struct rt_reset_controller rstcer; -}; -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); diff --git a/bsp/rockchip/rk3500/driver/clk/clk-rk3588.h b/bsp/rockchip/rk3500/driver/clk/clk-rk3588.h deleted file mode 100644 index 5a8a3152a7f..00000000000 --- a/bsp/rockchip/rk3500/driver/clk/clk-rk3588.h +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 -#include -#include -#include -#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__ */ diff --git a/bsp/rockchip/rk3500/driver/rockchip.h b/bsp/rockchip/rk3500/driver/rockchip.h deleted file mode 100644 index b121be0a3f1..00000000000 --- a/bsp/rockchip/rk3500/driver/rockchip.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * 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 - -#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__ */ diff --git a/bsp/rockchip/rk3500/driver/uart8250/8250-dw.c b/bsp/rockchip/rk3500/driver/uart8250/8250-dw.c deleted file mode 100644 index 2df3086474d..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/8250-dw.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * 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 - -#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_PLATFORM_EXPORT(dw8250_drv_register); diff --git a/bsp/rockchip/rk3500/driver/uart8250/8250.h b/bsp/rockchip/rk3500/driver/uart8250/8250.h deleted file mode 100644 index 5eeb3a376cc..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/8250.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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 -#include -#include -#include -#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__ */ diff --git a/bsp/rockchip/rk3500/driver/uart8250/Kconfig b/bsp/rockchip/rk3500/driver/uart8250/Kconfig deleted file mode 100644 index e67e9f619ee..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -config RT_SERIAL_8250 - bool "8250 Serila Family" - default n diff --git a/bsp/rockchip/rk3500/driver/uart8250/core.c b/bsp/rockchip/rk3500/driver/uart8250/core.c deleted file mode 100644 index 37fd912355f..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/core.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * 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,[,options] - * uart8250,mmio,[,options] - * uart8250,mmio16,[,options] - * uart8250,mmio32,[,options] - * uart8250,mmio32be,[,options] - * uart8250,0x[,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, -}; diff --git a/bsp/rockchip/rk3500/driver/uart8250/early.c b/bsp/rockchip/rk3500/driver/uart8250/early.c deleted file mode 100644 index 971550fcc44..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/early.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 */ diff --git a/bsp/rockchip/rk3500/driver/uart8250/regs.h b/bsp/rockchip/rk3500/driver/uart8250/regs.h deleted file mode 100644 index ae675c8c71a..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/regs.h +++ /dev/null @@ -1,365 +0,0 @@ -/* - * 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 - */ - -#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__ */ diff --git a/bsp/rockchip/rk3500/driver/uart8250/serial_dm.h b/bsp/rockchip/rk3500/driver/uart8250/serial_dm.h deleted file mode 100644 index 1ec07ef86b6..00000000000 --- a/bsp/rockchip/rk3500/driver/uart8250/serial_dm.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * 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 -#include -#include - -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__ */ diff --git a/bsp/rockchip/rk3500/rtconfig.h b/bsp/rockchip/rk3500/rtconfig.h index 3eaab8291ef..6897ff3729c 100644 --- a/bsp/rockchip/rk3500/rtconfig.h +++ b/bsp/rockchip/rk3500/rtconfig.h @@ -124,7 +124,7 @@ #define RT_USING_CONSOLE #define RT_CONSOLEBUF_SIZE 1024 #define RT_CONSOLE_DEVICE_NAME "uart2" -#define RT_VER_NUM 0x50201 +#define RT_VER_NUM 0x50300 #define RT_USING_STDC_ATOMIC #define RT_BACKTRACE_LEVEL_MAX_NR 32 /* end of RT-Thread Kernel */ @@ -141,7 +141,6 @@ /* 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 @@ -212,6 +211,7 @@ #define RT_USING_SERIAL_V1 #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_SERIAL_BYPASS +#define RT_SERIAL_8250 #define RT_USING_NULL #define RT_USING_ZERO #define RT_USING_RANDOM @@ -231,6 +231,12 @@ #define RT_BLK_PARTITION_EFI /* end of Partition Types */ #define RT_USING_RESET + +/* Power Management (PM) Domains device drivers */ + +/* end of Power Management (PM) Domains device drivers */ +#define RT_USING_MFD +#define RT_MFD_SYSCON #define RT_USING_OFW #define RT_FDT_EARLYCON_MSG_SIZE 128 #define RT_USING_OFW_BUS_RANGES_NUMBER 8 @@ -238,11 +244,18 @@ #define MAX_HANDLERS 1024 #define RT_PIC_ARM_GIC_V3 #define RT_USING_PIN +#define RT_PIN_ROCKCHIP #define RT_USING_PINCTRL +#define RT_PINCTRL_ROCKCHIP #define RT_USING_KTIME #define RT_USING_CLK +#define RT_CLK_ROCKCHIP_LINK +#define RT_CLK_ROCKCHIP +#define RT_CLK_ROCKCHIP_RK3568 +#define RT_CLK_ROCKCHIP_RK3588 #define RT_USING_HWTIMER #define RT_HWTIMER_ARM_ARCH +#define RT_HWTIMER_ROCKCHIP /* end of Device Drivers */ /* C/C++ and POSIX layer */ @@ -443,13 +456,9 @@ /* end of CPP11 */ -/* LwIP */ - -/* end of LwIP */ - -/* Netdev */ +/* Network */ -/* end of Netdev */ +/* end of Network */ /* Utest Framework */ @@ -667,15 +676,6 @@ /* end of Arduino libraries */ /* end of RT-Thread online packages */ - -/* 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_HWTIMER_ROCKCHIP -/* end of RT-Thread rockchip RK3500 drivers */ -#define SOC_RK3568 +#define SOC_RK3500 #endif diff --git a/bsp/rockchip/rk3500/rtconfig.py b/bsp/rockchip/rk3500/rtconfig.py index 5d4395155a5..82c78e8c64c 100644 --- a/bsp/rockchip/rk3500/rtconfig.py +++ b/bsp/rockchip/rk3500/rtconfig.py @@ -18,7 +18,7 @@ EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin' -BUILD = 'release' +BUILD = 'debug' if PLATFORM == 'gcc': # toolchains @@ -35,7 +35,7 @@ OBJCPY = PREFIX + 'objcopy' DEVICE = ' -g -march=armv8.2-a -mtune=cortex-a55 -fdiagnostics-color=always' - CPPFLAGS= ' -E -P -x assembler-with-cpp' + CPPFLAGS= ' -nostdinc -undef -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' diff --git a/bsp/rockchip/rk3568/README.md b/bsp/rockchip/rk3568/README.md deleted file mode 100644 index 6522e5a7381..00000000000 --- a/bsp/rockchip/rk3568/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# RK3568 BSP Introduction - -[中文页](README_zh.md) | 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: -``` -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: -``` -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. - -``` -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 | diff --git a/bsp/rockchip/rk3568/README_zh.md b/bsp/rockchip/rk3568/README_zh.md deleted file mode 100644 index 3a33c555e79..00000000000 --- a/bsp/rockchip/rk3568/README_zh.md +++ /dev/null @@ -1,58 +0,0 @@ -# RK3568 板级支持包说明 - -中文页 | [English](README.md) - -## 1. 简介 - -RK3568 是一款定位中高端的通用型 SOC,采用 22nm 制程工艺,集成四核 2GHz,Cortex-A55 架构和 Mali G52 GPU,支持 4K 解码和 1080P 编码。支持 SATA/PCIE/USB3.0 等各类型外围接口,内置独立的 0.8T NPU,可用于轻量级 AI 应用。支持双千兆以太网口,LPDDR4 内存等。 - -这份 RT-Thread BSP是针对 RK3568 的一份移植。开发者可选择使用 RADXA ROCK 3A 版本的 RK3568 廉价体验,其甚至可超量替代树莓派4B。 - -## 2. 编译说明 - -建议使用ARM Developer GNU交叉编译工具链,目前支持Linux/Windows平台: -``` -https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-a/downloads/ -``` -下载x86_64 Hosted平台下载对应的`xxx-aarch64-none-elf`二进制包,解压后设置`RTT_EXEC_PATH`环境变量为该编译器的bin目录下即可。 - -进入到`rt-thread/bsp/rockchip/rk3568`目录进行输入: -``` -scons -``` -可以看到正常生成`rtthread.elf`与`rtthread.bin`文件。 - -或者通过 `scons --exec-path="GCC工具链路径"` 命令,在指定工具链位置的同时直接编译。 - -## 3. 执行 - -RK3568 根据不同的开发板实现有不同的 Kernel 烧写方式,推荐烧录进 SD 卡:([官方板](https://wiki.t-firefly.com/zh_CN/ROC-RK3568-PC/hardware_doc.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/install/microSD))。 - -在烧写完 Kernel 后,将`rtthread.bin`放入 EFI 分区(第二分区),并在该分区的`boot.cmd`最前面中添加如下行: -```shell -fatload mmc 1:1 0x208000 /rtthread.bin;dcache flush;go 0x208000 -``` -修改脚本后,在该分区生成二进制脚本`boot.scr`: -```shell -# Linux 下安装 uboot-mkimage 软件包,Windows 下使用 MSYS2 安装 u-boot-tools 软件包 -mkimage -C none -A arm -T script -d boot.cmd boot.scr -``` - -根据不同的开发板实现串口最多可支持到 UART0~9,本工程默认使用 UART2([官方板](https://wiki.t-firefly.com/zh_CN/ROC-RK3568-PC/debug.html)|[RADXA ROCK 3A](https://wiki.radxa.com/Rock3/dev/serial-console)),波特率 1500000,请确保使用的串口支持该波特率。 - -``` -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.支持情况 - -| 驱动 | 支持情况 | 备注 | -| ------ | ---- | :------: | -| UART | 支持 | UART0~9 | diff --git a/bsp/rockchip/rk3568/driver/Kconfig b/bsp/rockchip/rk3568/driver/Kconfig deleted file mode 100644 index ca85882e962..00000000000 --- a/bsp/rockchip/rk3568/driver/Kconfig +++ /dev/null @@ -1,59 +0,0 @@ -menu "Hardware Drivers Config" - - menuconfig BSP_USING_UART - bool "Using UART" - select RT_USING_SERIAL - default y - - if BSP_USING_UART - config RT_USING_UART0 - bool "Enable UART 0" - default n - - config RT_USING_UART1 - bool "Enable UART 1" - default n - - config RT_USING_UART2 - bool "Enable UART 2" - default y - - config RT_USING_UART3 - bool "Enable UART 3" - default n - - config RT_USING_UART4 - bool "Enable UART 4" - default n - - config RT_USING_UART5 - bool "Enable UART 5" - default n - - config RT_USING_UART6 - bool "Enable UART 6" - default n - - config RT_USING_UART7 - bool "Enable UART 7" - default n - - config RT_USING_UART8 - bool "Enable UART 8" - default n - - config RT_USING_UART9 - bool "Enable UART 9" - default n - endif - - config BSP_USING_GIC - bool - default y - - config BSP_USING_GICV3 - bool - default y - - select ARCH_ARM_CORTEX_A55 -endmenu diff --git a/bsp/rockchip/rk3568/driver/board.c b/bsp/rockchip/rk3568/driver/board.c deleted file mode 100644 index 4280ee3ec41..00000000000 --- a/bsp/rockchip/rk3568/driver/board.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "mm_page.h" - -#define PLATFORM_MEM_TALBE(va, size) va, ((unsigned long)va + size - 1) - -struct mem_desc platform_mem_desc[] = -{ - {PLATFORM_MEM_TALBE(0x20000000, 0x10000000), 0x20000000, NORMAL_MEM}, - {PLATFORM_MEM_TALBE(GRF_PMU_BASE, 0x10000), GRF_PMU_BASE, DEVICE_MEM}, - {PLATFORM_MEM_TALBE(GRF_SYS_BASE, 0x10000), GRF_SYS_BASE, DEVICE_MEM}, - {PLATFORM_MEM_TALBE(CRU_BASE, 0x10000), CRU_BASE, DEVICE_MEM}, - {PLATFORM_MEM_TALBE(UART0_MMIO_BASE, 0x10000), UART0_MMIO_BASE, DEVICE_MEM}, - {PLATFORM_MEM_TALBE(UART1_MMIO_BASE, 0x90000), UART1_MMIO_BASE, DEVICE_MEM}, - {PLATFORM_MEM_TALBE(GIC_PL600_DISTRIBUTOR_PPTR, 0x10000), GIC_PL600_DISTRIBUTOR_PPTR, DEVICE_MEM}, - {PLATFORM_MEM_TALBE(GIC_PL600_REDISTRIBUTOR_PPTR, 0xc0000), GIC_PL600_REDISTRIBUTOR_PPTR, DEVICE_MEM}, -#ifdef PKG_USING_RT_OPENAMP - {PLATFORM_MEM_TALBE(AMP_SHARE_MEMORY_ADDRESS, AMP_SHARE_MEMORY_SIZE), AMP_SHARE_MEMORY_ADDRESS, NORMAL_MEM}, -#endif /* PKG_USING_RT_OPENAMP */ -}; - -const rt_uint32_t platform_mem_desc_size = sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]); - -void idle_wfi(void) -{ - __asm__ volatile ("wfi"); -} - -void rt_hw_board_init(void) -{ - extern unsigned long MMUTable[512]; - rt_region_t init_page_region; - - rt_hw_mmu_map_init(&rt_kernel_space, (void *) 0x20000000, 0xE0000000 - 1, MMUTable, 0); - - init_page_region.start = RT_HW_PAGE_START; - init_page_region.end = RT_HW_PAGE_END; - rt_page_init(init_page_region); - - rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, platform_mem_desc_size); - -#ifdef RT_USING_HEAP - /* initialize memory system */ - rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); -#endif - /* initialize hardware interrupt */ - rt_hw_interrupt_init(); - - /* initialize uart */ - rt_hw_uart_init(); - - /* initialize timer for os tick */ - rt_hw_gtimer_init(); - - rt_thread_idle_sethook(idle_wfi); - -#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE) - /* set console device */ - rt_console_set_device(RT_CONSOLE_DEVICE_NAME); -#endif - -#ifdef RT_USING_HEAP - /* initialize memory system */ - rt_kprintf("heap: [0x%08x - 0x%08x]\n", RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); -#endif - -#ifdef RT_USING_COMPONENTS_INIT - rt_components_board_init(); -#endif - -#ifdef RT_USING_SMP - /* install IPI handle */ - rt_hw_ipi_handler_install(RT_SCHEDULE_IPI, rt_scheduler_ipi_handler); - arm_gic_umask(0, IRQ_ARM_IPI_KICK); -#endif -} - -void reboot(void) -{ - psci_system_reboot(); - - void *cur_base = rt_ioremap((void *) CRU_BASE, 0x100); - HWREG32(cur_base + 0x00D4) = 0xfdb9; - HWREG32(cur_base + 0x00D8) = 0xeca8; -} -MSH_CMD_EXPORT(reboot, reboot...); - -static void print_cpu_id(int argc, char *argv[]) -{ - rt_kprintf("rt_hw_cpu_id:%d\n", rt_hw_cpu_id()); -} -MSH_CMD_EXPORT_ALIAS(print_cpu_id, cpuid, print_cpu_id); - -#ifdef RT_USING_AMP -void start_cpu(int argc, char *argv[]) -{ - rt_uint32_t status; - status = rt_psci_cpu_on(0x3, (rt_uint64_t) 0x7A000000); - rt_kprintf("arm_psci_cpu_on 0x%X\n", status); -} -MSH_CMD_EXPORT(start_cpu, start_cpu); - -#ifdef RT_AMP_SLAVE -void rt_hw_cpu_shutdown(void) -{ - rt_psci_cpu_off(0); -} -#endif /* RT_AMP_SLAVE */ -#endif /* RT_USING_AMP */ - -#if defined(RT_USING_SMP) || defined(RT_USING_AMP) -rt_uint64_t rt_cpu_mpidr_early[] = -{ - [0] = 0x80000000, - [1] = 0x80000100, - [2] = 0x80000200, - [3] = 0x80000300, - [RT_CPUS_NR] = 0 -}; -#endif - -#ifdef RT_USING_SMP -void rt_hw_secondary_cpu_up(void) -{ - int i; - extern void _secondary_cpu_entry(void); - rt_uint64_t entry = (rt_uint64_t)rt_kmem_v2p(_secondary_cpu_entry); - - for (i = 1; i < RT_CPUS_NR; ++i) - { - rt_psci_cpu_on(rt_cpu_mpidr_early[i], entry); - } -} - -extern unsigned long MMUTable[]; - -void secondary_cpu_c_start(void) -{ - rt_hw_mmu_ktbl_set((unsigned long)MMUTable); - rt_hw_spin_lock(&_cpus_lock); - - arm_gic_cpu_init(0, platform_get_gic_cpu_base()); - arm_gic_redist_init(0, platform_get_gic_redist_base()); - rt_hw_vector_init(); - rt_hw_gtimer_local_enable(); - arm_gic_umask(0, IRQ_ARM_IPI_KICK); - - rt_kprintf("\rcall cpu %d on success\n", rt_hw_cpu_id()); - - rt_system_scheduler_start(); -} - -void rt_hw_secondary_cpu_idle_exec(void) -{ - rt_hw_wfe(); -} -#endif diff --git a/bsp/rockchip/rk3568/driver/board.h b/bsp/rockchip/rk3568/driver/board.h deleted file mode 100644 index 470e23882ea..00000000000 --- a/bsp/rockchip/rk3568/driver/board.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2006-2022, 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 - -extern unsigned char __bss_start; -extern unsigned char __bss_end; - -#define RT_HW_PAGE_START RT_ALIGN((unsigned long)&__bss_end, 0x1000) -#define RT_HW_PAGE_END (RT_HW_PAGE_START + 0x100000) - -#define RT_HW_HEAP_BEGIN (void *)(RT_HW_PAGE_END) -#define RT_HW_HEAP_END (void *)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024) - -void rt_hw_board_init(void); - -#endif /* __BOARD_H__ */ diff --git a/bsp/rockchip/rk3568/driver/drv_uart.c b/bsp/rockchip/rk3568/driver/drv_uart.c deleted file mode 100644 index 9fc1b9693fe..00000000000 --- a/bsp/rockchip/rk3568/driver/drv_uart.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#include -#include -#include - -#include - -/* - * 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. - */ - -#define UART_RX 0 /* In: Receive buffer */ -#define UART_TX 0 /* Out: Transmit buffer */ - -#define UART_DLL 0 /* Out: Divisor Latch Low */ -#define UART_DLM 1 /* Out: Divisor Latch High */ - -#define UART_IER 1 /* Out: Interrupt Enable Register */ -#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ - -#define UART_SSR 0x22 /* In: Software Reset Register */ -#define UART_USR 0x1f /* UART Status Register */ - -#define UART_LCR 3 /* Out: Line Control Register */ -#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ -#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ -#define UART_LCR_PARITY 0x8 /* Parity Enable */ -#define UART_LCR_STOP 0x4 /* Stop bits: 0=1 bit, 1=2 bits */ -#define UART_LCR_WLEN8 0x3 /* Wordlength: 8 bits */ - -#define UART_MCR 4 /* Out: Modem Control Register */ -#define UART_MCR_RTS 0x02 /* RTS complement */ - -#define UART_LSR 5 /* In: Line Status Register */ -#define UART_LSR_BI 0x10 /* Break interrupt indicator */ -#define UART_LSR_DR 0x01 /* Receiver data ready */ - -#define UART_IIR 2 /* In: Interrupt ID Register */ -#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ -#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ -#define UART_IIR_RX_TIMEOUT 0x0c /* OMAP RX Timeout interrupt */ - -#define UART_FCR 2 /* Out: FIFO Control Register */ -#define UART_FCR_EN_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_REG_SHIFT 0x2 /* Register Shift*/ -#define UART_INPUT_CLK 24000000 - -struct hw_uart_device -{ - rt_ubase_t hw_base; - rt_uint32_t irqno; -#ifdef RT_USING_SMP - struct rt_spinlock spinlock; -#endif -}; - -#define BSP_DEFINE_UART_DEVICE(no) \ -static struct hw_uart_device _uart##no##_device = \ -{ \ - UART##no##_MMIO_BASE, \ - UART##no##_IRQ \ -}; \ -static struct rt_serial_device _serial##no; - -#ifdef RT_USING_UART0 -BSP_DEFINE_UART_DEVICE(0); -#endif - -#ifdef RT_USING_UART1 -BSP_DEFINE_UART_DEVICE(1); -#endif - -#ifdef RT_USING_UART2 -BSP_DEFINE_UART_DEVICE(2); -#endif - -#ifdef RT_USING_UART3 -BSP_DEFINE_UART_DEVICE(3); -#endif - -#ifdef RT_USING_UART4 -BSP_DEFINE_UART_DEVICE(4); -#endif - -#ifdef RT_USING_UART5 -BSP_DEFINE_UART_DEVICE(5); -#endif - -#ifdef RT_USING_UART6 -BSP_DEFINE_UART_DEVICE(6); -#endif - -#ifdef RT_USING_UART7 -BSP_DEFINE_UART_DEVICE(7); -#endif - -#ifdef RT_USING_UART8 -BSP_DEFINE_UART_DEVICE(8); -#endif - -#ifdef RT_USING_UART9 -BSP_DEFINE_UART_DEVICE(9); -#endif - -rt_inline rt_uint32_t dw8250_read32(rt_ubase_t addr, rt_ubase_t offset) -{ - return *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))); -} - -rt_inline void dw8250_write32(rt_ubase_t addr, rt_ubase_t offset, rt_uint32_t value) -{ - *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value; - - if (offset == UART_LCR) - { - int tries = 1000; - - /* Make sure LCR write wasn't ignored */ - while (tries--) - { - unsigned int lcr = dw8250_read32(addr, UART_LCR); - - if ((value & ~UART_LCR_SPAR) == (lcr & ~UART_LCR_SPAR)) - { - return; - } - - dw8250_write32(addr, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - dw8250_read32(addr, UART_RX); - - *((volatile rt_uint32_t *)(addr + (offset << UART_REG_SHIFT))) = value; - } - } -} - -static rt_err_t dw8250_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg) -{ - rt_base_t base, rate; - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - base = uart->hw_base; - -#ifdef RT_USING_SMP - rt_spin_lock_init(&uart->spinlock); -#endif - - /* Resset UART */ - dw8250_write32(base, UART_SSR, 1); - dw8250_write32(base, UART_SSR, 0); - - dw8250_write32(base, UART_IER, !UART_IER_RDI); - dw8250_write32(base, UART_FCR, UART_FCR_EN_FIFO | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); - - /* Disable flow ctrl */ - dw8250_write32(base, UART_MCR, 0); - /* Clear RTS */ - dw8250_write32(base, UART_MCR, dw8250_read32(base, UART_MCR) | UART_MCR_RTS); - - rate = UART_INPUT_CLK / 16 / serial->config.baud_rate; - - /* Enable access DLL & DLH */ - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) | UART_LCR_DLAB); - dw8250_write32(base, UART_DLL, (rate & 0xff)); - dw8250_write32(base, UART_DLM, (rate & 0xff00) >> 8); - /* Clear DLAB bit */ - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_DLAB)); - - dw8250_write32(base, UART_LCR, (dw8250_read32(base, UART_LCR) & (~UART_LCR_WLEN8)) | UART_LCR_WLEN8); - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_STOP)); - dw8250_write32(base, UART_LCR, dw8250_read32(base, UART_LCR) & (~UART_LCR_PARITY)); - - dw8250_write32(base, UART_IER, UART_IER_RDI); - - return RT_EOK; -} - -static rt_err_t dw8250_uart_control(struct rt_serial_device *serial, int cmd, void *arg) -{ - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - - switch (cmd) - { - case RT_DEVICE_CTRL_CLR_INT: - /* Disable rx irq */ - dw8250_write32(uart->hw_base, UART_IER, !UART_IER_RDI); - rt_hw_interrupt_mask(uart->irqno); - break; - - case RT_DEVICE_CTRL_SET_INT: - /* Enable rx irq */ - dw8250_write32(uart->hw_base, UART_IER, UART_IER_RDI); - rt_hw_interrupt_umask(uart->irqno); - break; - } - - return RT_EOK; -} - -static int dw8250_uart_putc(struct rt_serial_device *serial, char c) -{ - rt_base_t base; - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - base = uart->hw_base; - - while ((dw8250_read32(base, UART_USR) & 0x2) == 0) - { - } - - dw8250_write32(base, UART_TX, c); - - return 1; -} - -static int dw8250_uart_getc(struct rt_serial_device *serial) -{ - int ch = -1; - rt_base_t base; - struct hw_uart_device *uart; - - RT_ASSERT(serial != RT_NULL); - uart = (struct hw_uart_device *)serial->parent.user_data; - base = uart->hw_base; - - if ((dw8250_read32(base, UART_LSR) & 0x1)) - { - ch = dw8250_read32(base, UART_RX) & 0xff; - } - - return ch; -} - -static const struct rt_uart_ops _uart_ops = -{ - dw8250_uart_configure, - dw8250_uart_control, - dw8250_uart_putc, - dw8250_uart_getc, -}; - -static void rt_hw_uart_isr(int irqno, void *param) -{ - unsigned int iir, status; - struct rt_serial_device *serial = (struct rt_serial_device *)param; - struct hw_uart_device *uart = (struct hw_uart_device *)serial->parent.user_data; - - iir = dw8250_read32(uart->hw_base, 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) - { -#ifdef RT_USING_SMP - rt_base_t level = rt_spin_lock_irqsave(&uart->spinlock); -#endif - - status = dw8250_read32(uart->hw_base, UART_LSR); - - if (!(status & (UART_LSR_DR | UART_LSR_BI))) - { - dw8250_read32(uart->hw_base, UART_RX); - } - -#ifdef RT_USING_SMP - rt_spin_unlock_irqrestore(&uart->spinlock, level); -#endif - } - - if (!(iir & UART_IIR_NO_INT)) - { - rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); - } - - if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) - { - /* Clear the USR */ - dw8250_read32(uart->hw_base, UART_USR); - - return; - } -} - -int rt_hw_uart_init(void) -{ - rt_uint32_t value; - struct hw_uart_device* uart; - struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - RT_UNUSED(value); - - config.baud_rate = 1500000; - -#define BSP_INSTALL_UART_DEVICE(no) \ - uart = &_uart##no##_device; \ - _serial##no.ops = &_uart_ops; \ - _serial##no.config = config; \ - rt_hw_serial_register(&_serial##no, "uart" #no, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); \ - rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, &_serial##no, "uart" #no); - -#ifdef RT_USING_UART0 - BSP_INSTALL_UART_DEVICE(0); -#endif - -#ifdef RT_USING_UART1 - BSP_INSTALL_UART_DEVICE(1); -#endif - -#ifdef RT_USING_UART2 - BSP_INSTALL_UART_DEVICE(2); -#endif - -#ifdef RT_USING_UART3 - BSP_INSTALL_UART_DEVICE(3); -#endif - -#ifdef RT_USING_UART4 - HWREG32(CRU_BASE + 0x370) = 0xFFFF0000 | (0x600) |(HWREG32(CRU_BASE + 0x370) & 0xF0FF); - value = HWREG32(0xFDC60000 + 0x48); - value &= ~((7 << 8) | (7 << 4)); - value |= 0xFFFF0000 | (4 << 8) | (4 << 4); - HWREG32(0xFDC60000 + 0x48) = value; - HWREG32(0xFDC60000 + 0x30C) = 0xFFFF0000 | (1 << 14) | HWREG32(0xFDC60000 + 0x30C); - BSP_INSTALL_UART_DEVICE(4); -#endif - -#ifdef RT_USING_UART5 - BSP_INSTALL_UART_DEVICE(5); -#endif - -#ifdef RT_USING_UART6 - BSP_INSTALL_UART_DEVICE(6); -#endif - -#ifdef RT_USING_UART7 - BSP_INSTALL_UART_DEVICE(7); -#endif - -#ifdef RT_USING_UART8 - BSP_INSTALL_UART_DEVICE(8); -#endif - -#ifdef RT_USING_UART9 - BSP_INSTALL_UART_DEVICE(9); -#endif - - return 0; -} diff --git a/bsp/rockchip/rk3568/driver/rk3568.h b/bsp/rockchip/rk3568/driver/rk3568.h deleted file mode 100644 index bc87c8566bb..00000000000 --- a/bsp/rockchip/rk3568/driver/rk3568.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2006-2022, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2022-3-08 GuEe-GUI the first version - */ - -#ifndef __RK3568_H__ -#define __RK3568_H__ - -#include - -#define GRF_PMU_BASE 0xFDC20000 -#define GRF_SYS_BASE 0xFDC60000 -#define CRU_BASE 0xFDD20000 - - /* UART */ -#define UART_MMIO_BASE 0xfe650000 -#define UART0_MMIO_BASE 0xfdd50000 -#define UART1_MMIO_BASE (UART_MMIO_BASE + 0) -#define UART2_MMIO_BASE (UART_MMIO_BASE + 0x10000) -#define UART3_MMIO_BASE (UART_MMIO_BASE + 0x20000) -#define UART4_MMIO_BASE (UART_MMIO_BASE + 0x30000) -#define UART5_MMIO_BASE (UART_MMIO_BASE + 0x40000) -#define UART6_MMIO_BASE (UART_MMIO_BASE + 0x50000) -#define UART7_MMIO_BASE (UART_MMIO_BASE + 0x60000) -#define UART8_MMIO_BASE (UART_MMIO_BASE + 0x70000) -#define UART9_MMIO_BASE (UART_MMIO_BASE + 0x80000) - -#define UART_MMIO_SIZE 0x100 - -#define UART_IRQ_BASE (32 + 116) -#define UART0_IRQ (UART_IRQ_BASE + 0) -#define UART1_IRQ (UART_IRQ_BASE + 1) -#define UART2_IRQ (UART_IRQ_BASE + 2) -#define UART3_IRQ (UART_IRQ_BASE + 3) -#define UART4_IRQ (UART_IRQ_BASE + 4) -#define UART5_IRQ (UART_IRQ_BASE + 5) -#define UART6_IRQ (UART_IRQ_BASE + 6) -#define UART7_IRQ (UART_IRQ_BASE + 7) -#define UART8_IRQ (UART_IRQ_BASE + 8) -#define UART9_IRQ (UART_IRQ_BASE + 9) - -/* GPIO */ -#define GPIO0_MMIO_BASE 0xfdd60000 -#define GPIO1_MMIO_BASE 0xfe740000 -#define GPIO2_MMIO_BASE 0xfe750000 -#define GPIO3_MMIO_BASE 0xfe760000 -#define GPIO4_MMIO_BASE 0xfe770000 - -#define GPIO_MMIO_SIZE 0x100 - -#define GPIO_IRQ_BASE (32 + 33) -#define GPIO0_IRQ (GPIO_IRQ_BASE + 0) -#define GPIO1_IRQ (GPIO_IRQ_BASE + 1) -#define GPIO2_IRQ (GPIO_IRQ_BASE + 2) -#define GPIO3_IRQ (GPIO_IRQ_BASE + 3) -#define GPIO4_IRQ (GPIO_IRQ_BASE + 4) - -/* MMC */ -#define MMC0_MMIO_BASE 0xfe310000 /* sdhci */ -#define MMC1_MMIO_BASE 0xfe2b0000 /* sdmmc0 */ -#define MMC2_MMIO_BASE 0xfe2c0000 /* sdmmc1 */ -#define MMC3_MMIO_BASE 0xfe000000 /* sdmmc2 */ - -#define MMC0_MMIO_SIZE 0x10000 -#define MMC_MMIO_SIZE 0x4000 - -#define MMC0_IRQ (32 + 19) -#define MMC1_IRQ (32 + 98) -#define MMC2_IRQ (32 + 99) -#define MMC3_IRQ (32 + 100) - -/* Ethernet */ -#define GMAC0_MMIO_BASE 0xfe2a0000 -#define GMAC1_MMIO_BASE 0xfe010000 - -#define GMAC_MMIO_SIZE 0x10000 - -#define GMAC0_MAC_IRQ (32 + 27) -#define GMAC0_WAKE_IRQ (32 + 24) -#define GMAC1_MAC_IRQ (32 + 32) -#define GMAC1_WAKE_IRQ (32 + 29) - -/* GIC */ -#define MAX_HANDLERS 256 -#define GIC_IRQ_START 0 -#define ARM_GIC_NR_IRQS 256 -#define ARM_GIC_MAX_NR 1 - -#define IRQ_ARM_IPI_KICK 0 -#define IRQ_ARM_IPI_CALL 1 - -#define GIC_PL600_DISTRIBUTOR_PPTR 0xfd400000 -#define GIC_PL600_REDISTRIBUTOR_PPTR 0xfd460000 -#define GIC_PL600_CONTROLLER_PPTR RT_NULL -#define GIC_PL600_ITS_PPTR 0xfd440000 - -rt_inline rt_uint32_t platform_get_gic_dist_base(void) -{ - return GIC_PL600_DISTRIBUTOR_PPTR; -} - -rt_inline rt_uint32_t platform_get_gic_redist_base(void) -{ - return GIC_PL600_REDISTRIBUTOR_PPTR; -} - -rt_inline rt_uint32_t platform_get_gic_cpu_base(void) -{ - return GIC_PL600_CONTROLLER_PPTR; -} - -rt_inline rt_uint32_t platform_get_gic_its_base(void) -{ - return GIC_PL600_ITS_PPTR; -} - -#endif /* __RK3568_H__ */ diff --git a/bsp/rockchip/rk3568/link.lds b/bsp/rockchip/rk3568/link.lds deleted file mode 100644 index c720509d9a4..00000000000 --- a/bsp/rockchip/rk3568/link.lds +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2006-2023, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2017-5-30 bernard first version - */ - -OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64") -OUTPUT_ARCH(aarch64) - -SECTIONS -{ - _text_offset = 0x20000000; - - . = 0x20000000; - . = ALIGN(4096); - .text : - { - KEEP(*(.text.entrypoint)) /* The entry point */ - *(.vectors) - *(.text) /* remaining code */ - *(.text.*) /* remaining code */ - - *(.rodata) /* read-only data (constants) */ - *(.rodata*) - *(.glue_7) - *(.glue_7t) - *(.gnu.linkonce.t*) - - *(COMMON) - - /* section information for finsh shell */ - . = ALIGN(16); - __fsymtab_start = .; - KEEP(*(FSymTab)) - __fsymtab_end = .; - . = ALIGN(16); - __vsymtab_start = .; - KEEP(*(VSymTab)) - __vsymtab_end = .; - . = ALIGN(16); - - /* section information for initial. */ - . = ALIGN(16); - __rt_init_start = .; - KEEP(*(SORT(.rti_fn*))) - __rt_init_end = .; - . = ALIGN(16); - - . = ALIGN(16); - _etext = .; - } - - .eh_frame_hdr : - { - *(.eh_frame_hdr) - *(.eh_frame_entry) - } - .eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } - - . = ALIGN(16); - .data : - { - *(.data) - *(.data.*) - - *(.data1) - *(.data1.*) - - . = ALIGN(16); - _gp = ABSOLUTE(.); /* Base of small data */ - - *(.sdata) - *(.sdata.*) - } - - . = ALIGN(16); - .ctors : - { - PROVIDE(__ctors_start__ = .); - /* new GCC version uses .init_array */ - KEEP(*(SORT(.init_array.*))) - KEEP(*(.init_array)) - PROVIDE(__ctors_end__ = .); - } - - .dtors : - { - PROVIDE(__dtors_start__ = .); - KEEP(*(SORT(.dtors.*))) - KEEP(*(.dtors)) - PROVIDE(__dtors_end__ = .); - } - - . = ALIGN(16); - .bss : - { - PROVIDE(__bss_start = .); - *(.bss) - *(.bss.*) - *(.dynbss) - - . = ALIGN(16); - PROVIDE(__bss_end = .); - } - _end = .; - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } - /* DWARF debug sections. - * Symbols in the DWARF debugging sections are relative to the beginning - * of the section so we begin them at 0. */ - /* DWARF 1 */ - .debug 0 : { *(.debug) } - .line 0 : { *(.line) } - /* GNU DWARF 1 extensions */ - .debug_srcinfo 0 : { *(.debug_srcinfo) } - .debug_sfnames 0 : { *(.debug_sfnames) } - /* DWARF 1.1 and DWARF 2 */ - .debug_aranges 0 : { *(.debug_aranges) } - .debug_pubnames 0 : { *(.debug_pubnames) } - /* DWARF 2 */ - .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } - .debug_abbrev 0 : { *(.debug_abbrev) } - .debug_line 0 : { *(.debug_line) } - .debug_frame 0 : { *(.debug_frame) } - .debug_str 0 : { *(.debug_str) } - .debug_loc 0 : { *(.debug_loc) } - .debug_macinfo 0 : { *(.debug_macinfo) } - /* SGI/MIPS DWARF 2 extensions */ - .debug_weaknames 0 : { *(.debug_weaknames) } - .debug_funcnames 0 : { *(.debug_funcnames) } - .debug_typenames 0 : { *(.debug_typenames) } - .debug_varnames 0 : { *(.debug_varnames) } -} - -__bss_size = SIZEOF(.bss);