10000 mimxrt/flexspi_nor_c: Set the flash CLK frequency on boot. · micropython/micropython@e7d8cc2 · GitHub
[go: up one dir, main page]

Skip to content

Commit e7d8cc2

Browse files
committed
mimxrt/flexspi_nor_c: Set the 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>
1 parent 0d54c02 commit e7d8cc2

File tree

5 files changed

+95
-8
lines changed

5 files changed

+95
-8
lines changed

ports/mimxrt/flash.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
void flash_init(void) {
3030
// Upload the custom flash configuration
3131
// And fix the entry for PAGEPROGRAM_QUAD
32-
flexspi_nor_update_lut();
32+
// Update the flash CLK
33+
flexspi_nor_update_lut_clk(MICROPY_HW_FLASH_CLK);
3334

3435
// Configure FLEXSPI IP FIFO access.
3536
BOARD_FLEX_SPI->MCR0 &= ~(FLEXSPI_MCR0_ARDFEN_MASK);

ports/mimxrt/hal/flexspi_hyper_flash.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include "fsl_clock.h"
1010
#include "flexspi_hyper_flash.h"
1111

12-
void flexspi_nor_update_lut(void) {
12+
void flexspi_nor_update_lut_clk(uint32_t freq_index) {
1313
}
1414

1515
// Copy of a few (pseudo-)functions from fsl_clock.h, which were nor reliably

ports/mimxrt/hal/flexspi_hyper_flash.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ extern flexspi_nor_config_t qspiflash_config;
4747

4848
status_t flexspi_nor_hyperflash_cfi(FLEXSPI_Type *base);
4949
void flexspi_hyper_flash_init(void);
50-
void flexspi_nor_update_lut(void);
50+
void flexspi_nor_update_lut_clk(uint32_t freq_index);
5151
status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
5252
status_t flexspi_nor_flash_erase_block(FLEXSPI_Type *base, uint32_t address);
5353
status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t address, const uint32_t *src, uint32_t size);

ports/mimxrt/hal/flexspi_nor_flash.c

Lines changed: 90 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@
3838
#include "flexspi_nor_flash.h"
3939
#include "flexspi_flash_config.h"
4040

41+
bool flash_busy_status_pol = 0;
42+
bool flash_busy_status_offset = 0;
43+
4144
uint32_t LUT_pageprogram_quad[4] = {
4245
// 10 Page Program - quad mode
4346
FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0x32, RADDR_SDR, FLEXSPI_1PAD, 24),
@@ -54,16 +57,100 @@ uint32_t LUT_write_status[4] = {
5457
FLEXSPI_LUT_SEQ(0, 0, 0, 0, 0, 0), // Filler
5558
};
5659

57-
void flexspi_nor_update_lut(void) {
60+
#if defined(MIMXRT117x_SERIES)
61+
static uint8_t div_table_mhz[] = {
62+
17, // Entry 0 is out of range
63+
17, // 30 -> 31 MHz
64+
10, // 50 -> 52.8 MHz
65+
9, // 60 -> 58.7 MHz
66+
7, // 75 -> 75.4 MHz
67+
7, // 80 -> 75.4 MHz
68+
5, // 100 -> 105.6 Mhz
69+
4, // 133 -> 132 MHz
70+
3 // 166 -> 176 MHz
71+
};
72+
73+
#else
74+
typedef struct _ps_div_t {
75+
uint8_t pfd480_div;
76+
uint8_t podf_div;
77+
} ps_div_t;
78+
79+
static ps_div_t div_table_mhz[] = {
80+
{ 35, 8 }, // Entry 0 is out of range
81+
{ 35, 8 }, // 30 -> 30.85 MHz
82+
{ 29, 6 }, // 50 -> 49.65 MHz
83+
{ 18, 8 }, // 60 -> 60 MHz
84+
{ 23, 5 }, // 75 -> 75.13 MHz
85+
{ 18, 6 }, // 80 -> 80 MHz
86+
{ 17, 5 }, // 100 -> 191 Mhz
87+
{ 13, 5 }, // 133 -> 132.92 MHz
88+
{ 13, 4 } // 166 -> 166.15 MHz
89+
};
90+
#endif
91+
92+
__attribute__((section(".ram_functions"))) void flexspi_nor_update_lut_clk(uint32_t freq_index) {
93+
// Create a local copy of the LookupTable. Modify the entry for WRITESTATUSREG
94+
// Add an entry for PAGEPROGRAM_QUAD.
5895
uint32_t lookuptable_copy[64];
5996
memcpy(lookuptable_copy, (const uint32_t *)&qspiflash_config.memConfig.lookupTable, 64 * sizeof(uint32_t));
60-
// write WRITESTATUSREG code to entry 10
97+
// write local WRITESTATUSREG code to index 4
6198
memcpy(&lookuptable_copy[NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG * 4],
6299
LUT_write_status, 4 * sizeof(uint32_t));
63-
// write PAGEPROGRAM_QUAD code to entry 10
100+
// write local PAGEPROGRAM_QUAD code to index 10
64101
memcpy(&lookuptable_copy[NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD * 4],
65102
LUT_pageprogram_quad, 4 * sizeof(uint32_t));
103+
// Update the LookupTable.
66104
FLEXSPI_UpdateLUT(BOARD_FLEX_SPI, 0, lookuptable_copy, 64);
105+
106+
__DSB();
107+
__ISB();
108+
__disable_irq();
109+
SCB_DisableDCache();
110+
111+
#if defined(MIMXRT117x_SERIES)
112+
volatile uint8_t pll2_div = div_table_mhz[freq_index] - 1;
113+
114+
while (!FLEXSPI_GetBusIdleStatus(BOARD_FLEX_SPI)) {
115+
}
116+
FLEXSPI_Enable(BOARD_FLEX_SPI, false);
117+
118+
// Disable FlexSPI clock
119+
// Flexspi is clocked by PLL2. Only the divider can be changed.
120+
CCM->LPCG[kCLOCK_Flexspi1].DIRECT = ((uint32_t)kCLOCK_Off & CCM_LPCG_DIRECT_ON_MASK);
121+
// Change the PLL divider
122+
CCM->CLOCK_ROOT[kCLOCK_Root_Flexspi1].CONTROL = (CCM->CLOCK_ROOT[kCLOCK_Root_Flexspi1].CONTROL & ~CCM_CLOCK_ROOT_CONTROL_DIV_MASK) |
123+
CCM_CLOCK_ROOT_CONTROL_DIV(pll2_div);
124+
// Re-enable FlexSPI clock
125+
CCM->LPCG[kCLOCK_Flexspi1].DIRECT = ((uint32_t)kCLOCK_On & CCM_LPCG_DIRECT_ON_MASK);
126+
127+
#else
128+
129+
volatile uint8_t pfd480_div = div_table_mhz[freq_index].pfd480_div;
130+
volatile uint8_t podf_div = div_table_mhz[freq_index].podf_div - 1;
131+
132+
while (!FLEXSPI_GetBusIdleStatus(BOARD_FLEX_SPI)) {
133+
}
134+
FLEXSPI_Enable(BOARD_FLEX_SPI, false);
135+
136+
// Disable FlexSPI clock
137+
CCM->CCGR6 &= ~CCM_CCGR6_CG5_MASK;
138+
// Changing the clock is OK now.
139+
// Change the PFD
140+
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);
141+
// Change the flexspi divider
142+
CCM->CSCMR1 = (CCM->CSCMR1 & ~CCM_CSCMR1_FLEXSPI_PODF_MASK) | CCM_CSCMR1_FLEXSPI_PODF(podf_div);
143+
// Re-enable FlexSPI
144+
CCM->CCGR6 |= CCM_CCGR6_CG5_MASK;
145+
#endif
146+
147+
FLEXSPI_Enable(BOARD_FLEX_SPI, true);
148+
FLEXSPI_SoftwareReset(BOARD_FLEX_SPI);
149+
while (!FLEXSPI_GetBusIdleStatus(BOARD_FLEX_SPI)) {
150+
}
151+
152+
SCB_EnableDCache();
153+
__enable_irq();
67154
}
68155

69156
void flexspi_nor_reset(FLEXSPI_Type *base) __attribute__((section(".ram_functions")));

ports/mimxrt/hal/flexspi_nor_flash.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@
4545
extern flexspi_nor_config_t qspiflash_config;
4646

4747
status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
48-
status_t flexspi_nor_init(void);
49-
void flexspi_nor_update_lut(void);
48+
void flexspi_nor_update_lut_clk(uint32_t freq_index);
5049
status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
5150
status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
5251
status_t flexspi_nor_flash_erase_block(FLEXSPI_Type *base, uint32_t address);

0 commit comments

Comments
 (0)
0