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