root/drivers/spi/spi-coldfire-qspi.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mcfqspi_wr_qmr
  2. mcfqspi_wr_qdlyr
  3. mcfqspi_rd_qdlyr
  4. mcfqspi_wr_qwr
  5. mcfqspi_wr_qir
  6. mcfqspi_wr_qar
  7. mcfqspi_wr_qdr
  8. mcfqspi_rd_qdr
  9. mcfqspi_cs_select
  10. mcfqspi_cs_deselect
  11. mcfqspi_cs_setup
  12. mcfqspi_cs_teardown
  13. mcfqspi_qmr_baud
  14. mcfqspi_qdlyr_spe
  15. mcfqspi_irq_handler
  16. mcfqspi_transfer_msg8
  17. mcfqspi_transfer_msg16
  18. mcfqspi_set_cs
  19. mcfqspi_transfer_one
  20. mcfqspi_setup
  21. mcfqspi_probe
  22. mcfqspi_remove
  23. mcfqspi_suspend
  24. mcfqspi_resume
  25. mcfqspi_runtime_suspend
  26. mcfqspi_runtime_resume

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Freescale/Motorola Coldfire Queued SPI driver
   4  *
   5  * Copyright 2010 Steven King <sfking@fdwdc.com>
   6 */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/interrupt.h>
  11 #include <linux/errno.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/sched.h>
  14 #include <linux/delay.h>
  15 #include <linux/io.h>
  16 #include <linux/clk.h>
  17 #include <linux/err.h>
  18 #include <linux/spi/spi.h>
  19 #include <linux/pm_runtime.h>
  20 
  21 #include <asm/coldfire.h>
  22 #include <asm/mcfsim.h>
  23 #include <asm/mcfqspi.h>
  24 
  25 #define DRIVER_NAME "mcfqspi"
  26 
  27 #define MCFQSPI_BUSCLK                  (MCF_BUSCLK / 2)
  28 
  29 #define MCFQSPI_QMR                     0x00
  30 #define         MCFQSPI_QMR_MSTR        0x8000
  31 #define         MCFQSPI_QMR_CPOL        0x0200
  32 #define         MCFQSPI_QMR_CPHA        0x0100
  33 #define MCFQSPI_QDLYR                   0x04
  34 #define         MCFQSPI_QDLYR_SPE       0x8000
  35 #define MCFQSPI_QWR                     0x08
  36 #define         MCFQSPI_QWR_HALT        0x8000
  37 #define         MCFQSPI_QWR_WREN        0x4000
  38 #define         MCFQSPI_QWR_CSIV        0x1000
  39 #define MCFQSPI_QIR                     0x0C
  40 #define         MCFQSPI_QIR_WCEFB       0x8000
  41 #define         MCFQSPI_QIR_ABRTB       0x4000
  42 #define         MCFQSPI_QIR_ABRTL       0x1000
  43 #define         MCFQSPI_QIR_WCEFE       0x0800
  44 #define         MCFQSPI_QIR_ABRTE       0x0400
  45 #define         MCFQSPI_QIR_SPIFE       0x0100
  46 #define         MCFQSPI_QIR_WCEF        0x0008
  47 #define         MCFQSPI_QIR_ABRT        0x0004
  48 #define         MCFQSPI_QIR_SPIF        0x0001
  49 #define MCFQSPI_QAR                     0x010
  50 #define         MCFQSPI_QAR_TXBUF       0x00
  51 #define         MCFQSPI_QAR_RXBUF       0x10
  52 #define         MCFQSPI_QAR_CMDBUF      0x20
  53 #define MCFQSPI_QDR                     0x014
  54 #define MCFQSPI_QCR                     0x014
  55 #define         MCFQSPI_QCR_CONT        0x8000
  56 #define         MCFQSPI_QCR_BITSE       0x4000
  57 #define         MCFQSPI_QCR_DT          0x2000
  58 
  59 struct mcfqspi {
  60         void __iomem *iobase;
  61         int irq;
  62         struct clk *clk;
  63         struct mcfqspi_cs_control *cs_control;
  64 
  65         wait_queue_head_t waitq;
  66 };
  67 
  68 static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
  69 {
  70         writew(val, mcfqspi->iobase + MCFQSPI_QMR);
  71 }
  72 
  73 static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val)
  74 {
  75         writew(val, mcfqspi->iobase + MCFQSPI_QDLYR);
  76 }
  77 
  78 static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi)
  79 {
  80         return readw(mcfqspi->iobase + MCFQSPI_QDLYR);
  81 }
  82 
  83 static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val)
  84 {
  85         writew(val, mcfqspi->iobase + MCFQSPI_QWR);
  86 }
  87 
  88 static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val)
  89 {
  90         writew(val, mcfqspi->iobase + MCFQSPI_QIR);
  91 }
  92 
  93 static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val)
  94 {
  95         writew(val, mcfqspi->iobase + MCFQSPI_QAR);
  96 }
  97 
  98 static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val)
  99 {
 100         writew(val, mcfqspi->iobase + MCFQSPI_QDR);
 101 }
 102 
 103 static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi)
 104 {
 105         return readw(mcfqspi->iobase + MCFQSPI_QDR);
 106 }
 107 
 108 static void mcfqspi_cs_select(struct mcfqspi *mcfqspi, u8 chip_select,
 109                             bool cs_high)
 110 {
 111         mcfqspi->cs_control->select(mcfqspi->cs_control, chip_select, cs_high);
 112 }
 113 
 114 static void mcfqspi_cs_deselect(struct mcfqspi *mcfqspi, u8 chip_select,
 115                                 bool cs_high)
 116 {
 117         mcfqspi->cs_control->deselect(mcfqspi->cs_control, chip_select, cs_high);
 118 }
 119 
 120 static int mcfqspi_cs_setup(struct mcfqspi *mcfqspi)
 121 {
 122         return (mcfqspi->cs_control->setup) ?
 123                 mcfqspi->cs_control->setup(mcfqspi->cs_control) : 0;
 124 }
 125 
 126 static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)
 127 {
 128         if (mcfqspi->cs_control->teardown)
 129                 mcfqspi->cs_control->teardown(mcfqspi->cs_control);
 130 }
 131 
 132 static u8 mcfqspi_qmr_baud(u32 speed_hz)
 133 {
 134         return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u);
 135 }
 136 
 137 static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi)
 138 {
 139         return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE;
 140 }
 141 
 142 static irqreturn_t mcfqspi_irq_handler(int this_irq, void *dev_id)
 143 {
 144         struct mcfqspi *mcfqspi = dev_id;
 145 
 146         /* clear interrupt */
 147         mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE | MCFQSPI_QIR_SPIF);
 148         wake_up(&mcfqspi->waitq);
 149 
 150         return IRQ_HANDLED;
 151 }
 152 
 153 static void mcfqspi_transfer_msg8(struct mcfqspi *mcfqspi, unsigned count,
 154                                   const u8 *txbuf, u8 *rxbuf)
 155 {
 156         unsigned i, n, offset = 0;
 157 
 158         n = min(count, 16u);
 159 
 160         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
 161         for (i = 0; i < n; ++i)
 162                 mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
 163 
 164         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
 165         if (txbuf)
 166                 for (i = 0; i < n; ++i)
 167                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
 168         else
 169                 for (i = 0; i < count; ++i)
 170                         mcfqspi_wr_qdr(mcfqspi, 0);
 171 
 172         count -= n;
 173         if (count) {
 174                 u16 qwr = 0xf08;
 175                 mcfqspi_wr_qwr(mcfqspi, 0x700);
 176                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 177 
 178                 do {
 179                         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
 180                         mcfqspi_wr_qwr(mcfqspi, qwr);
 181                         mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 182                         if (rxbuf) {
 183                                 mcfqspi_wr_qar(mcfqspi,
 184                                                MCFQSPI_QAR_RXBUF + offset);
 185                                 for (i = 0; i < 8; ++i)
 186                                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
 187                         }
 188                         n = min(count, 8u);
 189                         if (txbuf) {
 190                                 mcfqspi_wr_qar(mcfqspi,
 191                                                MCFQSPI_QAR_TXBUF + offset);
 192                                 for (i = 0; i < n; ++i)
 193                                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
 194                         }
 195                         qwr = (offset ? 0x808 : 0) + ((n - 1) << 8);
 196                         offset ^= 8;
 197                         count -= n;
 198                 } while (count);
 199                 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
 200                 mcfqspi_wr_qwr(mcfqspi, qwr);
 201                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 202                 if (rxbuf) {
 203                         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
 204                         for (i = 0; i < 8; ++i)
 205                                 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
 206                         offset ^= 8;
 207                 }
 208         } else {
 209                 mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
 210                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 211         }
 212         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
 213         if (rxbuf) {
 214                 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
 215                 for (i = 0; i < n; ++i)
 216                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
 217         }
 218 }
 219 
 220 static void mcfqspi_transfer_msg16(struct mcfqspi *mcfqspi, unsigned count,
 221                                    const u16 *txbuf, u16 *rxbuf)
 222 {
 223         unsigned i, n, offset = 0;
 224 
 225         n = min(count, 16u);
 226 
 227         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_CMDBUF);
 228         for (i = 0; i < n; ++i)
 229                 mcfqspi_wr_qdr(mcfqspi, MCFQSPI_QCR_BITSE);
 230 
 231         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_TXBUF);
 232         if (txbuf)
 233                 for (i = 0; i < n; ++i)
 234                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
 235         else
 236                 for (i = 0; i < count; ++i)
 237                         mcfqspi_wr_qdr(mcfqspi, 0);
 238 
 239         count -= n;
 240         if (count) {
 241                 u16 qwr = 0xf08;
 242                 mcfqspi_wr_qwr(mcfqspi, 0x700);
 243                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 244 
 245                 do {
 246                         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
 247                         mcfqspi_wr_qwr(mcfqspi, qwr);
 248                         mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 249                         if (rxbuf) {
 250                                 mcfqspi_wr_qar(mcfqspi,
 251                                                MCFQSPI_QAR_RXBUF + offset);
 252                                 for (i = 0; i < 8; ++i)
 253                                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
 254                         }
 255                         n = min(count, 8u);
 256                         if (txbuf) {
 257                                 mcfqspi_wr_qar(mcfqspi,
 258                                                MCFQSPI_QAR_TXBUF + offset);
 259                                 for (i = 0; i < n; ++i)
 260                                         mcfqspi_wr_qdr(mcfqspi, *txbuf++);
 261                         }
 262                         qwr = (offset ? 0x808 : 0x000) + ((n - 1) << 8);
 263                         offset ^= 8;
 264                         count -= n;
 265                 } while (count);
 266                 wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
 267                 mcfqspi_wr_qwr(mcfqspi, qwr);
 268                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 269                 if (rxbuf) {
 270                         mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
 271                         for (i = 0; i < 8; ++i)
 272                                 *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
 273                         offset ^= 8;
 274                 }
 275         } else {
 276                 mcfqspi_wr_qwr(mcfqspi, (n - 1) << 8);
 277                 mcfqspi_wr_qdlyr(mcfqspi, MCFQSPI_QDLYR_SPE);
 278         }
 279         wait_event(mcfqspi->waitq, !mcfqspi_qdlyr_spe(mcfqspi));
 280         if (rxbuf) {
 281                 mcfqspi_wr_qar(mcfqspi, MCFQSPI_QAR_RXBUF + offset);
 282                 for (i = 0; i < n; ++i)
 283                         *rxbuf++ = mcfqspi_rd_qdr(mcfqspi);
 284         }
 285 }
 286 
 287 static void mcfqspi_set_cs(struct spi_device *spi, bool enable)
 288 {
 289         struct mcfqspi *mcfqspi = spi_master_get_devdata(spi->master);
 290         bool cs_high = spi->mode & SPI_CS_HIGH;
 291 
 292         if (enable)
 293                 mcfqspi_cs_select(mcfqspi, spi->chip_select, cs_high);
 294         else
 295                 mcfqspi_cs_deselect(mcfqspi, spi->chip_select, cs_high);
 296 }
 297 
 298 static int mcfqspi_transfer_one(struct spi_master *master,
 299                                 struct spi_device *spi,
 300                                 struct spi_transfer *t)
 301 {
 302         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 303         u16 qmr = MCFQSPI_QMR_MSTR;
 304 
 305         qmr |= t->bits_per_word << 10;
 306         if (spi->mode & SPI_CPHA)
 307                 qmr |= MCFQSPI_QMR_CPHA;
 308         if (spi->mode & SPI_CPOL)
 309                 qmr |= MCFQSPI_QMR_CPOL;
 310         qmr |= mcfqspi_qmr_baud(t->speed_hz);
 311         mcfqspi_wr_qmr(mcfqspi, qmr);
 312 
 313         mcfqspi_wr_qir(mcfqspi, MCFQSPI_QIR_SPIFE);
 314         if (t->bits_per_word == 8)
 315                 mcfqspi_transfer_msg8(mcfqspi, t->len, t->tx_buf, t->rx_buf);
 316         else
 317                 mcfqspi_transfer_msg16(mcfqspi, t->len / 2, t->tx_buf,
 318                                        t->rx_buf);
 319         mcfqspi_wr_qir(mcfqspi, 0);
 320 
 321         return 0;
 322 }
 323 
 324 static int mcfqspi_setup(struct spi_device *spi)
 325 {
 326         mcfqspi_cs_deselect(spi_master_get_devdata(spi->master),
 327                             spi->chip_select, spi->mode & SPI_CS_HIGH);
 328 
 329         dev_dbg(&spi->dev,
 330                         "bits per word %d, chip select %d, speed %d KHz\n",
 331                         spi->bits_per_word, spi->chip_select,
 332                         (MCFQSPI_BUSCLK / mcfqspi_qmr_baud(spi->max_speed_hz))
 333                         / 1000);
 334 
 335         return 0;
 336 }
 337 
 338 static int mcfqspi_probe(struct platform_device *pdev)
 339 {
 340         struct spi_master *master;
 341         struct mcfqspi *mcfqspi;
 342         struct mcfqspi_platform_data *pdata;
 343         int status;
 344 
 345         pdata = dev_get_platdata(&pdev->dev);
 346         if (!pdata) {
 347                 dev_dbg(&pdev->dev, "platform data is missing\n");
 348                 return -ENOENT;
 349         }
 350 
 351         if (!pdata->cs_control) {
 352                 dev_dbg(&pdev->dev, "pdata->cs_control is NULL\n");
 353                 return -EINVAL;
 354         }
 355 
 356         master = spi_alloc_master(&pdev->dev, sizeof(*mcfqspi));
 357         if (master == NULL) {
 358                 dev_dbg(&pdev->dev, "spi_alloc_master failed\n");
 359                 return -ENOMEM;
 360         }
 361 
 362         mcfqspi = spi_master_get_devdata(master);
 363 
 364         mcfqspi->iobase = devm_platform_ioremap_resource(pdev, 0);
 365         if (IS_ERR(mcfqspi->iobase)) {
 366                 status = PTR_ERR(mcfqspi->iobase);
 367                 goto fail0;
 368         }
 369 
 370         mcfqspi->irq = platform_get_irq(pdev, 0);
 371         if (mcfqspi->irq < 0) {
 372                 dev_dbg(&pdev->dev, "platform_get_irq failed\n");
 373                 status = -ENXIO;
 374                 goto fail0;
 375         }
 376 
 377         status = devm_request_irq(&pdev->dev, mcfqspi->irq, mcfqspi_irq_handler,
 378                                 0, pdev->name, mcfqspi);
 379         if (status) {
 380                 dev_dbg(&pdev->dev, "request_irq failed\n");
 381                 goto fail0;
 382         }
 383 
 384         mcfqspi->clk = devm_clk_get(&pdev->dev, "qspi_clk");
 385         if (IS_ERR(mcfqspi->clk)) {
 386                 dev_dbg(&pdev->dev, "clk_get failed\n");
 387                 status = PTR_ERR(mcfqspi->clk);
 388                 goto fail0;
 389         }
 390         clk_enable(mcfqspi->clk);
 391 
 392         master->bus_num = pdata->bus_num;
 393         master->num_chipselect = pdata->num_chipselect;
 394 
 395         mcfqspi->cs_control = pdata->cs_control;
 396         status = mcfqspi_cs_setup(mcfqspi);
 397         if (status) {
 398                 dev_dbg(&pdev->dev, "error initializing cs_control\n");
 399                 goto fail1;
 400         }
 401 
 402         init_waitqueue_head(&mcfqspi->waitq);
 403 
 404         master->mode_bits = SPI_CS_HIGH | SPI_CPOL | SPI_CPHA;
 405         master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 16);
 406         master->setup = mcfqspi_setup;
 407         master->set_cs = mcfqspi_set_cs;
 408         master->transfer_one = mcfqspi_transfer_one;
 409         master->auto_runtime_pm = true;
 410 
 411         platform_set_drvdata(pdev, master);
 412         pm_runtime_enable(&pdev->dev);
 413 
 414         status = devm_spi_register_master(&pdev->dev, master);
 415         if (status) {
 416                 dev_dbg(&pdev->dev, "spi_register_master failed\n");
 417                 goto fail2;
 418         }
 419 
 420         dev_info(&pdev->dev, "Coldfire QSPI bus driver\n");
 421 
 422         return 0;
 423 
 424 fail2:
 425         pm_runtime_disable(&pdev->dev);
 426         mcfqspi_cs_teardown(mcfqspi);
 427 fail1:
 428         clk_disable(mcfqspi->clk);
 429 fail0:
 430         spi_master_put(master);
 431 
 432         dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
 433 
 434         return status;
 435 }
 436 
 437 static int mcfqspi_remove(struct platform_device *pdev)
 438 {
 439         struct spi_master *master = platform_get_drvdata(pdev);
 440         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 441 
 442         pm_runtime_disable(&pdev->dev);
 443         /* disable the hardware (set the baud rate to 0) */
 444         mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
 445 
 446         mcfqspi_cs_teardown(mcfqspi);
 447         clk_disable(mcfqspi->clk);
 448 
 449         return 0;
 450 }
 451 
 452 #ifdef CONFIG_PM_SLEEP
 453 static int mcfqspi_suspend(struct device *dev)
 454 {
 455         struct spi_master *master = dev_get_drvdata(dev);
 456         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 457         int ret;
 458 
 459         ret = spi_master_suspend(master);
 460         if (ret)
 461                 return ret;
 462 
 463         clk_disable(mcfqspi->clk);
 464 
 465         return 0;
 466 }
 467 
 468 static int mcfqspi_resume(struct device *dev)
 469 {
 470         struct spi_master *master = dev_get_drvdata(dev);
 471         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 472 
 473         clk_enable(mcfqspi->clk);
 474 
 475         return spi_master_resume(master);
 476 }
 477 #endif
 478 
 479 #ifdef CONFIG_PM
 480 static int mcfqspi_runtime_suspend(struct device *dev)
 481 {
 482         struct spi_master *master = dev_get_drvdata(dev);
 483         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 484 
 485         clk_disable(mcfqspi->clk);
 486 
 487         return 0;
 488 }
 489 
 490 static int mcfqspi_runtime_resume(struct device *dev)
 491 {
 492         struct spi_master *master = dev_get_drvdata(dev);
 493         struct mcfqspi *mcfqspi = spi_master_get_devdata(master);
 494 
 495         clk_enable(mcfqspi->clk);
 496 
 497         return 0;
 498 }
 499 #endif
 500 
 501 static const struct dev_pm_ops mcfqspi_pm = {
 502         SET_SYSTEM_SLEEP_PM_OPS(mcfqspi_suspend, mcfqspi_resume)
 503         SET_RUNTIME_PM_OPS(mcfqspi_runtime_suspend, mcfqspi_runtime_resume,
 504                         NULL)
 505 };
 506 
 507 static struct platform_driver mcfqspi_driver = {
 508         .driver.name    = DRIVER_NAME,
 509         .driver.owner   = THIS_MODULE,
 510         .driver.pm      = &mcfqspi_pm,
 511         .probe          = mcfqspi_probe,
 512         .remove         = mcfqspi_remove,
 513 };
 514 module_platform_driver(mcfqspi_driver);
 515 
 516 MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
 517 MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
 518 MODULE_LICENSE("GPL");
 519 MODULE_ALIAS("platform:" DRIVER_NAME);

/* [<][>][^][v][top][bottom][index][help] */