c66x: Update PASS PLL init code
[keystone-rtos/ibl.git] / src / hw / plls / pll014phi / cfgpll.c
1 /********************************************************************************************************
2  * FILE PURPOSE: Config level PLL driver
3  ********************************************************************************************************
4  * FILE NAME: cfgpll.c
5  *
6  * DESCRIPTION: The boot driver for PLLs that dont have a pll controller, but are controlled
7  *                              by registers in config space.
8  *
9  *********************************************************************************************************/
10 #include "types.h"
11 #include "target.h"
12 #include "pllapi.h"
14 #define DEVICE_REG32_W(x,y)   *(volatile unsigned int *)(x)=(y)
15 #define DEVICE_REG32_R(x)    (*(volatile unsigned int *)(x))
17 #define BOOTBITMASK(x,y)      (   (   (  ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 )   )   <<  ((UINT32)y)   )
18 #define BOOT_READ_BITFIELD(z,x,y)   (((UINT32)z) & BOOTBITMASK(x,y)) >> (y)
19 #define BOOT_SET_BITFIELD(z,f,x,y)  (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) )
21 void pass_pll_delay (UINT32 del)
22 {
23   UINT32 i;
24   volatile UINT32 j;
26   for (i = j = 0; i < del; i++)
27     asm (" nop ");
29 } /* hw_pll_delay */
32 /*********************************************************************************************************
33  * FUNCTION PURPOSE: Configure and enable a pll
34  *********************************************************************************************************
35  * DESCRIPTION: The PLL is configured. If the existing configuration matches the requested one no
36  *              register write is made.
37  *********************************************************************************************************/
38 SINT16 hwPllSetCfgPll (UINT32 base, UINT32 prediv, UINT32 mult, UINT32 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz)
39 {
40     UINT32 reg;
41     UINT32 regb;
42     UINT32 bwAdj;
44     UINT16 currentPrediv;
45     UINT16 currentMult;
46     UINT16 currentPostdiv;
47     UINT16 currentBypass;
48     UINT16 currentBwAdj;
49     UINT16 currentEnable;
50     UINT16 currentClkOut;
52     reg =  DEVICE_REG32_R (base);
53     regb = DEVICE_REG32_R (base + 4);
55     currentPrediv  = 1 + BOOT_READ_BITFIELD (reg,  5,  0);
56     currentMult    = 1 + BOOT_READ_BITFIELD (reg, 18,  6);
57     currentPostdiv = 1 + BOOT_READ_BITFIELD (reg, 22, 19);
58     currentBypass  =     BOOT_READ_BITFIELD (reg, 23, 23);
59     currentBwAdj   = 1 + BOOT_READ_BITFIELD (reg, 31, 24) + ((BOOT_READ_BITFIELD (regb, 3, 0)) << 8);
60     currentEnable  =     BOOT_READ_BITFIELD(regb, 14, 14);
61     currentClkOut  =     BOOT_READ_BITFIELD(regb, 13, 13);
63     /* The PLL is currently enabled and connected if bypass == 0, enable == 1, clkout == 1 */
65     if ( (currentBypass  == 0)           &&
66          (currentPrediv  == prediv)      &&
67          (currentMult    == mult)        &&
68          (currentPostdiv == postdiv)     &&
69          (currentEnable  == 0)           &&
70          (currentClkOut  == 1)           &&  
71          (currentBwAdj   == (mult >> 1))  )
72         return (0);
75     /* bwAdj is based only on the mult value */
76     bwAdj = (mult >> 1) - 1;
78     /* Multiplier / divider values are input as 1 less then the desired value */
79     if (prediv > 0)
80         prediv -= 1;
82     if (mult > 0)
83         mult -= 1;
85     if (postdiv > 0)
86         postdiv -= 1;
88     regb = BOOT_SET_BITFIELD(regb, 1, 6, 6);
89     DEVICE_REG32_W (base + 4, regb);
91     /* Setup the PLL. Assert bypass */
92     reg = BOOT_SET_BITFIELD (reg, 1,              23, 23);   /* Bypass must be enabled */
93     DEVICE_REG32_W (base, reg);
95     /* Set bit 14 in register 1 to disable the PLL (assert reset) */
96     regb = BOOT_SET_BITFIELD(regb, 1, 14, 14);
97     DEVICE_REG32_W (base + 4, regb);
99     reg = BOOT_SET_BITFIELD (reg, prediv - 1, 5, 0);
100     reg = BOOT_SET_BITFIELD (reg, mult - 1, 18, 6);
101     reg = BOOT_SET_BITFIELD (reg, postdiv - 1, 22, 19);
102     reg = BOOT_SET_BITFIELD (reg, (bwAdj & 0xff), 31, 24);
104     DEVICE_REG32_W (base, reg);
106     /* The 4 MS Bits of bwadj */
107     regb = BOOT_SET_BITFIELD (regb, (bwAdj >> 8), 3, 0);
108     DEVICE_REG32_W (base + 4, regb);
111     /* Reset must be asserted for at least 5us. Give a huge amount of padding here to be safe
112      * (the factor of 100) */
113     pass_pll_delay(7000);
115     /* Clear bit 14 in register 1 to re-enable the pll */
116     regb = BOOT_SET_BITFIELD(regb, 0, 14, 14);
117     DEVICE_REG32_W (base + 4, regb);
119     /* Wait for 50 us */
120     pass_pll_delay(70000);
122     /* Disable the bypass */
123     reg = BOOT_SET_BITFIELD (reg, 0, 23, 23);   /* The value 0 disables the bypass */
124     DEVICE_REG32_W (base, reg);
126 #if 0    
127     /* Enable the output source (set bit 13) */
128     regb = BOOT_SET_BITFIELD(regb, 1, 13, 13);
129     DEVICE_REG32_W (base + 4, regb);
130 #endif
132     return (0);
134 } /* hwPllSetCfgPll */