1/*- 2 * Copyright (c) 2016 Oleksandr Tymoshenko <gonzo@FreeBSD.org> 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 AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD$"); 29 30#include "opt_acpi.h" 31 32#include <sys/param.h> 33#include <sys/bus.h> 34#include <sys/kernel.h> 35#include <sys/module.h> 36#include <sys/proc.h> 37#include <sys/rman.h> 38 39#include <machine/bus.h> 40#include <machine/resource.h> 41 42#include <dev/spibus/spi.h> 43#include <dev/spibus/spibusvar.h> 44 45#include <contrib/dev/acpica/include/acpi.h> 46#include <contrib/dev/acpica/include/accommon.h> 47 48#include <dev/acpica/acpivar.h> 49 50#include "spibus_if.h" 51 52/** 53 * Macros for driver mutex locking 54 */ 55#define INTELSPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) 56#define INTELSPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) 57#define INTELSPI_LOCK_INIT(_sc) \ 58 mtx_init(&_sc->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ 59 "intelspi", MTX_DEF) 60#define INTELSPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) 61#define INTELSPI_ASSERT_LOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED) 62#define INTELSPI_ASSERT_UNLOCKED(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED) 63 64#define INTELSPI_WRITE(_sc, _off, _val) \ 65 bus_write_4((_sc)->sc_mem_res, (_off), (_val)) 66#define INTELSPI_READ(_sc, _off) \ 67 bus_read_4((_sc)->sc_mem_res, (_off)) 68 69#define INTELSPI_BUSY 0x1 70#define TX_FIFO_THRESHOLD 2 71#define RX_FIFO_THRESHOLD 2 72#define CLOCK_DIV_10MHZ 5 73#define DATA_SIZE_8BITS 8 74 75#define CS_LOW 0 76#define CS_HIGH 1 77 78#define INTELSPI_SSPREG_SSCR0 0x0 79#define SSCR0_SCR(n) (((n) - 1) << 8) 80#define SSCR0_SSE (1 << 7) 81#define SSCR0_FRF_SPI (0 << 4) 82#define SSCR0_DSS(n) (((n) - 1) << 0) 83#define INTELSPI_SSPREG_SSCR1 0x4 84#define SSCR1_TINTE (1 << 19) 85#define SSCR1_RFT(n) (((n) - 1) << 10) 86#define SSCR1_RFT_MASK (0xf << 10) 87#define SSCR1_TFT(n) (((n) - 1) << 6) 88#define SSCR1_SPI_SPH (1 << 4) 89#define SSCR1_SPI_SPO (1 << 3) 90#define SSCR1_MODE_MASK (SSCR1_SPI_SPO | SSCR1_SPI_SPH) 91#define SSCR1_MODE_0 (0) 92#define SSCR1_MODE_1 (SSCR1_SPI_SPH) 93#define SSCR1_MODE_2 (SSCR1_SPI_SPO) 94#define SSCR1_MODE_3 (SSCR1_SPI_SPO | SSCR1_SPI_SPH) 95#define SSCR1_TIE (1 << 1) 96#define SSCR1_RIE (1 << 0) 97#define INTELSPI_SSPREG_SSSR 0x8 98#define SSSR_RFL_MASK (0xf << 12) 99#define SSSR_TFL_MASK (0xf << 8) 100#define SSSR_RNE (1 << 3) 101#define SSSR_TNF (1 << 2) 102#define INTELSPI_SSPREG_SSITR 0xC 103#define INTELSPI_SSPREG_SSDR 0x10 104#define INTELSPI_SSPREG_SSTO 0x28 105#define INTELSPI_SSPREG_SSPSP 0x2C 106#define INTELSPI_SSPREG_SSTSA 0x30 107#define INTELSPI_SSPREG_SSRSA 0x34 108#define INTELSPI_SSPREG_SSTSS 0x38 109#define INTELSPI_SSPREG_SSACD 0x3C 110#define INTELSPI_SSPREG_ITF 0x40 111#define INTELSPI_SSPREG_SITF 0x44 112#define INTELSPI_SSPREG_SIRF 0x48 113#define INTELSPI_SSPREG_PRV_CLOCK_PARAMS 0x400 114#define INTELSPI_SSPREG_RESETS 0x404 115#define INTELSPI_SSPREG_GENERAL 0x408 116#define INTELSPI_SSPREG_SSP_REG 0x40C 117#define INTELSPI_SSPREG_SPI_CS_CTRL 0x418 118#define SPI_CS_CTRL_CS_MASK (3) 119#define SPI_CS_CTRL_SW_MODE (1 << 0) 120#define SPI_CS_CTRL_HW_MODE (1 << 0) 121#define SPI_CS_CTRL_CS_HIGH (1 << 1) 122#define SPI_CS_CTRL_CS_LOW (0 << 1) 123 124struct intelspi_softc { 125 ACPI_HANDLE sc_handle; 126 device_t sc_dev; 127 struct mtx sc_mtx; 128 int sc_mem_rid; 129 struct resource *sc_mem_res; 130 int sc_irq_rid; 131 struct resource *sc_irq_res; 132 void *sc_irq_ih; 133 struct spi_command *sc_cmd; 134 uint32_t sc_len; 135 uint32_t sc_read; 136 uint32_t sc_flags; 137 uint32_t sc_written; 138}; 139 140static int intelspi_probe(device_t dev); 141static int intelspi_attach(device_t dev); 142static int intelspi_detach(device_t dev); 143static void intelspi_intr(void *); 144 145static int 146intelspi_txfifo_full(struct intelspi_softc *sc) 147{ 148 uint32_t sssr; 149 150 INTELSPI_ASSERT_LOCKED(sc); 151 152 sssr = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR); 153 if (sssr & SSSR_TNF) 154 return (0); 155 156 return (1); 157} 158 159static int 160intelspi_rxfifo_empty(struct intelspi_softc *sc) 161{ 162 uint32_t sssr; 163 164 INTELSPI_ASSERT_LOCKED(sc); 165 166 sssr = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR); 167 if (sssr & SSSR_RNE) 168 return (0); 169 else 170 return (1); 171} 172 173static void 174intelspi_fill_tx_fifo(struct intelspi_softc *sc) 175{ 176 struct spi_command *cmd; 177 uint32_t written; 178 uint8_t *data; 179 180 INTELSPI_ASSERT_LOCKED(sc); 181 182 cmd = sc->sc_cmd; 183 while (sc->sc_written < sc->sc_len && 184 !intelspi_txfifo_full(sc)) { 185 data = (uint8_t *)cmd->tx_cmd; 186 written = sc->sc_written++; 187 188 if (written >= cmd->tx_cmd_sz) { 189 data = (uint8_t *)cmd->tx_data; 190 written -= cmd->tx_cmd_sz; 191 } 192 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSDR, data[written]); 193 } 194} 195 196static void 197intelspi_drain_rx_fifo(struct intelspi_softc *sc) 198{ 199 struct spi_command *cmd; 200 uint32_t read; 201 uint8_t *data; 202 203 INTELSPI_ASSERT_LOCKED(sc); 204 205 cmd = sc->sc_cmd; 206 while (sc->sc_read < sc->sc_len && 207 !intelspi_rxfifo_empty(sc)) { 208 data = (uint8_t *)cmd->rx_cmd; 209 read = sc->sc_read++; 210 if (read >= cmd->rx_cmd_sz) { 211 data = (uint8_t *)cmd->rx_data; 212 read -= cmd->rx_cmd_sz; 213 } 214 data[read] = INTELSPI_READ(sc, INTELSPI_SSPREG_SSDR) & 0xff; 215 } 216} 217 218static int 219intelspi_transaction_done(struct intelspi_softc *sc) 220{ 221 int txfifo_empty; 222 uint32_t sssr; 223 224 INTELSPI_ASSERT_LOCKED(sc); 225 226 if (sc->sc_written != sc->sc_len || 227 sc->sc_read != sc->sc_len) 228 return (0); 229 230 sssr = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR); 231 txfifo_empty = ((sssr & SSSR_TFL_MASK) == 0) && 232 (sssr & SSSR_TNF); 233 234 if (txfifo_empty && !(sssr & SSSR_RNE)) 235 return (1); 236 237 return (0); 238} 239 240static int 241intelspi_transact(struct intelspi_softc *sc) 242{ 243 244 INTELSPI_ASSERT_LOCKED(sc); 245 246 /* TX - Fill up the FIFO. */ 247 intelspi_fill_tx_fifo(sc); 248 249 /* RX - Drain the FIFO. */ 250 intelspi_drain_rx_fifo(sc); 251 252 /* Check for end of transfer. */ 253 return intelspi_transaction_done(sc); 254} 255 256static void 257intelspi_intr(void *arg) 258{ 259 struct intelspi_softc *sc; 260 uint32_t reg; 261 262 sc = (struct intelspi_softc *)arg; 263 264 INTELSPI_LOCK(sc); 265 if ((sc->sc_flags & INTELSPI_BUSY) == 0) { 266 INTELSPI_UNLOCK(sc); 267 return; 268 } 269 270 /* Check if SSP if off */ 271 reg = INTELSPI_READ(sc, INTELSPI_SSPREG_SSSR); 272 if (reg == 0xffffffffU) { 273 INTELSPI_UNLOCK(sc); 274 return; 275 } 276 277 /* Check for end of transfer. */ 278 if (intelspi_transact(sc)) { 279 /* Disable interrupts */ 280 reg = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1); 281 reg &= ~(SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE); 282 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, reg); 283 wakeup(sc->sc_dev); 284 } 285 286 INTELSPI_UNLOCK(sc); 287} 288 289static void 290intelspi_init(struct intelspi_softc *sc) 291{ 292 uint32_t reg; 293 294 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, 0); 295 296 /* Manual CS control */ 297 reg = INTELSPI_READ(sc, INTELSPI_SSPREG_SPI_CS_CTRL); 298 reg &= ~(SPI_CS_CTRL_CS_MASK); 299 reg |= (SPI_CS_CTRL_SW_MODE | SPI_CS_CTRL_CS_HIGH); 300 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SPI_CS_CTRL, reg); 301 302 /* Set TX/RX FIFO IRQ threshold levels */ 303 reg = SSCR1_TFT(TX_FIFO_THRESHOLD) | SSCR1_RFT(RX_FIFO_THRESHOLD); 304 /* 305 * Set SPI mode. This should be part of transaction or sysctl 306 */ 307 reg |= SSCR1_MODE_0; 308 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, reg); 309 310 /* 311 * Parent clock on Minowboard Turbot is 50MHz 312 * divide it by 5 to set to more or less reasonable 313 * value. But this should be part of transaction config 314 * or sysctl 315 */ 316 reg = SSCR0_SCR(CLOCK_DIV_10MHZ); 317 /* Put SSP in SPI mode */ 318 reg |= SSCR0_FRF_SPI; 319 /* Data size */ 320 reg |= SSCR0_DSS(DATA_SIZE_8BITS); 321 /* Enable SSP */ 322 reg |= SSCR0_SSE; 323 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR0, reg); 324} 325 326static void 327intelspi_set_cs(struct intelspi_softc *sc, int level) 328{ 329 uint32_t reg; 330 331 reg = INTELSPI_READ(sc, INTELSPI_SSPREG_SPI_CS_CTRL); 332 reg &= ~(SPI_CS_CTRL_CS_MASK); 333 reg |= SPI_CS_CTRL_SW_MODE; 334 335 if (level == CS_HIGH) 336 reg |= SPI_CS_CTRL_CS_HIGH; 337 else 338 reg |= SPI_CS_CTRL_CS_LOW; 339 340 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SPI_CS_CTRL, reg); 341} 342 343static int 344intelspi_transfer(device_t dev, device_t child, struct spi_command *cmd) 345{ 346 struct intelspi_softc *sc; 347 int err; 348 uint32_t sscr1; 349 350 sc = device_get_softc(dev); 351 err = 0; 352 353 KASSERT(cmd->tx_cmd_sz == cmd->rx_cmd_sz, 354 ("TX/RX command sizes should be equal")); 355 KASSERT(cmd->tx_data_sz == cmd->rx_data_sz, 356 ("TX/RX data sizes should be equal")); 357 358 INTELSPI_LOCK(sc); 359 360 /* If the controller is in use wait until it is available. */ 361 while (sc->sc_flags & INTELSPI_BUSY) { 362 err = mtx_sleep(dev, &sc->sc_mtx, 0, "intelspi", 0); 363 if (err == EINTR) { 364 INTELSPI_UNLOCK(sc); 365 return (err); 366 } 367 } 368 369 /* Now we have control over SPI controller. */ 370 sc->sc_flags = INTELSPI_BUSY; 371 372 /* Save a pointer to the SPI command. */ 373 sc->sc_cmd = cmd; 374 sc->sc_read = 0; 375 sc->sc_written = 0; 376 sc->sc_len = cmd->tx_cmd_sz + cmd->tx_data_sz; 377 378 /* Enable CS */ 379 intelspi_set_cs(sc, CS_LOW); 380 /* Transfer as much as possible to FIFOs */ 381 if (!intelspi_transact(sc)) { 382 /* If FIFO is not large enough - enable interrupts */ 383 sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1); 384 sscr1 |= (SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE); 385 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1); 386 387 /* and wait for transaction to complete */ 388 err = mtx_sleep(dev, &sc->sc_mtx, 0, "intelspi", hz * 2); 389 } 390 391 /* de-asser CS */ 392 intelspi_set_cs(sc, CS_HIGH); 393 394 /* Clear transaction details */ 395 sc->sc_cmd = NULL; 396 sc->sc_read = 0; 397 sc->sc_written = 0; 398 sc->sc_len = 0; 399 400 /* Make sure the SPI engine and interrupts are disabled. */ 401 sscr1 = INTELSPI_READ(sc, INTELSPI_SSPREG_SSCR1); 402 sscr1 &= ~(SSCR1_TIE | SSCR1_RIE | SSCR1_TINTE); 403 INTELSPI_WRITE(sc, INTELSPI_SSPREG_SSCR1, sscr1); 404 405 /* Release the controller and wakeup the next thread waiting for it. */ 406 sc->sc_flags = 0; 407 wakeup_one(dev); 408 INTELSPI_UNLOCK(sc); 409 410 /* 411 * Check for transfer timeout. The SPI controller doesn't 412 * return errors. 413 */ 414 if (err == EWOULDBLOCK) { 415 device_printf(sc->sc_dev, "transfer timeout\n"); 416 err = EIO; 417 } 418 419 return (err); 420} 421 422static int 423intelspi_probe(device_t dev) 424{ 425 static char *gpio_ids[] = { "80860F0E", NULL }; 426 427 if (acpi_disabled("spi") || 428 ACPI_ID_PROBE(device_get_parent(dev), dev, gpio_ids) == NULL) 429 return (ENXIO); 430 431 device_set_desc(dev, "Intel SPI Controller"); 432 return (0); 433} 434 435static int 436intelspi_attach(device_t dev) 437{ 438 struct intelspi_softc *sc; 439 440 sc = device_get_softc(dev); 441 sc->sc_dev = dev; 442 sc->sc_handle = acpi_get_handle(dev); 443 444 INTELSPI_LOCK_INIT(sc); 445 446 sc->sc_mem_rid = 0; 447 sc->sc_mem_res = bus_alloc_resource_any(sc->sc_dev, 448 SYS_RES_MEMORY, &sc->sc_mem_rid, RF_ACTIVE); 449 if (sc->sc_mem_res == NULL) { 450 device_printf(dev, "can't allocate memory resource\n"); 451 goto error; 452 } 453 454 sc->sc_irq_rid = 0; 455 sc->sc_irq_res = bus_alloc_resource_any(sc->sc_dev, 456 SYS_RES_IRQ, &sc->sc_irq_rid, RF_ACTIVE); 457 if (sc->sc_irq_res == NULL) { 458 device_printf(dev, "can't allocate IRQ resource\n"); 459 goto error; 460 } 461 462 /* Hook up our interrupt handler. */ 463 if (bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 464 NULL, intelspi_intr, sc, &sc->sc_irq_ih)) { 465 device_printf(dev, "cannot setup the interrupt handler\n"); 466 goto error; 467 } 468 469 intelspi_init(sc); 470 471 device_add_child(dev, "spibus", -1); 472 473 return (bus_generic_attach(dev)); 474 475error: 476 INTELSPI_LOCK_DESTROY(sc); 477 478 if (sc->sc_mem_res != NULL) 479 bus_release_resource(dev, SYS_RES_MEMORY, 480 sc->sc_mem_rid, sc->sc_mem_res); 481 482 if (sc->sc_irq_res != NULL) 483 bus_release_resource(dev, SYS_RES_IRQ, 484 sc->sc_irq_rid, sc->sc_irq_res); 485 486 return (ENXIO); 487} 488 489static int 490intelspi_detach(device_t dev) 491{ 492 struct intelspi_softc *sc; 493 494 sc = device_get_softc(dev); 495 496 INTELSPI_LOCK_DESTROY(sc); 497 498 if (sc->sc_irq_ih) 499 bus_teardown_intr(dev, sc->sc_irq_res, sc->sc_irq_ih); 500 501 if (sc->sc_mem_res != NULL) 502 bus_release_resource(dev, SYS_RES_MEMORY, 503 sc->sc_mem_rid, sc->sc_mem_res); 504 505 if (sc->sc_irq_res != NULL) 506 bus_release_resource(dev, SYS_RES_IRQ, 507 sc->sc_irq_rid, sc->sc_irq_res); 508 509 return (bus_generic_detach(dev)); 510} 511 512static device_method_t intelspi_methods[] = { 513 /* Device interface */ 514 DEVMETHOD(device_probe, intelspi_probe), 515 DEVMETHOD(device_attach, intelspi_attach), 516 DEVMETHOD(device_detach, intelspi_detach), 517 518 /* SPI interface */ 519 DEVMETHOD(spibus_transfer, intelspi_transfer), 520 521 DEVMETHOD_END 522}; 523 524static driver_t intelspi_driver = { 525 "spi", 526 intelspi_methods, 527 sizeof(struct intelspi_softc), 528}; 529 530static devclass_t intelspi_devclass; 531DRIVER_MODULE(intelspi, acpi, intelspi_driver, intelspi_devclass, 0, 0); 532MODULE_DEPEND(intelspi, acpi, 1, 1, 1); 533MODULE_DEPEND(intelspi, spibus, 1, 1, 1); 534