1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * (c) 2020 Jorge Ramirez <jorge@foundries.io>, Foundries Ltd.
4 */
5 #include <arm.h>
6 #include <drivers/imx_i2c.h>
7 #include <initcall.h>
8 #include <io.h>
9 #include <kernel/boot.h>
10 #include <kernel/delay.h>
11 #include <kernel/dt.h>
12 #include <libfdt.h>
13 #include <mm/core_memprot.h>
14 #include <mm/core_mmu.h>
15 #include <platform_config.h>
16 #include <stdlib.h>
17 #include <trace.h>
18 #include <util.h>
19
20 #define I2C_CLK_RATE 24000000 /* Bits per second */
21
22 /* Utility macros (__x identifies the bus [1 .. 3]) */
23 #define I2C_CFG_SCL(__x) (IOMUXC_I2C1_SCL_CFG_OFF + ((__x) - 1) * 0x8)
24 #define I2C_CFG_SDA(__x) (IOMUXC_I2C1_SDA_CFG_OFF + ((__x) - 1) * 0x8)
25 #define I2C_MUX_SCL(__x) (IOMUXC_I2C1_SCL_MUX_OFF + ((__x) - 1) * 0x8)
26 #define I2C_MUX_SDA(__x) (IOMUXC_I2C1_SDA_MUX_OFF + ((__x) - 1) * 0x8)
27 #if defined(CFG_MX8MM) || defined(CFG_MX8MQ)
28 /* IOMUX */
29 #define I2C_INP_SCL(__x) 0 /* Not implemented */
30 #define I2C_INP_SDA(__x) 0 /* Not implemented */
31 #define I2C_INP_VAL(__x) 0 /* Not implemented */
32 #define I2C_MUX_VAL(__x) 0x010
33 #define I2C_CFG_VAL(__x) 0x1c3
34 /* Clock */
35 #define I2C_CLK_CGRBM(__x) 0 /* Not implemented */
36 #define I2C_CLK_CGR6BM(__x) 0
37 #define I2C_CLK_CGR(__x) CCM_CCRG_I2C##__x
38 #elif defined(CFG_MX6ULL)
39 /* IOMUX */
40 #define I2C_INP_SCL(__x) (IOMUXC_I2C1_SCL_INP_OFF + ((__x) - 1) * 0x8)
41 #define I2C_INP_SDA(__x) (IOMUXC_I2C1_SDA_INP_OFF + ((__x) - 1) * 0x8)
42 #define I2C_INP_VAL(__x) (((__x) == 1) ? 0x1 : 0x2)
43 #define I2C_MUX_VAL(__x) 0x012
44 #define I2C_CFG_VAL(__x) 0x1b8b0
45 /* Clock */
46 #define I2C_CLK_CGRBM(__x) BM_CCM_CCGR2_I2C##__x##_SERIAL
47 #define I2C_CLK_CGR6BM(__x) BM_CCM_CCGR6_I2C##__x##_SERIAL
48 #define I2C_CLK_CGR(__x) (((__x) == 4) ? CCM_CCGR6 : CCM_CCGR2)
49 #else
50 #error IMX_I2C driver not supported on this platform
51 #endif
52
53 static struct io_pa_va i2c_bus[4] = {
54 #if !defined(CFG_DT) || defined(CFG_EXTERNAL_DTB_OVERLAY)
55 #if defined(I2C1_BASE)
56 [0] = { .pa = I2C1_BASE, },
57 #endif
58 #if defined(I2C2_BASE)
59 [1] = { .pa = I2C2_BASE, },
60 #endif
61 #if defined(I2C3_BASE)
62 [2] = { .pa = I2C3_BASE, },
63 #endif
64 #if defined(I2C4_BASE)
65 [3] = { .pa = I2C4_BASE, },
66 #endif
67 #endif
68 };
69
70 static struct imx_i2c_clk {
71 struct io_pa_va base;
72 uint32_t i2c[ARRAY_SIZE(i2c_bus)];
73 uint32_t cgrbm[ARRAY_SIZE(i2c_bus)];
74 } i2c_clk = {
75 .base.pa = CCM_BASE,
76 .i2c = { I2C_CLK_CGR(1), I2C_CLK_CGR(2), I2C_CLK_CGR(3), I2C_CLK_CGR(4), },
77 .cgrbm = { I2C_CLK_CGRBM(1), I2C_CLK_CGRBM(2), I2C_CLK_CGRBM(3), I2C_CLK_CGR6BM(4),},
78 };
79
80 static struct imx_i2c_mux {
81 struct io_pa_va base;
82 struct imx_i2c_mux_regs {
83 uint32_t scl_mux;
84 uint32_t scl_cfg;
85 uint32_t scl_inp;
86 uint32_t sda_mux;
87 uint32_t sda_cfg;
88 uint32_t sda_inp;
89 } i2c[ARRAY_SIZE(i2c_bus)];
90 } i2c_mux = {
91 .base.pa = IOMUXC_BASE,
92 .i2c = {{ .scl_mux = I2C_MUX_SCL(1), .scl_cfg = I2C_CFG_SCL(1),
93 .scl_inp = I2C_INP_SCL(1), .sda_mux = I2C_MUX_SDA(1),
94 .sda_cfg = I2C_CFG_SDA(1), .sda_inp = I2C_INP_SDA(1), },
95 { .scl_mux = I2C_MUX_SCL(2), .scl_cfg = I2C_CFG_SCL(2),
96 .scl_inp = I2C_INP_SCL(2), .sda_mux = I2C_MUX_SDA(2),
97 .sda_cfg = I2C_CFG_SDA(2), .sda_inp = I2C_INP_SDA(2), },
98 { .scl_mux = I2C_MUX_SCL(3), .scl_cfg = I2C_CFG_SCL(3),
99 .scl_inp = I2C_INP_SCL(3), .sda_mux = I2C_MUX_SDA(3),
100 .sda_cfg = I2C_CFG_SDA(3), .sda_inp = I2C_INP_SDA(3), },
101 { .scl_mux = I2C_MUX_SCL(4), .scl_cfg = I2C_CFG_SCL(4),
102 .scl_inp = I2C_INP_SCL(4), .sda_mux = I2C_MUX_SDA(4),
103 .sda_cfg = I2C_CFG_SDA(4), .sda_inp = I2C_INP_SDA(4), },},
104 };
105
106 #define I2DR 0x10
107 #define I2SR 0x0C
108 #define I2CR 0x08
109 #define IFDR 0x04
110
111 #define I2CR_IEN BIT(7)
112 #define I2CR_IIEN BIT(6)
113 #define I2CR_MSTA BIT(5)
114 #define I2CR_MTX BIT(4)
115 #define I2CR_TX_NO_AK BIT(3)
116 #define I2CR_RSTA BIT(2)
117
118 #define I2SR_ICF BIT(7)
119 #define I2SR_IBB BIT(5)
120 #define I2SR_IAL BIT(4)
121 #define I2SR_IIF BIT(1)
122 #define I2SR_RX_NO_AK BIT(0)
123
i2c_io_read8(uint8_t bid,uint32_t address)124 static uint8_t i2c_io_read8(uint8_t bid, uint32_t address)
125 {
126 return io_read8(i2c_bus[bid].va + address);
127 }
128
i2c_io_write8(uint8_t bid,uint32_t address,uint8_t data)129 static void i2c_io_write8(uint8_t bid, uint32_t address, uint8_t data)
130 {
131 return io_write8(i2c_bus[bid].va + address, data);
132 }
133
bus_is_idle(uint32_t sr)134 static bool bus_is_idle(uint32_t sr)
135 {
136 return (sr & I2SR_IBB) == 0;
137 }
138
bus_is_busy(uint32_t sr)139 static bool bus_is_busy(uint32_t sr)
140 {
141 return !bus_is_idle(sr);
142 }
143
isr_active(uint32_t sr)144 static bool isr_active(uint32_t sr)
145 {
146 return (sr & I2SR_IIF) == I2SR_IIF;
147 }
148
149 static struct ifdr_pair {
150 uint32_t divider;
151 uint8_t prescaler;
152 } ifdr_table[] = {
153 { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 },
154 { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 },
155 { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, { 52, 0x05 },
156 { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2A }, { 72, 0x2B },
157 { 80, 0x2C }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A },
158 { 112, 0x2E }, { 128, 0x2F }, { 144, 0x0C }, { 160, 0x30 },
159 { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 },
160 { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, { 448, 0x36 },
161 { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x38 },
162 { 768, 0x39 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B },
163 { 1152, 0x18 }, { 1280, 0x3C }, { 1536, 0x3D }, { 1792, 0x3E },
164 { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D },
165 { 3072, 0x1E }, { 3840, 0x1F }
166 };
167
i2c_set_prescaler(uint8_t bid,uint32_t bps)168 static void i2c_set_prescaler(uint8_t bid, uint32_t bps)
169 {
170 struct ifdr_pair *p = ifdr_table;
171 struct ifdr_pair *q = p + ARRAY_SIZE(ifdr_table) - 1;
172 uint32_t div = (I2C_CLK_RATE + bps - 1) / bps;
173
174 if (div < p->divider)
175 q = p;
176 else if (div > q->divider)
177 p = q;
178
179 while (p != q) {
180 if (div <= p->divider)
181 break;
182 p++;
183 }
184
185 i2c_io_write8(bid, IFDR, p->prescaler);
186 }
187
i2c_set_bus_speed(uint8_t bid,int bps)188 static void i2c_set_bus_speed(uint8_t bid, int bps)
189 {
190 vaddr_t addr = i2c_clk.base.va;
191 uint32_t val = 0;
192
193 #if defined(CFG_MX8MM) || defined(CFG_MX8MQ)
194 addr += CCM_CCGRx_SET(i2c_clk.i2c[bid]);
195 val = CCM_CCGRx_ALWAYS_ON(0);
196 #elif defined(CFG_MX6ULL)
197 addr += i2c_clk.i2c[bid];
198 val = i2c_clk.cgrbm[bid] | io_read32(addr);
199 #else
200 #error IMX_I2C driver not supported on this platform
201 #endif
202 io_write32(addr, val);
203 i2c_set_prescaler(bid, bps);
204 }
205
i2c_sync_bus(uint8_t bid,bool (* match)(uint32_t),uint32_t * status)206 static TEE_Result i2c_sync_bus(uint8_t bid, bool (*match)(uint32_t),
207 uint32_t *status)
208 {
209 uint64_t tref = timeout_init_us(100000);
210 uint32_t sr = 0;
211
212 while (!timeout_elapsed(tref)) {
213 sr = i2c_io_read8(bid, I2SR);
214 if (sr & I2SR_IAL) {
215 EMSG("bus arbitration lost");
216 i2c_io_write8(bid, I2SR, sr & ~I2SR_IAL);
217 return TEE_ERROR_COMMUNICATION;
218 }
219 if ((*match)(sr)) {
220 if (status)
221 *status = sr;
222 return TEE_SUCCESS;
223 }
224 }
225
226 return TEE_ERROR_BUSY;
227 }
228
i2c_idle_bus(uint8_t bid)229 static TEE_Result i2c_idle_bus(uint8_t bid)
230 {
231 uint8_t tmp = i2c_io_read8(bid, I2CR) & ~I2CR_MSTA;
232 TEE_Result ret = TEE_SUCCESS;
233
234 i2c_io_write8(bid, I2CR, tmp);
235 ret = i2c_sync_bus(bid, &bus_is_idle, NULL);
236 i2c_io_write8(bid, I2SR, 0);
237
238 return ret;
239 }
240
i2c_write_byte(uint8_t bid,uint8_t byte)241 static TEE_Result i2c_write_byte(uint8_t bid, uint8_t byte)
242 {
243 TEE_Result ret = TEE_SUCCESS;
244 uint32_t status = 0;
245
246 i2c_io_write8(bid, I2DR, byte);
247 ret = i2c_sync_bus(bid, &isr_active, &status);
248 i2c_io_write8(bid, I2SR, 0);
249
250 if (!ret && (status & I2SR_RX_NO_AK))
251 return TEE_ERROR_BAD_STATE;
252
253 return ret;
254 }
255
i2c_read_byte(uint8_t bid,uint8_t * p)256 static TEE_Result i2c_read_byte(uint8_t bid, uint8_t *p)
257 {
258 TEE_Result ret = TEE_SUCCESS;
259
260 *p = i2c_io_read8(bid, I2DR);
261 ret = i2c_sync_bus(bid, &isr_active, NULL);
262 i2c_io_write8(bid, I2SR, 0);
263
264 return ret;
265 }
266
i2c_write_data(uint8_t bid,const uint8_t * buf,int len)267 static TEE_Result i2c_write_data(uint8_t bid, const uint8_t *buf, int len)
268 {
269 TEE_Result ret = TEE_SUCCESS;
270 uint32_t tmp = 0;
271
272 if (!len)
273 return TEE_SUCCESS;
274
275 tmp = i2c_io_read8(bid, I2CR) | I2CR_MTX | I2CR_TX_NO_AK;
276 i2c_io_write8(bid, I2CR, tmp);
277
278 while (len--) {
279 ret = i2c_write_byte(bid, *buf++);
280 if (ret)
281 return ret;
282 }
283
284 return ret;
285 }
286
i2c_read_data(uint8_t bid,uint8_t * buf,int len)287 static TEE_Result i2c_read_data(uint8_t bid, uint8_t *buf, int len)
288 {
289 TEE_Result ret = TEE_SUCCESS;
290 uint8_t dummy = 0;
291 uint32_t tmp = 0;
292
293 if (!len)
294 return TEE_SUCCESS;
295
296 tmp = i2c_io_read8(bid, I2CR) & ~I2CR_MTX;
297 tmp = (len == 1) ? tmp | I2CR_TX_NO_AK : tmp & ~I2CR_TX_NO_AK;
298 i2c_io_write8(bid, I2CR, tmp);
299 i2c_io_read8(bid, I2DR);
300
301 ret = i2c_read_byte(bid, &dummy);
302 if (ret)
303 return ret;
304
305 /*
306 * A data transfer ends when the master signals a stop; for a master
307 * receiver to terminate a transfer it must inform the slave transmiter
308 * by not acknowledging the last data byte. This is done by setting the
309 * transmit acknowledge bit before reading the next-to-last byte.
310 */
311 do {
312 if (len == 2) {
313 tmp = i2c_io_read8(bid, I2CR) | I2CR_TX_NO_AK;
314 i2c_io_write8(bid, I2CR, tmp);
315 }
316
317 ret = i2c_read_byte(bid, buf++);
318 if (ret)
319 return ret;
320 } while (len--);
321
322 return ret;
323 }
324
i2c_init_transfer(uint8_t bid,uint8_t chip)325 static TEE_Result i2c_init_transfer(uint8_t bid, uint8_t chip)
326 {
327 TEE_Result ret = TEE_SUCCESS;
328 uint32_t tmp = 0;
329
330 ret = i2c_idle_bus(bid);
331 if (ret)
332 return ret;
333
334 /* Enable the interface */
335 i2c_io_write8(bid, I2CR, I2CR_IEN);
336
337 tmp = i2c_io_read8(bid, I2CR) | I2CR_MSTA;
338 i2c_io_write8(bid, I2CR, tmp);
339
340 /* Wait until the bus is active */
341 ret = i2c_sync_bus(bid, &bus_is_busy, NULL);
342 if (ret)
343 return ret;
344
345 /* Slave address on the bus */
346 return i2c_write_data(bid, &chip, 1);
347 }
348
imx_i2c_read(uint8_t bid,uint8_t chip,uint8_t * buf,int len)349 TEE_Result imx_i2c_read(uint8_t bid, uint8_t chip, uint8_t *buf, int len)
350 {
351 TEE_Result ret = TEE_SUCCESS;
352
353 if (bid >= ARRAY_SIZE(i2c_bus))
354 return TEE_ERROR_BAD_PARAMETERS;
355
356 if ((len && !buf) || chip > 0x7F)
357 return TEE_ERROR_BAD_PARAMETERS;
358
359 if (!i2c_bus[bid].va)
360 return TEE_ERROR_BAD_PARAMETERS;
361
362 ret = i2c_init_transfer(bid, chip << 1 | BIT(0));
363 if (!ret)
364 ret = i2c_read_data(bid, buf, len);
365
366 if (i2c_idle_bus(bid))
367 IMSG("bus not idle");
368
369 return ret;
370 }
371
imx_i2c_write(uint8_t bid,uint8_t chip,const uint8_t * buf,int len)372 TEE_Result imx_i2c_write(uint8_t bid, uint8_t chip, const uint8_t *buf, int len)
373 {
374 TEE_Result ret = TEE_SUCCESS;
375
376 if (bid >= ARRAY_SIZE(i2c_bus))
377 return TEE_ERROR_BAD_PARAMETERS;
378
379 if ((len && !buf) || chip > 0x7F)
380 return TEE_ERROR_BAD_PARAMETERS;
381
382 if (!i2c_bus[bid].va)
383 return TEE_ERROR_BAD_PARAMETERS;
384
385 ret = i2c_init_transfer(bid, chip << 1);
386 if (!ret)
387 ret = i2c_write_data(bid, buf, len);
388
389 if (i2c_idle_bus(bid))
390 IMSG("bus not idle");
391
392 return ret;
393 }
394
imx_i2c_probe(uint8_t bid,uint8_t chip)395 TEE_Result imx_i2c_probe(uint8_t bid, uint8_t chip)
396 {
397 if (bid >= ARRAY_SIZE(i2c_bus))
398 return TEE_ERROR_BAD_PARAMETERS;
399
400 if (!i2c_bus[bid].va)
401 return TEE_ERROR_BAD_PARAMETERS;
402
403 if (chip > 0x7F)
404 return TEE_ERROR_BAD_PARAMETERS;
405
406 return imx_i2c_write(bid, chip, NULL, 0);
407 }
408
409 /*
410 * I2C bus initialization: configure the IOMUX and enable the clock.
411 * @bid: Bus ID: (0=I2C1), (1=I2C2), (2=I2C3), (3=I2C4).
412 * @bps: Bus baud rate, in bits per second.
413 */
imx_i2c_init(uint8_t bid,int bps)414 TEE_Result imx_i2c_init(uint8_t bid, int bps)
415 {
416 struct imx_i2c_mux *mux = &i2c_mux;
417
418 if (bid >= ARRAY_SIZE(i2c_bus))
419 return TEE_ERROR_BAD_PARAMETERS;
420
421 if (!bps)
422 return TEE_ERROR_BAD_PARAMETERS;
423
424 if (!i2c_bus[bid].va)
425 return TEE_ERROR_BAD_PARAMETERS;
426
427 io_write32(mux->base.va + mux->i2c[bid].scl_mux, I2C_MUX_VAL(bid));
428 io_write32(mux->base.va + mux->i2c[bid].scl_cfg, I2C_CFG_VAL(bid));
429 if (mux->i2c[bid].scl_inp)
430 io_write32(mux->base.va + mux->i2c[bid].scl_inp,
431 I2C_INP_VAL(bid + 1));
432
433 io_write32(mux->base.va + mux->i2c[bid].sda_mux, I2C_MUX_VAL(bid));
434 io_write32(mux->base.va + mux->i2c[bid].sda_cfg, I2C_CFG_VAL(bid));
435 if (mux->i2c[bid].sda_inp)
436 io_write32(mux->base.va + mux->i2c[bid].sda_inp,
437 I2C_INP_VAL(bid + 1));
438
439 /* Baud rate in bits per second */
440 i2c_set_bus_speed(bid, bps);
441
442 return TEE_SUCCESS;
443 }
444
get_va(paddr_t pa,vaddr_t * va)445 static TEE_Result get_va(paddr_t pa, vaddr_t *va)
446 {
447 *va = (vaddr_t)core_mmu_add_mapping(MEM_AREA_IO_SEC, pa, 0x10000);
448 if (!*va)
449 return TEE_ERROR_GENERIC;
450
451 return TEE_SUCCESS;
452 }
453
454 #if defined(CFG_DT) && !defined(CFG_EXTERNAL_DTB_OVERLAY)
455 static const char *const dt_i2c_match_table[] = {
456 "fsl,imx21-i2c",
457 };
458
i2c_mapped(const char * i2c_match)459 static TEE_Result i2c_mapped(const char *i2c_match)
460 {
461 TEE_Result ret = TEE_ERROR_GENERIC;
462 void *fdt = get_dt();
463 size_t size = 0;
464 size_t i = 0;
465 int off = 0;
466
467 if (!fdt)
468 return TEE_ERROR_NOT_SUPPORTED;
469
470 for (i = 0; i < ARRAY_SIZE(i2c_bus); i++) {
471 off = fdt_node_offset_by_compatible(fdt, off, i2c_match);
472 if (off < 0)
473 break;
474
475 if (!(_fdt_get_status(fdt, off) & DT_STATUS_OK_SEC)) {
476 EMSG("i2c%zu not enabled", i + 1);
477 continue;
478 }
479
480 if (dt_map_dev(fdt, off, &i2c_bus[i].va, &size) < 0) {
481 EMSG("i2c%zu not enabled", i + 1);
482 continue;
483 }
484
485 i2c_bus[i].pa = virt_to_phys((void *)i2c_bus[i].va);
486 ret = TEE_SUCCESS;
487 }
488
489 return ret;
490 }
491
i2c_map_controller(void)492 static TEE_Result i2c_map_controller(void)
493 {
494 TEE_Result ret = TEE_ERROR_GENERIC;
495 size_t i = 0;
496
497 for (i = 0; i < ARRAY_SIZE(dt_i2c_match_table); i++) {
498 ret = i2c_mapped(dt_i2c_match_table[i]);
499 if (!ret || ret == TEE_ERROR_NOT_SUPPORTED)
500 return ret;
501 }
502
503 return ret;
504 }
505 #else
i2c_map_controller(void)506 static TEE_Result i2c_map_controller(void)
507 {
508 TEE_Result ret = TEE_ERROR_GENERIC;
509 size_t n = 0;
510
511 for (n = 0; n < ARRAY_SIZE(i2c_bus); n++) {
512 if (i2c_bus[n].pa) {
513 if (get_va(i2c_bus[n].pa, &i2c_bus[n].va))
514 EMSG("i2c%zu not enabled", n + 1);
515 else
516 ret = TEE_SUCCESS;
517 } else {
518 IMSG("i2c%zu not enabled", n + 1);
519 }
520 }
521
522 return ret;
523 }
524 #endif
525
i2c_init(void)526 static TEE_Result i2c_init(void)
527 {
528 if (get_va(i2c_clk.base.pa, &i2c_clk.base.va))
529 return TEE_ERROR_GENERIC;
530
531 if (get_va(i2c_mux.base.pa, &i2c_mux.base.va))
532 return TEE_ERROR_GENERIC;
533
534 return i2c_map_controller();
535 }
536
537 early_init(i2c_init);
538