Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 04:52:16PM +0100, Mark Brown wrote: > On Wed, Sep 10, 2014 at 11:18:01PM +0800, Robin Gong wrote: > > On Wed, Sep 10, 2014 at 12:45:30PM +0100, Mark Brown wrote: > > > > > Yes, you're right. I should use "transfer->tx_sg->sgl == NULL" or > > > > "transfer->rx_sg->sgl == NULL" instead of usedma flag in driver, right? > > > > Right. > > > But looks spi core framework can make sure every rx or tx transfer in > > sequence. > > If so, can_dma will never be called until this transfer finished > > (spi_pump_messages), and my usedma flag also never be modified until next > > transfer start. Please correct me if I am wrong, thanks. > > Even if that were true currently this would still not be good code since > it would break in the face of SPI core changes. In any case the > assumption isn't true for the current SPI core, the DMA mapping is done > for all transfers in a message before we start running them and it's > entirely likely that we will have patterns like a short PIO transfer > followed by a big data block. Understood, will improve it in v6.Thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 11:18:01PM +0800, Robin Gong wrote: > On Wed, Sep 10, 2014 at 12:45:30PM +0100, Mark Brown wrote: > > > Yes, you're right. I should use "transfer->tx_sg->sgl == NULL" or > > > "transfer->rx_sg->sgl == NULL" instead of usedma flag in driver, right? > > Right. > But looks spi core framework can make sure every rx or tx transfer in > sequence. > If so, can_dma will never be called until this transfer finished > (spi_pump_messages), and my usedma flag also never be modified until next > transfer start. Please correct me if I am wrong, thanks. Even if that were true currently this would still not be good code since it would break in the face of SPI core changes. In any case the assumption isn't true for the current SPI core, the DMA mapping is done for all transfers in a message before we start running them and it's entirely likely that we will have patterns like a short PIO transfer followed by a big data block. signature.asc Description: Digital signature
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 12:45:30PM +0100, Mark Brown wrote: > On Wed, Sep 10, 2014 at 07:22:59PM +0800, Robin Gong wrote: > > On Wed, Sep 10, 2014 at 11:21:05AM +0100, Mark Brown wrote: > > > > This isn't going to work, anything that looks at the usedma flag will > > > see the result of the last thing that was checked which may or may not > > > be the transfer that it's handling. The driver should check to see if > > > the core mapped the transfer for DMA. > > > Yes, you're right. I should use "transfer->tx_sg->sgl == NULL" or > > "transfer->rx_sg->sgl == NULL" instead of usedma flag in driver, right? > > Right. But looks spi core framework can make sure every rx or tx transfer in sequence. If so, can_dma will never be called until this transfer finished (spi_pump_messages), and my usedma flag also never be modified until next transfer start. Please correct me if I am wrong, thanks. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 07:22:59PM +0800, Robin Gong wrote: > On Wed, Sep 10, 2014 at 11:21:05AM +0100, Mark Brown wrote: > > This isn't going to work, anything that looks at the usedma flag will > > see the result of the last thing that was checked which may or may not > > be the transfer that it's handling. The driver should check to see if > > the core mapped the transfer for DMA. > Yes, you're right. I should use "transfer->tx_sg->sgl == NULL" or > "transfer->rx_sg->sgl == NULL" instead of usedma flag in driver, right? Right. signature.asc Description: Digital signature
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 11:21:05AM +0100, Mark Brown wrote: > On Wed, Sep 10, 2014 at 09:30:04AM +0800, Robin Gong wrote: > > > +static bool spi_imx_can_dma(struct spi_master *master, struct spi_device > > *spi, > > +struct spi_transfer *transfer) > > +{ > > + struct spi_imx_data *spi_imx = spi_master_get_devdata(master); > > + > > + if (spi_imx->dma_is_inited && (transfer->len > spi_imx->rx_wml) > > + && (transfer->len > spi_imx->tx_wml)) > > + spi_imx->usedma = true; > > + else > > + spi_imx->usedma = false; > > + > > + return spi_imx->usedma; > > +} > > This isn't going to work, anything that looks at the usedma flag will > see the result of the last thing that was checked which may or may not > be the transfer that it's handling. The driver should check to see if > the core mapped the transfer for DMA. Yes, you're right. I should use "transfer->tx_sg->sgl == NULL" or "transfer->rx_sg->sgl == NULL" instead of usedma flag in driver, right? -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 09:30:04AM +0800, Robin Gong wrote: > +static bool spi_imx_can_dma(struct spi_master *master, struct spi_device > *spi, > + struct spi_transfer *transfer) > +{ > + struct spi_imx_data *spi_imx = spi_master_get_devdata(master); > + > + if (spi_imx->dma_is_inited && (transfer->len > spi_imx->rx_wml) > + && (transfer->len > spi_imx->tx_wml)) > + spi_imx->usedma = true; > + else > + spi_imx->usedma = false; > + > + return spi_imx->usedma; > +} This isn't going to work, anything that looks at the usedma flag will see the result of the last thing that was checked which may or may not be the transfer that it's handling. The driver should check to see if the core mapped the transfer for DMA. signature.asc Description: Digital signature
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 10:17:14AM +0200, Arnd Bergmann wrote: > On Wednesday 10 September 2014 09:30:04 Robin Gong wrote: > > Enable DMA support on i.mx6. The read speed can increase from 600KB/s > > to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. > > If not set "dma-names" in dts, spi will use PIO mode. This patch only > > validate on i.mx6, not i.mx5, but encourage ones to apply this patch > > on i.mx5 since they share the same IP. > > > > Note: > > Sometime, there is a weid data in rxfifo after one full tx/rx > > transfer finish by DMA on i.mx6dl, so we disable dma functhion on > > i.mx6dl. > > > > Signed-off-by: Frank Li > > Signed-off-by: Robin Gong > > > > > > The patch looks good to me, but you need to also update the > Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt file to > document the additional optional properties. > > Arnd Thanks for your reminding, I'll add it in the v6. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wednesday 10 September 2014 09:30:04 Robin Gong wrote: > Enable DMA support on i.mx6. The read speed can increase from 600KB/s > to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. > If not set "dma-names" in dts, spi will use PIO mode. This patch only > validate on i.mx6, not i.mx5, but encourage ones to apply this patch > on i.mx5 since they share the same IP. > > Note: > Sometime, there is a weid data in rxfifo after one full tx/rx > transfer finish by DMA on i.mx6dl, so we disable dma functhion on > i.mx6dl. > > Signed-off-by: Frank Li > Signed-off-by: Robin Gong > > The patch looks good to me, but you need to also update the Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt file to document the additional optional properties. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wednesday 10 September 2014 09:30:04 Robin Gong wrote: Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. If not set dma-names in dts, spi will use PIO mode. This patch only validate on i.mx6, not i.mx5, but encourage ones to apply this patch on i.mx5 since they share the same IP. Note: Sometime, there is a weid data in rxfifo after one full tx/rx transfer finish by DMA on i.mx6dl, so we disable dma functhion on i.mx6dl. Signed-off-by: Frank Li frank...@freescale.com Signed-off-by: Robin Gong b38...@freescale.com The patch looks good to me, but you need to also update the Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt file to document the additional optional properties. Arnd -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 10:17:14AM +0200, Arnd Bergmann wrote: On Wednesday 10 September 2014 09:30:04 Robin Gong wrote: Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. If not set dma-names in dts, spi will use PIO mode. This patch only validate on i.mx6, not i.mx5, but encourage ones to apply this patch on i.mx5 since they share the same IP. Note: Sometime, there is a weid data in rxfifo after one full tx/rx transfer finish by DMA on i.mx6dl, so we disable dma functhion on i.mx6dl. Signed-off-by: Frank Li frank...@freescale.com Signed-off-by: Robin Gong b38...@freescale.com The patch looks good to me, but you need to also update the Documentation/devicetree/bindings/spi/fsl-imx-cspi.txt file to document the additional optional properties. Arnd Thanks for your reminding, I'll add it in the v6. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 09:30:04AM +0800, Robin Gong wrote: +static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, + struct spi_transfer *transfer) +{ + struct spi_imx_data *spi_imx = spi_master_get_devdata(master); + + if (spi_imx-dma_is_inited (transfer-len spi_imx-rx_wml) + (transfer-len spi_imx-tx_wml)) + spi_imx-usedma = true; + else + spi_imx-usedma = false; + + return spi_imx-usedma; +} This isn't going to work, anything that looks at the usedma flag will see the result of the last thing that was checked which may or may not be the transfer that it's handling. The driver should check to see if the core mapped the transfer for DMA. signature.asc Description: Digital signature
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 11:21:05AM +0100, Mark Brown wrote: On Wed, Sep 10, 2014 at 09:30:04AM +0800, Robin Gong wrote: +static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, +struct spi_transfer *transfer) +{ + struct spi_imx_data *spi_imx = spi_master_get_devdata(master); + + if (spi_imx-dma_is_inited (transfer-len spi_imx-rx_wml) +(transfer-len spi_imx-tx_wml)) + spi_imx-usedma = true; + else + spi_imx-usedma = false; + + return spi_imx-usedma; +} This isn't going to work, anything that looks at the usedma flag will see the result of the last thing that was checked which may or may not be the transfer that it's handling. The driver should check to see if the core mapped the transfer for DMA. Yes, you're right. I should use transfer-tx_sg-sgl == NULL or transfer-rx_sg-sgl == NULL instead of usedma flag in driver, right? -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 07:22:59PM +0800, Robin Gong wrote: On Wed, Sep 10, 2014 at 11:21:05AM +0100, Mark Brown wrote: This isn't going to work, anything that looks at the usedma flag will see the result of the last thing that was checked which may or may not be the transfer that it's handling. The driver should check to see if the core mapped the transfer for DMA. Yes, you're right. I should use transfer-tx_sg-sgl == NULL or transfer-rx_sg-sgl == NULL instead of usedma flag in driver, right? Right. signature.asc Description: Digital signature
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 12:45:30PM +0100, Mark Brown wrote: On Wed, Sep 10, 2014 at 07:22:59PM +0800, Robin Gong wrote: On Wed, Sep 10, 2014 at 11:21:05AM +0100, Mark Brown wrote: This isn't going to work, anything that looks at the usedma flag will see the result of the last thing that was checked which may or may not be the transfer that it's handling. The driver should check to see if the core mapped the transfer for DMA. Yes, you're right. I should use transfer-tx_sg-sgl == NULL or transfer-rx_sg-sgl == NULL instead of usedma flag in driver, right? Right. But looks spi core framework can make sure every rx or tx transfer in sequence. If so, can_dma will never be called until this transfer finished (spi_pump_messages), and my usedma flag also never be modified until next transfer start. Please correct me if I am wrong, thanks. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 11:18:01PM +0800, Robin Gong wrote: On Wed, Sep 10, 2014 at 12:45:30PM +0100, Mark Brown wrote: Yes, you're right. I should use transfer-tx_sg-sgl == NULL or transfer-rx_sg-sgl == NULL instead of usedma flag in driver, right? Right. But looks spi core framework can make sure every rx or tx transfer in sequence. If so, can_dma will never be called until this transfer finished (spi_pump_messages), and my usedma flag also never be modified until next transfer start. Please correct me if I am wrong, thanks. Even if that were true currently this would still not be good code since it would break in the face of SPI core changes. In any case the assumption isn't true for the current SPI core, the DMA mapping is done for all transfers in a message before we start running them and it's entirely likely that we will have patterns like a short PIO transfer followed by a big data block. signature.asc Description: Digital signature
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 04:52:16PM +0100, Mark Brown wrote: On Wed, Sep 10, 2014 at 11:18:01PM +0800, Robin Gong wrote: On Wed, Sep 10, 2014 at 12:45:30PM +0100, Mark Brown wrote: Yes, you're right. I should use transfer-tx_sg-sgl == NULL or transfer-rx_sg-sgl == NULL instead of usedma flag in driver, right? Right. But looks spi core framework can make sure every rx or tx transfer in sequence. If so, can_dma will never be called until this transfer finished (spi_pump_messages), and my usedma flag also never be modified until next transfer start. Please correct me if I am wrong, thanks. Even if that were true currently this would still not be good code since it would break in the face of SPI core changes. In any case the assumption isn't true for the current SPI core, the DMA mapping is done for all transfers in a message before we start running them and it's entirely likely that we will have patterns like a short PIO transfer followed by a big data block. Understood, will improve it in v6.Thanks. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 09:46:04AM +0530, Varka Bhadram wrote: > On 09/10/2014 07:00 AM, Robin Gong wrote: > >Enable DMA support on i.mx6. The read speed can increase from 600KB/s > >to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. > > (...) > > >+ > >+static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data > >*spi_imx, > >+ struct spi_master *master, > >+ const struct resource *res) > >+{ > >+struct dma_slave_config slave_config = {}; > >+int ret; > >+ > >+/* Prepare for TX DMA: */ > >+master->dma_tx = dma_request_slave_channel(dev, "tx"); > >+if (!master->dma_tx) { > >+dev_err(dev, "cannot get the TX DMA channel!\n"); > >+ret = -EINVAL; > >+goto err; > >+} > >+ > >+slave_config.direction = DMA_MEM_TO_DEV; > >+slave_config.dst_addr = res->start + MXC_CSPITXDATA; > >+slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; > >+slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; > >+ret = dmaengine_slave_config(master->dma_tx, _config); > >+if (ret) { > >+dev_err(dev, "error in TX dma configuration."); > >+ > > Missed terminating new line.. > You mean lack "\n" in the print info? If yes, I can improve it in v6. > -- > Regards, > Varka Bhadram. > -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On 09/10/2014 07:00 AM, Robin Gong wrote: Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. (...) + +static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, +struct spi_master *master, +const struct resource *res) +{ + struct dma_slave_config slave_config = {}; + int ret; + + /* Prepare for TX DMA: */ + master->dma_tx = dma_request_slave_channel(dev, "tx"); + if (!master->dma_tx) { + dev_err(dev, "cannot get the TX DMA channel!\n"); + ret = -EINVAL; + goto err; + } + + slave_config.direction = DMA_MEM_TO_DEV; + slave_config.dst_addr = res->start + MXC_CSPITXDATA; + slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; + ret = dmaengine_slave_config(master->dma_tx, _config); + if (ret) { + dev_err(dev, "error in TX dma configuration."); + Missed terminating new line.. -- Regards, Varka Bhadram. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v5] spi: spi-imx: add DMA support
Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. If not set "dma-names" in dts, spi will use PIO mode. This patch only validate on i.mx6, not i.mx5, but encourage ones to apply this patch on i.mx5 since they share the same IP. Note: Sometime, there is a weid data in rxfifo after one full tx/rx transfer finish by DMA on i.mx6dl, so we disable dma functhion on i.mx6dl. Signed-off-by: Frank Li Signed-off-by: Robin Gong --- Change from v4: 1. Enrich comments. 2. Remove the rxfifo workaround. The issue only exist on i.mx6dl, so disable dma function in dts. Change from v3: 1. Use spi core framwork to handle dump tx/rx buf 2. Add one workaround for weird data in rxfifo when one full transfer done. Change from v2: http://thread.gmane.org/gmane.linux.ports.arm.kernel/291722/focus=294363 1. Dma setup only for imx51-ecspi 2. Use one small dummy buffer(1 bd size) to templiy store data for meanless rx/tx, instead of malloc the actual transfer size. 3. Split spi_mx_sdma_transfer to smaller and easily to read. 4. Fix some code indent. --- drivers/spi/spi-imx.c | 287 -- 1 file changed, 281 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 5daff20..c41a7a3 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include #include @@ -37,6 +39,7 @@ #include #include +#include #include #define DRIVER_NAME "spi_imx" @@ -51,6 +54,9 @@ #define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */ #define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */ +/* The maximum bytes that a sdma BD can transfer.*/ +#define MAX_SDMA_BD_BYTES (1 << 15) +#define IMX_DMA_TIMEOUT (msecs_to_jiffies(3000)) struct spi_imx_config { unsigned int speed_hz; unsigned int bpw; @@ -95,6 +101,16 @@ struct spi_imx_data { const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ + /* DMA */ + unsigned int dma_is_inited; + unsigned int dma_finished; + bool usedma; + u32 rx_wml; + u32 tx_wml; + u32 rxt_wml; + struct completion dma_rx_completion; + struct completion dma_tx_completion; + const struct spi_imx_devtype_data *devtype_data; int chipselect[0]; }; @@ -181,9 +197,24 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, return 7; } +static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, +struct spi_transfer *transfer) +{ + struct spi_imx_data *spi_imx = spi_master_get_devdata(master); + + if (spi_imx->dma_is_inited && (transfer->len > spi_imx->rx_wml) + && (transfer->len > spi_imx->tx_wml)) + spi_imx->usedma = true; + else + spi_imx->usedma = false; + + return spi_imx->usedma; +} + #define MX51_ECSPI_CTRL0x08 #define MX51_ECSPI_CTRL_ENABLE (1 << 0) #define MX51_ECSPI_CTRL_XCH(1 << 2) +#define MX51_ECSPI_CTRL_SMC(1 << 3) #define MX51_ECSPI_CTRL_MODE_MASK (0xf << 4) #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 @@ -201,6 +232,18 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, #define MX51_ECSPI_INT_TEEN(1 << 0) #define MX51_ECSPI_INT_RREN(1 << 3) +#define MX51_ECSPI_DMA 0x14 +#define MX51_ECSPI_DMA_TX_WML_OFFSET 0 +#define MX51_ECSPI_DMA_TX_WML_MASK 0x3F +#define MX51_ECSPI_DMA_RX_WML_OFFSET 16 +#define MX51_ECSPI_DMA_RX_WML_MASK (0x3F << 16) +#define MX51_ECSPI_DMA_RXT_WML_OFFSET 24 +#define MX51_ECSPI_DMA_RXT_WML_MASK(0x3F << 24) + +#define MX51_ECSPI_DMA_TEDEN_OFFSET7 +#define MX51_ECSPI_DMA_RXDEN_OFFSET23 +#define MX51_ECSPI_DMA_RXTDEN_OFFSET 31 + #define MX51_ECSPI_STAT0x18 #define MX51_ECSPI_STAT_RR (1 << 3) @@ -257,17 +300,22 @@ static void __maybe_unused mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int static void __maybe_unused mx51_ecspi_trigger(struct spi_imx_data *spi_imx) { - u32 reg; - - reg = readl(spi_imx->base + MX51_ECSPI_CTRL); - reg |= MX51_ECSPI_CTRL_XCH; + u32 reg = readl(spi_imx->base + MX51_ECSPI_CTRL); + + if (!spi_imx->usedma) + reg |= MX51_ECSPI_CTRL_XCH; + else if (!spi_imx->dma_finished) + reg |= MX51_ECSPI_CTRL_SMC; + else + reg &= ~MX51_ECSPI_CTRL_SMC; writel(reg, spi_imx->base + MX51_ECSPI_CTRL); } static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, struct spi_imx_config *config) { - u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0; + u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0; + u32
[PATCH v5] spi: spi-imx: add DMA support
Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. If not set dma-names in dts, spi will use PIO mode. This patch only validate on i.mx6, not i.mx5, but encourage ones to apply this patch on i.mx5 since they share the same IP. Note: Sometime, there is a weid data in rxfifo after one full tx/rx transfer finish by DMA on i.mx6dl, so we disable dma functhion on i.mx6dl. Signed-off-by: Frank Li frank...@freescale.com Signed-off-by: Robin Gong b38...@freescale.com --- Change from v4: 1. Enrich comments. 2. Remove the rxfifo workaround. The issue only exist on i.mx6dl, so disable dma function in dts. Change from v3: 1. Use spi core framwork to handle dump tx/rx buf 2. Add one workaround for weird data in rxfifo when one full transfer done. Change from v2: http://thread.gmane.org/gmane.linux.ports.arm.kernel/291722/focus=294363 1. Dma setup only for imx51-ecspi 2. Use one small dummy buffer(1 bd size) to templiy store data for meanless rx/tx, instead of malloc the actual transfer size. 3. Split spi_mx_sdma_transfer to smaller and easily to read. 4. Fix some code indent. --- drivers/spi/spi-imx.c | 287 -- 1 file changed, 281 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 5daff20..c41a7a3 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -21,6 +21,8 @@ #include linux/clk.h #include linux/completion.h #include linux/delay.h +#include linux/dmaengine.h +#include linux/dma-mapping.h #include linux/err.h #include linux/gpio.h #include linux/interrupt.h @@ -37,6 +39,7 @@ #include linux/of_device.h #include linux/of_gpio.h +#include linux/platform_data/dma-imx.h #include linux/platform_data/spi-imx.h #define DRIVER_NAME spi_imx @@ -51,6 +54,9 @@ #define MXC_INT_RR (1 0) /* Receive data ready interrupt */ #define MXC_INT_TE (1 1) /* Transmit FIFO empty interrupt */ +/* The maximum bytes that a sdma BD can transfer.*/ +#define MAX_SDMA_BD_BYTES (1 15) +#define IMX_DMA_TIMEOUT (msecs_to_jiffies(3000)) struct spi_imx_config { unsigned int speed_hz; unsigned int bpw; @@ -95,6 +101,16 @@ struct spi_imx_data { const void *tx_buf; unsigned int txfifo; /* number of words pushed in tx FIFO */ + /* DMA */ + unsigned int dma_is_inited; + unsigned int dma_finished; + bool usedma; + u32 rx_wml; + u32 tx_wml; + u32 rxt_wml; + struct completion dma_rx_completion; + struct completion dma_tx_completion; + const struct spi_imx_devtype_data *devtype_data; int chipselect[0]; }; @@ -181,9 +197,24 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, return 7; } +static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, +struct spi_transfer *transfer) +{ + struct spi_imx_data *spi_imx = spi_master_get_devdata(master); + + if (spi_imx-dma_is_inited (transfer-len spi_imx-rx_wml) +(transfer-len spi_imx-tx_wml)) + spi_imx-usedma = true; + else + spi_imx-usedma = false; + + return spi_imx-usedma; +} + #define MX51_ECSPI_CTRL0x08 #define MX51_ECSPI_CTRL_ENABLE (1 0) #define MX51_ECSPI_CTRL_XCH(1 2) +#define MX51_ECSPI_CTRL_SMC(1 3) #define MX51_ECSPI_CTRL_MODE_MASK (0xf 4) #define MX51_ECSPI_CTRL_POSTDIV_OFFSET 8 #define MX51_ECSPI_CTRL_PREDIV_OFFSET 12 @@ -201,6 +232,18 @@ static unsigned int spi_imx_clkdiv_2(unsigned int fin, #define MX51_ECSPI_INT_TEEN(1 0) #define MX51_ECSPI_INT_RREN(1 3) +#define MX51_ECSPI_DMA 0x14 +#define MX51_ECSPI_DMA_TX_WML_OFFSET 0 +#define MX51_ECSPI_DMA_TX_WML_MASK 0x3F +#define MX51_ECSPI_DMA_RX_WML_OFFSET 16 +#define MX51_ECSPI_DMA_RX_WML_MASK (0x3F 16) +#define MX51_ECSPI_DMA_RXT_WML_OFFSET 24 +#define MX51_ECSPI_DMA_RXT_WML_MASK(0x3F 24) + +#define MX51_ECSPI_DMA_TEDEN_OFFSET7 +#define MX51_ECSPI_DMA_RXDEN_OFFSET23 +#define MX51_ECSPI_DMA_RXTDEN_OFFSET 31 + #define MX51_ECSPI_STAT0x18 #define MX51_ECSPI_STAT_RR (1 3) @@ -257,17 +300,22 @@ static void __maybe_unused mx51_ecspi_intctrl(struct spi_imx_data *spi_imx, int static void __maybe_unused mx51_ecspi_trigger(struct spi_imx_data *spi_imx) { - u32 reg; - - reg = readl(spi_imx-base + MX51_ECSPI_CTRL); - reg |= MX51_ECSPI_CTRL_XCH; + u32 reg = readl(spi_imx-base + MX51_ECSPI_CTRL); + + if (!spi_imx-usedma) + reg |= MX51_ECSPI_CTRL_XCH; + else if (!spi_imx-dma_finished) + reg |= MX51_ECSPI_CTRL_SMC; + else + reg = ~MX51_ECSPI_CTRL_SMC; writel(reg, spi_imx-base + MX51_ECSPI_CTRL); } static int __maybe_unused mx51_ecspi_config(struct
Re: [PATCH v5] spi: spi-imx: add DMA support
On 09/10/2014 07:00 AM, Robin Gong wrote: Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. (...) + +static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, +struct spi_master *master, +const struct resource *res) +{ + struct dma_slave_config slave_config = {}; + int ret; + + /* Prepare for TX DMA: */ + master-dma_tx = dma_request_slave_channel(dev, tx); + if (!master-dma_tx) { + dev_err(dev, cannot get the TX DMA channel!\n); + ret = -EINVAL; + goto err; + } + + slave_config.direction = DMA_MEM_TO_DEV; + slave_config.dst_addr = res-start + MXC_CSPITXDATA; + slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; + ret = dmaengine_slave_config(master-dma_tx, slave_config); + if (ret) { + dev_err(dev, error in TX dma configuration.); + Missed terminating new line.. -- Regards, Varka Bhadram. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH v5] spi: spi-imx: add DMA support
On Wed, Sep 10, 2014 at 09:46:04AM +0530, Varka Bhadram wrote: On 09/10/2014 07:00 AM, Robin Gong wrote: Enable DMA support on i.mx6. The read speed can increase from 600KB/s to 1.2MB/s on i.mx6q. You can disable or enable dma function in dts. (...) + +static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, + struct spi_master *master, + const struct resource *res) +{ +struct dma_slave_config slave_config = {}; +int ret; + +/* Prepare for TX DMA: */ +master-dma_tx = dma_request_slave_channel(dev, tx); +if (!master-dma_tx) { +dev_err(dev, cannot get the TX DMA channel!\n); +ret = -EINVAL; +goto err; +} + +slave_config.direction = DMA_MEM_TO_DEV; +slave_config.dst_addr = res-start + MXC_CSPITXDATA; +slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; +slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; +ret = dmaengine_slave_config(master-dma_tx, slave_config); +if (ret) { +dev_err(dev, error in TX dma configuration.); + Missed terminating new line.. You mean lack \n in the print info? If yes, I can improve it in v6. -- Regards, Varka Bhadram. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/