linux/drivers/spi/spi-coldfire-qspi.c
<<
>>
Prefs
   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
  59struct 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
  68static void mcfqspi_wr_qmr(struct mcfqspi *mcfqspi, u16 val)
  69{
  70        writew(val, mcfqspi->iobase + MCFQSPI_QMR);
  71}
  72
  73static void mcfqspi_wr_qdlyr(struct mcfqspi *mcfqspi, u16 val)
  74{
  75        writew(val, mcfqspi->iobase + MCFQSPI_QDLYR);
  76}
  77
  78static u16 mcfqspi_rd_qdlyr(struct mcfqspi *mcfqspi)
  79{
  80        return readw(mcfqspi->iobase + MCFQSPI_QDLYR);
  81}
  82
  83static void mcfqspi_wr_qwr(struct mcfqspi *mcfqspi, u16 val)
  84{
  85        writew(val, mcfqspi->iobase + MCFQSPI_QWR);
  86}
  87
  88static void mcfqspi_wr_qir(struct mcfqspi *mcfqspi, u16 val)
  89{
  90        writew(val, mcfqspi->iobase + MCFQSPI_QIR);
  91}
  92
  93static void mcfqspi_wr_qar(struct mcfqspi *mcfqspi, u16 val)
  94{
  95        writew(val, mcfqspi->iobase + MCFQSPI_QAR);
  96}
  97
  98static void mcfqspi_wr_qdr(struct mcfqspi *mcfqspi, u16 val)
  99{
 100        writew(val, mcfqspi->iobase + MCFQSPI_QDR);
 101}
 102
 103static u16 mcfqspi_rd_qdr(struct mcfqspi *mcfqspi)
 104{
 105        return readw(mcfqspi->iobase + MCFQSPI_QDR);
 106}
 107
 108static 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
 114static 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
 120static 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
 126static void mcfqspi_cs_teardown(struct mcfqspi *mcfqspi)
 127{
 128        if (mcfqspi->cs_control->teardown)
 129                mcfqspi->cs_control->teardown(mcfqspi->cs_control);
 130}
 131
 132static u8 mcfqspi_qmr_baud(u32 speed_hz)
 133{
 134        return clamp((MCFQSPI_BUSCLK + speed_hz - 1) / speed_hz, 2u, 255u);
 135}
 136
 137static bool mcfqspi_qdlyr_spe(struct mcfqspi *mcfqspi)
 138{
 139        return mcfqspi_rd_qdlyr(mcfqspi) & MCFQSPI_QDLYR_SPE;
 140}
 141
 142static 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
 153static 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
 220static 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
 287static 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
 298static 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
 324static 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
 338static 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_prepare_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
 424fail2:
 425        pm_runtime_disable(&pdev->dev);
 426        mcfqspi_cs_teardown(mcfqspi);
 427fail1:
 428        clk_disable_unprepare(mcfqspi->clk);
 429fail0:
 430        spi_master_put(master);
 431
 432        dev_dbg(&pdev->dev, "Coldfire QSPI probe failed\n");
 433
 434        return status;
 435}
 436
 437static 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_unprepare(mcfqspi->clk);
 448
 449        return 0;
 450}
 451
 452#ifdef CONFIG_PM_SLEEP
 453static 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
 468static 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
 480static 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
 490static 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
 501static 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
 507static 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};
 514module_platform_driver(mcfqspi_driver);
 515
 516MODULE_AUTHOR("Steven King <sfking@fdwdc.com>");
 517MODULE_DESCRIPTION("Coldfire QSPI Controller Driver");
 518MODULE_LICENSE("GPL");
 519MODULE_ALIAS("platform:" DRIVER_NAME);
 520