📄 xllp_dmac.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2001, 2002 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: xllp_dmac.c
**
** PURPOSE: contains all primitive functions for Bulverde DMA Controller register
** access and control
**
******************************************************************************/
#include "xllp_dmac.h"
#define XLLP_DMAC_DDADR_RESERVED_MASK 0xFFFFFFF0
#define XLLP_DMAC_DRCMR_ENABLE 0x80
#define XLLP_DMAC_DRCMR_DISABLE 0x00
/**
* DMA Controller channels
**/
XLLP_DMAC_CHANNEL_T pArrayChannel[32];
/**
* Points to shared area with all DMAC registers
*
* MUST DO:
* Modify to reflect the DMAC register block of your operating environment.
**/
volatile P_XLLP_DMAC_T pDmacHandle = 0;
/**
* Channel priority sets
**/
const XLLP_DMAC_CHANNEL_T aPrioritySetCount = 8;
const XLLP_DMAC_CHANNEL_T ChannelPriorityHigh[]=
{
XLLP_DMAC_CHANNEL_0,
XLLP_DMAC_CHANNEL_1,
XLLP_DMAC_CHANNEL_2,
XLLP_DMAC_CHANNEL_3,
XLLP_DMAC_CHANNEL_16,
XLLP_DMAC_CHANNEL_17,
XLLP_DMAC_CHANNEL_18,
XLLP_DMAC_CHANNEL_19
};
const XLLP_DMAC_CHANNEL_T ChannelPriorityMedium[]=
{
XLLP_DMAC_CHANNEL_4,
XLLP_DMAC_CHANNEL_5,
XLLP_DMAC_CHANNEL_6,
XLLP_DMAC_CHANNEL_7,
XLLP_DMAC_CHANNEL_20,
XLLP_DMAC_CHANNEL_21,
XLLP_DMAC_CHANNEL_22,
XLLP_DMAC_CHANNEL_23
};
const XLLP_DMAC_CHANNEL_T ChannelPriorityLow[]=
{
XLLP_DMAC_CHANNEL_8,
XLLP_DMAC_CHANNEL_9,
XLLP_DMAC_CHANNEL_10,
XLLP_DMAC_CHANNEL_11,
XLLP_DMAC_CHANNEL_24,
XLLP_DMAC_CHANNEL_25,
XLLP_DMAC_CHANNEL_26,
XLLP_DMAC_CHANNEL_27
};
const XLLP_DMAC_CHANNEL_T ChannelPriorityLowest[]=
{
XLLP_DMAC_CHANNEL_12,
XLLP_DMAC_CHANNEL_13,
XLLP_DMAC_CHANNEL_14,
XLLP_DMAC_CHANNEL_15,
XLLP_DMAC_CHANNEL_28,
XLLP_DMAC_CHANNEL_29,
XLLP_DMAC_CHANNEL_30,
XLLP_DMAC_CHANNEL_31
};
// This is only needed when running without the XLLP DMA Engine.
XLLP_STATUS_T XllpDmacInitHandle(P_XLLP_DMAC_T address)
{
pDmacHandle = address;
return 0;
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmaAllocChannel
Description: XllpDmacAllocChannel is used to obtain an available channel in
the system. The channel that is allocated must then be used to
bind a service routine to the operating system such that all
interrupts that occur on the channel will be routed to the bound
service routine. Once the channel is done transferring data, it
can be freed by using XllpDmacFreeChannel.
Global Registers Modified: None
Input Arguments:
aChannelPriority: Specifies the priority of the channel reqested
Output Arguments:
pChannel: Holds the available DMA channel assigned to the calling device
driver. DMA channels range is from 0-31.
Return Value:
XLLP_STATUS_SUCCESS: Returned when a channel is available and assigned to caller
XLLP_NO_DMA_CHANNELS_AVAILABLE: Returned when there is no available channel
to be assigned
XLLP_DOC_HDR_END
*******************************************************************************/
XLLP_STATUS_T XllpDmacAllocChannel(
P_XLLP_DMAC_CHANNEL_T pChannel,
XLLP_DMAC_CHANNEL_PRIORITY_T aChannelPriority
)
{
XLLP_DMAC_CHANNEL_T i;
XLLP_DMAC_CHANNEL_T aChannel;
switch(aChannelPriority)
{
case XLLP_DMAC_CHANNEL_PRIORITY_HIGH:
{
for (i=0; i < aPrioritySetCount; i++ )
{
aChannel = ChannelPriorityHigh[i];
if (pArrayChannel[aChannel] == 0)
{
pArrayChannel[aChannel] = 1; // Set this channel to InUse
*pChannel = aChannel;
return (XLLP_STATUS_SUCCESS); // Return no error
}
}
break;
}
case XLLP_DMAC_CHANNEL_PRIORITY_MEDIUM:
{
for (i=0; i < aPrioritySetCount; i++ )
{
aChannel = ChannelPriorityMedium[i];
if (pArrayChannel[aChannel] == 0)
{
pArrayChannel[aChannel] = 1; // Set this channel to InUse
*pChannel = aChannel;
return (XLLP_STATUS_SUCCESS); // Return no error
}
}
break;
}
case XLLP_DMAC_CHANNEL_PRIORITY_LOW:
{
for (i=0; i < aPrioritySetCount; i++ )
{
aChannel = ChannelPriorityLow[i];
if (pArrayChannel[aChannel] == 0)
{
pArrayChannel[aChannel] = 1; // Set this channel to InUse
*pChannel = aChannel;
return (XLLP_STATUS_SUCCESS); // Return no error
}
}
break;
}
case XLLP_DMAC_CHANNEL_PRIORITY_LOWEST:
{
for (i=0; i < aPrioritySetCount; i++ )
{
aChannel = ChannelPriorityLowest[i];
if (pArrayChannel[aChannel] == 0)
{
pArrayChannel[aChannel] = 1; // Set this channel to InUse
*pChannel = aChannel;
return (XLLP_STATUS_SUCCESS); // Return no error
}
}
break;
}
}
/*
* If we got this far, that means no channel was available for
* the specified channel priority set. So look for any available
* channel and return it
*/
for (i=0; i < XLLP_DMAC_CHANNEL_NUM; i++ )
{
if (pArrayChannel[i] == 0)
{
pArrayChannel[i] = 1; // Set this channel to InUse
*pChannel = i;
return (XLLP_STATUS_SUCCESS); // Return no error
}
}
return XLLP_STATUS_NO_DMA_CHANNEL_AVAILABLE; // No DMA channel is free
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmacFreeChannel
Description: XllpDmacFreeChannel is used to free a previously obtained channel
back into the free channels pool in the system. A channel that
is freed automatically becomes available for allocation when needed,
and all interrupts that were previously being generated to this
channel will be disconnected.
Global Registers Modified:
DMA request to channel map register, DRCMRx
Input Arguments:
aChannel: Channel to be freed and made available for other users.
aDeviceDrcmr: Specifies the device that was using the channel to be freed. Valid
inputs are elements of type XLLP_DMAC_DRCMR_T, otherwise is invalid.
Output Arguments:
None
Return Value:
None
XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacFreeChannel(
XLLP_DMAC_CHANNEL_T aChannel,
XLLP_DMAC_DRCMR_T aDeviceDrcmr
)
{
/* Verify if channel is currently set as InUse */
if (pArrayChannel[aChannel] == 1)
{
pArrayChannel[aChannel] = (XLLP_DMAC_CHANNEL_T)0; /* Free this channel*/
/* UnMap device from channel */
if (aDeviceDrcmr != XLLP_DMAC_MEM2MEM_MOVE)
{
XllpDmacUnMapDeviceToChannel(aDeviceDrcmr, aChannel);
}
}
}
/******************************************************************************
XLLP_DOC_HDR_BEGIN
Function Name: XllpDmacFillLinkedDesc
Description: XllpDmacFillLinkedDesc is used to setup a descriptor or chained
descriptors for DMA transfer operations. To setup a descriptor
(ie. no chaining), the pointer to the next descriptor pNextDesc
is expected to be zero, otherwise pNextDesc expected to be a
valid descriptor pointer. Users wanting to chain multiple
descriptors will call this function to accomplish that task.
Global Registers Modified:
None
Input Arguments:
pDesc: Hold the pointer to the descriptor to be configured, cannot be a
null pointer.
pNextDesc: Holds the pointer to the next descriptor used in the DMA transfer
process after completely transferring data in the current descriptor
pDesc if the channel is not programmed to be stop. pNextDesc can
be a null pointer only if this descriptor is not meant to be chained.
aStopContinue: Specifies whether or not to configure this descriptor to stop
the channel after completely transferring data in this descriptor.
aBranch: Specifies whether to configure this descriptor to enable or disable
the descriptor branching mechanism. Valid values are element of type
XLLP_DMAC_DESC_BRANCH_T (1 or 0).
aSrcAddr: Holds the source address for this descriptor, cannot be null.
aTargetAddr: Holds the target address for this descriptor, cannot be null.
pCmd: Holds the commands for this descriptor. Users are required to initialize
the various fields of pCmd data structure before making this call.
Output Arguments:
None
Return Value:
None
XLLP_DOC_HDR_END
*******************************************************************************/
void XllpDmacFillLinkedDesc(
P_XLLP_DMAC_DESCRIPTOR_T pDesc,
P_XLLP_DMAC_DESCRIPTOR_T pNextDescPhyAddr,
XLLP_DMAC_DESC_ENABLE_T aStopContinue,
XLLP_DMAC_DESC_BRANCH_T aBranch,
XLLP_UINT32_T aSrcAddr,
XLLP_UINT32_T aTargetAddr,
XLLP_DMAC_COMMAND_T* pCmd
)
{
XLLP_VUINT32_T aTargetValue;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -