summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/MCD_dmaApi.c1026
-rw-r--r--drivers/dma/MCD_tasks.c2428
-rw-r--r--drivers/dma/MCD_tasksInit.c247
-rw-r--r--drivers/dma/Makefile46
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/fsl_law.c70
-rw-r--r--drivers/mtd/nand/Makefile2
-rw-r--r--drivers/mtd/nand/fsl_upm.c201
-rw-r--r--drivers/mtd/onenand/Makefile2
-rw-r--r--drivers/mtd/onenand/onenand_base.c20
-rw-r--r--drivers/mtd/onenand/onenand_uboot.c41
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/fsl_mcdmafec.c571
-rw-r--r--drivers/net/rtl8139.c23
-rw-r--r--drivers/net/tsec.c117
-rw-r--r--drivers/net/tsec.h8
-rw-r--r--drivers/qe/uec.c112
-rw-r--r--drivers/qe/uec_phy.c61
-rw-r--r--drivers/spi/Makefile46
-rw-r--r--drivers/spi/mpc8xxx_spi.c143
20 files changed, 5063 insertions, 103 deletions
diff --git a/drivers/dma/MCD_dmaApi.c b/drivers/dma/MCD_dmaApi.c
new file mode 100644
index 0000000..b0062b7
--- /dev/null
+++ b/drivers/dma/MCD_dmaApi.c
@@ -0,0 +1,1026 @@
+/*
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*Main C file for multi-channel DMA API. */
+
+#include <common.h>
+
+#ifdef CONFIG_FSLDMAFEC
+
+#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(srcAddr, srcAddr, destAddr, MCD_taskTable,
+ channel);
+ } else if (flags & MCD_FECRX_DMA) {
+ /* TDTStart and TDTEnd */
+ MCD_taskTable[channel].TDTstart =
+ MCD_modelTaskTable[TASK_FECRX].TDTstart;
+ MCD_taskTable[channel].TDTend =
+ MCD_modelTaskTable[TASK_FECRX].TDTend;
+ MCD_startDmaENetRcv(srcAddr, srcAddr, destAddr, MCD_taskTable,
+ channel);
+ } else if (flags & MCD_SINGLE_DMA) {
+ /* this buffer descriptor is used for storing off initial
+ parameters for later progress query calculation and for the
+ DMA to write the resulting checksum. The DMA does not use
+ this to determine how to operate, that info is passed with
+ the init routine */
+ MCD_relocBuffDesc[channel].srcAddr = srcAddr;
+ MCD_relocBuffDesc[channel].destAddr = destAddr;
+
+ /* 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(srcAddr, srcIncr, destAddr,
+ destIncr, dmaSize, xferSizeIncr,
+ flags, (int *)
+ &(MCD_relocBuffDesc[channel]),
+ cSave, MCD_taskTable, channel);
+ } else {
+ /* TDTStart and TDTEnd */
+ MCD_taskTable[channel].TDTstart =
+ MCD_modelTaskTable[TASK_SINGLEEU].TDTstart;
+ MCD_taskTable[channel].TDTend =
+ MCD_modelTaskTable[TASK_SINGLEEU].TDTend;
+ MCD_startDmaSingleEu(srcAddr, srcIncr, destAddr,
+ destIncr, dmaSize, xferSizeIncr,
+ flags, (int *)
+ &(MCD_relocBuffDesc[channel]),
+ cSave, MCD_taskTable, channel);
+ }
+ } else { /* chained 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;
+}
+#endif /* CONFIG_FSLDMAFEC */
diff --git a/drivers/dma/MCD_tasks.c b/drivers/dma/MCD_tasks.c
new file mode 100644
index 0000000..694e780
--- /dev/null
+++ b/drivers/dma/MCD_tasks.c
@@ -0,0 +1,2428 @@
+/*
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/* Contains task code and structures for Multi-channel DMA */
+
+#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/drivers/dma/MCD_tasksInit.c b/drivers/dma/MCD_tasksInit.c
new file mode 100644
index 0000000..0d28713
--- /dev/null
+++ b/drivers/dma/MCD_tasksInit.c
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+/* Functions for initializing variable tables of different types of tasks. */
+
+/*
+ * Do not edit!
+ */
+
+#ifdef CONFIG_FSLDMAFEC
+
+#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;
+}
+
+#endif /* CONFIG_FSLDMAFEC */
+
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
new file mode 100644
index 0000000..2dd5a0e
--- /dev/null
+++ b/drivers/dma/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2006
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libdma.a
+
+COBJS-y += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 78cec21..67521720 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -28,6 +28,7 @@ LIB := $(obj)libmisc.a
COBJS-y += ali512x.o
COBJS-y += ns87308.o
COBJS-y += status_led.o
+COBJS-$(CONFIG_FSL_LAW) += fsl_law.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/misc/fsl_law.c b/drivers/misc/fsl_law.c
new file mode 100644
index 0000000..8bdf5a7
--- /dev/null
+++ b/drivers/misc/fsl_law.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc.
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/fsl_law.h>
+#include <asm/io.h>
+
+#define LAWAR_EN 0x80000000
+
+void set_law(u8 idx, phys_addr_t addr, enum law_size sz, enum law_trgt_if id)
+{
+ volatile u32 *base = (volatile u32 *)(CFG_IMMR + 0xc08);
+ volatile u32 *lawbar = base + 8 * idx;
+ volatile u32 *lawar = base + 8 * idx + 2;
+
+ out_be32(lawbar, addr >> 12);
+ out_be32(lawar, LAWAR_EN | ((u32)id << 20) | (u32)sz);
+
+ return ;
+}
+
+void disable_law(u8 idx)
+{
+ volatile u32 *base = (volatile u32 *)(CFG_IMMR + 0xc08);
+ volatile u32 *lawbar = base + 8 * idx;
+ volatile u32 *lawar = base + 8 * idx + 2;
+
+ out_be32(lawar, 0);
+ out_be32(lawbar, 0);
+
+ return;
+}
+
+void init_laws(void)
+{
+ int i;
+ u8 law_idx = 0;
+
+ for (i = 0; i < num_law_entries; i++) {
+ if (law_table[i].index != -1)
+ law_idx = law_table[i].index;
+
+ set_law(law_idx++, law_table[i].addr,
+ law_table[i].size, law_table[i].trgt_id);
+ }
+
+ return ;
+}
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 42864f9..244fa09 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -32,6 +32,8 @@ COBJS-y += nand_ecc.o
COBJS-y += nand_bbt.o
COBJS-y += nand_util.o
+COBJS-y += fsl_upm.o
+
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
new file mode 100644
index 0000000..5cc410a
--- /dev/null
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -0,0 +1,201 @@
+/*
+ * FSL UPM NAND driver
+ *
+ * Copyright (C) 2007 MontaVista Software, Inc.
+ * Anton Vorontsov <avorontsov@ru.mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <config.h>
+
+#if defined(CONFIG_CMD_NAND) && defined(CONFIG_NAND_FSL_UPM)
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/fsl_upm.h>
+#include <nand.h>
+
+#define FSL_UPM_MxMR_OP_NO (0 << 28) /* normal operation */
+#define FSL_UPM_MxMR_OP_WA (1 << 28) /* write array */
+#define FSL_UPM_MxMR_OP_RA (2 << 28) /* read array */
+#define FSL_UPM_MxMR_OP_RP (3 << 28) /* run pattern */
+
+static void fsl_upm_start_pattern(struct fsl_upm *upm, u32 pat_offset)
+{
+ out_be32(upm->mxmr, FSL_UPM_MxMR_OP_RP | pat_offset);
+}
+
+static void fsl_upm_end_pattern(struct fsl_upm *upm)
+{
+ out_be32(upm->mxmr, FSL_UPM_MxMR_OP_NO);
+ while (in_be32(upm->mxmr) != FSL_UPM_MxMR_OP_NO)
+ eieio();
+}
+
+static void fsl_upm_run_pattern(struct fsl_upm *upm, int width, u32 cmd)
+{
+ out_be32(upm->mar, cmd << (32 - width * 8));
+ out_8(upm->io_addr, 0x0);
+}
+
+static void fsl_upm_setup(struct fsl_upm *upm)
+{
+ int i;
+
+ /* write upm array */
+ out_be32(upm->mxmr, FSL_UPM_MxMR_OP_WA);
+
+ for (i = 0; i < 64; i++) {
+ out_be32(upm->mdr, upm->array[i]);
+ out_8(upm->io_addr, 0x0);
+ }
+
+ /* normal operation */
+ out_be32(upm->mxmr, FSL_UPM_MxMR_OP_NO);
+ while (in_be32(upm->mxmr) != FSL_UPM_MxMR_OP_NO)
+ eieio();
+}
+
+static void fun_cmdfunc(struct mtd_info *mtd, unsigned command, int column,
+ int page_addr)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct fsl_upm_nand *fun = chip->priv;
+
+ fsl_upm_start_pattern(&fun->upm, fun->upm_cmd_offset);
+
+ if (command == NAND_CMD_SEQIN) {
+ int readcmd;
+
+ if (column >= mtd->oobblock) {
+ /* OOB area */
+ column -= mtd->oobblock;
+ readcmd = NAND_CMD_READOOB;
+ } else if (column < 256) {
+ /* First 256 bytes --> READ0 */
+ readcmd = NAND_CMD_READ0;
+ } else {
+ column -= 256;
+ readcmd = NAND_CMD_READ1;
+ }
+ fsl_upm_run_pattern(&fun->upm, fun->width, readcmd);
+ }
+
+ fsl_upm_run_pattern(&fun->upm, fun->width, command);
+
+ fsl_upm_end_pattern(&fun->upm);
+
+ fsl_upm_start_pattern(&fun->upm, fun->upm_addr_offset);
+
+ if (column != -1)
+ fsl_upm_run_pattern(&fun->upm, fun->width, column);
+
+ if (page_addr != -1) {
+ fsl_upm_run_pattern(&fun->upm, fun->width, page_addr);
+ fsl_upm_run_pattern(&fun->upm, fun->width,
+ (page_addr >> 8) & 0xFF);
+ if (chip->chipsize > (32 << 20)) {
+ fsl_upm_run_pattern(&fun->upm, fun->width,
+ (page_addr >> 16) & 0x0f);
+ }
+ }
+
+ fsl_upm_end_pattern(&fun->upm);
+
+ if (fun->wait_pattern) {
+ /*
+ * Some boards/chips needs this. At least on MPC8360E-RDK we
+ * need it. Probably weird chip, because I don't see any need
+ * for this on MPC8555E + Samsung K9F1G08U0A. Usually here are
+ * 0-2 unexpected busy states per block read.
+ */
+ while (!fun->dev_ready())
+ debug("unexpected busy state\n");
+ }
+}
+
+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ out_8(chip->IO_ADDR_W, byte);
+}
+
+static u8 nand_read_byte(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+
+ return in_8(chip->IO_ADDR_R);
+}
+
+static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+ for (i = 0; i < len; i++)
+ out_8(chip->IO_ADDR_W, buf[i]);
+}
+
+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+ for (i = 0; i < len; i++)
+ buf[i] = in_8(chip->IO_ADDR_R);
+}
+
+static int nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
+{
+ int i;
+ struct nand_chip *chip = mtd->priv;
+
+ for (i = 0; i < len; i++) {
+ if (buf[i] != in_8(chip->IO_ADDR_R))
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+static void nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+}
+
+static int nand_dev_ready(struct mtd_info *mtd)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct fsl_upm_nand *fun = chip->priv;
+
+ return fun->dev_ready();
+}
+
+int fsl_upm_nand_init(struct nand_chip *chip, struct fsl_upm_nand *fun)
+{
+ /* yet only 8 bit accessors implemented */
+ if (fun->width != 1)
+ return -ENOSYS;
+
+ fsl_upm_setup(&fun->upm);
+
+ chip->priv = fun;
+ chip->chip_delay = fun->chip_delay;
+ chip->eccmode = NAND_ECC_SOFT;
+ chip->cmdfunc = fun_cmdfunc;
+ chip->hwcontrol = nand_hwcontrol;
+ chip->read_byte = nand_read_byte;
+ chip->read_buf = nand_read_buf;
+ chip->write_byte = nand_write_byte;
+ chip->write_buf = nand_write_buf;
+ chip->verify_buf = nand_verify_buf;
+ chip->dev_ready = nand_dev_ready;
+
+ return 0;
+}
+#endif /* CONFIG_CMD_NAND */
diff --git a/drivers/mtd/onenand/Makefile b/drivers/mtd/onenand/Makefile
index 2049413..92074b2 100644
--- a/drivers/mtd/onenand/Makefile
+++ b/drivers/mtd/onenand/Makefile
@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libonenand.a
-COBJS := onenand_base.o onenand_bbt.o
+COBJS := onenand_uboot.o onenand_base.o onenand_bbt.o
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 7983a4a..d4003a2 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1271,24 +1271,4 @@ void onenand_release(struct mtd_info *mtd)
{
}
-/*
- * OneNAND initialization at U-Boot
- */
-struct mtd_info onenand_mtd;
-struct onenand_chip onenand_chip;
-
-void onenand_init(void)
-{
- memset(&onenand_mtd, 0, sizeof(struct mtd_info));
- memset(&onenand_chip, 0, sizeof(struct onenand_chip));
-
- onenand_chip.base = (void *)CFG_ONENAND_BASE;
- onenand_mtd.priv = &onenand_chip;
-
- onenand_scan(&onenand_mtd, 1);
-
- puts("OneNAND: ");
- print_size(onenand_mtd.size, "\n");
-}
-
#endif /* CONFIG_CMD_ONENAND */
diff --git a/drivers/mtd/onenand/onenand_uboot.c b/drivers/mtd/onenand/onenand_uboot.c
new file mode 100644
index 0000000..bd7466a
--- /dev/null
+++ b/drivers/mtd/onenand/onenand_uboot.c
@@ -0,0 +1,41 @@
+/*
+ * drivers/mtd/onenand/onenand_uboot.c
+ *
+ * Copyright (C) 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/*
+ * OneNAND initialization at U-Boot
+ */
+
+#include <common.h>
+
+#ifdef CONFIG_CMD_ONENAND
+
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+struct mtd_info onenand_mtd;
+struct onenand_chip onenand_chip;
+
+void onenand_init(void)
+{
+ memset(&onenand_mtd, 0, sizeof(struct mtd_info));
+ memset(&onenand_chip, 0, sizeof(struct onenand_chip));
+
+ onenand_chip.base = (void *) CFG_ONENAND_BASE;
+ onenand_mtd.priv = &onenand_chip;
+
+ onenand_scan(&onenand_mtd, 1);
+
+ puts("OneNAND: ");
+ print_size(onenand_mtd.size, "\n");
+}
+
+#endif /* CONFIG_CMD_ONENAND */
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 41e1bde..b9723fa 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -33,6 +33,7 @@ COBJS-y += dm9000x.o
COBJS-y += e1000.o
COBJS-y += eepro100.o
COBJS-y += enc28j60.o
+COBJS-y += fsl_mcdmafec.o
COBJS-y += inca-ip_sw.o
COBJS-y += ks8695eth.o
COBJS-y += lan91c96.o
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
new file mode 100644
index 0000000..0c876f3
--- /dev/null
+++ b/drivers/net/fsl_mcdmafec.c
@@ -0,0 +1,571 @@
+/*
+ * (C) Copyright 2000-2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2007 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <command.h>
+#include <config.h>
+#include <net.h>
+#include <miiphy.h>
+
+#ifdef CONFIG_FSLDMAFEC
+#undef ET_DEBUG
+#undef MII_DEBUG
+
+/* Ethernet Transmit and Receive Buffers */
+#define DBUF_LENGTH 1520
+#define PKT_MAXBUF_SIZE 1518
+#define PKT_MINBUF_SIZE 64
+#define PKT_MAXBLR_SIZE 1536
+#define LAST_PKTBUFSRX PKTBUFSRX - 1
+#define BD_ENET_RX_W_E (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)
+#define BD_ENET_TX_RDY_LST (BD_ENET_TX_READY | BD_ENET_TX_LAST)
+#define FIFO_ERRSTAT (FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF)
+
+/* RxBD bits definitions */
+#define BD_ENET_RX_ERR (BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR | \
+ BD_ENET_RX_OV | BD_ENET_RX_TR)
+
+#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI)
+#include <asm/immap.h>
+#include <asm/fsl_mcdmafec.h>
+
+#include "MCD_dma.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct fec_info_dma fec_info[] = {
+#ifdef CFG_FEC0_IOBASE
+ {
+ 0, /* index */
+ CFG_FEC0_IOBASE, /* io base */
+ CFG_FEC0_PINMUX, /* gpio pin muxing */
+ CFG_FEC0_MIIBASE, /* mii base */
+ -1, /* phy_addr */
+ 0, /* duplex and speed */
+ 0, /* phy name */
+ 0, /* phyname init */
+ 0, /* RX BD */
+ 0, /* TX BD */
+ 0, /* rx Index */
+ 0, /* tx Index */
+ 0, /* tx buffer */
+ 0, /* initialized flag */
+ (struct fec_info_dma *)-1, /* next */
+ FEC0_RX_TASK, /* rxTask */
+ FEC0_TX_TASK, /* txTask */
+ FEC0_RX_PRIORITY, /* rxPri */
+ FEC0_TX_PRIORITY, /* txPri */
+ FEC0_RX_INIT, /* rxInit */
+ FEC0_TX_INIT, /* txInit */
+ 0, /* usedTbdIndex */
+ 0, /* cleanTbdNum */
+ },
+#endif
+#ifdef CFG_FEC1_IOBASE
+ {
+ 1, /* index */
+ CFG_FEC1_IOBASE, /* io base */
+ CFG_FEC1_PINMUX, /* gpio pin muxing */
+ CFG_FEC1_MIIBASE, /* mii base */
+ -1, /* phy_addr */
+ 0, /* duplex and speed */
+ 0, /* phy name */
+ 0, /* phy name init */
+ 0, /* RX BD */
+ 0, /* TX BD */
+ 0, /* rx Index */
+ 0, /* tx Index */
+ 0, /* tx buffer */
+ 0, /* initialized flag */
+ (struct fec_info_dma *)-1, /* next */
+ FEC1_RX_TASK, /* rxTask */
+ FEC1_TX_TASK, /* txTask */
+ FEC1_RX_PRIORITY, /* rxPri */
+ FEC1_TX_PRIORITY, /* txPri */
+ FEC1_RX_INIT, /* rxInit */
+ FEC1_TX_INIT, /* txInit */
+ 0, /* usedTbdIndex */
+ 0, /* cleanTbdNum */
+ }
+#endif
+};
+
+static int fec_send(struct eth_device *dev, volatile void *packet, int length);
+static int fec_recv(struct eth_device *dev);
+static int fec_init(struct eth_device *dev, bd_t * bd);
+static void fec_halt(struct eth_device *dev);
+
+#ifdef ET_DEBUG
+static void dbg_fec_regs(struct eth_device *dev)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+
+ printf("=====\n");
+ printf("ievent %x - %x\n", (int)&fecp->eir, fecp->eir);
+ printf("imask %x - %x\n", (int)&fecp->eimr, fecp->eimr);
+ printf("ecntrl %x - %x\n", (int)&fecp->ecr, fecp->ecr);
+ printf("mii_mframe %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);
+ printf("mii_speed %x - %x\n", (int)&fecp->mscr, fecp->mscr);
+ printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);
+ printf("r_cntrl %x - %x\n", (int)&fecp->rcr, fecp->rcr);
+ printf("r hash %x - %x\n", (int)&fecp->rhr, fecp->rhr);
+ printf("x_cntrl %x - %x\n", (int)&fecp->tcr, fecp->tcr);
+ printf("padr_l %x - %x\n", (int)&fecp->palr, fecp->palr);
+ printf("padr_u %x - %x\n", (int)&fecp->paur, fecp->paur);
+ printf("op_pause %x - %x\n", (int)&fecp->opd, fecp->opd);
+ printf("iadr_u %x - %x\n", (int)&fecp->iaur, fecp->iaur);
+ printf("iadr_l %x - %x\n", (int)&fecp->ialr, fecp->ialr);
+ printf("gadr_u %x - %x\n", (int)&fecp->gaur, fecp->gaur);
+ printf("gadr_l %x - %x\n", (int)&fecp->galr, fecp->galr);
+ printf("x_wmrk %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);
+ printf("r_fdata %x - %x\n", (int)&fecp->rfdr, fecp->rfdr);
+ printf("r_fstat %x - %x\n", (int)&fecp->rfsr, fecp->rfsr);
+ printf("r_fctrl %x - %x\n", (int)&fecp->rfcr, fecp->rfcr);
+ printf("r_flrfp %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp);
+ printf("r_flwfp %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp);
+ printf("r_frfar %x - %x\n", (int)&fecp->rfar, fecp->rfar);
+ printf("r_frfrp %x - %x\n", (int)&fecp->rfrp, fecp->rfrp);
+ printf("r_frfwp %x - %x\n", (int)&fecp->rfwp, fecp->rfwp);
+ printf("t_fdata %x - %x\n", (int)&fecp->tfdr, fecp->tfdr);
+ printf("t_fstat %x - %x\n", (int)&fecp->tfsr, fecp->tfsr);
+ printf("t_fctrl %x - %x\n", (int)&fecp->tfcr, fecp->tfcr);
+ printf("t_flrfp %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp);
+ printf("t_flwfp %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp);
+ printf("t_ftfar %x - %x\n", (int)&fecp->tfar, fecp->tfar);
+ printf("t_ftfrp %x - %x\n", (int)&fecp->tfrp, fecp->tfrp);
+ printf("t_ftfwp %x - %x\n", (int)&fecp->tfwp, fecp->tfwp);
+ printf("frst %x - %x\n", (int)&fecp->frst, fecp->frst);
+ printf("ctcwr %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr);
+}
+#endif
+
+static void set_fec_duplex_speed(volatile fecdma_t * fecp, bd_t * bd, int dup_spd)
+{
+ if ((dup_spd >> 16) == FULL) {
+ /* Set maximum frame length */
+ fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |
+ FEC_RCR_PROM | 0x100;
+ fecp->tcr = FEC_TCR_FDEN;
+ } else {
+ /* Half duplex mode */
+ fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |
+ FEC_RCR_MII_MODE | FEC_RCR_DRT;
+ fecp->tcr &= ~FEC_TCR_FDEN;
+ }
+
+ if ((dup_spd & 0xFFFF) == _100BASET) {
+#ifdef MII_DEBUG
+ printf("100Mbps\n");
+#endif
+ bd->bi_ethspeed = 100;
+ } else {
+#ifdef MII_DEBUG
+ printf("10Mbps\n");
+#endif
+ bd->bi_ethspeed = 10;
+ }
+}
+
+static int fec_send(struct eth_device *dev, volatile void *packet, int length)
+{
+ struct fec_info_dma *info = dev->priv;
+ cbd_t *pTbd, *pUsedTbd;
+ u16 phyStatus;
+
+ miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &phyStatus);
+
+ /* process all the consumed TBDs */
+ while (info->cleanTbdNum < CFG_TX_ETH_BUFFER) {
+ pUsedTbd = &info->txbd[info->usedTbdIdx];
+ if (pUsedTbd->cbd_sc & BD_ENET_TX_READY) {
+#ifdef ET_DEBUG
+ printf("Cannot clean TBD %d, in use\n",
+ info->cleanTbdNum);
+#endif
+ return 0;
+ }
+
+ /* clean this buffer descriptor */
+ if (info->usedTbdIdx == (CFG_TX_ETH_BUFFER - 1))
+ pUsedTbd->cbd_sc = BD_ENET_TX_WRAP;
+ else
+ pUsedTbd->cbd_sc = 0;
+
+ /* update some indeces for a correct handling of the TBD ring */
+ info->cleanTbdNum++;
+ info->usedTbdIdx = (info->usedTbdIdx + 1) % CFG_TX_ETH_BUFFER;
+ }
+
+ /* Check for valid length of data. */
+ if ((length > 1500) || (length <= 0)) {
+ return -1;
+ }
+
+ /* Check the number of vacant TxBDs. */
+ if (info->cleanTbdNum < 1) {
+ printf("No available TxBDs ...\n");
+ return -1;
+ }
+
+ /* Get the first TxBD to send the mac header */
+ pTbd = &info->txbd[info->txIdx];
+ pTbd->cbd_datlen = length;
+ pTbd->cbd_bufaddr = (u32) packet;
+ pTbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY;
+ info->txIdx = (info->txIdx + 1) % CFG_TX_ETH_BUFFER;
+
+ /* Enable DMA transmit task */
+ MCD_continDma(info->txTask);
+
+ info->cleanTbdNum -= 1;
+
+ /* wait until frame is sent . */
+ while (pTbd->cbd_sc & BD_ENET_TX_READY) {
+ udelay(10);
+ }
+
+ return (int)(info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);
+}
+
+static int fec_recv(struct eth_device *dev)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+
+ cbd_t *pRbd = &info->rxbd[info->rxIdx];
+ u32 ievent;
+ int frame_length, len = 0;
+
+ /* Check if any critical events have happened */
+ ievent = fecp->eir;
+ if (ievent != 0) {
+ fecp->eir = ievent;
+
+ if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) {
+ printf("fec_recv: error\n");
+ fec_halt(dev);
+ fec_init(dev, NULL);
+ return 0;
+ }
+
+ if (ievent & FEC_EIR_HBERR) {
+ /* Heartbeat error */
+ fecp->tcr |= FEC_TCR_GTS;
+ }
+
+ if (ievent & FEC_EIR_GRA) {
+ /* Graceful stop complete */
+ if (fecp->tcr & FEC_TCR_GTS) {
+ printf("fec_recv: tcr_gts\n");
+ fec_halt(dev);
+ fecp->tcr &= ~FEC_TCR_GTS;
+ fec_init(dev, NULL);
+ }
+ }
+ }
+
+ if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) {
+ if ((pRbd->cbd_sc & BD_ENET_RX_LAST)
+ && !(pRbd->cbd_sc & BD_ENET_RX_ERR)
+ && ((pRbd->cbd_datlen - 4) > 14)) {
+
+ /* Get buffer address and size */
+ frame_length = pRbd->cbd_datlen - 4;
+
+ /* Fill the buffer and pass it to upper layers */
+ NetReceive((volatile uchar *)pRbd->cbd_bufaddr,
+ frame_length);
+ len = frame_length;
+ }
+
+ /* Reset buffer descriptor as empty */
+ if ((info->rxIdx) == (PKTBUFSRX - 1))
+ pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+ else
+ pRbd->cbd_sc = BD_ENET_RX_EMPTY;
+
+ pRbd->cbd_datlen = PKTSIZE_ALIGN;
+
+ /* Now, we have an empty RxBD, restart the DMA receive task */
+ MCD_continDma(info->rxTask);
+
+ /* Increment BD count */
+ info->rxIdx = (info->rxIdx + 1) % PKTBUFSRX;
+ }
+
+ return len;
+}
+
+static void fec_set_hwaddr(volatile fecdma_t * fecp, u8 * mac)
+{
+ u8 currByte; /* byte for which to compute the CRC */
+ int byte; /* loop - counter */
+ int bit; /* loop - counter */
+ u32 crc = 0xffffffff; /* initial value */
+
+ for (byte = 0; byte < 6; byte++) {
+ currByte = mac[byte];
+ for (bit = 0; bit < 8; bit++) {
+ if ((currByte & 0x01) ^ (crc & 0x01)) {
+ crc >>= 1;
+ crc = crc ^ 0xedb88320;
+ } else {
+ crc >>= 1;
+ }
+ currByte >>= 1;
+ }
+ }
+
+ crc = crc >> 26;
+
+ /* Set individual hash table register */
+ if (crc >= 32) {
+ fecp->ialr = (1 << (crc - 32));
+ fecp->iaur = 0;
+ } else {
+ fecp->ialr = 0;
+ fecp->iaur = (1 << crc);
+ }
+
+ /* Set physical address */
+ fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];
+ fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808;
+
+ /* Clear multicast address hash table */
+ fecp->gaur = 0;
+ fecp->galr = 0;
+}
+
+static int fec_init(struct eth_device *dev, bd_t * bd)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+ int i;
+
+#ifdef ET_DEBUG
+ printf("fec_init: iobase 0x%08x ...\n", info->iobase);
+#endif
+
+ fecpin_setclear(dev, 1);
+
+ fec_halt(dev);
+
+#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \
+ defined (CFG_DISCOVER_PHY)
+
+ mii_init();
+
+ set_fec_duplex_speed(fecp, bd, info->dup_spd);
+#else
+#ifndef CFG_DISCOVER_PHY
+ set_fec_duplex_speed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);
+#endif /* ifndef CFG_DISCOVER_PHY */
+#endif /* CONFIG_CMD_MII || CONFIG_MII */
+
+ /* We use strictly polling mode only */
+ fecp->eimr = 0;
+
+ /* Clear any pending interrupt */
+ fecp->eir = 0xffffffff;
+
+ /* Set station address */
+ if ((u32) fecp == CFG_FEC0_IOBASE) {
+ fec_set_hwaddr(fecp, bd->bi_enetaddr);
+ } else {
+ fec_set_hwaddr(fecp, bd->bi_enet1addr);
+ }
+
+ /* Set Opcode/Pause Duration Register */
+ fecp->opd = 0x00010020;
+
+ /* Setup Buffers and Buffer Desriptors */
+ info->rxIdx = 0;
+ info->txIdx = 0;
+
+ /* Setup Receiver Buffer Descriptors (13.14.24.18)
+ * Settings: Empty, Wrap */
+ for (i = 0; i < PKTBUFSRX; i++) {
+ info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
+ info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN;
+ info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ }
+ info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
+
+ /* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)
+ * Settings: Last, Tx CRC */
+ for (i = 0; i < CFG_TX_ETH_BUFFER; i++) {
+ info->txbd[i].cbd_sc = 0;
+ info->txbd[i].cbd_datlen = 0;
+ info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);
+ }
+ info->txbd[CFG_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP;
+
+ info->usedTbdIdx = 0;
+ info->cleanTbdNum = CFG_TX_ETH_BUFFER;
+
+ /* Set Rx FIFO alarm and granularity value */
+ fecp->rfcr = 0x0c000000;
+ fecp->rfar = 0x0000030c;
+
+ /* Set Tx FIFO granularity value */
+ fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000;
+ fecp->tfar = 0x00000080;
+
+ fecp->tfwr = 0x2;
+ fecp->ctcwr = 0x03000000;
+
+ /* Enable DMA receive task */
+ MCD_startDma(info->rxTask, /* Dma channel */
+ (s8 *) info->rxbd, /*Source Address */
+ 0, /* Source increment */
+ (s8 *) (&fecp->rfdr), /* dest */
+ 4, /* dest increment */
+ 0, /* DMA size */
+ 4, /* xfer size */
+ info->rxInit, /* initiator */
+ info->rxPri, /* priority */
+ (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF), /* Flags */
+ (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */
+ );
+
+ /* Enable DMA tx task with no ready buffer descriptors */
+ MCD_startDma(info->txTask, /* Dma channel */
+ (s8 *) info->txbd, /*Source Address */
+ 0, /* Source increment */
+ (s8 *) (&fecp->tfdr), /* dest */
+ 4, /* dest incr */
+ 0, /* DMA size */
+ 4, /* xfer size */
+ info->txInit, /* initiator */
+ info->txPri, /* priority */
+ (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF), /* Flags */
+ (MCD_NO_CSUM | MCD_NO_BYTE_SWAP) /* Function description */
+ );
+
+ /* Now enable the transmit and receive processing */
+ fecp->ecr |= FEC_ECR_ETHER_EN;
+
+ return 1;
+}
+
+static void fec_halt(struct eth_device *dev)
+{
+ struct fec_info_dma *info = dev->priv;
+ volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
+ int counter = 0xffff;
+
+ /* issue graceful stop command to the FEC transmitter if necessary */
+ fecp->tcr |= FEC_TCR_GTS;
+
+ /* wait for graceful stop to register */
+ while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) ;
+
+ /* Disable DMA tasks */
+ MCD_killDma(info->txTask);
+ MCD_killDma(info->rxTask);;
+
+ /* Disable the Ethernet Controller */
+ fecp->ecr &= ~FEC_ECR_ETHER_EN;
+
+ /* Clear FIFO status registers */
+ fecp->rfsr &= FIFO_ERRSTAT;
+ fecp->tfsr &= FIFO_ERRSTAT;
+
+ fecp->frst = 0x01000000;
+
+ /* Issue a reset command to the FEC chip */
+ fecp->ecr |= FEC_ECR_RESET;
+
+ /* wait at least 20 clock cycles */
+ udelay(10000);
+
+#ifdef ET_DEBUG
+ printf("Ethernet task stopped\n");
+#endif
+}
+
+int mcdmafec_initialize(bd_t * bis)
+{
+ struct eth_device *dev;
+ int i;
+
+ for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) {
+
+ dev =
+ (struct eth_device *)memalign(CFG_CACHELINE_SIZE,
+ sizeof *dev);
+ if (dev == NULL)
+ hang();
+
+ memset(dev, 0, sizeof(*dev));
+
+ sprintf(dev->name, "FEC%d", fec_info[i].index);
+
+ dev->priv = &fec_info[i];
+ dev->init = fec_init;
+ dev->halt = fec_halt;
+ dev->send = fec_send;
+ dev->recv = fec_recv;
+
+ /* setup Receive and Transmit buffer descriptor */
+ fec_info[i].rxbd =
+ (cbd_t *) memalign(CFG_CACHELINE_SIZE,
+ (PKTBUFSRX * sizeof(cbd_t)));
+ fec_info[i].txbd =
+ (cbd_t *) memalign(CFG_CACHELINE_SIZE,
+ (CFG_TX_ETH_BUFFER * sizeof(cbd_t)));
+ fec_info[i].txbuf =
+ (char *)memalign(CFG_CACHELINE_SIZE, DBUF_LENGTH);
+
+#ifdef ET_DEBUG
+ printf("rxbd %x txbd %x\n",
+ (int)fec_info[i].rxbd, (int)fec_info[i].txbd);
+#endif
+
+ fec_info[i].phy_name = (char *)memalign(CFG_CACHELINE_SIZE, 32);
+
+ eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+ miiphy_register(dev->name,
+ mcffec_miiphy_read, mcffec_miiphy_write);
+#endif
+
+ if (i > 0)
+ fec_info[i - 1].next = &fec_info[i];
+ }
+ fec_info[i - 1].next = &fec_info[0];
+
+ /* default speed */
+ bis->bi_ethspeed = 10;
+
+ return 1;
+}
+
+#endif /* CONFIG_CMD_NET && CONFIG_NET_MULTI */
+#endif /* CONFIG_FSLDMAFEC */
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index 4c24805..097f684 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -80,10 +80,7 @@
#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \
defined(CONFIG_RTL8139)
-#define TICKS_PER_SEC CFG_HZ
-#define TICKS_PER_MS (TICKS_PER_SEC/1000)
-
-#define RTL_TIMEOUT (1*TICKS_PER_SEC)
+#define RTL_TIMEOUT 100000
#define ETH_FRAME_LEN 1514
#define ETH_ALEN 6
@@ -392,6 +389,7 @@ static void rtl_reset(struct eth_device *dev)
#ifdef DEBUG_RX
printf("rx ring address is %X\n",(unsigned long)rx_ring);
#endif
+ flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
outl(phys_to_bus((int)rx_ring), ioaddr + RxBuf);
/* If we add multicast support, the MAR0 register would have to be
@@ -414,9 +412,10 @@ static void rtl_reset(struct eth_device *dev)
static int rtl_transmit(struct eth_device *dev, volatile void *packet, int length)
{
- unsigned int status, to;
+ unsigned int status;
unsigned long txstatus;
unsigned int len = length;
+ int i = 0;
ioaddr = dev->iobase;
@@ -432,12 +431,11 @@ static int rtl_transmit(struct eth_device *dev, volatile void *packet, int lengt
tx_buffer[len++] = '\0';
}
+ flush_cache((unsigned long)tx_buffer, length);
outl(phys_to_bus((int)tx_buffer), ioaddr + TxAddr0 + cur_tx*4);
outl(((TX_FIFO_THRESH<<11) & 0x003f0000) | len,
ioaddr + TxStatus0 + cur_tx*4);
- to = currticks() + RTL_TIMEOUT;
-
do {
status = inw(ioaddr + IntrStatus);
/* Only acknlowledge interrupt sources we can properly handle
@@ -445,7 +443,8 @@ static int rtl_transmit(struct eth_device *dev, volatile void *packet, int lengt
* rtl_poll() function. */
outw(status & (TxOK | TxErr | PCIErr), ioaddr + IntrStatus);
if ((status & (TxOK | TxErr | PCIErr)) != 0) break;
- } while (currticks() < to);
+ udelay(10);
+ } while (i++ < RTL_TIMEOUT);
txstatus = inl(ioaddr + TxStatus0 + cur_tx*4);
@@ -458,8 +457,8 @@ static int rtl_transmit(struct eth_device *dev, volatile void *packet, int lengt
return length;
} else {
#ifdef DEBUG_TX
- printf("tx timeout/error (%d ticks), status %hX txstatus %X\n",
- currticks()-to, status, txstatus);
+ printf("tx timeout/error (%d usecs), status %hX txstatus %X\n",
+ 10*i, status, txstatus);
#endif
rtl_reset(dev);
@@ -489,7 +488,8 @@ static int rtl_poll(struct eth_device *dev)
#endif
ring_offs = cur_rx % RX_BUF_LEN;
- rx_status = *(unsigned int*)KSEG1ADDR((rx_ring + ring_offs));
+ /* ring_offs is guaranteed being 4-byte aligned */
+ rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs));
rx_size = rx_status >> 16;
rx_status &= 0xffff;
@@ -519,6 +519,7 @@ static int rtl_poll(struct eth_device *dev)
printf("rx packet %d bytes", rx_size-4);
#endif
}
+ flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
outw(cur_rx - 16, ioaddr + RxBufPtr);
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 25392f6..e91d9ea 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -241,10 +241,9 @@ int tsec_init(struct eth_device *dev, bd_t * bd)
* It will wait for the write to be done (or for a timeout to
* expire) before exiting
*/
-void write_phy_reg(struct tsec_private *priv, uint regnum, uint value)
+void write_any_phy_reg(struct tsec_private *priv, uint phyid, uint regnum, uint value)
{
volatile tsec_t *regbase = priv->phyregs;
- uint phyid = priv->phyaddr;
int timeout = 1000000;
regbase->miimadd = (phyid << 8) | regnum;
@@ -255,17 +254,19 @@ void write_phy_reg(struct tsec_private *priv, uint regnum, uint value)
while ((regbase->miimind & MIIMIND_BUSY) && timeout--) ;
}
+/* #define to provide old write_phy_reg functionality without duplicating code */
+#define write_phy_reg(priv, regnum, value) write_any_phy_reg(priv,priv->phyaddr,regnum,value)
+
/* Reads register regnum on the device's PHY through the
* registers specified in priv. It lowers and raises the read
* command, and waits for the data to become valid (miimind
* notvalid bit cleared), and the bus to cease activity (miimind
* busy bit cleared), and then returns the value
*/
-uint read_phy_reg(struct tsec_private *priv, uint regnum)
+uint read_any_phy_reg(struct tsec_private *priv, uint phyid, uint regnum)
{
uint value;
volatile tsec_t *regbase = priv->phyregs;
- uint phyid = priv->phyaddr;
/* Put the address of the phy, and the register
* number into MIIMADD */
@@ -288,6 +289,9 @@ uint read_phy_reg(struct tsec_private *priv, uint regnum)
return value;
}
+/* #define to provide old read_phy_reg functionality without duplicating code */
+#define read_phy_reg(priv,regnum) read_any_phy_reg(priv,priv->phyaddr,regnum)
+
/* Discover which PHY is attached to the device, and configure it
* properly. If the PHY is not recognized, then return 0
* (failure). Otherwise, return 1
@@ -571,6 +575,63 @@ uint mii_parse_88E1011_psr(uint mii_reg, struct tsec_private * priv)
return 0;
}
+/* Parse the RTL8211B's status register for speed and duplex
+ * information
+ */
+uint mii_parse_RTL8211B_sr(uint mii_reg, struct tsec_private * priv)
+{
+ uint speed;
+
+ mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS);
+ if ((mii_reg & MIIM_RTL8211B_PHYSTAT_LINK) &&
+ !(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) {
+ int i = 0;
+
+ puts("Waiting for PHY realtime link");
+ while (!(mii_reg & MIIM_RTL8211B_PHYSTAT_SPDDONE)) {
+ /* Timeout reached ? */
+ if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+ puts(" TIMEOUT !\n");
+ priv->link = 0;
+ break;
+ }
+
+ if ((i++ % 1000) == 0) {
+ putc('.');
+ }
+ udelay(1000); /* 1 ms */
+ mii_reg = read_phy_reg(priv, MIIM_RTL8211B_PHY_STATUS);
+ }
+ puts(" done\n");
+ udelay(500000); /* another 500 ms (results in faster booting) */
+ } else {
+ if (mii_reg & MIIM_RTL8211B_PHYSTAT_LINK)
+ priv->link = 1;
+ else
+ priv->link = 0;
+ }
+
+ if (mii_reg & MIIM_RTL8211B_PHYSTAT_DUPLEX)
+ priv->duplexity = 1;
+ else
+ priv->duplexity = 0;
+
+ speed = (mii_reg & MIIM_RTL8211B_PHYSTAT_SPEED);
+
+ switch (speed) {
+ case MIIM_RTL8211B_PHYSTAT_GBIT:
+ priv->speed = 1000;
+ break;
+ case MIIM_RTL8211B_PHYSTAT_100:
+ priv->speed = 100;
+ break;
+ default:
+ priv->speed = 10;
+ }
+
+ return 0;
+}
+
/* Parse the cis8201's status register for speed and duplex
* information
*/
@@ -1361,6 +1422,33 @@ struct phy_info phy_info_dp83865 = {
},
};
+struct phy_info phy_info_rtl8211b = {
+ 0x001cc91,
+ "RealTek RTL8211B",
+ 4,
+ (struct phy_cmd[]){ /* config */
+ /* Reset and configure the PHY */
+ {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+ {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL},
+ {MIIM_ANAR, MIIM_ANAR_INIT, NULL},
+ {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL},
+ {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init},
+ {miim_end,}
+ },
+ (struct phy_cmd[]){ /* startup */
+ /* Status is read once to clear old link state */
+ {MIIM_STATUS, miim_read, NULL},
+ /* Auto-negotiate */
+ {MIIM_STATUS, miim_read, &mii_parse_sr},
+ /* Read the status */
+ {MIIM_RTL8211B_PHY_STATUS, miim_read, &mii_parse_RTL8211B_sr},
+ {miim_end,}
+ },
+ (struct phy_cmd[]){ /* shutdown */
+ {miim_end,}
+ },
+};
+
struct phy_info *phy_info[] = {
&phy_info_cis8204,
&phy_info_cis8201,
@@ -1374,6 +1462,7 @@ struct phy_info *phy_info[] = {
&phy_info_lxt971,
&phy_info_VSC8244,
&phy_info_dp83865,
+ &phy_info_rtl8211b,
&phy_info_generic,
NULL
};
@@ -1497,18 +1586,6 @@ static void relocate_cmds(void)
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) \
&& !defined(BITBANGMII)
-struct tsec_private *get_priv_for_phy(unsigned char phyaddr)
-{
- int i;
-
- for (i = 0; i < MAXCONTROLLERS; i++) {
- if (privlist[i]->phyaddr == phyaddr)
- return privlist[i];
- }
-
- return NULL;
-}
-
/*
* Read a MII PHY register.
*
@@ -1519,14 +1596,14 @@ static int tsec_miiphy_read(char *devname, unsigned char addr,
unsigned char reg, unsigned short *value)
{
unsigned short ret;
- struct tsec_private *priv = get_priv_for_phy(addr);
+ struct tsec_private *priv = privlist[0];
if (NULL == priv) {
printf("Can't read PHY at address %d\n", addr);
return -1;
}
- ret = (unsigned short)read_phy_reg(priv, reg);
+ ret = (unsigned short)read_any_phy_reg(priv, addr, reg);
*value = ret;
return 0;
@@ -1541,14 +1618,14 @@ static int tsec_miiphy_read(char *devname, unsigned char addr,
static int tsec_miiphy_write(char *devname, unsigned char addr,
unsigned char reg, unsigned short value)
{
- struct tsec_private *priv = get_priv_for_phy(addr);
+ struct tsec_private *priv = privlist[0];
if (NULL == priv) {
printf("Can't write PHY at address %d\n", addr);
return -1;
}
- write_phy_reg(priv, reg, value);
+ write_any_phy_reg(priv, addr, reg, value);
return 0;
}
diff --git a/drivers/net/tsec.h b/drivers/net/tsec.h
index 2f0092a..d4dc15a 100644
--- a/drivers/net/tsec.h
+++ b/drivers/net/tsec.h
@@ -184,6 +184,14 @@
#define MIIM_88E1145_PHY_PAGE 29
#define MIIM_88E1145_PHY_CAL_OV 30
+/* RTL8211B PHY Status Register */
+#define MIIM_RTL8211B_PHY_STATUS 0x11
+#define MIIM_RTL8211B_PHYSTAT_SPEED 0xc000
+#define MIIM_RTL8211B_PHYSTAT_GBIT 0x8000
+#define MIIM_RTL8211B_PHYSTAT_100 0x4000
+#define MIIM_RTL8211B_PHYSTAT_DUPLEX 0x2000
+#define MIIM_RTL8211B_PHYSTAT_SPDDONE 0x0800
+#define MIIM_RTL8211B_PHYSTAT_LINK 0x0400
/* DM9161 Control register values */
#define MIIM_DM9161_CR_STOP 0x0400
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index 6cb25bf..55f37cb 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -40,8 +40,13 @@ static uec_info_t eth1_uec_info = {
.tx_clock = CFG_UEC1_TX_CLK,
.eth_type = CFG_UEC1_ETH_TYPE,
},
+#if (CFG_UEC1_ETH_TYPE == FAST_ETH)
+ .num_threads_tx = UEC_NUM_OF_THREADS_1,
+ .num_threads_rx = UEC_NUM_OF_THREADS_1,
+#else
.num_threads_tx = UEC_NUM_OF_THREADS_4,
.num_threads_rx = UEC_NUM_OF_THREADS_4,
+#endif
.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.tx_bd_ring_len = 16,
@@ -58,8 +63,13 @@ static uec_info_t eth2_uec_info = {
.tx_clock = CFG_UEC2_TX_CLK,
.eth_type = CFG_UEC2_ETH_TYPE,
},
+#if (CFG_UEC2_ETH_TYPE == FAST_ETH)
+ .num_threads_tx = UEC_NUM_OF_THREADS_1,
+ .num_threads_rx = UEC_NUM_OF_THREADS_1,
+#else
.num_threads_tx = UEC_NUM_OF_THREADS_4,
.num_threads_rx = UEC_NUM_OF_THREADS_4,
+#endif
.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.tx_bd_ring_len = 16,
@@ -68,7 +78,6 @@ static uec_info_t eth2_uec_info = {
.enet_interface = CFG_UEC2_INTERFACE_MODE,
};
#endif
-
#ifdef CONFIG_UEC_ETH3
static uec_info_t eth3_uec_info = {
.uf_info = {
@@ -77,8 +86,13 @@ static uec_info_t eth3_uec_info = {
.tx_clock = CFG_UEC3_TX_CLK,
.eth_type = CFG_UEC3_ETH_TYPE,
},
+#if (CFG_UEC3_ETH_TYPE == FAST_ETH)
+ .num_threads_tx = UEC_NUM_OF_THREADS_1,
+ .num_threads_rx = UEC_NUM_OF_THREADS_1,
+#else
.num_threads_tx = UEC_NUM_OF_THREADS_4,
.num_threads_rx = UEC_NUM_OF_THREADS_4,
+#endif
.riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
.tx_bd_ring_len = 16,
@@ -87,6 +101,29 @@ static uec_info_t eth3_uec_info = {
.enet_interface = CFG_UEC3_INTERFACE_MODE,
};
#endif
+#ifdef CONFIG_UEC_ETH4
+static uec_info_t eth4_uec_info = {
+ .uf_info = {
+ .ucc_num = CFG_UEC4_UCC_NUM,
+ .rx_clock = CFG_UEC4_RX_CLK,
+ .tx_clock = CFG_UEC4_TX_CLK,
+ .eth_type = CFG_UEC4_ETH_TYPE,
+ },
+#if (CFG_UEC4_ETH_TYPE == FAST_ETH)
+ .num_threads_tx = UEC_NUM_OF_THREADS_1,
+ .num_threads_rx = UEC_NUM_OF_THREADS_1,
+#else
+ .num_threads_tx = UEC_NUM_OF_THREADS_4,
+ .num_threads_rx = UEC_NUM_OF_THREADS_4,
+#endif
+ .riscTx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+ .riscRx = QE_RISC_ALLOCATION_RISC1_AND_RISC2,
+ .tx_bd_ring_len = 16,
+ .rx_bd_ring_len = 16,
+ .phy_address = CFG_UEC4_PHY_ADDR,
+ .enet_interface = CFG_UEC4_INTERFACE_MODE,
+};
+#endif
static int uec_mac_enable(uec_private_t *uec, comm_dir_e mode)
{
@@ -475,6 +512,8 @@ static int init_phy(struct eth_device *dev)
uec->mii_info = mii_info;
+ qe_set_mii_clk_src(uec->uec_info->uf_info.ucc_num);
+
if (init_mii_management_configuration(umii_regs)) {
printf("%s: The MII Bus is stuck!", dev->name);
err = -1;
@@ -581,21 +620,12 @@ static void adjust_link(struct eth_device *dev)
static void phy_change(struct eth_device *dev)
{
uec_private_t *uec = (uec_private_t *)dev->priv;
- uec_t *uec_regs;
- int result = 0;
-
- uec_regs = uec->uec_regs;
-
- /* Delay 5s to give the PHY a chance to change the register state */
- udelay(5000000);
/* Update the link, speed, duplex */
- result = uec->mii_info->phyinfo->read_status(uec->mii_info);
+ uec->mii_info->phyinfo->read_status(uec->mii_info);
/* Adjust the interface according to speed */
- if ((0 == result) || (uec->mii_info->link == 0)) {
- adjust_link(dev);
- }
+ adjust_link(dev);
}
static int uec_set_mac_address(uec_private_t *uec, u8 *mac_addr)
@@ -1120,27 +1150,59 @@ static int uec_startup(uec_private_t *uec)
static int uec_init(struct eth_device* dev, bd_t *bd)
{
uec_private_t *uec;
- int err;
+ int err, i;
+ struct phy_info *curphy;
uec = (uec_private_t *)dev->priv;
if (uec->the_first_run == 0) {
- /* Set up the MAC address */
- if (dev->enetaddr[0] & 0x01) {
- printf("%s: MacAddress is multcast address\n",
- __FUNCTION__);
- return -1;
+ err = init_phy(dev);
+ if (err) {
+ printf("%s: Cannot initialize PHY, aborting.\n",
+ dev->name);
+ return err;
+ }
+
+ curphy = uec->mii_info->phyinfo;
+
+ if (curphy->config_aneg) {
+ err = curphy->config_aneg(uec->mii_info);
+ if (err) {
+ printf("%s: Can't negotiate PHY\n", dev->name);
+ return err;
+ }
}
- uec_set_mac_address(uec, dev->enetaddr);
+
+ /* Give PHYs up to 5 sec to report a link */
+ i = 50;
+ do {
+ err = curphy->read_status(uec->mii_info);
+ udelay(100000);
+ } while (((i-- > 0) && !uec->mii_info->link) || err);
+
+ if (err || i <= 0)
+ printf("warning: %s: timeout on PHY link\n", dev->name);
+
uec->the_first_run = 1;
}
+ /* Set up the MAC address */
+ if (dev->enetaddr[0] & 0x01) {
+ printf("%s: MacAddress is multcast address\n",
+ __FUNCTION__);
+ return -1;
+ }
+ uec_set_mac_address(uec, dev->enetaddr);
+
+
err = uec_open(uec, COMM_DIR_RX_AND_TX);
if (err) {
printf("%s: cannot enable UEC device\n", dev->name);
return -1;
}
+ phy_change(dev);
+
return (uec->mii_info->link ? 0 : -1);
}
@@ -1262,6 +1324,10 @@ int uec_initialize(int index)
#ifdef CONFIG_UEC_ETH3
uec_info = &eth3_uec_info;
#endif
+ } else if (index == 3) {
+#ifdef CONFIG_UEC_ETH4
+ uec_info = &eth4_uec_info;
+#endif
} else {
printf("%s: index is illegal.\n", __FUNCTION__);
return -EINVAL;
@@ -1289,14 +1355,6 @@ int uec_initialize(int index)
return err;
}
- err = init_phy(dev);
- if (err) {
- printf("%s: Cannot initialize PHY, aborting.\n", dev->name);
- return err;
- }
-
- phy_change(dev);
-
return 1;
}
#endif /* CONFIG_QE */
diff --git a/drivers/qe/uec_phy.c b/drivers/qe/uec_phy.c
index ca6faa6..c549b6b 100644
--- a/drivers/qe/uec_phy.c
+++ b/drivers/qe/uec_phy.c
@@ -28,7 +28,6 @@
#if defined(CONFIG_QE)
-#define UEC_VERBOSE_DEBUG
#define ugphy_printk(format, arg...) \
printf(format "\n", ## arg)
@@ -77,11 +76,10 @@ void uec_write_phy_reg (struct eth_device *dev, int mii_id, int regnum, int valu
/* Setting up the MII Mangement Control Register with the value */
out_be32 (&ug_regs->miimcon, (u32) value);
+ sync();
/* Wait till MII management write is complete */
while ((in_be32 (&ug_regs->miimind)) & MIIMIND_BUSY);
-
- udelay (100000);
}
/* Reads from register regnum in the PHY for device dev, */
@@ -101,20 +99,21 @@ int uec_read_phy_reg (struct eth_device *dev, int mii_id, int regnum)
tmp_reg = ((u32) mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | mii_reg;
out_be32 (&ug_regs->miimadd, tmp_reg);
- /* Perform an MII management read cycle */
+ /* clear MII management command cycle */
out_be32 (&ug_regs->miimcom, 0);
+ sync();
+
+ /* Perform an MII management read cycle */
out_be32 (&ug_regs->miimcom, MIIMCOM_READ_CYCLE);
/* Wait till MII management write is complete */
while ((in_be32 (&ug_regs->miimind)) &
(MIIMIND_NOT_VALID | MIIMIND_BUSY));
- udelay (100000);
-
/* Read MII management status */
value = (u16) in_be32 (&ug_regs->miimstat);
if (value == 0xffff)
- ugphy_warn
+ ugphy_vdbg
("read wrong value : mii_id %d,mii_reg %d, base %08x",
mii_id, mii_reg, (u32) & (ug_regs->miimcfg));
@@ -270,20 +269,38 @@ static int genmii_update_link (struct uec_mii_info *mii_info)
{
u16 status;
- /* Do a fake read */
+ /* Status is read once to clear old link state */
phy_read (mii_info, PHY_BMSR);
- /* Read link and autonegotiation status */
- status = phy_read (mii_info, PHY_BMSR);
- if ((status & PHY_BMSR_LS) == 0)
- mii_info->link = 0;
- else
+ /*
+ * Wait if the link is up, and autonegotiation is in progress
+ * (ie - we're capable and it's not done)
+ */
+ status = phy_read(mii_info, PHY_BMSR);
+ if ((status & PHY_BMSR_LS) && (status & PHY_BMSR_AUTN_ABLE)
+ && !(status & PHY_BMSR_AUTN_COMP)) {
+ int i = 0;
+
+ while (!(status & PHY_BMSR_AUTN_COMP)) {
+ /*
+ * Timeout reached ?
+ */
+ if (i > UGETH_AN_TIMEOUT) {
+ mii_info->link = 0;
+ return 0;
+ }
+
+ udelay(1000); /* 1 ms */
+ status = phy_read(mii_info, PHY_BMSR);
+ }
mii_info->link = 1;
-
- /* If we are autonegotiating, and not done,
- * return an error */
- if (mii_info->autoneg && !(status & PHY_BMSR_AUTN_COMP))
- return -EAGAIN;
+ udelay(500000); /* another 500 ms (results in faster booting) */
+ } else {
+ if (status & PHY_BMSR_LS)
+ mii_info->link = 1;
+ else
+ mii_info->link = 0;
+ }
return 0;
}
@@ -389,16 +406,12 @@ static int dm9161_init (struct uec_mii_info *mii_info)
/* PHY and MAC connect */
phy_write (mii_info, PHY_BMCR, phy_read (mii_info, PHY_BMCR) &
~PHY_BMCR_ISO);
-#ifdef CONFIG_RMII_MODE
- phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_RMII_INIT);
-#else
+
phy_write (mii_info, MII_DM9161_SCR, MII_DM9161_SCR_INIT);
-#endif
+
config_genmii_advert (mii_info);
/* Start/restart aneg */
genmii_config_aneg (mii_info);
- /* Delay to wait the aneg compeleted */
- udelay (3000000);
return 0;
}
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
new file mode 100644
index 0000000..0b7a2df
--- /dev/null
+++ b/drivers/spi/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2007
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB := $(obj)libspi.a
+
+COBJS-y += mpc8xxx_spi.o
+
+COBJS := $(COBJS-y)
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+all: $(LIB)
+
+$(LIB): $(obj).depend $(OBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c
new file mode 100644
index 0000000..a3d1c95
--- /dev/null
+++ b/drivers/spi/mpc8xxx_spi.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2006 Ben Warren, Qstreams Networks Inc.
+ * With help from the common/soft_spi and cpu/mpc8260 drivers
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <spi.h>
+#include <asm/mpc8xxx_spi.h>
+
+#ifdef CONFIG_HARD_SPI
+
+#define SPI_EV_NE (0x80000000 >> 22) /* Receiver Not Empty */
+#define SPI_EV_NF (0x80000000 >> 23) /* Transmitter Not Full */
+
+#define SPI_MODE_LOOP (0x80000000 >> 1) /* Loopback mode */
+#define SPI_MODE_REV (0x80000000 >> 5) /* Reverse mode - MSB first */
+#define SPI_MODE_MS (0x80000000 >> 6) /* Always master */
+#define SPI_MODE_EN (0x80000000 >> 7) /* Enable interface */
+
+#define SPI_TIMEOUT 1000
+
+void spi_init(void)
+{
+ volatile spi8xxx_t *spi = &((immap_t *) (CFG_IMMR))->spi;
+
+ /*
+ * SPI pins on the MPC83xx are not muxed, so all we do is initialize
+ * some registers
+ */
+ spi->mode = SPI_MODE_REV | SPI_MODE_MS | SPI_MODE_EN;
+ spi->mode = (spi->mode & 0xfff0ffff) | (1 << 16); /* Use SYSCLK / 8
+ (16.67MHz typ.) */
+ spi->event = 0xffffffff; /* Clear all SPI events */
+ spi->mask = 0x00000000; /* Mask all SPI interrupts */
+ spi->com = 0; /* LST bit doesn't do anything, so disregard */
+}
+
+int spi_xfer(spi_chipsel_type chipsel, int bitlen, uchar *dout, uchar *din)
+{
+ volatile spi8xxx_t *spi = &((immap_t *) (CFG_IMMR))->spi;
+ unsigned int tmpdout, tmpdin, event;
+ int numBlks = bitlen / 32 + (bitlen % 32 ? 1 : 0);
+ int tm, isRead = 0;
+ unsigned char charSize = 32;
+
+ debug("spi_xfer: chipsel %08X dout %08X din %08X bitlen %d\n",
+ (int)chipsel, *(uint *) dout, *(uint *) din, bitlen);
+
+ if (chipsel != NULL)
+ (*chipsel) (1); /* select the target chip */
+
+ spi->event = 0xffffffff; /* Clear all SPI events */
+
+ /* handle data in 32-bit chunks */
+ while (numBlks--) {
+ tmpdout = 0;
+ charSize = (bitlen >= 32 ? 32 : bitlen);
+
+ /* Shift data so it's msb-justified */
+ tmpdout = *(u32 *) dout >> (32 - charSize);
+
+ /* The LEN field of the SPMODE register is set as follows:
+ *
+ * Bit length setting
+ * len <= 4 3
+ * 4 < len <= 16 len - 1
+ * len > 16 0
+ */
+
+ if (bitlen <= 16) {
+ if (bitlen <= 4)
+ spi->mode = (spi->mode & 0xff0fffff) |
+ (3 << 20);
+ else
+ spi->mode = (spi->mode & 0xff0fffff) |
+ ((bitlen - 1) << 20);
+ } else {
+ spi->mode = (spi->mode & 0xff0fffff);
+ /* Set up the next iteration if sending > 32 bits */
+ bitlen -= 32;
+ dout += 4;
+ }
+
+ spi->tx = tmpdout; /* Write the data out */
+ debug("*** spi_xfer: ... %08x written\n", tmpdout);
+
+ /*
+ * Wait for SPI transmit to get out
+ * or time out (1 second = 1000 ms)
+ * The NE event must be read and cleared first
+ */
+ for (tm = 0, isRead = 0; tm < SPI_TIMEOUT; ++tm) {
+ event = spi->event;
+ if (event & SPI_EV_NE) {
+ tmpdin = spi->rx;
+ spi->event |= SPI_EV_NE;
+ isRead = 1;
+
+ *(u32 *) din = (tmpdin << (32 - charSize));
+ if (charSize == 32) {
+ /* Advance output buffer by 32 bits */
+ din += 4;
+ }
+ }
+ /*
+ * Only bail when we've had both NE and NF events.
+ * This will cause timeouts on RO devices, so maybe
+ * in the future put an arbitrary delay after writing
+ * the device. Arbitrary delays suck, though...
+ */
+ if (isRead && (event & SPI_EV_NF))
+ break;
+ }
+ if (tm >= SPI_TIMEOUT)
+ puts("*** spi_xfer: Time out during SPI transfer");
+
+ debug("*** spi_xfer: transfer ended. Value=%08x\n", tmpdin);
+ }
+
+ if (chipsel != NULL)
+ (*chipsel) (0); /* deselect the target chip */
+
+ return 0;
+}
+#endif /* CONFIG_HARD_SPI */