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>
This commit is contained in:
parent
661f78d809
commit
7c4c2951c0
2 changed files with 1419 additions and 0 deletions
593
arch/arm/mach-bcmring/dma_device.c
Normal file
593
arch/arm/mach-bcmring/dma_device.c
Normal file
|
@ -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 */
|
826
arch/arm/mach-bcmring/include/mach/dma.h
Normal file
826
arch/arm/mach-bcmring/include/mach/dma.h
Normal file
|
@ -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 channel is currently reserved for */
|
||||
DMA_Device_t lastDevType; /* Device type that used this previously */
|
||||
char name[20]; /* Name passed onto request_irq */
|
||||
|
||||
#if (DMA_DEBUG_TRACK_RESERVATION)
|
||||
const char *fileName; /* Place where channel reservation took place */
|
||||
int lineNum; /* Place where channel reservation took place */
|
||||
#endif
|
||||
dmacHw_HANDLE_t dmacHwHandle; /* low level channel handle. */
|
||||
|
||||
} DMA_Channel_t;
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* The DMA_Controller_t contains state information about each DMA controller.
|
||||
*
|
||||
* The freeChannelQ is stored in the controller data structure rather than
|
||||
* the channel data structure since several of the devices are accessible
|
||||
* from multiple controllers, and there is no way to know which controller
|
||||
* will become available first.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
DMA_Channel_t channel[DMA_NUM_CHANNELS];
|
||||
|
||||
} DMA_Controller_t;
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* The DMA_Global_t contains all of the global state information used by
|
||||
* the DMA code.
|
||||
*
|
||||
* Callers which need to allocate a shared channel will be queued up
|
||||
* on the freeChannelQ until a channel becomes available.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
struct semaphore lock; /* acquired when manipulating table entries */
|
||||
wait_queue_head_t freeChannelQ;
|
||||
|
||||
DMA_Controller_t controller[DMA_NUM_CONTROLLERS];
|
||||
|
||||
} DMA_Global_t;
|
||||
|
||||
/* ---- Variable Externs ------------------------------------------------- */
|
||||
|
||||
extern DMA_DeviceAttribute_t DMA_gDeviceAttribute[DMA_NUM_DEVICE_ENTRIES];
|
||||
|
||||
/* ---- Function Prototypes ---------------------------------------------- */
|
||||
|
||||
#if defined(__KERNEL__)
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initializes the DMA module.
|
||||
*
|
||||
* @return
|
||||
* 0 - Success
|
||||
* < 0 - Error
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_init(void);
|
||||
|
||||
#if (DMA_DEBUG_TRACK_RESERVATION)
|
||||
DMA_Handle_t dma_request_channel_dbg(DMA_Device_t dev, const char *fileName,
|
||||
int lineNum);
|
||||
#define dma_request_channel(dev) dma_request_channel_dbg(dev, __FILE__, __LINE__)
|
||||
#else
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Reserves a channel for use with @a dev. If the device is setup to use
|
||||
* a shared channel, then this function will block until a free channel
|
||||
* becomes available.
|
||||
*
|
||||
* @return
|
||||
* >= 0 - A valid DMA Handle.
|
||||
* -EBUSY - Device is currently being used.
|
||||
* -ENODEV - Device handed in is invalid.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
DMA_Handle_t dma_request_channel(DMA_Device_t dev /* Device to use with the allocated channel. */
|
||||
);
|
||||
#endif
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Frees a previously allocated DMA Handle.
|
||||
*
|
||||
* @return
|
||||
* 0 - DMA Handle was released successfully.
|
||||
* -EINVAL - Invalid DMA handle
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_free_channel(DMA_Handle_t channel /* DMA handle. */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Determines if a given device has been configured as using a shared
|
||||
* channel.
|
||||
*
|
||||
* @return boolean
|
||||
* 0 Device uses a dedicated channel
|
||||
* non-zero Device uses a shared channel
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_device_is_channel_shared(DMA_Device_t dev /* Device to check. */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Allocates memory to hold a descriptor ring. The descriptor ring then
|
||||
* needs to be populated by making one or more calls to
|
||||
* dna_add_descriptors.
|
||||
*
|
||||
* The returned descriptor ring will be automatically initialized.
|
||||
*
|
||||
* @return
|
||||
* 0 Descriptor ring was allocated successfully
|
||||
* -ENOMEM Unable to allocate memory for the desired number of descriptors.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_alloc_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to populate */
|
||||
int numDescriptors /* Number of descriptors that need to be allocated. */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Releases the memory which was previously allocated for a descriptor ring.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
void dma_free_descriptor_ring(DMA_DescriptorRing_t *ring /* Descriptor to release */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initializes a descriptor ring, so that descriptors can be added to it.
|
||||
* Once a descriptor ring has been allocated, it may be reinitialized for
|
||||
* use with additional/different regions of memory.
|
||||
*
|
||||
* Note that if 7 descriptors are allocated, it's perfectly acceptable to
|
||||
* initialize the ring with a smaller number of descriptors. The amount
|
||||
* of memory allocated for the descriptor ring will not be reduced, and
|
||||
* the descriptor ring may be reinitialized later
|
||||
*
|
||||
* @return
|
||||
* 0 Descriptor ring was initialized successfully
|
||||
* -ENOMEM The descriptor which was passed in has insufficient space
|
||||
* to hold the desired number of descriptors.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_init_descriptor_ring(DMA_DescriptorRing_t *ring, /* Descriptor ring to initialize */
|
||||
int numDescriptors /* Number of descriptors to initialize. */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Determines the number of descriptors which would be required for a
|
||||
* transfer of the indicated memory region.
|
||||
*
|
||||
* This function also needs to know which DMA device this transfer will
|
||||
* be destined for, so that the appropriate DMA configuration can be retrieved.
|
||||
* DMA parameters such as transfer width, and whether this is a memory-to-memory
|
||||
* or memory-to-peripheral, etc can all affect the actual number of descriptors
|
||||
* required.
|
||||
*
|
||||
* @return
|
||||
* > 0 Returns the number of descriptors required for the indicated transfer
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
|
||||
* -ENOMEM Memory exhausted
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_calculate_descriptor_count(DMA_Device_t device, /* DMA Device that this will be associated with */
|
||||
dma_addr_t srcData, /* Place to get data to write to device */
|
||||
dma_addr_t dstData, /* Pointer to device data address */
|
||||
size_t numBytes /* Number of bytes to transfer to the device */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Adds a region of memory to the descriptor ring. Note that it may take
|
||||
* multiple descriptors for each region of memory. It is the callers
|
||||
* responsibility to allocate a sufficiently large descriptor ring.
|
||||
*
|
||||
* @return
|
||||
* 0 Descriptors were added successfully
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
|
||||
* -ENOMEM Memory exhausted
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_add_descriptors(DMA_DescriptorRing_t *ring, /* Descriptor ring to add descriptors to */
|
||||
DMA_Device_t device, /* DMA Device that descriptors are for */
|
||||
dma_addr_t srcData, /* Place to get data (memory or device) */
|
||||
dma_addr_t dstData, /* Place to put data (memory or device) */
|
||||
size_t numBytes /* Number of bytes to transfer to the device */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the descriptor ring associated with a device.
|
||||
*
|
||||
* Once set, the descriptor ring will be associated with the device, even
|
||||
* across channel request/free calls. Passing in a NULL descriptor ring
|
||||
* will release any descriptor ring currently associated with the device.
|
||||
*
|
||||
* Note: If you call dma_transfer, or one of the other dma_alloc_ functions
|
||||
* the descriptor ring may be released and reallocated.
|
||||
*
|
||||
* Note: This function will release the descriptor memory for any current
|
||||
* descriptor ring associated with this device.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_set_device_descriptor_ring(DMA_Device_t device, /* Device to update the descriptor ring for. */
|
||||
DMA_DescriptorRing_t *ring /* Descriptor ring to add descriptors to */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Retrieves the descriptor ring associated with a device.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_get_device_descriptor_ring(DMA_Device_t device, /* Device to retrieve the descriptor ring for. */
|
||||
DMA_DescriptorRing_t *ring /* Place to store retrieved ring */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Allocates buffers for the descriptors. This is normally done automatically
|
||||
* but needs to be done explicitly when initiating a dma from interrupt
|
||||
* context.
|
||||
*
|
||||
* @return
|
||||
* 0 Descriptors were allocated successfully
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
|
||||
* -ENOMEM Memory exhausted
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_alloc_descriptors(DMA_Handle_t handle, /* DMA Handle */
|
||||
dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
|
||||
dma_addr_t srcData, /* Place to get data to write to device */
|
||||
dma_addr_t dstData, /* Pointer to device data address */
|
||||
size_t numBytes /* Number of bytes to transfer to the device */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Allocates and sets up descriptors for a double buffered circular buffer.
|
||||
*
|
||||
* This is primarily intended to be used for things like the ingress samples
|
||||
* from a microphone.
|
||||
*
|
||||
* @return
|
||||
* > 0 Number of descriptors actually allocated.
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
|
||||
* -ENOMEM Memory exhausted
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_alloc_double_dst_descriptors(DMA_Handle_t handle, /* DMA Handle */
|
||||
dma_addr_t srcData, /* Physical address of source data */
|
||||
dma_addr_t dstData1, /* Physical address of first destination buffer */
|
||||
dma_addr_t dstData2, /* Physical address of second destination buffer */
|
||||
size_t numBytes /* Number of bytes in each destination buffer */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initializes a DMA_MemMap_t data structure
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_init_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Releases any memory currently being held by a memory mapping structure.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_term_mem_map(DMA_MemMap_t *memMap /* Stores state information about the map */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Looks at a memory address and categorizes it.
|
||||
*
|
||||
* @return One of the values from the DMA_MemType_t enumeration.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
DMA_MemType_t dma_mem_type(void *addr);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Sets the process (aka userTask) associated with a mem map. This is
|
||||
* required if user-mode segments will be added to the mapping.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
static inline void dma_mem_map_set_user_task(DMA_MemMap_t *memMap,
|
||||
struct task_struct *task)
|
||||
{
|
||||
memMap->userTask = task;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Looks at a memory address and determines if we support DMA'ing to/from
|
||||
* that type of memory.
|
||||
*
|
||||
* @return boolean -
|
||||
* return value != 0 means dma supported
|
||||
* return value == 0 means dma not supported
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_mem_supports_dma(void *addr);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initializes a memory map for use. Since this function acquires a
|
||||
* sempaphore within the memory map, it is VERY important that dma_unmap
|
||||
* be called when you're finished using the map.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_map_start(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||
enum dma_data_direction dir /* Direction that the mapping will be going */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Adds a segment of memory to a memory map.
|
||||
*
|
||||
* @return 0 on success, error code otherwise.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_map_add_region(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||
void *mem, /* Virtual address that we want to get a map of */
|
||||
size_t numBytes /* Number of bytes being mapped */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Creates a descriptor ring from a memory mapping.
|
||||
*
|
||||
* @return 0 on sucess, error code otherwise.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_map_create_descriptor_ring(DMA_Device_t dev, /* DMA device (where the ring is stored) */
|
||||
DMA_MemMap_t *memMap, /* Memory map that will be used */
|
||||
dma_addr_t devPhysAddr /* Physical address of device */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Maps in a memory region such that it can be used for performing a DMA.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_map_mem(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||
void *addr, /* Virtual address that we want to get a map of */
|
||||
size_t count, /* Number of bytes being mapped */
|
||||
enum dma_data_direction dir /* Direction that the mapping will be going */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Maps in a memory region such that it can be used for performing a DMA.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_unmap(DMA_MemMap_t *memMap, /* Stores state information about the map */
|
||||
int dirtied /* non-zero if any of the pages were modified */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initiates a transfer when the descriptors have already been setup.
|
||||
*
|
||||
* This is a special case, and normally, the dma_transfer_xxx functions should
|
||||
* be used.
|
||||
*
|
||||
* @return
|
||||
* 0 Transfer was started successfully
|
||||
* -ENODEV Invalid handle
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_start_transfer(DMA_Handle_t handle);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Stops a previously started DMA transfer.
|
||||
*
|
||||
* @return
|
||||
* 0 Transfer was stopped successfully
|
||||
* -ENODEV Invalid handle
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_stop_transfer(DMA_Handle_t handle);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Waits for a DMA to complete by polling. This function is only intended
|
||||
* to be used for testing. Interrupts should be used for most DMA operations.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_wait_transfer_done(DMA_Handle_t handle);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initiates a DMA transfer
|
||||
*
|
||||
* @return
|
||||
* 0 Transfer was started successfully
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_transfer(DMA_Handle_t handle, /* DMA Handle */
|
||||
dmacHw_TRANSFER_TYPE_e transferType, /* Type of transfer being performed */
|
||||
dma_addr_t srcData, /* Place to get data to write to device */
|
||||
dma_addr_t dstData, /* Pointer to device data address */
|
||||
size_t numBytes /* Number of bytes to transfer to the device */
|
||||
);
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initiates a transfer from memory to a device.
|
||||
*
|
||||
* @return
|
||||
* 0 Transfer was started successfully
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _DEV_TO_MEM and not _MEM_TO_DEV)
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
static inline int dma_transfer_to_device(DMA_Handle_t handle, /* DMA Handle */
|
||||
dma_addr_t srcData, /* Place to get data to write to device (physical address) */
|
||||
dma_addr_t dstData, /* Pointer to device data address (physical address) */
|
||||
size_t numBytes /* Number of bytes to transfer to the device */
|
||||
) {
|
||||
return dma_transfer(handle,
|
||||
dmacHw_TRANSFER_TYPE_MEM_TO_PERIPHERAL,
|
||||
srcData, dstData, numBytes);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initiates a transfer from a device to memory.
|
||||
*
|
||||
* @return
|
||||
* 0 Transfer was started successfully
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device is _MEM_TO_DEV and not _DEV_TO_MEM)
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
static inline int dma_transfer_from_device(DMA_Handle_t handle, /* DMA Handle */
|
||||
dma_addr_t srcData, /* Pointer to the device data address (physical address) */
|
||||
dma_addr_t dstData, /* Place to store data retrieved from the device (physical address) */
|
||||
size_t numBytes /* Number of bytes to retrieve from the device */
|
||||
) {
|
||||
return dma_transfer(handle,
|
||||
dmacHw_TRANSFER_TYPE_PERIPHERAL_TO_MEM,
|
||||
srcData, dstData, numBytes);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Initiates a memory to memory transfer.
|
||||
*
|
||||
* @return
|
||||
* 0 Transfer was started successfully
|
||||
* -EINVAL Invalid device type for this kind of transfer
|
||||
* (i.e. the device wasn't DMA_DEVICE_MEM_TO_MEM)
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
static inline int dma_transfer_mem_to_mem(DMA_Handle_t handle, /* DMA Handle */
|
||||
dma_addr_t srcData, /* Place to transfer data from (physical address) */
|
||||
dma_addr_t dstData, /* Place to transfer data to (physical address) */
|
||||
size_t numBytes /* Number of bytes to transfer */
|
||||
) {
|
||||
return dma_transfer(handle,
|
||||
dmacHw_TRANSFER_TYPE_MEM_TO_MEM,
|
||||
srcData, dstData, numBytes);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
* Set the callback function which will be called when a transfer completes.
|
||||
* If a NULL callback function is set, then no callback will occur.
|
||||
*
|
||||
* @note @a devHandler will be called from IRQ context.
|
||||
*
|
||||
* @return
|
||||
* 0 - Success
|
||||
* -ENODEV - Device handed in is invalid.
|
||||
*/
|
||||
/****************************************************************************/
|
||||
|
||||
int dma_set_device_handler(DMA_Device_t dev, /* Device to set the callback for. */
|
||||
DMA_DeviceHandler_t devHandler, /* Function to call when the DMA completes */
|
||||
void *userData /* Pointer which will be passed to devHandler. */
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ASM_ARM_ARCH_BCMRING_DMA_H */
|
Loading…
Reference in a new issue