uboot/drivers/spi/davinci_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
   4 *
   5 * Driver for SPI controller on DaVinci. Based on atmel_spi.c
   6 * by Atmel Corporation
   7 *
   8 * Copyright (C) 2007 Atmel Corporation
   9 */
  10
  11#include <common.h>
  12#include <log.h>
  13#include <spi.h>
  14#include <malloc.h>
  15#include <asm/global_data.h>
  16#include <asm/io.h>
  17#include <asm/arch/hardware.h>
  18#include <dm.h>
  19#include <dm/platform_data/spi_davinci.h>
  20#include <linux/bitops.h>
  21#include <linux/delay.h>
  22
  23/* SPIGCR0 */
  24#define SPIGCR0_SPIENA_MASK     0x1
  25#define SPIGCR0_SPIRST_MASK     0x0
  26
  27/* SPIGCR0 */
  28#define SPIGCR1_CLKMOD_MASK     BIT(1)
  29#define SPIGCR1_MASTER_MASK     BIT(0)
  30#define SPIGCR1_SPIENA_MASK     BIT(24)
  31
  32/* SPIPC0 */
  33#define SPIPC0_DIFUN_MASK       BIT(11)         /* SIMO */
  34#define SPIPC0_DOFUN_MASK       BIT(10)         /* SOMI */
  35#define SPIPC0_CLKFUN_MASK      BIT(9)          /* CLK */
  36#define SPIPC0_EN0FUN_MASK      BIT(0)
  37
  38/* SPIFMT0 */
  39#define SPIFMT_SHIFTDIR_SHIFT   20
  40#define SPIFMT_POLARITY_SHIFT   17
  41#define SPIFMT_PHASE_SHIFT      16
  42#define SPIFMT_PRESCALE_SHIFT   8
  43
  44/* SPIDAT1 */
  45#define SPIDAT1_CSHOLD_SHIFT    28
  46#define SPIDAT1_CSNR_SHIFT      16
  47
  48/* SPIDELAY */
  49#define SPI_C2TDELAY_SHIFT      24
  50#define SPI_T2CDELAY_SHIFT      16
  51
  52/* SPIBUF */
  53#define SPIBUF_RXEMPTY_MASK     BIT(31)
  54#define SPIBUF_TXFULL_MASK      BIT(29)
  55
  56/* SPIDEF */
  57#define SPIDEF_CSDEF0_MASK      BIT(0)
  58
  59DECLARE_GLOBAL_DATA_PTR;
  60
  61/* davinci spi register set */
  62struct davinci_spi_regs {
  63        dv_reg  gcr0;           /* 0x00 */
  64        dv_reg  gcr1;           /* 0x04 */
  65        dv_reg  int0;           /* 0x08 */
  66        dv_reg  lvl;            /* 0x0c */
  67        dv_reg  flg;            /* 0x10 */
  68        dv_reg  pc0;            /* 0x14 */
  69        dv_reg  pc1;            /* 0x18 */
  70        dv_reg  pc2;            /* 0x1c */
  71        dv_reg  pc3;            /* 0x20 */
  72        dv_reg  pc4;            /* 0x24 */
  73        dv_reg  pc5;            /* 0x28 */
  74        dv_reg  rsvd[3];
  75        dv_reg  dat0;           /* 0x38 */
  76        dv_reg  dat1;           /* 0x3c */
  77        dv_reg  buf;            /* 0x40 */
  78        dv_reg  emu;            /* 0x44 */
  79        dv_reg  delay;          /* 0x48 */
  80        dv_reg  def;            /* 0x4c */
  81        dv_reg  fmt0;           /* 0x50 */
  82        dv_reg  fmt1;           /* 0x54 */
  83        dv_reg  fmt2;           /* 0x58 */
  84        dv_reg  fmt3;           /* 0x5c */
  85        dv_reg  intvec0;        /* 0x60 */
  86        dv_reg  intvec1;        /* 0x64 */
  87};
  88
  89/* davinci spi slave */
  90struct davinci_spi_slave {
  91        struct davinci_spi_regs *regs;
  92        unsigned int freq; /* current SPI bus frequency */
  93        unsigned int mode; /* current SPI mode used */
  94        u8 num_cs;         /* total no. of CS available */
  95        u8 cur_cs;         /* CS of current slave */
  96        bool half_duplex;  /* true, if master is half-duplex only */
  97};
  98
  99/*
 100 * This functions needs to act like a macro to avoid pipeline reloads in the
 101 * loops below. Use always_inline. This gains us about 160KiB/s and the bloat
 102 * appears to be zero bytes (da830).
 103 */
 104__attribute__((always_inline))
 105static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data)
 106{
 107        u32     buf_reg_val;
 108
 109        /* send out data */
 110        writel(data, &ds->regs->dat1);
 111
 112        /* wait for the data to clock in/out */
 113        while ((buf_reg_val = readl(&ds->regs->buf)) & SPIBUF_RXEMPTY_MASK)
 114                ;
 115
 116        return buf_reg_val;
 117}
 118
 119static int davinci_spi_read(struct davinci_spi_slave *ds, unsigned int len,
 120                            u8 *rxp, unsigned long flags)
 121{
 122        unsigned int data1_reg_val;
 123
 124        /* enable CS hold, CS[n] and clear the data bits */
 125        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
 126                         (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
 127
 128        /* wait till TXFULL is deasserted */
 129        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
 130                ;
 131
 132        /* preload the TX buffer to avoid clock starvation */
 133        writel(data1_reg_val, &ds->regs->dat1);
 134
 135        /* keep reading 1 byte until only 1 byte left */
 136        while ((len--) > 1)
 137                *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val);
 138
 139        /* clear CS hold when we reach the end */
 140        if (flags & SPI_XFER_END)
 141                data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
 142
 143        /* read the last byte */
 144        *rxp = davinci_spi_xfer_data(ds, data1_reg_val);
 145
 146        return 0;
 147}
 148
 149static int davinci_spi_write(struct davinci_spi_slave *ds, unsigned int len,
 150                             const u8 *txp, unsigned long flags)
 151{
 152        unsigned int data1_reg_val;
 153
 154        /* enable CS hold and clear the data bits */
 155        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
 156                         (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
 157
 158        /* wait till TXFULL is deasserted */
 159        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
 160                ;
 161
 162        /* preload the TX buffer to avoid clock starvation */
 163        if (len > 2) {
 164                writel(data1_reg_val | *txp++, &ds->regs->dat1);
 165                len--;
 166        }
 167
 168        /* keep writing 1 byte until only 1 byte left */
 169        while ((len--) > 1)
 170                davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
 171
 172        /* clear CS hold when we reach the end */
 173        if (flags & SPI_XFER_END)
 174                data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
 175
 176        /* write the last byte */
 177        davinci_spi_xfer_data(ds, data1_reg_val | *txp);
 178
 179        return 0;
 180}
 181
 182static int davinci_spi_read_write(struct davinci_spi_slave *ds, unsigned
 183                                  int len, u8 *rxp, const u8 *txp,
 184                                  unsigned long flags)
 185{
 186        unsigned int data1_reg_val;
 187
 188        /* enable CS hold and clear the data bits */
 189        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
 190                         (ds->cur_cs << SPIDAT1_CSNR_SHIFT));
 191
 192        /* wait till TXFULL is deasserted */
 193        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
 194                ;
 195
 196        /* keep reading and writing 1 byte until only 1 byte left */
 197        while ((len--) > 1)
 198                *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
 199
 200        /* clear CS hold when we reach the end */
 201        if (flags & SPI_XFER_END)
 202                data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
 203
 204        /* read and write the last byte */
 205        *rxp = davinci_spi_xfer_data(ds, data1_reg_val | *txp);
 206
 207        return 0;
 208}
 209
 210
 211static int __davinci_spi_claim_bus(struct davinci_spi_slave *ds, int cs)
 212{
 213        unsigned int mode = 0, scalar;
 214
 215        /* Enable the SPI hardware */
 216        writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
 217        udelay(1000);
 218        writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
 219
 220        /* Set master mode, powered up and not activated */
 221        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
 222
 223        /* CS, CLK, SIMO and SOMI are functional pins */
 224        writel(((1 << cs) | SPIPC0_CLKFUN_MASK |
 225                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
 226
 227        /* setup format */
 228        scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
 229
 230        /*
 231         * Use following format:
 232         *   character length = 8,
 233         *   MSB shifted out first
 234         */
 235        if (ds->mode & SPI_CPOL)
 236                mode |= SPI_CPOL;
 237        if (!(ds->mode & SPI_CPHA))
 238                mode |= SPI_CPHA;
 239        writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
 240                (mode << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
 241
 242        /*
 243         * Including a minor delay. No science here. Should be good even with
 244         * no delay
 245         */
 246        writel((50 << SPI_C2TDELAY_SHIFT) |
 247                (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
 248
 249        /* default chip select register */
 250        writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
 251
 252        /* no interrupts */
 253        writel(0, &ds->regs->int0);
 254        writel(0, &ds->regs->lvl);
 255
 256        /* enable SPI */
 257        writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
 258
 259        return 0;
 260}
 261
 262static int __davinci_spi_release_bus(struct davinci_spi_slave *ds)
 263{
 264        /* Disable the SPI hardware */
 265        writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
 266
 267        return 0;
 268}
 269
 270static int __davinci_spi_xfer(struct davinci_spi_slave *ds,
 271                unsigned int bitlen,  const void *dout, void *din,
 272                unsigned long flags)
 273{
 274        unsigned int len;
 275
 276        if (bitlen == 0)
 277                /* Finish any previously submitted transfers */
 278                goto out;
 279
 280        /*
 281         * It's not clear how non-8-bit-aligned transfers are supposed to be
 282         * represented as a stream of bytes...this is a limitation of
 283         * the current SPI interface - here we terminate on receiving such a
 284         * transfer request.
 285         */
 286        if (bitlen % 8) {
 287                /* Errors always terminate an ongoing transfer */
 288                flags |= SPI_XFER_END;
 289                goto out;
 290        }
 291
 292        len = bitlen / 8;
 293
 294        if (!dout)
 295                return davinci_spi_read(ds, len, din, flags);
 296        if (!din)
 297                return davinci_spi_write(ds, len, dout, flags);
 298        if (!ds->half_duplex)
 299                return davinci_spi_read_write(ds, len, din, dout, flags);
 300
 301        printf("SPI full duplex not supported\n");
 302        flags |= SPI_XFER_END;
 303
 304out:
 305        if (flags & SPI_XFER_END) {
 306                u8 dummy = 0;
 307                davinci_spi_write(ds, 1, &dummy, flags);
 308        }
 309        return 0;
 310}
 311
 312static int davinci_spi_set_speed(struct udevice *bus, uint max_hz)
 313{
 314        struct davinci_spi_slave *ds = dev_get_priv(bus);
 315
 316        debug("%s speed %u\n", __func__, max_hz);
 317        if (max_hz > CONFIG_SYS_SPI_CLK / 2)
 318                return -EINVAL;
 319
 320        ds->freq = max_hz;
 321
 322        return 0;
 323}
 324
 325static int davinci_spi_set_mode(struct udevice *bus, uint mode)
 326{
 327        struct davinci_spi_slave *ds = dev_get_priv(bus);
 328
 329        debug("%s mode %u\n", __func__, mode);
 330        ds->mode = mode;
 331
 332        return 0;
 333}
 334
 335static int davinci_spi_claim_bus(struct udevice *dev)
 336{
 337        struct dm_spi_slave_plat *slave_plat =
 338                dev_get_parent_plat(dev);
 339        struct udevice *bus = dev->parent;
 340        struct davinci_spi_slave *ds = dev_get_priv(bus);
 341
 342        if (slave_plat->cs >= ds->num_cs) {
 343                printf("Invalid SPI chipselect\n");
 344                return -EINVAL;
 345        }
 346        ds->half_duplex = slave_plat->mode & SPI_PREAMBLE;
 347
 348        return __davinci_spi_claim_bus(ds, slave_plat->cs);
 349}
 350
 351static int davinci_spi_release_bus(struct udevice *dev)
 352{
 353        struct davinci_spi_slave *ds = dev_get_priv(dev->parent);
 354
 355        return __davinci_spi_release_bus(ds);
 356}
 357
 358static int davinci_spi_xfer(struct udevice *dev, unsigned int bitlen,
 359                            const void *dout, void *din,
 360                            unsigned long flags)
 361{
 362        struct dm_spi_slave_plat *slave =
 363                dev_get_parent_plat(dev);
 364        struct udevice *bus = dev->parent;
 365        struct davinci_spi_slave *ds = dev_get_priv(bus);
 366
 367        if (slave->cs >= ds->num_cs) {
 368                printf("Invalid SPI chipselect\n");
 369                return -EINVAL;
 370        }
 371        ds->cur_cs = slave->cs;
 372
 373        return __davinci_spi_xfer(ds, bitlen, dout, din, flags);
 374}
 375
 376static const struct dm_spi_ops davinci_spi_ops = {
 377        .claim_bus      = davinci_spi_claim_bus,
 378        .release_bus    = davinci_spi_release_bus,
 379        .xfer           = davinci_spi_xfer,
 380        .set_speed      = davinci_spi_set_speed,
 381        .set_mode       = davinci_spi_set_mode,
 382};
 383
 384static int davinci_spi_probe(struct udevice *bus)
 385{
 386        struct davinci_spi_slave *ds = dev_get_priv(bus);
 387        struct davinci_spi_plat *plat = dev_get_plat(bus);
 388        ds->regs = plat->regs;
 389        ds->num_cs = plat->num_cs;
 390
 391        return 0;
 392}
 393
 394#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 395static int davinci_ofdata_to_platadata(struct udevice *bus)
 396{
 397        struct davinci_spi_plat *plat = dev_get_plat(bus);
 398        fdt_addr_t addr;
 399
 400        addr = dev_read_addr(bus);
 401        if (addr == FDT_ADDR_T_NONE)
 402                return -EINVAL;
 403
 404        plat->regs = (struct davinci_spi_regs *)addr;
 405        plat->num_cs = fdtdec_get_int(gd->fdt_blob, dev_of_offset(bus), "num-cs", 4);
 406
 407        return 0;
 408}
 409
 410static const struct udevice_id davinci_spi_ids[] = {
 411        { .compatible = "ti,keystone-spi" },
 412        { .compatible = "ti,dm6441-spi" },
 413        { .compatible = "ti,da830-spi" },
 414        { }
 415};
 416#endif
 417
 418U_BOOT_DRIVER(davinci_spi) = {
 419        .name = "davinci_spi",
 420        .id = UCLASS_SPI,
 421#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
 422        .of_match = davinci_spi_ids,
 423        .of_to_plat = davinci_ofdata_to_platadata,
 424        .plat_auto      = sizeof(struct davinci_spi_plat),
 425#endif
 426        .probe = davinci_spi_probe,
 427        .ops = &davinci_spi_ops,
 428        .priv_auto      = sizeof(struct davinci_spi_slave),
 429};
 430