uboot/drivers/spi/tegra20_slink.c
<<
>>
Prefs
   1/*
   2 * NVIDIA Tegra SPI-SLINK controller
   3 *
   4 * Copyright (c) 2010-2013 NVIDIA Corporation
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0
   7 */
   8
   9#include <common.h>
  10#include <dm.h>
  11#include <asm/io.h>
  12#include <asm/arch/clock.h>
  13#include <asm/arch-tegra/clk_rst.h>
  14#include <spi.h>
  15#include <fdtdec.h>
  16#include "tegra_spi.h"
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20/* COMMAND */
  21#define SLINK_CMD_ENB                   BIT(31)
  22#define SLINK_CMD_GO                    BIT(30)
  23#define SLINK_CMD_M_S                   BIT(28)
  24#define SLINK_CMD_IDLE_SCLK_DRIVE_LOW   (0 << 24)
  25#define SLINK_CMD_IDLE_SCLK_DRIVE_HIGH  BIT(24)
  26#define SLINK_CMD_IDLE_SCLK_PULL_LOW    (2 << 24)
  27#define SLINK_CMD_IDLE_SCLK_PULL_HIGH   (3 << 24)
  28#define SLINK_CMD_IDLE_SCLK_MASK        (3 << 24)
  29#define SLINK_CMD_CK_SDA                BIT(21)
  30#define SLINK_CMD_CS_POL                BIT(13)
  31#define SLINK_CMD_CS_VAL                BIT(12)
  32#define SLINK_CMD_CS_SOFT               BIT(11)
  33#define SLINK_CMD_BIT_LENGTH            BIT(4)
  34#define SLINK_CMD_BIT_LENGTH_MASK       GENMASK(4, 0)
  35/* COMMAND2 */
  36#define SLINK_CMD2_TXEN                 BIT(30)
  37#define SLINK_CMD2_RXEN                 BIT(31)
  38#define SLINK_CMD2_SS_EN                BIT(18)
  39#define SLINK_CMD2_SS_EN_SHIFT          18
  40#define SLINK_CMD2_SS_EN_MASK           GENMASK(19, 18)
  41#define SLINK_CMD2_CS_ACTIVE_BETWEEN    BIT(17)
  42/* STATUS */
  43#define SLINK_STAT_BSY                  BIT(31)
  44#define SLINK_STAT_RDY                  BIT(30)
  45#define SLINK_STAT_ERR                  BIT(29)
  46#define SLINK_STAT_RXF_FLUSH            BIT(27)
  47#define SLINK_STAT_TXF_FLUSH            BIT(26)
  48#define SLINK_STAT_RXF_OVF              BIT(25)
  49#define SLINK_STAT_TXF_UNR              BIT(24)
  50#define SLINK_STAT_RXF_EMPTY            BIT(23)
  51#define SLINK_STAT_RXF_FULL             BIT(22)
  52#define SLINK_STAT_TXF_EMPTY            BIT(21)
  53#define SLINK_STAT_TXF_FULL             BIT(20)
  54#define SLINK_STAT_TXF_OVF              BIT(19)
  55#define SLINK_STAT_RXF_UNR              BIT(18)
  56#define SLINK_STAT_CUR_BLKCNT           BIT(15)
  57/* STATUS2 */
  58#define SLINK_STAT2_RXF_FULL_CNT        BIT(16)
  59#define SLINK_STAT2_TXF_FULL_CNT        BIT(0)
  60
  61#define SPI_TIMEOUT             1000
  62#define TEGRA_SPI_MAX_FREQ      52000000
  63
  64struct spi_regs {
  65        u32 command;    /* SLINK_COMMAND_0 register  */
  66        u32 command2;   /* SLINK_COMMAND2_0 reg */
  67        u32 status;     /* SLINK_STATUS_0 register */
  68        u32 reserved;   /* Reserved offset 0C */
  69        u32 mas_data;   /* SLINK_MAS_DATA_0 reg */
  70        u32 slav_data;  /* SLINK_SLAVE_DATA_0 reg */
  71        u32 dma_ctl;    /* SLINK_DMA_CTL_0 register */
  72        u32 status2;    /* SLINK_STATUS2_0 reg */
  73        u32 rsvd[56];   /* 0x20 to 0xFF reserved */
  74        u32 tx_fifo;    /* SLINK_TX_FIFO_0 reg off 100h */
  75        u32 rsvd2[31];  /* 0x104 to 0x17F reserved */
  76        u32 rx_fifo;    /* SLINK_RX_FIFO_0 reg off 180h */
  77};
  78
  79struct tegra30_spi_priv {
  80        struct spi_regs *regs;
  81        unsigned int freq;
  82        unsigned int mode;
  83        int periph_id;
  84        int valid;
  85        int last_transaction_us;
  86};
  87
  88struct tegra_spi_slave {
  89        struct spi_slave slave;
  90        struct tegra30_spi_priv *ctrl;
  91};
  92
  93static int tegra30_spi_ofdata_to_platdata(struct udevice *bus)
  94{
  95        struct tegra_spi_platdata *plat = bus->platdata;
  96        const void *blob = gd->fdt_blob;
  97        int node = dev_of_offset(bus);
  98
  99        plat->base = devfdt_get_addr(bus);
 100        plat->periph_id = clock_decode_periph_id(bus);
 101
 102        if (plat->periph_id == PERIPH_ID_NONE) {
 103                debug("%s: could not decode periph id %d\n", __func__,
 104                      plat->periph_id);
 105                return -FDT_ERR_NOTFOUND;
 106        }
 107
 108        /* Use 500KHz as a suitable default */
 109        plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency",
 110                                        500000);
 111        plat->deactivate_delay_us = fdtdec_get_int(blob, node,
 112                                        "spi-deactivate-delay", 0);
 113        debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n",
 114              __func__, plat->base, plat->periph_id, plat->frequency,
 115              plat->deactivate_delay_us);
 116
 117        return 0;
 118}
 119
 120static int tegra30_spi_probe(struct udevice *bus)
 121{
 122        struct tegra_spi_platdata *plat = dev_get_platdata(bus);
 123        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 124
 125        priv->regs = (struct spi_regs *)plat->base;
 126
 127        priv->last_transaction_us = timer_get_us();
 128        priv->freq = plat->frequency;
 129        priv->periph_id = plat->periph_id;
 130
 131        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
 132        clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH,
 133                               priv->freq);
 134
 135        return 0;
 136}
 137
 138static int tegra30_spi_claim_bus(struct udevice *dev)
 139{
 140        struct udevice *bus = dev->parent;
 141        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 142        struct spi_regs *regs = priv->regs;
 143        u32 reg;
 144
 145        /* Change SPI clock to correct frequency, PLLP_OUT0 source */
 146        clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH,
 147                               priv->freq);
 148
 149        /* Clear stale status here */
 150        reg = SLINK_STAT_RDY | SLINK_STAT_RXF_FLUSH | SLINK_STAT_TXF_FLUSH | \
 151                SLINK_STAT_RXF_UNR | SLINK_STAT_TXF_OVF;
 152        writel(reg, &regs->status);
 153        debug("%s: STATUS = %08x\n", __func__, readl(&regs->status));
 154
 155        /* Set master mode and sw controlled CS */
 156        reg = readl(&regs->command);
 157        reg |= SLINK_CMD_M_S | SLINK_CMD_CS_SOFT;
 158        writel(reg, &regs->command);
 159        debug("%s: COMMAND = %08x\n", __func__, readl(&regs->command));
 160
 161        return 0;
 162}
 163
 164static void spi_cs_activate(struct udevice *dev)
 165{
 166        struct udevice *bus = dev->parent;
 167        struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
 168        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 169
 170        /* If it's too soon to do another transaction, wait */
 171        if (pdata->deactivate_delay_us &&
 172            priv->last_transaction_us) {
 173                ulong delay_us;         /* The delay completed so far */
 174                delay_us = timer_get_us() - priv->last_transaction_us;
 175                if (delay_us < pdata->deactivate_delay_us)
 176                        udelay(pdata->deactivate_delay_us - delay_us);
 177        }
 178
 179        /* CS is negated on Tegra, so drive a 1 to get a 0 */
 180        setbits_le32(&priv->regs->command, SLINK_CMD_CS_VAL);
 181}
 182
 183static void spi_cs_deactivate(struct udevice *dev)
 184{
 185        struct udevice *bus = dev->parent;
 186        struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
 187        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 188
 189        /* CS is negated on Tegra, so drive a 0 to get a 1 */
 190        clrbits_le32(&priv->regs->command, SLINK_CMD_CS_VAL);
 191
 192        /* Remember time of this transaction so we can honour the bus delay */
 193        if (pdata->deactivate_delay_us)
 194                priv->last_transaction_us = timer_get_us();
 195}
 196
 197static int tegra30_spi_xfer(struct udevice *dev, unsigned int bitlen,
 198                            const void *data_out, void *data_in,
 199                            unsigned long flags)
 200{
 201        struct udevice *bus = dev->parent;
 202        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 203        struct spi_regs *regs = priv->regs;
 204        u32 reg, tmpdout, tmpdin = 0;
 205        const u8 *dout = data_out;
 206        u8 *din = data_in;
 207        int num_bytes;
 208        int ret;
 209
 210        debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
 211              __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
 212        if (bitlen % 8)
 213                return -1;
 214        num_bytes = bitlen / 8;
 215
 216        ret = 0;
 217
 218        reg = readl(&regs->status);
 219        writel(reg, &regs->status);     /* Clear all SPI events via R/W */
 220        debug("%s entry: STATUS = %08x\n", __func__, reg);
 221
 222        reg = readl(&regs->status2);
 223        writel(reg, &regs->status2);    /* Clear all STATUS2 events via R/W */
 224        debug("%s entry: STATUS2 = %08x\n", __func__, reg);
 225
 226        debug("%s entry: COMMAND = %08x\n", __func__, readl(&regs->command));
 227
 228        clrsetbits_le32(&regs->command2, SLINK_CMD2_SS_EN_MASK,
 229                        SLINK_CMD2_TXEN | SLINK_CMD2_RXEN |
 230                        (spi_chip_select(dev) << SLINK_CMD2_SS_EN_SHIFT));
 231        debug("%s entry: COMMAND2 = %08x\n", __func__, readl(&regs->command2));
 232
 233        if (flags & SPI_XFER_BEGIN)
 234                spi_cs_activate(dev);
 235
 236        /* handle data in 32-bit chunks */
 237        while (num_bytes > 0) {
 238                int bytes;
 239                int is_read = 0;
 240                int tm, i;
 241
 242                tmpdout = 0;
 243                bytes = (num_bytes > 4) ?  4 : num_bytes;
 244
 245                if (dout != NULL) {
 246                        for (i = 0; i < bytes; ++i)
 247                                tmpdout = (tmpdout << 8) | dout[i];
 248                        dout += bytes;
 249                }
 250
 251                num_bytes -= bytes;
 252
 253                clrsetbits_le32(&regs->command, SLINK_CMD_BIT_LENGTH_MASK,
 254                                bytes * 8 - 1);
 255                writel(tmpdout, &regs->tx_fifo);
 256                setbits_le32(&regs->command, SLINK_CMD_GO);
 257
 258                /*
 259                 * Wait for SPI transmit FIFO to empty, or to time out.
 260                 * The RX FIFO status will be read and cleared last
 261                 */
 262                for (tm = 0, is_read = 0; tm < SPI_TIMEOUT; ++tm) {
 263                        u32 status;
 264
 265                        status = readl(&regs->status);
 266
 267                        /* We can exit when we've had both RX and TX activity */
 268                        if (is_read && (status & SLINK_STAT_TXF_EMPTY))
 269                                break;
 270
 271                        if ((status & (SLINK_STAT_BSY | SLINK_STAT_RDY)) !=
 272                                        SLINK_STAT_RDY)
 273                                tm++;
 274
 275                        else if (!(status & SLINK_STAT_RXF_EMPTY)) {
 276                                tmpdin = readl(&regs->rx_fifo);
 277                                is_read = 1;
 278
 279                                /* swap bytes read in */
 280                                if (din != NULL) {
 281                                        for (i = bytes - 1; i >= 0; --i) {
 282                                                din[i] = tmpdin & 0xff;
 283                                                tmpdin >>= 8;
 284                                        }
 285                                        din += bytes;
 286                                }
 287                        }
 288                }
 289
 290                if (tm >= SPI_TIMEOUT)
 291                        ret = tm;
 292
 293                /* clear ACK RDY, etc. bits */
 294                writel(readl(&regs->status), &regs->status);
 295        }
 296
 297        if (flags & SPI_XFER_END)
 298                spi_cs_deactivate(dev);
 299
 300        debug("%s: transfer ended. Value=%08x, status = %08x\n",
 301              __func__, tmpdin, readl(&regs->status));
 302
 303        if (ret) {
 304                printf("%s: timeout during SPI transfer, tm %d\n",
 305                       __func__, ret);
 306                return -1;
 307        }
 308
 309        return 0;
 310}
 311
 312static int tegra30_spi_set_speed(struct udevice *bus, uint speed)
 313{
 314        struct tegra_spi_platdata *plat = bus->platdata;
 315        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 316
 317        if (speed > plat->frequency)
 318                speed = plat->frequency;
 319        priv->freq = speed;
 320        debug("%s: regs=%p, speed=%d\n", __func__, priv->regs, priv->freq);
 321
 322        return 0;
 323}
 324
 325static int tegra30_spi_set_mode(struct udevice *bus, uint mode)
 326{
 327        struct tegra30_spi_priv *priv = dev_get_priv(bus);
 328        struct spi_regs *regs = priv->regs;
 329        u32 reg;
 330
 331        reg = readl(&regs->command);
 332
 333        /* Set CPOL and CPHA */
 334        reg &= ~(SLINK_CMD_IDLE_SCLK_MASK | SLINK_CMD_CK_SDA);
 335        if (mode & SPI_CPHA)
 336                reg |= SLINK_CMD_CK_SDA;
 337
 338        if (mode & SPI_CPOL)
 339                reg |= SLINK_CMD_IDLE_SCLK_DRIVE_HIGH;
 340        else
 341                reg |= SLINK_CMD_IDLE_SCLK_DRIVE_LOW;
 342
 343        writel(reg, &regs->command);
 344
 345        priv->mode = mode;
 346        debug("%s: regs=%p, mode=%d\n", __func__, priv->regs, priv->mode);
 347
 348        return 0;
 349}
 350
 351static const struct dm_spi_ops tegra30_spi_ops = {
 352        .claim_bus      = tegra30_spi_claim_bus,
 353        .xfer           = tegra30_spi_xfer,
 354        .set_speed      = tegra30_spi_set_speed,
 355        .set_mode       = tegra30_spi_set_mode,
 356        /*
 357         * cs_info is not needed, since we require all chip selects to be
 358         * in the device tree explicitly
 359         */
 360};
 361
 362static const struct udevice_id tegra30_spi_ids[] = {
 363        { .compatible = "nvidia,tegra20-slink" },
 364        { }
 365};
 366
 367U_BOOT_DRIVER(tegra30_spi) = {
 368        .name   = "tegra20_slink",
 369        .id     = UCLASS_SPI,
 370        .of_match = tegra30_spi_ids,
 371        .ops    = &tegra30_spi_ops,
 372        .ofdata_to_platdata = tegra30_spi_ofdata_to_platdata,
 373        .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
 374        .priv_auto_alloc_size = sizeof(struct tegra30_spi_priv),
 375        .probe  = tegra30_spi_probe,
 376};
 377