Message ID | 1363279254-22351-6-git-send-email-agust@denx.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Mar 14, 2013 at 05:40:53PM +0100, Anatolij Gustschin wrote: > Add SDHC DMA channel description to the mpc512x device > tree to enable slave channel requesting in the mxcmmc > driver. > > mpc512x DMA engine doesn't support endianness conversion > when reading/writing data from peripheral's FIFO, so we > have to swap data buffers before each DMA write and after > each DMA read transfer manually. > > Since chained SDHC DMA transfers are not supported on > mpc512x, limit 'max_segs' tunable parameter to one and > initialise it to 64 only when running on i.MX platforms. They are also not supported on the older i.MX platforms. Shouldn't this be handled in the DMA driver? Sascha
On Thu, 14 Mar 2013 21:11:39 +0100 Sascha Hauer <s.hauer@pengutronix.de> wrote: > On Thu, Mar 14, 2013 at 05:40:53PM +0100, Anatolij Gustschin wrote: > > Add SDHC DMA channel description to the mpc512x device > > tree to enable slave channel requesting in the mxcmmc > > driver. > > > > mpc512x DMA engine doesn't support endianness conversion > > when reading/writing data from peripheral's FIFO, so we > > have to swap data buffers before each DMA write and after > > each DMA read transfer manually. > > > > Since chained SDHC DMA transfers are not supported on > > mpc512x, limit 'max_segs' tunable parameter to one and > > initialise it to 64 only when running on i.MX platforms. > > They are also not supported on the older i.MX platforms. Shouldn't this > be handled in the DMA driver? This could be handled in the DMA driver, but up to now nobody cared to extend the DMA driver so. Anatolij -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index d1fe070..712b15a 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi @@ -152,6 +152,8 @@ compatible = "fsl,mpc5121-sdhc"; reg = <0x1500 0x100>; interrupts = <8 0x8>; + dmas = <&dma0 30>; + dma-names = "rx-tx"; }; i2c@1700 { diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index c0115e9..48e3fd8 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -343,6 +343,29 @@ static void mxcmci_softreset(struct mxcmci_host *host) } static int mxcmci_setup_dma(struct mmc_host *mmc); +#if IS_ENABLED(CONFIG_PPC_MPC512x) +static inline void buffer_swap32(u32 *buf, int len) +{ + int i; + + for (i = 0; i < ((len + 3) / 4); i++) { + st_le32(buf, *buf); + buf++; + } +} + +static void mxcmci_fixup_buffers(struct mmc_data *data) +{ + struct scatterlist *sg; + int i; + + for_each_sg(data->sg, sg, data->sg_len, i) + buffer_swap32(sg_virt(sg), sg->length); +} +#else +static inline void mxcmci_fixup_buffers(struct mmc_data *data) {} +#endif + static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) { unsigned int nob = data->blocks; @@ -378,6 +401,8 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data) } else { host->dma_dir = DMA_TO_DEVICE; slave_dirn = DMA_MEM_TO_DEV; + + mxcmci_fixup_buffers(data); } nents = dma_map_sg(host->dma->device->dev, data->sg, @@ -503,9 +528,11 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) struct mmc_data *data = host->data; int data_error; - if (mxcmci_use_dma(host)) + if (mxcmci_use_dma(host)) { dma_unmap_sg(host->dma->device->dev, data->sg, data->sg_len, host->dma_dir); + mxcmci_fixup_buffers(data); + } if (stat & STATUS_ERR_MASK) { dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n", @@ -1075,7 +1102,6 @@ static int mxcmci_probe(struct platform_device *pdev) mmc->caps |= MMC_CAP_SDIO_IRQ; /* MMC core transfer sizes tunable parameters */ - mmc->max_segs = 64; mmc->max_blk_size = 2048; mmc->max_blk_count = 65535; mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count; @@ -1096,6 +1122,11 @@ static int mxcmci_probe(struct platform_device *pdev) } else { host->devtype = pdev->id_entry->driver_data; } + + /* adjust max_segs after devtype detection */ + if (!is_mpc512x_mmc(host)) + mmc->max_segs = 64; + host->mmc = mmc; host->pdata = pdata; spin_lock_init(&host->lock);
Add SDHC DMA channel description to the mpc512x device tree to enable slave channel requesting in the mxcmmc driver. mpc512x DMA engine doesn't support endianness conversion when reading/writing data from peripheral's FIFO, so we have to swap data buffers before each DMA write and after each DMA read transfer manually. Since chained SDHC DMA transfers are not supported on mpc512x, limit 'max_segs' tunable parameter to one and initialise it to 64 only when running on i.MX platforms. Signed-off-by: Anatolij Gustschin <agust@denx.de> --- arch/powerpc/boot/dts/mpc5121.dtsi | 2 ++ drivers/mmc/host/mxcmmc.c | 35 +++++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-)