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", ®, 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