DDR3 and PA SS PLL driver code update
[keystone-rtos/ibl.git] / src / hw / plls / pll014phi / cfgpll2.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  *              This driver differs from cfgpll! In this file the reset is controlled by
10  *              bit 13 in register b, not bit 14!.
11  *
12  *********************************************************************************************************/
13 #include "types.h"
14 #include "target.h"
15 #include "pllapi.h"
17 #define DEVICE_REG32_W(x,y)   *(volatile unsigned int *)(x)=(y)
18 #define DEVICE_REG32_R(x)    (*(volatile unsigned int *)(x))
20 #define BOOTBITMASK(x,y)      (   (   (  ((UINT32)1 << (((UINT32)x)-((UINT32)y)+(UINT32)1) ) - (UINT32)1 )   )   <<  ((UINT32)y)   )
21 #define BOOT_READ_BITFIELD(z,x,y)   (((UINT32)z) & BOOTBITMASK(x,y)) >> (y)
22 #define BOOT_SET_BITFIELD(z,f,x,y)  (((UINT32)z) & ~BOOTBITMASK(x,y)) | ( (((UINT32)f) << (y)) & BOOTBITMASK(x,y) )
24 #define CHIP_LEVEL_REG          0x02620000
25 #define DDR3PLLCTL0             *(volatile unsigned int*)(CHIP_LEVEL_REG + 0x0330)
26 #define DDR3PLLCTL1             *(volatile unsigned int*)(CHIP_LEVEL_REG + 0x0334)
30 void ddr3_pll_delay (UINT32 del)
31 {
32   UINT32 i;
33   volatile UINT32 j;
35   for (i = j = 0; i < del; i++)
36     asm (" nop ");
38 }
40 /*********************************************************************************************************
41  * FUNCTION PURPOSE: Configure and enable a pll
42  *********************************************************************************************************
43  * DESCRIPTION: The PLL is configured. If the existing configuration matches the requested one no
44  *              register write is made.
45  *********************************************************************************************************/
46 SINT16 hwPllSetCfg2Pll (UINT32 base, UINT32 prediv, UINT32 mult, UINT32 postdiv, UINT32 chipFreqMhz, UINT32 pllFreqMhz)
47 {
48     UINT32 reg;
49     UINT32 regb;
50     UINT32 bwAdj;
52     UINT16 currentPrediv;
53     UINT16 currentMult;
54     UINT16 currentPostdiv;
55     UINT16 currentBypass;
56     UINT16 currentBwAdj;
57     UINT16 currentEnable;
59     reg =  DEVICE_REG32_R (base);
60     regb = DEVICE_REG32_R (base + 4);
62     currentPrediv  = 1 + BOOT_READ_BITFIELD (reg,  5,  0);
63     currentMult    = 1 + BOOT_READ_BITFIELD (reg, 18,  6);
64     currentPostdiv = 1 + BOOT_READ_BITFIELD (reg, 22, 19);
65     currentBypass  =     BOOT_READ_BITFIELD (reg, 23, 23);
66     currentBwAdj   = 1 + BOOT_READ_BITFIELD (reg, 31, 24) + ((BOOT_READ_BITFIELD (regb, 3, 0)) << 8);
67     currentEnable  =     BOOT_READ_BITFIELD(regb, 13, 13);
69     /* The PLL is currently enabled and connected if bypass == 0, enable == 1, clkout == 1 */
71     if ( (currentBypass  == 0)           &&
72          (currentPrediv  == prediv)      &&
73          (currentMult    == mult)        &&
74          (currentPostdiv == postdiv)     &&
75          (currentEnable  == 0)           &&
76          (currentBwAdj   == (mult >> 1))  )
77         return (0);
80     /* bwAdj is based only on the mult value */
81     bwAdj = (mult >> 1) - 1;
83     /* Multiplier / divider values are input as 1 less then the desired value */
84     if (prediv > 0)
85         prediv -= 1;
87     if (mult > 0)
88         mult -= 1;
90     if (postdiv > 0)
91         postdiv -= 1;
93     /* Write to the ENSAT bit */
94     regb = BOOT_SET_BITFIELD(regb, 1, 6, 6);
95     DEVICE_REG32_W (base + 4, regb);
97     /* Bypass must be enabled */
98     reg = BOOT_SET_BITFIELD (reg, 1, 23, 23);
99     DEVICE_REG32_W (base, reg);
101     /* Set bit 13 in register 1 to disable the PLL (assert reset) */
102     regb = BOOT_SET_BITFIELD(regb, 1, 13, 13);
103     DEVICE_REG32_W (base + 4, regb);
106     /* Configure CLKR, CLKF, CLKOD, BWADJ */
107     reg = ((prediv - 1) | ((mult - 1 ) << 6) | (bwAdj << 24));
110     DEVICE_REG32_W (base, reg);
112     /* The 4 MS Bits of bwadj */
113     regb = BOOT_SET_BITFIELD (regb, (bwAdj >> 8), 3, 0);
114     DEVICE_REG32_W (base + 4, regb);
117     /* Reset must be asserted for at least 5us. Give a huge amount of padding here to be safe
118      * (the factor of 100) */
119     ddr3_pll_delay(70000);
122     /* Clear bit 13 in register 1 to re-enable the pll */
123     regb = BOOT_SET_BITFIELD(regb, 0, 13, 13);
124     DEVICE_REG32_W (base + 4, regb);
126     /* Need to wait 100,000 output PLL cycles before releasing bypass and setting 
127      * up the clk output */
128     ddr3_pll_delay(70000);
130     /* Disable the bypass */
131     reg = BOOT_SET_BITFIELD (reg, 0, 23, 23);   /* The value 0 disables the bypass */
132     DEVICE_REG32_W (base, reg);
134     return (0);
136 } /* hwPllSetCfg2Pll */