aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/coldfire/files-2.6.31/arch/m68k/coldfire/m547x/MCD_dmaApi.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/coldfire/files-2.6.31/arch/m68k/coldfire/m547x/MCD_dmaApi.c')
-rw-r--r--target/linux/coldfire/files-2.6.31/arch/m68k/coldfire/m547x/MCD_dmaApi.c1045
1 files changed, 0 insertions, 1045 deletions
diff --git a/target/linux/coldfire/files-2.6.31/arch/m68k/coldfire/m547x/MCD_dmaApi.c b/target/linux/coldfire/files-2.6.31/arch/m68k/coldfire/m547x/MCD_dmaApi.c
deleted file mode 100644
index 9609d0c6dc..0000000000
--- a/target/linux/coldfire/files-2.6.31/arch/m68k/coldfire/m547x/MCD_dmaApi.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * drivers/dma/MCD_dmaApi.c
- *
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
- * Kurt Mahan <kmahan@freescale.com>
- * Shrek Wu b16972@freescale.com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include "MCD_dma.h"
-#include "MCD_tasksInit.h"
-#include "MCD_progCheck.h"
-
-/********************************************************************/
-/*
- * This is an API-internal pointer to the DMA's registers
- */
-dmaRegs *MCD_dmaBar;
-
-/*
- * These are the real and model task tables as generated by the
- * build process
- */
-extern TaskTableEntry MCD_realTaskTableSrc[NCHANNELS];
-extern TaskTableEntry MCD_modelTaskTableSrc[NUMOFVARIANTS];
-
-/*
- * However, this (usually) gets relocated to on-chip SRAM, at which
- * point we access them as these tables
- */
-volatile TaskTableEntry *MCD_taskTable;
-TaskTableEntry *MCD_modelTaskTable;
-
-
-/*
- * MCD_chStatus[] is an array of status indicators for remembering
- * whether a DMA has ever been attempted on each channel, pausing
- * status, etc.
- */
-static int MCD_chStatus[NCHANNELS] =
-{
- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA
-};
-
-/*
- * Prototypes for local functions
- */
-static void MCD_memcpy(int *dest, int *src, u32 size);
-static void MCD_resmActions(int channel);
-
-/*
- * Buffer descriptors used for storage of progress info for single Dmas
- * Also used as storage for the DMA for CRCs for single DMAs
- * Otherwise, the DMA does not parse these buffer descriptors
- */
-#ifdef MCD_INCLUDE_EU
-extern MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
-#else
-MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
-#endif
-MCD_bufDesc *MCD_relocBuffDesc;
-
-
-/*
- * Defines for the debug control register's functions
- */
-#define DBG_CTL_COMP1_TASK (0x00002000)
-/* have comparator 1 look for a task # */
-#define DBG_CTL_ENABLE (DBG_CTL_AUTO_ARM | \
- DBG_CTL_BREAK | \
- DBG_CTL_INT_BREAK | \
- DBG_CTL_COMP1_TASK)
-#define DBG_CTL_DISABLE (DBG_CTL_AUTO_ARM | \
- DBG_CTL_INT_BREAK | \
- DBG_CTL_COMP1_TASK)
-#define DBG_KILL_ALL_STAT (0xFFFFFFFF)
-
-/*
- * Offset to context save area where progress info is stored
- */
-#define CSAVE_OFFSET 10
-
-/*
- * Defines for Byte Swapping
- */
-#define MCD_BYTE_SWAP_KILLER 0xFFF8888F
-#define MCD_NO_BYTE_SWAP_ATALL 0x00040000
-
-/*
- * Execution Unit Identifiers
- */
-#define MAC 0 /* legacy - not used */
-#define LUAC 1 /* legacy - not used */
-#define CRC 2 /* legacy - not used */
-#define LURC 3 /* Logic Unit with CRC */
-
-/*
- * Task Identifiers
- */
-#define TASK_CHAINNOEU 0
-#define TASK_SINGLENOEU 1
-#ifdef MCD_INCLUDE_EU
-#define TASK_CHAINEU 2
-#define TASK_SINGLEEU 3
-#define TASK_FECRX 4
-#define TASK_FECTX 5
-#else
-#define TASK_CHAINEU 0
-#define TASK_SINGLEEU 1
-#define TASK_FECRX 2
-#define TASK_FECTX 3
-#endif
-
-/*
- * Structure to remember which variant is on which channel
- */
-typedef struct MCD_remVariants_struct MCD_remVariant;
-struct MCD_remVariants_struct {
- int remDestRsdIncr[NCHANNELS]; /* -1,0,1 */
- int remSrcRsdIncr[NCHANNELS]; /* -1,0,1 */
- s16 remDestIncr[NCHANNELS]; /* DestIncr */
- s16 remSrcIncr[NCHANNELS]; /* srcIncr */
- u32 remXferSize[NCHANNELS]; /* xferSize */
-};
-
-/*
- * Structure to remember the startDma parameters for each channel
- */
-MCD_remVariant MCD_remVariants;
-
-/********************************************************************/
-/*
- * Function: MCD_initDma
- * Purpose: Initializes the DMA API by setting up a pointer to the DMA
- * registers, relocating and creating the appropriate task
- * structures, and setting up some global settings
- * Arguments:
- * dmaBarAddr - pointer to the multichannel DMA registers
- * taskTableDest - location to move DMA task code and structs to
- * flags - operational parameters
- * Return Value:
- * MCD_TABLE_UNALIGNED if taskTableDest is not 512-byte aligned
- * MCD_OK otherwise
- */
-extern u32 MCD_funcDescTab0[];
-
-int MCD_initDma(dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags)
-{
- int i;
- TaskTableEntry *entryPtr;
-
- /* Setup the local pointer to register set */
- MCD_dmaBar = dmaBarAddr;
-
- /* Do we need to move/create a task table */
- if ((flags & MCD_RELOC_TASKS) != 0) {
- int fixedSize;
- u32 *fixedPtr;
- int varTabsOffset, funcDescTabsOffset;
- int contextSavesOffset;
- int taskDescTabsOffset;
- int taskTableSize, varTabsSize;
- int funcDescTabsSize, contextSavesSize;
- int taskDescTabSize;
- int i;
-
- /* Check if physical address is
- * aligned on 512 byte boundary */
- if (((u32)taskTableDest & 0x000001ff) != 0)
- return MCD_TABLE_UNALIGNED;
-
- MCD_taskTable = taskTableDest;
- /* set up local pointer to task Table */
-
- /*
- * Create a task table:
- * compute aligned base offsets for variable tables and
- * function descriptor tables, then
- * loop through the task table and setup the pointers
- *copy over model task table with the the actual
- *task descriptor tables
- */
- taskTableSize = NCHANNELS * sizeof(TaskTableEntry);
- /* Align variable tables to size */
- varTabsOffset = taskTableSize + (u32)taskTableDest;
- if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0)
- varTabsOffset = (varTabsOffset + VAR_TAB_SIZE)
- & (~VAR_TAB_SIZE);
- /* Align function descriptor tables */
- varTabsSize = NCHANNELS * VAR_TAB_SIZE;
- funcDescTabsOffset = varTabsOffset + varTabsSize;
-
- if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0)
- funcDescTabsOffset = (funcDescTabsOffset
- + FUNCDESC_TAB_SIZE) &
- (~FUNCDESC_TAB_SIZE);
-
- funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE;
- contextSavesOffset = funcDescTabsOffset
- + funcDescTabsSize;
- contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE);
- fixedSize = taskTableSize + varTabsSize +
- funcDescTabsSize + contextSavesSize;
-
- /* Zero the thing out */
- fixedPtr = (u32 *)taskTableDest;
- for (i = 0; i < (fixedSize/4); i++)
- fixedPtr[i] = 0;
-
- entryPtr = (TaskTableEntry *)MCD_taskTable;
- /* Set up fixed pointers */
- for (i = 0; i < NCHANNELS; i++) {
- entryPtr[i].varTab = (u32)varTabsOffset;
- /* update ptr to local value */
- entryPtr[i].FDTandFlags =
- (u32)funcDescTabsOffset | MCD_TT_FLAGS_DEF;
- entryPtr[i].contextSaveSpace =
- (u32)contextSavesOffset;
- varTabsOffset += VAR_TAB_SIZE;
-#ifdef MCD_INCLUDE_EU
- /* if not there is only one,
- * just point to the same one */
- funcDescTabsOffset += FUNCDESC_TAB_SIZE;
-#endif
- contextSavesOffset += CONTEXT_SAVE_SIZE;
- }
- /* Copy over the function descriptor table */
- for (i = 0; i < FUNCDESC_TAB_NUM; i++) {
- MCD_memcpy((void *)(entryPtr[i].FDTandFlags
- & ~MCD_TT_FLAGS_MASK),
- (void *)MCD_funcDescTab0,
- FUNCDESC_TAB_SIZE);
- }
-
- /* Copy model task table to where the
- * context save stuff leaves off */
- MCD_modelTaskTable =
- (TaskTableEntry *)contextSavesOffset;
-
- MCD_memcpy((void *)MCD_modelTaskTable,
- (void *)MCD_modelTaskTableSrc,
- NUMOFVARIANTS * sizeof(TaskTableEntry));
-
- /* Point to local version of model task table */
- entryPtr = MCD_modelTaskTable;
- taskDescTabsOffset = (u32)MCD_modelTaskTable +
- (NUMOFVARIANTS * sizeof(TaskTableEntry));
-
- /* Copy actual task code and update TDT ptrs
- * in local model task table */
- for (i = 0; i < NUMOFVARIANTS; i++) {
- taskDescTabSize = entryPtr[i].TDTend
- - entryPtr[i].TDTstart + 4;
- MCD_memcpy((void *)taskDescTabsOffset,
- (void *)entryPtr[i].TDTstart,
- taskDescTabSize);
- entryPtr[i].TDTstart =
- (u32)taskDescTabsOffset;
- taskDescTabsOffset += taskDescTabSize;
- entryPtr[i].TDTend =
- (u32)taskDescTabsOffset - 4;
- }
-#ifdef MCD_INCLUDE_EU
- /*
- * Tack single DMA BDs onto end of
- * code so API controls where
- * they are since DMA might write to them
- */
- MCD_relocBuffDesc = (MCD_bufDesc *)
- (entryPtr[NUMOFVARIANTS - 1].TDTend + 4);
-#else
- /*
- * DMA does not touch them so they
- * can be wherever and we don't need to
- * waste SRAM on them
- */
- MCD_relocBuffDesc = MCD_singleBufDescs;
-#endif
- } else {
- /*
- * Point the would-be relocated task tables and
- * the buffer descriptors
- * to the ones the linker generated
- */
- if (((u32)MCD_realTaskTableSrc & 0x000001ff) != 0)
- return MCD_TABLE_UNALIGNED;
-
- entryPtr = MCD_realTaskTableSrc;
- for (i = 0; i < NCHANNELS; i++) {
- if (((entryPtr[i].varTab
- & (VAR_TAB_SIZE - 1)) != 0) ||
- ((entryPtr[i].FDTandFlags &
- (FUNCDESC_TAB_SIZE - 1)) != 0))
- return MCD_TABLE_UNALIGNED;
- }
-
- MCD_taskTable = MCD_realTaskTableSrc;
- MCD_modelTaskTable = MCD_modelTaskTableSrc;
- MCD_relocBuffDesc = MCD_singleBufDescs;
- }
-
- /* Make all channels inactive,
- * and remember them as such: */
- MCD_dmaBar->taskbar = (u32) MCD_taskTable;
- for (i = 0; i < NCHANNELS; i++) {
- MCD_dmaBar->taskControl[i] = 0x0;
- MCD_chStatus[i] = MCD_NO_DMA;
- }
-
- /* Set up pausing mechanism to inactive state: */
- MCD_dmaBar->debugComp1 = 0;
- MCD_dmaBar->debugComp2 = 0;
- MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
- MCD_dmaBar->debugStatus = DBG_KILL_ALL_STAT;
-
- /* Enable or disable commbus prefetch */
- if ((flags & MCD_COMM_PREFETCH_EN) != 0)
- MCD_dmaBar->ptdControl &= ~PTD_CTL_COMM_PREFETCH;
- else
- MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH;
-
- return MCD_OK;
-}
-/*********************** End of MCD_initDma() ***********************/
-
-/********************************************************************/
-/* Function: MCD_dmaStatus
- * Purpose: Returns the status of the DMA on the requested channel
- * Arguments: channel - channel number
- * Returns: Predefined status indicators
- */
-int MCD_dmaStatus(int channel)
-{
- u16 tcrValue;
-
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- tcrValue = MCD_dmaBar->taskControl[channel];
- if ((tcrValue & TASK_CTL_EN) == 0) {
- /* Nothing running if last reported
- * with task enabled */
- if (MCD_chStatus[channel] == MCD_RUNNING
- || MCD_chStatus[channel] == MCD_IDLE)
- MCD_chStatus[channel] = MCD_DONE;
- } else /* something is running */{
- /* There are three possibilities:
- * paused, running or idle. */
- if (MCD_chStatus[channel] == MCD_RUNNING
- || MCD_chStatus[channel] == MCD_IDLE) {
- MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
- /* Determine which initiator
- * is asserted. */
- if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)
- MCD_chStatus[channel] = MCD_RUNNING;
- else
- MCD_chStatus[channel] = MCD_IDLE;
- /* Do not change the status if it is already paused */
- }
- }
- return MCD_chStatus[channel];
-}
-/******************** End of MCD_dmaStatus() ************************/
-
-/********************************************************************/
-/* Function: MCD_startDma
- * Ppurpose: Starts a particular kind of DMA
- * Arguments: see below
- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
- */
-
-int MCD_startDma(
- int channel,
-/* the channel on which to run the DMA */
- s8 *srcAddr,
-/* the address to move data from,
- * or physical buffer-descriptor address */
- s16 srcIncr,
-/* the amount to increment the source
- * address per transfer */
- s8 *destAddr,
-/* the address to move data to */
- s16 destIncr,
-/* the amount to increment the
- * destination address per transfer */
- u32 dmaSize,
-/* the number of bytes to transfer
- * independent of the transfer size */
- u32 xferSize,
-/* the number bytes in of each data
- * movement (1, 2, or 4) */
- u32 initiator,
-/* what device initiates the DMA */
- int priority,
-/* priority of the DMA */
- u32 flags,
-/* flags describing the DMA */
- u32 funcDesc
-/* a description of byte swapping,
- * bit swapping, and CRC actions */
-#ifdef MCD_NEED_ADDR_TRANS
- s8 *srcAddrVirt
-/* virtual buffer descriptor address TBD*/
-#endif
-)
-{
- int srcRsdIncr, destRsdIncr;
- int *cSave;
- short xferSizeIncr;
- int tcrCount = 0;
-#ifdef MCD_INCLUDE_EU
- u32 *realFuncArray;
-#endif
-
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
-#ifndef MCD_INCLUDE_EU
- funcDesc = MCD_FUNC_NOEU1;
-#endif
-
-#ifdef MCD_DEBUG
- printf("startDma:Setting up params\n");
-#endif
-
- /* Enable task-wise priority */
- MCD_dmaBar->ptdControl |= (u16) 0x8000;
-
- /* Calculate additional parameters
- * to the regular DMA calls. */
- srcRsdIncr = srcIncr < 0 ? -1 : (srcIncr > 0 ? 1 : 0);
- destRsdIncr = destIncr < 0 ? -1 : (destIncr > 0 ? 1 : 0);
- xferSizeIncr = (xferSize & 0xffff) | 0x20000000;
-
- /* Remember which variant is running for each channel */
- MCD_remVariants.remSrcRsdIncr[channel] = srcRsdIncr;
- MCD_remVariants.remDestRsdIncr[channel] = destRsdIncr;
- MCD_remVariants.remDestIncr[channel] = destIncr;
- MCD_remVariants.remSrcIncr[channel] = srcIncr;
- MCD_remVariants.remXferSize[channel] = xferSize;
-
- cSave = (int *)(MCD_taskTable[channel].contextSaveSpace)
- + CSAVE_OFFSET
- + CURRBD;
-
-#ifdef MCD_INCLUDE_EU
- realFuncArray = (u32 *)(MCD_taskTable[channel].FDTandFlags
- & 0xffffff00);
-
- /*
- * Modify the LURC's normal and byte-residue-loop functions
- * according to parameter.
- */
- switch (xferSize) {
- case 4:
- realFuncArray[(LURC*16)] = funcDesc;
- break;
- case 2:
- realFuncArray[(LURC*16)] = funcDesc & 0xfffff00f;
- break;
- case 1:
- default:
- realFuncArray[(LURC*16)] = funcDesc & 0xffff000f;
- break;
- }
-
- realFuncArray[(LURC*16 + 1)] = 0
- | (funcDesc & MCD_BYTE_SWAP_KILLER)
- | MCD_NO_BYTE_SWAP_ATALL;
-#endif
-
- /* Write the initiator field in the TCR and
- * set the initiator-hold bit*/
- MCD_dmaBar->taskControl[channel] = 0
- | (initiator << 8)
- | TASK_CTL_HIPRITSKEN
- | TASK_CTL_HLDINITNUM;
-
- /*
- * Current versions of the MPC8220 MCD have a hardware quirk that could
- * cause the write to the TCR to collide with an MDE access to the
- * initiator-register file, so we have to verify that the write occurred
- * correctly by reading back the value. On MCF547x/8x devices and any
- * future revisions of the MPC8220, this loop will not be entered.
- */
- while (((MCD_dmaBar->taskControl[channel] & 0x1fff) !=
- ((initiator << 8) | TASK_CTL_HIPRITSKEN
- | TASK_CTL_HLDINITNUM)) && (tcrCount < 1000)) {
- tcrCount++;
- MCD_dmaBar->taskControl[channel] = 0
- | (initiator << 8)
- | TASK_CTL_HIPRITSKEN
- | TASK_CTL_HLDINITNUM;
- }
-
- MCD_dmaBar->priority[channel] = (u8)priority & PRIORITY_PRI_MASK;
-
- if (channel < 8 && channel >= 0) {
- MCD_dmaBar->taskSize0 &= ~(0xf << (7-channel)*4);
- MCD_dmaBar->taskSize0
- |= (xferSize & 3) << (((7 - channel)*4) + 2);
- MCD_dmaBar->taskSize0
- |= (xferSize & 3) << ((7 - channel)*4);
- } else {
- MCD_dmaBar->taskSize1 &= ~(0xf << (15-channel)*4);
- MCD_dmaBar->taskSize1
- |= (xferSize & 3) << (((15 - channel)*4) + 2);
- MCD_dmaBar->taskSize1
- |= (xferSize & 3) << ((15 - channel)*4);
- }
-
- /* Setup task table flags/options */
- MCD_taskTable[channel].FDTandFlags &= ~MCD_TT_FLAGS_MASK;
- MCD_taskTable[channel].FDTandFlags |= (MCD_TT_FLAGS_MASK & flags);
-
- if (flags & MCD_FECTX_DMA) {
- /* TDTStart and TDTEnd */
- MCD_taskTable[channel].TDTstart =
- MCD_modelTaskTable[TASK_FECTX].TDTstart;
- MCD_taskTable[channel].TDTend =
- MCD_modelTaskTable[TASK_FECTX].TDTend;
- MCD_startDmaENetXmit(srcAddr, srcAddr, destAddr,
- MCD_taskTable, channel);
- } else if (flags & MCD_FECRX_DMA) {
- /* TDTStart and TDTEnd */
- MCD_taskTable[channel].TDTstart =
- MCD_modelTaskTable[TASK_FECRX].TDTstart;
- MCD_taskTable[channel].TDTend =
- MCD_modelTaskTable[TASK_FECRX].TDTend;
- MCD_startDmaENetRcv(srcAddr, srcAddr, destAddr,
- MCD_taskTable, channel);
- } else if (flags & MCD_SINGLE_DMA) {
- /*
- * This buffer descriptor is used for storing off
- * initial parameters for later progress query
- * calculation and for the DMA to write the resulting
- * checksum. The DMA does not use this to determine how
- * to operate, that info is passed with the init routine
- */
- MCD_relocBuffDesc[channel].srcAddr = srcAddr;
- MCD_relocBuffDesc[channel].destAddr = destAddr;
- MCD_relocBuffDesc[channel].lastDestAddr = destAddr;
- MCD_relocBuffDesc[channel].dmaSize = dmaSize;
- MCD_relocBuffDesc[channel].flags = 0;
- /* not used */
- MCD_relocBuffDesc[channel].csumResult = 0;
- /* not used */
- MCD_relocBuffDesc[channel].next = 0;
- /* not used */
-
- /* Initialize the progress-querying stuff
- * to show no progress:*/
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- SRCPTR + CSAVE_OFFSET] = (int)srcAddr;
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DESTPTR + CSAVE_OFFSET] = (int)destAddr;
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DCOUNT + CSAVE_OFFSET] = 0;
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- CURRBD + CSAVE_OFFSET] =
- (u32) &(MCD_relocBuffDesc[channel]);
-
- if ((funcDesc == MCD_FUNC_NOEU1)
- || (funcDesc == MCD_FUNC_NOEU2)) {
- /* TDTStart and TDTEnd */
- MCD_taskTable[channel].TDTstart =
- MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart;
- MCD_taskTable[channel].TDTend =
- MCD_modelTaskTable[TASK_SINGLENOEU].TDTend;
- MCD_startDmaSingleNoEu(srcAddr, srcIncr, destAddr,
- destIncr, dmaSize, xferSizeIncr, flags,
- (int *)&(MCD_relocBuffDesc[channel]),
- cSave, MCD_taskTable, channel);
- } else {
- /* TDTStart and TDTEnd */
- MCD_taskTable[channel].TDTstart =
- MCD_modelTaskTable[TASK_SINGLEEU].TDTstart;
- MCD_taskTable[channel].TDTend =
- MCD_modelTaskTable[TASK_SINGLEEU].TDTend;
- MCD_startDmaSingleEu(srcAddr, srcIncr, destAddr,
- destIncr, dmaSize, xferSizeIncr, flags,
- (int *)&(MCD_relocBuffDesc[channel]),
- cSave, MCD_taskTable, channel);
- }
- } else /* Chained DMA */ {
- /* Initialize the progress-querying
- * stuff to show no progress:*/
-#if 1 /* (!defined(MCD_NEED_ADDR_TRANS)) */
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- SRCPTR + CSAVE_OFFSET]
- = (int)((MCD_bufDesc *) srcAddr)->srcAddr;
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DESTPTR + CSAVE_OFFSET]
- = (int)((MCD_bufDesc *) srcAddr)->destAddr;
-#else
- /* if using address translation, need the
- * virtual addr of the first buffdesc */
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- SRCPTR + CSAVE_OFFSET]
- = (int)((MCD_bufDesc *) srcAddrVirt)->srcAddr;
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DESTPTR + CSAVE_OFFSET]
- = (int)((MCD_bufDesc *) srcAddrVirt)->destAddr;
-#endif
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DCOUNT + CSAVE_OFFSET] = 0;
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- CURRBD + CSAVE_OFFSET] = (u32) srcAddr;
-
- if (funcDesc == MCD_FUNC_NOEU1
- || funcDesc == MCD_FUNC_NOEU2) {
- /* TDTStart and TDTEnd */
- MCD_taskTable[channel].TDTstart =
- MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart;
- MCD_taskTable[channel].TDTend =
- MCD_modelTaskTable[TASK_CHAINNOEU].TDTend;
- MCD_startDmaChainNoEu((int *)srcAddr, srcIncr,
- destIncr, xferSize, xferSizeIncr, cSave,
- MCD_taskTable, channel);
- } else {
- /* TDTStart and TDTEnd */
- MCD_taskTable[channel].TDTstart =
- MCD_modelTaskTable[TASK_CHAINEU].TDTstart;
- MCD_taskTable[channel].TDTend =
- MCD_modelTaskTable[TASK_CHAINEU].TDTend;
- MCD_startDmaChainEu((int *)srcAddr, srcIncr, destIncr,
- xferSize, xferSizeIncr, cSave,
- MCD_taskTable, channel);
- }
- }
-
- MCD_chStatus[channel] = MCD_IDLE;
- return MCD_OK;
-}
-
-/************************ End of MCD_startDma() *********************/
-
-/********************************************************************/
-/* Function: MCD_XferProgrQuery
- * Purpose: Returns progress of DMA on requested channel
- * Arguments: channel - channel to retrieve progress for
- * progRep - pointer to user supplied MCD_XferProg struct
- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
- *
- * Notes:
- * MCD_XferProgrQuery() upon completing or after aborting a DMA, or
- * while the DMA is in progress, this function returns the first
- * DMA-destination address not (or not yet) used in the DMA. When
- * encountering a non-ready buffer descriptor, the information for
- * the last completed descriptor is returned.
- *
- * MCD_XferProgQuery() has to avoid the possibility of getting
- * partially-updated information in the event that we should happen
- * to query DMA progress just as the DMA is updating it. It does that
- * by taking advantage of the fact context is not saved frequently for
- * the most part. We therefore read it at least twice until we get the
- * same information twice in a row.
- *
- * Because a small, but not insignificant, amount of time is required
- * to write out the progress-query information, especially upon
- * completion of the DMA, it would be wise to guarantee some time lag
- * between successive readings of the progress-query information.
- */
-
-/*
- * How many iterations of the loop below to execute to stabilize values
- */
-#define STABTIME 0
-
-int MCD_XferProgrQuery(int channel, MCD_XferProg *progRep)
-{
- MCD_XferProg prevRep;
- int again;
- /* true if we are to try again to get consistent results */
- int i; /* used as a time-waste counter */
- int destDiffBytes;
- /* Total number of bytes that we think actually got xfered. */
- int numIterations; /* number of iterations */
- int bytesNotXfered; /* bytes that did not get xfered. */
- s8 *LWAlignedInitDestAddr, *LWAlignedCurrDestAddr;
- int subModVal, addModVal;
- /* Mode values to added and subtracted from the final destAddr */
-
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- /* Read a trial value for the progress-reporting values*/
- prevRep.lastSrcAddr =
- (s8 *)((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- SRCPTR + CSAVE_OFFSET];
- prevRep.lastDestAddr =
- (s8 *)((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DESTPTR + CSAVE_OFFSET];
- prevRep.dmaSize =
- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[
- DCOUNT + CSAVE_OFFSET];
- prevRep.currBufDesc =
- (MCD_bufDesc *)((volatile int *)MCD_taskTable[
- channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET];
-
- /* Repeatedly reread those values until
- * they match previous values: */
- do {
- /* Take a little bit of time to ensure stability: */
- for (i = 0; i < STABTIME; i++)
- i += i >> 2;
- /* make sure this loop does something so that it
- doesn't get optimized out */
- /* Check them again: */
- progRep->lastSrcAddr =
- (s8 *)((volatile int *)MCD_taskTable[
- channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
- progRep->lastDestAddr =
- (s8 *)((volatile int *)MCD_taskTable[
- channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
- progRep->dmaSize = ((volatile int *)MCD_taskTable[
- channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET];
- progRep->currBufDesc =
- (MCD_bufDesc *)((volatile int *)MCD_taskTable[
- channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET];
-
- /* See if they match: */
- if (prevRep.lastSrcAddr != progRep->lastSrcAddr
- || prevRep.lastDestAddr != progRep->lastDestAddr
- || prevRep.dmaSize != progRep->dmaSize
- || prevRep.currBufDesc != progRep->currBufDesc) {
- /* If they don't match, remember previous
- values and try again:*/
- prevRep.lastSrcAddr = progRep->lastSrcAddr;
- prevRep.lastDestAddr = progRep->lastDestAddr;
- prevRep.dmaSize = progRep->dmaSize;
- prevRep.currBufDesc = progRep->currBufDesc;
- again = MCD_TRUE;
- } else
- again = MCD_FALSE;
- } while (again == MCD_TRUE);
-
-
- /* Update dmaSize and lastDestAddr */
- switch (MCD_remVariants.remDestRsdIncr[channel]) {
- case MINUS1:
- subModVal = ((int)progRep->lastDestAddr)
- & ((MCD_remVariants.remXferSize[channel]) - 1);
- addModVal = ((int)progRep->currBufDesc->destAddr)
- & ((MCD_remVariants.remXferSize[channel]) - 1);
- LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr)
- - addModVal;
- LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;
- destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;
- bytesNotXfered =
- (destDiffBytes/MCD_remVariants.remDestIncr[channel]) *
- (MCD_remVariants.remDestIncr[channel]
- + MCD_remVariants.remXferSize[channel]);
- progRep->dmaSize = destDiffBytes - bytesNotXfered
- + addModVal - subModVal;
- break;
- case ZERO:
- progRep->lastDestAddr = progRep->currBufDesc->destAddr;
- break;
- case PLUS1:
- /* This value has to be subtracted
- from the final calculated dmaSize. */
- subModVal = ((int)progRep->currBufDesc->destAddr)
- & ((MCD_remVariants.remXferSize[channel]) - 1);
- /* These bytes are already in lastDestAddr. */
- addModVal = ((int)progRep->lastDestAddr)
- & ((MCD_remVariants.remXferSize[channel]) - 1);
- LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr)
- - subModVal;
- LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;
- destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);
- numIterations = (LWAlignedCurrDestAddr -
- LWAlignedInitDestAddr)/MCD_remVariants.remDestIncr[channel];
- bytesNotXfered = numIterations *
- (MCD_remVariants.remDestIncr[channel]
- - MCD_remVariants.remXferSize[channel]);
- progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;
- break;
- default:
- break;
- }
-
- /* This covers M1,P1,Z for source */
- switch (MCD_remVariants.remSrcRsdIncr[channel]) {
- case MINUS1:
- progRep->lastSrcAddr =
- progRep->currBufDesc->srcAddr +
- (MCD_remVariants.remSrcIncr[channel] *
- (progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
- break;
- case ZERO:
- progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;
- break;
- case PLUS1:
- progRep->lastSrcAddr =
- progRep->currBufDesc->srcAddr +
- (MCD_remVariants.remSrcIncr[channel] *
- (progRep->dmaSize/MCD_remVariants.remXferSize[channel]));
- break;
- default:
- break;
- }
-
- return MCD_OK;
-}
-/******************* End of MCD_XferProgrQuery() ********************/
-
-/********************************************************************/
-/* MCD_resmActions() does the majority of the actions of a DMA resume.
- * It is called from MCD_killDma() and MCD_resumeDma(). It has to be
- * a separate function because the kill function has to negate the task
- * enable before resuming it, but the resume function has to do nothing
- * if there is no DMA on that channel (i.e., if the enable bit is 0).
- */
-static void MCD_resmActions(int channel)
-{
- MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
- MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;
-
- /* Determine which initiators are asserted */
- MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
-
- if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)
- MCD_chStatus[channel] = MCD_RUNNING;
- else
- MCD_chStatus[channel] = MCD_IDLE;
-}
-/********************* End of MCD_resmActions() *********************/
-
-/********************************************************************/
-/* Function: MCD_killDma
- * Purpose: Halt the DMA on the requested channel, without any
- * intention of resuming the DMA.
- * Arguments: channel - requested channel
- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
- *
- * Notes:
- * A DMA may be killed from any state, including paused state, and it
- * always goes to the MCD_HALTED state even if it is killed while in
- * the MCD_NO_DMA or MCD_IDLE states.
- */
-int MCD_killDma(int channel)
-{
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- MCD_dmaBar->taskControl[channel] = 0x0;
-
- /* Clean up after a paused task */
- if (MCD_chStatus[channel] == MCD_PAUSED) {
- MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
- MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;
- }
-
- MCD_chStatus[channel] = MCD_HALTED;
-
- return MCD_OK;
-}
-/************************ End of MCD_killDma() **********************/
-
-/********************************************************************/
-/* Function: MCD_continDma
- * Purpose: Continue a DMA which as stopped due to encountering an
- * unready buffer descriptor.
- * Arguments: channel - channel to continue the DMA on
- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
- *
- * Notes:
- * This routine does not check to see if there is a task which can
- * be continued. Also this routine should not be used with single DMAs.
- */
-int MCD_continDma(int channel)
-{
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;
- MCD_chStatus[channel] = MCD_RUNNING;
-
- return MCD_OK;
-}
-/********************** End of MCD_continDma() **********************/
-
-/*********************************************************************
- * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit
- * to freeze a task and resume it. We freeze a task by breakpointing
- * on the stated task. That is, not any specific place in the task,
- * but any time that task executes. In particular, when that task
- * executes, we want to freeze that task and only that task.
- *
- * The bits of the debug control register influence interrupts vs.
- * breakpoints as follows:
- * - Bits 14 and 0 enable or disable debug functions. If enabled, you
- * will get the interrupt but you may or may not get a breakpoint.
- * - Bits 2 and 1 decide whether you also get a breakpoint in addition
- * to an interrupt.
- *
- * The debug unit can do these actions in response to either internally
- * detected breakpoint conditions from the comparators, or in response
- * to the external breakpoint pin, or both.
- * - Bits 14 and 1 perform the above-described functions for
- * internally-generated conditions, i.e., the debug comparators.
- * - Bits 0 and 2 perform the above-described functions for external
- * conditions, i.e., the breakpoint external pin.
- *
- * Note that, although you "always" get the interrupt when you turn
- * the debug functions, the interrupt can nevertheless, if desired, be
- * masked by the corresponding bit in the PTD's IMR. Note also that
- * this means that bits 14 and 0 must enable debug functions before
- * bits 1 and 2, respectively, have any effect.
- *
- * NOTE: It's extremely important to not pause more than one DMA channel
- * at a time.
- ********************************************************************/
-
-/********************************************************************/
-/* Function: MCD_pauseDma
- * Purpose: Pauses the DMA on a given channel (if any DMA is running
- * on that channel).
- * Arguments: channel
- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
- */
-int MCD_pauseDma(int channel)
-{
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) {
- MCD_dmaBar->debugComp1 = channel;
- MCD_dmaBar->debugControl =
- DBG_CTL_ENABLE | (1 << (channel + 16));
- MCD_chStatus[channel] = MCD_PAUSED;
- }
-
- return MCD_OK;
-}
-/************************* End of MCD_pauseDma() ********************/
-
-/********************************************************************/
-/* Function: MCD_resumeDma
- * Purpose: Resumes the DMA on a given channel (if any DMA is
- * running on that channel).
- * Arguments: channel - channel on which to resume DMA
- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
- */
-int MCD_resumeDma(int channel)
-{
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
- MCD_resmActions(channel);
-
- return MCD_OK;
-}
-/************************ End of MCD_resumeDma() ********************/
-
-/********************************************************************/
-/* Function: MCD_csumQuery
- * Purpose: Provide the checksum after performing a non-chained DMA
- * Arguments: channel - channel to report on
- * csum - pointer to where to write the checksum/CRC
- * Returns: MCD_ERROR if the channel is invalid, else MCD_OK
- *
- * Notes:
- *
- */
-int MCD_csumQuery(int channel, u32 *csum)
-{
-#ifdef MCD_INCLUDE_EU
- if ((channel < 0) || (channel >= NCHANNELS))
- return MCD_CHANNEL_INVALID;
-
- *csum = MCD_relocBuffDesc[channel].csumResult;
- return MCD_OK;
-#else
- return MCD_ERROR;
-#endif
-}
-/*********************** End of MCD_resumeDma() *********************/
-
-/********************************************************************/
-/* Function: MCD_getCodeSize
- * Purpose: Provide the size requirements of the microcoded tasks
- * Returns: Size in bytes
- */
-int MCD_getCodeSize(void)
-{
-#ifdef MCD_INCLUDE_EU
- return 0x2b64;
-#else
- return 0x1744;
-#endif
-}
-/********************** End of MCD_getCodeSize() ********************/
-
-/********************************************************************/
-/* Function: MCD_getVersion
- * Purpose: Provide the version string and number
- * Arguments: longVersion - user supplied pointer to a pointer to a char
- * which points to the version string
- * Returns: Version number and version string (by reference)
- */
-char MCD_versionString[] = "Multi-channel DMA API v1.0";
-#define MCD_REV_MAJOR 0x01
-#define MCD_REV_MINOR 0x00
-
-int MCD_getVersion(char **longVersion)
-{
- int ret = 0;
- *longVersion = MCD_versionString;
- ret = (MCD_REV_MAJOR << 8) | MCD_REV_MINOR;
- return ret;
-}
-/********************** End of MCD_getVersion() *********************/
-
-/********************************************************************/
-/* Private version of memcpy()
- * Note that everything this is used for is longword-aligned.
- */
-static void MCD_memcpy(int *dest, int *src, u32 size)
-{
- u32 i;
-
- for (i = 0; i < size; i += sizeof(int), dest++, src++)
- *dest = *src;
-}
-/********************************************************************/