blob: 737dd0a72f78a28a274cf27c27f8ba8895bc99f0 [file] [log] [blame]
Konstantin Porotchkin73cd8812018-02-26 16:06:35 +02001/*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8/* This driver provides I2C support for Marvell A8K and compatible SoCs */
9
10#include <a8k_i2c.h>
11#include <debug.h>
12#include <delay_timer.h>
13#include <errno.h>
14#include <mmio.h>
15#include <mvebu_def.h>
16
17#if LOG_LEVEL >= LOG_LEVEL_VERBOSE
18#define DEBUG_I2C
19#endif
20
21#define CONFIG_SYS_TCLK 250000000
22#define CONFIG_SYS_I2C_SPEED 100000
23#define CONFIG_SYS_I2C_SLAVE 0x0
24#define I2C_TIMEOUT_VALUE 0x500
25#define I2C_MAX_RETRY_CNT 1000
26#define I2C_CMD_WRITE 0x0
27#define I2C_CMD_READ 0x1
28
29#define I2C_DATA_ADDR_7BIT_OFFS 0x1
30#define I2C_DATA_ADDR_7BIT_MASK (0xFF << I2C_DATA_ADDR_7BIT_OFFS)
31
32#define I2C_CONTROL_ACK 0x00000004
33#define I2C_CONTROL_IFLG 0x00000008
34#define I2C_CONTROL_STOP 0x00000010
35#define I2C_CONTROL_START 0x00000020
36#define I2C_CONTROL_TWSIEN 0x00000040
37#define I2C_CONTROL_INTEN 0x00000080
38
39#define I2C_STATUS_START 0x08
40#define I2C_STATUS_REPEATED_START 0x10
41#define I2C_STATUS_ADDR_W_ACK 0x18
42#define I2C_STATUS_DATA_W_ACK 0x28
43#define I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER 0x38
44#define I2C_STATUS_ADDR_R_ACK 0x40
45#define I2C_STATUS_DATA_R_ACK 0x50
46#define I2C_STATUS_DATA_R_NAK 0x58
47#define I2C_STATUS_LOST_ARB_GENERAL_CALL 0x78
48#define I2C_STATUS_IDLE 0xF8
49
50#define I2C_UNSTUCK_TRIGGER 0x1
51#define I2C_UNSTUCK_ONGOING 0x2
52#define I2C_UNSTUCK_ERROR 0x4
53struct marvell_i2c_regs {
54 uint32_t slave_address;
55 uint32_t data;
56 uint32_t control;
57 union {
58 uint32_t status; /* when reading */
59 uint32_t baudrate; /* when writing */
60 } u;
61 uint32_t xtnd_slave_addr;
62 uint32_t reserved[2];
63 uint32_t soft_reset;
64 uint8_t reserved2[0xa0 - 0x20];
65 uint32_t unstuck;
66};
67
68static struct marvell_i2c_regs *base;
69
70static int marvell_i2c_lost_arbitration(uint32_t *status)
71{
72 *status = mmio_read_32((uintptr_t)&base->u.status);
73 if ((*status == I2C_STATUS_LOST_ARB_DATA_ADDR_TRANSFER) ||
74 (*status == I2C_STATUS_LOST_ARB_GENERAL_CALL))
75 return -EAGAIN;
76
77 return 0;
78}
79
80static void marvell_i2c_interrupt_clear(void)
81{
82 uint32_t reg;
83
84 reg = mmio_read_32((uintptr_t)&base->control);
85 reg &= ~(I2C_CONTROL_IFLG);
86 mmio_write_32((uintptr_t)&base->control, reg);
87 /* Wait for 1 us for the clear to take effect */
88 udelay(1);
89}
90
91static int marvell_i2c_interrupt_get(void)
92{
93 uint32_t reg;
94
95 /* get the interrupt flag bit */
96 reg = mmio_read_32((uintptr_t)&base->control);
97 reg &= I2C_CONTROL_IFLG;
98 return reg && I2C_CONTROL_IFLG;
99}
100
101static int marvell_i2c_wait_interrupt(void)
102{
103 uint32_t timeout = 0;
104
105 while (!marvell_i2c_interrupt_get() && (timeout++ < I2C_TIMEOUT_VALUE))
106 ;
107 if (timeout >= I2C_TIMEOUT_VALUE)
108 return -ETIMEDOUT;
109
110 return 0;
111}
112
113static int marvell_i2c_start_bit_set(void)
114{
115 int is_int_flag = 0;
116 uint32_t status;
117
118 if (marvell_i2c_interrupt_get())
119 is_int_flag = 1;
120
121 /* set start bit */
122 mmio_write_32((uintptr_t)&base->control,
123 mmio_read_32((uintptr_t)&base->control) |
124 I2C_CONTROL_START);
125
126 /* in case that the int flag was set before i.e. repeated start bit */
127 if (is_int_flag) {
128 VERBOSE("%s: repeated start Bit\n", __func__);
129 marvell_i2c_interrupt_clear();
130 }
131
132 if (marvell_i2c_wait_interrupt()) {
133 ERROR("Start clear bit timeout\n");
134 return -ETIMEDOUT;
135 }
136
137 /* check that start bit went down */
138 if ((mmio_read_32((uintptr_t)&base->control) &
139 I2C_CONTROL_START) != 0) {
140 ERROR("Start bit didn't went down\n");
141 return -EPERM;
142 }
143
144 /* check the status */
145 if (marvell_i2c_lost_arbitration(&status)) {
146 ERROR("%s - %d: Lost arbitration, got status %x\n",
147 __func__, __LINE__, status);
148 return -EAGAIN;
149 }
150 if ((status != I2C_STATUS_START) &&
151 (status != I2C_STATUS_REPEATED_START)) {
152 ERROR("Got status %x after enable start bit.\n", status);
153 return -EPERM;
154 }
155
156 return 0;
157}
158
159static int marvell_i2c_stop_bit_set(void)
160{
161 int timeout;
162 uint32_t status;
163
164 /* Generate stop bit */
165 mmio_write_32((uintptr_t)&base->control,
166 mmio_read_32((uintptr_t)&base->control) |
167 I2C_CONTROL_STOP);
168 marvell_i2c_interrupt_clear();
169
170 timeout = 0;
171 /* Read control register, check the control stop bit */
172 while ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) &&
173 (timeout++ < I2C_TIMEOUT_VALUE))
174 ;
175 if (timeout >= I2C_TIMEOUT_VALUE) {
176 ERROR("Stop bit didn't went down\n");
177 return -ETIMEDOUT;
178 }
179
180 /* check that stop bit went down */
181 if ((mmio_read_32((uintptr_t)&base->control) & I2C_CONTROL_STOP) != 0) {
182 ERROR("Stop bit didn't went down\n");
183 return -EPERM;
184 }
185
186 /* check the status */
187 if (marvell_i2c_lost_arbitration(&status)) {
188 ERROR("%s - %d: Lost arbitration, got status %x\n",
189 __func__, __LINE__, status);
190 return -EAGAIN;
191 }
192 if (status != I2C_STATUS_IDLE) {
193 ERROR("Got status %x after enable stop bit.\n", status);
194 return -EPERM;
195 }
196
197 return 0;
198}
199
200static int marvell_i2c_address_set(uint8_t chain, int command)
201{
202 uint32_t reg, status;
203
204 reg = (chain << I2C_DATA_ADDR_7BIT_OFFS) & I2C_DATA_ADDR_7BIT_MASK;
205 reg |= command;
206 mmio_write_32((uintptr_t)&base->data, reg);
207 udelay(1);
208
209 marvell_i2c_interrupt_clear();
210
211 if (marvell_i2c_wait_interrupt()) {
212 ERROR("Start clear bit timeout\n");
213 return -ETIMEDOUT;
214 }
215
216 /* check the status */
217 if (marvell_i2c_lost_arbitration(&status)) {
218 ERROR("%s - %d: Lost arbitration, got status %x\n",
219 __func__, __LINE__, status);
220 return -EAGAIN;
221 }
222 if (((status != I2C_STATUS_ADDR_R_ACK) && (command == I2C_CMD_READ)) ||
223 ((status != I2C_STATUS_ADDR_W_ACK) && (command == I2C_CMD_WRITE))) {
224 /* only in debug, since in boot we try to read the SPD
225 * of both DRAM, and we don't want error messages in cas
226 * DIMM doesn't exist.
227 */
228 INFO("%s: ERROR - status %x addr in %s mode.\n", __func__,
229 status, (command == I2C_CMD_WRITE) ? "Write" : "Read");
230 return -EPERM;
231 }
232
233 return 0;
234}
235
236/*
237 * The I2C module contains a clock divider to generate the SCL clock.
238 * This function calculates and sets the <N> and <M> fields in the I2C Baud
239 * Rate Register (t=01) to obtain given 'requested_speed'.
240 * The requested_speed will be equal to:
241 * CONFIG_SYS_TCLK / (10 * (M + 1) * (2 << N))
242 * Where M is the value represented by bits[6:3] and N is the value represented
243 * by bits[2:0] of "I2C Baud Rate Register".
244 * Therefore max M which can be set is 16 (2^4) and max N is 8 (2^3). So the
245 * lowest possible baudrate is:
246 * CONFIG_SYS_TCLK/(10 * (16 +1) * (2 << 8), which equals to:
247 * CONFIG_SYS_TCLK/87040. Assuming that CONFIG_SYS_TCLK=250MHz, the lowest
248 * possible frequency is ~2,872KHz.
249 */
250static unsigned int marvell_i2c_bus_speed_set(unsigned int requested_speed)
251{
252 unsigned int n, m, freq, margin, min_margin = 0xffffffff;
253 unsigned int actual_n = 0, actual_m = 0;
254 int val;
255
256 /* Calculate N and M for the TWSI clock baud rate */
257 for (n = 0; n < 8; n++) {
258 for (m = 0; m < 16; m++) {
259 freq = CONFIG_SYS_TCLK / (10 * (m + 1) * (2 << n));
260 val = requested_speed - freq;
261 margin = (val > 0) ? val : -val;
262
263 if ((freq <= requested_speed) &&
264 (margin < min_margin)) {
265 min_margin = margin;
266 actual_n = n;
267 actual_m = m;
268 }
269 }
270 }
271 VERBOSE("%s: actual_n = %u, actual_m = %u\n",
272 __func__, actual_n, actual_m);
273 /* Set the baud rate */
274 mmio_write_32((uintptr_t)&base->u.baudrate, (actual_m << 3) | actual_n);
275
276 return 0;
277}
278
279#ifdef DEBUG_I2C
280static int marvell_i2c_probe(uint8_t chip)
281{
282 int ret = 0;
283
284 ret = marvell_i2c_start_bit_set();
285 if (ret != 0) {
286 marvell_i2c_stop_bit_set();
287 ERROR("%s - %d: %s", __func__, __LINE__,
288 "marvell_i2c_start_bit_set failed\n");
289 return -EPERM;
290 }
291
292 ret = marvell_i2c_address_set(chip, I2C_CMD_WRITE);
293 if (ret != 0) {
294 marvell_i2c_stop_bit_set();
295 ERROR("%s - %d: %s", __func__, __LINE__,
296 "marvell_i2c_address_set failed\n");
297 return -EPERM;
298 }
299
300 marvell_i2c_stop_bit_set();
301
302 VERBOSE("%s: successful I2C probe\n", __func__);
303
304 return ret;
305}
306#endif
307
308/* regular i2c transaction */
309static int marvell_i2c_data_receive(uint8_t *p_block, uint32_t block_size)
310{
311 uint32_t reg, status, block_size_read = block_size;
312
313 /* Wait for cause interrupt */
314 if (marvell_i2c_wait_interrupt()) {
315 ERROR("Start clear bit timeout\n");
316 return -ETIMEDOUT;
317 }
318 while (block_size_read) {
319 if (block_size_read == 1) {
320 reg = mmio_read_32((uintptr_t)&base->control);
321 reg &= ~(I2C_CONTROL_ACK);
322 mmio_write_32((uintptr_t)&base->control, reg);
323 }
324 marvell_i2c_interrupt_clear();
325
326 if (marvell_i2c_wait_interrupt()) {
327 ERROR("Start clear bit timeout\n");
328 return -ETIMEDOUT;
329 }
330 /* check the status */
331 if (marvell_i2c_lost_arbitration(&status)) {
332 ERROR("%s - %d: Lost arbitration, got status %x\n",
333 __func__, __LINE__, status);
334 return -EAGAIN;
335 }
336 if ((status != I2C_STATUS_DATA_R_ACK) &&
337 (block_size_read != 1)) {
338 ERROR("Status %x in read transaction\n", status);
339 return -EPERM;
340 }
341 if ((status != I2C_STATUS_DATA_R_NAK) &&
342 (block_size_read == 1)) {
343 ERROR("Status %x in Rd Terminate\n", status);
344 return -EPERM;
345 }
346
347 /* read the data */
348 *p_block = (uint8_t) mmio_read_32((uintptr_t)&base->data);
349 VERBOSE("%s: place %d read %x\n", __func__,
350 block_size - block_size_read, *p_block);
351 p_block++;
352 block_size_read--;
353 }
354
355 return 0;
356}
357
358static int marvell_i2c_data_transmit(uint8_t *p_block, uint32_t block_size)
359{
360 uint32_t status, block_size_write = block_size;
361
362 if (marvell_i2c_wait_interrupt()) {
363 ERROR("Start clear bit timeout\n");
364 return -ETIMEDOUT;
365 }
366
367 while (block_size_write) {
368 /* write the data */
369 mmio_write_32((uintptr_t)&base->data, (uint32_t) *p_block);
370 VERBOSE("%s: index = %d, data = %x\n", __func__,
371 block_size - block_size_write, *p_block);
372 p_block++;
373 block_size_write--;
374
375 marvell_i2c_interrupt_clear();
376
377 if (marvell_i2c_wait_interrupt()) {
378 ERROR("Start clear bit timeout\n");
379 return -ETIMEDOUT;
380 }
381
382 /* check the status */
383 if (marvell_i2c_lost_arbitration(&status)) {
384 ERROR("%s - %d: Lost arbitration, got status %x\n",
385 __func__, __LINE__, status);
386 return -EAGAIN;
387 }
388 if (status != I2C_STATUS_DATA_W_ACK) {
389 ERROR("Status %x in write transaction\n", status);
390 return -EPERM;
391 }
392 }
393
394 return 0;
395}
396
397static int marvell_i2c_target_offset_set(uint8_t chip, uint32_t addr, int alen)
398{
399 uint8_t off_block[2];
400 uint32_t off_size;
401
402 if (alen == 2) { /* 2-byte addresses support */
403 off_block[0] = (addr >> 8) & 0xff;
404 off_block[1] = addr & 0xff;
405 off_size = 2;
406 } else { /* 1-byte addresses support */
407 off_block[0] = addr & 0xff;
408 off_size = 1;
409 }
410 VERBOSE("%s: off_size = %x addr1 = %x addr2 = %x\n", __func__,
411 off_size, off_block[0], off_block[1]);
412 return marvell_i2c_data_transmit(off_block, off_size);
413}
414
415static int marvell_i2c_unstuck(int ret)
416{
417 uint32_t v;
418
419 if (ret != -ETIMEDOUT)
420 return ret;
421 VERBOSE("Trying to \"unstuck i2c\"... ");
422 i2c_init(base);
423 mmio_write_32((uintptr_t)&base->unstuck, I2C_UNSTUCK_TRIGGER);
424 do {
425 v = mmio_read_32((uintptr_t)&base->unstuck);
426 } while (v & I2C_UNSTUCK_ONGOING);
427
428 if (v & I2C_UNSTUCK_ERROR) {
429 VERBOSE("failed - soft reset i2c\n");
430 ret = -EPERM;
431 } else {
432 VERBOSE("ok\n");
433 i2c_init(base);
434 ret = -EAGAIN;
435 }
436 return ret;
437}
438
439/*
440 * API Functions
441 */
442void i2c_init(void *i2c_base)
443{
444 /* For I2C speed and slave address, now we do not set them since
445 * we just provide the working speed and slave address in plat_def.h
446 * for i2c_init
447 */
448 base = (struct marvell_i2c_regs *)i2c_base;
449
450 /* Reset the I2C logic */
451 mmio_write_32((uintptr_t)&base->soft_reset, 0);
452
453 udelay(200);
454
455 marvell_i2c_bus_speed_set(CONFIG_SYS_I2C_SPEED);
456
457 /* Enable the I2C and slave */
458 mmio_write_32((uintptr_t)&base->control,
459 I2C_CONTROL_TWSIEN | I2C_CONTROL_ACK);
460
461 /* set the I2C slave address */
462 mmio_write_32((uintptr_t)&base->xtnd_slave_addr, 0);
463 mmio_write_32((uintptr_t)&base->slave_address, CONFIG_SYS_I2C_SLAVE);
464
465 /* unmask I2C interrupt */
466 mmio_write_32((uintptr_t)&base->control,
467 mmio_read_32((uintptr_t)&base->control) |
468 I2C_CONTROL_INTEN);
469
470 udelay(10);
471}
472
473/*
474 * i2c_read: - Read multiple bytes from an i2c device
475 *
476 * The higher level routines take into account that this function is only
477 * called with len < page length of the device (see configuration file)
478 *
479 * @chip: address of the chip which is to be read
480 * @addr: i2c data address within the chip
481 * @alen: length of the i2c data address (1..2 bytes)
482 * @buffer: where to write the data
483 * @len: how much byte do we want to read
484 * @return: 0 in case of success
485 */
486int i2c_read(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
487{
488 int ret = 0;
489 uint32_t counter = 0;
490
491#ifdef DEBUG_I2C
492 marvell_i2c_probe(chip);
493#endif
494
495 do {
496 if (ret != -EAGAIN && ret) {
497 ERROR("i2c transaction failed, after %d retries\n",
498 counter);
499 marvell_i2c_stop_bit_set();
500 return ret;
501 }
502
503 /* wait for 1 us for the interrupt clear to take effect */
504 if (counter > 0)
505 udelay(1);
506 counter++;
507
508 ret = marvell_i2c_start_bit_set();
509 if (ret) {
510 ret = marvell_i2c_unstuck(ret);
511 continue;
512 }
513
514 /* if EEPROM device */
515 if (alen != 0) {
516 ret = marvell_i2c_address_set(chip, I2C_CMD_WRITE);
517 if (ret)
518 continue;
519
520 ret = marvell_i2c_target_offset_set(chip, addr, alen);
521 if (ret)
522 continue;
523 ret = marvell_i2c_start_bit_set();
524 if (ret)
525 continue;
526 }
527
528 ret = marvell_i2c_address_set(chip, I2C_CMD_READ);
529 if (ret)
530 continue;
531
532 ret = marvell_i2c_data_receive(buffer, len);
533 if (ret)
534 continue;
535
536 ret = marvell_i2c_stop_bit_set();
537 } while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT));
538
539 if (counter == I2C_MAX_RETRY_CNT) {
540 ERROR("I2C transactions failed, got EAGAIN %d times\n",
541 I2C_MAX_RETRY_CNT);
542 ret = -EPERM;
543 }
544 mmio_write_32((uintptr_t)&base->control,
545 mmio_read_32((uintptr_t)&base->control) |
546 I2C_CONTROL_ACK);
547
548 udelay(1);
549 return ret;
550}
551
552/*
553 * i2c_write: - Write multiple bytes to an i2c device
554 *
555 * The higher level routines take into account that this function is only
556 * called with len < page length of the device (see configuration file)
557 *
558 * @chip: address of the chip which is to be written
559 * @addr: i2c data address within the chip
560 * @alen: length of the i2c data address (1..2 bytes)
561 * @buffer: where to find the data to be written
562 * @len: how much byte do we want to read
563 * @return: 0 in case of success
564 */
565int i2c_write(uint8_t chip, uint32_t addr, int alen, uint8_t *buffer, int len)
566{
567 int ret = 0;
568 uint32_t counter = 0;
569
570 do {
571 if (ret != -EAGAIN && ret) {
572 ERROR("i2c transaction failed\n");
573 marvell_i2c_stop_bit_set();
574 return ret;
575 }
576 /* wait for 1 us for the interrupt clear to take effect */
577 if (counter > 0)
578 udelay(1);
579 counter++;
580
581 ret = marvell_i2c_start_bit_set();
582 if (ret) {
583 ret = marvell_i2c_unstuck(ret);
584 continue;
585 }
586
587 ret = marvell_i2c_address_set(chip, I2C_CMD_WRITE);
588 if (ret)
589 continue;
590
591 /* if EEPROM device */
592 if (alen != 0) {
593 ret = marvell_i2c_target_offset_set(chip, addr, alen);
594 if (ret)
595 continue;
596 }
597
598 ret = marvell_i2c_data_transmit(buffer, len);
599 if (ret)
600 continue;
601
602 ret = marvell_i2c_stop_bit_set();
603 } while ((ret == -EAGAIN) && (counter < I2C_MAX_RETRY_CNT));
604
605 if (counter == I2C_MAX_RETRY_CNT) {
606 ERROR("I2C transactions failed, got EAGAIN %d times\n",
607 I2C_MAX_RETRY_CNT);
608 ret = -EPERM;
609 }
610
611 udelay(1);
612 return ret;
613}