[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_1_eng / packages / ti / board / src / evmKeystone / board_pll.c
1 /******************************************************************************
2 * Copyright (c) 2015 Texas Instruments Incorporated - http://www.ti.com
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 *****************************************************************************/
34 #include "board_internal.h"
35 #include "keystone_pll.h"
37 static CSL_PllcHandle pllcReg = (CSL_PllcHandle)PLLCTL_REGS_BASE_ADDR;
39 static void pllc_delay(uint32_t loops)
40 {
41 while (loops--) {
42 asm(" NOP");
43 }
44 }
46 static void wait_for_completion(const pllcConfig *data)
47 {
48 int i;
49 for (i = 0; i < 100; i++) {
50 pllc_delay(450);
51 if ((pllctl_reg_read(PLLSTAT) & PLLSTAT_GO) == 0)
52 break;
53 }
54 }
57 void init_pll(const pllcConfig *data)
58 {
59 uint32_t tmp, tmp_ctl, pllm, plld, pllod, bwadj;
61 pllm = data->pll_m - 1;
62 plld = (data->pll_d - 1) & PLL_DIV_MASK;
63 pllod = (data->pll_od - 1) & PLL_CLKOD_MASK;
65 if (data->pll == CSL_PLL_SYS) {
66 /* The requered delay before main PLL configuration */
67 pllc_delay(210000);
69 tmp = pllctl_reg_read(SECCTL);
71 if (tmp & (PLLCTL_BYPASS)) {
72 setbits32(keystonePllcRegs[data->pll].reg1,
73 PLLCTL_ENSAT);
75 pllctl_reg_clrbits(PLLCTL, PLLCTL_PLLEN |
76 PLLCTL_PLLENSRC);
77 pllc_delay(340);
79 pllctl_reg_setbits(SECCTL, PLLCTL_BYPASS);
80 pllctl_reg_setbits(PLLCTL, PLLCTL_PLLPWRDN);
81 pllc_delay(21000);
83 pllctl_reg_clrbits(PLLCTL, PLLCTL_PLLPWRDN);
84 } else {
85 pllctl_reg_clrbits(PLLCTL, PLLCTL_PLLEN |
86 PLLCTL_PLLENSRC);
87 pllc_delay(340);
88 }
89 /* */
90 #ifdef SOC_K2G
91 /* Reset PLL */
92 pllctl_reg_setbits(PLLCTL, PLLCTL_PLLRST);
93 #endif
95 pllctl_reg_write(PLLM, pllm & PLLM_MULT_LO_MASK);
97 clrsetbits32(keystonePllcRegs[data->pll].reg0,
98 PLLM_MULT_HI_SMASK, (pllm << 6));
100 /* Set the BWADJ (12 bit field) */
101 tmp_ctl = pllm >> 1; /* Divide the pllm by 2 */
102 clrsetbits32(keystonePllcRegs[data->pll].reg0,
103 PLL_BWADJ_LO_SMASK,
104 (tmp_ctl << PLL_BWADJ_LO_SHIFT));
105 clrsetbits32(keystonePllcRegs[data->pll].reg1,
106 PLL_BWADJ_HI_MASK,
107 (tmp_ctl >> 8));
109 /*
110 * Set the pll divider (6 bit field) *
111 * PLLD[5:0] is located in MAINPLLCTL0
112 */
113 clrsetbits32(keystonePllcRegs[data->pll].reg0,
114 PLL_DIV_MASK, plld);
116 /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
117 pllctl_reg_rmw(SECCTL, PLL_CLKOD_SMASK,
118 (pllod << PLL_CLKOD_SHIFT));
119 wait_for_completion(data);
121 #ifndef SOC_K2G
122 pllctl_reg_write(PLLDIV1_3[0], PLLM_RATIO_DIV1);
123 pllctl_reg_write(PLLDIV1_3[1], PLLM_RATIO_DIV2);
124 pllctl_reg_write(PLLDIV1_3[2], PLLM_RATIO_DIV3);
125 pllctl_reg_write(PLLDIV4_16[0], PLLM_RATIO_DIV4);
126 pllctl_reg_write(PLLDIV4_16[1], PLLM_RATIO_DIV5);
128 pllctl_reg_setbits(ALNCTL, 0x1f);
129 #endif
130 /*
131 * Set GOSET bit in PLLCMD to initiate the GO operation
132 * to change the divide
133 */
134 pllctl_reg_setbits(PLLCMD, PLLSTAT_GO);
135 pllc_delay(1500); /* wait for the phase adj */
136 wait_for_completion(data);
138 #ifndef SOC_K2G
139 /* Reset PLL */
140 pllctl_reg_setbits(PLLCTL, PLLCTL_PLLRST);
141 #endif
142 pllc_delay(21000); /* Wait for a minimum of 7 us*/
143 pllctl_reg_clrbits(PLLCTL, PLLCTL_PLLRST);
144 pllc_delay(105000); /* Wait for PLL Lock time (min 50 us) */
146 pllctl_reg_clrbits(SECCTL, PLLCTL_BYPASS);
148 pllctl_reg_setbits(PLLCTL, PLLCTL_PLLEN);
150 #if defined (SOC_K2H) || (SOC_K2K) || (SOC_K2L) || (SOC_K2G)
151 } else if (data->pll == CSL_PLL_ARM) {
152 bwadj = pllm >> 1;
153 /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */
154 setbits32(keystonePllcRegs[data->pll].reg0, PLLCTL_BYPASS);
155 /*
156 * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass)
157 * only applicable for Kepler
158 */
159 clrbits32(KS2_CHIP_MISC1, KS2_ARM_PLL_EN);
160 /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */
161 setbits32(keystonePllcRegs[data->pll].reg1 ,
162 PLL_PLLRST | PLLCTL_ENSAT);
164 /*
165 * 3 Program PLLM and PLLD in PLLCTL0 register
166 * 4 Program BWADJ[7:0] in PLLCTL0 and BWADJ[11:8] in
167 * PLLCTL1 register. BWADJ value must be set
168 * to ((PLLM + 1) >> 1) รข?? 1)
169 */
170 tmp = ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) |
171 (pllm << 6) |
172 (plld & PLL_DIV_MASK) |
173 (pllod << PLL_CLKOD_SHIFT) | PLLCTL_BYPASS;
174 HW_WR_REG32(keystonePllcRegs[data->pll].reg0, tmp);
176 /* Set BWADJ[11:8] bits */
177 tmp = HW_RD_REG32(keystonePllcRegs[data->pll].reg1);
178 tmp &= ~(PLL_BWADJ_HI_MASK);
179 tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK);
180 HW_WR_REG32(keystonePllcRegs[data->pll].reg1, tmp);
181 /*
182 * 5 Wait for at least 5 us based on the reference
183 * clock (PLL reset time)
184 */
185 pllc_delay(21000); /* Wait for a minimum of 7 us*/
187 /* 6 In PLLCTL1, write PLLRST = 0 (PLL reset is released) */
188 clrbits32(keystonePllcRegs[data->pll].reg1, PLL_PLLRST);
189 /*
190 * 7 Wait for at least 500 * REFCLK cycles * (PLLD + 1)
191 * (PLL lock time)
192 */
193 pllc_delay(105000);
194 /* 8 disable bypass */
195 clrbits32(keystonePllcRegs[data->pll].reg0, PLLCTL_BYPASS);
196 /*
197 * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass)
198 * only applicable for Kepler
199 */
200 setbits32(KS2_CHIP_MISC1, KS2_ARM_PLL_EN);
201 #endif
202 } else {
203 setbits32(keystonePllcRegs[data->pll].reg1, PLLCTL_ENSAT);
204 /*
205 * process keeps state of Bypass bit while programming
206 * all other DDR PLL settings
207 */
208 tmp = HW_RD_REG32(keystonePllcRegs[data->pll].reg0);
209 tmp &= PLLCTL_BYPASS; /* clear everything except Bypass */
210 setbits32(keystonePllcRegs[data->pll].reg0, PLLCTL_BYPASS);
212 /*
213 * Set the BWADJ[7:0], PLLD[5:0] and PLLM to PLLCTL0,
214 * bypass disabled
215 */
216 bwadj = pllm >> 1;
217 tmp |= ((bwadj & PLL_BWADJ_LO_MASK) << PLL_BWADJ_LO_SHIFT) |
218 (pllm << PLL_MULT_SHIFT) |
219 (plld & PLL_DIV_MASK) |
220 (pllod << PLL_CLKOD_SHIFT);
221 HW_WR_REG32(keystonePllcRegs[data->pll].reg0, tmp);
223 /* Set BWADJ[11:8] bits */
224 tmp = HW_RD_REG32(keystonePllcRegs[data->pll].reg1);
225 tmp &= ~(PLL_BWADJ_HI_MASK);
226 tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK);
228 HW_WR_REG32(keystonePllcRegs[data->pll].reg1, tmp);
230 /* Reset bit: bit 14 for both DDR3 & PASS PLL */
231 tmp = PLL_PLLRST;
232 /* Set RESET bit = 1 */
233 setbits32(keystonePllcRegs[data->pll].reg1, tmp);
234 /* Wait for a minimum of 7 us*/
235 pllc_delay(21000);
236 /* Clear RESET bit */
237 clrbits32(keystonePllcRegs[data->pll].reg1, tmp);
238 pllc_delay(105000);
240 /* clear BYPASS (Enable PLL Mode) */
241 clrbits32(keystonePllcRegs[data->pll].reg0, PLLCTL_BYPASS);
242 pllc_delay(21000); /* Wait for a minimum of 7 us*/
243 #if !defined (SOC_C6657) && !defined (SOC_K2G)
244 if (data->pll == CSL_PLL_PA)
245 {
246 setbits32(keystonePllcRegs[data->pll].reg1, PA_PLL_SEL);
247 pllc_delay(21000); /* Wait for a minimum of 7 us*/
248 }
249 #endif
250 }
252 /*
253 * This is required to provide a delay between multiple
254 * consequent PPL configurations
255 */
256 pllc_delay(210000);
257 }
259 /* Set the desired DDR3 configuration -- assumes 66.67 MHz DDR3 clock input */
260 Board_STATUS Board_PLLInit()
261 {
262 uint32_t i;
263 uint32_t numConfigs;
265 numConfigs = Board_getNumPllcConfigs();
266 for (i = 0; i < numConfigs; i++)
267 init_pll(&pllcConfigs[i]);
269 return BOARD_SOK;
270 }