blob: 2bcc967b05a847fbb7d4595c21e1c10464073a41 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-3-Clause */
/**
* \file edma.c
*
* \brief This file contains device abstraction layer APIs for the EDMA device.
* There are APIs here to enable the EDMA instance, set the required
* configurations for communication, transmit or receive data.
*/
/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
*
* Neither the name of Texas Instruments Incorporated nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/* Driver APIs */
#include <utils/attribute.h>
#include <ethdrivers/plat/edma.h>
#include <ethdrivers/plat/hw/hw_types.h>
/****************************************************************************/
/* GLOBAL VARIABLES */
/****************************************************************************/
unsigned int regionId;
/****************************************************************************/
/* API FUNCTION DEFINITIONS */
/****************************************************************************/
/**
* \brief EDMA3 Initialization
*
* This function initializes the EDMA3 Driver
* Clears the error specific registers (EMCR/EMCRh, QEMCR, CCERRCLR) &
* initialize the Queue Number Registers
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param queNum Event Queue Number to which the channel
* will be mapped (valid only for the
* Master Channel (DMA/QDMA) request).\n
*
* \return None
*
* \note The regionId is the shadow region(0 or 1) used and the,
* Event Queue used is either (0 or 1). There are only four shadow
* regions and only two event Queues
*/
void EDMA3Init(unsigned int baseAdd,
unsigned int queNum)
{
unsigned int count = 0;
unsigned int i = 0;
#ifdef _TMS320C6X
/* For DSP, regionId is assigned here and used globally in the driver */
regionId = (unsigned int)1u;
#else
/* FOR ARM, regionId is assigned here and used globally in the driver */
regionId = (unsigned int)0u;
#endif
/* Clear the Event miss Registers */
HWREG(baseAdd + EDMA3CC_EMCR) = EDMA3_SET_ALL_BITS;
HWREG(baseAdd + EDMA3CC_EMCRH) = EDMA3_SET_ALL_BITS;
HWREG(baseAdd + EDMA3CC_QEMCR) = EDMA3_SET_ALL_BITS;
/* Clear CCERR register */
HWREG(baseAdd + EDMA3CC_CCERRCLR) = EDMA3_SET_ALL_BITS;
/* FOR TYPE EDMA*/
/* Enable the DMA (0 - 64) channels in the DRAE and DRAEH register */
HWREG(baseAdd + EDMA3CC_DRAE(regionId)) = EDMA3_SET_ALL_BITS;
HWREG(baseAdd + EDMA3CC_DRAEH(regionId)) = EDMA3_SET_ALL_BITS;
if ((EDMA_REVID_AM335X == EDMAVersionGet())) {
for (i = 0; i < 64; i++) {
/* All events are one to one mapped with the channels */
HWREG(baseAdd + EDMA3CC_DCHMAP(i)) = i << 5;
}
}
/* Initialize the DMA Queue Number Registers */
for (count = 0; count < SOC_EDMA3_NUM_DMACH; count++) {
HWREG(baseAdd + EDMA3CC_DMAQNUM(count >> 3u)) &=
EDMA3CC_DMAQNUM_CLR(count);
HWREG(baseAdd + EDMA3CC_DMAQNUM(count >> 3u)) |=
EDMA3CC_DMAQNUM_SET(count, queNum);
}
/* FOR TYPE QDMA */
/* Enable the DMA (0 - 64) channels in the DRAE register */
HWREG(baseAdd + EDMA3CC_QRAE(regionId)) = EDMA3_SET_ALL_BITS;
/* Initialize the QDMA Queue Number Registers */
for (count = 0; count < SOC_EDMA3_NUM_QDMACH; count++) {
HWREG(baseAdd + EDMA3CC_QDMAQNUM) &= EDMA3CC_QDMAQNUM_CLR(count);
HWREG(baseAdd + EDMA3CC_QDMAQNUM) |=
EDMA3CC_QDMAQNUM_SET(count, queNum);
}
}
/**
* \brief This API return the revision Id of the peripheral.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return None
*/
unsigned int EDMA3PeripheralIdGet(unsigned int baseAdd)
{
return (HWREG(baseAdd + EDMA3CC_REVID));
}
/**
* \brief Enable channel to Shadow region mapping
*
* This API allocates DMA/QDMA channels or TCCs, and the same resources are
* enabled in the shadow region specific register (DRAE/DRAEH/QRAE).
* Here only one shadow region is used since, there is only one Master.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chtype (DMA/QDMA) Channel
* For Example: For DMA it is,
* EDMA3_CHANNEL_TYPE_DMA.\n
*
* \param chNum Allocated channel number.\n
*
* chtype can have values
* EDMA3_CHANNEL_TYPE_DMA\n
* EDMA3_CHANNEL_TYPE_QDMA
*
* \return None
*/
void EDMA3EnableChInShadowReg(unsigned int baseAdd,
unsigned int chType,
unsigned int chNum)
{
/* Allocate the DMA/QDMA channel */
if (EDMA3_CHANNEL_TYPE_DMA == chType) {
/* FOR TYPE EDMA*/
if (chNum < 32) {
/* Enable the DMA channel in the DRAE registers */
HWREG(baseAdd + EDMA3CC_DRAE(regionId)) |= (0x01u << chNum);
} else {
/* Enable the DMA channel in the DRAEH registers */
HWREG(baseAdd + EDMA3CC_DRAEH(regionId)) |= (0x01u << (chNum - 32));
}
} else if (EDMA3_CHANNEL_TYPE_QDMA == chType) {
/* FOR TYPE QDMA */
/* Enable the QDMA channel in the DRAE/DRAEH registers */
HWREG(baseAdd + EDMA3CC_QRAE(regionId)) |= 0x01u << chNum;
}
}
/**
* \brief Disable channel to Shadow region mapping
*
* This API allocates DMA/QDMA channels or TCCs, and the same resources are
* enabled in the shadow region specific register (DRAE/DRAEH/QRAE).
* Here only one shadow region is used since, there is only one Master.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chtype (DMA/QDMA) Channel
* For Example: For DMA it is,
* EDMA3_CHANNEL_TYPE_DMA.\n
*
* \param chNum Allocated channel number.\n
*
* chtype can have values
* EDMA3_CHANNEL_TYPE_DMA\n
* EDMA3_CHANNEL_TYPE_QDMA
*
* \return None
*/
void EDMA3DisableChInShadowReg(unsigned int baseAdd,
unsigned int chType,
unsigned int chNum)
{
/* Allocate the DMA/QDMA channel */
if (EDMA3_CHANNEL_TYPE_DMA == chType) {
/* FOR TYPE EDMA*/
if (chNum < 32) {
/* Enable the DMA channel in the DRAE registers */
HWREG(baseAdd + EDMA3CC_DRAE(regionId)) &= ~(0x01u << chNum);
} else {
/* Enable the DMA channel in the DRAEH registers */
HWREG(baseAdd + EDMA3CC_DRAEH(regionId)) &= ~(0x01u << (chNum - 32));
}
} else if (EDMA3_CHANNEL_TYPE_QDMA == chType) {
/* FOR TYPE QDMA */
/* Enable the QDMA channel in the DRAE/DRAEH registers */
HWREG(baseAdd + EDMA3CC_QRAE(regionId)) &= ((~0x01u) << chNum);
}
}
/**
* \brief This function maps DMA channel to any of the PaRAM sets
* in the PaRAM memory map.
*
* \param baseAdd Memory address of the EDMA instance used.
*
* \param channel The DMA channel number required to be mapped.
*
* \param paramSet It specifies the paramSet to which DMA channel
* required to be mapped.
*
* \return None
*/
void EDMA3ChannelToParamMap(unsigned int baseAdd,
unsigned int channel,
unsigned int paramSet)
{
HWREG(baseAdd + EDMA3CC_DCHMAP(channel)) = paramSet << 5;
}
/**
* \brief Map channel to Event Queue
*
* This API maps DMA/QDMA channels to the Event Queue
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chtype (DMA/QDMA) Channel
* For Example: For QDMA it is
* EDMA3_CHANNEL_TYPE_QDMA.\n
*
* \param chNum Allocated channel number.\n
*
* \param evtQNum Event Queue Number to which the channel
* will be mapped (valid only for the
* Master Channel (DMA/QDMA) request).\n
*
* chtype can have values
* EDMA3_CHANNEL_TYPE_DMA\n
* EDMA3_CHANNEL_TYPE_QDMA
*
* \return None
*/
void EDMA3MapChToEvtQ(unsigned int baseAdd,
unsigned int chType,
unsigned int chNum,
unsigned int evtQNum)
{
if (EDMA3_CHANNEL_TYPE_DMA == chType) {
/* Associate DMA Channel to Event Queue */
HWREG(baseAdd + EDMA3CC_DMAQNUM((chNum) >> 3u)) &=
EDMA3CC_DMAQNUM_CLR(chNum);
HWREG(baseAdd + EDMA3CC_DMAQNUM((chNum) >> 3u)) |=
EDMA3CC_DMAQNUM_SET((chNum), evtQNum);
} else if (EDMA3_CHANNEL_TYPE_QDMA == chType) {
/* Associate QDMA Channel to Event Queue */
HWREG(baseAdd + EDMA3CC_QDMAQNUM) |=
EDMA3CC_QDMAQNUM_SET(chNum, evtQNum);
}
}
/**
* \brief Remove Mapping of channel to Event Queue
*
* This API Unmaps DMA/QDMA channels to the Event Queue allocated
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chtype (DMA/QDMA) Channel
* For Example: For DMA it is
* EDMA3_CHANNEL_TYPE_DMA.\n
*
* \param chNum Allocated channel number.\n
*
* chtype can have values
* EDMA3_CHANNEL_TYPE_DMA\n
* EDMA3_CHANNEL_TYPE_QDMA
*
* \return None
*/
void EDMA3UnmapChToEvtQ(unsigned int baseAdd,
unsigned int chType,
unsigned int chNum)
{
if (EDMA3_CHANNEL_TYPE_DMA == chType) {
/* Unmap DMA Channel to Event Queue */
HWREG(baseAdd + EDMA3CC_DMAQNUM((chNum) >> 3u)) |=
EDMA3CC_DMAQNUM_CLR(chNum);
} else if (EDMA3_CHANNEL_TYPE_QDMA == chType) {
/* Unmap QDMA Channel to Event Queue */
HWREG(baseAdd + EDMA3CC_QDMAQNUM) |=
EDMA3CC_QDMAQNUM_CLR(chNum);
}
}
/**
* \brief Enables the user to map a QDMA channel to PaRAM set
* This API Needs to be called before programming the paRAM sets for
* the QDMA Channels.Application needs to maitain the paRAMId
* provided by this API.This paRAMId is used to set paRAM and get
* paRAM. Refer corresponding API's for more details.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated QDMA channel number.\n
*
* \param paRaMID PaRAM Id to which the QDMA channel will be
* mapped to.
*
* \return None
*
* Note : The PaRAMId requested must be greater than 32(SOC_EDMA3_NUM_DMACH).
* and lesser than SOC_EDMA3_NUM_DMACH + chNum Because, the first
* 32 PaRAM's are directly mapped to first 32 DMA channels and (32 - 38)
* for QDMA Channels. (32 - 38) is assigned by driver in this API.
*
*/
void EDMA3MapQdmaChToPaRAM(unsigned int baseAdd,
unsigned int chNum,
unsigned int *paRAMId)
{
/* First 32 channels are for DMA only */
/* if (((*paRAMId) > SOC_EDMA3_NUM_DMACH) &&
((*paRAMId) < SOC_EDMA3_NUM_DMACH+SOC_EDMA3_NUM_QDMACH)) */
if ((SOC_EDMA3_NUM_DMACH + chNum) == (*paRAMId)) {
/* Map Parameter RAM Set Number for specified channelId */
HWREG(baseAdd + EDMA3CC_QCHMAP(chNum)) &= EDMA3CC_QCHMAP_PAENTRY_CLR;
HWREG(baseAdd + EDMA3CC_QCHMAP(chNum)) |= EDMA3CC_QCHMAP_PAENTRY_SET(*paRAMId);
} else {
(*paRAMId) = (SOC_EDMA3_NUM_DMACH + chNum);
/* Map Parameter RAM Set Number for specified channelId */
HWREG(baseAdd + EDMA3CC_QCHMAP(chNum)) &= EDMA3CC_QCHMAP_PAENTRY_CLR;
HWREG(baseAdd + EDMA3CC_QCHMAP(chNum)) |= EDMA3CC_QCHMAP_PAENTRY_SET(*paRAMId);
}
}
/**
* \brief Assign a Trigger Word to the specified QDMA channel
*
* This API sets the Trigger word for the specific QDMA channel in the QCHMAP
* Register. Default QDMA trigger word is CCNT.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum QDMA Channel which needs to be assigned
* the Trigger Word
*
* \param trigWord The Trigger Word for the QDMA channel.
* Trigger Word is the word in the PaRAM
* Register Set which, when written to by CPU,
* will start the QDMA transfer automatically.
*
* \return None
*/
void EDMA3SetQdmaTrigWord(unsigned int baseAdd,
unsigned int chNum,
unsigned int trigWord)
{
/* Set the Trigger Word */
HWREG(baseAdd + EDMA3CC_QCHMAP(chNum)) |= EDMA3CC_QCHMAP_TRWORD_SET(trigWord);
}
/**
* \brief Enables the user to Clear any missed event
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*/
void EDMA3ClrMissEvt(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/*clear SECR to clean any previous NULL request */
HWREG(baseAdd + EDMA3CC_S_SECR(regionId)) = (0x01u << chNum);
/*clear EMCR to clean any previous NULL request */
HWREG(baseAdd + EDMA3CC_EMCR) |= (0x01u << chNum);
} else {
HWREG(baseAdd + EDMA3CC_S_SECRH(regionId)) = (0x01u << (chNum - 32));
/*clear EMCRH to clean any previous NULL request */
HWREG(baseAdd + EDMA3CC_EMCRH) |= (0x01u << (chNum - 32));
}
}
/**
* \brief Enables the user to Clear any QDMA missed event
*
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*/
void EDMA3QdmaClrMissEvt(unsigned int baseAdd,
unsigned int chNum)
{
/*clear SECR to clean any previous NULL request */
HWREG(baseAdd + EDMA3CC_S_QSECR(regionId)) = (0x01u << chNum);
/*clear EMCR to clean any previous NULL request */
HWREG(baseAdd + EDMA3CC_QEMCR) |= (0x01u << chNum);
}
/**
* \brief Enables the user to Clear any Channel controller Errors
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param Flags Masks to be passed.\n
*
* Flags can have values:
*
* EDMA3CC_CLR_TCCERR Clears the TCCERR bit in the EDMA3CC
* ERR Reg\n
* EDMA3CC_CLR_QTHRQ0 Queue threshold error clear for queue 0.\n
* EDMA3CC_CLR_QTHRQ1 Queue threshold error clear for queue 1.
*
* \return None
*/
void EDMA3ClrCCErr(unsigned int baseAdd,
unsigned int Flags)
{
/* (CCERRCLR) - clear channel controller error register */
HWREG(baseAdd + EDMA3CC_CCERRCLR) = Flags;
}
/**
* \brief Enables the user to Set an event. This API helps user to manually
* set events to initiate DMA transfer requests.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : This API is generally used during Manual transfers.\n
*/
void EDMA3SetEvt(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/* (ESR) - set corresponding bit to set a event */
HWREG(baseAdd + EDMA3CC_S_ESR(regionId)) |= (0x01u << chNum);
} else {
/* (ESRH) - set corresponding bit to set a event */
HWREG(baseAdd + EDMA3CC_S_ESRH(regionId)) |= (0x01u << (chNum - 32));
}
}
/**
* \brief Enables the user to Clear an event.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : This API is generally used during Manual transfers.\n
*/
void EDMA3ClrEvt(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/* (ECR) - set corresponding bit to clear a event */
HWREG(baseAdd + EDMA3CC_S_ECR(regionId)) |= (0x01u << chNum);
} else {
/* (ECRH) - set corresponding bit to clear a event */
HWREG(baseAdd + EDMA3CC_S_ECRH(regionId)) |= (0x01u << (chNum - 32));
}
}
/**
* \brief Enables the user to enable an DMA event.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : Writes of 1 to the bits in EESR sets the corresponding event
* bits in EER. This is generally used for Event Based transfers.\n
*/
void EDMA3EnableDmaEvt(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/* (EESR) - set corresponding bit to enable DMA event */
HWREG(baseAdd + EDMA3CC_S_EESR(regionId)) |= (0x01u << chNum);
} else {
/* (EESRH) - set corresponding bit to enable DMA event */
HWREG(baseAdd + EDMA3CC_S_EESRH(regionId)) |= (0x01u << (chNum - 32));
}
}
/**
* \brief Enables the user to Disable an DMA event.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : Writes of 1 to the bits in EECR clear the corresponding event bits
* in EER; writes of 0 have no effect.. This is generally used for
* Event Based transfers.\n
*/
void EDMA3DisableDmaEvt(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/* (EECR) - set corresponding bit to disable event */
HWREG(baseAdd + EDMA3CC_S_EECR(regionId)) |= (0x01u << chNum);
} else {
/* (EECRH) - set corresponding bit to disable event */
HWREG(baseAdd + EDMA3CC_S_EECRH(regionId)) |= (0x01u << chNum);
}
}
/**
* \brief Enables the user to enable an QDMA event.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : Writes of 1 to the bits in QEESR sets the corresponding event
bits in QEER.\n
*/
void EDMA3EnableQdmaEvt(unsigned int baseAdd,
unsigned int chNum)
{
/* (QEESR) - set corresponding bit to enable QDMA event */
HWREG(baseAdd + EDMA3CC_S_QEESR(regionId)) = (0x01u << chNum);
}
/**
* \brief Enables the user to disable an QDMA event.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : Writes of 1 to the bits in QEECR clears the corresponding event
bits in QEER.\n
*/
void EDMA3DisableQdmaEvt(unsigned int baseAdd,
unsigned int chNum)
{
/* (QEESR) - set corresponding bit to enable QDMA event */
HWREG(baseAdd + EDMA3CC_S_QEECR(regionId)) = (0x01u << chNum);
}
/**
* \brief This returns EDMA3 CC error status.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return value Status of the Interrupt Pending Register
*
*/
unsigned int EDMA3GetCCErrStatus(unsigned int baseAdd)
{
unsigned int IntrStatusVal = 0;
IntrStatusVal = (unsigned int)HWREG(baseAdd + EDMA3CC_CCERR);
return IntrStatusVal;
}
/**
* \brief This function returns interrupts status of those events
* which is less than 32.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return value Status of the Interrupt Pending Register
*
*/
unsigned int EDMA3GetIntrStatus(unsigned int baseAdd)
{
unsigned int IntrStatusVal = 0;
IntrStatusVal = (unsigned int)HWREG(baseAdd + EDMA3CC_S_IPR(regionId));
return IntrStatusVal;
}
/**
* \brief This function returns interrupts status of those events
* which is greater than 32.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return value Status of the Interrupt Pending Register
*
*/
unsigned int EDMA3IntrStatusHighGet(unsigned int baseAdd)
{
unsigned int IntrStatusVal = 0;
IntrStatusVal = (unsigned int)HWREG(baseAdd + EDMA3CC_S_IPRH(regionId));
return IntrStatusVal;
}
/**
* \brief This returns error interrupt status for those events whose
* event number is less than 32.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return value Status of the Interrupt Pending Register
*
*/
unsigned int EDMA3GetErrIntrStatus(unsigned int baseAdd)
{
unsigned int IntrStatusVal = 0;
IntrStatusVal = (unsigned int)HWREG(baseAdd + EDMA3CC_EMR);
return IntrStatusVal;
}
/**
* \brief This returns error interrupt status for those events whose
* event number is greater than 32.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return value Status of the Interrupt Pending Register
*
*/
unsigned int EDMA3ErrIntrHighStatusGet(unsigned int baseAdd)
{
unsigned int IntrStatusVal = 0;
IntrStatusVal = (unsigned int)HWREG(baseAdd + EDMA3CC_EMRH);
return IntrStatusVal;
}
/**
* \brief This returns QDMA error interrupt status.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \return value Status of the QDMA Interrupt Pending Register
*
*/
unsigned int EDMA3QdmaGetErrIntrStatus(unsigned int baseAdd)
{
unsigned int IntrStatusVal = 0;
IntrStatusVal = (unsigned int)HWREG(baseAdd + EDMA3CC_QEMR);
return IntrStatusVal;
}
/**
* \brief Enables the user to enable the transfer completion interrupt
* generation by the EDMA3CC for all DMA/QDMA channels.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : To set any interrupt bit in IER, a 1 must be written to the
* corresponding interrupt bit in the interrupt enable set register.
*/
void EDMA3EnableEvtIntr(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/* Interrupt Enable Set Register (IESR) */
HWREG(baseAdd + EDMA3CC_S_IESR(regionId)) |= (0x01u << chNum);
} else {
/* Interrupt Enable Set Register (IESRH) */
HWREG(baseAdd + EDMA3CC_S_IESRH(regionId)) |= (0x01u << (chNum - 32));
}
}
/**
* \brief Enables the user to clear CC interrupts
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Allocated channel number.\n
*
* \return None
*
* Note : Writes of 1 to the bits in IECR clear the corresponding interrupt
* bits in the interrupt enable registers (IER); writes of 0 have
* no effect.\n
*/
void EDMA3DisableEvtIntr(unsigned int baseAdd,
unsigned int chNum)
{
if (chNum < 32) {
/* Interrupt Enable Clear Register (IECR) */
HWREG(baseAdd + EDMA3CC_S_IECR(regionId)) |= (0x01u << chNum);
} else {
/* Interrupt Enable Clear Register (IECRH) */
HWREG(baseAdd + EDMA3CC_S_IECRH(regionId)) |= (0x01u << (chNum - 32));
}
}
/**
* \brief Enables the user to Clear an Interrupt.
*
* \param baseAdd Memory address of the EDMA instance used.
*
* \param value Value to be set to clear the Interrupt Status.
*
* \return None
*
*/
void EDMA3ClrIntr(unsigned int baseAdd, unsigned int value)
{
if (value < 32) {
HWREG(baseAdd + EDMA3CC_S_ICR(regionId)) = (1u << value);
} else {
HWREG(baseAdd + EDMA3CC_S_ICRH(regionId)) = (1u << (value - 32));
}
}
/**
* \brief Retrieve existing PaRAM set associated with specified logical
* channel (DMA/Link).
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Logical Channel whose PaRAM set is
* requested.\n
*
* \param currPaRAM User gets the existing PaRAM here.\n
*
* \return None
*/
void EDMA3GetPaRAM(unsigned int baseAdd,
unsigned int PaRAMId,
EDMA3CCPaRAMEntry* currPaRAM)
{
unsigned int i = 0;
unsigned int *sr;
unsigned int *ds = (unsigned int *)currPaRAM;
sr = (unsigned int *)(baseAdd + EDMA3CC_OPT(PaRAMId));
for (i = 0; i < EDMA3CC_PARAM_ENTRY_FIELDS; i++) {
*ds++ = *sr++;
}
}
/**
* \brief Retrieve existing PaRAM set associated with specified logical
* channel (QDMA).
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Logical Channel whose PaRAM set is
* requested.\n
*
* \param currPaRAM User gets the existing PaRAM here.\n
*
* \return None
*/
void EDMA3QdmaGetPaRAM(unsigned int baseAdd,
UNUSED unsigned int chNum,
unsigned int paRAMId,
EDMA3CCPaRAMEntry* currPaRAM)
{
unsigned int i = 0;
unsigned int *sr;
unsigned int *ds = (unsigned int *)currPaRAM;
sr = (unsigned int *)(baseAdd + EDMA3CC_OPT(paRAMId));
for (i = 0; i < EDMA3CC_PARAM_ENTRY_FIELDS; i++) {
*ds = *sr;
ds++;
sr++;
}
}
/**
* \brief Copy the user specified PaRAM Set onto the PaRAM Set associated
* with the logical channel (DMA/Link).
*
* This API takes a PaRAM Set as input and copies it onto the actual PaRAM Set
* associated with the logical channel. OPT field of the PaRAM Set is written
* first and the CCNT field is written last.
*
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Logical Channel whose PaRAM set is
* requested.\n
*
* \param newPaRAM Parameter RAM set to be copied onto existing
* PaRAM.\n
*
* \return None
*/
void EDMA3SetPaRAM(unsigned int baseAdd,
unsigned int chNum,
EDMA3CCPaRAMEntry* newPaRAM)
{
unsigned int PaRAMId = chNum; /* PaRAM mapped to channel Number */
unsigned int i = 0;
unsigned int *sr = (unsigned int *)newPaRAM;
volatile unsigned int *ds;
ds = (unsigned int *)(baseAdd + EDMA3CC_OPT(PaRAMId));
for (i = 0; i < EDMA3CC_PARAM_ENTRY_FIELDS; i++) {
*ds = *sr;
ds++;
sr++;
}
}
/**
* \brief Copy the user specified PaRAM Set onto the PaRAM Set associated
* with the logical channel (QDMA only).
*
* This API takes a PaRAM Set as input and copies it onto the actual PaRAM Set
* associated with the logical channel. OPT field of the PaRAM Set is written
* first and the CCNT field is written last.
*
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Logical Channel whose PaRAM set is
* requested.\n
*
* \param paRaMID PaRAM Id to which the QDMA channel is
* mapped to.
*
* \param newPaRAM Parameter RAM set to be copied onto existing
* PaRAM.\n
*
* \return None
*/
void EDMA3QdmaSetPaRAM(unsigned int baseAdd,
UNUSED unsigned int chNum,
unsigned int paRAMId,
EDMA3CCPaRAMEntry* newPaRAM)
{
unsigned int i = 0;
unsigned int *sr = (unsigned int *)newPaRAM;
unsigned int *ds;
ds = (unsigned int *)(baseAdd + EDMA3CC_OPT(paRAMId));
for (i = 0; i < EDMA3CC_PARAM_ENTRY_FIELDS; i++) {
*ds = *sr;
ds++;
sr++;
}
}
/**
* \brief Set a particular PaRAM set entry of the specified PaRAM set
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param paRaMID PaRAM Id to which the QDMA channel is
* mapped to.
*
* \param paRAMEntry Specify the PaRAM set entry which needs
* to be set.
*
* \param newPaRAMEntryVal The new field setting. Make sure this field is
* packed for setting certain fields in paRAM.
*
* paRAMEntry can have values:
*
* EDMA3CC_PARAM_ENTRY_OPT
* EDMA3CC_PARAM_ENTRY_SRC
* EDMA3CC_PARAM_ENTRY_ACNT_BCNT
* EDMA3CC_PARAM_ENTRY_DST
* EDMA3CC_PARAM_ENTRY_SRC_DST_BIDX
* EDMA3CC_PARAM_ENTRY_LINK_BCNTRLD
* EDMA3CC_PARAM_ENTRY_SRC_DST_CIDX
* EDMA3CC_PARAM_ENTRY_CCNT
*
* \return None
*
* \note This API should be used while setting the PaRAM set entry
* for QDMA channels. If EDMA3QdmaSetPaRAMEntry() used,
* it will trigger the QDMA channel before complete
* PaRAM set entry is written.
*/
void EDMA3QdmaSetPaRAMEntry(unsigned int baseAdd,
unsigned int paRAMId,
unsigned int paRAMEntry,
unsigned int newPaRAMEntryVal)
{
if ((paRAMEntry > EDMA3CC_PARAM_ENTRY_OPT) ||
(paRAMEntry < EDMA3CC_PARAM_ENTRY_CCNT)) {
HWREG(baseAdd + EDMA3CC_OPT(paRAMId) +
(unsigned int)(paRAMEntry * 0x04)) = newPaRAMEntryVal;
}
}
/**
* \brief Get a particular PaRAM entry of the specified PaRAM set
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param paRaMID PaRAM Id to which the QDMA channel is
* mapped to.
*
* \param paRAMEntry Specify the PaRAM set entry which needs
* to be read.
*
* paRAMEntry can have values:
*
* EDMA3CC_PARAM_ENTRY_OPT
* EDMA3CC_PARAM_ENTRY_SRC
* EDMA3CC_PARAM_ENTRY_ACNT_BCNT
* EDMA3CC_PARAM_ENTRY_DST
* EDMA3CC_PARAM_ENTRY_SRC_DST_BIDX
* EDMA3CC_PARAM_ENTRY_LINK_BCNTRLD
* EDMA3CC_PARAM_ENTRY_SRC_DST_CIDX
* EDMA3CC_PARAM_ENTRY_CCNT
*
* \return paRAMEntryVal The value of the paRAM field pointed by the
* paRAMEntry.
*
* \note This API should be used while reading the PaRAM set entry
* for QDMA channels. And the paRAMEntryVal is a packed value for
* certain fields of paRAMEntry.The user has to make sure the value
* is unpacked appropriately.
* For example, the third field is A_B_CNT. Hence he will have to
* unpack it to two 16 bit fields to get ACNT and BCNT.
*/
unsigned int EDMA3QdmaGetPaRAMEntry(unsigned int baseAdd,
unsigned int paRAMId,
unsigned int paRAMEntry)
{
unsigned int paRAMEntryVal = 0;
if ((paRAMEntry > EDMA3CC_PARAM_ENTRY_OPT) ||
(paRAMEntry < EDMA3CC_PARAM_ENTRY_CCNT)) {
paRAMEntryVal = HWREG(baseAdd + EDMA3CC_OPT(paRAMId) +
(unsigned int)(paRAMEntry * 0x04));
}
return(paRAMEntryVal);
}
/**
* \brief Request a DMA/QDMA/Link channel.
*
* Each channel (DMA/QDMA/Link) must be requested before initiating a DMA
* transfer on that channel.
*
* This API is used to allocate a logical channel (DMA/QDMA/Link) along with
* the associated resources. For DMA and QDMA channels, TCC and PaRAM Set are
* also allocated along with the requested channel.
*
* User can request a specific logical channel by passing the channel number
* in 'chNum'.
*
* For DMA/QDMA channels, after allocating all the EDMA3 resources, this API
* sets the TCC field of the OPT PaRAM Word with the allocated TCC. It also sets
* the event queue for the channel allocated. The event queue needs to be
* specified by the user.
*
* For DMA channel, it also sets the DCHMAP register.
*
* For QDMA channel, it sets the QCHMAP register and CCNT as trigger word and
* enables the QDMA channel by writing to the QEESR register.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chtype (DMA/QDMA) Channel
* For Example: For DMA it is
* EDMA3_CHANNEL_TYPE_DMA.\n
*
* \param chNum This is the channel number requested for a
* particular event.\n
*
* \param tccNum The channel number on which the
* completion/error interrupt is generated.
* Not used if user requested for a Link
* channel.\n
*
* \param evtQNum Event Queue Number to which the channel
* will be mapped (valid only for the
* Master Channel (DMA/QDMA) request).\n
*
* \return TRUE if parameters are valid, else FALSE
*/
unsigned int EDMA3RequestChannel(unsigned int baseAdd,
unsigned int chType,
unsigned int chNum,
unsigned int tccNum,
unsigned int evtQNum)
{
unsigned int retVal = FALSE;
if (chNum < SOC_EDMA3_NUM_DMACH) {
/* Enable the DMA channel in the enabled in the shadow region
* specific register
*/
EDMA3EnableChInShadowReg(baseAdd, chType, chNum);
EDMA3MapChToEvtQ( baseAdd, chType, chNum, evtQNum);
if (EDMA3_CHANNEL_TYPE_DMA == chType) {
/* Interrupt channel nums are < 32 */
if (tccNum < SOC_EDMA3_NUM_DMACH) {
/* Enable the Event Interrupt */
EDMA3EnableEvtIntr(baseAdd, chNum);
retVal = TRUE;
}
HWREG(baseAdd + EDMA3CC_OPT(chNum)) &= EDMA3CC_OPT_TCC_CLR;
HWREG(baseAdd + EDMA3CC_OPT(chNum)) |= EDMA3CC_OPT_TCC_SET(chNum);
} else if (EDMA3_CHANNEL_TYPE_QDMA == chType) {
/* Interrupt channel nums are < 8 */
if (tccNum < SOC_EDMA3_NUM_QDMACH) {
/* Enable the Event Interrupt */
EDMA3EnableEvtIntr(baseAdd, chNum);
retVal = TRUE;
}
HWREG(baseAdd + EDMA3CC_OPT(chNum)) &= EDMA3CC_OPT_TCC_CLR;
HWREG(baseAdd + EDMA3CC_OPT(chNum)) |= EDMA3CC_OPT_TCC_SET(chNum);
}
}
return retVal;
}
/**
* \brief Free the specified channel (DMA/QDMA/Link) and its associated
* resources (PaRAM Set, TCC etc) and removes various mappings.
*
* For Link channels, this API only frees the associated PaRAM Set.
*
* For DMA/QDMA channels, it does the following operations:
* 1) Disable any ongoing transfer on the channel,\n
* 2) Remove the channel to Event Queue mapping,\n
* 3) For DMA channels, clear the DCHMAP register, if available\n
* 4) For QDMA channels, clear the QCHMAP register,\n
* 5) Frees the DMA/QDMA channel in the end.\n
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chtype (DMA/QDMA) Channel
* For Example: For QDMA it is,
* EDMA3_CHANNEL_TYPE_QDMA.\n
*
* \param chNum This is the channel number requested for a
* particular event.\n
*
* \param trigMode Mode of triggering start of transfer.\n
*
* \param tccNum The channel number on which the
* completion/error interrupt is generated.
* Not used if user requested for a Link
* channel.\n
*
* \param evtQNum Event Queue Number to which the channel
* will be unmapped (valid only for the
* Master Channel (DMA/QDMA) request).\n
*
* trigMode can have values:
* EDMA3_TRIG_MODE_MANUAL\n
* EDMA3_TRIG_MODE_QDMA\n
* EDMA3_TRIG_MODE_EVENT
*
* \return TRUE if parameters are valid else return FALSE
*/
unsigned int EDMA3FreeChannel(unsigned int baseAdd, unsigned int chType,
unsigned int chNum, unsigned int trigMode,
unsigned int tccNum, UNUSED unsigned int evtQNum)
{
unsigned int retVal = FALSE;
if (chNum < SOC_EDMA3_NUM_DMACH) {
EDMA3DisableTransfer(baseAdd, chNum, trigMode);
/* Disable the DMA channel in the shadow region specific register
*/
EDMA3DisableChInShadowReg(baseAdd, chType, chNum);
EDMA3UnmapChToEvtQ( baseAdd, chType, chNum);
if (EDMA3_CHANNEL_TYPE_DMA == chType) {
/* Interrupt channel nums are < 32 */
if (tccNum < SOC_EDMA3_NUM_DMACH) {
/* Disable the DMA Event Interrupt */
EDMA3DisableEvtIntr(baseAdd, chNum);
retVal = TRUE;
}
} else if (EDMA3_CHANNEL_TYPE_QDMA == chType) {
/* Interrupt channel nums are < 8 */
if (tccNum < SOC_EDMA3_NUM_QDMACH) {
/* Disable the QDMA Event Interrupt */
EDMA3DisableEvtIntr(baseAdd, chNum);
retVal = TRUE;
}
}
}
return retVal;
}
/**
* \brief Start EDMA transfer on the specified channel.
*
* There are multiple ways to trigger an EDMA3 transfer. The triggering mode
* option allows choosing from the available triggering modes: Event,
* Manual or QDMA.
*
* In event triggered, a peripheral or an externally generated event triggers
* the transfer. This API clears the Event and Event Miss Register and then
* enables the DMA channel by writing to the EESR.
*
* In manual triggered mode, CPU manually triggers a transfer by writing a 1
* in the Event Set Register ESR. This API writes to the ESR to start the
* transfer.
*
* In QDMA triggered mode, a QDMA transfer is triggered when a CPU (or other
* EDMA3 programmer) writes to the trigger word of the QDMA channel PaRAM set
* (auto-triggered) or when the EDMA3CC performs a link update on a PaRAM set
* that has been mapped to a QDMA channel (link triggered). This API enables
* the QDMA channel by writing to the QEESR register.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Channel being used to enable transfer.\n
*
* \param trigMode Mode of triggering start of transfer (Manual,
* QDMA or Event).\n
*
* trigMode can have values:
* EDMA3_TRIG_MODE_MANUAL\n
* EDMA3_TRIG_MODE_QDMA\n
* EDMA3_TRIG_MODE_EVENT\n
*
* \return retVal TRUE or FALSE depending on the param passed.\n
*
*/
unsigned int EDMA3EnableTransfer(unsigned int baseAdd,
unsigned int chNum,
unsigned int trigMode)
{
unsigned int retVal = FALSE;
switch (trigMode) {
case EDMA3_TRIG_MODE_MANUAL :
if (chNum < SOC_EDMA3_NUM_DMACH) {
EDMA3SetEvt(baseAdd, chNum);
retVal = TRUE;
}
break;
case EDMA3_TRIG_MODE_QDMA :
if (chNum < SOC_EDMA3_NUM_QDMACH) {
EDMA3EnableQdmaEvt(baseAdd, chNum);
retVal = TRUE;
}
break;
case EDMA3_TRIG_MODE_EVENT :
if (chNum < SOC_EDMA3_NUM_DMACH) {
/*clear SECR & EMCR to clean any previous NULL request */
EDMA3ClrMissEvt(baseAdd, chNum);
/* Set EESR to enable event */
EDMA3EnableDmaEvt(baseAdd, chNum);
retVal = TRUE;
}
break;
default :
retVal = FALSE;
break;
}
return retVal;
}
/**
* \brief Disable DMA transfer on the specified channel
*
* There are multiple ways by which an EDMA3 transfer could be triggered.
* The triggering mode option allows choosing from the available triggering
* modes.
*
* To disable a channel which was previously triggered in manual mode,
* this API clears the Secondary Event Register and Event Miss Register,
* if set, for the specific DMA channel.
*
* To disable a channel which was previously triggered in QDMA mode, this
* API clears the QDMA Event Enable Register, for the specific QDMA channel.
*
* To disable a channel which was previously triggered in event mode, this API
* clears the Event Enable Register, Event Register, Secondary Event Register
* and Event Miss Register, if set, for the specific DMA channel.
*
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum Channel being used to enable transfer.\n
*
* \param trigMode Mode of triggering start of transfer (Manual,
* QDMA or Event).\n
*
* trigMode can have values:
* EDMA3_TRIG_MODE_MANUAL
* EDMA3_TRIG_MODE_QDMA
* EDMA3_TRIG_MODE_EVENT
*
* \return retVal TRUE or FALSE depending on the param passed.\n
*
*/
unsigned int EDMA3DisableTransfer(unsigned int baseAdd,
unsigned int chNum,
unsigned int trigMode)
{
unsigned int retVal = FALSE;
switch (trigMode) {
case EDMA3_TRIG_MODE_MANUAL :
if (chNum < SOC_EDMA3_NUM_DMACH) {
EDMA3ClrEvt(baseAdd, chNum);
retVal = TRUE;
}
break;
case EDMA3_TRIG_MODE_QDMA :
if (chNum < SOC_EDMA3_NUM_QDMACH) {
EDMA3DisableQdmaEvt(baseAdd, chNum);
retVal = TRUE;
}
break;
case EDMA3_TRIG_MODE_EVENT :
if (chNum < SOC_EDMA3_NUM_DMACH) {
/*clear SECR & EMCR to clean any previous NULL request */
EDMA3ClrMissEvt(baseAdd, chNum);
/* Set EESR to enable event */
EDMA3DisableDmaEvt(baseAdd, chNum);
retVal = TRUE;
}
break;
default :
retVal = FALSE;
break;
}
return retVal;
}
/**
* \brief Clears Event Register and Error Register for a specific
* DMA channel and brings back EDMA3 to its initial state.
*
* This API clears the Event register, Event Miss register, Event Enable
* register for a specific DMA channel. It also clears the CC Error register.
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param chNum This is the channel number requested for a
* particular event.\n
*
* \param evtQNum Event Queue Number to which the channel
* will be unmapped (valid only for the
* Master Channel (DMA/QDMA) request).\n
*
* \return none.\n
*/
void EDMA3ClearErrorBits(unsigned int baseAdd,
unsigned int chNum,
unsigned int evtQNum)
{
if (chNum < SOC_EDMA3_NUM_DMACH) {
if (chNum < 32) {
HWREG(baseAdd + EDMA3CC_S_EECR(regionId)) = (0x01u << chNum);
/* Write to EMCR to clear the corresponding EMR bit */
HWREG(baseAdd + EDMA3CC_EMCR) = (0x01u << chNum);
/* Clears the SER */
HWREG(baseAdd + EDMA3CC_S_SECR(regionId)) = (0x01u << chNum);
} else {
HWREG(baseAdd + EDMA3CC_S_EECRH(regionId)) = (0x01u << (chNum - 32));
/* Write to EMCR to clear the corresponding EMR bit */
HWREG(baseAdd + EDMA3CC_EMCRH) = (0x01u << (chNum - 32));
/* Clears the SER */
HWREG(baseAdd + EDMA3CC_S_SECRH(regionId)) = (0x01u << (chNum - 32));
}
}
/* Clear the global CC Error Register */
if (0 == evtQNum) {
HWREG(baseAdd + EDMA3CC_CCERRCLR) &= (EDMA3CC_CCERRCLR_QTHRXCD0 |
EDMA3CC_CCERRCLR_TCCERR);
} else if (1 == evtQNum) {
HWREG(baseAdd + EDMA3CC_CCERRCLR) &= (EDMA3CC_CCERRCLR_QTHRXCD1 |
EDMA3CC_CCERRCLR_TCCERR);
} else if (2 == evtQNum) {
HWREG(baseAdd + EDMA3CC_CCERRCLR) &= (EDMA3CC_CCERRCLR_QTHRXCD2 |
EDMA3CC_CCERRCLR_TCCERR);
} else if (3 == evtQNum) {
HWREG(baseAdd + EDMA3CC_CCERRCLR) &= (EDMA3CC_CCERRCLR_QTHRXCD2 |
EDMA3CC_CCERRCLR_TCCERR);
}
}
/**
* \brief EDMA3 Deinitialization
*
* This function deinitializes the EDMA3 Driver
* Clears the error specific registers (EMCR/EMCRh, QEMCR, CCERRCLR) &
* deinitialize the Queue Number Registers
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param queNum Event Queue used
*
* \return None
*
* \note The regionId is the shadow region(0 or 1) used and the,
* Event Queue used is either (0 or 1). There are only two shadow regions
* and only two event Queues
*/
void EDMA3Deinit(unsigned int baseAdd,
UNUSED unsigned int queNum)
{
unsigned int count = 0;
/* Disable the DMA (0 - 62) channels in the DRAE register */
HWREG(baseAdd + EDMA3CC_DRAE(regionId)) = EDMA3_CLR_ALL_BITS;
HWREG(baseAdd + EDMA3CC_DRAEH(regionId)) = EDMA3_CLR_ALL_BITS;
EDMA3ClrCCErr(baseAdd, EDMA3CC_CLR_TCCERR);
/* Clear the Event miss Registers */
HWREG(baseAdd + EDMA3CC_EMCR) = EDMA3_SET_ALL_BITS;
HWREG(baseAdd + EDMA3CC_EMCRH) = EDMA3_SET_ALL_BITS;
/* Clear CCERR register */
HWREG(baseAdd + EDMA3CC_CCERRCLR) = EDMA3_SET_ALL_BITS;
/* Deinitialize the Queue Number Registers */
for (count = 0; count < SOC_EDMA3_NUM_DMACH; count++) {
HWREG(baseAdd + EDMA3CC_DMAQNUM(count >> 3u)) &= EDMA3CC_DMAQNUM_CLR(count);
}
for (count = 0; count < SOC_EDMA3_NUM_QDMACH; count++) {
HWREG(baseAdd + EDMA3CC_QDMAQNUM) &= EDMA3CC_QDMAQNUM_CLR(count);
}
}
/**
* \brief This API can be used to save the register context for EDMA
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param edmaCntxPtr Pointer to the structure where the context
* needs to be saved.
*
* \return None
*/
void EDMA3ContextSave(unsigned int baseAddr, EDMACONTEXT *edmaCntxPtr)
{
unsigned int i;
unsigned int maxPar;
/* Get the Channel mapping reg Val */
for (i = 0; i < 64; i++) {
/* All events are one to one mapped with the channels */
edmaCntxPtr->dchMap[i] = HWREG(baseAddr + EDMA3CC_DCHMAP(i));
}
/* Get DMA Queue Number Register Val */
for (i = 0; i < 8; i++) {
edmaCntxPtr->dmaQNum[i] = HWREG(baseAddr + EDMA3CC_DMAQNUM((i)));
}
/* Get the DMA Region Access Enable Register val */
edmaCntxPtr->regAccEnableLow = HWREG(baseAddr + EDMA3CC_DRAE(0));
edmaCntxPtr->regAccEnableHigh = HWREG(baseAddr + EDMA3CC_DRAEH(0));
/* Get Event Set Register value */
edmaCntxPtr->eventSetRegLow = HWREG(baseAddr + EDMA3CC_S_ESR(0));
edmaCntxPtr->eventSetRegHigh = HWREG(baseAddr + EDMA3CC_S_ESRH(0));
/* Get Event Enable Set Register value */
edmaCntxPtr->enableEvtSetRegLow = HWREG(baseAddr + EDMA3CC_S_EER(0));
edmaCntxPtr->enableEvtSetRegHigh = HWREG(baseAddr + EDMA3CC_S_EERH(0));
/* Get Interrupt Enable Set Register value */
edmaCntxPtr->intEnableSetRegLow = HWREG(baseAddr + EDMA3CC_S_IER(0));
edmaCntxPtr->intEnableSetRegHigh = HWREG(baseAddr + EDMA3CC_S_IERH(0));
maxPar = 128;
if ((EDMA_REVID_AM335X == EDMAVersionGet())) {
maxPar = 256;
}
for (i = 0; i < maxPar; i++) {
/* Get the PaRAM values */
EDMA3GetPaRAM(baseAddr, i,
(struct EDMA3CCPaRAMEntry *)(&(edmaCntxPtr->dmaParEntry[i])));
}
}
/**
* \brief This API can be used to restore the register context for EDMA
*
* \param baseAdd Memory address of the EDMA instance used.\n
*
* \param edmaCntxPtr Pointer to the structure where the context
* needs to be restored from.
*
* \return None
*/
void EDMA3ContextRestore(unsigned int baseAddr, EDMACONTEXT *edmaCntxPtr)
{
unsigned int i;
unsigned int maxPar;
/* set the Channel mapping reg Val */
for (i = 0; i < 64; i++) {
/* All events are one to one mapped with the channels */
HWREG(baseAddr + EDMA3CC_DCHMAP(i)) = edmaCntxPtr->dchMap[i] ;
}
/* set DMA Queue Number Register Val */
for (i = 0; i < 8; i++) {
HWREG(baseAddr + EDMA3CC_DMAQNUM((i))) = edmaCntxPtr->dmaQNum[i];
}
/* set the DMA Region Access Enable Register val */
HWREG(baseAddr + EDMA3CC_DRAE(0)) = edmaCntxPtr->regAccEnableLow;
HWREG(baseAddr + EDMA3CC_DRAEH(0)) = edmaCntxPtr->regAccEnableHigh;
/* set Event Set Register value */
HWREG(baseAddr + EDMA3CC_S_ESR(0)) = edmaCntxPtr->eventSetRegLow;
HWREG(baseAddr + EDMA3CC_S_ESRH(0)) = edmaCntxPtr->eventSetRegHigh;
/* set Event Enable Set Register value */
HWREG(baseAddr + EDMA3CC_S_EESR(0)) = edmaCntxPtr->enableEvtSetRegLow;
HWREG(baseAddr + EDMA3CC_S_EESRH(0)) = edmaCntxPtr->enableEvtSetRegHigh;
/* set Interrupt Enable Set Register value */
HWREG(baseAddr + EDMA3CC_S_IESR(0)) = edmaCntxPtr->intEnableSetRegLow;
HWREG(baseAddr + EDMA3CC_S_IESRH(0)) = edmaCntxPtr->intEnableSetRegHigh;
maxPar = 128;
if ((EDMA_REVID_AM335X == EDMAVersionGet())) {
maxPar = 256;
}
for (i = 0; i < maxPar; i++) {
/* Get the PaRAM values */
EDMA3SetPaRAM(baseAddr, i,
(struct EDMA3CCPaRAMEntry *)(&(edmaCntxPtr->dmaParEntry[i])));
}
}
/********************************* End of file ******************************/