8de03f6ce1bf075709ead16ebce57cac01ceb4cb
1 /*************************************************************************************
2 * FILE PURPOSE: Provide PLL control functions
3 *************************************************************************************
4 * FILE NAME: pll.c
5 *
6 * DESCRIPTION: Provides functions to control the pll
7 *
8 *************************************************************************************/
9 #include "types.h"
10 #include "ibl.h"
11 #include "pllloc.h"
12 #include "pllapi.h"
13 #include "target.h"
15 #define DEVICE_REG32_W(x,y) *(volatile unsigned int *)(x)=(y)
16 #define DEVICE_REG32_R(x) (*(volatile unsigned int *)(x))
18 #define BOOTBITMASK(x,y) ( ( ( ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 ) ) << ((UINT32)y) )
19 #define BOOT_READ_BITFIELD(z,x,y) (((UINT32)z) & BOOTBITMASK(x,y)) >> (y)
20 #define BOOT_SET_BITFIELD(z,f,x,y) (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) )
23 typedef enum {
24 HW_PLL_DO_NOT_ENABLE_PLL,
25 HW_PLL_ENABLE_PLL
26 } hwPllEnable_t;
28 /*********************************************************************************
29 * FUNCTION PURPOSE: Provide a delay loop
30 *********************************************************************************
31 * DESCRIPTION: Generates a delay, units of cycles
32 *********************************************************************************/
33 void hw_pll_delay (UINT32 del)
34 {
35 UINT32 i;
36 volatile UINT32 j;
38 for (i = j = 0; i < del; i++)
39 asm (" nop ");
41 } /* hw_pll_delay */
44 /**********************************************************************************
45 * FUNCTION PURPOSE: Enables the pll to the specified multiplier
46 **********************************************************************************
47 * DESCRIPTION: Sets up the pll
48 **********************************************************************************/
49 /* latest Sequence as provided by Tom during 10/27 */
50 SINT16 hwPllSetPll (UINT32 pllNum, UINT32 prediv, UINT32 mult, UINT32 postdiv)
51 {
52 UINT32 ctl, reg;
53 UINT32 secctl;
54 UINT32 status;
55 UINT32 alnctl;
56 UINT32 pmult;
57 UINT32 pdiv;
58 UINT32 pllBase;
59 UINT32 i;
60 SINT16 ret = 0;
61 UINT32 pllm_min = 10, plld_min =0, outputdiv = 9;
62 UINT32 div2=3, div5=5, div8=64;
64 /* Mutliplier/divider values of 0 are invalid */
65 if (prediv == 0)
66 prediv = 1;
68 if (mult == 0)
69 mult = 1;
71 if (postdiv == 0)
72 postdiv = 1;
74 /* Get the base address of the pll */
75 pllBase = (UINT32) DEVICE_PLL_BASE(pllNum);
77 /* Wait for Stabilization time (min 100 us) */
78 /* assuming max device speed, 1.4GHz, 1 cycle = 0.714 ns *
79 * so, 100 us = 100000 ns = 140056 cycles */
80 hw_pll_delay (140056);
82 /* Program pllen=0 (pll bypass), pllrst=1 (reset pll), pllsrc = 0 */
83 ctl = DEVICE_REG32_R (pllBase + PLL_REG_CTL);
85 /* Check if PLL BYPASS is turned off previously */
86 secctl = DEVICE_REG32_R (pllBase + PLL_REG_SECCTL);
88 if ( (secctl & PLL_REG_SECCTL_FIELD_BYPASS) != 0 ) {
89 /* PLL BYPASS is turned on */
91 /* Clear the PLLENSRC bit */
92 ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLENSRC);
93 DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
95 /* Clear the PLLEN bit */
96 ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLEN);
97 DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
99 /* Wait for 4 Ref clocks */
100 /* The slowest clock can be at 24MHz, so min:160ns delay */
101 hw_pll_delay(225);
103 /* Put the PLL in Bypass mode to perform the power down mode */
104 secctl = secctl | PLL_REG_SECCTL_FIELD_BYPASS;
105 DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
107 /* Advisory 8: Multiple PLLs May Not Lock After Power-on Reset Issue *
108 * In order to ensure proper PLL startup, the PLL power_down pin needs to be *
109 * toggled. This is accomplished by toggling the PLLPWRDN bit in the PLLCTL *
110 * register. This needs to be done before the main PLL initialization *
111 * sequence */
112 ctl = ctl | 2;
113 DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
115 /* Stay in a loop such that the bit is set for 5 µs (minimum) and *
116 * then clear the bit. */
117 hw_pll_delay (14005); /* waiting 10 us */
119 /* Power up the PLL */
120 ctl = ctl & ~2;
121 DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
123 /* Set the ENSAT Bit */
124 /* Usage Note 9: For optimal PLL operation, the ENSAT bit in the PLL control *
125 * registers for the Main PLL, DDR3 PLL, and PA PLL should be set to 1. *
126 * The PLL initialization sequence in the boot ROM sets this bit to 0 and *
127 * could lead to non-optimal PLL operation. Software can set the bit to the *
128 * optimal value of 1 after boot */
129 reg = DEVICE_REG32_R (DEVICE_MAIN_PLL_CTL_1);
130 reg = reg | (1 << 6);
131 DEVICE_REG32_W (DEVICE_MAIN_PLL_CTL_1, reg);
132 }
134 /* Program the necessary multipliers/dividers and BW adjustments */
135 /* This routine will subtract 1 from the mult value */
136 pmult = chipPllExternalMult(pllNum, mult);
137 pmult = pmult & PLL_REG_PLLM_FIELD_MULTm1;
138 DEVICE_REG32_W (pllBase + PLL_REG_PLLM, pmult);
140 /* Set the PLL Divider */
141 chipPllSetExternalPrediv(pllNum, prediv - 1);
143 /* set the output divide */
144 secctl = BOOT_SET_BITFIELD(secctl, 1 & 0x000f, 22, 19);
145 DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
147 /* set the BWADJ */
148 chipPllExternalBwAdj (pllNum, mult);
150 /* WAIT FOR THE go STAT BIT HERE (50 us) */
151 hw_pll_delay (140056 >> 1);
152 /* wait for the GOSTAT, but don't trap if lock is never read */
153 for (i = 0; i < 100; i++) {
154 hw_pll_delay (300);
155 status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
156 if ( (status & PLL_REG_STATUS_FIELD_GOSTAT) == 0 )
157 break;
158 }
159 /* Enable the pll even if the lock failed. Return a warning. */
160 if (i == 100)
161 ret = -1;
163 /* Set PLL dividers if needed */
164 reg = 0x8000 | (div2 -1);
165 DEVICE_REG32_W (pllBase + PLL_REG_DIV2, reg);
167 reg = 0x8000 | (div5 -1);
168 DEVICE_REG32_W (pllBase + PLL_REG_DIV5, reg);
170 reg = 0x8000 | (div8 -1);
171 DEVICE_REG32_W (pllBase + PLL_REG_DIV8, reg);
173 /* Program ALNCTLn registers */
174 alnctl = DEVICE_REG32_R (pllBase + PLL_REG_ALNCTL);
175 alnctl = alnctl | ((1 << 1) | (1 << 4) | (1 << 7));
176 DEVICE_REG32_W (pllBase + PLL_REG_ALNCTL, alnctl);
178 /* Set GOSET bit in PLLCMD to initiate the GO operation to change the divide *
179 * values and align the SYSCLKs as programmed */
180 reg = DEVICE_REG32_R (pllBase + PLL_REG_CMD);
181 reg = reg | 1;
182 DEVICE_REG32_W (pllBase + PLL_REG_CMD, reg);
184 /* wait for the GOSTAT, but don't trap if lock is never read */
185 for (i = 0; i < 100; i++) {
186 hw_pll_delay (300);
187 status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
188 if ( (status & PLL_REG_STATUS_FIELD_GOSTAT) == 0 )
189 break;
190 }
192 /* Wait for the PLL Reset duration time (min: 1000 ns) */
193 hw_pll_delay (1400);
195 /* Release PLL from Reset */
196 ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLRST);
197 DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
199 /* Wait for PLL Lock time (min 50 us) */
200 hw_pll_delay (140056 >> 1);
202 /* wait for the pll to lock, but don't trap if lock is never read */
203 for (i = 0; i < 100; i++) {
204 hw_pll_delay (2000/7);
205 status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
206 if ( (status & PLL_REG_STATUS_FIELD_LOCK) != 0 )
207 break;
208 }
210 /* Enable the pll even if the lock failed. Return a warning. */
211 if (i == 100)
212 ret = -1;
214 /* Clear the secondary controller bypass bit */
215 secctl = secctl & ~PLL_REG_SECCTL_FIELD_BYPASS;
216 DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
219 /* Set pllen to 1 to enable pll mode */
220 ctl = ctl | PLL_REG_CTL_FIELD_PLLEN;
221 DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
223 return (ret);
224 } /* hwPllSetPll */