summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2026-06-29 13:44:52 -0600
committerTom Rini <trini@konsulko.com>2026-06-29 15:29:56 -0600
commit0d8e33717d7e5b2a4034cc88f18bf233f77801e7 (patch)
tree2ec6524c4386254d6abff755ce88759f5a01975c
parentd5046398433e48e7b0b664c1ee3e4e2af6f861a8 (diff)
parent4a72fd9fb09109857303ca64fd259009e1d4b554 (diff)
downloadu-boot-0d8e33717d7e5b2a4034cc88f18bf233f77801e7.tar.gz
u-boot-0d8e33717d7e5b2a4034cc88f18bf233f77801e7.zip
Merge patch series "arm: aspeed: add initial AST2700 SoC support"
Ryan Chen <ryan_chen@aspeedtech.com> says: AST2700 is the 8th generation of Integrated Remote Management Processor introduced by ASPEED Technology Inc. It is a Board Management Controller (BMC) SoC family with a dual-die architecture: SoC0 ("CPU" die with four ARM Cortex-A35 application cores) and SoC1 ("IO" die with peripherals) each SoC have its own SCU PLLs, clock dividers and reset domains. Link: https://lore.kernel.org/r/20260612-ast2700_clk-v4-0-9bea29cfdc39@aspeedtech.com
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arm/dts/Makefile2
-rw-r--r--arch/arm/dts/ast2700-evb.dts88
-rw-r--r--arch/arm/dts/ast2700-u-boot.dtsi25
-rw-r--r--arch/arm/dts/ast2700.dtsi693
-rw-r--r--arch/arm/include/asm/arch-aspeed/fmc_hdr.h52
-rw-r--r--arch/arm/include/asm/arch-aspeed/platform.h30
-rw-r--r--arch/arm/include/asm/arch-aspeed/scu.h145
-rw-r--r--arch/arm/include/asm/arch-aspeed/scu_ast2700.h514
-rw-r--r--arch/arm/include/asm/arch-aspeed/sdram.h137
-rw-r--r--arch/arm/mach-aspeed/Kconfig11
-rw-r--r--arch/arm/mach-aspeed/Makefile1
-rw-r--r--arch/arm/mach-aspeed/ast2700/Kconfig36
-rw-r--r--arch/arm/mach-aspeed/ast2700/Makefile2
-rw-r--r--arch/arm/mach-aspeed/ast2700/arm64-mmu.c43
-rw-r--r--arch/arm/mach-aspeed/ast2700/board_common.c90
-rw-r--r--arch/arm/mach-aspeed/ast2700/cpu-info.c114
-rw-r--r--arch/arm/mach-aspeed/ast2700/lowlevel_init.S132
-rw-r--r--arch/arm/mach-aspeed/ast2700/platform.c64
-rw-r--r--board/aspeed/evb_ast2700/Kconfig13
-rw-r--r--board/aspeed/evb_ast2700/Makefile1
-rw-r--r--board/aspeed/evb_ast2700/evb_ast2700.c5
-rw-r--r--configs/evb-ast2700_defconfig160
-rw-r--r--drivers/clk/aspeed/Makefile1
-rw-r--r--drivers/clk/aspeed/clk_ast2700.c952
-rw-r--r--drivers/ram/aspeed/Kconfig2
-rw-r--r--drivers/ram/aspeed/Makefile1
-rw-r--r--drivers/ram/aspeed/sdram_ast2700.c15
-rw-r--r--drivers/reset/Kconfig9
-rw-r--r--drivers/reset/Makefile1
-rw-r--r--drivers/reset/reset-ast2700.c82
-rw-r--r--drivers/spi/spi-aspeed-smc.c219
-rw-r--r--include/configs/evb_ast2700.h58
33 files changed, 3641 insertions, 68 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 370bcff56c1..3ac7b151241 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -214,11 +214,13 @@ M: Chia-Wei Wang <chiawei_wang@aspeedtech.com>
R: Aspeed BMC SW team <BMC-SW@aspeedtech.com>
R: Joel Stanley <joel@jms.id.au>
S: Maintained
+F: arch/arm/dts/ast*
F: drivers/i2c/ast_i2c.[ch]
F: drivers/net/ftgmac100.[ch]
F: drivers/watchdog/ast_wdt.c
N: aspeed
N: ast2500
+N: ast2700
ARM AXIADO AX3005 SCM3005
M: Siu Ming Tong <smtong@axiado.com>
@@ -230,6 +232,15 @@ F: arch/arm/mach-axiado/
F: board/axiado/scm3005/
F: configs/ax3005_scm3005_defconfig
F: include/configs/ax3005-scm3005.h
+=======
+F: drivers/pinctrl/aspeed/
+F: drivers/pwm/pwm-aspeed.c
+F: drivers/ram/aspeed/
+F: drivers/reset/reset-ast*.c
+F: drivers/watchdog/ast_wdt.c
+N: aspeed
+N: ast2700
+>>>>>>> 4a72fd9fb09109857303ca64fd259009e1d4b554
ARM BROADCOM BCM283X / BCM27XX
M: Matthias Brugger <mbrugger@suse.com>
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index a29d1807e71..25234697e6a 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1024,6 +1024,8 @@ dtb-$(CONFIG_ASPEED_AST2600) += \
ast2600-evb.dtb \
ast2600-sbp1.dtb \
ast2600-x4tf.dtb
+dtb-$(CONFIG_ASPEED_AST2700) += \
+ ast2700-evb.dtb
dtb-$(CONFIG_STM32MP15X) += \
stm32mp157c-odyssey.dtb
diff --git a/arch/arm/dts/ast2700-evb.dts b/arch/arm/dts/ast2700-evb.dts
new file mode 100644
index 00000000000..e7222d9691f
--- /dev/null
+++ b/arch/arm/dts/ast2700-evb.dts
@@ -0,0 +1,88 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+/dts-v1/;
+
+#include "ast2700.dtsi"
+#include "ast2700-u-boot.dtsi"
+
+/ {
+ model = "AST2700 EVB";
+ compatible = "aspeed,ast2700-evb", "aspeed,ast2700";
+
+ memory@400000000 {
+ device_type = "memory";
+ reg = <0x4 0x00000000 0x0 0x20000000>;
+ };
+
+ chosen {
+ stdout-path = &uart12;
+ };
+
+};
+
+&uart12 {
+ status = "okay";
+};
+
+&mdio0 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&mdio1 {
+ status = "okay";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ ethphy1: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
+
+&mac0 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy0>;
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+};
+
+&mac1 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&ethphy1>;
+ rx-internal-delay-ps = <0>;
+ tx-internal-delay-ps = <0>;
+};
+
+&fmc {
+ status = "okay";
+
+ flash@0 {
+ status = "okay";
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+
+ flash@1 {
+ status = "okay";
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+
+ flash@2 {
+ status = "okay";
+ spi-max-frequency = <50000000>;
+ spi-tx-bus-width = <4>;
+ spi-rx-bus-width = <4>;
+ };
+};
+
+&wdt0 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/ast2700-u-boot.dtsi b/arch/arm/dts/ast2700-u-boot.dtsi
new file mode 100644
index 00000000000..8830eca3a43
--- /dev/null
+++ b/arch/arm/dts/ast2700-u-boot.dtsi
@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+&soc0 {
+ bootph-all;
+};
+
+&sdrammc {
+ bootph-all;
+};
+
+&syscon0 {
+ bootph-all;
+};
+
+&uart12 {
+ bootph-all;
+};
+
+&soc1 {
+ bootph-all;
+};
+
+&syscon1 {
+ bootph-all;
+};
diff --git a/arch/arm/dts/ast2700.dtsi b/arch/arm/dts/ast2700.dtsi
new file mode 100644
index 00000000000..3dd6826fd0c
--- /dev/null
+++ b/arch/arm/dts/ast2700.dtsi
@@ -0,0 +1,693 @@
+// SPDX-License-Identifier: GPL-2.0+
+#include <dt-bindings/clock/aspeed,ast2700-scu.h>
+#include <dt-bindings/gpio/aspeed-gpio.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy.h>
+#include <dt-bindings/reset/aspeed,ast2700-scu.h>
+
+/ {
+ model = "Aspeed BMC";
+ compatible = "aspeed,ast2700";
+ interrupt-parent = <&gic>;
+ #address-cells = <2>;
+ #size-cells = <2>;
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart1;
+ serial2 = &uart2;
+ serial3 = &uart3;
+ serial4 = &uart4;
+ serial5 = &uart5;
+ serial6 = &uart6;
+ serial7 = &uart7;
+ serial8 = &uart8;
+ serial9 = &uart9;
+ serial10 = &uart10;
+ serial11 = &uart11;
+ serial12 = &uart12;
+ mmc0 = &emmc;
+ mmc1 = &sdhci;
+ ethernet0 = &mac0;
+ ethernet1 = &mac1;
+ ethernet2 = &mac2;
+ };
+
+ cpus {
+ #address-cells = <2>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x0>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu@1 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x1>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu@2 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x2>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ cpu@3 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a35";
+ reg = <0x0 0x3>;
+ enable-method = "psci";
+ next-level-cache = <&l2>;
+ };
+
+ l2: l2-cache0 {
+ compatible = "cache";
+ };
+
+ };
+
+ arm-pmu {
+ compatible = "arm,cortex-a35-pmu";
+ interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ timer {
+ compatible = "arm,armv8-timer";
+ interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+ <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+ };
+
+ gic: interrupt-controller@12200000 {
+ compatible = "arm,gic-v3";
+ reg = <0 0x12200000 0 0x10000>, /* GICD */
+ <0 0x12280000 0 0x80000>, /* GICR */
+ <0 0x40440000 0 0x1000>; /* GICC */
+ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ };
+
+ reserved-memory {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges;
+
+ atf: trusted-firmware-a@430000000 {
+ reg = <0x4 0x30000000 0x0 0x80000>;
+ no-map;
+ };
+
+ optee_core: optee-core@430080000 {
+ reg = <0x4 0x30080000 0x0 0x1000000>;
+ no-map;
+ };
+ };
+
+ soc0: soc@10000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x10000000 0x0 0x10000000 0x0 0x4000000>;
+
+ uhci0: usb@12040000 {
+ compatible = "aspeed,ast2700-uhci", "generic-uhci";
+ reg = <0x0 0x12040000 0x0 0x100>;
+ #ports = <2>;
+ clocks = <&syscon0 SCU0_CLK_GATE_UHCICLK>;
+ resets = <&syscon0 SCU0_RESET_UHCI>;
+ status = "disabled";
+ };
+
+ ehci0: usb@12061000 {
+ compatible = "aspeed,ast2700-ehci", "generic-ehci";
+ reg = <0x0 0x12061000 0x0 0x100>;
+ clocks = <&syscon0 SCU0_CLK_GATE_PORTAUSB2CLK>;
+ resets = <&syscon0 SCU0_RESET_PORTA_VHUB_EHCI>;
+ status = "disabled";
+ };
+
+ vhuba0: usb-vhub@12060000 {
+ compatible = "aspeed,ast2700-usb-vhuba0";
+ reg = <0 0x12060000 0 0x350>;
+ clocks = <&syscon0 SCU0_CLK_GATE_PORTAUSB2CLK>;
+ resets = <&syscon0 SCU0_RESET_PORTA_VHUB_EHCI>;
+ status = "disabled";
+ };
+
+ vhubb0: usb-vhub@12062000 {
+ compatible = "aspeed,ast2700-usb-vhubb0";
+ reg = <0x0 0x12062000 0x0 0x350>;
+ clocks = <&syscon0 SCU0_CLK_GATE_PORTBUSB2CLK>;
+ resets = <&syscon0 SCU0_RESET_PORTB_VHUB_EHCI>;
+ status = "disabled";
+ };
+
+ ehci1: usb@12063000 {
+ compatible = "aspeed,ast2700-ehci", "generic-ehci";
+ reg = <0x0 0x12063000 0x0 0x100>;
+ clocks = <&syscon0 SCU0_CLK_GATE_PORTBUSB2CLK>;
+ resets = <&syscon0 SCU0_RESET_PORTB_VHUB_EHCI>;
+ status = "disabled";
+ };
+
+ emmc_controller: sdc@12090000 {
+ compatible = "aspeed,ast2700-sd-controller";
+ reg = <0 0x12090000 0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x0 0x12090000 0x10000>;
+ clocks = <&syscon0 SCU0_CLK_GATE_EMMCCLK>;
+ resets = <&syscon0 SCU0_RESET_EMMC>;
+ status = "disable";
+
+ emmc: sdhci@100 {
+ compatible = "aspeed,ast2700-sdhci";
+ reg = <0x100 0x100>;
+ sdhci,auto-cmd12;
+ clocks = <&syscon0 SCU0_CLK_GATE_EMMCCLK>;
+ status = "disable";
+ };
+ };
+
+ intc0: interrupt-controller@12100000 {
+ compatible = "aspeed,ast2700-intc0";
+ reg = <0x0 0x12100000 0x0 0x3c00>;
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ #interrupt-cells = <1>;
+ };
+
+ sdrammc: sdrammc@12c00000 {
+ compatible = "aspeed,ast2700-sdrammc";
+ reg = <0 0x12c00000 0 0x3000 0 0x13000000 0 0x300 >;
+ clocks = <&syscon0 SCU0_CLK_MPLL>;
+ resets = <&syscon0 SCU0_RESET_SDRAM>;
+ aspeed,scu0 = <&syscon0>;
+ aspeed,scu1 = <&syscon1>;
+ };
+
+ syscon0: syscon@12c02000 {
+ compatible = "aspeed,ast2700-scu0", "syscon", "simple-mfd";
+ reg = <0x0 0x12c02000 0x0 0x1000>;
+ ranges = <0x0 0x0 0x12c02000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ pinctrl0: pinctrl@400 {
+ compatible = "aspeed,ast2700-soc0-pinctrl";
+ reg = <0x400 0x318>;
+ };
+ };
+
+ gpio0: gpio@12c11000 {
+ compatible = "aspeed,ast2700-gpio";
+ reg = <0x0 0x12c11000 0x0 0x1000>;
+ gpio-ranges = <&pinctrl0 0 0 12>;
+ ngpios = <12>;
+ clocks = <&syscon0 SCU0_CLK_APB>;
+ };
+
+ uart4: serial@12c1a000 {
+ compatible = "ns16550a";
+ reg = <0x0 0x12c1a000 0x0 0x1000>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon0 SCU0_CLK_GATE_UART4CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ mbox0: mbox@12c1c200 {
+ compatible = "aspeed,ast2700-mailbox";
+ reg = <0x0 0x12c1c200 0x0 0x100>, <0x0 0x12c1c300 0x0 0x100>;
+ reg-names = "tx", "rx";
+ #mbox-cells = <1>;
+ };
+
+ mbox1: mbox@12c1c600 {
+ compatible = "aspeed,ast2700-mailbox";
+ reg = <0x0 0x12c1c600 0x0 0x100>, <0x0 0x12c1c700 0x0 0x100>;
+ reg-names = "tx", "rx";
+ #mbox-cells = <1>;
+ };
+ };
+
+ soc1: soc@14000000 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges = <0x0 0x14000000 0x0 0x14000000 0x2 0xec000000>;
+
+ fmc: spi@14000000 {
+ reg = <0x0 0x14000000 0x0 0xc4>, <0x1 0x00000000 0x0 0x80000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2700-fmc";
+ status = "disabled";
+ clocks = <&syscon1 SCU1_CLK_AHB>;
+ num-cs = <3>;
+
+ flash@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+
+ flash@1 {
+ reg = <1>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+
+ flash@2 {
+ reg = <2>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
+ spi0: spi@14010000 {
+ reg = <0x0 0x14010000 0x0 0xc4>, <0x1 0x80000000 0x0 0x80000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2700-spi";
+ status = "disabled";
+ clocks = <&syscon1 SCU1_CLK_AHB>;
+ num-cs = <2>;
+
+ flash@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+
+ flash@1 {
+ reg = <1>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
+ spi1: spi@14020000 {
+ reg = <0x0 0x14020000 0x0 0xc4>, <0x2 0x00000000 0x0 0x80000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2700-spi";
+ status = "disabled";
+ clocks = <&syscon1 SCU1_CLK_AHB>;
+ num-cs = <2>;
+
+ flash@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+
+ flash@1 {
+ reg = <1>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
+ spi2: spi@14030000 {
+ reg = <0x0 0x14030000 0x0 0xc4>, <0x2 0x80000000 0x0 0x80000000>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "aspeed,ast2700-spi";
+ status = "disabled";
+ clocks = <&syscon1 SCU1_CLK_AHB>;
+ resets = <&syscon1 SCU1_RESET_SPI2>;
+ num-cs = <2>;
+
+ flash@0 {
+ reg = <0>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+
+ flash@1 {
+ reg = <1>;
+ compatible = "jedec,spi-nor";
+ status = "disabled";
+ };
+ };
+
+ mdio0: mdio@14040000 {
+ compatible = "aspeed,ast2700-mdio";
+ reg = <0 0x14040000 0 0x8>;
+ resets = <&syscon1 SCU1_RESET_MII>;
+ status = "disabled";
+ };
+
+ mdio1: mdio@14040008 {
+ compatible = "aspeed,ast2700-mdio";
+ reg = <0 0x14040008 0 0x8>;
+ resets = <&syscon1 SCU1_RESET_MII>;
+ status = "disabled";
+ };
+
+ mdio2: mdio@14040010 {
+ compatible = "aspeed,ast2700-mdio";
+ reg = <0 0x14040010 0 0x8>;
+ resets = <&syscon1 SCU1_RESET_MII>;
+ status = "disabled";
+ };
+
+ mac0: ftgmac@14050000 {
+ compatible = "aspeed,ast2700-mac", "faraday,ftgmac100";
+ reg = <0x0 0x14050000 0x0 0x200>;
+ clocks = <&syscon1 SCU1_CLK_GATE_MAC0CLK>;
+ resets = <&syscon1 SCU1_RESET_MAC0>;
+ status = "disabled";
+ };
+
+ mac1: ftgmac@14060000 {
+ compatible = "aspeed,ast2700-mac", "faraday,ftgmac100";
+ reg = <0x0 0x14060000 0x0 0x200>;
+ clocks = <&syscon1 SCU1_CLK_GATE_MAC1CLK>;
+ resets = <&syscon1 SCU1_RESET_MAC1>;
+ status = "disabled";
+ };
+
+ mac2: ftgmac@14070000 {
+ compatible = "aspeed,ast2700-mac", "faraday,ftgmac100";
+ reg = <0x0 0x14070000 0x0 0x200>;
+ clocks = <&syscon1 SCU1_CLK_GATE_MAC2CLK>;
+ resets = <&syscon1 SCU1_RESET_MAC2>;
+ status = "disabled";
+ };
+
+ sdio_controller: sdc@14080000 {
+ compatible = "aspeed,ast2700-sd-controller";
+ reg = <0 0x14080000 0 0x100>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ clocks = <&syscon1 SCU1_CLK_GATE_SDCLK>;
+ resets = <&syscon1 SCU1_RESET_SD>;
+ ranges = <0 0 0x14080000 0x10000>;
+ status = "disable";
+
+ sdhci: sdhci@100 {
+ compatible = "aspeed,ast2700-sdhci";
+ reg = <0x100 0x100>;
+ sdhci,auto-cmd12;
+ clocks = <&syscon1 SCU1_CLK_GATE_SDCLK>;
+ };
+ };
+
+ uhci1: usb@14110000 {
+ compatible = "aspeed,ast2700-uhci", "generic-uhci";
+ reg = <0x0 0x14110000 0x0 0x100>;
+ #ports = <2>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UHCICLK>;
+ resets = <&syscon1 SCU1_RESET_UHCI>;
+ status = "disabled";
+ };
+
+ vhubc: usb-vhub@14120000 {
+ compatible = "aspeed,ast2700-usb-vhub";
+ reg = <0x0 0x14120000 0x0 0x820>;
+ clocks = <&syscon1 SCU1_CLK_GATE_PORTCUSB2CLK>;
+ resets = <&syscon1 SCU1_RESET_PORTC_VHUB_EHCI>;
+ aspeed,vhub-downstream-ports = <7>;
+ aspeed,vhub-generic-endpoints = <21>;
+ status = "disabled";
+ };
+
+ ehci2: usb@14121000 {
+ compatible = "aspeed,ast2700-ehci", "generic-ehci";
+ reg = <0x0 0x14121000 0x0 0x100>;
+ clocks = <&syscon1 SCU1_CLK_GATE_PORTCUSB2CLK>;
+ resets = <&syscon1 SCU1_RESET_PORTC_VHUB_EHCI>;
+ status = "disabled";
+ };
+
+ vhubd: usb-vhub@14122000 {
+ compatible = "aspeed,ast2700-usb-vhub";
+ reg = <0x0 0x14122000 0x0 0x820>;
+ clocks = <&syscon1 SCU1_CLK_GATE_PORTDUSB2CLK>;
+ resets = <&syscon1 SCU1_RESET_PORTD_VHUB_EHCI>;
+ aspeed,vhub-downstream-ports = <7>;
+ aspeed,vhub-generic-endpoints = <21>;
+ status = "disabled";
+ };
+
+ ehci3: usb@14123000 {
+ compatible = "aspeed,ast2700-ehci", "generic-ehci";
+ reg = <0x0 0x14123000 0x0 0x100>;
+ clocks = <&syscon1 SCU1_CLK_GATE_PORTDUSB2CLK>;
+ resets = <&syscon1 SCU1_RESET_PORTD_VHUB_EHCI>;
+ status = "disabled";
+ };
+
+ syscon1: syscon@14c02000 {
+ compatible = "aspeed,ast2700-scu1", "syscon", "simple-mfd";
+ reg = <0x0 0x14c02000 0x0 0x1000>;
+ ranges = <0x0 0x0 0x14c02000 0x1000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ #clock-cells = <1>;
+ #reset-cells = <1>;
+
+ pinctrl1: pinctrl@400 {
+ compatible = "aspeed,ast2700-soc1-pinctrl";
+ reg = <0x400 0x2a0>;
+ };
+ };
+
+ gpio1: gpio@14c0b000 {
+ compatible = "aspeed,ast2700-gpio";
+ reg = <0x0 0x14c0b000 0x0 0x1000>;
+ #gpio-cells = <2>;
+ gpio-controller;
+ gpio-ranges = <&pinctrl1 0 0 216>;
+ ngpios = <216>;
+ clocks = <&syscon1 SCU1_CLK_AHB>;
+ };
+
+ intc1: interrupt-controller@14c18000 {
+ compatible = "aspeed,ast2700-intc1";
+ reg = <0 0x14c18000 0 0x400>;
+ interrupt-controller;
+ interrupt-parent = <&intc0>;
+ #interrupt-cells = <1>;
+ };
+
+ uart0: serial@14c33000 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33000 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART0CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart1: serial@14c33100 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33100 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART1CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart2: serial@14c33200 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33200 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART2CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart3: serial@14c33300 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33300 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART3CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart5: serial@14c33400 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33400 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART5CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart6: serial@14c33500 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33500 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART6CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart7: serial@14c33600 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33600 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART7CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart8: serial@14c33700 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33700 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART8CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart9: serial@14c33800 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33800 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART9CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart10: serial@14c33900 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33900 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART10CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart11: serial@14c33a00 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33a00 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART11CLK>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart12: serial@14c33b00 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33b00 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_GATE_UART12CLK>;
+ clock-frequency = <1846154>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart13: serial@14c33c00 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33c00 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_UART13>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ uart14: serial@14c33d00 {
+ compatible = "ns16550a";
+ reg = <0x0 0x14c33d00 0x0 0x100>;
+ reg-shift = <2>;
+ reg-io-width = <4>;
+ clocks = <&syscon1 SCU1_CLK_UART14>;
+ no-loopback-test;
+ status = "disabled";
+ };
+
+ wdt0: watchdog@14c37000 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37000 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt1: watchdog@14c37080 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37080 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt2: watchdog@14c37100 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37100 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt3: watchdog@14c37180 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37180 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt4: watchdog@14c37200 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37200 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt5: watchdog@14c37280 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37280 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt6: watchdog@14c37300 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37300 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt7: watchdog@14c37380 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37380 0x0 0x80>;
+ status = "disabled";
+ };
+
+ wdt_abr: watchdog@14c37400 {
+ compatible = "aspeed,ast2700-wdt";
+ reg = <0x0 0x14c37400 0x0 0x80>;
+ status = "disabled";
+ };
+
+ mbox2: mbox@14c39200 {
+ compatible = "aspeed,ast2700-mailbox";
+ reg = <0x0 0x14c39200 0x0 0x100>, <0x0 0x14c39300 0x0 0x100>;
+ reg-names = "tx", "rx";
+ #mbox-cells = <1>;
+ };
+
+ };
+};
diff --git a/arch/arm/include/asm/arch-aspeed/fmc_hdr.h b/arch/arm/include/asm/arch-aspeed/fmc_hdr.h
new file mode 100644
index 00000000000..c60277e1a81
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/fmc_hdr.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#ifndef __ASM_AST2700_FMC_HDR_H__
+#define __ASM_AST2700_FMC_HDR_H__
+
+#include <linux/types.h>
+
+#define HDR_MAGIC 0x48545341 /* ASTH */
+#define HDR_PB_MAX 30
+
+enum prebuilt_type {
+ PBT_END_MARK = 0x0,
+
+ PBT_DDR4_PMU_TRAIN_IMEM,
+ PBT_DDR4_PMU_TRAIN_DMEM,
+ PBT_DDR4_2D_PMU_TRAIN_IMEM,
+ PBT_DDR4_2D_PMU_TRAIN_DMEM,
+ PBT_DDR5_PMU_TRAIN_IMEM,
+ PBT_DDR5_PMU_TRAIN_DMEM,
+ PBT_DP_FW,
+ PBT_UEFI_X64_AST2700,
+
+ PBT_NUM
+};
+
+struct fmc_hdr_preamble {
+ u32 magic;
+ u32 version;
+};
+
+struct fmc_hdr_body {
+ u32 fmc_size;
+ union {
+ struct {
+ u32 type;
+ u32 size;
+ } pbs[0];
+ u32 raz[29];
+ };
+};
+
+struct fmc_hdr {
+ struct fmc_hdr_preamble preamble;
+ struct fmc_hdr_body body;
+} __packed;
+
+int fmc_hdr_get_prebuilt(u32 type, u32 *ofst, u32 *size);
+
+#endif
diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h
index 589abd4a3f6..82699c03c00 100644
--- a/arch/arm/include/asm/arch-aspeed/platform.h
+++ b/arch/arm/include/asm/arch-aspeed/platform.h
@@ -18,8 +18,36 @@
#define ASPEED_DRAM_BASE 0x80000000
#define ASPEED_SRAM_BASE 0x10000000
#define ASPEED_SRAM_SIZE 0x16000
+#elif defined(CONFIG_ASPEED_AST2700)
+#define ASPEED_CPU_AHBC_BASE 0x12000000
+#define ASPEED_CPU_REVISION_ID 0x12C02000
+#define ASPEED_CPU_SCU_BASE 0x12C02000
+#define ASPEED_CPU_HW_STRAP1 0x12C02010
+#define ASPEED_CPU_RESET_LOG1 0x12C02050
+#define ASPEED_CPU_RESET_LOG2 0x12C02060
+#define ASPEED_CPU_RESET_LOG3 0x12C02070
+#define ASPEED_MAC_COUNT 3
+#define ASPEED_DRAM_BASE 0x400000000
+#define ASPEED_SRAM_BASE 0x10000000
+#define ASPEED_SRAM_SIZE 0x20000
+#define ASPEED_FMC_REG_BASE 0x14000000
+#define ASPEED_FMC_CS0_BASE 0x100000000
+#define ASPEED_FMC_CS0_SIZE 0x80000000
+#define ASPEED_IO_MAC0_BASE 0x14050000
+#define ASPEED_IO_MAC1_BASE 0x14060000
+#define ASPEED_IO_AHBC_BASE 0x140b0000
+#define ASPEED_IO_REVISION_ID 0x14C02000
+#define CHIP_AST2700A1_ID_MASK BIT(16)
+#define ASPEED_IO_SCU_BASE 0x14C02000
+#define ASPEED_IO_HW_STRAP1 0x14C02010
+#define ASPEED_IO_RESET_LOG1 0x14C02050
+#define ASPEED_IO_RESET_LOG2 0x14C02060
+#define ASPEED_IO_RESET_LOG3 0x14C02070
+#define ASPEED_IO_RESET_LOG4 0x14C02080
+#define ASPEED_IO_GPIO_BASE 0x14C0B000
+#define ASPEED_WDTA_BASE 0x14C37400
#else
-#err "Unrecognized Aspeed platform."
+#error "Unrecognized Aspeed platform."
#endif
#endif
diff --git a/arch/arm/include/asm/arch-aspeed/scu.h b/arch/arm/include/asm/arch-aspeed/scu.h
new file mode 100644
index 00000000000..1aa7d38bace
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu.h
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#ifndef __ASM_AST2700_SCU_H__
+#define __ASM_AST2700_SCU_H__
+
+/* SCU0: CPU-die SCU */
+#define SCU0_HWSTRAP 0x010
+#define SCU0_HWSTRAP_DIS_RVAS BIT(30)
+#define SCU0_HWSTRAP_DIS_WDTFULL BIT(25)
+#define SCU0_HWSTRAP_DISARMICE_TZ BIT(22)
+#define SCU0_HWSTRAP_DISABLE_XHCI BIT(21)
+#define SCU0_HWSTRAP_BOOTEMMCSPEED BIT(20)
+#define SCU0_HWSTRAP_VGA_CC BIT(18)
+#define SCU0_HWSTRAP_EN_OPROM BIT(17)
+#define SCU0_HWSTRAP_DISARMICE BIT(16)
+#define SCU0_HWSTRAP_TSPRSNTSEL BIT(9)
+#define SCU0_HWSTRAP_DISDEBUG BIT(8)
+#define SCU0_HWSTRAP_HCLKHPLL BIT(7)
+#define SCU0_HWSTRAP_HCLKSEL GENMASK(6, 5)
+#define SCU0_HWSTRAP_CPUHPLL BIT(4)
+#define SCU0_HWSTRAP_HPLLFREQ GENMASK(3, 2)
+#define SCU0_HWSTRAP_BOOTSPI BIT(1)
+#define SCU0_HWSTRAP_HWSTRAP_DISCPU BIT(0)
+#define SCU0_DBGCTL 0x0c8
+#define SCU0_DBGCTL_MASK GENMASK(14, 0)
+#define SCU0_DBGCTL_UARTDBG BIT(1)
+#define SCU0_RSTCTL1 0x200
+#define SCU0_RSTCTL1_EMMC BIT(17)
+#define SCU0_RSTCTL1_HACE BIT(4)
+#define SCU0_RSTCTL1_CLR 0x204
+#define SCU0_RSTCTL1_CLR_EMMC BIT(17)
+#define SCU0_RSTCTL1_CLR_HACE BIT(4)
+#define SCU0_CLKGATE1 0x240
+#define SCU0_CLKGATE1_EMMC BIT(27)
+#define SCU0_CLKGATE1_HACE BIT(13)
+#define SCU0_CLKGATE1_DDRPHY BIT(11)
+#define SCU0_CLKGATE1_CLR 0x244
+#define SCU0_CLKGATE1_CLR_EMMC BIT(27)
+#define SCU0_CLKGATE1_CLR_HACE BIT(13)
+#define SCU0_CLKGATE1_CLR_DDRPHY BIT(11)
+#define SCU0_VGA0_SCRATCH 0x900
+#define SCU0_VGA0_SCRATCH_DRAM_INIT BIT(6)
+#define SCU0_PCI_MISC70 0xa70
+#define SCU0_PCI_MISC70_EN_PCIEXHCI0 BIT(3)
+#define SCU0_PCI_MISC70_EN_PCIEEHCI0 BIT(2)
+#define SCU0_PCI_MISC70_EN_PCIEVGA0 BIT(0)
+#define SCU0_PCI_MISC80 0xa80
+#define SCU0_PCI_MISC80_EN_PCIEXHCI1 BIT(3)
+#define SCU0_PCI_MISC80_EN_PCIEEHCI1 BIT(2)
+#define SCU0_PCI_MISC80_EN_PCIEVGA1 BIT(0)
+#define SCU0_PCI_MISCF0 0xaf0
+#define SCU0_PCI_MISCF0_EN_PCIEXHCI1 BIT(3)
+#define SCU0_PCI_MISCF0_EN_PCIEEHCI1 BIT(2)
+#define SCU0_PCI_MISCF0_EN_PCIEVGA1 BIT(0)
+#define SCU0_WPROT1 0xe04
+#define SCU0_WPROT1_0C8 BIT(18)
+
+/* SCU1: IO-die SCU */
+#define SCU1_REVISION 0x000
+#define SCU1_REVISION_HWID GENMASK(23, 16)
+#define SCU1_REVISION_CHIP_EFUSE GENMASK(15, 8)
+#define SCU1_HWSTRAP1 0x010
+#define SCU1_HWSTRAP1_DIS_CPTRA BIT(30)
+#define SCU1_HWSTRAP1_RECOVERY_USB_PORT GENMASK(29, 28)
+#define SCU1_HWSTRAP1_RECOVERY_INTERFACE GENMASK(27, 26)
+#define SCU1_HWSTRAP1_RECOVERY_I3C (BIT(26) | BIT(27))
+#define SCU1_HWSTRAP1_RECOVERY_I2C BIT(27)
+#define SCU1_HWSTRAP1_RECOVERY_USB BIT(26)
+#define SCU1_HWSTRAP1_SPI_FLASH_4_BYTE_MODE BIT(25)
+#define SCU1_HWSTRAP1_SPI_FLASH_WAIT_READY BIT(24)
+#define SCU1_HWSTRAP1_BOOT_UFS BIT(23)
+#define SCU1_HWSTRAP1_DIS_ROM BIT(22)
+#define SCU1_HWSTRAP1_DIS_CPTRAJTAG BIT(20)
+#define SCU1_HWSTRAP1_UARTDBGSEL BIT(19)
+#define SCU1_HWSTRAP1_DIS_UARTDBG BIT(18)
+#define SCU1_HWSTRAP1_DIS_WDTFULL BIT(17)
+#define SCU1_HWSTRAP1_DISDEBUG1 BIT(16)
+#define SCU1_HWSTRAP1_LTPI0_IO_DRIVING GENMASK(15, 14)
+#define SCU1_HWSTRAP1_ACPI_1 BIT(13)
+#define SCU1_HWSTRAP1_ACPI_0 BIT(12)
+#define SCU1_HWSTRAP1_BOOT_EMMC_UFS BIT(11)
+#define SCU1_HWSTRAP1_DDR4 BIT(10)
+#define SCU1_HWSTRAP1_LOW_SECURE BIT(8)
+#define SCU1_HWSTRAP1_EN_EMCS BIT(7)
+#define SCU1_HWSTRAP1_EN_GPIOPT BIT(6)
+#define SCU1_HWSTRAP1_EN_SECBOOT BIT(5)
+#define SCU1_HWSTRAP1_EN_RECOVERY_BOOT BIT(4)
+#define SCU1_HWSTRAP1_LTPI0_EN BIT(3)
+#define SCU1_HWSTRAP1_LTPI_IDX BIT(2)
+#define SCU1_HWSTRAP1_LTPI1_EN BIT(1)
+#define SCU1_HWSTRAP1_LTPI_MODE BIT(0)
+#define SCU1_HWSTRAP2 0x030
+#define SCU1_HWSTRAP2_FMC_ABR_SINGLE_FLASH BIT(29)
+#define SCU1_HWSTRAP2_FMC_ABR_CS_SWAP_DIS BIT(28)
+#define SCU1_HWSTRAP2_SPI_TPM_PCR_EXT_EN BIT(27)
+#define SCU1_HWSTRAP2_SPI_TPM_HASH_ALGO GENMASK(26, 25)
+#define SCU1_HWSTRAP2_BOOT_SPI_FREQ GENMASK(24, 23)
+#define SCU1_HWSTRAP2_RESERVED GENMASK(22, 19)
+#define SCU1_HWSTRAP2_FWSPI_CRTM GENMASK(18, 17)
+#define SCU1_HWSTRAP2_EN_FWSPIAUX BIT(16)
+#define SCU1_HWSTRAP2_FWSPISIZE GENMASK(15, 13)
+#define SCU1_HWSTRAP2_DIS_REC BIT(12)
+#define SCU1_HWSTRAP2_EN_CPTRA_DBG BIT(11)
+#define SCU1_HWSTRAP2_TPM_PCR_INDEX GENMASK(6, 2)
+#define SCU1_HWSTRAP2_ROM_CLEAR_SRAM BIT(1)
+#define SCU1_HWSTRAP2_ABR BIT(0)
+#define SCU1_RSTLOG0 0x050
+#define SCU1_RSTLOG0_BMC_CPU BIT(12)
+#define SCU1_RSTLOG0_ABR BIT(2)
+#define SCU1_RSTLOG0_EXTRSTN BIT(1)
+#define SCU1_RSTLOG0_SRST BIT(0)
+#define SCU1_MISC1 0x0c0
+#define SCU1_MISC1_UARTDBG_ROUTE GENMASK(23, 22)
+#define SCU1_MISC1_UART12_ROUTE GENMASK(21, 20)
+#define SCU1_DBGCTL 0x0c8
+#define SCU1_DBGCTL_MASK GENMASK(7, 0)
+#define SCU1_DBGCTL_UARTDBG BIT(6)
+#define SCU1_RNG_DATA 0x0f4
+#define SCU1_RSTCTL1 0x200
+#define SCU1_RSTCTL1_I3C(x) (BIT(16) << (x))
+#define SCU1_RSTCTL1_CLR 0x204
+#define SCU1_RSTCTL1_CLR_I3C(x) (BIT(16) << (x))
+#define SCU1_RSTCTL2 0x220
+#define SCU1_RSTCTL2_LTPI1 BIT(22)
+#define SCU1_RSTCTL2_LTPI0 BIT(20)
+#define SCU1_RSTCTL2_I2C BIT(15)
+#define SCU1_RSTCTL2_CPTRA BIT(9)
+#define SCU1_RSTCTL2_CLR 0x224
+#define SCU1_RSTCTL2_CLR_I2C BIT(15)
+#define SCU1_RSTCTL2_CLR_CPTRA BIT(9)
+#define SCU1_CLKGATE1 0x240
+#define SCU1_CLKGATE1_I3C(x) (BIT(16) << (x))
+#define SCU1_CLKGATE1_I2C BIT(15)
+#define SCU1_CLKGATE1_CLR 0x244
+#define SCU1_CLKGATE1_CLR_I3C(x) (BIT(16) << (x))
+#define SCU1_CLKGATE1_CLR_I2C BIT(15)
+#define SCU1_CLKGATE2 0x260
+#define SCU1_CLKGATE2_LTPI1_TX BIT(19)
+#define SCU1_CLKGATE2_LTPI_AHB BIT(10)
+#define SCU1_CLKGATE2_LTPI0_TX BIT(9)
+#define SCU1_CLKGATE2_CLR 0x264
+
+#endif
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2700.h b/arch/arm/include/asm/arch-aspeed/scu_ast2700.h
new file mode 100644
index 00000000000..b973fcc6610
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2700.h
@@ -0,0 +1,514 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#ifndef _ASM_ARCH_SCU_AST2700_H
+#define _ASM_ARCH_SCU_AST2700_H
+
+#include <linux/types.h>
+
+/* SoC0 SCU Register */
+#define SCU_CPU_REVISION_ID_HW GENMASK(23, 16)
+#define SCU_CPU_REVISION_ID_EFUSE GENMASK(15, 8)
+
+#define SCU_CPU_HWSTRAP_DIS_RVAS BIT(30)
+#define SCU_CPU_HWSTRAP_DP_SRC BIT(29)
+#define SCU_CPU_HWSTRAP_DAC_SRC BIT(28)
+#define SCU_CPU_HWSTRAP_VRAM_SIZE GENMASK(11, 10)
+#define SCU_CPU_HWSTRAP_DIS_CPU BIT(0)
+
+#define SCU_CPU_MISC_DP_RESET_SRC BIT(11)
+#define SCU_CPU_MISC_XDMA_CLIENT_EN BIT(4)
+#define SCU_CPU_MISC_2D_CLIENT_EN BIT(3)
+
+#define SCU_CPU_RST_SSP BIT(30)
+#define SCU_CPU_RST_DPMCU BIT(29)
+#define SCU_CPU_RST_DP BIT(28)
+#define SCU_CPU_RST_XDMA1 BIT(26)
+#define SCU_CPU_RST_XDMA0 BIT(25)
+#define SCU_CPU_RST_EMMC BIT(17)
+#define SCU_CPU_RST_EN_DP_PCI BIT(15)
+#define SCU_CPU_RST_CRT BIT(13)
+#define SCU_CPU_RST_RVAS1 BIT(10)
+#define SCU_CPU_RST_RVAS0 BIT(9)
+#define SCU_CPU_RST_2D BIT(7)
+#define SCU_CPU_RST_VIDEO BIT(6)
+#define SCU_CPU_RST_SOC BIT(5)
+#define SCU_CPU_RST_DDRPHY BIT(1)
+
+#define SCU_CPU_RST2_VGA BIT(12)
+#define SCU_CPU_RST2_E2M1 BIT(11)
+#define SCU_CPU_RST2_E2M0 BIT(10)
+#define SCU_CPU_RST2_TSP BIT(9)
+
+#define SCU_CPU_VGA_FUNC_DAC_OUTPUT GENMASK(11, 10)
+#define SCU_CPU_VGA_FUNC_DP_OUTPUT GENMASK(9, 8)
+#define SCU_CPU_VGA_FUNC_DAC_DISABLE BIT(7)
+
+#define SCU_CPU_PCI_MISC0C_FB_SIZE GENMASK(4, 0)
+
+#define SCU_CPU_PCI_MISC70_EN_XHCI BIT(3)
+#define SCU_CPU_PCI_MISC70_EN_EHCI BIT(2)
+#define SCU_CPU_PCI_MISC70_EN_IPMI BIT(1)
+#define SCU_CPU_PCI_MISC70_EN_VGA BIT(0)
+
+#define SCU_CPU_HPLL_P GENMASK(22, 19)
+#define SCU_CPU_HPLL_N GENMASK(18, 13)
+#define SCU_CPU_HPLL_M GENMASK(12, 0)
+
+#define SCU_CPU_HPLL2_LOCK BIT(31)
+#define SCU_CPU_HPLL2_BWADJ GENMASK(11, 0)
+
+#define SCU_CPU_SSP_TSP_RESET_STS BIT(8)
+#define SCU_CPU_SSP_TSP_SRAM_SD BIT(7)
+#define SCU_CPU_SSP_TSP_SRAM_DSLP BIT(6)
+#define SCU_CPU_SSP_TSP_SRAM_SLP BIT(5)
+#define SCU_CPU_SSP_TSP_NIDEN BIT(4)
+#define SCU_CPU_SSP_TSP_DBGEN BIT(3)
+#define SCU_CPU_SSP_TSP_DBG_ENABLE BIT(2)
+#define SCU_CPU_SSP_TSP_RESET BIT(1)
+#define SCU_CPU_SSP_TSP_ENABLE BIT(0)
+
+/* SoC1 SCU Register */
+#define SCU_IO_HWSTRAP_UFS BIT(23)
+#define SCU_IO_HWSTRAP_EMMC BIT(11)
+#define SCU_IO_HWSTRAP_SECBOOT BIT(5)
+#define SCU_IO_HWSTRAP_LTPI0_EN BIT(3)
+#define SCU_IO_HWSTRAP_LTPI1_EN BIT(1)
+
+/* CLK information */
+#define CLKIN_25M 25000000UL
+
+#define SCU_CPU_CLKGATE1_RVAS1 BIT(28)
+#define SCU_CPU_CLKGATE1_RVAS0 BIT(25)
+#define SCU_CPU_CLKGATE1_E2M1 BIT(19)
+#define SCU_CPU_CLKGATE1_DP BIT(18)
+#define SCU_CPU_CLKGATE1_DAC BIT(17)
+#define SCU_CPU_CLKGATE1_E2M0 BIT(12)
+#define SCU_CPU_CLKGATE1_VGA1 BIT(10)
+#define SCU_CPU_CLKGATE1_VGA0 BIT(5)
+
+/*
+ * Clock divider/multiplier configuration struct.
+ * For H-PLL and M-PLL the formula is
+ * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
+ * M - Numerator
+ * N - Denumerator
+ * P - Post Divider
+ * They have the same layout in their control register.
+ *
+ */
+union ast2700_pll_reg {
+ u32 w;
+ struct {
+ uint16_t m : 13; /* bit[12:0] */
+ uint8_t n : 6; /* bit[18:13] */
+ uint8_t p : 4; /* bit[22:19] */
+ uint8_t off : 1; /* bit[23] */
+ uint8_t bypass : 1; /* bit[24] */
+ uint8_t reset : 1; /* bit[25] */
+ uint8_t reserved : 6; /* bit[31:26] */
+ } b;
+};
+
+struct ast2700_pll_cfg {
+ union ast2700_pll_reg reg;
+ unsigned int ext_reg;
+};
+
+struct ast2700_pll_desc {
+ u32 in;
+ u32 out;
+ struct ast2700_pll_cfg cfg;
+};
+
+struct aspeed_clks {
+ ulong id;
+ const char *name;
+};
+
+#ifndef __ASSEMBLY__
+struct ast2700_scu0 {
+ u32 chip_id1; /* 0x000 */
+ u32 rsv_0x04[3]; /* 0x004 ~ 0x00C */
+ u32 hwstrap1; /* 0x010 */
+ u32 hwstrap1_clr; /* 0x014 */
+ u32 rsv_0x18[2]; /* 0x018 ~ 0x01C */
+ u32 hwstrap1_lock; /* 0x020 */
+ u32 hwstrap1_sec1; /* 0x024 */
+ u32 hwstrap1_sec2; /* 0x028 */
+ u32 hwstrap1_sec3; /* 0x02C */
+ u32 rsv_0x30[8]; /* 0x030 ~ 0x4C */
+ u32 sysrest_log1; /* 0x050 */
+ u32 sysrest_log1_sec1; /* 0x054 */
+ u32 sysrest_log1_sec2; /* 0x058 */
+ u32 sysrest_log1_sec3; /* 0x05C */
+ u32 sysrest_log2; /* 0x060 */
+ u32 sysrest_log2_sec1; /* 0x064 */
+ u32 sysrest_log2_sec2; /* 0x068 */
+ u32 sysrest_log2_sec3; /* 0x06C */
+ u32 sysrest_log3; /* 0x070 */
+ u32 sysrest_log3_sec1; /* 0x074 */
+ u32 sysrest_log3_sec2; /* 0x078 */
+ u32 sysrest_log3_sec3; /* 0x07C */
+ u32 rsv_0x80[8]; /* 0x080 ~ 0x9C */
+ u32 probe_sig_select; /* 0x0A0 */
+ u32 probe_sig_enable1; /* 0x0A4 */
+ u32 probe_sig_enable2; /* 0x0A8 */
+ u32 uart_dbg_rate; /* 0x0AC */
+ u32 rsv_0xB0[4]; /* 0x0B0 ~ 0xBC*/
+ u32 misc; /* 0x0C0 */
+ u32 rsv_0xC4; /* 0x0C4 */
+ u32 debug_ctrl; /* 0x0C8 */
+ u32 rsv_0xCC[5]; /* 0x0CC ~ 0x0DC */
+ u32 free_counter_read_low; /* 0x0E0 */
+ u32 free_counter_read_high; /* 0x0E4 */
+ u32 rsv_0xE8[2]; /* 0x0E8 ~ 0x0EC */
+ u32 random_num_ctrl; /* 0x0F0 */
+ u32 random_num_data; /* 0x0F4 */
+ u32 rsv_0xF8[10]; /* 0x0F8 ~ 0x11C */
+ u32 ssp_ctrl_1; /* 0x120 */
+ u32 ssp_ctrl_2; /* 0x124 */
+ u32 ssp_ctrl_3; /* 0x128 */
+ u32 ssp_ctrl_4; /* 0x12C */
+ u32 ssp_ctrl_5; /* 0x130 */
+ u32 ssp_ctrl_6; /* 0x134 */
+ u32 ssp_ctrl_7; /* 0x138 */
+ u32 rsv_0x13c[1]; /* 0x13C */
+ u32 ssp_remap0_base; /* 0x140 */
+ u32 ssp_remap0_size; /* 0x144 */
+ u32 ssp_remap1_base; /* 0x148 */
+ u32 ssp_remap1_size; /* 0x14c */
+ u32 ssp_remap2_base; /* 0x150 */
+ u32 ssp_remap2_size; /* 0x154 */
+ u32 rsv_0x158[2]; /* 0x158 ~ 0x15C */
+ u32 tsp_ctrl_1; /* 0x160 */
+ u32 rsv_0x164[1]; /* 0x164 */
+ u32 tsp_ctrl_3; /* 0x168 */
+ u32 tsp_ctrl_4; /* 0x16C */
+ u32 tsp_ctrl_5; /* 0x170 */
+ u32 tsp_ctrl_6; /* 0x174 */
+ u32 tsp_ctrl_7; /* 0x178 */
+ u32 rsv_0x17c[6]; /* 0x17C ~ 0x190 */
+ u32 tsp_remap_size; /* 0x194 */
+ u32 rsv_0x198[26]; /* 0x198 ~ 0x1FC */
+ u32 modrst1_ctrl; /* 0x200 */
+ u32 modrst1_clr; /* 0x204 */
+ u32 rsv_0x208[2]; /* 0x208 ~ 0x20C */
+ u32 modrst1_lock; /* 0x210 */
+ u32 modrst1_prot1; /* 0x214 */
+ u32 modrst1_prot2; /* 0x218 */
+ u32 modrst1_prot3; /* 0x21C */
+ u32 modrst2_ctrl; /* 0x220 */
+ u32 modrst2_clr; /* 0x224 */
+ u32 rsv_0x228[2]; /* 0x228 ~ 0x22C */
+ u32 modrst2_lock; /* 0x230 */
+ u32 modrst2_prot1; /* 0x234 */
+ u32 modrst2_prot2; /* 0x238 */
+ u32 modrst2_prot3; /* 0x23C */
+ u32 clkgate_ctrl; /* 0x240 */
+ u32 clkgate_clr; /* 0x244 */
+ u32 rsv_0x248[2]; /* 0x248 */
+ u32 clkgate_lock; /* 0x250 */
+ u32 clkgate_secure1; /* 0x254 */
+ u32 clkgate_secure2; /* 0x258 */
+ u32 clkgate_secure3; /* 0x25c */
+ u32 rsv_0x260[8]; /* 0x260 */
+ u32 clk_sel1; /* 0x280 */
+ u32 clk_sel2; /* 0x284 */
+ u32 clk_sel3; /* 0x288 */
+ u32 rsv_0x28c; /* 0x28c */
+ u32 clk_sel1_lock; /* 0x290 */
+ u32 clk_sel2_lock; /* 0x294 */
+ u32 clk_sel3_lock; /* 0x298 */
+ u32 rsv_0x29c; /* 0x29c */
+ u32 clk_sel1_secure1; /* 0x2a0 */
+ u32 clk_sel1_secure2; /* 0x2a4 */
+ u32 clk_sel1_secure3; /* 0x2a8 */
+ u32 rsv_0x2ac; /* 0x2ac */
+ u32 clk_sel2_secure1; /* 0x2b0 */
+ u32 clk_sel2_secure2; /* 0x2b4 */
+ u32 clk_sel2_secure3; /* 0x2b8 */
+ u32 rsv_0x2bc; /* 0x2bc */
+ u32 clk_sel3_secure1; /* 0x2c0 */
+ u32 clk_sel3_secure2; /* 0x2c4 */
+ u32 clk_sel3_secure3; /* 0x2c8 */
+ u32 rsv_0x2cc[9]; /* 0x2cc */
+ u32 extrst_sel; /* 0x2f0 */
+ u32 rsv_0x2f4[3]; /* 0x2f4 */
+ u32 hpll; /* 0x300 */
+ u32 hpll_ext; /* 0x304 */
+ u32 dpll; /* 0x308 */
+ u32 dpll_ext; /* 0x30C */
+ u32 mpll; /* 0x310 */
+ u32 mpll_ext; /* 0x314 */
+ u32 rsv_0x318[2]; /* 0x318 ~ 0x31C */
+ u32 d1clk_para; /* 0x320 */
+ u32 rsv_0x324[3]; /* 0x324 ~ 0x32C */
+ u32 d2clk_para; /* 0x330 */
+ u32 rsv_0x334[3]; /* 0x334 ~ 0x33C */
+ u32 crt1clk_para; /* 0x340 */
+ u32 rsv_0x344[3]; /* 0x344 ~ 0x34C */
+ u32 crt2clk_para; /* 0x350 */
+ u32 rsv_0x354[3]; /* 0x354 ~ 0x35C */
+ u32 mphyclk_para; /* 0x360 */
+ u32 rsv_0x364[7]; /* 0x364 ~ 0x37C */
+ u32 clkduty_meas_ctrl; /* 0x380 */
+ u32 clkduty1; /* 0x384 */
+ u32 clkduty2; /* 0x368 */
+ u32 clkduty_meas_res; /* 0x38c */
+ u32 rsv_0x390[4]; /* 0x390 ~ 0x39C */
+ u32 freq_counter_ctrl; /* 0x3a0 */
+ u32 freq_counter_cmp; /* 0x3a4 */
+ u32 prog_delay_ring_ctrl0; /* 0x3a8 */
+ u32 prog_delay_ring_ctrl1; /* 0x3ac */
+ u32 freq_counter_readback; /* 0x3b0 */
+ u32 rsv_0x3b4[19]; /* 0x3b4 */
+ u32 pinmux1; /* 0x400 */
+ u32 pinmux2; /* 0x404 */
+ u32 pinmux3; /* 0x408 */
+ u32 rsv_0x40c; /* 0x40C */
+ u32 pinmux4; /* 0x410 */
+ u32 vga_func_ctrl; /* 0x414 */
+ u32 rsv_0x418[2]; /* 0x418 */
+ u32 pinmux_lock0; /* 0x420 */
+ u32 pinmux_lock1; /* 0x424 */
+ u32 pinmux_lock2; /* 0x428 */
+ u32 rsv_0x42c;
+ u32 pinmux_lock3; /* 0x430 */
+ u32 pinmux_lock4; /* 0x434 */
+ u32 rsv_0x438[18];
+ u32 gpio18d0_ioctrl; /* 0x480 */
+ u32 gpio18d1_ioctrl; /* 0x484 */
+ u32 gpio18d2_ioctrl; /* 0x488 */
+ u32 gpio18d3_ioctrl; /* 0x48c */
+ u32 gpio18d4_ioctrl; /* 0x490 */
+ u32 gpio18d5_ioctrl; /* 0x494 */
+ u32 gpio18d6_ioctrl; /* 0x498 */
+ u32 gpio18d7_ioctrl; /* 0x49c */
+ u32 gpio18e0_ioctrl; /* 0x4a0 */
+ u32 gpio18e1_ioctrl; /* 0x4a4 */
+ u32 gpio18e2_ioctrl; /* 0x4a8 */
+ u32 gpio18e3_ioctrl; /* 0x4ac */
+ u32 jtag_ioctrl; /* 0x4b0 */
+ u32 uart_ioctrl; /* 0x4b4 */
+ u32 misc_ioctrl; /* 0x4b8 */
+ u32 rsv_0x4bc[17]; /* 0x4bc ~ 0x4fc */
+ u32 pinmux_seucre0_0; /* 0x500 */
+ u32 pinmux_seucre0_1; /* 0x504 */
+ u32 pinmux_seucre0_2; /* 0x508 */
+ u32 rsv_0x50c;
+ u32 pinmux_seucre0_3; /* 0x510 */
+ u32 pinmux_seucre0_4; /* 0x514 */
+ u32 rsv_0x518[58];
+ u32 pinmux_seucre1_0; /* 0x600 */
+ u32 pinmux_seucre1_1; /* 0x604 */
+ u32 pinmux_seucre1_2; /* 0x608 */
+ u32 rsv_0x60c;
+ u32 pinmux_seucre1_3; /* 0x610 */
+ u32 pinmux_seucre1_4; /* 0x614 */
+ u32 rsv_0x618[58];
+ u32 pinmux_seucre2_0; /* 0x700 */
+ u32 pinmux_seucre2_1; /* 0x704 */
+ u32 pinmux_seucre2_2; /* 0x708 */
+ u32 rsv_0x70c;
+ u32 pinmux_seucre2_3; /* 0x710 */
+ u32 pinmux_seucre2s_4; /* 0x714 */
+ u32 rsv_0x718[26];
+ u32 cpu_scratch[96]; /* 0x780 ~ 0x8FC */
+ u32 vga0_scratch1[4]; /* 0x900 ~ 0x90C */
+ u32 vga1_scratch1[4]; /* 0x910 ~ 0x91C */
+ u32 vga0_scratch2[8]; /* 0x920 ~ 0x93C */
+ u32 vga1_scratch2[8]; /* 0x940 ~ 0x95C */
+ u32 pci_cfg1[3]; /* 0x960 ~ 0x968 */
+ u32 rsv_0x96c; /* 0x96C */
+ u32 pcie_cfg1; /* 0x970 */
+ u32 mmio_decode1; /* 0x974 */
+ u32 reloc_ctrl_decode1[2]; /* 0x978 ~ 0x97C */
+ u32 rsv_0x980[4]; /* 0x980 ~ 0x98C */
+ u32 mbox_decode1; /* 0x990 */
+ u32 shared_sram_decode1[2];/* 0x994 ~ 0x998 */
+ u32 rsv_0x99c; /* 0x99C */
+ u32 pci_cfg2[3]; /* 0x9A0 ~ 0x9A8 */
+ u32 rsv_0x9ac; /* 0x9AC */
+ u32 pcie_cfg2; /* 0x9B0 */
+ u32 mmio_decode2; /* 0x9B4 */
+ u32 reloc_ctrl_decode2[2]; /* 0x9B8 ~ 0x9BC */
+ u32 rsv_0x9c0[4]; /* 0x9C0 ~ 0x9CC */
+ u32 mbox_decode2; /* 0x9D0 */
+ u32 shared_sram_decode2[2];/* 0x9D4 ~ 0x9D8 */
+ u32 rsv_0x9dc[9]; /* 0x9DC ~ 0x9FC */
+ u32 pci0_misc[32]; /* 0xA00 ~ 0xA7C */
+ u32 pci1_misc[32]; /* 0xA80 ~ 0xAFC */
+};
+
+struct ast2700_scu1 {
+ u32 chip_id1; /* 0x000 */
+ u32 rsv_0x04[3]; /* 0x004 ~ 0x00C */
+ u32 hwstrap1; /* 0x010 */
+ u32 hwstrap1_clr; /* 0x014 */
+ u32 rsv_0x18[2]; /* 0x018 ~ 0x01C */
+ u32 hwstrap1_lock; /* 0x020 */
+ u32 hwstrap1_sec1; /* 0x024 */
+ u32 hwstrap1_sec2; /* 0x028 */
+ u32 hwstrap1_sec3; /* 0x02C */
+ u32 hwstrap2; /* 0x030 */
+ u32 hwstrap2_clr; /* 0x034 */
+ u32 rsv_0x38[2]; /* 0x038 ~ 0x03C */
+ u32 hwstrap2_lock; /* 0x040 */
+ u32 hwstrap2_sec1; /* 0x044 */
+ u32 hwstrap2_sec2; /* 0x048 */
+ u32 hwstrap2_sec3; /* 0x04C */
+ u32 sysrest_log1; /* 0x050 */
+ u32 sysrest_log1_sec1; /* 0x054 */
+ u32 sysrest_log1_sec2; /* 0x058 */
+ u32 sysrest_log1_sec3; /* 0x05C */
+ u32 sysrest_log2; /* 0x060 */
+ u32 sysrest_log2_sec1; /* 0x064 */
+ u32 sysrest_log2_sec2; /* 0x068 */
+ u32 sysrest_log2_sec3; /* 0x06C */
+ u32 sysrest_log3; /* 0x070 */
+ u32 sysrest_log3_sec1; /* 0x074 */
+ u32 sysrest_log3_sec2; /* 0x078 */
+ u32 sysrest_log3_sec3; /* 0x07C */
+ u32 sysrest_log4; /* 0x080 */
+ u32 sysrest_log4_sec1; /* 0x084 */
+ u32 sysrest_log4_sec2; /* 0x088 */
+ u32 sysrest_log4_sec3; /* 0x08C */
+ u32 rsv_0x90[7]; /* 0x090 ~ 0xA8 */
+ u32 uart_dbg_rate; /* 0x0AC */
+ u32 rsv_0xB0[4]; /* 0x0B0 ~ 0xBC*/
+ u32 misc; /* 0x0C0 */
+ u32 rsv_0xC4; /* 0x0C4 */
+ u32 debug_ctrl; /* 0x0C8 */
+ u32 rsv_0xCC; /* 0x0CC */
+ u32 dac_ctrl; /* 0x0D0 */
+ u32 dac_crc_ctrl; /* 0x0D4 */
+ u32 rsv_0xD8[2]; /* 0x0D8 ~ 0x0DC */
+ u32 video_input_ctrl; /* 0x0E0 */
+ u32 rsv_0xE4[3]; /* 0x0E4 ~ 0x0EC */
+ u32 random_num_ctrl; /* 0x0F0 */
+ u32 random_num_data; /* 0x0F4 */
+ u32 rsv_0xF0[2]; /* 0x0F8 ~ 0x0FC */
+ u32 rsv_0x100[32]; /* 0x100 ~ 0x17C */
+ u32 scratch[32]; /* 0x180 ~ 0x1FC */
+ u32 modrst1_ctrl; /* 0x200 */
+ u32 modrst1_clr; /* 0x204 */
+ u32 rsv_0x208[2]; /* 0x208 ~ 0x20C */
+ u32 modrst_lock1; /* 0x210 */
+ u32 modrst1_sec1; /* 0x214 */
+ u32 modrst1_sec2; /* 0x218 */
+ u32 modrst1_sec3; /* 0x21C */
+ u32 modrst2_ctrl; /* 0x220 */
+ u32 modrst2_clr; /* 0x224 */
+ u32 rsv_0x228[2]; /* 0x228 ~ 0x22C */
+ u32 modrst2_lock; /* 0x230 */
+ u32 modrst2_prot1; /* 0x234 */
+ u32 modrst2_prot2; /* 0x238 */
+ u32 modrst2_prot3; /* 0x23C */
+ u32 clkgate_ctrl1; /* 0x240 */
+ u32 clkgate_clr1; /* 0x244 */
+ u32 rsv_0x248[2]; /* 0x248 */
+ u32 clkgate_lock1; /* 0x250 */
+ u32 clkgate_secure11; /* 0x254 */
+ u32 clkgate_secure12; /* 0x258 */
+ u32 clkgate_secure13; /* 0x25c */
+ u32 clkgate_ctrl2; /* 0x260 */
+ u32 clkgate_clr2; /* 0x264 */
+ u32 rsv_0x268[2]; /* 0x268 */
+ u32 clkgate_lock2; /* 0x270 */
+ u32 clkgate_secure21; /* 0x274 */
+ u32 clkgate_secure22; /* 0x278 */
+ u32 clkgate_secure23; /* 0x27c */
+ u32 clk_sel1; /* 0x280 */
+ u32 clk_sel2; /* 0x284 */
+ u32 rsv_0x288[2]; /* 0x288 */
+ u32 clk_sel1_lock; /* 0x290 */
+ u32 clk_sel2_lock; /* 0x294 */
+ u32 rsv_0x298[2]; /* 0x298 */
+ u32 clk_sel1_secure1; /* 0x2a0 */
+ u32 clk_sel1_secure2; /* 0x2a4 */
+ u32 rsv_0x2a8[2]; /* 0x2a8 */
+ u32 clk_sel2_secure1; /* 0x2b0 */
+ u32 clk_sel2_secure2; /* 0x2b4 */
+ u32 rsv_0x2b8[2]; /* 0x2b8 */
+ u32 clk_sel3_secure1; /* 0x2c0 */
+ u32 clk_sel3_secure2; /* 0x2c4 */
+ u32 rsv_0x2c8[10]; /* 0x2c8 */
+ u32 extrst_sel1; /* 0x2f0 */
+ u32 extrst_sel2; /* 0x2f4 */
+ u32 rsv_0x2f8[2]; /* 0x2f8 */
+ u32 hpll; /* 0x300 */
+ u32 hpll_ext; /* 0x304 */
+ u32 rsv_0x308[2]; /* 0x308 ~ 0x30C */
+ u32 apll; /* 0x310 */
+ u32 apll_ext; /* 0x314 */
+ u32 rsv_0x318[2]; /* 0x318 ~ 0x31C */
+ u32 dpll; /* 0x320 */
+ u32 dpll_ext; /* 0x324 */
+ u32 rsv_0x328[2]; /* 0x328 ~ 0x32C */
+ u32 uxclk_ctrl; /* 0x330 */
+ u32 huxclk_ctrl; /* 0x334 */
+ u32 rsv_0x338[18]; /* 0x338 ~ 0x37C */
+ u32 clkduty_meas_ctrl; /* 0x380 */
+ u32 clkduty1; /* 0x384 */
+ u32 clkduty2; /* 0x388 */
+ u32 rsv_0x38c; /* 0x38c */
+ u32 mac_delay; /* 0x390 */
+ u32 mac_100m_delay; /* 0x394 */
+ u32 mac_10m_delay; /* 0x398 */
+ u32 rsv_0x39c; /* 0x39c */
+ u32 freq_counter_ctrl; /* 0x3a0 */
+ u32 freq_counter_cmp; /* 0x3a4 */
+ u32 rsv_0x3a8[2]; /* 0x3a8 ~ 0x3aC */
+ u32 usb_ctrl; /* 0x3b0 */
+ u32 usb_lock; /* 0x3b4 */
+ u32 usb_secure1; /* 0x3b8 */
+ u32 usb_secure2; /* 0x3bc */
+ u32 usb_secure3; /* 0x3c0 */
+ u32 rsv_0x3c4[15]; /* 0x3c4 ~ 0x3fc */
+ u32 pinumx1; /* 0x400 */
+ u32 pinumx2; /* 0x404 */
+ u32 pinumx3; /* 0x408 */
+ u32 pinumx4; /* 0x40c */
+ u32 pinumx5; /* 0x410 */
+ u32 pinumx6; /* 0x414 */
+ u32 pinumx7; /* 0x418 */
+ u32 pinumx8; /* 0x41c */
+ u32 pinumx9; /* 0x420 */
+ u32 pinumx10; /* 0x424 */
+ u32 pinumx11; /* 0x428 */
+ u32 pinumx12; /* 0x42c */
+ u32 pinumx13; /* 0x430 */
+ u32 pinumx14; /* 0x434 */
+ u32 pinumx15; /* 0x438 */
+ u32 pinumx16; /* 0x43c */
+ u32 pinumx17; /* 0x440 */
+ u32 pinumx18; /* 0x444 */
+ u32 pinumx19; /* 0x448 */
+ u32 pinumx20; /* 0x44c */
+ u32 pinumx21; /* 0x450 */
+ u32 pinumx22; /* 0x454 */
+ u32 pinumx23; /* 0x458 */
+ u32 pinumx24; /* 0x45c */
+ u32 pinumx25; /* 0x460 */
+ u32 pinumx26; /* 0x464 */
+ u32 pinumx27; /* 0x468 */
+ u32 rsv_0x46c[4]; /* 0x46c ~ 0x478 */
+ u32 pinumx31; /* 0x47c */
+ u32 pull_down_dis[8]; /* 0x480 ~ 0x49c */
+ u32 pin_conf; /* 0x4a0 */
+ u32 rsv_0x4a4[7]; /* 0x4a4 ~ 0x4bc */
+ u32 io_driving0; /* 0x4c0 */
+ u32 io_driving1; /* 0x4c4 */
+ u32 io_driving2; /* 0x4c8 */
+ u32 io_driving3; /* 0x4cc */
+ u32 io_driving4; /* 0x4d0 */
+ u32 io_driving5; /* 0x4d4 */
+ u32 io_driving6; /* 0x4d8 */
+ u32 io_driving7; /* 0x4dc */
+ u32 io_driving8; /* 0x4e0 */
+};
+
+#endif
+#endif
diff --git a/arch/arm/include/asm/arch-aspeed/sdram.h b/arch/arm/include/asm/arch-aspeed/sdram.h
new file mode 100644
index 00000000000..daf48dd6ed1
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/sdram.h
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (c) Aspeed Technology Inc.
+ */
+#ifndef __ASM_AST2700_SDRAM_H__
+#define __ASM_AST2700_SDRAM_H__
+
+struct sdrammc_regs {
+ u32 prot_key;
+ u32 intr_status;
+ u32 intr_clear;
+ u32 intr_mask;
+ u32 mcfg;
+ u32 mctl;
+ u32 msts;
+ u32 error_status;
+ u32 actime1;
+ u32 actime2;
+ u32 actime3;
+ u32 actime4;
+ u32 actime5;
+ u32 actime6;
+ u32 actime7;
+ u32 dfi_timing;
+ u32 dcfg;
+ u32 dctl;
+ u32 mrctl;
+ u32 mrwr;
+ u32 mrrd;
+ u32 mr01;
+ u32 mr23;
+ u32 mr45;
+ u32 mr67;
+ u32 refctl;
+ u32 refmng_ctl;
+ u32 refsts;
+ u32 zqctl;
+ u32 ecc_addr_range;
+ u32 ecc_failure_status;
+ u32 ecc_failure_addr;
+ u32 ecc_test_control;
+ u32 ecc_test_status;
+ u32 arbctl;
+ u32 enccfg;
+ u32 protect_lock_set;
+ u32 protect_lock_status;
+ u32 protect_lock_reset;
+ u32 enc_min_addr;
+ u32 enc_max_addr;
+ u32 enc_key[4];
+ u32 enc_iv[3];
+ u32 bistcfg;
+ u32 bist_addr;
+ u32 bist_size;
+ u32 bist_patt;
+ u32 bist_res;
+ u32 bist_fail_addr;
+ u32 bist_fail_data[4];
+ u32 reserved2[2];
+ u32 debug_control;
+ u32 debug_status;
+ u32 phy_intf_status;
+ u32 testcfg;
+ u32 gfmcfg;
+ u32 gfm0ctl;
+ u32 gfm1ctl;
+ u32 reserved3[0xf8];
+};
+
+#define DRAMC_UNLK_KEY 0x1688a8a8
+
+/* offset 0x04 */
+#define DRAMC_IRQSTA_PWRCTL_ERR BIT(16)
+#define DRAMC_IRQSTA_PHY_ERR BIT(15)
+#define DRAMC_IRQSTA_LOWPOWER_DONE BIT(12)
+#define DRAMC_IRQSTA_FREQ_CHG_DONE BIT(11)
+#define DRAMC_IRQSTA_REF_DONE BIT(10)
+#define DRAMC_IRQSTA_ZQ_DONE BIT(9)
+#define DRAMC_IRQSTA_BIST_DONE BIT(8)
+#define DRAMC_IRQSTA_ECC_RCVY_ERR BIT(5)
+#define DRAMC_IRQSTA_ECC_ERR BIT(4)
+#define DRAMC_IRQSTA_PROT_ERR BIT(3)
+#define DRAMC_IRQSTA_OVERSZ_ERR BIT(2)
+#define DRAMC_IRQSTA_MR_DONE BIT(1)
+#define DRAMC_IRQSTA_PHY_INIT_DONE BIT(0)
+
+/* offset 0x14 */
+#define DRAMC_MCTL_WB_SOFT_RESET BIT(24)
+#define DRAMC_MCTL_PHY_CLK_DIS BIT(18)
+#define DRAMC_MCTL_PHY_RESET BIT(17)
+#define DRAMC_MCTL_PHY_POWER_ON BIT(16)
+#define DRAMC_MCTL_FREQ_CHG_START BIT(3)
+#define DRAMC_MCTL_PHY_LOWPOWER_START BIT(2)
+#define DRAMC_MCTL_SELF_REF_START BIT(1)
+#define DRAMC_MCTL_PHY_INIT_START BIT(0)
+
+/* offset 0x40 */
+#define DRAMC_DFICFG_WD_POL BIT(18)
+#define DRAMC_DFICFG_CKE_OUT BIT(17)
+#define DRAMC_DFICFG_RESET BIT(16)
+
+/* offset 0x48 */
+#define DRAMC_MRCTL_ERR_STATUS BIT(31)
+#define DRAMC_MRCTL_READY_STATUS BIT(30)
+#define DRAMC_MRCTL_MR_ADDR BIT(8)
+#define DRAMC_MRCTL_CMD_DLL_RST BIT(7)
+#define DRAMC_MRCTL_CMD_DQ_SEL BIT(6)
+#define DRAMC_MRCTL_CMD_TYPE BIT(2)
+#define DRAMC_MRCTL_CMD_WR_CTL BIT(1)
+#define DRAMC_MRCTL_CMD_START BIT(0)
+
+/* offset 0xC0 */
+#define DRAMC_BISTRES_RUNNING BIT(10)
+#define DRAMC_BISTRES_FAIL BIT(9)
+#define DRAMC_BISTRES_DONE BIT(8)
+#define DRAMC_BISTCFG_INIT_MODE BIT(7)
+#define DRAMC_BISTCFG_PMODE GENMASK(6, 4)
+#define DRAMC_BISTCFG_BMODE GENMASK(3, 2)
+#define DRAMC_BISTCFG_ENABLE BIT(1)
+#define DRAMC_BISTCFG_START BIT(0)
+#define BIST_PMODE_CRC (3)
+#define BIST_BMODE_RW_SWITCH (3)
+
+/* DRAMC048 MR Control Register */
+#define MR_TYPE_SHIFT 2
+#define MR_RW (0 << MR_TYPE_SHIFT)
+#define MR_MPC BIT(2)
+#define MR_VREFCS (2 << MR_TYPE_SHIFT)
+#define MR_VREFCA (3 << MR_TYPE_SHIFT)
+#define MR_ADDRESS_SHIFT 8
+#define MR_ADDR(n) (((n) << MR_ADDRESS_SHIFT) | DRAMC_MRCTL_CMD_WR_CTL)
+#define MR_NUM_SHIFT 4
+#define MR_NUM(n) ((n) << MR_NUM_SHIFT)
+#define MR_DLL_RESET BIT(7)
+#define MR_1T_MODE BIT(16)
+
+#endif
diff --git a/arch/arm/mach-aspeed/Kconfig b/arch/arm/mach-aspeed/Kconfig
index c88b1e59366..f4b038ebd9e 100644
--- a/arch/arm/mach-aspeed/Kconfig
+++ b/arch/arm/mach-aspeed/Kconfig
@@ -36,9 +36,20 @@ config ASPEED_AST2600
It is used as Board Management Controller on many server boards,
which is enabled by support of LPC and eSPI peripherals.
+config ASPEED_AST2700
+ bool "Support Aspeed AST2700 SoC"
+ select ARM64
+ select SYS_ARCH_TIMER
+ help
+ Support for the Aspeed AST2700, an arm64 (Cortex-A35) Baseboard
+ Management Controller (BMC) SoC. This is the 8th-generation BMC
+ SoC family from Aspeed and features a dual-die architecture
+ (CPU die + I/O die) connected via an internal coherent bus.
+
endchoice
source "arch/arm/mach-aspeed/ast2500/Kconfig"
source "arch/arm/mach-aspeed/ast2600/Kconfig"
+source "arch/arm/mach-aspeed/ast2700/Kconfig"
endif
diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile
index 42599c125b8..d0b4eb74c6c 100644
--- a/arch/arm/mach-aspeed/Makefile
+++ b/arch/arm/mach-aspeed/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_ARCH_ASPEED) += ast_wdt.o
obj-$(CONFIG_ASPEED_AST2500) += ast2500/
obj-$(CONFIG_ASPEED_AST2600) += ast2600/
+obj-$(CONFIG_ASPEED_AST2700) += ast2700/
diff --git a/arch/arm/mach-aspeed/ast2700/Kconfig b/arch/arm/mach-aspeed/ast2700/Kconfig
new file mode 100644
index 00000000000..3dd68db76db
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/Kconfig
@@ -0,0 +1,36 @@
+if ASPEED_AST2700
+
+config SYS_CPU
+ default "armv8"
+
+config SPI_KERNEL_FIT_ADDR
+ hex "SPI address of kernel FIT image"
+ default 0x100420000
+ help
+ Address in the SPI flash where the kernel FIT image is stored.
+ Used by the bootspi command to load and boot the kernel image
+ from the SPI flash on AST2700 platforms.
+
+choice
+ prompt "AST2700 board select"
+ depends on ASPEED_AST2700
+ default TARGET_EVB_AST2700
+ help
+ Select the AST2700 board model. Each board option configures
+ the board-specific Kconfig, defaults and devicetree.
+
+config TARGET_EVB_AST2700
+ bool "EVB-AST2700"
+ depends on ASPEED_AST2700
+ select ARCH_MISC_INIT
+ help
+ EVB-AST2700 is Aspeed evaluation board for AST2700A0 chip.
+ It has 512M of RAM, 32M of SPI flash, two Ethernet ports,
+ 4 Serial ports, 4 USB ports, VGA port, PCIe, SD card slot,
+ 20 pin JTAG, pinouts for 14 I2Cs, 3 SPIs and eSPI, 8 PWMs.
+
+endchoice
+
+source "board/aspeed/evb_ast2700/Kconfig"
+
+endif
diff --git a/arch/arm/mach-aspeed/ast2700/Makefile b/arch/arm/mach-aspeed/ast2700/Makefile
new file mode 100644
index 00000000000..38bd52f3d5d
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/Makefile
@@ -0,0 +1,2 @@
+obj-y += lowlevel_init.o board_common.o arm64-mmu.o platform.o
+obj-$(CONFIG_DISPLAY_CPUINFO) += cpu-info.o
diff --git a/arch/arm/mach-aspeed/ast2700/arm64-mmu.c b/arch/arm/mach-aspeed/ast2700/arm64-mmu.c
new file mode 100644
index 00000000000..a068e6ede97
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/arm64-mmu.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <dm.h>
+#include <asm/armv8/mmu.h>
+
+static struct mm_region aspeed2700_mem_map[] = {
+ {
+ .virt = 0x0UL,
+ .phys = 0x0UL,
+ .size = 0x40000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE |
+ PTE_BLOCK_PXN | PTE_BLOCK_UXN,
+ },
+ {
+ .virt = 0x40000000UL,
+ .phys = 0x40000000UL,
+ .size = 0x2C0000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+ PTE_BLOCK_NON_SHARE,
+ },
+ {
+ .virt = 0x400000000UL,
+ .phys = 0x400000000UL,
+ .size = 0x200000000UL,
+ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE,
+ },
+ {
+ /* List terminator */
+ 0,
+ }
+};
+
+struct mm_region *mem_map = aspeed2700_mem_map;
+
+u64 get_page_table_size(void)
+{
+ return 0x80000;
+}
diff --git a/arch/arm/mach-aspeed/ast2700/board_common.c b/arch/arm/mach-aspeed/ast2700/board_common.c
new file mode 100644
index 00000000000..6d2160bbca4
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/board_common.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <dm.h>
+#include <ram.h>
+#include <init.h>
+#include <timer.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+#include <linux/bitfield.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <dm/uclass.h>
+#include <asm/arch-aspeed/scu_ast2700.h>
+
+#define AHBC_GROUP(x) (0x40 * (x))
+#define AHBC_HREADY_WAIT_CNT_REG 0x34
+#define AHBC_HREADY_WAIT_CNT_MAX 0x3f
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+ int ret;
+ struct udevice *dev;
+ struct ram_info ram;
+
+ ret = uclass_get_device(UCLASS_RAM, 0, &dev);
+ if (ret) {
+ printf("cannot get DRAM driver\n");
+ debug("cannot get DRAM driver\n");
+ return ret;
+ }
+
+ ret = ram_get_info(dev, &ram);
+ if (ret) {
+ debug("cannot get DRAM information\n");
+ return ret;
+ }
+
+ gd->ram_size = ram.size;
+
+ return 0;
+}
+
+static void ahbc_init(void)
+{
+ u32 reg_val;
+ int i;
+
+ reg_val = readl(ASPEED_CPU_REVISION_ID);
+ if (FIELD_GET(SCU_CPU_REVISION_ID_HW, reg_val))
+ return;
+
+ /* CPU-die AHBC timeout counter */
+ for (i = 0; i < 4; i++)
+ writel(AHBC_HREADY_WAIT_CNT_MAX,
+ (void *)ASPEED_CPU_AHBC_BASE + AHBC_GROUP(i) + AHBC_HREADY_WAIT_CNT_REG);
+
+ /* IO-die AHBC timeout counter */
+ for (i = 0; i < 8; i++)
+ writel(AHBC_HREADY_WAIT_CNT_MAX,
+ (void *)ASPEED_IO_AHBC_BASE + AHBC_GROUP(i) + AHBC_HREADY_WAIT_CNT_REG);
+}
+
+int board_init(void)
+{
+ struct udevice *dev;
+ int i = 0;
+ int ret;
+
+ ahbc_init();
+
+ /*
+ * Loop over all MISC uclass drivers to call the comphy code
+ * and init all CP110 devices enabled in the DT
+ */
+ while (1) {
+ /* Call the comphy code via the MISC uclass driver */
+ ret = uclass_get_device(UCLASS_MISC, i++, &dev);
+
+ /* We're done, once no further CP110 device is found */
+ if (ret)
+ break;
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-aspeed/ast2700/cpu-info.c b/arch/arm/mach-aspeed/ast2700/cpu-info.c
new file mode 100644
index 00000000000..7f29c4d8c33
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/cpu-info.c
@@ -0,0 +1,114 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ * Ryan Chen <ryan_chen@aspeedtech.com>
+ */
+
+#include <command.h>
+#include <asm/io.h>
+#include <asm/arch/platform.h>
+#include <asm/arch/scu_ast2700.h>
+
+/* SoC mapping Table */
+#define SOC_ID(str, rev) { .name = str, .rev_id = rev, }
+
+struct soc_id {
+ const char *name;
+ u64 rev_id;
+};
+
+static struct soc_id soc_map_table[] = {
+ SOC_ID("AST2750-A0", 0x0600000306000003),
+ SOC_ID("AST2700-A0", 0x0600010306000103),
+ SOC_ID("AST2720-A0", 0x0600020306000203),
+ SOC_ID("AST2750-A1", 0x0601000306010003),
+ SOC_ID("AST2700-A1", 0x0601010306010103),
+ SOC_ID("AST2720-A1", 0x0601020306010203),
+ SOC_ID("AST2750-A2", 0x0602000306020003),
+ SOC_ID("AST2700-A2", 0x0602010306020103),
+ SOC_ID("AST2720-A2", 0x0602020306020203),
+};
+
+void ast2700_print_soc_id(void)
+{
+ int i;
+ u64 rev_id;
+
+ rev_id = readl(ASPEED_CPU_REVISION_ID);
+ rev_id = ((u64)readl(ASPEED_IO_REVISION_ID) << 32) | rev_id;
+
+ for (i = 0; i < ARRAY_SIZE(soc_map_table); i++) {
+ if (rev_id == soc_map_table[i].rev_id)
+ break;
+ }
+ if (i == ARRAY_SIZE(soc_map_table))
+ printf("Unknown-SOC: %llx\n", rev_id);
+ else
+ printf("SOC: %4s\n", soc_map_table[i].name);
+}
+
+#define SYS_DRAM_ECCRST BIT(3)
+#define SYS_ABRRST BIT(2)
+#define SYS_EXTRST BIT(1)
+#define SYS_SRST BIT(0)
+
+#define WDT_RST_BIT_MASK(s) (GENMASK(3, 0) << (s))
+#define BIT_WDT_FULL(s) (BIT(0) << (s))
+#define BIT_WDT_ARM(s) (BIT(1) << (s))
+#define BIT_WDT_SOC(s) (BIT(2) << (s))
+#define BIT_WDT_SW(s) (BIT(3) << (s))
+
+void ast2700_print_wdtrst_info(void)
+{
+ u32 wdt_rst = readl(ASPEED_IO_RESET_LOG4);
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (wdt_rst & WDT_RST_BIT_MASK(i * 4)) {
+ printf("RST: WDT%d ", i);
+ if (wdt_rst & BIT_WDT_SOC(i * 4)) {
+ printf("SOC ");
+ writel(BIT_WDT_SOC(i * 4), ASPEED_IO_RESET_LOG4);
+ }
+ if (wdt_rst & BIT_WDT_FULL(i * 4)) {
+ printf("FULL ");
+ writel(BIT_WDT_FULL(i * 4), ASPEED_IO_RESET_LOG4);
+ }
+ if (wdt_rst & BIT_WDT_ARM(i * 4)) {
+ printf("ARM ");
+ writel(BIT_WDT_ARM(i * 4), ASPEED_IO_RESET_LOG4);
+ }
+ if (wdt_rst & BIT_WDT_SW(i * 4)) {
+ printf("SW ");
+ writel(BIT_WDT_SW(i * 4), ASPEED_IO_RESET_LOG4);
+ }
+ printf("\n");
+ }
+ }
+}
+
+#define SYS_EXTRST BIT(1)
+#define SYS_SRST BIT(0)
+
+void ast2700_print_sysrst_info(void)
+{
+ u32 sys_rst = readl(ASPEED_CPU_RESET_LOG1);
+
+ if (sys_rst & SYS_SRST) {
+ printf("RST: Power On\n");
+ writel(SYS_SRST, ASPEED_CPU_RESET_LOG1);
+ } else if (sys_rst & SYS_EXTRST) {
+ printf("RST: EXTRST\n");
+ writel(SYS_EXTRST, ASPEED_CPU_RESET_LOG1);
+ } else {
+ ast2700_print_wdtrst_info();
+ }
+}
+
+int print_cpuinfo(void)
+{
+ ast2700_print_soc_id();
+ ast2700_print_sysrst_info();
+
+ return 0;
+}
diff --git a/arch/arm/mach-aspeed/ast2700/lowlevel_init.S b/arch/arm/mach-aspeed/ast2700/lowlevel_init.S
new file mode 100644
index 00000000000..9b78fed0b26
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/lowlevel_init.S
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) ASPEED Technology Inc.
+ */
+#include <config.h>
+#include <linux/linkage.h>
+
+/*
+ * SMP mailbox
+ * +-----------------------+ 0x40
+ * | |
+ * | mailbox insn. for |
+ * | cpuN GO sign polling |
+ * | |
+ * +-----------------------+ 0x20
+ * | cpu3 entrypoint |
+ * +-----------------------+ 0x18
+ * | cpu2 entrypoint |
+ * +-----------------------+ 0x10
+ * | cpu1 entrypoint |
+ * +-----------------------+ 0x8
+ * | reserved |
+ * +-----------------------+ 0x4
+ * | mailbox ready |
+ * +-----------------------+ SCU_CPU + 0x780
+ */
+
+#define SCU_CPU_BASE 0x12c02000
+#define SCU_CPU_SMP_READY (SCU_CPU_BASE + 0x780)
+#define SCU_CPU_SMP_EP1 (SCU_CPU_BASE + 0x788)
+#define SCU_CPU_SMP_EP2 (SCU_CPU_BASE + 0x790)
+#define SCU_CPU_SMP_EP3 (SCU_CPU_BASE + 0x798)
+#define SCU_CPU_SMP_POLLINSN (SCU_CPU_BASE + 0x7a0)
+
+ENTRY(lowlevel_init)
+ /* backup LR */
+ mov x29, lr
+
+#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
+ /* reset SMP mailbox ASAP */
+ ldr x0, =SCU_CPU_SMP_READY
+ str wzr, [x0]
+
+ /*
+ * get cpu core id
+ *
+ * ast2700 has 1-cluster, 4-cores CPU topology.
+ * Affinity level 0 in MPIDR is sufficient.
+ */
+ mrs x4, mpidr_el1
+ ands x4, x4, #0xff
+
+ /* cpu0 is the primary core to setup SMP mailbox */
+ beq do_primary_core_setup
+
+ /* hold cpuN until mailbox is ready */
+ ldr x0, =SCU_CPU_SMP_READY
+ movz w1, #0xcafe
+ movk w1, #0xbabe, lsl #16
+
+poll_mailbox_ready:
+ wfe
+ ldr w2, [x0]
+ cmp w1, w2
+ bne poll_mailbox_ready
+
+ /*
+ * parameters for relocated SMP go polling insn.
+ * x4 = cpu id
+ * x5 = SCU_CPU_SMP_EPx
+ */
+ add x5, x0, x4, lsl #3
+
+ /* jump to the polling loop in SMP mailbox, no return */
+ ldr x0, =SCU_CPU_SMP_POLLINSN
+ br x0
+
+do_primary_core_setup:
+ /* relocate mailbox insn. for cpuN to poll for SMP go signal */
+ adr x0, smp_mbox_insn
+ adr x1, smp_mbox_insn_end
+ ldr x2, =SCU_CPU_SMP_POLLINSN
+
+relocate_smp_mbox_insn:
+ ldr w3, [x0], #0x4
+ str w3, [x2], #0x4
+ cmp x0, x1
+ bne relocate_smp_mbox_insn
+
+ /* reset cpuN entrypoints */
+ ldr x0, =SCU_CPU_SMP_EP1
+ str xzr, [x0], #8
+ str xzr, [x0], #8
+ str xzr, [x0]
+
+ /* notify cpuN that SMP mailbox is ready */
+ movz w0, #0xcafe
+ movk w0, #0xbabe, lsl #16
+ ldr x1, =SCU_CPU_SMP_READY
+ str w0, [x1]
+
+ sev
+#endif /* !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) */
+
+ /* back to arch calling code */
+ mov lr, x29
+ ret
+ENDPROC(lowlevel_init)
+
+/*
+ * insn. inside mailbox to poll SMP go signal.
+ *
+ * Note that this code will be relocated, any absolute
+ * addressing should NOT be used.
+ */
+smp_mbox_insn:
+ /*
+ * x4 = cpu id
+ * x5 = SCU_CPU_SMP_EPx
+ */
+poll_smp_mbox_go:
+ wfe
+ ldr x0, [x5]
+ cmp x0, xzr
+ beq poll_smp_mbox_go
+
+ /* jump to secondary core entrypoint */
+ br x0
+
+smp_mbox_insn_end:
+ /* should never reach */
+ b .
diff --git a/arch/arm/mach-aspeed/ast2700/platform.c b/arch/arm/mach-aspeed/ast2700/platform.c
new file mode 100644
index 00000000000..9cca85766f6
--- /dev/null
+++ b/arch/arm/mach-aspeed/ast2700/platform.c
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <dm.h>
+#include <asm/arch-aspeed/scu_ast2700.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <env.h>
+#include <env_internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum env_location env_get_location(enum env_operation op, int prio)
+{
+ enum env_location env_loc = ENVL_UNKNOWN;
+ u32 strap = readl(ASPEED_IO_HW_STRAP1);
+
+ if (prio)
+ return env_loc;
+
+ if (IS_ENABLED(CONFIG_ENV_IS_NOWHERE)) {
+ env_loc = ENVL_NOWHERE;
+ } else if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH) &&
+ !(strap & SCU_IO_HWSTRAP_EMMC)) {
+ env_loc = ENVL_SPI_FLASH;
+ } else if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC) &&
+ (strap & SCU_IO_HWSTRAP_EMMC) &&
+ !(strap & SCU_IO_HWSTRAP_UFS)) {
+ env_loc = ENVL_MMC;
+ } else if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) {
+ /*
+ * This tree does not carry an ENV_IS_IN_UFS backend yet.
+ * Fall back to SPI flash when that backend exists.
+ */
+ env_loc = ENVL_SPI_FLASH;
+ } else {
+ env_loc = ENVL_NOWHERE;
+ }
+
+ return env_loc;
+}
+
+int arch_misc_init(void)
+{
+ if (IS_ENABLED(CONFIG_ARCH_MISC_INIT)) {
+ if ((readl(ASPEED_IO_HW_STRAP1) & SCU_IO_HWSTRAP_EMMC)) {
+ if ((readl(ASPEED_IO_HW_STRAP1) & SCU_IO_HWSTRAP_UFS))
+ env_set("boot_device", "ufs");
+ else
+ env_set("boot_device", "mmc");
+ } else {
+ env_set("boot_device", "spi");
+ }
+
+ if ((readl(ASPEED_IO_HW_STRAP1) & SCU_IO_HWSTRAP_SECBOOT))
+ env_set("verify", "yes");
+ else
+ env_set("verify", "no");
+ }
+
+ return 0;
+}
diff --git a/board/aspeed/evb_ast2700/Kconfig b/board/aspeed/evb_ast2700/Kconfig
new file mode 100644
index 00000000000..ede9eb7fb85
--- /dev/null
+++ b/board/aspeed/evb_ast2700/Kconfig
@@ -0,0 +1,13 @@
+if TARGET_EVB_AST2700
+
+config SYS_BOARD
+ default "evb_ast2700"
+
+config SYS_VENDOR
+ default "aspeed"
+
+config SYS_CONFIG_NAME
+ string "board configuration name"
+ default "evb_ast2700"
+
+endif
diff --git a/board/aspeed/evb_ast2700/Makefile b/board/aspeed/evb_ast2700/Makefile
new file mode 100644
index 00000000000..0c29700f5a9
--- /dev/null
+++ b/board/aspeed/evb_ast2700/Makefile
@@ -0,0 +1 @@
+obj-y += evb_ast2700.o
diff --git a/board/aspeed/evb_ast2700/evb_ast2700.c b/board/aspeed/evb_ast2700/evb_ast2700.c
new file mode 100644
index 00000000000..b34aa6e1682
--- /dev/null
+++ b/board/aspeed/evb_ast2700/evb_ast2700.c
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
diff --git a/configs/evb-ast2700_defconfig b/configs/evb-ast2700_defconfig
new file mode 100644
index 00000000000..d0733e14c67
--- /dev/null
+++ b/configs/evb-ast2700_defconfig
@@ -0,0 +1,160 @@
+CONFIG_ARM=y
+CONFIG_SKIP_LOWLEVEL_INIT=y
+CONFIG_POSITION_INDEPENDENT=y
+# CONFIG_INIT_SP_RELATIVE is not set
+CONFIG_ARM_SMCCC=y
+CONFIG_ARCH_ASPEED=y
+CONFIG_TEXT_BASE=0x400000000
+CONFIG_SYS_MALLOC_LEN=0x2000000
+CONFIG_ASPEED_AST2700=y
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
+CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x403000000
+CONFIG_ENV_SIZE=0x20000
+CONFIG_ENV_OFFSET=0x400000
+CONFIG_ENV_SECT_SIZE=0x20000
+CONFIG_DM_GPIO=y
+CONFIG_DEFAULT_DEVICE_TREE="ast2700-evb"
+CONFIG_DM_RESET=y
+CONFIG_SYS_LOAD_ADDR=0x403000000
+CONFIG_DEBUG_UART_BASE=0x14c33b00
+CONFIG_DEBUG_UART_CLOCK=1846154
+# CONFIG_PSCI_RESET is not set
+CONFIG_ARMV8_CRYPTO=y
+CONFIG_ENV_ADDR=0x400000
+CONFIG_SYS_PCI_64BIT=y
+CONFIG_PCI=y
+CONFIG_DEBUG_UART=y
+CONFIG_SYS_MEMTEST_START=0x403000000
+CONFIG_SYS_MEMTEST_END=0x403001000
+# CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+# CONFIG_BOOTMETH_EFILOADER is not set
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyS12,115200n8 root=/dev/ram rw earlycon"
+CONFIG_USE_BOOTCOMMAND=y
+CONFIG_BOOTCOMMAND="echo Boot from ${boot_device}; if test ${boot_device} = mmc; then run bootmmc; fi; if test ${boot_device} = spi; then run bootspi; fi; if test ${boot_device} = ufs; then run bootufs; fi;"
+CONFIG_SYS_CBSIZE=256
+CONFIG_SYS_PBSIZE=276
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_HUSH_PARSER=y
+# CONFIG_AUTO_COMPLETE is not set
+# CONFIG_CMD_CONSOLE is not set
+# CONFIG_CMD_BOOTFLOW is not set
+CONFIG_CMD_BOOTZ=y
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_BOOTEFI is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_IMI is not set
+# CONFIG_CMD_XIMG is not set
+CONFIG_CMD_EEPROM=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_SYS_ALT_MEMTEST=y
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNLZ4 is not set
+CONFIG_CMD_DFU=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_I2C=y
+CONFIG_CMD_MISC=y
+CONFIG_CMD_MMC=y
+CONFIG_CMD_PCI=y
+CONFIG_CMD_UFS=y
+CONFIG_CMD_NCSI=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_CACHE=y
+# CONFIG_CMD_EFICONFIG is not set
+CONFIG_CMD_TPM=y
+CONFIG_CMD_EXT4=y
+CONFIG_CMD_EXT4_WRITE=y
+# CONFIG_CMD_CYCLIC is not set
+CONFIG_DOS_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_ENV_OVERWRITE=y
+CONFIG_ENV_IS_IN_MMC=y
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_ENV_MMC_USE_DT=y
+CONFIG_USE_HOSTNAME=y
+CONFIG_HOSTNAME="ast2700-evb"
+CONFIG_BOOTP_SEND_HOSTNAME=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SYSCON=y
+CONFIG_CLK=y
+CONFIG_DM_HASH=y
+CONFIG_DFU_RAM=y
+CONFIG_GPIO_HOG=y
+CONFIG_ASPEED_G7_GPIO=y
+CONFIG_DM_I2C=y
+CONFIG_SYS_I2C_AST2600=y
+# CONFIG_INPUT is not set
+CONFIG_DM_MAILBOX=y
+CONFIG_I2C_EEPROM=y
+CONFIG_SUPPORT_EMMC_BOOT=y
+CONFIG_MMC_IO_VOLTAGE=y
+CONFIG_MMC_UHS_SUPPORT=y
+CONFIG_MMC_HS200_SUPPORT=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_SDMA=y
+CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_MTD=y
+CONFIG_DM_SPI_FLASH=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_SST=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_SPI_FLASH_XTX=y
+CONFIG_DM_MDIO=y
+CONFIG_FTGMAC100=y
+CONFIG_ASPEED_MDIO=y
+CONFIG_PHY_BROADCOM=y
+CONFIG_PHY_AIROHA=y
+CONFIG_PHY_REALTEK=y
+CONFIG_PHY_TI_DP83867=y
+CONFIG_PHY_NCSI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_CONFIG_HOST_BRIDGE=y
+CONFIG_PHY=y
+CONFIG_PINCTRL=y
+CONFIG_DM_REGULATOR=y
+CONFIG_DM_REGULATOR_FIXED=y
+CONFIG_DM_REGULATOR_GPIO=y
+CONFIG_RAM=y
+CONFIG_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEBUG_UART_SHIFT=2
+CONFIG_SYS_NS16550=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SPI_DIRMAP=y
+CONFIG_SPI_ASPEED_SMC=y
+CONFIG_SYSRESET=y
+# CONFIG_TPM_V1 is not set
+CONFIG_TPM2_TIS_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB_GADGET=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_MANUFACTURER="ASPEED"
+CONFIG_USB_GADGET_VENDOR_NUM=0x2245
+CONFIG_USB_GADGET_PRODUCT_NUM=0x2700
+CONFIG_USB_GADGET_OS_DESCRIPTORS=y
+CONFIG_USB_GADGET_DOWNLOAD=y
+CONFIG_UFS=y
+# CONFIG_WATCHDOG_AUTOSTART is not set
+CONFIG_WDT=y
+# CONFIG_WDT_ASPEED is not set
+CONFIG_ECDSA=y
+CONFIG_ECDSA_VERIFY=y
+CONFIG_TPM=y
+CONFIG_LZ4=y
+CONFIG_LZMA=y
+# CONFIG_TOOLS_MKEFICAPSULE is not set
diff --git a/drivers/clk/aspeed/Makefile b/drivers/clk/aspeed/Makefile
index 84776e5265e..285180b67cf 100644
--- a/drivers/clk/aspeed/Makefile
+++ b/drivers/clk/aspeed/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_ASPEED_AST2500) += clk_ast2500.o
obj-$(CONFIG_ASPEED_AST2600) += clk_ast2600.o
+obj-$(CONFIG_ASPEED_AST2700) += clk_ast2700.o
diff --git a/drivers/clk/aspeed/clk_ast2700.c b/drivers/clk/aspeed/clk_ast2700.c
new file mode 100644
index 00000000000..ca76abef48f
--- /dev/null
+++ b/drivers/clk/aspeed/clk_ast2700.c
@@ -0,0 +1,952 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <asm/arch/scu_ast2700.h>
+#include <clk-uclass.h>
+#include <dm.h>
+#include <dm/lists.h>
+#include <syscon.h>
+#include <linux/bitfield.h>
+
+#include <dt-bindings/clock/aspeed,ast2700-scu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * RGMII clock source tree
+ * HPLL -->|\
+ * | |---->| divider |---->RGMII 125M for MAC#0 & MAC#1
+ * APLL -->|/
+ */
+#define RGMII_DEFAULT_CLK_SRC SCU1_CLK_HPLL
+
+struct mac_delay_config {
+ u32 tx_delay_1000;
+ u32 rx_delay_1000;
+ u32 tx_delay_100;
+ u32 rx_delay_100;
+ u32 tx_delay_10;
+ u32 rx_delay_10;
+};
+
+typedef int (*ast2700_clk_init_fn)(struct udevice *dev);
+
+struct ast2700_clk_priv {
+ void __iomem *reg;
+ ast2700_clk_init_fn init;
+};
+
+static u32 ast2700_soc1_get_pll_rate(struct ast2700_scu1 *scu, int pll_idx)
+{
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+
+ switch (pll_idx) {
+ case SCU1_CLK_HPLL:
+ pll_reg.w = readl(&scu->hpll);
+ break;
+ case SCU1_CLK_APLL:
+ pll_reg.w = readl(&scu->apll);
+ break;
+ case SCU1_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ }
+
+ if (!pll_reg.b.bypass) {
+ mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1);
+ div = (pll_reg.b.p + 1);
+ }
+
+ return ((CLKIN_25M * mul) / div);
+}
+
+#define SCU_CLKSEL2_HCLK_DIV_MASK GENMASK(22, 20)
+#define SCU_CLKSEL2_HCLK_DIV_SHIFT 20
+
+static u32 ast2700_soc1_get_hclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 clk_sel2 = readl(&scu->clk_sel2);
+ u32 hclk_div = (clk_sel2 & SCU_CLKSEL2_HCLK_DIV_MASK) >>
+ SCU_CLKSEL2_HCLK_DIV_SHIFT;
+
+ if (!hclk_div)
+ hclk_div = 2;
+ else
+ hclk_div++;
+
+ return (rate / hclk_div);
+}
+
+#define SCU1_CLKSEL1_PCLK_DIV_MASK GENMASK(20, 18)
+#define SCU1_CLKSEL1_PCLK_DIV_SHIFT 18
+
+static u32 ast2700_soc1_get_pclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+
+ u32 clk_sel1 = readl(&scu->clk_sel1);
+ u32 pclk_div = (clk_sel1 & SCU1_CLKSEL1_PCLK_DIV_MASK) >>
+ SCU1_CLKSEL1_PCLK_DIV_SHIFT;
+
+ return (rate / ((pclk_div + 1) * 2));
+}
+
+#define SCU_UART_CLKGEN_N_MASK GENMASK(17, 8)
+#define SCU_UART_CLKGEN_N_SHIFT 8
+#define SCU_UART_CLKGEN_R_MASK GENMASK(7, 0)
+#define SCU_UART_CLKGEN_R_SHIFT 0
+
+static u32 ast2700_soc1_get_uart_uxclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 uxclk_sel = readl(&scu->clk_sel2) & GENMASK(1, 0);
+ u32 uxclk_ctrl = readl(&scu->uxclk_ctrl);
+ u32 rate;
+
+ switch (uxclk_sel) {
+ case 0:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ break;
+ }
+
+ u32 n = (uxclk_ctrl & SCU_UART_CLKGEN_N_MASK) >>
+ SCU_UART_CLKGEN_N_SHIFT;
+ u32 r = (uxclk_ctrl & SCU_UART_CLKGEN_R_MASK) >>
+ SCU_UART_CLKGEN_R_SHIFT;
+
+ return ((rate * r) / (n * 2));
+}
+
+#define SCU_HUART_CLKGEN_N_MASK GENMASK(17, 8)
+#define SCU_HUART_CLKGEN_N_SHIFT 8
+#define SCU_HUART_CLKGEN_R_MASK GENMASK(7, 0)
+#define SCU_HUART_CLKGEN_R_SHIFT 0
+
+static u32 ast2700_soc1_get_uart_huxclk_rate(struct ast2700_scu1 *scu)
+{
+ u32 huxclk_sel = (readl(&scu->clk_sel2) & GENMASK(4, 3)) >> 3;
+ u32 huxclk_ctrl = readl(&scu->huxclk_ctrl);
+ u32 n = (huxclk_ctrl & SCU_HUART_CLKGEN_N_MASK) >>
+ SCU_HUART_CLKGEN_N_SHIFT;
+ u32 r = (huxclk_ctrl & SCU_HUART_CLKGEN_R_MASK) >>
+ SCU_HUART_CLKGEN_R_SHIFT;
+ u32 rate;
+
+ switch (huxclk_sel) {
+ case 0:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 4;
+ break;
+ case 1:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL) / 2;
+ break;
+ case 2:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ break;
+ case 3:
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ break;
+ }
+
+ return ((rate * r) / (n * 2));
+}
+
+#define SCU_CLKSRC1_SDIO_DIV_MASK GENMASK(16, 14)
+#define SCU_CLKSRC1_SDIO_DIV_SHIFT 14
+#define SCU_CLKSRC1_SDIO_SEL BIT(13)
+const int ast2700_sd_div_tbl[] = {
+ 2, 2, 3, 4, 5, 6, 7, 8
+};
+
+static u32 ast2700_soc1_get_sdio_clk_rate(struct ast2700_scu1 *scu)
+{
+ u32 rate = 0;
+ u32 clk_sel1 = readl(&scu->clk_sel1);
+ u32 div = (clk_sel1 & SCU_CLKSRC1_SDIO_DIV_MASK) >>
+ SCU_CLKSRC1_SDIO_DIV_SHIFT;
+
+ if (clk_sel1 & SCU_CLKSRC1_SDIO_SEL)
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_APLL);
+ else
+ rate = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+
+ if (!div)
+ div = 1;
+
+ div++;
+
+ return (rate / div);
+}
+
+static void ast2700_init_sdclk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ int i;
+
+ for (i = 0; i < 8; i++) {
+ if (src_clk / ast2700_sd_div_tbl[i] <= 125000000)
+ break;
+ }
+
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~(SCU_CLKSRC1_SDIO_DIV_MASK | SCU_CLKSRC1_SDIO_SEL);
+ reg_280 |= i << SCU_CLKSRC1_SDIO_DIV_SHIFT;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static u32
+ast2700_soc1_get_uart_clk_rate(struct ast2700_scu1 *scu, int uart_idx)
+{
+ u32 rate = 0;
+
+ if (readl(&scu->clk_sel1) & BIT(uart_idx))
+ rate = ast2700_soc1_get_uart_huxclk_rate(scu);
+ else
+ rate = ast2700_soc1_get_uart_uxclk_rate(scu);
+
+ return rate;
+}
+
+static ulong ast2700_soc1_clk_get_rate(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case SCU1_CLK_HPLL:
+ case SCU1_CLK_APLL:
+ case SCU1_CLK_DPLL:
+ rate = ast2700_soc1_get_pll_rate(scu, clk->id);
+ break;
+ case SCU1_CLK_AHB:
+ rate = ast2700_soc1_get_hclk_rate(scu);
+ break;
+ case SCU1_CLK_APB:
+ rate = ast2700_soc1_get_pclk_rate(scu);
+ break;
+ case SCU1_CLK_GATE_UART0CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 0);
+ break;
+ case SCU1_CLK_GATE_UART1CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 1);
+ break;
+ case SCU1_CLK_GATE_UART2CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 2);
+ break;
+ case SCU1_CLK_GATE_UART3CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 3);
+ break;
+ case SCU1_CLK_GATE_UART5CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 5);
+ break;
+ case SCU1_CLK_GATE_UART6CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 6);
+ break;
+ case SCU1_CLK_GATE_UART7CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 7);
+ break;
+ case SCU1_CLK_GATE_UART8CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 8);
+ break;
+ case SCU1_CLK_GATE_UART9CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 9);
+ break;
+ case SCU1_CLK_GATE_UART10CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 10);
+ break;
+ case SCU1_CLK_GATE_UART11CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 11);
+ break;
+ case SCU1_CLK_GATE_UART12CLK:
+ rate = ast2700_soc1_get_uart_clk_rate(scu, 12);
+ break;
+ case SCU1_CLK_GATE_SDCLK:
+ rate = ast2700_soc1_get_sdio_clk_rate(scu);
+ break;
+ case SCU1_CLK_UXCLK:
+ rate = ast2700_soc1_get_uart_uxclk_rate(scu);
+ break;
+ case SCU1_CLK_HUXCLK:
+ rate = ast2700_soc1_get_uart_huxclk_rate(scu);
+ break;
+ default:
+ debug("%s: unknown clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static int ast2700_soc1_clk_enable(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+ u32 clkgate_bit;
+
+ if (clk->id >= 32)
+ clkgate_bit = BIT(clk->id - 32);
+ else
+ clkgate_bit = BIT(clk->id);
+
+ writel(clkgate_bit, &scu->clkgate_clr1);
+
+ return 0;
+}
+
+static const struct clk_ops ast2700_soc1_clk_ops = {
+ .get_rate = ast2700_soc1_clk_get_rate,
+ .enable = ast2700_soc1_clk_enable,
+};
+
+#define SCU_HW_REVISION_ID GENMASK(23, 16)
+#define SCU_CPUCLK_MASK GENMASK(4, 2)
+#define SCU_CPUCLK_SHIFT 2
+static u32 ast2700_soc0_get_hpll_rate(struct ast2700_scu0 *scu)
+{
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+ u32 rate;
+
+ pll_reg.w = readl(&scu->hpll);
+
+ if ((chip_id1 & SCU_HW_REVISION_ID) && (hwstrap1 & BIT(3))) {
+ switch ((hwstrap1 & GENMASK(4, 2)) >> 2) {
+ case 2:
+ rate = 1800000000;
+ break;
+ case 3:
+ rate = 1700000000;
+ break;
+ case 6:
+ rate = 1200000000;
+ break;
+ case 7:
+ rate = 800000000;
+ break;
+ default:
+ rate = 1600000000;
+ }
+ } else if (hwstrap1 & GENMASK(3, 2)) {
+ switch ((hwstrap1 & GENMASK(3, 2)) >> 2) {
+ case 1U:
+ rate = 1900000000;
+ break;
+ case 2U:
+ rate = 1800000000;
+ break;
+ case 3U:
+ rate = 1700000000;
+ break;
+ default:
+ rate = 1600000000;
+ break;
+ }
+ } else {
+ if (pll_reg.b.bypass == 0U) {
+ /* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+ div = (pll_reg.b.p + 1);
+ }
+ rate = ((CLKIN_25M * mul) / div);
+ }
+
+ return rate;
+}
+
+static u32 ast2700_soc0_get_pll_rate(struct ast2700_scu0 *scu, int pll_idx)
+{
+ union ast2700_pll_reg pll_reg;
+ u32 mul = 1, div = 1;
+ u32 rate;
+
+ switch (pll_idx) {
+ case SCU0_CLK_DPLL:
+ pll_reg.w = readl(&scu->dpll);
+ break;
+ case SCU0_CLK_MPLL:
+ pll_reg.w = readl(&scu->mpll);
+ break;
+ default:
+ pr_err("%s: invalid PSP clock source (%d)\n", __func__, pll_idx);
+ return 0;
+ }
+
+ if (pll_reg.b.bypass == 0U) {
+ if (pll_idx == SCU0_CLK_MPLL) {
+ /* F = 25Mhz * [M / (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m) / ((pll_reg.b.n + 1));
+ div = (pll_reg.b.p + 1);
+ } else {
+ /* F = 25Mhz * [(M + 2) / 2 * (n + 1)] / (p + 1) */
+ mul = (pll_reg.b.m + 1) / ((pll_reg.b.n + 1) * 2);
+ div = (pll_reg.b.p + 1);
+ }
+ }
+
+ rate = ((CLKIN_25M * mul) / div);
+
+ return rate;
+}
+
+/*
+ * AST2700A1
+ * SCU010[4:2]:
+ * 000: CPUCLK=MPLL=1.6GHz (MPLL default setting with SCU310, SCU314)
+ * 001: CPUCLK=HPLL=2.0GHz (HPLL default setting with SCU300, SCU304)
+ * 010: CPUCLK=HPLL=1.8GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 011: CPUCLK=HPLL=1.7GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 100: CPUCLK=MPLL/2=800MHz (MPLL default setting with SCU310, SCU314)
+ * 101: CPUCLK=HPLL/2=1.0GHz (HPLL default setting with SCU300, SCU304)
+ * 110: CPUCLK=HPLL=1.2GHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ * 111: CPUCLK=HPLL=800MHz (HPLL frequency is constance and is not controlled by SCU300, SCU304)
+ */
+
+static u32 ast2700_soc0_get_pspclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ u32 rate;
+ int cpuclk_set;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ cpuclk_set = (hwstrap1 & SCU_CPUCLK_MASK) >> SCU_CPUCLK_SHIFT;
+ switch (cpuclk_set) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ case 6:
+ case 7:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 4:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 2;
+ break;
+ case 5:
+ rate = ast2700_soc0_get_hpll_rate(scu) / 2;
+ break;
+ default:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ }
+ } else {
+ if (hwstrap1 & BIT(4))
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ else
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ }
+ return rate;
+}
+
+static u32 ast2700_soc0_get_axi0clk_rate(struct ast2700_scu0 *scu)
+{
+ return ast2700_soc0_get_pspclk_rate(scu) / 2;
+}
+
+#define SCU_AHB_DIV_MASK GENMASK(6, 5)
+#define SCU_AHB_DIV_SHIFT 5
+static u32 hclk_ast2700a1_div_table[] = {
+ 6, 5, 4, 7,
+};
+
+static u32 ast2700_soc0_get_hclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 hwstrap1 = readl(&scu->hwstrap1);
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 src_clk;
+ int div;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ if (hwstrap1 & BIT(7))
+ src_clk = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ else
+ src_clk = ast2700_soc0_get_hpll_rate(scu);
+
+ div = (hwstrap1 & SCU_AHB_DIV_MASK) >> SCU_AHB_DIV_SHIFT;
+ div = hclk_ast2700a1_div_table[div];
+ } else {
+ if (hwstrap1 & BIT(7))
+ src_clk = ast2700_soc0_get_hpll_rate(scu);
+ else
+ src_clk = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+
+ div = (hwstrap1 & SCU_AHB_DIV_MASK) >> SCU_AHB_DIV_SHIFT;
+
+ if (!div)
+ div = 4;
+ else
+ div = (div + 1) * 2;
+ }
+ return (src_clk / div);
+}
+
+static u32 ast2700_soc0_get_axi1clk_rate(struct ast2700_scu0 *scu)
+{
+ if (readl(&scu->chip_id1) & SCU_HW_REVISION_ID)
+ return ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+ else
+ return ast2700_soc0_get_hclk_rate(scu);
+}
+
+#define SCU0_CLKSEL1_PCLK_DIV_MASK GENMASK(25, 23)
+#define SCU0_CLKSEL1_PCLK_DIV_SHIFT 23
+
+static u32 ast2700_soc0_get_pclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 rate = ast2700_soc0_get_axi0clk_rate(scu);
+ u32 clksel1 = readl(&scu->clk_sel1);
+ int div;
+
+ div = (clksel1 & SCU0_CLKSEL1_PCLK_DIV_MASK) >>
+ SCU0_CLKSEL1_PCLK_DIV_SHIFT;
+
+ return (rate / ((div + 1) * 2));
+}
+
+#define SCU_CLKSEL1_MPHYCLK_SEL_MASK GENMASK(19, 18)
+#define SCU_CLKSEL1_MPHYCLK_SEL_SHIFT 18
+#define SCU_CLKSEL1_MPHYCLK_DIV_MASK GENMASK(7, 0)
+static u32 ast2700_soc0_get_mphyclk_rate(struct ast2700_scu0 *scu)
+{
+ int div = readl(&scu->mphyclk_para) & SCU_CLKSEL1_MPHYCLK_DIV_MASK;
+ u32 chip_id1 = readl(&scu->chip_id1);
+ u32 clk_sel2;
+ int clk_sel;
+ u32 rate = 0;
+
+ if (chip_id1 & SCU_HW_REVISION_ID) {
+ clk_sel2 = readl(&scu->clk_sel2);
+ clk_sel = (clk_sel2 & SCU_CLKSEL1_MPHYCLK_SEL_MASK)
+ >> SCU_CLKSEL1_MPHYCLK_SEL_SHIFT;
+ switch (clk_sel) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 2:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_DPLL);
+ break;
+ case 3:
+ rate = 26000000;
+ break;
+ }
+ } else {
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ }
+
+ return (rate / (div + 1));
+}
+
+static void ast2700_mphy_clk_init(struct ast2700_scu0 *scu)
+{
+ u32 clksrc1, rate = 0;
+ int i;
+
+ /* set mphy clk */
+ if (readl(&scu->chip_id1) & SCU_HW_REVISION_ID) {
+ clksrc1 = (readl(&scu->clk_sel2) & SCU_CLKSEL1_MPHYCLK_SEL_MASK)
+ >> SCU_CLKSEL1_MPHYCLK_SEL_SHIFT;
+ switch (clksrc1) {
+ case 0:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL);
+ break;
+ case 1:
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ break;
+ case 2:
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_DPLL);
+ break;
+ case 3:
+ rate = 26000000;
+ break;
+ }
+ } else {
+ rate = ast2700_soc0_get_hpll_rate(scu);
+ }
+
+ for (i = 1; i < 256; i++) {
+ if ((rate / i) <= 26000000)
+ break;
+ }
+
+ /* register defined the value plus 1 is divider*/
+ i--;
+ writel(i, &scu->mphyclk_para);
+}
+
+#define SCU_CLKSRC1_EMMC_DIV_MASK GENMASK(14, 12)
+#define SCU_CLKSRC1_EMMC_DIV_SHIFT 12
+#define SCU_CLKSRC1_EMMC_SEL BIT(11)
+static u32 ast2700_soc0_get_emmcclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 clksel1 = readl(&scu->clk_sel1);
+ u32 rate;
+ int div;
+
+ div = (clksel1 & SCU_CLKSRC1_EMMC_DIV_MASK) >> SCU_CLKSRC1_EMMC_DIV_SHIFT;
+
+ if (clksel1 & SCU_CLKSRC1_EMMC_SEL)
+ rate = ast2700_soc0_get_hpll_rate(scu) / 4;
+ else
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+
+ return (rate / ((div + 1) * 2));
+}
+
+static void ast2700_emmc_init(struct ast2700_scu0 *scu)
+{
+ u32 clksrc1, rate, div;
+ int i;
+
+ /* set clk/cmd driving */
+ writel(2, &scu->gpio18d0_ioctrl); /* clk driving */
+ writel(1, &scu->gpio18d1_ioctrl); /* cmd driving */
+ writel(1, &scu->gpio18d2_ioctrl); /* data0 driving */
+ writel(1, &scu->gpio18d3_ioctrl); /* data1 driving */
+ writel(1, &scu->gpio18d4_ioctrl); /* data2 driving */
+ writel(1, &scu->gpio18d5_ioctrl); /* data2 driving */
+
+ /* emmc clk: set clk src mpll/4:400Mhz */
+ clksrc1 = readl(&scu->clk_sel1);
+ rate = ast2700_soc0_get_pll_rate(scu, SCU0_CLK_MPLL) / 4;
+ for (i = 0; i < 8; i++) {
+ div = (i + 1) * 2;
+ if ((rate / div) <= 200000000)
+ break;
+ }
+
+ clksrc1 &= ~(SCU_CLKSRC1_EMMC_DIV_MASK | SCU_CLKSRC1_EMMC_SEL);
+ clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT);
+ writel(clksrc1, &scu->clk_sel1);
+}
+
+static void ast2700_vga_clk_init(struct ast2700_scu0 *scu)
+{
+ if ((readl(&scu->chip_id1) & SCU_HW_REVISION_ID) == 0)
+ return;
+
+ // Use d0clk/d1clk which generated from hpll for vga0/1 after A0
+ // Use CRT1clk as soc display source
+ setbits_le32(&scu->clk_sel3, BIT(14) | BIT(13) | BIT(12));
+}
+
+static u32 ast2700_soc0_get_uartclk_rate(struct ast2700_scu0 *scu)
+{
+ u32 clksel2 = readl(&scu->clk_sel2);
+ u32 div = 1;
+ u32 rate;
+
+ if (clksel2 & BIT(15))
+ rate = 192000000;
+ else
+ rate = 24000000;
+
+ if (clksel2 & BIT(30))
+ div = 13;
+ return (rate / div);
+}
+
+static ulong ast2700_soc0_clk_get_rate(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ ulong rate = 0;
+
+ switch (clk->id) {
+ case SCU0_CLK_PSP:
+ rate = ast2700_soc0_get_pspclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_HPLL:
+ rate = ast2700_soc0_get_hpll_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_DPLL:
+ case SCU0_CLK_MPLL:
+ rate = ast2700_soc0_get_pll_rate((struct ast2700_scu0 *)priv->reg, clk->id);
+ break;
+ case SCU0_CLK_AXI0:
+ rate = ast2700_soc0_get_axi0clk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_AXI1:
+ rate = ast2700_soc0_get_axi1clk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_AHB:
+ rate = ast2700_soc0_get_hclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_APB:
+ rate = ast2700_soc0_get_pclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_GATE_EMMCCLK:
+ rate = ast2700_soc0_get_emmcclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_GATE_UART4CLK:
+ rate = ast2700_soc0_get_uartclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ case SCU0_CLK_MPHY:
+ rate = ast2700_soc0_get_mphyclk_rate((struct ast2700_scu0 *)priv->reg);
+ break;
+ default:
+ debug("%s: unknown clk %ld\n", __func__, clk->id);
+ return -ENOENT;
+ }
+
+ return rate;
+}
+
+static int ast2700_soc0_clk_enable(struct clk *clk)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(clk->dev);
+ struct ast2700_scu0 *scu = (struct ast2700_scu0 *)priv->reg;
+ u32 clkgate_bit = BIT(clk->id);
+
+ writel(clkgate_bit, &scu->clkgate_clr);
+
+ return 0;
+}
+
+static const struct clk_ops ast2700_soc0_clk_ops = {
+ .get_rate = ast2700_soc0_clk_get_rate,
+ .enable = ast2700_soc0_clk_enable,
+};
+
+static void ast2700_init_mac_clk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ u8 div_idx;
+
+ /* The MAC source clock selects HPLL only, and the default clock
+ * setting is 200 Mhz.
+ * Calculate the corresponding divider:
+ * 1: div 2
+ * 2: div 3
+ * ...
+ * 7: div 8
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++)
+ if (DIV_ROUND_UP(src_clk, div_idx + 1) == 200000000)
+ break;
+
+ if (div_idx == 8) {
+ pr_err("MAC clock cannot divide to 200 MHz\n");
+ return;
+ }
+
+ /* set HPLL clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(31, 29);
+ reg_280 |= div_idx << 29;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static void ast2700_init_rgmii_clk(struct ast2700_scu1 *scu)
+{
+ u32 reg_284 = readl(&scu->clk_sel2);
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, RGMII_DEFAULT_CLK_SRC);
+
+ if (RGMII_DEFAULT_CLK_SRC == SCU1_CLK_HPLL) {
+ u32 reg_280;
+ u8 div_idx;
+
+ /* Calculate the corresponding divider:
+ * 1: div 4
+ * 2: div 6
+ * ...
+ * 7: div 16
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++) {
+ u8 div = 4 + 2 * (div_idx - 1);
+
+ if (DIV_ROUND_UP(src_clk, div) == 125000000)
+ break;
+ }
+ if (div_idx == 8) {
+ pr_err("RGMII using HPLL cannot divide to 125 MHz\n");
+ return;
+ }
+
+ /* set HPLL clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(27, 25);
+ reg_280 |= div_idx << 25;
+ writel(reg_280, &scu->clk_sel1);
+
+ /* select HPLL clock source */
+ reg_284 &= ~BIT(18);
+ } else {
+ /* APLL clock divider is fixed to 8 */
+ if (DIV_ROUND_UP(src_clk, 8) != 125000000) {
+ pr_err("RGMII using APLL cannot divide to 125 MHz\n");
+ return;
+ }
+
+ /* select APLL clock source */
+ reg_284 |= BIT(18);
+ }
+
+ writel(reg_284, &scu->clk_sel2);
+}
+
+static void ast2700_init_rmii_clk(struct ast2700_scu1 *scu)
+{
+ u32 src_clk = ast2700_soc1_get_pll_rate(scu, SCU1_CLK_HPLL);
+ u32 reg_280;
+ u8 div_idx;
+
+ /* The RMII source clock selects HPLL only.
+ * Calculate the corresponding divider:
+ * 1: div 8
+ * 2: div 12
+ * ...
+ * 7: div 32
+ */
+ for (div_idx = 1; div_idx <= 7; div_idx++) {
+ u8 div = 8 + 4 * (div_idx - 1);
+
+ if (DIV_ROUND_UP(src_clk, div) == 50000000)
+ break;
+ }
+ if (div_idx == 8) {
+ pr_err("RMII using HPLL cannot divide to 50 MHz\n");
+ return;
+ }
+
+ /* set RMII clock divider */
+ reg_280 = readl(&scu->clk_sel1);
+ reg_280 &= ~GENMASK(23, 21);
+ reg_280 |= div_idx << 21;
+ writel(reg_280, &scu->clk_sel1);
+}
+
+static void ast2700_init_spi(struct ast2700_scu1 *scu)
+{
+ writel(readl(&scu->io_driving8) | 0x0000aaaa, &scu->io_driving8); /* fwspi driving */
+ writel(readl(&scu->io_driving3) | 0x00000aaa, &scu->io_driving3); /* spi0 driving */
+ writel(readl(&scu->io_driving3) | 0x0aaa0000, &scu->io_driving3); /* spi1 driving */
+ writel(readl(&scu->io_driving4) | 0x00002aaa, &scu->io_driving4); /* spi2 driving */
+}
+
+#define SCU1_CLK_I3C_DIV_MASK GENMASK(25, 23)
+#define SCU1_CLK_I3C_DIV(n) ((n) - 1)
+static void ast2700_init_i3c_clk(struct ast2700_scu1 *scu)
+{
+ u32 reg_284;
+
+ /* I3C 250MHz = HPLL/4 */
+ reg_284 = readl(&scu->clk_sel2);
+ reg_284 &= ~SCU1_CLK_I3C_DIV_MASK;
+ reg_284 |= FIELD_PREP(SCU1_CLK_I3C_DIV_MASK, SCU1_CLK_I3C_DIV(4));
+ writel(reg_284, &scu->clk_sel2);
+}
+
+static int ast2700_clk1_init(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+ struct ast2700_scu1 *scu = (struct ast2700_scu1 *)priv->reg;
+
+ ast2700_init_spi(scu);
+ ast2700_init_mac_clk(scu);
+ ast2700_init_rgmii_clk(scu);
+ ast2700_init_rmii_clk(scu);
+ ast2700_init_sdclk(scu);
+ ast2700_init_i3c_clk(scu);
+
+ return 0;
+}
+
+static int ast2700_clk0_init(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+ struct ast2700_scu0 *scu = (struct ast2700_scu0 *)priv->reg;
+
+ ast2700_emmc_init(scu);
+ ast2700_mphy_clk_init(scu);
+ ast2700_vga_clk_init(scu);
+
+ return 0;
+}
+
+static int ast2700_clk_probe(struct udevice *dev)
+{
+ struct ast2700_clk_priv *priv = dev_get_priv(dev);
+
+ priv->init = (ast2700_clk_init_fn)dev_get_driver_data(dev);
+ priv->reg = (void __iomem *)dev_read_addr_ptr(dev);
+
+ if (priv->init)
+ return priv->init(dev);
+
+ return 0;
+}
+
+static int ast2700_clk_bind(struct udevice *dev)
+{
+ struct udevice *sysreset_dev, *rst_dev;
+ int ret;
+
+ /* The system reset driver does not have a device node, so bind it here */
+ ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &sysreset_dev);
+ if (ret)
+ debug("Warning: No sysreset driver: ret = %d\n", ret);
+
+ /* Bind the per-SCU reset controller to the same ofnode so that
+ * <&syscon0/1 RESET_X> phandle references resolve to a UCLASS_RESET
+ * device. This pairs with the airoha-style binding pattern.
+ */
+ if (CONFIG_IS_ENABLED(RESET_AST2700)) {
+ ret = device_bind_driver_to_node(dev, "ast2700_reset", "reset",
+ dev_ofnode(dev), &rst_dev);
+ if (ret)
+ debug("Warning: failed to bind reset controller: ret = %d\n", ret);
+ }
+
+ return 0;
+}
+
+static const struct udevice_id ast2700_soc1_clk_ids[] = {
+ { .compatible = "aspeed,ast2700-scu1", .data = (ulong)&ast2700_clk1_init },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2700_soc1_clk) = {
+ .name = "aspeed_ast2700_scu1",
+ .id = UCLASS_CLK,
+ .of_match = ast2700_soc1_clk_ids,
+ .priv_auto = sizeof(struct ast2700_clk_priv),
+ .ops = &ast2700_soc1_clk_ops,
+ .probe = ast2700_clk_probe,
+ .bind = ast2700_clk_bind,
+};
+
+static const struct udevice_id ast2700_soc0_clk_ids[] = {
+ { .compatible = "aspeed,ast2700-scu0", .data = (ulong)&ast2700_clk0_init },
+ { },
+};
+
+U_BOOT_DRIVER(aspeed_ast2700_soc0_clk) = {
+ .name = "aspeed_ast2700_scu0",
+ .id = UCLASS_CLK,
+ .of_match = ast2700_soc0_clk_ids,
+ .priv_auto = sizeof(struct ast2700_clk_priv),
+ .ops = &ast2700_soc0_clk_ops,
+ .probe = ast2700_clk_probe,
+ .bind = ast2700_clk_bind,
+};
diff --git a/drivers/ram/aspeed/Kconfig b/drivers/ram/aspeed/Kconfig
index 023444b700c..fa5c890bb7a 100644
--- a/drivers/ram/aspeed/Kconfig
+++ b/drivers/ram/aspeed/Kconfig
@@ -77,7 +77,7 @@ choice
prompt "AST2700 DDR target date rate"
default ASPEED_DDR_3200
depends on ASPEED_RAM
- depends on TARGET_ASPEED_AST2700_IBEX
+ depends on ASPEED_AST2700 || TARGET_ASPEED_AST2700_IBEX
config ASPEED_DDR_1600
bool "1600 Mbps"
diff --git a/drivers/ram/aspeed/Makefile b/drivers/ram/aspeed/Makefile
index 1f0b22c8e9f..d29e2154ce9 100644
--- a/drivers/ram/aspeed/Makefile
+++ b/drivers/ram/aspeed/Makefile
@@ -2,4 +2,5 @@
#
obj-$(CONFIG_ASPEED_AST2500) += sdram_ast2500.o
obj-$(CONFIG_ASPEED_AST2600) += sdram_ast2600.o
+obj-$(CONFIG_ASPEED_AST2700) += sdram_ast2700.o
obj-$(CONFIG_TARGET_ASPEED_AST2700_IBEX) += sdram_ast2700.o
diff --git a/drivers/ram/aspeed/sdram_ast2700.c b/drivers/ram/aspeed/sdram_ast2700.c
index 00974da52bb..8605a92abb2 100644
--- a/drivers/ram/aspeed/sdram_ast2700.c
+++ b/drivers/ram/aspeed/sdram_ast2700.c
@@ -14,6 +14,11 @@
#include <linux/sizes.h>
#include <ram.h>
+__weak int fmc_hdr_get_prebuilt(u32 type, u32 *ofst, u32 *size)
+{
+ return -ENOSYS;
+}
+
enum ddr_type {
DDR4_1600 = 0x0,
DDR4_2400,
@@ -128,13 +133,13 @@ static size_t ast2700_sdrammc_get_vga_mem_size(struct sdrammc *sdrammc)
reg = readl(scu0 + SCU0_PCI_MISC70);
if (reg & SCU0_PCI_MISC70_EN_PCIEVGA0) {
- debug("VGA0:%dMB\n", vga_memsz[sel] / SZ_1M);
+ debug("VGA0:%zuMB\n", vga_memsz[sel] / SZ_1M);
dual++;
}
reg = readl(scu0 + SCU0_PCI_MISC80);
if (reg & SCU0_PCI_MISC80_EN_PCIEVGA1) {
- debug("VGA1:%dMB\n", vga_memsz[sel] / SZ_1M);
+ debug("VGA1:%zuMB\n", vga_memsz[sel] / SZ_1M);
dual++;
}
@@ -560,7 +565,7 @@ void dwc_get_mailbox(struct sdrammc *sdrammc, const int mode, u32 *mbox)
dwc_ddrphy_apb_wr(0xd0031, 1);
}
-uint32_t dwc_readMsgBlock(struct sdrammc *sdrammc, const u32 addr_half)
+u32 dwc_readMsgBlock(struct sdrammc *sdrammc, const u32 addr_half)
{
u32 data_word;
@@ -727,7 +732,7 @@ int dwc_ddrphy_phyinit_userCustom_D_loadIMEM(struct sdrammc *sdrammc, const int
fmc_hdr_get_prebuilt(pb_type, &imem_ofst, &imem_size);
memcpy(sdrammc->phy + (DWC_PHY_IMEM_OFST << 1),
- (void *)(0x20000000 + imem_ofst), imem_size);
+ (void *)(uintptr_t)(0x20000000 + imem_ofst), imem_size);
return 0;
}
@@ -746,7 +751,7 @@ int dwc_ddrphy_phyinit_userCustom_F_loadDMEM(struct sdrammc *sdrammc,
fmc_hdr_get_prebuilt(pb_type, &dmem_ofst, &dmem_size);
memcpy(sdrammc->phy + (DWC_PHY_DMEM_OFST << 1),
- (void *)(0x20000000 + dmem_ofst), dmem_size);
+ (void *)(uintptr_t)(0x20000000 + dmem_ofst), dmem_size);
return 0;
}
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index e7c0870c918..c851354c7a5 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -107,6 +107,15 @@ config RESET_AST2600
Say Y if you want to control reset signals of different peripherals
through System Control Unit (SCU).
+config RESET_AST2700
+ bool "Reset controller driver for AST2700 SoCs"
+ depends on DM_RESET && ASPEED_AST2700
+ default y if ASPEED_AST2700
+ help
+ Support for reset controller on AST2700 SoC.
+ Say Y if you want to control reset signals of different peripherals
+ through System Control Unit (SCU).
+
config RESET_ROCKCHIP
bool "Reset controller driver for Rockchip SoCs"
depends on DM_RESET && ARCH_ROCKCHIP && CLK
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index 2c83f858895..3fce96509cd 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.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_AST2700) += reset-ast2700.o
obj-$(CONFIG_$(PHASE_)RESET_ROCKCHIP) += reset-rockchip.o rst-rk3506.o rst-rk3528.o rst-rk3576.o rst-rk3588.o
obj-$(CONFIG_RESET_MESON) += reset-meson.o
obj-$(CONFIG_RESET_SOCFPGA) += reset-socfpga.o
diff --git a/drivers/reset/reset-ast2700.c b/drivers/reset/reset-ast2700.c
new file mode 100644
index 00000000000..2dd9e36cc0a
--- /dev/null
+++ b/drivers/reset/reset-ast2700.c
@@ -0,0 +1,82 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#include <asm/io.h>
+#include <dm.h>
+#include <linux/err.h>
+#include <reset.h>
+#include <reset-uclass.h>
+
+/* Offset of the modrst register block within the SCU. */
+#define AST2700_RESET_OFFSET 0x200
+
+struct ast2700_reset_priv {
+ void __iomem *base;
+};
+
+static int ast2700_reset_assert(struct reset_ctl *reset_ctl)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+
+ if (reset_ctl->id < 32)
+ writel(BIT(reset_ctl->id), priv->base);
+ else
+ writel(BIT(reset_ctl->id - 32), priv->base + 0x20);
+
+ return 0;
+}
+
+static int ast2700_reset_deassert(struct reset_ctl *reset_ctl)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+
+ if (reset_ctl->id < 32)
+ writel(BIT(reset_ctl->id), priv->base + 0x04);
+ else
+ writel(BIT(reset_ctl->id - 32), priv->base + 0x24);
+
+ return 0;
+}
+
+static int ast2700_reset_status(struct reset_ctl *reset_ctl)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(reset_ctl->dev);
+ int status;
+
+ if (reset_ctl->id < 32)
+ status = BIT(reset_ctl->id) & readl(priv->base);
+ else
+ status = BIT(reset_ctl->id - 32) & readl(priv->base + 0x20);
+
+ return !!status;
+}
+
+static int ast2700_reset_probe(struct udevice *dev)
+{
+ struct ast2700_reset_priv *priv = dev_get_priv(dev);
+ void __iomem *scu_base;
+
+ scu_base = dev_read_addr_ptr(dev);
+ if (!scu_base)
+ return -EINVAL;
+
+ priv->base = scu_base + AST2700_RESET_OFFSET;
+
+ return 0;
+}
+
+static const struct reset_ops ast2700_reset_ops = {
+ .rst_assert = ast2700_reset_assert,
+ .rst_deassert = ast2700_reset_deassert,
+ .rst_status = ast2700_reset_status,
+};
+
+U_BOOT_DRIVER(ast2700_reset) = {
+ .name = "ast2700_reset",
+ .id = UCLASS_RESET,
+ .probe = ast2700_reset_probe,
+ .ops = &ast2700_reset_ops,
+ .priv_auto = sizeof(struct ast2700_reset_priv),
+};
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index ca29cfd7c88..0186b01ad9a 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -53,18 +53,20 @@ struct aspeed_spi_regs {
u32 dma_len; /* 0x8c DMA Length Register */
u32 dma_checksum; /* 0x90 Checksum Calculation Result */
u32 timings[ASPEED_SPI_MAX_CS]; /* 0x94 Read Timing Compensation */
+ u32 _reserved3[83]; /* 0xA8 - 0x1F0 */
+ u32 val_kept_wdt; /* 0x1F4 Value Kept WDT */
};
struct aspeed_spi_plat {
u8 max_cs;
- void __iomem *ahb_base; /* AHB address base for all flash devices. */
+ uintptr_t ahb_base; /* AHB address base for all flash devices. */
fdt_size_t ahb_sz; /* Overall AHB window size for all flash device. */
u32 hclk_rate; /* AHB clock rate */
};
struct aspeed_spi_flash {
- void __iomem *ahb_base;
- u32 ahb_decoded_sz;
+ uintptr_t ahb_base;
+ size_t ahb_decoded_sz;
u32 ce_ctrl_user;
u32 ce_ctrl_read;
u32 max_freq;
@@ -84,9 +86,9 @@ struct aspeed_spi_info {
u32 min_decoded_sz;
u32 clk_ctrl_mask;
void (*set_4byte)(struct udevice *bus, u32 cs);
- u32 (*segment_start)(struct udevice *bus, u32 reg);
- u32 (*segment_end)(struct udevice *bus, u32 reg);
- u32 (*segment_reg)(u32 start, u32 end);
+ uintptr_t (*segment_start)(struct udevice *bus, u32 reg);
+ uintptr_t (*segment_end)(struct udevice *bus, u32 reg);
+ u32 (*segment_reg)(uintptr_t start, uintptr_t end);
int (*adjust_decoded_sz)(struct udevice *bus);
u32 (*get_clk_setting)(struct udevice *dev, uint hz);
};
@@ -118,30 +120,30 @@ static u32 aspeed_spi_get_io_mode(u32 bus_width)
}
}
-static u32 ast2400_spi_segment_start(struct udevice *bus, u32 reg)
+static uintptr_t ast2400_spi_segment_start(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 start_offset = ((reg >> 16) & 0xff) << 23;
+ uintptr_t start_offset = ((reg >> 16) & 0xff) << 23;
if (start_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + start_offset;
+ return plat->ahb_base + start_offset;
}
-static u32 ast2400_spi_segment_end(struct udevice *bus, u32 reg)
+static uintptr_t ast2400_spi_segment_end(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 end_offset = ((reg >> 24) & 0xff) << 23;
+ uintptr_t end_offset = ((reg >> 24) & 0xff) << 23;
/* Meaningless end_offset, set to physical ahb base. */
if (end_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + end_offset;
+ return plat->ahb_base + end_offset;
}
-static u32 ast2400_spi_segment_reg(u32 start, u32 end)
+static u32 ast2400_spi_segment_reg(uintptr_t start, uintptr_t end)
{
if (start == end)
return 0;
@@ -206,30 +208,30 @@ static u32 ast2400_get_clk_setting(struct udevice *dev, uint max_hz)
return hclk_div;
}
-static u32 ast2500_spi_segment_start(struct udevice *bus, u32 reg)
+static uintptr_t ast2500_spi_segment_start(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 start_offset = ((reg >> 16) & 0xff) << 23;
+ uintptr_t start_offset = ((reg >> 16) & 0xff) << 23;
if (start_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + start_offset;
+ return plat->ahb_base + start_offset;
}
-static u32 ast2500_spi_segment_end(struct udevice *bus, u32 reg)
+static uintptr_t ast2500_spi_segment_end(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 end_offset = ((reg >> 24) & 0xff) << 23;
+ uintptr_t end_offset = ((reg >> 24) & 0xff) << 23;
/* Meaningless end_offset, set to physical ahb base. */
if (end_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + end_offset;
+ return plat->ahb_base + end_offset;
}
-static u32 ast2500_spi_segment_reg(u32 start, u32 end)
+static u32 ast2500_spi_segment_reg(uintptr_t start, uintptr_t end)
{
if (start == end)
return 0;
@@ -346,30 +348,30 @@ end:
return hclk_div;
}
-static u32 ast2600_spi_segment_start(struct udevice *bus, u32 reg)
+static uintptr_t ast2600_spi_segment_start(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 start_offset = (reg << 16) & 0x0ff00000;
+ uintptr_t start_offset = (reg << 16) & 0x0ff00000;
if (start_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + start_offset;
+ return plat->ahb_base + start_offset;
}
-static u32 ast2600_spi_segment_end(struct udevice *bus, u32 reg)
+static uintptr_t ast2600_spi_segment_end(struct udevice *bus, u32 reg)
{
struct aspeed_spi_plat *plat = dev_get_plat(bus);
- u32 end_offset = reg & 0x0ff00000;
+ uintptr_t end_offset = reg & 0x0ff00000;
/* Meaningless end_offset, set to physical ahb base. */
if (end_offset == 0)
- return (u32)plat->ahb_base;
+ return plat->ahb_base;
- return (u32)plat->ahb_base + end_offset + 0x100000;
+ return plat->ahb_base + end_offset + 0x100000;
}
-static u32 ast2600_spi_segment_reg(u32 start, u32 end)
+static u32 ast2600_spi_segment_reg(uintptr_t start, uintptr_t end)
{
if (start == end)
return 0;
@@ -473,6 +475,70 @@ static u32 ast2600_get_clk_setting(struct udevice *dev, uint max_hz)
return hclk_div;
}
+static uintptr_t ast2700_spi_segment_start(struct udevice *bus, u32 reg)
+{
+ struct aspeed_spi_plat *plat = dev_get_plat(bus);
+ uintptr_t start_offset = (reg & 0x0000ffff) << 16;
+
+ if (start_offset == 0)
+ return plat->ahb_base;
+
+ return plat->ahb_base + start_offset;
+}
+
+static uintptr_t ast2700_spi_segment_end(struct udevice *bus, u32 reg)
+{
+ struct aspeed_spi_plat *plat = dev_get_plat(bus);
+ uintptr_t end_offset = reg & 0xffff0000;
+
+ /* Meaningless end_offset, set to physical ahb base. */
+ if (end_offset == 0)
+ return plat->ahb_base;
+
+ return plat->ahb_base + end_offset;
+}
+
+static u32 ast2700_spi_segment_reg(uintptr_t start, uintptr_t end)
+{
+ if (start == end)
+ return 0;
+
+ return (((start >> 16) & 0x7fff) | ((end + 1) & 0x7fff0000));
+}
+
+static void ast2700_spi_chip_set_4byte(struct udevice *bus, u32 cs)
+{
+ struct aspeed_spi_priv *priv = dev_get_priv(bus);
+ u32 reg_val;
+
+ reg_val = readl(&priv->regs->ctrl);
+ reg_val |= 0x11 << cs;
+ writel(reg_val, &priv->regs->ctrl);
+
+ reg_val = readl(&priv->regs->val_kept_wdt);
+ reg_val |= (0x11 << 4) << cs;
+ writel(reg_val, &priv->regs->val_kept_wdt);
+}
+
+static int ast2700_adjust_decoded_size(struct udevice *bus)
+{
+ struct aspeed_spi_plat *plat = dev_get_plat(bus);
+ struct aspeed_spi_priv *priv = dev_get_priv(bus);
+ struct aspeed_spi_flash *flashes = &priv->flashes[0];
+ int ret;
+ int cs;
+
+ /* Close unused CS. */
+ for (cs = priv->num_cs; cs < plat->max_cs; cs++)
+ flashes[cs].ahb_decoded_sz = 0;
+
+ ret = aspeed_spi_trim_decoded_size(bus);
+ if (ret != 0)
+ return ret;
+
+ return 0;
+}
+
/*
* As the flash size grows up, we need to trim some decoded
* size if needed for the sake of conforming the maximum
@@ -512,12 +578,12 @@ static int aspeed_spi_trim_decoded_size(struct udevice *bus)
return 0;
}
-static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf,
+static int aspeed_spi_read_from_ahb(uintptr_t ahb_base, void *buf,
size_t len)
{
size_t offset = 0;
- if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) &&
+ if (IS_ALIGNED(ahb_base, sizeof(uintptr_t)) &&
IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) {
readsl(ahb_base, buf, len >> 2);
offset = len & ~0x3;
@@ -529,12 +595,12 @@ static int aspeed_spi_read_from_ahb(void __iomem *ahb_base, void *buf,
return 0;
}
-static int aspeed_spi_write_to_ahb(void __iomem *ahb_base, const void *buf,
+static int aspeed_spi_write_to_ahb(uintptr_t ahb_base, const void *buf,
size_t len)
{
size_t offset = 0;
- if (IS_ALIGNED((uintptr_t)ahb_base, sizeof(uintptr_t)) &&
+ if (IS_ALIGNED(ahb_base, sizeof(uintptr_t)) &&
IS_ALIGNED((uintptr_t)buf, sizeof(uintptr_t))) {
writesl(ahb_base, buf, len >> 2);
offset = len & ~0x3;
@@ -589,7 +655,7 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave,
struct aspeed_spi_priv *priv = dev_get_priv(bus);
struct dm_spi_slave_plat *slave_plat = dev_get_parent_plat(slave->dev);
u32 cs = slave_plat->cs[0];
- u32 ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs];
+ uintptr_t ce_ctrl_reg = (uintptr_t)&priv->regs->ce_ctrl[cs];
u32 ce_ctrl_val;
struct aspeed_spi_flash *flash = &priv->flashes[cs];
u8 dummy_data[16] = {0};
@@ -602,7 +668,7 @@ static int aspeed_spi_exec_op_user_mode(struct spi_slave *slave,
op->data.nbytes, op->data.buswidth);
if (priv->info == &ast2400_spi_info)
- ce_ctrl_reg = (u32)&priv->regs->ctrl;
+ ce_ctrl_reg = (uintptr_t)&priv->regs->ctrl;
/*
* Set controller to 4-byte address mode
@@ -670,7 +736,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
u32 i;
u32 cs = slave_plat->cs[0];
u32 cmd_io_conf;
- u32 ce_ctrl_reg;
+ uintptr_t ce_ctrl_reg;
if (desc->info.op_tmpl.data.dir == SPI_MEM_DATA_OUT) {
/*
@@ -681,9 +747,9 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
return -EOPNOTSUPP;
}
- ce_ctrl_reg = (u32)&priv->regs->ce_ctrl[cs];
+ ce_ctrl_reg = (uintptr_t)&priv->regs->ce_ctrl[cs];
if (info == &ast2400_spi_info)
- ce_ctrl_reg = (u32)&priv->regs->ctrl;
+ ce_ctrl_reg = (uintptr_t)&priv->regs->ctrl;
if (desc->info.length > 0x1000000)
priv->info->set_4byte(bus, cs);
@@ -693,7 +759,7 @@ static int aspeed_spi_dirmap_create(struct spi_mem_dirmap_desc *desc)
priv->flashes[cs].ahb_decoded_sz = desc->info.length;
for (i = 0; i < priv->num_cs; i++) {
- dev_dbg(dev, "cs: %d, sz: 0x%x\n", i,
+ dev_dbg(dev, "cs: %d, sz: 0x%zx\n", i,
priv->flashes[cs].ahb_decoded_sz);
}
@@ -728,7 +794,7 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
u32 cs = slave_plat->cs[0];
int ret;
- dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%x\n",
+ dev_dbg(dev, "read op:0x%x, addr:0x%llx, len:0x%zx\n",
desc->info.op_tmpl.cmd.opcode, offs, len);
if (priv->flashes[cs].ahb_decoded_sz < offs + len ||
@@ -738,7 +804,10 @@ static ssize_t aspeed_spi_dirmap_read(struct spi_mem_dirmap_desc *desc,
if (ret != 0)
return 0;
} else {
- memcpy_fromio(buf, priv->flashes[cs].ahb_base + offs, len);
+ memcpy_fromio(buf,
+ (void __iomem *)(priv->flashes[cs].ahb_base +
+ (uintptr_t)offs),
+ len);
}
return len;
@@ -783,19 +852,19 @@ static void aspeed_spi_decoded_range_set(struct udevice *bus)
struct aspeed_spi_plat *plat = dev_get_plat(bus);
struct aspeed_spi_priv *priv = dev_get_priv(bus);
u32 decoded_reg_val;
- u32 start_addr, end_addr;
+ uintptr_t start_addr, end_addr;
u32 cs;
for (cs = 0; cs < plat->max_cs; cs++) {
- start_addr = (u32)priv->flashes[cs].ahb_base;
- end_addr = (u32)priv->flashes[cs].ahb_base +
+ start_addr = priv->flashes[cs].ahb_base;
+ end_addr = priv->flashes[cs].ahb_base +
priv->flashes[cs].ahb_decoded_sz;
decoded_reg_val = priv->info->segment_reg(start_addr, end_addr);
writel(decoded_reg_val, &priv->regs->segment_addr[cs]);
- dev_dbg(bus, "cs: %d, decoded_reg: 0x%x, start: 0x%x, end: 0x%x\n",
+ dev_dbg(bus, "cs: %d, decoded_reg: 0x%x, start: 0x%lx, end: 0x%lx\n",
cs, decoded_reg_val, start_addr, end_addr);
}
}
@@ -851,13 +920,13 @@ static int aspeed_spi_decoded_ranges_sanity(struct udevice *bus)
* address base are monotonic increasing with CE#.
*/
for (cs = plat->max_cs - 1; cs > 0; cs--) {
- if ((u32)priv->flashes[cs].ahb_base != 0 &&
- (u32)priv->flashes[cs].ahb_base <
- (u32)priv->flashes[cs - 1].ahb_base +
+ if (priv->flashes[cs].ahb_base != 0 &&
+ priv->flashes[cs].ahb_base <
+ priv->flashes[cs - 1].ahb_base +
priv->flashes[cs - 1].ahb_decoded_sz) {
- dev_err(bus, "decoded range overlay 0x%08x 0x%08x\n",
- (u32)priv->flashes[cs].ahb_base,
- (u32)priv->flashes[cs - 1].ahb_base);
+ dev_err(bus, "decoded range overlay 0x%08lx 0x%08lx\n",
+ priv->flashes[cs].ahb_base,
+ priv->flashes[cs - 1].ahb_base);
return -EINVAL;
}
}
@@ -895,14 +964,13 @@ static int aspeed_spi_read_fixed_decoded_ranges(struct udevice *bus)
return ret;
for (i = 0; i < count; i++) {
- priv->flashes[ranges[i].cs].ahb_base =
- (void __iomem *)ranges[i].ahb_base;
+ priv->flashes[ranges[i].cs].ahb_base = ranges[i].ahb_base;
priv->flashes[ranges[i].cs].ahb_decoded_sz =
ranges[i].sz;
}
for (i = 0; i < plat->max_cs; i++) {
- dev_dbg(bus, "ahb_base: 0x%p, size: 0x%08x\n",
+ dev_dbg(bus, "ahb_base: 0x%lx, size: 0x%08zx\n",
priv->flashes[i].ahb_base,
priv->flashes[i].ahb_decoded_sz);
}
@@ -1063,6 +1131,32 @@ static const struct aspeed_spi_info ast2600_spi_info = {
.get_clk_setting = ast2600_get_clk_setting,
};
+static const struct aspeed_spi_info ast2700_fmc_info = {
+ .io_mode_mask = 0xf0000000,
+ .max_bus_width = 4,
+ .min_decoded_sz = 0x10000,
+ .clk_ctrl_mask = 0x0f000f00,
+ .set_4byte = ast2700_spi_chip_set_4byte,
+ .segment_start = ast2700_spi_segment_start,
+ .segment_end = ast2700_spi_segment_end,
+ .segment_reg = ast2700_spi_segment_reg,
+ .adjust_decoded_sz = ast2700_adjust_decoded_size,
+ .get_clk_setting = ast2600_get_clk_setting,
+};
+
+static const struct aspeed_spi_info ast2700_spi_info = {
+ .io_mode_mask = 0xf0000000,
+ .max_bus_width = 4,
+ .min_decoded_sz = 0x10000,
+ .clk_ctrl_mask = 0x0f000f00,
+ .set_4byte = ast2700_spi_chip_set_4byte,
+ .segment_start = ast2700_spi_segment_start,
+ .segment_end = ast2700_spi_segment_end,
+ .segment_reg = ast2700_spi_segment_reg,
+ .adjust_decoded_sz = ast2700_adjust_decoded_size,
+ .get_clk_setting = ast2600_get_clk_setting,
+};
+
static int aspeed_spi_claim_bus(struct udevice *dev)
{
struct udevice *bus = dev->parent;
@@ -1129,7 +1223,8 @@ static int apseed_spi_of_to_plat(struct udevice *bus)
return -EINVAL;
}
- plat->ahb_base = devfdt_get_addr_size_index_ptr(bus, 1, &plat->ahb_sz);
+ plat->ahb_base =
+ (uintptr_t)devfdt_get_addr_size_index_ptr(bus, 1, &plat->ahb_sz);
if (!plat->ahb_base) {
dev_err(bus, "wrong AHB base\n");
return -EINVAL;
@@ -1147,8 +1242,8 @@ static int apseed_spi_of_to_plat(struct udevice *bus)
plat->hclk_rate = clk_get_rate(&hclk);
- dev_dbg(bus, "ctrl_base = 0x%x, ahb_base = 0x%p, size = 0x%llx\n",
- (u32)priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
+ dev_dbg(bus, "ctrl_base = 0x%p, ahb_base = 0x%lx, size = 0x%llx\n",
+ priv->regs, plat->ahb_base, (fdt64_t)plat->ahb_sz);
dev_dbg(bus, "hclk = %dMHz, max_cs = %d\n",
plat->hclk_rate / 1000000, plat->max_cs);
@@ -1199,6 +1294,8 @@ static const struct udevice_id aspeed_spi_ids[] = {
{ .compatible = "aspeed,ast2500-spi", .data = (ulong)&ast2500_spi_info, },
{ .compatible = "aspeed,ast2600-fmc", .data = (ulong)&ast2600_fmc_info, },
{ .compatible = "aspeed,ast2600-spi", .data = (ulong)&ast2600_spi_info, },
+ { .compatible = "aspeed,ast2700-fmc", .data = (ulong)&ast2700_fmc_info, },
+ { .compatible = "aspeed,ast2700-spi", .data = (ulong)&ast2700_spi_info, },
{ }
};
diff --git a/include/configs/evb_ast2700.h b/include/configs/evb_ast2700.h
new file mode 100644
index 00000000000..6b73eddc1af
--- /dev/null
+++ b/include/configs/evb_ast2700.h
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) ASPEED Technology Inc.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/aspeed-common.h>
+
+/* Extra ENV for Boot Command */
+#define STR_HELPER(n) #n
+#define STR(n) STR_HELPER(n)
+
+#define CFG_SYS_UBOOT_BASE CONFIG_TEXT_BASE
+
+#define CFG_EXTRA_ENV_SETTINGS \
+ "bootspi=fdt addr ${fdtspiaddr} && " \
+ "fdt header get fitsize totalsize && " \
+ "cp.b ${fdtspiaddr} ${loadaddr} ${fitsize} && " \
+ "bootm ${loadaddr}; " \
+ "echo Error loading kernel FIT image\0" \
+ "loadaddr=" STR(CONFIG_SYS_LOAD_ADDR) "\0" \
+ "bootside=a\0" \
+ "rootfs=rofs-a\0" \
+ "setmmcargs=setenv bootargs ${bootargs} " \
+ "rootwait root=PARTLABEL=${rootfs}\0" \
+ "boota=setenv bootpart 2; setenv rootfs rofs-a; " \
+ "run setmmcargs; " \
+ "ext4load mmc 0:${bootpart} ${loadaddr} fitImage && " \
+ "bootm ${loadaddr}; " \
+ "echo Error loading kernel FIT image\0" \
+ "bootb=setenv bootpart 3; setenv rootfs rofs-b; " \
+ "run setmmcargs; " \
+ "ext4load mmc 0:${bootpart} ${loadaddr} fitImage && " \
+ "bootm ${loadaddr}; " \
+ "echo Error loading kernel FIT image\0" \
+ "bootmmc=if test \"${bootside}\" = \"b\"; " \
+ "then run bootb; run boota; " \
+ "else run boota; run bootb; fi\0" \
+ "setufsargs=setenv bootargs ${bootargs} " \
+ "rootwait root=PARTLABEL=${rootfs}\0" \
+ "ufsboota=setenv bootpart 2; setenv rootfs rofs-a; " \
+ "run setufsargs; " \
+ "ext4load scsi 0:${bootpart} ${loadaddr} fitImage && " \
+ "bootm ${loadaddr}; " \
+ "echo Error loading kernel FIT image\0" \
+ "ufsbootb=setenv bootpart 3; setenv rootfs rofs-b; " \
+ "run setufsargs; " \
+ "ext4load scsi 0:${bootpart} ${loadaddr} fitImage && " \
+ "bootm ${loadaddr}; " \
+ "echo Error loading kernel FIT image\0" \
+ "bootufs=if test \"${bootside}\" = \"b\"; " \
+ "then run ufsbootb; run ufsboota; " \
+ "else run ufsboota; run ufsbootb; fi\0" \
+ "verify=no\0" \
+ ""
+#endif /* __CONFIG_H */