[PATCH v1 5/5] ddr: altera: iossm: Enhance debug information for ECC errors

Chee, Tien Fong tien.fong.chee at altera.com
Mon Apr 21 08:59:58 CEST 2025



> -----Original Message-----
> From: Meng, Tingting <tingting.meng at altera.com>
> Sent: Monday, April 21, 2025 1:15 PM
> To: u-boot at lists.denx.de
> Cc: Marek Vasut <marex at denx.de>; Chee, Tien Fong
> <tien.fong.chee at altera.com>; Meng, Tingting <tingting.meng at altera.com>;
> Hea, Kok Kiang <kok.kiang.hea at altera.com>; Maniyam, Dinesh
> <dinesh.maniyam at altera.com>; Ng, Boon Khai <boon.khai.ng at altera.com>;
> Yuslaimi, Alif Zakuan <alif.zakuan.yuslaimi at altera.com>; Rosdi, Danish
> Ahmad <danish.ahmad.rosdi at altera.com>; Zamri, Muhammad Hazim Izzat
> <muhammad.hazim.izzat.zamri at altera.com>; Lim, Jit Loon
> <jit.loon.lim at altera.com>
> Subject: [PATCH v1 5/5] ddr: altera: iossm: Enhance debug information for
> ECC errors
> 
> From: Tingting Meng <tingting.meng at altera.com>
> 
> ECC debug information was enhanced to improve the readability of error
> messages.
> 
> Signed-off-by: Tingting Meng <tingting.meng at altera.com>
> ---
>  drivers/ddr/altera/iossm_mailbox.c | 64 ++++++++++++++++++++++++-----
> -
>  1 file changed, 51 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/ddr/altera/iossm_mailbox.c
> b/drivers/ddr/altera/iossm_mailbox.c
> index 26602858777..fc09dde3f9e 100644
> --- a/drivers/ddr/altera/iossm_mailbox.c
> +++ b/drivers/ddr/altera/iossm_mailbox.c
> @@ -98,6 +98,7 @@
> 
>  /* offset info of ECC_ERR_STATUS */
>  #define ECC_ERR_COUNTER_MASK		GENMASK(15, 0)
> +#define ECC_ERR_OVERFLOW_MASK		GENMASK(31, 16)
> 
>  /* offset info of ECC_ERR_DATA */
>  #define ECC_ERR_IP_TYPE_MASK		GENMASK(24, 22)
> @@ -106,6 +107,8 @@
>  #define ECC_ERR_TYPE_MASK		GENMASK(9, 6)
>  #define ECC_ERR_ADDR_UPPER_MASK		GENMASK(5, 0)
>  #define ECC_ERR_ADDR_LOWER_MASK		GENMASK(31, 0)
> +#define ECC_FULL_ADDR_UPPER_MASK	GENMASK(63, 32)
> +#define ECC_FULL_ADDR_LOWER_MASK	GENMASK(31, 0)
> 
>  #define MAX_ECC_ERR_INFO_COUNT 16
> 
> @@ -167,6 +170,24 @@ struct ecc_err_info {
>  	u32 addr_lower;
>  };
> 
> +struct ecc_overflow_error_desc {
> +	int bit;
> +	const char *msg;
> +};
> +
> +static const struct ecc_overflow_error_desc ecc_overflow_errors[] = {
> +	{ 0,  " - Single-bit error\n" },
> +	{ 1,  " - Multiple single-bit errors\n" },
> +	{ 2,  " - Double-bit error\n" },
> +	{ 3,  " - Multiple double-bit errors\n" },
> +	{ 8,  " - Single-bit error during ECC scrubbing\n" },
> +	{ 9,  " - Write link ECC single-bit error (LPDDR5 only)\n" },
> +	{ 10, " - Write link ECC double-bit error (LPDDR5 only)\n" },
> +	{ 11, " - Read link ECC single-bit error (LPDDR5 only)\n" },
> +	{ 12, " - Read link ECC double-bit error (LPDDR5 only)\n" },
> +	{ 13, " - RMW read link ECC double-bit error (LPDDR5 only)\n" }, };
> +
>  static int is_ddr_csr_clkgen_locked(u8 io96b_pll)  {
>  	int ret = 0;
> @@ -628,16 +649,28 @@ bool ecc_interrupt_status(struct io96b_info
> *io96b_ctrl)  {
>  	int i, j;
>  	u32 ecc_err_status;
> -	u16 ecc_err_counter;
> +	u16 ecc_err_counter, ecc_overflow_status;
>  	bool ecc_error_flag = false;
> 
>  	/* Get ECC double-bit error status */
>  	for (i = 0; i < io96b_ctrl->num_instance; i++) {
>  		ecc_err_status = readl(io96b_ctrl->io96b[i].io96b_csr_addr +
>  					IOSSM_ECC_ERR_STATUS_OFFSET);
> +
>  		ecc_err_counter = FIELD_GET(ECC_ERR_COUNTER_MASK,
> ecc_err_status);
> -		debug("%s: ECC error number detected on IO96B_%d: %d\n",
> -		      __func__, i, ecc_err_counter);
> +		log_err("%s: ECC error number detected on
> IO96B_%d: %d\n",
> +			__func__, i, ecc_err_counter);
> +
> +		ecc_overflow_status =
> FIELD_GET(ECC_ERR_OVERFLOW_MASK, ecc_err_status);
> +		if (ecc_overflow_status != 0) {
> +			log_err("ECC Error Overflow Flags:\n");
> +
> +			for (int i = 0; i < ARRAY_SIZE(ecc_overflow_errors);
> i++) {
> +				if (ecc_overflow_status &
> BIT(ecc_overflow_errors[i].bit)) {
> +					log_err("%s",
> ecc_overflow_errors[i].msg);
> +				}
> +			}
> +		}
> 
>  		if (ecc_err_counter != 0) {
>  			phys_addr_t address;
> @@ -661,15 +694,20 @@ bool ecc_interrupt_status(struct io96b_info
> *io96b_ctrl)
>  								ecc_err_data);
>  				err_info.addr_lower = readl(address +
> sizeof(u32));
> 
> -				debug("%s: ECC double-bit error detected on
> IO96B_%d:\n",
> -				      __func__, i);
> -				debug("- error info address :0x%llx\n",
> address);
> -				debug("- error ip type: %d\n",
> err_info.ip_type);
> -				debug("- error instance id: %d\n",
> err_info.instance_id);
> -				debug("- error source id: %d\n",
> err_info.source_id);
> -				debug("- error type: %d\n",
> err_info.err_type);
> -				debug("- error address upper: 0x%x\n",
> err_info.addr_upper);
> -				debug("- error address lower: 0x%x\n",
> err_info.addr_lower);
> +				log_err(" %s: DDR ECC Error Detected on
> IO96B_%d number:%d\n",
> +					__func__, i, j);
> +				log_err(" - error info address :0x%llx\n",
> address);
> +				log_err(" - error ip type: %d\n",
> err_info.ip_type);
> +				log_err(" - error instance id: %d\n",
> err_info.instance_id);
> +				log_err(" - error source id: %d\n",
> err_info.source_id);
> +				log_err(" - error type: %s\n",
> +
> 	is_double_bit_error(err_info.err_type) ?
> +					"Double-bit error" : "Single-bit error");
> +				log_err(" - error address: 0x%016llx\n",
> +
> 	(u64)FIELD_PREP(ECC_FULL_ADDR_UPPER_MASK,
> +							err_info.addr_upper)
> |
> +
> 	FIELD_PREP(ECC_FULL_ADDR_LOWER_MASK,
> +						   err_info.addr_lower));
> 
>  				if (is_double_bit_error(err_info.err_type)) {
>  					if (!ecc_error_flag)
> @@ -682,7 +720,7 @@ bool ecc_interrupt_status(struct io96b_info
> *io96b_ctrl)
>  	}
> 
>  	if (ecc_error_flag)
> -		printf("\n%s: ECC double-bit error detected!\n", __func__);
> +		log_err("\n%s: ECC double-bit error detected!\n", __func__);
> 
>  	return ecc_error_flag;
>  }
> --
> 2.25.1

Reviewed-by: Tien Fong Chee <tien.fong.chee at altera.com>

Best regards,
Tien Fong



More information about the U-Boot mailing list