* 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.