diff options
author | robert-hh <robert@hammelrath.com> | 2025-02-04 18:17:47 +0100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2025-02-10 11:32:26 +1100 |
commit | 0a433a02e1eab1c95e57129a1e828780c871be42 (patch) | |
tree | a35a831f29f1c19132a656cbf6da4844e40ee9bb | |
parent | d40849d07d2523fa16070bfcae34b51b7b14942b (diff) | |
download | micropython-0a433a02e1eab1c95e57129a1e828780c871be42.tar.gz micropython-0a433a02e1eab1c95e57129a1e828780c871be42.zip |
mimxrt/hal: Set the flexspi flash CLK frequency on boot.
The flash clock frequency may have been set to a different value by a
bootloader. Set the frequency according to the configured value. Use a
table of pre-calculated dividers to get the closest value for the flash
frequency, achieving for MIMXRT10xx:
30 -> 30.85 MHz
50 -> 49.65 MHz
60 -> 60 MHz
75 -> 75.13 MHz
80 -> 80 MHz
100 -> 99.31 Mhz
133 -> 132.92 MHz
166 -> 166.15 MHz
for MIMXRT1176:
30 -> 31 MHz
50 -> 52.8 MJz
60 -> 58.7 MHz
75 -> 75.4 MHz
80 -> 75.4 MHz
100 -> 105.6 MHz
133 -> 132 MHz
166 -> 176 MHz
Signed-off-by: robert-hh <robert@hammelrath.com>
-rw-r--r-- | ports/mimxrt/flash.c | 3 | ||||
-rw-r--r-- | ports/mimxrt/hal/flexspi_hyper_flash.c | 2 | ||||
-rw-r--r-- | ports/mimxrt/hal/flexspi_hyper_flash.h | 2 | ||||
-rw-r--r-- | ports/mimxrt/hal/flexspi_nor_flash.c | 93 | ||||
-rw-r--r-- | ports/mimxrt/hal/flexspi_nor_flash.h | 3 |
5 files changed, 95 insertions, 8 deletions
diff --git a/ports/mimxrt/flash.c b/ports/mimxrt/flash.c index cdcdc7483d..57091b36dd 100644 --- a/ports/mimxrt/flash.c +++ b/ports/mimxrt/flash.c @@ -29,7 +29,8 @@ void flash_init(void) { // Upload the custom flash configuration // And fix the entry for PAGEPROGRAM_QUAD - flexspi_nor_update_lut(); + // Update the flash CLK + flexspi_nor_update_lut_clk(MICROPY_HW_FLASH_CLK); // Configure FLEXSPI IP FIFO access. BOARD_FLEX_SPI->MCR0 &= ~(FLEXSPI_MCR0_ARDFEN_MASK); diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.c b/ports/mimxrt/hal/flexspi_hyper_flash.c index c0cd63ca0b..9171640a9e 100644 --- a/ports/mimxrt/hal/flexspi_hyper_flash.c +++ b/ports/mimxrt/hal/flexspi_hyper_flash.c @@ -9,7 +9,7 @@ #include "fsl_clock.h" #include "flexspi_hyper_flash.h" -void flexspi_nor_update_lut(void) { +void flexspi_nor_update_lut_clk(uint32_t freq_index) { } // Copy of a few (pseudo-)functions from fsl_clock.h, which were nor reliably diff --git a/ports/mimxrt/hal/flexspi_hyper_flash.h b/ports/mimxrt/hal/flexspi_hyper_flash.h index a6454a1c9a..40416d6e21 100644 --- a/ports/mimxrt/hal/flexspi_hyper_flash.h +++ b/ports/mimxrt/hal/flexspi_hyper_flash.h @@ -47,7 +47,7 @@ extern flexspi_nor_config_t qspiflash_config; status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base); void flexspi_hyper_flash_init(void); -void flexspi_nor_update_lut(void); +void flexspi_nor_update_lut_clk(uint32_t freq_index); status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); status_t flexspi_nor_flash_erase_block(FLEXSPI_Type *base, uint32_t address); status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size); diff --git a/ports/mimxrt/hal/flexspi_nor_flash.c b/ports/mimxrt/hal/flexspi_nor_flash.c index 6d5b830383..7fdb6b7c13 100644 --- a/ports/mimxrt/hal/flexspi_nor_flash.c +++ b/ports/mimxrt/hal/flexspi_nor_flash.c @@ -38,6 +38,9 @@ #include "flexspi_nor_flash.h" #include "flexspi_flash_config.h" +bool flash_busy_status_pol = 0; +bool flash_busy_status_offset = 0; + uint32_t LUT_pageprogram_quad[4] = { // 10 Page Program - quad mode FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 24), @@ -54,16 +57,100 @@ uint32_t LUT_write_status[4] = { FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler }; -void flexspi_nor_update_lut(void) { +#if defined(MIMXRT117x_SERIES) +static uint8_t div_table_mhz[] = { + 17, // Entry 0 is out of range + 17, // 30 -> 31 MHz + 10, // 50 -> 52.8 MHz + 9, // 60 -> 58.7 MHz + 7, // 75 -> 75.4 MHz + 7, // 80 -> 75.4 MHz + 5, // 100 -> 105.6 Mhz + 4, // 133 -> 132 MHz + 3 // 166 -> 176 MHz +}; + +#else +typedef struct _ps_div_t { + uint8_t pfd480_div; + uint8_t podf_div; +} ps_div_t; + +static ps_div_t div_table_mhz[] = { + { 35, 8 }, // Entry 0 is out of range + { 35, 8 }, // 30 -> 30.85 MHz + { 29, 6 }, // 50 -> 49.65 MHz + { 18, 8 }, // 60 -> 60 MHz + { 23, 5 }, // 75 -> 75.13 MHz + { 18, 6 }, // 80 -> 80 MHz + { 17, 5 }, // 100 -> 191 Mhz + { 13, 5 }, // 133 -> 132.92 MHz + { 13, 4 } // 166 -> 166.15 MHz +}; +#endif + +__attribute__((section(".ram_functions"))) void flexspi_nor_update_lut_clk(uint32_t freq_index) { + // Create a local copy of the LookupTable. Modify the entry for WRITESTATUSREG + // Add an entry for PAGEPROGRAM_QUAD. uint32_t lookuptable_copy[64]; memcpy(lookuptable_copy, (const uint32_t *)&qspiflash_config.memConfig.lookupTable, 64 * sizeof(uint32_t)); - // write WRITESTATUSREG code to entry 10 + // write local WRITESTATUSREG code to index 4 memcpy(&lookuptable_copy[NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG * 4], LUT_write_status, 4 * sizeof(uint32_t)); - // write PAGEPROGRAM_QUAD code to entry 10 + // write local PAGEPROGRAM_QUAD code to index 10 memcpy(&lookuptable_copy[NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD * 4], LUT_pageprogram_quad, 4 * sizeof(uint32_t)); + // Update the LookupTable. FLEXSPI_UpdateLUT(BOARD_FLEX_SPI, 0, lookuptable_copy, 64); + + __DSB(); + __ISB(); + __disable_irq(); + SCB_DisableDCache(); + + #if defined(MIMXRT117x_SERIES) + volatile uint8_t pll2_div = div_table_mhz[freq_index] - 1; + + while (!FLEXSPI_GetBusIdleStatus(BOARD_FLEX_SPI)) { + } + FLEXSPI_Enable(BOARD_FLEX_SPI, false); + + // Disable FlexSPI clock + // Flexspi is clocked by PLL2. Only the divider can be changed. + CCM->LPCG[kCLOCK_Flexspi1].DIRECT = ((uint32_t)kCLOCK_Off & CCM_LPCG_DIRECT_ON_MASK); + // Change the PLL divider + CCM->CLOCK_ROOT[kCLOCK_Root_Flexspi1].CONTROL = (CCM->CLOCK_ROOT[kCLOCK_Root_Flexspi1].CONTROL & ~CCM_CLOCK_ROOT_CONTROL_DIV_MASK) | + CCM_CLOCK_ROOT_CONTROL_DIV(pll2_div); + // Re-enable FlexSPI clock + CCM->LPCG[kCLOCK_Flexspi1].DIRECT = ((uint32_t)kCLOCK_On & CCM_LPCG_DIRECT_ON_MASK); + + #else + + volatile uint8_t pfd480_div = div_table_mhz[freq_index].pfd480_div; + volatile uint8_t podf_div = div_table_mhz[freq_index].podf_div - 1; + + while (!FLEXSPI_GetBusIdleStatus(BOARD_FLEX_SPI)) { + } + FLEXSPI_Enable(BOARD_FLEX_SPI, false); + + // Disable FlexSPI clock + CCM->CCGR6 &= ~CCM_CCGR6_CG5_MASK; + // Changing the clock is OK now. + // Change the PFD + CCM_ANALOG->PFD_480 = (CCM_ANALOG->PFD_480 & ~CCM_ANALOG_PFD_480_TOG_PFD0_FRAC_MASK) | CCM_ANALOG_PFD_480_TOG_PFD0_FRAC(pfd480_div); + // Change the flexspi divider + CCM->CSCMR1 = (CCM->CSCMR1 & ~CCM_CSCMR1_FLEXSPI_PODF_MASK) | CCM_CSCMR1_FLEXSPI_PODF(podf_div); + // Re-enable FlexSPI + CCM->CCGR6 |= CCM_CCGR6_CG5_MASK; + #endif + + FLEXSPI_Enable(BOARD_FLEX_SPI, true); + FLEXSPI_SoftwareReset(BOARD_FLEX_SPI); + while (!FLEXSPI_GetBusIdleStatus(BOARD_FLEX_SPI)) { + } + + SCB_EnableDCache(); + __enable_irq(); } void flexspi_nor_reset(FLEXSPI_Type *base) __attribute__((section(".ram_functions"))); diff --git a/ports/mimxrt/hal/flexspi_nor_flash.h b/ports/mimxrt/hal/flexspi_nor_flash.h index 2e61effc2b..dc5798d97f 100644 --- a/ports/mimxrt/hal/flexspi_nor_flash.h +++ b/ports/mimxrt/hal/flexspi_nor_flash.h @@ -45,8 +45,7 @@ extern flexspi_nor_config_t qspiflash_config; status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId); -status_t flexspi_nor_init(void); -void flexspi_nor_update_lut(void); +void flexspi_nor_update_lut_clk(uint32_t freq_index); status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base); status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address); status_t flexspi_nor_flash_erase_block(FLEXSPI_Type *base, uint32_t address); |