uboot/drivers/spi/davinci_spi.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
   3 *
   4 * Driver for SPI controller on DaVinci. Based on atmel_spi.c
   5 * by Atmel Corporation
   6 *
   7 * Copyright (C) 2007 Atmel Corporation
   8 *
   9 * See file CREDITS for list of people who contributed to this
  10 * project.
  11 *
  12 * This program is free software; you can redistribute it and/or
  13 * modify it under the terms of the GNU General Public License as
  14 * published by the Free Software Foundation; either version 2 of
  15 * the License, or (at your option) any later version.
  16 *
  17 * This program is distributed in the hope that it will be useful,
  18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 * GNU General Public License for more details.
  21 *
  22 * You should have received a copy of the GNU General Public License
  23 * along with this program; if not, write to the Free Software
  24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  25 * MA 02111-1307 USA
  26 */
  27#include <common.h>
  28#include <spi.h>
  29#include <malloc.h>
  30#include <asm/io.h>
  31#include <asm/arch/hardware.h>
  32#include "davinci_spi.h"
  33
  34void spi_init()
  35{
  36        /* do nothing */
  37}
  38
  39struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
  40                        unsigned int max_hz, unsigned int mode)
  41{
  42        struct davinci_spi_slave        *ds;
  43
  44        if (!spi_cs_is_valid(bus, cs))
  45                return NULL;
  46
  47        ds = malloc(sizeof(*ds));
  48        if (!ds)
  49                return NULL;
  50
  51        ds->slave.bus = bus;
  52        ds->slave.cs = cs;
  53        ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
  54        ds->freq = max_hz;
  55
  56        return &ds->slave;
  57}
  58
  59void spi_free_slave(struct spi_slave *slave)
  60{
  61        struct davinci_spi_slave *ds = to_davinci_spi(slave);
  62
  63        free(ds);
  64}
  65
  66int spi_claim_bus(struct spi_slave *slave)
  67{
  68        struct davinci_spi_slave *ds = to_davinci_spi(slave);
  69        unsigned int scalar;
  70
  71        /* Enable the SPI hardware */
  72        writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
  73        udelay(1000);
  74        writel(SPIGCR0_SPIENA_MASK, &ds->regs->gcr0);
  75
  76        /* Set master mode, powered up and not activated */
  77        writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
  78
  79        /* CS, CLK, SIMO and SOMI are functional pins */
  80        writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK |
  81                SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
  82
  83        /* setup format */
  84        scalar = ((CONFIG_SYS_SPI_CLK / ds->freq) - 1) & 0xFF;
  85
  86        /*
  87         * Use following format:
  88         *   character length = 8,
  89         *   clock signal delayed by half clk cycle,
  90         *   clock low in idle state - Mode 0,
  91         *   MSB shifted out first
  92         */
  93        writel(8 | (scalar << SPIFMT_PRESCALE_SHIFT) |
  94                (1 << SPIFMT_PHASE_SHIFT), &ds->regs->fmt0);
  95
  96        /*
  97         * Including a minor delay. No science here. Should be good even with
  98         * no delay
  99         */
 100        writel((50 << SPI_C2TDELAY_SHIFT) |
 101                (50 << SPI_T2CDELAY_SHIFT), &ds->regs->delay);
 102
 103        /* default chip select register */
 104        writel(SPIDEF_CSDEF0_MASK, &ds->regs->def);
 105
 106        /* no interrupts */
 107        writel(0, &ds->regs->int0);
 108        writel(0, &ds->regs->lvl);
 109
 110        /* enable SPI */
 111        writel((readl(&ds->regs->gcr1) | SPIGCR1_SPIENA_MASK), &ds->regs->gcr1);
 112
 113        return 0;
 114}
 115
 116void spi_release_bus(struct spi_slave *slave)
 117{
 118        struct davinci_spi_slave *ds = to_davinci_spi(slave);
 119
 120        /* Disable the SPI hardware */
 121        writel(SPIGCR0_SPIRST_MASK, &ds->regs->gcr0);
 122}
 123
 124/*
 125 * This functions needs to act like a macro to avoid pipeline reloads in the
 126 * loops below. Use always_inline. This gains us about 160KiB/s and the bloat
 127 * appears to be zero bytes (da830).
 128 */
 129__attribute__((always_inline))
 130static inline u32 davinci_spi_xfer_data(struct davinci_spi_slave *ds, u32 data)
 131{
 132        u32     buf_reg_val;
 133
 134        /* send out data */
 135        writel(data, &ds->regs->dat1);
 136
 137        /* wait for the data to clock in/out */
 138        while ((buf_reg_val = readl(&ds->regs->buf)) & SPIBUF_RXEMPTY_MASK)
 139                ;
 140
 141        return buf_reg_val;
 142}
 143
 144static int davinci_spi_read(struct spi_slave *slave, unsigned int len,
 145                            u8 *rxp, unsigned long flags)
 146{
 147        struct davinci_spi_slave *ds = to_davinci_spi(slave);
 148        unsigned int data1_reg_val;
 149
 150        /* enable CS hold, CS[n] and clear the data bits */
 151        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
 152                         (slave->cs << SPIDAT1_CSNR_SHIFT));
 153
 154        /* wait till TXFULL is deasserted */
 155        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
 156                ;
 157
 158        /* preload the TX buffer to avoid clock starvation */
 159        writel(data1_reg_val, &ds->regs->dat1);
 160
 161        /* keep reading 1 byte until only 1 byte left */
 162        while ((len--) > 1)
 163                *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val);
 164
 165        /* clear CS hold when we reach the end */
 166        if (flags & SPI_XFER_END)
 167                data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
 168
 169        /* read the last byte */
 170        *rxp = davinci_spi_xfer_data(ds, data1_reg_val);
 171
 172        return 0;
 173}
 174
 175static int davinci_spi_write(struct spi_slave *slave, unsigned int len,
 176                             const u8 *txp, unsigned long flags)
 177{
 178        struct davinci_spi_slave *ds = to_davinci_spi(slave);
 179        unsigned int data1_reg_val;
 180
 181        /* enable CS hold and clear the data bits */
 182        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
 183                         (slave->cs << SPIDAT1_CSNR_SHIFT));
 184
 185        /* wait till TXFULL is deasserted */
 186        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
 187                ;
 188
 189        /* preload the TX buffer to avoid clock starvation */
 190        if (len > 2) {
 191                writel(data1_reg_val | *txp++, &ds->regs->dat1);
 192                len--;
 193        }
 194
 195        /* keep writing 1 byte until only 1 byte left */
 196        while ((len--) > 1)
 197                davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
 198
 199        /* clear CS hold when we reach the end */
 200        if (flags & SPI_XFER_END)
 201                data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
 202
 203        /* write the last byte */
 204        davinci_spi_xfer_data(ds, data1_reg_val | *txp);
 205
 206        return 0;
 207}
 208
 209#ifndef CONFIG_SPI_HALF_DUPLEX
 210static int davinci_spi_read_write(struct spi_slave *slave, unsigned int len,
 211                                  u8 *rxp, const u8 *txp, unsigned long flags)
 212{
 213        struct davinci_spi_slave *ds = to_davinci_spi(slave);
 214        unsigned int data1_reg_val;
 215
 216        /* enable CS hold and clear the data bits */
 217        data1_reg_val = ((1 << SPIDAT1_CSHOLD_SHIFT) |
 218                         (slave->cs << SPIDAT1_CSNR_SHIFT));
 219
 220        /* wait till TXFULL is deasserted */
 221        while (readl(&ds->regs->buf) & SPIBUF_TXFULL_MASK)
 222                ;
 223
 224        /* keep reading and writing 1 byte until only 1 byte left */
 225        while ((len--) > 1)
 226                *rxp++ = davinci_spi_xfer_data(ds, data1_reg_val | *txp++);
 227
 228        /* clear CS hold when we reach the end */
 229        if (flags & SPI_XFER_END)
 230                data1_reg_val &= ~(1 << SPIDAT1_CSHOLD_SHIFT);
 231
 232        /* read and write the last byte */
 233        *rxp = davinci_spi_xfer_data(ds, data1_reg_val | *txp);
 234
 235        return 0;
 236}
 237#endif
 238
 239int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 240             const void *dout, void *din, unsigned long flags)
 241{
 242        unsigned int len;
 243
 244        if (bitlen == 0)
 245                /* Finish any previously submitted transfers */
 246                goto out;
 247
 248        /*
 249         * It's not clear how non-8-bit-aligned transfers are supposed to be
 250         * represented as a stream of bytes...this is a limitation of
 251         * the current SPI interface - here we terminate on receiving such a
 252         * transfer request.
 253         */
 254        if (bitlen % 8) {
 255                /* Errors always terminate an ongoing transfer */
 256                flags |= SPI_XFER_END;
 257                goto out;
 258        }
 259
 260        len = bitlen / 8;
 261
 262        if (!dout)
 263                return davinci_spi_read(slave, len, din, flags);
 264        else if (!din)
 265                return davinci_spi_write(slave, len, dout, flags);
 266#ifndef CONFIG_SPI_HALF_DUPLEX
 267        else
 268                return davinci_spi_read_write(slave, len, din, dout, flags);
 269#else
 270        printf("SPI full duplex transaction requested with "
 271               "CONFIG_SPI_HALF_DUPLEX defined.\n");
 272        flags |= SPI_XFER_END;
 273#endif
 274
 275out:
 276        if (flags & SPI_XFER_END) {
 277                u8 dummy = 0;
 278                davinci_spi_write(slave, 1, &dummy, flags);
 279        }
 280        return 0;
 281}
 282
 283int spi_cs_is_valid(unsigned int bus, unsigned int cs)
 284{
 285        return bus == 0 && cs == 0;
 286}
 287
 288void spi_cs_activate(struct spi_slave *slave)
 289{
 290        /* do nothing */
 291}
 292
 293void spi_cs_deactivate(struct spi_slave *slave)
 294{
 295        /* do nothing */
 296}
 297