diff --git a/package/boot/uboot-rockchip/Makefile b/package/boot/uboot-rockchip/Makefile index d02629011..ff9a80fb3 100644 --- a/package/boot/uboot-rockchip/Makefile +++ b/package/boot/uboot-rockchip/Makefile @@ -183,6 +183,35 @@ define U-Boot/sv901-eaio-rk3399 USE_RKBIN:=1 endef +# RK3528 boards + +define U-Boot/rk3528/Default + BUILD_SUBTARGET:=armv8 + DEPENDS:=+PACKAGE_u-boot-$(1):rkbin-rk3528 + ATF:=rk3528_bl31_v1.17.elf + TPL:=rk3528_ddr_1056MHz_v1.10.bin +endef + +define U-Boot/generic-rk3528 + $(U-Boot/rk3528/Default) + NAME:=GENERIC RK3528 + BUILD_DEVICES:= \ + armsom_sige1 \ + hinlink_opc-h28k \ + hinlink_opc-h29k \ + hinlink_opc-ht2 \ + widora_mangopi-m28c \ + widora_mangopi-m28k \ + widora_mangopi-m28k-pro +endef + +define U-Boot/radxa-e20c-rk3528 + $(U-Boot/rk3528/Default) + NAME:=Radxa E20C + BUILD_DEVICES:= \ + radxa_e20c +endef + # RK3566 boards define U-Boot/rk3566/Default @@ -384,6 +413,8 @@ define U-Boot/rock5a-rk3588s endef UBOOT_TARGETS := \ + generic-rk3528 \ + radxa-e20c-rk3528 \ nanopi-r3s-rk3566 \ panther-x2-rk3566 \ rock-3c-rk3566 \ diff --git a/package/boot/uboot-rockchip/patches/400-arm64-dts-rockchip-Add-base-DT-for-rk3528-SoC.patch b/package/boot/uboot-rockchip/patches/400-arm64-dts-rockchip-Add-base-DT-for-rk3528-SoC.patch new file mode 100644 index 000000000..4958b3c0e --- /dev/null +++ b/package/boot/uboot-rockchip/patches/400-arm64-dts-rockchip-Add-base-DT-for-rk3528-SoC.patch @@ -0,0 +1,210 @@ +From 7983e6c379a917c500eff31f5f9c646cc408e030 Mon Sep 17 00:00:00 2001 +From: Yao Zi +Date: Thu, 29 Aug 2024 09:27:04 +0000 +Subject: [PATCH] arm64: dts: rockchip: Add base DT for rk3528 SoC + +This initial device tree describes CPU, interrupts and UART on the chip +and is able to boot into basic kernel with only UART. Cache information +is omitted for now as there is no precise documentation. Support for +other features will be added later. + +Signed-off-by: Yao Zi +Link: https://lore.kernel.org/r/20240829092705.6241-4-ziyao@disroot.org +Signed-off-by: Heiko Stuebner +--- + arch/arm64/boot/dts/rockchip/rk3528.dtsi | 189 +++++++++++++++++++++++ + 1 file changed, 189 insertions(+) + create mode 100644 arch/arm64/boot/dts/rockchip/rk3528.dtsi + +--- /dev/null ++++ b/dts/upstream/src/arm64/rockchip/rk3528.dtsi +@@ -0,0 +1,189 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd. ++ * Copyright (c) 2024 Yao Zi ++ */ ++ ++#include ++#include ++ ++/ { ++ compatible = "rockchip,rk3528"; ++ ++ interrupt-parent = <&gic>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ serial2 = &uart2; ++ serial3 = &uart3; ++ serial4 = &uart4; ++ serial5 = &uart5; ++ serial6 = &uart6; ++ serial7 = &uart7; ++ }; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu-map { ++ cluster0 { ++ core0 { ++ cpu = <&cpu0>; ++ }; ++ core1 { ++ cpu = <&cpu1>; ++ }; ++ core2 { ++ cpu = <&cpu2>; ++ }; ++ core3 { ++ cpu = <&cpu3>; ++ }; ++ }; ++ }; ++ ++ cpu0: cpu@0 { ++ compatible = "arm,cortex-a53"; ++ reg = <0x0>; ++ device_type = "cpu"; ++ enable-method = "psci"; ++ }; ++ ++ cpu1: cpu@1 { ++ compatible = "arm,cortex-a53"; ++ reg = <0x1>; ++ device_type = "cpu"; ++ enable-method = "psci"; ++ }; ++ ++ cpu2: cpu@2 { ++ compatible = "arm,cortex-a53"; ++ reg = <0x2>; ++ device_type = "cpu"; ++ enable-method = "psci"; ++ }; ++ ++ cpu3: cpu@3 { ++ compatible = "arm,cortex-a53"; ++ reg = <0x3>; ++ device_type = "cpu"; ++ enable-method = "psci"; ++ }; ++ }; ++ ++ psci { ++ compatible = "arm,psci-1.0", "arm,psci-0.2"; ++ method = "smc"; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ ++ xin24m: clock-xin24m { ++ compatible = "fixed-clock"; ++ clock-frequency = <24000000>; ++ clock-output-names = "xin24m"; ++ #clock-cells = <0>; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ ranges = <0x0 0xfe000000 0x0 0xfe000000 0x0 0x2000000>; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ gic: interrupt-controller@fed01000 { ++ compatible = "arm,gic-400"; ++ reg = <0x0 0xfed01000 0 0x1000>, ++ <0x0 0xfed02000 0 0x2000>, ++ <0x0 0xfed04000 0 0x2000>, ++ <0x0 0xfed06000 0 0x2000>; ++ interrupts = ; ++ interrupt-controller; ++ #address-cells = <0>; ++ #interrupt-cells = <3>; ++ }; ++ ++ uart0: serial@ff9f0000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff9f0000 0x0 0x100>; ++ clock-frequency = <24000000>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@ff9f8000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xff9f8000 0x0 0x100>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@ffa00000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xffa00000 0x0 0x100>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart3: serial@ffa08000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xffa08000 0x0 0x100>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart4: serial@ffa10000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xffa10000 0x0 0x100>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart5: serial@ffa18000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xffa18000 0x0 0x100>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart6: serial@ffa20000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xffa20000 0x0 0x100>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart7: serial@ffa28000 { ++ compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; ++ reg = <0x0 0xffa28000 0x0 0x100>; ++ interrupts = ; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ }; ++}; diff --git a/package/boot/uboot-rockchip/patches/401-rockchip-mkimage-Add-support-for-RK3528.patch b/package/boot/uboot-rockchip/patches/401-rockchip-mkimage-Add-support-for-RK3528.patch new file mode 100644 index 000000000..16598df0b --- /dev/null +++ b/package/boot/uboot-rockchip/patches/401-rockchip-mkimage-Add-support-for-RK3528.patch @@ -0,0 +1,26 @@ +From 37a4c7f5fb6e75e248e84500f27d3945c502e381 Mon Sep 17 00:00:00 2001 +From: Yifeng Zhao +Date: Thu, 23 Jan 2025 22:48:13 +0000 +Subject: [PATCH 1/9] rockchip: mkimage: Add support for RK3528 + +Add support for generating Rockchip Boot Image for RK3528. + +Similar to RK3568, the RK3528 has 64 KiB SRAM and 4 KiB of it is +reserved for BootROM. + +Signed-off-by: Yifeng Zhao +Signed-off-by: Jonas Karlman +--- + tools/rkcommon.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/tools/rkcommon.c ++++ b/tools/rkcommon.c +@@ -134,6 +134,7 @@ static struct spl_info spl_infos[] = { + { "rk3399", "RK33", 0x30000 - 0x2000, false, RK_HEADER_V1 }, + { "rv1108", "RK11", 0x1800, false, RK_HEADER_V1 }, + { "rv1126", "110B", 0x10000 - 0x1000, false, RK_HEADER_V1 }, ++ { "rk3528", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 }, + { "rk3568", "RK35", 0x10000 - 0x1000, false, RK_HEADER_V2 }, + { "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 }, + }; diff --git a/package/boot/uboot-rockchip/patches/402-arch-arm-rockchip-Add-initial-support-for-RK3528.patch b/package/boot/uboot-rockchip/patches/402-arch-arm-rockchip-Add-initial-support-for-RK3528.patch new file mode 100644 index 000000000..97d71c6ef --- /dev/null +++ b/package/boot/uboot-rockchip/patches/402-arch-arm-rockchip-Add-initial-support-for-RK3528.patch @@ -0,0 +1,372 @@ +From f6c7b9632a51e6c29a8be4e4e6d137a511fbf3fb Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:14 +0000 +Subject: [PATCH 2/9] arch: arm: rockchip: Add initial support for RK3528 + +Rockchip RK3528 is a ARM-based SoC with quad-core Cortex-A53. + +Add initial arch support for the RK3528 SoC. + +Signed-off-by: Jonas Karlman +--- + arch/arm/include/asm/arch-rk3528/boot0.h | 9 ++ + arch/arm/include/asm/arch-rk3528/gpio.h | 9 ++ + arch/arm/mach-rockchip/Kconfig | 50 +++++++ + arch/arm/mach-rockchip/Makefile | 1 + + arch/arm/mach-rockchip/rk3528/Kconfig | 15 ++ + arch/arm/mach-rockchip/rk3528/Makefile | 4 + + arch/arm/mach-rockchip/rk3528/rk3528.c | 137 ++++++++++++++++++ + arch/arm/mach-rockchip/rk3528/syscon_rk3528.c | 19 +++ + drivers/usb/gadget/Kconfig | 1 + + include/configs/rk3528_common.h | 42 ++++++ + 10 files changed, 287 insertions(+) + create mode 100644 arch/arm/include/asm/arch-rk3528/boot0.h + create mode 100644 arch/arm/include/asm/arch-rk3528/gpio.h + create mode 100644 arch/arm/mach-rockchip/rk3528/Kconfig + create mode 100644 arch/arm/mach-rockchip/rk3528/Makefile + create mode 100644 arch/arm/mach-rockchip/rk3528/rk3528.c + create mode 100644 arch/arm/mach-rockchip/rk3528/syscon_rk3528.c + create mode 100644 include/configs/rk3528_common.h + +--- /dev/null ++++ b/arch/arm/include/asm/arch-rk3528/boot0.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* Copyright Contributors to the U-Boot project. */ ++ ++#ifndef __ASM_ARCH_BOOT0_H__ ++#define __ASM_ARCH_BOOT0_H__ ++ ++#include ++ ++#endif +--- /dev/null ++++ b/arch/arm/include/asm/arch-rk3528/gpio.h +@@ -0,0 +1,9 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* Copyright Contributors to the U-Boot project. */ ++ ++#ifndef __ASM_ARCH_GPIO_H__ ++#define __ASM_ARCH_GPIO_H__ ++ ++#include ++ ++#endif +--- a/arch/arm/mach-rockchip/Kconfig ++++ b/arch/arm/mach-rockchip/Kconfig +@@ -309,6 +309,55 @@ config ROCKCHIP_RK3399 + and video codec support. Peripherals include Gigabit Ethernet, + USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs. + ++config ROCKCHIP_RK3528 ++ bool "Support Rockchip RK3528" ++ select ARM64 ++ select SUPPORT_SPL ++ select SPL ++ select CLK ++ select PINCTRL ++ select RAM ++ select REGMAP ++ select SYSCON ++ select BOARD_LATE_INIT ++ select DM_REGULATOR_FIXED ++ select DM_RESET ++ imply ARMV8_CRYPTO ++ imply ARMV8_SET_SMPEN ++ imply BOOTSTD_FULL ++ imply DM_RNG ++ imply FIT ++ imply LEGACY_IMAGE_FORMAT ++ imply MISC ++ imply MISC_INIT_R ++ imply MMC_HS200_SUPPORT if MMC_SDHCI_ROCKCHIP ++ imply OF_LIBFDT_OVERLAY ++ imply OF_LIVE ++ imply OF_UPSTREAM ++ imply PHY_GIGE if DWC_ETH_QOS_ROCKCHIP ++ imply RNG_ROCKCHIP ++ imply ROCKCHIP_COMMON_BOARD ++ imply ROCKCHIP_COMMON_STACK_ADDR ++ imply ROCKCHIP_EXTERNAL_TPL ++ imply ROCKCHIP_OTP ++ imply SPL_ATF ++ imply SPL_ATF_NO_PLATFORM_PARAM if SPL_ATF ++ imply SPL_CLK ++ imply SPL_DM_SEQ_ALIAS ++ imply SPL_FIT_SIGNATURE ++ imply SPL_LOAD_FIT ++ imply SPL_MMC_HS200_SUPPORT if SPL_MMC && MMC_HS200_SUPPORT ++ imply SPL_OF_CONTROL ++ imply SPL_PINCTRL ++ imply SPL_RAM ++ imply SPL_REGMAP ++ imply SPL_SERIAL ++ imply SPL_SYSCON ++ imply SYS_RELOC_GD_ENV_ADDR ++ imply SYSRESET ++ help ++ The Rockchip RK3528 is a ARM-based SoC with quad-core Cortex-A53. ++ + config ROCKCHIP_RK3568 + bool "Support Rockchip RK3568" + select ARM64 +@@ -626,6 +675,7 @@ source "arch/arm/mach-rockchip/rk3308/Kc + source "arch/arm/mach-rockchip/rk3328/Kconfig" + source "arch/arm/mach-rockchip/rk3368/Kconfig" + source "arch/arm/mach-rockchip/rk3399/Kconfig" ++source "arch/arm/mach-rockchip/rk3528/Kconfig" + source "arch/arm/mach-rockchip/rk3568/Kconfig" + source "arch/arm/mach-rockchip/rk3588/Kconfig" + source "arch/arm/mach-rockchip/rv1108/Kconfig" +--- a/arch/arm/mach-rockchip/Makefile ++++ b/arch/arm/mach-rockchip/Makefile +@@ -42,6 +42,7 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += rk3308/ + obj-$(CONFIG_ROCKCHIP_RK3328) += rk3328/ + obj-$(CONFIG_ROCKCHIP_RK3368) += rk3368/ + obj-$(CONFIG_ROCKCHIP_RK3399) += rk3399/ ++obj-$(CONFIG_ROCKCHIP_RK3528) += rk3528/ + obj-$(CONFIG_ROCKCHIP_RK3568) += rk3568/ + obj-$(CONFIG_ROCKCHIP_RK3588) += rk3588/ + obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/ +--- /dev/null ++++ b/arch/arm/mach-rockchip/rk3528/Kconfig +@@ -0,0 +1,15 @@ ++if ROCKCHIP_RK3528 ++ ++config ROCKCHIP_BOOT_MODE_REG ++ default 0xff370200 ++ ++config ROCKCHIP_STIMER_BASE ++ default 0xff620000 ++ ++config SYS_SOC ++ default "rk3528" ++ ++config SYS_CONFIG_NAME ++ default "rk3528_common" ++ ++endif +--- /dev/null ++++ b/arch/arm/mach-rockchip/rk3528/Makefile +@@ -0,0 +1,4 @@ ++# SPDX-License-Identifier: GPL-2.0-or-later ++ ++obj-y += rk3528.o ++obj-y += syscon_rk3528.o +--- /dev/null ++++ b/arch/arm/mach-rockchip/rk3528/rk3528.c +@@ -0,0 +1,137 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++// Copyright Contributors to the U-Boot project. ++ ++#define LOG_CATEGORY LOGC_ARCH ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define FIREWALL_DDR_BASE 0xff2e0000 ++#define FW_DDR_MST6_REG 0x58 ++#define FW_DDR_MST7_REG 0x5c ++#define FW_DDR_MST14_REG 0x78 ++#define FW_DDR_MST16_REG 0x80 ++ ++const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { ++ [BROM_BOOTSOURCE_EMMC] = "/soc/mmc@ffbf0000", ++ [BROM_BOOTSOURCE_SD] = "/soc/mmc@ffc30000", ++}; ++ ++static struct mm_region rk3528_mem_map[] = { ++ { ++ .virt = 0x0UL, ++ .phys = 0x0UL, ++ .size = 0xfc000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | ++ PTE_BLOCK_INNER_SHARE ++ }, { ++ .virt = 0xfc000000UL, ++ .phys = 0xfc000000UL, ++ .size = 0x04000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE | ++ PTE_BLOCK_PXN | PTE_BLOCK_UXN ++ }, { ++ /* List terminator */ ++ 0, ++ } ++}; ++ ++struct mm_region *mem_map = rk3528_mem_map; ++ ++void board_debug_uart_init(void) ++{ ++} ++ ++int arch_cpu_init(void) ++{ ++ u32 val; ++ ++ if (!IS_ENABLED(CONFIG_SPL_BUILD)) ++ return 0; ++ ++ /* Set the emmc to access ddr memory */ ++ val = readl(FIREWALL_DDR_BASE + FW_DDR_MST6_REG); ++ writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST6_REG); ++ ++ /* Set the fspi to access ddr memory */ ++ val = readl(FIREWALL_DDR_BASE + FW_DDR_MST7_REG); ++ writel(val & 0xffff0000, FIREWALL_DDR_BASE + FW_DDR_MST7_REG); ++ ++ /* Set the sdmmc to access ddr memory */ ++ val = readl(FIREWALL_DDR_BASE + FW_DDR_MST14_REG); ++ writel(val & 0x0000ffff, FIREWALL_DDR_BASE + FW_DDR_MST14_REG); ++ ++ /* Set the usb to access ddr memory */ ++ val = readl(FIREWALL_DDR_BASE + FW_DDR_MST16_REG); ++ writel(val & 0xffff0000, FIREWALL_DDR_BASE + FW_DDR_MST16_REG); ++ ++ return 0; ++} ++ ++#define HP_TIMER_BASE CONFIG_ROCKCHIP_STIMER_BASE ++#define HP_CTRL_REG 0x04 ++#define TIMER_EN BIT(0) ++#define HP_LOAD_COUNT0_REG 0x14 ++#define HP_LOAD_COUNT1_REG 0x18 ++ ++void rockchip_stimer_init(void) ++{ ++ u32 reg; ++ ++ if (!IS_ENABLED(CONFIG_XPL_BUILD)) ++ return; ++ ++ reg = readl(HP_TIMER_BASE + HP_CTRL_REG); ++ if (reg & TIMER_EN) ++ return; ++ ++ asm volatile("msr cntfrq_el0, %0" : : "r" (CONFIG_COUNTER_FREQUENCY)); ++ writel(0xffffffff, HP_TIMER_BASE + HP_LOAD_COUNT0_REG); ++ writel(0xffffffff, HP_TIMER_BASE + HP_LOAD_COUNT1_REG); ++ writel(TIMER_EN, HP_TIMER_BASE + HP_CTRL_REG); ++} ++ ++#define RK3528_OTP_CPU_CODE_OFFSET 0x02 ++#define RK3528_OTP_CPU_CHIP_TYPE_OFFSET 0x28 ++ ++int checkboard(void) ++{ ++ u8 cpu_code[2], chip_type; ++ struct udevice *dev; ++ char suffix[2]; ++ int ret; ++ ++ if (!IS_ENABLED(CONFIG_ROCKCHIP_OTP) || !CONFIG_IS_ENABLED(MISC)) ++ return 0; ++ ++ ret = uclass_get_device_by_driver(UCLASS_MISC, ++ DM_DRIVER_GET(rockchip_otp), &dev); ++ if (ret) { ++ log_debug("Could not find otp device, ret=%d\n", ret); ++ return 0; ++ } ++ ++ /* cpu-code: SoC model, e.g. 0x35 0x28 */ ++ ret = misc_read(dev, RK3528_OTP_CPU_CODE_OFFSET, cpu_code, 2); ++ if (ret < 0) { ++ log_debug("Could not read cpu-code, ret=%d\n", ret); ++ return 0; ++ } ++ ++ ret = misc_read(dev, RK3528_OTP_CPU_CHIP_TYPE_OFFSET, &chip_type, 1); ++ if (ret < 0) { ++ log_debug("Could not read chip type, ret=%d\n", ret); ++ return 0; ++ } ++ ++ suffix[0] = chip_type != 0x1 ? 'A' : '\0'; ++ suffix[1] = '\0'; ++ ++ printf("SoC: RK%02x%02x%s\n", cpu_code[0], cpu_code[1], suffix); ++ ++ return 0; ++} +--- /dev/null ++++ b/arch/arm/mach-rockchip/rk3528/syscon_rk3528.c +@@ -0,0 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++// Copyright Contributors to the U-Boot project. ++ ++#include ++#include ++ ++static const struct udevice_id rk3528_syscon_ids[] = { ++ { .compatible = "rockchip,rk3528-grf", .data = ROCKCHIP_SYSCON_GRF }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rockchip_rk3528_syscon) = { ++ .name = "rockchip_rk3528_syscon", ++ .id = UCLASS_SYSCON, ++ .of_match = rk3528_syscon_ids, ++#if CONFIG_IS_ENABLED(OF_REAL) ++ .bind = dm_scan_fdt_dev, ++#endif ++}; +--- a/drivers/usb/gadget/Kconfig ++++ b/drivers/usb/gadget/Kconfig +@@ -85,6 +85,7 @@ config USB_GADGET_PRODUCT_NUM + default 0x330e if ROCKCHIP_RK3308 + default 0x350a if ROCKCHIP_RK3568 + default 0x350b if ROCKCHIP_RK3588 ++ default 0x350c if ROCKCHIP_RK3528 + default 0x0 + help + Product ID of the USB device emulated, reported to the host device. +--- /dev/null ++++ b/include/configs/rk3528_common.h +@@ -0,0 +1,42 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/* Copyright Contributors to the U-Boot project. */ ++ ++#ifndef __CONFIG_RK3528_COMMON_H ++#define __CONFIG_RK3528_COMMON_H ++ ++#define CFG_CPUID_OFFSET 0xa ++ ++#include "rockchip-common.h" ++ ++#define CFG_IRAM_BASE 0xfe480000 ++ ++#define CFG_SYS_SDRAM_BASE 0 ++#define SDRAM_MAX_SIZE 0xfc000000 ++ ++#ifndef CONFIG_XPL_BUILD ++ ++#ifndef ROCKCHIP_DEVICE_SETTINGS ++#define ROCKCHIP_DEVICE_SETTINGS ++#endif ++ ++#define ENV_MEM_LAYOUT_SETTINGS \ ++ "scriptaddr=0x00c00000\0" \ ++ "script_offset_f=0xffe000\0" \ ++ "script_size_f=0x2000\0" \ ++ "pxefile_addr_r=0x00e00000\0" \ ++ "kernel_addr_r=0x02000000\0" \ ++ "kernel_comp_addr_r=0x0a000000\0" \ ++ "fdt_addr_r=0x12000000\0" \ ++ "fdtoverlay_addr_r=0x12100000\0" \ ++ "ramdisk_addr_r=0x12180000\0" \ ++ "kernel_comp_size=0x8000000\0" ++ ++#define CFG_EXTRA_ENV_SETTINGS \ ++ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ ++ ENV_MEM_LAYOUT_SETTINGS \ ++ ROCKCHIP_DEVICE_SETTINGS \ ++ "boot_targets=" BOOT_TARGETS "\0" ++ ++#endif /* CONFIG_XPL_BUILD */ ++ ++#endif /* __CONFIG_RK3528_COMMON_H */ diff --git a/package/boot/uboot-rockchip/patches/403-ram-rockchip-Add-basic-support-for-RK3528.patch b/package/boot/uboot-rockchip/patches/403-ram-rockchip-Add-basic-support-for-RK3528.patch new file mode 100644 index 000000000..193a7b5bc --- /dev/null +++ b/package/boot/uboot-rockchip/patches/403-ram-rockchip-Add-basic-support-for-RK3528.patch @@ -0,0 +1,76 @@ +From 62e99c283ab507f93e7dadda1b05e5c459f0e60d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:15 +0000 +Subject: [PATCH 3/9] ram: rockchip: Add basic support for RK3528 + +Add support for reading DRAM size information from PMUGRF os_reg18 reg. + +Compared to most Rockchip SoCs the RK3528 use os_reg18 for DRAM info, +instead of os_reg2. + +Signed-off-by: Jonas Karlman +--- + arch/arm/mach-rockchip/sdram.c | 3 ++- + drivers/ram/rockchip/Makefile | 1 + + drivers/ram/rockchip/sdram_rk3528.c | 33 +++++++++++++++++++++++++++++ + 3 files changed, 36 insertions(+), 1 deletion(-) + create mode 100644 drivers/ram/rockchip/sdram_rk3528.c + +--- a/arch/arm/mach-rockchip/sdram.c ++++ b/arch/arm/mach-rockchip/sdram.c +@@ -110,7 +110,8 @@ static int rockchip_dram_init_banksize(v + u8 i, j; + + if (!IS_ENABLED(CONFIG_ROCKCHIP_RK3588) && +- !IS_ENABLED(CONFIG_ROCKCHIP_RK3568)) ++ !IS_ENABLED(CONFIG_ROCKCHIP_RK3568) && ++ !IS_ENABLED(CONFIG_ROCKCHIP_RK3528)) + return -ENOTSUPP; + + if (!IS_ENABLED(CONFIG_ROCKCHIP_EXTERNAL_TPL)) +--- a/drivers/ram/rockchip/Makefile ++++ b/drivers/ram/rockchip/Makefile +@@ -13,6 +13,7 @@ obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk + obj-$(CONFIG_ROCKCHIP_RK3308) = sdram_rk3308.o + obj-$(CONFIG_ROCKCHIP_RK3328) = sdram_rk3328.o sdram_pctl_px30.o sdram_phy_px30.o + obj-$(CONFIG_ROCKCHIP_RK3399) += sdram_rk3399.o ++obj-$(CONFIG_ROCKCHIP_RK3528) += sdram_rk3528.o + obj-$(CONFIG_ROCKCHIP_RK3568) += sdram_rk3568.o + obj-$(CONFIG_ROCKCHIP_RK3588) += sdram_rk3588.o + obj-$(CONFIG_ROCKCHIP_RV1126) += sdram_rv1126.o sdram_pctl_px30.o +--- /dev/null ++++ b/drivers/ram/rockchip/sdram_rk3528.c +@@ -0,0 +1,33 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++// Copyright Contributors to the U-Boot project. ++ ++#include ++#include ++#include ++ ++#define PMUGRF_BASE 0xff370000 ++#define OS_REG18_REG 0x248 ++ ++static int rk3528_dmc_get_info(struct udevice *dev, struct ram_info *info) ++{ ++ info->base = CFG_SYS_SDRAM_BASE; ++ info->size = rockchip_sdram_size(PMUGRF_BASE + OS_REG18_REG); ++ ++ return 0; ++} ++ ++static struct ram_ops rk3528_dmc_ops = { ++ .get_info = rk3528_dmc_get_info, ++}; ++ ++static const struct udevice_id rk3528_dmc_ids[] = { ++ { .compatible = "rockchip,rk3528-dmc" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rockchip_rk3528_dmc) = { ++ .name = "rockchip_rk3528_dmc", ++ .id = UCLASS_RAM, ++ .of_match = rk3528_dmc_ids, ++ .ops = &rk3528_dmc_ops, ++}; diff --git a/package/boot/uboot-rockchip/patches/404-clk-rockchip-Add-support-for-RK3528.patch b/package/boot/uboot-rockchip/patches/404-clk-rockchip-Add-support-for-RK3528.patch new file mode 100644 index 000000000..0bda1e08f --- /dev/null +++ b/package/boot/uboot-rockchip/patches/404-clk-rockchip-Add-support-for-RK3528.patch @@ -0,0 +1,3024 @@ +From f589cfb79c124649a74f09ec6e8534153dda176e Mon Sep 17 00:00:00 2001 +From: Joseph Chen +Date: Thu, 23 Jan 2025 22:48:16 +0000 +Subject: [PATCH 4/9] clk: rockchip: Add support for RK3528 + +Add clock driver for RK3528. + +Imported from vendor U-Boot linux-6.1-stan-rkr5 tag with minor +adjustments and fixes for mainline. + +Signed-off-by: Joseph Chen +Signed-off-by: Finley Xiao +Signed-off-by: Jonas Karlman +--- + arch/arm/include/asm/arch-rockchip/clock.h | 7 + + .../include/asm/arch-rockchip/cru_rk3528.h | 388 ++++ + arch/arm/mach-rockchip/rk3528/Makefile | 1 + + arch/arm/mach-rockchip/rk3528/clk_rk3528.c | 16 + + drivers/clk/rockchip/Makefile | 1 + + drivers/clk/rockchip/clk_pll.c | 23 +- + drivers/clk/rockchip/clk_rk3528.c | 1744 +++++++++++++++++ + include/dt-bindings/clock/rk3528-cru.h | 751 +++++++ + 8 files changed, 2925 insertions(+), 6 deletions(-) + create mode 100644 arch/arm/include/asm/arch-rockchip/cru_rk3528.h + create mode 100644 arch/arm/mach-rockchip/rk3528/clk_rk3528.c + create mode 100644 drivers/clk/rockchip/clk_rk3528.c + create mode 100644 include/dt-bindings/clock/rk3528-cru.h + +--- a/arch/arm/include/asm/arch-rockchip/clock.h ++++ b/arch/arm/include/asm/arch-rockchip/clock.h +@@ -15,6 +15,13 @@ struct udevice; + #define RKCLK_PLL_MODE_NORMAL 1 + #define RKCLK_PLL_MODE_DEEP 2 + ++/* ++ * PLL flags ++ */ ++#define ROCKCHIP_PLL_SYNC_RATE BIT(0) ++/* normal mode only. now only for pll_rk3036, pll_rk3328 type */ ++#define ROCKCHIP_PLL_FIXED_MODE BIT(1) ++ + enum { + ROCKCHIP_SYSCON_NOC, + ROCKCHIP_SYSCON_GRF, +--- /dev/null ++++ b/arch/arm/include/asm/arch-rockchip/cru_rk3528.h +@@ -0,0 +1,388 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd. ++ * Author: Joseph Chen ++ */ ++ ++#ifndef _ASM_ARCH_CRU_RK3528_H ++#define _ASM_ARCH_CRU_RK3528_H ++ ++#define MHz 1000000 ++#define KHz 1000 ++#define OSC_HZ (24 * MHz) ++ ++#define CPU_PVTPLL_HZ (1200 * MHz) ++#define APLL_HZ (600 * MHz) ++#define GPLL_HZ (1188 * MHz) ++#define CPLL_HZ (996 * MHz) ++#define PPLL_HZ (1000 * MHz) ++ ++/* RK3528 pll id */ ++enum rk3528_pll_id { ++ APLL, ++ CPLL, ++ GPLL, ++ PPLL, ++ DPLL, ++ PLL_COUNT, ++}; ++ ++struct rk3528_clk_priv { ++ struct rk3528_cru *cru; ++ unsigned long ppll_hz; ++ unsigned long gpll_hz; ++ unsigned long cpll_hz; ++ unsigned long armclk_hz; ++ unsigned long armclk_enter_hz; ++ unsigned long armclk_init_hz; ++ bool sync_kernel; ++}; ++ ++struct rk3528_pll { ++ unsigned int con0; ++ unsigned int con1; ++ unsigned int con2; ++ unsigned int con3; ++ unsigned int con4; ++ unsigned int reserved0[3]; ++}; ++ ++#define RK3528_CRU_BASE ((struct rk3528_cru *)0xff4a0000) ++ ++struct rk3528_cru { ++ unsigned int apll_con[5]; ++ unsigned int reserved0014[3]; ++ unsigned int cpll_con[5]; ++ unsigned int reserved0034[11]; ++ unsigned int gpll_con[5]; ++ unsigned int reserved0074[51 + 32]; ++ unsigned int reserved01c0[48]; ++ unsigned int mode_con[1]; ++ unsigned int reserved0284[31]; ++ unsigned int clksel_con[91]; ++ unsigned int reserved046c[229]; ++ unsigned int gate_con[46]; ++ unsigned int reserved08b8[82]; ++ unsigned int softrst_con[47]; ++ unsigned int reserved0abc[81]; ++ unsigned int glb_cnt_th; ++ unsigned int glb_rst_st; ++ unsigned int glb_srst_fst; ++ unsigned int glb_srst_snd; ++ unsigned int glb_rst_con; ++ unsigned int reserved0c14[6]; ++ unsigned int corewfi_con; ++ unsigned int reserved0c30[15604]; ++ ++ /* pmucru */ ++ unsigned int reserved10000[192]; ++ unsigned int pmuclksel_con[3]; ++ unsigned int reserved1030c[317]; ++ unsigned int pmugate_con[3]; ++ unsigned int reserved1080c[125]; ++ unsigned int pmusoftrst_con[3]; ++ unsigned int reserved10a08[7550 + 8191]; ++ ++ /* pciecru */ ++ unsigned int reserved20000[32]; ++ unsigned int ppll_con[5]; ++ unsigned int reserved20094[155]; ++ unsigned int pcieclksel_con[2]; ++ unsigned int reserved20308[318]; ++ unsigned int pciegate_con; ++}; ++ ++check_member(rk3528_cru, pciegate_con, 0x20800); ++ ++struct pll_rate_table { ++ unsigned long rate; ++ unsigned int fbdiv; ++ unsigned int postdiv1; ++ unsigned int refdiv; ++ unsigned int postdiv2; ++ unsigned int dsmpd; ++ unsigned int frac; ++}; ++ ++#define RK3528_PMU_CRU_BASE 0x10000 ++#define RK3528_PCIE_CRU_BASE 0x20000 ++#define RK3528_DDRPHY_CRU_BASE 0x28000 ++#define RK3528_PLL_CON(x) ((x) * 0x4) ++#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_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PMU_CRU_BASE) ++#define RK3528_PCIE_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PCIE_CRU_BASE) ++#define RK3528_DDRPHY_MODE_CON (0x280 + RK3528_DDRPHY_CRU_BASE) ++ ++#define RK3528_DIV_ACLK_M_CORE_SHIFT 11 ++#define RK3528_DIV_ACLK_M_CORE_MASK (0x1f << RK3528_DIV_ACLK_M_CORE_SHIFT) ++#define RK3528_DIV_PCLK_DBG_SHIFT 1 ++#define RK3528_DIV_PCLK_DBG_MASK (0x1f << RK3528_DIV_PCLK_DBG_SHIFT) ++ ++enum { ++ /* CRU_CLKSEL_CON00 */ ++ CLK_MATRIX_50M_SRC_DIV_SHIFT = 2, ++ CLK_MATRIX_50M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_50M_SRC_DIV_SHIFT, ++ CLK_MATRIX_100M_SRC_DIV_SHIFT = 7, ++ CLK_MATRIX_100M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_100M_SRC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON01 */ ++ CLK_MATRIX_150M_SRC_DIV_SHIFT = 0, ++ CLK_MATRIX_150M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_150M_SRC_DIV_SHIFT, ++ CLK_MATRIX_200M_SRC_DIV_SHIFT = 5, ++ CLK_MATRIX_200M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_200M_SRC_DIV_SHIFT, ++ CLK_MATRIX_250M_SRC_DIV_SHIFT = 10, ++ CLK_MATRIX_250M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_250M_SRC_DIV_SHIFT, ++ CLK_MATRIX_250M_SRC_SEL_SHIFT = 15, ++ CLK_MATRIX_250M_SRC_SEL_MASK = 0x1 << CLK_MATRIX_250M_SRC_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON02 */ ++ CLK_MATRIX_300M_SRC_DIV_SHIFT = 0, ++ CLK_MATRIX_300M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_300M_SRC_DIV_SHIFT, ++ CLK_MATRIX_339M_SRC_DIV_SHIFT = 5, ++ CLK_MATRIX_339M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_339M_SRC_DIV_SHIFT, ++ CLK_MATRIX_400M_SRC_DIV_SHIFT = 10, ++ CLK_MATRIX_400M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_400M_SRC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON03 */ ++ CLK_MATRIX_500M_SRC_DIV_SHIFT = 6, ++ CLK_MATRIX_500M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_500M_SRC_DIV_SHIFT, ++ CLK_MATRIX_500M_SRC_SEL_SHIFT = 11, ++ CLK_MATRIX_500M_SRC_SEL_MASK = 0x1 << CLK_MATRIX_500M_SRC_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON04 */ ++ CLK_MATRIX_600M_SRC_DIV_SHIFT = 0, ++ CLK_MATRIX_600M_SRC_DIV_MASK = 0x1F << CLK_MATRIX_600M_SRC_DIV_SHIFT, ++ CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX = 0U, ++ CLK_MATRIX_250M_SRC_SEL_CLK_CPLL_MUX = 1U, ++ CLK_MATRIX_500M_SRC_SEL_CLK_GPLL_MUX = 0U, ++ CLK_MATRIX_500M_SRC_SEL_CLK_CPLL_MUX = 1U, ++ ++ /* PMUCRU_CLKSEL_CON00 */ ++ CLK_I2C2_SEL_SHIFT = 0, ++ CLK_I2C2_SEL_MASK = 0x3 << CLK_I2C2_SEL_SHIFT, ++ ++ /* PCIE_CRU_CLKSEL_CON01 */ ++ PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT = 7, ++ PCIE_CLK_MATRIX_50M_SRC_DIV_MASK = 0x1f << PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT, ++ PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT = 11, ++ PCIE_CLK_MATRIX_100M_SRC_DIV_MASK = 0x1f << PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON32 */ ++ DCLK_VOP_SRC0_SEL_SHIFT = 10, ++ DCLK_VOP_SRC0_SEL_MASK = 0x1 << DCLK_VOP_SRC0_SEL_SHIFT, ++ DCLK_VOP_SRC0_DIV_SHIFT = 2, ++ DCLK_VOP_SRC0_DIV_MASK = 0xFF << DCLK_VOP_SRC0_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON33 */ ++ DCLK_VOP_SRC1_SEL_SHIFT = 8, ++ DCLK_VOP_SRC1_SEL_MASK = 0x1 << DCLK_VOP_SRC1_SEL_SHIFT, ++ DCLK_VOP_SRC1_DIV_SHIFT = 0, ++ DCLK_VOP_SRC1_DIV_MASK = 0xFF << DCLK_VOP_SRC1_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON43 */ ++ CLK_CORE_CRYPTO_SEL_SHIFT = 14, ++ CLK_CORE_CRYPTO_SEL_MASK = 0x3 << CLK_CORE_CRYPTO_SEL_SHIFT, ++ ACLK_BUS_VOPGL_ROOT_DIV_SHIFT = 0U, ++ ACLK_BUS_VOPGL_ROOT_DIV_MASK = 0x7U << ACLK_BUS_VOPGL_ROOT_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON44 */ ++ CLK_PWM0_SEL_SHIFT = 6, ++ CLK_PWM0_SEL_MASK = 0x3 << CLK_PWM0_SEL_SHIFT, ++ CLK_PWM1_SEL_SHIFT = 8, ++ CLK_PWM1_SEL_MASK = 0x3 << CLK_PWM1_SEL_SHIFT, ++ CLK_PWM0_SEL_CLK_MATRIX_100M_SRC = 0U, ++ CLK_PWM0_SEL_CLK_MATRIX_50M_SRC = 1U, ++ CLK_PWM0_SEL_XIN_OSC0_FUNC = 2U, ++ CLK_PWM1_SEL_CLK_MATRIX_100M_SRC = 0U, ++ CLK_PWM1_SEL_CLK_MATRIX_50M_SRC = 1U, ++ CLK_PWM1_SEL_XIN_OSC0_FUNC = 2U, ++ CLK_PKA_CRYPTO_SEL_SHIFT = 0, ++ CLK_PKA_CRYPTO_SEL_MASK = 0x3 << CLK_PKA_CRYPTO_SEL_SHIFT, ++ CLK_CORE_CRYPTO_SEL_CLK_MATRIX_300M_SRC = 0U, ++ CLK_CORE_CRYPTO_SEL_CLK_MATRIX_200M_SRC = 1U, ++ CLK_CORE_CRYPTO_SEL_CLK_MATRIX_100M_SRC = 2U, ++ CLK_CORE_CRYPTO_SEL_XIN_OSC0_FUNC = 3U, ++ CLK_PKA_CRYPTO_SEL_CLK_MATRIX_300M_SRC = 0U, ++ CLK_PKA_CRYPTO_SEL_CLK_MATRIX_200M_SRC = 1U, ++ CLK_PKA_CRYPTO_SEL_CLK_MATRIX_100M_SRC = 2U, ++ CLK_PKA_CRYPTO_SEL_XIN_OSC0_FUNC = 3U, ++ ++ /* CRU_CLKSEL_CON60 */ ++ CLK_MATRIX_25M_SRC_DIV_SHIFT = 2, ++ CLK_MATRIX_25M_SRC_DIV_MASK = 0xff << CLK_MATRIX_25M_SRC_DIV_SHIFT, ++ CLK_MATRIX_125M_SRC_DIV_SHIFT = 10, ++ CLK_MATRIX_125M_SRC_DIV_MASK = 0x1f << CLK_MATRIX_125M_SRC_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON61 */ ++ SCLK_SFC_DIV_SHIFT = 6, ++ SCLK_SFC_DIV_MASK = 0x3F << SCLK_SFC_DIV_SHIFT, ++ SCLK_SFC_SEL_SHIFT = 12, ++ SCLK_SFC_SEL_MASK = 0x3 << SCLK_SFC_SEL_SHIFT, ++ SCLK_SFC_SEL_CLK_GPLL_MUX = 0U, ++ SCLK_SFC_SEL_CLK_CPLL_MUX = 1U, ++ SCLK_SFC_SEL_XIN_OSC0_FUNC = 2U, ++ ++ /* CRU_CLKSEL_CON62 */ ++ CCLK_SRC_EMMC_DIV_SHIFT = 0, ++ CCLK_SRC_EMMC_DIV_MASK = 0x3F << CCLK_SRC_EMMC_DIV_SHIFT, ++ CCLK_SRC_EMMC_SEL_SHIFT = 6, ++ CCLK_SRC_EMMC_SEL_MASK = 0x3 << CCLK_SRC_EMMC_SEL_SHIFT, ++ BCLK_EMMC_SEL_SHIFT = 8, ++ BCLK_EMMC_SEL_MASK = 0x3 << BCLK_EMMC_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON63 */ ++ CLK_I2C3_SEL_SHIFT = 12, ++ CLK_I2C3_SEL_MASK = 0x3 << CLK_I2C3_SEL_SHIFT, ++ CLK_I2C5_SEL_SHIFT = 14, ++ CLK_I2C5_SEL_MASK = 0x3 << CLK_I2C5_SEL_SHIFT, ++ CLK_SPI1_SEL_SHIFT = 10, ++ CLK_SPI1_SEL_MASK = 0x3 << CLK_SPI1_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON64 */ ++ CLK_I2C6_SEL_SHIFT = 0, ++ CLK_I2C6_SEL_MASK = 0x3 << CLK_I2C6_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON74 */ ++ CLK_SARADC_DIV_SHIFT = 0, ++ CLK_SARADC_DIV_MASK = 0x7 << CLK_SARADC_DIV_SHIFT, ++ CLK_TSADC_DIV_SHIFT = 3, ++ CLK_TSADC_DIV_MASK = 0x1F << CLK_TSADC_DIV_SHIFT, ++ CLK_TSADC_TSEN_DIV_SHIFT = 8, ++ CLK_TSADC_TSEN_DIV_MASK = 0x1F << CLK_TSADC_TSEN_DIV_SHIFT, ++ ++ /* CRU_CLKSEL_CON79 */ ++ CLK_I2C1_SEL_SHIFT = 9, ++ CLK_I2C1_SEL_MASK = 0x3 << CLK_I2C1_SEL_SHIFT, ++ CLK_I2C0_SEL_SHIFT = 11, ++ CLK_I2C0_SEL_MASK = 0x3 << CLK_I2C0_SEL_SHIFT, ++ CLK_SPI0_SEL_SHIFT = 13, ++ CLK_SPI0_SEL_MASK = 0x3 << CLK_SPI0_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON83 */ ++ ACLK_VOP_ROOT_DIV_SHIFT = 12, ++ ACLK_VOP_ROOT_DIV_MASK = 0x7 << ACLK_VOP_ROOT_DIV_SHIFT, ++ ACLK_VOP_ROOT_SEL_SHIFT = 15, ++ ACLK_VOP_ROOT_SEL_MASK = 0x1 << ACLK_VOP_ROOT_SEL_SHIFT, ++ ++ /* CRU_CLKSEL_CON84 */ ++ DCLK_VOP0_SEL_SHIFT = 0, ++ DCLK_VOP0_SEL_MASK = 0x1 << DCLK_VOP0_SEL_SHIFT, ++ DCLK_VOP_SRC_SEL_CLK_GPLL_MUX = 0U, ++ DCLK_VOP_SRC_SEL_CLK_CPLL_MUX = 1U, ++ ACLK_VOP_ROOT_SEL_CLK_GPLL_MUX = 0U, ++ ACLK_VOP_ROOT_SEL_CLK_CPLL_MUX = 1U, ++ DCLK_VOP0_SEL_DCLK_VOP_SRC0 = 0U, ++ DCLK_VOP0_SEL_CLK_HDMIPHY_PIXEL_IO = 1U, ++ ++ /* CRU_CLKSEL_CON85 */ ++ CLK_I2C4_SEL_SHIFT = 13, ++ CLK_I2C4_SEL_MASK = 0x3 << CLK_I2C4_SEL_SHIFT, ++ CLK_I2C7_SEL_SHIFT = 0, ++ CLK_I2C7_SEL_MASK = 0x3 << CLK_I2C7_SEL_SHIFT, ++ CLK_I2C3_SEL_CLK_MATRIX_200M_SRC = 0U, ++ CLK_I2C3_SEL_CLK_MATRIX_100M_SRC = 1U, ++ CLK_I2C3_SEL_CLK_MATRIX_50M_SRC = 2U, ++ CLK_I2C3_SEL_XIN_OSC0_FUNC = 3U, ++ CLK_SPI1_SEL_CLK_MATRIX_200M_SRC = 0U, ++ CLK_SPI1_SEL_CLK_MATRIX_100M_SRC = 1U, ++ CLK_SPI1_SEL_CLK_MATRIX_50M_SRC = 2U, ++ CLK_SPI1_SEL_XIN_OSC0_FUNC = 3U, ++ CCLK_SRC_SDMMC0_DIV_SHIFT = 0, ++ CCLK_SRC_SDMMC0_DIV_MASK = 0x3F << CCLK_SRC_SDMMC0_DIV_SHIFT, ++ CCLK_SRC_SDMMC0_SEL_SHIFT = 6, ++ CCLK_SRC_SDMMC0_SEL_MASK = 0x3 << CCLK_SRC_SDMMC0_SEL_SHIFT, ++ CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX = 0U, ++ CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX = 1U, ++ CCLK_SRC_EMMC_SEL_XIN_OSC0_FUNC = 2U, ++ BCLK_EMMC_SEL_CLK_MATRIX_200M_SRC = 0U, ++ BCLK_EMMC_SEL_CLK_MATRIX_100M_SRC = 1U, ++ BCLK_EMMC_SEL_CLK_MATRIX_50M_SRC = 2U, ++ BCLK_EMMC_SEL_XIN_OSC0_FUNC = 3U, ++ CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX = 0U, ++ CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX = 1U, ++ CCLK_SRC_SDMMC0_SEL_XIN_OSC0_FUNC = 2U, ++ ++ /* CRU_CLKSEL_CON04 */ ++ CLK_UART0_SRC_DIV_SHIFT = 5, ++ CLK_UART0_SRC_DIV_MASK = 0x1F << CLK_UART0_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON05 */ ++ CLK_UART0_FRAC_DIV_SHIFT = 0, ++ CLK_UART0_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART0_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON06 */ ++ SCLK_UART0_SRC_SEL_SHIFT = 0, ++ SCLK_UART0_SRC_SEL_MASK = 0x3 << SCLK_UART0_SRC_SEL_SHIFT, ++ CLK_UART1_SRC_DIV_SHIFT = 2, ++ CLK_UART1_SRC_DIV_MASK = 0x1F << CLK_UART1_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON07 */ ++ CLK_UART1_FRAC_DIV_SHIFT = 0, ++ CLK_UART1_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART1_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON08 */ ++ SCLK_UART1_SRC_SEL_SHIFT = 0, ++ SCLK_UART1_SRC_SEL_MASK = 0x3 << SCLK_UART1_SRC_SEL_SHIFT, ++ CLK_UART2_SRC_DIV_SHIFT = 2, ++ CLK_UART2_SRC_DIV_MASK = 0x1F << CLK_UART2_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON09 */ ++ CLK_UART2_FRAC_DIV_SHIFT = 0, ++ CLK_UART2_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART2_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON10 */ ++ SCLK_UART2_SRC_SEL_SHIFT = 0, ++ SCLK_UART2_SRC_SEL_MASK = 0x3 << SCLK_UART2_SRC_SEL_SHIFT, ++ CLK_UART3_SRC_DIV_SHIFT = 2, ++ CLK_UART3_SRC_DIV_MASK = 0x1F << CLK_UART3_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON11 */ ++ CLK_UART3_FRAC_DIV_SHIFT = 0, ++ CLK_UART3_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART3_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON12 */ ++ SCLK_UART3_SRC_SEL_SHIFT = 0, ++ SCLK_UART3_SRC_SEL_MASK = 0x3 << SCLK_UART3_SRC_SEL_SHIFT, ++ CLK_UART4_SRC_DIV_SHIFT = 2, ++ CLK_UART4_SRC_DIV_MASK = 0x1F << CLK_UART4_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON13 */ ++ CLK_UART4_FRAC_DIV_SHIFT = 0, ++ CLK_UART4_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART4_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON14 */ ++ SCLK_UART4_SRC_SEL_SHIFT = 0, ++ SCLK_UART4_SRC_SEL_MASK = 0x3 << SCLK_UART4_SRC_SEL_SHIFT, ++ CLK_UART5_SRC_DIV_SHIFT = 2, ++ CLK_UART5_SRC_DIV_MASK = 0x1F << CLK_UART5_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON15 */ ++ CLK_UART5_FRAC_DIV_SHIFT = 0, ++ CLK_UART5_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART5_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON16 */ ++ SCLK_UART5_SRC_SEL_SHIFT = 0, ++ SCLK_UART5_SRC_SEL_MASK = 0x3 << SCLK_UART5_SRC_SEL_SHIFT, ++ CLK_UART6_SRC_DIV_SHIFT = 2, ++ CLK_UART6_SRC_DIV_MASK = 0x1F << CLK_UART6_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON17 */ ++ CLK_UART6_FRAC_DIV_SHIFT = 0, ++ CLK_UART6_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART6_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON18 */ ++ SCLK_UART6_SRC_SEL_SHIFT = 0, ++ SCLK_UART6_SRC_SEL_MASK = 0x3 << SCLK_UART6_SRC_SEL_SHIFT, ++ CLK_UART7_SRC_DIV_SHIFT = 2, ++ CLK_UART7_SRC_DIV_MASK = 0x1F << CLK_UART7_SRC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON19 */ ++ CLK_UART7_FRAC_DIV_SHIFT = 0, ++ CLK_UART7_FRAC_DIV_MASK = 0xFFFFFFFF << CLK_UART7_FRAC_DIV_SHIFT, ++ /* CRU_CLKSEL_CON20 */ ++ SCLK_UART7_SRC_SEL_SHIFT = 0, ++ SCLK_UART7_SRC_SEL_MASK = 0x3 << SCLK_UART7_SRC_SEL_SHIFT, ++ SCLK_UART0_SRC_SEL_CLK_UART0_SRC = 0U, ++ SCLK_UART0_SRC_SEL_CLK_UART0_FRAC = 1U, ++ SCLK_UART0_SRC_SEL_XIN_OSC0_FUNC = 2U, ++ ++ /* CRU_CLKSEL_CON60 */ ++ CLK_GMAC1_VPU_25M_DIV_SHIFT = 2, ++ CLK_GMAC1_VPU_25M_DIV_MASK = 0xFF << CLK_GMAC1_VPU_25M_DIV_SHIFT, ++ /* CRU_CLKSEL_CON66 */ ++ CLK_GMAC1_SRC_VPU_DIV_SHIFT = 0, ++ CLK_GMAC1_SRC_VPU_DIV_MASK = 0x3F << CLK_GMAC1_SRC_VPU_DIV_SHIFT, ++ /* CRU_CLKSEL_CON84 */ ++ CLK_GMAC0_SRC_DIV_SHIFT = 3, ++ CLK_GMAC0_SRC_DIV_MASK = 0x3F << CLK_GMAC0_SRC_DIV_SHIFT, ++}; ++ ++#endif /* _ASM_ARCH_CRU_RK3528_H */ +--- a/arch/arm/mach-rockchip/rk3528/Makefile ++++ b/arch/arm/mach-rockchip/rk3528/Makefile +@@ -1,4 +1,5 @@ + # SPDX-License-Identifier: GPL-2.0-or-later + + obj-y += rk3528.o ++obj-y += clk_rk3528.o + obj-y += syscon_rk3528.o +--- /dev/null ++++ b/arch/arm/mach-rockchip/rk3528/clk_rk3528.c +@@ -0,0 +1,16 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++// Copyright Contributors to the U-Boot project. ++ ++#include ++#include ++ ++int rockchip_get_clk(struct udevice **devp) ++{ ++ return uclass_get_device_by_driver(UCLASS_CLK, ++ DM_DRIVER_GET(rockchip_rk3528_cru), devp); ++} ++ ++void *rockchip_get_cru(void) ++{ ++ return RK3528_CRU_BASE; ++} +--- a/drivers/clk/rockchip/Makefile ++++ b/drivers/clk/rockchip/Makefile +@@ -15,6 +15,7 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += clk_rk3 + obj-$(CONFIG_ROCKCHIP_RK3328) += clk_rk3328.o + obj-$(CONFIG_ROCKCHIP_RK3368) += clk_rk3368.o + obj-$(CONFIG_ROCKCHIP_RK3399) += clk_rk3399.o ++obj-$(CONFIG_ROCKCHIP_RK3528) += clk_rk3528.o + obj-$(CONFIG_ROCKCHIP_RK3568) += clk_rk3568.o + obj-$(CONFIG_ROCKCHIP_RK3588) += clk_rk3588.o + obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o +--- a/drivers/clk/rockchip/clk_pll.c ++++ b/drivers/clk/rockchip/clk_pll.c +@@ -309,9 +309,11 @@ static int rk3036_pll_set_rate(struct ro + * When power on or changing PLL setting, + * we must force PLL into slow mode to ensure output stable clock. + */ +- rk_clrsetreg(base + pll->mode_offset, +- pll->mode_mask << pll->mode_shift, +- RKCLK_PLL_MODE_SLOW << pll->mode_shift); ++ if (!(pll->pll_flags & ROCKCHIP_PLL_FIXED_MODE)) { ++ rk_clrsetreg(base + pll->mode_offset, ++ pll->mode_mask << pll->mode_shift, ++ RKCLK_PLL_MODE_SLOW << pll->mode_shift); ++ } + + /* Power down */ + rk_setreg(base + pll->con_offset + 0x4, +@@ -345,8 +347,11 @@ static int rk3036_pll_set_rate(struct ro + while (!(readl(base + pll->con_offset + 0x4) & (1 << pll->lock_shift))) + udelay(1); + +- rk_clrsetreg(base + pll->mode_offset, pll->mode_mask << pll->mode_shift, +- RKCLK_PLL_MODE_NORMAL << pll->mode_shift); ++ if (!(pll->pll_flags & ROCKCHIP_PLL_FIXED_MODE)) { ++ rk_clrsetreg(base + pll->mode_offset, ++ pll->mode_mask << pll->mode_shift, ++ RKCLK_PLL_MODE_NORMAL << pll->mode_shift); ++ } + debug("PLL at %p: con0=%x con1= %x con2= %x mode= %x\n", + pll, readl(base + pll->con_offset), + readl(base + pll->con_offset + 0x4), +@@ -362,12 +367,18 @@ static ulong rk3036_pll_get_rate(struct + u32 refdiv, fbdiv, postdiv1, postdiv2, dsmpd, frac; + u32 con = 0, shift, mask; + ulong rate; ++ int mode; + + con = readl(base + pll->mode_offset); + shift = pll->mode_shift; + mask = pll->mode_mask << shift; + +- switch ((con & mask) >> shift) { ++ if (!(pll->pll_flags & ROCKCHIP_PLL_FIXED_MODE)) ++ mode = (con & mask) >> shift; ++ else ++ mode = RKCLK_PLL_MODE_NORMAL; ++ ++ switch (mode) { + case RKCLK_PLL_MODE_SLOW: + return OSC_HZ; + case RKCLK_PLL_MODE_NORMAL: +--- /dev/null ++++ b/drivers/clk/rockchip/clk_rk3528.c +@@ -0,0 +1,1744 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd. ++ * Author: Joseph Chen ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) ++ ++/* ++ * 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. ++ * ++ */ ++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 */ }, ++}; ++ ++static struct rockchip_pll_clock rk3528_pll_clks[] = { ++ [APLL] = PLL(pll_rk3328, PLL_APLL, RK3528_PLL_CON(0), ++ RK3528_MODE_CON, 0, 10, 0, rk3528_pll_rates), ++ ++ [CPLL] = PLL(pll_rk3328, PLL_CPLL, RK3528_PLL_CON(8), ++ RK3528_MODE_CON, 2, 10, 0, rk3528_pll_rates), ++ ++ [GPLL] = PLL(pll_rk3328, PLL_GPLL, RK3528_PLL_CON(24), ++ RK3528_MODE_CON, 4, 10, 0, rk3528_pll_rates), ++ ++ [PPLL] = PLL(pll_rk3328, PLL_PPLL, RK3528_PCIE_PLL_CON(32), ++ RK3528_MODE_CON, 6, 10, ROCKCHIP_PLL_FIXED_MODE, rk3528_pll_rates), ++ ++ [DPLL] = PLL(pll_rk3328, PLL_DPLL, RK3528_DDRPHY_PLL_CON(16), ++ RK3528_DDRPHY_MODE_CON, 0, 10, 0, rk3528_pll_rates), ++}; ++ ++#define RK3528_CPUCLK_RATE(_rate, _aclk_m_core, _pclk_dbg) \ ++{ \ ++ .rate = _rate##U, \ ++ .aclk_div = (_aclk_m_core), \ ++ .pclk_div = (_pclk_dbg), \ ++} ++ ++/* sign-off: _aclk_m_core: 550M, _pclk_dbg: 137.5M, */ ++static struct rockchip_cpu_rate_table rk3528_cpu_rates[] = { ++ 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), ++}; ++ ++/* ++ * ++ * rational_best_approximation(31415, 10000, ++ * (1 << 8) - 1, (1 << 5) - 1, &n, &d); ++ * ++ * you may look at given_numerator as a fixed point number, ++ * with the fractional part size described in given_denominator. ++ * ++ * for theoretical background, see: ++ * http://en.wikipedia.org/wiki/Continued_fraction ++ */ ++static void rational_best_approximation(unsigned long given_numerator, ++ unsigned long given_denominator, ++ unsigned long max_numerator, ++ unsigned long max_denominator, ++ unsigned long *best_numerator, ++ unsigned long *best_denominator) ++{ ++ unsigned long n, d, n0, d0, n1, d1; ++ ++ n = given_numerator; ++ d = given_denominator; ++ n0 = 0; ++ d1 = 0; ++ n1 = 1; ++ d0 = 1; ++ for (;;) { ++ unsigned long t, a; ++ ++ if (n1 > max_numerator || d1 > max_denominator) { ++ n1 = n0; ++ d1 = d0; ++ break; ++ } ++ if (d == 0) ++ break; ++ t = d; ++ a = n / d; ++ d = n % d; ++ n = t; ++ t = n0 + a * n1; ++ n0 = n1; ++ n1 = t; ++ t = d0 + a * d1; ++ d0 = d1; ++ d1 = t; ++ } ++ *best_numerator = n1; ++ *best_denominator = d1; ++} ++ ++static int rk3528_armclk_set_clk(struct rk3528_clk_priv *priv, ulong new_rate) ++{ ++ const struct rockchip_cpu_rate_table *rate; ++ struct rk3528_cru *cru = priv->cru; ++ ulong old_rate; ++ ++ rate = rockchip_get_cpu_settings(rk3528_cpu_rates, new_rate); ++ if (!rate) { ++ printf("%s unsupported rate\n", __func__); ++ return -EINVAL; ++ } ++ ++ /* ++ * set up dependent divisors for DBG and ACLK clocks. ++ */ ++ old_rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru, APLL); ++ if (old_rate > new_rate) { ++ if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL], ++ priv->cru, APLL, new_rate)) ++ return -EINVAL; ++ ++ rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK, ++ rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT); ++ ++ rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK, ++ rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT); ++ } else if (old_rate < new_rate) { ++ rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK, ++ rate->pclk_div << RK3528_DIV_PCLK_DBG_SHIFT); ++ ++ rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK, ++ rate->aclk_div << RK3528_DIV_ACLK_M_CORE_SHIFT); ++ ++ if (rockchip_pll_set_rate(&rk3528_pll_clks[APLL], ++ priv->cru, APLL, new_rate)) ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ ++static ulong rk3528_ppll_matrix_get_rate(struct rk3528_clk_priv *priv, ++ ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, mask, shift; ++ void *reg; ++ ++ switch (clk_id) { ++ case CLK_PPLL_50M_MATRIX: ++ case CLK_GMAC1_RMII_VPU: ++ mask = PCIE_CLK_MATRIX_50M_SRC_DIV_MASK; ++ shift = PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT; ++ reg = &cru->pcieclksel_con[1]; ++ break; ++ ++ case CLK_PPLL_100M_MATRIX: ++ mask = PCIE_CLK_MATRIX_100M_SRC_DIV_MASK; ++ shift = PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT; ++ reg = &cru->pcieclksel_con[1]; ++ break; ++ ++ case CLK_PPLL_125M_MATRIX: ++ case CLK_GMAC1_SRC_VPU: ++ mask = CLK_MATRIX_125M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_125M_SRC_DIV_SHIFT; ++ reg = &cru->clksel_con[60]; ++ break; ++ ++ case CLK_GMAC1_VPU_25M: ++ mask = CLK_MATRIX_25M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_25M_SRC_DIV_SHIFT; ++ reg = &cru->clksel_con[60]; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ div = (readl(reg) & mask) >> shift; ++ ++ return DIV_TO_RATE(priv->ppll_hz, div); ++} ++ ++static ulong rk3528_ppll_matrix_set_rate(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, div, mask, shift; ++ u8 is_pciecru = 0; ++ ++ switch (clk_id) { ++ case CLK_PPLL_50M_MATRIX: ++ id = 1; ++ mask = PCIE_CLK_MATRIX_50M_SRC_DIV_MASK; ++ shift = PCIE_CLK_MATRIX_50M_SRC_DIV_SHIFT; ++ is_pciecru = 1; ++ break; ++ ++ case CLK_PPLL_100M_MATRIX: ++ id = 1; ++ mask = PCIE_CLK_MATRIX_100M_SRC_DIV_MASK; ++ shift = PCIE_CLK_MATRIX_100M_SRC_DIV_SHIFT; ++ is_pciecru = 1; ++ break; ++ ++ case CLK_PPLL_125M_MATRIX: ++ id = 60; ++ mask = CLK_MATRIX_125M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_125M_SRC_DIV_SHIFT; ++ break; ++ case CLK_GMAC1_VPU_25M: ++ id = 60; ++ mask = CLK_MATRIX_25M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_25M_SRC_DIV_SHIFT; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ div = DIV_ROUND_UP(priv->ppll_hz, rate); ++ if (is_pciecru) ++ rk_clrsetreg(&cru->pcieclksel_con[id], mask, (div - 1) << shift); ++ else ++ rk_clrsetreg(&cru->clksel_con[id], mask, (div - 1) << shift); ++ ++ return rk3528_ppll_matrix_get_rate(priv, clk_id); ++} ++ ++static ulong rk3528_cgpll_matrix_get_rate(struct rk3528_clk_priv *priv, ++ ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 sel, div, mask, shift, con; ++ u32 sel_mask = 0, sel_shift; ++ u8 is_gpll_parent = 1; ++ u8 is_halfdiv = 0; ++ ulong prate; ++ ++ switch (clk_id) { ++ case CLK_MATRIX_50M_SRC: ++ con = 0; ++ mask = CLK_MATRIX_50M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_50M_SRC_DIV_SHIFT; ++ is_gpll_parent = 0; ++ break; ++ ++ case CLK_MATRIX_100M_SRC: ++ con = 0; ++ mask = CLK_MATRIX_100M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_100M_SRC_DIV_SHIFT; ++ is_gpll_parent = 0; ++ break; ++ ++ case CLK_MATRIX_150M_SRC: ++ con = 1; ++ mask = CLK_MATRIX_150M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_150M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_200M_SRC: ++ con = 1; ++ mask = CLK_MATRIX_200M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_200M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_250M_SRC: ++ con = 1; ++ mask = CLK_MATRIX_250M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_250M_SRC_DIV_SHIFT; ++ sel_mask = CLK_MATRIX_250M_SRC_SEL_MASK; ++ sel_shift = CLK_MATRIX_250M_SRC_SEL_SHIFT; ++ break; ++ ++ case CLK_MATRIX_300M_SRC: ++ con = 2; ++ mask = CLK_MATRIX_300M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_300M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_339M_SRC: ++ con = 2; ++ mask = CLK_MATRIX_339M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_339M_SRC_DIV_SHIFT; ++ is_halfdiv = 1; ++ break; ++ ++ case CLK_MATRIX_400M_SRC: ++ con = 2; ++ mask = CLK_MATRIX_400M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_400M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_500M_SRC: ++ con = 3; ++ mask = CLK_MATRIX_500M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_500M_SRC_DIV_SHIFT; ++ sel_mask = CLK_MATRIX_500M_SRC_SEL_MASK; ++ sel_shift = CLK_MATRIX_500M_SRC_SEL_SHIFT; ++ break; ++ ++ case CLK_MATRIX_600M_SRC: ++ con = 4; ++ mask = CLK_MATRIX_600M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_600M_SRC_DIV_SHIFT; ++ break; ++ ++ case ACLK_BUS_VOPGL_ROOT: ++ case ACLK_BUS_VOPGL_BIU: ++ con = 43; ++ mask = ACLK_BUS_VOPGL_ROOT_DIV_MASK; ++ shift = ACLK_BUS_VOPGL_ROOT_DIV_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ if (sel_mask) { ++ sel = (readl(&cru->clksel_con[con]) & sel_mask) >> sel_shift; ++ if (sel == CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX) // TODO ++ prate = priv->gpll_hz; ++ else ++ prate = priv->cpll_hz; ++ } else { ++ if (is_gpll_parent) ++ prate = priv->gpll_hz; ++ else ++ prate = priv->cpll_hz; ++ } ++ ++ div = (readl(&cru->clksel_con[con]) & mask) >> shift; ++ ++ /* NOTE: '-1' to balance the DIV_TO_RATE() 'div+1' */ ++ return is_halfdiv ? DIV_TO_RATE(prate * 2, (3 + 2 * div) - 1) : DIV_TO_RATE(prate, div); ++} ++ ++static ulong rk3528_cgpll_matrix_set_rate(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 sel, div, mask, shift, con; ++ u32 sel_mask = 0, sel_shift; ++ u8 is_gpll_parent = 1; ++ u8 is_halfdiv = 0; ++ ulong prate = 0; ++ ++ switch (clk_id) { ++ case CLK_MATRIX_50M_SRC: ++ con = 0; ++ mask = CLK_MATRIX_50M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_50M_SRC_DIV_SHIFT; ++ is_gpll_parent = 0; ++ break; ++ ++ case CLK_MATRIX_100M_SRC: ++ con = 0; ++ mask = CLK_MATRIX_100M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_100M_SRC_DIV_SHIFT; ++ is_gpll_parent = 0; ++ break; ++ ++ case CLK_MATRIX_150M_SRC: ++ con = 1; ++ mask = CLK_MATRIX_150M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_150M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_200M_SRC: ++ con = 1; ++ mask = CLK_MATRIX_200M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_200M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_250M_SRC: ++ con = 1; ++ mask = CLK_MATRIX_250M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_250M_SRC_DIV_SHIFT; ++ sel_mask = CLK_MATRIX_250M_SRC_SEL_MASK; ++ sel_shift = CLK_MATRIX_250M_SRC_SEL_SHIFT; ++ break; ++ ++ case CLK_MATRIX_300M_SRC: ++ con = 2; ++ mask = CLK_MATRIX_300M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_300M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_339M_SRC: ++ con = 2; ++ mask = CLK_MATRIX_339M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_339M_SRC_DIV_SHIFT; ++ is_halfdiv = 1; ++ break; ++ ++ case CLK_MATRIX_400M_SRC: ++ con = 2; ++ mask = CLK_MATRIX_400M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_400M_SRC_DIV_SHIFT; ++ break; ++ ++ case CLK_MATRIX_500M_SRC: ++ con = 3; ++ mask = CLK_MATRIX_500M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_500M_SRC_DIV_SHIFT; ++ sel_mask = CLK_MATRIX_500M_SRC_SEL_MASK; ++ sel_shift = CLK_MATRIX_500M_SRC_SEL_SHIFT; ++ break; ++ ++ case CLK_MATRIX_600M_SRC: ++ con = 4; ++ mask = CLK_MATRIX_600M_SRC_DIV_MASK; ++ shift = CLK_MATRIX_600M_SRC_DIV_SHIFT; ++ break; ++ ++ case ACLK_BUS_VOPGL_ROOT: ++ case ACLK_BUS_VOPGL_BIU: ++ con = 43; ++ mask = ACLK_BUS_VOPGL_ROOT_DIV_MASK; ++ shift = ACLK_BUS_VOPGL_ROOT_DIV_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ if (sel_mask) { ++ if (priv->gpll_hz % rate == 0) { ++ sel = CLK_MATRIX_250M_SRC_SEL_CLK_GPLL_MUX; // TODO ++ prate = priv->gpll_hz; ++ } else { ++ sel = CLK_MATRIX_250M_SRC_SEL_CLK_CPLL_MUX; ++ prate = priv->cpll_hz; ++ } ++ } else { ++ if (is_gpll_parent) ++ prate = priv->gpll_hz; ++ else ++ prate = priv->cpll_hz; ++ } ++ ++ if (is_halfdiv) ++ /* NOTE: '+1' to balance the following rk_clrsetreg() 'div-1' */ ++ div = DIV_ROUND_UP((prate * 2) - (3 * rate), 2 * rate) + 1; ++ else ++ div = DIV_ROUND_UP(prate, rate); ++ ++ rk_clrsetreg(&cru->clksel_con[con], mask, (div - 1) << shift); ++ if (sel_mask) ++ rk_clrsetreg(&cru->clksel_con[con], sel_mask, sel << sel_shift); ++ ++ return rk3528_cgpll_matrix_get_rate(priv, clk_id); ++} ++ ++static ulong rk3528_i2c_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, sel, con, mask, shift; ++ u8 is_pmucru = 0; ++ ulong rate; ++ ++ switch (clk_id) { ++ case CLK_I2C0: ++ id = 79; ++ mask = CLK_I2C0_SEL_MASK; ++ shift = CLK_I2C0_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C1: ++ id = 79; ++ mask = CLK_I2C1_SEL_MASK; ++ shift = CLK_I2C1_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C2: ++ id = 0; ++ mask = CLK_I2C2_SEL_MASK; ++ shift = CLK_I2C2_SEL_SHIFT; ++ is_pmucru = 1; ++ break; ++ ++ case CLK_I2C3: ++ id = 63; ++ mask = CLK_I2C3_SEL_MASK; ++ shift = CLK_I2C3_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C4: ++ id = 85; ++ mask = CLK_I2C4_SEL_MASK; ++ shift = CLK_I2C4_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C5: ++ id = 63; ++ mask = CLK_I2C5_SEL_MASK; ++ shift = CLK_I2C5_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C6: ++ id = 64; ++ mask = CLK_I2C6_SEL_MASK; ++ shift = CLK_I2C6_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C7: ++ id = 86; ++ mask = CLK_I2C7_SEL_MASK; ++ shift = CLK_I2C7_SEL_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ if (is_pmucru) ++ con = readl(&cru->pmuclksel_con[id]); ++ else ++ con = readl(&cru->clksel_con[id]); ++ sel = (con & mask) >> shift; ++ if (sel == CLK_I2C3_SEL_CLK_MATRIX_200M_SRC) ++ rate = 200 * MHz; ++ else if (sel == CLK_I2C3_SEL_CLK_MATRIX_100M_SRC) ++ rate = 100 * MHz; ++ else if (sel == CLK_I2C3_SEL_CLK_MATRIX_50M_SRC) ++ rate = 50 * MHz; ++ else ++ rate = OSC_HZ; ++ ++ return rate; ++} ++ ++static ulong rk3528_i2c_set_clk(struct rk3528_clk_priv *priv, ulong clk_id, ++ ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, sel, mask, shift; ++ u8 is_pmucru = 0; ++ ++ if (rate >= 198 * MHz) ++ sel = CLK_I2C3_SEL_CLK_MATRIX_200M_SRC; ++ else if (rate >= 99 * MHz) ++ sel = CLK_I2C3_SEL_CLK_MATRIX_100M_SRC; ++ else if (rate >= 50 * MHz) ++ sel = CLK_I2C3_SEL_CLK_MATRIX_50M_SRC; ++ else ++ sel = CLK_I2C3_SEL_XIN_OSC0_FUNC; ++ ++ switch (clk_id) { ++ case CLK_I2C0: ++ id = 79; ++ mask = CLK_I2C0_SEL_MASK; ++ shift = CLK_I2C0_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C1: ++ id = 79; ++ mask = CLK_I2C1_SEL_MASK; ++ shift = CLK_I2C1_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C2: ++ id = 0; ++ mask = CLK_I2C2_SEL_MASK; ++ shift = CLK_I2C2_SEL_SHIFT; ++ is_pmucru = 1; ++ break; ++ ++ case CLK_I2C3: ++ id = 63; ++ mask = CLK_I2C3_SEL_MASK; ++ shift = CLK_I2C3_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C4: ++ id = 85; ++ mask = CLK_I2C4_SEL_MASK; ++ shift = CLK_I2C4_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C5: ++ id = 63; ++ mask = CLK_I2C5_SEL_MASK; ++ shift = CLK_I2C5_SEL_SHIFT; ++ ++ case CLK_I2C6: ++ id = 64; ++ mask = CLK_I2C6_SEL_MASK; ++ shift = CLK_I2C6_SEL_SHIFT; ++ break; ++ ++ case CLK_I2C7: ++ id = 86; ++ mask = CLK_I2C7_SEL_MASK; ++ shift = CLK_I2C7_SEL_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ if (is_pmucru) ++ rk_clrsetreg(&cru->pmuclksel_con[id], mask, sel << shift); ++ else ++ rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); ++ ++ return rk3528_i2c_get_clk(priv, clk_id); ++} ++ ++static ulong rk3528_spi_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, sel, con, mask, shift; ++ ulong rate; ++ ++ switch (clk_id) { ++ case CLK_SPI0: ++ id = 79; ++ mask = CLK_SPI0_SEL_MASK; ++ shift = CLK_SPI0_SEL_SHIFT; ++ break; ++ ++ case CLK_SPI1: ++ id = 63; ++ mask = CLK_SPI1_SEL_MASK; ++ shift = CLK_SPI1_SEL_SHIFT; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ con = readl(&cru->clksel_con[id]); ++ sel = (con & mask) >> shift; ++ if (sel == CLK_SPI1_SEL_CLK_MATRIX_200M_SRC) ++ rate = 200 * MHz; ++ else if (sel == CLK_SPI1_SEL_CLK_MATRIX_100M_SRC) ++ rate = 100 * MHz; ++ else if (sel == CLK_SPI1_SEL_CLK_MATRIX_50M_SRC) ++ rate = 50 * MHz; ++ else ++ rate = OSC_HZ; ++ ++ return rate; ++} ++ ++static ulong rk3528_spi_set_clk(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, sel, mask, shift; ++ ++ if (rate >= 198 * MHz) ++ sel = CLK_SPI1_SEL_CLK_MATRIX_200M_SRC; ++ else if (rate >= 99 * MHz) ++ sel = CLK_SPI1_SEL_CLK_MATRIX_100M_SRC; ++ else if (rate >= 50 * MHz) ++ sel = CLK_SPI1_SEL_CLK_MATRIX_50M_SRC; ++ else ++ sel = CLK_SPI1_SEL_XIN_OSC0_FUNC; ++ ++ switch (clk_id) { ++ case CLK_SPI0: ++ id = 79; ++ mask = CLK_SPI0_SEL_MASK; ++ shift = CLK_SPI0_SEL_SHIFT; ++ break; ++ ++ case CLK_SPI1: ++ id = 63; ++ mask = CLK_SPI1_SEL_MASK; ++ shift = CLK_SPI1_SEL_SHIFT; ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); ++ ++ return rk3528_spi_get_clk(priv, clk_id); ++} ++ ++static ulong rk3528_pwm_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, sel, con, mask, shift; ++ ulong rate; ++ ++ switch (clk_id) { ++ case CLK_PWM0: ++ id = 44; ++ mask = CLK_PWM0_SEL_MASK; ++ shift = CLK_PWM0_SEL_SHIFT; ++ break; ++ ++ case CLK_PWM1: ++ id = 44; ++ mask = CLK_PWM1_SEL_MASK; ++ shift = CLK_PWM1_SEL_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ con = readl(&cru->clksel_con[id]); ++ sel = (con & mask) >> shift; ++ if (sel == CLK_PWM0_SEL_CLK_MATRIX_100M_SRC) ++ rate = 100 * MHz; ++ if (sel == CLK_PWM0_SEL_CLK_MATRIX_50M_SRC) ++ rate = 50 * MHz; ++ else ++ rate = OSC_HZ; ++ ++ return rate; ++} ++ ++static ulong rk3528_pwm_set_clk(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 id, sel, mask, shift; ++ ++ if (rate >= 99 * MHz) ++ sel = CLK_PWM0_SEL_CLK_MATRIX_100M_SRC; ++ else if (rate >= 50 * MHz) ++ sel = CLK_PWM0_SEL_CLK_MATRIX_50M_SRC; ++ else ++ sel = CLK_PWM0_SEL_XIN_OSC0_FUNC; ++ ++ switch (clk_id) { ++ case CLK_PWM0: ++ id = 44; ++ mask = CLK_PWM0_SEL_MASK; ++ shift = CLK_PWM0_SEL_SHIFT; ++ break; ++ ++ case CLK_PWM1: ++ id = 44; ++ mask = CLK_PWM1_SEL_MASK; ++ shift = CLK_PWM1_SEL_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ rk_clrsetreg(&cru->clksel_con[id], mask, sel << shift); ++ ++ return rk3528_pwm_get_clk(priv, clk_id); ++} ++ ++static ulong rk3528_adc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, con; ++ ++ con = readl(&cru->clksel_con[74]); ++ switch (clk_id) { ++ case CLK_SARADC: ++ div = (con & CLK_SARADC_DIV_MASK) >> ++ CLK_SARADC_DIV_SHIFT; ++ break; ++ ++ case CLK_TSADC_TSEN: ++ div = (con & CLK_TSADC_TSEN_DIV_MASK) >> ++ CLK_TSADC_TSEN_DIV_SHIFT; ++ break; ++ ++ case CLK_TSADC: ++ div = (con & CLK_TSADC_DIV_MASK) >> ++ CLK_TSADC_DIV_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ return DIV_TO_RATE(OSC_HZ, div); ++} ++ ++static ulong rk3528_adc_set_clk(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, mask, shift; ++ ++ switch (clk_id) { ++ case CLK_SARADC: ++ mask = CLK_SARADC_DIV_MASK; ++ shift = CLK_SARADC_DIV_SHIFT; ++ break; ++ ++ case CLK_TSADC_TSEN: ++ mask = CLK_TSADC_TSEN_DIV_MASK; ++ shift = CLK_TSADC_TSEN_DIV_SHIFT; ++ break; ++ ++ case CLK_TSADC: ++ mask = CLK_TSADC_DIV_MASK; ++ shift = CLK_TSADC_DIV_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ div = DIV_ROUND_UP(OSC_HZ, rate); ++ rk_clrsetreg(&cru->clksel_con[74], mask, (div - 1) << shift); ++ ++ return rk3528_adc_get_clk(priv, clk_id); ++} ++ ++static ulong rk3528_sdmmc_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, sel, con; ++ ulong prate; ++ ++ con = readl(&cru->clksel_con[85]); ++ div = (con & CCLK_SRC_SDMMC0_DIV_MASK) >> ++ CCLK_SRC_SDMMC0_DIV_SHIFT; ++ sel = (con & CCLK_SRC_SDMMC0_SEL_MASK) >> ++ CCLK_SRC_SDMMC0_SEL_SHIFT; ++ ++ if (sel == CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX) ++ prate = priv->gpll_hz; ++ else if (sel == CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX) ++ prate = priv->cpll_hz; ++ else ++ prate = OSC_HZ; ++ ++ return DIV_TO_RATE(prate, div); ++} ++ ++static ulong rk3528_sdmmc_set_clk(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, sel; ++ ++ if (OSC_HZ % rate == 0) { ++ div = DIV_ROUND_UP(OSC_HZ, rate); ++ sel = CCLK_SRC_SDMMC0_SEL_XIN_OSC0_FUNC; ++ } else if ((priv->cpll_hz % rate) == 0) { ++ div = DIV_ROUND_UP(priv->cpll_hz, rate); ++ sel = CCLK_SRC_SDMMC0_SEL_CLK_CPLL_MUX; ++ } else { ++ div = DIV_ROUND_UP(priv->gpll_hz, rate); ++ sel = CCLK_SRC_SDMMC0_SEL_CLK_GPLL_MUX; ++ } ++ ++ assert(div - 1 <= 63); ++ rk_clrsetreg(&cru->clksel_con[85], ++ CCLK_SRC_SDMMC0_SEL_MASK | ++ CCLK_SRC_SDMMC0_DIV_MASK, ++ sel << CCLK_SRC_SDMMC0_SEL_SHIFT | ++ (div - 1) << CCLK_SRC_SDMMC0_DIV_SHIFT); ++ ++ return rk3528_sdmmc_get_clk(priv, clk_id); ++} ++ ++static ulong rk3528_sfc_get_clk(struct rk3528_clk_priv *priv) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, sel, con, parent; ++ ++ con = readl(&cru->clksel_con[61]); ++ div = (con & SCLK_SFC_DIV_MASK) >> ++ SCLK_SFC_DIV_SHIFT; ++ sel = (con & SCLK_SFC_SEL_MASK) >> ++ SCLK_SFC_SEL_SHIFT; ++ if (sel == SCLK_SFC_SEL_CLK_GPLL_MUX) ++ parent = priv->gpll_hz; ++ else if (sel == SCLK_SFC_SEL_CLK_CPLL_MUX) ++ parent = priv->cpll_hz; ++ else ++ parent = OSC_HZ; ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong rk3528_sfc_set_clk(struct rk3528_clk_priv *priv, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ int div, sel; ++ ++ if (OSC_HZ % rate == 0) { ++ div = DIV_ROUND_UP(OSC_HZ, rate); ++ sel = SCLK_SFC_SEL_XIN_OSC0_FUNC; ++ } else if ((priv->cpll_hz % rate) == 0) { ++ div = DIV_ROUND_UP(priv->cpll_hz, rate); ++ sel = SCLK_SFC_SEL_CLK_CPLL_MUX; ++ } else { ++ div = DIV_ROUND_UP(priv->gpll_hz, rate); ++ sel = SCLK_SFC_SEL_CLK_GPLL_MUX; ++ } ++ ++ assert(div - 1 <= 63); ++ rk_clrsetreg(&cru->clksel_con[61], ++ SCLK_SFC_SEL_MASK | ++ SCLK_SFC_DIV_MASK, ++ sel << SCLK_SFC_SEL_SHIFT | ++ (div - 1) << SCLK_SFC_DIV_SHIFT); ++ ++ return rk3528_sfc_get_clk(priv); ++} ++ ++static ulong rk3528_emmc_get_clk(struct rk3528_clk_priv *priv) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, sel, con, parent; ++ ++ con = readl(&cru->clksel_con[62]); ++ div = (con & CCLK_SRC_EMMC_DIV_MASK) >> ++ CCLK_SRC_EMMC_DIV_SHIFT; ++ sel = (con & CCLK_SRC_EMMC_SEL_MASK) >> ++ CCLK_SRC_EMMC_SEL_SHIFT; ++ ++ if (sel == CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX) ++ parent = priv->gpll_hz; ++ else if (sel == CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX) ++ parent = priv->cpll_hz; ++ else ++ parent = OSC_HZ; ++ ++ return DIV_TO_RATE(parent, div); ++} ++ ++static ulong rk3528_emmc_set_clk(struct rk3528_clk_priv *priv, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div, sel; ++ ++ if (OSC_HZ % rate == 0) { ++ div = DIV_ROUND_UP(OSC_HZ, rate); ++ sel = CCLK_SRC_EMMC_SEL_XIN_OSC0_FUNC; ++ } else if ((priv->cpll_hz % rate) == 0) { ++ div = DIV_ROUND_UP(priv->cpll_hz, rate); ++ sel = CCLK_SRC_EMMC_SEL_CLK_CPLL_MUX; ++ } else { ++ div = DIV_ROUND_UP(priv->gpll_hz, rate); ++ sel = CCLK_SRC_EMMC_SEL_CLK_GPLL_MUX; ++ } ++ ++ assert(div - 1 <= 63); ++ rk_clrsetreg(&cru->clksel_con[62], ++ CCLK_SRC_EMMC_SEL_MASK | ++ CCLK_SRC_EMMC_DIV_MASK, ++ sel << CCLK_SRC_EMMC_SEL_SHIFT | ++ (div - 1) << CCLK_SRC_EMMC_DIV_SHIFT); ++ ++ return rk3528_emmc_get_clk(priv); ++} ++ ++static ulong rk3528_dclk_vop_get_clk(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div_mask, div_shift; ++ u32 sel_mask, sel_shift; ++ u32 id, con, sel, div; ++ ulong prate; ++ ++ switch (clk_id) { ++ case DCLK_VOP0: ++ id = 32; ++ sel_mask = DCLK_VOP_SRC0_SEL_MASK; ++ sel_shift = DCLK_VOP_SRC0_SEL_SHIFT; ++ /* FIXME if need src: clk_hdmiphy_pixel_io */ ++ div_mask = DCLK_VOP_SRC0_DIV_MASK; ++ div_shift = DCLK_VOP_SRC0_DIV_SHIFT; ++ break; ++ ++ case DCLK_VOP1: ++ id = 33; ++ sel_mask = DCLK_VOP_SRC1_SEL_MASK; ++ sel_shift = DCLK_VOP_SRC1_SEL_SHIFT; ++ div_mask = DCLK_VOP_SRC1_DIV_MASK; ++ div_shift = DCLK_VOP_SRC1_DIV_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ con = readl(&cru->clksel_con[id]); ++ div = (con & div_mask) >> div_shift; ++ sel = (con & sel_mask) >> sel_shift; ++ if (sel == DCLK_VOP_SRC_SEL_CLK_GPLL_MUX) ++ prate = priv->gpll_hz; ++ else ++ prate = priv->cpll_hz; ++ ++ return DIV_TO_RATE(prate, div); ++} ++ ++static ulong rk3528_dclk_vop_set_clk(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 div_mask, div_shift; ++ u32 sel_mask, sel_shift; ++ u32 id, sel, div; ++ ulong prate; ++ ++ switch (clk_id) { ++ case DCLK_VOP0: ++ id = 32; ++ sel_mask = DCLK_VOP_SRC0_SEL_MASK; ++ sel_shift = DCLK_VOP_SRC0_SEL_SHIFT; ++ /* FIXME if need src: clk_hdmiphy_pixel_io */ ++ div_mask = DCLK_VOP_SRC0_DIV_MASK; ++ div_shift = DCLK_VOP_SRC0_DIV_SHIFT; ++ break; ++ ++ case DCLK_VOP1: ++ id = 33; ++ sel_mask = DCLK_VOP_SRC1_SEL_MASK; ++ sel_shift = DCLK_VOP_SRC1_SEL_SHIFT; ++ div_mask = DCLK_VOP_SRC1_DIV_MASK; ++ div_shift = DCLK_VOP_SRC1_DIV_SHIFT; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ if ((priv->gpll_hz % rate) == 0) { ++ prate = priv->gpll_hz; ++ sel = (DCLK_VOP_SRC_SEL_CLK_GPLL_MUX << sel_shift) & sel_mask; ++ } else { ++ prate = priv->cpll_hz; ++ sel = (DCLK_VOP_SRC_SEL_CLK_CPLL_MUX << sel_shift) & sel_mask; ++ } ++ ++ div = ((DIV_ROUND_UP(prate, rate) - 1) << div_shift) & div_mask; ++ rk_clrsetreg(&cru->clksel_con[id], sel, div); ++ ++ return rk3528_dclk_vop_get_clk(priv, clk_id); ++} ++ ++static ulong rk3528_uart_get_rate(struct rk3528_clk_priv *priv, ulong clk_id) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 sel_shift, sel_mask, div_shift, div_mask; ++ u32 sel, id, con, frac_div, div; ++ ulong m, n, rate; ++ ++ switch (clk_id) { ++ case SCLK_UART0: ++ id = 6; ++ sel_shift = SCLK_UART0_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART0_SRC_SEL_MASK; ++ div_shift = CLK_UART0_SRC_DIV_SHIFT; ++ div_mask = CLK_UART0_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART1: ++ id = 8; ++ sel_shift = SCLK_UART1_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART1_SRC_SEL_MASK; ++ div_shift = CLK_UART1_SRC_DIV_SHIFT; ++ div_mask = CLK_UART1_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART2: ++ id = 10; ++ sel_shift = SCLK_UART2_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART2_SRC_SEL_MASK; ++ div_shift = CLK_UART2_SRC_DIV_SHIFT; ++ div_mask = CLK_UART2_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART3: ++ id = 12; ++ sel_shift = SCLK_UART3_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART3_SRC_SEL_MASK; ++ div_shift = CLK_UART3_SRC_DIV_SHIFT; ++ div_mask = CLK_UART3_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART4: ++ id = 14; ++ sel_shift = SCLK_UART4_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART4_SRC_SEL_MASK; ++ div_shift = CLK_UART4_SRC_DIV_SHIFT; ++ div_mask = CLK_UART4_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART5: ++ id = 16; ++ sel_shift = SCLK_UART5_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART5_SRC_SEL_MASK; ++ div_shift = CLK_UART5_SRC_DIV_SHIFT; ++ div_mask = CLK_UART5_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART6: ++ id = 18; ++ sel_shift = SCLK_UART6_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART6_SRC_SEL_MASK; ++ div_shift = CLK_UART6_SRC_DIV_SHIFT; ++ div_mask = CLK_UART6_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART7: ++ id = 20; ++ sel_shift = SCLK_UART7_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART7_SRC_SEL_MASK; ++ div_shift = CLK_UART7_SRC_DIV_SHIFT; ++ div_mask = CLK_UART7_SRC_DIV_MASK; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ con = readl(&cru->clksel_con[id - 2]); ++ div = (con & div_mask) >> div_shift; ++ ++ con = readl(&cru->clksel_con[id]); ++ sel = (con & sel_mask) >> sel_shift; ++ ++ if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_SRC) { ++ rate = DIV_TO_RATE(priv->gpll_hz, div); ++ } else if (sel == SCLK_UART0_SRC_SEL_CLK_UART0_FRAC) { ++ frac_div = readl(&cru->clksel_con[id - 1]); ++ n = (frac_div & 0xffff0000) >> 16; ++ m = frac_div & 0x0000ffff; ++ rate = DIV_TO_RATE(priv->gpll_hz, div) * n / m; ++ } else { ++ rate = OSC_HZ; ++ } ++ ++ return rate; ++} ++ ++static ulong rk3528_uart_set_rate(struct rk3528_clk_priv *priv, ++ ulong clk_id, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 sel_shift, sel_mask, div_shift, div_mask; ++ u32 sel, id, div; ++ ulong m = 0, n = 0, val; ++ ++ if (rate == OSC_HZ) { ++ sel = SCLK_UART0_SRC_SEL_XIN_OSC0_FUNC; ++ div = DIV_ROUND_UP(OSC_HZ, rate); ++ } else if (priv->gpll_hz % rate == 0) { ++ sel = SCLK_UART0_SRC_SEL_CLK_UART0_SRC; ++ div = DIV_ROUND_UP(priv->gpll_hz, rate); ++ } else { ++ sel = SCLK_UART0_SRC_SEL_CLK_UART0_FRAC; ++ div = 2; ++ rational_best_approximation(rate, priv->gpll_hz / div, ++ GENMASK(16 - 1, 0), ++ GENMASK(16 - 1, 0), ++ &n, &m); ++ } ++ ++ switch (clk_id) { ++ case SCLK_UART0: ++ id = 6; ++ sel_shift = SCLK_UART0_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART0_SRC_SEL_MASK; ++ div_shift = CLK_UART0_SRC_DIV_SHIFT; ++ div_mask = CLK_UART0_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART1: ++ id = 8; ++ sel_shift = SCLK_UART1_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART1_SRC_SEL_MASK; ++ div_shift = CLK_UART1_SRC_DIV_SHIFT; ++ div_mask = CLK_UART1_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART2: ++ id = 10; ++ sel_shift = SCLK_UART2_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART2_SRC_SEL_MASK; ++ div_shift = CLK_UART2_SRC_DIV_SHIFT; ++ div_mask = CLK_UART2_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART3: ++ id = 12; ++ sel_shift = SCLK_UART3_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART3_SRC_SEL_MASK; ++ div_shift = CLK_UART3_SRC_DIV_SHIFT; ++ div_mask = CLK_UART3_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART4: ++ id = 14; ++ sel_shift = SCLK_UART4_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART4_SRC_SEL_MASK; ++ div_shift = CLK_UART4_SRC_DIV_SHIFT; ++ div_mask = CLK_UART4_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART5: ++ id = 16; ++ sel_shift = SCLK_UART5_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART5_SRC_SEL_MASK; ++ div_shift = CLK_UART5_SRC_DIV_SHIFT; ++ div_mask = CLK_UART5_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART6: ++ id = 18; ++ sel_shift = SCLK_UART6_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART6_SRC_SEL_MASK; ++ div_shift = CLK_UART6_SRC_DIV_SHIFT; ++ div_mask = CLK_UART6_SRC_DIV_MASK; ++ break; ++ ++ case SCLK_UART7: ++ id = 20; ++ sel_shift = SCLK_UART7_SRC_SEL_SHIFT; ++ sel_mask = SCLK_UART7_SRC_SEL_MASK; ++ div_shift = CLK_UART7_SRC_DIV_SHIFT; ++ div_mask = CLK_UART7_SRC_DIV_MASK; ++ break; ++ ++ default: ++ return -ENOENT; ++ } ++ ++ rk_clrsetreg(&cru->clksel_con[id - 2], div_mask, (div - 1) << div_shift); ++ rk_clrsetreg(&cru->clksel_con[id], sel_mask, sel << sel_shift); ++ if (m && n) { ++ val = n << 16 | m; ++ writel(val, &cru->clksel_con[id - 1]); ++ } ++ ++ return rk3528_uart_get_rate(priv, clk_id); ++} ++ ++static ulong rk3528_clk_get_rate(struct clk *clk) ++{ ++ struct rk3528_clk_priv *priv = dev_get_priv(clk->dev); ++ ulong rate = 0; ++ ++ if (!priv->gpll_hz || !priv->cpll_hz) { ++ printf("%s: gpll=%lu, cpll=%ld\n", ++ __func__, priv->gpll_hz, priv->cpll_hz); ++ return -ENOENT; ++ } ++ ++ switch (clk->id) { ++ case PLL_APLL: ++ case ARMCLK: ++ rate = rockchip_pll_get_rate(&rk3528_pll_clks[APLL], priv->cru, ++ APLL); ++ break; ++ case PLL_CPLL: ++ rate = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL], priv->cru, ++ CPLL); ++ break; ++ case PLL_GPLL: ++ rate = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL], priv->cru, ++ GPLL); ++ break; ++ ++ case PLL_PPLL: ++ rate = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL], priv->cru, ++ PPLL); ++ break; ++ case PLL_DPLL: ++ rate = rockchip_pll_get_rate(&rk3528_pll_clks[DPLL], priv->cru, ++ DPLL); ++ break; ++ ++ case TCLK_WDT_NS: ++ rate = OSC_HZ; ++ break; ++ case CLK_I2C0: ++ case CLK_I2C1: ++ case CLK_I2C2: ++ case CLK_I2C3: ++ case CLK_I2C4: ++ case CLK_I2C5: ++ case CLK_I2C6: ++ case CLK_I2C7: ++ rate = rk3528_i2c_get_clk(priv, clk->id); ++ break; ++ case CLK_SPI0: ++ case CLK_SPI1: ++ rate = rk3528_spi_get_clk(priv, clk->id); ++ break; ++ case CLK_PWM0: ++ case CLK_PWM1: ++ rate = rk3528_pwm_get_clk(priv, clk->id); ++ break; ++ case CLK_SARADC: ++ case CLK_TSADC: ++ case CLK_TSADC_TSEN: ++ rate = rk3528_adc_get_clk(priv, clk->id); ++ break; ++ case CCLK_SRC_EMMC: ++ rate = rk3528_emmc_get_clk(priv); ++ break; ++ case HCLK_SDMMC0: ++ case CCLK_SRC_SDMMC0: ++ rate = rk3528_sdmmc_get_clk(priv, clk->id); ++ break; ++ case SCLK_SFC: ++ rate = rk3528_sfc_get_clk(priv); ++ break; ++ case DCLK_VOP0: ++ case DCLK_VOP1: ++ rate = rk3528_dclk_vop_get_clk(priv, clk->id); ++ break; ++ case DCLK_CVBS: ++ rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1) / 4; ++ break; ++ case DCLK_4X_CVBS: ++ rate = rk3528_dclk_vop_get_clk(priv, DCLK_VOP1); ++ break; ++ case SCLK_UART0: ++ case SCLK_UART1: ++ case SCLK_UART2: ++ case SCLK_UART3: ++ case SCLK_UART4: ++ case SCLK_UART5: ++ case SCLK_UART6: ++ case SCLK_UART7: ++ rate = rk3528_uart_get_rate(priv, clk->id); ++ break; ++ case CLK_MATRIX_50M_SRC: ++ case CLK_MATRIX_100M_SRC: ++ case CLK_MATRIX_150M_SRC: ++ case CLK_MATRIX_200M_SRC: ++ case CLK_MATRIX_250M_SRC: ++ case CLK_MATRIX_300M_SRC: ++ case CLK_MATRIX_339M_SRC: ++ case CLK_MATRIX_400M_SRC: ++ case CLK_MATRIX_500M_SRC: ++ case CLK_MATRIX_600M_SRC: ++ case ACLK_BUS_VOPGL_BIU: ++ rate = rk3528_cgpll_matrix_get_rate(priv, clk->id); ++ break; ++ case CLK_PPLL_50M_MATRIX: ++ case CLK_PPLL_100M_MATRIX: ++ case CLK_PPLL_125M_MATRIX: ++ case CLK_GMAC1_VPU_25M: ++ case CLK_GMAC1_RMII_VPU: ++ case CLK_GMAC1_SRC_VPU: ++ rate = rk3528_ppll_matrix_get_rate(priv, clk->id); ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return rate; ++}; ++ ++static ulong rk3528_clk_set_rate(struct clk *clk, ulong rate) ++{ ++ struct rk3528_clk_priv *priv = dev_get_priv(clk->dev); ++ ulong ret = 0; ++ ++ if (!priv->gpll_hz) { ++ printf("%s gpll=%lu\n", __func__, priv->gpll_hz); ++ return -ENOENT; ++ } ++ ++ switch (clk->id) { ++ case PLL_APLL: ++ case ARMCLK: ++ if (priv->armclk_hz) ++ rk3528_armclk_set_clk(priv, rate); ++ priv->armclk_hz = rate; ++ break; ++ case PLL_CPLL: ++ ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru, ++ CPLL, rate); ++ priv->cpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[CPLL], ++ priv->cru, CPLL); ++ break; ++ case PLL_GPLL: ++ ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru, ++ GPLL, rate); ++ priv->gpll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[GPLL], ++ priv->cru, GPLL); ++ break; ++ case PLL_PPLL: ++ ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru, ++ PPLL, rate); ++ priv->ppll_hz = rockchip_pll_get_rate(&rk3528_pll_clks[PPLL], ++ priv->cru, PPLL); ++ break; ++ case TCLK_WDT_NS: ++ return (rate == OSC_HZ) ? 0 : -EINVAL; ++ case CLK_I2C0: ++ case CLK_I2C1: ++ case CLK_I2C2: ++ case CLK_I2C3: ++ case CLK_I2C4: ++ case CLK_I2C5: ++ case CLK_I2C6: ++ case CLK_I2C7: ++ ret = rk3528_i2c_set_clk(priv, clk->id, rate); ++ break; ++ case CLK_SPI0: ++ case CLK_SPI1: ++ ret = rk3528_spi_set_clk(priv, clk->id, rate); ++ break; ++ case CLK_PWM0: ++ case CLK_PWM1: ++ ret = rk3528_pwm_set_clk(priv, clk->id, rate); ++ break; ++ case CLK_SARADC: ++ case CLK_TSADC: ++ case CLK_TSADC_TSEN: ++ ret = rk3528_adc_set_clk(priv, clk->id, rate); ++ break; ++ case HCLK_SDMMC0: ++ case CCLK_SRC_SDMMC0: ++ ret = rk3528_sdmmc_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_SFC: ++ ret = rk3528_sfc_set_clk(priv, rate); ++ break; ++ case CCLK_SRC_EMMC: ++ ret = rk3528_emmc_set_clk(priv, rate); ++ break; ++ case DCLK_VOP0: ++ case DCLK_VOP1: ++ ret = rk3528_dclk_vop_set_clk(priv, clk->id, rate); ++ break; ++ case SCLK_UART0: ++ case SCLK_UART1: ++ case SCLK_UART2: ++ case SCLK_UART3: ++ case SCLK_UART4: ++ case SCLK_UART5: ++ case SCLK_UART6: ++ case SCLK_UART7: ++ ret = rk3528_uart_set_rate(priv, clk->id, rate); ++ break; ++ case CLK_MATRIX_50M_SRC: ++ case CLK_MATRIX_100M_SRC: ++ case CLK_MATRIX_150M_SRC: ++ case CLK_MATRIX_200M_SRC: ++ case CLK_MATRIX_250M_SRC: ++ case CLK_MATRIX_300M_SRC: ++ case CLK_MATRIX_339M_SRC: ++ case CLK_MATRIX_400M_SRC: ++ case CLK_MATRIX_500M_SRC: ++ case CLK_MATRIX_600M_SRC: ++ case ACLK_BUS_VOPGL_BIU: ++ ret = rk3528_cgpll_matrix_set_rate(priv, clk->id, rate); ++ break; ++ case CLK_PPLL_50M_MATRIX: ++ case CLK_PPLL_100M_MATRIX: ++ case CLK_PPLL_125M_MATRIX: ++ case CLK_GMAC1_VPU_25M: ++ ret = rk3528_ppll_matrix_set_rate(priv, clk->id, rate); ++ break; ++ case CLK_GMAC1_RMII_VPU: ++ case CLK_GMAC1_SRC_VPU: ++ /* dummy set */ ++ ret = rk3528_ppll_matrix_get_rate(priv, clk->id); ++ break; ++ default: ++ return -ENOENT; ++ } ++ ++ return ret; ++}; ++ ++static struct clk_ops rk3528_clk_ops = { ++ .get_rate = rk3528_clk_get_rate, ++ .set_rate = rk3528_clk_set_rate, ++}; ++ ++#ifdef CONFIG_XPL_BUILD ++ ++#define COREGRF_BASE 0xff300000 ++#define PVTPLL_CON0_L 0x0 ++#define PVTPLL_CON0_H 0x4 ++ ++static int rk3528_cpu_pvtpll_set_rate(struct rk3528_clk_priv *priv, ulong rate) ++{ ++ struct rk3528_cru *cru = priv->cru; ++ u32 length; ++ ++ if (rate >= 1200000000) ++ length = 8; ++ else if (rate >= 1008000000) ++ length = 11; ++ else ++ length = 17; ++ ++ /* set pclk dbg div to 9 */ ++ rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK, ++ 9 << RK3528_DIV_PCLK_DBG_SHIFT); ++ /* set aclk_m_core div to 1 */ ++ rk_clrsetreg(&cru->clksel_con[39], RK3528_DIV_ACLK_M_CORE_MASK, ++ 1 << RK3528_DIV_ACLK_M_CORE_SHIFT); ++ ++ /* set ring sel = 1 */ ++ writel(0x07000000 | (1 << 8), COREGRF_BASE + PVTPLL_CON0_L); ++ /* set length */ ++ writel(0x007f0000 | length, COREGRF_BASE + PVTPLL_CON0_H); ++ /* enable pvtpll */ ++ writel(0x00020002, COREGRF_BASE + PVTPLL_CON0_L); ++ /* start monitor */ ++ writel(0x00010001, COREGRF_BASE + PVTPLL_CON0_L); ++ ++ /* set core mux pvtpll */ ++ writel(0x00010001, &cru->clksel_con[40]); ++ writel(0x00100010, &cru->clksel_con[39]); ++ ++ /* set pclk dbg div to 8 */ ++ rk_clrsetreg(&cru->clksel_con[40], RK3528_DIV_PCLK_DBG_MASK, ++ 8 << RK3528_DIV_PCLK_DBG_SHIFT); ++ ++ return 0; ++} ++#endif ++ ++static int rk3528_clk_init(struct rk3528_clk_priv *priv) ++{ ++ int ret; ++ ++ priv->sync_kernel = false; ++ ++#ifdef CONFIG_XPL_BUILD ++ /* ++ * BOOTROM: ++ * CPU 1902/2(postdiv1)=546M ++ * CPLL 996/2(postdiv1)=498M ++ * GPLL 1188/2(postdiv1)=594M ++ * |-- clk_matrix_200m_src_div=1 => rate: 300M ++ * |-- clk_matrix_300m_src_div=2 => rate: 200M ++ * ++ * Avoid overclocking when change GPLL rate: ++ * Change clk_matrix_200m_src_div to 5. ++ * Change clk_matrix_300m_src_div to 3. ++ */ ++ writel(0x01200120, &priv->cru->clksel_con[1]); ++ writel(0x00030003, &priv->cru->clksel_con[2]); ++ ++ if (!priv->armclk_enter_hz) { ++ priv->armclk_enter_hz = ++ rockchip_pll_get_rate(&rk3528_pll_clks[APLL], ++ priv->cru, APLL); ++ priv->armclk_init_hz = priv->armclk_enter_hz; ++ } ++ ++ if (priv->armclk_init_hz != APLL_HZ) { ++ ret = rk3528_armclk_set_clk(priv, APLL_HZ); ++ if (!ret) ++ priv->armclk_init_hz = APLL_HZ; ++ } ++ ++ if (!rk3528_cpu_pvtpll_set_rate(priv, CPU_PVTPLL_HZ)) { ++ debug("cpu pvtpll %d KHz\n", CPU_PVTPLL_HZ / 1000); ++ priv->armclk_init_hz = CPU_PVTPLL_HZ; ++ } ++#endif ++ ++ if (priv->cpll_hz != CPLL_HZ) { ++ ret = rockchip_pll_set_rate(&rk3528_pll_clks[CPLL], priv->cru, ++ CPLL, CPLL_HZ); ++ if (!ret) ++ priv->cpll_hz = CPLL_HZ; ++ } ++ ++ if (priv->gpll_hz != GPLL_HZ) { ++ ret = rockchip_pll_set_rate(&rk3528_pll_clks[GPLL], priv->cru, ++ GPLL, GPLL_HZ); ++ if (!ret) ++ priv->gpll_hz = GPLL_HZ; ++ } ++ ++ if (priv->ppll_hz != PPLL_HZ) { ++ ret = rockchip_pll_set_rate(&rk3528_pll_clks[PPLL], priv->cru, ++ PPLL, PPLL_HZ); ++ if (!ret) ++ priv->ppll_hz = PPLL_HZ; ++ } ++ ++#ifdef CONFIG_XPL_BUILD ++ /* Init to override bootrom config */ ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_50M_SRC, 50000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_100M_SRC, 100000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_150M_SRC, 150000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_200M_SRC, 200000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_250M_SRC, 250000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_300M_SRC, 300000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_339M_SRC, 340000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_400M_SRC, 400000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_500M_SRC, 500000000); ++ rk3528_cgpll_matrix_set_rate(priv, CLK_MATRIX_600M_SRC, 600000000); ++ rk3528_cgpll_matrix_set_rate(priv, ACLK_BUS_VOPGL_BIU, 500000000); ++ ++ /* The default rate is 100Mhz, it's not friendly for remote IR module */ ++ rk3528_pwm_set_clk(priv, CLK_PWM0, 24000000); ++ rk3528_pwm_set_clk(priv, CLK_PWM1, 24000000); ++#endif ++ return 0; ++} ++ ++static int rk3528_clk_probe(struct udevice *dev) ++{ ++ struct rk3528_clk_priv *priv = dev_get_priv(dev); ++ int ret; ++ ++ ret = rk3528_clk_init(priv); ++ if (ret) ++ return ret; ++ ++ /* Process 'assigned-{clocks/clock-parents/clock-rates}' properties */ ++ ret = clk_set_defaults(dev, 1); ++ if (ret) ++ debug("%s clk_set_defaults failed %d\n", __func__, ret); ++ else ++ priv->sync_kernel = true; ++ ++ return 0; ++} ++ ++static int rk3528_clk_ofdata_to_platdata(struct udevice *dev) ++{ ++ struct rk3528_clk_priv *priv = dev_get_priv(dev); ++ ++ priv->cru = dev_read_addr_ptr(dev); ++ ++ return 0; ++} ++ ++static int rk3528_clk_bind(struct udevice *dev) ++{ ++ struct udevice *sys_child; ++ struct sysreset_reg *priv; ++ int ret; ++ ++ /* The reset driver does not have a device node, so bind it here */ ++ ret = device_bind_driver(dev, "rockchip_sysreset", "sysreset", ++ &sys_child); ++ if (ret) { ++ debug("Warning: No sysreset driver: ret=%d\n", ret); ++ } else { ++ priv = malloc(sizeof(struct sysreset_reg)); ++ priv->glb_srst_fst_value = offsetof(struct rk3528_cru, ++ glb_srst_fst); ++ priv->glb_srst_snd_value = offsetof(struct rk3528_cru, ++ glb_srst_snd); ++ dev_set_priv(sys_child, priv); ++ } ++ ++#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) ++ ret = offsetof(struct rk3528_cru, softrst_con[0]); ++ ret = rockchip_reset_bind(dev, ret, 47); ++ if (ret) ++ debug("Warning: software reset driver bind failed\n"); ++#endif ++ ++ return 0; ++} ++ ++static const struct udevice_id rk3528_clk_ids[] = { ++ { .compatible = "rockchip,rk3528-cru" }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rockchip_rk3528_cru) = { ++ .name = "rockchip_rk3528_cru", ++ .id = UCLASS_CLK, ++ .of_match = rk3528_clk_ids, ++ .priv_auto = sizeof(struct rk3528_clk_priv), ++ .of_to_plat = rk3528_clk_ofdata_to_platdata, ++ .ops = &rk3528_clk_ops, ++ .bind = rk3528_clk_bind, ++ .probe = rk3528_clk_probe, ++}; +--- /dev/null ++++ b/include/dt-bindings/clock/rk3528-cru.h +@@ -0,0 +1,751 @@ ++/* 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 CLK_CORE_CRYPTO 119 ++#define CLK_PKA_CRYPTO 120 ++#define ACLK_CRYPTO 121 ++#define HCLK_CRYPTO 122 ++#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 PCLK_KLAD 483 ++#define HCLK_CRYPTO_S 484 ++#define HCLK_KLAD 485 ++#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 ++ ++/* 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 ++ ++/* 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/package/boot/uboot-rockchip/patches/405-pinctrl-rockchip-Add-support-for-RK3528.patch b/package/boot/uboot-rockchip/patches/405-pinctrl-rockchip-Add-support-for-RK3528.patch new file mode 100644 index 000000000..3351770d0 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/405-pinctrl-rockchip-Add-support-for-RK3528.patch @@ -0,0 +1,323 @@ +From 62eabfb295366711dfb761ec49bf39432861d45d Mon Sep 17 00:00:00 2001 +From: Steven Liu +Date: Thu, 23 Jan 2025 22:48:17 +0000 +Subject: [PATCH 5/9] pinctrl: rockchip: Add support for RK3528 + +Add pinctrl driver for RK3528. + +Imported from vendor U-Boot linux-6.1-stan-rkr5 tag with adjustments +to use regmap_update_bits(). + +Signed-off-by: Steven Liu +Signed-off-by: Jonas Karlman +--- + drivers/pinctrl/rockchip/Makefile | 1 + + drivers/pinctrl/rockchip/pinctrl-rk3528.c | 292 ++++++++++++++++++++++ + 2 files changed, 293 insertions(+) + create mode 100644 drivers/pinctrl/rockchip/pinctrl-rk3528.c + +--- a/drivers/pinctrl/rockchip/Makefile ++++ b/drivers/pinctrl/rockchip/Makefile +@@ -14,6 +14,7 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl + obj-$(CONFIG_ROCKCHIP_RK3328) += pinctrl-rk3328.o + obj-$(CONFIG_ROCKCHIP_RK3368) += pinctrl-rk3368.o + obj-$(CONFIG_ROCKCHIP_RK3399) += pinctrl-rk3399.o ++obj-$(CONFIG_ROCKCHIP_RK3528) += pinctrl-rk3528.o + obj-$(CONFIG_ROCKCHIP_RK3568) += pinctrl-rk3568.o + obj-$(CONFIG_ROCKCHIP_RK3588) += pinctrl-rk3588.o + obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o +--- /dev/null ++++ b/drivers/pinctrl/rockchip/pinctrl-rk3528.c +@@ -0,0 +1,292 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Copyright (c) 2022 Rockchip Electronics Co., Ltd. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#include "pinctrl-rockchip.h" ++#include ++ ++static int rk3528_set_mux(struct rockchip_pin_bank *bank, int pin, int mux) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ int iomux_num = (pin / 8); ++ struct regmap *regmap; ++ int reg, mask; ++ u8 bit; ++ u32 data, rmask; ++ ++ regmap = priv->regmap_base; ++ reg = bank->iomux[iomux_num].offset; ++ if ((pin % 8) >= 4) ++ reg += 0x4; ++ bit = (pin % 4) * 4; ++ mask = 0xf; ++ ++ data = (mask << (bit + 16)); ++ rmask = data | (data >> 16); ++ data |= (mux & mask) << bit; ++ ++ return regmap_update_bits(regmap, reg, rmask, data); ++} ++ ++#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 void rk3528_calc_drv_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ ++ *regmap = priv->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: ++ *reg = 0; ++ debug("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; ++} ++ ++static int rk3528_set_drive(struct rockchip_pin_bank *bank, ++ int pin_num, int strength) ++{ ++ struct regmap *regmap; ++ int reg; ++ u32 data, rmask; ++ u8 bit; ++ int drv = (1 << (strength + 1)) - 1; ++ ++ rk3528_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); ++ ++ /* enable the write to the equivalent lower bits */ ++ data = ((1 << RK3528_DRV_BITS_PER_PIN) - 1) << (bit + 16); ++ rmask = data | (data >> 16); ++ data |= (drv << bit); ++ ++ return regmap_update_bits(regmap, reg, rmask, data); ++} ++ ++#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 void rk3528_calc_pull_reg_and_bit(struct rockchip_pin_bank *bank, ++ int pin_num, struct regmap **regmap, ++ int *reg, u8 *bit) ++{ ++ struct rockchip_pinctrl_priv *priv = bank->priv; ++ ++ *regmap = priv->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: ++ *reg = 0; ++ debug("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; ++} ++ ++static int rk3528_set_pull(struct rockchip_pin_bank *bank, ++ int pin_num, int pull) ++{ ++ struct regmap *regmap; ++ int reg, ret; ++ u8 bit, type; ++ u32 data, rmask; ++ ++ if (pull == PIN_CONFIG_BIAS_PULL_PIN_DEFAULT) ++ return -EOPNOTSUPP; ++ ++ rk3528_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); ++ type = bank->pull_type[pin_num / 8]; ++ ret = rockchip_translate_pull_value(type, pull); ++ if (ret < 0) { ++ debug("unsupported pull setting %d\n", pull); ++ return ret; ++ } ++ ++ /* enable the write to the equivalent lower bits */ ++ data = ((1 << RK3528_PULL_BITS_PER_PIN) - 1) << (bit + 16); ++ rmask = data | (data >> 16); ++ data |= (ret << bit); ++ ++ return regmap_update_bits(regmap, reg, rmask, data); ++} ++ ++#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_priv *priv = bank->priv; ++ ++ *regmap = priv->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: ++ *reg = 0; ++ debug("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; ++} ++ ++static int rk3528_set_schmitt(struct rockchip_pin_bank *bank, ++ int pin_num, int enable) ++{ ++ struct regmap *regmap; ++ int reg; ++ u32 data, rmask; ++ u8 bit; ++ ++ rk3528_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); ++ ++ /* enable the write to the equivalent lower bits */ ++ data = ((1 << RK3528_SMT_BITS_PER_PIN) - 1) << (bit + 16); ++ rmask = data | (data >> 16); ++ data |= (enable << bit); ++ ++ return regmap_update_bits(regmap, reg, rmask, data); ++} ++ ++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 const struct rockchip_pin_ctrl rk3528_pin_ctrl = { ++ .pin_banks = rk3528_pin_banks, ++ .nr_banks = ARRAY_SIZE(rk3528_pin_banks), ++ .nr_pins = 160, ++ .grf_mux_offset = 0x0, ++ .set_mux = rk3528_set_mux, ++ .set_pull = rk3528_set_pull, ++ .set_drive = rk3528_set_drive, ++ .set_schmitt = rk3528_set_schmitt, ++}; ++ ++static const struct udevice_id rk3528_pinctrl_ids[] = { ++ { ++ .compatible = "rockchip,rk3528-pinctrl", ++ .data = (ulong)&rk3528_pin_ctrl ++ }, ++ { } ++}; ++ ++U_BOOT_DRIVER(rockchip_rk3528_pinctrl) = { ++ .name = "rockchip_rk3528_pinctrl", ++ .id = UCLASS_PINCTRL, ++ .of_match = rk3528_pinctrl_ids, ++ .priv_auto = sizeof(struct rockchip_pinctrl_priv), ++ .ops = &rockchip_pinctrl_ops, ++#if CONFIG_IS_ENABLED(OF_REAL) ++ .bind = dm_scan_fdt_dev, ++#endif ++ .probe = rockchip_pinctrl_probe, ++}; diff --git a/package/boot/uboot-rockchip/patches/406-mmc-rockchip_sdhci-Extend-variant-configuration.patch b/package/boot/uboot-rockchip/patches/406-mmc-rockchip_sdhci-Extend-variant-configuration.patch new file mode 100644 index 000000000..e2a433302 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/406-mmc-rockchip_sdhci-Extend-variant-configuration.patch @@ -0,0 +1,74 @@ +From 81dbef690f2f9734b67a2db9ac5abb773cb4b948 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:18 +0000 +Subject: [PATCH 6/9] mmc: rockchip_sdhci: Extend variant configuration + +RK3528 and RK3576 use different tap and delay num for cmdout and strbin. + +Move tap and delay num for cmdout and strbin to driver data to prepare +for adding new SoCs. + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/rockchip_sdhci.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/mmc/rockchip_sdhci.c ++++ b/drivers/mmc/rockchip_sdhci.c +@@ -156,6 +156,9 @@ struct sdhci_data { + u32 flags; + u8 hs200_txclk_tapnum; + u8 hs400_txclk_tapnum; ++ u8 hs400_cmdout_tapnum; ++ u8 hs400_strbin_tapnum; ++ u8 ddr50_strbin_delay_num; + }; + + static void rk3399_emmc_phy_power_on(struct rockchip_emmc_phy *phy, u32 clock) +@@ -348,7 +351,7 @@ static int rk3568_sdhci_config_dll(struc + extra = DLL_CMDOUT_SRC_CLK_NEG | + DLL_CMDOUT_BOTH_CLK_EDGE | + DWCMSHC_EMMC_DLL_DLYENA | +- DLL_CMDOUT_TAPNUM_90_DEGREES | ++ data->hs400_cmdout_tapnum | + DLL_CMDOUT_TAPNUM_FROM_SW; + sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_CMDOUT); + } +@@ -360,7 +363,7 @@ static int rk3568_sdhci_config_dll(struc + sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_TXCLK); + + extra = DWCMSHC_EMMC_DLL_DLYENA | +- DLL_STRBIN_TAPNUM_DEFAULT | ++ data->hs400_strbin_tapnum | + DLL_STRBIN_TAPNUM_FROM_SW; + sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN); + } else { +@@ -380,7 +383,7 @@ static int rk3568_sdhci_config_dll(struc + */ + extra = DWCMSHC_EMMC_DLL_DLYENA | + DLL_STRBIN_DELAY_NUM_SEL | +- DLL_STRBIN_DELAY_NUM_DEFAULT << DLL_STRBIN_DELAY_NUM_OFFSET; ++ data->ddr50_strbin_delay_num << DLL_STRBIN_DELAY_NUM_OFFSET; + sdhci_writel(host, extra, DWCMSHC_EMMC_DLL_STRBIN); + } + +@@ -654,6 +657,9 @@ static const struct sdhci_data rk3568_da + .flags = FLAG_INVERTER_FLAG_IN_RXCLK, + .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, + .hs400_txclk_tapnum = 0x8, ++ .hs400_cmdout_tapnum = DLL_CMDOUT_TAPNUM_90_DEGREES, ++ .hs400_strbin_tapnum = DLL_STRBIN_TAPNUM_DEFAULT, ++ .ddr50_strbin_delay_num = DLL_STRBIN_DELAY_NUM_DEFAULT, + }; + + static const struct sdhci_data rk3588_data = { +@@ -662,6 +668,9 @@ static const struct sdhci_data rk3588_da + .config_dll = rk3568_sdhci_config_dll, + .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, + .hs400_txclk_tapnum = 0x9, ++ .hs400_cmdout_tapnum = DLL_CMDOUT_TAPNUM_90_DEGREES, ++ .hs400_strbin_tapnum = DLL_STRBIN_TAPNUM_DEFAULT, ++ .ddr50_strbin_delay_num = DLL_STRBIN_DELAY_NUM_DEFAULT, + }; + + static const struct udevice_id sdhci_ids[] = { diff --git a/package/boot/uboot-rockchip/patches/407-mmc-rockchip_sdhci-Add-initial-support-for-RK3528.patch b/package/boot/uboot-rockchip/patches/407-mmc-rockchip_sdhci-Add-initial-support-for-RK3528.patch new file mode 100644 index 000000000..c73b2d8be --- /dev/null +++ b/package/boot/uboot-rockchip/patches/407-mmc-rockchip_sdhci-Add-initial-support-for-RK3528.patch @@ -0,0 +1,49 @@ +From 1d08efe86fd6756ba2b114ad2a256bea2d0e9b9e Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:19 +0000 +Subject: [PATCH 7/9] mmc: rockchip_sdhci: Add initial support for RK3528 + +Add initial support for SDHCI controller in RK3528. + +Only MMC Legacy and MMC High Speed (52MHz) mode is supported after this, +more work is needed to get the faster HS200/HS400/HS400ES modes working. + +Variant tap and delay num is copied from vendor Linux tag +linux-6.1-stan-rkr5. + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/rockchip_sdhci.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +--- a/drivers/mmc/rockchip_sdhci.c ++++ b/drivers/mmc/rockchip_sdhci.c +@@ -650,6 +650,17 @@ static const struct sdhci_data rk3399_da + .set_enhanced_strobe = rk3399_sdhci_set_enhanced_strobe, + }; + ++static const struct sdhci_data rk3528_data = { ++ .set_ios_post = rk3568_sdhci_set_ios_post, ++ .set_clock = rk3568_sdhci_set_clock, ++ .config_dll = rk3568_sdhci_config_dll, ++ .hs200_txclk_tapnum = 0xc, ++ .hs400_txclk_tapnum = 0x6, ++ .hs400_cmdout_tapnum = 0x6, ++ .hs400_strbin_tapnum = 0x3, ++ .ddr50_strbin_delay_num = 0xa, ++}; ++ + static const struct sdhci_data rk3568_data = { + .set_ios_post = rk3568_sdhci_set_ios_post, + .set_clock = rk3568_sdhci_set_clock, +@@ -679,6 +690,10 @@ static const struct udevice_id sdhci_ids + .data = (ulong)&rk3399_data, + }, + { ++ .compatible = "rockchip,rk3528-dwcmshc", ++ .data = (ulong)&rk3528_data, ++ }, ++ { + .compatible = "rockchip,rk3568-dwcmshc", + .data = (ulong)&rk3568_data, + }, diff --git a/package/boot/uboot-rockchip/patches/408-mmc-rockchip_sdhci-Gate-clock-for-glitch-free-phase.patch b/package/boot/uboot-rockchip/patches/408-mmc-rockchip_sdhci-Gate-clock-for-glitch-free-phase.patch new file mode 100644 index 000000000..8df26f2ab --- /dev/null +++ b/package/boot/uboot-rockchip/patches/408-mmc-rockchip_sdhci-Gate-clock-for-glitch-free-phase.patch @@ -0,0 +1,55 @@ +From ef8c8a638dd459d52d833693b3921010fbd883ff Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:20 +0000 +Subject: [PATCH 8/9] mmc: rockchip_sdhci: Gate clock for glitch free phase + switching + +Enable clock stopping to gate clock during phase code change to ensure +glitch free phase switching in auto-tuning circuit. Fixes HS200 mode +on RK3528. + +POST_CHANGE_DLY +Time taken for phase switching and stable clock output. +- Less than 4-cycle latency + +PRE_CHANGE_DLY +Maximum Latency specification between transmit clock and receive clock. +- Less than 4-cycle latency + +TUNE_CLK_STOP_EN +Clock stopping control for Tuning and auto-tuning circuit. When enabled, +clock gate control output is pulled low before changing phase select +codes. This effectively stops the receive clock. Changing phase code +when clocks are stopped ensures glitch free phase switching. +- Clocks stopped during phase code change + +Signed-off-by: Jonas Karlman +--- + drivers/mmc/rockchip_sdhci.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +--- a/drivers/mmc/rockchip_sdhci.c ++++ b/drivers/mmc/rockchip_sdhci.c +@@ -50,6 +50,10 @@ + #define DWCMSHC_EMMC_EMMC_CTRL 0x52c + #define DWCMSHC_CARD_IS_EMMC BIT(0) + #define DWCMSHC_ENHANCED_STROBE BIT(8) ++#define DWCMSHC_EMMC_AT_CTRL 0x540 ++#define EMMC_AT_CTRL_TUNE_CLK_STOP_EN BIT(16) ++#define EMMC_AT_CTRL_PRE_CHANGE_DLY 17 ++#define EMMC_AT_CTRL_POST_CHANGE_DLY 19 + #define DWCMSHC_EMMC_DLL_CTRL 0x800 + #define DWCMSHC_EMMC_DLL_CTRL_RESET BIT(1) + #define DWCMSHC_EMMC_DLL_RXCLK 0x804 +@@ -326,6 +330,11 @@ static int rk3568_sdhci_config_dll(struc + udelay(1); + sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL); + ++ extra = 0x3 << EMMC_AT_CTRL_POST_CHANGE_DLY | ++ 0x3 << EMMC_AT_CTRL_PRE_CHANGE_DLY | ++ EMMC_AT_CTRL_TUNE_CLK_STOP_EN; ++ sdhci_writel(host, extra, DWCMSHC_EMMC_AT_CTRL); ++ + /* Init DLL settings */ + extra = DWCMSHC_EMMC_DLL_START_DEFAULT << DWCMSHC_EMMC_DLL_START_POINT | + DWCMSHC_EMMC_DLL_INC_VALUE << DWCMSHC_EMMC_DLL_INC | diff --git a/package/boot/uboot-rockchip/patches/409-rng-rockchip-Add-support-for-rkrng-variant.patch b/package/boot/uboot-rockchip/patches/409-rng-rockchip-Add-support-for-rkrng-variant.patch new file mode 100644 index 000000000..32441a249 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/409-rng-rockchip-Add-support-for-rkrng-variant.patch @@ -0,0 +1,119 @@ +From 4e19cd0a572b6a27b82fef84c30fca69914b7798 Mon Sep 17 00:00:00 2001 +From: Lin Jinhan +Date: Thu, 23 Jan 2025 22:48:21 +0000 +Subject: [PATCH 9/9] rng: rockchip: Add support for rkrng variant + +Add support for rkrng variant, used by e.g. RK3528 and RK3576. + +Imported from vendor U-Boot linux-6.1-stan-rkr5 tag with minor +adjustments for mainline. + +Signed-off-by: Lin Jinhan +Signed-off-by: Jonas Karlman +--- + drivers/rng/rockchip_rng.c | 73 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 73 insertions(+) + +--- a/drivers/rng/rockchip_rng.c ++++ b/drivers/rng/rockchip_rng.c +@@ -70,6 +70,27 @@ + #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 */ ++ + #define RK_RNG_TIME_OUT 50000 /* max 50ms */ + + #define trng_write(pdata, pos, val) writel(val, (pdata)->base + (pos)) +@@ -228,6 +249,49 @@ exit: + return retval; + } + ++static int rkrng_init(struct udevice *dev) ++{ ++ struct rk_rng_plat *pdata = dev_get_priv(dev); ++ u32 reg = 0; ++ ++ rk_clrreg(pdata->base + RKRNG_CTRL, 0xffff); ++ ++ reg = trng_read(pdata, RKRNG_STATE); ++ trng_write(pdata, RKRNG_STATE, reg); ++ ++ return 0; ++} ++ ++static int rkrng_rng_read(struct udevice *dev, void *data, size_t len) ++{ ++ struct rk_rng_plat *pdata = dev_get_priv(dev); ++ u32 reg = 0; ++ int retval; ++ ++ if (len > RK_HW_RNG_MAX) ++ return -EINVAL; ++ ++ reg = RKRNG_CTRL_SW_DRNG_REQ; ++ ++ rk_clrsetreg(pdata->base + RKRNG_CTRL, 0xffff, reg); ++ ++ retval = readl_poll_timeout(pdata->base + RKRNG_STATE, reg, ++ (reg & RKRNG_STATE_SW_DRNG_ACK), ++ RK_RNG_TIME_OUT); ++ if (retval) ++ goto exit; ++ ++ trng_write(pdata, RKRNG_STATE, reg); ++ ++ rk_rng_read_regs(pdata->base + RKRNG_DRNG_DATA_0, data, len); ++ ++exit: ++ /* close TRNG */ ++ rk_clrreg(pdata->base + RKRNG_CTRL, 0xffff); ++ ++ return retval; ++} ++ + static int rockchip_rng_read(struct udevice *dev, void *data, size_t len) + { + unsigned char *buf = data; +@@ -295,6 +359,11 @@ static const struct rk_rng_soc_data rk_t + .rk_rng_read = rk_trngv1_rng_read, + }; + ++static const struct rk_rng_soc_data rkrng_soc_data = { ++ .rk_rng_init = rkrng_init, ++ .rk_rng_read = rkrng_rng_read, ++}; ++ + static const struct dm_rng_ops rockchip_rng_ops = { + .read = rockchip_rng_read, + }; +@@ -320,6 +389,10 @@ static const struct udevice_id rockchip_ + .compatible = "rockchip,trngv1", + .data = (ulong)&rk_trngv1_soc_data, + }, ++ { ++ .compatible = "rockchip,rkrng", ++ .data = (ulong)&rkrng_soc_data, ++ }, + {}, + }; + diff --git a/package/boot/uboot-rockchip/patches/411-arm-dts-rockchip-Add-rk3528-pinctrl.dtsi.patch b/package/boot/uboot-rockchip/patches/411-arm-dts-rockchip-Add-rk3528-pinctrl.dtsi.patch new file mode 100644 index 000000000..6b134676e --- /dev/null +++ b/package/boot/uboot-rockchip/patches/411-arm-dts-rockchip-Add-rk3528-pinctrl.dtsi.patch @@ -0,0 +1,1416 @@ +From fa2055e1249835666241bf30a6f0d9ccbddf22dd Mon Sep 17 00:00:00 2001 +From: Joseph Chen +Date: Thu, 23 Jan 2025 22:48:22 +0000 +Subject: [PATCH 1/4] arm: dts: rockchip: Add rk3528-pinctrl.dtsi + +Import rk3528-pinctrl.dtsi from vendor U-Boot and Linux tag +linux-6.1-stan-rkr5 with the hdmi-pins-idle node removed due to missing +label reference to pcfg_output_low_pull_down. + +Signed-off-by: Joseph Chen +Signed-off-by: Jonas Karlman +--- + arch/arm/dts/rk3528-pinctrl.dtsi | 1397 ++++++++++++++++++++++++++++++ + 1 file changed, 1397 insertions(+) + create mode 100644 arch/arm/dts/rk3528-pinctrl.dtsi + +--- /dev/null ++++ b/arch/arm/dts/rk3528-pinctrl.dtsi +@@ -0,0 +1,1397 @@ ++// 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_hpd */ ++ <0 RK_PA2 1 &pcfg_pull_none>, ++ /* hdmi_tx_scl */ ++ <0 RK_PA4 1 &pcfg_pull_none>, ++ /* hdmi_tx_sda */ ++ <0 RK_PA5 1 &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/package/boot/uboot-rockchip/patches/412-arm-dts-rockchip-Add-rk3528-u-boot.dtsi.patch b/package/boot/uboot-rockchip/patches/412-arm-dts-rockchip-Add-rk3528-u-boot.dtsi.patch new file mode 100644 index 000000000..6572b9f21 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/412-arm-dts-rockchip-Add-rk3528-u-boot.dtsi.patch @@ -0,0 +1,371 @@ +From efd80d2ddee68e1f070396c67a7f76426d065017 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:23 +0000 +Subject: [PATCH 2/4] arm: dts: rockchip: Add rk3528-u-boot.dtsi + +Add a rk3528-u-boot.dtsi extending the basic dts/upstream rk3528.dtsi +with bare minimum nodes to have a booting system from eMMC and SD-card. + +Signed-off-by: Jonas Karlman +--- + arch/arm/dts/rk3528-u-boot.dtsi | 354 ++++++++++++++++++++++++++++++++ + 1 file changed, 354 insertions(+) + create mode 100644 arch/arm/dts/rk3528-u-boot.dtsi + +--- /dev/null ++++ b/arch/arm/dts/rk3528-u-boot.dtsi +@@ -0,0 +1,354 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include ++#include ++#include "rockchip-u-boot.dtsi" ++ ++/ { ++ aliases { ++ gpio0 = &gpio0; ++ gpio1 = &gpio1; ++ gpio2 = &gpio2; ++ gpio3 = &gpio3; ++ gpio4 = &gpio4; ++ mmc0 = &sdhci; ++ mmc1 = &sdmmc; ++ }; ++ ++ chosen { ++ u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci; ++ }; ++ ++ dmc { ++ compatible = "rockchip,rk3528-dmc"; ++ bootph-all; ++ }; ++ ++ soc { ++ usb_host0_ehci: usb@ff100000 { ++ compatible = "rockchip,rk3528-ehci", "generic-ehci"; ++ reg = <0x0 0xff100000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_USBHOST>, <&cru HCLK_USBHOST_ARB>, ++ <&u2phy>; ++ phys = <&u2phy_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ usb_host0_ohci: usb@ff140000 { ++ compatible = "rockchip,rk3528-ohci", "generic-ohci"; ++ reg = <0x0 0xff140000 0x0 0x40000>; ++ interrupts = ; ++ clocks = <&cru HCLK_USBHOST>, <&cru HCLK_USBHOST_ARB>, ++ <&u2phy>; ++ phys = <&u2phy_host>; ++ phy-names = "usb"; ++ status = "disabled"; ++ }; ++ ++ grf: syscon@ff300000 { ++ compatible = "rockchip,rk3528-grf", ++ "syscon", "simple-mfd"; ++ reg = <0x0 0xff300000 0x0 0x90000>; ++ }; ++ ++ cru: clock-controller@ff4a0000 { ++ compatible = "rockchip,rk3528-cru"; ++ reg = <0x0 0xff4a0000 0x0 0x30000>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ ioc_grf: syscon@ff540000 { ++ compatible = "rockchip,rk3528-ioc-grf", "syscon"; ++ reg = <0x0 0xff540000 0x0 0x40000>; ++ }; ++ ++ saradc: adc@ffae0000 { ++ compatible = "rockchip,rk3528-saradc"; ++ reg = <0x0 0xffae0000 0x0 0x10000>; ++ interrupts = ; ++ #io-channel-cells = <1>; ++ clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>; ++ clock-names = "saradc", "apb_pclk"; ++ resets = <&cru SRST_PRESETN_SARADC>; ++ reset-names = "saradc-apb"; ++ status = "disabled"; ++ }; ++ ++ 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,blen = <0 0 0 0 16 8 4>; ++ snps,rd_osr_lmt = <8>; ++ snps,wr_osr_lmt = <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 = ; ++ clocks = <&cru CCLK_SRC_EMMC>, <&cru HCLK_EMMC>, ++ <&cru ACLK_EMMC>, <&cru BCLK_EMMC>, ++ <&cru TCLK_EMMC>; ++ clock-names = "core", "bus", "axi", "block", "timer"; ++ max-frequency = <200000000>; ++ status = "disabled"; ++ }; ++ ++ sdmmc: mmc@ffc30000 { ++ compatible = "rockchip,rk3528-dw-mshc", ++ "rockchip,rk3288-dw-mshc"; ++ reg = <0x0 0xffc30000 0x0 0x4000>; ++ interrupts = ; ++ max-frequency = <150000000>; ++ clocks = <&cru HCLK_SDMMC0>, <&cru CCLK_SRC_SDMMC0>; ++ clock-names = "biu", "ciu"; ++ fifo-depth = <0x100>; ++ status = "disabled"; ++ }; ++ ++ rng: rng@ffc50000 { ++ compatible = "rockchip,rkrng"; ++ reg = <0x0 0xffc50000 0x0 0x200>; ++ }; ++ ++ otp: otp@ffce0000 { ++ compatible = "rockchip,rk3528-otp", ++ "rockchip,rk3568-otp"; ++ reg = <0x0 0xffce0000 0x0 0x4000>; ++ }; ++ ++ u2phy: usb2phy@ffdf0000 { ++ compatible = "rockchip,rk3528-usb2phy"; ++ reg = <0x0 0xffdf0000 0x0 0x10000>; ++ clocks = <&cru CLK_REF_USBPHY>, <&cru PCLK_USBPHY>; ++ clock-names = "phyclk", "apb_pclk"; ++ #clock-cells = <0>; ++ rockchip,usbgrf = <&grf>; ++ status = "disabled"; ++ ++ u2phy_otg: otg-port { ++ interrupts = , ++ , ++ ; ++ interrupt-names = "otg-bvalid", "otg-id", ++ "linestate"; ++ #phy-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ u2phy_host: host-port { ++ interrupts = ; ++ interrupt-names = "linestate"; ++ #phy-cells = <0>; ++ 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>; ++ clocks = <&cru PCLK_GPIO0>, <&cru DBCLK_GPIO0>; ++ interrupts = ; ++ 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>; ++ clocks = <&cru PCLK_GPIO1>, <&cru DBCLK_GPIO1>; ++ interrupts = ; ++ 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>; ++ clocks = <&cru PCLK_GPIO2>, <&cru DBCLK_GPIO2>; ++ interrupts = ; ++ 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>; ++ clocks = <&cru PCLK_GPIO3>, <&cru DBCLK_GPIO3>; ++ interrupts = ; ++ 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>; ++ clocks = <&cru PCLK_GPIO4>, <&cru DBCLK_GPIO4>; ++ interrupts = ; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-ranges = <&pinctrl 0 128 32>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ }; ++ }; ++ }; ++}; ++ ++#include "rk3528-pinctrl.dtsi" ++ ++&cru { ++ bootph-all; ++}; ++ ++&emmc_bus8 { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&emmc_clk { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&emmc_cmd { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&emmc_strb { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&grf { ++ bootph-all; ++}; ++ ++&ioc_grf { ++ bootph-all; ++}; ++ ++&otp { ++ bootph-some-ram; ++}; ++ ++&pcfg_pull_none { ++ bootph-all; ++}; ++ ++&pcfg_pull_up { ++ bootph-all; ++}; ++ ++&pcfg_pull_up_drv_level_2 { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&pinctrl { ++ bootph-all; ++}; ++ ++&sdhci { ++ bootph-pre-ram; ++ bootph-some-ram; ++ u-boot,spl-fifo-mode; ++}; ++ ++&sdmmc { ++ bootph-pre-ram; ++ bootph-some-ram; ++ u-boot,spl-fifo-mode; ++}; ++ ++&sdmmc_bus4 { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&sdmmc_clk { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&sdmmc_cmd { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&sdmmc_det { ++ bootph-pre-ram; ++ bootph-some-ram; ++}; ++ ++&uart0 { ++ bootph-all; ++ clock-frequency = <24000000>; ++}; ++ ++&uart0m0_xfer { ++ bootph-pre-sram; ++ bootph-pre-ram; ++}; ++ ++&xin24m { ++ bootph-all; ++}; diff --git a/package/boot/uboot-rockchip/patches/413-board-rockchip-Add-minimal-generic-RK3528-board.patch b/package/boot/uboot-rockchip/patches/413-board-rockchip-Add-minimal-generic-RK3528-board.patch new file mode 100644 index 000000000..041e1ec17 --- /dev/null +++ b/package/boot/uboot-rockchip/patches/413-board-rockchip-Add-minimal-generic-RK3528-board.patch @@ -0,0 +1,159 @@ +From e7f5a4ae16f02ddaf2acf59b07e684c95338937d Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:24 +0000 +Subject: [PATCH 3/4] board: rockchip: Add minimal generic RK3528 board + +Add a minimal generic RK3528 board that only have eMMC and SDMMC +enabled. This defconfig can be used to boot from eMMC or SD-card on most +RK3528 boards that follow reference board design. + +Signed-off-by: Jonas Karlman +--- + arch/arm/dts/rk3528-generic-u-boot.dtsi | 31 +++++++++++++++++ + arch/arm/dts/rk3528-generic.dts | 20 +++++++++++ + arch/arm/mach-rockchip/rk3528/MAINTAINERS | 5 +++ + configs/generic-rk3528_defconfig | 41 +++++++++++++++++++++++ + doc/board/rockchip/rockchip.rst | 12 +++++++ + 5 files changed, 109 insertions(+) + create mode 100644 arch/arm/dts/rk3528-generic-u-boot.dtsi + create mode 100644 arch/arm/dts/rk3528-generic.dts + create mode 100644 arch/arm/mach-rockchip/rk3528/MAINTAINERS + create mode 100644 configs/generic-rk3528_defconfig + +--- /dev/null ++++ b/arch/arm/dts/rk3528-generic-u-boot.dtsi +@@ -0,0 +1,31 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "rk3528-u-boot.dtsi" ++ ++&sdhci { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ no-sd; ++ no-sdio; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, <&emmc_strb>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ no-mmc; ++ no-sdio; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_bus4>, <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_det>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0m0_xfer>; ++}; +--- /dev/null ++++ b/arch/arm/dts/rk3528-generic.dts +@@ -0,0 +1,20 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Minimal generic DT for RK3528 with eMMC and SD-card enabled ++ */ ++ ++/dts-v1/; ++#include "rk3528.dtsi" ++ ++/ { ++ model = "Generic RK3528"; ++ compatible = "rockchip,rk3528"; ++ ++ chosen { ++ stdout-path = "serial0:1500000n8"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; +--- /dev/null ++++ b/arch/arm/mach-rockchip/rk3528/MAINTAINERS +@@ -0,0 +1,5 @@ ++GENERIC-RK3528 ++M: Jonas Karlman ++S: Maintained ++F: arch/arm/dts/rk3528-generic* ++F: configs/generic-rk3528_defconfig +--- /dev/null ++++ b/configs/generic-rk3528_defconfig +@@ -0,0 +1,41 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_DEFAULT_DEVICE_TREE="rk3528-generic" ++CONFIG_ROCKCHIP_RK3528=y ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_DEBUG_UART_BASE=0xFF9F0000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART=y ++# CONFIG_BOOTMETH_VBE is not set ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3528-generic.dtb" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_SPL_MAX_SIZE=0x40000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_CMD_MEMINFO=y ++CONFIG_CMD_MEMINFO_MAP=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MISC=y ++CONFIG_CMD_MMC=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_RNG=y ++# CONFIG_SPL_DOS_PARTITION is not set ++# CONFIG_OF_UPSTREAM is not set ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_NO_NET=y ++# CONFIG_ADC is not set ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_SYSRESET_PSCI=y ++CONFIG_ERRNO_STR=y +--- a/doc/board/rockchip/rockchip.rst ++++ b/doc/board/rockchip/rockchip.rst +@@ -97,6 +97,9 @@ List of mainline supported Rockchip boar + - Rockchip Evb-RK3399 (evb_rk3399) + - Theobroma Systems RK3399-Q7 SoM - Puma (puma_rk3399) + ++* rk3528 ++ - Generic RK3528 (generic-rk3528) ++ + * rk3566 + - Anbernic RGxx3 (anbernic-rgxx3-rk3566) + - Hardkernel ODROID-M1S (odroid-m1s-rk3566) +@@ -255,6 +258,15 @@ To build rk3399 boards: + make evb-rk3399_defconfig + make CROSS_COMPILE=aarch64-linux-gnu- + ++To build rk3528 boards: ++ ++.. code-block:: bash ++ ++ export BL31=../rkbin/bin/rk35/rk3528_bl31_v1.18.elf ++ export ROCKCHIP_TPL=../rkbin/bin/rk35/rk3528_ddr_1056MHz_v1.10.bin ++ make generic-rk3528_defconfig ++ make CROSS_COMPILE=aarch64-linux-gnu- ++ + To build rk3568 boards: + + .. code-block:: bash diff --git a/package/boot/uboot-rockchip/patches/414-board-rockchip-Add-Radxa-E20C.patch b/package/boot/uboot-rockchip/patches/414-board-rockchip-Add-Radxa-E20C.patch new file mode 100644 index 000000000..16a81336a --- /dev/null +++ b/package/boot/uboot-rockchip/patches/414-board-rockchip-Add-Radxa-E20C.patch @@ -0,0 +1,199 @@ +From 66014f06f4b1d0c39e79fdd45201962913ec27a2 Mon Sep 17 00:00:00 2001 +From: Jonas Karlman +Date: Thu, 23 Jan 2025 22:48:25 +0000 +Subject: [PATCH 4/4] board: rockchip: Add Radxa E20C + +The Radxa E20C is an ultra-compact network computer with a RK3528A SoC +that offers a wide range of networking capabilities. + +Features tested on a Radxa E20C v1.104: +- SD-card boot +- eMMC boot +- Ethernet +- USB host + +Signed-off-by: Jonas Karlman +--- + arch/arm/dts/rk3528-radxa-e20c-u-boot.dtsi | 93 ++++++++++++++++++++++ + arch/arm/mach-rockchip/rk3528/MAINTAINERS | 6 ++ + configs/radxa-e20c-rk3528_defconfig | 54 +++++++++++++ + doc/board/rockchip/rockchip.rst | 1 + + 4 files changed, 154 insertions(+) + create mode 100644 arch/arm/dts/rk3528-radxa-e20c-u-boot.dtsi + create mode 100644 configs/radxa-e20c-rk3528_defconfig + +--- /dev/null ++++ b/arch/arm/dts/rk3528-radxa-e20c-u-boot.dtsi +@@ -0,0 +1,93 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "rk3528-u-boot.dtsi" ++ ++/ { ++ aliases { ++ ethernet0 = &gmac1; ++ }; ++ ++ vcc_1v8: regulator-1v8 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_1v8"; ++ regulator-always-on; ++ regulator-boot-on; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ }; ++ ++ vcc5v0_usb20: regulator-5v0-usb20 { ++ compatible = "regulator-fixed"; ++ enable-active-high; ++ gpios = <&gpio0 RK_PA1 GPIO_ACTIVE_HIGH>; ++ regulator-name = "vcc5v0_usb20"; ++ regulator-max-microvolt = <5000000>; ++ regulator-min-microvolt = <5000000>; ++ }; ++}; ++ ++&gmac1 { ++ clock_in_out = "output"; ++ phy-handle = <&rgmii_phy>; ++ phy-mode = "rgmii-id"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&rgmii_miim>, <&rgmii_tx_bus2>, <&rgmii_rx_bus2>, ++ <&rgmii_rgmii_clk>, <&rgmii_rgmii_bus>; ++ status = "okay"; ++}; ++ ++&mdio1 { ++ rgmii_phy: ethernet-phy@1 { ++ compatible = "ethernet-phy-ieee802.3-c22"; ++ reg = <0x1>; ++ reset-assert-us = <20000>; ++ reset-deassert-us = <100000>; ++ reset-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>; ++ }; ++}; ++ ++&saradc { ++ vref-supply = <&vcc_1v8>; ++ status = "okay"; ++}; ++ ++&sdhci { ++ bus-width = <8>; ++ cap-mmc-highspeed; ++ mmc-hs200-1_8v; ++ no-sd; ++ no-sdio; ++ non-removable; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, <&emmc_strb>; ++ status = "okay"; ++}; ++ ++&sdmmc { ++ bus-width = <4>; ++ cap-sd-highspeed; ++ disable-wp; ++ no-mmc; ++ no-sdio; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdmmc_bus4>, <&sdmmc_clk>, <&sdmmc_cmd>, <&sdmmc_det>; ++ status = "okay"; ++}; ++ ++&u2phy { ++ status = "okay"; ++}; ++ ++&u2phy_host { ++ phy-supply = <&vcc5v0_usb20>; ++ status = "okay"; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0m0_xfer>; ++}; ++ ++&usb_host0_ehci { ++ status = "okay"; ++}; +--- a/arch/arm/mach-rockchip/rk3528/MAINTAINERS ++++ b/arch/arm/mach-rockchip/rk3528/MAINTAINERS +@@ -3,3 +3,9 @@ M: Jonas Karlman + S: Maintained + F: arch/arm/dts/rk3528-generic* + F: configs/generic-rk3528_defconfig ++ ++RADXA-E20C ++M: Jonas Karlman ++S: Maintained ++F: arch/arm/dts/rk3528-radxa-e20c* ++F: configs/radxa-e20c-rk3528_defconfig +--- /dev/null ++++ b/configs/radxa-e20c-rk3528_defconfig +@@ -0,0 +1,54 @@ ++CONFIG_ARM=y ++CONFIG_SKIP_LOWLEVEL_INIT=y ++CONFIG_COUNTER_FREQUENCY=24000000 ++CONFIG_ARCH_ROCKCHIP=y ++CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3528-radxa-e20c" ++CONFIG_ROCKCHIP_RK3528=y ++CONFIG_SYS_LOAD_ADDR=0xc00800 ++CONFIG_DEBUG_UART_BASE=0xFF9F0000 ++CONFIG_DEBUG_UART_CLOCK=24000000 ++CONFIG_DEBUG_UART=y ++CONFIG_DEFAULT_FDT_FILE="rockchip/rk3528-radxa-e20c.dtb" ++# CONFIG_DISPLAY_CPUINFO is not set ++CONFIG_SPL_MAX_SIZE=0x40000 ++CONFIG_SPL_PAD_TO=0x7f8000 ++# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set ++CONFIG_CMD_MEMINFO=y ++CONFIG_CMD_MEMINFO_MAP=y ++CONFIG_CMD_ADC=y ++CONFIG_CMD_GPIO=y ++CONFIG_CMD_GPT=y ++CONFIG_CMD_MISC=y ++CONFIG_CMD_MMC=y ++CONFIG_CMD_USB=y ++# CONFIG_CMD_SETEXPR is not set ++CONFIG_CMD_RNG=y ++CONFIG_CMD_REGULATOR=y ++# CONFIG_SPL_DOS_PARTITION is not set ++CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" ++CONFIG_BUTTON=y ++CONFIG_BUTTON_ADC=y ++CONFIG_BUTTON_GPIO=y ++CONFIG_ROCKCHIP_GPIO=y ++CONFIG_LED=y ++CONFIG_LED_GPIO=y ++CONFIG_SUPPORT_EMMC_RPMB=y ++CONFIG_MMC_DW=y ++CONFIG_MMC_DW_ROCKCHIP=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_SDMA=y ++CONFIG_MMC_SDHCI_ROCKCHIP=y ++CONFIG_PHY_MOTORCOMM=y ++CONFIG_PHY_REALTEK=y ++CONFIG_DM_MDIO=y ++CONFIG_DWC_ETH_QOS=y ++CONFIG_DWC_ETH_QOS_ROCKCHIP=y ++CONFIG_PHY_ROCKCHIP_INNO_USB2=y ++CONFIG_BAUDRATE=1500000 ++CONFIG_DEBUG_UART_SHIFT=2 ++CONFIG_SYS_NS16550_MEM32=y ++CONFIG_SYSRESET_PSCI=y ++CONFIG_USB=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_GENERIC=y ++CONFIG_ERRNO_STR=y +--- a/doc/board/rockchip/rockchip.rst ++++ b/doc/board/rockchip/rockchip.rst +@@ -99,6 +99,7 @@ List of mainline supported Rockchip boar + + * rk3528 + - Generic RK3528 (generic-rk3528) ++ - Radxa E20C (radxa-e20c-rk3528) + + * rk3566 + - Anbernic RGxx3 (anbernic-rgxx3-rk3566)