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 93b67f1598
commit e352d4f3ad
5 changed files with 174 additions and 120 deletions

View File

@ -4910,4 +4910,7 @@
logic (leveraged from AVR32).
* nuttx/arch/arm/src/sam34/sam4l_periphclks.c/h: Add common
logic to enabled/disable SAM4L peripheral clocking (2013-6-5).
* nuttx/arch/arm/src/sam34/chip/sam4l_bpm.h and sam4l_scif.h: Add
register definitions for the SAM4L BMP and SCIF blocks (2013-6-6).
* nuttx/arch/arm/src/sam34/sam4l_clockconfig.c: New selects an
optimal power scaling mode (2013-6-6).

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);

View File

@ -54,66 +54,73 @@
************************************************************************************/
/* Clocking *************************************************************************/
/* After power-on reset, the sam3u device is running on a 4MHz internal RC. These
* definitions will configure clocking with MCK = 48MHz, PLLA = 96, and CPU=48MHz.
/* Select the DFLL as the source of the system clock.
*
* Options (define one):
* BOARD_SYSCLK_SOURCE_RCSYS - System RC oscillator
* BOARD_SYSCLK_SOURCE_OSC0 - Oscillator 0
* BOARD_SYSCLK_SOURCE_PLL0 - Phase Locked Loop 0
* BOARD_SYSCLK_SOURCE_DFLL0 - Digital Frequency Locked Loop
* BOARD_SYSCLK_SOURCE_RC80M - 80 MHz RC oscillator
* BOARD_SYSCLK_SOURCE_FCFAST12M - 12 MHz RC oscillator
* BOARD_SYSCLK_SOURCE_FCFAST8M - 8 MHz RC oscillator
* BOARD_SYSCLK_SOURCE_FCFAST4M - 4 MHz RC oscillator
* BOARD_SYSCLK_SOURCE_RC1M - 1 MHz RC oscillator
*/
/* Main oscillator register settings */
#define BOARD_SYSCLK_SOURCE_DFLL0 1
#define BOARD_CKGR_MOR_MOSCXTST (63 << CKGR_MOR_MOSCXTST_SHIFT) /* Start-up Time */
/* Nominal frequencies in on-chip RC oscillators. These are *not* configurable
* but appear here for use in frequency calculations. NOTE: These may frequencies
* may vary with temperature changes.
*/
/* PLLA configuration */
#define BOARD_RCSYS_FREQUENCY 115000 /* Nominal frequency of RCSYS (Hz) */
#define BOARD_RC32K_FREQUENCY 32768 /* Nominal frequency of RC32K (Hz) */
#define BOARD_RC80M_FREQUENCY 80000000 /* Nominal frequency of RC80M (Hz) */
#define BOARD_RCFAST4M_FREQUENCY 4000000 /* Nominal frequency of RCFAST4M (Hz) */
#define BOARD_RCFAST8M_FREQUENCY 8000000 /* Nominal frequency of RCFAST8M (Hz) */
#define BOARD_RCFAST12M_FREQUENCY 12000000 /* Nominal frequency of RCFAST12M (Hz) */
#define BOARD_RC1M_FREQUENCY 1000000 /* Nominal frequency of RC1M (Hz) */
#define BOARD_CKGR_PLLAR_MULA (7 << CKGR_PLLAR_MULA_SHIFT)
#define BOARD_CKGR_PLLAR_STMODE CKGR_PLLAR_STMODE_FAST
#define BOARD_CKGR_PLLAR_PLLACOUNT (63 << CKGR_PLLAR_PLLACOUNT_SHIFT)
#define BOARD_CKGR_PLLAR_DIVA CKGR_PLLAR_DIVA_BYPASS
/* On-board crystal frequencies */
/* PMC master clock register settings */
#define BOARD_OSC32_FREQUENCY 32768
#define BOARD_PMC_MCKR_CSS PMC_MCKR_CSS_PLLA
#define BOARD_PMC_MCKR_PRES PMC_MCKR_PRES_DIV2
/* Digital Frequency Locked Loop configuration
* Fdfll = (Fclk * DFLLmul) / DFLLdiv
* = 32768 * (48000000/32760) / 1 = 48MHz
*
* DFLL0 source options (select one):
* BOARD_DFLL0_SOURCE_RCSYS - System RC oscillator
* BOARD_DFLL0_SOURCE_OSC32K - 32.768KHz oscillator
* BOARD_DFLL0_SOURCE_OSC0 - Oscillator 0
* BOARD_DFLL0_SOURCE_RC80M - 80 MHz RC oscillator
* BOARD_DFLL0_SOURCE_RC32K - 32 kHz RC oscillator
*/
/* USB UTMI PLL start-up time */
#define BOARD_DFLL0_SOURCE_OSC32K 1
#define BOARD_FDLL0_FREQUENCY 48000000
#define BOARD_FDLL0_MUL (BOARD_FDLL0_FREQUENCY / BOARD_OSC32_FREQUENCY)
#define BOARD_FDLL0_DIV 1
#define BOARD_CKGR_UCKR_UPLLCOUNT (3 << CKGR_UCKR_UPLLCOUNT_SHIFT)
/* System clock dividers: Fbus = Fsys >> BUSshift */
/* System clock dividers: Fbus = Fsys / (2 ^ BUS_div) */
#define BOARD_SYSCLK_CPU_DIV 0
#define BOARD_SYSCLK_PBA_DIV 0
#define BOARD_SYSCLK_PBB_DIV 0
#define BOARD_SYSCLK_PBC_DIV 0
#define BOARD_SYSCLK_PBD_DIV 0
#define BOARD_CPU_SHIFT 0 /* Fcpu = Fsys = 48MHz */
#define BOARD_PBA_SHIFT 0 /* Fpba = Fsys = 48MHz */
#define BOARD_PBB_SHIFT 0 /* Fpbb = Fsys = 48MHz */
#define BOARD_PBC_SHIFT 0 /* Fpbc = Fsys = 48MHz */
#define BOARD_PBD_SHIFT 0 /* Fpbd = Fsys = 48MHz */
/* Resulting frequencies */
#define SAM_MAINOSC_FREQUENCY (12000000)
#define SAM_MCK_FREQUENCY (48000000)
#define SAM_PLLA_FREQUENCY (96000000)
#define SAM_CPU_FREQUENCY (48000000)
/* HSMCI clocking
*
* Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK)
* divided by (2*(CLKDIV+1)).
*
* MCI_SPEED = MCK / (2*(CLKDIV+1))
* CLKDIV = MCI / MCI_SPEED / 2 - 1
*/
/* MCK = 48MHz, CLKDIV = 59, MCI_SPEED = 48MHz / 2 * (59+1) = 400 KHz */
#define HSMCI_INIT_CLKDIV (59 << HSMCI_MR_CLKDIV_SHIFT)
/* MCK = 48MHz, CLKDIV = 1, MCI_SPEED = 48MHz / 2 * (1+1) = 12 MHz */
#define HSMCI_MMCXFR_CLKDIV (3 << HSMCI_MR_CLKDIV_SHIFT)
/* MCK = 48MHz, CLKDIV = 0, MCI_SPEED = 48MHz / 2 * (0+1) = 24 MHz */
#define HSMCI_SDXFR_CLKDIV (0 << HSMCI_MR_CLKDIV_SHIFT)
#define HSMCI_SDWIDEXFR_CLKDIV HSMCI_SDXFR_CLKDIV
#define BOARD_MAIN_FREQUENCY (12000000)
#define BOARD_CPU_FREQUENCY (BOARD_MAIN_FREQUENCY >> BOARD_CPU_SHIFT)
#define BOARD_PBA_FREQUENCY (BOARD_MAIN_FREQUENCY >> BOARD_PBA_SHIFT)
#define BOARD_PBB_FREQUENCY (BOARD_MAIN_FREQUENCY >> BOARD_PBB_SHIFT)
#define BOARD_PBC_FREQUENCY (BOARD_MAIN_FREQUENCY >> BOARD_PBC_SHIFT)
#define BOARD_PBD_FREQUENCY (BOARD_MAIN_FREQUENCY >> BOARD_PBD_SHIFT)
/* LED definitions ******************************************************************/
/* There are three LEDs on board the SAM4L Xplained Pro board: The EDBG