]> CyberLeo.Net >> Repos - FreeBSD/releng/8.2.git/blob - sys/contrib/octeon-sdk/cvmx-twsi-raw.c
Copy stable/8 to releng/8.2 in preparation for FreeBSD-8.2 release.
[FreeBSD/releng/8.2.git] / sys / contrib / octeon-sdk / cvmx-twsi-raw.c
1 /***********************license start***************
2  * Copyright (c) 2003-2007, Cavium Networks. All rights reserved.
3  *
4  * This software file (the "File") is owned and distributed by Cavium
5  * Networks ("Cavium") under the following dual licensing option: The dual
6  * licensing option gives you, the licensee, the choice between the following
7  * alternative licensing terms.  Once you have made an election to use the
8  * File under one of the following alternative licensing terms (license
9  * types) you are bound by the respective terms and you may distribute the
10  * file (or any derivative thereof), to the extent allowed by the respective
11  * licensing term, only if you (i) delete this introductory statement
12  * regarding the dual licensing option from the file you will distribute,
13  * (ii) delete the licensing term that you have elected NOT to use from the
14  * file you will distribute and (iii) follow the respective licensing term
15  * that you have elected to use with respect to the correct attribution or
16  * licensing term that you have to include with your distribution.
17  *
18  * ***
19  * OCTEON SDK License Type 2:
20  *
21  * IMPORTANT: Read this Agreement carefully before clicking on the "I accept"
22  * button to download the Software and/or before using the Software.  This
23  * License Agreement (the "Agreement") is a legal agreement between you,
24  * either an individual or a single legal entity ("You" or "you"), and Cavium
25  * Networks ("Cavium").  This Agreement governs your use of the Cavium
26  * software that can be downloaded after accepting this Agreement and/or that
27  * is accompanied by this Agreement (the "Software").  You must accept the
28  * terms of this Agreement before downloading and/or using the Software.  By
29  * clicking on the "I accept" button to download and/or by using the
30  * Software, you are indicating that you have read and understood, and assent
31  * to be bound by, the terms of this Agreement.  If you do not agree to the
32  * terms of the Agreement, you are not granted any rights whatsoever in the
33  * Software.  If you are not willing to be bound by these terms and
34  * conditions, you should not use or cease all use of the Software.  This
35  * Software is the property of Cavium Networks and constitutes the
36  * proprietary information of Cavium Networks.  You agree to take reasonable
37  * steps to prevent the disclosure, unauthorized use or unauthorized
38  * distribution of the Software to any third party.
39  *
40  * License Grant.  Subject to the terms and conditions of this Agreement,
41  * Cavium grants you a nonexclusive, non-transferable, worldwide, fully-paid
42  * and royalty-free license to
43  *
44  * (a) install, reproduce, and execute the executable version of the Software
45  * solely for your internal use and only (a) on hardware manufactured by
46  * Cavium, or (b) software of Cavium that simulates Cavium hardware;
47  *
48  * (b) create derivative works of any portions of the Software provided to
49  * you by Cavium in source code form, which portions enable features of the
50  * Cavium hardware products you or your licensees are entitled to use,
51  * provided that any such derivative works must be used only (a) on hardware
52  * manufactured by Cavium, or (b) software of Cavium that simulates Cavium
53  * hardware; and
54  *
55  * (c) distribute derivative works you created in accordance with clause (b)
56  * above, only in executable form and only if such distribution (i)
57  * reproduces the copyright notice that can be found at the very end of this
58  * Agreement and (ii) is pursuant to a binding license agreement that
59  * contains terms no less restrictive and no less protective of Cavium than
60  * this Agreement.  You will immediately notify Cavium if you become aware of
61  * any breach of any such license agreement.
62  *
63  * Restrictions.  The rights granted to you in this Agreement are subject to
64  * the following restrictions: Except as expressly set forth in this
65  * Agreement (a) you will not license, sell, rent, lease, transfer, assign,
66  * display, host, outsource, disclose or otherwise commercially exploit or
67  * make the Software, or any derivatives you create under this Agreement,
68  * available to any third party; (b) you will not modify or create derivative
69  * works of any part of the Software; (c) you will not access or use the
70  * Software in order to create similar or competitive products, components,
71  * or services; and (d), no part of the Software may be copied (except for
72  * the making of a single archival copy), reproduced, distributed,
73  * republished, downloaded, displayed, posted or transmitted in any form or
74  * by any means.
75  *
76  * Ownership.  You acknowledge and agree that, subject to the license grant
77  * contained in this Agreement and as between you and Cavium (a) Cavium owns
78  * all copies of and intellectual property rights to the Software, however
79  * made, and retains all rights in and to the Software, including all
80  * intellectual property rights therein, and (b) you own all the derivate
81  * works of the Software created by you under this Agreement, subject to
82  * Cavium's rights in the Software.  There are no implied licenses under this
83  * Agreement, and any rights not expressly granted to your hereunder are
84  * reserved by Cavium.  You will not, at any time, contest anywhere in the
85  * world Cavium's ownership of the intellectual property rights in and to the
86  * Software.
87  *
88  * Disclaimer of Warranties.  The Software is provided to you free of charge,
89  * and on an "As-Is" basis.  Cavium provides no technical support, warranties
90  * or remedies for the Software.  Cavium and its suppliers disclaim all
91  * express, implied or statutory warranties relating to the Software,
92  * including but not limited to, merchantability, fitness for a particular
93  * purpose, title, and non-infringement.  Cavium does not warrant that the
94  * Software and the use thereof will be error-free, that defects will be
95  * corrected, or that the Software is free of viruses or other harmful
96  * components.  If applicable law requires any warranties with respect to the
97  * Software, all such warranties are limited in duration to thirty (30) days
98  * from the date of download or first use, whichever comes first.
99  *
100  * Limitation of Liability.  Neither Cavium nor its suppliers shall be
101  * responsible or liable with respect to any subject matter of this Agreement
102  * or terms or conditions related thereto under any contract, negligence,
103  * strict liability or other theory (a) for loss or inaccuracy of data or
104  * cost of procurement of substitute goods, services or technology, or (b)
105  * for any indirect, incidental or consequential damages including, but not
106  * limited to loss of revenues and loss of profits.  Cavium's aggregate
107  * cumulative liability hereunder shall not exceed the greater of Fifty U.S.
108  * Dollars (U.S.$50.00) or the amount paid by you for the Software that
109  * caused the damage.  Certain states and/or jurisdictions do not allow the
110  * exclusion of implied warranties or limitation of liability for incidental
111  * or consequential damages, so the exclusions set forth above may not apply
112  * to you.
113  *
114  * Basis of Bargain.  The warranty disclaimer and limitation of liability set
115  * forth above are fundamental elements of the basis of the agreement between
116  * Cavium and you.  Cavium would not provide the Software without such
117  * limitations.  The warranty disclaimer and limitation of liability inure to
118  * the benefit of Cavium and Cavium's suppliers.
119  *
120  * Term and Termination.  This Agreement and the licenses granted hereunder
121  * are effective on the date you accept the terms of this Agreement, download
122  * the Software, or use the Software, whichever comes first, and shall
123  * continue unless this Agreement is terminated pursuant to this section.
124  * This Agreement immediately terminates in the event that you materially
125  * breach any of the terms hereof.  You may terminate this Agreement at any
126  * time, with or without cause, by destroying any copies of the Software in
127  * your possession.  Upon termination, the license granted hereunder shall
128  * terminate but the Sections titled "Restrictions", "Ownership", "Disclaimer
129  * of Warranties", "Limitation of Liability", "Basis of Bargain", "Term and
130  * Termination", "Export", and "Miscellaneous" will remain in effect.
131  *
132  * Export.  The Software and related technology are subject to U.S.  export
133  * control laws and may be subject to export or import regulations in other
134  * countries.  You agree to strictly comply with all such laws and
135  * regulations and acknowledges that you have the responsibility to obtain
136  * authorization to export, re-export, or import the Software and related
137  * technology, as may be required.  You will indemnify and hold Cavium
138  * harmless from any and all claims, losses, liabilities, damages, fines,
139  * penalties, costs and expenses (including attorney's fees) arising from or
140  * relating to any breach by you of your obligations under this section.
141  * Your obligations under this section shall survive the expiration or
142  * termination of this Agreement.
143  *
144  * Miscellaneous.  Neither the rights nor the obligations arising under this
145  * Agreement are assignable by you, and any such attempted assignment or
146  * transfer shall be void and without effect.  This Agreement shall be
147  * governed by and construed in accordance with the laws of the State of
148  * California without regard to any conflicts of laws provisions that would
149  * require application of the laws of another jurisdiction.  Any action under
150  * or relating to this Agreement shall be brought in the state and federal
151  * courts located in California, with venue in the courts located in Santa
152  * Clara County and each party hereby submits to the personal jurisdiction of
153  * such courts; provided, however, that nothing herein will operate to
154  * prohibit or restrict Cavium from filing for and obtaining injunctive
155  * relief from any court of competent jurisdiction.  The United Nations
156  * Convention on Contracts for the International Sale of Goods shall not
157  * apply to this Agreement.  In the event that any provision of this
158  * Agreement is found to be contrary to law, then such provision shall be
159  * construed as nearly as possible to reflect the intention of the parties,
160  * with the other provisions remaining in full force and effect.  Any notice
161  * to you may be provided by email.  This Agreement constitutes the entire
162  * agreement between the parties and supersedes all prior or contemporaneous,
163  * agreements, understandings and communications between the parties, whether
164  * written or oral, pertaining to the subject matter hereof.  Any
165  * modifications of this Agreement must be in writing and agreed to by both
166  * parties.
167  *
168  * Copyright (c) 2003-2007, Cavium Networks. All rights reserved.
169  *
170  * ***
171  *
172  * OCTEON SDK License Type 4:
173  *
174  * Author: Cavium Networks
175  *
176  * Contact: support@caviumnetworks.com
177  * This file is part of the OCTEON SDK
178  *
179  * Copyright (c) 2007 Cavium Networks
180  *
181  * This file is free software; you can redistribute it and/or modify
182  * it under the terms of the GNU General Public License, Version 2, as published by
183  * the Free Software Foundation.
184  *
185  * This file is distributed in the hope that it will be useful,
186  * but AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty of
187  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NONINFRINGEMENT.
188  * See the GNU General Public License for more details.
189  * it under the terms of the GNU General Public License, Version 2, as published by
190  * the Free Software Foundation.
191  *
192  * You should have received a copy of the GNU General Public License
193  * along with this file; if not, write to the Free Software
194  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
195  * or visit http://www.gnu.org/licenses/.
196  *
197  * This file may also be available under a different license from Cavium.
198  * Contact Cavium Networks for more information
199  ***********************license end**************************************/
200
201
202 /*
203  * This code is an example of using twsi core in raw mode, bypasing High 
204  * Level Controller (HLC). It is recommended to use HLC if only possible as 
205  * it is more efficient and robust mechanism. 
206  * The example code shows use of twsi for generating long (more that 8 bytes HLC limit) 
207  * read - write transactions using 7-bit addressing. Different types of 
208  * transactions can be generated if needed. Make sure that commands written to twsi core 
209  * follow core state transitions outlinged in OCTEON documentation. The core state is 
210  * reported in stat register after the command colpletion. In each state core will accept
211  *  only the allowed commands.
212  */
213  
214 #include <stdio.h>
215 #include <cvmx.h>
216 #include <cvmx-csr-typedefs.h>
217 #include "cvmx-twsi-raw.h"
218
219 /*
220  * uint8_t cvmx_twsix_read_ctr(int twsi_id, uint8_t reg)
221  * twsi core register read
222  * twsi_id - twsi core index
223  * reg 0 - 8-bit register
224  * returns 8-bit register contetn
225  */
226 uint8_t cvmx_twsix_read_ctr(int twsi_id, uint8_t reg)
227 {
228     cvmx_mio_twsx_sw_twsi_t sw_twsi_val;
229
230     sw_twsi_val.u64 = 0;
231     sw_twsi_val.s.v = 1;
232     sw_twsi_val.s.op = 6;
233     sw_twsi_val.s.eop_ia = reg;
234     sw_twsi_val.s.r = 1;
235     cvmx_write_csr(CVMX_MIO_TWSX_SW_TWSI(twsi_id), sw_twsi_val.u64);
236     while (((cvmx_mio_twsx_sw_twsi_t)(sw_twsi_val.u64 = cvmx_read_csr(CVMX_MIO_TWSX_SW_TWSI(twsi_id)))).s.v)
237         ;
238     return sw_twsi_val.s.d ;
239 }
240
241 /*
242  * uint8_t cvmx_twsix_write_ctr(int twsi_id, uint8_t reg, uint8_t data)
243  *
244  * twsi core register write
245  * twsi_id - twsi core index
246  * reg 0 - 8-bit register
247  * data - data to write
248  * returns 0;
249  */
250
251 int cvmx_twsix_write_ctr(int twsi_id, uint8_t reg, uint8_t data)
252 {
253     cvmx_mio_twsx_sw_twsi_t sw_twsi_val;
254
255     sw_twsi_val.u64 = 0;
256     sw_twsi_val.s.v = 1;
257     sw_twsi_val.s.op = 6;
258     sw_twsi_val.s.eop_ia = reg;
259     sw_twsi_val.s.d = data;
260     cvmx_write_csr(CVMX_MIO_TWSX_SW_TWSI(twsi_id), sw_twsi_val.u64);
261     while (((cvmx_mio_twsx_sw_twsi_t)(sw_twsi_val.u64 = cvmx_read_csr(CVMX_MIO_TWSX_SW_TWSI(twsi_id)))).s.v)
262         ;
263
264     return 0;
265 }
266
267 /*
268  * cvmx_twsi_wait_iflg(int twsi_id)
269  * cvmx_twsi_wait_stop(int twsi_id)
270  *
271  * Helper functions. 
272  * Busy wait for interrupt flag or stop bit on control register. This implementation is for OS-less 
273  * application. With OS services available it could be implemented with semaphore
274  * block and interrupt wake up. 
275  * TWSI_WAIT for loop must be defined large enough to allow on-wire transaction to finish - that is 
276  * about 10 twsi clocks
277  */
278 #define TWSI_WAIT 10000000
279 static inline int cvmx_twsi_wait_iflg(int twsi_id)
280 {
281     octeon_twsi_ctl_t ctl_reg;
282     int wait = TWSI_WAIT;
283     do{
284         ctl_reg.u8 = cvmx_twsix_read_ctr(twsi_id, TWSI_CTL_REG);
285     } while((ctl_reg.s.iflg ==0) && (wait-- >0));
286     if(wait == 0) return -1;
287     return 0;
288 }
289
290 static inline int cvmx_twsi_wait_stop(int twsi_id)
291 {
292     octeon_twsi_ctl_t ctl_reg;
293     int wait = TWSI_WAIT;
294     do{
295         ctl_reg.u8 = cvmx_twsix_read_ctr(twsi_id, TWSI_CTL_REG);
296     } while((ctl_reg.s.stp ==1) && (wait-- >0));
297     if(wait == 0) return -1;
298     return 0;
299 }
300
301
302 /*
303  * uint8_t octeon_twsi_read_byte(int twsi_id, uint8_t* byte, int ack) 
304  * uint8_t octeon_twsi_write_byte(int twsi_id, uint8_t byte)
305  *
306  * helper functions - read or write byte to data reg and reads the TWSI core status
307  */
308 static uint8_t octeon_twsi_read_byte(int twsi_id, uint8_t* byte, int ack)
309 {
310     octeon_twsi_ctl_t ctl_reg;
311     octeon_twsi_data_t data;
312     octeon_twsi_stat_t stat;
313
314     /* clear interrupt flag, set aak for requested ACK signal level */
315     ctl_reg.u8 =0;
316     ctl_reg.s.aak = (ack==0) ?0:1;
317     ctl_reg.s.enab =1;
318     cvmx_twsix_write_ctr(twsi_id, TWSI_CTL_REG, ctl_reg.u8);
319
320     /* wait for  twsi_ctl[iflg] to be set */
321     if(cvmx_twsi_wait_iflg(twsi_id)) goto error;
322
323     /* read the byte */
324     data.u8 =cvmx_twsix_read_ctr(twsi_id, TWSI_DATA_REG);
325     *byte = data.s.data;
326 error:
327     /* read the status */
328     stat.u8 = cvmx_twsix_read_ctr(twsi_id, TWSI_STAT_REG);
329     return stat.s.stat;
330 }
331
332 static uint8_t octeon_twsi_write_byte(int twsi_id, uint8_t byte)
333 {
334     octeon_twsi_ctl_t ctl_reg;
335     octeon_twsi_data_t data;
336     octeon_twsi_stat_t stat;
337
338     /* tx data byte - write to twsi_data reg, then clear twsi_ctl[iflg] */
339     data.s.data = byte;
340     cvmx_twsix_write_ctr(twsi_id, TWSI_DATA_REG, data.u8);
341
342     ctl_reg.u8 = cvmx_twsix_read_ctr(twsi_id, TWSI_CTL_REG);
343     ctl_reg.s.iflg =0;
344     cvmx_twsix_write_ctr(twsi_id, TWSI_CTL_REG, ctl_reg.u8);
345
346     /* wait for  twsi_ctl[iflg] to be set */
347     if(cvmx_twsi_wait_iflg(twsi_id)) goto error;
348 error:
349      /* read the status */
350      stat.u8 = cvmx_twsix_read_ctr(twsi_id, TWSI_STAT_REG);
351      return stat.s.stat;
352 }
353
354 /*
355  * int octeon_i2c_xfer_msg_raw(struct i2c_msg *msg)
356  *
357  * Send (read or write) a message with 7-bit address device over direct control of 
358  * TWSI core, bypassind HLC. Will try to finish the transaction on failure, so core state
359  * expected to be idle with HLC enabled on exit.
360  *
361  * dev - TWSI controller index (0 for cores with single controler)
362  * msg - message to transfer
363  * returns 0 on success, TWSI core state on error. Will try to finish the transaction on failure, so core state expected to be idle
364  */
365 int octeon_i2c_xfer_msg_raw(int twsi_id, struct i2c_msg *msg)
366 {
367     int i =0;
368     octeon_twsi_ctl_t ctl_reg;
369     octeon_twsi_addr_t addr;
370     octeon_twsi_stat_t stat;
371     int is_read = msg->flags & I2C_M_RD;
372     int ret =0;
373
374     /* check the core state, quit if not idle */
375     stat.u8 =cvmx_twsix_read_ctr(twsi_id, TWSI_STAT_REG);
376     if(stat.s.stat != TWSI_IDLE) {
377        msg->len =0; return stat.s.stat;
378     }
379
380     /* first send start - set twsi_ctl[sta] to 1 */
381     ctl_reg.u8 =0;
382     ctl_reg.s.enab =1;
383     ctl_reg.s.sta =1;
384     ctl_reg.s.iflg =0;
385     cvmx_twsix_write_ctr(twsi_id, TWSI_CTL_REG, ctl_reg.u8);
386     /* wait for  twsi_ctl[iflg] to be set */
387     if(cvmx_twsi_wait_iflg(twsi_id)) goto stop;
388
389     /* Write 7-bit addr to twsi_data; set read bit */
390     addr.s.slave_addr7 = msg->addr;
391     if(is_read) addr.s.r =1;
392     else addr.s.r =0;
393     stat.s.stat =octeon_twsi_write_byte(twsi_id, addr.u8);
394
395     /* Data read loop */
396     if( is_read) {
397     /* any status but ACK_RXED means failure - we try to send stop and go idle */
398       if(!(stat.s.stat == TWSI_ADDR_R_TX_ACK_RXED)) {
399       ret = stat.s.stat;
400       msg->len =0;
401       goto stop;
402      }
403      /* We read data from the buffer and send ACK back.
404        The last byte we read with negative ACK */
405       for(i =0; i<msg->len-1; i++)
406       {
407         stat.s.stat =octeon_twsi_read_byte(twsi_id, &msg->buf[i], 1);
408         if(stat.s.stat != TWSI_DATA_RX_ACK_TXED)
409            goto stop;
410       }
411       /* last read we send negACK */
412       stat.s.stat =octeon_twsi_read_byte(twsi_id, &msg->buf[i], 0);
413         if(stat.s.stat != TWSI_DATA_RX_NACK_TXED)
414              return stat.s.stat;
415     } /* read loop */
416
417     /* Data write loop */
418     else {
419     /* any status but ACK_RXED means failure - we try to send stop and go idle */
420       if(stat.s.stat != TWSI_ADDR_W_TX_ACK_RXED) {
421           ret = stat.s.stat;
422           msg->len =0;
423           goto stop;
424       }
425       /* We write data to the buffer and check for ACK. */
426       for(i =0; i<msg->len; i++)
427       {
428           stat.s.stat =octeon_twsi_write_byte(twsi_id, msg->buf[i]);
429           if(stat.s.stat == TWSI_DATA_TX_NACK_RXED) {
430               /* Negative ACK means slave can not RX more */
431               msg->len =i-1;
432               goto stop;
433           }
434           else if(stat.s.stat != TWSI_DATA_TX_ACK_RXED) {
435               /* lost arbitration? try to send stop and go idle. This current byte likely was not written */
436               msg->len = (i-2) >0? (i-2):0;
437               goto stop;
438           }
439       }
440     }  /* write loop */
441
442 stop:
443     ctl_reg.u8 =cvmx_twsix_read_ctr(twsi_id, TWSI_CTL_REG);
444     ctl_reg.s.stp =1;
445     ctl_reg.s.iflg =0;
446     cvmx_twsix_write_ctr(twsi_id, TWSI_CTL_REG, ctl_reg.u8);
447     /* wait for  twsi_ctl[stp] to clear */
448     cvmx_twsi_wait_stop(twsi_id);
449 #if 0
450     stat.u8 = cvmx_twsix_read_ctr(twsi_id, TWSI_STAT_REG);
451     if(stat.s.stat == TWSI_IDLE)
452 #endif
453     /* Leave TWSI core with HLC eabled */
454     {
455        ctl_reg.u8 =0;
456        ctl_reg.s.ce =1;
457        ctl_reg.s.enab =1;
458        ctl_reg.s.aak =1;
459        cvmx_twsix_write_ctr(twsi_id, TWSI_CTL_REG, ctl_reg.u8);
460     }
461
462     return ret;
463 }
464