Merge pull request #3 in PROCESSOR-SDK/ibl from PRSDK-5675 to master
[keystone-rtos/ibl.git] / src / hw / i2c / i2c.c
1 /*
2  *
3  * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/ 
4  * 
5  * 
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions 
8  *  are met:
9  *
10  *    Redistributions of source code must retain the above copyright 
11  *    notice, this list of conditions and the following disclaimer.
12  *
13  *    Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the 
15  *    documentation and/or other materials provided with the   
16  *    distribution.
17  *
18  *    Neither the name of Texas Instruments Incorporated nor the names of
19  *    its contributors may be used to endorse or promote products derived
20  *    from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
26  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
27  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34 */
38 /****************************************************************************
39  * FILE PURPOSE: An i2c driver for the rom boot loader
40  ****************************************************************************
41  * FILE NAME: i2c.c
42  *
43  * DESCRIPTION: Provides an i2c driver for the rom boot loader. The driver
44  *              is adapted from the csl polling driver in the 64x csl.
45  *
46  ****************************************************************************/ 
47 #include "types.h"
48 #include "i2c.h"
49 #include "i2cloc.h"
50 #include "target.h"
52 #define DEVICE_REG32_W(x,y)   *(volatile unsigned int *)(x)=(y)
53 #define DEVICE_REG32_R(x)    (*(volatile unsigned int *)(x))
55  /**************************************************************************
56   * Global variables
57   *************************************************************************/
58  UINT32 i2cCoreFreqMhz;
59  UINT32 i2cBitPeriodCycles; 
62 /***********************************************************************************
63  * FUNCTION PURPOSE: Provide an approximate delay
64  ***********************************************************************************
65  * DESCRIPTION: A delay in units of CPU cycles is executed
66  ***********************************************************************************/
67 static void chipDelay32 (uint32 del)
68 {
69     volatile unsigned int i;
71     for (i = 0; i < del/8; i++){
72         asm(" NOP ");
73     }
74 }
77 /***************************************************************************
78  * FUNCTION PURPOSE: Generate a delay
79  ***************************************************************************
80  * DESCRIPTION: Creates a delay specified in usec
81  ***************************************************************************/
82 void hw_i2c_delay_usec (UINT32 usec)
83 {
84   UINT32 delayCycles;
86   delayCycles = usec * i2cCoreFreqMhz;
88   chipDelay32 (delayCycles);
90 } /* hw_i2c_delay_usec */
91  
92  
93  /***************************************************************************
94   * FUNCTION PURPOSE: Initialize the I2C.
95   ***************************************************************************
96   * DESCRIPTION: Puts the I2C into reset, sets up the device and takes
97   *              the device out of reset in slave receiver mode.
98   **************************************************************************/
99 void hwI2Cinit (UINT16 coreFreqMhz, UINT16 moduleDivisor, UINT16 clkFreqKhz, UINT16 ownAddr)
100  {
101    UINT32 psc;
102    UINT32 clkx;
103    UINT32 tmp;
104    UINT32 moduleFreqMhzQ1;
105    UINT32 trueModFreqHz;
106    UINT32 trueModFreqkHz;
107  
108    /* Put the i2c peripheral into reset */
109    DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_RESET);
110    
111    /* To determine the module prescaler Q31.1 format will be used. This is just
112     * handled simply since the input module frequency is an integer it will just
113     * be multiplied by two. Dividing two Q31.1 result in a Q30.0, or the divider *
114     * Calculate module prescalars to get as close to target frequencies as possible */
115    moduleFreqMhzQ1 = (coreFreqMhz << 1) / moduleDivisor;
116    psc = moduleFreqMhzQ1 / I2C_TARGET_MODULE_FREQ_MHZ_Q1;
117    if (psc > 0)
118      psc = psc - 1;
119    trueModFreqHz = ((UINT32)coreFreqMhz * (UINT32)1000000) / (moduleDivisor * (psc+1));
120    
121    tmp = trueModFreqHz / (clkFreqKhz * 1000);
122    if (tmp > 12) 
123      clkx = (tmp - 12) >> 1;
124    else
125      clkx = 0;
126      
127    /* Store the core frequency for use in generating delay */
128    i2cCoreFreqMhz = coreFreqMhz;
129    
130    /* Calculate the number of micro seconds for each bit. */
131    trueModFreqkHz = trueModFreqHz / 1000;  /* Prevent 32 bit integer overlflow */
132    i2cBitPeriodCycles = (UINT32)coreFreqMhz * 1000 * (2 * clkx + 12) / trueModFreqkHz;
133    
134    /* Initialize the registers */
135    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_PSC, (UINT32)psc); 
136    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_OAR, (UINT32)ownAddr);
137    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_IER, (UINT32)0);
138    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_RESET);
139    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CLKL, clkx);
140    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CLKH, clkx); 
141    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_CNT, (UINT32)0);
142    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_SAR, (UINT32)0x3ff);
143    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_DXR, (UINT32)0);
144    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_PFUNC, (UINT32)0);
145    
146    /* Take the I2C out of reset in the slave receiver mode */
147    DEVICE_REG32_W(DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
148    
149    /* Read the receive register to clear it */
150    tmp = DEVICE_REG32_R(DEVICE_I2C_BASE + I2C_REG_DRR);
153 } /* hwI2Cinit */
156 /****************************************************************************
157  * FUNCTION PURPOSE: Perform a master write 
158  ****************************************************************************
159  * DESCRIPTION: Enters master transmitter mode, writes a specified number
160  *              of bytes. The byte stream arrives packed in the 16 bit
161  *              data stream, and are sent most significant byte first.
162  ****************************************************************************/
163 I2C_RET hwI2cMasterWrite (UINT32 eeprom_i2c_id, UINT8 *eData, UINT32 nbytes, UINT32 endBusState, BOOL busIsMine)
165   UINT32 timeoutCount;
166   UINT32 polling;
167   UINT32 value;
168   UINT32 str;
169   UINT16 i;
171   /* If the byte length is 0 there is nothing to do */
172   if (nbytes == 0)
173     return (I2C_RET_OK);
174    
175   /* Check for the bus busy signal */
176   if (busIsMine == FALSE)  {
177     timeoutCount = 0;
178     do  { 
179       polling = I2C_REG_STR_FIELD_BB(DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR));
180     
181       if (polling != 0)  {
182         hw_i2c_delay_usec (I2C_MASTER_TRANSMITTER_BUS_ACCESS_DELAY_US);
183       
184         timeoutCount += 1;
185         if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_BUS_ACCESS_TIMEOUT)  {
186       
187           /* Return to slave receiver, clear nack and bus busy */
188           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
189           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
190           return (I2C_RET_IDLE_TIMEOUT);
191         }
192       } else  { /* The bus is free */
193         timeoutCount = 0;
194       }
195     }
196     while (timeoutCount != 0);
198   }
199       
200   /* Enter master transmitter mode, set the slave address register */
201   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMT);
202   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_SAR, (UINT32)eeprom_i2c_id);
203   
204   /* Put the first byte into the transmit register, set the start bit */
205   value = *eData & 0x00ff;
206   eData = eData + 1;
207   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_DXR, value);
208   
210   /* Some delay required */
211   chipDelay32 (i2cBitPeriodCycles);
213   /* Set the start bit */
214   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMTSTRT);
215   
216   for (i = 1; i < nbytes; i++)  {
217     timeoutCount = 0;
218   
219     do  {
220       /* Read status */
221       str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
222     
223       /* On Nack return failure */
224       if (I2C_REG_STR_FIELD_NACK(str) != 0)  {
225       
226         /* Return to slave receiver, clear nack and bus busy */
227         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
228         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
229         return (I2C_RET_NO_ACK);
230       }
231         
232       /* Check for transmit ready */
233       if (I2C_REG_STR_FIELD_XRDY(str) != 0)  {
234         timeoutCount = 0;
235         
236         value = *eData & 0x00ff;
237         eData =  eData + 1;
238         
239         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_DXR, value);
241         
242       }  else  {   /* XRDY bit not set */
243         chipDelay32 (i2cBitPeriodCycles);
244         timeoutCount += 1;
245         if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_TIMEOUT)  {
246           /* Return to slave receiver, clear nack and bus busy */
247           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
248           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
249           return (I2C_RET_IDLE_TIMEOUT);
250         }
251       }
252           
253     } while (timeoutCount != 0);
255   } /* end for loop */
257   
258   /* If releasing the bus, send a stop bit */
259   if (endBusState == I2C_RELEASE_BUS)  {
260   
261     /* Wait for the ardy bit to go high */
262     timeoutCount = 0;
263     do  {
264       str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
265       if (I2C_REG_STR_FIELD_ARDY(str) != 0)  {
266         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTXMTSTOP);
267         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_CLR_BUSY);
268         hw_i2c_delay_usec (10000);
269         timeoutCount = 0;
270         
271       } else  { /* Registers not ready for access */
272         timeoutCount += 1;
273         
274         if (timeoutCount >= I2C_MAX_MASTER_TRANSMITTER_ARDY_TIMEOUT)  {
275            /* On timeout put the peripheral into reset, wait, then
276             * take it out of reset */
277            DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_RESET);
278            hw_i2c_delay_usec (10000);
279            DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
280            return (I2C_RET_IDLE_TIMEOUT);
281          }
282         chipDelay32 (i2cBitPeriodCycles); 
283       }
284     } while (timeoutCount != 0);
285     
286   } /* end bus release */
287   
288   return (I2C_RET_OK);
289   
290 } /* hwI2cMasterWrite */
291    
292   
294 /**************************************************************************
295  * FUNCTION PURPOSE: Perform a master read from an I2C prom
296  **************************************************************************
297  * DESCRIPTION: Reads a fixed number of bytes from an I2C prom. The read
298  *              consists of a master write of 2 bytes (forming a 16 bit address,
299  *              msb transmitted first), followed by a master read of the
300  *              input number of bytes. The bytes that are read are placed
301  *              in p_packed_bytes in big endian format.
302  **************************************************************************/
303 I2C_RET hwI2cMasterRead (
304   UINT32           byte_addr,
305   UINT32           byte_len,
306   UINT8           *p_packed_bytes,
307   UINT32           eeprom_i2c_id,
308   UINT32           address_delay)
311   UINT32  str;  
312   UINT32  timeoutCount;
313   UINT32  i;
314   UINT8   eAddr[2];
315   I2C_RET ret;
317   /* If the byte length is 0, there is nothing to do */
318   if (byte_len == 0)
319     return (I2C_RET_OK);
320     
321   /* Write the byte address to the eeprom. Do not send a stop */
322   eAddr[0] = (byte_addr >> 8) & 0xff;
323   eAddr[1] = byte_addr & 0xff;
325   ret = hwI2cMasterWrite (eeprom_i2c_id, eAddr, 2, I2C_DO_NOT_RELEASE_BUS, FALSE);
326   if (ret != I2C_RET_OK)
327     return (ret);
328     
329   /* Give the I2C prom some time to process the read command */
330   chipDelay32 (((UINT32)address_delay)<<8);
332   /* Set the start bit, begin the master read */
333   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTRCV);
335   /* Read the requested number of bytes */
336   for (i = 0; i < byte_len; i++)  {
337     timeoutCount = 0;
338   
339     do  {
340       /* Read status */
341       str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
342     
343       /* On Nack return failure */
344       if (I2C_REG_STR_FIELD_NACK(str) != 0)  {
345       
346         /* Return to slave receiver, clear nack and bus busy */
347         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
348         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
349         return (I2C_RET_NO_ACK);
350       }
351         
352       /* Check for receive byte ready */
353       if (I2C_REG_STR_FIELD_RRDY(str) != 0)  {
354         *p_packed_bytes = (UINT16) (DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_DRR) & 0x00ff);
355         timeoutCount = 0;
356         p_packed_bytes = p_packed_bytes + 1;
357         
358         
359       }  else  {   /* RRDY bit not set */
360         chipDelay32 (i2cBitPeriodCycles);
361         timeoutCount += 1;
362         if (timeoutCount >= I2C_MAX_MASTER_RECEIVE_TIMEOUT)  {
363           /* Return to slave receiver, clear nack and bus busy */
364           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
365           DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
366           return (I2C_RET_IDLE_TIMEOUT);
367         }
368       }
369           
370     } while (timeoutCount != 0);
372   } /* end for loop */
374   /* The data block has been read. Send the stop bit */
375   DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_MSTRCVSTOP);
376         
378   /* Wait for the rrdy and read the dummy byte */
379   timeoutCount = 0;
380   do  {
382     str = DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_STR);
384     /* Check for receive byte ready */
385     if (I2C_REG_STR_FIELD_RRDY(str) != 0)  {
386       eAddr[0] = (UINT16) (DEVICE_REG32_R (DEVICE_I2C_BASE + I2C_REG_DRR) & 0x00ff);
387       timeoutCount = 0;
389     }  else  {  /* rrdy not set */
391       chipDelay32 (i2cBitPeriodCycles);
392       timeoutCount += 1;
393       if (timeoutCount >= I2C_MAX_MASTER_RECEIVE_TIMEOUT)  {
394         /* Return to slave receiver, clear nack and bus busy */
395         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_MDR, I2C_VAL_REG_MDR_SLVRCV);
396         DEVICE_REG32_W (DEVICE_I2C_BASE + I2C_REG_STR, I2C_VAL_REG_STR_ON_FAIL);
397         return (I2C_RET_IDLE_TIMEOUT);
398       }
399     }
401   } while (timeoutCount != 0);
402   
403   return (I2C_RET_OK);
404   
405 } /* hwI2cMasterRead */
406