RE: DMA for Davinci SPI controller with multiple slave devices
-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
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
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