Root/target/linux/generic/files/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiEeprom.S

1/*******************************************************************************
2Copyright (C) Marvell International Ltd. and its affiliates
3
4This software file (the "File") is owned and distributed by Marvell
5International Ltd. and/or its affiliates ("Marvell") under the following
6alternative licensing terms. Once you have made an election to distribute the
7File under one of the following license alternatives, please (i) delete this
8introductory statement regarding license alternatives, (ii) delete the two
9license alternatives that you have not elected to use and (iii) preserve the
10Marvell copyright notice above.
11
12********************************************************************************
13Marvell Commercial License Option
14
15If you received this File from Marvell and you have entered into a commercial
16license agreement (a "Commercial License") with Marvell, the File is licensed
17to you under the terms of the applicable Commercial License.
18
19********************************************************************************
20Marvell GPL License Option
21
22If you received this File from Marvell, you may opt to use, redistribute and/or
23modify this File in accordance with the terms and conditions of the General
24Public License Version 2, June 1991 (the "GPL License"), a copy of which is
25available along with the File in the license.txt file or by writing to the Free
26Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
27on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
28
29THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
30WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
31DISCLAIMED. The GPL License provides additional details about this warranty
32disclaimer.
33********************************************************************************
34Marvell BSD License Option
35
36If you received this File from Marvell, you may opt to use, redistribute and/or
37modify this File under the following licensing terms.
38Redistribution and use in source and binary forms, with or without modification,
39are permitted provided that the following conditions are met:
40
41    * Redistributions of source code must retain the above copyright notice,
42        this list of conditions and the following disclaimer.
43
44    * Redistributions in binary form must reproduce the above copyright
45        notice, this list of conditions and the following disclaimer in the
46        documentation and/or other materials provided with the distribution.
47
48    * Neither the name of Marvell nor the names of its contributors may be
49        used to endorse or promote products derived from this software without
50        specific prior written permission.
51    
52THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
53ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
54WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
55DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
56ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
59ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
60(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
61SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
62
63*******************************************************************************/
64
65
66/* includes */
67#define MV_ASMLANGUAGE
68#include "ctrlEnv/mvCtrlEnvSpec.h"
69#include "boardEnv/mvBoardEnvSpec.h"
70#include "mvOsAsm.h"
71#include "mvTwsiSpec.h"
72#include "mvSysHwConfig.h"
73#include "ctrlEnv/sys/mvCpuIfRegs.h"
74#include "mvCommon.h"
75
76#define I2C_CH MV_BOARD_DIMM_I2C_CHANNEL
77
78/* defines */
79/* defines */
80
81
82        .data
83        .global _i2cInit
84        .global _i2cRead
85
86        .text
87
88/*******************************************************************************
89* _i2cInit - Initialize TWSI interface
90*
91* DESCRIPTION:
92* The function performs TWSI interface initialization. It resets the
93* TWSI state machine and initialize its clock to 100KHz assuming Tclock
94* of 133MHz.
95*
96* INPUT:
97* None.
98*
99* OUTPUT:
100* None.
101*
102* RETURN:
103* None.
104*
105*******************************************************************************/
106_i2cInit:
107        mov r9, LR /* Save link register */
108        mov r0, #0 /* Make sure r0 is zero */
109           
110        /* Reset the i2c Mechanism first */
111        MV_REG_WRITE_ASM (r0, r1, TWSI_SOFT_RESET_REG(I2C_CH))
112
113        bl _twsiDelay
114        bl _twsiDelay
115
116        /* Initializing the I2C mechanism. Assuming Tclock frequency */
117        /* of 166MHz. The I2C frequency in that case will be 100KHz. */
118        /* For this settings, M = 9 and N = 3. Set the baud-rate with the */
119        /* value of 0x2b (freq of ==> 100KHz */
120        /* see spec for more details about the calculation of this value) */
121        mov r6, #(9 << 3 | 3)
122        MV_REG_WRITE_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
123        
124        /* Enable the I2C master */
125    /* Enable TWSI interrupt in main mask reg */
126        mov r6, #0xC4
127        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
128        
129        /* Let the slow TWSI machine get used to the idea that it is enabled */
130        bl _twsiDelay
131        
132        
133        mov PC, r9 /* r9 is saved link register */
134
135/*******************************************************************************
136* _twsiDelay - Perform delay.
137*
138* DESCRIPTION:
139* The function performs a delay to enable TWSI logic to stable.
140*
141* INPUT:
142* None.
143*
144* OUTPUT:
145* None.
146*
147* RETURN:
148* None.
149*
150*******************************************************************************/
151_twsiDelay:
152        mov r10, #0x100000 /*was 0x400*/
153    
154_twsiDelayLoop:
155        subs r10, r10, #1
156        bne _twsiDelayLoop
157        
158        mov PC, LR
159
160/*******************************************************************************
161* _i2cRead - Read byte from I2C EEPROM device.
162*
163* DESCRIPTION:
164* The function returns a byte from I2C EEPROM device.
165* The EEPROM device is 7-bit address type.
166*
167* INPUT:
168* r4 has the DIMM0 base address with shift 1 bit to the left
169* r7 has the EEPROM offset
170*
171* OUTPUT:
172* None.
173*
174* RETURN:
175* r4 returns '0' if address can not be read.
176* r7 has byte value in case read is successful.
177*
178*******************************************************************************/
179_i2cRead:
180        mov r9, LR /* Save link register */
181       
182        /* Transmit the device address and desired offset within the EEPROM. */
183        
184        /* Generate Start Bit */
185        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
186        orr r6, r6, #TWSI_CONTROL_START_BIT
187        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
188
189        /* Wait for the interrupt flag (bit3) to be set */
190        mov r10, #0x50000
191loop_1:
192        subs r10, r10, #1
193        beq loop_1_timeout
194#ifdef MV78XX0
195        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
196        tst r6, #BIT2
197#else
198        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
199        tst r6, #BIT5
200#endif
201        beq loop_1
202            
203loop_1_timeout:
204            
205        /* Wait for the start bit to be reset by HW */
206        mov r10, #0x50000
207loop_2:
208        subs r10, r10, #1
209        beq loop_2_timeout
210        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
211        tst r6, #TWSI_CONTROL_START_BIT
212        bne loop_2
213           
214loop_2_timeout:
215
216        /* Wait for the status TWSI_START_CONDITION_TRA = 0x8 */
217        mov r10, #0x50000
218loop_3:
219        subs r10, r10, #1
220        beq loop_3_timeout
221        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
222        cmp r6, #0x08
223        bne loop_3
224        
225loop_3_timeout:
226        
227        /* writing the address of (DIMM0/1 << 1) with write indication */
228        mov r6, r4, LSL #1 /* Write operation address bit 0 must be 0 */
229        MV_REG_WRITE_ASM (r6, r1, TWSI_DATA_REG(I2C_CH))
230        
231        bl _twsiDelay
232        /* Clear the interrupt flag */
233        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
234        bic r6, r6, #TWSI_CONTROL_INT_FLAG_SET
235        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
236        bl _twsiDelay
237        
238        /* Waiting for the interrupt flag to be set which means that the
239           address has been transmitted */
240loop_4:
241#ifdef MV78XX0
242        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
243        tst r6, #BIT2
244#else
245        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
246        tst r6, #BIT5
247#endif
248        beq loop_4 /* if tst = 0, then the bit is not set yet */
249        
250        /* Wait for status TWSI_ADDR_PLUS_WRITE_BIT_TRA_ACK_REC = 0x18 */
251        mov r10, #0x50000 /* Set r10 to 0x50000 =~ 328,000 */
252
253loop_5:
254        subs r10, r10, #1 /* timeout count down */
255        bne testStatus
256        mov r4, #0 /* r4 = 0 -> operation failed */
257        b exit_i2cRead /* Exit if timeout (No DIMM) */
258
259testStatus:
260        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
261        cmp r6, #0x18
262        bne loop_5
263                
264
265        /* check if the offset is bigger than 256 byte*/
266        tst r7, #0x80000000
267        bne great_than_256
268                        
269        /* Write the offset to be read from the DIMM EEPROM */
270        MV_REG_WRITE_ASM (r7, r1, TWSI_DATA_REG(I2C_CH))
271        
272        b after_offset
273        
274great_than_256:
275        mov r10, r7, LSR #8
276        and r10, r10, #0xff
277        /* Write the offset0 to be read from the EEPROM */
278        MV_REG_WRITE_ASM (r10, r1, TWSI_DATA_REG(I2C_CH))
279        
280        /* Clear the interrupt flag ==> signaling that the address can now
281           be transmited */
282        
283        bl _twsiDelay
284        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
285        bic r6, r6, #TWSI_CONTROL_INT_FLAG_SET
286        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
287        bl _twsiDelay
288    
289        /* Wait for the interrupt to be set again ==> address has transmited */
290loop_6_1:
291#ifdef MV78XX0
292        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
293        tst r6, #BIT2
294#else
295        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
296        tst r6, #BIT5
297#endif
298        beq loop_6_1
299        
300        /* Wait for status TWSI_MAS_TRAN_DATA_BYTE_ACK_REC = 0x28 */
301loop_7_1:
302        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
303        cmp r6, #0x28
304        bne loop_7_1
305        
306        
307        mov r10, r7
308        and r10, r10, #0xff
309        /* Write the offset1 to be read from the EEPROM */
310        MV_REG_WRITE_ASM (r10, r1, TWSI_DATA_REG(I2C_CH))
311        
312        
313        
314after_offset:
315        
316        /* Clear the interrupt flag ==> signaling that the address can now
317           be transmited */
318        
319        bl _twsiDelay
320        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
321        bic r6, r6, #TWSI_CONTROL_INT_FLAG_SET
322        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
323        bl _twsiDelay
324    
325        /* Wait for the interrupt to be set again ==> address has transmited */
326loop_6:
327#ifdef MV78XX0
328        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
329        tst r6, #BIT2
330#else
331        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
332        tst r6, #BIT5
333#endif
334        beq loop_6
335        
336        /* Wait for status TWSI_MAS_TRAN_DATA_BYTE_ACK_REC = 0x28 */
337loop_7:
338        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
339        cmp r6, #0x28
340        bne loop_7
341        
342        /* Retransmit the device address with read indication to get the data */
343        
344        /* generate a repeated start bit */
345        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
346        orr r6, r6, #TWSI_CONTROL_START_BIT
347        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
348
349        
350        /* Clear the interrupt flag ==> the start bit will be transmitted. */
351        bl _twsiDelay
352        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
353        bic r6, r6, #TWSI_CONTROL_INT_FLAG_SET
354        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
355        bl _twsiDelay
356        
357       /* Wait for the interrupt flag (bit3) to be set */
358loop_9:
359#ifdef MV78XX0
360        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
361        tst r6, #BIT2
362#else
363        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
364        tst r6, #BIT5
365#endif
366        beq loop_9
367
368        /* Wait for the start bit to be reset by HW */
369loop_8:
370        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
371        tst r6, #TWSI_CONTROL_START_BIT
372        bne loop_8
373        
374        /* Wait for status TWSI_REPEATED_START_CONDITION_TRA = 0x10 */
375loop_10:
376        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
377        cmp r6, #0x10
378        bne loop_10
379        
380        /* Writing the address of (DIMM0<<1) with read indication (bit0 is 1) */
381        mov r6, r4, LSL #1
382        orr r6, r6, #1 /* Read operation address bit 0 must be 1 */
383        MV_REG_WRITE_ASM (r6, r1, TWSI_DATA_REG(I2C_CH))
384        
385        /* Clear the interrupt flag ==> the address will be transmitted */
386        bl _twsiDelay
387        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
388        bic r6, r6, #TWSI_CONTROL_INT_FLAG_SET
389        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
390        bl _twsiDelay
391        
392        /* Wait for the interrupt flag (bit3) to be set as a result of
393           transmitting the address. */
394loop_11:
395#ifdef MV78XX0
396        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
397        tst r6, #BIT2
398#else
399        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
400        tst r6, #BIT5
401#endif
402        beq loop_11
403        
404         /* Wait for status TWSI_ADDR_PLUS_READ_BIT_TRA_ACK_REC = 0x40 */
405loop_12:
406        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
407        cmp r6, #0x40
408        bne loop_12
409        
410        /* Clear the interrupt flag and the Acknoledge bit */
411        bl _twsiDelay
412        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
413        bic r6, r6, #(TWSI_CONTROL_INT_FLAG_SET | TWSI_CONTROL_ACK)
414        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
415        bl _twsiDelay
416        
417        /* Wait for the interrupt flag (bit3) to be set */
418loop_14:
419#ifdef MV78XX0
420        MV_REG_READ_ASM (r6, r1, CPU_INT_LOW_REG(I2C_CH))
421        tst r6, #BIT2
422#else
423        MV_REG_READ_ASM (r6, r1, CPU_MAIN_INT_CAUSE_REG)
424        tst r6, #BIT5
425#endif
426        beq loop_14
427        
428        /* Wait for status TWSI_MAS_REC_READ_DATA_ACK_NOT_TRA = 0x58 */
429loop_15:
430        MV_REG_READ_ASM (r6, r1, TWSI_STATUS_BAUDE_RATE_REG(I2C_CH))
431        cmp r6, #0x58
432        bne loop_15
433        
434        /* Store the data in r7. */
435        MV_REG_READ_ASM (r7, r1, TWSI_DATA_REG(I2C_CH))
436        
437        /* Generate stop bit */
438        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
439        orr r6, r6, #TWSI_CONTROL_STOP_BIT
440        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
441
442        
443        /* Clear the interrupt flag */
444        bl _twsiDelay
445        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
446        bic r6, r6, #TWSI_CONTROL_INT_FLAG_SET
447        MV_REG_WRITE_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
448        bl _twsiDelay
449        
450        /* Wait for the stop bit to be reset by HW */
451loop_16:
452        MV_REG_READ_ASM (r6, r1, TWSI_CONTROL_REG(I2C_CH))
453        tst r6, #TWSI_CONTROL_INT_FLAG_SET
454        bne loop_16
455
456exit_i2cRead:
457        mov PC, r9 /* r9 is saved link register */
458

Archive Download this file



interactive