[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_0_eng / packages / ti / platform_org / evmk2g / platform_lib / src / evmc66x.c
1 /*
2 * Copyright (c) 2010-2015, Texas Instruments Incorporated
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the 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 "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
34 /**
35 *
36 * \file evmc66x.c
37 *
38 * \brief This contains C66x specific functions.
39 *
40 ******************************************************************************/
42 /************************
43 * Include Files
44 ************************/
45 #include "platform_internal.h"
47 /******************************************************************************
48 *
49 * Function: pll_delay
50 *
51 * Description: Delay function
52 *
53 * Parameters: uint32_t ix - Delay value
54 *
55 * Return Value: None
56 *
57 ******************************************************************************/
58 static void pll_delay (uint32_t ix)
59 {
60 while (ix--) {
61 asm(" NOP");
62 }
63 }
65 /******************************************************************************
66 *
67 * Function: SetModulePllConfig
68 *
69 * Description: Configures module specific PLL
70 *
71 * Parameters: volatile uint32_t *pllCtl0 - PLL CTL0 register address
72 * volatile uint32_t *pllCtl1 - PLL CTL1 register address
73 * pll_init_data *data - PLL configuration values
74 * char *name - Name of the module
75 *
76 * Return Value: CSL_Status
77 *
78 ******************************************************************************/
79 static CSL_Status SetModulePllConfig (volatile uint32_t *pllCtl0,
80 volatile uint32_t *pllCtl1,
81 pll_init_data *data, char *name)
82 {
83 uint32_t pllctl0val;
84 uint32_t pllm = data->pll_m;
85 uint32_t plld = data->pll_d;
86 uint32_t clkod = data->pll_od;
87 uint32_t temp;
89 /* Unlock the Boot Config */
90 CSL_BootCfgUnlockKicker();
92 /* Usage Note 9: For optimal PLL operation, the ENSAT bit in the PLL control *
93 * registers should be set to 1. *
94 * The PLL initialization sequence in the boot ROM sets this bit to 0 and *
95 * could lead to non-optimal PLL operation. Software can set the bit to the *
96 * optimal value of 1 after boot *
97 * PLLCTL1_REG Bit map *
98 * |31...7 |6 |5 4 |3...0 | *
99 * |Reserved |ENSAT |Reserved |BWADJ[11:8]| */
101 *pllCtl1 |= 0x00000040;
103 /* Put the PLL in Bypass Mode *
104 * PLLCTL0_REG Bit map *
105 * |31...24 |23 |22...19 |18...6 |5...0 | *
106 * |BWADJ[7:0] |BYPASS |Reserved |PLLM |PLLD | */
108 *pllCtl0 |= 0x00800000; /* Set the Bit 23 */
110 /* Program the necessary multipliers/dividers and BW adjustments */
111 /* Set the divider values */
112 *pllCtl0 &= ~(MODULE_PLL_CLKD_MASK);
113 *pllCtl0 |= (plld & MODULE_PLL_CLKD_MASK);
115 /* Set the Multiplier values */
116 *pllCtl0 &= ~(MODULE_PLL_CLKM_MASK);
117 *pllCtl0 |= ((pllm << 6) & MODULE_PLL_CLKM_MASK);
119 /* Set CLKOD value */
120 *pllCtl0 &= ~(MODULE_PLL_CLKOD_MASK);
121 *pllCtl0 |= ((clkod << 19) & MODULE_PLL_CLKOD_MASK);
123 /* Set the BWADJ */
124 temp = ((pllm + 1) >> 1) - 1;
125 *pllCtl0 &= ~(0xFF000000);
126 *pllCtl0 |= ((temp << 24) & 0xFF000000);
127 *pllCtl1 &= ~(0x0000000F);
128 *pllCtl1 |= ((temp >> 8) & 0x0000000F);
130 /* In PLL Controller, reset the PLL (bit 14), in PLLCTL1_REG register */
131 *pllCtl1 |= 0x00004000;
133 /* Wait for PLL to lock min 5 micro seconds */
134 pll_delay(7000);
136 /* In PLLCTL1_REG, write PLLRST = 0 to bring PLL out of reset */
137 *pllCtl1 &= ~(0x00004000);
139 /* Wait for PLL to lock min 50 micro seconds*/
140 pll_delay(70000);
142 /* Put the PLL in PLL Mode *
143 * PLLCTL0_REG Bit map *
144 * |31...24 |23 |22...19 |18...6 |5...0 | *
145 * |BWADJ[7:0] |BYPASS |Reserved |PLLM |PLLD | */
146 *pllCtl0 &= ~(0x00800000); /* Reset the Bit 23 */
148 pllctl0val = *pllCtl0;
150 IFPRINT(platform_write("%s PLL CTL0 Register Value = %d\n", name, *pllCtl0));
151 IFPRINT(platform_write("%s PLL CTL1 Register Value = %d\n", name, *pllCtl1));
153 /* Tells the multiplier value for the PLL */
154 pllm = (((pllctl0val & MODULE_PLL_CLKM_MASK) >> 6) + 1);
155 IFPRINT(platform_write("%s PLL programmable multiplier = %d\n", name, pllm));
157 /* Tells the divider value for the PLL */
158 plld = (((pllctl0val & MODULE_PLL_CLKD_MASK) >> 0) + 1);
159 IFPRINT(platform_write("%s PLL programmable divider = %d\n", name, plld));
161 /* Tells the output divider value for the PLL */
162 clkod = (((pllctl0val & MODULE_PLL_CLKOD_MASK) >> 0) + 1);
163 IFPRINT(platform_write("%s PLL output divider = %d\n", name, clkod));
165 IFPRINT(platform_write("%s PLL Setup... Done.\n",name));
167 return (CSL_SOK);
168 }
170 /******************************************************************************
171 *
172 * Function: prog_pll1_values
173 *
174 * Description: Configures PLL registers
175 *
176 * Parameters: PllcHwSetup *hwSetup - PLL setup values
177 *
178 * Return Value: Status
179 *
180 ******************************************************************************/
181 int prog_pll1_values (PllcHwSetup *hwSetup)
182 {
183 uint32_t temp;
185 /* Check the Range for Multiplier and Divider here */
186 if ((hwSetup->pllM > 4095) ||
187 (hwSetup->preDiv > 63) ||
188 (hwSetup->postDiv > 15))
189 {
190 return -1;
191 }
193 /* Set the PLL Multiplier, Divider, BWADJ *
194 * The PLLM[5:0] bits of the multiplier are controlled by the PLLM Register *
195 * inside the PLL Controller and the PLLM[12:6] bits are controlled by the *
196 * chip-level MAINPLLCTL0 Register. *
197 * PLL Control Register (PLLM) Layout *
198 * |31...6 |5...0 | *
199 * |Reserved |PLLM | *
200 * *
201 * Main PLL Control Register (MAINPLLCTL0) *
202 * |31...24 |23...19 |18...12 | 11...6 |5...0 | *
203 * |BWADJ[7:0]| Reserved |PLLM[12:6] | Reserved | PLLD | */
205 /* Set pll multiplier (13 bit field) */
206 PLLM_REG = (hwSetup->pllM & 0x0000003F); /* bits[5:0] */
207 temp = (hwSetup->pllM & 0x1FC0) >> 6; /* bits[12:6] */
208 MAINPLLCTL0_REG &=~(0x0007F000); /*Clear PLLM field */
209 MAINPLLCTL0_REG |=((temp << 12) & 0x0007F000);
211 /* Set the BWADJ (12 bit field) *
212 * BWADJ[11:8] and BWADJ[7:0] are located in MAINPLLCTL0 and MAINPLLCTL1 *
213 * registers. BWADJ[11:0] should be programmed to a value equal to half of *
214 * PLLM[12:0] value (round down if PLLM has an odd value) *
215 * Example: If PLLM = 15, then BWADJ = 7 */
216 temp = ((hwSetup->pllM + 1) >> 1) - 1; /* Divide the pllm by 2 */
217 MAINPLLCTL0_REG &= ~(0xFF000000); /* Clear the BWADJ Field */
218 MAINPLLCTL0_REG |= ((temp << 24) & 0xFF000000);
219 MAINPLLCTL1_REG &= ~(0x0000000F); /* Clear the BWADJ field */
220 MAINPLLCTL1_REG |= ((temp >> 8) & 0x0000000F);
222 /* Set the pll divider (6 bit field) *
223 * PLLD[5:0] is located in MAINPLLCTL0 */
224 MAINPLLCTL0_REG &= ~(0x0000003F); /* Clear the Field */
225 MAINPLLCTL0_REG |= (hwSetup->preDiv & 0x0000003F);
227 /* Set the OUTPUT DIVIDE (4 bit field) in SECCTL */
228 SECCTL_REG &= ~(0x00780000); /* Clear the field */
229 SECCTL_REG |= ((hwSetup->postDiv << 19) & 0x00780000);
231 IFPRINT(platform_write("Main PLL CTL0 Register Value = %d\n", MAINPLLCTL0_REG));
232 IFPRINT(platform_write("Main PLL CTL1 Register Value = %d\n", MAINPLLCTL1_REG));
234 temp = (PLLM_REG & 0x0000003F); /* bits[5:0] */
235 temp |= (MAINPLLCTL0_REG & 0x0007F000) >> 6; /* bits[12:6] */
237 IFPRINT(platform_write("Main PLL Multiplier Value = %d\n", (temp + 1)));
238 IFPRINT(platform_write("Main PLL Divider Value = %d\n",
239 ((MAINPLLCTL0_REG & 0x3F) + 1)));
240 IFPRINT(platform_write("Main PLL Output Divider Value = %d\n",
241 (((SECCTL_REG & 0x00780000) >> 19) + 1)));
243 return (0);
244 }
246 /******************************************************************************
247 *
248 * Function: CorePllcHwSetup
249 *
250 * Description: Configures Core PLL
251 *
252 * Parameters: PllcHwSetup *hwSetup - PLL setup values
253 *
254 * Return Value: CSL_Status
255 *
256 ******************************************************************************/
257 CSL_Status CorePllcHwSetup (PllcHwSetup *hwSetup)
258 {
259 CSL_Status status = CSL_SOK;
260 volatile uint32_t i;
261 volatile uint32_t loopCount;
262 uint32_t temp;
264 /* Unlock the Boot Config */
265 CSL_BootCfgUnlockKicker();
268 /* Wait for Stabilization time (min 100 us) *
269 * The below loop is good enough for the Gel file to get minimum of *
270 * 100 micro seconds, this should be appropriately modified for port *
271 * to a C function *
272 * Minimum delay in GEL can be 1 milli seconds, so program to 1ms=1000us, *
273 * more than required, but should be Okay */
274 pll_delay(140056);
276 /* If PLL previously configured in RBL, avoid di/dt supply excursion by *
277 * matching PLL output to RefClk rate *
278 * if RBL configures the PLL, the BYPASS bit would be set to '0' */
279 temp = SECCTL_REG & 0x00800000; /* Check the Bit 23 value */
281 if (temp != 0) {
282 /* PLL BYPASS is enabled, we assume if not in Bypass ENSAT = 1 */
284 /* Usage Note 9: For optimal PLL operation, the ENSAT bit in the PLL control *
285 * registers for the Main PLL should be set to 1. *
286 * The PLL initialization sequence in the boot ROM sets this bit to 0 and *
287 * could lead to non-optimal PLL operation. Software can set the bit to the *
288 * optimal value of 1 after boot *
289 * Ref: http://www.ti.com/lit/er/sprz334b/sprz334b.pdf *
290 * |31...7 |6 |5 4 |3...0 | *
291 * |Reserved |ENSAT |Reserved |BWADJ[11:8]| */
293 MAINPLLCTL1_REG = MAINPLLCTL1_REG | 0x00000040;
295 /* Clear PLLEN bit */
296 PLLCTL_REG &= ~(1 << 0);
298 /* Clear PLLENSRC bit */
299 PLLCTL_REG &= ~(1 << 5);
301 /* Wait for 4 RefClks *
302 * Assuming slowest Ref clock of 24MHz, min: 160 ns delay */
303 pll_delay(225);
305 /* Bypass needed to perform PWRDN cycle for C6670 and C6678 *
306 * Needed on all devices when in NOBOOT, I2C or SPI boot modes *
307 * Ref: Figure 4-2 of http://www.ti.com/lit/ug/sprugv2a/sprugv2a.pdf *
308 * PLL Secondary Control Register (SECCTL) Layout *
309 * |31...24 |23 |22...19 |18...0 | *
310 * |Reserved |BYPASS |OUTPUT DIVIDE |Reserved | */
311 SECCTL_REG |= 0x00800000; /* Set the Bit 23 */
313 /* Advisory 8: Multiple PLLs May Not Lock After Power-on Reset Issue *
314 * In order to ensure proper PLL startup, the PLL power_down pin needs to be *
315 * toggled. This is accomplished by toggling the PLLPWRDN bit in the PLLCTL *
316 * register. This needs to be done before the main PLL initialization *
317 * sequence *
318 * Ref: Figure 4-1 of http://www.ti.com/lit/ug/sprugv2a/sprugv2a.pdf *
319 * PLL Control Register (PLLCTL) Layout *
320 * |31...4 |3 |2 |1 |0 | *
321 * |Reserved |PLLRST |Reserved |PLLPWRDN |Reserved | */
323 PLLCTL_REG |= 0x00000002; /*Power Down the PLL */
325 /* Stay in a loop such that the bit is set for 5 us (minimum) and *
326 * then clear the bit. */
328 pll_delay(14005);
330 /* Power up the PLL */
331 PLLCTL_REG &= ~(0x00000002);
333 }
334 else // PLL bypass disabled
335 {
336 /* Clear PLLEN bit */
337 PLLCTL_REG &= ~(1 << 0);
339 /* Clear PLLENSRC bit */
340 PLLCTL_REG &= ~(1 << 5);
342 /* Wait for 4 RefClks *
343 * Assuming slowest Ref clock of 24MHz, min: 160 ns delay */
344 pll_delay(225);
345 }
347 /* Program the necessary multipliers/dividers and BW adjustments */
348 prog_pll1_values(hwSetup);
350 /* go stat bit needs to be zero here */
351 /* Read the GOSTAT bit in PLLSTAT to make sure the bit returns to 0 to *
352 * indicate that the GO operation has completed */
353 /* wait for the GOSTAT, but don't trap if lock is never read */
354 for (i = 0; i < 100; i++) {
355 pll_delay(300);
356 if ( (PLLSTAT_REG & 0x00000001) == 0 ) {
357 break;
358 }
359 }
360 if (i == 100) {
361 return CSL_ESYS_FAIL;
362 }
364 /* Place PLL in Reset, In PLLCTL, write PLLRST = 1 (PLL is reset) */
365 PLLCTL_REG |= 0x00000008;
367 /* wait for the GOSTAT, but don't trap if lock is never read */
368 for (i = 0; i < 100; i++) {
369 pll_delay(300);
370 if ( (PLLSTAT_REG & 0x00000001) == 0 ) {
371 break;
372 }
373 }
374 if (i == 100) {
375 return (CSL_ESYS_FAIL);
376 }
378 /* Set PLL dividers if needed */
379 PLLDIV2_REG = (0x8000) | (hwSetup->pllDiv2);
380 PLLDIV3_REG = (0x8000) | (hwSetup->pllDiv3);
382 /* Program ALNCTLn */
383 /* Set bit 1 and 2 */
384 PLLALNCTL_REG |= ((1 << 1) | (1 << 2));
386 /* Set GOSET bit in PLLCMD to initiate the GO operation to change the divide *
387 * values and align the SYSCLKs as programmed */
388 PLLCMD_REG |= 0x00000001;
390 /* wait for the phase adj */
391 pll_delay(1000);
393 /* Read the GOSTAT bit in PLLSTAT to make sure the bit returns to 0 to *
394 * indicate that the GO operation has completed */
396 /* wait for the GOSTAT, but don't trap if lock is never read */
397 for (i = 0; i < 100; i++) {
398 pll_delay(300);
399 if ( (PLLSTAT_REG & 0x00000001) == 0 ) {
400 break;
401 }
402 }
403 if (i == 100) {
404 return (CSL_ESYS_FAIL);
405 }
407 /* Wait for a minimum of 7 us*/
408 pll_delay (14006);
410 /*In PLLCTL, write PLLRST = 0 to bring PLL out of reset */
411 PLLCTL_REG &= ~(0x00000008);
413 /* Wait for PLL Lock time (min 50 us) */
414 pll_delay (140056 >> 1);
415 SECCTL_REG &= ~(0x00800000); /* Release Bypass */
417 /* Set the PLLEN */
418 PLLCTL_REG |= (1 << 0);
420 return (status);
421 }
423 /******************************************************************************
424 *
425 * Function: CorePllcGetHwSetup
426 *
427 * Description: Reads Core PLL configuration values
428 *
429 * Parameters: PllcHwSetup *hwSetup - Structure to store PLL register values
430 *
431 * Return Value: CSL_Status
432 *
433 ******************************************************************************/
434 CSL_Status CorePllcGetHwSetup (PllcHwSetup *hwSetup)
435 {
436 hwSetup->divEnable = 0;
437 hwSetup->pllM = ((MAINPLLCTL0_REG >> 12) & 0x7F) << 6;
438 hwSetup->pllM |= (PLLM_REG & 0x3F);
439 hwSetup->preDiv = (MAINPLLCTL0_REG & 0x3F);
440 hwSetup->postDiv = (SECCTL_REG & 0x00780000) >> 19;
441 hwSetup->pllDiv2 = PLLDIV2_REG & 0xFF;
442 hwSetup->pllDiv3 = PLLDIV3_REG & 0xFF;
444 return (CSL_SOK);
445 }
447 /******************************************************************************
448 *
449 * Function: SetNssPllConfig
450 *
451 * Description: Configures NSS module PLL registers
452 *
453 * Parameters: None
454 *
455 * Return Value: CSL_Status
456 *
457 ******************************************************************************/
458 CSL_Status SetNssPllConfig (pll_init_data *data)
459 {
460 CSL_Status status;
462 status = SetModulePllConfig (&hBootCfg->NSS_PLL_CTL0,
463 &hBootCfg->NSS_PLL_CTL1,
464 data, "NSS");
466 return status;
467 }
469 /******************************************************************************
470 *
471 * Function: SetDssPllConfig
472 *
473 * Description: Configures DSS module PLL registers
474 *
475 * Parameters: None
476 *
477 * Return Value: CSL_Status
478 *
479 ******************************************************************************/
480 CSL_Status SetDssPllConfig (pll_init_data *data)
481 {
482 CSL_Status status;
484 status = SetModulePllConfig (&hBootCfg->DSS_PLL_CTL0,
485 &hBootCfg->DSS_PLL_CTL1,
486 data, "DSS");
488 return status;
489 }
491 /******************************************************************************
492 *
493 * Function: SetIcssPllConfig
494 *
495 * Description: Configures ICSS module PLL registers
496 *
497 * Parameters: None
498 *
499 * Return Value: CSL_Status
500 *
501 ******************************************************************************/
502 CSL_Status SetIcssPllConfig (pll_init_data *data)
503 {
504 CSL_Status status;
506 status = SetModulePllConfig (&hBootCfg->ICSS_PLL_CTL0,
507 &hBootCfg->ICSS_PLL_CTL1,
508 data, "ICSS");
510 return status;
511 }
513 /******************************************************************************
514 *
515 * Function: SetUartPllConfig
516 *
517 * Description: Configures UART module PLL registers
518 *
519 * Parameters: None
520 *
521 * Return Value: CSL_Status
522 *
523 ******************************************************************************/
524 CSL_Status SetUartPllConfig (pll_init_data *data)
525 {
526 CSL_Status status;
528 status = SetModulePllConfig (&hBootCfg->UART_PLL_CTL0,
529 &hBootCfg->UART_PLL_CTL1,
530 data, "UART");
532 return status;
533 }
535 /******************************************************************************
536 *
537 * Function: SetDDR3PllConfig
538 *
539 * Description: Configures DDR3 module PLL registers
540 *
541 * Parameters: pll_init_data *data - PLL configuration values
542 *
543 * Return Value: CSL_Status
544 *
545 ******************************************************************************/
546 CSL_Status SetDDR3PllConfig(pll_init_data *data)
547 {
548 CSL_Status status;
550 status = SetModulePllConfig (&hBootCfg->DDR3A_PLL_CTL0,
551 &hBootCfg->DDR3A_PLL_CTL1,
552 data, "DDR3");
553 return (status);
554 }
556 /******************************************************************************
557 *
558 * Function: configPllClkSelection
559 *
560 * Description: Configures pin muxing and clock selection for different modules
561 *
562 * Parameters: None
563 *
564 * Return Value: None
565 *
566 ******************************************************************************/
567 void configPllClkSelection (void)
568 {
569 /* Configure clock source for DDR
572 */
573 #ifdef DDRCLKP_INPUT
574 CSL_FINS(hBootCfg->DDR_CLKCTL, BOOTCFG_DDR_CLKCTL_DDR_CLK_MUXSEL, 1);
575 #else
576 CSL_FINS(hBootCfg->DDR_CLKCTL, BOOTCFG_DDR_CLKCTL_DDR_CLK_MUXSEL, 0);
577 #endif
579 /* Configure ICSS clock input to ICSS PLL
580 0 - Selects ICSS PLL output
581 1 - Selects NSS PLL output
582 */
583 CSL_FINS(hBootCfg->ICSS_CLKCTL, BOOTCFG_ICSS_CLKCTL_ICSS0_PLL_MUXSEL, 0);
584 CSL_FINS(hBootCfg->ICSS_CLKCTL, BOOTCFG_ICSS_CLKCTL_ICSS1_PLL_MUXSEL, 0);
586 /* Configure USB clock input to UART PLL
587 0 - Selects UART PLL output
588 1 - Selects NSS PLL output
589 */
590 CSL_FINS(hBootCfg->USB0_CLKCTL, BOOTCFG_USB0_CLKCTL_USB0_CLKCORE_SEL, 0);
591 CSL_FINS(hBootCfg->USB1_CLKCTL, BOOTCFG_USB1_CLKCTL_USB1_CLKCORE_SEL, 0);
592 }
594 /******************************************************************************
595 *
596 * Function: enablePllObsClk
597 *
598 * Description: Enables PLL observation clock
599 *
600 * Parameters: None
601 *
602 * Return Value: None
603 *
604 ******************************************************************************/
605 void enablePllObsClk (PllObsClk obsClk)
606 {
607 uint32_t bawosc_obsclk_en = 0x100;
609 /* Reset the observation clock register value */
610 hBootCfg->OBSCLKCTL = CSL_BOOTCFG_OBSCLKCTL_RESETVAL;
612 /* Enable the observation clock */
613 hBootCfg->OBSCLKCTL = (bawosc_obsclk_en << obsClk);
615 /* Select the observation clock */
616 hBootCfg->OBSCLKCTL |= obsClk;
617 }
619 /******************************************************************************
620 *
621 * Function: enable_power_domain
622 *
623 * Description: Enables the power for the given domain and its sub-module
624 *
625 * Parameters: uint32_t domain - Power domain ID
626 *
627 * Return Value: None
628 *
629 ******************************************************************************/
630 static void enable_power_domain(uint32_t domain)
631 {
632 CSL_PSC_enablePowerDomain (domain);
634 /* Enable sub-modules in the power domain */
635 switch(domain)
636 {
637 case CSL_PSC_PD_ALWAYSON:
638 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PMMC,
639 PSC_MODSTATE_ENABLE);
640 case CSL_PSC_PD_DEBUG:
641 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_DEBUG,
642 PSC_MODSTATE_ENABLE);
643 break;
644 case CSL_PSC_PD_NSS:
645 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_NSS,
646 PSC_MODSTATE_ENABLE);
647 break;
648 case CSL_PSC_PD_SA:
649 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SA,
650 PSC_MODSTATE_ENABLE);
651 break;
652 case CSL_PSC_PD_TERANET:
653 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_TERANET,
654 PSC_MODSTATE_ENABLE);
655 break;
656 case CSL_PSC_PD_SYS_COMP:
657 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SYS_COMP,
658 PSC_MODSTATE_ENABLE);
659 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_QSPI,
660 PSC_MODSTATE_ENABLE);
661 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MMC,
662 PSC_MODSTATE_ENABLE);
663 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_GPMC,
664 PSC_MODSTATE_ENABLE);
665 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MLB,
666 PSC_MODSTATE_ENABLE);
667 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_EHRPWM,
668 PSC_MODSTATE_ENABLE);
669 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_EQEP,
670 PSC_MODSTATE_ENABLE);
671 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ECAP,
672 PSC_MODSTATE_ENABLE);
673 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MCASP,
674 PSC_MODSTATE_ENABLE);
675 break;
676 case CSL_PSC_PD_SR:
677 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SR,
678 PSC_MODSTATE_ENABLE);
679 break;
680 case CSL_PSC_PD_MSMC:
681 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MSMC,
682 PSC_MODSTATE_ENABLE);
683 case CSL_PSC_PD_C66X_COREPAC_0:
684 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_C66X_COREPAC_0,
685 PSC_MODSTATE_ENABLE);
686 case CSL_PSC_PD_ARM:
687 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ARM,
688 PSC_MODSTATE_ENABLE);
689 break;
690 case CSL_PSC_PD_ASRC:
691 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ASRC,
692 PSC_MODSTATE_ENABLE);
693 break;
694 case CSL_PSC_PD_ICSS:
695 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ICSS,
696 PSC_MODSTATE_ENABLE);
697 break;
698 case CSL_PSC_PD_DSS:
699 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_DSS,
700 PSC_MODSTATE_ENABLE);
701 break;
702 case CSL_PSC_PD_PCIE:
703 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PCIE,
704 PSC_MODSTATE_ENABLE);
705 break;
706 case CSL_PSC_PD_USB:
707 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_USB_0,
708 PSC_MODSTATE_ENABLE);
709 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_USB_1,
710 PSC_MODSTATE_ENABLE);
711 break;
712 case CSL_PSC_PD_DDR3:
713 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_DDR3,
714 PSC_MODSTATE_ENABLE);
715 break;
716 default:
717 break;
718 }
720 /* Start the state transition */
721 CSL_PSC_startStateTransition (domain);
723 /* Wait until the state transition process is completed. */
724 while (!CSL_PSC_isStateTransitionDone (domain));
725 }
727 /******************************************************************************
728 *
729 * Function: PowerUpDomains
730 *
731 * Description: Power up all the power domains
732 *
733 * Parameters: None
734 *
735 * Return Value: None
736 *
737 ******************************************************************************/
738 void PowerUpDomains (void)
739 {
740 /* Enable NSS power domain */
741 enable_power_domain (CSL_PSC_PD_NSS);
743 /* Enable SA power domain */
744 enable_power_domain (CSL_PSC_PD_SA);
746 /* Enable Teranet power domain */
747 enable_power_domain (CSL_PSC_PD_TERANET);
749 /* Enable SYS_COMP power domain */
750 enable_power_domain (CSL_PSC_PD_SYS_COMP);
752 /* Enable SR power domain */
753 enable_power_domain (CSL_PSC_PD_SR);
755 /* Enable MSMC power domain */
756 enable_power_domain (CSL_PSC_PD_MSMC);
758 /* Enable ASRC power domain */
759 enable_power_domain (CSL_PSC_PD_ASRC);
761 /* Enable ICSS power domain */
762 enable_power_domain (CSL_PSC_PD_ICSS);
764 /* Enable DSS power domain */
765 enable_power_domain (CSL_PSC_PD_DSS);
767 /* Enable power PCIE power domain */
768 enable_power_domain (CSL_PSC_PD_PCIE);
770 /* Enable power USB power domain */
771 enable_power_domain (CSL_PSC_PD_USB);
773 /* Enable power DDR3 power domain */
774 enable_power_domain (CSL_PSC_PD_DDR3);
775 }
777 #define XMC_BASE_ADDR (CSL_XMC_CFG_REGS)
778 #define XMPAX2_L (*(volatile unsigned int*)(XMC_BASE_ADDR + 0x00000010))
779 #define XMPAX2_H (*(volatile unsigned int*)(XMC_BASE_ADDR + 0x00000014))
780 /*--------------------------------------------------------------*/
781 /* xmc_setup() */
782 /* XMC MPAX register setting to access DDR3 config space */
783 /*--------------------------------------------------------------*/
784 void xmc_setup()
785 {
786 /* mapping for ddr emif registers XMPAX*2 */
787 XMPAX2_L = 0x121010FF; /* replacement addr + perm */
788 XMPAX2_H = 0x2101000B; /* base addr + seg size (64KB)*/ //"1B"-->"B" by xj
789 }
791 static ddr3_emif_config ddr3_1600 = {
792 0x62005662, // sdcfg
793 0x0A385033, // sdtim1
794 0x00001CA5, // sdtim2
795 0x21ADFF32, // sdtim3
796 0x533F067F, // sdtim4
797 0x70073200, // zqcfg
798 0x00000C34, // sdrfc
799 };
801 static ddr3_phy_config ddr3phy_1600 = {
802 0xDC000, // pllcr
803 (IODDRM_MASK | ZCKSEL_MASK), // pgcr1_mask
804 ((1 << 2) | (2 << 7) | (1 << 23)), // pgcr1_val
805 0x42C21590, // ptr0
806 0xD05612C0, // ptr1
807 0, /* not set in gel */ // ptr2
808 0x06C30D40, // ptr3
809 0x6413880, // ptr4
810 (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK), // dcr_mask
811 ((1 << 10)), // dcr_val
812 0x550F6644, // dtpr0
813 0x328341E0, // dtpr1
814 0x50022A00, // dtpr2
815 0x00001430, // mr0
816 0x00000006, // mr1
817 0x00000018, // mr2
818 0x710035C7, // dtcr
819 0x00F03D09, // pgcr2
820 0x0001005D, // zq0cr1
821 0x0001005B, // zq1cr1
822 0x0001005B, // zq2cr1
823 0x00000033, // pir_v1
824 0x0000FF81, // pir_v2
825 0xB0000000 // ecc_ctl
826 };
828 void init_ddrphy(uint32_t base, ddr3_phy_config *phy_cfg, uint8_t eccEnable)
829 {
830 uint32_t tmp;
832 /* Reset DDR PHY */
833 CSL_FINS(hBootCfg->DDR3A_PLL_CTL1,
834 BOOTCFG_DDR3A_PLL_CTL1_DDR3A_PHY_RST, (uint32_t)1); //Assert DDR PHY reset after PLL enabled
835 platform_delay(5000);
836 CSL_FINS(hBootCfg->DDR3A_PLL_CTL1,
837 BOOTCFG_DDR3A_PLL_CTL1_DDR3A_PHY_RST, (uint32_t)0); //Release DDR PHY reset
839 while((read_reg(base + DDRPHY_PGSR0_OFFSET)
840 & 0x00000001) != 0x00000001);
842 // Program FRQSEL in the PLL Control Register (address offset 0x018).
843 write_reg(phy_cfg->pllcr, base + DDRPHY_PLLCR_OFFSET);
844 platform_delay (DDR_CFG_DELAY);
846 // Program WLSTEP=1, IODDRM=2(DDR3L), and ZCKSEL in the
847 // PHY General Configuration Register 1 (address offset 0x00C).
848 tmp = read_reg(base + DDRPHY_PGCR1_OFFSET);
849 tmp &= ~(phy_cfg->pgcr1_mask);
850 tmp |= phy_cfg->pgcr1_val;
851 write_reg(tmp, DDRPHY_PGCR1_OFFSET);
852 platform_delay (DDR_CFG_DELAY);
854 // Program PHY Timing Parameters Register 0-4 (address offset 0x01C - 0x02C).
855 write_reg(phy_cfg->ptr0, base + DDRPHY_PTR0_OFFSET);
856 write_reg(phy_cfg->ptr1, base + DDRPHY_PTR1_OFFSET);
857 // Maintain default values of Phy Timing Parameters Register 2 in PUB
858 write_reg(phy_cfg->ptr3, base + DDRPHY_PTR3_OFFSET);
859 write_reg(phy_cfg->ptr4, base + DDRPHY_PTR4_OFFSET);
861 /* Program PDQ, MPRDQ, and BYTEMASK in the DRAM Configuration
862 Register (address offset 0x044). */
863 // All other fields must be left at their default values.
864 tmp = read_reg(base + DDRPHY_DCR_OFFSET);
865 tmp &= ~(phy_cfg->dcr_mask);
866 tmp |= phy_cfg->dcr_val;
867 write_reg(tmp, base + DDRPHY_DCR_OFFSET);
868 platform_delay (DDR_CFG_DELAY);
870 // Program DRAM Timing Parameters Register 0-2 (address offset 0x048 - 0x050).
871 write_reg(phy_cfg->dtpr0, base + DDRPHY_DTPR0_OFFSET);
872 write_reg(phy_cfg->dtpr1, base + DDRPHY_DTPR1_OFFSET);
873 write_reg(phy_cfg->dtpr2, base + DDRPHY_DTPR2_OFFSET);
875 // Program BL=0, CL, WR, and PD=1 in the Mode Register 0 (address offset 0x054).
876 // All other fields must be left at their default values.
877 write_reg(phy_cfg->mr0, base + DDRPHY_MR0_OFFSET);
879 // Program DIC, RTT, and TDQS in the Mode Register 1 (address offset 0x058).
880 // All other fields must be left at their default values.
881 write_reg(phy_cfg->mr1, base + DDRPHY_MR1_OFFSET);
883 // Program Mode Register 2 (address offset 0x05C).
884 // Maintaining default values of Program Mode Register 2
885 //write_reg(phy_cfg->mr2, base + DDRPHY_MR2_OFFSET);
887 write_reg(phy_cfg->dtcr, base + DDRPHY_DTCR_OFFSET); //Single-rank
888 platform_delay (DDR_CFG_DELAY);
890 /* Program tREFPRD=(5*tREFI/ddr_clk_period) in the PHY General
891 Configuration Register 2 (address offset 0x08C). */
892 //All other fields must be left at their default values.
893 write_reg(phy_cfg->pgcr2, base + DDRPHY_PGCR2_OFFSET);
894 platform_delay (DDR_CFG_DELAY);
896 //Set Impedence Register and DFIPU0=1
897 write_reg(phy_cfg->zq0cr1, base + DDRPHY_ZQ0CR1_OFFSET);
898 write_reg(phy_cfg->zq1cr1, base + DDRPHY_ZQ1CR1_OFFSET);
899 write_reg(phy_cfg->zq2cr1, base + DDRPHY_ZQ2CR1_OFFSET);
901 // Re-trigger PHY initialization in DDR PHY through the VBUSP interface.
902 // Program 0x00000033 to the PHY Initialization Register (address offset 0x004)
903 // to re-trigger PLL, ZCAL, and DCAL initialization.
904 write_reg(phy_cfg->pir_v1, base + DDRPHY_PIR_OFFSET);
905 platform_delay (DDR_CFG_DELAY);
906 while((read_reg(base + DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1);
908 if(eccEnable == 0)
909 {
910 tmp = read_reg(base + DDRPHY_DATX8_4_OFFSET);
911 tmp = tmp & 0xFFFFFFFE; //Disable ECC byte lane
912 write_reg(tmp, base + DDRPHY_DATX8_4_OFFSET);
913 }
915 tmp = read_reg(base + DDRPHY_DATX8_5_OFFSET);
916 tmp = tmp & 0xFFFFFFFE; //Disable BL5 byte lane - not present in K2G
917 write_reg(tmp, base + DDRPHY_DATX8_5_OFFSET);
919 tmp = read_reg(base + DDRPHY_DATX8_6_OFFSET);
920 tmp = tmp & 0xFFFFFFFE; //Disable BL6 byte lane - not present in K2G
921 write_reg(tmp, base + DDRPHY_DATX8_6_OFFSET);
923 tmp = read_reg(base + DDRPHY_DATX8_7_OFFSET);
924 tmp = tmp & 0xFFFFFFFE; //Disable BL7 byte lane - not present in K2G
925 write_reg(tmp, base + DDRPHY_DATX8_7_OFFSET);
927 tmp = read_reg(base + DDRPHY_DATX8_8_OFFSET);
928 tmp = tmp & 0xFFFFFFFE; //Disable BL8 byte lane - not present in K2G
929 write_reg(tmp, base + DDRPHY_DATX8_8_OFFSET);
931 /* Trigger DDR3 initialization and leveling/training in DDR PHY
932 through the VBUSP interface.
933 * If using a 16-bit wide DDR interface, program DXEN=0 in the DATX8 2-7
934 General Configuration Registers (address offsets 0x240, 0x280, 0x2C0,
935 0x300, 0x340, and 0x380) to disable the leveling/training
936 for the upper byte lanes.
937 * If using a 32-bit wide DDR interface, program DXEN=0 in the DATX8 4-7
938 General Configuration Registers (address offsets 0x2C0, 0x300, 0x340,
939 and 0x380) to disable the leveling/training for the upper byte lanes.
940 * If ECC is not required, program DXEN=0 in the DATX8 8 General
941 Configuration Register (address offset 0x3C0) to disable the
942 leveling/training for the ECC byte lane.
943 * NOTE: Setup supports 64-bit by default, ECC enable by default.
944 */
945 write_reg(phy_cfg->pir_v2, base + DDRPHY_PIR_OFFSET);
946 platform_delay (DDR_CFG_DELAY);
947 while((read_reg(base + DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1);
949 if(eccEnable == 1)
950 {
951 // Enable ECC
952 write_reg(phy_cfg->ecc_ctl, base + DDR3_ECC_CTRL_OFFSET);
953 }
954 }
956 void init_ddremif(uint32_t base, ddr3_emif_config *emif_cfg)
957 {
958 write_reg(emif_cfg->sdcfg, base + DDR3_SDCFG_OFFSET );
959 write_reg(emif_cfg->sdtim1, base + DDR3_SDTIM1_OFFSET);
960 write_reg(emif_cfg->sdtim2, base + DDR3_SDTIM2_OFFSET);
961 write_reg(emif_cfg->sdtim3, base + DDR3_SDTIM3_OFFSET);
962 write_reg(emif_cfg->sdtim4, base + DDR3_SDTIM4_OFFSET);
963 write_reg(emif_cfg->zqcfg, base + DDR3_ZQCFG_OFFSET );
964 write_reg(emif_cfg->sdrfc, base + DDR3_SDRFC_OFFSET );
965 }
968 /* Set the desired DDR3 configuration -- assumes 66.67 MHz DDR3 clock input */
969 CSL_Status DDR3Init()
970 {
971 CSL_Status status = CSL_SOK;
973 CSL_BootCfgUnlockKicker();
976 init_ddrphy(DDR3A_DDRPHYC, &ddr3phy_1600, 0);
977 init_ddremif(DDR3A_EMIF_CTRL_BASE, &ddr3_1600);
979 return (status);
980 }