diff options
| author | Tom Rini <[email protected]> | 2025-04-22 07:59:38 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-04-22 07:59:38 -0600 |
| commit | 8ab3cd0229a0ebf204cb5fd94f8a09e62825ffb4 (patch) | |
| tree | 4675ee039b4959d0a76614927068be99a4777fb1 /drivers | |
| parent | 185fdf5e94731df05748b1c576effb52ff7a3ec5 (diff) | |
| parent | 0415429935d7e19595d2997ee08415d0d8052d4d (diff) | |
Merge tag 'u-boot-socfpga-next-20250422' of https://source.denx.de/u-boot/custodians/u-boot-socfpga
This pull request contains updates for the SoCFPGA platform, targeting
the 2025.07 release cycle. Highlights include enhancements to Agilex5
support, improvements in DDR error handling, and bridge reset handling
for SoC64 devices.
Key updates:
Agilex5 platform enhancements:
* New MMU region mappings and memory layout updates using
LMB_ARCH_MEM_MAP.
* Fixes for bloblist configuration, kernel FIT image generation, and
VAB flow enablement.
* GPIO pin control added for SDIO selection.
* Marvell PHY driver enabled in defconfig.
Agilex5 / SoC64 DDR subsystem:
* Added ECC debug improvements for IOSSM.
* Introduced LPDDR inline ECC support.
* Resolved size calculation overflow in memory driver.
SoC64 improvements:
* Enhanced mailbox communication with the SDM to reflect various
boot stage transitions.
* Implemented F2S bridge reset support and updated related reset
manager registers.
* Expanded SoC64 CPU info reporting.
General maintenance:
* Additional peripherals released from reset for Arria10.
* Cleanup of legacy or incorrect Kconfig implications.
This patch set has been tested on Agilex 5 devkit.
Passing all pipeline tests at:
https://source.denx.de/u-boot/custodians/u-boot-socfpga/-/pipelines/25867
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/ddr/altera/iossm_mailbox.c | 225 | ||||
| -rw-r--r-- | drivers/ddr/altera/iossm_mailbox.h | 11 | ||||
| -rw-r--r-- | drivers/ddr/altera/sdram_agilex5.c | 19 | ||||
| -rw-r--r-- | drivers/ddr/altera/sdram_soc64.c | 54 | ||||
| -rw-r--r-- | drivers/reset/reset-socfpga.c | 3 |
5 files changed, 257 insertions, 55 deletions
diff --git a/drivers/ddr/altera/iossm_mailbox.c b/drivers/ddr/altera/iossm_mailbox.c index db9435db657..fc09dde3f9e 100644 --- a/drivers/ddr/altera/iossm_mailbox.c +++ b/drivers/ddr/altera/iossm_mailbox.c @@ -10,6 +10,7 @@ #include <asm/arch/base_addr_soc64.h> #include <asm/io.h> #include <linux/bitfield.h> +#include <linux/sizes.h> #include "iossm_mailbox.h" #define TIMEOUT_120000MS 120000 @@ -87,6 +88,7 @@ /* offset info of ECC_ENABLE_INTF */ #define INTF_ECC_ENABLE_TYPE_MASK GENMASK(1, 0) +#define INTF_ECC_TYPE_MASK BIT(8) /* cmd opcode BIST_MEM_INIT_START, BIST performed on full memory address range */ #define BIST_FULL_MEM BIT(6) @@ -96,6 +98,7 @@ /* offset info of ECC_ERR_STATUS */ #define ECC_ERR_COUNTER_MASK GENMASK(15, 0) +#define ECC_ERR_OVERFLOW_MASK GENMASK(31, 16) /* offset info of ECC_ERR_DATA */ #define ECC_ERR_IP_TYPE_MASK GENMASK(24, 22) @@ -104,9 +107,15 @@ #define ECC_ERR_TYPE_MASK GENMASK(9, 6) #define ECC_ERR_ADDR_UPPER_MASK GENMASK(5, 0) #define ECC_ERR_ADDR_LOWER_MASK GENMASK(31, 0) +#define ECC_FULL_ADDR_UPPER_MASK GENMASK(63, 32) +#define ECC_FULL_ADDR_LOWER_MASK GENMASK(31, 0) #define MAX_ECC_ERR_INFO_COUNT 16 +#define BIST_START_ADDR_SPACE_MASK GENMASK(5, 0) +#define BIST_START_ADDR_LOW_MASK GENMASK(31, 0) +#define BIST_START_ADDR_HIGH_MASK GENMASK(37, 32) + #define IO96B_MB_REQ_SETUP(v, w, x, y, z) \ usr_req.ip_type = v; \ usr_req.ip_id = w; \ @@ -161,6 +170,24 @@ struct ecc_err_info { u32 addr_lower; }; +struct ecc_overflow_error_desc { + int bit; + const char *msg; +}; + +static const struct ecc_overflow_error_desc ecc_overflow_errors[] = { + { 0, " - Single-bit error\n" }, + { 1, " - Multiple single-bit errors\n" }, + { 2, " - Double-bit error\n" }, + { 3, " - Multiple double-bit errors\n" }, + { 8, " - Single-bit error during ECC scrubbing\n" }, + { 9, " - Write link ECC single-bit error (LPDDR5 only)\n" }, + { 10, " - Write link ECC double-bit error (LPDDR5 only)\n" }, + { 11, " - Read link ECC single-bit error (LPDDR5 only)\n" }, + { 12, " - Read link ECC double-bit error (LPDDR5 only)\n" }, + { 13, " - RMW read link ECC double-bit error (LPDDR5 only)\n" }, +}; + static int is_ddr_csr_clkgen_locked(u8 io96b_pll) { int ret = 0; @@ -512,7 +539,7 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl) { int i, j, ret = 0; u32 mem_width_info; - u16 memory_size, total_memory_size = 0; + phys_size_t memory_size, total_memory_size = 0; u32 mem_total_capacity_intf_offset[MAX_MEM_INTERFACE_SUPPORTED] = { IOSSM_MEM_TOTAL_CAPACITY_INTF0_OFFSET, @@ -526,8 +553,11 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl) mem_width_info = readl(io96b_ctrl->io96b[i].io96b_csr_addr + mem_total_capacity_intf_offset[j]); - memory_size = memory_size + - FIELD_GET(INTF_CAPACITY_GBITS_MASK, mem_width_info); + io96b_ctrl->io96b[i].mb_ctrl.memory_size[j] = + FIELD_GET(INTF_CAPACITY_GBITS_MASK, mem_width_info) * SZ_1G / SZ_8; + + if (io96b_ctrl->io96b[i].mb_ctrl.memory_size[j] != 0) + memory_size += io96b_ctrl->io96b[i].mb_ctrl.memory_size[j]; } if (!memory_size) { @@ -536,8 +566,6 @@ int get_mem_width_info(struct io96b_info *io96b_ctrl) goto err; } - io96b_ctrl->io96b[i].size = memory_size; - total_memory_size = total_memory_size + memory_size; } @@ -556,7 +584,7 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl) { int i, j, ret = 0; u32 ecc_enable_intf; - bool ecc_stat, ecc_stat_set = false; + bool ecc_status, ecc_status_set = false, inline_ecc = false; u32 ecc_enable_intf_offset[MAX_MEM_INTERFACE_SUPPORTED] = { IOSSM_ECC_ENABLE_INTF0_OFFSET, @@ -565,6 +593,7 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl) /* Initialize ECC status */ io96b_ctrl->ecc_status = false; + io96b_ctrl->inline_ecc = false; /* Get and ensure all memory interface(s) same ECC status */ for (i = 0; i < io96b_ctrl->num_instance; i++) { @@ -572,15 +601,21 @@ int ecc_enable_status(struct io96b_info *io96b_ctrl) ecc_enable_intf = readl(io96b_ctrl->io96b[i].io96b_csr_addr + ecc_enable_intf_offset[j]); - ecc_stat = (FIELD_GET(INTF_ECC_ENABLE_TYPE_MASK, ecc_enable_intf) + ecc_status = (FIELD_GET(INTF_ECC_ENABLE_TYPE_MASK, ecc_enable_intf) == 0) ? false : true; + inline_ecc = FIELD_GET(INTF_ECC_TYPE_MASK, ecc_enable_intf); + + if (!ecc_status_set) { + io96b_ctrl->ecc_status = ecc_status; + + if (io96b_ctrl->ecc_status) + io96b_ctrl->inline_ecc = inline_ecc; - if (!ecc_stat_set) { - io96b_ctrl->ecc_status = ecc_stat; - ecc_stat_set = true; + ecc_status_set = true; } - if (ecc_stat != io96b_ctrl->ecc_status) { + if (ecc_status != io96b_ctrl->ecc_status || + (io96b_ctrl->ecc_status && inline_ecc != io96b_ctrl->inline_ecc)) { printf("%s: Mismatch DDR ECC status on IO96B_%d\n", __func__, i); ret = -EINVAL; @@ -614,16 +649,28 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl) { int i, j; u32 ecc_err_status; - u16 ecc_err_counter; + u16 ecc_err_counter, ecc_overflow_status; bool ecc_error_flag = false; /* Get ECC double-bit error status */ for (i = 0; i < io96b_ctrl->num_instance; i++) { ecc_err_status = readl(io96b_ctrl->io96b[i].io96b_csr_addr + IOSSM_ECC_ERR_STATUS_OFFSET); + ecc_err_counter = FIELD_GET(ECC_ERR_COUNTER_MASK, ecc_err_status); - debug("%s: ECC error number detected on IO96B_%d: %d\n", - __func__, i, ecc_err_counter); + log_err("%s: ECC error number detected on IO96B_%d: %d\n", + __func__, i, ecc_err_counter); + + ecc_overflow_status = FIELD_GET(ECC_ERR_OVERFLOW_MASK, ecc_err_status); + if (ecc_overflow_status != 0) { + log_err("ECC Error Overflow Flags:\n"); + + for (int i = 0; i < ARRAY_SIZE(ecc_overflow_errors); i++) { + if (ecc_overflow_status & BIT(ecc_overflow_errors[i].bit)) { + log_err("%s", ecc_overflow_errors[i].msg); + } + } + } if (ecc_err_counter != 0) { phys_addr_t address; @@ -647,15 +694,20 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl) ecc_err_data); err_info.addr_lower = readl(address + sizeof(u32)); - debug("%s: ECC double-bit error detected on IO96B_%d:\n", - __func__, i); - debug("- error info address :0x%llx\n", address); - debug("- error ip type: %d\n", err_info.ip_type); - debug("- error instance id: %d\n", err_info.instance_id); - debug("- error source id: %d\n", err_info.source_id); - debug("- error type: %d\n", err_info.err_type); - debug("- error address upper: 0x%x\n", err_info.addr_upper); - debug("- error address lower: 0x%x\n", err_info.addr_lower); + log_err(" %s: DDR ECC Error Detected on IO96B_%d number:%d\n", + __func__, i, j); + log_err(" - error info address :0x%llx\n", address); + log_err(" - error ip type: %d\n", err_info.ip_type); + log_err(" - error instance id: %d\n", err_info.instance_id); + log_err(" - error source id: %d\n", err_info.source_id); + log_err(" - error type: %s\n", + is_double_bit_error(err_info.err_type) ? + "Double-bit error" : "Single-bit error"); + log_err(" - error address: 0x%016llx\n", + (u64)FIELD_PREP(ECC_FULL_ADDR_UPPER_MASK, + err_info.addr_upper) | + FIELD_PREP(ECC_FULL_ADDR_LOWER_MASK, + err_info.addr_lower)); if (is_double_bit_error(err_info.err_type)) { if (!ecc_error_flag) @@ -668,12 +720,12 @@ bool ecc_interrupt_status(struct io96b_info *io96b_ctrl) } if (ecc_error_flag) - printf("\n%s: ECC double-bit error detected!\n", __func__); + log_err("\n%s: ECC double-bit error detected!\n", __func__); return ecc_error_flag; } -int bist_mem_init_start(struct io96b_info *io96b_ctrl) +int out_of_band_bist_mem_init_start(struct io96b_info *io96b_ctrl) { struct io96b_mb_req usr_req; struct io96b_mb_resp usr_resp; @@ -746,3 +798,126 @@ int bist_mem_init_start(struct io96b_info *io96b_ctrl) err: return ret; } + +int bist_mem_init_by_addr(struct io96b_info *io96b_ctrl, int inst_id, int intf_id, + phys_addr_t base_addr, phys_size_t size) +{ + struct io96b_mb_req usr_req; + struct io96b_mb_resp usr_resp; + int n, ret = 0; + bool bist_start, bist_success; + u32 mem_exp, mem_init_status_intf, start; + phys_size_t chunk_size; + + u32 mem_init_status_offset[MAX_MEM_INTERFACE_SUPPORTED] = { + IOSSM_MEM_INIT_STATUS_INTF0_OFFSET, + IOSSM_MEM_INIT_STATUS_INTF1_OFFSET + }; + + /* Check if size is a power of 2 */ + if (size == 0 || (size & (size - 1)) != 0) { + ret = -EINVAL; + goto err; + } + + mem_exp = 0; + chunk_size = size; + + while (chunk_size >>= 1) + mem_exp++; + + /* Start memory initialization BIST on the specified address range */ + IO96B_MB_REQ_SETUP(io96b_ctrl->io96b[inst_id].mb_ctrl.ip_type[intf_id], + io96b_ctrl->io96b[inst_id].mb_ctrl.ip_id[intf_id], + CMD_TRIG_CONTROLLER_OP, BIST_MEM_INIT_START, 0); + + /* CMD_PARAM_0 bit[5:0] = mem_exp */ + /* CMD_PARAM_0 bit[6]: 0 - on the specified address range */ + usr_req.cmd_param[0] = FIELD_PREP(BIST_START_ADDR_SPACE_MASK, mem_exp); + /* Extract address fields START_ADDR[31:0] */ + usr_req.cmd_param[1] = FIELD_GET(BIST_START_ADDR_LOW_MASK, base_addr); + /* Extract address fields START_ADDR[37:32] */ + usr_req.cmd_param[2] = FIELD_GET(BIST_START_ADDR_HIGH_MASK, base_addr); + /* Initialize memory to all zeros */ + usr_req.cmd_param[3] = 0; + + bist_start = false; + bist_success = false; + + /* Send request to DDR controller */ + debug("%s:Initializing memory: Addr=0x%llx, Size=2^%u\n", __func__, + base_addr, mem_exp); + ret = io96b_mb_req(io96b_ctrl->io96b[inst_id].io96b_csr_addr, + usr_req, 0, &usr_resp); + if (ret) + goto err; + + bist_start = IOSSM_CMD_RESPONSE_DATA_SHORT(usr_resp.cmd_resp_status) + & BIT(0); + + if (!bist_start) { + printf("%s: Failed to initialize memory on IO96B_%d\n", __func__, + inst_id); + printf("%s: BIST_MEM_INIT_START Error code 0x%lx\n", __func__, + IOSSM_STATUS_CMD_RESPONSE_ERROR(usr_resp.cmd_resp_status)); + + ret = -EINVAL; + goto err; + } + + /* Polling for the initiated memory initialization BIST status */ + start = get_timer(0); + while (!bist_success) { + udelay(1); + + mem_init_status_intf = readl(io96b_ctrl->io96b[inst_id].io96b_csr_addr + + mem_init_status_offset[intf_id]); + + bist_success = FIELD_GET(INTF_BIST_STATUS_MASK, mem_init_status_intf); + + if (!bist_success && (get_timer(start) > TIMEOUT)) { + printf("%s: Timeout initialize memory on IO96B_%d\n", + __func__, inst_id); + printf("%s: BIST_MEM_INIT_STATUS Error code 0x%lx\n", + __func__, + IOSSM_STATUS_CMD_RESPONSE_ERROR(usr_resp.cmd_resp_status)); + + ret = -ETIMEDOUT; + goto err; + } + } + + debug("%s:DDR memory initializationat 0x%llx completed.\n", __func__, base_addr); + +err: + return ret; +} + +int inline_ecc_bist_mem_init(struct io96b_info *io96b_ctrl) +{ + int i, j, ret = 0; + + /* Memory initialization BIST performed on all memory interfaces */ + for (i = 0; i < io96b_ctrl->num_instance; i++) { + for (j = 0; j < io96b_ctrl->io96b[i].mb_ctrl.num_mem_interface; j++) { + ret = bist_mem_init_by_addr(io96b_ctrl, i, j, 0, + io96b_ctrl->io96b[i].mb_ctrl.memory_size[j]); + if (ret) { + printf("Error: Memory init failed at Instance %d, Interface %d\n", + i, j); + goto err; + } + } + } + +err: + return ret; +} + +int bist_mem_init_start(struct io96b_info *io96b_ctrl) +{ + if (io96b_ctrl->inline_ecc) + return inline_ecc_bist_mem_init(io96b_ctrl); + else + return out_of_band_bist_mem_init_start(io96b_ctrl); +} diff --git a/drivers/ddr/altera/iossm_mailbox.h b/drivers/ddr/altera/iossm_mailbox.h index 6f794781d30..02d1db28e20 100644 --- a/drivers/ddr/altera/iossm_mailbox.h +++ b/drivers/ddr/altera/iossm_mailbox.h @@ -40,11 +40,13 @@ enum iossm_mailbox_cmd_opcode { * @num_mem_interface: Number of memory interfaces instantiated * @ip_type: IP type implemented on the IO96B * @ip_instance_id: IP identifier for every IP instance implemented on the IO96B + * @memory_size[2]: Memory size for every IP instance implemented on the IO96B */ struct io96b_mb_ctrl { u32 num_mem_interface; u32 ip_type[2]; u32 ip_id[2]; + phys_size_t memory_size[2]; }; /* CMD_REQ Register Definition */ @@ -53,6 +55,9 @@ struct io96b_mb_ctrl { #define CMD_TYPE_MASK GENMASK(23, 16) #define CMD_OPCODE_MASK GENMASK(15, 0) +/* Computes the Inline ECC data region size */ +#define CALC_INLINE_ECC_HW_SIZE(size) (((size) * 7) / 8) + /* * IOSSM mailbox request * @ip_type: IP type for the specified memory interface @@ -83,13 +88,11 @@ struct io96b_mb_resp { /* * IO96B instance specific information * - * @size: Memory size * @io96b_csr_addr: IO96B instance CSR address * @cal_status: IO96B instance calibration status * @mb_ctrl: IOSSM mailbox required information */ struct io96b_instance { - u16 size; phys_addr_t io96b_csr_addr; bool cal_status; struct io96b_mb_ctrl mb_ctrl; @@ -102,6 +105,7 @@ struct io96b_instance { * @overall_cal_status: Overall calibration status for all IO96B instance(s) * @ddr_type: DDR memory type * @ecc_status: ECC enable status (false = disabled, true = enabled) + * @inline_ecc: Inline ECC or Out of Band ECC (false = Out of Band ECC, true = Inline ECC) * @overall_size: Total DDR memory size * @io96b[]: IO96B instance specific information * @ckgen_lock: IO96B GEN PLL lock (false = not locked, true = locked) @@ -115,7 +119,8 @@ struct io96b_info { bool overall_cal_status; const char *ddr_type; bool ecc_status; - u16 overall_size; + bool inline_ecc; + phys_size_t overall_size; struct io96b_instance io96b[MAX_IO96B_SUPPORTED]; bool ckgen_lock; u8 num_port; diff --git a/drivers/ddr/altera/sdram_agilex5.c b/drivers/ddr/altera/sdram_agilex5.c index 801a6bbab46..ee66c72157a 100644 --- a/drivers/ddr/altera/sdram_agilex5.c +++ b/drivers/ddr/altera/sdram_agilex5.c @@ -291,7 +291,14 @@ int sdram_mmr_init_full(struct udevice *dev) goto err; } - hw_size = (phys_size_t)io96b_ctrl->overall_size * SZ_1G / SZ_8; + ret = ecc_enable_status(io96b_ctrl); + if (ret) { + printf("DDR: Failed to get ECC enabled status\n"); + + goto err; + } + + hw_size = io96b_ctrl->overall_size; /* Get bank configuration from devicetree */ ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL, @@ -303,6 +310,9 @@ int sdram_mmr_init_full(struct udevice *dev) goto err; } + if (io96b_ctrl->inline_ecc) + hw_size = CALC_INLINE_ECC_HW_SIZE(hw_size); + if (gd->ram_size > hw_size) { printf("DDR: Warning: DRAM size from device tree (%lld MiB) exceeds\n", gd->ram_size >> 20); @@ -355,13 +365,6 @@ int sdram_mmr_init_full(struct udevice *dev) printf("%s: %lld MiB\n", io96b_ctrl->ddr_type, gd->ram_size >> 20); - ret = ecc_enable_status(io96b_ctrl); - if (ret) { - printf("DDR: Failed to get ECC enabled status\n"); - - goto err; - } - /* Is HPS cold or warm reset? If yes, Skip full memory initialization if ECC * enabled to preserve memory content */ diff --git a/drivers/ddr/altera/sdram_soc64.c b/drivers/ddr/altera/sdram_soc64.c index c8c9211adce..27fbe80ed41 100644 --- a/drivers/ddr/altera/sdram_soc64.c +++ b/drivers/ddr/altera/sdram_soc64.c @@ -185,35 +185,51 @@ void sdram_init_ecc_bits(struct bd_info *bd) void sdram_size_check(struct bd_info *bd) { phys_size_t total_ram_check = 0; - phys_size_t ram_check = 0; - phys_addr_t start = 0; - phys_size_t size, remaining_size; int bank; /* Sanity check ensure correct SDRAM size specified */ debug("DDR: Running SDRAM size sanity check\n"); for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + phys_size_t ram_check = 0; + phys_addr_t start = 0; + phys_size_t remaining_size; + start = bd->bi_dram[bank].start; remaining_size = bd->bi_dram[bank].size; + debug("Checking bank %d: start=0x%llx, size=0x%llx\n", + bank, start, remaining_size); + while (ram_check < bd->bi_dram[bank].size) { - size = min((phys_addr_t)SZ_1G, - (phys_addr_t)remaining_size); - - /* - * Ensure the size is power of two, this is requirement - * to run get_ram_size() / memory test - */ - if (size != 0 && ((size & (size - 1)) == 0)) { - ram_check += get_ram_size((void *) - (start + ram_check), size); - remaining_size = bd->bi_dram[bank].size - - ram_check; - } else { - puts("DDR: Memory test requires SDRAM size "); - puts("in power of two!\n"); + phys_size_t size, test_size, detected_size; + + size = min((phys_addr_t)SZ_1G, (phys_addr_t)remaining_size); + + if (size < SZ_8) { + puts("Invalid size: Memory size required to be multiple\n"); + puts("of 64-Bit word!\n"); hang(); } + + /* Adjust size to the nearest power of two to support get_ram_size() */ + test_size = SZ_8; + + while (test_size * 2 <= size) + test_size *= 2; + + debug("Testing memory at 0x%llx with size 0x%llx\n", + start + ram_check, test_size); + detected_size = get_ram_size((void *)(start + ram_check), test_size); + + if (detected_size != test_size) { + debug("Detected size 0x%llx doesn’t match the test size 0x%llx!\n", + detected_size, test_size); + puts("Memory testing failed!\n"); + hang(); + } + + ram_check += detected_size; + remaining_size = bd->bi_dram[bank].size - ram_check; } total_ram_check += ram_check; @@ -249,7 +265,7 @@ phys_size_t sdram_calculate_size(struct altera_sdram_plat *plat) DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw) + DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw)); - size *= (2 << (hmc_ecc_readl(plat, DDRIOCTRL) & + size *= ((phys_size_t)2 << (hmc_ecc_readl(plat, DDRIOCTRL) & DDR_HMC_DDRIOCTRL_IOSIZE_MSK)); return size; diff --git a/drivers/reset/reset-socfpga.c b/drivers/reset/reset-socfpga.c index 76d108080d9..e57729f0ef9 100644 --- a/drivers/reset/reset-socfpga.c +++ b/drivers/reset/reset-socfpga.c @@ -23,6 +23,7 @@ #include <linux/bitops.h> #include <linux/io.h> #include <linux/sizes.h> +#include <linux/kconfig.h> #define BANK_INCREMENT 4 #define NR_BANKS 8 @@ -114,6 +115,8 @@ static int socfpga_reset_remove(struct udevice *dev) if (socfpga_reset_keep_enabled()) { puts("Deasserting all peripheral resets\n"); writel(0, data->modrst_base + 4); + if (IS_ENABLED(CONFIG_TARGET_SOCFPGA_ARRIA10)) + writel(0, data->modrst_base + 8); } return 0; |
