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