This is an automated email from the ASF dual-hosted git repository.

casaroli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 5fde03e44390b4b54a237985d6c1d9dceaa074ca
Author: alexcekay <[email protected]>
AuthorDate: Tue Oct 27 16:29:29 2026 +0100

    arch/imxrt,imx9: Fix FlexSPI DLL setup using stale RX sample clock
    
    set_device_config() configured the DLL before writing the requested RX
    sample clock source to MCR0. configure_dll() derives the DLL setting
    from RXCLKSRC in MCR0, so it used the previous source: after init that
    is the DQS pad loopback, which yields the fixed default delay with the
    DLL disabled. A device sampling with the flash-provided DQS strobe
    (external input from DQS pad, no SCK2) at 100 MHz or more therefore ran
    without the DLL until set_device_config() was called a second time.
    
    The DLL lock wait also never ran: config_value was reused for MCR0
    before testing it against FLEXSPI_DLLCR_DLLEN_MASK.
    
    Fixed by writing RXCLKSRC before configuring the DLL and keeping the
    DLLCR value in its own variable for the lock check. This matches the
    NXP SDK, where FLEXSPI_Init() already sets RXCLKSRC before
    FLEXSPI_SetFlashConfig() calculates the DLL, and the lock check tests
    the DLLCR value.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: alexcekay <[email protected]>
---
 arch/arm/src/imxrt/imxrt_flexspi.c | 24 ++++++++++++------------
 arch/arm64/src/imx9/imx9_flexspi.c | 24 ++++++++++++------------
 2 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/arch/arm/src/imxrt/imxrt_flexspi.c 
b/arch/arm/src/imxrt/imxrt_flexspi.c
index 60181f6efef..beadf97975e 100644
--- a/arch/arm/src/imxrt/imxrt_flexspi.c
+++ b/arch/arm/src/imxrt/imxrt_flexspi.c
@@ -706,6 +706,7 @@ void imxrt_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
 {
   uint32_t config_value = 0;
   uint32_t status_value = 0;
+  uint32_t dll_value    = 0;
   uint8_t index        = (uint8_t)port >> 1u; /* PortA with index 0, PortB 
with index 1 */
 
   /* Wait for bus idle before change flash configuration */
@@ -761,10 +762,17 @@ void imxrt_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
 
   base->FLSHCR2[port] = config_value;
 
+  /* Set RX sample clock, the DLL configuration depends on it */
+
+  config_value = base->MCR0;
+  config_value &= ~FLEXSPI_MCR0_RXCLKSRC_MASK;
+  config_value |= FLEXSPI_MCR0_RXCLKSRC(config->rx_sample_clock);
+  base->MCR0 = config_value;
+
   /* Configure DLL */
 
-  config_value        = imxrt_flexspi_configure_dll(base, config);
-  base->DLLCR[index] = config_value;
+  dll_value          = imxrt_flexspi_configure_dll(base, config);
+  base->DLLCR[index] = dll_value;
 
   /* Configure write mask */
 
@@ -788,17 +796,9 @@ void imxrt_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
       base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMENB(config->enable_write_mask);
     }
 
-  /* Set RX Sample Clock */
-
-  config_value = base->MCR0;
-  config_value &= ~FLEXSPI_MCR0_RXCLKSRC_MASK;
-  config_value |= FLEXSPI_MCR0_RXCLKSRC(config->rx_sample_clock);
-
   /* Exit stop mode */
 
-  config_value &= ~FLEXSPI_MCR0_MDIS_MASK;
-
-  base->MCR0 = config_value;
+  base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
 
   /* According to ERR011377, need to delay at least 100 NOPs to ensure the
    * DLL is locked.
@@ -811,7 +811,7 @@ void imxrt_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
           ((uint32_t)FLEXSPI_FLASH_B_SAMPLE_CLOCK_SLAVE_DELAY_LOCKED |
            (uint32_t)FLEXSPI_FLASH_B_SAMPLE_CLOCK_REF_DELAY_LOCKED);
 
-  if (0u != (config_value & FLEXSPI_DLLCR_DLLEN_MASK))
+  if (0u != (dll_value & FLEXSPI_DLLCR_DLLEN_MASK))
     {
       /* Wait slave delay line locked and slave reference delay line locked */
 
diff --git a/arch/arm64/src/imx9/imx9_flexspi.c 
b/arch/arm64/src/imx9/imx9_flexspi.c
index 8fb5647ce30..ccd121632fc 100644
--- a/arch/arm64/src/imx9/imx9_flexspi.c
+++ b/arch/arm64/src/imx9/imx9_flexspi.c
@@ -646,6 +646,7 @@ void imx9_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
 {
   uint32_t config_value = 0;
   uint32_t status_value = 0;
+  uint32_t dll_value    = 0;
   uint8_t index        = (uint8_t)port >> 1u; /* PortA with index 0, PortB 
with index 1 */
 
   /* Wait for bus idle before change flash configuration */
@@ -701,10 +702,17 @@ void imx9_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
 
   base->FLSHCR2[port] = config_value;
 
+  /* Set RX sample clock, the DLL configuration depends on it */
+
+  config_value = base->MCR0;
+  config_value &= ~FLEXSPI_MCR0_RXCLKSRC_MASK;
+  config_value |= FLEXSPI_MCR0_RXCLKSRC(config->rx_sample_clock);
+  base->MCR0 = config_value;
+
   /* Configure DLL */
 
-  config_value        = imx9_flexspi_configure_dll(base, config);
-  base->DLLCR[index] = config_value;
+  dll_value          = imx9_flexspi_configure_dll(base, config);
+  base->DLLCR[index] = dll_value;
 
   /* Configure write mask */
 
@@ -728,17 +736,9 @@ void imx9_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
       base->FLSHCR4 |= FLEXSPI_FLSHCR4_WMENB(config->enable_write_mask);
     }
 
-  /* Set RX Sample Clock */
-
-  config_value = base->MCR0;
-  config_value &= ~FLEXSPI_MCR0_RXCLKSRC_MASK;
-  config_value |= FLEXSPI_MCR0_RXCLKSRC(config->rx_sample_clock);
-
   /* Exit stop mode */
 
-  config_value &= ~FLEXSPI_MCR0_MDIS_MASK;
-
-  base->MCR0 = config_value;
+  base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
 
   /* According to ERR011377, need to delay at least 100 NOPs to ensure the
    * DLL is locked.
@@ -751,7 +751,7 @@ void imx9_flexspi_set_device_config_private(struct 
flexspi_type_s *base,
           ((uint32_t)FLEXSPI_FLASH_B_SAMPLE_CLOCK_SLAVE_DELAY_LOCKED |
            (uint32_t)FLEXSPI_FLASH_B_SAMPLE_CLOCK_REF_DELAY_LOCKED);
 
-  if (0u != (config_value & FLEXSPI_DLLCR_DLLEN_MASK))
+  if (0u != (dll_value & FLEXSPI_DLLCR_DLLEN_MASK))
     {
       /* Wait slave delay line locked and slave reference delay line locked */
 

Reply via email to