soc: Remove copyright notices
[coreboot.git] / src / soc / cavium / cn81xx / twsi.c
bloba0ff3bb44497732a1fa699ab55504bf1d607162b
1 /*
2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
16 #include <console/console.h>
17 #include <soc/twsi.h>
18 #include <soc/clock.h>
19 #include <device/i2c.h>
20 #include <device/i2c_simple.h>
21 #include <delay.h>
22 #include <device/mmio.h>
23 #include <soc/addressmap.h>
25 #define TWSI_THP 24
27 #define TWSI_SW_TWSI 0x1000
28 #define TWSI_TWSI_SW 0x1008
29 #define TWSI_INT 0x1010
30 #define TWSI_SW_TWSI_EXT 0x1018
32 union twsx_sw_twsi {
33 u64 u;
34 struct {
35 u64 data:32;
36 u64 eop_ia:3;
37 u64 ia:5;
38 u64 addr:10;
39 u64 scr:2;
40 u64 size:3;
41 u64 sovr:1;
42 u64 r:1;
43 u64 op:4;
44 u64 eia:1;
45 u64 slonly:1;
46 u64 v:1;
47 } s;
50 union twsx_sw_twsi_ext {
51 u64 u;
52 struct {
53 u64 data:32;
54 u64 ia:8;
55 u64 :24;
56 } s;
59 union twsx_int {
60 u64 u;
61 struct {
62 u64 st_int:1; /** TWSX_SW_TWSI register update int */
63 u64 ts_int:1; /** TWSX_TWSI_SW register update int */
64 u64 core_int:1; /** TWSI core interrupt, ignored for HLC */
65 u64 :5; /** Reserved */
66 u64 sda_ovr:1; /** SDA testing override */
67 u64 scl_ovr:1; /** SCL testing override */
68 u64 sda:1; /** SDA signal */
69 u64 scl:1; /** SCL signal */
70 u64 :52; /** Reserved */
71 } s;
74 enum {
75 TWSI_OP_WRITE = 0,
76 TWSI_OP_READ = 1,
79 enum {
80 TWSI_EOP_SLAVE_ADDR = 0,
81 TWSI_EOP_CLK_CTL = 3,
82 TWSI_SW_EOP_IA = 6,
85 enum {
86 TWSI_SLAVEADD = 0,
87 TWSI_DATA = 1,
88 TWSI_CTL = 2,
89 TWSI_CLKCTL = 3,
90 TWSI_STAT = 3,
91 TWSI_SLAVEADD_EXT = 4,
92 TWSI_RST = 7,
95 enum {
96 TWSI_CTL_AAK = (1 << 2),
97 TWSI_CTL_IFLG = (1 << 3),
98 TWSI_CTL_STP = (1 << 4),
99 TWSI_CTL_STA = (1 << 5),
100 TWSI_CTL_ENAB = (1 << 6),
101 TWSI_CTL_CE = (1 << 7),
104 enum {
105 /** Bus error */
106 TWSI_STAT_BUS_ERROR = 0x00,
107 /** Start condition transmitted */
108 TWSI_STAT_START = 0x08,
109 /** Repeat start condition transmitted */
110 TWSI_STAT_RSTART = 0x10,
111 /** Address + write bit transmitted, ACK received */
112 TWSI_STAT_TXADDR_ACK = 0x18,
113 /** Address + write bit transmitted, /ACK received */
114 TWSI_STAT_TXADDR_NAK = 0x20,
115 /** Data byte transmitted in master mode, ACK received */
116 TWSI_STAT_TXDATA_ACK = 0x28,
117 /** Data byte transmitted in master mode, ACK received */
118 TWSI_STAT_TXDATA_NAK = 0x30,
119 /** Arbitration lost in address or data byte */
120 TWSI_STAT_TX_ARB_LOST = 0x38,
121 /** Address + read bit transmitted, ACK received */
122 TWSI_STAT_RXADDR_ACK = 0x40,
123 /** Address + read bit transmitted, /ACK received */
124 TWSI_STAT_RXADDR_NAK = 0x48,
125 /** Data byte received in master mode, ACK transmitted */
126 TWSI_STAT_RXDATA_ACK_SENT = 0x50,
127 /** Data byte received, NACK transmitted */
128 TWSI_STAT_RXDATA_NAK_SENT = 0x58,
129 /** Slave address received, sent ACK */
130 TWSI_STAT_SLAVE_RXADDR_ACK = 0x60,
132 * Arbitration lost in address as master, slave address + write bit
133 * received, ACK transmitted
135 TWSI_STAT_TX_ACK_ARB_LOST = 0x68,
136 /** General call address received, ACK transmitted */
137 TWSI_STAT_RX_GEN_ADDR_ACK = 0x70,
139 * Arbitration lost in address as master, general call address
140 * received, ACK transmitted
142 TWSI_STAT_RX_GEN_ADDR_ARB_LOST = 0x78,
143 /** Data byte received after slave address received, ACK transmitted */
144 TWSI_STAT_SLAVE_RXDATA_ACK = 0x80,
145 /** Data byte received after slave address received, /ACK transmitted */
146 TWSI_STAT_SLAVE_RXDATA_NAK = 0x88,
148 * Data byte received after general call address received, ACK
149 * transmitted
151 TWSI_STAT_GEN_RXADDR_ACK = 0x90,
153 * Data byte received after general call address received, /ACK
154 * transmitted
156 TWSI_STAT_GEN_RXADDR_NAK = 0x98,
157 /** STOP or repeated START condition received in slave mode */
158 TWSI_STAT_STOP_MULTI_START = 0xA0,
159 /** Slave address + read bit received, ACK transmitted */
160 TWSI_STAT_SLAVE_RXADDR2_ACK = 0xA8,
162 * Arbitration lost in address as master, slave address + read bit
163 * received, ACK transmitted
165 TWSI_STAT_RXDATA_ACK_ARB_LOST = 0xB0,
166 /** Data byte transmitted in slave mode, ACK received */
167 TWSI_STAT_SLAVE_TXDATA_ACK = 0xB8,
168 /** Data byte transmitted in slave mode, /ACK received */
169 TWSI_STAT_SLAVE_TXDATA_NAK = 0xC0,
170 /** Last byte transmitted in slave mode, ACK received */
171 TWSI_STAT_SLAVE_TXDATA_END_ACK = 0xC8,
172 /** Second address byte + write bit transmitted, ACK received */
173 TWSI_STAT_TXADDR2DATA_ACK = 0xD0,
174 /** Second address byte + write bit transmitted, /ACK received */
175 TWSI_STAT_TXADDR2DATA_NAK = 0xD8,
176 /** No relevant status information */
177 TWSI_STAT_IDLE = 0xF8
181 * Returns true if we lost arbitration
183 * @param code status code
184 * @param final_read true if this is the final read operation
186 * @return true if arbitration has been lost, false if it hasn't been lost.
188 static int twsi_i2c_lost_arb(u8 code, int final_read)
190 switch (code) {
191 /* Arbitration lost */
192 case TWSI_STAT_TX_ARB_LOST:
193 case TWSI_STAT_TX_ACK_ARB_LOST:
194 case TWSI_STAT_RX_GEN_ADDR_ARB_LOST:
195 case TWSI_STAT_RXDATA_ACK_ARB_LOST:
196 return -1;
198 /* Being addressed as slave, should back off and listen */
199 case TWSI_STAT_SLAVE_RXADDR_ACK:
200 case TWSI_STAT_RX_GEN_ADDR_ACK:
201 case TWSI_STAT_GEN_RXADDR_ACK:
202 case TWSI_STAT_GEN_RXADDR_NAK:
203 return -1;
205 /* Core busy as slave */
206 case TWSI_STAT_SLAVE_RXDATA_ACK:
207 case TWSI_STAT_SLAVE_RXDATA_NAK:
208 case TWSI_STAT_STOP_MULTI_START:
209 case TWSI_STAT_SLAVE_RXADDR2_ACK:
210 case TWSI_STAT_SLAVE_TXDATA_ACK:
211 case TWSI_STAT_SLAVE_TXDATA_NAK:
212 case TWSI_STAT_SLAVE_TXDATA_END_ACK:
213 return -1;
215 /* Ack allowed on pre-terminal bytes only */
216 case TWSI_STAT_RXDATA_ACK_SENT:
217 if (!final_read)
218 return 0;
219 return -1;
221 /* NAK allowed on terminal byte only */
222 case TWSI_STAT_RXDATA_NAK_SENT:
223 if (!final_read)
224 return 0;
225 return -1;
227 case TWSI_STAT_TXDATA_NAK:
228 case TWSI_STAT_TXADDR_NAK:
229 case TWSI_STAT_RXADDR_NAK:
230 case TWSI_STAT_TXADDR2DATA_NAK:
231 return -1;
233 return 0;
236 #define RST_BOOT_PNR_MUL(Val) ((Val >> 33) & 0x1F)
239 * Writes to the MIO_TWS(0..5)_SW_TWSI register
241 * @param baseaddr Base address of i2c registers
242 * @param sw_twsi value to write
244 * @return 0 for success, otherwise error
246 static u64 twsi_write_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
248 unsigned long timeout = 500000;
250 sw_twsi.s.r = 0;
251 sw_twsi.s.v = 1;
253 printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
254 write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
255 do {
256 sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
257 timeout--;
258 } while (sw_twsi.s.v != 0 && timeout > 0);
260 if (sw_twsi.s.v)
261 printk(BIOS_ERR, "%s: timed out\n", __func__);
262 return sw_twsi.u;
266 * Reads the MIO_TWS(0..5)_SW_TWSI register
268 * @param baseaddr Base address of i2c registers
269 * @param sw_twsi value for eia and op, etc. to read
271 * @return value of the register
273 static u64 twsi_read_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
275 unsigned long timeout = 500000;
276 sw_twsi.s.r = 1;
277 sw_twsi.s.v = 1;
279 printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
280 write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
282 do {
283 sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
284 timeout--;
285 } while (sw_twsi.s.v != 0 && timeout > 0);
287 if (sw_twsi.s.v)
288 printk(BIOS_ERR, "%s: Error writing 0x%llx\n", __func__,
289 sw_twsi.u);
291 printk(BIOS_SPEW, "%s: Returning 0x%llx\n", __func__, sw_twsi.u);
292 return sw_twsi.u;
296 * Write control register
298 * @param baseaddr Base address for i2c registers
299 * @param data data to write
301 static void twsi_write_ctl(void *baseaddr, const u8 data)
303 union twsx_sw_twsi twsi_sw;
305 printk(BIOS_SPEW, "%s(%p, 0x%x)\n", __func__, baseaddr, data);
306 twsi_sw.u = 0;
308 twsi_sw.s.op = TWSI_SW_EOP_IA;
309 twsi_sw.s.eop_ia = TWSI_CTL;
310 twsi_sw.s.data = data;
312 twsi_write_sw(baseaddr, twsi_sw);
316 * Reads the TWSI Control Register
318 * @param[in] baseaddr Base address for i2c
320 * @return 8-bit TWSI control register
322 static u32 twsi_read_ctl(void *baseaddr)
324 union twsx_sw_twsi sw_twsi;
326 sw_twsi.u = 0;
327 sw_twsi.s.op = TWSI_SW_EOP_IA;
328 sw_twsi.s.eop_ia = TWSI_CTL;
330 sw_twsi.u = twsi_read_sw(baseaddr, sw_twsi);
331 printk(BIOS_SPEW, "%s(%p): 0x%x\n", __func__, baseaddr, sw_twsi.s.data);
332 return sw_twsi.s.data;
336 * Read i2c status register
338 * @param baseaddr Base address of i2c registers
340 * @return value of status register
342 static u8 twsi_read_status(void *baseaddr)
344 union twsx_sw_twsi twsi_sw;
346 twsi_sw.u = 0;
347 twsi_sw.s.op = TWSI_SW_EOP_IA;
348 twsi_sw.s.eop_ia = TWSI_STAT;
350 return twsi_read_sw(baseaddr, twsi_sw);
354 * Waits for an i2c operation to complete
356 * @param baseaddr Base address of registers
358 * @return 0 for success, 1 if timeout
360 static int twsi_wait(void *baseaddr)
362 unsigned long timeout = 500000;
363 u8 twsi_ctl;
365 printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
366 do {
367 twsi_ctl = twsi_read_ctl(baseaddr);
368 twsi_ctl &= TWSI_CTL_IFLG;
369 timeout--;
370 } while (!twsi_ctl && timeout > 0);
372 printk(BIOS_SPEW, " return: %u\n", !twsi_ctl);
373 return !twsi_ctl;
377 * Sends an i2c stop condition
379 * @param baseaddr register base address
381 * @return 0 for success, -1 if error
383 static int twsi_stop(void *baseaddr)
385 u8 stat;
386 twsi_write_ctl(baseaddr, TWSI_CTL_STP | TWSI_CTL_ENAB);
388 stat = twsi_read_status(baseaddr);
389 if (stat != TWSI_STAT_IDLE) {
390 printk(BIOS_ERR, "%s: Bad status on bus@%p\n", __func__,
391 baseaddr);
392 return -1;
394 return 0;
398 * Manually clear the I2C bus and send a stop
400 static void twsi_unblock(void *baseaddr)
402 int i;
403 union twsx_int int_reg;
405 int_reg.u = 0;
406 for (i = 0; i < 9; i++) {
407 int_reg.s.scl_ovr = 0;
408 write64(baseaddr + TWSI_INT, int_reg.u);
409 udelay(5);
410 int_reg.s.scl_ovr = 1;
411 write64(baseaddr + TWSI_INT, int_reg.u);
412 udelay(5);
414 int_reg.s.sda_ovr = 1;
415 write64(baseaddr + TWSI_INT, int_reg.u);
416 udelay(5);
417 int_reg.s.scl_ovr = 0;
418 write64(baseaddr + TWSI_INT, int_reg.u);
419 udelay(5);
420 int_reg.u = 0;
421 write64(baseaddr + TWSI_INT, int_reg.u);
422 udelay(5);
426 * Unsticks the i2c bus
428 * @param baseaddr base address of registers
430 static int twsi_start_unstick(void *baseaddr)
432 twsi_stop(baseaddr);
434 twsi_unblock(baseaddr);
436 return 0;
440 * Sends an i2c start condition
442 * @param baseaddr base address of registers
444 * @return 0 for success, otherwise error
446 static int twsi_start(void *baseaddr)
448 int result;
449 u8 stat;
451 printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
452 twsi_write_ctl(baseaddr, TWSI_CTL_STA | TWSI_CTL_ENAB);
453 result = twsi_wait(baseaddr);
454 if (result) {
455 stat = twsi_read_status(baseaddr);
456 printk(BIOS_SPEW, "%s: result: 0x%x, status: 0x%x\n", __func__,
457 result, stat);
458 switch (stat) {
459 case TWSI_STAT_START:
460 case TWSI_STAT_RSTART:
461 return 0;
462 case TWSI_STAT_RXADDR_ACK:
463 default:
464 return twsi_start_unstick(baseaddr);
467 printk(BIOS_SPEW, "%s: success\n", __func__);
468 return 0;
472 * Writes data to the i2c bus
474 * @param baseraddr register base address
475 * @param slave_addr address of slave to write to
476 * @param buffer Pointer to buffer to write
477 * @param length Number of bytes in buffer to write
479 * @return 0 for success, otherwise error
481 static int twsi_write_data(void *baseaddr, const u8 slave_addr,
482 const u8 *buffer, const unsigned int length)
484 union twsx_sw_twsi twsi_sw;
485 unsigned int curr = 0;
486 int result;
488 printk(BIOS_SPEW, "%s(%p, 0x%x, %p, 0x%x)\n", __func__, baseaddr,
489 slave_addr, buffer, length);
490 result = twsi_start(baseaddr);
491 if (result) {
492 printk(BIOS_ERR, "%s: Could not start BUS transaction\n",
493 __func__);
494 return -1;
497 result = twsi_wait(baseaddr);
498 if (result) {
499 printk(BIOS_ERR, "%s: wait failed\n", __func__);
500 return result;
503 twsi_sw.u = 0;
504 twsi_sw.s.op = TWSI_SW_EOP_IA;
505 twsi_sw.s.eop_ia = TWSI_DATA;
506 twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_WRITE;
508 twsi_write_sw(baseaddr, twsi_sw);
509 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
511 printk(BIOS_SPEW, "%s: Waiting\n", __func__);
512 result = twsi_wait(baseaddr);
513 if (result) {
514 printk(BIOS_ERR, "%s: Timed out writing slave address 0x%x\n",
515 __func__, slave_addr);
516 return result;
518 result = twsi_read_status(baseaddr);
519 if ((result = twsi_read_status(baseaddr)) != TWSI_STAT_TXADDR_ACK) {
520 twsi_stop(baseaddr);
521 return twsi_i2c_lost_arb(result, 0);
524 while (curr < length) {
525 twsi_sw.u = 0;
526 twsi_sw.s.op = TWSI_SW_EOP_IA;
527 twsi_sw.s.eop_ia = TWSI_DATA;
528 twsi_sw.s.data = buffer[curr++];
530 twsi_write_sw(baseaddr, twsi_sw);
531 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
533 result = twsi_wait(baseaddr);
534 if (result) {
535 printk(BIOS_ERR, "%s: Timed out writing data to 0x%x\n",
536 __func__, slave_addr);
537 return result;
541 printk(BIOS_SPEW, "%s: Stopping\n", __func__);
542 return twsi_stop(baseaddr);
546 * Performs a read transaction on the i2c bus
548 * @param baseaddr Base address of twsi registers
549 * @param slave_addr i2c bus address to read from
550 * @param buffer buffer to read into
551 * @param length number of bytes to read
553 * @return 0 for success, otherwise error
555 static int twsi_read_data(void *baseaddr, const u8 slave_addr,
556 u8 *buffer, const unsigned int length)
558 union twsx_sw_twsi twsi_sw;
559 unsigned int curr = 0;
560 int result;
562 printk(BIOS_SPEW, "%s(%p, 0x%x, %p, %u)\n", __func__, baseaddr,
563 slave_addr, buffer, length);
564 result = twsi_start(baseaddr);
565 if (result) {
566 printk(BIOS_ERR, "%s: start failed\n", __func__);
567 return result;
570 result = twsi_wait(baseaddr);
571 if (result) {
572 printk(BIOS_ERR, "%s: wait failed\n", __func__);
573 return result;
576 twsi_sw.u = 0;
578 twsi_sw.s.op = TWSI_SW_EOP_IA;
579 twsi_sw.s.eop_ia = TWSI_DATA;
581 twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_READ;
583 twsi_write_sw(baseaddr, twsi_sw);
584 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
586 result = twsi_wait(baseaddr);
587 if (result) {
588 printk(BIOS_ERR, "%s: waiting for sending addr failed\n", __func__);
589 return result;
592 result = twsi_read_status(baseaddr);
593 if (result != TWSI_STAT_RXADDR_ACK) {
594 twsi_stop(baseaddr);
595 return twsi_i2c_lost_arb(result, 0);
598 while (curr < length) {
599 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB |
600 ((curr < length - 1) ? TWSI_CTL_AAK : 0));
602 result = twsi_wait(baseaddr);
603 if (result) {
604 printk(BIOS_ERR, "%s: waiting for data failed\n",
605 __func__);
606 return result;
609 twsi_sw.u = twsi_read_sw(baseaddr, twsi_sw);
610 buffer[curr++] = twsi_sw.s.data;
613 twsi_stop(baseaddr);
615 return 0;
618 static int twsi_set_speed(void *baseaddr, const unsigned int speed)
620 u64 io_clock_hz;
621 int n_div;
622 int m_div;
623 union twsx_sw_twsi sw_twsi;
625 io_clock_hz = thunderx_get_io_clock();
627 /* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the
628 * clocks M divider based on the SCLK.
629 * TWSI freq = (core freq) / (20 x (M+1) x (thp+1) x 2^N)
630 * M = ((core freq) / (20 x (TWSI freq) x (thp+1) x 2^N)) - 1
632 for (n_div = 0; n_div < 8; n_div++) {
633 m_div = io_clock_hz / (20 * speed * (TWSI_THP + 1));
634 m_div /= 1 << n_div;
635 m_div -= 1;
636 if (m_div < 16)
637 break;
639 if (m_div >= 16)
640 return -1;
642 sw_twsi.u = 0;
643 sw_twsi.s.v = 1;
644 sw_twsi.s.op = 0x6; /* See EOP field */
645 sw_twsi.s.r = 0; /* Select CLKCTL when R = 0 */
646 sw_twsi.s.eop_ia = 3; /* R=0 selects CLKCTL, R=1 selects STAT */
647 sw_twsi.s.data = ((m_div & 0xf) << 3) | ((n_div & 0x7) << 0);
649 twsi_write_sw(baseaddr, sw_twsi);
650 return 0;
653 int twsi_init(unsigned int bus, enum i2c_speed hz)
655 void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
656 if (!baseaddr)
657 return -1;
659 if (twsi_set_speed(baseaddr, hz) < 0)
660 return -1;
662 /* Enable TWSI, HLC disable, STOP, NAK */
663 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
665 return 0;
668 int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
669 int seg_count)
671 int result;
672 void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
673 if (!baseaddr)
674 return -1;
676 printk(BIOS_SPEW, "%s: %d messages\n", __func__, seg_count);
677 for (; seg_count > 0; seg_count--, segments++) {
678 if (segments->flags & I2C_M_RD) {
679 result = twsi_read_data(baseaddr, segments->slave,
680 segments->buf, segments->len);
681 } else {
682 result = twsi_write_data(baseaddr, segments->slave,
683 segments->buf, segments->len);
685 if (result) {
686 printk(BIOS_ERR, "%s: error transmitting data\n",
687 __func__);
688 return -1;
692 return 0;