1 /*- 2 * Copyright (c) 2017-2018, Rubicon Communications, LLC (Netgate) 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include <sys/param.h> 31 #include <sys/systm.h> 32 #include <sys/bus.h> 33 34 #include <sys/kernel.h> 35 #include <sys/lock.h> 36 #include <sys/module.h> 37 #include <sys/mutex.h> 38 #include <sys/rman.h> 39 40 #include <machine/bus.h> 41 #include <machine/resource.h> 42 #include <machine/intr.h> 43 44 #include <dev/ofw/ofw_bus.h> 45 #include <dev/ofw/ofw_bus_subr.h> 46 #include <dev/spibus/spi.h> 47 #include <dev/spibus/spibusvar.h> 48 49 #include <arm/mv/mvvar.h> 50 51 #include "spibus_if.h" 52 53 struct mv_spi_softc { 54 device_t sc_dev; 55 struct mtx sc_mtx; 56 struct resource *sc_mem_res; 57 struct resource *sc_irq_res; 58 struct spi_command *sc_cmd; 59 bus_space_tag_t sc_bst; 60 bus_space_handle_t sc_bsh; 61 uint32_t sc_len; 62 uint32_t sc_read; 63 uint32_t sc_flags; 64 uint32_t sc_written; 65 void *sc_intrhand; 66 }; 67 68 #define MV_SPI_BUSY 0x1 69 #define MV_SPI_WRITE(_sc, _off, _val) \ 70 bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off), (_val)) 71 #define MV_SPI_READ(_sc, _off) \ 72 bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off)) 73 #define MV_SPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 74 #define MV_SPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 75 76 #define MV_SPI_CONTROL 0 77 #define MV_SPI_CTRL_CS_MASK 7 78 #define MV_SPI_CTRL_CS_SHIFT 2 79 #define MV_SPI_CTRL_SMEMREADY (1 << 1) 80 #define MV_SPI_CTRL_CS_ACTIVE (1 << 0) 81 #define MV_SPI_CONF 0x4 82 #define MV_SPI_CONF_MODE_SHIFT 12 83 #define MV_SPI_CONF_MODE_MASK (3 << MV_SPI_CONF_MODE_SHIFT) 84 #define MV_SPI_CONF_BYTELEN (1 << 5) 85 #define MV_SPI_CONF_CLOCK_SPR_MASK 0xf 86 #define MV_SPI_CONF_CLOCK_SPPR_MASK 1 87 #define MV_SPI_CONF_CLOCK_SPPR_SHIFT 4 88 #define MV_SPI_CONF_CLOCK_SPPRHI_MASK 3 89 #define MV_SPI_CONF_CLOCK_SPPRHI_SHIFT 6 90 #define MV_SPI_CONF_CLOCK_MASK \ 91 ((MV_SPI_CONF_CLOCK_SPPRHI_MASK << MV_SPI_CONF_CLOCK_SPPRHI_SHIFT) | \ 92 (MV_SPI_CONF_CLOCK_SPPR_MASK << MV_SPI_CONF_CLOCK_SPPR_SHIFT) | \ 93 MV_SPI_CONF_CLOCK_SPR_MASK) 94 #define MV_SPI_DATAOUT 0x8 95 #define MV_SPI_DATAIN 0xc 96 #define MV_SPI_INTR_STAT 0x10 97 #define MV_SPI_INTR_MASK 0x14 98 #define MV_SPI_INTR_SMEMREADY (1 << 0) 99 100 static struct ofw_compat_data compat_data[] = { 101 {"marvell,armada-380-spi", 1}, 102 {NULL, 0} 103 }; 104 105 static void mv_spi_intr(void *); 106 107 static int 108 mv_spi_probe(device_t dev) 109 { 110 111 if (!ofw_bus_status_okay(dev)) 112 return (ENXIO); 113 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 114 return (ENXIO); 115 116 device_set_desc(dev, "Marvell SPI controller"); 117 118 return (BUS_PROBE_DEFAULT); 119 } 120 121 static int 122 mv_spi_attach(device_t dev) 123 { 124 struct mv_spi_softc *sc; 125 int rid; 126 uint32_t reg; 127 128 sc = device_get_softc(dev); 129 sc->sc_dev = dev; 130 131 rid = 0; 132 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 133 RF_ACTIVE); 134 if (!sc->sc_mem_res) { 135 device_printf(dev, "cannot allocate memory window\n"); 136 return (ENXIO); 137 } 138 139 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 140 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 141 142 rid = 0; 143 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 144 RF_ACTIVE); 145 if (!sc->sc_irq_res) { 146 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 147 device_printf(dev, "cannot allocate interrupt\n"); 148 return (ENXIO); 149 } 150 151 /* Deactivate the bus - just in case... */ 152 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 153 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg & ~MV_SPI_CTRL_CS_ACTIVE); 154 155 /* Disable the two bytes FIFO. */ 156 reg = MV_SPI_READ(sc, MV_SPI_CONF); 157 MV_SPI_WRITE(sc, MV_SPI_CONF, reg & ~MV_SPI_CONF_BYTELEN); 158 159 /* Clear and disable interrupts. */ 160 MV_SPI_WRITE(sc, MV_SPI_INTR_MASK, 0); 161 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 162 163 /* Hook up our interrupt handler. */ 164 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 165 NULL, mv_spi_intr, sc, &sc->sc_intrhand)) { 166 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 167 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 168 device_printf(dev, "cannot setup the interrupt handler\n"); 169 return (ENXIO); 170 } 171 172 mtx_init(&sc->sc_mtx, "mv_spi", NULL, MTX_DEF); 173 174 device_add_child(dev, "spibus", -1); 175 176 /* Probe and attach the spibus when interrupts are available. */ 177 config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); 178 179 return (0); 180 } 181 182 static int 183 mv_spi_detach(device_t dev) 184 { 185 struct mv_spi_softc *sc; 186 187 bus_generic_detach(dev); 188 189 sc = device_get_softc(dev); 190 mtx_destroy(&sc->sc_mtx); 191 if (sc->sc_intrhand) 192 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); 193 if (sc->sc_irq_res) 194 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 195 if (sc->sc_mem_res) 196 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 197 198 return (0); 199 } 200 201 static __inline void 202 mv_spi_rx_byte(struct mv_spi_softc *sc) 203 { 204 struct spi_command *cmd; 205 uint32_t read; 206 uint8_t *p; 207 208 cmd = sc->sc_cmd; 209 p = (uint8_t *)cmd->rx_cmd; 210 read = sc->sc_read++; 211 if (read >= cmd->rx_cmd_sz) { 212 p = (uint8_t *)cmd->rx_data; 213 read -= cmd->rx_cmd_sz; 214 } 215 p[read] = MV_SPI_READ(sc, MV_SPI_DATAIN) & 0xff; 216 } 217 218 static __inline void 219 mv_spi_tx_byte(struct mv_spi_softc *sc) 220 { 221 struct spi_command *cmd; 222 uint32_t written; 223 uint8_t *p; 224 225 cmd = sc->sc_cmd; 226 p = (uint8_t *)cmd->tx_cmd; 227 written = sc->sc_written++; 228 if (written >= cmd->tx_cmd_sz) { 229 p = (uint8_t *)cmd->tx_data; 230 written -= cmd->tx_cmd_sz; 231 } 232 MV_SPI_WRITE(sc, MV_SPI_DATAOUT, p[written]); 233 } 234 235 static void 236 mv_spi_intr(void *arg) 237 { 238 struct mv_spi_softc *sc; 239 240 sc = (struct mv_spi_softc *)arg; 241 MV_SPI_LOCK(sc); 242 243 /* Filter stray interrupts. */ 244 if ((sc->sc_flags & MV_SPI_BUSY) == 0) { 245 MV_SPI_UNLOCK(sc); 246 return; 247 } 248 249 /* RX */ 250 mv_spi_rx_byte(sc); 251 252 /* TX */ 253 mv_spi_tx_byte(sc); 254 255 /* Check for end of transfer. */ 256 if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) 257 wakeup(sc->sc_dev); 258 259 MV_SPI_UNLOCK(sc); 260 } 261 262 static int 263 mv_spi_psc_calc(uint32_t clock, uint32_t *spr, uint32_t *sppr) 264 { 265 uint32_t divider, tclk; 266 267 tclk = get_tclk_armada38x(); 268 for (*spr = 2; *spr <= 15; (*spr)++) { 269 for (*sppr = 0; *sppr <= 7; (*sppr)++) { 270 divider = *spr * (1 << *sppr); 271 if (tclk / divider <= clock) 272 return (0); 273 } 274 } 275 276 return (EINVAL); 277 } 278 279 static int 280 mv_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) 281 { 282 struct mv_spi_softc *sc; 283 uint32_t clock, cs, mode, reg, spr, sppr; 284 int resid, timeout; 285 286 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, 287 ("TX/RX command sizes should be equal")); 288 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, 289 ("TX/RX data sizes should be equal")); 290 291 /* Get the proper chip select, mode and clock for this transfer. */ 292 spibus_get_cs(child, &cs); 293 cs &= ~SPIBUS_CS_HIGH; 294 spibus_get_mode(child, &mode); 295 if (mode > 3) { 296 device_printf(dev, 297 "Invalid mode %u requested by %s\n", mode, 298 device_get_nameunit(child)); 299 return (EINVAL); 300 } 301 spibus_get_clock(child, &clock); 302 if (clock == 0 || mv_spi_psc_calc(clock, &spr, &sppr) != 0) { 303 device_printf(dev, 304 "Invalid clock %uHz requested by %s\n", clock, 305 device_get_nameunit(child)); 306 return (EINVAL); 307 } 308 309 sc = device_get_softc(dev); 310 MV_SPI_LOCK(sc); 311 312 /* Wait until the controller is free. */ 313 while (sc->sc_flags & MV_SPI_BUSY) 314 mtx_sleep(dev, &sc->sc_mtx, 0, "mv_spi", 0); 315 316 /* Now we have control over SPI controller. */ 317 sc->sc_flags = MV_SPI_BUSY; 318 319 /* Save a pointer to the SPI command. */ 320 sc->sc_cmd = cmd; 321 sc->sc_read = 0; 322 sc->sc_written = 0; 323 sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz; 324 325 /* Set SPI Mode and Clock. */ 326 reg = MV_SPI_READ(sc, MV_SPI_CONF); 327 reg &= ~(MV_SPI_CONF_MODE_MASK | MV_SPI_CONF_CLOCK_MASK); 328 reg |= mode << MV_SPI_CONF_MODE_SHIFT; 329 reg |= spr & MV_SPI_CONF_CLOCK_SPR_MASK; 330 reg |= (sppr & MV_SPI_CONF_CLOCK_SPPR_MASK) << 331 MV_SPI_CONF_CLOCK_SPPR_SHIFT; 332 reg |= (sppr & MV_SPI_CONF_CLOCK_SPPRHI_MASK) << 333 MV_SPI_CONF_CLOCK_SPPRHI_SHIFT; 334 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg); 335 336 /* Set CS number and assert CS. */ 337 reg = (cs & MV_SPI_CTRL_CS_MASK) << MV_SPI_CTRL_CS_SHIFT; 338 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg); 339 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 340 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg | MV_SPI_CTRL_CS_ACTIVE); 341 342 while ((resid = sc->sc_len - sc->sc_written) > 0) { 343 344 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 345 346 /* 347 * Write to start the transmission and read the byte 348 * back when ready. 349 */ 350 mv_spi_tx_byte(sc); 351 timeout = 1000; 352 while (--timeout > 0) { 353 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 354 if (reg & MV_SPI_CTRL_SMEMREADY) 355 break; 356 DELAY(1); 357 } 358 if (timeout == 0) 359 break; 360 mv_spi_rx_byte(sc); 361 } 362 363 /* Stop the controller. */ 364 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 365 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg & ~MV_SPI_CTRL_CS_ACTIVE); 366 MV_SPI_WRITE(sc, MV_SPI_INTR_MASK, 0); 367 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 368 369 /* Release the controller and wakeup the next thread waiting for it. */ 370 sc->sc_flags = 0; 371 wakeup_one(dev); 372 MV_SPI_UNLOCK(sc); 373 374 /* 375 * Check for transfer timeout. The SPI controller doesn't 376 * return errors. 377 */ 378 return ((timeout == 0) ? EIO : 0); 379 } 380 381 static phandle_t 382 mv_spi_get_node(device_t bus, device_t dev) 383 { 384 385 return (ofw_bus_get_node(bus)); 386 } 387 388 static device_method_t mv_spi_methods[] = { 389 /* Device interface */ 390 DEVMETHOD(device_probe, mv_spi_probe), 391 DEVMETHOD(device_attach, mv_spi_attach), 392 DEVMETHOD(device_detach, mv_spi_detach), 393 394 /* SPI interface */ 395 DEVMETHOD(spibus_transfer, mv_spi_transfer), 396 397 /* ofw_bus interface */ 398 DEVMETHOD(ofw_bus_get_node, mv_spi_get_node), 399 400 DEVMETHOD_END 401 }; 402 403 static devclass_t mv_spi_devclass; 404 405 static driver_t mv_spi_driver = { 406 "spi", 407 mv_spi_methods, 408 sizeof(struct mv_spi_softc), 409 }; 410 411 DRIVER_MODULE(mv_spi, simplebus, mv_spi_driver, mv_spi_devclass, 0, 0); 412