work in progress: SPI controller w/DMA SAM9X5
Subsystems (7)
cover work in progress: SPI controller w/DMA SAM9X5
Nicolas,
I said that I had some work done on sam9g35-ek, here is the spi part, based on your and Jean-Christophe work.
You have to enable CONFIG_ARCH_AT91SAM9X5 to get it work.
The goal of this patchset is to share the work I've done, it's not ready for upstream, but it may save some time.
It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
Best Regards,
Richard.
Jean-Christophe PLAGNIOL-VILLARD (3):
of: add dma-mask binding
of_spi: add generic binding support to specify cs gpio spi/atmel: add DT support
Nicolas Ferre (6):
spi/atmel_spi: trivial: change some comments spi/atmel_spi: add physical base address spi/atmel_spi: call unmapping on transfers buffers spi/atmel_spi: status information passed through controller data spi/atmel_spi: add flag to controller data for lock operations spi/atmel_spi: add dmaengine support
Richard Genoud (14):
spi-atmel: update with dmaengine interface
spi-atmel: fix __init/__devinit sections mismatch
spi-atmel: Fix spi-atmel driver to adapt to slave_config changes AT91 DMA OF support
add at91sam9x5 Kconfig ARCH/SOC link
spi-atmel: add DMA OF support
[BUG] SPI: array out of bound => no CS
[BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes
sam9x5: declare SPI clocks
spi-atmel: add sam9x5 SPI in device tree
spi-atmel: add dma support in sam9x5 device tree spi-atmel OF: complete documentation
spi-atmel: complete DMA slave OF documentation sam9x5ek DTS: enable SPI dataflash
Documentation/devicetree/bindings/spi/spi-bus.txt | 6 + .../devicetree/bindings/spi/spi_atmel.txt | 46 ++ arch/arm/boot/dts/at91sam9x5.dtsi | 42 ++ arch/arm/boot/dts/at91sam9x5ek.dtsi | 10 + arch/arm/mach-at91/Kconfig | 4 + arch/arm/mach-at91/at91sam9x5.c | 3 + arch/arm/mach-at91/include/mach/at_hdmac.h | 1 + drivers/of/Kconfig | 4 + drivers/of/Makefile | 1 + drivers/of/of_atmel.c | 111 ++++ drivers/of/platform.c | 23 +- drivers/spi/Kconfig | 9 + drivers/spi/spi-atmel.c | 611 ++++++++++++++++++-- drivers/spi/spi.c | 55 ++- include/linux/of_atmel.h | 29 + include/linux/spi/spi.h | 3 + 16 files changed, 914 insertions(+), 44 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/spi_atmel.txt create mode 100644 drivers/of/of_atmel.c create mode 100644 include/linux/of_atmel.h
Signature · 1 line
1.7.2.5
PATCH 1/23 of: add dma-mask binding
From: Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
This will allow each device to specify its dma-mask for this we use the coherent_dma_mask as pointer. By default the dma-mask will be set to DMA_BIT_MASK(32).
The microblaze architecture hook is drop
--- drivers/of/platform.c | 23 ++++++++++++++++------- 1 files changed, 16 insertions(+), 7 deletions(-)
drivers/of/platform.c +16 -7
@@ -121,6 +121,21 @@ void of_device_make_bus_id(struct device *dev)dev_set_name (dev,"%s.%d" , node->name, magic -1 ); } +static void of_get_dma_mask (struct device *dev,struct device_node *np) +{ +const __be32 *prop; +int len; + + prop =of_get_property (np,"dma-mask" , &len); + + dev->dma_mask = &dev->coherent_dma_mask; + +if (!prop) + dev->coherent_dma_mask =DMA_BIT_MASK (32 ); +else + dev->coherent_dma_mask =of_read_number (prop, len /4 ); +} +/** * of_device_alloc - Allocate and initialize an of_device * @np: device node to assign to device
@@ -161,10 +176,8 @@ struct platform_device *of_device_alloc(struct device_node *np,WARN_ON (of_irq_to_resource_table (np, res, num_irq) != num_irq); } +of_get_dma_mask (&dev->dev, np); dev->dev.of_node =of_node_get (np); -#if defined(CONFIG_MICROBLAZE ) - dev->dev.dma_mask = &dev->archdata.dma_mask; -#endif dev->dev.parent = parent;if (bus_id)
@@ -201,10 +214,6 @@ struct platform_device *of_platform_device_create_pdata(if (!dev)return NULL ; -#if defined(CONFIG_MICROBLAZE ) - dev->archdata.dma_mask =0xffffffffUL ; -#endif - dev->dev.coherent_dma_mask =DMA_BIT_MASK (32 ); dev->dev.bus = &platform_bus_type; dev->dev.platform_data = platform_data;
Signature · 1 line
1.7.2.5
PATCH 2/23 of_spi: add generic binding support to specify cs gpio
In reply to Richard GenoudFrom: Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
This will allow to use gpio for chip select with no modification in the driver binding
When use the cs-gpios, the gpio number will be passed via the cs_gpio field and the number of chip select will automatically increased.
--- Documentation/devicetree/bindings/spi/spi-bus.txt | 6 ++ drivers/spi/spi.c | 55 +++++++++++++++++++- include/linux/spi/spi.h | 3 + 3 files changed, 61 insertions(+), 3 deletions(-)
Documentation/devicetree/bindings/spi/spi-bus.txt +6 -0
@@ -12,6 +12,7 @@ The SPI master node requires the following properties: - #size-cells - should be zero. - compatible - name of SPI bus controller following generic names recommended practice. +- cs-gpios - (optional) gpios chip select. No other properties are required in the SPI bus node. It is assumed that a driver for an SPI bus device will understand that it is an SPI bus. However, the binding does not attempt to define the specific method for
@@ -21,6 +22,8 @@ assumption that board specific platform code will be used to manage chip selects. Individual drivers can define additional properties to support describing the chip select layout. +If cs-gpios is used the number of chip select will automatically increased. + SPI slave nodes must be children of the SPI master node and can contain the following properties. - reg - (required) chip select address of device.
@@ -34,6 +37,9 @@ contain the following properties. - spi-cs-high - (optional) Empty property indicating device requires chip select active high +If a gpio chipselect is used for the SPI slave the gpio number will be passed +via the controller_data + SPI example for an MPC5200 SPI bus: spi at f00 { #address-cells = <1>;
drivers/spi/spi.c +52 -3
97 lines not on this page · raw message
include/linux/spi/spi.h +3 -0
@@ -90,6 +90,7 @@ struct spi_device {void *controller_state;void *controller_data;char modalias[SPI_NAME_SIZE ]; +int cs_gpio;/* chip select gpio */ /* * likely need more hooks for more protocol options affecting how
@@ -362,6 +363,8 @@ struct spi_master {int (*transfer_one_message)(struct spi_master *master,struct spi_message *mesg);int (*unprepare_transfer_hardware)(struct spi_master *master); +/* gpio chip select */ +int *cs_gpios; };static inline void *spi_master_get_devdata (struct spi_master *master)
Signature · 1 line
1.7.2.5
PATCH 3/23 spi/atmel_spi: trivial: change some comments
In reply to Richard GenoudFrom: Nicolas Ferre <[email protected]>
To be accurate with introduction of dmaengine enabled driver.
--- drivers/spi/spi-atmel.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/spi/spi-atmel.c +2 -1
@@ -201,6 +201,7 @@ struct atmel_spi {struct spi_transfer *next_transfer;unsigned long next_remaining_bytes; +/* scratch buffer */ void *buffer;dma_addr_t buffer_dma; };
@@ -364,7 +365,7 @@ static void atmel_spi_next_xfer_data(struct spi_master *master, }/* -* Submit next transfer for DMA. +* Submit next transfer for PDC. * lock is held, spi irq is blocked */ static void atmel_spi_next_xfer(struct spi_master *master,
Signature · 1 line
1.7.2.5
PATCH 4/23 spi/atmel_spi: add physical base address
In reply to Richard GenoudFrom: Nicolas Ferre <[email protected]>
Needed for future use with dmaengine enabled driver.
--- drivers/spi/spi-atmel.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/spi/spi-atmel.c +2 -0
@@ -188,6 +188,7 @@struct atmel_spi {spinlock_t lock; +resource_size_t phybase;void __iomem *regs;int irq;struct clk *clk;
@@ -962,6 +963,7 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev) as->regs =ioremap (regs->start,resource_size (regs));if (!as->regs) goto out_free_buffer; + as->phybase = regs->start; as->irq = irq; as->clk = clk;
Signature · 1 line
1.7.2.5
PATCH 5/23 spi/atmel_spi: call unmapping on transfers buffers
In reply to Richard GenoudFrom: Nicolas Ferre <[email protected]>
--- drivers/spi/spi-atmel.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
drivers/spi/spi-atmel.c +5 -3
@@ -1011,6 +1011,7 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)struct spi_master *master =platform_get_drvdata (pdev);struct atmel_spi *as =spi_master_get_devdata (master);struct spi_message *msg; +struct spi_transfer *xfer;/* reset the hardware and block queue progress */ spin_lock_irq (&as->lock);
@@ -1022,9 +1023,10 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)/* Terminate remaining queued transfers */ list_for_each_entry (msg, &as->queue, queue) { -/* REVISIT unmapping the dma is a NOP on ARM and AVR32 -* but we shouldn't depend on that... -*/ +list_for_each_entry (xfer, &msg->transfers, transfer_list) { +if (!msg->is_dma_mapped) +atmel_spi_dma_unmap_xfer (master, xfer); + } msg->status = -ESHUTDOWN ; msg->complete (msg->context); }
Signature · 1 line
1.7.2.5
PATCH 6/23 spi/atmel_spi: status information passed through controller data
In reply to Richard GenoudFrom: Nicolas Ferre <[email protected]>
The status of transfer is stored in controller data structure so that it can be used not only by atmel_spi_msg_done() function. This will be useful for upcoming dmaengine enabled driver.
--- drivers/spi/spi-atmel.c | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-)
drivers/spi/spi-atmel.c +8 -5
@@ -201,6 +201,7 @@ struct atmel_spi {unsigned long current_remaining_bytes;struct spi_transfer *next_transfer;unsigned long next_remaining_bytes; +int done_status;/* scratch buffer */ void *buffer;
@@ -545,15 +546,15 @@ static void atmel_spi_dma_unmap_xfer(struct spi_master *master,static void atmel_spi_msg_done (struct spi_master *master,struct atmel_spi *as, -struct spi_message *msg,int status,int stay) +struct spi_message *msg,int stay) { -if (!stay || status <0 ) +if (!stay || as->done_status <0 )cs_deactivate (as, msg->spi);else as->stay = msg->spi;list_del (&msg->queue); - msg->status = status; + msg->status = as->done_status; dev_dbg(master->dev.parent, "xfer complete: %u bytes transferred\n",
@@ -565,6 +566,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as, as->current_transfer =NULL ; as->next_transfer =NULL ; + as->done_status =0 ;/* continue if needed */ if (list_empty (&as->queue) || as->stopping)
@@ -642,7 +644,8 @@ atmel_spi_interrupt(int irq, void *dev_id)/* Clear any overrun happening while cleaning up */ spi_readl (as,SR ); -atmel_spi_msg_done (master, as, msg, -EIO ,0 ); + as->done_status = -EIO ; +atmel_spi_msg_done (master, as, msg,0 ); }else if (pending & (SPI_BIT (RXBUFF ) |SPI_BIT (ENDRX ))) { ret =IRQ_HANDLED ;
@@ -660,7 +663,7 @@ atmel_spi_interrupt(int irq, void *dev_id)if (atmel_spi_xfer_is_last (msg, xfer)) {/* report completed message */ -atmel_spi_msg_done (master, as, msg,0 , +atmel_spi_msg_done (master, as, msg, xfer->cs_change); }else {if (xfer->cs_change) {
Signature · 1 line
1.7.2.5
PATCH 7/23 spi/atmel_spi: add flag to controller data for lock operations
In reply to Richard GenoudFrom: Nicolas Ferre <[email protected]>
Will allow to drop the lock during DMA operations.
--- drivers/spi/spi-atmel.c | 31 +++++++++++++++++++------------ 1 files changed, 19 insertions(+), 12 deletions(-)
drivers/spi/spi-atmel.c +19 -12
@@ -187,6 +187,7 @@*/ struct atmel_spi {spinlock_t lock; +unsigned long flags;resource_size_t phybase;void __iomem *regs;
@@ -324,6 +325,16 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi)gpio_set_value (asd->npcs_pin, !active); } +static void atmel_spi_lock (struct atmel_spi *as) +{ +spin_lock_irqsave (&as->lock, as->flags); +} + +static void atmel_spi_unlock (struct atmel_spi *as) +{ +spin_unlock_irqrestore (&as->lock, as->flags); +} +static inline int atmel_spi_xfer_is_last (struct spi_message *msg,struct spi_transfer *xfer) {
@@ -560,9 +571,9 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,"xfer complete: %u bytes transferred\n" , msg->actual_length); -spin_unlock (&as->lock); +atmel_spi_unlock (as); msg->complete (msg->context); -spin_lock (&as->lock); +atmel_spi_lock (as); as->current_transfer =NULL ; as->next_transfer =NULL ;
@@ -789,13 +800,11 @@ static int atmel_spi_setup(struct spi_device *spi) spi->controller_state = asd;gpio_direction_output (npcs_pin, !(spi->mode &SPI_CS_HIGH )); }else { -unsigned long flags; - -spin_lock_irqsave (&as->lock, flags); +atmel_spi_lock (as);if (as->stay == spi) as->stay =NULL ;cs_deactivate (as, spi); -spin_unlock_irqrestore (&as->lock, flags); +atmel_spi_unlock (as); } asd->csr = csr;
@@ -814,7 +823,6 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) {struct atmel_spi *as;struct spi_transfer *xfer; -unsigned long flags;struct device *controller = spi->master->dev.parent;u8 bits;struct atmel_spi_device *asd;
@@ -879,11 +887,11 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg) msg->status = -EINPROGRESS ; msg->actual_length =0 ; -spin_lock_irqsave (&as->lock, flags); +atmel_spi_lock (as);list_add_tail (&msg->queue, &as->queue);if (!as->current_transfer)atmel_spi_next_message (spi->master); -spin_unlock_irqrestore (&as->lock, flags); +atmel_spi_unlock (as);return 0 ; }
@@ -893,17 +901,16 @@ 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 (!asd)return ; -spin_lock_irqsave (&as->lock, flags); +atmel_spi_lock (as);if (as->stay == spi) { as->stay =NULL ;cs_deactivate (as, spi); } -spin_unlock_irqrestore (&as->lock, flags); +atmel_spi_unlock (as); spi->controller_state =NULL ;gpio_free (gpio);
Signature · 1 line
1.7.2.5
PATCH 8/23 spi/atmel: add DT support
In reply to Richard GenoudFrom: Jean-Christophe PLAGNIOL-VILLARD <[email protected]>
The atmel_spi use only gpio for chip select.
--- .../devicetree/bindings/spi/spi_atmel.txt | 6 +++++ drivers/spi/spi-atmel.c | 21 ++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/spi_atmel.txt
Documentation/devicetree/bindings/spi/spi_atmel.txt new file +6 -0
@@ -0,0 +1,6 @@ +Atmel SPI device + +Required properties: +- compatible : should be "atmel,at91rm9200-spi". +- reg: Address and length of the register set for the device +- interrupts: Should contain macb interrupt
drivers/spi/spi-atmel.c +17 -4
@@ -19,6 +19,7 @@#include <linux/interrupt.h> #include <linux/spi/spi.h> #include <linux/slab.h> +#include <linux/of.h> #include <asm/io.h> #include <mach/board.h>
@@ -711,7 +712,7 @@ static int atmel_spi_setup(struct spi_device *spi)u32 scbr, csr;unsigned int bits = spi->bits_per_word;unsigned long bus_hz; -unsigned int npcs_pin; +int npcs_pin;int ret; as =spi_master_get_devdata (spi->master);
@@ -783,7 +784,9 @@ static int atmel_spi_setup(struct spi_device *spi) csr |=SPI_BF (DLYBCT ,0 );/* chipselect must have been muxed as GPIO (e.g. in board setup) */ - npcs_pin = (unsigned int )spi->controller_data; +if (!gpio_is_valid (spi->cs_gpio)) + spi->cs_gpio = (int )spi->controller_data; + npcs_pin = spi->cs_gpio; asd = spi->controller_state;if (!asd) { asd =kzalloc (sizeof (struct atmel_spi_device ),GFP_KERNEL );
@@ -900,7 +903,7 @@ 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 gpio = spi->cs_gpio;if (!asd)return ;
@@ -950,7 +953,8 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev) master->mode_bits =SPI_CPOL |SPI_CPHA |SPI_CS_HIGH ; master->bus_num = pdev->id; - master->num_chipselect =4 ; + master->dev.of_node = pdev->dev.of_node; + master->num_chipselect = master->dev.of_node ?0 :4 ; master->setup = atmel_spi_setup; master->transfer = atmel_spi_transfer; master->cleanup = atmel_spi_cleanup;
@@ -1079,11 +1083,20 @@ static int atmel_spi_resume(struct platform_device *pdev)#define atmel_spi_resume NULL#endif +#if defined(CONFIG_OF ) +static const struct of_device_id atmel_spi_dt_ids[] = { + { .compatible ="atmel,at91rm9200-spi" }, + {/* sentinel */ } +}; + +MODULE_DEVICE_TABLE (of, atmel_spi_dt_ids); +#endif static struct platform_driver atmel_spi_driver = { .driver = { .name ="atmel_spi" , .owner =THIS_MODULE , + .of_match_table =of_match_ptr (atmel_spi_dt_ids), }, .suspend = atmel_spi_suspend, .resume = atmel_spi_resume,
Signature · 1 line
1.7.2.5
PATCH 9/23 spi/atmel_spi: add dmaengine support
In reply to Richard GenoudFrom: Nicolas Ferre <[email protected]>
--- drivers/spi/Kconfig | 9 + drivers/spi/spi-atmel.c | 483 ++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 482 insertions(+), 10 deletions(-)
drivers/spi/Kconfig +9 -0
@@ -74,6 +74,15 @@ config SPI_ATMEL This selects a driver for the Atmel SPI Controller, present on many AT32 (AVR32) and AT91 (ARM) chips. +config SPI_ATMEL_DMA + bool "Atmel SPI DMA support" + depends on SPI_ATMEL && (ARCH_AT91SAM9G45 || ARCH_AT91SAM9X5) && DMA_ENGINE && EXPERIMENTAL + default y + help + Say Y here if you want the Atmel SPI driver to use the DMA engine. Data transfers + will be handled by the DMA controller: it will increase throughput and reduce + CPU utilization. + config SPI_BFIN5XX tristate "SPI controller driver for ADI Blackfin5xx" depends on BLACKFIN
drivers/spi/spi-atmel.c +473 -10
599 lines not on this page · raw message
Signature · 1 line
1.7.2.5
PATCH 10/23 spi-atmel: update with dmaengine interface
In reply to Richard Genoudcommit 185ecb5f4fd43911c35956d4cc7d94a1da30417f changed dmaengine interface.
=> we have to update spi-atmel accordingly
--- drivers/spi/spi-atmel.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-)
drivers/spi/spi-atmel.c +4 -2
@@ -542,7 +542,8 @@ static int atmel_spi_next_xfer_dma(struct spi_master *master, &as->dma.sgrx,1 ,DMA_FROM_DEVICE , - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +DMA_PREP_INTERRUPT |DMA_CTRL_ACK , + NULL);if (!rxdesc) goto err_dma;
@@ -550,7 +551,8 @@ static int atmel_spi_next_xfer_dma(struct spi_master *master, &as->dma.sgtx,1 ,DMA_TO_DEVICE , - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); +DMA_PREP_INTERRUPT |DMA_CTRL_ACK , + NULL);if (!txdesc) goto err_dma;
Signature · 1 line
1.7.2.5
PATCH 11/23 spi-atmel: fix __init/__devinit sections mismatch
In reply to Richard Genoud--- drivers/spi/spi-atmel.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/spi/spi-atmel.c +3 -3
@@ -383,7 +383,7 @@ static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) }#if defined(CONFIG_SPI_ATMEL_DMA ) -static bool __init filter (struct dma_chan *chan,void *slave) +static bool filter (struct dma_chan *chan,void *slave) {struct at_dma_slave *sl = slave;
@@ -395,7 +395,7 @@ static bool __init filter(struct dma_chan *chan, void *slave) } } -static int __init atmel_spi_configure_dma (struct spi_master *master) +static int __devinit atmel_spi_configure_dma (struct spi_master *master) {struct atmel_spi *as =spi_master_get_devdata (master);struct device *controller = master->dev.parent;
@@ -628,7 +628,7 @@ static void atmel_spi_disable_dma_irq(struct atmel_spi *as)spi_writel (as,PTCR ,SPI_BIT (RXTDIS ) |SPI_BIT (TXTDIS )); } -static int __init atmel_spi_configure_dma (struct spi_master *master) +static int __devinit atmel_spi_configure_dma (struct spi_master *master) {struct atmel_spi *as =spi_master_get_devdata (master);
Signature · 1 line
1.7.2.5
PATCH 12/23 spi-atmel: Fix spi-atmel driver to adapt to slave_config changes
In reply to Richard GenoudThis is the following of the patch e2b35f3dbfc080f15b72834d08f04f0269dbe9be
--- drivers/spi/spi-atmel.c | 45 ++++++++++++++++++++++++++++++++++++--------- 1 files changed, 36 insertions(+), 9 deletions(-)
drivers/spi/spi-atmel.c +36 -9
@@ -399,17 +399,24 @@ static int __devinit atmel_spi_configure_dma(struct spi_master *master) {struct atmel_spi *as =spi_master_get_devdata (master);struct device *controller = master->dev.parent; +struct dma_slave_config slave_config;struct at_dma_slave *sdata; +int err; sdata = controller->platform_data; +memset (&slave_config,0 ,sizeof (slave_config)); + slave_config.dst_addr = (dma_addr_t )as->phybase +SPI_TDR ; + slave_config.src_addr = (dma_addr_t )as->phybase +SPI_RDR ; + slave_config.dst_addr_width =DMA_SLAVE_BUSWIDTH_1_BYTE ; + slave_config.src_addr_width =DMA_SLAVE_BUSWIDTH_1_BYTE ; + slave_config.src_maxburst =1 ; + slave_config.dst_maxburst =1 ; + slave_config.device_fc = false; +if (sdata && sdata->dma_dev) {dma_cap_mask_t mask; -/* setup DMA addresses */ - sdata->rx_reg = (dma_addr_t )as->phybase +SPI_RDR ; - sdata->tx_reg = (dma_addr_t )as->phybase +SPI_TDR ; -/* Try to grab two DMA channels */ dma_cap_zero (mask);dma_cap_set (DMA_SLAVE , mask);
@@ -417,14 +424,28 @@ static int __devinit atmel_spi_configure_dma(struct spi_master *master)if (as->dma.chan_tx) as->dma.chan_rx =dma_request_channel (mask, filter, sdata); } +if (!as->dma.chan_rx || !as->dma.chan_tx) { -if (as->dma.chan_rx) -dma_release_channel (as->dma.chan_rx); -if (as->dma.chan_tx) -dma_release_channel (as->dma.chan_tx);dev_err (&as->pdev->dev,"DMA channel not available, " "unable to use SPI\n" ); -return -EBUSY ; + err = -EBUSY ; + goto error; + } + + slave_config.direction =DMA_TO_DEVICE ; +if (dmaengine_slave_config (as->dma.chan_tx, &slave_config)) { +dev_err (&as->pdev->dev, +"failed to configure tx dma channel\n" ); + err = -EINVAL ; + goto error; + } + + slave_config.direction =DMA_FROM_DEVICE ; +if (dmaengine_slave_config (as->dma.chan_rx, &slave_config)) { +dev_err (&as->pdev->dev, +"failed to configure rx dma channel\n" ); + err = -EINVAL ; + goto error; } dev_info(&as->pdev->dev, "Using %s (tx) and "
@@ -433,6 +454,12 @@ static int __devinit atmel_spi_configure_dma(struct spi_master *master) dma_chan_name(as->dma.chan_rx));return 0 ; +error: +if (as->dma.chan_rx) +dma_release_channel (as->dma.chan_rx); +if (as->dma.chan_tx) +dma_release_channel (as->dma.chan_tx); +return err; }static void atmel_spi_stop_dma (struct atmel_spi *as)
Signature · 1 line
1.7.2.5
PATCH 13/23 AT91 DMA OF support
In reply to Richard Genoud--- arch/arm/mach-at91/include/mach/at_hdmac.h | 1 + drivers/of/Kconfig | 4 + drivers/of/Makefile | 1 + drivers/of/of_atmel.c | 112 ++++++++++++++++++++++++++++ include/linux/of_atmel.h | 29 +++++++ 5 files changed, 147 insertions(+), 0 deletions(-) create mode 100644 drivers/of/of_atmel.c create mode 100644 include/linux/of_atmel.h
arch/arm/mach-at91/include/mach/at_hdmac.h +1 -0
@@ -52,6 +52,7 @@ struct at_dma_slave {#define ATC_LOCK_IF_L_CHUNK (0x0 << 22)#define ATC_LOCK_IF_L_BUFFER (0x1 << 22)#define ATC_AHB_PROT_MASK (0x7 << 24)/* AHB Protection */ +#define ATC_AHB_PROT (h) (((h) << 24) && ATC_AHB_PROT_MASK)#define ATC_FIFOCFG_MASK (0x3 << 28)/* FIFO Request Configuration */ #define ATC_FIFOCFG_LARGESTBURST (0x0 << 28)#define ATC_FIFOCFG_HALFFIFO (0x1 << 28)
drivers/of/Kconfig +4 -0
@@ -83,4 +83,8 @@ config OF_MTD depends on MTD def_bool y +config OF_ATMEL + depends on AT_HDMAC + def_bool y + endmenu # OF
drivers/of/Makefile +1 -0
@@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o obj-$(CONFIG_OF_MTD) += of_mtd.o +obj-$(CONFIG_OF_ATMEL) += of_atmel.o
drivers/of/of_atmel.c new file +112 -0
112 lines not on this page · raw message
include/linux/of_atmel.h new file +29 -0
@@ -0,0 +1,29 @@ +#ifndef _LINUX_OF_ATMEL_H +#define _LINUX_OF_ATMEL_H +/* +* Copyright (C) 2012 Richard Genoud, Paratronic S.A. +* <[email protected]> +* +* Atmel specifics OF helpers +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ +#include <linux/of.h> +#include <linux/device.h> +#include <mach/at_hdmac.h> + +#ifdef CONFIG_OF_ATMEL +extern struct at_dma_slave *of_create_at_dma_slave (struct device_node *np, +struct bus_type *bus); +#else +static struct at_dma_slave *of_create_at_dma_slave (struct device_node *np, +struct bus_type *bus) +{ +return NULL ; +} +#endif /* CONFIG_OF_ATMEL */ + +#endif /* _LINUX_OF_ATMEL_H */
Signature · 1 line
1.7.2.5
PATCH 13/23 AT91 DMA OF support
Hi Richard,
I am not sure that this one will go further: there is an initiative to build a pretty generic DMA OF support... It takes time but it is progressing...
Anyway, there may have some bits to integrate in at_hdmac.c driver: I will have a closer look later.
Thanks,
On 08/14/2012 03:49 PM, Richard Genoud :
Quoted 199 lines
Signed-off-by Richard Genoud <[email protected]>--- arch/arm/mach-at91/include/mach/at_hdmac.h | 1 + drivers/of/Kconfig | 4 + drivers/of/Makefile | 1 + drivers/of/of_atmel.c | 112 ++++++++++++++++++++++++++++ include/linux/of_atmel.h | 29 +++++++ 5 files changed, 147 insertions(+), 0 deletions(-) create mode 100644 drivers/of/of_atmel.c create mode 100644 include/linux/of_atmel.harch/arm/mach-at91/include/mach/at_hdmac.h +1
-0@@ -52,6 +52,7 @@ struct at_dma_slave {#define ATC_LOCK_IF_L_CHUNK (0x0 << 22)#define ATC_LOCK_IF_L_BUFFER (0x1 << 22)#define ATC_AHB_PROT_MASK (0x7 << 24)/* AHB Protection */ +#define ATC_AHB_PROT (h) (((h) << 24) && ATC_AHB_PROT_MASK)#define ATC_FIFOCFG_MASK (0x3 << 28)/* FIFO Request Configuration */ #define ATC_FIFOCFG_LARGESTBURST (0x0 << 28)#define ATC_FIFOCFG_HALFFIFO (0x1 << 28)drivers/of/Kconfig +4
-0@@ -83,4 +83,8 @@ config OF_MTD depends on MTD def_bool y +config OF_ATMEL + depends on AT_HDMAC + def_bool y + endmenu # OFdrivers/of/Makefile +1
-0@@ -11,3 +11,4 @@ obj-$(CONFIG_OF_MDIO) += of_mdio.o obj-$(CONFIG_OF_PCI) += of_pci.o obj-$(CONFIG_OF_PCI_IRQ) += of_pci_irq.o obj-$(CONFIG_OF_MTD) += of_mtd.o +obj-$(CONFIG_OF_ATMEL) += of_atmel.odrivers/of/of_atmel.c new file +112
-0@@ -0,0 +1,112 @@ +/* +* Copyright (C) 2012 Richard Genoud, Paratronic S.A. +* <[email protected]> +* +* Atmel specifics OF helpers +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ +#include <linux/kernel.h> +#include <linux/export.h> +#include <linux/device.h> +#include <linux/slab.h> +#include <linux/printk.h> +#include <linux/byteorder/generic.h> +#include <mach/at_hdmac.h> +#include <linux/of.h> + +static int of_dev_node_match (struct device *dev,void *data) +{ +return dev->of_node == data; +} + +/** +* of_create_at_dma_slave - Alloc and initialize the struct at_dma_slave +* @np: pointer to node to create the struct for +* @bus: pointer to the bus type of the DMA device. +* +* Returns pointer to created DMA slave structure, or NULL in case of error. +*/ +struct at_dma_slave *of_create_at_dma_slave (struct device_node *np, +struct bus_type *bus) +{ +struct at_dma_slave *atslave; +struct device_node *n; +struct property *prop; +const __be32 *dma_list; +phandle phandle; +int size; +int err =-1 ; +u32 val; + + atslave =kzalloc (sizeof (struct at_dma_slave ),GFP_KERNEL ); +if (unlikely (!atslave)) { +pr_err ("cannot allocate memory\n" ); + goto error; + } + + atslave->cfg |=of_property_read_bool (np,"atc_src_rep" ) ?ATC_SRC_REP :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_dst_rep" ) ?ATC_DST_REP :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_src_h2sel_hw" ) ?ATC_SRC_H2SEL_HW :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_dst_h2sel_hw" ) ?ATC_DST_H2SEL_HW :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_sod" ) ?ATC_SOD :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_lock_if" ) ?ATC_LOCK_IF :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_lock_b" ) ?ATC_LOCK_B :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_lock_if_l" ) ?ATC_LOCK_IF_L :0 ; + atslave->cfg |=of_property_read_bool (np,"atc_lock_if_l_buffer" ) ?ATC_LOCK_IF_L_BUFFER :0 ; +if (of_property_read_bool (np,"atc_fifocfg_halffifo" )) + atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK ) |ATC_FIFOCFG_HALFFIFO ; +if (of_property_read_bool (np,"atc_fifocfg_enoughspace" )) + atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK ) |ATC_FIFOCFG_ENOUGHSPACE ; +if (of_property_read_bool (np,"atc_fifocfg_largestburst" )) + atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK ) |ATC_FIFOCFG_LARGESTBURST ; +if (!of_property_read_u32 (np,"atc_ahb_prot" , &val)) + atslave->cfg |=ATC_AHB_PROT (val); +if (!of_property_read_u32 (np,"atc_src_per" , &val)) + atslave->cfg |=ATC_SRC_PER (val); +if (!of_property_read_u32 (np,"atc_dst_per" , &val)) + atslave->cfg |=ATC_DST_PER (val); + +/* we need to associate the wanted dma struct device to +* atslave->dma_dev. This is needed when searching for +* a free dma channel +*/ + prop =of_find_property (np,"dma" , &size); +if (!prop) { +pr_err ("can't find the dma child node\n" ); + goto error; + } + dma_list = prop->value; + size /=sizeof (*dma_list); +if (size !=1 ) { +pr_err ("only one dma handle is supported\n" ); + goto error; + } + + phandle =be32_to_cpup (dma_list); + n =of_find_node_by_phandle (phandle); +if (!n) { +pr_err ("unable to find dma device: invalid phandle %s\n" , + prop->name); + goto error; + } + + atslave->dma_dev =bus_find_device (bus,NULL , n, of_dev_node_match); +if (!atslave->dma_dev) { +pr_err ("can't find struct device for DMA %s\n" , prop->name); + goto error; + } + +pr_debug ("DMA cfg register=0x%x DMA device path=%s\n" , + atslave->cfg, prop->name); + err =0 ; +error: +if (err) +kfree (atslave); +return atslave; +} +EXPORT_SYMBOL_GPL (of_create_at_dma_slave); +include/linux/of_atmel.h new file +29
-0@@ -0,0 +1,29 @@ +#ifndef _LINUX_OF_ATMEL_H +#define _LINUX_OF_ATMEL_H +/* +* Copyright (C) 2012 Richard Genoud, Paratronic S.A. +* <[email protected]> +* +* Atmel specifics OF helpers +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +*/ +#include <linux/of.h> +#include <linux/device.h> +#include <mach/at_hdmac.h> + +#ifdef CONFIG_OF_ATMEL +extern struct at_dma_slave *of_create_at_dma_slave (struct device_node *np, +struct bus_type *bus); +#else +static struct at_dma_slave *of_create_at_dma_slave (struct device_node *np, +struct bus_type *bus) +{ +return NULL ; +} +#endif /* CONFIG_OF_ATMEL */ + +#endif /* _LINUX_OF_ATMEL_H */
Signature · 1 line
Nicolas Ferre
PATCH 14/23 add at91sam9x5 Kconfig ARCH/SOC link
In reply to Richard Genoud--- arch/arm/mach-at91/Kconfig | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
arch/arm/mach-at91/Kconfig +4 -0
@@ -141,6 +141,10 @@ config ARCH_AT91SAM9G45 bool "AT91SAM9G45" select SOC_AT91SAM9G45 +config ARCH_AT91SAM9X5 + bool "AT91SAM9x5" + select SOC_AT91SAM9X5 + config ARCH_AT91X40 bool "AT91x40" depends on !MMU
Signature · 1 line
1.7.2.5
PATCH 15/23 spi-atmel: add DMA OF support
In reply to Richard Genoud--- drivers/of/of_atmel.c | 1 - drivers/spi/spi-atmel.c | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletions(-)
drivers/of/of_atmel.c +0 -1
@@ -55,7 +55,6 @@ struct at_dma_slave *of_create_at_dma_slave(struct device_node *np, atslave->cfg |=of_property_read_bool (np,"atc_sod" ) ?ATC_SOD :0 ; atslave->cfg |=of_property_read_bool (np,"atc_lock_if" ) ?ATC_LOCK_IF :0 ; atslave->cfg |=of_property_read_bool (np,"atc_lock_b" ) ?ATC_LOCK_B :0 ; - atslave->cfg |=of_property_read_bool (np,"atc_lock_if_l" ) ?ATC_LOCK_IF_L :0 ; atslave->cfg |=of_property_read_bool (np,"atc_lock_if_l_buffer" ) ?ATC_LOCK_IF_L_BUFFER :0 ;if (of_property_read_bool (np,"atc_fifocfg_halffifo" )) atslave->cfg = (atslave->cfg & ~ATC_FIFOCFG_MASK ) |ATC_FIFOCFG_HALFFIFO ;
drivers/spi/spi-atmel.c +22 -0
@@ -21,6 +21,7 @@#include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/of.h> +#include <linux/of_atmel.h> #include <asm/io.h> #include <mach/board.h>
@@ -1411,6 +1412,8 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)int ret;struct spi_master *master;struct atmel_spi *as; +struct bus_type *bus = pdev->dev.bus; +struct device_node *of = pdev->dev.of_node; regs =platform_get_resource (pdev,IORESOURCE_MEM ,0 );if (!regs)
@@ -1430,6 +1433,17 @@ static int __devinit atmel_spi_probe(struct platform_device *pdev)if (!master) goto out_free; + +/* populate platform_data from device tree */ +if (of) { + pdev->dev.platform_data =of_create_at_dma_slave (of, bus); +if (!pdev->dev.platform_data) { +dev_err (&pdev->dev,"could not get DMA\n" ); + ret = -EINVAL ; + goto out_free; + } + } +/* the spi->mode bits understood by this driver: */ master->mode_bits =SPI_CPOL |SPI_CPHA |SPI_CS_HIGH ;
@@ -1504,6 +1518,10 @@ out_free_buffer:dma_free_coherent (&pdev->dev,BUFFER_SIZE , as->buffer, as->buffer_dma); out_free: +if (of) { +kfree ((struct at_dma_slave *)(pdev->dev.platform_data)); + pdev->dev.platform_data =NULL ; + }clk_put (clk);spi_master_put (master);return ret;
@@ -1546,6 +1564,10 @@ static int __devexit atmel_spi_remove(struct platform_device *pdev)iounmap (as->regs);spi_unregister_master (master); +if (pdev->dev.of_node) { +kfree ((struct at_dma_slave *)(pdev->dev.platform_data)); + pdev->dev.platform_data =NULL ; + }return 0 ; }
Signature · 1 line
1.7.2.5
PATCH 16/23 SPI: array out of bound => no CS
In reply to Richard Genoud--- drivers/spi/spi.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/spi/spi.c +1 -1
@@ -976,8 +976,8 @@ static int of_spi_register_master(struct spi_master *master)return -ENOMEM ;memset (cs, -EINVAL , master->num_chipselect); - master->num_chipselect += nb; cs += master->num_chipselect; + master->num_chipselect += nb;for (i =0 ; i < nb; i++) cs[i] =of_get_named_gpio (np,"cs-gpios" , i);
Signature · 1 line
1.7.2.5
PATCH 17/23 atmel-spi && DMA: OOPS if buffer > 4400 bytes
In reply to Richard Genoudthis is just a quick and suboptimal workaround
--- drivers/spi/spi-atmel.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
drivers/spi/spi-atmel.c +2 -1
@@ -638,7 +638,8 @@ static void atmel_spi_next_xfer(struct spi_master *master, as->current_transfer = xfer; -if (atmel_spi_use_dma (xfer)) { +/* quick (and *really* not optimal) workaround for DMA BUG */ +if (atmel_spi_use_dma (xfer) && (xfer->len <BUFFER_SIZE )) {if (!atmel_spi_next_xfer_dma (master, xfer))return ;else
Signature · 1 line
1.7.2.5
PATCH 18/23 sam9x5: declare SPI clocks
In reply to Richard Genoud--- arch/arm/mach-at91/at91sam9x5.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
arch/arm/mach-at91/at91sam9x5.c +3 -0
@@ -16,6 +16,7 @@#include <mach/at91_pmc.h> #include <mach/cpu.h> #include <mach/board.h> +#include <mach/gpio.h> #include "soc.h" #include "generic.h"
@@ -231,6 +232,8 @@ static struct clk_lookup periph_clocks_lookups[] = {CLKDEV_CON_DEV_ID ("t0_clk" ,"f800c000.timer" , &tcb0_clk),CLKDEV_CON_DEV_ID ("dma_clk" ,"ffffec00.dma-controller" , &dma0_clk),CLKDEV_CON_DEV_ID ("dma_clk" ,"ffffee00.dma-controller" , &dma1_clk), +CLKDEV_CON_DEV_ID ("spi_clk" ,"f0000000.spi" , &spi0_clk), +CLKDEV_CON_DEV_ID ("spi_clk" ,"f0004000.spi" , &spi1_clk),CLKDEV_CON_ID ("pioA" , &pioAB_clk),CLKDEV_CON_ID ("pioB" , &pioAB_clk), CLKDEV_CON_ID("pioC", &pioCD_clk),
Signature · 1 line
1.7.2.5
PATCH 19/23 spi-atmel: add sam9x5 SPI in device tree
In reply to Richard Genoud--- arch/arm/boot/dts/at91sam9x5.dtsi | 30 ++++++++++++++++++++++++++++++ 1 files changed, 30 insertions(+), 0 deletions(-)
arch/arm/boot/dts/at91sam9x5.dtsi +30 -0
@@ -344,6 +344,36 @@ trigger-value = <0x6>; }; }; + + spi0: spi at f0000000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91rm9200-spi"; + reg = <0xf0000000 0x100>; + interrupts = <13 4 3>; + cs-gpios = <&pioA 14 0 + &pioA 7 0 /* conflicts with TXD2 */ + &pioA 1 0 /* conflicts with RXD0 */ + &pioB 3 0 /* conflicts with ERXDV */ + >; + dma-mask = <0xffffffff>; + status = "disabled"; + }; + + spi1: spi at f0004000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91rm9200-spi"; + reg = <0xf0004000 0x100>; + interrupts = <14 4 3>; + cs-gpios = <&pioA 8 0 /* conflitcs with RXD2 */ + &pioA 0 0 /* conflitcs with TXD0 */ + &pioA 31 0 /* conflitcs with TWCK0 */ + &pioA 30 0 /* conflitcs with TWD0 */ + >; + dma-mask = <0xffffffff>; + status = "disabled"; + }; }; nand0: nand at 40000000 {
Signature · 1 line
1.7.2.5
PATCH 20/23 spi-atmel: add dma support in sam9x5 device tree
In reply to Richard Genoud--- arch/arm/boot/dts/at91sam9x5.dtsi | 12 ++++++++++++ 1 files changed, 12 insertions(+), 0 deletions(-)
arch/arm/boot/dts/at91sam9x5.dtsi +12 -0
@@ -357,6 +357,12 @@ &pioB 3 0 /* conflicts with ERXDV */ >; dma-mask = <0xffffffff>; + dma = <&dma0>; + atc_src_per = <2>; /* AT_DMA_ID_SPI0_RX */ + atc_dst_per = <1>; /* AT_DMA_ID_SPI0_TX */ + atc_fifocfg_halffifo; + atc_src_h2sel_hw; + atc_dst_h2sel_hw; status = "disabled"; };
@@ -372,6 +378,12 @@ &pioA 30 0 /* conflitcs with TWD0 */ >; dma-mask = <0xffffffff>; + dma = <&dma0>; + atc_src_per = <4>; /* AT_DMA_ID_SPI1_RX */ + atc_dst_per = <3>; /* AT_DMA_ID_SPI1_TX */ + atc_fifocfg_halffifo; + atc_src_h2sel_hw; + atc_dst_h2sel_hw; status = "disabled"; }; };
Signature · 1 line
1.7.2.5
PATCH 21/23 spi-atmel OF: complete documentation
In reply to Richard Genoud--- .../devicetree/bindings/spi/spi_atmel.txt | 15 +++++++++++++++ 1 files changed, 15 insertions(+), 0 deletions(-)
Documentation/devicetree/bindings/spi/spi_atmel.txt +15 -0
@@ -4,3 +4,18 @@ Required properties: - compatible : should be "atmel,at91rm9200-spi". - reg: Address and length of the register set for the device - interrupts: Should contain macb interrupt +- cs-gpio: Should contain the GPIOs used for chipselect. + +spi0: spi at f0000000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "atmel,at91rm9200-spi"; + reg = <0xf0000000 0x100>; + interrupts = <13 4>; + cs-gpios = <&pioA 14 0 + &pioA 7 0 /* conflicts with TXD2 */ + &pioA 1 0 /* conflicts with RXD0 */ + &pioB 3 0 /* conflicts with ERXDV */ + >; + status = "disabled"; +};
Signature · 1 line
1.7.2.5
PATCH 22/23 spi-atmel: complete DMA slave OF documentation
In reply to Richard Genoud--- .../devicetree/bindings/spi/spi_atmel.txt | 25 ++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
Documentation/devicetree/bindings/spi/spi_atmel.txt +25 -0
@@ -5,6 +5,24 @@ Required properties: - reg: Address and length of the register set for the device - interrupts: Should contain macb interrupt - cs-gpio: Should contain the GPIOs used for chipselect. +- dma-mask: device coherent dma mask. +/* dma transfer configuration. Cf DMA Channel configuration register */ +- dma: handle to the dma controller that should be used. +- atc_src_per: source channel for DMA operation. +- atc_dst_per: destination channel for DMA operation. +- atc_src_h2sel_hw: Hardware handshaking interface is used to trigger a +transfer request. +- atc_dst_h2sel_hw: Hardware handshaking interface is used to trigger a +transfer request. +- atc_sod: STOP ON DONE activated. +- atc_lock_if: Interface Lock capability is enabled. +- atc_lock_b: AHB Bus Locking capability is enabled. +- atc_lock_if_l_buffer: The Master Interface Arbiter is locked by the channel x for a buffer transfer. +- atc_fifocfg_halffifo: When half FIFO size is available/filled, a source/destination request is serviced. +- atc_fifocfg_enoughspace: When there is enough space/data available to perform a single AHB access, then the request is serviced. +- atc_fifocfg_largestburst: The largest defined length AHB burst is performed on the destination AHB interface. +- atc_ahb_prot: AHB Protection value. (cf release manual) + spi0: spi at f0000000 { #address-cells = <1>;
@@ -17,5 +35,12 @@ spi0: spi at f0000000 { &pioA 1 0 /* conflicts with RXD0 */ &pioB 3 0 /* conflicts with ERXDV */ >; + dma-mask = <0xffffffff>; + dma = <&dma0>; + atc_src_per = <2>; /* AT_DMA_ID_SPI0_RX */ + atc_dst_per = <1>; /* AT_DMA_ID_SPI0_TX */ + atc_fifocfg_halffifo; + atc_src_h2sel_hw; + atc_dst_h2sel_hw; status = "disabled"; };
Signature · 1 line
1.7.2.5
PATCH 23/23 sam9x5ek DTS: enable SPI dataflash
In reply to Richard Genoud--- arch/arm/boot/dts/at91sam9x5ek.dtsi | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
arch/arm/boot/dts/at91sam9x5ek.dtsi +10 -0
@@ -30,6 +30,16 @@ phy-mode = "rmii"; status = "okay"; }; + + spi0: spi at f0000000 { + status = "okay"; + cs-gpios = <&pioA 14 0>; + m25p80 at 0 { + compatible = "atmel,at25df321a"; + spi-max-frequency = <50000000>; + reg = <0>; + }; + }; }; usb0: ohci at 00600000 {
Signature · 1 line
1.7.2.5
cover work in progress: SPI controller w/DMA SAM9X5
In reply to Richard Genoud2012/8/14 Richard Genoud <[email protected]>:
Quoted 4 lines
Nicolas,
I said that I had some work done on sam9g35-ek, here is the spi part, based on your and Jean-Christophe work.
You have to enableCONFIG_ARCH_AT91SAM9X5to get it work.
I forgot something:
As I didn't get pinctrl to work, on top of this patchset, I did a revert of "ARM: at91: add pinctrl support"
and I made this change :
arch/arm/mach-at91/at91sam9x5.c +8 -0
@@ -313,6 +313,13 @@ static void __init at91sam9x5_map_io(void)at91_init_sram (0 ,AT91SAM9X5_SRAM_BASE ,AT91SAM9X5_SRAM_SIZE ); } + +void __init at91sam9x5_initialize (void ) +{ +/* Register GPIO subsystem (using DT) */ +at91_gpio_init (NULL ,0 ); +} +/* -------------------------------------------------------------------- * Interrupt initialization * -------------------------------------------------------------------- */
@@ -320,4 +327,5 @@ static void __init at91sam9x5_map_io(void)struct at91_init_soc __initdata at91sam9x5_soc = { .map_io = at91sam9x5_map_io, .register_clocks = at91sam9x5_register_clocks, + .init = at91sam9x5_initialize, };
I also enabled the spi controller in the DTS:
(quoted diff) +0 -0
b/arch/arm/boot/dts/at91sam9x5.dtsi
index ef09816..cc1c830 100644
arch/arm/boot/dts/at91sam9x5.dtsi +1 -1
@@ -363,7 +363,7 @@ atc_fifocfg_halffifo; atc_src_h2sel_hw; atc_dst_h2sel_hw; - status = "disabled"; + status = "okay"; }; spi1: spi at f0004000 {
Signature · 1 line
for me, ck means con kolivas and not calvin klein... does it mean I'm a geek ?
cover work in progress: SPI controller w/DMA SAM9X5
In reply to Richard GenoudOn 08/14/2012 03:49 PM, Richard Genoud :
Quoted 11 lines
Nicolas,
I said that I had some work done on sam9g35-ek, here is the spi part, based on your and Jean-Christophe work.
You have to enableCONFIG_ARCH_AT91SAM9X5to get it work.The goal of this patchset is to share the work I've done, it's not ready for upstream, but it may save some time.
It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
Best Regards,
Richard,
Thanks a lot for updating this material: We really appreciate.
We will try to review this material together with Jean-Christophe and colleagues @ Atmel. I hope that we will go forward with this collected material in the near future.
Maybe DMA OF part will not be upstreamed as-is because of an ongoing initiative to build a generic dmaengine OF support.
Quoted 3 lines
Jean-Christophe PLAGNIOL-VILLARD (3):
of: add dma-mask binding
of_spi: add generic binding support to specify cs gpio
I know that Jean-Christophe has had difficulties to have feedback on there parts...
Quoted 10 lines
spi/atmel: add DT support
Nicolas Ferre (6):
spi/atmel_spi: trivial: change some comments spi/atmel_spi: add physical base address spi/atmel_spi: call unmapping on transfers buffers spi/atmel_spi: status information passed through controller data spi/atmel_spi: add flag to controller data for lock operations spi/atmel_spi: add dmaengine support
Quoted 2 lines
Richard Genoud (14):
spi-atmel: update with dmaengine interface
This will certainly be squashed in previous path.
Quoted 1 line
spi-atmel: fix __init/__devinit sections mismatch
This one also: but it is good to have them separated at fist.
Quoted 3 lines
spi-atmel: Fix spi-atmel driver to adapt to
slave_configchanges AT91 DMA OF support
add at91sam9x5KconfigARCH/SOC link
Is it fixup for a bug? Jean-Christophe, a though about this one?
Quoted 7 lines
spi-atmel: add DMA OF support
[BUG] SPI: array out of bound => no CS [BUG] atmel-spi && DMA: OOPS if buffer > 4400 bytes
sam9x5: declare SPI clocks
spi-atmel: add sam9x5 SPI in device tree
spi-atmel: add dma support in sam9x5 device tree spi-atmel OF: complete documentation
Maybe documentation has to be folded in the patch that actually adds the OF support.
Quoted 24 lines
spi-atmel: complete DMA slave OF documentation
sam9x5ek DTS: enable SPI dataflashDocumentation/devicetree/bindings/spi/spi-bus.txt | 6 + .../devicetree/bindings/spi/spi_atmel.txt | 46 ++ arch/arm/boot/dts/at91sam9x5.dtsi | 42 ++ arch/arm/boot/dts/at91sam9x5ek.dtsi | 10 + arch/arm/mach-at91/Kconfig | 4 + arch/arm/mach-at91/at91sam9x5.c | 3 + arch/arm/mach-at91/include/mach/at_hdmac.h | 1 + drivers/of/Kconfig | 4 + drivers/of/Makefile | 1 + drivers/of/of_atmel.c | 111 ++++ drivers/of/platform.c | 23 +- drivers/spi/Kconfig | 9 + drivers/spi/spi-atmel.c | 611 ++++++++++++++++++-- drivers/spi/spi.c | 55 ++- include/linux/of_atmel.h | 29 + include/linux/spi/spi.h | 3 + 16 files changed, 914 insertions(+), 44 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/spi_atmel.txt create mode 100644 drivers/of/of_atmel.c create mode 100644 include/linux/of_atmel.h
Signature · 1 line
Nicolas Ferre
cover work in progress: SPI controller w/DMA SAM9X5
Quoted 24 lines · Nicolas Ferre
On 08/14/2012 03:49 PM, Richard Genoud :
Quoted 11 lines
Nicolas,
I said that I had some work done on sam9g35-ek, here is the spi part, based on your and Jean-Christophe work.
You have to enableCONFIG_ARCH_AT91SAM9X5to get it work.The goal of this patchset is to share the work I've done, it's not ready for upstream, but it may save some time.
It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
Best Regards,
Richard,
Thanks a lot for updating this material: We really appreciate.
We will try to review this material together with Jean-Christophe and colleagues @ Atmel. I hope that we will go forward with this collected material in the near future.
Maybe DMA OF part will not be upstreamed as-is because of an ongoing initiative to build a generic dmaengine OF support.
Quoted 6 lines
Quoted 3 lines
Jean-Christophe PLAGNIOL-VILLARD (3):
of: add dma-mask binding
of_spi: add generic binding support to specify cs gpioI know that Jean-Christophe has had difficulties to have feedback on there parts...
yes I need to re-write it as suggest by Grant
will take a look later next week on this
Quoted 18 lines
Quoted 11 lines
spi/atmel: add DT support
Nicolas Ferre (6):
spi/atmel_spi: trivial: change some comments spi/atmel_spi: add physical base address spi/atmel_spi: call unmapping on transfers buffers spi/atmel_spi: status information passed through controller data spi/atmel_spi: add flag to controller data for lock operations spi/atmel_spi: add dmaengine supportQuoted 2 lines
Richard Genoud (14):
spi-atmel: update with dmaengine interfaceThis will certainly be squashed in previous path.
Quoted 1 line
spi-atmel: fix __init/__devinit sections mismatch
Quoted 7 lines
This one also: but it is good to have them separated at fist.
Quoted 3 lines
spi-atmel: Fix spi-atmel driver to adapt to
slave_configchanges AT91 DMA OF support
add at91sam9x5KconfigARCH/SOC linkIs it fixup for a bug? Jean-Christophe, a though about this one?
no the ARCH_xxx is old style can not be used on DT only soc
this patch need to be droped
Best Regards,
J.
cover work in progress: SPI controller w/DMA SAM9X5
On 08/14/2012 07:44 PM, Jean-Christophe PLAGNIOL-VILLARD :
Quoted 54 lines · Nicolas Ferre
Quoted 24 lines
On 08/14/2012 03:49 PM, Richard Genoud :
Quoted 11 lines
Nicolas,
I said that I had some work done on sam9g35-ek, here is the spi part, based on your and Jean-Christophe work.
You have to enableCONFIG_ARCH_AT91SAM9X5to get it work.The goal of this patchset is to share the work I've done, it's not ready for upstream, but it may save some time.
It's based on 3.6-rc1 + Jean-Christophe's pinctrl patchset.
Best Regards,
Richard,
Thanks a lot for updating this material: We really appreciate.
We will try to review this material together with Jean-Christophe and colleagues @ Atmel. I hope that we will go forward with this collected material in the near future.
Maybe DMA OF part will not be upstreamed as-is because of an ongoing initiative to build a generic dmaengine OF support.
Quoted 6 lines
Quoted 3 lines
Jean-Christophe PLAGNIOL-VILLARD (3):
of: add dma-mask binding
of_spi: add generic binding support to specify cs gpioI know that Jean-Christophe has had difficulties to have feedback on there parts...
yes I need to re-write it as suggest by Grant
will take a look later next week on this
Quoted 20 lines
Quoted 11 lines
spi/atmel: add DT support
Nicolas Ferre (6):
spi/atmel_spi: trivial: change some comments spi/atmel_spi: add physical base address spi/atmel_spi: call unmapping on transfers buffers spi/atmel_spi: status information passed through controller data spi/atmel_spi: add flag to controller data for lock operations spi/atmel_spi: add dmaengine supportQuoted 2 lines
Richard Genoud (14):
spi-atmel: update with dmaengine interfaceThis will certainly be squashed in previous path.
Quoted 1 line
spi-atmel: fix __init/__devinit sections mismatch
This one also: but it is good to have them separated at fist.
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
spi-atmel: Fix spi-atmel driver to adapt to
slave_configchanges AT91 DMA OF support
add at91sam9x5KconfigARCH/SOC linkIs it fixup for a bug? Jean-Christophe, a though about this one?
no the
ARCH_xxxis old style can not be used on DT only socthis patch need to be droped
That is what I suspected, thanks J.
Bye,
Signature · 1 line
Nicolas Ferre
cover work in progress: SPI controller w/DMA SAM9X5
2012/8/14 Nicolas Ferre <[email protected]>:
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
add at91sam9x5
KconfigARCH/SOC linkIs it fixup for a bug? Jean-Christophe, a though about this one?
no the
ARCH_xxxis old style can not be used on DT only socthis patch need to be droped
That is what I suspected, thanks J.
Yes, Jean-Christophe is right. This patch needs to be dropped, and this one should be applied instead:
drivers/spi/Kconfig +0 -1
@@ -76,7 +76,7 @@ config SPI_ATMEL config SPI_ATMEL_DMA bool "Atmel SPI DMA support" - depends on SPI_ATMEL && (ARCH_AT91SAM9G45 || ARCH_AT91SAM9X5) &&
DMA_ENGINE && EXPERIMENTAL
+ depends on SPI_ATMEL && (SOC_AT91SAM9G45 || SOC_AT91SAM9X5) &&DMA_ENGINE && EXPERIMENTAL
default y
help
Say Y here if you want the Atmel SPI driver to use the DMA engine.
Data transfers
Richard.
Signature · 1 line
for me, ck means con kolivas and not calvin klein... does it mean I'm a geek ?