summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorrobert-hh <robert@hammelrath.com>2025-02-04 18:17:47 +0100
committerDamien George <damien@micropython.org>2025-02-10 11:32:26 +1100
commit0a433a02e1eab1c95e57129a1e828780c871be42 (patch)
treea35a831f29f1c19132a656cbf6da4844e40ee9bb
parentd40849d07d2523fa16070bfcae34b51b7b14942b (diff)
downloadmicropython-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.c3
-rw-r--r--ports/mimxrt/hal/flexspi_hyper_flash.c2
-rw-r--r--ports/mimxrt/hal/flexspi_hyper_flash.h2
-rw-r--r--ports/mimxrt/hal/flexspi_nor_flash.c93
-rw-r--r--ports/mimxrt/hal/flexspi_nor_flash.h3
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);