src/soc: change "unsigned" to "unsigned int"
[coreboot.git] / src / soc / cavium / cn81xx / twsi.c
blobafa98c6adc1f63e06ee51fbc5d7e4bb3c7391fd3
1 /*
2 * This file is part of the coreboot project.
4 * Copyright 2018 Facebook, Inc.
5 * Copyright 2003-2017 Cavium Inc.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
18 #include <console/console.h>
19 #include <soc/twsi.h>
20 #include <soc/clock.h>
21 #include <device/i2c.h>
22 #include <device/i2c_simple.h>
23 #include <delay.h>
24 #include <device/mmio.h>
25 #include <soc/addressmap.h>
27 #define TWSI_THP 24
29 #define TWSI_SW_TWSI 0x1000
30 #define TWSI_TWSI_SW 0x1008
31 #define TWSI_INT 0x1010
32 #define TWSI_SW_TWSI_EXT 0x1018
34 union twsx_sw_twsi {
35 u64 u;
36 struct {
37 u64 data:32;
38 u64 eop_ia:3;
39 u64 ia:5;
40 u64 addr:10;
41 u64 scr:2;
42 u64 size:3;
43 u64 sovr:1;
44 u64 r:1;
45 u64 op:4;
46 u64 eia:1;
47 u64 slonly:1;
48 u64 v:1;
49 } s;
52 union twsx_sw_twsi_ext {
53 u64 u;
54 struct {
55 u64 data:32;
56 u64 ia:8;
57 u64 :24;
58 } s;
61 union twsx_int {
62 u64 u;
63 struct {
64 u64 st_int:1; /** TWSX_SW_TWSI register update int */
65 u64 ts_int:1; /** TWSX_TWSI_SW register update int */
66 u64 core_int:1; /** TWSI core interrupt, ignored for HLC */
67 u64 :5; /** Reserved */
68 u64 sda_ovr:1; /** SDA testing override */
69 u64 scl_ovr:1; /** SCL testing override */
70 u64 sda:1; /** SDA signal */
71 u64 scl:1; /** SCL signal */
72 u64 :52; /** Reserved */
73 } s;
76 enum {
77 TWSI_OP_WRITE = 0,
78 TWSI_OP_READ = 1,
81 enum {
82 TWSI_EOP_SLAVE_ADDR = 0,
83 TWSI_EOP_CLK_CTL = 3,
84 TWSI_SW_EOP_IA = 6,
87 enum {
88 TWSI_SLAVEADD = 0,
89 TWSI_DATA = 1,
90 TWSI_CTL = 2,
91 TWSI_CLKCTL = 3,
92 TWSI_STAT = 3,
93 TWSI_SLAVEADD_EXT = 4,
94 TWSI_RST = 7,
97 enum {
98 TWSI_CTL_AAK = (1 << 2),
99 TWSI_CTL_IFLG = (1 << 3),
100 TWSI_CTL_STP = (1 << 4),
101 TWSI_CTL_STA = (1 << 5),
102 TWSI_CTL_ENAB = (1 << 6),
103 TWSI_CTL_CE = (1 << 7),
106 enum {
107 /** Bus error */
108 TWSI_STAT_BUS_ERROR = 0x00,
109 /** Start condition transmitted */
110 TWSI_STAT_START = 0x08,
111 /** Repeat start condition transmitted */
112 TWSI_STAT_RSTART = 0x10,
113 /** Address + write bit transmitted, ACK received */
114 TWSI_STAT_TXADDR_ACK = 0x18,
115 /** Address + write bit transmitted, /ACK received */
116 TWSI_STAT_TXADDR_NAK = 0x20,
117 /** Data byte transmitted in master mode, ACK received */
118 TWSI_STAT_TXDATA_ACK = 0x28,
119 /** Data byte transmitted in master mode, ACK received */
120 TWSI_STAT_TXDATA_NAK = 0x30,
121 /** Arbitration lost in address or data byte */
122 TWSI_STAT_TX_ARB_LOST = 0x38,
123 /** Address + read bit transmitted, ACK received */
124 TWSI_STAT_RXADDR_ACK = 0x40,
125 /** Address + read bit transmitted, /ACK received */
126 TWSI_STAT_RXADDR_NAK = 0x48,
127 /** Data byte received in master mode, ACK transmitted */
128 TWSI_STAT_RXDATA_ACK_SENT = 0x50,
129 /** Data byte received, NACK transmitted */
130 TWSI_STAT_RXDATA_NAK_SENT = 0x58,
131 /** Slave address received, sent ACK */
132 TWSI_STAT_SLAVE_RXADDR_ACK = 0x60,
134 * Arbitration lost in address as master, slave address + write bit
135 * received, ACK transmitted
137 TWSI_STAT_TX_ACK_ARB_LOST = 0x68,
138 /** General call address received, ACK transmitted */
139 TWSI_STAT_RX_GEN_ADDR_ACK = 0x70,
141 * Arbitration lost in address as master, general call address
142 * received, ACK transmitted
144 TWSI_STAT_RX_GEN_ADDR_ARB_LOST = 0x78,
145 /** Data byte received after slave address received, ACK transmitted */
146 TWSI_STAT_SLAVE_RXDATA_ACK = 0x80,
147 /** Data byte received after slave address received, /ACK transmitted */
148 TWSI_STAT_SLAVE_RXDATA_NAK = 0x88,
150 * Data byte received after general call address received, ACK
151 * transmitted
153 TWSI_STAT_GEN_RXADDR_ACK = 0x90,
155 * Data byte received after general call address received, /ACK
156 * transmitted
158 TWSI_STAT_GEN_RXADDR_NAK = 0x98,
159 /** STOP or repeated START condition received in slave mode */
160 TWSI_STAT_STOP_MULTI_START = 0xA0,
161 /** Slave address + read bit received, ACK transmitted */
162 TWSI_STAT_SLAVE_RXADDR2_ACK = 0xA8,
164 * Arbitration lost in address as master, slave address + read bit
165 * received, ACK transmitted
167 TWSI_STAT_RXDATA_ACK_ARB_LOST = 0xB0,
168 /** Data byte transmitted in slave mode, ACK received */
169 TWSI_STAT_SLAVE_TXDATA_ACK = 0xB8,
170 /** Data byte transmitted in slave mode, /ACK received */
171 TWSI_STAT_SLAVE_TXDATA_NAK = 0xC0,
172 /** Last byte transmitted in slave mode, ACK received */
173 TWSI_STAT_SLAVE_TXDATA_END_ACK = 0xC8,
174 /** Second address byte + write bit transmitted, ACK received */
175 TWSI_STAT_TXADDR2DATA_ACK = 0xD0,
176 /** Second address byte + write bit transmitted, /ACK received */
177 TWSI_STAT_TXADDR2DATA_NAK = 0xD8,
178 /** No relevant status information */
179 TWSI_STAT_IDLE = 0xF8
183 * Returns true if we lost arbitration
185 * @param code status code
186 * @param final_read true if this is the final read operation
188 * @return true if arbitration has been lost, false if it hasn't been lost.
190 static int twsi_i2c_lost_arb(u8 code, int final_read)
192 switch (code) {
193 /* Arbitration lost */
194 case TWSI_STAT_TX_ARB_LOST:
195 case TWSI_STAT_TX_ACK_ARB_LOST:
196 case TWSI_STAT_RX_GEN_ADDR_ARB_LOST:
197 case TWSI_STAT_RXDATA_ACK_ARB_LOST:
198 return -1;
200 /* Being addressed as slave, should back off and listen */
201 case TWSI_STAT_SLAVE_RXADDR_ACK:
202 case TWSI_STAT_RX_GEN_ADDR_ACK:
203 case TWSI_STAT_GEN_RXADDR_ACK:
204 case TWSI_STAT_GEN_RXADDR_NAK:
205 return -1;
207 /* Core busy as slave */
208 case TWSI_STAT_SLAVE_RXDATA_ACK:
209 case TWSI_STAT_SLAVE_RXDATA_NAK:
210 case TWSI_STAT_STOP_MULTI_START:
211 case TWSI_STAT_SLAVE_RXADDR2_ACK:
212 case TWSI_STAT_SLAVE_TXDATA_ACK:
213 case TWSI_STAT_SLAVE_TXDATA_NAK:
214 case TWSI_STAT_SLAVE_TXDATA_END_ACK:
215 return -1;
217 /* Ack allowed on pre-terminal bytes only */
218 case TWSI_STAT_RXDATA_ACK_SENT:
219 if (!final_read)
220 return 0;
221 return -1;
223 /* NAK allowed on terminal byte only */
224 case TWSI_STAT_RXDATA_NAK_SENT:
225 if (!final_read)
226 return 0;
227 return -1;
229 case TWSI_STAT_TXDATA_NAK:
230 case TWSI_STAT_TXADDR_NAK:
231 case TWSI_STAT_RXADDR_NAK:
232 case TWSI_STAT_TXADDR2DATA_NAK:
233 return -1;
235 return 0;
238 #define RST_BOOT_PNR_MUL(Val) ((Val >> 33) & 0x1F)
241 * Writes to the MIO_TWS(0..5)_SW_TWSI register
243 * @param baseaddr Base address of i2c registers
244 * @param sw_twsi value to write
246 * @return 0 for success, otherwise error
248 static u64 twsi_write_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
250 unsigned long timeout = 500000;
252 sw_twsi.s.r = 0;
253 sw_twsi.s.v = 1;
255 printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
256 write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
257 do {
258 sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
259 timeout--;
260 } while (sw_twsi.s.v != 0 && timeout > 0);
262 if (sw_twsi.s.v)
263 printk(BIOS_ERR, "%s: timed out\n", __func__);
264 return sw_twsi.u;
268 * Reads the MIO_TWS(0..5)_SW_TWSI register
270 * @param baseaddr Base address of i2c registers
271 * @param sw_twsi value for eia and op, etc. to read
273 * @return value of the register
275 static u64 twsi_read_sw(void *baseaddr, union twsx_sw_twsi sw_twsi)
277 unsigned long timeout = 500000;
278 sw_twsi.s.r = 1;
279 sw_twsi.s.v = 1;
281 printk(BIOS_SPEW, "%s(%p, 0x%llx)\n", __func__, baseaddr, sw_twsi.u);
282 write64(baseaddr + TWSI_SW_TWSI, sw_twsi.u);
284 do {
285 sw_twsi.u = read64(baseaddr + TWSI_SW_TWSI);
286 timeout--;
287 } while (sw_twsi.s.v != 0 && timeout > 0);
289 if (sw_twsi.s.v)
290 printk(BIOS_ERR, "%s: Error writing 0x%llx\n", __func__,
291 sw_twsi.u);
293 printk(BIOS_SPEW, "%s: Returning 0x%llx\n", __func__, sw_twsi.u);
294 return sw_twsi.u;
298 * Write control register
300 * @param baseaddr Base address for i2c registers
301 * @param data data to write
303 static void twsi_write_ctl(void *baseaddr, const u8 data)
305 union twsx_sw_twsi twsi_sw;
307 printk(BIOS_SPEW, "%s(%p, 0x%x)\n", __func__, baseaddr, data);
308 twsi_sw.u = 0;
310 twsi_sw.s.op = TWSI_SW_EOP_IA;
311 twsi_sw.s.eop_ia = TWSI_CTL;
312 twsi_sw.s.data = data;
314 twsi_write_sw(baseaddr, twsi_sw);
318 * Reads the TWSI Control Register
320 * @param[in] baseaddr Base address for i2c
322 * @return 8-bit TWSI control register
324 static u32 twsi_read_ctl(void *baseaddr)
326 union twsx_sw_twsi sw_twsi;
328 sw_twsi.u = 0;
329 sw_twsi.s.op = TWSI_SW_EOP_IA;
330 sw_twsi.s.eop_ia = TWSI_CTL;
332 sw_twsi.u = twsi_read_sw(baseaddr, sw_twsi);
333 printk(BIOS_SPEW, "%s(%p): 0x%x\n", __func__, baseaddr, sw_twsi.s.data);
334 return sw_twsi.s.data;
338 * Read i2c status register
340 * @param baseaddr Base address of i2c registers
342 * @return value of status register
344 static u8 twsi_read_status(void *baseaddr)
346 union twsx_sw_twsi twsi_sw;
348 twsi_sw.u = 0;
349 twsi_sw.s.op = TWSI_SW_EOP_IA;
350 twsi_sw.s.eop_ia = TWSI_STAT;
352 return twsi_read_sw(baseaddr, twsi_sw);
356 * Waits for an i2c operation to complete
358 * @param baseaddr Base address of registers
360 * @return 0 for success, 1 if timeout
362 static int twsi_wait(void *baseaddr)
364 unsigned long timeout = 500000;
365 u8 twsi_ctl;
367 printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
368 do {
369 twsi_ctl = twsi_read_ctl(baseaddr);
370 twsi_ctl &= TWSI_CTL_IFLG;
371 timeout--;
372 } while (!twsi_ctl && timeout > 0);
374 printk(BIOS_SPEW, " return: %u\n", !twsi_ctl);
375 return !twsi_ctl;
379 * Sends an i2c stop condition
381 * @param baseaddr register base address
383 * @return 0 for success, -1 if error
385 static int twsi_stop(void *baseaddr)
387 u8 stat;
388 twsi_write_ctl(baseaddr, TWSI_CTL_STP | TWSI_CTL_ENAB);
390 stat = twsi_read_status(baseaddr);
391 if (stat != TWSI_STAT_IDLE) {
392 printk(BIOS_ERR, "%s: Bad status on bus@%p\n", __func__,
393 baseaddr);
394 return -1;
396 return 0;
400 * Manually clear the I2C bus and send a stop
402 static void twsi_unblock(void *baseaddr)
404 int i;
405 union twsx_int int_reg;
407 int_reg.u = 0;
408 for (i = 0; i < 9; i++) {
409 int_reg.s.scl_ovr = 0;
410 write64(baseaddr + TWSI_INT, int_reg.u);
411 udelay(5);
412 int_reg.s.scl_ovr = 1;
413 write64(baseaddr + TWSI_INT, int_reg.u);
414 udelay(5);
416 int_reg.s.sda_ovr = 1;
417 write64(baseaddr + TWSI_INT, int_reg.u);
418 udelay(5);
419 int_reg.s.scl_ovr = 0;
420 write64(baseaddr + TWSI_INT, int_reg.u);
421 udelay(5);
422 int_reg.u = 0;
423 write64(baseaddr + TWSI_INT, int_reg.u);
424 udelay(5);
428 * Unsticks the i2c bus
430 * @param baseaddr base address of registers
432 static int twsi_start_unstick(void *baseaddr)
434 twsi_stop(baseaddr);
436 twsi_unblock(baseaddr);
438 return 0;
442 * Sends an i2c start condition
444 * @param baseaddr base address of registers
446 * @return 0 for success, otherwise error
448 static int twsi_start(void *baseaddr)
450 int result;
451 u8 stat;
453 printk(BIOS_SPEW, "%s(%p)\n", __func__, baseaddr);
454 twsi_write_ctl(baseaddr, TWSI_CTL_STA | TWSI_CTL_ENAB);
455 result = twsi_wait(baseaddr);
456 if (result) {
457 stat = twsi_read_status(baseaddr);
458 printk(BIOS_SPEW, "%s: result: 0x%x, status: 0x%x\n", __func__,
459 result, stat);
460 switch (stat) {
461 case TWSI_STAT_START:
462 case TWSI_STAT_RSTART:
463 return 0;
464 case TWSI_STAT_RXADDR_ACK:
465 default:
466 return twsi_start_unstick(baseaddr);
469 printk(BIOS_SPEW, "%s: success\n", __func__);
470 return 0;
474 * Writes data to the i2c bus
476 * @param baseraddr register base address
477 * @param slave_addr address of slave to write to
478 * @param buffer Pointer to buffer to write
479 * @param length Number of bytes in buffer to write
481 * @return 0 for success, otherwise error
483 static int twsi_write_data(void *baseaddr, const u8 slave_addr,
484 const u8 *buffer, const unsigned int length)
486 union twsx_sw_twsi twsi_sw;
487 unsigned int curr = 0;
488 int result;
490 printk(BIOS_SPEW, "%s(%p, 0x%x, %p, 0x%x)\n", __func__, baseaddr,
491 slave_addr, buffer, length);
492 result = twsi_start(baseaddr);
493 if (result) {
494 printk(BIOS_ERR, "%s: Could not start BUS transaction\n",
495 __func__);
496 return -1;
499 result = twsi_wait(baseaddr);
500 if (result) {
501 printk(BIOS_ERR, "%s: wait failed\n", __func__);
502 return result;
505 twsi_sw.u = 0;
506 twsi_sw.s.op = TWSI_SW_EOP_IA;
507 twsi_sw.s.eop_ia = TWSI_DATA;
508 twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_WRITE;
510 twsi_write_sw(baseaddr, twsi_sw);
511 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
513 printk(BIOS_SPEW, "%s: Waiting\n", __func__);
514 result = twsi_wait(baseaddr);
515 if (result) {
516 printk(BIOS_ERR, "%s: Timed out writing slave address 0x%x\n",
517 __func__, slave_addr);
518 return result;
520 result = twsi_read_status(baseaddr);
521 if ((result = twsi_read_status(baseaddr)) != TWSI_STAT_TXADDR_ACK) {
522 twsi_stop(baseaddr);
523 return twsi_i2c_lost_arb(result, 0);
526 while (curr < length) {
527 twsi_sw.u = 0;
528 twsi_sw.s.op = TWSI_SW_EOP_IA;
529 twsi_sw.s.eop_ia = TWSI_DATA;
530 twsi_sw.s.data = buffer[curr++];
532 twsi_write_sw(baseaddr, twsi_sw);
533 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
535 result = twsi_wait(baseaddr);
536 if (result) {
537 printk(BIOS_ERR, "%s: Timed out writing data to 0x%x\n",
538 __func__, slave_addr);
539 return result;
543 printk(BIOS_SPEW, "%s: Stopping\n", __func__);
544 return twsi_stop(baseaddr);
548 * Performs a read transaction on the i2c bus
550 * @param baseaddr Base address of twsi registers
551 * @param slave_addr i2c bus address to read from
552 * @param buffer buffer to read into
553 * @param length number of bytes to read
555 * @return 0 for success, otherwise error
557 static int twsi_read_data(void *baseaddr, const u8 slave_addr,
558 u8 *buffer, const unsigned int length)
560 union twsx_sw_twsi twsi_sw;
561 unsigned int curr = 0;
562 int result;
564 printk(BIOS_SPEW, "%s(%p, 0x%x, %p, %u)\n", __func__, baseaddr,
565 slave_addr, buffer, length);
566 result = twsi_start(baseaddr);
567 if (result) {
568 printk(BIOS_ERR, "%s: start failed\n", __func__);
569 return result;
572 result = twsi_wait(baseaddr);
573 if (result) {
574 printk(BIOS_ERR, "%s: wait failed\n", __func__);
575 return result;
578 twsi_sw.u = 0;
580 twsi_sw.s.op = TWSI_SW_EOP_IA;
581 twsi_sw.s.eop_ia = TWSI_DATA;
583 twsi_sw.s.data = (u32) (slave_addr << 1) | TWSI_OP_READ;
585 twsi_write_sw(baseaddr, twsi_sw);
586 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
588 result = twsi_wait(baseaddr);
589 if (result) {
590 printk(BIOS_ERR, "%s: waiting for sending addr failed\n", __func__);
591 return result;
594 result = twsi_read_status(baseaddr);
595 if (result != TWSI_STAT_RXADDR_ACK) {
596 twsi_stop(baseaddr);
597 return twsi_i2c_lost_arb(result, 0);
600 while (curr < length) {
601 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB |
602 ((curr < length - 1) ? TWSI_CTL_AAK : 0));
604 result = twsi_wait(baseaddr);
605 if (result) {
606 printk(BIOS_ERR, "%s: waiting for data failed\n",
607 __func__);
608 return result;
611 twsi_sw.u = twsi_read_sw(baseaddr, twsi_sw);
612 buffer[curr++] = twsi_sw.s.data;
615 twsi_stop(baseaddr);
617 return 0;
620 static int twsi_set_speed(void *baseaddr, const unsigned int speed)
622 u64 io_clock_hz;
623 int n_div;
624 int m_div;
625 union twsx_sw_twsi sw_twsi;
627 io_clock_hz = thunderx_get_io_clock();
629 /* Set the TWSI clock to a conservative TWSI_BUS_FREQ. Compute the
630 * clocks M divider based on the SCLK.
631 * TWSI freq = (core freq) / (20 x (M+1) x (thp+1) x 2^N)
632 * M = ((core freq) / (20 x (TWSI freq) x (thp+1) x 2^N)) - 1
634 for (n_div = 0; n_div < 8; n_div++) {
635 m_div = io_clock_hz / (20 * speed * (TWSI_THP + 1));
636 m_div /= 1 << n_div;
637 m_div -= 1;
638 if (m_div < 16)
639 break;
641 if (m_div >= 16)
642 return -1;
644 sw_twsi.u = 0;
645 sw_twsi.s.v = 1;
646 sw_twsi.s.op = 0x6; /* See EOP field */
647 sw_twsi.s.r = 0; /* Select CLKCTL when R = 0 */
648 sw_twsi.s.eop_ia = 3; /* R=0 selects CLKCTL, R=1 selects STAT */
649 sw_twsi.s.data = ((m_div & 0xf) << 3) | ((n_div & 0x7) << 0);
651 twsi_write_sw(baseaddr, sw_twsi);
652 return 0;
655 int twsi_init(unsigned int bus, enum i2c_speed hz)
657 void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
658 if (!baseaddr)
659 return -1;
661 if (twsi_set_speed(baseaddr, hz) < 0)
662 return -1;
664 /* Enable TWSI, HLC disable, STOP, NAK */
665 twsi_write_ctl(baseaddr, TWSI_CTL_ENAB);
667 return 0;
670 int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
671 int seg_count)
673 int result;
674 void *baseaddr = (void *)MIO_TWSx_PF_BAR0(bus);
675 if (!baseaddr)
676 return -1;
678 printk(BIOS_SPEW, "%s: %d messages\n", __func__, seg_count);
679 for (; seg_count > 0; seg_count--, segments++) {
680 if (segments->flags & I2C_M_RD) {
681 result = twsi_read_data(baseaddr, segments->slave,
682 segments->buf, segments->len);
683 } else {
684 result = twsi_write_data(baseaddr, segments->slave,
685 segments->buf, segments->len);
687 if (result) {
688 printk(BIOS_ERR, "%s: error transmitting data\n",
689 __func__);
690 return -1;
694 return 0;