SAM4L: Add logic to configure FLASH read mode and wait states
This commit is contained in:
parent
11f81d3bfa
commit
2d5c249072
@ -80,7 +80,7 @@
|
||||
#define SAM_FLASHCALW_FCMD (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FCMD_OFFSET)
|
||||
#define SAM_FLASHCALW_FSR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FSR_OFFSET)
|
||||
#define SAM_FLASHCALW_FPR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FPR_OFFSET)
|
||||
#define SAM_FLASHCALW_FSR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FSR_OFFSET)
|
||||
#define SAM_FLASHCALW_FVR (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FVR_OFFSET)
|
||||
#define SAM_FLASHCALW_FGPFRHI (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FGPFRHI_OFFSET)
|
||||
#define SAM_FLASHCALW_FGPFRLO (SAM_FLASHCALW_BASE+SAM_FLASHCALW_FGPFRLO_OFFSET)
|
||||
|
||||
@ -131,6 +131,7 @@
|
||||
#define FLASHCALW_FCMD_PAGEN_MASK (0xffff << FLASHCALW_FCMD_PAGEN_SHIFT)
|
||||
#define FLASHCALW_FCMD_KEY_SHIFT (14) /* Bits 24-31: Write protection key */
|
||||
#define FLASHCALW_FCMD_KEY_MASK (0xff << FLASHCALW_FCMD_KEY_SHIFT)
|
||||
# define FLASHCALW_FCMD_KEY (0xa5 << FLASHCALW_FCMD_KEY_SHIFT)
|
||||
|
||||
/* Flash Status Register */
|
||||
|
||||
@ -161,7 +162,6 @@
|
||||
#define FLASHCALW_FSR_LOCK15 (1 << 31) /* Bit 31: Lock Region 15 Lock Status */
|
||||
|
||||
/* Flash Parameter Register */
|
||||
#define FLASHCALW_FPR_
|
||||
|
||||
#define FLASHCALW_FPR_FSZ_SHIFT (0) /* Bits 0-3: Flash Size */
|
||||
#define FLASHCALW_FPR_FSZ_MASK (15 << FLASHCALW_FPR_FSZ_SHIFT)
|
||||
|
@ -65,6 +65,14 @@
|
||||
# error "CONFIG_ARCH_RAMFUNCS must be defined"
|
||||
#endif
|
||||
|
||||
/* Board/Clock Setup *******************************************************/
|
||||
/* Verify dividers */
|
||||
|
||||
#if ((BOARD_CPU_SHIFT > BOARD_PBA_SHIFT) || (BOARD_CPU_SHIFT > BOARD_PBB_SHIFT) || \
|
||||
(BOARD_CPU_SHIFT > BOARD_PBC_SHIFT) || (BOARD_CPU_SHIFT > BOARD_PBD_SHIFT))
|
||||
# error BOARD_PBx_SHIFT must be greater than or equal to BOARD_CPU_SHIFT
|
||||
#endif
|
||||
|
||||
/* Nominal frequencies in on-chip RC oscillators. These may frequencies
|
||||
* may vary with temperature changes.
|
||||
*/
|
||||
@ -900,19 +908,24 @@ static inline void sam_setdividers(void)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_fws
|
||||
* Name: set_flash_waitstate
|
||||
*
|
||||
* Description:
|
||||
* Setup FLASH wait states.
|
||||
* Setup one or two FLASH wait states.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_fws(uint32_t cpuclock, uint32_t psm, bool fastwkup)
|
||||
static inline void set_flash_waitstate(bool waitstate)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Set or clear the FLASH wait state (FWS) bit in the FLASH control
|
||||
* register (FCR).
|
||||
*/
|
||||
|
||||
regval = getreg32(SAM_FLASHCALW_FCR);
|
||||
if (cpuclock > SAM_FLASHCALW_FWS0_MAXFREQ)
|
||||
|
||||
if (waitstate)
|
||||
{
|
||||
regval |= FLASHCALW_FCR_FWS;
|
||||
}
|
||||
@ -924,6 +937,157 @@ static inline void sam_fws(uint32_t cpuclock, uint32_t psm, bool fastwkup)
|
||||
putreg32(regval, SAM_FLASHCALW_FCR);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_flash_readmode
|
||||
*
|
||||
* Description:
|
||||
* Send a FLASH command to enable to disable high speed FLASH read mode.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_flash_readmode(uint32_t command)
|
||||
{
|
||||
uint32_t regval;
|
||||
|
||||
/* Make sure that any previous FLASH operation is completed */
|
||||
|
||||
while ((getreg32(SAM_FLASHCALW_FSR) & FLASHCALW_FSR_FRDY) == 0);
|
||||
|
||||
/* Write the specified FLASH command to the FCMD register */
|
||||
|
||||
regval = getreg32(SAM_FLASHCALW_FCMD);
|
||||
regval &= ~FLASHCALW_FCMD_CMD_MASK;
|
||||
regval |= (FLASHCALW_FCMD_KEY | command);
|
||||
putreg32(regval, SAM_FLASHCALW_FCMD);
|
||||
|
||||
/* Wait for this FLASH operation to complete */
|
||||
|
||||
while ((getreg32(SAM_FLASHCALW_FSR) & FLASHCALW_FSR_FRDY) == 0);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_flash_config
|
||||
*
|
||||
* Description:
|
||||
* Configure FLASH read mode and wait states.
|
||||
*
|
||||
* Maximum CPU frequency for 0 and 1 FLASH wait states (FWS) in various modes
|
||||
* (Table 42-30 in the big data sheet).
|
||||
*
|
||||
* ------- ------------------- ---------- ----------
|
||||
* Power Flash Read Mode Flash Maximum
|
||||
* Sclaing Wait Operating
|
||||
* Mode HSEN HSDIS FASTWKUP States Frequency
|
||||
* ------- ---- ----- -------- ---------- ----------
|
||||
* PS0 X X 1 12MHz
|
||||
* " " X 0 18MHz
|
||||
* " " X 1 36MHz
|
||||
* PS1 X X 1 12MHz
|
||||
* " " X 0 8MHz
|
||||
* " " X 1 12MHz
|
||||
* PS2 X 0 24Mhz
|
||||
* " " X 1 48MHz
|
||||
* ------- ---- ----- -------- ---------- ----------
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void sam_flash_config(uint32_t cpuclock, uint32_t psm, bool fastwkup)
|
||||
{
|
||||
bool waitstate;
|
||||
uint32_t command;
|
||||
|
||||
#ifdef CONFIG_SAM34_FLASH_HSEN
|
||||
/* High speed flash read mode (with power scaling mode == 2). Set one
|
||||
* wait state if the CPU clock frequency exceeds the threshold value
|
||||
* and enable high speed read mode.
|
||||
*/
|
||||
|
||||
waitstate = (cpuclock > FLASH_MAXFREQ_PS2_HSEN_FWS0);
|
||||
command = FLASHCALW_FCMD_CMD_HSEN;
|
||||
#else
|
||||
/* Assume that we will select no wait states and that we will disable high-
|
||||
* speed read mode.
|
||||
*/
|
||||
|
||||
waitstate = false;
|
||||
command = FLASHCALW_FCMD_CMD_HSDIS;
|
||||
|
||||
/* Handle power scaling mode == 0 FLASH configuration */
|
||||
|
||||
if (psm == 0)
|
||||
{
|
||||
/* Power scaling mode 0. We need to set wait state the CPU clock if
|
||||
* the CPU frequency exceeds a threshold.
|
||||
*/
|
||||
|
||||
if (cpuclock > FLASH_MAXFREQ_PS0_HSDIS_FWS0)
|
||||
{
|
||||
/* Set one wait state */
|
||||
|
||||
waitstate = true;
|
||||
|
||||
/* Enable high speed read mode if the frequency exceed the maximum
|
||||
* for the low speed configuration. This mode is not documented
|
||||
* in the data sheet, but I see that they do this in some Atmel
|
||||
* code examples.
|
||||
*/
|
||||
|
||||
if (cpuclock > FLASH_MAXFREQ_PS0_HSDIS_FWS1)
|
||||
{
|
||||
/* Enable high speed read mode. */
|
||||
|
||||
command = FLASHCALW_FCMD_CMD_HSEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* The is below the threshold that requires one wait state. But we
|
||||
* have to check a few more things.
|
||||
*/
|
||||
|
||||
else
|
||||
{
|
||||
/* If FLASH wake-up mode is selected and the we are in the lower
|
||||
* operating frequency for this mode, then set 1 waitate and
|
||||
* disable high speed read mode.
|
||||
*/
|
||||
|
||||
if ((fastwkup == true) &&
|
||||
(cpuclock <= FLASH_MAXFREQ_PS1_HSDIS_FASTWKUP_FWS1))
|
||||
{
|
||||
/* Set one wait state */
|
||||
|
||||
waistate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Otherwise, this is power scaling mode 1 */
|
||||
|
||||
else /* if (psm == 1) */
|
||||
{
|
||||
/* If we are in the lower operating frequency range, then select
|
||||
* zero wait states. Otherwise, select one wait state.
|
||||
*/
|
||||
|
||||
if (cpuclock > FLASH_MAXFREQ_PS1_HSDIS_FWS0)
|
||||
{
|
||||
/* Set one wait state */
|
||||
|
||||
waistate = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Set 0 or 1 waitstates */
|
||||
|
||||
set_flash_waitstate(waitstate);
|
||||
|
||||
/* Enable/disable the high-speed read mode. */
|
||||
|
||||
sam_flash_readmode(command);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam_mainclk
|
||||
*
|
||||
@ -1164,9 +1328,9 @@ void sam_clockconfig(void)
|
||||
// sam_mainclk(PM_MCCTRL_MCSEL_RCSYS);
|
||||
#elif defined(BOARD_SYSCLK_SOURCE_OSC0)
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
/* Configure FLASH read mode and wait states */
|
||||
|
||||
sam_fws(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
|
||||
/* Then switch the main clock to OSC0 */
|
||||
|
||||
@ -1178,9 +1342,9 @@ void sam_clockconfig(void)
|
||||
|
||||
sam_enablepll0();
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
/* Configure FLASH read mode and wait states */
|
||||
|
||||
sam_fws(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
|
||||
/* Then switch the main clock to PLL0 */
|
||||
|
||||
@ -1192,9 +1356,9 @@ void sam_clockconfig(void)
|
||||
|
||||
sam_enabledfll0();
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
/* Configure FLASH read mode and wait states */
|
||||
|
||||
sam_fws(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
|
||||
/* Then switch the main clock to DFLL0 */
|
||||
|
||||
@ -1202,9 +1366,9 @@ void sam_clockconfig(void)
|
||||
|
||||
#elif defined(BOARD_SYSCLK_SOURCE_RC80M)
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
/* Configure FLASH read mode and wait states */
|
||||
|
||||
sam_fws(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
|
||||
/* Then switch the main clock to RCM80 */
|
||||
|
||||
@ -1213,9 +1377,9 @@ void sam_clockconfig(void)
|
||||
#elif defined(BOARD_SYSCLK_SOURCE_FCFAST12M) || defined(BOARD_SYSCLK_SOURCE_FCFAST8M) || \
|
||||
defined(BOARD_SYSCLK_SOURCE_FCFAST4M)
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
/* Configure FLASH read mode and wait states */
|
||||
|
||||
sam_fws(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
|
||||
/* Then switch the main clock to RCFAST */
|
||||
|
||||
@ -1223,9 +1387,9 @@ void sam_clockconfig(void)
|
||||
|
||||
#elif defined(BOARD_SYSCLK_SOURCE_RC1M)
|
||||
|
||||
/* Set up FLASH wait states */
|
||||
/* Configure FLASH read mode and wait states */
|
||||
|
||||
sam_fws(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
sam_flash_config(BOARD_CPU_FREQUENCY, psm, fastwkup);
|
||||
|
||||
/* Then switch the main clock to RC1M */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user