Add register definitions for SAM4L BPM and SCIF blocks; SAM4L clock initialization now selects an optimal power scaling mode

This commit is contained in:
Gregory Nutt 2013-06-06 11:18:52 -06:00
parent 3e823e5468
commit 4055f6d697
3 changed files with 116 additions and 72 deletions

View File

@ -333,6 +333,36 @@
#define FLASH_CMD_HSEN 16 /* High Speed Mode Enable */
#define FLASH_CMD_HSDIS 17 /* High Speed Mode Disable */
/* 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
* ------- ---- ----- -------- ---------- ----------
*/
#define FLASH_MAXFREQ_PS0_HSDIS_FASTWKUP_FWS1 (12000000ul)
#define FLASH_MAXFREQ_PS0_HSDIS_FWS0 (18000000ul)
#define FLASH_MAXFREQ_PS0_HSDIS_FWS1 (36000000ul)
#define FLASH_MAXFREQ_PS1_HSDIS_FASTWKUP_FWS1 (12000000ul)
#define FLASH_MAXFREQ_PS1_HSDIS_FWS0 (8000000ul)
#define FLASH_MAXFREQ_PS1_HSDIS_FWS1 (12000000ul)
#define FLASH_MAXFREQ_PS2_HSEN_FWS0 (24000000ul)
#define FLASH_MAXFREQ_PS2_HSEN_FWS1 (48000000ul)
/************************************************************************************
* Public Types
************************************************************************************/

View File

@ -55,6 +55,17 @@
/****************************************************************************
* Private Definitions
****************************************************************************/
/* Nominal frequencies in on-chip RC oscillators. These may frequencies
* may vary with temperature changes.
*/
#define SAM_RCSYS_FREQUENCY 115000 /* Nominal frequency of RCSYS (Hz) */
#define SAM_RC32K_FREQUENCY 32768 /* Nominal frequency of RC32K (Hz) */
#define SAM_RC80M_FREQUENCY 80000000 /* Nominal frequency of RC80M (Hz) */
#define SAM_RCFAST4M_FREQUENCY 4000000 /* Nominal frequency of RCFAST4M (Hz) */
#define SAM_RCFAST8M_FREQUENCY 8000000 /* Nominal frequency of RCFAST8M (Hz) */
#define SAM_RCFAST12M_FREQUENCY 12000000 /* Nominal frequency of RCFAST12M (Hz) */
#define SAM_RC1M_FREQUENCY 1000000 /* Nominal frequency of RC1M (Hz) */
#if defined(SAM_CLOCK_OSC0) || \
(defined (SAM_CLOCK_PLL0) && defined(SAM_CLOCK_PLL0_OSC0)) || \
@ -62,12 +73,6 @@
# define NEED_OSC0
#endif
#if defined(SAM_CLOCK_OSC1) || \
(defined (SAM_CLOCK_PLL0) && defined(SAM_CLOCK_PLL0_OSC1)) || \
(defined (SAM_CLOCK_PLL1) && defined(SAM_CLOCK_PLL1_OSC1))
# define NEED_OSC1
#endif
/****************************************************************************
* Private Types
****************************************************************************/
@ -192,55 +197,6 @@ static inline void sam_enableosc0(void)
}
#endif
/****************************************************************************
* Name: sam_enableosc1
*
* Description:
* Initialiaze OSC0 settings per the definitions in the board.h file.
*
****************************************************************************/
#ifdef NEED_OSC1
static inline void sam_enableosc1(void)
{
uint32_t regval;
/* Enable OSC1 in the correct crystal mode by setting the mode value in OSCCTRL1 */
regval = getreg32(SAM_PM_OSCCTRL1);
regval &= ~PM_OSCCTRL_MODE_MASK;
#if SAM_FOSC1 < 900000
regval |= PM_OSCCTRL_MODE_XTALp9; /* Crystal XIN 0.4-0.9MHz */
#elif SAM_FOSC1 < 3000000
regval |= PM_OSCCTRL_MODE_XTAL3; /* Crystal XIN 0.9-3.0MHz */
#elif SAM_FOSC1 < 8000000
regval |= PM_OSCCTRL_MODE_XTAL8; /* Crystal XIN 3.0-8.0MHz */
#else
regval |= PM_OSCCTRL_MODE_XTALHI; /* Crystal XIN above 8.0MHz */
#endif
putreg32(regval, SAM_PM_OSCCTRL1);
/* Enable OSC1 using the startup time provided in board.h. This startup time
* is critical and depends on the characteristics of the crystal.
*/
regval = getreg32(SAM_PM_OSCCTRL1);
regval &= ~PM_OSCCTRL_STARTUP_MASK;
regval |= (SAM_OSC1STARTUP << PM_OSCCTRL_STARTUP_SHIFT);
putreg32(regval, SAM_PM_OSCCTRL1);
/* Enable OSC1 */
regval = getreg32(SAM_PM_MCCTRL);
regval |= PM_MCCTRL_OSC1EN;
putreg32(regval, SAM_PM_MCCTRL);
/* Wait for OSC1 to be ready */
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_OSC1RDY) == 0);
}
#endif
/****************************************************************************
* Name: sam_enablepll0
*
@ -505,17 +461,75 @@ static inline void sam_usbclock(void)
void sam_clockconfig(void)
{
uint32_t regval;
uint32_t bpmps;
bool fastwkup;
/* Enable clocking to the PICOCACHE */
sam_picocache();
/* Configure dividers derived clocks. These divider definitions must be
* provided in the board.h header file.
/* Configure dividers for derived clocks. These divider definitions must
* be provided in the board.h header file.
*/
sam_setdividers(BOARD_SYSCLK_CPU_DIV, BOARD_SYSCLK_PBA_DIV,
BOARD_SYSCLK_PBB_DIV, BOARD_SYSCLK_PBC_DIV,
BOARD_SYSCLK_PBD_DIV);
sam_setdividers(BOARD_CPU_SHIFT, BOARD_PBA_SHIFT, BOARD_PBB_SHIFT,
BOARD_PBC_SHIFT, BOARD_PBD_SHIFT);
/* Select a power scaling mode and possible fast wakeup so that we get the
* best possible flash performance. The following table shows the 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
* ------- ---- ----- -------- ---------- ----------
*/
#ifdef CONFIG_SAM_FLASH_HSEN
/* The high speed FLASH mode has been enabled. Select power scaling mode 2 */
bpmps = BPM_PMCON_PS2;
fastwkup = false;
#else
/* Not high speed mode. Check if we can go to power scaling mode 1. */
if (BOARD_CPU_FREQUENCY <= FLASH_MAXFREQ_PS1_HSDIS_FWS1)
{
/* Yes.. Do we also need to enable fast wakeup? */
bpmps = BPM_PMCON_PS1;
if (BOARD_CPU_FREQUENCY > FLASH_MAXFREQ_PS1_HSDIS_FWS0)
{
/* Yes.. enable fast wakeup */
regval = getreg32(SAM_BPM_PMCON);
regval |= BPM_PMCON_FASTWKUP;
putreg32(BPM_UNLOCK_KEY(0xaa) | BPM_UNLOCK_ADDR(SAM_BPM_PMCON_OFFSET), SAM_BPM_UNLOCK);
putreg32(regval, SAM_BPM_PMCON);
/* We need to remember that we did this */
fastwkup = true;
}
}
else
{
bpmps = BPM_PMCON_PS0;
}
#endif
#ifdef SAM_CLOCK_OSC32
/* Enable the 32KHz oscillator (need by the RTC module) */

View File

@ -98,7 +98,7 @@
static inline void up_enableosc32(void)
{
uint32_t regval;
/* Select the 32KHz oscillator crystal */
regval = getreg32(AVR32_PM_OSCCTRL32);
@ -225,7 +225,7 @@ static inline void up_enableosc1(void)
static inline void up_enablepll0(void)
{
/* Setup PLL0 */
regval = (AVR32_PLL0_DIV << PM_PLL_PLLDIV_SHIFT) | (AVR32_PLL0_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
/* Select PLL0/1 oscillator */
@ -256,7 +256,7 @@ static inline void up_enablepll0(void)
regval = getreg32(AVR32_PM_PLL0);
regval |= PM_PLL_PLLEN;
putreg32(regval, AVR32_PM_PLL0)
/* Wait for PLL0 locked. */
while ((getreg32(AVR32_PM_POSCSR) & PM_POSCSR_LOCK0) == 0);
@ -275,11 +275,11 @@ static inline void up_enablepll0(void)
static inline void up_enablepll1(void)
{
/* Setup PLL1 */
regval = (AVR32_PLL1_DIV << PM_PLL_PLLDIV_SHIFT) | (AVR32_PLL1_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
/* Select PLL0/1 oscillator */
#if AVR32_CLOCK_PLL_OSC1
regval |= PM_PLL_PLLOSC;
#endif
@ -363,7 +363,7 @@ static inline void up_clksel(void)
static void up_fws(uint32_t cpuclock)
{
uint32_t regval;
regval = getreg32(AVR32_FLASHC_FCR);
if (cpuclock > AVR32_FLASHC_FWS0_MAXFREQ)
{
@ -387,7 +387,7 @@ static void up_fws(uint32_t cpuclock)
static inline void up_mainclk(uint32_t mcsel)
{
uint32_t regval;
regval = getreg32(AVR32_PM_MCCTRL);
regval &= ~PM_MCCTRL_MCSEL_MASK;
regval |= mcsel;
@ -422,7 +422,7 @@ static inline void up_usbclock(void)
putreg32(regval, AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB))
/* Enable USB GCLK */
regval = getreg32(AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB))
regval |= PM_GCCTRL_CEN;
putreg32(regval, AVR32_PM_GCCTRL(AVR32_PM_GCLK_USBB))
@ -441,7 +441,7 @@ static inline void up_usbclock(void)
* file.
*
**************************************************************************/
void up_clkinitialize(void)
{
#ifdef AVR32_CLOCK_OSC32
@ -458,7 +458,7 @@ void up_clkinitialize(void)
/* Set up FLASH wait states */
up_fws(AVR32_FOSC0);
/* Then switch the main clock to OSC0 */
up_mainclk(PM_MCCTRL_MCSEL_OSC0);
@ -474,11 +474,11 @@ void up_clkinitialize(void)
/* Enable PLL0 using the settings in board.h */
up_enablepll0();
/* Set up FLASH wait states */
up_fws(AVR32_CPU_CLOCK);
/* Then switch the main clock to PLL0 */
up_mainclk(PM_MCCTRL_MCSEL_PLL0);