diff options
author | Gary King <gking@nvidia.com> | 2010-01-07 20:38:34 -0800 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-01-08 20:20:13 -0800 |
commit | 5970e4c5c9f56836e74d4fd12c5c0746a4faa40c (patch) | |
tree | 11aee6624f58359df2445751adb0fce0cf9ac98f /arch | |
parent | 277f0cdec01d89637fa9f20dd7522ef504222fd7 (diff) |
tegra DMA: improve integration of system DMA driver with RM DMA
add a function to the RM DMA code to return the number of unreserved
(RM DMA-managed) APB DMA channels, and use that as the starting offset
for system DMA driver managed channels
reserve 2 DMA channels for each high-speed (native driver) uart
Change-Id: Ib078f7ba32b887bc06d9f04219a30594c56435a5
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/dma.c | 29 | ||||
-rw-r--r-- | arch/arm/mach-tegra/include/mach/nvrm_linux.h | 35 | ||||
-rw-r--r-- | arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c | 23 |
3 files changed, 47 insertions, 40 deletions
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c index 3d6ed3e3c56e..064ac861a3c7 100644 --- a/arch/arm/mach-tegra/dma.c +++ b/arch/arm/mach-tegra/dma.c @@ -90,11 +90,6 @@ struct tegra_dma_channel { #define NV_DMA_MAX_CHANNELS 32 -/* We are only allowed to use the channels in the following range, others are - * used by different code base */ -#define NV_DMA_CHANNEL_MIN 12 -#define NV_DMA_CHANNEL_MAX 12 - static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS); static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS]; @@ -263,14 +258,14 @@ int tegra_dma_allocate_channel(int mode) int channel; struct tegra_dma_channel *ch; - /* NV_DMA_CHANNEL_MIN in the shared channel */ + /* first channel is the shared channel */ if (mode & TEGRA_DMA_SHARED) { - channel = NV_DMA_CHANNEL_MIN; + channel = TEGRA_SYSTEM_DMA_CH_MIN; } else { channel = find_first_zero_bit(channel_usage, - NV_DMA_MAX_CHANNELS); - if (channel > NV_DMA_MAX_CHANNELS) + ARRAY_SIZE(dma_channels)); + if (channel >= ARRAY_SIZE(dma_channels)) return -ENODEV; } __set_bit(channel, channel_usage); @@ -284,7 +279,8 @@ void tegra_dma_free_channel(int channel) { struct tegra_dma_channel *ch; - if (channel < NV_DMA_CHANNEL_MIN && channel >= NV_DMA_CHANNEL_MAX) + if (channel < TEGRA_SYSTEM_DMA_CH_MIN || + channel >= TEGRA_SYSTEM_DMA_CH_MAX) return; ch = &dma_channels[channel]; @@ -565,12 +561,13 @@ int __init tegra_dma_init(void) BUG_ON(max_channels > NV_DMA_MAX_CHANNELS); /* Reserve all the channels we are not supposed to touch */ - for (i=0; i< NV_DMA_MAX_CHANNELS; i++) { - if ((i < NV_DMA_CHANNEL_MIN) || (i >= NV_DMA_CHANNEL_MAX)) - __set_bit(i, channel_usage); - } + for (i=0; i<TEGRA_SYSTEM_DMA_CH_MIN; i++) + __set_bit(i, channel_usage); + + for (i=TEGRA_SYSTEM_DMA_CH_MAX; i<ARRAY_SIZE(dma_channels); i++) + __set_bit(i, channel_usage); - for (i = NV_DMA_CHANNEL_MIN; i < NV_DMA_CHANNEL_MAX; i++) { + for (i=TEGRA_SYSTEM_DMA_CH_MIN; i<TEGRA_SYSTEM_DMA_CH_MAX; i++) { struct tegra_dma_channel *ch = &dma_channels[i]; ch->id = i; @@ -591,7 +588,7 @@ int __init tegra_dma_init(void) tegra_dma_init_hw(ch); } - for (i = NV_DMA_CHANNEL_MIN; i < NV_DMA_CHANNEL_MAX; i++) { + for (i=TEGRA_SYSTEM_DMA_CH_MIN; i<TEGRA_SYSTEM_DMA_CH_MAX; i++) { irq = NvRmGetIrqForLogicalInterrupt(s_hRmGlobal, NvRmPrivModuleID_ApbDma, i); printk("Irq value = %d\n", irq); diff --git a/arch/arm/mach-tegra/include/mach/nvrm_linux.h b/arch/arm/mach-tegra/include/mach/nvrm_linux.h index efb9375dc521..035de018f01d 100644 --- a/arch/arm/mach-tegra/include/mach/nvrm_linux.h +++ b/arch/arm/mach-tegra/include/mach/nvrm_linux.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008-2009 NVIDIA Corporation. + * Copyright (c) 2008-2010 NVIDIA Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -56,20 +56,31 @@ extern NvRmDeviceHandle s_hRmGlobal; extern NvRmGpioHandle s_hGpioGlobal; -int tegra_get_partition_info_by_name( - const char *PartName, - NvU64 *pSectorStart, - NvU64 *pSectorLength, - NvU32 *pSectorSize); +int tegra_get_partition_info_by_name(const char *PartName, + NvU64 *pSectorStart, NvU64 *pSectorLength, NvU32 *pSectorSize); -int tegra_get_partition_info_by_num( - int PartitionNum, - char **pName, - NvU64 *pSectorStart, - NvU64 *pSectorEnd, - NvU32 *pSectorSize); +int tegra_get_partition_info_by_num(int PartitionNum, char **pName, + NvU64 *pSectorStart, NvU64 *pSectorEnd, NvU32 *pSectorSize); int tegra_was_boot_device(const char *pBootDev); +NvU32 NvRmDmaUnreservedChannels(void); + +#ifndef CONFIG_SERIAL_TEGRA_UARTS +#define TEGRA_SYSTEM_DMA_CH_UART 0 +#else +#define TEGRA_SYSTEM_DMA_CH_UART (2*CONFIG_SERIAL_TEGRA_UARTS) +#endif + +#ifdef CONFIG_TEGRA_SYSTEM_DMA +#define TEGRA_SYSTEM_DMA_CH_NUM (1 + TEGRA_SYSTEM_DMA_CH_UART) +#else +#define TEGRA_SYSTEM_DMA_CH_NUM (0) +#endif + +/* DMA channels available to system DMA driver */ +#define TEGRA_SYSTEM_DMA_CH_MIN NvRmDmaUnreservedChannels() +#define TEGRA_SYSTEM_DMA_CH_MAX \ + (TEGRA_SYSTEM_DMA_CH_MIN+TEGRA_SYSTEM_DMA_CH_NUM) #endif diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c index 0a798f4f4efe..a08f1d47a98b 100644 --- a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c +++ b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c @@ -133,6 +133,7 @@ #include "rm_dma_hw_private.h" #include "nvassert.h" #include "nvrm_priv_ap_general.h" +#include "mach/nvrm_linux.h" /* FIXME move these to some header file */ NvError NvRmPrivDmaInit(NvRmDeviceHandle hDevice); @@ -141,7 +142,6 @@ NvError NvRmPrivDmaSuspend(void); NvError NvRmPrivDmaResume(void); #define MAX_AVP_DMA_CHANNELS 3 -#define MAX_RESERVED_DMA_CHANNELS 3 // DMA capabilities -- these currently do not vary between chips @@ -394,6 +394,13 @@ static DmaHwInterface s_ApbDmaInterface; static NvOsInterruptHandle s_ApbDmaInterruptHandle = NULL; #endif +NvU32 NvRmDmaUnreservedChannels(void) +{ + return s_DmaInfo.NumApbDmaChannels - MAX_AVP_DMA_CHANNELS - + TEGRA_SYSTEM_DMA_CH_NUM; +} + + /** * Deinitialize the apb dma physical/virtual addresses. This function will * unmap the virtual mapping. @@ -969,7 +976,6 @@ static NvError RegisterAllDmaInterrupt(NvRmDeviceHandle hDevice) NvOsInterruptHandler DmaIntHandler = ApbDmaIsr; NvU32 Irq = 0; NvU32 i; - NvU32 n; /* Disable interrupts for all channels */ for (i=0; i < s_DmaInfo.NumApbDmaChannels; i++) @@ -979,9 +985,7 @@ static NvError RegisterAllDmaInterrupt(NvRmDeviceHandle hDevice) #if NVOS_IS_LINUX /* Register same interrupt hanlder for all APB DMA channels. */ - n = s_DmaInfo.NumApbDmaChannels - MAX_RESERVED_DMA_CHANNELS - - MAX_AVP_DMA_CHANNELS; - for (i=0; i < n; i++) + for (i=0; i < NvRmDmaUnreservedChannels(); i++) { Irq = NvRmGetIrqForLogicalInterrupt(hDevice, ModuleId, i); Error = NvRmInterruptRegister(hDevice, 1, &Irq, @@ -1015,11 +1019,8 @@ static void UnregisterAllDmaInterrupt(NvRmDeviceHandle hDevice) { #if NVOS_IS_LINUX NvU32 i; - NvU32 n; - n = s_DmaInfo.NumApbDmaChannels - MAX_RESERVED_DMA_CHANNELS - - MAX_AVP_DMA_CHANNELS; - for (i=0; i < n; i++) + for (i=0; i < NvRmDmaUnreservedChannels(); i++) { NvRmInterruptUnregister(hDevice, s_DmaInfo.pListApbDmaChannel[i].hIntrHandle); @@ -1326,7 +1327,6 @@ NvRmDmaAllocate( NvU32 UniqueId; RmDmaChannel *pDmaChannel = NULL; NvRmDmaHandle hNewDma = NULL; - NvU32 MaxChannel; RmDmaChannel *pChannelList = NULL; NvU32 ChanIndex; @@ -1385,13 +1385,12 @@ NvRmDmaAllocate( // For high priority dma channel request, use the free channel. And for low // priority channel use the used channel low priority channels. - MaxChannel = s_DmaInfo.NumApbDmaChannels - MAX_AVP_DMA_CHANNELS - MAX_RESERVED_DMA_CHANNELS; pChannelList = s_DmaInfo.pListApbDmaChannel; // Going to access the data which is shared across the different thread. NvOsMutexLock(s_DmaInfo.hDmaAllocMutex); - for (ChanIndex = 0; ChanIndex < MaxChannel; ++ChanIndex) + for (ChanIndex = 0; ChanIndex < NvRmDmaUnreservedChannels(); ++ChanIndex) { pDmaChannel = &pChannelList[ChanIndex]; if ((Priority == pDmaChannel->Priority) && (pDmaChannel->ChannelState == RmDmaChannelState_Free)) |