linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: Serge Semin <Sergey.Semin@baikalelectronics.ru>
To: Michal Simek <michal.simek@xilinx.com>,
	Borislav Petkov <bp@alien8.de>,
	Mauro Carvalho Chehab <mchehab@kernel.org>,
	Tony Luck <tony.luck@intel.com>,
	James Morse <james.morse@arm.com>,
	Robert Richter <rric@kernel.org>
Cc: Serge Semin <Sergey.Semin@baikalelectronics.ru>,
	Serge Semin <fancer.lancer@gmail.com>,
	Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>,
	Michail Ivanov <Michail.Ivanov@baikalelectronics.ru>,
	Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>,
	Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com>,
	Manish Narani <manish.narani@xilinx.com>,
	Dinh Nguyen <dinguyen@kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<linux-edac@vger.kernel.org>, <linux-kernel@vger.kernel.org>
Subject: [PATCH RESEND v3 05/18] EDAC/synopsys: Add DDRC basic parameters infrastructure
Date: Fri, 30 Sep 2022 02:35:17 +0300	[thread overview]
Message-ID: <20220929233530.13016-6-Sergey.Semin@baikalelectronics.ru> (raw)
In-Reply-To: <20220929233530.13016-1-Sergey.Semin@baikalelectronics.ru>

Currently the driver supports a single DW uMCTL2 DDRC IP-core: 64-bit DQ
bus, ECC SEC/DED with always on Scrub (HW-src scrub). This makes the
driver application being very limited. In addition to that lacking of any
controller capabilities/parameters infrastructure makes it harder to add
optional features support. Let's overcome all of that by adding a simple
DW uMCTL2 DDRC IP-core parameters infrastructure. It's made of the
snps_ddrc_info structure and a new method snps_get_ddrc_info() introduced
to fill the structure fields in. The structure contains the IP-core
parameters needed to create a more comprehensive driver and will be used
in the driver to activate/de-activate various features:
- ECC Mode: SEC/DED or Advanced X4/X8 ECC features. (Currently SEC/DED is
  only supported.)
- SDRAM mode: (LP)DDR[2-4] memory interfaces. (Required for the HIF/SDRAM
  address translation.)
- Memory Device config: Memory chips detected on the platform. (Applicable
  for DDR4 setups only.)
- DQ-bus width: Maximal DQ-bus width utilized by the device. (Required for
  the Application/HIF address translation.)
- DQ-bus mode: Actual DQ-bus width used to access the memory devices.
  (Required for the HIF/SDRAM address translation and ECC grain calc.)
- HIF/SDRAM burst length: Required for the Scrubber bandwidth
  calculation.
- HIF/SDRAM frequency ratio: Required for the SDRAM bandwidth
  calculation.
- SDRAM ranks number: Required for the Application/HIF address
  translation.

The list can be easily updated should any additional features support is
required to be added in future, but at this stage the driver is fixed in a
few places to have the new infrastructure utilized: SDRAM column address
mapper, MCI csrows initialization.

Note getting all of these parameters in a single method is very suitable
from two perspectives. First it localizes the IP-core parameters detection
thus improving the code readability and maintainability. Second it's very
suitable for the platform-specific quirks implementation. Since some of
the IP-core parameters can't be auto-detected at run-time, they will be
able to be fixed right in the parameters getter by means of the platform
quirks.

Signed-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>
---
 drivers/edac/synopsys_edac.c | 268 +++++++++++++++++++++++++++--------
 1 file changed, 211 insertions(+), 57 deletions(-)

diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c
index f2f83b24d62c..b4db70224ee9 100644
--- a/drivers/edac/synopsys_edac.c
+++ b/drivers/edac/synopsys_edac.c
@@ -12,6 +12,7 @@
 #include <linux/fs.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/seq_file.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 #include <linux/of.h>
@@ -87,16 +88,21 @@
 /* DDR Software control register */
 #define DDR_SWCTL			0x320
 
+/* ECC Poison pattern registers */
+#define ECC_POISONPAT0_OFST		0x37C
+#define ECC_POISONPAT1_OFST		0x380
+#define ECC_POISONPAT2_OFST		0x384
+
 /* DDR Master Register 0 definitions */
 #define DDR_MSTR_DEV_CFG_MASK		GENMASK(31, 30)
 #define DDR_MSTR_DEV_X4			0x0
 #define DDR_MSTR_DEV_X8			0x1
 #define DDR_MSTR_DEV_X16		0x2
 #define DDR_MSTR_DEV_X32		0x3
+#define DDR_MSTR_ACT_RANKS_MASK		GENMASK(27, 24)
+#define DDR_MSTR_FREQ_RATIO11		BIT(22)
+#define DDR_MSTR_BURST_RDWR		GENMASK(19, 16)
 #define DDR_MSTR_BUSWIDTH_MASK		GENMASK(13, 12)
-#define DDRCTL_EWDTH_16			2
-#define DDRCTL_EWDTH_32			1
-#define DDRCTL_EWDTH_64			0
 #define DDR_MSTR_MEM_MASK		GENMASK(5, 0)
 #define DDR_MSTR_MEM_DDR2		0
 #define DDR_MSTR_MEM_DDR3		BIT(0)
@@ -108,7 +114,6 @@
 
 /* ECC CFG0 register definitions */
 #define ECC_CFG0_MODE_MASK		GENMASK(2, 0)
-#define ECC_CFG0_MODE_SECDED		0x4
 
 /* ECC status register definitions */
 #define ECC_STAT_UE_MASK		GENMASK(23, 16)
@@ -206,6 +211,91 @@
 
 #define RANK_B0_BASE			6
 
+/**
+ * enum snps_dq_width - SDRAM DQ bus width (ECC capable).
+ * SNPS_DQ_32:	32-bit memory data width.
+ * SNPS_DQ_64:	64-bit memory data width.
+ */
+enum snps_dq_width {
+	SNPS_DQ_32 = 2,
+	SNPS_DQ_64 = 3,
+};
+
+/**
+ * enum snps_dq_mode - SDRAM DQ bus mode.
+ * @SNPS_DQ_FULL:	Full DQ bus width.
+ * @SNPS_DQ_HALF:	Half DQ bus width.
+ * @SNPS_DQ_QRTR:	Quarter DQ bus width.
+ */
+enum snps_dq_mode {
+	SNPS_DQ_FULL = 0,
+	SNPS_DQ_HALF = 1,
+	SNPS_DQ_QRTR = 2,
+};
+
+/**
+ * enum snps_burst_length - HIF/SDRAM burst transactions length.
+ * @SNPS_DDR_BL2:	Burst length 2xSDRAM-words.
+ * @SNPS_DDR_BL4:	Burst length 4xSDRAM-words.
+ * @SNPS_DDR_BL8:	Burst length 8xSDRAM-words.
+ * @SNPS_DDR_BL16:	Burst length 16xSDRAM-words.
+ */
+enum snps_burst_length {
+	SNPS_DDR_BL2 = 2,
+	SNPS_DDR_BL4 = 4,
+	SNPS_DDR_BL8 = 8,
+	SNPS_DDR_BL16 = 16,
+};
+
+/**
+ * enum snps_freq_ratio - HIF:SDRAM frequency ratio mode.
+ * @SNPS_FREQ_RATIO11:	1:1 frequency mode.
+ * @SNPS_FREQ_RATIO12:	1:2 frequency mode.
+ */
+enum snps_freq_ratio {
+	SNPS_FREQ_RATIO11 = 1,
+	SNPS_FREQ_RATIO12 = 2,
+};
+
+/**
+ * enum snps_ecc_mode - ECC mode.
+ * @SNPS_ECC_DISABLED:	ECC is disabled/unavailable.
+ * @SNPS_ECC_SECDED:	SEC/DED over 1 beat ECC (SideBand/Inline).
+ * @SNPS_ECC_ADVX4X8:	Advanced ECC X4/X8 (SideBand).
+ */
+enum snps_ecc_mode {
+	SNPS_ECC_DISABLED = 0,
+	SNPS_ECC_SECDED = 4,
+	SNPS_ECC_ADVX4X8 = 5,
+};
+
+/**
+ * struct snps_ddrc_info - DDR controller platform parameters.
+ * @caps:		DDR controller capabilities.
+ * @sdram_mode:		Current SDRAM mode selected.
+ * @dev_cfg:		Current memory device config (if applicable).
+ * @dq_width:		Memory data bus width (width of the DQ signals
+ *			connected to SDRAM chips).
+ * @dq_mode:		Proportion of the DQ bus utilized to access SDRAM.
+ * @sdram_burst_len:	SDRAM burst transaction length.
+ * @hif_burst_len:	HIF burst transaction length (Host Interface).
+ * @freq_ratio:		HIF/SDRAM frequency ratio mode.
+ * @ecc_mode:		ECC mode enabled for the DDR controller (SEC/DED, etc).
+ * @ranks:		Number of ranks enabled to access DIMM (1, 2 or 4).
+ */
+struct snps_ddrc_info {
+	unsigned int caps;
+	enum mem_type sdram_mode;
+	enum dev_type dev_cfg;
+	enum snps_dq_width dq_width;
+	enum snps_dq_mode dq_mode;
+	enum snps_burst_length sdram_burst_len;
+	enum snps_burst_length hif_burst_len;
+	enum snps_freq_ratio freq_ratio;
+	enum snps_ecc_mode ecc_mode;
+	unsigned int ranks;
+};
+
 /**
  * struct snps_ecc_error_info - ECC error log information.
  * @row:	Row number.
@@ -240,6 +330,7 @@ struct snps_ecc_status {
 
 /**
  * struct snps_edac_priv - DDR memory controller private data.
+ * @info:		DDR controller config info.
  * @pdev:		Platform device.
  * @baseaddr:		Base address of the DDR controller.
  * @lock:		Concurrent CSRs access lock.
@@ -254,6 +345,7 @@ struct snps_ecc_status {
  * @rank_shift:		Bit shifts for rank bit.
  */
 struct snps_edac_priv {
+	struct snps_ddrc_info info;
 	struct platform_device *pdev;
 	void __iomem *baseaddr;
 	spinlock_t lock;
@@ -492,23 +584,19 @@ static struct snps_edac_priv *snps_create_data(struct platform_device *pdev)
 
 /**
  * snps_get_dtype - Return the controller memory width.
- * @base:	DDR memory controller base address.
+ * @mstr:	Master CSR value.
  *
  * Get the EDAC device type width appropriate for the current controller
  * configuration.
  *
  * Return: a device type width enumeration.
  */
-static enum dev_type snps_get_dtype(const void __iomem *base)
+static inline enum dev_type snps_get_dtype(u32 mstr)
 {
-	u32 regval;
-
-	regval = readl(base + DDR_MSTR_OFST);
-	if (!(regval & DDR_MSTR_MEM_DDR4))
+	if (!(mstr & DDR_MSTR_MEM_DDR4))
 		return DEV_UNKNOWN;
 
-	regval = FIELD_GET(DDR_MSTR_DEV_CFG_MASK, regval);
-	switch (regval) {
+	switch (FIELD_GET(DDR_MSTR_DEV_CFG_MASK, mstr)) {
 	case DDR_MSTR_DEV_X4:
 		return DEV_X4;
 	case DDR_MSTR_DEV_X8:
@@ -522,24 +610,6 @@ static enum dev_type snps_get_dtype(const void __iomem *base)
 	return DEV_UNKNOWN;
 }
 
-/**
- * snps_get_ecc_state - Return the controller ECC enable/disable status.
- * @base:	DDR memory controller base address.
- *
- * Get the ECC enable/disable status for the controller.
- *
- * Return: a ECC status boolean i.e true/false - enabled/disabled.
- */
-static bool snps_get_ecc_state(void __iomem *base)
-{
-	u32 regval;
-
-	regval = readl(base + ECC_CFG0_OFST);
-	regval = FIELD_GET(ECC_CFG0_MODE_MASK, regval);
-
-	return (regval == ECC_CFG0_MODE_SECDED);
-}
-
 /**
  * snps_get_memsize - Read the size of the attached memory device.
  *
@@ -556,21 +626,16 @@ static u32 snps_get_memsize(void)
 
 /**
  * snps_get_mtype - Returns controller memory type.
- * @base:	Synopsys ECC status structure.
+ * @mstr:	Master CSR value.
  *
  * Get the EDAC memory type appropriate for the current controller
  * configuration.
  *
  * Return: a memory type enumeration.
  */
-static enum mem_type snps_get_mtype(const void __iomem *base)
+static inline enum mem_type snps_get_mtype(u32 mstr)
 {
-	u32 regval;
-
-	regval = readl(base + DDR_MSTR_OFST);
-	regval = FIELD_GET(DDR_MSTR_MEM_MASK, regval);
-
-	switch (regval) {
+	switch (FIELD_GET(DDR_MSTR_MEM_MASK, mstr)) {
 	case DDR_MSTR_MEM_DDR2:
 		return MEM_DDR2;
 	case DDR_MSTR_MEM_DDR3:
@@ -590,6 +655,69 @@ static enum mem_type snps_get_mtype(const void __iomem *base)
 	return MEM_RESERVED;
 }
 
+/**
+ * snps_get_ddrc_info - Get the DDR controller config data.
+ * @priv:	DDR memory controller private data.
+ *
+ * Return: negative errno if no ECC detected, otherwise - zero.
+ */
+static int snps_get_ddrc_info(struct snps_edac_priv *priv)
+{
+	int (*init_plat)(struct snps_edac_priv *priv);
+	u32 regval;
+
+	/* Before getting the DDRC parameters make sure ECC is enabled */
+	regval = readl(priv->baseaddr + ECC_CFG0_OFST);
+
+	priv->info.ecc_mode = FIELD_GET(ECC_CFG0_MODE_MASK, regval);
+	if (priv->info.ecc_mode != SNPS_ECC_SECDED) {
+		edac_printk(KERN_INFO, EDAC_MC, "SEC/DED ECC not enabled\n");
+		return -ENXIO;
+	}
+
+	/* Auto-detect the basic HIF/SDRAM bus parameters */
+	regval = readl(priv->baseaddr + DDR_MSTR_OFST);
+
+	priv->info.sdram_mode = snps_get_mtype(regval);
+	priv->info.dev_cfg = snps_get_dtype(regval);
+
+	priv->info.dq_mode = FIELD_GET(DDR_MSTR_BUSWIDTH_MASK, regval);
+
+	/*
+	 * Assume HIF burst length matches the SDRAM burst length since it's
+	 * not auto-detectable
+	 */
+	priv->info.sdram_burst_len = FIELD_GET(DDR_MSTR_BURST_RDWR, regval) << 1;
+	priv->info.hif_burst_len = priv->info.sdram_burst_len;
+
+	/* Retrieve the current HIF/SDRAM frequency ratio: 1:1 vs 1:2 */
+	priv->info.freq_ratio = !(regval & DDR_MSTR_FREQ_RATIO11) + 1;
+
+	/* Activated ranks field: set bit corresponds to populated rank */
+	priv->info.ranks = FIELD_GET(DDR_MSTR_ACT_RANKS_MASK, regval);
+	priv->info.ranks = hweight_long(priv->info.ranks);
+
+	/* Auto-detect the DQ bus width by using the ECC-poison pattern CSR */
+	writel(0, priv->baseaddr + DDR_SWCTL);
+
+	/*
+	 * If poison pattern [32:64] is changeable then DQ is 64-bit wide.
+	 * Note the feature has been available since IP-core v2.51a.
+	 */
+	regval = readl(priv->baseaddr + ECC_POISONPAT1_OFST);
+	writel(~regval, priv->baseaddr + ECC_POISONPAT1_OFST);
+	if (regval != readl(priv->baseaddr + ECC_POISONPAT1_OFST)) {
+		priv->info.dq_width = SNPS_DQ_64;
+		writel(regval, priv->baseaddr + ECC_POISONPAT1_OFST);
+	} else {
+		priv->info.dq_width = SNPS_DQ_32;
+	}
+
+	writel(1, priv->baseaddr + DDR_SWCTL);
+
+	return 0;
+}
+
 /**
  * snps_init_csrows - Initialize the csrow data.
  * @mci:	EDAC memory controller instance.
@@ -612,10 +740,10 @@ static void snps_init_csrows(struct mem_ctl_info *mci)
 		for (j = 0; j < csi->nr_channels; j++) {
 			dimm		= csi->channels[j]->dimm;
 			dimm->edac_mode	= EDAC_SECDED;
-			dimm->mtype	= snps_get_mtype(priv->baseaddr);
+			dimm->mtype	= priv->info.sdram_mode;
 			dimm->nr_pages	= (size >> PAGE_SHIFT) / csi->nr_channels;
 			dimm->grain	= SNPS_EDAC_ERR_GRAIN;
-			dimm->dtype	= snps_get_dtype(priv->baseaddr);
+			dimm->dtype	= priv->info.dev_cfg;
 		}
 	}
 }
@@ -729,6 +857,33 @@ static int snps_setup_irq(struct mem_ctl_info *mci)
 
 #define SNPS_DBGFS_BUF_LEN 128
 
+static int snps_ddrc_info_show(struct seq_file *s, void *data)
+{
+	struct mem_ctl_info *mci = s->private;
+	struct snps_edac_priv *priv = mci->pvt_info;
+
+	seq_printf(s, "SDRAM: %s\n", edac_mem_types[priv->info.sdram_mode]);
+
+	seq_printf(s, "DQ bus: %u/%s\n", (BITS_PER_BYTE << priv->info.dq_width),
+		   priv->info.dq_mode == SNPS_DQ_FULL ? "Full" :
+		   priv->info.dq_mode == SNPS_DQ_HALF ? "Half" :
+		   priv->info.dq_mode == SNPS_DQ_QRTR ? "Quarter" :
+		   "Unknown");
+	seq_printf(s, "Burst: SDRAM %u HIF %u\n", priv->info.sdram_burst_len,
+		   priv->info.hif_burst_len);
+
+	seq_printf(s, "Ranks: %u\n", priv->info.ranks);
+
+	seq_printf(s, "ECC: %s\n",
+		   priv->info.ecc_mode == SNPS_ECC_SECDED ? "SEC/DED" :
+		   priv->info.ecc_mode == SNPS_ECC_ADVX4X8 ? "Advanced X4/X8" :
+		   "Unknown");
+
+	return 0;
+}
+
+DEFINE_SHOW_ATTRIBUTE(snps_ddrc_info);
+
 /**
  * snps_data_poison_setup - Update poison registers.
  * @priv:		DDR memory controller private instance data.
@@ -850,12 +1005,8 @@ static void snps_setup_row_address_map(struct snps_edac_priv *priv, u32 *addrmap
 
 static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addrmap)
 {
-	u32 width, memtype;
 	int index;
 
-	memtype = readl(priv->baseaddr + DDR_MSTR_OFST);
-	width = FIELD_GET(DDR_MSTR_BUSWIDTH_MASK, memtype);
-
 	priv->col_shift[0] = 0;
 	priv->col_shift[1] = 1;
 	priv->col_shift[2] = (addrmap[2] & COL_MAX_VAL_MASK) + COL_B2_BASE;
@@ -879,8 +1030,8 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr
 	priv->col_shift[9] = (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) ==
 			COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 24) &
 					COL_MAX_VAL_MASK) + COL_B9_BASE);
-	if (width == DDRCTL_EWDTH_64) {
-		if (memtype & DDR_MSTR_MEM_LPDDR3) {
+	if (priv->info.dq_mode == SNPS_DQ_FULL) {
+		if (priv->info.sdram_mode == MEM_LPDDR3) {
 			priv->col_shift[10] = ((addrmap[4] &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				((addrmap[4] & COL_MAX_VAL_MASK) +
@@ -899,8 +1050,8 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr
 				(((addrmap[4] >> 8) & COL_MAX_VAL_MASK) +
 				 COL_B11_BASE);
 		}
-	} else if (width == DDRCTL_EWDTH_32) {
-		if (memtype & DDR_MSTR_MEM_LPDDR3) {
+	} else if (priv->info.dq_mode == SNPS_DQ_HALF) {
+		if (priv->info.sdram_mode == MEM_LPDDR3) {
 			priv->col_shift[10] = (((addrmap[3] >> 24) &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				(((addrmap[3] >> 24) & COL_MAX_VAL_MASK) +
@@ -920,7 +1071,7 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr
 				 COL_B10_BASE);
 		}
 	} else {
-		if (memtype & DDR_MSTR_MEM_LPDDR3) {
+		if (priv->info.sdram_mode == MEM_LPDDR3) {
 			priv->col_shift[10] = (((addrmap[3] >> 16) &
 				COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 :
 				(((addrmap[3] >> 16) & COL_MAX_VAL_MASK) +
@@ -941,10 +1092,11 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr
 		}
 	}
 
-	if (width) {
-		for (index = 9; index > width; index--) {
-			priv->col_shift[index] = priv->col_shift[index - width];
-			priv->col_shift[index - width] = 0;
+	if (priv->info.dq_mode) {
+		for (index = 9; index > priv->info.dq_mode; index--) {
+			priv->col_shift[index] =
+				priv->col_shift[index - priv->info.dq_mode];
+			priv->col_shift[index - priv->info.dq_mode] = 0;
 		}
 	}
 
@@ -1106,6 +1258,9 @@ static void snps_create_debugfs_nodes(struct mem_ctl_info *mci)
 
 	snps_setup_address_map(priv);
 
+	edac_debugfs_create_file("ddrc_info", 0400, mci->debugfs, mci,
+				 &snps_ddrc_info_fops);
+
 	edac_debugfs_create_file("inject_data_error", 0600, mci->debugfs, mci,
 				 &snps_inject_data_error);
 
@@ -1138,10 +1293,9 @@ static int snps_mc_probe(struct platform_device *pdev)
 	if (IS_ERR(priv))
 		return PTR_ERR(priv);
 
-	if (!snps_get_ecc_state(baseaddr)) {
-		edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n");
-		return -ENXIO;
-	}
+	rc = snps_get_ddrc_info(priv);
+	if (rc)
+		return rc;
 
 	mci = snps_mc_create(priv);
 	if (IS_ERR(mci))
-- 
2.37.3



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2022-09-29 23:45 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-29 23:35 [PATCH RESEND v3 00/18] EDAC/synopsys: Add generic DDRC info and address mapping Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 01/18] EDAC/synopsys: Convert sysfs nodes to debugfs ones Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 02/18] EDAC/mc: Extend memtypes with LPDDR(mDDR) and LPDDR2 Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 03/18] EDAC/synopsys: Extend memtypes supported by controller Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 04/18] EDAC/synopsys: Detach private data from mci instance Serge Semin
2022-09-29 23:35 ` Serge Semin [this message]
2022-09-29 23:35 ` [PATCH RESEND v3 06/18] EDAC/synopsys: Convert plat-data to plat-init function Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 07/18] EDAC/synopsys: Parse ADDRMAP[7-8] CSRs for (LP)DDR4 only Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 08/18] EDAC/synopsys: Parse ADDRMAP[0] CSR for multi-ranks case only Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 09/18] EDAC/synopsys: Set actual DIMM ECC errors grain Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 10/18] EDAC/synopsys: Get corrected bit position Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 11/18] EDAC/synopsys: Read full data pattern on errors Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 12/18] EDAC/synopsys: Read data syndrome " Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 13/18] EDAC/synopsys: Introduce System/SDRAM address translation interface Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 14/18] EDAC/synopsys: Simplify HIF/SDRAM column mapping get procedure Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 15/18] EDAC/synopsys: Add HIF/SDRAM mapping debugfs node Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 16/18] EDAC/synopsys: Add erroneous page-frame/offset reporting Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 17/18] EDAC/synopsys: Add system address regions support Serge Semin
2022-09-29 23:35 ` [PATCH RESEND v3 18/18] EDAC/synopsys: Add mapping-based memory size calculation 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=20220929233530.13016-6-Sergey.Semin@baikalelectronics.ru \
    --to=sergey.semin@baikalelectronics.ru \
    --cc=Alexey.Malahov@baikalelectronics.ru \
    --cc=Michail.Ivanov@baikalelectronics.ru \
    --cc=Pavel.Parkhomenko@baikalelectronics.ru \
    --cc=bp@alien8.de \
    --cc=dinguyen@kernel.org \
    --cc=fancer.lancer@gmail.com \
    --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@xilinx.com \
    --cc=punnaiah.choudary.kalluri@xilinx.com \
    --cc=rric@kernel.org \
    --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;
as well as URLs for NNTP newsgroup(s).