diff options
| author | fishsoupisgood <github@madingley.org> | 2019-04-29 01:17:54 +0100 | 
|---|---|---|
| committer | fishsoupisgood <github@madingley.org> | 2019-05-27 03:43:43 +0100 | 
| commit | 3f2546b2ef55b661fd8dd69682b38992225e86f6 (patch) | |
| tree | 65ca85f13617aee1dce474596800950f266a456c /roms/u-boot/drivers/dma | |
| download | qemu-master.tar.gz qemu-master.tar.bz2 qemu-master.zip  | |
Diffstat (limited to 'roms/u-boot/drivers/dma')
| -rw-r--r-- | roms/u-boot/drivers/dma/MCD_dmaApi.c | 1011 | ||||
| -rw-r--r-- | roms/u-boot/drivers/dma/MCD_tasks.c | 2414 | ||||
| -rw-r--r-- | roms/u-boot/drivers/dma/MCD_tasksInit.c | 226 | ||||
| -rw-r--r-- | roms/u-boot/drivers/dma/Makefile | 11 | ||||
| -rw-r--r-- | roms/u-boot/drivers/dma/apbh_dma.c | 616 | ||||
| -rw-r--r-- | roms/u-boot/drivers/dma/fsl_dma.c | 168 | ||||
| -rw-r--r-- | roms/u-boot/drivers/dma/omap3_dma.c | 167 | 
7 files changed, 4613 insertions, 0 deletions
diff --git a/roms/u-boot/drivers/dma/MCD_dmaApi.c b/roms/u-boot/drivers/dma/MCD_dmaApi.c new file mode 100644 index 00000000..74dba185 --- /dev/null +++ b/roms/u-boot/drivers/dma/MCD_dmaApi.c @@ -0,0 +1,1011 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/*Main C file for multi-channel DMA API. */ + +#include <common.h> + +#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) +#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 + * TBD- need this? + */ +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 *tablePtr = taskTableDest;TBD */ +		int varTabsOffset, funcDescTabsOffset, contextSavesOffset; +		int taskDescTabsOffset; +		int taskTableSize, varTabsSize, 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); + +		/* set up local pointer to task Table */ +		MCD_taskTable = taskTableDest; + +		/* +		 * 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++) { +			/* update ptr to local value */ +			entryPtr[i].varTab = (u32) varTabsOffset; +			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 saves 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); + +		/* need to add code to make sure that every thing else is +		   aligned properly TBD. this is problematic if we init +		   more than once or after running tasks, need to add +		   variable to see if we have aleady init'd */ +		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 as totally 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: */ +	/* no particular values yet for either comparator registers */ +	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, really need an ifdef or +	   something to keep from trying to set this in the 8220 */ +	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; +			/* This register is selected to know which initiator is +			   actually 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: + * srcAddr	- the channel on which to run the DMA + * srcIncr	- the address to move data from, or buffer-descriptor address + * destAddr	- the amount to increment the source address per transfer + * destIncr	- the address to move data to + * dmaSize	- the amount to increment the destination address per transfer + * xferSize	- the number bytes in of each data movement (1, 2, or 4) + * initiator	- what device initiates the DMA + * priority	- priority of the DMA + * flags	- flags describing the DMA + * funcDesc	- description of byte swapping, bit swapping, and CRC actions + * srcAddrVirt	- virtual buffer descriptor address TBD + * Returns:     MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + */ + +int MCD_startDma(int channel, s8 * srcAddr, s16 srcIncr, s8 * destAddr, +		 s16 destIncr, u32 dmaSize, u32 xferSize, u32 initiator, +		 int priority, u32 flags, u32 funcDesc +#ifdef MCD_NEED_ADDR_TRANS +		 s8 * srcAddrVirt +#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); + +	/* tbd - need to determine the proper response to a bad funcDesc when +	   not including EU functions, for now, assign a benign funcDesc, but +	   maybe should return an error */ +#ifndef MCD_INCLUDE_EU +	funcDesc = MCD_FUNC_NOEU1; +#endif + +#ifdef MCD_DEBUG +	printf("startDma:Setting up params\n"); +#endif +	/* Set us up for task-wise priority.  We don't technically need to do +	   this on every start, but since the register involved is in the same +	   longword as other registers that users are in control of, setting +	   it more than once is probably preferable.  That since the +	   documentation doesn't seem to be completely consistent about the +	   nature of the PTD control register. */ +	MCD_dmaBar->ptdControl |= (u16) 0x8000; + +	/* Not sure what we need to keep here rtm TBD */ +#if 1 +	/* 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 for each channel which variant is running. */ +	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; +#endif + +	cSave = +	    (int *)(MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET + +	    CURRBD; + +#ifdef MCD_INCLUDE_EU +	/* may move this to EU specific calls */ +	realFuncArray = +	    (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00); +	/* Modify the LURC's normal and byte-residue-loop functions according +	   to parameter. */ +	realFuncArray[(LURC * 16)] = xferSize == 4 ? +	    funcDesc : xferSize == 2 ? +	    funcDesc & 0xfffff00f : funcDesc & 0xffff000f; +	realFuncArray[(LURC * 16 + 1)] = +	    (funcDesc & MCD_BYTE_SWAP_KILLER) | MCD_NO_BYTE_SWAP_ATALL; +#endif +	/* Write the initiator field in the TCR, and also set the +	   initiator-hold bit. Note that,due to a hardware quirk, this could +	   collide with an MDE access to the initiator-register file, so we +	   have to verify that the write reads back correctly. */ + +	MCD_dmaBar->taskControl[channel] = +	    (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM; + +	while (((MCD_dmaBar->taskControl[channel] & 0x1fff) != +		((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM)) +	       && (tcrCount < 1000)) { +		tcrCount++; +		/*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020; */ +		MCD_dmaBar->taskControl[channel] = +		    (initiator << 8) | TASK_CTL_HIPRITSKEN | +		    TASK_CTL_HLDINITNUM; +	} + +	MCD_dmaBar->priority[channel] = (u8) priority & PRIORITY_PRI_MASK; +	/* should be albe to handle this stuff with only one write to ts reg +	   - tbd */ +	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 which mostly control the line +	   buffers */ +	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((char *)srcAddr, (char *)srcAddr, +				     (char *)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((char *)srcAddr, (char *)srcAddr, +				    (char *)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; + +		/* definitely not its final value */ +		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]); +		/* tbd - need to keep the user from trying to call the EU +		   routine when MCD_INCLUDE_EU is not defined */ +		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((char *)srcAddr, srcIncr, +					       (char *)destAddr, destIncr, +					       (int)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((char *)srcAddr, srcIncr, +					     (char *)destAddr, destIncr, +					     (int)dmaSize, xferSizeIncr, +					     flags, (int *) +					     &(MCD_relocBuffDesc[channel]), +					     cSave, MCD_taskTable, channel); +		} +	} else {		/* chained DMAS */ +		/* 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 ge +				   consistent results */ +	int i;			/* used as a time-waste counter */ +	int destDiffBytes;	/* Total no 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 { +		/* Waste a little bit of time to ensure stability: */ +		for (i = 0; i < STABTIME; i++) { +			/* make sure this loop does something so that it +			   doesn't get optimized out */ +			i += i >> 2; +		} +		/* 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 the dCount, srcAddr and destAddr */ +	/* To calculate dmaCount, we consider destination address. C +	   overs M1,P1,Z for destination */ +	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 dCount. */ +		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; +	/* This register is selected to know which initiator is +	   actually 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) +{ +	/* MCD_XferProg progRep; */ + +	if ((channel < 0) || (channel >= NCHANNELS)) +		return (MCD_CHANNEL_INVALID); + +	MCD_dmaBar->taskControl[channel] = 0x0; +	MCD_resumeDma(channel); +	/* +	 * This must be after the write to the TCR so that the task doesn't +	 * start up again momentarily, and before the status assignment so +	 * as to override whatever MCD_resumeDma() may do to the channel +	 * status. +	 */ +	MCD_chStatus[channel] = MCD_HALTED; + +	/* +	 * Update the current buffer descriptor's lastDestAddr field +	 * +	 * MCD_XferProgrQuery (channel, &progRep); +	 * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr; +	 */ +	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) +{ +	/* MCD_XferProg progRep; */ + +	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; + +		/* +		 * Update the current buffer descriptor's lastDestAddr field +		 * +		 * MCD_XferProgrQuery (channel, &progRep); +		 * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr; +		 */ +	} +	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 (0x2b5c); +#else +	return (0x173c); +#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 Alpha v0.3 (2004-04-26)"; +#define MCD_REV_MAJOR   0x00 +#define MCD_REV_MINOR   0x03 + +int MCD_getVersion(char **longVersion) +{ +	*longVersion = MCD_versionString; +	return ((MCD_REV_MAJOR << 8) | MCD_REV_MINOR); +} + +/********************** 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; +} diff --git a/roms/u-boot/drivers/dma/MCD_tasks.c b/roms/u-boot/drivers/dma/MCD_tasks.c new file mode 100644 index 00000000..f90e4e4e --- /dev/null +++ b/roms/u-boot/drivers/dma/MCD_tasks.c @@ -0,0 +1,2414 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* Contains task code and structures for Multi-channel DMA */ + +#include <common.h> + +#include <MCD_dma.h> + +u32 MCD_varTab0[]; +u32 MCD_varTab1[]; +u32 MCD_varTab2[]; +u32 MCD_varTab3[]; +u32 MCD_varTab4[]; +u32 MCD_varTab5[]; +u32 MCD_varTab6[]; +u32 MCD_varTab7[]; +u32 MCD_varTab8[]; +u32 MCD_varTab9[]; +u32 MCD_varTab10[]; +u32 MCD_varTab11[]; +u32 MCD_varTab12[]; +u32 MCD_varTab13[]; +u32 MCD_varTab14[]; +u32 MCD_varTab15[]; + +u32 MCD_funcDescTab0[]; +#ifdef MCD_INCLUDE_EU +u32 MCD_funcDescTab1[]; +u32 MCD_funcDescTab2[]; +u32 MCD_funcDescTab3[]; +u32 MCD_funcDescTab4[]; +u32 MCD_funcDescTab5[]; +u32 MCD_funcDescTab6[]; +u32 MCD_funcDescTab7[]; +u32 MCD_funcDescTab8[]; +u32 MCD_funcDescTab9[]; +u32 MCD_funcDescTab10[]; +u32 MCD_funcDescTab11[]; +u32 MCD_funcDescTab12[]; +u32 MCD_funcDescTab13[]; +u32 MCD_funcDescTab14[]; +u32 MCD_funcDescTab15[]; +#endif + +u32 MCD_contextSave0[]; +u32 MCD_contextSave1[]; +u32 MCD_contextSave2[]; +u32 MCD_contextSave3[]; +u32 MCD_contextSave4[]; +u32 MCD_contextSave5[]; +u32 MCD_contextSave6[]; +u32 MCD_contextSave7[]; +u32 MCD_contextSave8[]; +u32 MCD_contextSave9[]; +u32 MCD_contextSave10[]; +u32 MCD_contextSave11[]; +u32 MCD_contextSave12[]; +u32 MCD_contextSave13[]; +u32 MCD_contextSave14[]; +u32 MCD_contextSave15[]; + +u32 MCD_realTaskTableSrc[] = { +	0x00000000, +	0x00000000, +	(u32) MCD_varTab0,	/* Task 0 Variable Table */ +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave0,	/* Task 0 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab1,	/* Task 1 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab1,	/* Task 1 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave1,	/* Task 1 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab2,	/* Task 2 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab2,	/* Task 2 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave2,	/* Task 2 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab3,	/* Task 3 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab3,	/* Task 3 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave3,	/* Task 3 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab4,	/* Task 4 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab4,	/* Task 4 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave4,	/* Task 4 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab5,	/* Task 5 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab5,	/* Task 5 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave5,	/* Task 5 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab6,	/* Task 6 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab6,	/* Task 6 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave6,	/* Task 6 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab7,	/* Task 7 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab7,	/* Task 7 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave7,	/* Task 7 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab8,	/* Task 8 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab8,	/* Task 8 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave8,	/* Task 8 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab9,	/* Task 9 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab9,	/* Task 9 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave9,	/* Task 9 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab10,	/* Task 10 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab10,	/* Task 10 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave10,	/* Task 10 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab11,	/* Task 11 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab11,	/* Task 11 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave11,	/* Task 11 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab12,	/* Task 12 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab12,	/* Task 12 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave12,	/* Task 12 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab13,	/* Task 13 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab13,	/* Task 13 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave13,	/* Task 13 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab14,	/* Task 14 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab14,	/* Task 14 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave14,	/* Task 14 context save space */ +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_varTab15,	/* Task 15 Variable Table */ +#ifdef MCD_INCLUDE_EU +	(u32) MCD_funcDescTab15,	/* Task 15 Fn Desc. Table & Flags */ +#else +	(u32) MCD_funcDescTab0,	/* Task 0 Fn Desc. Table & Flags */ +#endif +	0x00000000, +	0x00000000, +	(u32) MCD_contextSave15,	/* Task 15 context save space */ +	0x00000000, +}; + +u32 MCD_varTab0[] = {		/* Task 0 Variable Table */ +	0x00000000,		/* var[0] */ +	0x00000000,		/* var[1] */ +	0x00000000,		/* var[2] */ +	0x00000000,		/* var[3] */ +	0x00000000,		/* var[4] */ +	0x00000000,		/* var[5] */ +	0x00000000,		/* var[6] */ +	0x00000000,		/* var[7] */ +	0x00000000,		/* var[8] */ +	0x00000000,		/* var[9] */ +	0x00000000,		/* var[10] */ +	0x00000000,		/* var[11] */ +	0x00000000,		/* var[12] */ +	0x00000000,		/* var[13] */ +	0x00000000,		/* var[14] */ +	0x00000000,		/* var[15] */ +	0x00000000,		/* var[16] */ +	0x00000000,		/* var[17] */ +	0x00000000,		/* var[18] */ +	0x00000000,		/* var[19] */ +	0x00000000,		/* var[20] */ +	0x00000000,		/* var[21] */ +	0x00000000,		/* var[22] */ +	0x00000000,		/* var[23] */ +	0xe0000000,		/* inc[0] */ +	0x20000000,		/* inc[1] */ +	0x2000ffff,		/* inc[2] */ +	0x00000000,		/* inc[3] */ +	0x00000000,		/* inc[4] */ +	0x00000000,		/* inc[5] */ +	0x00000000,		/* inc[6] */ +	0x00000000,		/* inc[7] */ +}; + +u32 MCD_varTab1[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab2[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab3[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab4[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab5[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab6[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab7[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab8[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab9[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab10[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab11[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab12[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab13[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab14[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_varTab15[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xe0000000, +	0x20000000, +	0x2000ffff, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_funcDescTab0[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +#ifdef MCD_INCLUDE_EU +u32 MCD_funcDescTab1[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab2[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab3[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab4[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab5[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab6[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab7[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab8[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab9[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab10[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab11[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab12[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab13[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab14[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; + +u32 MCD_funcDescTab15[] = { +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0xa0045670, +	0xa0000000, +	0xa0000000, +	0x20000000, +	0x21800000, +	0x21e00000, +	0x20400000, +	0x20500000, +	0x205a0000, +	0x20a00000, +	0x202fa000, +	0x202f9000, +	0x202ea000, +	0x202da000, +	0x202e2000, +	0x202f2000, +}; +#endif				/*MCD_INCLUDE_EU */ + +u32 MCD_contextSave0[128];	/* Task 0 context save space */ +u32 MCD_contextSave1[128];	/* Task 1 context save space */ +u32 MCD_contextSave2[128];	/* Task 2 context save space */ +u32 MCD_contextSave3[128];	/* Task 3 context save space */ +u32 MCD_contextSave4[128];	/* Task 4 context save space */ +u32 MCD_contextSave5[128];	/* Task 5 context save space */ +u32 MCD_contextSave6[128];	/* Task 6 context save space */ +u32 MCD_contextSave7[128];	/* Task 7 context save space */ +u32 MCD_contextSave8[128];	/* Task 8 context save space */ +u32 MCD_contextSave9[128];	/* Task 9 context save space */ +u32 MCD_contextSave10[128];	/* Task 10 context save space */ +u32 MCD_contextSave11[128];	/* Task 11 context save space */ +u32 MCD_contextSave12[128];	/* Task 12 context save space */ +u32 MCD_contextSave13[128];	/* Task 13 context save space */ +u32 MCD_contextSave14[128];	/* Task 14 context save space */ +u32 MCD_contextSave15[128];	/* Task 15 context save space */ + +u32 MCD_ChainNoEu_TDT[]; +u32 MCD_SingleNoEu_TDT[]; +#ifdef MCD_INCLUDE_EU +u32 MCD_ChainEu_TDT[]; +u32 MCD_SingleEu_TDT[]; +#endif +u32 MCD_ENetRcv_TDT[]; +u32 MCD_ENetXmit_TDT[]; + +u32 MCD_modelTaskTableSrc[] = { +	(u32) MCD_ChainNoEu_TDT, +	(u32) & ((u8 *) MCD_ChainNoEu_TDT)[0x0000016c], +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_SingleNoEu_TDT, +	(u32) & ((u8 *) MCD_SingleNoEu_TDT)[0x000000d4], +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +#ifdef MCD_INCLUDE_EU +	(u32) MCD_ChainEu_TDT, +	(u32) & ((u8 *) MCD_ChainEu_TDT)[0x000001b4], +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_SingleEu_TDT, +	(u32) & ((u8 *) MCD_SingleEu_TDT)[0x00000124], +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +#endif +	(u32) MCD_ENetRcv_TDT, +	(u32) & ((u8 *) MCD_ENetRcv_TDT)[0x0000009c], +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	(u32) MCD_ENetXmit_TDT, +	(u32) & ((u8 *) MCD_ENetXmit_TDT)[0x000000d0], +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +	0x00000000, +}; + +u32 MCD_ChainNoEu_TDT[] = { +	0x80004000, +	0x8118801b, +	0xb8c60018, +	0x10002b10, +	0x7000000d, +	0x018cf89f, +	0x6000000a, +	0x080cf89f, +	0x000001f8, +	0x98180364, +	0x8118801b, +	0xf8c6001a, +	0xb8c6601b, +	0x10002710, +	0x00000f18, +	0xb8c6001d, +	0x10001310, +	0x60000007, +	0x014cf88b, +	0x98c6001c, +	0x00000710, +	0x98c70018, +	0x10001f10, +	0x0000c818, +	0x000001f8, +	0xc1476018, +	0xc003231d, +	0x811a601b, +	0xc1862102, +	0x849be009, +	0x03fed7b8, +	0xda9b001b, +	0x9b9be01b, +	0x1000cb20, +	0x70000006, +	0x088cf88f, +	0x1000cb28, +	0x70000006, +	0x088cf88f, +	0x1000cb30, +	0x70000006, +	0x088cf88f, +	0x1000cb38, +	0x0000c728, +	0x000001f8, +	0xc1476018, +	0xc003241d, +	0x811a601b, +	0xda9b001b, +	0x9b9be01b, +	0x0000d3a0, +	0xc1862102, +	0x849be009, +	0x0bfed7b8, +	0xda9b001b, +	0x9b9be01b, +	0x1000cb20, +	0x70000006, +	0x088cf88f, +	0x1000cb28, +	0x70000006, +	0x088cf88f, +	0x1000cb30, +	0x70000006, +	0x088cf88f, +	0x1000cb38, +	0x0000c728, +	0x000001f8, +	0x8118801b, +	0xd8c60018, +	0x98c6601c, +	0x6000000b, +	0x0c8cfc9f, +	0x000001f8, +	0xa146001e, +	0x10000b08, +	0x10002050, +	0xb8c60018, +	0x10002b10, +	0x7000000a, +	0x080cf89f, +	0x6000000d, +	0x018cf89f, +	0x000001f8, +	0x8618801b, +	0x7000000e, +	0x084cf21f, +	0xd8990336, +	0x8019801b, +	0x040001f8, +	0x000001f8, +	0x000001f8, +}; + +u32 MCD_SingleNoEu_TDT[] = { +	0x8198001b, +	0x7000000d, +	0x080cf81f, +	0x8198801b, +	0x6000000e, +	0x084cf85f, +	0x000001f8, +	0x8298001b, +	0x7000000d, +	0x010cf81f, +	0x6000000e, +	0x018cf81f, +	0xc202601b, +	0xc002221c, +	0x809a601b, +	0xc10420c2, +	0x839be009, +	0x03fed7b8, +	0xda9b001b, +	0x9b9be01b, +	0x70000006, +	0x088cf889, +	0x1000cb28, +	0x70000006, +	0x088cf889, +	0x1000cb30, +	0x70000006, +	0x088cf889, +	0x0000cb38, +	0x000001f8, +	0xc202601b, +	0xc002229c, +	0x809a601b, +	0xda9b001b, +	0x9b9be01b, +	0x0000d3a0, +	0xc10420c2, +	0x839be009, +	0x0bfed7b8, +	0xda9b001b, +	0x9b9be01b, +	0x70000006, +	0x088cf889, +	0x1000cb28, +	0x70000006, +	0x088cf889, +	0x1000cb30, +	0x70000006, +	0x088cf889, +	0x0000cb38, +	0x000001f8, +	0xc318022d, +	0x8018801b, +	0x040001f8, +}; + +#ifdef MCD_INCLUDE_EU +u32 MCD_ChainEu_TDT[] = { +	0x80004000, +	0x8198801b, +	0xb8c68018, +	0x10002f10, +	0x7000000d, +	0x01ccf89f, +	0x6000000a, +	0x080cf89f, +	0x000001f8, +	0x981803a4, +	0x8198801b, +	0xf8c6801a, +	0xb8c6e01b, +	0x10002b10, +	0x00001318, +	0xb8c6801d, +	0x10001710, +	0x60000007, +	0x018cf88c, +	0x98c6801c, +	0x00000b10, +	0x98c78018, +	0x10002310, +	0x0000c820, +	0x000001f8, +	0x8698801b, +	0x7000000f, +	0x084cf2df, +	0xd899042d, +	0x8019801b, +	0x60000003, +	0x2cd7c7df, +	0xd8990364, +	0x8019801b, +	0x60000003, +	0x2c17c7df, +	0x000001f8, +	0xc1c7e018, +	0xc003a35e, +	0x819a601b, +	0xc206a142, +	0x851be009, +	0x63fe0000, +	0x0d4cfddf, +	0xda9b001b, +	0x9b9be01b, +	0x70000002, +	0x004cf81f, +	0x1000cb20, +	0x70000006, +	0x088cf891, +	0x1000cb28, +	0x70000006, +	0x088cf891, +	0x1000cb30, +	0x70000006, +	0x088cf891, +	0x1000cb38, +	0x0000c728, +	0x000001f8, +	0xc1c7e018, +	0xc003a49e, +	0x819a601b, +	0xda9b001b, +	0x9b9be01b, +	0x0000d3a0, +	0xc206a142, +	0x851be009, +	0x6bfe0000, +	0x0d4cfddf, +	0xda9b001b, +	0x9b9be01b, +	0x70000002, +	0x004cf81f, +	0x1000cb20, +	0x70000006, +	0x088cf891, +	0x1000cb28, +	0x70000006, +	0x088cf891, +	0x1000cb30, +	0x70000006, +	0x088cf891, +	0x1000cb38, +	0x0000c728, +	0x000001f8, +	0x8198801b, +	0xd8c68018, +	0x98c6e01c, +	0x6000000b, +	0x0c8cfc9f, +	0x0000cc08, +	0xa1c6801e, +	0x10000f08, +	0x10002458, +	0xb8c68018, +	0x10002f10, +	0x7000000a, +	0x080cf89f, +	0x6000000d, +	0x01ccf89f, +	0x000001f8, +	0x8698801b, +	0x7000000e, +	0x084cf25f, +	0xd899037f, +	0x8019801b, +	0x040001f8, +	0x000001f8, +	0x000001f8, +}; + +u32 MCD_SingleEu_TDT[] = { +	0x8218001b, +	0x7000000d, +	0x080cf81f, +	0x8218801b, +	0x6000000e, +	0x084cf85f, +	0x000001f8, +	0x8318001b, +	0x7000000d, +	0x014cf81f, +	0x6000000e, +	0x01ccf81f, +	0x8498001b, +	0x7000000f, +	0x080cf19f, +	0xd81882a4, +	0x8019001b, +	0x60000003, +	0x2c97c7df, +	0xd818826d, +	0x8019001b, +	0x60000003, +	0x2c17c7df, +	0x000001f8, +	0xc282e01b, +	0xc002a25e, +	0x811a601b, +	0xc184a102, +	0x841be009, +	0x63fe0000, +	0x0d4cfddf, +	0xda9b001b, +	0x9b9be01b, +	0x70000002, +	0x004cf99f, +	0x70000006, +	0x088cf88b, +	0x1000cb28, +	0x70000006, +	0x088cf88b, +	0x1000cb30, +	0x70000006, +	0x088cf88b, +	0x0000cb38, +	0x000001f8, +	0xc282e01b, +	0xc002a31e, +	0x811a601b, +	0xda9b001b, +	0x9b9be01b, +	0x0000d3a0, +	0xc184a102, +	0x841be009, +	0x6bfe0000, +	0x0d4cfddf, +	0xda9b001b, +	0x9b9be01b, +	0x70000002, +	0x004cf99f, +	0x70000006, +	0x088cf88b, +	0x1000cb28, +	0x70000006, +	0x088cf88b, +	0x1000cb30, +	0x70000006, +	0x088cf88b, +	0x0000cb38, +	0x000001f8, +	0x8144801c, +	0x0000c008, +	0xc398027f, +	0x8018801b, +	0x040001f8, +}; +#endif +u32 MCD_ENetRcv_TDT[] = { +	0x80004000, +	0x81988000, +	0x10000788, +	0x6000000a, +	0x080cf05f, +	0x98180209, +	0x81c40004, +	0x7000000e, +	0x010cf05f, +	0x7000000c, +	0x01ccf05f, +	0x70000004, +	0x014cf049, +	0x70000004, +	0x004cf04a, +	0x00000b88, +	0xc4030150, +	0x8119e012, +	0x03e0cf90, +	0x81188000, +	0x000ac788, +	0xc4030000, +	0x8199e000, +	0x70000004, +	0x084cfc8b, +	0x60000005, +	0x0cccf841, +	0x81c60000, +	0xc399021b, +	0x80198000, +	0x00008400, +	0x00000f08, +	0x81988000, +	0x10000788, +	0x6000000a, +	0x080cf05f, +	0xc2188209, +	0x80190000, +	0x040001f8, +	0x000001f8, +}; + +u32 MCD_ENetXmit_TDT[] = { +	0x80004000, +	0x81988000, +	0x10000788, +	0x6000000a, +	0x080cf05f, +	0x98180309, +	0x80004003, +	0x81c60004, +	0x7000000e, +	0x014cf05f, +	0x7000000c, +	0x028cf05f, +	0x7000000d, +	0x018cf05f, +	0x70000004, +	0x01ccf04d, +	0x10000b90, +	0x60000004, +	0x020cf0a1, +	0xc3188312, +	0x83c70000, +	0x00001f10, +	0xc583a3c3, +	0x81042325, +	0x03e0c798, +	0xd8990000, +	0x9999e000, +	0x000acf98, +	0xd8992306, +	0x9999e03f, +	0x03eac798, +	0xd8990000, +	0x9999e000, +	0x000acf98, +	0xd8990000, +	0x99832302, +	0x0beac798, +	0x81988000, +	0x6000000b, +	0x0c4cfc5f, +	0x81c80000, +	0xc5190312, +	0x80198000, +	0x00008400, +	0x00000f08, +	0x81988000, +	0x10000788, +	0x6000000a, +	0x080cf05f, +	0xc2988309, +	0x80190000, +	0x040001f8, +	0x000001f8, +}; + +#ifdef MCD_INCLUDE_EU +MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; +#endif diff --git a/roms/u-boot/drivers/dma/MCD_tasksInit.c b/roms/u-boot/drivers/dma/MCD_tasksInit.c new file mode 100644 index 00000000..ce1ef891 --- /dev/null +++ b/roms/u-boot/drivers/dma/MCD_tasksInit.c @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2004-2007 Freescale Semiconductor, Inc. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <common.h> + +/* Functions for initializing variable tables of different types of tasks. */ + +/* + * Do not edit! + */ + +#include <MCD_dma.h> + +extern dmaRegs *MCD_dmaBar; + +/* Task 0 */ + +void MCD_startDmaChainNoEu(int *currBD, short srcIncr, short destIncr, +			   int xferSize, short xferSizeIncr, int *cSave, +			   volatile TaskTableEntry * taskTable, int channel) +{ +	volatile TaskTableEntry *taskChan = taskTable + channel; + +	MCD_SET_VAR(taskChan, 2, (u32) currBD);	/* var[2] */ +	MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr));	/* inc[1] */ +	MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr));	/* inc[0] */ +	MCD_SET_VAR(taskChan, 11, (u32) xferSize);	/* var[11] */ +	MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr));	/* inc[2] */ +	MCD_SET_VAR(taskChan, 0, (u32) cSave);	/* var[0] */ +	MCD_SET_VAR(taskChan, 1, (u32) 0x00000000);	/* var[1] */ +	MCD_SET_VAR(taskChan, 3, (u32) 0x00000000);	/* var[3] */ +	MCD_SET_VAR(taskChan, 4, (u32) 0x00000000);	/* var[4] */ +	MCD_SET_VAR(taskChan, 5, (u32) 0x00000000);	/* var[5] */ +	MCD_SET_VAR(taskChan, 6, (u32) 0x00000000);	/* var[6] */ +	MCD_SET_VAR(taskChan, 7, (u32) 0x00000000);	/* var[7] */ +	MCD_SET_VAR(taskChan, 8, (u32) 0x00000000);	/* var[8] */ +	MCD_SET_VAR(taskChan, 9, (u32) 0x00000000);	/* var[9] */ +	MCD_SET_VAR(taskChan, 10, (u32) 0x00000000);	/* var[10] */ +	MCD_SET_VAR(taskChan, 12, (u32) 0x00000000);	/* var[12] */ +	MCD_SET_VAR(taskChan, 13, (u32) 0x80000000);	/* var[13] */ +	MCD_SET_VAR(taskChan, 14, (u32) 0x00000010);	/* var[14] */ +	MCD_SET_VAR(taskChan, 15, (u32) 0x00000004);	/* var[15] */ +	MCD_SET_VAR(taskChan, 16, (u32) 0x08000000);	/* var[16] */ +	MCD_SET_VAR(taskChan, 27, (u32) 0x00000000);	/* inc[3] */ +	MCD_SET_VAR(taskChan, 28, (u32) 0x80000000);	/* inc[4] */ +	MCD_SET_VAR(taskChan, 29, (u32) 0x80000001);	/* inc[5] */ +	MCD_SET_VAR(taskChan, 30, (u32) 0x40000000);	/* inc[6] */ + +	/* Set the task's Enable bit in its Task Control Register */ +	MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; +} + +/* Task 1 */ + +void MCD_startDmaSingleNoEu(char *srcAddr, short srcIncr, char *destAddr, +			    short destIncr, int dmaSize, short xferSizeIncr, +			    int flags, int *currBD, int *cSave, +			    volatile TaskTableEntry * taskTable, int channel) +{ +	volatile TaskTableEntry *taskChan = taskTable + channel; + +	MCD_SET_VAR(taskChan, 7, (u32) srcAddr);	/* var[7] */ +	MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr));	/* inc[1] */ +	MCD_SET_VAR(taskChan, 2, (u32) destAddr);	/* var[2] */ +	MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr));	/* inc[0] */ +	MCD_SET_VAR(taskChan, 3, (u32) dmaSize);	/* var[3] */ +	MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr));	/* inc[2] */ +	MCD_SET_VAR(taskChan, 5, (u32) flags);	/* var[5] */ +	MCD_SET_VAR(taskChan, 1, (u32) currBD);	/* var[1] */ +	MCD_SET_VAR(taskChan, 0, (u32) cSave);	/* var[0] */ +	MCD_SET_VAR(taskChan, 4, (u32) 0x00000000);	/* var[4] */ +	MCD_SET_VAR(taskChan, 6, (u32) 0x00000000);	/* var[6] */ +	MCD_SET_VAR(taskChan, 8, (u32) 0x00000000);	/* var[8] */ +	MCD_SET_VAR(taskChan, 9, (u32) 0x00000004);	/* var[9] */ +	MCD_SET_VAR(taskChan, 10, (u32) 0x08000000);	/* var[10] */ +	MCD_SET_VAR(taskChan, 27, (u32) 0x00000000);	/* inc[3] */ +	MCD_SET_VAR(taskChan, 28, (u32) 0x80000001);	/* inc[4] */ +	MCD_SET_VAR(taskChan, 29, (u32) 0x40000000);	/* inc[5] */ + +	/* Set the task's Enable bit in its Task Control Register */ +	MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; +} + +/* Task 2 */ + +void MCD_startDmaChainEu(int *currBD, short srcIncr, short destIncr, +			 int xferSize, short xferSizeIncr, int *cSave, +			 volatile TaskTableEntry * taskTable, int channel) +{ +	volatile TaskTableEntry *taskChan = taskTable + channel; + +	MCD_SET_VAR(taskChan, 3, (u32) currBD);	/* var[3] */ +	MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr));	/* inc[1] */ +	MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr));	/* inc[0] */ +	MCD_SET_VAR(taskChan, 12, (u32) xferSize);	/* var[12] */ +	MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr));	/* inc[2] */ +	MCD_SET_VAR(taskChan, 0, (u32) cSave);	/* var[0] */ +	MCD_SET_VAR(taskChan, 1, (u32) 0x00000000);	/* var[1] */ +	MCD_SET_VAR(taskChan, 2, (u32) 0x00000000);	/* var[2] */ +	MCD_SET_VAR(taskChan, 4, (u32) 0x00000000);	/* var[4] */ +	MCD_SET_VAR(taskChan, 5, (u32) 0x00000000);	/* var[5] */ +	MCD_SET_VAR(taskChan, 6, (u32) 0x00000000);	/* var[6] */ +	MCD_SET_VAR(taskChan, 7, (u32) 0x00000000);	/* var[7] */ +	MCD_SET_VAR(taskChan, 8, (u32) 0x00000000);	/* var[8] */ +	MCD_SET_VAR(taskChan, 9, (u32) 0x00000000);	/* var[9] */ +	MCD_SET_VAR(taskChan, 10, (u32) 0x00000000);	/* var[10] */ +	MCD_SET_VAR(taskChan, 11, (u32) 0x00000000);	/* var[11] */ +	MCD_SET_VAR(taskChan, 13, (u32) 0x00000000);	/* var[13] */ +	MCD_SET_VAR(taskChan, 14, (u32) 0x80000000);	/* var[14] */ +	MCD_SET_VAR(taskChan, 15, (u32) 0x00000010);	/* var[15] */ +	MCD_SET_VAR(taskChan, 16, (u32) 0x00000001);	/* var[16] */ +	MCD_SET_VAR(taskChan, 17, (u32) 0x00000004);	/* var[17] */ +	MCD_SET_VAR(taskChan, 18, (u32) 0x08000000);	/* var[18] */ +	MCD_SET_VAR(taskChan, 27, (u32) 0x00000000);	/* inc[3] */ +	MCD_SET_VAR(taskChan, 28, (u32) 0x80000000);	/* inc[4] */ +	MCD_SET_VAR(taskChan, 29, (u32) 0xc0000000);	/* inc[5] */ +	MCD_SET_VAR(taskChan, 30, (u32) 0x80000001);	/* inc[6] */ +	MCD_SET_VAR(taskChan, 31, (u32) 0x40000000);	/* inc[7] */ + +	/* Set the task's Enable bit in its Task Control Register */ +	MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; +} + +/* Task 3 */ + +void MCD_startDmaSingleEu(char *srcAddr, short srcIncr, char *destAddr, +			  short destIncr, int dmaSize, short xferSizeIncr, +			  int flags, int *currBD, int *cSave, +			  volatile TaskTableEntry * taskTable, int channel) +{ +	volatile TaskTableEntry *taskChan = taskTable + channel; + +	MCD_SET_VAR(taskChan, 8, (u32) srcAddr);	/* var[8] */ +	MCD_SET_VAR(taskChan, 25, (u32) (0xe000 << 16) | (0xffff & srcIncr));	/* inc[1] */ +	MCD_SET_VAR(taskChan, 3, (u32) destAddr);	/* var[3] */ +	MCD_SET_VAR(taskChan, 24, (u32) (0xe000 << 16) | (0xffff & destIncr));	/* inc[0] */ +	MCD_SET_VAR(taskChan, 4, (u32) dmaSize);	/* var[4] */ +	MCD_SET_VAR(taskChan, 26, (u32) (0x2000 << 16) | (0xffff & xferSizeIncr));	/* inc[2] */ +	MCD_SET_VAR(taskChan, 6, (u32) flags);	/* var[6] */ +	MCD_SET_VAR(taskChan, 2, (u32) currBD);	/* var[2] */ +	MCD_SET_VAR(taskChan, 0, (u32) cSave);	/* var[0] */ +	MCD_SET_VAR(taskChan, 1, (u32) 0x00000000);	/* var[1] */ +	MCD_SET_VAR(taskChan, 5, (u32) 0x00000000);	/* var[5] */ +	MCD_SET_VAR(taskChan, 7, (u32) 0x00000000);	/* var[7] */ +	MCD_SET_VAR(taskChan, 9, (u32) 0x00000000);	/* var[9] */ +	MCD_SET_VAR(taskChan, 10, (u32) 0x00000001);	/* var[10] */ +	MCD_SET_VAR(taskChan, 11, (u32) 0x00000004);	/* var[11] */ +	MCD_SET_VAR(taskChan, 12, (u32) 0x08000000);	/* var[12] */ +	MCD_SET_VAR(taskChan, 27, (u32) 0x00000000);	/* inc[3] */ +	MCD_SET_VAR(taskChan, 28, (u32) 0xc0000000);	/* inc[4] */ +	MCD_SET_VAR(taskChan, 29, (u32) 0x80000000);	/* inc[5] */ +	MCD_SET_VAR(taskChan, 30, (u32) 0x80000001);	/* inc[6] */ +	MCD_SET_VAR(taskChan, 31, (u32) 0x40000000);	/* inc[7] */ + +	/* Set the task's Enable bit in its Task Control Register */ +	MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; +} + +/* Task 4 */ + +void MCD_startDmaENetRcv(char *bDBase, char *currBD, char *rcvFifoPtr, +			 volatile TaskTableEntry * taskTable, int channel) +{ +	volatile TaskTableEntry *taskChan = taskTable + channel; + +	MCD_SET_VAR(taskChan, 0, (u32) bDBase);	/* var[0] */ +	MCD_SET_VAR(taskChan, 3, (u32) currBD);	/* var[3] */ +	MCD_SET_VAR(taskChan, 6, (u32) rcvFifoPtr);	/* var[6] */ +	MCD_SET_VAR(taskChan, 1, (u32) 0x00000000);	/* var[1] */ +	MCD_SET_VAR(taskChan, 2, (u32) 0x00000000);	/* var[2] */ +	MCD_SET_VAR(taskChan, 4, (u32) 0x00000000);	/* var[4] */ +	MCD_SET_VAR(taskChan, 5, (u32) 0x00000000);	/* var[5] */ +	MCD_SET_VAR(taskChan, 7, (u32) 0x00000000);	/* var[7] */ +	MCD_SET_VAR(taskChan, 8, (u32) 0x00000000);	/* var[8] */ +	MCD_SET_VAR(taskChan, 9, (u32) 0x0000ffff);	/* var[9] */ +	MCD_SET_VAR(taskChan, 10, (u32) 0x30000000);	/* var[10] */ +	MCD_SET_VAR(taskChan, 11, (u32) 0x0fffffff);	/* var[11] */ +	MCD_SET_VAR(taskChan, 12, (u32) 0x00000008);	/* var[12] */ +	MCD_SET_VAR(taskChan, 24, (u32) 0x00000000);	/* inc[0] */ +	MCD_SET_VAR(taskChan, 25, (u32) 0x60000000);	/* inc[1] */ +	MCD_SET_VAR(taskChan, 26, (u32) 0x20000004);	/* inc[2] */ +	MCD_SET_VAR(taskChan, 27, (u32) 0x40000000);	/* inc[3] */ + +	/* Set the task's Enable bit in its Task Control Register */ +	MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; +} + +/* Task 5 */ + +void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr, +			  volatile TaskTableEntry * taskTable, int channel) +{ +	volatile TaskTableEntry *taskChan = taskTable + channel; + +	MCD_SET_VAR(taskChan, 0, (u32) bDBase);	/* var[0] */ +	MCD_SET_VAR(taskChan, 3, (u32) currBD);	/* var[3] */ +	MCD_SET_VAR(taskChan, 11, (u32) xmitFifoPtr);	/* var[11] */ +	MCD_SET_VAR(taskChan, 1, (u32) 0x00000000);	/* var[1] */ +	MCD_SET_VAR(taskChan, 2, (u32) 0x00000000);	/* var[2] */ +	MCD_SET_VAR(taskChan, 4, (u32) 0x00000000);	/* var[4] */ +	MCD_SET_VAR(taskChan, 5, (u32) 0x00000000);	/* var[5] */ +	MCD_SET_VAR(taskChan, 6, (u32) 0x00000000);	/* var[6] */ +	MCD_SET_VAR(taskChan, 7, (u32) 0x00000000);	/* var[7] */ +	MCD_SET_VAR(taskChan, 8, (u32) 0x00000000);	/* var[8] */ +	MCD_SET_VAR(taskChan, 9, (u32) 0x00000000);	/* var[9] */ +	MCD_SET_VAR(taskChan, 10, (u32) 0x00000000);	/* var[10] */ +	MCD_SET_VAR(taskChan, 12, (u32) 0x00000000);	/* var[12] */ +	MCD_SET_VAR(taskChan, 13, (u32) 0x0000ffff);	/* var[13] */ +	MCD_SET_VAR(taskChan, 14, (u32) 0xffffffff);	/* var[14] */ +	MCD_SET_VAR(taskChan, 15, (u32) 0x00000004);	/* var[15] */ +	MCD_SET_VAR(taskChan, 16, (u32) 0x00000008);	/* var[16] */ +	MCD_SET_VAR(taskChan, 24, (u32) 0x00000000);	/* inc[0] */ +	MCD_SET_VAR(taskChan, 25, (u32) 0x60000000);	/* inc[1] */ +	MCD_SET_VAR(taskChan, 26, (u32) 0x40000000);	/* inc[2] */ +	MCD_SET_VAR(taskChan, 27, (u32) 0xc000fffc);	/* inc[3] */ +	MCD_SET_VAR(taskChan, 28, (u32) 0xe0000004);	/* inc[4] */ +	MCD_SET_VAR(taskChan, 29, (u32) 0x80000000);	/* inc[5] */ +	MCD_SET_VAR(taskChan, 30, (u32) 0x4000ffff);	/* inc[6] */ +	MCD_SET_VAR(taskChan, 31, (u32) 0xe0000001);	/* inc[7] */ + +	/* Set the task's Enable bit in its Task Control Register */ +	MCD_dmaBar->taskControl[channel] |= (u16) 0x8000; +} diff --git a/roms/u-boot/drivers/dma/Makefile b/roms/u-boot/drivers/dma/Makefile new file mode 100644 index 00000000..8b2821b7 --- /dev/null +++ b/roms/u-boot/drivers/dma/Makefile @@ -0,0 +1,11 @@ +# +# (C) Copyright 2006 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# SPDX-License-Identifier:	GPL-2.0+ +# + +obj-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o +obj-$(CONFIG_APBH_DMA) += apbh_dma.o +obj-$(CONFIG_FSL_DMA) += fsl_dma.o +obj-$(CONFIG_OMAP3_DMA) += omap3_dma.o diff --git a/roms/u-boot/drivers/dma/apbh_dma.c b/roms/u-boot/drivers/dma/apbh_dma.c new file mode 100644 index 00000000..22defcd7 --- /dev/null +++ b/roms/u-boot/drivers/dma/apbh_dma.c @@ -0,0 +1,616 @@ +/* + * Freescale i.MX28 APBH DMA driver + * + * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com> + * on behalf of DENX Software Engineering GmbH + * + * Based on code from LTIB: + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <linux/list.h> + +#include <common.h> +#include <malloc.h> +#include <asm/errno.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include <asm/imx-common/dma.h> +#include <asm/imx-common/regs-apbh.h> + +static struct mxs_dma_chan mxs_dma_channels[MXS_MAX_DMA_CHANNELS]; + +/* + * Test is the DMA channel is valid channel + */ +int mxs_dma_validate_chan(int channel) +{ +	struct mxs_dma_chan *pchan; + +	if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS)) +		return -EINVAL; + +	pchan = mxs_dma_channels + channel; +	if (!(pchan->flags & MXS_DMA_FLAGS_ALLOCATED)) +		return -EINVAL; + +	return 0; +} + +/* + * Return the address of the command within a descriptor. + */ +static unsigned int mxs_dma_cmd_address(struct mxs_dma_desc *desc) +{ +	return desc->address + offsetof(struct mxs_dma_desc, cmd); +} + +/* + * Read a DMA channel's hardware semaphore. + * + * As used by the MXS platform's DMA software, the DMA channel's hardware + * semaphore reflects the number of DMA commands the hardware will process, but + * has not yet finished. This is a volatile value read directly from hardware, + * so it must be be viewed as immediately stale. + * + * If the channel is not marked busy, or has finished processing all its + * commands, this value should be zero. + * + * See mxs_dma_append() for details on how DMA command blocks must be configured + * to maintain the expected behavior of the semaphore's value. + */ +static int mxs_dma_read_semaphore(int channel) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	uint32_t tmp; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	tmp = readl(&apbh_regs->ch[channel].hw_apbh_ch_sema); + +	tmp &= APBH_CHn_SEMA_PHORE_MASK; +	tmp >>= APBH_CHn_SEMA_PHORE_OFFSET; + +	return tmp; +} + +#ifndef	CONFIG_SYS_DCACHE_OFF +void mxs_dma_flush_desc(struct mxs_dma_desc *desc) +{ +	uint32_t addr; +	uint32_t size; + +	addr = (uint32_t)desc; +	size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); + +	flush_dcache_range(addr, addr + size); +} +#else +inline void mxs_dma_flush_desc(struct mxs_dma_desc *desc) {} +#endif + +/* + * Enable a DMA channel. + * + * If the given channel has any DMA descriptors on its active list, this + * function causes the DMA hardware to begin processing them. + * + * This function marks the DMA channel as "busy," whether or not there are any + * descriptors to process. + */ +static int mxs_dma_enable(int channel) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	unsigned int sem; +	struct mxs_dma_chan *pchan; +	struct mxs_dma_desc *pdesc; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	pchan = mxs_dma_channels + channel; + +	if (pchan->pending_num == 0) { +		pchan->flags |= MXS_DMA_FLAGS_BUSY; +		return 0; +	} + +	pdesc = list_first_entry(&pchan->active, struct mxs_dma_desc, node); +	if (pdesc == NULL) +		return -EFAULT; + +	if (pchan->flags & MXS_DMA_FLAGS_BUSY) { +		if (!(pdesc->cmd.data & MXS_DMA_DESC_CHAIN)) +			return 0; + +		sem = mxs_dma_read_semaphore(channel); +		if (sem == 0) +			return 0; + +		if (sem == 1) { +			pdesc = list_entry(pdesc->node.next, +					   struct mxs_dma_desc, node); +			writel(mxs_dma_cmd_address(pdesc), +				&apbh_regs->ch[channel].hw_apbh_ch_nxtcmdar); +		} +		writel(pchan->pending_num, +			&apbh_regs->ch[channel].hw_apbh_ch_sema); +		pchan->active_num += pchan->pending_num; +		pchan->pending_num = 0; +	} else { +		pchan->active_num += pchan->pending_num; +		pchan->pending_num = 0; +		writel(mxs_dma_cmd_address(pdesc), +			&apbh_regs->ch[channel].hw_apbh_ch_nxtcmdar); +		writel(pchan->active_num, +			&apbh_regs->ch[channel].hw_apbh_ch_sema); +		writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET), +			&apbh_regs->hw_apbh_ctrl0_clr); +	} + +	pchan->flags |= MXS_DMA_FLAGS_BUSY; +	return 0; +} + +/* + * Disable a DMA channel. + * + * This function shuts down a DMA channel and marks it as "not busy." Any + * descriptors on the active list are immediately moved to the head of the + * "done" list, whether or not they have actually been processed by the + * hardware. The "ready" flags of these descriptors are NOT cleared, so they + * still appear to be active. + * + * This function immediately shuts down a DMA channel's hardware, aborting any + * I/O that may be in progress, potentially leaving I/O hardware in an undefined + * state. It is unwise to call this function if there is ANY chance the hardware + * is still processing a command. + */ +static int mxs_dma_disable(int channel) +{ +	struct mxs_dma_chan *pchan; +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	pchan = mxs_dma_channels + channel; + +	if (!(pchan->flags & MXS_DMA_FLAGS_BUSY)) +		return -EINVAL; + +	writel(1 << (channel + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET), +		&apbh_regs->hw_apbh_ctrl0_set); + +	pchan->flags &= ~MXS_DMA_FLAGS_BUSY; +	pchan->active_num = 0; +	pchan->pending_num = 0; +	list_splice_init(&pchan->active, &pchan->done); + +	return 0; +} + +/* + * Resets the DMA channel hardware. + */ +static int mxs_dma_reset(int channel) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	int ret; +#if defined(CONFIG_MX23) +	uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set); +	uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET; +#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6)) +	uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set); +	uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; +#endif + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	writel(1 << (channel + offset), setreg); + +	return 0; +} + +/* + * Enable or disable DMA interrupt. + * + * This function enables the given DMA channel to interrupt the CPU. + */ +static int mxs_dma_enable_irq(int channel, int enable) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	if (enable) +		writel(1 << (channel + APBH_CTRL1_CH_CMDCMPLT_IRQ_EN_OFFSET), +			&apbh_regs->hw_apbh_ctrl1_set); +	else +		writel(1 << (channel + APBH_CTRL1_CH_CMDCMPLT_IRQ_EN_OFFSET), +			&apbh_regs->hw_apbh_ctrl1_clr); + +	return 0; +} + +/* + * Clear DMA interrupt. + * + * The software that is using the DMA channel must register to receive its + * interrupts and, when they arrive, must call this function to clear them. + */ +static int mxs_dma_ack_irq(int channel) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	writel(1 << channel, &apbh_regs->hw_apbh_ctrl1_clr); +	writel(1 << channel, &apbh_regs->hw_apbh_ctrl2_clr); + +	return 0; +} + +/* + * Request to reserve a DMA channel + */ +static int mxs_dma_request(int channel) +{ +	struct mxs_dma_chan *pchan; + +	if ((channel < 0) || (channel >= MXS_MAX_DMA_CHANNELS)) +		return -EINVAL; + +	pchan = mxs_dma_channels + channel; +	if ((pchan->flags & MXS_DMA_FLAGS_VALID) != MXS_DMA_FLAGS_VALID) +		return -ENODEV; + +	if (pchan->flags & MXS_DMA_FLAGS_ALLOCATED) +		return -EBUSY; + +	pchan->flags |= MXS_DMA_FLAGS_ALLOCATED; +	pchan->active_num = 0; +	pchan->pending_num = 0; + +	INIT_LIST_HEAD(&pchan->active); +	INIT_LIST_HEAD(&pchan->done); + +	return 0; +} + +/* + * Release a DMA channel. + * + * This function releases a DMA channel from its current owner. + * + * The channel will NOT be released if it's marked "busy" (see + * mxs_dma_enable()). + */ +int mxs_dma_release(int channel) +{ +	struct mxs_dma_chan *pchan; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	pchan = mxs_dma_channels + channel; + +	if (pchan->flags & MXS_DMA_FLAGS_BUSY) +		return -EBUSY; + +	pchan->dev = 0; +	pchan->active_num = 0; +	pchan->pending_num = 0; +	pchan->flags &= ~MXS_DMA_FLAGS_ALLOCATED; + +	return 0; +} + +/* + * Allocate DMA descriptor + */ +struct mxs_dma_desc *mxs_dma_desc_alloc(void) +{ +	struct mxs_dma_desc *pdesc; +	uint32_t size; + +	size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); +	pdesc = memalign(MXS_DMA_ALIGNMENT, size); + +	if (pdesc == NULL) +		return NULL; + +	memset(pdesc, 0, sizeof(*pdesc)); +	pdesc->address = (dma_addr_t)pdesc; + +	return pdesc; +}; + +/* + * Free DMA descriptor + */ +void mxs_dma_desc_free(struct mxs_dma_desc *pdesc) +{ +	if (pdesc == NULL) +		return; + +	free(pdesc); +} + +/* + * Add a DMA descriptor to a channel. + * + * If the descriptor list for this channel is not empty, this function sets the + * CHAIN bit and the NEXTCMD_ADDR fields in the last descriptor's DMA command so + * it will chain to the new descriptor's command. + * + * Then, this function marks the new descriptor as "ready," adds it to the end + * of the active descriptor list, and increments the count of pending + * descriptors. + * + * The MXS platform DMA software imposes some rules on DMA commands to maintain + * important invariants. These rules are NOT checked, but they must be carefully + * applied by software that uses MXS DMA channels. + * + * Invariant: + *     The DMA channel's hardware semaphore must reflect the number of DMA + *     commands the hardware will process, but has not yet finished. + * + * Explanation: + *     A DMA channel begins processing commands when its hardware semaphore is + *     written with a value greater than zero, and it stops processing commands + *     when the semaphore returns to zero. + * + *     When a channel finishes a DMA command, it will decrement its semaphore if + *     the DECREMENT_SEMAPHORE bit is set in that command's flags bits. + * + *     In principle, it's not necessary for the DECREMENT_SEMAPHORE to be set, + *     unless it suits the purposes of the software. For example, one could + *     construct a series of five DMA commands, with the DECREMENT_SEMAPHORE + *     bit set only in the last one. Then, setting the DMA channel's hardware + *     semaphore to one would cause the entire series of five commands to be + *     processed. However, this example would violate the invariant given above. + * + * Rule: + *    ALL DMA commands MUST have the DECREMENT_SEMAPHORE bit set so that the DMA + *    channel's hardware semaphore will be decremented EVERY time a command is + *    processed. + */ +int mxs_dma_desc_append(int channel, struct mxs_dma_desc *pdesc) +{ +	struct mxs_dma_chan *pchan; +	struct mxs_dma_desc *last; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	pchan = mxs_dma_channels + channel; + +	pdesc->cmd.next = mxs_dma_cmd_address(pdesc); +	pdesc->flags |= MXS_DMA_DESC_FIRST | MXS_DMA_DESC_LAST; + +	if (!list_empty(&pchan->active)) { +		last = list_entry(pchan->active.prev, struct mxs_dma_desc, +					node); + +		pdesc->flags &= ~MXS_DMA_DESC_FIRST; +		last->flags &= ~MXS_DMA_DESC_LAST; + +		last->cmd.next = mxs_dma_cmd_address(pdesc); +		last->cmd.data |= MXS_DMA_DESC_CHAIN; + +		mxs_dma_flush_desc(last); +	} +	pdesc->flags |= MXS_DMA_DESC_READY; +	if (pdesc->flags & MXS_DMA_DESC_FIRST) +		pchan->pending_num++; +	list_add_tail(&pdesc->node, &pchan->active); + +	mxs_dma_flush_desc(pdesc); + +	return ret; +} + +/* + * Clean up processed DMA descriptors. + * + * This function removes processed DMA descriptors from the "active" list. Pass + * in a non-NULL list head to get the descriptors moved to your list. Pass NULL + * to get the descriptors moved to the channel's "done" list. Descriptors on + * the "done" list can be retrieved with mxs_dma_get_finished(). + * + * This function marks the DMA channel as "not busy" if no unprocessed + * descriptors remain on the "active" list. + */ +static int mxs_dma_finish(int channel, struct list_head *head) +{ +	int sem; +	struct mxs_dma_chan *pchan; +	struct list_head *p, *q; +	struct mxs_dma_desc *pdesc; +	int ret; + +	ret = mxs_dma_validate_chan(channel); +	if (ret) +		return ret; + +	pchan = mxs_dma_channels + channel; + +	sem = mxs_dma_read_semaphore(channel); +	if (sem < 0) +		return sem; + +	if (sem == pchan->active_num) +		return 0; + +	list_for_each_safe(p, q, &pchan->active) { +		if ((pchan->active_num) <= sem) +			break; + +		pdesc = list_entry(p, struct mxs_dma_desc, node); +		pdesc->flags &= ~MXS_DMA_DESC_READY; + +		if (head) +			list_move_tail(p, head); +		else +			list_move_tail(p, &pchan->done); + +		if (pdesc->flags & MXS_DMA_DESC_LAST) +			pchan->active_num--; +	} + +	if (sem == 0) +		pchan->flags &= ~MXS_DMA_FLAGS_BUSY; + +	return 0; +} + +/* + * Wait for DMA channel to complete + */ +static int mxs_dma_wait_complete(uint32_t timeout, unsigned int chan) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; +	int ret; + +	ret = mxs_dma_validate_chan(chan); +	if (ret) +		return ret; + +	if (mxs_wait_mask_set(&apbh_regs->hw_apbh_ctrl1_reg, +				1 << chan, timeout)) { +		ret = -ETIMEDOUT; +		mxs_dma_reset(chan); +	} + +	return ret; +} + +/* + * Execute the DMA channel + */ +int mxs_dma_go(int chan) +{ +	uint32_t timeout = 10000000; +	int ret; + +	LIST_HEAD(tmp_desc_list); + +	mxs_dma_enable_irq(chan, 1); +	mxs_dma_enable(chan); + +	/* Wait for DMA to finish. */ +	ret = mxs_dma_wait_complete(timeout, chan); + +	/* Clear out the descriptors we just ran. */ +	mxs_dma_finish(chan, &tmp_desc_list); + +	/* Shut the DMA channel down. */ +	mxs_dma_ack_irq(chan); +	mxs_dma_reset(chan); +	mxs_dma_enable_irq(chan, 0); +	mxs_dma_disable(chan); + +	return ret; +} + +/* + * Execute a continuously running circular DMA descriptor. + * NOTE: This is not intended for general use, but rather + *	 for the LCD driver in Smart-LCD mode. It allows + *	 continuous triggering of the RUN bit there. + */ +void mxs_dma_circ_start(int chan, struct mxs_dma_desc *pdesc) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; + +	mxs_dma_flush_desc(pdesc); + +	mxs_dma_enable_irq(chan, 1); + +	writel(mxs_dma_cmd_address(pdesc), +		&apbh_regs->ch[chan].hw_apbh_ch_nxtcmdar); +	writel(1, &apbh_regs->ch[chan].hw_apbh_ch_sema); +	writel(1 << (chan + APBH_CTRL0_CLKGATE_CHANNEL_OFFSET), +		&apbh_regs->hw_apbh_ctrl0_clr); +} + +/* + * Initialize the DMA hardware + */ +void mxs_dma_init(void) +{ +	struct mxs_apbh_regs *apbh_regs = +		(struct mxs_apbh_regs *)MXS_APBH_BASE; + +	mxs_reset_block(&apbh_regs->hw_apbh_ctrl0_reg); + +#ifdef CONFIG_APBH_DMA_BURST8 +	writel(APBH_CTRL0_AHB_BURST8_EN, +		&apbh_regs->hw_apbh_ctrl0_set); +#else +	writel(APBH_CTRL0_AHB_BURST8_EN, +		&apbh_regs->hw_apbh_ctrl0_clr); +#endif + +#ifdef CONFIG_APBH_DMA_BURST +	writel(APBH_CTRL0_APB_BURST_EN, +		&apbh_regs->hw_apbh_ctrl0_set); +#else +	writel(APBH_CTRL0_APB_BURST_EN, +		&apbh_regs->hw_apbh_ctrl0_clr); +#endif +} + +int mxs_dma_init_channel(int channel) +{ +	struct mxs_dma_chan *pchan; +	int ret; + +	pchan = mxs_dma_channels + channel; +	pchan->flags = MXS_DMA_FLAGS_VALID; + +	ret = mxs_dma_request(channel); + +	if (ret) { +		printf("MXS DMA: Can't acquire DMA channel %i\n", +			channel); +		return ret; +	} + +	mxs_dma_reset(channel); +	mxs_dma_ack_irq(channel); + +	return 0; +} diff --git a/roms/u-boot/drivers/dma/fsl_dma.c b/roms/u-boot/drivers/dma/fsl_dma.c new file mode 100644 index 00000000..45e49c7f --- /dev/null +++ b/roms/u-boot/drivers/dma/fsl_dma.c @@ -0,0 +1,168 @@ +/* + * Copyright 2004,2007,2008 Freescale Semiconductor, Inc. + * (C) Copyright 2002, 2003 Motorola Inc. + * Xianghua Xiao (X.Xiao@motorola.com) + * + * (C) Copyright 2000 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +#include <config.h> +#include <common.h> +#include <asm/io.h> +#include <asm/fsl_dma.h> + +/* Controller can only transfer 2^26 - 1 bytes at a time */ +#define FSL_DMA_MAX_SIZE	(0x3ffffff) + +#if defined(CONFIG_MPC83xx) +#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_CTM_DIRECT | FSL_DMA_MR_DMSEN) +#else +#define FSL_DMA_MR_DEFAULT (FSL_DMA_MR_BWC_DIS | FSL_DMA_MR_CTM_DIRECT) +#endif + + +#if defined(CONFIG_MPC83xx) +dma83xx_t *dma_base = (void *)(CONFIG_SYS_MPC83xx_DMA_ADDR); +#elif defined(CONFIG_MPC85xx) +ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC85xx_DMA_ADDR); +#elif defined(CONFIG_MPC86xx) +ccsr_dma_t *dma_base = (void *)(CONFIG_SYS_MPC86xx_DMA_ADDR); +#else +#error "Freescale DMA engine not supported on your processor" +#endif + +static void dma_sync(void) +{ +#if defined(CONFIG_MPC85xx) +	asm("sync; isync; msync"); +#elif defined(CONFIG_MPC86xx) +	asm("sync; isync"); +#endif +} + +static void out_dma32(volatile unsigned *addr, int val) +{ +#if defined(CONFIG_MPC83xx) +	out_le32(addr, val); +#else +	out_be32(addr, val); +#endif +} + +static uint in_dma32(volatile unsigned *addr) +{ +#if defined(CONFIG_MPC83xx) +	return in_le32(addr); +#else +	return in_be32(addr); +#endif +} + +static uint dma_check(void) { +	volatile fsl_dma_t *dma = &dma_base->dma[0]; +	uint status; + +	/* While the channel is busy, spin */ +	do { +		status = in_dma32(&dma->sr); +	} while (status & FSL_DMA_SR_CB); + +	/* clear MR[CS] channel start bit */ +	out_dma32(&dma->mr, in_dma32(&dma->mr) & ~FSL_DMA_MR_CS); +	dma_sync(); + +	if (status != 0) +		printf ("DMA Error: status = %x\n", status); + +	return status; +} + +#if !defined(CONFIG_MPC83xx) +void dma_init(void) { +	volatile fsl_dma_t *dma = &dma_base->dma[0]; + +	out_dma32(&dma->satr, FSL_DMA_SATR_SREAD_SNOOP); +	out_dma32(&dma->datr, FSL_DMA_DATR_DWRITE_SNOOP); +	out_dma32(&dma->sr, 0xffffffff); /* clear any errors */ +	dma_sync(); +} +#endif + +int dmacpy(phys_addr_t dest, phys_addr_t src, phys_size_t count) { +	volatile fsl_dma_t *dma = &dma_base->dma[0]; +	uint xfer_size; + +	while (count) { +		xfer_size = MIN(FSL_DMA_MAX_SIZE, count); + +		out_dma32(&dma->dar, (u32) (dest & 0xFFFFFFFF)); +		out_dma32(&dma->sar, (u32) (src & 0xFFFFFFFF)); +#if !defined(CONFIG_MPC83xx) +		out_dma32(&dma->satr, +			in_dma32(&dma->satr) | (u32)((u64)src >> 32)); +		out_dma32(&dma->datr, +			in_dma32(&dma->datr) | (u32)((u64)dest >> 32)); +#endif +		out_dma32(&dma->bcr, xfer_size); +		dma_sync(); + +		/* Prepare mode register */ +		out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT); +		dma_sync(); + +		/* Start the transfer */ +		out_dma32(&dma->mr, FSL_DMA_MR_DEFAULT | FSL_DMA_MR_CS); + +		count -= xfer_size; +		src += xfer_size; +		dest += xfer_size; + +		dma_sync(); + +		if (dma_check()) +			return -1; +	} + +	return 0; +} + +/* + * 85xx/86xx use dma to initialize SDRAM when !CONFIG_ECC_INIT_VIA_DDRCONTROLLER + * while 83xx uses dma to initialize SDRAM when CONFIG_DDR_ECC_INIT_VIA_DMA + */ +#if ((!defined CONFIG_MPC83xx && defined(CONFIG_DDR_ECC) &&	\ +	!defined(CONFIG_ECC_INIT_VIA_DDRCONTROLLER)) ||		\ +	(defined(CONFIG_MPC83xx) && defined(CONFIG_DDR_ECC_INIT_VIA_DMA))) +void dma_meminit(uint val, uint size) +{ +	uint *p = 0; +	uint i = 0; + +	for (*p = 0; p < (uint *)(8 * 1024); p++) { +		if (((uint)p & 0x1f) == 0) +			ppcDcbz((ulong)p); + +		*p = (uint)CONFIG_MEM_INIT_VALUE; + +		if (((uint)p & 0x1c) == 0x1c) +			ppcDcbf((ulong)p); +	} + +	dmacpy(0x002000, 0, 0x002000); /* 8K */ +	dmacpy(0x004000, 0, 0x004000); /* 16K */ +	dmacpy(0x008000, 0, 0x008000); /* 32K */ +	dmacpy(0x010000, 0, 0x010000); /* 64K */ +	dmacpy(0x020000, 0, 0x020000); /* 128K */ +	dmacpy(0x040000, 0, 0x040000); /* 256K */ +	dmacpy(0x080000, 0, 0x080000); /* 512K */ +	dmacpy(0x100000, 0, 0x100000); /* 1M */ +	dmacpy(0x200000, 0, 0x200000); /* 2M */ +	dmacpy(0x400000, 0, 0x400000); /* 4M */ + +	for (i = 1; i < size / 0x800000; i++) +		dmacpy((0x800000 * i), 0, 0x800000); +} +#endif diff --git a/roms/u-boot/drivers/dma/omap3_dma.c b/roms/u-boot/drivers/dma/omap3_dma.c new file mode 100644 index 00000000..3320b3d0 --- /dev/null +++ b/roms/u-boot/drivers/dma/omap3_dma.c @@ -0,0 +1,167 @@ +/* Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> + * + * SPDX-License-Identifier:	GPL-2.0+ + */ + +/* This is a basic implementation of the SDMA/DMA4 controller of OMAP3 + * Tested on Silicon Revision major:0x4 minor:0x0 + */ + +#include <common.h> +#include <asm/arch/cpu.h> +#include <asm/arch/omap3.h> +#include <asm/arch/dma.h> +#include <asm/io.h> +#include <asm/errno.h> + +static struct dma4 *dma4_cfg = (struct dma4 *)OMAP34XX_DMA4_BASE; +uint32_t dma_active; /* if a transfer is started the respective +	bit is set for the logical channel */ + +/* Check if we have the given channel + * PARAMETERS: + * chan: Channel number + * + * RETURN of non-zero means error */ +static inline int check_channel(uint32_t chan) +{ +	if (chan < CHAN_NR_MIN || chan > CHAN_NR_MAX) +		return -EINVAL; +	return 0; +} + +static inline void reset_irq(uint32_t chan) +{ +	/* reset IRQ reason */ +	writel(0x1DFE, &dma4_cfg->chan[chan].csr); +	/* reset IRQ */ +	writel((1 << chan), &dma4_cfg->irqstatus_l[0]); +	dma_active &= ~(1 << chan); +} + +/* Set Source, Destination and Size of DMA transfer for the + * specified channel. + * PARAMETERS: + * chan: channel to use + * src: source of the transfer + * dst: destination of the transfer + * sze: Size of the transfer + * + * RETURN of non-zero means error */ +int omap3_dma_conf_transfer(uint32_t chan, uint32_t *src, uint32_t *dst, +		uint32_t sze) +{ +	if (check_channel(chan)) +		return -EINVAL; +	/* CDSA0 */ +	writel((uint32_t)src, &dma4_cfg->chan[chan].cssa); +	writel((uint32_t)dst, &dma4_cfg->chan[chan].cdsa); +	writel(sze, &dma4_cfg->chan[chan].cen); +return 0; +} + +/* Start the DMA transfer */ +int omap3_dma_start_transfer(uint32_t chan) +{ +	uint32_t val; + +	if (check_channel(chan)) +		return -EINVAL; + +	val = readl(&dma4_cfg->chan[chan].ccr); +	/* Test for channel already in use */ +	if (val & CCR_ENABLE_ENABLE) +		return -EBUSY; + +	writel((val | CCR_ENABLE_ENABLE), &dma4_cfg->chan[chan].ccr); +	dma_active |= (1 << chan); +	debug("started transfer...\n"); +	return 0; +} + +/* Busy-waiting for a DMA transfer + * This has to be called before another transfer is started + * PARAMETER + * chan: Channel to wait for + * + * RETURN of non-zero means error*/ +int omap3_dma_wait_for_transfer(uint32_t chan) +{ +	uint32_t val; + +	if (!(dma_active & (1 << chan))) { +		val = readl(&dma4_cfg->irqstatus_l[0]); +		if (!(val & chan)) { +			debug("dma: The channel you are trying to wait for " +				"was never activated - ERROR\n"); +			return -1; /* channel was never active */ +		} +	} + +	/* all irqs on line 0 */ +	while (!(readl(&dma4_cfg->irqstatus_l[0]) & (1 << chan))) +		asm("nop"); + +	val = readl(&dma4_cfg->chan[chan].csr); +	if ((val & CSR_TRANS_ERR) | (val & CSR_SUPERVISOR_ERR) | +			(val & CSR_MISALIGNED_ADRS_ERR)) { +		debug("err code: %X\n", val); +		debug("dma: transfer error detected\n"); +		reset_irq(chan); +		return -1; +	} +	reset_irq(chan); +	return 0; +} + +/* Get the revision of the DMA module + * PARAMETER + * minor: Address of minor revision to write + * major: Address of major revision to write + * + * RETURN of non-zero means error + */ +int omap3_dma_get_revision(uint32_t *minor, uint32_t *major) +{ +	uint32_t val; + +	/* debug information */ +	val = readl(&dma4_cfg->revision); +	*major = (val & 0x000000F0) >> 4; +	*minor = (val & 0x0000000F); +	debug("DMA Silicon revision (maj/min): 0x%X/0x%X\n", *major, *minor); +	return 0; +} + +/* Initial config of omap dma + */ +void omap3_dma_init(void) +{ +	dma_active = 0; +	/* All interrupts on channel 0 */ +	writel(0xFFFFFFFF, &dma4_cfg->irqenable_l[0]); +} + +/* set channel config to config + * + * RETURN of non-zero means error */ +int omap3_dma_conf_chan(uint32_t chan, struct dma4_chan *config) +{ +	if (check_channel(chan)) +		return -EINVAL; + +	dma4_cfg->chan[chan] = *config; +	return 0; +} + +/* get channel config to config + * + * RETURN of non-zero means error */ +int omap3_dma_get_conf_chan(uint32_t chan, struct dma4_chan *config) +{ +	if (check_channel(chan)) +		return -EINVAL; +	*config = dma4_cfg->chan[chan]; +	return 0; +}  | 
