xref: /optee_os/core/drivers/imx_i2c.c (revision 1437150987a08bdfaa304f77b89f3cdac5fe532e)
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/delay.h>
10 #include <mm/core_memprot.h>
11 #include <mm/core_mmu.h>
12 #include <platform_config.h>
13 #include <stdlib.h>
14 #include <trace.h>
15 #include <util.h>
16 
17 #define I2C_CLK_RATE	24000000 /* Bits per second */
18 
19 static struct io_pa_va i2c_bus[] = {
20 	{ .pa = I2C1_BASE, },
21 	{ .pa = I2C2_BASE, },
22 	{ .pa = I2C3_BASE, },
23 };
24 
25 static struct imx_i2c_clk {
26 	struct io_pa_va base;
27 	uint32_t i2c[ARRAY_SIZE(i2c_bus)];
28 } i2c_clk = {
29 	.base.pa = CCM_BASE,
30 	.i2c = { I2C_CLK_CGR(1), I2C_CLK_CGR(2), I2C_CLK_CGR(3), },
31 };
32 
33 static struct imx_i2c_mux {
34 	struct io_pa_va base;
35 	struct imx_i2c_mux_regs {
36 		uint32_t scl_mux;
37 		uint32_t scl_cfg;
38 		uint32_t sda_mux;
39 		uint32_t sda_cfg;
40 	} i2c[ARRAY_SIZE(i2c_bus)];
41 } i2c_mux = {
42 	.base.pa = IOMUXC_BASE,
43 	.i2c = {{ .scl_mux = I2C_MUX_SCL(1), .scl_cfg = I2C_CFG_SCL(1),
44 		.sda_mux = I2C_MUX_SDA(1), .sda_cfg = I2C_CFG_SDA(1), },
45 	       { .scl_mux = I2C_MUX_SCL(2), .scl_cfg = I2C_CFG_SCL(2),
46 		.sda_mux = I2C_MUX_SDA(2), .sda_cfg = I2C_CFG_SDA(2), },
47 	       { .scl_mux = I2C_MUX_SCL(3), .scl_cfg = I2C_CFG_SCL(3),
48 		.sda_mux = I2C_MUX_SDA(3), .sda_cfg = I2C_CFG_SDA(3), },},
49 };
50 
51 #define I2DR				0x10
52 #define I2SR				0x0C
53 #define I2CR				0x08
54 #define IFDR				0x04
55 
56 #define I2CR_IEN			BIT(7)
57 #define I2CR_IIEN			BIT(6)
58 #define I2CR_MSTA			BIT(5)
59 #define I2CR_MTX			BIT(4)
60 #define I2CR_TX_NO_AK			BIT(3)
61 #define I2CR_RSTA			BIT(2)
62 
63 #define I2SR_ICF			BIT(7)
64 #define I2SR_IBB			BIT(5)
65 #define I2SR_IAL			BIT(4)
66 #define I2SR_IIF			BIT(1)
67 #define I2SR_RX_NO_AK			BIT(0)
68 
69 static uint8_t i2c_io_read8(uint8_t bid, uint32_t address)
70 {
71 	return io_read8(i2c_bus[bid].va + address);
72 }
73 
74 static void i2c_io_write8(uint8_t bid, uint32_t address, uint8_t data)
75 {
76 	return io_write8(i2c_bus[bid].va + address, data);
77 }
78 
79 static bool bus_is_idle(uint32_t sr)
80 {
81 	return (sr & I2SR_IBB) == 0;
82 }
83 
84 static bool bus_is_busy(uint32_t sr)
85 {
86 	return !bus_is_idle(sr);
87 }
88 
89 static bool isr_active(uint32_t sr)
90 {
91 	return (sr & I2SR_IIF) == I2SR_IIF;
92 }
93 
94 static struct ifdr_pair {
95 	uint32_t divider;
96 	uint8_t prescaler;
97 } ifdr_table[] = {
98 	{ 22,	0x20 }, { 24,	0x21 }, { 26,	0x22 }, { 28,	0x23 },
99 	{ 30,	0x00 }, { 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
100 	{ 42,	0x03 }, { 44,	0x27 }, { 48,	0x28 }, { 52,	0x05 },
101 	{ 56,	0x29 }, { 60,	0x06 }, { 64,	0x2A }, { 72,	0x2B },
102 	{ 80,	0x2C }, { 88,	0x09 }, { 96,	0x2D }, { 104,	0x0A },
103 	{ 112,	0x2E }, { 128,	0x2F }, { 144,	0x0C }, { 160,	0x30 },
104 	{ 192,	0x31 }, { 224,	0x32 }, { 240,	0x0F }, { 256,	0x33 },
105 	{ 288,	0x10 }, { 320,	0x34 }, { 384,	0x35 }, { 448,	0x36 },
106 	{ 480,	0x13 }, { 512,	0x37 }, { 576,	0x14 }, { 640,	0x38 },
107 	{ 768,	0x39 }, { 896,	0x3A }, { 960,	0x17 }, { 1024,	0x3B },
108 	{ 1152,	0x18 }, { 1280,	0x3C }, { 1536,	0x3D }, { 1792,	0x3E },
109 	{ 1920,	0x1B }, { 2048,	0x3F }, { 2304,	0x1C }, { 2560,	0x1D },
110 	{ 3072,	0x1E }, { 3840,	0x1F }
111 };
112 
113 static void i2c_set_prescaler(uint8_t bid, uint32_t bps)
114 {
115 	struct ifdr_pair *p = ifdr_table;
116 	struct ifdr_pair *q = p + ARRAY_SIZE(ifdr_table) - 1;
117 	uint32_t div = (I2C_CLK_RATE + bps - 1) / bps;
118 
119 	if (div < p->divider)
120 		q = p;
121 	else if (div > q->divider)
122 		p = q;
123 
124 	while (p != q) {
125 		if (div <= p->divider)
126 			break;
127 		p++;
128 	}
129 
130 	i2c_io_write8(bid, IFDR, p->prescaler);
131 }
132 
133 static void i2c_set_bus_speed(uint8_t bid, int bps)
134 {
135 	/* Enable the clock */
136 	io_write32(i2c_clk.base.va + CCM_CCGRx_SET(i2c_clk.i2c[bid]),
137 		   CCM_CCGRx_ALWAYS_ON(0));
138 
139 	i2c_set_prescaler(bid, bps);
140 }
141 
142 static TEE_Result i2c_sync_bus(uint8_t bid, bool (*match)(uint32_t),
143 			       uint32_t *status)
144 {
145 	uint64_t tref = timeout_init_us(100000);
146 	uint32_t sr = 0;
147 
148 	while (!timeout_elapsed(tref)) {
149 		sr = i2c_io_read8(bid, I2SR);
150 		if (sr & I2SR_IAL) {
151 			EMSG("bus arbitration lost");
152 			i2c_io_write8(bid, I2SR, sr & ~I2SR_IAL);
153 			return TEE_ERROR_COMMUNICATION;
154 		}
155 		if ((*match)(sr)) {
156 			if (status)
157 				*status = sr;
158 			return TEE_SUCCESS;
159 		}
160 	}
161 
162 	return TEE_ERROR_BUSY;
163 }
164 
165 static TEE_Result i2c_idle_bus(uint8_t bid)
166 {
167 	uint8_t tmp = i2c_io_read8(bid, I2CR) & ~I2CR_MSTA;
168 	TEE_Result ret = TEE_SUCCESS;
169 
170 	i2c_io_write8(bid, I2CR, tmp);
171 	ret = i2c_sync_bus(bid, &bus_is_idle, NULL);
172 	i2c_io_write8(bid, I2SR, 0);
173 
174 	return ret;
175 }
176 
177 static TEE_Result i2c_write_byte(uint8_t bid, uint8_t byte)
178 {
179 	TEE_Result ret = TEE_SUCCESS;
180 	uint32_t status = 0;
181 
182 	i2c_io_write8(bid, I2DR, byte);
183 	ret = i2c_sync_bus(bid, &isr_active, &status);
184 	i2c_io_write8(bid, I2SR, 0);
185 
186 	if (!ret && (status & I2SR_RX_NO_AK))
187 		return TEE_ERROR_BAD_STATE;
188 
189 	return ret;
190 }
191 
192 static TEE_Result i2c_read_byte(uint8_t bid, uint8_t *p)
193 {
194 	TEE_Result ret = TEE_SUCCESS;
195 
196 	*p = i2c_io_read8(bid, I2DR);
197 	ret = i2c_sync_bus(bid, &isr_active, NULL);
198 	i2c_io_write8(bid, I2SR, 0);
199 
200 	return ret;
201 }
202 
203 static TEE_Result i2c_write_data(uint8_t bid, const uint8_t *buf, int len)
204 {
205 	TEE_Result ret = TEE_SUCCESS;
206 	uint32_t tmp = 0;
207 
208 	if (!len)
209 		return TEE_SUCCESS;
210 
211 	tmp = i2c_io_read8(bid, I2CR) | I2CR_MTX | I2CR_TX_NO_AK;
212 	i2c_io_write8(bid, I2CR, tmp);
213 
214 	while (len--) {
215 		ret = i2c_write_byte(bid, *buf++);
216 		if (ret)
217 			return ret;
218 	}
219 
220 	return ret;
221 }
222 
223 static TEE_Result i2c_read_data(uint8_t bid, uint8_t *buf, int len)
224 {
225 	TEE_Result ret = TEE_SUCCESS;
226 	uint8_t dummy = 0;
227 	uint32_t tmp = 0;
228 
229 	if (!len)
230 		return TEE_SUCCESS;
231 
232 	tmp = i2c_io_read8(bid, I2CR) & ~I2CR_MTX;
233 	tmp = (len == 1) ? tmp | I2CR_TX_NO_AK : tmp & ~I2CR_TX_NO_AK;
234 	i2c_io_write8(bid, I2CR, tmp);
235 	i2c_io_read8(bid, I2DR);
236 
237 	ret = i2c_read_byte(bid, &dummy);
238 	if (ret)
239 		return ret;
240 
241 	/*
242 	 * A data transfer ends when the master signals a stop; for a master
243 	 * receiver to terminate a transfer it must inform the slave transmiter
244 	 * by not acknowledging the last data byte. This is done by setting the
245 	 * transmit acknowledge bit before reading the next-to-last byte.
246 	 */
247 	do {
248 		if (len == 2) {
249 			tmp = i2c_io_read8(bid, I2CR) | I2CR_TX_NO_AK;
250 			i2c_io_write8(bid, I2CR, tmp);
251 		}
252 
253 		ret = i2c_read_byte(bid, buf++);
254 		if (ret)
255 			return ret;
256 	} while (len--);
257 
258 	return ret;
259 }
260 
261 static TEE_Result i2c_init_transfer(uint8_t bid, uint8_t chip)
262 {
263 	TEE_Result ret = TEE_SUCCESS;
264 	uint32_t tmp = 0;
265 
266 	ret = i2c_idle_bus(bid);
267 	if (ret)
268 		return ret;
269 
270 	/* Enable the interface */
271 	i2c_io_write8(bid, I2CR, I2CR_IEN);
272 
273 	tmp = i2c_io_read8(bid, I2CR) | I2CR_MSTA;
274 	i2c_io_write8(bid, I2CR, tmp);
275 
276 	/* Wait until the bus is active */
277 	ret = i2c_sync_bus(bid, &bus_is_busy, NULL);
278 	if (ret)
279 		return ret;
280 
281 	/* Slave address on the bus */
282 	return i2c_write_data(bid, &chip, 1);
283 }
284 
285 TEE_Result imx_i2c_read(uint8_t bid, uint8_t chip, uint8_t *buf, int len)
286 {
287 	TEE_Result ret = TEE_SUCCESS;
288 
289 	if (bid >= ARRAY_SIZE(i2c_bus))
290 		return TEE_ERROR_BAD_PARAMETERS;
291 
292 	if ((len && !buf) || chip > 0x7F)
293 		return TEE_ERROR_BAD_PARAMETERS;
294 
295 	ret = i2c_init_transfer(bid, chip << 1 | BIT(0));
296 	if (!ret)
297 		ret = i2c_read_data(bid, buf, len);
298 
299 	if (i2c_idle_bus(bid))
300 		IMSG("bus not idle");
301 
302 	return ret;
303 }
304 
305 TEE_Result imx_i2c_write(uint8_t bid, uint8_t chip, const uint8_t *buf, int len)
306 {
307 	TEE_Result ret = TEE_SUCCESS;
308 
309 	if (bid >= ARRAY_SIZE(i2c_bus))
310 		return TEE_ERROR_BAD_PARAMETERS;
311 
312 	if ((len && !buf) || chip > 0x7F)
313 		return TEE_ERROR_BAD_PARAMETERS;
314 
315 	ret = i2c_init_transfer(bid, chip << 1);
316 	if (!ret)
317 		ret = i2c_write_data(bid, buf, len);
318 
319 	if (i2c_idle_bus(bid))
320 		IMSG("bus not idle");
321 
322 	return ret;
323 }
324 
325 TEE_Result imx_i2c_probe(uint8_t bid, uint8_t chip)
326 {
327 	if (bid >= ARRAY_SIZE(i2c_bus))
328 		return TEE_ERROR_BAD_PARAMETERS;
329 
330 	if (chip > 0x7F)
331 		return TEE_ERROR_BAD_PARAMETERS;
332 
333 	return imx_i2c_write(bid, chip, NULL, 0);
334 }
335 
336 /*
337  * I2C bus initialization: configure the IOMUX and enable the clock.
338  * @bid: Bus ID: (0=I2C1), (1=I2C2), (2=I2C3).
339  * @bps: Bus baud rate, in bits per second.
340  */
341 TEE_Result imx_i2c_init(uint8_t bid, int bps)
342 {
343 	struct imx_i2c_mux *mux = &i2c_mux;
344 
345 	if (bid >= ARRAY_SIZE(i2c_bus))
346 		return TEE_ERROR_BAD_PARAMETERS;
347 
348 	if (!bps)
349 		return TEE_ERROR_BAD_PARAMETERS;
350 
351 	io_write32(mux->base.va + mux->i2c[bid].scl_mux, I2C_MUX_VAL(bid));
352 	io_write32(mux->base.va + mux->i2c[bid].scl_cfg, I2C_CFG_VAL(bid));
353 	io_write32(mux->base.va + mux->i2c[bid].sda_mux, I2C_MUX_VAL(bid));
354 	io_write32(mux->base.va + mux->i2c[bid].sda_cfg, I2C_CFG_VAL(bid));
355 
356 	/* Baud rate in bits per second */
357 	i2c_set_bus_speed(bid, bps);
358 
359 	return TEE_SUCCESS;
360 }
361 
362 static TEE_Result get_va(paddr_t pa, vaddr_t *va)
363 {
364 	if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, pa, 0x10000))
365 		return TEE_ERROR_GENERIC;
366 
367 	*va = (vaddr_t)phys_to_virt(pa, MEM_AREA_IO_SEC);
368 	if (*va)
369 		return TEE_SUCCESS;
370 
371 	return TEE_ERROR_GENERIC;
372 }
373 
374 static TEE_Result i2c_init(void)
375 {
376 	size_t n = 0;
377 
378 	if (get_va(i2c_clk.base.pa, &i2c_clk.base.va))
379 		return TEE_ERROR_GENERIC;
380 
381 	if (get_va(i2c_mux.base.pa, &i2c_mux.base.va))
382 		return TEE_ERROR_GENERIC;
383 
384 	for (n = 0; n < ARRAY_SIZE(i2c_bus); n++) {
385 		if (get_va(i2c_bus[n].pa, &i2c_bus[n].va))
386 			return TEE_ERROR_GENERIC;
387 	}
388 
389 	return TEE_SUCCESS;
390 }
391 
392 early_init(i2c_init);
393