···87878888config DMA_LEGACY
8989 bool "Legacy DMA support"
9090- default y if FSLDMAFEC
9190 help
9291 Enable legacy DMA support. This does not use driver model and should
9392 be migrated to the new API.
-1010
drivers/dma/MCD_dmaApi.c
···11-// SPDX-License-Identifier: GPL-2.0+
22-/*
33- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
44- */
55-66-/*Main C file for multi-channel DMA API. */
77-88-#include <common.h>
99-1010-#include <MCD_dma.h>
1111-#include <MCD_tasksInit.h>
1212-#include <MCD_progCheck.h>
1313-1414-/********************************************************************/
1515-/* This is an API-internal pointer to the DMA's registers */
1616-dmaRegs *MCD_dmaBar;
1717-1818-/*
1919- * These are the real and model task tables as generated by the
2020- * build process
2121- */
2222-extern TaskTableEntry MCD_realTaskTableSrc[NCHANNELS];
2323-extern TaskTableEntry MCD_modelTaskTableSrc[NUMOFVARIANTS];
2424-2525-/*
2626- * However, this (usually) gets relocated to on-chip SRAM, at which
2727- * point we access them as these tables
2828- */
2929-volatile TaskTableEntry *MCD_taskTable;
3030-TaskTableEntry *MCD_modelTaskTable;
3131-3232-/*
3333- * MCD_chStatus[] is an array of status indicators for remembering
3434- * whether a DMA has ever been attempted on each channel, pausing
3535- * status, etc.
3636- */
3737-static int MCD_chStatus[NCHANNELS] = {
3838- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
3939- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
4040- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA,
4141- MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA
4242-};
4343-4444-/* Prototypes for local functions */
4545-static void MCD_memcpy(int *dest, int *src, u32 size);
4646-static void MCD_resmActions(int channel);
4747-4848-/*
4949- * Buffer descriptors used for storage of progress info for single Dmas
5050- * Also used as storage for the DMA for CRCs for single DMAs
5151- * Otherwise, the DMA does not parse these buffer descriptors
5252- */
5353-#ifdef MCD_INCLUDE_EU
5454-extern MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
5555-#else
5656-MCD_bufDesc MCD_singleBufDescs[NCHANNELS];
5757-#endif
5858-MCD_bufDesc *MCD_relocBuffDesc;
5959-6060-/* Defines for the debug control register's functions */
6161-#define DBG_CTL_COMP1_TASK (0x00002000)
6262-#define DBG_CTL_ENABLE (DBG_CTL_AUTO_ARM | \
6363- DBG_CTL_BREAK | \
6464- DBG_CTL_INT_BREAK | \
6565- DBG_CTL_COMP1_TASK)
6666-#define DBG_CTL_DISABLE (DBG_CTL_AUTO_ARM | \
6767- DBG_CTL_INT_BREAK | \
6868- DBG_CTL_COMP1_TASK)
6969-#define DBG_KILL_ALL_STAT (0xFFFFFFFF)
7070-7171-/* Offset to context save area where progress info is stored */
7272-#define CSAVE_OFFSET 10
7373-7474-/* Defines for Byte Swapping */
7575-#define MCD_BYTE_SWAP_KILLER 0xFFF8888F
7676-#define MCD_NO_BYTE_SWAP_ATALL 0x00040000
7777-7878-/* Execution Unit Identifiers */
7979-#define MAC 0 /* legacy - not used */
8080-#define LUAC 1 /* legacy - not used */
8181-#define CRC 2 /* legacy - not used */
8282-#define LURC 3 /* Logic Unit with CRC */
8383-8484-/* Task Identifiers */
8585-#define TASK_CHAINNOEU 0
8686-#define TASK_SINGLENOEU 1
8787-#ifdef MCD_INCLUDE_EU
8888-#define TASK_CHAINEU 2
8989-#define TASK_SINGLEEU 3
9090-#define TASK_FECRX 4
9191-#define TASK_FECTX 5
9292-#else
9393-#define TASK_CHAINEU 0
9494-#define TASK_SINGLEEU 1
9595-#define TASK_FECRX 2
9696-#define TASK_FECTX 3
9797-#endif
9898-9999-/*
100100- * Structure to remember which variant is on which channel
101101- * TBD- need this?
102102- */
103103-typedef struct MCD_remVariants_struct MCD_remVariant;
104104-struct MCD_remVariants_struct {
105105- int remDestRsdIncr[NCHANNELS]; /* -1,0,1 */
106106- int remSrcRsdIncr[NCHANNELS]; /* -1,0,1 */
107107- s16 remDestIncr[NCHANNELS]; /* DestIncr */
108108- s16 remSrcIncr[NCHANNELS]; /* srcIncr */
109109- u32 remXferSize[NCHANNELS]; /* xferSize */
110110-};
111111-112112-/* Structure to remember the startDma parameters for each channel */
113113-MCD_remVariant MCD_remVariants;
114114-/********************************************************************/
115115-/* Function: MCD_initDma
116116- * Purpose: Initializes the DMA API by setting up a pointer to the DMA
117117- * registers, relocating and creating the appropriate task
118118- * structures, and setting up some global settings
119119- * Arguments:
120120- * dmaBarAddr - pointer to the multichannel DMA registers
121121- * taskTableDest - location to move DMA task code and structs to
122122- * flags - operational parameters
123123- * Return Value:
124124- * MCD_TABLE_UNALIGNED if taskTableDest is not 512-byte aligned
125125- * MCD_OK otherwise
126126- */
127127-extern u32 MCD_funcDescTab0[];
128128-129129-int MCD_initDma(dmaRegs * dmaBarAddr, void *taskTableDest, u32 flags)
130130-{
131131- int i;
132132- TaskTableEntry *entryPtr;
133133-134134- /* setup the local pointer to register set */
135135- MCD_dmaBar = dmaBarAddr;
136136-137137- /* do we need to move/create a task table */
138138- if ((flags & MCD_RELOC_TASKS) != 0) {
139139- int fixedSize;
140140- u32 *fixedPtr;
141141- /*int *tablePtr = taskTableDest;TBD */
142142- int varTabsOffset, funcDescTabsOffset, contextSavesOffset;
143143- int taskDescTabsOffset;
144144- int taskTableSize, varTabsSize, funcDescTabsSize,
145145- contextSavesSize;
146146- int taskDescTabSize;
147147-148148- int i;
149149-150150- /* check if physical address is aligned on 512 byte boundary */
151151- if (((u32) taskTableDest & 0x000001ff) != 0)
152152- return (MCD_TABLE_UNALIGNED);
153153-154154- /* set up local pointer to task Table */
155155- MCD_taskTable = taskTableDest;
156156-157157- /*
158158- * Create a task table:
159159- * - compute aligned base offsets for variable tables and
160160- * function descriptor tables, then
161161- * - loop through the task table and setup the pointers
162162- * - copy over model task table with the the actual task
163163- * descriptor tables
164164- */
165165-166166- taskTableSize = NCHANNELS * sizeof(TaskTableEntry);
167167- /* align variable tables to size */
168168- varTabsOffset = taskTableSize + (u32) taskTableDest;
169169- if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0)
170170- varTabsOffset =
171171- (varTabsOffset + VAR_TAB_SIZE) & (~VAR_TAB_SIZE);
172172- /* align function descriptor tables */
173173- varTabsSize = NCHANNELS * VAR_TAB_SIZE;
174174- funcDescTabsOffset = varTabsOffset + varTabsSize;
175175-176176- if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0)
177177- funcDescTabsOffset =
178178- (funcDescTabsOffset +
179179- FUNCDESC_TAB_SIZE) & (~FUNCDESC_TAB_SIZE);
180180-181181- funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE;
182182- contextSavesOffset = funcDescTabsOffset + funcDescTabsSize;
183183- contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE);
184184- fixedSize =
185185- taskTableSize + varTabsSize + funcDescTabsSize +
186186- contextSavesSize;
187187-188188- /* zero the thing out */
189189- fixedPtr = (u32 *) taskTableDest;
190190- for (i = 0; i < (fixedSize / 4); i++)
191191- fixedPtr[i] = 0;
192192-193193- entryPtr = (TaskTableEntry *) MCD_taskTable;
194194- /* set up fixed pointers */
195195- for (i = 0; i < NCHANNELS; i++) {
196196- /* update ptr to local value */
197197- entryPtr[i].varTab = (u32) varTabsOffset;
198198- entryPtr[i].FDTandFlags =
199199- (u32) funcDescTabsOffset | MCD_TT_FLAGS_DEF;
200200- entryPtr[i].contextSaveSpace = (u32) contextSavesOffset;
201201- varTabsOffset += VAR_TAB_SIZE;
202202-#ifdef MCD_INCLUDE_EU
203203- /* if not there is only one, just point to the
204204- same one */
205205- funcDescTabsOffset += FUNCDESC_TAB_SIZE;
206206-#endif
207207- contextSavesOffset += CONTEXT_SAVE_SIZE;
208208- }
209209- /* copy over the function descriptor table */
210210- for (i = 0; i < FUNCDESC_TAB_NUM; i++) {
211211- MCD_memcpy((void *)(entryPtr[i].
212212- FDTandFlags & ~MCD_TT_FLAGS_MASK),
213213- (void *)MCD_funcDescTab0, FUNCDESC_TAB_SIZE);
214214- }
215215-216216- /* copy model task table to where the context saves stuff
217217- leaves off */
218218- MCD_modelTaskTable = (TaskTableEntry *) contextSavesOffset;
219219-220220- MCD_memcpy((void *)MCD_modelTaskTable,
221221- (void *)MCD_modelTaskTableSrc,
222222- NUMOFVARIANTS * sizeof(TaskTableEntry));
223223-224224- /* point to local version of model task table */
225225- entryPtr = MCD_modelTaskTable;
226226- taskDescTabsOffset = (u32) MCD_modelTaskTable +
227227- (NUMOFVARIANTS * sizeof(TaskTableEntry));
228228-229229- /* copy actual task code and update TDT ptrs in local
230230- model task table */
231231- for (i = 0; i < NUMOFVARIANTS; i++) {
232232- taskDescTabSize =
233233- entryPtr[i].TDTend - entryPtr[i].TDTstart + 4;
234234- MCD_memcpy((void *)taskDescTabsOffset,
235235- (void *)entryPtr[i].TDTstart,
236236- taskDescTabSize);
237237- entryPtr[i].TDTstart = (u32) taskDescTabsOffset;
238238- taskDescTabsOffset += taskDescTabSize;
239239- entryPtr[i].TDTend = (u32) taskDescTabsOffset - 4;
240240- }
241241-#ifdef MCD_INCLUDE_EU
242242- /* Tack single DMA BDs onto end of code so API controls
243243- where they are since DMA might write to them */
244244- MCD_relocBuffDesc =
245245- (MCD_bufDesc *) (entryPtr[NUMOFVARIANTS - 1].TDTend + 4);
246246-#else
247247- /* DMA does not touch them so they can be wherever and we
248248- don't need to waste SRAM on them */
249249- MCD_relocBuffDesc = MCD_singleBufDescs;
250250-#endif
251251- } else {
252252- /* point the would-be relocated task tables and the
253253- buffer descriptors to the ones the linker generated */
254254-255255- if (((u32) MCD_realTaskTableSrc & 0x000001ff) != 0)
256256- return (MCD_TABLE_UNALIGNED);
257257-258258- /* need to add code to make sure that every thing else is
259259- aligned properly TBD. this is problematic if we init
260260- more than once or after running tasks, need to add
261261- variable to see if we have aleady init'd */
262262- entryPtr = MCD_realTaskTableSrc;
263263- for (i = 0; i < NCHANNELS; i++) {
264264- if (((entryPtr[i].varTab & (VAR_TAB_SIZE - 1)) != 0) ||
265265- ((entryPtr[i].
266266- FDTandFlags & (FUNCDESC_TAB_SIZE - 1)) != 0))
267267- return (MCD_TABLE_UNALIGNED);
268268- }
269269-270270- MCD_taskTable = MCD_realTaskTableSrc;
271271- MCD_modelTaskTable = MCD_modelTaskTableSrc;
272272- MCD_relocBuffDesc = MCD_singleBufDescs;
273273- }
274274-275275- /* Make all channels as totally inactive, and remember them as such: */
276276-277277- MCD_dmaBar->taskbar = (u32) MCD_taskTable;
278278- for (i = 0; i < NCHANNELS; i++) {
279279- MCD_dmaBar->taskControl[i] = 0x0;
280280- MCD_chStatus[i] = MCD_NO_DMA;
281281- }
282282-283283- /* Set up pausing mechanism to inactive state: */
284284- /* no particular values yet for either comparator registers */
285285- MCD_dmaBar->debugComp1 = 0;
286286- MCD_dmaBar->debugComp2 = 0;
287287- MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
288288- MCD_dmaBar->debugStatus = DBG_KILL_ALL_STAT;
289289-290290- /* enable or disable commbus prefetch, really need an ifdef or
291291- something to keep from trying to set this in the 8220 */
292292- if ((flags & MCD_COMM_PREFETCH_EN) != 0)
293293- MCD_dmaBar->ptdControl &= ~PTD_CTL_COMM_PREFETCH;
294294- else
295295- MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH;
296296-297297- return (MCD_OK);
298298-}
299299-300300-/*********************** End of MCD_initDma() ***********************/
301301-302302-/********************************************************************/
303303-/* Function: MCD_dmaStatus
304304- * Purpose: Returns the status of the DMA on the requested channel
305305- * Arguments: channel - channel number
306306- * Returns: Predefined status indicators
307307- */
308308-int MCD_dmaStatus(int channel)
309309-{
310310- u16 tcrValue;
311311-312312- if ((channel < 0) || (channel >= NCHANNELS))
313313- return (MCD_CHANNEL_INVALID);
314314-315315- tcrValue = MCD_dmaBar->taskControl[channel];
316316- if ((tcrValue & TASK_CTL_EN) == 0) { /* nothing running */
317317- /* if last reported with task enabled */
318318- if (MCD_chStatus[channel] == MCD_RUNNING
319319- || MCD_chStatus[channel] == MCD_IDLE)
320320- MCD_chStatus[channel] = MCD_DONE;
321321- } else { /* something is running */
322322-323323- /* There are three possibilities: paused, running or idle. */
324324- if (MCD_chStatus[channel] == MCD_RUNNING
325325- || MCD_chStatus[channel] == MCD_IDLE) {
326326- MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
327327- /* This register is selected to know which initiator is
328328- actually asserted. */
329329- if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)
330330- MCD_chStatus[channel] = MCD_RUNNING;
331331- else
332332- MCD_chStatus[channel] = MCD_IDLE;
333333- /* do not change the status if it is already paused. */
334334- }
335335- }
336336- return MCD_chStatus[channel];
337337-}
338338-339339-/******************** End of MCD_dmaStatus() ************************/
340340-341341-/********************************************************************/
342342-/* Function: MCD_startDma
343343- * Ppurpose: Starts a particular kind of DMA
344344- * Arguments:
345345- * srcAddr - the channel on which to run the DMA
346346- * srcIncr - the address to move data from, or buffer-descriptor address
347347- * destAddr - the amount to increment the source address per transfer
348348- * destIncr - the address to move data to
349349- * dmaSize - the amount to increment the destination address per transfer
350350- * xferSize - the number bytes in of each data movement (1, 2, or 4)
351351- * initiator - what device initiates the DMA
352352- * priority - priority of the DMA
353353- * flags - flags describing the DMA
354354- * funcDesc - description of byte swapping, bit swapping, and CRC actions
355355- * srcAddrVirt - virtual buffer descriptor address TBD
356356- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
357357- */
358358-359359-int MCD_startDma(int channel, s8 * srcAddr, s16 srcIncr, s8 * destAddr,
360360- s16 destIncr, u32 dmaSize, u32 xferSize, u32 initiator,
361361- int priority, u32 flags, u32 funcDesc
362362-#ifdef MCD_NEED_ADDR_TRANS
363363- s8 * srcAddrVirt
364364-#endif
365365- )
366366-{
367367- int srcRsdIncr, destRsdIncr;
368368- int *cSave;
369369- short xferSizeIncr;
370370- int tcrCount = 0;
371371-#ifdef MCD_INCLUDE_EU
372372- u32 *realFuncArray;
373373-#endif
374374-375375- if ((channel < 0) || (channel >= NCHANNELS))
376376- return (MCD_CHANNEL_INVALID);
377377-378378- /* tbd - need to determine the proper response to a bad funcDesc when
379379- not including EU functions, for now, assign a benign funcDesc, but
380380- maybe should return an error */
381381-#ifndef MCD_INCLUDE_EU
382382- funcDesc = MCD_FUNC_NOEU1;
383383-#endif
384384-385385-#ifdef MCD_DEBUG
386386- printf("startDma:Setting up params\n");
387387-#endif
388388- /* Set us up for task-wise priority. We don't technically need to do
389389- this on every start, but since the register involved is in the same
390390- longword as other registers that users are in control of, setting
391391- it more than once is probably preferable. That since the
392392- documentation doesn't seem to be completely consistent about the
393393- nature of the PTD control register. */
394394- MCD_dmaBar->ptdControl |= (u16) 0x8000;
395395-396396- /* Not sure what we need to keep here rtm TBD */
397397-#if 1
398398- /* Calculate additional parameters to the regular DMA calls. */
399399- srcRsdIncr = srcIncr < 0 ? -1 : (srcIncr > 0 ? 1 : 0);
400400- destRsdIncr = destIncr < 0 ? -1 : (destIncr > 0 ? 1 : 0);
401401-402402- xferSizeIncr = (xferSize & 0xffff) | 0x20000000;
403403-404404- /* Remember for each channel which variant is running. */
405405- MCD_remVariants.remSrcRsdIncr[channel] = srcRsdIncr;
406406- MCD_remVariants.remDestRsdIncr[channel] = destRsdIncr;
407407- MCD_remVariants.remDestIncr[channel] = destIncr;
408408- MCD_remVariants.remSrcIncr[channel] = srcIncr;
409409- MCD_remVariants.remXferSize[channel] = xferSize;
410410-#endif
411411-412412- cSave =
413413- (int *)(MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET +
414414- CURRBD;
415415-416416-#ifdef MCD_INCLUDE_EU
417417- /* may move this to EU specific calls */
418418- realFuncArray =
419419- (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00);
420420- /* Modify the LURC's normal and byte-residue-loop functions according
421421- to parameter. */
422422- realFuncArray[(LURC * 16)] = xferSize == 4 ?
423423- funcDesc : xferSize == 2 ?
424424- funcDesc & 0xfffff00f : funcDesc & 0xffff000f;
425425- realFuncArray[(LURC * 16 + 1)] =
426426- (funcDesc & MCD_BYTE_SWAP_KILLER) | MCD_NO_BYTE_SWAP_ATALL;
427427-#endif
428428- /* Write the initiator field in the TCR, and also set the
429429- initiator-hold bit. Note that,due to a hardware quirk, this could
430430- collide with an MDE access to the initiator-register file, so we
431431- have to verify that the write reads back correctly. */
432432-433433- MCD_dmaBar->taskControl[channel] =
434434- (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM;
435435-436436- while (((MCD_dmaBar->taskControl[channel] & 0x1fff) !=
437437- ((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM))
438438- && (tcrCount < 1000)) {
439439- tcrCount++;
440440- /*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020; */
441441- MCD_dmaBar->taskControl[channel] =
442442- (initiator << 8) | TASK_CTL_HIPRITSKEN |
443443- TASK_CTL_HLDINITNUM;
444444- }
445445-446446- MCD_dmaBar->priority[channel] = (u8) priority & PRIORITY_PRI_MASK;
447447- /* should be albe to handle this stuff with only one write to ts reg
448448- - tbd */
449449- if (channel < 8 && channel >= 0) {
450450- MCD_dmaBar->taskSize0 &= ~(0xf << (7 - channel) * 4);
451451- MCD_dmaBar->taskSize0 |=
452452- (xferSize & 3) << (((7 - channel) * 4) + 2);
453453- MCD_dmaBar->taskSize0 |= (xferSize & 3) << ((7 - channel) * 4);
454454- } else {
455455- MCD_dmaBar->taskSize1 &= ~(0xf << (15 - channel) * 4);
456456- MCD_dmaBar->taskSize1 |=
457457- (xferSize & 3) << (((15 - channel) * 4) + 2);
458458- MCD_dmaBar->taskSize1 |= (xferSize & 3) << ((15 - channel) * 4);
459459- }
460460-461461- /* setup task table flags/options which mostly control the line
462462- buffers */
463463- MCD_taskTable[channel].FDTandFlags &= ~MCD_TT_FLAGS_MASK;
464464- MCD_taskTable[channel].FDTandFlags |= (MCD_TT_FLAGS_MASK & flags);
465465-466466- if (flags & MCD_FECTX_DMA) {
467467- /* TDTStart and TDTEnd */
468468- MCD_taskTable[channel].TDTstart =
469469- MCD_modelTaskTable[TASK_FECTX].TDTstart;
470470- MCD_taskTable[channel].TDTend =
471471- MCD_modelTaskTable[TASK_FECTX].TDTend;
472472- MCD_startDmaENetXmit((char *)srcAddr, (char *)srcAddr,
473473- (char *)destAddr, MCD_taskTable,
474474- channel);
475475- } else if (flags & MCD_FECRX_DMA) {
476476- /* TDTStart and TDTEnd */
477477- MCD_taskTable[channel].TDTstart =
478478- MCD_modelTaskTable[TASK_FECRX].TDTstart;
479479- MCD_taskTable[channel].TDTend =
480480- MCD_modelTaskTable[TASK_FECRX].TDTend;
481481- MCD_startDmaENetRcv((char *)srcAddr, (char *)srcAddr,
482482- (char *)destAddr, MCD_taskTable,
483483- channel);
484484- } else if (flags & MCD_SINGLE_DMA) {
485485- /* this buffer descriptor is used for storing off initial
486486- parameters for later progress query calculation and for the
487487- DMA to write the resulting checksum. The DMA does not use
488488- this to determine how to operate, that info is passed with
489489- the init routine */
490490- MCD_relocBuffDesc[channel].srcAddr = srcAddr;
491491- MCD_relocBuffDesc[channel].destAddr = destAddr;
492492-493493- /* definitely not its final value */
494494- MCD_relocBuffDesc[channel].lastDestAddr = destAddr;
495495-496496- MCD_relocBuffDesc[channel].dmaSize = dmaSize;
497497- MCD_relocBuffDesc[channel].flags = 0; /* not used */
498498- MCD_relocBuffDesc[channel].csumResult = 0; /* not used */
499499- MCD_relocBuffDesc[channel].next = 0; /* not used */
500500-501501- /* Initialize the progress-querying stuff to show no
502502- progress: */
503503- ((volatile int *)MCD_taskTable[channel].
504504- contextSaveSpace)[SRCPTR + CSAVE_OFFSET] = (int)srcAddr;
505505- ((volatile int *)MCD_taskTable[channel].
506506- contextSaveSpace)[DESTPTR + CSAVE_OFFSET] = (int)destAddr;
507507- ((volatile int *)MCD_taskTable[channel].
508508- contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0;
509509- ((volatile int *)MCD_taskTable[channel].
510510- contextSaveSpace)[CURRBD + CSAVE_OFFSET] =
511511-(u32) & (MCD_relocBuffDesc[channel]);
512512- /* tbd - need to keep the user from trying to call the EU
513513- routine when MCD_INCLUDE_EU is not defined */
514514- if (funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2) {
515515- /* TDTStart and TDTEnd */
516516- MCD_taskTable[channel].TDTstart =
517517- MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart;
518518- MCD_taskTable[channel].TDTend =
519519- MCD_modelTaskTable[TASK_SINGLENOEU].TDTend;
520520- MCD_startDmaSingleNoEu((char *)srcAddr, srcIncr,
521521- (char *)destAddr, destIncr,
522522- (int)dmaSize, xferSizeIncr,
523523- flags, (int *)
524524- &(MCD_relocBuffDesc[channel]),
525525- cSave, MCD_taskTable, channel);
526526- } else {
527527- /* TDTStart and TDTEnd */
528528- MCD_taskTable[channel].TDTstart =
529529- MCD_modelTaskTable[TASK_SINGLEEU].TDTstart;
530530- MCD_taskTable[channel].TDTend =
531531- MCD_modelTaskTable[TASK_SINGLEEU].TDTend;
532532- MCD_startDmaSingleEu((char *)srcAddr, srcIncr,
533533- (char *)destAddr, destIncr,
534534- (int)dmaSize, xferSizeIncr,
535535- flags, (int *)
536536- &(MCD_relocBuffDesc[channel]),
537537- cSave, MCD_taskTable, channel);
538538- }
539539- } else { /* chained DMAS */
540540- /* Initialize the progress-querying stuff to show no
541541- progress: */
542542-#if 1
543543- /* (!defined(MCD_NEED_ADDR_TRANS)) */
544544- ((volatile int *)MCD_taskTable[channel].
545545- contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
546546- = (int)((MCD_bufDesc *) srcAddr)->srcAddr;
547547- ((volatile int *)MCD_taskTable[channel].
548548- contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
549549- = (int)((MCD_bufDesc *) srcAddr)->destAddr;
550550-#else
551551- /* if using address translation, need the virtual addr of the
552552- first buffdesc */
553553- ((volatile int *)MCD_taskTable[channel].
554554- contextSaveSpace)[SRCPTR + CSAVE_OFFSET]
555555- = (int)((MCD_bufDesc *) srcAddrVirt)->srcAddr;
556556- ((volatile int *)MCD_taskTable[channel].
557557- contextSaveSpace)[DESTPTR + CSAVE_OFFSET]
558558- = (int)((MCD_bufDesc *) srcAddrVirt)->destAddr;
559559-#endif
560560- ((volatile int *)MCD_taskTable[channel].
561561- contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0;
562562- ((volatile int *)MCD_taskTable[channel].
563563- contextSaveSpace)[CURRBD + CSAVE_OFFSET] = (u32) srcAddr;
564564-565565- if (funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2) {
566566- /*TDTStart and TDTEnd */
567567- MCD_taskTable[channel].TDTstart =
568568- MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart;
569569- MCD_taskTable[channel].TDTend =
570570- MCD_modelTaskTable[TASK_CHAINNOEU].TDTend;
571571- MCD_startDmaChainNoEu((int *)srcAddr, srcIncr,
572572- destIncr, xferSize,
573573- xferSizeIncr, cSave,
574574- MCD_taskTable, channel);
575575- } else {
576576- /*TDTStart and TDTEnd */
577577- MCD_taskTable[channel].TDTstart =
578578- MCD_modelTaskTable[TASK_CHAINEU].TDTstart;
579579- MCD_taskTable[channel].TDTend =
580580- MCD_modelTaskTable[TASK_CHAINEU].TDTend;
581581- MCD_startDmaChainEu((int *)srcAddr, srcIncr, destIncr,
582582- xferSize, xferSizeIncr, cSave,
583583- MCD_taskTable, channel);
584584- }
585585- }
586586- MCD_chStatus[channel] = MCD_IDLE;
587587- return (MCD_OK);
588588-}
589589-590590-/************************ End of MCD_startDma() *********************/
591591-592592-/********************************************************************/
593593-/* Function: MCD_XferProgrQuery
594594- * Purpose: Returns progress of DMA on requested channel
595595- * Arguments: channel - channel to retrieve progress for
596596- * progRep - pointer to user supplied MCD_XferProg struct
597597- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
598598- *
599599- * Notes:
600600- * MCD_XferProgrQuery() upon completing or after aborting a DMA, or
601601- * while the DMA is in progress, this function returns the first
602602- * DMA-destination address not (or not yet) used in the DMA. When
603603- * encountering a non-ready buffer descriptor, the information for
604604- * the last completed descriptor is returned.
605605- *
606606- * MCD_XferProgQuery() has to avoid the possibility of getting
607607- * partially-updated information in the event that we should happen
608608- * to query DMA progress just as the DMA is updating it. It does that
609609- * by taking advantage of the fact context is not saved frequently for
610610- * the most part. We therefore read it at least twice until we get the
611611- * same information twice in a row.
612612- *
613613- * Because a small, but not insignificant, amount of time is required
614614- * to write out the progress-query information, especially upon
615615- * completion of the DMA, it would be wise to guarantee some time lag
616616- * between successive readings of the progress-query information.
617617- */
618618-619619-/* How many iterations of the loop below to execute to stabilize values */
620620-#define STABTIME 0
621621-622622-int MCD_XferProgrQuery(int channel, MCD_XferProg * progRep)
623623-{
624624- MCD_XferProg prevRep;
625625- int again; /* true if we are to try again to ge
626626- consistent results */
627627- int i; /* used as a time-waste counter */
628628- int destDiffBytes; /* Total no of bytes that we think actually
629629- got xfered. */
630630- int numIterations; /* number of iterations */
631631- int bytesNotXfered; /* bytes that did not get xfered. */
632632- s8 *LWAlignedInitDestAddr, *LWAlignedCurrDestAddr;
633633- int subModVal, addModVal; /* Mode values to added and subtracted
634634- from the final destAddr */
635635-636636- if ((channel < 0) || (channel >= NCHANNELS))
637637- return (MCD_CHANNEL_INVALID);
638638-639639- /* Read a trial value for the progress-reporting values */
640640- prevRep.lastSrcAddr =
641641- (s8 *) ((volatile int *)MCD_taskTable[channel].
642642- contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
643643- prevRep.lastDestAddr =
644644- (s8 *) ((volatile int *)MCD_taskTable[channel].
645645- contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
646646- prevRep.dmaSize =
647647- ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT +
648648- CSAVE_OFFSET];
649649- prevRep.currBufDesc =
650650- (MCD_bufDesc *) ((volatile int *)MCD_taskTable[channel].
651651- contextSaveSpace)[CURRBD + CSAVE_OFFSET];
652652- /* Repeatedly reread those values until they match previous values: */
653653- do {
654654- /* Waste a little bit of time to ensure stability: */
655655- for (i = 0; i < STABTIME; i++) {
656656- /* make sure this loop does something so that it
657657- doesn't get optimized out */
658658- i += i >> 2;
659659- }
660660- /* Check them again: */
661661- progRep->lastSrcAddr =
662662- (s8 *) ((volatile int *)MCD_taskTable[channel].
663663- contextSaveSpace)[SRCPTR + CSAVE_OFFSET];
664664- progRep->lastDestAddr =
665665- (s8 *) ((volatile int *)MCD_taskTable[channel].
666666- contextSaveSpace)[DESTPTR + CSAVE_OFFSET];
667667- progRep->dmaSize =
668668- ((volatile int *)MCD_taskTable[channel].
669669- contextSaveSpace)[DCOUNT + CSAVE_OFFSET];
670670- progRep->currBufDesc =
671671- (MCD_bufDesc *) ((volatile int *)MCD_taskTable[channel].
672672- contextSaveSpace)[CURRBD + CSAVE_OFFSET];
673673- /* See if they match: */
674674- if (prevRep.lastSrcAddr != progRep->lastSrcAddr
675675- || prevRep.lastDestAddr != progRep->lastDestAddr
676676- || prevRep.dmaSize != progRep->dmaSize
677677- || prevRep.currBufDesc != progRep->currBufDesc) {
678678- /* If they don't match, remember previous values and
679679- try again: */
680680- prevRep.lastSrcAddr = progRep->lastSrcAddr;
681681- prevRep.lastDestAddr = progRep->lastDestAddr;
682682- prevRep.dmaSize = progRep->dmaSize;
683683- prevRep.currBufDesc = progRep->currBufDesc;
684684- again = MCD_TRUE;
685685- } else
686686- again = MCD_FALSE;
687687- } while (again == MCD_TRUE);
688688-689689- /* Update the dCount, srcAddr and destAddr */
690690- /* To calculate dmaCount, we consider destination address. C
691691- overs M1,P1,Z for destination */
692692- switch (MCD_remVariants.remDestRsdIncr[channel]) {
693693- case MINUS1:
694694- subModVal =
695695- ((int)progRep->
696696- lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) -
697697- 1);
698698- addModVal =
699699- ((int)progRep->currBufDesc->
700700- destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
701701- LWAlignedInitDestAddr =
702702- (progRep->currBufDesc->destAddr) - addModVal;
703703- LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal;
704704- destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr;
705705- bytesNotXfered =
706706- (destDiffBytes / MCD_remVariants.remDestIncr[channel]) *
707707- (MCD_remVariants.remDestIncr[channel]
708708- + MCD_remVariants.remXferSize[channel]);
709709- progRep->dmaSize =
710710- destDiffBytes - bytesNotXfered + addModVal - subModVal;
711711- break;
712712- case ZERO:
713713- progRep->lastDestAddr = progRep->currBufDesc->destAddr;
714714- break;
715715- case PLUS1:
716716- /* This value has to be subtracted from the final
717717- calculated dCount. */
718718- subModVal =
719719- ((int)progRep->currBufDesc->
720720- destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1);
721721- /* These bytes are already in lastDestAddr. */
722722- addModVal =
723723- ((int)progRep->
724724- lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) -
725725- 1);
726726- LWAlignedInitDestAddr =
727727- (progRep->currBufDesc->destAddr) - subModVal;
728728- LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal;
729729- destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr);
730730- numIterations =
731731- (LWAlignedCurrDestAddr -
732732- LWAlignedInitDestAddr) /
733733- MCD_remVariants.remDestIncr[channel];
734734- bytesNotXfered =
735735- numIterations * (MCD_remVariants.remDestIncr[channel]
736736- - MCD_remVariants.remXferSize[channel]);
737737- progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal;
738738- break;
739739- default:
740740- break;
741741- }
742742-743743- /* This covers M1,P1,Z for source */
744744- switch (MCD_remVariants.remSrcRsdIncr[channel]) {
745745- case MINUS1:
746746- progRep->lastSrcAddr =
747747- progRep->currBufDesc->srcAddr +
748748- (MCD_remVariants.remSrcIncr[channel] *
749749- (progRep->dmaSize / MCD_remVariants.remXferSize[channel]));
750750- break;
751751- case ZERO:
752752- progRep->lastSrcAddr = progRep->currBufDesc->srcAddr;
753753- break;
754754- case PLUS1:
755755- progRep->lastSrcAddr =
756756- progRep->currBufDesc->srcAddr +
757757- (MCD_remVariants.remSrcIncr[channel] *
758758- (progRep->dmaSize / MCD_remVariants.remXferSize[channel]));
759759- break;
760760- default:
761761- break;
762762- }
763763-764764- return (MCD_OK);
765765-}
766766-767767-/******************* End of MCD_XferProgrQuery() ********************/
768768-769769-/********************************************************************/
770770-/* MCD_resmActions() does the majority of the actions of a DMA resume.
771771- * It is called from MCD_killDma() and MCD_resumeDma(). It has to be
772772- * a separate function because the kill function has to negate the task
773773- * enable before resuming it, but the resume function has to do nothing
774774- * if there is no DMA on that channel (i.e., if the enable bit is 0).
775775- */
776776-static void MCD_resmActions(int channel)
777777-{
778778- MCD_dmaBar->debugControl = DBG_CTL_DISABLE;
779779- MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus;
780780- /* This register is selected to know which initiator is
781781- actually asserted. */
782782- MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT;
783783-784784- if ((MCD_dmaBar->ptdDebug >> channel) & 0x1)
785785- MCD_chStatus[channel] = MCD_RUNNING;
786786- else
787787- MCD_chStatus[channel] = MCD_IDLE;
788788-}
789789-790790-/********************* End of MCD_resmActions() *********************/
791791-792792-/********************************************************************/
793793-/* Function: MCD_killDma
794794- * Purpose: Halt the DMA on the requested channel, without any
795795- * intention of resuming the DMA.
796796- * Arguments: channel - requested channel
797797- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
798798- *
799799- * Notes:
800800- * A DMA may be killed from any state, including paused state, and it
801801- * always goes to the MCD_HALTED state even if it is killed while in
802802- * the MCD_NO_DMA or MCD_IDLE states.
803803- */
804804-int MCD_killDma(int channel)
805805-{
806806- /* MCD_XferProg progRep; */
807807-808808- if ((channel < 0) || (channel >= NCHANNELS))
809809- return (MCD_CHANNEL_INVALID);
810810-811811- MCD_dmaBar->taskControl[channel] = 0x0;
812812- MCD_resumeDma(channel);
813813- /*
814814- * This must be after the write to the TCR so that the task doesn't
815815- * start up again momentarily, and before the status assignment so
816816- * as to override whatever MCD_resumeDma() may do to the channel
817817- * status.
818818- */
819819- MCD_chStatus[channel] = MCD_HALTED;
820820-821821- /*
822822- * Update the current buffer descriptor's lastDestAddr field
823823- *
824824- * MCD_XferProgrQuery (channel, &progRep);
825825- * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
826826- */
827827- return (MCD_OK);
828828-}
829829-830830-/************************ End of MCD_killDma() **********************/
831831-832832-/********************************************************************/
833833-/* Function: MCD_continDma
834834- * Purpose: Continue a DMA which as stopped due to encountering an
835835- * unready buffer descriptor.
836836- * Arguments: channel - channel to continue the DMA on
837837- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
838838- *
839839- * Notes:
840840- * This routine does not check to see if there is a task which can
841841- * be continued. Also this routine should not be used with single DMAs.
842842- */
843843-int MCD_continDma(int channel)
844844-{
845845- if ((channel < 0) || (channel >= NCHANNELS))
846846- return (MCD_CHANNEL_INVALID);
847847-848848- MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN;
849849- MCD_chStatus[channel] = MCD_RUNNING;
850850-851851- return (MCD_OK);
852852-}
853853-854854-/********************** End of MCD_continDma() **********************/
855855-856856-/*********************************************************************
857857- * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit
858858- * to freeze a task and resume it. We freeze a task by breakpointing
859859- * on the stated task. That is, not any specific place in the task,
860860- * but any time that task executes. In particular, when that task
861861- * executes, we want to freeze that task and only that task.
862862- *
863863- * The bits of the debug control register influence interrupts vs.
864864- * breakpoints as follows:
865865- * - Bits 14 and 0 enable or disable debug functions. If enabled, you
866866- * will get the interrupt but you may or may not get a breakpoint.
867867- * - Bits 2 and 1 decide whether you also get a breakpoint in addition
868868- * to an interrupt.
869869- *
870870- * The debug unit can do these actions in response to either internally
871871- * detected breakpoint conditions from the comparators, or in response
872872- * to the external breakpoint pin, or both.
873873- * - Bits 14 and 1 perform the above-described functions for
874874- * internally-generated conditions, i.e., the debug comparators.
875875- * - Bits 0 and 2 perform the above-described functions for external
876876- * conditions, i.e., the breakpoint external pin.
877877- *
878878- * Note that, although you "always" get the interrupt when you turn
879879- * the debug functions, the interrupt can nevertheless, if desired, be
880880- * masked by the corresponding bit in the PTD's IMR. Note also that
881881- * this means that bits 14 and 0 must enable debug functions before
882882- * bits 1 and 2, respectively, have any effect.
883883- *
884884- * NOTE: It's extremely important to not pause more than one DMA channel
885885- * at a time.
886886- ********************************************************************/
887887-888888-/********************************************************************/
889889-/* Function: MCD_pauseDma
890890- * Purpose: Pauses the DMA on a given channel (if any DMA is running
891891- * on that channel).
892892- * Arguments: channel
893893- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
894894- */
895895-int MCD_pauseDma(int channel)
896896-{
897897- /* MCD_XferProg progRep; */
898898-899899- if ((channel < 0) || (channel >= NCHANNELS))
900900- return (MCD_CHANNEL_INVALID);
901901-902902- if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) {
903903- MCD_dmaBar->debugComp1 = channel;
904904- MCD_dmaBar->debugControl =
905905- DBG_CTL_ENABLE | (1 << (channel + 16));
906906- MCD_chStatus[channel] = MCD_PAUSED;
907907-908908- /*
909909- * Update the current buffer descriptor's lastDestAddr field
910910- *
911911- * MCD_XferProgrQuery (channel, &progRep);
912912- * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr;
913913- */
914914- }
915915- return (MCD_OK);
916916-}
917917-918918-/************************* End of MCD_pauseDma() ********************/
919919-920920-/********************************************************************/
921921-/* Function: MCD_resumeDma
922922- * Purpose: Resumes the DMA on a given channel (if any DMA is
923923- * running on that channel).
924924- * Arguments: channel - channel on which to resume DMA
925925- * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK
926926- */
927927-int MCD_resumeDma(int channel)
928928-{
929929- if ((channel < 0) || (channel >= NCHANNELS))
930930- return (MCD_CHANNEL_INVALID);
931931-932932- if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN)
933933- MCD_resmActions(channel);
934934-935935- return (MCD_OK);
936936-}
937937-938938-/************************ End of MCD_resumeDma() ********************/
939939-940940-/********************************************************************/
941941-/* Function: MCD_csumQuery
942942- * Purpose: Provide the checksum after performing a non-chained DMA
943943- * Arguments: channel - channel to report on
944944- * csum - pointer to where to write the checksum/CRC
945945- * Returns: MCD_ERROR if the channel is invalid, else MCD_OK
946946- *
947947- * Notes:
948948- *
949949- */
950950-int MCD_csumQuery(int channel, u32 * csum)
951951-{
952952-#ifdef MCD_INCLUDE_EU
953953- if ((channel < 0) || (channel >= NCHANNELS))
954954- return (MCD_CHANNEL_INVALID);
955955-956956- *csum = MCD_relocBuffDesc[channel].csumResult;
957957- return (MCD_OK);
958958-#else
959959- return (MCD_ERROR);
960960-#endif
961961-}
962962-963963-/*********************** End of MCD_resumeDma() *********************/
964964-965965-/********************************************************************/
966966-/* Function: MCD_getCodeSize
967967- * Purpose: Provide the size requirements of the microcoded tasks
968968- * Returns: Size in bytes
969969- */
970970-int MCD_getCodeSize(void)
971971-{
972972-#ifdef MCD_INCLUDE_EU
973973- return (0x2b5c);
974974-#else
975975- return (0x173c);
976976-#endif
977977-}
978978-979979-/********************** End of MCD_getCodeSize() ********************/
980980-981981-/********************************************************************/
982982-/* Function: MCD_getVersion
983983- * Purpose: Provide the version string and number
984984- * Arguments: longVersion - user supplied pointer to a pointer to a char
985985- * which points to the version string
986986- * Returns: Version number and version string (by reference)
987987- */
988988-char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)";
989989-#define MCD_REV_MAJOR 0x00
990990-#define MCD_REV_MINOR 0x03
991991-992992-int MCD_getVersion(char **longVersion)
993993-{
994994- *longVersion = MCD_versionString;
995995- return ((MCD_REV_MAJOR << 8) | MCD_REV_MINOR);
996996-}
997997-998998-/********************** End of MCD_getVersion() *********************/
999999-10001000-/********************************************************************/
10011001-/* Private version of memcpy()
10021002- * Note that everything this is used for is longword-aligned.
10031003- */
10041004-static void MCD_memcpy(int *dest, int *src, u32 size)
10051005-{
10061006- u32 i;
10071007-10081008- for (i = 0; i < size; i += sizeof(int), dest++, src++)
10091009- *dest = *src;
10101010-}
···11-/* SPDX-License-Identifier: GPL-2.0+ */
22-/*
33- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
44- */
55-66-#ifndef _MCD_API_H
77-#define _MCD_API_H
88-99-/* Turn Execution Unit tasks ON (#define) or OFF (#undef) */
1010-#undef MCD_INCLUDE_EU
1111-1212-/* Number of DMA channels */
1313-#define NCHANNELS 16
1414-1515-/* Total number of variants */
1616-#ifdef MCD_INCLUDE_EU
1717-#define NUMOFVARIANTS 6
1818-#else
1919-#define NUMOFVARIANTS 4
2020-#endif
2121-2222-/* Define sizes of the various tables */
2323-#define TASK_TABLE_SIZE (NCHANNELS*32)
2424-#define VAR_TAB_SIZE (128)
2525-#define CONTEXT_SAVE_SIZE (128)
2626-#define FUNCDESC_TAB_SIZE (256)
2727-2828-#ifdef MCD_INCLUDE_EU
2929-#define FUNCDESC_TAB_NUM 16
3030-#else
3131-#define FUNCDESC_TAB_NUM 1
3232-#endif
3333-3434-#ifndef DEFINESONLY
3535-3636-/* Portability typedefs */
3737-#if 1
3838-#include "common.h"
3939-#else
4040-#ifndef s32
4141-typedef int s32;
4242-#endif
4343-#ifndef u32
4444-typedef unsigned int u32;
4545-#endif
4646-#ifndef s16
4747-typedef short s16;
4848-#endif
4949-#ifndef u16
5050-typedef unsigned short u16;
5151-#endif
5252-#ifndef s8
5353-typedef char s8;
5454-#endif
5555-#ifndef u8
5656-typedef unsigned char u8;
5757-#endif
5858-#endif
5959-6060-/*
6161- * These structures represent the internal registers of the
6262- * multi-channel DMA
6363- */
6464-struct dmaRegs_s {
6565- u32 taskbar; /* task table base address */
6666- u32 currPtr;
6767- u32 endPtr;
6868- u32 varTablePtr;
6969- u16 dma_rsvd0;
7070- u16 ptdControl; /* ptd control */
7171- u32 intPending; /* interrupt pending */
7272- u32 intMask; /* interrupt mask */
7373- u16 taskControl[16]; /* task control */
7474- u8 priority[32]; /* priority */
7575- u32 initiatorMux; /* initiator mux control */
7676- u32 taskSize0; /* task size control 0. */
7777- u32 taskSize1; /* task size control 1. */
7878- u32 dma_rsvd1; /* reserved */
7979- u32 dma_rsvd2; /* reserved */
8080- u32 debugComp1; /* debug comparator 1 */
8181- u32 debugComp2; /* debug comparator 2 */
8282- u32 debugControl; /* debug control */
8383- u32 debugStatus; /* debug status */
8484- u32 ptdDebug; /* priority task decode debug */
8585- u32 dma_rsvd3[31]; /* reserved */
8686-};
8787-typedef volatile struct dmaRegs_s dmaRegs;
8888-8989-#endif
9090-9191-/* PTD contrl reg bits */
9292-#define PTD_CTL_TSK_PRI 0x8000
9393-#define PTD_CTL_COMM_PREFETCH 0x0001
9494-9595-/* Task Control reg bits and field masks */
9696-#define TASK_CTL_EN 0x8000
9797-#define TASK_CTL_VALID 0x4000
9898-#define TASK_CTL_ALWAYS 0x2000
9999-#define TASK_CTL_INIT_MASK 0x1f00
100100-#define TASK_CTL_ASTRT 0x0080
101101-#define TASK_CTL_HIPRITSKEN 0x0040
102102-#define TASK_CTL_HLDINITNUM 0x0020
103103-#define TASK_CTL_ASTSKNUM_MASK 0x000f
104104-105105-/* Priority reg bits and field masks */
106106-#define PRIORITY_HLD 0x80
107107-#define PRIORITY_PRI_MASK 0x07
108108-109109-/* Debug Control reg bits and field masks */
110110-#define DBG_CTL_BLOCK_TASKS_MASK 0xffff0000
111111-#define DBG_CTL_AUTO_ARM 0x00008000
112112-#define DBG_CTL_BREAK 0x00004000
113113-#define DBG_CTL_COMP1_TYP_MASK 0x00003800
114114-#define DBG_CTL_COMP2_TYP_MASK 0x00000070
115115-#define DBG_CTL_EXT_BREAK 0x00000004
116116-#define DBG_CTL_INT_BREAK 0x00000002
117117-118118-/*
119119- * PTD Debug reg selector addresses
120120- * This reg must be written with a value to show the contents of
121121- * one of the desired internal register.
122122- */
123123-#define PTD_DBG_REQ 0x00 /* shows the state of 31 initiators */
124124-#define PTD_DBG_TSK_VLD_INIT 0x01 /* shows which 16 tasks are valid and
125125- have initiators asserted */
126126-127127-/* General return values */
128128-#define MCD_OK 0
129129-#define MCD_ERROR -1
130130-#define MCD_TABLE_UNALIGNED -2
131131-#define MCD_CHANNEL_INVALID -3
132132-133133-/* MCD_initDma input flags */
134134-#define MCD_RELOC_TASKS 0x00000001
135135-#define MCD_NO_RELOC_TASKS 0x00000000
136136-#define MCD_COMM_PREFETCH_EN 0x00000002 /* MCF547x/548x ONLY */
137137-138138-/*
139139- * MCD_dmaStatus Status Values for each channel:
140140- * MCD_NO_DMA - No DMA has been requested since reset
141141- * MCD_IDLE - DMA active, but the initiator is currently inactive
142142- * MCD_RUNNING - DMA active, and the initiator is currently active
143143- * MCD_PAUSED - DMA active but it is currently paused
144144- * MCD_HALTED - the most recent DMA has been killed with MCD_killTask()
145145- * MCD_DONE - the most recent DMA has completed
146146- */
147147-#define MCD_NO_DMA 1
148148-#define MCD_IDLE 2
149149-#define MCD_RUNNING 3
150150-#define MCD_PAUSED 4
151151-#define MCD_HALTED 5
152152-#define MCD_DONE 6
153153-154154-/* MCD_startDma parameter defines */
155155-156156-/* Constants for the funcDesc parameter */
157157-/*
158158- * MCD_NO_BYTE_SWAP - to disable byte swapping
159159- * MCD_BYTE_REVERSE - to reverse the bytes of each u32 of the DMAed data
160160- * MCD_U16_REVERSE - to reverse the 16-bit halves of each 32-bit data
161161- * value being DMAed
162162- * MCD_U16_BYTE_REVERSE - to reverse the byte halves of each 16-bit half of
163163- * each 32-bit data value DMAed
164164- * MCD_NO_BIT_REV - do not reverse the bits of each byte DMAed
165165- * MCD_BIT_REV - reverse the bits of each byte DMAed
166166- * MCD_CRC16 - to perform CRC-16 on DMAed data
167167- * MCD_CRCCCITT - to perform CRC-CCITT on DMAed data
168168- * MCD_CRC32 - to perform CRC-32 on DMAed data
169169- * MCD_CSUMINET - to perform internet checksums on DMAed data
170170- * MCD_NO_CSUM - to perform no checksumming
171171- */
172172-#define MCD_NO_BYTE_SWAP 0x00045670
173173-#define MCD_BYTE_REVERSE 0x00076540
174174-#define MCD_U16_REVERSE 0x00067450
175175-#define MCD_U16_BYTE_REVERSE 0x00054760
176176-#define MCD_NO_BIT_REV 0x00000000
177177-#define MCD_BIT_REV 0x00088880
178178-/* CRCing: */
179179-#define MCD_CRC16 0xc0100000
180180-#define MCD_CRCCCITT 0xc0200000
181181-#define MCD_CRC32 0xc0300000
182182-#define MCD_CSUMINET 0xc0400000
183183-#define MCD_NO_CSUM 0xa0000000
184184-185185-#define MCD_FUNC_NOEU1 (MCD_NO_BYTE_SWAP | MCD_NO_BIT_REV | \
186186- MCD_NO_CSUM)
187187-#define MCD_FUNC_NOEU2 (MCD_NO_BYTE_SWAP | MCD_NO_CSUM)
188188-189189-/* Constants for the flags parameter */
190190-#define MCD_TT_FLAGS_RL 0x00000001 /* Read line */
191191-#define MCD_TT_FLAGS_CW 0x00000002 /* Combine Writes */
192192-#define MCD_TT_FLAGS_SP 0x00000004 /* MCF547x/548x ONLY */
193193-#define MCD_TT_FLAGS_MASK 0x000000ff
194194-#define MCD_TT_FLAGS_DEF (MCD_TT_FLAGS_RL | MCD_TT_FLAGS_CW)
195195-196196-#define MCD_SINGLE_DMA 0x00000100 /* Unchained DMA */
197197-#define MCD_CHAIN_DMA /* TBD */
198198-#define MCD_EU_DMA /* TBD */
199199-#define MCD_FECTX_DMA 0x00001000 /* FEC TX ring DMA */
200200-#define MCD_FECRX_DMA 0x00002000 /* FEC RX ring DMA */
201201-202202-/* these flags are valid for MCD_startDma and the chained buffer descriptors */
203203-/*
204204- * MCD_BUF_READY - indicates that this buf is now under the DMA's ctrl
205205- * MCD_WRAP - to tell the FEC Dmas to wrap to the first BD
206206- * MCD_INTERRUPT - to generate an interrupt after completion of the DMA
207207- * MCD_END_FRAME - tell the DMA to end the frame when transferring
208208- * last byte of data in buffer
209209- * MCD_CRC_RESTART - to empty out the accumulated checksum prior to
210210- * performing the DMA
211211- */
212212-#define MCD_BUF_READY 0x80000000
213213-#define MCD_WRAP 0x20000000
214214-#define MCD_INTERRUPT 0x10000000
215215-#define MCD_END_FRAME 0x08000000
216216-#define MCD_CRC_RESTART 0x40000000
217217-218218-/* Defines for the FEC buffer descriptor control/status word*/
219219-#define MCD_FEC_BUF_READY 0x8000
220220-#define MCD_FEC_WRAP 0x2000
221221-#define MCD_FEC_INTERRUPT 0x1000
222222-#define MCD_FEC_END_FRAME 0x0800
223223-224224-/* Defines for general intuitiveness */
225225-226226-#define MCD_TRUE 1
227227-#define MCD_FALSE 0
228228-229229-/* Three different cases for destination and source. */
230230-#define MINUS1 -1
231231-#define ZERO 0
232232-#define PLUS1 1
233233-234234-#ifndef DEFINESONLY
235235-236236-/* Task Table Entry struct*/
237237-typedef struct {
238238- u32 TDTstart; /* task descriptor table start */
239239- u32 TDTend; /* task descriptor table end */
240240- u32 varTab; /* variable table start */
241241- u32 FDTandFlags; /* function descriptor table start & flags */
242242- volatile u32 descAddrAndStatus;
243243- volatile u32 modifiedVarTab;
244244- u32 contextSaveSpace; /* context save space start */
245245- u32 literalBases;
246246-} TaskTableEntry;
247247-248248-/* Chained buffer descriptor:
249249- * flags - flags describing the DMA
250250- * csumResult - checksum performed since last checksum reset
251251- * srcAddr - the address to move data from
252252- * destAddr - the address to move data to
253253- * lastDestAddr - the last address written to
254254- * dmaSize - the no of bytes to xfer independent of the xfer sz
255255- * next - next buffer descriptor in chain
256256- * info - private info about this descriptor; DMA does not affect it
257257- */
258258-typedef volatile struct MCD_bufDesc_struct MCD_bufDesc;
259259-struct MCD_bufDesc_struct {
260260- u32 flags;
261261- u32 csumResult;
262262- s8 *srcAddr;
263263- s8 *destAddr;
264264- s8 *lastDestAddr;
265265- u32 dmaSize;
266266- MCD_bufDesc *next;
267267- u32 info;
268268-};
269269-270270-/* Progress Query struct:
271271- * lastSrcAddr - the most-recent or last, post-increment source address
272272- * lastDestAddr - the most-recent or last, post-increment destination address
273273- * dmaSize - the amount of data transferred for the current buffer
274274- * currBufDesc - pointer to the current buffer descriptor being DMAed
275275- */
276276-277277-typedef volatile struct MCD_XferProg_struct {
278278- s8 *lastSrcAddr;
279279- s8 *lastDestAddr;
280280- u32 dmaSize;
281281- MCD_bufDesc *currBufDesc;
282282-} MCD_XferProg;
283283-284284-/* FEC buffer descriptor */
285285-typedef volatile struct MCD_bufDescFec_struct {
286286- u16 statCtrl;
287287- u16 length;
288288- u32 dataPointer;
289289-} MCD_bufDescFec;
290290-291291-/*************************************************************************/
292292-/* API function Prototypes - see MCD_dmaApi.c for further notes */
293293-294294-/* MCD_startDma starts a particular kind of DMA:
295295- * srcAddr - the channel on which to run the DMA
296296- * srcIncr - the address to move data from, or buffer-descriptor address
297297- * destAddr - the amount to increment the source address per transfer
298298- * destIncr - the address to move data to
299299- * dmaSize - the amount to increment the destination address per transfer
300300- * xferSize - the number bytes in of each data movement (1, 2, or 4)
301301- * initiator - what device initiates the DMA
302302- * priority - priority of the DMA
303303- * flags - flags describing the DMA
304304- * funcDesc - description of byte swapping, bit swapping, and CRC actions
305305- */
306306-int MCD_startDma(int channel, s8 * srcAddr, s16 srcIncr, s8 * destAddr,
307307- s16 destIncr, u32 dmaSize, u32 xferSize, u32 initiator,
308308- int priority, u32 flags, u32 funcDesc);
309309-310310-/*
311311- * MCD_initDma() initializes the DMA API by setting up a pointer to the DMA
312312- * registers, relocating and creating the appropriate task structures, and
313313- * setting up some global settings
314314- */
315315-int MCD_initDma(dmaRegs * sDmaBarAddr, void *taskTableDest, u32 flags);
316316-317317-/* MCD_dmaStatus() returns the status of the DMA on the requested channel. */
318318-int MCD_dmaStatus(int channel);
319319-320320-/* MCD_XferProgrQuery() returns progress of DMA on requested channel */
321321-int MCD_XferProgrQuery(int channel, MCD_XferProg * progRep);
322322-323323-/*
324324- * MCD_killDma() halts the DMA on the requested channel, without any
325325- * intention of resuming the DMA.
326326- */
327327-int MCD_killDma(int channel);
328328-329329-/*
330330- * MCD_continDma() continues a DMA which as stopped due to encountering an
331331- * unready buffer descriptor.
332332- */
333333-int MCD_continDma(int channel);
334334-335335-/*
336336- * MCD_pauseDma() pauses the DMA on the given channel ( if any DMA is
337337- * running on that channel).
338338- */
339339-int MCD_pauseDma(int channel);
340340-341341-/*
342342- * MCD_resumeDma() resumes the DMA on a given channel (if any DMA is
343343- * running on that channel).
344344- */
345345-int MCD_resumeDma(int channel);
346346-347347-/* MCD_csumQuery provides the checksum/CRC after performing a non-chained DMA */
348348-int MCD_csumQuery(int channel, u32 * csum);
349349-350350-/*
351351- * MCD_getCodeSize provides the packed size required by the microcoded task
352352- * and structures.
353353- */
354354-int MCD_getCodeSize(void);
355355-356356-/*
357357- * MCD_getVersion provides a pointer to a version string and returns a
358358- * version number.
359359- */
360360-int MCD_getVersion(char **longVersion);
361361-362362-/* macro for setting a location in the variable table */
363363-#define MCD_SET_VAR(taskTab,idx,value) ((u32 *)(taskTab)->varTab)[idx] = value
364364-/* Note that MCD_SET_VAR() is invoked many times in firing up a DMA function,
365365- so I'm avoiding surrounding it with "do {} while(0)" */
366366-367367-#endif /* DEFINESONLY */
368368-369369-#endif /* _MCD_API_H */
-10
include/MCD_progCheck.h
···11-/* SPDX-License-Identifier: GPL-2.0+ */
22-/*
33- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
44- */
55-66- /* This file is autogenerated. Do not change */
77-#define CURRBD 4
88-#define DCOUNT 6
99-#define DESTPTR 5
1010-#define SRCPTR 7
-43
include/MCD_tasksInit.h
···11-/* SPDX-License-Identifier: GPL-2.0+ */
22-/*
33- * Copyright (C) 2004-2007 Freescale Semiconductor, Inc.
44- */
55-66-#ifndef MCD_TSK_INIT_H
77-#define MCD_TSK_INIT_H 1
88-99-/*
1010- * Do not edit!
1111- */
1212-1313-/* Task 0 */
1414-void MCD_startDmaChainNoEu(int *currBD, short srcIncr, short destIncr,
1515- int xferSize, short xferSizeIncr, int *cSave,
1616- volatile TaskTableEntry * taskTable, int channel);
1717-1818-/* Task 1 */
1919-void MCD_startDmaSingleNoEu(char *srcAddr, short srcIncr, char *destAddr,
2020- short destIncr, int dmaSize, short xferSizeIncr,
2121- int flags, int *currBD, int *cSave,
2222- volatile TaskTableEntry * taskTable, int channel);
2323-2424-/* Task 2 */
2525-void MCD_startDmaChainEu(int *currBD, short srcIncr, short destIncr,
2626- int xferSize, short xferSizeIncr, int *cSave,
2727- volatile TaskTableEntry * taskTable, int channel);
2828-2929-/* Task 3 */
3030-void MCD_startDmaSingleEu(char *srcAddr, short srcIncr, char *destAddr,
3131- short destIncr, int dmaSize, short xferSizeIncr,
3232- int flags, int *currBD, int *cSave,
3333- volatile TaskTableEntry * taskTable, int channel);
3434-3535-/* Task 4 */
3636-void MCD_startDmaENetRcv(char *bDBase, char *currBD, char *rcvFifoPtr,
3737- volatile TaskTableEntry * taskTable, int channel);
3838-3939-/* Task 5 */
4040-void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr,
4141- volatile TaskTableEntry * taskTable, int channel);
4242-4343-#endif /* MCD_TSK_INIT_H */