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