]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/device/c661x/c661xinit.c
Clean up the code and fixed instablitily issue in the NAND/EMIF driver
[keystone-rtos/ibl.git] / src / device / c661x / c661xinit.c
1 /**
2  * @file c661xinit.c
3  *
4  * @brief
5  *              c661x functions used during the initial stage of the ibl load
6  *
7  */
8 #include "ibl.h"
9 #include "iblloc.h"
10 #include "device.h"
11 #include "pllapi.h"
12 #include "spi_api.h"
13 #include "spi_loc.h"
14 #include "tiboot_c661x.h"       
17 /**
18  * @brief Configure the PLLs
19  *
20  * @details
21  *   The three PLLs are enabled. Only the main PLL has the ability to configure
22  *   the multiplier and dividers.
23  */
24 void devicePllConfig (void)
25 {
27     /* Unlock the chip registers and leave them unlocked */
28     *((Uint32 *)0x2620038) = 0x83e70b13;
29     *((Uint32 *)0x262003c) = 0x95a4f1e0;
31     if (ibl.pllConfig[ibl_MAIN_PLL].doEnable == TRUE)
32         hwPllSetPll (MAIN_PLL, 
33                      ibl.pllConfig[ibl_MAIN_PLL].prediv,
34                      ibl.pllConfig[ibl_MAIN_PLL].mult,
35                      ibl.pllConfig[ibl_MAIN_PLL].postdiv);
37     if (ibl.pllConfig[ibl_DDR_PLL].doEnable == TRUE)
38         hwPllSetCfg2Pll (DEVICE_PLL_BASE(DDR_PLL),
39                          ibl.pllConfig[ibl_DDR_PLL].prediv,
40                          ibl.pllConfig[ibl_DDR_PLL].mult,
41                          ibl.pllConfig[ibl_DDR_PLL].postdiv,
42                          ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz,
43                          ibl.pllConfig[ibl_DDR_PLL].pllOutFreqMhz);
45     if (ibl.pllConfig[ibl_NET_PLL].doEnable == TRUE)
46         hwPllSetCfgPll (DEVICE_PLL_BASE(NET_PLL),
47                         ibl.pllConfig[ibl_NET_PLL].prediv,
48                         ibl.pllConfig[ibl_NET_PLL].mult,
49                         ibl.pllConfig[ibl_NET_PLL].postdiv,
50                         ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz,
51                         ibl.pllConfig[ibl_NET_PLL].pllOutFreqMhz);
54 }
57 /**
58  * @brief
59  *  Return the endian status of the device
60  *
61  * @details
62  *  Returns true if the device is executing in little endian mode
63  */
64 extern cregister volatile unsigned int CSR;
66 bool deviceIsLittleEndian (void)
67 {
68     if ((CSR & (1 << 8)) == 0)    
69         return (FALSE);
71     return (TRUE);
73 }
76 /**
77  *  @brief
78  *      Return the device used for the second stage program load.
79  *      For SPI NAND a second stage loader is required and this
80  *      function must be changed to locate that fingerprint.
81  */
82 int32 deviceReadBootDevice (void)
83 {
84     uint32 v;
85     int32  w;
87     BOOT_PARAMS_COMMON_T *params;
89 #if  (defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && !defined(EXCLUDE_I2C))
91     return (BOOT_DEVICE_I2C);
93 #elif (defined(EXCLUDE_NOR_SPI) && !defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
95     return (BOOT_DEVICE_NAND_SPI);
97 #elif (!defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
99     return (BOOT_DEVICE_NOR_SPI);
101 #endif
103     v = *((Uint32 *)DEVICE_JTAG_ID_REG);
105     if (v == DEVICE_C6618_JTAG_ID_VAL)
106         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6618;
107     else
108         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6616;
110     switch (params->boot_mode)  {
112 #ifndef EXCLUDE_I2C
113         case BOOT_MODE_I2C:   w = BOOT_DEVICE_I2C;
114                               break;
115 #endif
117 #ifndef EXCLUDE_NOR_SPI
118         case BOOT_MODE_SPI:   w = BOOT_DEVICE_SPI_NOR;
119                               break;
120 #endif
122         default:              w = BOOT_DEVICE_INVALID;
123                               break;
124     
125     }
127     return (w);
130 #define L1PEDCMD            0x01846408
131 #define L2EDCEN             0x01846030
132 #define L2EDCMD             0x01846008
133 #define SMEDCC              0x0BC00010
134 /**
135  *  @brief
136  *      Enable the EDC for the local memory 
137  */
138 void iblEnableEDC ()
140     /* Enable L1P EDC */
141     *(volatile unsigned int *)(L1PEDCMD) = 0x1; //Set EN(bit0)=1        
143     /* Enable EDC L2EDCEN, set DL2CEN(bit0),PL2CEN(bit1),DL2SEN(bit2),PL2SEN(bit3),SDMAEN(bit4)=1 */
144         *(volatile unsigned int *)(L2EDCEN) |= 0x1F;    
146     /* Enalble L2 EDC */
147     *(volatile unsigned int *)(L2EDCMD) = 0x1;
149     /* Enalbe MSMC EDC */
150     *(volatile unsigned int *)(SMEDCC) &= 0x7FFFFFFF;   //Clear SEN(bit31)=0    
151         *(volatile unsigned int *)(SMEDCC) |= 0x40000000;       //Set ECM(bit30)=1      
154 #define FPGA_BM_GPI_STATUS_LO_REG           4   /* Boot Mode GPI Status (07-00 Low Byte) Register */
155 #define FPGA_BM_GPI_STATUS_HI_REG           5   /* Boot Mode GPI Status (15-08 High Byte) Register */
156 #define FPGA_READ_REG_CMD(x)                ((x | 0x80) << 8)
157 /**
158  * @brief
159  *      Enter the ROM boot loader if the FPGA boot register
160  *      indicates it was not I2C address 0x51 boot, this is necessary
161  *      to apply the PLL workaround for non-I2C boot modes
162  */
163 void iblEnterRom ()
165     uint32      reg =  DEVICE_REG32_R (DEVICE_REG_DEVSTAT);
166     uint32      v, dev_stat, bm_lo, bm_hi;
167     void        (*exit)();
169     /* Power up the SPI */
170     devicePowerPeriph (TARGET_PWR_SPI);
172     /* Reset SPI */
173     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
175     /* Release Reset */
176     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_ENABLE);
178     /* CS1, CLK, in and out are functional pins, FPGA uses SPI CS1 */
179     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIPC0, 0xe02);
181     /* prescale=7, char len=16 */
182     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIFMT(0), 0x710);
184     /* C2TDELAY=0x6, T2CDELAY=0x3 */
185     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIDELAY, 0x6030000);
187     /* Clear the SPIDAT0 */
188     //DEVICE_REG32_R (DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0);
190     /* Master mode, enable SPI */
191     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR1, 0x01000003);
193     /* Read the BM status lo register */
194         DEVICE_REG32_W(DEVICE_SPI_BASE(0) + 0x38, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_LO_REG));
195     chipDelay32(10000);
196     v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
197     if ( v & 0x100)
198     {
199         bm_lo = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
200     }
201     else
202     {
203         return;
204     }
206     /* Read the BM status hi register */
207         DEVICE_REG32_W(DEVICE_SPI_BASE(0) + 0x38, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_HI_REG));
208     chipDelay32(10000);
209     v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
210     if ( v & 0x100)
211     {
212         bm_hi = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
213     }
214     else
215     {
216         return;
217     }
219     /* Reset SPI */
220     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
222     if ( (BOOT_READ_BITFIELD(bm_lo,3,1) != 0x5)     ||
223          (BOOT_READ_BITFIELD(bm_hi,3,3) == 0x0) )    
224     { 
225         /* Not i2c boot or i2c boot with address 0x50 */
227         /* Update the DEVSTAT to v1 */
228         dev_stat = DEVICE_REG32_R(DEVICE_REG_DEVSTAT );
229         dev_stat &= ~(0x0000080E);
230         dev_stat |= ((bm_hi << 8) | bm_lo);
231         
232         /* Update the DEVSTAT register for the intended Boot Device and i2c Addr */
233         DEVICE_REG32_W (DEVICE_REG_DEVSTAT, dev_stat);
235         exit = (void (*)())BOOT_ROM_ENTER_ADDRESS;
236         (*exit)();        
237     }
240 #if (!defined(EXCLUDE_NOR_SPI) || !defined(EXCLUDE_NAND_SPI))
241 /**
242  *  @brief
243  *      Return the default hardware configuration for SPI. If this information
244  *      is available in the boot ROM it is used, otherwise defaults are used.
245  */
246 void deviceLoadInitSpiConfig (void *vcfg)
248     uint32 v;
250     spiConfig_t *cfg = (spiConfig_t *)vcfg;
252     BOOT_PARAMS_COMMON_T *params;
253     BOOT_PARAMS_SPI_T    *spip;
255     v = *((Uint32 *)DEVICE_JTAG_ID_REG);
257     if (v == DEVICE_C6618_JTAG_ID_VAL)
258         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6618;
259     else
260         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6616;
263     /* SPI_ROM is a constant defined during make which enables the use of the
264      * parameters from the ROM boot loader */
265     if ((SPI_ROM == 1) && (params->boot_mode == BOOT_MODE_SPI))  {
267         spip = (BOOT_PARAMS_SPI_T *)params;
269         cfg->port      = 0;
270         cfg->mode      = spip->mode;
271         cfg->addrWidth = spip->addrWidth;
272         cfg->npin      = spip->nPins;
273         cfg->csel      = spip->csel;
274         cfg->c2tdelay  = spip->c2tdelay;
276         v = (UINT32)spip->cpuFreqMhz * 1000;  /* CPU frequency in kHz */
277         v = v / (DEVICE_SPI_MOD_DIVIDER * (((UINT32)(spip->busFreqMhz) * 1000) + spip->busFreqKhz));
279         if (v > DEVICE_SPI_MAX_DIVIDER)
280             v = DEVICE_SPI_MAX_DIVIDER;
282         cfg->clkdiv = v;
284     }  else  {
286         cfg->port      = 0;
287         cfg->mode      = SPI_MODE;
288         cfg->addrWidth = SPI_ADDR_WIDTH;
289         cfg->npin      = SPI_NPIN;
290         cfg->csel      = SPI_CSEL;
291         cfg->c2tdelay  = SPI_C2TDEL;
292         cfg->clkdiv    = SPI_CLKDIV;
294     }
300 #endif