PASDK-183: merged latest framework updates.
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sap.c
2 /*
3 Copyright (c) 2016, 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 TEST_MULTICHANNEL
102 #define SAP_UNDER_LEN 8
104 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
105 int sap_OVER_1LANE = 0;     // used for overrun
106 int sap_OVER_4LANE[4] = {0,0,0,0};      // used for overrun
108 #ifdef DEBUG
109 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
111         //unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
112         //unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
113         unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
114         unsigned int *ptrPARAM0x41 = (unsigned int *)0x027048A0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
115         unsigned int *ptrPARAM0x42 = (unsigned int *)0x027048C0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
116         unsigned int *ptrPARAM0x43 = (unsigned int *)0x027048E0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
117         unsigned int *ptrPARAM0x44 = (unsigned int *)0x02704910; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
119         //Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
120         //Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
122         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));
123         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]);
124         Log_info4("PARAM0x19b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
126         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));
127         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]);
128         Log_info4("PARAM0x41b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x41[5], ptrPARAM0x41[6], ptrPARAM0x41[7]);
130         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));
131         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]);
132         Log_info4("PARAM0x42b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x42[5], ptrPARAM0x42[6], ptrPARAM0x42[7]);
134         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));
135         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]);
136         Log_info4("PARAM0x43b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x43[5], ptrPARAM0x43[6], ptrPARAM0x43[7]);
138         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));
139         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]);
140         Log_info4("PARAM0x44b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x44[5], ptrPARAM0x44[6], ptrPARAM0x44[7]);
141     //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
143 #endif
144 // .............................................................................
145 // notes:
146 //  . add control function to PORT table
147 //  . how to handle DMA/PORT specifics in parameter entries
148 //      can assume numSers = numChans is general and can be applied by DMA
149 //      same for wordSize?
150 //  . why are two idle stages needed (seems like 1 is enough)?
152 // .............................................................................
153 // only one global variable, not static so that DMA and port functions
154 // can access. We cant just store the address in devExt since the ISR has
155 // no context.
157 SAP_DriverObject sapDrv;
159 // needed since SAP_watchDog is called before SAP_init
160 Int SAP_initialized = 0;
162 //Int  SAP_close(DEV2_Handle);
163 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
164 Int  SAP_idle(DEV2_Handle, Bool);
165 Int  SAP_issue(DEV2_Handle);
166 Int  SAP_open(DEV2_Handle, String);
167 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
168 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
169 Int  SAP_reclaim(DEV2_Handle);
170 Int  SAP_shutdown(DEV2_Handle);
171 Int  SAP_start(DEV2_Handle);
172 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
173 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size);
174 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
176 // .............................................................................
178 // .............................................................................
180 SAP_DMA_Fxns SAP_EDMA_FXNS =
182         SAP_EDMA_setupParam,
183         SAP_EDMA_setupXfer,
184 };
187 SAP_Fxns SAP_FXNS =
189     NULL, //SAP_close, -- remove for IROM since not using
190     SAP_ctrl,
191     SAP_idle,
192     SAP_issue,
193     SAP_open,
194     NULL, //SAP_ready, -- remove for IROM since not using
195     SAP_reclaim,
196     SAP_shutdown,
197     SAP_start,
198     SAP_config,
200 #ifdef SAP_PORT_MCASP
201     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
202 #endif
203 #ifdef SAP_DMA_EDMA
204     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
205 #endif
206 };
208 // -----------------------------------------------------------------------------
209 // This function is not in the driver function table.
210 // Must be pointed at in GUI config tool.
211 //
212 Void SAP_init (Void)
214     DEV2_Device  *entry;
215     SAP_Fxns    *pFxns;
217     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
219     // find function table pointer (used by SAP_XX_FTABLE_init macros)
220     DEV2_match(SAP_NAME, &entry);
221     if (entry == NULL) {
222         Log_error1 ("SAP", SIO2_ENODEV);
223         return;
224     }
225     pFxns = (SAP_Fxns *) entry->fxns;
227     //SAP_DMA_FTABLE_init ();
228     SAP_PORT_FTABLE_init ();
230     sapDrv.numDevices = 0;
231     SAP_initialized = 1;
233     return;
234 } // SAP_init
236 // -----------------------------------------------------------------------------
238 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
240     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
241     const SAP_Params *pParams;
242     Int i, result = SIO2_OK;
243     EDMA3_DRV_Handle    hEdma;
244     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
246     switch (code) {
248 /* .......................................................................... */
250         case PAF_SIO_CONTROL_MUTE:
251         case PAF_SIO_CONTROL_UNMUTE:
252             pParams = pDevExt->pParams;
253             if (pParams == NULL)
254                 return SIO2_OK;
256             if (pParams->sio.control != NULL)
257                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
258             break;
260 /* .......................................................................... */
262         case PAF_SIO_CONTROL_OPEN:
263             if (pDevExt->runState)
264                 return SIO2_EBUSY;
266             if (!( pParams = (const SAP_Params *) arg ))
267                 return SIO2_OK;
269             if (result = SAP_FTABLE_config (device, pParams))
270                 return result;
272             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
273                 return result;
275             break;
277 /* .......................................................................... */
279         case PAF_SIO_CONTROL_CLOSE:
280             if (pDevExt->runState)
281                 return SIO2_EBUSY;
283             if (pDevExt->pParams == NULL)
284                                 return SIO2_EINVAL;
286             pParams = pDevExt->pParams;
288                         if (pParams->sio.moduleNum == 0)
289                                 hEdma = hEdma0;
290                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
291                                 hEdma = hEdma1;
293             if (pDevExt->activeEdma != EDMA_HINV) {
294                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
295                                 pDevExt->activeEdma = EDMA_HINV;
296                         }
298             for (i=0; i < pDevExt->numEdmaParams; i++) {
299                 if (pDevExt->edmaParams[i].hEdmaParam != EDMA_HINV)
300                 {
301                         EDMA3_DRV_freeChannel (hEdma, pDevExt->edmaParams[i].hEdmaParam);
302                         pDevExt->edmaParams[i].hEdmaParam = EDMA_HINV;
303                 }
304             }
306             if (pDevExt->errorEdma != EDMA_HINV) {
307                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->errorEdma);
308                                 pDevExt->errorEdma = EDMA_HINV;
309                         }
311             if (!(pParams = pDevExt->pParams))
312                 return SIO2_OK;
314             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
315                 return result;
317             result = SAP_PORT_FTABLE_close (device);
318             if (result)
319                 return result;
321             pDevExt->pParams = NULL;
322             break;
324 /* .......................................................................... */
326         case PAF_SIO_CONTROL_GET_WORDSIZE:
327                 if (!arg)
328                                 return SIO2_EINVAL;
329                         *((int *) arg) = pDevExt->edmaWordSize;
330             break;
332         case PAF_SIO_CONTROL_SET_WORDSIZE:
333             // defer to DMA processing
334                 // currently only supported for input
335                         if (device->mode != DEV2_INPUT)
336                                 return SIO2_EINVAL;
338                         // can't be running
339                         if (pDevExt->runState)
340                                 return SIO2_EBUSY;
342                         // driver only supports 2 or 4 bytes
343                    if ((arg != 2) && (arg != 4))
344                                 return SIO2_EINVAL;
346                         // return success for unconfigured devices?
347                         if (!pDevExt->pParams)
348                                 return SIO2_OK;
350                         // ask platform if size is supported
351                         pParams = pDevExt->pParams;
352                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
353                                 return result;
355                         pDevExt->edmaWordSize = arg;
356                         break;
358         case PAF_SIO_CONTROL_GET_PRECISION:
359             if (arg == 0)
360                 return SIO2_EINVAL;
362             pParams = pDevExt->pParams;
363             if (pParams == NULL)
364                 return( SIO2_EINVAL );
366             *((int *) arg) = pParams->sio.precision;
367             break;
369         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
370             if (arg == 0)
371                 return SIO2_EINVAL;
373             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
374             break;
376         case PAF_SIO_CONTROL_SET_RATEX:
377             pParams = pDevExt->pParams;
378             if (pParams == NULL)
379                 return SIO2_OK ;
381             if (pParams->sio.control == NULL)
382                 return SIO2_EINVAL;
384             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
385             break;
387 /* .......................................................................... */
389         case PAF_SIO_CONTROL_IDLE:
390             pParams = pDevExt->pParams;
391             if (pParams == NULL)
392                 return SIO2_OK ;
394             if (pParams->sio.control == NULL)
395                 return SIO2_EINVAL;
397             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
398             break;
400         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
401             // 1. Here we are intentionally not using SIO_Idle() and
402             //    leaving the Tx clock running. We need this to avoid DAC noise,
403             //    as well as provide a DIT clock when using digital output.
404             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
405                 return SIO2_EINVAL;
407             pParams = pDevExt->pParams;
409             if (pParams->sio.moduleNum == 0)
410                 hEdma = hEdma0;
411             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
412                                 hEdma = hEdma1;
414             result = SAP_FTABLE_shutdown (device);
415             if (result)
416                 return result;
418             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
419             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
421 #if 1
422             //DJDBG, if below enableTransfer() is commented, input side continuous working.
423      if (pDevExt->activeEdma != EDMA_HINV) {
424                 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
425             //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
426             EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
427      }
428 #endif
429             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
431             break;
433 /* .......................................................................... */
435         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
436             // needs to be attached
437             pParams = pDevExt->pParams;
438             if (pParams == NULL)
439                 return SIO2_OK;
441             if (pParams->sio.control == NULL)
442                 return SIO2_EINVAL;
444             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
445             break;
447         case PAF_SIO_CONTROL_WATCHDOG:
448             pParams = pDevExt->pParams;
449             if (pParams == NULL)
450                 return SIO2_OK;
451             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
452                 return result;
453             break;
454             
455 /* .......................................................................... */
457         // Timing stats specific to DMA engine
458         case PAF_SIO_CONTROL_ENABLE_STATS:
459         case PAF_SIO_CONTROL_DISABLE_STATS:
460         case PAF_SIO_CONTROL_GET_STATS:
461         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
462         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
463             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
464             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
465             break;
467 /* .......................................................................... */
469         case PAF_SIO_CONTROL_SET_DITSTATUS:
470             if(device->mode == DEV2_OUTPUT)
471             {
472                 const SAP_Params *pParams = pDevExt->pParams;
473                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
474                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
475                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
476                 int encSelect = *((int *) arg);
478                 // HACK -- determine DIT need by FXWID
479                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
480                 {
481                     if ( (encSelect == 0x13) ||
482                          (encSelect == 0xa)  || 
483                          (encSelect == 0x6)) // DTE, DDE, MPE 
484                     {
485                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
486                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
487                     }
488                     else
489                     {
490                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
491                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
492                     }
493                 }
495                 pParams = pDevExt->pParams;
496                 if (pParams == NULL)
497                     return SIO2_OK;
499                 if (pParams->sio.control != NULL)
500                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
501             }
502             break;
504 /* .......................................................................... */
506     }
508     return result;
509 } // SAP_ctrl
511 int gSAPIdleShutdownIn=0;
512 int gSAPIdleShutdownOut=0;
514 // -----------------------------------------------------------------------------
516 Int SAP_idle (DEV2_Handle device, Bool flush)
518     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
519     Int result = SIO2_OK;
520     EDMA3_DRV_Handle hEdma;
522     // do nothing if already idled or unattached
523     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
524         return result;
526         if (pDevExt->pParams->sio.moduleNum == 0)
527                 hEdma = hEdma0;
528         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
529                 hEdma = hEdma1;
531     // reset serial port -- stop generating sync events
532     result = SAP_PORT_FTABLE_reset (device);
533     if(device->mode == DEV2_OUTPUT)
534         gSAPResetOut++;
535     else
536         gSAPResetIn++;
537     if (result)
538     {
539         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
540         return result;
541     }
543     pDevExt->shutDown = 0; // force shutdown to run
544     result = SAP_FTABLE_shutdown (device);
545     if(device->mode == DEV2_OUTPUT)
546         gSAPIdleShutdownOut++;
547     else
548         gSAPIdleShutdownIn++;
550     if (result)
551     {
552         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
553         return result;
554     }
556     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
558     // disable interrupts and EDMA servicing
559    if (pDevExt->activeEdma != EDMA_HINV)
560            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
562     pDevExt->numQueued = 0;
564     // signal stopped
565     pDevExt->runState = 0;
567     // reset errorState
568     pDevExt->errorState = PAF_SIO_ERROR_NONE;
569     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
571     // place call to physical device
572     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
573         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
575     return result;
576 } // SAP_idle
578 // -----------------------------------------------------------------------------
580 Int SAP_start (DEV2_Handle device)
582     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
583     DEV2_Frame *pFrame;
584     int result;
585     EDMA3_DRV_Handle hEdma;
587     //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
589     // signal we have started
590     //    we change the state here since we have already moved a frame from the 
591     //    todevice queue to the xferQue. If an error occurs during one of the 
592     //    following resets/enables then we need to have runState !=0 in order
593     //    for SAP_idle to properly cleanup. Moreover, the following resets/enables
594     //    do not (and are now required not to) depend on runState being 0.
595     //pDevExt->runState = 1;
596     // Assume todevice queue is not empty -- how else could we be here?
597     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
599     // inidicate this xfer did not use param entry - just the active one
600     pFrame->misc = NULL;
601     if (pDevExt->pParams->sio.moduleNum == 0)
602         hEdma = hEdma0;
603     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
604                 hEdma = hEdma1;
606     // non-atomic functions since not running yet.
607     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
609     // initialize count
610     pDevExt->numQueued = 1;
612     result = SAP_PORT_FTABLE_reset (device);
613     if (result)
614     {
615         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
616         return result;
617     }
619     // enable DMA processing
621     // config active xfer for this buffer
622     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
624     //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
625       //              __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
626         // signal we have started -- this must come before last enable to prevent a race
627         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
628         // and completes before any further instructions in this thread are executed.
629         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
630         // will be serviced and generate an interrupt even before the McASP is enabled.
631         pDevExt->runState = 1;
632         pDevExt->shutDown = 0;
633         Log_info1 ("SAP: %d, SAP_start runState=1 & ENABLE TRANSFERS", __LINE__);
634         // enable interrupts and event servicing for this channel
635         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
637     // enable peripheral
638     result = SAP_PORT_FTABLE_enable (device);
640     if (result)
641     {
642         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
643         return result;
644     }
646     return SIO2_OK;
647 } // SAP_start
649 int gDmaParamsarray[17][3];
650 int gDmaParamsidx=0, gSAPSpecialCase=0;
651 // -----------------------------------------------------------------------------
653 Int SAP_issue (DEV2_Handle device)
655     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
656     DEV2_Frame *pFrame;
657     Int result;
658     SAP_EDMA_Param *pParam;
659     XDAS_UInt32 parentEdma;
661     //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
663     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
664     {
665         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
666             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
667         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
668                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
669         return SIO2_EBADIO;
670     }
672     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
673         {
674                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
675             return SIO2_EBADIO;
676         }
678     // if not yet running then configure active xfer and start
679     if (pDevExt->runState == 0)
680         return (SAP_FTABLE_start(device));
682     // .........................................................................
683     // here if running
685     // disable device interrupts
686     // TODO: is there an API to just disable the IER bit for this tcc?
687     unsigned int key = Hwi_disable ();
688        /* determine parent EDMA
689           if no xfers in queue and we are running then must be in the
690           error state so link to active channel otherwise link to last
691           transfer queued.
692        */
694        /* here we assume after Tx SIO_idle or overrun, the user
695           will issue, at least, back-to-back issue requests so
696           there should be no problem here.
697        */
698        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
699            parentEdma = pDevExt->activeEdma;
700        else {
701            // if here then xferQue has more than one element so ok to use tail
702            // last scheduled transfer must be queue->prev
703            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
704            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
705        }
707     // get frame and parameter table to use; ints off => non-atomic OK
708     //     dont need to check for empty queues since were here then todevice
709     //     must have a frame placed there by the SIO_issue layer.
710     //     paramQue must be valid since it is accessed the same as todevice.
711     //     (indirectly -- isr places used items onto paramQue and fromdevice que
712     //      at the same time)
713     // set misc argument to pParam so get enqueue later
714     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
715     pFrame = Queue_dequeue (device->todevice);
716     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
718     if (pParam->hEdmaParam == NULL)
719         Log_info0("SAP_issue: hEdma value is NULL");
720     // set misc argument to pParam so get enqueue later
721     pFrame->misc = (Arg) pParam;
723     // place on holder queue, ints off => non-atomic OK
724     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
725     if (pFrame->addr) {
726                 if (device->mode == DEV2_INPUT)
727                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
728                 else
729                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
730         }
732     // increment count
733     pDevExt->numQueued += 1;
735     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
736     Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
737                     __LINE__, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma);
739     /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
740         {
741         gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
742                 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
743                 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
744         } */
746         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
747                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
749         pDevExt->shutDown = 0;
751     // special case enables when not yet started
752     if (pDevExt->runState == 0) {
753         gSAPSpecialCase++;
754         result = SAP_FTABLE_start (device);
755         if (result) {
756             //SAP_DMA_FTABLE_unlock (device);
757                   Hwi_restore (key);
758             return result;
759         }
760     }
761     Hwi_restore (key); //DJDBG
763     return result;
764 } // SAP_issue
766 // -----------------------------------------------------------------------------
768 void swapHdmi(Ptr Input, int size)
771         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
772         MdInt *p1, *p2;
773         int i=0;
775         for (i=0; i< size; i+=16)
776         {
777                         p1 = (MdInt *)&Input[i];
778                         p2 = p1;
780                         L0 = *p1++;
781                         L1 = *p1++;
782                         L2 = *p1++;
783                         L3 = *p1++;
784                         R0 = *p1++;
785                         R1 = *p1++;
786                         R2 = *p1++;
787                         R3 = *p1++;
789                         *p2++ = L0;
790                         *p2++ = R0;
791                         *p2++ = L1;
792                         *p2++ = R1;
793                         *p2++ = L2;
794                         *p2++ = R2;
795                         *p2++ = L3;
796                         *p2++ = R3;
798         }
800         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (xdc_IArg)Input, p1, p2);
802         return;
805 Int SAP_reclaim (DEV2_Handle device)
807     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
808 #ifdef SAP_CACHE_SUPPORT
809     DEV2_Frame *pFrame;
810 #endif
812     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
814     // must be running and  error free 
815     if ((!pDevExt->runState) || (pDevExt->errorState))
816     {
817         //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
818         return SIO2_EBADIO;
819     }
821     // idle if necessary
822         if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
823                 Log_info1("SAP_reclaim: PAF_SIO_ERROR_FATAL,  Before Idle for device 0x%x  ", device->mode);
824             DEV2_idle (device, 1);
825             return SIO2_EBADIO;
826         }
828        // Log_info0("SAP_reclaim: Before SEM Pend");
830     // wait for ISR to signal block completion
831     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
832     if (!Semaphore_pend(pDevExt->sync, device->timeout))
833     {
834         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
835         return SIO2_ETIMEOUT;
836     }
837     //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
839 #if 1
840     // return error (owner must idle)
841     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
842     {
843         DEV2_idle (device, 1);
844         //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
845         return PAF_SIO_ERROR_FATAL;
846     }
847 #endif
849 #ifdef SAP_CACHE_SUPPORT
850     // invalidate CACHE region if input -- use clean since
851     //    Dont clean if was for fill.
852     // since pend returned we know that head of fromdevice is valid
853     pFrame = Queue_head (device->fromdevice);
854     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
855     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
856     {
857         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
858         {
859             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
860             Cache_wait();
862             // max HWI disable duration ~1ms observed
863             //unsigned int key = Hwi_disable ();                    // GJ: Revisit, along with other context protections here.
864             swapHdmi(pFrame->addr, pFrame->size);
865             //Hwi_restore(key);
867             Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
868             Cache_wait();
869         }
870     }
872 #endif
873     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
874         SW_BREAKPOINT; */
876     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
877     return SIO2_OK;
878 } // SAP_reclaim
881 // -----------------------------------------------------------------------------
883 Int SAP_open (DEV2_Handle device, String name)
885     SAP_DeviceExtension   *pDevExt;
886     DEV2_Device            *entry;
887     Int                    oldMask, result;
888     Error_Block                         eb;
889     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
891     // check SIO mode 
892     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
893         return SIO2_EMODE;
895     // allocate memory for device extension
896     device->object = NULL;
897     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
898     if (pDevExt == NULL)
899     {
900         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
901         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
902         asm( " SWBP 0" );  // SW Breakpoint
903         return SIO2_EALLOC;
904     }
905     device->object = (Ptr)pDevExt;
907     // inits
908     pDevExt->device = device;
909     pDevExt->sync = NULL;
910     pDevExt->pParams = NULL;
911     pDevExt->runState = 0;  // not yet started
912     pDevExt->errorState = PAF_SIO_ERROR_NONE;
913     pDevExt->shutDown = 1;
914     pDevExt->numQueued = 0;
915     pDevExt->activeEdma = EDMA_HINV;
916     pDevExt->errorEdma = EDMA_HINV;
917     pDevExt->firstTCC = 0;
918     pDevExt->optLevel = 0;
919     pDevExt->numParamSetup = 0;
920     pDevExt->numEdmaParams = 4;
922     // use dev match to fetch function table pointer for SAP
923     DEV2_match(SAP_NAME, &entry);
924     if (entry == NULL) {
925         Log_error1("SAP", SIO2_ENODEV);
926         return SIO2_ENODEV;
927     }
928     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
930     // create semaphore for device
931     pDevExt->sync = Semaphore_create (0, NULL, NULL);
932     if (pDevExt->sync == NULL)
933     {
934         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
935         return SIO2_EALLOC;
936     }
938     // queue inits
939     Queue_construct (&pDevExt->xferQue, NULL);
940     Queue_construct (&pDevExt->paramQue, NULL);
942     // update driver global (need to protect context)
943     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
944     {
945         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
946             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
947         SW_BREAKPOINT;
948     }
949     oldMask = Hwi_disable ();
950     sapDrv.device[sapDrv.numDevices] = device;
951     pDevExt->deviceNum = sapDrv.numDevices++;
952     Hwi_restore (oldMask);
954     // PORT init
955     result = SAP_PORT_FTABLE_open (device);
956     if (result)
957     {
958         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
959         return result;
960     }
962     return result;
963 } // SAP_open
965 // -----------------------------------------------------------------------------
967 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
969     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
970     Int                  result, Que_num, i;
971     EDMA3_DRV_Result     edmaResult;
972     Uint32                                      reqTcc;
973     EDMA3_DRV_Handle    hEdma;
974     Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
976     // cannot configure if transfer started
977     if (pDevExt->runState == 1)
978         return SIO2_EBADIO;
980     // save pointer to config structure in device extension. here so that
981     //   forthcoming functions can use/modify config structure.
982     pDevExt->pParams = pParams;
983     pDevExt->edmaWordSize = pParams->sio.wordSize;
985     // allocate Port resources.
986     //    This must come before DMA configuration
987     result = SAP_PORT_FTABLE_alloc (device);
988     if (result)
989     {
990         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
991         return result;
992     }
994     // .............................................................................
995     // EDMA configuration
997     // DA10x McASP0 Specific
998     if (pParams->sio.moduleNum == 0)
999     {
1000         hEdma = hEdma0;
1001         if (device->mode == DEV2_INPUT)
1002         {
1003                 Que_num = 0;
1004                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
1005         }
1006         else
1007         {
1008                 Que_num = 1;
1009                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
1010         }
1011     }
1012     // DA10x McASP1 Specific
1013     else if (pParams->sio.moduleNum == 1)
1014     {
1015         hEdma = hEdma1;
1016         if (device->mode == DEV2_INPUT)
1017                 {
1018                 Que_num = 0;
1019                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
1020                 }
1021                 else
1022                 {
1023                         Que_num = 1;
1024                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
1025                 }
1026     }
1027     // DA10x McASP2 Specific
1028     else if (pParams->sio.moduleNum == 2)
1029     {
1030         hEdma = hEdma1;
1031         if (device->mode == DEV2_INPUT)
1032                 {
1033                         Que_num = 0;
1034                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1035                 }
1036                 else
1037                 {
1038                         Que_num = 1;
1039                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1040                 }
1041     }
1044     for (i=0; i < pDevExt->numEdmaParams; i++) {
1046         reqTcc = EDMA3_DRV_TCC_ANY;
1047         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1048         edmaResult = EDMA3_DRV_requestChannel (
1049                 hEdma,
1050             &pDevExt->edmaParams[i].hEdmaParam,
1051             &reqTcc,
1052             (EDMA3_RM_EventQueue) Que_num,
1053             SAP_isrCallback,
1054             (void *) device);
1056         if (edmaResult != EDMA3_DRV_SOK)
1057             return SIO2_EALLOC;
1059         //not running => can use non-atomic functions
1060         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1062     }
1064     reqTcc = EDMA3_DRV_TCC_ANY;
1065         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1066         edmaResult = EDMA3_DRV_requestChannel (
1067             hEdma,
1068             &pDevExt->errorEdma,
1069             &reqTcc,
1070             (EDMA3_RM_EventQueue)Que_num,
1071             SAP_isrCallback,
1072             (void *) device);
1073         if (edmaResult != EDMA3_DRV_SOK)
1074             return SIO2_EALLOC;
1076         // allocate edma channel -- also disable and clear the interrupt
1079         pDevExt->firstTCC = pDevExt->activeEdma ;
1080         edmaResult = EDMA3_DRV_requestChannel (
1081                 hEdma,
1082                 &pDevExt->activeEdma,
1083                 &pDevExt->firstTCC,
1084                 (EDMA3_RM_EventQueue) 0,
1085                 SAP_isrCallback,
1086                 (void *) device);
1087         if (edmaResult != EDMA3_DRV_SOK)
1088                     {
1089                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1090                         return SIO2_EALLOC;
1091                     }
1093         // Configure error transfer
1094         //   make cnt same as # of channels in order to maintain alignment
1095         //   and the error transfer small so that we never have to wait
1096         //   long for it to complete and trigger a linked transfer. This is
1097         //   important for establishing output timing when we are idling with
1098         //   clocks still running. Is fine for Rx as well.
1099         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1101         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1103     return SIO2_OK;
1104 } // SAP_config
1106 // -----------------------------------------------------------------------------
1108 Int SAP_shutdown (DEV2_Handle device)
1110     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1111     SIO2_Handle stream = (SIO2_Handle) device;
1112     DEV2_Frame *pFrame;
1113     Int i;
1114     EDMA3_DRV_Handle hEdma;
1115     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1117     if (pDevExt->shutDown)
1118         return SIO2_EBADIO;
1120     if (pDevExt->pParams == NULL)
1121         return SIO2_EINVAL;
1123     if (pDevExt->pParams->sio.moduleNum == 0)
1124         hEdma = hEdma0;
1125     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1126         hEdma = hEdma1;
1127     if (pDevExt->activeEdma != EDMA_HINV)
1128         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1130     // reset queues
1131     while (!Queue_empty(device->todevice)) {
1132        // place oustanding requests onto holding queue
1133        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1134        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1135     }
1137     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1138         // pull frame from holding queue and place on user queue
1139         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1140         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1141     }
1144     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1145         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1147     // not running => can use non-atomic functions
1148     for (i=0; i < pDevExt->numEdmaParams; i++)
1149         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1151     // reset counter
1152     pDevExt->numQueued = 0;
1154     // make sure active is linked to error
1155         EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1157     // think this is better (from SIO_idle for standard model )
1158     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1159     while (!Queue_empty(device->fromdevice)) {
1160         /* place oustanding requests onto holding queue */
1161         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1162         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1163     }
1164     Semaphore_reset (pDevExt->sync, 0);
1165     
1166     pDevExt->shutDown = 1;
1167     pDevExt->numParamSetup = 0;
1168     
1169     /*result = SAP_DMA_FTABLE_unlock (device);
1170     if (result)
1171     {
1172         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1173         return result;
1174     } */
1176     return SIO2_OK;
1177 } // SAP_shutdown
1179 // -----------------------------------------------------------------------------
1180 int gSapWatchDogThrottle = 0; //DJDBG
1181 int gSapWatchDogIn =0;
1182 int gSapWatchDogOut = 0;
1183 int gSapWatchDogInSemPost = 0;
1184 int gSapWatchDogOutSemPost = 0;
1186 Void SAP_watchDog (Void)
1188     DEV2_Handle device;
1189     SAP_DeviceExtension *pDevExt;
1190     int i, oldMask, result;
1192     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1194     // do nothing if SAP_init not yet called
1195     if (!SAP_initialized)
1196     {
1197         Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1198         return;
1199     }
1201     // protect context
1202     Task_disable (); // needed since we may call SEM_post
1203     //oldMask = Hwi_disable ();
1206     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1208     for (i=0; i < sapDrv.numDevices; i++) {
1209         device  = sapDrv.device[i];
1211         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1213         pDevExt = (SAP_DeviceExtension *) device->object;
1215         // do nothing if not running
1216         if (!pDevExt->runState)
1217             continue;
1219         // call board specific watchdog
1220         // TODO: handle return value
1221         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1222         
1223         // if port layer returns error then must need to clean up
1224         result = SAP_PORT_FTABLE_watchDog (device);
1225         if (result) {
1226             // set errorState which will force owner thread
1227             //   to clean up via SIO_idle()
1228             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1229             if(device->mode == DEV2_INPUT)
1230                 gSapWatchDogIn++;
1231             else
1232                 gSapWatchDogOut++;
1234             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1235            /* if(gSapWatchDogThrottle == 0) //DJDBG
1236             {
1237                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1238             }
1239             gSapWatchDogThrottle ++;
1240             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1241             // if outstanding pend then post to free owner thead
1242             if (!Semaphore_pend(pDevExt->sync, 0))
1243             {
1244                 if(device->mode == DEV2_INPUT)
1245                         gSapWatchDogInSemPost++;
1246                 else
1247                         gSapWatchDogOutSemPost++;
1248                 Semaphore_post (pDevExt->sync);
1249             }
1250         }
1251     }
1254     // renable interrupts and task manager.
1255     // If we posted to the semaphore then the TSK_enable call will lead to
1256     // an immediate task switch to the associated audio thread.
1257     //Hwi_restore (oldMask);
1258     Task_enable ();
1260 } // SAP_watchDog
1262 // -----------------------------------------------------------------------------
1263 // Assumes that EDMA3 dispatcher handles TCC clearing.
1265 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1267     DEV2_Handle                 device;
1268     SAP_DeviceExtension       *pDevExt;
1269     DEV2_Frame                 *pFrame;
1270     unsigned int               opt;
1271     EDMA3_DRV_Handle                    hEdma;
1273     // could be here after Tx idle/overrun and this is the interrupt
1274     // for the last occuring error transfer so there is no transfer
1275     // to release, we just clear the int and exit.
1277     device = (DEV2_Handle) context;
1278     pDevExt = (SAP_DeviceExtension *)(device->object);
1279     //if (pDevExt->pParams == NULL)
1280         //return SIO2_EINVAL;
1282     if (pDevExt->pParams->sio.moduleNum == 0)
1283         hEdma = hEdma0;
1284     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1285         hEdma = hEdma1;
1287     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1288         // if here then an interrupt occured due to errorEdma or valid
1289         // transfer, we assume the xfer is long enough so it will not complete
1290         // before we are finished here.
1292         // if last transfer was valid then complete it
1293         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1295             // pull frame from holding queue
1296             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1298             // if used param entry then return it to queue
1299             if (pFrame->misc != NULL)
1300             {
1301                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1302                 if (device->mode == 1)
1303                         gisrOutput+=100;
1304             }
1306             // decrement count
1307             pDevExt->numQueued -= 1;
1308             //gIsrCnt++;
1309             if (device->mode == 1)
1310                 gIsrOutputCnt++;
1311             else
1312                 gIsrInputCnt++;
1313             // place frame onto user queue and signal user thread
1314             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1316             //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1317             // signal user thread
1318             Semaphore_post (pDevExt->sync);
1319 #if 0
1320             if(gIsrCnt > 10) { //DJDBG
1321                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1323             }
1324 #endif
1325         }
1326         else
1327                 gIsrElseCnt++;
1329         // determine if currently transferring buffer is valid based on interrupt enable bit
1330         // only valid transfers will generate interrupts
1331         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1333         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1334         {
1335                 if (device->mode == 1)
1336                         gIsrOutErrCnt++;
1337                 else
1338                         gIsrInErrCnt++;
1339                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1340         }
1342     } // runState
1343     else
1344     {
1345                 if (pDevExt->runState != 1)
1346                         gIsrRunCnt++;
1347                 else
1348                         gIsrNotRunCnt++;
1349     }
1351     return;
1352 } //SAP_isrCallback
1354 // -----------------------------------------------------------------------------
1356 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1358     EDMA3_DRV_Handle            hEdma;
1359     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1360 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1362         if (pDevExt->pParams == NULL)
1363                 return SIO2_EINVAL;
1365             if (pDevExt->pParams->sio.moduleNum == 0)
1366                 hEdma = hEdma0;
1367             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1368                 hEdma = hEdma1;
1370     // TODO: shouldn't this just be tcc interrupt disable?
1371     // at least until linkage phase...
1372     unsigned int key = Hwi_disable (); //DJDBG
1374     if(targetEdma == NULL)
1375     {
1376         Log_info0("targetEdma is NULL");
1377     }
1378     // configure transfer
1379     if(pFrame->addr == NULL) //DJDBG
1380     {
1381         Log_info0("pFrame has NULL address?");
1382     }
1383     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1385     if (parentEdma != EDMA_HINV)
1386         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1389     Hwi_restore (key); //DJDBG
1391     return SIO2_OK;
1392 } // SAP_setupXfer
1394 // -----------------------------------------------------------------------------
1395 // Configure EDMA3 parameter entry
1397 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1399     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1400     EDMA3_DRV_Handle            hEdma;
1401     EDMA3_DRV_PaRAMRegs  edmaConfig;
1403     if (pDevExt->pParams == NULL)
1404                 return SIO2_EINVAL;
1406         if (pDevExt->pParams->sio.moduleNum == 0)
1407                 hEdma = hEdma0;
1408         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1409                 hEdma = hEdma1;
1410     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1411    // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1413    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1415     // Init opt parameter to 0 which, without being overriden, configures as:
1416     //    A synchronized transfer (no FIFO mode on src or dst)
1417     //    no chaining or intermediate interrupts
1418     //    param is not static
1419     //    normal completion
1420     //    don't generate an interrupt (overriden below for regular xfers)
1421     edmaConfig.opt = 0;
1423     // not transferring blocks so c index is 0
1424     edmaConfig.destCIdx = 0;
1425     edmaConfig.srcCIdx = 0;
1427     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1428     if (device->mode == DEV2_OUTPUT) {
1429       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1430       edmaConfig.opt |= 2;
1431     }
1432     else {
1433         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1434         edmaConfig.opt |= 1;
1435     }
1437     // if regular transfer then enable interrupt with tcc code
1438     if (targetEdma != pDevExt->errorEdma) {
1439         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1440         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1441         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1442     }
1445     edmaConfig.aCnt = 4;
1446         edmaConfig.bCnt = pDevExt->numSers;
1447         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1448     edmaConfig.bCntReload = edmaConfig.bCnt;
1451     // handle direction specific requirements
1452     if (device->mode == DEV2_INPUT) {
1453         edmaConfig.srcBIdx  = 0;
1454                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1456         if (addr) {
1457             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1458             edmaConfig.destAddr = addr;
1459             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1460             if(pDevExt->edmaWordSize == 2)
1461                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1462         }
1463         else {
1464                 //if(pDevExt->edmaWordSize == 2)
1465                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1466             edmaConfig.destBIdx = 0;
1467             edmaConfig.destAddr = (unsigned int) &sap_OVER_4LANE;
1468             edmaConfig.cCnt = 1;
1469         }
1470     }
1471     else {
1472         edmaConfig.destBIdx = 0;
1473         edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1474         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1475         if (addr) {
1476             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1477             edmaConfig.srcAddr  = addr;
1478             //Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1479         }
1480         else {
1481             edmaConfig.srcBIdx  = 0;
1482             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1483 #if 1
1484             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1485             edmaConfig.cCnt = SAP_UNDER_LEN; //DJDBG, if underrun have frame of silence
1486 #endif
1487         }
1488     }
1489     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1490     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1492     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);
1493     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);
1495     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1497     // link child xfer
1498     if (childEdma != EDMA_HINV)
1499         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1501     return SIO2_OK;
1502 } //SAP_setupParam