uboot/drivers/spi/designware_spi.c
<<
>>
Prefs
   1/*
   2 * Designware master SPI core controller driver
   3 *
   4 * Copyright (C) 2014 Stefan Roese <sr@denx.de>
   5 *
   6 * Very loosely based on the Linux driver:
   7 * drivers/spi/spi-dw.c, which is:
   8 * Copyright (c) 2009, Intel Corporation.
   9 *
  10 * SPDX-License-Identifier:     GPL-2.0
  11 */
  12
  13#include <common.h>
  14#include <dm.h>
  15#include <errno.h>
  16#include <malloc.h>
  17#include <spi.h>
  18#include <fdtdec.h>
  19#include <linux/compat.h>
  20#include <asm/io.h>
  21#include <asm/arch/clock_manager.h>
  22
  23DECLARE_GLOBAL_DATA_PTR;
  24
  25/* Register offsets */
  26#define DW_SPI_CTRL0                    0x00
  27#define DW_SPI_CTRL1                    0x04
  28#define DW_SPI_SSIENR                   0x08
  29#define DW_SPI_MWCR                     0x0c
  30#define DW_SPI_SER                      0x10
  31#define DW_SPI_BAUDR                    0x14
  32#define DW_SPI_TXFLTR                   0x18
  33#define DW_SPI_RXFLTR                   0x1c
  34#define DW_SPI_TXFLR                    0x20
  35#define DW_SPI_RXFLR                    0x24
  36#define DW_SPI_SR                       0x28
  37#define DW_SPI_IMR                      0x2c
  38#define DW_SPI_ISR                      0x30
  39#define DW_SPI_RISR                     0x34
  40#define DW_SPI_TXOICR                   0x38
  41#define DW_SPI_RXOICR                   0x3c
  42#define DW_SPI_RXUICR                   0x40
  43#define DW_SPI_MSTICR                   0x44
  44#define DW_SPI_ICR                      0x48
  45#define DW_SPI_DMACR                    0x4c
  46#define DW_SPI_DMATDLR                  0x50
  47#define DW_SPI_DMARDLR                  0x54
  48#define DW_SPI_IDR                      0x58
  49#define DW_SPI_VERSION                  0x5c
  50#define DW_SPI_DR                       0x60
  51
  52/* Bit fields in CTRLR0 */
  53#define SPI_DFS_OFFSET                  0
  54
  55#define SPI_FRF_OFFSET                  4
  56#define SPI_FRF_SPI                     0x0
  57#define SPI_FRF_SSP                     0x1
  58#define SPI_FRF_MICROWIRE               0x2
  59#define SPI_FRF_RESV                    0x3
  60
  61#define SPI_MODE_OFFSET                 6
  62#define SPI_SCPH_OFFSET                 6
  63#define SPI_SCOL_OFFSET                 7
  64
  65#define SPI_TMOD_OFFSET                 8
  66#define SPI_TMOD_MASK                   (0x3 << SPI_TMOD_OFFSET)
  67#define SPI_TMOD_TR                     0x0             /* xmit & recv */
  68#define SPI_TMOD_TO                     0x1             /* xmit only */
  69#define SPI_TMOD_RO                     0x2             /* recv only */
  70#define SPI_TMOD_EPROMREAD              0x3             /* eeprom read mode */
  71
  72#define SPI_SLVOE_OFFSET                10
  73#define SPI_SRL_OFFSET                  11
  74#define SPI_CFS_OFFSET                  12
  75
  76/* Bit fields in SR, 7 bits */
  77#define SR_MASK                         GENMASK(6, 0)   /* cover 7 bits */
  78#define SR_BUSY                         BIT(0)
  79#define SR_TF_NOT_FULL                  BIT(1)
  80#define SR_TF_EMPT                      BIT(2)
  81#define SR_RF_NOT_EMPT                  BIT(3)
  82#define SR_RF_FULL                      BIT(4)
  83#define SR_TX_ERR                       BIT(5)
  84#define SR_DCOL                         BIT(6)
  85
  86#define RX_TIMEOUT                      1000            /* timeout in ms */
  87
  88struct dw_spi_platdata {
  89        s32 frequency;          /* Default clock frequency, -1 for none */
  90        void __iomem *regs;
  91};
  92
  93struct dw_spi_priv {
  94        void __iomem *regs;
  95        unsigned int freq;              /* Default frequency */
  96        unsigned int mode;
  97
  98        int bits_per_word;
  99        u8 cs;                  /* chip select pin */
 100        u8 tmode;               /* TR/TO/RO/EEPROM */
 101        u8 type;                /* SPI/SSP/MicroWire */
 102        int len;
 103
 104        u32 fifo_len;           /* depth of the FIFO buffer */
 105        void *tx;
 106        void *tx_end;
 107        void *rx;
 108        void *rx_end;
 109};
 110
 111static inline u32 dw_readl(struct dw_spi_priv *priv, u32 offset)
 112{
 113        return __raw_readl(priv->regs + offset);
 114}
 115
 116static inline void dw_writel(struct dw_spi_priv *priv, u32 offset, u32 val)
 117{
 118        __raw_writel(val, priv->regs + offset);
 119}
 120
 121static inline u16 dw_readw(struct dw_spi_priv *priv, u32 offset)
 122{
 123        return __raw_readw(priv->regs + offset);
 124}
 125
 126static inline void dw_writew(struct dw_spi_priv *priv, u32 offset, u16 val)
 127{
 128        __raw_writew(val, priv->regs + offset);
 129}
 130
 131static int dw_spi_ofdata_to_platdata(struct udevice *bus)
 132{
 133        struct dw_spi_platdata *plat = bus->platdata;
 134        const void *blob = gd->fdt_blob;
 135        int node = dev_of_offset(bus);
 136
 137        plat->regs = (struct dw_spi *)devfdt_get_addr(bus);
 138
 139        /* Use 500KHz as a suitable default */
 140        plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
 141                                        500000);
 142        debug("%s: regs=%p max-frequency=%d\n", __func__, plat->regs,
 143              plat->frequency);
 144
 145        return 0;
 146}
 147
 148static inline void spi_enable_chip(struct dw_spi_priv *priv, int enable)
 149{
 150        dw_writel(priv, DW_SPI_SSIENR, (enable ? 1 : 0));
 151}
 152
 153/* Restart the controller, disable all interrupts, clean rx fifo */
 154static void spi_hw_init(struct dw_spi_priv *priv)
 155{
 156        spi_enable_chip(priv, 0);
 157        dw_writel(priv, DW_SPI_IMR, 0xff);
 158        spi_enable_chip(priv, 1);
 159
 160        /*
 161         * Try to detect the FIFO depth if not set by interface driver,
 162         * the depth could be from 2 to 256 from HW spec
 163         */
 164        if (!priv->fifo_len) {
 165                u32 fifo;
 166
 167                for (fifo = 1; fifo < 256; fifo++) {
 168                        dw_writew(priv, DW_SPI_TXFLTR, fifo);
 169                        if (fifo != dw_readw(priv, DW_SPI_TXFLTR))
 170                                break;
 171                }
 172
 173                priv->fifo_len = (fifo == 1) ? 0 : fifo;
 174                dw_writew(priv, DW_SPI_TXFLTR, 0);
 175        }
 176        debug("%s: fifo_len=%d\n", __func__, priv->fifo_len);
 177}
 178
 179static int dw_spi_probe(struct udevice *bus)
 180{
 181        struct dw_spi_platdata *plat = dev_get_platdata(bus);
 182        struct dw_spi_priv *priv = dev_get_priv(bus);
 183
 184        priv->regs = plat->regs;
 185        priv->freq = plat->frequency;
 186
 187        /* Currently only bits_per_word == 8 supported */
 188        priv->bits_per_word = 8;
 189
 190        priv->tmode = 0; /* Tx & Rx */
 191
 192        /* Basic HW init */
 193        spi_hw_init(priv);
 194
 195        return 0;
 196}
 197
 198/* Return the max entries we can fill into tx fifo */
 199static inline u32 tx_max(struct dw_spi_priv *priv)
 200{
 201        u32 tx_left, tx_room, rxtx_gap;
 202
 203        tx_left = (priv->tx_end - priv->tx) / (priv->bits_per_word >> 3);
 204        tx_room = priv->fifo_len - dw_readw(priv, DW_SPI_TXFLR);
 205
 206        /*
 207         * Another concern is about the tx/rx mismatch, we
 208         * thought about using (priv->fifo_len - rxflr - txflr) as
 209         * one maximum value for tx, but it doesn't cover the
 210         * data which is out of tx/rx fifo and inside the
 211         * shift registers. So a control from sw point of
 212         * view is taken.
 213         */
 214        rxtx_gap = ((priv->rx_end - priv->rx) - (priv->tx_end - priv->tx)) /
 215                (priv->bits_per_word >> 3);
 216
 217        return min3(tx_left, tx_room, (u32)(priv->fifo_len - rxtx_gap));
 218}
 219
 220/* Return the max entries we should read out of rx fifo */
 221static inline u32 rx_max(struct dw_spi_priv *priv)
 222{
 223        u32 rx_left = (priv->rx_end - priv->rx) / (priv->bits_per_word >> 3);
 224
 225        return min_t(u32, rx_left, dw_readw(priv, DW_SPI_RXFLR));
 226}
 227
 228static void dw_writer(struct dw_spi_priv *priv)
 229{
 230        u32 max = tx_max(priv);
 231        u16 txw = 0;
 232
 233        while (max--) {
 234                /* Set the tx word if the transfer's original "tx" is not null */
 235                if (priv->tx_end - priv->len) {
 236                        if (priv->bits_per_word == 8)
 237                                txw = *(u8 *)(priv->tx);
 238                        else
 239                                txw = *(u16 *)(priv->tx);
 240                }
 241                dw_writew(priv, DW_SPI_DR, txw);
 242                debug("%s: tx=0x%02x\n", __func__, txw);
 243                priv->tx += priv->bits_per_word >> 3;
 244        }
 245}
 246
 247static int dw_reader(struct dw_spi_priv *priv)
 248{
 249        unsigned start = get_timer(0);
 250        u32 max;
 251        u16 rxw;
 252
 253        /* Wait for rx data to be ready */
 254        while (rx_max(priv) == 0) {
 255                if (get_timer(start) > RX_TIMEOUT)
 256                        return -ETIMEDOUT;
 257        }
 258
 259        max = rx_max(priv);
 260
 261        while (max--) {
 262                rxw = dw_readw(priv, DW_SPI_DR);
 263                debug("%s: rx=0x%02x\n", __func__, rxw);
 264
 265                /*
 266                 * Care about rx only if the transfer's original "rx" is
 267                 * not null
 268                 */
 269                if (priv->rx_end - priv->len) {
 270                        if (priv->bits_per_word == 8)
 271                                *(u8 *)(priv->rx) = rxw;
 272                        else
 273                                *(u16 *)(priv->rx) = rxw;
 274                }
 275                priv->rx += priv->bits_per_word >> 3;
 276        }
 277
 278        return 0;
 279}
 280
 281static int poll_transfer(struct dw_spi_priv *priv)
 282{
 283        int ret;
 284
 285        do {
 286                dw_writer(priv);
 287                ret = dw_reader(priv);
 288                if (ret < 0)
 289                        return ret;
 290        } while (priv->rx_end > priv->rx);
 291
 292        return 0;
 293}
 294
 295static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen,
 296                       const void *dout, void *din, unsigned long flags)
 297{
 298        struct udevice *bus = dev->parent;
 299        struct dw_spi_priv *priv = dev_get_priv(bus);
 300        const u8 *tx = dout;
 301        u8 *rx = din;
 302        int ret = 0;
 303        u32 cr0 = 0;
 304        u32 cs;
 305
 306        /* spi core configured to do 8 bit transfers */
 307        if (bitlen % 8) {
 308                debug("Non byte aligned SPI transfer.\n");
 309                return -1;
 310        }
 311
 312        cr0 = (priv->bits_per_word - 1) | (priv->type << SPI_FRF_OFFSET) |
 313                (priv->mode << SPI_MODE_OFFSET) |
 314                (priv->tmode << SPI_TMOD_OFFSET);
 315
 316        if (rx && tx)
 317                priv->tmode = SPI_TMOD_TR;
 318        else if (rx)
 319                priv->tmode = SPI_TMOD_RO;
 320        else
 321                priv->tmode = SPI_TMOD_TO;
 322
 323        cr0 &= ~SPI_TMOD_MASK;
 324        cr0 |= (priv->tmode << SPI_TMOD_OFFSET);
 325
 326        priv->len = bitlen >> 3;
 327        debug("%s: rx=%p tx=%p len=%d [bytes]\n", __func__, rx, tx, priv->len);
 328
 329        priv->tx = (void *)tx;
 330        priv->tx_end = priv->tx + priv->len;
 331        priv->rx = rx;
 332        priv->rx_end = priv->rx + priv->len;
 333
 334        /* Disable controller before writing control registers */
 335        spi_enable_chip(priv, 0);
 336
 337        debug("%s: cr0=%08x\n", __func__, cr0);
 338        /* Reprogram cr0 only if changed */
 339        if (dw_readw(priv, DW_SPI_CTRL0) != cr0)
 340                dw_writew(priv, DW_SPI_CTRL0, cr0);
 341
 342        /*
 343         * Configure the desired SS (slave select 0...3) in the controller
 344         * The DW SPI controller will activate and deactivate this CS
 345         * automatically. So no cs_activate() etc is needed in this driver.
 346         */
 347        cs = spi_chip_select(dev);
 348        dw_writel(priv, DW_SPI_SER, 1 << cs);
 349
 350        /* Enable controller after writing control registers */
 351        spi_enable_chip(priv, 1);
 352
 353        /* Start transfer in a polling loop */
 354        ret = poll_transfer(priv);
 355
 356        return ret;
 357}
 358
 359static int dw_spi_set_speed(struct udevice *bus, uint speed)
 360{
 361        struct dw_spi_platdata *plat = bus->platdata;
 362        struct dw_spi_priv *priv = dev_get_priv(bus);
 363        u16 clk_div;
 364
 365        if (speed > plat->frequency)
 366                speed = plat->frequency;
 367
 368        /* Disable controller before writing control registers */
 369        spi_enable_chip(priv, 0);
 370
 371        /* clk_div doesn't support odd number */
 372        clk_div = cm_get_spi_controller_clk_hz() / speed;
 373        clk_div = (clk_div + 1) & 0xfffe;
 374        dw_writel(priv, DW_SPI_BAUDR, clk_div);
 375
 376        /* Enable controller after writing control registers */
 377        spi_enable_chip(priv, 1);
 378
 379        priv->freq = speed;
 380        debug("%s: regs=%p speed=%d clk_div=%d\n", __func__, priv->regs,
 381              priv->freq, clk_div);
 382
 383        return 0;
 384}
 385
 386static int dw_spi_set_mode(struct udevice *bus, uint mode)
 387{
 388        struct dw_spi_priv *priv = dev_get_priv(bus);
 389
 390        /*
 391         * Can't set mode yet. Since this depends on if rx, tx, or
 392         * rx & tx is requested. So we have to defer this to the
 393         * real transfer function.
 394         */
 395        priv->mode = mode;
 396        debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
 397
 398        return 0;
 399}
 400
 401static const struct dm_spi_ops dw_spi_ops = {
 402        .xfer           = dw_spi_xfer,
 403        .set_speed      = dw_spi_set_speed,
 404        .set_mode       = dw_spi_set_mode,
 405        /*
 406         * cs_info is not needed, since we require all chip selects to be
 407         * in the device tree explicitly
 408         */
 409};
 410
 411static const struct udevice_id dw_spi_ids[] = {
 412        { .compatible = "snps,dw-apb-ssi" },
 413        { }
 414};
 415
 416U_BOOT_DRIVER(dw_spi) = {
 417        .name = "dw_spi",
 418        .id = UCLASS_SPI,
 419        .of_match = dw_spi_ids,
 420        .ops = &dw_spi_ops,
 421        .ofdata_to_platdata = dw_spi_ofdata_to_platdata,
 422        .platdata_auto_alloc_size = sizeof(struct dw_spi_platdata),
 423        .priv_auto_alloc_size = sizeof(struct dw_spi_priv),
 424        .probe = dw_spi_probe,
 425};
 426