xref: /btstack/port/samv71-xplained-atwilc3000/ASF/common/services/clock/samv71/genclk.h (revision 1b2596b5303dd8caeea8565532c93cca8dab8cc4)
1*1b2596b5SMatthias Ringwald /**
2*1b2596b5SMatthias Ringwald  * \file
3*1b2596b5SMatthias Ringwald  *
4*1b2596b5SMatthias Ringwald  * \brief Chip-specific generic clock management.
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_GENCLK_H_INCLUDED
48*1b2596b5SMatthias Ringwald #define CHIP_GENCLK_H_INCLUDED
49*1b2596b5SMatthias Ringwald 
50*1b2596b5SMatthias Ringwald #include <osc.h>
51*1b2596b5SMatthias Ringwald #include <pll.h>
52*1b2596b5SMatthias Ringwald 
53*1b2596b5SMatthias Ringwald /// @cond 0
54*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
55*1b2596b5SMatthias Ringwald #ifdef __cplusplus
56*1b2596b5SMatthias Ringwald extern "C" {
57*1b2596b5SMatthias Ringwald #endif
58*1b2596b5SMatthias Ringwald /**INDENT-ON**/
59*1b2596b5SMatthias Ringwald /// @endcond
60*1b2596b5SMatthias Ringwald 
61*1b2596b5SMatthias Ringwald /**
62*1b2596b5SMatthias Ringwald  * \weakgroup genclk_group
63*1b2596b5SMatthias Ringwald  * @{
64*1b2596b5SMatthias Ringwald  */
65*1b2596b5SMatthias Ringwald 
66*1b2596b5SMatthias Ringwald //! \name Programmable Clock Identifiers (PCK)
67*1b2596b5SMatthias Ringwald //@{
68*1b2596b5SMatthias Ringwald #define GENCLK_PCK_0 0 //!< PCK0 ID
69*1b2596b5SMatthias Ringwald #define GENCLK_PCK_1 1 //!< PCK1 ID
70*1b2596b5SMatthias Ringwald #define GENCLK_PCK_2 2 //!< PCK2 ID
71*1b2596b5SMatthias Ringwald //@}
72*1b2596b5SMatthias Ringwald 
73*1b2596b5SMatthias Ringwald //! \name Programmable Clock Sources (PCK)
74*1b2596b5SMatthias Ringwald //@{
75*1b2596b5SMatthias Ringwald 
76*1b2596b5SMatthias Ringwald enum genclk_source {
77*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_SLCK_RC       = 0,//!< Internal 32kHz RC oscillator as PCK source clock
78*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_SLCK_XTAL     = 1,//!< External 32kHz crystal oscillator as PCK source clock
79*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_SLCK_BYPASS   = 2,//!< External 32kHz bypass oscillator as PCK source clock
80*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_MAINCK_4M_RC  = 3,//!< Internal 4MHz RC oscillator as PCK source clock
81*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_MAINCK_8M_RC  = 4,//!< Internal 8MHz RC oscillator as PCK source clock
82*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_MAINCK_12M_RC = 5,//!< Internal 12MHz RC oscillator as PCK source clock
83*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_MAINCK_XTAL   = 6,//!< External crystal oscillator as PCK source clock
84*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_MAINCK_BYPASS = 7,//!< External bypass oscillator as PCK source clock
85*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_PLLACK        = 8,//!< Use PLLACK as PCK source clock
86*1b2596b5SMatthias Ringwald 	GENCLK_PCK_SRC_MCK           = 9,//!< Use Master Clk as PCK source clock
87*1b2596b5SMatthias Ringwald };
88*1b2596b5SMatthias Ringwald 
89*1b2596b5SMatthias Ringwald //@}
90*1b2596b5SMatthias Ringwald 
91*1b2596b5SMatthias Ringwald //! \name Programmable Clock Prescalers (PCK)
92*1b2596b5SMatthias Ringwald //@{
93*1b2596b5SMatthias Ringwald 
94*1b2596b5SMatthias Ringwald enum genclk_divider {
95*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_1  = PMC_PCK_PRES(0), //!< Set PCK clock prescaler to 1
96*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_2  = PMC_PCK_PRES(1), //!< Set PCK clock prescaler to 2
97*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_4  = PMC_PCK_PRES(2), //!< Set PCK clock prescaler to 4
98*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_8  = PMC_PCK_PRES(3), //!< Set PCK clock prescaler to 8
99*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_16 = PMC_PCK_PRES(4), //!< Set PCK clock prescaler to 16
100*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_32 = PMC_PCK_PRES(5), //!< Set PCK clock prescaler to 32
101*1b2596b5SMatthias Ringwald 	GENCLK_PCK_PRES_64 = PMC_PCK_PRES(6), //!< Set PCK clock prescaler to 64
102*1b2596b5SMatthias Ringwald };
103*1b2596b5SMatthias Ringwald 
104*1b2596b5SMatthias Ringwald //@}
105*1b2596b5SMatthias Ringwald 
106*1b2596b5SMatthias Ringwald struct genclk_config {
107*1b2596b5SMatthias Ringwald 	uint32_t ctrl;
108*1b2596b5SMatthias Ringwald };
109*1b2596b5SMatthias Ringwald 
genclk_config_defaults(struct genclk_config * p_cfg,uint32_t ul_id)110*1b2596b5SMatthias Ringwald static inline void genclk_config_defaults(struct genclk_config *p_cfg,
111*1b2596b5SMatthias Ringwald 		uint32_t ul_id)
112*1b2596b5SMatthias Ringwald {
113*1b2596b5SMatthias Ringwald 	ul_id = ul_id;
114*1b2596b5SMatthias Ringwald 	p_cfg->ctrl = 0;
115*1b2596b5SMatthias Ringwald }
116*1b2596b5SMatthias Ringwald 
genclk_config_read(struct genclk_config * p_cfg,uint32_t ul_id)117*1b2596b5SMatthias Ringwald static inline void genclk_config_read(struct genclk_config *p_cfg,
118*1b2596b5SMatthias Ringwald 		uint32_t ul_id)
119*1b2596b5SMatthias Ringwald {
120*1b2596b5SMatthias Ringwald 	p_cfg->ctrl = PMC->PMC_PCK[ul_id];
121*1b2596b5SMatthias Ringwald }
122*1b2596b5SMatthias Ringwald 
genclk_config_write(const struct genclk_config * p_cfg,uint32_t ul_id)123*1b2596b5SMatthias Ringwald static inline void genclk_config_write(const struct genclk_config *p_cfg,
124*1b2596b5SMatthias Ringwald 		uint32_t ul_id)
125*1b2596b5SMatthias Ringwald {
126*1b2596b5SMatthias Ringwald 	PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
127*1b2596b5SMatthias Ringwald }
128*1b2596b5SMatthias Ringwald 
129*1b2596b5SMatthias Ringwald //! \name Programmable Clock Source and Prescaler configuration
130*1b2596b5SMatthias Ringwald //@{
131*1b2596b5SMatthias Ringwald 
genclk_config_set_source(struct genclk_config * p_cfg,enum genclk_source e_src)132*1b2596b5SMatthias Ringwald static inline void genclk_config_set_source(struct genclk_config *p_cfg,
133*1b2596b5SMatthias Ringwald 		enum genclk_source e_src)
134*1b2596b5SMatthias Ringwald {
135*1b2596b5SMatthias Ringwald 	p_cfg->ctrl &= (~PMC_PCK_CSS_Msk);
136*1b2596b5SMatthias Ringwald 
137*1b2596b5SMatthias Ringwald 	switch (e_src) {
138*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_SLCK_RC:
139*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_SLCK_XTAL:
140*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_SLCK_BYPASS:
141*1b2596b5SMatthias Ringwald 		p_cfg->ctrl |= (PMC_PCK_CSS_SLOW_CLK);
142*1b2596b5SMatthias Ringwald 		break;
143*1b2596b5SMatthias Ringwald 
144*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_4M_RC:
145*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_8M_RC:
146*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_12M_RC:
147*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_XTAL:
148*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_BYPASS:
149*1b2596b5SMatthias Ringwald 		p_cfg->ctrl |= (PMC_PCK_CSS_MAIN_CLK);
150*1b2596b5SMatthias Ringwald 		break;
151*1b2596b5SMatthias Ringwald 
152*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_PLLACK:
153*1b2596b5SMatthias Ringwald 		p_cfg->ctrl |= (PMC_PCK_CSS_PLLA_CLK);
154*1b2596b5SMatthias Ringwald 		break;
155*1b2596b5SMatthias Ringwald 
156*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MCK:
157*1b2596b5SMatthias Ringwald 		p_cfg->ctrl |= (PMC_PCK_CSS_MCK);
158*1b2596b5SMatthias Ringwald 		break;
159*1b2596b5SMatthias Ringwald 
160*1b2596b5SMatthias Ringwald 	default:
161*1b2596b5SMatthias Ringwald 		break;
162*1b2596b5SMatthias Ringwald 	}
163*1b2596b5SMatthias Ringwald }
164*1b2596b5SMatthias Ringwald 
genclk_config_set_divider(struct genclk_config * p_cfg,uint32_t e_divider)165*1b2596b5SMatthias Ringwald static inline void genclk_config_set_divider(struct genclk_config *p_cfg,
166*1b2596b5SMatthias Ringwald 		uint32_t e_divider)
167*1b2596b5SMatthias Ringwald {
168*1b2596b5SMatthias Ringwald 	p_cfg->ctrl &= ~PMC_PCK_PRES_Msk;
169*1b2596b5SMatthias Ringwald 	p_cfg->ctrl |= e_divider;
170*1b2596b5SMatthias Ringwald }
171*1b2596b5SMatthias Ringwald 
172*1b2596b5SMatthias Ringwald //@}
173*1b2596b5SMatthias Ringwald 
genclk_enable(const struct genclk_config * p_cfg,uint32_t ul_id)174*1b2596b5SMatthias Ringwald static inline void genclk_enable(const struct genclk_config *p_cfg, uint32_t ul_id)
175*1b2596b5SMatthias Ringwald {
176*1b2596b5SMatthias Ringwald 	PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
177*1b2596b5SMatthias Ringwald 	pmc_enable_pck(ul_id);
178*1b2596b5SMatthias Ringwald }
179*1b2596b5SMatthias Ringwald 
genclk_disable(uint32_t ul_id)180*1b2596b5SMatthias Ringwald static inline void genclk_disable(uint32_t ul_id)
181*1b2596b5SMatthias Ringwald {
182*1b2596b5SMatthias Ringwald 	pmc_disable_pck(ul_id);
183*1b2596b5SMatthias Ringwald }
184*1b2596b5SMatthias Ringwald 
genclk_enable_source(enum genclk_source e_src)185*1b2596b5SMatthias Ringwald static inline void genclk_enable_source(enum genclk_source e_src)
186*1b2596b5SMatthias Ringwald {
187*1b2596b5SMatthias Ringwald 	switch (e_src) {
188*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_SLCK_RC:
189*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_SLCK_32K_RC)) {
190*1b2596b5SMatthias Ringwald 			osc_enable(OSC_SLCK_32K_RC);
191*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_SLCK_32K_RC);
192*1b2596b5SMatthias Ringwald 		}
193*1b2596b5SMatthias Ringwald 		break;
194*1b2596b5SMatthias Ringwald 
195*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_SLCK_XTAL:
196*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_SLCK_32K_XTAL)) {
197*1b2596b5SMatthias Ringwald 			osc_enable(OSC_SLCK_32K_XTAL);
198*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_SLCK_32K_XTAL);
199*1b2596b5SMatthias Ringwald 		}
200*1b2596b5SMatthias Ringwald 		break;
201*1b2596b5SMatthias Ringwald 
202*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_SLCK_BYPASS:
203*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_SLCK_32K_BYPASS)) {
204*1b2596b5SMatthias Ringwald 			osc_enable(OSC_SLCK_32K_BYPASS);
205*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_SLCK_32K_BYPASS);
206*1b2596b5SMatthias Ringwald 		}
207*1b2596b5SMatthias Ringwald 		break;
208*1b2596b5SMatthias Ringwald 
209*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_4M_RC:
210*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_MAINCK_4M_RC)) {
211*1b2596b5SMatthias Ringwald 			osc_enable(OSC_MAINCK_4M_RC);
212*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_MAINCK_4M_RC);
213*1b2596b5SMatthias Ringwald 		}
214*1b2596b5SMatthias Ringwald 		break;
215*1b2596b5SMatthias Ringwald 
216*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_8M_RC:
217*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_MAINCK_8M_RC)) {
218*1b2596b5SMatthias Ringwald 			osc_enable(OSC_MAINCK_8M_RC);
219*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_MAINCK_8M_RC);
220*1b2596b5SMatthias Ringwald 		}
221*1b2596b5SMatthias Ringwald 		break;
222*1b2596b5SMatthias Ringwald 
223*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_12M_RC:
224*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_MAINCK_12M_RC)) {
225*1b2596b5SMatthias Ringwald 			osc_enable(OSC_MAINCK_12M_RC);
226*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_MAINCK_12M_RC);
227*1b2596b5SMatthias Ringwald 		}
228*1b2596b5SMatthias Ringwald 		break;
229*1b2596b5SMatthias Ringwald 
230*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_XTAL:
231*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_MAINCK_XTAL)) {
232*1b2596b5SMatthias Ringwald 			osc_enable(OSC_MAINCK_XTAL);
233*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_MAINCK_XTAL);
234*1b2596b5SMatthias Ringwald 		}
235*1b2596b5SMatthias Ringwald 		break;
236*1b2596b5SMatthias Ringwald 
237*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MAINCK_BYPASS:
238*1b2596b5SMatthias Ringwald 		if (!osc_is_ready(OSC_MAINCK_BYPASS)) {
239*1b2596b5SMatthias Ringwald 			osc_enable(OSC_MAINCK_BYPASS);
240*1b2596b5SMatthias Ringwald 			osc_wait_ready(OSC_MAINCK_BYPASS);
241*1b2596b5SMatthias Ringwald 		}
242*1b2596b5SMatthias Ringwald 		break;
243*1b2596b5SMatthias Ringwald 
244*1b2596b5SMatthias Ringwald #ifdef CONFIG_PLL0_SOURCE
245*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_PLLACK:
246*1b2596b5SMatthias Ringwald 		pll_enable_config_defaults(0);
247*1b2596b5SMatthias Ringwald 		break;
248*1b2596b5SMatthias Ringwald #endif
249*1b2596b5SMatthias Ringwald 
250*1b2596b5SMatthias Ringwald 	case GENCLK_PCK_SRC_MCK:
251*1b2596b5SMatthias Ringwald 		break;
252*1b2596b5SMatthias Ringwald 
253*1b2596b5SMatthias Ringwald 	default:
254*1b2596b5SMatthias Ringwald 		Assert(false);
255*1b2596b5SMatthias Ringwald 		break;
256*1b2596b5SMatthias Ringwald 	}
257*1b2596b5SMatthias Ringwald }
258*1b2596b5SMatthias Ringwald 
259*1b2596b5SMatthias Ringwald //! @}
260*1b2596b5SMatthias Ringwald 
261*1b2596b5SMatthias Ringwald /// @cond 0
262*1b2596b5SMatthias Ringwald /**INDENT-OFF**/
263*1b2596b5SMatthias Ringwald #ifdef __cplusplus
264*1b2596b5SMatthias Ringwald }
265*1b2596b5SMatthias Ringwald #endif
266*1b2596b5SMatthias Ringwald /**INDENT-ON**/
267*1b2596b5SMatthias Ringwald /// @endcond
268*1b2596b5SMatthias Ringwald 
269*1b2596b5SMatthias Ringwald #endif /* CHIP_GENCLK_H_INCLUDED */
270