23eae4b8090f41e3e7ab32af9f393f91cae0eb17
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sap.c
2 /*
3 Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 //
37 //
38 // SIO driver implementation for audio I/O using McASP.
39 //
40 //
41 //
43 #ifndef SAP_CACHE_SUPPORT
44   // if you rebuild dap.c in your project without this defined, 
45   // the result is quite hard to find:  Occasional glitches in the sound.
46   #define SAP_CACHE_SUPPORT  // typically defined in the project
47 #endif
49 #ifdef SAP_CACHE_SUPPORT
50 #include <ti/sysbios/hal/Cache.h>
51 #endif
53 #include <stdlib.h>
54 #include <stdio.h>
55 #include <string.h> //memset
57 #include <xdc/std.h>
59 #include "sap.h"
61 #include <ti/sdo/edma3/drv/edma3_drv.h>
62 #include <ti/sdo/edma3/drv/src/edma3.h>
63 #include <ti/sdo/edma3/rm/edma3_rm.h>
64 #include <ti/sdo/edma3/drv/sample/bios6_edma3_drv_sample.h>
66 #include <ti/csl/cslr_device.h>
68 #define EDMA_HINV NULL
70 #include "sap_mcasp.h"
71 #include <pafsio.h>
73 // This works to set a breakpoint
74 #define SW_BREAKPOINT       asm( " SWBP 0" );
75 /* Software Breakpoint to Code Composer */
76 // SW_BREAKPOINT;
78 // global allocated in bios_edma3_drv_sample_init.c
79 extern EDMA3_DRV_Handle hEdma0;
80 extern EDMA3_DRV_Handle hEdma1;
82 int gStartError;
83 int gIsrInputCnt;
84 int gIsrOutputCnt;
85 int gIsrElseCnt;
86 int gIsrInErrCnt;
87 int gIsrOutErrCnt;
88 int gIsrRunCnt;
89 int gIsrNotRunCnt;
90 int gisrOutput;
91 int gSAPResetIn;
92 int gSAPResetOut;
94 typedef xdc_Short MdInt;
96 void swapHdmi(Ptr, int);
98 #define SAP_UNDER_LEN 8
100 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
101 int sap_OVER_1LANE = 0;     // used for overrun
102 int sap_OVER_4LANE[4] = {0,0,0,0};      // used for overrun
104 #ifdef DEBUG
105 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
107         //unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
108         //unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
109         unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
110         unsigned int *ptrPARAM0x41 = (unsigned int *)0x027048A0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
111         unsigned int *ptrPARAM0x42 = (unsigned int *)0x027048C0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
112         unsigned int *ptrPARAM0x43 = (unsigned int *)0x027048E0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
113         unsigned int *ptrPARAM0x44 = (unsigned int *)0x02704910; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
115         //Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
116         //Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
118         Log_info5("PARAM0x19a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x19[0] & 0x200000) >> 21), ((ptrPARAM0x19[0] & 0x100000) >> 20), ((ptrPARAM0x19[0] & 0x3F000) >> 12), ((ptrPARAM0x19[0] & 0x800) >> 11));
119         Log_info5("PARAM0x19b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x19[1], ptrPARAM0x19[2], ptrPARAM0x19[3], ptrPARAM0x19[4]);
120         Log_info4("PARAM0x19b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
122         Log_info5("PARAM0x41a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x41[0] & 0x200000) >> 21), ((ptrPARAM0x41[0] & 0x100000) >> 20), ((ptrPARAM0x41[0] & 0x3F000) >> 12), ((ptrPARAM0x41[0] & 0x800) >> 11));
123         Log_info5("PARAM0x41b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x41[1], ptrPARAM0x41[2], ptrPARAM0x41[3], ptrPARAM0x41[4]);
124         Log_info4("PARAM0x41b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x41[5], ptrPARAM0x41[6], ptrPARAM0x41[7]);
126         Log_info5("PARAM0x42a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x42[0] & 0x200000) >> 21), ((ptrPARAM0x42[0] & 0x100000) >> 20), ((ptrPARAM0x42[0] & 0x3F000) >> 12), ((ptrPARAM0x42[0] & 0x800) >> 11));
127         Log_info5("PARAM0x42b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x42[1], ptrPARAM0x42[2], ptrPARAM0x42[3], ptrPARAM0x42[4]);
128         Log_info4("PARAM0x42b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x42[5], ptrPARAM0x42[6], ptrPARAM0x42[7]);
130         Log_info5("PARAM0x43a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x43[0] & 0x200000) >> 21), ((ptrPARAM0x43[0] & 0x100000) >> 20), ((ptrPARAM0x43[0] & 0x3F000) >> 12), ((ptrPARAM0x43[0] & 0x800) >> 11));
131         Log_info5("PARAM0x43b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x43[1], ptrPARAM0x43[2], ptrPARAM0x43[3], ptrPARAM0x43[4]);
132         Log_info4("PARAM0x43b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x43[5], ptrPARAM0x43[6], ptrPARAM0x43[7]);
134         Log_info5("PARAM0x44a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x44[0] & 0x200000) >> 21), ((ptrPARAM0x44[0] & 0x100000) >> 20), ((ptrPARAM0x44[0] & 0x3F000) >> 12), ((ptrPARAM0x44[0] & 0x800) >> 11));
135         Log_info5("PARAM0x44b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x44[1], ptrPARAM0x44[2], ptrPARAM0x44[3], ptrPARAM0x44[4]);
136         Log_info4("PARAM0x44b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x44[5], ptrPARAM0x44[6], ptrPARAM0x44[7]);
137     //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
139 #endif
140 // .............................................................................
141 // notes:
142 //  . add control function to PORT table
143 //  . how to handle DMA/PORT specifics in parameter entries
144 //      can assume numSers = numChans is general and can be applied by DMA
145 //      same for wordSize?
146 //  . why are two idle stages needed (seems like 1 is enough)?
148 // .............................................................................
149 // only one global variable, not static so that DMA and port functions
150 // can access. We cant just store the address in devExt since the ISR has
151 // no context.
153 SAP_DriverObject sapDrv;
155 // needed since SAP_watchDog is called before SAP_init
156 Int SAP_initialized = 0;
158 //Int  SAP_close(DEV2_Handle);
159 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
160 Int  SAP_idle(DEV2_Handle, Bool);
161 Int  SAP_issue(DEV2_Handle);
162 Int  SAP_open(DEV2_Handle, String);
163 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
164 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
165 Int  SAP_reclaim(DEV2_Handle);
166 Int  SAP_shutdown(DEV2_Handle);
167 Int  SAP_start(DEV2_Handle);
168 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
169 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size);
170 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
172 // .............................................................................
174 // .............................................................................
176 SAP_DMA_Fxns SAP_EDMA_FXNS =
178         SAP_EDMA_setupParam,
179         SAP_EDMA_setupXfer,
180 };
183 SAP_Fxns SAP_FXNS =
185     NULL, //SAP_close, -- remove for IROM since not using
186     SAP_ctrl,
187     SAP_idle,
188     SAP_issue,
189     SAP_open,
190     NULL, //SAP_ready, -- remove for IROM since not using
191     SAP_reclaim,
192     SAP_shutdown,
193     SAP_start,
194     SAP_config,
196 #ifdef SAP_PORT_MCASP
197     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
198 #endif
199 #ifdef SAP_DMA_EDMA
200     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
201 #endif
202 };
204 // -----------------------------------------------------------------------------
205 // This function is not in the driver function table.
206 // Must be pointed at in GUI config tool.
207 //
208 Void SAP_init (Void)
210     DEV2_Device  *entry;
211     SAP_Fxns    *pFxns;
213     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
215     // find function table pointer (used by SAP_XX_FTABLE_init macros)
216     DEV2_match(SAP_NAME, &entry);
217     if (entry == NULL) {
218         Log_error1 ("SAP", SIO2_ENODEV);
219         return;
220     }
221     pFxns = (SAP_Fxns *) entry->fxns;
223     //SAP_DMA_FTABLE_init ();
224     SAP_PORT_FTABLE_init ();
226     sapDrv.numDevices = 0;
227     SAP_initialized = 1;
229     return;
230 } // SAP_init
232 // -----------------------------------------------------------------------------
234 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
236     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
237     const SAP_Params *pParams;
238     Int i, result = SIO2_OK;
239     EDMA3_DRV_Handle    hEdma;
240     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
242     switch (code) {
244 /* .......................................................................... */
246         case PAF_SIO_CONTROL_MUTE:
247         case PAF_SIO_CONTROL_UNMUTE:
248             pParams = pDevExt->pParams;
249             if (pParams == NULL)
250                 return SIO2_OK;
252             if (pParams->sio.control != NULL)
253                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
254             break;
256 /* .......................................................................... */
258         case PAF_SIO_CONTROL_OPEN:
259             if (pDevExt->runState)
260                 return SIO2_EBUSY;
262             if (!( pParams = (const SAP_Params *) arg ))
263                 return SIO2_OK;
265             if (result = SAP_FTABLE_config (device, pParams))
266                 return result;
268             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
269                 return result;
271             break;
273 /* .......................................................................... */
275         case PAF_SIO_CONTROL_CLOSE:
276             if (pDevExt->runState)
277                 return SIO2_EBUSY;
279             if (pDevExt->pParams == NULL)
280                                 return SIO2_EINVAL;
282             pParams = pDevExt->pParams;
284                         if (pParams->sio.moduleNum == 0)
285                                 hEdma = hEdma0;
286                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
287                                 hEdma = hEdma1;
289             if (pDevExt->activeEdma != EDMA_HINV) {
290                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
291                                 pDevExt->activeEdma = EDMA_HINV;
292                         }
294             for (i=0; i < pDevExt->numEdmaParams; i++) {
295                 if (pDevExt->edmaParams[i].hEdmaParam != EDMA_HINV)
296                 {
297                         EDMA3_DRV_freeChannel (hEdma, pDevExt->edmaParams[i].hEdmaParam);
298                         pDevExt->edmaParams[i].hEdmaParam = EDMA_HINV;
299                 }
300             }
302             if (pDevExt->errorEdma != EDMA_HINV) {
303                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->errorEdma);
304                                 pDevExt->errorEdma = EDMA_HINV;
305                         }
307             if (!(pParams = pDevExt->pParams))
308                 return SIO2_OK;
310             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
311                 return result;
313             result = SAP_PORT_FTABLE_close (device);
314             if (result)
315                 return result;
317             pDevExt->pParams = NULL;
318             break;
320 /* .......................................................................... */
322         case PAF_SIO_CONTROL_GET_WORDSIZE:
323                 if (!arg)
324                                 return SIO2_EINVAL;
325                         *((int *) arg) = pDevExt->edmaWordSize;
326             break;
328         case PAF_SIO_CONTROL_SET_WORDSIZE:
329             // defer to DMA processing
330                 // currently only supported for input
331                         if (device->mode != DEV2_INPUT)
332                                 return SIO2_EINVAL;
334                         // can't be running
335                         if (pDevExt->runState)
336                                 return SIO2_EBUSY;
338                         // driver only supports 2 or 4 bytes
339                    if ((arg != 2) && (arg != 4))
340                                 return SIO2_EINVAL;
342                         // return success for unconfigured devices?
343                         if (!pDevExt->pParams)
344                                 return SIO2_OK;
346                         // ask platform if size is supported
347                         pParams = pDevExt->pParams;
348                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
349                                 return result;
351                         pDevExt->edmaWordSize = arg;
352                         break;
354         case PAF_SIO_CONTROL_GET_PRECISION:
355             if (arg == 0)
356                 return SIO2_EINVAL;
358             pParams = pDevExt->pParams;
359             if (pParams == NULL)
360                 return( SIO2_EINVAL );
362             *((int *) arg) = pParams->sio.precision;
363             break;
365         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
366             if (arg == 0)
367                 return SIO2_EINVAL;
369             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
370             break;
372         case PAF_SIO_CONTROL_SET_RATEX:
373             pParams = pDevExt->pParams;
374             if (pParams == NULL)
375                 return SIO2_OK ;
377             if (pParams->sio.control == NULL)
378                 return SIO2_EINVAL;
380             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
381             break;
383 /* .......................................................................... */
385         case PAF_SIO_CONTROL_IDLE:
386             pParams = pDevExt->pParams;
387             if (pParams == NULL)
388                 return SIO2_OK ;
390             if (pParams->sio.control == NULL)
391                 return SIO2_EINVAL;
393             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
394             break;
396         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
397             // 1. Here we are intentionally not using SIO_Idle() and
398             //    leaving the Tx clock running. We need this to avoid DAC noise,
399             //    as well as provide a DIT clock when using digital output.
400             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
401                 return SIO2_EINVAL;
403             pParams = pDevExt->pParams;
405             if (pParams->sio.moduleNum == 0)
406                 hEdma = hEdma0;
407             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
408                                 hEdma = hEdma1;
410             result = SAP_FTABLE_shutdown (device);
411             if (result)
412                 return result;
414             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
415             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
417 #if 1
418             //DJDBG, if below enableTransfer() is commented, input side continuous working.
419      if (pDevExt->activeEdma != EDMA_HINV) {
420                 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
421             //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
422             EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
423      }
424 #endif
425             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
427             break;
429 /* .......................................................................... */
431         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
432             // needs to be attached
433             pParams = pDevExt->pParams;
434             if (pParams == NULL)
435                 return SIO2_OK;
437             if (pParams->sio.control == NULL)
438                 return SIO2_EINVAL;
440             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
441             break;
443         case PAF_SIO_CONTROL_WATCHDOG:
444             pParams = pDevExt->pParams;
445             if (pParams == NULL)
446                 return SIO2_OK;
447             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
448                 return result;
449             break;
450             
451 /* .......................................................................... */
453         // Timing stats specific to DMA engine
454         case PAF_SIO_CONTROL_ENABLE_STATS:
455         case PAF_SIO_CONTROL_DISABLE_STATS:
456         case PAF_SIO_CONTROL_GET_STATS:
457         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
458         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
459             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
460             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
461             break;
463 /* .......................................................................... */
465         case PAF_SIO_CONTROL_SET_DITSTATUS:
466             if(device->mode == DEV2_OUTPUT)
467             {
468                 const SAP_Params *pParams = pDevExt->pParams;
469                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
470                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
471                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
472                 int encSelect = *((int *) arg);
474                 // HACK -- determine DIT need by FXWID
475                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
476                 {
477                     if ( (encSelect == 0x13) ||
478                          (encSelect == 0xa)  || 
479                          (encSelect == 0x6)) // DTE, DDE, MPE 
480                     {
481                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
482                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
483                     }
484                     else
485                     {
486                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
487                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
488                     }
489                 }
491                 pParams = pDevExt->pParams;
492                 if (pParams == NULL)
493                     return SIO2_OK;
495                 if (pParams->sio.control != NULL)
496                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
497             }
498             break;
500 /* .......................................................................... */
502     }
504     return result;
505 } // SAP_ctrl
507 int gSAPIdleShutdownIn=0;
508 int gSAPIdleShutdownOut=0;
510 // -----------------------------------------------------------------------------
512 Int SAP_idle (DEV2_Handle device, Bool flush)
514     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
515     Int result = SIO2_OK;
516     EDMA3_DRV_Handle hEdma;
518     // do nothing if already idled or unattached
519     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
520         return result;
522         if (pDevExt->pParams->sio.moduleNum == 0)
523                 hEdma = hEdma0;
524         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
525                 hEdma = hEdma1;
527     // reset serial port -- stop generating sync events
528     result = SAP_PORT_FTABLE_reset (device);
529     if(device->mode == DEV2_OUTPUT)
530         gSAPResetOut++;
531     else
532         gSAPResetIn++;
533     if (result)
534     {
535         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
536         return result;
537     }
539     pDevExt->shutDown = 0; // force shutdown to run
540     result = SAP_FTABLE_shutdown (device);
541     if(device->mode == DEV2_OUTPUT)
542         gSAPIdleShutdownOut++;
543     else
544         gSAPIdleShutdownIn++;
546     if (result)
547     {
548         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
549         return result;
550     }
552     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
554     // disable interrupts and EDMA servicing
555    if (pDevExt->activeEdma != EDMA_HINV)
556            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
558     pDevExt->numQueued = 0;
560     // signal stopped
561     pDevExt->runState = 0;
563     // reset errorState
564     pDevExt->errorState = PAF_SIO_ERROR_NONE;
565     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
567     // place call to physical device
568     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
569         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
571     return result;
572 } // SAP_idle
574 // -----------------------------------------------------------------------------
576 Int SAP_start (DEV2_Handle device)
578     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
579     DEV2_Frame *pFrame;
580     int result;
581     EDMA3_DRV_Handle hEdma;
583     //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
585     // signal we have started
586     //    we change the state here since we have already moved a frame from the 
587     //    todevice queue to the xferQue. If an error occurs during one of the 
588     //    following resets/enables then we need to have runState !=0 in order
589     //    for SAP_idle to properly cleanup. Moreover, the following resets/enables
590     //    do not (and are now required not to) depend on runState being 0.
591     //pDevExt->runState = 1;
592     // Assume todevice queue is not empty -- how else could we be here?
593     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
595     // inidicate this xfer did not use param entry - just the active one
596     pFrame->misc = NULL;
597     if (pDevExt->pParams->sio.moduleNum == 0)
598         hEdma = hEdma0;
599     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
600                 hEdma = hEdma1;
602     // non-atomic functions since not running yet.
603     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
605     // initialize count
606     pDevExt->numQueued = 1;
608     result = SAP_PORT_FTABLE_reset (device);
609     if (result)
610     {
611         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
612         return result;
613     }
615     // enable DMA processing
617     // config active xfer for this buffer
618     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
620     //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
621       //              __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
622         // signal we have started -- this must come before last enable to prevent a race
623         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
624         // and completes before any further instructions in this thread are executed.
625         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
626         // will be serviced and generate an interrupt even before the McASP is enabled.
627         pDevExt->runState = 1;
628         pDevExt->shutDown = 0;
629         Log_info1 ("SAP: %d, SAP_start runState=1 & ENABLE TRANSFERS", __LINE__);
630         // enable interrupts and event servicing for this channel
631         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
633     // enable peripheral
634     result = SAP_PORT_FTABLE_enable (device);
636     if (result)
637     {
638         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
639         return result;
640     }
642     return SIO2_OK;
643 } // SAP_start
645 int gDmaParamsarray[17][3];
646 int gDmaParamsidx=0, gSAPSpecialCase=0;
647 // -----------------------------------------------------------------------------
649 Int SAP_issue (DEV2_Handle device)
651     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
652     DEV2_Frame *pFrame;
653     Int result;
654     SAP_EDMA_Param *pParam;
655     XDAS_UInt32 parentEdma;
657     //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
659     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
660     {
661         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
662             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
663         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
664                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
665         return SIO2_EBADIO;
666     }
668     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
669         {
670                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
671             return SIO2_EBADIO;
672         }
674     // if not yet running then configure active xfer and start
675     if (pDevExt->runState == 0)
676         return (SAP_FTABLE_start(device));
678     // .........................................................................
679     // here if running
681     // disable device interrupts
682     // TODO: is there an API to just disable the IER bit for this tcc?
683     unsigned int key = Hwi_disable ();
684        /* determine parent EDMA
685           if no xfers in queue and we are running then must be in the
686           error state so link to active channel otherwise link to last
687           transfer queued.
688        */
690        /* here we assume after Tx SIO_idle or overrun, the user
691           will issue, at least, back-to-back issue requests so
692           there should be no problem here.
693        */
694        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
695            parentEdma = pDevExt->activeEdma;
696        else {
697            // if here then xferQue has more than one element so ok to use tail
698            // last scheduled transfer must be queue->prev
699            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
700            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
701        }
703     // get frame and parameter table to use; ints off => non-atomic OK
704     //     dont need to check for empty queues since were here then todevice
705     //     must have a frame placed there by the SIO_issue layer.
706     //     paramQue must be valid since it is accessed the same as todevice.
707     //     (indirectly -- isr places used items onto paramQue and fromdevice que
708     //      at the same time)
709     // set misc argument to pParam so get enqueue later
710     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
711     pFrame = Queue_dequeue (device->todevice);
712     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
714     if (pParam->hEdmaParam == NULL)
715         Log_info0("SAP_issue: hEdma value is NULL");
716     // set misc argument to pParam so get enqueue later
717     pFrame->misc = (Arg) pParam;
719     // place on holder queue, ints off => non-atomic OK
720     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
721     if (pFrame->addr) {
722                 if (device->mode == DEV2_INPUT)
723                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
724                 else
725                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
726         }
728     // increment count
729     pDevExt->numQueued += 1;
731     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
732     Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
733                     __LINE__, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma);
735     /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
736         {
737         gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
738                 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
739                 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
740         } */
742         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
743                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
745         pDevExt->shutDown = 0;
747     // special case enables when not yet started
748     if (pDevExt->runState == 0) {
749         gSAPSpecialCase++;
750         result = SAP_FTABLE_start (device);
751         if (result) {
752             //SAP_DMA_FTABLE_unlock (device);
753                   Hwi_restore (key);
754             return result;
755         }
756     }
757     Hwi_restore (key); //DJDBG
759     return result;
760 } // SAP_issue
762 // -----------------------------------------------------------------------------
764 void swapHdmi(Ptr Input, int size)
767         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
768         MdInt *p1, *p2;
769         int i=0;
771         for (i=0; i< size; i+=16)
772         {
773                         p1 = (MdInt *)&Input[i];
774                         p2 = p1;
776                         L0 = *p1++;
777                         L1 = *p1++;
778                         L2 = *p1++;
779                         L3 = *p1++;
780                         R0 = *p1++;
781                         R1 = *p1++;
782                         R2 = *p1++;
783                         R3 = *p1++;
785                         *p2++ = L0;
786                         *p2++ = R0;
787                         *p2++ = L1;
788                         *p2++ = R1;
789                         *p2++ = L2;
790                         *p2++ = R2;
791                         *p2++ = L3;
792                         *p2++ = R3;
794         }
796         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (xdc_IArg)Input, p1, p2);
798         return;
801 Int SAP_reclaim (DEV2_Handle device)
803     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
804 #ifdef SAP_CACHE_SUPPORT
805     DEV2_Frame *pFrame;
806 #endif
808     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
810     // must be running and  error free 
811     if ((!pDevExt->runState) || (pDevExt->errorState))
812     {
813         //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
814         return SIO2_EBADIO;
815     }
817     // idle if necessary
818         if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
819                 Log_info1("SAP_reclaim: PAF_SIO_ERROR_FATAL,  Before Idle for device 0x%x  ", device->mode);
820             DEV2_idle (device, 1);
821             return SIO2_EBADIO;
822         }
824        // Log_info0("SAP_reclaim: Before SEM Pend");
826     // wait for ISR to signal block completion
827     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
828     if (!Semaphore_pend(pDevExt->sync, device->timeout))
829     {
830         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
831         return SIO2_ETIMEOUT;
832     }
833     //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
835 #if 1
836     // return error (owner must idle)
837     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
838     {
839         DEV2_idle (device, 1);
840         //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
841         return PAF_SIO_ERROR_FATAL;
842     }
843 #endif
845 #ifdef SAP_CACHE_SUPPORT
846     // invalidate CACHE region if input -- use clean since
847     //    Dont clean if was for fill.
848     // since pend returned we know that head of fromdevice is valid
849     pFrame = Queue_head (device->fromdevice);
850     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
851     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
852     {
853         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
854         {
855             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
856             Cache_wait();
858             // max HWI disable duration ~1ms observed
859             //unsigned int key = Hwi_disable ();                    // GJ: Revisit, along with other context protections here.
860             swapHdmi(pFrame->addr, pFrame->size);
861             //Hwi_restore(key);
863             Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
864             Cache_wait();
865         }
866     }
868 #endif
869     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
870         SW_BREAKPOINT; */
872     Log_info1("SAP_reclaim: Exiting with SIO2_OK for device 0x%x  ", device->mode);
873     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
874     return SIO2_OK;
875 } // SAP_reclaim
878 // -----------------------------------------------------------------------------
880 Int SAP_open (DEV2_Handle device, String name)
882     SAP_DeviceExtension   *pDevExt;
883     DEV2_Device            *entry;
884     Int                    oldMask, result;
885     Error_Block                         eb;
886     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
888     // check SIO mode 
889     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
890         return SIO2_EMODE;
892     // allocate memory for device extension
893     device->object = NULL;
894     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
895     if (pDevExt == NULL)
896     {
897         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
898         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
899         asm( " SWBP 0" );  // SW Breakpoint
900         return SIO2_EALLOC;
901     }
902     device->object = (Ptr)pDevExt;
904     // inits
905     pDevExt->device = device;
906     pDevExt->sync = NULL;
907     pDevExt->pParams = NULL;
908     pDevExt->runState = 0;  // not yet started
909     pDevExt->errorState = PAF_SIO_ERROR_NONE;
910     pDevExt->shutDown = 1;
911     pDevExt->numQueued = 0;
912     pDevExt->activeEdma = EDMA_HINV;
913     pDevExt->errorEdma = EDMA_HINV;
914     pDevExt->firstTCC = 0;
915     pDevExt->optLevel = 0;
916     pDevExt->numParamSetup = 0;
917     pDevExt->numEdmaParams = 4;
919     // use dev match to fetch function table pointer for SAP
920     DEV2_match(SAP_NAME, &entry);
921     if (entry == NULL) {
922         Log_error1("SAP", SIO2_ENODEV);
923         return SIO2_ENODEV;
924     }
925     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
927     // create semaphore for device
928     pDevExt->sync = Semaphore_create (0, NULL, NULL);
929     if (pDevExt->sync == NULL)
930     {
931         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
932         return SIO2_EALLOC;
933     }
935     // queue inits
936     Queue_construct (&pDevExt->xferQue, NULL);
937     Queue_construct (&pDevExt->paramQue, NULL);
939     // update driver global (need to protect context)
940     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
941     {
942         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
943             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
944         SW_BREAKPOINT;
945     }
946     oldMask = Hwi_disable ();
947     sapDrv.device[sapDrv.numDevices] = device;
948     pDevExt->deviceNum = sapDrv.numDevices++;
949     Hwi_restore (oldMask);
951     // PORT init
952     result = SAP_PORT_FTABLE_open (device);
953     if (result)
954     {
955         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
956         return result;
957     }
959     return result;
960 } // SAP_open
962 // -----------------------------------------------------------------------------
964 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
966     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
967     Int                  result, Que_num, i;
968     EDMA3_DRV_Result     edmaResult;
969     Uint32                                      reqTcc;
970     EDMA3_DRV_Handle    hEdma;
971     Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
973     // cannot configure if transfer started
974     if (pDevExt->runState == 1)
975         return SIO2_EBADIO;
977     // save pointer to config structure in device extension. here so that
978     //   forthcoming functions can use/modify config structure.
979     pDevExt->pParams = pParams;
980     pDevExt->edmaWordSize = pParams->sio.wordSize;
982     // allocate Port resources.
983     //    This must come before DMA configuration
984     result = SAP_PORT_FTABLE_alloc (device);
985     if (result)
986     {
987         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
988         return result;
989     }
991     // .............................................................................
992     // EDMA configuration
994     // DA10x McASP0 Specific
995     if (pParams->sio.moduleNum == 0)
996     {
997         hEdma = hEdma0;
998         if (device->mode == DEV2_INPUT)
999         {
1000                 Que_num = 0;
1001                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
1002         }
1003         else
1004         {
1005                 Que_num = 1;
1006                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
1007         }
1008     }
1009     // DA10x McASP1 Specific
1010     else if (pParams->sio.moduleNum == 1)
1011     {
1012         hEdma = hEdma1;
1013         if (device->mode == DEV2_INPUT)
1014                 {
1015                 Que_num = 0;
1016                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
1017                 }
1018                 else
1019                 {
1020                         Que_num = 1;
1021                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
1022                 }
1023     }
1024     // DA10x McASP2 Specific
1025     else if (pParams->sio.moduleNum == 2)
1026     {
1027         hEdma = hEdma1;
1028         if (device->mode == DEV2_INPUT)
1029                 {
1030                         Que_num = 0;
1031                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1032                 }
1033                 else
1034                 {
1035                         Que_num = 1;
1036                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1037                 }
1038     }
1041     for (i=0; i < pDevExt->numEdmaParams; i++) {
1043         reqTcc = EDMA3_DRV_TCC_ANY;
1044         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1045         edmaResult = EDMA3_DRV_requestChannel (
1046                 hEdma,
1047             &pDevExt->edmaParams[i].hEdmaParam,
1048             &reqTcc,
1049             (EDMA3_RM_EventQueue) Que_num,
1050             SAP_isrCallback,
1051             (void *) device);
1053         if (edmaResult != EDMA3_DRV_SOK)
1054             return SIO2_EALLOC;
1056         //not running => can use non-atomic functions
1057         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1059     }
1061     reqTcc = EDMA3_DRV_TCC_ANY;
1062         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1063         edmaResult = EDMA3_DRV_requestChannel (
1064             hEdma,
1065             &pDevExt->errorEdma,
1066             &reqTcc,
1067             (EDMA3_RM_EventQueue)Que_num,
1068             SAP_isrCallback,
1069             (void *) device);
1070         if (edmaResult != EDMA3_DRV_SOK)
1071             return SIO2_EALLOC;
1073         // allocate edma channel -- also disable and clear the interrupt
1076         pDevExt->firstTCC = pDevExt->activeEdma ;
1077         edmaResult = EDMA3_DRV_requestChannel (
1078                 hEdma,
1079                 &pDevExt->activeEdma,
1080                 &pDevExt->firstTCC,
1081                 (EDMA3_RM_EventQueue) 0,
1082                 SAP_isrCallback,
1083                 (void *) device);
1084         if (edmaResult != EDMA3_DRV_SOK)
1085                     {
1086                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1087                         return SIO2_EALLOC;
1088                     }
1090         // Configure error transfer
1091         //   make cnt same as # of channels in order to maintain alignment
1092         //   and the error transfer small so that we never have to wait
1093         //   long for it to complete and trigger a linked transfer. This is
1094         //   important for establishing output timing when we are idling with
1095         //   clocks still running. Is fine for Rx as well.
1096         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1098         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1100     return SIO2_OK;
1101 } // SAP_config
1103 // -----------------------------------------------------------------------------
1105 Int SAP_shutdown (DEV2_Handle device)
1107     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1108     SIO2_Handle stream = (SIO2_Handle) device;
1109     DEV2_Frame *pFrame;
1110     Int i;
1111     EDMA3_DRV_Handle hEdma;
1112     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1114     if (pDevExt->shutDown)
1115         return SIO2_EBADIO;
1117     if (pDevExt->pParams == NULL)
1118         return SIO2_EINVAL;
1120     if (pDevExt->pParams->sio.moduleNum == 0)
1121         hEdma = hEdma0;
1122     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1123         hEdma = hEdma1;
1124     if (pDevExt->activeEdma != EDMA_HINV)
1125         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1127     // reset queues
1128     while (!Queue_empty(device->todevice)) {
1129        // place oustanding requests onto holding queue
1130        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1131        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1132     }
1134     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1135         // pull frame from holding queue and place on user queue
1136         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1137         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1138     }
1141     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1142         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1144     // not running => can use non-atomic functions
1145     for (i=0; i < pDevExt->numEdmaParams; i++)
1146         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1148     // reset counter
1149     pDevExt->numQueued = 0;
1151     //DJDBG_SAP_EDMA_dumpParams(1);
1152     // make sure active is linked to error
1153         EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1155     // think this is better (from SIO_idle for standard model )
1156     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1157     while (!Queue_empty(device->fromdevice)) {
1158         /* place oustanding requests onto holding queue */
1159         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1160         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1161     }
1162     Semaphore_reset (pDevExt->sync, 0);
1163     
1164     pDevExt->shutDown = 1;
1165     pDevExt->numParamSetup = 0;
1166     
1167     /*result = SAP_DMA_FTABLE_unlock (device);
1168     if (result)
1169     {
1170         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1171         return result;
1172     } */
1174     return SIO2_OK;
1175 } // SAP_shutdown
1177 // -----------------------------------------------------------------------------
1178 int gSapWatchDogThrottle = 0; //DJDBG
1179 int gSapWatchDogIn =0;
1180 int gSapWatchDogOut = 0;
1181 int gSapWatchDogInSemPost = 0;
1182 int gSapWatchDogOutSemPost = 0;
1184 Void SAP_watchDog (Void)
1186     DEV2_Handle device;
1187     SAP_DeviceExtension *pDevExt;
1188     int i, oldMask, result;
1190     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1192     // do nothing if SAP_init not yet called
1193     if (!SAP_initialized)
1194     {
1195         Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1196         return;
1197     }
1199     // protect context
1200     Task_disable (); // needed since we may call SEM_post
1201     //oldMask = Hwi_disable ();
1204     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1206     for (i=0; i < sapDrv.numDevices; i++) {
1207         device  = sapDrv.device[i];
1209         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1211         pDevExt = (SAP_DeviceExtension *) device->object;
1213         // do nothing if not running
1214         if (!pDevExt->runState)
1215             continue;
1217         // call board specific watchdog
1218         // TODO: handle return value
1219         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1220         
1221         // if port layer returns error then must need to clean up
1222         result = SAP_PORT_FTABLE_watchDog (device);
1223         if (result) {
1224             // set errorState which will force owner thread
1225             //   to clean up via SIO_idle()
1226             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1227             if(device->mode == DEV2_INPUT)
1228                 gSapWatchDogIn++;
1229             else
1230                 gSapWatchDogOut++;
1232             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1233            /* if(gSapWatchDogThrottle == 0) //DJDBG
1234             {
1235                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1236             }
1237             gSapWatchDogThrottle ++;
1238             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1239             // if outstanding pend then post to free owner thead
1240             if (!Semaphore_pend(pDevExt->sync, 0))
1241             {
1242                 if(device->mode == DEV2_INPUT)
1243                         gSapWatchDogInSemPost++;
1244                 else
1245                         gSapWatchDogOutSemPost++;
1246                 Semaphore_post (pDevExt->sync);
1247             }
1248         }
1249     }
1252     // renable interrupts and task manager.
1253     // If we posted to the semaphore then the TSK_enable call will lead to
1254     // an immediate task switch to the associated audio thread.
1255     //Hwi_restore (oldMask);
1256     Task_enable ();
1258 } // SAP_watchDog
1260 // -----------------------------------------------------------------------------
1261 // Assumes that EDMA3 dispatcher handles TCC clearing.
1263 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1265     DEV2_Handle                 device;
1266     SAP_DeviceExtension       *pDevExt;
1267     DEV2_Frame                 *pFrame;
1268     unsigned int               opt;
1269     EDMA3_DRV_Handle                    hEdma;
1271     // could be here after Tx idle/overrun and this is the interrupt
1272     // for the last occuring error transfer so there is no transfer
1273     // to release, we just clear the int and exit.
1275     device = (DEV2_Handle) context;
1276     pDevExt = (SAP_DeviceExtension *)(device->object);
1277     //if (pDevExt->pParams == NULL)
1278         //return SIO2_EINVAL;
1280     if (pDevExt->pParams->sio.moduleNum == 0)
1281         hEdma = hEdma0;
1282     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1283         hEdma = hEdma1;
1285     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1286         // if here then an interrupt occured due to errorEdma or valid
1287         // transfer, we assume the xfer is long enough so it will not complete
1288         // before we are finished here.
1290         // if last transfer was valid then complete it
1291         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1293             // pull frame from holding queue
1294             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1296             // if used param entry then return it to queue
1297             if (pFrame->misc != NULL)
1298             {
1299                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1300                 if (device->mode == 1)
1301                         gisrOutput+=100;
1302             }
1304             // decrement count
1305             pDevExt->numQueued -= 1;
1306             //gIsrCnt++;
1307             if (device->mode == 1)
1308                 gIsrOutputCnt++;
1309             else
1310                 gIsrInputCnt++;
1311             // place frame onto user queue and signal user thread
1312             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1314             //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1315             // signal user thread
1316             Semaphore_post (pDevExt->sync);
1317 #if 0
1318             if(gIsrCnt > 10) { //DJDBG
1319                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1321             }
1322 #endif
1323         }
1324         else
1325                 gIsrElseCnt++;
1327         // determine if currently transferring buffer is valid based on interrupt enable bit
1328         // only valid transfers will generate interrupts
1329         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1331         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1332         {
1333                 if (device->mode == 1)
1334                         gIsrOutErrCnt++;
1335                 else
1336                         gIsrInErrCnt++;
1337                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1338         }
1340     } // runState
1341     else
1342     {
1343                 if (pDevExt->runState != 1)
1344                         gIsrRunCnt++;
1345                 else
1346                         gIsrNotRunCnt++;
1347     }
1349     return;
1350 } //SAP_isrCallback
1352 // -----------------------------------------------------------------------------
1354 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1356     EDMA3_DRV_Handle            hEdma;
1357     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1358 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1360         if (pDevExt->pParams == NULL)
1361                 return SIO2_EINVAL;
1363             if (pDevExt->pParams->sio.moduleNum == 0)
1364                 hEdma = hEdma0;
1365             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1366                 hEdma = hEdma1;
1368     // TODO: shouldn't this just be tcc interrupt disable?
1369     // at least until linkage phase...
1370     unsigned int key = Hwi_disable (); //DJDBG
1372     if(targetEdma == NULL)
1373     {
1374         Log_info0("targetEdma is NULL");
1375     }
1376     // configure transfer
1377     if(pFrame->addr == NULL) //DJDBG
1378     {
1379         Log_info0("pFrame has NULL address?");
1380     }
1381     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1383     if (parentEdma != EDMA_HINV)
1384         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1387     Hwi_restore (key); //DJDBG
1389     return SIO2_OK;
1390 } // SAP_setupXfer
1392 // -----------------------------------------------------------------------------
1393 // Configure EDMA3 parameter entry
1395 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1397     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1398     EDMA3_DRV_Handle            hEdma;
1399     EDMA3_DRV_PaRAMRegs  edmaConfig;
1401     if (pDevExt->pParams == NULL)
1402                 return SIO2_EINVAL;
1404         if (pDevExt->pParams->sio.moduleNum == 0)
1405                 hEdma = hEdma0;
1406         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1407                 hEdma = hEdma1;
1408     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1409    // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1411    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1413     // Init opt parameter to 0 which, without being overriden, configures as:
1414     //    A synchronized transfer (no FIFO mode on src or dst)
1415     //    no chaining or intermediate interrupts
1416     //    param is not static
1417     //    normal completion
1418     //    don't generate an interrupt (overriden below for regular xfers)
1419     edmaConfig.opt = 0;
1421     // not transferring blocks so c index is 0
1422     edmaConfig.destCIdx = 0;
1423     edmaConfig.srcCIdx = 0;
1425     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1426     if (device->mode == DEV2_OUTPUT) {
1427       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1428       edmaConfig.opt |= 2;
1429     }
1430     else {
1431         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1432         edmaConfig.opt |= 1;
1433     }
1435     // if regular transfer then enable interrupt with tcc code
1436     if (targetEdma != pDevExt->errorEdma) {
1437         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1438         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1439         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1440     }
1443     edmaConfig.aCnt = 4;
1444         edmaConfig.bCnt = pDevExt->numSers;
1445         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1446     edmaConfig.bCntReload = edmaConfig.bCnt;
1449     // handle direction specific requirements
1450     if (device->mode == DEV2_INPUT) {
1451         edmaConfig.srcBIdx  = 0;
1452                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1454         if (addr) {
1455             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1456             edmaConfig.destAddr = addr;
1457             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1458             if(pDevExt->edmaWordSize == 2)
1459                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1460         }
1461         else {
1462                 //if(pDevExt->edmaWordSize == 2)
1463                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1464             edmaConfig.destBIdx = 0;
1465             edmaConfig.destAddr = (unsigned int) &sap_OVER_4LANE;
1466             edmaConfig.cCnt = 1;
1467         }
1468     }
1469     else {
1470         edmaConfig.destBIdx = 0;
1471         edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1472         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1473         if (addr) {
1474             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1475             edmaConfig.srcAddr  = addr;
1476             //Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1477         }
1478         else {
1479             edmaConfig.srcBIdx  = 0;
1480             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1481 #if 1
1482             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1483             edmaConfig.cCnt = SAP_UNDER_LEN; //DJDBG, if underrun have frame of silence
1484 #endif
1485         }
1486     }
1487     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1488     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1490     Log_info5("SAP: Inside SAP_EDMA_setupParam with size=0x%x, targetEdma = 0x%x, CCNT = %d with dest-addr: 0x%x and OPT=0x%x", size, targetEdma, edmaConfig.cCnt, edmaConfig.destAddr, edmaConfig.opt);
1491     Log_info5("SAP: Inside SAP_EDMA_setupParam with aCnt=0x%x, bCnt = 0x%x, destBIdx = 0x%x destCIdx: 0x%x and bCntReload=0x%x", edmaConfig.aCnt, edmaConfig.bCnt, edmaConfig.destBIdx, edmaConfig.destCIdx, edmaConfig.bCntReload);
1493     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1495     // link child xfer
1496     if (childEdma != EDMA_HINV)
1497         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1499     return SIO2_OK;
1500 } //SAP_setupParam