xref: /openbmc/u-boot/drivers/i2c/imx_lpi2c.c (revision 87a62bce)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2016 Freescale Semiconductors, Inc.
4  */
5 
6 #include <common.h>
7 #include <errno.h>
8 #include <asm/io.h>
9 #include <asm/arch/clock.h>
10 #include <asm/arch/imx-regs.h>
11 #include <asm/arch/imx_lpi2c.h>
12 #include <asm/arch/sys_proto.h>
13 #include <dm.h>
14 #include <fdtdec.h>
15 #include <i2c.h>
16 
17 #define LPI2C_FIFO_SIZE 4
18 #define LPI2C_TIMEOUT_MS 100
19 
20 /* Weak linked function for overridden by some SoC power function */
21 int __weak init_i2c_power(unsigned i2c_num)
22 {
23 	return 0;
24 }
25 
26 static int imx_lpci2c_check_busy_bus(const struct imx_lpi2c_reg *regs)
27 {
28 	lpi2c_status_t result = LPI2C_SUCESS;
29 	u32 status;
30 
31 	status = readl(&regs->msr);
32 
33 	if ((status & LPI2C_MSR_BBF_MASK) && !(status & LPI2C_MSR_MBF_MASK))
34 		result = LPI2C_BUSY;
35 
36 	return result;
37 }
38 
39 static int imx_lpci2c_check_clear_error(struct imx_lpi2c_reg *regs)
40 {
41 	lpi2c_status_t result = LPI2C_SUCESS;
42 	u32 val, status;
43 
44 	status = readl(&regs->msr);
45 	/* errors to check for */
46 	status &= LPI2C_MSR_NDF_MASK | LPI2C_MSR_ALF_MASK |
47 		LPI2C_MSR_FEF_MASK | LPI2C_MSR_PLTF_MASK;
48 
49 	if (status) {
50 		if (status & LPI2C_MSR_PLTF_MASK)
51 			result = LPI2C_PIN_LOW_TIMEOUT_ERR;
52 		else if (status & LPI2C_MSR_ALF_MASK)
53 			result = LPI2C_ARB_LOST_ERR;
54 		else if (status & LPI2C_MSR_NDF_MASK)
55 			result = LPI2C_NAK_ERR;
56 		else if (status & LPI2C_MSR_FEF_MASK)
57 			result = LPI2C_FIFO_ERR;
58 
59 		/* clear status flags */
60 		writel(0x7f00, &regs->msr);
61 		/* reset fifos */
62 		val = readl(&regs->mcr);
63 		val |= LPI2C_MCR_RRF_MASK | LPI2C_MCR_RTF_MASK;
64 		writel(val, &regs->mcr);
65 	}
66 
67 	return result;
68 }
69 
70 static int bus_i2c_wait_for_tx_ready(struct imx_lpi2c_reg *regs)
71 {
72 	lpi2c_status_t result = LPI2C_SUCESS;
73 	u32 txcount = 0;
74 	ulong start_time = get_timer(0);
75 
76 	do {
77 		txcount = LPI2C_MFSR_TXCOUNT(readl(&regs->mfsr));
78 		txcount = LPI2C_FIFO_SIZE - txcount;
79 		result = imx_lpci2c_check_clear_error(regs);
80 		if (result) {
81 			debug("i2c: wait for tx ready: result 0x%x\n", result);
82 			return result;
83 		}
84 		if (get_timer(start_time) > LPI2C_TIMEOUT_MS) {
85 			debug("i2c: wait for tx ready: timeout\n");
86 			return -1;
87 		}
88 	} while (!txcount);
89 
90 	return result;
91 }
92 
93 static int bus_i2c_send(struct imx_lpi2c_reg *regs, u8 *txbuf, int len)
94 {
95 	lpi2c_status_t result = LPI2C_SUCESS;
96 
97 	/* empty tx */
98 	if (!len)
99 		return result;
100 
101 	while (len--) {
102 		result = bus_i2c_wait_for_tx_ready(regs);
103 		if (result) {
104 			debug("i2c: send wait fot tx ready: %d\n", result);
105 			return result;
106 		}
107 		writel(*txbuf++, &regs->mtdr);
108 	}
109 
110 	return result;
111 }
112 
113 static int bus_i2c_receive(struct imx_lpi2c_reg *regs, u8 *rxbuf, int len)
114 {
115 	lpi2c_status_t result = LPI2C_SUCESS;
116 	u32 val;
117 	ulong start_time = get_timer(0);
118 
119 	/* empty read */
120 	if (!len)
121 		return result;
122 
123 	result = bus_i2c_wait_for_tx_ready(regs);
124 	if (result) {
125 		debug("i2c: receive wait fot tx ready: %d\n", result);
126 		return result;
127 	}
128 
129 	/* clear all status flags */
130 	writel(0x7f00, &regs->msr);
131 	/* send receive command */
132 	val = LPI2C_MTDR_CMD(0x1) | LPI2C_MTDR_DATA(len - 1);
133 	writel(val, &regs->mtdr);
134 
135 	while (len--) {
136 		do {
137 			result = imx_lpci2c_check_clear_error(regs);
138 			if (result) {
139 				debug("i2c: receive check clear error: %d\n",
140 				      result);
141 				return result;
142 			}
143 			if (get_timer(start_time) > LPI2C_TIMEOUT_MS) {
144 				debug("i2c: receive mrdr: timeout\n");
145 				return -1;
146 			}
147 			val = readl(&regs->mrdr);
148 		} while (val & LPI2C_MRDR_RXEMPTY_MASK);
149 		*rxbuf++ = LPI2C_MRDR_DATA(val);
150 	}
151 
152 	return result;
153 }
154 
155 static int bus_i2c_start(struct imx_lpi2c_reg *regs, u8 addr, u8 dir)
156 {
157 	lpi2c_status_t result;
158 	u32 val;
159 
160 	result = imx_lpci2c_check_busy_bus(regs);
161 	if (result) {
162 		debug("i2c: start check busy bus: 0x%x\n", result);
163 		return result;
164 	}
165 	/* clear all status flags */
166 	writel(0x7f00, &regs->msr);
167 	/* turn off auto-stop condition */
168 	val = readl(&regs->mcfgr1) & ~LPI2C_MCFGR1_AUTOSTOP_MASK;
169 	writel(val, &regs->mcfgr1);
170 	/* wait tx fifo ready */
171 	result = bus_i2c_wait_for_tx_ready(regs);
172 	if (result) {
173 		debug("i2c: start wait for tx ready: 0x%x\n", result);
174 		return result;
175 	}
176 	/* issue start command */
177 	val = LPI2C_MTDR_CMD(0x4) | (addr << 0x1) | dir;
178 	writel(val, &regs->mtdr);
179 
180 	return result;
181 }
182 
183 static int bus_i2c_stop(struct imx_lpi2c_reg *regs)
184 {
185 	lpi2c_status_t result;
186 	u32 status;
187 
188 	result = bus_i2c_wait_for_tx_ready(regs);
189 	if (result) {
190 		debug("i2c: stop wait for tx ready: 0x%x\n", result);
191 		return result;
192 	}
193 
194 	/* send stop command */
195 	writel(LPI2C_MTDR_CMD(0x2), &regs->mtdr);
196 
197 	while (result == LPI2C_SUCESS) {
198 		status = readl(&regs->msr);
199 		result = imx_lpci2c_check_clear_error(regs);
200 		/* stop detect flag */
201 		if (status & LPI2C_MSR_SDF_MASK) {
202 			/* clear stop flag */
203 			status &= LPI2C_MSR_SDF_MASK;
204 			writel(status, &regs->msr);
205 			break;
206 		}
207 	}
208 
209 	return result;
210 }
211 
212 static int bus_i2c_read(struct imx_lpi2c_reg *regs, u32 chip, u8 *buf, int len)
213 {
214 	lpi2c_status_t result;
215 
216 	result = bus_i2c_start(regs, chip, 1);
217 	if (result)
218 		return result;
219 	result = bus_i2c_receive(regs, buf, len);
220 	if (result)
221 		return result;
222 	result = bus_i2c_stop(regs);
223 	if (result)
224 		return result;
225 
226 	return result;
227 }
228 
229 static int bus_i2c_write(struct imx_lpi2c_reg *regs, u32 chip, u8 *buf, int len)
230 {
231 	lpi2c_status_t result;
232 
233 	result = bus_i2c_start(regs, chip, 0);
234 	if (result)
235 		return result;
236 	result = bus_i2c_send(regs, buf, len);
237 	if (result)
238 		return result;
239 	result = bus_i2c_stop(regs);
240 	if (result)
241 		return result;
242 
243 	return result;
244 }
245 
246 
247 static int bus_i2c_set_bus_speed(struct udevice *bus, int speed)
248 {
249 	struct imx_lpi2c_reg *regs;
250 	u32 val;
251 	u32 preescale = 0, best_pre = 0, clkhi = 0;
252 	u32 best_clkhi = 0, abs_error = 0, rate;
253 	u32 error = 0xffffffff;
254 	u32 clock_rate;
255 	bool mode;
256 	int i;
257 
258 	regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
259 	clock_rate = imx_get_i2cclk(bus->seq);
260 	if (!clock_rate)
261 		return -EPERM;
262 
263 	mode = (readl(&regs->mcr) & LPI2C_MCR_MEN_MASK) >> LPI2C_MCR_MEN_SHIFT;
264 	/* disable master mode */
265 	val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
266 	writel(val | LPI2C_MCR_MEN(0), &regs->mcr);
267 
268 	for (preescale = 1; (preescale <= 128) &&
269 		(error != 0); preescale = 2 * preescale) {
270 		for (clkhi = 1; clkhi < 32; clkhi++) {
271 			if (clkhi == 1)
272 				rate = (clock_rate / preescale) / (1 + 3 + 2 + 2 / preescale);
273 			else
274 				rate = (clock_rate / preescale / (3 * clkhi + 2 + 2 / preescale));
275 
276 			abs_error = speed > rate ? speed - rate : rate - speed;
277 
278 			if (abs_error < error) {
279 				best_pre = preescale;
280 				best_clkhi = clkhi;
281 				error = abs_error;
282 				if (abs_error == 0)
283 					break;
284 			}
285 		}
286 	}
287 
288 	/* Standard, fast, fast mode plus and ultra-fast transfers. */
289 	val = LPI2C_MCCR0_CLKHI(best_clkhi);
290 	if (best_clkhi < 2)
291 		val |= LPI2C_MCCR0_CLKLO(3) | LPI2C_MCCR0_SETHOLD(2) | LPI2C_MCCR0_DATAVD(1);
292 	else
293 		val |= LPI2C_MCCR0_CLKLO(2 * best_clkhi) | LPI2C_MCCR0_SETHOLD(best_clkhi) |
294 			LPI2C_MCCR0_DATAVD(best_clkhi / 2);
295 	writel(val, &regs->mccr0);
296 
297 	for (i = 0; i < 8; i++) {
298 		if (best_pre == (1 << i)) {
299 			best_pre = i;
300 			break;
301 		}
302 	}
303 
304 	val = readl(&regs->mcfgr1) & ~LPI2C_MCFGR1_PRESCALE_MASK;
305 	writel(val | LPI2C_MCFGR1_PRESCALE(best_pre), &regs->mcfgr1);
306 
307 	if (mode) {
308 		val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
309 		writel(val | LPI2C_MCR_MEN(1), &regs->mcr);
310 	}
311 
312 	return 0;
313 }
314 
315 static int bus_i2c_init(struct udevice *bus, int speed)
316 {
317 	struct imx_lpi2c_reg *regs;
318 	u32 val;
319 	int ret;
320 
321 	regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
322 	/* reset peripheral */
323 	writel(LPI2C_MCR_RST_MASK, &regs->mcr);
324 	writel(0x0, &regs->mcr);
325 	/* Disable Dozen mode */
326 	writel(LPI2C_MCR_DBGEN(0) | LPI2C_MCR_DOZEN(1), &regs->mcr);
327 	/* host request disable, active high, external pin */
328 	val = readl(&regs->mcfgr0);
329 	val &= (~(LPI2C_MCFGR0_HREN_MASK | LPI2C_MCFGR0_HRPOL_MASK |
330 				LPI2C_MCFGR0_HRSEL_MASK));
331 	val |= LPI2C_MCFGR0_HRPOL(0x1);
332 	writel(val, &regs->mcfgr0);
333 	/* pincfg and ignore ack */
334 	val = readl(&regs->mcfgr1);
335 	val &= ~(LPI2C_MCFGR1_PINCFG_MASK | LPI2C_MCFGR1_IGNACK_MASK);
336 	val |= LPI2C_MCFGR1_PINCFG(0x0); /* 2 pin open drain */
337 	val |= LPI2C_MCFGR1_IGNACK(0x0); /* ignore nack */
338 	writel(val, &regs->mcfgr1);
339 
340 	ret = bus_i2c_set_bus_speed(bus, speed);
341 
342 	/* enable lpi2c in master mode */
343 	val = readl(&regs->mcr) & ~LPI2C_MCR_MEN_MASK;
344 	writel(val | LPI2C_MCR_MEN(1), &regs->mcr);
345 
346 	debug("i2c : controller bus %d, speed %d:\n", bus->seq, speed);
347 
348 	return ret;
349 }
350 
351 static int imx_lpi2c_probe_chip(struct udevice *bus, u32 chip,
352 				u32 chip_flags)
353 {
354 	struct imx_lpi2c_reg *regs;
355 	lpi2c_status_t result;
356 
357 	regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
358 	result = bus_i2c_start(regs, chip, 0);
359 	if (result) {
360 		bus_i2c_stop(regs);
361 		bus_i2c_init(bus, 100000);
362 		return result;
363 	}
364 
365 	result = bus_i2c_stop(regs);
366 	if (result) {
367 		bus_i2c_init(bus, 100000);
368 		return -result;
369 	}
370 
371 	return result;
372 }
373 
374 static int imx_lpi2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
375 {
376 	struct imx_lpi2c_reg *regs;
377 	int ret = 0;
378 
379 	regs = (struct imx_lpi2c_reg *)devfdt_get_addr(bus);
380 	for (; nmsgs > 0; nmsgs--, msg++) {
381 		debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
382 		if (msg->flags & I2C_M_RD)
383 			ret = bus_i2c_read(regs, msg->addr, msg->buf, msg->len);
384 		else {
385 			ret = bus_i2c_write(regs, msg->addr, msg->buf,
386 					    msg->len);
387 			if (ret)
388 				break;
389 		}
390 	}
391 
392 	if (ret)
393 		debug("i2c_write: error sending\n");
394 
395 	return ret;
396 }
397 
398 static int imx_lpi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
399 {
400 	return bus_i2c_set_bus_speed(bus, speed);
401 }
402 
403 static int imx_lpi2c_probe(struct udevice *bus)
404 {
405 	struct imx_lpi2c_bus *i2c_bus = dev_get_priv(bus);
406 	fdt_addr_t addr;
407 	int ret;
408 
409 	i2c_bus->driver_data = dev_get_driver_data(bus);
410 
411 	addr = devfdt_get_addr(bus);
412 	if (addr == FDT_ADDR_T_NONE)
413 		return -EINVAL;
414 
415 	i2c_bus->base = addr;
416 	i2c_bus->index = bus->seq;
417 	i2c_bus->bus = bus;
418 
419 	/* power up i2c resource */
420 	ret = init_i2c_power(bus->seq);
421 	if (ret) {
422 		debug("init_i2c_power err = %d\n", ret);
423 		return ret;
424 	}
425 
426 	/* To i.MX7ULP, only i2c4-7 can be handled by A7 core */
427 	ret = enable_i2c_clk(1, bus->seq);
428 	if (ret < 0)
429 		return ret;
430 
431 	ret = bus_i2c_init(bus, 100000);
432 	if (ret < 0)
433 		return ret;
434 
435 	debug("i2c : controller bus %d at %lu , speed %d: ",
436 	      bus->seq, i2c_bus->base,
437 	      i2c_bus->speed);
438 
439 	return 0;
440 }
441 
442 static const struct dm_i2c_ops imx_lpi2c_ops = {
443 	.xfer		= imx_lpi2c_xfer,
444 	.probe_chip	= imx_lpi2c_probe_chip,
445 	.set_bus_speed	= imx_lpi2c_set_bus_speed,
446 };
447 
448 static const struct udevice_id imx_lpi2c_ids[] = {
449 	{ .compatible = "fsl,imx7ulp-lpi2c", },
450 	{}
451 };
452 
453 U_BOOT_DRIVER(imx_lpi2c) = {
454 	.name = "imx_lpi2c",
455 	.id = UCLASS_I2C,
456 	.of_match = imx_lpi2c_ids,
457 	.probe = imx_lpi2c_probe,
458 	.priv_auto_alloc_size = sizeof(struct imx_lpi2c_bus),
459 	.ops = &imx_lpi2c_ops,
460 };
461