]>
Commit | Line | Data |
---|---|---|
5c2c3e8b SG |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | /* | |
3 | * Copyright (C) 2018 Marvell International Ltd. | |
4 | */ | |
5 | ||
5c2c3e8b SG |
6 | #include <clk.h> |
7 | #include <dm.h> | |
8 | #include <i2c.h> | |
af03bde0 | 9 | #include <time.h> |
5c2c3e8b SG |
10 | #include <asm/io.h> |
11 | #include <linux/bitfield.h> | |
12 | #include <linux/compat.h> | |
13 | #include <linux/delay.h> | |
14 | ||
15 | #define TWSI_SW_TWSI 0x00 | |
16 | #define TWSI_TWSI_SW 0x08 | |
17 | #define TWSI_INT 0x10 | |
18 | #define TWSI_SW_TWSI_EXT 0x18 | |
19 | ||
20 | #define TWSI_SW_DATA_MASK GENMASK_ULL(31, 0) | |
21 | #define TWSI_SW_EOP_IA_MASK GENMASK_ULL(34, 32) | |
22 | #define TWSI_SW_IA_MASK GENMASK_ULL(39, 35) | |
23 | #define TWSI_SW_ADDR_MASK GENMASK_ULL(49, 40) | |
24 | #define TWSI_SW_SCR_MASK GENMASK_ULL(51, 50) | |
25 | #define TWSI_SW_SIZE_MASK GENMASK_ULL(54, 52) | |
26 | #define TWSI_SW_SOVR BIT_ULL(55) | |
27 | #define TWSI_SW_R BIT_ULL(56) | |
28 | #define TWSI_SW_OP_MASK GENMASK_ULL(60, 57) | |
29 | #define TWSI_SW_EIA GENMASK_ULL(61) | |
30 | #define TWSI_SW_SLONLY BIT_ULL(62) | |
31 | #define TWSI_SW_V BIT_ULL(63) | |
32 | ||
33 | #define TWSI_INT_SDA_OVR BIT_ULL(8) | |
34 | #define TWSI_INT_SCL_OVR BIT_ULL(9) | |
35 | #define TWSI_INT_SDA BIT_ULL(10) | |
36 | #define TWSI_INT_SCL BIT_ULL(11) | |
37 | ||
38 | enum { | |
39 | TWSI_OP_WRITE = 0, | |
40 | TWSI_OP_READ = 1, | |
41 | }; | |
42 | ||
43 | enum { | |
44 | TWSI_EOP_SLAVE_ADDR = 0, | |
45 | TWSI_EOP_CLK_CTL = 3, | |
46 | TWSI_SW_EOP_IA = 6, | |
47 | }; | |
48 | ||
49 | enum { | |
50 | TWSI_SLAVEADD = 0, | |
51 | TWSI_DATA = 1, | |
52 | TWSI_CTL = 2, | |
53 | TWSI_CLKCTL = 3, | |
54 | TWSI_STAT = 3, | |
55 | TWSI_SLAVEADD_EXT = 4, | |
56 | TWSI_RST = 7, | |
57 | }; | |
58 | ||
59 | enum { | |
60 | TWSI_CTL_AAK = BIT(2), | |
61 | TWSI_CTL_IFLG = BIT(3), | |
62 | TWSI_CTL_STP = BIT(4), | |
63 | TWSI_CTL_STA = BIT(5), | |
64 | TWSI_CTL_ENAB = BIT(6), | |
65 | TWSI_CTL_CE = BIT(7), | |
66 | }; | |
67 | ||
68 | /* | |
69 | * Internal errors. When debugging is enabled, the driver will report the | |
70 | * error number and the user / developer can check the table below for the | |
71 | * detailed error description. | |
72 | */ | |
73 | enum { | |
74 | /** Bus error */ | |
75 | TWSI_STAT_BUS_ERROR = 0x00, | |
76 | /** Start condition transmitted */ | |
77 | TWSI_STAT_START = 0x08, | |
78 | /** Repeat start condition transmitted */ | |
79 | TWSI_STAT_RSTART = 0x10, | |
80 | /** Address + write bit transmitted, ACK received */ | |
81 | TWSI_STAT_TXADDR_ACK = 0x18, | |
82 | /** Address + write bit transmitted, /ACK received */ | |
83 | TWSI_STAT_TXADDR_NAK = 0x20, | |
84 | /** Data byte transmitted in master mode, ACK received */ | |
85 | TWSI_STAT_TXDATA_ACK = 0x28, | |
86 | /** Data byte transmitted in master mode, ACK received */ | |
87 | TWSI_STAT_TXDATA_NAK = 0x30, | |
88 | /** Arbitration lost in address or data byte */ | |
89 | TWSI_STAT_TX_ARB_LOST = 0x38, | |
90 | /** Address + read bit transmitted, ACK received */ | |
91 | TWSI_STAT_RXADDR_ACK = 0x40, | |
92 | /** Address + read bit transmitted, /ACK received */ | |
93 | TWSI_STAT_RXADDR_NAK = 0x48, | |
94 | /** Data byte received in master mode, ACK transmitted */ | |
95 | TWSI_STAT_RXDATA_ACK_SENT = 0x50, | |
96 | /** Data byte received, NACK transmitted */ | |
97 | TWSI_STAT_RXDATA_NAK_SENT = 0x58, | |
98 | /** Slave address received, sent ACK */ | |
99 | TWSI_STAT_SLAVE_RXADDR_ACK = 0x60, | |
100 | /** | |
101 | * Arbitration lost in address as master, slave address + write bit | |
102 | * received, ACK transmitted | |
103 | */ | |
104 | TWSI_STAT_TX_ACK_ARB_LOST = 0x68, | |
105 | /** General call address received, ACK transmitted */ | |
106 | TWSI_STAT_RX_GEN_ADDR_ACK = 0x70, | |
107 | /** | |
108 | * Arbitration lost in address as master, general call address | |
109 | * received, ACK transmitted | |
110 | */ | |
111 | TWSI_STAT_RX_GEN_ADDR_ARB_LOST = 0x78, | |
112 | /** Data byte received after slave address received, ACK transmitted */ | |
113 | TWSI_STAT_SLAVE_RXDATA_ACK = 0x80, | |
114 | /** Data byte received after slave address received, /ACK transmitted */ | |
115 | TWSI_STAT_SLAVE_RXDATA_NAK = 0x88, | |
116 | /** | |
117 | * Data byte received after general call address received, ACK | |
118 | * transmitted | |
119 | */ | |
120 | TWSI_STAT_GEN_RXADDR_ACK = 0x90, | |
121 | /** | |
122 | * Data byte received after general call address received, /ACK | |
123 | * transmitted | |
124 | */ | |
125 | TWSI_STAT_GEN_RXADDR_NAK = 0x98, | |
126 | /** STOP or repeated START condition received in slave mode */ | |
127 | TWSI_STAT_STOP_MULTI_START = 0xa0, | |
128 | /** Slave address + read bit received, ACK transmitted */ | |
129 | TWSI_STAT_SLAVE_RXADDR2_ACK = 0xa8, | |
130 | /** | |
131 | * Arbitration lost in address as master, slave address + read bit | |
132 | * received, ACK transmitted | |
133 | */ | |
134 | TWSI_STAT_RXDATA_ACK_ARB_LOST = 0xb0, | |
135 | /** Data byte transmitted in slave mode, ACK received */ | |
136 | TWSI_STAT_SLAVE_TXDATA_ACK = 0xb8, | |
137 | /** Data byte transmitted in slave mode, /ACK received */ | |
138 | TWSI_STAT_SLAVE_TXDATA_NAK = 0xc0, | |
139 | /** Last byte transmitted in slave mode, ACK received */ | |
140 | TWSI_STAT_SLAVE_TXDATA_END_ACK = 0xc8, | |
141 | /** Second address byte + write bit transmitted, ACK received */ | |
142 | TWSI_STAT_TXADDR2DATA_ACK = 0xd0, | |
143 | /** Second address byte + write bit transmitted, /ACK received */ | |
144 | TWSI_STAT_TXADDR2DATA_NAK = 0xd8, | |
145 | /** No relevant status information */ | |
146 | TWSI_STAT_IDLE = 0xf8 | |
147 | }; | |
148 | ||
6e7df1d1 | 149 | #define CFG_SYS_I2C_OCTEON_SLAVE_ADDR 0x77 |
5c2c3e8b SG |
150 | |
151 | enum { | |
152 | PROBE_PCI = 0, /* PCI based probing */ | |
153 | PROBE_DT, /* DT based probing */ | |
154 | }; | |
155 | ||
156 | enum { | |
157 | CLK_METHOD_OCTEON = 0, | |
158 | CLK_METHOD_OCTEONTX2, | |
159 | }; | |
160 | ||
161 | /** | |
162 | * struct octeon_i2c_data - SoC specific data of this driver | |
163 | * | |
164 | * @probe: Probing of this SoC (DT vs PCI) | |
165 | * @reg_offs: Register offset | |
166 | * @thp: THP define for divider calculation | |
167 | * @clk_method: Clock calculation method | |
168 | */ | |
169 | struct octeon_i2c_data { | |
170 | int probe; | |
171 | u32 reg_offs; | |
172 | int thp; | |
173 | int clk_method; | |
174 | }; | |
175 | ||
176 | /** | |
177 | * struct octeon_twsi - Private data of this driver | |
178 | * | |
179 | * @base: Base address of i2c registers | |
180 | * @data: Pointer to SoC specific data struct | |
181 | */ | |
182 | struct octeon_twsi { | |
183 | void __iomem *base; | |
184 | const struct octeon_i2c_data *data; | |
185 | struct clk clk; | |
186 | }; | |
187 | ||
188 | static void twsi_unblock(void *base); | |
189 | static int twsi_stop(void *base); | |
190 | ||
191 | /** | |
192 | * Returns true if we lost arbitration | |
193 | * | |
194 | * @code status code | |
195 | * @final_read true if this is the final read operation | |
185f812c | 196 | * Return: true if arbitration has been lost, false if it hasn't been lost. |
5c2c3e8b SG |
197 | */ |
198 | static int twsi_i2c_lost_arb(u8 code, int final_read) | |
199 | { | |
200 | switch (code) { | |
201 | case TWSI_STAT_TX_ARB_LOST: | |
202 | case TWSI_STAT_TX_ACK_ARB_LOST: | |
203 | case TWSI_STAT_RX_GEN_ADDR_ARB_LOST: | |
204 | case TWSI_STAT_RXDATA_ACK_ARB_LOST: | |
205 | /* Arbitration lost */ | |
206 | return -EAGAIN; | |
207 | ||
208 | case TWSI_STAT_SLAVE_RXADDR_ACK: | |
209 | case TWSI_STAT_RX_GEN_ADDR_ACK: | |
210 | case TWSI_STAT_GEN_RXADDR_ACK: | |
211 | case TWSI_STAT_GEN_RXADDR_NAK: | |
212 | /* Being addressed as slave, should back off and listen */ | |
213 | return -EIO; | |
214 | ||
215 | case TWSI_STAT_SLAVE_RXDATA_ACK: | |
216 | case TWSI_STAT_SLAVE_RXDATA_NAK: | |
217 | case TWSI_STAT_STOP_MULTI_START: | |
218 | case TWSI_STAT_SLAVE_RXADDR2_ACK: | |
219 | case TWSI_STAT_SLAVE_TXDATA_ACK: | |
220 | case TWSI_STAT_SLAVE_TXDATA_NAK: | |
221 | case TWSI_STAT_SLAVE_TXDATA_END_ACK: | |
222 | /* Core busy as slave */ | |
223 | return -EIO; | |
224 | ||
225 | case TWSI_STAT_RXDATA_ACK_SENT: | |
226 | /* Ack allowed on pre-terminal bytes only */ | |
227 | if (!final_read) | |
228 | return 0; | |
229 | return -EAGAIN; | |
230 | ||
231 | case TWSI_STAT_RXDATA_NAK_SENT: | |
232 | /* NAK allowed on terminal byte only */ | |
233 | if (!final_read) | |
234 | return 0; | |
235 | return -EAGAIN; | |
236 | ||
237 | case TWSI_STAT_TXDATA_NAK: | |
238 | case TWSI_STAT_TXADDR_NAK: | |
239 | case TWSI_STAT_RXADDR_NAK: | |
240 | case TWSI_STAT_TXADDR2DATA_NAK: | |
241 | return -EAGAIN; | |
242 | } | |
243 | ||
244 | return 0; | |
245 | } | |
246 | ||
247 | /** | |
248 | * Writes to the MIO_TWS(0..5)_SW_TWSI register | |
249 | * | |
250 | * @base Base address of i2c registers | |
251 | * @val value to write | |
185f812c | 252 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
253 | */ |
254 | static u64 twsi_write_sw(void __iomem *base, u64 val) | |
255 | { | |
256 | unsigned long start = get_timer(0); | |
257 | ||
258 | val &= ~TWSI_SW_R; | |
259 | val |= TWSI_SW_V; | |
260 | ||
261 | debug("%s(%p, 0x%llx)\n", __func__, base, val); | |
262 | writeq(val, base + TWSI_SW_TWSI); | |
263 | do { | |
264 | val = readq(base + TWSI_SW_TWSI); | |
265 | } while ((val & TWSI_SW_V) && (get_timer(start) < 50)); | |
266 | ||
267 | if (val & TWSI_SW_V) | |
268 | debug("%s: timed out\n", __func__); | |
269 | return val; | |
270 | } | |
271 | ||
272 | /** | |
273 | * Reads the MIO_TWS(0..5)_SW_TWSI register | |
274 | * | |
275 | * @base Base address of i2c registers | |
276 | * @val value for eia and op, etc. to read | |
185f812c | 277 | * Return: value of the register |
5c2c3e8b SG |
278 | */ |
279 | static u64 twsi_read_sw(void __iomem *base, u64 val) | |
280 | { | |
281 | unsigned long start = get_timer(0); | |
282 | ||
283 | val |= TWSI_SW_R | TWSI_SW_V; | |
284 | ||
285 | debug("%s(%p, 0x%llx)\n", __func__, base, val); | |
286 | writeq(val, base + TWSI_SW_TWSI); | |
287 | ||
288 | do { | |
289 | val = readq(base + TWSI_SW_TWSI); | |
290 | } while ((val & TWSI_SW_V) && (get_timer(start) < 50)); | |
291 | ||
292 | if (val & TWSI_SW_V) | |
293 | debug("%s: Error writing 0x%llx\n", __func__, val); | |
294 | ||
295 | debug("%s: Returning 0x%llx\n", __func__, val); | |
296 | return val; | |
297 | } | |
298 | ||
299 | /** | |
300 | * Write control register | |
301 | * | |
302 | * @base Base address for i2c registers | |
303 | * @data data to write | |
304 | */ | |
305 | static void twsi_write_ctl(void __iomem *base, u8 data) | |
306 | { | |
307 | u64 val; | |
308 | ||
309 | debug("%s(%p, 0x%x)\n", __func__, base, data); | |
310 | val = data | FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_CTL) | | |
311 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA); | |
312 | twsi_write_sw(base, val); | |
313 | } | |
314 | ||
315 | /** | |
316 | * Reads the TWSI Control Register | |
317 | * | |
318 | * @base Base address for i2c | |
185f812c | 319 | * Return: 8-bit TWSI control register |
5c2c3e8b SG |
320 | */ |
321 | static u8 twsi_read_ctl(void __iomem *base) | |
322 | { | |
323 | u64 val; | |
324 | ||
325 | val = FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_CTL) | | |
326 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA); | |
327 | val = twsi_read_sw(base, val); | |
328 | ||
329 | debug("%s(%p): 0x%x\n", __func__, base, (u8)val); | |
330 | return (u8)val; | |
331 | } | |
332 | ||
333 | /** | |
334 | * Read i2c status register | |
335 | * | |
336 | * @base Base address of i2c registers | |
185f812c | 337 | * Return: value of status register |
5c2c3e8b SG |
338 | */ |
339 | static u8 twsi_read_status(void __iomem *base) | |
340 | { | |
341 | u64 val; | |
342 | ||
343 | val = FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_STAT) | | |
344 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA); | |
345 | ||
346 | return twsi_read_sw(base, val); | |
347 | } | |
348 | ||
349 | /** | |
350 | * Waits for an i2c operation to complete | |
351 | * | |
352 | * @param base Base address of registers | |
185f812c | 353 | * Return: 0 for success, 1 if timeout |
5c2c3e8b SG |
354 | */ |
355 | static int twsi_wait(void __iomem *base) | |
356 | { | |
357 | unsigned long start = get_timer(0); | |
358 | u8 twsi_ctl; | |
359 | ||
360 | debug("%s(%p)\n", __func__, base); | |
361 | do { | |
362 | twsi_ctl = twsi_read_ctl(base); | |
363 | twsi_ctl &= TWSI_CTL_IFLG; | |
364 | } while (!twsi_ctl && get_timer(start) < 50); | |
365 | ||
366 | debug(" return: %u\n", !twsi_ctl); | |
367 | return !twsi_ctl; | |
368 | } | |
369 | ||
370 | /** | |
371 | * Unsticks the i2c bus | |
372 | * | |
373 | * @base base address of registers | |
374 | */ | |
375 | static int twsi_start_unstick(void __iomem *base) | |
376 | { | |
377 | twsi_stop(base); | |
378 | twsi_unblock(base); | |
379 | ||
380 | return 0; | |
381 | } | |
382 | ||
383 | /** | |
384 | * Sends an i2c start condition | |
385 | * | |
386 | * @base base address of registers | |
185f812c | 387 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
388 | */ |
389 | static int twsi_start(void __iomem *base) | |
390 | { | |
391 | int ret; | |
392 | u8 stat; | |
393 | ||
394 | debug("%s(%p)\n", __func__, base); | |
395 | twsi_write_ctl(base, TWSI_CTL_STA | TWSI_CTL_ENAB); | |
396 | ret = twsi_wait(base); | |
397 | if (ret) { | |
398 | stat = twsi_read_status(base); | |
399 | debug("%s: ret: 0x%x, status: 0x%x\n", __func__, ret, stat); | |
400 | switch (stat) { | |
401 | case TWSI_STAT_START: | |
402 | case TWSI_STAT_RSTART: | |
403 | return 0; | |
404 | case TWSI_STAT_RXADDR_ACK: | |
405 | default: | |
406 | return twsi_start_unstick(base); | |
407 | } | |
408 | } | |
409 | ||
410 | debug("%s: success\n", __func__); | |
411 | return 0; | |
412 | } | |
413 | ||
414 | /** | |
415 | * Sends an i2c stop condition | |
416 | * | |
417 | * @base register base address | |
185f812c | 418 | * Return: 0 for success, -1 if error |
5c2c3e8b SG |
419 | */ |
420 | static int twsi_stop(void __iomem *base) | |
421 | { | |
422 | u8 stat; | |
423 | ||
424 | twsi_write_ctl(base, TWSI_CTL_STP | TWSI_CTL_ENAB); | |
425 | ||
426 | stat = twsi_read_status(base); | |
427 | if (stat != TWSI_STAT_IDLE) { | |
428 | debug("%s: Bad status on bus@%p\n", __func__, base); | |
429 | return -1; | |
430 | } | |
431 | ||
432 | return 0; | |
433 | } | |
434 | ||
435 | /** | |
436 | * Writes data to the i2c bus | |
437 | * | |
438 | * @base register base address | |
439 | * @slave_addr address of slave to write to | |
440 | * @buffer Pointer to buffer to write | |
441 | * @length Number of bytes in buffer to write | |
185f812c | 442 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
443 | */ |
444 | static int twsi_write_data(void __iomem *base, u8 slave_addr, | |
445 | u8 *buffer, unsigned int length) | |
446 | { | |
447 | unsigned int curr = 0; | |
448 | u64 val; | |
449 | int ret; | |
450 | ||
451 | debug("%s(%p, 0x%x, %p, 0x%x)\n", __func__, base, slave_addr, | |
452 | buffer, length); | |
453 | ret = twsi_start(base); | |
454 | if (ret) { | |
455 | debug("%s: Could not start BUS transaction\n", __func__); | |
456 | return -1; | |
457 | } | |
458 | ||
459 | ret = twsi_wait(base); | |
460 | if (ret) { | |
461 | debug("%s: wait failed\n", __func__); | |
462 | return ret; | |
463 | } | |
464 | ||
465 | val = (u32)(slave_addr << 1) | TWSI_OP_WRITE | | |
466 | FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_DATA) | | |
467 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA); | |
468 | twsi_write_sw(base, val); | |
469 | twsi_write_ctl(base, TWSI_CTL_ENAB); | |
470 | ||
471 | debug("%s: Waiting\n", __func__); | |
472 | ret = twsi_wait(base); | |
473 | if (ret) { | |
474 | debug("%s: Timed out writing slave address 0x%x to target\n", | |
475 | __func__, slave_addr); | |
476 | return ret; | |
477 | } | |
478 | ||
479 | ret = twsi_read_status(base); | |
480 | debug("%s: status: 0x%x\n", __func__, ret); | |
481 | if (ret != TWSI_STAT_TXADDR_ACK) { | |
482 | debug("%s: status: 0x%x\n", __func__, ret); | |
483 | twsi_stop(base); | |
484 | return twsi_i2c_lost_arb(ret, 0); | |
485 | } | |
486 | ||
487 | while (curr < length) { | |
488 | val = buffer[curr++] | | |
489 | FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_DATA) | | |
490 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA); | |
491 | twsi_write_sw(base, val); | |
492 | twsi_write_ctl(base, TWSI_CTL_ENAB); | |
493 | ||
494 | debug("%s: Writing 0x%llx\n", __func__, val); | |
495 | ||
496 | ret = twsi_wait(base); | |
497 | if (ret) { | |
498 | debug("%s: Timed out writing data to 0x%x\n", | |
499 | __func__, slave_addr); | |
500 | return ret; | |
501 | } | |
502 | ret = twsi_read_status(base); | |
503 | debug("%s: status: 0x%x\n", __func__, ret); | |
504 | } | |
505 | ||
506 | debug("%s: Stopping\n", __func__); | |
507 | return twsi_stop(base); | |
508 | } | |
509 | ||
510 | /** | |
511 | * Manually clear the I2C bus and send a stop | |
512 | * | |
513 | * @base register base address | |
514 | */ | |
515 | static void twsi_unblock(void __iomem *base) | |
516 | { | |
517 | int i; | |
518 | ||
519 | for (i = 0; i < 9; i++) { | |
520 | writeq(0, base + TWSI_INT); | |
521 | udelay(5); | |
522 | writeq(TWSI_INT_SCL_OVR, base + TWSI_INT); | |
523 | udelay(5); | |
524 | } | |
525 | writeq(TWSI_INT_SCL_OVR | TWSI_INT_SDA_OVR, base + TWSI_INT); | |
526 | udelay(5); | |
527 | writeq(TWSI_INT_SDA_OVR, base + TWSI_INT); | |
528 | udelay(5); | |
529 | writeq(0, base + TWSI_INT); | |
530 | udelay(5); | |
531 | } | |
532 | ||
533 | /** | |
534 | * Performs a read transaction on the i2c bus | |
535 | * | |
536 | * @base Base address of twsi registers | |
537 | * @slave_addr i2c bus address to read from | |
538 | * @buffer buffer to read into | |
539 | * @length number of bytes to read | |
185f812c | 540 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
541 | */ |
542 | static int twsi_read_data(void __iomem *base, u8 slave_addr, | |
543 | u8 *buffer, unsigned int length) | |
544 | { | |
545 | unsigned int curr = 0; | |
546 | u64 val; | |
547 | int ret; | |
548 | ||
549 | debug("%s(%p, 0x%x, %p, %u)\n", __func__, base, slave_addr, | |
550 | buffer, length); | |
551 | ret = twsi_start(base); | |
552 | if (ret) { | |
553 | debug("%s: start failed\n", __func__); | |
554 | return ret; | |
555 | } | |
556 | ||
557 | ret = twsi_wait(base); | |
558 | if (ret) { | |
559 | debug("%s: wait failed\n", __func__); | |
560 | return ret; | |
561 | } | |
562 | ||
563 | val = (u32)(slave_addr << 1) | TWSI_OP_READ | | |
564 | FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_DATA) | | |
565 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA); | |
566 | twsi_write_sw(base, val); | |
567 | twsi_write_ctl(base, TWSI_CTL_ENAB); | |
568 | ||
569 | ret = twsi_wait(base); | |
570 | if (ret) { | |
571 | debug("%s: waiting for sending addr failed\n", __func__); | |
572 | return ret; | |
573 | } | |
574 | ||
575 | ret = twsi_read_status(base); | |
576 | debug("%s: status: 0x%x\n", __func__, ret); | |
577 | if (ret != TWSI_STAT_RXADDR_ACK) { | |
578 | debug("%s: status: 0x%x\n", __func__, ret); | |
579 | twsi_stop(base); | |
580 | return twsi_i2c_lost_arb(ret, 0); | |
581 | } | |
582 | ||
583 | while (curr < length) { | |
584 | twsi_write_ctl(base, TWSI_CTL_ENAB | | |
585 | ((curr < length - 1) ? TWSI_CTL_AAK : 0)); | |
586 | ||
587 | ret = twsi_wait(base); | |
588 | if (ret) { | |
589 | debug("%s: waiting for data failed\n", __func__); | |
590 | return ret; | |
591 | } | |
592 | ||
593 | val = twsi_read_sw(base, val); | |
594 | buffer[curr++] = (u8)val; | |
595 | } | |
596 | ||
597 | twsi_stop(base); | |
598 | ||
599 | return 0; | |
600 | } | |
601 | ||
602 | /** | |
603 | * Calculate the divisor values | |
604 | * | |
605 | * @speed Speed to set | |
606 | * @m_div Pointer to M divisor | |
607 | * @n_div Pointer to N divisor | |
185f812c | 608 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
609 | */ |
610 | static void twsi_calc_div(struct udevice *bus, ulong sclk, unsigned int speed, | |
611 | int *m_div, int *n_div) | |
612 | { | |
613 | struct octeon_twsi *twsi = dev_get_priv(bus); | |
614 | int thp = twsi->data->thp; | |
615 | int tclk, fsamp; | |
616 | int ndiv, mdiv; | |
617 | ||
618 | if (twsi->data->clk_method == CLK_METHOD_OCTEON) { | |
619 | tclk = sclk / (2 * (thp + 1)); | |
620 | } else { | |
621 | /* Refclk src in mode register defaults to 100MHz clock */ | |
622 | sclk = 100000000; /* 100 Mhz */ | |
623 | tclk = sclk / (thp + 2); | |
624 | } | |
625 | debug("%s( io_clock %lu tclk %u)\n", __func__, sclk, tclk); | |
626 | ||
627 | /* | |
628 | * Compute the clocks M divider: | |
629 | * | |
630 | * TWSI freq = (core freq) / (10 x (M+1) x 2 * (thp+1) x 2^N) | |
631 | * M = ((core freq) / (10 x (TWSI freq) x 2 * (thp+1) x 2^N)) - 1 | |
632 | * | |
633 | * For OcteonTX2 - | |
634 | * TWSI freq = (core freq) / (10 x (M+1) x (thp+2) x 2^N) | |
635 | * M = ((core freq) / (10 x (TWSI freq) x (thp+2) x 2^N)) - 1 | |
636 | */ | |
637 | for (ndiv = 0; ndiv < 8; ndiv++) { | |
638 | fsamp = tclk / (1 << ndiv); | |
639 | mdiv = fsamp / speed / 10; | |
640 | mdiv -= 1; | |
641 | if (mdiv < 16) | |
642 | break; | |
643 | } | |
644 | ||
645 | *m_div = mdiv; | |
646 | *n_div = ndiv; | |
647 | } | |
648 | ||
649 | /** | |
650 | * Init I2C controller | |
651 | * | |
652 | * @base Base address of twsi registers | |
653 | * @slave_addr I2C slave address to configure this controller to | |
185f812c | 654 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
655 | */ |
656 | static int twsi_init(void __iomem *base, int slaveaddr) | |
657 | { | |
658 | u64 val; | |
659 | ||
660 | debug("%s (%p, 0x%x)\n", __func__, base, slaveaddr); | |
661 | ||
662 | val = slaveaddr << 1 | | |
663 | FIELD_PREP(TWSI_SW_EOP_IA_MASK, 0) | | |
664 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA) | | |
665 | TWSI_SW_V; | |
666 | twsi_write_sw(base, val); | |
667 | ||
668 | /* Set slave address */ | |
669 | val = slaveaddr | | |
670 | FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_EOP_SLAVE_ADDR) | | |
671 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA) | | |
672 | TWSI_SW_V; | |
673 | twsi_write_sw(base, val); | |
674 | ||
675 | return 0; | |
676 | } | |
677 | ||
678 | /** | |
679 | * Transfers data over the i2c bus | |
680 | * | |
681 | * @bus i2c bus to transfer data over | |
682 | * @msg Array of i2c messages | |
683 | * @nmsgs Number of messages to send/receive | |
185f812c | 684 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
685 | */ |
686 | static int octeon_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, | |
687 | int nmsgs) | |
688 | { | |
689 | struct octeon_twsi *twsi = dev_get_priv(bus); | |
690 | int ret; | |
691 | int i; | |
692 | ||
693 | debug("%s: %d messages\n", __func__, nmsgs); | |
694 | for (i = 0; i < nmsgs; i++, msg++) { | |
695 | debug("%s: chip=0x%x, len=0x%x\n", __func__, msg->addr, | |
696 | msg->len); | |
697 | ||
698 | if (msg->flags & I2C_M_RD) { | |
699 | debug("%s: Reading data\n", __func__); | |
700 | ret = twsi_read_data(twsi->base, msg->addr, | |
701 | msg->buf, msg->len); | |
702 | } else { | |
703 | debug("%s: Writing data\n", __func__); | |
704 | ret = twsi_write_data(twsi->base, msg->addr, | |
705 | msg->buf, msg->len); | |
706 | } | |
707 | if (ret) { | |
708 | debug("%s: error sending\n", __func__); | |
709 | return -EREMOTEIO; | |
710 | } | |
711 | } | |
712 | ||
713 | return 0; | |
714 | } | |
715 | ||
716 | /** | |
717 | * Set I2C bus speed | |
718 | * | |
719 | * @bus i2c bus to transfer data over | |
720 | * @speed Speed in Hz to set | |
185f812c | 721 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
722 | */ |
723 | static int octeon_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) | |
724 | { | |
725 | struct octeon_twsi *twsi = dev_get_priv(bus); | |
726 | int m_div, n_div; | |
727 | ulong clk_rate; | |
728 | u64 val; | |
729 | ||
730 | debug("%s(%p, %u)\n", __func__, bus, speed); | |
731 | ||
732 | clk_rate = clk_get_rate(&twsi->clk); | |
733 | if (IS_ERR_VALUE(clk_rate)) | |
734 | return -EINVAL; | |
735 | ||
736 | twsi_calc_div(bus, clk_rate, speed, &m_div, &n_div); | |
737 | if (m_div >= 16) | |
738 | return -1; | |
739 | ||
740 | val = (u32)(((m_div & 0xf) << 3) | ((n_div & 0x7) << 0)) | | |
741 | FIELD_PREP(TWSI_SW_EOP_IA_MASK, TWSI_CLKCTL) | | |
742 | FIELD_PREP(TWSI_SW_OP_MASK, TWSI_SW_EOP_IA) | | |
743 | TWSI_SW_V; | |
744 | /* Only init non-slave ports */ | |
745 | writeq(val, twsi->base + TWSI_SW_TWSI); | |
746 | ||
747 | debug("%s: Wrote 0x%llx to sw_twsi\n", __func__, val); | |
748 | return 0; | |
749 | } | |
750 | ||
af03bde0 SR |
751 | static const struct octeon_i2c_data i2c_octeon_data = { |
752 | .probe = PROBE_DT, | |
753 | .reg_offs = 0x0000, | |
754 | .thp = 3, | |
755 | .clk_method = CLK_METHOD_OCTEON, | |
756 | }; | |
757 | ||
758 | static const struct octeon_i2c_data i2c_octeontx_data = { | |
759 | .probe = PROBE_PCI, | |
760 | .reg_offs = 0x1000, | |
761 | .thp = 24, | |
762 | .clk_method = CLK_METHOD_OCTEON, | |
763 | }; | |
764 | ||
765 | static const struct octeon_i2c_data i2c_octeontx2_data = { | |
766 | .probe = PROBE_PCI, | |
767 | .reg_offs = 0x1000, | |
768 | .thp = 3, | |
769 | .clk_method = CLK_METHOD_OCTEONTX2, | |
770 | }; | |
771 | ||
5c2c3e8b SG |
772 | /** |
773 | * Driver probe function | |
774 | * | |
775 | * @dev I2C device to probe | |
185f812c | 776 | * Return: 0 for success, otherwise error |
5c2c3e8b SG |
777 | */ |
778 | static int octeon_i2c_probe(struct udevice *dev) | |
779 | { | |
780 | struct octeon_twsi *twsi = dev_get_priv(dev); | |
781 | u32 i2c_slave_addr; | |
782 | int ret; | |
783 | ||
af03bde0 SR |
784 | /* Octeon TX2 needs a different data struct */ |
785 | if (device_is_compatible(dev, "cavium,thunderx-i2c")) | |
786 | dev->driver_data = (long)&i2c_octeontx2_data; | |
787 | ||
5c2c3e8b SG |
788 | twsi->data = (const struct octeon_i2c_data *)dev_get_driver_data(dev); |
789 | ||
790 | if (twsi->data->probe == PROBE_PCI) { | |
791 | pci_dev_t bdf = dm_pci_get_bdf(dev); | |
792 | ||
793 | debug("TWSI PCI device: %x\n", bdf); | |
5c2c3e8b | 794 | |
2635e3b5 | 795 | twsi->base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0, 0, 0, PCI_REGION_TYPE, |
5c2c3e8b SG |
796 | PCI_REGION_MEM); |
797 | } else { | |
798 | twsi->base = dev_remap_addr(dev); | |
799 | } | |
800 | twsi->base += twsi->data->reg_offs; | |
801 | ||
802 | i2c_slave_addr = dev_read_u32_default(dev, "i2c-sda-hold-time-ns", | |
6e7df1d1 | 803 | CFG_SYS_I2C_OCTEON_SLAVE_ADDR); |
5c2c3e8b SG |
804 | |
805 | ret = clk_get_by_index(dev, 0, &twsi->clk); | |
806 | if (ret < 0) | |
807 | return ret; | |
808 | ||
809 | ret = clk_enable(&twsi->clk); | |
810 | if (ret) | |
811 | return ret; | |
812 | ||
8b85dfc6 | 813 | debug("TWSI bus %d at %p\n", dev_seq(dev), twsi->base); |
5c2c3e8b SG |
814 | |
815 | /* Start with standard speed, real speed set via DT or cmd */ | |
816 | return twsi_init(twsi->base, i2c_slave_addr); | |
817 | } | |
818 | ||
819 | static const struct dm_i2c_ops octeon_i2c_ops = { | |
820 | .xfer = octeon_i2c_xfer, | |
821 | .set_bus_speed = octeon_i2c_set_bus_speed, | |
822 | }; | |
823 | ||
5c2c3e8b SG |
824 | static const struct udevice_id octeon_i2c_ids[] = { |
825 | { .compatible = "cavium,octeon-7890-twsi", | |
826 | .data = (ulong)&i2c_octeon_data }, | |
827 | { .compatible = "cavium,thunder-8890-twsi", | |
828 | .data = (ulong)&i2c_octeontx_data }, | |
5c2c3e8b SG |
829 | { } |
830 | }; | |
831 | ||
832 | U_BOOT_DRIVER(octeon_pci_twsi) = { | |
833 | .name = "i2c_octeon", | |
834 | .id = UCLASS_I2C, | |
835 | .of_match = octeon_i2c_ids, | |
836 | .probe = octeon_i2c_probe, | |
41575d8e | 837 | .priv_auto = sizeof(struct octeon_twsi), |
5c2c3e8b SG |
838 | .ops = &octeon_i2c_ops, |
839 | }; |