tegra_i2c.c revision 1.9 1 /* $NetBSD: tegra_i2c.c,v 1.9 2015/12/13 17:39:19 jmcneill Exp $ */
2
3 /*-
4 * Copyright (c) 2015 Jared D. McNeill <jmcneill (at) invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 __KERNEL_RCSID(0, "$NetBSD: tegra_i2c.c,v 1.9 2015/12/13 17:39:19 jmcneill Exp $");
31
32 #include <sys/param.h>
33 #include <sys/bus.h>
34 #include <sys/device.h>
35 #include <sys/intr.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38
39 #include <dev/i2c/i2cvar.h>
40
41 #include <arm/nvidia/tegra_reg.h>
42 #include <arm/nvidia/tegra_i2creg.h>
43 #include <arm/nvidia/tegra_var.h>
44
45 #include <dev/fdt/fdtvar.h>
46
47 /* XXX */
48 static int
49 tegra_i2c_addr2port(bus_addr_t addr)
50 {
51 switch (addr) {
52 case TEGRA_APB_BASE + TEGRA_I2C1_OFFSET:
53 return 0;
54 case TEGRA_APB_BASE + TEGRA_I2C2_OFFSET:
55 return 1;
56 case TEGRA_APB_BASE + TEGRA_I2C3_OFFSET:
57 return 2;
58 case TEGRA_APB_BASE + TEGRA_I2C4_OFFSET:
59 return 3;
60 case TEGRA_APB_BASE + TEGRA_I2C5_OFFSET:
61 return 4;
62 case TEGRA_APB_BASE + TEGRA_I2C6_OFFSET:
63 return 5;
64 default:
65 return -1;
66 }
67 }
68
69 static int tegra_i2c_match(device_t, cfdata_t, void *);
70 static void tegra_i2c_attach(device_t, device_t, void *);
71
72 static i2c_tag_t tegra_i2c_get_tag(device_t);
73
74 struct fdtbus_i2c_controller_func tegra_i2c_funcs = {
75 .get_tag = tegra_i2c_get_tag
76 };
77
78 struct tegra_i2c_softc {
79 device_t sc_dev;
80 bus_space_tag_t sc_bst;
81 bus_space_handle_t sc_bsh;
82 void * sc_ih;
83 u_int sc_port;
84
85 struct i2c_controller sc_ic;
86 kmutex_t sc_lock;
87 kcondvar_t sc_cv;
88 device_t sc_i2cdev;
89 };
90
91 static void tegra_i2c_init(struct tegra_i2c_softc *);
92 static int tegra_i2c_intr(void *);
93
94 static int tegra_i2c_acquire_bus(void *, int);
95 static void tegra_i2c_release_bus(void *, int);
96 static int tegra_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
97 size_t, void *, size_t, int);
98
99 static int tegra_i2c_wait(struct tegra_i2c_softc *, int);
100 static int tegra_i2c_write(struct tegra_i2c_softc *, i2c_addr_t,
101 const uint8_t *, size_t, int, bool);
102 static int tegra_i2c_read(struct tegra_i2c_softc *, i2c_addr_t, uint8_t *,
103 size_t, int);
104
105 CFATTACH_DECL_NEW(tegra_i2c, sizeof(struct tegra_i2c_softc),
106 tegra_i2c_match, tegra_i2c_attach, NULL, NULL);
107
108 #define I2C_WRITE(sc, reg, val) \
109 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
110 #define I2C_READ(sc, reg) \
111 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
112 #define I2C_SET_CLEAR(sc, reg, setval, clrval) \
113 tegra_reg_set_clear((sc)->sc_bst, (sc)->sc_bsh, (reg), (setval), (clrval))
114
115 static int
116 tegra_i2c_match(device_t parent, cfdata_t cf, void *aux)
117 {
118 const char * const compatible[] = { "nvidia,tegra124-i2c", NULL };
119 struct fdt_attach_args * const faa = aux;
120
121 return of_match_compatible(faa->faa_phandle, compatible);
122 }
123
124 static void
125 tegra_i2c_attach(device_t parent, device_t self, void *aux)
126 {
127 struct tegra_i2c_softc * const sc = device_private(self);
128 struct fdt_attach_args * const faa = aux;
129 struct i2cbus_attach_args iba;
130 prop_dictionary_t devs;
131 char intrstr[128];
132 bus_addr_t addr;
133 bus_size_t size;
134 u_int address_cells;
135 int len, error;
136
137 if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
138 aprint_error(": couldn't get registers\n");
139 return;
140 }
141
142 sc->sc_dev = self;
143 sc->sc_bst = faa->faa_bst;
144 error = bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh);
145 if (error) {
146 aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
147 return;
148 }
149 sc->sc_port = tegra_i2c_addr2port(addr);
150 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_VM);
151 cv_init(&sc->sc_cv, device_xname(self));
152
153 aprint_naive("\n");
154 aprint_normal(": I2C%d\n", sc->sc_port + 1);
155
156 if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
157 aprint_error_dev(self, "failed to decode interrupt\n");
158 return;
159 }
160
161 sc->sc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_VM,
162 FDT_INTR_MPSAFE, tegra_i2c_intr, sc);
163 if (sc->sc_ih == NULL) {
164 aprint_error_dev(self, "couldn't establish interrupt on %s\n",
165 intrstr);
166 return;
167 }
168 aprint_normal_dev(self, "interrupting on %s\n", intrstr);
169
170 /*
171 * Recommended setting for standard mode is to use an I2C source div
172 * of 20 (Tegra K1 Technical Reference Manual, Table 137)
173 */
174 tegra_car_periph_i2c_enable(sc->sc_port, 20400000);
175
176 tegra_i2c_init(sc);
177
178 sc->sc_ic.ic_cookie = sc;
179 sc->sc_ic.ic_acquire_bus = tegra_i2c_acquire_bus;
180 sc->sc_ic.ic_release_bus = tegra_i2c_release_bus;
181 sc->sc_ic.ic_exec = tegra_i2c_exec;
182
183 fdtbus_register_i2c_controller(self, faa->faa_phandle,
184 &tegra_i2c_funcs);
185
186 devs = prop_dictionary_create();
187 len = OF_getprop(faa->faa_phandle, "#address-cells",
188 &address_cells, sizeof(address_cells));
189 if (len == sizeof(address_cells)) {
190 address_cells = be32toh(address_cells);
191 } else {
192 address_cells = 1;
193 }
194 of_enter_i2c_devs(devs, faa->faa_phandle, address_cells * 4, 0);
195
196 iba.iba_tag = &sc->sc_ic;
197 iba.iba_child_devices = prop_dictionary_get(devs, "i2c-child-devices");
198 if (iba.iba_child_devices != NULL) {
199 prop_object_retain(iba.iba_child_devices);
200 } else {
201 iba.iba_child_devices = prop_array_create();
202 }
203 prop_object_release(devs);
204
205 sc->sc_i2cdev = config_found_ia(self, "i2cbus", &iba, iicbus_print);
206 }
207
208 static i2c_tag_t
209 tegra_i2c_get_tag(device_t dev)
210 {
211 struct tegra_i2c_softc * const sc = device_private(dev);
212
213 return &sc->sc_ic;
214 }
215
216 static void
217 tegra_i2c_init(struct tegra_i2c_softc *sc)
218 {
219 int retry = 10000;
220
221 I2C_WRITE(sc, I2C_CLK_DIVISOR_REG,
222 __SHIFTIN(0x19, I2C_CLK_DIVISOR_STD_FAST_MODE) |
223 __SHIFTIN(0x1, I2C_CLK_DIVISOR_HSMODE));
224
225 I2C_WRITE(sc, I2C_INTERRUPT_MASK_REG, 0);
226 I2C_WRITE(sc, I2C_CNFG_REG,
227 I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN);
228 I2C_SET_CLEAR(sc, I2C_SL_CNFG_REG, I2C_SL_CNFG_NEWSL, 0);
229 I2C_WRITE(sc, I2C_FIFO_CONTROL_REG,
230 __SHIFTIN(7, I2C_FIFO_CONTROL_TX_FIFO_TRIG) |
231 __SHIFTIN(0, I2C_FIFO_CONTROL_RX_FIFO_TRIG));
232
233 I2C_WRITE(sc, I2C_BUS_CONFIG_LOAD_REG,
234 I2C_BUS_CONFIG_LOAD_MSTR_CONFIG_LOAD);
235 while (--retry > 0) {
236 if (I2C_READ(sc, I2C_BUS_CONFIG_LOAD_REG) == 0)
237 break;
238 delay(10);
239 }
240 if (retry == 0) {
241 device_printf(sc->sc_dev, "config load timeout\n");
242 }
243 }
244
245 static int
246 tegra_i2c_intr(void *priv)
247 {
248 struct tegra_i2c_softc * const sc = priv;
249
250 const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG);
251 if (istatus == 0)
252 return 0;
253 I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus);
254
255 mutex_enter(&sc->sc_lock);
256 cv_broadcast(&sc->sc_cv);
257 mutex_exit(&sc->sc_lock);
258
259 return 1;
260 }
261
262 static int
263 tegra_i2c_acquire_bus(void *priv, int flags)
264 {
265 struct tegra_i2c_softc * const sc = priv;
266
267 mutex_enter(&sc->sc_lock);
268
269 return 0;
270 }
271
272 static void
273 tegra_i2c_release_bus(void *priv, int flags)
274 {
275 struct tegra_i2c_softc * const sc = priv;
276
277 mutex_exit(&sc->sc_lock);
278 }
279
280 static int
281 tegra_i2c_exec(void *priv, i2c_op_t op, i2c_addr_t addr, const void *cmdbuf,
282 size_t cmdlen, void *buf, size_t buflen, int flags)
283 {
284 struct tegra_i2c_softc * const sc = priv;
285 int retry, error;
286
287 #if notyet
288 if (cold)
289 #endif
290 flags |= I2C_F_POLL;
291
292 KASSERT(mutex_owned(&sc->sc_lock));
293
294 if ((flags & I2C_F_POLL) == 0) {
295 I2C_WRITE(sc, I2C_INTERRUPT_MASK_REG,
296 I2C_INTERRUPT_MASK_NOACK | I2C_INTERRUPT_MASK_ARB_LOST |
297 I2C_INTERRUPT_MASK_TIMEOUT |
298 I2C_INTERRUPT_MASK_ALL_PACKETS_XFER_COMPLETE);
299 }
300
301 const uint32_t flush_mask =
302 I2C_FIFO_CONTROL_TX_FIFO_FLUSH | I2C_FIFO_CONTROL_RX_FIFO_FLUSH;
303
304 I2C_SET_CLEAR(sc, I2C_FIFO_CONTROL_REG, flush_mask, 0);
305 for (retry = 10000; retry > 0; retry--) {
306 const uint32_t v = I2C_READ(sc, I2C_FIFO_CONTROL_REG);
307 if ((v & flush_mask) == 0)
308 break;
309 delay(1);
310 }
311 if (retry == 0) {
312 device_printf(sc->sc_dev, "timeout flushing FIFO\n");
313 return EIO;
314 }
315
316 if (cmdlen > 0) {
317 error = tegra_i2c_write(sc, addr, cmdbuf, cmdlen, flags,
318 I2C_OP_READ_P(op) ? true : false);
319 if (error) {
320 goto done;
321 }
322 }
323
324 if (I2C_OP_READ_P(op)) {
325 error = tegra_i2c_read(sc, addr, buf, buflen, flags);
326 } else {
327 error = tegra_i2c_write(sc, addr, buf, buflen, flags, false);
328 }
329
330 done:
331 if ((flags & I2C_F_POLL) == 0) {
332 I2C_WRITE(sc, I2C_INTERRUPT_MASK_REG, 0);
333 }
334
335 if (error) {
336 tegra_i2c_init(sc);
337 }
338
339 return error;
340 }
341
342 static int
343 tegra_i2c_wait(struct tegra_i2c_softc *sc, int flags)
344 {
345 int error, retry;
346 uint32_t stat = 0;
347
348 retry = (flags & I2C_F_POLL) ? 100000 : 100;
349
350 while (--retry > 0) {
351 if ((flags & I2C_F_POLL) == 0) {
352 error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock,
353 max(mstohz(10), 1));
354 if (error) {
355 return error;
356 }
357 }
358 stat = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG);
359 if (stat & I2C_INTERRUPT_STATUS_PACKET_XFER_COMPLETE) {
360 break;
361 }
362 if (flags & I2C_F_POLL) {
363 delay(10);
364 }
365 }
366 if (retry == 0) {
367 stat = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG);
368 device_printf(sc->sc_dev, "timed out, status = %#x\n", stat);
369 return ETIMEDOUT;
370 }
371
372 const uint32_t err_mask =
373 I2C_INTERRUPT_STATUS_NOACK |
374 I2C_INTERRUPT_STATUS_ARB_LOST |
375 I2C_INTERRUPT_MASK_TIMEOUT;
376
377 if (stat & err_mask) {
378 device_printf(sc->sc_dev, "error, status = %#x\n", stat);
379 return EIO;
380 }
381
382 return 0;
383 }
384
385 static int
386 tegra_i2c_write(struct tegra_i2c_softc *sc, i2c_addr_t addr, const uint8_t *buf,
387 size_t buflen, int flags, bool repeat_start)
388 {
389 const uint8_t *p = buf;
390 size_t n, resid = buflen;
391 uint32_t data;
392 int retry;
393
394 const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG);
395 I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus);
396
397 /* Generic Header 0 */
398 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG,
399 __SHIFTIN(I2C_IOPACKET_WORD0_PROTHDRSZ_REQ,
400 I2C_IOPACKET_WORD0_PROTHDRSZ) |
401 __SHIFTIN(sc->sc_port, I2C_IOPACKET_WORD0_CONTROLLERID) |
402 __SHIFTIN(1, I2C_IOPACKET_WORD0_PKTID) |
403 __SHIFTIN(I2C_IOPACKET_WORD0_PROTOCOL_I2C,
404 I2C_IOPACKET_WORD0_PROTOCOL) |
405 __SHIFTIN(I2C_IOPACKET_WORD0_PKTTYPE_REQ,
406 I2C_IOPACKET_WORD0_PKTTYPE));
407 /* Generic Header 1 */
408 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG,
409 __SHIFTIN(buflen - 1, I2C_IOPACKET_WORD1_PAYLOADSIZE));
410 /* I2C Master Transmit Packet Header */
411 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG,
412 I2C_IOPACKET_XMITHDR_IE |
413 (repeat_start ? I2C_IOPACKET_XMITHDR_REPEAT_STARTSTOP : 0) |
414 __SHIFTIN((addr << 1), I2C_IOPACKET_XMITHDR_SLAVE_ADDR));
415
416 /* Transmit data */
417 while (resid > 0) {
418 retry = 10000;
419 while (--retry > 0) {
420 const uint32_t fs = I2C_READ(sc, I2C_FIFO_STATUS_REG);
421 const u_int cnt =
422 __SHIFTOUT(fs, I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT);
423 if (cnt > 0)
424 break;
425 delay(10);
426 }
427 if (retry == 0) {
428 device_printf(sc->sc_dev, "TX FIFO timeout\n");
429 return ETIMEDOUT;
430 }
431
432 for (n = 0, data = 0; n < min(resid, 4); n++) {
433 data |= (uint32_t)p[n] << (n * 8);
434 }
435 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG, data);
436 resid -= min(resid, 4);
437 p += min(resid, 4);
438 }
439
440 return tegra_i2c_wait(sc, flags);
441 }
442
443 static int
444 tegra_i2c_read(struct tegra_i2c_softc *sc, i2c_addr_t addr, uint8_t *buf,
445 size_t buflen, int flags)
446 {
447 uint8_t *p = buf;
448 size_t n, resid = buflen;
449 uint32_t data;
450 int retry;
451
452 const uint32_t istatus = I2C_READ(sc, I2C_INTERRUPT_STATUS_REG);
453 I2C_WRITE(sc, I2C_INTERRUPT_STATUS_REG, istatus);
454
455 /* Generic Header 0 */
456 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG,
457 __SHIFTIN(I2C_IOPACKET_WORD0_PROTHDRSZ_REQ,
458 I2C_IOPACKET_WORD0_PROTHDRSZ) |
459 __SHIFTIN(sc->sc_port, I2C_IOPACKET_WORD0_CONTROLLERID) |
460 __SHIFTIN(1, I2C_IOPACKET_WORD0_PKTID) |
461 __SHIFTIN(I2C_IOPACKET_WORD0_PROTOCOL_I2C,
462 I2C_IOPACKET_WORD0_PROTOCOL) |
463 __SHIFTIN(I2C_IOPACKET_WORD0_PKTTYPE_REQ,
464 I2C_IOPACKET_WORD0_PKTTYPE));
465 /* Generic Header 1 */
466 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG,
467 __SHIFTIN(buflen - 1, I2C_IOPACKET_WORD1_PAYLOADSIZE));
468 /* I2C Master Transmit Packet Header */
469 I2C_WRITE(sc, I2C_TX_PACKET_FIFO_REG,
470 I2C_IOPACKET_XMITHDR_IE | I2C_IOPACKET_XMITHDR_READ |
471 __SHIFTIN((addr << 1) | 1, I2C_IOPACKET_XMITHDR_SLAVE_ADDR));
472
473 while (resid > 0) {
474 retry = 10000;
475 while (--retry > 0) {
476 const uint32_t fs = I2C_READ(sc, I2C_FIFO_STATUS_REG);
477 const u_int cnt =
478 __SHIFTOUT(fs, I2C_FIFO_STATUS_RX_FIFO_FULL_CNT);
479 if (cnt > 0)
480 break;
481 delay(10);
482 }
483 if (retry == 0) {
484 device_printf(sc->sc_dev, "RX FIFO timeout\n");
485 return ETIMEDOUT;
486 }
487
488 data = I2C_READ(sc, I2C_RX_FIFO_REG);
489 for (n = 0; n < min(resid, 4); n++) {
490 p[n] = (data >> (n * 8)) & 0xff;
491 }
492 resid -= min(resid, 4);
493 p += min(resid, 4);
494 }
495
496 return tegra_i2c_wait(sc, flags);
497 }
498
499 void
500 tegra_i2c_dvc_write(uint8_t addr, uint32_t data, size_t datalen)
501 {
502 bus_space_tag_t bst = &armv7_generic_bs_tag;
503 bus_space_handle_t bsh;
504
505 bus_space_subregion(bst, tegra_apb_bsh, TEGRA_I2C5_OFFSET,
506 TEGRA_I2C5_SIZE, &bsh);
507
508 bus_space_write_4(bst, bsh, I2C_CMD_ADDR0_REG, addr << 1);
509 bus_space_write_4(bst, bsh, I2C_CMD_DATA1_REG, data);
510 bus_space_write_4(bst, bsh, I2C_CNFG_REG,
511 __SHIFTIN(datalen - 1, I2C_CNFG_LENGTH) |
512 I2C_CNFG_NEW_MASTER_FSM |
513 I2C_CNFG_SEND);
514 }
515