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 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 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 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 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 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 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 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 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 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