[PATCH] [3.3] ARM: tegra: use APB DMA for accessing APB devices
Colin Cross
ccross at android.com
Tue Oct 18 14:37:28 EDT 2011
On Tue, Oct 18, 2011 at 11:18 AM, Olof Johansson <olof at lixom.net> wrote:
> From: Jon Mayo <jmayo at nvidia.com>
>
> Tegra2 hangs if APB registers are accessed from the cpu during an
> apb dma operation. The workaround is to use apb dma to read/write the
> registers instead.
>
> There is a dependency loop between fuses, clocks, and APBDMA. If dma
> is enabled, fuse reads must go through APBDMA to avoid corruption due
> to a hw bug. APBDMA requires a clock to be enabled. Clocks must read
> a fuse to determine allowable cpu frequencies.
>
> Separate out the fuse DMA initialization, and allow the fuse read
> and write functions to be called without using DMA before the DMA
> initialization has been completed. Access to the fuses before APBDMA
> is initialized won't hit the hardware bug because nothing else can be
> using DMA.
>
> Original fuse registar access code from Varun Wadekar
> <vwadekar at nvidia.com>, improved by Colin Cross <ccross at android.com>
> and later moved to separate driver by Jon Mayo <jmayo at nvidia.com>.
>
> Signed-off-by: Jon Mayo <jmayo at nvidia.com>
> [olof: hooked up init calls to dma init, minor cleanups]
> Signed-off-by: Olof Johansson <olof at lixom.net>
> ---
> arch/arm/mach-tegra/Makefile | 1 +
> arch/arm/mach-tegra/apbio.c | 149 ++++++++++++++++++++++++++++++++++++++++++
> arch/arm/mach-tegra/apbio.h | 22 ++++++
> arch/arm/mach-tegra/dma.c | 4 +
> 4 files changed, 176 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-tegra/apbio.c
> create mode 100644 arch/arm/mach-tegra/apbio.h
>
<snip>
> diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
> index c0cf967..b7b6957 100644
> --- a/arch/arm/mach-tegra/dma.c
> +++ b/arch/arm/mach-tegra/dma.c
> @@ -33,6 +33,8 @@
> #include <mach/iomap.h>
> #include <mach/suspend.h>
>
> +#include "apbio.h"
> +
> #define APB_DMA_GEN 0x000
> #define GEN_ENABLE (1<<31)
>
> @@ -735,6 +737,8 @@ int __init tegra_dma_init(void)
>
> tegra_dma_initialized = true;
>
> + tegra_init_apb_dma();
> +
It seems wrong for the dma api init to call init on one of the users
of the dma api. For explicit ordering dependencies like this, maybe
postcore_initcall is not the right way to trigger tegra_dma_init.
> return 0;
> fail:
> writel(0, addr + APB_DMA_GEN);
> --
> 1.7.4.1
>
>
More information about the linux-arm-kernel
mailing list