1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> 5 * Copyright (c) 2013 Luiz Otavio O Souza <loos@freebsd.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/bus.h> 36 37 #include <sys/kernel.h> 38 #include <sys/module.h> 39 #include <sys/rman.h> 40 #include <sys/lock.h> 41 #include <sys/mutex.h> 42 #include <sys/sysctl.h> 43 44 #include <machine/bus.h> 45 #include <machine/resource.h> 46 #include <machine/intr.h> 47 48 #include <dev/ofw/ofw_bus.h> 49 #include <dev/ofw/ofw_bus_subr.h> 50 51 #include <dev/spibus/spi.h> 52 #include <dev/spibus/spibusvar.h> 53 54 #include <arm/broadcom/bcm2835/bcm2835_gpio.h> 55 #include <arm/broadcom/bcm2835/bcm2835_spireg.h> 56 #include <arm/broadcom/bcm2835/bcm2835_spivar.h> 57 58 #include "spibus_if.h" 59 60 static struct ofw_compat_data compat_data[] = { 61 {"broadcom,bcm2835-spi", 1}, 62 {"brcm,bcm2835-spi", 1}, 63 {NULL, 0} 64 }; 65 66 static void bcm_spi_intr(void *); 67 68 #ifdef BCM_SPI_DEBUG 69 static void 70 bcm_spi_printr(device_t dev) 71 { 72 struct bcm_spi_softc *sc; 73 uint32_t reg; 74 75 sc = device_get_softc(dev); 76 reg = BCM_SPI_READ(sc, SPI_CS); 77 device_printf(dev, "CS=%b\n", reg, 78 "\20\1CS0\2CS1\3CPHA\4CPOL\7CSPOL" 79 "\10TA\11DMAEN\12INTD\13INTR\14ADCS\15REN\16LEN" 80 "\21DONE\22RXD\23TXD\24RXR\25RXF\26CSPOL0\27CSPOL1" 81 "\30CSPOL2\31DMA_LEN\32LEN_LONG"); 82 reg = BCM_SPI_READ(sc, SPI_CLK) & SPI_CLK_MASK; 83 if (reg % 2) 84 reg--; 85 if (reg == 0) 86 reg = 65536; 87 device_printf(dev, "CLK=%uMhz/%d=%luhz\n", 88 SPI_CORE_CLK / 1000000, reg, SPI_CORE_CLK / reg); 89 reg = BCM_SPI_READ(sc, SPI_DLEN) & SPI_DLEN_MASK; 90 device_printf(dev, "DLEN=%d\n", reg); 91 reg = BCM_SPI_READ(sc, SPI_LTOH) & SPI_LTOH_MASK; 92 device_printf(dev, "LTOH=%d\n", reg); 93 reg = BCM_SPI_READ(sc, SPI_DC); 94 device_printf(dev, "DC=RPANIC=%#x RDREQ=%#x TPANIC=%#x TDREQ=%#x\n", 95 (reg & SPI_DC_RPANIC_MASK) >> SPI_DC_RPANIC_SHIFT, 96 (reg & SPI_DC_RDREQ_MASK) >> SPI_DC_RDREQ_SHIFT, 97 (reg & SPI_DC_TPANIC_MASK) >> SPI_DC_TPANIC_SHIFT, 98 (reg & SPI_DC_TDREQ_MASK) >> SPI_DC_TDREQ_SHIFT); 99 } 100 #endif 101 102 static void 103 bcm_spi_modifyreg(struct bcm_spi_softc *sc, uint32_t off, uint32_t mask, 104 uint32_t value) 105 { 106 uint32_t reg; 107 108 mtx_assert(&sc->sc_mtx, MA_OWNED); 109 reg = BCM_SPI_READ(sc, off); 110 reg &= ~mask; 111 reg |= value; 112 BCM_SPI_WRITE(sc, off, reg); 113 } 114 115 static int 116 bcm_spi_clock_proc(SYSCTL_HANDLER_ARGS) 117 { 118 struct bcm_spi_softc *sc; 119 uint32_t clk; 120 int error; 121 122 sc = (struct bcm_spi_softc *)arg1; 123 124 BCM_SPI_LOCK(sc); 125 clk = BCM_SPI_READ(sc, SPI_CLK); 126 BCM_SPI_UNLOCK(sc); 127 clk &= 0xffff; 128 if (clk == 0) 129 clk = 65536; 130 clk = SPI_CORE_CLK / clk; 131 132 error = sysctl_handle_int(oidp, &clk, sizeof(clk), req); 133 if (error != 0 || req->newptr == NULL) 134 return (error); 135 136 clk = SPI_CORE_CLK / clk; 137 if (clk <= 1) 138 clk = 2; 139 else if (clk % 2) 140 clk--; 141 if (clk > 0xffff) 142 clk = 0; 143 BCM_SPI_LOCK(sc); 144 BCM_SPI_WRITE(sc, SPI_CLK, clk); 145 BCM_SPI_UNLOCK(sc); 146 147 return (0); 148 } 149 150 static int 151 bcm_spi_cs_bit_proc(SYSCTL_HANDLER_ARGS, uint32_t bit) 152 { 153 struct bcm_spi_softc *sc; 154 uint32_t reg; 155 int error; 156 157 sc = (struct bcm_spi_softc *)arg1; 158 BCM_SPI_LOCK(sc); 159 reg = BCM_SPI_READ(sc, SPI_CS); 160 BCM_SPI_UNLOCK(sc); 161 reg = (reg & bit) ? 1 : 0; 162 163 error = sysctl_handle_int(oidp, ®, sizeof(reg), req); 164 if (error != 0 || req->newptr == NULL) 165 return (error); 166 167 if (reg) 168 reg = bit; 169 BCM_SPI_LOCK(sc); 170 bcm_spi_modifyreg(sc, SPI_CS, bit, reg); 171 BCM_SPI_UNLOCK(sc); 172 173 return (0); 174 } 175 176 static int 177 bcm_spi_cpol_proc(SYSCTL_HANDLER_ARGS) 178 { 179 180 return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CPOL)); 181 } 182 183 static int 184 bcm_spi_cpha_proc(SYSCTL_HANDLER_ARGS) 185 { 186 187 return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CPHA)); 188 } 189 190 static int 191 bcm_spi_cspol0_proc(SYSCTL_HANDLER_ARGS) 192 { 193 194 return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CSPOL0)); 195 } 196 197 static int 198 bcm_spi_cspol1_proc(SYSCTL_HANDLER_ARGS) 199 { 200 201 return (bcm_spi_cs_bit_proc(oidp, arg1, arg2, req, SPI_CS_CSPOL1)); 202 } 203 204 static void 205 bcm_spi_sysctl_init(struct bcm_spi_softc *sc) 206 { 207 struct sysctl_ctx_list *ctx; 208 struct sysctl_oid *tree_node; 209 struct sysctl_oid_list *tree; 210 211 /* 212 * Add system sysctl tree/handlers. 213 */ 214 ctx = device_get_sysctl_ctx(sc->sc_dev); 215 tree_node = device_get_sysctl_tree(sc->sc_dev); 216 tree = SYSCTL_CHILDREN(tree_node); 217 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "clock", 218 CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc), 219 bcm_spi_clock_proc, "IU", "SPI BUS clock frequency"); 220 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cpol", 221 CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc), 222 bcm_spi_cpol_proc, "IU", "SPI BUS clock polarity"); 223 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cpha", 224 CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc), 225 bcm_spi_cpha_proc, "IU", "SPI BUS clock phase"); 226 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cspol0", 227 CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc), 228 bcm_spi_cspol0_proc, "IU", "SPI BUS chip select 0 polarity"); 229 SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "cspol1", 230 CTLFLAG_RW | CTLTYPE_UINT, sc, sizeof(*sc), 231 bcm_spi_cspol1_proc, "IU", "SPI BUS chip select 1 polarity"); 232 } 233 234 static int 235 bcm_spi_probe(device_t dev) 236 { 237 238 if (!ofw_bus_status_okay(dev)) 239 return (ENXIO); 240 241 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 242 return (ENXIO); 243 244 device_set_desc(dev, "BCM2708/2835 SPI controller"); 245 246 return (BUS_PROBE_DEFAULT); 247 } 248 249 static int 250 bcm_spi_attach(device_t dev) 251 { 252 struct bcm_spi_softc *sc; 253 device_t gpio; 254 int i, rid; 255 256 if (device_get_unit(dev) != 0) { 257 device_printf(dev, "only one SPI controller supported\n"); 258 return (ENXIO); 259 } 260 261 sc = device_get_softc(dev); 262 sc->sc_dev = dev; 263 264 /* Configure the GPIO pins to ALT0 function to enable SPI the pins. */ 265 gpio = devclass_get_device(devclass_find("gpio"), 0); 266 if (!gpio) { 267 device_printf(dev, "cannot find gpio0\n"); 268 return (ENXIO); 269 } 270 for (i = 0; i < nitems(bcm_spi_pins); i++) 271 bcm_gpio_set_alternate(gpio, bcm_spi_pins[i], BCM_GPIO_ALT0); 272 273 rid = 0; 274 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 275 RF_ACTIVE); 276 if (!sc->sc_mem_res) { 277 device_printf(dev, "cannot allocate memory window\n"); 278 return (ENXIO); 279 } 280 281 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 282 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 283 284 rid = 0; 285 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 286 RF_ACTIVE); 287 if (!sc->sc_irq_res) { 288 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 289 device_printf(dev, "cannot allocate interrupt\n"); 290 return (ENXIO); 291 } 292 293 /* Hook up our interrupt handler. */ 294 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 295 NULL, bcm_spi_intr, sc, &sc->sc_intrhand)) { 296 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 297 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 298 device_printf(dev, "cannot setup the interrupt handler\n"); 299 return (ENXIO); 300 } 301 302 mtx_init(&sc->sc_mtx, "bcm_spi", NULL, MTX_DEF); 303 304 /* Add sysctl nodes. */ 305 bcm_spi_sysctl_init(sc); 306 307 #ifdef BCM_SPI_DEBUG 308 bcm_spi_printr(dev); 309 #endif 310 311 /* 312 * Enable the SPI controller. Clear the rx and tx FIFO. 313 * Defaults to SPI mode 0. 314 */ 315 BCM_SPI_WRITE(sc, SPI_CS, SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO); 316 317 /* Set the SPI clock to 500Khz. */ 318 BCM_SPI_WRITE(sc, SPI_CLK, SPI_CORE_CLK / 500000); 319 320 #ifdef BCM_SPI_DEBUG 321 bcm_spi_printr(dev); 322 #endif 323 324 device_add_child(dev, "spibus", -1); 325 326 return (bus_generic_attach(dev)); 327 } 328 329 static int 330 bcm_spi_detach(device_t dev) 331 { 332 struct bcm_spi_softc *sc; 333 334 bus_generic_detach(dev); 335 336 sc = device_get_softc(dev); 337 mtx_destroy(&sc->sc_mtx); 338 if (sc->sc_intrhand) 339 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); 340 if (sc->sc_irq_res) 341 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 342 if (sc->sc_mem_res) 343 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 344 345 return (0); 346 } 347 348 static void 349 bcm_spi_fill_fifo(struct bcm_spi_softc *sc) 350 { 351 struct spi_command *cmd; 352 uint32_t cs, written; 353 uint8_t *data; 354 355 cmd = sc->sc_cmd; 356 cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD); 357 while (sc->sc_written < sc->sc_len && 358 cs == (SPI_CS_TA | SPI_CS_TXD)) { 359 data = (uint8_t *)cmd->tx_cmd; 360 written = sc->sc_written++; 361 if (written >= cmd->tx_cmd_sz) { 362 data = (uint8_t *)cmd->tx_data; 363 written -= cmd->tx_cmd_sz; 364 } 365 BCM_SPI_WRITE(sc, SPI_FIFO, data[written]); 366 cs = BCM_SPI_READ(sc, SPI_CS) & (SPI_CS_TA | SPI_CS_TXD); 367 } 368 } 369 370 static void 371 bcm_spi_drain_fifo(struct bcm_spi_softc *sc) 372 { 373 struct spi_command *cmd; 374 uint32_t cs, read; 375 uint8_t *data; 376 377 cmd = sc->sc_cmd; 378 cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD; 379 while (sc->sc_read < sc->sc_len && cs == SPI_CS_RXD) { 380 data = (uint8_t *)cmd->rx_cmd; 381 read = sc->sc_read++; 382 if (read >= cmd->rx_cmd_sz) { 383 data = (uint8_t *)cmd->rx_data; 384 read -= cmd->rx_cmd_sz; 385 } 386 data[read] = BCM_SPI_READ(sc, SPI_FIFO) & 0xff; 387 cs = BCM_SPI_READ(sc, SPI_CS) & SPI_CS_RXD; 388 } 389 } 390 391 static void 392 bcm_spi_intr(void *arg) 393 { 394 struct bcm_spi_softc *sc; 395 396 sc = (struct bcm_spi_softc *)arg; 397 BCM_SPI_LOCK(sc); 398 399 /* Filter stray interrupts. */ 400 if ((sc->sc_flags & BCM_SPI_BUSY) == 0) { 401 BCM_SPI_UNLOCK(sc); 402 return; 403 } 404 405 /* TX - Fill up the FIFO. */ 406 bcm_spi_fill_fifo(sc); 407 408 /* RX - Drain the FIFO. */ 409 bcm_spi_drain_fifo(sc); 410 411 /* Check for end of transfer. */ 412 if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) { 413 /* Disable interrupts and the SPI engine. */ 414 bcm_spi_modifyreg(sc, SPI_CS, 415 SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0); 416 wakeup(sc->sc_dev); 417 } 418 419 BCM_SPI_UNLOCK(sc); 420 } 421 422 static int 423 bcm_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) 424 { 425 struct bcm_spi_softc *sc; 426 uint32_t cs; 427 int err; 428 429 sc = device_get_softc(dev); 430 431 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, 432 ("TX/RX command sizes should be equal")); 433 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, 434 ("TX/RX data sizes should be equal")); 435 436 /* Get the proper chip select for this child. */ 437 spibus_get_cs(child, &cs); 438 439 cs &= ~SPIBUS_CS_HIGH; 440 441 if (cs > 2) { 442 device_printf(dev, 443 "Invalid chip select %d requested by %s\n", cs, 444 device_get_nameunit(child)); 445 return (EINVAL); 446 } 447 448 BCM_SPI_LOCK(sc); 449 450 /* If the controller is in use wait until it is available. */ 451 while (sc->sc_flags & BCM_SPI_BUSY) 452 mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", 0); 453 454 /* Now we have control over SPI controller. */ 455 sc->sc_flags = BCM_SPI_BUSY; 456 457 /* Clear the FIFO. */ 458 bcm_spi_modifyreg(sc, SPI_CS, 459 SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO, 460 SPI_CS_CLEAR_RXFIFO | SPI_CS_CLEAR_TXFIFO); 461 462 /* Save a pointer to the SPI command. */ 463 sc->sc_cmd = cmd; 464 sc->sc_read = 0; 465 sc->sc_written = 0; 466 sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz; 467 468 /* 469 * Set the CS for this transaction, enable interrupts and announce 470 * we're ready to tx. This will kick off the first interrupt. 471 */ 472 bcm_spi_modifyreg(sc, SPI_CS, 473 SPI_CS_MASK | SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 474 cs | SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD); 475 476 /* Wait for the transaction to complete. */ 477 err = mtx_sleep(dev, &sc->sc_mtx, 0, "bcm_spi", hz * 2); 478 479 /* Make sure the SPI engine and interrupts are disabled. */ 480 bcm_spi_modifyreg(sc, SPI_CS, SPI_CS_TA | SPI_CS_INTR | SPI_CS_INTD, 0); 481 482 /* Release the controller and wakeup the next thread waiting for it. */ 483 sc->sc_flags = 0; 484 wakeup_one(dev); 485 BCM_SPI_UNLOCK(sc); 486 487 /* 488 * Check for transfer timeout. The SPI controller doesn't 489 * return errors. 490 */ 491 if (err == EWOULDBLOCK) { 492 device_printf(sc->sc_dev, "SPI error\n"); 493 err = EIO; 494 } 495 496 return (err); 497 } 498 499 static phandle_t 500 bcm_spi_get_node(device_t bus, device_t dev) 501 { 502 503 /* We only have one child, the SPI bus, which needs our own node. */ 504 return (ofw_bus_get_node(bus)); 505 } 506 507 static device_method_t bcm_spi_methods[] = { 508 /* Device interface */ 509 DEVMETHOD(device_probe, bcm_spi_probe), 510 DEVMETHOD(device_attach, bcm_spi_attach), 511 DEVMETHOD(device_detach, bcm_spi_detach), 512 513 /* SPI interface */ 514 DEVMETHOD(spibus_transfer, bcm_spi_transfer), 515 516 /* ofw_bus interface */ 517 DEVMETHOD(ofw_bus_get_node, bcm_spi_get_node), 518 519 DEVMETHOD_END 520 }; 521 522 static devclass_t bcm_spi_devclass; 523 524 static driver_t bcm_spi_driver = { 525 "spi", 526 bcm_spi_methods, 527 sizeof(struct bcm_spi_softc), 528 }; 529 530 DRIVER_MODULE(bcm2835_spi, simplebus, bcm_spi_driver, bcm_spi_devclass, 0, 0); 531