linux/drivers/spi/spi-fsl-lpspi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// Freescale i.MX7ULP LPSPI driver
   4//
   5// Copyright 2016 Freescale Semiconductor, Inc.
   6
   7#include <linux/clk.h>
   8#include <linux/completion.h>
   9#include <linux/delay.h>
  10#include <linux/err.h>
  11#include <linux/interrupt.h>
  12#include <linux/io.h>
  13#include <linux/irq.h>
  14#include <linux/kernel.h>
  15#include <linux/module.h>
  16#include <linux/of.h>
  17#include <linux/of_device.h>
  18#include <linux/platform_device.h>
  19#include <linux/slab.h>
  20#include <linux/spi/spi.h>
  21#include <linux/spi/spi_bitbang.h>
  22#include <linux/types.h>
  23
  24#define DRIVER_NAME "fsl_lpspi"
  25
  26/* i.MX7ULP LPSPI registers */
  27#define IMX7ULP_VERID   0x0
  28#define IMX7ULP_PARAM   0x4
  29#define IMX7ULP_CR      0x10
  30#define IMX7ULP_SR      0x14
  31#define IMX7ULP_IER     0x18
  32#define IMX7ULP_DER     0x1c
  33#define IMX7ULP_CFGR0   0x20
  34#define IMX7ULP_CFGR1   0x24
  35#define IMX7ULP_DMR0    0x30
  36#define IMX7ULP_DMR1    0x34
  37#define IMX7ULP_CCR     0x40
  38#define IMX7ULP_FCR     0x58
  39#define IMX7ULP_FSR     0x5c
  40#define IMX7ULP_TCR     0x60
  41#define IMX7ULP_TDR     0x64
  42#define IMX7ULP_RSR     0x70
  43#define IMX7ULP_RDR     0x74
  44
  45/* General control register field define */
  46#define CR_RRF          BIT(9)
  47#define CR_RTF          BIT(8)
  48#define CR_RST          BIT(1)
  49#define CR_MEN          BIT(0)
  50#define SR_TCF          BIT(10)
  51#define SR_RDF          BIT(1)
  52#define SR_TDF          BIT(0)
  53#define IER_TCIE        BIT(10)
  54#define IER_RDIE        BIT(1)
  55#define IER_TDIE        BIT(0)
  56#define CFGR1_PCSCFG    BIT(27)
  57#define CFGR1_PCSPOL    BIT(8)
  58#define CFGR1_NOSTALL   BIT(3)
  59#define CFGR1_MASTER    BIT(0)
  60#define RSR_RXEMPTY     BIT(1)
  61#define TCR_CPOL        BIT(31)
  62#define TCR_CPHA        BIT(30)
  63#define TCR_CONT        BIT(21)
  64#define TCR_CONTC       BIT(20)
  65#define TCR_RXMSK       BIT(19)
  66#define TCR_TXMSK       BIT(18)
  67
  68static int clkdivs[] = {1, 2, 4, 8, 16, 32, 64, 128};
  69
  70struct lpspi_config {
  71        u8 bpw;
  72        u8 chip_select;
  73        u8 prescale;
  74        u16 mode;
  75        u32 speed_hz;
  76};
  77
  78struct fsl_lpspi_data {
  79        struct device *dev;
  80        void __iomem *base;
  81        struct clk *clk;
  82
  83        void *rx_buf;
  84        const void *tx_buf;
  85        void (*tx)(struct fsl_lpspi_data *);
  86        void (*rx)(struct fsl_lpspi_data *);
  87
  88        u32 remain;
  89        u8 txfifosize;
  90        u8 rxfifosize;
  91
  92        struct lpspi_config config;
  93        struct completion xfer_done;
  94};
  95
  96static const struct of_device_id fsl_lpspi_dt_ids[] = {
  97        { .compatible = "fsl,imx7ulp-spi", },
  98        { /* sentinel */ }
  99};
 100MODULE_DEVICE_TABLE(of, fsl_lpspi_dt_ids);
 101
 102#define LPSPI_BUF_RX(type)                                              \
 103static void fsl_lpspi_buf_rx_##type(struct fsl_lpspi_data *fsl_lpspi)   \
 104{                                                                       \
 105        unsigned int val = readl(fsl_lpspi->base + IMX7ULP_RDR);        \
 106                                                                        \
 107        if (fsl_lpspi->rx_buf) {                                        \
 108                *(type *)fsl_lpspi->rx_buf = val;                       \
 109                fsl_lpspi->rx_buf += sizeof(type);                      \
 110        }                                                               \
 111}
 112
 113#define LPSPI_BUF_TX(type)                                              \
 114static void fsl_lpspi_buf_tx_##type(struct fsl_lpspi_data *fsl_lpspi)   \
 115{                                                                       \
 116        type val = 0;                                                   \
 117                                                                        \
 118        if (fsl_lpspi->tx_buf) {                                        \
 119                val = *(type *)fsl_lpspi->tx_buf;                       \
 120                fsl_lpspi->tx_buf += sizeof(type);                      \
 121        }                                                               \
 122                                                                        \
 123        fsl_lpspi->remain -= sizeof(type);                              \
 124        writel(val, fsl_lpspi->base + IMX7ULP_TDR);                     \
 125}
 126
 127LPSPI_BUF_RX(u8)
 128LPSPI_BUF_TX(u8)
 129LPSPI_BUF_RX(u16)
 130LPSPI_BUF_TX(u16)
 131LPSPI_BUF_RX(u32)
 132LPSPI_BUF_TX(u32)
 133
 134static void fsl_lpspi_intctrl(struct fsl_lpspi_data *fsl_lpspi,
 135                              unsigned int enable)
 136{
 137        writel(enable, fsl_lpspi->base + IMX7ULP_IER);
 138}
 139
 140static int lpspi_prepare_xfer_hardware(struct spi_master *master)
 141{
 142        struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
 143
 144        return clk_prepare_enable(fsl_lpspi->clk);
 145}
 146
 147static int lpspi_unprepare_xfer_hardware(struct spi_master *master)
 148{
 149        struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
 150
 151        clk_disable_unprepare(fsl_lpspi->clk);
 152
 153        return 0;
 154}
 155
 156static int fsl_lpspi_txfifo_empty(struct fsl_lpspi_data *fsl_lpspi)
 157{
 158        u32 txcnt;
 159        unsigned long orig_jiffies = jiffies;
 160
 161        do {
 162                txcnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
 163
 164                if (time_after(jiffies, orig_jiffies + msecs_to_jiffies(500))) {
 165                        dev_dbg(fsl_lpspi->dev, "txfifo empty timeout\n");
 166                        return -ETIMEDOUT;
 167                }
 168                cond_resched();
 169
 170        } while (txcnt);
 171
 172        return 0;
 173}
 174
 175static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
 176{
 177        u8 txfifo_cnt;
 178
 179        txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
 180
 181        while (txfifo_cnt < fsl_lpspi->txfifosize) {
 182                if (!fsl_lpspi->remain)
 183                        break;
 184                fsl_lpspi->tx(fsl_lpspi);
 185                txfifo_cnt++;
 186        }
 187
 188        if (!fsl_lpspi->remain && (txfifo_cnt < fsl_lpspi->txfifosize))
 189                writel(0, fsl_lpspi->base + IMX7ULP_TDR);
 190        else
 191                fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE);
 192}
 193
 194static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
 195{
 196        while (!(readl(fsl_lpspi->base + IMX7ULP_RSR) & RSR_RXEMPTY))
 197                fsl_lpspi->rx(fsl_lpspi);
 198}
 199
 200static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
 201                              bool is_first_xfer)
 202{
 203        u32 temp = 0;
 204
 205        temp |= fsl_lpspi->config.bpw - 1;
 206        temp |= fsl_lpspi->config.prescale << 27;
 207        temp |= (fsl_lpspi->config.mode & 0x3) << 30;
 208        temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
 209
 210        /*
 211         * Set TCR_CONT will keep SS asserted after current transfer.
 212         * For the first transfer, clear TCR_CONTC to assert SS.
 213         * For subsequent transfer, set TCR_CONTC to keep SS asserted.
 214         */
 215        temp |= TCR_CONT;
 216        if (is_first_xfer)
 217                temp &= ~TCR_CONTC;
 218        else
 219                temp |= TCR_CONTC;
 220
 221        writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
 222
 223        dev_dbg(fsl_lpspi->dev, "TCR=0x%x\n", temp);
 224}
 225
 226static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
 227{
 228        u32 temp;
 229
 230        temp = fsl_lpspi->txfifosize >> 1 | (fsl_lpspi->rxfifosize >> 1) << 16;
 231
 232        writel(temp, fsl_lpspi->base + IMX7ULP_FCR);
 233
 234        dev_dbg(fsl_lpspi->dev, "FCR=0x%x\n", temp);
 235}
 236
 237static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
 238{
 239        struct lpspi_config config = fsl_lpspi->config;
 240        unsigned int perclk_rate, scldiv;
 241        u8 prescale;
 242
 243        perclk_rate = clk_get_rate(fsl_lpspi->clk);
 244        for (prescale = 0; prescale < 8; prescale++) {
 245                scldiv = perclk_rate /
 246                         (clkdivs[prescale] * config.speed_hz) - 2;
 247                if (scldiv < 256) {
 248                        fsl_lpspi->config.prescale = prescale;
 249                        break;
 250                }
 251        }
 252
 253        if (prescale == 8 && scldiv >= 256)
 254                return -EINVAL;
 255
 256        writel(scldiv, fsl_lpspi->base + IMX7ULP_CCR);
 257
 258        dev_dbg(fsl_lpspi->dev, "perclk=%d, speed=%d, prescale =%d, scldiv=%d\n",
 259                perclk_rate, config.speed_hz, prescale, scldiv);
 260
 261        return 0;
 262}
 263
 264static int fsl_lpspi_config(struct fsl_lpspi_data *fsl_lpspi)
 265{
 266        u32 temp;
 267        int ret;
 268
 269        temp = CR_RST;
 270        writel(temp, fsl_lpspi->base + IMX7ULP_CR);
 271        writel(0, fsl_lpspi->base + IMX7ULP_CR);
 272
 273        ret = fsl_lpspi_set_bitrate(fsl_lpspi);
 274        if (ret)
 275                return ret;
 276
 277        fsl_lpspi_set_watermark(fsl_lpspi);
 278
 279        temp = CFGR1_PCSCFG | CFGR1_MASTER | CFGR1_NOSTALL;
 280        if (fsl_lpspi->config.mode & SPI_CS_HIGH)
 281                temp |= CFGR1_PCSPOL;
 282        writel(temp, fsl_lpspi->base + IMX7ULP_CFGR1);
 283
 284        temp = readl(fsl_lpspi->base + IMX7ULP_CR);
 285        temp |= CR_RRF | CR_RTF | CR_MEN;
 286        writel(temp, fsl_lpspi->base + IMX7ULP_CR);
 287
 288        return 0;
 289}
 290
 291static void fsl_lpspi_setup_transfer(struct spi_device *spi,
 292                                     struct spi_transfer *t)
 293{
 294        struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(spi->master);
 295
 296        fsl_lpspi->config.mode = spi->mode;
 297        fsl_lpspi->config.bpw = t ? t->bits_per_word : spi->bits_per_word;
 298        fsl_lpspi->config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
 299        fsl_lpspi->config.chip_select = spi->chip_select;
 300
 301        if (!fsl_lpspi->config.speed_hz)
 302                fsl_lpspi->config.speed_hz = spi->max_speed_hz;
 303        if (!fsl_lpspi->config.bpw)
 304                fsl_lpspi->config.bpw = spi->bits_per_word;
 305
 306        /* Initialize the functions for transfer */
 307        if (fsl_lpspi->config.bpw <= 8) {
 308                fsl_lpspi->rx = fsl_lpspi_buf_rx_u8;
 309                fsl_lpspi->tx = fsl_lpspi_buf_tx_u8;
 310        } else if (fsl_lpspi->config.bpw <= 16) {
 311                fsl_lpspi->rx = fsl_lpspi_buf_rx_u16;
 312                fsl_lpspi->tx = fsl_lpspi_buf_tx_u16;
 313        } else {
 314                fsl_lpspi->rx = fsl_lpspi_buf_rx_u32;
 315                fsl_lpspi->tx = fsl_lpspi_buf_tx_u32;
 316        }
 317
 318        fsl_lpspi_config(fsl_lpspi);
 319}
 320
 321static int fsl_lpspi_transfer_one(struct spi_master *master,
 322                                  struct spi_device *spi,
 323                                  struct spi_transfer *t)
 324{
 325        struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
 326        int ret;
 327
 328        fsl_lpspi->tx_buf = t->tx_buf;
 329        fsl_lpspi->rx_buf = t->rx_buf;
 330        fsl_lpspi->remain = t->len;
 331
 332        reinit_completion(&fsl_lpspi->xfer_done);
 333        fsl_lpspi_write_tx_fifo(fsl_lpspi);
 334
 335        ret = wait_for_completion_timeout(&fsl_lpspi->xfer_done, HZ);
 336        if (!ret) {
 337                dev_dbg(fsl_lpspi->dev, "wait for completion timeout\n");
 338                return -ETIMEDOUT;
 339        }
 340
 341        ret = fsl_lpspi_txfifo_empty(fsl_lpspi);
 342        if (ret)
 343                return ret;
 344
 345        fsl_lpspi_read_rx_fifo(fsl_lpspi);
 346
 347        return 0;
 348}
 349
 350static int fsl_lpspi_transfer_one_msg(struct spi_master *master,
 351                                      struct spi_message *msg)
 352{
 353        struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
 354        struct spi_device *spi = msg->spi;
 355        struct spi_transfer *xfer;
 356        bool is_first_xfer = true;
 357        u32 temp;
 358        int ret = 0;
 359
 360        msg->status = 0;
 361        msg->actual_length = 0;
 362
 363        list_for_each_entry(xfer, &msg->transfers, transfer_list) {
 364                fsl_lpspi_setup_transfer(spi, xfer);
 365                fsl_lpspi_set_cmd(fsl_lpspi, is_first_xfer);
 366
 367                is_first_xfer = false;
 368
 369                ret = fsl_lpspi_transfer_one(master, spi, xfer);
 370                if (ret < 0)
 371                        goto complete;
 372
 373                msg->actual_length += xfer->len;
 374        }
 375
 376complete:
 377        /* de-assert SS, then finalize current message */
 378        temp = readl(fsl_lpspi->base + IMX7ULP_TCR);
 379        temp &= ~TCR_CONTC;
 380        writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
 381
 382        msg->status = ret;
 383        spi_finalize_current_message(master);
 384
 385        return ret;
 386}
 387
 388static irqreturn_t fsl_lpspi_isr(int irq, void *dev_id)
 389{
 390        struct fsl_lpspi_data *fsl_lpspi = dev_id;
 391        u32 temp;
 392
 393        fsl_lpspi_intctrl(fsl_lpspi, 0);
 394        temp = readl(fsl_lpspi->base + IMX7ULP_SR);
 395
 396        fsl_lpspi_read_rx_fifo(fsl_lpspi);
 397
 398        if (temp & SR_TDF) {
 399                fsl_lpspi_write_tx_fifo(fsl_lpspi);
 400
 401                if (!fsl_lpspi->remain)
 402                        complete(&fsl_lpspi->xfer_done);
 403
 404                return IRQ_HANDLED;
 405        }
 406
 407        return IRQ_NONE;
 408}
 409
 410static int fsl_lpspi_probe(struct platform_device *pdev)
 411{
 412        struct fsl_lpspi_data *fsl_lpspi;
 413        struct spi_master *master;
 414        struct resource *res;
 415        int ret, irq;
 416        u32 temp;
 417
 418        master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_lpspi_data));
 419        if (!master)
 420                return -ENOMEM;
 421
 422        platform_set_drvdata(pdev, master);
 423
 424        master->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32);
 425        master->bus_num = pdev->id;
 426
 427        fsl_lpspi = spi_master_get_devdata(master);
 428        fsl_lpspi->dev = &pdev->dev;
 429
 430        master->transfer_one_message = fsl_lpspi_transfer_one_msg;
 431        master->prepare_transfer_hardware = lpspi_prepare_xfer_hardware;
 432        master->unprepare_transfer_hardware = lpspi_unprepare_xfer_hardware;
 433        master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
 434        master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
 435        master->dev.of_node = pdev->dev.of_node;
 436        master->bus_num = pdev->id;
 437
 438        init_completion(&fsl_lpspi->xfer_done);
 439
 440        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 441        fsl_lpspi->base = devm_ioremap_resource(&pdev->dev, res);
 442        if (IS_ERR(fsl_lpspi->base)) {
 443                ret = PTR_ERR(fsl_lpspi->base);
 444                goto out_master_put;
 445        }
 446
 447        irq = platform_get_irq(pdev, 0);
 448        if (irq < 0) {
 449                ret = irq;
 450                goto out_master_put;
 451        }
 452
 453        ret = devm_request_irq(&pdev->dev, irq, fsl_lpspi_isr, 0,
 454                               dev_name(&pdev->dev), fsl_lpspi);
 455        if (ret) {
 456                dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
 457                goto out_master_put;
 458        }
 459
 460        fsl_lpspi->clk = devm_clk_get(&pdev->dev, "ipg");
 461        if (IS_ERR(fsl_lpspi->clk)) {
 462                ret = PTR_ERR(fsl_lpspi->clk);
 463                goto out_master_put;
 464        }
 465
 466        ret = clk_prepare_enable(fsl_lpspi->clk);
 467        if (ret) {
 468                dev_err(&pdev->dev, "can't enable lpspi clock, ret=%d\n", ret);
 469                goto out_master_put;
 470        }
 471
 472        temp = readl(fsl_lpspi->base + IMX7ULP_PARAM);
 473        fsl_lpspi->txfifosize = 1 << (temp & 0x0f);
 474        fsl_lpspi->rxfifosize = 1 << ((temp >> 8) & 0x0f);
 475
 476        clk_disable_unprepare(fsl_lpspi->clk);
 477
 478        ret = devm_spi_register_master(&pdev->dev, master);
 479        if (ret < 0) {
 480                dev_err(&pdev->dev, "spi_register_master error.\n");
 481                goto out_master_put;
 482        }
 483
 484        return 0;
 485
 486out_master_put:
 487        spi_master_put(master);
 488
 489        return ret;
 490}
 491
 492static int fsl_lpspi_remove(struct platform_device *pdev)
 493{
 494        struct spi_master *master = platform_get_drvdata(pdev);
 495        struct fsl_lpspi_data *fsl_lpspi = spi_master_get_devdata(master);
 496
 497        clk_disable_unprepare(fsl_lpspi->clk);
 498
 499        return 0;
 500}
 501
 502static struct platform_driver fsl_lpspi_driver = {
 503        .driver = {
 504                .name = DRIVER_NAME,
 505                .of_match_table = fsl_lpspi_dt_ids,
 506        },
 507        .probe = fsl_lpspi_probe,
 508        .remove = fsl_lpspi_remove,
 509};
 510module_platform_driver(fsl_lpspi_driver);
 511
 512MODULE_DESCRIPTION("LPSPI Master Controller driver");
 513MODULE_AUTHOR("Gao Pan <pandy.gao@nxp.com>");
 514MODULE_LICENSE("GPL");
 515