X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fspi%2Fbfin_spi.c;h=71a31d0127fee425e428bf579159b09865c3274c;hb=0ebc0ec6200907588881b3c7347af74dbcf9cb65;hp=213e79281aca3ddb8f24841927c4a890a3181aaa;hpb=909e9bf3ae6195ac6d52f9e453fba2be8e7e947f;p=u-boot diff --git a/drivers/spi/bfin_spi.c b/drivers/spi/bfin_spi.c index 213e79281a..71a31d0127 100644 --- a/drivers/spi/bfin_spi.c +++ b/drivers/spi/bfin_spi.c @@ -3,7 +3,7 @@ * * Copyright (c) 2005-2010 Analog Devices Inc. * - * Licensed under the GPL-2 or later. + * SPDX-License-Identifier: GPL-2.0+ */ /*#define DEBUG*/ @@ -13,7 +13,7 @@ #include #include -#include +#include #include #include #include @@ -141,14 +141,12 @@ static const unsigned short cs_pins[][7] = { void spi_set_speed(struct spi_slave *slave, uint hz) { struct bfin_spi_slave *bss = to_bfin_spi_slave(slave); - ulong sclk; + ulong clk; u32 baud; - sclk = get_sclk(); - baud = sclk / (2 * hz); + clk = get_spi_clk(); /* baud should be rounded up */ - if (sclk % (2 * hz)) - baud += 1; + baud = DIV_ROUND_UP(clk, 2 * hz); if (baud < 2) baud = 2; else if (baud > (u16)-1) @@ -165,29 +163,28 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, if (!spi_cs_is_valid(bus, cs)) return NULL; - if (bus >= ARRAY_SIZE(pins) || pins[bus] == NULL) { - debug("%s: invalid bus %u\n", __func__, bus); - return NULL; - } switch (bus) { #ifdef SPI0_CTL - case 0: mmr_base = SPI0_CTL; break; + case 0: + mmr_base = SPI0_CTL; break; #endif #ifdef SPI1_CTL - case 1: mmr_base = SPI1_CTL; break; + case 1: + mmr_base = SPI1_CTL; break; #endif #ifdef SPI2_CTL - case 2: mmr_base = SPI2_CTL; break; + case 2: + mmr_base = SPI2_CTL; break; #endif - default: return NULL; + default: + debug("%s: invalid bus %u\n", __func__, bus); + return NULL; } - bss = malloc(sizeof(*bss)); + bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs); if (!bss) return NULL; - bss->slave.bus = bus; - bss->slave.cs = cs; bss->mmr_base = (void *)mmr_base; bss->ctl = SPE | MSTR | TDBR_CORE; if (mode & SPI_CPHA) bss->ctl |= CPHA; @@ -197,7 +194,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, spi_set_speed(&bss->slave, max_hz); debug("%s: bus:%i cs:%i mmr:%x ctl:%x baud:%i flg:%i\n", __func__, - bus, cs, mmr_base, bss->ctl, baud, bss->flg); + bus, cs, mmr_base, bss->ctl, bss->baud, bss->flg); return &bss->slave; } @@ -244,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); @@ -395,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)