* [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC
@ 2025-01-27 14:22 Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 1/8] k3-ddr.c: Remove unwanted header files Neha Malcom Francis
` (7 more replies)
0 siblings, 8 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
Currently, the inline ECC implementation enables inline ECC across the
entire DDR space. However this is not always required and a more common
ask is to have only a portion of the DDR protected as enabling ECC
impacts read/write performance metrics.
This series aims to modify the logic to firstly support partial inline
ECC in its' most basic form which works for single controllers. Then it
introduces an algorithm to support multi DDR controllers where
interleaving plays a role. Since interleaving is handled by the MSMC, it
only makes sense to have the MSMC decide the inline ECC ranges for each
DDR.
WIP: A commandline test case patch for verifying the correct behaviour
of inline ECC including partial case. Will add the patch in v2, for now
repeated boot tests on the affected platforms as well as internal
memtester runs stand as testing.
Boot logs (J721S2): https://gist.github.com/nehamalcom/e5a76bece133c1ec716e2ed94d60ce74
Neha Malcom Francis (8):
k3-ddr.c: Remove unwanted header files
ram: k3-ddrss: Use DDR address instead of system address for
ecc_regions
ram: k3-ddrss: Add comment about ecc_reserved_space
ram: k3-ddrss: Add support for a partial inline ECC region
ram: k3-ddrss: Add CONFIG_K3_MULTI_DDR
ram: k3-ddrss: Add support for number of controllers under MSMC
ram: k3-ddrss: Add support for MSMC calculation of DDR inline ECC
regions
ram: k3-ddrss: Add support for partial inline ECC in multi-DDR systems
arch/arm/mach-k3/k3-ddr.c | 1 -
board/ti/common/k3-ddr.c | 1 -
drivers/ram/Kconfig | 10 ++
drivers/ram/k3-ddrss/k3-ddrss.c | 227 ++++++++++++++++++++++++++++++--
4 files changed, 226 insertions(+), 13 deletions(-)
--
2.34.1
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH 1/8] k3-ddr.c: Remove unwanted header files
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-28 5:02 ` Wadim Egorov
2025-01-27 14:22 ` [PATCH 2/8] ram: k3-ddrss: Use DDR address instead of system address for ecc_regions Neha Malcom Francis
` (6 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
This header file is not in use in these arch/board specific files,
remove them.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
arch/arm/mach-k3/k3-ddr.c | 1 -
board/ti/common/k3-ddr.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/arm/mach-k3/k3-ddr.c b/arch/arm/mach-k3/k3-ddr.c
index 6e3e60cdc86..026381490da 100644
--- a/arch/arm/mach-k3/k3-ddr.c
+++ b/arch/arm/mach-k3/k3-ddr.c
@@ -5,7 +5,6 @@
#include <fdt_support.h>
#include <dm/uclass.h>
-#include <k3-ddrss.h>
#include <spl.h>
#include <asm/arch/k3-ddr.h>
diff --git a/board/ti/common/k3-ddr.c b/board/ti/common/k3-ddr.c
index a8425da8de5..926f6ea0e7d 100644
--- a/board/ti/common/k3-ddr.c
+++ b/board/ti/common/k3-ddr.c
@@ -5,7 +5,6 @@
#include <fdt_support.h>
#include <dm/uclass.h>
-#include <k3-ddrss.h>
#include <spl.h>
#include "k3-ddr.h"
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 2/8] ram: k3-ddrss: Use DDR address instead of system address for ecc_regions
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 1/8] k3-ddr.c: Remove unwanted header files Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-28 5:46 ` Kumar, Udit
2025-01-27 14:22 ` [PATCH 3/8] ram: k3-ddrss: Add comment about ecc_reserved_space Neha Malcom Francis
` (5 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
Let ecc_regions[x].start reflect the start of the ECC region in terms of
DDR addressing rather than system addressing. This will make it easier
to extend the usage of the same ecc_regions structure for multi-DDR
systems as well.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
| 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index 05ea61bbfe9..24932cd837c 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -730,7 +730,7 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
u32 val;
/* Only Program region 0 which covers full ddr space */
- k3_ddrss_set_ecc_range_r0(base, ecc_region_start - ddrss->ddr_bank_base[0], ecc_range);
+ k3_ddrss_set_ecc_range_r0(base, ecc_region_start, ecc_range);
/* Enable ECC, RMW, WR_ALLOC */
writel(DDRSS_ECC_CTRL_REG_ECC_EN | DDRSS_ECC_CTRL_REG_RMW_EN |
@@ -799,7 +799,7 @@ static int k3_ddrss_probe(struct udevice *dev)
k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
/* Always configure one region that covers full DDR space */
- ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0];
+ ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] - ddrss->ddr_bank_base[0];
ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
k3_ddrss_lpddr4_ecc_init(ddrss);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 3/8] ram: k3-ddrss: Add comment about ecc_reserved_space
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 1/8] k3-ddr.c: Remove unwanted header files Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 2/8] ram: k3-ddrss: Use DDR address instead of system address for ecc_regions Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-28 5:47 ` Kumar, Udit
2025-01-27 14:22 ` [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region Neha Malcom Francis
` (4 subsequent siblings)
7 siblings, 1 reply; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
The reserved space needed for storing the parity remains the same no
matter the size of the region that is being protected. Add this as a
comment for better code understanding.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
| 4 ++++
1 file changed, 4 insertions(+)
--git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index 24932cd837c..ab46098adbf 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -715,6 +715,10 @@ static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss)
{
fdtdec_setup_mem_size_base_lowest();
+ /*
+ * Reserved region remains 1/9th of the total DDR available no matter the
+ * size of the region under protection
+ */
ddrss->ecc_reserved_space = ddrss->ddr_ram_size;
do_div(ddrss->ecc_reserved_space, 9);
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
` (2 preceding siblings ...)
2025-01-27 14:22 ` [PATCH 3/8] ram: k3-ddrss: Add comment about ecc_reserved_space Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-28 5:13 ` Wadim Egorov
2025-01-28 5:53 ` Kumar, Udit
2025-01-27 14:22 ` [PATCH 5/8] ram: k3-ddrss: Add CONFIG_K3_MULTI_DDR Neha Malcom Francis
` (3 subsequent siblings)
7 siblings, 2 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
Instead of defaulting to choosing the entire DDR region when enabling
inline ECC, allow picking of a range within the DDR space using DT to
enable.
It expects such a node within the memory node, in the absence of which
we resort to enabling inline ECC for the entire DDR region:
inline_ecc: protected@9e780000 {
device_type = "ecc";
reg = <0x9e780000 0x0080000>;
bootph-all;
};
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
| 52 +++++++++++++++++++++++++++++++--
1 file changed, 49 insertions(+), 3 deletions(-)
--git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index ab46098adbf..ea2578cda58 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -149,6 +149,7 @@ struct k3_ddrss_desc {
lpddr4_obj *driverdt;
lpddr4_config config;
lpddr4_privatedata pd;
+ struct k3_ddrss_ecc_region ecc_range;
struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS];
u64 ecc_reserved_space;
u64 ddr_bank_base[CONFIG_NR_DRAM_BANKS];
@@ -711,6 +712,30 @@ static void k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss)
ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank];
}
+static void k3_ddrss_ddr_inline_ecc_base_size_calc(struct k3_ddrss_ecc_region *range)
+{
+ fdt_addr_t base;
+ fdt_size_t size;
+ ofnode node1;
+
+ node1 = ofnode_null();
+
+ do {
+ node1 = ofnode_by_prop_value(node1, "device_type", "ecc", 4);
+ } while (!ofnode_is_enabled(node1));
+
+ base = ofnode_get_addr_size(node1, "reg", &size);
+
+ if (base == FDT_ADDR_T_NONE) {
+ debug("%s: Failed to get ECC node reg and size\n", __func__);
+ range->start = 0;
+ range->range = 0;
+ } else {
+ range->start = base;
+ range->range = size;
+ }
+}
+
static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss)
{
fdtdec_setup_mem_size_base_lowest();
@@ -759,8 +784,11 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
static int k3_ddrss_probe(struct udevice *dev)
{
+ u64 end;
int ret;
struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
+ __maybe_unused struct k3_ddrss_data *ddrss_data = (struct k3_ddrss_data *)dev_get_driver_data(dev);
+ __maybe_unused struct k3_ddrss_ecc_region *range = &ddrss->ecc_range;
debug("%s(dev=%p)\n", __func__, dev);
@@ -802,9 +830,27 @@ static int k3_ddrss_probe(struct udevice *dev)
k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
- /* Always configure one region that covers full DDR space */
- ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] - ddrss->ddr_bank_base[0];
- ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
+ k3_ddrss_ddr_inline_ecc_base_size_calc(range);
+ if (!range->range) {
+ /* Configure entire DDR space by default */
+ debug("%s: Defaulting to protecting entire DDR space using inline ECC\n",
+ __func__);
+ ddrss->ecc_range.start = ddrss->ddr_bank_base[0];
+ ddrss->ecc_range.range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
+ } else {
+ ddrss->ecc_range.start = range->start;
+ ddrss->ecc_range.range = range->range;
+ }
+
+ end = ddrss->ecc_range.start + ddrss->ecc_range.range;
+
+ if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
+ ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
+ else
+ ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
+
+ ddrss->ecc_regions[0].start = ddrss->ecc_range.start - ddrss->ddr_bank_base[0];
+
k3_ddrss_lpddr4_ecc_init(ddrss);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 5/8] ram: k3-ddrss: Add CONFIG_K3_MULTI_DDR
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
` (3 preceding siblings ...)
2025-01-27 14:22 ` [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 6/8] ram: k3-ddrss: Add support for number of controllers under MSMC Neha Malcom Francis
` (2 subsequent siblings)
7 siblings, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
As we increase the functionalities that the K3 DDRSS sub-system support,
it is becoming more evident that the same logic cannot apply to both
single as well as multiple DDR controller devices. Add
CONFIG_K3_MULTI_DDR to be used to differentiate between the two.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
drivers/ram/Kconfig | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/ram/Kconfig b/drivers/ram/Kconfig
index 899d7585489..0d19021d8e3 100644
--- a/drivers/ram/Kconfig
+++ b/drivers/ram/Kconfig
@@ -126,6 +126,16 @@ config K3_INLINE_ECC
need to be primed with a predefined value prior to enabling ECC
check.
+config K3_MULTI_DDR
+ bool "Enable support for multiple K3 DDRSS controllers"
+ depends on K3_DDRSS
+ help
+ Enabling this option adds support for configuring multiple DDR memory
+ controllers for K3 devices. The external memory interleave layer
+ present in the MSMC (Multicore Shared Memory Controller) is
+ responsible for interleaving between the controllers.
+ default y if SOC_K3_J721S2 || SOC_K3_J784S4
+
source "drivers/ram/aspeed/Kconfig"
source "drivers/ram/cadence/Kconfig"
source "drivers/ram/octeon/Kconfig"
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 6/8] ram: k3-ddrss: Add support for number of controllers under MSMC
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
` (4 preceding siblings ...)
2025-01-27 14:22 ` [PATCH 5/8] ram: k3-ddrss: Add CONFIG_K3_MULTI_DDR Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 7/8] ram: k3-ddrss: Add support for MSMC calculation of DDR inline ECC regions Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 8/8] ram: k3-ddrss: Add support for partial inline ECC in multi-DDR systems Neha Malcom Francis
7 siblings, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
In K3 multi-DDR systems, the MSMC is responsible for the interleave
mechanism across all the DDR controllers. Add support for MSMC to obtain
the number of controllers it's responsible for using the DT.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
| 8 ++++++++
1 file changed, 8 insertions(+)
--git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index ea2578cda58..51b4c1bf45a 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -121,6 +121,7 @@ struct k3_msmc {
enum ecc_enable enable;
enum emif_config config;
enum emif_active active;
+ u32 num_ddr;
};
#define K3_DDRSS_MAX_ECC_REGIONS 3
@@ -985,6 +986,13 @@ static int k3_msmc_probe(struct udevice *dev)
return -EINVAL;
}
+ ret = device_get_child_count(dev);
+ if (ret <= 0) {
+ dev_err(dev, "no child ddr nodes present");
+ return -EINVAL;
+ }
+ msmc->num_ddr = ret;
+
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 7/8] ram: k3-ddrss: Add support for MSMC calculation of DDR inline ECC regions
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
` (5 preceding siblings ...)
2025-01-27 14:22 ` [PATCH 6/8] ram: k3-ddrss: Add support for number of controllers under MSMC Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 8/8] ram: k3-ddrss: Add support for partial inline ECC in multi-DDR systems Neha Malcom Francis
7 siblings, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
Add support for calculation of the protected regions for each DDR in
multi-DDR systems. Since MSMC is the parent node of the individual DDRs
as well as responsible for their interleaving, it only makes sense for
MSMC to contain the logic for dividing the regions.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
| 122 ++++++++++++++++++++++++++++++--
1 file changed, 115 insertions(+), 7 deletions(-)
--git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index 51b4c1bf45a..205dce51799 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -53,6 +53,7 @@
#define SINGLE_DDR_SUBSYSTEM 0x1
#define MULTI_DDR_SUBSYSTEM 0x2
+#define MAX_MULTI_DDR 4
#define MULTI_DDR_CFG0 0x00114100
#define MULTI_DDR_CFG1 0x00114104
@@ -76,6 +77,24 @@ enum intrlv_gran {
GRAN_16GB
};
+u64 gran_bytes[] = {
+ 0x80,
+ 0x200,
+ 0x800,
+ 0x1000,
+ 0x4000,
+ 0x8000,
+ 0x80000,
+ 0x40000000,
+ 0x60000000,
+ 0x80000000,
+ 0xC0000000,
+ 0x100000000,
+ 0x180000000,
+ 0x200000000,
+ 0x400000000
+};
+
enum intrlv_size {
SIZE_0,
SIZE_128MB,
@@ -115,6 +134,13 @@ enum emif_active {
EMIF_ALL
};
+#define K3_DDRSS_MAX_ECC_REGIONS 3
+
+struct k3_ddrss_ecc_region {
+ u64 start;
+ u64 range;
+};
+
struct k3_msmc {
enum intrlv_gran gran;
enum intrlv_size size;
@@ -122,13 +148,7 @@ struct k3_msmc {
enum emif_config config;
enum emif_active active;
u32 num_ddr;
-};
-
-#define K3_DDRSS_MAX_ECC_REGIONS 3
-
-struct k3_ddrss_ecc_region {
- u64 start;
- u64 range;
+ struct k3_ddrss_ecc_region R0[MAX_MULTI_DDR];
};
struct k3_ddrss_desc {
@@ -914,6 +934,83 @@ U_BOOT_DRIVER(k3_ddrss) = {
.priv_auto = sizeof(struct k3_ddrss_desc),
};
+#if IS_ENABLED(CONFIG_K3_MULTI_DDR)
+static int k3_msmc_calculate_r0_regions(struct k3_msmc *msmc)
+{
+ u32 n1;
+ u32 size, ret = 0;
+ u32 gran = gran_bytes[msmc->gran];
+ u32 num_ddr = msmc->num_ddr;
+ struct k3_ddrss_ecc_region *range = NULL;
+ struct k3_ddrss_ecc_region R[num_ddr];
+
+ range = kzalloc(sizeof(range), GFP_KERNEL);
+ if (!range) {
+ debug("%s: failed to allocate range\n", __func__);
+ ret = -ENOMEM;
+ return ret;
+ }
+
+ k3_ddrss_ddr_inline_ecc_base_size_calc(range);
+
+ if (!range->range) {
+ ret = -EINVAL;
+ goto range_err;
+ }
+
+ memset(R, 0, num_ddr);
+
+ /* Find the first controller in the range */
+ n1 = ((range->start / gran) % num_ddr);
+ size = range->range;
+
+ if (size < gran) {
+ R[n1].start = range->start - 0x80000000;
+ R[n1].range = range->start + range->range - 0x80000000;
+ } else {
+ u32 chunk_start_addr = range->start;
+ u32 chunk_size = range->range;
+
+ while (chunk_size > 0) {
+ u32 edge;
+ u32 end = range->start + range->range;
+
+ if ((chunk_start_addr % gran) == 0)
+ edge = chunk_start_addr + gran;
+ else
+ edge = ((chunk_start_addr + (gran - 1)) & (-gran));
+
+ if (edge > end)
+ break;
+
+ if (R[n1].start == 0)
+ R[n1].start = chunk_start_addr;
+
+ R[n1].range = edge - R[n1].start;
+ chunk_size = end - edge;
+ chunk_start_addr = edge;
+
+ if (n1 == (num_ddr - 1))
+ n1 = 0;
+ else
+ n1++;
+ }
+
+ for (int i = 0; i < num_ddr; i++)
+ R[i].start = (R[i].start - 0x80000000 - (gran * i)) / num_ddr;
+ }
+
+ for (int i = 0; i < num_ddr; i++) {
+ msmc->R0[i].start = R[i].start;
+ msmc->R0[i].range = R[i].range;
+ }
+
+range_err:
+ free(range);
+ return ret;
+}
+#endif
+
static int k3_msmc_set_config(struct k3_msmc *msmc)
{
u32 ddr_cfg0 = 0;
@@ -993,6 +1090,17 @@ static int k3_msmc_probe(struct udevice *dev)
}
msmc->num_ddr = ret;
+#if IS_ENABLED(CONFIG_K3_MULTI_DDR) && IS_ENABLED(CONFIG_K3_INLINE_ECC)
+ ret = k3_msmc_calculate_r0_regions(msmc);
+ if (ret) {
+ /* Default to enabling inline ECC for entire DDR region */
+ debug("%s: calculation of inline ECC regions failed, defaulting to entire region\n",
+ __func__);
+
+ /* Use first R0 entry as a flag to denote MSMC calculation failure */
+ msmc->R0[0].start = -1;
+ }
+#endif
return 0;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH 8/8] ram: k3-ddrss: Add support for partial inline ECC in multi-DDR systems
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
` (6 preceding siblings ...)
2025-01-27 14:22 ` [PATCH 7/8] ram: k3-ddrss: Add support for MSMC calculation of DDR inline ECC regions Neha Malcom Francis
@ 2025-01-27 14:22 ` Neha Malcom Francis
7 siblings, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-27 14:22 UTC (permalink / raw)
To: trini, bb, w.egorov, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, n-francis, u-boot
The existing approach does not account for interleaving in the DDRs when
setting up regions. There is support for MSMC to calculate the regions
for each DDR, so modify k3_ddrss_probe to set the regions accordingly
for multi-DDR systems.
Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
---
| 43 +++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
--git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
index 205dce51799..8429dddeb58 100644
--- a/drivers/ram/k3-ddrss/k3-ddrss.c
+++ b/drivers/ram/k3-ddrss/k3-ddrss.c
@@ -808,8 +808,10 @@ static int k3_ddrss_probe(struct udevice *dev)
u64 end;
int ret;
struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
+ __maybe_unused u32 inst, ddr_ram_size, ecc_res;
__maybe_unused struct k3_ddrss_data *ddrss_data = (struct k3_ddrss_data *)dev_get_driver_data(dev);
__maybe_unused struct k3_ddrss_ecc_region *range = &ddrss->ecc_range;
+ __maybe_unused struct k3_msmc *msmc_parent = NULL;
debug("%s(dev=%p)\n", __func__, dev);
@@ -863,14 +865,51 @@ static int k3_ddrss_probe(struct udevice *dev)
ddrss->ecc_range.range = range->range;
}
+#if !CONFIG_IS_ENABLED(K3_MULTI_DDR)
end = ddrss->ecc_range.start + ddrss->ecc_range.range;
+ inst = ddrss->instance;
+ ddr_ram_size = ddrss->ddr_ram_size;
+ ecc_res = ddrss->ecc_reserved_space;
- if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
- ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
+ if (end > (ddr_ram_size - ecc_res))
+ ddrss->ecc_regions[0].range = ddr_ram_size - ecc_res;
else
ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
ddrss->ecc_regions[0].start = ddrss->ecc_range.start - ddrss->ddr_bank_base[0];
+#else
+
+ /* In case multi-DDR, we rely on MSMC's calculation of regions for each DDR */
+ msmc_parent = kzalloc(sizeof(msmc_parent), GFP_KERNEL);
+ if (!msmc_parent) {
+ debug("%s: failed to allocate msmc_parent\n", __func__);
+ return -ENOMEM;
+ }
+ msmc_parent = dev_get_priv(dev->parent);
+ if (!msmc_parent) {
+ printf("%s: could not get MSMC parent to set up inline ECC regions\n",
+ __func__);
+ kfree(msmc_parent);
+ return -EINVAL;
+ }
+
+ if (msmc_parent->R0[0].start < 0) {
+ /* Configure entire DDR space by default */
+ ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0];
+ ddrss->ecc_regions[0].range = ddr_ram_size - ecc_res;
+ } else {
+ end = msmc_parent->R0[inst].start + msmc_parent->R0[inst].range;
+
+ if (end > (ddr_ram_size - ecc_res))
+ ddrss->ecc_regions[0].range = ddr_ram_size - ecc_res;
+ else
+ ddrss->ecc_regions[0].range = msmc_parent->R0[inst].range;
+
+ ddrss->ecc_regions[0].start = msmc_parent->R0[inst].start;
+ }
+
+ kfree(msmc_parent);
+#endif
k3_ddrss_lpddr4_ecc_init(ddrss);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH 1/8] k3-ddr.c: Remove unwanted header files
2025-01-27 14:22 ` [PATCH 1/8] k3-ddr.c: Remove unwanted header files Neha Malcom Francis
@ 2025-01-28 5:02 ` Wadim Egorov
2025-01-28 5:19 ` Neha Malcom Francis
0 siblings, 1 reply; 18+ messages in thread
From: Wadim Egorov @ 2025-01-28 5:02 UTC (permalink / raw)
To: Neha Malcom Francis, trini, bb, s-k6, marek.vasut+renesas,
sabiya.d
Cc: u-kumar1, u-boot
Hi Neha,
Am 27.01.25 um 21:22 schrieb Neha Malcom Francis:
> This header file is not in use in these arch/board specific files,
> remove them.
>
> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
> ---
> arch/arm/mach-k3/k3-ddr.c | 1 -
> board/ti/common/k3-ddr.c | 1 -
> 2 files changed, 2 deletions(-)
>
> diff --git a/arch/arm/mach-k3/k3-ddr.c b/arch/arm/mach-k3/k3-ddr.c
> index 6e3e60cdc86..026381490da 100644
> --- a/arch/arm/mach-k3/k3-ddr.c
> +++ b/arch/arm/mach-k3/k3-ddr.c
> @@ -5,7 +5,6 @@
>
> #include <fdt_support.h>
> #include <dm/uclass.h>
> -#include <k3-ddrss.h>
k3_ddrss_ddr_fdt_fixup() is still used here and the compiler gives us a
implicit declaration warning.
Regards,
Wadim
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region
2025-01-27 14:22 ` [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region Neha Malcom Francis
@ 2025-01-28 5:13 ` Wadim Egorov
2025-01-28 5:21 ` Neha Malcom Francis
2025-01-28 5:53 ` Kumar, Udit
1 sibling, 1 reply; 18+ messages in thread
From: Wadim Egorov @ 2025-01-28 5:13 UTC (permalink / raw)
To: Neha Malcom Francis, trini, bb, s-k6, marek.vasut+renesas,
sabiya.d
Cc: u-kumar1, u-boot
Am 27.01.25 um 21:22 schrieb Neha Malcom Francis:
> Instead of defaulting to choosing the entire DDR region when enabling
> inline ECC, allow picking of a range within the DDR space using DT to
> enable.
>
> It expects such a node within the memory node, in the absence of which
> we resort to enabling inline ECC for the entire DDR region:
>
> inline_ecc: protected@9e780000 {
> device_type = "ecc";
> reg = <0x9e780000 0x0080000>;
> bootph-all;
> };
>
> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
I'm not sure what went wrong, but I had difficulties applying this
patch. I had to use git am --reject and manually resolve a few blocks.
> ---
> drivers/ram/k3-ddrss/k3-ddrss.c | 52 +++++++++++++++++++++++++++++++--
> 1 file changed, 49 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
> index ab46098adbf..ea2578cda58 100644
> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
> @@ -149,6 +149,7 @@ struct k3_ddrss_desc {
> lpddr4_obj *driverdt;
> lpddr4_config config;
> lpddr4_privatedata pd;
> + struct k3_ddrss_ecc_region ecc_range;
> struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS];
> u64 ecc_reserved_space;
> u64 ddr_bank_base[CONFIG_NR_DRAM_BANKS];
> @@ -711,6 +712,30 @@ static void k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss)
> ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank];
> }
>
> +static void k3_ddrss_ddr_inline_ecc_base_size_calc(struct k3_ddrss_ecc_region *range)
> +{
> + fdt_addr_t base;
> + fdt_size_t size;
> + ofnode node1;
> +
> + node1 = ofnode_null();
> +
> + do {
> + node1 = ofnode_by_prop_value(node1, "device_type", "ecc", 4);
> + } while (!ofnode_is_enabled(node1));
> +
> + base = ofnode_get_addr_size(node1, "reg", &size);
> +
> + if (base == FDT_ADDR_T_NONE) {
> + debug("%s: Failed to get ECC node reg and size\n", __func__);
> + range->start = 0;
> + range->range = 0;
> + } else {
> + range->start = base;
> + range->range = size;
> + }
> +}
> +
> static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss)
> {
> fdtdec_setup_mem_size_base_lowest();
> @@ -759,8 +784,11 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
>
> static int k3_ddrss_probe(struct udevice *dev)
> {
> + u64 end;
> int ret;
> struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
> + __maybe_unused struct k3_ddrss_data *ddrss_data = (struct k3_ddrss_data *)dev_get_driver_data(dev);
> + __maybe_unused struct k3_ddrss_ecc_region *range = &ddrss->ecc_range;
>
> debug("%s(dev=%p)\n", __func__, dev);
>
> @@ -802,9 +830,27 @@ static int k3_ddrss_probe(struct udevice *dev)
>
> k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
>
> - /* Always configure one region that covers full DDR space */
> - ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] - ddrss->ddr_bank_base[0];
> - ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> + k3_ddrss_ddr_inline_ecc_base_size_calc(range);
> + if (!range->range) {
> + /* Configure entire DDR space by default */
> + debug("%s: Defaulting to protecting entire DDR space using inline ECC\n",
> + __func__);
> + ddrss->ecc_range.start = ddrss->ddr_bank_base[0];
> + ddrss->ecc_range.range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> + } else {
> + ddrss->ecc_range.start = range->start;
> + ddrss->ecc_range.range = range->range;
> + }
> +
> + end = ddrss->ecc_range.start + ddrss->ecc_range.range;
> +
> + if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
> + ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> + else
> + ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
> +
> + ddrss->ecc_regions[0].start = ddrss->ecc_range.start - ddrss->ddr_bank_base[0];
> +
> k3_ddrss_lpddr4_ecc_init(ddrss);
> }
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 1/8] k3-ddr.c: Remove unwanted header files
2025-01-28 5:02 ` Wadim Egorov
@ 2025-01-28 5:19 ` Neha Malcom Francis
0 siblings, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-28 5:19 UTC (permalink / raw)
To: Wadim Egorov, trini, bb, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, u-boot
Hi Wadim
On 28-Jan-25 10:32 AM, Wadim Egorov wrote:
> Hi Neha,
>
> Am 27.01.25 um 21:22 schrieb Neha Malcom Francis:
>> This header file is not in use in these arch/board specific files,
>> remove them.
>>
>> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
>> ---
>> arch/arm/mach-k3/k3-ddr.c | 1 -
>> board/ti/common/k3-ddr.c | 1 -
>> 2 files changed, 2 deletions(-)
>>
>> diff --git a/arch/arm/mach-k3/k3-ddr.c b/arch/arm/mach-k3/k3-ddr.c
>> index 6e3e60cdc86..026381490da 100644
>> --- a/arch/arm/mach-k3/k3-ddr.c
>> +++ b/arch/arm/mach-k3/k3-ddr.c
>> @@ -5,7 +5,6 @@
>> #include <fdt_support.h>
>> #include <dm/uclass.h>
>> -#include <k3-ddrss.h>
>
> k3_ddrss_ddr_fdt_fixup() is still used here and the compiler gives us a
> implicit declaration warning.
>
Let me take a look at that, must've missed it out; this cleanup was
intended for the test patch that I will send out later.
> Regards,
> Wadim
>
--
Thanking You
Neha Malcom Francis
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region
2025-01-28 5:13 ` Wadim Egorov
@ 2025-01-28 5:21 ` Neha Malcom Francis
0 siblings, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-28 5:21 UTC (permalink / raw)
To: Wadim Egorov, trini, bb, s-k6, marek.vasut+renesas, sabiya.d
Cc: u-kumar1, u-boot
Hi Wadim
On 28-Jan-25 10:43 AM, Wadim Egorov wrote:
> Am 27.01.25 um 21:22 schrieb Neha Malcom Francis:
>> Instead of defaulting to choosing the entire DDR region when enabling
>> inline ECC, allow picking of a range within the DDR space using DT to
>> enable.
>>
>> It expects such a node within the memory node, in the absence of which
>> we resort to enabling inline ECC for the entire DDR region:
>>
>> inline_ecc: protected@9e780000 {
>> device_type = "ecc";
>> reg = <0x9e780000 0x0080000>;
>> bootph-all;
>> };
>>
>> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
>
> I'm not sure what went wrong, but I had difficulties applying this
> patch. I had to use git am --reject and manually resolve a few blocks.
>
This shouldn't have been the case, sorry about that; probably I didn't
base it on the latest tip; will rebase and send again.
>
>> ---
>> drivers/ram/k3-ddrss/k3-ddrss.c | 52 +++++++++++++++++++++++++++++++--
>> 1 file changed, 49 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c
>> b/drivers/ram/k3-ddrss/k3-ddrss.c
>> index ab46098adbf..ea2578cda58 100644
>> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
>> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
>> @@ -149,6 +149,7 @@ struct k3_ddrss_desc {
>> lpddr4_obj *driverdt;
>> lpddr4_config config;
>> lpddr4_privatedata pd;
>> + struct k3_ddrss_ecc_region ecc_range;
>> struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS];
>> u64 ecc_reserved_space;
>> u64 ddr_bank_base[CONFIG_NR_DRAM_BANKS];
>> @@ -711,6 +712,30 @@ static void
>> k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss)
>> ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank];
>> }
>> +static void k3_ddrss_ddr_inline_ecc_base_size_calc(struct
>> k3_ddrss_ecc_region *range)
>> +{
>> + fdt_addr_t base;
>> + fdt_size_t size;
>> + ofnode node1;
>> +
>> + node1 = ofnode_null();
>> +
>> + do {
>> + node1 = ofnode_by_prop_value(node1, "device_type", "ecc", 4);
>> + } while (!ofnode_is_enabled(node1));
>> +
>> + base = ofnode_get_addr_size(node1, "reg", &size);
>> +
>> + if (base == FDT_ADDR_T_NONE) {
>> + debug("%s: Failed to get ECC node reg and size\n", __func__);
>> + range->start = 0;
>> + range->range = 0;
>> + } else {
>> + range->start = base;
>> + range->range = size;
>> + }
>> +}
>> +
>> static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct
>> k3_ddrss_desc *ddrss)
>> {
>> fdtdec_setup_mem_size_base_lowest();
>> @@ -759,8 +784,11 @@ static void k3_ddrss_lpddr4_ecc_init(struct
>> k3_ddrss_desc *ddrss)
>> static int k3_ddrss_probe(struct udevice *dev)
>> {
>> + u64 end;
>> int ret;
>> struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
>> + __maybe_unused struct k3_ddrss_data *ddrss_data = (struct
>> k3_ddrss_data *)dev_get_driver_data(dev);
>> + __maybe_unused struct k3_ddrss_ecc_region *range =
>> &ddrss->ecc_range;
>> debug("%s(dev=%p)\n", __func__, dev);
>> @@ -802,9 +830,27 @@ static int k3_ddrss_probe(struct udevice *dev)
>> k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
>> - /* Always configure one region that covers full DDR space */
>> - ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] -
>> ddrss->ddr_bank_base[0];
>> - ddrss->ecc_regions[0].range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + k3_ddrss_ddr_inline_ecc_base_size_calc(range);
>> + if (!range->range) {
>> + /* Configure entire DDR space by default */
>> + debug("%s: Defaulting to protecting entire DDR space
>> using inline ECC\n",
>> + __func__);
>> + ddrss->ecc_range.start = ddrss->ddr_bank_base[0];
>> + ddrss->ecc_range.range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + } else {
>> + ddrss->ecc_range.start = range->start;
>> + ddrss->ecc_range.range = range->range;
>> + }
>> +
>> + end = ddrss->ecc_range.start + ddrss->ecc_range.range;
>> +
>> + if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
>> + ddrss->ecc_regions[0].range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + else
>> + ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
>> +
>> + ddrss->ecc_regions[0].start = ddrss->ecc_range.start -
>> ddrss->ddr_bank_base[0];
>> +
>> k3_ddrss_lpddr4_ecc_init(ddrss);
>> }
>
--
Thanking You
Neha Malcom Francis
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 2/8] ram: k3-ddrss: Use DDR address instead of system address for ecc_regions
2025-01-27 14:22 ` [PATCH 2/8] ram: k3-ddrss: Use DDR address instead of system address for ecc_regions Neha Malcom Francis
@ 2025-01-28 5:46 ` Kumar, Udit
0 siblings, 0 replies; 18+ messages in thread
From: Kumar, Udit @ 2025-01-28 5:46 UTC (permalink / raw)
To: Neha Malcom Francis, trini, bb, w.egorov, s-k6,
marek.vasut+renesas, sabiya.d
Cc: u-boot
On 1/27/2025 7:52 PM, Neha Malcom Francis wrote:
> Let ecc_regions[x].start reflect the start of the ECC region in terms of
> DDR addressing rather than system addressing. This will make it easier
> to extend the usage of the same ecc_regions structure for multi-DDR
> systems as well.
>
> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
> ---
> drivers/ram/k3-ddrss/k3-ddrss.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
> index 05ea61bbfe9..24932cd837c 100644
> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
> @@ -730,7 +730,7 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
> u32 val;
>
> /* Only Program region 0 which covers full ddr space */
> - k3_ddrss_set_ecc_range_r0(base, ecc_region_start - ddrss->ddr_bank_base[0], ecc_range);
> + k3_ddrss_set_ecc_range_r0(base, ecc_region_start, ecc_range);
>
> /* Enable ECC, RMW, WR_ALLOC */
> writel(DDRSS_ECC_CTRL_REG_ECC_EN | DDRSS_ECC_CTRL_REG_RMW_EN |
> @@ -799,7 +799,7 @@ static int k3_ddrss_probe(struct udevice *dev)
> k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
>
> /* Always configure one region that covers full DDR space */
> - ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0];
> + ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] - ddrss->ddr_bank_base[0];
you will get start as zero, here , if this is what you need just set to
zero
> ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> k3_ddrss_lpddr4_ecc_init(ddrss);
> }
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 3/8] ram: k3-ddrss: Add comment about ecc_reserved_space
2025-01-27 14:22 ` [PATCH 3/8] ram: k3-ddrss: Add comment about ecc_reserved_space Neha Malcom Francis
@ 2025-01-28 5:47 ` Kumar, Udit
0 siblings, 0 replies; 18+ messages in thread
From: Kumar, Udit @ 2025-01-28 5:47 UTC (permalink / raw)
To: Neha Malcom Francis, trini, bb, w.egorov, s-k6,
marek.vasut+renesas; +Cc: u-boot
On 1/27/2025 7:52 PM, Neha Malcom Francis wrote:
> The reserved space needed for storing the parity remains the same no
> matter the size of the region that is being protected. Add this as a
> comment for better code understanding.
>
> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
> ---
> drivers/ram/k3-ddrss/k3-ddrss.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
> index 24932cd837c..ab46098adbf 100644
> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
> @@ -715,6 +715,10 @@ static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss)
> {
> fdtdec_setup_mem_size_base_lowest();
>
> + /*
> + * Reserved region remains 1/9th of the total DDR available no matter the
> + * size of the region under protection
> + */
Please add why , you need 1/9th of DDR
> ddrss->ecc_reserved_space = ddrss->ddr_ram_size;
> do_div(ddrss->ecc_reserved_space, 9);
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region
2025-01-27 14:22 ` [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region Neha Malcom Francis
2025-01-28 5:13 ` Wadim Egorov
@ 2025-01-28 5:53 ` Kumar, Udit
2025-01-28 6:35 ` Neha Malcom Francis
2025-01-30 7:10 ` Neha Malcom Francis
1 sibling, 2 replies; 18+ messages in thread
From: Kumar, Udit @ 2025-01-28 5:53 UTC (permalink / raw)
To: Neha Malcom Francis, trini, bb, w.egorov, s-k6,
marek.vasut+renesas; +Cc: u-boot
On 1/27/2025 7:52 PM, Neha Malcom Francis wrote:
> Instead of defaulting to choosing the entire DDR region when enabling
> inline ECC, allow picking of a range within the DDR space using DT to
> enable.
>
> It expects such a node within the memory node, in the absence of which
> we resort to enabling inline ECC for the entire DDR region:
>
> inline_ecc: protected@9e780000 {
> device_type = "ecc";
> reg = <0x9e780000 0x0080000>;
> bootph-all;
> };
is this possible to have ECC on different part of memory ?
i mean, protect 0x9e780000 + 0x0080000
and then 0xa000_0000 + 0x0080000
>
> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
> ---
> drivers/ram/k3-ddrss/k3-ddrss.c | 52 +++++++++++++++++++++++++++++++--
> 1 file changed, 49 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c
> index ab46098adbf..ea2578cda58 100644
> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
> @@ -149,6 +149,7 @@ struct k3_ddrss_desc {
> lpddr4_obj *driverdt;
> lpddr4_config config;
> lpddr4_privatedata pd;
> + struct k3_ddrss_ecc_region ecc_range;
> struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS];
> u64 ecc_reserved_space;
> u64 ddr_bank_base[CONFIG_NR_DRAM_BANKS];
> @@ -711,6 +712,30 @@ static void k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss)
> ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank];
> }
>
> +static void k3_ddrss_ddr_inline_ecc_base_size_calc(struct k3_ddrss_ecc_region *range)
> +{
> + fdt_addr_t base;
> + fdt_size_t size;
> + ofnode node1;
> +
> + node1 = ofnode_null();
> +
> + do {
> + node1 = ofnode_by_prop_value(node1, "device_type", "ecc", 4);
> + } while (!ofnode_is_enabled(node1));
> +
> + base = ofnode_get_addr_size(node1, "reg", &size);
> +
> + if (base == FDT_ADDR_T_NONE) {
> + debug("%s: Failed to get ECC node reg and size\n", __func__);
> + range->start = 0;
> + range->range = 0;
> + } else {
> + range->start = base;
> + range->range = size;
> + }
> +}
> +
> static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct k3_ddrss_desc *ddrss)
> {
> fdtdec_setup_mem_size_base_lowest();
> @@ -759,8 +784,11 @@ static void k3_ddrss_lpddr4_ecc_init(struct k3_ddrss_desc *ddrss)
>
> static int k3_ddrss_probe(struct udevice *dev)
> {
> + u64 end;
> int ret;
> struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
> + __maybe_unused struct k3_ddrss_data *ddrss_data = (struct k3_ddrss_data *)dev_get_driver_data(dev);
> + __maybe_unused struct k3_ddrss_ecc_region *range = &ddrss->ecc_range;
>
> debug("%s(dev=%p)\n", __func__, dev);
>
> @@ -802,9 +830,27 @@ static int k3_ddrss_probe(struct udevice *dev)
>
> k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
>
> - /* Always configure one region that covers full DDR space */
> - ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] - ddrss->ddr_bank_base[0];
> - ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> + k3_ddrss_ddr_inline_ecc_base_size_calc(range);
> + if (!range->range) {
> + /* Configure entire DDR space by default */
> + debug("%s: Defaulting to protecting entire DDR space using inline ECC\n",
> + __func__);
> + ddrss->ecc_range.start = ddrss->ddr_bank_base[0];
> + ddrss->ecc_range.range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> + } else {
> + ddrss->ecc_range.start = range->start;
> + ddrss->ecc_range.range = range->range;
> + }
Do you really need ecc_range variable ? if not please thing of using
ddrss->ecc_regions[0]
> +
> + end = ddrss->ecc_range.start + ddrss->ecc_range.range;
> +
> + if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
> + ddrss->ecc_regions[0].range = ddrss->ddr_ram_size - ddrss->ecc_reserved_space;
> + else
> + ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
> +
> + ddrss->ecc_regions[0].start = ddrss->ecc_range.start - ddrss->ddr_bank_base[0];
> +
> k3_ddrss_lpddr4_ecc_init(ddrss);
> }
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region
2025-01-28 5:53 ` Kumar, Udit
@ 2025-01-28 6:35 ` Neha Malcom Francis
2025-01-30 7:10 ` Neha Malcom Francis
1 sibling, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-28 6:35 UTC (permalink / raw)
To: Kumar, Udit, trini, bb, w.egorov, s-k6, marek.vasut+renesas; +Cc: u-boot
Hi Udit
On 28-Jan-25 11:23 AM, Kumar, Udit wrote:
>
> On 1/27/2025 7:52 PM, Neha Malcom Francis wrote:
>> Instead of defaulting to choosing the entire DDR region when enabling
>> inline ECC, allow picking of a range within the DDR space using DT to
>> enable.
>>
>> It expects such a node within the memory node, in the absence of which
>> we resort to enabling inline ECC for the entire DDR region:
>>
>> inline_ecc: protected@9e780000 {
>> device_type = "ecc";
>> reg = <0x9e780000 0x0080000>;
>> bootph-all;
>> };
>
> is this possible to have ECC on different part of memory ?
>
> i mean, protect 0x9e780000 + 0x0080000
>
> and then 0xa000_0000 + 0x0080000
This hasn't been tested, and it won't work with this series presently. I
can take it up later once the base functionality is taken in.
>
>>
>> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
>> ---
>> drivers/ram/k3-ddrss/k3-ddrss.c | 52 +++++++++++++++++++++++++++++++--
>> 1 file changed, 49 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c
>> b/drivers/ram/k3-ddrss/k3-ddrss.c
>> index ab46098adbf..ea2578cda58 100644
>> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
>> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
>> @@ -149,6 +149,7 @@ struct k3_ddrss_desc {
>> lpddr4_obj *driverdt;
>> lpddr4_config config;
>> lpddr4_privatedata pd;
>> + struct k3_ddrss_ecc_region ecc_range;
>> struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS];
>> u64 ecc_reserved_space;
>> u64 ddr_bank_base[CONFIG_NR_DRAM_BANKS];
>> @@ -711,6 +712,30 @@ static void
>> k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss)
>> ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank];
>> }
>> +static void k3_ddrss_ddr_inline_ecc_base_size_calc(struct
>> k3_ddrss_ecc_region *range)
>> +{
>> + fdt_addr_t base;
>> + fdt_size_t size;
>> + ofnode node1;
>> +
>> + node1 = ofnode_null();
>> +
>> + do {
>> + node1 = ofnode_by_prop_value(node1, "device_type", "ecc", 4);
>> + } while (!ofnode_is_enabled(node1));
>> +
>> + base = ofnode_get_addr_size(node1, "reg", &size);
>> +
>> + if (base == FDT_ADDR_T_NONE) {
>> + debug("%s: Failed to get ECC node reg and size\n", __func__);
>> + range->start = 0;
>> + range->range = 0;
>> + } else {
>> + range->start = base;
>> + range->range = size;
>> + }
>> +}
>> +
>> static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct
>> k3_ddrss_desc *ddrss)
>> {
>> fdtdec_setup_mem_size_base_lowest();
>> @@ -759,8 +784,11 @@ static void k3_ddrss_lpddr4_ecc_init(struct
>> k3_ddrss_desc *ddrss)
>> static int k3_ddrss_probe(struct udevice *dev)
>> {
>> + u64 end;
>> int ret;
>> struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
>> + __maybe_unused struct k3_ddrss_data *ddrss_data = (struct
>> k3_ddrss_data *)dev_get_driver_data(dev);
>> + __maybe_unused struct k3_ddrss_ecc_region *range =
>> &ddrss->ecc_range;
>> debug("%s(dev=%p)\n", __func__, dev);
>> @@ -802,9 +830,27 @@ static int k3_ddrss_probe(struct udevice *dev)
>> k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
>> - /* Always configure one region that covers full DDR space */
>> - ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] -
>> ddrss->ddr_bank_base[0];
>> - ddrss->ecc_regions[0].range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + k3_ddrss_ddr_inline_ecc_base_size_calc(range);
>> + if (!range->range) {
>> + /* Configure entire DDR space by default */
>> + debug("%s: Defaulting to protecting entire DDR space
>> using inline ECC\n",
>> + __func__);
>> + ddrss->ecc_range.start = ddrss->ddr_bank_base[0];
>> + ddrss->ecc_range.range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + } else {
>> + ddrss->ecc_range.start = range->start;
>> + ddrss->ecc_range.range = range->range;
>> + }
> Do you really need ecc_range variable ? if not please thing of using
> ddrss->ecc_regions[0]
>> +
>> + end = ddrss->ecc_range.start + ddrss->ecc_range.range;
>> +
>> + if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
>> + ddrss->ecc_regions[0].range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + else
>> + ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
>> +
>> + ddrss->ecc_regions[0].start = ddrss->ecc_range.start -
>> ddrss->ddr_bank_base[0];
>> +
>> k3_ddrss_lpddr4_ecc_init(ddrss);
>> }
--
Thanking You
Neha Malcom Francis
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region
2025-01-28 5:53 ` Kumar, Udit
2025-01-28 6:35 ` Neha Malcom Francis
@ 2025-01-30 7:10 ` Neha Malcom Francis
1 sibling, 0 replies; 18+ messages in thread
From: Neha Malcom Francis @ 2025-01-30 7:10 UTC (permalink / raw)
To: Kumar, Udit, trini, bb, w.egorov, s-k6, marek.vasut+renesas; +Cc: u-boot
On 28-Jan-25 11:23 AM, Kumar, Udit wrote:
>
> On 1/27/2025 7:52 PM, Neha Malcom Francis wrote:
>> Instead of defaulting to choosing the entire DDR region when enabling
>> inline ECC, allow picking of a range within the DDR space using DT to
>> enable.
>>
>> It expects such a node within the memory node, in the absence of which
>> we resort to enabling inline ECC for the entire DDR region:
>>
>> inline_ecc: protected@9e780000 {
>> device_type = "ecc";
>> reg = <0x9e780000 0x0080000>;
>> bootph-all;
>> };
>
> is this possible to have ECC on different part of memory ?
>
> i mean, protect 0x9e780000 + 0x0080000
>
> and then 0xa000_0000 + 0x0080000
>
>>
>> Signed-off-by: Neha Malcom Francis <n-francis@ti.com>
>> ---
>> drivers/ram/k3-ddrss/k3-ddrss.c | 52 +++++++++++++++++++++++++++++++--
>> 1 file changed, 49 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/ram/k3-ddrss/k3-ddrss.c
>> b/drivers/ram/k3-ddrss/k3-ddrss.c
>> index ab46098adbf..ea2578cda58 100644
>> --- a/drivers/ram/k3-ddrss/k3-ddrss.c
>> +++ b/drivers/ram/k3-ddrss/k3-ddrss.c
>> @@ -149,6 +149,7 @@ struct k3_ddrss_desc {
>> lpddr4_obj *driverdt;
>> lpddr4_config config;
>> lpddr4_privatedata pd;
>> + struct k3_ddrss_ecc_region ecc_range;
>> struct k3_ddrss_ecc_region ecc_regions[K3_DDRSS_MAX_ECC_REGIONS];
>> u64 ecc_reserved_space;
>> u64 ddr_bank_base[CONFIG_NR_DRAM_BANKS];
>> @@ -711,6 +712,30 @@ static void
>> k3_ddrss_ddr_bank_base_size_calc(struct k3_ddrss_desc *ddrss)
>> ddrss->ddr_ram_size += ddrss->ddr_bank_size[bank];
>> }
>> +static void k3_ddrss_ddr_inline_ecc_base_size_calc(struct
>> k3_ddrss_ecc_region *range)
>> +{
>> + fdt_addr_t base;
>> + fdt_size_t size;
>> + ofnode node1;
>> +
>> + node1 = ofnode_null();
>> +
>> + do {
>> + node1 = ofnode_by_prop_value(node1, "device_type", "ecc", 4);
>> + } while (!ofnode_is_enabled(node1));
>> +
>> + base = ofnode_get_addr_size(node1, "reg", &size);
>> +
>> + if (base == FDT_ADDR_T_NONE) {
>> + debug("%s: Failed to get ECC node reg and size\n", __func__);
>> + range->start = 0;
>> + range->range = 0;
>> + } else {
>> + range->start = base;
>> + range->range = size;
>> + }
>> +}
>> +
>> static void k3_ddrss_lpddr4_ecc_calc_reserved_mem(struct
>> k3_ddrss_desc *ddrss)
>> {
>> fdtdec_setup_mem_size_base_lowest();
>> @@ -759,8 +784,11 @@ static void k3_ddrss_lpddr4_ecc_init(struct
>> k3_ddrss_desc *ddrss)
>> static int k3_ddrss_probe(struct udevice *dev)
>> {
>> + u64 end;
>> int ret;
>> struct k3_ddrss_desc *ddrss = dev_get_priv(dev);
>> + __maybe_unused struct k3_ddrss_data *ddrss_data = (struct
>> k3_ddrss_data *)dev_get_driver_data(dev);
>> + __maybe_unused struct k3_ddrss_ecc_region *range =
>> &ddrss->ecc_range;
>> debug("%s(dev=%p)\n", __func__, dev);
>> @@ -802,9 +830,27 @@ static int k3_ddrss_probe(struct udevice *dev)
>> k3_ddrss_lpddr4_ecc_calc_reserved_mem(ddrss);
>> - /* Always configure one region that covers full DDR space */
>> - ddrss->ecc_regions[0].start = ddrss->ddr_bank_base[0] -
>> ddrss->ddr_bank_base[0];
>> - ddrss->ecc_regions[0].range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + k3_ddrss_ddr_inline_ecc_base_size_calc(range);
>> + if (!range->range) {
>> + /* Configure entire DDR space by default */
>> + debug("%s: Defaulting to protecting entire DDR space
>> using inline ECC\n",
>> + __func__);
>> + ddrss->ecc_range.start = ddrss->ddr_bank_base[0];
>> + ddrss->ecc_range.range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + } else {
>> + ddrss->ecc_range.start = range->start;
>> + ddrss->ecc_range.range = range->range;
>> + }
> Do you really need ecc_range variable ? if not please thing of using
> ddrss->ecc_regions[0]
Using it as ddrss->ecc_regions[0] led to excess character count in the line.
>> +
>> + end = ddrss->ecc_range.start + ddrss->ecc_range.range;
>> +
>> + if (end > (ddrss->ddr_ram_size - ddrss->ecc_reserved_space))
>> + ddrss->ecc_regions[0].range = ddrss->ddr_ram_size -
>> ddrss->ecc_reserved_space;
>> + else
>> + ddrss->ecc_regions[0].range = ddrss->ecc_range.range;
>> +
>> + ddrss->ecc_regions[0].start = ddrss->ecc_range.start -
>> ddrss->ddr_bank_base[0];
>> +
>> k3_ddrss_lpddr4_ecc_init(ddrss);
>> }
--
Thanking You
Neha Malcom Francis
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2025-01-30 7:10 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-01-27 14:22 [PATCH 0/8] ram: k3-ddrss: Support partial inline ECC Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 1/8] k3-ddr.c: Remove unwanted header files Neha Malcom Francis
2025-01-28 5:02 ` Wadim Egorov
2025-01-28 5:19 ` Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 2/8] ram: k3-ddrss: Use DDR address instead of system address for ecc_regions Neha Malcom Francis
2025-01-28 5:46 ` Kumar, Udit
2025-01-27 14:22 ` [PATCH 3/8] ram: k3-ddrss: Add comment about ecc_reserved_space Neha Malcom Francis
2025-01-28 5:47 ` Kumar, Udit
2025-01-27 14:22 ` [PATCH 4/8] ram: k3-ddrss: Add support for a partial inline ECC region Neha Malcom Francis
2025-01-28 5:13 ` Wadim Egorov
2025-01-28 5:21 ` Neha Malcom Francis
2025-01-28 5:53 ` Kumar, Udit
2025-01-28 6:35 ` Neha Malcom Francis
2025-01-30 7:10 ` Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 5/8] ram: k3-ddrss: Add CONFIG_K3_MULTI_DDR Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 6/8] ram: k3-ddrss: Add support for number of controllers under MSMC Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 7/8] ram: k3-ddrss: Add support for MSMC calculation of DDR inline ECC regions Neha Malcom Francis
2025-01-27 14:22 ` [PATCH 8/8] ram: k3-ddrss: Add support for partial inline ECC in multi-DDR systems Neha Malcom Francis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox