58c144d788c99d039b72be0bb5953a1210f963d0
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;
125 }
127 return (w);
128 }
130 #define FPGA_BOOT_MODE_REG 0
131 #define FPGA_READ_BOOT_MODE_REG_CMD ((FPGA_BOOT_MODE_REG | 0x80) << 8)
132 /**
133 * @brief
134 * Re-enter the ROM boot loader if the FPGA boot register
135 * indicates it was not I2C or SPI boot, this is necessary
136 * to apply the PLL workaround for ROM boot modes
137 */
138 void iblReEnterRom ()
139 {
140 uint32 reg = DEVICE_REG32_R (DEVICE_REG_DEVSTAT);
141 uint32 v;
142 void (*exit)();
144 /* Reset */
145 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
147 /* Release Reset */
148 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_ENABLE);
150 /* CS1, CLK, in and out are functional pins, FPGA uses SPI CS1 */
151 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIPC0, 0xe02);
153 /* prescale=7, char len=16 */
154 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIFMT(0), 0x710);
156 /* C2TDELAY=0x6, T2CDELAY=0x3 */
157 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIDELAY, 0x6030000);
159 /* Clear the SPIDAT0 */
160 //DEVICE_REG32_R (DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0);
162 /* Master mode, enable SPI */
163 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR1, 0x01000003);
165 /* Send the read register address to FPGA */
166 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + 0x38, FPGA_READ_BOOT_MODE_REG_CMD);
168 chipDelay32(10000);
170 /* Check if received the data */
171 v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
172 if ( v & 0x100)
173 {
174 v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
176 /* Add code to check the boot mode in FPGA register, if not I2C, configure the
177 devstat with the actual boot mode and re-enter ROM boot loader */
178 #if 0
179 exit = (void (*)())BOOT_ROM_REENTER_ADDRESS;
180 (*exit)();
181 #endif
182 }
184 }
188 #if (!defined(EXCLUDE_NOR_SPI) || !defined(EXCLUDE_NAND_SPI))
189 /**
190 * @brief
191 * Return the default hardware configuration for SPI. If this information
192 * is available in the boot ROM it is used, otherwise defaults are used.
193 */
194 void deviceLoadInitSpiConfig (void *vcfg)
195 {
196 uint32 v;
198 spiConfig_t *cfg = (spiConfig_t *)vcfg;
200 BOOT_PARAMS_COMMON_T *params;
201 BOOT_PARAMS_SPI_T *spip;
203 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
205 if (v == DEVICE_C6618_JTAG_ID_VAL)
206 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6618;
207 else
208 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6616;
211 /* SPI_ROM is a constant defined during make which enables the use of the
212 * parameters from the ROM boot loader */
213 if ((SPI_ROM == 1) && (params->boot_mode == BOOT_MODE_SPI)) {
215 spip = (BOOT_PARAMS_SPI_T *)params;
217 cfg->port = 0;
218 cfg->mode = spip->mode;
219 cfg->addrWidth = spip->addrWidth;
220 cfg->npin = spip->nPins;
221 cfg->csel = spip->csel;
222 cfg->c2tdelay = spip->c2tdelay;
224 v = (UINT32)spip->cpuFreqMhz * 1000; /* CPU frequency in kHz */
225 v = v / (DEVICE_SPI_MOD_DIVIDER * (((UINT32)(spip->busFreqMhz) * 1000) + spip->busFreqKhz));
227 if (v > DEVICE_SPI_MAX_DIVIDER)
228 v = DEVICE_SPI_MAX_DIVIDER;
230 cfg->clkdiv = v;
232 } else {
234 cfg->port = 0;
235 cfg->mode = SPI_MODE;
236 cfg->addrWidth = SPI_ADDR_WIDTH;
237 cfg->npin = SPI_NPIN;
238 cfg->csel = SPI_CSEL;
239 cfg->c2tdelay = SPI_C2TDEL;
240 cfg->clkdiv = SPI_CLKDIV;
242 }
244 }
248 #endif