summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-01-07 20:38:34 -0800
committerGary King <gking@nvidia.com>2010-01-08 20:20:13 -0800
commit5970e4c5c9f56836e74d4fd12c5c0746a4faa40c (patch)
tree11aee6624f58359df2445751adb0fce0cf9ac98f /arch
parent277f0cdec01d89637fa9f20dd7522ef504222fd7 (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.c29
-rw-r--r--arch/arm/mach-tegra/include/mach/nvrm_linux.h35
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/nvrm_dma.c23
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))