1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "clock_freq.h"
32 #include "ccm_imx6sx.h"
33 #include "ccm_analog_imx6sx.h"
34 
35 /*FUNCTION**********************************************************************
36  *
37  * Function Name : get_epit_clock_freq
38  * Description   : Get clock frequency applys to the EPIIT module
39  *
40  *END**************************************************************************/
get_epit_clock_freq(EPIT_Type * base)41 uint32_t get_epit_clock_freq(EPIT_Type* base)
42 {
43     uint32_t root;
44     uint32_t hz;
45     uint32_t divPerclkPodf, divIpgPodf, divAhbPodf, divPeriphClk2Podf;
46 
47     /* Different instance has the same clock root, it's different from i.mx7d. */
48     /* Get the clock root according to the mux node of clock tree. */
49     if(CCM_GetRootMux(CCM, ccmRootPerclkClkSel) == ccmRootmuxPerclkClkOsc24m)
50     {
51         root = ccmRootmuxPerclkClkOsc24m;
52         hz = 24000000;
53         divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
54         divIpgPodf = 0;
55         divAhbPodf = 0;
56         divPeriphClk2Podf = 0;
57     }
58     else if(CCM_GetRootMux(CCM, ccmRootPeriphClkSel) == ccmRootmuxPeriphClkPrePeriphClkSel)
59     {
60         root = CCM_GetRootMux(CCM, ccmRootPrePeriphClkSel);
61         /* Here do not show all the clock root source,
62            if user use other clock root source, such as PLL2_PFD2, please
63            add it as follows according to the clock tree of CCM in reference manual. */
64         switch(root)
65         {
66             case ccmRootmuxPrePeriphClkPll2:
67                 hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllSysControl);
68                 divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
69                 divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
70                 divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
71                 divPeriphClk2Podf = 0;
72                 break;
73             default:
74                 return 0;
75         }
76     }
77     else if(CCM_GetRootMux(CCM, ccmRootPeriphClk2Sel) == ccmRootmuxPeriphClk2OSC24m)
78     {
79         root = ccmRootmuxPeriphClk2OSC24m;
80         hz = 24000000;
81         divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
82         divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
83         divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
84         divPeriphClk2Podf = CCM_GetRootDivider(CCM, ccmRootPeriphClk2Podf);
85     }
86     else
87     {
88         root = CCM_GetRootMux(CCM, ccmRootPll3SwClkSel);
89         /* Here do not show all the clock root source,
90            if user use other clock root source, such as PLL3_BYP, please
91            add it as follows according to the clock tree of CCM in reference manual. */
92         switch(root)
93         {
94             case ccmRootmuxPll3SwClkPll3:
95                 hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllUsb1Control);
96                 divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
97                 divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
98                 divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
99                 divPeriphClk2Podf = CCM_GetRootDivider(CCM, ccmRootPeriphClk2Podf);
100                 break;
101             default:
102                 return 0;
103         }
104     }
105 
106     return hz / (divPerclkPodf + 1) / (divIpgPodf + 1) / (divAhbPodf + 1) / (divPeriphClk2Podf + 1);
107 }
108 
109 /*FUNCTION**********************************************************************
110  *
111  * Function Name : get_I2C_clock_freq
112  * Description   : Get clock frequency applys to the I2C module
113  *
114  *END**************************************************************************/
get_i2c_clock_freq(I2C_Type * base)115 uint32_t get_i2c_clock_freq(I2C_Type* base)
116 {
117     uint32_t root;
118     uint32_t hz;
119     uint32_t divPerclkPodf, divIpgPodf, divAhbPodf, divPeriphClk2Podf;
120 
121     /* Different instance has the same clock root, it's different from i.mx7d. */
122     /* Get the clock root according to the mux node of clock tree. */
123     if(CCM_GetRootMux(CCM, ccmRootPerclkClkSel) == ccmRootmuxPerclkClkOsc24m)
124     {
125         root = ccmRootmuxPerclkClkOsc24m;
126         hz = 24000000;
127         divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
128         divIpgPodf = 0;
129         divAhbPodf = 0;
130         divPeriphClk2Podf = 0;
131     }
132     else if(CCM_GetRootMux(CCM, ccmRootPeriphClkSel) == ccmRootmuxPeriphClkPrePeriphClkSel)
133     {
134         root = CCM_GetRootMux(CCM, ccmRootPrePeriphClkSel);
135         /* Here do not show all the clock root source,
136            if user use other clock root source, such as PLL2_PFD2, please
137            add it as follows according to the clock tree of CCM in reference manual. */
138         switch(root)
139         {
140             case ccmRootmuxPrePeriphClkPll2:
141                 hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllSysControl);
142                 divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
143                 divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
144                 divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
145                 divPeriphClk2Podf = 0;
146                 break;
147             default:
148                 return 0;
149         }
150     }
151     else if(CCM_GetRootMux(CCM, ccmRootPeriphClk2Sel) == ccmRootmuxPeriphClk2OSC24m)
152     {
153         root = ccmRootmuxPeriphClk2OSC24m;
154         hz = 24000000;
155         divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
156         divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
157         divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
158         divPeriphClk2Podf = CCM_GetRootDivider(CCM, ccmRootPeriphClk2Podf);
159     }
160     else
161     {
162         root = CCM_GetRootMux(CCM, ccmRootPll3SwClkSel);
163         /* Here do not show all the clock root source,
164            if user use other clock root source, such as PLL3_BYP, please
165            add it as follows according to the clock tree of CCM in reference manual. */
166         switch(root)
167         {
168             case ccmRootmuxPll3SwClkPll3:
169                 hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllUsb1Control);
170                 divPerclkPodf = CCM_GetRootDivider(CCM, ccmRootPerclkPodf);
171                 divIpgPodf = CCM_GetRootDivider(CCM, ccmRootIpgPodf);
172                 divAhbPodf = CCM_GetRootDivider(CCM, ccmRootAhbPodf);
173                 divPeriphClk2Podf = CCM_GetRootDivider(CCM, ccmRootPeriphClk2Podf);
174                 break;
175             default:
176                 return 0;
177         }
178     }
179 
180     return hz / (divPerclkPodf + 1) / (divIpgPodf + 1) / (divAhbPodf + 1) / (divPeriphClk2Podf + 1);
181 }
182 
183 /*FUNCTION**********************************************************************
184  *
185  * Function Name : get_ecspi_clock_freq
186  * Description   : Get clock frequency applys to the ECSPI module
187  *
188  *END**************************************************************************/
get_ecspi_clock_freq(ECSPI_Type * base)189 uint32_t get_ecspi_clock_freq(ECSPI_Type* base)
190 {
191     uint32_t root;
192     uint32_t hz;
193     uint32_t divEcspiClkPodf, divStatic;
194 
195     if(CCM_GetRootMux(CCM, ccmRootEcspiClkSel) == ccmRootmuxEcspiClkOsc24m)
196     {
197         root = ccmRootmuxEcspiClkOsc24m;
198         hz = 24000000;
199         divEcspiClkPodf = CCM_GetRootDivider(CCM, ccmRootEcspiClkPodf);
200         divStatic = 0;
201     }
202     else
203     {
204         root = CCM_GetRootMux(CCM, ccmRootPll3SwClkSel);
205         /* Here do not show all the clock root source,
206            if user use other clock root source, such as PLL3_BYP, please
207            add it as follows according to the clock tree of CCM in reference manual. */
208         switch(root)
209         {
210             case ccmRootmuxPll3SwClkPll3:
211                 hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllUsb1Control);
212                 divEcspiClkPodf = CCM_GetRootDivider(CCM, ccmRootEcspiClkPodf);
213                 divStatic = 7;
214                 break;
215             default:
216                 return 0;
217         }
218     }
219 
220     return hz / (divEcspiClkPodf + 1) / (divStatic + 1);
221 }
222 
223 /*FUNCTION**********************************************************************
224  *
225  * Function Name : get_uart_clock_freq
226  * Description   : Get clock frequency applys to the UART module
227  *
228  *END**************************************************************************/
get_uart_clock_freq(UART_Type * base)229 uint32_t get_uart_clock_freq(UART_Type* base)
230 {
231     uint32_t root;
232     uint32_t hz;
233     uint32_t divUartClkPodf, divStatic;
234 
235     if(CCM_GetRootMux(CCM, ccmRootUartClkSel) == ccmRootmuxUartClkOsc24m)
236     {
237         root = ccmRootmuxUartClkOsc24m;
238         hz = 24000000;
239         divUartClkPodf = CCM_GetRootDivider(CCM, ccmRootUartClkPodf);
240         divStatic = 0;
241     }
242     else
243     {
244         root = CCM_GetRootMux(CCM, ccmRootPll3SwClkSel);
245         /* Here do not show all the clock root source,
246            if user use other clock root source, such as PLL3_BYP, please
247            add it as follows according to the clock tree of CCM in reference manual. */
248         switch(root)
249         {
250             case ccmRootmuxPll3SwClkPll3:
251                 hz = CCM_ANALOG_GetPllFreq(CCM_ANALOG, ccmAnalogPllUsb1Control);
252                 divUartClkPodf = CCM_GetRootDivider(CCM, ccmRootUartClkPodf);
253                 divStatic = 5;
254                 break;
255             default:
256                 return 0;
257         }
258     }
259 
260     return hz / (divUartClkPodf + 1) / (divStatic + 1);
261 }
262 
263 /*******************************************************************************
264  * EOF
265  ******************************************************************************/
266