[U-Boot] [PATCH 1/5] mmc: Tegra2: Support DMA restarts at buffer boundaries

Anton Staaf robotboy at chromium.org
Fri Oct 28 19:54:55 CEST 2011


On Thu, Oct 13, 2011 at 2:57 PM, Anton Staaf <robotboy at chromium.org> wrote:
> Currently if a DMA buffer straddles a buffer alignment boundary
> (512KiB) then the DMA engine will pause and generate a DMA
> interrupt.  Since the DMA interrupt is not enabled it will hang
> the MMC driver.
>
> This patch adds support for restarting the DMA transfer.  The
> SYSTEM_ADDRESS register contains the next address that would have
> been read/written when a boundary is hit.  So we can read that
> and write it back.  The write triggers the resumption of the
> transfer.
>
> Signed-off-by: Anton Staaf <robotboy at chromium.org>
> Cc: Tom Warren <twarren at nvidia.com>
> Cc: Stephen Warren <swarren at nvidia.com>

Adding Albert to CC.

-Anton

> ---
>  drivers/mmc/tegra2_mmc.c |   15 +++++++++++----
>  1 files changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/mmc/tegra2_mmc.c b/drivers/mmc/tegra2_mmc.c
> index 8b6f829..195f89d 100644
> --- a/drivers/mmc/tegra2_mmc.c
> +++ b/drivers/mmc/tegra2_mmc.c
> @@ -256,9 +256,15 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
>                                                __func__, mask);
>                                return -1;
>                        } else if (mask & (1 << 3)) {
> -                               /* DMA Interrupt */
> +                               /*
> +                                * DMA Interrupt, restart the transfer where
> +                                * it was interrupted.
> +                                */
> +                               unsigned int address = readl(&host->reg->sysad);
> +
>                                debug("DMA end\n");
> -                               break;
> +                               writel((1 << 3), &host->reg->norintsts);
> +                               writel(address, &host->reg->sysad);
>                        } else if (mask & (1 << 1)) {
>                                /* Transfer Complete */
>                                debug("r/w is done\n");
> @@ -442,12 +448,13 @@ static int mmc_core_init(struct mmc *mmc)
>         * NORMAL Interrupt Status Enable Register init
>         * [5] ENSTABUFRDRDY : Buffer Read Ready Status Enable
>         * [4] ENSTABUFWTRDY : Buffer write Ready Status Enable
> +        * [3] ENSTADMAINT : DMA Interrupt Status Enable
>         * [1] ENSTASTANSCMPLT : Transfre Complete Status Enable
>         * [0] ENSTACMDCMPLT : Command Complete Status Enable
> -       */
> +        */
>        mask = readl(&host->reg->norintstsen);
>        mask &= ~(0xffff);
> -       mask |= (1 << 5) | (1 << 4) | (1 << 1) | (1 << 0);
> +       mask |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 1) | (1 << 0);
>        writel(mask, &host->reg->norintstsen);
>
>        /*
> --
> 1.7.3.1
>
>


More information about the U-Boot mailing list