1 /**
2 * @file c66xinit.c
3 *
4 * @brief
5 * c66x 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_c66x.h"
17 #define CHIP_LEVEL_REG 0x02620000
18 #define DDR3PLLCTL0 *(volatile unsigned int*)(CHIP_LEVEL_REG + 0x0330)
19 #define DDR3PLLCTL1 *(volatile unsigned int*)(CHIP_LEVEL_REG + 0x0334)
21 static void ddr3_delay (uint32 del)
22 {
23 volatile unsigned int i;
25 for (i = 0; i < del; i++);
27 }
29 /**
30 * @brief Configure the PLLs
31 *
32 * @details
33 * The three PLLs are enabled. Only the main PLL has the ability to configure
34 * the multiplier and dividers.
35 */
36 void devicePllConfig (void)
37 {
38 unsigned int i;
40 /* Unlock the chip registers and leave them unlocked */
41 *((Uint32 *)0x2620038) = 0x83e70b13;
42 *((Uint32 *)0x262003c) = 0x95a4f1e0;
44 if (ibl.pllConfig[ibl_MAIN_PLL].doEnable == TRUE)
45 hwPllSetPll (MAIN_PLL,
46 ibl.pllConfig[ibl_MAIN_PLL].prediv,
47 ibl.pllConfig[ibl_MAIN_PLL].mult,
48 ibl.pllConfig[ibl_MAIN_PLL].postdiv);
51 if (ibl.pllConfig[ibl_DDR_PLL].doEnable == TRUE)
52 hwPllSetCfg2Pll (DEVICE_PLL_BASE(DDR_PLL),
53 ibl.pllConfig[ibl_DDR_PLL].prediv,
54 ibl.pllConfig[ibl_DDR_PLL].mult,
55 ibl.pllConfig[ibl_DDR_PLL].postdiv,
56 ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz,
57 ibl.pllConfig[ibl_DDR_PLL].pllOutFreqMhz);
60 if (ibl.pllConfig[ibl_NET_PLL].doEnable == TRUE)
61 hwPllSetCfgPll (DEVICE_PLL_BASE(NET_PLL),
62 ibl.pllConfig[ibl_NET_PLL].prediv,
63 ibl.pllConfig[ibl_NET_PLL].mult,
64 ibl.pllConfig[ibl_NET_PLL].postdiv,
65 ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz,
66 ibl.pllConfig[ibl_NET_PLL].pllOutFreqMhz);
68 }
71 /**
72 * @brief
73 * Return the endian status of the device
74 *
75 * @details
76 * Returns true if the device is executing in little endian mode
77 */
78 extern cregister volatile unsigned int CSR;
80 bool deviceIsLittleEndian (void)
81 {
82 if ((CSR & (1 << 8)) == 0)
83 return (FALSE);
85 return (TRUE);
87 }
90 /**
91 * @brief
92 * Return the device used for the second stage program load.
93 * For SPI NAND a second stage loader is required and this
94 * function must be changed to locate that fingerprint.
95 */
96 int32 deviceReadBootDevice (void)
97 {
98 uint32 v;
99 int32 w;
101 BOOT_PARAMS_COMMON_T *params;
103 #if (defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && !defined(EXCLUDE_I2C))
105 return (BOOT_DEVICE_I2C);
107 #elif (defined(EXCLUDE_NOR_SPI) && !defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
109 return (BOOT_DEVICE_NAND_SPI);
111 #elif (!defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
113 return (BOOT_DEVICE_NOR_SPI);
115 #endif
117 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
118 v &= DEVICE_JTAG_ID_MASK;
120 if (v == DEVICE_C6678_JTAG_ID_VAL)
121 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6678;
122 else
123 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6670;
125 switch (params->boot_mode) {
127 #ifndef EXCLUDE_I2C
128 case BOOT_MODE_I2C: w = BOOT_DEVICE_I2C;
129 break;
130 #endif
132 #ifndef EXCLUDE_NOR_SPI
133 case BOOT_MODE_SPI: w = BOOT_DEVICE_SPI_NOR;
134 break;
135 #endif
137 default: w = BOOT_DEVICE_INVALID;
138 break;
140 }
142 return (w);
143 }
145 #define L1PEDCMD 0x01846408
146 #define L2EDCEN 0x01846030
147 #define L2EDCMD 0x01846008
148 #define SMEDCC 0x0BC00010
149 /**
150 * @brief
151 * Enable the EDC for the local memory
152 */
153 void iblEnableEDC ()
154 {
155 /* Enable L1P EDC */
156 *(volatile unsigned int *)(L1PEDCMD) = 0x1; //Set EN(bit0)=1
158 /* Enable EDC L2EDCEN, set DL2CEN(bit0),PL2CEN(bit1),DL2SEN(bit2),PL2SEN(bit3),SDMAEN(bit4)=1 */
159 *(volatile unsigned int *)(L2EDCEN) |= 0x1F;
161 /* Enalble L2 EDC */
162 *(volatile unsigned int *)(L2EDCMD) = 0x1;
164 /* Enalbe MSMC EDC */
165 *(volatile unsigned int *)(SMEDCC) &= 0x7FFFFFFF; //Clear SEN(bit31)=0
166 *(volatile unsigned int *)(SMEDCC) |= 0x40000000; //Set ECM(bit30)=1
167 }
169 #ifdef IBL_ENABLE_PCIE_WORKAROUND
171 /* undocumented register in data manual
172 * Bit 0 of this register is supposed to give the status of PCIe PLL lock*/
173 #define PCIE_STS_REG 0x262015C
175 /* Workaround for PCIe boot mode support for C6678/C6670 */
176 /* This is a temporary workaround should be removed once fixed in RBL */
178 /* PCIe Config register base on C6678/C6670 */
179 #define PCIE_BASE_ADDR 0x21800000
181 /* PCIe Application registers */
182 #define PCIE_APP_CMD_STATUS 0x4
183 #define PCIE_APP_OB_SIZE 0x30
184 #define PCIE_APP_SERDES_CFG0 0x390
185 #define PCIE_APP_SERDES_CFG1 0x394
187 /* PCIe Local Configuration registers */
188 #define PCIE_VENDER_DEVICE_ID 0x1000
189 #define PCIE_STATUS_CMD 0x1004
190 #define PCIE_CLASSCODE_REVID 0x1008
191 #define PCIE_BAR0 0x1010
192 #define PCIE_BAR1 0x1014
193 #define PCIE_BAR2 0x1018
194 #define PCIE_BAR3 0x101c
195 #define PCIE_DEVICE_CAP 0x1074
196 #define PCIE_DEV_STAT_CTRL 0x1078
197 #define PCIE_LINK_STAT_CTRL 0x1080
198 #define PCIE_ACCR 0x1118
199 #define PCIE_DEBUG0 0x1728
200 #define PCIE_PL_GEN2 0x180C
202 /* SERDES Configuration registers */
203 #define PCIE_SERDES_CFG_PLL 0x2620358
205 void waitForBoot(UINT32 MAGIC_ADDR)
206 {
207 void (*exit)();
208 UINT32 i, entry_addr;
210 while(1)
211 {
212 entry_addr = DEVICE_REG32_R(MAGIC_ADDR);
213 if (entry_addr != 0)
214 {
215 /* jump to the exit point, which will be the entry point for the full IBL */
216 exit = (void (*)())entry_addr;
217 (*exit)();
218 }
219 for (i=0; i < 100; i++)
220 asm("nop");
221 }
222 }
224 void iblPCIeWorkaround()
225 {
226 UINT32 v, flag_6678 = 0, flag_6670 = 0, MAGIC_ADDR;
227 UINT32 i;
229 /* Power up PCIe */
230 devicePowerPeriph (TARGET_PWR_PCIE);
231 for(i=0; i<1000; i++) asm (" NOP");
233 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_SERDES_CFG0), 0x00062320); /* ss clock */
234 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_SERDES_CFG1), 0x00022320); /* ss clock */
236 /* Wait for PCIe PLL lock */
237 while(!(DEVICE_REG32_R(PCIE_STS_REG) & 1));
239 /* Determine 6670 or 6678 */
240 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
241 v &= DEVICE_JTAG_ID_MASK;
243 if (v == DEVICE_C6678_JTAG_ID_VAL) {
244 MAGIC_ADDR = 0x87fffc;
245 flag_6678 = 1;
246 }
247 if (v == DEVICE_C6670_JTAG_ID_VAL) {
248 MAGIC_ADDR = 0x8ffffc;
249 flag_6670 = 1;
250 }
252 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_CLASSCODE_REVID), 0x04800001); /* class 0x04, sub-class 0x80, Prog I/F 0x00, Other multimedia device */
253 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_LINK_STAT_CTRL), 0x10110080); /* extended sync, slot_clk_cfg = 1 */
255 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_VENDER_DEVICE_ID), 0xb005104c); /* Vendor and Device ID */
256 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_DEVICE_CAP), 0x288701); /* L0 = 4, L1 = 3 */
258 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_OB_SIZE), 0x00000003); /* OB_SIZE = 8M */
259 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_PL_GEN2), 0x0000000F); /* num_fts = 0xF*/
261 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0020); /* Set dbi_cs2 to allow access to the BAR registers */
263 if (flag_6678) {
264 /* 6678 */
265 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF); /* 4K */
266 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x0007FFFF); /* 512K */
267 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x003FFFFF); /* 4M */
268 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF); /* 16M */
269 }
271 if (flag_6670) {
272 /* 6670 */
273 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF); /* 4K */
274 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x000FFFFF); /* 1M */
275 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x001FFFFF); /* 2M */
276 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF); /* 16M */
277 }
279 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0); /* dbi_cs2=0 */
281 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_STATUS_CMD), 0x00100146); /* ENABLE mem access */
282 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_DEV_STAT_CTRL), 0x0000281F); /* Error control */
283 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_ACCR), 0x000001E0); /* Error control */
284 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0); /* non-prefetch, 32-bit, mem bar */
286 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0000007); /* enable LTSSM, IN, OB */
287 while((DEVICE_REG32_R(PCIE_BASE_ADDR + PCIE_DEBUG0) & 0x11)!=0x11); /* Wait for training to complete */
289 /* Wait for the Boot from Host */
290 DEVICE_REG32_W(MAGIC_ADDR, 0);
291 waitForBoot(MAGIC_ADDR);
293 /* Will never reach here */
294 return;
295 }
297 #endif
299 #define FPGA_BM_GPI_STATUS_LO_REG 4 /* Boot Mode GPI Status (07-00 Low Byte) Register */
300 #define FPGA_BM_GPI_STATUS_HI_REG 5 /* Boot Mode GPI Status (15-08 High Byte) Register */
301 #define FPGA_ICS557_SEL_CTRL_REG 0x50 /* ICS 557 Clock Selection
302 Control Register*/
303 #define FPGA_READ_REG_CMD(x) ((x | 0x80) << 8)
304 #define FPGA_WRITE_REG_CMD(addr,byte) (((addr & 0x7f) << 8) | (byte & 0xff))
306 /**
307 * @brief
308 * Enter the ROM boot loader if the FPGA boot register
309 * indicates it was not I2C address 0x51 boot, this is necessary
310 * to apply the PLL workaround for non-I2C boot modes
311 */
312 void iblEnterRom ()
313 {
314 uint32 v, dev_stat, bm_lo, bm_hi;
315 void (*exit)();
317 /* Power up the SPI */
318 devicePowerPeriph (TARGET_PWR_SPI);
320 /* Reset SPI */
321 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
323 /* Release Reset */
324 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_ENABLE);
326 /* CS1, CLK, in and out are functional pins, FPGA uses SPI CS1 */
327 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIPC0, 0xe02);
329 /* prescale=7, char len=16 */
330 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIFMT(0), 0x710);
332 /* C2TDELAY=0x6, T2CDELAY=0x3 */
333 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIDELAY, 0x6030000);
335 /* Clear the SPIDAT0 */
336 //DEVICE_REG32_R (DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0);
338 /* Master mode, enable SPI */
339 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR1, 0x01000003);
341 /* Read the BM status lo register */
342 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_LO_REG));
343 chipDelay32(10000);
344 v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
345 if ( v & 0x100)
346 {
347 bm_lo = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
348 }
349 else
350 {
351 return;
352 }
354 /* Read the BM status hi register */
355 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_HI_REG));
356 chipDelay32(10000);
357 v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
358 if ( v & 0x100)
359 {
360 bm_hi = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
361 }
362 else
363 {
364 return;
365 }
368 if ( (BOOT_READ_BITFIELD(bm_lo,3,1) != 0x5) ||
369 (BOOT_READ_BITFIELD(bm_hi,3,3) == 0x0) )
370 {
371 /* Not i2c boot or i2c boot with address 0x50 */
373 /* Update the DEVSTAT to v1 */
374 dev_stat = DEVICE_REG32_R(DEVICE_REG_DEVSTAT );
375 dev_stat &= ~(0x0000080E);
376 dev_stat |= ((bm_hi << 8) | bm_lo);
378 /* Update the DEVSTAT register for the intended Boot Device and i2c Addr */
379 DEVICE_REG32_W (DEVICE_REG_DEVSTAT, dev_stat);
381 #ifdef IBL_ENABLE_PCIE_WORKAROUND
382 #define BOOT_DEVICE_MASK 0xE
383 #define DEVSTAT_BOOTDEVICE_SHIFT 1
384 #define PCI_BOOT_MODE 0x4
386 if (((dev_stat & BOOT_DEVICE_MASK)>>DEVSTAT_BOOTDEVICE_SHIFT) == PCI_BOOT_MODE) {
387 /* Write ICS 557 Clock Selection Control Register in the FPGA */
388 /* 1 : FPGA_ICS557_SEL s driven high */
389 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0,
390 FPGA_WRITE_REG_CMD(FPGA_ICS557_SEL_CTRL_REG,1));
391 chipDelay32(10000);
392 /* Reset SPI */
393 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
395 iblPCIeWorkaround();
396 /* Will never reach here */
397 }
398 #endif
399 /* Reset SPI */
400 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
402 exit = (void (*)())BOOT_ROM_ENTER_ADDRESS;
403 (*exit)();
404 }
405 else
406 {
407 /* Update the DEVSTAT register for the actual boot configuration */
408 DEVICE_REG32_W (DEVICE_REG_DEVSTAT, ((bm_hi << 8) | bm_lo));
409 }
411 /* Reset SPI */
412 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
413 }
415 #if (!defined(EXCLUDE_NOR_SPI) || !defined(EXCLUDE_NAND_SPI))
416 /**
417 * @brief
418 * Return the default hardware configuration for SPI. If this information
419 * is available in the boot ROM it is used, otherwise defaults are used.
420 */
421 void deviceLoadInitSpiConfig (void *vcfg)
422 {
423 uint32 v;
425 spiConfig_t *cfg = (spiConfig_t *)vcfg;
427 BOOT_PARAMS_COMMON_T *params;
428 BOOT_PARAMS_SPI_T *spip;
430 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
431 v &= DEVICE_JTAG_ID_MASK;
433 if (v == DEVICE_C6678_JTAG_ID_VAL)
434 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6678;
435 else
436 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6670;
439 /* SPI_ROM is a constant defined during make which enables the use of the
440 * parameters from the ROM boot loader */
441 if ((SPI_ROM == 1) && (params->boot_mode == BOOT_MODE_SPI)) {
443 spip = (BOOT_PARAMS_SPI_T *)params;
445 cfg->port = 0;
446 cfg->mode = spip->mode;
447 cfg->addrWidth = spip->addrWidth;
448 cfg->npin = spip->nPins;
449 cfg->csel = spip->csel;
450 cfg->c2tdelay = spip->c2tdelay;
452 v = (UINT32)spip->cpuFreqMhz * 1000; /* CPU frequency in kHz */
453 v = v / (DEVICE_SPI_MOD_DIVIDER * (((UINT32)(spip->busFreqMhz) * 1000) + spip->busFreqKhz));
455 if (v > DEVICE_SPI_MAX_DIVIDER)
456 v = DEVICE_SPI_MAX_DIVIDER;
458 cfg->clkdiv = v;
460 } else {
462 cfg->port = 0;
463 cfg->mode = SPI_MODE;
464 cfg->addrWidth = SPI_ADDR_WIDTH;
465 cfg->npin = SPI_NPIN;
466 cfg->csel = SPI_CSEL;
467 cfg->c2tdelay = SPI_C2TDEL;
468 cfg->clkdiv = SPI_CLKDIV;
470 }
472 }
473 #endif