xref: /btstack/port/samv71-xplained-atwilc3000/ASF/common/services/clock/samv71/sysclk.h (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald  * \file
3*1b2596b5SMatthias Ringwald  *
4*1b2596b5SMatthias Ringwald  * \brief Chip-specific system clock management functions.
5*1b2596b5SMatthias Ringwald  *
6*1b2596b5SMatthias Ringwald  * Copyright (c) 2015 Atmel Corporation. All rights reserved.
7*1b2596b5SMatthias Ringwald  *
8*1b2596b5SMatthias Ringwald  * \asf_license_start
9*1b2596b5SMatthias Ringwald  *
10*1b2596b5SMatthias Ringwald  * \page License
11*1b2596b5SMatthias Ringwald  *
12*1b2596b5SMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
13*1b2596b5SMatthias Ringwald  * modification, are permitted provided that the following conditions are met:
14*1b2596b5SMatthias Ringwald  *
15*1b2596b5SMatthias Ringwald  * 1. Redistributions of source code must retain the above copyright notice,
16*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer.
17*1b2596b5SMatthias Ringwald  *
18*1b2596b5SMatthias Ringwald  * 2. Redistributions in binary form must reproduce the above copyright notice,
19*1b2596b5SMatthias Ringwald  *    this list of conditions and the following disclaimer in the documentation
20*1b2596b5SMatthias Ringwald  *    and/or other materials provided with the distribution.
21*1b2596b5SMatthias Ringwald  *
22*1b2596b5SMatthias Ringwald  * 3. The name of Atmel may not be used to endorse or promote products derived
23*1b2596b5SMatthias Ringwald  *    from this software without specific prior written permission.
24*1b2596b5SMatthias Ringwald  *
25*1b2596b5SMatthias Ringwald  * 4. This software may only be redistributed and used in connection with an
26*1b2596b5SMatthias Ringwald  *    Atmel microcontroller product.
27*1b2596b5SMatthias Ringwald  *
28*1b2596b5SMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29*1b2596b5SMatthias Ringwald  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30*1b2596b5SMatthias Ringwald  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31*1b2596b5SMatthias Ringwald  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32*1b2596b5SMatthias Ringwald  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33*1b2596b5SMatthias Ringwald  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34*1b2596b5SMatthias Ringwald  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35*1b2596b5SMatthias Ringwald  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36*1b2596b5SMatthias Ringwald  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37*1b2596b5SMatthias Ringwald  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38*1b2596b5SMatthias Ringwald  * POSSIBILITY OF SUCH DAMAGE.
39*1b2596b5SMatthias Ringwald  *
40*1b2596b5SMatthias Ringwald  * \asf_license_stop
41*1b2596b5SMatthias Ringwald  *
42*1b2596b5SMatthias Ringwald  */
43*1b2596b5SMatthias Ringwald /*
44*1b2596b5SMatthias Ringwald  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45*1b2596b5SMatthias Ringwald  */
46*1b2596b5SMatthias Ringwald 
47*1b2596b5SMatthias Ringwald #ifndef CHIP_SYSCLK_H_INCLUDED
48*1b2596b5SMatthias Ringwald #define CHIP_SYSCLK_H_INCLUDED
49*1b2596b5SMatthias Ringwald 
50*1b2596b5SMatthias Ringwald #include <osc.h>
51*1b2596b5SMatthias Ringwald #include <pll.h>
52*1b2596b5SMatthias Ringwald 
53*1b2596b5SMatthias Ringwald /**
54*1b2596b5SMatthias Ringwald  * \page sysclk_quickstart Quick Start Guide for the System Clock Management
55*1b2596b5SMatthias Ringwald  * service (SAMV71)
56*1b2596b5SMatthias Ringwald  *
57*1b2596b5SMatthias Ringwald  * This is the quick start guide for the \ref sysclk_group "System Clock
58*1b2596b5SMatthias Ringwald  * Management" service, with step-by-step instructions on how to configure and
59*1b2596b5SMatthias Ringwald  * use the service for specific use cases.
60*1b2596b5SMatthias Ringwald  *
61*1b2596b5SMatthias Ringwald  * \section sysclk_quickstart_usecases System Clock Management use cases
62*1b2596b5SMatthias Ringwald  * - \ref sysclk_quickstart_basic
63*1b2596b5SMatthias Ringwald  * - \ref sysclk_quickstart_use_case_2
64*1b2596b5SMatthias Ringwald  *
65*1b2596b5SMatthias Ringwald  * \section sysclk_quickstart_basic Basic usage of the System Clock Management
66*1b2596b5SMatthias Ringwald  * service
67*1b2596b5SMatthias Ringwald  * This section will present a basic use case for the System Clock Management
68*1b2596b5SMatthias Ringwald  * service. This use case will configure the main system clock to 120MHz,
69*1b2596b5SMatthias Ringwald  * using an internal PLL module to multiply the frequency of a crystal attached
70*1b2596b5SMatthias Ringwald  * to the microcontroller.
71*1b2596b5SMatthias Ringwald  *
72*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites
73*1b2596b5SMatthias Ringwald  *  - None
74*1b2596b5SMatthias Ringwald  *
75*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code
76*1b2596b5SMatthias Ringwald  * Add to the application initialization code:
77*1b2596b5SMatthias Ringwald  * \code
78*1b2596b5SMatthias Ringwald 	sysclk_init();
79*1b2596b5SMatthias Ringwald \endcode
80*1b2596b5SMatthias Ringwald  *
81*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow
82*1b2596b5SMatthias Ringwald  * -# Configure the system clocks according to the settings in conf_clock.h:
83*1b2596b5SMatthias Ringwald  *    \code sysclk_init(); \endcode
84*1b2596b5SMatthias Ringwald  *
85*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_1_example_code Example code
86*1b2596b5SMatthias Ringwald  *   Add or uncomment the following in your conf_clock.h header file,
87*1b2596b5SMatthias Ringwald  *   commenting out all other definitions of the same symbol(s):
88*1b2596b5SMatthias Ringwald  *   \code
89*1b2596b5SMatthias Ringwald 	   #define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLLACK
90*1b2596b5SMatthias Ringwald 
91*1b2596b5SMatthias Ringwald 	   // Fpll0 = (Fclk * PLL_mul) / PLL_div
92*1b2596b5SMatthias Ringwald 	   #define CONFIG_PLL0_SOURCE          PLL_SRC_MAINCK_XTAL
93*1b2596b5SMatthias Ringwald 	   #define CONFIG_PLL0_MUL             (120000000UL / BOARD_FREQ_MAINCK_XTAL)
94*1b2596b5SMatthias Ringwald 	   #define CONFIG_PLL0_DIV             1
95*1b2596b5SMatthias Ringwald 
96*1b2596b5SMatthias Ringwald 	   // Fbus = Fsys / BUS_div
97*1b2596b5SMatthias Ringwald 	   #define CONFIG_SYSCLK_PRES          SYSCLK_PRES_1
98*1b2596b5SMatthias Ringwald \endcode
99*1b2596b5SMatthias Ringwald  *
100*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow
101*1b2596b5SMatthias Ringwald  *  -# Configure the main system clock to use the output of the PLL module as
102*1b2596b5SMatthias Ringwald  *     its source:
103*1b2596b5SMatthias Ringwald  *   \code #define CONFIG_SYSCLK_SOURCE          SYSCLK_SRC_PLLACK \endcode
104*1b2596b5SMatthias Ringwald  *  -# Configure the PLL module to use the fast external fast crystal
105*1b2596b5SMatthias Ringwald  *     oscillator as its source:
106*1b2596b5SMatthias Ringwald  *   \code #define CONFIG_PLL0_SOURCE            PLL_SRC_MAINCK_XTAL \endcode
107*1b2596b5SMatthias Ringwald  *  -# Configure the PLL module to multiply the external fast crystal
108*1b2596b5SMatthias Ringwald  *     oscillator frequency up to 120MHz:
109*1b2596b5SMatthias Ringwald  *   \code
110*1b2596b5SMatthias Ringwald 	#define CONFIG_PLL0_MUL             (120000000UL / BOARD_FREQ_MAINCK_XTAL)
111*1b2596b5SMatthias Ringwald 	#define CONFIG_PLL0_DIV             1
112*1b2596b5SMatthias Ringwald \endcode
113*1b2596b5SMatthias Ringwald  *   \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the
114*1b2596b5SMatthias Ringwald  *   board \c conf_board.h configuration
115*1b2596b5SMatthias Ringwald  *         file as the frequency of the fast crystal attached to the microcontroller.
116*1b2596b5SMatthias Ringwald  *  -# Configure the main clock to run at the full 120MHz, disable scaling of
117*1b2596b5SMatthias Ringwald  *     the main system clock speed:
118*1b2596b5SMatthias Ringwald  *    \code
119*1b2596b5SMatthias Ringwald 	#define CONFIG_SYSCLK_PRES         SYSCLK_PRES_1
120*1b2596b5SMatthias Ringwald \endcode
121*1b2596b5SMatthias Ringwald  *    \note Some dividers are powers of two, while others are integer division
122*1b2596b5SMatthias Ringwald  *    factors. Refer to the formulas in the conf_clock.h template commented
123*1b2596b5SMatthias Ringwald  *    above each division define.
124*1b2596b5SMatthias Ringwald  */
125*1b2596b5SMatthias Ringwald 
126*1b2596b5SMatthias Ringwald /**
127*1b2596b5SMatthias Ringwald  * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock
128*1b2596b5SMatthias Ringwald  * Management (SAMV71)
129*1b2596b5SMatthias Ringwald  *
130*1b2596b5SMatthias Ringwald  * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus
131*1b2596b5SMatthias Ringwald  * Clock Management
132*1b2596b5SMatthias Ringwald  * This section will present a more advanced use case for the System Clock
133*1b2596b5SMatthias Ringwald  * Management service. This use case will configure the main system clock to
134*1b2596b5SMatthias Ringwald  * 96MHz, using an internal PLL module to multiply the frequency of a crystal
135*1b2596b5SMatthias Ringwald  * attached to the microcontroller. The USB clock will be configured via the
136*1b2596b5SMatthias Ringwald  * same PLL module.
137*1b2596b5SMatthias Ringwald  *
138*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites
139*1b2596b5SMatthias Ringwald  *  - None
140*1b2596b5SMatthias Ringwald  *
141*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code
142*1b2596b5SMatthias Ringwald  * Add to the application initialization code:
143*1b2596b5SMatthias Ringwald  * \code
144*1b2596b5SMatthias Ringwald 	sysclk_init();
145*1b2596b5SMatthias Ringwald \endcode
146*1b2596b5SMatthias Ringwald  *
147*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow
148*1b2596b5SMatthias Ringwald  * -# Configure the system clocks according to the settings in conf_clock.h:
149*1b2596b5SMatthias Ringwald  *    \code sysclk_init(); \endcode
150*1b2596b5SMatthias Ringwald  *
151*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_2_example_code Example code
152*1b2596b5SMatthias Ringwald  *   Add or uncomment the following in your conf_clock.h header file,
153*1b2596b5SMatthias Ringwald  *   commenting out all other definitions of the same symbol(s):
154*1b2596b5SMatthias Ringwald  *   \code
155*1b2596b5SMatthias Ringwald 	   #define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLLACK
156*1b2596b5SMatthias Ringwald 
157*1b2596b5SMatthias Ringwald 	   // Fpll0 = (Fclk * PLL_mul) / PLL_div
158*1b2596b5SMatthias Ringwald 	   #define CONFIG_PLL0_SOURCE          PLL_SRC_MAINCK_XTAL
159*1b2596b5SMatthias Ringwald 	   #define CONFIG_PLL0_MUL             (96000000UL / BOARD_FREQ_MAINCK_XTAL)
160*1b2596b5SMatthias Ringwald 	   #define CONFIG_PLL0_DIV             1
161*1b2596b5SMatthias Ringwald 
162*1b2596b5SMatthias Ringwald 	   // Fbus = Fsys / BUS_div
163*1b2596b5SMatthias Ringwald 	   #define CONFIG_SYSCLK_PRES          SYSCLK_PRES_1
164*1b2596b5SMatthias Ringwald 
165*1b2596b5SMatthias Ringwald 	   // Fusb = Fsys / USB_div
166*1b2596b5SMatthias Ringwald 	   #define CONFIG_USBCLK_SOURCE        USBCLK_SRC_PLL0
167*1b2596b5SMatthias Ringwald 	   #define CONFIG_USBCLK_DIV           2
168*1b2596b5SMatthias Ringwald \endcode
169*1b2596b5SMatthias Ringwald  *
170*1b2596b5SMatthias Ringwald  * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow
171*1b2596b5SMatthias Ringwald  *  -# Configure the main system clock to use the output of the PLL0 module as
172*1b2596b5SMatthias Ringwald  *     its source:
173*1b2596b5SMatthias Ringwald  *   \code #define CONFIG_SYSCLK_SOURCE          SYSCLK_SRC_PLLACK \endcode
174*1b2596b5SMatthias Ringwald  *  -# Configure the PLL0 module to use the fast external fast crystal
175*1b2596b5SMatthias Ringwald  *     oscillator as its source:
176*1b2596b5SMatthias Ringwald  *   \code #define CONFIG_PLL0_SOURCE            PLL_SRC_MAINCK_XTAL \endcode
177*1b2596b5SMatthias Ringwald  *  -# Configure the PLL0 module to multiply the external fast crystal
178*1b2596b5SMatthias Ringwald  *     oscillator frequency up to 96MHz:
179*1b2596b5SMatthias Ringwald  *   \code
180*1b2596b5SMatthias Ringwald 	#define CONFIG_PLL0_MUL             (96000000UL / BOARD_FREQ_MAINCK_XTAL)
181*1b2596b5SMatthias Ringwald 	#define CONFIG_PLL0_DIV             1
182*1b2596b5SMatthias Ringwald \endcode
183*1b2596b5SMatthias Ringwald  *   \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the
184*1b2596b5SMatthias Ringwald  *   board \c conf_board.h configuration file as the frequency of the fast
185*1b2596b5SMatthias Ringwald  *   crystal attached to the microcontroller.
186*1b2596b5SMatthias Ringwald  *  -# Configure the main clock to run at the full 96MHz, disable scaling of
187*1b2596b5SMatthias Ringwald  *     the main system clock speed:
188*1b2596b5SMatthias Ringwald  *    \code
189*1b2596b5SMatthias Ringwald 	#define CONFIG_SYSCLK_PRES         SYSCLK_PRES_1
190*1b2596b5SMatthias Ringwald \endcode
191*1b2596b5SMatthias Ringwald  *    \note Some dividers are powers of two, while others are integer division
192*1b2596b5SMatthias Ringwald  *    factors. Refer to the formulas in the conf_clock.h template commented
193*1b2596b5SMatthias Ringwald  *    above each division define.
194*1b2596b5SMatthias Ringwald  *  -# Configure the USB module clock to use the output of the PLL0 module as
195*1b2596b5SMatthias Ringwald  *     its source with division 2:
196*1b2596b5SMatthias Ringwald  *   \code
197*1b2596b5SMatthias Ringwald 	#define CONFIG_USBCLK_SOURCE        USBCLK_SRC_PLL0
198*1b2596b5SMatthias Ringwald 	#define CONFIG_USBCLK_DIV           2
199*1b2596b5SMatthias Ringwald \endcode
200*1b2596b5SMatthias Ringwald  */
201*1b2596b5SMatthias Ringwald 
202*1b2596b5SMatthias Ringwald /// @cond 0
203*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
204*1b2596b5SMatthias Ringwald #ifdef __cplusplus
205*1b2596b5SMatthias Ringwald extern "C" {
206*1b2596b5SMatthias Ringwald #endif
207*1b2596b5SMatthias Ringwald /**INDENT-ON**/
208*1b2596b5SMatthias Ringwald /// @endcond
209*1b2596b5SMatthias Ringwald 
210*1b2596b5SMatthias Ringwald /**
211*1b2596b5SMatthias Ringwald  * \weakgroup sysclk_group
212*1b2596b5SMatthias Ringwald  * @{
213*1b2596b5SMatthias Ringwald  */
214*1b2596b5SMatthias Ringwald 
215*1b2596b5SMatthias Ringwald //! \name Configuration Symbols
216*1b2596b5SMatthias Ringwald //@{
217*1b2596b5SMatthias Ringwald /**
218*1b2596b5SMatthias Ringwald  * \def CONFIG_SYSCLK_SOURCE
219*1b2596b5SMatthias Ringwald  * \brief Initial/static main system clock source
220*1b2596b5SMatthias Ringwald  *
221*1b2596b5SMatthias Ringwald  * The main system clock will be configured to use this clock during
222*1b2596b5SMatthias Ringwald  * initialization.
223*1b2596b5SMatthias Ringwald  */
224*1b2596b5SMatthias Ringwald #ifndef CONFIG_SYSCLK_SOURCE
225*1b2596b5SMatthias Ringwald # define CONFIG_SYSCLK_SOURCE   SYSCLK_SRC_MAINCK_4M_RC
226*1b2596b5SMatthias Ringwald #endif
227*1b2596b5SMatthias Ringwald /**
228*1b2596b5SMatthias Ringwald  * \def CONFIG_SYSCLK_PRES
229*1b2596b5SMatthias Ringwald  * \brief Initial CPU clock divider (mck)
230*1b2596b5SMatthias Ringwald  *
231*1b2596b5SMatthias Ringwald  * The MCK will run at
232*1b2596b5SMatthias Ringwald  * \f[
233*1b2596b5SMatthias Ringwald  *   f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz}
234*1b2596b5SMatthias Ringwald  * \f]
235*1b2596b5SMatthias Ringwald  * after initialization.
236*1b2596b5SMatthias Ringwald  */
237*1b2596b5SMatthias Ringwald #ifndef CONFIG_SYSCLK_PRES
238*1b2596b5SMatthias Ringwald # define CONFIG_SYSCLK_PRES  0
239*1b2596b5SMatthias Ringwald #endif
240*1b2596b5SMatthias Ringwald 
241*1b2596b5SMatthias Ringwald //@}
242*1b2596b5SMatthias Ringwald 
243*1b2596b5SMatthias Ringwald //! \name Master Clock Sources (MCK)
244*1b2596b5SMatthias Ringwald //@{
245*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_SLCK_RC         0 //!< Internal 32kHz RC oscillator as master source clock
246*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_SLCK_XTAL       1 //!< External 32kHz crystal oscillator as master source clock
247*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_SLCK_BYPASS     2 //!< External 32kHz bypass oscillator as master source clock
248*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_4M_RC    3 //!< Internal 4MHz RC oscillator as master source clock
249*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_8M_RC    4 //!< Internal 8MHz RC oscillator as master source clock
250*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_12M_RC   5 //!< Internal 12MHz RC oscillator as master source clock
251*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_XTAL     6 //!< External crystal oscillator as master source clock
252*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_MAINCK_BYPASS   7 //!< External bypass oscillator as master source clock
253*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_PLLACK          8 //!< Use PLLACK as master source clock
254*1b2596b5SMatthias Ringwald #define SYSCLK_SRC_UPLLCK          9       //!< Use UPLLCK as master source clock
255*1b2596b5SMatthias Ringwald //@}
256*1b2596b5SMatthias Ringwald 
257*1b2596b5SMatthias Ringwald //! \name Master Clock Prescalers (MCK)
258*1b2596b5SMatthias Ringwald //@{
259*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_1   PMC_MCKR_PRES_CLK_1  //!< Set master clock prescaler to 1
260*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_2   PMC_MCKR_PRES_CLK_2  //!< Set master clock prescaler to 2
261*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_4   PMC_MCKR_PRES_CLK_4  //!< Set master clock prescaler to 4
262*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_8   PMC_MCKR_PRES_CLK_8  //!< Set master clock prescaler to 8
263*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_16  PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16
264*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_32  PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32
265*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_64  PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64
266*1b2596b5SMatthias Ringwald #define SYSCLK_PRES_3   PMC_MCKR_PRES_CLK_3  //!< Set master clock prescaler to 3
267*1b2596b5SMatthias Ringwald //@}
268*1b2596b5SMatthias Ringwald 
269*1b2596b5SMatthias Ringwald //! \name Master Clock Division (MCK)
270*1b2596b5SMatthias Ringwald //@{
271*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_1   PMC_MCKR_MDIV_EQ_PCK  //!< Set master clock division to 1
272*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_2   PMC_MCKR_MDIV_PCK_DIV2  //!< Set master clock division to 2
273*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_4   PMC_MCKR_MDIV_PCK_DIV4  //!< Set master clock division to 4
274*1b2596b5SMatthias Ringwald #define SYSCLK_DIV_3   PMC_MCKR_MDIV_PCK_DIV3  //!< Set master clock division to 3
275*1b2596b5SMatthias Ringwald //@}
276*1b2596b5SMatthias Ringwald 
277*1b2596b5SMatthias Ringwald //! \name USB Clock Sources
278*1b2596b5SMatthias Ringwald //@{
279*1b2596b5SMatthias Ringwald #define USBCLK_SRC_PLL0       0     //!< Use PLLA
280*1b2596b5SMatthias Ringwald #define USBCLK_SRC_UPLL       1     //!< Use UPLL
281*1b2596b5SMatthias Ringwald //@}
282*1b2596b5SMatthias Ringwald 
283*1b2596b5SMatthias Ringwald /**
284*1b2596b5SMatthias Ringwald  * \def CONFIG_USBCLK_SOURCE
285*1b2596b5SMatthias Ringwald  * \brief Configuration symbol for the USB generic clock source
286*1b2596b5SMatthias Ringwald  *
287*1b2596b5SMatthias Ringwald  * Sets the clock source to use for the USB. The source must also be properly
288*1b2596b5SMatthias Ringwald  * configured.
289*1b2596b5SMatthias Ringwald  *
290*1b2596b5SMatthias Ringwald  * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if
291*1b2596b5SMatthias Ringwald  * USB is not required.
292*1b2596b5SMatthias Ringwald  */
293*1b2596b5SMatthias Ringwald #ifdef __DOXYGEN__
294*1b2596b5SMatthias Ringwald # define CONFIG_USBCLK_SOURCE
295*1b2596b5SMatthias Ringwald #endif
296*1b2596b5SMatthias Ringwald 
297*1b2596b5SMatthias Ringwald /**
298*1b2596b5SMatthias Ringwald  * \def CONFIG_USBCLK_DIV
299*1b2596b5SMatthias Ringwald  * \brief Configuration symbol for the USB generic clock divider setting
300*1b2596b5SMatthias Ringwald  *
301*1b2596b5SMatthias Ringwald  * Sets the clock division for the USB generic clock. If a USB clock source is
302*1b2596b5SMatthias Ringwald  * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be
303*1b2596b5SMatthias Ringwald  * defined.
304*1b2596b5SMatthias Ringwald  */
305*1b2596b5SMatthias Ringwald #ifdef __DOXYGEN__
306*1b2596b5SMatthias Ringwald # define CONFIG_USBCLK_DIV
307*1b2596b5SMatthias Ringwald #endif
308*1b2596b5SMatthias Ringwald 
309*1b2596b5SMatthias Ringwald /**
310*1b2596b5SMatthias Ringwald  * \name Querying the system clock
311*1b2596b5SMatthias Ringwald  *
312*1b2596b5SMatthias Ringwald  * The following functions may be used to query the current frequency of
313*1b2596b5SMatthias Ringwald  * the system clock and the CPU and bus clocks derived from it.
314*1b2596b5SMatthias Ringwald  * sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be
315*1b2596b5SMatthias Ringwald  * available on all platforms, although some platforms may define
316*1b2596b5SMatthias Ringwald  * additional accessors for various chip-internal bus clocks. These are
317*1b2596b5SMatthias Ringwald  * usually not intended to be queried directly by generic code.
318*1b2596b5SMatthias Ringwald  */
319*1b2596b5SMatthias Ringwald //@{
320*1b2596b5SMatthias Ringwald 
321*1b2596b5SMatthias Ringwald /**
322*1b2596b5SMatthias Ringwald  * \brief Return the current rate in Hz of the main system clock
323*1b2596b5SMatthias Ringwald  *
324*1b2596b5SMatthias Ringwald  * \todo This function assumes that the main clock source never changes
325*1b2596b5SMatthias Ringwald  * once it's been set up, and that PLL0 always runs at the compile-time
326*1b2596b5SMatthias Ringwald  * configured default rate. While this is probably the most common
327*1b2596b5SMatthias Ringwald  * configuration, which we want to support as a special case for
328*1b2596b5SMatthias Ringwald  * performance reasons, we will at some point need to support more
329*1b2596b5SMatthias Ringwald  * dynamic setups as well.
330*1b2596b5SMatthias Ringwald  */
331*1b2596b5SMatthias Ringwald #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
332*1b2596b5SMatthias Ringwald extern uint32_t sysclk_initialized;
333*1b2596b5SMatthias Ringwald #endif
sysclk_get_main_hz(void)334*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_main_hz(void)
335*1b2596b5SMatthias Ringwald {
336*1b2596b5SMatthias Ringwald #if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
337*1b2596b5SMatthias Ringwald 	if (!sysclk_initialized ) {
338*1b2596b5SMatthias Ringwald 		return OSC_MAINCK_4M_RC_HZ;
339*1b2596b5SMatthias Ringwald 	}
340*1b2596b5SMatthias Ringwald #endif
341*1b2596b5SMatthias Ringwald 
342*1b2596b5SMatthias Ringwald 	/* Config system clock setting */
343*1b2596b5SMatthias Ringwald 	if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) {
344*1b2596b5SMatthias Ringwald 		return OSC_SLCK_32K_RC_HZ;
345*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) {
346*1b2596b5SMatthias Ringwald 		return OSC_SLCK_32K_XTAL_HZ;
347*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) {
348*1b2596b5SMatthias Ringwald 		return OSC_SLCK_32K_BYPASS_HZ;
349*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) {
350*1b2596b5SMatthias Ringwald 		return OSC_MAINCK_4M_RC_HZ;
351*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) {
352*1b2596b5SMatthias Ringwald 		return OSC_MAINCK_8M_RC_HZ;
353*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) {
354*1b2596b5SMatthias Ringwald 		return OSC_MAINCK_12M_RC_HZ;
355*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) {
356*1b2596b5SMatthias Ringwald 		return OSC_MAINCK_XTAL_HZ;
357*1b2596b5SMatthias Ringwald 	} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) {
358*1b2596b5SMatthias Ringwald 		return OSC_MAINCK_BYPASS_HZ;
359*1b2596b5SMatthias Ringwald 	}
360*1b2596b5SMatthias Ringwald #ifdef CONFIG_PLL0_SOURCE
361*1b2596b5SMatthias Ringwald 	else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) {
362*1b2596b5SMatthias Ringwald 		return pll_get_default_rate(0);
363*1b2596b5SMatthias Ringwald 	}
364*1b2596b5SMatthias Ringwald #endif
365*1b2596b5SMatthias Ringwald 
366*1b2596b5SMatthias Ringwald #ifdef CONFIG_PLL1_SOURCE
367*1b2596b5SMatthias Ringwald 	else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_UPLLCK) {
368*1b2596b5SMatthias Ringwald 		return PLL_UPLL_HZ;
369*1b2596b5SMatthias Ringwald 	}
370*1b2596b5SMatthias Ringwald #endif
371*1b2596b5SMatthias Ringwald 	else {
372*1b2596b5SMatthias Ringwald 		/* unhandled_case(CONFIG_SYSCLK_SOURCE); */
373*1b2596b5SMatthias Ringwald 		return 0;
374*1b2596b5SMatthias Ringwald 	}
375*1b2596b5SMatthias Ringwald }
376*1b2596b5SMatthias Ringwald 
377*1b2596b5SMatthias Ringwald /**
378*1b2596b5SMatthias Ringwald  * \brief Return the current rate in Hz of the CPU clock
379*1b2596b5SMatthias Ringwald  *
380*1b2596b5SMatthias Ringwald  * \todo This function assumes that the CPU always runs at the system
381*1b2596b5SMatthias Ringwald  * clock frequency. We want to support at least two more scenarios:
382*1b2596b5SMatthias Ringwald  * Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus
383*1b2596b5SMatthias Ringwald  * clock dividers (which may change at run time). Ditto for all the bus
384*1b2596b5SMatthias Ringwald  * clocks.
385*1b2596b5SMatthias Ringwald  *
386*1b2596b5SMatthias Ringwald  * \return Frequency of the CPU clock, in Hz.
387*1b2596b5SMatthias Ringwald  */
sysclk_get_cpu_hz(void)388*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_cpu_hz(void)
389*1b2596b5SMatthias Ringwald {
390*1b2596b5SMatthias Ringwald 	/* CONFIG_SYSCLK_PRES is the register value for setting the expected */
391*1b2596b5SMatthias Ringwald 	/* prescaler, not an immediate value. */
392*1b2596b5SMatthias Ringwald 	return sysclk_get_main_hz() /
393*1b2596b5SMatthias Ringwald 		((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 :
394*1b2596b5SMatthias Ringwald 			(1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos)));
395*1b2596b5SMatthias Ringwald }
396*1b2596b5SMatthias Ringwald 
397*1b2596b5SMatthias Ringwald /**
398*1b2596b5SMatthias Ringwald  * \brief Retrieves the current rate in Hz of the peripheral clocks.
399*1b2596b5SMatthias Ringwald  *
400*1b2596b5SMatthias Ringwald  * \return Frequency of the peripheral clocks, in Hz.
401*1b2596b5SMatthias Ringwald  */
sysclk_get_peripheral_hz(void)402*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_peripheral_hz(void)
403*1b2596b5SMatthias Ringwald {
404*1b2596b5SMatthias Ringwald 	/* CONFIG_SYSCLK_PRES is the register value for setting the expected */
405*1b2596b5SMatthias Ringwald 	/* prescaler, not an immediate value. */
406*1b2596b5SMatthias Ringwald 	return sysclk_get_main_hz() /
407*1b2596b5SMatthias Ringwald 		(((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))) * CONFIG_SYSCLK_DIV);
408*1b2596b5SMatthias Ringwald }
409*1b2596b5SMatthias Ringwald 
410*1b2596b5SMatthias Ringwald /**
411*1b2596b5SMatthias Ringwald  * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached
412*1b2596b5SMatthias Ringwald  *        to the specified peripheral.
413*1b2596b5SMatthias Ringwald  *
414*1b2596b5SMatthias Ringwald  * \param module Pointer to the module's base address.
415*1b2596b5SMatthias Ringwald  *
416*1b2596b5SMatthias Ringwald  * \return Frequency of the bus attached to the specified peripheral, in Hz.
417*1b2596b5SMatthias Ringwald  */
sysclk_get_peripheral_bus_hz(const volatile void * module)418*1b2596b5SMatthias Ringwald static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module)
419*1b2596b5SMatthias Ringwald {
420*1b2596b5SMatthias Ringwald 	UNUSED(module);
421*1b2596b5SMatthias Ringwald 	return sysclk_get_peripheral_hz();
422*1b2596b5SMatthias Ringwald }
423*1b2596b5SMatthias Ringwald //@}
424*1b2596b5SMatthias Ringwald 
425*1b2596b5SMatthias Ringwald //! \name Enabling and disabling synchronous clocks
426*1b2596b5SMatthias Ringwald //@{
427*1b2596b5SMatthias Ringwald 
428*1b2596b5SMatthias Ringwald /**
429*1b2596b5SMatthias Ringwald  * \brief Enable a peripheral's clock.
430*1b2596b5SMatthias Ringwald  *
431*1b2596b5SMatthias Ringwald  * \param ul_id Id (number) of the peripheral clock.
432*1b2596b5SMatthias Ringwald  */
sysclk_enable_peripheral_clock(uint32_t ul_id)433*1b2596b5SMatthias Ringwald static inline void sysclk_enable_peripheral_clock(uint32_t ul_id)
434*1b2596b5SMatthias Ringwald {
435*1b2596b5SMatthias Ringwald 	pmc_enable_periph_clk(ul_id);
436*1b2596b5SMatthias Ringwald }
437*1b2596b5SMatthias Ringwald 
438*1b2596b5SMatthias Ringwald /**
439*1b2596b5SMatthias Ringwald  * \brief Disable a peripheral's clock.
440*1b2596b5SMatthias Ringwald  *
441*1b2596b5SMatthias Ringwald  * \param ul_id Id (number) of the peripheral clock.
442*1b2596b5SMatthias Ringwald  */
sysclk_disable_peripheral_clock(uint32_t ul_id)443*1b2596b5SMatthias Ringwald static inline void sysclk_disable_peripheral_clock(uint32_t ul_id)
444*1b2596b5SMatthias Ringwald {
445*1b2596b5SMatthias Ringwald 	pmc_disable_periph_clk(ul_id);
446*1b2596b5SMatthias Ringwald }
447*1b2596b5SMatthias Ringwald 
448*1b2596b5SMatthias Ringwald //@}
449*1b2596b5SMatthias Ringwald 
450*1b2596b5SMatthias Ringwald //! \name System Clock Source and Prescaler configuration
451*1b2596b5SMatthias Ringwald //@{
452*1b2596b5SMatthias Ringwald 
453*1b2596b5SMatthias Ringwald extern void sysclk_set_prescalers(uint32_t ul_pres);
454*1b2596b5SMatthias Ringwald extern void sysclk_set_source(uint32_t ul_src);
455*1b2596b5SMatthias Ringwald 
456*1b2596b5SMatthias Ringwald //@}
457*1b2596b5SMatthias Ringwald 
458*1b2596b5SMatthias Ringwald extern void sysclk_enable_usb(void);
459*1b2596b5SMatthias Ringwald extern void sysclk_disable_usb(void);
460*1b2596b5SMatthias Ringwald 
461*1b2596b5SMatthias Ringwald extern void sysclk_init(void);
462*1b2596b5SMatthias Ringwald 
463*1b2596b5SMatthias Ringwald //! @}
464*1b2596b5SMatthias Ringwald 
465*1b2596b5SMatthias Ringwald /// @cond 0
466*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
467*1b2596b5SMatthias Ringwald #ifdef __cplusplus
468*1b2596b5SMatthias Ringwald }
469*1b2596b5SMatthias Ringwald #endif
470*1b2596b5SMatthias Ringwald /**INDENT-ON**/
471*1b2596b5SMatthias Ringwald /// @endcond
472*1b2596b5SMatthias Ringwald 
473*1b2596b5SMatthias Ringwald #endif /* CHIP_SYSCLK_H_INCLUDED */
474