linux/drivers/spi/spi-dw-mid.c
<<
>>
Prefs
   1/*
   2 * Special handling for DW core on Intel MID platform
   3 *
   4 * Copyright (c) 2009, 2014 Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 */
  15
  16#include <linux/dma-mapping.h>
  17#include <linux/dmaengine.h>
  18#include <linux/interrupt.h>
  19#include <linux/slab.h>
  20#include <linux/spi/spi.h>
  21#include <linux/types.h>
  22
  23#include "spi-dw.h"
  24
  25#ifdef CONFIG_SPI_DW_MID_DMA
  26#include <linux/pci.h>
  27#include <linux/platform_data/dma-dw.h>
  28
  29#define RX_BUSY         0
  30#define TX_BUSY         1
  31
  32static struct dw_dma_slave mid_dma_tx = { .dst_id = 1 };
  33static struct dw_dma_slave mid_dma_rx = { .src_id = 0 };
  34
  35static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
  36{
  37        struct dw_dma_slave *s = param;
  38
  39        if (s->dma_dev != chan->device->dev)
  40                return false;
  41
  42        chan->private = s;
  43        return true;
  44}
  45
  46static int mid_spi_dma_init(struct dw_spi *dws)
  47{
  48        struct pci_dev *dma_dev;
  49        struct dw_dma_slave *tx = dws->dma_tx;
  50        struct dw_dma_slave *rx = dws->dma_rx;
  51        dma_cap_mask_t mask;
  52
  53        /*
  54         * Get pci device for DMA controller, currently it could only
  55         * be the DMA controller of Medfield
  56         */
  57        dma_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL);
  58        if (!dma_dev)
  59                return -ENODEV;
  60
  61        dma_cap_zero(mask);
  62        dma_cap_set(DMA_SLAVE, mask);
  63
  64        /* 1. Init rx channel */
  65        rx->dma_dev = &dma_dev->dev;
  66        dws->rxchan = dma_request_channel(mask, mid_spi_dma_chan_filter, rx);
  67        if (!dws->rxchan)
  68                goto err_exit;
  69        dws->master->dma_rx = dws->rxchan;
  70
  71        /* 2. Init tx channel */
  72        tx->dma_dev = &dma_dev->dev;
  73        dws->txchan = dma_request_channel(mask, mid_spi_dma_chan_filter, tx);
  74        if (!dws->txchan)
  75                goto free_rxchan;
  76        dws->master->dma_tx = dws->txchan;
  77
  78        dws->dma_inited = 1;
  79        return 0;
  80
  81free_rxchan:
  82        dma_release_channel(dws->rxchan);
  83err_exit:
  84        return -EBUSY;
  85}
  86
  87static void mid_spi_dma_exit(struct dw_spi *dws)
  88{
  89        if (!dws->dma_inited)
  90                return;
  91
  92        dmaengine_terminate_sync(dws->txchan);
  93        dma_release_channel(dws->txchan);
  94
  95        dmaengine_terminate_sync(dws->rxchan);
  96        dma_release_channel(dws->rxchan);
  97}
  98
  99static irqreturn_t dma_transfer(struct dw_spi *dws)
 100{
 101        u16 irq_status = dw_readl(dws, DW_SPI_ISR);
 102
 103        if (!irq_status)
 104                return IRQ_NONE;
 105
 106        dw_readl(dws, DW_SPI_ICR);
 107        spi_reset_chip(dws);
 108
 109        dev_err(&dws->master->dev, "%s: FIFO overrun/underrun\n", __func__);
 110        dws->master->cur_msg->status = -EIO;
 111        spi_finalize_current_transfer(dws->master);
 112        return IRQ_HANDLED;
 113}
 114
 115static bool mid_spi_can_dma(struct spi_master *master, struct spi_device *spi,
 116                struct spi_transfer *xfer)
 117{
 118        struct dw_spi *dws = spi_master_get_devdata(master);
 119
 120        if (!dws->dma_inited)
 121                return false;
 122
 123        return xfer->len > dws->fifo_len;
 124}
 125
 126static enum dma_slave_buswidth convert_dma_width(u32 dma_width) {
 127        if (dma_width == 1)
 128                return DMA_SLAVE_BUSWIDTH_1_BYTE;
 129        else if (dma_width == 2)
 130                return DMA_SLAVE_BUSWIDTH_2_BYTES;
 131
 132        return DMA_SLAVE_BUSWIDTH_UNDEFINED;
 133}
 134
 135/*
 136 * dws->dma_chan_busy is set before the dma transfer starts, callback for tx
 137 * channel will clear a corresponding bit.
 138 */
 139static void dw_spi_dma_tx_done(void *arg)
 140{
 141        struct dw_spi *dws = arg;
 142
 143        clear_bit(TX_BUSY, &dws->dma_chan_busy);
 144        if (test_bit(RX_BUSY, &dws->dma_chan_busy))
 145                return;
 146        spi_finalize_current_transfer(dws->master);
 147}
 148
 149static struct dma_async_tx_descriptor *dw_spi_dma_prepare_tx(struct dw_spi *dws,
 150                struct spi_transfer *xfer)
 151{
 152        struct dma_slave_config txconf;
 153        struct dma_async_tx_descriptor *txdesc;
 154
 155        if (!xfer->tx_buf)
 156                return NULL;
 157
 158        txconf.direction = DMA_MEM_TO_DEV;
 159        txconf.dst_addr = dws->dma_addr;
 160        txconf.dst_maxburst = 16;
 161        txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 162        txconf.dst_addr_width = convert_dma_width(dws->dma_width);
 163        txconf.device_fc = false;
 164
 165        dmaengine_slave_config(dws->txchan, &txconf);
 166
 167        txdesc = dmaengine_prep_slave_sg(dws->txchan,
 168                                xfer->tx_sg.sgl,
 169                                xfer->tx_sg.nents,
 170                                DMA_MEM_TO_DEV,
 171                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 172        if (!txdesc)
 173                return NULL;
 174
 175        txdesc->callback = dw_spi_dma_tx_done;
 176        txdesc->callback_param = dws;
 177
 178        return txdesc;
 179}
 180
 181/*
 182 * dws->dma_chan_busy is set before the dma transfer starts, callback for rx
 183 * channel will clear a corresponding bit.
 184 */
 185static void dw_spi_dma_rx_done(void *arg)
 186{
 187        struct dw_spi *dws = arg;
 188
 189        clear_bit(RX_BUSY, &dws->dma_chan_busy);
 190        if (test_bit(TX_BUSY, &dws->dma_chan_busy))
 191                return;
 192        spi_finalize_current_transfer(dws->master);
 193}
 194
 195static struct dma_async_tx_descriptor *dw_spi_dma_prepare_rx(struct dw_spi *dws,
 196                struct spi_transfer *xfer)
 197{
 198        struct dma_slave_config rxconf;
 199        struct dma_async_tx_descriptor *rxdesc;
 200
 201        if (!xfer->rx_buf)
 202                return NULL;
 203
 204        rxconf.direction = DMA_DEV_TO_MEM;
 205        rxconf.src_addr = dws->dma_addr;
 206        rxconf.src_maxburst = 16;
 207        rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
 208        rxconf.src_addr_width = convert_dma_width(dws->dma_width);
 209        rxconf.device_fc = false;
 210
 211        dmaengine_slave_config(dws->rxchan, &rxconf);
 212
 213        rxdesc = dmaengine_prep_slave_sg(dws->rxchan,
 214                                xfer->rx_sg.sgl,
 215                                xfer->rx_sg.nents,
 216                                DMA_DEV_TO_MEM,
 217                                DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
 218        if (!rxdesc)
 219                return NULL;
 220
 221        rxdesc->callback = dw_spi_dma_rx_done;
 222        rxdesc->callback_param = dws;
 223
 224        return rxdesc;
 225}
 226
 227static int mid_spi_dma_setup(struct dw_spi *dws, struct spi_transfer *xfer)
 228{
 229        u16 dma_ctrl = 0;
 230
 231        dw_writel(dws, DW_SPI_DMARDLR, 0xf);
 232        dw_writel(dws, DW_SPI_DMATDLR, 0x10);
 233
 234        if (xfer->tx_buf)
 235                dma_ctrl |= SPI_DMA_TDMAE;
 236        if (xfer->rx_buf)
 237                dma_ctrl |= SPI_DMA_RDMAE;
 238        dw_writel(dws, DW_SPI_DMACR, dma_ctrl);
 239
 240        /* Set the interrupt mask */
 241        spi_umask_intr(dws, SPI_INT_TXOI | SPI_INT_RXUI | SPI_INT_RXOI);
 242
 243        dws->transfer_handler = dma_transfer;
 244
 245        return 0;
 246}
 247
 248static int mid_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer)
 249{
 250        struct dma_async_tx_descriptor *txdesc, *rxdesc;
 251
 252        /* Prepare the TX dma transfer */
 253        txdesc = dw_spi_dma_prepare_tx(dws, xfer);
 254
 255        /* Prepare the RX dma transfer */
 256        rxdesc = dw_spi_dma_prepare_rx(dws, xfer);
 257
 258        /* rx must be started before tx due to spi instinct */
 259        if (rxdesc) {
 260                set_bit(RX_BUSY, &dws->dma_chan_busy);
 261                dmaengine_submit(rxdesc);
 262                dma_async_issue_pending(dws->rxchan);
 263        }
 264
 265        if (txdesc) {
 266                set_bit(TX_BUSY, &dws->dma_chan_busy);
 267                dmaengine_submit(txdesc);
 268                dma_async_issue_pending(dws->txchan);
 269        }
 270
 271        return 0;
 272}
 273
 274static void mid_spi_dma_stop(struct dw_spi *dws)
 275{
 276        if (test_bit(TX_BUSY, &dws->dma_chan_busy)) {
 277                dmaengine_terminate_sync(dws->txchan);
 278                clear_bit(TX_BUSY, &dws->dma_chan_busy);
 279        }
 280        if (test_bit(RX_BUSY, &dws->dma_chan_busy)) {
 281                dmaengine_terminate_sync(dws->rxchan);
 282                clear_bit(RX_BUSY, &dws->dma_chan_busy);
 283        }
 284}
 285
 286static const struct dw_spi_dma_ops mid_dma_ops = {
 287        .dma_init       = mid_spi_dma_init,
 288        .dma_exit       = mid_spi_dma_exit,
 289        .dma_setup      = mid_spi_dma_setup,
 290        .can_dma        = mid_spi_can_dma,
 291        .dma_transfer   = mid_spi_dma_transfer,
 292        .dma_stop       = mid_spi_dma_stop,
 293};
 294#endif
 295
 296/* Some specific info for SPI0 controller on Intel MID */
 297
 298/* HW info for MRST Clk Control Unit, 32b reg per controller */
 299#define MRST_SPI_CLK_BASE       100000000       /* 100m */
 300#define MRST_CLK_SPI_REG        0xff11d86c
 301#define CLK_SPI_BDIV_OFFSET     0
 302#define CLK_SPI_BDIV_MASK       0x00000007
 303#define CLK_SPI_CDIV_OFFSET     9
 304#define CLK_SPI_CDIV_MASK       0x00000e00
 305#define CLK_SPI_DISABLE_OFFSET  8
 306
 307int dw_spi_mid_init(struct dw_spi *dws)
 308{
 309        void __iomem *clk_reg;
 310        u32 clk_cdiv;
 311
 312        clk_reg = ioremap_nocache(MRST_CLK_SPI_REG, 16);
 313        if (!clk_reg)
 314                return -ENOMEM;
 315
 316        /* Get SPI controller operating freq info */
 317        clk_cdiv = readl(clk_reg + dws->bus_num * sizeof(u32));
 318        clk_cdiv &= CLK_SPI_CDIV_MASK;
 319        clk_cdiv >>= CLK_SPI_CDIV_OFFSET;
 320        dws->max_freq = MRST_SPI_CLK_BASE / (clk_cdiv + 1);
 321
 322        iounmap(clk_reg);
 323
 324#ifdef CONFIG_SPI_DW_MID_DMA
 325        dws->dma_tx = &mid_dma_tx;
 326        dws->dma_rx = &mid_dma_rx;
 327        dws->dma_ops = &mid_dma_ops;
 328#endif
 329        return 0;
 330}
 331