X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fspi%2Fatmel_spi.c;h=d21c24eaf0a95537baae7f22e783bff8658aa816;hb=dc77270f960a8b3cc39a6349a9fad58cc6053d53;hp=293b7cab3e57021afcfeddcd2a5b007fbfba229a;hpb=8bacb219018a52e6f02a3cff6a7badf102ddfc44;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 293b7ca..d21c24e 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -20,9 +20,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include "atmel_spi.h" @@ -30,13 +30,6 @@ * The core SPI transfer engine just talks to a register bank to set up * DMA transfers; transfer queue progress is driven by IRQs. The clock * framework provides the base clock, subdivided for each spi_device. - * - * Newer controllers, marked with "new_1" flag, have: - * - CR.LASTXFER - * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) - * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) - * - SPI_CSRx.CSAAT - * - SPI_CSRx.SBCR allows faster clocking */ struct atmel_spi { spinlock_t lock; @@ -45,7 +38,6 @@ struct atmel_spi { int irq; struct clk *clk; struct platform_device *pdev; - unsigned new_1:1; struct spi_device *stay; u8 stopping; @@ -59,10 +51,33 @@ struct atmel_spi { dma_addr_t buffer_dma; }; +/* Controller-specific per-slave state */ +struct atmel_spi_device { + unsigned int npcs_pin; + u32 csr; +}; + #define BUFFER_SIZE PAGE_SIZE #define INVALID_DMA_ADDRESS 0xffffffff /* + * Version 2 of the SPI controller has + * - CR.LASTXFER + * - SPI_MR.DIV32 may become FDIV or must-be-zero (here: always zero) + * - SPI_SR.TXEMPTY, SPI_SR.NSSR (and corresponding irqs) + * - SPI_CSRx.CSAAT + * - SPI_CSRx.SBCR allows faster clocking + * + * We can determine the controller version by reading the VERSION + * register, but I haven't checked that it exists on all chips, and + * this is cheaper anyway. + */ +static bool atmel_spi_is_v2(void) +{ + return !cpu_is_at91rm9200(); +} + +/* * Earlier SPI controllers (e.g. on at91rm9200) have a design bug whereby * they assume that spi slave device state will not change on deselect, so * that automagic deselection is OK. ("NPCSx rises if no data is to be @@ -80,29 +95,58 @@ struct atmel_spi { * Master on Chip Select 0.") No workaround exists for that ... so for * nCS0 on that chip, we (a) don't use the GPIO, (b) can't support CS_HIGH, * and (c) will trigger that first erratum in some cases. + * + * TODO: Test if the atmel_spi_is_v2() branch below works on + * AT91RM9200 if we use some other register than CSR0. However, don't + * do this unconditionally since AP7000 has an errata where the BITS + * field in CSR0 overrides all other CSRs. */ static void cs_activate(struct atmel_spi *as, struct spi_device *spi) { - unsigned gpio = (unsigned) spi->controller_data; + struct atmel_spi_device *asd = spi->controller_state; unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; - mr = spi_readl(as, MR); - mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); + if (atmel_spi_is_v2()) { + /* + * Always use CSR0. This ensures that the clock + * switches to the correct idle polarity before we + * toggle the CS. + */ + spi_writel(as, CSR0, asd->csr); + spi_writel(as, MR, SPI_BF(PCS, 0x0e) | SPI_BIT(MODFDIS) + | SPI_BIT(MSTR)); + mr = spi_readl(as, MR); + gpio_set_value(asd->npcs_pin, active); + } else { + u32 cpol = (spi->mode & SPI_CPOL) ? SPI_BIT(CPOL) : 0; + int i; + u32 csr; + + /* Make sure clock polarity is correct */ + for (i = 0; i < spi->master->num_chipselect; i++) { + csr = spi_readl(as, CSR0 + 4 * i); + if ((csr ^ cpol) & SPI_BIT(CPOL)) + spi_writel(as, CSR0 + 4 * i, + csr ^ SPI_BIT(CPOL)); + } + + mr = spi_readl(as, MR); + mr = SPI_BFINS(PCS, ~(1 << spi->chip_select), mr); + if (spi->chip_select != 0) + gpio_set_value(asd->npcs_pin, active); + spi_writel(as, MR, mr); + } dev_dbg(&spi->dev, "activate %u%s, mr %08x\n", - gpio, active ? " (high)" : "", + asd->npcs_pin, active ? " (high)" : "", mr); - - if (!(cpu_is_at91rm9200() && spi->chip_select == 0)) - gpio_set_value(gpio, active); - spi_writel(as, MR, mr); } static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) { - unsigned gpio = (unsigned) spi->controller_data; + struct atmel_spi_device *asd = spi->controller_state; unsigned active = spi->mode & SPI_CS_HIGH; u32 mr; @@ -116,11 +160,11 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) } dev_dbg(&spi->dev, "DEactivate %u%s, mr %08x\n", - gpio, active ? " (low)" : "", + asd->npcs_pin, active ? " (low)" : "", mr); - if (!(cpu_is_at91rm9200() && spi->chip_select == 0)) - gpio_set_value(gpio, !active); + if (atmel_spi_is_v2() || spi->chip_select != 0) + gpio_set_value(asd->npcs_pin, !active); } static inline int atmel_spi_xfer_is_last(struct spi_message *msg, @@ -145,14 +189,14 @@ static void atmel_spi_next_xfer_data(struct spi_master *master, /* use scratch buffer only when rx or tx data is unspecified */ if (xfer->rx_buf) - *rx_dma = xfer->rx_dma + xfer->len - len; + *rx_dma = xfer->rx_dma + xfer->len - *plen; else { *rx_dma = as->buffer_dma; if (len > BUFFER_SIZE) len = BUFFER_SIZE; } if (xfer->tx_buf) - *tx_dma = xfer->tx_dma + xfer->len - len; + *tx_dma = xfer->tx_dma + xfer->len - *plen; else { *tx_dma = as->buffer_dma; if (len > BUFFER_SIZE) @@ -174,7 +218,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, { struct atmel_spi *as = spi_master_get_devdata(master); struct spi_transfer *xfer; - u32 len, remaining, total; + u32 len, remaining; + u32 ieval; dma_addr_t tx_dma, rx_dma; if (!as->current_transfer) @@ -187,6 +232,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, xfer = NULL; if (xfer) { + spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); + len = xfer->len; atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); remaining = xfer->len - len; @@ -224,6 +271,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, as->next_transfer = xfer; if (xfer) { + u32 total; + total = len; atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); as->next_remaining_bytes = total - len; @@ -240,9 +289,11 @@ static void atmel_spi_next_xfer(struct spi_master *master, " next xfer %p: len %u tx %p/%08x rx %p/%08x\n", xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, xfer->rx_buf, xfer->rx_dma); + ieval = SPI_BIT(ENDRX) | SPI_BIT(OVRES); } else { spi_writel(as, RNCR, 0); spi_writel(as, TNCR, 0); + ieval = SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) | SPI_BIT(OVRES); } /* REVISIT: We're waiting for ENDRX before we start the next @@ -255,7 +306,7 @@ static void atmel_spi_next_xfer(struct spi_master *master, * * It should be doable, though. Just not now... */ - spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES)); + spi_writel(as, IER, ieval); spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); } @@ -271,7 +322,7 @@ static void atmel_spi_next_message(struct spi_master *master) spi = msg->spi; dev_dbg(master->dev.parent, "start message %p for %s\n", - msg, spi->dev.bus_id); + msg, dev_name(&spi->dev)); /* select chip if it's not still active */ if (as->stay) { @@ -303,14 +354,14 @@ atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) xfer->tx_dma = dma_map_single(dev, (void *) xfer->tx_buf, xfer->len, DMA_TO_DEVICE); - if (dma_mapping_error(xfer->tx_dma)) + if (dma_mapping_error(dev, xfer->tx_dma)) return -ENOMEM; } if (xfer->rx_buf) { xfer->rx_dma = dma_map_single(dev, xfer->rx_buf, xfer->len, DMA_FROM_DEVICE); - if (dma_mapping_error(xfer->rx_dma)) { + if (dma_mapping_error(dev, xfer->rx_dma)) { if (xfer->tx_buf) dma_unmap_single(dev, xfer->tx_dma, xfer->len, @@ -386,7 +437,7 @@ atmel_spi_interrupt(int irq, void *dev_id) ret = IRQ_HANDLED; - spi_writel(as, IDR, (SPI_BIT(ENDTX) | SPI_BIT(ENDRX) + spi_writel(as, IDR, (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX) | SPI_BIT(OVRES))); /* @@ -408,7 +459,7 @@ atmel_spi_interrupt(int irq, void *dev_id) if (xfer->delay_usecs) udelay(xfer->delay_usecs); - dev_warn(master->dev.parent, "fifo overrun (%u/%u remaining)\n", + dev_warn(master->dev.parent, "overrun (%u/%u remaining)\n", spi_readl(as, TCR), spi_readl(as, RCR)); /* @@ -432,7 +483,7 @@ atmel_spi_interrupt(int irq, void *dev_id) spi_readl(as, SR); atmel_spi_msg_done(master, as, msg, -EIO, 0); - } else if (pending & SPI_BIT(ENDRX)) { + } else if (pending & (SPI_BIT(RXBUFF) | SPI_BIT(ENDRX))) { ret = IRQ_HANDLED; spi_writel(as, IDR, pending); @@ -479,15 +530,13 @@ atmel_spi_interrupt(int irq, void *dev_id) return ret; } -/* the spi->mode bits understood by this driver: */ -#define MODEBITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH) - static int atmel_spi_setup(struct spi_device *spi) { struct atmel_spi *as; + struct atmel_spi_device *asd; u32 scbr, csr; unsigned int bits = spi->bits_per_word; - unsigned long bus_hz, sck_hz; + unsigned long bus_hz; unsigned int npcs_pin; int ret; @@ -503,8 +552,6 @@ static int atmel_spi_setup(struct spi_device *spi) return -EINVAL; } - if (bits == 0) - bits = 8; if (bits < 8 || bits > 16) { dev_dbg(&spi->dev, "setup: invalid bits_per_word %u (8 to 16)\n", @@ -512,28 +559,30 @@ static int atmel_spi_setup(struct spi_device *spi) return -EINVAL; } - if (spi->mode & ~MODEBITS) { - dev_dbg(&spi->dev, "setup: unsupported mode bits %x\n", - spi->mode & ~MODEBITS); - return -EINVAL; - } - /* see notes above re chipselect */ - if (cpu_is_at91rm9200() + if (!atmel_spi_is_v2() && spi->chip_select == 0 && (spi->mode & SPI_CS_HIGH)) { dev_dbg(&spi->dev, "setup: can't be active-high\n"); return -EINVAL; } - /* speed zero convention is used by some upper layers */ + /* v1 chips start out at half the peripheral bus speed. */ bus_hz = clk_get_rate(as->clk); + if (!atmel_spi_is_v2()) + bus_hz /= 2; + if (spi->max_speed_hz) { - /* assume div32/fdiv/mbz == 0 */ - if (!as->new_1) - bus_hz /= 2; - scbr = ((bus_hz + spi->max_speed_hz - 1) - / spi->max_speed_hz); + /* + * Calculate the lowest divider that satisfies the + * constraint, assuming div32/fdiv/mbz == 0. + */ + scbr = DIV_ROUND_UP(bus_hz, spi->max_speed_hz); + + /* + * If the resulting divider doesn't fit into the + * register bitfield, we can't satisfy the constraint. + */ if (scbr >= (1 << SPI_SCBR_SIZE)) { dev_dbg(&spi->dev, "setup: %d Hz too slow, scbr %u; min %ld Hz\n", @@ -541,8 +590,8 @@ static int atmel_spi_setup(struct spi_device *spi) return -EINVAL; } } else + /* speed zero means "as slow as possible" */ scbr = 0xff; - sck_hz = bus_hz / scbr; csr = SPI_BF(SCBR, scbr) | SPI_BF(BITS, bits - 8); if (spi->mode & SPI_CPOL) @@ -561,11 +610,20 @@ static int atmel_spi_setup(struct spi_device *spi) /* chipselect must have been muxed as GPIO (e.g. in board setup) */ npcs_pin = (unsigned int)spi->controller_data; - if (!spi->controller_state) { - ret = gpio_request(npcs_pin, spi->dev.bus_id); - if (ret) + asd = spi->controller_state; + if (!asd) { + asd = kzalloc(sizeof(struct atmel_spi_device), GFP_KERNEL); + if (!asd) + return -ENOMEM; + + ret = gpio_request(npcs_pin, dev_name(&spi->dev)); + if (ret) { + kfree(asd); return ret; - spi->controller_state = (void *)npcs_pin; + } + + asd->npcs_pin = npcs_pin; + spi->controller_state = asd; gpio_direction_output(npcs_pin, !(spi->mode & SPI_CS_HIGH)); } else { unsigned long flags; @@ -577,11 +635,14 @@ static int atmel_spi_setup(struct spi_device *spi) spin_unlock_irqrestore(&as->lock, flags); } + asd->csr = csr; + dev_dbg(&spi->dev, "setup: %lu Hz bpw %u mode 0x%x -> csr%d %08x\n", - sck_hz, bits, spi->mode, spi->chip_select, csr); + bus_hz / scbr, bits, spi->mode, spi->chip_select, csr); - spi_writel(as, CSR0 + 4 * spi->chip_select, csr); + if (!atmel_spi_is_v2()) + spi_writel(as, CSR0 + 4 * spi->chip_select, csr); return 0; } @@ -596,17 +657,16 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) as = spi_master_get_devdata(spi->master); dev_dbg(controller, "new message %p submitted for %s\n", - msg, spi->dev.bus_id); + msg, dev_name(&spi->dev)); - if (unlikely(list_empty(&msg->transfers) - || !spi->max_speed_hz)) + if (unlikely(list_empty(&msg->transfers))) return -EINVAL; if (as->stopping) return -ESHUTDOWN; list_for_each_entry(xfer, &msg->transfers, transfer_list) { - if (!(xfer->tx_buf || xfer->rx_buf)) { + if (!(xfer->tx_buf || xfer->rx_buf) && xfer->len) { dev_dbg(&spi->dev, "missing rx or tx buf\n"); return -EINVAL; } @@ -656,10 +716,11 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) static void atmel_spi_cleanup(struct spi_device *spi) { struct atmel_spi *as = spi_master_get_devdata(spi->master); + struct atmel_spi_device *asd = spi->controller_state; unsigned gpio = (unsigned) spi->controller_data; unsigned long flags; - if (!spi->controller_state) + if (!asd) return; spin_lock_irqsave(&as->lock, flags); @@ -669,7 +730,9 @@ static void atmel_spi_cleanup(struct spi_device *spi) } spin_unlock_irqrestore(&as->lock, flags); + spi->controller_state = NULL; gpio_free(gpio); + kfree(asd); } /*-------------------------------------------------------------------------*/ @@ -701,6 +764,9 @@ static int __init atmel_spi_probe(struct platform_device *pdev) if (!master) goto out_free; + /* the spi->mode bits understood by this driver: */ + master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; + master->bus_num = pdev->id; master->num_chipselect = 4; master->setup = atmel_spi_setup; @@ -722,22 +788,21 @@ static int __init atmel_spi_probe(struct platform_device *pdev) spin_lock_init(&as->lock); INIT_LIST_HEAD(&as->queue); as->pdev = pdev; - as->regs = ioremap(regs->start, (regs->end - regs->start) + 1); + as->regs = ioremap(regs->start, resource_size(regs)); if (!as->regs) goto out_free_buffer; as->irq = irq; as->clk = clk; - if (!cpu_is_at91rm9200()) - as->new_1 = 1; ret = request_irq(irq, atmel_spi_interrupt, 0, - pdev->dev.bus_id, master); + dev_name(&pdev->dev), master); if (ret) goto out_unmap_regs; /* Initialize the hardware */ clk_enable(clk); spi_writel(as, CR, SPI_BIT(SWRST)); + spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_writel(as, MR, SPI_BIT(MSTR) | SPI_BIT(MODFDIS)); spi_writel(as, PTCR, SPI_BIT(RXTDIS) | SPI_BIT(TXTDIS)); spi_writel(as, CR, SPI_BIT(SPIEN)); @@ -754,6 +819,7 @@ static int __init atmel_spi_probe(struct platform_device *pdev) out_reset_hw: spi_writel(as, CR, SPI_BIT(SWRST)); + spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ clk_disable(clk); free_irq(irq, master); out_unmap_regs: @@ -777,6 +843,7 @@ static int __exit atmel_spi_remove(struct platform_device *pdev) spin_lock_irq(&as->lock); as->stopping = 1; spi_writel(as, CR, SPI_BIT(SWRST)); + spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ spi_readl(as, SR); spin_unlock_irq(&as->lock); @@ -853,3 +920,4 @@ module_exit(atmel_spi_exit); MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver"); MODULE_AUTHOR("Haavard Skinnemoen "); MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:atmel_spi");