* Re: [PATCH v4 01/15] misc: fs_loader: Add QSPI RAW offset loading support
[not found] ` <20261016044047.21496-2-chen.huei.lok@altera.com>
@ 2026-10-21 1:55 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 1:55 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> Add support for loading data from a QSPI RAW flash offset through the
> generic firmware loader. Consumers include the DDR calibration backup
> restore path, and optionally FPGA bitstream loading from QSPI.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> doc/device-tree-bindings/misc/fs_loader.txt | 8 ++
> drivers/misc/fs_loader.c | 99 +++++++++++++++++----
> include/fs_loader.h | 33 ++++++-
> 3 files changed, 120 insertions(+), 20 deletions(-)
>
> diff --git a/doc/device-tree-bindings/misc/fs_loader.txt b/doc/device-tree-bindings/misc/fs_loader.txt
> index 542be4b25a0..8ee59db24d5 100644
> --- a/doc/device-tree-bindings/misc/fs_loader.txt
> +++ b/doc/device-tree-bindings/misc/fs_loader.txt
> @@ -12,6 +12,7 @@ Required properties:
> required for ubi and mounting.
> - ubivol: which volume of ubi the image loading from, this property is required
> for ubi and mounting.
> +- sfconfig: should only contain "bus number" and "chip selection".
>
> Example of storage device and partition search set for mmc, usb, sata and
> ubi in device tree source as shown in below:
> @@ -46,3 +47,10 @@ ubi in device tree source as shown in below:
> mtdpart = "UBI",
> ubivol = "ubi0";
> };
> +
> + Example for qspi:
> + fs_loader4: fs-loader@4 {
> + bootph-all;
> + compatible = "u-boot,fs-loader";
> + sfconfig = <0 0>;
> + };
> diff --git a/drivers/misc/fs_loader.c b/drivers/misc/fs_loader.c
> index 6af4c7f15e7..293db94dd29 100644
> --- a/drivers/misc/fs_loader.c
> +++ b/drivers/misc/fs_loader.c
> @@ -19,6 +19,7 @@
> #include <mapmem.h>
> #include <malloc.h>
> #include <spl.h>
> +#include <spi_flash.h>
>
> #ifdef CONFIG_CMD_UBIFS
> #include <ubi_uboot.h>
> @@ -121,16 +122,31 @@ static int _request_firmware_prepare(struct udevice *dev,
> const char *name, void *dbuf,
> size_t size, u32 offset)
> {
> - if (!name || name[0] == '\0')
> - return -EINVAL;
> -
> struct firmware *firmwarep = dev_get_priv(dev);
> + struct device_plat *plat = dev_get_plat(dev);
> + char *endptr;
> + u32 fw_offset;
>
> if (!firmwarep)
> return -ENOMEM;
>
> + if (plat->data_type == DATA_RAW) {
> + if (!name)
> + return -EINVAL;
> +
> + fw_offset = simple_strtoul(name, &endptr, 16);
> + if (name == endptr || *endptr != '\0')
> + return -EINVAL;
> +
> + firmwarep->offset = fw_offset + offset;
> + } else {
> + if (!name || name[0] == '\0')
> + return -EINVAL;
> +
> + firmwarep->offset = offset;
> + }
> +
> firmwarep->name = name;
> - firmwarep->offset = offset;
> firmwarep->data = dbuf;
> firmwarep->size = size;
>
> @@ -146,13 +162,17 @@ static int _request_firmware_prepare(struct udevice *dev,
> static int fw_get_filesystem_firmware(struct udevice *dev)
> {
> loff_t actread = 0;
> - char *storage_interface, *dev_part, *ubi_mtdpart, *ubi_volume;
> - int ret;
> + char *storage_interface = NULL, *dev_part = NULL;
> + char *ubi_mtdpart = NULL, *ubi_volume = NULL;
> + int ret = 0;
> + struct device_plat *plat = dev_get_plat(dev);
>
> - storage_interface = env_get("storage_interface");
> - dev_part = env_get("fw_dev_part");
> - ubi_mtdpart = env_get("fw_ubi_mtdpart");
> - ubi_volume = env_get("fw_ubi_volume");
> + if (CONFIG_IS_ENABLED(ENV_SUPPORT)) {
> + storage_interface = env_get("storage_interface");
> + dev_part = env_get("fw_dev_part");
> + ubi_mtdpart = env_get("fw_ubi_mtdpart");
> + ubi_volume = env_get("fw_ubi_volume");
> + }
>
> if (storage_interface && dev_part) {
> ret = fs_set_blk_dev(storage_interface, dev_part, FS_TYPE_ANY);
> @@ -167,7 +187,8 @@ static int fw_get_filesystem_firmware(struct udevice *dev)
> else
> ret = -ENODEV;
> } else {
> - ret = select_fs_dev(dev_get_plat(dev));
> + if (plat->data_type == DATA_FS)
> + ret = select_fs_dev(dev_get_plat(dev));
> }
>
> if (ret)
> @@ -178,8 +199,20 @@ static int fw_get_filesystem_firmware(struct udevice *dev)
> if (!firmwarep)
> return -ENOMEM;
>
> - ret = fs_read(firmwarep->name, (ulong)map_to_sysmem(firmwarep->data),
> - firmwarep->offset, firmwarep->size, &actread);
> + if (plat->data_type == DATA_FS)
> + ret = fs_read(firmwarep->name,
> + (ulong)map_to_sysmem(firmwarep->data),
> + firmwarep->offset, firmwarep->size, &actread);
> + else if (plat->data_type == DATA_RAW) {
> + if (IS_ENABLED(CONFIG_SPI_FLASH)) {
> + ret = spi_flash_read_dm(plat->flash, firmwarep->offset,
> + firmwarep->size,
> + (void *)firmwarep->data);
> + actread = firmwarep->size;
> + } else {
> + ret = -ENOSYS;
> + }
> + }
>
> if (ret) {
> debug("Error: %d Failed to read %s from flash %lld != %zu.\n",
> @@ -228,6 +261,7 @@ int request_firmware_into_buf(struct udevice *dev,
> static int fs_loader_of_to_plat(struct udevice *dev)
> {
> u32 phandlepart[2];
> + u32 sfconfig[2];
>
> ofnode fs_loader_node = dev_ofnode(dev);
>
> @@ -247,6 +281,15 @@ static int fs_loader_of_to_plat(struct udevice *dev)
>
> plat->ubivol = (char *)ofnode_read_string(
> fs_loader_node, "ubivol");
> +
> + if (!ofnode_read_u32_array(fs_loader_node, "sfconfig", sfconfig,
> + 2)) {
> + plat->data_type = DATA_RAW;
> + plat->sfconfig.bus = sfconfig[0];
> + plat->sfconfig.cs = sfconfig[1];
> + } else {
> + plat->data_type = DATA_FS;
> + }
> }
>
> return 0;
> @@ -254,11 +297,30 @@ static int fs_loader_of_to_plat(struct udevice *dev)
>
> static int fs_loader_probe(struct udevice *dev)
> {
> -#if CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(BLK)
> - int ret;
> + int ret = 0;
> struct device_plat *plat = dev_get_plat(dev);
>
> - if (plat->phandlepart.phandle) {
> + if (IS_ENABLED(CONFIG_SPI_FLASH) &&
> + plat->data_type == DATA_RAW && !plat->flash) {
> + debug("bus = %d\ncs = %d\n",
> + plat->sfconfig.bus, plat->sfconfig.cs);
> +
> + ret = spi_flash_probe_bus_cs(plat->sfconfig.bus,
> + plat->sfconfig.cs,
> + &plat->flash);
> + if (ret) {
> + debug("fs_loader: Failed to initialize SPI flash at ");
> + debug("%u:%u (error %d)\n", plat->sfconfig.bus,
> + plat->sfconfig.cs, ret);
> + return -ENODEV;
> + }
> +
> + if (!plat->flash)
> + return -EINVAL;
> + }
> +
> + if (CONFIG_IS_ENABLED(DM) && CONFIG_IS_ENABLED(BLK) &&
> + plat->phandlepart.phandle) {
> ofnode node = ofnode_get_by_phandle(plat->phandlepart.phandle);
> struct udevice *parent_dev = NULL;
>
> @@ -269,15 +331,14 @@ static int fs_loader_probe(struct udevice *dev)
> ret = blk_get_from_parent(parent_dev, &dev);
> if (ret) {
> debug("fs_loader: No block device: %d\n",
> - ret);
> + ret);
>
> return ret;
> }
> }
> }
> -#endif
>
> - return 0;
> + return ret;
> };
>
> static const struct udevice_id fs_loader_ids[] = {
> diff --git a/include/fs_loader.h b/include/fs_loader.h
> index 7e16e0f7030..f9c073fee6e 100644
> --- a/include/fs_loader.h
> +++ b/include/fs_loader.h
> @@ -23,18 +23,49 @@ struct phandle_part {
> };
>
> /**
> - * struct phandle_part - A place for storing all supported storage devices
> + * struct sf_config - A place for storing serial flash configuration
> + *
> + * This holds information about bus and chip-select of a serial flash
> + * configuration.
> + *
> + * @bus: SPI bus number.
> + * @cs: SPI chip selection.
> + */
> +struct sf_config {
> + u32 bus;
> + u32 cs;
> +};
> +
> +/**
> + * enum data_flags - Flag to indicate data as RAW or as filesystem
> + *
> + * DATA_RAW: Data stored as RAW.
> + * DATA_FS: DATA stored as filesystem.
> + */
> +enum data_flags {
> + DATA_RAW, /* Stored in raw */
> + DATA_FS, /* Stored within a file system */
> +};
> +
> +/**
> + * struct device_plat - A place for storing all supported storage devices
> *
> * This holds information about all supported storage devices for driver use.
> *
> * @phandlepart: Attribute data for block device.
> * @mtdpart: MTD partition for ubi partition.
> * @ubivol: UBI volume-name for ubifsmount.
> + * @data_type: Data type (RAW or filesystem).
> + * @sfconfig: Serial flash configuration.
> + * @flash: SPI flash device used for RAW offset reads.
> */
> struct device_plat {
> struct phandle_part phandlepart;
> char *mtdpart;
> char *ubivol;
> + enum data_flags data_type;
> + struct sf_config sfconfig;
> + struct udevice *flash;
> };
>
> /**
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 02/15] arm: dts: socfpga: n5x: add DDR retention calibration backup nodes
[not found] ` <20261016044047.21496-3-chen.huei.lok@altera.com>
@ 2026-10-21 2:07 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:07 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> Add the device tree nodes that the N5X DDR retention restore path depends
> on. Reintroduce the fs-loader node and the &sdr DDR calibration backup
> properties (firmware-loader, intel,ddrcal-qspi-offset and
> intel,ddrcal-ddr-offset) that were dropped during the switch to the
> upstream Linux DT config. These describe where the backup calibration
> data is stored and the firmware-loader instance used to read it back in
> SPL.
>
> Document the intel,sdr-ctl-n5x retention properties in
> doc/device-tree-bindings/ram/intel,sdr-ctl-n5x.txt, including the QSPI
> calibration-restore trust model (System Manager retention bit plus flash
> integrity checks) and fail-closed behaviour, and add an F: entry under
> ARM ALTERA SOCFPGA in MAINTAINERS for that binding path.
>
> Use bootph-all in place of the legacy u-boot,dm-pre-reloc so the nodes
> are bound in the pre-relocation SPL phase on the migrated device tree.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> MAINTAINERS | 1 +
> arch/arm/dts/socfpga_n5x_socdk-u-boot.dtsi | 13 ++++++
> .../ram/intel,sdr-ctl-n5x.txt | 44 +++++++++++++++++++
> 3 files changed, 58 insertions(+)
> create mode 100644 doc/device-tree-bindings/ram/intel,sdr-ctl-n5x.txt
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 420a3bbf730..3f83a3b11a1 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -181,6 +181,7 @@ M: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> M: Tien Fong Chee <tien.fong.chee@altera.com>
> S: Maintained
> T: git https://git.u-boot-project.org/u-boot/custodians/u-boot-socfpga.git
> +F: doc/device-tree-bindings/ram/intel,sdr-ctl-n5x.txt
> N: altera
> N: agilex
> N: socfpga
> diff --git a/arch/arm/dts/socfpga_n5x_socdk-u-boot.dtsi b/arch/arm/dts/socfpga_n5x_socdk-u-boot.dtsi
> index 3de75f36cbb..ea95d04d37d 100644
> --- a/arch/arm/dts/socfpga_n5x_socdk-u-boot.dtsi
> +++ b/arch/arm/dts/socfpga_n5x_socdk-u-boot.dtsi
> @@ -8,6 +8,12 @@
> #include "socfpga_n5x-u-boot.dtsi"
>
> /{
> + fs_loader0: fs-loader {
> + bootph-all;
> + compatible = "u-boot,fs-loader";
> + sfconfig = <0 0>;
> + };
> +
> chosen {
> u-boot,spl-boot-order = &mmc;
> };
> @@ -36,6 +42,13 @@
> };
> };
>
> +&sdr {
> + intel,ddrcal-qspi-offset = "0x7000000";
> + intel,ddrcal-ddr-offset = "0x100000";
> + firmware-loader = <&fs_loader0>;
> + bootph-all;
> +};
> +
> &flash0 {
> bootph-all;
> cdns,page-size = <256>;
> diff --git a/doc/device-tree-bindings/ram/intel,sdr-ctl-n5x.txt b/doc/device-tree-bindings/ram/intel,sdr-ctl-n5x.txt
> new file mode 100644
> index 00000000000..a86e7efdfb9
> --- /dev/null
> +++ b/doc/device-tree-bindings/ram/intel,sdr-ctl-n5x.txt
> @@ -0,0 +1,44 @@
> +* Intel N5X SDRAM controller
> +
> +Required properties:
> +--------------------
> +- compatible: must be "intel,sdr-ctl-n5x"
> +
> +Optional properties (DDR retention):
> +------------------------------------
> +- intel,ddrcal-qspi-offset: string, hex byte offset of the calibration
> + backup in QSPI (e.g. "0x7000000"). Used by SPL to load the backup
> + via the firmware loader.
> +- intel,ddrcal-ddr-offset: string, hex address in DRAM where a valid
> + backup is copied after a successful restore (e.g. "0x100000").
> +- firmware-loader: phandle to a "u-boot,fs-loader" node used to read
> + the QSPI backup. If omitted, the loader under /chosen is used.
> +
> +Trust model (QSPI calibration restore):
> +---------------------------------------
> +Skipping PHY recalibration after a configuration reset is gated by the
> +System Manager DDR retention bit together with the reset type.
> +The QSPI-sourced calibration backup is treated as untrusted until
> +integrity checks pass. Restore is fail-closed: on any missing DT
> +property, flash read failure, header magic mismatch, oversized
> +data_len that would overflow the HPS handoff region, CRC32 mismatch
> +over the calibration payload, or SHA384 mismatch over the DDR
> +configuration image, U-Boot discards the backup and runs a full PHY
> +calibration instead.
> +
> +Example:
> +--------
> +
> + fs_loader0: fs-loader {
> + bootph-all;
> + compatible = "u-boot,fs-loader";
> + sfconfig = <0 0>;
> + };
> +
> + sdr {
> + compatible = "intel,sdr-ctl-n5x";
> + intel,ddrcal-qspi-offset = "0x7000000";
> + intel,ddrcal-ddr-offset = "0x100000";
> + firmware-loader = <&fs_loader0>;
> + bootph-all;
> + };
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 03/15] arm: socfpga: n5x: enable QSPI mailbox before DDR init
[not found] ` <20261016044047.21496-4-chen.huei.lok@altera.com>
@ 2026-10-21 2:09 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:09 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> Move the mbox_qspi_open() call ahead of DRAM initialization so the QSPI
> controller is handed over to the HPS and its reference clock is
> configured before the DDR retention path reads the calibration backup
> from QSPI during DDR init.
>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> arch/arm/mach-socfpga/spl_n5x.c | 7 +++----
> 1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm/mach-socfpga/spl_n5x.c b/arch/arm/mach-socfpga/spl_n5x.c
> index 381aca6d32f..bb2d6187ffc 100644
> --- a/arch/arm/mach-socfpga/spl_n5x.c
> +++ b/arch/arm/mach-socfpga/spl_n5x.c
> @@ -105,6 +105,9 @@ void board_init_f(ulong dummy)
> hang();
> }
>
> + if (IS_ENABLED(CONFIG_CADENCE_QSPI))
> + mbox_qspi_open();
> +
> #if CONFIG_IS_ENABLED(ALTERA_SDRAM)
> ret = uclass_get_device(UCLASS_RAM, 0, &dev);
> if (ret) {
> @@ -112,8 +115,4 @@ void board_init_f(ulong dummy)
> hang();
> }
> #endif
> -
> -#ifdef CONFIG_CADENCE_QSPI
> - mbox_qspi_open();
> -#endif
> }
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 04/15] ddr: altera: n5x: Add self-refresh support in DDR4
[not found] ` <20261016044047.21496-5-chen.huei.lok@altera.com>
@ 2026-10-21 2:14 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:14 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> Enable self-refresh support in DDR4 for retaining DDR4 content with
> minimal power when reset is triggered. On a configuration reset with
> retention enabled, the trained PHY calibration data is restored from a
> backup instead of running a full calibration, so the DDR contents are
> preserved across the reset.
>
> The same INIT0.skip_dram_init / PWRCTL self-refresh entry settings that
> LPDDR4 requires are also applied to DDR4, as some DDR4 chips need them to
> enter and exit retention correctly.
>
> The backup calibration data is copied to DDR only when DDR retention is
> enabled, and the backup header length ('cal->header.data_len') is
> validated against the HPS handoff region so a corrupted or oversized
> value cannot overflow into the handoff data before it is consumed.
>
> Look up the DDR controller node using the "intel,sdr-ctl-n5x" compatible
> string so it matches the node defined in the device tree.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> .../include/mach/system_manager_soc64.h | 3 +-
> drivers/ddr/altera/sdram_n5x.c | 869 ++++++++++++++++--
> 2 files changed, 790 insertions(+), 82 deletions(-)
[...]
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 05/15] configs: socfpga: n5x: enable required configs for DDR retention
[not found] ` <20261016044047.21496-6-chen.huei.lok@altera.com>
@ 2026-10-21 2:16 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:16 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> DDR retention lets N5X skip a full DDR re-calibration across a
> configuration reset by reusing previously calibrated PHY data, which
> significantly shortens bring-up time. To do this the SPL must, early in
> boot and before DRAM is usable, locate a known-good backup of the
> calibration data, verify it, and replay it into the DDR PHY before
> handoff. Enable the configs that this restore path depends on:
>
> - CONFIG_FS_LOADER / CONFIG_SPL_FS_LOADER: the generic firmware loader is
> used by the DDR driver (request_firmware_into_buf()) to pull the backup
> calibration header and data from the QSPI/NAND RAW partition into the
> OCRAM scratch buffer (SOC64_OCRAM_PHY_BACKUP_BASE). The loader device is
> resolved through the "firmware-loader" phandle on the DDR node, falling
> back to /chosen. SPL_FS_LOADER is required because the restore runs in
> SPL, before DRAM is available. The N5X RAW path binds SPI flash from DT
> (sfconfig), so CONFIG_SPL_ENV_SUPPORT is not required.
>
> - CONFIG_SPL_CRC32: the retention path checksums the calibration payload
> with crc32_wd_buf() when storing and validating the QSPI backup. SPL
> must build lib/crc32.c (obj-$(CONFIG_SPL_CRC32)), which is not selected
> by SHA384.
>
> - CONFIG_SHA384: the calibration backup is bound to the current DDR
> configuration with a SHA-384 digest (sha384_csum_wd() over the DDR
> handoff image and the mem-clk table). On store the digest is written
> into the backup header; on restore it is recomputed and compared
> (is_ddrconfig_hash_match()), so a backup that no longer matches the
> running DDR / mem-clk configuration is rejected. Enabling SHA384 selects
> the SHA-512 implementation it is built on, so CONFIG_SHA512_ALGO does
> not need to be listed explicitly.
>
> Init order and failure modes: the restore is best-effort and fully
> guarded. The buffer load is bounds-checked against the HPS handoff region
> (SOC64_HANDOFF_BASE) to prevent overflow, the header magic must match, a
> CRC32 over the data must match, and finally the SHA-384 config hash must
> match. If any check fails (missing loader, read error, bad magic, CRC or
> hash mismatch) the backup is discarded and DDR falls back to a normal
> full calibration, so an invalid or stale backup never corrupts bring-up.
>
> These symbols are enabled only after the fs_loader RAW-partition support
> and the N5X self-refresh / retention restore code that consume them, so
> the series stays bisectable. The defconfig is kept in canonical
> savedefconfig order.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> configs/socfpga_n5x_defconfig | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/configs/socfpga_n5x_defconfig b/configs/socfpga_n5x_defconfig
> index 2d9456ef435..2119d8f4f4f 100644
> --- a/configs/socfpga_n5x_defconfig
> +++ b/configs/socfpga_n5x_defconfig
> @@ -72,6 +72,8 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
> CONFIG_DWAPB_GPIO=y
> CONFIG_DM_I2C=y
> CONFIG_SYS_I2C_DW=y
> +CONFIG_FS_LOADER=y
> +CONFIG_SPL_FS_LOADER=y
> CONFIG_SYS_MMC_MAX_BLK_COUNT=256
> CONFIG_MMC_DW=y
> CONFIG_SPI_FLASH_ISSI=y
> @@ -93,4 +95,5 @@ CONFIG_WDT=y
> # CONFIG_SPL_USE_TINY_PRINTF is not set
> CONFIG_PANIC_HANG=y
> CONFIG_SPL_CRC32=y
> +CONFIG_SHA384=y
> # CONFIG_TOOLS_MKEFICAPSULE is not set
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 06/15] ddr: altera: n5x: set DDR init progress bit for watchdog recovery
[not found] ` <20261016044047.21496-7-chen.huei.lok@altera.com>
@ 2026-10-21 2:18 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:18 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> Bit[30] of the boot scratch cold 8 register tracks DDR init progress. SDM
> inspects it when the watchdog fires due to a DDR init hang, so that it can
> run a clean reset of the DDR subsystem before the next attempt.
>
> Set the bit when SDRAM init starts and clear it once the basic memory test
> has passed.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 4ac22c536fc..4da0617e37c 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -420,6 +420,18 @@ enum data_process {
> LOADING
> };
>
> +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);
> +}
> +
> bool is_ddr_retention_enabled(u32 reg)
> {
> if (reg & ALT_SYSMGR_SCRATCH_REG_0_DDR_RETENTION_MASK)
> @@ -2820,6 +2832,7 @@ int sdram_mmr_init_full(struct udevice *dev)
>
> if (!is_ddr_init_skipped(reg)) {
> printf("SDRAM init in progress ...\n");
> + ddr_init_inprogress(true);
>
> /*
> * Polling reset complete, must be high to ensure DDR
> @@ -2970,6 +2983,9 @@ int sdram_mmr_init_full(struct udevice *dev)
>
> sdram_size_check(&bd);
>
> + /* Marking end of ddr init with passing basic memory test */
> + ddr_init_inprogress(false);
> +
> sdram_set_firewall(&bd);
>
> if (is_ddr_retention_enabled(reg)) {
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 07/15] ddr: altera: n5x: re-init DDR when double-bit ECC error is detected
[not found] ` <20261016044047.21496-8-chen.huei.lok@altera.com>
@ 2026-10-21 2:20 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:20 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> A double-bit ECC error (DBE) means the retained DDR contents can no longer
> be trusted. Detect the DBE status and force a full DDR init and
> calibration in that case instead of taking the retention / warm-reset skip
> path.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 33 ++++++++++++++++++++++++---------
> 1 file changed, 24 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 4da0617e37c..1bbd5bb0082 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -420,6 +420,17 @@ enum data_process {
> LOADING
> };
>
> +bool is_ddr_dbe_triggered(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;
> +}
> +
> void ddr_init_inprogress(bool start)
> {
> if (start)
> @@ -478,17 +489,20 @@ bool is_ddr_init_skipped(u32 reg)
>
> reset_type_print(reset_t);
>
> - if (reset_t == WARM_RESET) {
> - debug("%s: DDR init is skipped\n", __func__);
> - return true;
> - }
> -
> - if (reset_t == COLD_RESET) {
> - if (is_ddr_retention_enabled(reg)) {
> - debug("%s: DDR retention bit is set\n", __func__);
> + if (!is_ddr_dbe_triggered()) {
> + if (reset_t == WARM_RESET) {
> debug("%s: DDR init is skipped\n", __func__);
> return true;
> }
> +
> + if (reset_t == COLD_RESET) {
> + if (is_ddr_retention_enabled(reg)) {
> + debug("%s: DDR retention bit is set\n",
> + __func__);
> + debug("%s: DDR init is skipped\n", __func__);
> + return true;
> + }
> + }
> }
>
> debug("%s: DDR init is required\n", __func__);
> @@ -500,7 +514,8 @@ bool is_ddr_calibration_skipped(u32 reg)
> enum reset_type reset_t = get_reset_type(reg);
>
> if ((reset_t == NCONFIG || reset_t == JTAG_CONFIG ||
> - reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg)) {
> + reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg) &&
> + !is_ddr_dbe_triggered()) {
> debug("%s: DDR retention bit is set\n", __func__);
> return true;
> }
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 08/15] ddr: altera: n5x: re-init DDR after watchdog reset from init hang
[not found] ` <20261016044047.21496-9-chen.huei.lok@altera.com>
@ 2026-10-21 2:21 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:21 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> If the previous DDR init hung and was recovered by a watchdog reset, the
> DDR state is undefined and must not be reused. Detect the init-hang
> indication and force a full DDR init and calibration instead of taking the
> retention skip path.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 29 +++++++++++++++++++++--------
> 1 file changed, 21 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 1bbd5bb0082..858f2e76aa9 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -420,6 +420,17 @@ enum data_process {
> LOADING
> };
>
> +bool is_ddr_init_hang(void)
> +{
> + u32 reg = readl(socfpga_get_sysmgr_addr() +
> + SYSMGR_SOC64_BOOT_SCRATCH_COLD8);
> +
> + if (reg & ALT_SYSMGR_SCRATCH_REG_8_DDR_PROGRESS_MASK)
> + return true;
> +
> + return false;
> +}
> +
> bool is_ddr_dbe_triggered(void)
> {
> u32 reg = readl(socfpga_get_sysmgr_addr() +
> @@ -483,13 +494,13 @@ void reset_type_print(enum reset_type reset_t)
> }
> }
>
> -bool is_ddr_init_skipped(u32 reg)
> +bool is_ddr_init_skipped(u32 reg, bool is_ddr_hang_be4_rst)
> {
> enum reset_type reset_t = get_reset_type(reg);
>
> reset_type_print(reset_t);
>
> - if (!is_ddr_dbe_triggered()) {
> + if (!is_ddr_dbe_triggered() && !is_ddr_hang_be4_rst) {
> if (reset_t == WARM_RESET) {
> debug("%s: DDR init is skipped\n", __func__);
> return true;
> @@ -509,13 +520,13 @@ bool is_ddr_init_skipped(u32 reg)
> return false;
> }
>
> -bool is_ddr_calibration_skipped(u32 reg)
> +bool is_ddr_calibration_skipped(u32 reg, bool is_ddr_hang_be4_rst)
> {
> enum reset_type reset_t = get_reset_type(reg);
>
> if ((reset_t == NCONFIG || reset_t == JTAG_CONFIG ||
> reset_t == RSU_RECONFIG) && is_ddr_retention_enabled(reg) &&
> - !is_ddr_dbe_triggered()) {
> + !is_ddr_dbe_triggered() && !is_ddr_hang_be4_rst) {
> debug("%s: DDR retention bit is set\n", __func__);
> return true;
> }
> @@ -1598,7 +1609,7 @@ static bool is_cal_bak_data_valid(void)
> }
>
> static int init_phy(struct ddr_handoff *ddr_handoff_info,
> - bool *need_calibrate)
> + bool *need_calibrate, bool is_ddr_hang_be4_rst)
> {
> u32 reg = readl(socfpga_get_sysmgr_addr() +
> SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
> @@ -1627,7 +1638,7 @@ static int init_phy(struct ddr_handoff *ddr_handoff_info,
> ddr_handoff_info->phy_handoff_length,
> ddr_handoff_info->phy_base);
>
> - if (is_ddr_calibration_skipped(reg)) {
> + if (is_ddr_calibration_skipped(reg, is_ddr_hang_be4_rst)) {
> if (is_cal_bak_data_valid())
> *need_calibrate = false;
> else
> @@ -2820,6 +2831,7 @@ int sdram_mmr_init_full(struct udevice *dev)
> u32 reg = readl(socfpga_get_sysmgr_addr() +
> SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
> int ret;
> + bool is_ddr_hang_be4_rst = is_ddr_init_hang();
> bool need_calibrate = true;
> ulong ddr_offset;
> char *endptr;
> @@ -2845,7 +2857,7 @@ int sdram_mmr_init_full(struct udevice *dev)
> */
> writel(SOC64_CRAM_PHY_BACKUP_SKIP_MAGIC, SOC64_OCRAM_PHY_BACKUP_BASE);
>
> - if (!is_ddr_init_skipped(reg)) {
> + if (!is_ddr_init_skipped(reg, is_ddr_hang_be4_rst)) {
> printf("SDRAM init in progress ...\n");
> ddr_init_inprogress(true);
>
> @@ -2887,7 +2899,8 @@ int sdram_mmr_init_full(struct udevice *dev)
> printf("DDR controller configuration is completed\n");
>
> /* Initialize DDR PHY */
> - ret = init_phy(&ddr_handoff_info, &need_calibrate);
> + ret = init_phy(&ddr_handoff_info, &need_calibrate,
> + is_ddr_hang_be4_rst);
> if (ret) {
> debug("%s: Failed to inilialize DDR PHY\n", __func__);
> return ret;
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 09/15] ddr: altera: n5x: return error on invalid DDR controller type
[not found] ` <20261016044047.21496-10-chen.huei.lok@altera.com>
@ 2026-10-21 2:22 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:22 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> Return an error immediately when an invalid DDR controller type is passed
> in, so that uninitialised local variables such as val and upd_val are
> never used.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 858f2e76aa9..43d654341cc 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -2450,6 +2450,9 @@ static int set_cal_res_to_umctl2(struct ddr_handoff *handoff,
>
> upd_val = GET_LOWB_DATA(readw((uintptr_t)(handoff->phy_base +
> DMEM_MB_CDD_CHB_WW_0_1_OFFSET)));
> + } else {
> + debug("%s: Invalid DDR controller type\n", __func__);
> + return -ENXIO;
> }
>
> upd_val = max(val, upd_val);
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 10/15] ddr: altera: n5x: use correct cast for reset status register read
[not found] ` <20261016044047.21496-11-chen.huei.lok@altera.com>
@ 2026-10-21 2:24 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:24 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> Klocwork reported a potential value overflow from an incorrect typecast.
> It cannot actually happen here because the result never exceeds 32 bits,
> but correct the casting of the reset-status register read for the sake of
> good coding practice.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 43d654341cc..d1f0a0d312e 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -2869,9 +2869,9 @@ int sdram_mmr_init_full(struct udevice *dev)
> * subsystem in complete reset state before init DDR clock
> * and DDR controller
> */
> - ret = wait_for_bit_le32((const void *)((uintptr_t)(readl
> + ret = wait_for_bit_le32((const void *)((uintptr_t)readl
> (ddr_handoff_info.mem_reset_base) +
> - MEM_RST_MGR_STATUS)),
> + MEM_RST_MGR_STATUS),
> MEM_RST_MGR_STATUS_RESET_COMPLETE,
> true, TIMEOUT_200MS, false);
> if (ret) {
> @@ -2894,8 +2894,8 @@ int sdram_mmr_init_full(struct udevice *dev)
>
> /* Release the controller from reset */
> setbits_le32((uintptr_t)
> - (readl(ddr_handoff_info.mem_reset_base) +
> - MEM_RST_MGR_STATUS), MEM_RST_MGR_STATUS_AXI_RST |
> + readl(ddr_handoff_info.mem_reset_base) +
> + MEM_RST_MGR_STATUS, MEM_RST_MGR_STATUS_AXI_RST |
> MEM_RST_MGR_STATUS_CONTROLLER_RST |
> MEM_RST_MGR_STATUS_RESET_COMPLETE);
>
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 11/15] ddr: altera: n5x: fix debug log typo
[not found] ` <20261016044047.21496-12-chen.huei.lok@altera.com>
@ 2026-10-21 2:25 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:25 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> From: Tien Fong Chee <tien.fong.chee@altera.com>
>
> Fix a typo in the calibration-result debug log messages.
>
> Signed-off-by: Tien Fong Chee <tien.fong.chee@altera.com>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index d1f0a0d312e..244bf8ccb8c 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -2341,7 +2341,7 @@ static void set_cal_res_to_rankctrl(u32 reg_addr, u16 update_value,
>
> debug("max value divided by 2 is 0x%x\n", update_value);
> debug("umclt2 register 0x%x value is 0%x before ", reg_addr, reg);
> - debug("update with train result\n");
> + debug("updating with train result\n");
>
> value = (reg & mask) >> shift;
>
> @@ -2362,7 +2362,7 @@ static void set_cal_res_to_rankctrl(u32 reg_addr, u16 update_value,
>
> reg = readl((uintptr_t)reg_addr);
> debug("umclt2 register 0x%x value is 0%x before ", reg_addr, reg);
> - debug("update with train result\n");
> + debug("updating with train result\n");
> }
>
> /* helper function for updating train result to register */
> @@ -2375,7 +2375,7 @@ static void set_cal_res_to_reg(u32 reg_addr, u16 update_value, u32 mask,
>
> debug("max value divided by 2 is 0x%x\n", update_value);
> debug("umclt2 register 0x%x value is 0%x before ", reg_addr, reg);
> - debug("update with train result\n");
> + debug("updating with train result\n");
>
> value = (reg & mask) >> shift;
>
> @@ -2386,7 +2386,7 @@ static void set_cal_res_to_reg(u32 reg_addr, u16 update_value, u32 mask,
>
> reg = readl((uintptr_t)reg_addr);
> debug("umclt2 register 0x%x value is 0%x before ", reg_addr, reg);
> - debug("update with train result\n");
> + debug("updating with train result\n");
> }
>
> static u16 get_max_txdqsdlytg0_ux_p0(struct ddr_handoff *handoff, u32 reg,
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 12/15] ddr: altera: n5x: rename is_ddr_init_skipped() and quieten reset log
[not found] ` <20261016044047.21496-13-chen.huei.lok@altera.com>
@ 2026-10-21 2:27 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:27 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> Rename is_ddr_init_skipped() to is_ddr_init() and invert its return value
> so the helper reads naturally at the call site (true means DDR must be
> initialised). The decision is otherwise unchanged: init is required on
> POR, skipped on a warm reset, and skipped on a cold reset only when the
> retention bit is set.
>
> Switch the reset-type reporting from printf() to debug() so the reset
> cause is not printed on every boot, and add the NCONFIG, JTAG_CONFIG and
> RSU_RECONFIG cases. Define reset_type_debug_print() above its first caller
> so the new call site does not trigger an implicit-declaration warning.
>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 56 +++++++++++++---------------------
> 1 file changed, 22 insertions(+), 34 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 244bf8ccb8c..be512cd33b1 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -468,17 +468,17 @@ static enum reset_type get_reset_type(u32 reg)
> ALT_SYSMGR_SCRATCH_REG_0_DDR_RESET_TYPE_SHIFT;
> }
>
> -void reset_type_print(enum reset_type reset_t)
> +void reset_type_debug_print(u32 boot_scratch_cold0_reg)
> {
> - switch (reset_t) {
> + switch (get_reset_type(boot_scratch_cold0_reg)) {
> case POR_RESET:
> - printf("%s: POR is triggered\n", __func__);
> + debug("%s: POR is triggered\n", __func__);
> break;
> case WARM_RESET:
> - printf("%s: Warm reset is triggered\n", __func__);
> + debug("%s: Warm reset is triggered\n", __func__);
> break;
> case COLD_RESET:
> - printf("%s: Cold reset is triggered\n", __func__);
> + debug("%s: Cold reset is triggered\n", __func__);
> break;
> case NCONFIG:
> printf("%s: NCONFIG is triggered\n", __func__);
> @@ -490,34 +490,39 @@ void reset_type_print(enum reset_type reset_t)
> printf("%s: RSU_RECONFIG is triggered\n", __func__);
> break;
> default:
> - printf("%s: Invalid reset type\n", __func__);
> + debug("%s: Invalid reset type\n", __func__);
> }
> }
>
> -bool is_ddr_init_skipped(u32 reg, bool is_ddr_hang_be4_rst)
> +bool is_ddr_init(bool is_ddr_hang_be4_rst)
> {
> - enum reset_type reset_t = get_reset_type(reg);
> + u32 reg = readl(socfpga_get_sysmgr_addr() +
> + SYSMGR_SOC64_BOOT_SCRATCH_COLD0);
>
> - reset_type_print(reset_t);
> + reset_type_debug_print(reg);
>
> if (!is_ddr_dbe_triggered() && !is_ddr_hang_be4_rst) {
> - if (reset_t == WARM_RESET) {
> - debug("%s: DDR init is skipped\n", __func__);
> + if (get_reset_type(reg) == POR_RESET) {
> + debug("%s: DDR init is required\n", __func__);
> return true;
> }
>
> - if (reset_t == COLD_RESET) {
> + if (get_reset_type(reg) == WARM_RESET) {
> + debug("%s: DDR init is skipped\n", __func__);
> + return false;
> + }
> +
> + if (get_reset_type(reg) == COLD_RESET) {
> if (is_ddr_retention_enabled(reg)) {
> - debug("%s: DDR retention bit is set\n",
> - __func__);
> + debug("%s: DDR retention bit is set\n", __func__);
> debug("%s: DDR init is skipped\n", __func__);
> - return true;
> + return false;
> }
> }
> }
>
> debug("%s: DDR init is required\n", __func__);
> - return false;
> + return true;
> }
>
> bool is_ddr_calibration_skipped(u32 reg, bool is_ddr_hang_be4_rst)
> @@ -2811,23 +2816,6 @@ static int ddr_post_config(struct ddr_handoff *handoff, bool *need_calibrate)
> return ret;
> }
>
> -void reset_type_debug_print(u32 boot_scratch_cold0_reg)
> -{
> - switch (get_reset_type(boot_scratch_cold0_reg)) {
> - case POR_RESET:
> - debug("%s: POR is triggered\n", __func__);
> - break;
> - case WARM_RESET:
> - debug("%s: Warm reset is triggered\n", __func__);
> - break;
> - case COLD_RESET:
> - debug("%s: Cold reset is triggered\n", __func__);
> - break;
> - default:
> - debug("%s: Invalid reset type\n", __func__);
> - }
> -}
> -
> int sdram_mmr_init_full(struct udevice *dev)
> {
> u32 user_backup[2], user_backup_2nd[2];
> @@ -2860,7 +2848,7 @@ int sdram_mmr_init_full(struct udevice *dev)
> */
> writel(SOC64_CRAM_PHY_BACKUP_SKIP_MAGIC, SOC64_OCRAM_PHY_BACKUP_BASE);
>
> - if (!is_ddr_init_skipped(reg, is_ddr_hang_be4_rst)) {
> + if (is_ddr_init(is_ddr_hang_be4_rst)) {
> printf("SDRAM init in progress ...\n");
> ddr_init_inprogress(true);
>
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 13/15] ddr: altera: n5x: drop always-false unsigned less-than-zero checks
[not found] ` <20261016044047.21496-14-chen.huei.lok@altera.com>
@ 2026-10-21 2:29 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:29 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> The *_handoff_length fields are unsigned, so the "< 0" checks on them in
> populate_ddr_handoff() can never be true. Remove these dead comparisons.
>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 32 ++++++--------------------------
> 1 file changed, 6 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index be512cd33b1..558415d7931 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -1,6 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
> /*
> - * Copyright (C) 2020-2022 Intel Corporation <www.intel.com>
> + * Copyright (C) 2020-2023 Intel Corporation <www.intel.com>
> *
> */
>
> @@ -1731,12 +1731,6 @@ int populate_ddr_handoff(struct ddr_handoff *handoff)
> debug("%s: Umctl2 handoff length in word(32-bit) = 0x%x\n", __func__,
> (u32)handoff->cntlr_handoff_length);
>
> - /* Wrong format on user setting data */
> - if (handoff->cntlr_handoff_length < 0) {
> - debug("%s: Wrong format on user setting data\n", __func__);
> - return -ENOEXEC;
> - }
> -
> /* Get the next handoff section address */
> next_section_header = handoff->cntlr_handoff_base +
> handoff->cntlr_total_length;
> @@ -1789,13 +1783,6 @@ int populate_ddr_handoff(struct ddr_handoff *handoff)
> __func__,
> (u32)handoff->cntlr2_handoff_length);
>
> - /* Wrong format on user setting data */
> - if (handoff->cntlr2_handoff_length < 0) {
> - debug("%s: Wrong format on umctl2 user setting data\n",
> - __func__);
> - return -ENOEXEC;
> - }
> -
> /* Get the next handoff section address */
> next_section_header = handoff->cntlr2_handoff_base +
> handoff->cntlr2_total_length;
> @@ -1831,13 +1818,6 @@ int populate_ddr_handoff(struct ddr_handoff *handoff)
> debug("%s: PHY handoff length in word(32-bit) = 0x%x\n",
> __func__, (u32)handoff->phy_handoff_length);
>
> - /* Wrong format on PHY user setting data */
> - if (handoff->phy_handoff_length < 0) {
> - debug("%s: Wrong format on PHY user setting data\n",
> - __func__);
> - return -ENOEXEC;
> - }
> -
> /* Get the next handoff section address */
> next_section_header = handoff->phy_handoff_base +
> handoff->phy_total_length;
> @@ -1875,11 +1855,11 @@ int populate_ddr_handoff(struct ddr_handoff *handoff)
> debug("%s: PHY engine handoff length in word(32-bit) = 0x%x\n",
> __func__, (u32)handoff->phy_engine_handoff_length);
>
> - /* Wrong format on PHY init engine setting data */
> - if (handoff->phy_engine_handoff_length < 0) {
> - debug("%s: Wrong format on PHY init engine ",
> - __func__);
> - debug("user setting data\n");
> + /* Checking DDR handoff is overflow? */
> + if (SOC64_OCRAM_PHY_BACKUP_BASE <=
> + (handoff->phy_engine_handoff_base +
> + handoff->phy_engine_total_length)) {
> + printf("%s: DDR handoff is overflow\n ", __func__);
> return -ENOEXEC;
> }
>
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 14/15] ddr: altera: n5x: reconfigure DDR when mem-clk handoff changes
[not found] ` <20261016044047.21496-15-chen.huei.lok@altera.com>
@ 2026-10-21 2:30 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:30 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> Trigger a DDR reconfiguration when the memory clock values in the handoff
> data have changed, so that a retention restore is not attempted against a
> DDR configuration that no longer matches the running mem-clk settings.
>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> .../mach-socfpga/include/mach/handoff_soc64.h | 1 +
> arch/arm/mach-socfpga/wrap_handoff_soc64.c | 7 ++-
> drivers/ddr/altera/sdram_n5x.c | 59 ++++++++++++++++++-
> 3 files changed, 65 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm/mach-socfpga/include/mach/handoff_soc64.h b/arch/arm/mach-socfpga/include/mach/handoff_soc64.h
> index ae5af1f0100..0fb43acc98b 100644
> --- a/arch/arm/mach-socfpga/include/mach/handoff_soc64.h
> +++ b/arch/arm/mach-socfpga/include/mach/handoff_soc64.h
> @@ -47,6 +47,7 @@
> #define SOC64_HANDOFF_BASE 0x0007F000
> #elif IS_ENABLED(CONFIG_ARCH_SOCFPGA_N5X)
> #define SOC64_HANDOFF_BASE 0xFFE5F000
> +#define SOC64_HANDOFF_DDR_CLK_HANDOFF (SOC64_HANDOFF_BASE + 0x610)
> #define SOC64_HANDOFF_MISC (SOC64_HANDOFF_BASE + 0x630)
>
> /* DDR handoff */
> diff --git a/arch/arm/mach-socfpga/wrap_handoff_soc64.c b/arch/arm/mach-socfpga/wrap_handoff_soc64.c
> index ecde90f76f4..72e98806f8d 100644
> --- a/arch/arm/mach-socfpga/wrap_handoff_soc64.c
> +++ b/arch/arm/mach-socfpga/wrap_handoff_soc64.c
> @@ -27,7 +27,6 @@ static enum endianness check_endianness(u32 handoff)
> case SOC64_HANDOFF_MAGIC_IOCTL:
> case SOC64_HANDOFF_MAGIC_FPGA:
> case SOC64_HANDOFF_MAGIC_DELAY:
> - case SOC64_HANDOFF_MAGIC_CLOCK:
> case SOC64_HANDOFF_MAGIC_SDRAM:
> #if IS_ENABLED(CONFIG_ARCH_SOCFPGA_AGILEX5)
> case SOC64_HANDOFF_MAGIC_PERI:
> @@ -35,6 +34,12 @@ static enum endianness check_endianness(u32 handoff)
> case SOC64_HANDOFF_MAGIC_MISC:
> #endif
> return BIG_ENDIAN;
> + case SOC64_HANDOFF_MAGIC_CLOCK:
> + if (IS_ENABLED(CONFIG_ARCH_SOCFPGA_N5X)) {
> + debug("%s: mem clk handoff data\n", __func__);
> + return LITTLE_ENDIAN;
> + }
> + return BIG_ENDIAN;
> #if IS_ENABLED(CONFIG_ARCH_SOCFPGA_N5X)
> case SOC64_HANDOFF_DDR_UMCTL2_MAGIC:
> debug("%s: umctl2 handoff data\n", __func__);
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 558415d7931..11aa020d380 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -37,8 +37,9 @@ DECLARE_GLOBAL_DATA_PTR;
>
> /* DDR handoff SHA384 attribute */
> #define DDR_HANDOFF_IMG_ADDR 0xFFE44000
> -#define DDR_HANDOFF_IMG_LEN 0x1A000
> +#define DDR_HANDOFF_IMG_LEN 0x1A200
> #define CHUNKSZ_PER_WD_RESET (256 * 1024)
> +#define MEMCLK_HANDOFF_SIZE 0x2C
>
> /* MPFE NOC registers */
> #define FPGA2SDRAM_MGR_MAIN_SIDEBANDMGR_FLAGOUTSET0 0xF8024050
> @@ -1105,6 +1106,28 @@ static void phy_ocram(phys_addr_t phy_base, phys_addr_t phy_offset,
> }
> }
>
> +static int populate_memclk_handoff(void *handoff_base, u32 *mclk_table, u32 size)
> +{
> + u32 handoff_table[MEMCLK_HANDOFF_SIZE - 4];
> + u32 length = ARRAY_SIZE(handoff_table);
> + u32 offset = length - 8;
> + u32 i;
> + int ret = 0;
> +
> + ret = socfpga_handoff_read((void *)handoff_base, handoff_table, length);
> + if (ret) {
> + debug("%s: handoff read failed. ret: %d\n", __func__, ret);
> + return ret;
> + }
> +
> + for (i = 0; i < size; i++) {
> + mclk_table[i] = handoff_table[offset + i];
> + debug("mclk_table[%d]: 0x%x\n", i, mclk_table[i]);
> + }
> +
> + return ret;
> +}
> +
> static int cal_data_ocram(phys_addr_t phy_base, u32 addr,
> enum data_process proc)
> {
> @@ -1390,6 +1413,11 @@ static int cal_data_ocram(phys_addr_t phy_base, u32 addr,
> size_t phybak_num;
> const u32 *phybak_p = phybak;
> u16 *data;
> + u32 memclk_table[4];
> + u32 size = ARRAY_SIZE(memclk_table);
> + u8 *memclk_hash_offset = (u8 *)(SOC64_OCRAM_PHY_BACKUP_BASE - SZ_1K);
> + int ret = 0;
> +
> struct bac_cal_data_t *cal = (struct bac_cal_data_t *)
> ((uintptr_t)addr);
>
> @@ -1424,6 +1452,17 @@ static int cal_data_ocram(phys_addr_t phy_base, u32 addr,
> };
>
> if (proc == STORE) {
> + ret = populate_memclk_handoff((void *)SOC64_HANDOFF_CLOCK,
> + memclk_table, size);
> + if (ret) {
> + debug("%s: Memclks config Magic Number miss match. ret :%d\n",
> + __func__, ret);
> + return -EFAULT;
> + }
> +
> + sha384_csum_wd((u8 *)memclk_table, 4 * size,
> + memclk_hash_offset, CHUNKSZ_PER_WD_RESET);
> +
> /* Creating header */
> /* Generate HASH384 from the DDR config */
> sha384_csum_wd((u8 *)DDR_HANDOFF_IMG_ADDR,
> @@ -1454,10 +1493,28 @@ static bool is_ddrconfig_hash_match(const void *buffer)
> {
> int ret;
> u8 hash[SHA384_SUM_LEN];
> + u32 memclk_table[4];
> + u32 size = ARRAY_SIZE(memclk_table);
>
> /* Magic symbol in first 4 bytes of header */
> struct cal_header_t *header = (struct cal_header_t *)buffer;
>
> + /*
> + * Read and generate the hash for the Mem clk values and store before
> + * calcuting the HASH384 generation before Image.
> + */
> + ret = populate_memclk_handoff((void *)SOC64_HANDOFF_CLOCK,
> + memclk_table, size);
> + if (ret) {
> + debug("%s: Memclks config Magic Number miss match. ret : %d\n",
> + __func__, ret);
> + return false;
> + }
> +
> + sha384_csum_wd((u8 *)memclk_table, (4 * sizeof(u32)),
> + (u8 *)DDR_HANDOFF_IMG_ADDR + DDR_HANDOFF_IMG_LEN - SZ_512,
> + CHUNKSZ_PER_WD_RESET);
> +
> /* Generate HASH384 from the image */
> sha384_csum_wd((u8 *)DDR_HANDOFF_IMG_ADDR, DDR_HANDOFF_IMG_LEN,
> hash, CHUNKSZ_PER_WD_RESET);
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v4 15/15] ddr: altera: n5x: Replay PIE handoff on DDR retention restore
[not found] ` <20261016044047.21496-16-chen.huei.lok@altera.com>
@ 2026-10-21 2:31 ` Chee, Tien Fong
0 siblings, 0 replies; 15+ messages in thread
From: Chee, Tien Fong @ 2026-10-21 2:31 UTC (permalink / raw)
To: Chen Huei Lok, u-boot
Cc: Tom Rini, Marek Vasut, Simon Goldschmidt, Alif Zakuan Yuslaimi,
Boon Khai Ng, Kok Kiang Hea
On 16/10/2026 12:40 pm, Chen Huei Lok wrote:
> On the DDR retention restore path the trained PHY results are reloaded
> from the calibration backup by cal_data_ocram() in init_phy(), which
> leaves the PHY microcontroller stalled. Running update_training_result()
> there reads back results from a PHY that was never freshly trained and
> fails the DFI handshake, so DRAM init returns -ENODEV.
>
> Instead, bring the PHY microcontroller out of reset/stall and replay the
> PHY Init Engine handoff to return the PHY to normal operating mode.
>
> The PIE handoff table shares memory with the memclk hash scratch area
> (DDR_HANDOFF_IMG_ADDR + DDR_HANDOFF_IMG_LEN - SZ_512) used by
> is_ddrconfig_hash_match(). Snapshot and restore those bytes around the
> hash computation so the replayed PIE table is not corrupted.
>
> Signed-off-by: Chen Huei Lok <chen.huei.lok@altera.com>
> ---
> drivers/ddr/altera/sdram_n5x.c | 48 +++++++++++++++++++++++++++++-----
> 1 file changed, 42 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/ddr/altera/sdram_n5x.c b/drivers/ddr/altera/sdram_n5x.c
> index 11aa020d380..fd90a895a80 100644
> --- a/drivers/ddr/altera/sdram_n5x.c
> +++ b/drivers/ddr/altera/sdram_n5x.c
> @@ -1495,6 +1495,9 @@ static bool is_ddrconfig_hash_match(const void *buffer)
> u8 hash[SHA384_SUM_LEN];
> u32 memclk_table[4];
> u32 size = ARRAY_SIZE(memclk_table);
> + u8 *memclk_hash_dst = (u8 *)(DDR_HANDOFF_IMG_ADDR +
> + DDR_HANDOFF_IMG_LEN - SZ_512);
> + u8 saved_handoff[SHA384_SUM_LEN];
>
> /* Magic symbol in first 4 bytes of header */
> struct cal_header_t *header = (struct cal_header_t *)buffer;
> @@ -1511,14 +1514,26 @@ static bool is_ddrconfig_hash_match(const void *buffer)
> return false;
> }
>
> + /*
> + * The memclk hash is written into the tail of the hashed handoff image
> + * (DDR_HANDOFF_IMG_ADDR + DDR_HANDOFF_IMG_LEN - SZ_512) so that the
> + * whole-image hash covers it. That location overlaps the PHY init
> + * engine handoff table that phy_init_engine() replays on the retention
> + * restore path, so snapshot the original handoff bytes and restore them
> + * once the hash has been computed.
> + */
> + memcpy(saved_handoff, memclk_hash_dst, SHA384_SUM_LEN);
> +
> sha384_csum_wd((u8 *)memclk_table, (4 * sizeof(u32)),
> - (u8 *)DDR_HANDOFF_IMG_ADDR + DDR_HANDOFF_IMG_LEN - SZ_512,
> - CHUNKSZ_PER_WD_RESET);
> + memclk_hash_dst, CHUNKSZ_PER_WD_RESET);
>
> /* Generate HASH384 from the image */
> sha384_csum_wd((u8 *)DDR_HANDOFF_IMG_ADDR, DDR_HANDOFF_IMG_LEN,
> hash, CHUNKSZ_PER_WD_RESET);
>
> + /* Restore the handoff bytes clobbered by the memclk hash above */
> + memcpy(memclk_hash_dst, saved_handoff, SHA384_SUM_LEN);
> +
> ret = memcmp((void *)hash, (const void *)header->ddrconfig_hash,
> SHA384_SUM_LEN);
> if (ret) {
> @@ -2961,10 +2976,31 @@ int sdram_mmr_init_full(struct udevice *dev)
> }
>
> } else {
> - /* Updating training result to DDR controller */
> - ret = update_training_result(&ddr_handoff_info);
> - if (ret)
> - return ret;
> + /*
> + * Retention restore path: the trained results were
> + * already reloaded into the PHY by cal_data_ocram()
> + * (LOADING) in init_phy(), so update_training_result()
> + * must not run here (it would read back results from a
> + * PHY that was never freshly trained and fail the DFI
> + * handshake). Bring the PHY microcontroller out of
> + * reset/stall, then replay the PIE handoff to return the
> + * PHY to normal operating mode.
> + */
> + clrbits_le16(ddr_handoff_info.phy_base +
> + DDR_PHY_APBONLY0_OFFSET,
> + DDR_PHY_MICROCONTMUXSEL);
> + setbits_le16(ddr_handoff_info.phy_base +
> + DDR_PHY_MICRORESET_OFFSET,
> + DDR_PHY_MICRORESET_RESET |
> + DDR_PHY_MICRORESET_STALL);
> + clrbits_le16(ddr_handoff_info.phy_base +
> + DDR_PHY_MICRORESET_OFFSET,
> + DDR_PHY_MICRORESET_RESET);
> + setbits_le16(ddr_handoff_info.phy_base +
> + DDR_PHY_APBONLY0_OFFSET,
> + DDR_PHY_MICROCONTMUXSEL);
> +
> + phy_init_engine(&ddr_handoff_info);
> }
>
> /*
Reviewed-by: Tien Fong Chee <tien.fong.chee@altera.com>
Best regards,
Tien Fong
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2026-10-21 2:31 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20261016044047.21496-1-chen.huei.lok@altera.com>
[not found] ` <20261016044047.21496-2-chen.huei.lok@altera.com>
2026-10-21 1:55 ` [PATCH v4 01/15] misc: fs_loader: Add QSPI RAW offset loading support Chee, Tien Fong
[not found] ` <20261016044047.21496-3-chen.huei.lok@altera.com>
2026-10-21 2:07 ` [PATCH v4 02/15] arm: dts: socfpga: n5x: add DDR retention calibration backup nodes Chee, Tien Fong
[not found] ` <20261016044047.21496-4-chen.huei.lok@altera.com>
2026-10-21 2:09 ` [PATCH v4 03/15] arm: socfpga: n5x: enable QSPI mailbox before DDR init Chee, Tien Fong
[not found] ` <20261016044047.21496-5-chen.huei.lok@altera.com>
2026-10-21 2:14 ` [PATCH v4 04/15] ddr: altera: n5x: Add self-refresh support in DDR4 Chee, Tien Fong
[not found] ` <20261016044047.21496-6-chen.huei.lok@altera.com>
2026-10-21 2:16 ` [PATCH v4 05/15] configs: socfpga: n5x: enable required configs for DDR retention Chee, Tien Fong
[not found] ` <20261016044047.21496-7-chen.huei.lok@altera.com>
2026-10-21 2:18 ` [PATCH v4 06/15] ddr: altera: n5x: set DDR init progress bit for watchdog recovery Chee, Tien Fong
[not found] ` <20261016044047.21496-8-chen.huei.lok@altera.com>
2026-10-21 2:20 ` [PATCH v4 07/15] ddr: altera: n5x: re-init DDR when double-bit ECC error is detected Chee, Tien Fong
[not found] ` <20261016044047.21496-9-chen.huei.lok@altera.com>
2026-10-21 2:21 ` [PATCH v4 08/15] ddr: altera: n5x: re-init DDR after watchdog reset from init hang Chee, Tien Fong
[not found] ` <20261016044047.21496-10-chen.huei.lok@altera.com>
2026-10-21 2:22 ` [PATCH v4 09/15] ddr: altera: n5x: return error on invalid DDR controller type Chee, Tien Fong
[not found] ` <20261016044047.21496-11-chen.huei.lok@altera.com>
2026-10-21 2:24 ` [PATCH v4 10/15] ddr: altera: n5x: use correct cast for reset status register read Chee, Tien Fong
[not found] ` <20261016044047.21496-12-chen.huei.lok@altera.com>
2026-10-21 2:25 ` [PATCH v4 11/15] ddr: altera: n5x: fix debug log typo Chee, Tien Fong
[not found] ` <20261016044047.21496-13-chen.huei.lok@altera.com>
2026-10-21 2:27 ` [PATCH v4 12/15] ddr: altera: n5x: rename is_ddr_init_skipped() and quieten reset log Chee, Tien Fong
[not found] ` <20261016044047.21496-14-chen.huei.lok@altera.com>
2026-10-21 2:29 ` [PATCH v4 13/15] ddr: altera: n5x: drop always-false unsigned less-than-zero checks Chee, Tien Fong
[not found] ` <20261016044047.21496-15-chen.huei.lok@altera.com>
2026-10-21 2:30 ` [PATCH v4 14/15] ddr: altera: n5x: reconfigure DDR when mem-clk handoff changes Chee, Tien Fong
[not found] ` <20261016044047.21496-16-chen.huei.lok@altera.com>
2026-10-21 2:31 ` [PATCH v4 15/15] ddr: altera: n5x: Replay PIE handoff on DDR retention restore Chee, Tien Fong
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox