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);
52 /* 1333 MHz data rate */
53 /***************** 2.2 DDR3 PLL Configuration ************/
54 DDR3PLLCTL1 |= 0x00000040; //Set ENSAT bit = 1
55 DDR3PLLCTL0 |= 0x00800000; // Set BYPASS = 1
56 DDR3PLLCTL1 |= 0x00002000; //Set RESET bit = 1
58 DDR3PLLCTL0 = 0x090804C0; //Configure CLKR, CLKF, CLKOD, BWADJ
60 for (i = 0;i < 20;i++)
61 ddr3_delay(1000); //Wait for reset to complete
63 DDR3PLLCTL1 &= ~(0x00002000); //Clear RESET bit
65 for (i = 0;i < 500;i++)
66 ddr3_delay(1000); //Wait for PLL lock
68 DDR3PLLCTL0 &= ~(0x00800000); // Set BYPASS = 0
70 #if 0
72 if (ibl.pllConfig[ibl_DDR_PLL].doEnable == TRUE)
73 hwPllSetCfg2Pll (DEVICE_PLL_BASE(DDR_PLL),
74 ibl.pllConfig[ibl_DDR_PLL].prediv,
75 ibl.pllConfig[ibl_DDR_PLL].mult,
76 ibl.pllConfig[ibl_DDR_PLL].postdiv,
77 ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz,
78 ibl.pllConfig[ibl_DDR_PLL].pllOutFreqMhz);
80 #endif
82 if (ibl.pllConfig[ibl_NET_PLL].doEnable == TRUE)
83 hwPllSetCfgPll (DEVICE_PLL_BASE(NET_PLL),
84 ibl.pllConfig[ibl_NET_PLL].prediv,
85 ibl.pllConfig[ibl_NET_PLL].mult,
86 ibl.pllConfig[ibl_NET_PLL].postdiv,
87 ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz,
88 ibl.pllConfig[ibl_NET_PLL].pllOutFreqMhz);
91 }
94 /**
95 * @brief
96 * Return the endian status of the device
97 *
98 * @details
99 * Returns true if the device is executing in little endian mode
100 */
101 extern cregister volatile unsigned int CSR;
103 bool deviceIsLittleEndian (void)
104 {
105 if ((CSR & (1 << 8)) == 0)
106 return (FALSE);
108 return (TRUE);
110 }
113 /**
114 * @brief
115 * Return the device used for the second stage program load.
116 * For SPI NAND a second stage loader is required and this
117 * function must be changed to locate that fingerprint.
118 */
119 int32 deviceReadBootDevice (void)
120 {
121 uint32 v;
122 int32 w;
124 BOOT_PARAMS_COMMON_T *params;
126 #if (defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && !defined(EXCLUDE_I2C))
128 return (BOOT_DEVICE_I2C);
130 #elif (defined(EXCLUDE_NOR_SPI) && !defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
132 return (BOOT_DEVICE_NAND_SPI);
134 #elif (!defined(EXCLUDE_NOR_SPI) && defined(EXCLUDE_NAND_SPI) && defined(EXCLUDE_I2C))
136 return (BOOT_DEVICE_NOR_SPI);
138 #endif
140 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
141 v &= DEVICE_JTAG_ID_MASK;
143 if (v == DEVICE_C6678_JTAG_ID_VAL)
144 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6678;
145 else
146 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6670;
148 switch (params->boot_mode) {
150 #ifndef EXCLUDE_I2C
151 case BOOT_MODE_I2C: w = BOOT_DEVICE_I2C;
152 break;
153 #endif
155 #ifndef EXCLUDE_NOR_SPI
156 case BOOT_MODE_SPI: w = BOOT_DEVICE_SPI_NOR;
157 break;
158 #endif
160 default: w = BOOT_DEVICE_INVALID;
161 break;
163 }
165 return (w);
166 }
168 #define L1PEDCMD 0x01846408
169 #define L2EDCEN 0x01846030
170 #define L2EDCMD 0x01846008
171 #define SMEDCC 0x0BC00010
172 /**
173 * @brief
174 * Enable the EDC for the local memory
175 */
176 void iblEnableEDC ()
177 {
178 /* Enable L1P EDC */
179 *(volatile unsigned int *)(L1PEDCMD) = 0x1; //Set EN(bit0)=1
181 /* Enable EDC L2EDCEN, set DL2CEN(bit0),PL2CEN(bit1),DL2SEN(bit2),PL2SEN(bit3),SDMAEN(bit4)=1 */
182 *(volatile unsigned int *)(L2EDCEN) |= 0x1F;
184 /* Enalble L2 EDC */
185 *(volatile unsigned int *)(L2EDCMD) = 0x1;
187 /* Enalbe MSMC EDC */
188 *(volatile unsigned int *)(SMEDCC) &= 0x7FFFFFFF; //Clear SEN(bit31)=0
189 *(volatile unsigned int *)(SMEDCC) |= 0x40000000; //Set ECM(bit30)=1
190 }
192 #ifdef IBL_ENABLE_PCIE_WORKAROUND
194 /* undocumented register in data manual
195 * Bit 0 of this register is supposed to give the status of PCIe PLL lock*/
196 #define PCIE_STS_REG 0x262015C
198 /* Workaround for PCIe boot mode support for C6678/C6670 */
199 /* This is a temporary workaround should be removed once fixed in RBL */
201 /* PCIe Config register base on C6678/C6670 */
202 #define PCIE_BASE_ADDR 0x21800000
204 /* PCIe Application registers */
205 #define PCIE_APP_CMD_STATUS 0x4
206 #define PCIE_APP_OB_SIZE 0x30
207 #define PCIE_APP_SERDES_CFG0 0x390
208 #define PCIE_APP_SERDES_CFG1 0x394
210 /* PCIe Local Configuration registers */
211 #define PCIE_VENDER_DEVICE_ID 0x1000
212 #define PCIE_STATUS_CMD 0x1004
213 #define PCIE_CLASSCODE_REVID 0x1008
214 #define PCIE_BAR0 0x1010
215 #define PCIE_BAR1 0x1014
216 #define PCIE_BAR2 0x1018
217 #define PCIE_BAR3 0x101c
218 #define PCIE_DEVICE_CAP 0x1074
219 #define PCIE_DEV_STAT_CTRL 0x1078
220 #define PCIE_LINK_STAT_CTRL 0x1080
221 #define PCIE_ACCR 0x1118
222 #define PCIE_DEBUG0 0x1728
223 #define PCIE_PL_GEN2 0x180C
225 /* SERDES Configuration registers */
226 #define PCIE_SERDES_CFG_PLL 0x2620358
228 void waitForBoot(UINT32 MAGIC_ADDR)
229 {
230 void (*exit)();
231 UINT32 i, entry_addr;
233 while(1)
234 {
235 entry_addr = DEVICE_REG32_R(MAGIC_ADDR);
236 if (entry_addr != 0)
237 {
238 /* jump to the exit point, which will be the entry point for the full IBL */
239 exit = (void (*)())entry_addr;
240 (*exit)();
241 }
242 for (i=0; i < 100; i++)
243 asm("nop");
244 }
245 }
247 void iblPCIeWorkaround()
248 {
249 UINT32 v, flag_6678 = 0, flag_6670 = 0, MAGIC_ADDR;
250 UINT32 i;
252 /* Power up PCIe */
253 devicePowerPeriph (TARGET_PWR_PCIE);
254 for(i=0; i<1000; i++) asm (" NOP");
256 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_SERDES_CFG0), 0x00062320); /* ss clock */
257 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_SERDES_CFG1), 0x00022320); /* ss clock */
259 /* Wait for PCIe PLL lock */
260 while(!(DEVICE_REG32_R(PCIE_STS_REG) & 1));
262 /* Determine 6670 or 6678 */
263 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
264 v &= DEVICE_JTAG_ID_MASK;
266 if (v == DEVICE_C6678_JTAG_ID_VAL) {
267 MAGIC_ADDR = 0x87fffc;
268 flag_6678 = 1;
269 }
270 if (v == DEVICE_C6670_JTAG_ID_VAL) {
271 MAGIC_ADDR = 0x8ffffc;
272 flag_6670 = 1;
273 }
275 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_CLASSCODE_REVID), 0x04800001); /* class 0x04, sub-class 0x80, Prog I/F 0x00, Other multimedia device */
276 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_LINK_STAT_CTRL), 0x10110080); /* extended sync, slot_clk_cfg = 1 */
278 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_VENDER_DEVICE_ID), 0xb005104c); /* Vendor and Device ID */
279 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_DEVICE_CAP), 0x288701); /* L0 = 4, L1 = 3 */
281 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_OB_SIZE), 0x00000003); /* OB_SIZE = 8M */
282 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_PL_GEN2), 0x0000000F); /* num_fts = 0xF*/
284 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0020); /* Set dbi_cs2 to allow access to the BAR registers */
286 if (flag_6678) {
287 /* 6678 */
288 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF); /* 4K */
289 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x0007FFFF); /* 512K */
290 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x003FFFFF); /* 4M */
291 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF); /* 16M */
292 }
294 if (flag_6670) {
295 /* 6670 */
296 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0x00000FFF); /* 4K */
297 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR1), 0x000FFFFF); /* 1M */
298 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR2), 0x001FFFFF); /* 2M */
299 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR3), 0x00FFFFFF); /* 16M */
300 }
302 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0); /* dbi_cs2=0 */
304 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_STATUS_CMD), 0x00100146); /* ENABLE mem access */
305 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_DEV_STAT_CTRL), 0x0000281F); /* Error control */
306 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_ACCR), 0x000001E0); /* Error control */
307 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_BAR0), 0); /* non-prefetch, 32-bit, mem bar */
309 DEVICE_REG32_W ((PCIE_BASE_ADDR + PCIE_APP_CMD_STATUS), 0x0000007); /* enable LTSSM, IN, OB */
310 while((DEVICE_REG32_R(PCIE_BASE_ADDR + PCIE_DEBUG0) & 0x11)!=0x11); /* Wait for training to complete */
312 /* Wait for the Boot from Host */
313 DEVICE_REG32_W(MAGIC_ADDR, 0);
314 waitForBoot(MAGIC_ADDR);
316 /* Will never reach here */
317 return;
318 }
320 #endif
322 #define FPGA_BM_GPI_STATUS_LO_REG 4 /* Boot Mode GPI Status (07-00 Low Byte) Register */
323 #define FPGA_BM_GPI_STATUS_HI_REG 5 /* Boot Mode GPI Status (15-08 High Byte) Register */
324 #define FPGA_ICS557_SEL_CTRL_REG 0x50 /* ICS 557 Clock Selection
325 Control Register*/
326 #define FPGA_READ_REG_CMD(x) ((x | 0x80) << 8)
327 #define FPGA_WRITE_REG_CMD(addr,byte) (((addr & 0x7f) << 8) | (byte & 0xff))
329 /**
330 * @brief
331 * Enter the ROM boot loader if the FPGA boot register
332 * indicates it was not I2C address 0x51 boot, this is necessary
333 * to apply the PLL workaround for non-I2C boot modes
334 */
335 void iblEnterRom ()
336 {
337 uint32 v, dev_stat, bm_lo, bm_hi;
338 void (*exit)();
340 /* Power up the SPI */
341 devicePowerPeriph (TARGET_PWR_SPI);
343 /* Reset SPI */
344 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
346 /* Release Reset */
347 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_ENABLE);
349 /* CS1, CLK, in and out are functional pins, FPGA uses SPI CS1 */
350 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIPC0, 0xe02);
352 /* prescale=7, char len=16 */
353 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIFMT(0), 0x710);
355 /* C2TDELAY=0x6, T2CDELAY=0x3 */
356 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIDELAY, 0x6030000);
358 /* Clear the SPIDAT0 */
359 //DEVICE_REG32_R (DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0);
361 /* Master mode, enable SPI */
362 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR1, 0x01000003);
364 /* Read the BM status lo register */
365 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_LO_REG));
366 chipDelay32(10000);
367 v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
368 if ( v & 0x100)
369 {
370 bm_lo = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
371 }
372 else
373 {
374 return;
375 }
377 /* Read the BM status hi register */
378 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0, FPGA_READ_REG_CMD(FPGA_BM_GPI_STATUS_HI_REG));
379 chipDelay32(10000);
380 v = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIFLG);
381 if ( v & 0x100)
382 {
383 bm_hi = DEVICE_REG32_R(DEVICE_SPI_BASE(0) + SPI_REG_SPIBUF) & 0xff;
384 }
385 else
386 {
387 return;
388 }
391 if ( (BOOT_READ_BITFIELD(bm_lo,3,1) != 0x5) ||
392 (BOOT_READ_BITFIELD(bm_hi,3,3) == 0x0) )
393 {
394 /* Not i2c boot or i2c boot with address 0x50 */
396 /* Update the DEVSTAT to v1 */
397 dev_stat = DEVICE_REG32_R(DEVICE_REG_DEVSTAT );
398 dev_stat &= ~(0x0000080E);
399 dev_stat |= ((bm_hi << 8) | bm_lo);
401 /* Update the DEVSTAT register for the intended Boot Device and i2c Addr */
402 DEVICE_REG32_W (DEVICE_REG_DEVSTAT, dev_stat);
404 #ifdef IBL_ENABLE_PCIE_WORKAROUND
405 #define BOOT_DEVICE_MASK 0xE
406 #define DEVSTAT_BOOTDEVICE_SHIFT 1
407 #define PCI_BOOT_MODE 0x4
409 if (((dev_stat & BOOT_DEVICE_MASK)>>DEVSTAT_BOOTDEVICE_SHIFT) == PCI_BOOT_MODE) {
410 /* Write ICS 557 Clock Selection Control Register in the FPGA */
411 /* 1 : FPGA_ICS557_SEL s driven high */
412 DEVICE_REG32_W(DEVICE_SPI_BASE(0) + SPI_REG_SPIDAT0,
413 FPGA_WRITE_REG_CMD(FPGA_ICS557_SEL_CTRL_REG,1));
414 chipDelay32(10000);
415 /* Reset SPI */
416 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
418 iblPCIeWorkaround();
419 /* Will never reach here */
420 }
421 #endif
422 /* Reset SPI */
423 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
425 exit = (void (*)())BOOT_ROM_ENTER_ADDRESS;
426 (*exit)();
427 }
428 else
429 {
430 /* Update the DEVSTAT register for the actual boot configuration */
431 DEVICE_REG32_W (DEVICE_REG_DEVSTAT, ((bm_hi << 8) | bm_lo));
432 }
434 /* Reset SPI */
435 DEVICE_REG32_W (DEVICE_SPI_BASE(0) + SPI_REG_SPIGCR0, SPI_REG_VAL_SPIGCR0_RESET);
436 }
438 #if (!defined(EXCLUDE_NOR_SPI) || !defined(EXCLUDE_NAND_SPI))
439 /**
440 * @brief
441 * Return the default hardware configuration for SPI. If this information
442 * is available in the boot ROM it is used, otherwise defaults are used.
443 */
444 void deviceLoadInitSpiConfig (void *vcfg)
445 {
446 uint32 v;
448 spiConfig_t *cfg = (spiConfig_t *)vcfg;
450 BOOT_PARAMS_COMMON_T *params;
451 BOOT_PARAMS_SPI_T *spip;
453 v = *((Uint32 *)DEVICE_JTAG_ID_REG);
454 v &= DEVICE_JTAG_ID_MASK;
456 if (v == DEVICE_C6678_JTAG_ID_VAL)
457 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6678;
458 else
459 params = (BOOT_PARAMS_COMMON_T *)ROM_BOOT_PARAMS_ADDR_C6670;
462 /* SPI_ROM is a constant defined during make which enables the use of the
463 * parameters from the ROM boot loader */
464 if ((SPI_ROM == 1) && (params->boot_mode == BOOT_MODE_SPI)) {
466 spip = (BOOT_PARAMS_SPI_T *)params;
468 cfg->port = 0;
469 cfg->mode = spip->mode;
470 cfg->addrWidth = spip->addrWidth;
471 cfg->npin = spip->nPins;
472 cfg->csel = spip->csel;
473 cfg->c2tdelay = spip->c2tdelay;
475 v = (UINT32)spip->cpuFreqMhz * 1000; /* CPU frequency in kHz */
476 v = v / (DEVICE_SPI_MOD_DIVIDER * (((UINT32)(spip->busFreqMhz) * 1000) + spip->busFreqKhz));
478 if (v > DEVICE_SPI_MAX_DIVIDER)
479 v = DEVICE_SPI_MAX_DIVIDER;
481 cfg->clkdiv = v;
483 } else {
485 cfg->port = 0;
486 cfg->mode = SPI_MODE;
487 cfg->addrWidth = SPI_ADDR_WIDTH;
488 cfg->npin = SPI_NPIN;
489 cfg->csel = SPI_CSEL;
490 cfg->c2tdelay = SPI_C2TDEL;
491 cfg->clkdiv = SPI_CLKDIV;
493 }
495 }
496 #endif