diff --git a/ChangeLog b/ChangeLog index 9cc421afda5..fbdc5ab65cc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7068,4 +7068,8 @@ * arch/arm/src/sama5/sam_pmc.c and .h: Add functions to calculate PLLACK, PCK, and MCK frequencies given the main clock frequency (2014-3-29). - + * configs/sama5d*/include/board.h, board_sdram.h, and other files: + When booting from SDRAM, we need to query the PMC registers (using + the functions in sam_pmc.c) to determine the MCK, PCK, etc. We assume + that the MCK input clock is well known main crystal oscillator + frequency (2014-3-29). diff --git a/arch/arm/src/sama5/sam_clockconfig.c b/arch/arm/src/sama5/sam_clockconfig.c index fd116216429..6922d69150a 100644 --- a/arch/arm/src/sama5/sam_clockconfig.c +++ b/arch/arm/src/sama5/sam_clockconfig.c @@ -56,6 +56,11 @@ * Pre-processor Definitions ****************************************************************************/ +#undef NEED_PLLSETUP +#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) +# define NEED_PLLSETUP 1 +#endif + /**************************************************************************** * Private Types ****************************************************************************/ @@ -80,6 +85,7 @@ * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static void sam_pmcwait(uint32_t bit) { /* There is no timeout on this wait. Why not? Because the symptoms there @@ -90,15 +96,17 @@ static void sam_pmcwait(uint32_t bit) while ((getreg32(SAM_PMC_SR) & bit) == 0); } +#endif /**************************************************************************** * Name: sam_enablemosc * * Description: - * Enable the main osciallator + * Enable the main oscillator * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_enablemosc(void) { uint32_t regval; @@ -141,6 +149,7 @@ static inline void sam_enablemosc(void) sam_pmcwait(PMC_INT_MCKRDY); } } +#endif /**************************************************************************** * Name: sam_selectmosc @@ -152,6 +161,7 @@ static inline void sam_enablemosc(void) * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_selectmosc(void) { uint32_t regval; @@ -167,6 +177,7 @@ static inline void sam_selectmosc(void) sam_pmcwait(PMC_INT_MCKRDY); } +#endif /**************************************************************************** * Name: sam_pllasetup @@ -178,6 +189,7 @@ static inline void sam_selectmosc(void) * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_pllasetup(void) { uint32_t regval; @@ -197,6 +209,7 @@ static inline void sam_pllasetup(void) sam_pmcwait(PMC_INT_LOCKA); } +#endif /**************************************************************************** * Name: sam_plladivider @@ -206,6 +219,7 @@ static inline void sam_pllasetup(void) * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_plladivider(void) { uint32_t regval; @@ -246,6 +260,7 @@ static inline void sam_plladivider(void) sam_pmcwait(PMC_INT_MCKRDY); } +#endif /**************************************************************************** * Name: sam_mckprescaler @@ -255,6 +270,7 @@ static inline void sam_plladivider(void) * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_mckprescaler(void) { uint32_t regval; @@ -270,6 +286,7 @@ static inline void sam_mckprescaler(void) sam_pmcwait(PMC_INT_MCKRDY); } +#endif /**************************************************************************** * Name: sam_mckdivider @@ -280,6 +297,7 @@ static inline void sam_mckprescaler(void) * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_mckdivider(void) { uint32_t regval; @@ -295,6 +313,7 @@ static inline void sam_mckdivider(void) sam_pmcwait(PMC_INT_MCKRDY); } +#endif /**************************************************************************** * Name: sam_selectplla @@ -304,6 +323,7 @@ static inline void sam_mckdivider(void) * ****************************************************************************/ +#if defined(NEED_PLLSETUP) static inline void sam_selectplla(void) { uint32_t regval; @@ -319,6 +339,7 @@ static inline void sam_selectplla(void) sam_pmcwait(PMC_INT_MCKRDY); } +#endif /**************************************************************************** * Name: sam_usbclockconfig @@ -569,8 +590,8 @@ void sam_clockconfig(void) #ifdef CONFIG_SAMA5_BOOT_CS0FLASH if (config) #endif /* CONFIG_SAMA5_BOOT_CS0FLASH */ -#if defined(CONFIG_SAMA5_BOOT_ISRAM) || defined(CONFIG_SAMA5_BOOT_CS0FLASH) { +#if defined(NEED_PLLSETUP) /* Enable main oscillator (if it has not already been selected) */ sam_enablemosc(); @@ -601,10 +622,10 @@ void sam_clockconfig(void) /* Finally, elect the PLLA output as the input clock for PCK and MCK. */ sam_selectplla(); +#endif /* NEED_PLLSETUP */ /* Setup USB clocking */ sam_usbclockconfig(); } -#endif /* CONFIG_SAMA5_BOOT_ISRAM || CONFIG_SAMA5_BOOT_CS0FLASH */ } diff --git a/arch/arm/src/sama5/sam_pmc.c b/arch/arm/src/sama5/sam_pmc.c index a887126bd43..1fe3767224f 100755 --- a/arch/arm/src/sama5/sam_pmc.c +++ b/arch/arm/src/sama5/sam_pmc.c @@ -1,238 +1,339 @@ -/**************************************************************************** - * arch/arm/src/sama5/sam_pmc.c - * - * Copyright (C) 2014 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt - * - * References: - * - * SAMA5D3 Series Data Sheet - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name NuttX nor the names of its contributors may - * be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED - * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - ****************************************************************************/ - -/**************************************************************************** - * Included Files - ****************************************************************************/ - -#include - -#include - -#include - -#include "up_arch.h" - -#include "chip.h" -#include "chip/sam_pmc.h" -#include "sam_pmc.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -/**************************************************************************** - * Private Data - ****************************************************************************/ - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -/**************************************************************************** - * Name: sam_pllack_frequency - * - * Description: - * Given the Main Clock frequency that provides the input to PLLA, return - * the frequency of the PPA output clock, PLLACK - * - * Assumptions: - * PLLA is enabled. If the PLL is is disabled, either at the input divider - * or the output multiplier, the value zero is returned. - * - ****************************************************************************/ - -uint32_t sam_pllack_frequency(uint32_t mainclk) -{ - uint32_t regval; - uint32_t diva; - uint32_t mula; - uint32_t pllack; - - /* Get the PLLA divider (DIVA) and multiplier (MULA) */ - - regval = getreg32(SAM_PMC_CKGR_PLLAR); - - /* DIVA = 0: Divider output is 0 - * DIVA = 1: Divider is bypassed - * DIVA = 2-255: Divider output is the selected clock divided by DIVA - */ - - diva = (regval & PMC_CKGR_PLLAR_DIV_MASK) >> PMC_CKGR_PLLAR_DIV_SHIFT; - - pllack = mainclk; - if (diva > 1) - { - pllack /= diva; - } - else if (diva < 1) - { - return 0; - } - - /* MULA = 0: PLLA is deactivated - * MULA > 0: The PLLA Clock frequency is the PLLA input frequency - * multiplied by MULA + 1. - */ - - mula = (regval & PMC_CKGR_PLLAR_MUL_MASK) >> PMC_CKGR_PLLAR_MUL_SHIFT; - if (mula > 1) - { - pllack *= (mula + 1); - } - else if (diva < 1) - { - return 0; - } - - return pllack; -} - -/**************************************************************************** - * Name: sam_pck_frequency - * - * Description: - * Given the Main Clock frequency that provides the input to PLLA, return - * the frequency of the processor clock (PCK). - * - * Assumptions: - * PLLA is enabled and the either the main clock or the PLLA output clock - * (PLLACK) provides the input to the MCK prescaler. - * - ****************************************************************************/ - -uint32_t sam_pck_frequency(uint32_t mainclk) -{ - uint32_t regval; - uint32_t pres; - uint32_t pck; - - /* Get the input source selection to the master/processor clock divider */ - - regval = getreg32(SAM_PMC_MCKR); - switch (regval & PMC_MCKR_CSS_MASK) - { - case PMC_MCKR_CSS_MAIN: /* Main Clock */ - /* Use the Main Clock frequency */ - - pck = mainclk; - break; - - case PMC_MCKR_CSS_PLLA: /* PLLA Clock */ - /* Use the PLLA output clock */ - - pck = sam_pllack_frequency(mainclk); - if (pck == 0) - { - return 0; - } - - /* Check if the PLLACK output is divided by 2 */ - - if ((regval & PMC_MCKR_PLLADIV2) != 0) - { - pck >>= 1; - } - break; - - case PMC_MCKR_CSS_SLOW: /* Slow Clock */ - case PMC_MCKR_CSS_UPLL: /* UPLL Clock */ - default: - return 0; - } - - /* Get the PCK frequency which is given by the selected input clock - * divided by a power-of-two prescaler. - * - * PRES = 0: Selected clock - * PRES = n > 0: Selected clock divided by 2**n - */ - - pres = (regval & PMC_MCKR_PRES_MASK) >> PMC_MCKR_PRES_SHIFT; - return pck >> pres; -} - -/**************************************************************************** - * Name: sam_mck_frequency - * - * Description: - * Given the Main Clock frequency that provides the input to PLLA, return - * the frequency of the PPA output clock, PLLACK - * - * Assumptions: - * PLLA is enabled and the either the main clock or the PLLA output clock - * (PLLACK) provides the input to the MCK prescaler. - * - ****************************************************************************/ - -uint32_t sam_mck_frequency(uint32_t mainclk) -{ - uint32_t regval; - uint32_t mdiv; - uint32_t mck; - - /* The MCK frequency is equivalent to the PCK clock frequency with an - * additional divider. - */ - - mck = sam_pck_frequency(mainclk); - if (mck == 0) - { - return 0; - } - - /* MDIV = n: Master Clock is Prescaler Output Clock divided by (n + 1) */ - - regval = getreg32(SAM_PMC_MCKR); - mdiv = (regval & PMC_MCKR_MDIV_MASK) >> PMC_MCKR_MDIV_SHIFT; - if (mdiv > 0) - { - mck /= (mdiv + 1); - } - - return mck; -} +/**************************************************************************** + * arch/arm/src/sama5/sam_pmc.c + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * References: + * + * SAMA5D3 Series Data Sheet + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include + +#include "up_arch.h" + +#include "chip.h" + +#ifdef CONFIG_ARCH_HAVE_SDIO +# include "chip/sam_hsmci.h" +#endif + +#include "chip/sam_pmc.h" +#include "sam_pmc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: sam_pllack_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the PPA output clock, PLLACK + * + * Assumptions: + * PLLA is enabled. If the PLL is is disabled, either at the input divider + * or the output multiplier, the value zero is returned. + * + ****************************************************************************/ + +uint32_t sam_pllack_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t diva; + uint32_t mula; + uint32_t pllack; + + /* Get the PLLA divider (DIVA) and multiplier (MULA) */ + + regval = getreg32(SAM_PMC_CKGR_PLLAR); + + /* DIVA = 0: Divider output is 0 + * DIVA = 1: Divider is bypassed + * DIVA = 2-255: Divider output is the selected clock divided by DIVA + */ + + diva = (regval & PMC_CKGR_PLLAR_DIV_MASK) >> PMC_CKGR_PLLAR_DIV_SHIFT; + + pllack = mainclk; + if (diva > 1) + { + pllack /= diva; + } + else if (diva < 1) + { + return 0; + } + + /* MULA = 0: PLLA is deactivated + * MULA > 0: The PLLA Clock frequency is the PLLA input frequency + * multiplied by MULA + 1. + */ + + mula = (regval & PMC_CKGR_PLLAR_MUL_MASK) >> PMC_CKGR_PLLAR_MUL_SHIFT; + if (mula > 0) + { + pllack *= (mula + 1); + } + else + { + return 0; + } + + return pllack; +} + +/**************************************************************************** + * Name: sam_plladiv2_frequency + * + * Description: + * The PLLACK input to most clocking may or may not be divided by two. + * This function will return the possibly divided PLLACK clock input + * frequency. + * + * Assumptions: + * See sam_pllack_frequency. + * + ****************************************************************************/ + +uint32_t sam_plladiv2_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t pllack; + + /* Get the PLLA output clock */ + + pllack = sam_pllack_frequency(mainclk); + if (pllack == 0) + { + return 0; + } + + /* Check if the PLLACK output is divided by 2 */ + + regval = getreg32(SAM_PMC_MCKR); + if ((regval & PMC_MCKR_PLLADIV2) != 0) + { + pllack >>= 1; + } + + return pllack; +} + +/**************************************************************************** + * Name: sam_pck_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the processor clock (PCK). + * + * Assumptions: + * PLLA is enabled and the either the main clock or the PLLA output clock + * (PLLACK) provides the input to the MCK prescaler. + * + ****************************************************************************/ + +uint32_t sam_pck_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t pres; + uint32_t pck; + + /* Get the input source selection to the master/processor clock divider */ + + regval = getreg32(SAM_PMC_MCKR); + switch (regval & PMC_MCKR_CSS_MASK) + { + case PMC_MCKR_CSS_MAIN: /* Main Clock */ + /* Use the Main Clock frequency */ + + pck = mainclk; + break; + + case PMC_MCKR_CSS_PLLA: /* PLLA Clock */ + /* Use the PLLA output clock */ + + pck = sam_plladiv2_frequency(mainclk); + if (pck == 0) + { + return 0; + } + break; + + case PMC_MCKR_CSS_SLOW: /* Slow Clock */ + case PMC_MCKR_CSS_UPLL: /* UPLL Clock */ + default: + return 0; + } + + /* Get the PCK frequency which is given by the selected input clock + * divided by a power-of-two prescaler. + * + * PRES = 0: Selected clock + * PRES = n > 0: Selected clock divided by 2**n + */ + + pres = (regval & PMC_MCKR_PRES_MASK) >> PMC_MCKR_PRES_SHIFT; + return pck >> pres; +} + +/**************************************************************************** + * Name: sam_mck_frequency + * + * Description: + * Given the Main Clock frequency that provides the input to PLLA, return + * the frequency of the PPA output clock, PLLACK + * + * Assumptions: + * PLLA is enabled and the either the main clock or the PLLA output clock + * (PLLACK) provides the input to the MCK prescaler. + * + ****************************************************************************/ + +uint32_t sam_mck_frequency(uint32_t mainclk) +{ + uint32_t regval; + uint32_t mdiv; + uint32_t mck; + + /* The MCK frequency is equivalent to the PCK clock frequency with an + * additional divider. + */ + + mck = sam_pck_frequency(mainclk); + if (mck == 0) + { + return 0; + } + + /* MDIV = n: Master Clock is Prescaler Output Clock divided by encoded value */ + + regval = getreg32(SAM_PMC_MCKR); + switch (regval & PMC_MCKR_MDIV_MASK) + { + case PMC_MCKR_MDIV_PCKDIV1: + return mck; + + case PMC_MCKR_MDIV_PCKDIV2: + mdiv = 2; + break; + + case PMC_MCKR_MDIV_PCKDIV3: + mdiv = 3; + break; + + case PMC_MCKR_MDIV_PCKDIV4: + mdiv = 4; + break; + + default: + return 0; + } + + return mck / mdiv; +} + +/************************************************************************************ + * Name: sam_hsmci_clkdiv + * + * Description: + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + * + * TODO: This belongs elsewhere + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_SDIO +uint32_t sam_hsmci_clkdiv(uint32_t target) +{ + uint32_t clkfulldiv; + uint32_t ret; + + clkfulldiv = BOARD_MCK_FREQUENCY / target; + if (clkfulldiv > 2) + { + clkfulldiv -= 2; + } + else + { + clkfulldiv = 0; + } + + if (clkfulldiv > 511) + { + clkfulldiv = 511; + } + + ret = (clkfulldiv >> 1) << HSMCI_MR_CLKDIV_SHIFT; + if ((clkfulldiv & 1) != 0) + { + ret |= HSMCI_MR_CLKODD; + } + + return ret; +} +#endif diff --git a/arch/arm/src/sama5/sam_pmc.h b/arch/arm/src/sama5/sam_pmc.h index 904f70fb146..a562db754b0 100644 --- a/arch/arm/src/sama5/sam_pmc.h +++ b/arch/arm/src/sama5/sam_pmc.h @@ -65,7 +65,7 @@ extern "C" * Name: sam_pllack_frequency * * Description: - * Given the Main Clock frequency that provides the input to PLLA, return + * Given the Main Clock frequency that provides the input to PLLA, return * the frequency of the PPA output clock, PLLACK * * Assumptions: @@ -76,11 +76,26 @@ extern "C" uint32_t sam_pllack_frequency(uint32_t mainclk); +/**************************************************************************** + * Name: sam_plladiv2_frequency + * + * Description: + * The PLLACK input to most clocking may or may not be divided by two. + * This function will return the possibly divided PLLACK clock input + * frequency. + * + * Assumptions: + * See sam_pllack_frequency. + * + ****************************************************************************/ + +uint32_t sam_plladiv2_frequency(uint32_t mainclk); + /**************************************************************************** * Name: sam_pck_frequency * * Description: - * Given the Main Clock frequency that provides the input to PLLA, return + * Given the Main Clock frequency that provides the input to PLLA, return * the frequency of the processor clock (PCK). * * Assumptions: @@ -95,7 +110,7 @@ uint32_t sam_pck_frequency(uint32_t mainclk); * Name: sam_mck_frequency * * Description: - * Given the Main Clock frequency that provides the input to PLLA, return + * Given the Main Clock frequency that provides the input to PLLA, return * the frequency of the PPA output clock, PLLACK * * Assumptions: @@ -106,6 +121,30 @@ uint32_t sam_pck_frequency(uint32_t mainclk); uint32_t sam_mck_frequency(uint32_t mainclk); +/************************************************************************************ + * Name: sam_hsmci_clkdiv + * + * Description: + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + * + * TODO: This belongs elsewhere + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_HAVE_SDIO +uint32_t sam_hsmci_clkdiv(uint32_t target); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/sama5/sam_timerisr.c b/arch/arm/src/sama5/sam_timerisr.c index c048713216a..70da7b7bcec 100644 --- a/arch/arm/src/sama5/sam_timerisr.c +++ b/arch/arm/src/sama5/sam_timerisr.c @@ -70,14 +70,6 @@ #define PIT_PIV ((PIT_CLOCK + (CLK_TCK >> 1)) / CLK_TCK) -/* The size of the reload field is 20 bits. Verify that the reload value - * will fit in the reload register. - */ - -#if PIT_PIV > PIT_MR_PIV_MASK -# error PIT_PIV exceeds the maximum value -#endif - /**************************************************************************** * Private Types ****************************************************************************/ @@ -149,7 +141,10 @@ void up_timerinit(void) * interrupts from the PIT. */ - regval = PIT_PIV | PIT_MR_PITEN | PIT_MR_PITIEN; + regval = PIT_PIV; + DEBUGASSERT(regval <= PIT_MR_PIV_MASK); + + regval |= (PIT_MR_PITEN | PIT_MR_PITIEN); putreg32(regval, SAM_PIT_MR); /* And enable the timer interrupt */ diff --git a/configs/sama5d3-xplained/include/board.h b/configs/sama5d3-xplained/include/board.h index 59292dfdf4a..c98c629addb 100644 --- a/configs/sama5d3-xplained/include/board.h +++ b/configs/sama5d3-xplained/include/board.h @@ -51,7 +51,19 @@ * definitions will configure operational clocking. */ -#if 1 /* #if !defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) */ +#if defined(CONFIG_SAMA5_BOOT_SDRAM) +/* When booting from SDRAM, NuttX is loaded in SDRAM by an intermediate bootloader. + * That bootloader had to have already configured the PLL and SDRAM for proper + * operation. + * + * In this case, we don not reconfigure the clocking. Rather, we need to query + * the register settings to determine the clock frequencies. We can only assume that + * the Main clock source in the on-board 12MHz crystal. + */ + +# include + +#elif 1 /* #elif !defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) */ /* This is the configuration provided in the Atmel example code. This setup results * in a CPU clock of 396MHz. * diff --git a/configs/sama5d3-xplained/include/board_384mhz.h b/configs/sama5d3-xplained/include/board_384mhz.h index d2fea9be70f..350d661effa 100644 --- a/configs/sama5d3-xplained/include/board_384mhz.h +++ b/configs/sama5d3-xplained/include/board_384mhz.h @@ -157,7 +157,7 @@ #define BOARD_ADC_PRESCAL (7) #define BOARD_TSD_STARTUP (40) /* 40 nanoseconds */ #define BOARD_TSD_TRACKTIM (2000) /* Min 1µs at 8MHz */ -#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (unis nanoseconds) */ +#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (units nanoseconds) */ /* Resulting frequencies */ diff --git a/configs/sama5d3-xplained/include/board_396mhz.h b/configs/sama5d3-xplained/include/board_396mhz.h index 9882ff1fbc9..0bac554d7dc 100644 --- a/configs/sama5d3-xplained/include/board_396mhz.h +++ b/configs/sama5d3-xplained/include/board_396mhz.h @@ -115,7 +115,7 @@ #define BOARD_ADC_PRESCAL (7) #define BOARD_TSD_STARTUP (40) /* 40 nanoseconds */ #define BOARD_TSD_TRACKTIM (2000) /* Min 1µs at 8MHz */ -#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (unis nanoseconds) */ +#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (units nanoseconds) */ /* Resulting frequencies */ diff --git a/configs/sama5d3-xplained/include/board_sdram.h b/configs/sama5d3-xplained/include/board_sdram.h new file mode 100644 index 00000000000..28705d72af4 --- /dev/null +++ b/configs/sama5d3-xplained/include/board_sdram.h @@ -0,0 +1,167 @@ +/************************************************************************************ + * configs/sama5d3-xplained/include/board_sdram.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __CONFIGS_SAMA5D3_XPLAINED_INCLUDE_BOARD_SDRAM_H +#define __CONFIGS_SAMA5D3_XPLAINED_INCLUDE_BOARD_SDRAM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "sam_pmc.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* After power-on reset, the SAMA5 device is running on a 12MHz internal RC. When + * booting from SDRAM, NuttX is loaded in SDRAM by an intermediate bootloader. That + * bootloader had to have already configured the PLL and SDRAM for proper operation. + * + * In this case, we don not reconfigure the clocking. Rather, we need to query + * the register settings to determine the clock frequencies. We can only assume that + * the Main clock source in the on-board 12MHz crystal. + */ + +#define BOARD_MAINOSC_FREQUENCY (12000000) /* MAINOSC: 12MHz crystal on-board */ +#define BOARD_PLLA_FREQUENCY (sam_pllack_frequency(BOARD_MAINOSC_FREQUENCY)) +#define BOARD_PLLADIV2_FREQUENCY (sam_plladiv2_frequency(BOARD_MAINOSC_FREQUENCY)) +#define BOARD_PCK_FREQUENCY (sam_pck_frequency(BOARD_MAINOSC_FREQUENCY)) +#define BOARD_MCK_FREQUENCY (sam_mck_frequency(BOARD_MAINOSC_FREQUENCY)) + +#if defined(CONFIG_SAMA5_EHCI) || defined(CONFIG_SAMA5_OHCI) || \ + defined(CONFIG_SAMA5_UDPHS) + +/* The USB Host High Speed requires a 480 MHz clock (UPLLCK) for the embedded + * High-speed transceivers. UPLLCK is the output of the 480 MHz UTMI PLL + * (UPLL). The source clock of the UTMI PLL is the Main OSC output: Either + * the 12MHz internal RC oscillator on a an external 12MHz crystal. The + * Main OSC must be 12MHz because the UPLL has a built-in 40x multiplier. + * + * For High-speed operations, the user has to perform the following: + * + * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in + * PMC_PCER register. + * 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. + * 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register. + * 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register + * 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register. + * 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + * 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is + * selected. + * 8) Enable OHCI clocks, UHP bit in PMC_SCER register. + * + * Steps 2 through 7 performed here. 1 and 8 are performed in the EHCI + * driver is initialized. + */ + +# define BOARD_USE_UPLL 1 /* Use UPLL for clock source */ +# define BOARD_CKGR_UCKR_UPLLCOUNT (15) /* Maximum value */ +# define BOARD_CKGR_UCKR_BIASCOUNT (15) /* Maximum value */ +#endif + +/* ADC Configuration + * + * ADCClock = MCK / ((PRESCAL+1) * 2) + * PRESCAL = (MCK / (2 * ADCClock) - 1) + */ + +#define BOARD_ADCCLK_FREQUENCY (8000000) /* ADCCLK: MCK / ((7+1)*2) */ +#define BOARD_ADCCLK_FREQUENCY \ + ((BOARD_PLLADIV2_FREQUENCY / (2 *BOARD_PLLADIV2_FREQUENCY)) - 1) + +#define BOARD_ADC_PRESCAL (7) +#define BOARD_TSD_STARTUP (40) /* 40 nanoseconds */ +#define BOARD_TSD_TRACKTIM (2000) /* Min 1µs at 8MHz */ +#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (units nanoseconds) */ + +/* HSMCI clocking + * + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + */ + +/* Initial clock: 400 KHz (target) */ + +#define HSMCI_INIT_CLKDIV sam_hsmci_clkdiv(400000) + +/* MMC transfer clock: 20 MHz (target) */ + +#define HSMCI_MMCXFR_CLKDIV sam_hsmci_clkdiv(20000000) + +/* SD transfer clock: 25 MHz (target) */ + +#define HSMCI_SDXFR_CLKDIV sam_hsmci_clkdiv(25000000) + +#define HSMCI_SDWIDEXFR_CLKDIV HSMCI_SDXFR_CLKDIV + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* !__ASSEMBLY__ */ +#endif /* __CONFIGS_SAMA5D3_XPLAINED_INCLUDE_BOARD_SDRAM_H */ diff --git a/configs/sama5d3x-ek/include/board.h b/configs/sama5d3x-ek/include/board.h index 1c921ca5071..ad48e19444a 100644 --- a/configs/sama5d3x-ek/include/board.h +++ b/configs/sama5d3x-ek/include/board.h @@ -51,7 +51,19 @@ * definitions will configure operational clocking. */ -#if 1 /* #if !defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) */ +#if defined(CONFIG_SAMA5_BOOT_SDRAM) +/* When booting from SDRAM, NuttX is loaded in SDRAM by an intermediate bootloader. + * That bootloader had to have already configured the PLL and SDRAM for proper + * operation. + * + * In this case, we don not reconfigure the clocking. Rather, we need to query + * the register settings to determine the clock frequencies. We can only assume that + * the Main clock source in the on-board 12MHz crystal. + */ + +# include + +#elif 1 /* #elif !defined(CONFIG_SAMA5_OHCI) || defined(CONFIG_SAMA5_EHCI) */ /* This is the configuration provided in the Atmel example code. This setup results * in a CPU clock of 396MHz. * diff --git a/configs/sama5d3x-ek/include/board_384mhz.h b/configs/sama5d3x-ek/include/board_384mhz.h index b5054b63b40..4c899f24c8a 100644 --- a/configs/sama5d3x-ek/include/board_384mhz.h +++ b/configs/sama5d3x-ek/include/board_384mhz.h @@ -157,7 +157,7 @@ #define BOARD_ADC_PRESCAL (7) #define BOARD_TSD_STARTUP (40) /* 40 nanoseconds */ #define BOARD_TSD_TRACKTIM (2000) /* Min 1µs at 8MHz */ -#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (unis nanoseconds) */ +#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (units nanoseconds) */ /* Resulting frequencies */ diff --git a/configs/sama5d3x-ek/include/board_396mhz.h b/configs/sama5d3x-ek/include/board_396mhz.h index 79d136d36be..9580e1aabac 100644 --- a/configs/sama5d3x-ek/include/board_396mhz.h +++ b/configs/sama5d3x-ek/include/board_396mhz.h @@ -115,7 +115,7 @@ #define BOARD_ADC_PRESCAL (7) #define BOARD_TSD_STARTUP (40) /* 40 nanoseconds */ #define BOARD_TSD_TRACKTIM (2000) /* Min 1µs at 8MHz */ -#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (unis nanoseconds) */ +#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (units nanoseconds) */ /* Resulting frequencies */ diff --git a/configs/sama5d3x-ek/include/board_sdram.h b/configs/sama5d3x-ek/include/board_sdram.h new file mode 100644 index 00000000000..c870513f2ec --- /dev/null +++ b/configs/sama5d3x-ek/include/board_sdram.h @@ -0,0 +1,167 @@ +/************************************************************************************ + * configs/sama5d3x-ek/include/board_sdram.h + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __CONFIGS_SAMA5D3X_EK_INCLUDE_BOARD_SDRAM_H +#define __CONFIGS_SAMA5D3X_EK_INCLUDE_BOARD_SDRAM_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include +#include "sam_pmc.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ + +/* Clocking *************************************************************************/ +/* After power-on reset, the SAMA5 device is running on a 12MHz internal RC. When + * booting from SDRAM, NuttX is loaded in SDRAM by an intermediate bootloader. That + * bootloader had to have already configured the PLL and SDRAM for proper operation. + * + * In this case, we don not reconfigure the clocking. Rather, we need to query + * the register settings to determine the clock frequencies. We can only assume that + * the Main clock source in the on-board 12MHz crystal. + */ + +#define BOARD_MAINOSC_FREQUENCY (12000000) /* MAINOSC: 12MHz crystal on-board */ +#define BOARD_PLLA_FREQUENCY (sam_pllack_frequency(BOARD_MAINOSC_FREQUENCY)) +#define BOARD_PLLADIV2_FREQUENCY (sam_plladiv2_frequency(BOARD_MAINOSC_FREQUENCY)) +#define BOARD_PCK_FREQUENCY (sam_pck_frequency(BOARD_MAINOSC_FREQUENCY)) +#define BOARD_MCK_FREQUENCY (sam_mck_frequency(BOARD_MAINOSC_FREQUENCY)) + +#if defined(CONFIG_SAMA5_EHCI) || defined(CONFIG_SAMA5_OHCI) || \ + defined(CONFIG_SAMA5_UDPHS) + +/* The USB Host High Speed requires a 480 MHz clock (UPLLCK) for the embedded + * High-speed transceivers. UPLLCK is the output of the 480 MHz UTMI PLL + * (UPLL). The source clock of the UTMI PLL is the Main OSC output: Either + * the 12MHz internal RC oscillator on a an external 12MHz crystal. The + * Main OSC must be 12MHz because the UPLL has a built-in 40x multiplier. + * + * For High-speed operations, the user has to perform the following: + * + * 1) Enable UHP peripheral clock, bit (1 << AT91C_ID_UHPHS) in + * PMC_PCER register. + * 2) Write CKGR_PLLCOUNT field in PMC_UCKR register. + * 3) Enable UPLL, bit AT91C_CKGR_UPLLEN in PMC_UCKR register. + * 4) Wait until UTMI_PLL is locked. LOCKU bit in PMC_SR register + * 5) Enable BIAS, bit AT91C_CKGR_BIASEN in PMC_UCKR register. + * 6) Select UPLLCK as Input clock of OHCI part, USBS bit in PMC_USB + * register. + * 7) Program the OHCI clocks (UHP48M and UHP12M) with USBDIV field in + * PMC_USB register. USBDIV must be 9 (division by 10) if UPLLCK is + * selected. + * 8) Enable OHCI clocks, UHP bit in PMC_SCER register. + * + * Steps 2 through 7 performed here. 1 and 8 are performed in the EHCI + * driver is initialized. + */ + +# define BOARD_USE_UPLL 1 /* Use UPLL for clock source */ +# define BOARD_CKGR_UCKR_UPLLCOUNT (15) /* Maximum value */ +# define BOARD_CKGR_UCKR_BIASCOUNT (15) /* Maximum value */ +#endif + +/* ADC Configuration + * + * ADCClock = MCK / ((PRESCAL+1) * 2) + * PRESCAL = (MCK / (2 * ADCClock) - 1) + */ + +#define BOARD_ADCCLK_FREQUENCY (8000000) /* ADCCLK: MCK / ((7+1)*2) */ +#define BOARD_ADCCLK_FREQUENCY \ + ((BOARD_PLLADIV2_FREQUENCY / (2 *BOARD_PLLADIV2_FREQUENCY)) - 1) + +#define BOARD_ADC_PRESCAL (7) +#define BOARD_TSD_STARTUP (40) /* 40 nanoseconds */ +#define BOARD_TSD_TRACKTIM (2000) /* Min 1µs at 8MHz */ +#define BOARD_TSD_DEBOUNCE (10000000) /* 10 milliseconds (units nanoseconds) */ + +/* HSMCI clocking + * + * Multimedia Card Interface clock (MCCK or MCI_CK) is Master Clock (MCK) + * divided by (2*(CLKDIV) + CLOCKODD + 2). + * + * CLKFULLDIV = 2*CLKDIV + CLOCKODD; + * MCI_SPEED = MCK / (CLKFULLDIV + 2) + * CLKFULLDIV = MCK / MCI_SPEED - 2 + * + * CLKDIV = CLKFULLDIV >> 1 + * CLOCKODD = CLKFULLDIV & 1 + * + * Where CLKDIV has a range of 0-255. + */ + +/* Initial clock: 400 KHz (target) */ + +#define HSMCI_INIT_CLKDIV sam_hsmci_clkdiv(400000) + +/* MMC transfer clock: 20 MHz (target) */ + +#define HSMCI_MMCXFR_CLKDIV sam_hsmci_clkdiv(20000000) + +/* SD transfer clock: 25 MHz (target) */ + +#define HSMCI_SDXFR_CLKDIV sam_hsmci_clkdiv(25000000) + +#define HSMCI_SDWIDEXFR_CLKDIV HSMCI_SDXFR_CLKDIV + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" { +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* !__ASSEMBLY__ */ +#endif /* __CONFIGS_SAMA5D3X_EK_INCLUDE_BOARD_SDRAM_H */