RE: DMA for Davinci SPI controller with multiple slave devices

2010-01-14 Thread Brian Niebuhr
 -Original Message-
 From: Nori, Sekhar [mailto:nsek...@ti.com] 
 Sent: Thursday, January 14, 2010 12:44 AM
 To: Brian Niebuhr
 Cc: davinci-linux-open-source@linux.davincidsp.com
 Subject: RE: DMA for Davinci SPI controller with multiple 
 slave devices
 
 Hello Brian,
 
 On Thu, Jan 14, 2010 at 04:26:15, Brian Niebuhr wrote:
  I am working on building a kernel for a custom board based 
 on an OMAP
  L138.  As a baseline I am using the OMAP L138 SDK kernel.  
 On my board
  there are multiple SPI slaves connected to the SPI1 controller.  I'm
  getting some errors during boot because after the first slave has
  initialized, the others report an error that they can't aquire a DMA
  channel.
 
  I've been looking through the code and I understand why the error
  occurs, but I'm not sure how to fix it correctly.  Here's 
 what I know:
 
  - In arch/arm/mach-davinci/devices-da8xx.c there are two 
 DMA channels
  (one Tx, one Rx) allocated for the SPI1 controller.
 
  - In drivers/spi/davinci_spi_master.c the controller 
 maintains a struct
  davinci_spi_dma for every chip select.
 
  - In drivers/spi/davinci_spi_master.c, davinci_spi_probe() sets the
  dma_rx_sync_dev field of that structure for every chip 
 select to the Rx
  DMA channel, and likewise the dma_tx_sync_dev field of that 
 structure
  for every chip select to the Tx DMA channel.
 
  - Then for every SPI device,
  drivers/spi/davinci_spi_master.c:davinci_spi_setup() gets 
 called which
  in turn calls davinci_spi_request_dma().
 
  - So here is the problem: davinci_spi_request_dma() requests the
  channels specified in dma_rx_sync_dev and dma_tx_sync_dev, 
 which are the
  same channels for every device.  Therefore the first device 
 succeeds but
  additional devices on that controller fail.
 
 Yes, this was reported before when the driver patch was
 submitted for review[1]. But, in the interest of having
 the driver hit upstream sooner versus having all features
 supported correctly, this has remained a TODO item.
 
 
 
  So I'm trying to figure out what the driver writer intended so I can
  solve this problem.  I see two potential solutions:
 
  1. Allocate more DMA channels in devices-da8xx.c.  Then in
  davinci_spi_probe() set the dma_[rx|tx]_sync_dev fields to 
 a different
  channel for each device.  I don't fully understand though 
 if they would
  need separate eventqs too.  This seems unnecessary, though, 
 because only
  one can be active at a time anyway.
 
  2. Share the DMA channels between all devices on a controller.  This
  seems like it would work fine except for the fact that the 
 DMA callbacks
  would be messed up as written.  However I also think that 
 it would be
  possible to rewrite the callback function to work correctly.
 
 Right. Without a fix of some sort, the only other way is to not
 to use DMA at all and use PIO mode instead.
 
 
 
  I'm leaning toward (2), but I don't fully understand the driver.
 
 I believe (2) is the right way too.
 
   Does
  anyone have any suggestions on how to fix this, or am I 
 just completely
  misunderstanding how this is supposed to work?
 
 A fix is needed. It would be great if this
 is something you can help on.

I will attempt a fix, though it's going to be a while before I get to
test it.  If I can test before anyone else gets around to fixing it,
I'll submit a patch.


Brian


 
 Thanks,
 Sekhar
 
 [1] 
 http://linux.omap.com/pipermail/davinci-linux-open-source/2009
 -November/016979.html
 
 
 

___
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source


DMA for Davinci SPI controller with multiple slave devices

2010-01-13 Thread Brian Niebuhr
I am working on building a kernel for a custom board based on an OMAP
L138.  As a baseline I am using the OMAP L138 SDK kernel.  On my board
there are multiple SPI slaves connected to the SPI1 controller.  I'm
getting some errors during boot because after the first slave has
initialized, the others report an error that they can't aquire a DMA
channel.

I've been looking through the code and I understand why the error
occurs, but I'm not sure how to fix it correctly.  Here's what I know:

- In arch/arm/mach-davinci/devices-da8xx.c there are two DMA channels
(one Tx, one Rx) allocated for the SPI1 controller. 

- In drivers/spi/davinci_spi_master.c the controller maintains a struct
davinci_spi_dma for every chip select.

- In drivers/spi/davinci_spi_master.c, davinci_spi_probe() sets the
dma_rx_sync_dev field of that structure for every chip select to the Rx
DMA channel, and likewise the dma_tx_sync_dev field of that structure
for every chip select to the Tx DMA channel.

- Then for every SPI device,
drivers/spi/davinci_spi_master.c:davinci_spi_setup() gets called which
in turn calls davinci_spi_request_dma().  

- So here is the problem: davinci_spi_request_dma() requests the
channels specified in dma_rx_sync_dev and dma_tx_sync_dev, which are the
same channels for every device.  Therefore the first device succeeds but
additional devices on that controller fail.


So I'm trying to figure out what the driver writer intended so I can
solve this problem.  I see two potential solutions:

1. Allocate more DMA channels in devices-da8xx.c.  Then in
davinci_spi_probe() set the dma_[rx|tx]_sync_dev fields to a different
channel for each device.  I don't fully understand though if they would
need separate eventqs too.  This seems unnecessary, though, because only
one can be active at a time anyway.

2. Share the DMA channels between all devices on a controller.  This
seems like it would work fine except for the fact that the DMA callbacks
would be messed up as written.  However I also think that it would be
possible to rewrite the callback function to work correctly.


I'm leaning toward (2), but I don't fully understand the driver.  Does
anyone have any suggestions on how to fix this, or am I just completely
misunderstanding how this is supposed to work?

Thanks,

Brian


_
Brian Niebuhr
Principal Design Engineer
E.F. Johnson
 

___
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source


RE: DMA for Davinci SPI controller with multiple slave devices

2010-01-13 Thread Nori, Sekhar
Hello Brian,

On Thu, Jan 14, 2010 at 04:26:15, Brian Niebuhr wrote:
 I am working on building a kernel for a custom board based on an OMAP
 L138.  As a baseline I am using the OMAP L138 SDK kernel.  On my board
 there are multiple SPI slaves connected to the SPI1 controller.  I'm
 getting some errors during boot because after the first slave has
 initialized, the others report an error that they can't aquire a DMA
 channel.

 I've been looking through the code and I understand why the error
 occurs, but I'm not sure how to fix it correctly.  Here's what I know:

 - In arch/arm/mach-davinci/devices-da8xx.c there are two DMA channels
 (one Tx, one Rx) allocated for the SPI1 controller.

 - In drivers/spi/davinci_spi_master.c the controller maintains a struct
 davinci_spi_dma for every chip select.

 - In drivers/spi/davinci_spi_master.c, davinci_spi_probe() sets the
 dma_rx_sync_dev field of that structure for every chip select to the Rx
 DMA channel, and likewise the dma_tx_sync_dev field of that structure
 for every chip select to the Tx DMA channel.

 - Then for every SPI device,
 drivers/spi/davinci_spi_master.c:davinci_spi_setup() gets called which
 in turn calls davinci_spi_request_dma().

 - So here is the problem: davinci_spi_request_dma() requests the
 channels specified in dma_rx_sync_dev and dma_tx_sync_dev, which are the
 same channels for every device.  Therefore the first device succeeds but
 additional devices on that controller fail.

Yes, this was reported before when the driver patch was
submitted for review[1]. But, in the interest of having
the driver hit upstream sooner versus having all features
supported correctly, this has remained a TODO item.



 So I'm trying to figure out what the driver writer intended so I can
 solve this problem.  I see two potential solutions:

 1. Allocate more DMA channels in devices-da8xx.c.  Then in
 davinci_spi_probe() set the dma_[rx|tx]_sync_dev fields to a different
 channel for each device.  I don't fully understand though if they would
 need separate eventqs too.  This seems unnecessary, though, because only
 one can be active at a time anyway.

 2. Share the DMA channels between all devices on a controller.  This
 seems like it would work fine except for the fact that the DMA callbacks
 would be messed up as written.  However I also think that it would be
 possible to rewrite the callback function to work correctly.

Right. Without a fix of some sort, the only other way is to not
to use DMA at all and use PIO mode instead.



 I'm leaning toward (2), but I don't fully understand the driver.

I believe (2) is the right way too.

  Does
 anyone have any suggestions on how to fix this, or am I just completely
 misunderstanding how this is supposed to work?

A fix is needed. It would be great if this
is something you can help on.

Thanks,
Sekhar

[1] 
http://linux.omap.com/pipermail/davinci-linux-open-source/2009-November/016979.html

___
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source