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/module.h> 36 #include <sys/rman.h> 37 38 #include <machine/bus.h> 39 #include <machine/resource.h> 40 #include <machine/intr.h> 41 42 #include <dev/ofw/ofw_bus.h> 43 #include <dev/ofw/ofw_bus_subr.h> 44 #include <dev/spibus/spi.h> 45 #include <dev/spibus/spibusvar.h> 46 47 #include <arm/mv/mvvar.h> 48 49 #include "spibus_if.h" 50 51 struct mv_spi_softc { 52 device_t sc_dev; 53 struct mtx sc_mtx; 54 struct resource *sc_mem_res; 55 struct resource *sc_irq_res; 56 struct spi_command *sc_cmd; 57 bus_space_tag_t sc_bst; 58 bus_space_handle_t sc_bsh; 59 uint32_t sc_len; 60 uint32_t sc_read; 61 uint32_t sc_flags; 62 uint32_t sc_written; 63 void *sc_intrhand; 64 }; 65 66 #define MV_SPI_BUSY 0x1 67 #define MV_SPI_WRITE(_sc, _off, _val) \ 68 bus_space_write_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off), (_val)) 69 #define MV_SPI_READ(_sc, _off) \ 70 bus_space_read_4((_sc)->sc_bst, (_sc)->sc_bsh, (_off)) 71 #define MV_SPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 72 #define MV_SPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 73 74 #define MV_SPI_CONTROL 0 75 #define MV_SPI_CTRL_CS_MASK 7 76 #define MV_SPI_CTRL_CS_SHIFT 2 77 #define MV_SPI_CTRL_SMEMREADY (1 << 1) 78 #define MV_SPI_CTRL_CS_ACTIVE (1 << 0) 79 #define MV_SPI_CONF 0x4 80 #define MV_SPI_CONF_MODE_SHIFT 12 81 #define MV_SPI_CONF_MODE_MASK (3 << MV_SPI_CONF_MODE_SHIFT) 82 #define MV_SPI_CONF_BYTELEN (1 << 5) 83 #define MV_SPI_CONF_CLOCK_SPR_MASK 0xf 84 #define MV_SPI_CONF_CLOCK_SPPR_MASK 1 85 #define MV_SPI_CONF_CLOCK_SPPR_SHIFT 4 86 #define MV_SPI_CONF_CLOCK_SPPRHI_MASK 3 87 #define MV_SPI_CONF_CLOCK_SPPRHI_SHIFT 6 88 #define MV_SPI_CONF_CLOCK_MASK \ 89 ((MV_SPI_CONF_CLOCK_SPPRHI_MASK << MV_SPI_CONF_CLOCK_SPPRHI_SHIFT) | \ 90 (MV_SPI_CONF_CLOCK_SPPR_MASK << MV_SPI_CONF_CLOCK_SPPR_SHIFT) | \ 91 MV_SPI_CONF_CLOCK_SPR_MASK) 92 #define MV_SPI_DATAOUT 0x8 93 #define MV_SPI_DATAIN 0xc 94 #define MV_SPI_INTR_STAT 0x10 95 #define MV_SPI_INTR_MASK 0x14 96 #define MV_SPI_INTR_SMEMREADY (1 << 0) 97 98 static struct ofw_compat_data compat_data[] = { 99 {"marvell,armada-380-spi", 1}, 100 {NULL, 0} 101 }; 102 103 static void mv_spi_intr(void *); 104 105 static int 106 mv_spi_probe(device_t dev) 107 { 108 109 if (!ofw_bus_status_okay(dev)) 110 return (ENXIO); 111 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) 112 return (ENXIO); 113 114 device_set_desc(dev, "Marvell SPI controller"); 115 116 return (BUS_PROBE_DEFAULT); 117 } 118 119 static int 120 mv_spi_attach(device_t dev) 121 { 122 struct mv_spi_softc *sc; 123 int rid; 124 uint32_t reg; 125 126 sc = device_get_softc(dev); 127 sc->sc_dev = dev; 128 129 rid = 0; 130 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 131 RF_ACTIVE); 132 if (!sc->sc_mem_res) { 133 device_printf(dev, "cannot allocate memory window\n"); 134 return (ENXIO); 135 } 136 137 sc->sc_bst = rman_get_bustag(sc->sc_mem_res); 138 sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); 139 140 rid = 0; 141 sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 142 RF_ACTIVE); 143 if (!sc->sc_irq_res) { 144 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 145 device_printf(dev, "cannot allocate interrupt\n"); 146 return (ENXIO); 147 } 148 149 /* Deactivate the bus - just in case... */ 150 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 151 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg & ~MV_SPI_CTRL_CS_ACTIVE); 152 153 /* Disable the two bytes FIFO. */ 154 reg = MV_SPI_READ(sc, MV_SPI_CONF); 155 MV_SPI_WRITE(sc, MV_SPI_CONF, reg & ~MV_SPI_CONF_BYTELEN); 156 157 /* Clear and disable interrupts. */ 158 MV_SPI_WRITE(sc, MV_SPI_INTR_MASK, 0); 159 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 160 161 /* Hook up our interrupt handler. */ 162 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 163 NULL, mv_spi_intr, sc, &sc->sc_intrhand)) { 164 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); 165 bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); 166 device_printf(dev, "cannot setup the interrupt handler\n"); 167 return (ENXIO); 168 } 169 170 mtx_init(&sc->sc_mtx, "mv_spi", NULL, MTX_DEF); 171 172 device_add_child(dev, "spibus", -1); 173 174 /* Probe and attach the spibus when interrupts are available. */ 175 config_intrhook_oneshot((ich_func_t)bus_generic_attach, dev); 176 177 return (0); 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 342 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 343 344 /* 345 * Write to start the transmission and read the byte 346 * back when ready. 347 */ 348 mv_spi_tx_byte(sc); 349 timeout = 1000; 350 while (--timeout > 0) { 351 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 352 if (reg & MV_SPI_CTRL_SMEMREADY) 353 break; 354 DELAY(1); 355 } 356 if (timeout == 0) 357 break; 358 mv_spi_rx_byte(sc); 359 } 360 361 /* Stop the controller. */ 362 reg = MV_SPI_READ(sc, MV_SPI_CONTROL); 363 MV_SPI_WRITE(sc, MV_SPI_CONTROL, reg & ~MV_SPI_CTRL_CS_ACTIVE); 364 MV_SPI_WRITE(sc, MV_SPI_INTR_MASK, 0); 365 MV_SPI_WRITE(sc, MV_SPI_INTR_STAT, 0); 366 367 /* Release the controller and wakeup the next thread waiting for it. */ 368 sc->sc_flags = 0; 369 wakeup_one(dev); 370 MV_SPI_UNLOCK(sc); 371 372 /* 373 * Check for transfer timeout. The SPI controller doesn't 374 * return errors. 375 */ 376 return ((timeout == 0) ? EIO : 0); 377 } 378 379 static phandle_t 380 mv_spi_get_node(device_t bus, device_t dev) 381 { 382 383 return (ofw_bus_get_node(bus)); 384 } 385 386 static device_method_t mv_spi_methods[] = { 387 /* Device interface */ 388 DEVMETHOD(device_probe, mv_spi_probe), 389 DEVMETHOD(device_attach, mv_spi_attach), 390 DEVMETHOD(device_detach, mv_spi_detach), 391 392 /* SPI interface */ 393 DEVMETHOD(spibus_transfer, mv_spi_transfer), 394 395 /* ofw_bus interface */ 396 DEVMETHOD(ofw_bus_get_node, mv_spi_get_node), 397 398 DEVMETHOD_END 399 }; 400 401 static devclass_t mv_spi_devclass; 402 403 static driver_t mv_spi_driver = { 404 "spi", 405 mv_spi_methods, 406 sizeof(struct mv_spi_softc), 407 }; 408 409 DRIVER_MODULE(mv_spi, simplebus, mv_spi_driver, mv_spi_devclass, 0, 0); 410