This pull request introduces initial U-Boot support for Agilex7 M-series, along
with several enhancements and cleanups across existing Agilex platforms. Key
changes include new board support, DDR driver additions, updated device trees,
and broader SoCFPGA SPL improvements.

Highlights:

- Agilex7 M-series bring-up:
  - Basic DT support and board initialization for Agilex7 M-series SoC and
    SoCDK.
  - New sdram_agilex7m DDR driver with UIBSSM mailbox support and HBM support.
  - Clock driver support for Agilex7 M-series.
  - New defconfig: socfpga_agilex7m_defconfig.
- Agilex and Agilex5 enhancements:
  - Improved SPL support: ASYNC interrupt enabling, system manager init
    refactor, and cold scratch register usage.
  - Updated firewall probing and watchdog support in SPL.
  - Cleaned up DDR code, added secure region support for ATF, and improved warm
    reset handling.
- Device Tree and config updates:
  - Migration to upstream Linux DT layout for Agilex platforms.
  - Consolidated socfpga_agilex_defconfig and removed deprecated configs.
  - Platform-specific environment variables for Distro Boot added.
- Driver fixes and cleanups:
  - dwc_eth_xgmac and clk-agilex cleanup and improvements.
  - Several coverity and style fixes.

Contributions in this PR are from Alif Zakuan Yuslaimi, Tingting Meng, and
Andrew Goodbody.  This patch set has been tested on Agilex 5 devkit, Agilex
devkit and Agilex7m devkit.

Passing all pipeline tests at SoCFPGA U-boot custodian
https://source.denx.de/u-boot/custodians/u-boot-socfpga/-/pipelines/27318
This commit is contained in:
Tom Rini
2025-08-08 11:13:41 -06:00
47 changed files with 2113 additions and 1004 deletions

View File

@@ -152,13 +152,14 @@ ARM ALTERA SOCFPGA
M: Marek Vasut <marex@denx.de>
M: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
M: Tien Fong Chee <tien.fong.chee@altera.com>
M: Tingting Meng <tingting.meng@altera.com>
S: Maintained
T: git https://source.denx.de/u-boot/custodians/u-boot-socfpga.git
F: arch/arm/dts/socfpga_*
F: arch/arm/mach-socfpga/
F: board/intel/agilex-socdk/
F: configs/socfpga_*
F: drivers/ddr/altera/
F: drivers/power/domain/altr-pmgr-agilex5.c
F: arch/arm/mach-socfpga/
F: configs/socfpga_agilex5_vab_defconfig
F: drivers/sysreset/sysreset_socfpga*
ARM AMLOGIC SOC SUPPORT

View File

@@ -22,6 +22,9 @@ config ARM64_CRC32
not be present on all ARMv8.0, but is always present on ARMv8.1 and
newer.
config BOOTFILE
default kernel.itb if SPL_ATF && TARGET_SOCFPGA_SOC64
config COUNTER_FREQUENCY
int "Timer clock frequency"
depends on ARM64 || CPU_V7A
@@ -30,7 +33,7 @@ config COUNTER_FREQUENCY
ROCKCHIP_RK3288 || ROCKCHIP_RK322X || ROCKCHIP_RK3036
default 25000000 if ARCH_LX2160A || ARCH_LX2162A || ARCH_LS1088A
default 100000000 if ARCH_ZYNQMP
default 200000000 if ARCH_SOCFPGA && ARM64 && TARGET_SOCFPGA_AGILEX5
default 200000000 if TARGET_SOCFPGA_AGILEX5 || TARGET_SOCFPGA_AGILEX7M
default 0
help
For platforms with ARMv8-A and ARMv7-A which features a system
@@ -1173,7 +1176,7 @@ config ARCH_SOCFPGA
select SYSRESET
select SYSRESET_SOCFPGA if TARGET_SOCFPGA_GEN5 || TARGET_SOCFPGA_ARRIA10
select SYSRESET_SOCFPGA_SOC64 if !TARGET_SOCFPGA_AGILEX5 && \
TARGET_SOCFPGA_SOC64
TARGET_SOCFPGA_SOC64
select SYSRESET_PSCI if TARGET_SOCFPGA_AGILEX5
imply CMD_DM
imply CMD_MTDPARTS

View File

@@ -448,7 +448,6 @@ dtb-$(CONFIG_AM43XX) += am437x-gp-evm.dtb am437x-sk-evm.dtb \
dtb-$(CONFIG_TARGET_THUNDERX_88XX) += thunderx-88xx.dtb
dtb-$(CONFIG_ARCH_SOCFPGA) += \
socfpga_agilex_socdk.dtb \
socfpga_agilex5_socdk.dtb \
socfpga_arria5_secu1.dtb \
socfpga_arria5_socdk.dtb \

View File

@@ -3,20 +3,40 @@
* U-Boot additions
*
* Copyright (C) 2019-2020 Intel Corporation <www.intel.com>
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include "socfpga_soc64_u-boot.dtsi"
#include "socfpga_soc64_fit-u-boot.dtsi"
/{
memory {
aliases {
spi0 = &qspi;
i2c0 = &i2c1;
sysmgr = &sysmgr;
freeze_br0 = &freeze_controller;
};
memory@0 {
device_type = "memory";
#address-cells = <2>;
#size-cells = <2>;
bootph-all;
};
soc {
pmu {
compatible = "arm,armv8-pmuv3";
};
soc@0 {
bootph-all;
freeze_controller: freeze_controller@f9000450 {
compatible = "altr,freeze-bridge-controller";
reg = <0xf9000450 0x00000010>;
status = "disabled";
};
ccu: cache-controller@f7000000 {
compatible = "arteris,ncore-ccu";
reg = <0xf7000000 0x100900>;
@@ -29,11 +49,39 @@
bootph-all;
};
&gmac0 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
reset-names = "stmmaceth", "stmmaceth-ocp";
clocks = <&clkmgr AGILEX_EMAC0_CLK>;
clock-names = "stmmaceth";
phy-mode = "rgmii";
max-frame-size = <0x2328>;
status = "okay";
mdio0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
};
};
&gmac1 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
reset-names = "stmmaceth", "stmmaceth-ocp";
altr,sysmgr-syscon = <&sysmgr 0x48 0>;
clocks = <&clkmgr AGILEX_EMAC1_CLK>;
clock-names = "stmmaceth";
status = "disabled";
altr,sysmgr-syscon = <&sysmgr 0x48 0>;
};
&gmac2 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
reset-names = "stmmaceth", "stmmaceth-ocp";
altr,sysmgr-syscon = <&sysmgr 0x4c 0>;
clocks = <&clkmgr AGILEX_EMAC2_CLK>;
clock-names = "stmmaceth";
status = "disabled";
altr,sysmgr-syscon = <&sysmgr 0x4c 0>;
};
@@ -43,6 +91,7 @@
&i2c1 {
reset-names = "i2c";
status = "okay";
};
&i2c2 {
@@ -67,6 +116,15 @@
&qspi {
bootph-all;
compatible = "cdns,qspi-nor";
flash0: flash@0 {
};
};
&flash0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "jedec,spi-nor";
};
&rst {
@@ -84,6 +142,79 @@
bootph-all;
};
&socfpga_l3interconnect_firewall {
CCU_coh_cpu0_bypass_OC_Firewall_main_Firewall@f7100200 {
reg = <0xf7100200 0x00000014>;
intel,offset-settings =
/* Disable ocram security at CCU for non secure access */
<0x0000004 0x8000ffff 0xe003ffff>,
<0x0000008 0x8000ffff 0xe003ffff>,
<0x000000c 0x8000ffff 0xe003ffff>,
<0x0000010 0x8000ffff 0xe003ffff>;
bootph-all;
};
soc_noc_fw_mpfe_csr_inst_0_mpfe_scr@f8020000 {
reg = <0xf8020000 0x0000001c>;
intel,offset-settings =
/* Disable MPFE firewall for SMMU */
<0x00000000 0x00010101 0x00010101>,
/* Disable MPFE firewall for HMC adapter */
<0x00000004 0x00000001 0x00010101>;
bootph-all;
};
/*
* Below are all fpga2sdram firewall settings with default
* reset value for the sake of easy reference by users.
* Users may choose to remove any of these register
* configurations that they do not require in their specific
* implementation.
*/
soc_noc_fw_ddr_fpga2sdram_inst_0_ddr_scr@f8020100 {
reg = <0xf8020100 0x00000050>;
intel,offset-settings =
<0x0000000 0x00000000 0x0000000f>,
<0x0000004 0x00000000 0x0000000f>,
<0x0000008 0x00000000 0x0000000f>,
<0x0000010 0x00000000 0xffff0000>,
<0x0000014 0x00000000 0x000000ff>,
<0x0000018 0x00000000 0xffff0000>,
<0x000001c 0x00000000 0x000000ff>,
<0x0000020 0x00000000 0xffff0000>,
<0x0000024 0x00000000 0x000000ff>,
<0x0000028 0x00000000 0xffff0000>,
<0x000002c 0x00000000 0x000000ff>,
<0x0000030 0x00000000 0xffff0000>,
<0x0000034 0x00000000 0x000000ff>,
<0x0000038 0x00000000 0xffff0000>,
<0x000003c 0x00000000 0x000000ff>,
<0x0000040 0x00000000 0xffff0000>,
<0x0000044 0x00000000 0x000000ff>,
<0x0000048 0x00000000 0xffff0000>,
<0x000004c 0x00000000 0x000000ff>;
bootph-all;
};
/*
* Example of ccu_mem0_I_main QOS settings with
* default reset value for the sake of easy reference
* by users. Users may choose to remove any of these register
* configurations that they do not require in their specific
* implementation.
*/
soc_mpfe_noc_inst_0_ccu_mem0_I_main_QosGenerator@f8022080 {
reg = <0xf8022080 0x0000001c>;
intel,offset-settings =
<0x0000008 0x00000200 0x00000303>,
<0x000000c 0x00000003 0x00000003>,
<0x0000010 0x00000BFE 0x00007fff>,
<0x0000014 0x00000008 0x000003ff>,
<0x0000018 0x00000000 0x0000000f>;
bootph-all;
};
};
&sysmgr {
compatible = "altr,sys-mgr", "syscon";
bootph-all;
@@ -91,8 +222,51 @@
&uart0 {
bootph-all;
clock-frequency = <100000000>;
};
&watchdog0 {
bootph-all;
};
&nand {
clocks = <&clkmgr AGILEX_NAND_CLK>,
<&clkmgr AGILEX_NAND_X_CLK>;
clock-names = "nand", "nand_x";
};
&usb0 {
compatible = "snps,dwc2";
};
&usb1 {
compatible = "snps,dwc2";
};
&spi0 {
compatible = "intel,agilex-spi",
"snps,dw-apb-ssi-4.00a", "snps,dw-apb-ssi";
};
&spi1 {
compatible = "intel,agilex-spi",
"snps,dw-apb-ssi-4.00a", "snps,dw-apb-ssi";
};
&pdma {
#dma-channels = <8>;
#dma-requests = <32>;
};
#if !defined(CONFIG_SOCFPGA_SECURE_VAB_AUTH)
&binman {
/delete-node/ kernel;
};
#endif
#ifdef CONFIG_TARGET_SOCFPGA_AGILEX7M
&sdr {
compatible = "intel,sdr-ctl-agilex7m";
reg = <0xf8020000 0x100>;
};
#endif

View File

@@ -1,624 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019-2023 Intel Corporation <www.intel.com>
*/
/dts-v1/;
#include <dt-bindings/reset/altr,rst-mgr-s10.h>
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/clock/agilex-clock.h>
/ {
compatible = "intel,socfpga-agilex";
#address-cells = <2>;
#size-cells = <2>;
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
service_reserved: svcbuffer@0 {
compatible = "shared-dma-pool";
reg = <0x0 0x0 0x0 0x2000000>;
alignment = <0x1000>;
no-map;
};
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x0>;
};
cpu1: cpu@1 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x1>;
};
cpu2: cpu@2 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x2>;
};
cpu3: cpu@3 {
compatible = "arm,cortex-a53";
device_type = "cpu";
enable-method = "psci";
reg = <0x3>;
};
};
pmu {
compatible = "arm,armv8-pmuv3";
interrupts = <0 170 4>,
<0 171 4>,
<0 172 4>,
<0 173 4>;
interrupt-affinity = <&cpu0>,
<&cpu1>,
<&cpu2>,
<&cpu3>;
interrupt-parent = <&intc>;
};
psci {
compatible = "arm,psci-0.2";
method = "smc";
};
intc: intc@fffc1000 {
compatible = "arm,gic-400", "arm,cortex-a15-gic";
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x0 0xfffc1000 0x0 0x1000>,
<0x0 0xfffc2000 0x0 0x2000>,
<0x0 0xfffc4000 0x0 0x2000>,
<0x0 0xfffc6000 0x0 0x2000>;
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
device_type = "soc";
interrupt-parent = <&intc>;
ranges = <0 0 0 0xffffffff>;
base_fpga_region {
#address-cells = <0x1>;
#size-cells = <0x1>;
compatible = "fpga-region";
fpga-mgr = <&fpga_mgr>;
};
clkmgr: clock-controller@ffd10000 {
compatible = "intel,agilex-clkmgr";
reg = <0xffd10000 0x1000>;
#clock-cells = <1>;
};
clocks {
cb_intosc_hs_div2_clk: cb-intosc-hs-div2-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
};
cb_intosc_ls_clk: cb-intosc-ls-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
};
f2s_free_clk: f2s-free-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
};
osc1: osc1 {
#clock-cells = <0>;
compatible = "fixed-clock";
};
qspi_clk: qspi-clk {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <200000000>;
};
};
gmac0: ethernet@ff800000 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
reg = <0xff800000 0x2000>;
interrupts = <0 90 4>;
interrupt-names = "macirq";
mac-address = [00 00 00 00 00 00];
resets = <&rst EMAC0_RESET>, <&rst EMAC0_OCP_RESET>;
reset-names = "stmmaceth", "stmmaceth-ocp";
tx-fifo-depth = <16384>;
rx-fifo-depth = <16384>;
snps,multicast-filter-bins = <256>;
iommus = <&smmu 1>;
altr,sysmgr-syscon = <&sysmgr 0x44 0>;
clocks = <&clkmgr AGILEX_EMAC0_CLK>;
clock-names = "stmmaceth";
status = "disabled";
};
gmac1: ethernet@ff802000 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
reg = <0xff802000 0x2000>;
interrupts = <0 91 4>;
interrupt-names = "macirq";
mac-address = [00 00 00 00 00 00];
resets = <&rst EMAC1_RESET>, <&rst EMAC1_OCP_RESET>;
reset-names = "stmmaceth", "stmmaceth-ocp";
tx-fifo-depth = <16384>;
rx-fifo-depth = <16384>;
snps,multicast-filter-bins = <256>;
iommus = <&smmu 2>;
altr,sysmgr-syscon = <&sysmgr 0x48 8>;
clocks = <&clkmgr AGILEX_EMAC1_CLK>;
clock-names = "stmmaceth";
status = "disabled";
};
gmac2: ethernet@ff804000 {
compatible = "altr,socfpga-stmmac", "snps,dwmac-3.74a", "snps,dwmac";
reg = <0xff804000 0x2000>;
interrupts = <0 92 4>;
interrupt-names = "macirq";
mac-address = [00 00 00 00 00 00];
resets = <&rst EMAC2_RESET>, <&rst EMAC2_OCP_RESET>;
reset-names = "stmmaceth", "stmmaceth-ocp";
tx-fifo-depth = <16384>;
rx-fifo-depth = <16384>;
snps,multicast-filter-bins = <256>;
iommus = <&smmu 3>;
altr,sysmgr-syscon = <&sysmgr 0x4c 16>;
clocks = <&clkmgr AGILEX_EMAC2_CLK>;
clock-names = "stmmaceth";
status = "disabled";
};
gpio0: gpio@ffc03200 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dw-apb-gpio";
reg = <0xffc03200 0x100>;
resets = <&rst GPIO0_RESET>;
status = "disabled";
porta: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
snps,nr-gpios = <24>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 110 4>;
};
};
gpio1: gpio@ffc03300 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dw-apb-gpio";
reg = <0xffc03300 0x100>;
resets = <&rst GPIO1_RESET>;
status = "disabled";
portb: gpio-controller@0 {
compatible = "snps,dw-apb-gpio-port";
gpio-controller;
#gpio-cells = <2>;
snps,nr-gpios = <24>;
reg = <0>;
interrupt-controller;
#interrupt-cells = <2>;
interrupts = <0 111 4>;
};
};
i2c0: i2c@ffc02800 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xffc02800 0x100>;
interrupts = <0 103 4>;
resets = <&rst I2C0_RESET>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
status = "disabled";
};
i2c1: i2c@ffc02900 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xffc02900 0x100>;
interrupts = <0 104 4>;
resets = <&rst I2C1_RESET>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
status = "disabled";
};
i2c2: i2c@ffc02a00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xffc02a00 0x100>;
interrupts = <0 105 4>;
resets = <&rst I2C2_RESET>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
status = "disabled";
};
i2c3: i2c@ffc02b00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xffc02b00 0x100>;
interrupts = <0 106 4>;
resets = <&rst I2C3_RESET>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
status = "disabled";
};
i2c4: i2c@ffc02c00 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,designware-i2c";
reg = <0xffc02c00 0x100>;
interrupts = <0 107 4>;
resets = <&rst I2C4_RESET>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
status = "disabled";
};
mmc: dwmmc0@ff808000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "altr,socfpga-dw-mshc";
reg = <0xff808000 0x1000>;
interrupts = <0 96 4>;
fifo-depth = <0x400>;
resets = <&rst SDMMC_RESET>;
reset-names = "reset";
clocks = <&clkmgr AGILEX_L4_MP_CLK>,
<&clkmgr AGILEX_SDMMC_CLK>;
clock-names = "biu", "ciu";
iommus = <&smmu 5>;
status = "disabled";
};
nand: nand@ffb90000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "altr,socfpga-denali-nand";
reg = <0xffb90000 0x10000>,
<0xffb80000 0x1000>;
reg-names = "nand_data", "denali_reg";
interrupts = <0 97 4>;
resets = <&rst NAND_RESET>, <&rst NAND_OCP_RESET>;
status = "disabled";
};
ocram: sram@ffe00000 {
compatible = "mmio-sram";
reg = <0xffe00000 0x40000>;
};
pdma: pdma@ffda0000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0xffda0000 0x1000>;
interrupts = <0 81 4>,
<0 82 4>,
<0 83 4>,
<0 84 4>,
<0 85 4>,
<0 86 4>,
<0 87 4>,
<0 88 4>,
<0 89 4>;
#dma-cells = <1>;
#dma-channels = <8>;
#dma-requests = <32>;
resets = <&rst DMA_RESET>, <&rst DMA_OCP_RESET>;
reset-names = "dma", "dma-ocp";
clocks = <&clkmgr AGILEX_L4_MAIN_CLK>;
clock-names = "apb_pclk";
};
rst: rstmgr@ffd11000 {
#reset-cells = <1>;
compatible = "altr,stratix10-rst-mgr";
reg = <0xffd11000 0x100>;
};
smmu: iommu@fa000000 {
compatible = "arm,mmu-500", "arm,smmu-v2";
reg = <0xfa000000 0x40000>;
#global-interrupts = <2>;
#iommu-cells = <1>;
interrupt-parent = <&intc>;
interrupts = <0 128 4>, /* Global Secure Fault */
<0 129 4>, /* Global Non-secure Fault */
/* Non-secure Context Interrupts (32) */
<0 138 4>, <0 139 4>, <0 140 4>, <0 141 4>,
<0 142 4>, <0 143 4>, <0 144 4>, <0 145 4>,
<0 146 4>, <0 147 4>, <0 148 4>, <0 149 4>,
<0 150 4>, <0 151 4>, <0 152 4>, <0 153 4>,
<0 154 4>, <0 155 4>, <0 156 4>, <0 157 4>,
<0 158 4>, <0 159 4>, <0 160 4>, <0 161 4>,
<0 162 4>, <0 163 4>, <0 164 4>, <0 165 4>,
<0 166 4>, <0 167 4>, <0 168 4>, <0 169 4>;
stream-match-mask = <0x7ff0>;
status = "disabled";
};
spi0: spi@ffda4000 {
compatible = "intel,agilex-spi",
"snps,dw-apb-ssi-4.00a", "snps,dw-apb-ssi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xffda4000 0x1000>;
interrupts = <0 99 4>;
resets = <&rst SPIM0_RESET>;
reg-io-width = <4>;
num-cs = <4>;
clocks = <&clkmgr AGILEX_L4_MAIN_CLK>;
status = "disabled";
};
spi1: spi@ffda5000 {
compatible = "intel,agilex-spi",
"snps,dw-apb-ssi-4.00a", "snps,dw-apb-ssi";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xffda5000 0x1000>;
interrupts = <0 100 4>;
resets = <&rst SPIM1_RESET>;
reg-io-width = <4>;
num-cs = <4>;
clocks = <&clkmgr AGILEX_L4_MAIN_CLK>;
status = "disabled";
};
sysmgr: sysmgr@ffd12000 {
compatible = "altr,sys-mgr-s10","altr,sys-mgr";
reg = <0xffd12000 0x500>;
};
/* Local timer */
timer {
compatible = "arm,armv8-timer";
interrupts = <1 13 0xf08>,
<1 14 0xf08>,
<1 11 0xf08>,
<1 10 0xf08>;
};
timer0: timer0@ffc03000 {
compatible = "snps,dw-apb-timer";
interrupts = <0 113 4>;
reg = <0xffc03000 0x100>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
clock-names = "timer";
};
timer1: timer1@ffc03100 {
compatible = "snps,dw-apb-timer";
interrupts = <0 114 4>;
reg = <0xffc03100 0x100>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
clock-names = "timer";
};
timer2: timer2@ffd00000 {
compatible = "snps,dw-apb-timer";
interrupts = <0 115 4>;
reg = <0xffd00000 0x100>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
clock-names = "timer";
};
timer3: timer3@ffd00100 {
compatible = "snps,dw-apb-timer";
interrupts = <0 116 4>;
reg = <0xffd00100 0x100>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
clock-names = "timer";
};
uart0: serial0@ffc02000 {
compatible = "snps,dw-apb-uart";
reg = <0xffc02000 0x100>;
interrupts = <0 108 4>;
reg-shift = <2>;
reg-io-width = <4>;
resets = <&rst UART0_RESET>;
status = "disabled";
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
clock-frequency = <100000000>;
};
uart1: serial1@ffc02100 {
compatible = "snps,dw-apb-uart";
reg = <0xffc02100 0x100>;
interrupts = <0 109 4>;
reg-shift = <2>;
reg-io-width = <4>;
resets = <&rst UART1_RESET>;
clocks = <&clkmgr AGILEX_L4_SP_CLK>;
status = "disabled";
};
usbphy0: usbphy@0 {
#phy-cells = <0>;
compatible = "usb-nop-xceiv";
status = "okay";
};
usb0: usb@ffb00000 {
compatible = "snps,dwc2";
reg = <0xffb00000 0x40000>;
interrupts = <0 93 4>;
phys = <&usbphy0>;
phy-names = "usb2-phy";
resets = <&rst USB0_RESET>, <&rst USB0_OCP_RESET>;
reset-names = "dwc2", "dwc2-ecc";
clocks = <&clkmgr AGILEX_USB_CLK>;
iommus = <&smmu 6>;
status = "disabled";
};
usb1: usb@ffb40000 {
compatible = "snps,dwc2";
reg = <0xffb40000 0x40000>;
interrupts = <0 94 4>;
phys = <&usbphy0>;
phy-names = "usb2-phy";
resets = <&rst USB1_RESET>, <&rst USB1_OCP_RESET>;
reset-names = "dwc2", "dwc2-ecc";
iommus = <&smmu 7>;
clocks = <&clkmgr AGILEX_USB_CLK>;
status = "disabled";
};
watchdog0: watchdog@ffd00200 {
compatible = "snps,dw-wdt";
reg = <0xffd00200 0x100>;
interrupts = <0 117 4>;
resets = <&rst WATCHDOG0_RESET>;
clocks = <&clkmgr AGILEX_L4_SYS_FREE_CLK>;
status = "disabled";
};
watchdog1: watchdog@ffd00300 {
compatible = "snps,dw-wdt";
reg = <0xffd00300 0x100>;
interrupts = <0 118 4>;
resets = <&rst WATCHDOG1_RESET>;
clocks = <&clkmgr AGILEX_L4_SYS_FREE_CLK>;
status = "disabled";
};
watchdog2: watchdog@ffd00400 {
compatible = "snps,dw-wdt";
reg = <0xffd00400 0x100>;
interrupts = <0 125 4>;
resets = <&rst WATCHDOG2_RESET>;
clocks = <&clkmgr AGILEX_L4_SYS_FREE_CLK>;
status = "disabled";
};
watchdog3: watchdog@ffd00500 {
compatible = "snps,dw-wdt";
reg = <0xffd00500 0x100>;
interrupts = <0 126 4>;
resets = <&rst WATCHDOG3_RESET>;
clocks = <&clkmgr AGILEX_L4_SYS_FREE_CLK>;
status = "disabled";
};
sdr: sdr@f8011100 {
compatible = "altr,sdr-ctl", "syscon";
reg = <0xf8011100 0xc0>;
};
eccmgr {
compatible = "altr,socfpga-s10-ecc-manager",
"altr,socfpga-a10-ecc-manager";
altr,sysmgr-syscon = <&sysmgr>;
#address-cells = <1>;
#size-cells = <1>;
interrupts = <0 15 4>;
interrupt-controller;
#interrupt-cells = <2>;
ranges;
sdramedac {
compatible = "altr,sdram-edac-s10";
altr,sdr-syscon = <&sdr>;
interrupts = <16 4>;
};
ocram-ecc@ff8cc000 {
compatible = "altr,socfpga-s10-ocram-ecc",
"altr,socfpga-a10-ocram-ecc";
reg = <0xff8cc000 0x100>;
altr,ecc-parent = <&ocram>;
interrupts = <1 4>;
};
usb0-ecc@ff8c4000 {
compatible = "altr,socfpga-s10-usb-ecc",
"altr,socfpga-usb-ecc";
reg = <0xff8c4000 0x100>;
altr,ecc-parent = <&usb0>;
interrupts = <2 4>;
};
emac0-rx-ecc@ff8c0000 {
compatible = "altr,socfpga-s10-eth-mac-ecc",
"altr,socfpga-eth-mac-ecc";
reg = <0xff8c0000 0x100>;
altr,ecc-parent = <&gmac0>;
interrupts = <4 4>;
};
emac0-tx-ecc@ff8c0400 {
compatible = "altr,socfpga-s10-eth-mac-ecc",
"altr,socfpga-eth-mac-ecc";
reg = <0xff8c0400 0x100>;
altr,ecc-parent = <&gmac0>;
interrupts = <5 4>;
};
sdmmca-ecc@ff8c8c00 {
compatible = "altr,socfpga-s10-sdmmc-ecc",
"altr,socfpga-sdmmc-ecc";
reg = <0xff8c8c00 0x100>;
altr,ecc-parent = <&mmc>;
interrupts = <14 4>,
<15 4>;
};
};
qspi: spi@ff8d2000 {
compatible = "cdns,qspi-nor";
#address-cells = <1>;
#size-cells = <0>;
reg = <0xff8d2000 0x100>,
<0xff900000 0x100000>;
interrupts = <0 3 4>;
cdns,fifo-depth = <128>;
cdns,fifo-width = <4>;
cdns,trigger-address = <0x00000000>;
clocks = <&qspi_clk>;
status = "disabled";
};
firmware {
svc {
compatible = "intel,stratix10-svc";
method = "smc";
memory-region = <&service_reserved>;
fpga_mgr: fpga-mgr {
compatible = "intel,stratix10-soc-fpga-mgr";
};
};
};
};
};

View File

@@ -596,4 +596,8 @@
};
};
};
aliases {
sysmgr = &sysmgr;
};
};

View File

@@ -3,41 +3,139 @@
* U-Boot additions
*
* Copyright (C) 2019-2022 Intel Corporation <www.intel.com>
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include "socfpga_agilex-u-boot.dtsi"
#ifdef CONFIG_TARGET_SOCFPGA_AGILEX
/{
aliases {
spi0 = &qspi;
i2c0 = &i2c1;
freeze_br0 = &freeze_controller;
chosen {
stdout-path = "serial0:115200n8";
u-boot,spl-boot-order = &mmc,&flash0,&nand;
};
soc {
freeze_controller: freeze_controller@f9000450 {
compatible = "altr,freeze-bridge-controller";
reg = <0xf9000450 0x00000010>;
status = "disabled";
};
};
memory {
memory@0 {
/* 8GB */
reg = <0 0x00000000 0 0x80000000>,
<2 0x80000000 1 0x80000000>;
};
};
&flash0 {
compatible = "jedec,spi-nor";
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
bootph-all;
&qspi {
status = "okay";
};
#endif
#ifdef CONFIG_TARGET_SOCFPGA_AGILEX7M
/{
model = "SoCFPGA Agilex7-M SoCDK";
chosen {
stdout-path = "serial0:115200n8";
u-boot,spl-boot-order = &mmc;
};
memory@0 {
/*
* When LPDDR ECC is enabled, the last 1/8 of the memory region must
* be reserved for the Inline ECC buffer.
*
* Example for memory size with 2GB:
* memory {
* reg = <0x0 0x00000000 0x0 0x80000000>;
* };
*
* Example for memory size with 8GB:
* memory {
* reg = <0x0 0x00000000 0x0 0x80000000>,
* <0x1 0x00000000 0x1 0x80000000>;
* };
*
*
* Example for memory size with 2GB with LPDDR Inline ECC ON:
* memory {
* reg = <0x0 0x00000000 0x0 0x70000000>;
* };
*
* Example for memory size with 8GB with LPDDR Inline ECC ON:
* memory {
* reg = <0x0 0x00000000 0x0 0x80000000>,
* <0x1 0x00000000 0x1 0x40000000>;
* };
*/
/* Default memory size is 2GB */
reg = <0x0 0x00000000 0x0 0x80000000>;
};
};
&i2c1 {
&gmac2 {
status = "okay";
phy-mode = "rgmii";
phy-handle = <&phy0>;
max-frame-size = <3800>;
mdio2 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy2: ethernet-phy@2 {
reg = <4>;
txd0-skew-ps = <0>; /* -420ps */
txd1-skew-ps = <0>; /* -420ps */
txd2-skew-ps = <0>; /* -420ps */
txd3-skew-ps = <0>; /* -420ps */
rxd0-skew-ps = <420>; /* 0ps */
rxd1-skew-ps = <420>; /* 0ps */
rxd2-skew-ps = <420>; /* 0ps */
rxd3-skew-ps = <420>; /* 0ps */
txen-skew-ps = <0>; /* -420ps */
txc-skew-ps = <1860>; /* 960ps */
rxdv-skew-ps = <420>; /* 0ps */
rxc-skew-ps = <1680>; /* 780ps */
};
};
};
&qspi {
status = "disabled";
};
&socfpga_l3interconnect_firewall {
soc_noc_fw_mpfe_csr_inst_0_mpfe_scr@f8020000 {
intel,offset-settings =
/* Disable MPFE firewall for SMMU */
<0x00000000 0x00010101 0x00010101>;
};
};
#endif
&gmac0 {
mdio0 {
ethernet_phy0: ethernet-phy@0 {
reg = <4>;
txd0-skew-ps = <0>;
txd1-skew-ps = <0>;
txd2-skew-ps = <0>;
txd3-skew-ps = <0>;
rxd0-skew-ps = <0x1a4>;
rxd1-skew-ps = <0x1a4>;
rxd2-skew-ps = <0x1a4>;
rxd3-skew-ps = <0x1a4>;
txen-skew-ps = <0>;
txc-skew-ps = <0x384>;
rxdv-skew-ps = <0x1a4>;
rxc-skew-ps = <0x690>;
};
};
};
&nand {
status = "okay";
nand-bus-width = <16>;
bootph-all;
};
&mmc {
@@ -47,9 +145,39 @@
};
&qspi {
status = "okay";
/delete-property/ clocks;
};
&watchdog0 {
&flash0 {
reg = <0>;
spi-tx-bus-width = <4>;
spi-rx-bus-width = <4>;
spi-max-frequency = <100000000>;
bootph-all;
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>;
/delete-property/ cdns,read-delay;
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>;
};
};
};

View File

@@ -1,141 +0,0 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019, Intel Corporation
*/
#include "socfpga_agilex.dtsi"
/ {
model = "SoCFPGA Agilex SoCDK";
aliases {
serial0 = &uart0;
ethernet0 = &gmac0;
ethernet1 = &gmac1;
ethernet2 = &gmac2;
};
chosen {
stdout-path = "serial0:115200n8";
};
leds {
compatible = "gpio-leds";
hps0 {
label = "hps_led0";
gpios = <&portb 20 GPIO_ACTIVE_HIGH>;
};
hps1 {
label = "hps_led1";
gpios = <&portb 19 GPIO_ACTIVE_HIGH>;
};
hps2 {
label = "hps_led2";
gpios = <&portb 21 GPIO_ACTIVE_HIGH>;
};
};
memory {
device_type = "memory";
/* We expect the bootloader to fill in the reg */
reg = <0 0 0 0>;
};
soc {
clocks {
osc1 {
clock-frequency = <25000000>;
};
};
};
};
&gpio1 {
status = "okay";
};
&gmac0 {
status = "okay";
phy-mode = "rgmii";
phy-handle = <&phy0>;
max-frame-size = <9000>;
mdio0 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "snps,dwmac-mdio";
phy0: ethernet-phy@0 {
reg = <4>;
txd0-skew-ps = <0>; /* -420ps */
txd1-skew-ps = <0>; /* -420ps */
txd2-skew-ps = <0>; /* -420ps */
txd3-skew-ps = <0>; /* -420ps */
rxd0-skew-ps = <420>; /* 0ps */
rxd1-skew-ps = <420>; /* 0ps */
rxd2-skew-ps = <420>; /* 0ps */
rxd3-skew-ps = <420>; /* 0ps */
txen-skew-ps = <0>; /* -420ps */
txc-skew-ps = <900>; /* 0ps */
rxdv-skew-ps = <420>; /* 0ps */
rxc-skew-ps = <1680>; /* 780ps */
};
};
};
&mmc {
status = "okay";
cap-sd-highspeed;
broken-cd;
bus-width = <4>;
};
&uart0 {
status = "okay";
};
&usb0 {
status = "okay";
disable-over-current;
};
&watchdog0 {
status = "okay";
};
&qspi {
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 = "Boot and fpga data";
reg = <0x0 0x034B0000>;
};
qspi_rootfs: partition@34B0000 {
label = "Root Filesystem - JFFS2";
reg = <0x034B0000 0x0EB50000>;
};
};
};
};

View File

@@ -0,0 +1,163 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* U-Boot additions
*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
/ {
soc@0 {
socfpga-system-mgr-firewall {
compatible = "intel,socfpga-dtreg";
#address-cells = <1>;
#size-cells = <1>;
bootph-all;
i_sys_mgr_core@ffd12000 {
reg = <0xffd12000 0x00000230>;
intel,offset-settings =
/* Enable non-secure interface to DMA */
<0x00000020 0xff010000 0xff010011>,
/* Enable non-secure interface to DMA periph */
<0x00000024 0xffffffff 0xffffffff>;
bootph-all;
};
};
socfpga_l3interconnect_firewall:socfpga-l3interconnect-firewall {
compatible = "intel,socfpga-dtreg";
#address-cells = <1>;
#size-cells = <1>;
bootph-all;
noc_fw_l4_per_l4_per_scr@ffd21000 {
reg = <0xffd21000 0x00000074>;
intel,offset-settings =
/* Disable L4 periphs firewall */
<0x00000000 0x01010001 0x01010001>,
<0x00000004 0x01010001 0x01010001>,
<0x0000000c 0x01010001 0x01010001>,
<0x00000010 0x01010001 0x01010001>,
<0x0000001c 0x01010001 0x01010101>,
<0x00000020 0x01010001 0x01010101>,
<0x00000024 0x01010001 0x01010101>,
<0x00000028 0x01010001 0x01010101>,
<0x0000002c 0x01010001 0x01010001>,
<0x00000030 0x01010001 0x01010001>,
<0x00000034 0x01010001 0x01010001>,
<0x00000040 0x01010001 0x01010001>,
<0x00000044 0x01010001 0x01010101>,
<0x00000048 0x01010001 0x01010101>,
<0x00000050 0x01010001 0x01010101>,
<0x00000054 0x01010001 0x01010101>,
<0x00000058 0x01010001 0x01010101>,
<0x0000005c 0x01010001 0x01010101>,
<0x00000060 0x01010001 0x01010101>,
<0x00000064 0x01010001 0x01010101>,
<0x00000068 0x01010001 0x01010101>,
<0x0000006c 0x01010001 0x01010101>,
<0x00000070 0x01010001 0x01010101>;
bootph-all;
};
noc_fw_l4_sys_l4_sys_scr@ffd21100 {
reg = <0xffd21100 0x00000098>;
intel,offset-settings =
/* Disable L4 system firewall */
<0x00000008 0x01010001 0x01010001>,
<0x0000000c 0x01010001 0x01010001>,
<0x00000010 0x01010001 0x01010001>,
<0x00000014 0x01010001 0x01010001>,
<0x00000018 0x01010001 0x01010001>,
<0x0000001c 0x01010001 0x01010001>,
<0x00000020 0x01010001 0x01010001>,
<0x0000002c 0x01010001 0x01010001>,
<0x00000030 0x01010001 0x01010001>,
<0x00000034 0x01010001 0x01010001>,
<0x00000038 0x01010001 0x01010001>,
<0x00000040 0x01010001 0x01010001>,
<0x00000044 0x01010001 0x01010001>,
<0x00000048 0x01010001 0x01010001>,
<0x0000004c 0x01010001 0x01010001>,
<0x00000054 0x01010001 0x01010001>,
<0x00000058 0x01010001 0x01010001>,
<0x0000005c 0x01010001 0x01010001>,
<0x00000060 0x01010001 0x01010101>,
<0x00000064 0x01010001 0x01010101>,
<0x00000068 0x01010001 0x01010101>,
<0x0000006c 0x01010001 0x01010101>,
<0x00000070 0x01010001 0x01010101>,
<0x00000074 0x01010001 0x01010101>,
<0x00000078 0x01010001 0x03010001>,
<0x00000090 0x01010001 0x01010001>,
<0x00000094 0x01010001 0x01010001>;
bootph-all;
};
noc_fw_soc2fpga_soc2fpga_scr@ffd21200 {
reg = <0xffd21200 0x00000004>;
/* Disable soc2fpga security access */
intel,offset-settings = <0x00000000 0x0ffe0101 0x0ffe0101>;
bootph-all;
};
noc_fw_lwsoc2fpga_lwsoc2fpga_scr@ffd21300 {
reg = <0xffd21300 0x00000004>;
/* Disable lightweight soc2fpga security access */
intel,offset-settings = <0x00000000 0x0ffe0101 0x0ffe0101>;
bootph-all;
};
noc_fw_tcu_tcu_scr@ffd21400 {
reg = <0xffd21400 0x00000004>;
/* Disable DMA ECC security access, for SMMU use */
intel,offset-settings = <0x00000000 0x01010001 0x01010001>;
bootph-all;
};
noc_fw_priv_MemoryMap_priv@ffd24800 {
reg = <0xffd24800 0x0000000c>;
intel,offset-settings =
/* Enable non-prviledged access to various periphs */
<0x00000000 0xfff73ffb 0xfff73ffb>;
bootph-all;
};
};
socfpga_smmu_secure_config: socfpga-smmu-secure-config {
compatible = "intel,socfpga-dtreg";
#address-cells = <1>;
#size-cells = <1>;
bootph-all;
/* TCU */
noc_fw_tcu_tcu_scr@ffd21400 {
reg = <0xffd21400 0x00000004>;
intel,offset-settings =
<0x00000000 0x01010001 0x01010001>;
bootph-all;
};
/* System manager */
i_sys_mgt_sysmgr_csr@ffd12000 {
reg = <0xffd12000 0x00000500>;
intel,offset-settings =
/* i_sys_mgr_core_emac0 */
<0x00000044 0x0a000000 0xffff0103>,
/* i_sys_mgr_core_emac1 */
<0x00000048 0x0a000000 0xffff0103>,
/* i_sys_mgr_core_emac2 */
<0x0000004c 0x0a000000 0xffff0103>,
/* i_sys_mgr_core_nand_l3master */
<0x00000034 0x00220000 0x007733ff>,
/* i_sys_mgr_core_sdmmc_l3master */
<0x0000002c 0x00000020 0x03ff03ff>,
/* i_sys_mgr_core_usb0_l3master */
<0x00000038 0x00000200 0x03ff30ff>,
/* i_sys_mgr_core_usb1_l3master */
<0x0000003c 0x00000200 0x03ff30ff>;
bootph-all;
};
};
};
};

View File

@@ -60,6 +60,18 @@ config TARGET_SOCFPGA_AGILEX
select SPL_CLK if SPL
select TARGET_SOCFPGA_SOC64
config TARGET_SOCFPGA_AGILEX7M
bool
select ARMV8_MULTIENTRY
select ARMV8_SET_SMPEN
select BINMAN if SPL_ATF
select CLK
select FPGA_INTEL_SDM_MAILBOX
select GICV2
select NCORE_CACHE
select SPL_CLK if SPL
select TARGET_SOCFPGA_SOC64
config TARGET_SOCFPGA_AGILEX5
bool
select BINMAN if SPL_ATF
@@ -149,6 +161,10 @@ config TARGET_SOCFPGA_AGILEX_SOCDK
bool "Intel SOCFPGA SoCDK (Agilex)"
select TARGET_SOCFPGA_AGILEX
config TARGET_SOCFPGA_AGILEX7M_SOCDK
bool "Intel SOCFPGA SoCDK (Agilex7 M-series)"
select TARGET_SOCFPGA_AGILEX7M
config TARGET_SOCFPGA_AGILEX5_SOCDK
bool "Intel SOCFPGA SoCDK (Agilex5)"
select TARGET_SOCFPGA_AGILEX5
@@ -226,6 +242,7 @@ config TARGET_SOCFPGA_TERASIC_SOCKIT
endchoice
config SYS_BOARD
default "agilex7m-socdk" if TARGET_SOCFPGA_AGILEX7M_SOCDK
default "agilex5-socdk" if TARGET_SOCFPGA_AGILEX5_SOCDK
default "agilex-socdk" if TARGET_SOCFPGA_AGILEX_SOCDK
default "arria5-socdk" if TARGET_SOCFPGA_ARRIA5_SOCDK
@@ -248,6 +265,7 @@ config SYS_BOARD
default "vining_fpga" if TARGET_SOCFPGA_SOFTING_VINING_FPGA
config SYS_VENDOR
default "intel" if TARGET_SOCFPGA_AGILEX7M_SOCDK
default "intel" if TARGET_SOCFPGA_AGILEX5_SOCDK
default "intel" if TARGET_SOCFPGA_AGILEX_SOCDK
default "intel" if TARGET_SOCFPGA_N5X_SOCDK
@@ -271,6 +289,7 @@ config SYS_SOC
default "socfpga"
config SYS_CONFIG_NAME
default "socfpga_agilex7m_socdk" if TARGET_SOCFPGA_AGILEX7M_SOCDK
default "socfpga_agilex5_socdk" if TARGET_SOCFPGA_AGILEX5_SOCDK
default "socfpga_agilex_socdk" if TARGET_SOCFPGA_AGILEX_SOCDK
default "socfpga_arria5_secu1" if TARGET_SOCFPGA_ARRIA5_SECU1

View File

@@ -54,6 +54,7 @@ obj-y += timer_s10.o
obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += vab.o
obj-y += wrap_handoff_soc64.o
obj-y += wrap_pll_config_soc64.o
obj-y += altera-sysmgr.o
endif
ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
@@ -72,6 +73,22 @@ obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += secure_vab.o
obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += vab.o
endif
ifdef CONFIG_TARGET_SOCFPGA_AGILEX7M
obj-y += clock_manager_agilex.o
obj-y += lowlevel_init_soc64.o
obj-y += mailbox_s10.o
obj-y += misc_soc64.o
obj-y += mmu-arm64_s10.o
obj-y += reset_manager_s10.o
obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += secure_vab.o
obj-y += system_manager_soc64.o
obj-y += timer_s10.o
obj-$(CONFIG_SOCFPGA_SECURE_VAB_AUTH) += vab.o
obj-y += wrap_handoff_soc64.o
obj-y += wrap_pll_config_soc64.o
obj-y += altera-sysmgr.o
endif
ifdef CONFIG_TARGET_SOCFPGA_N5X
obj-y += clock_manager_n5x.o
obj-y += lowlevel_init_soc64.o
@@ -115,6 +132,9 @@ ifdef CONFIG_TARGET_SOCFPGA_AGILEX5
obj-y += spl_soc64.o
obj-y += spl_agilex5.o
endif
ifdef CONFIG_TARGET_SOCFPGA_AGILEX7M
obj-y += spl_agilex7m.o
endif
else
obj-$(CONFIG_SPL_ATF) += secure_reg_helper.o
obj-$(CONFIG_SPL_ATF) += smc_api.o

View File

@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2016-2024 Intel Corporation <www.intel.com>
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#ifndef _SOCFPGA_SOC64_BASE_HARDWARE_H_
@@ -45,8 +46,10 @@
#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
#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) || \
IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X) || \
IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
#define SOCFPGA_FW_MPU_DDR_SCR_ADDRESS 0xf8020200
#else
#define SOCFPGA_FW_MPU_DDR_SCR_ADDRESS 0xf8020100
@@ -75,6 +78,7 @@
#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

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2013-2024 Altera Corporation <www.altera.com>
* Copyright (C) 2013-2025 Altera Corporation <www.altera.com>
*/
#ifndef _CLOCK_MANAGER_H_
@@ -28,7 +28,7 @@ int cm_set_qspi_controller_clk_hz(u32 clk_hz);
#include <asm/arch/clock_manager_arria10.h>
#elif defined(CONFIG_TARGET_SOCFPGA_STRATIX10)
#include <asm/arch/clock_manager_s10.h>
#elif defined(CONFIG_TARGET_SOCFPGA_AGILEX)
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) || IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
#include <asm/arch/clock_manager_agilex.h>
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
#include <asm/arch/clock_manager_agilex5.h>

View File

@@ -18,7 +18,7 @@
#define SOC64_HANDOFF_MAGIC_FPGA 0x46504741
#define SOC64_HANDOFF_MAGIC_DELAY 0x444C4159
#define SOC64_HANDOFF_MAGIC_CLOCK 0x434C4B53
#define SOC64_HANDOFF_MAGIC_SDRAM 0x5344524d
#define SOC64_HANDOFF_MAGIC_SDRAM 0x5344524D
#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
#define SOC64_HANDOFF_MAGIC_PERI 0x50455249
#else
@@ -30,9 +30,19 @@
#define SOC64_HANDOFF_SIZE 4096
#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_STRATIX10) || \
IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX)
IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) || \
IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
#define SOC64_HANDOFF_BASE 0xFFE3F000
#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
#define SOC64_HANDOFF_MISC (SOC64_HANDOFF_BASE + 0x634)
/* DDR handoff */
#define SOC64_HANDOFF_DDR_BASE (SOC64_HANDOFF_BASE + 0x610)
#define SOC64_HANDOFF_DDR_LEN 5
#define SOC64_HANDOFF_DDR_INTERLEAVING_MODE_MASK BIT(0)
#define SOC64_HANDOFF_DDR_MEMORY_TYPE_MASK BIT(0)
#else
#define SOC64_HANDOFF_MISC (SOC64_HANDOFF_BASE + 0x610)
#endif
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
#define SOC64_HANDOFF_BASE 0x0007F000
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)

View File

@@ -41,7 +41,8 @@ void socfpga_sdram_remap_zero(void);
#endif
#if defined(CONFIG_TARGET_SOCFPGA_STRATIX10) || \
defined(CONFIG_TARGET_SOCFPGA_AGILEX)
defined(CONFIG_TARGET_SOCFPGA_AGILEX) || \
defined(CONFIG_TARGET_SOCFPGA_AGILEX7M)
int is_fpga_config_ready(void);
#endif
@@ -52,7 +53,7 @@ bool is_periph_program_force(void);
void set_regular_boot(unsigned int status);
void socfpga_pl310_clear(void);
void socfpga_get_managers_addr(void);
void socfpga_get_sys_mgr_addr(const char *compat);
void socfpga_get_sys_mgr_addr(void);
int qspi_flash_software_reset(void);
#endif /* _SOCFPGA_MISC_H_ */

View File

@@ -141,6 +141,27 @@ void populate_sysmgr_pinmux(void);
#define ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK (BIT(29) | BIT(28))
#define ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_SHIFT 28
/*
* 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 ALT_SYSMGR_SCRATCH_REG_8_OCRAM_DBE_MASK BIT(29)
#define ALT_SYSMGR_SCRATCH_REG_8_IO96B_HPS_MASK GENMASK(28, 27)
#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)

View File

@@ -12,15 +12,110 @@
ENTRY(lowlevel_init)
mov x29, lr /* Save LR */
#ifdef CONFIG_XPL_BUILD
/* Check for L2 reset magic word */
ldr x4, =L2_RESET_DONE_REG
ldr x5, [x4]
ldr x1, =L2_RESET_DONE_STATUS
cmp x1, x5
/* No L2 reset, skip warm reset */
b.ne skipwarmreset
/* Put all slaves CPUs into WFI mode */
branch_if_slave x0, put_cpu_in_wfi
/* L2 reset completed */
str xzr, [x4]
/* Clear previous CPU release address */
ldr x4, =CPU_RELEASE_ADDR
str wzr, [x4]
/* Master CPU (CPU0) request for warm reset */
mrs x1, rmr_el3
orr x1, x1, #0x02
msr rmr_el3, x1
isb
dsb sy
put_cpu_in_wfi:
wfi
b put_cpu_in_wfi
skipwarmreset:
#endif
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
#if defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_ATF)
/*
* In ATF flow, need to clear the old CPU address when cold reset
* being triggered, but shouldn't clear CPU address if it is reset
* by CPU-ON, so that the core can correctly jump to ATF code after
* reset by CPU-ON. CPU-ON trigger the reset via mpumodrst.
*
* Hardware will set 1 to core*_irq in mpurststat register in
* reset manager if the core is reset by mpumodrst.
*
* The following code will check the mpurststat to identify if the
* core is reset by mpumodrst, and it will skip CPU address clearing
* if the core is reset by mpumodrst. At last, the code need to clear
* the core*_irq by set it to 1. So that it can reflect the correct
* and latest status in next reset.
*/
/* Check if it is a master core off/on from kernel using boot scratch
* cold register 8 bit 19. This bit is set by ATF.
*/
ldr x4, =BOOT_SCRATCH_COLD8
ldr x5, [x4]
and x6, x5, #0x80000
cbnz x6, wait_for_atf_master
/* Retrieve mpurststat register in reset manager */
ldr x4, =SOCFPGA_RSTMGR_ADDRESS
ldr w5, [x4, #0x04]
/* Set mask based on current core id */
mrs x0, mpidr_el1
and x1, x0, #0xF
ldr x2, =0x00000100
lsl x2, x2, x1
/* Skip if core*_irq register is set */
and x6, x5, x2
cbnz x6, skip_clear_cpu_address
/*
* Reach here means core*_irq is 0, means the core is
* reset by cold, warm or watchdog reset.
* Clear previous CPU release address
*/
ldr x4, =CPU_RELEASE_ADDR
str wzr, [x4]
b skip_clear_core_irq
skip_clear_cpu_address:
/* Clear core*_irq register by writing 1 */
ldr x4, =SOCFPGA_RSTMGR_ADDRESS
str w2, [x4, #0x04]
skip_clear_core_irq:
/* Master CPU (CPU0) does not need to wait for atf */
branch_if_master x0, master_cpu
wait_for_atf:
ldr x4, =CPU_RELEASE_ADDR
ldr x5, [x4]
cbz x5, slave_wait_atf
br x5
slave_wait_atf:
branch_if_slave x0, wait_for_atf
wait_for_atf_master:
ldr x4, =CPU_RELEASE_ADDR
ldr x5, [x4]
cbz x5, master_wait_atf
br x5
master_wait_atf:
branch_if_master x0, wait_for_atf_master
master_cpu:
#else
branch_if_slave x0, 1f
#endif

View File

@@ -11,6 +11,7 @@
#include <hang.h>
#include <watchdog.h>
#include <fdtdec.h>
#include <dm/ofnode.h>
#include <linux/libfdt.h>
#include <linux/printk.h>
#include <miiphy.h>
@@ -222,8 +223,8 @@ static int do_bridge(struct cmd_tbl *cmdtp, int flag, int argc,
U_BOOT_CMD(bridge, 3, 1, do_bridge,
"SoCFPGA HPS FPGA bridge control",
"enable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
"bridge disable [mask] - Enable HPS-to-FPGA, FPGA-to-HPS, LWHPS-to-FPGA bridges\n"
"enable [mask] - Enable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2) bridges\n"
"bridge disable [mask] - Disable HPS-to-FPGA (Bit 0), LWHPS-to-FPGA (Bit 1), FPGA-to-HPS (Bit 2) bridges\n"
""
);
@@ -260,13 +261,12 @@ void socfpga_get_managers_addr(void)
if (ret)
hang();
if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX))
ret = socfpga_get_base_addr("intel,agilex-clkmgr",
&socfpga_clkmgr_base);
else if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X))
ret = socfpga_get_base_addr("intel,n5x-clkmgr",
&socfpga_clkmgr_base);
else if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5))
else if (!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX) &&
!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M) &&
!IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5))
ret = socfpga_get_base_addr("altr,clk-mgr",
&socfpga_clkmgr_base);
@@ -274,17 +274,24 @@ void socfpga_get_managers_addr(void)
hang();
}
void socfpga_get_sys_mgr_addr(const char *compat)
void socfpga_get_sys_mgr_addr(void)
{
int ret;
struct udevice *sysmgr_dev;
struct udevice *dev;
ret = uclass_get_device_by_name(UCLASS_NOP, compat, &sysmgr_dev);
ofnode node = ofnode_get_aliases_node("sysmgr");
if (!ofnode_valid(node)) {
printf("'sysmgr' alias not found in device tree\n");
hang();
}
ret = uclass_get_device_by_ofnode(UCLASS_NOP, node, &dev);
if (ret) {
printf("Altera system manager init failed: %d\n", ret);
hang();
} else {
socfpga_sysmgr_base = (phys_addr_t)dev_read_addr(sysmgr_dev);
socfpga_sysmgr_base = (phys_addr_t)dev_read_addr(dev);
}
}

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*
*/
@@ -18,20 +19,42 @@
#include <asm/arch/misc.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/system_manager.h>
#include <watchdog.h>
#include <wdt.h>
#include <dm/uclass.h>
DECLARE_GLOBAL_DATA_PTR;
u32 reset_flag(void)
{
/* Check rstmgr.stat for warm reset status */
u32 status = readl(SOCFPGA_RSTMGR_ADDRESS);
/* Check whether any L4 watchdogs or SDM had triggered warm reset */
u32 warm_reset_mask = RSTMGR_L4WD_MPU_WARMRESET_MASK;
if (status & warm_reset_mask)
return 0;
return 1;
}
void board_init_f(ulong dummy)
{
int ret;
struct udevice *dev;
/* Enable Async */
asm volatile("msr daifclr, #4");
#if defined(CONFIG_XPL_BUILD) && defined(CONFIG_SPL_RECOVER_DATA_SECTION)
spl_save_restore_data();
#endif
ret = spl_early_init();
if (ret)
hang();
socfpga_get_sys_mgr_addr();
socfpga_get_managers_addr();
/* Ensure watchdog is paused when debugging is happening */
@@ -62,11 +85,30 @@ void board_init_f(ulong dummy)
hang();
}
/*
* Enable watchdog as early as possible before initializing other
* component. Watchdog need to be enabled after clock driver because
* it will retrieve the clock frequency from clock driver.
*/
if (CONFIG_IS_ENABLED(WDT))
initr_watchdog();
preloader_console_init();
print_reset_info();
cm_print_clock_quick_summary();
firewall_setup();
ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-system-mgr-firewall", &dev);
if (ret) {
printf("System manager firewall configuration failed: %d\n", ret);
hang();
}
ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-l3interconnect-firewall", &dev);
if (ret) {
printf("L3 interconnect firewall configuration failed: %d\n", ret);
hang();
}
ret = uclass_get_device(UCLASS_CACHE, 0, &dev);
if (ret) {
debug("CCU init failed: %d\n", ret);

View File

@@ -51,7 +51,7 @@ void board_init_f(ulong dummy)
if (ret)
hang();
socfpga_get_sys_mgr_addr("sysmgr@10d12000");
socfpga_get_sys_mgr_addr();
socfpga_get_managers_addr();
sysmgr_pinmux_init();

View File

@@ -0,0 +1,106 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <hang.h>
#include <image.h>
#include <init.h>
#include <log.h>
#include <spl.h>
#include <wdt.h>
#include <asm/arch/clock_manager.h>
#include <asm/arch/firewall.h>
#include <asm/arch/mailbox_s10.h>
#include <asm/arch/misc.h>
#include <asm/arch/reset_manager.h>
#include <asm/arch/system_manager.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/u-boot.h>
#include <asm/utils.h>
#include <dm/uclass.h>
DECLARE_GLOBAL_DATA_PTR;
void board_init_f(ulong dummy)
{
int ret;
struct udevice *dev;
/* Enable Async */
asm volatile("msr daifclr, #4");
#ifdef CONFIG_XPL_BUILD
spl_save_restore_data();
#endif
ret = spl_early_init();
if (ret)
hang();
socfpga_get_sys_mgr_addr();
socfpga_get_managers_addr();
/* Ensure watchdog is paused when debugging is happening */
writel(SYSMGR_WDDBG_PAUSE_ALL_CPU,
socfpga_get_sysmgr_addr() + SYSMGR_SOC64_WDDBG);
/* ensure all processors are not released prior Linux boot */
writeq(0, CPU_RELEASE_ADDR);
timer_init();
mbox_init();
mbox_hps_stage_notify(HPS_EXECUTION_STATE_FSBL);
sysmgr_pinmux_init();
ret = uclass_get_device(UCLASS_CLK, 0, &dev);
if (ret) {
debug("Clock init failed: %d\n", ret);
hang();
}
/*
* Enable watchdog as early as possible before initializing other
* component. Watchdog need to be enabled after clock driver because
* it will retrieve the clock frequency from clock driver.
*/
if (CONFIG_IS_ENABLED(WDT))
initr_watchdog();
preloader_console_init();
print_reset_info();
cm_print_clock_quick_summary();
ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-system-mgr-firewall", &dev);
if (ret) {
printf("System manager firewall configuration failed: %d\n", ret);
hang();
}
ret = uclass_get_device_by_name(UCLASS_NOP, "socfpga-l3interconnect-firewall", &dev);
if (ret) {
printf("L3 interconnect firewall configuration failed: %d\n", ret);
hang();
}
ret = uclass_get_device(UCLASS_CACHE, 0, &dev);
if (ret) {
debug("CCU init failed: %d\n", ret);
hang();
}
if (IS_ENABLED(CONFIG_SPL_ALTERA_SDRAM)) {
ret = uclass_get_device(UCLASS_RAM, 0, &dev);
if (ret) {
debug("DRAM init failed: %d\n", ret);
hang();
}
}
if (IS_ENABLED(CONFIG_CADENCE_QSPI))
mbox_qspi_open();
}

View File

@@ -0,0 +1,7 @@
#
# Copyright (C) 2025 Altera Corporation <www.altera.com>
#
# SPDX-License-Identifier: GPL-2.0
#
obj-y := socfpga.o

View File

@@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <asm/arch/misc.h>
int board_early_init_f(void)
{
socfpga_get_sys_mgr_addr();
return 0;
}

View File

@@ -7,6 +7,6 @@
int board_early_init_f(void)
{
socfpga_get_sys_mgr_addr("sysmgr@10d12000");
socfpga_get_sys_mgr_addr();
return 0;
}

View File

@@ -0,0 +1,10 @@
SOCFPGA BOARD
M: Tien Fong Chee <tien.fong.chee@altera.com>
M: Alif Zakuan Yuslaimi <alif.zakuan.yuslaimi@altera.com>
S: Maintained
F: arch/arm/dts/socfpga_soc64_u-boot.dtsi
F: arch/arm/dts/socfpga_agilex7m*
F: arch/arm/mach-socfpga/spl_agilex7m.c
F: board/intel/agilex7m-socdk/
F: include/configs/socfpga_agilex7m_socdk.h
F: configs/socfpga_agilex7m_sdmmc_defconfig

View File

@@ -0,0 +1,7 @@
#
# Copyright (C) 2025 Altera Corporation <www.altera.com>
#
# SPDX-License-Identifier: GPL-2.0
#
obj-y := socfpga.o

View File

@@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <asm/arch/misc.h>
int board_early_init_f(void)
{
socfpga_get_sys_mgr_addr();
return 0;
}

View File

@@ -0,0 +1,19 @@
#include <configs/socfpga_agilex_defconfig>
CONFIG_NR_DRAM_BANKS=1
CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
# CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK is not set
# CONFIG_IDENT_STRING is not set
CONFIG_SPL_BSS_START_ADDR=0x1ff00000
CONFIG_TARGET_SOCFPGA_AGILEX7M_SOCDK=y
CONFIG_IDENT_STRING="socfpga_agilex7m"
# CONFIG_QSPI_BOOT is not set
CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x1fa00000
CONFIG_SYS_PROMPT="SOCFPGA_AGILEX7M # "
CONFIG_MTDIDS_DEFAULT="nand0=ffb90000.nand.0"
CONFIG_MTDPARTS_DEFAULT="mtdparts=ffb90000.nand.0:2m(u-boot),-(root)"
# CONFIG_ENV_IS_IN_UBI is not set
# CONFIG_ENV_UBI_PART is not set
# CONFIG_ENV_UBI_VOLUME is not set
# CONFIG_USE_BOOTFILE is not set
# CONFIG_DESIGNWARE_SPI is not set

View File

@@ -1,93 +0,0 @@
CONFIG_ARM=y
CONFIG_COUNTER_FREQUENCY=400000000
CONFIG_ARCH_SOCFPGA=y
CONFIG_TEXT_BASE=0x200000
CONFIG_SYS_MALLOC_LEN=0x500000
CONFIG_NR_DRAM_BANKS=2
CONFIG_SPL_LDSCRIPT="arch/arm/mach-socfpga/u-boot-spl-soc64.lds"
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
CONFIG_SF_DEFAULT_MODE=0x2003
CONFIG_ENV_SIZE=0x1000
CONFIG_ENV_OFFSET=0x200
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
CONFIG_DM_RESET=y
CONFIG_SPL_STACK=0xffe3f000
CONFIG_SPL_TEXT_BASE=0xFFE00000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x3ff00000
CONFIG_SPL_BSS_MAX_SIZE=0x100000
CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x02000000
CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y
CONFIG_IDENT_STRING="socfpga_agilex"
CONFIG_SPL_FS_FAT=y
CONFIG_REMAKE_ELF=y
CONFIG_FIT=y
CONFIG_SPL_FIT_SIGNATURE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="earlycon"
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="run fatscript; run mmcfitload; run mmcfitboot"
CONFIG_SYS_PBSIZE=2082
CONFIG_SPL_MAX_SIZE=0x40000
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SPL_HAVE_INIT_STACK=y
CONFIG_SPL_SYS_MALLOC=y
CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x3fa00000
CONFIG_SPL_SYS_MALLOC_SIZE=0x500000
CONFIG_SPL_CACHE=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_SPI_U_BOOT_OFFS=0x02000000
CONFIG_SPL_ATF=y
CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
CONFIG_SPL_TARGET="spl/u-boot-spl-dtb.hex"
CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="SOCFPGA_AGILEX # "
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_USE_BOOTFILE=y
CONFIG_BOOTFILE="kernel.itb"
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_ALTERA_SDRAM=y
CONFIG_DWAPB_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_DW=y
CONFIG_SYS_MMC_MAX_BLK_COUNT=256
CONFIG_MMC_DW=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_ETH_DESIGNWARE=y
CONFIG_MII=y
CONFIG_SYS_NS16550_MEM32=y
CONFIG_SPI=y
CONFIG_CADENCE_QSPI=y
CONFIG_DESIGNWARE_SPI=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_DESIGNWARE_WATCHDOG=y
CONFIG_WDT=y
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_PANIC_HANG=y
CONFIG_SPL_CRC32=y

View File

@@ -1,38 +1,38 @@
CONFIG_ARM=y
CONFIG_COUNTER_FREQUENCY=400000000
CONFIG_ARCH_SOCFPGA=y
CONFIG_TEXT_BASE=0x1000
CONFIG_SYS_MALLOC_LEN=0x500000
CONFIG_TEXT_BASE=0x200000
CONFIG_NR_DRAM_BANKS=2
CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x101000
CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x300000
CONFIG_SF_DEFAULT_MODE=0x2003
CONFIG_ENV_SIZE=0x1000
CONFIG_ENV_OFFSET=0x200
CONFIG_ENV_SIZE=0x2000
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
CONFIG_DEFAULT_DEVICE_TREE="intel/socfpga_agilex_socdk"
CONFIG_OF_UPSTREAM=y
CONFIG_DM_RESET=y
CONFIG_SPL_STACK=0xffe3f000
CONFIG_SPL_TEXT_BASE=0xFFE00000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x3ff00000
CONFIG_SPL_BSS_MAX_SIZE=0x100000
CONFIG_SYS_BOOTM_LEN=0x2000000
CONFIG_SYS_LOAD_ADDR=0x02000000
CONFIG_TARGET_SOCFPGA_AGILEX_SOCDK=y
CONFIG_IDENT_STRING="socfpga_agilex"
CONFIG_SPL_FS_FAT=y
# CONFIG_PSCI_RESET is not set
CONFIG_SYS_MEMTEST_START=0x00000000
CONFIG_SYS_MEMTEST_END=0x3fe00000
CONFIG_REMAKE_ELF=y
CONFIG_SPL_RECOVER_DATA_SECTION=y
CONFIG_FIT=y
CONFIG_SPL_FIT_SIGNATURE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x02000000
CONFIG_DISTRO_DEFAULTS=y
CONFIG_QSPI_BOOT=y
CONFIG_BOOTDELAY=5
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="earlycon"
CONFIG_USE_BOOTCOMMAND=y
CONFIG_BOOTCOMMAND="run fatscript; run mmcload; run linux_qspi_enable; run mmcboot"
CONFIG_SYS_PBSIZE=2082
CONFIG_BOOTARGS="earlycon panic=-1"
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SPL_MAX_SIZE=0x40000
# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SPL_HAVE_INIT_STACK=y
CONFIG_SPL_SYS_MALLOC=y
@@ -40,38 +40,49 @@ CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x3fa00000
CONFIG_SPL_SYS_MALLOC_SIZE=0x500000
CONFIG_SPL_CACHE=y
CONFIG_SPL_MTD=y
CONFIG_SPL_SPI_FLASH_MTD=y
CONFIG_SPL_SPI_LOAD=y
CONFIG_SYS_SPI_U_BOOT_OFFS=0x3c00000
CONFIG_SPL_TARGET="spl/u-boot-spl-dtb.hex"
CONFIG_HUSH_PARSER=y
CONFIG_SYS_SPI_U_BOOT_OFFS=0x04000000
CONFIG_SPL_ATF=y
CONFIG_SPL_ATF_NO_PLATFORM_PARAM=y
CONFIG_SYS_PROMPT="SOCFPGA_AGILEX # "
CONFIG_CMD_NVEDIT_SELECT=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_MMC=y
CONFIG_CMD_MTD=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
CONFIG_CMD_PING=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EXT4=y
CONFIG_CMD_FAT=y
CONFIG_CMD_FS_GENERIC=y
# CONFIG_CMD_MTDPARTS is not set
CONFIG_ENV_IS_IN_MMC=y
CONFIG_CMD_SMC=y
CONFIG_CMD_UBI=y
# CONFIG_ISO_PARTITION is not set
# CONFIG_EFI_PARTITION is not set
CONFIG_OF_LIST=""
CONFIG_ENV_IS_IN_FAT=y
CONFIG_ENV_IS_IN_UBI=y
CONFIG_ENV_FAT_DEVICE_AND_PART="0:1"
CONFIG_ENV_UBI_PART="root"
CONFIG_ENV_UBI_VOLUME="env"
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_USE_BOOTFILE=y
CONFIG_BOOTFILE="Image"
CONFIG_BOOTFILE="kernel.itb"
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SPL_ALTERA_SDRAM=y
CONFIG_DWAPB_GPIO=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_DW=y
CONFIG_MISC=y
CONFIG_SYS_MMC_MAX_BLK_COUNT=256
CONFIG_MMC_DW=y
CONFIG_DM_MTD=y
CONFIG_SPI_FLASH_SPANSION=y
CONFIG_SPI_FLASH_STMICRO=y
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
CONFIG_SPI_FLASH_MTD=y
CONFIG_PHY_MICREL=y
CONFIG_PHY_MICREL_KSZ90X1=y
CONFIG_ETH_DESIGNWARE=y
@@ -82,8 +93,9 @@ CONFIG_CADENCE_QSPI=y
CONFIG_DESIGNWARE_SPI=y
CONFIG_USB=y
CONFIG_USB_DWC2=y
CONFIG_USB_STORAGE=y
CONFIG_DESIGNWARE_WATCHDOG=y
CONFIG_WDT=y
# CONFIG_SPL_USE_TINY_PRINTF is not set
CONFIG_PANIC_HANG=y
CONFIG_SPL_CRC32=y
# CONFIG_TOOLS_MKEFICAPSULE is not set

View File

@@ -11,7 +11,8 @@ CONFIG_SF_DEFAULT_MODE=0x2003
CONFIG_ENV_SIZE=0x1000
CONFIG_ENV_OFFSET=0x200
CONFIG_DM_GPIO=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_agilex_socdk"
CONFIG_DEFAULT_DEVICE_TREE="intel/socfpga_agilex_socdk"
CONFIG_OF_UPSTREAM=y
CONFIG_DM_RESET=y
CONFIG_SPL_STACK=0xffe3f000
CONFIG_SPL_TEXT_BASE=0xFFE00000

View File

@@ -4,6 +4,7 @@
#
obj-$(CONFIG_TARGET_SOCFPGA_AGILEX) += clk-agilex.o
obj-$(CONFIG_TARGET_SOCFPGA_AGILEX7M) += clk-agilex.o
obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += clk-arria10.o
obj-$(CONFIG_TARGET_SOCFPGA_N5X) += clk-n5x.o
obj-$(CONFIG_TARGET_SOCFPGA_N5X) += clk-mem-n5x.o

View File

@@ -1,11 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <log.h>
#include <wait_bit.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/system.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/lists.h>
@@ -27,21 +30,33 @@ struct socfpga_clk_plat {
*/
static void clk_write_bypass_mainpll(struct socfpga_clk_plat *plat, u32 val)
{
void __iomem *base = plat->regs;
CM_REG_WRITEL(plat, val, CLKMGR_MAINPLL_BYPASS);
cm_wait_for_fsm();
wait_for_bit_le32(base + CLKMGR_STAT,
CLKMGR_STAT_BUSY, false, 20000, false);
}
static void clk_write_bypass_perpll(struct socfpga_clk_plat *plat, u32 val)
{
void __iomem *base = plat->regs;
CM_REG_WRITEL(plat, val, CLKMGR_PERPLL_BYPASS);
cm_wait_for_fsm();
wait_for_bit_le32(base + CLKMGR_STAT,
CLKMGR_STAT_BUSY, false, 20000, false);
}
/* 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)
{
void __iomem *base = plat->regs;
CM_REG_WRITEL(plat, val, CLKMGR_CTRL);
cm_wait_for_fsm();
wait_for_bit_le32(base + CLKMGR_STAT,
CLKMGR_STAT_BUSY, false, 20000, false);
}
#define MEMBUS_MAINPLL 0
@@ -238,6 +253,7 @@ static void clk_basic_init(struct udevice *dev,
{
struct socfpga_clk_plat *plat = dev_get_plat(dev);
u32 vcocalib;
uintptr_t base_addr = (uintptr_t)plat->regs;
if (!cfg)
return;
@@ -302,7 +318,8 @@ static void clk_basic_init(struct udevice *dev,
/* Membus programming for peripll */
membus_pll_configs(plat, MEMBUS_PERPLL);
cm_wait_for_lock(CLKMGR_STAT_ALLPLL_LOCKED_MASK);
wait_for_bit_le32((const void *)(base_addr + CLKMGR_STAT),
CLKMGR_STAT_ALLPLL_LOCKED_MASK, true, 20000, false);
/* Configure ping pong counters in altera group */
CM_REG_WRITEL(plat, cfg->alt_emacactr, CLKMGR_ALTR_EMACACTR);
@@ -337,6 +354,18 @@ static void clk_basic_init(struct udevice *dev,
CM_REG_CLRBITS(plat, CLKMGR_ALTR_EXTCNTRST,
CLKMGR_ALT_EXTCNTRST_ALLCNTRST);
#ifdef COUNTER_FREQUENCY_REAL
u32 cntfrq = COUNTER_FREQUENCY_REAL;
u32 counter_freq = 0;
/* 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));
debug("Counter freq = 0x%x\n", counter_freq);
}
#endif
/* Out of boot mode */
clk_write_ctrl(plat,
CM_REG_READL(plat, CLKMGR_CTRL) & ~CLKMGR_CTRL_BOOTMODE);

View File

@@ -10,6 +10,8 @@
#include <linux/bitops.h>
#endif
#define COUNTER_FREQUENCY_REAL 400000000
#define CM_REG_READL(plat, reg) \
readl((plat)->regs + (reg))

View File

@@ -13,4 +13,5 @@ obj-$(CONFIG_TARGET_SOCFPGA_STRATIX10) += sdram_soc64.o sdram_s10.o
obj-$(CONFIG_TARGET_SOCFPGA_AGILEX) += sdram_soc64.o sdram_agilex.o
obj-$(CONFIG_TARGET_SOCFPGA_N5X) += sdram_soc64.o sdram_n5x.o
obj-$(CONFIG_TARGET_SOCFPGA_AGILEX5) += sdram_soc64.o sdram_agilex5.o iossm_mailbox.o
obj-$(CONFIG_TARGET_SOCFPGA_AGILEX7M) += sdram_soc64.o sdram_agilex7m.o iossm_mailbox.o uibssm_mailbox.o
endif

View File

@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*
*/
@@ -72,12 +73,22 @@ int sdram_mmr_init_full(struct udevice *dev)
*/
/* Configure DDR IO size x16, x32 and x64 mode */
u32 update_value;
u32 reg;
update_value = hmc_readl(plat, NIOSRESERVED0);
update_value = (update_value & 0xFF) >> 5;
/* Configure DDR data rate 0-HAlf-rate 1-Quarter-rate */
update_value |= (hmc_readl(plat, CTRLCFG3) & 0x4);
/* Read ACF from boot_scratch_cold_8 register bit[18]*/
reg = readl(socfpga_get_sysmgr_addr() +
SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
reg = ((reg & SYSMGR_SCRATCH_REG_8_ACF_DDR_RATE_MASK)
>> SYSMGR_SCRATCH_REG_8_ACF_DDR_RATE_SHIFT);
/* bit-2 of DDRIOCTRL: Configure DDR data rate 0-Half-rate 1-Quarter-rate */
clrsetbits_le32(&update_value,
DDR_HMC_DDRIOCTRL_MPFE_HMCA_DATA_RATE_MSK,
reg << DDR_HMC_DDRIOCTRL_MPFE_HMCA_DATA_RATE_SHIFT);
hmc_ecc_writel(plat, update_value, DDRIOCTRL);
/* Copy values MMR IOHMC dramaddrw to HMC adp DRAMADDRWIDTH */
@@ -114,20 +125,6 @@ int sdram_mmr_init_full(struct udevice *dev)
printf("DDR: %lld MiB\n", gd->ram_size >> 20);
/* This enables nonsecure access to DDR */
/* mpuregion0addr_limit */
FW_MPU_DDR_SCR_WRITEL(gd->ram_size - 1,
FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT);
FW_MPU_DDR_SCR_WRITEL(0x1F, FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT);
/* nonmpuregion0addr_limit */
FW_MPU_DDR_SCR_WRITEL(gd->ram_size - 1,
FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT);
/* Enable mpuregion0enable and nonmpuregion0enable */
FW_MPU_DDR_SCR_WRITEL(MPUREGION0_ENABLE | NONMPUREGION0_ENABLE,
FW_MPU_DDR_SCR_EN_SET);
u32 ctrlcfg1 = hmc_readl(plat, CTRLCFG1);
/* Enable or disable the DDR ECC */
@@ -157,11 +154,10 @@ int sdram_mmr_init_full(struct udevice *dev)
DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));
}
/* Enable non-secure reads/writes to HMC Adapter for SDRAM ECC */
writel(FW_HMC_ADAPTOR_MPU_MASK, FW_HMC_ADAPTOR_REG_ADDR);
sdram_size_check(&bd);
sdram_set_firewall(&bd);
priv->info.base = bd.bi_dram[0].start;
priv->info.size = gd->ram_size;

View File

@@ -0,0 +1,500 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <dm.h>
#include <hang.h>
#include <log.h>
#include <ram.h>
#include <reset.h>
#include <wait_bit.h>
#include <wdt.h>
#include <asm/arch/system_manager.h>
#include <linux/bitfield.h>
#include "iossm_mailbox.h"
#include "sdram_soc64.h"
#include "uibssm_mailbox.h"
/* NOCPLL register */
#define SYSMGR_HMC_CLK 0xB4
#define SYSMGR_HMC_CLK_NOCPLL BIT(8)
/* 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 SIDEBANDMGR_FLAGOUTSET0_REG_MULTICHANNEL BIT(4)
#define SIDEBANDMGR_FLAGOUTSET0_REG_INTERLEAVING BIT(5)
/* Reset type */
enum reset_type {
POR_RESET,
WARM_RESET,
COLD_RESET,
NCONFIG,
JTAG_CONFIG,
RSU_RECONFIG
};
phys_addr_t io96b_csr_reg_addr[] = {
0xf8400000, /* IO96B_0 CSR registers address */
0xf8800000 /* IO96B_1 CSR registers address */
};
phys_addr_t uib_csr_reg_addr[] = {
0xf8400000, /* UIB_0 CSR registers address */
0xf8410000, /* UIB_1 CSR registers address */
0xf8420000, /* UIB_2 CSR registers address */
0xf8430000, /* UIB_3 CSR registers address */
0xf8440000, /* UIB_4 CSR registers address */
0xf8450000, /* UIB_5 CSR registers address */
0xf8460000, /* UIB_6 CSR registers address */
0xf8470000 /* UIB_7 CSR registers address */
};
static enum reset_type get_reset_type(u32 reg)
{
return FIELD_GET(ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_MASK, reg);
}
bool is_ddr_init_hang(void)
{
u32 reg = readl(socfpga_get_sysmgr_addr() +
SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
debug("%s: 0x%x\n", __func__, reg);
if (reg & ALT_SYSMGR_SCRATCH_REG_8_DDR_PROGRESS_MASK)
return true;
return false;
}
void ddr_init_inprogress(bool start)
{
if (start)
setbits_le32(socfpga_get_sysmgr_addr() +
SYSMGR_SOC64_BOOT_SCRATCH_COLD8,
ALT_SYSMGR_SCRATCH_REG_8_DDR_PROGRESS_MASK);
else
clrbits_le32(socfpga_get_sysmgr_addr() +
SYSMGR_SOC64_BOOT_SCRATCH_COLD8,
ALT_SYSMGR_SCRATCH_REG_8_DDR_PROGRESS_MASK);
}
static const char *memory_type_in_use(struct udevice *dev)
{
struct altera_sdram_plat *plat = dev_get_plat(dev);
return (plat->mem_type == DDR_MEMORY ? "DDR" : "HBM");
}
static bool is_ddr_in_use(struct udevice *dev)
{
struct altera_sdram_plat *plat = dev_get_plat(dev);
return (plat->mem_type == DDR_MEMORY ? true : false);
}
int populate_ddr_handoff(struct udevice *dev, struct io96b_info *io96b_ctrl,
struct uib_info *uib_ctrl)
{
struct altera_sdram_plat *plat = dev_get_plat(dev);
int i;
u8 count = 0;
u32 len = SOC64_HANDOFF_DDR_LEN;
u32 handoff_table[len];
/* Read handoff for DDR configuration */
socfpga_handoff_read((void *)SOC64_HANDOFF_DDR_BASE, handoff_table, len);
/* Interleaving Mode */
if (handoff_table[0] & SOC64_HANDOFF_DDR_INTERLEAVING_MODE_MASK)
plat->multichannel_interleaving = true;
else
plat->multichannel_interleaving = false;
debug("%s: MPFE-EMIF is in %s mode\n", __func__,
plat->multichannel_interleaving ? "interleaving" : "multichannel");
/* Memory type */
if (handoff_table[2] & SOC64_HANDOFF_DDR_MEMORY_TYPE_MASK)
plat->mem_type = HBM_MEMORY;
else
plat->mem_type = DDR_MEMORY;
debug("%s: Memory type is %s\n", __func__
, plat->mem_type ? "HBM" : "DDR");
if (plat->mem_type == HBM_MEMORY) {
/* Assign UIB CSR base address if it is valid */
for (i = 0; i < MAX_UIB_SUPPORTED; i++) {
if (handoff_table[3] & BIT(i)) {
uib_ctrl->uib[count].uib_csr_addr = uib_csr_reg_addr[i];
debug("%s: UIB 0x%llx CSR enabled\n", __func__
, uib_ctrl->uib[count].uib_csr_addr);
count++;
}
}
uib_ctrl->num_instance = count;
debug("%s: returned num_instance 0x%x\n", __func__, uib_ctrl->num_instance);
/*
* HBM memory size
* 1 UIB channel has 2 pseudo channels
* 1 pseudo channel is 1GB, hence 1 UIB channel is 2GB
*/
uib_ctrl->overall_size = (phys_size_t)uib_ctrl->num_instance * SZ_2G;
/* UIB ECC status */
uib_ctrl->ecc_status = handoff_table[4];
debug("%s: ECC status 0x%x\n", __func__, uib_ctrl->ecc_status);
} else {
/* Assign IO96B CSR base address if it is valid */
for (i = 0; i < MAX_IO96B_SUPPORTED; i++) {
if (handoff_table[1] & BIT(i)) {
io96b_ctrl->io96b[i].io96b_csr_addr = io96b_csr_reg_addr[i];
debug("%s: IO96B 0x%llx CSR enabled\n", __func__,
io96b_ctrl->io96b[i].io96b_csr_addr);
count++;
}
}
io96b_ctrl->num_instance = count;
debug("%s: returned num_instance 0x%x\n", __func__, io96b_ctrl->num_instance);
}
return 0;
}
int config_mpfe_sideband_mgr(struct udevice *dev)
{
struct altera_sdram_plat *plat = dev_get_plat(dev);
u32 reg, mask;
int ret = 0;
if (plat->multichannel_interleaving) {
mask = SIDEBANDMGR_FLAGOUTSET0_REG_INTERLEAVING;
setbits_le32(SIDEBANDMGR_FLAGOUTSET0_REG, mask);
} else {
mask = SIDEBANDMGR_FLAGOUTSET0_REG_MULTICHANNEL;
setbits_le32(SIDEBANDMGR_FLAGOUTSET0_REG, mask);
}
reg = readl(SIDEBANDMGR_FLAGOUTSTATUS0_REG);
debug("%s: F2SDRAM_SIDEBAND_FLAGOUTSTATUS0: 0x%x\n", __func__, reg);
if ((reg & mask) == SIDEBANDMGR_FLAGOUTSET0_REG_INTERLEAVING)
debug("%s: Interleaving bit is set\n", __func__);
else if ((reg & mask) == SIDEBANDMGR_FLAGOUTSET0_REG_MULTICHANNEL)
debug("%s: Multichannel bit is set\n", __func__);
else
ret = -EINVAL;
return ret;
}
bool hps_ocram_dbe_status(void)
{
u32 reg = readl(socfpga_get_sysmgr_addr() +
SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
if (reg & ALT_SYSMGR_SCRATCH_REG_8_OCRAM_DBE_MASK)
return true;
return false;
}
bool ddr_ecc_dbe_status(void)
{
u32 reg = readl(socfpga_get_sysmgr_addr() +
SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
if (reg & ALT_SYSMGR_SCRATCH_REG_8_DDR_DBE_MASK)
return true;
return false;
}
int sdram_mmr_init_full(struct udevice *dev)
{
int i, ret = 0;
struct altera_sdram_plat *plat = dev_get_plat(dev);
struct altera_sdram_priv *priv = dev_get_priv(dev);
struct io96b_info *io96b_ctrl = malloc(sizeof(*io96b_ctrl));
struct uib_info *uib_ctrl = malloc(sizeof(*uib_ctrl));
struct bd_info bd = {0};
bool full_mem_init = false, is_ddr_hang_be4_rst = false;
phys_size_t hw_size;
u32 reg = readl(socfpga_get_sysmgr_addr() + SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
enum reset_type reset_t = get_reset_type(reg);
/* Populating DDR handoff data */
debug("DDR: Populating DDR handoff\n");
ret = populate_ddr_handoff(dev, io96b_ctrl, uib_ctrl);
if (ret) {
printf("DDR: Failed to populate DDR handoff\n");
goto err;
}
debug("%s: Address MPFE 0x%llx\n", memory_type_in_use(dev), plat->mpfe_base_addr);
/* DDR initialization progress status tracking */
is_ddr_hang_be4_rst = is_ddr_init_hang();
printf("%s: SDRAM init in progress ...\n", memory_type_in_use(dev));
ddr_init_inprogress(true);
/* Configuring MPFE sideband manager registers - multichannel or interleaving*/
debug("%s: MPFE configuration in progress ...\n", memory_type_in_use(dev));
ret = config_mpfe_sideband_mgr(dev);
if (ret) {
printf("%s: Failed to configure multichannel/interleaving mode\n",
memory_type_in_use(dev));
goto err;
}
debug("%s: MPFE configuration completed\n", memory_type_in_use(dev));
debug("%s: Waiting for NOCPLL locked ...\n", memory_type_in_use(dev));
/* Ensure NOCPLL locked */
ret = wait_for_bit_le32((const void *)socfpga_get_sysmgr_addr() + SYSMGR_HMC_CLK
, SYSMGR_HMC_CLK_NOCPLL, true, TIMEOUT, false);
if (ret) {
printf("%s: NOCPLL is not locked\n", memory_type_in_use(dev));
goto err;
}
debug("%s: NOCPLL locked\n", memory_type_in_use(dev));
debug("%s: Checking calibration...\n", memory_type_in_use(dev));
if (is_ddr_in_use(dev)) {
/* Configure if polling is needed for IO96B GEN PLL locked */
io96b_ctrl->ckgen_lock = false;
/* Ensure calibration status passing */
init_mem_cal(io96b_ctrl);
printf("DDR: Calibration success\n");
/* Initiate IOSSM mailbox */
io96b_mb_init(io96b_ctrl);
/* DDR type */
ret = get_mem_technology(io96b_ctrl);
if (ret) {
printf("DDR: Failed to get DDR type\n");
goto err;
}
/* DDR size */
ret = get_mem_width_info(io96b_ctrl);
if (ret) {
printf("DDR: Failed to get DDR size\n");
goto err;
}
} else {
/* Ensure calibration status passing */
uib_init_mem_cal(uib_ctrl);
/* Need to trigger re-calibration for HBM DBE */
if (ddr_ecc_dbe_status()) {
for (i = 0; i < uib_ctrl->num_instance; i++)
uib_ctrl->uib[i].cal_status = false;
uib_ctrl->overall_cal_status = false;
}
/* Trigger re-calibration if calibration failed */
if (!(uib_ctrl->overall_cal_status)) {
printf("HBM: Re-calibration in progress...\n");
uib_trig_mem_cal(uib_ctrl);
}
if (!(uib_ctrl->overall_cal_status)) {
printf("HBM: Retry calibration failed & not able to re-calibrate\n");
ret = -EINVAL;
goto err;
}
debug("HBM: Setting Error Mask Register\n");
/* Responder Error Mask Register */
for (i = 0; i < uib_ctrl->num_instance; i++) {
clrsetbits_le32(uib_ctrl->uib[i].uib_csr_addr +
UIB_R_ERRMSK_PSEUDO_CH0_OFFSET,
UIB_DRAM_SBE_MSK | UIB_INTERNAL_CORR_ERR_MSK,
UIB_DRAM_SBE(0x1) | UIB_INTERNAL_CORR_ERR(0x1));
debug("HBM: Error Mask Pseudo CH0 addr: 0x%llx\n",
uib_ctrl->uib[i].uib_csr_addr +
UIB_R_ERRMSK_PSEUDO_CH0_OFFSET);
debug("HBM: Error Mask Pseudo CH0 value: 0x%x\n",
readl(uib_ctrl->uib[i].uib_csr_addr +
UIB_R_ERRMSK_PSEUDO_CH0_OFFSET));
clrsetbits_le32(uib_ctrl->uib[i].uib_csr_addr +
UIB_R_ERRMSK_PSEUDO_CH1_OFFSET,
UIB_DRAM_SBE_MSK | UIB_INTERNAL_CORR_ERR_MSK,
UIB_DRAM_SBE(0x1) | UIB_INTERNAL_CORR_ERR(0x1));
debug("HBM: Error Mask Pseudo CH1 addr: 0x%llx\n",
uib_ctrl->uib[i].uib_csr_addr +
UIB_R_ERRMSK_PSEUDO_CH1_OFFSET);
debug("HBM: Error Mask Pseudo CH1 value: 0x%x\n\n",
readl(uib_ctrl->uib[i].uib_csr_addr +
UIB_R_ERRMSK_PSEUDO_CH1_OFFSET));
}
printf("HBM: Calibration success\n");
}
/* Get bank configuration from devicetree */
ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
(phys_size_t *)&gd->ram_size, &bd);
if (ret) {
printf("%s: Failed to decode memory node\n", memory_type_in_use(dev));
goto err;
}
if (!is_ddr_in_use(dev)) {
hw_size = uib_ctrl->overall_size;
} else {
/* ECC status */
ret = ecc_enable_status(io96b_ctrl);
if (ret) {
printf("DDR: Failed to get DDR ECC status\n");
goto err;
}
hw_size = io96b_ctrl->overall_size;
if (io96b_ctrl->inline_ecc)
hw_size = CALC_INLINE_ECC_HW_SIZE(hw_size);
}
if (gd->ram_size != hw_size) {
printf("%s: Warning: DRAM size from device tree (%lld MiB)\n",
memory_type_in_use(dev), gd->ram_size >> 20);
printf(" mismatch with hardware (%lld MiB).\n",
hw_size >> 20);
}
if (gd->ram_size > hw_size) {
printf("%s: Error: DRAM size from device tree is greater\n",
memory_type_in_use(dev));
printf(" than hardware size.\n");
hang();
}
printf("%s: %lld MiB\n", (is_ddr_in_use(dev) ? io96b_ctrl->ddr_type : "HBM"),
gd->ram_size >> 20);
if (is_ddr_in_use(dev)) {
/*
* Is HPS cold or warm reset? If yes, Skip full memory initialization if ECC
* enabled to preserve memory content
*/
if (io96b_ctrl->ecc_status) {
if (ecc_interrupt_status(io96b_ctrl)) {
if (CONFIG_IS_ENABLED(WDT)) {
struct udevice *wdt;
printf("DDR: ECC error recover start now\n");
ret = uclass_first_device_err(UCLASS_WDT, &wdt);
if (ret) {
printf("DDR: Failed to trigger watchdog reset\n");
hang();
}
wdt_expire_now(wdt, 0);
}
hang();
}
full_mem_init = hps_ocram_dbe_status() | is_ddr_hang_be4_rst;
if (full_mem_init || !(reset_t == WARM_RESET || reset_t == COLD_RESET)) {
debug("%s: Needed to fully initialize DDR memory\n",
io96b_ctrl->ddr_type);
ret = bist_mem_init_start(io96b_ctrl);
if (ret) {
printf("%s: Failed to fully initialize DDR memory\n",
io96b_ctrl->ddr_type);
goto err;
}
}
}
} else {
debug("HBM: ECC enable status: %d\n", uib_ctrl->ecc_status);
/*
* Is HPS cold or warm reset? If yes, Skip full memory initialization if ECC
* enabled to preserve memory content
*/
if (uib_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)) {
debug("HBM: Needed to fully initialize HBM memory\n");
ret = uib_bist_mem_init_start(uib_ctrl);
if (ret) {
printf("HBM: Failed to fully initialize HBM memory\n");
goto err;
}
}
}
}
/* Ensure sanity memory test passing */
sdram_size_check(&bd);
printf("%s: size check success\n", (is_ddr_in_use(dev) ? io96b_ctrl->ddr_type : "HBM"));
sdram_set_firewall(&bd);
printf("%s: firewall init success\n", (is_ddr_in_use(dev) ? io96b_ctrl->ddr_type : "HBM"));
priv->info.base = bd.bi_dram[0].start;
priv->info.size = gd->ram_size;
/* Ending DDR driver initialization success tracking */
ddr_init_inprogress(false);
printf("%s init success\n", (is_ddr_in_use(dev) ? io96b_ctrl->ddr_type : "HBM"));
err:
free(io96b_ctrl);
free(uib_ctrl);
return ret;
}

View File

@@ -29,7 +29,10 @@
#define PGTABLE_OFF 0x4000
#if !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
#define SINGLE_RANK_CLAMSHELL 0xc3c3
#define DUAL_RANK_CLAMSHELL 0xa5a5
#if !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) && !IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
u32 hmc_readl(struct altera_sdram_plat *plat, u32 reg)
{
return readl(plat->iomhc + reg);
@@ -258,8 +261,19 @@ phys_size_t sdram_calculate_size(struct altera_sdram_plat *plat)
{
u32 dramaddrw = hmc_readl(plat, DRAMADDRW);
u32 reg_ctrlcfg6_value = hmc_readl(plat, CTRLCFG6);
u32 cs_rank = CTRLCFG6_CFG_CS_CHIP(reg_ctrlcfg6_value);
u32 cs_addr_width;
if (cs_rank == SINGLE_RANK_CLAMSHELL)
cs_addr_width = 0;
else if (cs_rank == DUAL_RANK_CLAMSHELL)
cs_addr_width = 1;
else
cs_addr_width = DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw);
phys_size_t size = (phys_size_t)1 <<
(DRAMADDRW_CFG_CS_ADDR_WIDTH(dramaddrw) +
(cs_addr_width +
DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw) +
DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) +
@@ -398,7 +412,7 @@ static int altera_sdram_of_to_plat(struct udevice *dev)
/* These regs info are part of DDR handoff in bitstream */
#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
return 0;
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5)
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX5) || IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
addr = dev_read_addr_index(dev, 0);
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
@@ -467,6 +481,7 @@ static const struct udevice_id altera_sdram_ids[] = {
{ .compatible = "intel,sdr-ctl-agilex" },
{ .compatible = "intel,sdr-ctl-n5x" },
{ .compatible = "intel,sdr-ctl-agilex5" },
{ .compatible = "intel,sdr-ctl-agilex7m" },
{ /* sentinel */ }
};

View File

@@ -21,6 +21,17 @@ struct altera_sdram_plat {
bool dualport;
bool dualemif;
};
#elif IS_ENABLED(CONFIG_TARGET_SOCFPGA_AGILEX7M)
enum memory_type {
DDR_MEMORY = 0,
HBM_MEMORY
};
struct altera_sdram_plat {
fdt_addr_t mpfe_base_addr;
bool multichannel_interleaving;
enum memory_type mem_type;
};
#else
struct altera_sdram_plat {
void __iomem *hmc;
@@ -48,6 +59,8 @@ struct altera_sdram_plat {
#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)
@@ -63,7 +76,7 @@ struct altera_sdram_plat {
#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_CORE2SEQ_INT_REQ 0x0000000f
#define DDR_HMC_SEQ2CORE_INT_RESP_MASK BIT(3)
#define DDR_HMC_HPSINTFCSEL_ENABLE_MASK 0x001f1f1f
@@ -75,6 +88,8 @@ struct altera_sdram_plat {
#define CTRLCFG0 0x28
#define CTRLCFG1 0x2c
#define CTRLCFG3 0x34
#define CTRLCFG5 0x3c
#define CTRLCFG6 0x40
#define DRAMTIMING0 0x50
#define CALTIMING0 0x7c
#define CALTIMING1 0x80
@@ -89,90 +104,93 @@ struct altera_sdram_plat {
#define NIOSRESERVED2 0x118
#define DRAMADDRW_CFG_COL_ADDR_WIDTH(x) \
(((x) >> 0) & 0x1F)
((x) & 0x1f)
#define DRAMADDRW_CFG_ROW_ADDR_WIDTH(x) \
(((x) >> 5) & 0x1F)
(((x) >> 5) & 0x1f)
#define DRAMADDRW_CFG_BANK_ADDR_WIDTH(x) \
(((x) >> 10) & 0xF)
(((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) >> 0) & 0xF)
((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)
(((x) >> 9) & 0x1f)
#define CTRLCFG1_CFG_DBC3_BURST_LEN(x) \
(((x) >> 0) & 0x1F)
((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) >> 0) & 0x7F)
((x) & 0x7f)
#define CALTIMING0_CFG_ACT_TO_RDWR(x) \
(((x) >> 0) & 0x3F)
((x) & 0x3f)
#define CALTIMING0_CFG_ACT_TO_PCH(x) \
(((x) >> 6) & 0x3F)
(((x) >> 6) & 0x3f)
#define CALTIMING0_CFG_ACT_TO_ACT(x) \
(((x) >> 12) & 0x3F)
(((x) >> 12) & 0x3f)
#define CALTIMING0_CFG_ACT_TO_ACT_DB(x) \
(((x) >> 18) & 0x3F)
(((x) >> 18) & 0x3f)
#define CALTIMING1_CFG_RD_TO_RD(x) \
(((x) >> 0) & 0x3F)
((x) & 0x3f)
#define CALTIMING1_CFG_RD_TO_RD_DC(x) \
(((x) >> 6) & 0x3F)
(((x) >> 6) & 0x3f)
#define CALTIMING1_CFG_RD_TO_RD_DB(x) \
(((x) >> 12) & 0x3F)
(((x) >> 12) & 0x3f)
#define CALTIMING1_CFG_RD_TO_WR(x) \
(((x) >> 18) & 0x3F)
#define CALTIMING1_CFG_RD_TO_WR_DC(x) \
(((x) >> 24) & 0x3F)
(((x) >> 24) & 0x3f)
#define CALTIMING2_CFG_RD_TO_WR_DB(x) \
(((x) >> 0) & 0x3F)
((x) & 0x3f)
#define CALTIMING2_CFG_RD_TO_WR_PCH(x) \
(((x) >> 6) & 0x3F)
(((x) >> 6) & 0x3f)
#define CALTIMING2_CFG_RD_AP_TO_VALID(x) \
(((x) >> 12) & 0x3F)
(((x) >> 12) & 0x3f)
#define CALTIMING2_CFG_WR_TO_WR(x) \
(((x) >> 18) & 0x3F)
(((x) >> 18) & 0x3f)
#define CALTIMING2_CFG_WR_TO_WR_DC(x) \
(((x) >> 24) & 0x3F)
(((x) >> 24) & 0x3f)
#define CALTIMING3_CFG_WR_TO_WR_DB(x) \
(((x) >> 0) & 0x3F)
((x) & 0x3F)
#define CALTIMING3_CFG_WR_TO_RD(x) \
(((x) >> 6) & 0x3F)
(((x) >> 6) & 0x3f)
#define CALTIMING3_CFG_WR_TO_RD_DC(x) \
(((x) >> 12) & 0x3F)
(((x) >> 12) & 0x3f)
#define CALTIMING3_CFG_WR_TO_RD_DB(x) \
(((x) >> 18) & 0x3F)
(((x) >> 18) & 0x3f)
#define CALTIMING3_CFG_WR_TO_PCH(x) \
(((x) >> 24) & 0x3F)
(((x) >> 24) & 0x3f)
#define CALTIMING4_CFG_WR_AP_TO_VALID(x) \
(((x) >> 0) & 0x3F)
((x) & 0x3f)
#define CALTIMING4_CFG_PCH_TO_VALID(x) \
(((x) >> 6) & 0x3F)
(((x) >> 6) & 0x3f)
#define CALTIMING4_CFG_PCH_ALL_TO_VALID(x) \
(((x) >> 12) & 0x3F)
(((x) >> 12) & 0x3f)
#define CALTIMING4_CFG_ARF_TO_VALID(x) \
(((x) >> 18) & 0xFF)
(((x) >> 18) & 0xff)
#define CALTIMING4_CFG_PDN_TO_VALID(x) \
(((x) >> 26) & 0x3F)
(((x) >> 26) & 0x3f)
#define CALTIMING9_CFG_4_ACT_TO_ACT(x) \
(((x) >> 0) & 0xFF)
((x) & 0xff)
/* Firewall DDR scheduler MPFE */
#define FW_HMC_ADAPTOR_REG_ADDR 0xf8020004

View File

@@ -0,0 +1,321 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#include <hang.h>
#include <wait_bit.h>
#include <asm/io.h>
#include <linux/bitfield.h>
#include "uibssm_mailbox.h"
#define MAX_RETRIES 3
int uib_bist_mem_init_start(struct uib_info *uib_ctrl)
{
struct uib_mb_resp usr_resp;
bool bist_start, bist_success;
u32 start;
for (int i = 0; i < uib_ctrl->num_instance; i++) {
bist_start = false;
bist_success = false;
/*
* Full memory initialization BIST performed on all UIB channels
* start memory initialization BIST on full memory address
*/
uib_mb_req(uib_ctrl->uib[i].uib_csr_addr,
UIB_CMD_TRIG_CONTROLLER_OP,
UIB_BIST_MEM_INIT_START,
UIB_BIST_FULL_MEM, &usr_resp);
bist_start = UIBSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) &
UIB_BIST_INITIATE_PASS;
if (!bist_start) {
printf("%s: Failed to initialize memory on UIB instance %d\n",
__func__, i);
return -EINVAL;
}
/* Polling for the initiated memory initialization BIST status */
start = get_timer(0);
while (!bist_success) {
udelay(1);
/*
* cmd_param_0 is not used in BIST status request,
* hence set the value to 0
*/
uib_mb_req(uib_ctrl->uib[i].uib_csr_addr,
UIB_CMD_TRIG_CONTROLLER_OP,
UIB_BIST_MEM_INIT_STATUS,
0, &usr_resp);
bist_success = UIBSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) &
BIT(0);
if (!bist_success && (get_timer(start) > TIMEOUT)) {
printf("%s: Timeout initializing memory on UIB instance %d\n",
__func__, i);
return -ETIMEDOUT;
}
}
debug("%s: Memory initialized successfully on UIB instance %d\n", __func__, i);
}
return 0;
}
int uib_cal_status(phys_addr_t addr)
{
int ret = 0;
phys_addr_t status_addr = addr + UIB_R_INITSTS_OFFSET;
/* Ensure calibration completed */
ret = wait_for_bit_le32((const void *)status_addr, UIB_R_INITSTS_INITSTS_PASS, true,
TIMEOUT, false);
if (ret)
printf("%s: HBM calibration UIB instance 0x%llx timeout\n", __func__, status_addr);
return ret;
}
void uib_init_mem_cal(struct uib_info *uib_ctrl)
{
int i, ret;
if (!uib_ctrl->num_instance) {
uib_ctrl->overall_cal_status = false;
} else {
uib_ctrl->overall_cal_status = true;
/* Check initial calibration status for the assigned UIB */
for (i = 0; i < uib_ctrl->num_instance; i++) {
ret = uib_cal_status(uib_ctrl->uib[i].uib_csr_addr);
if (ret) {
uib_ctrl->uib[i].cal_status = false;
uib_ctrl->overall_cal_status = false;
printf("%s: Initial HBM calibration UIB_%d failed\n", __func__, i);
break;
}
uib_ctrl->uib[i].cal_status = true;
debug("%s: Initial HBM calibration UIB_%d succeed\n", __func__, i);
}
}
}
/* Trying 3 times re-calibration if initial calibration failed */
void uib_trig_mem_cal(struct uib_info *uib_ctrl)
{
int i, j, cal_stat;
if (!uib_ctrl->num_instance) {
uib_ctrl->overall_cal_status = false;
} else {
uib_ctrl->overall_cal_status = true;
for (i = 0; i < uib_ctrl->num_instance; i++) {
uib_ctrl->uib[i].cal_status = false;
/* Initiate Re-calibration */
for (j = 0; j < MAX_RETRIES; j++) {
clrsetbits_le32(uib_ctrl->uib[i].uib_csr_addr +
UIB_R_INITCTL_OFFSET,
UIB_R_INITCTL_INITTYPE_MASK |
UIB_R_INITCTL_INITREQ_MASK,
UIB_R_INITCTL_INITTYPE(UIB_RST_REQUEST_WITH_CAL) |
UIB_R_INITCTL_INITREQ(1));
cal_stat = uib_cal_status(uib_ctrl->uib[i].uib_csr_addr);
if (cal_stat)
continue;
debug("%s: HBM re-calibration UIB_%d succeed\n", __func__, i);
uib_ctrl->uib[i].cal_status = true;
break;
}
if (!uib_ctrl->uib[i].cal_status) {
uib_ctrl->overall_cal_status = false;
printf("%s: HBM re-calibration UIB_%d failed\n", __func__, i);
break;
}
}
}
}
static void uib_mailbox_write_request(u32 data, u32 target_write_addr, phys_addr_t csr_addr)
{
int ret;
/*
* Read from chms0020 MBWRADDR_VALID and ensure its not set or
* wait till it get cleared by controller
*/
debug("%s: #1 Read MBWRADDR_VALID from UIB_R_MBWRCTL\n", __func__);
ret = wait_for_bit_le32((const void *)csr_addr + UIB_R_MBWRCTL,
UIB_R_MBWRCTL_MBWRADDR_VALID, false, TIMEOUT, false);
if (ret) {
printf("%s: TIMEOUT!!! MBWRADDR_VALID is not zero\n", __func__);
hang();
}
/* Write <target write address> to chms0024 MBWRADDR */
debug("%s: #2 Write 0x%x to UIB_R_MBWRADDR\n", __func__, target_write_addr);
writel(target_write_addr, csr_addr + UIB_R_MBWRADDR);
/*
* Write 1 to chms0020 MBWRADDR_VALID to indicate the address is now valid
* for FW to read
*/
debug("%s: #3 Write 1 to MBWRADDR_VALID for FW to read address\n", __func__);
setbits_le32(csr_addr + UIB_R_MBWRCTL, UIB_R_MBWRCTL_MBWRADDR_VALID);
/*
* Read from chms0020 MBWRDATA_VALID and ensure its not set or
* wait till it get cleared by controller
*/
debug("%s: #4 Read MBWRDATA_VALID from UIB_R_MBWRCTL\n", __func__);
ret = wait_for_bit_le32((const void *)csr_addr + UIB_R_MBWRCTL,
UIB_R_MBWRCTL_MBWRDATA_VALID, false, TIMEOUT, false);
if (ret) {
printf("%s: TIMEOUT!!! MBWRADDR_VALID is not zero\n", __func__);
hang();
}
/*
* Read from chms0020 MBWRDATA_END and ensure its not set or
* wait till it get cleared by controller
*/
debug("%s: #5 Read R_MBWRCTL_MBWRDATA_END from UIB_R_MBWRCTL\n", __func__);
ret = wait_for_bit_le32((const void *)csr_addr + UIB_R_MBWRCTL,
UIB_R_MBWRCTL_MBWRDATA_END, false, TIMEOUT, false);
if (ret) {
printf("%s: TIMEOUT!!! MBWRDATA_END is not zero\n", __func__);
hang();
}
/* Write <write data> to chms0028 MMR_MBWRDATA */
debug("%s: #6 Write 0x%x to UIB_R_MBWRDATA\n", __func__, data);
writel(data, csr_addr + UIB_R_MBWRDATA);
/*
* Write 1 to chms0020 MBWRDATA_END to indicate if the <write data> is the last burst
* for FW to read for the <target write address>
*/
debug("%s: #7 Write 1 to MBWRDATA_END to inform FW this is last burst of data to read\n",
__func__);
setbits_le32(csr_addr + UIB_R_MBWRCTL, UIB_R_MBWRCTL_MBWRDATA_END);
/* Write 1 to chms0020 MBWRDATA_VALID to indicate the data is now valid for FW to read */
debug("%s: #8 Write 1 to MBWRDATA_VALID for FW to read data\n", __func__);
setbits_le32(csr_addr + UIB_R_MBWRCTL, UIB_R_MBWRCTL_MBWRDATA_VALID);
}
static u32 uib_mailbox_read_request(u32 target_read_addr, phys_addr_t csr_addr)
{
int ret;
u32 reg, rd_data = 0;
/*
* Read from chms0030 MBRDADDR_VALID and ensure its not set or
* wait till it get cleared by controller
*/
debug("%s: #1 Read MBRDADDR_VALID from UIB_R_MBRDCTL\n", __func__);
ret = wait_for_bit_le32((const void *)csr_addr + UIB_R_MBRDCTL,
UIB_R_MBRDCTL_MBRDADDR_VALID, false, TIMEOUT, false);
if (ret) {
printf("%s: TIMEOUT!!! MBRDADDR_VALID is not zero\n", __func__);
hang();
}
/* Write <target read address> to chms0034 MBRDADDR */
debug("%s: #2 Write 0x%x to UIB_R_MBRDADDR\n", __func__, target_read_addr);
writel(target_read_addr, csr_addr + UIB_R_MBRDADDR);
/*
* Write 1 to chms0030 MBRDADDR_VALID to indicate the address is now valid
* for FW to read
*/
debug("%s: #3 Write 1 to MBRDADDR_VALID for FW to read address\n", __func__);
setbits_le32(csr_addr + UIB_R_MBRDCTL, UIB_R_MBRDCTL_MBRDADDR_VALID);
/*
* Continuously poll the chms0030 MBRDDATA_VALID. If MBRDDATA_VALID are set, read
* chms0038 MBRDDATA and chms0030 MBRDDATA_END to retrieve the <read data> and
* <end of read burst> status accordingly
*/
debug("%s: #4 Read MBRDDATA_VALID from UIB_R_MBRDCTL\n", __func__);
ret = wait_for_bit_le32((const void *)csr_addr + UIB_R_MBRDCTL,
UIB_R_MBRDCTL_MBRDDATA_VALID, true, TIMEOUT, false);
if (ret) {
printf("%s: TIMEOUT!!! MBRDDATA_VALID is zero\n", __func__);
hang();
}
reg = readl(csr_addr + UIB_R_MBRRDATA);
debug("%s: #5 Read data from UIB_R_MBRRDATA = 0x%x\n", __func__, reg);
rd_data = reg;
reg = readl(csr_addr + UIB_R_MBRDCTL);
debug("%s: #6 Read end of read burst status from UIB_R_MBRDCTL = 0x%x\n", __func__, reg);
/*
* Once done retrieving the data, write 1 to chms0030 MBRDDATA_VALID,
* chms0030 MBRDDATA_END to clear the register
*/
debug("%s: #7 Write 1 to MBRDDATA_VALID for FW to read address\n", __func__);
setbits_le32(csr_addr + UIB_R_MBRDCTL, UIB_R_MBRDCTL_MBRDDATA_VALID |
UIB_R_MBWRCTL_MBWRDATA_END);
return rd_data;
}
int uib_mb_req(phys_addr_t uib_csr_addr, u32 usr_cmd_type, u32 usr_cmd_opcode,
u32 cmd_param_0, struct uib_mb_resp *resp)
{
u32 cmd_req;
/* Initialized zeros for responses */
resp->cmd_resp_status = 0;
/* Write CMD_REQ (CMD_TYPE and CMD_OPCODE) */
cmd_req = FIELD_PREP(CMD_TYPE_MASK, usr_cmd_type) |
FIELD_PREP(CMD_OPCODE_MASK, usr_cmd_opcode);
uib_mailbox_write_request(cmd_req, 0, uib_csr_addr);
debug("%s: Write 0x%x to UIBSSM_CMD_REQ_OFFSET 0x%llx\n", __func__, cmd_req, uib_csr_addr);
/* Write CMD_PARAM_* */
if (cmd_param_0)
uib_mailbox_write_request(cmd_param_0, 0, uib_csr_addr);
else
debug("%s: cmd_param_0 is NULL\n", __func__);
/* read CMD_RESPONSE_STATUS */
resp->cmd_resp_status = uib_mailbox_read_request(0, uib_csr_addr);
debug("%s: CMD_RESPONSE_STATUS 0x%llx: 0x%x\n", __func__,
uib_csr_addr, resp->cmd_resp_status);
debug("%s: STATUS_CMD_RESPONSE_ERROR: 0x%lx\n", __func__,
UIBSSM_CMD_RESPONSE_ERROR(resp->cmd_resp_status));
debug("%s: STATUS_GENERAL_ERROR: 0x%lx\n", __func__,
UIBSSM_GENERAL_ERROR(resp->cmd_resp_status));
return 0;
}

View File

@@ -0,0 +1,116 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*/
#define TIMEOUT_120000MS 120000
#define TIMEOUT TIMEOUT_120000MS
#define UIBSSM_CMD_RESPONSE_DATA_SHORT_MASK GENMASK(31, 16)
#define UIBSSM_CMD_RESPONSE_DATA_SHORT(x) FIELD_GET(UIBSSM_CMD_RESPONSE_DATA_SHORT_MASK, x)
#define UIBSSM_CMD_RESPONSE_ERROR_MASK GENMASK(7, 5)
#define UIBSSM_CMD_RESPONSE_ERROR(x) FIELD_GET(UIBSSM_CMD_RESPONSE_ERROR_MASK, x)
#define UIBSSM_GENERAL_ERROR_MASK GENMASK(4, 1)
#define UIBSSM_GENERAL_ERROR(x) FIELD_GET(UIBSSM_GENERAL_ERROR_MASK, x)
/* UIB Responder Initialization Control Register */
#define UIB_R_INITCTL_OFFSET 0x10
#define UIB_R_INITCTL_INITREQ_MASK BIT(0)
#define UIB_R_INITCTL_INITTYPE_MASK GENMASK(11, 8)
#define UIB_R_INITCTL_INITREQ(x) FIELD_PREP(UIB_R_INITCTL_INITREQ_MASK, x)
#define UIB_R_INITCTL_INITTYPE(x) FIELD_PREP(UIB_R_INITCTL_INITTYPE_MASK, x)
#define UIB_RST_REQUEST_WITH_CAL 5
/* UIB Initialization control and status registers */
#define UIB_R_INITSTS_OFFSET 0x14
#define UIB_R_INITSTS_INITSTS_PASS BIT(1)
#define MAX_UIB_SUPPORTED 8
#define UIB_R_MBWRCTL 0x20
#define UIB_R_MBWRADDR 0x24
#define UIB_R_MBWRDATA 0x28
#define UIB_R_MBWRCTL_MBWRADDR_VALID BIT(0)
#define UIB_R_MBWRCTL_MBWRDATA_VALID BIT(4)
#define UIB_R_MBWRCTL_MBWRDATA_END BIT(7)
#define UIB_R_MBRDCTL 0x30
#define UIB_R_MBRDADDR 0x34
#define UIB_R_MBRRDATA 0x38
#define UIB_R_MBRDCTL_MBRDADDR_VALID BIT(0)
#define UIB_R_MBRDCTL_MBRDDATA_VALID BIT(4)
#define UIB_R_MBRDCTL_MBRDDATA_END BIT(7)
/* Responder Error Mask Register */
#define UIB_R_ERRMSK_PSEUDO_CH0_OFFSET 0x520
#define UIB_R_ERRMSK_PSEUDO_CH1_OFFSET 0X820
#define UIB_DRAM_SBE_MSK BIT(25)
#define UIB_INTERNAL_CORR_ERR_MSK BIT(30)
#define UIB_DRAM_SBE(x) FIELD_PREP(UIB_DRAM_SBE_MSK, x)
#define UIB_INTERNAL_CORR_ERR(x) FIELD_PREP(UIB_INTERNAL_CORR_ERR_MSK, x)
/* CMD_REQ Register Definition */
#define CMD_TYPE_MASK GENMASK(23, 16)
#define CMD_OPCODE_MASK GENMASK(15, 0)
/* supported mailbox command type */
enum uibssm_mailbox_cmd_type {
UIB_CMD_TRIG_CONTROLLER_OP = 0x04
};
/* supported mailbox command opcode */
enum uibssm_mailbox_cmd_opcode {
UIB_BIST_MEM_INIT_START = 0x0303,
UIB_BIST_MEM_INIT_STATUS
};
/* CMD_PARAM_0 for opcode UIB_BIST_MEM_INIT_START */
#define UIB_BIST_FULL_MEM BIT(6)
/* UIBSSM_CMD_RESPONSE_DATA_SHORT for opcode UIB_BIST_MEM_INIT_START */
#define UIB_BIST_INITIATE_PASS BIT(0)
/*
* UIBSSM mailbox response outputs
*
* @cmd_resp_status: Command Interface status
*/
struct uib_mb_resp {
u32 cmd_resp_status;
};
/*
* UIB instance specific information
*
* @uib_csr_addr: UIB instance CSR address
* @cal_status: UIB instance calibration status
*/
struct uib_instance {
phys_addr_t uib_csr_addr;
bool cal_status;
};
/*
* Overall UIB instance(s) information
*
* @num_instance: Number of instance(s) assigned to HPS
* @overall_cal_status: Overall calibration status for all UIB instance(s)
* @ecc_status: ECC enable status (false = disabled, true = enabled)
* @overall_size: Total HBM memory size
* @uib: UIB instance specific information
*/
struct uib_info {
u8 num_instance;
bool overall_cal_status;
bool ecc_status;
phys_size_t overall_size;
struct uib_instance uib[MAX_UIB_SUPPORTED];
};
/* Supported UIB function */
int uib_mb_req(phys_addr_t uib_csr_addr,
u32 usr_cmd_type, u32 usr_cmd_opcode,
u32 cmd_param_0, struct uib_mb_resp *resp);
int uib_cal_status(phys_addr_t addr);
void uib_init_mem_cal(struct uib_info *uib_ctrl);
void uib_trig_mem_cal(struct uib_info *uib_ctrl);
int uib_bist_mem_init_start(struct uib_info *uib_ctrl);

View File

@@ -1102,7 +1102,7 @@ static int xgmac_probe(struct udevice *dev)
ret = xgmac->config->ops->xgmac_start_clks(dev);
if (ret < 0) {
pr_err("%s xgmac_start_clks() failed: %d\n", dev->name, ret);
return ret;
goto err_remove_resources_core;
}
if (IS_ENABLED(CONFIG_DM_ETH_PHY))

View File

@@ -39,11 +39,9 @@ phy_interface_t dwxgmac_of_get_mac_mode(struct udevice *dev)
if (!mac_mode)
return PHY_INTERFACE_MODE_NA;
if (mac_mode) {
for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
if (!strcmp(mac_mode, phy_interface_strings[i]))
return i;
}
for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++) {
if (!strcmp(mac_mode, phy_interface_strings[i]))
return i;
}
return PHY_INTERFACE_MODE_NA;
}

View File

@@ -1,19 +1,78 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Pepperl+Fuchs
* Copyright (C) 2025 Altera Corporation <www.altera.com>
* Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
*/
#include <command.h>
#include <cpu_func.h>
#include <dm.h>
#include <errno.h>
#include <sysreset.h>
#include <asm/arch/mailbox_s10.h>
#include <asm/arch/reset_manager.h>
#include <asm/secure.h>
#define GICD_CTRL_ADDRESS 0xfffc1000
static __always_inline void __l2_reset_cpu(void)
{
asm volatile(/* Disable GIC distributor (IRQs). */
"str wzr, [%3]\n"
/* Set Magic Number */
"str %0, [%1]\n"
/* Increase timeout in rstmgr.hdsktimeout */
"ldr x2, =0xFFFFFF\n"
"str w2, [%2, #0x64]\n"
"ldr w2, [%2, #0x10]\n"
/*
* Set l2flushen = 1, etrstallen = 1,
* fpgahsen = 1 and sdrselfrefen = 1
* in rstmgr.hdsken to perform handshake
* in certain peripherals before trigger
* L2 reset.
*/
"ldr x3, =0x10D\n"
"orr x2, x2, x3\n"
"str w2, [%2, #0x10]\n"
/* Trigger L2 reset in rstmgr.coldmodrst */
"ldr w2, [%2, #0x34]\n"
"orr x2, x2, #0x100\n"
"isb\n"
"dsb sy\n"
"str w2, [%2, #0x34]\n"
/* Put all cores into WFI mode */
"1:\n"
" wfi\n"
" b 1b\n"
: : "r" (L2_RESET_DONE_STATUS),
"r" (L2_RESET_DONE_REG),
"r" (SOCFPGA_RSTMGR_ADDRESS),
"r" (GICD_CTRL_ADDRESS)
: "x1", "x2", "x3");
}
static void l2_reset_cpu(void)
{
__l2_reset_cpu();
}
static int socfpga_sysreset_request(struct udevice *dev,
enum sysreset_t type)
{
puts("Mailbox: Issuing mailbox cmd REBOOT_HPS\n");
mbox_reset_cold();
if (type == SYSRESET_WARM) {
/* flush dcache */
flush_dcache_all();
/* request a warm reset */
puts("Do warm reset now...\n");
l2_reset_cpu();
} else {
puts("Mailbox: Issuing mailbox cmd REBOOT_HPS\n");
mbox_reset_cold();
}
return -EINPROGRESS;
}

View File

@@ -31,7 +31,7 @@ config WATCHDOG_TIMEOUT_MSECS
default 128000 if ARCH_MX5 || ARCH_MX6
default 128000 if ARCH_MX7 || ARCH_VF610
default 30000 if ARCH_SNAPDRAGON
default 30000 if ARCH_SOCFPGA
default 10000 if ARCH_SOCFPGA
default 16000 if ARCH_SUNXI
default 5376 if ULP_WATCHDOG
default 15000 if ARCH_BCM283X

View File

@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0
*
* Copyright (C) 2025 Altera Corporation <www.altera.com>
*
*/
#ifndef __CONFIG_SOCFGPA_AGILEX7M_H__
#define __CONFIG_SOCFGPA_AGILEX7M_H__
#include <configs/socfpga_soc64_common.h>
#endif /* __CONFIG_SOCFGPA_AGILEX7M_H__ */

View File

@@ -18,6 +18,20 @@
/* sysmgr.boot_scratch_cold4 & 5 (64bit) will be used for PSCI_CPU_ON call */
#define CPU_RELEASE_ADDR 0xFFD12210
/*
* Share sysmgr.boot_scratch_cold6 & 7 (64bit) with VBAR_LE3_BASE_ADDR
* Indicate L2 reset is done. HPS should trigger warm reset via RMR_EL3.
*/
#define L2_RESET_DONE_REG 0xFFD12218
/* sysmgr.boot_scratch_cold8 bit 17 (1bit) will be used to check whether CPU0
* is being powered off/on from kernel
*/
#define BOOT_SCRATCH_COLD8 0xFFD12220
/* Magic word to indicate L2 reset is completed */
#define L2_RESET_DONE_STATUS 0x1228E5E7
/*
* U-Boot console configurations
*/
@@ -39,6 +53,9 @@
* U-Boot environment configurations
*/
#define CFG_SYS_NAND_U_BOOT_SIZE (1 * 1024 * 1024)
#define CFG_SYS_NAND_U_BOOT_DST CONFIG_TEXT_BASE
/*
* Environment variable
*/
@@ -159,6 +176,7 @@
" ${qspi_clock}; echo QSPI clock frequency updated; fi; fi\0" \
"scriptaddr=0x05FF0000\0" \
"scriptfile=boot.scr\0" \
"nandroot=ubi0:rootfs\0" \
"socfpga_legacy_reset_compat=1\0" \
"smc_fid_rd=0xC2000007\0" \
"smc_fid_wr=0xC2000008\0" \
@@ -214,6 +232,10 @@
"scriptfile=u-boot.scr\0" \
"fatscript=if fatload mmc 0:1 ${scriptaddr} ${scriptfile};" \
"then source ${scriptaddr}:script; fi\0" \
"nandfitboot=setenv bootargs " CONFIG_BOOTARGS \
" root=${nandroot} rw rootwait rootfstype=ubifs ubi.mtd=1; " \
"bootm ${loadaddr}\0" \
"nandfitload=ubi part root; ubi readvol ${loadaddr} kernel\0" \
"socfpga_legacy_reset_compat=1\0" \
"smc_fid_rd=0xC2000007\0" \
"smc_fid_wr=0xC2000008\0" \