1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <errno.h> 18#include <string.h> 19 20#include <gpio.h> 21#include <spi.h> 22#include <spi_priv.h> 23#include <util.h> 24#include <atomicBitset.h> 25#include <atomic.h> 26#include <platform.h> 27 28#include <plat/cmsis.h> 29#include <plat/dma.h> 30#include <plat/gpio.h> 31#include <plat/pwr.h> 32#include <plat/exti.h> 33#include <plat/syscfg.h> 34#include <plat/spi.h> 35#include <plat/plat.h> 36 37#define SPI_CR1_CPHA (1 << 0) 38#define SPI_CR1_CPOL (1 << 1) 39#define SPI_CR1_MSTR (1 << 2) 40 41#define SPI_CR1_BR(x) ((LOG2_CEIL(x) - 1) << 3) 42#define SPI_CR1_BR_MIN 2 43#define SPI_CR1_BR_MAX 256 44#define SPI_CR1_BR_MASK (0x7 << 3) 45 46#define SPI_CR1_SPE (1 << 6) 47#define SPI_CR1_LSBFIRST (1 << 7) 48#define SPI_CR1_SSI (1 << 8) 49#define SPI_CR1_SSM (1 << 9) 50#define SPI_CR1_RXONLY (1 << 10) 51#define SPI_CR1_DFF (1 << 11) 52#define SPI_CR1_BIDIOE (1 << 14) 53#define SPI_CR1_BIDIMODE (1 << 15) 54 55#define SPI_CR2_TXEIE (1 << 7) 56#define SPI_CR2_RXNEIE (1 << 6) 57#define SPI_CR2_ERRIE (1 << 5) 58#define SPI_CR2_TXDMAEN (1 << 1) 59#define SPI_CR2_RXDMAEN (1 << 0) 60#define SPI_CR2_INT_MASK (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE) 61 62#define SPI_CR2_SSOE (1 << 2) 63 64#define SPI_SR_RXNE (1 << 0) 65#define SPI_SR_TXE (1 << 1) 66#define SPI_SR_BSY (1 << 7) 67 68struct StmSpi { 69 volatile uint32_t CR1; 70 volatile uint32_t CR2; 71 volatile uint32_t SR; 72 volatile uint32_t DR; 73 volatile uint32_t CRCPR; 74 volatile uint32_t RXCRCR; 75 volatile uint32_t TXCRCR; 76 volatile uint32_t I2SCFGR; 77 volatile uint32_t I2SPR; 78}; 79 80struct StmSpiState { 81 uint8_t bitsPerWord; 82 uint8_t xferEnable; 83 84 uint16_t rxWord; 85 uint16_t txWord; 86 87 bool rxDone; 88 bool txDone; 89 90 struct ChainedIsr isrNss; 91 92 bool nssChange; 93}; 94 95struct StmSpiCfg { 96 struct StmSpi *regs; 97 98 uint32_t clockBus; 99 uint32_t clockUnit; 100 101 IRQn_Type irq; 102 103 uint8_t dmaBus; 104}; 105 106struct StmSpiDev { 107 struct SpiDevice *base; 108 const struct StmSpiCfg *cfg; 109 const struct StmSpiBoardCfg *board; 110 struct StmSpiState state; 111 112 struct Gpio *miso; 113 struct Gpio *mosi; 114 struct Gpio *sck; 115 struct Gpio *nss; 116}; 117 118static inline struct Gpio *stmSpiGpioInit(uint32_t gpioNum, enum StmGpioSpeed speed, enum StmGpioAltFunc func) 119{ 120 struct Gpio *gpio = gpioRequest(gpioNum); 121 122 if (gpio) 123 gpioConfigAlt(gpio, speed, GPIO_PULL_NONE, GPIO_OUT_PUSH_PULL, func); 124 125 return gpio; 126} 127 128static inline void stmSpiDataPullMode(struct StmSpiDev *pdev, enum StmGpioSpeed dataSpeed, enum GpioPullMode dataPull) 129{ 130 gpioConfigAlt(pdev->miso, dataSpeed, dataPull, GPIO_OUT_PUSH_PULL, pdev->board->gpioFunc); 131 gpioConfigAlt(pdev->mosi, dataSpeed, dataPull, GPIO_OUT_PUSH_PULL, pdev->board->gpioFunc); 132} 133 134static inline void stmSpiSckPullMode(struct StmSpiDev *pdev, enum StmGpioSpeed sckSpeed, enum GpioPullMode sckPull) 135{ 136 gpioConfigAlt(pdev->sck, sckSpeed, sckPull, GPIO_OUT_PUSH_PULL, pdev->board->gpioFunc); 137} 138 139static inline void stmSpiStartDma(struct StmSpiDev *pdev, 140 const struct StmSpiDmaCfg *dmaCfg, const void *buf, uint8_t bitsPerWord, 141 bool minc, size_t size, DmaCallbackF callback, bool rx) 142{ 143 struct StmSpi *regs = pdev->cfg->regs; 144 struct dmaMode mode; 145 146 memset(&mode, 0, sizeof(mode)); 147 148 if (bitsPerWord == 8) { 149 mode.psize = DMA_SIZE_8_BITS; 150 mode.msize = DMA_SIZE_8_BITS; 151 } else { 152 mode.psize = DMA_SIZE_16_BITS; 153 mode.msize = DMA_SIZE_16_BITS; 154 } 155 mode.priority = DMA_PRIORITY_HIGH; 156 mode.direction = rx ? DMA_DIRECTION_PERIPH_TO_MEM : 157 DMA_DIRECTION_MEM_TO_PERIPH; 158 mode.periphAddr = (uintptr_t)®s->DR; 159 mode.minc = minc; 160 mode.channel = dmaCfg->channel; 161 162 dmaStart(pdev->cfg->dmaBus, dmaCfg->stream, buf, size, &mode, callback, 163 pdev); 164} 165 166static inline int stmSpiEnable(struct StmSpiDev *pdev, 167 const struct SpiMode *mode, bool master) 168{ 169 struct StmSpi *regs = pdev->cfg->regs; 170 struct StmSpiState *state = &pdev->state; 171 172 if (mode->bitsPerWord != 8 && 173 mode->bitsPerWord != 16) 174 return -EINVAL; 175 176 unsigned int div; 177 if (master) { 178 if (!mode->speed) 179 return -EINVAL; 180 181 uint32_t pclk = pwrGetBusSpeed(PERIPH_BUS_AHB1); 182 div = pclk / mode->speed; 183 if (div > SPI_CR1_BR_MAX) 184 return -EINVAL; 185 else if (div < SPI_CR1_BR_MIN) 186 div = SPI_CR1_BR_MIN; 187 } 188 189 atomicWriteByte(&state->xferEnable, false); 190 191 state->txWord = mode->txWord; 192 state->bitsPerWord = mode->bitsPerWord; 193 194 pwrUnitClock(pdev->cfg->clockBus, pdev->cfg->clockUnit, true); 195 196 if (master) { 197 regs->CR1 &= ~SPI_CR1_BR_MASK; 198 regs->CR1 |= SPI_CR1_BR(div); 199 } 200 201 if (mode->cpol == SPI_CPOL_IDLE_LO) 202 regs->CR1 &= ~SPI_CR1_CPOL; 203 else 204 regs->CR1 |= SPI_CR1_CPOL; 205 206 if (mode->cpha == SPI_CPHA_LEADING_EDGE) 207 regs->CR1 &= ~SPI_CR1_CPHA; 208 else 209 regs->CR1 |= SPI_CR1_CPHA; 210 211 if (mode->bitsPerWord == 8) 212 regs->CR1 &= ~SPI_CR1_DFF; 213 else 214 regs->CR1 |= SPI_CR1_DFF; 215 216 if (mode->format == SPI_FORMAT_MSB_FIRST) 217 regs->CR1 &= ~SPI_CR1_LSBFIRST; 218 else 219 regs->CR1 |= SPI_CR1_LSBFIRST; 220 221 if (master) 222 regs->CR1 |= SPI_CR1_SSI | SPI_CR1_SSM | SPI_CR1_MSTR; 223 else 224 regs->CR1 &= ~(SPI_CR1_SSM | SPI_CR1_MSTR); 225 226 return 0; 227} 228 229static int stmSpiMasterStartSync(struct SpiDevice *dev, spi_cs_t cs, 230 const struct SpiMode *mode) 231{ 232 struct StmSpiDev *pdev = dev->pdata; 233 234 int err = stmSpiEnable(pdev, mode, true); 235 if (err < 0) 236 return err; 237 238 stmSpiDataPullMode(pdev, pdev->board->gpioSpeed, pdev->board->gpioPull); 239 stmSpiSckPullMode(pdev, pdev->board->gpioSpeed, mode->cpol ? GPIO_PULL_UP : GPIO_PULL_DOWN); 240 241 if (!pdev->nss) 242 pdev->nss = gpioRequest(cs); 243 if (!pdev->nss) 244 return -ENODEV; 245 gpioConfigOutput(pdev->nss, pdev->board->gpioSpeed, pdev->board->gpioPull, GPIO_OUT_PUSH_PULL, 1); 246 247 return 0; 248} 249 250static int stmSpiSlaveStartSync(struct SpiDevice *dev, 251 const struct SpiMode *mode) 252{ 253 struct StmSpiDev *pdev = dev->pdata; 254 255 stmSpiDataPullMode(pdev, pdev->board->gpioSpeed, GPIO_PULL_NONE); 256 stmSpiSckPullMode(pdev, pdev->board->gpioSpeed, GPIO_PULL_NONE); 257 258 if (!pdev->nss) 259 pdev->nss = stmSpiGpioInit(pdev->board->gpioNss, pdev->board->gpioSpeed, pdev->board->gpioFunc); 260 if (!pdev->nss) 261 return -ENODEV; 262 263 return stmSpiEnable(pdev, mode, false); 264} 265 266static inline bool stmSpiIsMaster(struct StmSpiDev *pdev) 267{ 268 struct StmSpi *regs = pdev->cfg->regs; 269 return !!(regs->CR1 & SPI_CR1_MSTR); 270} 271 272static void stmSpiDone(struct StmSpiDev *pdev, int err) 273{ 274 struct StmSpi *regs = pdev->cfg->regs; 275 struct StmSpiState *state = &pdev->state; 276 277 if (pdev->board->sleepDev >= 0) 278 platReleaseDevInSleepMode(pdev->board->sleepDev); 279 280 while (regs->SR & SPI_SR_BSY) 281 ; 282 283 if (stmSpiIsMaster(pdev)) { 284 if (state->nssChange && pdev->nss) 285 gpioSet(pdev->nss, 1); 286 spiMasterRxTxDone(pdev->base, err); 287 } else { 288 regs->CR2 = SPI_CR2_TXEIE; 289 spiSlaveRxTxDone(pdev->base, err); 290 } 291} 292 293static void stmSpiRxDone(void *cookie, uint16_t bytesLeft, int err) 294{ 295 struct StmSpiDev *pdev = cookie; 296 struct StmSpi *regs = pdev->cfg->regs; 297 struct StmSpiState *state = &pdev->state; 298 299 regs->CR2 &= ~SPI_CR2_RXDMAEN; 300 state->rxDone = true; 301 302 if (state->txDone) { 303 atomicWriteByte(&state->xferEnable, false); 304 stmSpiDone(pdev, err); 305 } 306} 307 308static void stmSpiTxDone(void *cookie, uint16_t bytesLeft, int err) 309{ 310 struct StmSpiDev *pdev = cookie; 311 struct StmSpi *regs = pdev->cfg->regs; 312 struct StmSpiState *state = &pdev->state; 313 314 regs->CR2 &= ~SPI_CR2_TXDMAEN; 315 state->txDone = true; 316 317 if (state->rxDone) { 318 atomicWriteByte(&state->xferEnable, false); 319 stmSpiDone(pdev, err); 320 } 321} 322 323static int stmSpiRxTx(struct SpiDevice *dev, void *rxBuf, const void *txBuf, 324 size_t size, const struct SpiMode *mode) 325{ 326 struct StmSpiDev *pdev = dev->pdata; 327 struct StmSpi *regs = pdev->cfg->regs; 328 struct StmSpiState *state = &pdev->state; 329 bool rxMinc = true, txMinc = true; 330 uint32_t cr2 = SPI_CR2_TXDMAEN; 331 332 if (atomicXchgByte(&state->xferEnable, true) == true) 333 return -EBUSY; 334 335 if (stmSpiIsMaster(pdev) && pdev->nss) 336 gpioSet(pdev->nss, 0); 337 338 state->rxDone = false; 339 state->txDone = false; 340 state->nssChange = mode->nssChange; 341 342 /* In master mode, if RX is ignored at any point, then turning it on 343 * later may cause the SPI/DMA controllers to "receive" a stale byte 344 * sitting in a FIFO somewhere (even when their respective registers say 345 * their FIFOs are empty, and even if the SPI FIFO is explicitly cleared). 346 * Work around this by DMAing bytes we don't care about into a throwaway 347 * 1-word buffer. 348 * 349 * In slave mode, this specific WAR sometimes causes bigger problems 350 * (the first byte TXed is sometimes dropped or corrupted). Slave mode 351 * has its own WARs below. 352 */ 353 if (!rxBuf && stmSpiIsMaster(pdev)) { 354 rxBuf = &state->rxWord; 355 rxMinc = false; 356 } 357 358 if (rxBuf) { 359 stmSpiStartDma(pdev, &pdev->board->dmaRx, rxBuf, mode->bitsPerWord, 360 rxMinc, size, stmSpiRxDone, true); 361 cr2 |= SPI_CR2_RXDMAEN; 362 } else { 363 state->rxDone = true; 364 } 365 366 if (!txBuf) { 367 txBuf = &state->txWord; 368 txMinc = false; 369 } 370 stmSpiStartDma(pdev, &pdev->board->dmaTx, txBuf, mode->bitsPerWord, txMinc, 371 size, stmSpiTxDone, false); 372 373 /* Ensure the TXE and RXNE bits are cleared; otherwise the DMA controller 374 * may "receive" the byte sitting in the SPI controller's FIFO right now, 375 * or drop/corrupt the first TX byte. Timing is crucial here, so do it 376 * right before enabling DMA. 377 */ 378 if (!stmSpiIsMaster(pdev)) { 379 regs->CR2 &= ~SPI_CR2_TXEIE; 380 NVIC_ClearPendingIRQ(pdev->cfg->irq); 381 382 if (regs->SR & SPI_SR_RXNE) 383 (void)regs->DR; 384 385 if (regs->SR & SPI_SR_TXE) 386 regs->DR = mode->txWord; 387 } 388 389 if (pdev->board->sleepDev >= 0) 390 platRequestDevInSleepMode(pdev->board->sleepDev, 12); 391 392 regs->CR2 = cr2; 393 regs->CR1 |= SPI_CR1_SPE; 394 395 396 return 0; 397} 398 399static int stmSpiSlaveIdle(struct SpiDevice *dev, const struct SpiMode *mode) 400{ 401 struct StmSpiDev *pdev = dev->pdata; 402 struct StmSpi *regs = pdev->cfg->regs; 403 struct StmSpiState *state = &pdev->state; 404 405 if (atomicXchgByte(&state->xferEnable, true) == true) 406 return -EBUSY; 407 408 regs->CR2 = SPI_CR2_TXEIE; 409 regs->CR1 |= SPI_CR1_SPE; 410 411 atomicXchgByte(&state->xferEnable, false); 412 return 0; 413} 414 415static inline void stmSpiDisable(struct SpiDevice *dev, bool master) 416{ 417 struct StmSpiDev *pdev = dev->pdata; 418 struct StmSpi *regs = pdev->cfg->regs; 419 420 while (regs->SR & SPI_SR_BSY) 421 ; 422 423 if (master) { 424 stmSpiSckPullMode(pdev, pdev->board->gpioSpeed, pdev->board->gpioPull); 425 } 426 427 regs->CR2 &= ~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN | SPI_CR2_TXEIE); 428 regs->CR1 &= ~SPI_CR1_SPE; 429 pwrUnitClock(pdev->cfg->clockBus, pdev->cfg->clockUnit, false); 430} 431 432static int stmSpiMasterStopSync(struct SpiDevice *dev) 433{ 434 struct StmSpiDev *pdev = dev->pdata; 435 436 if (pdev->nss) { 437 gpioSet(pdev->nss, 1); 438 gpioRelease(pdev->nss); 439 } 440 441 stmSpiDisable(dev, true); 442 pdev->nss = NULL; 443 return 0; 444} 445 446static int stmSpiSlaveStopSync(struct SpiDevice *dev) 447{ 448 struct StmSpiDev *pdev = dev->pdata; 449 450 if (pdev->nss) 451 gpioRelease(pdev->nss); 452 453 stmSpiDisable(dev, false); 454 pdev->nss = NULL; 455 return 0; 456} 457 458static bool stmSpiExtiIsr(struct ChainedIsr *isr) 459{ 460 struct StmSpiState *state = container_of(isr, struct StmSpiState, isrNss); 461 struct StmSpiDev *pdev = container_of(state, struct StmSpiDev, state); 462 463 if (pdev->nss && !extiIsPendingGpio(pdev->nss)) 464 return false; 465 466 spiSlaveCsInactive(pdev->base); 467 if (pdev->nss) 468 extiClearPendingGpio(pdev->nss); 469 return true; 470} 471 472static void stmSpiSlaveSetCsInterrupt(struct SpiDevice *dev, bool enabled) 473{ 474 struct StmSpiDev *pdev = dev->pdata; 475 struct ChainedIsr *isr = &pdev->state.isrNss; 476 477 if (enabled) { 478 isr->func = stmSpiExtiIsr; 479 480 if (pdev->nss) { 481 syscfgSetExtiPort(pdev->nss); 482 extiEnableIntGpio(pdev->nss, EXTI_TRIGGER_RISING); 483 } 484 extiChainIsr(pdev->board->irqNss, isr); 485 } else { 486 extiUnchainIsr(pdev->board->irqNss, isr); 487 if (pdev->nss) 488 extiDisableIntGpio(pdev->nss); 489 } 490} 491 492static bool stmSpiSlaveCsIsActive(struct SpiDevice *dev) 493{ 494 struct StmSpiDev *pdev = dev->pdata; 495 return pdev->nss && !gpioGet(pdev->nss); 496} 497 498static inline void stmSpiTxe(struct StmSpiDev *pdev) 499{ 500 struct StmSpi *regs = pdev->cfg->regs; 501 502 /** 503 * n.b.: if nothing handles the TXE interrupt in slave mode, the SPI 504 * controller will just keep reading the existing value from DR anytime it 505 * needs data 506 */ 507 regs->DR = pdev->state.txWord; 508 regs->CR2 &= ~SPI_CR2_TXEIE; 509} 510 511static void stmSpiIsr(struct StmSpiDev *pdev) 512{ 513 struct StmSpi *regs = pdev->cfg->regs; 514 515 if (regs->SR & SPI_SR_TXE) { 516 stmSpiTxe(pdev); 517 } 518 519 /* TODO: error conditions */ 520} 521 522static int stmSpiRelease(struct SpiDevice *dev) 523{ 524 struct StmSpiDev *pdev = dev->pdata; 525 526 NVIC_DisableIRQ(pdev->cfg->irq); 527 528 pdev->base = NULL; 529 return 0; 530} 531 532#define DECLARE_IRQ_HANDLER(_n) \ 533 void SPI##_n##_IRQHandler(); \ 534 void SPI##_n##_IRQHandler() \ 535 { \ 536 stmSpiIsr(&mStmSpiDevs[_n - 1]); \ 537 } 538 539const struct SpiDevice_ops mStmSpiOps = { 540 .masterStartSync = stmSpiMasterStartSync, 541 .masterRxTx = stmSpiRxTx, 542 .masterStopSync = stmSpiMasterStopSync, 543 544 .slaveStartSync = stmSpiSlaveStartSync, 545 .slaveIdle = stmSpiSlaveIdle, 546 .slaveRxTx = stmSpiRxTx, 547 .slaveStopSync = stmSpiSlaveStopSync, 548 549 .slaveSetCsInterrupt = stmSpiSlaveSetCsInterrupt, 550 .slaveCsIsActive = stmSpiSlaveCsIsActive, 551 552 .release = stmSpiRelease, 553}; 554 555static const struct StmSpiCfg mStmSpiCfgs[] = { 556 [0] = { 557 .regs = (struct StmSpi *)SPI1_BASE, 558 559 .clockBus = PERIPH_BUS_APB2, 560 .clockUnit = PERIPH_APB2_SPI1, 561 562 .irq = SPI1_IRQn, 563 564 .dmaBus = SPI1_DMA_BUS, 565 }, 566 [1] = { 567 .regs = (struct StmSpi *)SPI2_BASE, 568 569 .clockBus = PERIPH_BUS_APB1, 570 .clockUnit = PERIPH_APB1_SPI2, 571 572 .irq = SPI2_IRQn, 573 574 .dmaBus = SPI2_DMA_BUS, 575 }, 576 [2] = { 577 .regs = (struct StmSpi *)SPI3_BASE, 578 579 .clockBus = PERIPH_BUS_APB1, 580 .clockUnit = PERIPH_APB1_SPI3, 581 582 .irq = SPI3_IRQn, 583 584 .dmaBus = SPI3_DMA_BUS, 585 }, 586}; 587 588static struct StmSpiDev mStmSpiDevs[ARRAY_SIZE(mStmSpiCfgs)]; 589DECLARE_IRQ_HANDLER(1) 590DECLARE_IRQ_HANDLER(2) 591DECLARE_IRQ_HANDLER(3) 592 593static void stmSpiInit(struct StmSpiDev *pdev, const struct StmSpiCfg *cfg, 594 const struct StmSpiBoardCfg *board, struct SpiDevice *dev) 595{ 596 pdev->miso = stmSpiGpioInit(board->gpioMiso, board->gpioSpeed, board->gpioFunc); 597 pdev->mosi = stmSpiGpioInit(board->gpioMosi, board->gpioSpeed, board->gpioFunc); 598 pdev->sck = stmSpiGpioInit(board->gpioSclk, board->gpioSpeed, board->gpioFunc); 599 600 NVIC_EnableIRQ(cfg->irq); 601 602 pdev->base = dev; 603 pdev->cfg = cfg; 604 pdev->board = board; 605} 606 607int spiRequest(struct SpiDevice *dev, uint8_t busId) 608{ 609 if (busId >= ARRAY_SIZE(mStmSpiDevs)) 610 return -ENODEV; 611 612 const struct StmSpiBoardCfg *board = boardStmSpiCfg(busId); 613 if (!board) 614 return -ENODEV; 615 616 struct StmSpiDev *pdev = &mStmSpiDevs[busId]; 617 const struct StmSpiCfg *cfg = &mStmSpiCfgs[busId]; 618 if (!pdev->base) 619 stmSpiInit(pdev, cfg, board, dev); 620 621 memset(&pdev->state, 0, sizeof(pdev->state)); 622 dev->ops = &mStmSpiOps; 623 dev->pdata = pdev; 624 return 0; 625} 626 627const enum IRQn spiRxIrq(uint8_t busId) 628{ 629 if (busId >= ARRAY_SIZE(mStmSpiDevs)) 630 return -ENODEV; 631 632 struct StmSpiDev *pdev = &mStmSpiDevs[busId]; 633 634 return dmaIrq(pdev->cfg->dmaBus, pdev->board->dmaRx.stream); 635} 636 637const enum IRQn spiTxIrq(uint8_t busId) 638{ 639 if (busId >= ARRAY_SIZE(mStmSpiDevs)) 640 return -ENODEV; 641 642 struct StmSpiDev *pdev = &mStmSpiDevs[busId]; 643 644 return dmaIrq(pdev->cfg->dmaBus, pdev->board->dmaTx.stream); 645} 646