1 /*************************************************************************************
2 * FILE PURPOSE: Write the ibl configuration table to the i2c eeprom
3 *************************************************************************************
4 * @file i2cparam.c
5 *
6 * @brief
7 * Creates the ibl configuration table and writes to the i2c
8 *
9 *************************************************************************************/
11 #include "types.h"
12 #include "ibl.h"
13 #include "i2c.h"
14 #include "pllapi.h"
15 #include "iblcfg.h"
16 #include "target.h"
17 #include "string.h"
18 #include <stdlib.h>
19 #include <stdio.h>
21 ibl_t ibl;
23 #define SETIP(array,i0,i1,i2,i3) array[0]=(i0); \
24 array[1]=(i1); \
25 array[2]=(i2); \
26 array[3]=(i3)
28 /**
29 * @brief The desired ibl configuration is setup here. Edit the fields
30 * to match the desired setup.
31 */
32 void setupTable (void)
33 {
35 /* Initialize the table */
36 memset (&ibl, 0, sizeof (ibl_t));
38 ibl.iblMagic = ibl_MAGIC_VALUE;
40 ibl.pllConfig[ibl_MAIN_PLL].doEnable = TRUE;
41 ibl.pllConfig[ibl_MAIN_PLL].prediv = 1;
42 ibl.pllConfig[ibl_MAIN_PLL].mult = 25;
43 ibl.pllConfig[ibl_MAIN_PLL].postdiv = 1;
44 ibl.pllConfig[ibl_MAIN_PLL].pllOutFreqMhz = 625;
46 /* The DDR PLL. The multipliers/dividers are fixed, so are really dont cares */
47 ibl.pllConfig[ibl_DDR_PLL].doEnable = TRUE;
49 /* The network PLL. The multipliers/dividers are fixed */
50 ibl.pllConfig[ibl_NET_PLL].doEnable = TRUE;
52 /* EMIF configuration. The values are for DDR at 533 MHz */
53 ibl.ddrConfig.configDdr = TRUE;
55 ibl.ddrConfig.uEmif.emif3p1.sdcfg = 0x00538832; /* timing, 32bit wide */
56 ibl.ddrConfig.uEmif.emif3p1.sdrfc = 0x0000073B; /* Refresh 533Mhz */
57 ibl.ddrConfig.uEmif.emif3p1.sdtim1 = 0x47245BD2; /* Timing 1 */
58 ibl.ddrConfig.uEmif.emif3p1.sdtim2 = 0x0125DC44; /* Timing 2 */
59 ibl.ddrConfig.uEmif.emif3p1.dmcctl = 0x50001906; /* PHY read latency for CAS 5 is 5 + 2 - 1 */
61 /* Ethernet configuration for port 0 */
62 ibl.ethConfig[0].ethPriority = ibl_HIGHEST_PRIORITY;
63 ibl.ethConfig[0].port = 0;
65 /* Bootp is disabled. The server and file name are provided here */
66 ibl.ethConfig[0].doBootp = FALSE;
67 ibl.ethConfig[0].useBootpServerIp = FALSE;
68 ibl.ethConfig[0].useBootpFileName = FALSE;
69 ibl.ethConfig[0].bootFormat = ibl_BOOT_FORMAT_BBLOB;
71 SETIP(ibl.ethConfig[0].ethInfo.ipAddr, 10,218,109,21);
72 SETIP(ibl.ethConfig[0].ethInfo.serverIp, 10,218,109,196);
73 SETIP(ibl.ethConfig[0].ethInfo.gatewayIp, 10,218,109,1);
74 SETIP(ibl.ethConfig[0].ethInfo.netmask, 255,255,255,0);
76 /* Leave the hardware address as 0 so the e-fuse value will be used */
78 strcpy (ibl.ethConfig[0].ethInfo.fileName, "test.blob");
80 /* Even though the entire range of DDR2 is chosen, the load will
81 * stop when the ftp reaches the end of the file */
82 ibl.ethConfig[0].blob.startAddress = 0xe0000000; /* Base address of DDR2 */
83 ibl.ethConfig[0].blob.sizeBytes = 0x20000000; /* All of DDR2 */
84 ibl.ethConfig[0].blob.branchAddress = 0xe0000000; /* Base of DDR2 */
86 /* For port 1 use bootp */
87 /* Ethernet configuration for port 0 */
88 ibl.ethConfig[1].ethPriority = ibl_HIGHEST_PRIORITY + 1;
89 ibl.ethConfig[1].port = 1;
91 /* Bootp is disabled. The server and file name are provided here */
92 ibl.ethConfig[1].doBootp = TRUE;
93 ibl.ethConfig[1].useBootpServerIp = TRUE;
94 ibl.ethConfig[1].useBootpFileName = TRUE;
95 ibl.ethConfig[1].bootFormat = ibl_BOOT_FORMAT_BBLOB;
98 /* Leave the hardware address as 0 so the e-fuse value will be used */
99 /* Leave all remaining fields as 0 since bootp will fill them in */
102 /* Even though the entire range of DDR2 is chosen, the load will
103 * stop when the ftp reaches the end of the file */
104 ibl.ethConfig[1].blob.startAddress = 0xe0000000; /* Base address of DDR2 */
105 ibl.ethConfig[1].blob.sizeBytes = 0x20000000; /* All of DDR2 */
106 ibl.ethConfig[1].blob.branchAddress = 0xe0000000; /* Base of DDR2 */
110 /* MDIO configuration */
111 ibl.mdioConfig.nMdioOps = 8;
112 ibl.mdioConfig.mdioClkDiv = 0x20;
113 ibl.mdioConfig.interDelay = 1400; /* ~2ms at 700 MHz */
115 ibl.mdioConfig.mdio[0] = (1 << 30) | (27 << 21) | (24 << 16) | 0x848b;
116 ibl.mdioConfig.mdio[1] = (1 << 30) | (20 << 21) | (24 << 16) | 0x0ce0;
117 ibl.mdioConfig.mdio[2] = (1 << 30) | (24 << 21) | (24 << 16) | 0x4101;
118 ibl.mdioConfig.mdio[3] = (1 << 30) | ( 0 << 21) | (24 << 16) | 0x9140;
120 ibl.mdioConfig.mdio[4] = (1 << 30) | (27 << 21) | (25 << 16) | 0x848b;
121 ibl.mdioConfig.mdio[5] = (1 << 30) | (20 << 21) | (25 << 16) | 0x0ce0;
122 ibl.mdioConfig.mdio[6] = (1 << 30) | (24 << 21) | (25 << 16) | 0x4101;
123 ibl.mdioConfig.mdio[7] = (1 << 30) | ( 0 << 21) | (25 << 16) | 0x9140;
126 /* Nand boot is disabled */
127 ibl.nandConfig.nandPriority = ibl_DEVICE_NOBOOT;
129 }
132 /**
133 * @brief
134 * Display the error returned by the i2c driver
135 */
136 void showI2cError (I2C_RET iret, char *stage)
137 {
138 char *ecode;
140 switch (iret) {
141 case I2C_RET_LOST_ARB: ecode = "I2C master lost an arbitration battle";
142 break;
144 case I2C_RET_NO_ACK: ecode = "I2C master detected no ack from slave";
145 break;
147 case I2C_RET_IDLE_TIMEOUT: ecode = "I2C timed out";
148 break;
150 case I2C_RET_BAD_REQUEST: ecode = "I2C driver detected a bad data request";
151 break;
153 case I2C_RET_CLOCK_STUCK_LOW: ecode = "I2C driver found the bus stuck low";
154 break;
156 case I2C_RET_GEN_ERROR: ecode = "I2C driver reported a general error";
157 break;
159 }
161 printf ("Error: %s, reported at stage: %s\n", ecode, stage);
163 }
165 /**
166 * @brief
167 * Group the data into a 64 byte (max) data block aligned on a 64 byte boundary
168 */
169 Int32 formBlock (UINT8 *base, Int32 dataSize, Int32 *offset, Uint8 *data, Uint32 baseI2cDataAddr)
170 {
171 Uint32 currentAddress;
172 Int32 nbytes;
173 Int32 i;
175 /* The I2C eeprom address is the parameter base address plus the current offset
176 * The number of bytes is blocked to end on a 64 byte boundary */
177 currentAddress = baseI2cDataAddr + *offset;
178 nbytes = 64 - (currentAddress & (64 - 1));
180 /* Only write the bytes in the input array */
181 if (*offset + nbytes > dataSize)
182 nbytes = dataSize - *offset;
184 if (nbytes == 0)
185 return (0);
187 /* The address is placed first */
188 data[0] = (currentAddress >> 8) & 0xff;
189 data[1] = (currentAddress >> 0) & 0xff;
191 /* The data */
192 for (i = 0; i < nbytes; i++)
193 data[i+2] = base[*offset + i];
195 /* Update the offset */
196 *offset += nbytes;
198 /* Return the total number of bytes (including address) to go on the bus */
199 return (nbytes + 2);
201 }
205 void main (void)
206 {
207 I2C_RET iret;
208 UINT8 writeBlock[66];
209 char iline[132];
210 Int32 n;
211 Int32 currentOffset;
213 volatile Int32 i;
216 /* Program the main system PLL */
217 hwPllSetPll (MAIN_PLL,
218 1, /* Pre-divider */
219 IBL_I2C_DEV_FREQ_MHZ / 25, /* Multiplier */
220 1); /* Post-divider */
222 setupTable();
224 hwI2Cinit (IBL_I2C_DEV_FREQ_MHZ, /* The CPU frequency during I2C data load */
225 DEVICE_I2C_MODULE_DIVISOR, /* The divide down of CPU that drives the i2c */
226 IBL_I2C_CLK_FREQ_KHZ/8, /* The I2C data rate used during table load. Slowed for writes */
227 IBL_I2C_OWN_ADDR); /* The address used by this device on the i2c bus */
230 /* Block the data into 64 byte blocks aligned on 64 byte boundaries for the data write.
231 * The block address is prepended to the data block before writing */
232 currentOffset = 0;
233 do {
235 n = formBlock ((UINT8 *)&ibl, sizeof(ibl_t), ¤tOffset, writeBlock, IBL_I2C_CFG_TABLE_DATA_ADDR);
237 if (n > 0) {
239 iret = hwI2cMasterWrite (IBL_I2C_CFG_EEPROM_BUS_ADDR, /* The I2C bus address of the eeprom */
240 writeBlock, /* The data to write */
241 n, /* The number of bytes to write */
242 I2C_RELEASE_BUS, /* Release the bus when the write is done */
243 FALSE ); /* Bus is not owned at start of operation */
245 if (iret != I2C_RET_OK) {
246 sprintf (iline, "Block at offset %d\n", currentOffset);
247 showI2cError (iret, iline);
248 return;
249 }
251 /* Need some delay to allow the programming to occur */
252 for (i = 0; i < 600000; i++);
254 }
256 } while (n > 0);
260 printf ("I2c table write complete\n");
262 }