diff options
author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-05-30 14:45:06 +0200 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-05-30 14:45:06 +0200 |
commit | a19b0dd62d7b8efc658fa1aa685ff5665878f3ee (patch) | |
tree | 1fadf0fb3da83203ba28f209ec99e1b33e03f4d5 /drivers/spi | |
parent | 60985bba58e7695dac1fddae8cdbb62d8cfd1254 (diff) | |
parent | a71d45d706a5b51c348160163b6c159632273fed (diff) | |
download | u-boot-a19b0dd62d7b8efc658fa1aa685ff5665878f3ee.zip u-boot-a19b0dd62d7b8efc658fa1aa685ff5665878f3ee.tar.gz u-boot-a19b0dd62d7b8efc658fa1aa685ff5665878f3ee.tar.bz2 |
Merge branch 'u-boot/master' into 'u-boot-arm/master'
Conflicts:
common/cmd_fpga.c
drivers/usb/host/ohci-at91.c
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/bfin_spi.c | 105 |
1 files changed, 3 insertions, 102 deletions
diff --git a/drivers/spi/bfin_spi.c b/drivers/spi/bfin_spi.c index ab2e8b9..a9a4d92 100644 --- a/drivers/spi/bfin_spi.c +++ b/drivers/spi/bfin_spi.c @@ -13,7 +13,6 @@ #include <spi.h> #include <asm/blackfin.h> -#include <asm/dma.h> #include <asm/gpio.h> #include <asm/portmux.h> #include <asm/mach-common/bits/spi.h> @@ -242,109 +241,15 @@ void spi_release_bus(struct spi_slave *slave) SSYNC(); } -#ifdef __ADSPBF54x__ -# define SPI_DMA_BASE DMA4_NEXT_DESC_PTR -#elif defined(__ADSPBF533__) || defined(__ADSPBF532__) || defined(__ADSPBF531__) || \ - defined(__ADSPBF538__) || defined(__ADSPBF539__) -# define SPI_DMA_BASE DMA5_NEXT_DESC_PTR -#elif defined(__ADSPBF561__) -# define SPI_DMA_BASE DMA2_4_NEXT_DESC_PTR -#elif defined(__ADSPBF537__) || defined(__ADSPBF536__) || defined(__ADSPBF534__) || \ - defined(__ADSPBF52x__) || defined(__ADSPBF51x__) -# define SPI_DMA_BASE DMA7_NEXT_DESC_PTR -# elif defined(__ADSPBF50x__) -# define SPI_DMA_BASE DMA6_NEXT_DESC_PTR -#else -# error "Please provide SPI DMA channel defines" -#endif -static volatile struct dma_register *dma = (void *)SPI_DMA_BASE; - #ifndef CONFIG_BFIN_SPI_IDLE_VAL # define CONFIG_BFIN_SPI_IDLE_VAL 0xff #endif -#ifdef CONFIG_BFIN_SPI_NO_DMA -# define SPI_DMA 0 -#else -# define SPI_DMA 1 -#endif - -static int spi_dma_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx, - uint bytes) -{ - int ret = -1; - u16 ndsize, spi_config, dma_config; - struct dmasg dmasg[2]; - const u8 *buf; - - if (tx) { - debug("%s: doing half duplex TX\n", __func__); - buf = tx; - spi_config = TDBR_DMA; - dma_config = 0; - } else { - debug("%s: doing half duplex RX\n", __func__); - buf = rx; - spi_config = RDBR_DMA; - dma_config = WNR; - } - - dmasg[0].start_addr = (unsigned long)buf; - dmasg[0].x_modify = 1; - dma_config |= WDSIZE_8 | DMAEN; - if (bytes <= 65536) { - blackfin_dcache_flush_invalidate_range(buf, buf + bytes); - ndsize = NDSIZE_5; - dmasg[0].cfg = NDSIZE_0 | dma_config | FLOW_STOP | DI_EN; - dmasg[0].x_count = bytes; - } else { - blackfin_dcache_flush_invalidate_range(buf, buf + 65536 - 1); - ndsize = NDSIZE_7; - dmasg[0].cfg = NDSIZE_5 | dma_config | FLOW_ARRAY | DMA2D; - dmasg[0].x_count = 0; /* 2^16 */ - dmasg[0].y_count = bytes >> 16; /* count / 2^16 */ - dmasg[0].y_modify = 1; - dmasg[1].start_addr = (unsigned long)(buf + (bytes & ~0xFFFF)); - dmasg[1].cfg = NDSIZE_0 | dma_config | FLOW_STOP | DI_EN; - dmasg[1].x_count = bytes & 0xFFFF; /* count % 2^16 */ - dmasg[1].x_modify = 1; - } - - dma->cfg = 0; - dma->irq_status = DMA_DONE | DMA_ERR; - dma->curr_desc_ptr = dmasg; - write_SPI_CTL(bss, (bss->ctl & ~TDBR_CORE)); - write_SPI_STAT(bss, -1); - SSYNC(); - - write_SPI_TDBR(bss, CONFIG_BFIN_SPI_IDLE_VAL); - dma->cfg = ndsize | FLOW_ARRAY | DMAEN; - write_SPI_CTL(bss, (bss->ctl & ~TDBR_CORE) | spi_config); - SSYNC(); - - /* - * We already invalidated the first 64k, - * now while we just wait invalidate the remaining part. - * Its not likely that the DMA is going to overtake - */ - if (bytes > 65536) - blackfin_dcache_flush_invalidate_range(buf + 65536, buf + bytes); - - while (!(dma->irq_status & DMA_DONE)) - if (ctrlc()) - goto done; - - dma->cfg = 0; - - ret = 0; - done: - write_SPI_CTL(bss, bss->ctl); - return ret; -} - static int spi_pio_xfer(struct bfin_spi_slave *bss, const u8 *tx, u8 *rx, uint bytes) { + /* discard invalid data and clear RXS */ + read_SPI_RDBR(bss); /* todo: take advantage of hardware fifos */ while (bytes--) { u8 value = (tx ? *tx++ : CONFIG_BFIN_SPI_IDLE_VAL); @@ -393,11 +298,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout, if (flags & SPI_XFER_BEGIN) spi_cs_activate(slave); - /* TX DMA doesn't work quite right */ - if (SPI_DMA && bytes > 6 && (!tx /*|| !rx*/)) - ret = spi_dma_xfer(bss, tx, rx, bytes); - else - ret = spi_pio_xfer(bss, tx, rx, bytes); + ret = spi_pio_xfer(bss, tx, rx, bytes); done: if (flags & SPI_XFER_END) |