c66x: PLL init code update based on latest review
authorSandeep Paulraj <s-paulraj@ti.com>
Wed, 2 Nov 2011 21:26:16 +0000 (17:26 -0400)
committerSandeep Paulraj <s-paulraj@ti.com>
Wed, 2 Nov 2011 21:26:16 +0000 (17:26 -0400)
Signed-off-by: Sandeep Paulraj <s-paulraj@ti.com>
src/hw/plls/pll014phi/pll.c

index 8de03f6ce1bf075709ead16ebce57cac01ceb4cb..266af2f62c94db799c276548ef5009205133c005 100644 (file)
@@ -46,7 +46,6 @@ void hw_pll_delay (UINT32 del)
  **********************************************************************************
  * DESCRIPTION: Sets up the pll
  **********************************************************************************/
-/* latest Sequence as provided by Tom during 10/27 */
 SINT16 hwPllSetPll (UINT32 pllNum, UINT32 prediv, UINT32 mult, UINT32 postdiv)
 {
   UINT32 ctl, reg;
@@ -88,139 +87,150 @@ SINT16 hwPllSetPll (UINT32 pllNum, UINT32 prediv, UINT32 mult, UINT32 postdiv)
   if ( (secctl & PLL_REG_SECCTL_FIELD_BYPASS) != 0 ) {
     /* PLL BYPASS is turned on */
 
-    /* Clear the PLLENSRC bit */
-     ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLENSRC);
-     DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
-
-    /* Clear the PLLEN bit */
-     ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLEN);
-     DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
-
-     /* Wait for 4 Ref clocks */
-     /* The slowest clock can be at 24MHz, so min:160ns delay */
-     hw_pll_delay(225);
-
-     /* Put the PLL in Bypass mode to perform the power down mode */
-     secctl = secctl | PLL_REG_SECCTL_FIELD_BYPASS;
-     DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
-
-     /* Advisory 8: Multiple PLLs May Not Lock After Power-on Reset Issue         *  
-      * In order to ensure proper PLL startup, the PLL power_down pin needs to be *  
-      * toggled. This is accomplished by toggling the PLLPWRDN bit in the PLLCTL  *  
-      * register. This needs to be done before the main PLL initialization        *  
-      * sequence                                                                  */
-      ctl = ctl | 2;
-      DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
-
-      /* Stay in a loop such that the bit is set for 5 µs (minimum) and           *   
-       * then clear the bit.                                                      */
-      hw_pll_delay (14005); /* waiting 10 us */
-
-      /* Power up the PLL */
-      ctl = ctl & ~2;
-      DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
-
-      /* Set the ENSAT Bit */
-     /* Usage Note 9: For optimal PLL operation, the ENSAT bit in the PLL control *  
-      * registers for the Main PLL, DDR3 PLL, and PA PLL should be set to 1.      *  
-      * The PLL initialization sequence in the boot ROM sets this bit to 0 and    *  
-      * could lead to non-optimal PLL operation. Software can set the bit to the  *  
-      * optimal value of 1 after boot                                             */
+       /* Set the ENSAT Bit */
+       /* Usage Note 9: For optimal PLL operation, the ENSAT bit in the PLL control
+        * registers for the Main PLL, DDR3 PLL, and PA PLL should be set to 1.
+        * The PLL initialization sequence in the boot ROM sets this bit to 0 and
+        * could lead to non-optimal PLL operation. Software can set the bit to the
+        * optimal value of 1 after boot
+        */
         reg = DEVICE_REG32_R (DEVICE_MAIN_PLL_CTL_1);
         reg = reg | (1 << 6);
         DEVICE_REG32_W (DEVICE_MAIN_PLL_CTL_1, reg);
-  }
 
-  /* Program the necessary multipliers/dividers and BW adjustments            */
-   /* This routine will subtract 1 from the mult value */
-  pmult = chipPllExternalMult(pllNum, mult);
-  pmult   = pmult & PLL_REG_PLLM_FIELD_MULTm1;
-  DEVICE_REG32_W (pllBase + PLL_REG_PLLM, pmult);
-
-  /* Set the PLL Divider */
-  chipPllSetExternalPrediv(pllNum, prediv - 1);  
-
-  /* set the output divide */
-  secctl = BOOT_SET_BITFIELD(secctl, 1 & 0x000f, 22, 19);
-  DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl); 
-      
-  /* set the BWADJ */
-  chipPllExternalBwAdj (pllNum, mult);
-
-  /* WAIT FOR THE go STAT BIT HERE (50 us) */
-    hw_pll_delay (140056 >> 1);   
-  /* wait for the GOSTAT, but don't trap if lock is never read */
-  for (i = 0; i < 100; i++)  {
-    hw_pll_delay (300);
-    status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
-    if ( (status & PLL_REG_STATUS_FIELD_GOSTAT) == 0 )
-      break;
-  }
-  /* Enable the pll even if the lock failed. Return a warning. */
-  if (i == 100)  
-    ret = -1;
-  
-  /* Set PLL dividers if needed */
-  reg = 0x8000 | (div2 -1);
-  DEVICE_REG32_W (pllBase + PLL_REG_DIV2, reg);
-
-  reg = 0x8000 | (div5 -1);
-  DEVICE_REG32_W (pllBase + PLL_REG_DIV5, reg);
-
-  reg = 0x8000 | (div8 -1);
-  DEVICE_REG32_W (pllBase + PLL_REG_DIV8, reg);
-
-  /* Program ALNCTLn registers */
-  alnctl = DEVICE_REG32_R (pllBase + PLL_REG_ALNCTL);
-  alnctl = alnctl | ((1 << 1) | (1 << 4) | (1 << 7));
-  DEVICE_REG32_W (pllBase + PLL_REG_ALNCTL, alnctl);
-
-  /* Set GOSET bit in PLLCMD to initiate the GO operation to change the divide *   
-   * values and align the SYSCLKs as programmed                                */
-  reg = DEVICE_REG32_R (pllBase + PLL_REG_CMD);
-  reg = reg | 1;
-  DEVICE_REG32_W (pllBase + PLL_REG_CMD, reg);
-
-  /* wait for the GOSTAT, but don't trap if lock is never read */
-  for (i = 0; i < 100; i++)  {
-    hw_pll_delay (300);
-    status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
-    if ( (status & PLL_REG_STATUS_FIELD_GOSTAT) == 0 )
-      break;
+       /* Clear the PLLENSRC bit */
+       ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLENSRC);
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+
+       /* Clear the PLLEN bit */
+       ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLEN);
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+
+       
+       /* Wait for 4 Ref clocks */
+       /* The slowest clock can be at 24MHz, so min:160ns delay */
+       hw_pll_delay(225);
+
+       /* Put the PLL in Bypass mode to perform the power down mode */
+       secctl = secctl | PLL_REG_SECCTL_FIELD_BYPASS;
+       DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
+
+       /* Advisory 8: Multiple PLLs May Not Lock After Power-on Reset Issue
+         * In order to ensure proper PLL startup, the PLL power_down pin needs to be
+         * toggled. This is accomplished by toggling the PLLPWRDN bit in the PLLCTL
+         * register. This needs to be done before the main PLL initialization
+         * sequence
+        */
+       ctl = ctl | 2;
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+
+       /* Stay in a loop such that the bit is set for 5 µs (minimum) and
+        * then clear the bit.
+        */
+       hw_pll_delay (14005); /* waiting 10 us */
+
+       /* Power up the PLL */
+       ctl = ctl & ~2;
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+       
   }
 
-  /* Wait for the PLL Reset duration time (min: 1000 ns)                      */
-    hw_pll_delay (1400);
-
-  /* Release PLL from Reset */
-    ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLRST);
-    DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
-
-  /* Wait for PLL Lock time (min 50 us) */
-    hw_pll_delay (140056 >> 1);  
+       /* Assert PLL Reset */
+       ctl = ctl | (PLL_REG_CTL_FIELD_PLLRST);
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+
+       /* Program the necessary multipliers/dividers and BW adjustments
+        * This routine will subtract 1 from the mult value
+        */
+       pmult = chipPllExternalMult(pllNum, mult);
+       pmult   = pmult & PLL_REG_PLLM_FIELD_MULTm1;
+       DEVICE_REG32_W (pllBase + PLL_REG_PLLM, pmult);
+
+       /* set the BWADJ */
+       chipPllExternalBwAdj (pllNum, mult);
+
+       /* Set the PLL Divider */
+       chipPllSetExternalPrediv(pllNum, prediv - 1);  
+
+       /* set the output divide */
+       secctl = BOOT_SET_BITFIELD(secctl, 1 & 0x000f, 22, 19);
+       DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl); 
+       
+       /* WAIT FOR THE go STAT BIT HERE (50 us) */
+       hw_pll_delay (140056 >> 1);   
+       /* wait for the GOSTAT, but don't trap if lock is never read */
+       for (i = 0; i < 100; i++)  {
+               hw_pll_delay (300);
+               status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
+               if ( (status & PLL_REG_STATUS_FIELD_GOSTAT) == 0 )
+                       break;
+       }
+
+       /* Enable the pll even if the lock failed. Return a warning. */
+       if (i == 100)  
+               ret = -1;
+  
+       /* Set PLL dividers if needed */
+       reg = 0x8000 | (div2 -1);
+       DEVICE_REG32_W (pllBase + PLL_REG_DIV2, reg);
+
+       reg = 0x8000 | (div5 -1);
+       DEVICE_REG32_W (pllBase + PLL_REG_DIV5, reg);
+
+       reg = 0x8000 | (div8 -1);
+       DEVICE_REG32_W (pllBase + PLL_REG_DIV8, reg);
+
+       /* Program ALNCTLn registers */
+       alnctl = DEVICE_REG32_R (pllBase + PLL_REG_ALNCTL);
+       alnctl = alnctl | ((1 << 1) | (1 << 4) | (1 << 7));
+       DEVICE_REG32_W (pllBase + PLL_REG_ALNCTL, alnctl);
+
+       /* Set GOSET bit in PLLCMD to initiate the GO operation to change the divide *   
+        * values and align the SYSCLKs as programmed                                */
+       reg = DEVICE_REG32_R (pllBase + PLL_REG_CMD);
+       reg = reg | 1;
+       DEVICE_REG32_W (pllBase + PLL_REG_CMD, reg);
+
+       /* wait for the GOSTAT, but don't trap if lock is never read */
+       for (i = 0; i < 100; i++)  {
+               hw_pll_delay (300);
+               status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
+               if ( (status & PLL_REG_STATUS_FIELD_GOSTAT) == 0 )
+                       break;
+       }
+
+       /* Wait for 7 us, use 10 us*/
+       hw_pll_delay (14006);
+
+       /* Release PLL from Reset */
+       ctl = ctl & ~(PLL_REG_CTL_FIELD_PLLRST);
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+
+       /* Wait for PLL Lock time (min 50 us) */
+       hw_pll_delay (140056 >> 1);  
    
-  /* wait for the pll to lock, but don't trap if lock is never read */
-  for (i = 0; i < 100; i++)  {
-    hw_pll_delay (2000/7);
-    status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
-    if ( (status & PLL_REG_STATUS_FIELD_LOCK) != 0 )
-      break;
-  }
-
-  /* Enable the pll even if the lock failed. Return a warning. */
-  if (i == 100)  
-    ret = -1;
-
-  /* Clear the secondary controller bypass bit */
-  secctl = secctl & ~PLL_REG_SECCTL_FIELD_BYPASS;
-  DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
-
-
-  /* Set pllen to 1 to enable pll mode */
-  ctl = ctl | PLL_REG_CTL_FIELD_PLLEN;
-  DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
+       /* wait for the pll to lock, but don't trap if lock is never read */
+       for (i = 0; i < 100; i++)  {
+               hw_pll_delay (2000/7);
+               status = DEVICE_REG32_R (pllBase + PLL_REG_PLLSTAT);
+               if ( (status & PLL_REG_STATUS_FIELD_LOCK) != 0 )
+                       break;
+       }
+
+       /* Enable the pll even if the lock failed. Return a warning. */
+       if (i == 100)  
+               ret = -1;
+
+       /* Clear the secondary controller bypass bit */
+       secctl = secctl & ~PLL_REG_SECCTL_FIELD_BYPASS;
+       DEVICE_REG32_W (pllBase + PLL_REG_SECCTL, secctl);
+
+
+       /* Set pllen to 1 to enable pll mode */
+       ctl = ctl | PLL_REG_CTL_FIELD_PLLEN;
+       DEVICE_REG32_W (pllBase + PLL_REG_CTL, ctl);
   
-  return (ret);
+       return (ret);
 } /* hwPllSetPll */