uboot/drivers/spi/atmel_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2007 Atmel Corporation
   4 */
   5#include <common.h>
   6#include <clk.h>
   7#include <dm.h>
   8#include <fdtdec.h>
   9#include <spi.h>
  10#include <malloc.h>
  11#include <wait_bit.h>
  12
  13#include <asm/io.h>
  14
  15#include <asm/arch/clk.h>
  16#include <asm/arch/hardware.h>
  17#ifdef CONFIG_DM_SPI
  18#include <asm/arch/at91_spi.h>
  19#endif
  20#ifdef CONFIG_DM_GPIO
  21#include <asm/gpio.h>
  22#endif
  23
  24#include "atmel_spi.h"
  25
  26#ifndef CONFIG_DM_SPI
  27
  28static int spi_has_wdrbt(struct atmel_spi_slave *slave)
  29{
  30        unsigned int ver;
  31
  32        ver = spi_readl(slave, VERSION);
  33
  34        return (ATMEL_SPI_VERSION_REV(ver) >= 0x210);
  35}
  36
  37struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  38                        unsigned int max_hz, unsigned int mode)
  39{
  40        struct atmel_spi_slave  *as;
  41        unsigned int            scbr;
  42        u32                     csrx;
  43        void                    *regs;
  44
  45        if (!spi_cs_is_valid(bus, cs))
  46                return NULL;
  47
  48        switch (bus) {
  49        case 0:
  50                regs = (void *)ATMEL_BASE_SPI0;
  51                break;
  52#ifdef ATMEL_BASE_SPI1
  53        case 1:
  54                regs = (void *)ATMEL_BASE_SPI1;
  55                break;
  56#endif
  57#ifdef ATMEL_BASE_SPI2
  58        case 2:
  59                regs = (void *)ATMEL_BASE_SPI2;
  60                break;
  61#endif
  62#ifdef ATMEL_BASE_SPI3
  63        case 3:
  64                regs = (void *)ATMEL_BASE_SPI3;
  65                break;
  66#endif
  67        default:
  68                return NULL;
  69        }
  70
  71
  72        scbr = (get_spi_clk_rate(bus) + max_hz - 1) / max_hz;
  73        if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
  74                /* Too low max SCK rate */
  75                return NULL;
  76        if (scbr < 1)
  77                scbr = 1;
  78
  79        csrx = ATMEL_SPI_CSRx_SCBR(scbr);
  80        csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
  81        if (!(mode & SPI_CPHA))
  82                csrx |= ATMEL_SPI_CSRx_NCPHA;
  83        if (mode & SPI_CPOL)
  84                csrx |= ATMEL_SPI_CSRx_CPOL;
  85
  86        as = spi_alloc_slave(struct atmel_spi_slave, bus, cs);
  87        if (!as)
  88                return NULL;
  89
  90        as->regs = regs;
  91        as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS
  92                        | ATMEL_SPI_MR_PCS(~(1 << cs) & 0xf);
  93        if (spi_has_wdrbt(as))
  94                as->mr |= ATMEL_SPI_MR_WDRBT;
  95
  96        spi_writel(as, CSR(cs), csrx);
  97
  98        return &as->slave;
  99}
 100
 101void spi_free_slave(struct spi_slave *slave)
 102{
 103        struct atmel_spi_slave *as = to_atmel_spi(slave);
 104
 105        free(as);
 106}
 107
 108int spi_claim_bus(struct spi_slave *slave)
 109{
 110        struct atmel_spi_slave *as = to_atmel_spi(slave);
 111
 112        /* Enable the SPI hardware */
 113        spi_writel(as, CR, ATMEL_SPI_CR_SPIEN);
 114
 115        /*
 116         * Select the slave. This should set SCK to the correct
 117         * initial state, etc.
 118         */
 119        spi_writel(as, MR, as->mr);
 120
 121        return 0;
 122}
 123
 124void spi_release_bus(struct spi_slave *slave)
 125{
 126        struct atmel_spi_slave *as = to_atmel_spi(slave);
 127
 128        /* Disable the SPI hardware */
 129        spi_writel(as, CR, ATMEL_SPI_CR_SPIDIS);
 130}
 131
 132int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 133                const void *dout, void *din, unsigned long flags)
 134{
 135        struct atmel_spi_slave *as = to_atmel_spi(slave);
 136        unsigned int    len_tx;
 137        unsigned int    len_rx;
 138        unsigned int    len;
 139        u32             status;
 140        const u8        *txp = dout;
 141        u8              *rxp = din;
 142        u8              value;
 143
 144        if (bitlen == 0)
 145                /* Finish any previously submitted transfers */
 146                goto out;
 147
 148        /*
 149         * TODO: The controller can do non-multiple-of-8 bit
 150         * transfers, but this driver currently doesn't support it.
 151         *
 152         * It's also not clear how such transfers are supposed to be
 153         * represented as a stream of bytes...this is a limitation of
 154         * the current SPI interface.
 155         */
 156        if (bitlen % 8) {
 157                /* Errors always terminate an ongoing transfer */
 158                flags |= SPI_XFER_END;
 159                goto out;
 160        }
 161
 162        len = bitlen / 8;
 163
 164        /*
 165         * The controller can do automatic CS control, but it is
 166         * somewhat quirky, and it doesn't really buy us much anyway
 167         * in the context of U-Boot.
 168         */
 169        if (flags & SPI_XFER_BEGIN) {
 170                spi_cs_activate(slave);
 171                /*
 172                 * sometimes the RDR is not empty when we get here,
 173                 * in theory that should not happen, but it DOES happen.
 174                 * Read it here to be on the safe side.
 175                 * That also clears the OVRES flag. Required if the
 176                 * following loop exits due to OVRES!
 177                 */
 178                spi_readl(as, RDR);
 179        }
 180
 181        for (len_tx = 0, len_rx = 0; len_rx < len; ) {
 182                status = spi_readl(as, SR);
 183
 184                if (status & ATMEL_SPI_SR_OVRES)
 185                        return -1;
 186
 187                if (len_tx < len && (status & ATMEL_SPI_SR_TDRE)) {
 188                        if (txp)
 189                                value = *txp++;
 190                        else
 191                                value = 0;
 192                        spi_writel(as, TDR, value);
 193                        len_tx++;
 194                }
 195                if (status & ATMEL_SPI_SR_RDRF) {
 196                        value = spi_readl(as, RDR);
 197                        if (rxp)
 198                                *rxp++ = value;
 199                        len_rx++;
 200                }
 201        }
 202
 203out:
 204        if (flags & SPI_XFER_END) {
 205                /*
 206                 * Wait until the transfer is completely done before
 207                 * we deactivate CS.
 208                 */
 209                do {
 210                        status = spi_readl(as, SR);
 211                } while (!(status & ATMEL_SPI_SR_TXEMPTY));
 212
 213                spi_cs_deactivate(slave);
 214        }
 215
 216        return 0;
 217}
 218
 219#else
 220
 221#define MAX_CS_COUNT    4
 222
 223struct atmel_spi_platdata {
 224        struct at91_spi *regs;
 225};
 226
 227struct atmel_spi_priv {
 228        unsigned int freq;              /* Default frequency */
 229        unsigned int mode;
 230        ulong bus_clk_rate;
 231#ifdef CONFIG_DM_GPIO
 232        struct gpio_desc cs_gpios[MAX_CS_COUNT];
 233#endif
 234};
 235
 236static int atmel_spi_claim_bus(struct udevice *dev)
 237{
 238        struct udevice *bus = dev_get_parent(dev);
 239        struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
 240        struct atmel_spi_priv *priv = dev_get_priv(bus);
 241        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 242        struct at91_spi *reg_base = bus_plat->regs;
 243        u32 cs = slave_plat->cs;
 244        u32 freq = priv->freq;
 245        u32 scbr, csrx, mode;
 246
 247        scbr = (priv->bus_clk_rate + freq - 1) / freq;
 248        if (scbr > ATMEL_SPI_CSRx_SCBR_MAX)
 249                return -EINVAL;
 250
 251        if (scbr < 1)
 252                scbr = 1;
 253
 254        csrx = ATMEL_SPI_CSRx_SCBR(scbr);
 255        csrx |= ATMEL_SPI_CSRx_BITS(ATMEL_SPI_BITS_8);
 256
 257        if (!(priv->mode & SPI_CPHA))
 258                csrx |= ATMEL_SPI_CSRx_NCPHA;
 259        if (priv->mode & SPI_CPOL)
 260                csrx |= ATMEL_SPI_CSRx_CPOL;
 261
 262        writel(csrx, &reg_base->csr[cs]);
 263
 264        mode = ATMEL_SPI_MR_MSTR |
 265               ATMEL_SPI_MR_MODFDIS |
 266               ATMEL_SPI_MR_WDRBT |
 267               ATMEL_SPI_MR_PCS(~(1 << cs));
 268
 269        writel(mode, &reg_base->mr);
 270
 271        writel(ATMEL_SPI_CR_SPIEN, &reg_base->cr);
 272
 273        return 0;
 274}
 275
 276static int atmel_spi_release_bus(struct udevice *dev)
 277{
 278        struct udevice *bus = dev_get_parent(dev);
 279        struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
 280
 281        writel(ATMEL_SPI_CR_SPIDIS, &bus_plat->regs->cr);
 282
 283        return 0;
 284}
 285
 286static void atmel_spi_cs_activate(struct udevice *dev)
 287{
 288#ifdef CONFIG_DM_GPIO
 289        struct udevice *bus = dev_get_parent(dev);
 290        struct atmel_spi_priv *priv = dev_get_priv(bus);
 291        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 292        u32 cs = slave_plat->cs;
 293
 294        if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
 295                return;
 296
 297        dm_gpio_set_value(&priv->cs_gpios[cs], 0);
 298#endif
 299}
 300
 301static void atmel_spi_cs_deactivate(struct udevice *dev)
 302{
 303#ifdef CONFIG_DM_GPIO
 304        struct udevice *bus = dev_get_parent(dev);
 305        struct atmel_spi_priv *priv = dev_get_priv(bus);
 306        struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
 307        u32 cs = slave_plat->cs;
 308
 309        if (!dm_gpio_is_valid(&priv->cs_gpios[cs]))
 310                return;
 311
 312        dm_gpio_set_value(&priv->cs_gpios[cs], 1);
 313#endif
 314}
 315
 316static int atmel_spi_xfer(struct udevice *dev, unsigned int bitlen,
 317                          const void *dout, void *din, unsigned long flags)
 318{
 319        struct udevice *bus = dev_get_parent(dev);
 320        struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
 321        struct at91_spi *reg_base = bus_plat->regs;
 322
 323        u32 len_tx, len_rx, len;
 324        u32 status;
 325        const u8 *txp = dout;
 326        u8 *rxp = din;
 327        u8 value;
 328
 329        if (bitlen == 0)
 330                goto out;
 331
 332        /*
 333         * The controller can do non-multiple-of-8 bit
 334         * transfers, but this driver currently doesn't support it.
 335         *
 336         * It's also not clear how such transfers are supposed to be
 337         * represented as a stream of bytes...this is a limitation of
 338         * the current SPI interface.
 339         */
 340        if (bitlen % 8) {
 341                /* Errors always terminate an ongoing transfer */
 342                flags |= SPI_XFER_END;
 343                goto out;
 344        }
 345
 346        len = bitlen / 8;
 347
 348        /*
 349         * The controller can do automatic CS control, but it is
 350         * somewhat quirky, and it doesn't really buy us much anyway
 351         * in the context of U-Boot.
 352         */
 353        if (flags & SPI_XFER_BEGIN) {
 354                atmel_spi_cs_activate(dev);
 355
 356                /*
 357                 * sometimes the RDR is not empty when we get here,
 358                 * in theory that should not happen, but it DOES happen.
 359                 * Read it here to be on the safe side.
 360                 * That also clears the OVRES flag. Required if the
 361                 * following loop exits due to OVRES!
 362                 */
 363                readl(&reg_base->rdr);
 364        }
 365
 366        for (len_tx = 0, len_rx = 0; len_rx < len; ) {
 367                status = readl(&reg_base->sr);
 368
 369                if (status & ATMEL_SPI_SR_OVRES)
 370                        return -1;
 371
 372                if ((len_tx < len) && (status & ATMEL_SPI_SR_TDRE)) {
 373                        if (txp)
 374                                value = *txp++;
 375                        else
 376                                value = 0;
 377                        writel(value, &reg_base->tdr);
 378                        len_tx++;
 379                }
 380
 381                if (status & ATMEL_SPI_SR_RDRF) {
 382                        value = readl(&reg_base->rdr);
 383                        if (rxp)
 384                                *rxp++ = value;
 385                        len_rx++;
 386                }
 387        }
 388
 389out:
 390        if (flags & SPI_XFER_END) {
 391                /*
 392                 * Wait until the transfer is completely done before
 393                 * we deactivate CS.
 394                 */
 395                wait_for_bit_le32(&reg_base->sr,
 396                                  ATMEL_SPI_SR_TXEMPTY, true, 1000, false);
 397
 398                atmel_spi_cs_deactivate(dev);
 399        }
 400
 401        return 0;
 402}
 403
 404static int atmel_spi_set_speed(struct udevice *bus, uint speed)
 405{
 406        struct atmel_spi_priv *priv = dev_get_priv(bus);
 407
 408        priv->freq = speed;
 409
 410        return 0;
 411}
 412
 413static int atmel_spi_set_mode(struct udevice *bus, uint mode)
 414{
 415        struct atmel_spi_priv *priv = dev_get_priv(bus);
 416
 417        priv->mode = mode;
 418
 419        return 0;
 420}
 421
 422static const struct dm_spi_ops atmel_spi_ops = {
 423        .claim_bus      = atmel_spi_claim_bus,
 424        .release_bus    = atmel_spi_release_bus,
 425        .xfer           = atmel_spi_xfer,
 426        .set_speed      = atmel_spi_set_speed,
 427        .set_mode       = atmel_spi_set_mode,
 428        /*
 429         * cs_info is not needed, since we require all chip selects to be
 430         * in the device tree explicitly
 431         */
 432};
 433
 434static int atmel_spi_enable_clk(struct udevice *bus)
 435{
 436        struct atmel_spi_priv *priv = dev_get_priv(bus);
 437        struct clk clk;
 438        ulong clk_rate;
 439        int ret;
 440
 441        ret = clk_get_by_index(bus, 0, &clk);
 442        if (ret)
 443                return -EINVAL;
 444
 445        ret = clk_enable(&clk);
 446        if (ret)
 447                return ret;
 448
 449        clk_rate = clk_get_rate(&clk);
 450        if (!clk_rate)
 451                return -EINVAL;
 452
 453        priv->bus_clk_rate = clk_rate;
 454
 455        clk_free(&clk);
 456
 457        return 0;
 458}
 459
 460static int atmel_spi_probe(struct udevice *bus)
 461{
 462        struct atmel_spi_platdata *bus_plat = dev_get_platdata(bus);
 463        int ret;
 464
 465        ret = atmel_spi_enable_clk(bus);
 466        if (ret)
 467                return ret;
 468
 469        bus_plat->regs = (struct at91_spi *)devfdt_get_addr(bus);
 470
 471#ifdef CONFIG_DM_GPIO
 472        struct atmel_spi_priv *priv = dev_get_priv(bus);
 473        int i;
 474
 475        ret = gpio_request_list_by_name(bus, "cs-gpios", priv->cs_gpios,
 476                                        ARRAY_SIZE(priv->cs_gpios), 0);
 477        if (ret < 0) {
 478                pr_err("Can't get %s gpios! Error: %d", bus->name, ret);
 479                return ret;
 480        }
 481
 482        for(i = 0; i < ARRAY_SIZE(priv->cs_gpios); i++) {
 483                if (!dm_gpio_is_valid(&priv->cs_gpios[i]))
 484                        continue;
 485
 486                dm_gpio_set_dir_flags(&priv->cs_gpios[i],
 487                                      GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
 488        }
 489#endif
 490
 491        writel(ATMEL_SPI_CR_SWRST, &bus_plat->regs->cr);
 492
 493        return 0;
 494}
 495
 496static const struct udevice_id atmel_spi_ids[] = {
 497        { .compatible = "atmel,at91rm9200-spi" },
 498        { }
 499};
 500
 501U_BOOT_DRIVER(atmel_spi) = {
 502        .name   = "atmel_spi",
 503        .id     = UCLASS_SPI,
 504        .of_match = atmel_spi_ids,
 505        .ops    = &atmel_spi_ops,
 506        .platdata_auto_alloc_size = sizeof(struct atmel_spi_platdata),
 507        .priv_auto_alloc_size = sizeof(struct atmel_spi_priv),
 508        .probe  = atmel_spi_probe,
 509};
 510#endif
 511