xref: /openbsd/sys/arch/octeon/dev/octiic.c (revision e5dd7070)
1 /*	$OpenBSD: octiic.c,v 1.1 2019/04/23 13:53:47 visa Exp $	*/
2 
3 /*
4  * Copyright (c) 2019 Visa Hankala
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * Driver for OCTEON two-wire serial interface core.
21  */
22 
23 #include <sys/param.h>
24 #include <sys/systm.h>
25 #include <sys/device.h>
26 #include <sys/stdint.h>
27 
28 #include <dev/i2c/i2cvar.h>
29 #include <dev/ofw/fdt.h>
30 #include <dev/ofw/openfirm.h>
31 
32 #include <machine/bus.h>
33 #include <machine/fdt.h>
34 #include <machine/octeonvar.h>
35 
36 struct octiic_softc {
37 	struct device		 sc_dev;
38 	int			 sc_node;
39 	bus_space_tag_t		 sc_iot;
40 	bus_space_handle_t	 sc_ioh;
41 
42 	struct i2c_controller	 sc_i2c_tag;
43 	struct rwlock		 sc_i2c_lock;
44 
45 	int			 sc_start_sent;
46 };
47 
48 int	octiic_match(struct device *, void *, void *);
49 void	octiic_attach(struct device *, struct device *, void *);
50 
51 int	octiic_i2c_acquire_bus(void *, int);
52 void	octiic_i2c_release_bus(void *, int);
53 int	octiic_i2c_send_start(void *, int);
54 int	octiic_i2c_send_stop(void *, int);
55 int	octiic_i2c_initiate_xfer(void *, i2c_addr_t, int);
56 int	octiic_i2c_read_byte(void *, uint8_t *, int);
57 int	octiic_i2c_write_byte(void *, uint8_t, int);
58 void	octiic_i2c_scan(struct device *, struct i2cbus_attach_args *, void *);
59 
60 int	octiic_reg_read(struct octiic_softc *, uint8_t, uint8_t *);
61 int	octiic_reg_write(struct octiic_softc *, uint8_t, uint8_t);
62 int	octiic_set_clock(struct octiic_softc *, uint32_t);
63 int	octiic_wait(struct octiic_softc *, uint8_t, int);
64 
65 const struct cfattach octiic_ca = {
66 	sizeof(struct octiic_softc), octiic_match, octiic_attach
67 };
68 
69 struct cfdriver octiic_cd = {
70 	NULL, "octiic", DV_DULL
71 };
72 
73 #define TWSI_RD_8(sc, reg) \
74 	bus_space_read_8((sc)->sc_iot, (sc)->sc_ioh, (reg))
75 #define TWSI_WR_8(sc, reg, val) \
76 	bus_space_write_8((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
77 
78 #define TWSI_SW_TWSI		0x00
79 #define   TWSI_SW_TWSI_V		0x8000000000000000ull
80 #define   TWSI_SW_TWSI_SLONLY		0x4000000000000000ull
81 #define   TWSI_SW_TWSI_EIA		0x2000000000000000ull
82 #define   TWSI_SW_TWSI_OP_M		0x1e00000000000000ull
83 #define   TWSI_SW_TWSI_OP_S		57
84 #define   TWSI_SW_TWSI_R                0x0100000000000000ull
85 #define   TWSI_SW_TWSI_SOVR		0x0080000000000000ull
86 #define   TWSI_SW_TWSI_SIZE_M		0x0070000000000000ull
87 #define   TWSI_SW_TWSI_SIZE_S		52
88 #define   TWSI_SW_TWSI_SCR_M		0x000c000000000000ull
89 #define   TWSI_SW_TWSI_SCR_S		50
90 #define   TWSI_SW_TWSI_A_M		0x0003ff0000000000ull
91 #define   TWSI_SW_TWSI_A_S		40
92 #define   TWSI_SW_TWSI_IA_M		0x000000f800000000ull
93 #define   TWSI_SW_TWSI_IA_S		35
94 #define   TWSI_SW_TWSI_EOP_IA_M		0x0000000700000000ull
95 #define   TWSI_SW_TWSI_EOP_IA_S		32
96 #define   TWSI_SW_TWSI_D_M		0x00000000ffffffffull
97 
98 /* Opcodes for field TWSI_SW_TWSI_OP */
99 #define TWSI_OP_CLK			0x04
100 #define TWSI_OP_EOP			0x06
101 
102 /* Addresses for field TWSI_SW_TWSI_IA */
103 #define TWSI_IA_DATA			0x01
104 #define TWSI_IA_CTL			0x02
105 #define TWSI_IA_CLKCTL			0x03	/* write only */
106 #define TWSI_IA_STAT			0x03	/* read only */
107 #define TWSI_IA_RST			0x07
108 
109 #define TWSI_INT		0x10
110 
111 /* Control register bits */
112 #define TWSI_CTL_CE			0x80
113 #define TWSI_CTL_ENAB			0x40
114 #define TWSI_CTL_STA			0x20
115 #define TWSI_CTL_STP			0x10
116 #define TWSI_CTL_IFLG			0x08
117 #define TWSI_CTL_AAK			0x04
118 
119 /* Core states */
120 #define TWSI_STAT_ERROR			0x00
121 #define TWSI_STAT_START			0x08
122 #define TWSI_STAT_RSTART		0x10
123 #define TWSI_STAT_AWT_ACK		0x18
124 #define TWSI_STAT_MBT_ACK		0x28
125 #define TWSI_STAT_ART_ACK		0x40
126 #define TWSI_STAT_MBR_ACK		0x50
127 #define TWSI_STAT_MBR_NAK		0x58
128 #define TWSI_STAT_IDLE			0xf8
129 
130 int
131 octiic_match(struct device *parent, void *match, void *aux)
132 {
133 	struct fdt_attach_args *fa = aux;
134 
135 	return OF_is_compatible(fa->fa_node, "cavium,octeon-3860-twsi") ||
136 	    OF_is_compatible(fa->fa_node, "cavium,octeon-7890-twsi");
137 }
138 
139 void
140 octiic_attach(struct device *parent, struct device *self, void *aux)
141 {
142 	struct i2cbus_attach_args iba;
143 	struct fdt_attach_args *faa = aux;
144 	struct octiic_softc *sc = (struct octiic_softc *)self;
145 	uint32_t freq;
146 
147 	sc->sc_node = faa->fa_node;
148 	sc->sc_iot = faa->fa_iot;
149 
150 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, faa->fa_reg[0].size,
151 	    0, &sc->sc_ioh)) {
152 		printf(": failed to map registers\n");
153 		return;
154 	}
155 
156 	freq = OF_getpropint(faa->fa_node, "clock-frequency", 100000);
157 	if (octiic_set_clock(sc, freq) != 0) {
158 		printf(": clock setup failed\n");
159 		return;
160 	}
161 
162 	/* Reset the controller. */
163 	if (octiic_reg_write(sc, TWSI_IA_RST, 0) != 0) {
164 		printf(": register write timeout\n");
165 		return;
166 	}
167 
168 	delay(1000);
169 
170 	if (octiic_wait(sc, TWSI_STAT_IDLE, I2C_F_POLL) != 0) {
171 		printf(": reset failed\n");
172 		return;
173 	}
174 
175 	printf("\n");
176 
177 	rw_init(&sc->sc_i2c_lock, "iiclk");
178 	sc->sc_i2c_tag.ic_cookie = sc;
179 	sc->sc_i2c_tag.ic_acquire_bus = octiic_i2c_acquire_bus;
180 	sc->sc_i2c_tag.ic_release_bus = octiic_i2c_release_bus;
181 	sc->sc_i2c_tag.ic_send_start = octiic_i2c_send_start;
182 	sc->sc_i2c_tag.ic_send_stop = octiic_i2c_send_stop;
183 	sc->sc_i2c_tag.ic_initiate_xfer = octiic_i2c_initiate_xfer;
184 	sc->sc_i2c_tag.ic_read_byte = octiic_i2c_read_byte;
185 	sc->sc_i2c_tag.ic_write_byte = octiic_i2c_write_byte;
186 
187 	memset(&iba, 0, sizeof(iba));
188 	iba.iba_name = "iic";
189 	iba.iba_tag = &sc->sc_i2c_tag;
190 	config_found(self, &iba, iicbus_print);
191 }
192 
193 int
194 octiic_i2c_acquire_bus(void *arg, int flags)
195 {
196 	struct octiic_softc *sc = arg;
197 
198 	if (cold || (flags & I2C_F_POLL))
199 		return 0;
200 
201 	return rw_enter(&sc->sc_i2c_lock, RW_WRITE | RW_INTR);
202 }
203 
204 void
205 octiic_i2c_release_bus(void *arg, int flags)
206 {
207 	struct octiic_softc *sc = arg;
208 
209 	if (cold || (flags & I2C_F_POLL))
210 		return;
211 
212 	rw_exit(&sc->sc_i2c_lock);
213 }
214 
215 int
216 octiic_i2c_send_start(void *cookie, int flags)
217 {
218 	struct octiic_softc *sc = cookie;
219 	int error;
220 	uint8_t nstate;
221 
222 	error = octiic_reg_write(sc, TWSI_IA_CTL, TWSI_CTL_ENAB | TWSI_CTL_STA);
223 	if (error != 0)
224 		return error;
225 
226 	delay(10);
227 
228 	if (sc->sc_start_sent)
229 		nstate = TWSI_STAT_RSTART;
230 	else
231 		nstate = TWSI_STAT_START;
232 	error = octiic_wait(sc, nstate, flags);
233 	if (error != 0)
234 		return error;
235 
236 	sc->sc_start_sent = 1;
237 
238 	return 0;
239 }
240 
241 int
242 octiic_i2c_send_stop(void *cookie, int flags)
243 {
244 	struct octiic_softc *sc = cookie;
245 
246 	sc->sc_start_sent = 0;
247 
248 	return octiic_reg_write(sc, TWSI_IA_CTL, TWSI_CTL_ENAB | TWSI_CTL_STP);
249 }
250 
251 int
252 octiic_i2c_initiate_xfer(void *cookie, i2c_addr_t addr, int flags)
253 {
254 	struct octiic_softc *sc = cookie;
255 	int error;
256 	uint8_t mode = 0, nstate;
257 
258 	error = octiic_i2c_send_start(sc, flags);
259 	if (error != 0)
260 		return error;
261 
262 	if (flags & I2C_F_READ)
263 		mode = 0x01;
264 	nstate = flags & I2C_F_READ ? TWSI_STAT_ART_ACK : TWSI_STAT_AWT_ACK;
265 
266 	/* Handle 10-bit addressing. */
267 	if (addr > 0x7f) {
268 		octiic_reg_write(sc, TWSI_IA_DATA, ((addr >> 7) << 1) | mode);
269 		octiic_reg_write(sc, TWSI_IA_CTL, TWSI_CTL_ENAB);
270 
271 		error = octiic_wait(sc, nstate, flags);
272 		if (error != 0)
273 			return error;
274 	}
275 
276 	octiic_reg_write(sc, TWSI_IA_DATA, ((addr & 0x7f) << 1) | mode);
277 	octiic_reg_write(sc, TWSI_IA_CTL, TWSI_CTL_ENAB);
278 
279 	error = octiic_wait(sc, nstate, flags);
280 	if (error != 0)
281 		return error;
282 
283 	return 0;
284 }
285 
286 int
287 octiic_i2c_read_byte(void *cookie, uint8_t *datap, int flags)
288 {
289 	struct octiic_softc *sc = cookie;
290 	int error;
291 	uint8_t ctl, nstate;
292 
293 	ctl = TWSI_CTL_ENAB;
294 	if ((flags & I2C_F_LAST) == 0)
295 		ctl |= TWSI_CTL_AAK;
296 	octiic_reg_write(sc, TWSI_IA_CTL, ctl);
297 
298 	nstate = flags & I2C_F_LAST ? TWSI_STAT_MBR_NAK : TWSI_STAT_MBR_ACK;
299 	error = octiic_wait(sc, nstate, flags);
300 	if (error != 0)
301 		return error;
302 
303 	octiic_reg_read(sc, TWSI_IA_DATA, datap);
304 
305 	if (flags & I2C_F_STOP)
306 		error = octiic_i2c_send_stop(sc, flags);
307 
308 	return 0;
309 }
310 
311 int
312 octiic_i2c_write_byte(void *cookie, uint8_t data, int flags)
313 {
314 	struct octiic_softc *sc = cookie;
315 	int error;
316 
317 	octiic_reg_write(sc, TWSI_IA_DATA, data);
318 	octiic_reg_write(sc, TWSI_IA_CTL, TWSI_CTL_ENAB);
319 
320 	error = octiic_wait(sc, TWSI_STAT_MBT_ACK, flags);
321 	if (error != 0)
322 		return error;
323 
324 	if (flags & I2C_F_STOP)
325 		error = octiic_i2c_send_stop(sc, flags);
326 
327 	return error;
328 }
329 
330 int
331 octiic_reg_read(struct octiic_softc *sc, uint8_t reg, uint8_t *pval)
332 {
333 	uint64_t data;
334 	int timeout;
335 
336 	TWSI_WR_8(sc, TWSI_SW_TWSI, TWSI_SW_TWSI_V | TWSI_SW_TWSI_R |
337 	    ((uint64_t)TWSI_OP_EOP << TWSI_SW_TWSI_OP_S) |
338 	    ((uint64_t)reg << TWSI_SW_TWSI_EOP_IA_S));
339 
340 	for (timeout = 100000; timeout > 0; timeout--) {
341 		data = TWSI_RD_8(sc, TWSI_SW_TWSI);
342 		if ((data & TWSI_SW_TWSI_V) == 0)
343 			break;
344 		delay(1);
345 	}
346 	if (timeout == 0)
347 		return ETIMEDOUT;
348 
349 	*pval = (uint8_t)data;
350 	return 0;
351 }
352 
353 int
354 octiic_reg_write(struct octiic_softc *sc, uint8_t reg, uint8_t val)
355 {
356 	uint64_t data;
357 	int timeout;
358 
359 	TWSI_WR_8(sc, TWSI_SW_TWSI, TWSI_SW_TWSI_V |
360 	    ((uint64_t)TWSI_OP_EOP << TWSI_SW_TWSI_OP_S) |
361 	    ((uint64_t)reg << TWSI_SW_TWSI_EOP_IA_S) | val);
362 
363 	for (timeout = 100000; timeout > 0; timeout--) {
364 		data = TWSI_RD_8(sc, TWSI_SW_TWSI);
365 		if ((data & TWSI_SW_TWSI_V) == 0)
366 			break;
367 		delay(1);
368 	}
369 	if (timeout == 0)
370 		return ETIMEDOUT;
371 
372 	return 0;
373 }
374 
375 /*
376  * Wait until the controller has finished current operation.
377  * Fail if the new state is not `nstate'.
378  */
379 int
380 octiic_wait(struct octiic_softc *sc, uint8_t nstate, int flags)
381 {
382 	uint8_t ctl, stat;
383 	int timeout;
384 
385 	for (timeout = 100000; timeout > 0; timeout--) {
386 		octiic_reg_read(sc, TWSI_IA_CTL, &ctl);
387 		if (ctl & TWSI_CTL_IFLG)
388 			break;
389 	}
390 
391 	octiic_reg_read(sc, TWSI_IA_STAT, &stat);
392 	if (stat != nstate)
393 		return EIO;
394 
395 	return 0;
396 }
397 
398 int
399 octiic_set_clock(struct octiic_softc *sc, uint32_t freq)
400 {
401 	uint64_t best_tclk = 0, tclk;
402 	uint64_t ioclk = octeon_ioclock_speed();
403 	int best_m = 2, best_n = 0, best_thp = 24;
404 	int m, n, thp;
405 
406 	/*
407 	 * Find a combination of clock dividers `thp', `m' and `n' that gives
408 	 * bus frequency close to but no more than `freq'.
409 	 */
410 #define TCLK(ioclk, thp, n, m) \
411     ((ioclk) / (20 * ((thp) + 1) * (1 << (n)) * ((m) + 1)))
412 	for (thp = 6; thp <= 72 && best_tclk < freq; thp <<= 1) {
413 		for (n = 7; n > 0; n--) {
414 			if (TCLK(ioclk, thp, n, 16) > freq)
415 				break;
416 		}
417 		for (m = 15; m > 2; m--) {
418 			if (TCLK(ioclk, thp, n, m - 1) > freq)
419 				break;
420 		}
421 
422 		tclk = TCLK(ioclk, thp, n, m);
423 		if (tclk <= freq && tclk > best_tclk) {
424 			best_tclk = tclk;
425 			best_thp = thp;
426 			best_m = m;
427 			best_n = n;
428 		}
429 	}
430 #undef TCLK
431 
432 	TWSI_WR_8(sc, TWSI_SW_TWSI, TWSI_SW_TWSI_V |
433 	    ((uint64_t)TWSI_OP_CLK << TWSI_SW_TWSI_OP_S) | best_thp);
434 
435 	octiic_reg_write(sc, TWSI_IA_CLKCTL, (best_m << 3) | best_n);
436 
437 	return 0;
438 }
439