From b158ef7c445a1ab66134c410c901766d0a73e486 Mon Sep 17 00:00:00 2001 From: Bryan Brattlof Date: Wed, 24 Jun 2026 10:35:07 -0500 Subject: arm: mach-omap2: am33xx: ddr: ensure proper reset->cke delay With the Beaglebone Black the delay on DDR_RESET to DDR_CKE is currently ~135us and not the >500us required by JEDEC spec. The issue here is the REF_CTRL register performs two purposes. It is the counter for CKE to RESET delay before the DDR controller is initialized and used to configure the refresh rate after initialization of the controller. So to avoid inadvertently configuring the CKE to DDR delay, ensure we initialize the controller before we configure the refresh rate. Fixes: 69b918b65d11 ("am33xx,ddr3: fix ddr3 sdram configuration") Signed-off-by: Bryan Brattlof --- arch/arm/mach-omap2/am33xx/ddr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-omap2/am33xx/ddr.c b/arch/arm/mach-omap2/am33xx/ddr.c index 41eec005cb1..a40813a99d8 100644 --- a/arch/arm/mach-omap2/am33xx/ddr.c +++ b/arch/arm/mach-omap2/am33xx/ddr.c @@ -185,10 +185,10 @@ void config_sdram(const struct emif_regs *regs, int nr) if (regs->zq_config) { writel(regs->zq_config, &emif_reg[nr]->emif_zq_config); writel(regs->sdram_config, &cstat->secure_emif_sdram_config); - writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); /* Trigger initialization */ writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl); + writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config); /* Wait 1ms because of L3 timeout error */ udelay(1000); -- cgit v1.3.1 From 3ddd0f9bc879ab62522164b50c41181e909b9a0b Mon Sep 17 00:00:00 2001 From: Bryan Brattlof Date: Wed, 24 Jun 2026 10:35:08 -0500 Subject: arm: mach-omap2: am33xx: check VTP before reinitalizing During a warm reset, the DDR controller will be put into a self refresh state and will exit self refresh on reset release which will put the controller in a ready state during bootup. However we will reinitialize the controller regardless which will temporarily (~6us) glitch the DDR_RESET line low Fix this by checking if the VTP controller is already in a ready state before we initialize the controller unnecessarily. Fixes: 3ba65f97cbed ("am33xx: refactor emif4/ddr to support multiple EMIF instances") Signed-off-by: Bryan Brattlof --- arch/arm/mach-omap2/am33xx/emif4.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-omap2/am33xx/emif4.c b/arch/arm/mach-omap2/am33xx/emif4.c index f19c66822d2..96e239b31a0 100644 --- a/arch/arm/mach-omap2/am33xx/emif4.c +++ b/arch/arm/mach-omap2/am33xx/emif4.c @@ -29,12 +29,21 @@ static struct cm_device_inst *cm_device = static void config_vtp(int nr) { - writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE, - &vtpreg[nr]->vtp0ctrlreg); - writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN), - &vtpreg[nr]->vtp0ctrlreg); - writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN, - &vtpreg[nr]->vtp0ctrlreg); + /* + * A warm reset will result in DDR going into self refresh. Once the + * reset is released we will exit self refresh and resume normally + * so a reinitialization of the controller is not needed. + * + * Check to see if VTP is ready before we reinitialize the controller + */ + if ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) != VTP_CTRL_READY) { + writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_ENABLE, + &vtpreg[nr]->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) & (~VTP_CTRL_START_EN), + &vtpreg[nr]->vtp0ctrlreg); + writel(readl(&vtpreg[nr]->vtp0ctrlreg) | VTP_CTRL_START_EN, + &vtpreg[nr]->vtp0ctrlreg); + } /* Poll for READY */ while ((readl(&vtpreg[nr]->vtp0ctrlreg) & VTP_CTRL_READY) != -- cgit v1.3.1