[processor-sdk/performance-audio-sr.git] / psdk_cust / pdk_k2g_1_0_1_0_eng / packages / ti / board / src / flash / platform_flash / 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: uint8_t sysClkSel - SYSCLKSEL pin status
563 *
564 * Return Value: None
565 *
566 ******************************************************************************/
567 void configPllClkSelection (uint8_t sysClkSel)
568 {
569 /* Configure clock source for DDR
572 */
573 CSL_FINS(hBootCfg->DDR_CLKCTL, BOOTCFG_DDR_CLKCTL_DDR_CLK_MUXSEL,
574 sysClkSel);
576 /* Configure ICSS clock input to ICSS PLL
577 0 - Selects ICSS PLL output
578 1 - Selects NSS PLL output
579 */
580 CSL_FINS(hBootCfg->ICSS_CLKCTL, BOOTCFG_ICSS_CLKCTL_ICSS0_PLL_MUXSEL, 0);
581 CSL_FINS(hBootCfg->ICSS_CLKCTL, BOOTCFG_ICSS_CLKCTL_ICSS1_PLL_MUXSEL, 0);
583 /* Configure USB clock input to UART PLL
584 0 - Selects UART PLL output
585 1 - Selects NSS PLL output
586 */
587 CSL_FINS(hBootCfg->USB0_CLKCTL, BOOTCFG_USB0_CLKCTL_USB0_CLKCORE_SEL, 0);
588 CSL_FINS(hBootCfg->USB1_CLKCTL, BOOTCFG_USB1_CLKCTL_USB1_CLKCORE_SEL, 0);
589 }
591 /******************************************************************************
592 *
593 * Function: enablePllObsClk
594 *
595 * Description: Enables PLL observation clock
596 *
597 * Parameters: None
598 *
599 * Return Value: None
600 *
601 ******************************************************************************/
602 void enablePllObsClk (PllObsClk obsClk)
603 {
604 uint32_t bawosc_obsclk_en = 0x100;
606 /* Reset the observation clock register value */
607 hBootCfg->OBSCLKCTL = CSL_BOOTCFG_OBSCLKCTL_RESETVAL;
609 /* Enable the observation clock */
610 hBootCfg->OBSCLKCTL = (bawosc_obsclk_en << obsClk);
612 /* Select the observation clock */
613 hBootCfg->OBSCLKCTL |= obsClk;
614 }
616 /******************************************************************************
617 *
618 * Function: enable_power_domain
619 *
620 * Description: Enables the power for the given domain and its sub-module
621 *
622 * Parameters: uint32_t domain - Power domain ID
623 *
624 * Return Value: None
625 *
626 ******************************************************************************/
627 static void enable_power_domain(uint32_t domain)
628 {
629 CSL_PSC_enablePowerDomain (domain);
631 /* Enable sub-modules in the power domain */
632 switch(domain)
633 {
634 case CSL_PSC_PD_ALWAYSON:
635 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PMMC,
636 PSC_MODSTATE_ENABLE);
637 case CSL_PSC_PD_DEBUG:
638 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_DEBUG,
639 PSC_MODSTATE_ENABLE);
640 break;
641 case CSL_PSC_PD_NSS:
642 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_NSS,
643 PSC_MODSTATE_ENABLE);
644 break;
645 case CSL_PSC_PD_SA:
646 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SA,
647 PSC_MODSTATE_ENABLE);
648 break;
649 case CSL_PSC_PD_TERANET:
650 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_TERANET,
651 PSC_MODSTATE_ENABLE);
652 break;
653 case CSL_PSC_PD_SYS_COMP:
654 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SYS_COMP,
655 PSC_MODSTATE_ENABLE);
656 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_QSPI,
657 PSC_MODSTATE_ENABLE);
658 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MMC,
659 PSC_MODSTATE_ENABLE);
660 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_GPMC,
661 PSC_MODSTATE_ENABLE);
662 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MLB,
663 PSC_MODSTATE_ENABLE);
664 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_EHRPWM,
665 PSC_MODSTATE_ENABLE);
666 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_EQEP,
667 PSC_MODSTATE_ENABLE);
668 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ECAP,
669 PSC_MODSTATE_ENABLE);
670 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MCASP,
671 PSC_MODSTATE_ENABLE);
672 break;
673 case CSL_PSC_PD_SR:
674 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_SR,
675 PSC_MODSTATE_ENABLE);
676 break;
677 case CSL_PSC_PD_MSMC:
678 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_MSMC,
679 PSC_MODSTATE_ENABLE);
680 case CSL_PSC_PD_C66X_COREPAC_0:
681 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_C66X_COREPAC_0,
682 PSC_MODSTATE_ENABLE);
683 case CSL_PSC_PD_ARM:
684 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ARM,
685 PSC_MODSTATE_ENABLE);
686 break;
687 case CSL_PSC_PD_ASRC:
688 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ASRC,
689 PSC_MODSTATE_ENABLE);
690 break;
691 case CSL_PSC_PD_ICSS:
692 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_ICSS,
693 PSC_MODSTATE_ENABLE);
694 break;
695 case CSL_PSC_PD_DSS:
696 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_DSS,
697 PSC_MODSTATE_ENABLE);
698 break;
699 case CSL_PSC_PD_PCIE:
700 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_PCIE,
701 PSC_MODSTATE_ENABLE);
702 break;
703 case CSL_PSC_PD_USB:
704 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_USB_0,
705 PSC_MODSTATE_ENABLE);
706 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_USB_1,
707 PSC_MODSTATE_ENABLE);
708 break;
709 case CSL_PSC_PD_DDR3:
710 CSL_PSC_setModuleNextState (CSL_PSC_LPSC_DDR3,
711 PSC_MODSTATE_ENABLE);
712 break;
713 default:
714 break;
715 }
717 /* Start the state transition */
718 CSL_PSC_startStateTransition (domain);
720 /* Wait until the state transition process is completed. */
721 while (!CSL_PSC_isStateTransitionDone (domain));
722 }
724 /******************************************************************************
725 *
726 * Function: PowerUpDomains
727 *
728 * Description: Power up all the power domains
729 *
730 * Parameters: None
731 *
732 * Return Value: None
733 *
734 ******************************************************************************/
735 void PowerUpDomains (void)
736 {
737 /* Enable NSS power domain */
738 enable_power_domain (CSL_PSC_PD_NSS);
740 /* Enable SA power domain */
741 enable_power_domain (CSL_PSC_PD_SA);
743 /* Enable Teranet power domain */
744 enable_power_domain (CSL_PSC_PD_TERANET);
746 /* Enable SYS_COMP power domain */
747 enable_power_domain (CSL_PSC_PD_SYS_COMP);
749 /* Enable SR power domain */
750 enable_power_domain (CSL_PSC_PD_SR);
752 /* Enable MSMC power domain */
753 enable_power_domain (CSL_PSC_PD_MSMC);
755 /* Enable ASRC power domain */
756 enable_power_domain (CSL_PSC_PD_ASRC);
758 /* Enable ICSS power domain */
759 enable_power_domain (CSL_PSC_PD_ICSS);
761 /* Enable DSS power domain */
762 enable_power_domain (CSL_PSC_PD_DSS);
764 /* Enable power PCIE power domain */
765 enable_power_domain (CSL_PSC_PD_PCIE);
767 /* Enable power USB power domain */
768 enable_power_domain (CSL_PSC_PD_USB);
770 /* Enable power DDR3 power domain */
771 enable_power_domain (CSL_PSC_PD_DDR3);
772 }
774 #define XMC_BASE_ADDR (CSL_XMC_CFG_REGS)
775 #define XMPAX2_L (*(volatile unsigned int*)(XMC_BASE_ADDR + 0x00000010))
776 #define XMPAX2_H (*(volatile unsigned int*)(XMC_BASE_ADDR + 0x00000014))
777 /*--------------------------------------------------------------*/
778 /* xmc_setup() */
779 /* XMC MPAX register setting to access DDR3 config space */
780 /*--------------------------------------------------------------*/
781 void xmc_setup()
782 {
783 /* mapping for ddr emif registers XMPAX*2 */
784 XMPAX2_L = 0x121010FF; /* replacement addr + perm */
785 XMPAX2_H = 0x2101000B; /* base addr + seg size (64KB)*/ //"1B"-->"B" by xj
786 }
788 static ddr3_emif_config ddr3_1600 = {
789 0x62005662, // sdcfg
790 0x0A344C23, // sdtim1
791 0x00001CA5, // sdtim2
792 0x21ADFF32, // sdtim3
793 0x533F067F, // sdtim4
794 0x70073200, // zqcfg
795 0x00000C34, // sdrfc
796 };
798 static ddr3_phy_config ddr3phy_1600 = {
799 0xDC000, // pllcr
800 (IODDRM_MASK | ZCKSEL_MASK), // pgcr1_mask
801 ((1 << 2) | (2 << 7) | (1 << 23)), // pgcr1_val
802 0x42C21590, // ptr0
803 0xD05612C0, // ptr1
804 0, /* not set in gel */ // ptr2
805 0x06C30D40, // ptr3
806 0x6413880, // ptr4
807 (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK), // dcr_mask
808 ((1 << 10)), // dcr_val
809 0x550F6644, // dtpr0
810 0x328341E0, // dtpr1
811 0x50022A00, // dtpr2
812 0x00001430, // mr0
813 0x00000006, // mr1
814 0x00000018, // mr2
815 0x710035C7, // dtcr
816 0x00F03D09, // pgcr2
817 0x0001005D, // zq0cr1
818 0x0001005B, // zq1cr1
819 0x0001005B, // zq2cr1
820 0x00000033, // pir_v1
821 0x0000FF81, // pir_v2
822 0xB0000000 // ecc_ctl
823 };
825 void init_ddrphy(uint32_t base, ddr3_phy_config *phy_cfg, uint8_t eccEnable)
826 {
827 uint32_t tmp;
829 /* Reset DDR PHY */
830 CSL_FINS(hBootCfg->DDR3A_PLL_CTL1,
831 BOOTCFG_DDR3A_PLL_CTL1_DDR3A_PHY_RST, (uint32_t)1); //Assert DDR PHY reset after PLL enabled
832 platform_delay(5000);
833 CSL_FINS(hBootCfg->DDR3A_PLL_CTL1,
834 BOOTCFG_DDR3A_PLL_CTL1_DDR3A_PHY_RST, (uint32_t)0); //Release DDR PHY reset
836 while((read_reg(base + DDRPHY_PGSR0_OFFSET)
837 & 0x00000001) != 0x00000001);
839 // Program FRQSEL in the PLL Control Register (address offset 0x018).
840 write_reg(phy_cfg->pllcr, base + DDRPHY_PLLCR_OFFSET);
841 platform_delay (DDR_CFG_DELAY);
843 // Program WLSTEP=1, IODDRM=2(DDR3L), and ZCKSEL in the
844 // PHY General Configuration Register 1 (address offset 0x00C).
845 tmp = read_reg(base + DDRPHY_PGCR1_OFFSET);
846 tmp &= ~(phy_cfg->pgcr1_mask);
847 tmp |= phy_cfg->pgcr1_val;
848 write_reg(tmp, DDRPHY_PGCR1_OFFSET);
849 platform_delay (DDR_CFG_DELAY);
851 // Program PHY Timing Parameters Register 0-4 (address offset 0x01C - 0x02C).
852 write_reg(phy_cfg->ptr0, base + DDRPHY_PTR0_OFFSET);
853 write_reg(phy_cfg->ptr1, base + DDRPHY_PTR1_OFFSET);
854 // Maintain default values of Phy Timing Parameters Register 2 in PUB
855 write_reg(phy_cfg->ptr3, base + DDRPHY_PTR3_OFFSET);
856 write_reg(phy_cfg->ptr4, base + DDRPHY_PTR4_OFFSET);
858 /* Program PDQ, MPRDQ, and BYTEMASK in the DRAM Configuration
859 Register (address offset 0x044). */
860 // All other fields must be left at their default values.
861 tmp = read_reg(base + DDRPHY_DCR_OFFSET);
862 tmp &= ~(phy_cfg->dcr_mask);
863 tmp |= phy_cfg->dcr_val;
864 write_reg(tmp, base + DDRPHY_DCR_OFFSET);
865 platform_delay (DDR_CFG_DELAY);
867 // Program DRAM Timing Parameters Register 0-2 (address offset 0x048 - 0x050).
868 write_reg(phy_cfg->dtpr0, base + DDRPHY_DTPR0_OFFSET);
869 write_reg(phy_cfg->dtpr1, base + DDRPHY_DTPR1_OFFSET);
870 write_reg(phy_cfg->dtpr2, base + DDRPHY_DTPR2_OFFSET);
872 // Program BL=0, CL, WR, and PD=1 in the Mode Register 0 (address offset 0x054).
873 // All other fields must be left at their default values.
874 write_reg(phy_cfg->mr0, base + DDRPHY_MR0_OFFSET);
876 // Program DIC, RTT, and TDQS in the Mode Register 1 (address offset 0x058).
877 // All other fields must be left at their default values.
878 write_reg(phy_cfg->mr1, base + DDRPHY_MR1_OFFSET);
880 // Program Mode Register 2 (address offset 0x05C).
881 // Maintaining default values of Program Mode Register 2
882 //write_reg(phy_cfg->mr2, base + DDRPHY_MR2_OFFSET);
884 write_reg(phy_cfg->dtcr, base + DDRPHY_DTCR_OFFSET); //Single-rank
885 platform_delay (DDR_CFG_DELAY);
887 /* Program tREFPRD=(5*tREFI/ddr_clk_period) in the PHY General
888 Configuration Register 2 (address offset 0x08C). */
889 //All other fields must be left at their default values.
890 write_reg(phy_cfg->pgcr2, base + DDRPHY_PGCR2_OFFSET);
891 platform_delay (DDR_CFG_DELAY);
893 //Set Impedence Register and DFIPU0=1
894 write_reg(phy_cfg->zq0cr1, base + DDRPHY_ZQ0CR1_OFFSET);
895 write_reg(phy_cfg->zq1cr1, base + DDRPHY_ZQ1CR1_OFFSET);
896 write_reg(phy_cfg->zq2cr1, base + DDRPHY_ZQ2CR1_OFFSET);
898 // Re-trigger PHY initialization in DDR PHY through the VBUSP interface.
899 // Program 0x00000033 to the PHY Initialization Register (address offset 0x004)
900 // to re-trigger PLL, ZCAL, and DCAL initialization.
901 write_reg(phy_cfg->pir_v1, base + DDRPHY_PIR_OFFSET);
902 platform_delay (DDR_CFG_DELAY);
903 while((read_reg(base + DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1);
905 if(eccEnable == 0)
906 {
907 tmp = read_reg(base + DDRPHY_DATX8_4_OFFSET);
908 tmp = tmp & 0xFFFFFFFE; //Disable ECC byte lane
909 write_reg(tmp, base + DDRPHY_DATX8_4_OFFSET);
910 }
912 tmp = read_reg(base + DDRPHY_DATX8_5_OFFSET);
913 tmp = tmp & 0xFFFFFFFE; //Disable BL5 byte lane - not present in K2G
914 write_reg(tmp, base + DDRPHY_DATX8_5_OFFSET);
916 tmp = read_reg(base + DDRPHY_DATX8_6_OFFSET);
917 tmp = tmp & 0xFFFFFFFE; //Disable BL6 byte lane - not present in K2G
918 write_reg(tmp, base + DDRPHY_DATX8_6_OFFSET);
920 tmp = read_reg(base + DDRPHY_DATX8_7_OFFSET);
921 tmp = tmp & 0xFFFFFFFE; //Disable BL7 byte lane - not present in K2G
922 write_reg(tmp, base + DDRPHY_DATX8_7_OFFSET);
924 tmp = read_reg(base + DDRPHY_DATX8_8_OFFSET);
925 tmp = tmp & 0xFFFFFFFE; //Disable BL8 byte lane - not present in K2G
926 write_reg(tmp, base + DDRPHY_DATX8_8_OFFSET);
928 /* Trigger DDR3 initialization and leveling/training in DDR PHY
929 through the VBUSP interface.
930 * If using a 16-bit wide DDR interface, program DXEN=0 in the DATX8 2-7
931 General Configuration Registers (address offsets 0x240, 0x280, 0x2C0,
932 0x300, 0x340, and 0x380) to disable the leveling/training
933 for the upper byte lanes.
934 * If using a 32-bit wide DDR interface, program DXEN=0 in the DATX8 4-7
935 General Configuration Registers (address offsets 0x2C0, 0x300, 0x340,
936 and 0x380) to disable the leveling/training for the upper byte lanes.
937 * If ECC is not required, program DXEN=0 in the DATX8 8 General
938 Configuration Register (address offset 0x3C0) to disable the
939 leveling/training for the ECC byte lane.
940 * NOTE: Setup supports 64-bit by default, ECC enable by default.
941 */
942 write_reg(phy_cfg->pir_v2, base + DDRPHY_PIR_OFFSET);
943 platform_delay (DDR_CFG_DELAY);
944 while((read_reg(base + DDRPHY_PGSR0_OFFSET) & 0x1) != 0x1);
946 if(eccEnable == 1)
947 {
948 // Enable ECC
949 write_reg(phy_cfg->ecc_ctl, base + DDR3_ECC_CTRL_OFFSET);
950 }
951 }
953 void init_ddremif(uint32_t base, ddr3_emif_config *emif_cfg)
954 {
955 write_reg(emif_cfg->sdcfg, base + DDR3_SDCFG_OFFSET );
956 write_reg(emif_cfg->sdtim1, base + DDR3_SDTIM1_OFFSET);
957 write_reg(emif_cfg->sdtim2, base + DDR3_SDTIM2_OFFSET);
958 write_reg(emif_cfg->sdtim3, base + DDR3_SDTIM3_OFFSET);
959 write_reg(emif_cfg->sdtim4, base + DDR3_SDTIM4_OFFSET);
960 write_reg(emif_cfg->zqcfg, base + DDR3_ZQCFG_OFFSET );
961 write_reg(emif_cfg->sdrfc, base + DDR3_SDRFC_OFFSET );
962 }
965 /* Set the desired DDR3 configuration -- assumes 66.67 MHz DDR3 clock input */
966 CSL_Status DDR3Init()
967 {
968 CSL_Status status = CSL_SOK;
970 CSL_BootCfgUnlockKicker();
973 init_ddrphy(DDR3A_DDRPHYC, &ddr3phy_1600, 0);
974 init_ddremif(DDR3A_EMIF_CTRL_BASE, &ddr3_1600);
976 return (status);
977 }