stm32g4: Fix incorrect FLASH wait states

When the architectural support for STM32G4 family was added, the
reference manual (RM0440) was at revision 2. Since then, it has
undergone several revisions. One significant change is in the
table of FLASH wait states: section 3.3.3 table 9. The outcome
of this change is that fewer FLASH wait states are needed for
most CPU clock (HCLK) frequencies. Notably, if running the CPU
clock at the maximum 170 MHz, only 4 FLASH wait states are
needed, rather than the previously programmed 8 wait states.
This gives a noticeable performance boost.

arch/arm/src/stm32/stm32g4xxxx_rcc.c:

    * FLASH_ACR_LATENCY_SETTING: Reimplement compile-time logic
      that selects the required wait state setting to use the new
      updated table.

    * Update all comments to indicate that RM0440 Rev 5 is used.

    * Update section numbers mentioned in comments in cases where
      they have changed due to added sections in the manual.
This commit is contained in:
Nathan Hartman 2020-12-20 14:54:45 -05:00 committed by Mateusz Szafoni
parent 881121444c
commit 4cefc5ce7a

View File

@ -19,7 +19,7 @@
****************************************************************************/ ****************************************************************************/
/* Unless otherwise specified, when comments in this file refer to the /* Unless otherwise specified, when comments in this file refer to the
* reference manual, that is the STM32G4 Reference Manual (RM0440 Rev 2). * reference manual, that is the STM32G4 Reference Manual (RM0440 Rev 5).
* *
* This file requires a clocking configuration, which is set in board.h, * This file requires a clocking configuration, which is set in board.h,
* consisting of some or all of the following defines: * consisting of some or all of the following defines:
@ -126,7 +126,7 @@
/* Per the reference manual: /* Per the reference manual:
* *
* Choose PWR VOS range setting and R1MODE based on SYSCLK frequency (see * Choose PWR VOS range setting and R1MODE based on SYSCLK frequency (see
* section 5.1.5, Dynamic voltage scaling management). * section 6.1.5, Dynamic voltage scaling management).
* *
* Choose number of FLASH wait states according to CPU clock (HCLK) * Choose number of FLASH wait states according to CPU clock (HCLK)
* frequency (see section 3.3.3, Read access latency, and Table 9 in that * frequency (see section 3.3.3, Read access latency, and Table 9 in that
@ -138,43 +138,48 @@
#if (STM32_SYSCLK_FREQUENCY > 26000000) #if (STM32_SYSCLK_FREQUENCY > 26000000)
# define PWR_CR1_VOS_RANGE_SETTING PWR_CR1_VOS_RANGE_1 # define PWR_CR1_VOS_RANGE_SETTING PWR_CR1_VOS_RANGE_1
# if (STM32_SYSCLK_FREQUENCY > 150000000) # if (STM32_SYSCLK_FREQUENCY > 150000000) /* Table 9, left column, "Vcore Range 1 boost mode" */
# define PWR_CR5_R1MODE_SETTING 0 # define PWR_CR5_R1MODE_SETTING 0
# else # if (STM32_HCLK_FREQUENCY <= 34000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_0
# elif (STM32_HCLK_FREQUENCY <= 68000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_1
# elif (STM32_HCLK_FREQUENCY <= 102000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_2
# elif (STM32_HCLK_FREQUENCY <= 136000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_3
# elif (STM32_HCLK_FREQUENCY <= 170000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_4
# else
# error "Incorrect STM32_HCLK_FREQUENCY (Vcore range 1 boost mode)!"
# endif
# else /* Table 9, middle column, "Vcore Range 1 normal mode" */
# define PWR_CR5_R1MODE_SETTING PWR_CR5_R1MODE # define PWR_CR5_R1MODE_SETTING PWR_CR5_R1MODE
# if (STM32_HCLK_FREQUENCY <= 30000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_0
# elif (STM32_HCLK_FREQUENCY <= 60000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_1
# elif (STM32_HCLK_FREQUENCY <= 90000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_2
# elif (STM32_HCLK_FREQUENCY <= 120000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_3
# elif (STM32_HCLK_FREQUENCY <= 150000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_4
# else
# error "Incorrect STM32_HCLK_FREQUENCY (Vcore range 1 normal mode)!"
# endif
# endif # endif
# if (STM32_HCLK_FREQUENCY <= 20000000) #else /* Table 9, right column, "Vcore Range 2" */
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_0
# elif (STM32_HCLK_FREQUENCY <= 40000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_1
# elif (STM32_HCLK_FREQUENCY <= 60000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_2
# elif (STM32_HCLK_FREQUENCY <= 80000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_3
# elif (STM32_HCLK_FREQUENCY <= 100000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_4
# elif (STM32_HCLK_FREQUENCY <= 120000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_5
# elif (STM32_HCLK_FREQUENCY <= 140000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_6
# elif (STM32_HCLK_FREQUENCY <= 160000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_7
# elif (STM32_HCLK_FREQUENCY <= 170000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_8
# else
# error "Incorrect STM32_HCLK_FREQUENCY (VOS range 1)!"
# endif
#else
# define PWR_CR1_VOS_RANGE_SETTING PWR_CR1_VOS_RANGE_2; # define PWR_CR1_VOS_RANGE_SETTING PWR_CR1_VOS_RANGE_2;
# define PWR_CR5_R1MODE_SETTING 0 # define PWR_CR5_R1MODE_SETTING 0
# if (STM32_HCLK_FREQUENCY <= 8000000) # if (STM32_HCLK_FREQUENCY <= 12000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_0 # define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_0
# elif (STM32_HCLK_FREQUENCY <= 16000000) # elif (STM32_HCLK_FREQUENCY <= 24000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_1 # define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_1
# elif (STM32_HCLK_FREQUENCY <= 26000000) # elif (STM32_HCLK_FREQUENCY <= 26000000)
# define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_2 # define FLASH_ACR_LATENCY_SETTING FLASH_ACR_LATENCY_2
# else # else
# error "Incorrect STM32_HCLK_FREQUENCY! (VOS range 2)" # error "Incorrect STM32_HCLK_FREQUENCY! (Vcore range 2)"
# endif # endif
#endif #endif
@ -901,7 +906,7 @@ static void stm32_stdclockconfig(void)
/* If SYSCLK > 150MHz, temporarily set the HCLK prescaler (RCC_CFGR_HPRE) /* If SYSCLK > 150MHz, temporarily set the HCLK prescaler (RCC_CFGR_HPRE)
* to divide by 2 (RCC_CFGR_HPRE_SYSCLKd2) before changing SYSCLK source * to divide by 2 (RCC_CFGR_HPRE_SYSCLKd2) before changing SYSCLK source
* to PLL. Afterwards, (after waiting at least 1us) change back to no * to PLL. Afterwards, (after waiting at least 1us) change back to no
* division (RCC_CFGR_HPRE_SYSCLK). See reference manual, section 5.1.5. * division (RCC_CFGR_HPRE_SYSCLK). See reference manual, section 6.1.5.
*/ */
regval = getreg32(STM32_RCC_CFGR); regval = getreg32(STM32_RCC_CFGR);