From be32bce9df100196122d80967cb96b9dd9299ed4 Mon Sep 17 00:00:00 2001 From: aiamadeus <2789289348@qq.com> Date: Fri, 16 Aug 2024 23:18:15 +0800 Subject: [PATCH] rockchip: add basic support for RK3528(A) RK3528 is a cost down SoC with high CPU performance. However, it has poor PCIe performance (same for RK3576). Also CPU 0/1 can't get any rest due to rkbin limitation. Some code references: https://github.com/warpme/minimyth2 --- target/linux/rockchip/armv8/config-6.1 | 9 +- target/linux/rockchip/armv8/config-6.6 | 7 +- .../boot/dts/rockchip/rk3528-pinctrl.dtsi | 1406 +++++++++++++++ .../arch/arm64/boot/dts/rockchip/rk3528.dtsi | 1439 +++++++++++++++ .../drivers/char/hw_random/rockchip-rng.c | 348 +++- .../files/drivers/clk/rockchip/clk-rk3528.c | 1124 ++++++++++++ .../pci/controller/dwc/pcie-dw-rkvendor.c | 1538 +++++++++++++++++ .../pci/controller/dwc/rockchip-pcie-dma.h | 269 +++ .../include/dt-bindings/clock/rk3528-cru.h | 746 ++++++++ .../include/dt-bindings/power/rk3528-power.h | 18 + ...-pinctrl-rockchip-add-rk3528-support.patch | 269 +++ ...rmal-rockchip-add-support-for-rk3528.patch | 353 ++++ ...-rockchip-power-domain-Add-always-on.patch | 61 + ...chip-power-domain-add-rk3528-support.patch | 103 ++ ...-add-clock-controller-for-the-RK3528.patch | 177 ++ ...stmmac-dwmac-rk3528-add-GMAC-support.patch | 227 +++ ...inno-usb2-add-phy-support-for-rk3528.patch | 64 + ...ip-naneng-combphy-add-support-rk3528.patch | 176 ++ ...i-of-dwcmshc-pcie-support-for-rk3528.patch | 107 ++ ...w_mmc-rockchip-add-v2-tuning-support.patch | 110 ++ ...-pinctrl-rockchip-add-rk3528-support.patch | 269 +++ ...rmal-rockchip-add-support-for-rk3528.patch | 191 ++ ...-rockchip-power-domain-Add-always-on.patch | 61 + ...chip-power-domain-add-rk3528-support.patch | 103 ++ ...-add-clock-controller-for-the-RK3528.patch | 178 ++ ...stmmac-dwmac-rk3528-add-GMAC-support.patch | 227 +++ ...inno-usb2-add-phy-support-for-rk3528.patch | 64 + ...ip-naneng-combphy-add-support-rk3528.patch | 176 ++ ...i-of-dwcmshc-pcie-support-for-rk3528.patch | 107 ++ ...w_mmc-rockchip-add-v2-tuning-support.patch | 110 ++ 30 files changed, 9990 insertions(+), 47 deletions(-) create mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528-pinctrl.dtsi create mode 100644 target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528.dtsi create mode 100644 target/linux/rockchip/files/drivers/clk/rockchip/clk-rk3528.c create mode 100644 target/linux/rockchip/files/drivers/pci/controller/dwc/pcie-dw-rkvendor.c create mode 100644 target/linux/rockchip/files/drivers/pci/controller/dwc/rockchip-pcie-dma.h create mode 100644 target/linux/rockchip/files/include/dt-bindings/clock/rk3528-cru.h create mode 100644 target/linux/rockchip/files/include/dt-bindings/power/rk3528-power.h create mode 100644 target/linux/rockchip/patches-6.1/301-pinctrl-rockchip-add-rk3528-support.patch create mode 100644 target/linux/rockchip/patches-6.1/302-thermal-rockchip-add-support-for-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.1/303-soc-rockchip-power-domain-Add-always-on.patch create mode 100644 target/linux/rockchip/patches-6.1/304-soc-rockchip-power-domain-add-rk3528-support.patch create mode 100644 target/linux/rockchip/patches-6.1/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch create mode 100644 target/linux/rockchip/patches-6.1/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch create mode 100644 target/linux/rockchip/patches-6.1/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.1/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.1/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.1/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch create mode 100644 target/linux/rockchip/patches-6.6/301-pinctrl-rockchip-add-rk3528-support.patch create mode 100644 target/linux/rockchip/patches-6.6/302-thermal-rockchip-add-support-for-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.6/303-soc-rockchip-power-domain-Add-always-on.patch create mode 100644 target/linux/rockchip/patches-6.6/304-soc-rockchip-power-domain-add-rk3528-support.patch create mode 100644 target/linux/rockchip/patches-6.6/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch create mode 100644 target/linux/rockchip/patches-6.6/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch create mode 100644 target/linux/rockchip/patches-6.6/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.6/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.6/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch create mode 100644 target/linux/rockchip/patches-6.6/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch diff --git a/target/linux/rockchip/armv8/config-6.1 b/target/linux/rockchip/armv8/config-6.1 index 03d46d92b..4f979fda1 100644 --- a/target/linux/rockchip/armv8/config-6.1 +++ b/target/linux/rockchip/armv8/config-6.1 @@ -97,6 +97,7 @@ CONFIG_BLK_DEV_NVME=y CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_MQ_PCI=y +CONFIG_BLK_NVMEM=y CONFIG_BLK_PM=y CONFIG_BLOCK_COMPAT=y CONFIG_BRCMSTB_GISB_ARB=y @@ -112,6 +113,7 @@ CONFIG_CLK_RK3308=y CONFIG_CLK_RK3328=y CONFIG_CLK_RK3368=y CONFIG_CLK_RK3399=y +CONFIG_CLK_RK3528=y CONFIG_CLK_RK3568=y CONFIG_CLONE_BACKWARDS=y CONFIG_CMA=y @@ -135,7 +137,6 @@ CONFIG_COMPAT=y CONFIG_COMPAT_32BIT_TIME=y # CONFIG_COMPAT_ALIGNMENT_FIXUPS is not set CONFIG_COMPAT_BINFMT_ELF=y -CONFIG_COMPAT_NETLINK_MESSAGES=y CONFIG_COMPAT_OLD_SIGACTION=y CONFIG_CONFIGFS_FS=y CONFIG_CONSOLE_TRANSLATIONS=y @@ -160,6 +161,7 @@ CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y CONFIG_CPU_ISOLATION=y CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_MITIGATIONS=y CONFIG_CPU_PM=y CONFIG_CPU_RMAP=y CONFIG_CPU_THERMAL=y @@ -200,7 +202,6 @@ CONFIG_DEVMEM=y # CONFIG_DEVPORT is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y -# CONFIG_DEVTMPFS_SAFE is not set CONFIG_DMADEVICES=y CONFIG_DMA_CMA=y CONFIG_DMA_DIRECT_REMAP=y @@ -238,7 +239,7 @@ CONFIG_FS_POSIX_ACL=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_REGS=y CONFIG_GENERIC_ALLOCATOR=y @@ -411,6 +412,7 @@ CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=256 CONFIG_NVMEM=y +CONFIG_NVMEM_LAYOUTS=y CONFIG_NVMEM_ROCKCHIP_EFUSE=y CONFIG_NVMEM_ROCKCHIP_OTP=y CONFIG_NVMEM_SYSFS=y @@ -462,6 +464,7 @@ CONFIG_PCI_STUB=y CONFIG_PCS_XPCS=y CONFIG_PGTABLE_LEVELS=4 CONFIG_PHYLIB=y +CONFIG_PHYLIB_LEDS=y CONFIG_PHYLINK=y CONFIG_PHYS_ADDR_T_64BIT=y CONFIG_PHY_ROCKCHIP_DP=y diff --git a/target/linux/rockchip/armv8/config-6.6 b/target/linux/rockchip/armv8/config-6.6 index 32773253f..d38b2d8ac 100644 --- a/target/linux/rockchip/armv8/config-6.6 +++ b/target/linux/rockchip/armv8/config-6.6 @@ -101,6 +101,7 @@ CONFIG_BLK_DEV_PCIESSD_MTIP32XX=y CONFIG_BLK_DEV_SD=y CONFIG_BLK_MQ_PCI=y CONFIG_BLK_PM=y +CONFIG_BLOCK_NOTIFIERS=y CONFIG_BRCMSTB_GISB_ARB=y CONFIG_BSD_PROCESS_ACCT=y CONFIG_BSD_PROCESS_ACCT_V3=y @@ -116,6 +117,7 @@ CONFIG_CLK_RK3308=y CONFIG_CLK_RK3328=y CONFIG_CLK_RK3368=y CONFIG_CLK_RK3399=y +CONFIG_CLK_RK3528=y CONFIG_CLK_RK3568=y CONFIG_CLK_RK3588=y CONFIG_CLONE_BACKWARDS=y @@ -164,6 +166,7 @@ CONFIG_CPU_IDLE_GOV_MENU=y CONFIG_CPU_IDLE_MULTIPLE_DRIVERS=y CONFIG_CPU_ISOLATION=y CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_CPU_MITIGATIONS=y CONFIG_CPU_PM=y CONFIG_CPU_RMAP=y CONFIG_CPU_THERMAL=y @@ -250,7 +253,7 @@ CONFIG_FUNCTION_ALIGNMENT_4B=y CONFIG_FWNODE_MDIO=y CONFIG_FW_LOADER_PAGED_BUF=y CONFIG_FW_LOADER_SYSFS=y -CONFIG_GCC11_NO_ARRAY_BOUNDS=y +CONFIG_GCC10_NO_ARRAY_BOUNDS=y CONFIG_GCC_ASM_GOTO_OUTPUT_WORKAROUND=y CONFIG_GCC_SUPPORTS_DYNAMIC_FTRACE_WITH_ARGS=y CONFIG_GENERIC_ALLOCATOR=y @@ -432,6 +435,7 @@ CONFIG_NO_HZ_COMMON=y CONFIG_NO_HZ_IDLE=y CONFIG_NR_CPUS=256 CONFIG_NVMEM=y +CONFIG_NVMEM_BLOCK=y CONFIG_NVMEM_LAYOUTS=y CONFIG_NVMEM_ROCKCHIP_EFUSE=y CONFIG_NVMEM_ROCKCHIP_OTP=y @@ -683,7 +687,6 @@ CONFIG_TYPEC_FUSB302=y CONFIG_TYPEC_TCPM=y # CONFIG_TYPEC_TPS6598X is not set # CONFIG_TYPEC_WUSB3801 is not set -# CONFIG_UACCE is not set # CONFIG_UCLAMP_TASK is not set # CONFIG_UEVENT_HELPER is not set CONFIG_UNINLINE_SPIN_UNLOCK=y diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528-pinctrl.dtsi b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528-pinctrl.dtsi new file mode 100644 index 000000000..fad0bd9be --- /dev/null +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528-pinctrl.dtsi @@ -0,0 +1,1406 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + */ + +#include +#include "rockchip-pinconf.dtsi" + +/* + * This file is auto generated by pin2dts tool, please keep these code + * by adding changes at end of this file. + */ +&pinctrl { + arm { + /omit-if-no-ref/ + arm_pins: arm-pins { + rockchip,pins = + /* arm_avs */ + <4 RK_PC4 3 &pcfg_pull_none>; + }; + }; + + clk { + /omit-if-no-ref/ + clkm0_32k_out: clkm0-32k-out { + rockchip,pins = + /* clkm0_32k_out */ + <3 RK_PC3 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + clkm1_32k_out: clkm1-32k-out { + rockchip,pins = + /* clkm1_32k_out */ + <1 RK_PC3 1 &pcfg_pull_none>; + }; + }; + + emmc { + /omit-if-no-ref/ + emmc_rstnout: emmc-rstnout { + rockchip,pins = + /* emmc_rstn */ + <1 RK_PD6 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + emmc_bus8: emmc-bus8 { + rockchip,pins = + /* emmc_d0 */ + <1 RK_PC4 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d1 */ + <1 RK_PC5 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d2 */ + <1 RK_PC6 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d3 */ + <1 RK_PC7 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d4 */ + <1 RK_PD0 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d5 */ + <1 RK_PD1 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d6 */ + <1 RK_PD2 1 &pcfg_pull_up_drv_level_2>, + /* emmc_d7 */ + <1 RK_PD3 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + emmc_clk: emmc-clk { + rockchip,pins = + /* emmc_clk */ + <1 RK_PD5 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + emmc_cmd: emmc-cmd { + rockchip,pins = + /* emmc_cmd */ + <1 RK_PD4 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + emmc_strb: emmc-strb { + rockchip,pins = + /* emmc_strb */ + <1 RK_PD7 1 &pcfg_pull_none>; + }; + }; + + eth { + /omit-if-no-ref/ + eth_pins: eth-pins { + rockchip,pins = + /* eth_clk_25m_out */ + <3 RK_PB5 2 &pcfg_pull_none_drv_level_2>; + }; + }; + + fephy { + /omit-if-no-ref/ + fephym0_led_dpx: fephym0-led_dpx { + rockchip,pins = + /* fephy_led_dpx_m0 */ + <4 RK_PB5 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + fephym0_led_link: fephym0-led_link { + rockchip,pins = + /* fephy_led_link_m0 */ + <4 RK_PC0 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + fephym0_led_spd: fephym0-led_spd { + rockchip,pins = + /* fephy_led_spd_m0 */ + <4 RK_PB7 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + fephym1_led_dpx: fephym1-led_dpx { + rockchip,pins = + /* fephy_led_dpx_m1 */ + <2 RK_PA4 5 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + fephym1_led_link: fephym1-led_link { + rockchip,pins = + /* fephy_led_link_m1 */ + <2 RK_PA6 5 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + fephym1_led_spd: fephym1-led_spd { + rockchip,pins = + /* fephy_led_spd_m1 */ + <2 RK_PA5 5 &pcfg_pull_none>; + }; + }; + + fspi { + /omit-if-no-ref/ + fspi_pins: fspi-pins { + rockchip,pins = + /* fspi_clk */ + <1 RK_PD5 2 &pcfg_pull_none>, + /* fspi_d0 */ + <1 RK_PC4 2 &pcfg_pull_none>, + /* fspi_d1 */ + <1 RK_PC5 2 &pcfg_pull_none>, + /* fspi_d2 */ + <1 RK_PC6 2 &pcfg_pull_none>, + /* fspi_d3 */ + <1 RK_PC7 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + fspi_csn0: fspi-csn0 { + rockchip,pins = + /* fspi_csn0 */ + <1 RK_PD0 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + fspi_csn1: fspi-csn1 { + rockchip,pins = + /* fspi_csn1 */ + <1 RK_PD1 2 &pcfg_pull_none>; + }; + }; + + gpu { + /omit-if-no-ref/ + gpu_pins: gpu-pins { + rockchip,pins = + /* gpu_avs */ + <4 RK_PC3 3 &pcfg_pull_none>; + }; + }; + + hdmi { + /omit-if-no-ref/ + hdmi_pins: hdmi-pins { + rockchip,pins = + /* hdmi_tx_cec */ + <0 RK_PA3 1 &pcfg_pull_none>, + /* hdmi_tx_scl */ + <0 RK_PA4 1 &pcfg_pull_none>, + /* hdmi_tx_sda */ + <0 RK_PA5 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + hdmi_pins_idle: hdmi-pins-idle { + rockchip,pins = + /* hdmi_tx_cec */ + <0 RK_PA3 1 &pcfg_pull_none>, + /* hdmi_tx_scl */ + <0 RK_PA4 0 &pcfg_pull_none>, + /* hdmi_tx_sda */ + <0 RK_PA5 0 &pcfg_pull_none>; + }; + }; + + hsm { + /omit-if-no-ref/ + hsmm0_pins: hsmm0-pins { + rockchip,pins = + /* hsm_clk_out_m0 */ + <2 RK_PA2 4 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + hsmm1_pins: hsmm1-pins { + rockchip,pins = + /* hsm_clk_out_m1 */ + <1 RK_PA4 3 &pcfg_pull_none>; + }; + }; + + i2c0 { + /omit-if-no-ref/ + i2c0m0_xfer: i2c0m0-xfer { + rockchip,pins = + /* i2c0_scl_m0 */ + <4 RK_PC4 2 &pcfg_pull_none_smt>, + /* i2c0_sda_m0 */ + <4 RK_PC3 2 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2c0m1_xfer: i2c0m1-xfer { + rockchip,pins = + /* i2c0_scl_m1 */ + <4 RK_PA1 2 &pcfg_pull_none_smt>, + /* i2c0_sda_m1 */ + <4 RK_PA0 2 &pcfg_pull_none_smt>; + }; + }; + + i2c1 { + /omit-if-no-ref/ + i2c1m0_xfer: i2c1m0-xfer { + rockchip,pins = + /* i2c1_scl_m0 */ + <4 RK_PA3 2 &pcfg_pull_none_smt>, + /* i2c1_sda_m0 */ + <4 RK_PA2 2 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2c1m1_xfer: i2c1m1-xfer { + rockchip,pins = + /* i2c1_scl_m1 */ + <4 RK_PC5 4 &pcfg_pull_none_smt>, + /* i2c1_sda_m1 */ + <4 RK_PC6 4 &pcfg_pull_none_smt>; + }; + }; + + i2c2 { + /omit-if-no-ref/ + i2c2m0_xfer: i2c2m0-xfer { + rockchip,pins = + /* i2c2_scl_m0 */ + <0 RK_PA4 2 &pcfg_pull_none_smt>, + /* i2c2_sda_m0 */ + <0 RK_PA5 2 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2c2m1_xfer: i2c2m1-xfer { + rockchip,pins = + /* i2c2_scl_m1 */ + <1 RK_PA5 3 &pcfg_pull_none_smt>, + /* i2c2_sda_m1 */ + <1 RK_PA6 3 &pcfg_pull_none_smt>; + }; + }; + + i2c3 { + /omit-if-no-ref/ + i2c3m0_xfer: i2c3m0-xfer { + rockchip,pins = + /* i2c3_scl_m0 */ + <1 RK_PA0 2 &pcfg_pull_none_smt>, + /* i2c3_sda_m0 */ + <1 RK_PA1 2 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2c3m1_xfer: i2c3m1-xfer { + rockchip,pins = + /* i2c3_scl_m1 */ + <3 RK_PC1 5 &pcfg_pull_none_smt>, + /* i2c3_sda_m1 */ + <3 RK_PC3 5 &pcfg_pull_none_smt>; + }; + }; + + i2c4 { + /omit-if-no-ref/ + i2c4_xfer: i2c4-xfer { + rockchip,pins = + /* i2c4_scl */ + <2 RK_PA0 4 &pcfg_pull_none_smt>, + /* i2c4_sda */ + <2 RK_PA1 4 &pcfg_pull_none_smt>; + }; + }; + + i2c5 { + /omit-if-no-ref/ + i2c5m0_xfer: i2c5m0-xfer { + rockchip,pins = + /* i2c5_scl_m0 */ + <1 RK_PB2 3 &pcfg_pull_none_smt>, + /* i2c5_sda_m0 */ + <1 RK_PB3 3 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2c5m1_xfer: i2c5m1-xfer { + rockchip,pins = + /* i2c5_scl_m1 */ + <1 RK_PD2 3 &pcfg_pull_none_smt>, + /* i2c5_sda_m1 */ + <1 RK_PD3 3 &pcfg_pull_none_smt>; + }; + }; + + i2c6 { + /omit-if-no-ref/ + i2c6m0_xfer: i2c6m0-xfer { + rockchip,pins = + /* i2c6_scl_m0 */ + <3 RK_PB2 5 &pcfg_pull_none_smt>, + /* i2c6_sda_m0 */ + <3 RK_PB3 5 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2c6m1_xfer: i2c6m1-xfer { + rockchip,pins = + /* i2c6_scl_m1 */ + <1 RK_PD4 3 &pcfg_pull_none_smt>, + /* i2c6_sda_m1 */ + <1 RK_PD7 3 &pcfg_pull_none_smt>; + }; + }; + + i2c7 { + /omit-if-no-ref/ + i2c7_xfer: i2c7-xfer { + rockchip,pins = + /* i2c7_scl */ + <2 RK_PA5 4 &pcfg_pull_none_smt>, + /* i2c7_sda */ + <2 RK_PA6 4 &pcfg_pull_none_smt>; + }; + }; + + i2s0 { + /omit-if-no-ref/ + i2s0m0_lrck: i2s0m0-lrck { + rockchip,pins = + /* i2s0_lrck_m0 */ + <3 RK_PB6 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s0m0_mclk: i2s0m0-mclk { + rockchip,pins = + /* i2s0_mclk_m0 */ + <3 RK_PB4 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s0m0_sclk: i2s0m0-sclk { + rockchip,pins = + /* i2s0_sclk_m0 */ + <3 RK_PB5 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s0m0_sdi: i2s0m0-sdi { + rockchip,pins = + /* i2s0m0_sdi */ + <3 RK_PB7 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + i2s0m0_sdo: i2s0m0-sdo { + rockchip,pins = + /* i2s0m0_sdo */ + <3 RK_PC0 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s0m1_lrck: i2s0m1-lrck { + rockchip,pins = + /* i2s0_lrck_m1 */ + <1 RK_PB6 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s0m1_mclk: i2s0m1-mclk { + rockchip,pins = + /* i2s0_mclk_m1 */ + <1 RK_PB4 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s0m1_sclk: i2s0m1-sclk { + rockchip,pins = + /* i2s0_sclk_m1 */ + <1 RK_PB5 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s0m1_sdi: i2s0m1-sdi { + rockchip,pins = + /* i2s0m1_sdi */ + <1 RK_PB7 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + i2s0m1_sdo: i2s0m1-sdo { + rockchip,pins = + /* i2s0m1_sdo */ + <1 RK_PC0 1 &pcfg_pull_none>; + }; + }; + + i2s1 { + /omit-if-no-ref/ + i2s1_lrck: i2s1-lrck { + rockchip,pins = + /* i2s1_lrck */ + <4 RK_PA6 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s1_mclk: i2s1-mclk { + rockchip,pins = + /* i2s1_mclk */ + <4 RK_PA4 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s1_sclk: i2s1-sclk { + rockchip,pins = + /* i2s1_sclk */ + <4 RK_PA5 1 &pcfg_pull_none_smt>; + }; + + /omit-if-no-ref/ + i2s1_sdi0: i2s1-sdi0 { + rockchip,pins = + /* i2s1_sdi0 */ + <4 RK_PB4 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdi1: i2s1-sdi1 { + rockchip,pins = + /* i2s1_sdi1 */ + <4 RK_PB3 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdi2: i2s1-sdi2 { + rockchip,pins = + /* i2s1_sdi2 */ + <4 RK_PA3 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdi3: i2s1-sdi3 { + rockchip,pins = + /* i2s1_sdi3 */ + <4 RK_PA2 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdo0: i2s1-sdo0 { + rockchip,pins = + /* i2s1_sdo0 */ + <4 RK_PA7 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdo1: i2s1-sdo1 { + rockchip,pins = + /* i2s1_sdo1 */ + <4 RK_PB0 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdo2: i2s1-sdo2 { + rockchip,pins = + /* i2s1_sdo2 */ + <4 RK_PB1 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + i2s1_sdo3: i2s1-sdo3 { + rockchip,pins = + /* i2s1_sdo3 */ + <4 RK_PB2 1 &pcfg_pull_none>; + }; + }; + + jtag { + /omit-if-no-ref/ + jtagm0_pins: jtagm0-pins { + rockchip,pins = + /* jtag_cpu_tck_m0 */ + <2 RK_PA2 2 &pcfg_pull_none>, + /* jtag_cpu_tms_m0 */ + <2 RK_PA3 2 &pcfg_pull_none>, + /* jtag_mcu_tck_m0 */ + <2 RK_PA4 2 &pcfg_pull_none>, + /* jtag_mcu_tms_m0 */ + <2 RK_PA5 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + jtagm1_pins: jtagm1-pins { + rockchip,pins = + /* jtag_cpu_tck_m1 */ + <4 RK_PD0 2 &pcfg_pull_none>, + /* jtag_cpu_tms_m1 */ + <4 RK_PC7 2 &pcfg_pull_none>, + /* jtag_mcu_tck_m1 */ + <4 RK_PD0 3 &pcfg_pull_none>, + /* jtag_mcu_tms_m1 */ + <4 RK_PC7 3 &pcfg_pull_none>; + }; + }; + + pcie { + /omit-if-no-ref/ + pciem0_pins: pciem0-pins { + rockchip,pins = + /* pcie_clkreqn_m0 */ + <3 RK_PA6 5 &pcfg_pull_none>, + /* pcie_perstn_m0 */ + <3 RK_PB0 5 &pcfg_pull_none>, + /* pcie_waken_m0 */ + <3 RK_PA7 5 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + pciem1_pins: pciem1-pins { + rockchip,pins = + /* pcie_clkreqn_m1 */ + <1 RK_PA0 4 &pcfg_pull_none>, + /* pcie_perstn_m1 */ + <1 RK_PA2 4 &pcfg_pull_none>, + /* pcie_waken_m1 */ + <1 RK_PA1 4 &pcfg_pull_none>; + }; + }; + + pdm { + /omit-if-no-ref/ + pdm_clk0: pdm-clk0 { + rockchip,pins = + /* pdm_clk0 */ + <4 RK_PB5 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + pdm_clk1: pdm-clk1 { + rockchip,pins = + /* pdm_clk1 */ + <4 RK_PA4 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + pdm_sdi0: pdm-sdi0 { + rockchip,pins = + /* pdm_sdi0 */ + <4 RK_PB2 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + pdm_sdi1: pdm-sdi1 { + rockchip,pins = + /* pdm_sdi1 */ + <4 RK_PB1 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + pdm_sdi2: pdm-sdi2 { + rockchip,pins = + /* pdm_sdi2 */ + <4 RK_PB3 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + pdm_sdi3: pdm-sdi3 { + rockchip,pins = + /* pdm_sdi3 */ + <4 RK_PC1 3 &pcfg_pull_none>; + }; + }; + + pmu { + /omit-if-no-ref/ + pmu_pins: pmu-pins { + rockchip,pins = + /* pmu_debug */ + <4 RK_PA0 4 &pcfg_pull_none>; + }; + }; + + pwm0 { + /omit-if-no-ref/ + pwm0m0_pins: pwm0m0-pins { + rockchip,pins = + /* pwm0_m0 */ + <4 RK_PC3 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm0m1_pins: pwm0m1-pins { + rockchip,pins = + /* pwm0_m1 */ + <1 RK_PA2 5 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm1 { + /omit-if-no-ref/ + pwm1m0_pins: pwm1m0-pins { + rockchip,pins = + /* pwm1_m0 */ + <4 RK_PC4 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm1m1_pins: pwm1m1-pins { + rockchip,pins = + /* pwm1_m1 */ + <1 RK_PA3 4 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm2 { + /omit-if-no-ref/ + pwm2m0_pins: pwm2m0-pins { + rockchip,pins = + /* pwm2_m0 */ + <4 RK_PC5 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm2m1_pins: pwm2m1-pins { + rockchip,pins = + /* pwm2_m1 */ + <1 RK_PA7 2 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm3 { + /omit-if-no-ref/ + pwm3m0_pins: pwm3m0-pins { + rockchip,pins = + /* pwm3_m0 */ + <4 RK_PC6 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm3m1_pins: pwm3m1-pins { + rockchip,pins = + /* pwm3_m1 */ + <2 RK_PA4 3 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm4 { + /omit-if-no-ref/ + pwm4m0_pins: pwm4m0-pins { + rockchip,pins = + /* pwm4_m0 */ + <4 RK_PB7 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm4m1_pins: pwm4m1-pins { + rockchip,pins = + /* pwm4_m1 */ + <1 RK_PA4 2 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm5 { + /omit-if-no-ref/ + pwm5m0_pins: pwm5m0-pins { + rockchip,pins = + /* pwm5_m0 */ + <4 RK_PC0 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm5m1_pins: pwm5m1-pins { + rockchip,pins = + /* pwm5_m1 */ + <3 RK_PC3 1 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm6 { + /omit-if-no-ref/ + pwm6m0_pins: pwm6m0-pins { + rockchip,pins = + /* pwm6_m0 */ + <4 RK_PC1 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm6m1_pins: pwm6m1-pins { + rockchip,pins = + /* pwm6_m1 */ + <1 RK_PC3 3 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm6m2_pins: pwm6m2-pins { + rockchip,pins = + /* pwm6_m2 */ + <3 RK_PC1 1 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwm7 { + /omit-if-no-ref/ + pwm7m0_pins: pwm7m0-pins { + rockchip,pins = + /* pwm7_m0 */ + <4 RK_PC2 1 &pcfg_pull_none_drv_level_0>; + }; + + /omit-if-no-ref/ + pwm7m1_pins: pwm7m1-pins { + rockchip,pins = + /* pwm7_m1 */ + <1 RK_PC2 2 &pcfg_pull_none_drv_level_0>; + }; + }; + + pwr { + /omit-if-no-ref/ + pwr_pins: pwr-pins { + rockchip,pins = + /* pwr_ctrl0 */ + <4 RK_PC2 2 &pcfg_pull_none>, + /* pwr_ctrl1 */ + <4 RK_PB6 1 &pcfg_pull_none>; + }; + }; + + ref { + /omit-if-no-ref/ + refm0_pins: refm0-pins { + rockchip,pins = + /* ref_clk_out_m0 */ + <0 RK_PA1 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + refm1_pins: refm1-pins { + rockchip,pins = + /* ref_clk_out_m1 */ + <3 RK_PC3 6 &pcfg_pull_none>; + }; + }; + + rgmii { + /omit-if-no-ref/ + rgmii_miim: rgmii-miim { + rockchip,pins = + /* rgmii_mdc */ + <3 RK_PB6 2 &pcfg_pull_none_drv_level_2>, + /* rgmii_mdio */ + <3 RK_PB7 2 &pcfg_pull_none_drv_level_2>; + }; + + /omit-if-no-ref/ + rgmii_rx_bus2: rgmii-rx_bus2 { + rockchip,pins = + /* rgmii_rxd0 */ + <3 RK_PA3 2 &pcfg_pull_none>, + /* rgmii_rxd1 */ + <3 RK_PA2 2 &pcfg_pull_none>, + /* rgmii_rxdv_crs */ + <3 RK_PC2 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + rgmii_tx_bus2: rgmii-tx_bus2 { + rockchip,pins = + /* rgmii_txd0 */ + <3 RK_PA1 2 &pcfg_pull_none_drv_level_2>, + /* rgmii_txd1 */ + <3 RK_PA0 2 &pcfg_pull_none_drv_level_2>, + /* rgmii_txen */ + <3 RK_PC0 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + rgmii_rgmii_clk: rgmii-rgmii_clk { + rockchip,pins = + /* rgmii_rxclk */ + <3 RK_PA5 2 &pcfg_pull_none>, + /* rgmii_txclk */ + <3 RK_PA4 2 &pcfg_pull_none_drv_level_2>; + }; + + /omit-if-no-ref/ + rgmii_rgmii_bus: rgmii-rgmii_bus { + rockchip,pins = + /* rgmii_rxd2 */ + <3 RK_PA7 2 &pcfg_pull_none>, + /* rgmii_rxd3 */ + <3 RK_PA6 2 &pcfg_pull_none>, + /* rgmii_txd2 */ + <3 RK_PB1 2 &pcfg_pull_none_drv_level_2>, + /* rgmii_txd3 */ + <3 RK_PB0 2 &pcfg_pull_none_drv_level_2>; + }; + + /omit-if-no-ref/ + rgmii_clk: rgmii-clk { + rockchip,pins = + /* rgmii_clk */ + <3 RK_PB4 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + rgmii_txer: rgmii-txer { + rockchip,pins = + /* rgmii_txer */ + <3 RK_PC1 2 &pcfg_pull_none>; + }; + }; + + scr { + /omit-if-no-ref/ + scrm0_pins: scrm0-pins { + rockchip,pins = + /* scr_clk_m0 */ + <1 RK_PA2 3 &pcfg_pull_none>, + /* scr_data_m0 */ + <1 RK_PA1 3 &pcfg_pull_none>, + /* scr_detn_m0 */ + <1 RK_PA0 3 &pcfg_pull_none>, + /* scr_rstn_m0 */ + <1 RK_PA3 3 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + scrm1_pins: scrm1-pins { + rockchip,pins = + /* scr_clk_m1 */ + <2 RK_PA5 3 &pcfg_pull_none>, + /* scr_data_m1 */ + <2 RK_PA3 4 &pcfg_pull_none>, + /* scr_detn_m1 */ + <2 RK_PA6 3 &pcfg_pull_none>, + /* scr_rstn_m1 */ + <2 RK_PA4 4 &pcfg_pull_none>; + }; + }; + + sdio0 { + /omit-if-no-ref/ + sdio0_bus4: sdio0-bus4 { + rockchip,pins = + /* sdio0_d0 */ + <1 RK_PA0 1 &pcfg_pull_up_drv_level_2>, + /* sdio0_d1 */ + <1 RK_PA1 1 &pcfg_pull_up_drv_level_2>, + /* sdio0_d2 */ + <1 RK_PA2 1 &pcfg_pull_up_drv_level_2>, + /* sdio0_d3 */ + <1 RK_PA3 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdio0_clk: sdio0-clk { + rockchip,pins = + /* sdio0_clk */ + <1 RK_PA5 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdio0_cmd: sdio0-cmd { + rockchip,pins = + /* sdio0_cmd */ + <1 RK_PA4 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdio0_det: sdio0-det { + rockchip,pins = + /* sdio0_det */ + <1 RK_PA6 1 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + sdio0_pwren: sdio0-pwren { + rockchip,pins = + /* sdio0_pwren */ + <1 RK_PA7 1 &pcfg_pull_none>; + }; + }; + + sdio1 { + /omit-if-no-ref/ + sdio1_bus4: sdio1-bus4 { + rockchip,pins = + /* sdio1_d0 */ + <3 RK_PA6 1 &pcfg_pull_up_drv_level_2>, + /* sdio1_d1 */ + <3 RK_PA7 1 &pcfg_pull_up_drv_level_2>, + /* sdio1_d2 */ + <3 RK_PB0 1 &pcfg_pull_up_drv_level_2>, + /* sdio1_d3 */ + <3 RK_PB1 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdio1_clk: sdio1-clk { + rockchip,pins = + /* sdio1_clk */ + <3 RK_PA4 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdio1_cmd: sdio1-cmd { + rockchip,pins = + /* sdio1_cmd */ + <3 RK_PA5 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdio1_det: sdio1-det { + rockchip,pins = + /* sdio1_det */ + <3 RK_PB3 1 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + sdio1_pwren: sdio1-pwren { + rockchip,pins = + /* sdio1_pwren */ + <3 RK_PB2 1 &pcfg_pull_none>; + }; + }; + + sdmmc { + /omit-if-no-ref/ + sdmmc_bus4: sdmmc-bus4 { + rockchip,pins = + /* sdmmc_d0 */ + <2 RK_PA0 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc_d1 */ + <2 RK_PA1 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc_d2 */ + <2 RK_PA2 1 &pcfg_pull_up_drv_level_2>, + /* sdmmc_d3 */ + <2 RK_PA3 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdmmc_clk: sdmmc-clk { + rockchip,pins = + /* sdmmc_clk */ + <2 RK_PA5 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdmmc_cmd: sdmmc-cmd { + rockchip,pins = + /* sdmmc_cmd */ + <2 RK_PA4 1 &pcfg_pull_up_drv_level_2>; + }; + + /omit-if-no-ref/ + sdmmc_det: sdmmc-det { + rockchip,pins = + /* sdmmc_detn */ + <2 RK_PA6 1 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + sdmmc_pwren: sdmmc-pwren { + rockchip,pins = + /* sdmmc_pwren */ + <4 RK_PA1 1 &pcfg_pull_none>; + }; + }; + + spdif { + /omit-if-no-ref/ + spdifm0_pins: spdifm0-pins { + rockchip,pins = + /* spdif_tx_m0 */ + <4 RK_PA0 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + spdifm1_pins: spdifm1-pins { + rockchip,pins = + /* spdif_tx_m1 */ + <1 RK_PC3 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + spdifm2_pins: spdifm2-pins { + rockchip,pins = + /* spdif_tx_m2 */ + <3 RK_PC3 2 &pcfg_pull_none>; + }; + }; + + spi0 { + /omit-if-no-ref/ + spi0_pins: spi0-pins { + rockchip,pins = + /* spi0_clk */ + <4 RK_PB4 2 &pcfg_pull_none_drv_level_2>, + /* spi0_miso */ + <4 RK_PB3 2 &pcfg_pull_none_drv_level_2>, + /* spi0_mosi */ + <4 RK_PB2 2 &pcfg_pull_none_drv_level_2>; + }; + + /omit-if-no-ref/ + spi0_csn0: spi0-csn0 { + rockchip,pins = + /* spi0_csn0 */ + <4 RK_PB6 2 &pcfg_pull_none_drv_level_2>; + }; + /omit-if-no-ref/ + spi0_csn1: spi0-csn1 { + rockchip,pins = + /* spi0_csn1 */ + <4 RK_PC1 2 &pcfg_pull_none_drv_level_2>; + }; + }; + + spi1 { + /omit-if-no-ref/ + spi1_pins: spi1-pins { + rockchip,pins = + /* spi1_clk */ + <1 RK_PB6 2 &pcfg_pull_none_drv_level_2>, + /* spi1_miso */ + <1 RK_PC0 2 &pcfg_pull_none_drv_level_2>, + /* spi1_mosi */ + <1 RK_PB7 2 &pcfg_pull_none_drv_level_2>; + }; + + /omit-if-no-ref/ + spi1_csn0: spi1-csn0 { + rockchip,pins = + /* spi1_csn0 */ + <1 RK_PC1 1 &pcfg_pull_none_drv_level_2>; + }; + /omit-if-no-ref/ + spi1_csn1: spi1-csn1 { + rockchip,pins = + /* spi1_csn1 */ + <1 RK_PC2 1 &pcfg_pull_none_drv_level_2>; + }; + }; + + tsi0 { + /omit-if-no-ref/ + tsi0_pins: tsi0-pins { + rockchip,pins = + /* tsi0_clkin */ + <3 RK_PB2 3 &pcfg_pull_none>, + /* tsi0_d0 */ + <3 RK_PB1 3 &pcfg_pull_none>, + /* tsi0_d1 */ + <3 RK_PB5 3 &pcfg_pull_none>, + /* tsi0_d2 */ + <3 RK_PB6 3 &pcfg_pull_none>, + /* tsi0_d3 */ + <3 RK_PB7 3 &pcfg_pull_none>, + /* tsi0_d4 */ + <3 RK_PA3 3 &pcfg_pull_none>, + /* tsi0_d5 */ + <3 RK_PA2 3 &pcfg_pull_none>, + /* tsi0_d6 */ + <3 RK_PA1 3 &pcfg_pull_none>, + /* tsi0_d7 */ + <3 RK_PA0 3 &pcfg_pull_none>, + /* tsi0_fail */ + <3 RK_PC0 3 &pcfg_pull_none>, + /* tsi0_sync */ + <3 RK_PB4 3 &pcfg_pull_none>, + /* tsi0_valid */ + <3 RK_PB3 3 &pcfg_pull_none>; + }; + }; + + tsi1 { + /omit-if-no-ref/ + tsi1_pins: tsi1-pins { + rockchip,pins = + /* tsi1_clkin */ + <3 RK_PA5 3 &pcfg_pull_none>, + /* tsi1_d0 */ + <3 RK_PA4 3 &pcfg_pull_none>, + /* tsi1_sync */ + <3 RK_PA7 3 &pcfg_pull_none>, + /* tsi1_valid */ + <3 RK_PA6 3 &pcfg_pull_none>; + }; + }; + + uart0 { + /omit-if-no-ref/ + uart0m0_xfer: uart0m0-xfer { + rockchip,pins = + /* uart0_rx_m0 */ + <4 RK_PC7 1 &pcfg_pull_up>, + /* uart0_tx_m0 */ + <4 RK_PD0 1 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart0m1_xfer: uart0m1-xfer { + rockchip,pins = + /* uart0_rx_m1 */ + <2 RK_PA0 2 &pcfg_pull_up>, + /* uart0_tx_m1 */ + <2 RK_PA1 2 &pcfg_pull_up>; + }; + }; + + uart1 { + /omit-if-no-ref/ + uart1m0_xfer: uart1m0-xfer { + rockchip,pins = + /* uart1_rx_m0 */ + <4 RK_PA7 2 &pcfg_pull_up>, + /* uart1_tx_m0 */ + <4 RK_PA6 2 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart1m1_xfer: uart1m1-xfer { + rockchip,pins = + /* uart1_rx_m1 */ + <4 RK_PC6 2 &pcfg_pull_up>, + /* uart1_tx_m1 */ + <4 RK_PC5 2 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart1_ctsn: uart1-ctsn { + rockchip,pins = + /* uart1_ctsn */ + <4 RK_PA4 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart1_rtsn: uart1-rtsn { + rockchip,pins = + /* uart1_rtsn */ + <4 RK_PA5 2 &pcfg_pull_none>; + }; + }; + + uart2 { + /omit-if-no-ref/ + uart2m0_xfer: uart2m0-xfer { + rockchip,pins = + /* uart2_rx_m0 */ + <3 RK_PA0 1 &pcfg_pull_up>, + /* uart2_tx_m0 */ + <3 RK_PA1 1 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart2m0_ctsn: uart2m0-ctsn { + rockchip,pins = + /* uart2m0_ctsn */ + <3 RK_PA3 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart2m0_rtsn: uart2m0-rtsn { + rockchip,pins = + /* uart2m0_rtsn */ + <3 RK_PA2 1 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + uart2m1_xfer: uart2m1-xfer { + rockchip,pins = + /* uart2_rx_m1 */ + <1 RK_PB0 1 &pcfg_pull_up>, + /* uart2_tx_m1 */ + <1 RK_PB1 1 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart2m1_ctsn: uart2m1-ctsn { + rockchip,pins = + /* uart2m1_ctsn */ + <1 RK_PB3 1 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart2m1_rtsn: uart2m1-rtsn { + rockchip,pins = + /* uart2m1_rtsn */ + <1 RK_PB2 1 &pcfg_pull_none>; + }; + }; + + uart3 { + /omit-if-no-ref/ + uart3m0_xfer: uart3m0-xfer { + rockchip,pins = + /* uart3_rx_m0 */ + <4 RK_PB0 2 &pcfg_pull_up>, + /* uart3_tx_m0 */ + <4 RK_PB1 2 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart3m1_xfer: uart3m1-xfer { + rockchip,pins = + /* uart3_rx_m1 */ + <4 RK_PB7 3 &pcfg_pull_up>, + /* uart3_tx_m1 */ + <4 RK_PC0 3 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart3_ctsn: uart3-ctsn { + rockchip,pins = + /* uart3_ctsn */ + <4 RK_PA3 3 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart3_rtsn: uart3-rtsn { + rockchip,pins = + /* uart3_rtsn */ + <4 RK_PA2 3 &pcfg_pull_none>; + }; + }; + + uart4 { + /omit-if-no-ref/ + uart4_xfer: uart4-xfer { + rockchip,pins = + /* uart4_rx */ + <2 RK_PA2 3 &pcfg_pull_up>, + /* uart4_tx */ + <2 RK_PA3 3 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart4_ctsn: uart4-ctsn { + rockchip,pins = + /* uart4_ctsn */ + <2 RK_PA1 3 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart4_rtsn: uart4-rtsn { + rockchip,pins = + /* uart4_rtsn */ + <2 RK_PA0 3 &pcfg_pull_none>; + }; + }; + + uart5 { + /omit-if-no-ref/ + uart5m0_xfer: uart5m0-xfer { + rockchip,pins = + /* uart5_rx_m0 */ + <1 RK_PA2 2 &pcfg_pull_up>, + /* uart5_tx_m0 */ + <1 RK_PA3 2 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart5m0_ctsn: uart5m0-ctsn { + rockchip,pins = + /* uart5m0_ctsn */ + <1 RK_PA6 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart5m0_rtsn: uart5m0-rtsn { + rockchip,pins = + /* uart5m0_rtsn */ + <1 RK_PA5 2 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + uart5m1_xfer: uart5m1-xfer { + rockchip,pins = + /* uart5_rx_m1 */ + <1 RK_PD4 2 &pcfg_pull_up>, + /* uart5_tx_m1 */ + <1 RK_PD7 2 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart5m1_ctsn: uart5m1-ctsn { + rockchip,pins = + /* uart5m1_ctsn */ + <1 RK_PD3 2 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart5m1_rtsn: uart5m1-rtsn { + rockchip,pins = + /* uart5m1_rtsn */ + <1 RK_PD2 2 &pcfg_pull_none>; + }; + }; + + uart6 { + /omit-if-no-ref/ + uart6m0_xfer: uart6m0-xfer { + rockchip,pins = + /* uart6_rx_m0 */ + <3 RK_PA7 4 &pcfg_pull_up>, + /* uart6_tx_m0 */ + <3 RK_PA6 4 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart6m1_xfer: uart6m1-xfer { + rockchip,pins = + /* uart6_rx_m1 */ + <3 RK_PC3 4 &pcfg_pull_up>, + /* uart6_tx_m1 */ + <3 RK_PC1 4 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart6_ctsn: uart6-ctsn { + rockchip,pins = + /* uart6_ctsn */ + <3 RK_PA4 4 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart6_rtsn: uart6-rtsn { + rockchip,pins = + /* uart6_rtsn */ + <3 RK_PA5 4 &pcfg_pull_none>; + }; + }; + + uart7 { + /omit-if-no-ref/ + uart7m0_xfer: uart7m0-xfer { + rockchip,pins = + /* uart7_rx_m0 */ + <3 RK_PB3 4 &pcfg_pull_up>, + /* uart7_tx_m0 */ + <3 RK_PB2 4 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart7m0_ctsn: uart7m0-ctsn { + rockchip,pins = + /* uart7m0_ctsn */ + <3 RK_PB0 4 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart7m0_rtsn: uart7m0-rtsn { + rockchip,pins = + /* uart7m0_rtsn */ + <3 RK_PB1 4 &pcfg_pull_none>; + }; + + /omit-if-no-ref/ + uart7m1_xfer: uart7m1-xfer { + rockchip,pins = + /* uart7_rx_m1 */ + <1 RK_PB3 4 &pcfg_pull_up>, + /* uart7_tx_m1 */ + <1 RK_PB2 4 &pcfg_pull_up>; + }; + + /omit-if-no-ref/ + uart7m1_ctsn: uart7m1-ctsn { + rockchip,pins = + /* uart7m1_ctsn */ + <1 RK_PB0 4 &pcfg_pull_none>; + }; + /omit-if-no-ref/ + uart7m1_rtsn: uart7m1-rtsn { + rockchip,pins = + /* uart7m1_rtsn */ + <1 RK_PB1 4 &pcfg_pull_none>; + }; + }; +}; diff --git a/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528.dtsi b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528.dtsi new file mode 100644 index 000000000..c43d379b7 --- /dev/null +++ b/target/linux/rockchip/files/arch/arm64/boot/dts/rockchip/rk3528.dtsi @@ -0,0 +1,1439 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/ { + interrupt-parent = <&gic>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + serial5 = &uart5; + serial6 = &uart6; + serial7 = &uart7; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &sfc; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + }; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x0>; + clocks = <&scmi_clk SCMI_CLK_CPU>; + assigned-clocks = <&scmi_clk SCMI_CLK_CPU>; + assigned-clock-rates = <1200000000>; + dynamic-power-coefficient = <147>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu1: cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x1>; + clocks = <&scmi_clk SCMI_CLK_CPU>; + dynamic-power-coefficient = <147>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu2: cpu@2 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x2>; + clocks = <&scmi_clk SCMI_CLK_CPU>; + dynamic-power-coefficient = <147>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + + cpu3: cpu@3 { + device_type = "cpu"; + compatible = "arm,cortex-a53"; + reg = <0x0 0x3>; + clocks = <&scmi_clk SCMI_CLK_CPU>; + dynamic-power-coefficient = <147>; + #cooling-cells = <2>; + enable-method = "psci"; + operating-points-v2 = <&cpu0_opp_table>; + }; + }; + + cpu0_opp_table: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-408000000 { + opp-hz = /bits/ 64 <408000000>; + opp-microvolt = <825000 825000 1100000>; + clock-latency-ns = <40000>; + opp-suspend; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <825000 825000 1100000>; + clock-latency-ns = <40000>; + }; + + opp-816000000 { + opp-hz = /bits/ 64 <816000000>; + opp-microvolt = <825000 825000 1100000>; + clock-latency-ns = <40000>; + }; + + opp-1008000000 { + opp-hz = /bits/ 64 <1008000000>; + opp-microvolt = <825000 825000 1100000>; + clock-latency-ns = <40000>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <825000 825000 1100000>; + clock-latency-ns = <40000>; + }; + + opp-1416000000 { + opp-hz = /bits/ 64 <1416000000>; + opp-microvolt = <962500 962500 1100000>; + clock-latency-ns = <40000>; + }; + + opp-1608000000 { + opp-hz = /bits/ 64 <1608000000>; + opp-microvolt = <1012500 1012500 1100000>; + clock-latency-ns = <40000>; + }; + + opp-1800000000 { + opp-hz = /bits/ 64 <1800000000>; + opp-microvolt = <1062500 1062500 1100000>; + clock-latency-ns = <40000>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <2016000000>; + opp-microvolt = <1100000 1100000 1100000>; + clock-latency-ns = <40000>; + }; + }; + + arm-pmu { + compatible = "arm,cortex-a53-pmu"; + interrupts = , + , + , + ; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + + firmware { + scmi: scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82000010>; + shmem = <&scmi_shmem>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + }; + }; + + gpu_opp_table: gpu-opp-table { + compatible = "operating-points-v2"; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <875000 875000 1000000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <875000 875000 1000000>; + }; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <875000 875000 1000000>; + }; + + opp-700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = <900000 900000 1000000>; + }; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <950000 950000 1000000>; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + }; + + xin24m: xin24m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "xin24m"; + }; + + sram@10f000 { + compatible = "mmio-sram"; + reg = <0x0 0x0010f000 0x0 0x100>; + ranges = <0 0x0 0x0010f000 0x100>; + #address-cells = <1>; + #size-cells = <1>; + + scmi_shmem: sram@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x100>; + }; + }; + + pcie2x1: pcie@fe4f0000 { + compatible = "rockchip,rk3528-pcie", "snps,dw-pcie"; + reg = <0x0 0xfe000000 0x0 0x400000>, + <0x0 0xfe4f0000 0x0 0x010000>, + <0x0 0xfc000000 0x0 0x100000>; + reg-names = "pcie-dbi", "pcie-apb", "config"; + interrupts = , + , + , + , + , + ; + interrupt-names = "msi", "pmc", "sys", "legacy", "msg", "err"; + bus-range = <0x0 0xff>; + clocks = <&cru ACLK_PCIE>, <&cru HCLK_PCIE_SLV>, + <&cru HCLK_PCIE_DBI>, <&cru PCLK_CRU_PCIE>, + <&cru CLK_PCIE_AUX>, <&cru PCLK_PCIE>, + <&cru PCLK_PCIE_PHY>; + clock-names = "aclk", "hclk_slv", + "hclk_dbi", "pclk_cru", + "aux", "pclk", + "pipe"; + device_type = "pci"; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie_intc 0>, + <0 0 0 2 &pcie_intc 1>, + <0 0 0 3 &pcie_intc 2>, + <0 0 0 4 &pcie_intc 3>; + linux,pci-domain = <0>; + max-link-speed = <2>; + num-ib-windows = <8>; + num-ob-windows = <8>; + num-viewport = <4>; + num-lanes = <1>; + phys = <&combphy PHY_TYPE_PCIE>; + phy-names = "pcie-phy"; + ranges = <0x81000000 0x0 0xfc100000 0x0 0xfc100000 0x0 0x00100000 + 0x82000000 0x0 0xfc200000 0x0 0xfc200000 0x0 0x01e00000 + 0xc3000000 0x1 0x00000000 0x1 0x00000000 0x0 0x40000000>; + resets = <&cru SRST_RESETN_PCIE_POWER_UP>, <&cru SRST_PRESETN_PCIE>, + <&cru SRST_PRESETN_CRU_PCIE>; + reset-names = "pwr", "periph", "preset_cru"; + #address-cells = <3>; + #size-cells = <2>; + status = "disabled"; + + pcie_intc: legacy-interrupt-controller { + #address-cells = <0>; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-parent = <&gic>; + interrupts = ; + }; + }; + + usb_host0_xhci: usb@fe500000 { + compatible = "rockchip,rk3528-dwc3", "snps,dwc3"; + reg = <0x0 0xfe500000 0x0 0x400000>; + interrupts = ; + clocks = <&cru CLK_REF_USB3OTG>, <&cru CLK_SUSPEND_USB3OTG>, + <&cru ACLK_USB3OTG>; + clock-names = "ref_clk", "suspend_clk", + "bus_clk"; + dr_mode = "otg"; + phys = <&usb2phy0_otg>, <&combphy PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; + phy_type = "utmi_wide"; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,dis-u2-freeclk-exists-quirk; + snps,dis_enblslpm_quirk; + snps,dis_u2_susphy_quirk; + resets = <&cru SRST_ARESETN_USB3OTG>; + reset-names = "usb3-otg"; + status = "disabled"; + }; + + gic: interrupt-controller@fed01000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0xfed01000 0 0x1000>, + <0x0 0xfed02000 0 0x2000>, + <0x0 0xfed04000 0 0x2000>, + <0x0 0xfed06000 0 0x2000>; + interrupts = ; + }; + + usb_host0_ehci: usb@ff100000 { + compatible = "generic-ehci"; + reg = <0x0 0xff100000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_USBHOST>, + <&cru HCLK_USBHOST_ARB>, + <&usb2phy>; + clock-names = "usbhost", "arbiter", "utmi"; + phys = <&usb2phy0_host>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + usb_host0_ohci: usb@ff140000 { + compatible = "generic-ohci"; + reg = <0x0 0xff140000 0x0 0x40000>; + interrupts = ; + clocks = <&cru HCLK_USBHOST>, + <&cru HCLK_USBHOST_ARB>, + <&usb2phy>; + clock-names = "usbhost", "arbiter", "utmi"; + phys = <&usb2phy0_host>; + phy-names = "usb2-phy"; + status = "disabled"; + }; + + qos_crypto_a: qos@ff200000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200000 0x0 0x20>; + }; + + qos_crypto_p: qos@ff200080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200080 0x0 0x20>; + }; + + qos_dcf: qos@ff200100 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200100 0x0 0x20>; + }; + + qos_dft2apb: qos@ff200200 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200200 0x0 0x20>; + }; + + qos_dma2ddr: qos@ff200280 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200280 0x0 0x20>; + }; + + qos_dmac: qos@ff200300 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200300 0x0 0x20>; + }; + + qos_keyreader: qos@ff200380 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200380 0x0 0x20>; + }; + + qos_cpu: qos@ff210000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff210000 0x0 0x20>; + }; + + qos_debug: qos@ff210080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff210080 0x0 0x20>; + }; + + qos_gpu_m0: qos@ff220000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff220000 0x0 0x20>; + }; + + qos_gpu_m1: qos@ff220080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff220080 0x0 0x20>; + }; + + qos_pmu_mcu: qos@ff240000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff240000 0x0 0x20>; + }; + + qos_rkvdec: qos@ff250000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff250000 0x0 0x20>; + }; + + qos_rkvenc: qos@ff260000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff260000 0x0 0x20>; + }; + + qos_gmac0: qos@ff270000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270000 0x0 0x20>; + }; + + qos_hdcp: qos@ff270080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270080 0x0 0x20>; + }; + + qos_jpegdec: qos@ff270100 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270100 0x0 0x20>; + }; + + qos_rga2_m0ro: qos@ff270200 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270200 0x0 0x20>; + }; + + qos_rga2_m0wo: qos@ff270280 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270280 0x0 0x20>; + }; + + qos_sdmmc0: qos@ff270300 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270300 0x0 0x20>; + }; + + qos_usb2host: qos@ff270380 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270380 0x0 0x20>; + }; + + qos_vdpp: qos@ff270480 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270480 0x0 0x20>; + }; + + qos_vop: qos@ff270500 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270500 0x0 0x20>; + }; + + qos_emmc: qos@ff280000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280000 0x0 0x20>; + }; + + qos_fspi: qos@ff280080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280080 0x0 0x20>; + }; + + qos_gmac1: qos@ff280100 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280100 0x0 0x20>; + }; + + qos_pcie: qos@ff280180 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280180 0x0 0x20>; + }; + + qos_sdio0: qos@ff280200 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280200 0x0 0x20>; + }; + + qos_sdio1: qos@ff280280 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280280 0x0 0x20>; + }; + + qos_tsp: qos@ff280300 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280300 0x0 0x20>; + }; + + qos_usb3otg: qos@ff280380 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280380 0x0 0x20>; + }; + + qos_vpu: qos@ff280400 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280400 0x0 0x20>; + }; + + grf: syscon@ff300000 { + compatible = "rockchip,rk3528-grf", "syscon", "simple-mfd"; + reg = <0x0 0xff300000 0x0 0x90000>; + + grf_cru: grf-clock-controller { + compatible = "rockchip,rk3528-grf-cru"; + #clock-cells = <1>; + }; + + reboot-mode { + compatible = "syscon-reboot-mode"; + offset = <0x70200>; + mode-bootloader = ; + mode-fastboot = ; + mode-loader = ; + mode-normal = ; + mode-recovery = ; + }; + }; + + cru: clock-controller@ff4a0000 { + compatible = "rockchip,rk3528-cru"; + reg = <0x0 0xff4a0000 0x0 0x30000>; + rockchip,grf = <&grf>; + #clock-cells = <1>; + #reset-cells = <1>; + assigned-clocks = + <&cru XIN_OSC0_DIV>, + <&cru PLL_GPLL>, + <&cru PLL_PPLL>, + <&cru PLL_CPLL>, + <&cru CLK_MATRIX_250M_SRC>, + <&cru CLK_MATRIX_500M_SRC>, + <&cru CLK_MATRIX_50M_SRC>, + <&cru CLK_MATRIX_100M_SRC>, + <&cru CLK_MATRIX_150M_SRC>, + <&cru CLK_MATRIX_200M_SRC>, + <&cru CLK_MATRIX_300M_SRC>, + <&cru CLK_MATRIX_339M_SRC>, + <&cru CLK_MATRIX_400M_SRC>, + <&cru CLK_MATRIX_600M_SRC>, + <&cru CLK_PPLL_50M_MATRIX>, + <&cru CLK_PPLL_100M_MATRIX>, + <&cru CLK_PPLL_125M_MATRIX>, + <&cru ACLK_BUS_VOPGL_ROOT>, + <&cru ACLK_VO_ROOT>, + <&cru ACLK_VPU_ROOT>, + <&cru ACLK_VPU_L_ROOT>; + assigned-clock-rates = + <32768>, + <1188000000>, + <1000000000>, + <996000000>, + <250000000>, + <500000000>, + <50000000>, + <100000000>, + <150000000>, + <200000000>, + <300000000>, + <340000000>, + <400000000>, + <600000000>, + <50000000>, + <100000000>, + <125000000>, + <500000000>, + <340000000>, + <300000000>, + <200000000>; + }; + + ioc_grf: syscon@ff540000 { + compatible = "rockchip,rk3528-ioc-grf", "syscon"; + reg = <0x0 0xff540000 0x0 0x40000>; + }; + + pmu: power-management@ff600000 { + compatible = "rockchip,rk3528-pmu", "syscon", "simple-mfd"; + reg = <0x0 0xff600000 0x0 0x2000>; + + power: power-controller { + compatible = "rockchip,rk3528-power-controller"; + #power-domain-cells = <1>; + #address-cells = <1>; + #size-cells = <0>; + + pd_gpu@RK3528_PD_GPU { + reg = ; + clocks = <&cru ACLK_GPU_MALI>, + <&cru PCLK_GPU_ROOT>; + pm_qos = <&qos_gpu_m0>, + <&qos_gpu_m1>; + }; + pd_rkvdec@RK3528_PD_RKVDEC { + reg = ; + }; + pd_rkvenc@RK3528_PD_RKVENC { + reg = ; + }; + pd_vo@RK3528_PD_VO { + reg = ; + }; + pd_vpu@RK3528_PD_VPU { + reg = ; + }; + }; + }; + + mailbox: mailbox@ff630000 { + compatible = "rockchip,rk3528-mailbox", + "rockchip,rk3368-mailbox"; + reg = <0x0 0xff630000 0x0 0x200>; + interrupts = ; + clocks = <&cru PCLK_PMU_MAILBOX>; + clock-names = "pclk_mailbox"; + #mbox-cells = <1>; + status = "disabled"; + }; + + gpu: gpu@ff700000 { + compatible = "rockchip,rk3528-mali", "arm,mali-450"; + reg = <0x0 0xff700000 0x0 0x40000>; + interrupts = , + , + , + , + , + , + ; + interrupt-names = "gp", + "gpmmu", + "pp", + "pp0", + "ppmmu0", + "pp1", + "ppmmu1"; + clocks = <&cru ACLK_GPU_MALI>, <&cru PCLK_GPU_ROOT>; + clock-names = "bus", "core"; + assigned-clocks = <&scmi_clk SCMI_CLK_GPU>; + assigned-clock-rates = <300000000>; + power-domains = <&power RK3528_PD_GPU>; + operating-points-v2 = <&gpu_opp_table>; + rockchip,grf = <&grf>; + #cooling-cells = <2>; + status = "disabled"; + }; + + spi0: spi@ff9c0000 { + compatible = "rockchip,rk3528-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff9c0000 0x0 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru CLK_SPI0>, <&cru PCLK_SPI0>, <&cru SCLK_IN_SPI0>; + clock-names = "spiclk", "apb_pclk", "sclk_in"; + dmas = <&dmac 25>, <&dmac 24>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_csn0 &spi0_csn1 &spi0_pins>; + status = "disabled"; + }; + + spi1: spi@ff9d0000 { + compatible = "rockchip,rk3528-spi", "rockchip,rk3066-spi"; + reg = <0x0 0xff9d0000 0x0 0x1000>; + interrupts = ; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&cru CLK_SPI1>, <&cru PCLK_SPI1>, <&cru SCLK_IN_SPI1>; + clock-names = "spiclk", "apb_pclk", "sclk_in"; + dmas = <&dmac 31>, <&dmac 30>; + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_csn0 &spi1_csn1 &spi1_pins>; + status = "disabled"; + }; + + uart0: serial@ff9f0000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff9f0000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 9>, <&dmac 8>; + status = "disabled"; + }; + + uart1: serial@ff9f8000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xff9f8000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 11>, <&dmac 10>; + status = "disabled"; + }; + + uart2: serial@ffa00000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xffa00000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 13>, <&dmac 12>; + status = "disabled"; + }; + + uart3: serial@ffa08000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xffa08000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 15>, <&dmac 14>; + status = "disabled"; + }; + + uart4: serial@ffa10000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xffa10000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 17>, <&dmac 16>; + status = "disabled"; + }; + + uart5: serial@ffa18000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xffa18000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 19>, <&dmac 18>; + status = "disabled"; + }; + + uart6: serial@ffa20000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xffa20000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 21>, <&dmac 20>; + status = "disabled"; + }; + + uart7: serial@ffa28000 { + compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + reg = <0x0 0xffa28000 0x0 0x100>; + interrupts = ; + clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>; + clock-names = "baudclk", "apb_pclk"; + reg-shift = <2>; + reg-io-width = <4>; + dmas = <&dmac 23>, <&dmac 22>; + status = "disabled"; + }; + + i2c0: i2c@ffa50000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa50000 0x0 0x1000>; + clocks = <&cru CLK_I2C0>, <&cru PCLK_I2C0>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0m0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@ffa58000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa58000 0x0 0x1000>; + clocks = <&cru CLK_I2C1>, <&cru PCLK_I2C1>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1m0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@ffa60000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa60000 0x0 0x1000>; + clocks = <&cru CLK_I2C2>, <&cru PCLK_I2C2>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2m0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@ffa68000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa68000 0x0 0x1000>; + clocks = <&cru CLK_I2C3>, <&cru PCLK_I2C3>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c3m0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@ffa70000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa70000 0x0 0x1000>; + clocks = <&cru CLK_I2C4>, <&cru PCLK_I2C4>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c4_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@ffa78000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa78000 0x0 0x1000>; + clocks = <&cru CLK_I2C5>, <&cru PCLK_I2C5>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c5m0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@ffa80000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa80000 0x0 0x1000>; + clocks = <&cru CLK_I2C6>, <&cru PCLK_I2C6>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m0_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c7: i2c@ffa88000 { + compatible = "rockchip,rk3528-i2c", "rockchip,rk3399-i2c"; + reg = <0x0 0xffa88000 0x0 0x1000>; + clocks = <&cru CLK_I2C7>, <&cru PCLK_I2C7>; + clock-names = "i2c", "pclk"; + interrupts = ; + pinctrl-names = "default"; + pinctrl-0 = <&i2c7_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + pwm0: pwm@ffa90000 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa90000 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm0m0_pins>; + clocks = <&cru CLK_PWM0>, <&cru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm1: pwm@ffa90010 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa90010 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm1m0_pins>; + clocks = <&cru CLK_PWM0>, <&cru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm2: pwm@ffa90020 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa90020 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm2m0_pins>; + clocks = <&cru CLK_PWM0>, <&cru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm3: pwm@ffa90030 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa90030 0x0 0x10>; + interrupts = , + ; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm3m0_pins>; + clocks = <&cru CLK_PWM0>, <&cru PCLK_PWM0>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm4: pwm@ffa98000 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa98000 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm4m0_pins>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm5: pwm@ffa98010 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa98010 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm5m0_pins>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm6: pwm@ffa98020 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa98020 0x0 0x10>; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm6m0_pins>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + pwm7: pwm@ffa98030 { + compatible = "rockchip,rk3528-pwm", "rockchip,rk3328-pwm"; + reg = <0x0 0xffa98030 0x0 0x10>; + interrupts = , + ; + #pwm-cells = <3>; + pinctrl-names = "active"; + pinctrl-0 = <&pwm7m0_pins>; + clocks = <&cru CLK_PWM1>, <&cru PCLK_PWM1>; + clock-names = "pwm", "pclk"; + status = "disabled"; + }; + + wdt: watchdog@ffac0000 { + compatible = "rockchip,rk3528-wdt", "snps,dw-wdt"; + reg = <0x0 0xffac0000 0x0 0x100>; + clocks = <&cru TCLK_WDT_NS>, <&cru PCLK_WDT_NS>; + clock-names = "tclk", "pclk"; + interrupts = ; + status = "disabled"; + }; + + thermal-zones { + soc_thermal: soc-thermal { + polling-delay-passive = <20>; + polling-delay = <1000>; + sustainable-power = <638>; + + thermal-sensors = <&tsadc 0>; + + trips { + threshold: trip-point-0 { + temperature = <95000>; + hysteresis = <2000>; + type = "passive"; + }; + target: trip-point-1 { + temperature = <110000>; + hysteresis = <2000>; + type = "passive"; + }; + soc_crit: soc-crit { + temperature = <120000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + map1 { + trip = <&target>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + }; + }; + }; + + tsadc: tsadc@ffad0000 { + compatible = "rockchip,rk3528-tsadc"; + reg = <0x0 0xffad0000 0x0 0x400>; + rockchip,grf = <&grf>; + interrupts = ; + clocks = <&cru CLK_TSADC>, <&cru CLK_TSADC_TSEN>, <&cru PCLK_TSADC>; + clock-names = "tsadc", "tsadc_tsen", "apb_pclk"; + assigned-clocks = <&cru CLK_TSADC>, <&cru CLK_TSADC_TSEN>; + assigned-clock-rates = <1200000>, <12000000>; + resets = <&cru SRST_RESETN_TSADC>, <&cru SRST_PRESETN_TSADC>; + reset-names = "tsadc", "tsadc-apb"; + rockchip,hw-tshut-temp = <120000>; + rockchip,hw-tshut-mode = <0>; + rockchip,hw-tshut-polarity = <0>; + #thermal-sensor-cells = <1>; + status = "disabled"; + }; + + saradc: saradc@ffae0000 { + compatible = "rockchip,rk3528-saradc"; + reg = <0x0 0xffae0000 0x0 0x10000>; + interrupts = ; + clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + resets = <&cru SRST_PRESETN_SARADC>; + reset-names = "saradc-apb"; + #io-channel-cells = <1>; + status = "disabled"; + }; + + pdm: pdm@ffbb0000 { + compatible = "rockchip,rk3528-pdm", "rockchip,rk3568-pdm"; + reg = <0x0 0xffbb0000 0x0 0x1000>; + clocks = <&cru MCLK_PDM>, <&cru HCLK_PDM>; + clock-names = "pdm_clk", "pdm_hclk"; + dmas = <&dmac 6>; + dma-names = "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&pdm_clk0 + &pdm_clk1 + &pdm_sdi0 + &pdm_sdi1 + &pdm_sdi2 + &pdm_sdi3>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + spdif: spdif@ffbc0000 { + compatible = "rockchip,rk3528-spdif", "rockchip,rk3568-spdif"; + reg = <0x0 0xffbc0000 0x0 0x1000>; + interrupts = ; + clock-names = "mclk", "hclk"; + clocks = <&cru MCLK_SPDIF>, <&cru HCLK_SPDIF>; + dmas = <&dmac 7>; + dma-names = "tx"; + pinctrl-names = "default"; + pinctrl-0 = <&spdifm0_pins>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + gmac0: ethernet@ffbd0000 { + compatible = "rockchip,rk3528-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xffbd0000 0x0 0x10000>; + interrupts = , + ; + interrupt-names = "macirq", "eth_wake_irq"; + clocks = <&cru CLK_GMAC0_SRC>, <&cru CLK_GMAC0_RMII_50M>, + <&cru CLK_GMAC0_RX>, <&cru CLK_GMAC0_TX>, + <&cru PCLK_MAC_VO>, <&cru ACLK_MAC_VO>; + clock-names = "stmmaceth", "clk_mac_ref", + "mac_clk_rx", "mac_clk_tx", + "pclk_mac", "aclk_mac"; + resets = <&cru SRST_ARESETN_MAC_VO>; + reset-names = "stmmaceth"; + rockchip,grf = <&grf>; + snps,axi-config = <&gmac0_stmmac_axi_setup>; + snps,mixed-burst; + snps,mtl-rx-config = <&gmac0_mtl_rx_setup>; + snps,mtl-tx-config = <&gmac0_mtl_tx_setup>; + snps,tso; + phy-mode = "rmii"; + clock_in_out = "input"; + phy-handle = <&rmii0_phy>; + status = "disabled"; + + mdio0: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + + rmii0_phy: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <2>; + clocks = <&cru CLK_MACPHY>; + resets = <&cru SRST_RESETN_MACPHY>; + }; + }; + + gmac0_stmmac_axi_setup: stmmac-axi-config { + snps,blen = <0 0 0 0 16 8 4>; + snps,rd_osr_lmt = <8>; + snps,wr_osr_lmt = <4>; + }; + + gmac0_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + queue0 {}; + }; + + gmac0_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + queue0 {}; + }; + }; + + gmac1: ethernet@ffbe0000 { + compatible = "rockchip,rk3528-gmac", "snps,dwmac-4.20a"; + reg = <0x0 0xffbe0000 0x0 0x10000>; + interrupts = , + ; + interrupt-names = "macirq", "eth_wake_irq"; + clocks = <&cru CLK_GMAC1_SRC_VPU>, <&cru CLK_GMAC1_RMII_VPU>, + <&cru PCLK_MAC_VPU>, <&cru ACLK_MAC_VPU>; + clock-names = "stmmaceth", "clk_mac_ref", + "pclk_mac", "aclk_mac"; + resets = <&cru SRST_ARESETN_MAC>; + reset-names = "stmmaceth"; + rockchip,grf = <&grf>; + snps,axi-config = <&gmac1_stmmac_axi_setup>; + snps,mixed-burst; + snps,mtl-rx-config = <&gmac1_mtl_rx_setup>; + snps,mtl-tx-config = <&gmac1_mtl_tx_setup>; + snps,tso; + status = "disabled"; + + mdio1: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <0x1>; + #size-cells = <0x0>; + }; + + gmac1_stmmac_axi_setup: stmmac-axi-config { + snps,wr_osr_lmt = <4>; + snps,rd_osr_lmt = <8>; + snps,blen = <0 0 0 0 16 8 4>; + }; + + gmac1_mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <1>; + queue0 {}; + }; + + gmac1_mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <1>; + queue0 {}; + }; + }; + + sdhci: mmc@ffbf0000 { + compatible = "rockchip,rk3528-dwcmshc"; + reg = <0x0 0xffbf0000 0x0 0x10000>; + interrupts = ; + assigned-clocks = <&cru BCLK_EMMC>, <&cru TCLK_EMMC>, <&cru CCLK_SRC_EMMC>; + assigned-clock-rates = <200000000>, <24000000>, <200000000>; + clocks = <&cru CCLK_SRC_EMMC>, <&cru HCLK_EMMC>, + <&cru ACLK_EMMC>, <&cru BCLK_EMMC>, + <&cru TCLK_EMMC>; + clock-names = "core", "bus", "axi", "block", "timer"; + resets = <&cru SRST_CRESETN_EMMC>, <&cru SRST_HRESETN_EMMC>, + <&cru SRST_ARESETN_EMMC>, <&cru SRST_BRESETN_EMMC>, + <&cru SRST_TRESETN_EMMC>; + reset-names = "core", "bus", "axi", "block", "timer"; + max-frequency = <200000000>; + status = "disabled"; + }; + + sfc: spi@ffc00000 { + compatible = "rockchip,sfc"; + reg = <0x0 0xffc00000 0x0 0x4000>; + interrupts = ; + clocks = <&cru SCLK_SFC>, <&cru HCLK_SFC>; + clock-names = "clk_sfc", "hclk_sfc"; + assigned-clocks = <&cru SCLK_SFC>; + assigned-clock-rates = <100000000>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + sdio0: mmc@ffc10000 { + compatible = "rockchip,rk3528-dw-mshc", + "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xffc10000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDIO0>, <&cru CCLK_SRC_SDIO0>, + <&grf_cru SCLK_SDIO0_DRV>, <&grf_cru SCLK_SDIO0_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_HRESETN_SDIO0>; + reset-names = "reset"; + status = "disabled"; + }; + + sdio1: mmc@ffc20000 { + compatible = "rockchip,rk3528-dw-mshc", + "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xffc20000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDIO1>, <&cru CCLK_SRC_SDIO1>, + <&grf_cru SCLK_SDIO1_DRV>, <&grf_cru SCLK_SDIO1_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_HRESETN_SDIO1>; + reset-names = "reset"; + status = "disabled"; + }; + + sdmmc: mmc@ffc30000 { + compatible = "rockchip,rk3528-dw-mshc", + "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xffc30000 0x0 0x4000>; + interrupts = ; + clocks = <&cru HCLK_SDMMC0>, <&cru CCLK_SRC_SDMMC0>, + <&grf_cru SCLK_SDMMC_DRV>, <&grf_cru SCLK_SDMMC_SAMPLE>; + clock-names = "biu", "ciu", "ciu-drive", "ciu-sample"; + fifo-depth = <0x100>; + max-frequency = <150000000>; + resets = <&cru SRST_HRESETN_SDMMC0>; + reset-names = "reset"; + rockchip,use-v2-tuning; + status = "disabled"; + }; + + rng: rng@ffc50000 { + compatible = "rockchip,rkrng"; + reg = <0x0 0xffc50000 0x0 0x200>; + interrupts = ; + clocks = <&scmi_clk SCMI_HCLK_TRNG>; + clock-names = "hclk_trng"; + resets = <&cru SRST_HRESETN_TRNG_NS>; + reset-names = "reset"; + status = "disabled"; + }; + + dmac: dma-controller@ffd60000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0xffd60000 0x0 0x4000>; + interrupts = , + , + , + , + , + , + , + , + ; + arm,pl330-periph-burst; + clocks = <&cru ACLK_DMAC>; + clock-names = "apb_pclk"; + #dma-cells = <1>; + }; + + combphy: phy@ffdc0000 { + compatible = "rockchip,rk3528-naneng-combphy"; + reg = <0x0 0xffdc0000 0x0 0x10000>; + clocks = <&cru CLK_REF_PCIE_INNER_PHY>, <&cru PCLK_PCIE_PHY>, <&cru PCLK_PIPE_GRF>; + clock-names = "ref", "apb", "pipe"; + assigned-clocks = <&cru CLK_REF_PCIE_INNER_PHY>; + assigned-clock-rates = <100000000>; + resets = <&cru SRST_PRESETN_PCIE_PHY>, <&cru SRST_RESETN_PCIE_PIPE_PHY>; + reset-names = "apb", "phy"; + rockchip,pipe-grf = <&grf>; + rockchip,pipe-phy-grf = <&grf>; + #phy-cells = <1>; + status = "disabled"; + }; + + usb2phy: usb2-phy@ffdf0000 { + compatible = "rockchip,rk3528-usb2phy"; + reg = <0x0 0xffdf0000 0x0 0x10000>; + clocks = <&cru CLK_REF_USBPHY>, <&cru PCLK_USBPHY>; + clock-names = "phyclk", "apb_pclk"; + rockchip,usbgrf = <&grf>; + #clock-cells = <0>; + status = "disabled"; + + usb2phy0_otg: otg-port { + #phy-cells = <0>; + interrupts = , + , + ; + interrupt-names = "otg-bvalid", + "otg-id", + "linestate"; + status = "disabled"; + }; + + usb2phy0_host: host-port { + #phy-cells = <0>; + interrupts = ; + interrupt-names = "linestate"; + status = "disabled"; + }; + }; + + pinctrl: pinctrl { + compatible = "rockchip,rk3528-pinctrl"; + rockchip,grf = <&ioc_grf>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gpio0: gpio@ff610000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xff610000 0x0 0x200>; + interrupts = ; + clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 0 32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio1: gpio@ffaf0000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xffaf0000 0x0 0x200>; + interrupts = ; + clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 32 32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio2: gpio@ffb00000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xffb00000 0x0 0x200>; + interrupts = ; + clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 64 32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio3: gpio@ffb10000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xffb10000 0x0 0x200>; + interrupts = ; + clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 96 32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + + gpio4: gpio@ffb20000 { + compatible = "rockchip,gpio-bank"; + reg = <0x0 0xffb20000 0x0 0x200>; + interrupts = ; + clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 128 32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +#include "rk3528-pinctrl.dtsi" diff --git a/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c b/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c index 9a61f8087..1f0b7b6ea 100644 --- a/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c +++ b/target/linux/rockchip/files/drivers/char/hw_random/rockchip-rng.c @@ -21,7 +21,7 @@ #define ROCKCHIP_AUTOSUSPEND_DELAY 100 #define ROCKCHIP_POLL_PERIOD_US 100 -#define ROCKCHIP_POLL_TIMEOUT_US 10000 +#define ROCKCHIP_POLL_TIMEOUT_US 50000 #define RK_MAX_RNG_BYTE (32) /* start of CRYPTO V1 register define */ @@ -37,7 +37,8 @@ /* end of CRYPTO V1 register define */ /* start of CRYPTO V2 register define */ -#define CRYPTO_V2_RNG_CTL 0x0400 +#define CRYPTO_V2_RNG_DEFAULT_OFFSET 0x0400 +#define CRYPTO_V2_RNG_CTL 0x0 #define CRYPTO_V2_RNG_64_BIT_LEN _SBF(4, 0x00) #define CRYPTO_V2_RNG_128_BIT_LEN _SBF(4, 0x01) #define CRYPTO_V2_RNG_192_BIT_LEN _SBF(4, 0x02) @@ -48,11 +49,69 @@ #define CRYPTO_V2_RNG_SLOWEST_SOC_RING _SBF(2, 0x03) #define CRYPTO_V2_RNG_ENABLE BIT(1) #define CRYPTO_V2_RNG_START BIT(0) -#define CRYPTO_V2_RNG_SAMPLE_CNT 0x0404 -#define CRYPTO_V2_RNG_DOUT_0 0x0410 +#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 _SBF(0, 0x00) +#define TRNG_V1_CTRL_RAND _SBF(0, 0x01) +#define TRNG_V1_CTRL_SEED _SBF(0, 0x02) + +#define TRNG_V1_STAT 0x0004 +#define TRNG_V1_STAT_SEEDED BIT(9) +#define TRNG_V1_STAT_GENERATING BIT(30) +#define TRNG_V1_STAT_RESEEDING BIT(31) + +#define TRNG_V1_MODE 0x0008 +#define TRNG_V1_MODE_128_BIT _SBF(3, 0x00) +#define TRNG_V1_MODE_256_BIT _SBF(3, 0x01) + +#define TRNG_V1_IE 0x0010 +#define TRNG_V1_IE_GLBL_EN BIT(31) +#define TRNG_V1_IE_SEED_DONE_EN BIT(1) +#define TRNG_V1_IE_RAND_RDY_EN BIT(0) + +#define TRNG_V1_ISTAT 0x0014 +#define TRNG_V1_ISTAT_RAND_RDY 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 */ + +/* start of RKRNG register define */ +#define RKRNG_CTRL 0x0010 +#define RKRNG_CTRL_INST_REQ BIT(0) +#define RKRNG_CTRL_RESEED_REQ BIT(1) +#define RKRNG_CTRL_TEST_REQ BIT(2) +#define RKRNG_CTRL_SW_DRNG_REQ BIT(3) +#define RKRNG_CTRL_SW_TRNG_REQ BIT(4) + +#define RKRNG_STATE 0x0014 +#define RKRNG_STATE_INST_ACK BIT(0) +#define RKRNG_STATE_RESEED_ACK BIT(1) +#define RKRNG_STATE_TEST_ACK BIT(2) +#define RKRNG_STATE_SW_DRNG_ACK BIT(3) +#define RKRNG_STATE_SW_TRNG_ACK BIT(4) + +/* DRNG_DATA_0 ~ DNG_DATA_7 */ +#define RKRNG_DRNG_DATA_0 0x0070 +#define RKRNG_DRNG_DATA_7 0x008C + +/* end of RKRNG register define */ + struct rk_rng_soc_data { + u32 default_offset; + + int (*rk_rng_init)(struct hwrng *rng); int (*rk_rng_read)(struct hwrng *rng, void *buf, size_t max, bool wait); }; @@ -99,6 +158,38 @@ static void rk_rng_cleanup(struct hwrng *rng) clk_bulk_disable_unprepare(rk_rng->clk_num, rk_rng->clk_bulks); } +static int rk_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + int ret; + int read_len = 0; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + if (!rk_rng->soc_data->rk_rng_read) + return -EFAULT; + + ret = pm_runtime_get_sync(rk_rng->dev); + if (ret < 0) { + pm_runtime_put_noidle(rk_rng->dev); + return ret; + } + + ret = 0; + while (max > ret) { + read_len = rk_rng->soc_data->rk_rng_read(rng, buf + ret, + max - ret, wait); + if (read_len < 0) { + ret = read_len; + break; + } + ret += read_len; + } + + pm_runtime_mark_last_busy(rk_rng->dev); + pm_runtime_put_sync_autosuspend(rk_rng->dev); + + return ret; +} + static void rk_rng_read_regs(struct rk_rng *rng, u32 offset, void *buf, size_t size) { @@ -108,18 +199,12 @@ static void rk_rng_read_regs(struct rk_rng *rng, u32 offset, void *buf, *(u32 *)(buf + i) = be32_to_cpu(rk_rng_readl(rng, offset + i)); } -static int rk_rng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) +static int crypto_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) { int ret = 0; u32 reg_ctrl = 0; struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); - ret = pm_runtime_get_sync(rk_rng->dev); - if (ret < 0) { - pm_runtime_put_noidle(rk_rng->dev); - return ret; - } - /* enable osc_ring to get entropy, sample period is set as 100 */ reg_ctrl = CRYPTO_V1_OSC_ENABLE | CRYPTO_V1_TRNG_SAMPLE_PERIOD(100); rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_TRNG_CTRL); @@ -128,10 +213,12 @@ static int rk_rng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) rk_rng_writel(rk_rng, reg_ctrl, CRYPTO_V1_CTRL); - ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V1_CTRL, reg_ctrl, - !(reg_ctrl & CRYPTO_V1_RNG_START), - ROCKCHIP_POLL_PERIOD_US, - ROCKCHIP_POLL_TIMEOUT_US); + ret = read_poll_timeout(rk_rng_readl, reg_ctrl, + !(reg_ctrl & CRYPTO_V1_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, CRYPTO_V1_CTRL); + if (ret < 0) goto out; @@ -144,24 +231,15 @@ out: rk_rng_writel(rk_rng, HIWORD_UPDATE(0, CRYPTO_V1_RNG_START, 0), CRYPTO_V1_CTRL); - pm_runtime_mark_last_busy(rk_rng->dev); - pm_runtime_put_sync_autosuspend(rk_rng->dev); - return ret; } -static int rk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) +static int crypto_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) { int ret = 0; u32 reg_ctrl = 0; struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); - ret = pm_runtime_get_sync(rk_rng->dev); - if (ret < 0) { - pm_runtime_put_noidle(rk_rng->dev); - return ret; - } - /* enable osc_ring to get entropy, sample period is set as 100 */ rk_rng_writel(rk_rng, 100, CRYPTO_V2_RNG_SAMPLE_CNT); @@ -171,12 +249,13 @@ static int rk_rng_v2_read(struct hwrng *rng, void *buf, size_t max, bool wait) reg_ctrl |= CRYPTO_V2_RNG_START; rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), - CRYPTO_V2_RNG_CTL); + CRYPTO_V2_RNG_CTL); - ret = readl_poll_timeout(rk_rng->mem + CRYPTO_V2_RNG_CTL, reg_ctrl, - !(reg_ctrl & CRYPTO_V2_RNG_START), - ROCKCHIP_POLL_PERIOD_US, - ROCKCHIP_POLL_TIMEOUT_US); + ret = read_poll_timeout(rk_rng_readl, reg_ctrl, + !(reg_ctrl & CRYPTO_V2_RNG_START), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, CRYPTO_V2_RNG_CTL); if (ret < 0) goto out; @@ -188,28 +267,188 @@ out: /* close TRNG */ rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), CRYPTO_V2_RNG_CTL); - pm_runtime_mark_last_busy(rk_rng->dev); - pm_runtime_put_sync_autosuspend(rk_rng->dev); + return ret; +} + +static int trng_v1_init(struct hwrng *rng) +{ + int ret; + uint32_t auto_reseed_cnt = 1000; + uint32_t reg_ctrl, status, version; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + version = rk_rng_readl(rk_rng, TRNG_V1_VERSION); + if (version != TRNG_v1_VERSION_CODE) { + dev_err(rk_rng->dev, + "wrong trng version, expected = %08x, actual = %08x\n", + TRNG_V1_VERSION, version); + ret = -EFAULT; + goto exit; + } + + status = rk_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)) { + uint32_t mask = TRNG_V1_STAT_SEEDED | + TRNG_V1_STAT_GENERATING | + TRNG_V1_STAT_RESEEDING; + + udelay(10); + + /* wait for GENERATING and RESEEDING flag to clear */ + read_poll_timeout(rk_rng_readl, reg_ctrl, + (reg_ctrl & mask) == TRNG_V1_STAT_SEEDED, + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, TRNG_V1_STAT); + } + + /* clear ISTAT flag because trng may auto reseeding when power on */ + reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT); + rk_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT); + + /* auto reseed after (auto_reseed_cnt * 16) byte rand generate */ + rk_rng_writel(rk_rng, auto_reseed_cnt, TRNG_V1_AUTO_RQSTS); + + ret = 0; +exit: return ret; } -static const struct rk_rng_soc_data rk_rng_v1_soc_data = { - .rk_rng_read = rk_rng_v1_read, +static int trng_v1_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + int ret = 0; + u32 reg_ctrl = 0; + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + + /* clear ISTAT anyway */ + reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT); + rk_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT); + + /* generate 256 bit random */ + rk_rng_writel(rk_rng, TRNG_V1_MODE_256_BIT, TRNG_V1_MODE); + rk_rng_writel(rk_rng, TRNG_V1_CTRL_RAND, TRNG_V1_CTRL); + + /* + * Generate 256 bit random data will cost 1024 clock cycles. + * Estimated at 150M RNG module frequency, it takes 6.7 microseconds. + */ + udelay(10); + reg_ctrl = rk_rng_readl(rk_rng, TRNG_V1_ISTAT); + if (!(reg_ctrl & TRNG_V1_ISTAT_RAND_RDY)) { + /* wait RAND_RDY triggered */ + ret = read_poll_timeout(rk_rng_readl, reg_ctrl, + (reg_ctrl & TRNG_V1_ISTAT_RAND_RDY), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US, false, + rk_rng, TRNG_V1_ISTAT); + if (ret < 0) + goto out; + } + + ret = min_t(size_t, max, RK_MAX_RNG_BYTE); + + rk_rng_read_regs(rk_rng, TRNG_V1_RAND0, buf, ret); + + /* clear all status flag */ + rk_rng_writel(rk_rng, reg_ctrl, TRNG_V1_ISTAT); +out: + /* close TRNG */ + rk_rng_writel(rk_rng, TRNG_V1_CTRL_NOP, TRNG_V1_CTRL); + + return ret; +} + +static int rkrng_init(struct hwrng *rng) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + u32 reg = 0; + + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL); + + reg = rk_rng_readl(rk_rng, RKRNG_STATE); + rk_rng_writel(rk_rng, reg, RKRNG_STATE); + + return 0; +} + +static int rkrng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + struct rk_rng *rk_rng = container_of(rng, struct rk_rng, rng); + u32 reg_ctrl = 0; + int ret; + + reg_ctrl = RKRNG_CTRL_SW_DRNG_REQ; + + rk_rng_writel(rk_rng, HIWORD_UPDATE(reg_ctrl, 0xffff, 0), RKRNG_CTRL); + + ret = readl_poll_timeout(rk_rng->mem + RKRNG_STATE, reg_ctrl, + (reg_ctrl & RKRNG_STATE_SW_DRNG_ACK), + ROCKCHIP_POLL_PERIOD_US, + ROCKCHIP_POLL_TIMEOUT_US); + + if (ret) + goto exit; + + rk_rng_writel(rk_rng, reg_ctrl, RKRNG_STATE); + + ret = min_t(size_t, max, RK_MAX_RNG_BYTE); + + rk_rng_read_regs(rk_rng, RKRNG_DRNG_DATA_0, buf, ret); + +exit: + /* close TRNG */ + rk_rng_writel(rk_rng, HIWORD_UPDATE(0, 0xffff, 0), RKRNG_CTRL); + + return ret; +} + +static const struct rk_rng_soc_data crypto_v1_soc_data = { + .default_offset = 0, + + .rk_rng_read = crypto_v1_read, }; -static const struct rk_rng_soc_data rk_rng_v2_soc_data = { - .rk_rng_read = rk_rng_v2_read, +static const struct rk_rng_soc_data crypto_v2_soc_data = { + .default_offset = CRYPTO_V2_RNG_DEFAULT_OFFSET, + + .rk_rng_read = crypto_v2_read, +}; + +static const struct rk_rng_soc_data trng_v1_soc_data = { + .default_offset = 0, + + .rk_rng_init = trng_v1_init, + .rk_rng_read = trng_v1_read, +}; + +static const struct rk_rng_soc_data rkrng_soc_data = { + .default_offset = 0, + + .rk_rng_init = rkrng_init, + .rk_rng_read = rkrng_read, }; static const struct of_device_id rk_rng_dt_match[] = { { .compatible = "rockchip,cryptov1-rng", - .data = (void *)&rk_rng_v1_soc_data, + .data = (void *)&crypto_v1_soc_data, }, { .compatible = "rockchip,cryptov2-rng", - .data = (void *)&rk_rng_v2_soc_data, + .data = (void *)&crypto_v2_soc_data, + }, + { + .compatible = "rockchip,trngv1", + .data = (void *)&trng_v1_soc_data, + }, + { + .compatible = "rockchip,rkrng", + .data = (void *)&rkrng_soc_data, }, { }, }; @@ -222,6 +461,7 @@ static int rk_rng_probe(struct platform_device *pdev) struct rk_rng *rk_rng; struct device_node *np = pdev->dev.of_node; const struct of_device_id *match; + resource_size_t map_size; dev_dbg(&pdev->dev, "probing...\n"); rk_rng = devm_kzalloc(&pdev->dev, sizeof(struct rk_rng), GFP_KERNEL); @@ -237,13 +477,27 @@ static int rk_rng_probe(struct platform_device *pdev) rk_rng->rng.init = rk_rng_init; rk_rng->rng.cleanup = rk_rng_cleanup, #endif - rk_rng->rng.read = rk_rng->soc_data->rk_rng_read; + rk_rng->rng.read = rk_rng_read; rk_rng->rng.quality = 999; - rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, NULL); + rk_rng->mem = devm_of_iomap(&pdev->dev, pdev->dev.of_node, 0, &map_size); if (IS_ERR(rk_rng->mem)) return PTR_ERR(rk_rng->mem); + /* compatible with crypto v2 module */ + /* + * With old dtsi configurations, the RNG base was equal to the crypto + * base, so both drivers could not be enabled at the same time. + * RNG base = CRYPTO base + RNG offset + * (Since RK356X, RNG module is no longer belongs to CRYPTO module) + * + * With new dtsi configurations, CRYPTO regs is divided into two parts + * |---cipher---|---rng---|---pka---|, and RNG base is real RNG base. + * RNG driver and CRYPTO driver could be enabled at the same time. + */ + if (map_size > rk_rng->soc_data->default_offset) + rk_rng->mem += rk_rng->soc_data->default_offset; + rk_rng->clk_num = devm_clk_bulk_get_all(&pdev->dev, &rk_rng->clk_bulks); if (rk_rng->clk_num < 0) { dev_err(&pdev->dev, "failed to get clks property\n"); @@ -253,7 +507,7 @@ static int rk_rng_probe(struct platform_device *pdev) platform_set_drvdata(pdev, rk_rng); pm_runtime_set_autosuspend_delay(&pdev->dev, - ROCKCHIP_AUTOSUSPEND_DELAY); + ROCKCHIP_AUTOSUSPEND_DELAY); pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_enable(&pdev->dev); @@ -263,6 +517,16 @@ static int rk_rng_probe(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); } + /* for some platform need hardware operation when probe */ + if (rk_rng->soc_data->rk_rng_init) { + pm_runtime_get_sync(rk_rng->dev); + + ret = rk_rng->soc_data->rk_rng_init(&rk_rng->rng); + + pm_runtime_mark_last_busy(rk_rng->dev); + pm_runtime_put_sync_autosuspend(rk_rng->dev); + } + return ret; } @@ -285,7 +549,7 @@ static int rk_rng_runtime_resume(struct device *dev) static const struct dev_pm_ops rk_rng_pm_ops = { SET_RUNTIME_PM_OPS(rk_rng_runtime_suspend, - rk_rng_runtime_resume, NULL) + rk_rng_runtime_resume, NULL) SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) }; diff --git a/target/linux/rockchip/files/drivers/clk/rockchip/clk-rk3528.c b/target/linux/rockchip/files/drivers/clk/rockchip/clk-rk3528.c new file mode 100644 index 000000000..6de4209eb --- /dev/null +++ b/target/linux/rockchip/files/drivers/clk/rockchip/clk-rk3528.c @@ -0,0 +1,1124 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Rockchip Electronics Co. Ltd. + * Author: Joseph Chen + */ + +#include +#include +#include +#include +#include +#include +#include +#include "clk.h" + +#define RK3528_GRF_SOC_STATUS0 0x1a0 + +enum rk3528_plls { + apll, cpll, gpll, ppll, dpll, +}; + +/* + * ## PLL attention. + * + * [FRAC PLL]: GPLL, PPLL, DPLL + * - frac mode: refdiv can be 1 or 2 only + * - int mode: refdiv has no special limit + * - VCO range: [950, 3800] MHZ + * + * [INT PLL]: CPLL, APLL + * - int mode: refdiv can be 1 or 2 only + * - VCO range: [475, 1900] MHZ + * + * [PPLL]: normal mode only. + * + * + * ## CRU access attention. + * + * pclk_cru => pclk_vo_root => aclk_vo_root + * pclk_cru_pcie => pclk_vpu_root => aclk_vpu_root + * pclk_cru_ddrphy => hclk_rkvdec_root => aclk_rkvdec_root + */ +static struct rockchip_pll_rate_table rk3528_pll_rates[] = { + /* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */ + 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(1512000000, 1, 63, 1, 1, 1, 0), + RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0), + RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0), + RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0), + RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0), /* GPLL */ + RK3036_PLL_RATE(1092000000, 2, 91, 1, 1, 1, 0), + RK3036_PLL_RATE(1008000000, 1, 42, 1, 1, 1, 0), + RK3036_PLL_RATE(1000000000, 1, 125, 3, 1, 1, 0), /* PPLL */ + RK3036_PLL_RATE(996000000, 2, 83, 1, 1, 1, 0), /* CPLL */ + RK3036_PLL_RATE(960000000, 1, 40, 1, 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(600000000, 1, 50, 2, 1, 1, 0), + RK3036_PLL_RATE(594000000, 2, 99, 2, 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(216000000, 1, 72, 4, 2, 1, 0), + RK3036_PLL_RATE(96000000, 1, 24, 3, 2, 1, 0), + { /* sentinel */ }, +}; + +#define RK3528_DIV_ACLK_M_CORE_MASK 0x1f +#define RK3528_DIV_ACLK_M_CORE_SHIFT 11 +#define RK3528_DIV_PCLK_DBG_MASK 0x1f +#define RK3528_DIV_PCLK_DBG_SHIFT 1 + +#define RK3528_CLKSEL39(_aclk_m_core) \ +{ \ + .reg = RK3528_CLKSEL_CON(39), \ + .val = HIWORD_UPDATE(_aclk_m_core, RK3528_DIV_ACLK_M_CORE_MASK, \ + RK3528_DIV_ACLK_M_CORE_SHIFT), \ +} + +#define RK3528_CLKSEL40(_pclk_dbg) \ +{ \ + .reg = RK3528_CLKSEL_CON(40), \ + .val = HIWORD_UPDATE(_pclk_dbg, RK3528_DIV_PCLK_DBG_MASK, \ + RK3528_DIV_PCLK_DBG_SHIFT), \ +} + +/* SIGN-OFF: _aclk_m_core: 550M, _pclk_dbg: 137.5M, */ +#define RK3528_CPUCLK_RATE(_prate, _aclk_m_core, _pclk_dbg) \ +{ \ + .prate = _prate, \ + .divs = { \ + RK3528_CLKSEL39(_aclk_m_core), \ + RK3528_CLKSEL40(_pclk_dbg), \ + }, \ +} + +static struct rockchip_cpuclk_rate_table rk3528_cpuclk_rates[] __initdata = { + /* APLL(CPU) rate <= 1900M, due to APLL VCO limit */ + RK3528_CPUCLK_RATE(1896000000, 1, 13), + RK3528_CPUCLK_RATE(1800000000, 1, 12), + RK3528_CPUCLK_RATE(1704000000, 1, 11), + RK3528_CPUCLK_RATE(1608000000, 1, 11), + RK3528_CPUCLK_RATE(1512000000, 1, 11), + RK3528_CPUCLK_RATE(1416000000, 1, 9), + RK3528_CPUCLK_RATE(1296000000, 1, 8), + RK3528_CPUCLK_RATE(1200000000, 1, 8), + RK3528_CPUCLK_RATE(1188000000, 1, 8), + RK3528_CPUCLK_RATE(1092000000, 1, 7), + RK3528_CPUCLK_RATE(1008000000, 1, 6), + RK3528_CPUCLK_RATE(1000000000, 1, 6), + RK3528_CPUCLK_RATE(996000000, 1, 6), + RK3528_CPUCLK_RATE(960000000, 1, 6), + RK3528_CPUCLK_RATE(912000000, 1, 6), + RK3528_CPUCLK_RATE(816000000, 1, 5), + RK3528_CPUCLK_RATE(600000000, 1, 3), + RK3528_CPUCLK_RATE(594000000, 1, 3), + RK3528_CPUCLK_RATE(408000000, 1, 2), + RK3528_CPUCLK_RATE(312000000, 1, 2), + RK3528_CPUCLK_RATE(216000000, 1, 1), + RK3528_CPUCLK_RATE(96000000, 1, 0), +}; + +static const struct rockchip_cpuclk_reg_data rk3528_cpuclk_data = { + .core_reg[0] = RK3528_CLKSEL_CON(39), + .div_core_shift[0] = 5, + .div_core_mask[0] = 0x1f, + .num_cores = 1, + .mux_core_alt = 1, + .mux_core_main = 0, + .mux_core_shift = 10, + .mux_core_mask = 0x1, +}; + +PNAME(mux_pll_p) = { "xin24m" }; +PNAME(mux_24m_32k_p) = { "xin24m", "clk_32k" }; +PNAME(mux_armclk_p) = { "apll", "gpll" }; +PNAME(mux_gpll_cpll_p) = { "gpll", "cpll" }; +PNAME(mux_gpll_cpll_xin24m_p) = { "gpll", "cpll", "xin24m" }; +PNAME(mux_100m_50m_24m_p) = { "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAME(mux_150m_100m_24m_p) = { "clk_150m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_200m_100m_24m_p) = { "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_200m_100m_50m_24m_p) = { "clk_200m_src", "clk_100m_src", "clk_50m_src", "xin24m" }; +PNAME(mux_300m_200m_100m_24m_p) = { "clk_300m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_339m_200m_100m_24m_p) = { "clk_339m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_500m_200m_100m_24m_p) = { "clk_500m_src", "clk_200m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_500m_300m_100m_24m_p) = { "clk_500m_src", "clk_300m_src", "clk_100m_src", "xin24m" }; +PNAME(mux_600m_300m_200m_24m_p) = { "clk_600m_src", "clk_300m_src", "clk_200m_src", "xin24m" }; +PNAME(aclk_gpu_p) = { "aclk_gpu_root", "clk_gpu_pvtpll_src" }; +PNAME(aclk_rkvdec_pvtmux_root_p) = { "aclk_rkvdec_root", "clk_rkvdec_pvtpll_src" }; +PNAME(clk_i2c2_p) = { "clk_200m_src", "clk_100m_src", "xin24m", "clk_32k" }; +PNAME(clk_ref_pcie_inner_phy_p) = { "clk_ppll_100m_src", "xin24m" }; +PNAME(dclk_vop0_p) = { "dclk_vop_src0", "clk_hdmiphy_pixel_io" }; +PNAME(mclk_i2s0_2ch_sai_src_p) = { "clk_i2s0_2ch_src", "clk_i2s0_2ch_frac", "xin12m" }; +PNAME(mclk_i2s1_8ch_sai_src_p) = { "clk_i2s1_8ch_src", "clk_i2s1_8ch_frac", "xin12m" }; +PNAME(mclk_i2s2_2ch_sai_src_p) = { "clk_i2s2_2ch_src", "clk_i2s2_2ch_frac", "xin12m" }; +PNAME(mclk_i2s3_8ch_sai_src_p) = { "clk_i2s3_8ch_src", "clk_i2s3_8ch_frac", "xin12m" }; +PNAME(mclk_sai_i2s0_p) = { "mclk_i2s0_2ch_sai_src", "i2s0_mclkin" }; +PNAME(mclk_sai_i2s1_p) = { "mclk_i2s1_8ch_sai_src", "i2s1_mclkin" }; +PNAME(mclk_spdif_src_p) = { "clk_spdif_src", "clk_spdif_frac", "xin12m" }; +PNAME(sclk_uart0_src_p) = { "clk_uart0_src", "clk_uart0_frac", "xin24m" }; +PNAME(sclk_uart1_src_p) = { "clk_uart1_src", "clk_uart1_frac", "xin24m" }; +PNAME(sclk_uart2_src_p) = { "clk_uart2_src", "clk_uart2_frac", "xin24m" }; +PNAME(sclk_uart3_src_p) = { "clk_uart3_src", "clk_uart3_frac", "xin24m" }; +PNAME(sclk_uart4_src_p) = { "clk_uart4_src", "clk_uart4_frac", "xin24m" }; +PNAME(sclk_uart5_src_p) = { "clk_uart5_src", "clk_uart5_frac", "xin24m" }; +PNAME(sclk_uart6_src_p) = { "clk_uart6_src", "clk_uart6_frac", "xin24m" }; +PNAME(sclk_uart7_src_p) = { "clk_uart7_src", "clk_uart7_frac", "xin24m" }; +PNAME(clk_32k_p) = { "xin_osc0_div", "clk_pvtm_32k" }; + +static struct rockchip_pll_clock rk3528_pll_clks[] __initdata = { + [apll] = PLL(pll_rk3328, PLL_APLL, "apll", mux_pll_p, + CLK_IS_CRITICAL, RK3528_PLL_CON(0), + RK3528_MODE_CON, 0, 0, 0, rk3528_pll_rates), + + [cpll] = PLL(pll_rk3328, PLL_CPLL, "cpll", mux_pll_p, + CLK_IS_CRITICAL, RK3528_PLL_CON(8), + RK3528_MODE_CON, 2, 0, 0, rk3528_pll_rates), + + [gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p, + CLK_IS_CRITICAL, RK3528_PLL_CON(24), + RK3528_MODE_CON, 4, 0, 0, rk3528_pll_rates), + + [ppll] = PLL(pll_rk3328, PLL_PPLL, "ppll", mux_pll_p, + CLK_IS_CRITICAL, RK3528_PCIE_PLL_CON(32), + RK3528_MODE_CON, 6, 0, + ROCKCHIP_PLL_FIXED_MODE, rk3528_pll_rates), + + [dpll] = PLL(pll_rk3328, PLL_DPLL, "dpll", mux_pll_p, + CLK_IS_CRITICAL, RK3528_DDRPHY_PLL_CON(16), + RK3528_DDRPHY_MODE_CON, 0, 0, 0, rk3528_pll_rates), +}; + +#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_clk_branch rk3528_uart0_fracmux __initdata = + MUX(CLK_UART0, "clk_uart0", sclk_uart0_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(6), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart1_fracmux __initdata = + MUX(CLK_UART1, "clk_uart1", sclk_uart1_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(8), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart2_fracmux __initdata = + MUX(CLK_UART2, "clk_uart2", sclk_uart2_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(10), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart3_fracmux __initdata = + MUX(CLK_UART3, "clk_uart3", sclk_uart3_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(12), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart4_fracmux __initdata = + MUX(CLK_UART4, "clk_uart4", sclk_uart4_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(14), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart5_fracmux __initdata = + MUX(CLK_UART5, "clk_uart5", sclk_uart5_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(16), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart6_fracmux __initdata = + MUX(CLK_UART6, "clk_uart6", sclk_uart6_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(18), 0, 2, MFLAGS); + +static struct rockchip_clk_branch rk3528_uart7_fracmux __initdata = + MUX(CLK_UART7, "clk_uart7", sclk_uart7_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(20), 0, 2, MFLAGS); + +static struct rockchip_clk_branch mclk_i2s0_2ch_sai_src_fracmux __initdata = + MUX(MCLK_I2S0_2CH_SAI_SRC_PRE, "mclk_i2s0_2ch_sai_src_pre", mclk_i2s0_2ch_sai_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(22), 0, 2, MFLAGS); + +static struct rockchip_clk_branch mclk_i2s1_8ch_sai_src_fracmux __initdata = + MUX(MCLK_I2S1_8CH_SAI_SRC_PRE, "mclk_i2s1_8ch_sai_src_pre", mclk_i2s1_8ch_sai_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(26), 0, 2, MFLAGS); + +static struct rockchip_clk_branch mclk_i2s2_2ch_sai_src_fracmux __initdata = + MUX(MCLK_I2S2_2CH_SAI_SRC_PRE, "mclk_i2s2_2ch_sai_src_pre", mclk_i2s2_2ch_sai_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(28), 0, 2, MFLAGS); + +static struct rockchip_clk_branch mclk_i2s3_8ch_sai_src_fracmux __initdata = + MUX(MCLK_I2S3_8CH_SAI_SRC_PRE, "mclk_i2s3_8ch_sai_src_pre", mclk_i2s3_8ch_sai_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(24), 0, 2, MFLAGS); + +static struct rockchip_clk_branch mclk_spdif_src_fracmux __initdata = + MUX(MCLK_SDPDIF_SRC_PRE, "mclk_spdif_src_pre", mclk_spdif_src_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(32), 0, 2, MFLAGS); + +/* + * CRU Clock-Architecture + */ +static struct rockchip_clk_branch rk3528_clk_branches[] __initdata = { + /* top */ + FACTOR(0, "xin12m", "xin24m", 0, 1, 2), + + COMPOSITE(CLK_MATRIX_250M_SRC, "clk_250m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(1), 15, 1, MFLAGS, 10, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 5, GFLAGS), + COMPOSITE(CLK_MATRIX_500M_SRC, "clk_500m_src", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(3), 11, 1, MFLAGS, 6, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 10, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_50M_SRC, "clk_50m_src", "cpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(0), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_100M_SRC, "clk_100m_src", "cpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(0), 7, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 2, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_150M_SRC, "clk_150m_src", "gpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(1), 0, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 3, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_200M_SRC, "clk_200m_src", "gpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(1), 5, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 4, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_300M_SRC, "clk_300m_src", "gpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(2), 0, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 6, GFLAGS), + COMPOSITE_NOMUX_HALFDIV(CLK_MATRIX_339M_SRC, "clk_339m_src", "gpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(2), 5, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 7, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_400M_SRC, "clk_400m_src", "gpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(2), 10, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_MATRIX_600M_SRC, "clk_600m_src", "gpll", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(4), 0, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 11, GFLAGS), + COMPOSITE(DCLK_VOP_SRC0, "dclk_vop_src0", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(32), 10, 1, MFLAGS, 2, 8, DFLAGS, + RK3528_CLKGATE_CON(3), 7, GFLAGS), + COMPOSITE(DCLK_VOP_SRC1, "dclk_vop_src1", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(33), 8, 1, MFLAGS, 0, 8, DFLAGS, + RK3528_CLKGATE_CON(3), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_HSM, "clk_hsm", "xin24m", 0, + RK3528_CLKSEL_CON(36), 5, 5, DFLAGS, + RK3528_CLKGATE_CON(3), 13, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART0_SRC, "clk_uart0_src", "gpll", 0, + RK3528_CLKSEL_CON(4), 5, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 12, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART0_FRAC, "clk_uart0_frac", "clk_uart0_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(5), 0, + RK3528_CLKGATE_CON(0), 13, GFLAGS, &rk3528_uart0_fracmux), + GATE(SCLK_UART0, "sclk_uart0", "clk_uart0", 0, + RK3528_CLKGATE_CON(0), 14, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART1_SRC, "clk_uart1_src", "gpll", 0, + RK3528_CLKSEL_CON(6), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART1_FRAC, "clk_uart1_frac", "clk_uart1_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(7), 0, + RK3528_CLKGATE_CON(1), 0, GFLAGS, &rk3528_uart1_fracmux), + GATE(SCLK_UART1, "sclk_uart1", "clk_uart1", 0, + RK3528_CLKGATE_CON(1), 1, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART2_SRC, "clk_uart2_src", "gpll", 0, + RK3528_CLKSEL_CON(8), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(1), 2, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART2_FRAC, "clk_uart2_frac", "clk_uart2_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(9), 0, + RK3528_CLKGATE_CON(1), 3, GFLAGS, &rk3528_uart2_fracmux), + GATE(SCLK_UART2, "sclk_uart2", "clk_uart2", 0, + RK3528_CLKGATE_CON(1), 4, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART3_SRC, "clk_uart3_src", "gpll", 0, + RK3528_CLKSEL_CON(10), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(1), 5, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART3_FRAC, "clk_uart3_frac", "clk_uart3_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(11), 0, + RK3528_CLKGATE_CON(1), 6, GFLAGS, &rk3528_uart3_fracmux), + GATE(SCLK_UART3, "sclk_uart3", "clk_uart3", 0, + RK3528_CLKGATE_CON(1), 7, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART4_SRC, "clk_uart4_src", "gpll", 0, + RK3528_CLKSEL_CON(12), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(1), 8, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART4_FRAC, "clk_uart4_frac", "clk_uart4_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(13), 0, + RK3528_CLKGATE_CON(1), 9, GFLAGS, &rk3528_uart4_fracmux), + GATE(SCLK_UART4, "sclk_uart4", "clk_uart4", 0, + RK3528_CLKGATE_CON(1), 10, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART5_SRC, "clk_uart5_src", "gpll", 0, + RK3528_CLKSEL_CON(14), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(1), 11, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART5_FRAC, "clk_uart5_frac", "clk_uart5_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(15), 0, + RK3528_CLKGATE_CON(1), 12, GFLAGS, &rk3528_uart5_fracmux), + GATE(SCLK_UART5, "sclk_uart5", "clk_uart5", 0, + RK3528_CLKGATE_CON(1), 13, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART6_SRC, "clk_uart6_src", "gpll", 0, + RK3528_CLKSEL_CON(16), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(1), 14, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART6_FRAC, "clk_uart6_frac", "clk_uart6_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(17), 0, + RK3528_CLKGATE_CON(1), 15, GFLAGS, &rk3528_uart6_fracmux), + GATE(SCLK_UART6, "sclk_uart6", "clk_uart6", 0, + RK3528_CLKGATE_CON(2), 0, GFLAGS), + + COMPOSITE_NOMUX(CLK_UART7_SRC, "clk_uart7_src", "gpll", 0, + RK3528_CLKSEL_CON(18), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(2), 1, GFLAGS), + COMPOSITE_FRACMUX(CLK_UART7_FRAC, "clk_uart7_frac", "clk_uart7_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(19), 0, + RK3528_CLKGATE_CON(2), 2, GFLAGS, &rk3528_uart7_fracmux), + GATE(SCLK_UART7, "sclk_uart7", "clk_uart7", 0, + RK3528_CLKGATE_CON(2), 3, GFLAGS), + + COMPOSITE_NOMUX(CLK_I2S0_2CH_SRC, "clk_i2s0_2ch_src", "gpll", 0, + RK3528_CLKSEL_CON(20), 8, 5, DFLAGS, + RK3528_CLKGATE_CON(2), 5, GFLAGS), + COMPOSITE_FRACMUX(CLK_I2S0_2CH_FRAC, "clk_i2s0_2ch_frac", "clk_i2s0_2ch_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(21), 0, + RK3528_CLKGATE_CON(2), 6, GFLAGS, &mclk_i2s0_2ch_sai_src_fracmux), + GATE(MCLK_I2S0_2CH_SAI_SRC, "mclk_i2s0_2ch_sai_src", "mclk_i2s0_2ch_sai_src_pre", 0, + RK3528_CLKGATE_CON(2), 7, GFLAGS), + + COMPOSITE_NOMUX(CLK_I2S1_8CH_SRC, "clk_i2s1_8ch_src", "gpll", 0, + RK3528_CLKSEL_CON(24), 3, 5, DFLAGS, + RK3528_CLKGATE_CON(2), 11, GFLAGS), + COMPOSITE_FRACMUX(CLK_I2S1_8CH_FRAC, "clk_i2s1_8ch_frac", "clk_i2s1_8ch_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(25), 0, + RK3528_CLKGATE_CON(2), 12, GFLAGS, &mclk_i2s1_8ch_sai_src_fracmux), + GATE(MCLK_I2S1_8CH_SAI_SRC, "mclk_i2s1_8ch_sai_src", "mclk_i2s1_8ch_sai_src_pre", 0, + RK3528_CLKGATE_CON(2), 13, GFLAGS), + + COMPOSITE_NOMUX(CLK_I2S2_2CH_SRC, "clk_i2s2_2ch_src", "gpll", 0, + RK3528_CLKSEL_CON(26), 3, 5, DFLAGS, + RK3528_CLKGATE_CON(2), 14, GFLAGS), + COMPOSITE_FRACMUX(CLK_I2S2_2CH_FRAC, "clk_i2s2_2ch_frac", "clk_i2s2_2ch_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(27), 0, + RK3528_CLKGATE_CON(2), 15, GFLAGS, &mclk_i2s2_2ch_sai_src_fracmux), + GATE(MCLK_I2S2_2CH_SAI_SRC, "mclk_i2s2_2ch_sai_src", "mclk_i2s2_2ch_sai_src_pre", 0, + RK3528_CLKGATE_CON(3), 0, GFLAGS), + + COMPOSITE_NOMUX(CLK_I2S3_8CH_SRC, "clk_i2s3_8ch_src", "gpll", 0, + RK3528_CLKSEL_CON(22), 3, 5, DFLAGS, + RK3528_CLKGATE_CON(2), 8, GFLAGS), + COMPOSITE_FRACMUX(CLK_I2S3_8CH_FRAC, "clk_i2s3_8ch_frac", "clk_i2s3_8ch_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(23), 0, + RK3528_CLKGATE_CON(2), 9, GFLAGS, &mclk_i2s3_8ch_sai_src_fracmux), + GATE(MCLK_I2S3_8CH_SAI_SRC, "mclk_i2s3_8ch_sai_src", "mclk_i2s3_8ch_sai_src_pre", 0, + RK3528_CLKGATE_CON(2), 10, GFLAGS), + + COMPOSITE_NOMUX(CLK_SPDIF_SRC, "clk_spdif_src", "gpll", 0, + RK3528_CLKSEL_CON(30), 2, 5, DFLAGS, + RK3528_CLKGATE_CON(3), 4, GFLAGS), + COMPOSITE_FRACMUX(CLK_SPDIF_FRAC, "clk_spdif_frac", "clk_spdif_src", CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(31), 0, + RK3528_CLKGATE_CON(3), 5, GFLAGS, &mclk_spdif_src_fracmux), + GATE(MCLK_SPDIF_SRC, "mclk_spdif_src", "mclk_spdif_src_pre", 0, + RK3528_CLKGATE_CON(3), 6, GFLAGS), + + /* bus */ + COMPOSITE_NODIV(ACLK_BUS_M_ROOT, "aclk_bus_m_root", mux_300m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(43), 12, 2, MFLAGS, + RK3528_CLKGATE_CON(8), 7, GFLAGS), + GATE(ACLK_GIC, "aclk_gic", "aclk_bus_m_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(9), 1, GFLAGS), + + COMPOSITE_NODIV(ACLK_BUS_ROOT, "aclk_bus_root", mux_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(43), 6, 2, MFLAGS, + RK3528_CLKGATE_CON(8), 4, GFLAGS), + GATE(ACLK_SPINLOCK, "aclk_spinlock", "aclk_bus_root", 0, + RK3528_CLKGATE_CON(9), 2, GFLAGS), + GATE(ACLK_DMAC, "aclk_dmac", "aclk_bus_root", 0, + RK3528_CLKGATE_CON(9), 4, GFLAGS), + GATE(ACLK_DCF, "aclk_dcf", "aclk_bus_root", 0, + RK3528_CLKGATE_CON(11), 11, GFLAGS), + COMPOSITE(ACLK_BUS_VOPGL_ROOT, "aclk_bus_vopgl_root", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(43), 3, 1, MFLAGS, 0, 3, DFLAGS, + RK3528_CLKGATE_CON(8), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_BUS_H_ROOT, "aclk_bus_h_root", mux_500m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(43), 4, 2, MFLAGS, + RK3528_CLKGATE_CON(8), 2, GFLAGS), + GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_h_root", 0, + RK3528_CLKGATE_CON(10), 14, GFLAGS), + + COMPOSITE_NODIV(HCLK_BUS_ROOT, "hclk_bus_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(43), 8, 2, MFLAGS, + RK3528_CLKGATE_CON(8), 5, GFLAGS), + + COMPOSITE_NODIV(PCLK_BUS_ROOT, "pclk_bus_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(43), 10, 2, MFLAGS, + RK3528_CLKGATE_CON(8), 6, GFLAGS), + GATE(PCLK_DFT2APB, "pclk_dft2apb", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(8), 13, GFLAGS), + GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(8), 15, GFLAGS), + GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(9), 5, GFLAGS), + GATE(PCLK_JDBCK_DAP, "pclk_jdbck_dap", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(9), 12, GFLAGS), + GATE(PCLK_WDT_NS, "pclk_wdt_ns", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(9), 15, GFLAGS), + GATE(PCLK_UART0, "pclk_uart0", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(10), 7, GFLAGS), + GATE(PCLK_PWM0, "pclk_pwm0", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(11), 4, GFLAGS), + GATE(PCLK_PWM1, "pclk_pwm1", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(11), 7, GFLAGS), + GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(10), 13, GFLAGS), + GATE(PCLK_SCR, "pclk_scr", "pclk_bus_root", 0, + RK3528_CLKGATE_CON(11), 10, GFLAGS), + GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(11), 12, GFLAGS), + + COMPOSITE_NODIV(CLK_PWM0, "clk_pwm0", mux_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(44), 6, 2, MFLAGS, + RK3528_CLKGATE_CON(11), 5, GFLAGS), + COMPOSITE_NODIV(CLK_PWM1, "clk_pwm1", mux_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(44), 8, 2, MFLAGS, + RK3528_CLKGATE_CON(11), 8, GFLAGS), + + GATE(CLK_CAPTURE_PWM1, "clk_capture_pwm1", "xin24m", 0, + RK3528_CLKGATE_CON(11), 9, GFLAGS), + GATE(CLK_CAPTURE_PWM0, "clk_capture_pwm0", "xin24m", 0, + RK3528_CLKGATE_CON(11), 6, GFLAGS), + GATE(CLK_JDBCK_DAP, "clk_jdbck_dap", "xin24m", 0, + RK3528_CLKGATE_CON(9), 13, GFLAGS), + GATE(TCLK_WDT_NS, "tclk_wdt_ns", "xin24m", 0, + RK3528_CLKGATE_CON(10), 0, GFLAGS), + + GATE(CLK_TIMER_ROOT, "clk_timer_root", "xin24m", 0, + RK3528_CLKGATE_CON(8), 9, GFLAGS), + GATE(CLK_TIMER0, "clk_timer0", "clk_timer_root", 0, + RK3528_CLKGATE_CON(9), 6, GFLAGS), + GATE(CLK_TIMER1, "clk_timer1", "clk_timer_root", 0, + RK3528_CLKGATE_CON(9), 7, GFLAGS), + GATE(CLK_TIMER2, "clk_timer2", "clk_timer_root", 0, + RK3528_CLKGATE_CON(9), 8, GFLAGS), + GATE(CLK_TIMER3, "clk_timer3", "clk_timer_root", 0, + RK3528_CLKGATE_CON(9), 9, GFLAGS), + GATE(CLK_TIMER4, "clk_timer4", "clk_timer_root", 0, + RK3528_CLKGATE_CON(9), 10, GFLAGS), + GATE(CLK_TIMER5, "clk_timer5", "clk_timer_root", 0, + RK3528_CLKGATE_CON(9), 11, GFLAGS), + + /* pmu */ + GATE(HCLK_PMU_ROOT, "hclk_pmu_root", "clk_100m_src", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(0), 1, GFLAGS), + GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "clk_100m_src", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(0), 0, GFLAGS), + + GATE(FCLK_MCU, "fclk_mcu", "hclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(0), 7, GFLAGS), + GATE(HCLK_PMU_SRAM, "hclk_pmu_sram", "hclk_pmu_root", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(5), 4, GFLAGS), + + GATE(PCLK_I2C2, "pclk_i2c2", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(0), 2, GFLAGS), + GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(1), 2, GFLAGS), + GATE(PCLK_PMU_IOC, "pclk_pmu_ioc", "pclk_pmu_root", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(1), 5, GFLAGS), + GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(1), 6, GFLAGS), + GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(1), 7, GFLAGS), + GATE(PCLK_PMU_WDT, "pclk_pmu_wdt", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(1), 10, GFLAGS), + GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(0), 13, GFLAGS), + GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(0), 14, GFLAGS), + GATE(PCLK_OSCCHK, "pclk_oscchk", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(0), 9, GFLAGS), + GATE(PCLK_PMU_MAILBOX, "pclk_pmu_mailbox", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(1), 12, GFLAGS), + GATE(PCLK_SCRKEYGEN, "pclk_scrkeygen", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(1), 15, GFLAGS), + GATE(PCLK_PVTM_PMU, "pclk_pvtm_pmu", "pclk_pmu_root", 0, + RK3528_PMU_CLKGATE_CON(5), 1, GFLAGS), + + COMPOSITE_NODIV(CLK_I2C2, "clk_i2c2", clk_i2c2_p, 0, + RK3528_PMU_CLKSEL_CON(0), 0, 2, MFLAGS, + RK3528_PMU_CLKGATE_CON(0), 3, GFLAGS), + + GATE(CLK_REFOUT, "clk_refout", "xin24m", 0, + RK3528_PMU_CLKGATE_CON(2), 4, GFLAGS), + COMPOSITE_NOMUX(CLK_PVTM_PMU, "clk_pvtm_pmu", "xin24m", 0, + RK3528_PMU_CLKSEL_CON(5), 0, 5, DFLAGS, + RK3528_PMU_CLKGATE_CON(5), 0, GFLAGS), + + COMPOSITE_FRAC(XIN_OSC0_DIV, "xin_osc0_div", "xin24m", 0, + RK3528_PMU_CLKSEL_CON(1), 0, + RK3528_PMU_CLKGATE_CON(1), 0, GFLAGS), + /* clk_32k: internal! No path from external osc 32k */ + MUX(CLK_DEEPSLOW, "clk_32k", clk_32k_p, CLK_IS_CRITICAL, + RK3528_PMU_CLKSEL_CON(2), 0, 1, MFLAGS), + GATE(RTC_CLK_MCU, "rtc_clk_mcu", "clk_32k", 0, + RK3528_PMU_CLKGATE_CON(0), 8, GFLAGS), + GATE(CLK_DDR_FAIL_SAFE, "clk_ddr_fail_safe", "xin24m", CLK_IS_CRITICAL, + RK3528_PMU_CLKGATE_CON(1), 1, GFLAGS), + + COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", mux_24m_32k_p, 0, + RK3528_PMU_CLKSEL_CON(0), 2, 1, MFLAGS, + RK3528_PMU_CLKGATE_CON(0), 15, GFLAGS), + COMPOSITE_NODIV(TCLK_PMU_WDT, "tclk_pmu_wdt", mux_24m_32k_p, 0, + RK3528_PMU_CLKSEL_CON(2), 1, 1, MFLAGS, + RK3528_PMU_CLKGATE_CON(1), 11, GFLAGS), + + /* core */ + COMPOSITE_NOMUX(ACLK_M_CORE_BIU, "aclk_m_core", "armclk", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(39), 11, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3528_CLKGATE_CON(5), 12, GFLAGS), + COMPOSITE_NOMUX(PCLK_DBG, "pclk_dbg", "armclk", CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(40), 1, 5, DFLAGS | CLK_DIVIDER_READ_ONLY, + RK3528_CLKGATE_CON(5), 13, GFLAGS), + GATE(PCLK_CPU_ROOT, "pclk_cpu_root", "pclk_dbg", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(6), 1, GFLAGS), + GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_cpu_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(6), 2, GFLAGS), + + /* ddr */ + GATE(CLK_DDRC_SRC, "clk_ddrc_src", "dpll", CLK_IS_CRITICAL, + RK3528_DDRPHY_CLKGATE_CON(0), 0, GFLAGS), + GATE(CLK_DDR_PHY, "clk_ddr_phy", "dpll", CLK_IS_CRITICAL, + RK3528_DDRPHY_CLKGATE_CON(0), 1, GFLAGS), + + COMPOSITE_NODIV(PCLK_DDR_ROOT, "pclk_ddr_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(90), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(45), 0, GFLAGS), + GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_ddr_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 3, GFLAGS), + GATE(PCLK_DDR_HWLP, "pclk_ddr_hwlp", "pclk_ddr_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 8, GFLAGS), + GATE(CLK_TIMER_DDRMON, "clk_timer_ddrmon", "xin24m", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 4, GFLAGS), + + GATE(PCLK_DDRC, "pclk_ddrc", "pclk_ddr_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 2, GFLAGS), + GATE(PCLK_DDR_GRF, "pclk_ddr_grf", "pclk_ddr_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 6, GFLAGS), + GATE(PCLK_DDRPHY, "pclk_ddrphy", "pclk_ddr_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 9, GFLAGS), + + GATE(ACLK_DDR_UPCTL, "aclk_ddr_upctl", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 11, GFLAGS), + GATE(CLK_DDR_UPCTL, "clk_ddr_upctl", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 12, GFLAGS), + GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 13, GFLAGS), + GATE(ACLK_DDR_SCRAMBLE, "aclk_ddr_scramble", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 14, GFLAGS), + GATE(ACLK_SPLIT, "aclk_split", "clk_ddrc_src", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(45), 15, GFLAGS), + + /* gpu */ + COMPOSITE_NODIV(ACLK_GPU_ROOT, "aclk_gpu_root", mux_500m_300m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(76), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(34), 0, GFLAGS), + COMPOSITE_NODIV(ACLK_GPU, "aclk_gpu", aclk_gpu_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(76), 6, 1, MFLAGS, + RK3528_CLKGATE_CON(34), 7, GFLAGS), + GATE(ACLK_GPU_MALI, "aclk_gpu_mali", "aclk_gpu", 0, + RK3528_CLKGATE_CON(34), 8, GFLAGS), + COMPOSITE_NODIV(PCLK_GPU_ROOT, "pclk_gpu_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(76), 4, 2, MFLAGS, + RK3528_CLKGATE_CON(34), 2, GFLAGS), + + /* rkvdec */ + COMPOSITE_NODIV(ACLK_RKVDEC_ROOT_NDFT, "aclk_rkvdec_root", mux_339m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(88), 6, 2, MFLAGS, + RK3528_CLKGATE_CON(44), 3, GFLAGS), + COMPOSITE_NODIV(HCLK_RKVDEC_ROOT, "hclk_rkvdec_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(88), 4, 2, MFLAGS, + RK3528_CLKGATE_CON(44), 2, GFLAGS), + GATE(PCLK_DDRPHY_CRU, "pclk_ddrphy_cru", "hclk_rkvdec_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(44), 4, GFLAGS), + GATE(HCLK_RKVDEC, "hclk_rkvdec", "hclk_rkvdec_root", 0, + RK3528_CLKGATE_CON(44), 9, GFLAGS), + COMPOSITE_NODIV(CLK_HEVC_CA_RKVDEC, "clk_hevc_ca_rkvdec", mux_600m_300m_200m_24m_p, 0, + RK3528_CLKSEL_CON(88), 11, 2, MFLAGS, + RK3528_CLKGATE_CON(44), 11, GFLAGS), + MUX(ACLK_RKVDEC_PVTMUX_ROOT, "aclk_rkvdec_pvtmux_root", aclk_rkvdec_pvtmux_root_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(88), 13, 1, MFLAGS), + GATE(ACLK_RKVDEC, "aclk_rkvdec", "aclk_rkvdec_pvtmux_root", 0, + RK3528_CLKGATE_CON(44), 8, GFLAGS), + + /* rkvenc */ + COMPOSITE_NODIV(ACLK_RKVENC_ROOT, "aclk_rkvenc_root", mux_300m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(79), 2, 2, MFLAGS, + RK3528_CLKGATE_CON(36), 1, GFLAGS), + GATE(ACLK_RKVENC, "aclk_rkvenc", "aclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(36), 7, GFLAGS), + + COMPOSITE_NODIV(PCLK_RKVENC_ROOT, "pclk_rkvenc_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(79), 4, 2, MFLAGS, + RK3528_CLKGATE_CON(36), 2, GFLAGS), + GATE(PCLK_RKVENC_IOC, "pclk_rkvenc_ioc", "pclk_rkvenc_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(37), 10, GFLAGS), + GATE(PCLK_RKVENC_GRF, "pclk_rkvenc_grf", "pclk_rkvenc_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(38), 6, GFLAGS), + GATE(PCLK_I2C1, "pclk_i2c1", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(36), 11, GFLAGS), + GATE(PCLK_I2C0, "pclk_i2c0", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(36), 13, GFLAGS), + GATE(PCLK_SPI0, "pclk_spi0", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(37), 2, GFLAGS), + GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(37), 8, GFLAGS), + GATE(PCLK_UART1, "pclk_uart1", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(38), 2, GFLAGS), + GATE(PCLK_UART3, "pclk_uart3", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(38), 4, GFLAGS), + GATE(PCLK_CAN0, "pclk_can0", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(38), 7, GFLAGS), + GATE(PCLK_CAN1, "pclk_can1", "pclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(38), 9, GFLAGS), + + COMPOSITE_NODIV(MCLK_PDM, "mclk_pdm", mux_150m_100m_24m_p, 0, + RK3528_CLKSEL_CON(80), 12, 2, MFLAGS, + RK3528_CLKGATE_CON(38), 1, GFLAGS), + COMPOSITE(CLK_CAN0, "clk_can0", mux_gpll_cpll_p, 0, + RK3528_CLKSEL_CON(81), 6, 1, MFLAGS, 0, 6, DFLAGS, + RK3528_CLKGATE_CON(38), 8, GFLAGS), + COMPOSITE(CLK_CAN1, "clk_can1", mux_gpll_cpll_p, 0, + RK3528_CLKSEL_CON(81), 13, 1, MFLAGS, 7, 6, DFLAGS, + RK3528_CLKGATE_CON(38), 10, GFLAGS), + + COMPOSITE_NODIV(HCLK_RKVENC_ROOT, "hclk_rkvenc_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(79), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(36), 0, GFLAGS), + GATE(HCLK_SAI_I2S1, "hclk_sai_i2s1", "hclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(36), 9, GFLAGS), + GATE(HCLK_SPDIF, "hclk_spdif", "hclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(37), 14, GFLAGS), + GATE(HCLK_PDM, "hclk_pdm", "hclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(38), 0, GFLAGS), + GATE(HCLK_RKVENC, "hclk_rkvenc", "hclk_rkvenc_root", 0, + RK3528_CLKGATE_CON(36), 6, GFLAGS), + + COMPOSITE_NODIV(CLK_CORE_RKVENC, "clk_core_rkvenc", mux_300m_200m_100m_24m_p, 0, + RK3528_CLKSEL_CON(79), 6, 2, MFLAGS, + RK3528_CLKGATE_CON(36), 8, GFLAGS), + COMPOSITE_NODIV(CLK_I2C0, "clk_i2c0", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(79), 11, 2, MFLAGS, + RK3528_CLKGATE_CON(36), 14, GFLAGS), + COMPOSITE_NODIV(CLK_I2C1, "clk_i2c1", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(79), 9, 2, MFLAGS, + RK3528_CLKGATE_CON(36), 12, GFLAGS), + COMPOSITE_NODIV(CLK_SPI0, "clk_spi0", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(79), 13, 2, MFLAGS, + RK3528_CLKGATE_CON(37), 3, GFLAGS), + COMPOSITE_NODIV(MCLK_SAI_I2S1, "mclk_sai_i2s1", mclk_sai_i2s1_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(79), 8, 1, MFLAGS, + RK3528_CLKGATE_CON(36), 10, GFLAGS), + GATE(DBCLK_GPIO4, "dbclk_gpio4", "xin24m", 0, + RK3528_CLKGATE_CON(37), 9, GFLAGS), + + /* vo */ + COMPOSITE_NODIV(HCLK_VO_ROOT, "hclk_vo_root", mux_150m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(83), 2, 2, MFLAGS, + RK3528_CLKGATE_CON(39), 1, GFLAGS), + GATE(HCLK_VOP, "hclk_vop", "hclk_vo_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(40), 2, GFLAGS), + GATE(HCLK_USBHOST, "hclk_usbhost", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(43), 3, GFLAGS), + GATE(HCLK_JPEG_DECODER, "hclk_jpeg_decoder", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(41), 7, GFLAGS), + GATE(HCLK_VDPP, "hclk_vdpp", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(39), 10, GFLAGS), + GATE(HCLK_CVBS, "hclk_cvbs", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(41), 3, GFLAGS), + GATE(HCLK_USBHOST_ARB, "hclk_usbhost_arb", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(43), 4, GFLAGS), + GATE(HCLK_SAI_I2S3, "hclk_sai_i2s3", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(42), 1, GFLAGS), + GATE(HCLK_HDCP, "hclk_hdcp", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(41), 1, GFLAGS), + GATE(HCLK_RGA2E, "hclk_rga2e", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(39), 7, GFLAGS), + GATE(HCLK_SDMMC0, "hclk_sdmmc0", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(42), 9, GFLAGS), + GATE(HCLK_HDCP_KEY, "hclk_hdcp_key", "hclk_vo_root", 0, + RK3528_CLKGATE_CON(40), 15, GFLAGS), + + COMPOSITE_NODIV(ACLK_VO_L_ROOT, "aclk_vo_l_root", mux_150m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(84), 1, 2, MFLAGS, + RK3528_CLKGATE_CON(41), 8, GFLAGS), + GATE(ACLK_MAC_VO, "aclk_gmac0", "aclk_vo_l_root", 0, + RK3528_CLKGATE_CON(41), 10, GFLAGS), + + COMPOSITE_NODIV(PCLK_VO_ROOT, "pclk_vo_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(83), 4, 2, MFLAGS, + RK3528_CLKGATE_CON(39), 2, GFLAGS), + GATE(PCLK_MAC_VO, "pclk_gmac0", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(41), 11, GFLAGS), + GATE(PCLK_VCDCPHY, "pclk_vcdcphy", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(42), 4, GFLAGS), + GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(42), 5, GFLAGS), + GATE(PCLK_VO_IOC, "pclk_vo_ioc", "pclk_vo_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(42), 7, GFLAGS), + GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(42), 11, GFLAGS), + GATE(PCLK_UART4, "pclk_uart4", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(43), 7, GFLAGS), + GATE(PCLK_I2C4, "pclk_i2c4", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(43), 9, GFLAGS), + GATE(PCLK_I2C7, "pclk_i2c7", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(43), 11, GFLAGS), + + GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(43), 13, GFLAGS), + + GATE(PCLK_VO_GRF, "pclk_vo_grf", "pclk_vo_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(39), 13, GFLAGS), + GATE(PCLK_CRU, "pclk_cru", "pclk_vo_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(39), 15, GFLAGS), + GATE(PCLK_HDMI, "pclk_hdmi", "pclk_vo_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(40), 6, GFLAGS), + GATE(PCLK_HDMIPHY, "pclk_hdmiphy", "pclk_vo_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(40), 14, GFLAGS), + GATE(PCLK_HDCP, "pclk_hdcp", "pclk_vo_root", 0, + RK3528_CLKGATE_CON(41), 2, GFLAGS), + + COMPOSITE_NODIV(CLK_CORE_VDPP, "clk_core_vdpp", mux_339m_200m_100m_24m_p, 0, + RK3528_CLKSEL_CON(83), 10, 2, MFLAGS, + RK3528_CLKGATE_CON(39), 12, GFLAGS), + COMPOSITE_NODIV(CLK_CORE_RGA2E, "clk_core_rga2e", mux_339m_200m_100m_24m_p, 0, + RK3528_CLKSEL_CON(83), 8, 2, MFLAGS, + RK3528_CLKGATE_CON(39), 9, GFLAGS), + COMPOSITE_NODIV(ACLK_JPEG_ROOT, "aclk_jpeg_root", mux_339m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(84), 9, 2, MFLAGS, + RK3528_CLKGATE_CON(41), 15, GFLAGS), + GATE(ACLK_JPEG_DECODER, "aclk_jpeg_decoder", "aclk_jpeg_root", 0, + RK3528_CLKGATE_CON(41), 6, GFLAGS), + + COMPOSITE_NODIV(ACLK_VO_ROOT, "aclk_vo_root", mux_339m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(83), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(39), 0, GFLAGS), + GATE_NO_SET_RATE(ACLK_RGA2E, "aclk_rga2e", "aclk_vo_root", 0, + RK3528_CLKGATE_CON(39), 8, GFLAGS), + GATE_NO_SET_RATE(ACLK_VDPP, "aclk_vdpp", "aclk_vo_root", 0, + RK3528_CLKGATE_CON(39), 11, GFLAGS), + GATE_NO_SET_RATE(ACLK_HDCP, "aclk_hdcp", "aclk_vo_root", 0, + RK3528_CLKGATE_CON(41), 0, GFLAGS), + + COMPOSITE(CCLK_SRC_SDMMC0, "cclk_src_sdmmc0", mux_gpll_cpll_xin24m_p, 0, + RK3528_CLKSEL_CON(85), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3528_CLKGATE_CON(42), 8, GFLAGS), + + COMPOSITE(ACLK_VOP_ROOT, "aclk_vop_root", mux_gpll_cpll_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(83), 15, 1, MFLAGS, 12, 3, DFLAGS, + RK3528_CLKGATE_CON(40), 0, GFLAGS), + GATE(ACLK_VOP, "aclk_vop", "aclk_vop_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(40), 5, GFLAGS), + + COMPOSITE_NODIV(CLK_I2C4, "clk_i2c4", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(85), 13, 2, MFLAGS, + RK3528_CLKGATE_CON(43), 10, GFLAGS), + COMPOSITE_NODIV(CLK_I2C7, "clk_i2c7", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(86), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(43), 12, GFLAGS), + GATE(DBCLK_GPIO2, "dbclk_gpio2", "xin24m", 0, + RK3528_CLKGATE_CON(42), 6, GFLAGS), + + GATE(CLK_HDMIHDP0, "clk_hdmihdp0", "xin24m", 0, + RK3528_CLKGATE_CON(43), 2, GFLAGS), + GATE(CLK_MACPHY, "clk_macphy", "xin24m", 0, + RK3528_CLKGATE_CON(42), 3, GFLAGS), + GATE(CLK_REF_USBPHY, "clk_ref_usbphy", "xin24m", 0, + RK3528_CLKGATE_CON(43), 14, GFLAGS), + GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m", 0, + RK3528_CLKGATE_CON(42), 12, GFLAGS), + FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2), + + GATE(MCLK_SAI_I2S3, "mclk_sai_i2s3", "mclk_i2s3_8ch_sai_src", 0, + RK3528_CLKGATE_CON(42), 2, GFLAGS), + COMPOSITE_NODIV(DCLK_VOP0, "dclk_vop0", dclk_vop0_p, + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT | CLK_SET_RATE_NO_REPARENT, + RK3528_CLKSEL_CON(84), 0, 1, MFLAGS, + RK3528_CLKGATE_CON(40), 3, GFLAGS), + GATE(DCLK_VOP1, "dclk_vop1", "dclk_vop_src1", + CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + RK3528_CLKGATE_CON(40), 4, GFLAGS), + FACTOR_GATE(DCLK_CVBS, "dclk_cvbs", "dclk_vop1", 0, 1, 4, + RK3528_CLKGATE_CON(41), 4, GFLAGS), + GATE(DCLK_4X_CVBS, "dclk_4x_cvbs", "dclk_vop1", 0, + RK3528_CLKGATE_CON(41), 5, GFLAGS), + + FACTOR_GATE(CLK_SFR_HDMI, "clk_sfr_hdmi", "dclk_vop_src1", CLK_IS_CRITICAL, 1, 4, + RK3528_CLKGATE_CON(40), 7, GFLAGS), + + GATE(CLK_SPDIF_HDMI, "clk_spdif_hdmi", "mclk_spdif_src", 0, + RK3528_CLKGATE_CON(40), 10, GFLAGS), + GATE(MCLK_SPDIF, "mclk_spdif", "mclk_spdif_src", 0, + RK3528_CLKGATE_CON(37), 15, GFLAGS), + GATE(CLK_CEC_HDMI, "clk_cec_hdmi", "clk_32k", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(40), 8, GFLAGS), + /* vpu */ + GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m", 0, + RK3528_CLKGATE_CON(26), 5, GFLAGS), + GATE(DBCLK_GPIO3, "dbclk_gpio3", "xin24m", 0, + RK3528_CLKGATE_CON(27), 1, GFLAGS), + GATE(CLK_SUSPEND_USB3OTG, "clk_suspend_usb3otg", "xin24m", 0, + RK3528_CLKGATE_CON(33), 4, GFLAGS), + GATE(CLK_PCIE_AUX, "clk_pcie_aux", "xin24m", 0, + RK3528_CLKGATE_CON(30), 2, GFLAGS), + GATE(TCLK_EMMC, "tclk_emmc", "xin24m", 0, + RK3528_CLKGATE_CON(26), 3, GFLAGS), + GATE(CLK_REF_USB3OTG, "clk_ref_usb3otg", "xin24m", 0, + RK3528_CLKGATE_CON(33), 2, GFLAGS), + COMPOSITE(CCLK_SRC_SDIO0, "cclk_src_sdio0", mux_gpll_cpll_xin24m_p, 0, + RK3528_CLKSEL_CON(72), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3528_CLKGATE_CON(32), 1, GFLAGS), + + COMPOSITE_NODIV(PCLK_VPU_ROOT, "pclk_vpu_root", mux_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(61), 4, 2, MFLAGS, + RK3528_CLKGATE_CON(25), 5, GFLAGS), + GATE(PCLK_VPU_GRF, "pclk_vpu_grf", "pclk_vpu_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(25), 12, GFLAGS), + GATE(PCLK_CRU_PCIE, "pclk_cru_pcie", "pclk_vpu_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(25), 11, GFLAGS), + GATE(PCLK_UART6, "pclk_uart6", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 11, GFLAGS), + GATE(PCLK_CAN2, "pclk_can2", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(32), 7, GFLAGS), + GATE(PCLK_SPI1, "pclk_spi1", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 4, GFLAGS), + GATE(PCLK_CAN3, "pclk_can3", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(32), 9, GFLAGS), + GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 0, GFLAGS), + GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(26), 4, GFLAGS), + GATE(PCLK_SARADC, "pclk_saradc", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(32), 11, GFLAGS), + GATE(PCLK_ACODEC, "pclk_acodec", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(26), 13, GFLAGS), + GATE(PCLK_UART7, "pclk_uart7", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 13, GFLAGS), + GATE(PCLK_UART5, "pclk_uart5", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 9, GFLAGS), + GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(32), 14, GFLAGS), + GATE(PCLK_PCIE, "pclk_pcie", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(30), 1, GFLAGS), + GATE(PCLK_UART2, "pclk_uart2", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 7, GFLAGS), + GATE(PCLK_VPU_IOC, "pclk_vpu_ioc", "pclk_vpu_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(26), 8, GFLAGS), + GATE(PCLK_PIPE_GRF, "pclk_pipe_grf", "pclk_vpu_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(30), 7, GFLAGS), + GATE(PCLK_I2C5, "pclk_i2c5", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(28), 1, GFLAGS), + GATE(PCLK_PCIE_PHY, "pclk_pcie_phy", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(30), 6, GFLAGS), + GATE(PCLK_I2C3, "pclk_i2c3", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(27), 15, GFLAGS), + GATE(PCLK_MAC_VPU, "pclk_gmac1", "pclk_vpu_root", CLK_IS_CRITICAL, + RK3528_CLKGATE_CON(28), 6, GFLAGS), + GATE(PCLK_I2C6, "pclk_i2c6", "pclk_vpu_root", 0, + RK3528_CLKGATE_CON(28), 3, GFLAGS), + + COMPOSITE_NODIV(ACLK_VPU_L_ROOT, "aclk_vpu_l_root", mux_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(60), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(25), 0, GFLAGS), + GATE_NO_SET_RATE(ACLK_EMMC, "aclk_emmc", "aclk_vpu_l_root", 0, + RK3528_CLKGATE_CON(26), 1, GFLAGS), + GATE_NO_SET_RATE(ACLK_MAC_VPU, "aclk_gmac1", "aclk_vpu_l_root", 0, + RK3528_CLKGATE_CON(28), 5, GFLAGS), + GATE_NO_SET_RATE(ACLK_PCIE, "aclk_pcie", "aclk_vpu_l_root", 0, + RK3528_CLKGATE_CON(30), 3, GFLAGS), + + GATE_NO_SET_RATE(ACLK_USB3OTG, "aclk_usb3otg", "aclk_vpu_l_root", 0, + RK3528_CLKGATE_CON(33), 1, GFLAGS), + + COMPOSITE_NODIV(HCLK_VPU_ROOT, "hclk_vpu_root", mux_200m_100m_50m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(61), 2, 2, MFLAGS, + RK3528_CLKGATE_CON(25), 4, GFLAGS), + GATE(HCLK_VPU, "hclk_vpu", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(25), 10, GFLAGS), + GATE(HCLK_SFC, "hclk_sfc", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(25), 13, GFLAGS), + GATE(HCLK_EMMC, "hclk_emmc", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(26), 0, GFLAGS), + GATE(HCLK_SAI_I2S0, "hclk_sai_i2s0", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(26), 9, GFLAGS), + GATE(HCLK_SAI_I2S2, "hclk_sai_i2s2", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(26), 11, GFLAGS), + + GATE(HCLK_PCIE_SLV, "hclk_pcie_slv", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(30), 4, GFLAGS), + GATE(HCLK_PCIE_DBI, "hclk_pcie_dbi", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(30), 5, GFLAGS), + GATE(HCLK_SDIO0, "hclk_sdio0", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(32), 2, GFLAGS), + GATE(HCLK_SDIO1, "hclk_sdio1", "hclk_vpu_root", 0, + RK3528_CLKGATE_CON(32), 4, GFLAGS), + + COMPOSITE_NOMUX(CLK_GMAC1_VPU_25M, "clk_gmac1_25m", "ppll", 0, + RK3528_CLKSEL_CON(60), 2, 8, DFLAGS, + RK3528_CLKGATE_CON(25), 1, GFLAGS), + COMPOSITE_NOMUX(CLK_PPLL_125M_MATRIX, "clk_ppll_125m_src", "ppll", 0, + RK3528_CLKSEL_CON(60), 10, 5, DFLAGS, + RK3528_CLKGATE_CON(25), 2, GFLAGS), + + COMPOSITE(CLK_CAN3, "clk_can3", mux_gpll_cpll_p, 0, + RK3528_CLKSEL_CON(73), 13, 1, MFLAGS, 7, 6, DFLAGS, + RK3528_CLKGATE_CON(32), 10, GFLAGS), + COMPOSITE_NODIV(CLK_I2C6, "clk_i2c6", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(64), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(28), 4, GFLAGS), + + COMPOSITE(SCLK_SFC, "sclk_sfc", mux_gpll_cpll_xin24m_p, 0, + RK3528_CLKSEL_CON(61), 12, 2, MFLAGS, 6, 6, DFLAGS, + RK3528_CLKGATE_CON(25), 14, GFLAGS), + COMPOSITE(CCLK_SRC_EMMC, "cclk_src_emmc", mux_gpll_cpll_xin24m_p, 0, + RK3528_CLKSEL_CON(62), 6, 2, MFLAGS, 0, 6, DFLAGS, + RK3528_CLKGATE_CON(25), 15, GFLAGS), + + COMPOSITE_NODIV(ACLK_VPU_ROOT, "aclk_vpu_root", mux_300m_200m_100m_24m_p, CLK_IS_CRITICAL, + RK3528_CLKSEL_CON(61), 0, 2, MFLAGS, + RK3528_CLKGATE_CON(25), 3, GFLAGS), + GATE(ACLK_VPU, "aclk_vpu", "aclk_vpu_root", 0, + RK3528_CLKGATE_CON(25), 9, GFLAGS), + + COMPOSITE_NODIV(CLK_SPI1, "clk_spi1", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(63), 10, 2, MFLAGS, + RK3528_CLKGATE_CON(27), 5, GFLAGS), + COMPOSITE(CCLK_SRC_SDIO1, "cclk_src_sdio1", mux_gpll_cpll_xin24m_p, 0, + RK3528_CLKSEL_CON(72), 14, 2, MFLAGS, 8, 6, DFLAGS, + RK3528_CLKGATE_CON(32), 3, GFLAGS), + COMPOSITE(CLK_CAN2, "clk_can2", mux_gpll_cpll_p, 0, + RK3528_CLKSEL_CON(73), 6, 1, MFLAGS, 0, 6, DFLAGS, + RK3528_CLKGATE_CON(32), 8, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m", 0, + RK3528_CLKSEL_CON(74), 3, 5, DFLAGS, + RK3528_CLKGATE_CON(32), 15, GFLAGS), + COMPOSITE_NOMUX(CLK_SARADC, "clk_saradc", "xin24m", 0, + RK3528_CLKSEL_CON(74), 0, 3, DFLAGS, + RK3528_CLKGATE_CON(32), 12, GFLAGS), + COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m", 0, + RK3528_CLKSEL_CON(74), 8, 5, DFLAGS, + RK3528_CLKGATE_CON(33), 0, GFLAGS), + COMPOSITE_NODIV(BCLK_EMMC, "bclk_emmc", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(62), 8, 2, MFLAGS, + RK3528_CLKGATE_CON(26), 2, GFLAGS), + COMPOSITE_NOMUX(MCLK_ACODEC_TX, "mclk_acodec_tx", "mclk_i2s2_2ch_sai_src", 0, + RK3528_CLKSEL_CON(63), 0, 8, DFLAGS, + RK3528_CLKGATE_CON(26), 14, GFLAGS), + COMPOSITE_NODIV(CLK_I2C3, "clk_i2c3", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(63), 12, 2, MFLAGS, + RK3528_CLKGATE_CON(28), 0, GFLAGS), + COMPOSITE_NODIV(CLK_I2C5, "clk_i2c5", mux_200m_100m_50m_24m_p, 0, + RK3528_CLKSEL_CON(63), 14, 2, MFLAGS, + RK3528_CLKGATE_CON(28), 2, GFLAGS), + COMPOSITE_NODIV(MCLK_SAI_I2S0, "mclk_sai_i2s0", mclk_sai_i2s0_p, CLK_SET_RATE_PARENT, + RK3528_CLKSEL_CON(62), 10, 1, MFLAGS, + RK3528_CLKGATE_CON(26), 10, GFLAGS), + GATE(MCLK_SAI_I2S2, "mclk_sai_i2s2", "mclk_i2s2_2ch_sai_src", 0, + RK3528_CLKGATE_CON(26), 12, GFLAGS), + /* pcie */ + COMPOSITE_NOMUX(CLK_PPLL_100M_MATRIX, "clk_ppll_100m_src", "ppll", CLK_IS_CRITICAL, + RK3528_PCIE_CLKSEL_CON(1), 2, 5, DFLAGS, + RK3528_PCIE_CLKGATE_CON(0), 1, GFLAGS), + COMPOSITE_NOMUX(CLK_PPLL_50M_MATRIX, "clk_ppll_50m_src", "ppll", CLK_IS_CRITICAL, + RK3528_PCIE_CLKSEL_CON(1), 7, 5, DFLAGS, + RK3528_PCIE_CLKGATE_CON(0), 2, GFLAGS), + MUX(CLK_REF_PCIE_INNER_PHY, "clk_ref_pcie_inner_phy", clk_ref_pcie_inner_phy_p, 0, + RK3528_PCIE_CLKSEL_CON(1), 13, 1, MFLAGS), + FACTOR(CLK_REF_PCIE_100M_PHY, "clk_ref_pcie_100m_phy", "clk_ppll_100m_src", 0, 1, 1), + + /* gmac */ + FACTOR(CLK_GMAC1_RMII_VPU, "clk_gmac1_50m", "clk_ppll_50m_src", 0, 1, 1), + FACTOR(CLK_GMAC1_SRC_VPU, "clk_gmac1_125m", "clk_ppll_125m_src", 0, 1, 1), + + /* they are orphans */ + DIV(CLK_GMAC0_SRC, "clk_gmac0_src", "clk_gmac0_io_i", 0, + RK3528_CLKSEL_CON(84), 3, 6, DFLAGS), + GATE(CLK_GMAC0_TX, "clk_gmac0_tx", "clk_gmac0_src", 0, + RK3528_CLKGATE_CON(41), 13, GFLAGS), + GATE(CLK_GMAC0_RX, "clk_gmac0_rx", "clk_gmac0_src", 0, + RK3528_CLKGATE_CON(41), 14, GFLAGS), + GATE(CLK_GMAC0_RMII_50M, "clk_gmac0_rmii_50m", "clk_gmac0_io_i", 0, + RK3528_CLKGATE_CON(41), 12, GFLAGS), + GATE(CLK_SCRKEYGEN, "clk_scrkeygen", "clk_pmupvtm_out", 0, + RK3528_PMU_CLKGATE_CON(2), 0, GFLAGS), + GATE(CLK_PVTM_OSCCHK, "clk_pvtm_oscchk", "clk_pmupvtm_out", 0, + RK3528_PMU_CLKGATE_CON(2), 1, GFLAGS), +}; + +static struct rockchip_clk_branch rk3528_grf_clk_branches[] __initdata = { + MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "cclk_src_sdmmc0", RK3528_SDMMC_CON0, 1), + MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "cclk_src_sdmmc0", RK3528_SDMMC_CON1, 1), + MMC(SCLK_SDIO0_DRV, "sdio0_drv", "cclk_src_sdio0", RK3528_SDIO0_CON0, 1), + MMC(SCLK_SDIO0_SAMPLE, "sdio0_sample", "cclk_src_sdio0", RK3528_SDIO0_CON1, 1), + MMC(SCLK_SDIO1_DRV, "sdio1_drv", "cclk_src_sdio1", RK3528_SDIO1_CON0, 1), + MMC(SCLK_SDIO1_SAMPLE, "sdio1_sample", "cclk_src_sdio1", RK3528_SDIO1_CON1, 1), +}; + +static void __iomem *rk3528_cru_base; + +static void __init rk3528_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + struct clk **clks; + + reg_base = of_iomap(np, 0); + if (!reg_base) { + pr_err("%s: could not map cru region\n", __func__); + return; + } + + rk3528_cru_base = reg_base; + + ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip clk init failed\n", __func__); + iounmap(reg_base); + return; + } + clks = ctx->clk_data.clks; + + rockchip_clk_register_plls(ctx, rk3528_pll_clks, + ARRAY_SIZE(rk3528_pll_clks), + RK3528_GRF_SOC_STATUS0); + + rockchip_clk_register_armclk(ctx, ARMCLK, "armclk", + mux_armclk_p, ARRAY_SIZE(mux_armclk_p), + &rk3528_cpuclk_data, rk3528_cpuclk_rates, + ARRAY_SIZE(rk3528_cpuclk_rates)); + rockchip_clk_register_branches(ctx, rk3528_clk_branches, + ARRAY_SIZE(rk3528_clk_branches)); + + rockchip_register_softrst(np, 47, reg_base + RK3528_SOFTRST_CON(0), + ROCKCHIP_SOFTRST_HIWORD_MASK); + rockchip_register_restart_notifier(ctx, RK3528_GLB_SRST_FST, NULL); + + rockchip_clk_of_add_provider(np, ctx); +} + +CLK_OF_DECLARE(rk3528_cru, "rockchip,rk3528-cru", rk3528_clk_init); + +static void __init rk3528_grf_clk_init(struct device_node *np) +{ + struct rockchip_clk_provider *ctx; + void __iomem *reg_base; + + reg_base = of_iomap(of_get_parent(np), 0); + if (!reg_base) { + pr_err("%s: could not map cru grf region\n", __func__); + return; + } + + ctx = rockchip_clk_init(np, reg_base, CLK_NR_GRF_CLKS); + if (IS_ERR(ctx)) { + pr_err("%s: rockchip grf clk init failed\n", __func__); + return; + } + + rockchip_clk_register_branches(ctx, rk3528_grf_clk_branches, + ARRAY_SIZE(rk3528_grf_clk_branches)); + + rockchip_clk_of_add_provider(np, ctx); +} + +CLK_OF_DECLARE(rk3528_grf_cru, "rockchip,rk3528-grf-cru", rk3528_grf_clk_init); diff --git a/target/linux/rockchip/files/drivers/pci/controller/dwc/pcie-dw-rkvendor.c b/target/linux/rockchip/files/drivers/pci/controller/dwc/pcie-dw-rkvendor.c new file mode 100644 index 000000000..228525cb5 --- /dev/null +++ b/target/linux/rockchip/files/drivers/pci/controller/dwc/pcie-dw-rkvendor.c @@ -0,0 +1,1538 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PCIe host controller driver for Rockchip SoCs. + * + * Copyright (C) 2021 Rockchip Electronics Co., Ltd. + * http://www.rock-chips.com + * + * Author: Simon Xue + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-designware.h" +#include "rockchip-pcie-dma.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 + +#define PCIE_CAP_LINK_CONTROL2_LINK_STATUS 0xa0 + +#define PCIE_CLIENT_INTR_STATUS_MSG_RX 0x04 +#define PME_TO_ACK (BIT(9) | 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 BIT(3) +#define PCIE_CLIENT_MSG_GEN 0x34 +#define PME_TURN_OFF (BIT(4) | BIT(20)) +#define PCIE_CLIENT_GENERAL_DEBUG 0x104 +#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 +#define PCIE_LTSSM_APP_DLY1_EN BIT(0) +#define PCIE_LTSSM_APP_DLY2_EN BIT(1) +#define PCIE_LTSSM_APP_DLY1_DONE BIT(2) +#define PCIE_LTSSM_APP_DLY2_DONE BIT(3) +#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) +#define PCIE_CLIENT_LTSSM_STATUS 0x300 +#define SMLH_LINKUP BIT(16) +#define RDLH_LINKUP 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_PL_ORDER_RULE_CTRL_OFF 0x8B4 +#define RK_PCIE_L2_TMOUT_US 5000 +#define RK_PCIE_HOTRESET_TMOUT_US 10000 +#define PORT_LOGIC_LTSSM_STATE_L2(ltssm) \ + ((ltssm & PORT_LOGIC_LTSSM_STATE_MASK) == 0x15) +#define RK_PCIE_ENUM_HW_RETRYIES 2 + +#define PORT_LINK_LPBK_ENABLE BIT(2) + +struct rk_pcie { + struct dw_pcie *pci; + void __iomem *dbi_base; + void __iomem *apb_base; + struct phy *phy; + struct clk_bulk_data *clks; + struct reset_control *rsts; + unsigned int clk_cnt; + struct gpio_desc *rst_gpio; + u32 perst_inactive_ms; + struct dma_trx_obj *dma_obj; + bool in_suspend; + bool skip_scan_in_resume; + bool is_signal_test; + bool bifurcation; + bool supports_clkreq; + struct regulator *vpcie3v3; + struct irq_domain *irq_domain; + raw_spinlock_t intx_lock; + u16 aspm; + u32 l1ss_ctl1; + struct dentry *debugfs; + struct workqueue_struct *hot_rst_wq; + struct work_struct hot_rst_work; + u32 comp_prst[2]; + u32 intx; +}; + +#define to_rk_pcie(x) dev_get_drvdata((x)->dev) +static int rk_pcie_disable_power(struct rk_pcie *rk_pcie); +static int rk_pcie_enable_power(struct rk_pcie *rk_pcie); + +static int rk_pcie_read(void __iomem *addr, int size, u32 *val) +{ + if ((uintptr_t)addr & (size - 1)) { + *val = 0; + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + if (size == 4) { + *val = readl(addr); + } else if (size == 2) { + *val = readw(addr); + } else if (size == 1) { + *val = readb(addr); + } else { + *val = 0; + return PCIBIOS_BAD_REGISTER_NUMBER; + } + + return PCIBIOS_SUCCESSFUL; +} + +static int rk_pcie_write(void __iomem *addr, int size, u32 val) +{ + if ((uintptr_t)addr & (size - 1)) + return PCIBIOS_BAD_REGISTER_NUMBER; + + if (size == 4) + writel(val, addr); + else if (size == 2) + writew(val, addr); + else if (size == 1) + writeb(val, addr); + else + return PCIBIOS_BAD_REGISTER_NUMBER; + + return PCIBIOS_SUCCESSFUL; +} + +static u32 __rk_pcie_read_apb(struct rk_pcie *rk_pcie, void __iomem *base, + u32 reg, size_t size) +{ + int ret; + u32 val; + + ret = rk_pcie_read(base + reg, size, &val); + if (ret) + dev_err(rk_pcie->pci->dev, "Read APB address failed\n"); + + return val; +} + +static void __rk_pcie_write_apb(struct rk_pcie *rk_pcie, void __iomem *base, + u32 reg, size_t size, u32 val) +{ + int ret; + + ret = rk_pcie_write(base + reg, size, val); + if (ret) + dev_err(rk_pcie->pci->dev, "Write APB address failed\n"); +} + +static inline u32 rk_pcie_readl_apb(struct rk_pcie *rk_pcie, u32 reg) +{ + return __rk_pcie_read_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4); +} + +static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg, + u32 val) +{ + __rk_pcie_write_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4, val); +} + +#if defined(CONFIG_PCIEASPM) +static void disable_aspm_l1ss(struct rk_pcie *rk_pcie) +{ + u32 val, cfg_link_cap_l1sub; + + val = dw_pcie_find_ext_capability(rk_pcie->pci, PCI_EXT_CAP_ID_L1SS); + if (!val) { + dev_err(rk_pcie->pci->dev, "can't find l1ss cap\n"); + + return; + } + + cfg_link_cap_l1sub = val + PCI_L1SS_CAP; + + val = dw_pcie_readl_dbi(rk_pcie->pci, cfg_link_cap_l1sub); + val &= ~(PCI_L1SS_CAP_ASPM_L1_1 | PCI_L1SS_CAP_ASPM_L1_2 | PCI_L1SS_CAP_L1_PM_SS); + dw_pcie_writel_dbi(rk_pcie->pci, cfg_link_cap_l1sub, val); +} +#else +static inline void disable_aspm_l1ss(struct rk_pcie *rk_pcie) { return; } +#endif + +static inline void rk_pcie_set_mode(struct rk_pcie *rk_pcie) +{ + if (rk_pcie->supports_clkreq) { + /* Application is ready to have reference clock removed */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_POWER, 0x00010001); + } else { + /* Pull down CLKREQ# to assert the connecting CLOCK_GEN OE */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_POWER, 0x30011000); + disable_aspm_l1ss(rk_pcie); + } + rk_pcie_writel_apb(rk_pcie, 0x0, 0xf00040); +} + +static inline void rk_pcie_link_status_clear(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_GENERAL_DEBUG, 0x0); +} + +static inline void rk_pcie_disable_ltssm(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, 0x0, 0xc0008); +} + +static inline void rk_pcie_enable_ltssm(struct rk_pcie *rk_pcie) +{ + rk_pcie_writel_apb(rk_pcie, 0x0, 0xC000C); +} + +static int rk_pcie_link_up(struct dw_pcie *pci) +{ + struct rk_pcie *rk_pcie = to_rk_pcie(pci); + u32 val; + + val = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS); + if ((val & (RDLH_LINKUP | SMLH_LINKUP)) == 0x30000) + return 1; + + return 0; +} + +static void rk_pcie_enable_debug(struct rk_pcie *rk_pcie) +{ + if (!IS_ENABLED(CONFIG_DEBUG_FS)) + return; + + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_PTN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D0, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_TRN_HIT_D1, + PCIE_CLIENT_DBG_TRANSITION_DATA); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_DBG_FIFO_MODE_CON, + PCIE_CLIENT_DBF_EN); +} + +static int rk_pcie_establish_link(struct dw_pcie *pci) +{ + struct rk_pcie *rk_pcie = to_rk_pcie(pci); + int hw_retries = 0; + int retries; + u32 ltssm; + + /* + * 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)) { + dev_err(pci->dev, "link is already up\n"); + return 0; + } + + for (hw_retries = 0; hw_retries < RK_PCIE_ENUM_HW_RETRYIES; hw_retries++) { + /* Rest the device */ + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); + + rk_pcie_disable_ltssm(rk_pcie); + rk_pcie_link_status_clear(rk_pcie); + rk_pcie_enable_debug(rk_pcie); + + /* Enable client reset or link down interrupt */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0x40000); + + /* Enable LTSSM */ + rk_pcie_enable_ltssm(rk_pcie); + + /* + * 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, please add more in DT node by add rockchip,perst-inactive-ms. + */ + msleep(rk_pcie->perst_inactive_ms); + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 1); + + /* + * Add this 1ms delay because we observe link is always up stably after it and + * could help us save 20ms for scanning devices. + */ + usleep_range(1000, 1100); + + for (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. + */ + msleep(50); + /* In case link drop after linkup, double check it */ + if (dw_pcie_link_up(pci)) { + dev_info(pci->dev, "PCIe Link up, LTSSM is 0x%x\n", + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); + return 0; + } + } + + dev_info_ratelimited(pci->dev, "PCIe Linking... LTSSM is 0x%x\n", + rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS)); + msleep(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 = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_LTSSM_STATUS); + dev_err(pci->dev, "PCIe Link Fail, LTSSM is 0x%x, hw_retries=%d\n", ltssm, hw_retries); + if (ltssm >= 3 && !rk_pcie->is_signal_test) { + rk_pcie_disable_power(rk_pcie); + msleep(1000); + rk_pcie_enable_power(rk_pcie); + } else { + break; + } + } + + return rk_pcie->is_signal_test == true ? 0 : -EINVAL; +} + +static bool rk_pcie_udma_enabled(struct rk_pcie *rk_pcie) +{ + return dw_pcie_readl_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_CTRL_OFF); +} + +static int rk_pcie_init_dma_trx(struct rk_pcie *rk_pcie) +{ + if (!rk_pcie_udma_enabled(rk_pcie)) + return 0; + + rk_pcie->dma_obj = pcie_dw_dmatest_register(rk_pcie->pci->dev, true); + if (IS_ERR(rk_pcie->dma_obj)) { + dev_err(rk_pcie->pci->dev, "failed to prepare dmatest\n"); + return -EINVAL; + } + + /* Enable client write and read interrupt */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xc000000); + + /* Enable core write interrupt */ + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_INT_MASK, + 0x0); + /* Enable core read interrupt */ + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_INT_MASK, + 0x0); + return 0; +} + +static struct dw_pcie_host_ops rk_pcie_host_ops; + +static int rk_add_pcie_port(struct rk_pcie *rk_pcie, struct platform_device *pdev) +{ + int ret; + struct dw_pcie *pci = rk_pcie->pci; + struct dw_pcie_rp *pp = &pci->pp; + struct device *dev = pci->dev; + + pp->ops = &rk_pcie_host_ops; + + ret = dw_pcie_host_init(pp); + if (ret) { + dev_err(dev, "failed to initialize host\n"); + return ret; + } + + /* Disable BAR0 BAR1 */ + dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_0, 0x0); + dw_pcie_writel_dbi2(pci, PCI_BASE_ADDRESS_1, 0x0); + + return 0; +} + +static int rk_pcie_clk_init(struct rk_pcie *rk_pcie) +{ + struct device *dev = rk_pcie->pci->dev; + int ret; + + rk_pcie->clk_cnt = devm_clk_bulk_get_all(dev, &rk_pcie->clks); + if (rk_pcie->clk_cnt < 1) + return -ENODEV; + + ret = clk_bulk_prepare_enable(rk_pcie->clk_cnt, rk_pcie->clks); + if (ret) { + dev_err(dev, "failed to prepare enable pcie bulk clks: %d\n", ret); + return ret; + } + + return 0; +} + +static int rk_pcie_resource_get(struct platform_device *pdev, + struct rk_pcie *rk_pcie) +{ + struct resource *dbi_base; + struct resource *apb_base; + + dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pcie-dbi"); + if (!dbi_base) { + dev_err(&pdev->dev, "get pcie-dbi failed\n"); + return -ENODEV; + } + + rk_pcie->dbi_base = devm_ioremap_resource(&pdev->dev, dbi_base); + if (IS_ERR(rk_pcie->dbi_base)) + return PTR_ERR(rk_pcie->dbi_base); + + rk_pcie->pci->dbi_base = rk_pcie->dbi_base; + rk_pcie->pci->dbi_base2 = rk_pcie->pci->dbi_base + SZ_1M; + + apb_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "pcie-apb"); + if (!apb_base) { + dev_err(&pdev->dev, "get pcie-apb failed\n"); + return -ENODEV; + } + rk_pcie->apb_base = devm_ioremap_resource(&pdev->dev, apb_base); + if (IS_ERR(rk_pcie->apb_base)) + return PTR_ERR(rk_pcie->apb_base); + + /* + * Rest the device before enabling power because some of the + * platforms may use external refclk input with the some power + * rail connect to 100MHz OSC chip. So once the power is up for + * the slot and the refclk is available, which isn't quite follow + * the spec. We should make sure it is in reset state before + * everthing's ready. + */ + rk_pcie->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", + GPIOD_OUT_LOW); + if (IS_ERR(rk_pcie->rst_gpio)) { + dev_err(&pdev->dev, "invalid reset-gpios property in node\n"); + return PTR_ERR(rk_pcie->rst_gpio); + } + + if (device_property_read_u32(&pdev->dev, "rockchip,perst-inactive-ms", + &rk_pcie->perst_inactive_ms)) + rk_pcie->perst_inactive_ms = 200; + + return 0; +} + +static int rk_pcie_phy_init(struct rk_pcie *rk_pcie) +{ + int ret; + struct device *dev = rk_pcie->pci->dev; + + rk_pcie->phy = devm_phy_optional_get(dev, "pcie-phy"); + if (IS_ERR(rk_pcie->phy)) { + if (PTR_ERR(rk_pcie->phy) != -EPROBE_DEFER) + dev_err(dev, "missing phy\n"); + return PTR_ERR(rk_pcie->phy); + } + + ret = phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); + if (ret) { + dev_err(dev, "fail to set phy to rc mode, err %d\n", ret); + return ret; + } + + if (rk_pcie->bifurcation) + phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_BIFURCATION); + + ret = phy_init(rk_pcie->phy); + if (ret < 0) { + dev_err(dev, "fail to init phy, err %d\n", ret); + return ret; + } + + phy_power_on(rk_pcie->phy); + + return 0; +} + +static void rk_pcie_start_dma_rd(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off) +{ + struct rk_pcie *rk_pcie = dev_get_drvdata(obj->dev); + + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_ENB, + cur->enb.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_CTRL_LO, + cur->ctx_reg.ctrllo.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_CTRL_HI, + cur->ctx_reg.ctrlhi.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_XFERSIZE, + cur->ctx_reg.xfersize); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_SAR_PTR_LO, + cur->ctx_reg.sarptrlo); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_SAR_PTR_HI, + cur->ctx_reg.sarptrhi); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_DAR_PTR_LO, + cur->ctx_reg.darptrlo); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_RD_DAR_PTR_HI, + cur->ctx_reg.darptrhi); + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_RD_DOORBELL, + cur->start.asdword); +} + +static void rk_pcie_start_dma_wr(struct dma_trx_obj *obj, struct dma_table *cur, int ctr_off) +{ + struct rk_pcie *rk_pcie = dev_get_drvdata(obj->dev); + + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_ENB, + cur->enb.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_CTRL_LO, + cur->ctx_reg.ctrllo.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_CTRL_HI, + cur->ctx_reg.ctrlhi.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_XFERSIZE, + cur->ctx_reg.xfersize); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_SAR_PTR_LO, + cur->ctx_reg.sarptrlo); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_SAR_PTR_HI, + cur->ctx_reg.sarptrhi); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_DAR_PTR_LO, + cur->ctx_reg.darptrlo); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_DAR_PTR_HI, + cur->ctx_reg.darptrhi); + dw_pcie_writel_dbi(rk_pcie->pci, ctr_off + PCIE_DMA_WR_WEILO, + cur->weilo.asdword); + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + PCIE_DMA_WR_DOORBELL, + cur->start.asdword); +} + +static void rk_pcie_start_dma_dwc(struct dma_trx_obj *obj, struct dma_table *table) +{ + int dir = table->dir; + int chn = table->chn; + + int ctr_off = PCIE_DMA_OFFSET + chn * 0x200; + + if (dir == DMA_FROM_BUS) + rk_pcie_start_dma_rd(obj, table, ctr_off); + else if (dir == DMA_TO_BUS) + rk_pcie_start_dma_wr(obj, table, ctr_off); +} + +static void rk_pcie_config_dma_dwc(struct dma_table *table) +{ + table->enb.enb = 0x1; + table->ctx_reg.ctrllo.lie = 0x1; + table->ctx_reg.ctrllo.rie = 0x0; + table->ctx_reg.ctrllo.td = 0x1; + table->ctx_reg.ctrlhi.asdword = 0x0; + table->ctx_reg.xfersize = table->buf_size; + if (table->dir == DMA_FROM_BUS) { + table->ctx_reg.sarptrlo = (u32)(table->bus & 0xffffffff); + table->ctx_reg.sarptrhi = (u32)(table->bus >> 32); + table->ctx_reg.darptrlo = (u32)(table->local & 0xffffffff); + table->ctx_reg.darptrhi = (u32)(table->local >> 32); + } else if (table->dir == DMA_TO_BUS) { + table->ctx_reg.sarptrlo = (u32)(table->local & 0xffffffff); + table->ctx_reg.sarptrhi = (u32)(table->local >> 32); + table->ctx_reg.darptrlo = (u32)(table->bus & 0xffffffff); + table->ctx_reg.darptrhi = (u32)(table->bus >> 32); + } + table->weilo.weight0 = 0x0; + table->start.stop = 0x0; + table->start.chnl = table->chn; +} + +static void rk_pcie_hot_rst_work(struct work_struct *work) +{ + struct rk_pcie *rk_pcie = container_of(work, struct rk_pcie, hot_rst_work); + u32 val, status; + int ret; + + /* Setup command register */ + val = dw_pcie_readl_dbi(rk_pcie->pci, PCI_COMMAND); + val &= 0xffff0000; + val |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER | PCI_COMMAND_SERR; + dw_pcie_writel_dbi(rk_pcie->pci, PCI_COMMAND, val); + + if (rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL) & PCIE_LTSSM_APP_DLY2_EN) { + ret = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS, + status, ((status & 0x3F) == 0), 100, RK_PCIE_HOTRESET_TMOUT_US); + if (ret) + dev_err(rk_pcie->pci->dev, "wait for detect quiet failed!\n"); + + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, + (PCIE_LTSSM_APP_DLY2_DONE) | ((PCIE_LTSSM_APP_DLY2_DONE) << 16)); + } +} + +static irqreturn_t rk_pcie_sys_irq_handler(int irq, void *arg) +{ + struct rk_pcie *rk_pcie = arg; + u32 chn; + union int_status status; + union int_clear clears; + u32 reg; + + status.asdword = dw_pcie_readl_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_WR_INT_STATUS); + for (chn = 0; chn < PCIE_DMA_CHANEL_MAX_NUM; chn++) { + if (status.donesta & BIT(chn)) { + clears.doneclr = 0x1 << chn; + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_WR_INT_CLEAR, clears.asdword); + if (rk_pcie->dma_obj && rk_pcie->dma_obj->cb) + rk_pcie->dma_obj->cb(rk_pcie->dma_obj, chn, DMA_TO_BUS); + } + + if (status.abortsta & BIT(chn)) { + dev_err(rk_pcie->pci->dev, "%s, abort\n", __func__); + clears.abortclr = 0x1 << chn; + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_WR_INT_CLEAR, clears.asdword); + } + } + + status.asdword = dw_pcie_readl_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_RD_INT_STATUS); + for (chn = 0; chn < PCIE_DMA_CHANEL_MAX_NUM; chn++) { + if (status.donesta & BIT(chn)) { + clears.doneclr = 0x1 << chn; + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_RD_INT_CLEAR, clears.asdword); + if (rk_pcie->dma_obj && rk_pcie->dma_obj->cb) + rk_pcie->dma_obj->cb(rk_pcie->dma_obj, chn, DMA_FROM_BUS); + } + + if (status.abortsta & BIT(chn)) { + dev_err(rk_pcie->pci->dev, "%s, abort\n", __func__); + clears.abortclr = 0x1 << chn; + dw_pcie_writel_dbi(rk_pcie->pci, PCIE_DMA_OFFSET + + PCIE_DMA_RD_INT_CLEAR, clears.asdword); + } + } + + reg = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC); + if (reg & BIT(2)) + queue_work(rk_pcie->hot_rst_wq, &rk_pcie->hot_rst_work); + + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MISC, reg); + + return IRQ_HANDLED; +} + +static int rk_pcie_request_sys_irq(struct rk_pcie *rk_pcie, + struct platform_device *pdev) +{ + int irq, ret; + + irq = platform_get_irq_byname(pdev, "sys"); + if (irq < 0) { + dev_err(rk_pcie->pci->dev, "missing sys IRQ resource\n"); + return -EINVAL; + } + + ret = devm_request_irq(rk_pcie->pci->dev, irq, rk_pcie_sys_irq_handler, + IRQF_SHARED, "pcie-sys", rk_pcie); + if (ret) { + dev_err(rk_pcie->pci->dev, "failed to request PCIe subsystem IRQ\n"); + return ret; + } + + return 0; +} + +static const struct of_device_id rk_pcie_of_match[] = { + { .compatible = "rockchip,rk3528-pcie", }, + { .compatible = "rockchip,rk3562-pcie", }, + { .compatible = "rockchip,rk3576-pcie", }, + {}, +}; + +MODULE_DEVICE_TABLE(of, rk_pcie_of_match); + +static const struct dw_pcie_ops dw_pcie_ops = { + .start_link = rk_pcie_establish_link, + .link_up = rk_pcie_link_up, +}; + +static void rk_pcie_fast_link_setup(struct rk_pcie *rk_pcie) +{ + u32 val; + + /* LTSSM EN ctrl mode */ + val = rk_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); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_HOT_RESET_CTRL, val); +} + +static void rk_pcie_legacy_irq_mask(struct irq_data *d) +{ + struct rk_pcie *rk_pcie = irq_data_get_irq_chip_data(d); + unsigned long flags; + + raw_spin_lock_irqsave(&rk_pcie->intx_lock, flags); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + MASK_LEGACY_INT(d->hwirq)); + raw_spin_unlock_irqrestore(&rk_pcie->intx_lock, flags); +} + +static void rk_pcie_legacy_irq_unmask(struct irq_data *d) +{ + struct rk_pcie *rk_pcie = irq_data_get_irq_chip_data(d); + unsigned long flags; + + raw_spin_lock_irqsave(&rk_pcie->intx_lock, flags); + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + UNMASK_LEGACY_INT(d->hwirq)); + raw_spin_unlock_irqrestore(&rk_pcie->intx_lock, flags); +} + +static struct irq_chip rk_pcie_legacy_irq_chip = { + .name = "rk-pcie-legacy-int", + .irq_enable = rk_pcie_legacy_irq_unmask, + .irq_disable = rk_pcie_legacy_irq_mask, + .irq_mask = rk_pcie_legacy_irq_mask, + .irq_unmask = rk_pcie_legacy_irq_unmask, + .flags = IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MASK_ON_SUSPEND, +}; + +static int rk_pcie_intx_map(struct irq_domain *domain, unsigned int irq, + irq_hw_number_t hwirq) +{ + irq_set_chip_and_handler(irq, &rk_pcie_legacy_irq_chip, handle_level_irq); + irq_set_chip_data(irq, domain->host_data); + + return 0; +} + +static const struct irq_domain_ops intx_domain_ops = { + .map = rk_pcie_intx_map, +}; + +static void rk_pcie_legacy_int_handler(struct irq_desc *desc) +{ + struct irq_chip *chip = irq_desc_get_chip(desc); + struct rk_pcie *rockchip = irq_desc_get_handler_data(desc); + struct device *dev = rockchip->pci->dev; + u32 reg; + u32 hwirq; + int ret; + + chained_irq_enter(chip, desc); + + reg = rk_pcie_readl_apb(rockchip, PCIE_CLIENT_INTR_STATUS_LEGACY); + reg = reg & 0xf; + + while (reg) { + hwirq = ffs(reg) - 1; + reg &= ~BIT(hwirq); + + ret = generic_handle_domain_irq(rockchip->irq_domain, hwirq); + if (ret) + dev_err(dev, "unexpected IRQ, INT%d\n", hwirq); + } + + chained_irq_exit(chip, desc); +} + +static int rk_pcie_init_irq_domain(struct rk_pcie *rockchip) +{ + struct device *dev = rockchip->pci->dev; + struct device_node *intc = of_get_next_child(dev->of_node, NULL); + + if (!intc) { + dev_err(dev, "missing child interrupt-controller node\n"); + return -EINVAL; + } + + raw_spin_lock_init(&rockchip->intx_lock); + rockchip->irq_domain = irq_domain_add_linear(intc, PCI_NUM_INTX, + &intx_domain_ops, rockchip); + if (!rockchip->irq_domain) { + dev_err(dev, "failed to get a INTx IRQ domain\n"); + return -EINVAL; + } + + return 0; +} + +static int rk_pcie_enable_power(struct rk_pcie *rk_pcie) +{ + int ret = 0; + struct device *dev = rk_pcie->pci->dev; + + if (IS_ERR(rk_pcie->vpcie3v3)) + return ret; + + ret = regulator_enable(rk_pcie->vpcie3v3); + if (ret) + dev_err(dev, "fail to enable vpcie3v3 regulator\n"); + + return ret; +} + +static int rk_pcie_disable_power(struct rk_pcie *rk_pcie) +{ + int ret = 0; + struct device *dev = rk_pcie->pci->dev; + + if (IS_ERR(rk_pcie->vpcie3v3)) + return ret; + + ret = regulator_disable(rk_pcie->vpcie3v3); + if (ret) + dev_err(dev, "fail to disable vpcie3v3 regulator\n"); + + return ret; +} + +#define RAS_DES_EVENT(ss, v) \ +do { \ + dw_pcie_writel_dbi(pcie->pci, cap_base + 8, v); \ + seq_printf(s, ss "0x%x\n", dw_pcie_readl_dbi(pcie->pci, cap_base + 0xc)); \ +} while (0) + +static int rockchip_pcie_rasdes_show(struct seq_file *s, void *unused) +{ + struct rk_pcie *pcie = s->private; + int cap_base; + u32 val = rk_pcie_readl_apb(pcie, PCIE_CLIENT_CDM_RASDES_TBA_INFO_CMN); + char *pm; + + if (val & BIT(6)) + pm = "In training"; + else if (val & BIT(5)) + pm = "L1.2"; + else if (val & BIT(4)) + pm = "L1.1"; + else if (val & BIT(3)) + pm = "L1"; + else if (val & BIT(2)) + pm = "L0"; + else if (val & 0x3) + pm = (val == 0x3) ? "L0s" : (val & BIT(1) ? "RX L0s" : "TX L0s"); + else + pm = "Invalid"; + + seq_printf(s, "Common event signal status: 0x%s\n", pm); + + cap_base = dw_pcie_find_ext_capability(pcie->pci, PCI_EXT_CAP_ID_VNDR); + if (!cap_base) { + dev_err(pcie->pci->dev, "Not able to find RASDES CAP!\n"); + return 0; + } + + RAS_DES_EVENT("EBUF Overflow: ", 0); + RAS_DES_EVENT("EBUF Under-run: ", 0x0010000); + RAS_DES_EVENT("Decode Error: ", 0x0020000); + RAS_DES_EVENT("Running Disparity Error: ", 0x0030000); + RAS_DES_EVENT("SKP OS Parity Error: ", 0x0040000); + RAS_DES_EVENT("SYNC Header Error: ", 0x0050000); + RAS_DES_EVENT("CTL SKP OS Parity Error: ", 0x0060000); + RAS_DES_EVENT("Detect EI Infer: ", 0x1050000); + RAS_DES_EVENT("Receiver Error: ", 0x1060000); + RAS_DES_EVENT("Rx Recovery Request: ", 0x1070000); + RAS_DES_EVENT("N_FTS Timeout: ", 0x1080000); + RAS_DES_EVENT("Framing Error: ", 0x1090000); + RAS_DES_EVENT("Deskew Error: ", 0x10a0000); + RAS_DES_EVENT("BAD TLP: ", 0x2000000); + RAS_DES_EVENT("LCRC Error: ", 0x2010000); + RAS_DES_EVENT("BAD DLLP: ", 0x2020000); + RAS_DES_EVENT("Replay Number Rollover: ", 0x2030000); + RAS_DES_EVENT("Replay Timeout: ", 0x2040000); + RAS_DES_EVENT("Rx Nak DLLP: ", 0x2050000); + RAS_DES_EVENT("Tx Nak DLLP: ", 0x2060000); + RAS_DES_EVENT("Retry TLP: ", 0x2070000); + RAS_DES_EVENT("FC Timeout: ", 0x3000000); + RAS_DES_EVENT("Poisoned TLP: ", 0x3010000); + RAS_DES_EVENT("ECRC Error: ", 0x3020000); + RAS_DES_EVENT("Unsupported Request: ", 0x3030000); + RAS_DES_EVENT("Completer Abort: ", 0x3040000); + RAS_DES_EVENT("Completion Timeout: ", 0x3050000); + + return 0; +} + +static int rockchip_pcie_rasdes_open(struct inode *inode, struct file *file) +{ + return single_open(file, rockchip_pcie_rasdes_show, + inode->i_private); +} + +static ssize_t rockchip_pcie_rasdes_write(struct file *file, + const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct seq_file *s = file->private_data; + struct rk_pcie *pcie = s->private; + char buf[32]; + int cap_base; + + if (copy_from_user(&buf, ubuf, min_t(size_t, sizeof(buf) - 1, count))) + return -EFAULT; + + cap_base = dw_pcie_find_ext_capability(pcie->pci, PCI_EXT_CAP_ID_VNDR); + if (!cap_base) { + dev_err(pcie->pci->dev, "Not able to find RASDES CAP!\n"); + return 0; + } + + if (!strncmp(buf, "enable", 6)) { + dev_info(pcie->pci->dev, "RAS DES Event: Enable ALL!\n"); + dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x1c); + dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x3); + } else if (!strncmp(buf, "disable", 7)) { + dev_info(pcie->pci->dev, "RAS DES Event: disable ALL!\n"); + dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x14); + } else if (!strncmp(buf, "clear", 5)) { + dev_info(pcie->pci->dev, "RAS DES Event: Clear ALL!\n"); + dw_pcie_writel_dbi(pcie->pci, cap_base + 8, 0x3); + } else { + dev_info(pcie->pci->dev, "Not support command!\n"); + } + + return count; +} + +static const struct file_operations rockchip_pcie_rasdes_ops = { + .owner = THIS_MODULE, + .open = rockchip_pcie_rasdes_open, + .read = seq_read, + .write = rockchip_pcie_rasdes_write, +}; + +static int rockchip_pcie_fifo_show(struct seq_file *s, void *data) +{ + struct rk_pcie *pcie = (struct rk_pcie *)dev_get_drvdata(s->private); + u32 loop; + + seq_printf(s, "ltssm = 0x%x\n", + rk_pcie_readl_apb(pcie, PCIE_CLIENT_LTSSM_STATUS)); + for (loop = 0; loop < 64; loop++) + seq_printf(s, "fifo_status = 0x%x\n", + rk_pcie_readl_apb(pcie, PCIE_CLIENT_DBG_FIFO_STATUS)); + + return 0; +} + +static void rockchip_pcie_debugfs_exit(struct rk_pcie *pcie) +{ + debugfs_remove_recursive(pcie->debugfs); + pcie->debugfs = NULL; +} + +static int rockchip_pcie_debugfs_init(struct rk_pcie *pcie) +{ + struct dentry *file; + + pcie->debugfs = debugfs_create_dir(dev_name(pcie->pci->dev), NULL); + if (!pcie->debugfs) + return -ENOMEM; + + debugfs_create_devm_seqfile(pcie->pci->dev, "dumpfifo", + pcie->debugfs, + rockchip_pcie_fifo_show); + file = debugfs_create_file("err_event", 0644, pcie->debugfs, + pcie, &rockchip_pcie_rasdes_ops); + if (!file) + goto remove; + + return 0; + +remove: + rockchip_pcie_debugfs_exit(pcie); + + return -ENOMEM; +} + +static int rk_pcie_really_probe(void *p) +{ + struct platform_device *pdev = p; + struct device *dev = &pdev->dev; + struct rk_pcie *rk_pcie; + struct dw_pcie *pci; + const struct of_device_id *match; + int irq, ret; + u32 val = 0; + + match = of_match_device(rk_pcie_of_match, dev); + if (!match) { + ret = -EINVAL; + goto release_driver; + } + + rk_pcie = devm_kzalloc(dev, sizeof(*rk_pcie), GFP_KERNEL); + if (!rk_pcie) { + ret = -ENOMEM; + goto release_driver; + } + + pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); + if (!pci) { + ret = -ENOMEM; + goto release_driver; + } + + pci->dev = dev; + pci->ops = &dw_pcie_ops; + rk_pcie->pci = pci; + + if (device_property_read_bool(dev, "rockchip,bifurcation")) + rk_pcie->bifurcation = true; + + ret = rk_pcie_resource_get(pdev, rk_pcie); + if (ret) { + dev_err(dev, "resource init failed\n"); + goto release_driver; + } + + rk_pcie->supports_clkreq = device_property_read_bool(dev, "supports-clkreq"); + +retry_regulator: + /* DON'T MOVE ME: must be enable before phy init */ + rk_pcie->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); + if (IS_ERR(rk_pcie->vpcie3v3)) { + if (PTR_ERR(rk_pcie->vpcie3v3) != -ENODEV) { + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) { + /* Deferred but in threaded context for most 10s */ + msleep(20); + if (++val < 500) + goto retry_regulator; + } + + ret = PTR_ERR(rk_pcie->vpcie3v3); + goto release_driver; + } + + dev_err(dev, "no vpcie3v3 regulator found\n"); + } + + ret = rk_pcie_enable_power(rk_pcie); + if (ret) + goto release_driver; + + ret = rk_pcie_phy_init(rk_pcie); + if (ret) { + dev_err(dev, "phy init failed\n"); + goto disable_vpcie3v3; + } + + rk_pcie->rsts = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(rk_pcie->rsts)) { + ret = PTR_ERR(rk_pcie->rsts); + dev_err(dev, "failed to get reset lines\n"); + goto disable_phy; + } + + reset_control_deassert(rk_pcie->rsts); + + ret = rk_pcie_clk_init(rk_pcie); + if (ret) { + dev_err(dev, "clock init failed\n"); + goto disable_phy; + } + + /* + * Misc interrupts was masked by default. However, they will be + * unmasked by FW before jumpping into kernel. Mask all misc interrupts, + * as we don't need to ack them before registering irq. And they will be + * unmasked later. + */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK, 0xffffffff); + + ret = rk_pcie_request_sys_irq(rk_pcie, pdev); + if (ret) { + dev_err(dev, "pcie irq init failed\n"); + goto disable_clk; + } + + platform_set_drvdata(pdev, rk_pcie); + + dw_pcie_dbi_ro_wr_en(pci); + + rk_pcie_fast_link_setup(rk_pcie); + + /* Legacy interrupt is optional */ + ret = rk_pcie_init_irq_domain(rk_pcie); + if (!ret) { + irq = platform_get_irq_byname(pdev, "legacy"); + if (irq >= 0) { + irq_set_chained_handler_and_data(irq, rk_pcie_legacy_int_handler, + rk_pcie); + /* Unmask all legacy interrupt from INTA~INTD */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + UNMASK_ALL_LEGACY_INT); + } else { + dev_err(dev, "missing legacy IRQ resource\n"); + } + } + + /* Set PCIe RC mode */ + rk_pcie_set_mode(rk_pcie); + + /* Force into loopback master mode */ + if (device_property_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 = 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 (!device_property_read_u32_array(dev, "rockchip,compliance-mode", + rk_pcie->comp_prst, 2)) { + BUG_ON(rk_pcie->comp_prst[0] > 3 || rk_pcie->comp_prst[1] > 10); + if (!rk_pcie->comp_prst[0]) { + dev_info(dev, "Auto compliance mode for SMA tool.\n"); + } else { + dev_info(dev, "compliance mode for soldered board Gen%d, P%d.\n", + rk_pcie->comp_prst[0], rk_pcie->comp_prst[1]); + val = dw_pcie_readl_dbi(pci, PCIE_CAP_LINK_CONTROL2_LINK_STATUS); + val |= 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 = true; + } + + /* Skip waiting for training to pass in system PM routine */ + if (device_property_read_bool(dev, "rockchip,skip-scan-in-resume")) + rk_pcie->skip_scan_in_resume = true; + + rk_pcie->hot_rst_wq = create_singlethread_workqueue("rk_pcie_hot_rst_wq"); + if (!rk_pcie->hot_rst_wq) { + dev_err(dev, "failed to create hot_rst workqueue\n"); + ret = -ENOMEM; + goto remove_irq_domain; + } + INIT_WORK(&rk_pcie->hot_rst_work, rk_pcie_hot_rst_work); + + ret = rk_add_pcie_port(rk_pcie, pdev); + + if (rk_pcie->is_signal_test == true) + return 0; + + if (ret) + goto remove_rst_wq; + + ret = rk_pcie_init_dma_trx(rk_pcie); + if (ret) { + dev_err(dev, "failed to add dma extension\n"); + goto remove_rst_wq; + } + + if (rk_pcie->dma_obj) { + rk_pcie->dma_obj->start_dma_func = rk_pcie_start_dma_dwc; + rk_pcie->dma_obj->config_dma_func = rk_pcie_config_dma_dwc; + } + + dw_pcie_dbi_ro_wr_dis(pci); + + device_init_wakeup(dev, true); + + /* Enable async system PM for multiports SoC */ + device_enable_async_suspend(dev); + + if (IS_ENABLED(CONFIG_DEBUG_FS)) { + ret = rockchip_pcie_debugfs_init(rk_pcie); + if (ret < 0) + dev_err(dev, "failed to setup debugfs: %d\n", ret); + + /* Enable RASDES Error event by default */ + val = dw_pcie_find_ext_capability(rk_pcie->pci, PCI_EXT_CAP_ID_VNDR); + if (!val) { + dev_err(dev, "Not able to find RASDES CAP!\n"); + return 0; + } + + dw_pcie_writel_dbi(rk_pcie->pci, val + 8, 0x1c); + dw_pcie_writel_dbi(rk_pcie->pci, val + 8, 0x3); + } + + return 0; + +remove_rst_wq: + destroy_workqueue(rk_pcie->hot_rst_wq); +remove_irq_domain: + if (rk_pcie->irq_domain) + irq_domain_remove(rk_pcie->irq_domain); +disable_clk: + clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); +disable_phy: + phy_power_off(rk_pcie->phy); + phy_exit(rk_pcie->phy); +disable_vpcie3v3: + rk_pcie_disable_power(rk_pcie); +release_driver: + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) + device_release_driver(dev); + + return ret; +} + +static int rk_pcie_probe(struct platform_device *pdev) +{ + if (IS_ENABLED(CONFIG_PCIE_RK_THREADED_INIT)) { + struct task_struct *tsk; + + tsk = kthread_run(rk_pcie_really_probe, pdev, "rk-pcie"); + if (IS_ERR(tsk)) { + dev_err(&pdev->dev, "start rk-pcie thread failed\n"); + return PTR_ERR(tsk); + } + + return 0; + } + + return rk_pcie_really_probe(pdev); +} + +#ifdef CONFIG_PCIEASPM +static void rk_pcie_downstream_dev_to_d0(struct rk_pcie *rk_pcie, bool enable) +{ + struct dw_pcie_rp *pp = &rk_pcie->pci->pp; + struct pci_bus *child, *root_bus = NULL; + struct pci_dev *pdev, *bridge; + u32 val; + + list_for_each_entry(child, &pp->bridge->bus->children, node) { + /* Bring downstream devices to D3 if they are not already in */ + if (child->parent == pp->bridge->bus) { + root_bus = child; + bridge = root_bus->self; + break; + } + } + + if (!root_bus) { + dev_err(rk_pcie->pci->dev, "Failed to find downstream devices\n"); + return; + } + + /* Save and restore root bus ASPM */ + if (enable) { + if (rk_pcie->l1ss_ctl1) + dw_pcie_writel_dbi(rk_pcie->pci, bridge->l1ss + PCI_L1SS_CTL1, rk_pcie->l1ss_ctl1); + + /* rk_pcie->aspm woule be saved in advance when enable is false */ + dw_pcie_writel_dbi(rk_pcie->pci, bridge->pcie_cap + PCI_EXP_LNKCTL, rk_pcie->aspm); + } else { + val = dw_pcie_readl_dbi(rk_pcie->pci, bridge->l1ss + PCI_L1SS_CTL1); + if (val & PCI_L1SS_CTL1_L1SS_MASK) + rk_pcie->l1ss_ctl1 = val; + else + rk_pcie->l1ss_ctl1 = 0; + + val = dw_pcie_readl_dbi(rk_pcie->pci, bridge->pcie_cap + PCI_EXP_LNKCTL); + rk_pcie->aspm = val & PCI_EXP_LNKCTL_ASPMC; + val &= ~(PCI_EXP_LNKCAP_ASPM_L1 | PCI_EXP_LNKCAP_ASPM_L0S); + dw_pcie_writel_dbi(rk_pcie->pci, bridge->pcie_cap + PCI_EXP_LNKCTL, val); + } + + list_for_each_entry(pdev, &root_bus->devices, bus_list) { + if (PCI_SLOT(pdev->devfn) == 0) { + if (pci_set_power_state(pdev, PCI_D0)) + dev_err(rk_pcie->pci->dev, + "Failed to transition %s to D3hot state\n", + dev_name(&pdev->dev)); + if (enable) { + if (rk_pcie->l1ss_ctl1) { + pci_read_config_dword(pdev, pdev->l1ss + PCI_L1SS_CTL1, &val); + val &= ~PCI_L1SS_CTL1_L1SS_MASK; + val |= (rk_pcie->l1ss_ctl1 & PCI_L1SS_CTL1_L1SS_MASK); + pci_write_config_dword(pdev, pdev->l1ss + PCI_L1SS_CTL1, val); + } + + pcie_capability_clear_and_set_word(pdev, PCI_EXP_LNKCTL, + PCI_EXP_LNKCTL_ASPMC, rk_pcie->aspm); + } else { + pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1); + } + } + } +} +#endif + +static int __maybe_unused rockchip_dw_pcie_suspend(struct device *dev) +{ + struct rk_pcie *rk_pcie = dev_get_drvdata(dev); + struct dw_pcie *pci = rk_pcie->pci; + int ret = 0; + u32 status; + + /* + * 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_wr_dis(rk_pcie->pci); + + rk_pcie_link_status_clear(rk_pcie); + + /* 2. Broadcast PME_Turn_Off Message */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_MSG_GEN, PME_TURN_OFF); + ret = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_MSG_GEN, + status, !(status & BIT(4)), 20, RK_PCIE_L2_TMOUT_US); + if (ret) { + dev_err(dev, "Failed to send PME_Turn_Off\n"); + goto no_l2; + } + + /* 3. Wait for PME_TO_Ack */ + ret = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_INTR_STATUS_MSG_RX, + status, status & BIT(9), 20, RK_PCIE_L2_TMOUT_US); + if (ret) { + dev_err(dev, "Failed to receive PME_TO_Ack\n"); + goto no_l2; + } + + /* 4. Clear PME_TO_Ack and Wait for ready to enter L23 message */ + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_STATUS_MSG_RX, PME_TO_ACK); + ret = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_POWER, + status, status & READY_ENTER_L23, 20, RK_PCIE_L2_TMOUT_US); + if (ret) { + dev_err(dev, "Failed to ready to enter L23\n"); + goto no_l2; + } + + /* 5. Check we are in L2 */ + ret = readl_poll_timeout(rk_pcie->apb_base + PCIE_CLIENT_LTSSM_STATUS, + status, PORT_LOGIC_LTSSM_STATE_L2(status), 20, RK_PCIE_L2_TMOUT_US); + if (ret) + dev_err(pci->dev, "Link isn't in L2 idle!\n"); + +no_l2: + rk_pcie_disable_ltssm(rk_pcie); + + ret = phy_validate(rk_pcie->phy, PHY_TYPE_PCIE, 0, NULL); + if (ret && ret != -EOPNOTSUPP) { + dev_err(dev, "PHY is reused by other controller, check the dts!\n"); + return ret; + } + + /* make sure assert phy success */ + usleep_range(200, 300); + + phy_power_off(rk_pcie->phy); + phy_exit(rk_pcie->phy); + + rk_pcie->intx = rk_pcie_readl_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY); + + clk_bulk_disable_unprepare(rk_pcie->clk_cnt, rk_pcie->clks); + + rk_pcie->in_suspend = true; + + gpiod_set_value_cansleep(rk_pcie->rst_gpio, 0); + ret = rk_pcie_disable_power(rk_pcie); + + return ret; +} + +static int __maybe_unused rockchip_dw_pcie_resume(struct device *dev) +{ + struct rk_pcie *rk_pcie = dev_get_drvdata(dev); + int ret; + + reset_control_assert(rk_pcie->rsts); + udelay(10); + reset_control_deassert(rk_pcie->rsts); + + ret = rk_pcie_enable_power(rk_pcie); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(rk_pcie->clk_cnt, rk_pcie->clks); + if (ret) { + dev_err(dev, "failed to prepare enable pcie bulk clks: %d\n", ret); + return ret; + } + + ret = phy_set_mode_ext(rk_pcie->phy, PHY_MODE_PCIE, PHY_MODE_PCIE_RC); + if (ret) { + dev_err(dev, "fail to set phy to rc mode, err %d\n", ret); + return ret; + } + + ret = phy_init(rk_pcie->phy); + if (ret < 0) { + dev_err(dev, "fail to init phy, err %d\n", ret); + return ret; + } + + phy_power_on(rk_pcie->phy); + + dw_pcie_dbi_ro_wr_en(rk_pcie->pci); + + rk_pcie_fast_link_setup(rk_pcie); + + /* Set PCIe RC mode */ + rk_pcie_set_mode(rk_pcie); + + dw_pcie_setup_rc(&rk_pcie->pci->pp); + + rk_pcie_writel_apb(rk_pcie, PCIE_CLIENT_INTR_MASK_LEGACY, + rk_pcie->intx | 0xffff0000); + + ret = rk_pcie_establish_link(rk_pcie->pci); + if (ret) { + dev_err(dev, "failed to establish pcie link\n"); + goto err; + } + + dw_pcie_dbi_ro_wr_dis(rk_pcie->pci); + rk_pcie->in_suspend = false; + + return 0; +err: + rk_pcie_disable_power(rk_pcie); + + return ret; +} + +#ifdef CONFIG_PCIEASPM +static int rockchip_dw_pcie_prepare(struct device *dev) +{ + struct rk_pcie *rk_pcie = dev_get_drvdata(dev); + + dw_pcie_dbi_ro_wr_en(rk_pcie->pci); + rk_pcie_downstream_dev_to_d0(rk_pcie, false); + dw_pcie_dbi_ro_wr_dis(rk_pcie->pci); + + return 0; +} + +static void rockchip_dw_pcie_complete(struct device *dev) +{ + struct rk_pcie *rk_pcie = dev_get_drvdata(dev); + + dw_pcie_dbi_ro_wr_en(rk_pcie->pci); + rk_pcie_downstream_dev_to_d0(rk_pcie, true); + dw_pcie_dbi_ro_wr_dis(rk_pcie->pci); +} +#endif + +static const struct dev_pm_ops rockchip_dw_pcie_pm_ops = { +#ifdef CONFIG_PCIEASPM + .prepare = rockchip_dw_pcie_prepare, + .complete = rockchip_dw_pcie_complete, +#endif + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_dw_pcie_suspend, + rockchip_dw_pcie_resume) +}; + +static struct platform_driver rk_plat_pcie_driver = { + .driver = { + .name = "rk-pcie", + .of_match_table = rk_pcie_of_match, + .suppress_bind_attrs = true, + .pm = &rockchip_dw_pcie_pm_ops, + }, + .probe = rk_pcie_probe, +}; + +module_platform_driver(rk_plat_pcie_driver); + +MODULE_AUTHOR("Simon Xue "); +MODULE_DESCRIPTION("RockChip PCIe Controller driver"); +MODULE_LICENSE("GPL v2"); diff --git a/target/linux/rockchip/files/drivers/pci/controller/dwc/rockchip-pcie-dma.h b/target/linux/rockchip/files/drivers/pci/controller/dwc/rockchip-pcie-dma.h new file mode 100644 index 000000000..de4fc419b --- /dev/null +++ b/target/linux/rockchip/files/drivers/pci/controller/dwc/rockchip-pcie-dma.h @@ -0,0 +1,269 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2018 Rockchip Electronics Co., Ltd. + */ +#ifndef __SOC_ROCKCHIP_PCIE_DMA_TRX_H +#define __SOC_ROCKCHIP_PCIE_DMA_TRX_H + +#include + +#define PCIE_DMA_TABLE_NUM 32 + +#define PCIE_DMA_TRX_TYPE_NUM 3 + +#define PCIE_DMA_CHN0 0x0 +#define PCIE_DMA_CHN1 0x1 +#define PCIE_DMA_DEFAULT_CHN PCIE_DMA_CHN0 + +#define PCIE_DMA_DATA_SND_TABLE_OFFSET 0x0 +#define PCIE_DMA_DATA_RCV_ACK_TABLE_OFFSET 0x8 +#define PCIE_DMA_DATA_FREE_ACK_TABLE_OFFSET 0x10 +#define PCIE_DMA_DATA_READ_REMOTE_TABLE_OFFSET 0x18 + +/* DMA linked list register filed */ +#define PCIE_DWC_DMA_CB BIT(0) +#define PCIE_DWC_DMA_TCB BIT(1) +#define PCIE_DWC_DMA_LLP BIT(2) +#define PCIE_DWC_DMA_LIE BIT(3) +#define PCIE_DWC_DMA_RIE BIT(4) +#define PCIE_DWC_DMA_CCS BIT(8) +#define PCIE_DWC_DMA_LLE BIT(9) + +#define SET_LL_32(ll, value) \ + writel(value, ll) + +#define SET_LL_64(ll, value) \ + writeq(value, ll) + +enum dma_dir { + DMA_FROM_BUS, + DMA_TO_BUS, +}; + +enum dma_mode { + RK_PCIE_DMA_BLOCK, + RK_PCIE_DMA_LL, +}; + +/** + * The Channel Control Register for read and write. + */ +union chan_ctrl_lo { + struct { + u32 cb :1; // 0 + u32 tcb :1; // 1 + u32 llp :1; // 2 + u32 lie :1; // 3 + u32 rie :1; // 4 + u32 cs :2; // 5:6 + u32 rsvd1 :1; // 7 + u32 ccs :1; // 8 + u32 llen :1; // 9 + u32 b_64s :1; // 10 + u32 b_64d :1; // 11 + u32 pf :5; // 12:16 + u32 rsvd2 :7; // 17:23 + u32 sn :1; // 24 + u32 ro :1; // 25 + u32 td :1; // 26 + u32 tc :3; // 27:29 + u32 at :2; // 30:31 + }; + u32 asdword; +}; + +/** + * The Channel Control Register high part for read and write. + */ +union chan_ctrl_hi { + struct { + u32 vfenb :1; // 0 + u32 vfunc :8; // 1-8 + u32 rsvd0 :23; // 9-31 + }; + u32 asdword; +}; + +/** + * The Channel Weight Register. + */ +union weight { + struct { + u32 weight0 :5; // 0:4 + u32 weight1 :5; // 5:9 + u32 weight2 :5; // 10:14 + u32 weight3 :5; // 15:19 + u32 rsvd :12; // 20:31 + }; + u32 asdword; +}; + +/** + * The Doorbell Register for read and write. + */ +union db { + struct { + u32 chnl :3; // 0 + u32 reserved0 :28; // 3:30 + u32 stop :1; // 31 + }; + u32 asdword; +}; + +/** + * The Context Registers for read and write. + */ +struct ctx_regs { + union chan_ctrl_lo ctrllo; + union chan_ctrl_hi ctrlhi; + u32 xfersize; + u32 sarptrlo; + u32 sarptrhi; + u32 darptrlo; + u32 darptrhi; +}; + +/** + * The Enable Register for read and write. + */ +union enb { + struct { + u32 enb :1; // 0 + u32 reserved0 :31; // 1:31 + }; + u32 asdword; +}; + +/** + * The Interrupt Status Register for read and write. + */ +union int_status { + struct { + u32 donesta :8; + u32 rsvd0 :8; + u32 abortsta :8; + u32 rsvd1 :8; + }; + u32 asdword; +}; + +/** + * The Interrupt Clear Register for read and write. + */ +union int_clear { + struct { + u32 doneclr :8; + u32 rsvd0 :8; + u32 abortclr :8; + u32 rsvd1 :8; + }; + u32 asdword; +}; + +struct dma_table { + u32 *descs; + int chn; + phys_addr_t phys_descs; + u32 dir; + u32 type; + struct list_head tbl_node; + union enb enb; + struct ctx_regs ctx_reg; + union weight weilo; + union weight weihi; + union db start; + phys_addr_t local; + phys_addr_t bus; + size_t buf_size; + u32 dma_mode; +}; + +struct rk_edma_lli { + u32 control; + u32 transfer_size; + union { + u64 reg; + struct { + u32 lsb; + u32 msb; + }; + } sar; + union { + u64 reg; + struct { + u32 lsb; + u32 msb; + }; + } dar; +} __packed; + +struct rk_edma_llp { + u32 control; + u32 reserved; + union { + u64 reg; + struct { + u32 lsb; + u32 msb; + }; + } llp; +} __packed; + +struct dma_trx_obj { + struct device *dev; + int loop_count; + int loop_count_threshold; + void *local_mem_base; + phys_addr_t local_mem_start; + size_t local_mem_size; + phys_addr_t remote_mem_start; + void *region_base; + phys_addr_t region_start; + size_t region_size; + int dma_free; + unsigned long local_write_available; + unsigned long local_read_available; + unsigned long remote_write_available; + spinlock_t tbl_list_lock; /* lock dma table */ + struct list_head tbl_list; + struct work_struct dma_trx_work; + wait_queue_head_t event_queue; + struct workqueue_struct *dma_trx_wq; + struct dma_table *table[PCIE_DMA_TABLE_NUM]; + struct dma_table *cur; + struct hrtimer scan_timer; + int busno; + void *priv; + struct completion done; + int ref_count; + struct mutex count_mutex; + unsigned long irq_num; + struct dentry *pcie_root; + struct pcie_misc_dev *pcie_dev; + void (*start_dma_func)(struct dma_trx_obj *obj, struct dma_table *table); + void (*config_dma_func)(struct dma_table *table); + int (*get_dma_status)(struct dma_trx_obj *obj, u8 chn, enum dma_dir dir); + int (*cb)(struct dma_trx_obj *obj, u32 chn, enum dma_dir dir); + void (*dma_debug)(struct dma_trx_obj *obj, struct dma_table *table); + ktime_t begin; + ktime_t end; + u64 cache_time_total; + u64 cache_time_avarage; + u32 buffer_size; + u32 rd_buf_size; + u32 wr_buf_size; + u32 ack_base; + u32 set_data_check_pos; + u32 set_local_idx_pos; + u32 set_buf_size_pos; + u32 set_chk_sum_pos; + u32 version; + int addr_reverse; +}; + +static inline struct dma_trx_obj *pcie_dw_dmatest_register(struct device *dev, bool irq_en) +{ + return NULL; +} + +#endif diff --git a/target/linux/rockchip/files/include/dt-bindings/clock/rk3528-cru.h b/target/linux/rockchip/files/include/dt-bindings/clock/rk3528-cru.h new file mode 100644 index 000000000..5ec1681ca --- /dev/null +++ b/target/linux/rockchip/files/include/dt-bindings/clock/rk3528-cru.h @@ -0,0 +1,746 @@ +/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ +/* + * Copyright (c) 2022 Rockchip Electronics Co. Ltd. + * Author: Joseph Chen + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3528_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3528_H + +/* cru-clocks indices */ + +/* core clocks */ +#define PLL_APLL 1 +#define PLL_CPLL 2 +#define PLL_GPLL 3 +#define PLL_PPLL 4 +#define PLL_DPLL 5 +#define ARMCLK 6 + +#define XIN_OSC0_HALF 8 +#define CLK_MATRIX_50M_SRC 9 +#define CLK_MATRIX_100M_SRC 10 +#define CLK_MATRIX_150M_SRC 11 +#define CLK_MATRIX_200M_SRC 12 +#define CLK_MATRIX_250M_SRC 13 +#define CLK_MATRIX_300M_SRC 14 +#define CLK_MATRIX_339M_SRC 15 +#define CLK_MATRIX_400M_SRC 16 +#define CLK_MATRIX_500M_SRC 17 +#define CLK_MATRIX_600M_SRC 18 +#define CLK_UART0_SRC 19 +#define CLK_UART0_FRAC 20 +#define SCLK_UART0 21 +#define CLK_UART1_SRC 22 +#define CLK_UART1_FRAC 23 +#define SCLK_UART1 24 +#define CLK_UART2_SRC 25 +#define CLK_UART2_FRAC 26 +#define SCLK_UART2 27 +#define CLK_UART3_SRC 28 +#define CLK_UART3_FRAC 29 +#define SCLK_UART3 30 +#define CLK_UART4_SRC 31 +#define CLK_UART4_FRAC 32 +#define SCLK_UART4 33 +#define CLK_UART5_SRC 34 +#define CLK_UART5_FRAC 35 +#define SCLK_UART5 36 +#define CLK_UART6_SRC 37 +#define CLK_UART6_FRAC 38 +#define SCLK_UART6 39 +#define CLK_UART7_SRC 40 +#define CLK_UART7_FRAC 41 +#define SCLK_UART7 42 +#define CLK_I2S0_2CH_SRC 43 +#define CLK_I2S0_2CH_FRAC 44 +#define MCLK_I2S0_2CH_SAI_SRC 45 +#define CLK_I2S3_8CH_SRC 46 +#define CLK_I2S3_8CH_FRAC 47 +#define MCLK_I2S3_8CH_SAI_SRC 48 +#define CLK_I2S1_8CH_SRC 49 +#define CLK_I2S1_8CH_FRAC 50 +#define MCLK_I2S1_8CH_SAI_SRC 51 +#define CLK_I2S2_2CH_SRC 52 +#define CLK_I2S2_2CH_FRAC 53 +#define MCLK_I2S2_2CH_SAI_SRC 54 +#define CLK_SPDIF_SRC 55 +#define CLK_SPDIF_FRAC 56 +#define MCLK_SPDIF_SRC 57 +#define DCLK_VOP_SRC0 58 +#define DCLK_VOP_SRC1 59 +#define CLK_HSM 60 +#define CLK_CORE_SRC_ACS 63 +#define CLK_CORE_SRC_PVTMUX 65 +#define CLK_CORE_SRC 66 +#define CLK_CORE 67 +#define ACLK_M_CORE_BIU 68 +#define CLK_CORE_PVTPLL_SRC 69 +#define PCLK_DBG 70 +#define SWCLKTCK 71 +#define CLK_SCANHS_CORE 72 +#define CLK_SCANHS_ACLKM_CORE 73 +#define CLK_SCANHS_PCLK_DBG 74 +#define CLK_SCANHS_PCLK_CPU_BIU 76 +#define PCLK_CPU_ROOT 77 +#define PCLK_CORE_GRF 78 +#define PCLK_DAPLITE_BIU 79 +#define PCLK_CPU_BIU 80 +#define CLK_REF_PVTPLL_CORE 81 +#define ACLK_BUS_VOPGL_ROOT 85 +#define ACLK_BUS_VOPGL_BIU 86 +#define ACLK_BUS_H_ROOT 87 +#define ACLK_BUS_H_BIU 88 +#define ACLK_BUS_ROOT 89 +#define HCLK_BUS_ROOT 90 +#define PCLK_BUS_ROOT 91 +#define ACLK_BUS_M_ROOT 92 +#define ACLK_SYSMEM_BIU 93 +#define CLK_TIMER_ROOT 95 +#define ACLK_BUS_BIU 96 +#define HCLK_BUS_BIU 97 +#define PCLK_BUS_BIU 98 +#define PCLK_DFT2APB 99 +#define PCLK_BUS_GRF 100 +#define ACLK_BUS_M_BIU 101 +#define ACLK_GIC 102 +#define ACLK_SPINLOCK 103 +#define ACLK_DMAC 104 +#define PCLK_TIMER 105 +#define CLK_TIMER0 106 +#define CLK_TIMER1 107 +#define CLK_TIMER2 108 +#define CLK_TIMER3 109 +#define CLK_TIMER4 110 +#define CLK_TIMER5 111 +#define PCLK_JDBCK_DAP 112 +#define CLK_JDBCK_DAP 113 +#define PCLK_WDT_NS 114 +#define TCLK_WDT_NS 115 +#define HCLK_TRNG_NS 116 +#define PCLK_UART0 117 +#define PCLK_DMA2DDR 123 +#define ACLK_DMA2DDR 124 +#define PCLK_PWM0 126 +#define CLK_PWM0 127 +#define CLK_CAPTURE_PWM0 128 +#define PCLK_PWM1 129 +#define CLK_PWM1 130 +#define CLK_CAPTURE_PWM1 131 +#define PCLK_SCR 134 +#define ACLK_DCF 135 +#define PCLK_INTMUX 138 +#define CLK_PPLL_I 141 +#define CLK_PPLL_MUX 142 +#define CLK_PPLL_100M_MATRIX 143 +#define CLK_PPLL_50M_MATRIX 144 +#define CLK_REF_PCIE_INNER_PHY 145 +#define CLK_REF_PCIE_100M_PHY 146 +#define ACLK_VPU_L_ROOT 147 +#define CLK_GMAC1_VPU_25M 148 +#define CLK_PPLL_125M_MATRIX 149 +#define ACLK_VPU_ROOT 150 +#define HCLK_VPU_ROOT 151 +#define PCLK_VPU_ROOT 152 +#define ACLK_VPU_BIU 153 +#define HCLK_VPU_BIU 154 +#define PCLK_VPU_BIU 155 +#define ACLK_VPU 156 +#define HCLK_VPU 157 +#define PCLK_CRU_PCIE 158 +#define PCLK_VPU_GRF 159 +#define HCLK_SFC 160 +#define SCLK_SFC 161 +#define CCLK_SRC_EMMC 163 +#define HCLK_EMMC 164 +#define ACLK_EMMC 165 +#define BCLK_EMMC 166 +#define TCLK_EMMC 167 +#define PCLK_GPIO1 168 +#define DBCLK_GPIO1 169 +#define ACLK_VPU_L_BIU 172 +#define PCLK_VPU_IOC 173 +#define HCLK_SAI_I2S0 174 +#define MCLK_SAI_I2S0 175 +#define HCLK_SAI_I2S2 176 +#define MCLK_SAI_I2S2 177 +#define PCLK_ACODEC 178 +#define MCLK_ACODEC_TX 179 +#define PCLK_GPIO3 186 +#define DBCLK_GPIO3 187 +#define PCLK_SPI1 189 +#define CLK_SPI1 190 +#define SCLK_IN_SPI1 191 +#define PCLK_UART2 192 +#define PCLK_UART5 194 +#define PCLK_UART6 196 +#define PCLK_UART7 198 +#define PCLK_I2C3 200 +#define CLK_I2C3 201 +#define PCLK_I2C5 202 +#define CLK_I2C5 203 +#define PCLK_I2C6 204 +#define CLK_I2C6 205 +#define ACLK_MAC_VPU 206 +#define PCLK_MAC_VPU 207 +#define CLK_GMAC1_RMII_VPU 209 +#define CLK_GMAC1_SRC_VPU 210 +#define PCLK_PCIE 215 +#define CLK_PCIE_AUX 216 +#define ACLK_PCIE 217 +#define HCLK_PCIE_SLV 218 +#define HCLK_PCIE_DBI 219 +#define PCLK_PCIE_PHY 220 +#define PCLK_PIPE_GRF 221 +#define CLK_PIPE_USB3OTG_COMBO 230 +#define CLK_UTMI_USB3OTG 232 +#define CLK_PCIE_PIPE_PHY 235 +#define CCLK_SRC_SDIO0 240 +#define HCLK_SDIO0 241 +#define CCLK_SRC_SDIO1 244 +#define HCLK_SDIO1 245 +#define CLK_TS_0 246 +#define CLK_TS_1 247 +#define PCLK_CAN2 250 +#define CLK_CAN2 251 +#define PCLK_CAN3 252 +#define CLK_CAN3 253 +#define PCLK_SARADC 256 +#define CLK_SARADC 257 +#define PCLK_TSADC 258 +#define CLK_TSADC 259 +#define CLK_TSADC_TSEN 260 +#define ACLK_USB3OTG 261 +#define CLK_REF_USB3OTG 262 +#define CLK_SUSPEND_USB3OTG 263 +#define ACLK_GPU_ROOT 269 +#define PCLK_GPU_ROOT 270 +#define ACLK_GPU_BIU 271 +#define PCLK_GPU_BIU 272 +#define ACLK_GPU 273 +#define CLK_GPU_PVTPLL_SRC 274 +#define ACLK_GPU_MALI 275 +#define HCLK_RKVENC_ROOT 281 +#define ACLK_RKVENC_ROOT 282 +#define PCLK_RKVENC_ROOT 283 +#define HCLK_RKVENC_BIU 284 +#define ACLK_RKVENC_BIU 285 +#define PCLK_RKVENC_BIU 286 +#define HCLK_RKVENC 287 +#define ACLK_RKVENC 288 +#define CLK_CORE_RKVENC 289 +#define HCLK_SAI_I2S1 290 +#define MCLK_SAI_I2S1 291 +#define PCLK_I2C1 292 +#define CLK_I2C1 293 +#define PCLK_I2C0 294 +#define CLK_I2C0 295 +#define CLK_UART_JTAG 296 +#define PCLK_SPI0 297 +#define CLK_SPI0 298 +#define SCLK_IN_SPI0 299 +#define PCLK_GPIO4 300 +#define DBCLK_GPIO4 301 +#define PCLK_RKVENC_IOC 302 +#define HCLK_SPDIF 308 +#define MCLK_SPDIF 309 +#define HCLK_PDM 310 +#define MCLK_PDM 311 +#define PCLK_UART1 315 +#define PCLK_UART3 317 +#define PCLK_RKVENC_GRF 319 +#define PCLK_CAN0 320 +#define CLK_CAN0 321 +#define PCLK_CAN1 322 +#define CLK_CAN1 323 +#define ACLK_VO_ROOT 324 +#define HCLK_VO_ROOT 325 +#define PCLK_VO_ROOT 326 +#define ACLK_VO_BIU 327 +#define HCLK_VO_BIU 328 +#define PCLK_VO_BIU 329 +#define HCLK_RGA2E 330 +#define ACLK_RGA2E 331 +#define CLK_CORE_RGA2E 332 +#define HCLK_VDPP 333 +#define ACLK_VDPP 334 +#define CLK_CORE_VDPP 335 +#define PCLK_VO_GRF 336 +#define PCLK_CRU 337 +#define ACLK_VOP_ROOT 338 +#define ACLK_VOP_BIU 339 +#define HCLK_VOP 340 +#define DCLK_VOP0 341 +#define DCLK_VOP1 342 +#define ACLK_VOP 343 +#define PCLK_HDMI 344 +#define CLK_SFR_HDMI 345 +#define CLK_CEC_HDMI 346 +#define CLK_SPDIF_HDMI 347 +#define CLK_HDMIPHY_TMDSSRC 348 +#define CLK_HDMIPHY_PREP 349 +#define PCLK_HDMIPHY 352 +#define HCLK_HDCP_KEY 354 +#define ACLK_HDCP 355 +#define HCLK_HDCP 356 +#define PCLK_HDCP 357 +#define HCLK_CVBS 358 +#define DCLK_CVBS 359 +#define DCLK_4X_CVBS 360 +#define ACLK_JPEG_DECODER 361 +#define HCLK_JPEG_DECODER 362 +#define ACLK_VO_L_ROOT 375 +#define ACLK_VO_L_BIU 376 +#define ACLK_MAC_VO 377 +#define PCLK_MAC_VO 378 +#define CLK_GMAC0_SRC 379 +#define CLK_GMAC0_RMII_50M 380 +#define CLK_GMAC0_TX 381 +#define CLK_GMAC0_RX 382 +#define ACLK_JPEG_ROOT 385 +#define ACLK_JPEG_BIU 386 +#define HCLK_SAI_I2S3 387 +#define MCLK_SAI_I2S3 388 +#define CLK_MACPHY 398 +#define PCLK_VCDCPHY 399 +#define PCLK_GPIO2 404 +#define DBCLK_GPIO2 405 +#define PCLK_VO_IOC 406 +#define CCLK_SRC_SDMMC0 407 +#define HCLK_SDMMC0 408 +#define PCLK_OTPC_NS 411 +#define CLK_SBPI_OTPC_NS 412 +#define CLK_USER_OTPC_NS 413 +#define CLK_HDMIHDP0 415 +#define HCLK_USBHOST 416 +#define HCLK_USBHOST_ARB 417 +#define CLK_USBHOST_OHCI 418 +#define CLK_USBHOST_UTMI 419 +#define PCLK_UART4 420 +#define PCLK_I2C4 422 +#define CLK_I2C4 423 +#define PCLK_I2C7 424 +#define CLK_I2C7 425 +#define PCLK_USBPHY 426 +#define CLK_REF_USBPHY 427 +#define HCLK_RKVDEC_ROOT 433 +#define ACLK_RKVDEC_ROOT_NDFT 434 +#define PCLK_DDRPHY_CRU 435 +#define HCLK_RKVDEC_BIU 436 +#define ACLK_RKVDEC_BIU 437 +#define ACLK_RKVDEC 439 +#define HCLK_RKVDEC 440 +#define CLK_HEVC_CA_RKVDEC 441 +#define ACLK_RKVDEC_PVTMUX_ROOT 442 +#define CLK_RKVDEC_PVTPLL_SRC 443 +#define PCLK_DDR_ROOT 449 +#define PCLK_DDR_BIU 450 +#define PCLK_DDRC 451 +#define PCLK_DDRMON 452 +#define CLK_TIMER_DDRMON 453 +#define PCLK_MSCH_BIU 454 +#define PCLK_DDR_GRF 455 +#define PCLK_DDR_HWLP 456 +#define PCLK_DDRPHY 457 +#define CLK_MSCH_BIU 463 +#define ACLK_DDR_UPCTL 464 +#define CLK_DDR_UPCTL 465 +#define CLK_DDRMON 466 +#define ACLK_DDR_SCRAMBLE 467 +#define ACLK_SPLIT 468 +#define CLK_DDRC_SRC 470 +#define CLK_DDR_PHY 471 +#define PCLK_OTPC_S 472 +#define CLK_SBPI_OTPC_S 473 +#define CLK_USER_OTPC_S 474 +#define PCLK_KEYREADER 475 +#define PCLK_BUS_SGRF 476 +#define PCLK_STIMER 477 +#define CLK_STIMER0 478 +#define CLK_STIMER1 479 +#define PCLK_WDT_S 480 +#define TCLK_WDT_S 481 +#define HCLK_TRNG_S 482 +#define HCLK_BOOTROM 486 +#define PCLK_DCF 487 +#define ACLK_SYSMEM 488 +#define HCLK_TSP 489 +#define ACLK_TSP 490 +#define CLK_CORE_TSP 491 +#define CLK_OTPC_ARB 492 +#define PCLK_OTP_MASK 493 +#define CLK_PMC_OTP 494 +#define PCLK_PMU_ROOT 495 +#define HCLK_PMU_ROOT 496 +#define PCLK_I2C2 497 +#define CLK_I2C2 498 +#define HCLK_PMU_BIU 500 +#define PCLK_PMU_BIU 501 +#define FCLK_MCU 502 +#define RTC_CLK_MCU 504 +#define PCLK_OSCCHK 505 +#define CLK_PMU_MCU_JTAG 506 +#define PCLK_PMU 508 +#define PCLK_GPIO0 509 +#define DBCLK_GPIO0 510 +#define XIN_OSC0_DIV 511 +#define CLK_DEEPSLOW 512 +#define CLK_DDR_FAIL_SAFE 513 +#define PCLK_PMU_HP_TIMER 514 +#define CLK_PMU_HP_TIMER 515 +#define CLK_PMU_32K_HP_TIMER 516 +#define PCLK_PMU_IOC 517 +#define PCLK_PMU_CRU 518 +#define PCLK_PMU_GRF 519 +#define PCLK_PMU_WDT 520 +#define TCLK_PMU_WDT 521 +#define PCLK_PMU_MAILBOX 522 +#define PCLK_SCRKEYGEN 524 +#define CLK_SCRKEYGEN 525 +#define CLK_PVTM_OSCCHK 526 +#define CLK_REFOUT 530 +#define CLK_PVTM_PMU 532 +#define PCLK_PVTM_PMU 533 +#define PCLK_PMU_SGRF 534 +#define HCLK_PMU_SRAM 535 +#define CLK_UART0 536 +#define CLK_UART1 537 +#define CLK_UART2 538 +#define CLK_UART3 539 +#define CLK_UART4 540 +#define CLK_UART5 541 +#define CLK_UART6 542 +#define CLK_UART7 543 +#define MCLK_I2S0_2CH_SAI_SRC_PRE 544 +#define MCLK_I2S1_8CH_SAI_SRC_PRE 545 +#define MCLK_I2S2_2CH_SAI_SRC_PRE 546 +#define MCLK_I2S3_8CH_SAI_SRC_PRE 547 +#define MCLK_SDPDIF_SRC_PRE 548 +#define CLK_NR_CLKS (MCLK_SDPDIF_SRC_PRE + 1) + +/* grf-clocks indices */ +#define SCLK_SDMMC_DRV 1 +#define SCLK_SDMMC_SAMPLE 2 +#define SCLK_SDIO0_DRV 3 +#define SCLK_SDIO0_SAMPLE 4 +#define SCLK_SDIO1_DRV 5 +#define SCLK_SDIO1_SAMPLE 6 +#define CLK_NR_GRF_CLKS (SCLK_SDIO1_SAMPLE + 1) + +/* scmi-clocks indices */ +#define SCMI_PCLK_KEYREADER 0 +#define SCMI_HCLK_KLAD 1 +#define SCMI_PCLK_KLAD 2 +#define SCMI_HCLK_TRNG_S 3 +#define SCMI_HCLK_CRYPTO_S 4 +#define SCMI_PCLK_WDT_S 5 +#define SCMI_TCLK_WDT_S 6 +#define SCMI_PCLK_STIMER 7 +#define SCMI_CLK_STIMER0 8 +#define SCMI_CLK_STIMER1 9 +#define SCMI_PCLK_OTP_MASK 10 +#define SCMI_PCLK_OTPC_S 11 +#define SCMI_CLK_SBPI_OTPC_S 12 +#define SCMI_CLK_USER_OTPC_S 13 +#define SCMI_CLK_PMC_OTP 14 +#define SCMI_CLK_OTPC_ARB 15 +#define SCMI_CLK_CORE_TSP 16 +#define SCMI_ACLK_TSP 17 +#define SCMI_HCLK_TSP 18 +#define SCMI_PCLK_DCF 19 +#define SCMI_CLK_DDR 20 +#define SCMI_CLK_CPU 21 +#define SCMI_CLK_GPU 22 +#define SCMI_CORE_CRYPTO 23 +#define SCMI_ACLK_CRYPTO 24 +#define SCMI_PKA_CRYPTO 25 +#define SCMI_HCLK_CRYPTO 26 +#define SCMI_CORE_CRYPTO_S 27 +#define SCMI_ACLK_CRYPTO_S 28 +#define SCMI_PKA_CRYPTO_S 29 +#define SCMI_CORE_KLAD 30 +#define SCMI_ACLK_KLAD 31 +#define SCMI_HCLK_TRNG 32 + +// CRU_SOFTRST_CON03(Offset:0xA0C) +#define SRST_NCOREPORESET0 0x00000030 +#define SRST_NCOREPORESET1 0x00000031 +#define SRST_NCOREPORESET2 0x00000032 +#define SRST_NCOREPORESET3 0x00000033 +#define SRST_NCORESET0 0x00000034 +#define SRST_NCORESET1 0x00000035 +#define SRST_NCORESET2 0x00000036 +#define SRST_NCORESET3 0x00000037 +#define SRST_NL2RESET 0x00000038 +#define SRST_ARESETN_M_CORE_BIU 0x00000039 +#define SRST_RESETN_CORE_CRYPTO 0x0000003A + +// CRU_SOFTRST_CON05(Offset:0xA14) +#define SRST_PRESETN_DBG 0x0000005D +#define SRST_POTRESETN_DBG 0x0000005E +#define SRST_NTRESETN_DBG 0x0000005F + +// CRU_SOFTRST_CON06(Offset:0xA18) +#define SRST_PRESETN_CORE_GRF 0x00000062 +#define SRST_PRESETN_DAPLITE_BIU 0x00000063 +#define SRST_PRESETN_CPU_BIU 0x00000064 +#define SRST_RESETN_REF_PVTPLL_CORE 0x00000067 + +// CRU_SOFTRST_CON08(Offset:0xA20) +#define SRST_ARESETN_BUS_VOPGL_BIU 0x00000081 +#define SRST_ARESETN_BUS_H_BIU 0x00000083 +#define SRST_ARESETN_SYSMEM_BIU 0x00000088 +#define SRST_ARESETN_BUS_BIU 0x0000008A +#define SRST_HRESETN_BUS_BIU 0x0000008B +#define SRST_PRESETN_BUS_BIU 0x0000008C +#define SRST_PRESETN_DFT2APB 0x0000008D +#define SRST_PRESETN_BUS_GRF 0x0000008F + +// CRU_SOFTRST_CON09(Offset:0xA24) +#define SRST_ARESETN_BUS_M_BIU 0x00000090 +#define SRST_ARESETN_GIC 0x00000091 +#define SRST_ARESETN_SPINLOCK 0x00000092 +#define SRST_ARESETN_DMAC 0x00000094 +#define SRST_PRESETN_TIMER 0x00000095 +#define SRST_RESETN_TIMER0 0x00000096 +#define SRST_RESETN_TIMER1 0x00000097 +#define SRST_RESETN_TIMER2 0x00000098 +#define SRST_RESETN_TIMER3 0x00000099 +#define SRST_RESETN_TIMER4 0x0000009A +#define SRST_RESETN_TIMER5 0x0000009B +#define SRST_PRESETN_JDBCK_DAP 0x0000009C +#define SRST_RESETN_JDBCK_DAP 0x0000009D +#define SRST_PRESETN_WDT_NS 0x0000009F + +// CRU_SOFTRST_CON10(Offset:0xA28) +#define SRST_TRESETN_WDT_NS 0x000000A0 +#define SRST_HRESETN_TRNG_NS 0x000000A3 +#define SRST_PRESETN_UART0 0x000000A7 +#define SRST_SRESETN_UART0 0x000000A8 +#define SRST_RESETN_PKA_CRYPTO 0x000000AA +#define SRST_ARESETN_CRYPTO 0x000000AB +#define SRST_HRESETN_CRYPTO 0x000000AC +#define SRST_PRESETN_DMA2DDR 0x000000AD +#define SRST_ARESETN_DMA2DDR 0x000000AE + +// CRU_SOFTRST_CON11(Offset:0xA2C) +#define SRST_PRESETN_PWM0 0x000000B4 +#define SRST_RESETN_PWM0 0x000000B5 +#define SRST_PRESETN_PWM1 0x000000B7 +#define SRST_RESETN_PWM1 0x000000B8 +#define SRST_PRESETN_SCR 0x000000BA +#define SRST_ARESETN_DCF 0x000000BB +#define SRST_PRESETN_INTMUX 0x000000BC + +// CRU_SOFTRST_CON25(Offset:0xA64) +#define SRST_ARESETN_VPU_BIU 0x00000196 +#define SRST_HRESETN_VPU_BIU 0x00000197 +#define SRST_PRESETN_VPU_BIU 0x00000198 +#define SRST_ARESETN_VPU 0x00000199 +#define SRST_HRESETN_VPU 0x0000019A +#define SRST_PRESETN_CRU_PCIE 0x0000019B +#define SRST_PRESETN_VPU_GRF 0x0000019C +#define SRST_HRESETN_SFC 0x0000019D +#define SRST_SRESETN_SFC 0x0000019E +#define SRST_CRESETN_EMMC 0x0000019F + +// CRU_SOFTRST_CON26(Offset:0xA68) +#define SRST_HRESETN_EMMC 0x000001A0 +#define SRST_ARESETN_EMMC 0x000001A1 +#define SRST_BRESETN_EMMC 0x000001A2 +#define SRST_TRESETN_EMMC 0x000001A3 +#define SRST_PRESETN_GPIO1 0x000001A4 +#define SRST_DBRESETN_GPIO1 0x000001A5 +#define SRST_ARESETN_VPU_L_BIU 0x000001A6 +#define SRST_PRESETN_VPU_IOC 0x000001A8 +#define SRST_HRESETN_SAI_I2S0 0x000001A9 +#define SRST_MRESETN_SAI_I2S0 0x000001AA +#define SRST_HRESETN_SAI_I2S2 0x000001AB +#define SRST_MRESETN_SAI_I2S2 0x000001AC +#define SRST_PRESETN_ACODEC 0x000001AD + +// CRU_SOFTRST_CON27(Offset:0xA6C) +#define SRST_PRESETN_GPIO3 0x000001B0 +#define SRST_DBRESETN_GPIO3 0x000001B1 +#define SRST_PRESETN_SPI1 0x000001B4 +#define SRST_RESETN_SPI1 0x000001B5 +#define SRST_PRESETN_UART2 0x000001B7 +#define SRST_SRESETN_UART2 0x000001B8 +#define SRST_PRESETN_UART5 0x000001B9 +#define SRST_SRESETN_UART5 0x000001BA +#define SRST_PRESETN_UART6 0x000001BB +#define SRST_SRESETN_UART6 0x000001BC +#define SRST_PRESETN_UART7 0x000001BD +#define SRST_SRESETN_UART7 0x000001BE +#define SRST_PRESETN_I2C3 0x000001BF + +// CRU_SOFTRST_CON28(Offset:0xA70) +#define SRST_RESETN_I2C3 0x000001C0 +#define SRST_PRESETN_I2C5 0x000001C1 +#define SRST_RESETN_I2C5 0x000001C2 +#define SRST_PRESETN_I2C6 0x000001C3 +#define SRST_RESETN_I2C6 0x000001C4 +#define SRST_ARESETN_MAC 0x000001C5 + +// CRU_SOFTRST_CON30(Offset:0xA78) +#define SRST_PRESETN_PCIE 0x000001E1 +#define SRST_RESETN_PCIE_PIPE_PHY 0x000001E2 +#define SRST_RESETN_PCIE_POWER_UP 0x000001E3 +#define SRST_PRESETN_PCIE_PHY 0x000001E6 +#define SRST_PRESETN_PIPE_GRF 0x000001E7 + +// CRU_SOFTRST_CON32(Offset:0xA80) +#define SRST_HRESETN_SDIO0 0x00000202 +#define SRST_HRESETN_SDIO1 0x00000204 +#define SRST_RESETN_TS_0 0x00000205 +#define SRST_RESETN_TS_1 0x00000206 +#define SRST_PRESETN_CAN2 0x00000207 +#define SRST_RESETN_CAN2 0x00000208 +#define SRST_PRESETN_CAN3 0x00000209 +#define SRST_RESETN_CAN3 0x0000020A +#define SRST_PRESETN_SARADC 0x0000020B +#define SRST_RESETN_SARADC 0x0000020C +#define SRST_RESETN_SARADC_PHY 0x0000020D +#define SRST_PRESETN_TSADC 0x0000020E +#define SRST_RESETN_TSADC 0x0000020F + +// CRU_SOFTRST_CON33(Offset:0xA84) +#define SRST_ARESETN_USB3OTG 0x00000211 + +// CRU_SOFTRST_CON34(Offset:0xA88) +#define SRST_ARESETN_GPU_BIU 0x00000223 +#define SRST_PRESETN_GPU_BIU 0x00000225 +#define SRST_ARESETN_GPU 0x00000228 +#define SRST_RESETN_REF_PVTPLL_GPU 0x00000229 + +// CRU_SOFTRST_CON36(Offset:0xA90) +#define SRST_HRESETN_RKVENC_BIU 0x00000243 +#define SRST_ARESETN_RKVENC_BIU 0x00000244 +#define SRST_PRESETN_RKVENC_BIU 0x00000245 +#define SRST_HRESETN_RKVENC 0x00000246 +#define SRST_ARESETN_RKVENC 0x00000247 +#define SRST_RESETN_CORE_RKVENC 0x00000248 +#define SRST_HRESETN_SAI_I2S1 0x00000249 +#define SRST_MRESETN_SAI_I2S1 0x0000024A +#define SRST_PRESETN_I2C1 0x0000024B +#define SRST_RESETN_I2C1 0x0000024C +#define SRST_PRESETN_I2C0 0x0000024D +#define SRST_RESETN_I2C0 0x0000024E + +// CRU_SOFTRST_CON37(Offset:0xA94) +#define SRST_PRESETN_SPI0 0x00000252 +#define SRST_RESETN_SPI0 0x00000253 +#define SRST_PRESETN_GPIO4 0x00000258 +#define SRST_DBRESETN_GPIO4 0x00000259 +#define SRST_PRESETN_RKVENC_IOC 0x0000025A +#define SRST_HRESETN_SPDIF 0x0000025E +#define SRST_MRESETN_SPDIF 0x0000025F + +// CRU_SOFTRST_CON38(Offset:0xA98) +#define SRST_HRESETN_PDM 0x00000260 +#define SRST_MRESETN_PDM 0x00000261 +#define SRST_PRESETN_UART1 0x00000262 +#define SRST_SRESETN_UART1 0x00000263 +#define SRST_PRESETN_UART3 0x00000264 +#define SRST_SRESETN_UART3 0x00000265 +#define SRST_PRESETN_RKVENC_GRF 0x00000266 +#define SRST_PRESETN_CAN0 0x00000267 +#define SRST_RESETN_CAN0 0x00000268 +#define SRST_PRESETN_CAN1 0x00000269 +#define SRST_RESETN_CAN1 0x0000026A + +// CRU_SOFTRST_CON39(Offset:0xA9C) +#define SRST_ARESETN_VO_BIU 0x00000273 +#define SRST_HRESETN_VO_BIU 0x00000274 +#define SRST_PRESETN_VO_BIU 0x00000275 +#define SRST_HRESETN_RGA2E 0x00000277 +#define SRST_ARESETN_RGA2E 0x00000278 +#define SRST_RESETN_CORE_RGA2E 0x00000279 +#define SRST_HRESETN_VDPP 0x0000027A +#define SRST_ARESETN_VDPP 0x0000027B +#define SRST_RESETN_CORE_VDPP 0x0000027C +#define SRST_PRESETN_VO_GRF 0x0000027D +#define SRST_PRESETN_CRU 0x0000027F + +// CRU_SOFTRST_CON40(Offset:0xAA0) +#define SRST_ARESETN_VOP_BIU 0x00000281 +#define SRST_HRESETN_VOP 0x00000282 +#define SRST_DRESETN_VOP0 0x00000283 +#define SRST_DRESETN_VOP1 0x00000284 +#define SRST_ARESETN_VOP 0x00000285 +#define SRST_PRESETN_HDMI 0x00000286 +#define SRST_HDMI_RESETN 0x00000287 +#define SRST_PRESETN_HDMIPHY 0x0000028E +#define SRST_HRESETN_HDCP_KEY 0x0000028F + +// CRU_SOFTRST_CON41(Offset:0xAA4) +#define SRST_ARESETN_HDCP 0x00000290 +#define SRST_HRESETN_HDCP 0x00000291 +#define SRST_PRESETN_HDCP 0x00000292 +#define SRST_HRESETN_CVBS 0x00000293 +#define SRST_DRESETN_CVBS_VOP 0x00000294 +#define SRST_DRESETN_4X_CVBS_VOP 0x00000295 +#define SRST_ARESETN_JPEG_DECODER 0x00000296 +#define SRST_HRESETN_JPEG_DECODER 0x00000297 +#define SRST_ARESETN_VO_L_BIU 0x00000299 +#define SRST_ARESETN_MAC_VO 0x0000029A + +// CRU_SOFTRST_CON42(Offset:0xAA8) +#define SRST_ARESETN_JPEG_BIU 0x000002A0 +#define SRST_HRESETN_SAI_I2S3 0x000002A1 +#define SRST_MRESETN_SAI_I2S3 0x000002A2 +#define SRST_RESETN_MACPHY 0x000002A3 +#define SRST_PRESETN_VCDCPHY 0x000002A4 +#define SRST_PRESETN_GPIO2 0x000002A5 +#define SRST_DBRESETN_GPIO2 0x000002A6 +#define SRST_PRESETN_VO_IOC 0x000002A7 +#define SRST_HRESETN_SDMMC0 0x000002A9 +#define SRST_PRESETN_OTPC_NS 0x000002AB +#define SRST_RESETN_SBPI_OTPC_NS 0x000002AC +#define SRST_RESETN_USER_OTPC_NS 0x000002AD + +// CRU_SOFTRST_CON43(Offset:0xAAC) +#define SRST_RESETN_HDMIHDP0 0x000002B2 +#define SRST_HRESETN_USBHOST 0x000002B3 +#define SRST_HRESETN_USBHOST_ARB 0x000002B4 +#define SRST_RESETN_HOST_UTMI 0x000002B6 +#define SRST_PRESETN_UART4 0x000002B7 +#define SRST_SRESETN_UART4 0x000002B8 +#define SRST_PRESETN_I2C4 0x000002B9 +#define SRST_RESETN_I2C4 0x000002BA +#define SRST_PRESETN_I2C7 0x000002BB +#define SRST_RESETN_I2C7 0x000002BC +#define SRST_PRESETN_USBPHY 0x000002BD +#define SRST_RESETN_USBPHY_POR 0x000002BE +#define SRST_RESETN_USBPHY_OTG 0x000002BF + +// CRU_SOFTRST_CON44(Offset:0xAB0) +#define SRST_RESETN_USBPHY_HOST 0x000002C0 +#define SRST_PRESETN_DDRPHY_CRU 0x000002C4 +#define SRST_HRESETN_RKVDEC_BIU 0x000002C6 +#define SRST_ARESETN_RKVDEC_BIU 0x000002C7 +#define SRST_ARESETN_RKVDEC 0x000002C8 +#define SRST_HRESETN_RKVDEC 0x000002C9 +#define SRST_RESETN_HEVC_CA_RKVDEC 0x000002CB +#define SRST_RESETN_REF_PVTPLL_RKVDEC 0x000002CC + +// CRU_SOFTRST_CON45(Offset:0xAB4) +#define SRST_PRESETN_DDR_BIU 0x000002D1 +#define SRST_PRESETN_DDRC 0x000002D2 +#define SRST_PRESETN_DDRMON 0x000002D3 +#define SRST_RESETN_TIMER_DDRMON 0x000002D4 +#define SRST_PRESETN_MSCH_BIU 0x000002D5 +#define SRST_PRESETN_DDR_GRF 0x000002D6 +#define SRST_PRESETN_DDR_HWLP 0x000002D8 +#define SRST_PRESETN_DDRPHY 0x000002D9 +#define SRST_RESETN_MSCH_BIU 0x000002DA +#define SRST_ARESETN_DDR_UPCTL 0x000002DB +#define SRST_RESETN_DDR_UPCTL 0x000002DC +#define SRST_RESETN_DDRMON 0x000002DD +#define SRST_ARESETN_DDR_SCRAMBLE 0x000002DE +#define SRST_ARESETN_SPLIT 0x000002DF + +// CRU_SOFTRST_CON46(Offset:0xAB8) +#define SRST_RESETN_DDR_PHY 0x000002E0 + +#endif diff --git a/target/linux/rockchip/files/include/dt-bindings/power/rk3528-power.h b/target/linux/rockchip/files/include/dt-bindings/power/rk3528-power.h new file mode 100644 index 000000000..a9963a177 --- /dev/null +++ b/target/linux/rockchip/files/include/dt-bindings/power/rk3528-power.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-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 diff --git a/target/linux/rockchip/patches-6.1/301-pinctrl-rockchip-add-rk3528-support.patch b/target/linux/rockchip/patches-6.1/301-pinctrl-rockchip-add-rk3528-support.patch new file mode 100644 index 000000000..84546d264 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/301-pinctrl-rockchip-add-rk3528-support.patch @@ -0,0 +1,269 @@ +From ee5af82a6f88fd28849ea6d98cf43fbe9cbbbb19 Mon Sep 17 00:00:00 2001 +From: Steven Liu +Date: Thu, 11 Aug 2022 15:15:28 +0800 +Subject: [PATCH] pinctrl: rockchip: add rk3528 support + +Signed-off-by: Steven Liu +Change-Id: I2c1d32907168caf8a8afee6d1f742795b3d13536 +--- + drivers/pinctrl/pinctrl-rockchip.c | 196 ++++++++++++++++++++++++++++- + drivers/pinctrl/pinctrl-rockchip.h | 1 + + 2 files changed, 196 insertions(+), 1 deletion(-) + +--- a/drivers/pinctrl/pinctrl-rockchip.c ++++ b/drivers/pinctrl/pinctrl-rockchip.c +@@ -2019,6 +2019,150 @@ static int rk3568_calc_pull_reg_and_bit( + return 0; + } + ++#define RK3528_DRV_BITS_PER_PIN 8 ++#define RK3528_DRV_PINS_PER_REG 2 ++#define RK3528_DRV_GPIO0_OFFSET 0x100 ++#define RK3528_DRV_GPIO1_OFFSET 0x20120 ++#define RK3528_DRV_GPIO2_OFFSET 0x30160 ++#define RK3528_DRV_GPIO3_OFFSET 0x20190 ++#define RK3528_DRV_GPIO4_OFFSET 0x101C0 ++ ++static int rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl *info = bank->drvdata; ++ ++ *regmap = info->regmap_base; ++ switch (bank->bank_num) { ++ case 0: ++ *reg = RK3528_DRV_GPIO0_OFFSET; ++ break; ++ ++ case 1: ++ *reg = RK3528_DRV_GPIO1_OFFSET; ++ break; ++ ++ case 2: ++ *reg = RK3528_DRV_GPIO2_OFFSET; ++ break; ++ ++ case 3: ++ *reg = RK3528_DRV_GPIO3_OFFSET; ++ break; ++ ++ case 4: ++ *reg = RK3528_DRV_GPIO4_OFFSET; ++ break; ++ ++ default: ++ dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); ++ break; ++ } ++ ++ *reg += ((pin_num / RK3528_DRV_PINS_PER_REG) * 4); ++ *bit = pin_num % RK3528_DRV_PINS_PER_REG; ++ *bit *= RK3528_DRV_BITS_PER_PIN; ++ ++ return 0; ++} ++ ++#define RK3528_PULL_BITS_PER_PIN 2 ++#define RK3528_PULL_PINS_PER_REG 8 ++#define RK3528_PULL_GPIO0_OFFSET 0x200 ++#define RK3528_PULL_GPIO1_OFFSET 0x20210 ++#define RK3528_PULL_GPIO2_OFFSET 0x30220 ++#define RK3528_PULL_GPIO3_OFFSET 0x20230 ++#define RK3528_PULL_GPIO4_OFFSET 0x10240 ++ ++static int rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl *info = bank->drvdata; ++ ++ *regmap = info->regmap_base; ++ switch (bank->bank_num) { ++ case 0: ++ *reg = RK3528_PULL_GPIO0_OFFSET; ++ break; ++ ++ case 1: ++ *reg = RK3528_PULL_GPIO1_OFFSET; ++ break; ++ ++ case 2: ++ *reg = RK3528_PULL_GPIO2_OFFSET; ++ break; ++ ++ case 3: ++ *reg = RK3528_PULL_GPIO3_OFFSET; ++ break; ++ ++ case 4: ++ *reg = RK3528_PULL_GPIO4_OFFSET; ++ break; ++ ++ default: ++ dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); ++ break; ++ } ++ ++ *reg += ((pin_num / RK3528_PULL_PINS_PER_REG) * 4); ++ *bit = pin_num % RK3528_PULL_PINS_PER_REG; ++ *bit *= RK3528_PULL_BITS_PER_PIN; ++ ++ return 0; ++} ++ ++#define RK3528_SMT_BITS_PER_PIN 1 ++#define RK3528_SMT_PINS_PER_REG 8 ++#define RK3528_SMT_GPIO0_OFFSET 0x400 ++#define RK3528_SMT_GPIO1_OFFSET 0x20410 ++#define RK3528_SMT_GPIO2_OFFSET 0x30420 ++#define RK3528_SMT_GPIO3_OFFSET 0x20430 ++#define RK3528_SMT_GPIO4_OFFSET 0x10440 ++ ++static int rk3528_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, ++ struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl *info = bank->drvdata; ++ ++ *regmap = info->regmap_base; ++ switch (bank->bank_num) { ++ case 0: ++ *reg = RK3528_SMT_GPIO0_OFFSET; ++ break; ++ ++ case 1: ++ *reg = RK3528_SMT_GPIO1_OFFSET; ++ break; ++ ++ case 2: ++ *reg = RK3528_SMT_GPIO2_OFFSET; ++ break; ++ ++ case 3: ++ *reg = RK3528_SMT_GPIO3_OFFSET; ++ break; ++ ++ case 4: ++ *reg = RK3528_SMT_GPIO4_OFFSET; ++ break; ++ ++ default: ++ dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); ++ break; ++ } ++ ++ *reg += ((pin_num / RK3528_SMT_PINS_PER_REG) * 4); ++ *bit = pin_num % RK3528_SMT_PINS_PER_REG; ++ *bit *= RK3528_SMT_BITS_PER_PIN; ++ return 0; ++} ++ + #define RK3568_DRV_PMU_OFFSET 0x70 + #define RK3568_DRV_GRF_OFFSET 0x200 + #define RK3568_DRV_BITS_PER_PIN 8 +@@ -2342,6 +2486,10 @@ static int rockchip_set_drive_perpin(str + rmask_bits = RK3588_DRV_BITS_PER_PIN; + ret = strength; + goto config; ++ } else if (ctrl->type == RK3528) { ++ rmask_bits = RK3528_DRV_BITS_PER_PIN; ++ ret = (1 << (strength + 1)) - 1; ++ goto config; + } else if (ctrl->type == RK3568) { + rmask_bits = RK3568_DRV_BITS_PER_PIN; + ret = (1 << (strength + 1)) - 1; +@@ -2482,6 +2630,7 @@ static int rockchip_get_pull(struct rock + case RK3328: + case RK3368: + case RK3399: ++ case RK3528: + case RK3568: + case RK3588: + pull_type = bank->pull_type[pin_num / 8]; +@@ -2541,6 +2690,7 @@ static int rockchip_set_pull(struct rock + case RK3328: + case RK3368: + case RK3399: ++ case RK3528: + case RK3568: + case RK3588: + pull_type = bank->pull_type[pin_num / 8]; +@@ -2806,6 +2956,7 @@ static bool rockchip_pinconf_pull_valid( + case RK3328: + case RK3368: + case RK3399: ++ case RK3528: + case RK3568: + case RK3588: + return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); +@@ -3931,6 +4082,49 @@ static struct rockchip_pin_ctrl rk3399_p + .drv_calc_reg = rk3399_calc_drv_reg_and_bit, + }; + ++static struct rockchip_pin_bank rk3528_pin_banks[] = { ++ PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0, 0, 0, 0), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x20020, 0x20028, 0x20030, 0x20038), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x30040, 0, 0, 0), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x20060, 0x20068, 0x20070, 0), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x10080, 0x10088, 0x10090, 0x10098), ++}; ++ ++static struct rockchip_pin_ctrl rk3528_pin_ctrl __maybe_unused = { ++ .pin_banks = rk3528_pin_banks, ++ .nr_banks = ARRAY_SIZE(rk3528_pin_banks), ++ .label = "RK3528-GPIO", ++ .type = RK3528, ++ .pull_calc_reg = rk3528_calc_pull_reg_and_bit, ++ .drv_calc_reg = rk3528_calc_drv_reg_and_bit, ++ .schmitt_calc_reg = rk3528_calc_schmitt_reg_and_bit, ++}; ++ + 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, +@@ -4024,6 +4218,8 @@ static const struct of_device_id rockchi + .data = &rk3368_pin_ctrl }, + { .compatible = "rockchip,rk3399-pinctrl", + .data = &rk3399_pin_ctrl }, ++ { .compatible = "rockchip,rk3528-pinctrl", ++ .data = &rk3528_pin_ctrl }, + { .compatible = "rockchip,rk3568-pinctrl", + .data = &rk3568_pin_ctrl }, + { .compatible = "rockchip,rk3588-pinctrl", +--- a/drivers/pinctrl/pinctrl-rockchip.h ++++ b/drivers/pinctrl/pinctrl-rockchip.h +@@ -196,6 +196,7 @@ enum rockchip_pinctrl_type { + RK3328, + RK3368, + RK3399, ++ RK3528, + RK3568, + RK3588, + }; diff --git a/target/linux/rockchip/patches-6.1/302-thermal-rockchip-add-support-for-rk3528.patch b/target/linux/rockchip/patches-6.1/302-thermal-rockchip-add-support-for-rk3528.patch new file mode 100644 index 000000000..2f67840dd --- /dev/null +++ b/target/linux/rockchip/patches-6.1/302-thermal-rockchip-add-support-for-rk3528.patch @@ -0,0 +1,353 @@ +From 1e244fb37e21ce92a32b203cb030510bc3b42d29 Mon Sep 17 00:00:00 2001 +From: Shaohan Yao +Date: Fri, 9 Sep 2022 14:34:08 +0800 +Subject: [PATCH] thermal: rockchip: Support the rk3528 SoC in thermal driver + +There are one Temperature Sensor on rk3528, channel 0 is for chip. + +Signed-off-by: Shaohan Yao +Change-Id: Ib5bbb81615fe9fab80f26cdd2098cfb56746ca15 +--- + drivers/thermal/rockchip_thermal.c | 107 +++++++++++++++++++++++++++++ + 1 file changed, 107 insertions(+) + +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -180,32 +180,55 @@ struct rockchip_thermal_data { + #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 TSADCV2_AUTO_PERIOD 0x68 + #define TSADCV2_AUTO_PERIOD_HT 0x6c ++#define TSADCV3_AUTO_PERIOD 0x154 ++#define TSADCV3_AUTO_PERIOD_HT 0x158 ++#define TSADCV9_Q_MAX 0x210 ++#define TSADCV9_FLOW_CON 0x218 + + #define TSADCV2_AUTO_EN BIT(0) ++#define TSADCV2_AUTO_EN_MASK BIT(16) + #define TSADCV2_AUTO_SRC_EN(chn) BIT(4 + (chn)) ++#define TSADCV3_AUTO_SRC_EN(chn) BIT(chn) ++#define TSADCV3_AUTO_SRC_EN_MASK(chn) BIT(16 + chn) + #define TSADCV2_AUTO_TSHUT_POLARITY_HIGH BIT(8) ++#define TSADCV2_AUTO_TSHUT_POLARITY_MASK BIT(24) + + #define TSADCV3_AUTO_Q_SEL_EN BIT(1) ++#define TSADCV3_AUTO_Q_SEL_EN_MASK BIT(17) + + #define TSADCV2_INT_SRC_EN(chn) BIT(chn) ++#define TSADCV2_INT_SRC_EN_MASK(chn) BIT(16 + (chn)) + #define TSADCV2_SHUT_2GPIO_SRC_EN(chn) BIT(4 + (chn)) + #define TSADCV2_SHUT_2CRU_SRC_EN(chn) BIT(8 + (chn)) + + #define TSADCV2_INT_PD_CLEAR_MASK ~BIT(8) + #define TSADCV3_INT_PD_CLEAR_MASK ~BIT(16) ++#define TSADCV4_INT_PD_CLEAR_MASK 0xffffffff + + #define TSADCV2_DATA_MASK 0xfff + #define TSADCV3_DATA_MASK 0x3ff ++#define TSADCV5_DATA_MASK 0x7ff + + #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 + #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 ++#define TSADCV3_HIGHT_INT_DEBOUNCE 0x14c ++#define TSADCV3_HIGHT_TSHUT_DEBOUNCE 0x150 + #define TSADCV2_AUTO_PERIOD_TIME 250 /* 250ms */ + #define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* 50ms */ + #define TSADCV3_AUTO_PERIOD_TIME 1875 /* 2.5ms */ +@@ -213,6 +236,9 @@ struct rockchip_thermal_data { + + #define TSADCV5_AUTO_PERIOD_TIME 1622 /* 2.5ms */ + #define TSADCV5_AUTO_PERIOD_HT_TIME 1622 /* 2.5ms */ ++#define TSADCV7_AUTO_PERIOD_TIME 3000 /* 2.5ms */ ++#define TSADCV7_AUTO_PERIOD_HT_TIME 3000 /* 2.5ms */ ++#define TSADCV3_Q_MAX_VAL 0x7ff /* 11bit 2047 */ + + #define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */ + #define TSADCV5_USER_INTER_PD_SOC 0xfc0 /* 97us, at least 90us */ +@@ -223,6 +249,8 @@ struct rockchip_thermal_data { + + #define PX30_GRF_SOC_CON2 0x0408 + ++#define RK3528_GRF_TSADC_CON 0x40030 ++ + #define RK3568_GRF_TSADC_CON 0x0600 + #define RK3568_GRF_TSADC_ANA_REG0 (0x10001 << 0) + #define RK3568_GRF_TSADC_ANA_REG1 (0x10001 << 1) +@@ -484,6 +512,45 @@ static const struct tsadc_table rk3399_c + {TSADCV3_DATA_MASK, 125000}, + }; + ++static const struct tsadc_table rk3528_code_table[] = { ++ {0, -40000}, ++ {1419, -40000}, ++ {1427, -35000}, ++ {1435, -30000}, ++ {1443, -25000}, ++ {1452, -20000}, ++ {1460, -15000}, ++ {1468, -10000}, ++ {1477, -5000}, ++ {1486, 0}, ++ {1494, 5000}, ++ {1502, 10000}, ++ {1510, 15000}, ++ {1519, 20000}, ++ {1527, 25000}, ++ {1535, 30000}, ++ {1544, 35000}, ++ {1552, 40000}, ++ {1561, 45000}, ++ {1569, 50000}, ++ {1578, 55000}, ++ {1586, 60000}, ++ {1594, 65000}, ++ {1603, 70000}, ++ {1612, 75000}, ++ {1620, 80000}, ++ {1628, 85000}, ++ {1637, 90000}, ++ {1646, 95000}, ++ {1654, 100000}, ++ {1662, 105000}, ++ {1671, 110000}, ++ {1679, 115000}, ++ {1688, 120000}, ++ {1696, 125000}, ++ {TSADCV5_DATA_MASK, 125000}, ++}; ++ + static const struct tsadc_table rk3568_code_table[] = { + {0, -40000}, + {1584, -40000}, +@@ -793,6 +860,37 @@ static void rk_tsadcv7_initialize(struct + } + } + ++static void rk_tsadcv11_initialize(struct regmap *grf, void __iomem *regs, ++ enum tshut_polarity tshut_polarity) ++{ ++ writel_relaxed(TSADCV7_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD); ++ writel_relaxed(TSADCV7_AUTO_PERIOD_HT_TIME, ++ regs + TSADCV3_AUTO_PERIOD_HT); ++ writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, ++ regs + TSADCV3_HIGHT_INT_DEBOUNCE); ++ writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, ++ regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE); ++ writel_relaxed(TSADCV3_Q_MAX_VAL, regs + TSADCV9_Q_MAX); ++ writel_relaxed(TSADCV3_AUTO_Q_SEL_EN | TSADCV3_AUTO_Q_SEL_EN_MASK, ++ regs + TSADCV2_AUTO_CON); ++ if (tshut_polarity == TSHUT_HIGH_ACTIVE) ++ writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH | ++ TSADCV2_AUTO_TSHUT_POLARITY_MASK, ++ regs + TSADCV2_AUTO_CON); ++ else ++ writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK, ++ regs + TSADCV2_AUTO_CON); ++ ++ if (!IS_ERR(grf)) { ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN); ++ udelay(15); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2); ++ usleep_range(100, 200); ++ } ++} ++ + static void rk_tsadcv2_irq_ack(void __iomem *regs) + { + u32 val; +@@ -809,6 +907,17 @@ static void rk_tsadcv3_irq_ack(void __io + writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, regs + TSADCV2_INT_PD); + } + ++static void rk_tsadcv4_irq_ack(void __iomem *regs) ++{ ++ u32 val; ++ ++ val = readl_relaxed(regs + TSADCV3_INT_PD); ++ writel_relaxed(val & TSADCV4_INT_PD_CLEAR_MASK, regs + TSADCV3_INT_PD); ++ val = readl_relaxed(regs + TSADCV3_HSHUT_PD); ++ writel_relaxed(val & TSADCV3_INT_PD_CLEAR_MASK, ++ regs + TSADCV3_HSHUT_PD); ++} ++ + static void rk_tsadcv2_control(void __iomem *regs, bool enable) + { + u32 val; +@@ -844,6 +953,18 @@ static void rk_tsadcv3_control(void __io + writel_relaxed(val, regs + TSADCV2_AUTO_CON); + } + ++static void rk_tsadcv4_control(void __iomem *regs, bool enable) ++{ ++ u32 val; ++ ++ if (enable) ++ val = TSADCV2_AUTO_EN | TSADCV2_AUTO_EN_MASK; ++ else ++ val = TSADCV2_AUTO_EN_MASK; ++ ++ writel_relaxed(val, regs + TSADCV2_AUTO_CON); ++} ++ + static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int *temp) + { +@@ -854,6 +975,16 @@ static int rk_tsadcv2_get_temp(const str + return rk_tsadcv2_code_to_temp(table, val, temp); + } + ++static int rk_tsadcv4_get_temp(const struct chip_tsadc_table *table, ++ int chn, void __iomem *regs, int *temp) ++{ ++ u32 val; ++ ++ val = readl_relaxed(regs + TSADCV3_DATA(chn)); ++ ++ return rk_tsadcv2_code_to_temp(table, val, temp); ++} ++ + static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int temp) + { +@@ -888,6 +1019,33 @@ static int rk_tsadcv2_alarm_temp(const s + return 0; + } + ++static int rk_tsadcv3_alarm_temp(const struct chip_tsadc_table *table, ++ int chn, void __iomem *regs, int temp) ++{ ++ u32 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 == INT_MAX) { ++ writel_relaxed(TSADCV2_INT_SRC_EN_MASK(chn), ++ regs + TSADCV3_HT_INT_EN); ++ return 0; ++ } ++ /* Make sure the value is valid */ ++ alarm_value = rk_tsadcv2_temp_to_code(table, temp); ++ if (alarm_value == table->data_mask) ++ return -ERANGE; ++ writel_relaxed(alarm_value & table->data_mask, ++ regs + TSADCV3_COMP_INT(chn)); ++ writel_relaxed(TSADCV2_INT_SRC_EN(chn) | TSADCV2_INT_SRC_EN_MASK(chn), ++ regs + TSADCV3_HT_INT_EN); ++ return 0; ++} ++ + static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table, + int chn, void __iomem *regs, int temp) + { +@@ -907,6 +1065,25 @@ static int rk_tsadcv2_tshut_temp(const s + return 0; + } + ++static int rk_tsadcv3_tshut_temp(const struct chip_tsadc_table *table, ++ int chn, void __iomem *regs, int temp) ++{ ++ u32 tshut_value; ++ ++ /* Make sure the value is valid */ ++ tshut_value = rk_tsadcv2_temp_to_code(table, temp); ++ if (tshut_value == table->data_mask) ++ return -ERANGE; ++ ++ writel_relaxed(tshut_value, regs + TSADCV3_COMP_SHUT(chn)); ++ ++ /* TSHUT will be valid */ ++ writel_relaxed(TSADCV3_AUTO_SRC_EN(chn) | TSADCV3_AUTO_SRC_EN_MASK(chn), ++ regs + TSADCV3_AUTO_SRC_CON); ++ ++ return 0; ++} ++ + static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, + enum tshut_mode mode) + { +@@ -924,6 +1101,22 @@ static void rk_tsadcv2_tshut_mode(int ch + writel_relaxed(val, regs + TSADCV2_INT_EN); + } + ++static void rk_tsadcv3_tshut_mode(int chn, void __iomem *regs, ++ enum tshut_mode mode) ++{ ++ u32 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); ++ } ++ writel_relaxed(val_gpio, regs + TSADCV3_HSHUT_GPIO_INT_EN); ++ writel_relaxed(val_cru, regs + TSADCV3_HSHUT_CRU_INT_EN); ++} ++ + static const struct rockchip_tsadc_chip px30_tsadc_data = { + .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ +@@ -1119,6 +1312,30 @@ static const struct rockchip_tsadc_chip + }, + }; + ++static const struct rockchip_tsadc_chip rk3528_tsadc_data = { ++ .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ ++ .chn_num = 1, /* one channels for tsadc */ ++ ++ .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_tsadcv11_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 = rk3528_code_table, ++ .length = ARRAY_SIZE(rk3528_code_table), ++ .data_mask = TSADCV2_DATA_MASK, ++ .mode = ADC_INCREMENT, ++ }, ++}; ++ + static const struct rockchip_tsadc_chip rk3568_tsadc_data = { + .chn_id[SENSOR_CPU] = 0, /* cpu sensor is channel 0 */ + .chn_id[SENSOR_GPU] = 1, /* gpu sensor is channel 1 */ +@@ -1177,6 +1394,10 @@ static const struct of_device_id of_rock + .data = (void *)&rk3399_tsadc_data, + }, + { ++ .compatible = "rockchip,rk3528-tsadc", ++ .data = (void *)&rk3528_tsadc_data, ++ }, ++ { + .compatible = "rockchip,rk3568-tsadc", + .data = (void *)&rk3568_tsadc_data, + }, diff --git a/target/linux/rockchip/patches-6.1/303-soc-rockchip-power-domain-Add-always-on.patch b/target/linux/rockchip/patches-6.1/303-soc-rockchip-power-domain-Add-always-on.patch new file mode 100644 index 000000000..aff29efed --- /dev/null +++ b/target/linux/rockchip/patches-6.1/303-soc-rockchip-power-domain-Add-always-on.patch @@ -0,0 +1,61 @@ +From 54d4b6b3014f3122a2235533e6511b0d6ca2cd45 Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Wed, 12 Oct 2022 19:25:38 +0800 +Subject: [PATCH] soc: rockchip: power-domain: Add always on configuration for + power domain + +Signed-off-by: Finley Xiao +Change-Id: Ic57f7f3a564f7d71b680e3c435d0460474b5a4a0 +--- + drivers/soc/rockchip/pm_domains.c | 41 +++++++++++++++++++++++-------- + 1 file changed, 31 insertions(+), 10 deletions(-) + +--- a/drivers/soc/rockchip/pm_domains.c ++++ b/drivers/soc/rockchip/pm_domains.c +@@ -44,6 +44,7 @@ struct rockchip_domain_info { + int pwr_w_mask; + int req_w_mask; + int repair_status_mask; ++ bool always_on; + u32 pwr_offset; + u32 req_offset; + }; +@@ -527,6 +528,26 @@ static void rockchip_pd_detach_dev(struc + pm_clk_destroy(dev); + } + ++static int rockchip_pd_add_alwasy_on_flag(struct rockchip_pm_domain *pd) ++{ ++ int error; ++ ++ if (pd->genpd.flags & GENPD_FLAG_ALWAYS_ON) ++ return 0; ++ pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; ++ if (!rockchip_pmu_domain_is_on(pd)) { ++ error = rockchip_pd_power(pd, true); ++ if (error) { ++ dev_err(pd->pmu->dev, ++ "failed to power on domain '%s': %d\n", ++ pd->genpd.name, error); ++ return error; ++ } ++ } ++ ++ return 0; ++} ++ + static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, + struct device_node *node) + { +@@ -645,6 +666,11 @@ static int rockchip_pm_add_one_domain(st + pd->genpd.flags = GENPD_FLAG_PM_CLK; + if (pd_info->active_wakeup) + pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; ++ if (pd_info->always_on) { ++ error = rockchip_pd_add_alwasy_on_flag(pd); ++ if (error) ++ goto err_unprepare_clocks; ++ } + pm_genpd_init(&pd->genpd, NULL, !rockchip_pmu_domain_is_on(pd)); + + pmu->genpd_data.domains[id] = &pd->genpd; diff --git a/target/linux/rockchip/patches-6.1/304-soc-rockchip-power-domain-add-rk3528-support.patch b/target/linux/rockchip/patches-6.1/304-soc-rockchip-power-domain-add-rk3528-support.patch new file mode 100644 index 000000000..ec735c9ce --- /dev/null +++ b/target/linux/rockchip/patches-6.1/304-soc-rockchip-power-domain-add-rk3528-support.patch @@ -0,0 +1,103 @@ +From 2ed777fcd035089bd7996bfa09c023521ecf0e24 Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Fri, 30 Sep 2022 20:11:50 +0800 +Subject: [PATCH] soc: rockchip: power-domain: add power domain support for + rk3528 + +This driver is modified to support RK3528 SoCs. + +Signed-off-by: Finley Xiao +Change-Id: If024916eb7b52ec86ff7533aedefc1bda457b612 +--- + drivers/soc/rockchip/pm_domains.c | 47 +++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +--- a/drivers/soc/rockchip/pm_domains.c ++++ b/drivers/soc/rockchip/pm_domains.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -120,6 +121,20 @@ struct rockchip_pmu { + .active_wakeup = wakeup, \ + } + ++#define DOMAIN_M_A(_name, pwr, status, req, idle, ack, always, wakeup) \ ++{ \ ++ .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), \ ++ .always_on = always, \ ++ .active_wakeup = wakeup, \ ++} ++ + #define DOMAIN_M_O_R(_name, p_offset, pwr, status, r_status, r_offset, req, idle, ack, wakeup) \ + { \ + .name = _name, \ +@@ -164,6 +179,9 @@ struct rockchip_pmu { + #define DOMAIN_RK3399(name, pwr, status, req, wakeup) \ + DOMAIN(name, pwr, status, req, req, req, wakeup) + ++#define DOMAIN_RK3528(name, pwr, req, always, wakeup) \ ++ DOMAIN_M_A(name, pwr, pwr, req, req, req, always, wakeup) ++ + #define DOMAIN_RK3568(name, pwr, req, wakeup) \ + DOMAIN_M(name, pwr, pwr, req, req, req, wakeup) + +@@ -1037,6 +1055,18 @@ static const struct rockchip_domain_info + [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399("sdioaudio", BIT(31), BIT(31), BIT(29), true), + }; + ++static const struct rockchip_domain_info rk3528_pm_domains[] = { ++ [RK3528_PD_PMU] = DOMAIN_RK3528("pmu", 0, BIT(0), true, false), ++ [RK3528_PD_BUS] = DOMAIN_RK3528("bus", 0, BIT(1), true, false), ++ [RK3528_PD_DDR] = DOMAIN_RK3528("ddr", 0, BIT(2), true, false), ++ [RK3528_PD_MSCH] = DOMAIN_RK3528("msch", 0, BIT(3), true, false), ++ [RK3528_PD_GPU] = DOMAIN_RK3528("gpu", BIT(0), BIT(4), true, false), ++ [RK3528_PD_RKVDEC] = DOMAIN_RK3528("vdec", 0, BIT(5), true, false), ++ [RK3528_PD_RKVENC] = DOMAIN_RK3528("venc", 0, BIT(6), true, false), ++ [RK3528_PD_VO] = DOMAIN_RK3528("vo", 0, BIT(7), true, false), ++ [RK3528_PD_VPU] = DOMAIN_RK3528("vpu", 0, BIT(8), true, false), ++}; ++ + static const struct rockchip_domain_info rk3568_pm_domains[] = { + [RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false), + [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false), +@@ -1216,6 +1246,17 @@ static const struct rockchip_pmu_info rk + .domain_info = rk3399_pm_domains, + }; + ++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 = ARRAY_SIZE(rk3528_pm_domains), ++ .domain_info = rk3528_pm_domains, ++}; ++ + static const struct rockchip_pmu_info rk3568_pmu = { + .pwr_offset = 0xa0, + .status_offset = 0x98, +@@ -1296,6 +1337,10 @@ static const struct of_device_id rockchi + .data = (void *)&rk3399_pmu, + }, + { ++ .compatible = "rockchip,rk3528-power-controller", ++ .data = (void *)&rk3528_pmu, ++ }, ++ { + .compatible = "rockchip,rk3568-power-controller", + .data = (void *)&rk3568_pmu, + }, diff --git a/target/linux/rockchip/patches-6.1/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch b/target/linux/rockchip/patches-6.1/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch new file mode 100644 index 000000000..1d48c4ae5 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch @@ -0,0 +1,177 @@ +From 16f512f1e10375dc48aa6c26cedeb7079aba01de Mon Sep 17 00:00:00 2001 +From: Joseph Chen +Date: Sat, 13 Aug 2022 01:15:20 +0000 +Subject: [PATCH] clk: rockchip: Add clock controller for the RK3528 + +Add the clock tree definition for the new RK3528 SoC. + +gmac1 clocks are all controlled by GRF, but CRU helps to abstract +these two clocks for gmac1 since the clock source is from CRU. + +The io-in clocks are module phy output clock, gating child +clocks by disabling phy output but not CRU gate. + +Add gmac0 clocks. +They are all orphans if clk_gmac0_io_i is not registered by +GMAC driver. But it's fine that GMAC driver only get it but +not to set/get rate. + +Add CLK_SET_RATE_PARENT for mclk_sai_i2s0/1. +Allowed to change parent rate. + +Add CLK_SET_RATE_NO_REPARENT for dclk_vop0. +dclk_vop0 is often used for HDMI, it prefers parent clock from +clk_hdmiphy_pixel_io for better clock quality and any rate. +It assigns clk_hdmiphy_pixel_io as parent in dts and hope not to +change parent any more. + +Add CLK_SET_RATE_PARENT for aclk_gpu. +Allow aclk_gpu and aclk_gpu_mali to change parent rate. + +Add CLK_SET_RATE_PARENT for aclk_rkvdec_pvtmux_root. +Allow aclk_rkvdec_pvtmux_root and aclk_rkvdec to change parent rate. + +set aclk_m_core = core_clk/2. +aclk_m_core signoff is 550M, but we set div=2 for better +performance. + +Add CLK_IS_CRITICAL for clk_32k. +Mainly for pvtpll during reboot stage. + +Add CLK_IS_CRITICAL for all IOC clocks. +IOC doesn't share clock with GRF. The iomux can't be changed if they +are disabled. + +Disable aclk_{vpu,vpu_l,vo}_root rate change +They are all shared by multiple modules, disable rate change +by modules. + +Don't register clk_uart_jtag +It's for force jtag uart delay counter. It must be open +for box product without tf card but with uart0. + +Signed-off-by: Joseph Chen +Signed-off-by: Elaine Zhang +Change-Id: I09745b6a31484d6a27f04e608268d9738c1fe224 +--- + drivers/clk/rockchip/Kconfig | 7 + + drivers/clk/rockchip/Makefile | 1 + + drivers/clk/rockchip/clk-rk3528.c | 1187 +++++++++++++++++++++++++++++ + drivers/clk/rockchip/clk.h | 28 + + 4 files changed, 1223 insertions(+) + create mode 100644 drivers/clk/rockchip/clk-rk3528.c + +--- a/drivers/clk/rockchip/Kconfig ++++ b/drivers/clk/rockchip/Kconfig +@@ -93,6 +93,13 @@ config CLK_RK3399 + help + Build the driver for RK3399 Clock Driver. + ++config CLK_RK3528 ++ bool "Rockchip RK3528 clock controller support" ++ depends on ARM64 || COMPILE_TEST ++ default y ++ help ++ Build the driver for RK3528 Clock Driver. ++ + config CLK_RK3568 + bool "Rockchip RK3568 clock controller support" + depends on ARM64 || COMPILE_TEST +--- a/drivers/clk/rockchip/Makefile ++++ b/drivers/clk/rockchip/Makefile +@@ -27,4 +27,5 @@ obj-$(CONFIG_CLK_RK3308) += clk-r + obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o + obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o + obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o ++obj-$(CONFIG_CLK_RK3528) += clk-rk3528.o + obj-$(CONFIG_CLK_RK3568) += clk-rk3568.o +--- a/drivers/clk/rockchip/clk.c ++++ b/drivers/clk/rockchip/clk.c +@@ -514,6 +514,14 @@ void rockchip_clk_register_branches(stru + ctx->reg_base + list->gate_offset, + list->gate_shift, list->gate_flags, &ctx->lock); + break; ++ case branch_gate_no_set_rate: ++ flags &= ~CLK_SET_RATE_PARENT; ++ ++ clk = clk_register_gate(NULL, list->name, ++ list->parent_names[0], flags, ++ ctx->reg_base + list->gate_offset, ++ list->gate_shift, list->gate_flags, &ctx->lock); ++ break; + case branch_composite: + clk = rockchip_clk_register_branch(list->name, + list->parent_names, list->num_parents, +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -207,6 +207,34 @@ struct clk; + #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) + #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) + ++#define RK3528_PMU_CRU_BASE 0x10000 ++#define RK3528_PCIE_CRU_BASE 0x20000 ++#define RK3528_DDRPHY_CRU_BASE 0x28000 ++#define RK3528_VPU_GRF_BASE 0x40000 ++#define RK3528_VO_GRF_BASE 0x60000 ++#define RK3528_SDMMC_CON0 (RK3528_VO_GRF_BASE + 0x24) ++#define RK3528_SDMMC_CON1 (RK3528_VO_GRF_BASE + 0x28) ++#define RK3528_SDIO0_CON0 (RK3528_VPU_GRF_BASE + 0x4) ++#define RK3528_SDIO0_CON1 (RK3528_VPU_GRF_BASE + 0x8) ++#define RK3528_SDIO1_CON0 (RK3528_VPU_GRF_BASE + 0xc) ++#define RK3528_SDIO1_CON1 (RK3528_VPU_GRF_BASE + 0x10) ++#define RK3528_PLL_CON(x) RK2928_PLL_CON(x) ++#define RK3528_PCIE_PLL_CON(x) ((x) * 0x4 + RK3528_PCIE_CRU_BASE) ++#define RK3528_DDRPHY_PLL_CON(x) ((x) * 0x4 + RK3528_DDRPHY_CRU_BASE) ++#define RK3528_MODE_CON 0x280 ++#define RK3528_CLKSEL_CON(x) ((x) * 0x4 + 0x300) ++#define RK3528_CLKGATE_CON(x) ((x) * 0x4 + 0x800) ++#define RK3528_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) ++#define RK3528_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PMU_CRU_BASE) ++#define RK3528_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_PMU_CRU_BASE) ++#define RK3528_PCIE_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PCIE_CRU_BASE) ++#define RK3528_PCIE_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_PCIE_CRU_BASE) ++#define RK3528_DDRPHY_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_DDRPHY_CRU_BASE) ++#define RK3528_DDRPHY_MODE_CON (0x280 + RK3528_DDRPHY_CRU_BASE) ++#define RK3528_GLB_CNT_TH 0xc00 ++#define RK3528_GLB_SRST_FST 0xc08 ++#define RK3528_GLB_SRST_SND 0xc0c ++ + #define RK3568_PLL_CON(x) RK2928_PLL_CON(x) + #define RK3568_MODE_CON0 0xc0 + #define RK3568_MISC_CON0 0xc4 +@@ -345,6 +373,7 @@ struct rockchip_pll_clock { + }; + + #define ROCKCHIP_PLL_SYNC_RATE BIT(0) ++#define ROCKCHIP_PLL_FIXED_MODE BIT(1) + + #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ + _lshift, _pflags, _rtable) \ +@@ -448,6 +477,7 @@ enum rockchip_clk_branch_type { + branch_muxgrf, + branch_divider, + branch_fraction_divider, ++ branch_gate_no_set_rate, + branch_gate, + branch_mmc, + branch_inverter, +@@ -768,6 +798,19 @@ struct rockchip_clk_branch { + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ ++ .flags = f, \ ++ .gate_offset = o, \ ++ .gate_shift = b, \ ++ .gate_flags = gf, \ ++ } ++ ++#define GATE_NO_SET_RATE(_id, cname, pname, f, o, b, gf) \ ++ { \ ++ .id = _id, \ ++ .branch_type = branch_gate_no_set_rate, \ ++ .name = cname, \ ++ .parent_names = (const char *[]){ pname }, \ ++ .num_parents = 1, \ + .flags = f, \ + .gate_offset = o, \ + .gate_shift = b, \ diff --git a/target/linux/rockchip/patches-6.1/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch b/target/linux/rockchip/patches-6.1/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch new file mode 100644 index 000000000..e94f979a8 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch @@ -0,0 +1,227 @@ +From 61c0ac431798861b0696ccc549138b2eec8a4766 Mon Sep 17 00:00:00 2001 +From: David Wu +Date: Sat, 24 Sep 2022 18:29:52 +0800 +Subject: [PATCH] ethernet: stmmac: dwmac-rk: Add GMAC support for RK3528 + +Add constants and callback functions for the dwmac on RK3528 Soc. +As can be seen, the base structure is the same. In addition, there +is an internal phy inside with Gmac0. + +Signed-off-by: David Wu +Change-Id: I8a69a1239ed3ae91bfe44c96287210da758f9cf9 +--- + .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 179 +++++++++++++++++- + 1 file changed, 173 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -1142,6 +1142,201 @@ static const struct rk_gmac_ops rk3399_o + .set_rmii_speed = rk3399_set_rmii_speed, + }; + ++#define RK3528_VO_GRF_GMAC_CON 0X60018 ++#define RK3528_VPU_GRF_GMAC_CON5 0X40018 ++#define RK3528_VPU_GRF_GMAC_CON6 0X4001c ++ ++#define RK3528_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) ++#define RK3528_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) ++#define RK3528_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) ++#define RK3528_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) ++ ++#define RK3528_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8) ++#define RK3528_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0) ++ ++#define RK3528_GMAC0_PHY_INTF_SEL_RMII GRF_BIT(1) ++#define RK3528_GMAC1_PHY_INTF_SEL_RGMII GRF_CLR_BIT(8) ++#define RK3528_GMAC1_PHY_INTF_SEL_RMII GRF_BIT(8) ++ ++#define RK3528_GMAC1_CLK_SELET_CRU GRF_CLR_BIT(12) ++#define RK3528_GMAC1_CLK_SELET_IO GRF_BIT(12) ++ ++#define RK3528_GMAC0_CLK_RMII_DIV2 GRF_BIT(3) ++#define RK3528_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(3) ++#define RK3528_GMAC1_CLK_RMII_DIV2 GRF_BIT(10) ++#define RK3528_GMAC1_CLK_RMII_DIV20 GRF_CLR_BIT(10) ++ ++#define RK3528_GMAC1_CLK_RGMII_DIV1 \ ++ (GRF_CLR_BIT(11) | GRF_CLR_BIT(10)) ++#define RK3528_GMAC1_CLK_RGMII_DIV5 \ ++ (GRF_BIT(11) | GRF_BIT(10)) ++#define RK3528_GMAC1_CLK_RGMII_DIV50 \ ++ (GRF_BIT(11) | GRF_CLR_BIT(10)) ++ ++#define RK3528_GMAC0_CLK_RMII_GATE GRF_BIT(2) ++#define RK3528_GMAC0_CLK_RMII_NOGATE GRF_CLR_BIT(2) ++#define RK3528_GMAC1_CLK_RMII_GATE GRF_BIT(9) ++#define RK3528_GMAC1_CLK_RMII_NOGATE GRF_CLR_BIT(9) ++ ++#define RK3528_VO_GRF_MACPHY_CON0 0X6001c ++#define RK3528_VO_GRF_MACPHY_CON1 0X60020 ++ ++static void rk3528_set_to_rgmii(struct rk_priv_data *bsp_priv, ++ int tx_delay, int rx_delay) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return; ++ } ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, ++ RK3528_GMAC1_PHY_INTF_SEL_RGMII); ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, ++ RK3528_GMAC_CLK_RX_DL_CFG(rx_delay) | ++ RK3528_GMAC_CLK_TX_DL_CFG(tx_delay)); ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON6, ++ RK3528_GMAC_CLK_RX_DL_CFG(rx_delay) | ++ RK3528_GMAC_CLK_TX_DL_CFG(tx_delay)); ++} ++ ++static void rk3528_set_to_rmii(struct rk_priv_data *bsp_priv) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ unsigned int id = bsp_priv->id; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); ++ return; ++ } ++ ++ if (id == 1) ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, ++ RK3528_GMAC1_PHY_INTF_SEL_RMII); ++ else ++ regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON, ++ RK3528_GMAC0_PHY_INTF_SEL_RMII); ++} ++ ++static void rk3528_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ unsigned int val = 0; ++ ++ switch (speed) { ++ case 10: ++ val = RK3528_GMAC1_CLK_RGMII_DIV50; ++ break; ++ case 100: ++ val = RK3528_GMAC1_CLK_RGMII_DIV5; ++ break; ++ case 1000: ++ val = RK3528_GMAC1_CLK_RGMII_DIV1; ++ break; ++ default: ++ goto err; ++ } ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, val); ++ return; ++err: ++ dev_err(dev, "unknown RGMII speed value for GMAC speed=%d", speed); ++} ++ ++static void rk3528_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ unsigned int val, offset, id = bsp_priv->id; ++ ++ switch (speed) { ++ case 10: ++ val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV20 : ++ RK3528_GMAC0_CLK_RMII_DIV20; ++ break; ++ case 100: ++ val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV2 : ++ RK3528_GMAC0_CLK_RMII_DIV2; ++ break; ++ default: ++ goto err; ++ } ++ ++ offset = (id == 1) ? RK3528_VPU_GRF_GMAC_CON5 : RK3528_VO_GRF_GMAC_CON; ++ regmap_write(bsp_priv->grf, offset, val); ++ ++ return; ++err: ++ dev_err(dev, "unknown RMII speed value for GMAC speed=%d", speed); ++} ++ ++static void rk3528_set_clock_selection(struct rk_priv_data *bsp_priv, ++ bool input, bool enable) ++{ ++ unsigned int value, id = bsp_priv->id; ++ ++ if (id == 1) { ++ value = input ? RK3528_GMAC1_CLK_SELET_IO : ++ RK3528_GMAC1_CLK_SELET_CRU; ++ value |= enable ? RK3528_GMAC1_CLK_RMII_NOGATE : ++ RK3528_GMAC1_CLK_RMII_GATE; ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, value); ++ } else { ++ value = enable ? RK3528_GMAC0_CLK_RMII_NOGATE : ++ RK3528_GMAC0_CLK_RMII_GATE; ++ regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON, value); ++ } ++} ++ ++/* Integrated FEPHY */ ++#define RK_FEPHY_SHUTDOWN GRF_BIT(1) ++#define RK_FEPHY_POWERUP GRF_CLR_BIT(1) ++#define RK_FEPHY_INTERNAL_RMII_SEL GRF_BIT(6) ++#define RK_FEPHY_24M_CLK_SEL (GRF_BIT(8) | GRF_BIT(9)) ++#define RK_FEPHY_PHY_ID GRF_BIT(11) ++ ++#define RK_FEPHY_BGS HIWORD_UPDATE(0x0, 0xf, 0) ++ ++static void rk3528_integrated_sphy_power(struct rk_priv_data *priv) ++{ ++ struct device *dev = &priv->pdev->dev; ++ ++ if (IS_ERR(priv->grf) || !priv->phy_reset) { ++ dev_err(dev, "%s: Missing rockchip,grf or phy_reset property\n", ++ __func__); ++ return; ++ } ++ ++ unsigned int bgs = RK_FEPHY_BGS; ++ ++ reset_control_assert(priv->phy_reset); ++ udelay(20); ++ regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON0, ++ RK_FEPHY_POWERUP | ++ RK_FEPHY_INTERNAL_RMII_SEL | ++ RK_FEPHY_24M_CLK_SEL | ++ RK_FEPHY_PHY_ID); ++ ++ /*if (priv->otp_data > 0) ++ bgs = HIWORD_UPDATE(priv->otp_data, 0xf, 0);*/ ++ ++ regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON1, bgs); ++ usleep_range(10 * 1000, 12 * 1000); ++ reset_control_deassert(priv->phy_reset); ++ usleep_range(50 * 1000, 60 * 1000); ++} ++ ++static const struct rk_gmac_ops rk3528_ops = { ++ .set_to_rgmii = rk3528_set_to_rgmii, ++ .set_to_rmii = rk3528_set_to_rmii, ++ .set_rgmii_speed = rk3528_set_rgmii_speed, ++ .set_rmii_speed = rk3528_set_rmii_speed, ++ .set_clock_selection = rk3528_set_clock_selection, ++ .integrated_phy_powerup = rk3528_integrated_sphy_power, ++}; ++ + #define RK3568_GRF_GMAC0_CON0 0x0380 + #define RK3568_GRF_GMAC0_CON1 0x0384 + #define RK3568_GRF_GMAC1_CON0 0x0388 +@@ -2107,6 +2302,7 @@ static const struct of_device_id rk_gmac + { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, + { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, + { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, ++ { .compatible = "rockchip,rk3528-gmac", .data = &rk3528_ops }, + { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops }, + { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops }, + { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, diff --git a/target/linux/rockchip/patches-6.1/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch b/target/linux/rockchip/patches-6.1/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch new file mode 100644 index 000000000..b3f340595 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch @@ -0,0 +1,64 @@ +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1597,6 +1597,53 @@ static const struct rockchip_usb2phy_cfg + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3528_phy_cfgs[] = { ++ { ++ .reg = 0xffdf0000, ++ .num_ports = 2, ++ .clkout_ctl = { 0x041c, 7, 2, 0, 0x27 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x6004c, 15, 0, 0, 0x1d1 }, ++ .bvalid_det_en = { 0x60074, 3, 2, 0, 3 }, ++ .bvalid_det_st = { 0x60078, 3, 2, 0, 3 }, ++ .bvalid_det_clr = { 0x6007c, 3, 2, 0, 3 }, ++ .id_det_en = { 0x60074, 5, 4, 0, 3 }, ++ .id_det_st = { 0x60078, 5, 4, 0, 3 }, ++ .id_det_clr = { 0x6007c, 5, 4, 0, 3 }, ++ .ls_det_en = { 0x60074, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x60078, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x6007c, 0, 0, 0, 1 }, ++ .utmi_avalid = { 0x6006c, 1, 1, 0, 1 }, ++ .utmi_bvalid = { 0x6006c, 0, 0, 0, 1 }, ++ .utmi_id = { 0x6006c, 6, 6, 0, 1 }, ++ .utmi_ls = { 0x6006c, 5, 4, 0, 1 }, ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x6005c, 15, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x60090, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x60094, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x60098, 0, 0, 0, 1 }, ++ .utmi_ls = { 0x6006c, 13, 12, 0, 1 }, ++ .utmi_hstdet = { 0x6006c, 15, 15, 0, 1 } ++ } ++ }, ++ .chg_det = { ++ .opmode = { 0x6004c, 3, 0, 5, 1 }, ++ .cp_det = { 0x6006c, 19, 19, 0, 1 }, ++ .dcp_det = { 0x6006c, 18, 18, 0, 1 }, ++ .dp_det = { 0x6006c, 20, 20, 0, 1 }, ++ .idm_sink_en = { 0x60058, 1, 1, 0, 1 }, ++ .idp_sink_en = { 0x60058, 0, 0, 0, 1 }, ++ .idp_src_en = { 0x60058, 2, 2, 0, 1 }, ++ .rdm_pdwn_en = { 0x60058, 3, 3, 0, 1 }, ++ .vdm_src_en = { 0x60058, 5, 5, 0, 1 }, ++ .vdp_src_en = { 0x60058, 4, 4, 0, 1 }, ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { + { + .reg = 0xfe8a0000, +@@ -1713,6 +1760,7 @@ static const struct of_device_id rockchi + { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, + { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, + { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, ++ { .compatible = "rockchip,rk3528-usb2phy", .data = &rk3528_phy_cfgs }, + { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, + { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, + {} diff --git a/target/linux/rockchip/patches-6.1/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch b/target/linux/rockchip/patches-6.1/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch new file mode 100644 index 000000000..6881e5743 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch @@ -0,0 +1,176 @@ +From 432666b59bdbef2c386e92dd88be4206203ff8ac Mon Sep 17 00:00:00 2001 +From: Jon Lin +Date: Sat, 8 Oct 2022 15:48:37 +0800 +Subject: [PATCH] phy: rockchip: naneng-combphy: add support rk3528 + +1. The layout of controller registers has changed, remove legacy config; +2. Using the default value for grf register; +3. sync to use rk3568 parameter for phy PLL, signal test pass +4. Add 24MHz refclk for rk3528 PCIe, Enable the counting clock of the +rterm detect by setting tx_trim[14] bit for rx detecting. +5. set SSC modulation frequency to 31.5KHz + +Change-Id: I45742c416d452037e61b7a7b8765269931d56402 +Signed-off-by: Jon Lin +Signed-off-by: Jianwei Zheng +--- + .../rockchip/phy-rockchip-naneng-combphy.c | 139 +++++++++++++++++- + 1 file changed, 138 insertions(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -79,7 +79,7 @@ + struct rockchip_combphy_priv; + + struct combphy_reg { +- u16 offset; ++ u32 offset; + u16 bitend; + u16 bitstart; + u16 disable; +@@ -89,11 +89,13 @@ struct combphy_reg { + struct rockchip_combphy_grfcfg { + struct combphy_reg pcie_mode_set; + struct combphy_reg usb_mode_set; ++ struct combphy_reg u3otg0_port_en; + 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; +@@ -359,6 +361,120 @@ static int rockchip_combphy_probe(struct + return PTR_ERR_OR_ZERO(phy_provider); + } + ++static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) ++{ ++ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ++ unsigned long rate; ++ u32 val; ++ ++ switch (priv->type) { ++ case PHY_TYPE_PCIE: ++ /* Set SSC downward spread spectrum. */ ++ val = readl(priv->mmio + 0x18); ++ val &= ~GENMASK(5, 4); ++ val |= 0x01 << 4; ++ writel(val, priv->mmio + 0x18); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); ++ break; ++ ++ case PHY_TYPE_USB3: ++ /* Set SSC downward spread spectrum. */ ++ val = readl(priv->mmio + 0x18); ++ val &= ~GENMASK(5, 4); ++ val |= 0x01 << 4; ++ writel(val, priv->mmio + 0x18); ++ ++ /* Enable adaptive CTLE for USB3.0 Rx. */ ++ val = readl(priv->mmio + 0x200); ++ val &= ~GENMASK(17, 17); ++ val |= 0x01 << 17; ++ writel(val, priv->mmio + 0x200); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); ++ break; ++ ++ default: ++ dev_err(priv->dev, "incompatible PHY type\n"); ++ return -EINVAL; ++ } ++ ++ rate = clk_get_rate(priv->refclk); ++ ++ switch (rate) { ++ case REF_CLOCK_24MHz: ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); ++ if (priv->type == PHY_TYPE_USB3) { ++ /* Set ssc_cnt[10:0]=00101111101 & 31.5KHz. */ ++ val = readl(priv->mmio + 0x100); ++ val &= ~GENMASK(10, 0); ++ val |= 0x17d; ++ writel(val, priv->mmio + 0x100); ++ } else if (priv->type == PHY_TYPE_PCIE) { ++ /* tx_trim[14]=1, Enable the counting clock of the rterm detect */ ++ val = readl(priv->mmio + 0x218); ++ val |= (1 << 14); ++ writel(val, priv->mmio + 0x218); ++ } ++ break; ++ ++ case REF_CLOCK_100MHz: ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); ++ if (priv->type == PHY_TYPE_PCIE) { ++ /* PLL KVCO tuning fine. */ ++ val = readl(priv->mmio + 0x18); ++ val &= ~(0x7 << 10); ++ val |= 0x2 << 10; ++ writel(val, priv->mmio + 0x18); ++ ++ /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000 */ ++ val = readl(priv->mmio + 0x108); ++ val &= ~(0x7f7); ++ val |= 0x4f0; ++ writel(val, priv->mmio + 0x108); ++ } ++ break; ++ ++ default: ++ dev_err(priv->dev, "unsupported rate: %lu\n", rate); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { ++ /* pipe-phy-grf */ ++ .pcie_mode_set = { 0x48000, 5, 0, 0x00, 0x11 }, ++ .usb_mode_set = { 0x48000, 5, 0, 0x00, 0x04 }, ++ .pipe_rxterm_set = { 0x48000, 12, 12, 0x00, 0x01 }, ++ .pipe_txelec_set = { 0x48004, 1, 1, 0x00, 0x01 }, ++ .pipe_txcomp_set = { 0x48004, 4, 4, 0x00, 0x01 }, ++ .pipe_clk_24m = { 0x48004, 14, 13, 0x00, 0x00 }, ++ .pipe_clk_100m = { 0x48004, 14, 13, 0x00, 0x02 }, ++ .pipe_rxterm_sel = { 0x48008, 8, 8, 0x00, 0x01 }, ++ .pipe_txelec_sel = { 0x48008, 12, 12, 0x00, 0x01 }, ++ .pipe_txcomp_sel = { 0x48008, 15, 15, 0x00, 0x01 }, ++ .pipe_clk_ext = { 0x4800c, 9, 8, 0x02, 0x01 }, ++ .pipe_phy_status = { 0x48034, 6, 6, 0x01, 0x00 }, ++ .con0_for_pcie = { 0x48000, 15, 0, 0x00, 0x110 }, ++ .con1_for_pcie = { 0x48004, 15, 0, 0x00, 0x00 }, ++ .con2_for_pcie = { 0x48008, 15, 0, 0x00, 0x101 }, ++ .con3_for_pcie = { 0x4800c, 15, 0, 0x00, 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 int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + { + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; +@@ -561,6 +677,10 @@ static const struct rockchip_combphy_cfg + + static const struct of_device_id rockchip_combphy_of_match[] = { + { ++ .compatible = "rockchip,rk3528-naneng-combphy", ++ .data = &rk3528_combphy_cfgs, ++ }, ++ { + .compatible = "rockchip,rk3568-naneng-combphy", + .data = &rk3568_combphy_cfgs, + }, diff --git a/target/linux/rockchip/patches-6.1/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch b/target/linux/rockchip/patches-6.1/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch new file mode 100644 index 000000000..ea040ade7 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch @@ -0,0 +1,107 @@ +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -295,19 +295,20 @@ static void dwcmshc_rk3568_set_clock(str + 0x3 << 19; /* post-change delay */ + sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); + +- if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || +- host->mmc->ios.timing == MMC_TIMING_MMC_HS400) ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) + txclk_tapnum = priv->txclk_tapnum; + +- if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { + txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES; + +- extra = DLL_CMDOUT_SRC_CLK_NEG | +- DLL_CMDOUT_EN_SRC_CLK_NEG | +- DWCMSHC_EMMC_DLL_DLYENA | +- DLL_CMDOUT_TAPNUM_90_DEGREES | +- DLL_CMDOUT_TAPNUM_FROM_SW; +- sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT); ++ if (priv->devtype != DWCMSHC_RK3568) { ++ extra = DLL_CMDOUT_SRC_CLK_NEG | ++ DLL_CMDOUT_EN_SRC_CLK_NEG | ++ DWCMSHC_EMMC_DLL_DLYENA | ++ DLL_CMDOUT_TAPNUM_90_DEGREES | ++ DLL_CMDOUT_TAPNUM_FROM_SW; ++ sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT); ++ } + } + + extra = DWCMSHC_EMMC_DLL_DLYENA | +@@ -355,6 +356,15 @@ static const struct sdhci_ops sdhci_dwcm + .adma_write_desc = dwcmshc_adma_write_desc, + }; + ++static const struct sdhci_ops sdhci_dwcmshc_rk3528_ops = { ++ .set_clock = dwcmshc_rk3568_set_clock, ++ .set_bus_width = sdhci_set_bus_width, ++ .set_uhs_signaling = dwcmshc_set_uhs_signaling, ++ .get_max_clock = sdhci_pltfm_clk_get_max_clock, ++ .reset = rk35xx_sdhci_reset, ++ .adma_write_desc = dwcmshc_adma_write_desc, ++}; ++ + static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { + .ops = &sdhci_dwcmshc_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, +@@ -378,6 +388,14 @@ static const struct sdhci_pltfm_data sdh + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, + }; + ++static const struct sdhci_pltfm_data sdhci_dwcmshc_rk3528_pdata = { ++ .ops = &sdhci_dwcmshc_rk3528_ops, ++ .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | ++ SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, ++}; ++ + static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) + { + int err; +@@ -443,6 +461,10 @@ static const struct of_device_id sdhci_d + .data = &sdhci_dwcmshc_rk35xx_pdata, + }, + { ++ .compatible = "rockchip,rk3528-dwcmshc", ++ .data = &sdhci_dwcmshc_rk3528_pdata, ++ }, ++ { + .compatible = "snps,dwcmshc-sdhci", + .data = &sdhci_dwcmshc_pdata, + }, +@@ -521,17 +543,18 @@ static int dwcmshc_probe(struct platform + host->mmc_host_ops.request = dwcmshc_request; + host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; + +- if (pltfm_data == &sdhci_dwcmshc_rk35xx_pdata) { ++ if ((pltfm_data == &sdhci_dwcmshc_rk35xx_pdata) || ++ (pltfm_data == &sdhci_dwcmshc_rk3528_pdata)) { + rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL); + if (!rk_priv) { + err = -ENOMEM; + goto err_clk; + } + +- if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc")) +- rk_priv->devtype = DWCMSHC_RK3588; +- else ++ if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3568-dwcmshc")) + rk_priv->devtype = DWCMSHC_RK3568; ++ else ++ rk_priv->devtype = DWCMSHC_RK3588; + + priv->priv = rk_priv; + +--- a/drivers/pci/controller/dwc/Makefile ++++ b/drivers/pci/controller/dwc/Makefile +@@ -16,6 +16,7 @@ obj-$(CONFIG_PCIE_QCOM_EP) += pcie-qcom- + obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o + obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o + obj-$(CONFIG_PCIE_ROCKCHIP_DW_HOST) += pcie-dw-rockchip.o ++obj-$(CONFIG_PCIE_ROCKCHIP_DW_HOST) += pcie-dw-rkvendor.o + obj-$(CONFIG_PCIE_INTEL_GW) += pcie-intel-gw.o + obj-$(CONFIG_PCIE_KEEMBAY) += pcie-keembay.o + obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o diff --git a/target/linux/rockchip/patches-6.1/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch b/target/linux/rockchip/patches-6.1/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch new file mode 100644 index 000000000..ce7733722 --- /dev/null +++ b/target/linux/rockchip/patches-6.1/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch @@ -0,0 +1,110 @@ +From 4ff037c13c1e7ab16362d39a59ebb8fffb929f99 Mon Sep 17 00:00:00 2001 +From: Shawn Lin +Date: Wed, 15 Apr 2020 09:19:09 +0800 +Subject: [PATCH] mmc: dw_mmc-rockchip: add v2 tuning support + +v2 tuning will inherit pre-stage loader's phase +settings for the first time, and do re-tune if +necessary. Re-tune will still try the rough degrees, +for instance, 90, 180, 270, 360 but continue to do the +fine tuning if sample window isn't good enough. + +Change-Id: I593384ee381d09df5b9adfc29a18eb22517b2764 +Signed-off-by: Shawn Lin +--- + drivers/mmc/host/dw_mmc-rockchip.c | 48 ++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +--- a/drivers/mmc/host/dw_mmc-rockchip.c ++++ b/drivers/mmc/host/dw_mmc-rockchip.c +@@ -24,6 +24,8 @@ struct dw_mci_rockchip_priv_data { + struct clk *sample_clk; + int default_sample_phase; + int num_phases; ++ int last_degree; ++ bool use_v2_tuning; + }; + + static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) +@@ -134,6 +136,58 @@ static void dw_mci_rk3288_set_ios(struct + #define TUNING_ITERATION_TO_PHASE(i, num_phases) \ + (DIV_ROUND_UP((i) * 360, num_phases)) + ++static int dw_mci_v2_execute_tuning(struct dw_mci_slot *slot, u32 opcode) ++{ ++ struct dw_mci *host = slot->host; ++ struct dw_mci_rockchip_priv_data *priv = host->priv; ++ struct mmc_host *mmc = slot->mmc; ++ u32 degrees[4] = {0, 90, 180, 270}, degree; ++ int i; ++ static bool inherit = true; ++ ++ if (inherit) { ++ inherit = false; ++ i = clk_get_phase(priv->sample_clk) / 90; ++ degree = degrees[i]; ++ goto done; ++ } ++ ++ /* ++ * 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 < ARRAY_SIZE(degrees); i++) { ++ degree = degrees[i] + priv->last_degree + 90; ++ degree = degree % 360; ++ clk_set_phase(priv->sample_clk, degree); ++ if (mmc_send_tuning(mmc, opcode, NULL)) { ++ /* ++ * Tuning error, the phase is a bad phase, ++ * then try using the calculated best phase. ++ */ ++ dev_info(host->dev, "V2 tuned phase to %d error, try the best phase\n", degree); ++ degree = (degree + 180) % 360; ++ clk_set_phase(priv->sample_clk, degree); ++ if (!mmc_send_tuning(mmc, opcode, NULL)) ++ break; ++ } ++ } ++ ++ if (i == ARRAY_SIZE(degrees)) { ++ dev_warn(host->dev, "V2 All phases bad!"); ++ return -EIO; ++ } ++ ++done: ++ dev_info(host->dev, "V2 Successfully tuned phase to %d\n", degree); ++ priv->last_degree = degree; ++ return 0; ++} ++ + static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode) + { + struct dw_mci *host = slot->host; +@@ -157,6 +211,12 @@ static int dw_mci_rk3288_execute_tuning( + return -EIO; + } + ++ if (priv->use_v2_tuning) { ++ if (!dw_mci_v2_execute_tuning(slot, opcode)) ++ return 0; ++ /* Otherwise we continue using fine tuning */ ++ } ++ + ranges = kmalloc_array(priv->num_phases / 2 + 1, + sizeof(*ranges), GFP_KERNEL); + if (!ranges) +@@ -277,6 +337,9 @@ static int dw_mci_rk3288_parse_dt(struct + &priv->default_sample_phase)) + priv->default_sample_phase = 0; + ++ if (of_property_read_bool(np, "rockchip,use-v2-tuning")) ++ priv->use_v2_tuning = true; ++ + priv->drv_clk = devm_clk_get(host->dev, "ciu-drive"); + if (IS_ERR(priv->drv_clk)) + dev_dbg(host->dev, "ciu-drive not available\n"); diff --git a/target/linux/rockchip/patches-6.6/301-pinctrl-rockchip-add-rk3528-support.patch b/target/linux/rockchip/patches-6.6/301-pinctrl-rockchip-add-rk3528-support.patch new file mode 100644 index 000000000..a5411fe4b --- /dev/null +++ b/target/linux/rockchip/patches-6.6/301-pinctrl-rockchip-add-rk3528-support.patch @@ -0,0 +1,269 @@ +From ee5af82a6f88fd28849ea6d98cf43fbe9cbbbb19 Mon Sep 17 00:00:00 2001 +From: Steven Liu +Date: Thu, 11 Aug 2022 15:15:28 +0800 +Subject: [PATCH] pinctrl: rockchip: add rk3528 support + +Signed-off-by: Steven Liu +Change-Id: I2c1d32907168caf8a8afee6d1f742795b3d13536 +--- + drivers/pinctrl/pinctrl-rockchip.c | 196 ++++++++++++++++++++++++++++- + drivers/pinctrl/pinctrl-rockchip.h | 1 + + 2 files changed, 196 insertions(+), 1 deletion(-) + +--- a/drivers/pinctrl/pinctrl-rockchip.c ++++ b/drivers/pinctrl/pinctrl-rockchip.c +@@ -2018,6 +2018,150 @@ static int rk3568_calc_pull_reg_and_bit( + return 0; + } + ++#define RK3528_DRV_BITS_PER_PIN 8 ++#define RK3528_DRV_PINS_PER_REG 2 ++#define RK3528_DRV_GPIO0_OFFSET 0x100 ++#define RK3528_DRV_GPIO1_OFFSET 0x20120 ++#define RK3528_DRV_GPIO2_OFFSET 0x30160 ++#define RK3528_DRV_GPIO3_OFFSET 0x20190 ++#define RK3528_DRV_GPIO4_OFFSET 0x101C0 ++ ++static int rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl *info = bank->drvdata; ++ ++ *regmap = info->regmap_base; ++ switch (bank->bank_num) { ++ case 0: ++ *reg = RK3528_DRV_GPIO0_OFFSET; ++ break; ++ ++ case 1: ++ *reg = RK3528_DRV_GPIO1_OFFSET; ++ break; ++ ++ case 2: ++ *reg = RK3528_DRV_GPIO2_OFFSET; ++ break; ++ ++ case 3: ++ *reg = RK3528_DRV_GPIO3_OFFSET; ++ break; ++ ++ case 4: ++ *reg = RK3528_DRV_GPIO4_OFFSET; ++ break; ++ ++ default: ++ dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); ++ break; ++ } ++ ++ *reg += ((pin_num / RK3528_DRV_PINS_PER_REG) * 4); ++ *bit = pin_num % RK3528_DRV_PINS_PER_REG; ++ *bit *= RK3528_DRV_BITS_PER_PIN; ++ ++ return 0; ++} ++ ++#define RK3528_PULL_BITS_PER_PIN 2 ++#define RK3528_PULL_PINS_PER_REG 8 ++#define RK3528_PULL_GPIO0_OFFSET 0x200 ++#define RK3528_PULL_GPIO1_OFFSET 0x20210 ++#define RK3528_PULL_GPIO2_OFFSET 0x30220 ++#define RK3528_PULL_GPIO3_OFFSET 0x20230 ++#define RK3528_PULL_GPIO4_OFFSET 0x10240 ++ ++static int rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl *info = bank->drvdata; ++ ++ *regmap = info->regmap_base; ++ switch (bank->bank_num) { ++ case 0: ++ *reg = RK3528_PULL_GPIO0_OFFSET; ++ break; ++ ++ case 1: ++ *reg = RK3528_PULL_GPIO1_OFFSET; ++ break; ++ ++ case 2: ++ *reg = RK3528_PULL_GPIO2_OFFSET; ++ break; ++ ++ case 3: ++ *reg = RK3528_PULL_GPIO3_OFFSET; ++ break; ++ ++ case 4: ++ *reg = RK3528_PULL_GPIO4_OFFSET; ++ break; ++ ++ default: ++ dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); ++ break; ++ } ++ ++ *reg += ((pin_num / RK3528_PULL_PINS_PER_REG) * 4); ++ *bit = pin_num % RK3528_PULL_PINS_PER_REG; ++ *bit *= RK3528_PULL_BITS_PER_PIN; ++ ++ return 0; ++} ++ ++#define RK3528_SMT_BITS_PER_PIN 1 ++#define RK3528_SMT_PINS_PER_REG 8 ++#define RK3528_SMT_GPIO0_OFFSET 0x400 ++#define RK3528_SMT_GPIO1_OFFSET 0x20410 ++#define RK3528_SMT_GPIO2_OFFSET 0x30420 ++#define RK3528_SMT_GPIO3_OFFSET 0x20430 ++#define RK3528_SMT_GPIO4_OFFSET 0x10440 ++ ++static int rk3528_calc_schmitt_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, ++ struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl *info = bank->drvdata; ++ ++ *regmap = info->regmap_base; ++ switch (bank->bank_num) { ++ case 0: ++ *reg = RK3528_SMT_GPIO0_OFFSET; ++ break; ++ ++ case 1: ++ *reg = RK3528_SMT_GPIO1_OFFSET; ++ break; ++ ++ case 2: ++ *reg = RK3528_SMT_GPIO2_OFFSET; ++ break; ++ ++ case 3: ++ *reg = RK3528_SMT_GPIO3_OFFSET; ++ break; ++ ++ case 4: ++ *reg = RK3528_SMT_GPIO4_OFFSET; ++ break; ++ ++ default: ++ dev_err(info->dev, "unsupported bank_num %d\n", bank->bank_num); ++ break; ++ } ++ ++ *reg += ((pin_num / RK3528_SMT_PINS_PER_REG) * 4); ++ *bit = pin_num % RK3528_SMT_PINS_PER_REG; ++ *bit *= RK3528_SMT_BITS_PER_PIN; ++ return 0; ++} ++ + #define RK3568_DRV_PMU_OFFSET 0x70 + #define RK3568_DRV_GRF_OFFSET 0x200 + #define RK3568_DRV_BITS_PER_PIN 8 +@@ -2341,6 +2485,10 @@ static int rockchip_set_drive_perpin(str + rmask_bits = RK3588_DRV_BITS_PER_PIN; + ret = strength; + goto config; ++ } else if (ctrl->type == RK3528) { ++ rmask_bits = RK3528_DRV_BITS_PER_PIN; ++ ret = (1 << (strength + 1)) - 1; ++ goto config; + } else if (ctrl->type == RK3568) { + rmask_bits = RK3568_DRV_BITS_PER_PIN; + ret = (1 << (strength + 1)) - 1; +@@ -2481,6 +2629,7 @@ static int rockchip_get_pull(struct rock + case RK3328: + case RK3368: + case RK3399: ++ case RK3528: + case RK3568: + case RK3588: + pull_type = bank->pull_type[pin_num / 8]; +@@ -2540,6 +2689,7 @@ static int rockchip_set_pull(struct rock + case RK3328: + case RK3368: + case RK3399: ++ case RK3528: + case RK3568: + case RK3588: + pull_type = bank->pull_type[pin_num / 8]; +@@ -2805,6 +2955,7 @@ static bool rockchip_pinconf_pull_valid( + case RK3328: + case RK3368: + case RK3399: ++ case RK3528: + case RK3568: + case RK3588: + return (pull != PIN_CONFIG_BIAS_PULL_PIN_DEFAULT); +@@ -3930,6 +4081,49 @@ static struct rockchip_pin_ctrl rk3399_p + .drv_calc_reg = rk3399_calc_drv_reg_and_bit, + }; + ++static struct rockchip_pin_bank rk3528_pin_banks[] = { ++ PIN_BANK_IOMUX_FLAGS_OFFSET(0, 32, "gpio0", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0, 0, 0, 0), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(1, 32, "gpio1", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x20020, 0x20028, 0x20030, 0x20038), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(2, 32, "gpio2", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x30040, 0, 0, 0), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(3, 32, "gpio3", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x20060, 0x20068, 0x20070, 0), ++ PIN_BANK_IOMUX_FLAGS_OFFSET(4, 32, "gpio4", ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ IOMUX_WIDTH_4BIT, ++ 0x10080, 0x10088, 0x10090, 0x10098), ++}; ++ ++static struct rockchip_pin_ctrl rk3528_pin_ctrl __maybe_unused = { ++ .pin_banks = rk3528_pin_banks, ++ .nr_banks = ARRAY_SIZE(rk3528_pin_banks), ++ .label = "RK3528-GPIO", ++ .type = RK3528, ++ .pull_calc_reg = rk3528_calc_pull_reg_and_bit, ++ .drv_calc_reg = rk3528_calc_drv_reg_and_bit, ++ .schmitt_calc_reg = rk3528_calc_schmitt_reg_and_bit, ++}; ++ + 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, +@@ -4023,6 +4217,8 @@ static const struct of_device_id rockchi + .data = &rk3368_pin_ctrl }, + { .compatible = "rockchip,rk3399-pinctrl", + .data = &rk3399_pin_ctrl }, ++ { .compatible = "rockchip,rk3528-pinctrl", ++ .data = &rk3528_pin_ctrl }, + { .compatible = "rockchip,rk3568-pinctrl", + .data = &rk3568_pin_ctrl }, + { .compatible = "rockchip,rk3588-pinctrl", +--- a/drivers/pinctrl/pinctrl-rockchip.h ++++ b/drivers/pinctrl/pinctrl-rockchip.h +@@ -196,6 +196,7 @@ enum rockchip_pinctrl_type { + RK3328, + RK3368, + RK3399, ++ RK3528, + RK3568, + RK3588, + }; diff --git a/target/linux/rockchip/patches-6.6/302-thermal-rockchip-add-support-for-rk3528.patch b/target/linux/rockchip/patches-6.6/302-thermal-rockchip-add-support-for-rk3528.patch new file mode 100644 index 000000000..600229e78 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/302-thermal-rockchip-add-support-for-rk3528.patch @@ -0,0 +1,191 @@ +From 1e244fb37e21ce92a32b203cb030510bc3b42d29 Mon Sep 17 00:00:00 2001 +From: Shaohan Yao +Date: Fri, 9 Sep 2022 14:34:08 +0800 +Subject: [PATCH] thermal: rockchip: Support the rk3528 SoC in thermal driver + +There are one Temperature Sensor on rk3528, channel 0 is for chip. + +Signed-off-by: Shaohan Yao +Change-Id: Ib5bbb81615fe9fab80f26cdd2098cfb56746ca15 +--- + drivers/thermal/rockchip_thermal.c | 107 +++++++++++++++++++++++++++++ + 1 file changed, 107 insertions(+) + +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -185,6 +185,8 @@ struct rockchip_thermal_data { + #define TSADCV2_AUTO_PERIOD_HT 0x6c + #define TSADCV3_AUTO_PERIOD 0x154 + #define TSADCV3_AUTO_PERIOD_HT 0x158 ++#define TSADCV9_Q_MAX 0x210 ++#define TSADCV9_FLOW_CON 0x218 + + #define TSADCV2_AUTO_EN BIT(0) + #define TSADCV2_AUTO_EN_MASK BIT(16) +@@ -195,6 +197,7 @@ struct rockchip_thermal_data { + #define TSADCV2_AUTO_TSHUT_POLARITY_MASK BIT(24) + + #define TSADCV3_AUTO_Q_SEL_EN BIT(1) ++#define TSADCV3_AUTO_Q_SEL_EN_MASK BIT(17) + + #define TSADCV2_INT_SRC_EN(chn) BIT(chn) + #define TSADCV2_INT_SRC_EN_MASK(chn) BIT(16 + (chn)) +@@ -208,9 +211,12 @@ struct rockchip_thermal_data { + #define TSADCV2_DATA_MASK 0xfff + #define TSADCV3_DATA_MASK 0x3ff + #define TSADCV4_DATA_MASK 0x1ff ++#define TSADCV5_DATA_MASK 0x7ff + + #define TSADCV2_HIGHT_INT_DEBOUNCE_COUNT 4 + #define TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT 4 ++#define TSADCV3_HIGHT_INT_DEBOUNCE 0x14c ++#define TSADCV3_HIGHT_TSHUT_DEBOUNCE 0x150 + #define TSADCV2_AUTO_PERIOD_TIME 250 /* 250ms */ + #define TSADCV2_AUTO_PERIOD_HT_TIME 50 /* 50ms */ + #define TSADCV3_AUTO_PERIOD_TIME 1875 /* 2.5ms */ +@@ -220,6 +226,9 @@ struct rockchip_thermal_data { + #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 TSADCV7_AUTO_PERIOD_TIME 3000 /* 2.5ms */ ++#define TSADCV7_AUTO_PERIOD_HT_TIME 3000 /* 2.5ms */ ++#define TSADCV3_Q_MAX_VAL 0x7ff /* 11bit 2047 */ + + #define TSADCV2_USER_INTER_PD_SOC 0x340 /* 13 clocks */ + #define TSADCV5_USER_INTER_PD_SOC 0xfc0 /* 97us, at least 90us */ +@@ -230,6 +239,8 @@ struct rockchip_thermal_data { + + #define PX30_GRF_SOC_CON2 0x0408 + ++#define RK3528_GRF_TSADC_CON 0x40030 ++ + #define RK3568_GRF_TSADC_CON 0x0600 + #define RK3568_GRF_TSADC_ANA_REG0 (0x10001 << 0) + #define RK3568_GRF_TSADC_ANA_REG1 (0x10001 << 1) +@@ -497,6 +508,45 @@ static const struct tsadc_table rk3399_c + {TSADCV3_DATA_MASK, 125000}, + }; + ++static const struct tsadc_table rk3528_code_table[] = { ++ {0, -40000}, ++ {1419, -40000}, ++ {1427, -35000}, ++ {1435, -30000}, ++ {1443, -25000}, ++ {1452, -20000}, ++ {1460, -15000}, ++ {1468, -10000}, ++ {1477, -5000}, ++ {1486, 0}, ++ {1494, 5000}, ++ {1502, 10000}, ++ {1510, 15000}, ++ {1519, 20000}, ++ {1527, 25000}, ++ {1535, 30000}, ++ {1544, 35000}, ++ {1552, 40000}, ++ {1561, 45000}, ++ {1569, 50000}, ++ {1578, 55000}, ++ {1586, 60000}, ++ {1594, 65000}, ++ {1603, 70000}, ++ {1612, 75000}, ++ {1620, 80000}, ++ {1628, 85000}, ++ {1637, 90000}, ++ {1646, 95000}, ++ {1654, 100000}, ++ {1662, 105000}, ++ {1671, 110000}, ++ {1679, 115000}, ++ {1688, 120000}, ++ {1696, 125000}, ++ {TSADCV5_DATA_MASK, 125000}, ++}; ++ + static const struct tsadc_table rk3568_code_table[] = { + {0, -40000}, + {1584, -40000}, +@@ -834,6 +884,37 @@ static void rk_tsadcv8_initialize(struct + regs + TSADCV2_AUTO_CON); + } + ++static void rk_tsadcv11_initialize(struct regmap *grf, void __iomem *regs, ++ enum tshut_polarity tshut_polarity) ++{ ++ writel_relaxed(TSADCV7_AUTO_PERIOD_TIME, regs + TSADCV3_AUTO_PERIOD); ++ writel_relaxed(TSADCV7_AUTO_PERIOD_HT_TIME, ++ regs + TSADCV3_AUTO_PERIOD_HT); ++ writel_relaxed(TSADCV2_HIGHT_INT_DEBOUNCE_COUNT, ++ regs + TSADCV3_HIGHT_INT_DEBOUNCE); ++ writel_relaxed(TSADCV2_HIGHT_TSHUT_DEBOUNCE_COUNT, ++ regs + TSADCV3_HIGHT_TSHUT_DEBOUNCE); ++ writel_relaxed(TSADCV3_Q_MAX_VAL, regs + TSADCV9_Q_MAX); ++ writel_relaxed(TSADCV3_AUTO_Q_SEL_EN | TSADCV3_AUTO_Q_SEL_EN_MASK, ++ regs + TSADCV2_AUTO_CON); ++ if (tshut_polarity == TSHUT_HIGH_ACTIVE) ++ writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_HIGH | ++ TSADCV2_AUTO_TSHUT_POLARITY_MASK, ++ regs + TSADCV2_AUTO_CON); ++ else ++ writel_relaxed(TSADCV2_AUTO_TSHUT_POLARITY_MASK, ++ regs + TSADCV2_AUTO_CON); ++ ++ if (!IS_ERR(grf)) { ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_TSEN); ++ udelay(15); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG0); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG1); ++ regmap_write(grf, RK3528_GRF_TSADC_CON, RK3568_GRF_TSADC_ANA_REG2); ++ usleep_range(100, 200); ++ } ++} ++ + static void rk_tsadcv2_irq_ack(void __iomem *regs) + { + u32 val; +@@ -1258,6 +1339,31 @@ static const struct rockchip_tsadc_chip + }, + }; + ++static const struct rockchip_tsadc_chip rk3528_tsadc_data = { ++ /* cpu, gpu */ ++ .chn_offset = 0, ++ .chn_num = 1, /* one channels for tsadc */ ++ ++ .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_tsadcv11_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 = rk3528_code_table, ++ .length = ARRAY_SIZE(rk3528_code_table), ++ .data_mask = TSADCV2_DATA_MASK, ++ .mode = ADC_INCREMENT, ++ }, ++}; ++ + static const struct rockchip_tsadc_chip rk3568_tsadc_data = { + /* cpu, gpu */ + .chn_offset = 0, +@@ -1338,6 +1444,10 @@ static const struct of_device_id of_rock + .data = (void *)&rk3399_tsadc_data, + }, + { ++ .compatible = "rockchip,rk3528-tsadc", ++ .data = (void *)&rk3528_tsadc_data, ++ }, ++ { + .compatible = "rockchip,rk3568-tsadc", + .data = (void *)&rk3568_tsadc_data, + }, diff --git a/target/linux/rockchip/patches-6.6/303-soc-rockchip-power-domain-Add-always-on.patch b/target/linux/rockchip/patches-6.6/303-soc-rockchip-power-domain-Add-always-on.patch new file mode 100644 index 000000000..83434c946 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/303-soc-rockchip-power-domain-Add-always-on.patch @@ -0,0 +1,61 @@ +From 54d4b6b3014f3122a2235533e6511b0d6ca2cd45 Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Wed, 12 Oct 2022 19:25:38 +0800 +Subject: [PATCH] soc: rockchip: power-domain: Add always on configuration for + power domain + +Signed-off-by: Finley Xiao +Change-Id: Ic57f7f3a564f7d71b680e3c435d0460474b5a4a0 +--- + drivers/pmdomain/rockchip/pm-domains.c | 41 +++++++++++++++++++++++-------- + 1 file changed, 31 insertions(+), 10 deletions(-) + +--- a/drivers/pmdomain/rockchip/pm-domains.c ++++ b/drivers/pmdomain/rockchip/pm-domains.c +@@ -45,6 +45,7 @@ struct rockchip_domain_info { + int req_w_mask; + int mem_status_mask; + int repair_status_mask; ++ bool always_on; + u32 pwr_offset; + u32 mem_offset; + u32 req_offset; +@@ -612,6 +613,26 @@ static void rockchip_pd_detach_dev(struc + pm_clk_destroy(dev); + } + ++static int rockchip_pd_add_alwasy_on_flag(struct rockchip_pm_domain *pd) ++{ ++ int error; ++ ++ if (pd->genpd.flags & GENPD_FLAG_ALWAYS_ON) ++ return 0; ++ pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; ++ if (!rockchip_pmu_domain_is_on(pd)) { ++ error = rockchip_pd_power(pd, true); ++ if (error) { ++ dev_err(pd->pmu->dev, ++ "failed to power on domain '%s': %d\n", ++ pd->genpd.name, error); ++ return error; ++ } ++ } ++ ++ return 0; ++} ++ + static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, + struct device_node *node) + { +@@ -730,6 +751,11 @@ static int rockchip_pm_add_one_domain(st + pd->genpd.flags = GENPD_FLAG_PM_CLK; + if (pd_info->active_wakeup) + pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; ++ if (pd_info->always_on) { ++ error = rockchip_pd_add_alwasy_on_flag(pd); ++ if (error) ++ goto err_unprepare_clocks; ++ } + pm_genpd_init(&pd->genpd, NULL, + !rockchip_pmu_domain_is_on(pd) || + (pd->info->mem_status_mask && !rockchip_pmu_domain_is_mem_on(pd))); diff --git a/target/linux/rockchip/patches-6.6/304-soc-rockchip-power-domain-add-rk3528-support.patch b/target/linux/rockchip/patches-6.6/304-soc-rockchip-power-domain-add-rk3528-support.patch new file mode 100644 index 000000000..f83ceafa9 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/304-soc-rockchip-power-domain-add-rk3528-support.patch @@ -0,0 +1,103 @@ +From 2ed777fcd035089bd7996bfa09c023521ecf0e24 Mon Sep 17 00:00:00 2001 +From: Finley Xiao +Date: Fri, 30 Sep 2022 20:11:50 +0800 +Subject: [PATCH] soc: rockchip: power-domain: add power domain support for + rk3528 + +This driver is modified to support RK3528 SoCs. + +Signed-off-by: Finley Xiao +Change-Id: If024916eb7b52ec86ff7533aedefc1bda457b612 +--- + drivers/pmdomain/rockchip/pm-domains.c | 47 +++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +--- a/drivers/pmdomain/rockchip/pm-domains.c ++++ b/drivers/pmdomain/rockchip/pm-domains.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -125,6 +126,20 @@ struct rockchip_pmu { + .active_wakeup = wakeup, \ + } + ++#define DOMAIN_M_A(_name, pwr, status, req, idle, ack, always, wakeup) \ ++{ \ ++ .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), \ ++ .always_on = always, \ ++ .active_wakeup = wakeup, \ ++} ++ + #define DOMAIN_M_O_R(_name, p_offset, pwr, status, m_offset, m_status, r_status, r_offset, req, idle, ack, wakeup) \ + { \ + .name = _name, \ +@@ -171,6 +186,9 @@ struct rockchip_pmu { + #define DOMAIN_RK3399(name, pwr, status, req, wakeup) \ + DOMAIN(name, pwr, status, req, req, req, wakeup) + ++#define DOMAIN_RK3528(name, pwr, req, always, wakeup) \ ++ DOMAIN_M_A(name, pwr, pwr, req, req, req, always, wakeup) ++ + #define DOMAIN_RK3568(name, pwr, req, wakeup) \ + DOMAIN_M(name, pwr, pwr, req, req, req, wakeup) + +@@ -1125,6 +1143,18 @@ static const struct rockchip_domain_info + [RK3399_PD_SDIOAUDIO] = DOMAIN_RK3399("sdioaudio", BIT(31), BIT(31), BIT(29), true), + }; + ++static const struct rockchip_domain_info rk3528_pm_domains[] = { ++ [RK3528_PD_PMU] = DOMAIN_RK3528("pmu", 0, BIT(0), true, false), ++ [RK3528_PD_BUS] = DOMAIN_RK3528("bus", 0, BIT(1), true, false), ++ [RK3528_PD_DDR] = DOMAIN_RK3528("ddr", 0, BIT(2), true, false), ++ [RK3528_PD_MSCH] = DOMAIN_RK3528("msch", 0, BIT(3), true, false), ++ [RK3528_PD_GPU] = DOMAIN_RK3528("gpu", BIT(0), BIT(4), true, false), ++ [RK3528_PD_RKVDEC] = DOMAIN_RK3528("vdec", 0, BIT(5), true, false), ++ [RK3528_PD_RKVENC] = DOMAIN_RK3528("venc", 0, BIT(6), true, false), ++ [RK3528_PD_VO] = DOMAIN_RK3528("vo", 0, BIT(7), true, false), ++ [RK3528_PD_VPU] = DOMAIN_RK3528("vpu", 0, BIT(8), true, false), ++}; ++ + static const struct rockchip_domain_info rk3568_pm_domains[] = { + [RK3568_PD_NPU] = DOMAIN_RK3568("npu", BIT(1), BIT(2), false), + [RK3568_PD_GPU] = DOMAIN_RK3568("gpu", BIT(0), BIT(1), false), +@@ -1304,6 +1334,17 @@ static const struct rockchip_pmu_info rk + .domain_info = rk3399_pm_domains, + }; + ++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 = ARRAY_SIZE(rk3528_pm_domains), ++ .domain_info = rk3528_pm_domains, ++}; ++ + static const struct rockchip_pmu_info rk3568_pmu = { + .pwr_offset = 0xa0, + .status_offset = 0x98, +@@ -1387,6 +1428,10 @@ static const struct of_device_id rockchi + .data = (void *)&rk3399_pmu, + }, + { ++ .compatible = "rockchip,rk3528-power-controller", ++ .data = (void *)&rk3528_pmu, ++ }, ++ { + .compatible = "rockchip,rk3568-power-controller", + .data = (void *)&rk3568_pmu, + }, diff --git a/target/linux/rockchip/patches-6.6/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch b/target/linux/rockchip/patches-6.6/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch new file mode 100644 index 000000000..23651d34b --- /dev/null +++ b/target/linux/rockchip/patches-6.6/305-clk-rockchip-add-clock-controller-for-the-RK3528.patch @@ -0,0 +1,178 @@ +From 16f512f1e10375dc48aa6c26cedeb7079aba01de Mon Sep 17 00:00:00 2001 +From: Joseph Chen +Date: Sat, 13 Aug 2022 01:15:20 +0000 +Subject: [PATCH] clk: rockchip: Add clock controller for the RK3528 + +Add the clock tree definition for the new RK3528 SoC. + +gmac1 clocks are all controlled by GRF, but CRU helps to abstract +these two clocks for gmac1 since the clock source is from CRU. + +The io-in clocks are module phy output clock, gating child +clocks by disabling phy output but not CRU gate. + +Add gmac0 clocks. +They are all orphans if clk_gmac0_io_i is not registered by +GMAC driver. But it's fine that GMAC driver only get it but +not to set/get rate. + +Add CLK_SET_RATE_PARENT for mclk_sai_i2s0/1. +Allowed to change parent rate. + +Add CLK_SET_RATE_NO_REPARENT for dclk_vop0. +dclk_vop0 is often used for HDMI, it prefers parent clock from +clk_hdmiphy_pixel_io for better clock quality and any rate. +It assigns clk_hdmiphy_pixel_io as parent in dts and hope not to +change parent any more. + +Add CLK_SET_RATE_PARENT for aclk_gpu. +Allow aclk_gpu and aclk_gpu_mali to change parent rate. + +Add CLK_SET_RATE_PARENT for aclk_rkvdec_pvtmux_root. +Allow aclk_rkvdec_pvtmux_root and aclk_rkvdec to change parent rate. + +set aclk_m_core = core_clk/2. +aclk_m_core signoff is 550M, but we set div=2 for better +performance. + +Add CLK_IS_CRITICAL for clk_32k. +Mainly for pvtpll during reboot stage. + +Add CLK_IS_CRITICAL for all IOC clocks. +IOC doesn't share clock with GRF. The iomux can't be changed if they +are disabled. + +Disable aclk_{vpu,vpu_l,vo}_root rate change +They are all shared by multiple modules, disable rate change +by modules. + +Don't register clk_uart_jtag +It's for force jtag uart delay counter. It must be open +for box product without tf card but with uart0. + +Signed-off-by: Joseph Chen +Signed-off-by: Elaine Zhang +Change-Id: I09745b6a31484d6a27f04e608268d9738c1fe224 +--- + drivers/clk/rockchip/Kconfig | 7 + + drivers/clk/rockchip/Makefile | 1 + + drivers/clk/rockchip/clk-rk3528.c | 1187 +++++++++++++++++++++++++++++ + drivers/clk/rockchip/clk.h | 28 + + 4 files changed, 1223 insertions(+) + create mode 100644 drivers/clk/rockchip/clk-rk3528.c + +--- a/drivers/clk/rockchip/Kconfig ++++ b/drivers/clk/rockchip/Kconfig +@@ -93,6 +93,13 @@ config CLK_RK3399 + help + Build the driver for RK3399 Clock Driver. + ++config CLK_RK3528 ++ bool "Rockchip RK3528 clock controller support" ++ depends on ARM64 || COMPILE_TEST ++ default y ++ help ++ Build the driver for RK3528 Clock Driver. ++ + config CLK_RK3568 + bool "Rockchip RK3568 clock controller support" + depends on ARM64 || COMPILE_TEST +--- a/drivers/clk/rockchip/Makefile ++++ b/drivers/clk/rockchip/Makefile +@@ -27,5 +27,6 @@ obj-$(CONFIG_CLK_RK3308) += clk-r + obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o + obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o + obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o ++obj-$(CONFIG_CLK_RK3528) += clk-rk3528.o + obj-$(CONFIG_CLK_RK3568) += clk-rk3568.o + obj-$(CONFIG_CLK_RK3588) += clk-rk3588.o rst-rk3588.o +--- a/drivers/clk/rockchip/clk.c ++++ b/drivers/clk/rockchip/clk.c +@@ -509,6 +509,14 @@ void rockchip_clk_register_branches(stru + ctx->reg_base + list->gate_offset, + list->gate_shift, list->gate_flags, &ctx->lock); + break; ++ case branch_gate_no_set_rate: ++ flags &= ~CLK_SET_RATE_PARENT; ++ ++ clk = clk_register_gate(NULL, list->name, ++ list->parent_names[0], flags, ++ ctx->reg_base + list->gate_offset, ++ list->gate_shift, list->gate_flags, &ctx->lock); ++ break; + case branch_composite: + clk = rockchip_clk_register_branch(list->name, + list->parent_names, list->num_parents, +--- a/drivers/clk/rockchip/clk.h ++++ b/drivers/clk/rockchip/clk.h +@@ -207,6 +207,34 @@ struct clk; + #define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100) + #define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110) + ++#define RK3528_PMU_CRU_BASE 0x10000 ++#define RK3528_PCIE_CRU_BASE 0x20000 ++#define RK3528_DDRPHY_CRU_BASE 0x28000 ++#define RK3528_VPU_GRF_BASE 0x40000 ++#define RK3528_VO_GRF_BASE 0x60000 ++#define RK3528_SDMMC_CON0 (RK3528_VO_GRF_BASE + 0x24) ++#define RK3528_SDMMC_CON1 (RK3528_VO_GRF_BASE + 0x28) ++#define RK3528_SDIO0_CON0 (RK3528_VPU_GRF_BASE + 0x4) ++#define RK3528_SDIO0_CON1 (RK3528_VPU_GRF_BASE + 0x8) ++#define RK3528_SDIO1_CON0 (RK3528_VPU_GRF_BASE + 0xc) ++#define RK3528_SDIO1_CON1 (RK3528_VPU_GRF_BASE + 0x10) ++#define RK3528_PLL_CON(x) RK2928_PLL_CON(x) ++#define RK3528_PCIE_PLL_CON(x) ((x) * 0x4 + RK3528_PCIE_CRU_BASE) ++#define RK3528_DDRPHY_PLL_CON(x) ((x) * 0x4 + RK3528_DDRPHY_CRU_BASE) ++#define RK3528_MODE_CON 0x280 ++#define RK3528_CLKSEL_CON(x) ((x) * 0x4 + 0x300) ++#define RK3528_CLKGATE_CON(x) ((x) * 0x4 + 0x800) ++#define RK3528_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) ++#define RK3528_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PMU_CRU_BASE) ++#define RK3528_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_PMU_CRU_BASE) ++#define RK3528_PCIE_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PCIE_CRU_BASE) ++#define RK3528_PCIE_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_PCIE_CRU_BASE) ++#define RK3528_DDRPHY_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_DDRPHY_CRU_BASE) ++#define RK3528_DDRPHY_MODE_CON (0x280 + RK3528_DDRPHY_CRU_BASE) ++#define RK3528_GLB_CNT_TH 0xc00 ++#define RK3528_GLB_SRST_FST 0xc08 ++#define RK3528_GLB_SRST_SND 0xc0c ++ + #define RK3568_PLL_CON(x) RK2928_PLL_CON(x) + #define RK3568_MODE_CON0 0xc0 + #define RK3568_MISC_CON0 0xc4 +@@ -408,6 +436,7 @@ struct rockchip_pll_clock { + }; + + #define ROCKCHIP_PLL_SYNC_RATE BIT(0) ++#define ROCKCHIP_PLL_FIXED_MODE BIT(1) + + #define PLL(_type, _id, _name, _pnames, _flags, _con, _mode, _mshift, \ + _lshift, _pflags, _rtable) \ +@@ -516,6 +545,7 @@ enum rockchip_clk_branch_type { + branch_muxgrf, + branch_divider, + branch_fraction_divider, ++ branch_gate_no_set_rate, + branch_gate, + branch_mmc, + branch_inverter, +@@ -836,6 +866,19 @@ struct rockchip_clk_branch { + .name = cname, \ + .parent_names = (const char *[]){ pname }, \ + .num_parents = 1, \ ++ .flags = f, \ ++ .gate_offset = o, \ ++ .gate_shift = b, \ ++ .gate_flags = gf, \ ++ } ++ ++#define GATE_NO_SET_RATE(_id, cname, pname, f, o, b, gf) \ ++ { \ ++ .id = _id, \ ++ .branch_type = branch_gate_no_set_rate, \ ++ .name = cname, \ ++ .parent_names = (const char *[]){ pname }, \ ++ .num_parents = 1, \ + .flags = f, \ + .gate_offset = o, \ + .gate_shift = b, \ diff --git a/target/linux/rockchip/patches-6.6/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch b/target/linux/rockchip/patches-6.6/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch new file mode 100644 index 000000000..5547584d3 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/306-ethernet-stmmac-dwmac-rk3528-add-GMAC-support.patch @@ -0,0 +1,227 @@ +From 61c0ac431798861b0696ccc549138b2eec8a4766 Mon Sep 17 00:00:00 2001 +From: David Wu +Date: Sat, 24 Sep 2022 18:29:52 +0800 +Subject: [PATCH] ethernet: stmmac: dwmac-rk: Add GMAC support for RK3528 + +Add constants and callback functions for the dwmac on RK3528 Soc. +As can be seen, the base structure is the same. In addition, there +is an internal phy inside with Gmac0. + +Signed-off-by: David Wu +Change-Id: I8a69a1239ed3ae91bfe44c96287210da758f9cf9 +--- + .../net/ethernet/stmicro/stmmac/dwmac-rk.c | 179 +++++++++++++++++- + 1 file changed, 173 insertions(+), 6 deletions(-) + +--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c ++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c +@@ -1142,6 +1142,201 @@ static const struct rk_gmac_ops rk3399_o + .set_rmii_speed = rk3399_set_rmii_speed, + }; + ++#define RK3528_VO_GRF_GMAC_CON 0X60018 ++#define RK3528_VPU_GRF_GMAC_CON5 0X40018 ++#define RK3528_VPU_GRF_GMAC_CON6 0X4001c ++ ++#define RK3528_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) ++#define RK3528_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) ++#define RK3528_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) ++#define RK3528_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) ++ ++#define RK3528_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8) ++#define RK3528_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0) ++ ++#define RK3528_GMAC0_PHY_INTF_SEL_RMII GRF_BIT(1) ++#define RK3528_GMAC1_PHY_INTF_SEL_RGMII GRF_CLR_BIT(8) ++#define RK3528_GMAC1_PHY_INTF_SEL_RMII GRF_BIT(8) ++ ++#define RK3528_GMAC1_CLK_SELET_CRU GRF_CLR_BIT(12) ++#define RK3528_GMAC1_CLK_SELET_IO GRF_BIT(12) ++ ++#define RK3528_GMAC0_CLK_RMII_DIV2 GRF_BIT(3) ++#define RK3528_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(3) ++#define RK3528_GMAC1_CLK_RMII_DIV2 GRF_BIT(10) ++#define RK3528_GMAC1_CLK_RMII_DIV20 GRF_CLR_BIT(10) ++ ++#define RK3528_GMAC1_CLK_RGMII_DIV1 \ ++ (GRF_CLR_BIT(11) | GRF_CLR_BIT(10)) ++#define RK3528_GMAC1_CLK_RGMII_DIV5 \ ++ (GRF_BIT(11) | GRF_BIT(10)) ++#define RK3528_GMAC1_CLK_RGMII_DIV50 \ ++ (GRF_BIT(11) | GRF_CLR_BIT(10)) ++ ++#define RK3528_GMAC0_CLK_RMII_GATE GRF_BIT(2) ++#define RK3528_GMAC0_CLK_RMII_NOGATE GRF_CLR_BIT(2) ++#define RK3528_GMAC1_CLK_RMII_GATE GRF_BIT(9) ++#define RK3528_GMAC1_CLK_RMII_NOGATE GRF_CLR_BIT(9) ++ ++#define RK3528_VO_GRF_MACPHY_CON0 0X6001c ++#define RK3528_VO_GRF_MACPHY_CON1 0X60020 ++ ++static void rk3528_set_to_rgmii(struct rk_priv_data *bsp_priv, ++ int tx_delay, int rx_delay) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "Missing rockchip,grf property\n"); ++ return; ++ } ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, ++ RK3528_GMAC1_PHY_INTF_SEL_RGMII); ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, ++ RK3528_GMAC_CLK_RX_DL_CFG(rx_delay) | ++ RK3528_GMAC_CLK_TX_DL_CFG(tx_delay)); ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON6, ++ RK3528_GMAC_CLK_RX_DL_CFG(rx_delay) | ++ RK3528_GMAC_CLK_TX_DL_CFG(tx_delay)); ++} ++ ++static void rk3528_set_to_rmii(struct rk_priv_data *bsp_priv) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ unsigned int id = bsp_priv->id; ++ ++ if (IS_ERR(bsp_priv->grf)) { ++ dev_err(dev, "%s: Missing rockchip,grf property\n", __func__); ++ return; ++ } ++ ++ if (id == 1) ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, ++ RK3528_GMAC1_PHY_INTF_SEL_RMII); ++ else ++ regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON, ++ RK3528_GMAC0_PHY_INTF_SEL_RMII); ++} ++ ++static void rk3528_set_rgmii_speed(struct rk_priv_data *bsp_priv, int speed) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ unsigned int val = 0; ++ ++ switch (speed) { ++ case 10: ++ val = RK3528_GMAC1_CLK_RGMII_DIV50; ++ break; ++ case 100: ++ val = RK3528_GMAC1_CLK_RGMII_DIV5; ++ break; ++ case 1000: ++ val = RK3528_GMAC1_CLK_RGMII_DIV1; ++ break; ++ default: ++ goto err; ++ } ++ ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, val); ++ return; ++err: ++ dev_err(dev, "unknown RGMII speed value for GMAC speed=%d", speed); ++} ++ ++static void rk3528_set_rmii_speed(struct rk_priv_data *bsp_priv, int speed) ++{ ++ struct device *dev = &bsp_priv->pdev->dev; ++ unsigned int val, offset, id = bsp_priv->id; ++ ++ switch (speed) { ++ case 10: ++ val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV20 : ++ RK3528_GMAC0_CLK_RMII_DIV20; ++ break; ++ case 100: ++ val = (id == 1) ? RK3528_GMAC1_CLK_RMII_DIV2 : ++ RK3528_GMAC0_CLK_RMII_DIV2; ++ break; ++ default: ++ goto err; ++ } ++ ++ offset = (id == 1) ? RK3528_VPU_GRF_GMAC_CON5 : RK3528_VO_GRF_GMAC_CON; ++ regmap_write(bsp_priv->grf, offset, val); ++ ++ return; ++err: ++ dev_err(dev, "unknown RMII speed value for GMAC speed=%d", speed); ++} ++ ++static void rk3528_set_clock_selection(struct rk_priv_data *bsp_priv, ++ bool input, bool enable) ++{ ++ unsigned int value, id = bsp_priv->id; ++ ++ if (id == 1) { ++ value = input ? RK3528_GMAC1_CLK_SELET_IO : ++ RK3528_GMAC1_CLK_SELET_CRU; ++ value |= enable ? RK3528_GMAC1_CLK_RMII_NOGATE : ++ RK3528_GMAC1_CLK_RMII_GATE; ++ regmap_write(bsp_priv->grf, RK3528_VPU_GRF_GMAC_CON5, value); ++ } else { ++ value = enable ? RK3528_GMAC0_CLK_RMII_NOGATE : ++ RK3528_GMAC0_CLK_RMII_GATE; ++ regmap_write(bsp_priv->grf, RK3528_VO_GRF_GMAC_CON, value); ++ } ++} ++ ++/* Integrated FEPHY */ ++#define RK_FEPHY_SHUTDOWN GRF_BIT(1) ++#define RK_FEPHY_POWERUP GRF_CLR_BIT(1) ++#define RK_FEPHY_INTERNAL_RMII_SEL GRF_BIT(6) ++#define RK_FEPHY_24M_CLK_SEL (GRF_BIT(8) | GRF_BIT(9)) ++#define RK_FEPHY_PHY_ID GRF_BIT(11) ++ ++#define RK_FEPHY_BGS HIWORD_UPDATE(0x0, 0xf, 0) ++ ++static void rk3528_integrated_sphy_power(struct rk_priv_data *priv) ++{ ++ struct device *dev = &priv->pdev->dev; ++ ++ if (IS_ERR(priv->grf) || !priv->phy_reset) { ++ dev_err(dev, "%s: Missing rockchip,grf or phy_reset property\n", ++ __func__); ++ return; ++ } ++ ++ unsigned int bgs = RK_FEPHY_BGS; ++ ++ reset_control_assert(priv->phy_reset); ++ udelay(20); ++ regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON0, ++ RK_FEPHY_POWERUP | ++ RK_FEPHY_INTERNAL_RMII_SEL | ++ RK_FEPHY_24M_CLK_SEL | ++ RK_FEPHY_PHY_ID); ++ ++ /*if (priv->otp_data > 0) ++ bgs = HIWORD_UPDATE(priv->otp_data, 0xf, 0);*/ ++ ++ regmap_write(priv->grf, RK3528_VO_GRF_MACPHY_CON1, bgs); ++ usleep_range(10 * 1000, 12 * 1000); ++ reset_control_deassert(priv->phy_reset); ++ usleep_range(50 * 1000, 60 * 1000); ++} ++ ++static const struct rk_gmac_ops rk3528_ops = { ++ .set_to_rgmii = rk3528_set_to_rgmii, ++ .set_to_rmii = rk3528_set_to_rmii, ++ .set_rgmii_speed = rk3528_set_rgmii_speed, ++ .set_rmii_speed = rk3528_set_rmii_speed, ++ .set_clock_selection = rk3528_set_clock_selection, ++ .integrated_phy_powerup = rk3528_integrated_sphy_power, ++}; ++ + #define RK3568_GRF_GMAC0_CON0 0x0380 + #define RK3568_GRF_GMAC0_CON1 0x0384 + #define RK3568_GRF_GMAC1_CON0 0x0388 +@@ -2106,6 +2301,7 @@ static const struct of_device_id rk_gmac + { .compatible = "rockchip,rk3366-gmac", .data = &rk3366_ops }, + { .compatible = "rockchip,rk3368-gmac", .data = &rk3368_ops }, + { .compatible = "rockchip,rk3399-gmac", .data = &rk3399_ops }, ++ { .compatible = "rockchip,rk3528-gmac", .data = &rk3528_ops }, + { .compatible = "rockchip,rk3568-gmac", .data = &rk3568_ops }, + { .compatible = "rockchip,rk3588-gmac", .data = &rk3588_ops }, + { .compatible = "rockchip,rv1108-gmac", .data = &rv1108_ops }, diff --git a/target/linux/rockchip/patches-6.6/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch b/target/linux/rockchip/patches-6.6/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch new file mode 100644 index 000000000..2e6ab180d --- /dev/null +++ b/target/linux/rockchip/patches-6.6/307-phy-rockchip-inno-usb2-add-phy-support-for-rk3528.patch @@ -0,0 +1,64 @@ +--- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c ++++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +@@ -1761,6 +1761,53 @@ static const struct rockchip_usb2phy_cfg + { /* sentinel */ } + }; + ++static const struct rockchip_usb2phy_cfg rk3528_phy_cfgs[] = { ++ { ++ .reg = 0xffdf0000, ++ .num_ports = 2, ++ .clkout_ctl = { 0x041c, 7, 2, 0, 0x27 }, ++ .port_cfgs = { ++ [USB2PHY_PORT_OTG] = { ++ .phy_sus = { 0x6004c, 15, 0, 0, 0x1d1 }, ++ .bvalid_det_en = { 0x60074, 3, 2, 0, 3 }, ++ .bvalid_det_st = { 0x60078, 3, 2, 0, 3 }, ++ .bvalid_det_clr = { 0x6007c, 3, 2, 0, 3 }, ++ .id_det_en = { 0x60074, 5, 4, 0, 3 }, ++ .id_det_st = { 0x60078, 5, 4, 0, 3 }, ++ .id_det_clr = { 0x6007c, 5, 4, 0, 3 }, ++ .ls_det_en = { 0x60074, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x60078, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x6007c, 0, 0, 0, 1 }, ++ .utmi_avalid = { 0x6006c, 1, 1, 0, 1 }, ++ .utmi_bvalid = { 0x6006c, 0, 0, 0, 1 }, ++ .utmi_id = { 0x6006c, 6, 6, 0, 1 }, ++ .utmi_ls = { 0x6006c, 5, 4, 0, 1 }, ++ }, ++ [USB2PHY_PORT_HOST] = { ++ .phy_sus = { 0x6005c, 15, 0, 0x1d2, 0x1d1 }, ++ .ls_det_en = { 0x60090, 0, 0, 0, 1 }, ++ .ls_det_st = { 0x60094, 0, 0, 0, 1 }, ++ .ls_det_clr = { 0x60098, 0, 0, 0, 1 }, ++ .utmi_ls = { 0x6006c, 13, 12, 0, 1 }, ++ .utmi_hstdet = { 0x6006c, 15, 15, 0, 1 } ++ } ++ }, ++ .chg_det = { ++ .opmode = { 0x6004c, 3, 0, 5, 1 }, ++ .cp_det = { 0x6006c, 19, 19, 0, 1 }, ++ .dcp_det = { 0x6006c, 18, 18, 0, 1 }, ++ .dp_det = { 0x6006c, 20, 20, 0, 1 }, ++ .idm_sink_en = { 0x60058, 1, 1, 0, 1 }, ++ .idp_sink_en = { 0x60058, 0, 0, 0, 1 }, ++ .idp_src_en = { 0x60058, 2, 2, 0, 1 }, ++ .rdm_pdwn_en = { 0x60058, 3, 3, 0, 1 }, ++ .vdm_src_en = { 0x60058, 5, 5, 0, 1 }, ++ .vdp_src_en = { 0x60058, 4, 4, 0, 1 }, ++ }, ++ }, ++ { /* sentinel */ } ++}; ++ + static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { + { + .reg = 0xfe8a0000, +@@ -1997,6 +2044,7 @@ static const struct of_device_id rockchi + { .compatible = "rockchip,rk3328-usb2phy", .data = &rk3328_phy_cfgs }, + { .compatible = "rockchip,rk3366-usb2phy", .data = &rk3366_phy_cfgs }, + { .compatible = "rockchip,rk3399-usb2phy", .data = &rk3399_phy_cfgs }, ++ { .compatible = "rockchip,rk3528-usb2phy", .data = &rk3528_phy_cfgs }, + { .compatible = "rockchip,rk3568-usb2phy", .data = &rk3568_phy_cfgs }, + { .compatible = "rockchip,rk3588-usb2phy", .data = &rk3588_phy_cfgs }, + { .compatible = "rockchip,rv1108-usb2phy", .data = &rv1108_phy_cfgs }, diff --git a/target/linux/rockchip/patches-6.6/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch b/target/linux/rockchip/patches-6.6/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch new file mode 100644 index 000000000..ca277999f --- /dev/null +++ b/target/linux/rockchip/patches-6.6/308-phy-rockchip-naneng-combphy-add-support-rk3528.patch @@ -0,0 +1,176 @@ +From 432666b59bdbef2c386e92dd88be4206203ff8ac Mon Sep 17 00:00:00 2001 +From: Jon Lin +Date: Sat, 8 Oct 2022 15:48:37 +0800 +Subject: [PATCH] phy: rockchip: naneng-combphy: add support rk3528 + +1. The layout of controller registers has changed, remove legacy config; +2. Using the default value for grf register; +3. sync to use rk3568 parameter for phy PLL, signal test pass +4. Add 24MHz refclk for rk3528 PCIe, Enable the counting clock of the +rterm detect by setting tx_trim[14] bit for rx detecting. +5. set SSC modulation frequency to 31.5KHz + +Change-Id: I45742c416d452037e61b7a7b8765269931d56402 +Signed-off-by: Jon Lin +Signed-off-by: Jianwei Zheng +--- + .../rockchip/phy-rockchip-naneng-combphy.c | 139 +++++++++++++++++- + 1 file changed, 138 insertions(+), 1 deletion(-) + +--- a/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c ++++ b/drivers/phy/rockchip/phy-rockchip-naneng-combphy.c +@@ -83,7 +83,7 @@ + struct rockchip_combphy_priv; + + struct combphy_reg { +- u16 offset; ++ u32 offset; + u16 bitend; + u16 bitstart; + u16 disable; +@@ -93,11 +93,13 @@ struct combphy_reg { + struct rockchip_combphy_grfcfg { + struct combphy_reg pcie_mode_set; + struct combphy_reg usb_mode_set; ++ struct combphy_reg u3otg0_port_en; + 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; +@@ -378,6 +380,120 @@ static int rockchip_combphy_probe(struct + return PTR_ERR_OR_ZERO(phy_provider); + } + ++static int rk3528_combphy_cfg(struct rockchip_combphy_priv *priv) ++{ ++ const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; ++ unsigned long rate; ++ u32 val; ++ ++ switch (priv->type) { ++ case PHY_TYPE_PCIE: ++ /* Set SSC downward spread spectrum. */ ++ val = readl(priv->mmio + 0x18); ++ val &= ~GENMASK(5, 4); ++ val |= 0x01 << 4; ++ writel(val, priv->mmio + 0x18); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con0_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con1_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con2_for_pcie, true); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->con3_for_pcie, true); ++ break; ++ ++ case PHY_TYPE_USB3: ++ /* Set SSC downward spread spectrum. */ ++ val = readl(priv->mmio + 0x18); ++ val &= ~GENMASK(5, 4); ++ val |= 0x01 << 4; ++ writel(val, priv->mmio + 0x18); ++ ++ /* Enable adaptive CTLE for USB3.0 Rx. */ ++ val = readl(priv->mmio + 0x200); ++ val &= ~GENMASK(17, 17); ++ val |= 0x01 << 17; ++ writel(val, priv->mmio + 0x200); ++ ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txcomp_sel, false); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_txelec_sel, false); ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->usb_mode_set, true); ++ break; ++ ++ default: ++ dev_err(priv->dev, "incompatible PHY type\n"); ++ return -EINVAL; ++ } ++ ++ rate = clk_get_rate(priv->refclk); ++ ++ switch (rate) { ++ case REF_CLOCK_24MHz: ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_24m, true); ++ if (priv->type == PHY_TYPE_USB3) { ++ /* Set ssc_cnt[10:0]=00101111101 & 31.5KHz. */ ++ val = readl(priv->mmio + 0x100); ++ val &= ~GENMASK(10, 0); ++ val |= 0x17d; ++ writel(val, priv->mmio + 0x100); ++ } else if (priv->type == PHY_TYPE_PCIE) { ++ /* tx_trim[14]=1, Enable the counting clock of the rterm detect */ ++ val = readl(priv->mmio + 0x218); ++ val |= (1 << 14); ++ writel(val, priv->mmio + 0x218); ++ } ++ break; ++ ++ case REF_CLOCK_100MHz: ++ rockchip_combphy_param_write(priv->phy_grf, &cfg->pipe_clk_100m, true); ++ if (priv->type == PHY_TYPE_PCIE) { ++ /* PLL KVCO tuning fine. */ ++ val = readl(priv->mmio + 0x18); ++ val &= ~(0x7 << 10); ++ val |= 0x2 << 10; ++ writel(val, priv->mmio + 0x18); ++ ++ /* su_trim[6:4]=111, [10:7]=1001, [2:0]=000 */ ++ val = readl(priv->mmio + 0x108); ++ val &= ~(0x7f7); ++ val |= 0x4f0; ++ writel(val, priv->mmio + 0x108); ++ } ++ break; ++ ++ default: ++ dev_err(priv->dev, "unsupported rate: %lu\n", rate); ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static const struct rockchip_combphy_grfcfg rk3528_combphy_grfcfgs = { ++ /* pipe-phy-grf */ ++ .pcie_mode_set = { 0x48000, 5, 0, 0x00, 0x11 }, ++ .usb_mode_set = { 0x48000, 5, 0, 0x00, 0x04 }, ++ .pipe_rxterm_set = { 0x48000, 12, 12, 0x00, 0x01 }, ++ .pipe_txelec_set = { 0x48004, 1, 1, 0x00, 0x01 }, ++ .pipe_txcomp_set = { 0x48004, 4, 4, 0x00, 0x01 }, ++ .pipe_clk_24m = { 0x48004, 14, 13, 0x00, 0x00 }, ++ .pipe_clk_100m = { 0x48004, 14, 13, 0x00, 0x02 }, ++ .pipe_rxterm_sel = { 0x48008, 8, 8, 0x00, 0x01 }, ++ .pipe_txelec_sel = { 0x48008, 12, 12, 0x00, 0x01 }, ++ .pipe_txcomp_sel = { 0x48008, 15, 15, 0x00, 0x01 }, ++ .pipe_clk_ext = { 0x4800c, 9, 8, 0x02, 0x01 }, ++ .pipe_phy_status = { 0x48034, 6, 6, 0x01, 0x00 }, ++ .con0_for_pcie = { 0x48000, 15, 0, 0x00, 0x110 }, ++ .con1_for_pcie = { 0x48004, 15, 0, 0x00, 0x00 }, ++ .con2_for_pcie = { 0x48008, 15, 0, 0x00, 0x101 }, ++ .con3_for_pcie = { 0x4800c, 15, 0, 0x00, 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 int rk3568_combphy_cfg(struct rockchip_combphy_priv *priv) + { + const struct rockchip_combphy_grfcfg *cfg = priv->cfg->grfcfg; +@@ -772,6 +888,10 @@ static const struct rockchip_combphy_cfg + + static const struct of_device_id rockchip_combphy_of_match[] = { + { ++ .compatible = "rockchip,rk3528-naneng-combphy", ++ .data = &rk3528_combphy_cfgs, ++ }, ++ { + .compatible = "rockchip,rk3568-naneng-combphy", + .data = &rk3568_combphy_cfgs, + }, diff --git a/target/linux/rockchip/patches-6.6/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch b/target/linux/rockchip/patches-6.6/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch new file mode 100644 index 000000000..2f636b814 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/309-mmc-sdhci-of-dwcmshc-pcie-support-for-rk3528.patch @@ -0,0 +1,107 @@ +--- a/drivers/mmc/host/sdhci-of-dwcmshc.c ++++ b/drivers/mmc/host/sdhci-of-dwcmshc.c +@@ -296,19 +296,20 @@ static void dwcmshc_rk3568_set_clock(str + 0x3 << 19; /* post-change delay */ + sdhci_writel(host, extra, dwc_priv->vendor_specific_area1 + DWCMSHC_EMMC_ATCTRL); + +- if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 || +- host->mmc->ios.timing == MMC_TIMING_MMC_HS400) ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200) + txclk_tapnum = priv->txclk_tapnum; + +- if ((priv->devtype == DWCMSHC_RK3588) && host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { ++ if (host->mmc->ios.timing == MMC_TIMING_MMC_HS400) { + txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES; + +- extra = DLL_CMDOUT_SRC_CLK_NEG | +- DLL_CMDOUT_EN_SRC_CLK_NEG | +- DWCMSHC_EMMC_DLL_DLYENA | +- DLL_CMDOUT_TAPNUM_90_DEGREES | +- DLL_CMDOUT_TAPNUM_FROM_SW; +- sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT); ++ if (priv->devtype != DWCMSHC_RK3568) { ++ extra = DLL_CMDOUT_SRC_CLK_NEG | ++ DLL_CMDOUT_EN_SRC_CLK_NEG | ++ DWCMSHC_EMMC_DLL_DLYENA | ++ DLL_CMDOUT_TAPNUM_90_DEGREES | ++ DLL_CMDOUT_TAPNUM_FROM_SW; ++ sdhci_writel(host, extra, DECMSHC_EMMC_DLL_CMDOUT); ++ } + } + + extra = DWCMSHC_EMMC_DLL_DLYENA | +@@ -356,6 +357,15 @@ static const struct sdhci_ops sdhci_dwcm + .adma_write_desc = dwcmshc_adma_write_desc, + }; + ++static const struct sdhci_ops sdhci_dwcmshc_rk3528_ops = { ++ .set_clock = dwcmshc_rk3568_set_clock, ++ .set_bus_width = sdhci_set_bus_width, ++ .set_uhs_signaling = dwcmshc_set_uhs_signaling, ++ .get_max_clock = sdhci_pltfm_clk_get_max_clock, ++ .reset = rk35xx_sdhci_reset, ++ .adma_write_desc = dwcmshc_adma_write_desc, ++}; ++ + static const struct sdhci_pltfm_data sdhci_dwcmshc_pdata = { + .ops = &sdhci_dwcmshc_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, +@@ -379,6 +389,14 @@ static const struct sdhci_pltfm_data sdh + SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, + }; + ++static const struct sdhci_pltfm_data sdhci_dwcmshc_rk3528_pdata = { ++ .ops = &sdhci_dwcmshc_rk3528_ops, ++ .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | ++ SDHCI_QUIRK_BROKEN_TIMEOUT_VAL, ++ .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | ++ SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN, ++}; ++ + static int dwcmshc_rk35xx_init(struct sdhci_host *host, struct dwcmshc_priv *dwc_priv) + { + int err; +@@ -444,6 +462,10 @@ static const struct of_device_id sdhci_d + .data = &sdhci_dwcmshc_rk35xx_pdata, + }, + { ++ .compatible = "rockchip,rk3528-dwcmshc", ++ .data = &sdhci_dwcmshc_rk3528_pdata, ++ }, ++ { + .compatible = "snps,dwcmshc-sdhci", + .data = &sdhci_dwcmshc_pdata, + }, +@@ -523,17 +545,18 @@ static int dwcmshc_probe(struct platform + host->mmc_host_ops.request = dwcmshc_request; + host->mmc_host_ops.hs400_enhanced_strobe = dwcmshc_hs400_enhanced_strobe; + +- if (pltfm_data == &sdhci_dwcmshc_rk35xx_pdata) { ++ if ((pltfm_data == &sdhci_dwcmshc_rk35xx_pdata) || ++ (pltfm_data == &sdhci_dwcmshc_rk3528_pdata)) { + rk_priv = devm_kzalloc(&pdev->dev, sizeof(struct rk35xx_priv), GFP_KERNEL); + if (!rk_priv) { + err = -ENOMEM; + goto err_clk; + } + +- if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3588-dwcmshc")) +- rk_priv->devtype = DWCMSHC_RK3588; +- else ++ if (of_device_is_compatible(pdev->dev.of_node, "rockchip,rk3568-dwcmshc")) + rk_priv->devtype = DWCMSHC_RK3568; ++ else ++ rk_priv->devtype = DWCMSHC_RK3588; + + priv->priv = rk_priv; + +--- a/drivers/pci/controller/dwc/Makefile ++++ b/drivers/pci/controller/dwc/Makefile +@@ -17,6 +17,7 @@ obj-$(CONFIG_PCIE_QCOM_EP) += pcie-qcom- + obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o + obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o + obj-$(CONFIG_PCIE_ROCKCHIP_DW_HOST) += pcie-dw-rockchip.o ++obj-$(CONFIG_PCIE_ROCKCHIP_DW_HOST) += pcie-dw-rkvendor.o + obj-$(CONFIG_PCIE_INTEL_GW) += pcie-intel-gw.o + obj-$(CONFIG_PCIE_KEEMBAY) += pcie-keembay.o + obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o diff --git a/target/linux/rockchip/patches-6.6/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch b/target/linux/rockchip/patches-6.6/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch new file mode 100644 index 000000000..ce7733722 --- /dev/null +++ b/target/linux/rockchip/patches-6.6/310-mmc-dw_mmc-rockchip-add-v2-tuning-support.patch @@ -0,0 +1,110 @@ +From 4ff037c13c1e7ab16362d39a59ebb8fffb929f99 Mon Sep 17 00:00:00 2001 +From: Shawn Lin +Date: Wed, 15 Apr 2020 09:19:09 +0800 +Subject: [PATCH] mmc: dw_mmc-rockchip: add v2 tuning support + +v2 tuning will inherit pre-stage loader's phase +settings for the first time, and do re-tune if +necessary. Re-tune will still try the rough degrees, +for instance, 90, 180, 270, 360 but continue to do the +fine tuning if sample window isn't good enough. + +Change-Id: I593384ee381d09df5b9adfc29a18eb22517b2764 +Signed-off-by: Shawn Lin +--- + drivers/mmc/host/dw_mmc-rockchip.c | 48 ++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) + +--- a/drivers/mmc/host/dw_mmc-rockchip.c ++++ b/drivers/mmc/host/dw_mmc-rockchip.c +@@ -24,6 +24,8 @@ struct dw_mci_rockchip_priv_data { + struct clk *sample_clk; + int default_sample_phase; + int num_phases; ++ int last_degree; ++ bool use_v2_tuning; + }; + + static void dw_mci_rk3288_set_ios(struct dw_mci *host, struct mmc_ios *ios) +@@ -134,6 +136,58 @@ static void dw_mci_rk3288_set_ios(struct + #define TUNING_ITERATION_TO_PHASE(i, num_phases) \ + (DIV_ROUND_UP((i) * 360, num_phases)) + ++static int dw_mci_v2_execute_tuning(struct dw_mci_slot *slot, u32 opcode) ++{ ++ struct dw_mci *host = slot->host; ++ struct dw_mci_rockchip_priv_data *priv = host->priv; ++ struct mmc_host *mmc = slot->mmc; ++ u32 degrees[4] = {0, 90, 180, 270}, degree; ++ int i; ++ static bool inherit = true; ++ ++ if (inherit) { ++ inherit = false; ++ i = clk_get_phase(priv->sample_clk) / 90; ++ degree = degrees[i]; ++ goto done; ++ } ++ ++ /* ++ * 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 < ARRAY_SIZE(degrees); i++) { ++ degree = degrees[i] + priv->last_degree + 90; ++ degree = degree % 360; ++ clk_set_phase(priv->sample_clk, degree); ++ if (mmc_send_tuning(mmc, opcode, NULL)) { ++ /* ++ * Tuning error, the phase is a bad phase, ++ * then try using the calculated best phase. ++ */ ++ dev_info(host->dev, "V2 tuned phase to %d error, try the best phase\n", degree); ++ degree = (degree + 180) % 360; ++ clk_set_phase(priv->sample_clk, degree); ++ if (!mmc_send_tuning(mmc, opcode, NULL)) ++ break; ++ } ++ } ++ ++ if (i == ARRAY_SIZE(degrees)) { ++ dev_warn(host->dev, "V2 All phases bad!"); ++ return -EIO; ++ } ++ ++done: ++ dev_info(host->dev, "V2 Successfully tuned phase to %d\n", degree); ++ priv->last_degree = degree; ++ return 0; ++} ++ + static int dw_mci_rk3288_execute_tuning(struct dw_mci_slot *slot, u32 opcode) + { + struct dw_mci *host = slot->host; +@@ -157,6 +211,12 @@ static int dw_mci_rk3288_execute_tuning( + return -EIO; + } + ++ if (priv->use_v2_tuning) { ++ if (!dw_mci_v2_execute_tuning(slot, opcode)) ++ return 0; ++ /* Otherwise we continue using fine tuning */ ++ } ++ + ranges = kmalloc_array(priv->num_phases / 2 + 1, + sizeof(*ranges), GFP_KERNEL); + if (!ranges) +@@ -277,6 +337,9 @@ static int dw_mci_rk3288_parse_dt(struct + &priv->default_sample_phase)) + priv->default_sample_phase = 0; + ++ if (of_property_read_bool(np, "rockchip,use-v2-tuning")) ++ priv->use_v2_tuning = true; ++ + priv->drv_clk = devm_clk_get(host->dev, "ciu-drive"); + if (IS_ERR(priv->drv_clk)) + dev_dbg(host->dev, "ciu-drive not available\n");