* [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5
@ 2024-10-29 8:42 Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 01/10] ARM: socfpga: kconfig: sort entries Steffen Trumtrar
` (9 more replies)
0 siblings, 10 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
This series adds basic support for the Altera Agilex5 SoCFPGA series.
Currently only booting from QSPI is supported. Flashing the image to the
QSPI has to be done with quartus_pgm, therefore there are still some
essential things left to have proper support for this platform.
Nevertheless it boots from QSPI and starts linux on the included
Arrow AXE5 board.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
Steffen Trumtrar (10):
ARM: socfpga: kconfig: sort entries
mach: socfpga: debug_ll: rework putc_ll
reset: reset-socfpga: build only for 32-bit socfpga
arm: socfgpa: add support for SoCFPGA Agilex5
ARM: socfpga: add Arrow AXE5 Agilex5 board
net: add support for Designware XGMAC (10gb) ethernet
net: phy: add Analog Devices ADIN1300
linux: clk: add clk_parent_data
clk: support init->parent_data
clk: socfpga: add agilex5 clock support
arch/arm/Kconfig | 3 -
arch/arm/boards/Makefile | 1 +
arch/arm/boards/arrow-axe5-eagle/Makefile | 3 +
arch/arm/boards/arrow-axe5-eagle/board.c | 23 +
arch/arm/boards/arrow-axe5-eagle/lowlevel.c | 58 ++
arch/arm/configs/socfpga-agilex5_defconfig | 88 +++
arch/arm/dts/Makefile | 1 +
arch/arm/dts/socfpga_agilex5.dtsi | 71 +++
arch/arm/dts/socfpga_agilex5_axe5_eagle.dts | 94 +++
arch/arm/mach-socfpga/Kconfig | 56 +-
arch/arm/mach-socfpga/Makefile | 13 +
arch/arm/mach-socfpga/agilex5-clock-manager.c | 411 +++++++++++++
arch/arm/mach-socfpga/agilex5-sdram.c | 352 +++++++++++
arch/arm/mach-socfpga/agilex5-secreg.c | 289 +++++++++
arch/arm/mach-socfpga/arria10-init.c | 2 +-
arch/arm/mach-socfpga/atf.c | 34 ++
arch/arm/mach-socfpga/cpu_init.c | 43 ++
arch/arm/mach-socfpga/cyclone5-init.c | 2 +-
arch/arm/mach-socfpga/iossm_mailbox.c | 551 +++++++++++++++++
arch/arm/mach-socfpga/iossm_mailbox.h | 152 +++++
arch/arm/mach-socfpga/mailbox_s10.c | 407 +++++++++++++
arch/arm/mach-socfpga/secure_reg_helper.c | 75 +++
arch/arm/mach-socfpga/smc_api.c | 43 ++
arch/arm/mach-socfpga/soc64-system-manager.c | 102 ++++
arch/arm/mach-socfpga/soc64-wrap-handoff.c | 124 ++++
common/Kconfig.debug_ll | 17 +
drivers/clk/clk.c | 48 +-
drivers/clk/socfpga/Makefile | 4 +-
drivers/clk/socfpga/clk-agilex5.c | 834 ++++++++++++++++++++++++++
drivers/clk/socfpga/clk-gate-s10.c | 184 ++++++
drivers/clk/socfpga/clk-periph-s10.c | 163 +++++
drivers/clk/socfpga/clk-pll-s10.c | 140 +++++
drivers/clk/socfpga/clk.h | 9 +
drivers/clk/socfpga/stratix10-clk.h | 73 +++
drivers/net/Kconfig | 18 +
drivers/net/Makefile | 2 +
drivers/net/designware_xgmac.c | 829 +++++++++++++++++++++++++
drivers/net/designware_xgmac.h | 294 +++++++++
drivers/net/designware_xgmac_socfpga.c | 156 +++++
drivers/net/phy/Kconfig | 7 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/adin.c | 360 +++++++++++
drivers/reset/Kconfig | 6 +
drivers/reset/Makefile | 2 +-
firmware/Kconfig | 3 +
firmware/Makefile | 1 +
images/Makefile.socfpga | 17 +
include/dt-bindings/clock/agilex5-clock.h | 100 +++
include/linux/clk.h | 15 +
include/linux/intel-smc.h | 545 +++++++++++++++++
include/mach/socfpga/agilex5-clk.h | 266 ++++++++
include/mach/socfpga/atf.h | 14 +
include/mach/socfpga/debug_ll.h | 44 +-
include/mach/socfpga/generic.h | 3 +
include/mach/socfpga/init.h | 2 +
include/mach/socfpga/mailbox_s10.h | 199 ++++++
include/mach/socfpga/secure_reg_helper.h | 19 +
include/mach/socfpga/smc_api.h | 12 +
include/mach/socfpga/soc64-firewall.h | 177 ++++++
include/mach/socfpga/soc64-handoff.h | 50 ++
include/mach/socfpga/soc64-init.h | 4 +
include/mach/socfpga/soc64-regs.h | 195 ++++++
include/mach/socfpga/soc64-reset-manager.h | 40 ++
include/mach/socfpga/soc64-sdram.h | 203 +++++++
include/mach/socfpga/soc64-system-manager.h | 176 ++++++
65 files changed, 8190 insertions(+), 40 deletions(-)
---
base-commit: 1f31cde526d4e251da6464cac42ee2252643b972
change-id: 20241029-v2024-10-0-topic-socfpga-agilex5-c087bbc7d774
Best regards,
--
Steffen Trumtrar <s.trumtrar@pengutronix.de>
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 01/10] ARM: socfpga: kconfig: sort entries
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 02/10] mach: socfpga: debug_ll: rework putc_ll Steffen Trumtrar
` (8 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Sort the SoCFPGA entries in the menu by soc type. Add a comment while at it.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm/mach-socfpga/Kconfig | 23 +++++++++++++++--------
1 file changed, 15 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index a4d71777978869c29443e4499c262875a835437d..80a15377b2e4be4d1386904a298a9aadcffbab00 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -23,6 +23,10 @@ config ARCH_SOCFPGA_ARRIA10
select OFDEVICE
select OFTREE
+if 32BIT
+
+comment "Cyclone5 boards"
+
config MACH_SOCFPGA_ALTERA_SOCDK
select ARCH_SOCFPGA_CYCLONE5
bool "Altera SoCFPGA Development Kit"
@@ -31,14 +35,6 @@ config MACH_SOCFPGA_EBV_SOCRATES
select ARCH_SOCFPGA_CYCLONE5
bool "EBV Socrates"
-config MACH_SOCFPGA_ENCLUSTRA_AA1
- select ARCH_SOCFPGA_ARRIA10
- bool "Enclustra AA1"
-
-config MACH_SOCFPGA_REFLEX_ACHILLES
- select ARCH_SOCFPGA_ARRIA10
- bool "Reflex Achilles"
-
config MACH_SOCFPGA_TERASIC_DE0_NANO_SOC
select ARCH_SOCFPGA_CYCLONE5
bool "Terasic DE0-NANO-SoC aka Atlas"
@@ -51,4 +47,15 @@ config MACH_SOCFPGA_TERASIC_SOCKIT
select ARCH_SOCFPGA_CYCLONE5
bool "Terasic SoCKit"
+comment "Arria10 boards"
+
+config MACH_SOCFPGA_ENCLUSTRA_AA1
+ select ARCH_SOCFPGA_ARRIA10
+ bool "Enclustra AA1"
+
+config MACH_SOCFPGA_REFLEX_ACHILLES
+ select ARCH_SOCFPGA_ARRIA10
+ bool "Reflex Achilles"
+
+endif
endif
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 02/10] mach: socfpga: debug_ll: rework putc_ll
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 01/10] ARM: socfpga: kconfig: sort entries Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 03/10] reset: reset-socfpga: build only for 32-bit socfpga Steffen Trumtrar
` (7 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Cleanup the debug_ll code for SoCFPGA. The old Gen5 Socfpga have a
narrower ioport width for the NS16550. All newer generations support
32-bit access. Invert the logic and add new *_uart_putc functions for
use with pbl_set_putc.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm/mach-socfpga/arria10-init.c | 2 +-
arch/arm/mach-socfpga/cyclone5-init.c | 2 +-
include/mach/socfpga/debug_ll.h | 44 +++++++++++++++++++++++------------
3 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/arch/arm/mach-socfpga/arria10-init.c b/arch/arm/mach-socfpga/arria10-init.c
index f8a15ec8b46a761904e470d66bd0900fdb0686ec..14cee3196ade7d36adbb1b70c5b0041bce3cc193 100644
--- a/arch/arm/mach-socfpga/arria10-init.c
+++ b/arch/arm/mach-socfpga/arria10-init.c
@@ -147,7 +147,7 @@ void arria10_finish_io(uint32_t *pinmux)
arria10_reset_deassert_fpga_peripherals();
- INIT_LL();
+ socfpga_uart_setup_ll();
puts_ll("lowlevel init done\n");
}
diff --git a/arch/arm/mach-socfpga/cyclone5-init.c b/arch/arm/mach-socfpga/cyclone5-init.c
index 79a9b15d8761baa8b576a83871a06fbf0559ce91..63ec48b8e48d7e8daa9ce9c158ad5716739b9b3d 100644
--- a/arch/arm/mach-socfpga/cyclone5-init.c
+++ b/arch/arm/mach-socfpga/cyclone5-init.c
@@ -56,5 +56,5 @@ void socfpga_lowlevel_init(struct socfpga_cm_config *cm_config,
writel(0x18, CYCLONE5_L3REGS_ADDRESS);
writel(0x1, 0xfffefc00);
- INIT_LL();
+ socfpga_uart_setup_ll();
}
diff --git a/include/mach/socfpga/debug_ll.h b/include/mach/socfpga/debug_ll.h
index 25b3581634704ac523b031a915b73408b674e0c5..698cca60373f7e382db12344e83925dbcb3b35aa 100644
--- a/include/mach/socfpga/debug_ll.h
+++ b/include/mach/socfpga/debug_ll.h
@@ -30,6 +30,26 @@
#define SCR 0x1c
#define THR 0x30
+static inline void socfpga_gen5_uart_putc(void *base, int c)
+{
+ /* Wait until there is space in the FIFO */
+ while ((readb(base + LSR) & LSR_THRE) == 0);
+ /* Send the character */
+ writeb(c, base + THR);
+ /* Wait to make sure it hits the line, in case we die too soon. */
+ while ((readb(base + LSR) & LSR_THRE) == 0);
+}
+
+static inline void socfpga_uart_putc(void *base, int c)
+{
+ /* Wait until there is space in the FIFO */
+ while ((readl(base + LSR) & LSR_THRE) == 0);
+ /* Send the character */
+ writel(c, base + THR);
+ /* Wait to make sure it hits the line, in case we die too soon. */
+ while ((readl(base + LSR) & LSR_THRE) == 0);
+}
+
#ifdef CONFIG_DEBUG_LL
static inline unsigned int ns16550_calc_divisor(unsigned int clk,
unsigned int baudrate)
@@ -37,7 +57,7 @@ static inline unsigned int ns16550_calc_divisor(unsigned int clk,
return (clk / 16 / baudrate);
}
-static inline void INIT_LL(void)
+static inline void socfpga_uart_setup_ll(void)
{
unsigned int div = ns16550_calc_divisor(CONFIG_DEBUG_SOCFPGA_UART_CLOCK,
115200);
@@ -53,25 +73,19 @@ static inline void INIT_LL(void)
writel(FCRVAL, UART_BASE + FCR);
}
-#ifdef CONFIG_ARCH_SOCFPGA_ARRIA10
+#if defined(CONFIG_ARCH_SOCFPGA_CYCLONE5)
static inline void PUTC_LL(char c)
{
- /* Wait until there is space in the FIFO */
- while ((readl(UART_BASE + LSR) & LSR_THRE) == 0);
- /* Send the character */
- writel(c, UART_BASE + THR);
- /* Wait to make sure it hits the line, in case we die too soon. */
- while ((readl(UART_BASE + LSR) & LSR_THRE) == 0);
+ void __iomem *base = IOMEM(UART_BASE);
+
+ socfpga_gen5_uart_putc(base, c);
}
#else
static inline void PUTC_LL(char c)
{
- /* Wait until there is space in the FIFO */
- while ((readb(UART_BASE + LSR) & LSR_THRE) == 0);
- /* Send the character */
- writeb(c, UART_BASE + THR);
- /* Wait to make sure it hits the line, in case we die too soon. */
- while ((readb(UART_BASE + LSR) & LSR_THRE) == 0);
+ void __iomem *base = IOMEM(UART_BASE);
+
+ socfpga_uart_putc(base, c);
}
#endif
@@ -80,7 +94,7 @@ static inline unsigned int ns16550_calc_divisor(unsigned int clk,
unsigned int baudrate) {
return -ENOSYS;
}
-static inline void INIT_LL(void) {}
+static inline void socfpga_uart_setup_ll(void) {}
static inline void PUTC_LL(char c) {}
#endif
#endif /* __MACH_SOCFPGA_DEBUG_LL_H__ */
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 03/10] reset: reset-socfpga: build only for 32-bit socfpga
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 01/10] ARM: socfpga: kconfig: sort entries Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 02/10] mach: socfpga: debug_ll: rework putc_ll Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 04/10] arm: socfgpa: add support for SoCFPGA Agilex5 Steffen Trumtrar
` (6 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
The 64-bit SoCFPGA platforms will use reset-simple.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/reset/Kconfig | 6 ++++++
drivers/reset/Makefile | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig
index 16c05d50f0e30cb93609c6fbaa4287975894509a..c3779f087490f57deeabf2178723983a87d0446c 100644
--- a/drivers/reset/Kconfig
+++ b/drivers/reset/Kconfig
@@ -57,4 +57,10 @@ config RESET_SCMI
This driver uses SCMI Message Protocol to interact with the
firmware controlling all the reset signals.
+config RESET_SOCFPGA32
+ bool "SoCFPGA 32-bit Reset Driver"
+ default ARCH_SOCFPGA && 32BIT
+ help
+ This enables the reset controller driver for 32-bit SoCFPGA platforms.
+
endif
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile
index b1668433d76af89a49ef577ad9d0cdc4af48de8d..a446cb20d0b7ddb6404fdf385498bdf6a076e34e 100644
--- a/drivers/reset/Makefile
+++ b/drivers/reset/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-$(CONFIG_RESET_CONTROLLER) += core.o
obj-$(CONFIG_RESET_SIMPLE) += reset-simple.o
-obj-$(CONFIG_ARCH_SOCFPGA) += reset-socfpga.o
+obj-$(CONFIG_RESET_SOCFPGA32) += reset-socfpga.o
obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
obj-$(CONFIG_RESET_STARFIVE) += reset-starfive-vic.o
obj-$(CONFIG_RESET_SCMI) += reset-scmi.o
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 04/10] arm: socfgpa: add support for SoCFPGA Agilex5
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (2 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 03/10] reset: reset-socfpga: build only for 32-bit socfpga Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-11-04 10:31 ` Sascha Hauer
2024-10-29 8:42 ` [PATCH 05/10] ARM: socfpga: add Arrow AXE5 Agilex5 board Steffen Trumtrar
` (5 subsequent siblings)
9 siblings, 1 reply; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Add initial support for the Intel Agilex5 SoCFPGA platform.
The Agilex5 devices have:
- Quad-core cluster consisting of Dual-core 64-bit Arm Cortex-A76, and dual-core 64-bit Arm Cortex-A55 (SoC only)
- High-Speed transceivers, up to 17.1 Gbps (group B) and 28.1 Gbps (group A)
- PCIe Gen4 x4
- DDR4/LPDDR4/LPDDR5, and DDR5 (group A)
- Native MIPI CSI-2 and D-PHY (multiple channels)
- Secure Device Manager (SDM) to support secure configuration and tamper prevention, and hardened cryptographic engines
(from https://www.rocketboards.org/foswiki/Documentation/ArrowAXE5EagleDevelopmentKit)
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm/Kconfig | 3 -
arch/arm/dts/socfpga_agilex5.dtsi | 71 ++++
arch/arm/mach-socfpga/Kconfig | 37 +-
arch/arm/mach-socfpga/Makefile | 13 +
arch/arm/mach-socfpga/agilex5-clock-manager.c | 411 +++++++++++++++++++
arch/arm/mach-socfpga/agilex5-sdram.c | 352 ++++++++++++++++
arch/arm/mach-socfpga/agilex5-secreg.c | 289 ++++++++++++++
arch/arm/mach-socfpga/atf.c | 34 ++
arch/arm/mach-socfpga/cpu_init.c | 43 ++
arch/arm/mach-socfpga/iossm_mailbox.c | 551 ++++++++++++++++++++++++++
arch/arm/mach-socfpga/iossm_mailbox.h | 152 +++++++
arch/arm/mach-socfpga/mailbox_s10.c | 407 +++++++++++++++++++
arch/arm/mach-socfpga/secure_reg_helper.c | 75 ++++
arch/arm/mach-socfpga/smc_api.c | 43 ++
arch/arm/mach-socfpga/soc64-system-manager.c | 102 +++++
arch/arm/mach-socfpga/soc64-wrap-handoff.c | 124 ++++++
common/Kconfig.debug_ll | 17 +
firmware/Kconfig | 3 +
firmware/Makefile | 1 +
images/Makefile.socfpga | 8 +
include/dt-bindings/clock/agilex5-clock.h | 71 ++++
include/linux/intel-smc.h | 545 +++++++++++++++++++++++++
include/mach/socfpga/agilex5-clk.h | 266 +++++++++++++
include/mach/socfpga/atf.h | 14 +
include/mach/socfpga/generic.h | 3 +
include/mach/socfpga/init.h | 2 +
include/mach/socfpga/mailbox_s10.h | 199 ++++++++++
include/mach/socfpga/secure_reg_helper.h | 19 +
include/mach/socfpga/smc_api.h | 12 +
include/mach/socfpga/soc64-firewall.h | 177 +++++++++
include/mach/socfpga/soc64-handoff.h | 50 +++
include/mach/socfpga/soc64-init.h | 4 +
include/mach/socfpga/soc64-regs.h | 195 +++++++++
include/mach/socfpga/soc64-reset-manager.h | 40 ++
include/mach/socfpga/soc64-sdram.h | 203 ++++++++++
include/mach/socfpga/soc64-system-manager.h | 176 ++++++++
36 files changed, 4705 insertions(+), 7 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 9b90c8009a352cb3f572e6e92a7b7571c94dad4d..6a8fd6d4973b0a8149f781eed493896bf3abed1a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -103,10 +103,7 @@ config ARCH_PXA
config ARCH_SOCFPGA
bool "Altera SOCFPGA"
- depends on 32BIT
select HAS_DEBUG_LL
- select ARM_SMP_TWD
- select CPU_V7
select COMMON_CLK
config ARCH_TEGRA
diff --git a/arch/arm/dts/socfpga_agilex5.dtsi b/arch/arm/dts/socfpga_agilex5.dtsi
new file mode 100644
index 0000000000000000000000000000000000000000..24bebf7c3a951acaad03c9b43e14735a5923ca04
--- /dev/null
+++ b/arch/arm/dts/socfpga_agilex5.dtsi
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019-2023 Intel Corporation <www.intel.com>
+ */
+
+&soc {
+ gmac0: ethernet@10810000 {
+ compatible = "intel,socfpga-dwxgmac", "snps,dwxgmac-2.10", "snps,dwxgmac";
+ reg = <0x10810000 0x3500>;
+ interrupts = <0 190 4>;
+ interrupt-names = "macirq";
+ resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>;
+ reset-names = "stmmaceth", "stmmaceth-ocp";
+ tx-fifo-depth = <32768>;
+ rx-fifo-depth = <16384>;
+ altr,sysmgr-syscon = <&sysmgr 0x44 0>;
+ clocks = <&clkmgr AGILEX5_EMAC0_CLK>;
+ clock-names = "stmmaceth";
+ status = "disabled";
+ };
+
+ gmac1: ethernet@10820000 {
+ compatible = "intel,socfpga-dwxgmac", "snps,dwxgmac-2.10", "snps,dwxgmac";
+ reg = <0x10820000 0x3500>;
+ interrupts = <0 207 4>;
+ interrupt-names = "macirq";
+ resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>;
+ reset-names = "stmmaceth", "stmmaceth-ocp";
+ tx-fifo-depth = <32768>;
+ rx-fifo-depth = <16384>;
+ altr,sysmgr-syscon = <&sysmgr 0x48 0>;
+ clocks = <&clkmgr AGILEX5_EMAC1_CLK>;
+ clock-names = "stmmaceth";
+ status = "disabled";
+ };
+
+ gmac2: ethernet@10830000 {
+ compatible = "intel,socfpga-dwxgmac", "snps,dwxgmac-2.10", "snps,dwxgmac";
+ reg = <0x10830000 0x3500>;
+ interrupts = <0 224 4>;
+ interrupt-names = "macirq";
+ resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>;
+ reset-names = "stmmaceth", "stmmaceth-ocp";
+ tx-fifo-depth = <32768>;
+ rx-fifo-depth = <16384>;
+ altr,sysmgr-syscon = <&sysmgr 0x4c 0>;
+ clocks = <&clkmgr AGILEX5_EMAC2_CLK>;
+ clock-names = "stmmaceth";
+ status = "disabled";
+ };
+
+ gpio0: gpio@10c03200 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x10c03200 0x100>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ resets = <&rst GPIO0_RESET>;
+ status = "disabled";
+
+ porta: gpio-controller@0 {
+ compatible = "snps,dw-apb-gpio-port";
+ reg = <0>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <24>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+};
diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 80a15377b2e4be4d1386904a298a9aadcffbab00..f0dce3bad0429d38840975a2f3c3640731e7a605 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -4,13 +4,17 @@ if ARCH_SOCFPGA
config ARCH_SOCFPGA_XLOAD
bool
- prompt "Build preloader image"
+ depends on ARCH_SOCFPGA_CYCLONE5
+ prompt "Build SoCFPGA preloader image"
-comment "Altera SoCFPGA System-on-Chip"
+menu "SoCFPGA boards"
+
+if 32BIT
config ARCH_SOCFPGA_CYCLONE5
bool
select CPU_V7
+ select ARM_SMP_TWD
select OFDEVICE if !ARCH_SOCFPGA_XLOAD
select OFTREE if !ARCH_SOCFPGA_XLOAD
select GPIOLIB if !ARCH_SOCFPGA_XLOAD
@@ -18,13 +22,12 @@ config ARCH_SOCFPGA_CYCLONE5
config ARCH_SOCFPGA_ARRIA10
bool
select CPU_V7
+ select ARM_SMP_TWD
select ARM_USE_COMPRESSED_DTB
select RESET_CONTROLLER
select OFDEVICE
select OFTREE
-if 32BIT
-
comment "Cyclone5 boards"
config MACH_SOCFPGA_ALTERA_SOCDK
@@ -58,4 +61,30 @@ config MACH_SOCFPGA_REFLEX_ACHILLES
bool "Reflex Achilles"
endif
+
+if 64BIT
+
+config ARCH_SOCFPGA_AGILEX5
+ bool
+ select CPU_V8
+ select ARM_USE_COMPRESSED_DTB
+ select RESET_CONTROLLER
+ select RESET_SIMPLE
+ select OFDEVICE
+ select OFTREE
+ select FIRMWARE_AGILEX5_ATF
+ select ARM_ATF
+ select ARM_SMCCC
+
+
+comment "SoCFPGA Agilex5 boards"
+
+config MACH_SOCFPGA_ARROW_AXE5_EAGLE
+ bool "Arrow AXE5 Eagle"
+ select ARCH_SOCFPGA_AGILEX5
+
+endif
+
+endmenu
+
endif
diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
index 008dbc38877211fe1f317cb8eb660d8514611ddd..81934a3ded7fe6dcfb4c8ac26473a25a96560863 100644
--- a/arch/arm/mach-socfpga/Makefile
+++ b/arch/arm/mach-socfpga/Makefile
@@ -14,6 +14,19 @@ obj-pbl-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += arria10-bootsource.o \
arria10-init.o \
arria10-sdram.o
+pbl-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += soc64-system-manager.o \
+ soc64-wrap-handoff.o \
+ iossm_mailbox.o \
+ mailbox_s10.o \
+ agilex5-sdram.o \
+ agilex5-secreg.o \
+ agilex5-clock-manager.o \
+ atf.o
+
+obj-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += secure_reg_helper.o \
+ mailbox_s10.o \
+ smc_api.o
+
ifdef CONFIG_ARCH_SOCFPGA_CYCLONE5
obj-$(CONFIG_ARCH_SOCFPGA_XLOAD) += xload.o
endif
diff --git a/arch/arm/mach-socfpga/agilex5-clock-manager.c b/arch/arm/mach-socfpga/agilex5-clock-manager.c
new file mode 100644
index 0000000000000000000000000000000000000000..2d5c742644396cad627643c2a4b422fecbf0eeac
--- /dev/null
+++ b/arch/arm/mach-socfpga/agilex5-clock-manager.c
@@ -0,0 +1,411 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019-2023 Intel Corporation <www.intel.com>
+ */
+
+#include <common.h>
+#include <io.h>
+#include <asm/system.h>
+#include <dt-bindings/clock/agilex5-clock.h>
+#include <linux/bitops.h>
+#include <clock.h>
+#include <mach/socfpga/agilex5-clk.h>
+#include <mach/socfpga/generic.h>
+#include <mach/socfpga/soc64-handoff.h>
+#include <mach/socfpga/soc64-regs.h>
+
+#define MPIDR_AFF1_OFFSET 8
+#define MPIDR_AFF1_MASK 0x3
+#define CORE0 1
+#define CORE1 2
+#define CORE2 3
+#define CORE3 4
+
+/* Derived from l4_main_clk (PSS clock) */
+#define COUNTER_FREQUENCY_REAL 400000000
+
+struct socfpga_clk_plat {
+ void __iomem *regs;
+};
+
+static void cm_wait_for_lock(u32 mask)
+{
+ u32 inter_val;
+ u32 retry = 0;
+
+ do {
+ inter_val = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_STAT) & mask;
+ /* Wait for stable lock */
+ if (inter_val == mask)
+ retry++;
+ else
+ retry = 0;
+ if (retry >= 10)
+ break;
+ } while (1);
+}
+
+/* function to poll in the fsm busy bit */
+static void cm_wait_for_fsm(void)
+{
+ register u32 inter_val;
+
+ do {
+ inter_val = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_STAT) &
+ CLKMGR_STAT_BUSY;
+ } while (inter_val);
+}
+
+/*
+ * function to write the bypass register which requires a poll of the
+ * busy bit
+ */
+static void clk_write_bypass_mainpll(struct socfpga_clk_plat *plat, u32 val)
+{
+ CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_BYPASS);
+ cm_wait_for_fsm();
+}
+
+static void clk_write_bypass_perpll(struct socfpga_clk_plat *plat, u32 val)
+{
+ CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_BYPASS);
+ cm_wait_for_fsm();
+}
+
+/* function to write the ctrl register which requires a poll of the busy bit */
+static void clk_write_ctrl(struct socfpga_clk_plat *plat, u32 val)
+{
+ CM_REG_WRITEL(plat, val, CLKMGR_CTRL);
+ cm_wait_for_fsm();
+}
+
+#define MEMBUS_MAINPLL 0
+#define MEMBUS_PERPLL 1
+#define MEMBUS_TIMEOUT 1000
+
+#define MEMBUS_CLKSLICE_REG 0x27
+#define MEMBUS_SYNTHCALFOSC_INIT_CENTERFREQ_REG 0xb3
+#define MEMBUS_SYNTHPPM_WATCHDOGTMR_VF01_REG 0xe6
+#define MEMBUS_CALCLKSLICE0_DUTY_LOCOVR_REG 0x03
+#define MEMBUS_CALCLKSLICE1_DUTY_LOCOVR_REG 0x07
+
+static const struct {
+ u32 reg;
+ u32 val;
+ u32 mask;
+} membus_pll[] = {
+ {
+ MEMBUS_CLKSLICE_REG,
+ /*
+ * BIT[7:7]
+ * Enable source synchronous mode
+ */
+ BIT(7),
+ BIT(7)
+ },
+ {
+ MEMBUS_SYNTHCALFOSC_INIT_CENTERFREQ_REG,
+ /*
+ * BIT[0:0]
+ * Sets synthcalfosc_init_centerfreq=1 to limit overshoot
+ * frequency during lock
+ */
+ BIT(0),
+ BIT(0)
+ },
+ {
+ MEMBUS_SYNTHPPM_WATCHDOGTMR_VF01_REG,
+ /*
+ * BIT[0:0]
+ * Sets synthppm_watchdogtmr_vf0=1 to give the pll more time
+ * to settle before lock is asserted.
+ */
+ BIT(0),
+ BIT(0)
+ },
+ {
+ MEMBUS_CALCLKSLICE0_DUTY_LOCOVR_REG,
+ /*
+ * BIT[6:0]
+ * Centering duty cycle for clkslice0 output
+ */
+ 0x4a,
+ GENMASK(6, 0)
+ },
+ {
+ MEMBUS_CALCLKSLICE1_DUTY_LOCOVR_REG,
+ /*
+ * BIT[6:0]
+ * Centering duty cycle for clkslice1 output
+ */
+ 0x4a,
+ GENMASK(6, 0)
+ },
+};
+
+static int membus_wait_for_req(struct socfpga_clk_plat *plat, u32 pll,
+ int timeout)
+{
+ int cnt = 0;
+ u32 req_status;
+
+ if (pll == MEMBUS_MAINPLL)
+ req_status = CM_REG_READL(plat, CLKMGR_MAINPLL_MEM);
+ else
+ req_status = CM_REG_READL(plat, CLKMGR_PERPLL_MEM);
+
+ while ((cnt < timeout) && (req_status & CLKMGR_MEM_REQ_SET_MSK)) {
+ if (pll == MEMBUS_MAINPLL)
+ req_status = CM_REG_READL(plat, CLKMGR_MAINPLL_MEM);
+ else
+ req_status = CM_REG_READL(plat, CLKMGR_PERPLL_MEM);
+ cnt++;
+ }
+
+ if (cnt >= timeout)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+static int membus_write_pll(struct socfpga_clk_plat *plat, u32 pll,
+ u32 addr_offset, u32 wdat, int timeout)
+{
+ u32 addr;
+ u32 val;
+
+ addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+
+ val = (CLKMGR_MEM_REQ_SET_MSK | CLKMGR_MEM_WR_SET_MSK |
+ (wdat << CLKMGR_MEM_WDAT_LSB_OFFSET) | addr);
+
+ if (pll == MEMBUS_MAINPLL)
+ CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_MEM);
+ else
+ CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_MEM);
+
+ return membus_wait_for_req(plat, pll, timeout);
+}
+
+static int membus_read_pll(struct socfpga_clk_plat *plat, u32 pll,
+ u32 addr_offset, u32 *rdata, int timeout)
+{
+ u32 addr;
+ u32 val;
+
+ addr = ((addr_offset | CLKMGR_MEM_ADDR_START) & CLKMGR_MEM_ADDR_MASK);
+
+ val = ((CLKMGR_MEM_REQ_SET_MSK & ~CLKMGR_MEM_WR_SET_MSK) | addr);
+
+ if (pll == MEMBUS_MAINPLL)
+ CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_MEM);
+ else
+ CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_MEM);
+
+ *rdata = 0;
+
+ if (membus_wait_for_req(plat, pll, timeout))
+ return -ETIMEDOUT;
+
+ if (pll == MEMBUS_MAINPLL)
+ *rdata = CM_REG_READL(plat, CLKMGR_MAINPLL_MEMSTAT);
+ else
+ *rdata = CM_REG_READL(plat, CLKMGR_PERPLL_MEMSTAT);
+
+ return 0;
+}
+
+static void membus_pll_configs(struct socfpga_clk_plat *plat, u32 pll)
+{
+ int i;
+ u32 rdata;
+
+ for (i = 0; i < ARRAY_SIZE(membus_pll); i++) {
+ membus_read_pll(plat, pll, membus_pll[i].reg,
+ &rdata, MEMBUS_TIMEOUT);
+ membus_write_pll(plat, pll, membus_pll[i].reg,
+ ((rdata & ~membus_pll[i].mask) | membus_pll[i].val),
+ MEMBUS_TIMEOUT);
+ }
+}
+
+static u32 calc_vocalib_pll(u32 pllm, u32 pllglob)
+{
+ u32 mdiv, refclkdiv, arefclkdiv, drefclkdiv, mscnt, hscnt, vcocalib;
+
+ mdiv = pllm & CLKMGR_PLLM_MDIV_MASK;
+ arefclkdiv = (pllglob & CLKMGR_PLLGLOB_AREFCLKDIV_MASK) >>
+ CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET;
+ drefclkdiv = (pllglob & CLKMGR_PLLGLOB_DREFCLKDIV_MASK) >>
+ CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET;
+ refclkdiv = (pllglob & CLKMGR_PLLGLOB_REFCLKDIV_MASK) >>
+ CLKMGR_PLLGLOB_REFCLKDIV_OFFSET;
+ mscnt = CLKMGR_VCOCALIB_MSCNT_CONST / (mdiv * BIT(drefclkdiv));
+ if (!mscnt)
+ mscnt = 1;
+ hscnt = (mdiv * mscnt * BIT(drefclkdiv) / refclkdiv) -
+ CLKMGR_VCOCALIB_HSCNT_CONST;
+ vcocalib = (hscnt & CLKMGR_VCOCALIB_HSCNT_MASK) |
+ ((mscnt << CLKMGR_VCOCALIB_MSCNT_OFFSET) &
+ CLKMGR_VCOCALIB_MSCNT_MASK);
+
+ return vcocalib;
+}
+
+/*
+ * Setup clocks while making no assumptions about previous state of the clocks.
+ */
+static void clk_basic_init(struct socfpga_clk_plat *plat,
+ const struct cm_config * const cfg)
+{
+ u32 vcocalib;
+ u32 cntfrq = COUNTER_FREQUENCY_REAL;
+ u32 counter_freq = 0;
+
+
+ if (!cfg)
+ return;
+
+ /* Always force clock manager into boot mode before any configuration */
+ clk_write_ctrl(plat,
+ CM_REG_READL(plat, CLKMGR_CTRL) | CLKMGR_CTRL_BOOTMODE);
+
+ /* Put both PLLs in bypass */
+ clk_write_bypass_mainpll(plat, CLKMGR_BYPASS_MAINPLL_ALL);
+ clk_write_bypass_perpll(plat, CLKMGR_BYPASS_PERPLL_ALL);
+
+ /* Put both PLLs in Reset and Power Down */
+ CM_REG_CLRBITS(plat, CLKMGR_MAINPLL_PLLGLOB,
+ CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
+ CM_REG_CLRBITS(plat, CLKMGR_PERPLL_PLLGLOB,
+ CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
+
+ /* setup main PLL dividers where calculate the vcocalib value */
+ vcocalib = calc_vocalib_pll(cfg->main_pll_pllm, cfg->main_pll_pllglob);
+ CM_REG_WRITEL(plat, cfg->main_pll_pllglob & ~CLKMGR_PLLGLOB_RST_MASK,
+ CLKMGR_MAINPLL_PLLGLOB);
+ CM_REG_WRITEL(plat, cfg->main_pll_fdbck, CLKMGR_MAINPLL_FDBCK);
+ CM_REG_WRITEL(plat, vcocalib, CLKMGR_MAINPLL_VCOCALIB);
+ CM_REG_WRITEL(plat, cfg->main_pll_pllc0, CLKMGR_MAINPLL_PLLC0);
+ CM_REG_WRITEL(plat, cfg->main_pll_pllc1, CLKMGR_MAINPLL_PLLC1);
+ CM_REG_WRITEL(plat, cfg->main_pll_pllc2, CLKMGR_MAINPLL_PLLC2);
+ CM_REG_WRITEL(plat, cfg->main_pll_pllc3, CLKMGR_MAINPLL_PLLC3);
+ CM_REG_WRITEL(plat, cfg->main_pll_pllm, CLKMGR_MAINPLL_PLLM);
+ CM_REG_WRITEL(plat, cfg->main_pll_nocclk, CLKMGR_MAINPLL_NOCCLK);
+ CM_REG_WRITEL(plat, cfg->main_pll_nocdiv, CLKMGR_MAINPLL_NOCDIV);
+
+ /* setup peripheral PLL dividers where calculate the vcocalib value */
+ vcocalib = calc_vocalib_pll(cfg->per_pll_pllm, cfg->per_pll_pllglob);
+ CM_REG_WRITEL(plat, cfg->per_pll_pllglob & ~CLKMGR_PLLGLOB_RST_MASK,
+ CLKMGR_PERPLL_PLLGLOB);
+ CM_REG_WRITEL(plat, cfg->per_pll_fdbck, CLKMGR_PERPLL_FDBCK);
+ CM_REG_WRITEL(plat, vcocalib, CLKMGR_PERPLL_VCOCALIB);
+ CM_REG_WRITEL(plat, cfg->per_pll_pllc0, CLKMGR_PERPLL_PLLC0);
+ CM_REG_WRITEL(plat, cfg->per_pll_pllc1, CLKMGR_PERPLL_PLLC1);
+ CM_REG_WRITEL(plat, cfg->per_pll_pllc2, CLKMGR_PERPLL_PLLC2);
+ CM_REG_WRITEL(plat, cfg->per_pll_pllc3, CLKMGR_PERPLL_PLLC3);
+ CM_REG_WRITEL(plat, cfg->per_pll_pllm, CLKMGR_PERPLL_PLLM);
+ CM_REG_WRITEL(plat, cfg->per_pll_emacctl, CLKMGR_PERPLL_EMACCTL);
+ CM_REG_WRITEL(plat, cfg->per_pll_gpiodiv, CLKMGR_PERPLL_GPIODIV);
+
+ /* Configure ping pong counters in control group */
+ CM_REG_WRITEL(plat, cfg->ctl_emacactr, CLKMGR_CTL_EMACACTR);
+ CM_REG_WRITEL(plat, cfg->ctl_emacbctr, CLKMGR_CTL_EMACBCTR);
+ CM_REG_WRITEL(plat, cfg->ctl_emacptpctr, CLKMGR_CTL_EMACPTPCTR);
+ CM_REG_WRITEL(plat, cfg->ctl_gpiodbctr, CLKMGR_CTL_GPIODBCTR);
+ CM_REG_WRITEL(plat, cfg->ctl_s2fuser0ctr, CLKMGR_CTL_S2FUSER0CTR);
+ CM_REG_WRITEL(plat, cfg->ctl_s2fuser1ctr, CLKMGR_CTL_S2FUSER1CTR);
+ CM_REG_WRITEL(plat, cfg->ctl_psirefctr, CLKMGR_CTL_PSIREFCTR);
+ CM_REG_WRITEL(plat, cfg->ctl_usb31ctr, CLKMGR_CTL_USB31CTR);
+ CM_REG_WRITEL(plat, cfg->ctl_dsuctr, CLKMGR_CTL_DSUCTR);
+ CM_REG_WRITEL(plat, cfg->ctl_core01ctr, CLKMGR_CTL_CORE01CTR);
+ CM_REG_WRITEL(plat, cfg->ctl_core23ctr, CLKMGR_CTL_CORE23CTR);
+ CM_REG_WRITEL(plat, cfg->ctl_core2ctr, CLKMGR_CTL_CORE2CTR);
+ CM_REG_WRITEL(plat, cfg->ctl_core3ctr, CLKMGR_CTL_CORE3CTR);
+
+ /* Take both PLL out of reset and power up */
+ CM_REG_SETBITS(plat, CLKMGR_MAINPLL_PLLGLOB,
+ CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
+ CM_REG_SETBITS(plat, CLKMGR_PERPLL_PLLGLOB,
+ CLKMGR_PLLGLOB_PD_MASK | CLKMGR_PLLGLOB_RST_MASK);
+
+ /* Membus programming for mainpll */
+ membus_pll_configs(plat, MEMBUS_MAINPLL);
+ /* Membus programming for peripll */
+ membus_pll_configs(plat, MEMBUS_PERPLL);
+
+ /* Enable Main pll clkslices */
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC0) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_MAINPLL_PLLC0);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC1) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_MAINPLL_PLLC1);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC2) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_MAINPLL_PLLC2);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLC3) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_MAINPLL_PLLC3);
+
+ /* Enable Periph pll clkslices */
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC0) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_PERPLL_PLLC0);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC1) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_PERPLL_PLLC1);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC2) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_PERPLL_PLLC2);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC3) |
+ CLKMGR_PLLCX_EN_SET_MSK,
+ CLKMGR_PERPLL_PLLC3);
+
+ cm_wait_for_lock(CLKMGR_STAT_ALLPLL_LOCKED_MASK);
+
+ CM_REG_WRITEL(plat, CLKMGR_LOSTLOCK_SET_MASK, CLKMGR_MAINPLL_LOSTLOCK);
+ CM_REG_WRITEL(plat, CLKMGR_LOSTLOCK_SET_MASK, CLKMGR_PERPLL_LOSTLOCK);
+
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLGLOB) |
+ CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
+ CLKMGR_MAINPLL_PLLGLOB);
+ CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLGLOB) |
+ CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
+ CLKMGR_PERPLL_PLLGLOB);
+
+ /* Take all PLLs out of bypass */
+ clk_write_bypass_mainpll(plat, 0);
+ clk_write_bypass_perpll(plat, 0);
+
+ /* Clear the loss of lock bits (write 1 to clear) */
+ CM_REG_CLRBITS(plat, CLKMGR_INTRCLR,
+ CLKMGR_INTER_PERPLLLOST_MASK |
+ CLKMGR_INTER_MAINPLLLOST_MASK);
+
+ /* Take all ping pong counters out of reset */
+ CM_REG_CLRBITS(plat, CLKMGR_CTL_EXTCNTRST,
+ CLKMGR_CTL_EXTCNTRST_ALLCNTRST);
+
+ /* Update with accurate clock frequency */
+ if (current_el() == 3) {
+ asm volatile("msr cntfrq_el0, %0" : : "r" (cntfrq) : "memory");
+ asm volatile("mrs %0, cntfrq_el0" : "=r" (counter_freq));
+ }
+
+ /* Out of boot mode */
+ clk_write_ctrl(plat, CM_REG_READL(plat, CLKMGR_CTRL) &
+ ~CLKMGR_CTRL_BOOTMODE);
+}
+
+int agilex5_clk_init(void)
+{
+ struct socfpga_clk_plat plat;
+ const struct cm_config *cm_default_cfg = cm_get_default_config();
+
+ plat.regs = (void __iomem *)SOCFPGA_CLKMGR_ADDRESS;
+
+ clk_basic_init(&plat, cm_default_cfg);
+
+ return 0;
+}
diff --git a/arch/arm/mach-socfpga/agilex5-sdram.c b/arch/arm/mach-socfpga/agilex5-sdram.c
new file mode 100644
index 0000000000000000000000000000000000000000..4e1b03f400add0ebeab038716b1c02e8a228f237
--- /dev/null
+++ b/arch/arm/mach-socfpga/agilex5-sdram.c
@@ -0,0 +1,352 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019-2024 Intel Corporation <www.intel.com>
+ *
+ */
+#include <common.h>
+#include <errno.h>
+#include "iossm_mailbox.h"
+#include <xfuncs.h>
+#include <linux/sizes.h>
+#include <linux/bitfield.h>
+#include <mach/socfpga/soc64-firewall.h>
+#include <mach/socfpga/soc64-handoff.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-sdram.h>
+#include <mach/socfpga/soc64-system-manager.h>
+
+/* MPFE NOC registers */
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0 0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTSTATUS0 0x58
+#define SIDEBANDMGR_FLAGOUTSET0_REG SOCFPGA_F2SDRAM_MGR_ADDRESS +\
+ F2SDRAM_SIDEBAND_FLAGOUTSET0
+#define SIDEBANDMGR_FLAGOUTSTATUS0_REG SOCFPGA_F2SDRAM_MGR_ADDRESS +\
+ F2SDRAM_SIDEBAND_FLAGOUTSTATUS0
+
+#define PORT_EMIF_CONFIG_OFFSET 4
+
+/* Reset type */
+enum reset_type {
+ POR_RESET,
+ WARM_RESET,
+ COLD_RESET,
+ NCONFIG,
+ JTAG_CONFIG,
+ RSU_RECONFIG
+};
+
+phys_addr_t io96b_csr_reg_addr[] = {
+ 0x18400000, /* IO96B_0 CSR registers address */
+ 0x18800000 /* IO96B_1 CSR registers address */
+};
+
+static enum reset_type get_reset_type(u32 reg)
+{
+ return (reg & ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_MASK) >>
+ ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_SHIFT;
+}
+
+static int set_mpfe_config(void)
+{
+ /* Set mpfe_lite_intfcsel */
+ setbits_le32(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + SYSMGR_SOC64_MPFE_CONFIG, BIT(2));
+
+ /* Set mpfe_lite_active */
+ setbits_le32(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + SYSMGR_SOC64_MPFE_CONFIG, BIT(8));
+
+ pr_debug("%s: mpfe_config: 0x%x\n", __func__,
+ readl(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + SYSMGR_SOC64_MPFE_CONFIG));
+
+ return 0;
+}
+
+static bool is_ddr_init_hang(void)
+{
+ u32 reg = readl(IOMEM(SOCFPGA_SYSMGR_ADDRESS) +
+ SYSMGR_SOC64_BOOT_SCRATCH_POR0);
+
+ if (reg & ALT_SYSMGR_SCRATCH_REG_POR_0_DDR_PROGRESS_MASK)
+ return true;
+
+ return false;
+}
+
+static void ddr_init_inprogress(bool start)
+{
+ if (start)
+ setbits_le32(IOMEM(SOCFPGA_SYSMGR_ADDRESS) +
+ SYSMGR_SOC64_BOOT_SCRATCH_POR0,
+ ALT_SYSMGR_SCRATCH_REG_POR_0_DDR_PROGRESS_MASK);
+ else
+ clrbits_le32(IOMEM(SOCFPGA_SYSMGR_ADDRESS) +
+ SYSMGR_SOC64_BOOT_SCRATCH_POR0,
+ ALT_SYSMGR_SCRATCH_REG_POR_0_DDR_PROGRESS_MASK);
+}
+
+static int populate_ddr_handoff(struct altera_sdram_plat *plat, struct io96b_info *io96b_ctrl)
+{
+ int i;
+ u32 len = SOC64_HANDOFF_SDRAM_LEN;
+ u32 handoff_table[len];
+
+ /* Read handoff for DDR configuration */
+ socfpga_handoff_read((void *)SOC64_HANDOFF_SDRAM, handoff_table, len);
+
+ /* Read handoff - dual port
+ FIXME: Intel u-boot has a patch that HACKs this to 0
+ https://github.com/altera-opensource/meta-intel-fpga-refdes/ \
+ blob/master/recipes-bsp/u-boot/files/v1-0001-HSD-15015933655-ddr-altera-agilex5-Hack-dual-port-DO-NOT-MERGE.patch
+ Patch doesn't say why or what is broken here: handoff files? dualport RAM access?
+ */
+ //plat->dualport = FIELD_GET(BIT(0), handoff_table[PORT_EMIF_CONFIG_OFFSET]);
+ plat->dualport = 0;
+ pr_debug("%s: dualport from handoff: 0x%x\n", __func__, plat->dualport);
+
+ if (plat->dualport)
+ io96b_ctrl->num_port = 2;
+ else
+ io96b_ctrl->num_port = 1;
+
+ /* Read handoff - dual EMIF */
+ plat->dualemif = FIELD_GET(BIT(1), handoff_table[PORT_EMIF_CONFIG_OFFSET]);
+ pr_debug("%s: dualemif from handoff: 0x%x\n", __func__, plat->dualemif);
+
+ if (plat->dualemif)
+ io96b_ctrl->num_instance = 2;
+ else
+ io96b_ctrl->num_instance = 1;
+
+ /* Assign IO96B CSR base address if it is valid */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ io96b_ctrl->io96b[i].io96b_csr_addr = io96b_csr_reg_addr[i];
+ pr_debug("%s: IO96B 0x%llx CSR enabled\n", __func__
+ , io96b_ctrl->io96b[i].io96b_csr_addr);
+ }
+
+ return 0;
+}
+
+static int config_mpfe_sideband_mgr(struct altera_sdram_plat *plat)
+{
+ /* Dual port setting */
+ if (plat->dualport)
+ setbits_le32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(4));
+
+ /* Dual EMIF setting */
+ if (plat->dualemif) {
+ set_mpfe_config();
+ setbits_le32(SIDEBANDMGR_FLAGOUTSET0_REG, BIT(5));
+ }
+
+ pr_debug("%s: SIDEBANDMGR_FLAGOUTSTATUS0: 0x%x\n", __func__,
+ readl(SIDEBANDMGR_FLAGOUTSTATUS0_REG));
+
+ return 0;
+}
+
+static void config_ccu_mgr(struct altera_sdram_plat *plat)
+{
+ int ret = 0;
+
+ if (plat->dualport || plat->dualemif) {
+ pr_debug("%s: config interleaving on ccu reg\n", __func__);
+ agilex5_security_interleaving_on();
+ } else {
+ pr_debug("%s: config interleaving off ccu reg\n", __func__);
+ agilex5_security_interleaving_off();
+ }
+
+ if (ret) {
+ printf("interleaving on/off ccu settings init failed: %d\n", ret);
+ hang();
+ }
+}
+
+static bool hps_ocram_dbe_status(void)
+{
+ u32 reg = readl(IOMEM(SOCFPGA_SYSMGR_ADDRESS) +
+ SYSMGR_SOC64_BOOT_SCRATCH_COLD3);
+
+ if (reg & ALT_SYSMGR_SCRATCH_REG_3_OCRAM_DBE_MASK)
+ return true;
+
+ return false;
+}
+
+static bool ddr_ecc_dbe_status(void)
+{
+ u32 reg = readl(IOMEM(SOCFPGA_SYSMGR_ADDRESS) +
+ SYSMGR_SOC64_BOOT_SCRATCH_COLD3);
+
+ if (reg & ALT_SYSMGR_SCRATCH_REG_3_DDR_DBE_MASK)
+ return true;
+
+ return false;
+}
+
+static void sdram_set_firewall(phys_size_t hw_size)
+{
+ phys_size_t value;
+ u32 lower, upper;
+
+ value = SOCFPGA_AGILEX5_DDR_BASE;
+ /* Keep first 1MB of SDRAM memory region as secure region when
+ * using ATF flow, where the ATF code is located.
+ */
+ value += SZ_1M;
+
+ /* Setting non-secure MPU region base and base extended */
+ lower = lower_32_bits(value);
+ upper = upper_32_bits(value);
+ FW_MPU_DDR_SCR_WRITEL(lower, FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE);
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff, FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT);
+ FW_F2SDRAM_DDR_SCR_WRITEL(lower, FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE);
+ FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff, FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT);
+
+ /* Setting non-secure Non-MPU region base and base extended */
+ FW_MPU_DDR_SCR_WRITEL(lower, FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE);
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff, FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT);
+
+ /* Setting non-secure MPU limit and limit extended */
+ value = SOCFPGA_AGILEX5_DDR_BASE + hw_size - 1;
+
+ lower = lower_32_bits(value);
+ upper = upper_32_bits(value);
+
+ FW_MPU_DDR_SCR_WRITEL(lower, FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT);
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff, FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT);
+
+ /* Setting non-secure Non-MPU limit and limit extended */
+ FW_MPU_DDR_SCR_WRITEL(lower, FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT);
+ FW_MPU_DDR_SCR_WRITEL(upper & 0xff, FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT);
+ FW_MPU_DDR_SCR_WRITEL(BIT(0) | BIT(8), FW_MPU_DDR_SCR_EN_SET);
+
+ FW_F2SDRAM_DDR_SCR_WRITEL(lower, FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT);
+ FW_F2SDRAM_DDR_SCR_WRITEL(upper & 0xff, FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT);
+ FW_F2SDRAM_DDR_SCR_WRITEL(BIT(0), FW_F2SDRAM_DDR_SCR_EN_SET);
+}
+
+int agilex5_ddr_init_full(void)
+{
+ int ret;
+ int i;
+ phys_size_t hw_size;
+ struct altera_sdram_plat plat;
+ struct io96b_info io96b_ctrl;
+
+ enum reset_type reset_t = get_reset_type(SOCFPGA_SYSMGR_ADDRESS +
+ SYSMGR_SOC64_BOOT_SCRATCH_COLD3);
+ bool full_mem_init = false;
+
+ /* DDR initialization progress status tracking */
+ bool is_ddr_hang_be4_rst = is_ddr_init_hang();
+
+ pr_debug("DDR: SDRAM init in progress ...\n");
+ ddr_init_inprogress(true);
+
+ plat.mpfe_base_addr = IOMEM(SOCFPGA_MPFE_CSR_ADDRESS);
+
+ pr_debug("DDR: Address MPFE 0x%p\n", plat.mpfe_base_addr);
+
+ /* Populating DDR handoff data */
+ pr_debug("DDR: Checking SDRAM configuration in progress ...\n");
+ ret = populate_ddr_handoff(&plat, &io96b_ctrl);
+ if (ret) {
+ pr_debug("DDR: Failed to populate DDR handoff\n");
+ return ret;
+ }
+
+ /* Configuring MPFE sideband manager registers - dual port & dual emif*/
+ ret = config_mpfe_sideband_mgr(&plat);
+ if (ret) {
+ pr_debug("DDR: Failed to configure dual port dual emif\n");
+ return ret;
+ }
+
+ /* Configuring Interleave/Non-interleave ccu registers */
+ config_ccu_mgr(&plat);
+
+ /* Configure if polling is needed for IO96B GEN PLL locked */
+ io96b_ctrl.ckgen_lock = true;
+
+ /* Ensure calibration status passing */
+ init_mem_cal(&io96b_ctrl);
+
+ /* Initiate IOSSM mailbox */
+ io96b_mb_init(&io96b_ctrl);
+
+ /* Need to trigger re-calibration for DDR DBE */
+ if (ddr_ecc_dbe_status()) {
+ for (i = 0; i < io96b_ctrl.num_instance; i++)
+ io96b_ctrl.io96b[i].cal_status = false;
+
+ io96b_ctrl.overall_cal_status = false;
+ }
+
+ /* Trigger re-calibration if calibration failed */
+ if (!(io96b_ctrl.overall_cal_status)) {
+ pr_debug("DDR: Re-calibration in progress...\n");
+ trig_mem_cal(&io96b_ctrl);
+ }
+
+ pr_debug("DDR: Calibration success\n");
+
+ /* DDR type, DDR size and ECC status) */
+ ret = get_mem_technology(&io96b_ctrl);
+ if (ret) {
+ pr_debug("DDR: Failed to get DDR type\n");
+ return ret;
+ }
+
+ ret = get_mem_width_info(&io96b_ctrl);
+ if (ret) {
+ pr_debug("DDR: Failed to get DDR size\n");
+ return ret;
+ }
+
+ hw_size = (phys_size_t)io96b_ctrl.overall_size * SZ_1G / SZ_8;
+
+ pr_debug("%s: %lld MiB\n", io96b_ctrl.ddr_type, hw_size >> 20);
+
+ ret = ecc_enable_status(&io96b_ctrl);
+ if (ret) {
+ pr_debug("DDR: Failed to get DDR ECC status\n");
+ return ret;
+ }
+
+ /* Is HPS cold or warm reset? If yes, Skip full memory initialization if ECC
+ * enabled to preserve memory content
+ */
+ if (io96b_ctrl.ecc_status) {
+ full_mem_init = hps_ocram_dbe_status() | ddr_ecc_dbe_status() |
+ is_ddr_hang_be4_rst;
+ if (full_mem_init || !(reset_t == WARM_RESET || reset_t == COLD_RESET)) {
+ ret = bist_mem_init_start(&io96b_ctrl);
+ if (ret) {
+ pr_debug("DDR: Failed to fully initialize DDR memory\n");
+ return ret;
+ }
+ }
+
+ pr_debug("SDRAM-ECC: Initialized success\n");
+ }
+
+ sdram_set_firewall(hw_size);
+
+ /* Firewall setting for MPFE CSR */
+ /* IO96B0_reg */
+ writel(0x1, 0x18000d00);
+ /* IO96B1_reg */
+ writel(0x1, 0x18000d04);
+ /* noc_csr */
+ writel(0x1, 0x18000d08);
+
+ pr_debug("DDR: firewall init success\n");
+
+ /* Ending DDR driver initialization success tracking */
+ ddr_init_inprogress(false);
+
+ pr_debug("DDR: init success\n");
+
+ return 0;
+}
diff --git a/arch/arm/mach-socfpga/agilex5-secreg.c b/arch/arm/mach-socfpga/agilex5-secreg.c
new file mode 100644
index 0000000000000000000000000000000000000000..042ba10db71c6fbd4a7d164603d3a3600b9ccc1a
--- /dev/null
+++ b/arch/arm/mach-socfpga/agilex5-secreg.c
@@ -0,0 +1,289 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <common.h>
+#include <io.h>
+#include <mach/socfpga/debug_ll.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-system-manager.h>
+
+#define BUILD_SOC64_WRITE_SECREG(name, addr) \
+ static inline void soc64_write_##name(const int offset, \
+ const int val, \
+ const int mask) \
+ { \
+ void __iomem *iomem = IOMEM(addr); \
+ soc64_set(iomem, offset, val, mask); \
+ }
+
+static inline void soc64_set(void __iomem *addr, int offset, u32 val, int mask)
+{
+ u32 set_mask;
+
+ if (mask == 0xffffffff)
+ writel(val, addr + offset);
+ else {
+ set_mask = mask & val;
+
+ clrsetbits_le32(addr + offset, mask, set_mask);
+ }
+
+ pr_debug("%s: set 0x%p = 0x%08x & 0x%08x\n", __func__,
+ addr + offset, val, mask);
+}
+
+BUILD_SOC64_WRITE_SECREG(ccu, SOCFPGA_CCU_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(dce0, SOCFPGA_DCE0_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(dce1, SOCFPGA_DCE1_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(dmi0, SOCFPGA_DMI0_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(dmi1, SOCFPGA_DMI1_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(fpga2soc, SOCFPGA_FPGA2SOC_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(gic_m, SOCFPGA_GIC_M_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(iom, SOCFPGA_CCU_IOM_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(l4_per, SOCFPGA_FIREWALL_L4_PER_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(l4_sys, SOCFPGA_FIREWALL_L4_SYS_ADDRESS)
+BUILD_SOC64_WRITE_SECREG(tcu, SOCFPGA_TCU_ADDRESS)
+
+void agilex5_security_interleaving_off(void)
+{
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+
+ soc64_write_gic_m(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+
+ soc64_write_tcu(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+
+ soc64_write_iom(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+
+ soc64_write_dce0(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+
+ soc64_write_dce1(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 3, 0x1f);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81300006, 0xc1f03e1f);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81700006, 0xc1f03e1f);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81b00006, 0xc1f03e1f);
+}
+
+void agilex5_security_interleaving_on(void)
+{
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+
+ soc64_write_gic_m(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+
+ soc64_write_tcu(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+
+ soc64_write_iom(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+
+ soc64_write_dce0(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+
+ soc64_write_dce1(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 1, 0x1f);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG, 0x81200006, 0xc1f03e1f);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG, 0x81600006, 0xc1f03e1f);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG, 0x81a00006, 0xc1f03e1f);
+}
+
+void agilex5_initialize_security_policies(void)
+{
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU1AMIGR_REG, 0, 0x07070777);
+ soc64_write_ccu(SOCFPGA_SECREG_DII1_MPFE_LR_REG, 0x18000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_DII1_MPFE_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_DII1_MPFE_BAR_REG, 0xc0e00200, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_CCU_DII2_GIC_LR_REG, 0x1d000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_CCU_DII2_GIC_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_CCU_DII2_GIC_BAR_REG, 0xc0800400, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_LR_REG, 0x20000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_BAR_REG, 0xc1100006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_LR_REG, 0x40000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_BAR_REG, 0xc1200006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_LR_REG, 0x400000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_BAR_REG, 0xc1600006, 0xc1f03e1f);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_LR_REG, 0x4000000, 0xffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_HR_REG, 0, 0xff);
+ soc64_write_ccu(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_BAR_REG, 0x6, 0xf); //
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_ccu(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU1MIFSR_REG, 0, 0x7070777);
+ soc64_write_fpga2soc(SOCFPGA_FPGA2SOC_PSS_LR_REG, 0x10000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_FPGA2SOC_PSS_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_FPGA2SOC_PSS_BAR_REG, 0xc0f00000, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DII1_MPFE_LR_REG, 0x18000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DII1_MPFE_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DII1_MPFE_BAR_REG, 0xc0e00200, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_BAR_REG, 0x20000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_LR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_HR_REG, 0xc1100006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_LR_REG, 0x40000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_BAR_REG, 0xc1200006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_LR_REG, 0x400000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_BAR_REG, 0xc1600006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_LR_REG, 0x4000000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_HR_REG, 0, 0xff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_BAR_REG, 0xc1a00006, 0xc1f03e1f);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_fpga2soc(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+
+ soc64_write_gic_m(SOCFPGA_SECREG_NCAIU1MIFSR_REG, 0, 0x7070777);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_gic_m(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+
+ soc64_write_tcu(SOCFPGA_SECREG_NCAIU1MIFSR_REG, 0, 0x7070777);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_tcu(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+
+ soc64_write_iom(SOCFPGA_SECREG_NCAIU1MIFSR_REG, 0, 0x7070777);
+ soc64_write_iom(SOCFPGA_SECREG_DII1_MPFE_LR_REG, 0x18000, 0xffffffff);
+ soc64_write_iom(SOCFPGA_SECREG_DII1_MPFE_HR_REG, 0, 0xff);
+ soc64_write_iom(SOCFPGA_SECREG_DII1_MPFE_BAR_REG, 0xc0e00200, 0xc1f03e1f);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_iom(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+
+ soc64_write_dce0(SOCFPGA_SECREG_NCAIU1MIFSR_REG, 0, 0x7070777);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_dce0(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+ soc64_write_dce1(SOCFPGA_SECREG_NCAIU1MIFSR_REG, 0, 0x7070777);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG, 0x80000, 0xffffffff);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG, 0, 0xff);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG, 0x800000, 0xffffffff);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG, 0, 0xff);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG, 0x8000000, 0xffffffff);
+ soc64_write_dce1(SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG, 0, 0xff);
+ soc64_write_dmi0(SOCFPGA_DMI0_DMIUSMCTCR_REG, 1, 0x3);
+ soc64_write_dmi0(SOCFPGA_DMI0_DMIUSMCTCR_REG, 3, 0x3);
+ soc64_write_dmi1(SOCFPGA_DMI1_DMIUSMCTCR_REG, 1, 0x3);
+ soc64_write_dmi1(SOCFPGA_DMI1_DMIUSMCTCR_REG, 3, 0x3);
+
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_NAND_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_USB0_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_USB1_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SPI_MAIN0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SPI_MAIN1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SPI_SEC0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SPI_SEC1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_EMAC0_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_EMAC1_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_EMAC2_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SDMMC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_GPIO0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_GPIO1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I2C0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I2C1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I2C2_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I2C3_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I2C4_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SP_TIMER0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_SP_TIMER1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_UART0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_UART1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I3C0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_I3C1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_DMA0_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_DMA1_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_COMBO_PHY_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_per(SOCFPGA_FIREWALL_L4_PER_NAND_SDMA_REG, 0x1010301, 0x1010301);
+
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_DMA_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_EMAC0RX_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_EMAC0TX_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_EMAC1RX_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_EMAC1TX_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_EMAC2RX_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_EMAC2TX_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_NAND_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_NAND_READ_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_NAND_WRITE_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_OCRAM_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_SDMMC_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_USB0_ECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_USB1_CACHEECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_CLOCK_MANAGER_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_IO_MANAGER_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_RESET_MANAGER_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_SYSTEM_MANAGER_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_OSC0_TIMER_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_OSC1_TIMER0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_WATCHDOG0_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_WATCHDOG1_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_WATCHDOG2_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_WATCHDOG3_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_DAP_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_WATCHDOG4_REG, 0x1010301, 0x1010301);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_POWER_MANAGER_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_USB1_RXECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_USB1_TXECC_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_L4_NOC_PROBES_REG, 0x1010001, 0x1010001);
+ soc64_write_l4_sys(SOCFPGA_FIREWALL_L4_SYS_L4_NOC_QOS_REG, 0x1010001, 0x1010001);
+
+ soc64_set(IOMEM(SOCFPGA_FIREWALL_SOC2FPGA_ADDRESS), 0, 0xffe0301, 0xffe0301);
+ soc64_set(IOMEM(SOCFPGA_FIREWALL_LWSOC2FPGA_ADDRESS), 0, 0xffe0301, 0xffe0301);
+ soc64_set(IOMEM(SOCFPGA_FIREWALL_TCU_ADDRESS), 0, 0xffe0301, 0xffe0301);
+
+ /* Enable non-secure access to ocram */
+ clrbits_le32(SOCFPGA_OCRAM_FIREWALL_ADDRESS + 0x18, BIT(0));
+}
diff --git a/arch/arm/mach-socfpga/atf.c b/arch/arm/mach-socfpga/atf.c
new file mode 100644
index 0000000000000000000000000000000000000000..23e2fffdce59c6da4c4e1b632e5ddb9ba22889b1
--- /dev/null
+++ b/arch/arm/mach-socfpga/atf.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <asm/sections.h>
+#include <common.h>
+#include <firmware.h>
+#include <asm-generic/memory_layout.h>
+#include <asm/atf_common.h>
+#include <asm/barebox-arm.h>
+#include <mach/socfpga/atf.h>
+#include <mach/socfpga/generic.h>
+#include <mach/socfpga/soc64-regs.h>
+
+void __noreturn agilex5_load_and_start_image_via_tfa(unsigned long memsize)
+{
+ unsigned long atf_dest = AGILEX5_ATF_BL31_BASE_ADDR;
+ void __noreturn (*bl31)(void) = (void *)atf_dest;
+ const void *tfa;
+ size_t tfa_size;
+
+ pr_debug("Load TFA\n");
+
+ memcpy((void *)AGILEX5_ATF_BL33_BASE_ADDR, __image_start, barebox_image_size);
+
+ get_builtin_firmware(agilex5_bl31_bin, &tfa, &tfa_size);
+
+ memcpy(bl31, tfa, tfa_size);
+
+ asm volatile("msr sp_el2, %0" : :
+ "r" (AGILEX5_ATF_BL33_BASE_ADDR - 16) :
+ "cc");
+
+ pr_debug("Jumping to @0x%08lx\n", atf_dest);
+ bl31_entry((uintptr_t)bl31, 0, AGILEX5_ATF_BL33_BASE_ADDR, 0);
+ __builtin_unreachable();
+}
diff --git a/arch/arm/mach-socfpga/cpu_init.c b/arch/arm/mach-socfpga/cpu_init.c
index 73b69c34c56f86c045abc4916e68a6d8af0885cd..048bd0f867065cfa26dedb112a2667453d534af8 100644
--- a/arch/arm/mach-socfpga/cpu_init.c
+++ b/arch/arm/mach-socfpga/cpu_init.c
@@ -1,12 +1,55 @@
// SPDX-License-Identifier: GPL-2.0
#include <common.h>
+#include <io.h>
+#include <debug_ll.h>
#include <asm/barebox-arm-head.h>
#include <asm/errata.h>
#include <mach/socfpga/init.h>
+#include <mach/socfpga/agilex5-clk.h>
+#include <mach/socfpga/mailbox_s10.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-reset-manager.h>
+#include <mach/socfpga/soc64-system-manager.h>
+#ifdef CONFIG_CPU_32
void arria10_cpu_lowlevel_init(void)
{
enable_arm_errata_794072_war();
enable_arm_errata_845369_war();
}
+#else
+void socfpga_agilex5_cpu_lowlevel_init(void)
+{
+ int enable = 0x3;
+ int loadval = ~0;
+ int val;
+
+ arm_cpu_lowlevel_init();
+
+ agilex5_sysmgr_pinmux_init();
+
+ /* Disable all watchdogs */
+ writel(SYSMGR_WDDBG_PAUSE_ALL_CPU, SOCFPGA_SYSMGR_ADDRESS +
+ SYSMGR_SOC64_WDDBG);
+ /* Let everything out of reset but the watchdogs */
+ val = 0xf;
+ writel(val, SOCFPGA_RSTMGR_ADDRESS + RSTMGR_SOC64_PER1MODRST);
+
+ /* de-assert resets */
+ writel(0, SOCFPGA_RSTMGR_ADDRESS + RSTMGR_SOC64_BRGMODRST);
+
+ /* configure DFI_SEL for SDMMC */
+ writel(SYSMGR_SOC64_COMBOPHY_DFISEL_SDMMC,
+ SOCFPGA_SYSMGR_ADDRESS+ SYSMGR_SOC64_COMBOPHY_DFISEL);
+
+ writel(enable, SOCFPGA_GTIMER_SEC_ADDRESS);
+ asm volatile("msr cntp_ctl_el0, %0" : : "r" (enable));
+ asm volatile("msr cntp_tval_el0, %0" : : "r" (loadval));
+
+ /* configure default base clkmgr clock - 200MHz */
+ val = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOCDIV);
+ val &= 0xfffcffff | (CLKMGR_NOCDIV_SOFTPHY_DIV_ONE << CLKMGR_NOCDIV_SOFTPHY_OFFSET);
+ writel(val, SOCFPGA_CLKMGR_ADDRESS + CLKMGR_MAINPLL_NOCDIV);
+}
+#endif
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
new file mode 100644
index 0000000000000000000000000000000000000000..de79b8370d8524553b31feb6e8845f7100408d1f
--- /dev/null
+++ b/arch/arm/mach-socfpga/iossm_mailbox.c
@@ -0,0 +1,551 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022-2024 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <linux/bitfield.h>
+#include "iossm_mailbox.h"
+#include <mach/socfpga/generic.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-system-manager.h>
+
+#define ECC_INTSTATUS_SERR SOCFPGA_SYSMGR_ADDRESS + 0x9C
+#define ECC_INISTATUS_DERR SOCFPGA_SYSMGR_ADDRESS + 0xA0
+#define DDR_CSR_CLKGEN_LOCKED_IO96B0_MASK BIT(16)
+#define DDR_CSR_CLKGEN_LOCKED_IO96B1_MASK BIT(17)
+
+#define DDR_CSR_CLKGEN_LOCKED_IO96B_MASK(x) (i == 0 ? DDR_CSR_CLKGEN_LOCKED_IO96B0_MASK : \
+ DDR_CSR_CLKGEN_LOCKED_IO96B1_MASK)
+#define MAX_RETRY_COUNT 3
+#define NUM_CMD_RESPONSE_DATA 3
+
+#define INTF_IP_TYPE_MASK GENMASK(31, 29)
+#define INTF_INSTANCE_ID_MASK GENMASK(28, 24)
+
+/* supported DDR type list */
+static const char *ddr_type_list[7] = {
+ "DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
+};
+
+static int wait_for_timeout(const void __iomem *reg, u32 mask, bool set)
+{
+ int timeout = 1000000;
+ int val;
+
+ while (timeout > 0) {
+ val = readl(IOMEM(reg));
+ if (!set)
+ val = ~val;
+
+ if ((val & mask) == mask)
+ return 0;
+ __udelay(10);
+ timeout--;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static int is_ddr_csr_clkgen_locked(u32 clkgen_mask, u8 num_port)
+{
+ int ret;
+
+ ret = wait_for_timeout(IOMEM(ECC_INTSTATUS_SERR), clkgen_mask, true);
+ if (ret) {
+ pr_debug("%s: ddr csr clkgena locked is timeout\n", __func__);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* Mailbox request function
+ * This function will send the request to IOSSM mailbox and wait for response return
+ *
+ * @io96b_csr_addr: CSR address for the target IO96B
+ * @ip_type: IP type for the specified memory interface
+ * @instance_id: IP instance ID for the specified memory interface
+ * @usr_cmd_type: User desire IOSSM mailbox command type
+ * @usr_cmd_opcode: User desire IOSSM mailbox command opcode
+ * @cmd_param_*: Parameters (if applicable) for the requested IOSSM mailbox command
+ * @resp_data_len: User desire extra response data fields other than
+ * CMD_RESPONSE_DATA_SHORT field on CMD_RESPONSE_STATUS
+ * @resp: Structure contain responses returned from the requested IOSSM
+ * mailbox command
+ */
+int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id
+ , u32 usr_cmd_type, u32 usr_cmd_opcode, u32 cmd_param_0
+ , u32 cmd_param_1, u32 cmd_param_2, u32 cmd_param_3
+ , u32 cmd_param_4, u32 cmd_param_5, u32 cmd_param_6
+ , u32 resp_data_len, struct io96b_mb_resp *resp)
+{
+ int i;
+ int ret;
+ u32 cmd_req, cmd_resp;
+
+ /* Initialized zeros for responses*/
+ resp->cmd_resp_status = 0;
+ for (i = 0; i < NUM_CMD_RESPONSE_DATA; i++)
+ resp->cmd_resp_data[i] = 0;
+
+ /* Ensure CMD_REQ is cleared before write any command request */
+ ret = wait_for_timeout((IOMEM(io96b_csr_addr) + IOSSM_CMD_REQ_OFFSET), GENMASK(31, 0), false);
+ if (ret) {
+ printf("%s: CMD_REQ not ready\n", __func__);
+ return -1;
+ }
+
+ /* Write CMD_PARAM_* */
+ for (i = 0; i < 6 ; i++) {
+ switch (i) {
+ case 0:
+ if (cmd_param_0)
+ writel(cmd_param_0, io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET);
+ break;
+ case 1:
+ if (cmd_param_1)
+ writel(cmd_param_1, io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET);
+ break;
+ case 2:
+ if (cmd_param_2)
+ writel(cmd_param_2, io96b_csr_addr + IOSSM_CMD_PARAM_2_OFFSET);
+ break;
+ case 3:
+ if (cmd_param_3)
+ writel(cmd_param_3, io96b_csr_addr + IOSSM_CMD_PARAM_3_OFFSET);
+ break;
+ case 4:
+ if (cmd_param_4)
+ writel(cmd_param_4, io96b_csr_addr + IOSSM_CMD_PARAM_4_OFFSET);
+ break;
+ case 5:
+ if (cmd_param_5)
+ writel(cmd_param_5, io96b_csr_addr + IOSSM_CMD_PARAM_5_OFFSET);
+ break;
+ case 6:
+ if (cmd_param_6)
+ writel(cmd_param_6, io96b_csr_addr + IOSSM_CMD_PARAM_6_OFFSET);
+ break;
+ default:
+ printf("%s: Invalid command parameter\n", __func__);
+ }
+ }
+
+ /* Write CMD_REQ (IP_TYPE, IP_INSTANCE_ID, CMD_TYPE and CMD_OPCODE) */
+ cmd_req = (usr_cmd_opcode << 0) | (usr_cmd_type << 16) | (instance_id << 24) |
+ (ip_type << 29);
+ writel(cmd_req, io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
+ pr_debug("%s: Write 0x%x to IOSSM_CMD_REQ_OFFSET 0x%llx\n", __func__, cmd_req
+ , io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
+
+ /* Read CMD_RESPONSE_READY in CMD_RESPONSE_STATUS*/
+ ret = wait_for_timeout((IOMEM(io96b_csr_addr) + IOSSM_CMD_RESPONSE_STATUS_OFFSET),
+ IOSSM_STATUS_COMMAND_RESPONSE_READY, true);
+ if (ret) {
+ printf("%s: CMD_RESPONSE ERROR:\n", __func__);
+ cmd_resp = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ printf("%s: STATUS_GENERAL_ERROR: 0x%x\n", __func__, (cmd_resp >> 1) & 0xF);
+ printf("%s: STATUS_CMD_RESPONSE_ERROR: 0x%x\n", __func__, (cmd_resp >> 5) & 0x7);
+ }
+
+ /* read CMD_RESPONSE_STATUS*/
+ resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ pr_debug("%s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n", __func__, io96b_csr_addr +
+ IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+ /* read CMD_RESPONSE_DATA_* */
+ for (i = 0; i < resp_data_len; i++) {
+ switch (i) {
+ case 0:
+ resp->cmd_resp_data[i] =
+ readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
+ pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x%llx: 0x%x\n", __func__
+ , io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET,
+ resp->cmd_resp_data[i]);
+ break;
+ case 1:
+ resp->cmd_resp_data[i] =
+ readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
+ pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x%llx: 0x%x\n", __func__
+ , io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET,
+ resp->cmd_resp_data[i]);
+ break;
+ case 2:
+ resp->cmd_resp_data[i] =
+ readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
+ pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x%llx: 0x%x\n", __func__
+ , io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET,
+ resp->cmd_resp_data[i]);
+ break;
+ default:
+ printf("%s: Invalid response data\n", __func__);
+ }
+ }
+
+ resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ pr_debug("%s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n", __func__, io96b_csr_addr +
+ IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+ /* write CMD_RESPONSE_READY = 0 */
+ clrbits_le32((u32 *)(uintptr_t)(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET)
+ , IOSSM_STATUS_COMMAND_RESPONSE_READY);
+
+ resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
+ pr_debug("%s: CMD_RESPONSE_READY 0x%llx: 0x%x\n", __func__, io96b_csr_addr +
+ IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
+
+ return 0;
+}
+
+/*
+ * Initial function to be called to set memory interface IP type and instance ID
+ * IP type and instance ID need to be determined before sending mailbox command
+ */
+void io96b_mb_init(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ u8 ip_type_ret, instance_id_ret;
+ int i, j, k;
+
+ pr_debug("%s: num_instance %d\n", __func__, io96b_ctrl->num_instance);
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ pr_debug("%s: get memory interface IO96B %d\n", __func__, i);
+ /* Get memory interface IP type and instance ID (IP identifier) */
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0, CMD_GET_SYS_INFO
+ , GET_MEM_INTF_INFO, 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+ pr_debug("%s: get response from memory interface IO96B %d\n", __func__, i);
+ /* Retrieve number of memory interface(s) */
+ io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) & 0x3;
+ pr_debug("%s: IO96B %d: num_mem_interface: 0x%x\n", __func__, i
+ , io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface);
+
+ /* Retrieve memory interface IP type and instance ID (IP identifier) */
+ j = 0;
+ for (k = 0; k < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; k++) {
+ ip_type_ret = FIELD_GET(INTF_IP_TYPE_MASK, usr_resp.cmd_resp_data[k]);
+ instance_id_ret = FIELD_GET(INTF_INSTANCE_ID_MASK
+ , usr_resp.cmd_resp_data[k]);
+
+ if (ip_type_ret) {
+ io96b_ctrl->io96b[i].mb_ctrl.ip_type[j] = ip_type_ret;
+ io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j] = instance_id_ret;
+ pr_debug("%s: IO96B %d mem_interface %d: ip_type_ret: 0x%x\n"
+ , __func__, i, j, ip_type_ret);
+ pr_debug("%s: IO96B %d mem_interface %d: instance_id_ret: 0x%x\n"
+ , __func__, i, j, instance_id_ret);
+ j++;
+ }
+ }
+ }
+}
+
+int io96b_cal_status(phys_addr_t addr)
+{
+ int ret;
+ u32 cal_success, cal_fail;
+ phys_addr_t status_addr = addr + IOSSM_STATUS_OFFSET;
+ /* Ensure calibration completed */
+ ret = wait_for_timeout(IOMEM(status_addr), IOSSM_STATUS_CAL_BUSY, false);
+ if (ret) {
+ printf("%s: SDRAM calibration IO96b instance 0x%llx timeout\n", __func__
+ , status_addr);
+ hang();
+ }
+
+ /* Calibration status */
+ cal_success = readl(status_addr) & IOSSM_STATUS_CAL_SUCCESS;
+ cal_fail = readl(status_addr) & IOSSM_STATUS_CAL_FAIL;
+
+ if (cal_success && !cal_fail)
+ return 0;
+ else
+ return -EPERM;
+}
+
+void init_mem_cal(struct io96b_info *io96b_ctrl)
+{
+ int count, i, ret;
+
+ /* Initialize overall calibration status */
+ io96b_ctrl->overall_cal_status = false;
+
+ /* Check initial calibration status for the assigned IO96B*/
+ count = 0;
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ if (io96b_ctrl->ckgen_lock) {
+ ret = is_ddr_csr_clkgen_locked(DDR_CSR_CLKGEN_LOCKED_IO96B_MASK(i),
+ io96b_ctrl->num_port);
+ if (ret) {
+ printf("%s: ckgena_lock iossm IO96B_%d is not locked\n",
+ __func__, i);
+ hang();
+ }
+ }
+ ret = io96b_cal_status(io96b_ctrl->io96b[i].io96b_csr_addr);
+ if (ret) {
+ io96b_ctrl->io96b[i].cal_status = false;
+ printf("%s: Initial DDR calibration IO96B_%d failed %d\n", __func__, i
+ , ret);
+ hang();
+ }
+ io96b_ctrl->io96b[i].cal_status = true;
+ printf("%s: Initial DDR calibration IO96B_%d succeed\n", __func__, i);
+ count++;
+ }
+
+ if (count == io96b_ctrl->num_instance)
+ io96b_ctrl->overall_cal_status = true;
+}
+
+/*
+ * Trying 3 times re-calibration if initial calibration failed
+ */
+int trig_mem_cal(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ bool recal_success;
+ int i, j, k;
+ u32 cal_stat_offset;
+ u8 cal_stat;
+ u8 trig_cal_stat;
+ int count = 0;
+
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ if (!(io96b_ctrl->io96b[i].cal_status)) {
+ for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+ /* Get the memory calibration status for memory interface */
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0
+ , CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0
+ , 0, 0, 0, 0, 2, &usr_resp);
+
+ recal_success = false;
+
+ /* Re-calibration first memory interface with failed calibration */
+ for (k = 0; k < MAX_RETRY_COUNT; k++) {
+ cal_stat_offset = usr_resp.cmd_resp_data[j];
+ cal_stat = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
+ cal_stat_offset);
+ if (cal_stat == INTF_MEM_CAL_STATUS_SUCCESS) {
+ recal_success = true;
+ break;
+ }
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
+ , CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0, 0
+ , 0, 0, 2, &usr_resp);
+
+ trig_cal_stat =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) &
+ BIT(0);
+ pr_debug("%s: Memory calibration triggered status = %d\n",
+ __func__, trig_cal_stat);
+
+ udelay(1);
+
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0
+ , CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS
+ , 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
+ }
+
+ if (!recal_success) {
+ printf("%s: Error as SDRAM calibration failed\n", __func__);
+ hang();
+ }
+ }
+
+ io96b_ctrl->io96b[i].cal_status = true;
+ io96b_ctrl->overall_cal_status = io96b_ctrl->io96b[i].cal_status;
+ printf("%s: Initial DDR calibration IO96B_%d succeed\n", __func__, i);
+ count++;
+ }
+ }
+
+ if (io96b_ctrl->overall_cal_status)
+ pr_debug("%s: Overall SDRAM calibration success\n", __func__);
+
+ return 0;
+}
+
+int get_mem_technology(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ u8 ddr_type_ret;
+
+ /* Initialize ddr type */
+ io96b_ctrl->ddr_type = ddr_type_list[6];
+
+ /* Get and ensure all memory interface(s) same DDR type */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
+ , CMD_GET_MEM_INFO, GET_MEM_TECHNOLOGY, 0, 0, 0, 0
+ , 0, 0, 0, 0, &usr_resp);
+
+ ddr_type_ret =
+ IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(2, 0);
+
+ if (!strcmp(io96b_ctrl->ddr_type, "UNKNOWN"))
+ io96b_ctrl->ddr_type = ddr_type_list[ddr_type_ret];
+
+ if (ddr_type_list[ddr_type_ret] != io96b_ctrl->ddr_type) {
+ printf("%s: Mismatch DDR type on IO96B_%d\n", __func__, i);
+ return -ENOEXEC;
+ }
+ }
+ }
+
+ return 0;
+}
+
+int get_mem_width_info(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ u16 memory_size;
+ u16 total_memory_size = 0;
+
+ /* Get all memory interface(s) total memory size on all instance(s) */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ memory_size = 0;
+ for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
+ , CMD_GET_MEM_INFO, GET_MEM_WIDTH_INFO, 0, 0, 0, 0
+ , 0, 0, 0, 2, &usr_resp);
+
+ memory_size = memory_size +
+ (usr_resp.cmd_resp_data[1] & GENMASK(7, 0));
+ }
+
+ if (!memory_size) {
+ printf("%s: Failed to get valid memory size\n", __func__);
+ return -ENOEXEC;
+ }
+
+ io96b_ctrl->io96b[i].size = memory_size;
+
+ total_memory_size = total_memory_size + memory_size;
+ }
+
+ if (!total_memory_size) {
+ printf("%s: Failed to get valid memory size\n", __func__);
+ return -ENOEXEC;
+ }
+
+ io96b_ctrl->overall_size = total_memory_size;
+
+ return 0;
+}
+
+int ecc_enable_status(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ bool ecc_stat_set = false;
+ bool ecc_stat;
+
+ /* Initialize ECC status */
+ io96b_ctrl->ecc_status = false;
+
+ /* Get and ensure all memory interface(s) same ECC status */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
+ , CMD_TRIG_CONTROLLER_OP, ECC_ENABLE_STATUS, 0, 0, 0
+ , 0, 0, 0, 0, 0, &usr_resp);
+
+ ecc_stat = ((IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(1, 0)) == 0 ? false : true);
+
+ if (!ecc_stat_set) {
+ io96b_ctrl->ecc_status = ecc_stat;
+ ecc_stat_set = true;
+ }
+
+ if (ecc_stat != io96b_ctrl->ecc_status) {
+ printf("%s: Mismatch DDR ECC status on IO96B_%d\n"
+ , __func__, i);
+ return -ENOEXEC;
+ }
+ }
+ }
+
+ pr_debug("%s: ECC enable status: %d\n", __func__, io96b_ctrl->ecc_status);
+
+ return 0;
+}
+
+int bist_mem_init_start(struct io96b_info *io96b_ctrl)
+{
+ struct io96b_mb_resp usr_resp;
+ int i, j;
+ bool bist_start, bist_success;
+ int timeout = 1000000;
+
+ /* Full memory initialization BIST performed on all memory interface(s) */
+ for (i = 0; i < io96b_ctrl->num_instance; i++) {
+ for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
+ bist_start = false;
+ bist_success = false;
+
+ /* Start memory initialization BIST on full memory address */
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
+ , CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0x40
+ , 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ bist_start =
+ (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & BIT(0));
+
+ if (!bist_start) {
+ printf("%s: Failed to initialized memory on IO96B_%d\n"
+ , __func__, i);
+ printf("%s: BIST_MEM_INIT_START Error code 0x%x\n", __func__
+ , (IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status)
+ & GENMASK(2, 1)) > 0x1);
+ return -ENOEXEC;
+ }
+
+ /* Polling for the initiated memory initialization BIST status */
+ while (!bist_success) {
+ io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
+ , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
+ , CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_STATUS, 0
+ , 0, 0, 0, 0, 0, 0, 0, &usr_resp);
+
+ bist_success = (IOSSM_CMD_RESPONSE_DATA_SHORT
+ (usr_resp.cmd_resp_status) & BIT(0));
+
+ if (!bist_success && (timeout-- < 0)) {
+ printf("%s: Timeout initialize memory on IO96B_%d\n"
+ , __func__, i);
+ printf("%s: BIST_MEM_INIT_STATUS Error code 0x%x\n"
+ , __func__, (IOSSM_CMD_RESPONSE_DATA_SHORT
+ (usr_resp.cmd_resp_status)
+ & GENMASK(2, 1)) > 0x1);
+ return -ETIMEDOUT;
+ }
+
+ __udelay(1);
+ }
+ }
+
+ pr_debug("%s: Memory initialized successfully on IO96B_%d\n", __func__, i);
+ }
+ return 0;
+}
diff --git a/arch/arm/mach-socfpga/iossm_mailbox.h b/arch/arm/mach-socfpga/iossm_mailbox.h
new file mode 100644
index 0000000000000000000000000000000000000000..86c93a38d5845d34ad82b510ac09b8048f42c64e
--- /dev/null
+++ b/arch/arm/mach-socfpga/iossm_mailbox.h
@@ -0,0 +1,152 @@
+#ifndef IOSSM_MAILBOX_H_
+#define IOSSM_MAILBOX_H_
+
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2022-2023 Intel Corporation <www.intel.com>
+ */
+
+#define TIMEOUT 120000
+#define IOSSM_STATUS_CAL_SUCCESS BIT(0)
+#define IOSSM_STATUS_CAL_FAIL BIT(1)
+#define IOSSM_STATUS_CAL_BUSY BIT(2)
+#define IOSSM_STATUS_COMMAND_RESPONSE_READY BIT(0)
+#define IOSSM_CMD_RESPONSE_STATUS_OFFSET 0x45C
+#define IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x458
+#define IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x454
+#define IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x450
+#define IOSSM_CMD_REQ_OFFSET 0x43C
+#define IOSSM_CMD_PARAM_0_OFFSET 0x438
+#define IOSSM_CMD_PARAM_1_OFFSET 0x434
+#define IOSSM_CMD_PARAM_2_OFFSET 0x430
+#define IOSSM_CMD_PARAM_3_OFFSET 0x42C
+#define IOSSM_CMD_PARAM_4_OFFSET 0x428
+#define IOSSM_CMD_PARAM_5_OFFSET 0x424
+#define IOSSM_CMD_PARAM_6_OFFSET 0x420
+#define IOSSM_STATUS_OFFSET 0x400
+#define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK GENMASK(31, 16)
+#define IOSSM_CMD_RESPONSE_DATA_SHORT(data) (((data) & IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16)
+#define MAX_IO96B_SUPPORTED 2
+
+/* supported mailbox command type */
+enum iossm_mailbox_cmd_type {
+ CMD_NOP,
+ CMD_GET_SYS_INFO,
+ CMD_GET_MEM_INFO,
+ CMD_GET_MEM_CAL_INFO,
+ CMD_TRIG_CONTROLLER_OP,
+ CMD_TRIG_MEM_CAL_OP
+};
+
+/* supported mailbox command opcode */
+enum iossm_mailbox_cmd_opcode {
+ GET_MEM_INTF_INFO = 0x0001,
+ GET_MEM_TECHNOLOGY,
+ GET_MEMCLK_FREQ_KHZ,
+ GET_MEM_WIDTH_INFO,
+ ECC_ENABLE_SET = 0x0101,
+ ECC_ENABLE_STATUS,
+ ECC_INTERRUPT_STATUS,
+ ECC_INTERRUPT_ACK,
+ ECC_INTERRUPT_MASK,
+ ECC_WRITEBACK_ENABLE,
+ ECC_SCRUB_IN_PROGRESS_STATUS = 0x0201,
+ ECC_SCRUB_MODE_0_START,
+ ECC_SCRUB_MODE_1_START,
+ BIST_STANDARD_MODE_START = 0x0301,
+ BIST_RESULTS_STATUS,
+ BIST_MEM_INIT_START,
+ BIST_MEM_INIT_STATUS,
+ BIST_SET_DATA_PATTERN_UPPER,
+ BIST_SET_DATA_PATTERN_LOWER,
+ TRIG_MEM_CAL = 0x000a,
+ GET_MEM_CAL_STATUS
+};
+
+/* response data of cmd opcode GET_MEM_CAL_STATUS */
+#define INTF_UNUSED 0x0
+#define INTF_MEM_CAL_STATUS_SUCCESS 0x1
+#define INTF_MEM_CAL_STATUS_FAIL 0x2
+#define INTF_MEM_CAL_STATUS_ONGOING 0x4
+
+/*
+ * IOSSM mailbox required information
+ *
+ * @num_mem_interface: Number of memory interfaces instantiated
+ * @ip_type: IP type implemented on the IO96B
+ * @ip_instance_id: IP identifier for every IP instance implemented on the IO96B
+ */
+struct io96b_mb_ctrl {
+ u32 num_mem_interface;
+ u32 ip_type[2];
+ u32 ip_instance_id[2];
+};
+
+/*
+ * IOSSM mailbox response outputs
+ *
+ * @cmd_resp_status: Command Interface status
+ * @cmd_resp_data_*: More spaces for command response
+ */
+struct io96b_mb_resp {
+ u32 cmd_resp_status;
+ u32 cmd_resp_data[3];
+};
+
+/*
+ * IO96B instance specific information
+ *
+ * @size: Memory size
+ * @io96b_csr_addr: IO96B instance CSR address
+ * @cal_status: IO96B instance calibration status
+ * @mb_ctrl: IOSSM mailbox required information
+ */
+struct io96b_instance {
+ u16 size;
+ phys_addr_t io96b_csr_addr;
+ bool cal_status;
+ struct io96b_mb_ctrl mb_ctrl;
+};
+
+/*
+ * Overall IO96B instance(s) information
+ *
+ * @num_instance: Number of instance(s) assigned to HPS
+ * @overall_cal_status: Overall calibration status for all IO96B instance(s)
+ * @ddr_type: DDR memory type
+ * @ecc_status: ECC enable status (false = disabled, true = enabled)
+ * @overall_size: Total DDR memory size
+ * @io96b[]: IO96B instance specific information
+ * @ckgen_lock: IO96B GEN PLL lock (false = not locked, true = locked)
+ * @num_port: Number of IO96B port.
+ */
+struct io96b_info {
+ u8 num_instance;
+ bool overall_cal_status;
+ const char *ddr_type;
+ bool ecc_status;
+ u16 overall_size;
+ struct io96b_instance io96b[MAX_IO96B_SUPPORTED];
+ bool ckgen_lock;
+ u8 num_port;
+};
+
+int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id
+ , u32 usr_cmd_type, u32 usr_cmd_opcode, u32 cmd_param_0
+ , u32 cmd_param_1, u32 cmd_param_2, u32 cmd_param_3, u32 cmd_param_4
+ , u32 cmd_param_5, u32 cmd_param_6, u32 resp_data_len
+ , struct io96b_mb_resp *resp);
+
+/* Supported IOSSM mailbox function */
+void io96b_mb_init(struct io96b_info *io96b_ctrl);
+int io96b_cal_status(phys_addr_t addr);
+void init_mem_cal(struct io96b_info *io96b_ctrl);
+int trig_mem_cal(struct io96b_info *io96b_ctrl);
+int get_mem_technology(struct io96b_info *io96b_ctrl);
+int get_mem_width_info(struct io96b_info *io96b_ctrl);
+int ecc_enable_status(struct io96b_info *io96b_ctrl);
+int bist_mem_init_start(struct io96b_info *io96b_ctrl);
+
+
+
+#endif // IOSSM_MAILBOX_H_
diff --git a/arch/arm/mach-socfpga/mailbox_s10.c b/arch/arm/mach-socfpga/mailbox_s10.c
new file mode 100644
index 0000000000000000000000000000000000000000..26b240138e7c8be56a74052ca91d08cdf696c3a4
--- /dev/null
+++ b/arch/arm/mach-socfpga/mailbox_s10.c
@@ -0,0 +1,407 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017-2023 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <mach/socfpga/mailbox_s10.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-system-manager.h>
+
+#define MBOX_READL(reg) \
+ readl(SOCFPGA_MAILBOX_ADDRESS + (reg))
+
+#define MBOX_WRITEL(data, reg) \
+ writel(data, SOCFPGA_MAILBOX_ADDRESS + (reg))
+
+#define MBOX_READ_RESP_BUF(rout) \
+ MBOX_READL(MBOX_RESP_BUF + ((rout) * sizeof(u32)))
+
+#define MBOX_WRITE_CMD_BUF(data, cin) \
+ MBOX_WRITEL(data, MBOX_CMD_BUF + ((cin) * sizeof(u32)))
+
+static __always_inline int mbox_polling_resp(u32 rout)
+{
+ u32 rin;
+ unsigned long i = 2000;
+
+ while (i) {
+ rin = MBOX_READL(MBOX_RIN);
+ if (rout != rin)
+ return 0;
+
+ udelay(1000);
+ i--;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static __always_inline int mbox_is_cmdbuf_full(u32 cin)
+{
+ return (((cin + 1) % MBOX_CMD_BUFFER_SIZE) == MBOX_READL(MBOX_COUT));
+}
+
+static __always_inline int mbox_is_cmdbuf_empty(u32 cin)
+{
+ return (((MBOX_READL(MBOX_COUT) + 1) % MBOX_CMD_BUFFER_SIZE) == cin);
+}
+
+static __always_inline int mbox_wait_for_cmdbuf_empty(u32 cin)
+{
+ int timeout = 2000;
+
+ while (timeout) {
+ if (mbox_is_cmdbuf_empty(cin))
+ return 0;
+
+ udelay(1000);
+ timeout--;
+ }
+
+ return -ETIMEDOUT;
+}
+
+static __always_inline int mbox_write_cmd_buffer(u32 *cin, u32 data,
+ int *is_cmdbuf_overflow)
+{
+ int timeout = 1000;
+
+ while (timeout) {
+ if (mbox_is_cmdbuf_full(*cin)) {
+ if (is_cmdbuf_overflow &&
+ *is_cmdbuf_overflow == 0) {
+ /* Trigger SDM doorbell */
+ MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
+ *is_cmdbuf_overflow = 1;
+ }
+ udelay(1000);
+ } else {
+ /* write header to circular buffer */
+ MBOX_WRITE_CMD_BUF(data, (*cin)++);
+ *cin %= MBOX_CMD_BUFFER_SIZE;
+ MBOX_WRITEL(*cin, MBOX_CIN);
+ if (is_cmdbuf_overflow)
+ *is_cmdbuf_overflow = 0;
+ break;
+ }
+ timeout--;
+ }
+
+ if (!timeout)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+
+/* Check for available slot and write to circular buffer.
+ * It also update command valid offset (cin) register.
+ */
+static __always_inline int mbox_fill_cmd_circular_buff(u32 header, u32 len,
+ u32 *arg)
+{
+ int i, ret;
+ int is_cmdbuf_overflow = 0;
+ u32 cin = MBOX_READL(MBOX_CIN) % MBOX_CMD_BUFFER_SIZE;
+
+ ret = mbox_write_cmd_buffer(&cin, header, &is_cmdbuf_overflow);
+ if (ret)
+ return ret;
+
+ /* write arguments */
+ for (i = 0; i < len; i++) {
+ is_cmdbuf_overflow = 0;
+ ret = mbox_write_cmd_buffer(&cin, arg[i], &is_cmdbuf_overflow);
+ if (ret)
+ return ret;
+ }
+
+ /* Always trigger the SDM doorbell at the end to ensure SDM able to read
+ * the remaining data.
+ */
+ MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
+
+ return 0;
+}
+
+/* Check the command and fill it into circular buffer */
+static __always_inline int mbox_prepare_cmd_only(u8 id, u32 cmd,
+ u8 is_indirect, u32 len,
+ u32 *arg)
+{
+ u32 header;
+ int ret;
+
+ if (cmd > MBOX_MAX_CMD_INDEX)
+ return -EINVAL;
+
+ header = MBOX_CMD_HEADER(MBOX_CLIENT_ID_BAREBOX, id, len,
+ (is_indirect) ? 1 : 0, cmd);
+
+ ret = mbox_fill_cmd_circular_buff(header, len, arg);
+
+ return ret;
+}
+
+/* Send command only without waiting for responses from SDM */
+static __always_inline int mbox_send_cmd_only_common(u8 id, u32 cmd,
+ u8 is_indirect, u32 len,
+ u32 *arg)
+{
+ return mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
+}
+
+/* Return number of responses received in buffer */
+static __always_inline int __mbox_rcv_resp(u32 *resp_buf, u32 resp_buf_max_len)
+{
+ u32 rin;
+ u32 rout;
+ u32 resp_len = 0;
+
+ /* clear doorbell from SDM if it was SET */
+ if (MBOX_READL(MBOX_DOORBELL_FROM_SDM) & 1)
+ MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
+
+ /* read current response offset */
+ rout = MBOX_READL(MBOX_ROUT);
+ /* read response valid offset */
+ rin = MBOX_READL(MBOX_RIN);
+
+ while (rin != rout && (resp_len < resp_buf_max_len)) {
+ /* Response received */
+ if (resp_buf)
+ resp_buf[resp_len++] = MBOX_READ_RESP_BUF(rout);
+
+ rout++;
+ /* wrapping around when it reach the buffer size */
+ rout %= MBOX_RESP_BUFFER_SIZE;
+ /* update next ROUT */
+ MBOX_WRITEL(rout, MBOX_ROUT);
+ }
+
+ return resp_len;
+}
+
+/* Support one command and up to 31 words argument length only */
+static __always_inline int mbox_send_cmd_common(u8 id, u32 cmd, u8 is_indirect,
+ u32 len, u32 *arg, u8 urgent,
+ u32 *resp_buf_len,
+ u32 *resp_buf)
+{
+ u32 rin;
+ u32 resp;
+ u32 rout;
+ u32 status;
+ u32 resp_len;
+ u32 buf_len;
+ int ret;
+
+ if (urgent) {
+ /* Read status because it is toggled */
+ status = MBOX_READL(MBOX_STATUS) & MBOX_STATUS_UA_MSK;
+ /* Write urgent command to urgent register */
+ MBOX_WRITEL(cmd, MBOX_URG);
+ /* write doorbell */
+ MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
+ } else {
+ ret = mbox_prepare_cmd_only(id, cmd, is_indirect, len, arg);
+ if (ret)
+ return ret;
+ }
+
+ while (1) {
+ ret = 1000;
+
+ /* Wait for doorbell from SDM */
+ do {
+ if (MBOX_READL(MBOX_DOORBELL_FROM_SDM))
+ break;
+ udelay(1000);
+ } while (--ret);
+
+ if (!ret)
+ return -ETIMEDOUT;
+
+ /* clear interrupt */
+ MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
+
+ if (urgent) {
+ u32 new_status = MBOX_READL(MBOX_STATUS);
+
+ /* Urgent ACK is toggled */
+ if ((new_status & MBOX_STATUS_UA_MSK) ^ status)
+ return 0;
+
+ return -ECOMM;
+ }
+
+ /* read current response offset */
+ rout = MBOX_READL(MBOX_ROUT);
+
+ /* read response valid offset */
+ rin = MBOX_READL(MBOX_RIN);
+
+ if (rout != rin) {
+ /* Response received */
+ resp = MBOX_READ_RESP_BUF(rout);
+ rout++;
+ /* wrapping around when it reach the buffer size */
+ rout %= MBOX_RESP_BUFFER_SIZE;
+ /* update next ROUT */
+ MBOX_WRITEL(rout, MBOX_ROUT);
+
+ /* check client ID and ID */
+ if ((MBOX_RESP_CLIENT_GET(resp) ==
+ MBOX_CLIENT_ID_BAREBOX) &&
+ (MBOX_RESP_ID_GET(resp) == id)) {
+ int resp_err = MBOX_RESP_ERR_GET(resp);
+
+ if (resp_buf_len) {
+ buf_len = *resp_buf_len;
+ *resp_buf_len = 0;
+ } else {
+ buf_len = 0;
+ }
+
+ resp_len = MBOX_RESP_LEN_GET(resp);
+ while (resp_len) {
+ ret = mbox_polling_resp(rout);
+ if (ret)
+ return ret;
+ /* we need to process response buffer
+ * even caller doesn't need it
+ */
+ resp = MBOX_READ_RESP_BUF(rout);
+ rout++;
+ resp_len--;
+ rout %= MBOX_RESP_BUFFER_SIZE;
+ MBOX_WRITEL(rout, MBOX_ROUT);
+ if (buf_len) {
+ /* copy response to buffer */
+ resp_buf[*resp_buf_len] = resp;
+ (*resp_buf_len)++;
+ buf_len--;
+ }
+ }
+ return resp_err;
+ }
+ }
+ }
+
+ return -EIO;
+}
+
+static __always_inline int mbox_send_cmd_common_retry(u8 id, u32 cmd,
+ u8 is_indirect,
+ u32 len, u32 *arg,
+ u8 urgent,
+ u32 *resp_buf_len,
+ u32 *resp_buf)
+{
+ int ret;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ ret = mbox_send_cmd_common(id, cmd, is_indirect, len, arg,
+ urgent, resp_buf_len, resp_buf);
+ if (ret == MBOX_RESP_TIMEOUT || ret == MBOX_RESP_DEVICE_BUSY)
+ udelay(2000); /* wait for 2ms before resend */
+ else
+ break;
+ }
+
+ return ret;
+}
+
+int mbox_init(void)
+{
+ int ret;
+
+ /* enable mailbox interrupts */
+ MBOX_WRITEL(MBOX_ALL_INTRS, MBOX_FLAGS);
+
+ /* Ensure urgent request is cleared */
+ MBOX_WRITEL(0, MBOX_URG);
+
+ /* Ensure the Doorbell Interrupt is cleared */
+ MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
+
+ ret = mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_RESTART, MBOX_CMD_DIRECT, 0,
+ NULL, 1, 0, NULL);
+ if (ret)
+ return ret;
+
+ pr_debug("%s: success...\n", __func__);
+
+ /* Renable mailbox interrupts after MBOX_RESTART */
+ MBOX_WRITEL(MBOX_ALL_INTRS, MBOX_FLAGS);
+
+ return 0;
+}
+
+int mbox_qspi_close(void)
+{
+ return mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_QSPI_CLOSE, MBOX_CMD_DIRECT,
+ 0, NULL, 0, 0, NULL);
+}
+
+int mbox_qspi_open(void)
+{
+ int ret;
+ u32 resp_buf[1];
+ u32 resp_buf_len;
+ u32 reg;
+ u32 clk_khz;
+
+ ret = mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_QSPI_OPEN, MBOX_CMD_DIRECT,
+ 0, NULL, 0, 0, NULL);
+ if (ret) {
+ /* retry again by closing and reopen the QSPI again */
+ ret = mbox_qspi_close();
+ if (ret)
+ return ret;
+
+ ret = mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_QSPI_OPEN,
+ MBOX_CMD_DIRECT, 0, NULL, 0, 0, NULL);
+ if (ret)
+ return ret;
+ }
+
+ /* HPS will directly control the QSPI controller, no longer mailbox */
+ resp_buf_len = 1;
+ ret = mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_QSPI_DIRECT, MBOX_CMD_DIRECT,
+ 0, NULL, 0, (u32 *)&resp_buf_len,
+ (u32 *)&resp_buf);
+ if (ret)
+ goto error;
+
+ /* Get the QSPI clock from SDM response and save for later use */
+ clk_khz = resp_buf[0];
+ if (clk_khz < 1000)
+ return -EINVAL;
+
+ clk_khz /= 1000;
+ pr_info("QSPI: reference clock at %d kHZ\n", clk_khz);
+
+ reg = (readl(SOCFPGA_SYSMGR_ADDRESS + SYSMGR_SOC64_BOOT_SCRATCH_COLD0)) &
+ ~(SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK);
+
+ writel((clk_khz & SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK) | reg,
+ SOCFPGA_SYSMGR_ADDRESS + SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
+
+ return 0;
+
+error:
+ mbox_qspi_close();
+
+ return ret;
+}
+
+int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
+ u8 urgent, u32 *resp_buf_len, u32 *resp_buf)
+{
+ return mbox_send_cmd_common_retry(id, cmd, is_indirect, len, arg,
+ urgent, resp_buf_len, resp_buf);
+}
diff --git a/arch/arm/mach-socfpga/secure_reg_helper.c b/arch/arm/mach-socfpga/secure_reg_helper.c
new file mode 100644
index 0000000000000000000000000000000000000000..fe855aec8dd79cb2ab2d82a8dd4a41134150d452
--- /dev/null
+++ b/arch/arm/mach-socfpga/secure_reg_helper.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020-2022 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <mach/socfpga/secure_reg_helper.h>
+#include <mach/socfpga/smc_api.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-system-manager.h>
+#include <linux/errno.h>
+#include <linux/intel-smc.h>
+
+static int socfpga_secure_convert_reg_id_to_addr(u32 id, phys_addr_t *reg_addr)
+{
+ switch (id) {
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0:
+ *reg_addr = SOCFPGA_SYSMGR_ADDRESS + SYSMGR_SOC64_EMAC0;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1:
+ *reg_addr = SOCFPGA_SYSMGR_ADDRESS + SYSMGR_SOC64_EMAC1;
+ break;
+ case SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2:
+ *reg_addr = SOCFPGA_SYSMGR_ADDRESS + SYSMGR_SOC64_EMAC2;
+ break;
+ default:
+ return -EADDRNOTAVAIL;
+ }
+ return 0;
+}
+
+int socfpga_secure_reg_read32(u32 id, u32 *val)
+{
+ int ret;
+ u32 ret_arg[4];
+ phys_addr_t reg_addr;
+
+ ret = socfpga_secure_convert_reg_id_to_addr(id, ®_addr);
+ if (ret)
+ return ret;
+
+ ret = invoke_smc(INTEL_SIP_SMC_REG_READ, reg_addr, 0, 0, ret_arg);
+ if (ret)
+ return ret;
+
+ *val = ret_arg[0];
+
+ return 0;
+}
+
+int socfpga_secure_reg_write32(u32 id, u32 val)
+{
+ int ret;
+ phys_addr_t reg_addr;
+
+ ret = socfpga_secure_convert_reg_id_to_addr(id, ®_addr);
+ if (ret)
+ return ret;
+
+ return invoke_smc(INTEL_SIP_SMC_REG_WRITE, reg_addr, (u64) val, 0, 0);
+}
+
+int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val)
+{
+ int ret;
+ phys_addr_t reg_addr;
+
+ ret = socfpga_secure_convert_reg_id_to_addr(id, ®_addr);
+ if (ret)
+ return ret;
+
+ return invoke_smc(INTEL_SIP_SMC_REG_UPDATE, reg_addr, (u64) mask, (u64) val, 0);
+}
diff --git a/arch/arm/mach-socfpga/smc_api.c b/arch/arm/mach-socfpga/smc_api.c
new file mode 100644
index 0000000000000000000000000000000000000000..2540c3301cc978ab06bafd92554efff77757579b
--- /dev/null
+++ b/arch/arm/mach-socfpga/smc_api.c
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020-2024 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <mach/socfpga/smc_api.h>
+#include <linux/arm-smccc.h>
+#include <linux/intel-smc.h>
+#include <linux/kernel.h>
+
+int invoke_smc(u32 func_id, u64 arg0, u64 arg1, u64 arg2, u32 *ret_payload)
+{
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(func_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
+
+ if (ret_payload) {
+ ret_payload[0] = lower_32_bits(res.a0);
+ ret_payload[1] = upper_32_bits(res.a0);
+ ret_payload[2] = lower_32_bits(res.a1);
+ ret_payload[3] = upper_32_bits(res.a1);
+ }
+
+ return res.a0;
+}
+
+int smc_get_usercode(u32 *usercode)
+{
+ u32 res;
+ int ret;
+
+ if (!usercode)
+ return -EINVAL;
+
+ ret = invoke_smc(INTEL_SIP_SMC_GET_USERCODE, 0, 0, 0, &res);
+
+ if (ret == INTEL_SIP_SMC_STATUS_OK)
+ *usercode = res;
+
+ return ret;
+}
diff --git a/arch/arm/mach-socfpga/soc64-system-manager.c b/arch/arm/mach-socfpga/soc64-system-manager.c
new file mode 100644
index 0000000000000000000000000000000000000000..b66a7556975558fe460523322a00a366c9fc68a9
--- /dev/null
+++ b/arch/arm/mach-socfpga/soc64-system-manager.c
@@ -0,0 +1,102 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2016-2021 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <mach/socfpga/soc64-handoff.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-system-manager.h>
+
+/*
+ * Populate the value for SYSMGR.FPGAINTF.MODULE based on pinmux setting.
+ * The value is not wrote to SYSMGR.FPGAINTF.MODULE but
+ * CONFIG_SYSMGR_ISWGRP_HANDOFF.
+ */
+static void populate_sysmgr_fpgaintf_module(void)
+{
+ void __iomem *sysmgr = IOMEM(SOCFPGA_SYSMGR_ADDRESS);
+ u32 handoff_val = 0;
+
+ /* Enable the signal for those HPS peripherals that use FPGA. */
+ if (readl(sysmgr + SYSMGR_SOC64_NAND_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_NAND;
+ if (readl(sysmgr + SYSMGR_SOC64_SDMMC_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_SDMMC;
+ if (readl(sysmgr + SYSMGR_SOC64_SPIM0_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_SPIM0;
+ if (readl(sysmgr + SYSMGR_SOC64_SPIM1_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_SPIM1;
+ writel(handoff_val, sysmgr + SYSMGR_SOC64_FPGAINTF_EN2);
+
+ handoff_val = 0;
+ if (readl(sysmgr + SYSMGR_SOC64_EMAC0_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_EMAC0;
+ if (readl(sysmgr + SYSMGR_SOC64_EMAC1_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_EMAC1;
+ if (readl(sysmgr + SYSMGR_SOC64_EMAC2_USEFPGA) == SYSMGR_FPGAINTF_USEFPGA)
+ handoff_val |= SYSMGR_FPGAINTF_EMAC2;
+ writel(handoff_val, sysmgr + SYSMGR_SOC64_FPGAINTF_EN3);
+}
+
+/*
+ * Configure all the pin muxes
+ */
+static void populate_sysmgr_pinmux(void)
+{
+ u32 len, i;
+ void __iomem *sysmgr = IOMEM(SOCFPGA_SYSMGR_ADDRESS);
+ u32 len_mux = socfpga_get_handoff_size((void __iomem *)SOC64_HANDOFF_MUX);
+ u32 len_ioctl = socfpga_get_handoff_size((void __iomem *)SOC64_HANDOFF_IOCTL);
+ u32 len_fpga = socfpga_get_handoff_size((void __iomem *)SOC64_HANDOFF_FPGA);
+ u32 len_delay = socfpga_get_handoff_size((void __iomem *)SOC64_HANDOFF_DELAY);
+
+ len = (len_mux > len_ioctl) ? len_mux : len_ioctl;
+ len = (len > len_fpga) ? len : len_fpga;
+ len = (len > len_delay) ? len : len_delay;
+
+ u32 handoff_table[len];
+
+ /* setup the pin sel */
+ len = (len_mux < SOC64_HANDOFF_MUX_LEN) ? len_mux : SOC64_HANDOFF_MUX_LEN;
+ socfpga_handoff_read(IOMEM(SOC64_HANDOFF_MUX), handoff_table, len);
+ for (i = 0; i < len; i = i + 2) {
+ writel(handoff_table[i + 1], handoff_table[i] + sysmgr +
+ SYSMGR_SOC64_PINSEL0);
+ }
+
+ /* setup the pin ctrl */
+ len = (len_ioctl < SOC64_HANDOFF_IOCTL_LEN) ? len_ioctl : SOC64_HANDOFF_IOCTL_LEN;
+ socfpga_handoff_read(IOMEM(SOC64_HANDOFF_IOCTL), handoff_table, len);
+ for (i = 0; i < len; i = i + 2) {
+ writel(handoff_table[i + 1], handoff_table[i] + sysmgr +
+ SYSMGR_SOC64_IOCTRL0);
+ }
+
+ /* setup the fpga use */
+ len = (len_fpga < SOC64_HANDOFF_FPGA_LEN) ? len_fpga : SOC64_HANDOFF_FPGA_LEN;
+ socfpga_handoff_read(IOMEM(SOC64_HANDOFF_FPGA), handoff_table, len);
+ for (i = 0; i < len; i = i + 2) {
+ writel(handoff_table[i + 1], handoff_table[i] + sysmgr +
+ SYSMGR_SOC64_EMAC0_USEFPGA);
+ }
+
+ /* setup the IO delay */
+ len = (len_delay < SOC64_HANDOFF_DELAY_LEN) ? len_delay : SOC64_HANDOFF_DELAY_LEN;
+ socfpga_handoff_read(IOMEM(SOC64_HANDOFF_DELAY), handoff_table, len);
+ for (i = 0; i < len; i = i + 2) {
+ writel(handoff_table[i + 1], handoff_table[i] + sysmgr +
+ SYSMGR_SOC64_IODELAY0);
+ }
+}
+
+/*
+ * Configure all the pin muxes
+ */
+void agilex5_sysmgr_pinmux_init(void)
+{
+ populate_sysmgr_pinmux();
+ populate_sysmgr_fpgaintf_module();
+}
diff --git a/arch/arm/mach-socfpga/soc64-wrap-handoff.c b/arch/arm/mach-socfpga/soc64-wrap-handoff.c
new file mode 100644
index 0000000000000000000000000000000000000000..c506e21001f677dd23fb5eb6cc11d06952acf20d
--- /dev/null
+++ b/arch/arm/mach-socfpga/soc64-wrap-handoff.c
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020-2022 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <errno.h>
+#include <mach/socfpga/agilex5-clk.h>
+#include <mach/socfpga/soc64-handoff.h>
+
+enum endianness {
+ LITTLE_ENDIAN = 0,
+ BIG_ENDIAN,
+ UNKNOWN_ENDIANNESS
+};
+
+static enum endianness check_endianness(u32 handoff)
+{
+ switch (handoff) {
+ case SOC64_HANDOFF_MAGIC_BOOT:
+ case SOC64_HANDOFF_MAGIC_MUX:
+ case SOC64_HANDOFF_MAGIC_IOCTL:
+ case SOC64_HANDOFF_MAGIC_FPGA:
+ case SOC64_HANDOFF_MAGIC_DELAY:
+ case SOC64_HANDOFF_MAGIC_PERI:
+ case SOC64_HANDOFF_MAGIC_SDRAM:
+ case SOC64_HANDOFF_MAGIC_CLOCK:
+ return BIG_ENDIAN;
+ default:
+ return UNKNOWN_ENDIANNESS;
+ }
+}
+
+static int getting_endianness(void __iomem *handoff_address, enum endianness *endian_t)
+{
+ /* Checking handoff data is little endian ? */
+ *endian_t = check_endianness(readl(handoff_address));
+
+ if (*endian_t == UNKNOWN_ENDIANNESS) {
+ /* Trying to check handoff data is big endian? */
+ *endian_t = check_endianness(swab32(readl(handoff_address)));
+ if (*endian_t == UNKNOWN_ENDIANNESS)
+ return -EPERM;
+ }
+
+ return 0;
+}
+
+const struct cm_config * const cm_get_default_config(void)
+{
+ struct cm_config *cm_handoff_cfg = (struct cm_config *)
+ (SOC64_HANDOFF_CLOCK + SOC64_HANDOFF_OFFSET_DATA);
+ u32 *conversion = (u32 *)cm_handoff_cfg;
+ u32 handoff_clk = readl(SOC64_HANDOFF_CLOCK);
+ u32 i;
+
+ if (swab32(handoff_clk) == SOC64_HANDOFF_MAGIC_CLOCK) {
+ writel(swab32(handoff_clk), SOC64_HANDOFF_CLOCK);
+ for (i = 0; i < (sizeof(*cm_handoff_cfg) / sizeof(u32)); i++)
+ conversion[i] = swab32(conversion[i]);
+ return cm_handoff_cfg;
+ } else if (handoff_clk == SOC64_HANDOFF_MAGIC_CLOCK) {
+ return cm_handoff_cfg;
+ }
+
+ return NULL;
+}
+
+int socfpga_get_handoff_size(void __iomem *handoff_address)
+{
+ u32 size;
+ int ret;
+ enum endianness endian_t;
+
+ ret = getting_endianness(handoff_address, &endian_t);
+ if (ret)
+ return ret;
+
+ size = readl(handoff_address + SOC64_HANDOFF_OFFSET_LENGTH);
+ if (endian_t == BIG_ENDIAN)
+ size = swab32(size);
+
+ size = (size - SOC64_HANDOFF_OFFSET_DATA) / sizeof(u32);
+
+ return size;
+}
+
+int socfpga_handoff_read(void __iomem *handoff_address, void *table, u32 table_len)
+{
+ u32 temp;
+ u32 *table_x32 = table;
+ u32 i = 0;
+ int ret;
+ enum endianness endian_t;
+
+ ret = getting_endianness(handoff_address, &endian_t);
+ if (ret)
+ return ret;
+
+ temp = readl(handoff_address + SOC64_HANDOFF_OFFSET_DATA +
+ (i * sizeof(u32)));
+
+ if (endian_t == BIG_ENDIAN)
+ *table_x32 = swab32(temp);
+ else if (endian_t == LITTLE_ENDIAN)
+ *table_x32 = temp;
+
+ for (i = 1; i < table_len; i++) {
+ table_x32++;
+
+ temp = readl(handoff_address +
+ SOC64_HANDOFF_OFFSET_DATA +
+ (i * sizeof(u32)));
+
+ if (endian_t == BIG_ENDIAN)
+ *table_x32 = swab32(temp);
+ else if (endian_t == LITTLE_ENDIAN)
+ *table_x32 = temp;
+ }
+
+ return 0;
+}
diff --git a/common/Kconfig.debug_ll b/common/Kconfig.debug_ll
index 1f9255b1a45bce4f432ca8a3462352ded7dc5504..28c0ed496d915a25a3fbdee07a71eb80a45bde7d 100644
--- a/common/Kconfig.debug_ll
+++ b/common/Kconfig.debug_ll
@@ -239,6 +239,20 @@ config DEBUG_SOCFPGA_UART1
Say Y here if you want kernel low-level debugging support
on SOCFPGA(Arria 10) based platforms.
+config DEBUG_SOCFPGA_AGILEX5_UART0
+ bool "Use Agilex5 UART0 for low-level debug"
+ depends on ARCH_SOCFPGA_AGILEX5
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Agilex5 based platforms.
+
+config DEBUG_SOCFPGA_AGILEX5_UART1
+ bool "Use Agilex5 UART1 for low-level debug"
+ depends on ARCH_SOCFPGA_AGILEX5
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Agilex5 based platforms.
+
config DEBUG_STM32MP_UART
bool "Use STM32MP UART4 for low-level debug"
depends on ARCH_STM32
@@ -420,12 +434,15 @@ config DEBUG_SOCFPGA_UART_PHYS_ADDR
hex "Physical base address of debug UART" if DEBUG_LL
default 0xffc02000 if DEBUG_SOCFPGA_UART0
default 0xffc02100 if DEBUG_SOCFPGA_UART1
+ default 0x10c02000 if DEBUG_SOCFPGA_AGILEX5_UART0
+ default 0x10c02100 if DEBUG_SOCFPGA_AGILEX5_UART1
depends on ARCH_SOCFPGA
config DEBUG_SOCFPGA_UART_CLOCK
int "SoCFPGA UART debug clock" if DEBUG_LL
default 100000000 if ARCH_SOCFPGA_CYCLONE5
default 50000000 if ARCH_SOCFPGA_ARRIA10
+ default 100000000 if ARCH_SOCFPGA_AGILEX5
depends on ARCH_SOCFPGA
help
Choose UART root clock.
diff --git a/firmware/Kconfig b/firmware/Kconfig
index ae7bbdc71e3a37ae485d52c7719c4da150ebac40..76c47a9fe8715038ced200557ee56b359358f725 100644
--- a/firmware/Kconfig
+++ b/firmware/Kconfig
@@ -41,6 +41,9 @@ config FIRMWARE_IMX8MQ_ATF
config FIRMWARE_IMX93_ATF
bool
+config FIRMWARE_AGILEX5_ATF
+ bool
+
config FIRMWARE_IMX8MM_OPTEE
bool "install OP-TEE on i.MX8MM boards"
depends on FIRMWARE_IMX8MM_ATF && PBL_OPTEE
diff --git a/firmware/Makefile b/firmware/Makefile
index 7265c55c4253e91b9d3f8fa1cf4fb416ed459826..e01b6d4ee02d0eb9b04e765dc60d9dfea5a938a9 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -17,6 +17,7 @@ pbl-firmware-$(CONFIG_FIRMWARE_IMX8MN_ATF) += imx8mn-bl31.bin$(if $(CONFIG_FIRMW
pbl-firmware-$(CONFIG_FIRMWARE_IMX8MP_ATF) += imx8mp-bl31.bin$(if $(CONFIG_FIRMWARE_IMX8MP_OPTEE),-optee,)
pbl-firmware-$(CONFIG_FIRMWARE_IMX8MQ_ATF) += imx8mq-bl31.bin
pbl-firmware-$(CONFIG_FIRMWARE_IMX93_ATF) += imx93-bl31.bin$(if $(CONFIG_FIRMWARE_IMX93_OPTEE),-optee,)
+pbl-firmware-$(CONFIG_FIRMWARE_AGILEX5_ATF) += agilex5-bl31.bin
fw-external-$(CONFIG_FIRMWARE_IMX8MM_OPTEE) += imx8mm-bl32.bin
fw-external-$(CONFIG_FIRMWARE_IMX8MN_OPTEE) += imx8mn-bl32.bin
fw-external-$(CONFIG_FIRMWARE_IMX8MP_OPTEE) += imx8mp-bl32.bin
diff --git a/images/Makefile.socfpga b/images/Makefile.socfpga
index 7f95bed03297e616532ffb38cb36742b155146f5..807ca78e4ac8636382107f844eeb83ba9007a583 100644
--- a/images/Makefile.socfpga
+++ b/images/Makefile.socfpga
@@ -14,6 +14,14 @@ quiet_cmd_socfpga_image = SOCFPGA-IMG $@
$(obj)/%.socfpgaimg: $(obj)/% FORCE
$(call if_changed,socfpga_image)
+# %.hex - convert into Intel hex format
+# ----------------------------------------------------------------
+quiet_cmd_socfpga_objcopy = SOCFPGA-OBJCOPY $@
+ cmd_socfpga_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) -I binary -O ihex --change-address=0x0 $< $@
+
+$(obj)/%.hex: $(obj)/% FORCE
+ $(call if_changed,socfpga_objcopy)
+
# ----------------------- Cyclone5 based boards ---------------------------
pblb-$(CONFIG_MACH_SOCFPGA_ALTERA_SOCDK) += start_socfpga_socdk_xload
FILE_barebox-socfpga-socdk-xload.img = start_socfpga_socdk_xload.pblb.socfpgaimg
diff --git a/include/dt-bindings/clock/agilex5-clock.h b/include/dt-bindings/clock/agilex5-clock.h
new file mode 100644
index 0000000000000000000000000000000000000000..269108465387c0becb165d5fdc5d5eb4460ed9c8
--- /dev/null
+++ b/include/dt-bindings/clock/agilex5-clock.h
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019-2022, Intel Corporation
+ */
+
+#ifndef __AGILEX5_CLOCK_H
+#define __AGILEX5_CLOCK_H
+
+/* fixed rate clocks */
+#define AGILEX5_OSC1 0
+#define AGILEX5_CB_INTOSC_HS_DIV2_CLK 1
+#define AGILEX5_CB_INTOSC_LS_CLK 2
+#define AGILEX5_L4_SYS_FREE_CLK 3
+#define AGILEX5_F2S_FREE_CLK 4
+
+/* PLL clocks */
+#define AGILEX5_MAIN_PLL_CLK 5
+#define AGILEX5_MAIN_PLL_C0_CLK 6
+#define AGILEX5_MAIN_PLL_C1_CLK 7
+#define AGILEX5_MAIN_PLL_C2_CLK 8
+#define AGILEX5_MAIN_PLL_C3_CLK 9
+#define AGILEX5_PERIPH_PLL_CLK 10
+#define AGILEX5_PERIPH_PLL_C0_CLK 11
+#define AGILEX5_PERIPH_PLL_C1_CLK 12
+#define AGILEX5_PERIPH_PLL_C2_CLK 13
+#define AGILEX5_PERIPH_PLL_C3_CLK 14
+#define AGILEX5_MPU_FREE_CLK 15
+#define AGILEX5_MPU_CCU_CLK 16
+#define AGILEX5_BOOT_CLK 17
+
+/* fixed factor clocks */
+#define AGILEX5_L3_MAIN_FREE_CLK 18
+#define AGILEX5_NOC_FREE_CLK 19
+#define AGILEX5_S2F_USR0_CLK 20
+#define AGILEX5_NOC_CLK 21
+#define AGILEX5_EMAC_A_FREE_CLK 22
+#define AGILEX5_EMAC_B_FREE_CLK 23
+#define AGILEX5_EMAC_PTP_FREE_CLK 24
+#define AGILEX5_GPIO_DB_FREE_CLK 25
+#define AGILEX5_SDMMC_FREE_CLK 26
+#define AGILEX5_S2F_USER0_FREE_CLK 27
+#define AGILEX5_S2F_USER1_FREE_CLK 28
+#define AGILEX5_PSI_REF_FREE_CLK 29
+
+/* Gate clocks */
+#define AGILEX5_MPU_CLK 30
+#define AGILEX5_MPU_PERIPH_CLK 31
+#define AGILEX5_L4_MAIN_CLK 32
+#define AGILEX5_L4_MP_CLK 33
+#define AGILEX5_L4_SP_CLK 34
+#define AGILEX5_CS_AT_CLK 35
+#define AGILEX5_CS_TRACE_CLK 36
+#define AGILEX5_CS_PDBG_CLK 37
+#define AGILEX5_CS_TIMER_CLK 38
+#define AGILEX5_S2F_USER0_CLK 39
+#define AGILEX5_EMAC0_CLK 40
+#define AGILEX5_EMAC1_CLK 41
+#define AGILEX5_EMAC2_CLK 42
+#define AGILEX5_EMAC_PTP_CLK 43
+#define AGILEX5_GPIO_DB_CLK 44
+#define AGILEX5_NAND_CLK 45
+#define AGILEX5_PSI_REF_CLK 46
+#define AGILEX5_S2F_USER1_CLK 47
+#define AGILEX5_SDMMC_CLK 48
+#define AGILEX5_SPI_M_CLK 49
+#define AGILEX5_USB_CLK 50
+#define AGILEX5_NAND_X_CLK 51
+#define AGILEX5_NAND_ECC_CLK 52
+#define AGILEX5_NUM_CLKS 53
+
+#endif /* __AGILEX5_CLOCK_H */
diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h
new file mode 100644
index 0000000000000000000000000000000000000000..e15fa3d4da21a4da61c759bf26d66a9f4d769210
--- /dev/null
+++ b/include/linux/intel-smc.h
@@ -0,0 +1,545 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017-2018, Intel Corporation
+ */
+
+#ifndef __INTEL_SMC_H
+#define __INTEL_SMC_H
+
+#include <linux/arm-smccc.h>
+#include <linux/bitops.h>
+
+/*
+ * This file defines the Secure Monitor Call (SMC) message protocol used for
+ * service layer driver in normal world (EL1) to communicate with secure
+ * monitor software in Secure Monitor Exception Level 3 (EL3).
+ *
+ * This file is shared with secure firmware (FW) which is out of u-boot tree.
+ *
+ * An ARM SMC instruction takes a function identifier and up to 6 64-bit
+ * register values as arguments, and can return up to 4 64-bit register
+ * values. The operation of the secure monitor is determined by the parameter
+ * values passed in through registers.
+
+ * EL1 and EL3 communicates pointer as physical address rather than the
+ * virtual address.
+ */
+
+/*
+ * Functions specified by ARM SMC Calling convention:
+ *
+ * FAST call executes atomic operations, returns when the requested operation
+ * has completed.
+ * STD call starts a operation which can be preempted by a non-secure
+ * interrupt. The call can return before the requested operation has
+ * completed.
+ *
+ * a0..a7 is used as register names in the descriptions below, on arm32
+ * that translates to r0..r7 and on arm64 to w0..w7.
+ */
+
+#define INTEL_SIP_SMC_STD_CALL_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_SIP, (func_num))
+
+#define INTEL_SIP_SMC_FAST_CALL_VAL(func_num) \
+ ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \
+ ARM_SMCCC_OWNER_SIP, (func_num))
+
+/*
+ * Return values in INTEL_SIP_SMC_* call
+ *
+ * INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION:
+ * Secure monitor software doesn't recognize the request.
+ *
+ * INTEL_SIP_SMC_STATUS_OK:
+ * SMC call completed successfully,
+ * In case of FPGA configuration write operation, it means secure monitor
+ * software can accept the next chunk of FPGA configuration data.
+ *
+ * INTEL_SIP_SMC_STATUS_BUSY:
+ * In case of FPGA configuration write operation, it means secure monitor
+ * software is still processing previous data & can't accept the next chunk
+ * of data. Service driver needs to issue
+ * INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE call to query the
+ * completed block(s).
+ *
+ * INTEL_SIP_SMC_STATUS_ERROR:
+ * There is error during the SMC call process.
+ *
+ * INTEL_SIP_SMC_REG_ERROR:
+ * There is error during a read or write operation of the protected
+ * registers.
+ */
+#define INTEL_SIP_SMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF
+#define INTEL_SIP_SMC_STATUS_OK 0x0
+#define INTEL_SIP_SMC_STATUS_BUSY 0x1
+#define INTEL_SIP_SMC_STATUS_REJECTED 0x2
+#define INTEL_SIP_SMC_STATUS_ERROR 0x4
+#define INTEL_SIP_SMC_REG_ERROR 0x5
+#define INTEL_SIP_SMC_RSU_ERROR 0x7
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_START
+ *
+ * Sync call used by service driver at EL1 to request the FPGA in EL3 to
+ * be prepare to receive a new configuration.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_START.
+ * a1: flag for full or partial configuration
+ * 0 full reconfiguration.
+ * 1 partial reconfiguration.
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START 1
+#define INTEL_SIP_SMC_FPGA_CONFIG_START \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_START)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_WRITE
+ *
+ * Async call used by service driver at EL1 to provide FPGA configuration data
+ * to secure world.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_WRITE.
+ * a1: 64bit physical address of the configuration data memory block
+ * a2: Size of configuration data block.
+ * a3-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY,
+ * INTEL_SIP_SMC_STATUS_REJECTED or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1: 64bit physical address of 1st completed memory block if any completed
+ * block, otherwise zero value.
+ * a2: 64bit physical address of 2nd completed memory block if any completed
+ * block, otherwise zero value.
+ * a3: 64bit physical address of 3rd completed memory block if any completed
+ * block, otherwise zero value.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE 2
+#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE \
+ INTEL_SIP_SMC_STD_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_WRITE)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE
+ *
+ * Sync call used by service driver at EL1 to track the completed write
+ * transactions. This request is called after INTEL_SIP_SMC_FPGA_CONFIG_WRITE
+ * call returns INTEL_SIP_SMC_STATUS_BUSY.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY or
+ * INTEL_SIP_SMC_STATUS_ERROR.
+ * a1: 64bit physical address of 1st completed memory block.
+ * a2: 64bit physical address of 2nd completed memory block if
+ * any completed block, otherwise zero value.
+ * a3: 64bit physical address of 3rd completed memory block if
+ * any completed block, otherwise zero value.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE 3
+#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE \
+INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_COMPLETED_WRITE)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_ISDONE
+ *
+ * Sync call used by service driver at EL1 to inform secure world that all
+ * data are sent, to check whether or not the secure world had completed
+ * the FPGA configuration process.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_ISDONE.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK, INTEL_SIP_SMC_STATUS_BUSY or
+ * INTEL_SIP_SMC_STATUS_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE 4
+#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_ISDONE)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM
+ *
+ * Sync call used by service driver at EL1 to query the physical address of
+ * memory block reserved by secure monitor software.
+ *
+ * Call register usage:
+ * a0:INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1: start of physical address of reserved memory block.
+ * a2: size of reserved memory block.
+ * a3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM 5
+#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_GET_MEM)
+
+/*
+ * Request INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK
+ *
+ * For SMC loop-back mode only, used for internal integration, debugging
+ * or troubleshooting.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK.
+ * a1-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK 6
+#define INTEL_SIP_SMC_FPGA_CONFIG_LOOPBACK \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_FPGA_CONFIG_LOOPBACK)
+
+/*
+ * Request INTEL_SIP_SMC_REG_READ
+ *
+ * Read a protected register using SMCCC
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_READ.
+ * a1: register address.
+ * a2-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+ * a1: Value in the register
+ * a2-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_READ 7
+#define INTEL_SIP_SMC_REG_READ \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_READ)
+
+/*
+ * Request INTEL_SIP_SMC_REG_WRITE
+ *
+ * Write a protected register using SMCCC
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_WRITE.
+ * a1: register address
+ * a2: value to program into register.
+ * a3-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+ * a1-3: not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_WRITE 8
+#define INTEL_SIP_SMC_REG_WRITE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_WRITE)
+
+/*
+ * Request INTEL_SIP_SMC_FUNCID_REG_UPDATE
+ *
+ * Update one or more bits in a protected register using a
+ * read-modify-write operation.
+ *
+ * Call register usage:
+ * a0: INTEL_SIP_SMC_REG_UPDATE.
+ * a1: register address
+ * a2: Write Mask.
+ * a3: Value to write.
+ * a4-7: not used.
+ *
+ * Return status:
+ * a0: INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+ * a1-3: Not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_REG_UPDATE 9
+#define INTEL_SIP_SMC_REG_UPDATE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_REG_UPDATE)
+
+/*
+* Request INTEL_SIP_SMC_RSU_STATUS
+*
+* Sync call used by service driver at EL1 to query the RSU status
+*
+* Call register usage:
+* a0 INTEL_SIP_SMC_RSU_STATUS
+* a1-7 not used
+*
+* Return status
+* a0: Current Image
+* a1: Last Failing Image
+* a2: Version [width 32 bit] | State [width 32 bit]
+* a3: Error details [width 32 bit] | Error location [width 32 bit]
+*
+* Or
+*
+* a0: INTEL_SIP_SMC_RSU_ERROR
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_STATUS 11
+#define INTEL_SIP_SMC_RSU_STATUS \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_STATUS)
+
+/*
+* Request INTEL_SIP_SMC_RSU_UPDATE
+*
+* Sync call used by service driver at EL1 to tell you next reboot is RSU_UPDATE
+*
+* Call register usage:
+* a0 INTEL_SIP_SMC_RSU_UPDATE
+* a1 64bit physical address of the configuration data memory in flash
+* a2-7 not used
+*
+* Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_UPDATE 12
+#define INTEL_SIP_SMC_RSU_UPDATE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_UPDATE)
+
+/*
+ * Request INTEL_SIP_SMC_ECC_DBE
+ *
+ * Sync call used by service driver at EL1 alert EL3 that a Double Bit
+ * ECC error has occurred.
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_ECC_DBE
+ * a1 SysManager Double Bit Error value
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_ECC_DBE 13
+#define INTEL_SIP_SMC_ECC_DBE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_ECC_DBE)
+
+/*
+* Request INTEL_SIP_SMC_RSU_NOTIFY
+*
+* Sync call used by service driver at EL1 to report HPS software execution stage
+*
+* Call register usage:
+* a0 INTEL_SIP_SMC_RSU_NOTIFY
+* a1 32bit HPS software execution stage
+* a2-7 not used
+*
+* Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_REG_ERROR.
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_NOTIFY 14
+#define INTEL_SIP_SMC_RSU_NOTIFY \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_NOTIFY)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_RETRY_COUNTER
+ *
+ * Sync call used by service driver at EL1 to query the RSU retry counter
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_RETRY_COUNTER
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_RSU_ERROR.
+ * a1 retry counter
+*/
+#define INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER 15
+#define INTEL_SIP_SMC_RSU_RETRY_COUNTER \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_RETRY_COUNTER)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_DCMF_VERSION
+ *
+ * Sync call used by service driver at EL1 to query DCMF version
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_DCMF_VERSION
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1 dcmf1 version | dcmf0 version
+ * a2 dcmf3 version | dcmf2 version
+ *
+ * Or
+ *
+ * a0 INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION 16
+#define INTEL_SIP_SMC_RSU_DCMF_VERSION \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_VERSION)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION
+ *
+ * Sync call used by SSBL (EL2) to copy DCMF version to ATF memory
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION
+ * a1 dcmf1 version | dcmf0 version
+ * a2 dcmf3 version | dcmf2 version
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION 17
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_VERSION \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_VERSION)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_MAX_RETRY
+ *
+ * Sync call used by service driver at EL1 to query max_retry parameter
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_MAX_RETRY
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1 max_retry
+ *
+ * Or
+ *
+ * a0 INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY 18
+#define INTEL_SIP_SMC_RSU_MAX_RETRY \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_MAX_RETRY)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_COPY_MAX_RETRY
+ *
+ * Sync call used by SSBL (EL2) to copy RSU 'max retry' to ATF memory
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_COPY_MAX_RETRY
+ * a1 max retry
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY 19
+#define INTEL_SIP_SMC_RSU_COPY_MAX_RETRY \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_MAX_RETRY)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_DCMF_STATUS
+ *
+ * Sync call used by service driver at EL1 to query DCMF status
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_DCMF_STATUS
+ * a1-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ * a1 dcmf3 status | dcmf2 status | dcmf1 status | dcmf0 status
+ *
+ * Or
+ *
+ * a0 INTEL_SIP_SMC_RSU_ERROR
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS 20
+#define INTEL_SIP_SMC_RSU_DCMF_STATUS \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_DCMF_STATUS)
+
+/*
+ * Request INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS
+ *
+ * Sync call used by SSBL (EL2) to copy RSU 'dcmf status' to ATF memory
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS
+ * a1 dcmf status
+ * a2-7 not used
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS 21
+#define INTEL_SIP_SMC_RSU_COPY_DCMF_STATUS \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_RSU_COPY_DCMF_STATUS)
+
+/*
+ * Request INTEL_SIP_SMC_HPS_SET_BRIDGES
+ *
+ * Enable/disable the SoC FPGA bridges
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_HPS_SET_BRIDGES
+ * a1 Set bridges status:
+ * Bit 0: 0 - Disable, 1 - Enable
+ * Bit 1: 1 - Has mask value in a2
+ * a2 Mask value
+ * Bit 0: soc2fpga
+ * Bit 1: lwhps2fpga
+ * Bit 2: fpga2soc
+ * Bit 3: f2sdram0 (For Stratix 10 only)
+ * Bit 4: f2sdram1 (For Stratix 10 only)
+ * Bit 5: f2sdram2 (For Stratix 10 only)
+ * a3-7 not used
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK
+ */
+#define INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES 50
+#define INTEL_SIP_SMC_HPS_SET_BRIDGES \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_HPS_SET_BRIDGES)
+
+/*
+ * Request INTEL_SIP_SMC_MBOX_SEND_CMD
+ *
+ * Send mailbox command to SDM
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_MBOX_SEND_CMD
+ * a1 Mailbox command
+ * a2 64bit physical address pointer to command's arguments
+ * a3 Length of the argument
+ * a4 Urgent command:
+ * 0 - Disable
+ * 1 - Enable
+ * a5 64bit physical address pointer to a buffer for receiving responses
+ * a6 Length of the buffer
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR
+ * a1 Status of mailbox response
+ * a2 Received length in the buffer
+ */
+#define INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD 60
+#define INTEL_SIP_SMC_MBOX_SEND_CMD \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_MBOX_SEND_CMD)
+
+/*
+ * Request INTEL_SIP_SMC_GET_USERCODE
+ *
+ * Send mailbox command to get usercode from SDM
+ *
+ * Call register usage:
+ * a0 INTEL_SIP_SMC_GET_USERCODE
+ * a1-7 not used.
+ *
+ * Return status
+ * a0 INTEL_SIP_SMC_STATUS_OK or INTEL_SIP_SMC_STATUS_ERROR
+ * a1 User code
+ * a2-3 not used.
+ */
+#define INTEL_SIP_SMC_FUNCID_GET_USERCODE 61
+#define INTEL_SIP_SMC_GET_USERCODE \
+ INTEL_SIP_SMC_FAST_CALL_VAL(INTEL_SIP_SMC_FUNCID_GET_USERCODE)
+
+#endif
diff --git a/include/mach/socfpga/agilex5-clk.h b/include/mach/socfpga/agilex5-clk.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f689db4f0481c0ec353843b15387d94066337d5
--- /dev/null
+++ b/include/mach/socfpga/agilex5-clk.h
@@ -0,0 +1,266 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2019-2022 Intel Corporation <www.intel.com>
+ */
+
+#ifndef _CLK_AGILEX5_
+#define _CLK_AGILEX5_
+
+#ifndef __ASSEMBLY__
+#include <linux/bitops.h>
+#endif
+
+#define CLKMGR_INTOSC_HZ 400000000
+
+#define CM_REG_READL(plat, reg) \
+ readl((plat)->regs + (reg))
+
+#define CM_REG_WRITEL(plat, data, reg) \
+ writel(data, (plat)->regs + (reg))
+
+#define CM_REG_CLRBITS(plat, reg, clear) \
+ clrbits_le32((plat)->regs + (reg), (clear))
+
+#define CM_REG_SETBITS(plat, reg, set) \
+ setbits_le32((plat)->regs + (reg), (set))
+
+struct cm_config {
+ /* main group */
+ u32 main_pll_nocclk;
+ u32 main_pll_nocdiv;
+ u32 main_pll_pllglob;
+ u32 main_pll_fdbck;
+ u32 main_pll_pllc0;
+ u32 main_pll_pllc1;
+ u32 main_pll_pllc2;
+ u32 main_pll_pllc3;
+ u32 main_pll_pllm;
+
+ /* peripheral group */
+ u32 per_pll_emacctl;
+ u32 per_pll_gpiodiv;
+ u32 per_pll_pllglob;
+ u32 per_pll_fdbck;
+ u32 per_pll_pllc0;
+ u32 per_pll_pllc1;
+ u32 per_pll_pllc2;
+ u32 per_pll_pllc3;
+ u32 per_pll_pllm;
+
+ /* control group */
+ u32 ctl_emacactr;
+ u32 ctl_emacbctr;
+ u32 ctl_emacptpctr;
+ u32 ctl_gpiodbctr;
+ u32 ctl_s2fuser0ctr;
+ u32 ctl_s2fuser1ctr;
+ u32 ctl_psirefctr;
+ u32 ctl_usb31ctr;
+ u32 ctl_dsuctr;
+ u32 ctl_core01ctr;
+ u32 ctl_core23ctr;
+ u32 ctl_core2ctr;
+ u32 ctl_core3ctr;
+
+
+ /* incoming clock */
+ u32 hps_osc_clk_hz;
+ u32 fpga_clk_hz;
+ u32 spare[3];
+};
+
+/* Clock Manager registers */
+#define CLKMGR_CTRL 0
+#define CLKMGR_STAT 4
+#define CLKMGR_TESTIOCTRL 8
+#define CLKMGR_INTRGEN 0x0c
+#define CLKMGR_INTRMSK 0x10
+#define CLKMGR_INTRCLR 0x14
+#define CLKMGR_INTRSTS 0x18
+#define CLKMGR_INTRSTK 0x1c
+#define CLKMGR_INTRRAW 0x20
+
+/* Clock Manager Main PPL group registers */
+#define CLKMGR_MAINPLL_EN 0x24
+#define CLKMGR_MAINPLL_ENS 0x28
+#define CLKMGR_MAINPLL_ENR 0x2c
+#define CLKMGR_MAINPLL_BYPASS 0x30
+#define CLKMGR_MAINPLL_BYPASSS 0x34
+#define CLKMGR_MAINPLL_BYPASSR 0x38
+#define CLKMGR_MAINPLL_NOCCLK 0x40
+#define CLKMGR_MAINPLL_NOCDIV 0x44
+#define CLKMGR_MAINPLL_PLLGLOB 0x48
+#define CLKMGR_MAINPLL_FDBCK 0x4c
+#define CLKMGR_MAINPLL_MEM 0x50
+#define CLKMGR_MAINPLL_MEMSTAT 0x54
+#define CLKMGR_MAINPLL_VCOCALIB 0x58
+#define CLKMGR_MAINPLL_PLLC0 0x5c
+#define CLKMGR_MAINPLL_PLLC1 0x60
+#define CLKMGR_MAINPLL_PLLC2 0x64
+#define CLKMGR_MAINPLL_PLLC3 0x68
+#define CLKMGR_MAINPLL_PLLM 0x6c
+#define CLKMGR_MAINPLL_FHOP 0x70
+#define CLKMGR_MAINPLL_SSC 0x74
+#define CLKMGR_MAINPLL_LOSTLOCK 0x78
+
+/* Clock Manager Peripheral PPL group registers */
+#define CLKMGR_PERPLL_EN 0x7c
+#define CLKMGR_PERPLL_ENS 0x80
+#define CLKMGR_PERPLL_ENR 0x84
+#define CLKMGR_PERPLL_BYPASS 0x88
+#define CLKMGR_PERPLL_BYPASSS 0x8c
+#define CLKMGR_PERPLL_BYPASSR 0x90
+#define CLKMGR_PERPLL_EMACCTL 0x94
+#define CLKMGR_PERPLL_GPIODIV 0x98
+#define CLKMGR_PERPLL_PLLGLOB 0x9c
+#define CLKMGR_PERPLL_FDBCK 0xa0
+#define CLKMGR_PERPLL_MEM 0xa4
+#define CLKMGR_PERPLL_MEMSTAT 0xa8
+#define CLKMGR_PERPLL_VCOCALIB 0xac
+#define CLKMGR_PERPLL_PLLC0 0xb0
+#define CLKMGR_PERPLL_PLLC1 0xb4
+#define CLKMGR_PERPLL_PLLC2 0xb8
+#define CLKMGR_PERPLL_PLLC3 0xbc
+#define CLKMGR_PERPLL_PLLM 0xc0
+#define CLKMGR_PERPLL_FHOP 0xc4
+#define CLKMGR_PERPLL_SSC 0xc8
+#define CLKMGR_PERPLL_LOSTLOCK 0xcc
+
+/* Clock Manager Control group registers */
+#define CLKMGR_CTL_JTAG 0xd0
+#define CLKMGR_CTL_EMACACTR 0xd4
+#define CLKMGR_CTL_EMACBCTR 0xd8
+#define CLKMGR_CTL_EMACPTPCTR 0xdc
+#define CLKMGR_CTL_GPIODBCTR 0xe0
+#define CLKMGR_CTL_S2FUSER0CTR 0xe8
+#define CLKMGR_CTL_S2FUSER1CTR 0xec
+#define CLKMGR_CTL_PSIREFCTR 0xf0
+#define CLKMGR_CTL_EXTCNTRST 0xf4
+#define CLKMGR_CTL_USB31CTR 0xf8
+#define CLKMGR_CTL_DSUCTR 0xfc
+#define CLKMGR_CTL_CORE01CTR 0x100
+#define CLKMGR_CTL_CORE23CTR 0x104
+#define CLKMGR_CTL_CORE2CTR 0x108
+#define CLKMGR_CTL_CORE3CTR 0x10C
+
+#define CLKMGR_CTRL_BOOTMODE BIT(0)
+
+#define CLKMGR_STAT_BUSY BIT(0)
+#define CLKMGR_STAT_MAINPLL_LOCKED BIT(8)
+#define CLKMGR_STAT_MAIN_TRANS BIT(9)
+#define CLKMGR_STAT_PERPLL_LOCKED BIT(16)
+#define CLKMGR_STAT_PERF_TRANS BIT(17)
+#define CLKMGR_STAT_BOOTMODE BIT(24)
+#define CLKMGR_STAT_BOOTCLKSRC BIT(25)
+
+#define CLKMGR_STAT_ALLPLL_LOCKED_MASK \
+ (CLKMGR_STAT_MAINPLL_LOCKED | CLKMGR_STAT_PERPLL_LOCKED)
+
+#define CLKMGR_INTER_MAINPLLLOCKED_MASK 0x00000001
+#define CLKMGR_INTER_PERPLLLOCKED_MASK 0x00000002
+#define CLKMGR_INTER_MAINPLLLOST_MASK 0x00000004
+#define CLKMGR_INTER_PERPLLLOST_MASK 0x00000008
+
+#define CLKMGR_CLKSRC_MASK GENMASK(18, 16)
+#define CLKMGR_CLKSRC_OFFSET 16
+#define CLKMGR_CLKSRC_MAIN 0
+#define CLKMGR_CLKSRC_PER 1
+#define CLKMGR_CLKSRC_OSC1 2
+#define CLKMGR_CLKSRC_INTOSC 3
+#define CLKMGR_CLKSRC_FPGA 4
+#define CLKMGR_CLKCNT_MSK GENMASK(10, 0)
+
+#define CLKMGR_BYPASS_MAINPLL_ALL 0xf6
+#define CLKMGR_BYPASS_PERPLL_ALL 0xef
+
+#define CLKMGR_NOCDIV_SOFTPHY_DIV_ONE 0
+#define CLKMGR_NOCDIV_SOFTPHY_DIV_TWO 1
+#define CLKMGR_NOCDIV_SOFTPHY_DIV_FOUR 2
+#define CLKMGR_NOCDIV_L4SYSFREECLK_OFFSET 0
+#define CLKMGR_NOCDIV_L4MPCLK_OFFSET 4
+#define CLKMGR_NOCDIV_L4SPCLK_OFFSET 6
+#define CLKMGR_NOCDIV_SOFTPHY_OFFSET 16
+#define CLKMGR_NOCDIV_CCU_OFFSET 18
+#define CLKMGR_NOCDIV_MPUPERIPH_OFFSET 20
+#define CLKMGR_NOCDIV_CSATCLK_OFFSET 24
+#define CLKMGR_NOCDIV_CSTRACECLK_OFFSET 26
+#define CLKMGR_NOCDIV_CSPDBGCLK_OFFSET 28
+#define CLKMGR_NOCDIV_DIVIDER_MASK 0x3
+
+#define CLKMGR_PLLGLOB_PD_MASK BIT(0)
+#define CLKMGR_PLLGLOB_RST_MASK BIT(1)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_MASK GENMASK(11, 8)
+#define CLKMGR_PLLGLOB_DREFCLKDIV_MASK GENMASK(13, 12)
+#define CLKMGR_PLLGLOB_REFCLKDIV_MASK GENMASK(13, 8)
+#define CLKMGR_PLLGLOB_MODCLKDIV_MASK GENMASK(24, 27)
+#define CLKMGR_PLLGLOB_AREFCLKDIV_OFFSET 8
+#define CLKMGR_PLLGLOB_DREFCLKDIV_OFFSET 12
+#define CLKMGR_PLLGLOB_REFCLKDIV_OFFSET 8
+#define CLKMGR_PLLGLOB_MODCLKDIV_OFFSET 24
+#define CLKMGR_PLLGLOB_VCO_PSRC_MASK GENMASK(17, 16)
+#define CLKMGR_PLLGLOB_VCO_PSRC_OFFSET 16
+#define CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK BIT(29)
+
+#define CLKMGR_VCO_PSRC_EOSC1 0
+#define CLKMGR_VCO_PSRC_INTOSC 1
+#define CLKMGR_VCO_PSRC_F2S 2
+
+#define CLKMGR_MEM_REQ_SET_MSK BIT(24)
+#define CLKMGR_MEM_WR_SET_MSK BIT(25)
+#define CLKMGR_MEM_ERR_MSK BIT(26)
+#define CLKMGR_MEM_WDAT_LSB_OFFSET 16
+#define CLKMGR_MEM_ADDR_MASK GENMASK(15, 0)
+#define CLKMGR_MEM_ADDR_START 0x00004000
+
+#define CLKMGR_PLLCX_EN_SET_MSK BIT(27)
+#define CLKMGR_PLLCX_MUTE_SET_MSK BIT(28)
+
+#define CLKMGR_VCOCALIB_MSCNT_MASK GENMASK(23, 16)
+#define CLKMGR_VCOCALIB_MSCNT_OFFSET 16
+#define CLKMGR_VCOCALIB_HSCNT_MASK GENMASK(9, 0)
+#define CLKMGR_VCOCALIB_MSCNT_CONST 100
+#define CLKMGR_VCOCALIB_HSCNT_CONST 4
+
+#define CLKMGR_PLLM_MDIV_MASK GENMASK(9, 0)
+
+#define CLKMGR_LOSTLOCK_SET_MASK BIT(0)
+
+#define CLKMGR_PERPLLGRP_EN_SDMMCCLK_MASK BIT(5)
+#define CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_OFFSET 26
+#define CLKMGR_PERPLLGRP_EMACCTL_EMAC0SELB_MASK BIT(26)
+#define CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_OFFSET 27
+#define CLKMGR_PERPLLGRP_EMACCTL_EMAC1SELB_MASK BIT(27)
+#define CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_OFFSET 28
+#define CLKMGR_PERPLLGRP_EMACCTL_EMAC2SELB_MASK BIT(28)
+
+#define CLKMGR_CTL_EMACCTR_SRC_OFFSET 16
+#define CLKMGR_CTL_EMACCTR_SRC_MASK GENMASK(18, 16)
+#define CLKMGR_CTL_EMACCTR_CNT_OFFSET 0
+#define CLKMGR_CTL_EMACCTR_CNT_MASK GENMASK(10, 0)
+
+#define CLKMGR_CTL_EXTCNTRST_EMACACNTRST BIT(0)
+#define CLKMGR_CTL_EXTCNTRST_EMACBCNTRST BIT(1)
+#define CLKMGR_CTL_EXTCNTRST_EMACPTPCNTRST BIT(2)
+#define CLKMGR_CTL_EXTCNTRST_GPIODBCNTRST BIT(3)
+#define CLKMGR_CTL_EXTCNTRST_S2FUSER0CNTRST BIT(5)
+#define CLKMGR_CTL_EXTCNTRST_S2FUSER1CNTRST BIT(6)
+#define CLKMGR_CTL_EXTCNTRST_PSIREFCNTRST BIT(7)
+#define CLKMGR_CTL_EXTCNTRST_USB31REFCNTRST BIT(8)
+#define CLKMGR_CTL_EXTCNTRST_DSUCNTRST BIT(10)
+#define CLKMGR_CTL_EXTCNTRST_CORE01CNTRST BIT(11)
+#define CLKMGR_CTL_EXTCNTRST_CORE2CNTRST BIT(12)
+#define CLKMGR_CTL_EXTCNTRST_CORE3CNTRST BIT(13)
+#define CLKMGR_CTL_EXTCNTRST_ALLCNTRST \
+ (CLKMGR_CTL_EXTCNTRST_EMACACNTRST | \
+ CLKMGR_CTL_EXTCNTRST_EMACBCNTRST | \
+ CLKMGR_CTL_EXTCNTRST_EMACPTPCNTRST | \
+ CLKMGR_CTL_EXTCNTRST_GPIODBCNTRST | \
+ CLKMGR_CTL_EXTCNTRST_S2FUSER0CNTRST | \
+ CLKMGR_CTL_EXTCNTRST_S2FUSER1CNTRST | \
+ CLKMGR_CTL_EXTCNTRST_PSIREFCNTRST | \
+ CLKMGR_CTL_EXTCNTRST_USB31REFCNTRST | \
+ CLKMGR_CTL_EXTCNTRST_DSUCNTRST | \
+ CLKMGR_CTL_EXTCNTRST_CORE01CNTRST | \
+ CLKMGR_CTL_EXTCNTRST_CORE2CNTRST | \
+ CLKMGR_CTL_EXTCNTRST_CORE3CNTRST)
+#endif /* _CLK_AGILEX5_ */
diff --git a/include/mach/socfpga/atf.h b/include/mach/socfpga/atf.h
new file mode 100644
index 0000000000000000000000000000000000000000..a1ae878015bc48613cbdca73ac971f3f3dd844fe
--- /dev/null
+++ b/include/mach/socfpga/atf.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef ATF_H_
+#define ATF_H_
+
+#include <linux/sizes.h>
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <asm/system.h>
+
+#define AGILEX5_ATF_BL31_BASE_ADDR 0x80000000
+#define AGILEX5_ATF_BL33_BASE_ADDR 0x80200000
+
+#endif
diff --git a/include/mach/socfpga/generic.h b/include/mach/socfpga/generic.h
index 40224897c1d2e05b934cd49963ac4ddeaeb28a25..673ccf90a19cda93b0856b7e494c5e519a00b83c 100644
--- a/include/mach/socfpga/generic.h
+++ b/include/mach/socfpga/generic.h
@@ -99,6 +99,9 @@ static inline void arria10_kick_l4wd0(void) {}
static inline void arria10_watchdog_disable(void) {}
#endif
+int agilex5_clk_init(void);
+void __noreturn agilex5_load_and_start_image_via_tfa(unsigned long memsize);
+
static inline void __udelay(unsigned us)
{
volatile unsigned int i;
diff --git a/include/mach/socfpga/init.h b/include/mach/socfpga/init.h
index c0e073ee1347cb4d76d74aeb3f513b1764996a59..06c480fe42f131d4f785643cd30e58780b3a0e52 100644
--- a/include/mach/socfpga/init.h
+++ b/include/mach/socfpga/init.h
@@ -5,4 +5,6 @@
void arria10_cpu_lowlevel_init(void);
+void socfpga_agilex5_cpu_lowlevel_init(void);
+
#endif
diff --git a/include/mach/socfpga/mailbox_s10.h b/include/mach/socfpga/mailbox_s10.h
new file mode 100644
index 0000000000000000000000000000000000000000..195e913d9228b51e4c91eb88932a9a3017c5deb1
--- /dev/null
+++ b/include/mach/socfpga/mailbox_s10.h
@@ -0,0 +1,199 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2017-2023 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef _MAILBOX_S10_H_
+#define _MAILBOX_S10_H_
+
+/* user define barebox ID */
+#include <linux/bitops.h>
+#define MBOX_CLIENT_ID_BAREBOX 0x2
+#define MBOX_ID_BAREBOX 0x2
+
+#define MBOX_CMD_DIRECT 0
+#define MBOX_CMD_INDIRECT 1
+
+#define MBOX_MAX_CMD_INDEX 2047
+#define MBOX_CMD_BUFFER_SIZE 32
+#define MBOX_RESP_BUFFER_SIZE 16
+
+#define MBOX_HDR_CMD_LSB 0
+#define MBOX_HDR_CMD_MSK (BIT(11) - 1)
+#define MBOX_HDR_I_LSB 11
+#define MBOX_HDR_I_MSK BIT(11)
+#define MBOX_HDR_LEN_LSB 12
+#define MBOX_HDR_LEN_MSK 0x007FF000
+#define MBOX_HDR_ID_LSB 24
+#define MBOX_HDR_ID_MSK 0x0F000000
+#define MBOX_HDR_CLIENT_LSB 28
+#define MBOX_HDR_CLIENT_MSK 0xF0000000
+
+/* Interrupt flags */
+#define MBOX_FLAGS_INT_COE BIT(0) /* COUT update interrupt enable */
+#define MBOX_FLAGS_INT_RIE BIT(1) /* RIN update interrupt enable */
+#define MBOX_FLAGS_INT_UAE BIT(8) /* Urgent ACK interrupt enable */
+#define MBOX_ALL_INTRS (MBOX_FLAGS_INT_COE | \
+ MBOX_FLAGS_INT_RIE | \
+ MBOX_FLAGS_INT_UAE)
+
+/* Status */
+#define MBOX_STATUS_UA_MSK BIT(8)
+
+#define MBOX_CMD_HEADER(client, id, len, indirect, cmd) \
+ ((((cmd) << MBOX_HDR_CMD_LSB) & MBOX_HDR_CMD_MSK) | \
+ (((indirect) << MBOX_HDR_I_LSB) & MBOX_HDR_I_MSK) | \
+ (((len) << MBOX_HDR_LEN_LSB) & MBOX_HDR_LEN_MSK) | \
+ (((id) << MBOX_HDR_ID_LSB) & MBOX_HDR_ID_MSK) | \
+ (((client) << MBOX_HDR_CLIENT_LSB) & MBOX_HDR_CLIENT_MSK))
+
+#define MBOX_RESP_ERR_GET(resp) \
+ (((resp) & MBOX_HDR_CMD_MSK) >> MBOX_HDR_CMD_LSB)
+#define MBOX_RESP_LEN_GET(resp) \
+ (((resp) & MBOX_HDR_LEN_MSK) >> MBOX_HDR_LEN_LSB)
+#define MBOX_RESP_ID_GET(resp) \
+ (((resp) & MBOX_HDR_ID_MSK) >> MBOX_HDR_ID_LSB)
+#define MBOX_RESP_CLIENT_GET(resp) \
+ (((resp) & MBOX_HDR_CLIENT_MSK) >> MBOX_HDR_CLIENT_LSB)
+
+/* Response error list */
+enum ALT_SDM_MBOX_RESP_CODE {
+ /* CMD completed successfully, but check resp ARGS for any errors */
+ MBOX_RESP_STATOK = 0,
+ /* CMD is incorrectly formatted in some way */
+ MBOX_RESP_INVALID_COMMAND = 1,
+ /* BootROM Command code not undesrtood */
+ MBOX_RESP_UNKNOWN_BR = 2,
+ /* CMD code not recognized by firmware */
+ MBOX_RESP_UNKNOWN = 3,
+ /* Length setting is not a valid length for this CMD type */
+ MBOX_RESP_INVALID_LEN = 4,
+ /* Indirect setting is not valid for this CMD type */
+ MBOX_RESP_INVALID_INDIRECT_SETTING = 5,
+ /* HW source which is not allowed to send CMD type */
+ MBOX_RESP_CMD_INVALID_ON_SRC = 6,
+ /* Client with ID not associated with any running PR CMD tries to run
+ * RECONFIG_DATA RECONFIG_STATUS and accessing QSPI / SDMMC using ID
+ * without exclusive access
+ */
+ MBOX_RESP_CLIENT_ID_NO_MATCH = 8,
+ /* Address provided to the system is invalid (alignment, range
+ * permission)
+ */
+ MBOX_RESP_INVALID_ADDR = 0x9,
+ /* Signature authentication failed */
+ MBOX_RESP_AUTH_FAIL = 0xA,
+ /* CMD timed out */
+ MBOX_RESP_TIMEOUT = 0xB,
+ /* HW (i.e. QSPI) is not ready (initialized or configured) */
+ MBOX_RESP_HW_NOT_RDY = 0xC,
+ /* Function is not supported in this firmware */
+ MBOX_FUNC_NOT_SUPPORTED = 0xF,
+ /* Invalid license for IID registration */
+ MBOX_RESP_PUF_ACCCES_FAILED = 0x80,
+ MBOX_PUF_ENROLL_DISABLE = 0x81,
+ MBOX_RESP_PUF_ENROLL_FAIL = 0x82,
+ MBOX_RESP_PUF_RAM_TEST_FAIL = 0x83,
+ MBOX_RESP_ATTEST_CERT_GEN_FAIL = 0x84,
+ /* Operation not allowed under current security settings */
+ MBOX_RESP_NOT_ALLOWED_UNDER_SECURITY_SETTINGS = 0x85,
+ MBOX_RESP_PUF_TRNG_FAIL = 0x86,
+ MBOX_RESP_FUSE_ALREADY_BLOWN = 0x87,
+ MBOX_RESP_INVALID_SIGNATURE = 0x88,
+ MBOX_RESP_INVALID_HASH = 0x8b,
+ MBOX_RESP_INVALID_CERTIFICATE = 0x91,
+ /* Indicates that the device (FPGA or HPS) is not configured */
+ MBOX_RESP_NOT_CONFIGURED = 0x100,
+ /* Indicates that the device is busy */
+ MBOX_RESP_DEVICE_BUSY = 0x1FF,
+ /* Indicates that there is no valid response available */
+ MBOX_RESP_NO_VALID_RESP_AVAILABLE = 0x2FF,
+ /* General Error */
+ MBOX_RESP_ERROR = 0x3FF,
+};
+
+/* Mailbox command list */
+#define MBOX_RESTART 2
+#define MBOX_CONFIG_STATUS 4
+#define MBOX_RECONFIG 6
+#define MBOX_RECONFIG_MSEL 7
+#define MBOX_RECONFIG_DATA 8
+#define MBOX_RECONFIG_STATUS 9
+#define MBOX_VAB_SRC_CERT 11
+#define MBOX_GET_USERCODE 19
+#define MBOX_QSPI_OPEN 50
+#define MBOX_QSPI_CLOSE 51
+#define MBOX_QSPI_DIRECT 59
+#define MBOX_REBOOT_HPS 71
+#define MBOX_GET_SUBPARTITION_TABLE 90
+#define MBOX_RSU_STATUS 91
+#define MBOX_RSU_UPDATE 92
+#define MBOX_HPS_STAGE_NOTIFY 93
+#define MBOX_QSPI_GET_DEVICE_INFO 116 /* get QSPI size and erasesize */
+
+/* Mailbox response len */
+#define QSPI_GET_DEVICE_INFO_RESP_LEN 8
+
+/* Mailbox registers */
+#define MBOX_CIN 0 /* command valid offset */
+#define MBOX_ROUT 4 /* response output offset */
+#define MBOX_URG 8 /* urgent command */
+#define MBOX_FLAGS 0x0c /* interrupt enables */
+#define MBOX_COUT 0x20 /* command free offset */
+#define MBOX_RIN 0x24 /* respond valid offset */
+#define MBOX_STATUS 0x2c /* mailbox status */
+#define MBOX_CMD_BUF 0x40 /* circular command buffer */
+#define MBOX_RESP_BUF 0xc0 /* circular response buffer */
+#define MBOX_DOORBELL_TO_SDM 0x400 /* Doorbell to SDM */
+#define MBOX_DOORBELL_FROM_SDM 0x480 /* Doorbell from SDM */
+
+/* Status and bit information returned by RECONFIG_STATUS */
+#define RECONFIG_STATUS_RESPONSE_LEN 6
+#define RECONFIG_STATUS_STATE 0
+#define RECONFIG_STATUS_PIN_STATUS 2
+#define RECONFIG_STATUS_SOFTFUNC_STATUS 3
+
+/* Macros for specifying number of arguments in mailbox command */
+#define MBOX_NUM_ARGS(n, b) (((n) & 0xFF) << (b))
+#define MBOX_DIRECT_COUNT(n) MBOX_NUM_ARGS((n), 0)
+#define MBOX_ARG_DESC_COUNT(n) MBOX_NUM_ARGS((n), 8)
+#define MBOX_RESP_DESC_COUNT(n) MBOX_NUM_ARGS((n), 16)
+
+#define MBOX_CFGSTAT_STATE_IDLE 0x00000000
+#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000
+#define MBOX_CFGSTAT_STATE_FAILACK 0x08000000
+#define MBOX_CFGSTAT_STATE_ERROR_INVALID 0xf0000001
+#define MBOX_CFGSTAT_STATE_ERROR_CORRUPT 0xf0000002
+#define MBOX_CFGSTAT_STATE_ERROR_AUTH 0xf0000003
+#define MBOX_CFGSTAT_STATE_ERROR_CORE_IO 0xf0000004
+#define MBOX_CFGSTAT_STATE_ERROR_HARDWARE 0xf0000005
+#define MBOX_CFGSTAT_STATE_ERROR_FAKE 0xf0000006
+#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007
+#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008
+
+#define RCF_SOFTFUNC_STATUS_CONF_DONE BIT(0)
+#define RCF_SOFTFUNC_STATUS_INIT_DONE BIT(1)
+#define RCF_SOFTFUNC_STATUS_SEU_ERROR BIT(3)
+#define RCF_PIN_STATUS_NSTATUS BIT(31)
+
+/* Defines for HPS_STAGE_NOTIFY */
+#define HPS_EXECUTION_STATE_FSBL 0
+#define HPS_EXECUTION_STATE_SSBL 1
+#define HPS_EXECUTION_STATE_OS 2
+
+int mbox_send_cmd(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg, u8 urgent,
+ u32 *resp_buf_len, u32 *resp_buf);
+int mbox_send_cmd_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg,
+ u8 urgent, u32 *resp_buf_len, u32 *resp_buf);
+int mbox_send_cmd_only(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg);
+int mbox_send_cmd_only_psci(u8 id, u32 cmd, u8 is_indirect, u32 len, u32 *arg);
+int mbox_rcv_resp(u32 *resp_buf, u32 resp_buf_max_len);
+int mbox_rcv_resp_psci(u32 *resp_buf, u32 resp_buf_max_len);
+int mbox_init(void);
+
+int mbox_qspi_close(void);
+int mbox_qspi_open(void);
+int mbox_qspi_get_device_info(u32 *resp_buf, u32 resp_buf_len);
+
+#endif /* _MAILBOX_S10_H_ */
diff --git a/include/mach/socfpga/secure_reg_helper.h b/include/mach/socfpga/secure_reg_helper.h
new file mode 100644
index 0000000000000000000000000000000000000000..d5a11122c723b22b6d1b93833e494909f758f3b5
--- /dev/null
+++ b/include/mach/socfpga/secure_reg_helper.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2020 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef _SECURE_REG_HELPER_H_
+#define _SECURE_REG_HELPER_H_
+
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_SDMMC 1
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 2
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC1 3
+#define SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC2 4
+
+int socfpga_secure_reg_read32(u32 id, u32 *val);
+int socfpga_secure_reg_write32(u32 id, u32 val);
+int socfpga_secure_reg_update32(u32 id, u32 mask, u32 val);
+
+#endif /* _SECURE_REG_HELPER_H_ */
diff --git a/include/mach/socfpga/smc_api.h b/include/mach/socfpga/smc_api.h
new file mode 100644
index 0000000000000000000000000000000000000000..491bcaeb019aac986013bb98c59b6109dda719f0
--- /dev/null
+++ b/include/mach/socfpga/smc_api.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2020 Intel Corporation
+ */
+
+#ifndef _SMC_API_H_
+#define _SMC_API_H_
+
+int invoke_smc(u32 func_id, u64 arg0, u64 arg1, u64 arg2, u32 *ret_payload);
+int smc_get_usercode(u32 *usercode);
+
+#endif /* _SMC_API_H_ */
diff --git a/include/mach/socfpga/soc64-firewall.h b/include/mach/socfpga/soc64-firewall.h
new file mode 100644
index 0000000000000000000000000000000000000000..659b84ca1f3f20ede52ed9b0bc0b03d9611e4d26
--- /dev/null
+++ b/include/mach/socfpga/soc64-firewall.h
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2017-2023 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef _FIREWALL_H_
+#define _FIREWALL_H_
+
+#include <linux/bitops.h>
+
+struct socfpga_firwall_l4_per {
+ u32 nand; /* 0x00 */
+ u32 nand_data;
+ u32 _pad_0x8;
+ u32 usb0;
+ u32 usb1; /* 0x10 */
+ u32 _pad_0x14;
+ u32 _pad_0x18;
+ u32 spim0;
+ u32 spim1; /* 0x20 */
+ u32 spis0;
+ u32 spis1;
+ u32 emac0;
+ u32 emac1; /* 0x30 */
+ u32 emac2;
+ u32 _pad_0x38;
+ u32 _pad_0x3c;
+ u32 sdmmc; /* 0x40 */
+ u32 gpio0;
+ u32 gpio1;
+ u32 _pad_0x4c;
+ u32 i2c0; /* 0x50 */
+ u32 i2c1;
+ u32 i2c2;
+ u32 i2c3;
+ u32 i2c4; /* 0x60 */
+ u32 timer0;
+ u32 timer1;
+ u32 uart0;
+ u32 uart1; /* 0x70 */
+};
+
+struct socfpga_firwall_l4_sys {
+ u32 _pad_0x00; /* 0x00 */
+ u32 _pad_0x04;
+ u32 dma_ecc;
+ u32 emac0rx_ecc;
+ u32 emac0tx_ecc; /* 0x10 */
+ u32 emac1rx_ecc;
+ u32 emac1tx_ecc;
+ u32 emac2rx_ecc;
+ u32 emac2tx_ecc; /* 0x20 */
+ u32 _pad_0x24;
+ u32 _pad_0x28;
+ u32 nand_ecc;
+ u32 nand_read_ecc; /* 0x30 */
+ u32 nand_write_ecc;
+ u32 ocram_ecc;
+ u32 _pad_0x3c;
+ u32 sdmmc_ecc; /* 0x40 */
+ u32 usb0_ecc;
+ u32 usb1_ecc;
+ u32 clock_manager;
+ u32 _pad_0x50; /* 0x50 */
+ u32 io_manager;
+ u32 reset_manager;
+ u32 system_manager;
+ u32 osc0_timer; /* 0x60 */
+ u32 osc1_timer;
+ u32 watchdog0;
+ u32 watchdog1;
+ u32 watchdog2; /* 0x70 */
+ u32 watchdog3;
+};
+
+#define FIREWALL_L4_DISABLE_ALL (BIT(0) | BIT(24) | BIT(16))
+#define FIREWALL_MPFE_SCR_DISABLE_ALL (BIT(0) | BIT(8) | BIT(16))
+#define FIREWALL_MPFE_SCR_DISABLE_MPU BIT(0)
+#define FIREWALL_BRIDGE_DISABLE_ALL (~0)
+
+/* Cache coherency unit (CCU) registers */
+#define CCU_CPU0_MPRT_ADBASE_DDRREG 0x4400
+#define CCU_CPU0_MPRT_ADBASE_MEMSPACE0 0x45c0
+#define CCU_CPU0_MPRT_ADBASE_MEMSPACE1A 0x45e0
+#define CCU_CPU0_MPRT_ADBASE_MEMSPACE1B 0x4600
+#define CCU_CPU0_MPRT_ADBASE_MEMSPACE1C 0x4620
+#define CCU_CPU0_MPRT_ADBASE_MEMSPACE1D 0x4640
+#define CCU_CPU0_MPRT_ADBASE_MEMSPACE1E 0x4660
+
+#define CCU_CPU0_MPRT_ADMASK_MEM_RAM0 0x4688
+
+#define CCU_IOM_MPRT_ADBASE_MEMSPACE0 0x18560
+#define CCU_IOM_MPRT_ADBASE_MEMSPACE1A 0x18580
+#define CCU_IOM_MPRT_ADBASE_MEMSPACE1B 0x185a0
+#define CCU_IOM_MPRT_ADBASE_MEMSPACE1C 0x185c0
+#define CCU_IOM_MPRT_ADBASE_MEMSPACE1D 0x185e0
+#define CCU_IOM_MPRT_ADBASE_MEMSPACE1E 0x18600
+
+#define CCU_IOM_MPRT_ADMASK_MEM_RAM0 0x18628
+
+#define CCU_TCU_MPRT_ADBASE_MEMSPACE0 0x2c520
+#define CCU_TCU_MPRT_ADBASE_MEMSPACE1A 0x2c540
+#define CCU_TCU_MPRT_ADBASE_MEMSPACE1B 0x2c560
+#define CCU_TCU_MPRT_ADBASE_MEMSPACE1C 0x2c580
+#define CCU_TCU_MPRT_ADBASE_MEMSPACE1D 0x2c5a0
+#define CCU_TCU_MPRT_ADBASE_MEMSPACE1E 0x2c5c0
+
+#define CCU_FPGA_MPRT_ADBASE_MEMSPACE0 0x105a0
+#define CCU_FPGA_MPRT_ADBASE_MEMSPACE1A 0x105c0
+#define CCU_FPGA_MPRT_ADBASE_MEMSPACE1B 0x105e0
+#define CCU_FPGA_MPRT_ADBASE_MEMSPACE1C 0x10600
+#define CCU_FPGA_MPRT_ADBASE_MEMSPACE1D 0x10620
+#define CCU_FPGA_MPRT_ADBASE_MEMSPACE1E 0x10640
+
+
+#define CCU_ADMASK_P_MASK BIT(0)
+#define CCU_ADMASK_NS_MASK BIT(1)
+
+#define CCU_ADBASE_DI_MASK BIT(4)
+
+#define CCU_REG_ADDR(reg) \
+ (SOCFPGA_CCU_ADDRESS + (reg))
+
+/* Firewall MPU DDR SCR registers */
+#define FW_MPU_DDR_SCR_EN 0x00
+#define FW_MPU_DDR_SCR_EN_SET 0x04
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASE 0x10
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_BASEEXT 0x14
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT 0x18
+#define FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT 0x1c
+
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASE 0x90
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_BASEEXT 0x94
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT 0x98
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT 0x9c
+#define FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT_FIELD 0xff
+
+/* Firewall F2SDRAM DDR SCR registers */
+#define FW_F2SDRAM_DDR_SCR_EN 0x00
+#define FW_F2SDRAM_DDR_SCR_EN_SET 0x04
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASE 0x10
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_BASEEXT 0x14
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMIT 0x18
+#define FW_F2SDRAM_DDR_SCR_REGION0ADDR_LIMITEXT 0x1c
+
+/* Firewall MPFE SCR Registers */
+#define FW_MPFE_SCR_HMC 0x00
+#define FW_MPFE_SCR_HMC_ADAPTOR 0x04
+
+#define MPUREGION0_ENABLE BIT(0)
+#define NONMPUREGION0_ENABLE BIT(8)
+
+#define FW_MPU_DDR_SCR_WRITEL(data, reg) \
+ writel(data, SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg)); \
+ writel(data, SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg))
+#define FW_F2SDRAM_DDR_SCR_WRITEL(data, reg) \
+ writel(data, SOCFPGA_FW_TBU2NOC_ADDRESS + (reg))
+
+#define FW_MPU_DDR_DMI0_SCR_READL(reg) readl(SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS + (reg));
+#define FW_MPU_DDR_DMI1_SCR_READL(reg) readl(SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS + (reg));
+#define FW_F2SDRAM_DDR_SCR_READL(reg) readl(SOCFPGA_FW_TBU2NOC_ADDRESS + (reg))
+
+/* Secure Transaction Register */
+#define SECURE_TRANS_OFFS 0x190
+#define SECURE_TRANS_REG SOCFPGA_SYSMGR_ADDRESS +\
+ SECURE_TRANS_OFFS
+#define SECURE_TRANS_RESET 0x0
+#define SECURE_TRANS_SET 0x33
+#define OCRAM_SECURE_REGION1_OFFS 0x18
+#define OCRAM_SECURE_REGION1_REG SOCFPGA_OCRAM_FIREWALL_ADDRESS +\
+ OCRAM_SECURE_REGION1_OFFS
+#define NON_SECURE_ACCESS 0x0
+
+void firewall_setup(void);
+
+#endif /* _FIREWALL_H_ */
diff --git a/include/mach/socfpga/soc64-handoff.h b/include/mach/socfpga/soc64-handoff.h
new file mode 100644
index 0000000000000000000000000000000000000000..5e079b34b84fd874f70cdb664de3c90f7464d111
--- /dev/null
+++ b/include/mach/socfpga/soc64-handoff.h
@@ -0,0 +1,50 @@
+/* SPDX-License-Identifier: GPL-2.0
+ *
+ * Copyright (C) 2016-2024 Intel Corporation <www.intel.com>
+ *
+ */
+
+#ifndef _HANDOFF_SOC64_H_
+#define _HANDOFF_SOC64_H_
+
+/*
+ * Offset for HW handoff from Quartus tools
+ */
+/* HPS handoff */
+#define SOC64_HANDOFF_MAGIC_BOOT 0x424F4F54
+#define SOC64_HANDOFF_MAGIC_MUX 0x504D5558
+#define SOC64_HANDOFF_MAGIC_IOCTL 0x494F4354
+#define SOC64_HANDOFF_MAGIC_FPGA 0x46504741
+#define SOC64_HANDOFF_MAGIC_DELAY 0x444C4159
+#define SOC64_HANDOFF_MAGIC_CLOCK 0x434C4B53
+#define SOC64_HANDOFF_MAGIC_PERI 0x50455249
+#define SOC64_HANDOFF_MAGIC_SDRAM 0x5344524d
+
+#define SOC64_HANDOFF_OFFSET_LENGTH 0x4
+#define SOC64_HANDOFF_OFFSET_DATA 0x10
+#define SOC64_HANDOFF_SIZE 4096
+
+#define SOC64_HANDOFF_BASE 0x0007F000
+
+#define SOC64_HANDOFF_MUX (SOC64_HANDOFF_BASE + 0x10)
+#define SOC64_HANDOFF_IOCTL (SOC64_HANDOFF_BASE + 0x1A0)
+#define SOC64_HANDOFF_FPGA (SOC64_HANDOFF_BASE + 0x330)
+#define SOC64_HANDOFF_DELAY (SOC64_HANDOFF_BASE + 0x3F0)
+#define SOC64_HANDOFF_CLOCK (SOC64_HANDOFF_BASE + 0x580)
+#define SOC64_HANDOFF_PERI (SOC64_HANDOFF_BASE + 0x620)
+#define SOC64_HANDOFF_SDRAM (SOC64_HANDOFF_BASE + 0x634)
+#define SOC64_HANDOFF_SDRAM_LEN 5
+
+#define SOC64_HANDOFF_CLOCK_OSC (SOC64_HANDOFF_BASE + 0x60c)
+#define SOC64_HANDOFF_CLOCK_FPGA (SOC64_HANDOFF_BASE + 0x610)
+
+#define SOC64_HANDOFF_MUX_LEN 96
+#define SOC64_HANDOFF_IOCTL_LEN 96
+#define SOC64_HANDOFF_FPGA_LEN 40
+#define SOC64_HANDOFF_DELAY_LEN 96
+
+int socfpga_get_handoff_size(void *handoff_address);
+int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len);
+const struct cm_config * const cm_get_default_config(void);
+
+#endif /* _HANDOFF_SOC64_H_ */
diff --git a/include/mach/socfpga/soc64-init.h b/include/mach/socfpga/soc64-init.h
new file mode 100644
index 0000000000000000000000000000000000000000..15113f70701c6452affad3725c3e8375133300f3
--- /dev/null
+++ b/include/mach/socfpga/soc64-init.h
@@ -0,0 +1,4 @@
+#ifndef SOC64-INIT_H_
+#define SOC64-INIT_H_
+
+#endif // SOC64-INIT_H_
diff --git a/include/mach/socfpga/soc64-regs.h b/include/mach/socfpga/soc64-regs.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd8cfa17ba1bf0c62a02c9db39dc09347131dd61
--- /dev/null
+++ b/include/mach/socfpga/soc64-regs.h
@@ -0,0 +1,195 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016-2023 Intel Corporation <www.intel.com>
+ */
+
+#ifndef _SOCFPGA_SOC64_BASE_HARDWARE_H_
+#define _SOCFPGA_SOC64_BASE_HARDWARE_H_
+
+#if IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX5)
+#define SOCFPGA_CCU_ADDRESS 0x1c000000
+#define SOCFPGA_CCU_DII2_GIC_BAR_REG 0x420
+#define SOCFPGA_CCU_DII2_GIC_LR_REG 0x424
+#define SOCFPGA_CCU_DII2_GIC_HR_REG 0x428
+
+#define SOCFPGA_FPGA2SOC_ADDRESS 0x1c001000
+#define SOCFPGA_FPGA2SOC_PSS_BAR_REG 0x400
+#define SOCFPGA_FPGA2SOC_PSS_LR_REG 0x404
+#define SOCFPGA_FPGA2SOC_PSS_HR_REG 0x408
+
+#define SOCFPGA_GIC_M_ADDRESS 0x1c002000
+#define SOCFPGA_TCU_ADDRESS 0x1c003000
+#define SOCFPGA_CCU_IOM_ADDRESS 0x1c004000
+#define SOCFPGA_DCE0_ADDRESS 0x1c005000
+#define SOCFPGA_DCE1_ADDRESS 0x1c006000
+
+#define SOCFPGA_SECREG_NCAIU1AMIGR_REG 0x3c0
+#define SOCFPGA_SECREG_NCAIU1MIFSR_REG 0x3c4
+#define SOCFPGA_SECREG_DII1_MPFE_BAR_REG 0x410
+#define SOCFPGA_SECREG_DII1_MPFE_LR_REG 0x414
+#define SOCFPGA_SECREG_DII1_MPFE_HR_REG 0x418
+#define SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_BAR_REG 0x440
+#define SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_LR_REG 0x444
+#define SOCFPGA_SECREG_NCAIU0_LWSOC2FPGA_HR_REG 0x448
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_BAR_REG 0x450
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_LR_REG 0x454
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_1G_HR_REG 0x458
+#define SOCFPGA_SECREG_DMI_SDRAM_2G_BAR_REG 0x460
+#define SOCFPGA_SECREG_DMI_SDRAM_2G_LR_REG 0x464
+#define SOCFPGA_SECREG_DMI_SDRAM_2G_HR_REG 0x468
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_BAR_REG 0x470
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_LR_REG 0x474
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_16G_HR_REG 0x478
+#define SOCFPGA_SECREG_DMI_SDRAM_30G_BAR_REG 0x480
+#define SOCFPGA_SECREG_DMI_SDRAM_30G_LR_REG 0x484
+#define SOCFPGA_SECREG_DMI_SDRAM_30G_HR_REG 0x488
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_BAR_REG 0x490
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_LR_REG 0x494
+#define SOCFPGA_SECREG_NCAIU0_SOC2FPGA_256G_HR_REG 0x498
+#define SOCFPGA_SECREG_DMI_SDRAM_480G_BAR_REG 0x4a0
+#define SOCFPGA_SECREG_DMI_SDRAM_480G_LR_REG 0x4a4
+#define SOCFPGA_SECREG_DMI_SDRAM_480G_HR_REG 0x4a8
+
+#define SOCFPGA_DMI0_ADDRESS 0x1c007000
+#define SOCFPGA_DMI0_DMIUSMCTCR_REG 0x300
+
+#define SOCFPGA_DMI1_ADDRESS 0x1c008000
+#define SOCFPGA_DMI1_DMIUSMCTCR_REG 0x300
+
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS 0x18001000
+#define SOCFPGA_SMMU_ADDRESS 0x16000000
+#define SOCFPGA_OCRAM_FIREWALL_ADDRESS 0x108cc400
+#define SOCFPGA_MAILBOX_ADDRESS 0x10a30000
+#define SOCFPGA_UART0_ADDRESS 0x10c02000
+#define SOCFPGA_UART1_ADDRESS 0x10c02100
+#define SOCFPGA_SPTIMER0_ADDRESS 0x10c03000
+#define SOCFPGA_SPTIMER1_ADDRESS 0x10c03100
+#define SOCFPGA_SYSTIMER0_ADDRESS 0x10d00000
+#define SOCFPGA_SYSTIMER1_ADDRESS 0x10d00100
+#define SOCFPGA_L4WD0_ADDRESS 0x10d00200
+#define SOCFPGA_L4WD1_ADDRESS 0x10d00300
+#define SOCFPGA_L4WD2_ADDRESS 0x10d00400
+#define SOCFPGA_L4WD3_ADDRESS 0x10d00500
+#define SOCFPGA_L4WD4_ADDRESS 0x10d00600
+#define SOCFPGA_GTIMER_SEC_ADDRESS 0x10d01000
+#define SOCFPGA_GTIMER_NSEC_ADDRESS 0x10d02000
+#define SOCFPGA_CLKMGR_ADDRESS 0x10d10000
+#define SOCFPGA_RSTMGR_ADDRESS 0x10d11000
+#define SOCFPGA_SYSMGR_ADDRESS 0x10d12000
+#define SOCFPGA_PINMUX_ADDRESS 0x10d13000
+#define SOCFPGA_OCRAM_ADDRESS 0x00000000
+#define SOCFPGA_MPFE_CSR_ADDRESS 0x18000000
+#define SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS 0x18000800
+#define SOCFPGA_FW_DDR_CCU_DMI1_ADDRESS 0x18000A00
+#define SOCFPGA_FW_TBU2NOC_ADDRESS 0x18000C00
+#define SOCFPGA_FIREWALL_L4_PER_ADDRESS 0x10d21000
+#define SOCFPGA_FIREWALL_L4_PER_NAND_REG 0x0
+#define SOCFPGA_FIREWALL_L4_PER_USB0_REG 0xc
+#define SOCFPGA_FIREWALL_L4_PER_USB1_REG 0x10
+#define SOCFPGA_FIREWALL_L4_PER_SPI_MAIN0_REG 0x1c
+#define SOCFPGA_FIREWALL_L4_PER_SPI_MAIN1_REG 0x20
+#define SOCFPGA_FIREWALL_L4_PER_SPI_SEC0_REG 0x24
+#define SOCFPGA_FIREWALL_L4_PER_SPI_SEC1_REG 0x28
+#define SOCFPGA_FIREWALL_L4_PER_EMAC0_REG 0x2c
+#define SOCFPGA_FIREWALL_L4_PER_EMAC1_REG 0x30
+#define SOCFPGA_FIREWALL_L4_PER_EMAC2_REG 0x34
+#define SOCFPGA_FIREWALL_L4_PER_SDMMC_REG 0x40
+#define SOCFPGA_FIREWALL_L4_PER_GPIO0_REG 0x44
+#define SOCFPGA_FIREWALL_L4_PER_GPIO1_REG 0x48
+#define SOCFPGA_FIREWALL_L4_PER_I2C0_REG 0x50
+#define SOCFPGA_FIREWALL_L4_PER_I2C1_REG 0x54
+#define SOCFPGA_FIREWALL_L4_PER_I2C2_REG 0x58
+#define SOCFPGA_FIREWALL_L4_PER_I2C3_REG 0x5c
+#define SOCFPGA_FIREWALL_L4_PER_I2C4_REG 0x60
+#define SOCFPGA_FIREWALL_L4_PER_SP_TIMER0_REG 0x64
+#define SOCFPGA_FIREWALL_L4_PER_SP_TIMER1_REG 0x68
+#define SOCFPGA_FIREWALL_L4_PER_UART0_REG 0x6c
+#define SOCFPGA_FIREWALL_L4_PER_UART1_REG 0x70
+#define SOCFPGA_FIREWALL_L4_PER_I3C0_REG 0x74
+#define SOCFPGA_FIREWALL_L4_PER_I3C1_REG 0x78
+#define SOCFPGA_FIREWALL_L4_PER_DMA0_REG 0x7c
+#define SOCFPGA_FIREWALL_L4_PER_DMA1_REG 0x80
+#define SOCFPGA_FIREWALL_L4_PER_COMBO_PHY_REG 0x84
+#define SOCFPGA_FIREWALL_L4_PER_NAND_SDMA_REG 0x88
+
+#define SOCFPGA_FIREWALL_L4_SYS_ADDRESS 0x10d21100
+#define SOCFPGA_FIREWALL_L4_SYS_DMA_ECC_REG 0x08
+#define SOCFPGA_FIREWALL_L4_SYS_EMAC0RX_ECC_REG 0x0c
+#define SOCFPGA_FIREWALL_L4_SYS_EMAC0TX_ECC_REG 0x10
+#define SOCFPGA_FIREWALL_L4_SYS_EMAC1RX_ECC_REG 0x14
+#define SOCFPGA_FIREWALL_L4_SYS_EMAC1TX_ECC_REG 0x18
+#define SOCFPGA_FIREWALL_L4_SYS_EMAC2RX_ECC_REG 0x1c
+#define SOCFPGA_FIREWALL_L4_SYS_EMAC2TX_ECC_REG 0x20
+#define SOCFPGA_FIREWALL_L4_SYS_NAND_ECC_REG 0x2c
+#define SOCFPGA_FIREWALL_L4_SYS_NAND_READ_ECC_REG 0x30
+#define SOCFPGA_FIREWALL_L4_SYS_NAND_WRITE_ECC_REG 0x34
+#define SOCFPGA_FIREWALL_L4_SYS_OCRAM_ECC_REG 0x38
+#define SOCFPGA_FIREWALL_L4_SYS_SDMMC_ECC_REG 0x40
+#define SOCFPGA_FIREWALL_L4_SYS_USB0_ECC_REG 0x44
+#define SOCFPGA_FIREWALL_L4_SYS_USB1_CACHEECC_REG 0x48
+#define SOCFPGA_FIREWALL_L4_SYS_CLOCK_MANAGER_REG 0x4c
+#define SOCFPGA_FIREWALL_L4_SYS_IO_MANAGER_REG 0x54
+#define SOCFPGA_FIREWALL_L4_SYS_RESET_MANAGER_REG 0x58
+#define SOCFPGA_FIREWALL_L4_SYS_SYSTEM_MANAGER_REG 0x5c
+#define SOCFPGA_FIREWALL_L4_SYS_OSC0_TIMER_REG 0x60
+#define SOCFPGA_FIREWALL_L4_SYS_OSC1_TIMER0_REG 0x64
+#define SOCFPGA_FIREWALL_L4_SYS_WATCHDOG0_REG 0x68
+#define SOCFPGA_FIREWALL_L4_SYS_WATCHDOG1_REG 0x6c
+#define SOCFPGA_FIREWALL_L4_SYS_WATCHDOG2_REG 0x70
+#define SOCFPGA_FIREWALL_L4_SYS_WATCHDOG3_REG 0x74
+#define SOCFPGA_FIREWALL_L4_SYS_DAP_REG 0x78
+#define SOCFPGA_FIREWALL_L4_SYS_WATCHDOG4_REG 0x7c
+#define SOCFPGA_FIREWALL_L4_SYS_POWER_MANAGER_REG 0x80
+#define SOCFPGA_FIREWALL_L4_SYS_USB1_RXECC_REG 0x84
+#define SOCFPGA_FIREWALL_L4_SYS_USB1_TXECC_REG 0x88
+#define SOCFPGA_FIREWALL_L4_SYS_L4_NOC_PROBES_REG 0x90
+#define SOCFPGA_FIREWALL_L4_SYS_L4_NOC_QOS_REG 0x94
+
+#define SOCFPGA_FIREWALL_SOC2FPGA_ADDRESS 0x10d21200
+#define SOCFPGA_FIREWALL_LWSOC2FPGA_ADDRESS 0x10d21300
+#define SOCFPGA_FIREWALL_TCU_ADDRESS 0x10d21400
+#define GICD_BASE 0x1d000000
+#define GICR_BASE 0x1d060000
+
+#define SOCFPGA_AGILEX5_DDR_BASE 0x80000000
+
+#else
+#define SOCFPGA_CCU_ADDRESS 0xf7000000
+#define SOCFPGA_SDR_SCHEDULER_ADDRESS 0xf8000400
+#define SOCFPGA_HMC_MMR_IO48_ADDRESS 0xf8010000
+#define SOCFPGA_SDR_ADDRESS 0xf8011000
+#define SOCFPGA_FW_MPFE_SCR_ADDRESS 0xf8020000
+#define SOCFPGA_FW_MPU_DDR_SCR_ADDRESS 0xf8020100
+#define SOCFPGA_F2SDRAM_MGR_ADDRESS 0xf8024000
+#define SOCFPGA_SMMU_ADDRESS 0xfa000000
+#define SOCFPGA_MAILBOX_ADDRESS 0xffa30000
+#define SOCFPGA_UART0_ADDRESS 0xffc02000
+#define SOCFPGA_UART1_ADDRESS 0xffc02100
+#define SOCFPGA_SPTIMER0_ADDRESS 0xffc03000
+#define SOCFPGA_SPTIMER1_ADDRESS 0xffc03100
+#define SOCFPGA_SYSTIMER0_ADDRESS 0xffd00000
+#define SOCFPGA_SYSTIMER1_ADDRESS 0xffd00100
+#define SOCFPGA_L4WD0_ADDRESS 0xffd00200
+#define SOCFPGA_L4WD1_ADDRESS 0xffd00300
+#define SOCFPGA_L4WD2_ADDRESS 0xffd00400
+#define SOCFPGA_L4WD3_ADDRESS 0xffd00500
+#define SOCFPGA_GTIMER_SEC_ADDRESS 0xffd01000
+#define SOCFPGA_GTIMER_NSEC_ADDRESS 0xffd02000
+#define SOCFPGA_CLKMGR_ADDRESS 0xffd10000
+#define SOCFPGA_RSTMGR_ADDRESS 0xffd11000
+#define SOCFPGA_SYSMGR_ADDRESS 0xffd12000
+#define SOCFPGA_PINMUX_DEDICATED_IO_ADDRESS 0xffd13000
+#define SOCFPGA_FIREWALL_L4_PER 0xffd21000
+#define SOCFPGA_FIREWALL_L4_SYS 0xffd21100
+#define SOCFPGA_FIREWALL_SOC2FPGA 0xffd21200
+#define SOCFPGA_FIREWALL_LWSOC2FPGA 0xffd21300
+#define SOCFPGA_FIREWALL_TCU 0xffd21400
+#define SOCFPGA_FIREWALL_PRIV_MEMORYMAP_PRIV 0xffd24800
+#define SOCFPGA_DMANONSECURE_ADDRESS 0xffda0000
+#define SOCFPGA_DMASECURE_ADDRESS 0xffda1000
+#define SOCFPGA_OCRAM_ADDRESS 0xffe00000
+#define GICD_BASE 0xfffc1000
+#define GICC_BASE 0xfffc2000
+#endif
+
+#endif /* _SOCFPGA_SOC64_BASE_HARDWARE_H_ */
diff --git a/include/mach/socfpga/soc64-reset-manager.h b/include/mach/socfpga/soc64-reset-manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..d9822ae9bfd9d02581432dc2aeb2051334c149bb
--- /dev/null
+++ b/include/mach/socfpga/soc64-reset-manager.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2016-2022 Intel Corporation <www.intel.com>
+ */
+
+#ifndef _RESET_MANAGER_SOC64_H_
+#define _RESET_MANAGER_SOC64_H_
+
+#define RSTMGR_SOC64_STATUS 0x00
+#define RSTMGR_SOC64_HDSKEN 0x10
+#define RSTMGR_SOC64_HDSKREQ 0x14
+#define RSTMGR_SOC64_HDSKACK 0x18
+#define RSTMGR_SOC64_MPUMODRST 0x20
+#define RSTMGR_SOC64_PER0MODRST 0x24
+#define RSTMGR_SOC64_PER1MODRST 0x28
+#define RSTMGR_SOC64_BRGMODRST 0x2c
+
+#define RSTMGR_MPUMODRST_CORE0 0
+#define RSTMGR_PER0MODRST_OCP_MASK 0x0020bf00
+
+#define RSTMGR_BRGMODRST_SOC2FPGA_MASK BIT(0)
+#define RSTMGR_BRGMODRST_LWSOC2FPGA_MASK BIT(1)
+#define RSTMGR_BRGMODRST_FPGA2SOC_MASK BIT(2)
+#define RSTMGR_BRGMODRST_F2SDRAM0_MASK BIT(3)
+#define RSTMGR_BRGMODRST_F2SDRAM1_MASK BIT(4)
+#define RSTMGR_BRGMODRST_F2SDRAM2_MASK BIT(5)
+#define RSTMGR_BRGMODRST_DDRSCH_MASK BIT(6)
+
+#define RSTMGR_HDSKEN_FPGAHSEN BIT(2)
+#define RSTMGR_HDSKREQ_FPGAHSREQ BIT(2)
+
+/* SDM, Watchdogs and MPU warm reset mask */
+#define RSTMGR_STAT_SDMWARMRST 0x2
+#define RSTMGR_STAT_MPU0RST_BITPOS 8
+#define RSTMGR_STAT_L4WD0RST_BITPOS 16
+#define RSTMGR_STAT_L4WD0RST_BIT 0x1F0000
+#define RSTMGR_L4WD_MPU_WARMRESET_MASK RSTMGR_STAT_SDMWARMRST | \
+ RSTMGR_STAT_L4WD0RST_BIT
+
+#endif /* _RESET_MANAGER_SOC64_H_ */
diff --git a/include/mach/socfpga/soc64-sdram.h b/include/mach/socfpga/soc64-sdram.h
new file mode 100644
index 0000000000000000000000000000000000000000..c84cd7f8253734dfb7066077c3b8401884efb0ed
--- /dev/null
+++ b/include/mach/socfpga/soc64-sdram.h
@@ -0,0 +1,203 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017-2023 Intel Corporation <www.intel.com>
+ */
+
+#ifndef _SDRAM_SOC64_H_
+#define _SDRAM_SOC64_H_
+
+#include <linux/sizes.h>
+
+struct altera_sdram_plat {
+ void __iomem *mpfe_base_addr;
+ bool dualport;
+ bool dualemif;
+};
+
+/* ECC HMC registers */
+#define DDRIOCTRL 0x8
+#define DDRCALSTAT 0xc
+#define DRAMADDRWIDTH 0xe0
+#define ECCCTRL1 0x100
+#define ECCCTRL2 0x104
+#define ERRINTEN 0x110
+#define ERRINTENS 0x114
+#define INTMODE 0x11c
+#define INTSTAT 0x120
+#define AUTOWB_CORRADDR 0x138
+#define ECC_REG2WRECCDATABUS 0x144
+#define ECC_DIAGON 0x150
+#define ECC_DECSTAT 0x154
+#define HPSINTFCSEL 0x210
+#define RSTHANDSHAKECTRL 0x214
+#define RSTHANDSHAKESTAT 0x218
+
+#define DDR_HMC_DDRIOCTRL_IOSIZE_MSK 0x00000003
+#define DDR_HMC_DDRIOCTRL_MPFE_HMCA_DATA_RATE_MSK BIT(2)
+#define DDR_HMC_DDRIOCTRL_MPFE_HMCA_DATA_RATE_SHIFT 2
+#define DDR_HMC_DDRCALSTAT_CAL_MSK BIT(0)
+#define DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK BIT(16)
+#define DDR_HMC_ECCCTL_CNT_RST_SET_MSK BIT(8)
+#define DDR_HMC_ECCCTL_ECC_EN_SET_MSK BIT(0)
+#define DDR_HMC_ECCCTL2_RMW_EN_SET_MSK BIT(8)
+#define DDR_HMC_ECCCTL2_AWB_EN_SET_MSK BIT(0)
+#define DDR_HMC_ECC_DIAGON_ECCDIAGON_EN_SET_MSK BIT(16)
+#define DDR_HMC_ECC_DIAGON_WRDIAGON_EN_SET_MSK BIT(0)
+#define DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK BIT(0)
+#define DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK BIT(1)
+#define DDR_HMC_INTSTAT_SERRPENA_SET_MSK BIT(0)
+#define DDR_HMC_INTSTAT_DERRPENA_SET_MSK BIT(1)
+#define DDR_HMC_INTSTAT_ADDRMTCFLG_SET_MSK BIT(16)
+#define DDR_HMC_INTMODE_INTMODE_SET_MSK BIT(0)
+#define DDR_HMC_RSTHANDSHAKE_MASK 0x0000000f
+#define DDR_HMC_CORE2SEQ_INT_REQ 0xF
+#define DDR_HMC_SEQ2CORE_INT_RESP_MASK BIT(3)
+#define DDR_HMC_HPSINTFCSEL_ENABLE_MASK 0x001f1f1f
+
+#define DDR_HMC_ERRINTEN_INTMASK \
+ (DDR_HMC_ERRINTEN_SERRINTEN_EN_SET_MSK | \
+ DDR_HMC_ERRINTEN_DERRINTEN_EN_SET_MSK)
+
+/* HMC MMR IO48 registers */
+#define CTRLCFG0 0x28
+#define CTRLCFG1 0x2c
+#define CTRLCFG3 0x34
+#define CTRLCFG5 0x3c
+#define CTRLCFG6 0x40
+#define DRAMTIMING0 0x50
+#define CALTIMING0 0x7c
+#define CALTIMING1 0x80
+#define CALTIMING2 0x84
+#define CALTIMING3 0x88
+#define CALTIMING4 0x8c
+#define CALTIMING9 0xa0
+#define DRAMADDRW 0xa8
+#define DRAMSTS 0xec
+#define NIOSRESERVED0 0x110
+#define NIOSRESERVED1 0x114
+#define NIOSRESERVED2 0x118
+
+#define CTRLCFG3_CFG_CTRL_CMD_RATE_QUARTER BIT(2)
+#define CTRLCFG5_CFG_CTRL_RC_EN_MASK BIT(8)
+
+#define DRAMADDRW_CFG_COL_ADDR_WIDTH(x) \
+ ((x) & 0x1F)
+#define DRAMADDRW_CFG_ROW_ADDR_WIDTH(x) \
+ (((x) >> 5) & 0x1F)
+#define DRAMADDRW_CFG_BANK_ADDR_WIDTH(x) \
+ (((x) >> 10) & 0xF)
+#define DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(x) \
+ (((x) >> 14) & 0x3)
+#define DRAMADDRW_CFG_CS_ADDR_WIDTH(x) \
+ (((x) >> 16) & 0x7)
+
+#define CTRLCFG0_CFG_MEMTYPE(x) \
+ ((x) & 0xF)
+#define CTRLCFG0_CFG_DIMM_TYPE(x) \
+ (((x) >> 4) & 0x7)
+#define CTRLCFG0_CFG_AC_POS(x) \
+ (((x) >> 7) & 0x3)
+#define CTRLCFG0_CFG_CTRL_BURST_LEN(x) \
+ (((x) >> 9) & 0x1F)
+
+#define CTRLCFG1_CFG_DBC3_BURST_LEN(x) \
+ ((x) & 0x1F)
+#define CTRLCFG1_CFG_ADDR_ORDER(x) \
+ (((x) >> 5) & 0x3)
+#define CTRLCFG1_CFG_CTRL_EN_ECC(x) \
+ (((x) >> 7) & 0x1)
+
+#define CTRLCFG6_CFG_CS_CHIP(x) \
+ ((x) & 0xFFFF)
+
+#define DRAMTIMING0_CFG_TCL(x) \
+ ((x) & 0x7F)
+
+#define CALTIMING0_CFG_ACT_TO_RDWR(x) \
+ ((x) & 0x3F)
+#define CALTIMING0_CFG_ACT_TO_PCH(x) \
+ (((x) >> 6) & 0x3F)
+#define CALTIMING0_CFG_ACT_TO_ACT(x) \
+ (((x) >> 12) & 0x3F)
+#define CALTIMING0_CFG_ACT_TO_ACT_DB(x) \
+ (((x) >> 18) & 0x3F)
+
+#define CALTIMING1_CFG_RD_TO_RD(x) \
+ ((x) & 0x3F)
+#define CALTIMING1_CFG_RD_TO_RD_DC(x) \
+ (((x) >> 6) & 0x3F)
+#define CALTIMING1_CFG_RD_TO_RD_DB(x) \
+ (((x) >> 12) & 0x3F)
+#define CALTIMING1_CFG_RD_TO_WR(x) \
+ (((x) >> 18) & 0x3F)
+#define CALTIMING1_CFG_RD_TO_WR_DC(x) \
+ (((x) >> 24) & 0x3F)
+
+#define CALTIMING2_CFG_RD_TO_WR_DB(x) \
+ ((x) & 0x3F)
+#define CALTIMING2_CFG_RD_TO_WR_PCH(x) \
+ (((x) >> 6) & 0x3F)
+#define CALTIMING2_CFG_RD_AP_TO_VALID(x) \
+ (((x) >> 12) & 0x3F)
+#define CALTIMING2_CFG_WR_TO_WR(x) \
+ (((x) >> 18) & 0x3F)
+#define CALTIMING2_CFG_WR_TO_WR_DC(x) \
+ (((x) >> 24) & 0x3F)
+
+#define CALTIMING3_CFG_WR_TO_WR_DB(x) \
+ ((x) & 0x3F)
+#define CALTIMING3_CFG_WR_TO_RD(x) \
+ (((x) >> 6) & 0x3F)
+#define CALTIMING3_CFG_WR_TO_RD_DC(x) \
+ (((x) >> 12) & 0x3F)
+#define CALTIMING3_CFG_WR_TO_RD_DB(x) \
+ (((x) >> 18) & 0x3F)
+#define CALTIMING3_CFG_WR_TO_PCH(x) \
+ (((x) >> 24) & 0x3F)
+
+#define CALTIMING4_CFG_WR_AP_TO_VALID(x) \
+ ((x) & 0x3F)
+#define CALTIMING4_CFG_PCH_TO_VALID(x) \
+ (((x) >> 6) & 0x3F)
+#define CALTIMING4_CFG_PCH_ALL_TO_VALID(x) \
+ (((x) >> 12) & 0x3F)
+#define CALTIMING4_CFG_ARF_TO_VALID(x) \
+ (((x) >> 18) & 0xFF)
+#define CALTIMING4_CFG_PDN_TO_VALID(x) \
+ (((x) >> 26) & 0x3F)
+
+#define CALTIMING9_CFG_4_ACT_TO_ACT(x) \
+ ((x) & 0xFF)
+
+/* Firewall DDR scheduler MPFE */
+#define FW_HMC_ADAPTOR_REG_ADDR 0xf8020004
+#define FW_HMC_ADAPTOR_MPU_MASK BIT(0)
+
+u32 hmc_readl(struct altera_sdram_plat *plat, u32 reg);
+u32 hmc_ecc_readl(struct altera_sdram_plat *plat, u32 reg);
+u32 hmc_ecc_writel(struct altera_sdram_plat *plat,
+ u32 data, u32 reg);
+u32 ddr_sch_writel(struct altera_sdram_plat *plat, u32 data,
+ u32 reg);
+int emif_clear(struct altera_sdram_plat *plat);
+int emif_reset(struct altera_sdram_plat *plat);
+int poll_hmc_clock_status(void);
+void sdram_clear_mem(phys_addr_t addr, phys_size_t size);
+//void sdram_set_firewall(struct bd_info *bd);
+phys_size_t sdram_calculate_size(struct altera_sdram_plat *plat);
+int agilex5_ddr_init_full(void);
+
+static inline resource_size_t agilex5_mpfe_sdram_size(void)
+{
+ u32 lower;
+ resource_size_t mem = 0;
+
+ lower = FW_MPU_DDR_DMI0_SCR_READL(SOCFPGA_FW_DDR_CCU_DMI0_ADDRESS +
+ FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT);
+
+ mem = lower;
+
+ return mem;
+}
+
+#endif /* _SDRAM_SOC64_H_ */
diff --git a/include/mach/socfpga/soc64-system-manager.h b/include/mach/socfpga/soc64-system-manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..862e974b190245862dc7975cbeb281ba6b263dc7
--- /dev/null
+++ b/include/mach/socfpga/soc64-system-manager.h
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+* Copyright (C) 2019-2023 Intel Corporation <www.intel.com>
+ */
+
+#ifndef _SOC64_SYSTEM_MANAGER_H_
+#define _SOC64_SYSTEM_MANAGER_H_
+
+#include <linux/bitops.h>
+
+#define SYSMGR_SOC64_SILICONID_1 0x00
+#define SYSMGR_SOC64_SILICONID_2 0x04
+#define SYSMGR_SOC64_WDDBG 0x08
+#define SYSMGR_SOC64_MPU_STATUS 0x10
+#define SYSMGR_SOC64_SDMMC 0x28
+#define SYSMGR_SOC64_SDMMC_L3MASTER 0x2c
+#define SYSMGR_SOC64_COMBOPHY_DFISEL 0xfc
+#define SYSMGR_SOC64_COMBOPHY_DFISEL_SDMMC 0x1
+#define SYSMGR_SOC64_NANDGRP_L3MASTER 0x34
+#define SYSMGR_SOC64_USB0_L3MASTER 0x38
+#define SYSMGR_SOC64_USB1_L3MASTER 0x3c
+#define SYSMGR_SOC64_TSN_GLOBAL 0x40
+#define SYSMGR_SOC64_TSN_0 0x44
+#define SYSMGR_SOC64_TSN_1 0x48
+#define SYSMGR_SOC64_TSN_2 0x4C
+#define SYSMGR_SOC64_TSN_0_ACE 0x50
+#define SYSMGR_SOC64_TSN_1_ACE 0x54
+#define SYSMGR_SOC64_TSN_2_ACE 0x58
+#define SYSMGR_SOC64_FPGAINTF_EN1 0x68
+#define SYSMGR_SOC64_FPGAINTF_EN2 0x6C
+#define SYSMGR_SOC64_FPGAINTF_EN3 0x70
+#define SYSMGR_SOC64_DMAC0_L3_MASTER 0x74
+#define SYSMGR_SOC64_ETR_L3_MASTER 0x78
+#define SYSMGR_SOC64_DMAC1_L3_MASTER 0x7C
+#define SYSMGR_SOC64_SEC_CTRL_SLT 0x80
+#define SYSMGR_SOC64_OSC_TRIM 0x84
+#define SYSMGR_SOC64_DMAC0_CTRL_STATUS_REG 0x88
+#define SYSMGR_SOC64_DMAC1_CTRL_STATUS_REG 0x8C
+#define SYSMGR_SOC64_ECC_INTMASK_VALUE 0x90
+#define SYSMGR_SOC64_ECC_INTMASK_SET 0x94
+#define SYSMGR_SOC64_ECC_INTMASK_CLR 0x98
+#define SYSMGR_SOC64_ECC_INTMASK_SERR 0x9C
+#define SYSMGR_SOC64_ECC_INTMASK_DERR 0xA0
+#define SYSMGR_SOC64_NOC_TIMEOUT 0xC0
+#define SYSMGR_SOC64_NOC_IDLEREQ_SET 0xc4
+#define SYSMGR_SOC64_NOC_IDLEREQ_CLR 0xc8
+#define SYSMGR_SOC64_NOC_IDLEREQ_VAL 0xcc
+#define SYSMGR_SOC64_NOC_IDLEACK 0xd0
+#define SYSMGR_SOC64_NOC_IDLESTATUS 0xD4
+#define SYSMGR_SOC64_FPGA2SOC_CTRL 0xD8
+#define SYSMGR_SOC64_FPGA_CONFIG 0xDC
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD0 0x200
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD1 0x204
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD2 0x208
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD3 0x20C
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD4 0x210
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD5 0x214
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD6 0x218
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD7 0x21C
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD8 0x220
+#define SYSMGR_SOC64_BOOT_SCRATCH_COLD9 0x224
+#define SYSMGR_SOC64_MPFE_CONFIG 0x228
+#define SYSMGR_SOC64_BOOT_SCRATCH_POR0 0x258
+#define SYSMGR_SOC64_BOOT_SCRATCH_POR1 0x25C
+
+#define SYSMGR_SCRATCH_REG_0_QSPI_REFCLK_MASK GENMASK(31, 0)
+#define ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_MASK GENMASK(31, 29)
+#define ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_SHIFT 29
+#define ALT_SYSMGR_SCRATCH_REG_3_DDR_DBE_MASK BIT(1)
+#define ALT_SYSMGR_SCRATCH_REG_3_OCRAM_DBE_MASK BIT(0)
+#define ALT_SYSMGR_SCRATCH_REG_POR_0_DDR_PROGRESS_MASK BIT(0)
+#define ALT_SYSMGR_SCRATCH_REG_POR_1_REVA_WORKAROUND_USER_MODE_MASK BIT(0)
+#define ALT_SYSMGR_SCRATCH_REG_POR_1_REVA_WORKAROUND_MASK BIT(1)
+
+#define SYSMGR_SOC64_EMAC_GLOBAL SYSMGR_SOC64_TSN_GLOBAL
+#define SYSMGR_SOC64_EMAC0 SYSMGR_SOC64_TSN_0
+#define SYSMGR_SOC64_EMAC1 SYSMGR_SOC64_TSN_1
+#define SYSMGR_SOC64_EMAC2 SYSMGR_SOC64_TSN_2
+#define SYSMGR_SOC64_EMAC0_ACE SYSMGR_SOC64_TSN_0_ACE
+#define SYSMGR_SOC64_EMAC1_ACE SYSMGR_SOC64_TSN_1_ACE
+#define SYSMGR_SOC64_EMAC2_ACE SYSMGR_SOC64_TSN_2_ACE
+
+#define SYSMGR_SOC64_PINSEL0 0x1000
+#define SYSMGR_SOC64_IOCTRL0 0x1130
+#define SYSMGR_SOC64_EMAC0_USEFPGA 0x1300
+#define SYSMGR_SOC64_EMAC1_USEFPGA 0x1304
+#define SYSMGR_SOC64_EMAC2_USEFPGA 0x1308
+#define SYSMGR_SOC64_I2C0_USEFPGA 0x130c
+#define SYSMGR_SOC64_I2C1_USEFPGA 0x1310
+#define SYSMGR_SOC64_I2C_EMAC0_USEFPGA 0x1314
+#define SYSMGR_SOC64_I2C_EMAC1_USEFPGA 0x1318
+#define SYSMGR_SOC64_I2C_EMAC2_USEFPGA 0x131c
+#define SYSMGR_SOC64_NAND_USEFPGA 0x1320
+#define SYSMGR_SOC64_SPIM0_USEFPGA 0x1328
+#define SYSMGR_SOC64_SPIM1_USEFPGA 0x132c
+#define SYSMGR_SOC64_SPIS0_USEFPGA 0x1330
+#define SYSMGR_SOC64_SPIS1_USEFPGA 0x1334
+#define SYSMGR_SOC64_UART0_USEFPGA 0x1338
+#define SYSMGR_SOC64_UART1_USEFPGA 0x133c
+#define SYSMGR_SOC64_MDIO0_USEFPGA 0x1340
+#define SYSMGR_SOC64_MDIO1_USEFPGA 0x1344
+#define SYSMGR_SOC64_MDIO2_USEFPGA 0x1348
+#define SYSMGR_SOC64_JTAG_USEFPGA 0x1350
+#define SYSMGR_SOC64_SDMMC_USEFPGA 0x1354
+#define SYSMGR_SOC64_HPS_OSC_CLK 0x1358
+#define SYSMGR_SOC64_IODELAY0 0x1400
+#define SYSMGR_SOC64_PERI 0x15D0
+
+/*
+ * Bits for SYSMGR_SOC64_BOOT_SCRATCH_COLD8
+ * Bit[31] reserved for FSBL to check DBE is triggered (set by SDM to "1") ?
+ *
+ * Bit[30] reserved for FSBL to update the DDR init progress
+ * 1 - means in progress, 0 - haven't started / DDR is up running.
+ *
+* Bit[19] store ATF CPU0 ON OFF value.
+*
+ * Bit[18] reserved for SDM to configure ACF
+ * Bit[17:1] - Setting by Linux EDAC.
+ * Bit[1](ECC_OCRAM), Bit[16](ECC_DDR0), Bit[17](ECC_DDR1)
+ */
+#define ALT_SYSMGR_SCRATCH_REG_8_DDR_DBE_MASK BIT(31)
+#define ALT_SYSMGR_SCRATCH_REG_8_DDR_PROGRESS_MASK BIT(30)
+#define SYSMGR_SCRATCH_REG_8_ACF_DDR_RATE_MASK BIT(18)
+#define SYSMGR_SCRATCH_REG_8_ACF_DDR_RATE_SHIFT 18
+
+#define SYSMGR_SDMMC SYSMGR_SOC64_SDMMC
+
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGPINMUX BIT(0)
+#define SYSMGR_ROMCODEGRP_CTRL_WARMRSTCFGIO BIT(1)
+#define SYSMGR_ECC_OCRAM_EN BIT(0)
+#define SYSMGR_ECC_OCRAM_SERR BIT(3)
+#define SYSMGR_ECC_OCRAM_DERR BIT(4)
+#define SYSMGR_FPGACONFIG_FPGA_COMPLETE BIT(0)
+#define SYSMGR_FPGACONFIG_EARLY_USERMODE BIT(1)
+#define SYSMGR_FPGACONFIG_READY_MASK (SYSMGR_FPGACONFIG_FPGA_COMPLETE | \
+ SYSMGR_FPGACONFIG_EARLY_USERMODE)
+
+#define SYSMGR_FPGAINTF_USEFPGA 0x1
+#define SYSMGR_FPGAINTF_NAND BIT(4)
+#define SYSMGR_FPGAINTF_SDMMC BIT(8)
+#define SYSMGR_FPGAINTF_SPIM0 BIT(16)
+#define SYSMGR_FPGAINTF_SPIM1 BIT(24)
+#define SYSMGR_FPGAINTF_EMAC0 BIT(0)
+#define SYSMGR_FPGAINTF_EMAC1 BIT(8)
+#define SYSMGR_FPGAINTF_EMAC2 BIT(16)
+
+#define SYSMGR_SDMMC_SMPLSEL_SHIFT 4
+#define SYSMGR_SDMMC_DRVSEL_SHIFT 0
+
+/* EMAC Group Bit definitions */
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
+
+#define SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB 0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB 2
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x3
+
+#define SYSMGR_NOC_H2F_MSK 0x00000001
+#define SYSMGR_NOC_LWH2F_MSK 0x00000010
+#define SYSMGR_HMC_CLK_STATUS_MSK 0x00000001
+
+#define SYSMGR_DMA_IRQ_NS 0xFF000000
+#define SYSMGR_DMA_MGR_NS 0x00010000
+
+#define SYSMGR_DMAPERIPH_ALL_NS 0xFFFFFFFF
+
+#define SYSMGR_WDDBG_PAUSE_ALL_CPU 0x0F0F0F0F
+
+void agilex5_security_interleaving_on(void);
+void agilex5_security_interleaving_off(void);
+void agilex5_initialize_security_policies(void);
+void agilex5_sysmgr_pinmux_init(void);
+
+#endif /* _SOC64_SYSTEM_MANAGER_H_ */
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 05/10] ARM: socfpga: add Arrow AXE5 Agilex5 board
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (3 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 04/10] arm: socfgpa: add support for SoCFPGA Agilex5 Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-11-04 10:48 ` Sascha Hauer
2024-10-29 8:42 ` [PATCH 06/10] net: add support for Designware XGMAC (10gb) ethernet Steffen Trumtrar
` (4 subsequent siblings)
9 siblings, 1 reply; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Add the Agilex5-based Arrow AXE5-Eagle board.
It consists among other things of:
- Agilex5 SoCFPGA
- 1 GB LPDDR4 SDRAM for HPS
- 1 GB LPDDR4 SDRAM for FPGA
- 1 Gb QSPI for configuration via SDM
- microSD
- 4-port USB hub
- 2x 1Gb Ethernet
- HDMI output
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
arch/arm/boards/Makefile | 1 +
arch/arm/boards/arrow-axe5-eagle/Makefile | 3 +
arch/arm/boards/arrow-axe5-eagle/board.c | 23 +++++++
arch/arm/boards/arrow-axe5-eagle/lowlevel.c | 58 ++++++++++++++++++
arch/arm/configs/socfpga-agilex5_defconfig | 88 +++++++++++++++++++++++++++
arch/arm/dts/Makefile | 1 +
arch/arm/dts/socfpga_agilex5_axe5_eagle.dts | 94 +++++++++++++++++++++++++++++
images/Makefile.socfpga | 9 +++
8 files changed, 277 insertions(+)
diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
index e0dc27cb3d21cc7bc763f148595321562d65d740..bc4d3bb4ea9e5691de90cbf7e6b0fbc577076732 100644
--- a/arch/arm/boards/Makefile
+++ b/arch/arm/boards/Makefile
@@ -111,6 +111,7 @@ obj-$(CONFIG_MACH_SAMA5D4_WIFX) += sama5d4_wifx/
obj-$(CONFIG_MACH_SCB9328) += scb9328/
obj-$(CONFIG_MACH_SEEED_ODYSSEY) += seeed-odyssey/
obj-$(CONFIG_MACH_SOCFPGA_ALTERA_SOCDK) += altera-socdk/
+obj-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += arrow-axe5-eagle/
obj-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += ebv-socrates/
obj-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1) += enclustra-aa1/
obj-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += reflex-achilles/
diff --git a/arch/arm/boards/arrow-axe5-eagle/Makefile b/arch/arm/boards/arrow-axe5-eagle/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..1d052d28c9fc6a82dbf806eedac60fac8a56d4f9
--- /dev/null
+++ b/arch/arm/boards/arrow-axe5-eagle/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0-only
+lwl-y += lowlevel.o
+obj-y += board.o
diff --git a/arch/arm/boards/arrow-axe5-eagle/board.c b/arch/arm/boards/arrow-axe5-eagle/board.c
new file mode 100644
index 0000000000000000000000000000000000000000..1efea0b3d9cf0aa5ecd7c67ea9348708dcfd0b80
--- /dev/null
+++ b/arch/arm/boards/arrow-axe5-eagle/board.c
@@ -0,0 +1,23 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <bbu.h>
+#include <mach/socfpga/soc64-regs.h>
+
+static int axe5_init(void)
+{
+ if (!of_machine_is_compatible("arrow,axe5-eagle"))
+ return 0;
+
+ pr_debug("Change the pullup values on EMAC2 HPS mii signals\n");
+ writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x224);
+ writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x228);
+ writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x23c);
+ writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x234);
+ writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x248);
+ writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x24c);
+
+ return 0;
+}
+postcore_initcall(axe5_init);
diff --git a/arch/arm/boards/arrow-axe5-eagle/lowlevel.c b/arch/arm/boards/arrow-axe5-eagle/lowlevel.c
new file mode 100644
index 0000000000000000000000000000000000000000..f69d4d91f9ea9a60c17ae58d4f3c124663c600ff
--- /dev/null
+++ b/arch/arm/boards/arrow-axe5-eagle/lowlevel.c
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <common.h>
+#include <io.h>
+#include <linux/sizes.h>
+#include <asm/barebox-arm.h>
+#include <asm/system.h>
+#include <pbl.h>
+#include <mach/socfpga/debug_ll.h>
+#include <mach/socfpga/init.h>
+#include <mach/socfpga/generic.h>
+#include <mach/socfpga/mailbox_s10.h>
+#include <mach/socfpga/soc64-firewall.h>
+#include <mach/socfpga/soc64-regs.h>
+#include <mach/socfpga/soc64-sdram.h>
+#include <mach/socfpga/soc64-system-manager.h>
+
+extern char __dtb_z_socfpga_agilex5_axe5_eagle_start[];
+
+#define AXE5_STACKTOP (SZ_512K)
+
+static noinline void axe5_eagle_continue(void)
+{
+ void *fdt;
+
+ agilex5_clk_init();
+
+ socfpga_uart_setup_ll();
+ pbl_set_putc(socfpga_uart_putc, (void *) SOCFPGA_UART0_ADDRESS);
+
+ pr_debug("Lowlevel init done\n");
+
+ if (current_el() == 3) {
+ agilex5_initialize_security_policies();
+ pr_debug("Security policies initialized\n");
+
+ agilex5_ddr_init_full();
+
+ mbox_init();
+ mbox_qspi_open();
+
+ agilex5_load_and_start_image_via_tfa(SZ_1G);
+ }
+
+ fdt = __dtb_z_socfpga_agilex5_axe5_eagle_start;
+
+ barebox_arm_entry(SOCFPGA_AGILEX5_DDR_BASE + SZ_1M, SZ_1G - SZ_1M, fdt);
+}
+
+ENTRY_FUNCTION_WITHSTACK(start_socfpga_agilex5_axe5_eagle, AXE5_STACKTOP, r0, r1, r2)
+{
+ if (current_el() == 3)
+ socfpga_agilex5_cpu_lowlevel_init();
+
+ relocate_to_current_adr();
+ setup_c();
+
+ axe5_eagle_continue();
+}
diff --git a/arch/arm/configs/socfpga-agilex5_defconfig b/arch/arm/configs/socfpga-agilex5_defconfig
new file mode 100644
index 0000000000000000000000000000000000000000..b443a1281e6ad621d7270cade3ea0d60ccdc9af5
--- /dev/null
+++ b/arch/arm/configs/socfpga-agilex5_defconfig
@@ -0,0 +1,88 @@
+CONFIG_ARCH_SOCFPGA=y
+CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MMU=y
+CONFIG_MALLOC_SIZE=0x0
+CONFIG_MALLOC_TLSF=y
+CONFIG_KALLSYMS=y
+CONFIG_PROMPT="barebox> "
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+# CONFIG_TIMESTAMP is not set
+CONFIG_BOOTM_SHOW_TYPE=y
+CONFIG_BOOTM_VERBOSE=y
+CONFIG_BOOTM_INITRD=y
+CONFIG_BOOTM_OFTREE=y
+CONFIG_BOOTM_OFTREE_UIMAGE=y
+CONFIG_BOOTM_AIMAGE=y
+CONFIG_BLSPEC=y
+CONFIG_SYSTEM_PARTITIONS=y
+CONFIG_CONSOLE_ACTIVATE_FIRST=y
+CONFIG_CONSOLE_ALLOW_COLOR=y
+CONFIG_PBL_CONSOLE=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_RESET_SOURCE=y
+CONFIG_PRINTF_FULL=y
+CONFIG_CMD_DMESG=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_DEFAULTENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_MAGICVAR=y
+CONFIG_CMD_MAGICVAR_HELP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_FILETYPE=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_MD5SUM=y
+CONFIG_CMD_SHA256SUM=y
+CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_LET=y
+CONFIG_CMD_READF=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_ETHLOG=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_LOGIN=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_CRC=y
+CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MEMTEST=y
+CONFIG_CMD_MM=y
+CONFIG_CMD_CLK=y
+CONFIG_CMD_DETECT=y
+CONFIG_CMD_BAREBOX_UPDATE=y
+CONFIG_CMD_OF_DIFF=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_DISPLAY_TIMINGS=y
+CONFIG_CMD_OF_FIXUP_STATUS=y
+CONFIG_CMD_OF_OVERLAY=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIME=y
+CONFIG_NET=y
+CONFIG_OF_BAREBOX_DRIVERS=y
+CONFIG_OF_BAREBOX_ENV_IN_FS=y
+CONFIG_OF_OVERLAY_LIVE=y
+CONFIG_SERIAL_DEV_BUS=y
+CONFIG_DRIVER_SERIAL_NS16550=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+CONFIG_MTD_SPI_NOR=y
+CONFIG_SPI_CADENCE_QUADSPI=y
+CONFIG_MFD_SYSCON=y
+# CONFIG_PINCTRL is not set
+CONFIG_ARM_SCMI_PROTOCOL=y
+# CONFIG_VIRTIO_MENU is not set
+CONFIG_MAILBOX=y
+CONFIG_FS_TFTP=y
+CONFIG_ZLIB=y
+CONFIG_CRC_CCITT=y
+CONFIG_NLS=y
+# CONFIG_MISSING_FIRMWARE_ERROR is not set
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3b3236b4165f7ff9fa7acb57bbf9c0ad597c778f..50b7429142ee2fb573d33166c76020975fb5b49f 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -137,6 +137,7 @@ lwl-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += socfpga_arria10_achilles.dtb.o
lwl-$(CONFIG_MACH_SOCFPGA_TERASIC_DE0_NANO_SOC) += socfpga_cyclone5_de0_nano_soc.dtb.o
lwl-$(CONFIG_MACH_SOCFPGA_TERASIC_DE10_NANO) += socfpga_cyclone5_de10_nano.dtb.o
lwl-$(CONFIG_MACH_SOCFPGA_TERASIC_SOCKIT) += socfpga_cyclone5_sockit.dtb.o
+lwl-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += socfpga_agilex5_axe5_eagle.dtb.o
lwl-$(CONFIG_MACH_SOLIDRUN_CUBOX) += dove-cubox-bb.dtb.o
lwl-$(CONFIG_MACH_SOLIDRUN_MICROSOM) += imx6dl-hummingboard.dtb.o imx6q-hummingboard.dtb.o \
imx6dl-hummingboard2.dtb.o imx6q-hummingboard2.dtb.o \
diff --git a/arch/arm/dts/socfpga_agilex5_axe5_eagle.dts b/arch/arm/dts/socfpga_agilex5_axe5_eagle.dts
new file mode 100644
index 0000000000000000000000000000000000000000..cd12a2ccd22adca728dcf196a489fdc8c7b9347f
--- /dev/null
+++ b/arch/arm/dts/socfpga_agilex5_axe5_eagle.dts
@@ -0,0 +1,94 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2024 Pengutronix, Steffen Trumtrar <kernel@pengutronix.de>
+ */
+
+#include <arm64/intel/socfpga_agilex5.dtsi>
+#include "socfpga_agilex5.dtsi"
+
+/ {
+ model = "SoCFPGA Agilex5 AXE5-Eagle";
+ compatible = "arrow,axe5-eagle", "intel,socfpga-agilex","altr,socfpga";
+
+ aliases {
+ serial0 = &uart0;
+ ethernet0 = &gmac2;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+
+ memory@80100000 {
+ device_type = "memory";
+ reg = <0 0x80100000 0 0x3ff00000>;
+ };
+};
+
+&osc1 {
+ clock-frequency = <25000000>;
+};
+
+&gpio0 {
+ status = "okay";
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&qspi {
+ status = "okay";
+
+ flash0: flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "mt25qu02g";
+ reg = <0>;
+ spi-max-frequency = <100000000>;
+
+ m25p,fast-read;
+ cdns,page-size = <256>;
+ cdns,block-size = <16>;
+ cdns,read-delay = <1>;
+ cdns,tshsl-ns = <50>;
+ cdns,tsd2d-ns = <50>;
+ cdns,tchsh-ns = <4>;
+ cdns,tslch-ns = <4>;
+
+ partitions {
+ compatible = "fixed-partitions";
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ qspi_boot: partition@0 {
+ label = "u-boot";
+ reg = <0x0 0x04200000>;
+ };
+
+ root: partition@4200000 {
+ label = "root";
+ reg = <0x04200000 0x0BE00000>;
+ };
+ };
+ };
+};
+
+&gmac2 {
+ status = "okay";
+ phy-mode = "rgmii-id";
+ phy-handle = <&emac2_phy0>;
+
+ max-frame-size = <9000>;
+
+ mdio0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "snps,dwmac-mdio";
+ emac2_phy0: ethernet-phy@1 {
+ reg = <0x1>;
+ adi,rx-internal-delay-ps = <2000>;
+ adi,tx-internal-delay-ps = <2000>;
+ };
+ };
+};
diff --git a/images/Makefile.socfpga b/images/Makefile.socfpga
index 807ca78e4ac8636382107f844eeb83ba9007a583..db1a47b6a1ad7f6a7d08036bdeed6a50b707ac47 100644
--- a/images/Makefile.socfpga
+++ b/images/Makefile.socfpga
@@ -87,6 +87,15 @@ pblb-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += start_socfpga_socrates
FILE_barebox-socfpga-socrates.img = start_socfpga_socrates.pblb
socfpga-barebox-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += barebox-socfpga-socrates.img
+# ----------------------- Agilex5 based boards ---------------------------
+pblb-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += start_socfpga_agilex5_axe5_eagle
+FILE_barebox-socfpga-agilex5-axe5-eagle.img = start_socfpga_agilex5_axe5_eagle.pblb.hex
+socfpga-barebox-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += barebox-socfpga-agilex5-axe5-eagle.img
+
+pblb-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += start_socfpga_agilex5_axe5_eagle
+FILE_barebox-socfpga-agilex5-axe5-eagle-2nd.img = start_socfpga_agilex5_axe5_eagle.pblb
+socfpga-barebox-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += barebox-socfpga-agilex5-axe5-eagle-2nd.img
+
ifdef CONFIG_ARCH_SOCFPGA_XLOAD
image-y += $(socfpga-xload-y)
else
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 06/10] net: add support for Designware XGMAC (10gb) ethernet
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (4 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 05/10] ARM: socfpga: add Arrow AXE5 Agilex5 board Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-11-04 11:14 ` Sascha Hauer
2024-10-29 8:42 ` [PATCH 07/10] net: phy: add Analog Devices ADIN1300 Steffen Trumtrar
` (3 subsequent siblings)
9 siblings, 1 reply; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
The Designware XGMAC is designed for 1/2.5/5/10G ethernet applications.
It is mostly identical to the eqos driver but has a different register
layout.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/net/Kconfig | 18 +
drivers/net/Makefile | 2 +
drivers/net/designware_xgmac.c | 829 +++++++++++++++++++++++++++++++++
drivers/net/designware_xgmac.h | 294 ++++++++++++
drivers/net/designware_xgmac_socfpga.c | 156 +++++++
5 files changed, 1299 insertions(+)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 13e9ff6924bbf454c77487ca247c68c458d18f1a..b5134be4b8b3186cd765a1005ade6fade5dd939e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -140,6 +140,24 @@ config DRIVER_NET_DESIGNWARE_ROCKCHIP
help
This option enables support for the Ethernet MAC on different Rockchip SoCs
+config DRIVER_NET_DESIGNWARE_XGMAC
+ bool "Designware XGMAC Ethernet driver support" if COMPILE_TEST
+ depends on HAS_DMA && OFTREE
+ select PHYLIB
+ select MFD_SYSCON
+ help
+ This option enables support for the Synopsys Designware Ethernet XGMAC (10G Ethernet MAC).
+
+config DRIVER_NET_DESIGNWARE_XGMAC_SOCFPGA
+ bool "Designware XGMAC Ethernet driver support for SOCFPGA"
+ select DRIVER_NET_DESIGNWARE_XGMAC
+ depends on (ARCH_SOCFPGA_AGILEX5 || COMPILE_TEST)
+ select RESET_CONTROLLER if ARCH_SOCFPGA
+ select RESET_SIMPLE if ARCH_SOCFPGA_AGILEX5
+ help
+ This option enables support for the Synopsys Designware Ethernet XGMAC with specific configuration
+ for the Intel SoC FPGA chip.
+
config DRIVER_NET_DM9K
bool "Davicom dm9k[E|A|B] ethernet driver"
depends on HAS_DM9000 || COMPILE_TEST
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 207345cfa3688a4d65d2f7f20bd56cef32759024..76582fde366393905b05629772be175a3910b4c6 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -19,6 +19,8 @@ obj-$(CONFIG_DRIVER_NET_DESIGNWARE_IMX8) += designware_imx.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_STM32) += designware_stm32.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_TEGRA186) += designware_tegra186.o
obj-$(CONFIG_DRIVER_NET_DESIGNWARE_ROCKCHIP) += designware_rockchip.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE_XGMAC) += designware_xgmac.o
+obj-$(CONFIG_DRIVER_NET_DESIGNWARE_XGMAC_SOCFPGA) += designware_xgmac_socfpga.o
obj-$(CONFIG_DRIVER_NET_DM9K) += dm9k.o
obj-$(CONFIG_DRIVER_NET_E1000) += e1000/
obj-$(CONFIG_DRIVER_NET_ENC28J60) += enc28j60.o
diff --git a/drivers/net/designware_xgmac.c b/drivers/net/designware_xgmac.c
new file mode 100644
index 0000000000000000000000000000000000000000..7b7c288ada559095d1c4fefb0a7823a5ba358ee7
--- /dev/null
+++ b/drivers/net/designware_xgmac.c
@@ -0,0 +1,829 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Intel Corporation.
+ *
+ * Portions based on U-Boot's dwc_eth_qos.c.
+ */
+
+/*
+ * This driver supports the Synopsys Designware Ethernet XGMAC (10G Ethernet
+ * MAC) IP block. The IP supports multiple options for bus type, clocking/
+ * reset structure, and feature list.
+ *
+ * The driver is written such that generic core logic is kept separate from
+ * configuration-specific logic. Code that interacts with configuration-
+ * specific resources is split out into separate functions to avoid polluting
+ * common code. If/when this driver is enhanced to support multiple
+ * configurations, the core code should be adapted to call all configuration-
+ * specific functions through function pointers, with the definition of those
+ * function pointers being supplied by struct udevice_id xgmac_ids[]'s .data
+ * field.
+ *
+ * This configuration uses an AXI master/DMA bus, an AHB slave/register bus,
+ * contains the DMA, MTL, and MAC sub-blocks, and supports a single RGMII PHY.
+ * This configuration also has SW control over all clock and reset signals to
+ * the HW block.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <dma.h>
+#include <errno.h>
+#include <malloc.h>
+#include <net.h>
+#include <of_net.h>
+#include <linux/iopoll.h>
+#include <linux/phy.h>
+#include <asm/cache.h>
+#include "designware_xgmac.h"
+
+static int xgmac_mdio_wait_idle(struct xgmac_priv *xgmac)
+{
+ u32 idle;
+
+ return readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
+ !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
+ XGMAC_TIMEOUT_100MS);
+}
+
+static int xgmac_mdio_read(struct mii_bus *bus, int mdio_addr, int mdio_reg)
+{
+ struct xgmac_priv *xgmac = bus->priv;
+ u32 val;
+ u32 hw_addr;
+ u32 idle;
+ int ret;
+
+ ret = readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
+ !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
+ XGMAC_TIMEOUT_100MS);
+ if (ret) {
+ pr_err("MDIO not idle at entry: %d\n", ret);
+ return ret;
+ }
+
+ /* Set clause 22 format */
+ val = BIT(mdio_addr);
+ writel(val, &xgmac->mac_regs->mdio_clause_22_port);
+
+ hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
+ (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
+
+ val = xgmac->config->config_mac_mdio <<
+ XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT;
+
+ val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
+ XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ |
+ XGMAC_MAC_MDIO_ADDRESS_SBUSY;
+
+ ret = readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
+ !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
+ XGMAC_TIMEOUT_100MS);
+ if (ret) {
+ pr_err("MDIO not idle at entry: %d\n", ret);
+ return ret;
+ }
+
+ writel(hw_addr, &xgmac->mac_regs->mdio_address);
+ writel(val, &xgmac->mac_regs->mdio_data);
+
+ ret = readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
+ !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
+ XGMAC_TIMEOUT_100MS);
+ if (ret) {
+ pr_err("MDIO read didn't complete: %d\n", ret);
+ return ret;
+ }
+
+ val = readl(&xgmac->mac_regs->mdio_data);
+ val &= XGMAC_MAC_MDIO_DATA_GD_MASK;
+
+ return val;
+}
+
+static int xgmac_mdio_write(struct mii_bus *bus, int mdio_addr, int mdio_reg,
+ u16 mdio_val)
+{
+ struct xgmac_priv *xgmac = bus->priv;
+ u32 val;
+ u32 hw_addr;
+ int ret;
+
+ ret = xgmac_mdio_wait_idle(xgmac);
+ if (ret) {
+ pr_err("MDIO not idle at entry: %d\n", ret);
+ return ret;
+ }
+
+ /* Set clause 22 format */
+ val = BIT(mdio_addr);
+ writel(val, &xgmac->mac_regs->mdio_clause_22_port);
+
+ hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
+ (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
+
+ hw_addr |= (mdio_reg >> XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) <<
+ XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT;
+
+ val = (xgmac->config->config_mac_mdio <<
+ XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT);
+
+ val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
+ mdio_val | XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE |
+ XGMAC_MAC_MDIO_ADDRESS_SBUSY;
+
+ ret = xgmac_mdio_wait_idle(xgmac);
+ if (ret) {
+ pr_err("MDIO not idle at entry: %d\n", ret);
+ return ret;
+ }
+
+ writel(hw_addr, &xgmac->mac_regs->mdio_address);
+ writel(val, &xgmac->mac_regs->mdio_data);
+
+ ret = xgmac_mdio_wait_idle(xgmac);
+ if (ret) {
+ pr_err("MDIO write didn't complete: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int xgmac_set_full_duplex(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ clrbits_le32(&xgmac->mac_regs->mac_extended_conf, XGMAC_MAC_EXT_CONF_HD);
+
+ return 0;
+}
+
+static int xgmac_set_half_duplex(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ setbits_le32(&xgmac->mac_regs->mac_extended_conf, XGMAC_MAC_EXT_CONF_HD);
+
+ /* WAR: Flush TX queue when switching to half-duplex */
+ setbits_le32(&xgmac->mtl_regs->txq0_operation_mode,
+ XGMAC_MTL_TXQ0_OPERATION_MODE_FTQ);
+
+ return 0;
+}
+
+static int xgmac_set_gmii_speed(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ clrsetbits_le32(&xgmac->mac_regs->tx_configuration,
+ XGMAC_MAC_CONF_SS_SHIFT_MASK,
+ XGMAC_MAC_CONF_SS_1G_GMII << XGMAC_MAC_CONF_SS_SHIFT);
+
+ return 0;
+}
+
+static int xgmac_set_mii_speed_100(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ clrsetbits_le32(&xgmac->mac_regs->tx_configuration,
+ XGMAC_MAC_CONF_SS_SHIFT_MASK,
+ XGMAC_MAC_CONF_SS_100M_MII << XGMAC_MAC_CONF_SS_SHIFT);
+
+ return 0;
+}
+
+static int xgmac_set_mii_speed_10(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ clrsetbits_le32(&xgmac->mac_regs->tx_configuration,
+ XGMAC_MAC_CONF_SS_SHIFT_MASK,
+ XGMAC_MAC_CONF_SS_2_10M_MII << XGMAC_MAC_CONF_SS_SHIFT);
+
+ return 0;
+}
+
+static void xgmac_adjust_link(struct eth_device *edev)
+{
+ struct device *dev = edev->parent;
+ bool en_calibration;
+ int ret;
+
+ if (edev->phydev->duplex)
+ ret = xgmac_set_full_duplex(dev);
+ else
+ ret = xgmac_set_half_duplex(dev);
+ if (ret < 0) {
+ pr_err("xgmac_set_*_duplex() failed: %d\n", ret);
+ }
+
+ switch (edev->phydev->speed) {
+ case SPEED_1000:
+ en_calibration = true;
+ ret = xgmac_set_gmii_speed(dev);
+ break;
+ case SPEED_100:
+ en_calibration = true;
+ ret = xgmac_set_mii_speed_100(dev);
+ break;
+ case SPEED_10:
+ en_calibration = false;
+ ret = xgmac_set_mii_speed_10(dev);
+ break;
+ default:
+ pr_err("invalid speed %d\n", edev->phydev->speed);
+ }
+ if (ret < 0)
+ pr_err("xgmac_set_*mii_speed*() failed: %d\n", ret);
+}
+
+static int xgmac_write_hwaddr(struct eth_device *edev, const unsigned char *mac)
+{
+ struct xgmac_priv *xgmac = edev->priv;
+ u32 val;
+
+ memcpy(xgmac->macaddr, mac, ETH_ALEN);
+
+ /*
+ * This function may be called before start() or after stop(). At that
+ * time, on at least some configurations of the XGMAC HW, all clocks to
+ * the XGMAC HW block will be stopped, and a reset signal applied. If
+ * any register access is attempted in this state, bus timeouts or CPU
+ * hangs may occur. This check prevents that.
+ *
+ * A simple solution to this problem would be to not implement
+ * write_hwaddr(), since start() always writes the MAC address into HW
+ * anyway. However, it is desirable to implement write_hwaddr() to
+ * support the case of SW that runs subsequent to U-Boot which expects
+ * the MAC address to already be programmed into the XGMAC registers,
+ * which must happen irrespective of whether the U-Boot user (or
+ * scripts) actually made use of the XGMAC device, and hence
+ * irrespective of whether start() was ever called.
+ *
+ */
+ if (!xgmac->config->reg_access_always_ok && !xgmac->reg_access_ok)
+ return 0;
+
+ /* Update the MAC address */
+ val = (xgmac->macaddr[5] << 8) |
+ (xgmac->macaddr[4]);
+ writel(val, &xgmac->mac_regs->address0_high);
+ val = (xgmac->macaddr[3] << 24) |
+ (xgmac->macaddr[2] << 16) |
+ (xgmac->macaddr[1] << 8) |
+ (xgmac->macaddr[0]);
+ writel(val, &xgmac->mac_regs->address0_low);
+ return 0;
+}
+
+static int xgmac_read_rom_hwaddr(struct eth_device *edev, unsigned char *mac)
+{
+ struct xgmac_priv *xgmac = edev->priv;
+ int ret;
+
+ ret = xgmac->config->ops->xgmac_get_enetaddr(edev->parent);
+ if (ret < 0)
+ return ret;
+
+ return !is_valid_ether_addr(xgmac->macaddr);
+}
+
+static int xgmac_start(struct eth_device *edev)
+{
+ struct xgmac_priv *xgmac = edev->priv;
+ int ret, i;
+ u32 val, tx_fifo_sz, rx_fifo_sz, tqs, rqs, pbl;
+ ulong last_rx_desc;
+ ulong desc_pad;
+ u32 idle;
+
+ ret = phy_device_connect(edev, &xgmac->miibus, xgmac->phy_addr,
+ xgmac_adjust_link, 0, xgmac->interface);
+ if (ret)
+ return ret;
+
+ ret = xgmac->config->ops->xgmac_start_resets(edev->parent);
+ if (ret < 0) {
+ pr_err("xgmac_start_resets() failed: %d\n", ret);
+ goto err;
+ }
+
+ xgmac->reg_access_ok = true;
+
+ setbits_le32(&xgmac->dma_regs->mode, XGMAC_DMA_MODE_SWR);
+
+ ret = readl_poll_timeout(&xgmac->dma_regs->mode, idle,
+ !(idle & XGMAC_DMA_MODE_SWR),
+ XGMAC_TIMEOUT_100MS);
+ if (ret) {
+ pr_err("XGMAC_DMA_MODE_SWR stuck: %d\n", ret);
+ goto err;
+ }
+
+ /* Configure MTL */
+
+ /* Enable Store and Forward mode for TX */
+ /* Program Tx operating mode */
+ setbits_le32(&xgmac->mtl_regs->txq0_operation_mode,
+ XGMAC_MTL_TXQ0_OPERATION_MODE_TSF |
+ (XGMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_ENABLED <<
+ XGMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_SHIFT));
+
+ /* Transmit Queue weight */
+ writel(0x10, &xgmac->mtl_regs->txq0_quantum_weight);
+
+ /* Enable Store and Forward mode for RX, since no jumbo frame */
+ setbits_le32(&xgmac->mtl_regs->rxq0_operation_mode,
+ XGMAC_MTL_RXQ0_OPERATION_MODE_RSF);
+
+ /* Transmit/Receive queue fifo size; use all RAM for 1 queue */
+ val = readl(&xgmac->mac_regs->hw_feature1);
+ tx_fifo_sz = (val >> XGMAC_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT) &
+ XGMAC_MAC_HW_FEATURE1_TXFIFOSIZE_MASK;
+ rx_fifo_sz = (val >> XGMAC_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT) &
+ XGMAC_MAC_HW_FEATURE1_RXFIFOSIZE_MASK;
+
+ /*
+ * r/tx_fifo_sz is encoded as log2(n / 128). Undo that by shifting.
+ * r/tqs is encoded as (n / 256) - 1.
+ */
+ tqs = (128 << tx_fifo_sz) / 256 - 1;
+ rqs = (128 << rx_fifo_sz) / 256 - 1;
+
+ clrsetbits_le32(&xgmac->mtl_regs->txq0_operation_mode,
+ XGMAC_MTL_TXQ0_OPERATION_MODE_TQS_MASK <<
+ XGMAC_MTL_TXQ0_OPERATION_MODE_TQS_SHIFT,
+ tqs << XGMAC_MTL_TXQ0_OPERATION_MODE_TQS_SHIFT);
+ clrsetbits_le32(&xgmac->mtl_regs->rxq0_operation_mode,
+ XGMAC_MTL_RXQ0_OPERATION_MODE_RQS_MASK <<
+ XGMAC_MTL_RXQ0_OPERATION_MODE_RQS_SHIFT,
+ rqs << XGMAC_MTL_RXQ0_OPERATION_MODE_RQS_SHIFT);
+
+ setbits_le32(&xgmac->mtl_regs->rxq0_operation_mode,
+ XGMAC_MTL_RXQ0_OPERATION_MODE_EHFC);
+
+ /* Configure MAC */
+ clrsetbits_le32(&xgmac->mac_regs->rxq_ctrl0,
+ XGMAC_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
+ XGMAC_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
+ xgmac->config->config_mac <<
+ XGMAC_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
+
+ /* Multicast and Broadcast Queue Enable */
+ setbits_le32(&xgmac->mac_regs->rxq_ctrl1,
+ XGMAC_MAC_RXQ_CTRL1_MCBCQEN);
+
+ /* enable promisc mode and receive all mode */
+ setbits_le32(&xgmac->mac_regs->mac_packet_filter,
+ XGMAC_MAC_PACKET_FILTER_RA |
+ XGMAC_MAC_PACKET_FILTER_PR);
+
+ /* Set TX flow control parameters */
+ /* Set Pause Time */
+ setbits_le32(&xgmac->mac_regs->q0_tx_flow_ctrl,
+ XGMAC_MAC_Q0_TX_FLOW_CTRL_PT_MASK <<
+ XGMAC_MAC_Q0_TX_FLOW_CTRL_PT_SHIFT);
+
+ /* Assign priority for RX flow control */
+ clrbits_le32(&xgmac->mac_regs->rxq_ctrl2,
+ XGMAC_MAC_RXQ_CTRL2_PSRQ0_MASK <<
+ XGMAC_MAC_RXQ_CTRL2_PSRQ0_SHIFT);
+
+ /* Enable flow control */
+ setbits_le32(&xgmac->mac_regs->q0_tx_flow_ctrl,
+ XGMAC_MAC_Q0_TX_FLOW_CTRL_TFE);
+ setbits_le32(&xgmac->mac_regs->rx_flow_ctrl,
+ XGMAC_MAC_RX_FLOW_CTRL_RFE);
+
+ clrbits_le32(&xgmac->mac_regs->tx_configuration,
+ XGMAC_MAC_CONF_JD);
+
+ clrbits_le32(&xgmac->mac_regs->rx_configuration,
+ XGMAC_MAC_CONF_JE |
+ XGMAC_MAC_CONF_GPSLCE |
+ XGMAC_MAC_CONF_WD);
+
+ setbits_le32(&xgmac->mac_regs->rx_configuration,
+ XGMAC_MAC_CONF_ACS |
+ XGMAC_MAC_CONF_CST);
+
+ /* Configure DMA */
+ clrsetbits_le32(&xgmac->dma_regs->sysbus_mode,
+ XGMAC_DMA_SYSBUS_MODE_AAL,
+ XGMAC_DMA_SYSBUS_MODE_EAME |
+ XGMAC_DMA_SYSBUS_MODE_UNDEF);
+
+ /* Enable OSP mode */
+ setbits_le32(&xgmac->dma_regs->ch0_tx_control,
+ XGMAC_DMA_CH0_TX_CONTROL_OSP);
+
+ /* RX buffer size. Must be a multiple of bus width */
+ clrsetbits_le32(&xgmac->dma_regs->ch0_rx_control,
+ XGMAC_DMA_CH0_RX_CONTROL_RBSZ_MASK <<
+ XGMAC_DMA_CH0_RX_CONTROL_RBSZ_SHIFT,
+ XGMAC_MAX_PACKET_SIZE <<
+ XGMAC_DMA_CH0_RX_CONTROL_RBSZ_SHIFT);
+
+ desc_pad = 0;
+
+ setbits_le32(&xgmac->dma_regs->ch0_control,
+ XGMAC_DMA_CH0_CONTROL_PBLX8 |
+ (desc_pad << XGMAC_DMA_CH0_CONTROL_DSL_SHIFT));
+
+ /*
+ * Burst length must be < 1/2 FIFO size.
+ * FIFO size in tqs is encoded as (n / 256) - 1.
+ * Each burst is n * 8 (PBLX8) * 16 (AXI width) == 128 bytes.
+ * Half of n * 256 is n * 128, so pbl == tqs, modulo the -1.
+ */
+ pbl = tqs + 1;
+ if (pbl > 32)
+ pbl = 32;
+
+ clrsetbits_le32(&xgmac->dma_regs->ch0_tx_control,
+ XGMAC_DMA_CH0_TX_CONTROL_TXPBL_MASK <<
+ XGMAC_DMA_CH0_TX_CONTROL_TXPBL_SHIFT,
+ pbl << XGMAC_DMA_CH0_TX_CONTROL_TXPBL_SHIFT);
+
+ clrsetbits_le32(&xgmac->dma_regs->ch0_rx_control,
+ XGMAC_DMA_CH0_RX_CONTROL_RXPBL_MASK <<
+ XGMAC_DMA_CH0_RX_CONTROL_RXPBL_SHIFT,
+ 8 << XGMAC_DMA_CH0_RX_CONTROL_RXPBL_SHIFT);
+
+ /* DMA performance configuration */
+ val = (XGMAC_DMA_SYSBUS_MODE_RD_OSR_LMT_MASK <<
+ XGMAC_DMA_SYSBUS_MODE_RD_OSR_LMT_SHIFT) |
+ (XGMAC_DMA_SYSBUS_MODE_WR_OSR_LMT_MASK <<
+ XGMAC_DMA_SYSBUS_MODE_WR_OSR_LMT_SHIFT) |
+ XGMAC_DMA_SYSBUS_MODE_EAME |
+ XGMAC_DMA_SYSBUS_MODE_BLEN16 |
+ XGMAC_DMA_SYSBUS_MODE_BLEN8 |
+ XGMAC_DMA_SYSBUS_MODE_BLEN4 |
+ XGMAC_DMA_SYSBUS_MODE_BLEN32;
+
+ writel(val, &xgmac->dma_regs->sysbus_mode);
+
+ /* Set up descriptors */
+
+ xgmac->tx_desc_idx = 0;
+ xgmac->rx_desc_idx = 0;
+
+ for (i = 0; i < XGMAC_DESCRIPTORS_NUM; i++) {
+ struct xgmac_desc *rx_desc = &xgmac->rx_descs[i];
+
+ writel(XGMAC_DESC3_OWN, &rx_desc->des3);
+ }
+
+ writel(0, &xgmac->dma_regs->ch0_txdesc_list_haddress);
+ writel(xgmac->tx_descs_phys, &xgmac->dma_regs->ch0_txdesc_list_address);
+ writel(XGMAC_DESCRIPTORS_NUM - 1,
+ &xgmac->dma_regs->ch0_txdesc_ring_length);
+
+ writel(0, &xgmac->dma_regs->ch0_rxdesc_list_haddress);
+ writel(xgmac->rx_descs_phys, &xgmac->dma_regs->ch0_rxdesc_list_address);
+ writel(XGMAC_DESCRIPTORS_NUM - 1,
+ &xgmac->dma_regs->ch0_rxdesc_ring_length);
+
+ /* Enable everything */
+ setbits_le32(&xgmac->dma_regs->ch0_tx_control,
+ XGMAC_DMA_CH0_TX_CONTROL_ST);
+ setbits_le32(&xgmac->dma_regs->ch0_rx_control,
+ XGMAC_DMA_CH0_RX_CONTROL_SR);
+ setbits_le32(&xgmac->mac_regs->tx_configuration,
+ XGMAC_MAC_CONF_TE);
+ setbits_le32(&xgmac->mac_regs->rx_configuration,
+ XGMAC_MAC_CONF_RE);
+
+ /* TX tail pointer not written until we need to TX a packet */
+ /*
+ * Point RX tail pointer at last descriptor. Ideally, we'd point at the
+ * first descriptor, implying all descriptors were available. However,
+ * that's not distinguishable from none of the descriptors being
+ * available.
+ */
+ last_rx_desc = (ulong)&xgmac->rx_descs[(XGMAC_DESCRIPTORS_NUM - 1)];
+ writel(last_rx_desc, &xgmac->dma_regs->ch0_rxdesc_tail_pointer);
+
+ xgmac->started = true;
+
+ return 0;
+
+err:
+ return ret;
+}
+
+static void xgmac_stop(struct eth_device *edev)
+{
+ struct xgmac_priv *xgmac = edev->priv;
+ u64 start_time;
+ u32 val;
+ u32 trcsts;
+ u32 txqsts;
+ u32 prxq;
+ u32 rxqsts;
+
+ debug("%s(dev=%p):\n", __func__, edev);
+
+ if (!xgmac->started)
+ return;
+ xgmac->started = false;
+ xgmac->reg_access_ok = false;
+
+ /* Disable TX DMA */
+ clrbits_le32(&xgmac->dma_regs->ch0_tx_control,
+ XGMAC_DMA_CH0_TX_CONTROL_ST);
+
+ /* Wait for TX all packets to drain out of MTL */
+ start_time = get_time_ns();
+
+ while (!is_timeout(start_time, XGMAC_TIMEOUT_100MS)) {
+ val = readl(&xgmac->mtl_regs->txq0_debug);
+
+ trcsts = (val >> XGMAC_MTL_TXQ0_DEBUG_TRCSTS_SHIFT) &
+ XGMAC_MTL_TXQ0_DEBUG_TRCSTS_MASK;
+
+ txqsts = val & XGMAC_MTL_TXQ0_DEBUG_TXQSTS;
+
+ if (trcsts != XGMAC_MTL_TXQ0_DEBUG_TRCSTS_READ_STATE && !txqsts)
+ break;
+ }
+
+ /* Turn off MAC TX and RX */
+ clrbits_le32(&xgmac->mac_regs->tx_configuration,
+ XGMAC_MAC_CONF_RE);
+ clrbits_le32(&xgmac->mac_regs->rx_configuration,
+ XGMAC_MAC_CONF_RE);
+
+ /* Wait for all RX packets to drain out of MTL */
+ start_time = get_time_ns();
+
+ while (!is_timeout(start_time, XGMAC_TIMEOUT_100MS)) {
+ val = readl(&xgmac->mtl_regs->rxq0_debug);
+
+ prxq = (val >> XGMAC_MTL_RXQ0_DEBUG_PRXQ_SHIFT) &
+ XGMAC_MTL_RXQ0_DEBUG_PRXQ_MASK;
+
+ rxqsts = (val >> XGMAC_MTL_RXQ0_DEBUG_RXQSTS_SHIFT) &
+ XGMAC_MTL_RXQ0_DEBUG_RXQSTS_MASK;
+
+ if (!prxq && !rxqsts)
+ break;
+ }
+
+ /* Turn off RX DMA */
+ clrbits_le32(&xgmac->dma_regs->ch0_rx_control,
+ XGMAC_DMA_CH0_RX_CONTROL_SR);
+}
+
+static int xgmac_send(struct eth_device *edev, void *packet, int length)
+{
+ struct xgmac_priv *xgmac = edev->priv;
+ struct xgmac_desc *tx_desc;
+ dma_addr_t dma;
+ u32 des3_prev, des3;
+ int ret;
+
+ tx_desc = &xgmac->tx_descs[xgmac->tx_desc_idx];
+ xgmac->tx_desc_idx++;
+ xgmac->tx_desc_idx %= XGMAC_DESCRIPTORS_NUM;
+
+ dma = dma_map_single(edev->parent, packet, length, DMA_TO_DEVICE);
+ if (dma_mapping_error(edev->parent, dma))
+ return -EFAULT;
+
+ tx_desc->des0 = dma;
+ tx_desc->des1 = 0;
+ tx_desc->des2 = length;
+ /*
+ * Make sure that if HW sees the _OWN write below, it will see all the
+ * writes to the rest of the descriptor too.
+ */
+ barrier();
+
+ des3_prev = XGMAC_DESC3_OWN | XGMAC_DESC3_FD | XGMAC_DESC3_LD | length;
+ writel(des3_prev, &tx_desc->des3);
+ writel((ulong)(tx_desc + 1), &xgmac->dma_regs->ch0_txdesc_tail_pointer); // <-- TODO
+
+ ret = readl_poll_timeout(&tx_desc->des3, des3,
+ !(des3 & XGMAC_DESC3_OWN),
+ 100 * USEC_PER_MSEC);
+
+ dma_unmap_single(edev->parent, dma, length, DMA_TO_DEVICE);
+
+ if (ret == -ETIMEDOUT)
+ debug("%s: TX timeout 0x%08x\n", __func__, des3);
+
+ return ret;
+}
+
+static void xgmac_recv(struct eth_device *edev)
+{
+ struct xgmac_priv *xgmac = edev->priv;
+ struct xgmac_desc *rx_desc;
+ dma_addr_t dma;
+ void *pkt;
+ int length;
+
+ rx_desc = &xgmac->rx_descs[xgmac->rx_desc_idx];
+
+ if (rx_desc->des3 & XGMAC_DESC3_OWN)
+ return;
+
+ dma = xgmac->dma_rx_buf[xgmac->rx_desc_idx];
+ pkt = phys_to_virt(dma);
+ length = rx_desc->des3 & XGMAC_RDES3_PKT_LENGTH_MASK;
+
+ dma_sync_single_for_cpu(edev->parent, (unsigned long)pkt, length,
+ DMA_FROM_DEVICE);
+ net_receive(edev, pkt, length);
+ dma_sync_single_for_device(edev->parent, (unsigned long)pkt,
+ length, DMA_FROM_DEVICE);
+
+ /* Read Format RX descriptor */
+ rx_desc = &xgmac->rx_descs[xgmac->rx_desc_idx];
+ rx_desc->des0 = dma;
+ rx_desc->des1 = 0;
+ rx_desc->des2 = 0;
+ /*
+ * Make sure that if HW sees the _OWN write below, it will see all the
+ * writes to the rest of the descriptor too.
+ */
+ rx_desc->des3 = XGMAC_DESC3_OWN;
+ barrier();
+
+ writel((ulong)rx_desc, &xgmac->dma_regs->ch0_rxdesc_tail_pointer);
+
+ xgmac->rx_desc_idx++;
+ xgmac->rx_desc_idx %= XGMAC_DESCRIPTORS_NUM;
+}
+
+static int xgmac_probe_resources_core(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+ unsigned int desc_step;
+ int ret = 0;
+ void *p;
+ int i;
+
+ /* Maximum distance between neighboring descriptors, in Bytes. */
+ desc_step = sizeof(struct xgmac_desc);
+
+ xgmac->tx_descs = dma_alloc_coherent(XGMAC_DESCRIPTORS_SIZE,
+ &xgmac->tx_descs_phys);
+ if (!xgmac->tx_descs) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ xgmac->rx_descs = dma_alloc_coherent(XGMAC_DESCRIPTORS_SIZE,
+ &xgmac->rx_descs_phys);
+ if (!xgmac->rx_descs) {
+ ret = -ENOMEM;
+ goto err_free_tx_descs;
+ }
+
+ p = dma_alloc(XGMAC_RX_BUFFER_SIZE);
+ if (!p)
+ goto err_free_descs;
+
+ for (i = 0; i < XGMAC_DESCRIPTORS_NUM; i++) {
+ struct xgmac_desc *rx_desc = &xgmac->rx_descs[i];
+ dma_addr_t dma;
+
+ dma = dma_map_single(dev, p, XGMAC_MAX_PACKET_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(dev, dma)) {
+ ret = -EFAULT;
+ goto err_free_dma_bufs;
+ }
+
+ rx_desc->des0 = dma;
+ xgmac->dma_rx_buf[i] = dma;
+
+ p += XGMAC_MAX_PACKET_SIZE;
+ }
+
+ return 0;
+
+err_free_dma_bufs:
+ dma_free(phys_to_virt(xgmac->rx_descs[0].des0));
+err_free_descs:
+ dma_free_coherent(xgmac->rx_descs, xgmac->rx_descs_phys, XGMAC_DESCRIPTORS_SIZE);
+err_free_tx_descs:
+ dma_free_coherent(xgmac->tx_descs, xgmac->tx_descs_phys, XGMAC_DESCRIPTORS_SIZE);
+err:
+
+ return ret;
+}
+
+static int xgmac_remove_resources_core(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ dma_free(xgmac->rx_dma_buf);
+ dma_free_coherent(xgmac->rx_descs, xgmac->rx_descs_phys, XGMAC_DESCRIPTORS_SIZE);
+ dma_free_coherent(xgmac->tx_descs, xgmac->tx_descs_phys, XGMAC_DESCRIPTORS_SIZE);
+
+ return 0;
+}
+
+static void xgmac_probe_dt(struct device *dev, struct xgmac_priv *xgmac)
+{
+ struct device_node *child;
+
+ xgmac->interface = of_get_phy_mode(dev->of_node);
+ xgmac->phy_addr = 0;
+
+ /* Set MDIO bus device node, if present. */
+ for_each_child_of_node(dev->of_node, child) {
+ if (of_device_is_compatible(child, "snps,dwmac-mdio") ||
+ (child->name && !of_node_cmp(child->name, "mdio"))) {
+ xgmac->miibus.dev.of_node = child;
+ break;
+ }
+ }
+}
+
+int xgmac_probe(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct mii_bus *miibus;
+ struct xgmac_priv *xgmac;
+ struct resource *iores;
+ struct eth_device *edev;
+ int ret = 0;
+
+ xgmac = xzalloc(sizeof(*xgmac));
+
+ xgmac->dev = dev;
+ ret = dev_get_drvdata(dev, (const void **)&xgmac->config);
+ if (ret < 0) {
+ pr_err("xgmac_probe() failed to get driver data: %d\n", ret);
+ return ret;
+ }
+
+ iores = dev_request_mem_resource(dev, 0);
+ if (IS_ERR(iores))
+ return PTR_ERR(iores);
+ xgmac->regs = IOMEM(iores->start);
+
+ xgmac->mac_regs = (void *)(xgmac->regs + XGMAC_MAC_REGS_BASE);
+ xgmac->mtl_regs = (void *)(xgmac->regs + XGMAC_MTL_REGS_BASE);
+ xgmac->dma_regs = (void *)(xgmac->regs + XGMAC_DMA_REGS_BASE);
+
+ xgmac_probe_dt(dev, xgmac);
+
+ edev = &xgmac->netdev;
+ dev->priv = edev->priv = xgmac;
+
+ edev->parent = dev;
+ edev->open = xgmac_start;
+ edev->send = xgmac_send;
+ edev->halt = xgmac_stop;
+ edev->recv = xgmac_recv;
+ edev->get_ethaddr = xgmac_read_rom_hwaddr;
+ edev->set_ethaddr = xgmac_write_hwaddr;
+
+ of_property_read_u32(np, "max-speed", &xgmac->max_speed);
+
+ miibus = &xgmac->miibus;
+ miibus->parent = edev->parent;
+ miibus->read = xgmac_mdio_read;
+ miibus->write = xgmac_mdio_write;
+ miibus->priv = xgmac;
+
+ ret = xgmac_probe_resources_core(dev);
+ if (ret < 0) {
+ pr_err("xgmac_probe_resources_core() failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = xgmac->config->ops->xgmac_probe_resources(dev);
+ if (ret < 0) {
+ pr_err("xgmac_probe_resources() failed: %d\n", ret);
+ goto err_remove_resources_core;
+ }
+
+ ret = mdiobus_register(miibus);
+ if (ret)
+ return ret;
+
+ return eth_register(edev);
+
+err_remove_resources_core:
+ xgmac_remove_resources_core(dev);
+
+ return ret;
+}
+
+void xgmac_remove(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ eth_unregister(&xgmac->netdev);
+ mdiobus_unregister(&xgmac->miibus);
+
+ xgmac_remove_resources_core(dev);
+}
diff --git a/drivers/net/designware_xgmac.h b/drivers/net/designware_xgmac.h
new file mode 100644
index 0000000000000000000000000000000000000000..f6d39adf6c21cd7c17805add7aee3ffe396e18a4
--- /dev/null
+++ b/drivers/net/designware_xgmac.h
@@ -0,0 +1,294 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright 2023 Intel Coporation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/phy.h>
+
+/* Core registers */
+
+#define XGMAC_MAC_REGS_BASE 0x000
+
+struct xgmac_mac_regs {
+ u32 tx_configuration; /* 0x000 */
+ u32 rx_configuration; /* 0x004 */
+ u32 mac_packet_filter; /* 0x008 */
+ u32 unused_00c[(0x070 - 0x00c) / 4]; /* 0x00c */
+ u32 q0_tx_flow_ctrl; /* 0x070 */
+ u32 unused_070[(0x090 - 0x074) / 4]; /* 0x074 */
+ u32 rx_flow_ctrl; /* 0x090 */
+ u32 unused_094[(0x0a0 - 0x094) / 4]; /* 0x094 */
+ u32 rxq_ctrl0; /* 0x0a0 */
+ u32 rxq_ctrl1; /* 0x0a4 */
+ u32 rxq_ctrl2; /* 0x0a8 */
+ u32 unused_0ac[(0x0dc - 0x0ac) / 4]; /* 0x0ac */
+ u32 us_tic_counter; /* 0x0dc */
+ u32 unused_0e0[(0x11c - 0x0e0) / 4]; /* 0x0e0 */
+ u32 hw_feature0; /* 0x11c */
+ u32 hw_feature1; /* 0x120 */
+ u32 hw_feature2; /* 0x124 */
+ u32 hw_feature3; /* 0x128 */
+ u32 hw_feature4; /* 0x12c */
+ u32 unused_130[(0x140 - 0x130) / 4]; /* 0x130 */
+ u32 mac_extended_conf; /* 0x140 */
+ u32 unused_144[(0x200 - 0x144) / 4]; /* 0x144 */
+ u32 mdio_address; /* 0x200 */
+ u32 mdio_data; /* 0x204 */
+ u32 mdio_cont_write_addr; /* 0x208 */
+ u32 mdio_cont_write_data; /* 0x20c */
+ u32 mdio_cont_scan_port_enable; /* 0x210 */
+ u32 mdio_intr_status; /* 0x214 */
+ u32 mdio_intr_enable; /* 0x218 */
+ u32 mdio_port_cnct_dsnct_status; /* 0x21c */
+ u32 mdio_clause_22_port; /* 0x220 */
+ u32 unused_224[(0x300 - 0x224) / 4]; /* 0x224 */
+ u32 address0_high; /* 0x300 */
+ u32 address0_low; /* 0x304 */
+};
+
+#define XGMAC_TIMEOUT_100MS 100000
+#define XGMAC_MAC_CONF_SS_SHIFT 29
+#define XGMAC_MAC_CONF_SS_SHIFT_MASK GENMASK(31, 29)
+#define XGMAC_MAC_CONF_SS_10G_XGMII 0
+#define XGMAC_MAC_CONF_SS_2_5G_GMII 2
+#define XGMAC_MAC_CONF_SS_1G_GMII 3
+#define XGMAC_MAC_CONF_SS_100M_MII 4
+#define XGMAC_MAC_CONF_SS_5G_XGMII 5
+#define XGMAC_MAC_CONF_SS_2_5G_XGMII 6
+#define XGMAC_MAC_CONF_SS_2_10M_MII 7
+
+#define XGMAC_MAC_CONF_JD BIT(16)
+#define XGMAC_MAC_CONF_JE BIT(8)
+#define XGMAC_MAC_CONF_WD BIT(7)
+#define XGMAC_MAC_CONF_GPSLCE BIT(6)
+#define XGMAC_MAC_CONF_CST BIT(2)
+#define XGMAC_MAC_CONF_ACS BIT(1)
+#define XGMAC_MAC_CONF_TE BIT(0)
+#define XGMAC_MAC_CONF_RE BIT(0)
+
+#define XGMAC_MAC_EXT_CONF_HD BIT(24)
+
+#define XGMAC_MAC_PACKET_FILTER_RA BIT(31)
+#define XGMAC_MAC_PACKET_FILTER_PR BIT(0)
+
+#define XGMAC_MAC_Q0_TX_FLOW_CTRL_PT_SHIFT 16
+#define XGMAC_MAC_Q0_TX_FLOW_CTRL_PT_MASK GENMASK(15, 0)
+#define XGMAC_MAC_Q0_TX_FLOW_CTRL_TFE BIT(1)
+
+#define XGMAC_MAC_RX_FLOW_CTRL_RFE BIT(0)
+#define XGMAC_MAC_RXQ_CTRL0_RXQ0EN_SHIFT 0
+#define XGMAC_MAC_RXQ_CTRL0_RXQ0EN_MASK GENMASK(1, 0)
+#define XGMAC_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0
+#define XGMAC_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2
+#define XGMAC_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
+
+#define XGMAC_MAC_RXQ_CTRL1_MCBCQEN BIT(15)
+
+#define XGMAC_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0
+#define XGMAC_MAC_RXQ_CTRL2_PSRQ0_MASK GENMASK(7, 0)
+
+#define XGMAC_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT 6
+#define XGMAC_MAC_HW_FEATURE1_TXFIFOSIZE_MASK GENMASK(4, 0)
+#define XGMAC_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT 0
+#define XGMAC_MAC_HW_FEATURE1_RXFIFOSIZE_MASK GENMASK(4, 0)
+
+#define XGMAC_MDIO_SINGLE_CMD_SHIFT 16
+#define XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ 3 << XGMAC_MDIO_SINGLE_CMD_SHIFT
+#define XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_WRITE BIT(16)
+#define XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT 16
+#define XGMAC_MAC_MDIO_ADDRESS_PA_MASK GENMASK(15, 0)
+#define XGMAC_MAC_MDIO_ADDRESS_DA_SHIFT 21
+#define XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT 19
+#define XGMAC_MAC_MDIO_ADDRESS_CR_100_150 0
+#define XGMAC_MAC_MDIO_ADDRESS_CR_150_250 1
+#define XGMAC_MAC_MDIO_ADDRESS_CR_250_300 2
+#define XGMAC_MAC_MDIO_ADDRESS_CR_300_350 3
+#define XGMAC_MAC_MDIO_ADDRESS_CR_350_400 4
+#define XGMAC_MAC_MDIO_ADDRESS_CR_400_500 5
+#define XGMAC_MAC_MDIO_ADDRESS_SADDR BIT(18)
+#define XGMAC_MAC_MDIO_ADDRESS_SBUSY BIT(22)
+#define XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK GENMASK(4, 0)
+#define XGMAC_MAC_MDIO_DATA_GD_MASK GENMASK(15, 0)
+
+/* MTL Registers */
+
+#define XGMAC_MTL_REGS_BASE 0x1000
+
+struct xgmac_mtl_regs {
+ u32 mtl_operation_mode; /* 0x1000 */
+ u32 unused_1004[(0x1030 - 0x1004) / 4]; /* 0x1004 */
+ u32 mtl_rxq_dma_map0; /* 0x1030 */
+ u32 mtl_rxq_dma_map1; /* 0x1034 */
+ u32 mtl_rxq_dma_map2; /* 0x1038 */
+ u32 mtl_rxq_dma_map3; /* 0x103c */
+ u32 mtl_tc_prty_map0; /* 0x1040 */
+ u32 mtl_tc_prty_map1; /* 0x1044 */
+ u32 unused_1048[(0x1100 - 0x1048) / 4]; /* 0x1048 */
+ u32 txq0_operation_mode; /* 0x1100 */
+ u32 unused_1104; /* 0x1104 */
+ u32 txq0_debug; /* 0x1108 */
+ u32 unused_100c[(0x1118 - 0x110c) / 4]; /* 0x110c */
+ u32 txq0_quantum_weight; /* 0x1118 */
+ u32 unused_111c[(0x1140 - 0x111c) / 4]; /* 0x111c */
+ u32 rxq0_operation_mode; /* 0x1140 */
+ u32 unused_1144; /* 0x1144 */
+ u32 rxq0_debug; /* 0x1148 */
+};
+
+#define XGMAC_MTL_TXQ0_OPERATION_MODE_TQS_SHIFT 16
+#define XGMAC_MTL_TXQ0_OPERATION_MODE_TQS_MASK GENMASK(8, 0)
+#define XGMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_SHIFT 2
+#define XGMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_ENABLED 2
+#define XGMAC_MTL_TXQ0_OPERATION_MODE_TSF BIT(1)
+#define XGMAC_MTL_TXQ0_OPERATION_MODE_FTQ BIT(0)
+
+#define XGMAC_MTL_TXQ0_DEBUG_TXQSTS BIT(4)
+#define XGMAC_MTL_TXQ0_DEBUG_TRCSTS_SHIFT 1
+#define XGMAC_MTL_TXQ0_DEBUG_TRCSTS_MASK GENMASK(2, 0)
+#define XGMAC_MTL_TXQ0_DEBUG_TRCSTS_READ_STATE 0x1
+
+#define XGMAC_MTL_RXQ0_OPERATION_MODE_RQS_SHIFT 16
+#define XGMAC_MTL_RXQ0_OPERATION_MODE_RQS_MASK GENMASK(9, 0)
+#define XGMAC_MTL_RXQ0_OPERATION_MODE_EHFC BIT(7)
+#define XGMAC_MTL_RXQ0_OPERATION_MODE_RSF BIT(5)
+
+#define XGMAC_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16
+#define XGMAC_MTL_RXQ0_DEBUG_PRXQ_MASK GENMASK(14, 0)
+#define XGMAC_MTL_RXQ0_DEBUG_RXQSTS_SHIFT 4
+#define XGMAC_MTL_RXQ0_DEBUG_RXQSTS_MASK GENMASK(1, 0)
+
+/* DMA Registers */
+
+#define XGMAC_DMA_REGS_BASE 0x3000
+
+struct xgmac_dma_regs {
+ u32 mode; /* 0x3000 */
+ u32 sysbus_mode; /* 0x3004 */
+ u32 unused_3008[(0x3100 - 0x3008) / 4]; /* 0x3008 */
+ u32 ch0_control; /* 0x3100 */
+ u32 ch0_tx_control; /* 0x3104 */
+ u32 ch0_rx_control; /* 0x3108 */
+ u32 slot_func_control_status; /* 0x310c */
+ u32 ch0_txdesc_list_haddress; /* 0x3110 */
+ u32 ch0_txdesc_list_address; /* 0x3114 */
+ u32 ch0_rxdesc_list_haddress; /* 0x3118 */
+ u32 ch0_rxdesc_list_address; /* 0x311c */
+ u32 unused_3120; /* 0x3120 */
+ u32 ch0_txdesc_tail_pointer; /* 0x3124 */
+ u32 unused_3128; /* 0x3128 */
+ u32 ch0_rxdesc_tail_pointer; /* 0x312c */
+ u32 ch0_txdesc_ring_length; /* 0x3130 */
+ u32 ch0_rxdesc_ring_length; /* 0x3134 */
+ u32 unused_3138[(0x3160 - 0x3138) / 4]; /* 0x3138 */
+ u32 ch0_status; /* 0x3160 */
+};
+
+#define XGMAC_DMA_MODE_SWR BIT(0)
+#define XGMAC_DMA_SYSBUS_MODE_WR_OSR_LMT_SHIFT 24
+#define XGMAC_DMA_SYSBUS_MODE_WR_OSR_LMT_MASK GENMASK(4, 0)
+#define XGMAC_DMA_SYSBUS_MODE_RD_OSR_LMT_SHIFT 16
+#define XGMAC_DMA_SYSBUS_MODE_RD_OSR_LMT_MASK GENMASK(4, 0)
+#define XGMAC_DMA_SYSBUS_MODE_AAL BIT(12)
+#define XGMAC_DMA_SYSBUS_MODE_EAME BIT(11)
+#define XGMAC_DMA_SYSBUS_MODE_BLEN32 BIT(4)
+#define XGMAC_DMA_SYSBUS_MODE_BLEN16 BIT(3)
+#define XGMAC_DMA_SYSBUS_MODE_BLEN8 BIT(2)
+#define XGMAC_DMA_SYSBUS_MODE_BLEN4 BIT(1)
+#define XGMAC_DMA_SYSBUS_MODE_UNDEF BIT(0)
+
+#define XGMAC_DMA_CH0_CONTROL_DSL_SHIFT 18
+#define XGMAC_DMA_CH0_CONTROL_PBLX8 BIT(16)
+
+#define XGMAC_DMA_CH0_TX_CONTROL_TXPBL_SHIFT 16
+#define XGMAC_DMA_CH0_TX_CONTROL_TXPBL_MASK GENMASK(5, 0)
+#define XGMAC_DMA_CH0_TX_CONTROL_OSP BIT(4)
+#define XGMAC_DMA_CH0_TX_CONTROL_ST BIT(0)
+
+#define XGMAC_DMA_CH0_RX_CONTROL_RXPBL_SHIFT 16
+#define XGMAC_DMA_CH0_RX_CONTROL_RXPBL_MASK GENMASK(5, 0)
+#define XGMAC_DMA_CH0_RX_CONTROL_RBSZ_SHIFT 4
+#define XGMAC_DMA_CH0_RX_CONTROL_RBSZ_MASK GENMASK(10, 0)
+#define XGMAC_DMA_CH0_RX_CONTROL_SR BIT(0)
+
+/* Descriptors */
+#define XGMAC_DESCRIPTOR_WORDS 4
+#define XGMAC_DESCRIPTOR_SIZE (XGMAC_DESCRIPTOR_WORDS * 4)
+#define XGMAC_DESCRIPTORS_NUM 8
+#define XGMAC_DESCRIPTOR_ALIGN 64
+#define XGMAC_DESCRIPTORS_SIZE ALIGN(XGMAC_DESCRIPTORS_NUM * \
+ XGMAC_DESCRIPTOR_SIZE, XGMAC_DESCRIPTOR_ALIGN)
+#define XGMAC_BUFFER_ALIGN XGMAC_DESCRIPTOR_ALIGN
+#define XGMAC_MAX_PACKET_SIZE ALIGN(1568, XGMAC_DESCRIPTOR_ALIGN)
+#define XGMAC_RX_BUFFER_SIZE (XGMAC_DESCRIPTORS_NUM * XGMAC_MAX_PACKET_SIZE)
+
+#define XGMAC_RDES3_PKT_LENGTH_MASK GENMASK(13, 0)
+
+struct xgmac_desc {
+ u32 des0;
+ u32 des1;
+ u32 des2;
+ u32 des3;
+};
+
+#define XGMAC_DESC3_OWN BIT(31)
+#define XGMAC_DESC3_FD BIT(29)
+#define XGMAC_DESC3_LD BIT(28)
+
+#define XGMAC_AXI_WIDTH_32 4
+#define XGMAC_AXI_WIDTH_64 8
+#define XGMAC_AXI_WIDTH_128 16
+
+struct xgmac_config {
+ bool reg_access_always_ok;
+ int swr_wait;
+ int config_mac;
+ int config_mac_mdio;
+ unsigned int axi_bus_width;
+ phy_interface_t interface;
+ struct xgmac_ops *ops;
+};
+
+struct xgmac_ops {
+ int (*xgmac_probe_resources)(struct device *dev);
+ int (*xgmac_start_resets)(struct device *dev);
+ int (*xgmac_get_enetaddr)(struct device *dev);
+};
+
+struct xgmac_priv {
+ struct eth_device netdev;
+ struct device *dev;
+ const struct xgmac_config *config;
+ void __iomem *regs;
+ struct xgmac_mac_regs *mac_regs;
+ struct xgmac_mtl_regs *mtl_regs;
+ struct xgmac_dma_regs *dma_regs;
+ struct reset_control *rst;
+ struct reset_control *rst_ocp;
+ struct mii_bus miibus;
+ int phy_addr;
+ phy_interface_t interface;
+
+ u8 macaddr[6];
+
+ u32 reg_offset, reg_shift;
+ u32 max_speed;
+ struct xgmac_desc *tx_descs, *rx_descs;
+ dma_addr_t tx_descs_phys, rx_descs_phys;
+ dma_addr_t dma_rx_buf[XGMAC_DESCRIPTORS_NUM];
+ int tx_desc_idx, rx_desc_idx;
+ unsigned int desc_size;
+ unsigned int desc_per_cacheline;
+ void *rx_dma_buf;
+ bool started;
+ bool reg_access_ok;
+ bool clk_ck_enabled;
+};
+
+int xgmac_probe(struct device *dev);
+void xgmac_remove(struct device *dev);
+void xgmac_flush_desc_generic(void *desc);
+void xgmac_flush_buffer_generic(void *buf, size_t size);
+int xgmac_null_ops(struct device *dev);
+
+extern struct xgmac_config xgmac_socfpga_config;
diff --git a/drivers/net/designware_xgmac_socfpga.c b/drivers/net/designware_xgmac_socfpga.c
new file mode 100644
index 0000000000000000000000000000000000000000..7d8dba3c17cdb3fe7c82a6fa9315fecfdbfcc32a
--- /dev/null
+++ b/drivers/net/designware_xgmac_socfpga.c
@@ -0,0 +1,156 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023, Intel Corporation
+ */
+#define DEBUG
+#include <common.h>
+#include <init.h>
+#include <errno.h>
+#include <malloc.h>
+#include <net.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <mfd/syscon.h>
+#include <linux/clk.h>
+#include <mach/socfpga/soc64-system-manager.h>
+#include <mach/socfpga/secure_reg_helper.h>
+
+#include "designware_xgmac.h"
+
+#define SOCFPGA_XGMAC_SYSCON_ARG_COUNT 2
+
+static int dwxgmac_socfpga_do_setphy(struct device *dev, u32 modereg)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+ u32 modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK;
+ u32 index = (xgmac->reg_offset - SYSMGR_SOC64_EMAC0) >> 2;
+ u32 id = SOCFPGA_SECURE_REG_SYSMGR_SOC64_EMAC0 + index;
+ int ret;
+
+ ret = socfpga_secure_reg_update32(id, modemask, modereg);
+ if (ret) {
+ dev_err(dev, "Failed to set PHY register via SMC call\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int xgmac_probe_resources_socfpga(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+ phy_interface_t interface;
+ int ret;
+ u32 modereg;
+
+ interface = xgmac->interface;
+
+ switch (interface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ case PHY_INTERFACE_MODE_RGMII_ID:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
+ break;
+ default:
+ dev_err(dev, "Unsupported PHY mode\n");
+ return -EINVAL;
+ }
+
+ /* Get PHY syscon */
+ ret = of_property_read_u32_index(dev->of_node, "altr,sysmgr-syscon",
+ 1, &xgmac->reg_offset);
+ if (ret) {
+ dev_err(dev, "Could not read reg_offset from sysmgr-syscon! Please update the devicetree.\n");
+
+ return -EINVAL;
+ }
+
+ ret = of_property_read_u32_index(dev->of_node, "altr,sysmgr-syscon",
+ 2, &xgmac->reg_shift);
+ if (ret) {
+ dev_err(dev, "Could not read reg_shift from sysmgr-syscon! Please update the devicetree.\n");
+ return -EINVAL;
+ }
+
+ xgmac->rst = reset_control_get(dev, "stmmaceth");
+ if (IS_ERR(xgmac->rst)) {
+ dev_err(dev, "Invalid reset line 'stmmaceth'.\n");
+ return PTR_ERR(xgmac->rst);
+ }
+ xgmac->rst_ocp = reset_control_get(dev, "stmmaceth-ocp");
+ if (IS_ERR(xgmac->rst_ocp)) {
+ dev_err(dev, "Invalid reset line 'stmmaceth-ocp'.\n");
+ return PTR_ERR(xgmac->rst_ocp);
+ }
+
+ reset_control_assert(xgmac->rst_ocp);
+ reset_control_assert(xgmac->rst);
+
+ ret = dwxgmac_socfpga_do_setphy(dev, modereg);
+ if (ret)
+ return ret;
+
+ reset_control_deassert(xgmac->rst_ocp);
+ reset_control_deassert(xgmac->rst);
+
+ return 0;
+}
+
+static int xgmac_get_enetaddr_socfpga(struct device *dev)
+{
+ return -ENOTSUPP;
+}
+
+static int xgmac_start_resets_socfpga(struct device *dev)
+{
+ struct xgmac_priv *xgmac = dev_get_priv(dev);
+
+ reset_control_assert(xgmac->rst);
+ reset_control_assert(xgmac->rst_ocp);
+
+ udelay(2);
+
+ reset_control_deassert(xgmac->rst);
+ reset_control_deassert(xgmac->rst_ocp);
+
+ return 0;
+}
+
+static struct xgmac_ops xgmac_socfpga_ops = {
+ .xgmac_probe_resources = xgmac_probe_resources_socfpga,
+ .xgmac_start_resets = xgmac_start_resets_socfpga,
+ .xgmac_get_enetaddr = xgmac_get_enetaddr_socfpga,
+};
+
+struct xgmac_config __maybe_unused xgmac_socfpga_config = {
+ .reg_access_always_ok = false,
+ .swr_wait = 50,
+ .config_mac = XGMAC_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
+ .config_mac_mdio = XGMAC_MAC_MDIO_ADDRESS_CR_350_400,
+ .axi_bus_width = XGMAC_AXI_WIDTH_64,
+ .ops = &xgmac_socfpga_ops
+};
+
+static __maybe_unused struct of_device_id xgmac_socfpga_compatible[] = {
+ {
+ .compatible = "intel,socfpga-dwxgmac",
+ .data = &xgmac_socfpga_config
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(of, xgmac_socfpga_compatible);
+
+static struct driver xgmac_socfpga_driver = {
+ .name = "designware-xgmac-socfpga",
+ .probe = xgmac_probe,
+ .remove = xgmac_remove,
+ .of_compatible = DRV_OF_COMPAT(xgmac_socfpga_compatible),
+};
+device_platform_driver(xgmac_socfpga_driver);
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 07/10] net: phy: add Analog Devices ADIN1300
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (5 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 06/10] net: add support for Designware XGMAC (10gb) ethernet Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 08/10] linux: clk: add clk_parent_data Steffen Trumtrar
` (2 subsequent siblings)
9 siblings, 0 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
The Analog Devices ADIN1300 is a low power 10Mbps,100Mbps, and 1Gbps
ethernet phy.
(https://www.analog.com/media/en/technical-documentation/data-sheets/adin1300.pdf)
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/net/phy/Kconfig | 7 +
drivers/net/phy/Makefile | 1 +
drivers/net/phy/adin.c | 360 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 368 insertions(+)
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 8e12671801f39a4507937e16d2382e60c258990e..ac6fcf79027aa587b658d5f43cfbf7bb4f86f1f3 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -9,6 +9,13 @@ if PHYLIB
comment "MII PHY device drivers"
+config ADIN_PHY
+ bool "Driver for Analog Devices Industrial Ethernet PHYs"
+ help
+ Currently supports the:
+ - ADIN1300
+ Ethernet PHY
+
config AR8327N_PHY
bool "Driver for QCA AR8327N PHYs"
help
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index ce15e1bab79fb227f48dca5e9cdba2d0f7e92f7b..862a7e9ba1d19a12b272431c88d452e1434e757a 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
obj-y += phy.o mdio_bus.o phy-core.o
+obj-$(CONFIG_ADIN_PHY) += adin.o
obj-$(CONFIG_AR8327N_PHY) += ar8327.o
obj-$(CONFIG_AT803X_PHY) += at803x.o
obj-$(CONFIG_DAVICOM_PHY) += davicom.o
diff --git a/drivers/net/phy/adin.c b/drivers/net/phy/adin.c
new file mode 100644
index 0000000000000000000000000000000000000000..413722d9297d28c50633c1f6c1892a055fb728f9
--- /dev/null
+++ b/drivers/net/phy/adin.c
@@ -0,0 +1,360 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Driver for Analog Devices Industrial Ethernet PHYs
+ *
+ * Copyright 2019 Analog Devices Inc.
+ */
+#include <common.h>
+#include <init.h>
+#include <linux/bitfield.h>
+#include <linux/mdio.h>
+#include <linux/phy.h>
+#include <linux/string.h>
+
+#define PHY_ID_ADIN1200 0x0283bc20
+#define PHY_ID_ADIN1300 0x0283bc30
+
+#define ADIN1300_MII_EXT_REG_PTR 0x0010
+#define ADIN1300_MII_EXT_REG_DATA 0x0011
+
+#define ADIN1300_PHY_CTRL1 0x0012
+#define ADIN1300_AUTO_MDI_EN BIT(10)
+#define ADIN1300_MAN_MDIX_EN BIT(9)
+#define ADIN1300_DIAG_CLK_EN BIT(2)
+
+#define ADIN1300_RX_ERR_CNT 0x0014
+
+#define ADIN1300_PHY_CTRL_STATUS2 0x0015
+#define ADIN1300_NRG_PD_EN BIT(3)
+#define ADIN1300_NRG_PD_TX_EN BIT(2)
+#define ADIN1300_NRG_PD_STATUS BIT(1)
+
+#define ADIN1300_PHY_CTRL2 0x0016
+#define ADIN1300_DOWNSPEED_AN_100_EN BIT(11)
+#define ADIN1300_DOWNSPEED_AN_10_EN BIT(10)
+#define ADIN1300_GROUP_MDIO_EN BIT(6)
+#define ADIN1300_DOWNSPEEDS_EN \
+ (ADIN1300_DOWNSPEED_AN_100_EN | ADIN1300_DOWNSPEED_AN_10_EN)
+
+#define ADIN1300_PHY_CTRL3 0x0017
+#define ADIN1300_LINKING_EN BIT(13)
+#define ADIN1300_DOWNSPEED_RETRIES_MSK GENMASK(12, 10)
+
+#define ADIN1300_INT_MASK_REG 0x0018
+#define ADIN1300_INT_MDIO_SYNC_EN BIT(9)
+#define ADIN1300_INT_ANEG_STAT_CHNG_EN BIT(8)
+#define ADIN1300_INT_ANEG_PAGE_RX_EN BIT(6)
+#define ADIN1300_INT_IDLE_ERR_CNT_EN BIT(5)
+#define ADIN1300_INT_MAC_FIFO_OU_EN BIT(4)
+#define ADIN1300_INT_RX_STAT_CHNG_EN BIT(3)
+#define ADIN1300_INT_LINK_STAT_CHNG_EN BIT(2)
+#define ADIN1300_INT_SPEED_CHNG_EN BIT(1)
+#define ADIN1300_INT_HW_IRQ_EN BIT(0)
+#define ADIN1300_INT_MASK_EN \
+ (ADIN1300_INT_LINK_STAT_CHNG_EN | ADIN1300_INT_HW_IRQ_EN)
+#define ADIN1300_INT_STATUS_REG 0x0019
+
+#define ADIN1300_PHY_STATUS1 0x001a
+#define ADIN1300_PAIR_01_SWAP BIT(11)
+
+/* EEE register addresses, accessible via Clause 22 access using
+ * ADIN1300_MII_EXT_REG_PTR & ADIN1300_MII_EXT_REG_DATA.
+ * The bit-fields are the same as specified by IEEE for EEE.
+ */
+#define ADIN1300_EEE_CAP_REG 0x8000
+#define ADIN1300_EEE_ADV_REG 0x8001
+#define ADIN1300_EEE_LPABLE_REG 0x8002
+#define ADIN1300_CLOCK_STOP_REG 0x9400
+#define ADIN1300_LPI_WAKE_ERR_CNT_REG 0xa000
+
+#define ADIN1300_CDIAG_RUN 0xba1b
+#define ADIN1300_CDIAG_RUN_EN BIT(0)
+
+/*
+ * The XSIM3/2/1 and XSHRT3/2/1 are actually relative.
+ * For CDIAG_DTLD_RSLTS(0) it's ADIN1300_CDIAG_RSLT_XSIM3/2/1
+ * For CDIAG_DTLD_RSLTS(1) it's ADIN1300_CDIAG_RSLT_XSIM3/2/0
+ * For CDIAG_DTLD_RSLTS(2) it's ADIN1300_CDIAG_RSLT_XSIM3/1/0
+ * For CDIAG_DTLD_RSLTS(3) it's ADIN1300_CDIAG_RSLT_XSIM2/1/0
+ */
+#define ADIN1300_CDIAG_DTLD_RSLTS(x) (0xba1d + (x))
+#define ADIN1300_CDIAG_RSLT_BUSY BIT(10)
+#define ADIN1300_CDIAG_RSLT_XSIM3 BIT(9)
+#define ADIN1300_CDIAG_RSLT_XSIM2 BIT(8)
+#define ADIN1300_CDIAG_RSLT_XSIM1 BIT(7)
+#define ADIN1300_CDIAG_RSLT_SIM BIT(6)
+#define ADIN1300_CDIAG_RSLT_XSHRT3 BIT(5)
+#define ADIN1300_CDIAG_RSLT_XSHRT2 BIT(4)
+#define ADIN1300_CDIAG_RSLT_XSHRT1 BIT(3)
+#define ADIN1300_CDIAG_RSLT_SHRT BIT(2)
+#define ADIN1300_CDIAG_RSLT_OPEN BIT(1)
+#define ADIN1300_CDIAG_RSLT_GOOD BIT(0)
+
+#define ADIN1300_CDIAG_FLT_DIST(x) (0xba21 + (x))
+
+#define ADIN1300_GE_SOFT_RESET_REG 0xff0c
+#define ADIN1300_GE_SOFT_RESET BIT(0)
+
+#define ADIN1300_GE_CLK_CFG_REG 0xff1f
+#define ADIN1300_GE_CLK_CFG_MASK GENMASK(5, 0)
+#define ADIN1300_GE_CLK_CFG_RCVR_125 BIT(5)
+#define ADIN1300_GE_CLK_CFG_FREE_125 BIT(4)
+#define ADIN1300_GE_CLK_CFG_REF_EN BIT(3)
+#define ADIN1300_GE_CLK_CFG_HRT_RCVR BIT(2)
+#define ADIN1300_GE_CLK_CFG_HRT_FREE BIT(1)
+#define ADIN1300_GE_CLK_CFG_25 BIT(0)
+
+#define ADIN1300_GE_RGMII_CFG_REG 0xff23
+#define ADIN1300_GE_RGMII_RX_MSK GENMASK(8, 6)
+#define ADIN1300_GE_RGMII_RX_SEL(x) \
+ FIELD_PREP(ADIN1300_GE_RGMII_RX_MSK, x)
+#define ADIN1300_GE_RGMII_GTX_MSK GENMASK(5, 3)
+#define ADIN1300_GE_RGMII_GTX_SEL(x) \
+ FIELD_PREP(ADIN1300_GE_RGMII_GTX_MSK, x)
+#define ADIN1300_GE_RGMII_RXID_EN BIT(2)
+#define ADIN1300_GE_RGMII_TXID_EN BIT(1)
+#define ADIN1300_GE_RGMII_EN BIT(0)
+
+/* RGMII internal delay settings for rx and tx for ADIN1300 */
+#define ADIN1300_RGMII_1_60_NS 0x0001
+#define ADIN1300_RGMII_1_80_NS 0x0002
+#define ADIN1300_RGMII_2_00_NS 0x0000
+#define ADIN1300_RGMII_2_20_NS 0x0006
+#define ADIN1300_RGMII_2_40_NS 0x0007
+
+#define ADIN1300_GE_RMII_CFG_REG 0xff24
+#define ADIN1300_GE_RMII_FIFO_DEPTH_MSK GENMASK(6, 4)
+#define ADIN1300_GE_RMII_FIFO_DEPTH_SEL(x) \
+ FIELD_PREP(ADIN1300_GE_RMII_FIFO_DEPTH_MSK, x)
+#define ADIN1300_GE_RMII_EN BIT(0)
+
+/* RMII fifo depth values */
+#define ADIN1300_RMII_4_BITS 0x0000
+#define ADIN1300_RMII_8_BITS 0x0001
+#define ADIN1300_RMII_12_BITS 0x0002
+#define ADIN1300_RMII_16_BITS 0x0003
+#define ADIN1300_RMII_20_BITS 0x0004
+#define ADIN1300_RMII_24_BITS 0x0005
+
+/**
+ * struct adin_cfg_reg_map - map a config value to aregister value
+ * @cfg: value in device configuration
+ * @reg: value in the register
+ */
+struct adin_cfg_reg_map {
+ int cfg;
+ int reg;
+};
+
+static const struct adin_cfg_reg_map adin_rgmii_delays[] = {
+ { 1600, ADIN1300_RGMII_1_60_NS },
+ { 1800, ADIN1300_RGMII_1_80_NS },
+ { 2000, ADIN1300_RGMII_2_00_NS },
+ { 2200, ADIN1300_RGMII_2_20_NS },
+ { 2400, ADIN1300_RGMII_2_40_NS },
+ { },
+};
+
+static const struct adin_cfg_reg_map adin_rmii_fifo_depths[] = {
+ { 4, ADIN1300_RMII_4_BITS },
+ { 8, ADIN1300_RMII_8_BITS },
+ { 12, ADIN1300_RMII_12_BITS },
+ { 16, ADIN1300_RMII_16_BITS },
+ { 20, ADIN1300_RMII_20_BITS },
+ { 24, ADIN1300_RMII_24_BITS },
+ { },
+};
+
+static int adin_lookup_reg_value(const struct adin_cfg_reg_map *tbl, int cfg)
+{
+ size_t i;
+
+ for (i = 0; tbl[i].cfg; i++) {
+ if (tbl[i].cfg == cfg)
+ return tbl[i].reg;
+ }
+
+ return -EINVAL;
+}
+
+static u32 adin_get_reg_value(struct phy_device *phydev,
+ const char *prop_name,
+ const struct adin_cfg_reg_map *tbl,
+ u32 dflt)
+{
+ struct device *dev = &phydev->bus->dev;
+ u32 val;
+ int rc;
+
+ if (of_property_read_u32(dev->of_node, prop_name, &val))
+ return dflt;
+
+ rc = adin_lookup_reg_value(tbl, val);
+ if (rc < 0) {
+ phydev_warn(phydev,
+ "Unsupported value %u for %s using default (%u)\n",
+ val, prop_name, dflt);
+ return dflt;
+ }
+
+ return rc;
+}
+
+static u16 adin_ext_read(struct phy_device *phydev, const u32 regnum)
+{
+ u16 val;
+
+ phy_write(phydev, ADIN1300_MII_EXT_REG_PTR, regnum);
+ val = phy_read(phydev, ADIN1300_MII_EXT_REG_DATA);
+
+ debug("%s: adin@0x%x 0x%x=0x%x\n", __func__, phydev->addr, regnum, val);
+
+ return val;
+}
+
+static int adin_ext_write(struct phy_device *phydev, const u32 regnum, const u16 val)
+{
+ debug("%s: adin@0x%x 0x%x=0x%x\n", __func__, phydev->addr, regnum, val);
+
+ phy_write(phydev, ADIN1300_MII_EXT_REG_PTR, regnum);
+
+ return phy_write(phydev, ADIN1300_MII_EXT_REG_DATA, val);
+}
+
+static int adin_config_rgmii_mode(struct phy_device *phydev)
+{
+ u32 val;
+ int reg;
+
+ if (!phy_interface_is_rgmii(phydev))
+ return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_RGMII_CFG_REG,
+ ADIN1300_GE_RGMII_EN);
+
+ reg = adin_ext_read(phydev, ADIN1300_GE_RGMII_CFG_REG);
+ if (reg < 0)
+ return reg;
+
+ reg |= ADIN1300_GE_RGMII_EN;
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
+ reg |= ADIN1300_GE_RGMII_RXID_EN;
+
+ val = adin_get_reg_value(phydev, "adi,rx-internal-delay-ps",
+ adin_rgmii_delays,
+ ADIN1300_RGMII_2_00_NS);
+ reg &= ~ADIN1300_GE_RGMII_RX_MSK;
+ reg |= ADIN1300_GE_RGMII_RX_SEL(val);
+ } else {
+ reg &= ~ADIN1300_GE_RGMII_RXID_EN;
+ }
+
+ if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+ phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+ reg |= ADIN1300_GE_RGMII_TXID_EN;
+
+ val = adin_get_reg_value(phydev, "adi,tx-internal-delay-ps",
+ adin_rgmii_delays,
+ ADIN1300_RGMII_2_00_NS);
+ reg &= ~ADIN1300_GE_RGMII_GTX_MSK;
+ reg |= ADIN1300_GE_RGMII_GTX_SEL(val);
+ } else {
+ reg &= ~ADIN1300_GE_RGMII_TXID_EN;
+ }
+
+ return adin_ext_write(phydev, ADIN1300_GE_RGMII_CFG_REG, reg);
+}
+
+static int adin_config_rmii_mode(struct phy_device *phydev)
+{
+ u32 val;
+ int reg;
+
+ if (phydev->interface != PHY_INTERFACE_MODE_RMII)
+ return phy_clear_bits_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_RMII_CFG_REG,
+ ADIN1300_GE_RMII_EN);
+
+ reg = phy_read_mmd(phydev, MDIO_MMD_VEND1, ADIN1300_GE_RMII_CFG_REG);
+ if (reg < 0)
+ return reg;
+
+ reg |= ADIN1300_GE_RMII_EN;
+
+ val = adin_get_reg_value(phydev, "adi,fifo-depth-bits",
+ adin_rmii_fifo_depths,
+ ADIN1300_RMII_8_BITS);
+
+ reg &= ~ADIN1300_GE_RMII_FIFO_DEPTH_MSK;
+ reg |= ADIN1300_GE_RMII_FIFO_DEPTH_SEL(val);
+
+ return phy_write_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_RMII_CFG_REG, reg);
+}
+
+static int adin_config_init(struct phy_device *phydev)
+{
+ int rc;
+
+ rc = adin_config_rgmii_mode(phydev);
+ if (rc < 0)
+ return rc;
+
+ rc = adin_config_rmii_mode(phydev);
+ if (rc < 0)
+ return rc;
+
+ return genphy_config_init(phydev);
+}
+
+static int adin_soft_reset(struct phy_device *phydev)
+{
+ int rc;
+
+ /* Read link and autonegotiation status */
+ /* The reset bit is self-clearing, set it and wait */
+ rc = phy_set_bits_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_SOFT_RESET_REG,
+ ADIN1300_GE_SOFT_RESET);
+ if (rc < 0)
+ return rc;
+
+ mdelay(20);
+
+ /* If we get a read error something may be wrong */
+ rc = phy_read_mmd(phydev, MDIO_MMD_VEND1,
+ ADIN1300_GE_SOFT_RESET_REG);
+
+ return rc < 0 ? rc : 0;
+}
+
+static int adin_config_aneg(struct phy_device *phydev)
+{
+ int ret;
+
+ ret = genphy_config_aneg(phydev);
+ if (ret < 0)
+ return ret;
+
+ /* Enable Autonegotiation */
+ phy_write(phydev, MII_BMCR, BMCR_ANENABLE);
+ phydev->autoneg = AUTONEG_ENABLE;
+
+ return 0;
+}
+
+static struct phy_driver adin_driver[] = {
+ {
+ .phy_id = 0x0283bc30,
+ .phy_id_mask = 0xffffffff,
+ .drv.name = "ADIN1300",
+ .features = PHY_GBIT_FEATURES,
+ .config_init = adin_config_init,
+ .soft_reset = adin_soft_reset,
+ .config_aneg = adin_config_aneg,
+ .read_status = genphy_read_status,
+ },
+};
+
+device_phy_drivers(adin_driver);
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 08/10] linux: clk: add clk_parent_data
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (6 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 07/10] net: phy: add Analog Devices ADIN1300 Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 09/10] clk: support init->parent_data Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 10/10] clk: socfpga: add agilex5 clock support Steffen Trumtrar
9 siblings, 0 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Some linux clock drivers use the clk_parent_data struct.
Import it from linux to make driver porting easier.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
include/linux/clk.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index ae03dcfdb2a27266188bdec99da74f861c8b8846..b7a7b8138a555c0508821d313ade153cd720195e 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -333,6 +333,20 @@ struct clk_ops {
int (*get_phase)(struct clk_hw *hw);
};
+/**
+ * struct clk_parent_data - clk parent information
+ * @hw: parent clk_hw pointer (used for clk providers with internal clks)
+ * @fw_name: parent name local to provider registering clk
+ * @name: globally unique parent name (used as a fallback)
+ * @index: parent index local to provider registering clk (if @fw_name absent)
+ */
+struct clk_parent_data {
+ const struct clk_hw *hw;
+ const char *fw_name;
+ const char *name;
+ int index;
+};
+
/**
* struct clk_init_data - holds init data that's common to all clocks and is
* shared between the clock provider and the common clock framework.
@@ -349,6 +363,7 @@ struct clk_init_data {
const char *name;
const struct clk_ops *ops;
const char * const *parent_names;
+ const struct clk_parent_data *parent_data;
const struct clk_hw **parent_hws;
unsigned int num_parents;
unsigned long flags;
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 09/10] clk: support init->parent_data
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (7 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 08/10] linux: clk: add clk_parent_data Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 10/10] clk: socfpga: add agilex5 clock support Steffen Trumtrar
9 siblings, 0 replies; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Linux clk driver supports matching parents via init->parent_data instead
of init->parent_names.
Add support for this feature to barebox, too.
Linux however supports setting a "name" and "fw_name" for a parent
clock. "fw_name" is a local name for the provider registering the clock
and "name" is a globally unique parent name. For the time being, only
support the globally unique "name" field.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/clk/clk.c | 48 ++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 8 deletions(-)
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index bd368782804c9a2cce1ced7826501363c0c2ab2d..be4060e6d5a0d7ecbed729b4d96570d7980f5857 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -476,11 +476,28 @@ int bclk_register(struct clk *clk)
return ret;
}
+static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
+{
+ const char *dst;
+
+ if (!src) {
+ if (must_exist)
+ return -EINVAL;
+ return 0;
+ }
+
+ *dst_p = dst = xstrdup(src);
+ if (!dst)
+ return -ENOMEM;
+
+ return 0;
+}
+
struct clk *clk_register(struct device *dev, struct clk_hw *hw)
{
struct clk *clk;
const struct clk_init_data *init = hw->init;
- char **parent_names = NULL;
+ const char **parent_names = NULL;
int i, ret;
if (!hw->init)
@@ -496,14 +513,29 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
clk->parents = xzalloc(sizeof(struct clk *) * clk->num_parents);
- if (init->parent_names) {
+ if (init->parent_names || init->parent_data) {
parent_names = xzalloc(init->num_parents * sizeof(char *));
- for (i = 0; i < init->num_parents; i++)
- parent_names[i] = xstrdup(init->parent_names[i]);
-
- clk->parent_names = (const char *const*)parent_names;
-
+ for (i = 0; i < init->num_parents; i++) {
+ if (init->parent_names) {
+ ret = clk_cpy_name(&parent_names[i],
+ init->parent_names[i], true);
+ } else if (init->parent_data) {
+ /* Linux copies fw_name and if successful also name.
+ * As fw_name is not handled in barebox, just copy the
+ * name field and fallback to hw->clk.name if it doesn't
+ * exist.
+ */
+ ret = clk_cpy_name(&parent_names[i],
+ init->parent_data[i].name,
+ true);
+ if (ret)
+ ret = clk_cpy_name(&parent_names[i],
+ init->parent_data[i].hw->clk.name,
+ false);
+ }
+ }
+ clk->parent_names = (const char *const *)parent_names;
} else {
for (i = 0; i < init->num_parents; i++)
clk->parents[i] = clk_hw_to_clk(init->parent_hws[i]);
@@ -515,7 +547,7 @@ struct clk *clk_register(struct device *dev, struct clk_hw *hw)
if (ret) {
if (parent_names) {
for (i = 0; i < init->num_parents; i++)
- free(parent_names[i]);
+ free(&parent_names[i]);
free(parent_names);
}
free(clk->parents);
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH 10/10] clk: socfpga: add agilex5 clock support
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
` (8 preceding siblings ...)
2024-10-29 8:42 ` [PATCH 09/10] clk: support init->parent_data Steffen Trumtrar
@ 2024-10-29 8:42 ` Steffen Trumtrar
2024-11-04 11:23 ` Sascha Hauer
9 siblings, 1 reply; 15+ messages in thread
From: Steffen Trumtrar @ 2024-10-29 8:42 UTC (permalink / raw)
To: barebox; +Cc: Steffen Trumtrar
Add support for the Stratix10 and Agilex5 pll,gate and periph clocks.
Only tested on Agilex5.
Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
---
drivers/clk/socfpga/Makefile | 4 +-
drivers/clk/socfpga/clk-agilex5.c | 834 ++++++++++++++++++++++++++++++
drivers/clk/socfpga/clk-gate-s10.c | 184 +++++++
drivers/clk/socfpga/clk-periph-s10.c | 163 ++++++
drivers/clk/socfpga/clk-pll-s10.c | 140 +++++
drivers/clk/socfpga/clk.h | 9 +
drivers/clk/socfpga/stratix10-clk.h | 73 +++
include/dt-bindings/clock/agilex5-clock.h | 135 +++--
8 files changed, 1488 insertions(+), 54 deletions(-)
diff --git a/drivers/clk/socfpga/Makefile b/drivers/clk/socfpga/Makefile
index 0a195cbf3f8efe2828cc2eade549d550001f0ca1..bd6f2266fc6847d3201d3fcb536e8061816ac8e3 100644
--- a/drivers/clk/socfpga/Makefile
+++ b/drivers/clk/socfpga/Makefile
@@ -1,4 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
-obj-y += clk.o
+obj-$(CONFIG_ARCH_SOCFPGA_CYCLONE5) += clk.o
+obj-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += clk.o
obj-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += clk-gate-a10.o clk-periph-a10.o clk-pll-a10.o
+obj-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += clk-agilex5.o clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o
diff --git a/drivers/clk/socfpga/clk-agilex5.c b/drivers/clk/socfpga/clk-agilex5.c
new file mode 100644
index 0000000000000000000000000000000000000000..b6452b960b4fb0a03901c79617e9375185426cf9
--- /dev/null
+++ b/drivers/clk/socfpga/clk-agilex5.c
@@ -0,0 +1,834 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022, Intel Corporation
+ */
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+
+#include <dt-bindings/clock/agilex5-clock.h>
+
+#include "stratix10-clk.h"
+
+static const struct clk_parent_data pll_mux[] = {
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data boot_mux[] = {
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+};
+
+static const struct clk_parent_data core0_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c0",
+ .name = "peri_pll_c0",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data core1_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c0",
+ .name = "peri_pll_c0",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data core2_free_mux[] = {
+ {
+ .fw_name = "main_pll_c0",
+ .name = "main_pll_c0",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data core3_free_mux[] = {
+ {
+ .fw_name = "main_pll_c0",
+ .name = "main_pll_c0",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data dsu_free_mux[] = {
+ {
+ .fw_name = "main_pll_c2",
+ .name = "main_pll_c2",
+ },
+ {
+ .fw_name = "peri_pll_c0",
+ .name = "peri_pll_c0",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data noc_free_mux[] = {
+ {
+ .fw_name = "main_pll_c3",
+ .name = "main_pll_c3",
+ },
+ {
+ .fw_name = "peri_pll_c1",
+ .name = "peri_pll_c1",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data emaca_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data emacb_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data emac_ptp_free_mux[] = {
+ {
+ .fw_name = "main_pll_c3",
+ .name = "main_pll_c3",
+ },
+ {
+ .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data gpio_db_free_mux[] = {
+ {
+ .fw_name = "main_pll_c3",
+ .name = "main_pll_c3",
+ },
+ {
+ .fw_name = "peri_pll_c1",
+ .name = "peri_pll_c1",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data psi_ref_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data usb31_free_mux[] = {
+ {
+ .fw_name = "main_pll_c3",
+ .name = "main_pll_c3",
+ },
+ {
+ .fw_name = "peri_pll_c2",
+ .name = "peri_pll_c2",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data s2f_usr0_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data s2f_usr1_free_mux[] = {
+ {
+ .fw_name = "main_pll_c1",
+ .name = "main_pll_c1",
+ },
+ {
+ .fw_name = "peri_pll_c3",
+ .name = "peri_pll_c3",
+ },
+ {
+ .fw_name = "osc1",
+ .name = "osc1",
+ },
+ {
+ .fw_name = "cb-intosc-hs-div2-clk",
+ .name = "cb-intosc-hs-div2-clk",
+ },
+ {
+ .fw_name = "f2s-free-clk",
+ .name = "f2s-free-clk",
+ },
+};
+
+static const struct clk_parent_data core0_mux[] = {
+ {
+ .fw_name = "core0_free_clk",
+ .name = "core0_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data core1_mux[] = {
+ {
+ .fw_name = "core1_free_clk",
+ .name = "core1_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data core2_mux[] = {
+ {
+ .fw_name = "core2_free_clk",
+ .name = "core2_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data core3_mux[] = {
+ {
+ .fw_name = "core3_free_clk",
+ .name = "core3_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data dsu_mux[] = {
+ {
+ .fw_name = "dsu_free_clk",
+ .name = "dsu_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data emac_mux[] = {
+ {
+ .fw_name = "emaca_free_clk",
+ .name = "emaca_free_clk",
+ },
+ {
+ .fw_name = "emacb_free_clk",
+ .name = "emacb_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data noc_mux[] = {
+ {
+ .fw_name = "noc_free_clk",
+ .name = "noc_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data s2f_user0_mux[] = {
+ {
+ .fw_name = "s2f_user0_free_clk",
+ .name = "s2f_user0_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data s2f_user1_mux[] = {
+ {
+ .fw_name = "s2f_user1_free_clk",
+ .name = "s2f_user1_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data psi_mux[] = {
+ {
+ .fw_name = "psi_ref_free_clk",
+ .name = "psi_ref_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data gpio_db_mux[] = {
+ {
+ .fw_name = "gpio_db_free_clk",
+ .name = "gpio_db_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data emac_ptp_mux[] = {
+ {
+ .fw_name = "emac_ptp_free_clk",
+ .name = "emac_ptp_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+static const struct clk_parent_data usb31_mux[] = {
+ {
+ .fw_name = "usb31_free_clk",
+ .name = "usb31_free_clk",
+ },
+ {
+ .fw_name = "boot_clk",
+ .name = "boot_clk",
+ },
+};
+
+/*
+ * TODO - Clocks in AO (always on) controller
+ * 2 main PLLs only
+ */
+static const struct stratix10_pll_clock agilex5_pll_clks[] = {
+ { AGILEX5_BOOT_CLK, "boot_clk", boot_mux, ARRAY_SIZE(boot_mux), 0,
+ 0x0 },
+ { AGILEX5_MAIN_PLL_CLK, "main_pll", pll_mux, ARRAY_SIZE(pll_mux), 0,
+ 0x48 },
+ { AGILEX5_PERIPH_PLL_CLK, "periph_pll", pll_mux, ARRAY_SIZE(pll_mux), 0,
+ 0x9C },
+};
+
+static const struct stratix10_perip_c_clock agilex5_main_perip_c_clks[] = {
+ { AGILEX5_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0,
+ 0x5C },
+ { AGILEX5_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0,
+ 0x60 },
+ { AGILEX5_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0,
+ 0x64 },
+ { AGILEX5_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0,
+ 0x68 },
+ { AGILEX5_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0,
+ 0xB0 },
+ { AGILEX5_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0,
+ 0xB4 },
+ { AGILEX5_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0,
+ 0xB8 },
+ { AGILEX5_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0,
+ 0xBC },
+};
+
+/* Non-SW clock-gated enabled clocks */
+static const struct stratix10_perip_cnt_clock agilex5_main_perip_cnt_clks[] = {
+ { AGILEX5_CORE0_FREE_CLK, "core0_free_clk", NULL, core0_free_mux,
+ ARRAY_SIZE(core0_free_mux), 0, 0x0104, 0, 0, 0},
+ { AGILEX5_CORE1_FREE_CLK, "core1_free_clk", NULL, core1_free_mux,
+ ARRAY_SIZE(core1_free_mux), 0, 0x0104, 0, 0, 0},
+ { AGILEX5_CORE2_FREE_CLK, "core2_free_clk", NULL, core2_free_mux,
+ ARRAY_SIZE(core2_free_mux), 0, 0x010C, 0, 0, 0},
+ { AGILEX5_CORE3_FREE_CLK, "core3_free_clk", NULL, core3_free_mux,
+ ARRAY_SIZE(core3_free_mux), 0, 0x0110, 0, 0, 0},
+ { AGILEX5_DSU_FREE_CLK, "dsu_free_clk", NULL, dsu_free_mux,
+ ARRAY_SIZE(dsu_free_mux), 0, 0x0100, 0, 0, 0},
+ { AGILEX5_NOC_FREE_CLK, "noc_free_clk", NULL, noc_free_mux,
+ ARRAY_SIZE(noc_free_mux), 0, 0x40, 0, 0, 0 },
+ { AGILEX5_EMAC_A_FREE_CLK, "emaca_free_clk", NULL, emaca_free_mux,
+ ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0 },
+ { AGILEX5_EMAC_B_FREE_CLK, "emacb_free_clk", NULL, emacb_free_mux,
+ ARRAY_SIZE(emacb_free_mux), 0, 0xD8, 0, 0x88, 1 },
+ { AGILEX5_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", NULL,
+ emac_ptp_free_mux, ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88,
+ 2 },
+ { AGILEX5_GPIO_DB_FREE_CLK, "gpio_db_free_clk", NULL, gpio_db_free_mux,
+ ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3 },
+ { AGILEX5_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", NULL,
+ s2f_usr0_free_mux, ARRAY_SIZE(s2f_usr0_free_mux), 0, 0xE8, 0, 0x30,
+ 2 },
+ { AGILEX5_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", NULL,
+ s2f_usr1_free_mux, ARRAY_SIZE(s2f_usr1_free_mux), 0, 0xEC, 0, 0x88,
+ 5 },
+ { AGILEX5_PSI_REF_FREE_CLK, "psi_ref_free_clk", NULL, psi_ref_free_mux,
+ ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6 },
+ { AGILEX5_USB31_FREE_CLK, "usb31_free_clk", NULL, usb31_free_mux,
+ ARRAY_SIZE(usb31_free_mux), 0, 0xF8, 0, 0x88, 7},
+};
+
+/* SW Clock gate enabled clocks */
+static const struct stratix10_gate_clock agilex5_gate_clks[] = {
+
+ /* TODO HW Managed Clocks list */
+
+ /* TODO SW Managed Clocks list */
+
+ /* Main PLL0 Begin */
+ /* MPU clocks */
+ { AGILEX5_CORE0_CLK, "core0_clk", NULL, core0_mux,
+ ARRAY_SIZE(core0_mux), 0, 0x24, 8, 0, 0, 0, 0x30, 5, 0 },
+ { AGILEX5_CORE1_CLK, "core1_clk", NULL, core1_mux,
+ ARRAY_SIZE(core1_mux), 0, 0x24, 9, 0, 0, 0, 0x30, 5, 0 },
+ { AGILEX5_CORE2_CLK, "core2_clk", NULL, core2_mux,
+ ARRAY_SIZE(core2_mux), 0, 0x24, 10, 0, 0, 0, 0x30, 6, 0 },
+ { AGILEX5_CORE3_CLK, "core3_clk", NULL, core3_mux,
+ ARRAY_SIZE(core3_mux), 0, 0x24, 11, 0, 0, 0, 0x30, 7, 0 },
+ { AGILEX5_MPU_CLK, "dsu_clk", NULL, dsu_mux, ARRAY_SIZE(dsu_mux), 0, 0,
+ 0, 0, 0, 0, 0x34, 4, 0 },
+ { AGILEX5_MPU_PERIPH_CLK, "mpu_periph_clk", NULL, dsu_mux,
+ ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 20, 2, 0x34, 4, 0 },
+ { AGILEX5_MPU_CCU_CLK, "mpu_ccu_clk", NULL, dsu_mux,
+ ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 18, 2, 0x34, 4, 0 },
+
+ /* ANGTS TODO l4 main clk has no divider now. To check. */
+ { AGILEX5_L4_MAIN_CLK, "l4_main_clk", NULL, noc_mux,
+ ARRAY_SIZE(noc_mux), 0, 0x24, 1, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_L4_MP_CLK, "l4_mp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
+ 0x24, 2, 0x44, 4, 2, 0x30, 1, 0 },
+ { AGILEX5_L4_SYS_FREE_CLK, "l4_sys_free_clk", NULL, noc_mux,
+ ARRAY_SIZE(noc_mux), 0, 0, 0, 0x44, 2, 2, 0x30, 1, 0 },
+ { AGILEX5_L4_SP_CLK, "l4_sp_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux),
+ CLK_IS_CRITICAL, 0x24, 3, 0x44, 6, 2, 0x30, 1, 0 },
+
+ /* Core sight clocks*/
+ { AGILEX5_CS_AT_CLK, "cs_at_clk", NULL, noc_mux, ARRAY_SIZE(noc_mux), 0,
+ 0x24, 4, 0x44, 24, 2, 0x30, 1, 0 },
+ { AGILEX5_CS_TRACE_CLK, "cs_trace_clk", NULL, noc_mux,
+ ARRAY_SIZE(noc_mux), 0, 0x24, 4, 0x44, 26, 2, 0x30, 1, 0 },
+ { AGILEX5_CS_PDBG_CLK, "cs_pdbg_clk", "cs_at_clk", NULL, 1, 0, 0x24, 4,
+ 0x44, 28, 1, 0, 0, 0 },
+ /* Main PLL0 End */
+
+ /* Main Peripheral PLL1 Begin */
+ { AGILEX5_EMAC0_CLK, "emac0_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux),
+ 0, 0x7C, 0, 0, 0, 0, 0x94, 26, 0 },
+ { AGILEX5_EMAC1_CLK, "emac1_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux),
+ 0, 0x7C, 1, 0, 0, 0, 0x94, 27, 0 },
+ { AGILEX5_EMAC2_CLK, "emac2_clk", NULL, emac_mux, ARRAY_SIZE(emac_mux),
+ 0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0 },
+ { AGILEX5_EMAC_PTP_CLK, "emac_ptp_clk", NULL, emac_ptp_mux,
+ ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, 3, 0, 0, 0, 0x88, 2, 0 },
+ { AGILEX5_GPIO_DB_CLK, "gpio_db_clk", NULL, gpio_db_mux,
+ ARRAY_SIZE(gpio_db_mux), 0, 0x7C, 4, 0x98, 0, 16, 0x88, 3, 1 },
+ /* Main Peripheral PLL1 End */
+
+ /* Peripheral clocks */
+ { AGILEX5_S2F_USER0_CLK, "s2f_user0_clk", NULL, s2f_user0_mux,
+ ARRAY_SIZE(s2f_user0_mux), 0, 0x24, 6, 0, 0, 0, 0x30, 2, 0 },
+ { AGILEX5_S2F_USER1_CLK, "s2f_user1_clk", NULL, s2f_user1_mux,
+ ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0 },
+ { AGILEX5_PSI_REF_CLK, "psi_ref_clk", NULL, psi_mux,
+ ARRAY_SIZE(psi_mux), 0, 0x7C, 7, 0, 0, 0, 0x88, 6, 0 },
+ { AGILEX5_USB31_SUSPEND_CLK, "usb31_suspend_clk", NULL, usb31_mux,
+ ARRAY_SIZE(usb31_mux), 0, 0x7C, 25, 0, 0, 0, 0x88, 7, 0 },
+ { AGILEX5_USB31_BUS_CLK_EARLY, "usb31_bus_clk_early", "l4_main_clk",
+ NULL, 1, 0, 0x7C, 25, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_USB2OTG_HCLK, "usb2otg_hclk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+ 8, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SPIM_0_CLK, "spim_0_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 9,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SPIM_1_CLK, "spim_1_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 11,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SPIS_0_CLK, "spis_0_clk", "l4_sp_clk", NULL, 1, 0, 0x7C, 12,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SPIS_1_CLK, "spis_1_clk", "l4_sp_clk", NULL, 1, 0, 0x7C, 13,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_DMA_CORE_CLK, "dma_core_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+ 14, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_DMA_HS_CLK, "dma_hs_clk", "l4_mp_clk", NULL, 1, 0, 0x7C, 14,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I3C_0_CORE_CLK, "i3c_0_core_clk", "l4_mp_clk", NULL, 1, 0,
+ 0x7C, 18, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I3C_1_CORE_CLK, "i3c_1_core_clk", "l4_mp_clk", NULL, 1, 0,
+ 0x7C, 19, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I2C_0_PCLK, "i2c_0_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 15,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I2C_1_PCLK, "i2c_1_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 16,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I2C_EMAC0_PCLK, "i2c_emac0_pclk", "l4_sp_clk", NULL, 1, 0,
+ 0x7C, 17, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I2C_EMAC1_PCLK, "i2c_emac1_pclk", "l4_sp_clk", NULL, 1, 0,
+ 0x7C, 22, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_I2C_EMAC2_PCLK, "i2c_emac2_pclk", "l4_sp_clk", NULL, 1, 0,
+ 0x7C, 27, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_UART_0_PCLK, "uart_0_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 20,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_UART_1_PCLK, "uart_1_pclk", "l4_sp_clk", NULL, 1, 0, 0x7C, 21,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SPTIMER_0_PCLK, "sptimer_0_pclk", "l4_sp_clk", NULL, 1, 0,
+ 0x7C, 23, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SPTIMER_1_PCLK, "sptimer_1_pclk", "l4_sp_clk", NULL, 1, 0,
+ 0x7C, 24, 0, 0, 0, 0, 0, 0 },
+
+ /*NAND, SD/MMC and SoftPHY overall clocking*/
+ { AGILEX5_DFI_CLK, "dfi_clk", "l4_mp_clk", NULL, 1, 0, 0, 0, 0x44, 16,
+ 2, 0, 0, 0 },
+ { AGILEX5_NAND_NF_CLK, "nand_nf_clk", "dfi_clk", NULL, 1, 0, 0x7C, 10,
+ 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_NAND_BCH_CLK, "nand_bch_clk", "l4_mp_clk", NULL, 1, 0, 0x7C,
+ 10, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SDMMC_SDPHY_REG_CLK, "sdmmc_sdphy_reg_clk", "l4_mp_clk", NULL,
+ 1, 0, 0x7C, 5, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SDMCLK, "sdmclk", "dfi_clk", NULL, 1, 0, 0x7C, 5, 0, 0, 0, 0,
+ 0, 0 },
+ { AGILEX5_SOFTPHY_REG_PCLK, "softphy_reg_pclk", "l4_mp_clk", NULL, 1, 0,
+ 0x7C, 26, 0, 0, 0, 0, 0, 0 },
+ { AGILEX5_SOFTPHY_PHY_CLK, "softphy_phy_clk", "l4_mp_clk", NULL, 1, 0,
+ 0x7C, 26, 0x44, 16, 2, 0, 0, 0 },
+ { AGILEX5_SOFTPHY_CTRL_CLK, "softphy_ctrl_clk", "dfi_clk", NULL, 1, 0,
+ 0x7C, 26, 0, 0, 0, 0, 0, 0 },
+};
+
+static int
+agilex5_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
+ int nums, struct stratix10_clock_data *data)
+{
+ struct clk_hw *hw_clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ hw_clk = s10_register_periph(&clks[i], base);
+ if (IS_ERR(hw_clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ clks[i].name);
+ continue;
+ }
+ data->clk_data.hws[clks[i].id] = hw_clk;
+ }
+ return 0;
+}
+
+static int
+agilex5_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *clks,
+ int nums, struct stratix10_clock_data *data)
+{
+ struct clk_hw *hw_clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ hw_clk = s10_register_cnt_periph(&clks[i], base);
+ if (IS_ERR(hw_clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ clks[i].name);
+ continue;
+ }
+ data->clk_data.hws[clks[i].id] = hw_clk;
+ }
+
+ return 0;
+}
+
+static int agilex5_clk_register_gate(const struct stratix10_gate_clock *clks,
+ int nums,
+ struct stratix10_clock_data *data)
+{
+ struct clk_hw *hw_clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ hw_clk = agilex_register_gate(&clks[i], base);
+ if (IS_ERR(hw_clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ clks[i].name);
+ continue;
+ }
+ data->clk_data.hws[clks[i].id] = hw_clk;
+ }
+
+ return 0;
+}
+
+static int agilex5_clk_register_pll(const struct stratix10_pll_clock *clks,
+ int nums, struct stratix10_clock_data *data)
+{
+ struct clk_hw *hw_clk;
+ void __iomem *base = data->base;
+ int i;
+
+ for (i = 0; i < nums; i++) {
+ hw_clk = agilex5_register_pll(&clks[i], base);
+ if (IS_ERR(hw_clk)) {
+ pr_err("%s: failed to register clock %s\n", __func__,
+ clks[i].name);
+ continue;
+ }
+ data->clk_data.hws[clks[i].id] = hw_clk;
+ }
+
+ return 0;
+}
+
+static int agilex5_clkmgr_probe(struct device *dev)
+{
+ struct device_node *np = dev->of_node;
+ struct stratix10_clock_data *clk_data;
+ struct resource *res;
+ int i, num_clks;
+
+ res = dev_get_resource(dev, IORESOURCE_MEM, 0);
+ if (IS_ERR(res))
+ return PTR_ERR(res);
+
+ num_clks = AGILEX5_NUM_CLKS;
+
+ clk_data = xzalloc(struct_size(clk_data, clk_data.hws, num_clks));
+ if (!clk_data)
+ return -ENOMEM;
+
+ for (i = 0; i < num_clks; i++)
+ clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
+
+ clk_data->base = IOMEM(res->start);
+ clk_data->clk_data.num = num_clks;
+
+ agilex5_clk_register_pll(agilex5_pll_clks, ARRAY_SIZE(agilex5_pll_clks),
+ clk_data);
+
+ agilex5_clk_register_c_perip(agilex5_main_perip_c_clks,
+ ARRAY_SIZE(agilex5_main_perip_c_clks),
+ clk_data);
+
+ agilex5_clk_register_cnt_perip(agilex5_main_perip_cnt_clks,
+ ARRAY_SIZE(agilex5_main_perip_cnt_clks),
+ clk_data);
+
+ agilex5_clk_register_gate(agilex5_gate_clks,
+ ARRAY_SIZE(agilex5_gate_clks), clk_data);
+
+ of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
+ return 0;
+}
+
+static const struct of_device_id agilex5_clkmgr_match_table[] = {
+ {
+ .compatible = "intel,agilex5-clkmgr",
+ } , {
+ /* sentinel */
+ }
+};
+
+static struct driver agilex5_clkmgr_driver = {
+ .name = "agilex5-clkmgr",
+ .of_match_table = agilex5_clkmgr_match_table,
+ .probe = agilex5_clkmgr_probe,
+};
+
+static int __init agilex5_clk_init(void)
+{
+ return platform_driver_register(&agilex5_clkmgr_driver);
+}
+core_initcall(agilex5_clk_init);
diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c
new file mode 100644
index 0000000000000000000000000000000000000000..2aac28c7c2d4bc24d640bcab5c6fa047123fafa0
--- /dev/null
+++ b/drivers/clk/socfpga/clk-gate-s10.c
@@ -0,0 +1,184 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017, Intel Corporation
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#include "stratix10-clk.h"
+#include "clk.h"
+
+#define SOCFPGA_CS_PDBG_CLK "cs_pdbg_clk"
+#define to_socfpga_gate_clk(p) container_of(p, struct socfpga_gate_clk, hw)
+
+#define SOCFPGA_EMAC0_CLK "emac0_clk"
+#define SOCFPGA_EMAC1_CLK "emac1_clk"
+#define SOCFPGA_EMAC2_CLK "emac2_clk"
+#define AGILEX_BYPASS_OFFSET 0xC
+#define STRATIX10_BYPASS_OFFSET 0x2C
+#define BOOTCLK_BYPASS 2
+
+static unsigned long socfpga_gate_clk_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
+ u32 div = 1, val;
+
+ if (socfpgaclk->fixed_div) {
+ div = socfpgaclk->fixed_div;
+ } else if (socfpgaclk->div_reg) {
+ val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
+ val &= GENMASK(socfpgaclk->width - 1, 0);
+ div = (1 << val);
+ }
+ return parent_rate / div;
+}
+
+static unsigned long socfpga_dbg_clk_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
+ u32 div, val;
+
+ val = readl(socfpgaclk->div_reg) >> socfpgaclk->shift;
+ val &= GENMASK(socfpgaclk->width - 1, 0);
+ div = (1 << val);
+ div = div ? 4 : 1;
+
+ return parent_rate / div;
+}
+
+static int socfpga_gate_get_parent(struct clk_hw *hwclk)
+{
+ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
+ u32 mask, second_bypass;
+ u8 parent = 0;
+ const char *name = clk_hw_get_name(hwclk);
+
+printk("%s: %s\n", __func__, name);
+
+ if (socfpgaclk->bypass_reg) {
+ mask = (0x1 << socfpgaclk->bypass_shift);
+ parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
+ socfpgaclk->bypass_shift);
+printk("%s: parent %d\n", __func__, parent);
+ }
+
+ if (streq(name, SOCFPGA_EMAC0_CLK) ||
+ streq(name, SOCFPGA_EMAC1_CLK) ||
+ streq(name, SOCFPGA_EMAC2_CLK)) {
+ second_bypass = readl(socfpgaclk->bypass_reg -
+ STRATIX10_BYPASS_OFFSET);
+ /* EMACA bypass to bootclk @0xB0 offset */
+ if (second_bypass & 0x1)
+ if (parent == 0) /* only applicable if parent is maca */
+ parent = BOOTCLK_BYPASS;
+
+ if (second_bypass & 0x2)
+ if (parent == 1) /* only applicable if parent is macb */
+ parent = BOOTCLK_BYPASS;
+ }
+ return parent;
+}
+
+static int socfpga_agilex_gate_get_parent(struct clk_hw *hwclk)
+{
+ struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
+ u32 mask, second_bypass;
+ u8 parent = 0;
+ const char *name = clk_hw_get_name(hwclk);
+
+ if (socfpgaclk->bypass_reg) {
+ mask = (0x1 << socfpgaclk->bypass_shift);
+ parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
+ socfpgaclk->bypass_shift);
+ }
+
+ if (streq(name, SOCFPGA_EMAC0_CLK) ||
+ streq(name, SOCFPGA_EMAC1_CLK) ||
+ streq(name, SOCFPGA_EMAC2_CLK)) {
+ second_bypass = readl(socfpgaclk->bypass_reg -
+ AGILEX_BYPASS_OFFSET);
+ /* EMACA bypass to bootclk @0x88 offset */
+ if (second_bypass & 0x1)
+ if (parent == 0) /* only applicable if parent is maca */
+ parent = BOOTCLK_BYPASS;
+
+ if (second_bypass & 0x2)
+ if (parent == 1) /* only applicable if parent is macb */
+ parent = BOOTCLK_BYPASS;
+ }
+
+ return parent;
+}
+
+static struct clk_ops agilex_gateclk_ops = {
+ .recalc_rate = socfpga_gate_clk_recalc_rate,
+ .get_parent = socfpga_agilex_gate_get_parent,
+};
+
+static const struct clk_ops dbgclk_ops = {
+ .recalc_rate = socfpga_dbg_clk_recalc_rate,
+ .get_parent = socfpga_gate_get_parent,
+};
+
+struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase)
+{
+ struct clk_hw *hw_clk;
+ struct socfpga_gate_clk *socfpga_clk;
+ struct clk_init_data init;
+ const char *parent_name = clks->parent_name;
+ int ret;
+
+ socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
+ if (!socfpga_clk)
+ return NULL;
+
+ socfpga_clk->reg = regbase + clks->gate_reg;
+ socfpga_clk->bit_idx = clks->gate_idx;
+
+ agilex_gateclk_ops.enable = clk_gate_ops.enable;
+ agilex_gateclk_ops.disable = clk_gate_ops.disable;
+
+ socfpga_clk->fixed_div = clks->fixed_div;
+
+ if (clks->div_reg)
+ socfpga_clk->div_reg = regbase + clks->div_reg;
+ else
+ socfpga_clk->div_reg = NULL;
+
+ socfpga_clk->width = clks->div_width;
+ socfpga_clk->shift = clks->div_offset;
+
+ if (clks->bypass_reg)
+ socfpga_clk->bypass_reg = regbase + clks->bypass_reg;
+ else
+ socfpga_clk->bypass_reg = NULL;
+ socfpga_clk->bypass_shift = clks->bypass_shift;
+
+ if (streq(clks->name, "cs_pdbg_clk"))
+ init.ops = &dbgclk_ops;
+ else
+ init.ops = &agilex_gateclk_ops;
+ init.name = clks->name;
+ init.flags = clks->flags;
+
+ init.num_parents = clks->num_parents;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ if (init.parent_names == NULL)
+ init.parent_data = clks->parent_data;
+ socfpga_clk->hw.init = &init;
+
+ hw_clk = &socfpga_clk->hw;
+
+ ret = clk_hw_register(NULL, &socfpga_clk->hw);
+ if (ret) {
+ kfree(socfpga_clk);
+ return ERR_PTR(ret);
+ }
+ return hw_clk;
+}
diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c
new file mode 100644
index 0000000000000000000000000000000000000000..68f9d4bc80af5587666e1a4900362eba290ef4f4
--- /dev/null
+++ b/drivers/clk/socfpga/clk-periph-s10.c
@@ -0,0 +1,163 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017, Intel Corporation
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk-provider.h>
+
+#include "stratix10-clk.h"
+#include "clk.h"
+
+#define CLK_MGR_FREE_SHIFT 16
+#define CLK_MGR_FREE_MASK 0x7
+#define SWCTRLBTCLKSEN_SHIFT 8
+
+#define to_periph_clk(p) container_of(p, struct socfpga_periph_clk, hw)
+
+static unsigned long clk_peri_c_clk_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk);
+ unsigned long div = 1;
+ u32 val;
+
+ val = readl(socfpgaclk->reg);
+ val &= GENMASK(SWCTRLBTCLKSEN_SHIFT - 1, 0);
+ parent_rate /= val;
+
+ return parent_rate / div;
+}
+
+static unsigned long clk_peri_cnt_clk_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk);
+ unsigned long div = 1;
+
+ if (socfpgaclk->fixed_div) {
+ div = socfpgaclk->fixed_div;
+ } else {
+ if (socfpgaclk->reg)
+ div = ((readl(socfpgaclk->reg) & 0x7ff) + 1);
+ }
+
+ return parent_rate / div;
+}
+
+static int clk_periclk_get_parent(struct clk_hw *hwclk)
+{
+ struct socfpga_periph_clk *socfpgaclk = to_periph_clk(hwclk);
+ u32 clk_src, mask;
+ u8 parent = 0;
+
+ /* handle the bypass first */
+ if (socfpgaclk->bypass_reg) {
+ mask = (0x1 << socfpgaclk->bypass_shift);
+ parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
+ socfpgaclk->bypass_shift);
+ if (parent)
+ return parent;
+ }
+
+ if (socfpgaclk->reg) {
+ clk_src = readl(socfpgaclk->reg);
+ parent = (clk_src >> CLK_MGR_FREE_SHIFT) &
+ CLK_MGR_FREE_MASK;
+ }
+ return parent;
+}
+
+static const struct clk_ops peri_c_clk_ops = {
+ .recalc_rate = clk_peri_c_clk_recalc_rate,
+ .get_parent = clk_periclk_get_parent,
+};
+
+static const struct clk_ops peri_cnt_clk_ops = {
+ .recalc_rate = clk_peri_cnt_clk_recalc_rate,
+ .get_parent = clk_periclk_get_parent,
+};
+
+struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
+ void __iomem *reg)
+{
+ struct clk_hw *hw_clk;
+ struct socfpga_periph_clk *periph_clk;
+ struct clk_init_data init;
+ const char *name = clks->name;
+ const char *parent_name = clks->parent_name;
+ int ret;
+
+ periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
+ if (WARN_ON(!periph_clk))
+ return NULL;
+
+ periph_clk->reg = reg + clks->offset;
+
+ init.name = name;
+ init.ops = &peri_c_clk_ops;
+ init.flags = clks->flags;
+
+ init.num_parents = clks->num_parents;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ if (init.parent_names == NULL)
+ init.parent_data = clks->parent_data;
+
+ periph_clk->hw.init = &init;
+ hw_clk = &periph_clk->hw;
+
+ ret = clk_hw_register(NULL, hw_clk);
+ if (ret) {
+ kfree(periph_clk);
+ return ERR_PTR(ret);
+ }
+ return hw_clk;
+}
+
+struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks,
+ void __iomem *regbase)
+{
+ struct clk_hw *hw_clk;
+ struct socfpga_periph_clk *periph_clk;
+ struct clk_init_data init;
+ const char *name = clks->name;
+ const char *parent_name = clks->parent_name;
+ int ret;
+
+ periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
+ if (WARN_ON(!periph_clk))
+ return NULL;
+
+ if (clks->offset)
+ periph_clk->reg = regbase + clks->offset;
+ else
+ periph_clk->reg = NULL;
+
+ if (clks->bypass_reg)
+ periph_clk->bypass_reg = regbase + clks->bypass_reg;
+ else
+ periph_clk->bypass_reg = NULL;
+ periph_clk->bypass_shift = clks->bypass_shift;
+ periph_clk->fixed_div = clks->fixed_divider;
+
+ init.name = name;
+ init.ops = &peri_cnt_clk_ops;
+ init.flags = clks->flags;
+
+ init.num_parents = clks->num_parents;
+ init.parent_names = parent_name ? &parent_name : NULL;
+ if (init.parent_names == NULL)
+ init.parent_data = clks->parent_data;
+
+ periph_clk->hw.init = &init;
+ hw_clk = &periph_clk->hw;
+
+ ret = clk_hw_register(NULL, hw_clk);
+ if (ret) {
+ kfree(periph_clk);
+ return ERR_PTR(ret);
+ }
+ return hw_clk;
+}
diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c
new file mode 100644
index 0000000000000000000000000000000000000000..59e5ec33b06b6cf634b353bf6d6fe4d345171550
--- /dev/null
+++ b/drivers/clk/socfpga/clk-pll-s10.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017, Intel Corporation
+ */
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+
+#include "stratix10-clk.h"
+#include "clk.h"
+
+/* Clock Manager offsets */
+#define CLK_MGR_PLL_CLK_SRC_SHIFT 16
+#define CLK_MGR_PLL_CLK_SRC_MASK 0x3
+
+/* PLL Clock enable bits */
+#define SOCFPGA_PLL_POWER 0
+#define SOCFPGA_PLL_RESET_MASK 0x2
+#define SOCFPGA_PLL_REFDIV_MASK 0x00003F00
+#define SOCFPGA_PLL_REFDIV_SHIFT 8
+#define SOCFPGA_PLL_AREFDIV_MASK 0x00000F00
+#define SOCFPGA_PLL_DREFDIV_MASK 0x00003000
+#define SOCFPGA_PLL_DREFDIV_SHIFT 12
+#define SOCFPGA_PLL_MDIV_MASK 0xFF000000
+#define SOCFPGA_PLL_MDIV_SHIFT 24
+#define SOCFPGA_AGILEX_PLL_MDIV_MASK 0x000003FF
+#define SWCTRLBTCLKSEL_MASK 0x200
+#define SWCTRLBTCLKSEL_SHIFT 9
+
+#define SOCFPGA_BOOT_CLK "boot_clk"
+
+#define to_socfpga_clk(p) container_of(p, struct socfpga_pll, hw)
+
+static unsigned long agilex_clk_pll_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+ unsigned long arefdiv, reg, mdiv;
+ unsigned long long vco_freq;
+
+ /* read VCO1 reg for numerator and denominator */
+ reg = readl(socfpgaclk->reg);
+ arefdiv = (reg & SOCFPGA_PLL_AREFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT;
+
+ vco_freq = (unsigned long long)parent_rate / arefdiv;
+
+ /* Read mdiv and fdiv from the fdbck register */
+ reg = readl(socfpgaclk->reg + 0x24);
+ mdiv = reg & SOCFPGA_AGILEX_PLL_MDIV_MASK;
+
+ vco_freq = (unsigned long long)vco_freq * mdiv;
+ return (unsigned long)vco_freq;
+}
+
+static unsigned long clk_boot_clk_recalc_rate(struct clk_hw *hwclk,
+ unsigned long parent_rate)
+{
+ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+ u32 div;
+
+ div = ((readl(socfpgaclk->reg) &
+ SWCTRLBTCLKSEL_MASK) >>
+ SWCTRLBTCLKSEL_SHIFT);
+ div += 1;
+ return parent_rate / div;
+}
+
+static int clk_pll_get_parent(struct clk_hw *hwclk)
+{
+ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+ u32 pll_src;
+
+ pll_src = readl(socfpgaclk->reg);
+ return (pll_src >> CLK_MGR_PLL_CLK_SRC_SHIFT) &
+ CLK_MGR_PLL_CLK_SRC_MASK;
+}
+
+static int clk_boot_get_parent(struct clk_hw *hwclk)
+{
+ struct socfpga_pll *socfpgaclk = to_socfpga_clk(hwclk);
+ u32 pll_src;
+
+ pll_src = readl(socfpgaclk->reg);
+ return (pll_src >> SWCTRLBTCLKSEL_SHIFT) &
+ SWCTRLBTCLKSEL_MASK;
+}
+
+/* TODO need to fix, Agilex5 SM requires change */
+static const struct clk_ops agilex5_clk_pll_ops = {
+ /* TODO This may require a custom Agilex5 implementation */
+ .recalc_rate = agilex_clk_pll_recalc_rate,
+ .get_parent = clk_pll_get_parent,
+};
+
+static const struct clk_ops clk_boot_ops = {
+ .recalc_rate = clk_boot_clk_recalc_rate,
+ .get_parent = clk_boot_get_parent,
+};
+
+struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
+ void __iomem *reg)
+{
+ struct clk_hw *hw_clk;
+ struct socfpga_pll *pll_clk;
+ struct clk_init_data init;
+ const char *name = clks->name;
+ int ret;
+
+ pll_clk = xzalloc(sizeof(*pll_clk));
+ if (!pll_clk)
+ return ERR_PTR(-ENOMEM);
+
+ pll_clk->reg = reg + clks->offset;
+
+ if (streq(name, SOCFPGA_BOOT_CLK))
+ init.ops = &clk_boot_ops;
+ else
+ init.ops = &agilex5_clk_pll_ops;
+
+ init.name = name;
+ init.flags = clks->flags;
+
+ init.num_parents = clks->num_parents;
+ init.parent_names = NULL;
+ init.parent_data = clks->parent_data;
+ pll_clk->hw.init = &init;
+
+ pll_clk->bit_idx = SOCFPGA_PLL_POWER;
+ hw_clk = &pll_clk->hw;
+
+ ret = clk_hw_register(NULL, hw_clk);
+ if (ret) {
+ kfree(pll_clk);
+ return ERR_PTR(ret);
+ }
+ return hw_clk;
+}
+
diff --git a/drivers/clk/socfpga/clk.h b/drivers/clk/socfpga/clk.h
index 402f714436ab2f94dc5ecbad244915f0fa1c6194..19fc45e7f639583342b37422f30762d673421760 100644
--- a/drivers/clk/socfpga/clk.h
+++ b/drivers/clk/socfpga/clk.h
@@ -20,6 +20,11 @@
#define SOCFPGA_MAX_PARENTS 5
#define streq(a, b) (strcmp((a), (b)) == 0)
+#define SYSMGR_SDMMC_CTRL_SET(smplsel, drvsel) \
+ ((((smplsel) & 0x7) << 3) | (((drvsel) & 0x7) << 0))
+
+#define SYSMGR_SDMMC_CTRL_SET_AS10(smplsel, drvsel) \
+ ((((smplsel) & 0x7) << 4) | (((drvsel) & 0x7) << 0))
extern void __iomem *clk_mgr_base_addr;
@@ -58,11 +63,13 @@ struct socfpga_gate_clk {
char *parent_name;
u32 fixed_div;
void __iomem *div_reg;
+ void __iomem *bypass_reg;
struct regmap *sys_mgr_base_addr;
u32 width; /* only valid if div_reg != 0 */
u32 shift; /* only valid if div_reg != 0 */
u32 bit_idx;
void __iomem *reg;
+ u32 bypass_shift; /* only valid if bypass_reg != 0 */
u32 clk_phase[2];
const char *parent_names[SOCFPGA_MAX_PARENTS];
};
@@ -73,8 +80,10 @@ struct socfpga_periph_clk {
char *parent_name;
u32 fixed_div;
void __iomem *div_reg;
+ void __iomem *bypass_reg;
u32 width; /* only valid if div_reg != 0 */
u32 shift; /* only valid if div_reg != 0 */
+ u32 bypass_shift; /* only valid if bypass_reg != 0 */
const char *parent_names[SOCFPGA_MAX_PARENTS];
};
diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h
new file mode 100644
index 0000000000000000000000000000000000000000..1fe025f65f7a05faf00efc3991d2afc9c564d5ca
--- /dev/null
+++ b/drivers/clk/socfpga/stratix10-clk.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2017, Intel Corporation
+ */
+
+#ifndef __STRATIX10_CLK_H
+#define __STRATIX10_CLK_H
+
+struct stratix10_clock_data {
+ void __iomem *base;
+
+ /* Must be last */
+ struct clk_hw_onecell_data clk_data;
+};
+
+struct stratix10_pll_clock {
+ unsigned int id;
+ const char *name;
+ const struct clk_parent_data *parent_data;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned long offset;
+};
+
+struct stratix10_perip_c_clock {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ const struct clk_parent_data *parent_data;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned long offset;
+};
+
+struct stratix10_perip_cnt_clock {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ const struct clk_parent_data *parent_data;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned long offset;
+ u8 fixed_divider;
+ unsigned long bypass_reg;
+ unsigned long bypass_shift;
+};
+
+struct stratix10_gate_clock {
+ unsigned int id;
+ const char *name;
+ const char *parent_name;
+ const struct clk_parent_data *parent_data;
+ u8 num_parents;
+ unsigned long flags;
+ unsigned long gate_reg;
+ u8 gate_idx;
+ unsigned long div_reg;
+ u8 div_offset;
+ u8 div_width;
+ unsigned long bypass_reg;
+ u8 bypass_shift;
+ u8 fixed_div;
+};
+
+struct clk_hw *agilex5_register_pll(const struct stratix10_pll_clock *clks,
+ void __iomem *reg);
+struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
+ void __iomem *reg);
+struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks,
+ void __iomem *reg);
+struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks,
+ void __iomem *reg);
+#endif /* __STRATIX10_CLK_H */
diff --git a/include/dt-bindings/clock/agilex5-clock.h b/include/dt-bindings/clock/agilex5-clock.h
index 269108465387c0becb165d5fdc5d5eb4460ed9c8..8ddb96407eacdbb8998f5915d680328bf85b91aa 100644
--- a/include/dt-bindings/clock/agilex5-clock.h
+++ b/include/dt-bindings/clock/agilex5-clock.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
- * Copyright (C) 2019-2022, Intel Corporation
+ * Copyright (C) 2022, Intel Corporation
*/
#ifndef __AGILEX5_CLOCK_H
@@ -9,63 +9,92 @@
/* fixed rate clocks */
#define AGILEX5_OSC1 0
#define AGILEX5_CB_INTOSC_HS_DIV2_CLK 1
-#define AGILEX5_CB_INTOSC_LS_CLK 2
-#define AGILEX5_L4_SYS_FREE_CLK 3
-#define AGILEX5_F2S_FREE_CLK 4
+#define AGILEX5_CB_INTOSC_LS_CLK 2
+#define AGILEX5_F2S_FREE_CLK 3
/* PLL clocks */
-#define AGILEX5_MAIN_PLL_CLK 5
-#define AGILEX5_MAIN_PLL_C0_CLK 6
-#define AGILEX5_MAIN_PLL_C1_CLK 7
-#define AGILEX5_MAIN_PLL_C2_CLK 8
-#define AGILEX5_MAIN_PLL_C3_CLK 9
-#define AGILEX5_PERIPH_PLL_CLK 10
-#define AGILEX5_PERIPH_PLL_C0_CLK 11
-#define AGILEX5_PERIPH_PLL_C1_CLK 12
-#define AGILEX5_PERIPH_PLL_C2_CLK 13
-#define AGILEX5_PERIPH_PLL_C3_CLK 14
-#define AGILEX5_MPU_FREE_CLK 15
-#define AGILEX5_MPU_CCU_CLK 16
-#define AGILEX5_BOOT_CLK 17
+#define AGILEX5_MAIN_PLL_CLK 4
+#define AGILEX5_MAIN_PLL_C0_CLK 5
+#define AGILEX5_MAIN_PLL_C1_CLK 6
+#define AGILEX5_MAIN_PLL_C2_CLK 7
+#define AGILEX5_MAIN_PLL_C3_CLK 8
+#define AGILEX5_PERIPH_PLL_CLK 9
+#define AGILEX5_PERIPH_PLL_C0_CLK 10
+#define AGILEX5_PERIPH_PLL_C1_CLK 11
+#define AGILEX5_PERIPH_PLL_C2_CLK 12
+#define AGILEX5_PERIPH_PLL_C3_CLK 13
+#define AGILEX5_CORE0_FREE_CLK 14
+#define AGILEX5_CORE1_FREE_CLK 15
+#define AGILEX5_CORE2_FREE_CLK 16
+#define AGILEX5_CORE3_FREE_CLK 17
+#define AGILEX5_DSU_FREE_CLK 18
+#define AGILEX5_BOOT_CLK 19
/* fixed factor clocks */
-#define AGILEX5_L3_MAIN_FREE_CLK 18
-#define AGILEX5_NOC_FREE_CLK 19
-#define AGILEX5_S2F_USR0_CLK 20
-#define AGILEX5_NOC_CLK 21
-#define AGILEX5_EMAC_A_FREE_CLK 22
-#define AGILEX5_EMAC_B_FREE_CLK 23
-#define AGILEX5_EMAC_PTP_FREE_CLK 24
-#define AGILEX5_GPIO_DB_FREE_CLK 25
-#define AGILEX5_SDMMC_FREE_CLK 26
-#define AGILEX5_S2F_USER0_FREE_CLK 27
-#define AGILEX5_S2F_USER1_FREE_CLK 28
-#define AGILEX5_PSI_REF_FREE_CLK 29
+#define AGILEX5_L3_MAIN_FREE_CLK 20
+#define AGILEX5_NOC_FREE_CLK 21
+#define AGILEX5_S2F_USR0_CLK 22
+#define AGILEX5_NOC_CLK 23
+#define AGILEX5_EMAC_A_FREE_CLK 24
+#define AGILEX5_EMAC_B_FREE_CLK 25
+#define AGILEX5_EMAC_PTP_FREE_CLK 26
+#define AGILEX5_GPIO_DB_FREE_CLK 27
+#define AGILEX5_S2F_USER0_FREE_CLK 28
+#define AGILEX5_S2F_USER1_FREE_CLK 29
+#define AGILEX5_PSI_REF_FREE_CLK 30
+#define AGILEX5_USB31_FREE_CLK 31
/* Gate clocks */
-#define AGILEX5_MPU_CLK 30
-#define AGILEX5_MPU_PERIPH_CLK 31
-#define AGILEX5_L4_MAIN_CLK 32
-#define AGILEX5_L4_MP_CLK 33
-#define AGILEX5_L4_SP_CLK 34
-#define AGILEX5_CS_AT_CLK 35
-#define AGILEX5_CS_TRACE_CLK 36
-#define AGILEX5_CS_PDBG_CLK 37
-#define AGILEX5_CS_TIMER_CLK 38
-#define AGILEX5_S2F_USER0_CLK 39
-#define AGILEX5_EMAC0_CLK 40
-#define AGILEX5_EMAC1_CLK 41
-#define AGILEX5_EMAC2_CLK 42
-#define AGILEX5_EMAC_PTP_CLK 43
-#define AGILEX5_GPIO_DB_CLK 44
-#define AGILEX5_NAND_CLK 45
-#define AGILEX5_PSI_REF_CLK 46
-#define AGILEX5_S2F_USER1_CLK 47
-#define AGILEX5_SDMMC_CLK 48
-#define AGILEX5_SPI_M_CLK 49
-#define AGILEX5_USB_CLK 50
-#define AGILEX5_NAND_X_CLK 51
-#define AGILEX5_NAND_ECC_CLK 52
-#define AGILEX5_NUM_CLKS 53
+#define AGILEX5_CORE0_CLK 32
+#define AGILEX5_CORE1_CLK 33
+#define AGILEX5_CORE2_CLK 34
+#define AGILEX5_CORE3_CLK 35
+#define AGILEX5_MPU_CLK 36
+#define AGILEX5_MPU_PERIPH_CLK 37
+#define AGILEX5_MPU_CCU_CLK 38
+#define AGILEX5_L4_MAIN_CLK 39
+#define AGILEX5_L4_MP_CLK 40
+#define AGILEX5_L4_SYS_FREE_CLK 41
+#define AGILEX5_L4_SP_CLK 42
+#define AGILEX5_CS_AT_CLK 43
+#define AGILEX5_CS_TRACE_CLK 44
+#define AGILEX5_CS_PDBG_CLK 45
+#define AGILEX5_EMAC1_CLK 47
+#define AGILEX5_EMAC2_CLK 48
+#define AGILEX5_EMAC_PTP_CLK 49
+#define AGILEX5_GPIO_DB_CLK 50
+#define AGILEX5_S2F_USER0_CLK 51
+#define AGILEX5_S2F_USER1_CLK 52
+#define AGILEX5_PSI_REF_CLK 53
+#define AGILEX5_USB31_SUSPEND_CLK 54
+#define AGILEX5_EMAC0_CLK 46
+#define AGILEX5_USB31_BUS_CLK_EARLY 55
+#define AGILEX5_USB2OTG_HCLK 56
+#define AGILEX5_SPIM_0_CLK 57
+#define AGILEX5_SPIM_1_CLK 58
+#define AGILEX5_SPIS_0_CLK 59
+#define AGILEX5_SPIS_1_CLK 60
+#define AGILEX5_DMA_CORE_CLK 61
+#define AGILEX5_DMA_HS_CLK 62
+#define AGILEX5_I3C_0_CORE_CLK 63
+#define AGILEX5_I3C_1_CORE_CLK 64
+#define AGILEX5_I2C_0_PCLK 65
+#define AGILEX5_I2C_1_PCLK 66
+#define AGILEX5_I2C_EMAC0_PCLK 67
+#define AGILEX5_I2C_EMAC1_PCLK 68
+#define AGILEX5_I2C_EMAC2_PCLK 69
+#define AGILEX5_UART_0_PCLK 70
+#define AGILEX5_UART_1_PCLK 71
+#define AGILEX5_SPTIMER_0_PCLK 72
+#define AGILEX5_SPTIMER_1_PCLK 73
+#define AGILEX5_DFI_CLK 74
+#define AGILEX5_NAND_NF_CLK 75
+#define AGILEX5_NAND_BCH_CLK 76
+#define AGILEX5_SDMMC_SDPHY_REG_CLK 77
+#define AGILEX5_SDMCLK 78
+#define AGILEX5_SOFTPHY_REG_PCLK 79
+#define AGILEX5_SOFTPHY_PHY_CLK 80
+#define AGILEX5_SOFTPHY_CTRL_CLK 81
+#define AGILEX5_NUM_CLKS 82
#endif /* __AGILEX5_CLOCK_H */
--
2.46.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 04/10] arm: socfgpa: add support for SoCFPGA Agilex5
2024-10-29 8:42 ` [PATCH 04/10] arm: socfgpa: add support for SoCFPGA Agilex5 Steffen Trumtrar
@ 2024-11-04 10:31 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2024-11-04 10:31 UTC (permalink / raw)
To: Steffen Trumtrar; +Cc: barebox
On Tue, Oct 29, 2024 at 09:42:34AM +0100, Steffen Trumtrar wrote:
> diff --git a/arch/arm/mach-socfpga/Makefile b/arch/arm/mach-socfpga/Makefile
> index 008dbc38877211fe1f317cb8eb660d8514611ddd..81934a3ded7fe6dcfb4c8ac26473a25a96560863 100644
> --- a/arch/arm/mach-socfpga/Makefile
> +++ b/arch/arm/mach-socfpga/Makefile
> @@ -14,6 +14,19 @@ obj-pbl-$(CONFIG_ARCH_SOCFPGA_ARRIA10) += arria10-bootsource.o \
> arria10-init.o \
> arria10-sdram.o
>
> +pbl-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += soc64-system-manager.o \
> + soc64-wrap-handoff.o \
> + iossm_mailbox.o \
> + mailbox_s10.o \
> + agilex5-sdram.o \
> + agilex5-secreg.o \
> + agilex5-clock-manager.o \
> + atf.o
> +
> +obj-$(CONFIG_ARCH_SOCFPGA_AGILEX5) += secure_reg_helper.o \
> + mailbox_s10.o \
> + smc_api.o
Some whitespace inconsistencies here.
> +static void cm_wait_for_lock(u32 mask)
> +{
> + u32 inter_val;
> + u32 retry = 0;
> +
> + do {
> + inter_val = readl(SOCFPGA_CLKMGR_ADDRESS + CLKMGR_STAT) & mask;
> + /* Wait for stable lock */
> + if (inter_val == mask)
> + retry++;
> + else
> + retry = 0;
This looks strange. Shouldn't you return once your lock condition is
satisfied?
> + if (retry >= 10)
> + break;
> + } while (1);
> +}
> +
> +
> + /* Enable Periph pll clkslices */
> + CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC0) |
> + CLKMGR_PLLCX_EN_SET_MSK,
> + CLKMGR_PERPLL_PLLC0);
> + CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC1) |
> + CLKMGR_PLLCX_EN_SET_MSK,
> + CLKMGR_PERPLL_PLLC1);
> + CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC2) |
> + CLKMGR_PLLCX_EN_SET_MSK,
> + CLKMGR_PERPLL_PLLC2);
> + CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLC3) |
> + CLKMGR_PLLCX_EN_SET_MSK,
> + CLKMGR_PERPLL_PLLC3);
Use CM_REG_SETBITS instead?
> +
> + cm_wait_for_lock(CLKMGR_STAT_ALLPLL_LOCKED_MASK);
> +
> + CM_REG_WRITEL(plat, CLKMGR_LOSTLOCK_SET_MASK, CLKMGR_MAINPLL_LOSTLOCK);
> + CM_REG_WRITEL(plat, CLKMGR_LOSTLOCK_SET_MASK, CLKMGR_PERPLL_LOSTLOCK);
> +
> + CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_MAINPLL_PLLGLOB) |
> + CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
> + CLKMGR_MAINPLL_PLLGLOB);
> + CM_REG_WRITEL(plat, CM_REG_READL(plat, CLKMGR_PERPLL_PLLGLOB) |
> + CLKMGR_PLLGLOB_CLR_LOSTLOCK_BYPASS_MASK,
> + CLKMGR_PERPLL_PLLGLOB);
Here as well.
> +/* MPFE NOC registers */
> +#define F2SDRAM_SIDEBAND_FLAGOUTSET0 0x50
> +#define F2SDRAM_SIDEBAND_FLAGOUTSTATUS0 0x58
> +#define SIDEBANDMGR_FLAGOUTSET0_REG SOCFPGA_F2SDRAM_MGR_ADDRESS +\
> + F2SDRAM_SIDEBAND_FLAGOUTSET0
> +#define SIDEBANDMGR_FLAGOUTSTATUS0_REG SOCFPGA_F2SDRAM_MGR_ADDRESS +\
> + F2SDRAM_SIDEBAND_FLAGOUTSTATUS0
> +
> +#define PORT_EMIF_CONFIG_OFFSET 4
> +
> +/* Reset type */
> +enum reset_type {
> + POR_RESET,
> + WARM_RESET,
> + COLD_RESET,
> + NCONFIG,
> + JTAG_CONFIG,
> + RSU_RECONFIG
> +};
> +
> +phys_addr_t io96b_csr_reg_addr[] = {
> + 0x18400000, /* IO96B_0 CSR registers address */
> + 0x18800000 /* IO96B_1 CSR registers address */
> +};
Should be static
> +
> +static enum reset_type get_reset_type(u32 reg)
> +{
> + return (reg & ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_MASK) >>
> + ALT_SYSMGR_SCRATCH_REG_3_DDR_RESET_TYPE_SHIFT;
> +}
It looks like the caller passes a register address in reg whereas this
function seems to interpret it as a register value.
> +
> +static int set_mpfe_config(void)
> +{
> + /* Set mpfe_lite_intfcsel */
> + setbits_le32(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + SYSMGR_SOC64_MPFE_CONFIG, BIT(2));
> +
> + /* Set mpfe_lite_active */
> + setbits_le32(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + SYSMGR_SOC64_MPFE_CONFIG, BIT(8));
> +
> + pr_debug("%s: mpfe_config: 0x%x\n", __func__,
> + readl(IOMEM(SOCFPGA_SYSMGR_ADDRESS) + SYSMGR_SOC64_MPFE_CONFIG));
> +
> + return 0;
> +}
> +
> +static void config_ccu_mgr(struct altera_sdram_plat *plat)
> +{
> + int ret = 0;
> +
> + if (plat->dualport || plat->dualemif) {
> + pr_debug("%s: config interleaving on ccu reg\n", __func__);
> + agilex5_security_interleaving_on();
> + } else {
> + pr_debug("%s: config interleaving off ccu reg\n", __func__);
> + agilex5_security_interleaving_off();
> + }
> +
> + if (ret) {
> + printf("interleaving on/off ccu settings init failed: %d\n", ret);
> + hang();
> + }
'ret' is never set to anything in this function.
> +}
> +
> +static bool hps_ocram_dbe_status(void)
> +{
> + u32 reg = readl(IOMEM(SOCFPGA_SYSMGR_ADDRESS) +
> + SYSMGR_SOC64_BOOT_SCRATCH_COLD3);
> +
> + if (reg & ALT_SYSMGR_SCRATCH_REG_3_OCRAM_DBE_MASK)
> + return true;
> +
> + return false;
> +}
> +
...
> + sdram_set_firewall(hw_size);
> +
> + /* Firewall setting for MPFE CSR */
> + /* IO96B0_reg */
> + writel(0x1, 0x18000d00);
> + /* IO96B1_reg */
> + writel(0x1, 0x18000d04);
> + /* noc_csr */
> + writel(0x1, 0x18000d08);
SOCFPGA_MPFE_CSR_ADDRESS + 0xd08 instead?
> +
> + pr_debug("DDR: firewall init success\n");
> +
> + /* Ending DDR driver initialization success tracking */
> + ddr_init_inprogress(false);
> +
> + pr_debug("DDR: init success\n");
> +
> + return 0;
> +}
> diff --git a/arch/arm/mach-socfpga/iossm_mailbox.c b/arch/arm/mach-socfpga/iossm_mailbox.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..de79b8370d8524553b31feb6e8845f7100408d1f
> --- /dev/null
> +++ b/arch/arm/mach-socfpga/iossm_mailbox.c
> @@ -0,0 +1,551 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2022-2024 Intel Corporation <www.intel.com>
> + *
> + */
> +
You're using pr_ functions here. Please define a pr_fmt to give the user
more context.
> +#include <common.h>
> +#include <io.h>
> +#include <linux/bitfield.h>
> +#include "iossm_mailbox.h"
> +#include <mach/socfpga/generic.h>
> +#include <mach/socfpga/soc64-regs.h>
> +#include <mach/socfpga/soc64-system-manager.h>
> +
> +#define ECC_INTSTATUS_SERR SOCFPGA_SYSMGR_ADDRESS + 0x9C
> +#define ECC_INISTATUS_DERR SOCFPGA_SYSMGR_ADDRESS + 0xA0
> +#define DDR_CSR_CLKGEN_LOCKED_IO96B0_MASK BIT(16)
> +#define DDR_CSR_CLKGEN_LOCKED_IO96B1_MASK BIT(17)
> +
> +#define DDR_CSR_CLKGEN_LOCKED_IO96B_MASK(x) (i == 0 ? DDR_CSR_CLKGEN_LOCKED_IO96B0_MASK : \
> + DDR_CSR_CLKGEN_LOCKED_IO96B1_MASK)
> +#define MAX_RETRY_COUNT 3
> +#define NUM_CMD_RESPONSE_DATA 3
> +
> +#define INTF_IP_TYPE_MASK GENMASK(31, 29)
> +#define INTF_INSTANCE_ID_MASK GENMASK(28, 24)
> +
> +/* supported DDR type list */
> +static const char *ddr_type_list[7] = {
> + "DDR4", "DDR5", "DDR5_RDIMM", "LPDDR4", "LPDDR5", "QDRIV", "UNKNOWN"
> +};
> +
> +int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id
> + , u32 usr_cmd_type, u32 usr_cmd_opcode, u32 cmd_param_0
> + , u32 cmd_param_1, u32 cmd_param_2, u32 cmd_param_3
> + , u32 cmd_param_4, u32 cmd_param_5, u32 cmd_param_6
> + , u32 resp_data_len, struct io96b_mb_resp *resp)
> +{
> + int i;
> + int ret;
> + u32 cmd_req, cmd_resp;
> +
> + /* Initialized zeros for responses*/
> + resp->cmd_resp_status = 0;
> + for (i = 0; i < NUM_CMD_RESPONSE_DATA; i++)
> + resp->cmd_resp_data[i] = 0;
Could be:
memset(resp, 0x0, sizeof(*resp));
> +
> + /* Ensure CMD_REQ is cleared before write any command request */
> + ret = wait_for_timeout((IOMEM(io96b_csr_addr) + IOSSM_CMD_REQ_OFFSET), GENMASK(31, 0), false);
> + if (ret) {
> + printf("%s: CMD_REQ not ready\n", __func__);
pr_err()
None of the callers checks the return value. Maybe print some of the
incoming parameters to see where we actually are in case of an error.
> + return -1;
> + }
> +
> + /* Write CMD_PARAM_* */
> + for (i = 0; i < 6 ; i++) {
> + switch (i) {
> + case 0:
> + if (cmd_param_0)
> + writel(cmd_param_0, io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET);
> + break;
> + case 1:
> + if (cmd_param_1)
> + writel(cmd_param_1, io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET);
> + break;
> + case 2:
> + if (cmd_param_2)
> + writel(cmd_param_2, io96b_csr_addr + IOSSM_CMD_PARAM_2_OFFSET);
> + break;
> + case 3:
> + if (cmd_param_3)
> + writel(cmd_param_3, io96b_csr_addr + IOSSM_CMD_PARAM_3_OFFSET);
> + break;
> + case 4:
> + if (cmd_param_4)
> + writel(cmd_param_4, io96b_csr_addr + IOSSM_CMD_PARAM_4_OFFSET);
> + break;
> + case 5:
> + if (cmd_param_5)
> + writel(cmd_param_5, io96b_csr_addr + IOSSM_CMD_PARAM_5_OFFSET);
> + break;
> + case 6:
> + if (cmd_param_6)
> + writel(cmd_param_6, io96b_csr_addr + IOSSM_CMD_PARAM_6_OFFSET);
> + break;
> + default:
> + printf("%s: Invalid command parameter\n", __func__);
> + }
> + }
Do I miss something or is this loop together with the switch/case just
unnecessary and could be dropped? Should be plain
if (cmd_param_0)
writel(cmd_param_0, io96b_csr_addr + IOSSM_CMD_PARAM_0_OFFSET);
if (cmd_param_1)
writel(cmd_param_1, io96b_csr_addr + IOSSM_CMD_PARAM_1_OFFSET);
...
What's the purpose of the if() before writing the registers? With the
if() check it looks like you only risk that the previous value is
reused, so maybe better drop it?
cmd_param_6 is always unused which is likely not intended.
> +
> + /* Write CMD_REQ (IP_TYPE, IP_INSTANCE_ID, CMD_TYPE and CMD_OPCODE) */
> + cmd_req = (usr_cmd_opcode << 0) | (usr_cmd_type << 16) | (instance_id << 24) |
> + (ip_type << 29);
> + writel(cmd_req, io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
> + pr_debug("%s: Write 0x%x to IOSSM_CMD_REQ_OFFSET 0x%llx\n", __func__, cmd_req
> + , io96b_csr_addr + IOSSM_CMD_REQ_OFFSET);
> +
> + /* Read CMD_RESPONSE_READY in CMD_RESPONSE_STATUS*/
> + ret = wait_for_timeout((IOMEM(io96b_csr_addr) + IOSSM_CMD_RESPONSE_STATUS_OFFSET),
> + IOSSM_STATUS_COMMAND_RESPONSE_READY, true);
> + if (ret) {
> + printf("%s: CMD_RESPONSE ERROR:\n", __func__);
> + cmd_resp = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
> + printf("%s: STATUS_GENERAL_ERROR: 0x%x\n", __func__, (cmd_resp >> 1) & 0xF);
> + printf("%s: STATUS_CMD_RESPONSE_ERROR: 0x%x\n", __func__, (cmd_resp >> 5) & 0x7);
pr_something()
> + }
> +
> + /* read CMD_RESPONSE_STATUS*/
> + resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
> + pr_debug("%s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n", __func__, io96b_csr_addr +
> + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
> +
> + /* read CMD_RESPONSE_DATA_* */
> + for (i = 0; i < resp_data_len; i++) {
Passing resp_data_len to this function looks rather unnecessary. Just
always read all 3 response data words. The caller should be able to pick
the desired onces by itself.
> + switch (i) {
> + case 0:
> + resp->cmd_resp_data[i] =
> + readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET);
> + pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x%llx: 0x%x\n", __func__
> + , io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_0_OFFSET,
> + resp->cmd_resp_data[i]);
> + break;
> + case 1:
> + resp->cmd_resp_data[i] =
> + readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET);
> + pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x%llx: 0x%x\n", __func__
> + , io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_1_OFFSET,
> + resp->cmd_resp_data[i]);
> + break;
> + case 2:
> + resp->cmd_resp_data[i] =
> + readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET);
> + pr_debug("%s: IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x%llx: 0x%x\n", __func__
> + , io96b_csr_addr + IOSSM_CMD_RESPONSE_DATA_2_OFFSET,
> + resp->cmd_resp_data[i]);
> + break;
> + default:
> + printf("%s: Invalid response data\n", __func__);
> + }
> + }
Define a IOSSM_CMD_RESPONSE_DATA_OFFSET[x] and cleanup this loop.
> +
> + resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
> + pr_debug("%s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n", __func__, io96b_csr_addr +
> + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
> +
> + /* write CMD_RESPONSE_READY = 0 */
> + clrbits_le32((u32 *)(uintptr_t)(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET)
> + , IOSSM_STATUS_COMMAND_RESPONSE_READY);
> +
> + resp->cmd_resp_status = readl(io96b_csr_addr + IOSSM_CMD_RESPONSE_STATUS_OFFSET);
> + pr_debug("%s: CMD_RESPONSE_READY 0x%llx: 0x%x\n", __func__, io96b_csr_addr +
> + IOSSM_CMD_RESPONSE_STATUS_OFFSET, resp->cmd_resp_status);
> +
> + return 0;
> +}
> +
> +
...
> +void init_mem_cal(struct io96b_info *io96b_ctrl)
> +{
> + int count, i, ret;
> +
> + /* Initialize overall calibration status */
> + io96b_ctrl->overall_cal_status = false;
> +
> + /* Check initial calibration status for the assigned IO96B*/
> + count = 0;
> + for (i = 0; i < io96b_ctrl->num_instance; i++) {
> + if (io96b_ctrl->ckgen_lock) {
> + ret = is_ddr_csr_clkgen_locked(DDR_CSR_CLKGEN_LOCKED_IO96B_MASK(i),
> + io96b_ctrl->num_port);
> + if (ret) {
> + printf("%s: ckgena_lock iossm IO96B_%d is not locked\n",
> + __func__, i);
> + hang();
> + }
> + }
> + ret = io96b_cal_status(io96b_ctrl->io96b[i].io96b_csr_addr);
> + if (ret) {
> + io96b_ctrl->io96b[i].cal_status = false;
> + printf("%s: Initial DDR calibration IO96B_%d failed %d\n", __func__, i
> + , ret);
> + hang();
> + }
> + io96b_ctrl->io96b[i].cal_status = true;
> + printf("%s: Initial DDR calibration IO96B_%d succeed\n", __func__, i);
> + count++;
> + }
> +
> + if (count == io96b_ctrl->num_instance)
> + io96b_ctrl->overall_cal_status = true;
Is there any chance to leave the loop with this condition not met?
> +}
> +
> +/*
> + * Trying 3 times re-calibration if initial calibration failed
> + */
> +int trig_mem_cal(struct io96b_info *io96b_ctrl)
> +{
> + struct io96b_mb_resp usr_resp;
> + bool recal_success;
> + int i, j, k;
> + u32 cal_stat_offset;
> + u8 cal_stat;
> + u8 trig_cal_stat;
> + int count = 0;
> +
> + for (i = 0; i < io96b_ctrl->num_instance; i++) {
> + if (!(io96b_ctrl->io96b[i].cal_status)) {
Invert this condition and continue the loop instead. Saves you one
indention level.
> + for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) {
> + /* Get the memory calibration status for memory interface */
> + io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0
> + , CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS, 0, 0, 0
> + , 0, 0, 0, 0, 2, &usr_resp);
Move this into the loop below.
> +
> + recal_success = false;
> +
> + /* Re-calibration first memory interface with failed calibration */
> + for (k = 0; k < MAX_RETRY_COUNT; k++) {
> + cal_stat_offset = usr_resp.cmd_resp_data[j];
> + cal_stat = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
> + cal_stat_offset);
> + if (cal_stat == INTF_MEM_CAL_STATUS_SUCCESS) {
> + recal_success = true;
> + break;
> + }
> + io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr
> + , io96b_ctrl->io96b[i].mb_ctrl.ip_type[j]
> + , io96b_ctrl->io96b[i].mb_ctrl.ip_instance_id[j]
> + , CMD_TRIG_MEM_CAL_OP, TRIG_MEM_CAL, 0, 0, 0, 0, 0
> + , 0, 0, 2, &usr_resp);
> +
> + trig_cal_stat =
> + IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) &
> + BIT(0);
> + pr_debug("%s: Memory calibration triggered status = %d\n",
> + __func__, trig_cal_stat);
> +
> + udelay(1);
> +
> + io96b_mb_req(io96b_ctrl->io96b[i].io96b_csr_addr, 0, 0
> + , CMD_TRIG_MEM_CAL_OP, GET_MEM_CAL_STATUS
> + , 0, 0, 0, 0, 0, 0, 0, 2, &usr_resp);
> + }
> +
> + if (!recal_success) {
> + printf("%s: Error as SDRAM calibration failed\n", __func__);
> + hang();
> + }
> + }
> +
> + io96b_ctrl->io96b[i].cal_status = true;
> + io96b_ctrl->overall_cal_status = io96b_ctrl->io96b[i].cal_status;
> + printf("%s: Initial DDR calibration IO96B_%d succeed\n", __func__, i);
> + count++;
> + }
> + }
> +
> + if (io96b_ctrl->overall_cal_status)
> + pr_debug("%s: Overall SDRAM calibration success\n", __func__);
> +
> + return 0;
> +}
> +
> +++ b/arch/arm/mach-socfpga/iossm_mailbox.h
> @@ -0,0 +1,152 @@
> +#ifndef IOSSM_MAILBOX_H_
> +#define IOSSM_MAILBOX_H_
> +
> +/* SPDX-License-Identifier: GPL-2.0 */
> +/*
> + * Copyright (C) 2022-2023 Intel Corporation <www.intel.com>
> + */
> +
> +#define TIMEOUT 120000
This define is unused.
> +#define IOSSM_STATUS_CAL_SUCCESS BIT(0)
> +#define IOSSM_STATUS_CAL_FAIL BIT(1)
> +#define IOSSM_STATUS_CAL_BUSY BIT(2)
> +#define IOSSM_STATUS_COMMAND_RESPONSE_READY BIT(0)
> +#define IOSSM_CMD_RESPONSE_STATUS_OFFSET 0x45C
> +#define IOSSM_CMD_RESPONSE_DATA_0_OFFSET 0x458
> +#define IOSSM_CMD_RESPONSE_DATA_1_OFFSET 0x454
> +#define IOSSM_CMD_RESPONSE_DATA_2_OFFSET 0x450
> +#define IOSSM_CMD_REQ_OFFSET 0x43C
> +#define IOSSM_CMD_PARAM_0_OFFSET 0x438
> +#define IOSSM_CMD_PARAM_1_OFFSET 0x434
> +#define IOSSM_CMD_PARAM_2_OFFSET 0x430
> +#define IOSSM_CMD_PARAM_3_OFFSET 0x42C
> +#define IOSSM_CMD_PARAM_4_OFFSET 0x428
> +#define IOSSM_CMD_PARAM_5_OFFSET 0x424
> +#define IOSSM_CMD_PARAM_6_OFFSET 0x420
> +#define IOSSM_STATUS_OFFSET 0x400
> +#define IOSSM_CMD_RESPONSE_DATA_SHORT_MASK GENMASK(31, 16)
> +#define IOSSM_CMD_RESPONSE_DATA_SHORT(data) (((data) & IOSSM_CMD_RESPONSE_DATA_SHORT_MASK) >> 16)
> +#define MAX_IO96B_SUPPORTED 2
> +
> +int io96b_mb_req(phys_addr_t io96b_csr_addr, u32 ip_type, u32 instance_id
> + , u32 usr_cmd_type, u32 usr_cmd_opcode, u32 cmd_param_0
> + , u32 cmd_param_1, u32 cmd_param_2, u32 cmd_param_3, u32 cmd_param_4
> + , u32 cmd_param_5, u32 cmd_param_6, u32 resp_data_len
> + , struct io96b_mb_resp *resp);
The majority of callers do not set any cmd_param, so maybe create
a static inline io96b_mb_req_no_param()?
> +
> +/* Supported IOSSM mailbox function */
> +void io96b_mb_init(struct io96b_info *io96b_ctrl);
> +int io96b_cal_status(phys_addr_t addr);
> +void init_mem_cal(struct io96b_info *io96b_ctrl);
> +int trig_mem_cal(struct io96b_info *io96b_ctrl);
> +int get_mem_technology(struct io96b_info *io96b_ctrl);
> +int get_mem_width_info(struct io96b_info *io96b_ctrl);
> +int ecc_enable_status(struct io96b_info *io96b_ctrl);
> +int bist_mem_init_start(struct io96b_info *io96b_ctrl);
Please give these functions a meaningful prefix. io96b_ maybe?
> +#include <mach/socfpga/mailbox_s10.h>
> +#include <mach/socfpga/soc64-regs.h>
> +#include <mach/socfpga/soc64-system-manager.h>
> +
> +#define MBOX_READL(reg) \
> + readl(SOCFPGA_MAILBOX_ADDRESS + (reg))
> +
> +#define MBOX_WRITEL(data, reg) \
> + writel(data, SOCFPGA_MAILBOX_ADDRESS + (reg))
> +
> +#define MBOX_READ_RESP_BUF(rout) \
> + MBOX_READL(MBOX_RESP_BUF + ((rout) * sizeof(u32)))
> +
> +#define MBOX_WRITE_CMD_BUF(data, cin) \
> + MBOX_WRITEL(data, MBOX_CMD_BUF + ((cin) * sizeof(u32)))
> +
> +static __always_inline int mbox_polling_resp(u32 rout)
Why not let the compiler decide if this and the following functions
should be inlined or not?
> +{
> + u32 rin;
> + unsigned long i = 2000;
> +
> + while (i) {
> + rin = MBOX_READL(MBOX_RIN);
> + if (rout != rin)
> + return 0;
> +
> + udelay(1000);
> + i--;
> + }
> +
> + return -ETIMEDOUT;
> +}
> +
> +static __always_inline int mbox_write_cmd_buffer(u32 *cin, u32 data,
> + int *is_cmdbuf_overflow)
*is_cmdbuf_overflow is always initialized to 0 by the caller which makes
it rather unnecessary to be a function parameter.
> +{
> + int timeout = 1000;
> +
> + while (timeout) {
> + if (mbox_is_cmdbuf_full(*cin)) {
> + if (is_cmdbuf_overflow &&
> + *is_cmdbuf_overflow == 0) {
> + /* Trigger SDM doorbell */
> + MBOX_WRITEL(1, MBOX_DOORBELL_TO_SDM);
> + *is_cmdbuf_overflow = 1;
> + }
> + udelay(1000);
> + } else {
> + /* write header to circular buffer */
> + MBOX_WRITE_CMD_BUF(data, (*cin)++);
> + *cin %= MBOX_CMD_BUFFER_SIZE;
> + MBOX_WRITEL(*cin, MBOX_CIN);
> + if (is_cmdbuf_overflow)
> + *is_cmdbuf_overflow = 0;
> + break;
> + }
> + timeout--;
> + }
> +
> + if (!timeout)
> + return -ETIMEDOUT;
> +
> + return 0;
> +}
> +
> +
...
> +
> +int mbox_init(void)
Please give exported functions a meaningful prefix.
> +{
> + int ret;
> +
> + /* enable mailbox interrupts */
> + MBOX_WRITEL(MBOX_ALL_INTRS, MBOX_FLAGS);
> +
> + /* Ensure urgent request is cleared */
> + MBOX_WRITEL(0, MBOX_URG);
> +
> + /* Ensure the Doorbell Interrupt is cleared */
> + MBOX_WRITEL(0, MBOX_DOORBELL_FROM_SDM);
> +
> + ret = mbox_send_cmd(MBOX_ID_BAREBOX, MBOX_RESTART, MBOX_CMD_DIRECT, 0,
> + NULL, 1, 0, NULL);
> + if (ret)
> + return ret;
> +
> + pr_debug("%s: success...\n", __func__);
> +
> + /* Renable mailbox interrupts after MBOX_RESTART */
> + MBOX_WRITEL(MBOX_ALL_INTRS, MBOX_FLAGS);
> +
> + return 0;
> +}
> +
> diff --git a/include/linux/intel-smc.h b/include/linux/intel-smc.h
Move somewhere in include/mach/socfpga/
> new file mode 100644
> diff --git a/include/mach/socfpga/soc64-init.h b/include/mach/socfpga/soc64-init.h
> new file mode 100644
> index 0000000000000000000000000000000000000000..15113f70701c6452affad3725c3e8375133300f3
> --- /dev/null
> +++ b/include/mach/socfpga/soc64-init.h
> @@ -0,0 +1,4 @@
> +#ifndef SOC64-INIT_H_
> +#define SOC64-INIT_H_
> +
> +#endif // SOC64-INIT_H_
This file is empty and unused.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 05/10] ARM: socfpga: add Arrow AXE5 Agilex5 board
2024-10-29 8:42 ` [PATCH 05/10] ARM: socfpga: add Arrow AXE5 Agilex5 board Steffen Trumtrar
@ 2024-11-04 10:48 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2024-11-04 10:48 UTC (permalink / raw)
To: Steffen Trumtrar; +Cc: barebox
On Tue, Oct 29, 2024 at 09:42:35AM +0100, Steffen Trumtrar wrote:
> Add the Agilex5-based Arrow AXE5-Eagle board.
> It consists among other things of:
> - Agilex5 SoCFPGA
> - 1 GB LPDDR4 SDRAM for HPS
> - 1 GB LPDDR4 SDRAM for FPGA
> - 1 Gb QSPI for configuration via SDM
> - microSD
> - 4-port USB hub
> - 2x 1Gb Ethernet
> - HDMI output
>
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> ---
> arch/arm/boards/Makefile | 1 +
> arch/arm/boards/arrow-axe5-eagle/Makefile | 3 +
> arch/arm/boards/arrow-axe5-eagle/board.c | 23 +++++++
> arch/arm/boards/arrow-axe5-eagle/lowlevel.c | 58 ++++++++++++++++++
> arch/arm/configs/socfpga-agilex5_defconfig | 88 +++++++++++++++++++++++++++
> arch/arm/dts/Makefile | 1 +
> arch/arm/dts/socfpga_agilex5_axe5_eagle.dts | 94 +++++++++++++++++++++++++++++
> images/Makefile.socfpga | 9 +++
> 8 files changed, 277 insertions(+)
>
> diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile
> index e0dc27cb3d21cc7bc763f148595321562d65d740..bc4d3bb4ea9e5691de90cbf7e6b0fbc577076732 100644
> --- a/arch/arm/boards/Makefile
> +++ b/arch/arm/boards/Makefile
> @@ -111,6 +111,7 @@ obj-$(CONFIG_MACH_SAMA5D4_WIFX) += sama5d4_wifx/
> obj-$(CONFIG_MACH_SCB9328) += scb9328/
> obj-$(CONFIG_MACH_SEEED_ODYSSEY) += seeed-odyssey/
> obj-$(CONFIG_MACH_SOCFPGA_ALTERA_SOCDK) += altera-socdk/
> +obj-$(CONFIG_MACH_SOCFPGA_ARROW_AXE5_EAGLE) += arrow-axe5-eagle/
> obj-$(CONFIG_MACH_SOCFPGA_EBV_SOCRATES) += ebv-socrates/
> obj-$(CONFIG_MACH_SOCFPGA_ENCLUSTRA_AA1) += enclustra-aa1/
> obj-$(CONFIG_MACH_SOCFPGA_REFLEX_ACHILLES) += reflex-achilles/
> diff --git a/arch/arm/boards/arrow-axe5-eagle/Makefile b/arch/arm/boards/arrow-axe5-eagle/Makefile
> new file mode 100644
> index 0000000000000000000000000000000000000000..1d052d28c9fc6a82dbf806eedac60fac8a56d4f9
> --- /dev/null
> +++ b/arch/arm/boards/arrow-axe5-eagle/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +lwl-y += lowlevel.o
> +obj-y += board.o
> diff --git a/arch/arm/boards/arrow-axe5-eagle/board.c b/arch/arm/boards/arrow-axe5-eagle/board.c
> new file mode 100644
> index 0000000000000000000000000000000000000000..1efea0b3d9cf0aa5ecd7c67ea9348708dcfd0b80
> --- /dev/null
> +++ b/arch/arm/boards/arrow-axe5-eagle/board.c
> @@ -0,0 +1,23 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +#include <common.h>
> +#include <init.h>
> +#include <io.h>
> +#include <bbu.h>
> +#include <mach/socfpga/soc64-regs.h>
> +
> +static int axe5_init(void)
> +{
> + if (!of_machine_is_compatible("arrow,axe5-eagle"))
> + return 0;
> +
> + pr_debug("Change the pullup values on EMAC2 HPS mii signals\n");
> + writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x224);
> + writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x228);
> + writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x23c);
> + writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x234);
> + writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x248);
> + writel(0x14, SOCFPGA_PINMUX_ADDRESS + 0x24c);
> +
> + return 0;
> +}
> +postcore_initcall(axe5_init);
Please convert to a board driver.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 06/10] net: add support for Designware XGMAC (10gb) ethernet
2024-10-29 8:42 ` [PATCH 06/10] net: add support for Designware XGMAC (10gb) ethernet Steffen Trumtrar
@ 2024-11-04 11:14 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2024-11-04 11:14 UTC (permalink / raw)
To: Steffen Trumtrar; +Cc: barebox
On Tue, Oct 29, 2024 at 09:42:36AM +0100, Steffen Trumtrar wrote:
> +static int xgmac_mdio_read(struct mii_bus *bus, int mdio_addr, int mdio_reg)
> +{
> + struct xgmac_priv *xgmac = bus->priv;
> + u32 val;
> + u32 hw_addr;
> + u32 idle;
> + int ret;
> +
> + ret = readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
> + !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
> + XGMAC_TIMEOUT_100MS);
> + if (ret) {
> + pr_err("MDIO not idle at entry: %d\n", ret);
dev_err() please. Same for other pr_ style functions in this file.
> + return ret;
> + }
> +
> + /* Set clause 22 format */
> + val = BIT(mdio_addr);
> + writel(val, &xgmac->mac_regs->mdio_clause_22_port);
> +
> + hw_addr = (mdio_addr << XGMAC_MAC_MDIO_ADDRESS_PA_SHIFT) |
> + (mdio_reg & XGMAC_MAC_MDIO_REG_ADDR_C22P_MASK);
> +
> + val = xgmac->config->config_mac_mdio <<
> + XGMAC_MAC_MDIO_ADDRESS_CR_SHIFT;
> +
> + val |= XGMAC_MAC_MDIO_ADDRESS_SADDR |
> + XGMAC_MDIO_SINGLE_CMD_ADDR_CMD_READ |
> + XGMAC_MAC_MDIO_ADDRESS_SBUSY;
> +
> + ret = readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
> + !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
> + XGMAC_TIMEOUT_100MS);
> + if (ret) {
> + pr_err("MDIO not idle at entry: %d\n", ret);
> + return ret;
> + }
> +
> + writel(hw_addr, &xgmac->mac_regs->mdio_address);
> + writel(val, &xgmac->mac_regs->mdio_data);
> +
> + ret = readl_poll_timeout(&xgmac->mac_regs->mdio_data, idle,
> + !(idle & XGMAC_MAC_MDIO_ADDRESS_SBUSY),
> + XGMAC_TIMEOUT_100MS);
> + if (ret) {
> + pr_err("MDIO read didn't complete: %d\n", ret);
> + return ret;
> + }
> +
> + val = readl(&xgmac->mac_regs->mdio_data);
> + val &= XGMAC_MAC_MDIO_DATA_GD_MASK;
> +
> + return val;
> +}
> +
> +static int xgmac_send(struct eth_device *edev, void *packet, int length)
> +{
> + struct xgmac_priv *xgmac = edev->priv;
> + struct xgmac_desc *tx_desc;
> + dma_addr_t dma;
> + u32 des3_prev, des3;
> + int ret;
> +
> + tx_desc = &xgmac->tx_descs[xgmac->tx_desc_idx];
> + xgmac->tx_desc_idx++;
> + xgmac->tx_desc_idx %= XGMAC_DESCRIPTORS_NUM;
> +
> + dma = dma_map_single(edev->parent, packet, length, DMA_TO_DEVICE);
> + if (dma_mapping_error(edev->parent, dma))
> + return -EFAULT;
> +
> + tx_desc->des0 = dma;
lower_32_bits()
> + tx_desc->des1 = 0;
upper_32_bits() go here?
> + tx_desc->des2 = length;
> + /*
> + * Make sure that if HW sees the _OWN write below, it will see all the
> + * writes to the rest of the descriptor too.
> + */
> + barrier();
> +
> + des3_prev = XGMAC_DESC3_OWN | XGMAC_DESC3_FD | XGMAC_DESC3_LD | length;
> + writel(des3_prev, &tx_desc->des3);
> + writel((ulong)(tx_desc + 1), &xgmac->dma_regs->ch0_txdesc_tail_pointer); // <-- TODO
> +
> + ret = readl_poll_timeout(&tx_desc->des3, des3,
> + !(des3 & XGMAC_DESC3_OWN),
> + 100 * USEC_PER_MSEC);
> +
> + dma_unmap_single(edev->parent, dma, length, DMA_TO_DEVICE);
> +
> + if (ret == -ETIMEDOUT)
> + debug("%s: TX timeout 0x%08x\n", __func__, des3);
> +
> + return ret;
> +}
> +
> +static void xgmac_recv(struct eth_device *edev)
> +{
> + struct xgmac_priv *xgmac = edev->priv;
> + struct xgmac_desc *rx_desc;
> + dma_addr_t dma;
> + void *pkt;
> + int length;
> +
> + rx_desc = &xgmac->rx_descs[xgmac->rx_desc_idx];
> +
> + if (rx_desc->des3 & XGMAC_DESC3_OWN)
> + return;
> +
> + dma = xgmac->dma_rx_buf[xgmac->rx_desc_idx];
> + pkt = phys_to_virt(dma);
You should store the virtual address somewhere in your private data and
use it here rather than converting back the dma address.
> + length = rx_desc->des3 & XGMAC_RDES3_PKT_LENGTH_MASK;
> +
> + dma_sync_single_for_cpu(edev->parent, (unsigned long)pkt, length,
> + DMA_FROM_DEVICE);
Use the dma address directly here.
> + net_receive(edev, pkt, length);
> + dma_sync_single_for_device(edev->parent, (unsigned long)pkt,
> + length, DMA_FROM_DEVICE);
> +
> + /* Read Format RX descriptor */
> + rx_desc = &xgmac->rx_descs[xgmac->rx_desc_idx];
> + rx_desc->des0 = dma;
> + rx_desc->des1 = 0;
> + rx_desc->des2 = 0;
> + /*
> + * Make sure that if HW sees the _OWN write below, it will see all the
> + * writes to the rest of the descriptor too.
> + */
> + rx_desc->des3 = XGMAC_DESC3_OWN;
> + barrier();
> +
> + writel((ulong)rx_desc, &xgmac->dma_regs->ch0_rxdesc_tail_pointer);
calculate the address based on xgmac->rx_descs_phys rather than assuming
a 1:1 mapping.
> +
> + xgmac->rx_desc_idx++;
> + xgmac->rx_desc_idx %= XGMAC_DESCRIPTORS_NUM;
> +}
> +
> +int xgmac_probe(struct device *dev)
> +{
> + struct device_node *np = dev->of_node;
> + struct mii_bus *miibus;
> + struct xgmac_priv *xgmac;
> + struct resource *iores;
> + struct eth_device *edev;
> + int ret = 0;
> +
> + xgmac = xzalloc(sizeof(*xgmac));
> +
> + xgmac->dev = dev;
> + ret = dev_get_drvdata(dev, (const void **)&xgmac->config);
Use device_get_match_data() instead.
> + if (ret < 0) {
> + pr_err("xgmac_probe() failed to get driver data: %d\n", ret);
> + return ret;
> + }
> +
> + iores = dev_request_mem_resource(dev, 0);
> + if (IS_ERR(iores))
> + return PTR_ERR(iores);
> + xgmac->regs = IOMEM(iores->start);
> +
> + xgmac->mac_regs = (void *)(xgmac->regs + XGMAC_MAC_REGS_BASE);
> + xgmac->mtl_regs = (void *)(xgmac->regs + XGMAC_MTL_REGS_BASE);
> + xgmac->dma_regs = (void *)(xgmac->regs + XGMAC_DMA_REGS_BASE);
xgmac->regs already is of type void *, no need to cast-
> +
> +/* DMA Registers */
> +
> +#define XGMAC_DMA_REGS_BASE 0x3000
> +
> +struct xgmac_dma_regs {
> + u32 mode; /* 0x3000 */
> + u32 sysbus_mode; /* 0x3004 */
> + u32 unused_3008[(0x3100 - 0x3008) / 4]; /* 0x3008 */
> + u32 ch0_control; /* 0x3100 */
> + u32 ch0_tx_control; /* 0x3104 */
> + u32 ch0_rx_control; /* 0x3108 */
> + u32 slot_func_control_status; /* 0x310c */
> + u32 ch0_txdesc_list_haddress; /* 0x3110 */
> + u32 ch0_txdesc_list_address; /* 0x3114 */
> + u32 ch0_rxdesc_list_haddress; /* 0x3118 */
> + u32 ch0_rxdesc_list_address; /* 0x311c */
> + u32 unused_3120; /* 0x3120 */
Is this really unused or should it be the upper 32 bit of
ch0_txdesc_tail_pointer?
> + u32 ch0_txdesc_tail_pointer; /* 0x3124 */
> + u32 unused_3128; /* 0x3128 */
Same for ch0_rxdesc_tail_pointer.
> + u32 ch0_rxdesc_tail_pointer; /* 0x312c */
> + u32 ch0_txdesc_ring_length; /* 0x3130 */
> + u32 ch0_rxdesc_ring_length; /* 0x3134 */
> + u32 unused_3138[(0x3160 - 0x3138) / 4]; /* 0x3138 */
> + u32 ch0_status; /* 0x3160 */
> +};
> +
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH 10/10] clk: socfpga: add agilex5 clock support
2024-10-29 8:42 ` [PATCH 10/10] clk: socfpga: add agilex5 clock support Steffen Trumtrar
@ 2024-11-04 11:23 ` Sascha Hauer
0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2024-11-04 11:23 UTC (permalink / raw)
To: Steffen Trumtrar; +Cc: barebox
On Tue, Oct 29, 2024 at 09:42:40AM +0100, Steffen Trumtrar wrote:
> Add support for the Stratix10 and Agilex5 pll,gate and periph clocks.
>
> Only tested on Agilex5.
>
> Signed-off-by: Steffen Trumtrar <s.trumtrar@pengutronix.de>
> ---
> drivers/clk/socfpga/Makefile | 4 +-
> drivers/clk/socfpga/clk-agilex5.c | 834 ++++++++++++++++++++++++++++++
> drivers/clk/socfpga/clk-gate-s10.c | 184 +++++++
> drivers/clk/socfpga/clk-periph-s10.c | 163 ++++++
> drivers/clk/socfpga/clk-pll-s10.c | 140 +++++
> drivers/clk/socfpga/clk.h | 9 +
> drivers/clk/socfpga/stratix10-clk.h | 73 +++
> include/dt-bindings/clock/agilex5-clock.h | 135 +++--
> 8 files changed, 1488 insertions(+), 54 deletions(-)
Move this patch up. clk support should be available when adding a board
using it.
> +static int agilex5_clkmgr_probe(struct device *dev)
> +{
> + struct device_node *np = dev->of_node;
> + struct stratix10_clock_data *clk_data;
> + struct resource *res;
> + int i, num_clks;
> +
> + res = dev_get_resource(dev, IORESOURCE_MEM, 0);
> + if (IS_ERR(res))
> + return PTR_ERR(res);
> +
> + num_clks = AGILEX5_NUM_CLKS;
> +
> + clk_data = xzalloc(struct_size(clk_data, clk_data.hws, num_clks));
> + if (!clk_data)
> + return -ENOMEM;
Won't happen.
> +static int socfpga_gate_get_parent(struct clk_hw *hwclk)
> +{
> + struct socfpga_gate_clk *socfpgaclk = to_socfpga_gate_clk(hwclk);
> + u32 mask, second_bypass;
> + u8 parent = 0;
> + const char *name = clk_hw_get_name(hwclk);
> +
> +printk("%s: %s\n", __func__, name);
> +
> + if (socfpgaclk->bypass_reg) {
> + mask = (0x1 << socfpgaclk->bypass_shift);
> + parent = ((readl(socfpgaclk->bypass_reg) & mask) >>
> + socfpgaclk->bypass_shift);
> +printk("%s: parent %d\n", __func__, parent);
Debugging leftovers.
> +struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase)
> +{
> + struct clk_hw *hw_clk;
> + struct socfpga_gate_clk *socfpga_clk;
> + struct clk_init_data init;
> + const char *parent_name = clks->parent_name;
> + int ret;
> +
> + socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
> + if (!socfpga_clk)
> + return NULL;
Won't happen.
> diff --git a/include/dt-bindings/clock/agilex5-clock.h b/include/dt-bindings/clock/agilex5-clock.h
We have dts/include/dt-bindings/clock/intel,agilex5-clkmgr.h derived
from upstream dts import. Please switch to this one instead.
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2024-11-04 11:32 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-10-29 8:42 [PATCH 00/10] ARM: SoCFPGA: Add initial support for Agilex5 Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 01/10] ARM: socfpga: kconfig: sort entries Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 02/10] mach: socfpga: debug_ll: rework putc_ll Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 03/10] reset: reset-socfpga: build only for 32-bit socfpga Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 04/10] arm: socfgpa: add support for SoCFPGA Agilex5 Steffen Trumtrar
2024-11-04 10:31 ` Sascha Hauer
2024-10-29 8:42 ` [PATCH 05/10] ARM: socfpga: add Arrow AXE5 Agilex5 board Steffen Trumtrar
2024-11-04 10:48 ` Sascha Hauer
2024-10-29 8:42 ` [PATCH 06/10] net: add support for Designware XGMAC (10gb) ethernet Steffen Trumtrar
2024-11-04 11:14 ` Sascha Hauer
2024-10-29 8:42 ` [PATCH 07/10] net: phy: add Analog Devices ADIN1300 Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 08/10] linux: clk: add clk_parent_data Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 09/10] clk: support init->parent_data Steffen Trumtrar
2024-10-29 8:42 ` [PATCH 10/10] clk: socfpga: add agilex5 clock support Steffen Trumtrar
2024-11-04 11:23 ` Sascha Hauer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox