mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [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, &reg_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, &reg_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, &reg_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