diff options
author | Leo Chen <leochen@broadcom.com> | 2009-08-07 20:00:39 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2009-08-15 16:01:40 +0100 |
commit | 7c4c2951c0077eecf9a9dfda59a43eedd09a01f4 (patch) | |
tree | 42db7b303dbd6e4a6dd943070f4c84aae7e4a8dd /arch/arm/mach-bcmring | |
parent | 661f78d80969eefb25a0e99c08c0eba81b37861e (diff) |
ARM: 5647/1: bcmring: add bcmring dma.h and dma_device.c
add bcmring dma.h and dma_device.c
Signed-off-by: Leo Chen <leochen@broadcom.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-bcmring')
-rw-r--r-- | arch/arm/mach-bcmring/dma_device.c | 593 | ||||
-rw-r--r-- | arch/arm/mach-bcmring/include/mach/dma.h | 826 |
2 files changed, 1419 insertions, 0 deletions
diff --git a/arch/arm/mach-bcmring/dma_device.c b/arch/arm/mach-bcmring/dma_device.c new file mode 100644 index 00000000000..ca0ad736870 --- /dev/null +++ b/arch/arm/mach-bcmring/dma_device.c @@ -0,0 +1,593 @@ +/***************************************************************************** +* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/****************************************************************************/ +/** +* @file dma_device.c +* +* @brief private array of DMA_DeviceAttribute_t +*/ +/****************************************************************************/ + +DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES] = { + [DMA_DEVICE_MEM_TO_MEM] = /* MEM 2 MEM */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, + .name = "mem-to-mem", + .config = { + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + + }, + }, + [DMA_DEVICE_VPM_MEM_TO_MEM] = /* VPM */ + { + .flags = DMA_DEVICE_FLAG_IS_DEDICATED | DMA_DEVICE_FLAG_NO_ISR, + .name = "vpm", + .dedicatedController = 0, + .dedicatedChannel = 0, + /* reserve DMA0:0 for VPM */ + }, + [DMA_DEVICE_NAND_MEM_TO_MEM] = /* NAND */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, + .name = "nand", + .config = { + .srcPeripheralPort = 0, + .dstPeripheralPort = 0, + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_6, + }, + }, + [DMA_DEVICE_PIF_MEM_TO_DEV] = /* PIF TX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1 + | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO + | DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST | DMA_DEVICE_FLAG_PORT_PER_DMAC, + .name = "pif_tx", + .dmacPort = {14, 5}, + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + /* dstPeripheralPort = 5 or 14 */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + .maxDataPerBlock = 16256, + }, + }, + [DMA_DEVICE_PIF_DEV_TO_MEM] = /* PIF RX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1 + | DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO + /* DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST */ + | DMA_DEVICE_FLAG_PORT_PER_DMAC, + .name = "pif_rx", + .dmacPort = {14, 5}, + .config = { + /* srcPeripheralPort = 5 or 14 */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + .maxDataPerBlock = 16256, + }, + }, + [DMA_DEVICE_I2S0_DEV_TO_MEM] = /* I2S RX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "i2s0_rx", + .config = { + .srcPeripheralPort = 0, /* SRC: I2S0 */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_I2S0_MEM_TO_DEV] = /* I2S TX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "i2s0_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 1, /* DST: I2S0 */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_I2S1_DEV_TO_MEM] = /* I2S1 RX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA1, + .name = "i2s1_rx", + .config = { + .srcPeripheralPort = 2, /* SRC: I2S1 */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_16, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_I2S1_MEM_TO_DEV] = /* I2S1 TX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA1, + .name = "i2s1_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 3, /* DST: I2S1 */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_16, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_ESW_MEM_TO_DEV] = /* ESW TX */ + { + .name = "esw_tx", + .flags = DMA_DEVICE_FLAG_IS_DEDICATED, + .dedicatedController = 1, + .dedicatedChannel = 3, + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 1, /* DST: ESW (MTP) */ + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_DISABLE, + /* DMAx_AHB_SSTATARy */ + .srcStatusRegisterAddress = 0x00000000, + /* DMAx_AHB_DSTATARy */ + .dstStatusRegisterAddress = 0x30490010, + /* DMAx_AHB_CFGy */ + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + /* DMAx_AHB_CTLy */ + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_0, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + }, + }, + [DMA_DEVICE_ESW_DEV_TO_MEM] = /* ESW RX */ + { + .name = "esw_rx", + .flags = DMA_DEVICE_FLAG_IS_DEDICATED, + .dedicatedController = 1, + .dedicatedChannel = 2, + .config = { + .srcPeripheralPort = 0, /* SRC: ESW (PTM) */ + .dstPeripheralPort = 0, /* DST: memory */ + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_DISABLE, + /* DMAx_AHB_SSTATARy */ + .srcStatusRegisterAddress = 0x30480010, + /* DMAx_AHB_DSTATARy */ + .dstStatusRegisterAddress = 0x00000000, + /* DMAx_AHB_CFGy */ + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + /* DMAx_AHB_CTLy */ + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_0, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + }, + }, + [DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM] = /* APM Codec A Ingress */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "apm_a_rx", + .config = { + .srcPeripheralPort = 2, /* SRC: Codec A Ingress FIFO */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV] = /* APM Codec A Egress */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "apm_a_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 3, /* DST: Codec A Egress FIFO */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM] = /* APM Codec B Ingress */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "apm_b_rx", + .config = { + .srcPeripheralPort = 4, /* SRC: Codec B Ingress FIFO */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV] = /* APM Codec B Egress */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "apm_b_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 5, /* DST: Codec B Egress FIFO */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM] = /* APM Codec C Ingress */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA1, + .name = "apm_c_rx", + .config = { + .srcPeripheralPort = 4, /* SRC: Codec C Ingress FIFO */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_APM_PCM0_DEV_TO_MEM] = /* PCM0 RX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "pcm0_rx", + .config = { + .srcPeripheralPort = 12, /* SRC: PCM0 */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_APM_PCM0_MEM_TO_DEV] = /* PCM0 TX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0, + .name = "pcm0_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 13, /* DST: PCM0 */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_APM_PCM1_DEV_TO_MEM] = /* PCM1 RX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA1, + .name = "pcm1_rx", + .config = { + .srcPeripheralPort = 14, /* SRC: PCM1 */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_4, + .blockTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_CONTINUOUS, + }, + }, + [DMA_DEVICE_APM_PCM1_MEM_TO_DEV] = /* PCM1 TX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA1, + .name = "pcm1_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 15, /* DST: PCM1 */ + .srcStatusRegisterAddress = 0, + .dstStatusRegisterAddress = 0, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_4, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_SPUM_DEV_TO_MEM] = /* SPUM RX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, + .name = "spum_rx", + .config = { + .srcPeripheralPort = 6, /* SRC: Codec A Ingress FIFO */ + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + /* Busrt size **MUST** be 16 for SPUM to work */ + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + /* on the RX side, SPU needs to be the flow controller */ + .flowControler = dmacHw_FLOW_CONTROL_PERIPHERAL, + }, + }, + [DMA_DEVICE_SPUM_MEM_TO_DEV] = /* SPUM TX */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, + .name = "spum_tx", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .dstPeripheralPort = 7, /* DST: SPUM */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .blockTransferInterrupt = dmacHw_INTERRUPT_DISABLE, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_32, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_32, + /* Busrt size **MUST** be 16 for SPUM to work */ + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_16, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_16, + .transferMode = dmacHw_TRANSFER_MODE_PERREQUEST, + }, + }, + [DMA_DEVICE_MEM_TO_VRAM] = /* MEM 2 VRAM */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, + .name = "mem-to-vram", + .config = { + .srcPeripheralPort = 0, /* SRC: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_1, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_2, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + }, + }, + [DMA_DEVICE_VRAM_TO_MEM] = /* VRAM 2 MEM */ + { + .flags = DMA_DEVICE_FLAG_ON_DMA0 | DMA_DEVICE_FLAG_ON_DMA1, + .name = "vram-to-mem", + .config = { + .dstPeripheralPort = 0, /* DST: memory */ + .srcStatusRegisterAddress = 0x00000000, + .dstStatusRegisterAddress = 0x00000000, + .srcUpdate = dmacHw_SRC_ADDRESS_UPDATE_MODE_INC, + .dstUpdate = dmacHw_DST_ADDRESS_UPDATE_MODE_INC, + .transferType = dmacHw_TRANSFER_TYPE_MEM_TO_MEM, + .srcMasterInterface = dmacHw_SRC_MASTER_INTERFACE_2, + .dstMasterInterface = dmacHw_DST_MASTER_INTERFACE_1, + .completeTransferInterrupt = dmacHw_INTERRUPT_ENABLE, + .errorInterrupt = dmacHw_INTERRUPT_ENABLE, + .channelPriority = dmacHw_CHANNEL_PRIORITY_7, + .srcMaxTransactionWidth = dmacHw_SRC_TRANSACTION_WIDTH_64, + .dstMaxTransactionWidth = dmacHw_DST_TRANSACTION_WIDTH_64, + .srcMaxBurstWidth = dmacHw_SRC_BURST_WIDTH_8, + .dstMaxBurstWidth = dmacHw_DST_BURST_WIDTH_8, + }, + }, +}; +EXPORT_SYMBOL(DMA_gDeviceAttribute); /* primarily for dma-test.c */ diff --git a/arch/arm/mach-bcmring/include/mach/dma.h b/arch/arm/mach-bcmring/include/mach/dma.h new file mode 100644 index 00000000000..847980c85c8 --- /dev/null +++ b/arch/arm/mach-bcmring/include/mach/dma.h @@ -0,0 +1,826 @@ +/***************************************************************************** +* Copyright 2004 - 2008 Broadcom Corporation. All rights reserved. +* +* Unless you and Broadcom execute a separate written software license +* agreement governing use of this software, this software is licensed to you +* under the terms of the GNU General Public License version 2, available at +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL"). +* +* Notwithstanding the above, under no circumstances may you combine this +* software in any way with any other Broadcom software provided under a +* license other than the GPL, without Broadcom's express prior written +* consent. +*****************************************************************************/ + +/****************************************************************************/ +/** +* @file dma.h +* +* @brief API definitions for the linux DMA interface. +*/ +/****************************************************************************/ + +#if !defined(ASM_ARM_ARCH_BCMRING_DMA_H) +#define ASM_ARM_ARCH_BCMRING_DMA_H + +/* ---- Include Files ---------------------------------------------------- */ + +#include <linux/kernel.h> +#include <linux/wait.h> +#include <linux/semaphore.h> +#include <csp/dmacHw.h> +#include <mach/timer.h> +#include <linux/scatterlist.h> +#include <linux/dma-mapping.h> +#include <linux/mm.h> +#include <linux/vmalloc.h> +#include <linux/pagemap.h> + +/* ---- Constants and Types ---------------------------------------------- */ + +/* If DMA_DEBUG_TRACK_RESERVATION is set to a non-zero value, then the filename */ +/* and line number of the reservation request will be recorded in the channel table */ + +#define DMA_DEBUG_TRACK_RESERVATION 1 + +#define DMA_NUM_CONTROLLERS 2 +#define DMA_NUM_CHANNELS 8 /* per controller */ + +typedef enum { + DMA_DEVICE_MEM_TO_MEM, /* For memory to memory transfers */ + DMA_DEVICE_I2S0_DEV_TO_MEM, + DMA_DEVICE_I2S0_MEM_TO_DEV, + DMA_DEVICE_I2S1_DEV_TO_MEM, + DMA_DEVICE_I2S1_MEM_TO_DEV, + DMA_DEVICE_APM_CODEC_A_DEV_TO_MEM, + DMA_DEVICE_APM_CODEC_A_MEM_TO_DEV, + DMA_DEVICE_APM_CODEC_B_DEV_TO_MEM, + DMA_DEVICE_APM_CODEC_B_MEM_TO_DEV, + DMA_DEVICE_APM_CODEC_C_DEV_TO_MEM, /* Additional mic input for beam-forming */ + DMA_DEVICE_APM_PCM0_DEV_TO_MEM, + DMA_DEVICE_APM_PCM0_MEM_TO_DEV, + DMA_DEVICE_APM_PCM1_DEV_TO_MEM, + DMA_DEVICE_APM_PCM1_MEM_TO_DEV, + DMA_DEVICE_SPUM_DEV_TO_MEM, + DMA_DEVICE_SPUM_MEM_TO_DEV, + DMA_DEVICE_SPIH_DEV_TO_MEM, + DMA_DEVICE_SPIH_MEM_TO_DEV, + DMA_DEVICE_UART_A_DEV_TO_MEM, + DMA_DEVICE_UART_A_MEM_TO_DEV, + DMA_DEVICE_UART_B_DEV_TO_MEM, + DMA_DEVICE_UART_B_MEM_TO_DEV, + DMA_DEVICE_PIF_MEM_TO_DEV, + DMA_DEVICE_PIF_DEV_TO_MEM, + DMA_DEVICE_ESW_DEV_TO_MEM, + DMA_DEVICE_ESW_MEM_TO_DEV, + DMA_DEVICE_VPM_MEM_TO_MEM, + DMA_DEVICE_CLCD_MEM_TO_MEM, + DMA_DEVICE_NAND_MEM_TO_MEM, + DMA_DEVICE_MEM_TO_VRAM, + DMA_DEVICE_VRAM_TO_MEM, + + /* Add new entries before this line. */ + + DMA_NUM_DEVICE_ENTRIES, + DMA_DEVICE_NONE = 0xff, /* Special value to indicate that no device is currently assigned. */ + +} DMA_Device_t; + +/**************************************************************************** +* +* The DMA_Handle_t is the primary object used by callers of the API. +* +*****************************************************************************/ + +#define DMA_INVALID_HANDLE ((DMA_Handle_t) -1) + +typedef int DMA_Handle_t; + +/**************************************************************************** +* +* The DMA_DescriptorRing_t contains a ring of descriptors which is used +* to point to regions of memory. +* +*****************************************************************************/ + +typedef struct { + void *virtAddr; /* Virtual Address of the descriptor ring */ + dma_addr_t physAddr; /* Physical address of the descriptor ring */ + int descriptorsAllocated; /* Number of descriptors allocated in the descriptor ring */ + size_t bytesAllocated; /* Number of bytes allocated in the descriptor ring */ + +} DMA_DescriptorRing_t; + +/**************************************************************************** +* +* The DMA_MemType_t and DMA_MemMap_t are helper structures used to setup +* DMA chains from a variety of memory sources. +* +*****************************************************************************/ + +#define DMA_MEM_MAP_MIN_SIZE 4096 /* Pages less than this size are better */ + /* off not being DMA'd. */ + +typedef enum { + DMA_MEM_TYPE_NONE, /* Not a valid setting */ + DMA_MEM_TYPE_VMALLOC, /* Memory came from vmalloc call */ + DMA_MEM_TYPE_KMALLOC, /* Memory came from kmalloc call */ + DMA_MEM_TYPE_DMA, /* Memory came from dma_alloc_xxx call */ + DMA_MEM_TYPE_USER, /* Memory came from user space. */ + +} DMA_MemType_t; + +/* A segment represents a physically and virtually contiguous chunk of memory. */ +/* i.e. each segment can be DMA'd */ +/* A user of the DMA code will add memory regions. Each region may need to be */ +/* represented by one or more segments. */ + +typedef struct { + void *virtAddr; /* Virtual address used for this segment */ + dma_addr_t physAddr; /* Physical address this segment maps to */ + size_t numBytes; /* Size of the segment, in bytes */ + +} DMA_Segment_t; + +/* A region represents a virtually contiguous chunk of memory, which may be */ +/* made up of multiple segments. */ + +typedef struct { + DMA_MemType_t memType; + void *virtAddr; + size_t numBytes; + + /* Each region (virtually contiguous) consists of one or more segments. Each */ + /* segment is virtually and physically contiguous. */ + + int numSegmentsUsed; + int numSegmentsAllocated; + DMA_Segment_t *segment; + + /* When a region corresponds to user memory, we need to lock all of the pages */ + /* down before we can figure out the physical addresses. The lockedPage array contains */ + /* the pages that were locked, and which subsequently need to be unlocked once the */ + /* memory is unmapped. */ + + unsigned numLockedPages; + struct page **lockedPages; + +} DMA_Region_t; + +typedef struct { + int inUse; /* Is this mapping currently being used? */ + struct semaphore lock; /* Acquired when using this structure */ + enum dma_data_direction dir; /* Direction this transfer is intended for */ + + /* In the event that we're mapping user memory, we need to know which task */ + /* the memory is for, so that we can obtain the correct mm locks. */ + + struct task_struct *userTask; + + int numRegionsUsed; + int numRegionsAllocated; + DMA_Region_t *region; + +} DMA_MemMap_t; + +/**************************************************************************** +* +* The DMA_DeviceAttribute_t contains information which describes a +* particular DMA device (or peripheral). +* +* It is anticipated that the arrary of DMA_DeviceAttribute_t's will be +* statically initialized. +* +*****************************************************************************/ + +/* The device handler is called whenever a DMA operation completes. The reaon */ +/* for it to be called will be a bitmask with one or more of the following bits */ +/* set. */ + +#define DMA_HANDLER_REASON_BLOCK_COMPLETE dmacHw_INTERRUPT_STATUS_BLOCK +#define DMA_HANDLER_REASON_TRANSFER_COMPLETE dmacHw_INTERRUPT_STATUS_TRANS +#define DMA_HANDLER_REASON_ERROR dmacHw_INTERRUPT_STATUS_ERROR + +typedef void (*DMA_DeviceHandler_t) (DMA_Device_t dev, int reason, + void *userData); + +#define DMA_DEVICE_FLAG_ON_DMA0 0x00000001 +#define DMA_DEVICE_FLAG_ON_DMA1 0x00000002 +#define DMA_DEVICE_FLAG_PORT_PER_DMAC 0x00000004 /* If set, it means that the port used on DMAC0 is different from the port used on DMAC1 */ +#define DMA_DEVICE_FLAG_ALLOC_DMA1_FIRST 0x00000008 /* If set, allocate from DMA1 before allocating from DMA0 */ +#define DMA_DEVICE_FLAG_IS_DEDICATED 0x00000100 +#define DMA_DEVICE_FLAG_NO_ISR 0x00000200 +#define DMA_DEVICE_FLAG_ALLOW_LARGE_FIFO 0x00000400 +#define DMA_DEVICE_FLAG_IN_USE 0x00000800 /* If set, device is in use on a channel */ + +/* Note: Some DMA devices can be used from multiple DMA Controllers. The bitmask is used to */ +/* determine which DMA controllers a given device can be used from, and the interface */ +/* array determeines the actual interface number to use for a given controller. */ + +typedef struct { + uint32_t flags; /* Bitmask of DMA_DEVICE_FLAG_xxx constants */ + uint8_t dedicatedController; /* Controller number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */ + uint8_t dedicatedChannel; /* Channel number to use if DMA_DEVICE_FLAG_IS_DEDICATED is set. */ + const char *name; /* Will show up in the /proc entry */ + + uint32_t dmacPort[DMA_NUM_CONTROLLERS]; /* Specifies the port number when DMA_DEVICE_FLAG_PORT_PER_DMAC flag is set */ + + dmacHw_CONFIG_t config; /* Configuration to use when DMA'ing using this device */ + + void *userData; /* Passed to the devHandler */ + DMA_DeviceHandler_t devHandler; /* Called when DMA operations finish. */ + + timer_tick_count_t transferStartTime; /* Time the current transfer was started */ + + /* The following statistical information will be collected and presented in a proc entry. */ + /* Note: With a contiuous bandwidth of 1 Gb/sec, it would take 584 years to overflow */ + /* a 64 bit counter. */ + + uint64_t numTransfers; /* Number of DMA transfers performed */ + uint64_t transferTicks; /* Total time spent doing DMA transfers (measured in timer_tick_count_t's) */ + uint64_t transferBytes; /* Total bytes transferred */ + uint32_t timesBlocked; /* Number of times a channel was unavailable */ + uint32_t numBytes; /* Last transfer size */ + + /* It's not possible to free memory which is allocated for the descriptors from within */ + /* the ISR. So make the presumption that a given device will tend to use the */ + /* same sized buffers over and over again, and we keep them around. */ + + DMA_DescriptorRing_t ring; /* Ring of descriptors allocated for this device */ + + /* We stash away some of the information from the previous transfer. If back-to-back */ + /* transfers are performed from the same buffer, then we don't have to keep re-initializing */ + /* the descriptor buffers. */ + + uint32_t prevNumBytes; + dma_addr_t prevSrcData; + dma_addr_t prevDstData; + +} DMA_DeviceAttribute_t; + +/**************************************************************************** +* +* DMA_Channel_t, DMA_Controller_t, and DMA_State_t are really internal +* data structures and don't belong in this header file, but are included +* merely for discussion. +* +* By the time this is implemented, these structures will be moved out into +* the appropriate C source file instead. +* +*****************************************************************************/ + +/**************************************************************************** +* +* The DMA_Channel_t contains state information about each DMA channel. Some +* of the channels are dedicated. Non-dedicated channels are shared +* amongst the other devices. +* +*****************************************************************************/ + +#define DMA_CHANNEL_FLAG_IN_USE 0x00000001 +#define DMA_CHANNEL_FLAG_IS_DEDICATED 0x00000002 +#define DMA_CHANNEL_FLAG_NO_ISR 0x00000004 +#define DMA_CHANNEL_FLAG_LARGE_FIFO 0x00000008 + +typedef struct { + uint32_t flags; /* bitmask of DMA_CHANNEL_FLAG_xxx constants */ + DMA_Device_t devType; /* Device this |