1 /* $NetBSD: rk_i2c.c,v 1.12 2021/11/13 01:08:15 jmcneill Exp $ */
2
3 /*-
4 * Copyright (c) 2018 Jared McNeill <jmcneill@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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30
31 __KERNEL_RCSID(0, "$NetBSD: rk_i2c.c,v 1.12 2021/11/13 01:08:15 jmcneill Exp $");
32
33 #include <sys/param.h>
34 #include <sys/bus.h>
35 #include <sys/device.h>
36 #include <sys/intr.h>
37 #include <sys/systm.h>
38 #include <sys/time.h>
39 #include <sys/kmem.h>
40
41 #include <dev/i2c/i2cvar.h>
42
43 #include <dev/fdt/fdtvar.h>
44
45 #define RKI2C_CON 0x000
46 #define RKI2C_CON_ACT2NAK __BIT(6)
47 #define RKI2C_CON_ACK __BIT(5)
48 #define RKI2C_CON_STOP __BIT(4)
49 #define RKI2C_CON_START __BIT(3)
50 #define RKI2C_CON_I2C_MODE __BITS(2,1)
51 #define RKI2C_CON_I2C_MODE_TX 0
52 #define RKI2C_CON_I2C_MODE_RTX 1
53 #define RKI2C_CON_I2C_MODE_RX 2
54 #define RKI2C_CON_I2C_MODE_RRX 3
55 #define RKI2C_CON_I2C_EN __BIT(0)
56
57 #define RKI2C_CLKDIV 0x004
58 #define RKI2C_CLKDIV_CLKDIVH __BITS(31,16)
59 #define RKI2C_CLKDIV_CLKDIVL __BITS(15,0)
60
61 #define RKI2C_MRXADDR 0x008
62 #define RKI2C_MRXADDR_ADDHVLD __BIT(26)
63 #define RKI2C_MRXADDR_ADDMVLD __BIT(25)
64 #define RKI2C_MRXADDR_ADDLVLD __BIT(24)
65 #define RKI2C_MRXADDR_SADDR __BITS(23,0)
66
67 #define RKI2C_MRXRADDR 0x00c
68 #define RKI2C_MRXRADDR_ADDHVLD __BIT(26)
69 #define RKI2C_MRXRADDR_ADDMVLD __BIT(25)
70 #define RKI2C_MRXRADDR_ADDLVLD __BIT(24)
71 #define RKI2C_MRXRADDR_SADDR __BITS(23,0)
72
73 #define RKI2C_MTXCNT 0x010
74 #define RKI2C_MTXCNT_MTXCNT __BITS(5,0)
75
76 #define RKI2C_MRXCNT 0x014
77 #define RKI2C_MRXCNT_MRXCNT __BITS(5,0)
78
79 #define RKI2C_IEN 0x018
80 #define RKI2C_IEN_NAKRCVIEN __BIT(6)
81 #define RKI2C_IEN_STOPIEN __BIT(5)
82 #define RKI2C_IEN_STARTIEN __BIT(4)
83 #define RKI2C_IEN_MBRFIEN __BIT(3)
84 #define RKI2C_IEN_MBTFIEN __BIT(2)
85 #define RKI2C_IEN_BRFIEN __BIT(1)
86 #define RKI2C_IEN_BTFIEN __BIT(0)
87
88 #define RKI2C_IPD 0x01c
89 #define RKI2C_IPD_NAKRCVIPD __BIT(6)
90 #define RKI2C_IPD_STOPIPD __BIT(5)
91 #define RKI2C_IPD_STARTIPD __BIT(4)
92 #define RKI2C_IPD_MBRFIPD __BIT(3)
93 #define RKI2C_IPD_MBTFIPD __BIT(2)
94 #define RKI2C_IPD_BRFIPD __BIT(1)
95 #define RKI2C_IPD_BTFIPD __BIT(0)
96
97 #define RKI2C_FCNT 0x020
98 #define RKI2C_FCNT_FCNT __BITS(5,0)
99
100 #define RKI2C_TXDATA(n) (0x100 + (n) * 4)
101 #define RKI2C_RXDATA(n) (0x200 + (n) * 4)
102
103 /* Compat data flags */
104 #define RKI2C_HAS_PCLK __BIT(0)
105
106 static const struct device_compatible_entry compat_data[] = {
107 { .compat = "rockchip,rk3288-i2c", .value = 0 },
108 { .compat = "rockchip,rk3399-i2c", .value = RKI2C_HAS_PCLK },
109 DEVICE_COMPAT_EOL
110 };
111
112 struct rk_i2c_softc {
113 device_t sc_dev;
114 bus_space_tag_t sc_bst;
115 bus_space_handle_t sc_bsh;
116 struct clk *sc_sclk;
117 struct clk *sc_pclk;
118
119 u_int sc_clkfreq;
120
121 struct i2c_controller sc_ic;
122 };
123
124 #define RD4(sc, reg) \
125 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
126 #define WR4(sc, reg, val) \
127 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
128
129 static void
rk_i2c_init(struct rk_i2c_softc * sc)130 rk_i2c_init(struct rk_i2c_softc *sc)
131 {
132 int div, divl, divh;
133 u_int rate;
134
135 /*
136 * SCL frequency is calculated by the following formula:
137 *
138 * SCL Divisor = 8 * (CLKDIVL + 1 + CLKDIVH + 1)
139 * SCL = PCLK / SCLK Divisor
140 */
141
142 rate = clk_get_rate(sc->sc_sclk);
143 div = howmany(rate, sc->sc_clkfreq * 8) - 2;
144 if (div >= 0) {
145 divl = div / 2;
146 if (div % 2 == 0)
147 divh = divl;
148 else
149 divh = howmany(div, 2);
150 } else {
151 divl = divh = 0;
152 }
153
154 WR4(sc, RKI2C_CLKDIV,
155 __SHIFTIN(divh, RKI2C_CLKDIV_CLKDIVH) |
156 __SHIFTIN(divl, RKI2C_CLKDIV_CLKDIVL));
157
158 /*
159 * Disable the module until we are ready to use it.
160 */
161 WR4(sc, RKI2C_CON, 0);
162 WR4(sc, RKI2C_IEN, 0);
163 WR4(sc, RKI2C_IPD, RD4(sc, RKI2C_IPD));
164 }
165
166 static int
rk_i2c_wait(struct rk_i2c_softc * sc,uint32_t mask)167 rk_i2c_wait(struct rk_i2c_softc *sc, uint32_t mask)
168 {
169 u_int timeo = 100000;
170 uint32_t val;
171
172 const uint32_t ipdmask = mask | RKI2C_IPD_NAKRCVIPD;
173 do {
174 val = RD4(sc, RKI2C_IPD);
175 if (val & ipdmask)
176 break;
177 delay(1);
178 } while (--timeo > 0);
179
180 WR4(sc, RKI2C_IPD, val & ipdmask);
181
182 if ((val & RKI2C_IPD_NAKRCVIPD) != 0)
183 return EIO;
184 if ((val & mask) != 0)
185 return 0;
186
187 return ETIMEDOUT;
188 }
189
190 static int
rk_i2c_start(struct rk_i2c_softc * sc)191 rk_i2c_start(struct rk_i2c_softc *sc)
192 {
193 uint32_t con;
194 int error;
195
196 /* Send start */
197 con = RD4(sc, RKI2C_CON);
198 con |= RKI2C_CON_START;
199 WR4(sc, RKI2C_CON, con);
200
201 if ((error = rk_i2c_wait(sc, RKI2C_IPD_STARTIPD)) != 0)
202 return error;
203
204 con &= ~RKI2C_CON_START;
205 WR4(sc, RKI2C_CON, con);
206
207 return 0;
208 }
209
210 static int
rk_i2c_stop(struct rk_i2c_softc * sc)211 rk_i2c_stop(struct rk_i2c_softc *sc)
212 {
213 uint32_t con;
214 int error;
215
216 /* Send start */
217 con = RD4(sc, RKI2C_CON);
218 con |= RKI2C_CON_STOP;
219 WR4(sc, RKI2C_CON, con);
220
221 if ((error = rk_i2c_wait(sc, RKI2C_IPD_STOPIPD)) != 0)
222 return error;
223
224 con &= ~RKI2C_CON_STOP;
225 WR4(sc, RKI2C_CON, con);
226
227 return 0;
228 }
229
230 static int
rk_i2c_write(struct rk_i2c_softc * sc,i2c_addr_t addr,const uint8_t * cmd,size_t cmdlen,const uint8_t * buf,size_t buflen,int flags,bool send_start)231 rk_i2c_write(struct rk_i2c_softc *sc, i2c_addr_t addr, const uint8_t *cmd,
232 size_t cmdlen, const uint8_t *buf, size_t buflen, int flags, bool send_start)
233 {
234 union {
235 uint8_t data8[32];
236 uint32_t data32[8];
237 } txdata;
238 uint32_t con;
239 u_int mode;
240 int error;
241 size_t len;
242
243 len = cmdlen + buflen;
244 if (len > 31)
245 return EINVAL;
246
247 mode = RKI2C_CON_I2C_MODE_TX;
248 con = RKI2C_CON_I2C_EN | __SHIFTIN(mode, RKI2C_CON_I2C_MODE);
249 WR4(sc, RKI2C_CON, con);
250
251 if (send_start && (error = rk_i2c_start(sc)) != 0)
252 return error;
253
254 /* Transmit data. Slave address goes in the lower 8 bits of TXDATA0 */
255 txdata.data8[0] = addr << 1;
256 memcpy(&txdata.data8[1], cmd, cmdlen);
257 memcpy(&txdata.data8[1 + cmdlen], buf, buflen);
258 #if _BYTE_ORDER == _BIG_ENDIAN
259 for (int i = 0; i < howmany(len + 1, 4); i++)
260 LE32TOH(txdata.data32[i]);
261 #endif
262 bus_space_write_region_4(sc->sc_bst, sc->sc_bsh, RKI2C_TXDATA(0),
263 txdata.data32, howmany(len + 1, 4));
264 WR4(sc, RKI2C_MTXCNT, __SHIFTIN(len + 1, RKI2C_MTXCNT_MTXCNT));
265
266 if ((error = rk_i2c_wait(sc, RKI2C_IPD_MBTFIPD)) != 0)
267 return error;
268
269 return 0;
270 }
271
272 static int
rk_i2c_read(struct rk_i2c_softc * sc,i2c_addr_t addr,const uint8_t * cmd,size_t cmdlen,uint8_t * buf,size_t buflen,int flags,bool send_start,bool last_ack)273 rk_i2c_read(struct rk_i2c_softc *sc, i2c_addr_t addr,
274 const uint8_t *cmd, size_t cmdlen, uint8_t *buf,
275 size_t buflen, int flags, bool send_start, bool last_ack)
276 {
277 uint32_t rxdata[8];
278 uint32_t con, mrxaddr, mrxraddr;
279 u_int mode;
280 int error, n;
281
282 if (buflen > 32)
283 return EINVAL;
284 if (cmdlen > 3)
285 return EINVAL;
286
287 mode = send_start ? RKI2C_CON_I2C_MODE_RTX : RKI2C_CON_I2C_MODE_RX;
288 con = RKI2C_CON_I2C_EN | __SHIFTIN(mode, RKI2C_CON_I2C_MODE);
289 WR4(sc, RKI2C_CON, con);
290
291 if (send_start && (error = rk_i2c_start(sc)) != 0)
292 return error;
293
294 if (send_start) {
295 mrxaddr = __SHIFTIN((addr << 1) | 1, RKI2C_MRXADDR_SADDR) |
296 RKI2C_MRXADDR_ADDLVLD;
297 WR4(sc, RKI2C_MRXADDR, mrxaddr);
298 for (n = 0, mrxraddr = 0; n < cmdlen; n++) {
299 mrxraddr |= cmd[n] << (n * 8);
300 mrxraddr |= (RKI2C_MRXRADDR_ADDLVLD << n);
301 }
302 WR4(sc, RKI2C_MRXRADDR, mrxraddr);
303 }
304
305 if (last_ack) {
306 con |= RKI2C_CON_ACK;
307 }
308 WR4(sc, RKI2C_CON, con);
309
310 /* Receive data. Slave address goes in the lower 8 bits of MRXADDR */
311 WR4(sc, RKI2C_MRXCNT, __SHIFTIN(buflen, RKI2C_MRXCNT_MRXCNT));
312 if ((error = rk_i2c_wait(sc, RKI2C_IPD_MBRFIPD)) != 0)
313 return error;
314
315 #if 0
316 bus_space_read_region_4(sc->sc_bst, sc->sc_bsh, RKI2C_RXDATA(0),
317 rxdata, howmany(buflen, 4));
318 #else
319 for (n = 0; n < roundup(buflen, 4); n += 4)
320 rxdata[n/4] = RD4(sc, RKI2C_RXDATA(n/4));
321 #endif
322
323 #if _BYTE_ORDER == _BIG_ENDIAN
324 for (int i = 0; i < howmany(buflen, 4); i++)
325 HTOLE32(rxdata[i]);
326 #endif
327
328 memcpy(buf, rxdata, buflen);
329
330 return 0;
331 }
332
333 static int
rk_i2c_exec(void * priv,i2c_op_t op,i2c_addr_t addr,const void * cmdbuf,size_t cmdlen,void * buf,size_t buflen,int flags)334 rk_i2c_exec(void *priv, i2c_op_t op, i2c_addr_t addr,
335 const void *cmdbuf, size_t cmdlen, void *buf, size_t buflen, int flags)
336 {
337 struct rk_i2c_softc * const sc = priv;
338 bool send_start = true;
339 int error;
340
341 if (I2C_OP_READ_P(op)) {
342 uint8_t *databuf = buf;
343 while (buflen > 0) {
344 const size_t datalen = uimin(buflen, 32);
345 const bool last_ack = datalen == buflen;
346 error = rk_i2c_read(sc, addr, cmdbuf, cmdlen, databuf, datalen, flags, send_start, last_ack);
347 if (error != 0)
348 break;
349 databuf += datalen;
350 buflen -= datalen;
351 send_start = false;
352 cmdbuf = NULL;
353 cmdlen = 0;
354 }
355 } else {
356 error = rk_i2c_write(sc, addr, cmdbuf, cmdlen, buf, buflen, flags, send_start);
357 }
358
359 if (error != 0 || I2C_OP_STOP_P(op))
360 rk_i2c_stop(sc);
361
362 WR4(sc, RKI2C_CON, 0);
363 WR4(sc, RKI2C_IPD, RD4(sc, RKI2C_IPD));
364
365 return error;
366 }
367
368 static int
rk_i2c_match(device_t parent,cfdata_t cf,void * aux)369 rk_i2c_match(device_t parent, cfdata_t cf, void *aux)
370 {
371 struct fdt_attach_args * const faa = aux;
372
373 return of_compatible_match(faa->faa_phandle, compat_data);
374 }
375
376 static void
rk_i2c_attach(device_t parent,device_t self,void * aux)377 rk_i2c_attach(device_t parent, device_t self, void *aux)
378 {
379 struct rk_i2c_softc * const sc = device_private(self);
380 struct fdt_attach_args * const faa = aux;
381 const int phandle = faa->faa_phandle;
382 bus_addr_t addr;
383 bus_size_t size;
384 u_int flags;
385
386 if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
387 aprint_error(": couldn't get registers\n");
388 return;
389 }
390
391 flags = of_compatible_lookup(phandle, compat_data)->value;
392
393 sc->sc_sclk = fdtbus_clock_get(phandle, "i2c");
394 if (sc->sc_sclk == NULL || clk_enable(sc->sc_sclk) != 0) {
395 aprint_error(": couldn't enable sclk\n");
396 return;
397 }
398
399 if (ISSET(flags, RKI2C_HAS_PCLK)) {
400 sc->sc_pclk = fdtbus_clock_get(phandle, "pclk");
401 if (sc->sc_pclk == NULL || clk_enable(sc->sc_pclk) != 0) {
402 aprint_error(": couldn't enable pclk\n");
403 return;
404 }
405 }
406
407 if (of_getprop_uint32(phandle, "clock-frequency", &sc->sc_clkfreq))
408 sc->sc_clkfreq = 100000;
409
410 sc->sc_dev = self;
411 sc->sc_bst = faa->faa_bst;
412 if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
413 aprint_error(": couldn't map registers\n");
414 return;
415 }
416
417 aprint_naive("\n");
418 aprint_normal(": Rockchip I2C (%u Hz)\n", sc->sc_clkfreq);
419
420 fdtbus_clock_assign(phandle);
421
422 rk_i2c_init(sc);
423
424 iic_tag_init(&sc->sc_ic);
425 sc->sc_ic.ic_cookie = sc;
426 sc->sc_ic.ic_exec = rk_i2c_exec;
427
428 fdtbus_register_i2c_controller(&sc->sc_ic, phandle);
429
430 fdtbus_attach_i2cbus(self, phandle, &sc->sc_ic, iicbus_print);
431 }
432
433 CFATTACH_DECL_NEW(rk_i2c, sizeof(struct rk_i2c_softc),
434 rk_i2c_match, rk_i2c_attach, NULL, NULL);
435