26f49fda64fb6f3f431dbc473a936100609c4811
[keystone-rtos/ibl.git] / src / util / i2cConfig / i2cparam.c
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 */
107     
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;
132 /**
133  *  @brief
134  *     Display the error returned by the i2c driver 
135  */
136 void showI2cError (I2C_RET iret, char *stage)
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);
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)
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);
205 void main (void)
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), &currentOffset, 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);
257             
258     
260     printf ("I2c table write complete\n");
266