All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR
@ 2021-09-16 23:12 Dinh Nguyen
  2021-09-16 23:12 ` [PATCHv2 2/2] EDAC/synopsys: v3.80a of the synopsys edac contoller is also on the N5X Dinh Nguyen
  2021-09-17 12:18 ` [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR Michal Simek
  0 siblings, 2 replies; 4+ messages in thread
From: Dinh Nguyen @ 2021-09-16 23:12 UTC (permalink / raw)
  To: michal.simek
  Cc: dinguyen, bp, mchehab, tony.luck, james.morse, rric,
	linux-kernel, linux-edac

Adds support for version 3.80a of the Synopsys DDR controller with EDAC. This
version of the controller has the following differences:

- UE/CE are auto cleared
- Interrupts are supported by default

Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
v2: remove "This patch" from commit message
---
 drivers/edac/synopsys_edac.c | 53 ++++++++++++++++++++++++++++++------
 1 file changed, 44 insertions(+), 9 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index 7e7146b22c16..297845e65b65 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -101,6 +101,7 @@
 /* DDR ECC Quirks */
 #define DDR_ECC_INTR_SUPPORT		BIT(0)
 #define DDR_ECC_DATA_POISON_SUPPORT	BIT(1)
+#define DDR_ECC_INTR_SELF_CLEAR		BIT(2)
 
 /* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */
 /* ECC Configuration Registers */
@@ -171,6 +172,10 @@
 #define DDR_QOS_IRQ_EN_OFST		0x20208
 #define DDR_QOS_IRQ_DB_OFST		0x2020C
 
+/* DDR QOS Interrupt register definitions */
+#define DDR_UE_MASK			0x200
+#define DDR_CE_MASK			0x100
+
 /* ECC Corrected Error Register Mask and Shifts*/
 #define ECC_CEADDR0_RW_MASK		0x3FFFF
 #define ECC_CEADDR0_RNK_MASK		BIT(24)
@@ -533,10 +538,16 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 	priv = mci->pvt_info;
 	p_data = priv->p_data;
 
-	regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
-	regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
-	if (!(regval & ECC_CE_UE_INTR_MASK))
-		return IRQ_NONE;
+	/*
+	 * v3.0 of the controller has the ce/ue bits cleared automatically
+	 * cleared, so this condition does not apply.
+	 */
+	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
+		regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
+		regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
+		if (!(regval & ECC_CE_UE_INTR_MASK))
+			return IRQ_NONE;
+	}
 
 	status = p_data->get_error_info(priv);
 	if (status)
@@ -548,7 +559,9 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
 
 	edac_dbg(3, "Total error count CE %d UE %d\n",
 		 priv->ce_cnt, priv->ue_cnt);
-	writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
+	/* v3.0 of the controller does not have this register */
+	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
+		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
 	return IRQ_HANDLED;
 }
 
@@ -834,8 +847,13 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
 static void enable_intr(struct synps_edac_priv *priv)
 {
 	/* Enable UE/CE Interrupts */
-	writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
-			priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
+	if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
+		writel(DDR_UE_MASK | DDR_CE_MASK,
+		       priv->baseaddr + ECC_CLR_OFST);
+	else
+		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
+		       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
+
 }
 
 static void disable_intr(struct synps_edac_priv *priv)
@@ -890,6 +908,19 @@ static const struct synps_platform_data zynqmp_edac_def = {
 			  ),
 };
 
+static const struct synps_platform_data synopsys_edac_def = {
+	.get_error_info	= zynqmp_get_error_info,
+	.get_mtype	= zynqmp_get_mtype,
+	.get_dtype	= zynqmp_get_dtype,
+	.get_ecc_state	= zynqmp_get_ecc_state,
+	.quirks         = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
+#ifdef CONFIG_EDAC_DEBUG
+			  | DDR_ECC_DATA_POISON_SUPPORT
+#endif
+			  ),
+};
+
+
 static const struct of_device_id synps_edac_match[] = {
 	{
 		.compatible = "xlnx,zynq-ddrc-a05",
@@ -899,6 +930,10 @@ static const struct of_device_id synps_edac_match[] = {
 		.compatible = "xlnx,zynqmp-ddrc-2.40a",
 		.data = (void *)&zynqmp_edac_def
 	},
+	{
+		.compatible = "snps,ddrc-3.80a",
+		.data = (void *)&synopsys_edac_def
+	},
 	{
 		/* end of table */
 	}
@@ -1352,8 +1387,8 @@ static int mc_probe(struct platform_device *pdev)
 		}
 	}
 
-	if (of_device_is_compatible(pdev->dev.of_node,
-				    "xlnx,zynqmp-ddrc-2.40a"))
+	if (!of_device_is_compatible(pdev->dev.of_node,
+				    "xlnx,zynq-ddrc-a05"))
 		setup_address_map(priv);
 #endif
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCHv2 2/2] EDAC/synopsys: v3.80a of the synopsys edac contoller is also on the N5X
  2021-09-16 23:12 [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR Dinh Nguyen
@ 2021-09-16 23:12 ` Dinh Nguyen
  2021-09-17 12:11   ` Michal Simek
  2021-09-17 12:18 ` [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR Michal Simek
  1 sibling, 1 reply; 4+ messages in thread
From: Dinh Nguyen @ 2021-09-16 23:12 UTC (permalink / raw)
  To: michal.simek
  Cc: dinguyen, bp, mchehab, tony.luck, james.morse, rric,
	linux-kernel, linux-edac

Intel's N5X platform is also using the Synopsys EDAC controller.

Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
---
v2: no changes
---
 drivers/edac/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
index 2fc4c3f91fd5..df46e7483aa0 100644
--- a/drivers/edac/Kconfig
+++ b/drivers/edac/Kconfig
@@ -484,7 +484,7 @@ config EDAC_ARMADA_XP
 
 config EDAC_SYNOPSYS
 	tristate "Synopsys DDR Memory Controller"
-	depends on ARCH_ZYNQ || ARCH_ZYNQMP
+	depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_N5X
 	help
 	  Support for error detection and correction on the Synopsys DDR
 	  memory controller.
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCHv2 2/2] EDAC/synopsys: v3.80a of the synopsys edac contoller is also on the N5X
  2021-09-16 23:12 ` [PATCHv2 2/2] EDAC/synopsys: v3.80a of the synopsys edac contoller is also on the N5X Dinh Nguyen
@ 2021-09-17 12:11   ` Michal Simek
  0 siblings, 0 replies; 4+ messages in thread
From: Michal Simek @ 2021-09-17 12:11 UTC (permalink / raw)
  To: Dinh Nguyen, michal.simek
  Cc: bp, mchehab, tony.luck, james.morse, rric, linux-kernel, linux-edac



On 9/17/21 1:12 AM, Dinh Nguyen wrote:
> Intel's N5X platform is also using the Synopsys EDAC controller.
> 
> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
> ---
> v2: no changes
> ---
>  drivers/edac/Kconfig | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig
> index 2fc4c3f91fd5..df46e7483aa0 100644
> --- a/drivers/edac/Kconfig
> +++ b/drivers/edac/Kconfig
> @@ -484,7 +484,7 @@ config EDAC_ARMADA_XP
>  
>  config EDAC_SYNOPSYS
>  	tristate "Synopsys DDR Memory Controller"
> -	depends on ARCH_ZYNQ || ARCH_ZYNQMP
> +	depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_N5X
>  	help
>  	  Support for error detection and correction on the Synopsys DDR
>  	  memory controller.
> 

NACK.
You have removed ARCH_N5X already
4a9a1a5602d8 ("arm64: socfpga: merge Agilex and N5X into
ARCH_INTEL_SOCFPGA")
I can't see any reason to use this symbol.

Also ARCH_N5X is in arm64 defconfig which should be removed.

M

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR
  2021-09-16 23:12 [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR Dinh Nguyen
  2021-09-16 23:12 ` [PATCHv2 2/2] EDAC/synopsys: v3.80a of the synopsys edac contoller is also on the N5X Dinh Nguyen
@ 2021-09-17 12:18 ` Michal Simek
  1 sibling, 0 replies; 4+ messages in thread
From: Michal Simek @ 2021-09-17 12:18 UTC (permalink / raw)
  To: Dinh Nguyen, michal.simek
  Cc: bp, mchehab, tony.luck, james.morse, rric, linux-kernel, linux-edac



On 9/17/21 1:12 AM, Dinh Nguyen wrote:
> Adds support for version 3.80a of the Synopsys DDR controller with EDAC. This
> version of the controller has the following differences:
> 
> - UE/CE are auto cleared
> - Interrupts are supported by default
> 
> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
> ---
> v2: remove "This patch" from commit message
> ---
>  drivers/edac/synopsys_edac.c | 53 ++++++++++++++++++++++++++++++------
>  1 file changed, 44 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
> index 7e7146b22c16..297845e65b65 100644
> --- a/drivers/edac/synopsys_edac.c
> +++ b/drivers/edac/synopsys_edac.c
> @@ -101,6 +101,7 @@
>  /* DDR ECC Quirks */
>  #define DDR_ECC_INTR_SUPPORT		BIT(0)
>  #define DDR_ECC_DATA_POISON_SUPPORT	BIT(1)
> +#define DDR_ECC_INTR_SELF_CLEAR		BIT(2)
>  
>  /* ZynqMP Enhanced DDR memory controller registers that are relevant to ECC */
>  /* ECC Configuration Registers */
> @@ -171,6 +172,10 @@
>  #define DDR_QOS_IRQ_EN_OFST		0x20208
>  #define DDR_QOS_IRQ_DB_OFST		0x2020C
>  
> +/* DDR QOS Interrupt register definitions */
> +#define DDR_UE_MASK			0x200
> +#define DDR_CE_MASK			0x100

Use BIT macro or genmask for these.

> +
>  /* ECC Corrected Error Register Mask and Shifts*/
>  #define ECC_CEADDR0_RW_MASK		0x3FFFF
>  #define ECC_CEADDR0_RNK_MASK		BIT(24)
> @@ -533,10 +538,16 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
>  	priv = mci->pvt_info;
>  	p_data = priv->p_data;
>  
> -	regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
> -	regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
> -	if (!(regval & ECC_CE_UE_INTR_MASK))
> -		return IRQ_NONE;
> +	/*
> +	 * v3.0 of the controller has the ce/ue bits cleared automatically
> +	 * cleared, so this condition does not apply.

cleared is here twice

> +	 */
> +	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)) {
> +		regval = readl(priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
> +		regval &= (DDR_QOSCE_MASK | DDR_QOSUE_MASK);
> +		if (!(regval & ECC_CE_UE_INTR_MASK))
> +			return IRQ_NONE;
> +	}
>  
>  	status = p_data->get_error_info(priv);
>  	if (status)
> @@ -548,7 +559,9 @@ static irqreturn_t intr_handler(int irq, void *dev_id)
>  
>  	edac_dbg(3, "Total error count CE %d UE %d\n",
>  		 priv->ce_cnt, priv->ue_cnt);
> -	writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
> +	/* v3.0 of the controller does not have this register */
> +	if (!(priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR))
> +		writel(regval, priv->baseaddr + DDR_QOS_IRQ_STAT_OFST);
>  	return IRQ_HANDLED;
>  }
>  
> @@ -834,8 +847,13 @@ static void mc_init(struct mem_ctl_info *mci, struct platform_device *pdev)
>  static void enable_intr(struct synps_edac_priv *priv)
>  {
>  	/* Enable UE/CE Interrupts */
> -	writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
> -			priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
> +	if (priv->p_data->quirks & DDR_ECC_INTR_SELF_CLEAR)
> +		writel(DDR_UE_MASK | DDR_CE_MASK,
> +		       priv->baseaddr + ECC_CLR_OFST);
> +	else
> +		writel(DDR_QOSUE_MASK | DDR_QOSCE_MASK,
> +		       priv->baseaddr + DDR_QOS_IRQ_EN_OFST);
> +
>  }
>  
>  static void disable_intr(struct synps_edac_priv *priv)
> @@ -890,6 +908,19 @@ static const struct synps_platform_data zynqmp_edac_def = {
>  			  ),
>  };
>  
> +static const struct synps_platform_data synopsys_edac_def = {
> +	.get_error_info	= zynqmp_get_error_info,
> +	.get_mtype	= zynqmp_get_mtype,
> +	.get_dtype	= zynqmp_get_dtype,
> +	.get_ecc_state	= zynqmp_get_ecc_state,
> +	.quirks         = (DDR_ECC_INTR_SUPPORT | DDR_ECC_INTR_SELF_CLEAR
> +#ifdef CONFIG_EDAC_DEBUG
> +			  | DDR_ECC_DATA_POISON_SUPPORT
> +#endif
> +			  ),
> +};
> +
> +
>  static const struct of_device_id synps_edac_match[] = {
>  	{
>  		.compatible = "xlnx,zynq-ddrc-a05",
> @@ -899,6 +930,10 @@ static const struct of_device_id synps_edac_match[] = {
>  		.compatible = "xlnx,zynqmp-ddrc-2.40a",
>  		.data = (void *)&zynqmp_edac_def
>  	},
> +	{
> +		.compatible = "snps,ddrc-3.80a",
> +		.data = (void *)&synopsys_edac_def
> +	},
>  	{
>  		/* end of table */
>  	}
> @@ -1352,8 +1387,8 @@ static int mc_probe(struct platform_device *pdev)
>  		}
>  	}
>  
> -	if (of_device_is_compatible(pdev->dev.of_node,
> -				    "xlnx,zynqmp-ddrc-2.40a"))
> +	if (!of_device_is_compatible(pdev->dev.of_node,
> +				    "xlnx,zynq-ddrc-a05"))
>  		setup_address_map(priv);

would be better to create quirk for it. You have the whole
infrastructure in place that's why it should be easy to do. (In separate
patch please).

Thanks,
Michal

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-09-17 12:19 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-16 23:12 [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR Dinh Nguyen
2021-09-16 23:12 ` [PATCHv2 2/2] EDAC/synopsys: v3.80a of the synopsys edac contoller is also on the N5X Dinh Nguyen
2021-09-17 12:11   ` Michal Simek
2021-09-17 12:18 ` [PATCHv2 1/2] EDAC/synopsys: add support for version 3 of the Synopsys EDAC DDR Michal Simek

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.