Update SAM4L PLL0 logic

This commit is contained in:
Gregory Nutt 2013-06-07 10:28:06 -06:00
parent f4954c743d
commit 5052df2e69
3 changed files with 391 additions and 231 deletions

View File

@ -209,6 +209,8 @@
#define SCIF_PLL0_PLLEN (1 << 0) /* Bit 0: PLL Enable */
#define SCIF_PLL0_PLLOSC_SHIFT (1) /* Bits 1-2: PLL Oscillator Select */
#define SCIF_PLL0_PLLOSC_MASK (3 << SCIF_PLL0_PLLOSC_SHIFT)
# define SCIF_PLL0_PLLOSC_OSC0 (0 << SCIF_PLL0_PLLOSC_SHIFT) /* Output clock from Oscillator0 */
# define SCIF_PLL0_PLLOSC_GCLK9 (1 << SCIF_PLL0_PLLOSC_SHIFT) /* Generic clock 9 */
#define SCIF_PLL0_PLLOPT_SHIFT (3) /* Bits 3-5: PLL Option */
#define SCIF_PLL0_PLLOPT_MASK (7 << SCIF_PLL0_PLLOPT_SHIFT)
# define SCIF_PLL0_PLLOPT_FVO (1 << SCIF_PLL0_PLLOPT_SHIFT) /* Selects the VCO frequency range (fvco) */
@ -220,6 +222,23 @@
#define SCIF_PLL0_PLLMUL_MASK (15 << SCIF_PLL0_PLLMUL_SHIFT)
#define SCIF_PLL0_PLLCOUNT_SHIFT (24) /* Bits 24-24: PLL Count */
#define SCIF_PLL0_PLLCOUNT_MASK (63 << SCIF_PLL0_PLLCOUNT_SHIFT)
# define SCIF_PLL0_PLLCOUNT_MAX (63 << SCIF_PLL0_PLLCOUNT_SHIFT)
/* PLL0 operates in two frequency ranges as determined by SCIF_PLL0_PLLOPT_FVO:
*
* 0: 80MHz < fvco < 180MHz
* 1: 160MHz < fvco < 240MHz
*
* These ranges and recommend threshold value are defined below:
*/
#define SCIF_PLL0_VCO_RANGE1_MINFREQ 160000000
#define SCIF_PLL0_VCO_RANGE1_MAXFREQ 240000000
#define SCIF_PLL0_VCO_RANGE0_MINFREQ 80000000
#define SCIF_PLL0_VCO_RANGE0_MAXFREQ 180000000
#define SAM_PLL0_VCO_RANGE_THRESHOLD \
((SCIF_PLL0_VCO_RANGE1_MINFREQ + SCIF_PLL0_VCO_RANGE0_MAXFREQ) >> 1)
/* DFLL0 Config Register */
@ -340,6 +359,20 @@
#define SCIF_GCCTRL_DIVEN (1 << 1) /* Bit 1: Divide Enable */
#define SCIF_GCCTRL_OSCSEL_SHIFT (8) /* Bits 8-12: Oscillator Select */
#define SCIF_GCCTRL_OSCSEL_MASK (31 << SCIF_GCCTRL_OSCSEL_SHIFT)
# define SCIF_GCCTRL_OSCSEL_RCSYS (0 << SCIF_GCCTRL_OSCSEL_SHIFT) /* System RC oscillator */
# define SCIF_GCCTRL_OSCSEL_OSC32K (1 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from OSC32K */
# define SCIF_GCCTRL_OSCSEL_DFLL0 (2 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from DFLL0 */
# define SCIF_GCCTRL_OSCSEL_OSC0 (3 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from Oscillator0 */
# define SCIF_GCCTRL_OSCSEL_RC80M (4 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 80MHz RCOSC */
# define SCIF_GCCTRL_OSCSEL_RCFAST (5 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 4,8,12MHz RCFAST */
# define SCIF_GCCTRL_OSCSEL_RC1M (6 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 1MHz RC1M */
# define SCIF_GCCTRL_OSCSEL_CPUCLK (7 << SCIF_GCCTRL_OSCSEL_SHIFT) /* The CPU clock */
# define SCIF_GCCTRL_OSCSEL_HSBCLK (8 << SCIF_GCCTRL_OSCSEL_SHIFT) /* High Speed Bus clock */
# define SCIF_GCCTRL_OSCSEL_PBACLK (9 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus A clock */
# define SCIF_GCCTRL_OSCSEL_PBBCLK (10 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus B clock */
# define SCIF_GCCTRL_OSCSEL_PBCCLK (11 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus C clock */
# define SCIF_GCCTRL_OSCSEL_PBDCLK (12 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Peripheral Bus D clock */
# define SCIF_GCCTRL_OSCSEL_RC32K (13 << SCIF_GCCTRL_OSCSEL_SHIFT) /* Output from 32kHz RCOSC */
#define SCIF_GCCTRL_DIV_SHIFT (16) /* Bits 16-31: Division Factor */
#define SCIF_GCCTRL_DIV_MASK (0xffff << SCIF_GCCTRL_DIV_SHIFT)

View File

@ -62,133 +62,139 @@
* 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) */
#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) */
/* Oscillator 0. This might be the system clock or the source clock for
* either PLL0 or DFPLL.
* either PLL0 or DFPLL. It might also be needed if OSC0 is the source
* clock for GCLK9.
*
* By selecting CONFIG_SAM_OSC0, you can also force the clock to be enabled
* at boot time.
*/
#if defined(CONFIG_SAM_OSC0) || defined(BOARD_SYSCLK_SOURCE_OSC0) || \
defined(BOARD_DFLL0_SOURCE_OSC0) || defined(BOARD_PLL0_SOURCE_OSC0)
# define NEED_OSC0 1
defined(BOARD_DFLL0_SOURCE_OSC0) || defined(BOARD_PLL0_SOURCE_OSC0) || \
defined(BOARD_GLCK9_SOURCE_OSC0)
# define NEED_OSC0 1
#endif
#ifdef NEED_OSC0
# if !defined(BOARD_OSC0_STARTUP_US)
# error BOARD_OSC0_STARTUP_US is not defined
# elif BOARD_OSC0_STARTUP_US == 0
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_0
# define OSC0_STARTUP_TIMEOUT 8
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_0
# define SAM_OSC0_STARTUP_TIMEOUT 8
# elif BOARD_OSC0_STARTUP_US <= 557
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_64
# define OSC0_STARTUP_TIMEOUT 80
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_64
# define SAM_OSC0_STARTUP_TIMEOUT 80
# elif BOARD_OSC0_STARTUP_US <= 1100
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_128
# define OSC0_STARTUP_TIMEOUT 160
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_128
# define SAM_OSC0_STARTUP_TIMEOUT 160
# elif BOARD_OSC0_STARTUP_US <= 18000
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_2K
# define OSC0_STARTUP_TIMEOUT 2560
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_2K
# define SAM_OSC0_STARTUP_TIMEOUT 2560
# elif BOARD_OSC0_STARTUP_US <= 36000
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_4K
# define OSC0_STARTUP_TIMEOUT 5120
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_4K
# define SAM_OSC0_STARTUP_TIMEOUT 5120
# elif BOARD_OSC0_STARTUP_US <= 71000
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_8K
# define OSC0_STARTUP_TIMEOUT 10240
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_8K
# define SAM_OSC0_STARTUP_TIMEOUT 10240
# elif BOARD_OSC0_STARTUP_US <= 143000
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_16K
# define OSC0_STARTUP_TIMEOUT 20480
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_16K
# define SAM_OSC0_STARTUP_TIMEOUT 20480
# elif BOARD_OSC0_STARTUP_US <= 285000
# define OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_32K
# define OSC0_STARTUP_TIMEOUT 40960
# define SAM_OSC0_STARTUP_VALUE SCIF_OSCCTRL0_STARTUP_32K
# define SAM_OSC0_STARTUP_TIMEOUT 40960
# else
# error BOARD_OSC0_STARTUP_US is out of range
# endif
# ifdef BOARD_OSC0_IS_XTAL
# define OSC0_MODE_VALUE SCIF_OSCCTRL0_MODE
# define SAM_OSC0_MODE_VALUE SCIF_OSCCTRL0_MODE
# if BOARD_OSC0_FREQUENCY < 2000000
# define OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(0)
# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(0)
# elif BOARD_OSC0_FREQUENCY < 4000000
# define OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(1)
# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(1)
# elif BOARD_OSC0_FREQUENCY < 8000000
# define OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(2)
# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(2)
# elif BOARD_OSC0_FREQUENCY < 16000000
# define OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(3)
# define SAM_OSC0_GAIN_VALUE SCIF_OSCCTRL0_GAIN(3)
# else
# define OSC0_GAIN_VALUE ((0x1u << 4) | SCIF_OSCCTRL0_GAIN(0))
# define SAM_OSC0_GAIN_VALUE ((0x1u << 4) | SCIF_OSCCTRL0_GAIN(0))
# endif
# else
# define OSC0_MODE_VALUE 0
# define OSC0_GAIN_VALUE 0
# define SAM_OSC0_MODE_VALUE 0
# define SAM_OSC0_GAIN_VALUE 0
# endif
#endif
/* OSC32. The 32K oscillator may be the source clock for DFPLL0.
/* OSC32. The 32K oscillator may be the source clock for DFPLL0 or
* the source clock for GLK9 that might be used to driver PLL0.
*
* By selecting CONFIG_SAM_OSC32K, you can also force the clock to be
* enabled at boot time. OSC32 may needed by other devices as well
* (AST, WDT, PICUART, RTC).
*/
#if defined(CONFIG_SAM_OSC32K) || defined(BOARD_DFLL0_SOURCE_OSC32K)
# define NEED_OSC32K 1
#if defined(CONFIG_SAM_OSC32K) || defined(BOARD_DFLL0_SOURCE_OSC32K) || \
defined(BOARD_GLCK9_SOURCE_OSC32K)
# define NEED_OSC32K 1
#endif
#ifdef NEED_OSC32K
# if !defined(BOARD_OSC32_STARTUP_US)
# error BOARD_OSC32_STARTUP_US is not defined
# elif BOARD_OSC32_STARTUP_US == 0
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_0
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_0
# elif BOARD_OSC32_STARTUP_US <= 1100
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_128
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_128
# elif BOARD_OSC32_STARTUP_US <= 72300
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_8K
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_8K
# elif BOARD_OSC32_STARTUP_US <= 143000
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_16K
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_16K
# elif BOARD_OSC32_STARTUP_US <= 570000
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_64K
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_64K
# elif BOARD_OSC32_STARTUP_US <= 1100000
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_128K
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_128K
# elif BOARD_OSC32_STARTUP_US <= 2300000
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_256K
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_256K
# elif BOARD_OSC32_STARTUP_US <= 4600000
# define OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_512K
# define SAM_OSC32_STARTUP_VALUE BSCIF_OSCCTRL32_STARTUP_512K
# else
# error BOARD_OSC32_STARTUP_US is out of range
# endif
# ifdef BOARD_OSC32_IS_XTAL
# define OSC32_MODE_VALUE BSCIF_OSCCTRL32_MODE_XTAL
# define SAM_OSC32_MODE_VALUE SCIF_OSCCTRL32_MODE_XTAL
# else
# define OSC32_MODE_VALUE BSCIF_OSCCTRL32_MODE_EXTCLK
# define SAM_OSC32_MODE_VALUE BSCIF_OSCCTRL32_MODE_EXTCLK
# endif
# ifndef BOARD_OSC32_SELCURR
# define BOARD_OSC32_SELCURR BSCIF_OSCCTRL32_SELCURR_300
# define BOARD_OSC32_SELCURR BSCIF_OSCCTRL32_SELCURR_300
# endif
#endif
/* RC80M. This might be the system clock or the source clock for the DFPLL.
/* RC80M. This might be the system clock or the source clock for the DFPLL
* or it could be the source for GCLK9 that drives PLL0.
*
* By selecting CONFIG_SAM_RC80M, you can also force the clock to be enabled
* at boot time.
*/
#if defined(CONFIG_SAM_RC80M) || defined(BOARD_SYSCLK_SOURCE_RC80M) || \
defined(BOARD_DFLL0_SOURCE_RC80M)
# define NEED_RC80M 1
defined(BOARD_DFLL0_SOURCE_RC80M) || BOARD_GLCK9_SOURCE_RC80M
# define NEED_RC80M 1
#endif
/* RCFAST. The 12/8/4 fast RC oscillator may be used as the system clock.
/* RCFAST. The 12/8/4 fast RC oscillator may be used as the system clock
* or as the source for GLCK9 that drives PLL0.
* If not then, it may be enabled by setting the CONFIG_SAM_RCFASTxM
* configuration variable.
*/
@ -204,49 +210,191 @@
# if defined(CONFIG_SAM_RCFAST8M) || defined(CONFIG_SAM_RCFAST4M)
# error BOARD_SYSCLK_SOURCE_FCFAST12M inconsistent with CONFIG_SAM_RCFAST8/4M
# endif
# define NEED_RCFAST
# define RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_12MHZ
# define NEED_RCFAST 1
# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_12MHZ
# define SAM_RCFAST_FREQUENCY SAM_RCFAST12M_FREQUENCY
#elif defined(BOARD_SYSCLK_SOURCE_FCFAST8M)
# if defined(CONFIG_SAM_RCFAST12M) || defined(CONFIG_SAM_RCFAST4M)
# error BOARD_SYSCLK_SOURCE_FCFAST8M inconsistent with CONFIG_SAM_RCFAST12/4M
# endif
# define NEED_RCFAST
# define RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_8MHZ
# define NEED_RCFAST 1
# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_8MHZ
# define SAM_RCFAST_FREQUENCY SAM_RCFAST8M_FREQUENCY
#elif defined(BOARD_SYSCLK_SOURCE_FCFAST4M)
# if defined(CONFIG_SAM_RCFAST12M) || defined(CONFIG_SAM_RCFAST8M)
# error BOARD_SYSCLK_SOURCE_FCFAST4M inconsistent with CONFIG_SAM_RCFAST12/8M
# endif
# define NEED_RCFAST
# define RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_4MHZ
# define NEED_RCFAST 1
# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_4MHZ
# define SAM_RCFAST_FREQUENCY SAM_RCFAST4M_FREQUENCY
#elif defined(CONFIG_SAM_RCFAST12M)
# define NEED_RCFAST
# define RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_12MHZ
# define NEED_RCFAST 1
# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_12MHZ
# define SAM_RCFAST_FREQUENCY SAM_RCFAST12M_FREQUENCY
#elif defined(CONFIG_SAM_RCFAST8M)
# define NEED_RCFAST
# define RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_8MHZ
# define NEED_RCFAST 1
# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_8MHZ
# define SAM_RCFAST_FREQUENCY SAM_RCFAST8M_FREQUENCY
#elif defined(CONFIG_SAM_RCFAST4M)
# define NEED_RCFAST
# define RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_4MHZ
# define NEED_RCFAST 1
# define SAM_RCFAST_RANGE SCIF_RCFASTCFG_FRANGE_4MHZ
# define SAM_RCFAST_FREQUENCY SAM_RCFAST4M_FREQUENCY
#endif
/* RC1M. The 1M RC oscillator may be used as the system block.
/* RC1M. The 1M RC oscillator may be used as the system block or
* may be the source clock for GLCK9 that drives PLL0
*
* By selecting CONFIG_SAM_RC1M, you can also force the clock to be
* enabled at boot time.
*/
#if defined(CONFIG_SAM_RC1M) || defined(BOARD_SYSCLK_SOURCE_RC1M)
# define NEED_RC1M 1
#if defined(CONFIG_SAM_RC1M) || defined(BOARD_SYSCLK_SOURCE_RC1M) || \
defined(BOARD_GLCK9_SOURCE_RC1M)
# define NEED_RC1M 1
#endif
/* RC32K. The 32KHz RC oscillator may be used as the input to DFLL0.
/* RC32K. The 32KHz RC oscillator may be used as the input to DFLL0
* or as the input to GCLK9 that drives PLL0.
*
* By selecting CONFIG_SAM_RC32K, you can also force the clock to be
* enabled at boot time.
*/
#if defined(CONFIG_SAM_RC32K) || defined(BOARD_DFLL0_SOURCE_RC32K)
# define NEED_RC32K 1
#if defined(CONFIG_SAM_RC32K) || defined(BOARD_DFLL0_SOURCE_RC32K) || \
defined(BOARD_GLCK9_SOURCE_RC32K)
# define NEED_RC32K 1
#endif
/* GCLK9. May used as a source clock for PLL0 */
#ifdef BOARD_PLL0_SOURCE_GCLK9
# define NEED_GLCK9 1
#ifdef NEED_GLCK9
# if defined(BOARD_GLCK9_SOURCE_RCSYS)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RCSYS
# define SAM_GCLK9_FREQUENCY SAM_RCSYS_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_OSC32K)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_OSC32K
# define SAM_GCLK9_FREQUENCY BOARD_OSC32_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_DFLL0)
# error BOARD_GLCK9_SOURCE_DFLL0 is not supported
# elif defined(BOARD_GLCK9_SOURCE_OSC0)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_OSC0
# define SAM_GCLK9_FREQUENCY BOARD_OSC0_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_RC80M)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RC80M
# define SAM_GCLK9_FREQUENCY SAM_RC80M_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_RCFAST)
# error BOARD_GLCK9_SOURCE_RCFAST is not supported (needs RCFAST configuration)
# elif defined(BOARD_GLCK9_SOURCE_RC1M)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RC1M
# define SAM_GCLK9_FREQUENCY SAM_RCFAST_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_CPUCLK)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_CPUCLK
# define SAM_GCLK9_FREQUENCY BOARD_CPU_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_HSBCLK)
# error BOARD_GLCK9_SOURCE_HSBCLK is not supported (REVISIT)
# elif defined(BOARD_GLCK9_SOURCE_PBACLK)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBACLK
# define SAM_GCLK9_FREQUENCY BOARD_PBA_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_PBBCLK)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBBCLK
# define SAM_GCLK9_FREQUENCY BOARD_PBB_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_PBCCLK)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBCCLK
# define SAM_GCLK9_FREQUENCY BOARD_PBC_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_PBDCLK)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_PBDCLK
# define SAM_GCLK9_FREQUENCY BOARD_PBD_FREQUENCY
# elif defined(BOARD_GLCK9_SOURCE_RC32K)
# define SAM_GCLK9_SOURCE_VALUE SCIF_GCCTRL_OSCSEL_RC32K
# define SAM_GCLK9_FREQUENCY SAM_RC32K_FREQUENCY
# else
# error Missing GCLK9 source
# endif
#endif
/* PLL0 */
#ifdef BOARD_SYSCLK_SOURCE_PLL0
/* PLL0 source */
# if defined(BOARD_PLL0_SOURCE_OSC0)
# define SAM_PLL0_SOURCE SCIF_PLL0_PLLOSC_OSC0
# define SAM_PLL0_SOURCE_FREQUENCY BOARD_OSC0_FREQUENCY
# elif defined(BOARD_PLL0_SOURCE_GCLK9)
# define SAM_PLL0_SOURCE SCIF_PLL0_PLLOSC_GCLK9
# define SAM_PLL0_SOURCE_FREQUENCY SAM_GCLK9_FREQUENCY
# else
# error Missing PLL0 source
# endif
/* PLL0 Multipler and Divider */
# if !defined(BOARD_PLL0_MUL)
# error BOARD_PLL0_MUL is not defined
# elif BOARD_PLL0_MUL <= 2 || BOARD_PLL0_MUL > 16
# error BOARD_PLL0_MUL is out of range
# endif
# if !defined(BOARD_PLL0_DIV)
# error BOARD_PLL0_DIV is not defined
# elif BOARD_PLL0_DIV < 1 || BOARD_PLL0_DIV > 15
# error BOARD_PLL0_DIV is out of range
# endif
/* PLL0 frequency ranges */
# define SAM_PLL0_MIN_FREQUENCY 40000000
# define SAM_PLL0_MAX_FREQUENCY 240000000
/* PLL0 VCO frequency */
# define SAM_PLL0_VCO_DIV1_FREQUENCY \
(SAM_PLL0_SOURCE_FREQUENCY * BOARD_PLL0_MUL / BOARD_PLL0_DIV)
# if (SAM_PLL0_VCO_DIV1_FREQUENCY < SAM_PLL0_MIN_FREQUENCY) || \
(SAM_PLL0_VCO_DIV1_FREQUENCY > SAM_PLL0_MAX_FREQUENCY)
# error PLL0 VCO frequency is out of range
# endif
/* PLL0 Options:
*
* PLL0 supports an option to divide the frequency output by 2. We
* will do this division to bring the internal VCO frequency up to the
* minimum value
*
* PLL0 operates in two frequency ranges as determined by
* SCIF_PLL0_PLLOPT_FVO:
*
* 0: 80MHz < fvco < 180MHz
* 1: 160MHz < fvco < 240MHz
*
* Select the correct frequncy range using the recommended threshold
* value.
*/
# if SAM_PLL0_VCO_DIV1_FREQUENCY < (2*SAM_PLL0_MIN_FREQUENCY) && BOARD_PLL0_MUL <= 8
# define SAM_PLL0_VCO_FREQUENCY (2 * SAM_PLL0_VCO_DIV1_FREQUENCY)
# define SAM_PLL0_MUL (2 * BOARD_PLL0_MUL)
# if SAM_PLL0_VCO_FREQUENCY > (SAM_PLL0_VCO_RANGE_THRESHOLD / 2)
# define SAM_PLL0_OPTIONS (SCIF_PLL0_PLLOPT_DIV2 | SCIF_PLL0_PLLOPT_FVO)
# else
# define SAM_PLL0_OPTIONS SCIF_PLL0_PLLOPT_DIV2
# endif
# else
# define SAM_PLL0_VCO_FREQUENCY SAM_PLL0_VCO_DIV1_FREQUENCY
# define SAM_PLL0_MUL BOARD_PLL0_MUL
# if SAM_PLL0_VCO_FREQUENCY > SAM_PLL0_VCO_RANGE_THRESHOLD
# define SAM_PLL0_OPTIONS SCIF_PLL0_PLLOPT_FVO
# else
# define SAM_PLL0_OPTIONS 0
# endif
# endif
#endif
/****************************************************************************
@ -305,19 +453,15 @@ static inline void sam_picocache(void)
#ifdef NEED_OSC0
static inline void sam_enableosc0(void)
{
irqstate_t flags;
uint32_t regval;
regval = OSC0_STARTUP_VALUE | OSC0_GAIN_VALUE | OSC0_MODE_VALUE |
/* Enable and configure OSC0 */
regval = SAM_OSC0_STARTUP_VALUE | SAM_OSC0_GAIN_VALUE | SAM_OSC0_MODE_VALUE |
SCIF_OSCCTRL0_OSCEN;
/* The following two statements must be atomic */
flags = irqsave();
putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_OSCCTRL0_OFFSET),
SAM_SCIF_UNLOCK);
putreg32(regval, SAM_SCIF_OSCCTRL0);
irqrestore(flags);
/* Wait for OSC0 to be ready */
@ -337,24 +481,19 @@ static inline void sam_enableosc0(void)
#ifdef NEED_OSC32K
static inline void sam_enableosc32(void)
{
irqstate_t flags;
uint32_t regval;
/* Set up the OSCCTRL32 register using settings from the board.h file.
* Also enable the oscillator and provide bother the 32KHz and 1KHz output.
*/
regval = OSC32_STARTUP_VALUE | BOARD_OSC32_SELCURR | OSC32_MODE_VALUE |
regval = SAM_OSC32_STARTUP_VALUE | BOARD_OSC32_SELCURR | SAM_OSC32_MODE_VALUE |
BSCIF_OSCCTRL32_EN1K | BSCIF_OSCCTRL32_EN32K |
BSCIF_OSCCTRL32_OSC32EN;
/* The following two statements must be atomic */
flags = irqsave();
putreg32(BSCIF_UNLOCK_KEY(0xaa) | BSCIF_UNLOCK_ADDR(SAM_BSCIF_OSCCTRL32_OFFSET),
SAM_BSCIF_UNLOCK);
putreg32(regval, SAM_BSCIF_OSCCTRL32);
irqrestore(flags);
/* Wait for OSC32 to be ready */
@ -374,17 +513,14 @@ static inline void sam_enableosc32(void)
#ifdef NEED_RC80M
static inline void sam_enablerc80m(void)
{
irqstate_t flags;
uint32_t regval;
/* The following two statements must be atomic */
/* Configure and enable RC80M */
flags = irqsave();
regval = getreg32(SAM_SCIF_RC80MCR);
putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_RC80MCR_OFFSET),
SAM_SCIF_UNLOCK);
putreg32(regval | SCIF_RC80MCR_EN, SAM_SCIF_RC80MCR);
irqrestore(flags);
/* Wait for OSC32 to be ready */
@ -404,20 +540,17 @@ static inline void sam_enablerc80m(void)
#ifdef NEED_RCFAST
static inline void sam_enablercfast(void)
{
irqstate_t flags;
uint32_t regval;
/* The following must be atomic */
/* Configure and enable RCFAST */
flags = irqsave();
regval = getreg32(SAM_SCIF_RCFASTCFG);
regval &= ~SCIF_RCFASTCFG_FRANGE_MASK;
regval |= (RCFAST_RANGE | SCIF_RCFASTCFG_EN);
regval |= (SAM_RCFAST_RANGE | SCIF_RCFASTCFG_EN);
putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(SAM_SCIF_RCFASTCFG_OFFSET),
SAM_SCIF_UNLOCK);
putreg32(regval, SAM_SCIF_RCFASTCFG);
irqrestore(flags);
/* Wait for RCFAST to be ready */
@ -437,20 +570,17 @@ static inline void sam_enablercfast(void)
#ifdef NEED_RC1M
static inline void sam_enablerc1m(void)
{
irqstate_t flags;
uint32_t regval;
/* The following must be atomic */
/* Configure and enable RC1M */
flags = irqsave();
regval = getreg32(SAM_BSCIF_RC1MCR);
regval &= ~BSCIF_RCFASTCFG_FRANGE_MASK;
regval |= (RCFAST_RANGE | BSCIF_RCFASTCFG_EN);
regval |= (SAM_RCFAST_RANGE | BSCIF_RCFASTCFG_EN);
putreg32(BSCIF_UNLOCK_KEY(0xaa) | BSCIF_UNLOCK_ADDR(SAM_BSCIF_RC1MCR_OFFSET),
SAM_BSCIF_UNLOCK);
putreg32(regval | BSCIF_RC1MCR_CLKOEN, SAM_BSCIF_RC1MCR);
irqrestore(flags);
/* Wait for RCFAST to be ready */
@ -468,19 +598,16 @@ static inline void sam_enablerc1m(void)
****************************************************************************/
#ifdef NEED_RC32K
void sam_enablerc32k(void)
static inline void sam_enablerc32k(void)
{
irqstate_t flags;
uint32_t regval;
/* The following must be atomic */
/* Configure and enable RC32K */
flags = irqsave();
regval = getreg32(SAM_BSCIF_RC32KCR);
putreg32(BSCIF_UNLOCK_KEY(0xaa) | BSCIF_UNLOCK_ADDR(SAM_BSCIF_RC32KCR_OFFSET),
SAM_BSCIF_UNLOCK);
putreg32(regval | BSCIF_RC32KCR_EN32K | BSCIF_RC32KCR_EN, SAM_BSCIF_RC32KCR);
irqrestore(flags);
/* Wait for RCFAST to be ready */
@ -488,6 +615,26 @@ void sam_enablerc32k(void)
}
#endif
/****************************************************************************
* Name: sam_enableglck9
*
* Description:
* Enable GLCK9.
*
****************************************************************************/
#ifdef NEED_GLCK9
static inline void sam_enableglck9(void)
{
/* Enable the generic clock using the source specified in the board.h
* file. No division is used so that the GCLK9 frequency is the same
* as the source frequency.
*/
putreg32(SAM_GCLK9_SOURCE_VALUE | SCIF_GCCTRL_CEN, SAM_SCIF_GCCTRL9);
}
#endif
/****************************************************************************
* Name: sam_enablepll0
*
@ -497,94 +644,47 @@ void sam_enablerc32k(void)
****************************************************************************/
#ifdef SAM_CLOCK_PLL0
static inline void sam_pll0putreg(uint32_t regval, uint32_t regaddr,
uint32_t regoffset)
{
putreg32(SCIF_UNLOCK_KEY(0xaa) | SCIF_UNLOCK_ADDR(regoffset),
SAM_SCIF_UNLOCK);
putreg32(regval, regaddr);
}
static inline void sam_enablepll0(void)
{
/* Setup PLL0 */
uint32_t regval;
regval = (SAM_PLL0_DIV << PM_PLL_PLLDIV_SHIFT) | (SAM_PLL0_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
/* Clear the PLL0 control register */
/* Select PLL0/1 oscillator */
sam_pll0putreg(0, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET);
#if SAM_CLOCK_PLL_OSC1
regval |= PM_PLL_PLLOSC;
#endif
/* Write the selected options */
putreg32(regval, SAM_PM_PLL0);
regval = getreg32(SAM_SCIF_PLL0);
regval &= SCIF_PLL0_PLLOPT_MASK;
regval |= SAM_PLL0_OPTIONS;
sam_pll0putreg(regval, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET);
/* Set PLL0 options */
/* Set up the multiers and dividers */
regval = getreg32(SAM_PM_PLL0);
regval &= ~PM_PLL_PLLOPT_MASK
#if SAM_PLL0_FREQ < 160000000
regval |= PM_PLL_PLLOPT_VCO;
#endif
#if SAM_PLL0_DIV2 != 0
regval |= PM_PLL_PLLOPT_XTRADIV;
#endif
#if SAM_PLL0_WBWM != 0
regval |= PM_PLL_PLLOPT_WBWDIS;
#endif
putreg32(regval, SAM_PM_PLL0)
regval = getreg32(SAM_SCIF_PLL0);
regval &= ~(SCIF_PLL0_PLLOSC_MASK | SCIF_PLL0_PLLDIV_MASK | SCIF_PLL0_PLLMUL_MASK);
regval |= ((SAM_PLL0_MUL - 1) << SCIF_PLL0_PLLMUL_SHIFT) |
(BOARD_FDLL0_DIV << SCIF_PLL0_PLLDIV_SHIFT) |
SCIF_PLL0_PLLCOUNT_MAX | SAM_PLL0_SOURCE;
sam_pll0putreg(regval, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET);
/* Enable PLL0 */
/* And, finally, enable PLL0 */
regval = getreg32(SAM_PM_PLL0);
regval |= PM_PLL_PLLEN;
putreg32(regval, SAM_PM_PLL0)
regval = getreg32(SAM_SCIF_PLL0);
regval |= SCIF_PLL_PLLEN;
sam_pll0putreg(regval, SAM_SCIF_PLL0, SAM_SCIF_PLL0_OFFSET);
/* Wait for PLL0 locked. */
/* Wait for PLL0 to become locked */
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_LOCK0) == 0);
}
#endif
/****************************************************************************
* Name: sam_enablepll1
*
* Description:
* Initialiaze PLL1 settings per the definitions in the board.h file.
*
****************************************************************************/
#ifdef SAM_CLOCK_PLL1
static inline void sam_enablepll1(void)
{
/* Setup PLL1 */
regval = (SAM_PLL1_DIV << PM_PLL_PLLDIV_SHIFT) | (SAM_PLL1_MUL << PM_PLL_PLLMUL_SHIFT) | (16 << PM_PLL_PLLCOUNT_SHIFT)
/* Select PLL0/1 oscillator */
#if SAM_CLOCK_PLL_OSC1
regval |= PM_PLL_PLLOSC;
#endif
putreg32(regval, SAM_PM_PLL1);
/* Set PLL1 options */
regval = getreg32(SAM_PM_PLL1);
regval &= ~PM_PLL_PLLOPT_MASK
#if SAM_PLL1_FREQ < 160000000
regval |= PM_PLL_PLLOPT_VCO;
#endif
#if SAM_PLL1_DIV2 != 0
regval |= PM_PLL_PLLOPT_XTRADIV;
#endif
#if SAM_PLL1_WBWM != 0
regval |= PM_PLL_PLLOPT_WBWDIS;
#endif
putreg32(regval, SAM_PM_PLL1)
/* Enable PLL1 */
regval = getreg32(SAM_PM_PLL1);
regval |= PM_PLL_PLLEN;
putreg32(regval, SAM_PM_PLL1)
/* Wait for PLL1 locked. */
while ((getreg32(SAM_PM_POSCSR) & PM_POSCSR_LOCK1) == 0);
while ((getreg32(SAM_SCIF_PCLKSR) & SCIF_INT_PLL0LOCK) == 0);
}
#endif
@ -596,49 +696,47 @@ static inline void sam_enablepll1(void)
*
****************************************************************************/
static inline void sam_setdividers(uint32_t cpudiv, uint32_t pbadiv,
uint32_t pbbdiv, uint32_t pbcdiv,
uint32_t pbddiv)
static inline void sam_setdividers(void)
{
irqstate_t flags;
uint32_t cpusel = 0;
uint32_t pbasel = 0;
uint32_t pbbsel = 0;
uint32_t pbcsel = 0;
uint32_t pbdsel = 0;
uint32_t cpusel;
uint32_t pbasel;
uint32_t pbbsel;
uint32_t pbcsel;
uint32_t pbdsel;
/* Get the register setting for each divider value */
if (cpudiv > 0)
{
cpusel = (PM_CPUSEL(cpudiv - 1)) | PM_CPUSEL_DIV;
}
#if BOARD_CPU_SHIFT > 0
cpusel = (PM_CPUSEL(BOARD_CPU_SHIFT - 1)) | PM_CPUSEL_DIV;
#else
cpusel = 0;
#endif
if (pbadiv > 0)
{
pbasel = (PM_PBSEL(pbadiv - 1)) | PM_PBSEL_DIV;
}
#if BOARD_PBA_SHIFT > 0
pbasel = (PM_PBSEL(BOARD_PBA_SHIFT - 1)) | PM_PBSEL_DIV;
#else
pbasel = 0;
#endif
if (pbbdiv > 0)
{
pbbsel = (PM_PBSEL(pbbdiv - 1)) | PM_PBSEL_DIV;
}
#if BOARD_PBB_SHIFT >0
pbbsel = (PM_PBSEL(BOARD_PBB_SHIFT - 1)) | PM_PBSEL_DIV;
#else
pbbsel = 0;
#endif
if (pbcdiv > 0)
{
pbcsel = (PM_PBSEL(pbcdiv - 1)) | PM_PBSEL_DIV;
}
#if BOARD_PBC_SHIFT > 0
pbcsel = (PM_PBSEL(BOARD_PBC_SHIFT - 1)) | PM_PBSEL_DIV;
#else
pbcsel = 0;
#endif
if (pbddiv > 0)
{
pbdsel = (PM_PBSEL(pbddiv - 1)) | PM_PBSEL_DIV;
}
#if BOARD_PBD_SHIFT > 0
pbdsel = (PM_PBSEL(BOARD_PBD_SHIFT - 1)) | PM_PBSEL_DIV;
#else
pbdsel = 0;
#endif
/* Then set the divider values. The following operations need to be atomic
* for the unlock-write sequeuences.
*/
flags = irqsave();
/* Then set the divider values. */
putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_CPUSEL_OFFSET), SAM_PM_UNLOCK);
putreg32(cpusel, SAM_PM_CPUSEL);
@ -654,8 +752,6 @@ static inline void sam_setdividers(uint32_t cpudiv, uint32_t pbadiv,
putreg32(PM_UNLOCK_KEY(0xaa) | PM_UNLOCK_ADDR(SAM_PM_PBDSEL_OFFSET), SAM_PM_UNLOCK);
putreg32(pbdsel, SAM_PM_PBDSEL);
irqrestore(flags);
}
/****************************************************************************
@ -764,9 +860,7 @@ void sam_clockconfig(void)
* be provided in the board.h header file.
*/
sam_setdividers(BOARD_CPU_SHIFT, BOARD_PBA_SHIFT, BOARD_PBB_SHIFT,
BOARD_PBC_SHIFT, BOARD_PBD_SHIFT);
sam_setdividers();
/* Select a power scaling mode and possible fast wakeup so that we get the
* best possible flash performance. The following table shows the maximum
@ -864,8 +958,11 @@ void sam_clockconfig(void)
sam_enablerc32k();
#endif
/* Enable the PLL or FDLL */
#warning Missing Logic
#ifdef NEED_GLCK9
/* Enable the GLCK9 */
sam_enableglck9();
#endif
/* Switch to the system clock selected by the settings in the board.h
* header file.
@ -875,9 +972,8 @@ void sam_clockconfig(void)
/* Since this function only executes at power up, we know that we are
* already running from RCSYS.
*/
#endif
#elif defined(BOARD_SYSCLK_SOURCE_OSC0)
#ifdef NEED_OSC0
/* Set up FLASH wait states */
sam_fws(SAM_FOSC0);
@ -885,9 +981,9 @@ void sam_clockconfig(void)
/* Then switch the main clock to OSC0 */
sam_mainclk(PM_MCCTRL_MCSEL_OSC0);
#endif
#ifdef SAM_CLOCK_PLL0
#elif defined(BOARD_SYSCLK_SOURCE_PLL0)
/* Enable PLL0 using the settings in board.h */
sam_enablepll0();
@ -899,16 +995,20 @@ void sam_clockconfig(void)
/* Then switch the main clock to PLL0 */
sam_mainclk(PM_MCCTRL_MCSEL_PLL0);
#elif defined(BOARD_SYSCLK_SOURCE_DFLL0)
# error Missing logic
#elif defined(BOARD_SYSCLK_SOURCE_RC80M)
# error Missing logic
#elif defined(BOARD_SYSCLK_SOURCE_FCFAST12M) || defined(BOARD_SYSCLK_SOURCE_FCFAST8M) || \
defined(BOARD_SYSCLK_SOURCE_FCFAST4M)
# error Missing logic
#elif defined(BOARD_SYSCLK_SOURCE_RC1M)
# error Missing logic
#else
# error "No SYSCLK source frequency"
#endif
#ifdef SAM_CLOCK_PLL1
/* Enable PLL1 using the settings in board.h */
sam_enablepll1();
#endif
/* Set up the USBB GCLK */
#ifdef CONFIG_USBDEV
void sam_usbclock();
#endif

View File

@ -98,6 +98,8 @@
* BOARD_DFLL0_SOURCE_OSC0 - Oscillator 0
* BOARD_DFLL0_SOURCE_RC80M - 80 MHz RC oscillator
* BOARD_DFLL0_SOURCE_RC32K - 32 kHz RC oscillator
*
* NOTE: Nothing must be defined if the DFPLL is not used
*/
#define BOARD_DFLL0_SOURCE_OSC32K 1
@ -105,6 +107,31 @@
#define BOARD_FDLL0_MUL (BOARD_FDLL0_FREQUENCY / BOARD_OSC32_FREQUENCY)
#define BOARD_FDLL0_DIV 1
/* Phase Locked Loop configuration
* Fdfll = (Fclk * PLLmul) / PLLdiv
*
* PLL0 source options (select one):
* BOARD_PLL0_SOURCE_OSC0 - Oscillator 0
* BOARD_PLL0_SOURCE_GCLK9 - General clock 9
*
* BOARD_GLCK9_SOURCE_RCSYS - System RC oscillator
* BOARD_GLCK9_SOURCE_OSC32K - Output from OSC32K
* BOARD_GLCK9_SOURCE_DFLL0 - Output from DFLL0
* BOARD_GLCK9_SOURCE_OSC0 - Output from Oscillator0
* BOARD_GLCK9_SOURCE_RC80M - Output from 80MHz RCOSC
* BOARD_GLCK9_SOURCE_RCFAST - Output from 4,8,12MHz RCFAST
* BOARD_GLCK9_SOURCE_RC1M - Output from 1MHz RC1M
* BOARD_GLCK9_SOURCE_CPUCLK - The CPU clock
* BOARD_GLCK9_SOURCE_HSBCLK - High Speed Bus clock
* BOARD_GLCK9_SOURCE_PBACLK - Peripheral Bus A clock
* BOARD_GLCK9_SOURCE_PBBCLK - Peripheral Bus B clock
* BOARD_GLCK9_SOURCE_PBCCLK - Peripheral Bus C clock
* BOARD_GLCK9_SOURCE_PBDCLK - Peripheral Bus D clock
* BOARD_GLCK9_SOURCE_RC32K - Output from 32kHz RCOSC
*
* NOTE: Nothing must be defined if the PLL0 is not used
*/
/* System clock dividers: Fbus = Fsys >> BUSshift */
#define BOARD_CPU_SHIFT 0 /* Fcpu = Fsys = 48MHz */