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 "ccm_analog_imx7d.h"
32
33 /*******************************************************************************
34 * Code
35 ******************************************************************************/
36
37 /*FUNCTION**********************************************************************
38 *
39 * Function Name : CCM_ANALOG_GetArmPllFreq
40 * Description : Get ARM PLL frequency
41 *
42 *END**************************************************************************/
CCM_ANALOG_GetArmPllFreq(CCM_ANALOG_Type * base)43 uint32_t CCM_ANALOG_GetArmPllFreq(CCM_ANALOG_Type * base)
44 {
45 if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllArmControl))
46 return 24000000ul;
47
48 return 12000000ul * (CCM_ANALOG_PLL_ARM & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK);
49 }
50
51 /*FUNCTION**********************************************************************
52 *
53 * Function Name : CCM_ANALOG_GetSysPllFreq
54 * Description : Get system PLL frequency
55 *
56 *END**************************************************************************/
CCM_ANALOG_GetSysPllFreq(CCM_ANALOG_Type * base)57 uint32_t CCM_ANALOG_GetSysPllFreq(CCM_ANALOG_Type * base)
58 {
59 if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPll480Control))
60 return 24000000ul;
61
62 if (CCM_ANALOG_PLL_480 & CCM_ANALOG_PLL_480_DIV_SELECT_MASK)
63 return 528000000ul;
64 else
65 return 480000000ul;
66 }
67
68 /*FUNCTION**********************************************************************
69 *
70 * Function Name : CCM_ANALOG_GetDdrPllFreq
71 * Description : Get DDR PLL frequency
72 *
73 *END**************************************************************************/
CCM_ANALOG_GetDdrPllFreq(CCM_ANALOG_Type * base)74 uint32_t CCM_ANALOG_GetDdrPllFreq(CCM_ANALOG_Type * base)
75 {
76 uint8_t divSelect, divTestSelect;
77 float factor;
78
79 if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllDdrControl))
80 return 24000000ul;
81
82 divSelect = CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG) & CCM_ANALOG_PLL_DDR_DIV_SELECT_MASK;
83 divTestSelect = (CCM_ANALOG_PLL_DDR_REG(CCM_ANALOG) & CCM_ANALOG_PLL_DDR_TEST_DIV_SELECT_MASK) >>
84 CCM_ANALOG_PLL_DDR_TEST_DIV_SELECT_SHIFT;
85
86 switch (divTestSelect)
87 {
88 case 0x0:
89 divTestSelect = 2;
90 break;
91 case 0x1:
92 divTestSelect = 1;
93 break;
94 case 0x2:
95 case 0x3:
96 divTestSelect = 0;
97 break;
98 }
99
100 if (CCM_ANALOG_PLL_DDR_SS_REG(base) & CCM_ANALOG_PLL_DDR_SS_ENABLE_MASK)
101 {
102 factor = ((float)(CCM_ANALOG_PLL_DDR_SS_REG(base) & CCM_ANALOG_PLL_DDR_SS_STEP_MASK)) /
103 ((float)(CCM_ANALOG_PLL_DDR_DENOM_REG(base) & CCM_ANALOG_PLL_DDR_DENOM_B_MASK)) *
104 ((float)(CCM_ANALOG_PLL_DDR_NUM_REG(base) & CCM_ANALOG_PLL_DDR_NUM_A_MASK));
105 return (uint32_t)((24000000ul >> divTestSelect) * (divSelect + factor));
106 }
107 else
108 {
109 return (24000000ul >> divTestSelect) * divSelect;
110 }
111 }
112
113 /*FUNCTION**********************************************************************
114 *
115 * Function Name : CCM_ANALOG_GetEnetPllFreq
116 * Description : Get Ethernet PLL frequency
117 *
118 *END**************************************************************************/
CCM_ANALOG_GetEnetPllFreq(CCM_ANALOG_Type * base)119 uint32_t CCM_ANALOG_GetEnetPllFreq(CCM_ANALOG_Type * base)
120 {
121 if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllEnetControl))
122 return 24000000ul;
123
124 return 1000000000ul;
125 }
126
127 /*FUNCTION**********************************************************************
128 *
129 * Function Name : CCM_ANALOG_GetAudioPllFreq
130 * Description : Get Ethernet PLL frequency
131 *
132 *END**************************************************************************/
CCM_ANALOG_GetAudioPllFreq(CCM_ANALOG_Type * base)133 uint32_t CCM_ANALOG_GetAudioPllFreq(CCM_ANALOG_Type * base)
134 {
135 uint8_t divSelect, divPostSelect, divTestSelect;
136 float factor;
137
138 if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllAudioControl))
139 return 24000000ul;
140
141 divSelect = CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_AUDIO_DIV_SELECT_MASK;
142 divPostSelect = (CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_AUDIO_POST_DIV_SEL_MASK) >>
143 CCM_ANALOG_PLL_AUDIO_POST_DIV_SEL_SHIFT;
144 divTestSelect = (CCM_ANALOG_PLL_AUDIO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_AUDIO_TEST_DIV_SELECT_MASK) >>
145 CCM_ANALOG_PLL_AUDIO_TEST_DIV_SELECT_SHIFT;
146
147 switch (divPostSelect)
148 {
149 case 0x0:
150 case 0x2:
151 divPostSelect = 0;
152 break;
153 case 0x1:
154 divPostSelect = 1;
155 break;
156 case 0x3:
157 divPostSelect = 2;
158 break;
159 }
160
161 switch (divTestSelect)
162 {
163 case 0x0:
164 divTestSelect = 2;
165 break;
166 case 0x1:
167 divTestSelect = 1;
168 break;
169 case 0x2:
170 case 0x3:
171 divTestSelect = 0;
172 break;
173 }
174
175 if (CCM_ANALOG_PLL_AUDIO_SS_REG(base) & CCM_ANALOG_PLL_AUDIO_SS_ENABLE_MASK)
176 {
177 factor = ((float)(CCM_ANALOG_PLL_AUDIO_SS_REG(base) & CCM_ANALOG_PLL_AUDIO_SS_STEP_MASK)) /
178 ((float)(CCM_ANALOG_PLL_AUDIO_DENOM_REG(base) & CCM_ANALOG_PLL_AUDIO_DENOM_B_MASK)) *
179 ((float)(CCM_ANALOG_PLL_AUDIO_NUM_REG(base) & CCM_ANALOG_PLL_AUDIO_NUM_A_MASK));
180 return (uint32_t)(((24000000ul >> divTestSelect) >> divPostSelect) * (divSelect + factor));
181 }
182 else
183 {
184 return ((24000000ul >> divTestSelect) >> divPostSelect) * divSelect;
185 }
186 }
187
188 /*FUNCTION**********************************************************************
189 *
190 * Function Name : CCM_ANALOG_GetVideoPllFreq
191 * Description : Get Ethernet PLL frequency
192 *
193 *END**************************************************************************/
CCM_ANALOG_GetVideoPllFreq(CCM_ANALOG_Type * base)194 uint32_t CCM_ANALOG_GetVideoPllFreq(CCM_ANALOG_Type * base)
195 {
196 uint8_t divSelect, divPostSelect, divTestSelect;
197 float factor;
198
199 if (CCM_ANALOG_IsPllBypassed(base, ccmAnalogPllVideoControl))
200 return 24000000ul;
201
202 divSelect = CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_VIDEO_DIV_SELECT_MASK;
203 divPostSelect = (CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_VIDEO_POST_DIV_SEL_MASK) >>
204 CCM_ANALOG_PLL_VIDEO_POST_DIV_SEL_SHIFT;
205 divTestSelect = (CCM_ANALOG_PLL_VIDEO_REG(CCM_ANALOG) & CCM_ANALOG_PLL_VIDEO_TEST_DIV_SELECT_MASK) >>
206 CCM_ANALOG_PLL_VIDEO_TEST_DIV_SELECT_SHIFT;
207
208 switch (divPostSelect)
209 {
210 case 0x0:
211 case 0x2:
212 divPostSelect = 0;
213 break;
214 case 0x1:
215 divPostSelect = 1;
216 break;
217 case 0x3:
218 divPostSelect = 2;
219 break;
220 }
221
222 switch (divTestSelect)
223 {
224 case 0x0:
225 divTestSelect = 2;
226 break;
227 case 0x1:
228 divTestSelect = 1;
229 break;
230 case 0x2:
231 case 0x3:
232 divTestSelect = 0;
233 break;
234 }
235
236 if (CCM_ANALOG_PLL_VIDEO_SS_REG(base) & CCM_ANALOG_PLL_VIDEO_SS_ENABLE_MASK)
237 {
238 factor = ((float)(CCM_ANALOG_PLL_VIDEO_SS_REG(base) & CCM_ANALOG_PLL_VIDEO_SS_STEP_MASK)) /
239 ((float)(CCM_ANALOG_PLL_VIDEO_DENOM_REG(base) & CCM_ANALOG_PLL_VIDEO_DENOM_B_MASK)) *
240 ((float)(CCM_ANALOG_PLL_VIDEO_NUM_REG(base) & CCM_ANALOG_PLL_VIDEO_NUM_A_MASK));
241 return (uint32_t)(((24000000ul >> divTestSelect) >> divPostSelect) * (divSelect + factor));
242 }
243 else
244 {
245 return ((24000000ul >> divTestSelect) >> divPostSelect) * divSelect;
246 }
247 }
248
249 /*FUNCTION**********************************************************************
250 *
251 * Function Name : CCM_ANALOG_GetPfdFreq
252 * Description : Get PFD frequency
253 *
254 *END**************************************************************************/
CCM_ANALOG_GetPfdFreq(CCM_ANALOG_Type * base,uint32_t pfdFrac)255 uint32_t CCM_ANALOG_GetPfdFreq(CCM_ANALOG_Type * base, uint32_t pfdFrac)
256 {
257 uint32_t main, frac;
258
259 /* PFD should work with system PLL without bypass */
260 assert(!CCM_ANALOG_IsPllBypassed(base, ccmAnalogPll480Control));
261
262 main = CCM_ANALOG_GetSysPllFreq(base);
263 frac = CCM_ANALOG_GetPfdFrac(base, pfdFrac);
264
265 return main / frac * 18;
266 }
267
268 /*******************************************************************************
269 * EOF
270 ******************************************************************************/
271