diff options
238 files changed, 14120 insertions, 2004 deletions
diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index cb787d32f14..01ab0c11f98 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -350,6 +350,8 @@ stages: sandbox64_clang: TEST_PY_BD: "sandbox64" OVERRIDE: "-O clang-18" + sandbox64_lwip: + TEST_PY_BD: "sandbox64_lwip" sandbox_spl: TEST_PY_BD: "sandbox_spl" TEST_PY_TEST_SPEC: "test_ofplatdata or test_handoff or test_spl" diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5f3418e482f..145bdad83bf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -290,6 +290,17 @@ sandbox64 with clang test.py: OVERRIDE: "-O clang-18" <<: *buildman_and_testpy_dfn +sandbox64_lwip test.py: + parallel: + matrix: + - HOST: "fast arm64" + - HOST: "fast amd64" + tags: + - ${HOST} + variables: + TEST_PY_BD: "sandbox64_lwip" + <<: *buildman_and_testpy_dfn + sandbox_spl test.py: variables: TEST_PY_BD: "sandbox_spl" @@ -96,7 +96,8 @@ This contributor prefers not to receive mails <noreply@example.com> <pali.rohar@ Padmarao Begari <padmarao.begari@amd.com> <padmarao.begari@microchip.com> Patrice Chotard <patrice.chotard@foss.st.com> <patrice.chotard@st.com> Patrick Delaunay <patrick.delaunay@foss.st.com> <patrick.delaunay@st.com> -Paul Burton <paul.burton@mips.com> <paul.burton@imgtec.com> +Paul Burton <paulburton@kernel.org> <paul.burton@imgtec.com> +Paul Burton <paulburton@kernel.org> <paul.burton@mips.com> Philipp Tomsich <philipp.tomsich@vrull.eu> <philipp.tomsich@theobroma-systems.com> Piyush Mehta <piyush.mehta@amd.com> <piyush.mehta@xilinx.com> Prabhakar Kushwaha <prabhakar@freescale.com> diff --git a/MAINTAINERS b/MAINTAINERS index 0d8b58a12ef..ebbb0b6e8d0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -157,6 +157,7 @@ S: Maintained T: git https://source.denx.de/u-boot/custodians/u-boot-socfpga.git F: drivers/ddr/altera/ F: arch/arm/mach-socfpga/ +F: configs/socfpga_agilex5_vab_defconfig F: drivers/sysreset/sysreset_socfpga* ARM AMLOGIC SOC SUPPORT diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d8c99d3ab19..df373d38a55 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1138,6 +1138,7 @@ config ARCH_SOCFPGA select DM_SERIAL select GPIO_EXTRA_HEADER select ENABLE_ARM_SOC_BOOT0_HOOK if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10 + select LMB_ARCH_MEM_MAP if TARGET_SOCFPGA_SOC64 select OF_CONTROL select SPL_DM_RESET if DM_RESET select SPL_DM_SERIAL @@ -1171,8 +1172,6 @@ config ARCH_SOCFPGA imply SPL_DM_SPI_FLASH imply SPL_LIBDISK_SUPPORT imply SPL_MMC - imply SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION - imply SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE imply SPL_SPI_FLASH_SUPPORT imply SPL_SPI imply L2X0_CACHE diff --git a/arch/arm/dts/at91-sam9x60_curiosity.dts b/arch/arm/dts/at91-sam9x60_curiosity.dts index 7f00014f13c..1c7f0fa6a49 100644 --- a/arch/arm/dts/at91-sam9x60_curiosity.dts +++ b/arch/arm/dts/at91-sam9x60_curiosity.dts @@ -319,6 +319,10 @@ pinctrl-0 = <&pinctrl_sdhci1>; }; +&usb0 { + status = "okay"; +}; + &usb1 { num-ports = <3>; atmel,vbus-gpio = <0 diff --git a/arch/arm/dts/px30-evb-u-boot.dtsi b/arch/arm/dts/px30-evb-u-boot.dtsi deleted file mode 100644 index 61b1433af91..00000000000 --- a/arch/arm/dts/px30-evb-u-boot.dtsi +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/* - * (C) Copyright 2020 Rockchip Electronics Co., Ltd - */ - -#include "px30-u-boot.dtsi" - -&rng { - status = "okay"; -}; diff --git a/arch/arm/dts/px30-u-boot.dtsi b/arch/arm/dts/px30-u-boot.dtsi index abc6b49e666..157d0ea6930 100644 --- a/arch/arm/dts/px30-u-boot.dtsi +++ b/arch/arm/dts/px30-u-boot.dtsi @@ -24,7 +24,6 @@ rng: rng@ff0b0000 { compatible = "rockchip,cryptov2-rng"; reg = <0x0 0xff0b0000 0x0 0x4000>; - status = "disabled"; }; }; diff --git a/arch/arm/dts/rk3328-generic-u-boot.dtsi b/arch/arm/dts/rk3328-generic-u-boot.dtsi new file mode 100644 index 00000000000..af890e912dd --- /dev/null +++ b/arch/arm/dts/rk3328-generic-u-boot.dtsi @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk3328-u-boot.dtsi" + +&gpio0 { + /delete-property/ bootph-pre-ram; +}; + +&pcfg_pull_down_4ma { + bootph-pre-ram; + bootph-some-ram; +}; + +&spi0 { + flash@0 { + bootph-pre-ram; + bootph-some-ram; + }; +}; + +&spi0m2_clk { + bootph-pre-ram; + bootph-some-ram; +}; + +&spi0m2_cs0 { + bootph-pre-ram; + bootph-some-ram; +}; + +&spi0m2_rx { + bootph-pre-ram; + bootph-some-ram; +}; + +&spi0m2_tx { + bootph-pre-ram; + bootph-some-ram; +}; diff --git a/arch/arm/dts/rk3328-generic.dts b/arch/arm/dts/rk3328-generic.dts new file mode 100644 index 00000000000..af0da845716 --- /dev/null +++ b/arch/arm/dts/rk3328-generic.dts @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Minimal generic DT for RK3328 with eMMC, SD-card, SPI flash and USB OTG enabled + */ + +/dts-v1/; +#include "rk3328.dtsi" + +/ { + model = "Generic RK3328"; + compatible = "rockchip,rk3328"; + + aliases { + mmc0 = &emmc; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; +}; + +&emmc { + bus-width = <8>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + no-sd; + no-sdio; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_clk &emmc_cmd &emmc_bus8>; + status = "okay"; +}; + +&sdmmc0m1_pin { + rockchip,pins = <0 RK_PD6 RK_FUNC_GPIO &pcfg_pull_down_4ma>; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + no-mmc; + no-sdio; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc0_clk &sdmmc0_cmd &sdmmc0_dectn &sdmmc0_bus4 &sdmmc0m1_pin>; + status = "okay"; +}; + +&spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + }; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usb20_otg { + dr_mode = "peripheral"; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3399-generic-u-boot.dtsi b/arch/arm/dts/rk3399-generic-u-boot.dtsi new file mode 100644 index 00000000000..d977b642f8d --- /dev/null +++ b/arch/arm/dts/rk3399-generic-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk3399-u-boot.dtsi" + +&spi1 { + flash@0 { + bootph-pre-ram; + bootph-some-ram; + }; +}; diff --git a/arch/arm/dts/rk3399-generic.dts b/arch/arm/dts/rk3399-generic.dts new file mode 100644 index 00000000000..c698f59c565 --- /dev/null +++ b/arch/arm/dts/rk3399-generic.dts @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Minimal generic DT for RK3399 with eMMC, SD-card, SPI flash and USB OTG enabled + */ + +/dts-v1/; +#include "rk3399.dtsi" + +/ { + model = "Generic RK3399"; + compatible = "rockchip,rk3399"; + + aliases { + mmc0 = &sdhci; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; +}; + +&emmc_phy { + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + max-frequency = <150000000>; + mmc-hs200-1_8v; + mmc-ddr-1_8v; + no-sd; + no-sdio; + non-removable; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + max-frequency = <150000000>; + no-mmc; + no-sdio; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_cd>; + status = "okay"; +}; + +&spi1 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <25000000>; + }; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usbdrd3_0 { + status = "okay"; +}; + +&usbdrd_dwc3_0 { + dr_mode = "peripheral"; + maximum-speed = "high-speed"; + phys = <&u2phy0_otg>; + phy-names = "usb2-phy"; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3528-generic-u-boot.dtsi b/arch/arm/dts/rk3528-generic-u-boot.dtsi new file mode 100644 index 00000000000..cc830b51456 --- /dev/null +++ b/arch/arm/dts/rk3528-generic-u-boot.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk3528-u-boot.dtsi" + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + no-mmc; + no-sdio; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3528-generic.dts b/arch/arm/dts/rk3528-generic.dts new file mode 100644 index 00000000000..792d3e04a4c --- /dev/null +++ b/arch/arm/dts/rk3528-generic.dts @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Minimal generic DT for RK3528 with eMMC enabled + */ + +/dts-v1/; +#include "rk3528.dtsi" + +/ { + model = "Generic RK3528"; + compatible = "rockchip,rk3528"; + + chosen { + stdout-path = "serial0:1500000n8"; + }; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + no-sd; + no-sdio; + non-removable; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0m0_xfer>; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3528-radxa-e20c-u-boot.dtsi b/arch/arm/dts/rk3528-radxa-e20c-u-boot.dtsi new file mode 100644 index 00000000000..9c2f03a786c --- /dev/null +++ b/arch/arm/dts/rk3528-radxa-e20c-u-boot.dtsi @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk3528-u-boot.dtsi" + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + vmmc-supply = <&vcc_3v3>; + status = "okay"; +}; diff --git a/arch/arm/dts/rk3528-u-boot.dtsi b/arch/arm/dts/rk3528-u-boot.dtsi new file mode 100644 index 00000000000..eb6a55cd5c9 --- /dev/null +++ b/arch/arm/dts/rk3528-u-boot.dtsi @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rockchip-u-boot.dtsi" + +/ { + aliases { + mmc0 = &sdhci; + mmc1 = &sdmmc; + }; + + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci; + }; + + dmc { + compatible = "rockchip,rk3528-dmc"; + bootph-all; + }; + + soc { + rng: rng@ffc50000 { + compatible = "rockchip,rkrng"; + reg = <0x0 0xffc50000 0x0 0x200>; + }; + + otp: nvmem@ffce0000 { + compatible = "rockchip,rk3528-otp"; + reg = <0x0 0xffce0000 0x0 0x4000>; + }; + + sdmmc: mmc@ffc30000 { + compatible = "rockchip,rk3528-dw-mshc", + "rockchip,rk3288-dw-mshc"; + reg = <0x0 0xffc30000 0x0 0x4000>; + clocks = <&cru HCLK_SDMMC0>, <&cru CCLK_SRC_SDMMC0>; + clock-names = "biu", "ciu"; + fifo-depth = <0x100>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + max-frequency = <150000000>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4>, <&sdmmc_clk>, <&sdmmc_cmd>, + <&sdmmc_det>; + resets = <&cru SRST_H_SDMMC0>; + reset-names = "reset"; + rockchip,default-sample-phase = <90>; + status = "disabled"; + }; + }; +}; + +&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; +}; + +&gmac0_clk { + 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/arch/arm/dts/rk356x-u-boot.dtsi b/arch/arm/dts/rk356x-u-boot.dtsi index 24a976cf7e2..87186973953 100644 --- a/arch/arm/dts/rk356x-u-boot.dtsi +++ b/arch/arm/dts/rk356x-u-boot.dtsi @@ -21,11 +21,6 @@ bootph-all; }; - rng: rng@fe388000 { - compatible = "rockchip,cryptov2-rng"; - reg = <0x0 0xfe388000 0x0 0x2000>; - }; - otp: nvmem@fe38c000 { compatible = "rockchip,rk3568-otp"; reg = <0x0 0xfe38c000 0x0 0x4000>; @@ -121,6 +116,10 @@ bootph-all; }; +&rng { + status = "okay"; +}; + &sdhci { bootph-pre-ram; bootph-some-ram; diff --git a/arch/arm/dts/rk3576-roc-pc-u-boot.dtsi b/arch/arm/dts/rk3576-roc-pc-u-boot.dtsi new file mode 100644 index 00000000000..97240345ed4 --- /dev/null +++ b/arch/arm/dts/rk3576-roc-pc-u-boot.dtsi @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2023 Joshua Riek <jjriek@verizon.net> + * + */ + +#include "rk3576-u-boot.dtsi" + +&sdhci { + cap-mmc-highspeed; +}; diff --git a/arch/arm/dts/rk3576-u-boot.dtsi b/arch/arm/dts/rk3576-u-boot.dtsi new file mode 100644 index 00000000000..be99a48a630 --- /dev/null +++ b/arch/arm/dts/rk3576-u-boot.dtsi @@ -0,0 +1,131 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * (C) Copyright 2025 Rockchip Electronics Co., Ltd + */ + +#include "rockchip-u-boot.dtsi" + +/ { + chosen { + u-boot,spl-boot-order = "same-as-spl", &sdmmc, &sdhci; + }; + + dmc { + compatible = "rockchip,rk3576-dmc"; + bootph-all; + }; +}; + +&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_rstnout { + bootph-pre-ram; + bootph-some-ram; +}; + +&emmc_strb { + bootph-pre-ram; + bootph-some-ram; +}; + +&ioc_grf { + bootph-all; +}; + +&pcfg_pull_none { + bootph-all; +}; + +&pcfg_pull_up { + bootph-all; +}; + +&pcfg_pull_up_drv_level_2 { + bootph-pre-ram; + bootph-some-ram; +}; + +&pcfg_pull_up_drv_level_3 { + bootph-pre-ram; + bootph-some-ram; +}; + +&pinctrl { + bootph-all; +}; + +&pmu1_grf { + 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; +}; + +&sdmmc0_bus4 { + bootph-pre-ram; + bootph-some-ram; +}; + +&sdmmc0_clk { + bootph-pre-ram; + bootph-some-ram; +}; + +&sdmmc0_cmd { + bootph-pre-ram; + bootph-some-ram; +}; + +&sdmmc0_det { + bootph-pre-ram; + bootph-some-ram; +}; + +&sdmmc0_pwren { + bootph-pre-ram; + bootph-some-ram; +}; + +&sys_grf { + bootph-all; +}; + +&uart0 { + bootph-all; + clock-frequency = <24000000>; +}; + +&uart0m0_xfer { + bootph-pre-sram; + bootph-pre-ram; +}; + +&xin24m { + bootph-all; +}; diff --git a/arch/arm/dts/rk3588s-u-boot.dtsi b/arch/arm/dts/rk3588s-u-boot.dtsi index 8880d162b11..5eeb138f351 100644 --- a/arch/arm/dts/rk3588s-u-boot.dtsi +++ b/arch/arm/dts/rk3588s-u-boot.dtsi @@ -18,11 +18,6 @@ compatible = "rockchip,rk3588-dmc"; bootph-all; }; - - rng: rng@fe378000 { - compatible = "rockchip,trngv1"; - reg = <0x0 0xfe378000 0x0 0x200>; - }; }; #ifdef CONFIG_ROCKCHIP_SPI_IMAGE diff --git a/arch/arm/dts/sam9x60.dtsi b/arch/arm/dts/sam9x60.dtsi index 60de9140226..7631dfaa07f 100644 --- a/arch/arm/dts/sam9x60.dtsi +++ b/arch/arm/dts/sam9x60.dtsi @@ -70,6 +70,19 @@ #size-cells = <1>; ranges; + usb0: gadget@500000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "microchip,sam9x60-udc"; + reg = <0x500000 0x100000>, + <0xf803c000 0x400>; + clocks = <&pmc PMC_TYPE_PERIPHERAL 23>, <&pmc PMC_TYPE_CORE 8>; + clock-names = "pclk", "hclk"; + assigned-clocks = <&pmc PMC_TYPE_CORE 8>; + assigned-clock-rates = <480000000>; + status = "disabled"; + }; + usb1: usb@600000 { compatible = "atmel,at91rm9200-ohci", "usb-ohci"; reg = <0x00600000 0x100000>; diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi index 7b62fffb4ff..62191ff5d97 100644 --- a/arch/arm/dts/sama5d2.dtsi +++ b/arch/arm/dts/sama5d2.dtsi @@ -778,6 +778,7 @@ compatible = "atmel,at91sam9260-pit"; reg = <0xf8048030 0x10>; clocks = <&h32ck>; + bootph-all; }; watchdog: watchdog@f8048040 { diff --git a/arch/arm/dts/socfpga_agilex5-u-boot.dtsi b/arch/arm/dts/socfpga_agilex5-u-boot.dtsi index 8d6503dd091..874e71b5ca4 100644 --- a/arch/arm/dts/socfpga_agilex5-u-boot.dtsi +++ b/arch/arm/dts/socfpga_agilex5-u-boot.dtsi @@ -208,7 +208,8 @@ intel,offset-settings = /* DMIUSMCTCR */ <0x00000300 0x00000001 0x00000003>, - <0x00000300 0x00000003 0x00000003>; + <0x00000300 0x00000003 0x00000003>, + <0x00000308 0x00000004 0x0000001F>; bootph-all; }; @@ -218,7 +219,8 @@ intel,offset-settings = /* DMIUSMCTCR */ <0x00000300 0x00000001 0x00000003>, - <0x00000300 0x00000003 0x00000003>; + <0x00000300 0x00000003 0x00000003>, + <0x00000308 0x00000004 0x0000001F>; bootph-all; }; }; @@ -673,6 +675,17 @@ bootph-all; }; +&gpio1 { + /* Configure GPIO 1 pin 3 as output pin with value 0 during GPIO probe */ + portb: gpio-controller@0{ + sdio_sel { + gpio-hog; + gpios = <3 GPIO_ACTIVE_HIGH>; + output-low; + }; + }; +}; + &i2c0 { reset-names = "i2c"; }; diff --git a/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi index d7ab58267eb..8d7dc0945ab 100644 --- a/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi +++ b/arch/arm/dts/socfpga_agilex5_socdk-u-boot.dtsi @@ -25,34 +25,44 @@ /* * Both Memory base address and size default info is retrieved from HW setting. * Reconfiguration / Overwrite these info can be done with examples below. - */ - /* + * + * When LPDDR ECC is enabled, the last 1/8 of the memory region must + * be reserved for the Inline ECC buffer. + * * Example for memory size with 2GB: * memory { * reg = <0x0 0x80000000 0x0 0x80000000>; * }; - */ - /* + * * Example for memory size with 8GB: * memory { * reg = <0x0 0x80000000 0x0 0x80000000>, * <0x8 0x80000000 0x1 0x80000000>; * }; - */ - /* + * * Example for memory size with 32GB: * memory { * reg = <0x0 0x80000000 0x0 0x80000000>, * <0x8 0x80000000 0x7 0x80000000>; * }; - */ - /* + * * Example for memory size with 512GB: * memory { * reg = <0x0 0x80000000 0x0 0x80000000>, * <0x8 0x80000000 0x7 0x80000000>, * <0x88 0x00000000 0x78 0x00000000>; * }; + * + * Example for memory size with 2GB with LPDDR Inline ECC ON: + * memory { + * reg = <0x0 0x80000000 0x0 0x70000000>; + * }; + * + * Example for memory size with 8GB with LPDDR Inline ECC ON: + * memory { + * reg = <0x0 0x80000000 0x0 0x80000000>, + * <0x8 0x80000000 0x1 0x40000000>; + * }; */ chosen { diff --git a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi index 15306db6002..93a8e0697d6 100644 --- a/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi +++ b/arch/arm/dts/socfpga_soc64_fit-u-boot.dtsi @@ -106,8 +106,13 @@ arch = "arm64"; os = "linux"; compression = "none"; + #if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) + load = <0x86000000>; + entry = <0x86000000>; + #else load = <0x6000000>; entry = <0x6000000>; + #endif kernel_blob: blob-ext { filename = "Image"; }; diff --git a/arch/arm/include/asm/arch-rk3528/boot0.h b/arch/arm/include/asm/arch-rk3528/boot0.h new file mode 100644 index 00000000000..8ae46f25a87 --- /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 <asm/arch-rockchip/boot0.h> + +#endif diff --git a/arch/arm/include/asm/arch-rk3528/gpio.h b/arch/arm/include/asm/arch-rk3528/gpio.h new file mode 100644 index 00000000000..5516e649b80 --- /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 <asm/arch-rockchip/gpio.h> + +#endif diff --git a/arch/arm/include/asm/arch-rk3576/boot0.h b/arch/arm/include/asm/arch-rk3576/boot0.h new file mode 100644 index 00000000000..dea2b20252d --- /dev/null +++ b/arch/arm/include/asm/arch-rk3576/boot0.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2021 Rockchip Electronics Co., Ltd + */ + +#ifndef __ASM_ARCH_BOOT0_H__ +#define __ASM_ARCH_BOOT0_H__ + +#include <asm/arch-rockchip/boot0.h> + +#endif diff --git a/arch/arm/include/asm/arch-rk3576/gpio.h b/arch/arm/include/asm/arch-rk3576/gpio.h new file mode 100644 index 00000000000..b48c0a5cf84 --- /dev/null +++ b/arch/arm/include/asm/arch-rk3576/gpio.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2021 Rockchip Electronics Co., Ltd + */ + +#ifndef __ASM_ARCH_GPIO_H__ +#define __ASM_ARCH_GPIO_H__ + +#include <asm/arch-rockchip/gpio.h> + +#endif diff --git a/arch/arm/include/asm/arch-rockchip/clock.h b/arch/arm/include/asm/arch-rockchip/clock.h index 73e5283108b..3c204501f70 100644 --- 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, @@ -208,6 +215,26 @@ int rockchip_reset_bind(struct udevice *pdev, u32 reg_offset, u32 reg_number); int rockchip_reset_bind_lut(struct udevice *pdev, const int *lookup_table, u32 reg_offset, u32 reg_number); /* + * rk3528_reset_bind_lut() - Bind soft reset device as child of clock device + * using dedicated RK3528 lookup table + * + * @pdev: clock udevice + * @reg_offset: the first offset in cru for softreset registers + * @reg_number: the reg numbers of softreset registers + * Return: 0 success, or error value + */ +int rk3528_reset_bind_lut(struct udevice *pdev, u32 reg_offset, u32 reg_number); +/* + * rk3576_reset_bind_lut() - Bind soft reset device as child of clock device + * using dedicated RK3576 lookup table + * + * @pdev: clock udevice + * @reg_offset: the first offset in cru for softreset registers + * @reg_number: the reg numbers of softreset registers + * Return: 0 success, or error value + */ +int rk3576_reset_bind_lut(struct udevice *pdev, u32 reg_offset, u32 reg_number); +/* * rk3588_reset_bind_lut() - Bind soft reset device as child of clock device * using dedicated RK3588 lookup table * diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3528.h b/arch/arm/include/asm/arch-rockchip/cru_rk3528.h new file mode 100644 index 00000000000..b4020958a04 --- /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 <chenjh@rock-chips.com> + */ + +#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 */ diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3576.h b/arch/arm/include/asm/arch-rockchip/cru_rk3576.h new file mode 100644 index 00000000000..c51750beff2 --- /dev/null +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3576.h @@ -0,0 +1,491 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2020 Rockchip Electronics Co. Ltd. + * Author: Elaine Zhang <zhangqing@rock-chips.com> + */ + +#ifndef _ASM_ARCH_CRU_RK3576_H +#define _ASM_ARCH_CRU_RK3576_H + +#define MHz 1000000 +#define KHz 1000 +#define OSC_HZ (24 * MHz) + +#define CPU_PVTPLL_HZ (1008 * MHz) +#define LPLL_HZ (816 * MHz) +#define GPLL_HZ (1188 * MHz) +#define CPLL_HZ (1000 * MHz) +#define PPLL_HZ (1100 * MHz) +#define GMAC0_PTP_REFCLK_IN (24 * MHz) +#define GMAC1_PTP_REFCLK_IN (24 * MHz) + +/* RK3576 pll id */ +enum rk3576_pll_id { + BPLL, + LPLL, + DPLL, + CPLL, + GPLL, + VPLL, + AUPLL, + SPLL, + PPLL, + PLL_COUNT, +}; + +struct rk3576_clk_priv { + struct rk3576_cru *cru; + ulong ppll_hz; + ulong gpll_hz; + ulong cpll_hz; + ulong vpll_hz; + ulong aupll_hz; + ulong spll_hz; + ulong lpll_hz; + ulong bpll_hz; + ulong armclk_hz; + ulong armclk_enter_hz; + ulong armclk_init_hz; + bool sync_kernel; + bool set_armclk_rate; +}; + +struct rk3576_pll { + unsigned int con0; + unsigned int con1; + unsigned int con2; + unsigned int con3; + unsigned int con4; + unsigned int reserved0[3]; +}; + +struct rk3576_cru { + struct rk3576_pll pll[18]; + unsigned int reserved0[16];/* Address Offset: 0x0240 */ + unsigned int mode_con00;/* Address Offset: 0x0280 */ + unsigned int reserved1[31];/* Address Offset: 0x0284 */ + unsigned int clksel_con[181]; /* Address Offset: 0x0300 */ + unsigned int reserved2[139];/* Address Offset: 0x05d4 */ + unsigned int clkgate_con[80];/* Address Offset: 0x0800 */ + unsigned int reserved3[48];/* Address Offset: 0x0938 */ + unsigned int softrst_con[80];/* Address Offset: 0x0400 */ + unsigned int reserved4[48];/* Address Offset: 0x0b38 */ + unsigned int glb_cnt_th;/* Address Offset: 0x0c00 */ + unsigned int glb_rst_st;/* Address Offset: 0x0c04 */ + unsigned int glb_srst_fst;/* Address Offset: 0x0c08 */ + unsigned int glb_srsr_snd; /* Address Offset: 0x0c0c */ + unsigned int glb_rst_con;/* Address Offset: 0x0c10 */ + unsigned int reserved5[43];/* Address Offset: 0x0c14 */ + unsigned int smoth_divfree_con[3];/* Address Offset: 0x0cc0 */ + unsigned int fracdiv_high_con[4];/* Address Offset: 0x0ccc */ + unsigned int reserved8[32137];/* Address Offset: 0x0c38 */ + unsigned int pmuclksel_con[22]; /* Address Offset: 0x20300 */ + unsigned int reserved9[298];/* Address Offset: 0x20358 */ + unsigned int pmuclkgate_con[8]; /* Address Offset: 0x20800 */ + unsigned int reserved10[32440];/* Address Offset: 0x20820 */ + unsigned int litclksel_con[4]; /* Address Offset: 0x40300 */ +}; + +check_member(rk3576_cru, mode_con00, 0x280); +check_member(rk3576_cru, pmuclksel_con[1], 0x20304); + +struct pll_rate_table { + unsigned long rate; + unsigned int m; + unsigned int p; + unsigned int s; + unsigned int k; +}; + +#define RK3576_PHP_CRU_BASE 0x8000 +#define RK3576_PMU_CRU_BASE 0x20000 +#define RK3576_BIGCORE_CRU_BASE 0x38000 +#define RK3576_LITCORE_CRU_BASE 0x40000 +#define RK3576_CCI_CRU_BASE 0x48000 +#define RK3576_CRU_BASE 0x27200000 +#define RK3576_SCRU_BASE 0x27214000 + +#define RK3576_BIGCORE_GRF_BASE 0x2600C000 +#define RK3576_LITCORE_GRF_BASE 0x2600E000 +#define RK3576_CCI_GRF_BASE 0x26010000 + +#define RK3576_PLL_CON(x) ((x) * 0x4) +#define RK3576_MODE_CON0 0x280 +#define RK3576_BPLL_MODE_CON0 (RK3576_BIGCORE_CRU_BASE + 0x280) +#define RK3576_LPLL_MODE_CON0 (RK3576_LITCORE_CRU_BASE + 0x280) +#define RK3576_PPLL_MODE_CON0 (RK3576_PHP_CRU_BASE + 0x280) +#define RK3576_CLKSEL_CON(x) ((x) * 0x4 + 0x300) +#define RK3576_CLKGATE_CON(x) ((x) * 0x4 + 0x800) +#define RK3576_SOFTRST_CON(x) ((x) * 0x4 + 0xa00) +#define RK3576_GLB_CNT_TH 0xc00 +#define RK3576_GLB_SRST_FST 0xc08 +#define RK3576_GLB_SRST_SND 0xc0c +#define RK3576_GLB_RST_CON 0xc10 +#define RK3576_GLB_RST_ST 0xc04 +#define RK3576_SDIO_CON0 0xC24 +#define RK3576_SDIO_CON1 0xC28 +#define RK3576_SDMMC_CON0 0xC30 +#define RK3576_SDMMC_CON1 0xC34 + +#define RK3576_PHP_CLKSEL_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0x300) +#define RK3576_PHP_CLKGATE_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0x800) +#define RK3576_PHP_SOFTRST_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE + 0xa00) + +#define RK3576_PMU_PLL_CON(x) ((x) * 0x4 + RK3576_PHP_CRU_BASE) +#define RK3576_PMU_CLKSEL_CON(x) ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0x300) +#define RK3576_PMU_CLKGATE_CON(x) ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0x800) +#define RK3576_PMU_SOFTRST_CON(x) ((x) * 0x4 + RK3576_PMU_CRU_BASE + 0xa00) + +#define RK3576_CCI_CLKSEL_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0x300) +#define RK3576_CCI_CLKGATE_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0x800) +#define RK3576_CCI_SOFTRST_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE + 0xa00) + +#define RK3576_BPLL_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE) +#define RK3576_BIGCORE_CLKSEL_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0x300) +#define RK3576_BIGCORE_CLKGATE_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0x800) +#define RK3576_BIGCORE_SOFTRST_CON(x) ((x) * 0x4 + RK3576_BIGCORE_CRU_BASE + 0xa00) +#define RK3576_LPLL_CON(x) ((x) * 0x4 + RK3576_CCI_CRU_BASE) +#define RK3576_LITCORE_CLKSEL_CON(x) ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0x300) +#define RK3576_LITCORE_CLKGATE_CON(x) ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0x800) +#define RK3576_LITCORE_SOFTRST_CON(x) ((x) * 0x4 + RK3576_LITCORE_CRU_BASE + 0xa00) + +enum { + /* CRU_CLK_SEL8_CON */ + PCLK_TOP_SEL_SHIFT = 7, + PCLK_TOP_SEL_MASK = 3 << PCLK_TOP_SEL_SHIFT, + PCLK_TOP_SEL_100M = 0, + PCLK_TOP_SEL_50M, + PCLK_TOP_SEL_OSC, + + /* CRU_CLK_SEL9_CON */ + ACLK_TOP_SEL_SHIFT = 5, + ACLK_TOP_SEL_MASK = 3 << ACLK_TOP_SEL_SHIFT, + ACLK_TOP_SEL_GPLL = 0, + ACLK_TOP_SEL_CPLL, + ACLK_TOP_SEL_AUPLL, + ACLK_TOP_DIV_SHIFT = 0, + ACLK_TOP_DIV_MASK = 0x1f << ACLK_TOP_DIV_SHIFT, + + /* CRU_CLK_SEL10_CON */ + ACLK_TOP_MID_SEL_SHIFT = 5, + ACLK_TOP_MID_SEL_MASK = 1 << ACLK_TOP_MID_SEL_SHIFT, + ACLK_TOP_MID_SEL_GPLL = 0, + ACLK_TOP_MID_SEL_CPLL, + ACLK_TOP_MID_DIV_SHIFT = 0, + ACLK_TOP_MID_DIV_MASK = 0x1f << ACLK_TOP_MID_DIV_SHIFT, + + /* CRU_CLK_SEL19_CON */ + HCLK_TOP_SEL_SHIFT = 2, + HCLK_TOP_SEL_MASK = 3 << HCLK_TOP_SEL_SHIFT, + HCLK_TOP_SEL_200M = 0, + HCLK_TOP_SEL_100M, + HCLK_TOP_SEL_50M, + HCLK_TOP_SEL_OSC, + + /* CRU_CLK_SEL25_CON */ + CLK_UART_FRAC_NUMERATOR_SHIFT = 16, + CLK_UART_FRAC_NUMERATOR_MASK = 0xffff << 16, + CLK_UART_FRAC_DENOMINATOR_SHIFT = 0, + CLK_UART_FRAC_DENOMINATOR_MASK = 0xffff, + + /* CRU_CLK_SEL26_CON */ + CLK_UART_SRC_SEL_SHIFT = 0, + CLK_UART_SRC_SEL_MASK = 0x3 << CLK_UART_SRC_SEL_SHIFT, + CLK_UART_SRC_SEL_GPLL = 0, + CLK_UART_SRC_SEL_CPLL, + CLK_UART_SRC_SEL_AUPLL, + CLK_UART_SRC_SEL_OSC, + + /* CRU_CLK_SEL27_CON */ + CLK_UART1_SRC_SEL_SHIFT = 13, + CLK_UART1_SRC_SEL_MASK = 0x7 << CLK_UART1_SRC_SEL_SHIFT, + CLK_UART1_SRC_DIV_SHIFT = 5, + CLK_UART1_SRC_DIV_MASK = 0xff << CLK_UART1_SRC_DIV_SHIFT, + + /* CRU_CLK_SEL30_CON */ + CLK_GMAC0_125M_DIV_SHIFT = 10, + CLK_GMAC0_125M_DIV_MASK = 0x1f << CLK_GMAC0_125M_DIV_SHIFT, + + /* CRU_CLK_SEL31_CON */ + CLK_GMAC1_125M_DIV_SHIFT = 0, + CLK_GMAC1_125M_DIV_MASK = 0x1f << CLK_GMAC1_125M_DIV_SHIFT, + + /* CRU_CLK_SEL33_CON */ + REF_CLK0_OUT_PLL_SEL_SHIFT = 8, + REF_CLK0_OUT_PLL_SEL_MASK = 7 << REF_CLK0_OUT_PLL_SEL_SHIFT, + REF_CLK0_OUT_PLL_SEL_GPLL = 0, + REF_CLK0_OUT_PLL_SEL_CPLL, + REF_CLK0_OUT_PLL_SEL_SPLL, + REF_CLK0_OUT_PLL_SEL_AUPLL, + REF_CLK0_OUT_PLL_SEL_LPLL, + REF_CLK0_OUT_PLL_SEL_OSC, + REF_CLK0_OUT_PLL_DIV_SHIFT = 0, + REF_CLK0_OUT_PLL_DIV_MASK = 0xff << REF_CLK0_OUT_PLL_DIV_SHIFT, + + /* CRU_CLK_SEL55_CON */ + ACLK_BUS_ROOT_SEL_SHIFT = 9, + ACLK_BUS_ROOT_SEL_MASK = 1 << ACLK_BUS_ROOT_SEL_SHIFT, + ACLK_BUS_ROOT_SEL_GPLL = 0, + ACLK_BUS_ROOT_SEL_CPLL, + ACLK_BUS_ROOT_DIV_SHIFT = 4, + ACLK_BUS_ROOT_DIV_MASK = 0x1f << ACLK_BUS_ROOT_DIV_SHIFT, + PCLK_BUS_ROOT_SEL_SHIFT = 2, + PCLK_BUS_ROOT_SEL_MASK = 3 << PCLK_BUS_ROOT_SEL_SHIFT, + PCLK_BUS_ROOT_SEL_100M = 0, + PCLK_BUS_ROOT_SEL_50M, + PCLK_BUS_ROOT_SEL_OSC, + HCLK_BUS_ROOT_SEL_SHIFT = 0, + HCLK_BUS_ROOT_SEL_MASK = 3 << HCLK_BUS_ROOT_SEL_SHIFT, + HCLK_BUS_ROOT_SEL_200M = 0, + HCLK_BUS_ROOT_SEL_100M, + HCLK_BUS_ROOT_SEL_50M, + HCLK_BUS_ROOT_SEL_OSC, + + /* CRU_CLK_SEL57_CON */ + CLK_I2C8_SEL_SHIFT = 14, + CLK_I2C8_SEL_MASK = 3 << CLK_I2C8_SEL_SHIFT, + CLK_I2C7_SEL_SHIFT = 12, + CLK_I2C7_SEL_MASK = 3 << CLK_I2C7_SEL_SHIFT, + CLK_I2C6_SEL_SHIFT = 10, + CLK_I2C6_SEL_MASK = 3 << CLK_I2C6_SEL_SHIFT, + CLK_I2C5_SEL_SHIFT = 8, + CLK_I2C5_SEL_MASK = 3 << CLK_I2C5_SEL_SHIFT, + CLK_I2C4_SEL_SHIFT = 6, + CLK_I2C4_SEL_MASK = 3 << CLK_I2C4_SEL_SHIFT, + CLK_I2C3_SEL_SHIFT = 4, + CLK_I2C3_SEL_MASK = 3 << CLK_I2C3_SEL_SHIFT, + CLK_I2C2_SEL_SHIFT = 2, + CLK_I2C2_SEL_MASK = 3 << CLK_I2C2_SEL_SHIFT, + CLK_I2C1_SEL_SHIFT = 0, + CLK_I2C1_SEL_MASK = 3 << CLK_I2C1_SEL_SHIFT, + CLK_I2C_SEL_200M = 0, + CLK_I2C_SEL_100M, + CLK_I2C_SEL_50M, + CLK_I2C_SEL_OSC, + + /* CRU_CLK_SEL58_CON */ + CLK_SARADC_SEL_SHIFT = 12, + CLK_SARADC_SEL_MASK = 0x1 << CLK_SARADC_SEL_SHIFT, + CLK_SARADC_SEL_GPLL = 0, + CLK_SARADC_SEL_OSC, + CLK_SARADC_DIV_SHIFT = 4, + CLK_SARADC_DIV_MASK = 0xff << CLK_SARADC_DIV_SHIFT, + CLK_I2C9_SEL_SHIFT = 0, + CLK_I2C9_SEL_MASK = 3 << CLK_I2C9_SEL_SHIFT, + + /* CRU_CLK_SEL59_CON */ + CLK_TSADC_DIV_SHIFT = 0, + CLK_TSADC_DIV_MASK = 0xff << CLK_TSADC_DIV_SHIFT, + + /* CRU_CLK_SEL60_CON */ + CLK_UART_SEL_SHIFT = 8, + CLK_UART_SEL_MASK = 7 << CLK_UART_SEL_SHIFT, + CLK_UART_SEL_GPLL = 0, + CLK_UART_SEL_CPLL, + CLK_UART_SEL_AUPLL, + CLK_UART_SEL_OSC, + CLK_UART_SEL_FRAC0, + CLK_UART_SEL_FRAC1, + CLK_UART_SEL_FRAC2, + CLK_UART_DIV_SHIFT = 0, + CLK_UART_DIV_MASK = 0xff << CLK_UART_DIV_SHIFT, + + /* CRU_CLK_SEL70_CON */ + CLK_SPI0_SEL_SHIFT = 13, + CLK_SPI0_SEL_MASK = 3 << CLK_SPI0_SEL_SHIFT, + CLK_SPI_SEL_200M = 0, + CLK_SPI_SEL_100M, + CLK_SPI_SEL_50M, + CLK_SPI_SEL_OSC, + + /* CRU_CLK_SEL71_CON */ + CLK_PWM1_SEL_SHIFT = 8, + CLK_PWM1_SEL_MASK = 3 << CLK_PWM1_SEL_SHIFT, + CLK_SPI4_SEL_SHIFT = 6, + CLK_SPI4_SEL_MASK = 3 << CLK_SPI4_SEL_SHIFT, + CLK_SPI3_SEL_SHIFT = 4, + CLK_SPI3_SEL_MASK = 3 << CLK_SPI3_SEL_SHIFT, + CLK_SPI2_SEL_SHIFT = 2, + CLK_SPI2_SEL_MASK = 3 << CLK_SPI2_SEL_SHIFT, + CLK_SPI1_SEL_SHIFT = 0, + CLK_SPI1_SEL_MASK = 3 << CLK_SPI1_SEL_SHIFT, + CLK_PWM_SEL_100M = 0, + CLK_PWM_SEL_50M, + CLK_PWM_SEL_OSC, + + /* CRU_CLK_SEL72_CON */ + DCLK_DECOM_SEL_SHIFT = 5, + DCLK_DECOM_SEL_MASK = 1 << DCLK_DECOM_SEL_SHIFT, + DCLK_DECOM_SEL_GPLL = 0, + DCLK_DECOM_SEL_SPLL, + DCLK_DECOM_DIV_SHIFT = 0, + DCLK_DECOM_DIV_MASK = 0x1f << DCLK_DECOM_DIV_SHIFT, + + /* CRU_CLK_SEL74_CON */ + CLK_PWM2_SEL_SHIFT = 6, + CLK_PWM2_SEL_MASK = 3 << CLK_PWM2_SEL_SHIFT, + + /* CRU_CLK_SEL89_CON */ + CCLK_EMMC_SEL_SHIFT = 14, + CCLK_EMMC_SEL_MASK = 3 << CCLK_EMMC_SEL_SHIFT, + CCLK_EMMC_SEL_GPLL = 0, + CCLK_EMMC_SEL_CPLL, + CCLK_EMMC_SEL_OSC, + CCLK_EMMC_DIV_SHIFT = 8, + CCLK_EMMC_DIV_MASK = 0x3f << CCLK_EMMC_DIV_SHIFT, + SCLK_FSPI_SEL_SHIFT = 6, + SCLK_FSPI_SEL_MASK = 3 << SCLK_FSPI_SEL_SHIFT, + SCLK_FSPI_SEL_GPLL = 0, + SCLK_FSPI_SEL_CPLL, + SCLK_FSPI_SEL_OSC, + SCLK_FSPI_DIV_SHIFT = 0, + SCLK_FSPI_DIV_MASK = 0x3f << SCLK_FSPI_DIV_SHIFT, + + /* CRU_CLK_SEL90_CON */ + BCLK_EMMC_SEL_SHIFT = 0, + BCLK_EMMC_SEL_MASK = 3 << BCLK_EMMC_SEL_SHIFT, + BCLK_EMMC_SEL_200M = 0, + BCLK_EMMC_SEL_100M, + BCLK_EMMC_SEL_50M, + BCLK_EMMC_SEL_OSC, + + /* CRU_CLK_SEL104_CON */ + CLK_GMAC1_PTP_SEL_SHIFT = 13, + CLK_GMAC1_PTP_SEL_MASK = 3 << CLK_GMAC1_PTP_SEL_SHIFT, + CLK_GMAC1_PTP_SEL_GPLL = 0, + CLK_GMAC1_PTP_SEL_CPLL, + CLK_GMAC1_PTP_SEL_REFIN, + CLK_GMAC1_PTP_DIV_SHIFT = 8, + CLK_GMAC1_PTP_DIV_MASK = 0x1f << CLK_GMAC1_PTP_DIV_SHIFT, + CCLK_SDIO_SRC_SEL_SHIFT = 6, + CCLK_SDIO_SRC_SEL_MASK = 3 << CCLK_SDIO_SRC_SEL_SHIFT, + CCLK_SDIO_SRC_SEL_GPLL = 0, + CCLK_SDIO_SRC_SEL_CPLL, + CCLK_SDIO_SRC_SEL_OSC, + CCLK_SDIO_SRC_DIV_SHIFT = 0, + CCLK_SDIO_SRC_DIV_MASK = 0x3f << CCLK_SDIO_SRC_DIV_SHIFT, + + /* CRU_CLK_SEL105_CON */ + CCLK_SDMMC0_SRC_SEL_SHIFT = 13, + CCLK_SDMMC0_SRC_SEL_MASK = 3 << CCLK_SDMMC0_SRC_SEL_SHIFT, + CCLK_SDMMC0_SRC_SEL_GPLL = 0, + CCLK_SDMMC0_SRC_SEL_CPLL, + CCLK_SDMMC0_SRC_SEL_OSC, + CCLK_SDMMC0_SRC_DIV_SHIFT = 7, + CCLK_SDMMC0_SRC_DIV_MASK = 0x3f << CCLK_SDMMC0_SRC_DIV_SHIFT, + CLK_GMAC0_PTP_SEL_SHIFT = 5, + CLK_GMAC0_PTP_SEL_MASK = 3 << CLK_GMAC0_PTP_SEL_SHIFT, + CLK_GMAC0_PTP_SEL_GPLL = 0, + CLK_GMAC0_PTP_SEL_CPLL, + CLK_GMAC0_PTP_SEL_REFIN, + CLK_GMAC0_PTP_DIV_SHIFT = 0, + CLK_GMAC0_PTP_DIV_MASK = 0x1f << CLK_GMAC0_PTP_DIV_SHIFT, + + /* CRU_CLK_SEL123_CON */ + DCLK_EBC_SEL_SHIFT = 12, + DCLK_EBC_SEL_MASK = 7 << DCLK_EBC_SEL_SHIFT, + DCLK_EBC_SEL_GPLL = 0, + DCLK_EBC_SEL_CPLL, + DCLK_EBC_SEL_VPLL, + DCLK_EBC_SEL_AUPLL, + DCLK_EBC_SEL_LPLL, + DCLK_EBC_SEL_FRAC_SRC, + DCLK_EBC_SEL_OSC, + DCLK_EBC_DIV_SHIFT = 3, + DCLK_EBC_DIV_MASK = 0x1ff << DCLK_EBC_DIV_SHIFT, + DCLK_EBC_FRAC_SRC_SEL_SHIFT = 0, + DCLK_EBC_FRAC_SRC_SEL_MASK = 7 << DCLK_EBC_FRAC_SRC_SEL_SHIFT, + DCLK_EBC_FRAC_SRC_SEL_GPLL = 0, + DCLK_EBC_FRAC_SRC_SEL_CPLL, + DCLK_EBC_FRAC_SRC_SEL_VPLL, + DCLK_EBC_FRAC_SRC_SEL_AUPLL, + DCLK_EBC_FRAC_SRC_SEL_OSC, + + /* CRU_CLK_SEL144_CON */ + PCLK_VOP_ROOT_SEL_SHIFT = 12, + PCLK_VOP_ROOT_SEL_MASK = 3 << PCLK_VOP_ROOT_SEL_SHIFT, + PCLK_VOP_ROOT_SEL_100M = 0, + PCLK_VOP_ROOT_SEL_50M, + PCLK_VOP_ROOT_SEL_OSC, + HCLK_VOP_ROOT_SEL_SHIFT = 10, + HCLK_VOP_ROOT_SEL_MASK = 3 << HCLK_VOP_ROOT_SEL_SHIFT, + HCLK_VOP_ROOT_SEL_200M = 0, + HCLK_VOP_ROOT_SEL_100M, + HCLK_VOP_ROOT_SEL_50M, + HCLK_VOP_ROOT_SEL_OSC, + ACLK_VOP_ROOT_SEL_SHIFT = 5, + ACLK_VOP_ROOT_SEL_MASK = 7 << ACLK_VOP_ROOT_SEL_SHIFT, + ACLK_VOP_ROOT_SEL_GPLL = 0, + ACLK_VOP_ROOT_SEL_CPLL, + ACLK_VOP_ROOT_SEL_AUPLL, + ACLK_VOP_ROOT_SEL_SPLL, + ACLK_VOP_ROOT_SEL_LPLL, + ACLK_VOP_ROOT_DIV_SHIFT = 0, + ACLK_VOP_ROOT_DIV_MASK = 0x1f << ACLK_VOP_ROOT_DIV_SHIFT, + + /* CRU_CLK_SEL145_CON */ + DCLK0_VOP_SRC_SEL_SHIFT = 8, + DCLK0_VOP_SRC_SEL_MASK = 7 << DCLK0_VOP_SRC_SEL_SHIFT, + DCLK_VOP_SRC_SEL_GPLL = 0, + DCLK_VOP_SRC_SEL_CPLL, + DCLK_VOP_SRC_SEL_VPLL, + DCLK_VOP_SRC_SEL_BPLL, + DCLK_VOP_SRC_SEL_LPLL, + DCLK0_VOP_SRC_DIV_SHIFT = 0, + DCLK0_VOP_SRC_DIV_MASK = 0xff << DCLK0_VOP_SRC_DIV_SHIFT, + + /* CRU_CLK_SEL147_CON */ + DCLK2_VOP_SEL_SHIFT = 13, + DCLK2_VOP_SEL_MASK = 1 << DCLK2_VOP_SEL_SHIFT, + DCLK1_VOP_SEL_SHIFT = 12, + DCLK1_VOP_SEL_MASK = 1 << DCLK1_VOP_SEL_SHIFT, + DCLK0_VOP_SEL_SHIFT = 11, + DCLK0_VOP_SEL_MASK = 1 << DCLK0_VOP_SEL_SHIFT, + + /* CRU_CLK_SEL149_CON */ + ACLK_VO0_ROOT_SEL_SHIFT = 5, + ACLK_VO0_ROOT_SEL_MASK = 3 << ACLK_VO0_ROOT_SEL_SHIFT, + ACLK_VO0_ROOT_SEL_GPLL = 0, + ACLK_VO0_ROOT_SEL_CPLL, + ACLK_VO0_ROOT_SEL_LPLL, + ACLK_VO0_ROOT_SEL_BPLL, + ACLK_VO0_ROOT_DIV_SHIFT = 0, + ACLK_VO0_ROOT_DIV_MASK = 0x1f << ACLK_VO0_ROOT_DIV_SHIFT, + + /* CRU_CLK_SEL151_CON */ + CLK_DSIHOST0_SEL_SHIFT = 7, + CLK_DSIHOST0_SEL_MASK = 7 << CLK_DSIHOST0_SEL_SHIFT, + CLK_DSIHOST0_SEL_GPLL = 0, + CLK_DSIHOST0_SEL_CPLL, + CLK_DSIHOST0_SEL_SPLL, + CLK_DSIHOST0_SEL_VPLL, + CLK_DSIHOST0_SEL_BPLL, + CLK_DSIHOST0_SEL_LPLL, + CLK_DSIHOST0_DIV_SHIFT = 0, + CLK_DSIHOST0_DIV_MASK = 0x7f << CLK_DSIHOST0_DIV_SHIFT, + + /* PMUCRU_CLK_SEL5_CON */ + CLK_PMU1PWM_SEL_SHIFT = 2, + CLK_PMU1PWM_SEL_MASK = 3 << CLK_PMU1PWM_SEL_SHIFT, + + /* PMUCRU_CLK_SEL6_CON */ + CLK_I2C0_SEL_SHIFT = 7, + CLK_I2C0_SEL_MASK = 3 << CLK_I2C0_SEL_SHIFT, + + /* PMUCRU_CLK_SEL8_CON */ + CLK_UART1_SEL_SHIFT = 0, + CLK_UART1_SEL_MASK = 1 << CLK_UART1_SEL_SHIFT, + CLK_UART1_SEL_TOP = 0, + CLK_UART1_SEL_OSC, + + /* LITCRU_CLK_SEL0_CON */ + CLK_LITCORE_SEL_SHIFT = 12, + CLK_LITCORE_SEL_MASK = 3 << CLK_LITCORE_SEL_SHIFT, + CLK_LITCORE_SEL_LPLL = 0, + CLK_LITCORE_SEL_GPLL, + CLK_LITCORE_SEL_PVTPLL, + CLK_LITCORE_DIV_SHIFT = 7, + CLK_LITCORE_DIV_MASK = 0x1f << CLK_LITCORE_DIV_SHIFT, + +}; +#endif diff --git a/arch/arm/mach-k3/r5/am62px/clk-data.c b/arch/arm/mach-k3/r5/am62px/clk-data.c index 4b9892fe051..bc62d1d0d08 100644 --- a/arch/arm/mach-k3/r5/am62px/clk-data.c +++ b/arch/arm/mach-k3/r5/am62px/clk-data.c @@ -59,7 +59,7 @@ static const char * const sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk_parents[] = { static const char * const clkout0_ctrl_out0_parents[] = { "hsdiv4_16fft_main_2_hsdivout1_clk", - "hsdiv4_16fft_main_2_hsdivout1_clk", + "hsdiv4_16fft_main_2_hsdivout1_clk10", }; static const char * const main_emmcsd0_refclk_sel_out0_parents[] = { @@ -193,6 +193,7 @@ static const struct clk_data clk_list[] = { CLK_DIV("hsdiv4_16fft_main_1_hsdivout2_clk", "pllfracf2_ssmod_16fft_main_1_foutvcop_clk", 0x681088, 0, 7, 0, 0), CLK_DIV("hsdiv4_16fft_main_1_hsdivout3_clk", "pllfracf2_ssmod_16fft_main_1_foutvcop_clk", 0x68108c, 0, 7, 0, 0), CLK_DIV("hsdiv4_16fft_main_2_hsdivout1_clk", "pllfracf2_ssmod_16fft_main_2_foutvcop_clk", 0x682084, 0, 7, 0, 0), + CLK_DIV("hsdiv4_16fft_main_2_hsdivout1_clk10", "pllfracf2_ssmod_16fft_main_2_foutvcop_clk", 0x682084, 0, 7, 0, 0), CLK_DIV("hsdiv4_16fft_main_2_hsdivout2_clk", "pllfracf2_ssmod_16fft_main_2_foutvcop_clk", 0x682088, 0, 7, 0, 0), CLK_DIV("hsdiv4_16fft_mcu_0_hsdivout0_clk", "pllfracf2_ssmod_16fft_mcu_0_foutvcop_clk", 0x4040080, 0, 7, 0, 0), CLK_MUX_PLLCTRL("sam62_pll_ctrl_wrap_main_0_sysclkout_clk", sam62_pll_ctrl_wrap_main_0_sysclkout_clk_parents, 2, 0x410000, 0), @@ -281,7 +282,7 @@ static const struct dev_clk soc_dev_clk_data[] = { DEV_CLK(146, 5, "sam62_pll_ctrl_wrap_main_0_chip_div1_clk_clk"), DEV_CLK(157, 36, "clkout0_ctrl_out0"), DEV_CLK(157, 37, "hsdiv4_16fft_main_2_hsdivout1_clk"), - DEV_CLK(157, 38, "hsdiv4_16fft_main_2_hsdivout1_clk"), + DEV_CLK(157, 38, "hsdiv4_16fft_main_2_hsdivout1_clk10"), DEV_CLK(157, 40, "sam62_pll_ctrl_wrap_main_0_chip_div1_clk_clk"), DEV_CLK(157, 54, "mshsi2c_main_0_porscl"), DEV_CLK(157, 91, "sam62_pll_ctrl_wrap_mcu_0_sysclkout_clk"), diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig index c6e347b8d9d..9210877a4a4 100644 --- a/arch/arm/mach-rockchip/Kconfig +++ b/arch/arm/mach-rockchip/Kconfig @@ -15,7 +15,9 @@ config ROCKCHIP_PX30 select TPL_SERIAL select DEBUG_UART_BOARD_INIT imply ROCKCHIP_COMMON_BOARD + imply ROCKCHIP_COMMON_STACK_ADDR imply SPL_ROCKCHIP_COMMON_BOARD + imply TPL_LIBGENERIC_SUPPORT imply ARMV8_CRYPTO imply ARMV8_SET_SMPEN help @@ -176,6 +178,8 @@ config ROCKCHIP_RK3308 imply OF_UPSTREAM imply RNG_ROCKCHIP imply ROCKCHIP_COMMON_BOARD + imply ROCKCHIP_COMMON_STACK_ADDR + imply ROCKCHIP_EXTERNAL_TPL imply ROCKCHIP_OTP imply SPL_CLK imply SPL_DM_SEQ_ALIAS @@ -197,7 +201,6 @@ config ROCKCHIP_RK3328 select SUPPORT_SPL select SPL select SUPPORT_TPL - select TPL select TPL_HAVE_INIT_STACK if TPL imply ARMV8_CRYPTO imply ARMV8_SET_SMPEN @@ -208,11 +211,14 @@ config ROCKCHIP_RK3328 imply OF_UPSTREAM imply PRE_CONSOLE_BUFFER imply ROCKCHIP_COMMON_BOARD + imply ROCKCHIP_COMMON_STACK_ADDR imply ROCKCHIP_EFUSE imply ROCKCHIP_SDRAM_COMMON imply SPL_ROCKCHIP_COMMON_BOARD imply SPL_SEPARATE_BSS imply SPL_SERIAL + imply TPL if !ROCKCHIP_EXTERNAL_TPL + imply TPL_ROCKCHIP_COMMON_BOARD imply TPL_SERIAL help The Rockchip RK3328 is a ARM-based SoC with a quad-core Cortex-A53. @@ -285,6 +291,7 @@ config ROCKCHIP_RK3399 imply PRE_CONSOLE_BUFFER imply RNG_ROCKCHIP imply ROCKCHIP_COMMON_BOARD + imply ROCKCHIP_COMMON_STACK_ADDR imply ROCKCHIP_EFUSE imply ROCKCHIP_SDRAM_COMMON imply SPL_DM_SEQ_ALIAS @@ -312,6 +319,56 @@ 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 + imply SYSRESET_PSCI if SPL_ATF + help + The Rockchip RK3528 is a ARM-based SoC with a quad-core Cortex-A53. + config ROCKCHIP_RK3568 bool "Support Rockchip RK3568" select ARM64 @@ -334,6 +391,8 @@ config ROCKCHIP_RK3568 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_NO_PLATFORM_PARAM if SPL_ATF imply SPL_MMC_HS200_SUPPORT if SPL_MMC && MMC_HS200_SUPPORT @@ -344,6 +403,56 @@ config ROCKCHIP_RK3568 and video codec support. Peripherals include Gigabit Ethernet, USB2 host and OTG, SDIO, I2S, UARTs, SPI, I2C and PWMs. +config ROCKCHIP_RK3576 + bool "Support Rockchip RK3576" + 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 RK3576 is a ARM-based SoC with quad-core Cortex-A72 and + and quad-core Cortex-A53. + config ROCKCHIP_RK3588 bool "Support Rockchip RK3588" select ARM64 @@ -367,6 +476,8 @@ config ROCKCHIP_RK3588 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 SCMI_FIRMWARE imply SPL_ATF_NO_PLATFORM_PARAM if SPL_ATF @@ -493,7 +604,6 @@ config TPL_ROCKCHIP_COMMON_BOARD config ROCKCHIP_EXTERNAL_TPL bool "Use external TPL binary" - default y if ROCKCHIP_RK3308 || ROCKCHIP_RK3568 || ROCKCHIP_RK3588 help Some Rockchip SoCs require an external TPL to initialize DRAM. Enable this option and build with ROCKCHIP_TPL=/path/to/ddr.bin to @@ -603,17 +713,17 @@ config LNX_KRNL_IMG_TEXT_OFFSET_BASE config ROCKCHIP_COMMON_STACK_ADDR bool depends on SPL_SHARES_INIT_SP_ADDR + depends on TPL || ROCKCHIP_EXTERNAL_TPL select HAS_CUSTOM_SYS_INIT_SP_ADDR imply SPL_LIBCOMMON_SUPPORT if SPL imply SPL_LIBGENERIC_SUPPORT if SPL imply SPL_ROCKCHIP_COMMON_BOARD if SPL imply SPL_SYS_MALLOC_F if SPL imply SPL_SYS_MALLOC_SIMPLE if SPL - imply TPL_LIBCOMMON_SUPPORT if TPL - imply TPL_LIBGENERIC_SUPPORT if TPL - imply TPL_ROCKCHIP_COMMON_BOARD if TPL - imply TPL_SYS_MALLOC_F if TPL - imply TPL_SYS_MALLOC_SIMPLE if TPL + imply TPL_LIBCOMMON_SUPPORT if TPL && TPL_ROCKCHIP_COMMON_BOARD + imply TPL_LIBGENERIC_SUPPORT if TPL && TPL_ROCKCHIP_COMMON_BOARD + imply TPL_SYS_MALLOC_F if TPL && TPL_ROCKCHIP_COMMON_BOARD + imply TPL_SYS_MALLOC_SIMPLE if TPL && TPL_ROCKCHIP_COMMON_BOARD config NR_DRAM_BANKS default 10 if ROCKCHIP_EXTERNAL_TPL @@ -629,7 +739,9 @@ source "arch/arm/mach-rockchip/rk3308/Kconfig" 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/rk3576/Kconfig" source "arch/arm/mach-rockchip/rk3588/Kconfig" source "arch/arm/mach-rockchip/rv1108/Kconfig" source "arch/arm/mach-rockchip/rv1126/Kconfig" @@ -637,40 +749,64 @@ source "arch/arm/mach-rockchip/rv1126/Kconfig" if ROCKCHIP_COMMON_STACK_ADDR && SPL_SHARES_INIT_SP_ADDR config CUSTOM_SYS_INIT_SP_ADDR - default 0x3f00000 + default 0x63f00000 if SPL_TEXT_BASE = 0x60000000 + default 0x43f00000 if SPL_TEXT_BASE = 0x40000000 + default 0x03f00000 if SPL_TEXT_BASE = 0x00000000 config SYS_MALLOC_F_LEN - default 0x10000 if CUSTOM_SYS_INIT_SP_ADDR = 0x3f00000 + default 0x10000 if CUSTOM_SYS_INIT_SP_ADDR = 0x63f00000 + default 0x10000 if CUSTOM_SYS_INIT_SP_ADDR = 0x43f00000 + default 0x10000 if CUSTOM_SYS_INIT_SP_ADDR = 0x03f00000 config SPL_SYS_MALLOC_F_LEN - default 0x8000 if CUSTOM_SYS_INIT_SP_ADDR = 0x3f00000 + default 0x8000 if CUSTOM_SYS_INIT_SP_ADDR = 0x63f00000 + default 0x8000 if CUSTOM_SYS_INIT_SP_ADDR = 0x43f00000 + default 0x8000 if CUSTOM_SYS_INIT_SP_ADDR = 0x03f00000 config TPL_SYS_MALLOC_F_LEN - default 0x4000 if CUSTOM_SYS_INIT_SP_ADDR = 0x3f00000 + default 0x0800 if CUSTOM_SYS_INIT_SP_ADDR = 0x63f00000 + default 0x4000 if CUSTOM_SYS_INIT_SP_ADDR = 0x43f00000 + default 0x4000 if CUSTOM_SYS_INIT_SP_ADDR = 0x03f00000 config TEXT_BASE - default 0x00200000 if ARM64 + default 0x60200000 if SPL_TEXT_BASE = 0x60000000 + default 0x40200000 if SPL_TEXT_BASE = 0x40000000 + default 0x00200000 if SPL_TEXT_BASE = 0x00000000 config SPL_TEXT_BASE - default 0x0 if ARM64 + default 0x60000000 if ROCKCHIP_RK3036 || ROCKCHIP_RK3066 || \ + ROCKCHIP_RK3128 || ROCKCHIP_RK3188 || \ + ROCKCHIP_RK322X || ROCKCHIP_RV1108 + default 0x40000000 if ROCKCHIP_RK3576 + default 0x00000000 config SPL_HAS_BSS_LINKER_SECTION default y if ARM64 config SPL_BSS_START_ADDR - default 0x3f80000 + default 0x63f80000 if SPL_TEXT_BASE = 0x60000000 + default 0x43f80000 if SPL_TEXT_BASE = 0x40000000 + default 0x03f80000 if SPL_TEXT_BASE = 0x00000000 config SPL_BSS_MAX_SIZE - default 0x8000 if SPL_BSS_START_ADDR = 0x3f80000 + default 0x8000 if SPL_BSS_START_ADDR = 0x63f80000 + default 0x8000 if SPL_BSS_START_ADDR = 0x43f80000 + default 0x8000 if SPL_BSS_START_ADDR = 0x03f80000 config SPL_STACK_R - default y if CUSTOM_SYS_INIT_SP_ADDR = 0x3f00000 + default y if CUSTOM_SYS_INIT_SP_ADDR = 0x63f00000 + default y if CUSTOM_SYS_INIT_SP_ADDR = 0x43f00000 + default y if CUSTOM_SYS_INIT_SP_ADDR = 0x03f00000 config SPL_STACK_R_ADDR - default 0x3e00000 if CUSTOM_SYS_INIT_SP_ADDR = 0x3f00000 + default 0x63e00000 if CUSTOM_SYS_INIT_SP_ADDR = 0x63f00000 + default 0x43e00000 if CUSTOM_SYS_INIT_SP_ADDR = 0x43f00000 + default 0x03e00000 if CUSTOM_SYS_INIT_SP_ADDR = 0x03f00000 config SPL_STACK_R_MALLOC_SIMPLE_LEN - default 0x200000 if SPL_STACK_R_ADDR = 0x3e00000 + default 0x200000 if SPL_STACK_R_ADDR = 0x63e00000 + default 0x200000 if SPL_STACK_R_ADDR = 0x43e00000 + default 0x200000 if SPL_STACK_R_ADDR = 0x03e00000 endif endif diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index 5e7edc99cdc..ae15a9f8a2d 100644 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -42,7 +42,9 @@ 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_RK3576) += rk3576/ obj-$(CONFIG_ROCKCHIP_RK3588) += rk3588/ obj-$(CONFIG_ROCKCHIP_RV1108) += rv1108/ obj-$(CONFIG_ROCKCHIP_RV1126) += rv1126/ diff --git a/arch/arm/mach-rockchip/px30/Kconfig b/arch/arm/mach-rockchip/px30/Kconfig index dcf9eb8144b..2b57b166894 100644 --- a/arch/arm/mach-rockchip/px30/Kconfig +++ b/arch/arm/mach-rockchip/px30/Kconfig @@ -68,9 +68,6 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "px30" -config ROCKCHIP_COMMON_STACK_ADDR - default y - config SYS_MALLOC_F_LEN default 0x400 if !SPL_SHARES_INIT_SP_ADDR diff --git a/arch/arm/mach-rockchip/rk3308/Kconfig b/arch/arm/mach-rockchip/rk3308/Kconfig index fac966207a9..06572d545f6 100644 --- a/arch/arm/mach-rockchip/rk3308/Kconfig +++ b/arch/arm/mach-rockchip/rk3308/Kconfig @@ -17,9 +17,6 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "rk3308" -config ROCKCHIP_COMMON_STACK_ADDR - default y - config TEXT_BASE default 0x00600000 diff --git a/arch/arm/mach-rockchip/rk3308/rk3308.c b/arch/arm/mach-rockchip/rk3308/rk3308.c index 03d97e1d746..6916f1a2444 100644 --- a/arch/arm/mach-rockchip/rk3308/rk3308.c +++ b/arch/arm/mach-rockchip/rk3308/rk3308.c @@ -3,15 +3,12 @@ *Copyright (c) 2018 Rockchip Electronics Co., Ltd */ #include <init.h> -#include <malloc.h> +#include <asm/armv8/mmu.h> #include <asm/arch-rockchip/bootrom.h> #include <asm/arch-rockchip/grf_rk3308.h> #include <asm/arch-rockchip/hardware.h> -#include <asm/gpio.h> -#include <debug_uart.h> #include <linux/bitops.h> -#include <asm/armv8/mmu.h> static struct mm_region rk3308_mem_map[] = { { .virt = 0x0UL, @@ -38,22 +35,6 @@ struct mm_region *mem_map = rk3308_mem_map; #define SGRF_BASE 0xff2b0000 enum { - GPIO1C7_SHIFT = 8, - GPIO1C7_MASK = GENMASK(11, 8), - GPIO1C7_GPIO = 0, - GPIO1C7_UART1_RTSN, - GPIO1C7_UART2_TX_M0, - GPIO1C7_SPI2_MOSI, - GPIO1C7_JTAG_TMS, - - GPIO1C6_SHIFT = 4, - GPIO1C6_MASK = GENMASK(7, 4), - GPIO1C6_GPIO = 0, - GPIO1C6_UART1_CTSN, - GPIO1C6_UART2_RX_M0, - GPIO1C6_SPI2_MISO, - GPIO1C6_JTAG_TCLK, - GPIO4D3_SHIFT = 6, GPIO4D3_MASK = GENMASK(7, 6), GPIO4D3_GPIO = 0, @@ -116,60 +97,12 @@ enum { GPIO2A2_SEL_SRC_CTRL_SEL_PLUS = 1, }; -enum { - IOVSEL3_CTRL_SHIFT = 8, - IOVSEL3_CTRL_MASK = BIT(8), - VCCIO3_SEL_BY_GPIO = 0, - VCCIO3_SEL_BY_IOVSEL3, - - IOVSEL3_SHIFT = 3, - IOVSEL3_MASK = BIT(3), - VCCIO3_3V3 = 0, - VCCIO3_1V8, -}; - -/* - * The voltage of VCCIO3(which is the voltage domain of emmc/flash/sfc - * interface) can indicated by GPIO0_A4 or io_vsel3. The SOC defaults - * use GPIO0_A4 to indicate power supply voltage for VCCIO3 by hardware, - * then we can switch to io_vsel3 after system power on, and release GPIO0_A4 - * for other usage. - */ - -#define GPIO0_A4 4 - const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { [BROM_BOOTSOURCE_EMMC] = "/mmc@ff490000", [BROM_BOOTSOURCE_SPINOR] = "/spi@ff4c0000/flash@0", [BROM_BOOTSOURCE_SD] = "/mmc@ff480000", }; -int rk_board_init(void) -{ - static struct rk3308_grf * const grf = (void *)GRF_BASE; - u32 val; - int ret; - - ret = gpio_request(GPIO0_A4, "gpio0_a4"); - if (ret < 0) { - printf("request for gpio0_a4 failed:%d\n", ret); - return 0; - } - - gpio_direction_input(GPIO0_A4); - - if (gpio_get_value(GPIO0_A4)) - val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT | - VCCIO3_1V8 << IOVSEL3_SHIFT; - else - val = VCCIO3_SEL_BY_IOVSEL3 << IOVSEL3_CTRL_SHIFT | - VCCIO3_3V3 << IOVSEL3_SHIFT; - rk_clrsetreg(&grf->soc_con0, IOVSEL3_CTRL_MASK | IOVSEL3_MASK, val); - - gpio_free(GPIO0_A4); - return 0; -} - #ifdef CONFIG_DEBUG_UART_BOARD_INIT __weak void board_debug_uart_init(void) { diff --git a/arch/arm/mach-rockchip/rk3328/Kconfig b/arch/arm/mach-rockchip/rk3328/Kconfig index 70770da5fdf..ec1dae8d413 100644 --- a/arch/arm/mach-rockchip/rk3328/Kconfig +++ b/arch/arm/mach-rockchip/rk3328/Kconfig @@ -21,9 +21,6 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "rk3328" -config ROCKCHIP_COMMON_STACK_ADDR - default y - config TPL_LDSCRIPT default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds" diff --git a/arch/arm/mach-rockchip/rk3399/Kconfig b/arch/arm/mach-rockchip/rk3399/Kconfig index 500cfcd87af..b2430207ee9 100644 --- a/arch/arm/mach-rockchip/rk3399/Kconfig +++ b/arch/arm/mach-rockchip/rk3399/Kconfig @@ -143,9 +143,6 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "rk3399" -config ROCKCHIP_COMMON_STACK_ADDR - default y - config TPL_LDSCRIPT default "arch/arm/mach-rockchip/u-boot-tpl-v8.lds" diff --git a/arch/arm/mach-rockchip/rk3528/Kconfig b/arch/arm/mach-rockchip/rk3528/Kconfig new file mode 100644 index 00000000000..993b2dd274e --- /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 diff --git a/arch/arm/mach-rockchip/rk3528/MAINTAINERS b/arch/arm/mach-rockchip/rk3528/MAINTAINERS new file mode 100644 index 00000000000..f343f71cf7f --- /dev/null +++ b/arch/arm/mach-rockchip/rk3528/MAINTAINERS @@ -0,0 +1,11 @@ +GENERIC-RK3528 +M: Jonas Karlman <jonas@kwiboo.se> +S: Maintained +F: arch/arm/dts/rk3528-generic* +F: configs/generic-rk3528_defconfig + +RADXA-E20C +M: Jonas Karlman <jonas@kwiboo.se> +S: Maintained +F: arch/arm/dts/rk3528-radxa-e20c* +F: configs/radxa-e20c-rk3528_defconfig diff --git a/arch/arm/mach-rockchip/rk3528/Makefile b/arch/arm/mach-rockchip/rk3528/Makefile new file mode 100644 index 00000000000..f0c18cd39d2 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3528/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +obj-y += rk3528.o +obj-y += clk_rk3528.o +obj-y += syscon_rk3528.o diff --git a/arch/arm/mach-rockchip/rk3528/clk_rk3528.c b/arch/arm/mach-rockchip/rk3528/clk_rk3528.c new file mode 100644 index 00000000000..6e77f11cbec --- /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 <dm.h> +#include <asm/arch-rockchip/cru_rk3528.h> + +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; +} diff --git a/arch/arm/mach-rockchip/rk3528/rk3528.c b/arch/arm/mach-rockchip/rk3528/rk3528.c new file mode 100644 index 00000000000..4892ff6ba9d --- /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 <dm.h> +#include <misc.h> +#include <asm/armv8/mmu.h> +#include <asm/arch-rockchip/bootrom.h> +#include <asm/arch-rockchip/hardware.h> + +#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; +} diff --git a/arch/arm/mach-rockchip/rk3528/syscon_rk3528.c b/arch/arm/mach-rockchip/rk3528/syscon_rk3528.c new file mode 100644 index 00000000000..4a32a5f732e --- /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 <dm.h> +#include <asm/arch-rockchip/clock.h> + +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 +}; diff --git a/arch/arm/mach-rockchip/rk3568/Kconfig b/arch/arm/mach-rockchip/rk3568/Kconfig index ce327ed6f9e..01b53a47ddb 100644 --- a/arch/arm/mach-rockchip/rk3568/Kconfig +++ b/arch/arm/mach-rockchip/rk3568/Kconfig @@ -5,7 +5,6 @@ choice config TARGET_EVB_RK3568 bool "RK3568 evaluation board" - select BOARD_LATE_INIT help RK3568 EVB is a evaluation board for Rockchp RK3568. @@ -71,9 +70,6 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "rk3568" -config ROCKCHIP_COMMON_STACK_ADDR - default y - config TEXT_BASE default 0x00a00000 @@ -87,4 +83,7 @@ source "board/qnap/ts433/Kconfig" source "board/radxa/zero3-rk3566/Kconfig" source "board/xunlong/orangepi-3b-rk3566/Kconfig" +config SYS_CONFIG_NAME + default "rk3568_common" + endif diff --git a/arch/arm/mach-rockchip/rk3576/Kconfig b/arch/arm/mach-rockchip/rk3576/Kconfig new file mode 100644 index 00000000000..f347caf8904 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3576/Kconfig @@ -0,0 +1,23 @@ +if ROCKCHIP_RK3576 + +config TARGET_ROC_PC_RK3576 + bool "Firefly ROC-RK3576-PC" + help + ROC-RK3576-PC is a single board computer from Firefly + using the Rockchip RK3576. + +config ROCKCHIP_BOOT_MODE_REG + default 0x26024040 + +config ROCKCHIP_STIMER_BASE + default 0x27400000 + +config SYS_SOC + default "rk3576" + +source board/firefly/roc-pc-rk3576/Kconfig + +config SYS_CONFIG_NAME + default "rk3576_common" + +endif diff --git a/arch/arm/mach-rockchip/rk3576/Makefile b/arch/arm/mach-rockchip/rk3576/Makefile new file mode 100644 index 00000000000..cbc58257deb --- /dev/null +++ b/arch/arm/mach-rockchip/rk3576/Makefile @@ -0,0 +1,9 @@ +# +# (C) Copyright 2023 Rockchip Electronics Co., Ltd +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += rk3576.o +obj-y += clk_rk3576.o +obj-y += syscon_rk3576.o diff --git a/arch/arm/mach-rockchip/rk3576/clk_rk3576.c b/arch/arm/mach-rockchip/rk3576/clk_rk3576.c new file mode 100644 index 00000000000..edda1afd0bd --- /dev/null +++ b/arch/arm/mach-rockchip/rk3576/clk_rk3576.c @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) Copyright 2020 Rockchip Electronics Co., Ltd. + */ + +#include <dm.h> +#include <asm/arch-rockchip/cru_rk3576.h> + +int rockchip_get_clk(struct udevice **devp) +{ + return uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(rockchip_rk3576_cru), devp); +} + +void *rockchip_get_cru(void) +{ + return (void *)RK3576_CRU_BASE; +} diff --git a/arch/arm/mach-rockchip/rk3576/rk3576.c b/arch/arm/mach-rockchip/rk3576/rk3576.c new file mode 100644 index 00000000000..ba5c94b4b3d --- /dev/null +++ b/arch/arm/mach-rockchip/rk3576/rk3576.c @@ -0,0 +1,155 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2024 Rockchip Electronics Co., Ltd + */ + +#include <asm/armv8/mmu.h> +#include <asm/arch-rockchip/bootrom.h> +#include <asm/arch-rockchip/hardware.h> + +#define SYS_GRF_BASE 0x2600A000 +#define SYS_GRF_SOC_CON2 0x0008 +#define SYS_GRF_SOC_CON7 0x001c +#define SYS_GRF_SOC_CON11 0x002c +#define SYS_GRF_SOC_CON12 0x0030 + +#define GPIO0_IOC_BASE 0x26040000 +#define GPIO0B_PULL_L 0x0024 +#define GPIO0B_IE_L 0x002C + +#define SYS_SGRF_BASE 0x26004000 +#define SYS_SGRF_SOC_CON14 0x0058 +#define SYS_SGRF_SOC_CON15 0x005C +#define SYS_SGRF_SOC_CON20 0x0070 + +#define FW_SYS_SGRF_BASE 0x26005000 +#define SGRF_DOMAIN_CON1 0x4 +#define SGRF_DOMAIN_CON2 0x8 +#define SGRF_DOMAIN_CON3 0xc +#define SGRF_DOMAIN_CON4 0x10 +#define SGRF_DOMAIN_CON5 0x14 + +const char * const boot_devices[BROM_LAST_BOOTSOURCE + 1] = { + [BROM_BOOTSOURCE_EMMC] = "/soc/mmc@2a330000", + [BROM_BOOTSOURCE_SD] = "/soc/mmc@2a310000", +}; + +static struct mm_region rk3576_mem_map[] = { + { + /* I/O area */ + .virt = 0x20000000UL, + .phys = 0x20000000UL, + .size = 0xb080000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* PMU_SRAM, CBUF, SYSTEM_SRAM */ + .virt = 0x3fe70000UL, + .phys = 0x3fe70000UL, + .size = 0x190000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* MSCH_DDR_PORT */ + .virt = 0x40000000UL, + .phys = 0x40000000UL, + .size = 0x400000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, { + /* PCIe 0+1 */ + .virt = 0x900000000UL, + .phys = 0x900000000UL, + .size = 0x100800000UL, + .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 = rk3576_mem_map; + +void board_debug_uart_init(void) +{ +} + +#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 << 16) | TIMER_EN, HP_TIMER_BASE + HP_CTRL_REG); +} + +int arch_cpu_init(void) +{ + u32 val; + + if (!IS_ENABLED(CONFIG_SPL_BUILD)) + return 0; + + /* Set the emmc to access ddr memory */ + val = readl(FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON2); + writel(val | 0x7, FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON2); + + /* Set the sdmmc0 to access ddr memory */ + val = readl(FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON5); + writel(val | 0x700, FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON5); + + /* Set the UFS to access ddr memory */ + val = readl(FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON3); + writel(val | 0x70000, FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON3); + + /* Set the fspi0 and fspi1 to access ddr memory */ + val = readl(FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON4); + writel(val | 0x7700, FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON4); + + /* Set the decom to access ddr memory */ + val = readl(FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON1); + writel(val | 0x700, FW_SYS_SGRF_BASE + SGRF_DOMAIN_CON1); + + /* + * Set the GPIO0B0~B3 pull up and input enable. + * Keep consistent with other IO. + */ + writel(0x00ff00ff, GPIO0_IOC_BASE + GPIO0B_PULL_L); + writel(0x000f000f, GPIO0_IOC_BASE + GPIO0B_IE_L); + + /* + * Set SYS_GRF_SOC_CON2[12](input of pwm2_ch0) as 0, + * keep consistent with other pwm. + */ + writel(0x10000000, SYS_GRF_BASE + SYS_GRF_SOC_CON2); + + /* Enable noc slave response timeout */ + writel(0x80008000, SYS_GRF_BASE + SYS_GRF_SOC_CON11); + writel(0xffffffe0, SYS_GRF_BASE + SYS_GRF_SOC_CON12); + + /* + * Enable cci channels for below module AXI R/W + * Module: GMAC0/1, MMU0/1(PCIe, SATA, USB3) + */ + writel(0xffffff00, SYS_SGRF_BASE + SYS_SGRF_SOC_CON20); + + return 0; +} diff --git a/arch/arm/mach-rockchip/rk3576/syscon_rk3576.c b/arch/arm/mach-rockchip/rk3576/syscon_rk3576.c new file mode 100644 index 00000000000..0dbf8f8d9c0 --- /dev/null +++ b/arch/arm/mach-rockchip/rk3576/syscon_rk3576.c @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * (C) Copyright 2023 Rockchip Electronics Co., Ltd + */ + +#include <dm.h> +#include <asm/arch-rockchip/clock.h> + +static const struct udevice_id rk3576_syscon_ids[] = { + { .compatible = "rockchip,rk3576-sys-grf", .data = ROCKCHIP_SYSCON_GRF }, + { .compatible = "rockchip,rk3576-pmu1-grf", .data = ROCKCHIP_SYSCON_PMUGRF }, + { } +}; + +U_BOOT_DRIVER(rockchip_rk3576_syscon) = { + .name = "rockchip_rk3576_syscon", + .id = UCLASS_SYSCON, + .of_match = rk3576_syscon_ids, +#if CONFIG_IS_ENABLED(OF_REAL) + .bind = dm_scan_fdt_dev, +#endif +}; diff --git a/arch/arm/mach-rockchip/rk3588/Kconfig b/arch/arm/mach-rockchip/rk3588/Kconfig index 155b8f00ca2..4e7942ada87 100644 --- a/arch/arm/mach-rockchip/rk3588/Kconfig +++ b/arch/arm/mach-rockchip/rk3588/Kconfig @@ -2,13 +2,11 @@ if ROCKCHIP_RK3588 config TARGET_EVB_RK3588 bool "Rockchip EVB1 v10" - select BOARD_LATE_INIT help RK3588 EVB is a evaluation board for Rockchp RK3588. config TARGET_CM3588_NAS_RK3588 bool "FriendlyElec CM3588 NAS" - select BOARD_LATE_INIT help The CM3588 NAS by FriendlyElec pairs the CM3588 compute module, based on the Rockchip RK3588 SoC, with the CM3588 NAS Kit carrier board. @@ -31,7 +29,6 @@ config TARGET_CM3588_NAS_RK3588 config TARGET_GENBOOK_CM5_RK3588 bool "Cool Pi CM5 GenBook" - select BOARD_LATE_INIT help GeenBook is a notebook based on Rockchip RK3588, and works as a carrier board connect with CM5 SOM. @@ -49,7 +46,6 @@ config TARGET_GENBOOK_CM5_RK3588 config TARGET_JAGUAR_RK3588 bool "Theobroma Systems SBC-RK3588-AMR (Jaguar)" - select BOARD_LATE_INIT help The SBC-RK3588-AMR is a Single Board Computer designed by Theobroma Systems for autonomous mobile robots. @@ -76,7 +72,6 @@ config TARGET_JAGUAR_RK3588 config TARGET_KHADAS_EDGE2_RK3588 bool "Khadas Edge2 RK3588 board" - select BOARD_LATE_INIT help Khadas Edge2 is a Rockchip RK3588S based SBC (Single Board Computer) by Khadas. @@ -98,7 +93,6 @@ config TARGET_KHADAS_EDGE2_RK3588 config TARGET_NANOPCT6_RK3588 bool "FriendlyElec NanoPC-T6 RK3588 board" - select BOARD_LATE_INIT help The NanoPC-T6 is a Rockchip RK3588 based SBC by FriendlyElec. @@ -143,7 +137,6 @@ config TARGET_NANOPCT6_RK3588 config TARGET_NANOPI_R6C_RK3588S bool "FriendlyElec NanoPi R6C" - select BOARD_LATE_INIT help The NanoPi R6C is a SBC by FriendlyElec based on the Rockchip RK3588s. @@ -155,7 +148,6 @@ config TARGET_NANOPI_R6C_RK3588S config TARGET_NANOPI_R6S_RK3588S bool "FriendlyElec NanoPi R6S" - select BOARD_LATE_INIT help The NanoPi R6S is a SBC by FriendlyElec based on the Rockchip RK3588s. @@ -167,7 +159,6 @@ config TARGET_NANOPI_R6S_RK3588S config TARGET_NOVA_RK3588 bool "Indiedroid Nova RK3588" - select BOARD_LATE_INIT help Indiedroid Nova is a Rockchip RK3588s based SBC by Indiedroid. It comes in configurations from 4GB of RAM to 16GB of RAM, @@ -176,13 +167,11 @@ config TARGET_NOVA_RK3588 config TARGET_ODROID_M2_RK3588S bool "Hardkernel ODROID-M2" - select BOARD_LATE_INIT help Hardkernel ODROID-M2 single board computer with a RK3588S2 SoC. config TARGET_RK3588_NEU6 bool "Edgeble Neural Compute Module 6(Neu6) SoM" - select BOARD_LATE_INIT help Neu6A: Neural Compute Module 6A(Neu6A) is a 96boards SoM-CB compute module @@ -204,7 +193,6 @@ config TARGET_RK3588_NEU6 config TARGET_ROCK5A_RK3588 bool "Radxa ROCK5A RK3588 board" - select BOARD_LATE_INIT help Radxa ROCK5A is a Rockchip RK3588S based SBC (Single Board Computer) by Radxa. @@ -231,7 +219,6 @@ config TARGET_ROCK5A_RK3588 config TARGET_ROCK5B_RK3588 bool "Radxa ROCK5B RK3588 board" - select BOARD_LATE_INIT help Radxa ROCK5B is a Rockchip RK3588 based SBC (Single Board Computer) by Radxa. @@ -256,7 +243,6 @@ config TARGET_ROCK5B_RK3588 config TARGET_ROCK_5_ITX_RK3588 bool "Radxa ROCK-5-ITX RK3588 board" - select BOARD_LATE_INIT help Radxa ROCK-5-ITX is a Rockchip RK3588 based SBC (Single Board Computer) by Radxa in the ITX formfactor. @@ -284,7 +270,6 @@ config TARGET_ROCK_5_ITX_RK3588 config TARGET_ROCK_5C_RK3588S bool "Radxa ROCK 5C RK3588S2 board" - select BOARD_LATE_INIT help Radxa ROCK 5C is a Rockchip RK3588S2 based single board computer. @@ -304,7 +289,6 @@ config TARGET_ROCK_5C_RK3588S config TARGET_SIGE7_RK3588 bool "ArmSoM Sige7 RK3588 board" - select BOARD_LATE_INIT help ArmSoM Sige7 is a Rockchip RK3588 based SBC (Single Board Computer) by ArmSoM. @@ -329,14 +313,12 @@ config TARGET_SIGE7_RK3588 config TARGET_QUARTZPRO64_RK3588 bool "Pine64 QuartzPro64 RK3588 board" - select BOARD_LATE_INIT help Pine64 QuartzPro64 is a Rockchip RK3588 based SBC (Single Board Computer) by Pine64. config TARGET_TIGER_RK3588 bool "Theobroma Systems SOM-RK3588-Q7 (Tiger)" - select BOARD_LATE_INIT help The RK3588-Q7 SoM is a Qseven-compatible (70mm x 70mm, MXM-230 connector) system-on-module from Theobroma Systems, featuring the @@ -366,7 +348,6 @@ config TARGET_TIGER_RK3588 config TARGET_TURINGRK1_RK3588 bool "Turing Machines RK1 RK3588 board" - select BOARD_LATE_INIT help The Turing RK1 is a Rockchip RK3588 based SoM from Turing Machines. @@ -389,7 +370,6 @@ config TARGET_TURINGRK1_RK3588 config TARGET_TOYBRICK_RK3588 bool "Toybrick TB-RK3588X board" - select BOARD_LATE_INIT help Rockchip Toybrick TB-RK3588X is a Rockchip RK3588 based development board. TB-RK3588X adopts core board and mainboard design. The core board is connected @@ -420,9 +400,6 @@ config ROCKCHIP_STIMER_BASE config SYS_SOC default "rk3588" -config ROCKCHIP_COMMON_STACK_ADDR - default y - config TEXT_BASE default 0x00a00000 @@ -447,4 +424,7 @@ source "board/rockchip/toybrick_rk3588/Kconfig" source "board/theobroma-systems/jaguar_rk3588/Kconfig" source "board/theobroma-systems/tiger_rk3588/Kconfig" +config SYS_CONFIG_NAME + default "rk3588_common" + endif diff --git a/arch/arm/mach-rockchip/rk3588/rk3588.c b/arch/arm/mach-rockchip/rk3588/rk3588.c index c1dce3ee370..e2278ff792b 100644 --- a/arch/arm/mach-rockchip/rk3588/rk3588.c +++ b/arch/arm/mach-rockchip/rk3588/rk3588.c @@ -116,18 +116,25 @@ void board_debug_uart_init(void) } #ifdef CONFIG_XPL_BUILD + +#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) { /* If Timer already enabled, don't re-init it */ - u32 reg = readl(CONFIG_ROCKCHIP_STIMER_BASE + 0x4); + u32 reg = readl(HP_TIMER_BASE + HP_CTRL_REG); - if (reg & 0x1) + if (reg & TIMER_EN) return; - asm volatile("msr CNTFRQ_EL0, %0" : : "r" (CONFIG_COUNTER_FREQUENCY)); - writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x14); - writel(0xffffffff, CONFIG_ROCKCHIP_STIMER_BASE + 0x18); - writel(0x1, CONFIG_ROCKCHIP_STIMER_BASE + 0x4); + 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); } #endif diff --git a/arch/arm/mach-rockchip/sdram.c b/arch/arm/mach-rockchip/sdram.c index f7d32829295..3bc482331c7 100644 --- a/arch/arm/mach-rockchip/sdram.c +++ b/arch/arm/mach-rockchip/sdram.c @@ -110,7 +110,9 @@ static int rockchip_dram_init_banksize(void) u8 i, j; if (!IS_ENABLED(CONFIG_ROCKCHIP_RK3588) && - !IS_ENABLED(CONFIG_ROCKCHIP_RK3568)) + !IS_ENABLED(CONFIG_ROCKCHIP_RK3576) && + !IS_ENABLED(CONFIG_ROCKCHIP_RK3568) && + !IS_ENABLED(CONFIG_ROCKCHIP_RK3528)) return -ENOTSUPP; if (!IS_ENABLED(CONFIG_ROCKCHIP_EXTERNAL_TPL)) @@ -181,9 +183,9 @@ static int rockchip_dram_init_banksize(void) * BL31 (TF-A) reserves the first 2MB but DDR_MEM tag may not * have it, so force this space as reserved. */ - if (start_addr < SZ_2M) { - size -= SZ_2M - start_addr; - start_addr = SZ_2M; + if (start_addr < CFG_SYS_SDRAM_BASE + SZ_2M) { + size -= CFG_SYS_SDRAM_BASE + SZ_2M - start_addr; + start_addr = CFG_SYS_SDRAM_BASE + SZ_2M; } /* @@ -228,7 +230,7 @@ static int rockchip_dram_init_banksize(void) return -EINVAL; } - size -= rsrv_end - start_addr; + size -= rsrv_end - (start_addr - CFG_SYS_SDRAM_BASE); start_addr = rsrv_end; break; } @@ -301,8 +303,8 @@ int dram_init_banksize(void) debug("Couldn't use ATAG (%d) to detect DDR layout, falling back...\n", ret); - /* Reserve 0x200000 for ATF bl31 */ - gd->bd->bi_dram[0].start = 0x200000; + /* Reserve 2M for ATF bl31 */ + gd->bd->bi_dram[0].start = CFG_SYS_SDRAM_BASE + SZ_2M; gd->bd->bi_dram[0].size = top - gd->bd->bi_dram[0].start; /* Add usable memory beyond the blob of space for peripheral near 4GB */ diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile index 22d48dfae1c..c43fdee4a48 100644 --- a/arch/arm/mach-socfpga/Makefile +++ b/arch/arm/mach-socfpga/Makefile @@ -68,6 +68,8 @@ obj-y += altera-sysmgr.o obj-y += ccu_ncore3.o obj-y += system_manager_soc64.o obj-y += timer_s10.o +obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += secure_vab.o +obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += vab.o endif ifdef CONFIG_TARGET_SOCFPGA_N5X diff --git a/arch/arm/mach-socfpga/board.c b/arch/arm/mach-socfpga/board.c index 27072e53135..8506d510413 100644 --- a/arch/arm/mach-socfpga/board.c +++ b/arch/arm/mach-socfpga/board.c @@ -195,3 +195,16 @@ void board_prep_linux(struct bootm_headers *images) } } #endif + +#if CONFIG_IS_ENABLED(LMB_ARCH_MEM_MAP) +void lmb_arch_add_memory(void) +{ + int i; + struct bd_info *bd = gd->bd; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + if (bd->bi_dram[i].size) + lmb_add(bd->bi_dram[i].start, bd->bi_dram[i].size); + } +} +#endif diff --git a/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h b/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h index 65721098b2b..5ac868a281b 100644 --- a/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/base_addr_soc64.h @@ -51,6 +51,7 @@ #else #define SOCFPGA_FW_MPU_DDR_SCR_ADDRESS 0xf8020100 #endif +#define SOCFPGA_F2SDRAM_MGR_ADDRESS 0xf8024000 #define SOCFPGA_SMMU_ADDRESS 0xfa000000 #define SOCFPGA_MAILBOX_ADDRESS 0xffa30000 #define SOCFPGA_UART0_ADDRESS 0xffc02000 diff --git a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h index 45cc9912f94..2099c51b682 100644 --- a/arch/arm/mach-socfpga/include/mach/mailbox_s10.h +++ b/arch/arm/mach-socfpga/include/mach/mailbox_s10.h @@ -128,6 +128,7 @@ enum ALT_SDM_MBOX_RESP_CODE { #define MBOX_QSPI_CLOSE 51 #define MBOX_QSPI_DIRECT 59 #define MBOX_REBOOT_HPS 71 +#define MBOX_HPS_STAGE_NOTIFY 93 /* Mailbox registers */ #define MBOX_CIN 0 /* command valid offset */ @@ -385,6 +386,8 @@ enum MBOX_CFGSTAT_MINOR_ERR_CODE { #define RCF_SOFTFUNC_STATUS_SEU_ERROR BIT(3) #define RCF_PIN_STATUS_NSTATUS BIT(31) +#define HPS_EXECUTION_STATE_FSBL 0 + int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, u8 urgent, u32 *resp_buf_len, u32 *resp_buf); int mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, @@ -401,6 +404,7 @@ int mbox_qspi_open(void); #endif int mbox_reset_cold(void); +int mbox_hps_stage_notify(u32 execution_stage); int mbox_get_fpga_config_status(u32 cmd); int mbox_get_fpga_config_status_psci(u32 cmd); #endif /* _MAILBOX_S10_H_ */ diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h index 058fdd6e548..4b010be9ee8 100644 --- a/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h +++ b/arch/arm/mach-socfpga/include/mach/reset_manager_soc64.h @@ -10,9 +10,12 @@ void reset_deassert_peripherals_handoff(void); int cpu_has_been_warmreset(void); void print_reset_info(void); -void socfpga_bridges_reset(int enable); +void socfpga_bridges_reset(int enable, unsigned int mask); #define RSTMGR_SOC64_STATUS 0x00 +#define RSTMGR_SOC64_HDSKEN 0x10 +#define RSTMGR_SOC64_HDSKREQ 0x14 +#define RSTMGR_SOC64_HDSKACK 0x18 #define RSTMGR_SOC64_MPUMODRST 0x20 #define RSTMGR_SOC64_PER0MODRST 0x24 #define RSTMGR_SOC64_PER1MODRST 0x28 @@ -20,8 +23,17 @@ void socfpga_bridges_reset(int enable); #define RSTMGR_MPUMODRST_CORE0 0 #define RSTMGR_PER0MODRST_OCP_MASK 0x0020bf00 -#define RSTMGR_BRGMODRST_DDRSCH_MASK 0X00000040 -#define RSTMGR_BRGMODRST_FPGA2SOC_MASK 0x00000004 + +#define RSTMGR_BRGMODRST_SOC2FPGA_MASK BIT(0) +#define RSTMGR_BRGMODRST_LWSOC2FPGA_MASK BIT(1) +#define RSTMGR_BRGMODRST_FPGA2SOC_MASK BIT(2) +#define RSTMGR_BRGMODRST_F2SDRAM0_MASK BIT(3) +#define RSTMGR_BRGMODRST_F2SDRAM1_MASK BIT(4) +#define RSTMGR_BRGMODRST_F2SDRAM2_MASK BIT(5) +#define RSTMGR_BRGMODRST_DDRSCH_MASK BIT(6) + +#define RSTMGR_HDSKEN_FPGAHSEN BIT(2) +#define RSTMGR_HDSKREQ_FPGAHSREQ BIT(2) /* SDM, Watchdogs and MPU warm reset mask */ #define RSTMGR_STAT_SDMWARMRST 0x2 diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c index b69bd3e47ec..f9c34e85711 100644 --- a/arch/arm/mach-socfpga/mailbox_s10.c +++ b/arch/arm/mach-socfpga/mailbox_s10.c @@ -6,6 +6,7 @@ #include <asm/arch/clock_manager.h> #include <asm/arch/mailbox_s10.h> +#include <asm/arch/smc_api.h> #include <asm/arch/system_manager.h> #include <asm/global_data.h> #include <asm/io.h> @@ -474,6 +475,17 @@ int __secure mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, urgent, resp_buf_len, resp_buf); } +int mbox_hps_stage_notify(u32 execution_stage) +{ +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_ATF) + return smc_send_mailbox(MBOX_HPS_STAGE_NOTIFY, 1, &execution_stage, + 0, 0, NULL); +#else + return mbox_send_cmd(MBOX_ID_UBOOT, MBOX_HPS_STAGE_NOTIFY, + MBOX_CMD_DIRECT, 1, &execution_stage, 0, 0, NULL); +#endif +} + int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg) { return mbox_send_cmd_only_common(id, cmd, is_indirect, len, arg); diff --git a/arch/arm/mach-socfpga/misc_soc64.c b/arch/arm/mach-socfpga/misc_soc64.c index e0b2b4237e1..4f080f4f0b3 100644 --- a/arch/arm/mach-socfpga/misc_soc64.c +++ b/arch/arm/mach-socfpga/misc_soc64.c @@ -61,7 +61,7 @@ void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, #if defined(CONFIG_DISPLAY_CPUINFO) int print_cpuinfo(void) { - printf("CPU: Intel FPGA SoCFPGA Platform (ARMv8 64bit Cortex-%s)\n", + printf("CPU: Altera FPGA SoCFPGA Platform (ARMv8 64bit Cortex-%s)\n", IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) ? "A55/A76" : "A53"); return 0; @@ -107,5 +107,5 @@ void do_bridge_reset(int enable, unsigned int mask) return; } - socfpga_bridges_reset(enable); + socfpga_bridges_reset(enable, mask); } diff --git a/arch/arm/mach-socfpga/mmu-arm64_s10.c b/arch/arm/mach-socfpga/mmu-arm64_s10.c index b8e40d9a788..1dc44ab4797 100644 --- a/arch/arm/mach-socfpga/mmu-arm64_s10.c +++ b/arch/arm/mach-socfpga/mmu-arm64_s10.c @@ -58,6 +58,20 @@ static struct mm_region socfpga_agilex5_mem_map[] = { .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE, }, { + /* MEM 30GB */ + .virt = 0x880000000UL, + .phys = 0x880000000UL, + .size = 0x780000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE, + }, { + /* MEM 480GB */ + .virt = 0x8800000000UL, + .phys = 0x8800000000UL, + .size = 0x7800000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE, + }, { /* List terminator */ }, }; diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c index a634c11a028..abb62a9b49f 100644 --- a/arch/arm/mach-socfpga/reset_manager_s10.c +++ b/arch/arm/mach-socfpga/reset_manager_s10.c @@ -1,21 +1,34 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (C) 2016-2018 Intel Corporation <www.intel.com> + * Copyright (C) 2025 Altera Corporation <www.altera.com> * */ +#include <errno.h> #include <hang.h> #include <asm/global_data.h> #include <asm/io.h> +#include <asm/secure.h> #include <asm/arch/reset_manager.h> #include <asm/arch/smc_api.h> #include <asm/arch/system_manager.h> +#include <asm/arch/timer.h> #include <dt-bindings/reset/altr,rst-mgr-s10.h> +#include <exports.h> #include <linux/iopoll.h> #include <linux/intel-smc.h> +#include <wait_bit.h> DECLARE_GLOBAL_DATA_PTR; +#define TIMEOUT_300MS 300 + +/* F2S manager registers */ +#define F2SDRAM_SIDEBAND_FLAGINSTATUS0 0x14 +#define F2SDRAM_SIDEBAND_FLAGOUTSET0 0x50 +#define F2SDRAM_SIDEBAND_FLAGOUTCLR0 0x54 + /* Assert or de-assert SoCFPGA reset manager reset. */ void socfpga_per_reset(u32 reset, int set) { @@ -56,66 +69,213 @@ void socfpga_per_reset_all(void) writel(0xffffffff, socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER1MODRST); } -void socfpga_bridges_reset(int enable) +static void socfpga_f2s_bridges_reset(int enable, unsigned int mask) { -#if !defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_ATF) - u64 arg = enable; + int ret; + u32 brg_mask; + u32 flagout_idlereq = 0; + u32 flagoutset_fdrain = 0; + u32 flagoutset_en = 0; + u32 flaginstatus_idleack = 0; + u32 flaginstatus_respempty = 0; + + if (CONFIG_IS_ENABLED(TARGET_SOCFPGA_STRATIX10)) { + /* Support fpga2soc and f2sdram */ + brg_mask = mask & (RSTMGR_BRGMODRST_FPGA2SOC_MASK | + RSTMGR_BRGMODRST_F2SDRAM0_MASK | + RSTMGR_BRGMODRST_F2SDRAM1_MASK | + RSTMGR_BRGMODRST_F2SDRAM2_MASK); - int ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, &arg, 1, NULL, 0); - if (ret) { - printf("SMC call failed with error %d in %s.\n", ret, __func__); + if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM0_MASK) { + flagout_idlereq |= BIT(0); + flaginstatus_idleack |= BIT(1); + flagoutset_fdrain |= BIT(2); + flagoutset_en |= BIT(1); + flaginstatus_respempty |= BIT(3); + } + + if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM1_MASK) { + flagout_idlereq |= BIT(3); + flaginstatus_idleack |= BIT(5); + flagoutset_fdrain |= BIT(5); + flagoutset_en |= BIT(4); + flaginstatus_respempty |= BIT(7); + } + + if (brg_mask & RSTMGR_BRGMODRST_F2SDRAM2_MASK) { + flagout_idlereq |= BIT(6); + flaginstatus_idleack |= BIT(9); + flagoutset_fdrain |= BIT(8); + flagoutset_en |= BIT(7); + flaginstatus_respempty |= BIT(11); + } + } else { + /* Support fpga2soc only */ + brg_mask = mask & RSTMGR_BRGMODRST_FPGA2SOC_MASK; + if (brg_mask & RSTMGR_BRGMODRST_FPGA2SOC_MASK) { + flagout_idlereq |= BIT(0); + flaginstatus_idleack |= BIT(1); + flagoutset_fdrain |= BIT(2); + flagoutset_en |= BIT(1); + flaginstatus_respempty |= BIT(3); + } + } + + /* mask is not set, return here */ + if (!brg_mask) return; + + if (enable) { + clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST, + brg_mask); + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTCLR0, + flagout_idlereq); + + /* Wait for mpfe noc idleack to 0 */ + wait_for_bit_le32((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGINSTATUS0), + flaginstatus_idleack, false, TIMEOUT_300MS, false); + + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTCLR0, + flagoutset_fdrain); + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_en); + + udelay(1); /* wait 1us */ + } else { + if (readl((socfpga_get_rstmgr_addr() + + RSTMGR_SOC64_BRGMODRST) & brg_mask)) { + /* Bridge cannot be reset twice */ + return; + } + + setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKEN, + RSTMGR_HDSKEN_FPGAHSEN); + setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ, + RSTMGR_HDSKREQ_FPGAHSREQ); + + /* Wait for FPGA ack the handshake request to 1 */ + wait_for_bit_le32((u32 *)(socfpga_get_rstmgr_addr() + + RSTMGR_SOC64_HDSKACK), RSTMGR_HDSKREQ_FPGAHSREQ, + true, TIMEOUT_300MS, false); + + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTCLR0, flagoutset_en); + + udelay(1); + + /* Requests MPFE NoC to idle */ + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTSET0, flagout_idlereq); + + /* Force F2S bridge to drain */ + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_fdrain); + + /* Wait for respond queue empty status to 1 (resp idle) */ + ret = wait_for_bit_le32((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGINSTATUS0), + flaginstatus_respempty, true, + TIMEOUT_300MS, false); + + /* Confirm again */ + if (!ret) + ret = wait_for_bit_le32((u32 *) + (SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGINSTATUS0), + flaginstatus_respempty, true, + TIMEOUT_300MS, false); + + setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST, + brg_mask & ~RSTMGR_BRGMODRST_FPGA2SOC_MASK); + clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ, + RSTMGR_HDSKREQ_FPGAHSREQ); + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTCLR0, + flagout_idlereq); } -#else - u32 reg; +} + +static void socfpga_s2f_bridges_reset(int enable, unsigned int mask) +{ + unsigned int noc_mask = 0; + unsigned int brg_mask = 0; + + if (mask & RSTMGR_BRGMODRST_SOC2FPGA_MASK) { + noc_mask = SYSMGR_NOC_H2F_MSK; + brg_mask = RSTMGR_BRGMODRST_SOC2FPGA_MASK; + } + + if (mask & RSTMGR_BRGMODRST_LWSOC2FPGA_MASK) { + noc_mask |= SYSMGR_NOC_LWH2F_MSK; + brg_mask |= RSTMGR_BRGMODRST_LWSOC2FPGA_MASK; + } + + /* s2f mask is not set, return here */ + if (!brg_mask) + return; if (enable) { /* clear idle request to all bridges */ setbits_le32(socfpga_get_sysmgr_addr() + - SYSMGR_SOC64_NOC_IDLEREQ_CLR, ~0); + SYSMGR_SOC64_NOC_IDLEREQ_CLR, noc_mask); - /* Release all bridges from reset state */ + /* Release SOC2FPGA bridges from reset state */ clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST, - ~0); + brg_mask); - /* Poll until all idleack to 0 */ - read_poll_timeout(readl, reg, !reg, 1000, 300000, - socfpga_get_sysmgr_addr() + - SYSMGR_SOC64_NOC_IDLEACK); + /* Wait for all NOC master ack to 0 */ + wait_for_bit_le32((u32 *)(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_NOC_IDLEACK), noc_mask, false, + TIMEOUT_300MS, false); } else { /* set idle request to all bridges */ - writel(~0, - socfpga_get_sysmgr_addr() + - SYSMGR_SOC64_NOC_IDLEREQ_SET); + setbits_le32(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_NOC_IDLEREQ_SET, noc_mask); /* Enable the NOC timeout */ writel(1, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT); - /* Poll until all idleack to 1 */ - read_poll_timeout(readl, reg, - reg == (SYSMGR_NOC_H2F_MSK | - SYSMGR_NOC_LWH2F_MSK), - 1000, 300000, - socfpga_get_sysmgr_addr() + - SYSMGR_SOC64_NOC_IDLEACK); - - /* Poll until all idlestatus to 1 */ - read_poll_timeout(readl, reg, - reg == (SYSMGR_NOC_H2F_MSK | - SYSMGR_NOC_LWH2F_MSK), - 1000, 300000, - socfpga_get_sysmgr_addr() + - SYSMGR_SOC64_NOC_IDLESTATUS); - - /* Reset all bridges (except NOR DDR scheduler & F2S) */ + /* Wait for all NOC master ack to 1 */ + wait_for_bit_le32((u32 *)(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_NOC_IDLEACK), noc_mask, true, + TIMEOUT_300MS, false); + + /* Wait for all NOC master idlestatus to 1 */ + wait_for_bit_le32((u32 *)(socfpga_get_sysmgr_addr() + + SYSMGR_SOC64_NOC_IDLESTATUS), noc_mask, true, + TIMEOUT_300MS, false); + + /* Reset all SOC2FPGA bridges */ setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST, - ~(RSTMGR_BRGMODRST_DDRSCH_MASK | - RSTMGR_BRGMODRST_FPGA2SOC_MASK)); + brg_mask); /* Disable NOC timeout */ writel(0, socfpga_get_sysmgr_addr() + SYSMGR_SOC64_NOC_TIMEOUT); } -#endif +} + +void socfpga_bridges_reset(int enable, unsigned int mask) +{ + if (!IS_ENABLED(CONFIG_XPL_BUILD) && IS_ENABLED(CONFIG_SPL_ATF)) { + u64 arg[2]; + int ret; + + /* Set bit-1 to indicate has mask value in arg[1]. */ + arg[0] = (enable & BIT(0)) | BIT(1); + arg[1] = mask; + + ret = invoke_smc(INTEL_SIP_SMC_HPS_SET_BRIDGES, arg, + ARRAY_SIZE(arg), NULL, 0); + if (ret) + printf("Failed to %s the HPS bridges, check bridges availability. Status %d.\n", + enable ? "enable" : "disable", ret); + } else { + socfpga_s2f_bridges_reset(enable, mask); + socfpga_f2s_bridges_reset(enable, mask); + } } /* diff --git a/arch/arm/mach-socfpga/spl_agilex.c b/arch/arm/mach-socfpga/spl_agilex.c index 52617a39cca..91c27a5543d 100644 --- a/arch/arm/mach-socfpga/spl_agilex.c +++ b/arch/arm/mach-socfpga/spl_agilex.c @@ -50,6 +50,10 @@ void board_init_f(ulong dummy) timer_init(); + mbox_init(); + + mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL); + sysmgr_pinmux_init(); ret = uclass_get_device(UCLASS_CLK, 0, &dev); @@ -77,8 +81,6 @@ void board_init_f(ulong dummy) } #endif - mbox_init(); - #ifdef CONFIG_CADENCE_QSPI mbox_qspi_open(); #endif diff --git a/arch/arm/mach-socfpga/spl_agilex5.c b/arch/arm/mach-socfpga/spl_agilex5.c index 3451611082d..a9aad5350d2 100644 --- a/arch/arm/mach-socfpga/spl_agilex5.c +++ b/arch/arm/mach-socfpga/spl_agilex5.c @@ -62,6 +62,10 @@ void board_init_f(ulong dummy) timer_init(); + mbox_init(); + + mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL); + ret = uclass_get_device(UCLASS_CLK, 0, &dev); if (ret) { debug("Clock init failed: %d\n", ret); @@ -100,8 +104,6 @@ void board_init_f(ulong dummy) } } - mbox_init(); - if (IS_ENABLED(CONFIG_CADENCE_QSPI)) mbox_qspi_open(); diff --git a/arch/arm/mach-socfpga/spl_n5x.c b/arch/arm/mach-socfpga/spl_n5x.c index 5ff137e5c6f..81283ef7162 100644 --- a/arch/arm/mach-socfpga/spl_n5x.c +++ b/arch/arm/mach-socfpga/spl_n5x.c @@ -49,6 +49,10 @@ void board_init_f(ulong dummy) timer_init(); + mbox_init(); + + mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL); + sysmgr_pinmux_init(); preloader_console_init(); @@ -84,8 +88,6 @@ void board_init_f(ulong dummy) } #endif - mbox_init(); - #ifdef CONFIG_CADENCE_QSPI mbox_qspi_open(); #endif diff --git a/arch/arm/mach-socfpga/spl_s10.c b/arch/arm/mach-socfpga/spl_s10.c index 53852cb7443..fa83ff96adc 100644 --- a/arch/arm/mach-socfpga/spl_s10.c +++ b/arch/arm/mach-socfpga/spl_s10.c @@ -52,6 +52,10 @@ void board_init_f(ulong dummy) socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0); timer_init(); + mbox_init(); + + mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL); + sysmgr_pinmux_init(); /* configuring the HPS clocks */ @@ -84,8 +88,6 @@ void board_init_f(ulong dummy) } #endif - mbox_init(); - #ifdef CONFIG_CADENCE_QSPI mbox_qspi_open(); #endif diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7ea439e857c..a0317011de7 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -146,7 +146,35 @@ config TARGET_BOSTON select SUPPORTS_CPU_MIPS64_R6 select SUPPORT_BIG_ENDIAN select SUPPORT_LITTLE_ENDIAN + imply OF_UPSTREAM + imply BOOTSTD_FULL + imply CLK + imply CLK_BOSTON imply CMD_DM + imply AHCI + imply AHCI_PCI + imply CFI_FLASH + imply MTD_NOR_FLASH + imply MMC + imply MMC_PCI + imply MMC_SDHCI + imply MMC_SDHCI_SDMA + imply PCH_GBE + imply PCI + imply PCI_XILINX + imply PCI_INIT_R + imply SCSI + imply SCSI_AHCI + imply SYS_NS16550 + imply SYSRESET + imply SYSRESET_CMD_POWEROFF + imply SYSRESET_SYSCON + imply USB + imply USB_EHCI_HCD + imply USB_EHCI_PCI + imply USB_XHCI_HCD + imply USB_XHCI_PCI + imply CMD_USB config TARGET_XILFPGA bool "Support Imagination Xilfpga" @@ -322,6 +350,7 @@ config MIPS_CACHE_DISABLE config MIPS_RELOCATION_TABLE_SIZE hex "Relocation table size" range 0x100 0x10000 + default "0xc000" if TARGET_MALTA default "0x8000" ---help--- A table of relocation data will be appended to the U-Boot binary diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile index 752e771514f..7c4ee8b668b 100644 --- a/arch/mips/dts/Makefile +++ b/arch/mips/dts/Makefile @@ -3,7 +3,6 @@ dtb-$(CONFIG_TARGET_AP121) += ap121.dtb dtb-$(CONFIG_TARGET_AP143) += ap143.dtb dtb-$(CONFIG_TARGET_AP152) += ap152.dtb -dtb-$(CONFIG_TARGET_BOSTON) += img,boston.dtb dtb-$(CONFIG_TARGET_MALTA) += mti,malta.dtb dtb-$(CONFIG_TARGET_PIC32MZDASK) += pic32mzda_sk.dtb dtb-$(CONFIG_TARGET_XILFPGA) += nexys4ddr.dtb diff --git a/arch/mips/dts/boston-u-boot.dtsi b/arch/mips/dts/boston-u-boot.dtsi new file mode 100644 index 00000000000..1b0c0a28961 --- /dev/null +++ b/arch/mips/dts/boston-u-boot.dtsi @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ + +&plat_regs { + compatible = "img,boston-platform-regs", "syscon", "simple-mfd"; + bootph-all; +}; + +&clk_boston { + bootph-all; +}; diff --git a/arch/mips/dts/img,boston.dts b/arch/mips/dts/img,boston.dts deleted file mode 100644 index c1a73963037..00000000000 --- a/arch/mips/dts/img,boston.dts +++ /dev/null @@ -1,222 +0,0 @@ -/dts-v1/; - -#include <dt-bindings/clock/boston-clock.h> -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/interrupt-controller/irq.h> -#include <dt-bindings/interrupt-controller/mips-gic.h> - -/ { - #address-cells = <1>; - #size-cells = <1>; - compatible = "img,boston"; - - chosen { - stdout-path = &uart0; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "img,mips"; - reg = <0>; - clocks = <&clk_boston BOSTON_CLK_CPU>; - }; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x10000000>; - }; - - gic: interrupt-controller { - compatible = "mti,gic"; - - interrupt-controller; - #interrupt-cells = <3>; - - timer { - compatible = "mti,gic-timer"; - interrupts = <GIC_LOCAL 1 IRQ_TYPE_NONE>; - clocks = <&clk_boston BOSTON_CLK_CPU>; - }; - }; - - pci0: pci@10000000 { - status = "disabled"; - compatible = "xlnx,axi-pcie-host-1.00.a"; - device_type = "pci"; - reg = <0x10000000 0x2000000>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 2 IRQ_TYPE_LEVEL_HIGH>; - - ranges = <0x02000000 0 0x40000000 - 0x40000000 0 0x40000000>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pci0_intc 0>, - <0 0 0 2 &pci0_intc 1>, - <0 0 0 3 &pci0_intc 2>, - <0 0 0 4 &pci0_intc 3>; - - pci0_intc: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - - pci1: pci@12000000 { - status = "disabled"; - compatible = "xlnx,axi-pcie-host-1.00.a"; - device_type = "pci"; - reg = <0x12000000 0x2000000>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 1 IRQ_TYPE_LEVEL_HIGH>; - - ranges = <0x02000000 0 0x20000000 - 0x20000000 0 0x20000000>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pci1_intc 0>, - <0 0 0 2 &pci1_intc 1>, - <0 0 0 3 &pci1_intc 2>, - <0 0 0 4 &pci1_intc 3>; - - pci1_intc: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - }; - - pci2: pci@14000000 { - compatible = "xlnx,axi-pcie-host-1.00.a"; - device_type = "pci"; - reg = <0x14000000 0x2000000>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 0 IRQ_TYPE_LEVEL_HIGH>; - - ranges = <0x02000000 0 0x16000000 - 0x16000000 0 0x100000>; - - interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &pci2_intc 0>, - <0 0 0 2 &pci2_intc 1>, - <0 0 0 3 &pci2_intc 2>, - <0 0 0 4 &pci2_intc 3>; - - pci2_intc: interrupt-controller { - interrupt-controller; - #address-cells = <0>; - #interrupt-cells = <1>; - }; - - pci2_root@0,0,0 { - compatible = "pci10ee,7021"; - reg = <0x00000000 0 0 0 0>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - eg20t_bridge@1,0,0 { - compatible = "pci8086,8800"; - reg = <0x00010000 0 0 0 0>; - - #address-cells = <3>; - #size-cells = <2>; - #interrupt-cells = <1>; - - eg20t_mac@2,0,1 { - compatible = "pci8086,8802"; - reg = <0x00020100 0 0 0 0>; - phy-reset-gpios = <&eg20t_gpio 6 GPIO_ACTIVE_LOW>; - }; - - eg20t_gpio: eg20t_gpio@2,0,2 { - compatible = "pci8086,8803"; - reg = <0x00020200 0 0 0 0>; - - gpio-controller; - #gpio-cells = <2>; - }; - - eg20t_i2c@2,12,2 { - compatible = "pci8086,8817"; - reg = <0x00026200 0 0 0 0>; - - #address-cells = <1>; - #size-cells = <0>; - - rtc@0x68 { - compatible = "st,m41t81s"; - reg = <0x68>; - }; - }; - }; - }; - }; - - plat_regs: system-controller@17ffd000 { - compatible = "img,boston-platform-regs", "syscon"; - reg = <0x17ffd000 0x1000>; - bootph-all; - }; - - clk_boston: clock { - compatible = "img,boston-clock"; - #clock-cells = <1>; - regmap = <&plat_regs>; - bootph-all; - }; - - reboot: syscon-reboot { - compatible = "syscon-reboot"; - regmap = <&plat_regs>; - offset = <0x10>; - mask = <0x10>; - }; - - uart0: uart@17ffe000 { - compatible = "ns16550a"; - reg = <0x17ffe000 0x1000>; - reg-shift = <2>; - reg-io-width = <4>; - - interrupt-parent = <&gic>; - interrupts = <GIC_SHARED 3 IRQ_TYPE_LEVEL_HIGH>; - - clocks = <&clk_boston BOSTON_CLK_SYS>; - - bootph-all; - }; - - lcd: lcd@17fff000 { - compatible = "img,boston-lcd"; - reg = <0x17fff000 0x8>; - }; - - flash@18000000 { - compatible = "cfi-flash"; - reg = <0x18000000 0x8000000>; - bank-width = <2>; - }; -}; diff --git a/arch/mips/include/asm/acpi_table.h b/arch/mips/include/asm/acpi_table.h new file mode 100644 index 00000000000..b4139d0ba32 --- /dev/null +++ b/arch/mips/include/asm/acpi_table.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef __ASM_ACPI_TABLE_H__ +#define __ASM_ACPI_TABLE_H__ + +/* + * This file is needed by some drivers. + */ + +#endif /* __ASM_ACPI_TABLE_H__ */ diff --git a/arch/riscv/dts/jh7110-u-boot.dtsi b/arch/riscv/dts/jh7110-u-boot.dtsi index ce7d9e16961..a9e318c4a31 100644 --- a/arch/riscv/dts/jh7110-u-boot.dtsi +++ b/arch/riscv/dts/jh7110-u-boot.dtsi @@ -102,6 +102,10 @@ bootph-pre-ram; }; +&pllclk { + bootph-pre-ram; +}; + &syscrg { bootph-pre-ram; }; diff --git a/board/emulation/qemu-arm/MAINTAINERS b/board/emulation/qemu-arm/MAINTAINERS index 7bc0ee698c5..538769f8040 100644 --- a/board/emulation/qemu-arm/MAINTAINERS +++ b/board/emulation/qemu-arm/MAINTAINERS @@ -5,6 +5,5 @@ F: board/emulation/qemu-arm/ F: board/emulation/common/ F: include/configs/qemu-arm.h F: include/configs/qemu-sbsa.h -F: configs/qemu_arm_defconfig -F: configs/qemu_arm64_defconfig +F: configs/qemu_arm* F: configs/qemu-arm-sbsa_defconfig diff --git a/board/emulation/qemu-riscv/MAINTAINERS b/board/emulation/qemu-riscv/MAINTAINERS index 3d7453f1b43..d75d1b5f190 100644 --- a/board/emulation/qemu-riscv/MAINTAINERS +++ b/board/emulation/qemu-riscv/MAINTAINERS @@ -4,9 +4,4 @@ S: Maintained F: board/emulation/qemu-riscv/ F: board/emulation/common/ F: include/configs/qemu-riscv.h -F: configs/qemu-riscv32_defconfig -F: configs/qemu-riscv32_smode_defconfig -F: configs/qemu-riscv32_spl_defconfig -F: configs/qemu-riscv64_defconfig -F: configs/qemu-riscv64_smode_defconfig -F: configs/qemu-riscv64_spl_defconfig +F: configs/qemu-riscv* diff --git a/board/firefly/roc-pc-rk3576/Kconfig b/board/firefly/roc-pc-rk3576/Kconfig new file mode 100644 index 00000000000..2fc0f913c37 --- /dev/null +++ b/board/firefly/roc-pc-rk3576/Kconfig @@ -0,0 +1,12 @@ +if TARGET_ROC_PC_RK3576 + +config SYS_BOARD + default "roc-pc-rk3576" + +config SYS_VENDOR + default "firefly" + +config SYS_CONFIG_NAME + default "roc-pc-rk3576" + +endif diff --git a/board/firefly/roc-pc-rk3576/MAINTAINERS b/board/firefly/roc-pc-rk3576/MAINTAINERS new file mode 100644 index 00000000000..aa8897c16fc --- /dev/null +++ b/board/firefly/roc-pc-rk3576/MAINTAINERS @@ -0,0 +1,7 @@ +ROC-RK3576-PC +M: Heiko Stuebner <heiko@sntech.de> +S: Maintained +F: board/firefly/roc-pc-rk3576 +F: include/configs/roc-pc-rk3576.h +F: configs/roc-pc-rk3576_defconfig +F: arch/arm/dts/rk3576-roc-pc* diff --git a/board/imgtec/boston/Kconfig b/board/imgtec/boston/Kconfig index 5537788001a..965847d9650 100644 --- a/board/imgtec/boston/Kconfig +++ b/board/imgtec/boston/Kconfig @@ -9,6 +9,10 @@ config SYS_VENDOR config SYS_CONFIG_NAME default "boston" + +config ENV_SOURCE_FILE + default "boston" + config TEXT_BASE default 0x9fc00000 if 32BIT default 0xffffffff9fc00000 if 64BIT diff --git a/board/imgtec/boston/MAINTAINERS b/board/imgtec/boston/MAINTAINERS index 07f6156ffcb..b03a6487db2 100644 --- a/board/imgtec/boston/MAINTAINERS +++ b/board/imgtec/boston/MAINTAINERS @@ -1,6 +1,7 @@ BOSTON BOARD -M: Paul Burton <paul.burton@mips.com> +M: Paul Burton <paulburton@kernel.org> S: Maintained +F: arch/mips/dts/boston-u-boot.dtsi F: board/imgtec/boston/ F: include/configs/boston.h F: configs/boston32r2_defconfig diff --git a/board/imgtec/boston/boston.env b/board/imgtec/boston/boston.env new file mode 100644 index 00000000000..796e0fd6bf9 --- /dev/null +++ b/board/imgtec/boston/boston.env @@ -0,0 +1,9 @@ +#ifdef CONFIG_64BIT +fdt_addr_r=0xffffffff80001000 +kernel_addr_r=0xffffffff88000000 +ramdisk_addr_r=0xffffffff8b000000 +#else +fdt_addr_r=0x80001000 +kernel_addr_r=0x88000000 +ramdisk_addr_r=0x8b000000 +#endif diff --git a/board/imgtec/malta/MAINTAINERS b/board/imgtec/malta/MAINTAINERS index b1cf297f4fa..252c5e45ab5 100644 --- a/board/imgtec/malta/MAINTAINERS +++ b/board/imgtec/malta/MAINTAINERS @@ -1,5 +1,5 @@ MALTA BOARD -M: Paul Burton <paul.burton@mips.com> +M: Paul Burton <paulburton@kernel.org> S: Maintained F: board/imgtec/malta/ F: include/configs/malta.h diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 6ecd3eb120f..1b0b664fa2b 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -359,9 +359,6 @@ static void set_fdtfile(void) */ static void set_fdt_addr(void) { - if (env_get("fdt_addr")) - return; - if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) return; @@ -602,6 +599,9 @@ void update_fdt_from_fw(void *fdt, void *fw_fdt) /* Bluetooth device address as provided by the firmware */ copy_property(fdt, fw_fdt, "/soc/serial@7e201000/bluetooth", "local-bd-address"); + + /* copy uart clk as provided by the firmware */ + copy_property(fdt, fw_fdt, "/clocks/clk-uart", "clock-frequency"); } int ft_board_setup(void *blob, struct bd_info *bd) diff --git a/board/raspberrypi/rpi/rpi.env b/board/raspberrypi/rpi/rpi.env index 30228285edd..9ac9d6768ca 100644 --- a/board/raspberrypi/rpi/rpi.env +++ b/board/raspberrypi/rpi/rpi.env @@ -48,30 +48,33 @@ dfu_alt_info+=zImage fat 0 1 * * scriptaddr and pxefile_addr_r can be pretty much anywhere that doesn't * conflict with something else. Reserving 1M for each of them at - * 0x02400000-0x02500000 and 0x02500000-0x02600000 should be plenty. + * 0x05400000-0x05500000 and 0x05500000-0x05600000 should be plenty. * * On ARM, both the DTB and any possible initrd must be loaded such that they * fit inside the lowmem mapping in Linux. In practice, this usually means not * more than ~700M away from the start of the kernel image but this number can * be larger OR smaller depending on e.g. the 'vmalloc=xxxM' command line * parameter given to the kernel. So reserving memory from low to high - * satisfies this constraint again. Reserving 1M at 0x02600000-0x02700000 for - * the DTB leaves rest of the free RAM to the initrd starting at 0x02700000. - * Even with the smallest possible CPU-GPU memory split of the CPU getting - * only 64M, the remaining 25M starting at 0x02700000 should allow quite - * large initrds before they start colliding with U-Boot. + * satisfies this constraint again. Reserving 1M at 0x05600000-0x05700000 for + * the DTB leaves rest of the free RAM to the initrd starting at 0x05700000. + * This means that the board must have at least 128MB of RAM available to + * U-Boot, more if the initrd is large. + * + * For compressed kernels, the maximum size is just under 32MB, with an area for + * decompression at 0x02000000 with space for 52MB, which is plenty for current + * kernels. + * + * limit bootm_size to 512MB so that all boot images stay within the bottom + * 512MB of memory */ -#ifdef CONFIG_ARM64 -fdt_high=ffffffffffffffff -initrd_high=ffffffffffffffff -#else -fdt_high=ffffffff -initrd_high=ffffffff -#endif +bootm_size=0x20000000 + kernel_addr_r=0x00080000 -scriptaddr=0x02400000 -pxefile_addr_r=0x02500000 -fdt_addr_r=0x02600000 -ramdisk_addr_r=0x02700000 +kernel_comp_addr_r=0x02000000 +kernel_comp_size=0x03400000 +scriptaddr=0x05400000 +pxefile_addr_r=0x05500000 +fdt_addr_r=0x05600000 +ramdisk_addr_r=0x05700000 boot_targets=mmc usb pxe dhcp diff --git a/board/rockchip/evb_rk3328/MAINTAINERS b/board/rockchip/evb_rk3328/MAINTAINERS index 5f81be55b8e..8c9b42fe2bb 100644 --- a/board/rockchip/evb_rk3328/MAINTAINERS +++ b/board/rockchip/evb_rk3328/MAINTAINERS @@ -7,6 +7,12 @@ F: configs/evb-rk3328_defconfig F: arch/arm/dts/rk3328-evb.dts F: arch/arm/dts/rk3328-evb-u-boot.dtsi +GENERIC-RK3328 +M: Jonas Karlman <jonas@kwiboo.se> +S: Maintained +F: configs/generic-rk3328_defconfig +F: arch/arm/dts/rk3328-generic* + NANOPI-R2C-RK3328 M: Tianling Shen <cnsztl@gmail.com> S: Maintained diff --git a/board/rockchip/evb_rk3399/MAINTAINERS b/board/rockchip/evb_rk3399/MAINTAINERS index 8dab3fa70f5..8319db2e976 100644 --- a/board/rockchip/evb_rk3399/MAINTAINERS +++ b/board/rockchip/evb_rk3399/MAINTAINERS @@ -14,6 +14,12 @@ S: Maintained F: configs/eaidk-610-rk3399_defconfig F: arch/arm/dts/rk3399-eaidk-610* +GENERIC-RK3399 +M: Jonas Karlman <jonas@kwiboo.se> +S: Maintained +F: configs/generic-rk3399_defconfig +F: arch/arm/dts/rk3399-generic* + KHADAS-EDGE M: Nick Xie <nick@khadas.com> S: Maintained diff --git a/board/sandbox/sandbox.env b/board/sandbox/sandbox.env index a2c19702d64..29197f56e95 100644 --- a/board/sandbox/sandbox.env +++ b/board/sandbox/sandbox.env @@ -8,6 +8,11 @@ stderr=serial,vidconsole ethaddr=02:00:11:22:33:44 eth6addr=02:00:11:22:33:47 ipaddr=192.0.2.1 +ipaddr2=192.0.2.3 +ipaddr3=192.0.2.4 +ipaddr5=192.0.2.6 +ipaddr6=192.0.2.7 +ipaddr7=192.0.2.8 /* * These are used for distro boot which is not supported. But once bootmethod diff --git a/board/theobroma-systems/common/Makefile b/board/theobroma-systems/common/Makefile new file mode 100644 index 00000000000..c1cadb4b913 --- /dev/null +++ b/board/theobroma-systems/common/Makefile @@ -0,0 +1,9 @@ +# +# Copyright (c) 2025 Cherry Embedded Solutions GmbH +# +# SPDX-License-Identifier: GPL-2.0+ +# + +ifneq ($(CONFIG_XPL_BUILD),y) +obj-y += common.o +endif diff --git a/board/theobroma-systems/jaguar_rk3588/Makefile b/board/theobroma-systems/jaguar_rk3588/Makefile index d43bf194b68..38b73d2846c 100644 --- a/board/theobroma-systems/jaguar_rk3588/Makefile +++ b/board/theobroma-systems/jaguar_rk3588/Makefile @@ -5,6 +5,3 @@ # obj-y += jaguar_rk3588.o -ifneq ($(CONFIG_XPL_BUILD),y) -obj-y += ../common/common.o -endif diff --git a/board/theobroma-systems/puma_rk3399/Makefile b/board/theobroma-systems/puma_rk3399/Makefile index 2256e72cda1..d962b56f111 100644 --- a/board/theobroma-systems/puma_rk3399/Makefile +++ b/board/theobroma-systems/puma_rk3399/Makefile @@ -5,6 +5,3 @@ # obj-y += puma-rk3399.o -ifneq ($(CONFIG_XPL_BUILD),y) -obj-y += ../common/common.o -endif diff --git a/board/theobroma-systems/ringneck_px30/Makefile b/board/theobroma-systems/ringneck_px30/Makefile index 4d108f2d011..31ada1a6942 100644 --- a/board/theobroma-systems/ringneck_px30/Makefile +++ b/board/theobroma-systems/ringneck_px30/Makefile @@ -5,6 +5,3 @@ # obj-y += ringneck-px30.o -ifneq ($(CONFIG_XPL_BUILD),y) -obj-y += ../common/common.o -endif diff --git a/board/theobroma-systems/tiger_rk3588/Makefile b/board/theobroma-systems/tiger_rk3588/Makefile index 94b0859eb35..900647735fb 100644 --- a/board/theobroma-systems/tiger_rk3588/Makefile +++ b/board/theobroma-systems/tiger_rk3588/Makefile @@ -5,6 +5,3 @@ # obj-y += tiger_rk3588.o -ifneq ($(CONFIG_XPL_BUILD),y) -obj-y += ../common/common.o -endif diff --git a/cmd/bootefi.c b/cmd/bootefi.c index dce8285b047..cea6d356ee6 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -38,6 +38,9 @@ static efi_status_t bootefi_run_prepare(const char *load_options_path, if (ret != EFI_SUCCESS) return ret; + (*image_objp)->auth_status = EFI_IMAGE_AUTH_PASSED; + (*image_objp)->entry = efi_selftest; + /* Transfer environment variable as load options */ return efi_env_set_load_options((efi_handle_t)*image_objp, load_options_path, @@ -106,8 +109,8 @@ static int do_efi_selftest(void) return CMD_RET_FAILURE; /* Execute the test */ - ret = EFI_CALL(efi_selftest(&image_obj->header, &systab)); - free(loaded_image_info->load_options); + ret = do_bootefi_exec(&image_obj->header, + loaded_image_info->load_options); efi_free_pool(test_device_path); efi_free_pool(test_image_path); if (ret != EFI_SUCCESS) diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c index e08b6ba4a5d..629bf1b82c7 100644 --- a/cmd/eficonfig.c +++ b/cmd/eficonfig.c @@ -2283,26 +2283,11 @@ static efi_status_t eficonfig_init(void) { efi_status_t ret = EFI_SUCCESS; static bool init; - struct efi_handler *handler; unsigned long columns, rows; if (!init) { - ret = efi_search_protocol(efi_root, &efi_guid_text_input_protocol, &handler); - if (ret != EFI_SUCCESS) - return ret; - - ret = efi_protocol_open(handler, (void **)&cin, efi_root, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (ret != EFI_SUCCESS) - return ret; - ret = efi_search_protocol(efi_root, &efi_guid_text_output_protocol, &handler); - if (ret != EFI_SUCCESS) - return ret; - - ret = efi_protocol_open(handler, (void **)&cout, efi_root, NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (ret != EFI_SUCCESS) - return ret; + cout = systab.con_out; + cin = systab.con_in; cout->query_mode(cout, cout->mode->mode, &columns, &rows); avail_row = rows - (EFICONFIG_MENU_HEADER_ROW_NUM + diff --git a/cmd/net.c b/cmd/net.c index 79525f73a51..eaa1de5295f 100644 --- a/cmd/net.c +++ b/cmd/net.c @@ -456,8 +456,7 @@ static int netboot_common(enum proto_t proto, struct cmd_tbl *cmdtp, int argc, } #if defined(CONFIG_CMD_PING) -static int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) +int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { if (argc < 2) return CMD_RET_USAGE; diff --git a/cmd/pxe.c b/cmd/pxe.c index 37b8dea6ad6..0f26b3b4219 100644 --- a/cmd/pxe.c +++ b/cmd/pxe.c @@ -13,7 +13,6 @@ #include "pxe_utils.h" -#ifdef CONFIG_CMD_NET const char *pxe_default_paths[] = { #ifdef CONFIG_SYS_SOC #ifdef CONFIG_SYS_BOARD @@ -331,5 +330,3 @@ U_BOOT_CMD(pxe, 4, 1, do_pxe, "get [" USE_IP6_CMD_PARAM "] - try to retrieve a pxe file using tftp\n" "pxe boot [pxefile_addr_r] [-ipv6] - boot from the pxe file at pxefile_addr_r\n" ); - -#endif /* CONFIG_CMD_NET */ diff --git a/common/board_r.c b/common/board_r.c index 65d74e3c092..bc6fd6448c2 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -509,7 +509,7 @@ static int initr_boot_led_on(void) return 0; } -#if defined(CONFIG_CMD_NET) +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) static int initr_net(void) { puts("Net: "); @@ -779,7 +779,7 @@ static void initcall_run_r(void) #if CONFIG_IS_ENABLED(PCI_ENDPOINT) INITCALL(pci_ep_init); #endif -#if CONFIG_IS_ENABLED(CMD_NET) +#if CONFIG_IS_ENABLED(NET) || CONFIG_IS_ENABLED(NET_LWIP) WATCHDOG_RESET(); INITCALL(initr_net); #endif diff --git a/configs/am65x_evm_a53_defconfig b/configs/am65x_evm_a53_defconfig index 12c4cb96815..2cfebac53df 100644 --- a/configs/am65x_evm_a53_defconfig +++ b/configs/am65x_evm_a53_defconfig @@ -35,9 +35,10 @@ CONFIG_PCI=y CONFIG_SPL_LOAD_FIT=y CONFIG_SPL_LOAD_FIT_ADDRESS=0x81000000 CONFIG_SPL_LOAD_FIT_APPLY_OVERLAY=y +CONFIG_BOOTSTD_FULL=y +CONFIG_BOOTSTD_BOOTCOMMAND=y CONFIG_DISTRO_DEFAULTS=y CONFIG_OF_SYSTEM_SETUP=y -CONFIG_BOOTCOMMAND="run findfdt; run distro_bootcmd; run init_${boot}; run boot_rprocs; if test ${boot_fit} -eq 1; then run get_fit_${boot}; run get_overlaystring; run run_fit; else; run get_kern_${boot}; run get_fdt_${boot}; run get_overlay_${boot}; run run_kern; fi;" CONFIG_LOGLEVEL=7 CONFIG_SPL_MAX_SIZE=0x58000 CONFIG_SPL_SYS_MALLOC_SIMPLE=y diff --git a/configs/boston32r2_defconfig b/configs/boston32r2_defconfig index 6f4dfad5a31..5556148f3cf 100644 --- a/configs/boston32r2_defconfig +++ b/configs/boston32r2_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston32r2el_defconfig b/configs/boston32r2el_defconfig index cdf13c8332f..d23eb99518e 100644 --- a/configs/boston32r2el_defconfig +++ b/configs/boston32r2el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston32r6_defconfig b/configs/boston32r6_defconfig index d8fb956914c..56738e955e3 100644 --- a/configs/boston32r6_defconfig +++ b/configs/boston32r6_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston32r6el_defconfig b/configs/boston32r6el_defconfig index b6d3102cf2a..ddc6655dd7c 100644 --- a/configs/boston32r6el_defconfig +++ b/configs/boston32r6el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0x88000000 CONFIG_ENV_ADDR=0xBFFE0000 diff --git a/configs/boston64r2_defconfig b/configs/boston64r2_defconfig index 6b23d180f84..fa234b62305 100644 --- a/configs/boston64r2_defconfig +++ b/configs/boston64r2_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/boston64r2el_defconfig b/configs/boston64r2el_defconfig index ff4b52615a6..58bf8817ab6 100644 --- a/configs/boston64r2el_defconfig +++ b/configs/boston64r2el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/boston64r6_defconfig b/configs/boston64r6_defconfig index a7446ec5555..eb3ec0064dc 100644 --- a/configs/boston64r6_defconfig +++ b/configs/boston64r6_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/boston64r6el_defconfig b/configs/boston64r6el_defconfig index 0dab8efb875..332c2ba39e9 100644 --- a/configs/boston64r6el_defconfig +++ b/configs/boston64r6el_defconfig @@ -4,7 +4,7 @@ CONFIG_SYS_MALLOC_LEN=0x40000 CONFIG_SYS_MALLOC_F_LEN=0x400 CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_SECT_SIZE=0x20000 -CONFIG_DEFAULT_DEVICE_TREE="img,boston" +CONFIG_DEFAULT_DEVICE_TREE="img/boston" CONFIG_SYS_BOOTM_LEN=0x4000000 CONFIG_SYS_LOAD_ADDR=0xffffffff88000000 CONFIG_ENV_ADDR=0xFFFFFFFFBFFE0000 diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig index b7f4a76ce68..2c69e913394 100644 --- a/configs/gardena-smart-gateway-mt7688_defconfig +++ b/configs/gardena-smart-gateway-mt7688_defconfig @@ -47,6 +47,7 @@ CONFIG_SPL_SYS_MALLOC_SIMPLE=y CONFIG_SPL_NOR_SUPPORT=y CONFIG_HUSH_PARSER=y CONFIG_CMD_LICENSE=y +CONFIG_SYS_BOOTM_LEN=0x2000000 # CONFIG_CMD_ELF is not set # CONFIG_CMD_XIMG is not set CONFIG_CMD_MEMINFO=y diff --git a/configs/generic-rk3328_defconfig b/configs/generic-rk3328_defconfig new file mode 100644 index 00000000000..8d34a293fd4 --- /dev/null +++ b/configs/generic-rk3328_defconfig @@ -0,0 +1,90 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_SF_DEFAULT_SPEED=25000000 +CONFIG_DEFAULT_DEVICE_TREE="rk3328-generic" +CONFIG_DM_RESET=y +CONFIG_ROCKCHIP_RK3328=y +CONFIG_ROCKCHIP_EXTERNAL_TPL=y +CONFIG_ROCKCHIP_SPI_IMAGE=y +CONFIG_SYS_LOAD_ADDR=0x800800 +CONFIG_DEBUG_UART_BASE=0xFF130000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_DEBUG_UART=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT=y +# CONFIG_BOOTMETH_VBE is not set +CONFIG_LEGACY_IMAGE_FORMAT=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3328-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_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 +CONFIG_SPL_ATF=y +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +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_ROCKUSB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_RNG=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +# CONFIG_OF_UPSTREAM is not set +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NO_NET=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_SYSCON=y +CONFIG_SPL_SYSCON=y +# CONFIG_ADC is not set +CONFIG_CLK=y +CONFIG_SPL_CLK=y +# CONFIG_USB_FUNCTION_FASTBOOT is not set +CONFIG_ROCKCHIP_GPIO=y +# CONFIG_ROCKCHIP_IODOMAIN is not set +CONFIG_SUPPORT_EMMC_RPMB=y +CONFIG_MMC_DW=y +CONFIG_MMC_DW_ROCKCHIP=y +CONFIG_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SILICONKAISER=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_ZBIT=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_PINCTRL=y +CONFIG_SPL_PINCTRL=y +CONFIG_RAM=y +CONFIG_SPL_RAM=y +CONFIG_DM_RNG=y +CONFIG_RNG_ROCKCHIP=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_ROCKCHIP_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_USB=y +CONFIG_DM_USB_GADGET=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DWC2_OTG=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_FUNCTION_ROCKUSB=y +CONFIG_ERRNO_STR=y diff --git a/configs/generic-rk3399_defconfig b/configs/generic-rk3399_defconfig new file mode 100644 index 00000000000..3abe65bcd68 --- /dev/null +++ b/configs/generic-rk3399_defconfig @@ -0,0 +1,77 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_NR_DRAM_BANKS=1 +CONFIG_SF_DEFAULT_SPEED=25000000 +CONFIG_DEFAULT_DEVICE_TREE="rk3399-generic" +CONFIG_DM_RESET=y +CONFIG_ROCKCHIP_RK3399=y +CONFIG_ROCKCHIP_EXTERNAL_TPL=y +CONFIG_ROCKCHIP_SPI_IMAGE=y +CONFIG_TARGET_EVB_RK3399=y +CONFIG_SYS_LOAD_ADDR=0x800800 +CONFIG_SF_DEFAULT_BUS=1 +CONFIG_DEBUG_UART_BASE=0xFF1A0000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI=y +CONFIG_DEBUG_UART=y +CONFIG_FIT_VERBOSE=y +# CONFIG_BOOTMETH_VBE is not set +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3399-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_SPL_SPI_LOAD=y +CONFIG_SYS_SPI_U_BOOT_OFFS=0xE0000 +CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y +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_ROCKUSB=y +CONFIG_CMD_USB_MASS_STORAGE=y +# CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_RNG=y +# CONFIG_SPL_DOS_PARTITION is not set +CONFIG_SPL_OF_CONTROL=y +# CONFIG_OF_UPSTREAM is not set +CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents" +CONFIG_SYS_RELOC_GD_ENV_ADDR=y +CONFIG_NO_NET=y +# CONFIG_ADC is not set +# CONFIG_USB_FUNCTION_FASTBOOT is not set +CONFIG_ROCKCHIP_GPIO=y +# CONFIG_ROCKCHIP_IODOMAIN is not set +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_SPI_FLASH_SFDP_SUPPORT=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SILICONKAISER=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_XMC=y +CONFIG_SPI_FLASH_XTX=y +CONFIG_SPI_FLASH_ZBIT=y +CONFIG_PHY_ROCKCHIP_INNO_USB2=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_ROCKCHIP_SPI=y +CONFIG_SYSRESET=y +CONFIG_SYSRESET_PSCI=y +CONFIG_USB=y +CONFIG_USB_DWC3=y +CONFIG_USB_DWC3_GENERIC=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_FUNCTION_ROCKUSB=y +CONFIG_ERRNO_STR=y diff --git a/configs/generic-rk3528_defconfig b/configs/generic-rk3528_defconfig new file mode 100644 index 00000000000..e19c7bc4801 --- /dev/null +++ b/configs/generic-rk3528_defconfig @@ -0,0 +1,40 @@ +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_ERRNO_STR=y diff --git a/configs/generic-rk3568_defconfig b/configs/generic-rk3568_defconfig index f79f0e84400..76418ba7032 100644 --- a/configs/generic-rk3568_defconfig +++ b/configs/generic-rk3568_defconfig @@ -28,6 +28,8 @@ CONFIG_SPL_PAD_TO=0x7f8000 CONFIG_SPL_SPI_LOAD=y CONFIG_SYS_SPI_U_BOOT_OFFS=0x60000 CONFIG_SPL_ATF=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMINFO_MAP=y CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y CONFIG_CMD_MISC=y @@ -35,6 +37,7 @@ CONFIG_CMD_MMC=y CONFIG_CMD_ROCKUSB=y CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_RNG=y # CONFIG_SPL_DOS_PARTITION is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_LIVE=y diff --git a/configs/generic-rk3588_defconfig b/configs/generic-rk3588_defconfig index 51e31dce3a9..2075584cf56 100644 --- a/configs/generic-rk3588_defconfig +++ b/configs/generic-rk3588_defconfig @@ -22,6 +22,8 @@ CONFIG_SPL_MAX_SIZE=0x40000 CONFIG_SPL_PAD_TO=0x7f8000 # CONFIG_SPL_RAW_IMAGE_SUPPORT is not set CONFIG_SPL_ATF=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_MEMINFO_MAP=y CONFIG_CMD_GPIO=y CONFIG_CMD_GPT=y CONFIG_CMD_MISC=y @@ -29,6 +31,7 @@ CONFIG_CMD_MMC=y CONFIG_CMD_ROCKUSB=y CONFIG_CMD_USB_MASS_STORAGE=y # CONFIG_CMD_SETEXPR is not set +CONFIG_CMD_RNG=y # CONFIG_SPL_DOS_PARTITION is not set CONFIG_SPL_OF_CONTROL=y CONFIG_OF_LIVE=y diff --git a/configs/qemu-arm-sbsa_defconfig b/configs/qemu-arm-sbsa_defconfig index 8c5d3eb4be8..3819670defe 100644 --- a/configs/qemu-arm-sbsa_defconfig +++ b/configs/qemu-arm-sbsa_defconfig @@ -9,3 +9,4 @@ CONFIG_EFI_PARTITION=y CONFIG_PARTITION_TYPE_GUID=y CONFIG_EFI_MEDIA=y CONFIG_FS_FAT=y +CONFIG_UNIT_TEST=y diff --git a/configs/qemu-ppce500_defconfig b/configs/qemu-ppce500_defconfig index 9f20b3fcd73..a444899db33 100644 --- a/configs/qemu-ppce500_defconfig +++ b/configs/qemu-ppce500_defconfig @@ -66,3 +66,4 @@ CONFIG_VIRTIO_NET=y CONFIG_VIRTIO_BLK=y CONFIG_ADDR_MAP=y CONFIG_PANIC_HANG=y +CONFIG_UNIT_TEST=y diff --git a/configs/qemu-riscv32_spl_defconfig b/configs/qemu-riscv32_spl_defconfig index 9906f8b2dad..8d5f9d9f5cc 100644 --- a/configs/qemu-riscv32_spl_defconfig +++ b/configs/qemu-riscv32_spl_defconfig @@ -26,3 +26,4 @@ CONFIG_DM_MTD=y CONFIG_FLASH_SHOW_PROGRESS=0 CONFIG_SYS_MAX_FLASH_BANKS=2 # CONFIG_BINMAN_FDT is not set +CONFIG_UNIT_TEST=y diff --git a/configs/qemu-riscv64_smode_acpi_defconfig b/configs/qemu-riscv64_smode_acpi_defconfig new file mode 100644 index 00000000000..e78e5ffb390 --- /dev/null +++ b/configs/qemu-riscv64_smode_acpi_defconfig @@ -0,0 +1,2 @@ +#include <configs/qemu-riscv64_smode_defconfig> +#include <board/emulation/configs/acpi.config> diff --git a/configs/qemu-riscv64_spl_defconfig b/configs/qemu-riscv64_spl_defconfig index 27e092bd208..18b7e049d86 100644 --- a/configs/qemu-riscv64_spl_defconfig +++ b/configs/qemu-riscv64_spl_defconfig @@ -25,3 +25,4 @@ CONFIG_DM_MTD=y CONFIG_FLASH_SHOW_PROGRESS=0 CONFIG_SYS_MAX_FLASH_BANKS=2 # CONFIG_BINMAN_FDT is not set +CONFIG_UNIT_TEST=y diff --git a/configs/qemu-x86_64_defconfig b/configs/qemu-x86_64_defconfig index 58b1fbf132d..47075dc265a 100644 --- a/configs/qemu-x86_64_defconfig +++ b/configs/qemu-x86_64_defconfig @@ -93,3 +93,4 @@ CONFIG_SPL_VIDEO=y CONFIG_GENERATE_ACPI_TABLE=y CONFIG_CMD_DHRYSTONE=y # CONFIG_GZIP is not set +CONFIG_UNIT_TEST=y diff --git a/configs/qemu_arm64_acpi_defconfig b/configs/qemu_arm64_acpi_defconfig new file mode 100644 index 00000000000..f85f2913530 --- /dev/null +++ b/configs/qemu_arm64_acpi_defconfig @@ -0,0 +1,2 @@ +#include <configs/qemu_arm64_defconfig> +#include <board/emulation/configs/acpi.config> diff --git a/configs/radxa-e20c-rk3528_defconfig b/configs/radxa-e20c-rk3528_defconfig new file mode 100644 index 00000000000..08f3a13af3b --- /dev/null +++ b/configs/radxa-e20c-rk3528_defconfig @@ -0,0 +1,56 @@ +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_REGULATOR_PWM=y +CONFIG_DM_REGULATOR_GPIO=y +CONFIG_PWM_ROCKCHIP=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_USB=y +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_GENERIC=y +CONFIG_ERRNO_STR=y diff --git a/configs/ringneck-px30_defconfig b/configs/ringneck-px30_defconfig index 324581b4082..b6b3d3e2b3f 100644 --- a/configs/ringneck-px30_defconfig +++ b/configs/ringneck-px30_defconfig @@ -5,6 +5,7 @@ CONFIG_ARCH_ROCKCHIP=y CONFIG_SPL_GPIO=y CONFIG_NR_DRAM_BANKS=2 CONFIG_DEFAULT_DEVICE_TREE="rockchip/px30-ringneck-haikou" +CONFIG_OF_LIBFDT_OVERLAY=y CONFIG_DM_RESET=y CONFIG_ROCKCHIP_PX30=y # CONFIG_TPL_ROCKCHIP_COMMON_BOARD is not set diff --git a/configs/roc-pc-rk3576_defconfig b/configs/roc-pc-rk3576_defconfig new file mode 100644 index 00000000000..af2c1026636 --- /dev/null +++ b/configs/roc-pc-rk3576_defconfig @@ -0,0 +1,45 @@ +CONFIG_ARM=y +CONFIG_SKIP_LOWLEVEL_INIT=y +CONFIG_COUNTER_FREQUENCY=24000000 +CONFIG_ARCH_ROCKCHIP=y +CONFIG_DEFAULT_DEVICE_TREE="rockchip/rk3576-roc-pc" +CONFIG_ROCKCHIP_RK3576=y +CONFIG_TARGET_ROC_PC_RK3576=y +CONFIG_SYS_LOAD_ADDR=0x40c00800 +CONFIG_DEBUG_UART_BASE=0x2AD40000 +CONFIG_DEBUG_UART_CLOCK=24000000 +CONFIG_DEBUG_UART=y +CONFIG_DEFAULT_FDT_FILE="rockchip/rk3576-roc-pc.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_GPIO=y +CONFIG_CMD_GPT=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MMC=y +# CONFIG_CMD_SETEXPR is not set +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_ROCKCHIP_GPIO=y +CONFIG_SYS_I2C_ROCKCHIP=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_DWC_ETH_QOS=y +CONFIG_DWC_ETH_QOS_ROCKCHIP=y +CONFIG_DM_PMIC=y +CONFIG_PMIC_RK8XX=y +CONFIG_REGULATOR_RK8XX=y +CONFIG_BAUDRATE=1500000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_SYS_NS16550_MEM32=y +CONFIG_SYSRESET_PSCI=y +CONFIG_ERRNO_STR=y diff --git a/configs/sandbox64_lwip_defconfig b/configs/sandbox64_lwip_defconfig new file mode 100644 index 00000000000..0e92728533f --- /dev/null +++ b/configs/sandbox64_lwip_defconfig @@ -0,0 +1,5 @@ +#include <configs/sandbox64_defconfig> + +CONFIG_SANDBOX=y + +CONFIG_NET_LWIP=y diff --git a/configs/socfpga_agilex5_defconfig b/configs/socfpga_agilex5_defconfig index 8f327e5f2ab..4ac0a5d9b99 100644 --- a/configs/socfpga_agilex5_defconfig +++ b/configs/socfpga_agilex5_defconfig @@ -1,6 +1,7 @@ CONFIG_ARM=y CONFIG_ARCH_SOCFPGA=y CONFIG_TEXT_BASE=0x80200000 +CONFIG_SPL_GPIO=y CONFIG_NR_DRAM_BANKS=3 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x80300000 @@ -31,6 +32,8 @@ CONFIG_USE_BOOTARGS=y CONFIG_BOOTARGS="console=ttyS0,115200 initrd=0x90000000 root=/dev/ram0 rw init=/sbin/init ramdisk_size=10000000 earlycon panic=-1 nosmp kvm-arm.mode=nvhe" CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BLOBLIST=y +CONFIG_BLOBLIST_FIXED=y +CONFIG_BLOBLIST_ADDR=0x7e000 CONFIG_BLOBLIST_SIZE=0x1000 CONFIG_SPL_MAX_SIZE=0x40000 CONFIG_HANDOFF=y @@ -73,6 +76,8 @@ CONFIG_BOOTFILE="kernel.itb" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM_SEQ_ALIAS=y CONFIG_SPL_ALTERA_SDRAM=y +CONFIG_GPIO_HOG=y +CONFIG_SPL_GPIO_HOG=y CONFIG_DWAPB_GPIO=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_DW=y @@ -82,6 +87,7 @@ CONFIG_SPI_FLASH_SPANSION=y CONFIG_SPI_FLASH_STMICRO=y # CONFIG_SPI_FLASH_USE_4K_SECTORS is not set CONFIG_SPI_FLASH_MTD=y +CONFIG_PHY_MARVELL=y CONFIG_DWC_ETH_XGMAC=y CONFIG_RGMII=y CONFIG_SYS_NS16550_MEM32=y diff --git a/configs/socfpga_agilex5_vab_defconfig b/configs/socfpga_agilex5_vab_defconfig new file mode 100644 index 00000000000..a5f4b335760 --- /dev/null +++ b/configs/socfpga_agilex5_vab_defconfig @@ -0,0 +1,3 @@ +#include <configs/socfpga_agilex5_defconfig> + +CONFIG_SOCFPGA_SECURE_VAB_AUTH=y diff --git a/doc/board/rockchip/rockchip.rst b/doc/board/rockchip/rockchip.rst index 1407080f1f4..b06f87b137c 100644 --- a/doc/board/rockchip/rockchip.rst +++ b/doc/board/rockchip/rockchip.rst @@ -66,6 +66,7 @@ List of mainline supported Rockchip boards: - FriendlyElec NanoPi R2C Plus (nanopi-r2c-plus-rk3328) - FriendlyElec NanoPi R2S (nanopi-r2s-rk3328) - FriendlyElec NanoPi R2S Plus (nanopi-r2s-plus-rk3328) + - Generic RK3328 (generic-rk3328) - Pine64 Rock64 (rock64-rk3328) - Radxa ROCK Pi E (rock-pi-e-rk3328) - Xunlong Orange Pi R1 Plus (orangepi-r1-plus-rk3328) @@ -83,6 +84,7 @@ List of mainline supported Rockchip boards: - FriendlyElec NanoPi M4 (nanopi-m4-rk3399) - FriendlyElec NanoPi M4B (nanopi-m4b-rk3399) - FriendlyARM NanoPi NEO4 (nanopi-neo4-rk3399) + - Generic RK3399 (generic-rk3399) - Google Bob (chromebook_bob) - Google Kevin (chromebook_kevin) - Khadas Edge (khadas-edge-rk3399) @@ -97,6 +99,10 @@ List of mainline supported Rockchip boards: - Rockchip Evb-RK3399 (evb_rk3399) - Theobroma Systems RK3399-Q7 SoM - Puma (puma_rk3399) +* rk3528 + - Generic RK3528 (generic-rk3528) + - Radxa E20C (radxa-e20c-rk3528) + * rk3566 - Anbernic RGxx3 (anbernic-rgxx3-rk3566) - FriendlyElec NanoPi R3S (nanopi-r3s-rk3566) @@ -126,6 +132,9 @@ List of mainline supported Rockchip boards: - Radxa ROCK 3A (rock-3a-rk3568) - Radxa ROCK 3B (rock-3b-rk3568) +* rk3576 + - Firefly ROC-RK3576-PC (roc-pc-rk3576) + * rk3588 - ArmSoM Sige7 (sige7-rk3588) - Rockchip EVB (evb-rk3588) @@ -258,6 +267,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 @@ -268,6 +286,15 @@ To build rk3568 boards: make evb-rk3568_defconfig make CROSS_COMPILE=aarch64-linux-gnu- +To build rk3576 boards: + +.. code-block:: bash + + export BL31=../rkbin/bin/rk35/rk3576_bl31_v1.04.elf + export ROCKCHIP_TPL=../rkbin/bin/rk35/rk3576_ddr_lp4_2112MHz_lp5_2736MHz_v1.03.bin + make roc-pc-rk3576_defconfig + make CROSS_COMPILE=aarch64-linux-gnu- + To build rk3588 boards: .. code-block:: bash diff --git a/doc/develop/devicetree/dt_qemu.rst b/doc/develop/devicetree/dt_qemu.rst index 8ba2b225590..b452e2a997a 100644 --- a/doc/develop/devicetree/dt_qemu.rst +++ b/doc/develop/devicetree/dt_qemu.rst @@ -16,15 +16,22 @@ Obtaining the QEMU devicetree Where QEMU generates its own devicetree to pass to U-Boot you can use `-dtb u-boot.dtb` to force QEMU to use U-Boot's in-tree version. -To obtain the devicetree that qemu generates, add `-machine dumpdtb=qemu.dtb`, -e.g.:: - - qemu-system-arm -machine virt -machine dumpdtb=qemu.dtb - - qemu-system-aarch64 -machine virt -machine dumpdtb=qemu.dtb - - qemu-system-riscv64 -machine virt -machine dumpdtb=qemu.dtb - +To obtain the devicetree that QEMU generates, add `dumpdtb=qemu.dtb` to the +`-machine` argument, e.g. + +.. code-block:: bash + + qemu-system-aarch64 \ + -machine virt,gic-version=3,dumpdtb=qemu.dtb \ + -cpu cortex-a57 \ + -smp 4 \ + -memory 8G \ + -chardev socket,id=chrtpm,path=/tmp/mytpm1/swtpm-sock \ + -tpmdev emulator,id=tpm0,chardev=chrtpm \ + -device tpm-tis-device,tpmdev=tpm0 + +Except for the dumpdtb=qemu.dtb sub-parameter use the same qemu-system-<arch> +invocation that you would use to start U-Boot to to get a complete device-tree. Merging in U-Boot nodes/properties ---------------------------------- diff --git a/doc/develop/release_cycle.rst b/doc/develop/release_cycle.rst index cbbc2bad0eb..50948c00927 100644 --- a/doc/develop/release_cycle.rst +++ b/doc/develop/release_cycle.rst @@ -1,3 +1,5 @@ +.. |next_ver| replace:: v2025.07 + Release Cycle ============= @@ -53,13 +55,13 @@ Current Status * U-Boot v2025.04 was released on Monday, 07 April 2025. -* The Merge Window for the next release (v2025.07) is **open** until the -rc1 +* The Merge Window for the next release (|next_ver|) is **open** until the -rc1 release on Monday, 28 April 2025. * The next branch is now **closed** until the -rc2 release on Monday, 12 May 2025. -* Release "v2025.07" is scheduled for Monday, 07 July 2025. +* Release "|next_ver|" is scheduled for Monday, 07 July 2025. Future Releases --------------- @@ -69,15 +71,15 @@ Future Releases .. For the next scheduled release, release candidates were made on:: -.. * U-Boot v2025.07-rc1 was released on Mon 21 April 2025. +.. * U-Boot |next_ver|-rc1 was released on Mon 21 April 2025. -.. * U-Boot v2025.07-rc2 was released on Mon 12 May 2025. +.. * U-Boot |next_ver|-rc2 was released on Mon 12 May 2025. -.. * U-Boot v2025.07-rc3 was released on Mon 26 May 2025. +.. * U-Boot |next_ver|-rc3 was released on Mon 26 May 2025. -.. * U-Boot v2025.07-rc4 was released on Mon 09 June 2025. +.. * U-Boot |next_ver|-rc4 was released on Mon 09 June 2025. -.. * U-Boot v2025.07-rc5 was released on Mon 23 June 2025. +.. * U-Boot |next_ver|-rc5 was released on Mon 23 June 2025. Please note that the following dates are planned only and may be deviated from as needed. diff --git a/drivers/adc/rockchip-saradc.c b/drivers/adc/rockchip-saradc.c index 7cf9735f60d..1515951403c 100644 --- a/drivers/adc/rockchip-saradc.c +++ b/drivers/adc/rockchip-saradc.c @@ -339,6 +339,14 @@ static const struct rockchip_saradc_data rk3399_saradc_data = { .stop = rockchip_saradc_stop_v1, }; +static const struct rockchip_saradc_data rk3528_saradc_data = { + .num_bits = 10, + .num_channels = 4, + .clk_rate = 1000000, + .channel_data = rockchip_saradc_channel_data_v2, + .start_channel = rockchip_saradc_start_channel_v2, +}; + static const struct rockchip_saradc_data rk3588_saradc_data = { .num_bits = 12, .num_channels = 8, @@ -354,6 +362,8 @@ static const struct udevice_id rockchip_saradc_ids[] = { .data = (ulong)&rk3066_tsadc_data }, { .compatible = "rockchip,rk3399-saradc", .data = (ulong)&rk3399_saradc_data }, + { .compatible = "rockchip,rk3528-saradc", + .data = (ulong)&rk3528_saradc_data }, { .compatible = "rockchip,rk3588-saradc", .data = (ulong)&rk3588_saradc_data }, { } diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index b532b3b7339..38e953ee79c 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -420,7 +420,7 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 opts) { - phys_addr_t pa = virt_to_phys((void *)pp->cmd_tbl); + phys_addr_t pa = virt_to_phys(pp->cmd_tbl); pp->cmd_slot->opts = cpu_to_le32(opts); pp->cmd_slot->status = 0; @@ -449,7 +449,7 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { struct ahci_ioports *pp = &(uc_priv->port[port]); void __iomem *port_mmio = pp->port_mmio; - u64 dma_addr; + phys_addr_t dma_addr; u32 port_status; void __iomem *mem; @@ -472,34 +472,32 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) * First item in chunk of DMA memory: 32-slot command table, * 32 bytes each in size */ - pp->cmd_slot = - (struct ahci_cmd_hdr *)(uintptr_t)virt_to_phys((void *)mem); - debug("cmd_slot = %p\n", pp->cmd_slot); - mem += (AHCI_CMD_SLOT_SZ + 224); + pp->cmd_slot = (struct ahci_cmd_hdr *)mem; + mem += AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT; /* * Second item: Received-FIS area */ - pp->rx_fis = virt_to_phys((void *)mem); + pp->rx_fis = mem; mem += AHCI_RX_FIS_SZ; /* * Third item: data area for storing a single command * and its scatter-gather table */ - pp->cmd_tbl = virt_to_phys((void *)mem); - debug("cmd_tbl_dma = %lx\n", pp->cmd_tbl); + pp->cmd_tbl = mem; mem += AHCI_CMD_TBL_HDR; - pp->cmd_tbl_sg = - (struct ahci_sg *)(uintptr_t)virt_to_phys((void *)mem); - - dma_addr = (ulong)pp->cmd_slot; - writel_with_flush(dma_addr, port_mmio + PORT_LST_ADDR); - writel_with_flush(dma_addr >> 32, port_mmio + PORT_LST_ADDR_HI); - dma_addr = (ulong)pp->rx_fis; - writel_with_flush(dma_addr, port_mmio + PORT_FIS_ADDR); - writel_with_flush(dma_addr >> 32, port_mmio + PORT_FIS_ADDR_HI); + pp->cmd_tbl_sg = (struct ahci_sg *)(mem); + + dma_addr = virt_to_phys(pp->cmd_slot); + debug("cmd_slot_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), port_mmio + PORT_LST_ADDR); + writel_with_flush(upper_32_bits(dma_addr), port_mmio + PORT_LST_ADDR_HI); + dma_addr = virt_to_phys(pp->rx_fis); + debug("rx_fis_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), port_mmio + PORT_FIS_ADDR); + writel_with_flush(upper_32_bits(dma_addr), port_mmio + PORT_FIS_ADDR_HI); #ifdef CONFIG_SUNXI_AHCI sunxi_dma_init(port_mmio); diff --git a/drivers/ata/dwc_ahsata.c b/drivers/ata/dwc_ahsata.c index 203f98edffc..d225289fe6e 100644 --- a/drivers/ata/dwc_ahsata.c +++ b/drivers/ata/dwc_ahsata.c @@ -7,6 +7,7 @@ #include <ahci.h> #include <blk.h> #include <bootdev.h> +#include <clk.h> #include <cpu_func.h> #include <dm.h> #include <dwc_ahsata.h> @@ -19,9 +20,11 @@ #include <sata.h> #include <asm/cache.h> #include <asm/io.h> +#if IS_ENABLED(CONFIG_ARCH_MX5) || IS_ENABLED(CONFIG_ARCH_MX6) #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> #include <asm/mach-imx/sata.h> +#endif #include <linux/bitops.h> #include <linux/ctype.h> #include <linux/delay.h> @@ -116,13 +119,12 @@ static int ahci_setup_oobr(struct ahci_uc_priv *uc_priv, int clk) return 0; } -static int ahci_host_init(struct ahci_uc_priv *uc_priv) +static int ahci_host_init(struct ahci_uc_priv *uc_priv, int clk) { u32 tmp, cap_save, num_ports; int i, j, timeout = 1000; struct sata_port_regs *port_mmio = NULL; struct sata_host_regs *host_mmio = uc_priv->mmio_base; - int clk = mxc_get_clock(MXC_SATA_CLK); cap_save = readl(&host_mmio->cap); cap_save |= SATA_HOST_CAP_SSS; @@ -330,6 +332,7 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, { struct ahci_ioports *pp = &uc_priv->port[port]; struct ahci_sg *ahci_sg = pp->cmd_tbl_sg; + phys_addr_t pa = virt_to_phys(buf); u32 sg_count, max_bytes; int i; @@ -341,9 +344,8 @@ static int ahci_fill_sg(struct ahci_uc_priv *uc_priv, u8 port, } for (i = 0; i < sg_count; i++) { - ahci_sg->addr = - cpu_to_le32((u32)buf + i * max_bytes); - ahci_sg->addr_hi = 0; + ahci_sg->addr = cpu_to_le32(lower_32_bits(pa)); + ahci_sg->addr_hi = cpu_to_le32(upper_32_bits(pa)); ahci_sg->flags_size = cpu_to_le32(0x3fffff & (buf_len < max_bytes ? (buf_len - 1) @@ -359,14 +361,14 @@ static void ahci_fill_cmd_slot(struct ahci_ioports *pp, u32 cmd_slot, u32 opts) { struct ahci_cmd_hdr *cmd_hdr = (struct ahci_cmd_hdr *)(pp->cmd_slot + AHCI_CMD_SLOT_SZ * cmd_slot); + phys_addr_t pa = virt_to_phys(pp->cmd_tbl); memset(cmd_hdr, 0, AHCI_CMD_SLOT_SZ); cmd_hdr->opts = cpu_to_le32(opts); cmd_hdr->status = 0; - pp->cmd_slot->tbl_addr = cpu_to_le32((u32)pp->cmd_tbl & 0xffffffff); + pp->cmd_slot->tbl_addr = cpu_to_le32(lower_32_bits(pa)); #ifdef CONFIG_PHYS_64BIT - pp->cmd_slot->tbl_addr_hi = - cpu_to_le32((u32)(((pp->cmd_tbl) >> 16) >> 16)); + pp->cmd_slot->tbl_addr_hi = cpu_to_le32(upper_32_bits(pa)); #endif } @@ -404,7 +406,7 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, } ahci_fill_cmd_slot(pp, cmd_slot, opts); - flush_cache((int)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ); + flush_cache((ulong)(pp->cmd_slot), AHCI_PORT_PRIV_DMA_SZ); writel_with_flush(1 << cmd_slot, &port_mmio->ci); if (waiting_for_cmd_completed((u8 *)&port_mmio->ci, 10000, @@ -412,8 +414,8 @@ static int ahci_exec_ata_cmd(struct ahci_uc_priv *uc_priv, u8 port, printf("timeout exit!\n"); return -1; } - invalidate_dcache_range((int)(pp->cmd_slot), - (int)(pp->cmd_slot)+AHCI_PORT_PRIV_DMA_SZ); + invalidate_dcache_range((ulong)(pp->cmd_slot), + (ulong)(pp->cmd_slot) + AHCI_PORT_PRIV_DMA_SZ); debug("ahci_exec_ata_cmd: %d byte transferred.\n", pp->cmd_slot->status); if (!is_write) @@ -441,8 +443,9 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) { struct ahci_ioports *pp = &uc_priv->port[port]; struct sata_port_regs *port_mmio = pp->port_mmio; + phys_addr_t dma_addr; u32 port_status; - u32 mem; + void *mem; int timeout = 10000000; debug("Enter start port: %d\n", port); @@ -453,22 +456,20 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) return -1; } - mem = (u32)malloc(AHCI_PORT_PRIV_DMA_SZ + 1024); + mem = memalign(2048, AHCI_PORT_PRIV_DMA_SZ); if (!mem) { printf("No mem for table!\n"); return -ENOMEM; } - mem = (mem + 0x400) & (~0x3ff); /* Aligned to 1024-bytes */ - memset((u8 *)mem, 0, AHCI_PORT_PRIV_DMA_SZ); + memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); /* * First item in chunk of DMA memory: 32-slot command table, * 32 bytes each in size */ pp->cmd_slot = (struct ahci_cmd_hdr *)mem; - debug("cmd_slot = 0x%x\n", (unsigned int) pp->cmd_slot); - mem += (AHCI_CMD_SLOT_SZ * DWC_AHSATA_MAX_CMD_SLOTS); + mem += AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT; /* * Second item: Received-FIS area, 256-Byte aligned @@ -481,14 +482,19 @@ static int ahci_port_start(struct ahci_uc_priv *uc_priv, u8 port) * and its scatter-gather table */ pp->cmd_tbl = mem; - debug("cmd_tbl_dma = 0x%lx\n", pp->cmd_tbl); - mem += AHCI_CMD_TBL_HDR; + pp->cmd_tbl_sg = (struct ahci_sg *)mem; writel_with_flush(0x00004444, &port_mmio->dmacr); - pp->cmd_tbl_sg = (struct ahci_sg *)mem; - writel_with_flush((u32)pp->cmd_slot, &port_mmio->clb); - writel_with_flush(pp->rx_fis, &port_mmio->fb); + dma_addr = virt_to_phys(pp->cmd_slot); + debug("cmd_slot_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), &port_mmio->clb); + writel_with_flush(upper_32_bits(dma_addr), &port_mmio->clbu); + dma_addr = virt_to_phys(pp->cmd_slot); + debug("rx_fis_slot_dma = 0x%08llx\n", (u64)dma_addr); + writel_with_flush(lower_32_bits(dma_addr), &port_mmio->fb); + writel_with_flush(upper_32_bits(dma_addr), &port_mmio->fbu); + /* Enable FRE */ writel_with_flush((SATA_PORT_CMD_FRE | readl(&port_mmio->cmd)), @@ -910,17 +916,41 @@ int dwc_ahsata_scan(struct udevice *dev) int dwc_ahsata_probe(struct udevice *dev) { struct ahci_uc_priv *uc_priv = dev_get_uclass_priv(dev); + struct clk_bulk clk_bulk __maybe_unused; + struct clk clk __maybe_unused; + int sataclk; int ret; -#if defined(CONFIG_MX6) +#if IS_ENABLED(CONFIG_MX6) setup_sata(); #endif +#if IS_ENABLED(CONFIG_MX5) || IS_ENABLED(CONFIG_MX6) + sataclk = mxc_get_clock(MXC_SATA_CLK); +#else + ret = clk_get_bulk(dev, &clk_bulk); + if (ret) + return ret; + + ret = clk_enable_bulk(&clk_bulk); + if (ret) + return ret; + + ret = clk_get_by_name(dev, "sata", &clk); + if (ret) + return ret; + + sataclk = clk_get_rate(&clk); +#endif + if (IS_ERR_VALUE(sataclk)) { + log_err("Unable to get SATA clock rate\n"); + return -EINVAL; + } uc_priv->host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | ATA_FLAG_NO_ATAPI; uc_priv->mmio_base = dev_read_addr_ptr(dev); /* initialize adapter */ - ret = ahci_host_init(uc_priv); + ret = ahci_host_init(uc_priv, sataclk); if (ret) return ret; @@ -962,7 +992,6 @@ U_BOOT_DRIVER(dwc_ahsata_blk) = { .ops = &dwc_ahsata_blk_ops, }; -#if CONFIG_IS_ENABLED(DWC_AHSATA_AHCI) struct ahci_ops dwc_ahsata_ahci_ops = { .port_status = dwc_ahsata_port_status, .reset = dwc_ahsata_bus_reset, @@ -970,7 +999,9 @@ struct ahci_ops dwc_ahsata_ahci_ops = { }; static const struct udevice_id dwc_ahsata_ahci_ids[] = { + { .compatible = "fsl,imx53-ahci" }, { .compatible = "fsl,imx6q-ahci" }, + { .compatible = "fsl,imx6qp-ahci" }, { } }; @@ -981,4 +1012,3 @@ U_BOOT_DRIVER(dwc_ahsata_ahci) = { .ops = &dwc_ahsata_ahci_ops, .probe = dwc_ahsata_probe, }; -#endif diff --git a/drivers/ata/dwc_ahsata_priv.h b/drivers/ata/dwc_ahsata_priv.h index 5b0579ae115..0c2cd5446b5 100644 --- a/drivers/ata/dwc_ahsata_priv.h +++ b/drivers/ata/dwc_ahsata_priv.h @@ -7,8 +7,6 @@ #ifndef __DWC_AHSATA_PRIV_H__ #define __DWC_AHSATA_PRIV_H__ -#define DWC_AHSATA_MAX_CMD_SLOTS 32 - /* Max host controller numbers */ #define SATA_HC_MAX_NUM 4 /* Max command queue depth per host controller */ diff --git a/drivers/clk/clk_boston.c b/drivers/clk/clk_boston.c index 030ff7cc58e..71e030f463e 100644 --- a/drivers/clk/clk_boston.c +++ b/drivers/clk/clk_boston.c @@ -58,17 +58,21 @@ const struct clk_ops clk_boston_ops = { .get_rate = clk_boston_get_rate, }; -static int clk_boston_of_to_plat(struct udevice *dev) +static int clk_boston_probe(struct udevice *dev) { struct clk_boston *state = dev_get_plat(dev); struct udevice *syscon; int err; - err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, - "regmap", &syscon); - if (err) { - pr_err("unable to find syscon device\n"); - return err; + if (dev->parent && device_get_uclass_id(dev->parent) == UCLASS_SYSCON) { + syscon = dev->parent; + } else { + err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, + "regmap", &syscon); + if (err) { + pr_err("unable to find syscon device\n"); + return err; + } } state->regmap = syscon_get_regmap(syscon); @@ -91,7 +95,8 @@ U_BOOT_DRIVER(clk_boston) = { .name = "boston_clock", .id = UCLASS_CLK, .of_match = clk_boston_match, - .of_to_plat = clk_boston_of_to_plat, + .probe = clk_boston_probe, .plat_auto = sizeof(struct clk_boston), .ops = &clk_boston_ops, + .flags = DM_FLAG_PRE_RELOC, }; diff --git a/drivers/clk/rockchip/Makefile b/drivers/clk/rockchip/Makefile index 9e379cc2e3b..34b63d4df34 100644 --- a/drivers/clk/rockchip/Makefile +++ b/drivers/clk/rockchip/Makefile @@ -15,7 +15,9 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += clk_rk3308.o 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_RK3576) += clk_rk3576.o obj-$(CONFIG_ROCKCHIP_RK3588) += clk_rk3588.o obj-$(CONFIG_ROCKCHIP_RV1108) += clk_rv1108.o obj-$(CONFIG_ROCKCHIP_RV1126) += clk_rv1126.o diff --git a/drivers/clk/rockchip/clk_pll.c b/drivers/clk/rockchip/clk_pll.c index 44c6f14618d..9dec40b1fe8 100644 --- 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 rockchip_pll_clock *pll, * 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 rockchip_pll_clock *pll, 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 rockchip_pll_clock *pll, 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: diff --git a/drivers/clk/rockchip/clk_rk3528.c b/drivers/clk/rockchip/clk_rk3528.c new file mode 100644 index 00000000000..06f20895acc --- /dev/null +++ b/drivers/clk/rockchip/clk_rk3528.c @@ -0,0 +1,1754 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + * Author: Joseph Chen <chenjh@rock-chips.com> + */ + +#include <bitfield.h> +#include <clk-uclass.h> +#include <dm.h> +#include <errno.h> +#include <syscon.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/cru_rk3528.h> +#include <asm/arch-rockchip/hardware.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dt-bindings/clock/rockchip,rk3528-cru.h> +#include <linux/delay.h> + +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; + 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) + 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_EMMC: + 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_EMMC: + 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; + + /* Might occur in cru assigned-clocks, can be ignored here */ + case ACLK_BUS_VOPGL_ROOT: + case BCLK_EMMC: + case XIN_OSC0_DIV: + ret = 0; + 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 = rk3528_reset_bind_lut(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, +}; diff --git a/drivers/clk/rockchip/clk_rk3576.c b/drivers/clk/rockchip/clk_rk3576.c new file mode 100644 index 00000000000..e84a0943a94 --- /dev/null +++ b/drivers/clk/rockchip/clk_rk3576.c @@ -0,0 +1,2513 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 Fuzhou Rockchip Electronics Co., Ltd + * Author: Elaine Zhang <zhangqing@rock-chips.com> + */ + +#include <bitfield.h> +#include <clk-uclass.h> +#include <dm.h> +#include <errno.h> +#include <syscon.h> +#include <asm/arch-rockchip/cru_rk3576.h> +#include <asm/arch-rockchip/clock.h> +#include <asm/arch-rockchip/hardware.h> +#include <dm/device-internal.h> +#include <dm/lists.h> +#include <dt-bindings/clock/rockchip,rk3576-cru.h> +#include <linux/delay.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) + +static struct rockchip_pll_rate_table rk3576_24m_pll_rates[] = { + /* _mhz, _p, _m, _s, _k */ + RK3588_PLL_RATE(1500000000, 2, 250, 1, 0), + RK3588_PLL_RATE(1200000000, 1, 100, 1, 0), + RK3588_PLL_RATE(1188000000, 2, 198, 1, 0), + RK3588_PLL_RATE(1150000000, 3, 575, 2, 0), + RK3588_PLL_RATE(1100000000, 3, 550, 2, 0), + RK3588_PLL_RATE(1008000000, 2, 336, 2, 0), + RK3588_PLL_RATE(1000000000, 3, 500, 2, 0), + RK3588_PLL_RATE(900000000, 2, 300, 2, 0), + RK3588_PLL_RATE(850000000, 3, 425, 2, 0), + RK3588_PLL_RATE(816000000, 2, 272, 2, 0), + RK3588_PLL_RATE(786432000, 2, 262, 2, 9437), + RK3588_PLL_RATE(786000000, 1, 131, 2, 0), + RK3588_PLL_RATE(742500000, 4, 495, 2, 0), + RK3588_PLL_RATE(722534400, 8, 963, 2, 24850), + RK3588_PLL_RATE(600000000, 2, 200, 2, 0), + RK3588_PLL_RATE(594000000, 2, 198, 2, 0), + RK3588_PLL_RATE(200000000, 3, 400, 4, 0), + RK3588_PLL_RATE(100000000, 3, 400, 5, 0), + { /* sentinel */ }, +}; + +static struct rockchip_pll_clock rk3576_pll_clks[] = { + [BPLL] = PLL(pll_rk3588, PLL_BPLL, RK3576_PLL_CON(0), + RK3576_BPLL_MODE_CON0, 0, 15, 0, + rk3576_24m_pll_rates), + [LPLL] = PLL(pll_rk3588, PLL_LPLL, RK3576_LPLL_CON(16), + RK3576_LPLL_MODE_CON0, 0, 15, 0, rk3576_24m_pll_rates), + [VPLL] = PLL(pll_rk3588, PLL_VPLL, RK3576_PLL_CON(88), + RK3576_LPLL_MODE_CON0, 4, 15, 0, rk3576_24m_pll_rates), + [AUPLL] = PLL(pll_rk3588, PLL_AUPLL, RK3576_PLL_CON(96), + RK3576_MODE_CON0, 6, 15, 0, rk3576_24m_pll_rates), + [CPLL] = PLL(pll_rk3588, PLL_CPLL, RK3576_PLL_CON(104), + RK3576_MODE_CON0, 8, 15, 0, rk3576_24m_pll_rates), + [GPLL] = PLL(pll_rk3588, PLL_GPLL, RK3576_PLL_CON(112), + RK3576_MODE_CON0, 2, 15, 0, rk3576_24m_pll_rates), + [PPLL] = PLL(pll_rk3588, PLL_PPLL, RK3576_PMU_PLL_CON(128), + RK3576_MODE_CON0, 10, 15, 0, rk3576_24m_pll_rates), +}; + +#ifdef CONFIG_SPL_BUILD +#ifndef BITS_WITH_WMASK +#define BITS_WITH_WMASK(bits, msk, shift) \ + ((bits) << (shift)) | ((msk) << ((shift) + 16)) +#endif +#endif + +#ifndef CONFIG_SPL_BUILD +/* + * + * 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; +} +#endif + +static ulong rk3576_bus_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 con, sel, div, rate; + + switch (clk_id) { + case ACLK_BUS_ROOT: + con = readl(&cru->clksel_con[55]); + sel = (con & ACLK_BUS_ROOT_SEL_MASK) >> + ACLK_BUS_ROOT_SEL_SHIFT; + div = (con & ACLK_BUS_ROOT_DIV_MASK) >> + ACLK_BUS_ROOT_DIV_SHIFT; + if (sel == ACLK_BUS_ROOT_SEL_CPLL) + rate = DIV_TO_RATE(priv->cpll_hz, div); + else + rate = DIV_TO_RATE(priv->gpll_hz, div); + break; + case HCLK_BUS_ROOT: + con = readl(&cru->clksel_con[55]); + sel = (con & HCLK_BUS_ROOT_SEL_MASK) >> + HCLK_BUS_ROOT_SEL_SHIFT; + if (sel == HCLK_BUS_ROOT_SEL_200M) + rate = 198 * MHz; + else if (sel == HCLK_BUS_ROOT_SEL_100M) + rate = 100 * MHz; + else if (sel == HCLK_BUS_ROOT_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + break; + case PCLK_BUS_ROOT: + con = readl(&cru->clksel_con[55]); + sel = (con & PCLK_BUS_ROOT_SEL_MASK) >> + PCLK_BUS_ROOT_SEL_SHIFT; + if (sel == PCLK_BUS_ROOT_SEL_100M) + rate = 100 * MHz; + else if (sel == PCLK_BUS_ROOT_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3576_bus_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk, src_clk_div; + + switch (clk_id) { + case ACLK_BUS_ROOT: + if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_BUS_ROOT_SEL_CPLL; + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_BUS_ROOT_SEL_GPLL; + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + rk_clrsetreg(&cru->clksel_con[55], + ACLK_BUS_ROOT_SEL_MASK, + src_clk << ACLK_BUS_ROOT_SEL_SHIFT); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[55], + ACLK_BUS_ROOT_DIV_MASK | + ACLK_BUS_ROOT_SEL_MASK, + (src_clk << + ACLK_BUS_ROOT_SEL_SHIFT) | + (src_clk_div - 1) << ACLK_BUS_ROOT_DIV_SHIFT); + break; + case HCLK_BUS_ROOT: + if (rate >= 198 * MHz) + src_clk = HCLK_BUS_ROOT_SEL_200M; + else if (rate >= 99 * MHz) + src_clk = HCLK_BUS_ROOT_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = HCLK_BUS_ROOT_SEL_50M; + else + src_clk = HCLK_BUS_ROOT_SEL_OSC; + rk_clrsetreg(&cru->clksel_con[55], + HCLK_BUS_ROOT_SEL_MASK, + src_clk << HCLK_BUS_ROOT_SEL_SHIFT); + break; + case PCLK_BUS_ROOT: + if (rate >= 99 * MHz) + src_clk = PCLK_BUS_ROOT_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = PCLK_BUS_ROOT_SEL_50M; + else + src_clk = PCLK_BUS_ROOT_SEL_OSC; + rk_clrsetreg(&cru->clksel_con[55], + PCLK_BUS_ROOT_SEL_MASK, + src_clk << PCLK_BUS_ROOT_SEL_SHIFT); + break; + default: + printf("do not support this center freq\n"); + return -EINVAL; + } + + return rk3576_bus_get_clk(priv, clk_id); +} + +static ulong rk3576_top_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 con, sel, div, rate, prate; + + switch (clk_id) { + case ACLK_TOP: + con = readl(&cru->clksel_con[9]); + div = (con & ACLK_TOP_DIV_MASK) >> + ACLK_TOP_DIV_SHIFT; + sel = (con & ACLK_TOP_SEL_MASK) >> + ACLK_TOP_SEL_SHIFT; + if (sel == ACLK_TOP_SEL_CPLL) + prate = priv->cpll_hz; + else if (sel == ACLK_TOP_SEL_AUPLL) + prate = priv->aupll_hz; + else + prate = priv->gpll_hz; + return DIV_TO_RATE(prate, div); + case ACLK_TOP_MID: + con = readl(&cru->clksel_con[10]); + div = (con & ACLK_TOP_MID_DIV_MASK) >> + ACLK_TOP_MID_DIV_SHIFT; + sel = (con & ACLK_TOP_MID_SEL_MASK) >> + ACLK_TOP_MID_SEL_SHIFT; + if (sel == ACLK_TOP_MID_SEL_CPLL) + prate = priv->cpll_hz; + else + prate = priv->gpll_hz; + return DIV_TO_RATE(prate, div); + case PCLK_TOP_ROOT: + con = readl(&cru->clksel_con[8]); + sel = (con & PCLK_TOP_SEL_MASK) >> PCLK_TOP_SEL_SHIFT; + if (sel == PCLK_TOP_SEL_100M) + rate = 100 * MHz; + else if (sel == PCLK_TOP_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + break; + case HCLK_TOP: + con = readl(&cru->clksel_con[19]); + sel = (con & HCLK_TOP_SEL_MASK) >> HCLK_TOP_SEL_SHIFT; + if (sel == HCLK_TOP_SEL_200M) + rate = 200 * MHz; + else if (sel == HCLK_TOP_SEL_100M) + rate = 100 * MHz; + else if (sel == HCLK_TOP_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + break; + default: + return -ENOENT; + } + + return rate; +} + +static ulong rk3576_top_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk, src_clk_div; + + switch (clk_id) { + case ACLK_TOP: + if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_TOP_SEL_CPLL; + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_TOP_SEL_GPLL; + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[9], + ACLK_TOP_DIV_MASK | + ACLK_TOP_SEL_MASK, + (src_clk << + ACLK_TOP_SEL_SHIFT) | + (src_clk_div - 1) << ACLK_TOP_SEL_SHIFT); + break; + case ACLK_TOP_MID: + if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_TOP_MID_SEL_CPLL; + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_TOP_MID_SEL_GPLL; + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + rk_clrsetreg(&cru->clksel_con[10], + ACLK_TOP_MID_DIV_MASK | + ACLK_TOP_MID_SEL_MASK, + (ACLK_TOP_MID_SEL_GPLL << + ACLK_TOP_MID_SEL_SHIFT) | + (src_clk_div - 1) << ACLK_TOP_MID_DIV_SHIFT); + break; + case PCLK_TOP_ROOT: + if (rate >= 99 * MHz) + src_clk = PCLK_TOP_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = PCLK_TOP_SEL_50M; + else + src_clk = PCLK_TOP_SEL_OSC; + rk_clrsetreg(&cru->clksel_con[8], + PCLK_TOP_SEL_MASK, + src_clk << PCLK_TOP_SEL_SHIFT); + break; + case HCLK_TOP: + if (rate >= 198 * MHz) + src_clk = HCLK_TOP_SEL_200M; + else if (rate >= 99 * MHz) + src_clk = HCLK_TOP_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = HCLK_TOP_SEL_50M; + else + src_clk = HCLK_TOP_SEL_OSC; + rk_clrsetreg(&cru->clksel_con[19], + HCLK_TOP_SEL_MASK, + src_clk << HCLK_TOP_SEL_SHIFT); + break; + default: + printf("do not support this top freq\n"); + return -EINVAL; + } + + return rk3576_top_get_clk(priv, clk_id); +} + +static ulong rk3576_i2c_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 sel, con; + ulong rate; + + switch (clk_id) { + case CLK_I2C0: + con = readl(&cru->pmuclksel_con[6]); + sel = (con & CLK_I2C0_SEL_MASK) >> CLK_I2C0_SEL_SHIFT; + break; + case CLK_I2C1: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C1_SEL_MASK) >> CLK_I2C1_SEL_SHIFT; + break; + case CLK_I2C2: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C2_SEL_MASK) >> CLK_I2C2_SEL_SHIFT; + break; + case CLK_I2C3: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C3_SEL_MASK) >> CLK_I2C3_SEL_SHIFT; + break; + case CLK_I2C4: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C4_SEL_MASK) >> CLK_I2C4_SEL_SHIFT; + break; + case CLK_I2C5: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C5_SEL_MASK) >> CLK_I2C5_SEL_SHIFT; + break; + case CLK_I2C6: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C6_SEL_MASK) >> CLK_I2C6_SEL_SHIFT; + break; + case CLK_I2C7: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C7_SEL_MASK) >> CLK_I2C7_SEL_SHIFT; + break; + case CLK_I2C8: + con = readl(&cru->clksel_con[57]); + sel = (con & CLK_I2C8_SEL_MASK) >> CLK_I2C8_SEL_SHIFT; + break; + case CLK_I2C9: + con = readl(&cru->clksel_con[58]); + sel = (con & CLK_I2C9_SEL_MASK) >> CLK_I2C9_SEL_SHIFT; + break; + + default: + return -ENOENT; + } + if (sel == CLK_I2C_SEL_200M) + rate = 200 * MHz; + else if (sel == CLK_I2C_SEL_100M) + rate = 100 * MHz; + else if (sel == CLK_I2C_SEL_50M) + rate = 50 * MHz; + else + rate = OSC_HZ; + + return rate; +} + +static ulong rk3576_i2c_set_clk(struct rk3576_clk_priv *priv, ulong clk_id, + ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk; + + if (rate >= 198 * MHz) + src_clk = CLK_I2C_SEL_200M; + else if (rate >= 99 * MHz) + src_clk = CLK_I2C_SEL_100M; + if (rate >= 50 * MHz) + src_clk = CLK_I2C_SEL_50M; + else + src_clk = CLK_I2C_SEL_OSC; + + switch (clk_id) { + case CLK_I2C0: + rk_clrsetreg(&cru->pmuclksel_con[6], CLK_I2C0_SEL_MASK, + src_clk << CLK_I2C0_SEL_SHIFT); + break; + case CLK_I2C1: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C1_SEL_MASK, + src_clk << CLK_I2C1_SEL_SHIFT); + break; + case CLK_I2C2: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C2_SEL_MASK, + src_clk << CLK_I2C2_SEL_SHIFT); + break; + case CLK_I2C3: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C3_SEL_MASK, + src_clk << CLK_I2C3_SEL_SHIFT); + break; + case CLK_I2C4: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C4_SEL_MASK, + src_clk << CLK_I2C4_SEL_SHIFT); + break; + case CLK_I2C5: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C5_SEL_MASK, + src_clk << CLK_I2C5_SEL_SHIFT); + break; + case CLK_I2C6: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C6_SEL_MASK, + src_clk << CLK_I2C6_SEL_SHIFT); + break; + case CLK_I2C7: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C7_SEL_MASK, + src_clk << CLK_I2C7_SEL_SHIFT); + break; + case CLK_I2C8: + rk_clrsetreg(&cru->clksel_con[57], CLK_I2C8_SEL_MASK, + src_clk << CLK_I2C8_SEL_SHIFT); + case CLK_I2C9: + rk_clrsetreg(&cru->clksel_con[58], CLK_I2C9_SEL_MASK, + src_clk << CLK_I2C9_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3576_i2c_get_clk(priv, clk_id); +} + +static ulong rk3576_spi_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 sel, con; + + switch (clk_id) { + case CLK_SPI0: + con = readl(&cru->clksel_con[70]); + sel = (con & CLK_SPI0_SEL_MASK) >> CLK_SPI0_SEL_SHIFT; + break; + case CLK_SPI1: + con = readl(&cru->clksel_con[71]); + sel = (con & CLK_SPI1_SEL_MASK) >> CLK_SPI1_SEL_SHIFT; + break; + case CLK_SPI2: + con = readl(&cru->clksel_con[71]); + sel = (con & CLK_SPI2_SEL_MASK) >> CLK_SPI2_SEL_SHIFT; + break; + case CLK_SPI3: + con = readl(&cru->clksel_con[71]); + sel = (con & CLK_SPI3_SEL_MASK) >> CLK_SPI3_SEL_SHIFT; + break; + case CLK_SPI4: + con = readl(&cru->clksel_con[71]); + sel = (con & CLK_SPI4_SEL_MASK) >> CLK_SPI4_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + switch (sel) { + case CLK_SPI_SEL_200M: + return 200 * MHz; + case CLK_SPI_SEL_100M: + return 100 * MHz; + case CLK_SPI_SEL_50M: + return 50 * MHz; + case CLK_SPI_SEL_OSC: + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3576_spi_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk; + + if (rate >= 198 * MHz) + src_clk = CLK_SPI_SEL_200M; + else if (rate >= 99 * MHz) + src_clk = CLK_SPI_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = CLK_SPI_SEL_50M; + else + src_clk = CLK_SPI_SEL_OSC; + + switch (clk_id) { + case CLK_SPI0: + rk_clrsetreg(&cru->clksel_con[70], + CLK_SPI0_SEL_MASK, + src_clk << CLK_SPI0_SEL_SHIFT); + break; + case CLK_SPI1: + rk_clrsetreg(&cru->clksel_con[71], + CLK_SPI1_SEL_MASK, + src_clk << CLK_SPI1_SEL_SHIFT); + break; + case CLK_SPI2: + rk_clrsetreg(&cru->clksel_con[71], + CLK_SPI2_SEL_MASK, + src_clk << CLK_SPI2_SEL_SHIFT); + break; + case CLK_SPI3: + rk_clrsetreg(&cru->clksel_con[71], + CLK_SPI3_SEL_MASK, + src_clk << CLK_SPI3_SEL_SHIFT); + break; + case CLK_SPI4: + rk_clrsetreg(&cru->clksel_con[71], + CLK_SPI4_SEL_MASK, + src_clk << CLK_SPI4_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3576_spi_get_clk(priv, clk_id); +} + +static ulong rk3576_pwm_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 sel, con; + + switch (clk_id) { + case CLK_PWM1: + con = readl(&cru->clksel_con[71]); + sel = (con & CLK_PWM1_SEL_MASK) >> CLK_PWM1_SEL_SHIFT; + break; + case CLK_PWM2: + con = readl(&cru->clksel_con[74]); + sel = (con & CLK_PWM2_SEL_MASK) >> CLK_PWM2_SEL_SHIFT; + break; + case CLK_PMU1PWM: + con = readl(&cru->pmuclksel_con[5]); + sel = (con & CLK_PMU1PWM_SEL_MASK) >> CLK_PMU1PWM_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + switch (sel) { + case CLK_PWM_SEL_100M: + return 100 * MHz; + case CLK_PWM_SEL_50M: + return 50 * MHz; + case CLK_PWM_SEL_OSC: + return OSC_HZ; + default: + return -ENOENT; + } +} + +static ulong rk3576_pwm_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk; + + if (rate >= 99 * MHz) + src_clk = CLK_PWM_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = CLK_PWM_SEL_50M; + else + src_clk = CLK_PWM_SEL_OSC; + + switch (clk_id) { + case CLK_PWM1: + rk_clrsetreg(&cru->clksel_con[71], + CLK_PWM1_SEL_MASK, + src_clk << CLK_PWM1_SEL_SHIFT); + break; + case CLK_PWM2: + rk_clrsetreg(&cru->clksel_con[74], + CLK_PWM2_SEL_MASK, + src_clk << CLK_PWM2_SEL_SHIFT); + break; + case CLK_PMU1PWM: + rk_clrsetreg(&cru->pmuclksel_con[5], + CLK_PMU1PWM_SEL_MASK, + src_clk << CLK_PMU1PWM_SEL_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3576_pwm_get_clk(priv, clk_id); +} + +static ulong rk3576_adc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 div, sel, con, prate; + + switch (clk_id) { + case CLK_SARADC: + con = readl(&cru->clksel_con[58]); + div = (con & CLK_SARADC_DIV_MASK) >> CLK_SARADC_DIV_SHIFT; + sel = (con & CLK_SARADC_SEL_MASK) >> + CLK_SARADC_SEL_SHIFT; + if (sel == CLK_SARADC_SEL_OSC) + prate = OSC_HZ; + else + prate = priv->gpll_hz; + return DIV_TO_RATE(prate, div); + case CLK_TSADC: + con = readl(&cru->clksel_con[59]); + div = (con & CLK_TSADC_DIV_MASK) >> + CLK_TSADC_DIV_SHIFT; + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + default: + return -ENOENT; + } +} + +static ulong rk3576_adc_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk_div; + + switch (clk_id) { + case CLK_SARADC: + if (!(OSC_HZ % rate)) { + src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); + assert(src_clk_div - 1 <= 255); + rk_clrsetreg(&cru->clksel_con[58], + CLK_SARADC_SEL_MASK | + CLK_SARADC_DIV_MASK, + (CLK_SARADC_SEL_OSC << + CLK_SARADC_SEL_SHIFT) | + (src_clk_div - 1) << + CLK_SARADC_DIV_SHIFT); + } else { + src_clk_div = DIV_ROUND_UP(priv->gpll_hz, rate); + assert(src_clk_div - 1 <= 255); + rk_clrsetreg(&cru->clksel_con[59], + CLK_SARADC_SEL_MASK | + CLK_SARADC_DIV_MASK, + (CLK_SARADC_SEL_GPLL << + CLK_SARADC_SEL_SHIFT) | + (src_clk_div - 1) << + CLK_SARADC_DIV_SHIFT); + } + break; + case CLK_TSADC: + src_clk_div = DIV_ROUND_UP(OSC_HZ, rate); + assert(src_clk_div - 1 <= 255); + rk_clrsetreg(&cru->clksel_con[58], + CLK_TSADC_DIV_MASK, + (src_clk_div - 1) << + CLK_TSADC_DIV_SHIFT); + break; + default: + return -ENOENT; + } + return rk3576_adc_get_clk(priv, clk_id); +} + +static ulong rk3576_mmc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 sel, con, prate, div = 0; + + switch (clk_id) { + case CCLK_SRC_SDIO: + case HCLK_SDIO: + con = readl(&cru->clksel_con[104]); + div = (con & CCLK_SDIO_SRC_DIV_MASK) >> CCLK_SDIO_SRC_DIV_SHIFT; + sel = (con & CCLK_SDIO_SRC_SEL_MASK) >> + CCLK_SDIO_SRC_SEL_SHIFT; + if (sel == CCLK_SDIO_SRC_SEL_GPLL) + prate = priv->gpll_hz; + else if (sel == CCLK_SDIO_SRC_SEL_CPLL) + prate = priv->cpll_hz; + else + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + case CCLK_SRC_SDMMC0: + case HCLK_SDMMC0: + con = readl(&cru->clksel_con[105]); + div = (con & CCLK_SDMMC0_SRC_DIV_MASK) >> CCLK_SDMMC0_SRC_DIV_SHIFT; + sel = (con & CCLK_SDMMC0_SRC_SEL_MASK) >> + CCLK_SDMMC0_SRC_SEL_SHIFT; + if (sel == CCLK_SDMMC0_SRC_SEL_GPLL) + prate = priv->gpll_hz; + else if (sel == CCLK_SDMMC0_SRC_SEL_CPLL) + prate = priv->cpll_hz; + else + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + case CCLK_SRC_EMMC: + case HCLK_EMMC: + con = readl(&cru->clksel_con[89]); + div = (con & CCLK_EMMC_DIV_MASK) >> CCLK_EMMC_DIV_SHIFT; + sel = (con & CCLK_EMMC_SEL_MASK) >> + CCLK_EMMC_SEL_SHIFT; + if (sel == CCLK_EMMC_SEL_GPLL) + prate = priv->gpll_hz; + else if (sel == CCLK_EMMC_SEL_CPLL) + prate = priv->cpll_hz; + else + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + case BCLK_EMMC: + con = readl(&cru->clksel_con[90]); + sel = (con & BCLK_EMMC_SEL_MASK) >> + BCLK_EMMC_SEL_SHIFT; + if (sel == BCLK_EMMC_SEL_200M) + prate = 200 * MHz; + else if (sel == BCLK_EMMC_SEL_100M) + prate = 100 * MHz; + else if (sel == BCLK_EMMC_SEL_50M) + prate = 50 * MHz; + else + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + case SCLK_FSPI_X2: + con = readl(&cru->clksel_con[89]); + div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT; + sel = (con & SCLK_FSPI_SEL_MASK) >> + SCLK_FSPI_SEL_SHIFT; + if (sel == SCLK_FSPI_SEL_GPLL) + prate = priv->gpll_hz; + else if (sel == SCLK_FSPI_SEL_CPLL) + prate = priv->cpll_hz; + else + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + case SCLK_FSPI1_X2: + con = readl(&cru->clksel_con[106]); + div = (con & SCLK_FSPI_DIV_MASK) >> SCLK_FSPI_DIV_SHIFT; + sel = (con & SCLK_FSPI_SEL_MASK) >> + SCLK_FSPI_SEL_SHIFT; + if (sel == SCLK_FSPI_SEL_GPLL) + prate = priv->gpll_hz; + else if (sel == SCLK_FSPI_SEL_CPLL) + prate = priv->cpll_hz; + else + prate = OSC_HZ; + return DIV_TO_RATE(prate, div); + case DCLK_DECOM: + con = readl(&cru->clksel_con[72]); + div = (con & DCLK_DECOM_DIV_MASK) >> DCLK_DECOM_DIV_SHIFT; + sel = (con & DCLK_DECOM_SEL_MASK) >> DCLK_DECOM_SEL_SHIFT; + if (sel == DCLK_DECOM_SEL_SPLL) + prate = priv->spll_hz; + else + prate = priv->gpll_hz; + return DIV_TO_RATE(prate, div); + + default: + return -ENOENT; + } +} + +static ulong rk3576_mmc_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk, div = 0; + + switch (clk_id) { + case CCLK_SRC_SDIO: + case CCLK_SRC_SDMMC0: + case CCLK_SRC_EMMC: + case SCLK_FSPI_X2: + case SCLK_FSPI1_X2: + case HCLK_SDMMC0: + case HCLK_EMMC: + case HCLK_SDIO: + if (!(OSC_HZ % rate)) { + src_clk = SCLK_FSPI_SEL_OSC; + div = DIV_ROUND_UP(OSC_HZ, rate); + } else if (!(priv->cpll_hz % rate)) { + src_clk = SCLK_FSPI_SEL_CPLL; + div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = SCLK_FSPI_SEL_GPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + break; + case BCLK_EMMC: + if (rate >= 198 * MHz) + src_clk = BCLK_EMMC_SEL_200M; + else if (rate >= 99 * MHz) + src_clk = BCLK_EMMC_SEL_100M; + else if (rate >= 50 * MHz) + src_clk = BCLK_EMMC_SEL_50M; + else + src_clk = BCLK_EMMC_SEL_OSC; + break; + case DCLK_DECOM: + if (!(priv->spll_hz % rate)) { + src_clk = DCLK_DECOM_SEL_SPLL; + div = DIV_ROUND_UP(priv->spll_hz, rate); + } else { + src_clk = DCLK_DECOM_SEL_GPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + break; + default: + return -ENOENT; + } + + switch (clk_id) { + case CCLK_SRC_SDIO: + case HCLK_SDIO: + rk_clrsetreg(&cru->clksel_con[104], + CCLK_SDIO_SRC_SEL_MASK | + CCLK_SDIO_SRC_DIV_MASK, + (src_clk << CCLK_SDIO_SRC_SEL_SHIFT) | + (div - 1) << CCLK_SDIO_SRC_DIV_SHIFT); + break; + case CCLK_SRC_SDMMC0: + case HCLK_SDMMC0: + rk_clrsetreg(&cru->clksel_con[105], + CCLK_SDMMC0_SRC_SEL_MASK | + CCLK_SDMMC0_SRC_DIV_MASK, + (src_clk << CCLK_SDMMC0_SRC_SEL_SHIFT) | + (div - 1) << CCLK_SDMMC0_SRC_DIV_SHIFT); + break; + case CCLK_SRC_EMMC: + case HCLK_EMMC: + rk_clrsetreg(&cru->clksel_con[89], + CCLK_EMMC_DIV_MASK | + CCLK_EMMC_SEL_MASK, + (src_clk << CCLK_EMMC_SEL_SHIFT) | + (div - 1) << CCLK_EMMC_DIV_SHIFT); + break; + case SCLK_FSPI_X2: + rk_clrsetreg(&cru->clksel_con[89], + SCLK_FSPI_DIV_MASK | + SCLK_FSPI_SEL_MASK, + (src_clk << SCLK_FSPI_SEL_SHIFT) | + (div - 1) << SCLK_FSPI_DIV_SHIFT); + break; + case SCLK_FSPI1_X2: + rk_clrsetreg(&cru->clksel_con[106], + SCLK_FSPI_DIV_MASK | + SCLK_FSPI_SEL_MASK, + (src_clk << SCLK_FSPI_SEL_SHIFT) | + (div - 1) << SCLK_FSPI_DIV_SHIFT); + break; + case BCLK_EMMC: + rk_clrsetreg(&cru->clksel_con[90], + BCLK_EMMC_SEL_MASK, + src_clk << BCLK_EMMC_SEL_SHIFT); + break; + case DCLK_DECOM: + rk_clrsetreg(&cru->clksel_con[72], + DCLK_DECOM_DIV_MASK | + DCLK_DECOM_SEL_MASK, + (src_clk << DCLK_DECOM_SEL_SHIFT) | + (div - 1) << DCLK_DECOM_DIV_SHIFT); + break; + + default: + return -ENOENT; + } + + return rk3576_mmc_get_clk(priv, clk_id); +} + +#ifndef CONFIG_SPL_BUILD + +static ulong rk3576_aclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 div, sel, con, parent = 0; + + switch (clk_id) { + case ACLK_VOP_ROOT: + case ACLK_VOP: + con = readl(&cru->clksel_con[144]); + div = (con & ACLK_VOP_ROOT_DIV_MASK) >> ACLK_VOP_ROOT_DIV_SHIFT; + sel = (con & ACLK_VOP_ROOT_SEL_MASK) >> ACLK_VOP_ROOT_SEL_SHIFT; + if (sel == ACLK_VOP_ROOT_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_VOP_ROOT_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == ACLK_VOP_ROOT_SEL_AUPLL) + parent = priv->aupll_hz; + else if (sel == ACLK_VOP_ROOT_SEL_SPLL) + parent = priv->spll_hz; + else if (sel == ACLK_VOP_ROOT_SEL_LPLL) + parent = priv->lpll_hz / 2; + return DIV_TO_RATE(parent, div); + case ACLK_VO0_ROOT: + con = readl(&cru->clksel_con[149]); + div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT; + sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT; + if (sel == ACLK_VO0_ROOT_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_VO0_ROOT_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == ACLK_VO0_ROOT_SEL_LPLL) + parent = priv->lpll_hz / 2; + else if (sel == ACLK_VO0_ROOT_SEL_BPLL) + parent = priv->bpll_hz / 4; + return DIV_TO_RATE(parent, div); + case ACLK_VO1_ROOT: + con = readl(&cru->clksel_con[158]); + div = (con & ACLK_VO0_ROOT_DIV_MASK) >> ACLK_VO0_ROOT_DIV_SHIFT; + sel = (con & ACLK_VO0_ROOT_SEL_MASK) >> ACLK_VO0_ROOT_SEL_SHIFT; + if (sel == ACLK_VO0_ROOT_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == ACLK_VO0_ROOT_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == ACLK_VO0_ROOT_SEL_LPLL) + parent = priv->lpll_hz / 2; + else if (sel == ACLK_VO0_ROOT_SEL_BPLL) + parent = priv->bpll_hz / 4; + return DIV_TO_RATE(parent, div); + case HCLK_VOP_ROOT: + con = readl(&cru->clksel_con[144]); + sel = (con & HCLK_VOP_ROOT_SEL_MASK) >> HCLK_VOP_ROOT_SEL_SHIFT; + if (sel == HCLK_VOP_ROOT_SEL_200M) + return 200 * MHz; + else if (sel == HCLK_VOP_ROOT_SEL_100M) + return 100 * MHz; + else if (sel == HCLK_VOP_ROOT_SEL_50M) + return 50 * MHz; + else + return OSC_HZ; + case PCLK_VOP_ROOT: + con = readl(&cru->clksel_con[144]); + sel = (con & PCLK_VOP_ROOT_SEL_MASK) >> PCLK_VOP_ROOT_SEL_SHIFT; + if (sel == PCLK_VOP_ROOT_SEL_100M) + return 100 * MHz; + else if (sel == PCLK_VOP_ROOT_SEL_50M) + return 50 * MHz; + else + return OSC_HZ; + + default: + return -ENOENT; + } +} + +static ulong rk3576_aclk_vop_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int src_clk, div; + + switch (clk_id) { + case ACLK_VOP_ROOT: + case ACLK_VOP: + if (rate == 700 * MHz) { + src_clk = ACLK_VOP_ROOT_SEL_SPLL; + div = 1; + } else if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_VOP_ROOT_SEL_CPLL; + div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_VOP_ROOT_SEL_GPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + rk_clrsetreg(&cru->clksel_con[144], + ACLK_VOP_ROOT_DIV_MASK | + ACLK_VOP_ROOT_SEL_MASK, + (src_clk << ACLK_VOP_ROOT_SEL_SHIFT) | + (div - 1) << ACLK_VOP_ROOT_DIV_SHIFT); + break; + case ACLK_VO0_ROOT: + if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_VO0_ROOT_SEL_CPLL; + div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_VO0_ROOT_SEL_GPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + rk_clrsetreg(&cru->clksel_con[149], + ACLK_VO0_ROOT_DIV_MASK | + ACLK_VO0_ROOT_SEL_MASK, + (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) | + (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT); + break; + case ACLK_VO1_ROOT: + if (!(priv->cpll_hz % rate)) { + src_clk = ACLK_VO0_ROOT_SEL_CPLL; + div = DIV_ROUND_UP(priv->cpll_hz, rate); + } else { + src_clk = ACLK_VO0_ROOT_SEL_GPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } + rk_clrsetreg(&cru->clksel_con[158], + ACLK_VO0_ROOT_DIV_MASK | + ACLK_VO0_ROOT_SEL_MASK, + (src_clk << ACLK_VO0_ROOT_SEL_SHIFT) | + (div - 1) << ACLK_VO0_ROOT_DIV_SHIFT); + break; + case HCLK_VOP_ROOT: + if (rate == 200 * MHz) + src_clk = HCLK_VOP_ROOT_SEL_200M; + else if (rate == 100 * MHz) + src_clk = HCLK_VOP_ROOT_SEL_100M; + else if (rate == 50 * MHz) + src_clk = HCLK_VOP_ROOT_SEL_50M; + else + src_clk = HCLK_VOP_ROOT_SEL_OSC; + rk_clrsetreg(&cru->clksel_con[144], + HCLK_VOP_ROOT_SEL_MASK, + src_clk << HCLK_VOP_ROOT_SEL_SHIFT); + break; + case PCLK_VOP_ROOT: + if (rate == 100 * MHz) + src_clk = PCLK_VOP_ROOT_SEL_100M; + else if (rate == 50 * MHz) + src_clk = PCLK_VOP_ROOT_SEL_50M; + else + src_clk = PCLK_VOP_ROOT_SEL_OSC; + rk_clrsetreg(&cru->clksel_con[144], + PCLK_VOP_ROOT_SEL_MASK, + src_clk << PCLK_VOP_ROOT_SEL_SHIFT); + break; + + default: + return -ENOENT; + } + + return rk3576_aclk_vop_get_clk(priv, clk_id); +} + +static ulong rk3576_dclk_vop_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 div, sel, con, parent; + + switch (clk_id) { + case DCLK_VP0: + case DCLK_VP0_SRC: + con = readl(&cru->clksel_con[145]); + div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; + sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; + break; + case DCLK_VP1: + case DCLK_VP1_SRC: + con = readl(&cru->clksel_con[146]); + div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; + sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; + break; + case DCLK_VP2: + case DCLK_VP2_SRC: + con = readl(&cru->clksel_con[147]); + div = (con & DCLK0_VOP_SRC_DIV_MASK) >> DCLK0_VOP_SRC_DIV_SHIFT; + sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + if (sel == DCLK_VOP_SRC_SEL_VPLL) + parent = priv->vpll_hz; + else if (sel == DCLK_VOP_SRC_SEL_BPLL) + parent = priv->bpll_hz / 4; + else if (sel == DCLK_VOP_SRC_SEL_LPLL) + parent = priv->lpll_hz / 2; + else if (sel == DCLK_VOP_SRC_SEL_GPLL) + parent = priv->gpll_hz; + else + parent = priv->cpll_hz; + + return DIV_TO_RATE(parent, div); +} + +#define RK3576_VOP_PLL_LIMIT_FREQ 600000000 + +static ulong rk3576_dclk_vop_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + ulong pll_rate, now, best_rate = 0; + u32 i, conid, con, sel, div, best_div = 0, best_sel = 0; + u32 mask, div_shift, sel_shift; + + switch (clk_id) { + case DCLK_VP0: + case DCLK_VP0_SRC: + conid = 145; + con = readl(&cru->clksel_con[conid]); + sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; + mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; + div_shift = DCLK0_VOP_SRC_DIV_SHIFT; + sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; + break; + case DCLK_VP1: + case DCLK_VP1_SRC: + conid = 146; + con = readl(&cru->clksel_con[conid]); + sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; + mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; + div_shift = DCLK0_VOP_SRC_DIV_SHIFT; + sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; + break; + case DCLK_VP2: + case DCLK_VP2_SRC: + conid = 147; + con = readl(&cru->clksel_con[conid]); + sel = (con & DCLK0_VOP_SRC_SEL_MASK) >> DCLK0_VOP_SRC_SEL_SHIFT; + mask = DCLK0_VOP_SRC_SEL_MASK | DCLK0_VOP_SRC_DIV_MASK; + div_shift = DCLK0_VOP_SRC_DIV_SHIFT; + sel_shift = DCLK0_VOP_SRC_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + if (sel == DCLK_VOP_SRC_SEL_VPLL) { + pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], + priv->cru, VPLL); + if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && pll_rate % rate == 0) { + div = DIV_ROUND_UP(pll_rate, rate); + rk_clrsetreg(&cru->clksel_con[conid], + mask, + DCLK_VOP_SRC_SEL_VPLL << sel_shift | + ((div - 1) << div_shift)); + } else { + div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, rate); + if (div % 2) + div = div + 1; + rk_clrsetreg(&cru->clksel_con[conid], + mask, + DCLK_VOP_SRC_SEL_VPLL << sel_shift | + ((div - 1) << div_shift)); + rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], + priv->cru, VPLL, div * rate); + priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], + priv->cru, VPLL); + } + } else { + for (i = 0; i <= DCLK_VOP_SRC_SEL_LPLL; i++) { + switch (i) { + case DCLK_VOP_SRC_SEL_GPLL: + pll_rate = priv->gpll_hz; + break; + case DCLK_VOP_SRC_SEL_CPLL: + pll_rate = priv->cpll_hz; + break; + case DCLK_VOP_SRC_SEL_BPLL: + pll_rate = 0; + break; + case DCLK_VOP_SRC_SEL_LPLL: + pll_rate = 0; + break; + case DCLK_VOP_SRC_SEL_VPLL: + pll_rate = 0; + break; + default: + printf("do not support this vop pll sel\n"); + return -EINVAL; + } + + div = DIV_ROUND_UP(pll_rate, rate); + if (div > 255) + continue; + now = pll_rate / div; + if (abs(rate - now) < abs(rate - best_rate)) { + best_rate = now; + best_div = div; + best_sel = i; + } + debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", + pll_rate, best_rate, best_div, best_sel); + } + + if (best_rate) { + rk_clrsetreg(&cru->clksel_con[conid], + mask, + best_sel << sel_shift | + (best_div - 1) << div_shift); + } else { + printf("do not support this vop freq %lu\n", rate); + return -EINVAL; + } + } + + return rk3576_dclk_vop_get_clk(priv, clk_id); +} + +static ulong rk3576_clk_csihost_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 div, sel, con, parent; + + switch (clk_id) { + case CLK_DSIHOST0: + con = readl(&cru->clksel_con[151]); + div = (con & CLK_DSIHOST0_DIV_MASK) >> CLK_DSIHOST0_DIV_SHIFT; + sel = (con & CLK_DSIHOST0_SEL_MASK) >> CLK_DSIHOST0_SEL_SHIFT; + break; + default: + return -ENOENT; + } + + if (sel == CLK_DSIHOST0_SEL_VPLL) + parent = priv->vpll_hz; + else if (sel == CLK_DSIHOST0_SEL_BPLL) + parent = priv->bpll_hz / 4; + else if (sel == CLK_DSIHOST0_SEL_LPLL) + parent = priv->lpll_hz / 2; + else if (sel == CLK_DSIHOST0_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == CLK_DSIHOST0_SEL_SPLL) + parent = priv->spll_hz; + else + parent = priv->cpll_hz; + + return DIV_TO_RATE(parent, div); +} + +static ulong rk3576_clk_csihost_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + ulong pll_rate, now, best_rate = 0; + u32 i, con, div, best_div = 0, best_sel = 0; + u32 mask, div_shift, sel_shift; + + switch (clk_id) { + case CLK_DSIHOST0: + con = 151; + mask = CLK_DSIHOST0_SEL_MASK | CLK_DSIHOST0_DIV_MASK; + div_shift = CLK_DSIHOST0_DIV_SHIFT; + sel_shift = CLK_DSIHOST0_SEL_SHIFT; + break; + default: + return -ENOENT; + } + for (i = 0; i <= CLK_DSIHOST0_SEL_LPLL; i++) { + switch (i) { + case CLK_DSIHOST0_SEL_GPLL: + pll_rate = priv->gpll_hz; + break; + case CLK_DSIHOST0_SEL_CPLL: + pll_rate = priv->cpll_hz; + break; + case CLK_DSIHOST0_SEL_BPLL: + pll_rate = 0; + break; + case CLK_DSIHOST0_SEL_LPLL: + pll_rate = 0; + break; + case CLK_DSIHOST0_SEL_VPLL: + pll_rate = 0; + break; + case CLK_DSIHOST0_SEL_SPLL: + pll_rate = priv->spll_hz; + break; + default: + printf("do not support this vop pll sel\n"); + return -EINVAL; + } + + div = DIV_ROUND_UP(pll_rate, rate); + if (div > 255) + continue; + now = pll_rate / div; + if (abs(rate - now) < abs(rate - best_rate)) { + best_rate = now; + best_div = div; + best_sel = i; + } + debug("p_rate=%lu, best_rate=%lu, div=%u, sel=%u\n", + pll_rate, best_rate, best_div, best_sel); + } + + if (best_rate) { + rk_clrsetreg(&cru->clksel_con[con], + mask, + best_sel << sel_shift | + (best_div - 1) << div_shift); + } else { + printf("do not support this vop freq %lu\n", rate); + return -EINVAL; + } + + return rk3576_clk_csihost_get_clk(priv, clk_id); +} + +static ulong rk3576_dclk_ebc_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 div, sel, con, parent; + unsigned long m = 0, n = 0; + + switch (clk_id) { + case DCLK_EBC: + con = readl(&cru->clksel_con[123]); + div = (con & DCLK_EBC_DIV_MASK) >> DCLK_EBC_DIV_SHIFT; + sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; + if (sel == DCLK_EBC_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == DCLK_EBC_SEL_VPLL) + parent = priv->vpll_hz; + else if (sel == DCLK_EBC_SEL_AUPLL) + parent = priv->aupll_hz; + else if (sel == DCLK_EBC_SEL_LPLL) + parent = priv->lpll_hz / 2; + else if (sel == DCLK_EBC_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == DCLK_EBC_SEL_FRAC_SRC) + parent = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC); + else + parent = OSC_HZ; + return DIV_TO_RATE(parent, div); + case DCLK_EBC_FRAC_SRC: + con = readl(&cru->clksel_con[123]); + div = readl(&cru->clksel_con[122]); + sel = (con & DCLK_EBC_FRAC_SRC_SEL_MASK) >> DCLK_EBC_FRAC_SRC_SEL_SHIFT; + if (sel == DCLK_EBC_FRAC_SRC_SEL_GPLL) + parent = priv->gpll_hz; + else if (sel == DCLK_EBC_FRAC_SRC_SEL_CPLL) + parent = priv->cpll_hz; + else if (sel == DCLK_EBC_FRAC_SRC_SEL_VPLL) + parent = priv->vpll_hz; + else if (sel == DCLK_EBC_FRAC_SRC_SEL_AUPLL) + parent = priv->aupll_hz; + else + parent = OSC_HZ; + + n = div & CLK_UART_FRAC_NUMERATOR_MASK; + n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; + m = div & CLK_UART_FRAC_DENOMINATOR_MASK; + m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; + return parent * n / m; + default: + return -ENOENT; + } +} + +static ulong rk3576_dclk_ebc_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + ulong pll_rate, now, best_rate = 0; + u32 i, con, sel, div, best_div = 0, best_sel = 0; + unsigned long m = 0, n = 0, val; + + switch (clk_id) { + case DCLK_EBC: + con = readl(&cru->clksel_con[123]); + sel = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; + if (sel == DCLK_EBC_SEL_VPLL) { + pll_rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], + priv->cru, VPLL); + if (pll_rate >= RK3576_VOP_PLL_LIMIT_FREQ && + pll_rate % rate == 0) { + div = DIV_ROUND_UP(pll_rate, rate); + rk_clrsetreg(&cru->clksel_con[123], + DCLK_EBC_DIV_MASK, + (div - 1) << DCLK_EBC_DIV_SHIFT); + } else { + div = DIV_ROUND_UP(RK3576_VOP_PLL_LIMIT_FREQ, + rate); + if (div % 2) + div = div + 1; + rk_clrsetreg(&cru->clksel_con[123], + DCLK_EBC_DIV_MASK, + (div - 1) << DCLK_EBC_DIV_SHIFT); + rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], + priv->cru, + VPLL, div * rate); + priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], + priv->cru, + VPLL); + } + } else if (sel == DCLK_EBC_SEL_FRAC_SRC) { + rk3576_dclk_ebc_set_clk(priv, DCLK_EBC_FRAC_SRC, rate); + div = rk3576_dclk_ebc_get_clk(priv, DCLK_EBC_FRAC_SRC) / rate; + rk_clrsetreg(&cru->clksel_con[123], + DCLK_EBC_DIV_MASK, + (div - 1) << DCLK_EBC_DIV_SHIFT); + } else { + for (i = 0; i <= DCLK_EBC_SEL_LPLL; i++) { + switch (i) { + case DCLK_EBC_SEL_GPLL: + pll_rate = priv->gpll_hz; + break; + case DCLK_EBC_SEL_CPLL: + pll_rate = priv->cpll_hz; + break; + case DCLK_EBC_SEL_VPLL: + pll_rate = 0; + break; + case DCLK_EBC_SEL_AUPLL: + pll_rate = priv->aupll_hz; + break; + case DCLK_EBC_SEL_LPLL: + pll_rate = 0; + break; + default: + printf("not support ebc pll sel\n"); + return -EINVAL; + } + + div = DIV_ROUND_UP(pll_rate, rate); + if (div > 255) + continue; + now = pll_rate / div; + if (abs(rate - now) < abs(rate - best_rate)) { + best_rate = now; + best_div = div; + best_sel = i; + } + } + + if (best_rate) { + rk_clrsetreg(&cru->clksel_con[123], + DCLK_EBC_DIV_MASK | + DCLK_EBC_SEL_MASK, + best_sel << + DCLK_EBC_SEL_SHIFT | + (best_div - 1) << + DCLK_EBC_DIV_SHIFT); + } else { + printf("do not support this vop freq %lu\n", + rate); + return -EINVAL; + } + } + break; + case DCLK_EBC_FRAC_SRC: + sel = DCLK_EBC_FRAC_SRC_SEL_GPLL; + div = 1; + rational_best_approximation(rate, priv->gpll_hz, + GENMASK(16 - 1, 0), + GENMASK(16 - 1, 0), + &m, &n); + + if (m < 4 && m != 0) { + if (n % 2 == 0) + val = 1; + else + val = DIV_ROUND_UP(4, m); + + n *= val; + m *= val; + if (n > 0xffff) + n = 0xffff; + } + + rk_clrsetreg(&cru->clksel_con[123], + DCLK_EBC_FRAC_SRC_SEL_MASK, + (sel << DCLK_EBC_FRAC_SRC_SEL_SHIFT)); + if (m && n) { + val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; + writel(val, &cru->clksel_con[122]); + } + break; + default: + return -ENOENT; + } + return rk3576_dclk_ebc_get_clk(priv, clk_id); +} + +static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 con, div, src, p_rate; + + switch (clk_id) { + case CLK_GMAC0_PTP_REF_SRC: + case CLK_GMAC0_PTP_REF: + con = readl(&cru->clksel_con[105]); + div = (con & CLK_GMAC0_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; + src = (con & CLK_GMAC0_PTP_SEL_MASK) >> CLK_GMAC0_PTP_SEL_SHIFT; + if (src == CLK_GMAC0_PTP_SEL_GPLL) + p_rate = priv->gpll_hz; + else if (src == CLK_GMAC0_PTP_SEL_CPLL) + p_rate = priv->cpll_hz; + else + p_rate = GMAC0_PTP_REFCLK_IN; + return DIV_TO_RATE(p_rate, div); + case CLK_GMAC1_PTP_REF_SRC: + case CLK_GMAC1_PTP_REF: + con = readl(&cru->clksel_con[104]); + div = (con & CLK_GMAC1_PTP_DIV_MASK) >> CLK_GMAC0_PTP_DIV_SHIFT; + src = (con & CLK_GMAC1_PTP_SEL_MASK) >> CLK_GMAC1_PTP_SEL_SHIFT; + if (src == CLK_GMAC1_PTP_SEL_GPLL) + p_rate = priv->gpll_hz; + else if (src == CLK_GMAC1_PTP_SEL_CPLL) + p_rate = priv->cpll_hz; + else + p_rate = GMAC1_PTP_REFCLK_IN; + return DIV_TO_RATE(p_rate, div); + case CLK_GMAC0_125M_SRC: + con = readl(&cru->clksel_con[30]); + div = (con & CLK_GMAC0_125M_DIV_MASK) >> CLK_GMAC0_125M_DIV_SHIFT; + return DIV_TO_RATE(priv->cpll_hz, div); + case CLK_GMAC1_125M_SRC: + con = readl(&cru->clksel_con[31]); + div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT; + return DIV_TO_RATE(priv->cpll_hz, div); + default: + return -ENOENT; + } +} + +static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + int div, src; + + div = DIV_ROUND_UP(priv->cpll_hz, rate); + + switch (clk_id) { + case CLK_GMAC0_PTP_REF_SRC: + case CLK_GMAC0_PTP_REF: + if (rate == GMAC0_PTP_REFCLK_IN) { + src = CLK_GMAC0_PTP_SEL_REFIN; + div = 1; + } else if (!(priv->gpll_hz % rate)) { + src = CLK_GMAC0_PTP_SEL_GPLL; + div = priv->gpll_hz / rate; + } else { + src = CLK_GMAC0_PTP_SEL_CPLL; + div = priv->cpll_hz / rate; + } + rk_clrsetreg(&cru->clksel_con[105], + CLK_GMAC0_PTP_DIV_MASK | CLK_GMAC0_PTP_SEL_MASK, + src << CLK_GMAC0_PTP_SEL_SHIFT | + (div - 1) << CLK_GMAC0_PTP_DIV_SHIFT); + break; + case CLK_GMAC1_PTP_REF_SRC: + case CLK_GMAC1_PTP_REF: + if (rate == GMAC1_PTP_REFCLK_IN) { + src = CLK_GMAC1_PTP_SEL_REFIN; + div = 1; + } else if (!(priv->gpll_hz % rate)) { + src = CLK_GMAC1_PTP_SEL_GPLL; + div = priv->gpll_hz / rate; + } else { + src = CLK_GMAC1_PTP_SEL_CPLL; + div = priv->cpll_hz / rate; + } + rk_clrsetreg(&cru->clksel_con[104], + CLK_GMAC1_PTP_DIV_MASK | CLK_GMAC1_PTP_SEL_MASK, + src << CLK_GMAC1_PTP_SEL_SHIFT | + (div - 1) << CLK_GMAC1_PTP_DIV_SHIFT); + break; + + case CLK_GMAC0_125M_SRC: + rk_clrsetreg(&cru->clksel_con[30], + CLK_GMAC0_125M_DIV_MASK, + (div - 1) << CLK_GMAC0_125M_DIV_SHIFT); + break; + case CLK_GMAC1_125M_SRC: + rk_clrsetreg(&cru->clksel_con[31], + CLK_GMAC1_125M_DIV_MASK, + (div - 1) << CLK_GMAC1_125M_DIV_SHIFT); + break; + default: + return -ENOENT; + } + + return rk3576_gmac_get_clk(priv, clk_id); +} + +static ulong rk3576_uart_frac_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 reg, con, fracdiv, p_src, p_rate; + unsigned long m, n; + + switch (clk_id) { + case CLK_UART_FRAC_0: + reg = 21; + break; + case CLK_UART_FRAC_1: + reg = 23; + break; + case CLK_UART_FRAC_2: + reg = 25; + break; + default: + return -ENOENT; + } + con = readl(&cru->clksel_con[reg + 1]); + p_src = (con & CLK_UART_SRC_SEL_MASK) >> CLK_UART_SRC_SEL_SHIFT; + if (p_src == CLK_UART_SRC_SEL_GPLL) + p_rate = priv->gpll_hz; + else if (p_src == CLK_UART_SRC_SEL_CPLL) + p_rate = priv->cpll_hz; + else if (p_src == CLK_UART_SRC_SEL_AUPLL) + p_rate = priv->aupll_hz; + else + p_rate = OSC_HZ; + + fracdiv = readl(&cru->clksel_con[reg]); + n = fracdiv & CLK_UART_FRAC_NUMERATOR_MASK; + n >>= CLK_UART_FRAC_NUMERATOR_SHIFT; + m = fracdiv & CLK_UART_FRAC_DENOMINATOR_MASK; + m >>= CLK_UART_FRAC_DENOMINATOR_SHIFT; + return p_rate * n / m; +} + +static ulong rk3576_uart_frac_set_rate(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + u32 reg, clk_src, p_rate; + unsigned long m = 0, n = 0, val; + + if (priv->cpll_hz % rate == 0) { + clk_src = CLK_UART_SRC_SEL_CPLL; + p_rate = priv->cpll_hz; + } else if (rate == OSC_HZ) { + clk_src = CLK_UART_SRC_SEL_OSC; + p_rate = OSC_HZ; + } else { + clk_src = CLK_UART_SRC_SEL_GPLL; + p_rate = priv->cpll_hz; + } + + rational_best_approximation(rate, p_rate, GENMASK(16 - 1, 0), + GENMASK(16 - 1, 0), &m, &n); + + if (m < 4 && m != 0) { + if (n % 2 == 0) + val = 1; + else + val = DIV_ROUND_UP(4, m); + + n *= val; + m *= val; + if (n > 0xffff) + n = 0xffff; + } + + switch (clk_id) { + case CLK_UART_FRAC_0: + reg = 21; + break; + case CLK_UART_FRAC_1: + reg = 23; + break; + case CLK_UART_FRAC_2: + reg = 25; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[reg + 1], + CLK_UART_SRC_SEL_MASK, + (clk_src << CLK_UART_SRC_SEL_SHIFT)); + if (m && n) { + val = m << CLK_UART_FRAC_NUMERATOR_SHIFT | n; + writel(val, &cru->clksel_con[reg]); + } + + return rk3576_uart_frac_get_rate(priv, clk_id); +} + +static ulong rk3576_uart_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 con, div, src, p_rate; + + switch (clk_id) { + case SCLK_UART0: + con = readl(&cru->clksel_con[60]); + break; + case SCLK_UART1: + con = readl(&cru->pmuclksel_con[8]); + src = (con & CLK_UART1_SEL_MASK) >> CLK_UART1_SEL_SHIFT; + if (src == CLK_UART1_SEL_OSC) + return OSC_HZ; + con = readl(&cru->clksel_con[27]); + break; + case SCLK_UART2: + con = readl(&cru->clksel_con[61]); + break; + case SCLK_UART3: + con = readl(&cru->clksel_con[62]); + break; + case SCLK_UART4: + con = readl(&cru->clksel_con[63]); + break; + case SCLK_UART5: + con = readl(&cru->clksel_con[64]); + break; + case SCLK_UART6: + con = readl(&cru->clksel_con[65]); + break; + case SCLK_UART7: + con = readl(&cru->clksel_con[66]); + break; + case SCLK_UART8: + con = readl(&cru->clksel_con[67]); + break; + case SCLK_UART9: + con = readl(&cru->clksel_con[68]); + break; + case SCLK_UART10: + con = readl(&cru->clksel_con[69]); + break; + case SCLK_UART11: + con = readl(&cru->clksel_con[70]); + break; + default: + return -ENOENT; + } + if (clk_id == SCLK_UART1) { + src = (con & CLK_UART1_SRC_SEL_SHIFT) >> CLK_UART1_SRC_SEL_SHIFT; + div = (con & CLK_UART1_SRC_DIV_MASK) >> CLK_UART1_SRC_DIV_SHIFT; + } else { + src = (con & CLK_UART_SEL_MASK) >> CLK_UART_SEL_SHIFT; + div = (con & CLK_UART_DIV_MASK) >> CLK_UART_DIV_SHIFT; + } + if (src == CLK_UART_SEL_GPLL) + p_rate = priv->gpll_hz; + else if (src == CLK_UART_SEL_CPLL) + p_rate = priv->cpll_hz; + else if (src == CLK_UART_SEL_AUPLL) + p_rate = priv->aupll_hz; + else if (src == CLK_UART_SEL_FRAC0) + p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0); + else if (src == CLK_UART_SEL_FRAC1) + p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1); + else if (src == CLK_UART_SEL_FRAC2) + p_rate = rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2); + else + p_rate = OSC_HZ; + + return DIV_TO_RATE(p_rate, div); +} + +static ulong rk3576_uart_set_rate(struct rk3576_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3576_cru *cru = priv->cru; + u32 reg, clk_src = 0, div = 0; + + if (!(priv->gpll_hz % rate)) { + clk_src = CLK_UART_SEL_GPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } else if (!(priv->cpll_hz % rate)) { + clk_src = CLK_UART_SEL_CPLL; + div = DIV_ROUND_UP(priv->gpll_hz, rate); + } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0) % rate)) { + clk_src = CLK_UART_SEL_FRAC0; + div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_0), rate); + } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1) % rate)) { + clk_src = CLK_UART_SEL_FRAC1; + div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_1), rate); + } else if (!(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2) % rate)) { + clk_src = CLK_UART_SEL_FRAC2; + div = DIV_ROUND_UP(rk3576_uart_frac_get_rate(priv, CLK_UART_FRAC_2), rate); + } else if (!(OSC_HZ % rate)) { + clk_src = CLK_UART_SEL_OSC; + div = DIV_ROUND_UP(OSC_HZ, rate); + } + + switch (clk_id) { + case SCLK_UART0: + reg = 60; + break; + case SCLK_UART1: + if (rate == OSC_HZ) { + rk_clrsetreg(&cru->pmuclksel_con[8], + CLK_UART1_SEL_MASK, + CLK_UART1_SEL_OSC << CLK_UART1_SEL_SHIFT); + return 0; + } + + rk_clrsetreg(&cru->clksel_con[27], + CLK_UART1_SRC_SEL_MASK | CLK_UART1_SRC_DIV_MASK, + (clk_src << CLK_UART1_SRC_SEL_SHIFT) | + ((div - 1) << CLK_UART1_SRC_DIV_SHIFT)); + rk_clrsetreg(&cru->pmuclksel_con[8], + CLK_UART1_SEL_MASK, + CLK_UART1_SEL_TOP << CLK_UART1_SEL_SHIFT); + return 0; + case SCLK_UART2: + reg = 61; + break; + case SCLK_UART3: + reg = 62; + break; + case SCLK_UART4: + reg = 63; + break; + case SCLK_UART5: + reg = 64; + break; + case SCLK_UART6: + reg = 65; + break; + case SCLK_UART7: + reg = 66; + break; + case SCLK_UART8: + reg = 67; + break; + case SCLK_UART9: + reg = 68; + break; + case SCLK_UART10: + reg = 69; + break; + case SCLK_UART11: + reg = 70; + break; + default: + return -ENOENT; + } + + rk_clrsetreg(&cru->clksel_con[reg], + CLK_UART_SEL_MASK | + CLK_UART_DIV_MASK, + (clk_src << CLK_UART_SEL_SHIFT) | + ((div - 1) << CLK_UART_DIV_SHIFT)); + + return rk3576_uart_get_rate(priv, clk_id); +} +#endif + +static ulong rk3576_ufs_ref_get_rate(struct rk3576_clk_priv *priv, ulong clk_id) +{ + struct rk3576_cru *cru = priv->cru; + u32 src, div; + + src = readl(&cru->pmuclksel_con[3]) & 0x3; + div = readl(&cru->pmuclksel_con[1]) & 0xff; + if (src == 0) + return OSC_HZ; + else if (src == 2) + return priv->ppll_hz / (div + 1); + else + return 26000000; +} + +static ulong rk3576_clk_get_rate(struct clk *clk) +{ + struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); + ulong rate = 0; + + if (!priv->gpll_hz) { + printf("%s gpll=%lu\n", __func__, priv->gpll_hz); + return -ENOENT; + } + + if (!priv->ppll_hz) { + priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], + priv->cru, PPLL); + } + + switch (clk->id) { + case PLL_LPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], priv->cru, + LPLL); + priv->lpll_hz = rate; + break; + case PLL_BPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[BPLL], priv->cru, + BPLL); + priv->bpll_hz = rate; + break; + case PLL_GPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], priv->cru, + GPLL); + break; + case PLL_CPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], priv->cru, + CPLL); + break; + case PLL_VPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], priv->cru, + VPLL); + break; + case PLL_AUPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], priv->cru, + AUPLL); + break; + case PLL_PPLL: + rate = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], priv->cru, + PPLL) * 2; + break; + case ACLK_BUS_ROOT: + case HCLK_BUS_ROOT: + case PCLK_BUS_ROOT: + rate = rk3576_bus_get_clk(priv, clk->id); + break; + case ACLK_TOP: + case HCLK_TOP: + case PCLK_TOP_ROOT: + case ACLK_TOP_MID: + rate = rk3576_top_get_clk(priv, clk->id); + break; + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + case CLK_I2C6: + case CLK_I2C7: + case CLK_I2C8: + case CLK_I2C9: + rate = rk3576_i2c_get_clk(priv, clk->id); + break; + case CLK_SPI0: + case CLK_SPI1: + case CLK_SPI2: + case CLK_SPI3: + case CLK_SPI4: + rate = rk3576_spi_get_clk(priv, clk->id); + break; + case CLK_PWM1: + case CLK_PWM2: + case CLK_PMU1PWM: + rate = rk3576_pwm_get_clk(priv, clk->id); + break; + case CLK_SARADC: + case CLK_TSADC: + rate = rk3576_adc_get_clk(priv, clk->id); + break; + case CCLK_SRC_SDIO: + case CCLK_SRC_SDMMC0: + case CCLK_SRC_EMMC: + case BCLK_EMMC: + case SCLK_FSPI_X2: + case SCLK_FSPI1_X2: + case DCLK_DECOM: + case HCLK_SDMMC0: + case HCLK_EMMC: + case HCLK_SDIO: + rate = rk3576_mmc_get_clk(priv, clk->id); + break; + case TCLK_EMMC: + case TCLK_WDT0: + rate = OSC_HZ; + break; +#ifndef CONFIG_SPL_BUILD + case ACLK_VOP_ROOT: + case ACLK_VOP: + case ACLK_VO0_ROOT: + case ACLK_VO1_ROOT: + case HCLK_VOP_ROOT: + case PCLK_VOP_ROOT: + rate = rk3576_aclk_vop_get_clk(priv, clk->id); + break; + case DCLK_VP0: + case DCLK_VP0_SRC: + case DCLK_VP1: + case DCLK_VP1_SRC: + case DCLK_VP2: + case DCLK_VP2_SRC: + rate = rk3576_dclk_vop_get_clk(priv, clk->id); + break; + case CLK_GMAC0_PTP_REF_SRC: + case CLK_GMAC1_PTP_REF_SRC: + case CLK_GMAC0_PTP_REF: + case CLK_GMAC1_PTP_REF: + case CLK_GMAC0_125M_SRC: + case CLK_GMAC1_125M_SRC: + rate = rk3576_gmac_get_clk(priv, clk->id); + break; + case CLK_UART_FRAC_0: + case CLK_UART_FRAC_1: + case CLK_UART_FRAC_2: + rate = rk3576_uart_frac_get_rate(priv, clk->id); + 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: + case SCLK_UART8: + case SCLK_UART9: + case SCLK_UART10: + case SCLK_UART11: + rate = rk3576_uart_get_rate(priv, clk->id); + break; + case CLK_DSIHOST0: + rate = rk3576_clk_csihost_get_clk(priv, clk->id); + break; + case DCLK_EBC: + case DCLK_EBC_FRAC_SRC: + rate = rk3576_dclk_ebc_get_clk(priv, clk->id); + break; +#endif + case CLK_REF_UFS_CLKOUT: + case CLK_REF_OSC_MPHY: + rate = rk3576_ufs_ref_get_rate(priv, clk->id); + break; + + default: + return -ENOENT; + } + + return rate; +}; + +static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate) +{ + struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); + ulong ret = 0; + + if (!priv->ppll_hz) { + priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], + priv->cru, PPLL); + } + if (!priv->aupll_hz) { + priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], + priv->cru, AUPLL); + } + + switch (clk->id) { + case PLL_CPLL: + ret = rockchip_pll_set_rate(&rk3576_pll_clks[CPLL], priv->cru, + CPLL, rate); + priv->cpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[CPLL], + priv->cru, CPLL); + break; + case PLL_GPLL: + ret = rockchip_pll_set_rate(&rk3576_pll_clks[GPLL], priv->cru, + GPLL, rate); + priv->gpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[GPLL], + priv->cru, GPLL); + break; + case PLL_VPLL: + ret = rockchip_pll_set_rate(&rk3576_pll_clks[VPLL], priv->cru, + VPLL, rate); + priv->vpll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[VPLL], + priv->cru, VPLL); + break; + case PLL_AUPLL: + ret = rockchip_pll_set_rate(&rk3576_pll_clks[AUPLL], priv->cru, + AUPLL, rate); + priv->aupll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[AUPLL], + priv->cru, AUPLL); + break; + case PLL_PPLL: + ret = rockchip_pll_set_rate(&rk3576_pll_clks[PPLL], priv->cru, + PPLL, rate); + priv->ppll_hz = rockchip_pll_get_rate(&rk3576_pll_clks[PPLL], + priv->cru, PPLL) * 2; + break; + case ACLK_BUS_ROOT: + case HCLK_BUS_ROOT: + case PCLK_BUS_ROOT: + ret = rk3576_bus_set_clk(priv, clk->id, rate); + break; + case ACLK_TOP: + case HCLK_TOP: + case PCLK_TOP_ROOT: + case ACLK_TOP_MID: + ret = rk3576_top_set_clk(priv, clk->id, rate); + break; + case CLK_I2C0: + case CLK_I2C1: + case CLK_I2C2: + case CLK_I2C3: + case CLK_I2C4: + case CLK_I2C5: + case CLK_I2C6: + case CLK_I2C7: + case CLK_I2C8: + case CLK_I2C9: + ret = rk3576_i2c_set_clk(priv, clk->id, rate); + break; + case CLK_SPI0: + case CLK_SPI1: + case CLK_SPI2: + case CLK_SPI3: + case CLK_SPI4: + ret = rk3576_spi_set_clk(priv, clk->id, rate); + break; + case CLK_PWM1: + case CLK_PWM2: + case CLK_PMU1PWM: + ret = rk3576_pwm_set_clk(priv, clk->id, rate); + break; + case CLK_SARADC: + case CLK_TSADC: + ret = rk3576_adc_set_clk(priv, clk->id, rate); + break; + case CCLK_SRC_SDIO: + case CCLK_SRC_SDMMC0: + case CCLK_SRC_EMMC: + case BCLK_EMMC: + case SCLK_FSPI_X2: + case SCLK_FSPI1_X2: + case DCLK_DECOM: + case HCLK_SDMMC0: + case HCLK_EMMC: + case HCLK_SDIO: + ret = rk3576_mmc_set_clk(priv, clk->id, rate); + break; + case TCLK_EMMC: + case TCLK_WDT0: + ret = OSC_HZ; + break; + + /* Might occur in cru assigned-clocks, can be ignored here */ + case CLK_AUDIO_FRAC_0: + case CLK_AUDIO_FRAC_1: + case CLK_AUDIO_FRAC_0_SRC: + case CLK_AUDIO_FRAC_1_SRC: + case CLK_CPLL_DIV2: + case CLK_CPLL_DIV4: + case CLK_CPLL_DIV10: + case FCLK_DDR_CM0_CORE: + case ACLK_PHP_ROOT: + ret = 0; + break; +#ifndef CONFIG_SPL_BUILD + case ACLK_VOP_ROOT: + case ACLK_VOP: + case ACLK_VO0_ROOT: + case ACLK_VO1_ROOT: + case HCLK_VOP_ROOT: + case PCLK_VOP_ROOT: + ret = rk3576_aclk_vop_set_clk(priv, clk->id, rate); + break; + case DCLK_VP0: + case DCLK_VP0_SRC: + case DCLK_VP1: + case DCLK_VP1_SRC: + case DCLK_VP2: + case DCLK_VP2_SRC: + ret = rk3576_dclk_vop_set_clk(priv, clk->id, rate); + break; + case CLK_GMAC0_PTP_REF_SRC: + case CLK_GMAC1_PTP_REF_SRC: + case CLK_GMAC0_PTP_REF: + case CLK_GMAC1_PTP_REF: + case CLK_GMAC0_125M_SRC: + case CLK_GMAC1_125M_SRC: + ret = rk3576_gmac_set_clk(priv, clk->id, rate); + break; + case CLK_UART_FRAC_0: + case CLK_UART_FRAC_1: + case CLK_UART_FRAC_2: + ret = rk3576_uart_frac_set_rate(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: + case SCLK_UART8: + case SCLK_UART9: + case SCLK_UART10: + case SCLK_UART11: + ret = rk3576_uart_set_rate(priv, clk->id, rate); + break; + case CLK_DSIHOST0: + ret = rk3576_clk_csihost_set_clk(priv, clk->id, rate); + break; + case DCLK_EBC: + case DCLK_EBC_FRAC_SRC: + ret = rk3576_dclk_ebc_set_clk(priv, clk->id, rate); + break; +#endif + default: + return -ENOENT; + } + + return ret; +}; + +#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) +static int __maybe_unused rk3576_dclk_vop_set_parent(struct clk *clk, + struct clk *parent) +{ + struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3576_cru *cru = priv->cru; + u32 sel; + const char *clock_dev_name = parent->dev->name; + + if (parent->id == PLL_VPLL) + sel = 2; + else if (parent->id == PLL_GPLL) + sel = 0; + else if (parent->id == PLL_CPLL) + sel = 1; + else if (parent->id == PLL_BPLL) + sel = 3; + else + sel = 4; + + switch (clk->id) { + case DCLK_VP0_SRC: + rk_clrsetreg(&cru->clksel_con[145], DCLK0_VOP_SRC_SEL_MASK, + sel << DCLK0_VOP_SRC_SEL_SHIFT); + break; + case DCLK_VP1_SRC: + rk_clrsetreg(&cru->clksel_con[146], DCLK0_VOP_SRC_SEL_MASK, + sel << DCLK0_VOP_SRC_SEL_SHIFT); + break; + case DCLK_VP2_SRC: + rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SRC_SEL_MASK, + sel << DCLK0_VOP_SRC_SEL_SHIFT); + break; + case DCLK_VP0: + if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) + sel = 1; + else + sel = 0; + rk_clrsetreg(&cru->clksel_con[147], DCLK0_VOP_SEL_MASK, + sel << DCLK0_VOP_SEL_SHIFT); + break; + case DCLK_VP1: + if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) + sel = 1; + else + sel = 0; + rk_clrsetreg(&cru->clksel_con[147], DCLK1_VOP_SEL_MASK, + sel << DCLK1_VOP_SEL_SHIFT); + break; + case DCLK_VP2: + if (!strcmp(clock_dev_name, "hdmiphypll_clk0")) + sel = 1; + else + sel = 0; + rk_clrsetreg(&cru->clksel_con[147], DCLK2_VOP_SEL_MASK, + sel << DCLK2_VOP_SEL_SHIFT); + break; + case DCLK_EBC: + if (parent->id == PLL_GPLL) + sel = 0; + else if (parent->id == PLL_CPLL) + sel = 1; + else if (parent->id == PLL_VPLL) + sel = 2; + else if (parent->id == PLL_AUPLL) + sel = 3; + else if (parent->id == PLL_LPLL) + sel = 4; + else if (parent->id == DCLK_EBC_FRAC_SRC) + sel = 5; + else + sel = 6; + rk_clrsetreg(&cru->clksel_con[123], DCLK_EBC_SEL_MASK, + sel << DCLK_EBC_SEL_SHIFT); + break; + default: + return -EINVAL; + } + return 0; +} + +static int __maybe_unused rk3576_ufs_ref_set_parent(struct clk *clk, + struct clk *parent) +{ + struct rk3576_clk_priv *priv = dev_get_priv(clk->dev); + struct rk3576_cru *cru = priv->cru; + u32 sel; + const char *clock_dev_name = parent->dev->name; + + if (parent->id == CLK_REF_MPHY_26M) + sel = 2; + else if (!strcmp(clock_dev_name, "xin24m")) + sel = 0; + else + sel = 1; + + rk_clrsetreg(&cru->pmuclksel_con[3], 0x3, sel << 0); + return 0; +} + +static int rk3576_clk_set_parent(struct clk *clk, struct clk *parent) +{ + switch (clk->id) { + case DCLK_VP0_SRC: + case DCLK_VP1_SRC: + case DCLK_VP2_SRC: + case DCLK_VP0: + case DCLK_VP1: + case DCLK_VP2: + case DCLK_EBC: + return rk3576_dclk_vop_set_parent(clk, parent); + case CLK_REF_OSC_MPHY: + return rk3576_ufs_ref_set_parent(clk, parent); + case CLK_AUDIO_FRAC_0_SRC: + case CLK_AUDIO_FRAC_1_SRC: + /* Might occur in cru assigned-clocks, can be ignored here */ + return 0; + default: + return -ENOENT; + } + + return 0; +} +#endif + +static struct clk_ops rk3576_clk_ops = { + .get_rate = rk3576_clk_get_rate, + .set_rate = rk3576_clk_set_rate, +#if (IS_ENABLED(OF_CONTROL)) || (!IS_ENABLED(OF_PLATDATA)) + .set_parent = rk3576_clk_set_parent, +#endif +}; + +static void rk3576_clk_init(struct rk3576_clk_priv *priv) +{ + int ret; + + priv->spll_hz = 702000000; + + if (priv->cpll_hz != CPLL_HZ) { + ret = rockchip_pll_set_rate(&rk3576_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(&rk3576_pll_clks[GPLL], priv->cru, + GPLL, GPLL_HZ); + if (!ret) + priv->gpll_hz = GPLL_HZ; + } + rk_clrsetreg(&priv->cru->clksel_con[123], + DCLK_EBC_FRAC_SRC_SEL_MASK, + (DCLK_EBC_FRAC_SRC_SEL_GPLL << + DCLK_EBC_FRAC_SRC_SEL_SHIFT)); +} + +static int rk3576_clk_probe(struct udevice *dev) +{ + struct rk3576_clk_priv *priv = dev_get_priv(dev); + int ret; + + priv->sync_kernel = false; + +#ifdef CONFIG_SPL_BUILD + /* relase presetn_bigcore_biu/cru/grf */ + writel(0x1c001c00, 0x26010010); + /* set spll to normal mode */ + writel(BITS_WITH_WMASK(2, 0x7U, 6), + RK3576_SCRU_BASE + RK3576_PLL_CON(137)); + writel(BITS_WITH_WMASK(1, 0x3U, 0), + RK3576_SCRU_BASE + RK3576_MODE_CON0); + /* fix ppll\aupll\cpll */ + writel(BITS_WITH_WMASK(2, 0x7U, 6), + RK3576_CRU_BASE + RK3576_PMU_PLL_CON(129)); + writel(BITS_WITH_WMASK(2, 0x7U, 6), + RK3576_CRU_BASE + RK3576_PLL_CON(97)); + writel(BITS_WITH_WMASK(2, 0x7U, 6), + RK3576_CRU_BASE + RK3576_PLL_CON(105)); + writel(BITS_WITH_WMASK(1, 0x3U, 6), + RK3576_CRU_BASE + RK3576_MODE_CON0); + writel(BITS_WITH_WMASK(1, 0x3U, 8), + RK3576_CRU_BASE + RK3576_MODE_CON0); + /* init cci */ + writel(0xffff0000, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); + rockchip_pll_set_rate(&rk3576_pll_clks[BPLL], priv->cru, + BPLL, LPLL_HZ); + if (!priv->armclk_enter_hz) { + ret = rockchip_pll_set_rate(&rk3576_pll_clks[LPLL], priv->cru, + LPLL, LPLL_HZ); + priv->armclk_enter_hz = + rockchip_pll_get_rate(&rk3576_pll_clks[LPLL], + priv->cru, LPLL); + priv->armclk_init_hz = priv->armclk_enter_hz; + rk_clrsetreg(&priv->cru->litclksel_con[0], CLK_LITCORE_DIV_MASK, + 0 << CLK_LITCORE_DIV_SHIFT); + } + /* init cci */ + writel(0xffff20cb, RK3576_CRU_BASE + RK3576_CCI_CLKSEL_CON(4)); + + /* Change bigcore rm from 4 to 3 */ + writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x3c); + writel(0x001c000c, RK3576_BIGCORE_GRF_BASE + 0x44); + writel(0x00020002, RK3576_BIGCORE_GRF_BASE + 0x38); + udelay(1); + writel(0x00020000, RK3576_BIGCORE_GRF_BASE + 0x38); + /* Change litcore rm from 4 to 3 */ + writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x3c); + writel(0x001c000c, RK3576_LITCORE_GRF_BASE + 0x44); + writel(0x00020002, RK3576_LITCORE_GRF_BASE + 0x38); + udelay(1); + writel(0x00020000, RK3576_LITCORE_GRF_BASE + 0x38); + /* Change cci rm form 4 to 3 */ + writel(0x001c000c, RK3576_CCI_GRF_BASE + 0x54); +#endif + + rk3576_clk_init(priv); + + /* 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 rk3576_clk_ofdata_to_platdata(struct udevice *dev) +{ + struct rk3576_clk_priv *priv = dev_get_priv(dev); + + priv->cru = dev_read_addr_ptr(dev); + + return 0; +} + +static int rk3576_clk_bind(struct udevice *dev) +{ + int ret; + struct udevice *sys_child; + struct sysreset_reg *priv; + + /* 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 rk3576_cru, + glb_srst_fst); + priv->glb_srst_snd_value = offsetof(struct rk3576_cru, + glb_srsr_snd); + dev_set_priv(sys_child, priv); + } + +#if CONFIG_IS_ENABLED(RESET_ROCKCHIP) + ret = offsetof(struct rk3576_cru, softrst_con[0]); + ret = rk3576_reset_bind_lut(dev, ret, 32776); + if (ret) + debug("Warning: software reset driver bind failed\n"); +#endif + + return 0; +} + +static const struct udevice_id rk3576_clk_ids[] = { + { .compatible = "rockchip,rk3576-cru" }, + { } +}; + +U_BOOT_DRIVER(rockchip_rk3576_cru) = { + .name = "rockchip_rk3576_cru", + .id = UCLASS_CLK, + .of_match = rk3576_clk_ids, + .priv_auto = sizeof(struct rk3576_clk_priv), + .of_to_plat = rk3576_clk_ofdata_to_platdata, + .ops = &rk3576_clk_ops, + .bind = rk3576_clk_bind, + .probe = rk3576_clk_probe, +}; diff --git a/drivers/ddr/altera/iossm_mailbox.c b/drivers/ddr/altera/iossm_mailbox.c index db9435db657..fc09dde3f9e 100644 --- a/drivers/ddr/altera/iossm_mailbox.c +++ b/drivers/ddr/altera/iossm_mailbox.c @@ -10,6 +10,7 @@ #include <asm/arch/base_addr_soc64.h> #include <asm/io.h> #include <linux/bitfield.h> +#include <linux/sizes.h> #include "iossm_mailbox.h" #define TIMEOUT_120000MS 120000 @@ -87,6 +88,7 @@ /* offset info of ECC_ENABLE_INTF */ #define INTF_ECC_ENABLE_TYPE_MASK GENMASK(1, 0) +#define INTF_ECC_TYPE_MASK BIT(8) /* cmd opcode BIST_MEM_INIT_START, BIST performed on full memory address range */ #define BIST_FULL_MEM BIT(6) @@ -96,6 +98,7 @@ /* offset info of ECC_ERR_STATUS */ #define ECC_ERR_COUNTER_MASK GENMASK(15, 0) +#define ECC_ERR_OVERFLOW_MASK GENMASK(31, 16) /* offset info of ECC_ERR_DATA */ #define ECC_ERR_IP_TYPE_MASK GENMASK(24, 22) @@ -104,9 +107,15 @@ #define ECC_ERR_TYPE_MASK GENMASK(9, 6) #define ECC_ERR_ADDR_UPPER_MASK GENMASK(5, 0) #define ECC_ERR_ADDR_LOWER_MASK GENMASK(31, 0) +#define ECC_FULL_ADDR_UPPER_MASK GENMASK(63, 32) +#define ECC_FULL_ADDR_LOWER_MASK GENMASK(31, 0) #define MAX_ECC_ERR_INFO_COUNT 16 +#define BIST_START_ADDR_SPACE_MASK GENMASK(5, 0) +#define BIST_START_ADDR_LOW_MASK GENMASK(31, 0) +#define BIST_START_ADDR_HIGH_MASK GENMASK(37, 32) + #define IO96B_MB_REQ_SETUP(v, w, x, y, z) \ usr_req.ip_type = v; \ usr_req.ip_id = w; \ @@ -161,6 +170,24 @@ struct ecc_err_info { u32 addr_lower; }; +struct ecc_overflow_error_desc { + int bit; + const char *msg; +}; + +static const struct ecc_overflow_error_desc ecc_overflow_errors[] = { + { 0, " - Single-bit error\n" }, + { 1, " - Multiple single-bit errors\n" }, + { 2, " - Double-bit error\n" }, + { 3, " - Multiple double-bit errors\n" }, + { 8, " - Single-bit error during ECC scrubbing\n" }, + { 9, " - Write link ECC single-bit error (LPDDR5 only)\n" }, + { 10, " - Write link ECC double-bit error (LPDDR5 only)\n" }, + { 11, " - Read link ECC single-bit error (LPDDR5 only)\n" }, + { 12, " - Read link ECC double-bit error (LPDDR5 only)\n" }, + { 13, " - RMW read link ECC double-bit error (LPDDR5 only)\n" }, +}; + static int is_ddr_csr_clkgen_locked(u8 io96b_pll) { int ret = 0; @@ -512,7 +539,7 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl) { int i, j, ret = 0; u32 mem_width_info; - u16 memory_size, total_memory_size = 0; + phys_size_t memory_size, total_memory_size = 0; u32 mem_total_capacity_intf_offset[MAX_MEM_INTERFACE_SUPPORTED] = { IOSSM_MEM_TOTAL_CAPACITY_INTF0_OFFSET, @@ -526,8 +553,11 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl) mem_width_info = readl(io96b_ctrl->io96b[i].io96b_csr_addr + mem_total_capacity_intf_offset[j]); - memory_size = memory_size + - FIELD_GET(INTF_CAPACITY_GBITS_MASK, mem_width_info); + io96b_ctrl->io96b[i].mb_ctrl.memory_size[j] = + FIELD_GET(INTF_CAPACITY_GBITS_MASK, mem_width_info) * SZ_1G / SZ_8; + + if (io96b_ctrl->io96b[i].mb_ctrl.memory_size[j] != 0) + memory_size += io96b_ctrl->io96b[i].mb_ctrl.memory_size[j]; } if (!memory_size) { @@ -536,8 +566,6 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl) goto err; } - io96b_ctrl->io96b[i].size = memory_size; - total_memory_size = total_memory_size + memory_size; } @@ -556,7 +584,7 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl) { int i, j, ret = 0; u32 ecc_enable_intf; - bool ecc_stat, ecc_stat_set = false; + bool ecc_status, ecc_status_set = false, inline_ecc = false; u32 ecc_enable_intf_offset[MAX_MEM_INTERFACE_SUPPORTED] = { IOSSM_ECC_ENABLE_INTF0_OFFSET, @@ -565,6 +593,7 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl) /* Initialize ECC status */ io96b_ctrl->ecc_status = false; + io96b_ctrl->inline_ecc = false; /* Get and ensure all memory interface(s) same ECC status */ for (i = 0; i < io96b_ctrl->num_instance; i++) { @@ -572,15 +601,21 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl) ecc_enable_intf = readl(io96b_ctrl->io96b[i].io96b_csr_addr + ecc_enable_intf_offset[j]); - ecc_stat = (FIELD_GET(INTF_ECC_ENABLE_TYPE_MASK, ecc_enable_intf) + ecc_status = (FIELD_GET(INTF_ECC_ENABLE_TYPE_MASK, ecc_enable_intf) == 0) ? false : true; + inline_ecc = FIELD_GET(INTF_ECC_TYPE_MASK, ecc_enable_intf); + + if (!ecc_status_set) { + io96b_ctrl->ecc_status = ecc_status; + + if (io96b_ctrl->ecc_status) + io96b_ctrl->inline_ecc = inline_ecc; - if (!ecc_stat_set) { - io96b_ctrl->ecc_status = ecc_stat; - ecc_stat_set = true; + ecc_status_set = true; } - if (ecc_stat != io96b_ctrl->ecc_status) { + if (ecc_status != io96b_ctrl->ecc_status || + (io96b_ctrl->ecc_status && inline_ecc != io96b_ctrl->inline_ecc)) { printf("%s: Mismatch DDR ECC status on IO96B_%d\n", __func__, i); ret = -EINVAL; @@ -614,16 +649,28 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl) { int i, j; u32 ecc_err_status; - u16 ecc_err_counter; + u16 ecc_err_counter, ecc_overflow_status; bool ecc_error_flag = false; /* Get ECC double-bit error status */ for (i = 0; i < io96b_ctrl->num_instance; i++) { ecc_err_status = readl(io96b_ctrl->io96b[i].io96b_csr_addr + IOSSM_ECC_ERR_STATUS_OFFSET); + ecc_err_counter = FIELD_GET(ECC_ERR_COUNTER_MASK, ecc_err_status); - debug("%s: ECC error number detected on IO96B_%d: %d\n", - __func__, i, ecc_err_counter); + log_err("%s: ECC error number detected on IO96B_%d: %d\n", + __func__, i, ecc_err_counter); + + ecc_overflow_status = FIELD_GET(ECC_ERR_OVERFLOW_MASK, ecc_err_status); + if (ecc_overflow_status != 0) { + log_err("ECC Error Overflow Flags:\n"); + + for (int i = 0; i < ARRAY_SIZE(ecc_overflow_errors); i++) { + if (ecc_overflow_status & BIT(ecc_overflow_errors[i].bit)) { + log_err("%s", ecc_overflow_errors[i].msg); + } + } + } if (ecc_err_counter != 0) { phys_addr_t address; @@ -647,15 +694,20 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl) ecc_err_data); err_info.addr_lower = readl(address + sizeof(u32)); - debug("%s: ECC double-bit error detected on IO96B_%d:\n", - __func__, i); - debug("- error info address :0x%llx\n", address); - debug("- error ip type: %d\n", err_info.ip_type); - debug("- error instance id: %d\n", err_info.instance_id); - debug("- error source id: %d\n", err_info.source_id); - debug("- error type: %d\n", err_info.err_type); - debug("- error address upper: 0x%x\n", err_info.addr_upper); - debug("- error address lower: 0x%x\n", err_info.addr_lower); + log_err(" %s: DDR ECC Error Detected on IO96B_%d number:%d\n", + __func__, i, j); + log_err(" - error info address :0x%llx\n", address); + log_err(" - error ip type: %d\n", err_info.ip_type); + log_err(" - error instance id: %d\n", err_info.instance_id); + log_err(" - error source id: %d\n", err_info.source_id); + log_err(" - error type: %s\n", + is_double_bit_error(err_info.err_type) ? + "Double-bit error" : "Single-bit error"); + log_err(" - error address: 0x%016llx\n", + (u64)FIELD_PREP(ECC_FULL_ADDR_UPPER_MASK, + err_info.addr_upper) | + FIELD_PREP(ECC_FULL_ADDR_LOWER_MASK, + err_info.addr_lower)); if (is_double_bit_error(err_info.err_type)) { if (!ecc_error_flag) @@ -668,12 +720,12 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl) } if (ecc_error_flag) - printf("\n%s: ECC double-bit error detected!\n", __func__); + log_err("\n%s: ECC double-bit error detected!\n", __func__); return ecc_error_flag; } -int bist_mem_init_start(struct io96b_info *io96b_ctrl) +int out_of_band_bist_mem_init_start(struct io96b_info *io96b_ctrl) { struct io96b_mb_req usr_req; struct io96b_mb_resp usr_resp; @@ -746,3 +798,126 @@ int bist_mem_init_start(struct io96b_info *io96b_ctrl) err: return ret; } + +int bist_mem_init_by_addr(struct io96b_info *io96b_ctrl, int inst_id, int intf_id, + phys_addr_t base_addr, phys_size_t size) +{ + struct io96b_mb_req usr_req; + struct io96b_mb_resp usr_resp; + int n, ret = 0; + bool bist_start, bist_success; + u32 mem_exp, mem_init_status_intf, start; + phys_size_t chunk_size; + + u32 mem_init_status_offset[MAX_MEM_INTERFACE_SUPPORTED] = { + IOSSM_MEM_INIT_STATUS_INTF0_OFFSET, + IOSSM_MEM_INIT_STATUS_INTF1_OFFSET + }; + + /* Check if size is a power of 2 */ + if (size == 0 || (size & (size - 1)) != 0) { + ret = -EINVAL; + goto err; + } + + mem_exp = 0; + chunk_size = size; + + while (chunk_size >>= 1) + mem_exp++; + + /* Start memory initialization BIST on the specified address range */ + IO96B_MB_REQ_SETUP(io96b_ctrl->io96b[inst_id].mb_ctrl.ip_type[intf_id], + io96b_ctrl->io96b[inst_id].mb_ctrl.ip_id[intf_id], + CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0); + + /* CMD_PARAM_0 bit[5:0] = mem_exp */ + /* CMD_PARAM_0 bit[6]: 0 - on the specified address range */ + usr_req.cmd_param[0] = FIELD_PREP(BIST_START_ADDR_SPACE_MASK, mem_exp); + /* Extract address fields START_ADDR[31:0] */ + usr_req.cmd_param[1] = FIELD_GET(BIST_START_ADDR_LOW_MASK, base_addr); + /* Extract address fields START_ADDR[37:32] */ + usr_req.cmd_param[2] = FIELD_GET(BIST_START_ADDR_HIGH_MASK, base_addr); + /* Initialize memory to all zeros */ + usr_req.cmd_param[3] = 0; + + bist_start = false; + bist_success = false; + + /* Send request to DDR controller */ + debug("%s:Initializing memory: Addr=0x%llx, Size=2^%u\n", __func__, + base_addr, mem_exp); + ret = io96b_mb_req(io96b_ctrl->io96b[inst_id].io96b_csr_addr, + usr_req, 0, &usr_resp); + if (ret) + goto err; + + bist_start = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) + & BIT(0); + + if (!bist_start) { + printf("%s: Failed to initialize memory on IO96B_%d\n", __func__, + inst_id); + printf("%s: BIST_MEM_INIT_START Error code 0x%lx\n", __func__, + IOSSM_STATUS_CMD_RESPONSE_ERROR(usr_resp.cmd_resp_status)); + + ret = -EINVAL; + goto err; + } + + /* Polling for the initiated memory initialization BIST status */ + start = get_timer(0); + while (!bist_success) { + udelay(1); + + mem_init_status_intf = readl(io96b_ctrl->io96b[inst_id].io96b_csr_addr + + mem_init_status_offset[intf_id]); + + bist_success = FIELD_GET(INTF_BIST_STATUS_MASK, mem_init_status_intf); + + if (!bist_success && (get_timer(start) > TIMEOUT)) { + printf("%s: Timeout initialize memory on IO96B_%d\n", + __func__, inst_id); + printf("%s: BIST_MEM_INIT_STATUS Error code 0x%lx\n", + __func__, + IOSSM_STATUS_CMD_RESPONSE_ERROR(usr_resp.cmd_resp_status)); + + ret = -ETIMEDOUT; + goto err; + } + } + + debug("%s:DDR memory initializationat 0x%llx completed.\n", __func__, base_addr); + +err: + return ret; +} + +int inline_ecc_bist_mem_init(struct io96b_info *io96b_ctrl) +{ + int i, j, ret = 0; + + /* Memory initialization BIST performed on all memory interfaces */ + for (i = 0; i < io96b_ctrl->num_instance; i++) { + for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) { + ret = bist_mem_init_by_addr(io96b_ctrl, i, j, 0, + io96b_ctrl->io96b[i].mb_ctrl.memory_size[j]); + if (ret) { + printf("Error: Memory init failed at Instance %d, Interface %d\n", + i, j); + goto err; + } + } + } + +err: + return ret; +} + +int bist_mem_init_start(struct io96b_info *io96b_ctrl) +{ + if (io96b_ctrl->inline_ecc) + return inline_ecc_bist_mem_init(io96b_ctrl); + else + return out_of_band_bist_mem_init_start(io96b_ctrl); +} diff --git a/drivers/ddr/altera/iossm_mailbox.h b/drivers/ddr/altera/iossm_mailbox.h index 6f794781d30..02d1db28e20 100644 --- a/drivers/ddr/altera/iossm_mailbox.h +++ b/drivers/ddr/altera/iossm_mailbox.h @@ -40,11 +40,13 @@ enum iossm_mailbox_cmd_opcode { * @num_mem_interface: Number of memory interfaces instantiated * @ip_type: IP type implemented on the IO96B * @ip_instance_id: IP identifier for every IP instance implemented on the IO96B + * @memory_size[2]: Memory size for every IP instance implemented on the IO96B */ struct io96b_mb_ctrl { u32 num_mem_interface; u32 ip_type[2]; u32 ip_id[2]; + phys_size_t memory_size[2]; }; /* CMD_REQ Register Definition */ @@ -53,6 +55,9 @@ struct io96b_mb_ctrl { #define CMD_TYPE_MASK GENMASK(23, 16) #define CMD_OPCODE_MASK GENMASK(15, 0) +/* Computes the Inline ECC data region size */ +#define CALC_INLINE_ECC_HW_SIZE(size) (((size) * 7) / 8) + /* * IOSSM mailbox request * @ip_type: IP type for the specified memory interface @@ -83,13 +88,11 @@ struct io96b_mb_resp { /* * IO96B instance specific information * - * @size: Memory size * @io96b_csr_addr: IO96B instance CSR address * @cal_status: IO96B instance calibration status * @mb_ctrl: IOSSM mailbox required information */ struct io96b_instance { - u16 size; phys_addr_t io96b_csr_addr; bool cal_status; struct io96b_mb_ctrl mb_ctrl; @@ -102,6 +105,7 @@ struct io96b_instance { * @overall_cal_status: Overall calibration status for all IO96B instance(s) * @ddr_type: DDR memory type * @ecc_status: ECC enable status (false = disabled, true = enabled) + * @inline_ecc: Inline ECC or Out of Band ECC (false = Out of Band ECC, true = Inline ECC) * @overall_size: Total DDR memory size * @io96b[]: IO96B instance specific information * @ckgen_lock: IO96B GEN PLL lock (false = not locked, true = locked) @@ -115,7 +119,8 @@ struct io96b_info { bool overall_cal_status; const char *ddr_type; bool ecc_status; - u16 overall_size; + bool inline_ecc; + phys_size_t overall_size; struct io96b_instance io96b[MAX_IO96B_SUPPORTED]; bool ckgen_lock; u8 num_port; diff --git a/drivers/ddr/altera/sdram_agilex5.c b/drivers/ddr/altera/sdram_agilex5.c index 801a6bbab46..ee66c72157a 100644 --- a/drivers/ddr/altera/sdram_agilex5.c +++ b/drivers/ddr/altera/sdram_agilex5.c @@ -291,7 +291,14 @@ int sdram_mmr_init_full(struct udevice *dev) goto err; } - hw_size = (phys_size_t)io96b_ctrl->overall_size * SZ_1G / SZ_8; + ret = ecc_enable_status(io96b_ctrl); + if (ret) { + printf("DDR: Failed to get ECC enabled status\n"); + + goto err; + } + + hw_size = io96b_ctrl->overall_size; /* Get bank configuration from devicetree */ ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL, @@ -303,6 +310,9 @@ int sdram_mmr_init_full(struct udevice *dev) goto err; } + if (io96b_ctrl->inline_ecc) + hw_size = CALC_INLINE_ECC_HW_SIZE(hw_size); + if (gd->ram_size > hw_size) { printf("DDR: Warning: DRAM size from device tree (%lld MiB) exceeds\n", gd->ram_size >> 20); @@ -355,13 +365,6 @@ int sdram_mmr_init_full(struct udevice *dev) printf("%s: %lld MiB\n", io96b_ctrl->ddr_type, gd->ram_size >> 20); - ret = ecc_enable_status(io96b_ctrl); - if (ret) { - printf("DDR: Failed to get ECC enabled status\n"); - - goto err; - } - /* Is HPS cold or warm reset? If yes, Skip full memory initialization if ECC * enabled to preserve memory content */ diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c index c8c9211adce..27fbe80ed41 100644 --- a/drivers/ddr/altera/sdram_soc64.c +++ b/drivers/ddr/altera/sdram_soc64.c @@ -185,35 +185,51 @@ void sdram_init_ecc_bits(struct bd_info *bd) void sdram_size_check(struct bd_info *bd) { phys_size_t total_ram_check = 0; - phys_size_t ram_check = 0; - phys_addr_t start = 0; - phys_size_t size, remaining_size; int bank; /* Sanity check ensure correct SDRAM size specified */ debug("DDR: Running SDRAM size sanity check\n"); for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + phys_size_t ram_check = 0; + phys_addr_t start = 0; + phys_size_t remaining_size; + start = bd->bi_dram[bank].start; remaining_size = bd->bi_dram[bank].size; + debug("Checking bank %d: start=0x%llx, size=0x%llx\n", + bank, start, remaining_size); + while (ram_check < bd->bi_dram[bank].size) { - size = min((phys_addr_t)SZ_1G, - (phys_addr_t)remaining_size); - - /* - * Ensure the size is power of two, this is requirement - * to run get_ram_size() / memory test - */ - if (size != 0 && ((size & (size - 1)) == 0)) { - ram_check += get_ram_size((void *) - (start + ram_check), size); - remaining_size = bd->bi_dram[bank].size - - ram_check; - } else { - puts("DDR: Memory test requires SDRAM size "); - puts("in power of two!\n"); + phys_size_t size, test_size, detected_size; + + size = min((phys_addr_t)SZ_1G, (phys_addr_t)remaining_size); + + if (size < SZ_8) { + puts("Invalid size: Memory size required to be multiple\n"); + puts("of 64-Bit word!\n"); hang(); } + + /* Adjust size to the nearest power of two to support get_ram_size() */ + test_size = SZ_8; + + while (test_size * 2 <= size) + test_size *= 2; + + debug("Testing memory at 0x%llx with size 0x%llx\n", + start + ram_check, test_size); + detected_size = get_ram_size((void *)(start + ram_check), test_size); + + if (detected_size != test_size) { + debug("Detected size 0x%llx doesn’t match the test size 0x%llx!\n", + detected_size, test_size); + puts("Memory testing failed!\n"); + hang(); + } + + ram_check += detected_size; + remaining_size = bd->bi_dram[bank].size - ram_check; } total_ram_check += ram_check; @@ -249,7 +265,7 @@ phys_size_t sdram_calculate_size(struct altera_sdram_plat *plat) DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) + DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw)); - size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) & + size *= ((phys_size_t)2 << (hmc_ecc_readl(plat, DDRIOCTRL) & DDR_HMC_DDRIOCTRL_IOSIZE_MSK)); return size; diff --git a/drivers/firmware/scmi/sandbox-scmi_devices.c b/drivers/firmware/scmi/sandbox-scmi_devices.c index 9f253b0fd40..96c2922b067 100644 --- a/drivers/firmware/scmi/sandbox-scmi_devices.c +++ b/drivers/firmware/scmi/sandbox-scmi_devices.c @@ -163,5 +163,4 @@ U_BOOT_DRIVER(sandbox_scmi_devices) = { .priv_auto = sizeof(struct sandbox_scmi_device_priv), .remove = sandbox_scmi_devices_remove, .probe = sandbox_scmi_devices_probe, - .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; diff --git a/drivers/firmware/scmi/scmi_agent-uclass.c b/drivers/firmware/scmi/scmi_agent-uclass.c index 8c907c3b032..e6e43ae936a 100644 --- a/drivers/firmware/scmi/scmi_agent-uclass.c +++ b/drivers/firmware/scmi/scmi_agent-uclass.c @@ -427,14 +427,8 @@ static int scmi_bind_protocols(struct udevice *dev) break; case SCMI_PROTOCOL_ID_VOLTAGE_DOMAIN: if (IS_ENABLED(CONFIG_DM_REGULATOR_SCMI) && - scmi_protocol_is_supported(dev, protocol_id)) { - node = ofnode_find_subnode(node, "regulators"); - if (!ofnode_valid(node)) { - dev_err(dev, "no regulators node\n"); - return -ENXIO; - } + scmi_protocol_is_supported(dev, protocol_id)) drv = DM_DRIVER_GET(scmi_voltage_domain); - } break; default: break; diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 46e76385961..146bc621c7e 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -510,6 +510,15 @@ config SYS_I2C_OMAP24XX help Add support for the OMAP2+ I2C driver. +config SYS_I2C_OMAP24XX_REPEATED_START + bool "Enable I2C repeated start" + depends on SYS_I2C_OMAP24XX + default y if ARCH_K3 + help + Enable support for repeated start. Updates driver defaults to not + send a Stop condition and issue Repeated Start (Sr) for subsequent + i2c msgs. + config SYS_I2C_RCAR_I2C bool "Renesas R-Car I2C driver" depends on (RCAR_GEN2 || RCAR_64) && DM_I2C diff --git a/drivers/i2c/mtk_i2c.c b/drivers/i2c/mtk_i2c.c index 3450177741a..55381dbeced 100644 --- a/drivers/i2c/mtk_i2c.c +++ b/drivers/i2c/mtk_i2c.c @@ -143,7 +143,6 @@ static const uint mt_i2c_regs_v1[] = { [REG_RSV_DEBUG] = 0x44, [REG_HS] = 0x48, [REG_SOFTRESET] = 0x50, - [REG_SOFTRESET] = 0x50, [REG_DCM_EN] = 0x54, [REG_DEBUGSTAT] = 0x64, [REG_DEBUGCTRL] = 0x68, @@ -879,7 +878,7 @@ static const struct udevice_id mtk_i2c_ids[] = { }, { .compatible = "mediatek,mt8518-i2c", .data = (ulong)&mt8518_soc_data, - } + }, {} }; U_BOOT_DRIVER(mtk_i2c) = { diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c index ebe472e20cd..a6361d3d17d 100644 --- a/drivers/i2c/omap24xx_i2c.c +++ b/drivers/i2c/omap24xx_i2c.c @@ -535,12 +535,16 @@ pr_exit: return res; } +#if !CONFIG_IS_ENABLED(DM_I2C) +/* + * The legacy I2C functions. These need to get removed once + * all users of this driver are converted to DM. + */ + /* * i2c_read: Function now uses a single I2C read transaction with bulk transfer * of the requested number of bytes (note that the 'i2c md' command - * limits this to 16 bytes anyway). If CONFIG_I2C_REPEATED_START is - * defined in the board config header, this transaction shall be with - * Repeated Start (Sr) between the address and data phases; otherwise + * limits this to 16 bytes anyway). * Stop-Start (P-S) shall be used (some I2C chips do require a P-S). * The address (reg offset) may be 0, 1 or 2 bytes long. * Function now reads correctly from chips that return more than one @@ -608,16 +612,10 @@ static int __omap24_i2c_read(void __iomem *i2c_base, int ip_rev, int waitdelay, if (alen) { /* Must write reg offset first */ -#ifdef CONFIG_I2C_REPEATED_START - /* No stop bit, use Repeated Start (Sr) */ - omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST | - I2C_CON_STT | I2C_CON_TRX, OMAP_I2C_CON_REG); -#else /* Stop - Start (P-S) */ omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP | I2C_CON_TRX, OMAP_I2C_CON_REG); -#endif /* Send register offset */ while (1) { status = wait_for_event(i2c_base, ip_rev, waitdelay); @@ -836,11 +834,6 @@ wr_exit: return i2c_error; } -#if !CONFIG_IS_ENABLED(DM_I2C) -/* - * The legacy I2C functions. These need to get removed once - * all users of this driver are converted to DM. - */ static void __iomem *omap24_get_base(struct i2c_adapter *adap) { switch (adap->hwadapnr) { @@ -971,28 +964,140 @@ U_BOOT_I2C_ADAP_COMPLETE(omap24_4, omap24_i2c_init, omap24_i2c_probe, #else /* CONFIG_DM_I2C */ +static int __omap24_i2c_xfer_msg(void __iomem *i2c_base, int ip_rev, int waitdelay, + uchar chip, uchar *buffer, int len, u16 i2c_con_reg) +{ + int i; + u16 status; + int i2c_error = 0; + int timeout = I2C_TIMEOUT; + + if (len < 0) { + printf("%s: data len < 0\n", __func__); + return -EINVAL; + } + + if (!buffer) { + printf("%s: NULL pointer passed\n", __func__); + return -EINVAL; + } + + if (!(i2c_con_reg & I2C_CON_EN)) { + printf("%s: I2C_CON_EN not set\n", __func__); + return -EINVAL; + } + + /* Set slave address */ + omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG); + /* Read/Write len bytes data */ + omap_i2c_write_reg(i2c_base, ip_rev, len, OMAP_I2C_CNT_REG); + /* Configure the I2C_CON register */ + omap_i2c_write_reg(i2c_base, ip_rev, i2c_con_reg, OMAP_I2C_CON_REG); + + /* read/write data bytewise */ + for (i = 0; i < len; i++) { + status = wait_for_event(i2c_base, ip_rev, waitdelay); + /* Ignore I2C_STAT_RRDY in transmitter mode */ + if (i2c_con_reg & I2C_CON_TRX) + status &= ~I2C_STAT_RRDY; + else + status &= ~I2C_STAT_XRDY; + + /* Try to identify bus that is not padconf'd for I2C */ + if (status == I2C_STAT_XRDY) { + i2c_error = -EREMOTEIO; + printf("%s: pads on bus probably not configured (status=0x%x)\n", + __func__, status); + goto xfer_exit; + } + if (status == 0 || (status & I2C_STAT_NACK)) { + i2c_error = -EREMOTEIO; + printf("%s: error waiting for ACK (status=0x%x)\n", + __func__, status); + goto xfer_exit; + } + if (status & I2C_STAT_XRDY) { + /* Transmit data */ + omap_i2c_write_reg(i2c_base, ip_rev, + buffer[i], OMAP_I2C_DATA_REG); + omap_i2c_write_reg(i2c_base, ip_rev, + I2C_STAT_XRDY, OMAP_I2C_STAT_REG); + } + if (status & I2C_STAT_RRDY) { + /* Receive data */ + *buffer++ = omap_i2c_read_reg(i2c_base, ip_rev, + OMAP_I2C_DATA_REG); + omap_i2c_write_reg(i2c_base, ip_rev, + I2C_STAT_RRDY, OMAP_I2C_STAT_REG); + } + } + + /* + * poll ARDY bit for making sure that last byte really has been + * transferred on the bus. + */ + do { + status = wait_for_event(i2c_base, ip_rev, waitdelay); + } while (!(status & I2C_STAT_ARDY) && timeout--); + if (timeout <= 0) { + printf("%s: timed out on last byte!\n", __func__); + i2c_error = -EREMOTEIO; + goto xfer_exit; + } else { + omap_i2c_write_reg(i2c_base, ip_rev, I2C_STAT_ARDY, OMAP_I2C_STAT_REG); + } + + /* If Stop bit set, flush FIFO. */ + if (i2c_con_reg & I2C_CON_STP) + goto xfer_exit; + + return 0; + +xfer_exit: + flush_fifo(i2c_base, ip_rev); + omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG); + return i2c_error; +} + static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) { struct omap_i2c *priv = dev_get_priv(bus); int ret; + u16 i2c_con_reg = 0; - debug("i2c_xfer: %d messages\n", nmsgs); - for (; nmsgs > 0; nmsgs--, msg++) { - debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len); - if (msg->flags & I2C_M_RD) { - ret = __omap24_i2c_read(priv->regs, priv->ip_rev, - priv->waitdelay, - msg->addr, 0, 0, msg->buf, - msg->len); - } else { - ret = __omap24_i2c_write(priv->regs, priv->ip_rev, - priv->waitdelay, - msg->addr, 0, 0, msg->buf, - msg->len); - } + debug("%s: %d messages\n", __func__, nmsgs); + for (int i = 0; i < nmsgs; i++, msg++) { + /* + * If previous msg sent a Stop or if this is the first msg + * Wait until bus not busy + */ + if ((i2c_con_reg & I2C_CON_STP) || (i == 0)) + if (wait_for_bb(priv->regs, priv->ip_rev, priv->waitdelay)) + return -EREMOTEIO; + + /* Set Controller mode with Start bit */ + i2c_con_reg = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT; + /* Set Transmitter/Receiver mode if it is a write/read msg */ + if (msg->flags & I2C_M_RD) + i2c_con_reg &= ~I2C_CON_TRX; + else + i2c_con_reg |= I2C_CON_TRX; + /* Send Stop condition (P) by default */ + if (!IS_ENABLED(CONFIG_SYS_I2C_OMAP24XX_REPEATED_START)) + i2c_con_reg |= I2C_CON_STP; + /* Send Stop if explicitly requested or if this is the last msg */ + if ((msg->flags & I2C_M_STOP) || (i == nmsgs - 1)) + i2c_con_reg |= I2C_CON_STP; + + debug("%s: chip=0x%x, len=0x%x, i2c_con_reg=0x%x\n", + __func__, msg->addr, msg->len, i2c_con_reg); + + ret = __omap24_i2c_xfer_msg(priv->regs, priv->ip_rev, priv->waitdelay, + msg->addr, msg->buf, msg->len, + i2c_con_reg); if (ret) { - debug("i2c_write: error sending\n"); - return -EREMOTEIO; + printf("%s: errored out at msg %d: %d\n", __func__, i, ret); + return ret; } } diff --git a/drivers/misc/rockchip-otp.c b/drivers/misc/rockchip-otp.c index 2123c31038f..46820425a84 100644 --- a/drivers/misc/rockchip-otp.c +++ b/drivers/misc/rockchip-otp.c @@ -361,6 +361,13 @@ static const struct rockchip_otp_data rk3568_data = { .block_size = 2, }; +static const struct rockchip_otp_data rk3576_data = { + .read = rockchip_rk3588_otp_read, + .offset = 0x700, + .size = 0x100, + .block_size = 4, +}; + static const struct rockchip_otp_data rk3588_data = { .read = rockchip_rk3588_otp_read, .offset = 0xC00, @@ -384,10 +391,18 @@ static const struct udevice_id rockchip_otp_ids[] = { .data = (ulong)&px30_data, }, { + .compatible = "rockchip,rk3528-otp", + .data = (ulong)&rk3568_data, + }, + { .compatible = "rockchip,rk3568-otp", .data = (ulong)&rk3568_data, }, { + .compatible = "rockchip,rk3576-otp", + .data = (ulong)&rk3576_data, + }, + { .compatible = "rockchip,rk3588-otp", .data = (ulong)&rk3588_data, }, diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 9af84da1599..2f4dc5bd887 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -83,6 +83,19 @@ int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us) return dm_mmc_wait_dat0(mmc->dev, state, timeout_us); } +void dm_mmc_send_init_stream(struct udevice *dev) +{ + struct dm_mmc_ops *ops = mmc_get_ops(dev); + + if (ops->send_init_stream) + ops->send_init_stream(dev); +} + +void mmc_send_init_stream(struct mmc *mmc) +{ + dm_mmc_send_init_stream(mmc->dev); +} + static int dm_mmc_get_wp(struct udevice *dev) { struct dm_mmc_ops *ops = mmc_get_ops(dev); diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 47139e0a911..cdcf2e0c8fe 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1663,6 +1663,10 @@ static int mmc_execute_tuning(struct mmc *mmc, uint opcode) } #endif +static void mmc_send_init_stream(struct mmc *mmc) +{ +} + static int mmc_set_ios(struct mmc *mmc) { int ret = 0; @@ -2550,7 +2554,7 @@ static int mmc_startup(struct mmc *mmc) /* * For MMC cards, set the Relative Address. - * For SD cards, get the Relatvie Address. + * For SD cards, get the Relative Address. * This also puts the cards into Standby State */ if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ @@ -2929,6 +2933,8 @@ int mmc_get_op_cond(struct mmc *mmc, bool quiet) retry: mmc_set_initial_state(mmc); + mmc_send_init_stream(mmc); + /* Reset the Card */ err = mmc_go_idle(mmc); diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index e66ab25d02a..92bc72b267c 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -780,6 +780,14 @@ tuning_error: return ret; } #endif + +static void omap_hsmmc_send_init_stream(struct udevice *dev) +{ + struct omap_hsmmc_data *priv = dev_get_priv(dev); + struct hsmmc *mmc_base = priv->base_addr; + + mmc_init_stream(mmc_base); +} #endif static void mmc_enable_irq(struct mmc *mmc, struct mmc_cmd *cmd) @@ -1515,9 +1523,10 @@ static const struct dm_mmc_ops omap_hsmmc_ops = { .get_wp = omap_hsmmc_getwp, #endif #if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) - .execute_tuning = omap_hsmmc_execute_tuning, + .execute_tuning = omap_hsmmc_execute_tuning, #endif - .wait_dat0 = omap_hsmmc_wait_dat0, + .send_init_stream = omap_hsmmc_send_init_stream, + .wait_dat0 = omap_hsmmc_wait_dat0, }; #else static const struct mmc_ops omap_hsmmc_ops = { diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index 422b8f7e4c8..7a72abaa38a 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -171,6 +171,7 @@ static int rockchip_dwmmc_bind(struct udevice *dev) static const struct udevice_id rockchip_dwmmc_ids[] = { { .compatible = "rockchip,rk2928-dw-mshc" }, { .compatible = "rockchip,rk3288-dw-mshc" }, + { .compatible = "rockchip,rk3576-dw-mshc" }, { } }; diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index da630b9d97a..761e3619329 100644 --- 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 @@ -156,6 +160,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) @@ -323,6 +330,11 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab 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 | @@ -348,7 +360,7 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab 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 +372,7 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab 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 +392,7 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab */ 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); } @@ -647,6 +659,17 @@ static const struct sdhci_data rk3399_data = { .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, @@ -654,6 +677,20 @@ static const struct sdhci_data rk3568_data = { .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 rk3576_data = { + .set_ios_post = rk3568_sdhci_set_ios_post, + .set_clock = rk3568_sdhci_set_clock, + .config_dll = rk3568_sdhci_config_dll, + .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, + .hs400_txclk_tapnum = 0x7, + .hs400_cmdout_tapnum = 0x7, + .hs400_strbin_tapnum = 0x5, + .ddr50_strbin_delay_num = 0xa, }; static const struct sdhci_data rk3588_data = { @@ -662,6 +699,9 @@ static const struct sdhci_data rk3588_data = { .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[] = { @@ -670,10 +710,18 @@ 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, }, { + .compatible = "rockchip,rk3576-dwcmshc", + .data = (ulong)&rk3576_data, + }, + { .compatible = "rockchip,rk3588-dwcmshc", .data = (ulong)&rk3588_data, }, diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index a0a7890bd26..4434d364777 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -48,7 +48,6 @@ config DM_DSA bool "Enable Driver Model for DSA switches" depends on DM_MDIO depends on PHY_FIXED - depends on !NET_LWIP help Enable driver model for DSA switches @@ -358,7 +357,7 @@ config ESSEDMA config ETH_SANDBOX depends on SANDBOX - depends on NET + depends on NET || NET_LWIP default y bool "Sandbox: Mocked Ethernet driver" help @@ -367,17 +366,6 @@ config ETH_SANDBOX This driver is particularly useful in the test/dm/eth.c tests -config ETH_SANDBOX_LWIP - depends on SANDBOX - depends on NET_LWIP - default y - bool "Sandbox: Mocked Ethernet driver (for NET_LWIP)" - help - This driver is meant as a replacement for ETH_SANDBOX when - the network stack is NET_LWIP rather than NET. It currently - does nothing, i.e. it drops the sent packets and never receives - data. - config ETH_SANDBOX_RAW depends on SANDBOX depends on NET diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 3244d39036d..67bba3a8536 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -41,7 +41,6 @@ obj-$(CONFIG_ETH_DESIGNWARE_SOCFPGA) += dwmac_socfpga.o obj-$(CONFIG_ETH_SANDBOX) += sandbox.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw-bus.o obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o -obj-$(CONFIG_ETH_SANDBOX_LWIP) += sandbox-lwip.o obj-$(CONFIG_FEC_MXC) += fec_mxc.o obj-$(CONFIG_FMAN_ENET) += fm/ obj-$(CONFIG_FMAN_ENET) += fsl_mdio.o diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index b4ec3614696..b1bc422f791 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1612,10 +1612,18 @@ static const struct udevice_id eqos_ids[] = { #endif #if IS_ENABLED(CONFIG_DWC_ETH_QOS_ROCKCHIP) { + .compatible = "rockchip,rk3528-gmac", + .data = (ulong)&eqos_rockchip_config + }, + { .compatible = "rockchip,rk3568-gmac", .data = (ulong)&eqos_rockchip_config }, { + .compatible = "rockchip,rk3576-gmac", + .data = (ulong)&eqos_rockchip_config + }, + { .compatible = "rockchip,rk3588-gmac", .data = (ulong)&eqos_rockchip_config }, diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c index f3a0f63003e..d646d3ebac8 100644 --- a/drivers/net/dwc_eth_qos_rockchip.c +++ b/drivers/net/dwc_eth_qos_rockchip.c @@ -50,6 +50,132 @@ struct rockchip_platform_data { (((tx) ? soc##_GMAC_TXCLK_DLY_ENABLE : soc##_GMAC_TXCLK_DLY_DISABLE) | \ ((rx) ? soc##_GMAC_RXCLK_DLY_ENABLE : soc##_GMAC_RXCLK_DLY_DISABLE)) +#define RK3528_VO_GRF_GMAC_CON 0x0018 +#define RK3528_VPU_GRF_GMAC_CON5 0x0018 +#define RK3528_VPU_GRF_GMAC_CON6 0x001c + +#define RK3528_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) +#define RK3528_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) +#define RK3528_GMAC_TXCLK_DLY_ENABLE GRF_BIT(14) +#define RK3528_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(14) + +#define RK3528_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 8) +#define RK3528_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0xFF, 0) + +#define RK3528_GMAC0_PHY_INTF_SEL_RMII GRF_BIT(1) +#define RK3528_GMAC1_PHY_INTF_SEL_RGMII GRF_CLR_BIT(8) +#define RK3528_GMAC1_PHY_INTF_SEL_RMII GRF_BIT(8) + +#define RK3528_GMAC1_CLK_SELECT_CRU GRF_CLR_BIT(12) +#define RK3528_GMAC1_CLK_SELECT_IO GRF_BIT(12) + +#define RK3528_GMAC0_CLK_RMII_DIV2 GRF_BIT(3) +#define RK3528_GMAC0_CLK_RMII_DIV20 GRF_CLR_BIT(3) +#define RK3528_GMAC1_CLK_RMII_DIV2 GRF_BIT(10) +#define RK3528_GMAC1_CLK_RMII_DIV20 GRF_CLR_BIT(10) + +#define RK3528_GMAC1_CLK_RGMII_DIV1 (GRF_CLR_BIT(11) | GRF_CLR_BIT(10)) +#define RK3528_GMAC1_CLK_RGMII_DIV5 (GRF_BIT(11) | GRF_BIT(10)) +#define RK3528_GMAC1_CLK_RGMII_DIV50 (GRF_BIT(11) | GRF_CLR_BIT(10)) + +#define RK3528_GMAC0_CLK_RMII_GATE GRF_BIT(2) +#define RK3528_GMAC0_CLK_RMII_NOGATE GRF_CLR_BIT(2) +#define RK3528_GMAC1_CLK_RMII_GATE GRF_BIT(9) +#define RK3528_GMAC1_CLK_RMII_NOGATE GRF_CLR_BIT(9) + +static int rk3528_set_to_rgmii(struct udevice *dev, + int tx_delay, int rx_delay) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + + regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5, + RK3528_GMAC1_PHY_INTF_SEL_RGMII); + + regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5, + DELAY_ENABLE(RK3528, tx_delay, rx_delay)); + + regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON6, + RK3528_GMAC_CLK_RX_DL_CFG(rx_delay) | + RK3528_GMAC_CLK_TX_DL_CFG(tx_delay)); + + return 0; +} + +static int rk3528_set_to_rmii(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + + if (data->id == 1) + regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5, + RK3528_GMAC1_PHY_INTF_SEL_RMII); + else + regmap_write(data->grf, RK3528_VO_GRF_GMAC_CON, + RK3528_GMAC0_PHY_INTF_SEL_RMII | + RK3528_GMAC0_CLK_RMII_DIV2); + + return 0; +} + +static int rk3528_set_gmac_speed(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + u32 val, reg; + + switch (eqos->phy->speed) { + case SPEED_10: + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) + val = data->id == 1 ? RK3528_GMAC1_CLK_RMII_DIV20 : + RK3528_GMAC0_CLK_RMII_DIV20; + else + val = RK3528_GMAC1_CLK_RGMII_DIV50; + break; + case SPEED_100: + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) + val = data->id == 1 ? RK3528_GMAC1_CLK_RMII_DIV2 : + RK3528_GMAC0_CLK_RMII_DIV2; + else + val = RK3528_GMAC1_CLK_RGMII_DIV5; + break; + case SPEED_1000: + if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII) + val = RK3528_GMAC1_CLK_RGMII_DIV1; + else + return -EINVAL; + break; + default: + return -EINVAL; + } + + reg = data->id == 1 ? RK3528_VPU_GRF_GMAC_CON5 : + RK3528_VO_GRF_GMAC_CON; + regmap_write(data->grf, reg, val); + + return 0; +} + +static void rk3528_set_clock_selection(struct udevice *dev, bool enable) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + u32 val; + + if (data->id == 1) { + val = data->clock_input ? RK3528_GMAC1_CLK_SELECT_IO : + RK3528_GMAC1_CLK_SELECT_CRU; + val |= enable ? RK3528_GMAC1_CLK_RMII_NOGATE : + RK3528_GMAC1_CLK_RMII_GATE; + regmap_write(data->grf, RK3528_VPU_GRF_GMAC_CON5, val); + } else { + val = enable ? RK3528_GMAC0_CLK_RMII_NOGATE : + RK3528_GMAC0_CLK_RMII_GATE; + regmap_write(data->grf, RK3528_VO_GRF_GMAC_CON, val); + } +} + #define RK3568_GRF_GMAC0_CON0 0x0380 #define RK3568_GRF_GMAC0_CON1 0x0384 #define RK3568_GRF_GMAC1_CON0 0x0388 @@ -134,6 +260,145 @@ static int rk3568_set_gmac_speed(struct udevice *dev) return 0; } +/* VCCIO0_1_3_IOC */ +#define RK3576_VCCIO0_1_3_IOC_CON2 0x6408 +#define RK3576_VCCIO0_1_3_IOC_CON3 0x640c +#define RK3576_VCCIO0_1_3_IOC_CON4 0x6410 +#define RK3576_VCCIO0_1_3_IOC_CON5 0x6414 + +#define RK3576_GMAC_RXCLK_DLY_ENABLE GRF_BIT(15) +#define RK3576_GMAC_RXCLK_DLY_DISABLE GRF_CLR_BIT(15) +#define RK3576_GMAC_TXCLK_DLY_ENABLE GRF_BIT(7) +#define RK3576_GMAC_TXCLK_DLY_DISABLE GRF_CLR_BIT(7) + +#define RK3576_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8) +#define RK3576_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0) + +/* SDGMAC_GRF */ +#define RK3576_GRF_GMAC_CON0 0x0020 +#define RK3576_GRF_GMAC_CON1 0x0024 + +#define RK3576_GMAC_RMII_MODE GRF_BIT(3) +#define RK3576_GMAC_RGMII_MODE GRF_CLR_BIT(3) + +#define RK3576_GMAC_CLK_SELECT_IO GRF_BIT(7) +#define RK3576_GMAC_CLK_SELECT_CRU GRF_CLR_BIT(7) + +#define RK3576_GMAC_CLK_RMII_DIV2 GRF_BIT(5) +#define RK3576_GMAC_CLK_RMII_DIV20 GRF_CLR_BIT(5) + +#define RK3576_GMAC_CLK_RGMII_DIV1 \ + (GRF_CLR_BIT(6) | GRF_CLR_BIT(5)) +#define RK3576_GMAC_CLK_RGMII_DIV5 \ + (GRF_BIT(6) | GRF_BIT(5)) +#define RK3576_GMAC_CLK_RGMII_DIV50 \ + (GRF_BIT(6) | GRF_CLR_BIT(5)) + +#define RK3576_GMAC_CLK_RMII_GATE GRF_BIT(4) +#define RK3576_GMAC_CLK_RMII_NOGATE GRF_CLR_BIT(4) + +static int rk3576_set_to_rgmii(struct udevice *dev, + int tx_delay, int rx_delay) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + u32 offset_con; + + offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 : + RK3576_GRF_GMAC_CON0; + + regmap_write(data->grf, offset_con, RK3576_GMAC_RGMII_MODE); + + offset_con = data->id == 1 ? RK3576_VCCIO0_1_3_IOC_CON4 : + RK3576_VCCIO0_1_3_IOC_CON2; + + /* m0 && m1 delay enabled */ + regmap_write(data->php_grf, offset_con, + DELAY_ENABLE(RK3576, tx_delay, rx_delay)); + regmap_write(data->php_grf, offset_con + 0x4, + DELAY_ENABLE(RK3576, tx_delay, rx_delay)); + + /* m0 && m1 delay value */ + regmap_write(data->php_grf, offset_con, + RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) | + RK3576_GMAC_CLK_RX_DL_CFG(rx_delay)); + regmap_write(data->php_grf, offset_con + 0x4, + RK3576_GMAC_CLK_TX_DL_CFG(tx_delay) | + RK3576_GMAC_CLK_RX_DL_CFG(rx_delay)); + + return 0; +} + +static int rk3576_set_to_rmii(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + u32 offset_con; + + offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 : + RK3576_GRF_GMAC_CON0; + + regmap_write(data->grf, offset_con, RK3576_GMAC_RMII_MODE); + + return 0; +} + +static int rk3576_set_gmac_speed(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + u32 val = 0, offset_con; + + switch (eqos->phy->speed) { + case SPEED_10: + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) + val = RK3576_GMAC_CLK_RMII_DIV20; + else + val = RK3576_GMAC_CLK_RGMII_DIV50; + break; + case SPEED_100: + if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII) + val = RK3576_GMAC_CLK_RMII_DIV2; + else + val = RK3576_GMAC_CLK_RGMII_DIV5; + break; + case SPEED_1000: + if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII) + val = RK3576_GMAC_CLK_RGMII_DIV1; + else + return -EINVAL; + break; + default: + return -EINVAL; + } + + offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 : + RK3576_GRF_GMAC_CON0; + + regmap_write(data->grf, offset_con, val); + + return 0; +} + +static void rk3576_set_clock_selection(struct udevice *dev, bool enable) +{ + struct eth_pdata *pdata = dev_get_plat(dev); + struct rockchip_platform_data *data = pdata->priv_pdata; + + u32 val = data->clock_input ? RK3576_GMAC_CLK_SELECT_IO : + RK3576_GMAC_CLK_SELECT_CRU; + u32 offset_con; + + val |= enable ? RK3576_GMAC_CLK_RMII_NOGATE : + RK3576_GMAC_CLK_RMII_GATE; + + offset_con = data->id == 1 ? RK3576_GRF_GMAC_CON1 : + RK3576_GRF_GMAC_CON0; + + regmap_write(data->grf, offset_con, val); +} + #define RK3588_DELAY_ENABLE(id, tx, rx) \ (((tx) ? RK3588_GMAC_TXCLK_DLY_ENABLE(id) : RK3588_GMAC_TXCLK_DLY_DISABLE(id)) | \ ((rx) ? RK3588_GMAC_RXCLK_DLY_ENABLE(id) : RK3588_GMAC_RXCLK_DLY_DISABLE(id))) @@ -270,6 +535,18 @@ static void rk3588_set_clock_selection(struct udevice *dev, bool enable) static const struct rk_gmac_ops rk_gmac_ops[] = { { + .compatible = "rockchip,rk3528-gmac", + .set_to_rgmii = rk3528_set_to_rgmii, + .set_to_rmii = rk3528_set_to_rmii, + .set_gmac_speed = rk3528_set_gmac_speed, + .set_clock_selection = rk3528_set_clock_selection, + .regs = { + 0xffbd0000, /* gmac0 */ + 0xffbe0000, /* gmac1 */ + 0x0, /* sentinel */ + }, + }, + { .compatible = "rockchip,rk3568-gmac", .set_to_rgmii = rk3568_set_to_rgmii, .set_to_rmii = rk3568_set_to_rmii, @@ -281,6 +558,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = { }, }, { + .compatible = "rockchip,rk3576-gmac", + .set_to_rgmii = rk3576_set_to_rgmii, + .set_to_rmii = rk3576_set_to_rmii, + .set_gmac_speed = rk3576_set_gmac_speed, + .set_clock_selection = rk3576_set_clock_selection, + .regs = { + 0x2a220000, /* gmac0 */ + 0x2a230000, /* gmac1 */ + 0x0, /* sentinel */ + }, + }, + { .compatible = "rockchip,rk3588-gmac", .set_to_rgmii = rk3588_set_to_rgmii, .set_to_rmii = rk3588_set_to_rmii, @@ -357,7 +646,8 @@ static int eqos_probe_resources_rk(struct udevice *dev) goto err_free; } - if (device_is_compatible(dev, "rockchip,rk3588-gmac")) { + if (device_is_compatible(dev, "rockchip,rk3588-gmac") || + device_is_compatible(dev, "rockchip,rk3576-gmac")) { data->php_grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf"); if (IS_ERR(data->php_grf)) { diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 5b4cf30b0a3..3132718e4f8 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -79,40 +79,6 @@ config PHY_ADIN help Add support for configuring RGMII on Analog Devices ADIN PHYs. -menuconfig PHY_AIROHA - bool "Airoha Ethernet PHYs support" - -config PHY_AIROHA_EN8811H - bool "Airoha Ethernet EN8811H support" - depends on PHY_AIROHA - help - AIROHA EN8811H supported. - -choice - prompt "Location of the Airoha PHY firmware" - default PHY_AIROHA_FW_IN_MMC - depends on PHY_AIROHA_EN8811H - -config PHY_AIROHA_FW_IN_MMC - bool "Airoha firmware in MMC boot1 partition" - -endchoice - -config AIROHA_FW_ADDR - hex "Airoha Firmware Address" - depends on PHY_AIROHA_EN8811H - default 0x0 - -config AIROHA_MD32_DM_SIZE - hex "Airoha Firmware MD32 DM Size" - depends on PHY_AIROHA_EN8811H - default 0x4000 - -config AIROHA_MD32_DSP_SIZE - hex "Airoha Firmware MD32 DSP Size" - depends on PHY_AIROHA_EN8811H - default 0x20000 - menuconfig PHY_AQUANTIA bool "Aquantia Ethernet PHYs support" select PHY_GIGE diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 87dee3c15b9..2487f366e1c 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_MV88E6352_SWITCH) += mv88e6352.o obj-$(CONFIG_PHYLIB) += phy.o obj-$(CONFIG_PHYLIB_10G) += generic_10g.o obj-$(CONFIG_PHY_ADIN) += adin.o -obj-$(CONFIG_PHY_AIROHA_EN8811H) += air_en8811h.o obj-$(CONFIG_PHY_AQUANTIA) += aquantia.o obj-$(CONFIG_PHY_ATHEROS) += atheros.o obj-$(CONFIG_PHY_BROADCOM) += broadcom.o diff --git a/drivers/net/phy/air_en8811h.c b/drivers/net/phy/air_en8811h.c deleted file mode 100644 index 96bb24418a0..00000000000 --- a/drivers/net/phy/air_en8811h.c +++ /dev/null @@ -1,783 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Driver for the Airoha EN8811H 2.5 Gigabit PHY. - * - * Limitations of the EN8811H: - * - Only full duplex supported - * - Forced speed (AN off) is not supported by hardware (100Mbps) - * - * Source originated from linux air_en8811h.c - * - * Copyright (C) 2025 Airoha Technology Corp. - */ -#include <phy.h> -#include <errno.h> -#include <malloc.h> -#include <asm/unaligned.h> -#include <linux/iopoll.h> -#include <dm/device_compat.h> -#include <linux/bitops.h> -#include <mmc.h> - -#define EN8811H_PHY_ID 0x03a2a411 - -#define AIR_FW_ADDR_DM 0x00000000 -#define AIR_FW_ADDR_DSP 0x00100000 - -#define EN8811H_MD32_DM_SIZE 0x4000 -#define EN8811H_MD32_DSP_SIZE 0x20000 - - #define EN8811H_FW_CTRL_1 0x0f0018 - #define EN8811H_FW_CTRL_1_START 0x0 - #define EN8811H_FW_CTRL_1_FINISH 0x1 - #define EN8811H_FW_CTRL_2 0x800000 - #define EN8811H_FW_CTRL_2_LOADING BIT(11) - - /* MII Registers */ - #define AIR_AUX_CTRL_STATUS 0x1d - #define AIR_AUX_CTRL_STATUS_SPEED_MASK GENMASK(4, 2) - #define AIR_AUX_CTRL_STATUS_SPEED_100 0x4 - #define AIR_AUX_CTRL_STATUS_SPEED_1000 0x8 - #define AIR_AUX_CTRL_STATUS_SPEED_2500 0xc - -#define AIR_EXT_PAGE_ACCESS 0x1f -#define AIR_PHY_PAGE_STANDARD 0x0000 -#define AIR_PHY_PAGE_EXTENDED_4 0x0004 - -/* MII Registers Page 4*/ -#define AIR_BPBUS_MODE 0x10 -#define AIR_BPBUS_MODE_ADDR_FIXED 0x0000 -#define AIR_BPBUS_MODE_ADDR_INCR BIT(15) -#define AIR_BPBUS_WR_ADDR_HIGH 0x11 -#define AIR_BPBUS_WR_ADDR_LOW 0x12 -#define AIR_BPBUS_WR_DATA_HIGH 0x13 -#define AIR_BPBUS_WR_DATA_LOW 0x14 -#define AIR_BPBUS_RD_ADDR_HIGH 0x15 -#define AIR_BPBUS_RD_ADDR_LOW 0x16 -#define AIR_BPBUS_RD_DATA_HIGH 0x17 -#define AIR_BPBUS_RD_DATA_LOW 0x18 - -/* Registers on MDIO_MMD_VEND1 */ -#define EN8811H_PHY_FW_STATUS 0x8009 -#define EN8811H_PHY_READY 0x02 - -/* Registers on MDIO_MMD_VEND2 */ -#define AIR_PHY_LED_BCR 0x021 -#define AIR_PHY_LED_BCR_MODE_MASK GENMASK(1, 0) -#define AIR_PHY_LED_BCR_TIME_TEST BIT(2) -#define AIR_PHY_LED_BCR_CLK_EN BIT(3) -#define AIR_PHY_LED_BCR_EXT_CTRL BIT(15) - -#define AIR_PHY_LED_DUR_ON 0x022 - -#define AIR_PHY_LED_DUR_BLINK 0x023 - -#define AIR_PHY_LED_ON(i) (0x024 + ((i) * 2)) -#define AIR_PHY_LED_ON_MASK (GENMASK(6, 0) | BIT(8)) -#define AIR_PHY_LED_ON_LINK1000 BIT(0) -#define AIR_PHY_LED_ON_LINK100 BIT(1) -#define AIR_PHY_LED_ON_LINK10 BIT(2) -#define AIR_PHY_LED_ON_LINKDOWN BIT(3) -#define AIR_PHY_LED_ON_FDX BIT(4) /* Full duplex */ -#define AIR_PHY_LED_ON_HDX BIT(5) /* Half duplex */ -#define AIR_PHY_LED_ON_FORCE_ON BIT(6) -#define AIR_PHY_LED_ON_LINK2500 BIT(8) -#define AIR_PHY_LED_ON_POLARITY BIT(14) -#define AIR_PHY_LED_ON_ENABLE BIT(15) - -#define AIR_PHY_LED_BLINK(i) (0x025 + ((i) * 2)) -#define AIR_PHY_LED_BLINK_1000TX BIT(0) -#define AIR_PHY_LED_BLINK_1000RX BIT(1) -#define AIR_PHY_LED_BLINK_100TX BIT(2) -#define AIR_PHY_LED_BLINK_100RX BIT(3) -#define AIR_PHY_LED_BLINK_10TX BIT(4) -#define AIR_PHY_LED_BLINK_10RX BIT(5) -#define AIR_PHY_LED_BLINK_COLLISION BIT(6) -#define AIR_PHY_LED_BLINK_RX_CRC_ERR BIT(7) -#define AIR_PHY_LED_BLINK_RX_IDLE_ERR BIT(8) -#define AIR_PHY_LED_BLINK_FORCE_BLINK BIT(9) -#define AIR_PHY_LED_BLINK_2500TX BIT(10) -#define AIR_PHY_LED_BLINK_2500RX BIT(11) - -#define EN8811H_FW_VERSION 0x3b3c - -#define EN8811H_POLARITY 0xca0f8 -#define EN8811H_POLARITY_TX_NORMAL BIT(0) -#define EN8811H_POLARITY_RX_REVERSE BIT(1) - -#define EN8811H_CLK_CGM 0xcf958 -#define EN8811H_CLK_CGM_CKO BIT(26) -#define EN8811H_HWTRAP1 0xcf914 -#define EN8811H_HWTRAP1_CKO BIT(12) - -#define air_upper_16_bits(n) ((u16)((n) >> 16)) -#define air_lower_16_bits(n) ((u16)((n) & 0xffff)) - -/* Led definitions */ -#define EN8811H_LED_COUNT 3 - -/* Default LED setup: - * GPIO5 <-> LED0 On: Link detected - * GPIO4 <-> LED1 On: Link detected at 2500 and 1000 Mbps - * GPIO3 <-> LED2 On: Link detected at 2500 and 100 Mbps - */ -#define AIR_DEFAULT_TRIGGER_LED0 (AIR_PHY_LED_ON_LINK2500 | \ - AIR_PHY_LED_ON_LINK1000 | \ - AIR_PHY_LED_ON_LINK100) -#define AIR_DEFAULT_TRIGGER_LED1 (AIR_PHY_LED_ON_LINK2500 | \ - AIR_PHY_LED_ON_LINK1000 | \ - AIR_PHY_LED_BLINK_2500TX | \ - AIR_PHY_LED_BLINK_2500RX | \ - AIR_PHY_LED_BLINK_1000TX | \ - AIR_PHY_LED_BLINK_1000RX) -#define AIR_DEFAULT_TRIGGER_LED2 (AIR_PHY_LED_ON_LINK2500 | \ - AIR_PHY_LED_ON_LINK100 | \ - AIR_PHY_LED_BLINK_2500TX | \ - AIR_PHY_LED_BLINK_2500RX | \ - AIR_PHY_LED_BLINK_100TX | \ - AIR_PHY_LED_BLINK_100RX) - -struct led { - unsigned long rules; -}; - -enum { - AIR_PHY_LED_DUR_BLINK_32MS, - AIR_PHY_LED_DUR_BLINK_64MS, - AIR_PHY_LED_DUR_BLINK_128MS, - AIR_PHY_LED_DUR_BLINK_256MS, - AIR_PHY_LED_DUR_BLINK_512MS, - AIR_PHY_LED_DUR_BLINK_1024MS, -}; - -enum { - AIR_LED_DISABLE, - AIR_LED_ENABLE, -}; - -enum { - AIR_ACTIVE_LOW, - AIR_ACTIVE_HIGH, -}; - -enum { - AIR_LED_MODE_DISABLE, - AIR_LED_MODE_USER_DEFINE, -}; - -#define AIR_PHY_LED_DUR_UNIT 781 -#define AIR_PHY_LED_DUR (AIR_PHY_LED_DUR_UNIT << AIR_PHY_LED_DUR_BLINK_64MS) - -struct en8811h_priv { - int firmware_version; - bool mcu_needs_restart; - struct led led[EN8811H_LED_COUNT]; -}; - -static int air_phy_read_page(struct phy_device *phydev) -{ - return phy_read(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS); -} - -static int air_phy_write_page(struct phy_device *phydev, int page) -{ - return phy_write(phydev, MDIO_DEVAD_NONE, AIR_EXT_PAGE_ACCESS, page); -} - -int air_phy_select_page(struct phy_device *phydev, int page) -{ - int ret, oldpage; - - oldpage = air_phy_read_page(phydev); - if (oldpage < 0) - return oldpage; - - if (oldpage != page) { - ret = air_phy_write_page(phydev, page); - if (ret < 0) - return ret; - } - - return oldpage; -} - -int air_phy_restore_page(struct phy_device *phydev, int oldpage, int ret) -{ - int r; - - if (oldpage >= 0) { - r = air_phy_write_page(phydev, oldpage); - - if (ret >= 0 && r < 0) - ret = r; - } else { - ret = oldpage; - } - - return ret; -} - -static int air_buckpbus_reg_write(struct phy_device *phydev, - u32 pbus_address, u32 pbus_data) -{ - int ret, saved_page; - - saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); - - if (saved_page >= 0) { - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH, - air_upper_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW, - air_lower_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH, - air_upper_16_bits(pbus_data)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW, - air_lower_16_bits(pbus_data)); - if (ret < 0) - goto restore_page; - } - -restore_page: - if (ret < 0) - printf("%s 0x%08x failed: %d\n", __func__, - pbus_address, ret); - - return air_phy_restore_page(phydev, saved_page, ret); -} - -static int air_buckpbus_reg_read(struct phy_device *phydev, - u32 pbus_address, u32 *pbus_data) -{ - int pbus_data_low, pbus_data_high; - int ret = 0, saved_page; - - saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); - - if (saved_page >= 0) { - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH, - air_upper_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW, - air_lower_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH); - if (pbus_data_high < 0) { - ret = pbus_data_high; - goto restore_page; - } - - pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW); - if (pbus_data_low < 0) { - ret = pbus_data_low; - goto restore_page; - } - - *pbus_data = pbus_data_low | (pbus_data_high << 16); - } - -restore_page: - if (ret < 0) - printf("%s 0x%08x failed: %d\n", __func__, - pbus_address, ret); - - return air_phy_restore_page(phydev, saved_page, ret); -} - -static int air_buckpbus_reg_modify(struct phy_device *phydev, - u32 pbus_address, u32 mask, u32 set) -{ - int pbus_data_low, pbus_data_high; - u32 pbus_data_old, pbus_data_new; - int ret = 0, saved_page; - - saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); - - if (saved_page >= 0) { - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_FIXED); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_HIGH, - air_upper_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_ADDR_LOW, - air_lower_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - pbus_data_high = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_HIGH); - if (pbus_data_high < 0) - return pbus_data_high; - - pbus_data_low = phy_read(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_RD_DATA_LOW); - if (pbus_data_low < 0) - return pbus_data_low; - - pbus_data_old = pbus_data_low | (pbus_data_high << 16); - pbus_data_new = (pbus_data_old & ~mask) | set; - if (pbus_data_new == pbus_data_old) - return 0; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH, - air_upper_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW, - air_lower_16_bits(pbus_address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH, - air_upper_16_bits(pbus_data_new)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW, - air_lower_16_bits(pbus_data_new)); - if (ret < 0) - goto restore_page; - } - -restore_page: - if (ret < 0) - printf("%s 0x%08x failed: %d\n", __func__, - pbus_address, ret); - - return air_phy_restore_page(phydev, saved_page, ret); -} - -static int air_write_buf(struct phy_device *phydev, unsigned long address, - unsigned long array_size, const unsigned char *buffer) -{ - unsigned int offset; - int ret, saved_page; - u16 val; - - saved_page = air_phy_select_page(phydev, AIR_PHY_PAGE_EXTENDED_4); - - if (saved_page >= 0) { - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_MODE, AIR_BPBUS_MODE_ADDR_INCR); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_HIGH, - air_upper_16_bits(address)); - if (ret < 0) - goto restore_page; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_ADDR_LOW, - air_lower_16_bits(address)); - if (ret < 0) - goto restore_page; - - for (offset = 0; offset < array_size; offset += 4) { - val = get_unaligned_le16(&buffer[offset + 2]); - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_HIGH, val); - if (ret < 0) - goto restore_page; - - val = get_unaligned_le16(&buffer[offset]); - ret = phy_write(phydev, MDIO_DEVAD_NONE, AIR_BPBUS_WR_DATA_LOW, val); - if (ret < 0) - goto restore_page; - } - } - -restore_page: - if (ret < 0) - printf("%s 0x%08lx failed: %d\n", __func__, - address, ret); - - return air_phy_restore_page(phydev, saved_page, ret); -} - -__weak ulong *en8811h_get_fw_addr(void) -{ - return (ulong *)CONFIG_AIROHA_FW_ADDR; -} - -static int en8811h_wait_mcu_ready(struct phy_device *phydev) -{ - int ret, reg_value; - - /* Because of mdio-lock, may have to wait for multiple loads */ - ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1, - EN8811H_PHY_FW_STATUS, reg_value, - reg_value == EN8811H_PHY_READY, - 20000, 7500000, true); - if (ret) { - printf("MCU not ready: 0x%x\n", reg_value); - return -ENODEV; - } - - return 0; -} - -static int en8811h_load_firmware(struct phy_device *phydev) -{ - int ret; - char *addr = NULL; - struct en8811h_priv *priv = phydev->priv; - int dev = CONFIG_SYS_MMC_ENV_DEV; - u32 cnt = (CONFIG_AIROHA_MD32_DM_SIZE + - CONFIG_AIROHA_MD32_DSP_SIZE) / 512; - ulong airoha_fw_addr = (ulong)en8811h_get_fw_addr(); - u32 blk = airoha_fw_addr / 512; - - addr = malloc(CONFIG_AIROHA_MD32_DM_SIZE + CONFIG_AIROHA_MD32_DSP_SIZE); - if (!addr) { - puts("cannot allocated buffer for firmware.\n"); - return -ENOMEM; - } - - if (IS_ENABLED(CONFIG_PHY_AIROHA_FW_IN_MMC)) { - struct mmc *mmc = find_mmc_device(dev); - - if (!mmc) { - puts("Failed to find MMC device for Airoha ucode\n"); - goto en8811h_load_firmware_out; - } - - printf("MMC read: dev # %u, block # %u, count %u ...\n", - dev, blk, cnt); - - if (mmc_init(mmc)) { - puts("initializing MMC device failed.\n"); - goto en8811h_load_firmware_out; - } - - ret = mmc_set_part_conf(mmc, 1, 2, 2); - if (ret) { - puts("cannot access eMMC boot1 hw partition.\n"); - goto en8811h_load_firmware_out; - } - - (void)blk_dread(mmc_get_blk_desc(mmc), blk, cnt, addr); - - mmc_set_part_conf(mmc, 1, 1, 0); - - } else { - puts("EN8811H firmware loading not implemented"); - free(addr); - addr = NULL; - return -EOPNOTSUPP; - } - - ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, - EN8811H_FW_CTRL_1_START); - if (ret < 0) - return ret; - - ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2, - EN8811H_FW_CTRL_2_LOADING, - EN8811H_FW_CTRL_2_LOADING); - if (ret < 0) - return ret; - - ret = air_write_buf(phydev, AIR_FW_ADDR_DM, CONFIG_AIROHA_MD32_DM_SIZE, addr); - if (ret < 0) - goto en8811h_load_firmware_out; - - ret = air_write_buf(phydev, AIR_FW_ADDR_DSP, CONFIG_AIROHA_MD32_DSP_SIZE, - addr + CONFIG_AIROHA_MD32_DM_SIZE); - if (ret < 0) - goto en8811h_load_firmware_out; - - ret = air_buckpbus_reg_modify(phydev, EN8811H_FW_CTRL_2, - EN8811H_FW_CTRL_2_LOADING, 0); - if (ret < 0) - return ret; - - ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, - EN8811H_FW_CTRL_1_FINISH); - if (ret < 0) - return ret; - - ret = en8811h_wait_mcu_ready(phydev); - - air_buckpbus_reg_read(phydev, EN8811H_FW_VERSION, - &priv->firmware_version); - printf("MD32 firmware version: %08x\n", - priv->firmware_version); - -en8811h_load_firmware_out: - free(addr); - if (ret < 0) - printf("Firmware loading failed: %d\n", ret); - - return ret; -} - -static int en8811h_restart_mcu(struct phy_device *phydev) -{ - int ret; - - ret = phy_write_mmd(phydev, 0x1e, 0x8009, 0x0); - if (ret < 0) - return ret; - - ret = air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, - EN8811H_FW_CTRL_1_START); - if (ret < 0) - return ret; - - return air_buckpbus_reg_write(phydev, EN8811H_FW_CTRL_1, - EN8811H_FW_CTRL_1_FINISH); -} - -static int air_led_hw_control_set(struct phy_device *phydev, - u8 index, unsigned long rules) -{ - struct en8811h_priv *priv = phydev->priv; - u16 on = 0, blink = 0; - int ret; - - if (index >= EN8811H_LED_COUNT) - return -EINVAL; - - on |= rules & (AIR_PHY_LED_ON_LINK100 | - AIR_PHY_LED_ON_LINK1000 | - AIR_PHY_LED_ON_LINK2500); - - blink |= rules & (AIR_PHY_LED_BLINK_100TX | - AIR_PHY_LED_BLINK_100RX | - AIR_PHY_LED_BLINK_1000TX | - AIR_PHY_LED_BLINK_1000RX | - AIR_PHY_LED_BLINK_2500TX | - AIR_PHY_LED_BLINK_2500RX); - - if (blink || on) { - on &= ~AIR_PHY_LED_ON_FORCE_ON; - blink &= ~AIR_PHY_LED_BLINK_FORCE_BLINK; - } else { - priv->led[index].rules = 0; - } - - ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_ON(index), - AIR_PHY_LED_ON_MASK, on); - if (ret < 0) - return ret; - - return phy_write_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BLINK(index), - blink); -} - -static int air_led_init(struct phy_device *phydev, u8 index, u8 state, u8 pol) -{ - int val = 0; - int err; - - if (index >= EN8811H_LED_COUNT) - return -EINVAL; - - if (state == AIR_LED_ENABLE) - val |= AIR_PHY_LED_ON_ENABLE; - else - val &= ~AIR_PHY_LED_ON_ENABLE; - - if (pol == AIR_ACTIVE_HIGH) - val |= AIR_PHY_LED_ON_POLARITY; - else - val &= ~AIR_PHY_LED_ON_POLARITY; - - err = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_ON(index), val); - if (err < 0) - return err; - - return 0; -} - -static int air_leds_init(struct phy_device *phydev, int num, int dur, int mode) -{ - int ret, i; - struct en8811h_priv *priv = phydev->priv; - - ret = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_DUR_BLINK, dur); - if (ret < 0) - return ret; - - ret = phy_write_mmd(phydev, 0x1f, AIR_PHY_LED_DUR_ON, dur >> 1); - if (ret < 0) - return ret; - - switch (mode) { - case AIR_LED_MODE_DISABLE: - ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, - AIR_PHY_LED_BCR_EXT_CTRL | - AIR_PHY_LED_BCR_MODE_MASK, 0); - break; - case AIR_LED_MODE_USER_DEFINE: - ret = phy_modify_mmd(phydev, MDIO_MMD_VEND2, AIR_PHY_LED_BCR, - AIR_PHY_LED_BCR_EXT_CTRL | - AIR_PHY_LED_BCR_CLK_EN, - AIR_PHY_LED_BCR_EXT_CTRL | - AIR_PHY_LED_BCR_CLK_EN); - if (ret < 0) - return ret; - break; - default: - printf("LED mode %d is not supported\n", mode); - return -EINVAL; - } - - for (i = 0; i < num; ++i) { - ret = air_led_init(phydev, i, AIR_LED_ENABLE, AIR_ACTIVE_HIGH); - if (ret < 0) { - printf("LED%d init failed: %d\n", i, ret); - return ret; - } - air_led_hw_control_set(phydev, i, priv->led[i].rules); - } - - return 0; -} - -static int en8811h_config(struct phy_device *phydev) -{ - ofnode node = phy_get_ofnode(phydev); - struct en8811h_priv *priv = phydev->priv; - int ret = 0; - u32 pbus_value = 0; - - /* If restart happened in .probe(), no need to restart now */ - if (priv->mcu_needs_restart) { - ret = en8811h_restart_mcu(phydev); - if (ret < 0) - return ret; - } else { - ret = en8811h_load_firmware(phydev); - if (ret) { - printf("Load firmware fail.\n"); - return ret; - } - /* Next calls to .config() mcu needs to restart */ - priv->mcu_needs_restart = true; - } - - ret = phy_write_mmd(phydev, 0x1e, 0x800c, 0x0); - ret |= phy_write_mmd(phydev, 0x1e, 0x800d, 0x0); - ret |= phy_write_mmd(phydev, 0x1e, 0x800e, 0x1101); - ret |= phy_write_mmd(phydev, 0x1e, 0x800f, 0x0002); - if (ret < 0) - return ret; - - /* Serdes polarity */ - pbus_value = 0; - if (ofnode_read_bool(node, "airoha,pnswap-rx")) - pbus_value |= EN8811H_POLARITY_RX_REVERSE; - else - pbus_value &= ~EN8811H_POLARITY_RX_REVERSE; - if (ofnode_read_bool(node, "airoha,pnswap-tx")) - pbus_value &= ~EN8811H_POLARITY_TX_NORMAL; - else - pbus_value |= EN8811H_POLARITY_TX_NORMAL; - ret = air_buckpbus_reg_modify(phydev, EN8811H_POLARITY, - EN8811H_POLARITY_RX_REVERSE | - EN8811H_POLARITY_TX_NORMAL, pbus_value); - if (ret < 0) - return ret; - - ret = air_leds_init(phydev, EN8811H_LED_COUNT, AIR_PHY_LED_DUR, - AIR_LED_MODE_USER_DEFINE); - if (ret < 0) { - printf("Failed to disable leds: %d\n", ret); - return ret; - } - - return 0; -} - -static int en8811h_parse_status(struct phy_device *phydev) -{ - int ret = 0, reg_value; - - phydev->duplex = DUPLEX_FULL; - - reg_value = phy_read(phydev, MDIO_DEVAD_NONE, AIR_AUX_CTRL_STATUS); - if (reg_value < 0) - return reg_value; - - switch (reg_value & AIR_AUX_CTRL_STATUS_SPEED_MASK) { - case AIR_AUX_CTRL_STATUS_SPEED_2500: - phydev->speed = SPEED_2500; - break; - case AIR_AUX_CTRL_STATUS_SPEED_1000: - phydev->speed = SPEED_1000; - break; - case AIR_AUX_CTRL_STATUS_SPEED_100: - phydev->speed = SPEED_100; - break; - default: - printf("Auto-neg error, defaulting to 100M/FD\n"); - phydev->speed = SPEED_100; - break; - } - - return ret; -} - -static int en8811h_startup(struct phy_device *phydev) -{ - int ret = 0; - - ret = genphy_update_link(phydev); - if (ret) - return ret; - - return en8811h_parse_status(phydev); -} - -static int en8811h_probe(struct phy_device *phydev) -{ - struct en8811h_priv *priv; - - priv = malloc(sizeof(*priv)); - if (!priv) - return -ENOMEM; - memset(priv, 0, sizeof(*priv)); - - priv->led[0].rules = AIR_DEFAULT_TRIGGER_LED0; - priv->led[1].rules = AIR_DEFAULT_TRIGGER_LED1; - priv->led[2].rules = AIR_DEFAULT_TRIGGER_LED2; - - /* mcu has just restarted after firmware load */ - priv->mcu_needs_restart = false; - - phydev->priv = priv; - - return 0; -} - -U_BOOT_PHY_DRIVER(en8811h) = { - .name = "Airoha EN8811H", - .uid = EN8811H_PHY_ID, - .mask = 0x0ffffff0, - .config = &en8811h_config, - .probe = &en8811h_probe, - .startup = &en8811h_startup, - .shutdown = &genphy_shutdown, -}; diff --git a/drivers/net/sandbox-lwip.c b/drivers/net/sandbox-lwip.c deleted file mode 100644 index 3721033c310..00000000000 --- a/drivers/net/sandbox-lwip.c +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Copyright (c) 2015 National Instruments - * - * (C) Copyright 2015 - * Joe Hershberger <joe.hershberger@ni.com> - */ - -#include <dm.h> -#include <log.h> -#include <malloc.h> -#include <net.h> -#include <asm/eth.h> -#include <asm/global_data.h> -#include <asm/test.h> - -DECLARE_GLOBAL_DATA_PTR; - -static int sb_lwip_eth_start(struct udevice *dev) -{ - debug("eth_sandbox_lwip: Start\n"); - - return 0; -} - -static int sb_lwip_eth_send(struct udevice *dev, void *packet, int length) -{ - debug("eth_sandbox_lwip: Send packet %d\n", length); - - return -ENOTSUPP; -} - -static int sb_lwip_eth_recv(struct udevice *dev, int flags, uchar **packetp) -{ - return -EAGAIN; -} - -static int sb_lwip_eth_free_pkt(struct udevice *dev, uchar *packet, int length) -{ - return 0; -} - -static void sb_lwip_eth_stop(struct udevice *dev) -{ -} - -static int sb_lwip_eth_write_hwaddr(struct udevice *dev) -{ - return 0; -} - -static const struct eth_ops sb_eth_ops = { - .start = sb_lwip_eth_start, - .send = sb_lwip_eth_send, - .recv = sb_lwip_eth_recv, - .free_pkt = sb_lwip_eth_free_pkt, - .stop = sb_lwip_eth_stop, - .write_hwaddr = sb_lwip_eth_write_hwaddr, -}; - -static int sb_lwip_eth_remove(struct udevice *dev) -{ - return 0; -} - -static int sb_lwip_eth_of_to_plat(struct udevice *dev) -{ - return 0; -} - -static const struct udevice_id sb_eth_ids[] = { - { .compatible = "sandbox,eth" }, - { } -}; - -U_BOOT_DRIVER(eth_sandbox) = { - .name = "eth_lwip_sandbox", - .id = UCLASS_ETH, - .of_match = sb_eth_ids, - .of_to_plat = sb_lwip_eth_of_to_plat, - .remove = sb_lwip_eth_remove, - .ops = &sb_eth_ops, - .priv_auto = 0, - .plat_auto = sizeof(struct eth_pdata), -}; diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c index fe3627db6e3..2011fd31f41 100644 --- a/drivers/net/sandbox.c +++ b/drivers/net/sandbox.c @@ -9,13 +9,84 @@ #include <dm.h> #include <log.h> #include <malloc.h> -#include <net.h> #include <asm/eth.h> #include <asm/global_data.h> #include <asm/test.h> +#include <asm/types.h> + +/* + * Structure definitions for network protocols. Since this file is used for + * both NET and NET_LWIP, and given that the two network stacks do have + * conflicting types (for instance struct icmp_hdr), it is on purpose that the + * structures are defined locally with minimal dependencies -- <asm/types.h> is + * included for the bit types and that's it. + */ + +#define ETHADDR_LEN 6 +#define IP4_LEN 4 + +struct ethhdr { + u8 dst[ETHADDR_LEN]; + u8 src[ETHADDR_LEN]; + u16 protlen; +} __attribute__((packed)); + +#define ETHHDR_SIZE (sizeof(struct ethhdr)) + +struct arphdr { + u16 htype; + u16 ptype; + u8 hlen; + u8 plen; + u16 op; +} __attribute__((packed)); + +#define ARPHDR_SIZE (sizeof(struct arphdr)) + +#define ARP_REQUEST 1 +#define ARP_REPLY 2 + +struct arpdata { + u8 sha[ETHADDR_LEN]; + u32 spa; + u8 tha[ETHADDR_LEN]; + u32 tpa; +} __attribute__((packed)); + +#define ARPDATA_SIZE (sizeof(struct arpdata)) + +struct iphdr { + u8 hl_v; + u8 tos; + u16 len; + u16 id; + u16 off; + u8 ttl; + u8 prot; + u16 sum; + u32 src; + u32 dst; +} __attribute__((packed)); + +#define IPHDR_SIZE (sizeof(struct iphdr)) + +struct icmphdr { + u8 type; + u8 code; + u16 checksum; + u16 id; + u16 sequence; +} __attribute__((packed)); + +#define ICMPHDR_SIZE (sizeof(struct icmphdr)) + +#define ICMP_ECHO_REQUEST 8 +#define ICMP_ECHO_REPLY 0 +#define IPPROTO_ICMP 1 DECLARE_GLOBAL_DATA_PTR; +static const u8 null_ethaddr[6]; static bool skip_timeout; /* @@ -59,17 +130,19 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet, unsigned int len) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth = packet; - struct arp_hdr *arp; - struct ethernet_hdr *eth_recv; - struct arp_hdr *arp_recv; - - if (ntohs(eth->et_protlen) != PROT_ARP) + struct ethhdr *eth = packet; + struct arphdr *arp; + struct arpdata *arpd; + struct ethhdr *eth_recv; + struct arphdr *arp_recv; + struct arpdata *arp_recvd; + + if (ntohs(eth->protlen) != PROT_ARP) return -EAGAIN; - arp = packet + ETHER_HDR_SIZE; + arp = packet + ETHHDR_SIZE; - if (ntohs(arp->ar_op) != ARPOP_REQUEST) + if (ntohs(arp->op) != ARP_REQUEST) return -EAGAIN; /* Don't allow the buffer to overrun */ @@ -77,27 +150,29 @@ int sandbox_eth_arp_req_to_reply(struct udevice *dev, void *packet, return 0; /* store this as the assumed IP of the fake host */ - priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa); + arpd = (struct arpdata *)(arp + 1); + priv->fake_host_ipaddr.s_addr = arpd->tpa; /* Formulate a fake response */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_ARP); - - arp_recv = (void *)eth_recv + ETHER_HDR_SIZE; - arp_recv->ar_hrd = htons(ARP_ETHER); - arp_recv->ar_pro = htons(PROT_IP); - arp_recv->ar_hln = ARP_HLEN; - arp_recv->ar_pln = ARP_PLEN; - arp_recv->ar_op = htons(ARPOP_REPLY); - memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); - memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN); - net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa); - - priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + ARP_HDR_SIZE; + memcpy(eth_recv->dst, eth->src, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_ARP); + + arp_recv = (void *)eth_recv + ETHHDR_SIZE; + arp_recv->htype = htons(ARP_ETHER); + arp_recv->ptype = htons(PROT_IP); + arp_recv->hlen = ETHADDR_LEN; + arp_recv->plen = IP4_LEN; + arp_recv->op = htons(ARP_REPLY); + arp_recvd = (struct arpdata *)(arp_recv + 1); + memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN); + arp_recvd->spa = priv->fake_host_ipaddr.s_addr; + memcpy(&arp_recvd->tha, &arpd->sha, ETHADDR_LEN); + arp_recvd->tpa = arpd->spa; + + priv->recv_packet_length[priv->recv_packets] = ETHHDR_SIZE + + ARPHDR_SIZE + ARPDATA_SIZE; ++priv->recv_packets; return 0; @@ -114,22 +189,22 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, unsigned int len) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth = packet; - struct ip_udp_hdr *ip; - struct icmp_hdr *icmp; - struct ethernet_hdr *eth_recv; - struct ip_udp_hdr *ipr; - struct icmp_hdr *icmpr; - - if (ntohs(eth->et_protlen) != PROT_IP) + struct ethhdr *eth = packet; + struct iphdr *ip; + struct icmphdr *icmp; + struct ethhdr *eth_recv; + struct iphdr *ipr; + struct icmphdr *icmpr; + + if (ntohs(eth->protlen) != PROT_IP) return -EAGAIN; - ip = packet + ETHER_HDR_SIZE; + ip = packet + ETHHDR_SIZE; - if (ip->ip_p != IPPROTO_ICMP) + if (ip->prot != IPPROTO_ICMP) return -EAGAIN; - icmp = (struct icmp_hdr *)&ip->udp_src; + icmp = (struct icmphdr *)(ip + 1); if (icmp->type != ICMP_ECHO_REQUEST) return -EAGAIN; @@ -141,19 +216,19 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, /* reply to the ping */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; memcpy(eth_recv, packet, len); - ipr = (void *)eth_recv + ETHER_HDR_SIZE; - icmpr = (struct icmp_hdr *)&ipr->udp_src; - memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - ipr->ip_sum = 0; - ipr->ip_off = 0; - net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src); - net_write_ip((void *)&ipr->ip_src, priv->fake_host_ipaddr); - ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + ipr = (void *)eth_recv + ETHHDR_SIZE; + icmpr = (struct icmphdr *)(ipr + 1); + memcpy(eth_recv->dst, eth->src, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + ipr->sum = 0; + ipr->off = 0; + ipr->dst = ip->src; + ipr->src = priv->fake_host_ipaddr.s_addr; + ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE); icmpr->type = ICMP_ECHO_REPLY; icmpr->checksum = 0; - icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE); priv->recv_packet_length[priv->recv_packets] = len; ++priv->recv_packets; @@ -171,8 +246,9 @@ int sandbox_eth_ping_req_to_reply(struct udevice *dev, void *packet, int sandbox_eth_recv_arp_req(struct udevice *dev) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth_recv; - struct arp_hdr *arp_recv; + struct ethhdr *eth_recv; + struct arphdr *arp_recv; + struct arpdata *arp_recvd; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -180,23 +256,24 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) /* Formulate a fake request */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, net_bcast_ethaddr, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_ARP); - - arp_recv = (void *)eth_recv + ETHER_HDR_SIZE; - arp_recv->ar_hrd = htons(ARP_ETHER); - arp_recv->ar_pro = htons(PROT_IP); - arp_recv->ar_hln = ARP_HLEN; - arp_recv->ar_pln = ARP_PLEN; - arp_recv->ar_op = htons(ARPOP_REQUEST); - memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr); - memcpy(&arp_recv->ar_tha, net_null_ethaddr, ARP_HLEN); - net_write_ip(&arp_recv->ar_tpa, net_ip); + memcpy(eth_recv->dst, net_bcast_ethaddr, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_ARP); + + arp_recv = (void *)eth_recv + ETHHDR_SIZE; + arp_recv->htype = htons(ARP_ETHER); + arp_recv->ptype = htons(PROT_IP); + arp_recv->hlen = ETHADDR_LEN; + arp_recv->plen = IP4_LEN; + arp_recv->op = htons(ARP_REQUEST); + arp_recvd = (struct arpdata *)(arp_recv + 1); + memcpy(&arp_recvd->sha, priv->fake_host_hwaddr, ETHADDR_LEN); + arp_recvd->spa = priv->fake_host_ipaddr.s_addr; + memcpy(&arp_recvd->tha, null_ethaddr, ETHADDR_LEN); + arp_recvd->tpa = net_ip.s_addr; priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + ARP_HDR_SIZE; + ETHHDR_SIZE + ARPHDR_SIZE + ARPDATA_SIZE; ++priv->recv_packets; return 0; @@ -212,9 +289,10 @@ int sandbox_eth_recv_arp_req(struct udevice *dev) int sandbox_eth_recv_ping_req(struct udevice *dev) { struct eth_sandbox_priv *priv = dev_get_priv(dev); - struct ethernet_hdr *eth_recv; - struct ip_udp_hdr *ipr; - struct icmp_hdr *icmpr; + struct eth_pdata *pdata = dev_get_plat(dev); + struct ethhdr *eth_recv; + struct iphdr *ipr; + struct icmphdr *icmpr; /* Don't allow the buffer to overrun */ if (priv->recv_packets >= PKTBUFSRX) @@ -223,31 +301,31 @@ int sandbox_eth_recv_ping_req(struct udevice *dev) /* Formulate a fake ping */ eth_recv = (void *)priv->recv_packet_buffer[priv->recv_packets]; - memcpy(eth_recv->et_dest, net_ethaddr, ARP_HLEN); - memcpy(eth_recv->et_src, priv->fake_host_hwaddr, ARP_HLEN); - eth_recv->et_protlen = htons(PROT_IP); + memcpy(eth_recv->dst, pdata->enetaddr, ETHADDR_LEN); + memcpy(eth_recv->src, priv->fake_host_hwaddr, ETHADDR_LEN); + eth_recv->protlen = htons(PROT_IP); - ipr = (void *)eth_recv + ETHER_HDR_SIZE; - ipr->ip_hl_v = 0x45; - ipr->ip_len = htons(IP_ICMP_HDR_SIZE); - ipr->ip_off = htons(IP_FLAGS_DFRAG); - ipr->ip_p = IPPROTO_ICMP; - ipr->ip_sum = 0; - net_write_ip(&ipr->ip_src, priv->fake_host_ipaddr); - net_write_ip(&ipr->ip_dst, net_ip); - ipr->ip_sum = compute_ip_checksum(ipr, IP_HDR_SIZE); + ipr = (void *)eth_recv + ETHHDR_SIZE; + ipr->hl_v = 0x45; + ipr->len = htons(IPHDR_SIZE + ICMPHDR_SIZE); + ipr->off = htons(IP_FLAGS_DFRAG); + ipr->prot = IPPROTO_ICMP; + ipr->sum = 0; + ipr->src = priv->fake_host_ipaddr.s_addr; + ipr->dst = net_ip.s_addr; + ipr->sum = compute_ip_checksum(ipr, IPHDR_SIZE); - icmpr = (struct icmp_hdr *)&ipr->udp_src; + icmpr = (struct icmphdr *)(ipr + 1); icmpr->type = ICMP_ECHO_REQUEST; icmpr->code = 0; icmpr->checksum = 0; - icmpr->un.echo.id = 0; - icmpr->un.echo.sequence = htons(1); - icmpr->checksum = compute_ip_checksum(icmpr, ICMP_HDR_SIZE); + icmpr->id = 0; + icmpr->sequence = htons(1); + icmpr->checksum = compute_ip_checksum(icmpr, ICMPHDR_SIZE); priv->recv_packet_length[priv->recv_packets] = - ETHER_HDR_SIZE + IP_ICMP_HDR_SIZE; + ETHHDR_SIZE + IPHDR_SIZE + ICMPHDR_SIZE; ++priv->recv_packets; return 0; @@ -398,7 +476,7 @@ static int sb_eth_write_hwaddr(struct udevice *dev) debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name, pdata->enetaddr); - memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ARP_HLEN); + memcpy(priv->fake_host_hwaddr, pdata->enetaddr, ETHADDR_LEN); return 0; } diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 4f876d39875..409049137cc 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -67,6 +67,7 @@ config PCI_CONFIG_HOST_BRIDGE config PCI_MAP_SYSTEM_MEMORY bool "Map local system memory from a virtual base address" depends on MIPS + default y if !ARCH_MAP_SYSMEM help Say Y if base address of system memory is being used as a virtual address instead of a physical address (e.g. on MIPS). The PCI core will then remap @@ -75,6 +76,15 @@ config PCI_MAP_SYSTEM_MEMORY This should only be required on MIPS where CFG_SYS_SDRAM_BASE is still being used as virtual address. +config PCI_BRIDGE_MEM_ALIGNMENT + hex "Alignment boundary of PCI memory resource allocation" + default 0x10000 if TARGET_BOSTON + default 0x100000 + help + Specify a boundary for alignment of PCI memory resource allocation, + this is normally 0x100000 (1MB) but can be reduced to accommodate + hardware with tight bridge range if hardware allows. + config PCI_SRIOV bool "Enable Single Root I/O Virtualization support for PCI" help diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index e68e31a8227..4a1c782be36 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -373,8 +373,8 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, 0xff); if (pci_mem) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_mem, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_mem, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); /* * Set up memory and I/O filter limits, assume 32-bit @@ -388,8 +388,8 @@ void dm_pciauto_prescan_setup_bridge(struct udevice *dev, int sub_bus) } if (pci_prefetch) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_prefetch, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_prefetch, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); /* * Set up memory and I/O filter limits, assume 32-bit @@ -466,8 +466,8 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) dm_pci_write_config8(dev, PCI_SUBORDINATE_BUS, sub_bus - dev_seq(ctlr)); if (pci_mem) { - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_mem, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_mem, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); dm_pci_write_config16(dev, PCI_MEMORY_LIMIT, ((pci_mem->bus_lower - 1) >> 16) & @@ -481,8 +481,8 @@ void dm_pciauto_postscan_setup_bridge(struct udevice *dev, int sub_bus) &prefechable_64); prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; - /* Round memory allocator to 1MB boundary */ - pciauto_region_align(pci_prefetch, 0x100000); + /* Round memory allocator */ + pciauto_region_align(pci_prefetch, CONFIG_PCI_BRIDGE_MEM_ALIGNMENT); dm_pci_write_config16(dev, PCI_PREF_MEMORY_LIMIT, (((pci_prefetch->bus_lower - 1) >> 16) & diff --git a/drivers/pci/pcie_xilinx.c b/drivers/pci/pcie_xilinx.c index a674ab04bee..63058e8e7c5 100644 --- a/drivers/pci/pcie_xilinx.c +++ b/drivers/pci/pcie_xilinx.c @@ -18,14 +18,19 @@ */ struct xilinx_pcie { void *cfg_base; + pci_size_t size; + int first_busno; }; /* Register definitions */ -#define XILINX_PCIE_REG_PSCR 0x144 -#define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) -#define XILINX_PCIE_REG_RPSC 0x148 -#define XILINX_PCIE_REG_RPSC_BEN BIT(0) - +#define XILINX_PCIE_REG_BRIDGE_INFO 0x130 +#define XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_SHIFT 16 +#define XILINX_PCIE_REG_BRIDGE_INFO_ECAMSZ_MASK (0x7 << 16) +#define XILINX_PCIE_REG_INT_MASK 0x13c +#define XILINX_PCIE_REG_PSCR 0x144 +#define XILINX_PCIE_REG_PSCR_LNKUP BIT(11) +#define XILINX_PCIE_REG_RPSC 0x148 +#define XILINX_PCIE_REG_RPSC_BEN BIT(0) /** * pcie_xilinx_link_up() - Check whether the PCIe link is up * @pcie: Pointer to the PCI controller state @@ -61,14 +66,18 @@ static int pcie_xilinx_config_address(const struct udevice *udev, pci_dev_t bdf, uint offset, void **paddress) { struct xilinx_pcie *pcie = dev_get_priv(udev); - unsigned int bus = PCI_BUS(bdf); + unsigned int bus = PCI_BUS(bdf) - pcie->first_busno; unsigned int dev = PCI_DEV(bdf); unsigned int func = PCI_FUNC(bdf); + int num_buses = DIV_ROUND_UP(pcie->size, 1 << 16); void *addr; if ((bus > 0) && !pcie_xilinx_link_up(pcie)) return -ENODEV; + if (bus > num_buses) + return -ENODEV; + /* * Busses 0 (host-PCIe bridge) & 1 (its immediate child) are * limited to a single device each. @@ -142,20 +151,37 @@ static int pcie_xilinx_of_to_plat(struct udevice *dev) struct xilinx_pcie *pcie = dev_get_priv(dev); fdt_addr_t addr; fdt_size_t size; - u32 rpsc; addr = dev_read_addr_size(dev, &size); if (addr == FDT_ADDR_T_NONE) return -EINVAL; - pcie->cfg_base = devm_ioremap(dev, addr, size); - if (IS_ERR(pcie->cfg_base)) - return PTR_ERR(pcie->cfg_base); + pcie->cfg_base = map_physmem(addr, size, MAP_NOCACHE); + if (!pcie->cfg_base) + return -ENOMEM; + pcie->size = size; + return 0; +} - /* Enable the Bridge enable bit */ - rpsc = __raw_readl(pcie->cfg_base + XILINX_PCIE_REG_RPSC); +static int pci_xilinx_probe(struct udevice *dev) +{ + struct xilinx_pcie *pcie = dev_get_priv(dev); + u32 rpsc; + int num_buses = DIV_ROUND_UP(pcie->size, 1 << 16); + + pcie->first_busno = dev_seq(dev); + + /* Disable all interrupts */ + writel(0, pcie->cfg_base + XILINX_PCIE_REG_INT_MASK); + + /* Enable the bridge */ + rpsc = readl(pcie->cfg_base + XILINX_PCIE_REG_RPSC); rpsc |= XILINX_PCIE_REG_RPSC_BEN; - __raw_writel(rpsc, pcie->cfg_base + XILINX_PCIE_REG_RPSC); + writel(rpsc, pcie->cfg_base + XILINX_PCIE_REG_RPSC); + + /* Enable access to all possible subordinate buses */ + writel((0 << 0) | (1 << 8) | (num_buses << 16), + pcie->cfg_base + PCI_PRIMARY_BUS); return 0; } @@ -176,5 +202,6 @@ U_BOOT_DRIVER(pcie_xilinx) = { .of_match = pcie_xilinx_ids, .ops = &pcie_xilinx_ops, .of_to_plat = pcie_xilinx_of_to_plat, + .probe = pci_xilinx_probe, .priv_auto = sizeof(struct xilinx_pcie), }; diff --git a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c index 43f6e020a6a..88b33de1b2a 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-usb2.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-usb2.c @@ -40,11 +40,13 @@ struct rockchip_usb2phy_port_cfg { struct rockchip_usb2phy_cfg { unsigned int reg; struct usb2phy_reg clkout_ctl; + struct usb2phy_reg clkout_ctl_phy; const struct rockchip_usb2phy_port_cfg port_cfgs[USB2PHY_NUM_PORTS]; }; struct rockchip_usb2phy { struct regmap *reg_base; + struct regmap *phy_base; struct clk phyclk; const struct rockchip_usb2phy_cfg *phy_cfg; }; @@ -165,6 +167,22 @@ static struct phy_ops rockchip_usb2phy_ops = { .of_xlate = rockchip_usb2phy_of_xlate, }; +static void rockchip_usb2phy_clkout_ctl(struct clk *clk, struct regmap **base, + const struct usb2phy_reg **clkout_ctl) +{ + struct udevice *parent = dev_get_parent(clk->dev); + struct rockchip_usb2phy *priv = dev_get_priv(parent); + const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg; + + if (priv->phy_cfg->clkout_ctl_phy.enable) { + *base = priv->phy_base; + *clkout_ctl = &phy_cfg->clkout_ctl_phy; + } else { + *base = priv->reg_base; + *clkout_ctl = &phy_cfg->clkout_ctl; + } +} + /** * round_rate() - Adjust a rate to the exact rate a clock can provide. * @clk: The clock to manipulate. @@ -185,13 +203,14 @@ ulong rockchip_usb2phy_clk_round_rate(struct clk *clk, ulong rate) */ int rockchip_usb2phy_clk_enable(struct clk *clk) { - struct udevice *parent = dev_get_parent(clk->dev); - struct rockchip_usb2phy *priv = dev_get_priv(parent); - const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg; + const struct usb2phy_reg *clkout_ctl; + struct regmap *base; + + rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl); /* turn on 480m clk output if it is off */ - if (!property_enabled(priv->reg_base, &phy_cfg->clkout_ctl)) { - property_enable(priv->reg_base, &phy_cfg->clkout_ctl, true); + if (!property_enabled(base, clkout_ctl)) { + property_enable(base, clkout_ctl, true); /* waiting for the clk become stable */ usleep_range(1200, 1300); @@ -208,12 +227,13 @@ int rockchip_usb2phy_clk_enable(struct clk *clk) */ int rockchip_usb2phy_clk_disable(struct clk *clk) { - struct udevice *parent = dev_get_parent(clk->dev); - struct rockchip_usb2phy *priv = dev_get_priv(parent); - const struct rockchip_usb2phy_cfg *phy_cfg = priv->phy_cfg; + const struct usb2phy_reg *clkout_ctl; + struct regmap *base; + + rockchip_usb2phy_clkout_ctl(clk, &base, &clkout_ctl); /* turn off 480m clk output */ - property_enable(priv->reg_base, &phy_cfg->clkout_ctl, false); + property_enable(base, clkout_ctl, false); return 0; } @@ -281,7 +301,10 @@ static int rockchip_usb2phy_probe(struct udevice *dev) return ret; } - return 0; + if (priv->phy_cfg->clkout_ctl_phy.enable) + ret = regmap_init_mem_index(dev_ofnode(dev), &priv->phy_base, 0); + + return ret; } static int rockchip_usb2phy_bind(struct udevice *dev) @@ -389,6 +412,22 @@ static const struct rockchip_usb2phy_cfg rk3399_usb2phy_cfgs[] = { { /* sentinel */ } }; +static const struct rockchip_usb2phy_cfg rk3528_phy_cfgs[] = { + { + .reg = 0xffdf0000, + .clkout_ctl_phy = { 0x041c, 7, 2, 0, 0x27 }, + .port_cfgs = { + [USB2PHY_PORT_OTG] = { + .phy_sus = { 0x004c, 1, 0, 2, 1 }, + }, + [USB2PHY_PORT_HOST] = { + .phy_sus = { 0x005c, 1, 0, 2, 1 }, + } + }, + }, + { /* sentinel */ } +}; + static const struct rockchip_usb2phy_cfg rk3568_phy_cfgs[] = { { .reg = 0xfe8a0000, @@ -471,6 +510,10 @@ static const struct udevice_id rockchip_usb2phy_ids[] = { .data = (ulong)&rk3399_usb2phy_cfgs, }, { + .compatible = "rockchip,rk3528-usb2phy", + .data = (ulong)&rk3528_phy_cfgs, + }, + { .compatible = "rockchip,rk3568-usb2phy", .data = (ulong)&rk3568_phy_cfgs, }, diff --git a/drivers/pinctrl/rockchip/Makefile b/drivers/pinctrl/rockchip/Makefile index c91f650b043..e17415e1ca6 100644 --- a/drivers/pinctrl/rockchip/Makefile +++ b/drivers/pinctrl/rockchip/Makefile @@ -14,7 +14,9 @@ obj-$(CONFIG_ROCKCHIP_RK3308) += pinctrl-rk3308.o 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_RK3576) += pinctrl-rk3576.o obj-$(CONFIG_ROCKCHIP_RK3588) += pinctrl-rk3588.o obj-$(CONFIG_ROCKCHIP_RV1108) += pinctrl-rv1108.o obj-$(CONFIG_ROCKCHIP_RV1126) += pinctrl-rv1126.o diff --git a/drivers/pinctrl/rockchip/pinctrl-rk3528.c b/drivers/pinctrl/rockchip/pinctrl-rk3528.c new file mode 100644 index 00000000000..a3e1f0b2c9d --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl-rk3528.c @@ -0,0 +1,273 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + */ + +#include <dm.h> +#include <dm/pinctrl.h> +#include <regmap.h> +#include <syscon.h> + +#include "pinctrl-rockchip.h" +#include <dt-bindings/pinctrl/rockchip.h> + +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; + + if (bank->bank_num == 0) { + *reg = RK3528_DRV_GPIO0_OFFSET; + } else if (bank->bank_num == 1) { + *reg = RK3528_DRV_GPIO1_OFFSET; + } else if (bank->bank_num == 2) { + *reg = RK3528_DRV_GPIO2_OFFSET; + } else if (bank->bank_num == 3) { + *reg = RK3528_DRV_GPIO3_OFFSET; + } else if (bank->bank_num == 4) { + *reg = RK3528_DRV_GPIO4_OFFSET; + } else { + *reg = 0; + debug("unsupported bank_num %d\n", bank->bank_num); + } + + *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; + + if (bank->bank_num == 0) { + *reg = RK3528_PULL_GPIO0_OFFSET; + } else if (bank->bank_num == 1) { + *reg = RK3528_PULL_GPIO1_OFFSET; + } else if (bank->bank_num == 2) { + *reg = RK3528_PULL_GPIO2_OFFSET; + } else if (bank->bank_num == 3) { + *reg = RK3528_PULL_GPIO3_OFFSET; + } else if (bank->bank_num == 4) { + *reg = RK3528_PULL_GPIO4_OFFSET; + } else { + *reg = 0; + debug("unsupported bank_num %d\n", bank->bank_num); + } + + *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; + + if (bank->bank_num == 0) { + *reg = RK3528_SMT_GPIO0_OFFSET; + } else if (bank->bank_num == 1) { + *reg = RK3528_SMT_GPIO1_OFFSET; + } else if (bank->bank_num == 2) { + *reg = RK3528_SMT_GPIO2_OFFSET; + } else if (bank->bank_num == 3) { + *reg = RK3528_SMT_GPIO3_OFFSET; + } else if (bank->bank_num == 4) { + *reg = RK3528_SMT_GPIO4_OFFSET; + } else { + *reg = 0; + debug("unsupported bank_num %d\n", bank->bank_num); + } + + *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), + .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/drivers/pinctrl/rockchip/pinctrl-rk3576.c b/drivers/pinctrl/rockchip/pinctrl-rk3576.c new file mode 100644 index 00000000000..66e1142ac1f --- /dev/null +++ b/drivers/pinctrl/rockchip/pinctrl-rk3576.c @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2024 Rockchip Electronics Co., Ltd + */ + +#include <dm.h> +#include <dm/pinctrl.h> +#include <regmap.h> +#include <syscon.h> + +#include "pinctrl-rockchip.h" +#include <dt-bindings/pinctrl/rockchip.h> + +static int rk3576_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; + + if (bank->bank_num == 0 && pin >= RK_PB4 && pin <= RK_PB7) + reg += 0x1FF4; /* GPIO0_IOC_GPIO0B_IOMUX_SEL_H */ + + return regmap_update_bits(regmap, reg, rmask, data); +} + +#define RK3576_DRV_BITS_PER_PIN 4 +#define RK3576_DRV_PINS_PER_REG 4 +#define RK3576_DRV_GPIO0_AL_OFFSET 0x10 +#define RK3576_DRV_GPIO0_BH_OFFSET 0x2014 +#define RK3576_DRV_GPIO1_OFFSET 0x6020 +#define RK3576_DRV_GPIO2_OFFSET 0x6040 +#define RK3576_DRV_GPIO3_OFFSET 0x6060 +#define RK3576_DRV_GPIO4_AL_OFFSET 0x6080 +#define RK3576_DRV_GPIO4_CL_OFFSET 0xA090 +#define RK3576_DRV_GPIO4_DL_OFFSET 0xB098 + +static void rk3576_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; + if (bank->bank_num == 0 && pin_num < 12) { + *reg = RK3576_DRV_GPIO0_AL_OFFSET; + } else if (bank->bank_num == 0) { + *reg = RK3576_DRV_GPIO0_BH_OFFSET - 0xc; + } else if (bank->bank_num == 1) { + *reg = RK3576_DRV_GPIO1_OFFSET; + } else if (bank->bank_num == 2) { + *reg = RK3576_DRV_GPIO2_OFFSET; + } else if (bank->bank_num == 3) { + *reg = RK3576_DRV_GPIO3_OFFSET; + } else if (bank->bank_num == 4 && pin_num < 16) { + *reg = RK3576_DRV_GPIO4_AL_OFFSET; + } else if (bank->bank_num == 4 && pin_num < 24) { + *reg = RK3576_DRV_GPIO4_CL_OFFSET - 0x10; + } else if (bank->bank_num == 4) { + *reg = RK3576_DRV_GPIO4_DL_OFFSET - 0x18; + } else { + *reg = 0; + debug("unsupported bank_num %d\n", bank->bank_num); + } + + *reg += ((pin_num / RK3576_DRV_PINS_PER_REG) * 4); + *bit = pin_num % RK3576_DRV_PINS_PER_REG; + *bit *= RK3576_DRV_BITS_PER_PIN; +} + +static int rk3576_set_drive(struct rockchip_pin_bank *bank, + int pin_num, int strength) +{ + struct regmap *regmap; + int reg; + u32 data, rmask; + u8 bit; + int drv = ((strength & BIT(2)) >> 2) | ((strength & BIT(0)) << 2) | (strength & BIT(1)); + + rk3576_calc_drv_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3576_DRV_BITS_PER_PIN) - 1) << (bit + 16); + rmask = data | (data >> 16); + data |= (drv << bit); + + return regmap_update_bits(regmap, reg, rmask, data); +} + +#define RK3576_PULL_BITS_PER_PIN 2 +#define RK3576_PULL_PINS_PER_REG 8 +#define RK3576_PULL_GPIO0_AL_OFFSET 0x20 +#define RK3576_PULL_GPIO0_BH_OFFSET 0x2028 +#define RK3576_PULL_GPIO1_OFFSET 0x6110 +#define RK3576_PULL_GPIO2_OFFSET 0x6120 +#define RK3576_PULL_GPIO3_OFFSET 0x6130 +#define RK3576_PULL_GPIO4_AL_OFFSET 0x6140 +#define RK3576_PULL_GPIO4_CL_OFFSET 0xA148 +#define RK3576_PULL_GPIO4_DL_OFFSET 0xB14C + +static void rk3576_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; + if (bank->bank_num == 0 && pin_num < 12) { + *reg = RK3576_PULL_GPIO0_AL_OFFSET; + } else if (bank->bank_num == 0) { + *reg = RK3576_PULL_GPIO0_BH_OFFSET - 0x4; + } else if (bank->bank_num == 1) { + *reg = RK3576_PULL_GPIO1_OFFSET; + } else if (bank->bank_num == 2) { + *reg = RK3576_PULL_GPIO2_OFFSET; + } else if (bank->bank_num == 3) { + *reg = RK3576_PULL_GPIO3_OFFSET; + } else if (bank->bank_num == 4 && pin_num < 16) { + *reg = RK3576_PULL_GPIO4_AL_OFFSET; + } else if (bank->bank_num == 4 && pin_num < 24) { + *reg = RK3576_PULL_GPIO4_CL_OFFSET - 0x8; + } else if (bank->bank_num == 4) { + *reg = RK3576_PULL_GPIO4_DL_OFFSET - 0xc; + } else { + *reg = 0; + debug("unsupported bank_num %d\n", bank->bank_num); + } + + *reg += ((pin_num / RK3576_PULL_PINS_PER_REG) * 4); + *bit = pin_num % RK3576_PULL_PINS_PER_REG; + *bit *= RK3576_PULL_BITS_PER_PIN; +} + +static int rk3576_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 -ENOTSUPP; + + rk3576_calc_pull_reg_and_bit(bank, pin_num, ®map, ®, &bit); + type = 1; /* FIXME: was always set to 1 in vendor kernel */ + 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 << RK3576_PULL_BITS_PER_PIN) - 1) << (bit + 16); + rmask = data | (data >> 16); + data |= (ret << bit); + + return regmap_update_bits(regmap, reg, rmask, data); +} + +#define RK3576_SMT_BITS_PER_PIN 1 +#define RK3576_SMT_PINS_PER_REG 8 +#define RK3576_SMT_GPIO0_AL_OFFSET 0x30 +#define RK3576_SMT_GPIO0_BH_OFFSET 0x2040 +#define RK3576_SMT_GPIO1_OFFSET 0x6210 +#define RK3576_SMT_GPIO2_OFFSET 0x6220 +#define RK3576_SMT_GPIO3_OFFSET 0x6230 +#define RK3576_SMT_GPIO4_AL_OFFSET 0x6240 +#define RK3576_SMT_GPIO4_CL_OFFSET 0xA248 +#define RK3576_SMT_GPIO4_DL_OFFSET 0xB24C + +static void rk3576_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; + if (bank->bank_num == 0 && pin_num < 12) { + *reg = RK3576_SMT_GPIO0_AL_OFFSET; + } else if (bank->bank_num == 0) { + *reg = RK3576_SMT_GPIO0_BH_OFFSET - 0x4; + } else if (bank->bank_num == 1) { + *reg = RK3576_SMT_GPIO1_OFFSET; + } else if (bank->bank_num == 2) { + *reg = RK3576_SMT_GPIO2_OFFSET; + } else if (bank->bank_num == 3) { + *reg = RK3576_SMT_GPIO3_OFFSET; + } else if (bank->bank_num == 4 && pin_num < 16) { + *reg = RK3576_SMT_GPIO4_AL_OFFSET; + } else if (bank->bank_num == 4 && pin_num < 24) { + *reg = RK3576_SMT_GPIO4_CL_OFFSET - 0x8; + } else if (bank->bank_num == 4) { + *reg = RK3576_SMT_GPIO4_DL_OFFSET - 0xc; + } else { + *reg = 0; + debug("unsupported bank_num %d\n", bank->bank_num); + } + + *reg += ((pin_num / RK3576_SMT_PINS_PER_REG) * 4); + *bit = pin_num % RK3576_SMT_PINS_PER_REG; + *bit *= RK3576_SMT_BITS_PER_PIN; +} + +static int rk3576_set_schmitt(struct rockchip_pin_bank *bank, + int pin_num, int enable) +{ + struct regmap *regmap; + int reg; + u32 data, rmask; + u8 bit; + + rk3576_calc_schmitt_reg_and_bit(bank, pin_num, ®map, ®, &bit); + + /* enable the write to the equivalent lower bits */ + data = ((1 << RK3576_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 rk3576_pin_banks[] = { + RK3576_PIN_BANK_FLAGS(0, 32, "gpio0", IOMUX_WIDTH_4BIT, + 0, 0x8, 0x2004, 0x200C), + RK3576_PIN_BANK_FLAGS(1, 32, "gpio1", IOMUX_WIDTH_4BIT, + 0x4020, 0x4028, 0x4030, 0x4038), + RK3576_PIN_BANK_FLAGS(2, 32, "gpio2", IOMUX_WIDTH_4BIT, + 0x4040, 0x4048, 0x4050, 0x4058), + RK3576_PIN_BANK_FLAGS(3, 32, "gpio3", IOMUX_WIDTH_4BIT, + 0x4060, 0x4068, 0x4070, 0x4078), + RK3576_PIN_BANK_FLAGS(4, 32, "gpio4", IOMUX_WIDTH_4BIT, + 0x4080, 0x4088, 0xA390, 0xB398), +}; + +static const struct rockchip_pin_ctrl rk3576_pin_ctrl = { + .pin_banks = rk3576_pin_banks, + .nr_banks = ARRAY_SIZE(rk3576_pin_banks), + .grf_mux_offset = 0x0, + .set_mux = rk3576_set_mux, + .set_pull = rk3576_set_pull, + .set_drive = rk3576_set_drive, + .set_schmitt = rk3576_set_schmitt, +}; + +static const struct udevice_id rk3576_pinctrl_ids[] = { + { + .compatible = "rockchip,rk3576-pinctrl", + .data = (ulong)&rk3576_pin_ctrl + }, + { } +}; + +U_BOOT_DRIVER(pinctrl_rk3576) = { + .name = "rockchip_rk3576_pinctrl", + .id = UCLASS_PINCTRL, + .of_match = rk3576_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/drivers/pinctrl/rockchip/pinctrl-rockchip.h b/drivers/pinctrl/rockchip/pinctrl-rockchip.h index df7bc684d29..5e3c9c90760 100644 --- a/drivers/pinctrl/rockchip/pinctrl-rockchip.h +++ b/drivers/pinctrl/rockchip/pinctrl-rockchip.h @@ -458,6 +458,9 @@ struct rockchip_pin_bank { #define MR_PMUGRF(ID, PIN, FUNC, REG, VAL) \ PIN_BANK_MUX_ROUTE_FLAGS(ID, PIN, FUNC, REG, VAL, ROUTE_TYPE_PMUGRF) +#define RK3576_PIN_BANK_FLAGS(ID, PIN, LABEL, M, O1, O2, O3, O4) \ + PIN_BANK_IOMUX_FLAGS_OFFSET(ID, PIN, LABEL, M, M, M, M, O1, O2, O3, O4) + #define RK3588_PIN_BANK_FLAGS(ID, PIN, LABEL, M, P) \ PIN_BANK_IOMUX_FLAGS_PULL_FLAGS(ID, PIN, LABEL, M, M, M, M, P, P, P, P) diff --git a/drivers/power/domain/power-domain-uclass.c b/drivers/power/domain/power-domain-uclass.c index a6e5f9ed036..938bd8cbc9f 100644 --- a/drivers/power/domain/power-domain-uclass.c +++ b/drivers/power/domain/power-domain-uclass.c @@ -12,10 +12,6 @@ #include <power-domain-uclass.h> #include <dm/device-internal.h> -struct power_domain_priv { - int on_count; -}; - static inline struct power_domain_ops *power_domain_dev_ops(struct udevice *dev) { return (struct power_domain_ops *)dev->driver->ops; @@ -111,49 +107,22 @@ int power_domain_free(struct power_domain *power_domain) return ops->rfree ? ops->rfree(power_domain) : 0; } -int power_domain_on_lowlevel(struct power_domain *power_domain) +int power_domain_on(struct power_domain *power_domain) { - struct power_domain_priv *priv = dev_get_uclass_priv(power_domain->dev); struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); - int ret; debug("%s(power_domain=%p)\n", __func__, power_domain); - if (priv->on_count++ > 0) - return -EALREADY; - - ret = ops->on ? ops->on(power_domain) : 0; - if (ret) { - priv->on_count--; - return ret; - } - - return 0; + return ops->on ? ops->on(power_domain) : 0; } -int power_domain_off_lowlevel(struct power_domain *power_domain) +int power_domain_off(struct power_domain *power_domain) { - struct power_domain_priv *priv = dev_get_uclass_priv(power_domain->dev); struct power_domain_ops *ops = power_domain_dev_ops(power_domain->dev); - int ret; debug("%s(power_domain=%p)\n", __func__, power_domain); - if (priv->on_count <= 0) { - debug("Power domain %s already off.\n", power_domain->dev->name); - return -EALREADY; - } - - if (priv->on_count-- > 1) - return -EBUSY; - - ret = ops->off ? ops->off(power_domain) : 0; - if (ret) { - priv->on_count++; - return ret; - } - - return 0; + return ops->off ? ops->off(power_domain) : 0; } #if CONFIG_IS_ENABLED(OF_REAL) @@ -211,5 +180,4 @@ int dev_power_domain_off(struct udevice *dev) UCLASS_DRIVER(power_domain) = { .id = UCLASS_POWER_DOMAIN, .name = "power_domain", - .per_device_auto = sizeof(struct power_domain_priv), }; diff --git a/drivers/power/domain/sandbox-power-domain-test.c b/drivers/power/domain/sandbox-power-domain-test.c index 5b530974e94..08c15ef342b 100644 --- a/drivers/power/domain/sandbox-power-domain-test.c +++ b/drivers/power/domain/sandbox-power-domain-test.c @@ -51,5 +51,4 @@ U_BOOT_DRIVER(sandbox_power_domain_test) = { .id = UCLASS_MISC, .of_match = sandbox_power_domain_test_ids, .priv_auto = sizeof(struct sandbox_power_domain_test), - .flags = DM_FLAG_DEFAULT_PD_CTRL_OFF, }; diff --git a/drivers/power/regulator/scmi_regulator.c b/drivers/power/regulator/scmi_regulator.c index 99f6506f162..79db1a6a8aa 100644 --- a/drivers/power/regulator/scmi_regulator.c +++ b/drivers/power/regulator/scmi_regulator.c @@ -175,12 +175,19 @@ U_BOOT_DRIVER(scmi_regulator) = { static int scmi_regulator_bind(struct udevice *dev) { struct driver *drv; + ofnode regul_node; ofnode node; int ret; + regul_node = ofnode_find_subnode(dev_ofnode(dev), "regulators"); + if (!ofnode_valid(regul_node)) { + dev_err(dev, "no regulators node\n"); + return -ENXIO; + } + drv = DM_DRIVER_GET(scmi_regulator); - ofnode_for_each_subnode(node, dev_ofnode(dev)) { + ofnode_for_each_subnode(node, regul_node) { ret = device_bind(dev, drv, ofnode_get_name(node), NULL, node, NULL); if (ret) diff --git a/drivers/ram/rockchip/Makefile b/drivers/ram/rockchip/Makefile index 36dc0500dab..fd94aad0cd4 100644 --- a/drivers/ram/rockchip/Makefile +++ b/drivers/ram/rockchip/Makefile @@ -13,7 +13,9 @@ obj-$(CONFIG_ROCKCHIP_RK3288) = sdram_rk3288.o 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_RK3576) += sdram_rk3576.o obj-$(CONFIG_ROCKCHIP_RK3588) += sdram_rk3588.o obj-$(CONFIG_ROCKCHIP_RV1126) += sdram_rv1126.o sdram_pctl_px30.o obj-$(CONFIG_ROCKCHIP_SDRAM_COMMON) += sdram_common.o diff --git a/drivers/ram/rockchip/sdram_rk3528.c b/drivers/ram/rockchip/sdram_rk3528.c new file mode 100644 index 00000000000..89d325bea66 --- /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 <dm.h> +#include <ram.h> +#include <asm/arch-rockchip/sdram.h> + +#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/drivers/ram/rockchip/sdram_rk3576.c b/drivers/ram/rockchip/sdram_rk3576.c new file mode 100644 index 00000000000..5a66032ef8f --- /dev/null +++ b/drivers/ram/rockchip/sdram_rk3576.c @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2024 Rockchip Electronics Co., Ltd. + */ + +#include <dm.h> +#include <ram.h> +#include <asm/arch-rockchip/sdram.h> + +#define PMU1GRF_BASE 0x26026000 +#define OS_REG2_REG 0x208 + +static int rk3576_dmc_get_info(struct udevice *dev, struct ram_info *info) +{ + info->base = CFG_SYS_SDRAM_BASE; + info->size = rockchip_sdram_size(PMU1GRF_BASE + OS_REG2_REG); + + return 0; +} + +static struct ram_ops rk3576_dmc_ops = { + .get_info = rk3576_dmc_get_info, +}; + +static const struct udevice_id rk3576_dmc_ids[] = { + { .compatible = "rockchip,rk3576-dmc" }, + { } +}; + +U_BOOT_DRIVER(rockchip_rk3576_dmc) = { + .name = "rockchip_rk3576_dmc", + .id = UCLASS_RAM, + .of_match = rk3576_dmc_ids, + .ops = &rk3576_dmc_ops, +}; diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index b9494396013..1dd3cd99a14 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -17,7 +17,7 @@ obj-$(CONFIG_RESET_BCM6345) += reset-bcm6345.o obj-$(CONFIG_RESET_UNIPHIER) += reset-uniphier.o obj-$(CONFIG_RESET_AST2500) += reset-ast2500.o obj-$(CONFIG_RESET_AST2600) += reset-ast2600.o -obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o rst-rk3588.o +obj-$(CONFIG_RESET_ROCKCHIP) += reset-rockchip.o rst-rk3528.o rst-rk3576.o rst-rk3588.o obj-$(CONFIG_RESET_MESON) += reset-meson.o obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o obj-$(CONFIG_RESET_MEDIATEK) += reset-mediatek.o diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index 76d108080d9..e57729f0ef9 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -23,6 +23,7 @@ #include <linux/bitops.h> #include <linux/io.h> #include <linux/sizes.h> +#include <linux/kconfig.h> #define BANK_INCREMENT 4 #define NR_BANKS 8 @@ -114,6 +115,8 @@ static int socfpga_reset_remove(struct udevice *dev) if (socfpga_reset_keep_enabled()) { puts("Deasserting all peripheral resets\n"); writel(0, data->modrst_base + 4); + if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_ARRIA10)) + writel(0, data->modrst_base + 8); } return 0; diff --git a/drivers/reset/rst-rk3528.c b/drivers/reset/rst-rk3528.c new file mode 100644 index 00000000000..f6e760d468d --- /dev/null +++ b/drivers/reset/rst-rk3528.c @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + * Based on Sebastian Reichel's implementation for RK3588 + */ + +#include <dm.h> +#include <asm/arch-rockchip/clock.h> +#include <dt-bindings/reset/rockchip,rk3528-cru.h> + +/* 0xFF4A0000 + 0x0A00 */ +#define RK3528_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit) + +/* mapping table for reset ID to register offset */ +static const int rk3528_register_offset[] = { + /* CRU_SOFTRST_CON03 */ + RK3528_CRU_RESET_OFFSET(SRST_CORE0_PO, 3, 0), + RK3528_CRU_RESET_OFFSET(SRST_CORE1_PO, 3, 1), + RK3528_CRU_RESET_OFFSET(SRST_CORE2_PO, 3, 2), + RK3528_CRU_RESET_OFFSET(SRST_CORE3_PO, 3, 3), + RK3528_CRU_RESET_OFFSET(SRST_CORE0, 3, 4), + RK3528_CRU_RESET_OFFSET(SRST_CORE1, 3, 5), + RK3528_CRU_RESET_OFFSET(SRST_CORE2, 3, 6), + RK3528_CRU_RESET_OFFSET(SRST_CORE3, 3, 7), + RK3528_CRU_RESET_OFFSET(SRST_NL2, 3, 8), + RK3528_CRU_RESET_OFFSET(SRST_CORE_BIU, 3, 9), + RK3528_CRU_RESET_OFFSET(SRST_CORE_CRYPTO, 3, 10), + + /* CRU_SOFTRST_CON05 */ + RK3528_CRU_RESET_OFFSET(SRST_P_DBG, 5, 13), + RK3528_CRU_RESET_OFFSET(SRST_POT_DBG, 5, 14), + RK3528_CRU_RESET_OFFSET(SRST_NT_DBG, 5, 15), + + /* CRU_SOFTRST_CON06 */ + RK3528_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 6, 2), + RK3528_CRU_RESET_OFFSET(SRST_P_DAPLITE_BIU, 6, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_CPU_BIU, 6, 4), + RK3528_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 6, 7), + + /* CRU_SOFTRST_CON08 */ + RK3528_CRU_RESET_OFFSET(SRST_A_BUS_VOPGL_BIU, 8, 1), + RK3528_CRU_RESET_OFFSET(SRST_A_BUS_H_BIU, 8, 3), + RK3528_CRU_RESET_OFFSET(SRST_A_SYSMEM_BIU, 8, 8), + RK3528_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 8, 10), + RK3528_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 8, 11), + RK3528_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 8, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_DFT2APB, 8, 13), + RK3528_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 8, 15), + + /* CRU_SOFTRST_CON09 */ + RK3528_CRU_RESET_OFFSET(SRST_A_BUS_M_BIU, 9, 0), + RK3528_CRU_RESET_OFFSET(SRST_A_GIC, 9, 1), + RK3528_CRU_RESET_OFFSET(SRST_A_SPINLOCK, 9, 2), + RK3528_CRU_RESET_OFFSET(SRST_A_DMAC, 9, 4), + RK3528_CRU_RESET_OFFSET(SRST_P_TIMER, 9, 5), + RK3528_CRU_RESET_OFFSET(SRST_TIMER0, 9, 6), + RK3528_CRU_RESET_OFFSET(SRST_TIMER1, 9, 7), + RK3528_CRU_RESET_OFFSET(SRST_TIMER2, 9, 8), + RK3528_CRU_RESET_OFFSET(SRST_TIMER3, 9, 9), + RK3528_CRU_RESET_OFFSET(SRST_TIMER4, 9, 10), + RK3528_CRU_RESET_OFFSET(SRST_TIMER5, 9, 11), + RK3528_CRU_RESET_OFFSET(SRST_P_JDBCK_DAP, 9, 12), + RK3528_CRU_RESET_OFFSET(SRST_JDBCK_DAP, 9, 13), + RK3528_CRU_RESET_OFFSET(SRST_P_WDT_NS, 9, 15), + + /* CRU_SOFTRST_CON10 */ + RK3528_CRU_RESET_OFFSET(SRST_T_WDT_NS, 10, 0), + RK3528_CRU_RESET_OFFSET(SRST_H_TRNG_NS, 10, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_UART0, 10, 7), + RK3528_CRU_RESET_OFFSET(SRST_S_UART0, 10, 8), + RK3528_CRU_RESET_OFFSET(SRST_PKA_CRYPTO, 10, 10), + RK3528_CRU_RESET_OFFSET(SRST_A_CRYPTO, 10, 11), + RK3528_CRU_RESET_OFFSET(SRST_H_CRYPTO, 10, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 10, 13), + RK3528_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 10, 14), + + /* CRU_SOFTRST_CON11 */ + RK3528_CRU_RESET_OFFSET(SRST_P_PWM0, 11, 4), + RK3528_CRU_RESET_OFFSET(SRST_PWM0, 11, 5), + RK3528_CRU_RESET_OFFSET(SRST_P_PWM1, 11, 7), + RK3528_CRU_RESET_OFFSET(SRST_PWM1, 11, 8), + RK3528_CRU_RESET_OFFSET(SRST_P_SCR, 11, 10), + RK3528_CRU_RESET_OFFSET(SRST_A_DCF, 11, 11), + RK3528_CRU_RESET_OFFSET(SRST_P_INTMUX, 11, 12), + + /* CRU_SOFTRST_CON25 */ + RK3528_CRU_RESET_OFFSET(SRST_A_VPU_BIU, 25, 6), + RK3528_CRU_RESET_OFFSET(SRST_H_VPU_BIU, 25, 7), + RK3528_CRU_RESET_OFFSET(SRST_P_VPU_BIU, 25, 8), + RK3528_CRU_RESET_OFFSET(SRST_A_VPU, 25, 9), + RK3528_CRU_RESET_OFFSET(SRST_H_VPU, 25, 10), + RK3528_CRU_RESET_OFFSET(SRST_P_CRU_PCIE, 25, 11), + RK3528_CRU_RESET_OFFSET(SRST_P_VPU_GRF, 25, 12), + RK3528_CRU_RESET_OFFSET(SRST_H_SFC, 25, 13), + RK3528_CRU_RESET_OFFSET(SRST_S_SFC, 25, 14), + RK3528_CRU_RESET_OFFSET(SRST_C_EMMC, 25, 15), + + /* CRU_SOFTRST_CON26 */ + RK3528_CRU_RESET_OFFSET(SRST_H_EMMC, 26, 0), + RK3528_CRU_RESET_OFFSET(SRST_A_EMMC, 26, 1), + RK3528_CRU_RESET_OFFSET(SRST_B_EMMC, 26, 2), + RK3528_CRU_RESET_OFFSET(SRST_T_EMMC, 26, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_GPIO1, 26, 4), + RK3528_CRU_RESET_OFFSET(SRST_DB_GPIO1, 26, 5), + RK3528_CRU_RESET_OFFSET(SRST_A_VPU_L_BIU, 26, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_VPU_IOC, 26, 8), + RK3528_CRU_RESET_OFFSET(SRST_H_SAI_I2S0, 26, 9), + RK3528_CRU_RESET_OFFSET(SRST_M_SAI_I2S0, 26, 10), + RK3528_CRU_RESET_OFFSET(SRST_H_SAI_I2S2, 26, 11), + RK3528_CRU_RESET_OFFSET(SRST_M_SAI_I2S2, 26, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_ACODEC, 26, 13), + + /* CRU_SOFTRST_CON27 */ + RK3528_CRU_RESET_OFFSET(SRST_P_GPIO3, 27, 0), + RK3528_CRU_RESET_OFFSET(SRST_DB_GPIO3, 27, 1), + RK3528_CRU_RESET_OFFSET(SRST_P_SPI1, 27, 4), + RK3528_CRU_RESET_OFFSET(SRST_SPI1, 27, 5), + RK3528_CRU_RESET_OFFSET(SRST_P_UART2, 27, 7), + RK3528_CRU_RESET_OFFSET(SRST_S_UART2, 27, 8), + RK3528_CRU_RESET_OFFSET(SRST_P_UART5, 27, 9), + RK3528_CRU_RESET_OFFSET(SRST_S_UART5, 27, 10), + RK3528_CRU_RESET_OFFSET(SRST_P_UART6, 27, 11), + RK3528_CRU_RESET_OFFSET(SRST_S_UART6, 27, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_UART7, 27, 13), + RK3528_CRU_RESET_OFFSET(SRST_S_UART7, 27, 14), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C3, 27, 15), + + /* CRU_SOFTRST_CON28 */ + RK3528_CRU_RESET_OFFSET(SRST_I2C3, 28, 0), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C5, 28, 1), + RK3528_CRU_RESET_OFFSET(SRST_I2C5, 28, 2), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C6, 28, 3), + RK3528_CRU_RESET_OFFSET(SRST_I2C6, 28, 4), + RK3528_CRU_RESET_OFFSET(SRST_A_MAC, 28, 5), + + /* CRU_SOFTRST_CON30 */ + RK3528_CRU_RESET_OFFSET(SRST_P_PCIE, 30, 1), + RK3528_CRU_RESET_OFFSET(SRST_PCIE_PIPE_PHY, 30, 2), + RK3528_CRU_RESET_OFFSET(SRST_PCIE_POWER_UP, 30, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_PCIE_PHY, 30, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_PIPE_GRF, 30, 7), + + /* CRU_SOFTRST_CON32 */ + RK3528_CRU_RESET_OFFSET(SRST_H_SDIO0, 32, 2), + RK3528_CRU_RESET_OFFSET(SRST_H_SDIO1, 32, 4), + RK3528_CRU_RESET_OFFSET(SRST_TS_0, 32, 5), + RK3528_CRU_RESET_OFFSET(SRST_TS_1, 32, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_CAN2, 32, 7), + RK3528_CRU_RESET_OFFSET(SRST_CAN2, 32, 8), + RK3528_CRU_RESET_OFFSET(SRST_P_CAN3, 32, 9), + RK3528_CRU_RESET_OFFSET(SRST_CAN3, 32, 10), + RK3528_CRU_RESET_OFFSET(SRST_P_SARADC, 32, 11), + RK3528_CRU_RESET_OFFSET(SRST_SARADC, 32, 12), + RK3528_CRU_RESET_OFFSET(SRST_SARADC_PHY, 32, 13), + RK3528_CRU_RESET_OFFSET(SRST_P_TSADC, 32, 14), + RK3528_CRU_RESET_OFFSET(SRST_TSADC, 32, 15), + + /* CRU_SOFTRST_CON33 */ + RK3528_CRU_RESET_OFFSET(SRST_A_USB3OTG, 33, 1), + + /* CRU_SOFTRST_CON34 */ + RK3528_CRU_RESET_OFFSET(SRST_A_GPU_BIU, 34, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_GPU_BIU, 34, 5), + RK3528_CRU_RESET_OFFSET(SRST_A_GPU, 34, 8), + RK3528_CRU_RESET_OFFSET(SRST_REF_PVTPLL_GPU, 34, 9), + + /* CRU_SOFTRST_CON36 */ + RK3528_CRU_RESET_OFFSET(SRST_H_RKVENC_BIU, 36, 3), + RK3528_CRU_RESET_OFFSET(SRST_A_RKVENC_BIU, 36, 4), + RK3528_CRU_RESET_OFFSET(SRST_P_RKVENC_BIU, 36, 5), + RK3528_CRU_RESET_OFFSET(SRST_H_RKVENC, 36, 6), + RK3528_CRU_RESET_OFFSET(SRST_A_RKVENC, 36, 7), + RK3528_CRU_RESET_OFFSET(SRST_CORE_RKVENC, 36, 8), + RK3528_CRU_RESET_OFFSET(SRST_H_SAI_I2S1, 36, 9), + RK3528_CRU_RESET_OFFSET(SRST_M_SAI_I2S1, 36, 10), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C1, 36, 11), + RK3528_CRU_RESET_OFFSET(SRST_I2C1, 36, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C0, 36, 13), + RK3528_CRU_RESET_OFFSET(SRST_I2C0, 36, 14), + + /* CRU_SOFTRST_CON37 */ + RK3528_CRU_RESET_OFFSET(SRST_P_SPI0, 37, 2), + RK3528_CRU_RESET_OFFSET(SRST_SPI0, 37, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_GPIO4, 37, 8), + RK3528_CRU_RESET_OFFSET(SRST_DB_GPIO4, 37, 9), + RK3528_CRU_RESET_OFFSET(SRST_P_RKVENC_IOC, 37, 10), + RK3528_CRU_RESET_OFFSET(SRST_H_SPDIF, 37, 14), + RK3528_CRU_RESET_OFFSET(SRST_M_SPDIF, 37, 15), + + /* CRU_SOFTRST_CON38 */ + RK3528_CRU_RESET_OFFSET(SRST_H_PDM, 38, 0), + RK3528_CRU_RESET_OFFSET(SRST_M_PDM, 38, 1), + RK3528_CRU_RESET_OFFSET(SRST_P_UART1, 38, 2), + RK3528_CRU_RESET_OFFSET(SRST_S_UART1, 38, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_UART3, 38, 4), + RK3528_CRU_RESET_OFFSET(SRST_S_UART3, 38, 5), + RK3528_CRU_RESET_OFFSET(SRST_P_RKVENC_GRF, 38, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_CAN0, 38, 7), + RK3528_CRU_RESET_OFFSET(SRST_CAN0, 38, 8), + RK3528_CRU_RESET_OFFSET(SRST_P_CAN1, 38, 9), + RK3528_CRU_RESET_OFFSET(SRST_CAN1, 38, 10), + + /* CRU_SOFTRST_CON39 */ + RK3528_CRU_RESET_OFFSET(SRST_A_VO_BIU, 39, 3), + RK3528_CRU_RESET_OFFSET(SRST_H_VO_BIU, 39, 4), + RK3528_CRU_RESET_OFFSET(SRST_P_VO_BIU, 39, 5), + RK3528_CRU_RESET_OFFSET(SRST_H_RGA2E, 39, 7), + RK3528_CRU_RESET_OFFSET(SRST_A_RGA2E, 39, 8), + RK3528_CRU_RESET_OFFSET(SRST_CORE_RGA2E, 39, 9), + RK3528_CRU_RESET_OFFSET(SRST_H_VDPP, 39, 10), + RK3528_CRU_RESET_OFFSET(SRST_A_VDPP, 39, 11), + RK3528_CRU_RESET_OFFSET(SRST_CORE_VDPP, 39, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_VO_GRF, 39, 13), + RK3528_CRU_RESET_OFFSET(SRST_P_CRU, 39, 15), + + /* CRU_SOFTRST_CON40 */ + RK3528_CRU_RESET_OFFSET(SRST_A_VOP_BIU, 40, 1), + RK3528_CRU_RESET_OFFSET(SRST_H_VOP, 40, 2), + RK3528_CRU_RESET_OFFSET(SRST_D_VOP0, 40, 3), + RK3528_CRU_RESET_OFFSET(SRST_D_VOP1, 40, 4), + RK3528_CRU_RESET_OFFSET(SRST_A_VOP, 40, 5), + RK3528_CRU_RESET_OFFSET(SRST_P_HDMI, 40, 6), + RK3528_CRU_RESET_OFFSET(SRST_HDMI, 40, 7), + RK3528_CRU_RESET_OFFSET(SRST_P_HDMIPHY, 40, 14), + RK3528_CRU_RESET_OFFSET(SRST_H_HDCP_KEY, 40, 15), + + /* CRU_SOFTRST_CON41 */ + RK3528_CRU_RESET_OFFSET(SRST_A_HDCP, 41, 0), + RK3528_CRU_RESET_OFFSET(SRST_H_HDCP, 41, 1), + RK3528_CRU_RESET_OFFSET(SRST_P_HDCP, 41, 2), + RK3528_CRU_RESET_OFFSET(SRST_H_CVBS, 41, 3), + RK3528_CRU_RESET_OFFSET(SRST_D_CVBS_VOP, 41, 4), + RK3528_CRU_RESET_OFFSET(SRST_D_4X_CVBS_VOP, 41, 5), + RK3528_CRU_RESET_OFFSET(SRST_A_JPEG_DECODER, 41, 6), + RK3528_CRU_RESET_OFFSET(SRST_H_JPEG_DECODER, 41, 7), + RK3528_CRU_RESET_OFFSET(SRST_A_VO_L_BIU, 41, 9), + RK3528_CRU_RESET_OFFSET(SRST_A_MAC_VO, 41, 10), + + /* CRU_SOFTRST_CON42 */ + RK3528_CRU_RESET_OFFSET(SRST_A_JPEG_BIU, 42, 0), + RK3528_CRU_RESET_OFFSET(SRST_H_SAI_I2S3, 42, 1), + RK3528_CRU_RESET_OFFSET(SRST_M_SAI_I2S3, 42, 2), + RK3528_CRU_RESET_OFFSET(SRST_MACPHY, 42, 3), + RK3528_CRU_RESET_OFFSET(SRST_P_VCDCPHY, 42, 4), + RK3528_CRU_RESET_OFFSET(SRST_P_GPIO2, 42, 5), + RK3528_CRU_RESET_OFFSET(SRST_DB_GPIO2, 42, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_VO_IOC, 42, 7), + RK3528_CRU_RESET_OFFSET(SRST_H_SDMMC0, 42, 9), + RK3528_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 42, 11), + RK3528_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 42, 12), + RK3528_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 42, 13), + + /* CRU_SOFTRST_CON43 */ + RK3528_CRU_RESET_OFFSET(SRST_HDMIHDP0, 43, 2), + RK3528_CRU_RESET_OFFSET(SRST_H_USBHOST, 43, 3), + RK3528_CRU_RESET_OFFSET(SRST_H_USBHOST_ARB, 43, 4), + RK3528_CRU_RESET_OFFSET(SRST_HOST_UTMI, 43, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_UART4, 43, 7), + RK3528_CRU_RESET_OFFSET(SRST_S_UART4, 43, 8), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C4, 43, 9), + RK3528_CRU_RESET_OFFSET(SRST_I2C4, 43, 10), + RK3528_CRU_RESET_OFFSET(SRST_P_I2C7, 43, 11), + RK3528_CRU_RESET_OFFSET(SRST_I2C7, 43, 12), + RK3528_CRU_RESET_OFFSET(SRST_P_USBPHY, 43, 13), + RK3528_CRU_RESET_OFFSET(SRST_USBPHY_POR, 43, 14), + RK3528_CRU_RESET_OFFSET(SRST_USBPHY_OTG, 43, 15), + + /* CRU_SOFTRST_CON44 */ + RK3528_CRU_RESET_OFFSET(SRST_USBPHY_HOST, 44, 0), + RK3528_CRU_RESET_OFFSET(SRST_P_DDRPHY_CRU, 44, 4), + RK3528_CRU_RESET_OFFSET(SRST_H_RKVDEC_BIU, 44, 6), + RK3528_CRU_RESET_OFFSET(SRST_A_RKVDEC_BIU, 44, 7), + RK3528_CRU_RESET_OFFSET(SRST_A_RKVDEC, 44, 8), + RK3528_CRU_RESET_OFFSET(SRST_H_RKVDEC, 44, 9), + RK3528_CRU_RESET_OFFSET(SRST_HEVC_CA_RKVDEC, 44, 11), + RK3528_CRU_RESET_OFFSET(SRST_REF_PVTPLL_RKVDEC, 44, 12), + + /* CRU_SOFTRST_CON45 */ + RK3528_CRU_RESET_OFFSET(SRST_P_DDR_BIU, 45, 1), + RK3528_CRU_RESET_OFFSET(SRST_P_DDRC, 45, 2), + RK3528_CRU_RESET_OFFSET(SRST_P_DDRMON, 45, 3), + RK3528_CRU_RESET_OFFSET(SRST_TIMER_DDRMON, 45, 4), + RK3528_CRU_RESET_OFFSET(SRST_P_MSCH_BIU, 45, 5), + RK3528_CRU_RESET_OFFSET(SRST_P_DDR_GRF, 45, 6), + RK3528_CRU_RESET_OFFSET(SRST_P_DDR_HWLP, 45, 8), + RK3528_CRU_RESET_OFFSET(SRST_P_DDRPHY, 45, 9), + RK3528_CRU_RESET_OFFSET(SRST_MSCH_BIU, 45, 10), + RK3528_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL, 45, 11), + RK3528_CRU_RESET_OFFSET(SRST_DDR_UPCTL, 45, 12), + RK3528_CRU_RESET_OFFSET(SRST_DDRMON, 45, 13), + RK3528_CRU_RESET_OFFSET(SRST_A_DDR_SCRAMBLE, 45, 14), + RK3528_CRU_RESET_OFFSET(SRST_A_SPLIT, 45, 15), + + /* CRU_SOFTRST_CON46 */ + RK3528_CRU_RESET_OFFSET(SRST_DDR_PHY, 46, 0), +}; + +int rk3528_reset_bind_lut(struct udevice *pdev, u32 reg_offset, u32 reg_number) +{ + return rockchip_reset_bind_lut(pdev, rk3528_register_offset, + reg_offset, reg_number); +} diff --git a/drivers/reset/rst-rk3576.c b/drivers/reset/rst-rk3576.c new file mode 100644 index 00000000000..a6b83a2fd74 --- /dev/null +++ b/drivers/reset/rst-rk3576.c @@ -0,0 +1,647 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2021 Rockchip Electronics Co., Ltd. + * Copyright (c) 2024 Collabora Ltd. + * Author: Detlev Casanova <detlev.casanova@collabora.com> + * Based on Sebastian Reichel's implementation for RK3588 + */ + +#include <dm.h> +#include <asm/arch-rockchip/clock.h> +#include <dt-bindings/reset/rockchip,rk3576-cru.h> + +/* 0x27200000 + 0x0A00 */ +#define RK3576_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + (reg) * 16 + (bit)) +/* 0x27208000 + 0x0A00 */ +#define RK3576_PHPCRU_RESET_OFFSET(id, reg, bit) [id] = (0x8000 * 4 + (reg) * 16 + (bit)) +/* 0x27210000 + 0x0A00 */ +#define RK3576_SECURENSCRU_RESET_OFFSET(id, reg, bit) [id] = (0x10000 * 4 + (reg) * 16 + (bit)) +/* 0x27220000 + 0x0A00 */ +#define RK3576_PMU1CRU_RESET_OFFSET(id, reg, bit) [id] = (0x20000 * 4 + (reg) * 16 + (bit)) + +/* mapping table for reset ID to register offset */ +static const int rk3576_register_offset[] = { + /* SOFTRST_CON01 */ + RK3576_CRU_RESET_OFFSET(SRST_A_TOP_BIU, 1, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_TOP_BIU, 1, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_TOP_MID_BIU, 1, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_SECURE_HIGH_BIU, 1, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_TOP_BIU, 1, 14), + + /* SOFTRST_CON02 */ + RK3576_CRU_RESET_OFFSET(SRST_H_VO0VOP_CHANNEL_BIU, 2, 0), + RK3576_CRU_RESET_OFFSET(SRST_A_VO0VOP_CHANNEL_BIU, 2, 1), + + /* SOFTRST_CON06 */ + RK3576_CRU_RESET_OFFSET(SRST_BISRINTF, 6, 2), + + /* SOFTRST_CON07 */ + RK3576_CRU_RESET_OFFSET(SRST_H_AUDIO_BIU, 7, 2), + RK3576_CRU_RESET_OFFSET(SRST_H_ASRC_2CH_0, 7, 3), + RK3576_CRU_RESET_OFFSET(SRST_H_ASRC_2CH_1, 7, 4), + RK3576_CRU_RESET_OFFSET(SRST_H_ASRC_4CH_0, 7, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_ASRC_4CH_1, 7, 6), + RK3576_CRU_RESET_OFFSET(SRST_ASRC_2CH_0, 7, 7), + RK3576_CRU_RESET_OFFSET(SRST_ASRC_2CH_1, 7, 8), + RK3576_CRU_RESET_OFFSET(SRST_ASRC_4CH_0, 7, 9), + RK3576_CRU_RESET_OFFSET(SRST_ASRC_4CH_1, 7, 10), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI0_8CH, 7, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI0_8CH, 7, 13), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_RX0, 7, 14), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_RX0, 7, 15), + + /* SOFTRST_CON08 */ + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_RX1, 8, 0), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_RX1, 8, 1), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI1_8CH, 8, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI1_8CH, 8, 6), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI2_2CH, 8, 8), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI2_2CH, 8, 10), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI3_2CH, 8, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI3_2CH, 8, 14), + + /* SOFTRST_CON09 */ + RK3576_CRU_RESET_OFFSET(SRST_M_SAI4_2CH, 9, 0), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI4_2CH, 9, 2), + RK3576_CRU_RESET_OFFSET(SRST_H_ACDCDIG_DSM, 9, 3), + RK3576_CRU_RESET_OFFSET(SRST_M_ACDCDIG_DSM, 9, 4), + RK3576_CRU_RESET_OFFSET(SRST_PDM1, 9, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_PDM1, 9, 7), + RK3576_CRU_RESET_OFFSET(SRST_M_PDM1, 9, 8), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_TX0, 9, 9), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_TX0, 9, 10), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_TX1, 9, 11), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_TX1, 9, 12), + + /* SOFTRST_CON11 */ + RK3576_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 11, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 11, 4), + RK3576_CRU_RESET_OFFSET(SRST_P_CRU, 11, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_CAN0, 11, 6), + RK3576_CRU_RESET_OFFSET(SRST_CAN0, 11, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_CAN1, 11, 8), + RK3576_CRU_RESET_OFFSET(SRST_CAN1, 11, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_INTMUX2BUS, 11, 12), + RK3576_CRU_RESET_OFFSET(SRST_P_VCCIO_IOC, 11, 13), + RK3576_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 11, 14), + RK3576_CRU_RESET_OFFSET(SRST_KEY_SHIFT, 11, 15), + + /* SOFTRST_CON12 */ + RK3576_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C3, 12, 2), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C4, 12, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C5, 12, 4), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C6, 12, 5), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C7, 12, 6), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C8, 12, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_I2C9, 12, 8), + RK3576_CRU_RESET_OFFSET(SRST_P_WDT_BUSMCU, 12, 9), + RK3576_CRU_RESET_OFFSET(SRST_T_WDT_BUSMCU, 12, 10), + RK3576_CRU_RESET_OFFSET(SRST_A_GIC, 12, 11), + RK3576_CRU_RESET_OFFSET(SRST_I2C1, 12, 12), + RK3576_CRU_RESET_OFFSET(SRST_I2C2, 12, 13), + RK3576_CRU_RESET_OFFSET(SRST_I2C3, 12, 14), + RK3576_CRU_RESET_OFFSET(SRST_I2C4, 12, 15), + + /* SOFTRST_CON13 */ + RK3576_CRU_RESET_OFFSET(SRST_I2C5, 13, 0), + RK3576_CRU_RESET_OFFSET(SRST_I2C6, 13, 1), + RK3576_CRU_RESET_OFFSET(SRST_I2C7, 13, 2), + RK3576_CRU_RESET_OFFSET(SRST_I2C8, 13, 3), + RK3576_CRU_RESET_OFFSET(SRST_I2C9, 13, 4), + RK3576_CRU_RESET_OFFSET(SRST_P_SARADC, 13, 6), + RK3576_CRU_RESET_OFFSET(SRST_SARADC, 13, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_TSADC, 13, 8), + RK3576_CRU_RESET_OFFSET(SRST_TSADC, 13, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_UART0, 13, 10), + RK3576_CRU_RESET_OFFSET(SRST_P_UART2, 13, 11), + RK3576_CRU_RESET_OFFSET(SRST_P_UART3, 13, 12), + RK3576_CRU_RESET_OFFSET(SRST_P_UART4, 13, 13), + RK3576_CRU_RESET_OFFSET(SRST_P_UART5, 13, 14), + RK3576_CRU_RESET_OFFSET(SRST_P_UART6, 13, 15), + + /* SOFTRST_CON14 */ + RK3576_CRU_RESET_OFFSET(SRST_P_UART7, 14, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_UART8, 14, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_UART9, 14, 2), + RK3576_CRU_RESET_OFFSET(SRST_P_UART10, 14, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_UART11, 14, 4), + RK3576_CRU_RESET_OFFSET(SRST_S_UART0, 14, 5), + RK3576_CRU_RESET_OFFSET(SRST_S_UART2, 14, 6), + RK3576_CRU_RESET_OFFSET(SRST_S_UART3, 14, 9), + RK3576_CRU_RESET_OFFSET(SRST_S_UART4, 14, 12), + RK3576_CRU_RESET_OFFSET(SRST_S_UART5, 14, 15), + + /* SOFTRST_CON15 */ + RK3576_CRU_RESET_OFFSET(SRST_S_UART6, 15, 2), + RK3576_CRU_RESET_OFFSET(SRST_S_UART7, 15, 5), + RK3576_CRU_RESET_OFFSET(SRST_S_UART8, 15, 8), + RK3576_CRU_RESET_OFFSET(SRST_S_UART9, 15, 9), + RK3576_CRU_RESET_OFFSET(SRST_S_UART10, 15, 10), + RK3576_CRU_RESET_OFFSET(SRST_S_UART11, 15, 11), + RK3576_CRU_RESET_OFFSET(SRST_P_SPI0, 15, 13), + RK3576_CRU_RESET_OFFSET(SRST_P_SPI1, 15, 14), + RK3576_CRU_RESET_OFFSET(SRST_P_SPI2, 15, 15), + + /* SOFTRST_CON16 */ + RK3576_CRU_RESET_OFFSET(SRST_P_SPI3, 16, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_SPI4, 16, 1), + RK3576_CRU_RESET_OFFSET(SRST_SPI0, 16, 2), + RK3576_CRU_RESET_OFFSET(SRST_SPI1, 16, 3), + RK3576_CRU_RESET_OFFSET(SRST_SPI2, 16, 4), + RK3576_CRU_RESET_OFFSET(SRST_SPI3, 16, 5), + RK3576_CRU_RESET_OFFSET(SRST_SPI4, 16, 6), + RK3576_CRU_RESET_OFFSET(SRST_P_WDT0, 16, 7), + RK3576_CRU_RESET_OFFSET(SRST_T_WDT0, 16, 8), + RK3576_CRU_RESET_OFFSET(SRST_P_SYS_GRF, 16, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_PWM1, 16, 10), + RK3576_CRU_RESET_OFFSET(SRST_PWM1, 16, 11), + + /* SOFTRST_CON17 */ + RK3576_CRU_RESET_OFFSET(SRST_P_BUSTIMER0, 17, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_BUSTIMER1, 17, 4), + RK3576_CRU_RESET_OFFSET(SRST_TIMER0, 17, 6), + RK3576_CRU_RESET_OFFSET(SRST_TIMER1, 17, 7), + RK3576_CRU_RESET_OFFSET(SRST_TIMER2, 17, 8), + RK3576_CRU_RESET_OFFSET(SRST_TIMER3, 17, 9), + RK3576_CRU_RESET_OFFSET(SRST_TIMER4, 17, 10), + RK3576_CRU_RESET_OFFSET(SRST_TIMER5, 17, 11), + RK3576_CRU_RESET_OFFSET(SRST_P_BUSIOC, 17, 12), + RK3576_CRU_RESET_OFFSET(SRST_P_MAILBOX0, 17, 13), + RK3576_CRU_RESET_OFFSET(SRST_P_GPIO1, 17, 15), + + /* SOFTRST_CON18 */ + RK3576_CRU_RESET_OFFSET(SRST_GPIO1, 18, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_GPIO2, 18, 1), + RK3576_CRU_RESET_OFFSET(SRST_GPIO2, 18, 2), + RK3576_CRU_RESET_OFFSET(SRST_P_GPIO3, 18, 3), + RK3576_CRU_RESET_OFFSET(SRST_GPIO3, 18, 4), + RK3576_CRU_RESET_OFFSET(SRST_P_GPIO4, 18, 5), + RK3576_CRU_RESET_OFFSET(SRST_GPIO4, 18, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_DECOM, 18, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_DECOM, 18, 8), + RK3576_CRU_RESET_OFFSET(SRST_D_DECOM, 18, 9), + RK3576_CRU_RESET_OFFSET(SRST_TIMER6, 18, 11), + RK3576_CRU_RESET_OFFSET(SRST_TIMER7, 18, 12), + RK3576_CRU_RESET_OFFSET(SRST_TIMER8, 18, 13), + RK3576_CRU_RESET_OFFSET(SRST_TIMER9, 18, 14), + RK3576_CRU_RESET_OFFSET(SRST_TIMER10, 18, 15), + + /* SOFTRST_CON19 */ + RK3576_CRU_RESET_OFFSET(SRST_TIMER11, 19, 0), + RK3576_CRU_RESET_OFFSET(SRST_A_DMAC0, 19, 1), + RK3576_CRU_RESET_OFFSET(SRST_A_DMAC1, 19, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_DMAC2, 19, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_SPINLOCK, 19, 4), + RK3576_CRU_RESET_OFFSET(SRST_REF_PVTPLL_BUS, 19, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_I3C0, 19, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_I3C1, 19, 9), + RK3576_CRU_RESET_OFFSET(SRST_H_BUS_CM0_BIU, 19, 11), + RK3576_CRU_RESET_OFFSET(SRST_F_BUS_CM0_CORE, 19, 12), + RK3576_CRU_RESET_OFFSET(SRST_T_BUS_CM0_JTAG, 19, 13), + + /* SOFTRST_CON20 */ + RK3576_CRU_RESET_OFFSET(SRST_P_INTMUX2PMU, 20, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_INTMUX2DDR, 20, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_PVTPLL_BUS, 20, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_PWM2, 20, 4), + RK3576_CRU_RESET_OFFSET(SRST_PWM2, 20, 5), + RK3576_CRU_RESET_OFFSET(SRST_FREQ_PWM1, 20, 8), + RK3576_CRU_RESET_OFFSET(SRST_COUNTER_PWM1, 20, 9), + RK3576_CRU_RESET_OFFSET(SRST_I3C0, 20, 12), + RK3576_CRU_RESET_OFFSET(SRST_I3C1, 20, 13), + + /* SOFTRST_CON21 */ + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_MON_CH0, 21, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_BIU, 21, 2), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_UPCTL_CH0, 21, 3), + RK3576_CRU_RESET_OFFSET(SRST_TM_DDR_MON_CH0, 21, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 21, 5), + RK3576_CRU_RESET_OFFSET(SRST_DFI_CH0, 21, 6), + RK3576_CRU_RESET_OFFSET(SRST_DDR_MON_CH0, 21, 10), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_HWLP_CH0, 21, 13), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_MON_CH1, 21, 14), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_HWLP_CH1, 21, 15), + + /* SOFTRST_CON22 */ + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_UPCTL_CH1, 22, 0), + RK3576_CRU_RESET_OFFSET(SRST_TM_DDR_MON_CH1, 22, 1), + RK3576_CRU_RESET_OFFSET(SRST_DFI_CH1, 22, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR01_MSCH0, 22, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR01_MSCH1, 22, 4), + RK3576_CRU_RESET_OFFSET(SRST_DDR_MON_CH1, 22, 6), + RK3576_CRU_RESET_OFFSET(SRST_DDR_SCRAMBLE_CH0, 22, 9), + RK3576_CRU_RESET_OFFSET(SRST_DDR_SCRAMBLE_CH1, 22, 10), + RK3576_CRU_RESET_OFFSET(SRST_P_AHB2APB, 22, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_AHB2APB, 22, 13), + RK3576_CRU_RESET_OFFSET(SRST_H_DDR_BIU, 22, 14), + RK3576_CRU_RESET_OFFSET(SRST_F_DDR_CM0_CORE, 22, 15), + + /* SOFTRST_CON23 */ + RK3576_CRU_RESET_OFFSET(SRST_P_DDR01_MSCH0, 23, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR01_MSCH1, 23, 2), + RK3576_CRU_RESET_OFFSET(SRST_DDR_TIMER0, 23, 4), + RK3576_CRU_RESET_OFFSET(SRST_DDR_TIMER1, 23, 5), + RK3576_CRU_RESET_OFFSET(SRST_T_WDT_DDR, 23, 6), + RK3576_CRU_RESET_OFFSET(SRST_P_WDT, 23, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_TIMER, 23, 8), + RK3576_CRU_RESET_OFFSET(SRST_T_DDR_CM0_JTAG, 23, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_DDR_GRF, 23, 11), + + /* SOFTRST_CON25 */ + RK3576_CRU_RESET_OFFSET(SRST_DDR_UPCTL_CH0, 25, 1), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_0_CH0, 25, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_1_CH0, 25, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_2_CH0, 25, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_3_CH0, 25, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_4_CH0, 25, 6), + + /* SOFTRST_CON26 */ + RK3576_CRU_RESET_OFFSET(SRST_DDR_UPCTL_CH1, 26, 1), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_0_CH1, 26, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_1_CH1, 26, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_2_CH1, 26, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_3_CH1, 26, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_UPCTL_4_CH1, 26, 6), + + /* SOFTRST_CON27 */ + RK3576_CRU_RESET_OFFSET(SRST_REF_PVTPLL_DDR, 27, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_PVTPLL_DDR, 27, 1), + + /* SOFTRST_CON28 */ + RK3576_CRU_RESET_OFFSET(SRST_A_RKNN0, 28, 9), + RK3576_CRU_RESET_OFFSET(SRST_A_RKNN0_BIU, 28, 11), + RK3576_CRU_RESET_OFFSET(SRST_L_RKNN0_BIU, 28, 12), + + /* SOFTRST_CON29 */ + RK3576_CRU_RESET_OFFSET(SRST_A_RKNN1, 29, 0), + RK3576_CRU_RESET_OFFSET(SRST_A_RKNN1_BIU, 29, 2), + RK3576_CRU_RESET_OFFSET(SRST_L_RKNN1_BIU, 29, 3), + + /* SOFTRST_CON31 */ + RK3576_CRU_RESET_OFFSET(SRST_NPU_DAP, 31, 0), + RK3576_CRU_RESET_OFFSET(SRST_L_NPUSUBSYS_BIU, 31, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_NPUTOP_BIU, 31, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_NPU_TIMER, 31, 10), + RK3576_CRU_RESET_OFFSET(SRST_NPUTIMER0, 31, 12), + RK3576_CRU_RESET_OFFSET(SRST_NPUTIMER1, 31, 13), + RK3576_CRU_RESET_OFFSET(SRST_P_NPU_WDT, 31, 14), + RK3576_CRU_RESET_OFFSET(SRST_T_NPU_WDT, 31, 15), + + /* SOFTRST_CON32 */ + RK3576_CRU_RESET_OFFSET(SRST_A_RKNN_CBUF, 32, 0), + RK3576_CRU_RESET_OFFSET(SRST_A_RVCORE0, 32, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_NPU_GRF, 32, 2), + RK3576_CRU_RESET_OFFSET(SRST_P_PVTPLL_NPU, 32, 3), + RK3576_CRU_RESET_OFFSET(SRST_NPU_PVTPLL, 32, 4), + RK3576_CRU_RESET_OFFSET(SRST_H_NPU_CM0_BIU, 32, 6), + RK3576_CRU_RESET_OFFSET(SRST_F_NPU_CM0_CORE, 32, 7), + RK3576_CRU_RESET_OFFSET(SRST_T_NPU_CM0_JTAG, 32, 8), + RK3576_CRU_RESET_OFFSET(SRST_A_RKNNTOP_BIU, 32, 11), + RK3576_CRU_RESET_OFFSET(SRST_H_RKNN_CBUF, 32, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_RKNNTOP_BIU, 32, 13), + + /* SOFTRST_CON33 */ + RK3576_CRU_RESET_OFFSET(SRST_H_NVM_BIU, 33, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_NVM_BIU, 33, 3), + RK3576_CRU_RESET_OFFSET(SRST_S_FSPI, 33, 6), + RK3576_CRU_RESET_OFFSET(SRST_H_FSPI, 33, 7), + RK3576_CRU_RESET_OFFSET(SRST_C_EMMC, 33, 8), + RK3576_CRU_RESET_OFFSET(SRST_H_EMMC, 33, 9), + RK3576_CRU_RESET_OFFSET(SRST_A_EMMC, 33, 10), + RK3576_CRU_RESET_OFFSET(SRST_B_EMMC, 33, 11), + RK3576_CRU_RESET_OFFSET(SRST_T_EMMC, 33, 12), + + /* SOFTRST_CON34 */ + RK3576_CRU_RESET_OFFSET(SRST_P_GRF, 34, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_PHP_BIU, 34, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_PHP_BIU, 34, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_PCIE0, 34, 13), + RK3576_CRU_RESET_OFFSET(SRST_PCIE0_POWER_UP, 34, 15), + + /* SOFTRST_CON35 */ + RK3576_CRU_RESET_OFFSET(SRST_A_USB3OTG1, 35, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_MMU0, 35, 11), + RK3576_CRU_RESET_OFFSET(SRST_A_SLV_MMU0, 35, 13), + RK3576_CRU_RESET_OFFSET(SRST_A_MMU1, 35, 14), + + /* SOFTRST_CON36 */ + RK3576_CRU_RESET_OFFSET(SRST_A_SLV_MMU1, 36, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_PCIE1, 36, 7), + RK3576_CRU_RESET_OFFSET(SRST_PCIE1_POWER_UP, 36, 9), + + /* SOFTRST_CON37 */ + RK3576_CRU_RESET_OFFSET(SRST_RXOOB0, 37, 0), + RK3576_CRU_RESET_OFFSET(SRST_RXOOB1, 37, 1), + RK3576_CRU_RESET_OFFSET(SRST_PMALIVE0, 37, 2), + RK3576_CRU_RESET_OFFSET(SRST_PMALIVE1, 37, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_SATA0, 37, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_SATA1, 37, 5), + RK3576_CRU_RESET_OFFSET(SRST_ASIC1, 37, 6), + RK3576_CRU_RESET_OFFSET(SRST_ASIC0, 37, 7), + + /* SOFTRST_CON40 */ + RK3576_CRU_RESET_OFFSET(SRST_P_CSIDPHY1, 40, 2), + RK3576_CRU_RESET_OFFSET(SRST_SCAN_CSIDPHY1, 40, 3), + + /* SOFTRST_CON42 */ + RK3576_CRU_RESET_OFFSET(SRST_P_SDGMAC_GRF, 42, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_SDGMAC_BIU, 42, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_SDGMAC_BIU, 42, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_SDGMAC_BIU, 42, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_GMAC0, 42, 7), + RK3576_CRU_RESET_OFFSET(SRST_A_GMAC1, 42, 8), + RK3576_CRU_RESET_OFFSET(SRST_P_GMAC0, 42, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_GMAC1, 42, 10), + RK3576_CRU_RESET_OFFSET(SRST_H_SDIO, 42, 12), + + /* SOFTRST_CON43 */ + RK3576_CRU_RESET_OFFSET(SRST_H_SDMMC0, 43, 2), + RK3576_CRU_RESET_OFFSET(SRST_S_FSPI1, 43, 3), + RK3576_CRU_RESET_OFFSET(SRST_H_FSPI1, 43, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_DSMC_BIU, 43, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_DSMC, 43, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_DSMC, 43, 8), + RK3576_CRU_RESET_OFFSET(SRST_H_HSGPIO, 43, 10), + RK3576_CRU_RESET_OFFSET(SRST_HSGPIO, 43, 11), + RK3576_CRU_RESET_OFFSET(SRST_A_HSGPIO, 43, 13), + + /* SOFTRST_CON45 */ + RK3576_CRU_RESET_OFFSET(SRST_H_RKVDEC, 45, 3), + RK3576_CRU_RESET_OFFSET(SRST_H_RKVDEC_BIU, 45, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_RKVDEC_BIU, 45, 6), + RK3576_CRU_RESET_OFFSET(SRST_RKVDEC_HEVC_CA, 45, 8), + RK3576_CRU_RESET_OFFSET(SRST_RKVDEC_CORE, 45, 9), + + /* SOFTRST_CON47 */ + RK3576_CRU_RESET_OFFSET(SRST_A_USB_BIU, 47, 3), + RK3576_CRU_RESET_OFFSET(SRST_P_USBUFS_BIU, 47, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_USB3OTG0, 47, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_UFS_BIU, 47, 10), + RK3576_CRU_RESET_OFFSET(SRST_A_MMU2, 47, 12), + RK3576_CRU_RESET_OFFSET(SRST_A_SLV_MMU2, 47, 13), + RK3576_CRU_RESET_OFFSET(SRST_A_UFS_SYS, 47, 15), + + /* SOFTRST_CON48 */ + RK3576_CRU_RESET_OFFSET(SRST_A_UFS, 48, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_USBUFS_GRF, 48, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_UFS_GRF, 48, 2), + + /* SOFTRST_CON49 */ + RK3576_CRU_RESET_OFFSET(SRST_H_VPU_BIU, 49, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_JPEG_BIU, 49, 7), + RK3576_CRU_RESET_OFFSET(SRST_A_RGA_BIU, 49, 10), + RK3576_CRU_RESET_OFFSET(SRST_A_VDPP_BIU, 49, 11), + RK3576_CRU_RESET_OFFSET(SRST_A_EBC_BIU, 49, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_RGA2E_0, 49, 13), + RK3576_CRU_RESET_OFFSET(SRST_A_RGA2E_0, 49, 14), + RK3576_CRU_RESET_OFFSET(SRST_CORE_RGA2E_0, 49, 15), + + /* SOFTRST_CON50 */ + RK3576_CRU_RESET_OFFSET(SRST_A_JPEG, 50, 0), + RK3576_CRU_RESET_OFFSET(SRST_H_JPEG, 50, 1), + RK3576_CRU_RESET_OFFSET(SRST_H_VDPP, 50, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_VDPP, 50, 3), + RK3576_CRU_RESET_OFFSET(SRST_CORE_VDPP, 50, 4), + RK3576_CRU_RESET_OFFSET(SRST_H_RGA2E_1, 50, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_RGA2E_1, 50, 6), + RK3576_CRU_RESET_OFFSET(SRST_CORE_RGA2E_1, 50, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_EBC, 50, 10), + RK3576_CRU_RESET_OFFSET(SRST_A_EBC, 50, 11), + RK3576_CRU_RESET_OFFSET(SRST_D_EBC, 50, 12), + + /* SOFTRST_CON51 */ + RK3576_CRU_RESET_OFFSET(SRST_H_VEPU0_BIU, 51, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_VEPU0_BIU, 51, 3), + RK3576_CRU_RESET_OFFSET(SRST_H_VEPU0, 51, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_VEPU0, 51, 5), + RK3576_CRU_RESET_OFFSET(SRST_VEPU0_CORE, 51, 6), + + /* SOFTRST_CON53 */ + RK3576_CRU_RESET_OFFSET(SRST_A_VI_BIU, 53, 3), + RK3576_CRU_RESET_OFFSET(SRST_H_VI_BIU, 53, 4), + RK3576_CRU_RESET_OFFSET(SRST_P_VI_BIU, 53, 5), + RK3576_CRU_RESET_OFFSET(SRST_D_VICAP, 53, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_VICAP, 53, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_VICAP, 53, 8), + RK3576_CRU_RESET_OFFSET(SRST_ISP0, 53, 10), + RK3576_CRU_RESET_OFFSET(SRST_ISP0_VICAP, 53, 11), + + /* SOFTRST_CON54 */ + RK3576_CRU_RESET_OFFSET(SRST_CORE_VPSS, 54, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_CSI_HOST_0, 54, 4), + RK3576_CRU_RESET_OFFSET(SRST_P_CSI_HOST_1, 54, 5), + RK3576_CRU_RESET_OFFSET(SRST_P_CSI_HOST_2, 54, 6), + RK3576_CRU_RESET_OFFSET(SRST_P_CSI_HOST_3, 54, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_CSI_HOST_4, 54, 8), + + /* SOFTRST_CON59 */ + RK3576_CRU_RESET_OFFSET(SRST_CIFIN, 59, 0), + RK3576_CRU_RESET_OFFSET(SRST_VICAP_I0CLK, 59, 1), + RK3576_CRU_RESET_OFFSET(SRST_VICAP_I1CLK, 59, 2), + RK3576_CRU_RESET_OFFSET(SRST_VICAP_I2CLK, 59, 3), + RK3576_CRU_RESET_OFFSET(SRST_VICAP_I3CLK, 59, 4), + RK3576_CRU_RESET_OFFSET(SRST_VICAP_I4CLK, 59, 5), + + /* SOFTRST_CON61 */ + RK3576_CRU_RESET_OFFSET(SRST_A_VOP_BIU, 61, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_VOP2_BIU, 61, 5), + RK3576_CRU_RESET_OFFSET(SRST_H_VOP_BIU, 61, 6), + RK3576_CRU_RESET_OFFSET(SRST_P_VOP_BIU, 61, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_VOP, 61, 8), + RK3576_CRU_RESET_OFFSET(SRST_A_VOP, 61, 9), + RK3576_CRU_RESET_OFFSET(SRST_D_VP0, 61, 13), + + /* SOFTRST_CON62 */ + RK3576_CRU_RESET_OFFSET(SRST_D_VP1, 62, 0), + RK3576_CRU_RESET_OFFSET(SRST_D_VP2, 62, 1), + RK3576_CRU_RESET_OFFSET(SRST_P_VOP2_BIU, 62, 2), + RK3576_CRU_RESET_OFFSET(SRST_P_VOPGRF, 62, 3), + + /* SOFTRST_CON63 */ + RK3576_CRU_RESET_OFFSET(SRST_H_VO0_BIU, 63, 5), + RK3576_CRU_RESET_OFFSET(SRST_P_VO0_BIU, 63, 7), + RK3576_CRU_RESET_OFFSET(SRST_A_HDCP0_BIU, 63, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_VO0_GRF, 63, 10), + RK3576_CRU_RESET_OFFSET(SRST_A_HDCP0, 63, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_HDCP0, 63, 13), + RK3576_CRU_RESET_OFFSET(SRST_HDCP0, 63, 14), + + /* SOFTRST_CON64 */ + RK3576_CRU_RESET_OFFSET(SRST_P_DSIHOST0, 64, 5), + RK3576_CRU_RESET_OFFSET(SRST_DSIHOST0, 64, 6), + RK3576_CRU_RESET_OFFSET(SRST_P_HDMITX0, 64, 7), + RK3576_CRU_RESET_OFFSET(SRST_HDMITX0_REF, 64, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_EDP0, 64, 13), + RK3576_CRU_RESET_OFFSET(SRST_EDP0_24M, 64, 14), + + /* SOFTRST_CON65 */ + RK3576_CRU_RESET_OFFSET(SRST_M_SAI5_8CH, 65, 4), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI5_8CH, 65, 5), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI6_8CH, 65, 8), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI6_8CH, 65, 9), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_TX2, 65, 10), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_TX2, 65, 13), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_RX2, 65, 14), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_RX2, 65, 15), + + /* SOFTRST_CON66 */ + RK3576_CRU_RESET_OFFSET(SRST_H_SAI8_8CH, 66, 0), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI8_8CH, 66, 2), + + /* SOFTRST_CON67 */ + RK3576_CRU_RESET_OFFSET(SRST_H_VO1_BIU, 67, 5), + RK3576_CRU_RESET_OFFSET(SRST_P_VO1_BIU, 67, 6), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI7_8CH, 67, 9), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI7_8CH, 67, 10), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_TX3, 67, 11), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_TX4, 67, 12), + RK3576_CRU_RESET_OFFSET(SRST_H_SPDIF_TX5, 67, 13), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_TX3, 67, 14), + + /* SOFTRST_CON68 */ + RK3576_CRU_RESET_OFFSET(SRST_DP0, 68, 0), + RK3576_CRU_RESET_OFFSET(SRST_P_VO1_GRF, 68, 2), + RK3576_CRU_RESET_OFFSET(SRST_A_HDCP1_BIU, 68, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_HDCP1, 68, 4), + RK3576_CRU_RESET_OFFSET(SRST_H_HDCP1, 68, 5), + RK3576_CRU_RESET_OFFSET(SRST_HDCP1, 68, 6), + RK3576_CRU_RESET_OFFSET(SRST_H_SAI9_8CH, 68, 9), + RK3576_CRU_RESET_OFFSET(SRST_M_SAI9_8CH, 68, 11), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_TX4, 68, 12), + RK3576_CRU_RESET_OFFSET(SRST_M_SPDIF_TX5, 68, 13), + + /* SOFTRST_CON69 */ + RK3576_CRU_RESET_OFFSET(SRST_GPU, 69, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_S_GPU_BIU, 69, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_M0_GPU_BIU, 69, 7), + RK3576_CRU_RESET_OFFSET(SRST_P_GPU_BIU, 69, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_GPU_GRF, 69, 13), + RK3576_CRU_RESET_OFFSET(SRST_GPU_PVTPLL, 69, 14), + RK3576_CRU_RESET_OFFSET(SRST_P_PVTPLL_GPU, 69, 15), + + /* SOFTRST_CON72 */ + RK3576_CRU_RESET_OFFSET(SRST_A_CENTER_BIU, 72, 4), + RK3576_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 72, 5), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_SHAREMEM, 72, 6), + RK3576_CRU_RESET_OFFSET(SRST_A_DDR_SHAREMEM_BIU, 72, 7), + RK3576_CRU_RESET_OFFSET(SRST_H_CENTER_BIU, 72, 8), + RK3576_CRU_RESET_OFFSET(SRST_P_CENTER_GRF, 72, 9), + RK3576_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 72, 10), + RK3576_CRU_RESET_OFFSET(SRST_P_SHAREMEM, 72, 11), + RK3576_CRU_RESET_OFFSET(SRST_P_CENTER_BIU, 72, 12), + + /* SOFTRST_CON75 */ + RK3576_CRU_RESET_OFFSET(SRST_LINKSYM_HDMITXPHY0, 75, 1), + + /* SOFTRST_CON78 */ + RK3576_CRU_RESET_OFFSET(SRST_DP0_PIXELCLK, 78, 1), + RK3576_CRU_RESET_OFFSET(SRST_PHY_DP0_TX, 78, 2), + RK3576_CRU_RESET_OFFSET(SRST_DP1_PIXELCLK, 78, 3), + RK3576_CRU_RESET_OFFSET(SRST_DP2_PIXELCLK, 78, 4), + + /* SOFTRST_CON79 */ + RK3576_CRU_RESET_OFFSET(SRST_H_VEPU1_BIU, 79, 1), + RK3576_CRU_RESET_OFFSET(SRST_A_VEPU1_BIU, 79, 2), + RK3576_CRU_RESET_OFFSET(SRST_H_VEPU1, 79, 3), + RK3576_CRU_RESET_OFFSET(SRST_A_VEPU1, 79, 4), + RK3576_CRU_RESET_OFFSET(SRST_VEPU1_CORE, 79, 5), + + /* PPLL_SOFTRST_CON00 */ + RK3576_PHPCRU_RESET_OFFSET(SRST_P_PHPPHY_CRU, 0, 1), + RK3576_PHPCRU_RESET_OFFSET(SRST_P_APB2ASB_SLV_CHIP_TOP, 0, 3), + RK3576_PHPCRU_RESET_OFFSET(SRST_P_PCIE2_COMBOPHY0, 0, 5), + RK3576_PHPCRU_RESET_OFFSET(SRST_P_PCIE2_COMBOPHY0_GRF, 0, 6), + RK3576_PHPCRU_RESET_OFFSET(SRST_P_PCIE2_COMBOPHY1, 0, 7), + RK3576_PHPCRU_RESET_OFFSET(SRST_P_PCIE2_COMBOPHY1_GRF, 0, 8), + + /* PPLL_SOFTRST_CON01 */ + RK3576_PHPCRU_RESET_OFFSET(SRST_PCIE0_PIPE_PHY, 1, 5), + RK3576_PHPCRU_RESET_OFFSET(SRST_PCIE1_PIPE_PHY, 1, 8), + + /* SECURENS_SOFTRST_CON00 */ + RK3576_SECURENSCRU_RESET_OFFSET(SRST_H_CRYPTO_NS, 0, 3), + RK3576_SECURENSCRU_RESET_OFFSET(SRST_H_TRNG_NS, 0, 4), + RK3576_SECURENSCRU_RESET_OFFSET(SRST_P_OTPC_NS, 0, 8), + RK3576_SECURENSCRU_RESET_OFFSET(SRST_OTPC_NS, 0, 9), + + /* PMU1_SOFTRST_CON00 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_HDPTX_GRF, 0, 0), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_HDPTX_APB, 0, 1), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_MIPI_DCPHY, 0, 2), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_DCPHY_GRF, 0, 3), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_BOT0_APB2ASB, 0, 4), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_BOT1_APB2ASB, 0, 5), + RK3576_PMU1CRU_RESET_OFFSET(SRST_USB2DEBUG, 0, 6), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_CSIPHY_GRF, 0, 7), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_CSIPHY, 0, 8), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_USBPHY_GRF_0, 0, 9), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_USBPHY_GRF_1, 0, 10), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_USBDP_GRF, 0, 11), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_USBDPPHY, 0, 12), + RK3576_PMU1CRU_RESET_OFFSET(SRST_USBDP_COMBO_PHY_INIT, 0, 15), + + /* PMU1_SOFTRST_CON01 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_USBDP_COMBO_PHY_CMN, 1, 0), + RK3576_PMU1CRU_RESET_OFFSET(SRST_USBDP_COMBO_PHY_LANE, 1, 1), + RK3576_PMU1CRU_RESET_OFFSET(SRST_USBDP_COMBO_PHY_PCS, 1, 2), + RK3576_PMU1CRU_RESET_OFFSET(SRST_M_MIPI_DCPHY, 1, 3), + RK3576_PMU1CRU_RESET_OFFSET(SRST_S_MIPI_DCPHY, 1, 4), + RK3576_PMU1CRU_RESET_OFFSET(SRST_SCAN_CSIPHY, 1, 5), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_VCCIO6_IOC, 1, 6), + RK3576_PMU1CRU_RESET_OFFSET(SRST_OTGPHY_0, 1, 7), + RK3576_PMU1CRU_RESET_OFFSET(SRST_OTGPHY_1, 1, 8), + RK3576_PMU1CRU_RESET_OFFSET(SRST_HDPTX_INIT, 1, 9), + RK3576_PMU1CRU_RESET_OFFSET(SRST_HDPTX_CMN, 1, 10), + RK3576_PMU1CRU_RESET_OFFSET(SRST_HDPTX_LANE, 1, 11), + RK3576_PMU1CRU_RESET_OFFSET(SRST_HDMITXHDP, 1, 13), + + /* PMU1_SOFTRST_CON02 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_MPHY_INIT, 2, 0), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_MPHY_GRF, 2, 1), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_VCCIO7_IOC, 2, 3), + + /* PMU1_SOFTRST_CON03 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_H_PMU1_BIU, 3, 9), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU1_NIU, 3, 10), + RK3576_PMU1CRU_RESET_OFFSET(SRST_H_PMU_CM0_BIU, 3, 11), + RK3576_PMU1CRU_RESET_OFFSET(SRST_PMU_CM0_CORE, 3, 12), + RK3576_PMU1CRU_RESET_OFFSET(SRST_PMU_CM0_JTAG, 3, 13), + + /* PMU1_SOFTRST_CON04 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_CRU_PMU1, 4, 1), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU1_GRF, 4, 3), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU1_IOC, 4, 4), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU1WDT, 4, 5), + RK3576_PMU1CRU_RESET_OFFSET(SRST_T_PMU1WDT, 4, 6), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMUTIMER, 4, 7), + RK3576_PMU1CRU_RESET_OFFSET(SRST_PMUTIMER0, 4, 9), + RK3576_PMU1CRU_RESET_OFFSET(SRST_PMUTIMER1, 4, 10), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU1PWM, 4, 11), + RK3576_PMU1CRU_RESET_OFFSET(SRST_PMU1PWM, 4, 12), + + /* PMU1_SOFTRST_CON05 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_I2C0, 5, 1), + RK3576_PMU1CRU_RESET_OFFSET(SRST_I2C0, 5, 2), + RK3576_PMU1CRU_RESET_OFFSET(SRST_S_UART1, 5, 5), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_UART1, 5, 6), + RK3576_PMU1CRU_RESET_OFFSET(SRST_PDM0, 5, 13), + RK3576_PMU1CRU_RESET_OFFSET(SRST_H_PDM0, 5, 15), + + /* PMU1_SOFTRST_CON06 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_M_PDM0, 6, 0), + RK3576_PMU1CRU_RESET_OFFSET(SRST_H_VAD, 6, 1), + + /* PMU1_SOFTRST_CON07 */ + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU0GRF, 7, 4), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_PMU0IOC, 7, 5), + RK3576_PMU1CRU_RESET_OFFSET(SRST_P_GPIO0, 7, 6), + RK3576_PMU1CRU_RESET_OFFSET(SRST_DB_GPIO0, 7, 7), +}; + +int rk3576_reset_bind_lut(struct udevice *pdev, u32 reg_offset, u32 reg_number) +{ + return rockchip_reset_bind_lut(pdev, rk3576_register_offset, + reg_offset, reg_number); +} diff --git a/drivers/rng/rockchip_rng.c b/drivers/rng/rockchip_rng.c index 2426648fbd5..d854ea90044 100644 --- 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_trngv1_soc_data = { .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, }; @@ -313,13 +382,21 @@ static const struct udevice_id rockchip_rng_match[] = { .data = (ulong)&rk_cryptov1_soc_data, }, { + .compatible = "rockchip,rk3568-rng", + .data = (ulong)&rk_cryptov2_soc_data, + }, + { .compatible = "rockchip,cryptov2-rng", .data = (ulong)&rk_cryptov2_soc_data, }, { - .compatible = "rockchip,trngv1", + .compatible = "rockchip,rk3588-rng", .data = (ulong)&rk_trngv1_soc_data, }, + { + .compatible = "rockchip,rkrng", + .data = (ulong)&rkrng_soc_data, + }, {}, }; diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index c815764c2bc..46a83141481 100644 --- 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. diff --git a/dts/upstream/Bindings/arm/rockchip.yaml b/dts/upstream/Bindings/arm/rockchip.yaml index 522a6f0450e..0f4ca08d9ae 100644 --- a/dts/upstream/Bindings/arm/rockchip.yaml +++ b/dts/upstream/Bindings/arm/rockchip.yaml @@ -236,6 +236,11 @@ properties: - firefly,roc-rk3399-pc-plus - const: rockchip,rk3399 + - description: Firefly ROC-RK3576-PC + items: + - const: firefly,roc-rk3576-pc + - const: rockchip,rk3576 + - description: Firefly Station M2 items: - const: firefly,rk3566-roc-pc diff --git a/dts/upstream/Bindings/clock/rockchip,rk3528-cru.yaml b/dts/upstream/Bindings/clock/rockchip,rk3528-cru.yaml new file mode 100644 index 00000000000..5a3ec902351 --- /dev/null +++ b/dts/upstream/Bindings/clock/rockchip,rk3528-cru.yaml @@ -0,0 +1,64 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/rockchip,rk3528-cru.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Rockchip RK3528 Clock and Reset Controller + +maintainers: + - Yao Zi <ziyao@disroot.org> + +description: | + The RK3528 clock controller generates the clock and also implements a reset + controller for SoC peripherals. For example, it provides SCLK_UART0 and + PCLK_UART0 as well as SRST_P_UART0 and SRST_S_UART0 for the first UART + module. + Each clock is assigned an identifier, consumer nodes can use it to specify + the clock. All available clock and reset IDs are defined in dt-binding + headers. + +properties: + compatible: + const: rockchip,rk3528-cru + + reg: + maxItems: 1 + + clocks: + items: + - description: External 24MHz oscillator clock + - description: > + 50MHz clock generated by PHY module, for generating GMAC0 clocks only. + + clock-names: + items: + - const: xin24m + - const: gmac0 + + "#clock-cells": + const: 1 + + "#reset-cells": + const: 1 + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + - "#reset-cells" + +additionalProperties: false + +examples: + - | + clock-controller@ff4a0000 { + compatible = "rockchip,rk3528-cru"; + reg = <0xff4a0000 0x30000>; + clocks = <&xin24m>, <&gmac0_clk>; + clock-names = "xin24m", "gmac0"; + #clock-cells = <1>; + #reset-cells = <1>; + }; diff --git a/dts/upstream/include/dt-bindings/clock/rockchip,rk3528-cru.h b/dts/upstream/include/dt-bindings/clock/rockchip,rk3528-cru.h new file mode 100644 index 00000000000..55a448f5ed6 --- /dev/null +++ b/dts/upstream/include/dt-bindings/clock/rockchip,rk3528-cru.h @@ -0,0 +1,453 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022 Rockchip Electronics Co. Ltd. + * Copyright (c) 2024 Yao Zi <ziyao@disroot.org> + * Author: Joseph Chen <chenjh@rock-chips.com> + */ + +#ifndef _DT_BINDINGS_CLK_ROCKCHIP_RK3528_H +#define _DT_BINDINGS_CLK_ROCKCHIP_RK3528_H + +/* cru-clocks indices */ +#define PLL_APLL 0 +#define PLL_CPLL 1 +#define PLL_GPLL 2 +#define PLL_PPLL 3 +#define PLL_DPLL 4 +#define ARMCLK 5 +#define XIN_OSC0_HALF 6 +#define CLK_MATRIX_50M_SRC 7 +#define CLK_MATRIX_100M_SRC 8 +#define CLK_MATRIX_150M_SRC 9 +#define CLK_MATRIX_200M_SRC 10 +#define CLK_MATRIX_250M_SRC 11 +#define CLK_MATRIX_300M_SRC 12 +#define CLK_MATRIX_339M_SRC 13 +#define CLK_MATRIX_400M_SRC 14 +#define CLK_MATRIX_500M_SRC 15 +#define CLK_MATRIX_600M_SRC 16 +#define CLK_UART0_SRC 17 +#define CLK_UART0_FRAC 18 +#define SCLK_UART0 19 +#define CLK_UART1_SRC 20 +#define CLK_UART1_FRAC 21 +#define SCLK_UART1 22 +#define CLK_UART2_SRC 23 +#define CLK_UART2_FRAC 24 +#define SCLK_UART2 25 +#define CLK_UART3_SRC 26 +#define CLK_UART3_FRAC 27 +#define SCLK_UART3 28 +#define CLK_UART4_SRC 29 +#define CLK_UART4_FRAC 30 +#define SCLK_UART4 31 +#define CLK_UART5_SRC 32 +#define CLK_UART5_FRAC 33 +#define SCLK_UART5 34 +#define CLK_UART6_SRC 35 +#define CLK_UART6_FRAC 36 +#define SCLK_UART6 37 +#define CLK_UART7_SRC 38 +#define CLK_UART7_FRAC 39 +#define SCLK_UART7 40 +#define CLK_I2S0_2CH_SRC 41 +#define CLK_I2S0_2CH_FRAC 42 +#define MCLK_I2S0_2CH_SAI_SRC 43 +#define CLK_I2S3_8CH_SRC 44 +#define CLK_I2S3_8CH_FRAC 45 +#define MCLK_I2S3_8CH_SAI_SRC 46 +#define CLK_I2S1_8CH_SRC 47 +#define CLK_I2S1_8CH_FRAC 48 +#define MCLK_I2S1_8CH_SAI_SRC 49 +#define CLK_I2S2_2CH_SRC 50 +#define CLK_I2S2_2CH_FRAC 51 +#define MCLK_I2S2_2CH_SAI_SRC 52 +#define CLK_SPDIF_SRC 53 +#define CLK_SPDIF_FRAC 54 +#define MCLK_SPDIF_SRC 55 +#define DCLK_VOP_SRC0 56 +#define DCLK_VOP_SRC1 57 +#define CLK_HSM 58 +#define CLK_CORE_SRC_ACS 59 +#define CLK_CORE_SRC_PVTMUX 60 +#define CLK_CORE_SRC 61 +#define CLK_CORE 62 +#define ACLK_M_CORE_BIU 63 +#define CLK_CORE_PVTPLL_SRC 64 +#define PCLK_DBG 65 +#define SWCLKTCK 66 +#define CLK_SCANHS_CORE 67 +#define CLK_SCANHS_ACLKM_CORE 68 +#define CLK_SCANHS_PCLK_DBG 69 +#define CLK_SCANHS_PCLK_CPU_BIU 70 +#define PCLK_CPU_ROOT 71 +#define PCLK_CORE_GRF 72 +#define PCLK_DAPLITE_BIU 73 +#define PCLK_CPU_BIU 74 +#define CLK_REF_PVTPLL_CORE 75 +#define ACLK_BUS_VOPGL_ROOT 76 +#define ACLK_BUS_VOPGL_BIU 77 +#define ACLK_BUS_H_ROOT 78 +#define ACLK_BUS_H_BIU 79 +#define ACLK_BUS_ROOT 80 +#define HCLK_BUS_ROOT 81 +#define PCLK_BUS_ROOT 82 +#define ACLK_BUS_M_ROOT 83 +#define ACLK_SYSMEM_BIU 84 +#define CLK_TIMER_ROOT 85 +#define ACLK_BUS_BIU 86 +#define HCLK_BUS_BIU 87 +#define PCLK_BUS_BIU 88 +#define PCLK_DFT2APB 89 +#define PCLK_BUS_GRF 90 +#define ACLK_BUS_M_BIU 91 +#define ACLK_GIC 92 +#define ACLK_SPINLOCK 93 +#define ACLK_DMAC 94 +#define PCLK_TIMER 95 +#define CLK_TIMER0 96 +#define CLK_TIMER1 97 +#define CLK_TIMER2 98 +#define CLK_TIMER3 99 +#define CLK_TIMER4 100 +#define CLK_TIMER5 101 +#define PCLK_JDBCK_DAP 102 +#define CLK_JDBCK_DAP 103 +#define PCLK_WDT_NS 104 +#define TCLK_WDT_NS 105 +#define HCLK_TRNG_NS 106 +#define PCLK_UART0 107 +#define PCLK_DMA2DDR 108 +#define ACLK_DMA2DDR 109 +#define PCLK_PWM0 110 +#define CLK_PWM0 111 +#define CLK_CAPTURE_PWM0 112 +#define PCLK_PWM1 113 +#define CLK_PWM1 114 +#define CLK_CAPTURE_PWM1 115 +#define PCLK_SCR 116 +#define ACLK_DCF 117 +#define PCLK_INTMUX 118 +#define CLK_PPLL_I 119 +#define CLK_PPLL_MUX 120 +#define CLK_PPLL_100M_MATRIX 121 +#define CLK_PPLL_50M_MATRIX 122 +#define CLK_REF_PCIE_INNER_PHY 123 +#define CLK_REF_PCIE_100M_PHY 124 +#define ACLK_VPU_L_ROOT 125 +#define CLK_GMAC1_VPU_25M 126 +#define CLK_PPLL_125M_MATRIX 127 +#define ACLK_VPU_ROOT 128 +#define HCLK_VPU_ROOT 129 +#define PCLK_VPU_ROOT 130 +#define ACLK_VPU_BIU 131 +#define HCLK_VPU_BIU 132 +#define PCLK_VPU_BIU 133 +#define ACLK_VPU 134 +#define HCLK_VPU 135 +#define PCLK_CRU_PCIE 136 +#define PCLK_VPU_GRF 137 +#define HCLK_SFC 138 +#define SCLK_SFC 139 +#define CCLK_SRC_EMMC 140 +#define HCLK_EMMC 141 +#define ACLK_EMMC 142 +#define BCLK_EMMC 143 +#define TCLK_EMMC 144 +#define PCLK_GPIO1 145 +#define DBCLK_GPIO1 146 +#define ACLK_VPU_L_BIU 147 +#define PCLK_VPU_IOC 148 +#define HCLK_SAI_I2S0 149 +#define MCLK_SAI_I2S0 150 +#define HCLK_SAI_I2S2 151 +#define MCLK_SAI_I2S2 152 +#define PCLK_ACODEC 153 +#define MCLK_ACODEC_TX 154 +#define PCLK_GPIO3 155 +#define DBCLK_GPIO3 156 +#define PCLK_SPI1 157 +#define CLK_SPI1 158 +#define SCLK_IN_SPI1 159 +#define PCLK_UART2 160 +#define PCLK_UART5 161 +#define PCLK_UART6 162 +#define PCLK_UART7 163 +#define PCLK_I2C3 164 +#define CLK_I2C3 165 +#define PCLK_I2C5 166 +#define CLK_I2C5 167 +#define PCLK_I2C6 168 +#define CLK_I2C6 169 +#define ACLK_MAC_VPU 170 +#define PCLK_MAC_VPU 171 +#define CLK_GMAC1_RMII_VPU 172 +#define CLK_GMAC1_SRC_VPU 173 +#define PCLK_PCIE 174 +#define CLK_PCIE_AUX 175 +#define ACLK_PCIE 176 +#define HCLK_PCIE_SLV 177 +#define HCLK_PCIE_DBI 178 +#define PCLK_PCIE_PHY 179 +#define PCLK_PIPE_GRF 180 +#define CLK_PIPE_USB3OTG_COMBO 181 +#define CLK_UTMI_USB3OTG 182 +#define CLK_PCIE_PIPE_PHY 183 +#define CCLK_SRC_SDIO0 184 +#define HCLK_SDIO0 185 +#define CCLK_SRC_SDIO1 186 +#define HCLK_SDIO1 187 +#define CLK_TS_0 188 +#define CLK_TS_1 189 +#define PCLK_CAN2 190 +#define CLK_CAN2 191 +#define PCLK_CAN3 192 +#define CLK_CAN3 193 +#define PCLK_SARADC 194 +#define CLK_SARADC 195 +#define PCLK_TSADC 196 +#define CLK_TSADC 197 +#define CLK_TSADC_TSEN 198 +#define ACLK_USB3OTG 199 +#define CLK_REF_USB3OTG 200 +#define CLK_SUSPEND_USB3OTG 201 +#define ACLK_GPU_ROOT 202 +#define PCLK_GPU_ROOT 203 +#define ACLK_GPU_BIU 204 +#define PCLK_GPU_BIU 205 +#define ACLK_GPU 206 +#define CLK_GPU_PVTPLL_SRC 207 +#define ACLK_GPU_MALI 208 +#define HCLK_RKVENC_ROOT 209 +#define ACLK_RKVENC_ROOT 210 +#define PCLK_RKVENC_ROOT 211 +#define HCLK_RKVENC_BIU 212 +#define ACLK_RKVENC_BIU 213 +#define PCLK_RKVENC_BIU 214 +#define HCLK_RKVENC 215 +#define ACLK_RKVENC 216 +#define CLK_CORE_RKVENC 217 +#define HCLK_SAI_I2S1 218 +#define MCLK_SAI_I2S1 219 +#define PCLK_I2C1 220 +#define CLK_I2C1 221 +#define PCLK_I2C0 222 +#define CLK_I2C0 223 +#define CLK_UART_JTAG 224 +#define PCLK_SPI0 225 +#define CLK_SPI0 226 +#define SCLK_IN_SPI0 227 +#define PCLK_GPIO4 228 +#define DBCLK_GPIO4 229 +#define PCLK_RKVENC_IOC 230 +#define HCLK_SPDIF 231 +#define MCLK_SPDIF 232 +#define HCLK_PDM 233 +#define MCLK_PDM 234 +#define PCLK_UART1 235 +#define PCLK_UART3 236 +#define PCLK_RKVENC_GRF 237 +#define PCLK_CAN0 238 +#define CLK_CAN0 239 +#define PCLK_CAN1 240 +#define CLK_CAN1 241 +#define ACLK_VO_ROOT 242 +#define HCLK_VO_ROOT 243 +#define PCLK_VO_ROOT 244 +#define ACLK_VO_BIU 245 +#define HCLK_VO_BIU 246 +#define PCLK_VO_BIU 247 +#define HCLK_RGA2E 248 +#define ACLK_RGA2E 249 +#define CLK_CORE_RGA2E 250 +#define HCLK_VDPP 251 +#define ACLK_VDPP 252 +#define CLK_CORE_VDPP 253 +#define PCLK_VO_GRF 254 +#define PCLK_CRU 255 +#define ACLK_VOP_ROOT 256 +#define ACLK_VOP_BIU 257 +#define HCLK_VOP 258 +#define DCLK_VOP0 259 +#define DCLK_VOP1 260 +#define ACLK_VOP 261 +#define PCLK_HDMI 262 +#define CLK_SFR_HDMI 263 +#define CLK_CEC_HDMI 264 +#define CLK_SPDIF_HDMI 265 +#define CLK_HDMIPHY_TMDSSRC 266 +#define CLK_HDMIPHY_PREP 267 +#define PCLK_HDMIPHY 268 +#define HCLK_HDCP_KEY 269 +#define ACLK_HDCP 270 +#define HCLK_HDCP 271 +#define PCLK_HDCP 272 +#define HCLK_CVBS 273 +#define DCLK_CVBS 274 +#define DCLK_4X_CVBS 275 +#define ACLK_JPEG_DECODER 276 +#define HCLK_JPEG_DECODER 277 +#define ACLK_VO_L_ROOT 278 +#define ACLK_VO_L_BIU 279 +#define ACLK_MAC_VO 280 +#define PCLK_MAC_VO 281 +#define CLK_GMAC0_SRC 282 +#define CLK_GMAC0_RMII_50M 283 +#define CLK_GMAC0_TX 284 +#define CLK_GMAC0_RX 285 +#define ACLK_JPEG_ROOT 286 +#define ACLK_JPEG_BIU 287 +#define HCLK_SAI_I2S3 288 +#define MCLK_SAI_I2S3 289 +#define CLK_MACPHY 290 +#define PCLK_VCDCPHY 291 +#define PCLK_GPIO2 292 +#define DBCLK_GPIO2 293 +#define PCLK_VO_IOC 294 +#define CCLK_SRC_SDMMC0 295 +#define HCLK_SDMMC0 296 +#define PCLK_OTPC_NS 297 +#define CLK_SBPI_OTPC_NS 298 +#define CLK_USER_OTPC_NS 299 +#define CLK_HDMIHDP0 300 +#define HCLK_USBHOST 301 +#define HCLK_USBHOST_ARB 302 +#define CLK_USBHOST_OHCI 303 +#define CLK_USBHOST_UTMI 304 +#define PCLK_UART4 305 +#define PCLK_I2C4 306 +#define CLK_I2C4 307 +#define PCLK_I2C7 308 +#define CLK_I2C7 309 +#define PCLK_USBPHY 310 +#define CLK_REF_USBPHY 311 +#define HCLK_RKVDEC_ROOT 312 +#define ACLK_RKVDEC_ROOT_NDFT 313 +#define PCLK_DDRPHY_CRU 314 +#define HCLK_RKVDEC_BIU 315 +#define ACLK_RKVDEC_BIU 316 +#define ACLK_RKVDEC 317 +#define HCLK_RKVDEC 318 +#define CLK_HEVC_CA_RKVDEC 319 +#define ACLK_RKVDEC_PVTMUX_ROOT 320 +#define CLK_RKVDEC_PVTPLL_SRC 321 +#define PCLK_DDR_ROOT 322 +#define PCLK_DDR_BIU 323 +#define PCLK_DDRC 324 +#define PCLK_DDRMON 325 +#define CLK_TIMER_DDRMON 326 +#define PCLK_MSCH_BIU 327 +#define PCLK_DDR_GRF 328 +#define PCLK_DDR_HWLP 329 +#define PCLK_DDRPHY 330 +#define CLK_MSCH_BIU 331 +#define ACLK_DDR_UPCTL 332 +#define CLK_DDR_UPCTL 333 +#define CLK_DDRMON 334 +#define ACLK_DDR_SCRAMBLE 335 +#define ACLK_SPLIT 336 +#define CLK_DDRC_SRC 337 +#define CLK_DDR_PHY 338 +#define PCLK_OTPC_S 339 +#define CLK_SBPI_OTPC_S 340 +#define CLK_USER_OTPC_S 341 +#define PCLK_KEYREADER 342 +#define PCLK_BUS_SGRF 343 +#define PCLK_STIMER 344 +#define CLK_STIMER0 345 +#define CLK_STIMER1 346 +#define PCLK_WDT_S 347 +#define TCLK_WDT_S 348 +#define HCLK_TRNG_S 349 +#define HCLK_BOOTROM 350 +#define PCLK_DCF 351 +#define ACLK_SYSMEM 352 +#define HCLK_TSP 353 +#define ACLK_TSP 354 +#define CLK_CORE_TSP 355 +#define CLK_OTPC_ARB 356 +#define PCLK_OTP_MASK 357 +#define CLK_PMC_OTP 358 +#define PCLK_PMU_ROOT 359 +#define HCLK_PMU_ROOT 360 +#define PCLK_I2C2 361 +#define CLK_I2C2 362 +#define HCLK_PMU_BIU 363 +#define PCLK_PMU_BIU 364 +#define FCLK_MCU 365 +#define RTC_CLK_MCU 366 +#define PCLK_OSCCHK 367 +#define CLK_PMU_MCU_JTAG 368 +#define PCLK_PMU 369 +#define PCLK_GPIO0 370 +#define DBCLK_GPIO0 371 +#define XIN_OSC0_DIV 372 +#define CLK_DEEPSLOW 373 +#define CLK_DDR_FAIL_SAFE 374 +#define PCLK_PMU_HP_TIMER 375 +#define CLK_PMU_HP_TIMER 376 +#define CLK_PMU_32K_HP_TIMER 377 +#define PCLK_PMU_IOC 378 +#define PCLK_PMU_CRU 379 +#define PCLK_PMU_GRF 380 +#define PCLK_PMU_WDT 381 +#define TCLK_PMU_WDT 382 +#define PCLK_PMU_MAILBOX 383 +#define PCLK_SCRKEYGEN 384 +#define CLK_SCRKEYGEN 385 +#define CLK_PVTM_OSCCHK 386 +#define CLK_REFOUT 387 +#define CLK_PVTM_PMU 388 +#define PCLK_PVTM_PMU 389 +#define PCLK_PMU_SGRF 390 +#define HCLK_PMU_SRAM 391 +#define CLK_UART0 392 +#define CLK_UART1 393 +#define CLK_UART2 394 +#define CLK_UART3 395 +#define CLK_UART4 396 +#define CLK_UART5 397 +#define CLK_UART6 398 +#define CLK_UART7 399 +#define MCLK_I2S0_2CH_SAI_SRC_PRE 400 +#define MCLK_I2S1_8CH_SAI_SRC_PRE 401 +#define MCLK_I2S2_2CH_SAI_SRC_PRE 402 +#define MCLK_I2S3_8CH_SAI_SRC_PRE 403 +#define MCLK_SDPDIF_SRC_PRE 404 + +/* 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 + +#endif // _DT_BINDINGS_CLK_ROCKCHIP_RK3528_H diff --git a/dts/upstream/include/dt-bindings/reset/rockchip,rk3528-cru.h b/dts/upstream/include/dt-bindings/reset/rockchip,rk3528-cru.h new file mode 100644 index 00000000000..6b024c5f2e1 --- /dev/null +++ b/dts/upstream/include/dt-bindings/reset/rockchip,rk3528-cru.h @@ -0,0 +1,241 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */ +/* + * Copyright (c) 2022 Rockchip Electronics Co. Ltd. + * Copyright (c) 2024 Yao Zi <ziyao@disroot.org> + * Author: Joseph Chen <chenjh@rock-chips.com> + */ + +#ifndef _DT_BINDINGS_RESET_ROCKCHIP_RK3528_H +#define _DT_BINDINGS_RESET_ROCKCHIP_RK3528_H + +#define SRST_CORE0_PO 0 +#define SRST_CORE1_PO 1 +#define SRST_CORE2_PO 2 +#define SRST_CORE3_PO 3 +#define SRST_CORE0 4 +#define SRST_CORE1 5 +#define SRST_CORE2 6 +#define SRST_CORE3 7 +#define SRST_NL2 8 +#define SRST_CORE_BIU 9 +#define SRST_CORE_CRYPTO 10 +#define SRST_P_DBG 11 +#define SRST_POT_DBG 12 +#define SRST_NT_DBG 13 +#define SRST_P_CORE_GRF 14 +#define SRST_P_DAPLITE_BIU 15 +#define SRST_P_CPU_BIU 16 +#define SRST_REF_PVTPLL_CORE 17 +#define SRST_A_BUS_VOPGL_BIU 18 +#define SRST_A_BUS_H_BIU 19 +#define SRST_A_SYSMEM_BIU 20 +#define SRST_A_BUS_BIU 21 +#define SRST_H_BUS_BIU 22 +#define SRST_P_BUS_BIU 23 +#define SRST_P_DFT2APB 24 +#define SRST_P_BUS_GRF 25 +#define SRST_A_BUS_M_BIU 26 +#define SRST_A_GIC 27 +#define SRST_A_SPINLOCK 28 +#define SRST_A_DMAC 29 +#define SRST_P_TIMER 30 +#define SRST_TIMER0 31 +#define SRST_TIMER1 32 +#define SRST_TIMER2 33 +#define SRST_TIMER3 34 +#define SRST_TIMER4 35 +#define SRST_TIMER5 36 +#define SRST_P_JDBCK_DAP 37 +#define SRST_JDBCK_DAP 38 +#define SRST_P_WDT_NS 39 +#define SRST_T_WDT_NS 40 +#define SRST_H_TRNG_NS 41 +#define SRST_P_UART0 42 +#define SRST_S_UART0 43 +#define SRST_PKA_CRYPTO 44 +#define SRST_A_CRYPTO 45 +#define SRST_H_CRYPTO 46 +#define SRST_P_DMA2DDR 47 +#define SRST_A_DMA2DDR 48 +#define SRST_P_PWM0 49 +#define SRST_PWM0 50 +#define SRST_P_PWM1 51 +#define SRST_PWM1 52 +#define SRST_P_SCR 53 +#define SRST_A_DCF 54 +#define SRST_P_INTMUX 55 +#define SRST_A_VPU_BIU 56 +#define SRST_H_VPU_BIU 57 +#define SRST_P_VPU_BIU 58 +#define SRST_A_VPU 59 +#define SRST_H_VPU 60 +#define SRST_P_CRU_PCIE 61 +#define SRST_P_VPU_GRF 62 +#define SRST_H_SFC 63 +#define SRST_S_SFC 64 +#define SRST_C_EMMC 65 +#define SRST_H_EMMC 66 +#define SRST_A_EMMC 67 +#define SRST_B_EMMC 68 +#define SRST_T_EMMC 69 +#define SRST_P_GPIO1 70 +#define SRST_DB_GPIO1 71 +#define SRST_A_VPU_L_BIU 72 +#define SRST_P_VPU_IOC 73 +#define SRST_H_SAI_I2S0 74 +#define SRST_M_SAI_I2S0 75 +#define SRST_H_SAI_I2S2 76 +#define SRST_M_SAI_I2S2 77 +#define SRST_P_ACODEC 78 +#define SRST_P_GPIO3 79 +#define SRST_DB_GPIO3 80 +#define SRST_P_SPI1 81 +#define SRST_SPI1 82 +#define SRST_P_UART2 83 +#define SRST_S_UART2 84 +#define SRST_P_UART5 85 +#define SRST_S_UART5 86 +#define SRST_P_UART6 87 +#define SRST_S_UART6 88 +#define SRST_P_UART7 89 +#define SRST_S_UART7 90 +#define SRST_P_I2C3 91 +#define SRST_I2C3 92 +#define SRST_P_I2C5 93 +#define SRST_I2C5 94 +#define SRST_P_I2C6 95 +#define SRST_I2C6 96 +#define SRST_A_MAC 97 +#define SRST_P_PCIE 98 +#define SRST_PCIE_PIPE_PHY 99 +#define SRST_PCIE_POWER_UP 100 +#define SRST_P_PCIE_PHY 101 +#define SRST_P_PIPE_GRF 102 +#define SRST_H_SDIO0 103 +#define SRST_H_SDIO1 104 +#define SRST_TS_0 105 +#define SRST_TS_1 106 +#define SRST_P_CAN2 107 +#define SRST_CAN2 108 +#define SRST_P_CAN3 109 +#define SRST_CAN3 110 +#define SRST_P_SARADC 111 +#define SRST_SARADC 112 +#define SRST_SARADC_PHY 113 +#define SRST_P_TSADC 114 +#define SRST_TSADC 115 +#define SRST_A_USB3OTG 116 +#define SRST_A_GPU_BIU 117 +#define SRST_P_GPU_BIU 118 +#define SRST_A_GPU 119 +#define SRST_REF_PVTPLL_GPU 120 +#define SRST_H_RKVENC_BIU 121 +#define SRST_A_RKVENC_BIU 122 +#define SRST_P_RKVENC_BIU 123 +#define SRST_H_RKVENC 124 +#define SRST_A_RKVENC 125 +#define SRST_CORE_RKVENC 126 +#define SRST_H_SAI_I2S1 127 +#define SRST_M_SAI_I2S1 128 +#define SRST_P_I2C1 129 +#define SRST_I2C1 130 +#define SRST_P_I2C0 131 +#define SRST_I2C0 132 +#define SRST_P_SPI0 133 +#define SRST_SPI0 134 +#define SRST_P_GPIO4 135 +#define SRST_DB_GPIO4 136 +#define SRST_P_RKVENC_IOC 137 +#define SRST_H_SPDIF 138 +#define SRST_M_SPDIF 139 +#define SRST_H_PDM 140 +#define SRST_M_PDM 141 +#define SRST_P_UART1 142 +#define SRST_S_UART1 143 +#define SRST_P_UART3 144 +#define SRST_S_UART3 145 +#define SRST_P_RKVENC_GRF 146 +#define SRST_P_CAN0 147 +#define SRST_CAN0 148 +#define SRST_P_CAN1 149 +#define SRST_CAN1 150 +#define SRST_A_VO_BIU 151 +#define SRST_H_VO_BIU 152 +#define SRST_P_VO_BIU 153 +#define SRST_H_RGA2E 154 +#define SRST_A_RGA2E 155 +#define SRST_CORE_RGA2E 156 +#define SRST_H_VDPP 157 +#define SRST_A_VDPP 158 +#define SRST_CORE_VDPP 159 +#define SRST_P_VO_GRF 160 +#define SRST_P_CRU 161 +#define SRST_A_VOP_BIU 162 +#define SRST_H_VOP 163 +#define SRST_D_VOP0 164 +#define SRST_D_VOP1 165 +#define SRST_A_VOP 166 +#define SRST_P_HDMI 167 +#define SRST_HDMI 168 +#define SRST_P_HDMIPHY 169 +#define SRST_H_HDCP_KEY 170 +#define SRST_A_HDCP 171 +#define SRST_H_HDCP 172 +#define SRST_P_HDCP 173 +#define SRST_H_CVBS 174 +#define SRST_D_CVBS_VOP 175 +#define SRST_D_4X_CVBS_VOP 176 +#define SRST_A_JPEG_DECODER 177 +#define SRST_H_JPEG_DECODER 178 +#define SRST_A_VO_L_BIU 179 +#define SRST_A_MAC_VO 180 +#define SRST_A_JPEG_BIU 181 +#define SRST_H_SAI_I2S3 182 +#define SRST_M_SAI_I2S3 183 +#define SRST_MACPHY 184 +#define SRST_P_VCDCPHY 185 +#define SRST_P_GPIO2 186 +#define SRST_DB_GPIO2 187 +#define SRST_P_VO_IOC 188 +#define SRST_H_SDMMC0 189 +#define SRST_P_OTPC_NS 190 +#define SRST_SBPI_OTPC_NS 191 +#define SRST_USER_OTPC_NS 192 +#define SRST_HDMIHDP0 193 +#define SRST_H_USBHOST 194 +#define SRST_H_USBHOST_ARB 195 +#define SRST_HOST_UTMI 196 +#define SRST_P_UART4 197 +#define SRST_S_UART4 198 +#define SRST_P_I2C4 199 +#define SRST_I2C4 200 +#define SRST_P_I2C7 201 +#define SRST_I2C7 202 +#define SRST_P_USBPHY 203 +#define SRST_USBPHY_POR 204 +#define SRST_USBPHY_OTG 205 +#define SRST_USBPHY_HOST 206 +#define SRST_P_DDRPHY_CRU 207 +#define SRST_H_RKVDEC_BIU 208 +#define SRST_A_RKVDEC_BIU 209 +#define SRST_A_RKVDEC 210 +#define SRST_H_RKVDEC 211 +#define SRST_HEVC_CA_RKVDEC 212 +#define SRST_REF_PVTPLL_RKVDEC 213 +#define SRST_P_DDR_BIU 214 +#define SRST_P_DDRC 215 +#define SRST_P_DDRMON 216 +#define SRST_TIMER_DDRMON 217 +#define SRST_P_MSCH_BIU 218 +#define SRST_P_DDR_GRF 219 +#define SRST_P_DDR_HWLP 220 +#define SRST_P_DDRPHY 221 +#define SRST_MSCH_BIU 222 +#define SRST_A_DDR_UPCTL 223 +#define SRST_DDR_UPCTL 224 +#define SRST_DDRMON 225 +#define SRST_A_DDR_SCRAMBLE 226 +#define SRST_A_SPLIT 227 +#define SRST_DDR_PHY 228 + +#endif // _DT_BINDINGS_RESET_ROCKCHIP_RK3528_H diff --git a/dts/upstream/src/arm64/rockchip/rk3528-pinctrl.dtsi b/dts/upstream/src/arm64/rockchip/rk3528-pinctrl.dtsi new file mode 100644 index 00000000000..ea051362fb2 --- /dev/null +++ b/dts/upstream/src/arm64/rockchip/rk3528-pinctrl.dtsi @@ -0,0 +1,1397 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + */ + +#include <dt-bindings/pinctrl/rockchip.h> +#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/dts/upstream/src/arm64/rockchip/rk3528-radxa-e20c.dts b/dts/upstream/src/arm64/rockchip/rk3528-radxa-e20c.dts index d2cdb63d4a9..57a446b5cbd 100644 --- a/dts/upstream/src/arm64/rockchip/rk3528-radxa-e20c.dts +++ b/dts/upstream/src/arm64/rockchip/rk3528-radxa-e20c.dts @@ -6,17 +6,150 @@ */ /dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> #include "rk3528.dtsi" / { model = "Radxa E20C"; compatible = "radxa,e20c", "rockchip,rk3528"; + aliases { + mmc0 = &sdhci; + }; + chosen { stdout-path = "serial0:1500000n8"; }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "MASKROM"; + linux,code = <KEY_SETUP>; + press-threshold-microvolt = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&user_key>; + + button-user { + gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; + label = "USER"; + linux,code = <BTN_1>; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&lan_led_g>, <&sys_led_g>, <&wan_led_g>; + + led-lan { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_LAN; + gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "netdev"; + }; + + led-sys { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + function = LED_FUNCTION_HEARTBEAT; + gpios = <&gpio4 RK_PC1 GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + }; + + led-wan { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_WAN; + gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "netdev"; + }; + }; + + vcc_1v8: regulator-1v8-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + }; + + vcc_3v3: regulator-3v3-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&pinctrl { + gpio-keys { + user_key: user-key { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + lan_led_g: lan-led-g { + rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sys_led_g: sys-led-g { + rockchip,pins = <4 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led_g: wan-led-g { + rockchip,pins = <4 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + no-sd; + no-sdio; + non-removable; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; }; &uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0m0_xfer>; status = "okay"; }; diff --git a/dts/upstream/src/arm64/rockchip/rk3528.dtsi b/dts/upstream/src/arm64/rockchip/rk3528.dtsi index e58faa985aa..26c3559d6a6 100644 --- a/dts/upstream/src/arm64/rockchip/rk3528.dtsi +++ b/dts/upstream/src/arm64/rockchip/rk3528.dtsi @@ -4,8 +4,12 @@ * Copyright (c) 2024 Yao Zi <ziyao@disroot.org> */ +#include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/clock/rockchip,rk3528-cru.h> +#include <dt-bindings/reset/rockchip,rk3528-cru.h> / { compatible = "rockchip,rk3528"; @@ -15,6 +19,11 @@ #size-cells = <2>; aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; serial0 = &uart0; serial1 = &uart1; serial2 = &uart2; @@ -51,6 +60,7 @@ reg = <0x0>; device_type = "cpu"; enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; }; cpu1: cpu@1 { @@ -58,6 +68,7 @@ reg = <0x1>; device_type = "cpu"; enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; }; cpu2: cpu@2 { @@ -65,6 +76,7 @@ reg = <0x2>; device_type = "cpu"; enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; }; cpu3: cpu@3 { @@ -72,6 +84,22 @@ reg = <0x3>; device_type = "cpu"; enable-method = "psci"; + clocks = <&scmi_clk SCMI_CLK_CPU>; + }; + }; + + firmware { + scmi: scmi { + compatible = "arm,scmi-smc"; + arm,smc-id = <0x82000010>; + shmem = <&scmi_shmem>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; }; }; @@ -80,6 +108,18 @@ method = "smc"; }; + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + scmi_shmem: shmem@10f000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x0010f000 0x0 0x100>; + no-map; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, @@ -95,6 +135,13 @@ #clock-cells = <0>; }; + gmac0_clk: clock-gmac50m { + compatible = "fixed-clock"; + clock-frequency = <50000000>; + clock-output-names = "gmac0"; + #clock-cells = <0>; + }; + soc { compatible = "simple-bus"; ranges = <0x0 0xfe000000 0x0 0xfe000000 0x0 0x2000000>; @@ -114,10 +161,219 @@ #interrupt-cells = <3>; }; + qos_crypto_a: qos@ff200000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200000 0x0 0x20>; + }; + + qos_crypto_p: qos@ff200080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200080 0x0 0x20>; + }; + + qos_dcf: qos@ff200100 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200100 0x0 0x20>; + }; + + qos_dft2apb: qos@ff200200 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200200 0x0 0x20>; + }; + + qos_dma2ddr: qos@ff200280 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200280 0x0 0x20>; + }; + + qos_dmac: qos@ff200300 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200300 0x0 0x20>; + }; + + qos_keyreader: qos@ff200380 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff200380 0x0 0x20>; + }; + + qos_cpu: qos@ff210000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff210000 0x0 0x20>; + }; + + qos_debug: qos@ff210080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff210080 0x0 0x20>; + }; + + qos_gpu_m0: qos@ff220000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff220000 0x0 0x20>; + }; + + qos_gpu_m1: qos@ff220080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff220080 0x0 0x20>; + }; + + qos_pmu_mcu: qos@ff240000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff240000 0x0 0x20>; + }; + + qos_rkvdec: qos@ff250000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff250000 0x0 0x20>; + }; + + qos_rkvenc: qos@ff260000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff260000 0x0 0x20>; + }; + + qos_gmac0: qos@ff270000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270000 0x0 0x20>; + }; + + qos_hdcp: qos@ff270080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270080 0x0 0x20>; + }; + + qos_jpegdec: qos@ff270100 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270100 0x0 0x20>; + }; + + qos_rga2_m0ro: qos@ff270200 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270200 0x0 0x20>; + }; + + qos_rga2_m0wo: qos@ff270280 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270280 0x0 0x20>; + }; + + qos_sdmmc0: qos@ff270300 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270300 0x0 0x20>; + }; + + qos_usb2host: qos@ff270380 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270380 0x0 0x20>; + }; + + qos_vdpp: qos@ff270480 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270480 0x0 0x20>; + }; + + qos_vop: qos@ff270500 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff270500 0x0 0x20>; + }; + + qos_emmc: qos@ff280000 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280000 0x0 0x20>; + }; + + qos_fspi: qos@ff280080 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280080 0x0 0x20>; + }; + + qos_gmac1: qos@ff280100 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280100 0x0 0x20>; + }; + + qos_pcie: qos@ff280180 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280180 0x0 0x20>; + }; + + qos_sdio0: qos@ff280200 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280200 0x0 0x20>; + }; + + qos_sdio1: qos@ff280280 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280280 0x0 0x20>; + }; + + qos_tsp: qos@ff280300 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280300 0x0 0x20>; + }; + + qos_usb3otg: qos@ff280380 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280380 0x0 0x20>; + }; + + qos_vpu: qos@ff280400 { + compatible = "rockchip,rk3528-qos", "syscon"; + reg = <0x0 0xff280400 0x0 0x20>; + }; + + cru: clock-controller@ff4a0000 { + compatible = "rockchip,rk3528-cru"; + reg = <0x0 0xff4a0000 0x0 0x30000>; + assigned-clocks = + <&cru XIN_OSC0_DIV>, <&cru PLL_GPLL>, + <&cru PLL_PPLL>, <&cru PLL_CPLL>, + <&cru ARMCLK>, <&cru CLK_MATRIX_250M_SRC>, + <&cru CLK_MATRIX_500M_SRC>, + <&cru CLK_MATRIX_50M_SRC>, + <&cru CLK_MATRIX_100M_SRC>, + <&cru CLK_MATRIX_150M_SRC>, + <&cru CLK_MATRIX_200M_SRC>, + <&cru CLK_MATRIX_300M_SRC>, + <&cru CLK_MATRIX_339M_SRC>, + <&cru CLK_MATRIX_400M_SRC>, + <&cru CLK_MATRIX_600M_SRC>, + <&cru CLK_PPLL_50M_MATRIX>, + <&cru CLK_PPLL_100M_MATRIX>, + <&cru CLK_PPLL_125M_MATRIX>, + <&cru ACLK_BUS_VOPGL_ROOT>; + assigned-clock-rates = + <32768>, <1188000000>, + <1000000000>, <996000000>, + <408000000>, <250000000>, + <500000000>, + <50000000>, + <100000000>, + <150000000>, + <200000000>, + <300000000>, + <340000000>, + <400000000>, + <600000000>, + <50000000>, + <100000000>, + <125000000>, + <500000000>; + clocks = <&xin24m>, <&gmac0_clk>; + clock-names = "xin24m", "gmac0"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + ioc_grf: syscon@ff540000 { + compatible = "rockchip,rk3528-ioc-grf", "syscon"; + reg = <0x0 0xff540000 0x0 0x40000>; + }; + uart0: serial@ff9f0000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xff9f0000 0x0 0x100>; - clock-frequency = <24000000>; + clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; @@ -127,6 +383,8 @@ uart1: serial@ff9f8000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xff9f8000 0x0 0x100>; + clocks = <&cru SCLK_UART1>, <&cru PCLK_UART1>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; @@ -136,6 +394,8 @@ uart2: serial@ffa00000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xffa00000 0x0 0x100>; + clocks = <&cru SCLK_UART2>, <&cru PCLK_UART2>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; @@ -144,6 +404,8 @@ uart3: serial@ffa08000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; + clocks = <&cru SCLK_UART3>, <&cru PCLK_UART3>; + clock-names = "baudclk", "apb_pclk"; reg = <0x0 0xffa08000 0x0 0x100>; reg-io-width = <4>; reg-shift = <2>; @@ -153,6 +415,8 @@ uart4: serial@ffa10000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xffa10000 0x0 0x100>; + clocks = <&cru SCLK_UART4>, <&cru PCLK_UART4>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; @@ -162,6 +426,8 @@ uart5: serial@ffa18000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xffa18000 0x0 0x100>; + clocks = <&cru SCLK_UART5>, <&cru PCLK_UART5>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; @@ -171,6 +437,8 @@ uart6: serial@ffa20000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xffa20000 0x0 0x100>; + clocks = <&cru SCLK_UART6>, <&cru PCLK_UART6>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; @@ -180,10 +448,118 @@ uart7: serial@ffa28000 { compatible = "rockchip,rk3528-uart", "snps,dw-apb-uart"; reg = <0x0 0xffa28000 0x0 0x100>; + clocks = <&cru SCLK_UART7>, <&cru PCLK_UART7>; + clock-names = "baudclk", "apb_pclk"; interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; reg-io-width = <4>; reg-shift = <2>; status = "disabled"; }; + + saradc: adc@ffae0000 { + compatible = "rockchip,rk3528-saradc"; + reg = <0x0 0xffae0000 0x0 0x10000>; + clocks = <&cru CLK_SARADC>, <&cru PCLK_SARADC>; + clock-names = "saradc", "apb_pclk"; + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + resets = <&cru SRST_P_SARADC>; + reset-names = "saradc-apb"; + #io-channel-cells = <1>; + status = "disabled"; + }; + + sdhci: mmc@ffbf0000 { + compatible = "rockchip,rk3528-dwcmshc", + "rockchip,rk3588-dwcmshc"; + reg = <0x0 0xffbf0000 0x0 0x10000>; + assigned-clocks = <&cru BCLK_EMMC>, <&cru TCLK_EMMC>, + <&cru CCLK_SRC_EMMC>; + assigned-clock-rates = <200000000>, <24000000>, + <200000000>; + clocks = <&cru CCLK_SRC_EMMC>, <&cru HCLK_EMMC>, + <&cru ACLK_EMMC>, <&cru BCLK_EMMC>, + <&cru TCLK_EMMC>; + clock-names = "core", "bus", "axi", "block", "timer"; + interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + max-frequency = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8>, <&emmc_clk>, <&emmc_cmd>, + <&emmc_strb>; + resets = <&cru SRST_C_EMMC>, <&cru SRST_H_EMMC>, + <&cru SRST_A_EMMC>, <&cru SRST_B_EMMC>, + <&cru SRST_T_EMMC>; + reset-names = "core", "bus", "axi", "block", "timer"; + 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 = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>; + 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 = <GIC_SPI 78 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl 0 128 32>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; }; }; + +#include "rk3528-pinctrl.dtsi" diff --git a/dts/upstream/src/arm64/rockchip/rk3576-roc-pc.dts b/dts/upstream/src/arm64/rockchip/rk3576-roc-pc.dts new file mode 100644 index 00000000000..612b7bb0b74 --- /dev/null +++ b/dts/upstream/src/arm64/rockchip/rk3576-roc-pc.dts @@ -0,0 +1,736 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Firefly Technology Co. Ltd + * Copyright (c) 2024 Heiko Stuebner <heiko@sntech.de> + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/pwm/pwm.h> +#include <dt-bindings/usb/pd.h> +#include "rk3576.dtsi" + +/ { + model = "Firefly ROC-RK3576-PC"; + compatible = "firefly,roc-rk3576-pc", "rockchip,rk3576"; + + aliases { + mmc0 = &sdhci; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial0:1500000n8"; + }; + + adc-keys-0 { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "Maskrom"; + linux,code = <KEY_SETUP>; + press-threshold-microvolt = <17000>; + }; + }; + + adc-keys-1 { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-recovery { + label = "Recovery"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <17000>; + }; + }; + + vbus5v0_typec: regulator-vbus5v0-typec { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PD1 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_otg0_pwren_h>; + regulator-name = "vbus5v0_typec"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_device_s0>; + }; + + vcc12v_dcin: regulator-vcc12v-dcin { + compatible = "regulator-fixed"; + regulator-name = "vcc12v_dcin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc1v2_ufs_vccq_s0: regulator-vcc1v2-ufs-vccq-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v2_ufs_vccq_s0"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc1v8_ufs_vccq2_s0: regulator-vcc1v8-ufs-vccq2-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc1v8_ufs_vccq2_s0"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8_s3>; + }; + + vcc3v3_pcie: regulator-vcc3v3-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio2 RK_PB3 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie_pwren_h>; + regulator-name = "vcc3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <5000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc3v3_rtc_s5: regulator-vcc3v3-rtc-s5 { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_rtc_s5"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc5v0_device_s0: regulator-vcc5v0-device-s0 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio2 RK_PC0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5vd_en>; + regulator-name = "vcc5v0_device"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_sys_s5: regulator-vcc5v0-sys-s5 { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_usb20_host1: regulator-vcc5v0-usb20-host1 { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio0 RK_PC7 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb3_host_pwren_h>; + regulator-name = "vcc5v0_host1"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_device_s0>; + }; + + vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v1_nldo_s3"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc_1v8_s0: regulator-vcc-1v8-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8_s0"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_1v8_s3>; + }; + + vcc_2v0_pldo_s3: regulator-vcc-2v0-pldo-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_2v0_pldo_s3"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + vin-supply = <&vcc5v0_sys_s5>; + }; + + vcc_3v3_s0: regulator-vcc-3v3-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_s0"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_ufs_s0: regulator-vcc-ufs-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_ufs_s0"; + regulator-boot-on; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys_s5>; + }; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big_s0>; +}; + +&gpu { + mali-supply = <&vdd_gpu_s0>; + status = "okay"; +}; + +&gmac0 { + clock_in_out = "output"; + pinctrl-names = "default"; + pinctrl-0 = <ð0m0_miim + ð0m0_tx_bus2 + ð0m0_rx_bus2 + ð0m0_rgmii_clk + ð0m0_rgmii_bus + ðm0_clk0_25m_out>; + /* Use rgmii-rxid mode to disable rx delay inside Soc */ + phy-mode = "rgmii-rxid"; + phy-handle = <&rgmii_phy0>; + tx_delay = <0x21>; + status = "okay"; +}; + +&mdio0 { + status = "okay"; + + rgmii_phy0: phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + clocks = <&cru REFCLKO25M_GMAC0_OUT>; + /* Reset time is 20ms, 100ms for rtl8211f */ + reset-delay-us = <20000>; + reset-gpios = <&gpio2 RK_PB5 GPIO_ACTIVE_LOW>; + reset-post-delay-us = <100000>; + }; +}; + +&i2c1 { + status = "okay"; + + pmic@23 { + compatible = "rockchip,rk806"; + reg = <0x23>; + interrupt-parent = <&gpio0>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, + <&rk806_dvs2_null>, <&rk806_dvs3_null>; + system-power-controller; + + vcc1-supply = <&vcc5v0_sys_s5>; + vcc2-supply = <&vcc5v0_sys_s5>; + vcc3-supply = <&vcc5v0_sys_s5>; + vcc4-supply = <&vcc5v0_sys_s5>; + vcc5-supply = <&vcc5v0_sys_s5>; + vcc6-supply = <&vcc5v0_sys_s5>; + vcc7-supply = <&vcc5v0_sys_s5>; + vcc8-supply = <&vcc5v0_sys_s5>; + vcc9-supply = <&vcc5v0_sys_s5>; + vcc10-supply = <&vcc5v0_sys_s5>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc5v0_sys_s5>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcc5v0_sys_s5>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun0"; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + }; + + rk806_dvs1_slp: dvs1-slp-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun1"; + }; + + rk806_dvs1_pwrdn: dvs1-pwrdn-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun2"; + }; + + rk806_dvs1_rst: dvs1-rst-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun3"; + }; + + rk806_dvs2_slp: dvs2-slp-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun1"; + }; + + rk806_dvs2_pwrdn: dvs2-pwrdn-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun2"; + }; + + rk806_dvs2_rst: dvs2-rst-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun3"; + }; + + rk806_dvs2_dvs: dvs2-dvs-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun4"; + }; + + rk806_dvs2_gpio: dvs2-gpio-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun5"; + }; + + rk806_dvs3_slp: dvs3-slp-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun1"; + }; + + rk806_dvs3_pwrdn: dvs3-pwrdn-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun2"; + }; + + rk806_dvs3_rst: dvs3-rst-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun3"; + }; + + rk806_dvs3_dvs: dvs3-dvs-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun4"; + }; + + rk806_dvs3_gpio: dvs3-gpio-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun5"; + }; + + regulators { + vdd_cpu_big_s0: dcdc-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_cpu_big_s0"; + regulator-enable-ramp-delay = <400>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_npu_s0: dcdc-reg2 { + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_npu_s0"; + regulator-enable-ramp-delay = <400>; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: dcdc-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_cpu_lit_s0"; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vcc_3v3_s3: dcdc-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vdd_gpu_s0: dcdc-reg5 { + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <900000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_gpu_s0"; + regulator-enable-ramp-delay = <400>; + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + vddq_ddr_s0: dcdc-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vddq_ddr_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_logic_s0: dcdc-reg7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <800000>; + regulator-name = "vdd_logic_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd2_ddr_s3: dcdc-reg9 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vdd2_ddr_s3"; + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg10 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdd_ddr_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_1v8_s0: pldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca_1v8_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pldo2_s0: pldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pldo2_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_1v2_s0: pldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdda_1v2_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcca_3v3_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vccio_sd_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca1v8_pldo6_s3: pldo-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcca1v8_pldo6_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s3"; + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdda_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdda_ddr_pll_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda0v75_hdmi_s0: nldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <837500>; + regulator-max-microvolt = <837500>; + regulator-name = "vdda0v75_hdmi_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "vdda_0v85_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdda_0v75_s0: nldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdda_0v75_s0"; + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + + /* pc9202 watchdog@3c with enable-gpio gpio0-c3 */ + + /* hnyetek,husb311 typec-portc@4e */ + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "hym8563"; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int_l>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA0 IRQ_TYPE_LEVEL_LOW>; + wakeup-source; + }; +}; + +&saradc { + vref-supply = <&vcca_1v8_s0>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + no-sdio; + no-sd; + non-removable; + max-frequency = <200000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + full-pwr-cycle-in-suspend; + status = "okay"; +}; + +&sdmmc { + max-frequency = <200000000>; + no-sdio; + no-mmc; + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&pinctrl { + hym8563 { + rtc_int_l: rtc-int-l { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + power { + vcc5vd_en: vcc5vd-en { + rockchip,pins = <2 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_pwren_h: pcie-pwren-h { + rockchip,pins = <2 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + hub_reset_h: hub-reset-h { + rockchip,pins = <2 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usb3_host_pwren_h: usb3-host-pwren-h { + rockchip,pins = <0 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usb_otg0_pwren_h: usb-otg0-pwren-h { + rockchip,pins = <0 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usbc0_int_l: usbc0-int-l { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + watchdog { + wd_en: wd-en { + rockchip,pins = <0 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&uart0 { + pinctrl-0 = <&uart0m0_xfer>; + status = "okay"; +}; + +&uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&uart4m1_xfer &uart4m1_ctsn>; + status = "okay"; +}; + +/* On the extension pin header */ +&uart6 { + pinctrl-names = "default"; + pinctrl-0 = <&uart6m3_xfer>; + status = "okay"; +}; diff --git a/dts/upstream/src/arm64/rockchip/rk3576.dtsi b/dts/upstream/src/arm64/rockchip/rk3576.dtsi index 4dde954043e..29b47799849 100644 --- a/dts/upstream/src/arm64/rockchip/rk3576.dtsi +++ b/dts/upstream/src/arm64/rockchip/rk3576.dtsi @@ -1260,6 +1260,45 @@ status = "disabled"; }; + otp: otp@2a580000 { + compatible = "rockchip,rk3576-otp"; + reg = <0x0 0x2a580000 0x0 0x400>; + #address-cells = <1>; + #size-cells = <1>; + clocks = <&cru CLK_OTPC_NS>, <&cru PCLK_OTPC_NS>, + <&cru CLK_OTP_PHY_G>; + clock-names = "otp", "apb_pclk", "phy"; + resets = <&cru SRST_OTPC_NS>, <&cru SRST_P_OTPC_NS>; + reset-names = "otp", "apb"; + + /* Data cells */ + cpu_code: cpu-code@2 { + reg = <0x02 0x2>; + }; + otp_cpu_version: cpu-version@5 { + reg = <0x05 0x1>; + bits = <3 3>; + }; + otp_id: id@a { + reg = <0x0a 0x10>; + }; + cpub_leakage: cpub-leakage@1e { + reg = <0x1e 0x1>; + }; + cpul_leakage: cpul-leakage@1f { + reg = <0x1f 0x1>; + }; + npu_leakage: npu-leakage@20 { + reg = <0x20 0x1>; + }; + gpu_leakage: gpu-leakage@21 { + reg = <0x21 0x1>; + }; + log_leakage: log-leakage@22 { + reg = <0x22 0x1>; + }; + }; + gic: interrupt-controller@2a701000 { compatible = "arm,gic-400"; reg = <0x0 0x2a701000 0 0x10000>, diff --git a/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi b/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi index c3abdfb04f8..2623afa7963 100644 --- a/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi +++ b/dts/upstream/src/arm64/rockchip/rk3588-base.dtsi @@ -1921,6 +1921,14 @@ status = "disabled"; }; + rng@fe378000 { + compatible = "rockchip,rk3588-rng"; + reg = <0x0 0xfe378000 0x0 0x200>; + interrupts = <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&scmi_clk SCMI_HCLK_SECURE_NS>; + resets = <&scmi_reset 48>; + }; + i2s0_8ch: i2s@fe470000 { compatible = "rockchip,rk3588-i2s-tdm"; reg = <0x0 0xfe470000 0x0 0x1000>; diff --git a/dts/upstream/src/mips/Makefile b/dts/upstream/src/mips/Makefile new file mode 100644 index 00000000000..9a8f6aa3584 --- /dev/null +++ b/dts/upstream/src/mips/Makefile @@ -0,0 +1,14 @@ +# SPDX-License-Identifier: GPL-2.0+ + +include $(srctree)/scripts/Makefile.dts + +targets += $(dtb-y) + +# Add any required device tree compiler flags here +DTC_FLAGS += -a 0x8 + +PHONY += dtbs +dtbs: $(addprefix $(obj)/, $(dtb-y)) + @: + +clean-files := */*.dtb */*.dtbo diff --git a/fs/exfat/io.c b/fs/exfat/io.c index 81e82829c72..c56f5675987 100644 --- a/fs/exfat/io.c +++ b/fs/exfat/io.c @@ -597,15 +597,13 @@ ssize_t exfat_generic_pwrite(struct exfat* ef, struct exfat_node* node, } #ifdef __UBOOT__ +#define PATH_MAX FS_DIRENT_NAME_LEN + struct exfat_dir_stream { + char dirname[PATH_MAX]; struct fs_dir_stream fs_dirs; struct fs_dirent dirent; - - struct exfat_node* node; - struct exfat_iterator it; - /* State tracker flags for emulated . and .. dirents */ - bool dot; - bool dotdot; + int offset; }; int exfat_fs_probe(struct blk_desc *fs_dev_desc, @@ -626,8 +624,6 @@ error: return ret; } -#define PATH_MAX FS_DIRENT_NAME_LEN - /* Adapted from uclibc 1.0.35 */ static char *exfat_realpath(const char *path, char got_path[]) { @@ -721,31 +717,31 @@ int exfat_lookup_realpath(struct exfat* ef, struct exfat_node** node, int exfat_fs_opendir(const char *filename, struct fs_dir_stream **dirsp) { struct exfat_dir_stream *dirs; + struct exfat_node *dnode; int err; - dirs = calloc(1, sizeof(*dirs)); - if (!dirs) - return -ENOMEM; - - err = exfat_lookup_realpath(&ctxt.ef, &dirs->node, filename); + err = exfat_lookup_realpath(&ctxt.ef, &dnode, filename); if (err) - goto err_out; + return err; - if (!(dirs->node->attrib & EXFAT_ATTRIB_DIR)) { + if (!(dnode->attrib & EXFAT_ATTRIB_DIR)) err = -ENOTDIR; - goto err_out; - } - err = exfat_opendir(&ctxt.ef, dirs->node, &dirs->it); + exfat_put_node(&ctxt.ef, dnode); + if (err) - goto err_out; + return err; + + dirs = calloc(1, sizeof(*dirs)); + if (!dirs) + return -ENOMEM; + + strcpy(dirs->dirname, filename); + dirs->offset = -1; *dirsp = &dirs->fs_dirs; return 0; -err_out: - free(dirs); - return err; } int exfat_fs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp) @@ -753,50 +749,77 @@ int exfat_fs_readdir(struct fs_dir_stream *fs_dirs, struct fs_dirent **dentp) struct exfat_dir_stream *dirs = container_of(fs_dirs, struct exfat_dir_stream, fs_dirs); struct fs_dirent *dent = &dirs->dirent; - struct exfat_node* node; + struct exfat_node *dnode, *node; + struct exfat_iterator it; + int offset = 0; + int err; + + err = exfat_lookup_realpath(&ctxt.ef, &dnode, dirs->dirname); + if (err) + return err; + + if (!(dnode->attrib & EXFAT_ATTRIB_DIR)) { + err = -ENOTDIR; + goto err_out; + } /* Emulate current directory ./ */ - if (!dirs->dot) { - dirs->dot = true; + if (dirs->offset == -1) { + dirs->offset++; snprintf(dent->name, FS_DIRENT_NAME_LEN, "."); dent->type = FS_DT_DIR; *dentp = dent; - return 0; + goto err_out; } /* Emulate parent directory ../ */ - if (!dirs->dotdot) { - dirs->dotdot = true; + if (dirs->offset == 0) { + dirs->offset++; snprintf(dent->name, FS_DIRENT_NAME_LEN, ".."); dent->type = FS_DT_DIR; *dentp = dent; - return 0; + goto err_out; } + err = exfat_opendir(&ctxt.ef, dnode, &it); + if (err) + goto err_out; + + *dentp = NULL; + /* Read actual directory content */ - node = exfat_readdir(&dirs->it); - if (!node) { /* No more content, reset . and .. emulation */ - dirs->dot = false; - dirs->dotdot = false; - return 1; - } + while ((node = exfat_readdir(&it))) { + if (dirs->offset != ++offset) { + exfat_put_node(&ctxt.ef, node); + continue; + } - exfat_get_name(node, dent->name); - if (node->attrib & EXFAT_ATTRIB_DIR) { - dent->type = FS_DT_DIR; - } else { - dent->type = FS_DT_REG; - dent->size = node->size; + exfat_get_name(node, dent->name); + if (node->attrib & EXFAT_ATTRIB_DIR) { + dent->type = FS_DT_DIR; + } else { + dent->type = FS_DT_REG; + dent->size = node->size; + } + exfat_put_node(&ctxt.ef, node); + *dentp = dent; + dirs->offset++; + break; } - *dentp = dent; + exfat_closedir(&ctxt.ef, &it); - return 0; +err_out: + exfat_put_node(&ctxt.ef, dnode); + return err; } void exfat_fs_closedir(struct fs_dir_stream *fs_dirs) { - free(fs_dirs); + struct exfat_dir_stream *dirs = + container_of(fs_dirs, struct exfat_dir_stream, fs_dirs); + + free(dirs); } int exfat_fs_ls(const char *dirname) @@ -852,11 +875,11 @@ int exfat_fs_exists(const char *filename) err = exfat_lookup_realpath(&ctxt.ef, &node, filename); if (err) - return err; + return 0; exfat_put_node(&ctxt.ef, node); - return 0; + return 1; } int exfat_fs_size(const char *filename, loff_t *size) @@ -898,9 +921,7 @@ int exfat_fs_read(const char *filename, void *buf, loff_t offset, loff_t len, *actread = sz; - exfat_put_node(&ctxt.ef, node); - - return exfat_flush_node(&ctxt.ef, node); + err = exfat_flush_node(&ctxt.ef, node); exit: exfat_put_node(&ctxt.ef, node); return err; @@ -992,6 +1013,11 @@ exit: return err; } +int exfat_fs_rename(const char *old_path, const char *new_path) +{ + return exfat_rename(&ctxt.ef, old_path, new_path); +} + void exfat_fs_close(void) { exfat_unmount(&ctxt.ef); diff --git a/fs/exfat/lookup.c b/fs/exfat/lookup.c index 9867aab95f3..1d9aae9e036 100644 --- a/fs/exfat/lookup.c +++ b/fs/exfat/lookup.c @@ -218,8 +218,9 @@ int exfat_split(struct exfat* ef, struct exfat_node** parent, exfat_put_node(ef, *parent); *parent = *node; } +#ifndef __UBOOT__ exfat_bug("impossible"); -#ifdef __UBOOT__ +#else return 0; #endif } @@ -401,6 +401,7 @@ static struct fstype_info fstypes[] = { .ln = fs_ln_unsupported, .unlink = exfat_fs_unlink, .mkdir = exfat_fs_mkdir, + .rename = exfat_fs_rename, }, #endif { diff --git a/fs/squashfs/sqfs.c b/fs/squashfs/sqfs.c index 7c364686f14..2dcdd60f683 100644 --- a/fs/squashfs/sqfs.c +++ b/fs/squashfs/sqfs.c @@ -949,7 +949,7 @@ static int sqfs_opendir_nest(const char *filename, struct fs_dir_stream **dirsp) goto out; } - token_list = malloc(token_count * sizeof(char *)); + token_list = calloc(token_count, sizeof(char *)); if (!token_list) { ret = -EINVAL; goto out; @@ -987,9 +987,11 @@ static int sqfs_opendir_nest(const char *filename, struct fs_dir_stream **dirsp) *dirsp = (struct fs_dir_stream *)dirs; out: - for (j = 0; j < token_count; j++) - free(token_list[j]); - free(token_list); + if (token_list) { + for (j = 0; j < token_count; j++) + free(token_list[j]); + free(token_list); + } free(pos_list); free(path); if (ret) { diff --git a/include/ahci.h b/include/ahci.h index d4f0f3ce0e7..eb05cc687f6 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -137,8 +137,8 @@ struct ahci_ioports { void __iomem *port_mmio; struct ahci_cmd_hdr *cmd_slot; struct ahci_sg *cmd_tbl_sg; - ulong cmd_tbl; - u32 rx_fis; + void *cmd_tbl; + void *rx_fis; }; /** diff --git a/include/configs/anbernic-rgxx3-rk3566.h b/include/configs/anbernic-rgxx3-rk3566.h index 3c4ea4e7d84..3d9e05a976a 100644 --- a/include/configs/anbernic-rgxx3-rk3566.h +++ b/include/configs/anbernic-rgxx3-rk3566.h @@ -3,10 +3,10 @@ #ifndef __ANBERNIC_RGXX3_RK3566_H #define __ANBERNIC_RGXX3_RK3566_H -#include <configs/rk3568_common.h> - #define ROCKCHIP_DEVICE_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" +#include <configs/rk3568_common.h> + #endif diff --git a/include/configs/evb_rk3568.h b/include/configs/evb_rk3568.h index a0f2383bf2f..9070160cf58 100644 --- a/include/configs/evb_rk3568.h +++ b/include/configs/evb_rk3568.h @@ -6,10 +6,10 @@ #ifndef __EVB_RK3568_H #define __EVB_RK3568_H -#include <configs/rk3568_common.h> - #define ROCKCHIP_DEVICE_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" +#include <configs/rk3568_common.h> + #endif diff --git a/include/configs/evb_rk3588.h b/include/configs/evb_rk3588.h index 4568e2cace6..5ff1ddbfcbe 100644 --- a/include/configs/evb_rk3588.h +++ b/include/configs/evb_rk3588.h @@ -6,10 +6,10 @@ #ifndef __EVB_RK3588_H #define __EVB_RK3588_H -#include <configs/rk3588_common.h> - #define ROCKCHIP_DEVICE_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" +#include <configs/rk3588_common.h> + #endif diff --git a/include/configs/khadas-edge2-rk3588s.h b/include/configs/khadas-edge2-rk3588s.h index d279cf3826a..fe8461d6362 100644 --- a/include/configs/khadas-edge2-rk3588s.h +++ b/include/configs/khadas-edge2-rk3588s.h @@ -6,10 +6,10 @@ #ifndef __KHADAS_EDGE2_RK3588_H #define __KHADAS_EDGE2_RK3588_H -#include <configs/rk3588_common.h> - #define ROCKCHIP_DEVICE_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" +#include <configs/rk3588_common.h> + #endif /* __KHADAS_EDGE2_RK3588_H */ diff --git a/include/configs/powkiddy-x55-rk3566.h b/include/configs/powkiddy-x55-rk3566.h index 4b25c6a8774..8ace435434f 100644 --- a/include/configs/powkiddy-x55-rk3566.h +++ b/include/configs/powkiddy-x55-rk3566.h @@ -3,10 +3,10 @@ #ifndef __POWKIDDY_X55_RK3566_H #define __POWKIDDY_X55_RK3566_H -#include <configs/rk3568_common.h> - #define ROCKCHIP_DEVICE_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" +#include <configs/rk3568_common.h> + #endif diff --git a/include/configs/px30_common.h b/include/configs/px30_common.h index 13ed9011764..d0539003fd5 100644 --- a/include/configs/px30_common.h +++ b/include/configs/px30_common.h @@ -20,6 +20,7 @@ "scriptaddr=0x00500000\0" \ "pxefile_addr_r=0x00600000\0" \ "fdt_addr_r=0x08300000\0" \ + "fdtoverlay_addr_r=0x08400000\0" \ "kernel_addr_r=0x00280000\0" \ "ramdisk_addr_r=0x0a200000\0" \ "kernel_comp_addr_r=0x03e80000\0" \ diff --git a/include/configs/rk3528_common.h b/include/configs/rk3528_common.h new file mode 100644 index 00000000000..f7dc6ecd594 --- /dev/null +++ b/include/configs/rk3528_common.h @@ -0,0 +1,38 @@ +/* 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 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_RK3528_COMMON_H */ diff --git a/include/configs/rk3568_common.h b/include/configs/rk3568_common.h index 09b7b71c6af..b2a35db0b94 100644 --- a/include/configs/rk3568_common.h +++ b/include/configs/rk3568_common.h @@ -15,6 +15,10 @@ #define CFG_SYS_SDRAM_BASE 0 #define SDRAM_MAX_SIZE 0xf0000000 +#ifndef ROCKCHIP_DEVICE_SETTINGS +#define ROCKCHIP_DEVICE_SETTINGS +#endif + #define ENV_MEM_LAYOUT_SETTINGS \ "scriptaddr=0x00c00000\0" \ "script_offset_f=0xffe000\0" \ @@ -29,7 +33,6 @@ #define CFG_EXTRA_ENV_SETTINGS \ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ - "partitions=" PARTS_DEFAULT \ ENV_MEM_LAYOUT_SETTINGS \ ROCKCHIP_DEVICE_SETTINGS \ "boot_targets=" BOOT_TARGETS "\0" diff --git a/include/configs/rk3576_common.h b/include/configs/rk3576_common.h new file mode 100644 index 00000000000..14d1d863609 --- /dev/null +++ b/include/configs/rk3576_common.h @@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2024 Rockchip Electronics Co., Ltd + */ + +#ifndef __CONFIG_RK3576_COMMON_H +#define __CONFIG_RK3576_COMMON_H + +#define CFG_CPUID_OFFSET 0xa + +#include "rockchip-common.h" + +#define CFG_IRAM_BASE 0x3ff80000 + +#define CFG_SYS_SDRAM_BASE 0x40000000 +/* Used by board_get_usable_ram_top(), space below the 4G address boundary */ +#define SDRAM_MAX_SIZE (SZ_4G - CFG_SYS_SDRAM_BASE) + +#ifndef ROCKCHIP_DEVICE_SETTINGS +#define ROCKCHIP_DEVICE_SETTINGS +#endif + +#define ENV_MEM_LAYOUT_SETTINGS \ + "scriptaddr=0x40c00000\0" \ + "script_offset_f=0xffe000\0" \ + "script_size_f=0x2000\0" \ + "pxefile_addr_r=0x40e00000\0" \ + "kernel_addr_r=0x42000000\0" \ + "kernel_comp_addr_r=0x4a000000\0" \ + "fdt_addr_r=0x52000000\0" \ + "fdtoverlay_addr_r=0x52100000\0" \ + "ramdisk_addr_r=0x52180000\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_RK3576_COMMON_H */ diff --git a/include/configs/rk3588_common.h b/include/configs/rk3588_common.h index e6654c275ac..2f0d40deb64 100644 --- a/include/configs/rk3588_common.h +++ b/include/configs/rk3588_common.h @@ -14,6 +14,10 @@ #define CFG_SYS_SDRAM_BASE 0 #define SDRAM_MAX_SIZE 0xf0000000 +#ifndef ROCKCHIP_DEVICE_SETTINGS +#define ROCKCHIP_DEVICE_SETTINGS +#endif + #define ENV_MEM_LAYOUT_SETTINGS \ "scriptaddr=0x00c00000\0" \ "script_offset_f=0xffe000\0" \ @@ -28,7 +32,6 @@ #define CFG_EXTRA_ENV_SETTINGS \ "fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \ - "partitions=" PARTS_DEFAULT \ ENV_MEM_LAYOUT_SETTINGS \ ROCKCHIP_DEVICE_SETTINGS \ "boot_targets=" BOOT_TARGETS "\0" diff --git a/include/configs/roc-pc-rk3576.h b/include/configs/roc-pc-rk3576.h new file mode 100644 index 00000000000..77c95f0c560 --- /dev/null +++ b/include/configs/roc-pc-rk3576.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2023 Rockchip Electronics Co., Ltd. + */ + +#ifndef __ROC_PC_RK3576_H +#define __ROC_PC_RK3576_H + +#define ROCKCHIP_DEVICE_SETTINGS \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" + +#include <configs/rk3576_common.h> + +#endif diff --git a/include/configs/toybrick_rk3588.h b/include/configs/toybrick_rk3588.h index faa2e6c19c3..00565089676 100644 --- a/include/configs/toybrick_rk3588.h +++ b/include/configs/toybrick_rk3588.h @@ -6,10 +6,10 @@ #ifndef __TOYBRICK_RK3588_H #define __TOYBRICK_RK3588_H -#include <configs/rk3588_common.h> - #define ROCKCHIP_DEVICE_SETTINGS \ "stdout=serial,vidconsole\0" \ "stderr=serial,vidconsole\0" +#include <configs/rk3588_common.h> + #endif diff --git a/include/exfat.h b/include/exfat.h index 7e43beeb348..75fce5b6566 100644 --- a/include/exfat.h +++ b/include/exfat.h @@ -20,5 +20,6 @@ int exfat_fs_unlink(const char *filename); int exfat_fs_mkdir(const char *dirname); int exfat_fs_write(const char *filename, void *buf, loff_t offset, loff_t len, loff_t *actwrite); +int exfat_fs_rename(const char *old_path, const char *new_path); #endif /* _EXFAT_H */ diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h index a54eff43add..6455335bae4 100644 --- a/include/linux/intel-smc.h +++ b/include/linux/intel-smc.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (C) 2017-2018, Intel Corporation + * Copyright (C) 2025 Altera Corporation <www.altera.com> */ #ifndef __INTEL_SMC_H @@ -482,10 +483,16 @@ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE) * Call register usage: * a0 INTEL_SIP_SMC_HPS_SET_BRIDGES * a1 Set bridges status: - * 0 - Disable - * 1 - Enable - * a2-7 not used - * + * Bit 0: 0 - Disable, 1 - Enable + * Bit 1: 1 - Has mask value in a2 + * a2 Mask value + * Bit 0: soc2fpga + * Bit 1: lwhps2fpga + * Bit 2: fpga2soc + * Bit 3: f2sdram0 (For Stratix 10 only) + * Bit 4: f2sdram1 (For Stratix 10 only) + * Bit 5: f2sdram2 (For Stratix 10 only) + * a3-7 not used * Return status * a0 INTEL_SIP_SMC_STATUS_OK */ diff --git a/include/mmc.h b/include/mmc.h index 52cacfd0eab..eead666ae44 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -494,6 +494,14 @@ struct dm_mmc_ops { int (*set_ios)(struct udevice *dev); /** + * send_init_stream() - send the initialization stream: 74 clock cycles + * This is used after power up before sending the first command + * + * @dev: Device to update + */ + void (*send_init_stream)(struct udevice *dev); + + /** * get_cd() - See whether a card is present * * @dev: Device to check @@ -572,6 +580,7 @@ struct dm_mmc_ops { /* Transition functions for compatibility */ int mmc_set_ios(struct mmc *mmc); +void mmc_send_init_stream(struct mmc *mmc); int mmc_getcd(struct mmc *mmc); int mmc_getwp(struct mmc *mmc); int mmc_execute_tuning(struct mmc *mmc, uint opcode); diff --git a/include/net-common.h b/include/net-common.h index 30860f5975a..e536968a92b 100644 --- a/include/net-common.h +++ b/include/net-common.h @@ -471,6 +471,9 @@ static inline struct in_addr env_get_ip(char *var) int net_init(void); +/* Called when a network operation fails to know if it should be re-tried */ +int net_start_again(void); + /* NET compatibility */ enum proto_t; int net_loop(enum proto_t protocol); @@ -490,6 +493,18 @@ int net_loop(enum proto_t protocol); */ int dhcp_run(ulong addr, const char *fname, bool autoload); + +/** + * do_ping - Run the ping command + * + * @cmdtp: Unused + * @flag: Command flags (CMD_FLAG_...) + * @argc: Number of arguments + * @argv: List of arguments + * Return: result (see enum command_ret_t) + */ +int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); + /** * do_tftpb - Run the tftpboot command * diff --git a/include/net-legacy.h b/include/net-legacy.h index bc0f0cde9fe..51780999a88 100644 --- a/include/net-legacy.h +++ b/include/net-legacy.h @@ -347,9 +347,6 @@ extern int net_ntp_time_offset; /* offset time from UTC */ int net_loop(enum proto_t); -/* Load failed. Start again. */ -int net_start_again(void); - /* Get size of the ethernet header when we send */ int net_eth_hdr_size(void); diff --git a/include/net-lwip.h b/include/net-lwip.h index 64e5c720560..b762956e8fd 100644 --- a/include/net-lwip.h +++ b/include/net-lwip.h @@ -10,7 +10,14 @@ enum proto_t { TFTPGET }; -void net_lwip_set_current(void); +static inline int eth_is_on_demand_init(void) +{ + return 1; +} + +int eth_init_state_only(void); /* Set active state */ + +int net_lwip_eth_start(void); struct netif *net_lwip_new_netif(struct udevice *udev); struct netif *net_lwip_new_netif_noip(struct udevice *udev); void net_lwip_remove_netif(struct netif *netif); @@ -27,7 +34,6 @@ bool wget_validate_uri(char *uri); int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); -int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); int do_wget(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[]); #endif /* __NET_LWIP_H__ */ diff --git a/include/net6.h b/include/net6.h index 1ed989e584a..2ceeaba0639 100644 --- a/include/net6.h +++ b/include/net6.h @@ -90,6 +90,16 @@ struct udp_hdr { 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x00, \ 0x00, 0x00, 0x00, 0x02 } } } +/* + * With IPv6, the broadcast MAC address is not used. Instead, it should use + * the multicast address (see RFC RFC2464 section 7) + */ +#define IPV6_ALL_NODE_ETH_ADDR(_ip6_addr) {0x33, \ + 0x33, \ + _ip6_addr.in6_u.u6_addr8[12], \ + _ip6_addr.in6_u.u6_addr8[13], \ + _ip6_addr.in6_u.u6_addr8[14], \ + _ip6_addr.in6_u.u6_addr8[15]} #define IPV6_LINK_LOCAL_PREFIX 0xfe80 #define IPV6_LINK_LOCAL_MASK 0xffb0 /* The first 10-bit of address mask. */ diff --git a/include/power-domain.h b/include/power-domain.h index ad33dea76ce..18525073e5e 100644 --- a/include/power-domain.h +++ b/include/power-domain.h @@ -147,82 +147,38 @@ static inline int power_domain_free(struct power_domain *power_domain) #endif /** - * power_domain_on_lowlevel - Enable power to a power domain (with refcounting) + * power_domain_on - Enable power to a power domain. * * @power_domain: A power domain struct that was previously successfully * requested by power_domain_get(). - * Return: 0 if the transition has been performed correctly, - * -EALREADY if the domain is already on, - * a negative error code otherwise. + * Return: 0 if OK, or a negative error code. */ #if CONFIG_IS_ENABLED(POWER_DOMAIN) -int power_domain_on_lowlevel(struct power_domain *power_domain); +int power_domain_on(struct power_domain *power_domain); #else -static inline int power_domain_on_lowlevel(struct power_domain *power_domain) +static inline int power_domain_on(struct power_domain *power_domain) { return -ENOSYS; } #endif /** - * power_domain_on - Enable power to a power domain (ignores the actual state - * of the power domain) - * - * @power_domain: A power domain struct that was previously successfully - * requested by power_domain_get(). - * Return: a negative error code upon error during the transition, 0 otherwise. - */ -static inline int power_domain_on(struct power_domain *power_domain) -{ - int ret; - - ret = power_domain_on_lowlevel(power_domain); - if (ret == -EALREADY) - ret = 0; - - return ret; -} - -/** - * power_domain_off_lowlevel - Disable power to a power domain (with refcounting) + * power_domain_off - Disable power to a power domain. * * @power_domain: A power domain struct that was previously successfully * requested by power_domain_get(). - * Return: 0 if the transition has been performed correctly, - * -EALREADY if the domain is already off, - * -EBUSY if another device is keeping the domain on (but the refcounter - * is decremented), - * a negative error code otherwise. + * Return: 0 if OK, or a negative error code. */ #if CONFIG_IS_ENABLED(POWER_DOMAIN) -int power_domain_off_lowlevel(struct power_domain *power_domain); +int power_domain_off(struct power_domain *power_domain); #else -static inline int power_domain_off_lowlevel(struct power_domain *power_domain) +static inline int power_domain_off(struct power_domain *power_domain) { return -ENOSYS; } #endif /** - * power_domain_off - Disable power to a power domain (ignores the actual state - * of the power domain) - * - * @power_domain: A power domain struct that was previously successfully - * requested by power_domain_get(). - * Return: a negative error code upon error during the transition, 0 otherwise. - */ -static inline int power_domain_off(struct power_domain *power_domain) -{ - int ret; - - ret = power_domain_off_lowlevel(power_domain); - if (ret == -EALREADY || ret == -EBUSY) - ret = 0; - - return ret; -} - -/** * dev_power_domain_on - Enable power domains for a device . * * @dev: The client device. diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index 17fbfad116f..d78bf7d6191 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -51,6 +51,7 @@ efi_selftest_variables_runtime.o \ efi_selftest_watchdog.o obj-$(CONFIG_EFI_ECPT) += efi_selftest_ecpt.o +obj-$(CONFIG_ARM64) += efi_selftest_el.o obj-$(CONFIG_NETDEVICES) += efi_selftest_snp.o obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_http.o obj-$(CONFIG_EFI_HTTP_PROTOCOL) += efi_selftest_ipconfig.o diff --git a/lib/efi_selftest/efi_selftest_el.c b/lib/efi_selftest/efi_selftest_el.c new file mode 100644 index 00000000000..f9941caf22d --- /dev/null +++ b/lib/efi_selftest/efi_selftest_el.c @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Check current exception level on ARMv8. + */ +#include <efi_loader.h> +#include <efi_selftest.h> + +/** + * current_exception_level() + * + * Return: current exception level, 0 - 3 + */ +static unsigned int current_exception_level(void) +{ + unsigned long el; + + asm volatile ( + "MRS %0, CurrentEL" + : "=r" (el) : : ); + + return (el >> 2) & 0x3; +} + +/** + * execute() - execute test + * + * Check that the exception level is not EL3. + */ +static int execute(void) +{ + unsigned int el = current_exception_level(); + + efi_st_printf("Exception level EL%u\n", el); + if (el != 1 && el != 2) { + efi_st_error("EL1 or EL2 expected"); + return EFI_ST_FAILURE; + } + + return EFI_ST_SUCCESS; +} + +EFI_UNIT_TEST(el) = { + .name = "exception level", + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, + .execute = execute, +}; diff --git a/lib/uuid.c b/lib/uuid.c index 75658778044..6abbcf27b1f 100644 --- a/lib/uuid.c +++ b/lib/uuid.c @@ -67,8 +67,11 @@ static const struct { efi_guid_t guid; } list_guid[] = { #ifndef USE_HOSTCC +#if defined(CONFIG_PARTITION_TYPE_GUID) || defined(CONFIG_CMD_EFIDEBUG) || \ + defined(CONFIG_EFI) + {"EFI System Partition", PARTITION_SYSTEM_GUID}, +#endif #ifdef CONFIG_PARTITION_TYPE_GUID - {"system", PARTITION_SYSTEM_GUID}, {"mbr", LEGACY_MBR_PARTITION_GUID}, {"msft", PARTITION_MSFT_RESERVED_GUID}, {"data", PARTITION_BASIC_DATA_GUID}, @@ -182,10 +185,6 @@ static const struct { { "TCG2", EFI_TCG2_PROTOCOL_GUID, - }, - { - "System Partition", - PARTITION_SYSTEM_GUID }, { "Firmware Management", diff --git a/net/Makefile b/net/Makefile index 41edbacabc9..d63f62b7c8a 100644 --- a/net/Makefile +++ b/net/Makefile @@ -11,7 +11,6 @@ obj-$(CONFIG_NET) += arp.o obj-$(CONFIG_CMD_BOOTP) += bootp.o obj-$(CONFIG_CMD_CDP) += cdp.o obj-$(CONFIG_CMD_DNS) += dns.o -obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_CMD_LINK_LOCAL) += link_local.o obj-$(CONFIG_IPV6) += ndisc.o obj-$(CONFIG_$(PHASE_)DM_ETH) += net.o @@ -39,6 +38,7 @@ CFLAGS_eth_common.o += -Wno-format-extra-args endif ifeq ($(filter y,$(CONFIG_NET) $(CONFIG_NET_LWIP)),y) +obj-$(CONFIG_DM_DSA) += dsa-uclass.o obj-$(CONFIG_$(PHASE_)DM_ETH) += eth-uclass.o obj-$(CONFIG_$(PHASE_)BOOTDEV_ETH) += eth_bootdev.o obj-$(CONFIG_DM_MDIO) += mdio-uclass.o diff --git a/net/dhcpv6.c b/net/dhcpv6.c index 54619ee6983..0c2de75ba1d 100644 --- a/net/dhcpv6.c +++ b/net/dhcpv6.c @@ -29,6 +29,10 @@ int updated_sol_max_rt_ms = SOL_MAX_RT_MS; /* state machine parameters/variables */ struct dhcp6_sm_params sm_params; +/* DHCPv6 all server IP6 address */ +const struct in6_addr dhcp_mcast_ip6 = DHCP6_MULTICAST_ADDR; +/* IPv6 multicast ethernet address */ +const u8 net_dhcp6_mcast_ethaddr[6] = IPV6_ALL_NODE_ETH_ADDR(dhcp_mcast_ip6); static void dhcp6_state_machine(bool timeout, uchar *rx_pkt, unsigned int len); @@ -171,7 +175,6 @@ static int dhcp6_add_option(int option_id, uchar *pkt) */ static void dhcp6_send_solicit_packet(void) { - struct in6_addr dhcp_bcast_ip6; int len = 0; uchar *pkt; uchar *dhcp_pkt_start_ptr; @@ -200,9 +203,8 @@ static void dhcp6_send_solicit_packet(void) len = pkt - dhcp_pkt_start_ptr; /* send UDP packet to DHCP6 multicast address */ - string_to_ip6(DHCP6_MULTICAST_ADDR, sizeof(DHCP6_MULTICAST_ADDR), &dhcp_bcast_ip6); net_set_udp_handler(dhcp6_handler); - net_send_udp_packet6((uchar *)net_bcast_ethaddr, &dhcp_bcast_ip6, + net_send_udp_packet6((uchar *)net_dhcp6_mcast_ethaddr, (struct in6_addr *)&dhcp_mcast_ip6, PORT_DHCP6_S, PORT_DHCP6_C, len); } @@ -218,7 +220,6 @@ static void dhcp6_send_solicit_packet(void) */ static void dhcp6_send_request_packet(void) { - struct in6_addr dhcp_bcast_ip6; int len = 0; uchar *pkt; uchar *dhcp_pkt_start_ptr; @@ -252,9 +253,8 @@ static void dhcp6_send_request_packet(void) len = pkt - dhcp_pkt_start_ptr; /* send UDP packet to DHCP6 multicast address */ - string_to_ip6(DHCP6_MULTICAST_ADDR, strlen(DHCP6_MULTICAST_ADDR), &dhcp_bcast_ip6); net_set_udp_handler(dhcp6_handler); - net_send_udp_packet6((uchar *)net_bcast_ethaddr, &dhcp_bcast_ip6, + net_send_udp_packet6((uchar *)net_dhcp6_mcast_ethaddr, (struct in6_addr *)&dhcp_mcast_ip6, PORT_DHCP6_S, PORT_DHCP6_C, len); } @@ -473,8 +473,7 @@ static int dhcp6_check_advertise_packet(uchar *rx_pkt, unsigned int len) * server UID, save the new server UID and preference */ if (!sm_params.server_uid.uid_ptr || - (sm_params.server_uid.uid_ptr && - sm_params.server_uid.preference < sm_params.rx_status.preference)) { + sm_params.server_uid.preference < sm_params.rx_status.preference) { rx_uid_size = sm_params.rx_status.server_uid_size; if (sm_params.server_uid.uid_ptr) free(sm_params.server_uid.uid_ptr); diff --git a/net/dhcpv6.h b/net/dhcpv6.h index 65c8e4c71d3..d41a3c30615 100644 --- a/net/dhcpv6.h +++ b/net/dhcpv6.h @@ -40,7 +40,13 @@ /* vendor-class-data to send in vendor clas option */ #define DHCP6_VCI_STRING "U-Boot" -#define DHCP6_MULTICAST_ADDR "ff02::1:2" /* DHCP multicast address */ +/* + * All-DHCPv6 server multicast address + */ +#define DHCP6_MULTICAST_ADDR { { { 0xFF, 0x02, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x00, 0x00, 0x00, \ + 0x00, 0x01, 0x00, 0x02 } } } /* DHCP6 States supported */ enum dhcp6_state { diff --git a/net/lwip/dhcp.c b/net/lwip/dhcp.c index 3b7e4700c6e..92bd7067a7f 100644 --- a/net/lwip/dhcp.c +++ b/net/lwip/dhcp.c @@ -115,7 +115,8 @@ int do_dhcp(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) int ret; struct udevice *dev; - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; dev = eth_get_dev(); if (!dev) { diff --git a/net/lwip/dns.c b/net/lwip/dns.c index 149bdb784dc..19172ac959a 100644 --- a/net/lwip/dns.c +++ b/net/lwip/dns.c @@ -121,7 +121,8 @@ int do_dns(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (argc == 3) var = argv[2]; - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) + return CMD_RET_FAILURE; return dns_loop(eth_get_dev(), name, var); } diff --git a/net/lwip/net-lwip.c b/net/lwip/net-lwip.c index 6b7b696dbf0..f05c4cd3f64 100644 --- a/net/lwip/net-lwip.c +++ b/net/lwip/net-lwip.c @@ -14,6 +14,7 @@ #include <lwip/init.h> #include <lwip/prot/etharp.h> #include <net.h> +#include <timer.h> /* xx:xx:xx:xx:xx:xx\0 */ #define MAC_ADDR_STRLEN 18 @@ -21,6 +22,8 @@ #if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER) void (*push_packet)(void *, int len) = 0; #endif +static int net_try_count; +static int net_restarted; int net_restart_wrap; static uchar net_pkt_buf[(PKTBUFSRX) * PKTSIZE_ALIGN + PKTALIGN]; uchar *net_rx_packets[PKTBUFSRX]; @@ -134,18 +137,27 @@ static int get_udev_ipv4_info(struct udevice *dev, ip4_addr_t *ip, return 0; } -/* Initialize the lwIP stack and the ethernet devices and set current device */ -void net_lwip_set_current(void) +/* + * Initialize the network stack if needed and start the current device if valid + */ +int net_lwip_eth_start(void) { - static bool init_done; - - if (!init_done) { - eth_init_rings(); - eth_init(); - lwip_init(); - init_done = true; + int ret; + + net_init(); + if (eth_is_on_demand_init()) { + eth_halt(); + eth_set_current(); + ret = eth_init(); + if (ret < 0) { + eth_halt(); + return ret; + } + } else { + eth_init_state_only(); } - eth_set_current(); + + return 0; } static struct netif *new_netif(struct udevice *udev, bool with_ip) @@ -224,11 +236,20 @@ void net_lwip_remove_netif(struct netif *netif) free(netif); } +/* + * Initialize the network buffers, an ethernet device, and the lwIP stack + * (once). + */ int net_init(void) { - eth_set_current(); + static bool init_done; - net_lwip_new_netif(eth_get_dev()); + if (!init_done) { + eth_init_rings(); + eth_init(); + lwip_init(); + init_done = true; + } return 0; } @@ -319,5 +340,48 @@ int net_loop(enum proto_t protocol) u32_t sys_now(void) { +#if CONFIG_IS_ENABLED(SANDBOX_TIMER) + return timer_early_get_count(); +#else return get_timer(0); +#endif +} + +int net_start_again(void) +{ + char *nretry; + int retry_forever = 0; + unsigned long retrycnt = 0; + + nretry = env_get("netretry"); + if (nretry) { + if (!strcmp(nretry, "yes")) + retry_forever = 1; + else if (!strcmp(nretry, "no")) + retrycnt = 0; + else if (!strcmp(nretry, "once")) + retrycnt = 1; + else + retrycnt = simple_strtoul(nretry, NULL, 0); + } else { + retrycnt = 0; + retry_forever = 0; + } + + if ((!retry_forever) && (net_try_count > retrycnt)) { + eth_halt(); + /* + * We don't provide a way for the protocol to return an error, + * but this is almost always the reason. + */ + return -ETIMEDOUT; + } + + net_try_count++; + + eth_halt(); +#if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER) + eth_try_another(!net_restarted); +#endif + return eth_init(); } diff --git a/net/lwip/ping.c b/net/lwip/ping.c index c586a96806d..d8042ceecf9 100644 --- a/net/lwip/ping.c +++ b/net/lwip/ping.c @@ -168,10 +168,13 @@ int do_ping(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) if (!ipaddr_aton(argv[1], &addr)) return CMD_RET_USAGE; - net_lwip_set_current(); - - if (ping_loop(eth_get_dev(), &addr) < 0) - return CMD_RET_FAILURE; +restart: + if (net_lwip_eth_start() < 0 || ping_loop(eth_get_dev(), &addr) < 0) { + if (net_start_again() == 0) + goto restart; + else + return CMD_RET_FAILURE; + } return CMD_RET_SUCCESS; } diff --git a/net/lwip/tftp.c b/net/lwip/tftp.c index 123d66b5dba..4f9b2049187 100644 --- a/net/lwip/tftp.c +++ b/net/lwip/tftp.c @@ -280,7 +280,10 @@ int do_tftpb(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) goto out; } - net_lwip_set_current(); + if (net_lwip_eth_start() < 0) { + ret = CMD_RET_FAILURE; + goto out; + } if (tftp_loop(eth_get_dev(), laddr, fname, srvip, port) < 0) ret = CMD_RET_FAILURE; diff --git a/net/lwip/wget.c b/net/lwip/wget.c index ec098148835..a3b82908877 100644 --- a/net/lwip/wget.c +++ b/net/lwip/wget.c @@ -471,7 +471,11 @@ static int wget_loop(struct udevice *udev, ulong dst_addr, char *uri) int wget_do_request(ulong dst_addr, char *uri) { - net_lwip_set_current(); + int ret; + + ret = net_lwip_eth_start(); + if (ret < 0) + return ret; if (!wget_info) wget_info = &default_wget_info; diff --git a/test/cmd/command.c b/test/cmd/command.c index 5ec93d490ba..5b1e5a77e5d 100644 --- a/test/cmd/command.c +++ b/test/cmd/command.c @@ -45,31 +45,32 @@ static int command_test(struct unit_test_state *uts) "setenv list ${list}3", strlen("setenv list 1"), 0); ut_assert(!strcmp("1", env_get("list"))); - ut_asserteq(1, run_command("false", 0)); ut_assertok(run_command("echo", 0)); - ut_asserteq(1, run_command_list("false", -1, 0)); ut_assertok(run_command_list("echo", -1, 0)); -#ifdef CONFIG_HUSH_PARSER - run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0); - run_command("run foo", 0); - ut_assertnonnull(env_get("black")); - ut_asserteq(0, strcmp("1", env_get("black"))); - ut_assertnonnull(env_get("adder")); - ut_asserteq(0, strcmp("2", env_get("adder"))); -#endif - - ut_assertok(run_command("", 0)); - ut_assertok(run_command(" ", 0)); + if (IS_ENABLED(CONFIG_HUSH_PARSER)) { + ut_asserteq(1, run_command("false", 0)); + ut_asserteq(1, run_command_list("false", -1, 0)); + run_command("setenv foo 'setenv black 1\nsetenv adder 2'", 0); + run_command("run foo", 0); + ut_assertnonnull(env_get("black")); + ut_asserteq(0, strcmp("1", env_get("black"))); + ut_assertnonnull(env_get("adder")); + ut_asserteq(0, strcmp("2", env_get("adder"))); + ut_assertok(run_command("", 0)); + ut_assertok(run_command(" ", 0)); + } ut_asserteq(1, run_command("'", 0)); /* Variadic function test-cases */ + if (IS_ENABLED(CONFIG_HUSH_PARSER)) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wformat-zero-length" - ut_assertok(run_commandf("")); + ut_assertok(run_commandf("")); #pragma GCC diagnostic pop - ut_assertok(run_commandf(" ")); + ut_assertok(run_commandf(" ")); + } ut_asserteq(1, run_commandf("'")); ut_assertok(run_commandf("env %s %s", "delete -f", "list")); diff --git a/test/common/print.c b/test/common/print.c index e3711b10809..c48efc2783f 100644 --- a/test/common/print.c +++ b/test/common/print.c @@ -45,11 +45,11 @@ static int print_guid(struct unit_test_state *uts) sprintf(str, "%pUL", guid); ut_asserteq_str("04030201-0605-0807-090A-0B0C0D0E0F10", str); sprintf(str, "%pUs", guid_esp); - if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID)) { /* brace needed */ - ut_asserteq_str("system", str); - } else { + if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) || + IS_ENABLED(CONFIG_CMD_EFIDEBUG) || IS_ENABLED(CONFIG_EFI)) + ut_asserteq_str("EFI System Partition", str); + else ut_asserteq_str("c12a7328-f81f-11d2-ba4b-00a0c93ec93b", str); - } ret = snprintf(str, 4, "%pUL", guid); ut_asserteq(0, str[3]); ut_asserteq(36, ret); diff --git a/test/dm/Makefile b/test/dm/Makefile index 3afcc26ca57..917dafe7d22 100644 --- a/test/dm/Makefile +++ b/test/dm/Makefile @@ -46,9 +46,7 @@ obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi_host.o obj-$(CONFIG_DM_DSA) += dsa.o obj-$(CONFIG_ECDSA_VERIFY) += ecdsa.o obj-$(CONFIG_EFI_MEDIA_SANDBOX) += efi_media.o -ifdef CONFIG_NET obj-$(CONFIG_DM_ETH) += eth.o -endif obj-$(CONFIG_EXTCON) += extcon.o ifneq ($(CONFIG_EFI_PARTITION),) obj-$(CONFIG_FASTBOOT_FLASH_MMC) += fastboot.o diff --git a/test/dm/dsa.c b/test/dm/dsa.c index c6b4e12a758..9a31ae39d95 100644 --- a/test/dm/dsa.c +++ b/test/dm/dsa.c @@ -63,15 +63,15 @@ DM_TEST(dm_test_dsa_probe, UTF_SCAN_FDT); */ static int dm_test_dsa(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.2.3.5"); + char *argv[] = { "ping", "1.1.2.2" }; env_set("ethact", "eth2"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", "lan0"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", "lan1"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); env_set("ethact", ""); diff --git a/test/dm/eth.c b/test/dm/eth.c index 467495863e1..1087ae9572d 100644 --- a/test/dm/eth.c +++ b/test/dm/eth.c @@ -171,18 +171,18 @@ DM_TEST(dm_test_ip6_make_lladdr, UTF_SCAN_FDT); static int dm_test_eth(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; env_set("ethact", "eth@10002000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth@10003000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; @@ -191,22 +191,23 @@ DM_TEST(dm_test_eth, UTF_SCAN_FDT); static int dm_test_eth_alias(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; + env_set("ethact", "eth0"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth6"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); /* Expected to fail since eth1 is not defined in the device tree */ env_set("ethact", "eth1"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); env_set("ethact", "eth5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); return 0; @@ -215,18 +216,18 @@ DM_TEST(dm_test_eth_alias, UTF_SCAN_FDT); static int dm_test_eth_prime(struct unit_test_state *uts) { - net_ping_ip = string_to_ip("1.1.2.2"); + char *argv[] = { "ping", "1.1.2.2" }; /* Expected to be "eth@10003000" because of ethprime variable */ env_set("ethact", NULL); env_set("ethprime", "eth5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10003000", env_get("ethact")); /* Expected to be "eth@10002000" because it is first */ env_set("ethact", NULL); env_set("ethprime", NULL); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); return 0; @@ -249,6 +250,7 @@ DM_TEST(dm_test_eth_prime, UTF_SCAN_FDT); */ static int dm_test_eth_act(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; struct udevice *dev[DM_TEST_ETH_NUM]; const char *ethname[DM_TEST_ETH_NUM] = {"eth@10002000", "eth@10003000", "sbe5", "eth@10004000"}; @@ -258,7 +260,6 @@ static int dm_test_eth_act(struct unit_test_state *uts) int i; memset(ethaddr, '\0', sizeof(ethaddr)); - net_ping_ip = string_to_ip("1.1.2.2"); /* Prepare the test scenario */ for (i = 0; i < DM_TEST_ETH_NUM; i++) { @@ -281,7 +282,7 @@ static int dm_test_eth_act(struct unit_test_state *uts) env_set("ethact", ethname[0]); /* Segment fault might happen if something is wrong */ - ut_asserteq(-ENODEV, net_loop(PING)); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); for (i = 0; i < DM_TEST_ETH_NUM; i++) { /* Restore the env */ @@ -334,15 +335,17 @@ DM_TEST(dm_test_ethaddr, UTF_SCAN_FDT); /* The asserts include a return on fail; cleanup in the caller */ static int _dm_test_eth_rotate1(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* Make sure that the default is to rotate to the next interface */ env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10002000", env_get("ethact")); /* If ethrotate is no, then we should fail on a bad MAC */ env_set("ethact", "eth@10004000"); env_set("ethrotate", "no"); - ut_asserteq(-EINVAL, net_loop(PING)); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); return 0; @@ -350,14 +353,16 @@ static int _dm_test_eth_rotate1(struct unit_test_state *uts) static int _dm_test_eth_rotate2(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* Make sure we can skip invalid devices */ env_set("ethact", "eth@10004000"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("eth@10004000", env_get("ethact")); /* Make sure we can handle device name which is not eth# */ env_set("ethact", "sbe5"); - ut_assertok(net_loop(PING)); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); ut_asserteq_str("sbe5", env_get("ethact")); return 0; @@ -368,9 +373,6 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) char ethaddr[18]; int retval; - /* Set target IP to mock ping */ - net_ping_ip = string_to_ip("1.1.2.2"); - /* Invalidate eth1's MAC address */ memset(ethaddr, '\0', sizeof(ethaddr)); strncpy(ethaddr, env_get("eth6addr"), 17); @@ -396,6 +398,7 @@ static int dm_test_eth_rotate(struct unit_test_state *uts) /* Restore the env */ env_set("ethaddr", ethaddr); } + /* Restore the env */ env_set(".flags", NULL); @@ -406,26 +409,28 @@ DM_TEST(dm_test_eth_rotate, UTF_SCAN_FDT); /* The asserts include a return on fail; cleanup in the caller */ static int _dm_test_net_retry(struct unit_test_state *uts) { + char *argv[] = { "ping", "1.1.2.2" }; + /* - * eth1 is disabled and netretry is yes, so the ping should succeed and - * the active device should be eth0 + * eth0 is disabled and netretry is yes, so the ping should succeed and + * the active device should be eth1 */ - sandbox_eth_disable_response(1, true); - env_set("ethact", "lan1"); + sandbox_eth_disable_response(0, true); + env_set("ethact", "eth@10002000"); env_set("netretry", "yes"); sandbox_eth_skip_timeout(); - ut_assertok(net_loop(PING)); - ut_asserteq_str("eth@10002000", env_get("ethact")); + ut_assertok(do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); + ut_asserteq_str("eth@10003000", env_get("ethact")); /* - * eth1 is disabled and netretry is no, so the ping should fail and the - * active device should be eth1 + * eth0 is disabled and netretry is no, so the ping should fail and the + * active device should be eth0 */ - env_set("ethact", "lan1"); + env_set("ethact", "eth@10002000"); env_set("netretry", "no"); sandbox_eth_skip_timeout(); - ut_asserteq(-ENONET, net_loop(PING)); - ut_asserteq_str("lan1", env_get("ethact")); + ut_asserteq(CMD_RET_FAILURE, do_ping(NULL, 0, ARRAY_SIZE(argv), argv)); + ut_asserteq_str("eth@10002000", env_get("ethact")); return 0; } @@ -434,8 +439,6 @@ static int dm_test_net_retry(struct unit_test_state *uts) { int retval; - net_ping_ip = string_to_ip("1.1.2.2"); - retval = _dm_test_net_retry(uts); /* Restore the env */ @@ -446,6 +449,7 @@ static int dm_test_net_retry(struct unit_test_state *uts) } DM_TEST(dm_test_net_retry, UTF_SCAN_FDT); +#if CONFIG_IS_ENABLED(NET) static int sb_check_arp_reply(struct udevice *dev, void *packet, unsigned int len) { @@ -511,7 +515,9 @@ static int sb_with_async_arp_handler(struct udevice *dev, void *packet, return sb_check_arp_reply(dev, packet, len); } +#endif +#if CONFIG_IS_ENABLED(NET) static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) { net_ping_ip = string_to_ip("1.1.2.2"); @@ -529,7 +535,9 @@ static int dm_test_eth_async_arp_reply(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_eth_async_arp_reply, UTF_SCAN_FDT); +#endif +#if CONFIG_IS_ENABLED(NET) static int sb_check_ping_reply(struct udevice *dev, void *packet, unsigned int len) { @@ -613,6 +621,7 @@ static int dm_test_eth_async_ping_reply(struct unit_test_state *uts) return 0; } DM_TEST(dm_test_eth_async_ping_reply, UTF_SCAN_FDT); +#endif #if IS_ENABLED(CONFIG_IPV6_ROUTER_DISCOVERY) diff --git a/test/dm/power-domain.c b/test/dm/power-domain.c index 8a95f6bdb90..896cf5b2ae9 100644 --- a/test/dm/power-domain.c +++ b/test/dm/power-domain.c @@ -27,7 +27,7 @@ static int dm_test_power_domain(struct unit_test_state *uts) ut_assertok(uclass_get_device_by_name(UCLASS_MISC, "power-domain-test", &dev_test)); - ut_asserteq(0, sandbox_power_domain_query(dev_power_domain, + ut_asserteq(1, sandbox_power_domain_query(dev_power_domain, TEST_POWER_DOMAIN)); ut_assertok(sandbox_power_domain_test_get(dev_test)); diff --git a/test/py/tests/test_fs/conftest.py b/test/py/tests/test_fs/conftest.py index c73fb4abbcb..0205048e73a 100644 --- a/test/py/tests/test_fs/conftest.py +++ b/test/py/tests/test_fs/conftest.py @@ -17,7 +17,7 @@ supported_fs_fat = ['fat12', 'fat16'] supported_fs_mkdir = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic'] supported_fs_unlink = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic'] supported_fs_symlink = ['ext4'] -supported_fs_rename = ['fat12', 'fat16', 'fat32'] +supported_fs_rename = ['fat12', 'fat16', 'fat32', 'exfat', 'fs_generic'] # # Filesystem test specific setup diff --git a/test/py/tests/test_fs/test_basic.py b/test/py/tests/test_fs/test_basic.py index 64a3b50f52a..88b163ce305 100644 --- a/test/py/tests/test_fs/test_basic.py +++ b/test/py/tests/test_fs/test_basic.py @@ -35,6 +35,19 @@ class TestFsBasic(object): '%sls host 0:0 invalid_d' % fs_cmd_prefix) assert('' == output) + with ubman.log.section('Test Case 1c - test -e'): + # Test Case 1 - test -e + output = ubman.run_command_list([ + 'host bind 0 %s' % fs_img, + 'test -e host 0:0 1MB.file && echo PASS']) + assert('PASS' in ''.join(output)) + + with ubman.log.section('Test Case 1d - test -e (invalid file)'): + # In addition, test with a nonexistent file to see if we crash. + output = ubman.run_command( + 'test -e host 0:0 2MB.file || echo PASS') + assert('PASS' in ''.join(output)) + def test_fs2(self, ubman, fs_obj_basic): """ Test Case 2 - size command for a small file diff --git a/tools/rkcommon.c b/tools/rkcommon.c index 3e52236b15a..a0caa029cc0 100644 --- a/tools/rkcommon.c +++ b/tools/rkcommon.c @@ -134,7 +134,9 @@ 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 }, + { "rk3576", "RK35", 0x80000 - 0x1000, false, RK_HEADER_V2 }, { "rk3588", "RK35", 0x100000 - 0x1000, false, RK_HEADER_V2 }, }; |