xref: /openbsd-src/sys/dev/fdt/rkspi.c (revision 0f9e9ec23bb2b65cc62a3d17df12827a45dae80c)
1 /* $OpenBSD: rkspi.c,v 1.2 2024/05/13 01:15:50 jsg Exp $ */
2 /*
3  * Copyright (c) 2018,2023 Patrick Wildt <patrick@blueri.se>
4  * Copyright (c) 2024 Mark Kettenis <kettenis@openbsd.org>
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 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 
23 #include <machine/bus.h>
24 #include <machine/fdt.h>
25 
26 #include <dev/ofw/openfirm.h>
27 #include <dev/ofw/ofw_clock.h>
28 #include <dev/ofw/ofw_pinctrl.h>
29 #include <dev/ofw/fdt.h>
30 #include <dev/spi/spivar.h>
31 
32 /* registers */
33 #define SPI_CTRLR0			0x0000
34 #define  SPI_CTRLR0_DFS_4BIT			(0x0 << 0)
35 #define  SPI_CTRLR0_DFS_8BIT			(0x1 << 0)
36 #define  SPI_CTRLR0_DFS_16BIT			(0x2 << 0)
37 #define  SPI_CTRLR0_SCPH			(0x1 << 6)
38 #define  SPI_CTRLR0_SCPOL			(0x1 << 7)
39 #define  SPI_CTRLR0_CSM_KEEP			(0x0 << 8)
40 #define  SPI_CTRLR0_CSM_HALF			(0x1 << 8)
41 #define  SPI_CTRLR0_CSM_ONE			(0x2 << 8)
42 #define  SPI_CTRLR0_SSD_HALF			(0x0 << 10)
43 #define  SPI_CTRLR0_SSD_ONE			(0x1 << 10)
44 #define  SPI_CTRLR0_EM_LITTLE			(0x0 << 11)
45 #define  SPI_CTRLR0_EM_BIG			(0x1 << 11)
46 #define  SPI_CTRLR0_FBM_MSB			(0x0 << 12)
47 #define  SPI_CTRLR0_FBM_LSB			(0x1 << 12)
48 #define  SPI_CTRLR0_BHT_16BIT			(0x0 << 13)
49 #define  SPI_CTRLR0_BHT_8BIT			(0x1 << 13)
50 #define  SPI_CTRLR0_RSD(x)			((x) << 14)
51 #define  SPI_CTRLR0_FRF_SPI			(0x0 << 16)
52 #define  SPI_CTRLR0_FRF_SSP			(0x1 << 16)
53 #define  SPI_CTRLR0_FRF_MICROWIRE		(0x2 << 16)
54 #define  SPI_CTRLR0_XFM_TR			(0x0 << 18)
55 #define  SPI_CTRLR0_XFM_TO			(0x1 << 18)
56 #define  SPI_CTRLR0_XFM_RO			(0x2 << 18)
57 #define  SPI_CTRLR0_SOI(x)			((1 << (x)) << 23)
58 #define SPI_CTRLR1			0x0004
59 #define SPI_ENR				0x0008
60 #define SPI_SER				0x000c
61 #define  SPI_SER_CS(x)				((1 << (x)) << 0)
62 #define SPI_BAUDR			0x0010
63 #define SPI_TXFTLR			0x0014
64 #define SPI_RXFTLR			0x0018
65 #define SPI_TXFLR			0x001c
66 #define SPI_RXFLR			0x0020
67 #define SPI_SR				0x0024
68 #define  SPI_SR_BSF				(1 << 0)
69 #define  SPI_SR_TFF				(1 << 1)
70 #define  SPI_SR_TFE				(1 << 2)
71 #define  SPI_SR_RFE				(1 << 3)
72 #define  SPI_SR_RFF				(1 << 4)
73 #define SPI_IPR				0x0028
74 #define SPI_IMR				0x002c
75 #define SPI_ISR				0x0030
76 #define SPI_RISR			0x0034
77 #define SPI_ICR				0x0038
78 #define  SPI_ICR_MASK				(0x7f << 0)
79 #define SPI_DMACR			0x003c
80 #define SPI_DMATDLR			0x0040
81 #define SPI_DMARDLR			0x0044
82 #define SPI_VERSION			0x0048
83 #define SPI_TXDR			0x0400
84 #define SPI_RXDR			0x0800
85 
86 #define DEVNAME(sc)	((sc)->sc_dev.dv_xname)
87 
88 struct rkspi_softc {
89 	struct device		 sc_dev;
90 	bus_space_tag_t		 sc_iot;
91 	bus_space_handle_t	 sc_ioh;
92 	bus_size_t		 sc_ios;
93 	int			 sc_node;
94 
95 	struct rwlock		 sc_buslock;
96 	struct spi_controller	 sc_tag;
97 
98 	int			 sc_ridx;
99 	int			 sc_widx;
100 	int			 sc_cs;
101 	u_int			 sc_cs_delay;
102 	u_int			 sc_spi_freq;
103 };
104 
105 int	 rkspi_match(struct device *, void *, void *);
106 void	 rkspi_attach(struct device *, struct device *, void *);
107 int	 rkspi_detach(struct device *, int);
108 
109 void	 rkspi_config(void *, struct spi_config *);
110 int	 rkspi_transfer(void *, char *, char *, int, int);
111 int	 rkspi_acquire_bus(void *, int);
112 void	 rkspi_release_bus(void *, int);
113 
114 int	 rkspi_wait_state(struct rkspi_softc *, uint32_t, uint32_t);
115 
116 void	 rkspi_scan(struct rkspi_softc *);
117 
118 #define HREAD4(sc, reg)							\
119 	(bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)))
120 #define HWRITE4(sc, reg, val)						\
121 	bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
122 #define HSET4(sc, reg, bits)						\
123 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) | (bits))
124 #define HCLR4(sc, reg, bits)						\
125 	HWRITE4((sc), (reg), HREAD4((sc), (reg)) & ~(bits))
126 
127 const struct cfattach rkspi_ca = {
128 	sizeof(struct rkspi_softc), rkspi_match, rkspi_attach,
129 	rkspi_detach
130 };
131 
132 struct cfdriver rkspi_cd = {
133 	NULL, "rkspi", DV_DULL
134 };
135 
136 int
rkspi_match(struct device * parent,void * match,void * aux)137 rkspi_match(struct device *parent, void *match, void *aux)
138 {
139 	struct fdt_attach_args *faa = aux;
140 
141 	return OF_is_compatible(faa->fa_node, "rockchip,rk3066-spi");
142 }
143 
144 void
rkspi_attach(struct device * parent,struct device * self,void * aux)145 rkspi_attach(struct device *parent, struct device *self, void *aux)
146 {
147 	struct rkspi_softc *sc = (struct rkspi_softc *)self;
148 	struct fdt_attach_args *faa = aux;
149 
150 	if (faa->fa_nreg < 1)
151 		return;
152 
153 	sc->sc_iot = faa->fa_iot;
154 	sc->sc_ios = faa->fa_reg[0].size;
155 	sc->sc_node = faa->fa_node;
156 	if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr,
157 	    faa->fa_reg[0].size, 0, &sc->sc_ioh)) {
158 		printf(": can't map registers\n");
159 		return;
160 	}
161 
162 	pinctrl_byname(sc->sc_node, "default");
163 	clock_set_assigned(sc->sc_node);
164 	clock_enable(sc->sc_node, "apb_pclk");
165 	clock_enable(sc->sc_node, "spiclk");
166 
167 	sc->sc_spi_freq = clock_get_frequency(sc->sc_node, "spiclk");
168 
169 	printf("\n");
170 
171 	HWRITE4(sc, SPI_ENR, 0);
172 	HWRITE4(sc, SPI_DMACR, 0);
173 	HWRITE4(sc, SPI_DMATDLR, 0);
174 	HWRITE4(sc, SPI_DMARDLR, 0);
175 	HWRITE4(sc, SPI_IPR, 0);
176 	HWRITE4(sc, SPI_IMR, 0);
177 	HWRITE4(sc, SPI_ICR, SPI_ICR_MASK);
178 
179 	rw_init(&sc->sc_buslock, sc->sc_dev.dv_xname);
180 
181 	sc->sc_tag.sc_cookie = sc;
182 	sc->sc_tag.sc_config = rkspi_config;
183 	sc->sc_tag.sc_transfer = rkspi_transfer;
184 	sc->sc_tag.sc_acquire_bus = rkspi_acquire_bus;
185 	sc->sc_tag.sc_release_bus = rkspi_release_bus;
186 
187 	rkspi_scan(sc);
188 }
189 
190 int
rkspi_detach(struct device * self,int flags)191 rkspi_detach(struct device *self, int flags)
192 {
193 	struct rkspi_softc *sc = (struct rkspi_softc *)self;
194 
195 	HWRITE4(sc, SPI_ENR, 0);
196 	HWRITE4(sc, SPI_IMR, 0);
197 	bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios);
198 	return 0;
199 }
200 
201 void
rkspi_config(void * cookie,struct spi_config * conf)202 rkspi_config(void *cookie, struct spi_config *conf)
203 {
204 	struct rkspi_softc *sc = cookie;
205 	uint32_t ctrlr0;
206 	uint16_t div;
207 	int cs;
208 
209 	div = 2;
210 	while ((sc->sc_spi_freq / div) > conf->sc_freq)
211 		div++;
212 	/* Clock divider needs to be even. */
213 	if (div & 1)
214 		div++;
215 
216 	cs = conf->sc_cs;
217 	if (cs >= 2) {
218 		printf("%s: invalid chip-select (%d)\n", DEVNAME(sc), cs);
219 		return;
220 	}
221 	sc->sc_cs = cs;
222 	sc->sc_cs_delay = conf->sc_cs_delay;
223 
224 	ctrlr0 = SPI_CTRLR0_BHT_8BIT | SPI_CTRLR0_SSD_ONE | SPI_CTRLR0_EM_BIG;
225 	if (conf->sc_flags & SPI_CONFIG_CPHA)
226 		ctrlr0 |= SPI_CTRLR0_SCPH;
227 	if (conf->sc_flags & SPI_CONFIG_CPOL)
228 		ctrlr0 |= SPI_CTRLR0_SCPOL;
229 	switch (conf->sc_bpw) {
230 	case 4:
231 		ctrlr0 |= SPI_CTRLR0_DFS_4BIT;
232 		break;
233 	case 8:
234 		ctrlr0 |= SPI_CTRLR0_DFS_8BIT;
235 		break;
236 	case 16:
237 		ctrlr0 |= SPI_CTRLR0_DFS_16BIT;
238 		break;
239 	default:
240 		printf("%s: invalid bits-per-word (%d)\n", DEVNAME(sc),
241 		    conf->sc_bpw);
242 		return;
243 	}
244 
245 	HWRITE4(sc, SPI_ENR, 0);
246 	HWRITE4(sc, SPI_SER, 0);
247 	HWRITE4(sc, SPI_CTRLR0, ctrlr0);
248 	HWRITE4(sc, SPI_BAUDR, div);
249 }
250 
251 int
rkspi_wait_state(struct rkspi_softc * sc,uint32_t mask,uint32_t value)252 rkspi_wait_state(struct rkspi_softc *sc, uint32_t mask, uint32_t value)
253 {
254 	int timeout;
255 
256 	for (timeout = 1000; timeout > 0; timeout--) {
257 		if ((HREAD4(sc, SPI_SR) & mask) == value)
258 			return 0;
259 		delay(10);
260 	}
261 
262 	return ETIMEDOUT;
263 }
264 
265 int
rkspi_transfer(void * cookie,char * out,char * in,int len,int flags)266 rkspi_transfer(void *cookie, char *out, char *in, int len, int flags)
267 {
268 	struct rkspi_softc *sc = cookie;
269 	int i;
270 
271 	sc->sc_ridx = sc->sc_widx = 0;
272 
273 	/* drain input buffer */
274 	while (!(HREAD4(sc, SPI_SR) & SPI_SR_RFE))
275 		HREAD4(sc, SPI_RXDR);
276 
277 	if (out)
278 		HCLR4(sc, SPI_CTRLR0, SPI_CTRLR0_XFM_RO);
279 	else
280 		HSET4(sc, SPI_CTRLR0, SPI_CTRLR0_XFM_RO);
281 	HWRITE4(sc, SPI_CTRLR1, len - 1);
282 
283 	HSET4(sc, SPI_SER, SPI_SER_CS(sc->sc_cs));
284 	delay(sc->sc_cs_delay);
285 
286 	HWRITE4(sc, SPI_ENR, 1);
287 
288 	while (sc->sc_ridx < len || sc->sc_widx < len) {
289 		for (i = sc->sc_widx; i < len; i++) {
290 			if (rkspi_wait_state(sc, SPI_SR_TFF, 0))
291 				goto err;
292 			if (out)
293 				HWRITE4(sc, SPI_TXDR, out[i]);
294 			sc->sc_widx++;
295 		}
296 
297 		for (i = sc->sc_ridx; i < sc->sc_widx; i++) {
298 			if (rkspi_wait_state(sc, SPI_SR_RFE, 0))
299 				goto err;
300 			if (in)
301 				in[i] = HREAD4(sc, SPI_RXDR);
302 			else
303 				HREAD4(sc, SPI_RXDR);
304 			sc->sc_ridx++;
305 		}
306 
307 		if (rkspi_wait_state(sc, SPI_SR_BSF, 0))
308 			goto err;
309 	}
310 
311 	HWRITE4(sc, SPI_ENR, 0);
312 
313 	if (!ISSET(flags, SPI_KEEP_CS))
314 		HCLR4(sc, SPI_SER, SPI_SER_CS(sc->sc_cs));
315 	return 0;
316 
317 err:
318 	HWRITE4(sc, SPI_ENR, 0);
319 
320 	HCLR4(sc, SPI_SER, SPI_SER_CS(sc->sc_cs));
321 	return ETIMEDOUT;
322 }
323 
324 int
rkspi_acquire_bus(void * cookie,int flags)325 rkspi_acquire_bus(void *cookie, int flags)
326 {
327 	struct rkspi_softc *sc = cookie;
328 
329 	rw_enter(&sc->sc_buslock, RW_WRITE);
330 	return 0;
331 }
332 
333 void
rkspi_release_bus(void * cookie,int flags)334 rkspi_release_bus(void *cookie, int flags)
335 {
336 	struct rkspi_softc *sc = cookie;
337 
338 	rw_exit(&sc->sc_buslock);
339 }
340 
341 void
rkspi_scan(struct rkspi_softc * sc)342 rkspi_scan(struct rkspi_softc *sc)
343 {
344 	struct spi_attach_args sa;
345 	uint32_t reg[1];
346 	char name[32];
347 	int node;
348 
349 	for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) {
350 		memset(name, 0, sizeof(name));
351 		memset(reg, 0, sizeof(reg));
352 
353 		if (OF_getprop(node, "compatible", name, sizeof(name)) == -1)
354 			continue;
355 		if (name[0] == '\0')
356 			continue;
357 
358 		if (OF_getprop(node, "reg", &reg, sizeof(reg)) != sizeof(reg))
359 			continue;
360 
361 		memset(&sa, 0, sizeof(sa));
362 		sa.sa_tag = &sc->sc_tag;
363 		sa.sa_name = name;
364 		sa.sa_cookie = &node;
365 
366 		config_found(&sc->sc_dev, &sa, NULL);
367 	}
368 }
369