[PATCH u-boot v2019.04-aspeed-openbmc] ram/aspeed: Re-init ECC if requested but not enabled

Joel Stanley joel at jms.id.au
Wed Sep 21 15:53:18 AEST 2022


If a machine has a new u-boot installed that enables ECC, but it has not
had a power cycle since being updated, the DDR will not re-initalise and
ECC will stay disabled.

Similarly for the reverse case, where ECC was enabled but a new u-boot
disables it.

Detect if ECC has been requested by the firmware and check against the
hardware state. If it does not match, and the DDR has already been
initialised, proceed as if the DDR has not been set up.

Signed-off-by: Joel Stanley <joel at jms.id.au>
---
This is untested on hardware, but attempts to solve a problem when
upgrading firmware to enable ECC.

Aspeed, is it okay to re-init DRAM like this?

 drivers/ram/aspeed/sdram_ast2600.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)

diff --git a/drivers/ram/aspeed/sdram_ast2600.c b/drivers/ram/aspeed/sdram_ast2600.c
index 5f7b160faddf..d5a9875e4fde 100644
--- a/drivers/ram/aspeed/sdram_ast2600.c
+++ b/drivers/ram/aspeed/sdram_ast2600.c
@@ -891,6 +891,27 @@ static void ast2600_sdrammc_ecc_enable(struct dram_info *info, u32 conf_size_mb)
 	writel(0, &regs->intr_ctrl);
 }
 
+static bool ast2600_sdrammc_init_required(struct udevice *dev)
+{
+	struct dram_info *priv = dev_get_priv(dev);
+	struct ast2600_sdrammc_regs *regs = priv->regs;
+	bool ecc_requested;
+	bool ecc_enabled;
+	bool dram_ready;
+
+	ecc_requested = dev_read_bool(dev, "aspeed,ecc-enabled");
+	ecc_enabled = readl(&regs->config) & SDRAM_CONF_ECC_SETUP;
+	dram_ready  = readl(priv->scu + AST_SCU_HANDSHAKE) & SCU_SDRAM_INIT_READY_MASK;
+
+	if (!dram_ready)
+		return true;
+
+	if (ecc_requested != ecc_enabled)
+		return true;
+
+	return false;
+}
+
 static int ast2600_sdrammc_probe(struct udevice *dev)
 {
 	struct dram_info *priv = (struct dram_info *)dev_get_priv(dev);
@@ -913,8 +934,7 @@ static int ast2600_sdrammc_probe(struct udevice *dev)
 		return PTR_ERR(priv->scu);
 	}
 
-	reg = readl(priv->scu + AST_SCU_HANDSHAKE);
-	if (reg & SCU_SDRAM_INIT_READY_MASK) {
+	if (ast2600_sdrammc_init_required(dev)) {
 		printf("already initialized, ");
 		setbits_le32(priv->scu + AST_SCU_HANDSHAKE, SCU_HANDSHAKE_MASK);
 		ast2600_sdrammc_update_size(priv);
-- 
2.35.1



More information about the openbmc mailing list