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 return (bus_delayed_attach_children(dev)); 178 } 179 180 static int 181 mv_spi_detach(device_t dev) 182 { 183 struct mv_spi_softc *sc; 184 185 bus_generic_detach(dev); 186 187 sc = device_get_softc(dev); 188 mtx_destroy(&sc->sc_mtx); 189 if (sc->sc_intrhand) 190 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_intrhand); 191 if (sc->sc_irq_res) 192 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 193 if (sc->sc_mem_res) 194 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 195 196 return (0); 197 } 198 199 static __inline void 200 mv_spi_rx_byte(struct mv_spi_softc *sc) 201 { 202 struct spi_command *cmd; 203 uint32_t read; 204 uint8_t *p; 205 206 cmd = sc->sc_cmd; 207 p = (uint8_t *)cmd->rx_cmd; 208 read = sc->sc_read++; 209 if (read >= cmd->rx_cmd_sz) { 210 p = (uint8_t *)cmd->rx_data; 211 read -= cmd->rx_cmd_sz; 212 } 213 p[read] = MV_SPI_READ(sc, MV_SPI_DATAIN) & 0xff; 214 } 215 216 static __inline void 217 mv_spi_tx_byte(struct mv_spi_softc *sc) 218 { 219 struct spi_command *cmd; 220 uint32_t written; 221 uint8_t *p; 222 223 cmd = sc->sc_cmd; 224 p = (uint8_t *)cmd->tx_cmd; 225 written = sc->sc_written++; 226 if (written >= cmd->tx_cmd_sz) { 227 p = (uint8_t *)cmd->tx_data; 228 written -= cmd->tx_cmd_sz; 229 } 230 MV_SPI_WRITE(sc, MV_SPI_DATAOUT, p[written]); 231 } 232 233 static void 234 mv_spi_intr(void *arg) 235 { 236 struct mv_spi_softc *sc; 237 238 sc = (struct mv_spi_softc *)arg; 239 MV_SPI_LOCK(sc); 240 241 /* Filter stray interrupts. */ 242 if ((sc->sc_flags & MV_SPI_BUSY) == 0) { 243 MV_SPI_UNLOCK(sc); 244 return; 245 } 246 247 /* RX */ 248 mv_spi_rx_byte(sc); 249 250 /* TX */ 251 mv_spi_tx_byte(sc); 252 253 /* Check for end of transfer. */ 254 if (sc->sc_written == sc->sc_len && sc->sc_read == sc->sc_len) 255 wakeup(sc->sc_dev); 256 257 MV_SPI_UNLOCK(sc); 258 } 259 260 static int 261 mv_spi_psc_calc(uint32_t clock, uint32_t *spr, uint32_t *sppr) 262 { 263 uint32_t divider, tclk; 264 265 tclk = get_tclk_armada38x(); 266 for (*spr = 2; *spr <= 15; (*spr)++) { 267 for (*sppr = 0; *sppr <= 7; (*sppr)++) { 268 divider = *spr * (1 << *sppr); 269 if (tclk / divider <= clock) 270 return (0); 271 } 272 } 273 274 return (EINVAL); 275 } 276 277 static int 278 mv_spi_transfer(device_t dev, device_t child, struct spi_command *cmd) 279 { 280 struct mv_spi_softc *sc; 281 uint32_t clock, cs, mode, reg, spr, sppr; 282 int resid, timeout; 283 284 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, 285 ("TX/RX command sizes should be equal")); 286 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, 287 ("TX/RX data sizes should be equal")); 288 289 /* Get the proper chip select, mode and clock for this transfer. */ 290 spibus_get_cs(child, &cs); 291 cs &= ~SPIBUS_CS_HIGH; 292 spibus_get_mode(child, &mode); 293 if (mode > 3) { 294 device_printf(dev, 295 "Invalid mode %u requested by %s\n", mode, 296 device_get_nameunit(child)); 297 return (EINVAL); 298 } 299 spibus_get_clock(child, &clock); 300 if (clock == 0 || mv_spi_psc_calc(clock, &spr, &sppr) != 0) { 301 device_printf(dev, 302 "Invalid clock %uHz requested by %s\n", clock, 303 device_get_nameunit(child)); 304 return (EINVAL); 305 } 306 307 sc = device_get_softc(dev); 308 MV_SPI_LOCK(sc); 309 310 /* Wait until the controller is free. */ 311 while (sc->sc_flags & MV_SPI_BUSY) 312 mtx_sleep(dev, &sc->sc_mtx, 0, "mv_spi", 0); 313 314 /* Now we have control over SPI controller. */ 315 sc->sc_flags = MV_SPI_BUSY; 316 317 /* Save a pointer to the SPI command. */ 318 sc->sc_cmd = cmd; 319 sc->sc_read = 0; 320 sc->sc_written = 0; 321 sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz; 322 323 /* Set SPI Mode and Clock. */ 324 reg = MV_SPI_READ(sc, MV_SPI_CONF); 325 reg &= ~(MV_SPI_CONF_MODE_MASK | MV_SPI_CONF_CLOCK_MASK); 326 reg |= mode << MV_SPI_CONF_MODE_SHIFT; 327 reg |= spr & MV_SPI_CONF_CLOCK_SPR_MASK; 328 reg |= (sppr & MV_SPI_CONF_CLOCK_SPPR_MASK) << 329 MV_SPI_CONF_CLOCK_SPPR_SHIFT; 330 reg |= (sppr & MV_SPI_CONF_CLOCK_SPPRHI_MASK) << 331 MV_SPI_CONF_CLOCK_SPPRHI_SHIFT; 332 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg); 333 334 /* Set CS number and assert CS. */ 335 reg = (cs & MV_SPI_CTRL_CS_MASK) << MV_SPI_CTRL_CS_SHIFT; 336 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg); 337 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 338 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg | MV_SPI_CTRL_CS_ACTIVE); 339 340 while ((resid = sc->sc_len - sc->sc_written) > 0) { 341 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 342 343 /* 344 * Write to start the transmission and read the byte 345 * back when ready. 346 */ 347 mv_spi_tx_byte(sc); 348 timeout = 1000; 349 while (--timeout > 0) { 350 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 351 if (reg & MV_SPI_CTRL_SMEMREADY) 352 break; 353 DELAY(1); 354 } 355 if (timeout == 0) 356 break; 357 mv_spi_rx_byte(sc); 358 } 359 360 /* Stop the controller. */ 361 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 362 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg & ~MV_SPI_CTRL_CS_ACTIVE); 363 MV_SPI_WRITE(sc, MV_SPI_INTR_MASK, 0); 364 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 365 366 /* Release the controller and wakeup the next thread waiting for it. */ 367 sc->sc_flags = 0; 368 wakeup_one(dev); 369 MV_SPI_UNLOCK(sc); 370 371 /* 372 * Check for transfer timeout. The SPI controller doesn't 373 * return errors. 374 */ 375 return ((timeout == 0) ? EIO : 0); 376 } 377 378 static phandle_t 379 mv_spi_get_node(device_t bus, device_t dev) 380 { 381 382 return (ofw_bus_get_node(bus)); 383 } 384 385 static device_method_t mv_spi_methods[] = { 386 /* Device interface */ 387 DEVMETHOD(device_probe, mv_spi_probe), 388 DEVMETHOD(device_attach, mv_spi_attach), 389 DEVMETHOD(device_detach, mv_spi_detach), 390 391 /* SPI interface */ 392 DEVMETHOD(spibus_transfer, mv_spi_transfer), 393 394 /* ofw_bus interface */ 395 DEVMETHOD(ofw_bus_get_node, mv_spi_get_node), 396 397 DEVMETHOD_END 398 }; 399 400 static devclass_t mv_spi_devclass; 401 402 static driver_t mv_spi_driver = { 403 "spi", 404 mv_spi_methods, 405 sizeof(struct mv_spi_softc), 406 }; 407 408 DRIVER_MODULE(mv_spi, simplebus, mv_spi_driver, mv_spi_devclass, 0, 0); 409