public inbox for linux-edac@vger.kernel.org
 help / color / mirror / Atom feed
From: Serge Semin <fancer.lancer@gmail.com>
To: Michal Simek <michal.simek@amd.com>,
	Alexander Stein <alexander.stein@ew.tq-group.com>,
	Borislav Petkov <bp@alien8.de>, Tony Luck <tony.luck@intel.com>,
	James Morse <james.morse@arm.com>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Robert Richter <rric@kernel.org>,
	Manish Narani <manish.narani@xilinx.com>
Cc: Serge Semin <fancer.lancer@gmail.com>,
	Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com>,
	Dinh Nguyen <dinguyen@kernel.org>,
	Shubhrajyoti Datta <shubhrajyoti.datta@gmail.com>,
	Arnd Bergmann <arnd@arndb.de>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>,
	Borislav Petkov <bp@suse.de>
Subject: [PATCH RESEND v6 01/18] EDAC/synopsys: Fix generic device type detection procedure
Date: Thu, 27 Jun 2024 20:32:08 +0300	[thread overview]
Message-ID: <20240627173251.25718-2-fancer.lancer@gmail.com> (raw)
In-Reply-To: <20240627173251.25718-1-fancer.lancer@gmail.com>

First of all the enum dev_type constants describe the memory DRAM chips
used at the stick, not the entire DQ-bus width (see the enumeration kdoc
for details). So what is returned from the zynqmp_get_dtype() function and
then specified to the dimm_info->dtype field is definitely incorrect
because the DDR controller DQ-bus width doesn't determine a strict
DDR-chips configuration on the attached memory device.

Secondly the DRAM chips type has nothing to do with the data bus width
specified in the MSTR.data_bus_width CSR field. The CSR field just
determines the _part_ of the whole DQ-bus currently used to access the data
from the all DRAM memory chips. So it doesn't indicate the individual
chips type.

Thirdly in case of the DW uMCTL2 controllers the DRAM chips type can be
firmly determined only in case of the DDR4 protocol by means of the
MSTR.device_config field state (the field is supposed to be set by the system
firmware though). From this and the rest of the perspective the
zynqmp_get_dtype() implementation is incorrect.

Finally the DW uMCTL2 DDRC ECC capability doesn't depend on the memory
chips type. Moreover it doesn't depend on the utilized data bus width in
runtime either. The IP-core reference manual says in [1,2] that the ECC
support can't be enabled during the IP-core synthesis for the DRAM data
bus widths other than 16, 32 or 64. At the same time the bus width mode
(MSTR.data_bus_width) doesn't change the ECC feature availability. Thus it
was wrong to determine the ECC state with respect to the DQ-bus width
mode. From this perspective the zynqmp_get_ecc_state() implementation is
incorrect either. It shouldn't rely on the currently utilized DQ-bus
part or the attached DDR-chip types.

Fix all of the mistakes described above in the zynqmp_get_dtype() and
zynqmp_get_ecc_state() methods: determine the actual DRAM chips data width
only for the DDR4 protocol and return that it's UNKNOWN in the rest of the
cases; determine the ECC availability by the ECCCFG0.ecc_mode field state
only (that field can't be modified anyway if the IP-core was synthesized
with no ECC support).

[1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2)
Databook, Version 3.91a, October 2020, p. 421.
[2] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2)
Databook, Version 3.91a, October 2020, p. 633.

Fixes: b500b4a029d5 ("EDAC, synopsys: Add ECC support for ZynqMP DDR controller")
Signed-off-by: Serge Semin <fancer.lancer@gmail.com>
Reviewed-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>

---

Changelog v2:
- Include "linux/bitfield.h" header file to get the FIELD_GET macro
  definition. (@tbot)

Changelog v6:
- Fix the zynqmp_get_dtype() method kdoc.
- Split up the commit log into paragraphs.
---
 drivers/edac/synopsys_edac.c | 55 +++++++++++++++---------------------
 1 file changed, 23 insertions(+), 32 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index ea7a9a342dd3..b6bdbc1289f3 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -664,36 +664,35 @@ static enum dev_type zynq_get_dtype(const void __iomem *base)
 }
 
 /**
- * zynqmp_get_dtype - Return the controller memory width.
+ * zynqmp_get_dtype - Return the DDR memory chips type.
  * @base:	DDR memory controller base address.
  *
- * Get the EDAC device type width appropriate for the current controller
+ * Get the attached DDR chips type based on the current controller
  * configuration.
  *
- * Return: a device type width enumeration.
+ * Return: type of the memory DRAM chips.
  */
 static enum dev_type zynqmp_get_dtype(const void __iomem *base)
 {
-	enum dev_type dt;
-	u32 width;
-
-	width = readl(base + CTRL_OFST);
-	width = (width & ECC_CTRL_BUSWIDTH_MASK) >> ECC_CTRL_BUSWIDTH_SHIFT;
-	switch (width) {
-	case DDRCTL_EWDTH_16:
-		dt = DEV_X2;
-		break;
-	case DDRCTL_EWDTH_32:
-		dt = DEV_X4;
-		break;
-	case DDRCTL_EWDTH_64:
-		dt = DEV_X8;
-		break;
-	default:
-		dt = DEV_UNKNOWN;
+	u32 regval;
+
+	regval = readl(base + CTRL_OFST);
+	if (!(regval & MEM_TYPE_DDR4))
+		return DEV_UNKNOWN;
+
+	regval = (regval & DDRC_MSTR_CFG_MASK) >> DDRC_MSTR_CFG_SHIFT;
+	switch (regval) {
+	case DDRC_MSTR_CFG_X4_MASK:
+		return DEV_X4;
+	case DDRC_MSTR_CFG_X8_MASK:
+		return DEV_X8;
+	case DDRC_MSTR_CFG_X16_MASK:
+		return DEV_X16;
+	case DDRC_MSTR_CFG_X32_MASK:
+		return DEV_X32;
 	}
 
-	return dt;
+	return DEV_UNKNOWN;
 }
 
 /**
@@ -730,19 +729,11 @@ static bool zynq_get_ecc_state(void __iomem *base)
  */
 static bool zynqmp_get_ecc_state(void __iomem *base)
 {
-	enum dev_type dt;
-	u32 ecctype;
+	u32 regval;
 
-	dt = zynqmp_get_dtype(base);
-	if (dt == DEV_UNKNOWN)
-		return false;
+	regval = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
 
-	ecctype = readl(base + ECC_CFG0_OFST) & SCRUB_MODE_MASK;
-	if ((ecctype == SCRUB_MODE_SECDED) &&
-	    ((dt == DEV_X2) || (dt == DEV_X4) || (dt == DEV_X8)))
-		return true;
-
-	return false;
+	return (regval == SCRUB_MODE_SECDED);
 }
 
 /**
-- 
2.43.0


  reply	other threads:[~2024-06-27 17:33 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-27 17:32 [PATCH RESEND v6 00/18] EDAC/mc/synopsys: Various fixes and cleanups Serge Semin
2024-06-27 17:32 ` Serge Semin [this message]
2024-06-28  6:01   ` [PATCH RESEND v6 01/18] EDAC/synopsys: Fix generic device type detection procedure Borislav Petkov
2024-06-27 17:32 ` [PATCH RESEND v6 02/18] EDAC/synopsys: Fix mci->scrub_cap field setting Serge Semin
2024-07-09 11:35   ` Borislav Petkov
2024-07-11 15:11     ` Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 03/18] EDAC/synopsys: Drop erroneous ADDRMAP4.addrmap_col_b10 parse Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 04/18] EDAC/synopsys: Fix reading errors count before ECC status Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 05/18] EDAC/synopsys: Fix misleading IRQ self-cleared quirk flag Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 06/18] EDAC/synopsys: Drop internal CE and UE counters Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 07/18] EDAC/synopsys: Drop local to_mci() macro definition Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 08/18] EDAC/synopsys: Drop struct ecc_error_info.blknr field Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 09/18] EDAC/synopsys: Shorten out struct ecc_error_info.bankgrpnr field name Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 10/18] EDAC/synopsys: Drop redundant info from the error messages Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 11/18] EDAC/mc: Init DIMM labels in MC registration method Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 12/18] EDAC/mc: Add generic unique MC index allocation procedure Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 13/18] EDAC/mc: Re-use " Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 14/18] EDAC/synopsys: Detach Zynq A05 DDRC support to separate driver Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 15/18] EDAC/synopsys: Drop unused platform-specific setup API Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 16/18] EDAC/synopsys: Unify CSRs macro declarations Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 17/18] EDAC/synopsys: Unify struct/macro/function prefixes Serge Semin
2024-06-27 17:32 ` [PATCH RESEND v6 18/18] EDAC/synopsys: Convert to using BIT/GENMASK/FIELD_x macros Serge Semin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240627173251.25718-2-fancer.lancer@gmail.com \
    --to=fancer.lancer@gmail.com \
    --cc=alexander.stein@ew.tq-group.com \
    --cc=arnd@arndb.de \
    --cc=bp@alien8.de \
    --cc=bp@suse.de \
    --cc=dinguyen@kernel.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=james.morse@arm.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-edac@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=manish.narani@xilinx.com \
    --cc=mchehab@kernel.org \
    --cc=michal.simek@amd.com \
    --cc=punnaiah.choudary.kalluri@xilinx.com \
    --cc=rric@kernel.org \
    --cc=shubhrajyoti.datta@amd.com \
    --cc=shubhrajyoti.datta@gmail.com \
    --cc=tony.luck@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox