]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/ibl.git/blob - src/device/c661x/c661xinit.c
Changes to make IBL NAND boot work on C6670 Beta-2 EVM
[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);
104     v &= DEVICE_JTAG_ID_MASK;
106     if (v == DEVICE_C6678_JTAG_ID_VAL)
107         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6678;
108     else
109         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6670;
111     switch (params->boot_mode)  {
113 #ifndef EXCLUDE_I2C
114         case BOOT_MODE_I2C:   w = BOOT_DEVICE_I2C;
115                               break;
116 #endif
118 #ifndef EXCLUDE_NOR_SPI
119         case BOOT_MODE_SPI:   w = BOOT_DEVICE_SPI_NOR;
120                               break;
121 #endif
123         default:              w = BOOT_DEVICE_INVALID;
124                               break;
125     
126     }
128     return (w);
131 #define L1PEDCMD            0x01846408
132 #define L2EDCEN             0x01846030
133 #define L2EDCMD             0x01846008
134 #define SMEDCC              0x0BC00010
135 /**
136  *  @brief
137  *      Enable the EDC for the local memory 
138  */
139 void iblEnableEDC ()
141     /* Enable L1P EDC */
142     *(volatile unsigned int *)(L1PEDCMD) = 0x1; //Set EN(bit0)=1        
144     /* Enable EDC L2EDCEN, set DL2CEN(bit0),PL2CEN(bit1),DL2SEN(bit2),PL2SEN(bit3),SDMAEN(bit4)=1 */
145         *(volatile unsigned int *)(L2EDCEN) |= 0x1F;    
147     /* Enalble L2 EDC */
148     *(volatile unsigned int *)(L2EDCMD) = 0x1;
150     /* Enalbe MSMC EDC */
151     *(volatile unsigned int *)(SMEDCC) &= 0x7FFFFFFF;   //Clear SEN(bit31)=0    
152         *(volatile unsigned int *)(SMEDCC) |= 0x40000000;       //Set ECM(bit30)=1      
155 #define FPGA_BM_GPI_STATUS_LO_REG           4   /* Boot Mode GPI Status (07-00 Low Byte) Register */
156 #define FPGA_BM_GPI_STATUS_HI_REG           5   /* Boot Mode GPI Status (15-08 High Byte) Register */
157 #define FPGA_READ_REG_CMD(x)                ((x | 0x80) << 8)
158 /**
159  * @brief
160  *      Enter the ROM boot loader if the FPGA boot register
161  *      indicates it was not I2C address 0x51 boot, this is necessary
162  *      to apply the PLL workaround for non-I2C boot modes
163  */
164 void iblEnterRom ()
166     uint32      reg =  DEVICE_REG32_R (DEVICE_REG_DEVSTAT);
167     uint32      v, dev_stat, bm_lo, bm_hi;
168     void        (*exit)();
170     /* Power up the SPI */
171     devicePowerPeriph (TARGET_PWR_SPI);
173     /* Reset SPI */
174     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
176     /* Release Reset */
177     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_ENABLE);
179     /* CS1, CLK, in and out are functional pins, FPGA uses SPI CS1 */
180     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIPC0, 0xe02);
182     /* prescale=7, char len=16 */
183     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIFMT(0), 0x710);
185     /* C2TDELAY=0x6, T2CDELAY=0x3 */
186     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIDELAY, 0x6030000);
188     /* Clear the SPIDAT0 */
189     //DEVICE_REG32_R (DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0);
191     /* Master mode, enable SPI */
192     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR1, 0x01000003);
194     /* Read the BM status lo register */
195         DEVICE_REG32_W(DEVICE_SPI_BASE(0) + 0x38, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_LO_REG));
196     chipDelay32(10000);
197     v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
198     if ( v & 0x100)
199     {
200         bm_lo = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
201     }
202     else
203     {
204         return;
205     }
207     /* Read the BM status hi register */
208         DEVICE_REG32_W(DEVICE_SPI_BASE(0) + 0x38, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_HI_REG));
209     chipDelay32(10000);
210     v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
211     if ( v & 0x100)
212     {
213         bm_hi = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
214     }
215     else
216     {
217         return;
218     }
220     /* Reset SPI */
221     DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
223     if ( (BOOT_READ_BITFIELD(bm_lo,3,1) != 0x5)     ||
224          (BOOT_READ_BITFIELD(bm_hi,3,3) == 0x0) )    
225     { 
226         /* Not i2c boot or i2c boot with address 0x50 */
228         /* Update the DEVSTAT to v1 */
229         dev_stat = DEVICE_REG32_R(DEVICE_REG_DEVSTAT );
230         dev_stat &= ~(0x0000080E);
231         dev_stat |= ((bm_hi << 8) | bm_lo);
232         
233         /* Update the DEVSTAT register for the intended Boot Device and i2c Addr */
234         DEVICE_REG32_W (DEVICE_REG_DEVSTAT, dev_stat);
236         exit = (void (*)())BOOT_ROM_ENTER_ADDRESS;
237         (*exit)();        
238     }
239     else
240     {
241         /* Update the DEVSTAT register for the actual boot configuration */
242         DEVICE_REG32_W (DEVICE_REG_DEVSTAT, ((bm_hi << 8) | bm_lo));
243     }
246 #if (!defined(EXCLUDE_NOR_SPI) || !defined(EXCLUDE_NAND_SPI))
247 /**
248  *  @brief
249  *      Return the default hardware configuration for SPI. If this information
250  *      is available in the boot ROM it is used, otherwise defaults are used.
251  */
252 void deviceLoadInitSpiConfig (void *vcfg)
254     uint32 v;
256     spiConfig_t *cfg = (spiConfig_t *)vcfg;
258     BOOT_PARAMS_COMMON_T *params;
259     BOOT_PARAMS_SPI_T    *spip;
261     v = *((Uint32 *)DEVICE_JTAG_ID_REG);
262     v &= DEVICE_JTAG_ID_MASK;
264     if (v == DEVICE_C6678_JTAG_ID_VAL)
265         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6678;
266     else
267         params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6670;
270     /* SPI_ROM is a constant defined during make which enables the use of the
271      * parameters from the ROM boot loader */
272     if ((SPI_ROM == 1) && (params->boot_mode == BOOT_MODE_SPI))  {
274         spip = (BOOT_PARAMS_SPI_T *)params;
276         cfg->port      = 0;
277         cfg->mode      = spip->mode;
278         cfg->addrWidth = spip->addrWidth;
279         cfg->npin      = spip->nPins;
280         cfg->csel      = spip->csel;
281         cfg->c2tdelay  = spip->c2tdelay;
283         v = (UINT32)spip->cpuFreqMhz * 1000;  /* CPU frequency in kHz */
284         v = v / (DEVICE_SPI_MOD_DIVIDER * (((UINT32)(spip->busFreqMhz) * 1000) + spip->busFreqKhz));
286         if (v > DEVICE_SPI_MAX_DIVIDER)
287             v = DEVICE_SPI_MAX_DIVIDER;
289         cfg->clkdiv = v;
291     }  else  {
293         cfg->port      = 0;
294         cfg->mode      = SPI_MODE;
295         cfg->addrWidth = SPI_ADDR_WIDTH;
296         cfg->npin      = SPI_NPIN;
297         cfg->csel      = SPI_CSEL;
298         cfg->c2tdelay  = SPI_C2TDEL;
299         cfg->clkdiv    = SPI_CLKDIV;
301     }
307 #endif