PASDK-53: EDMA programming fix, to suit both 1-lane & 4-lane HDMI input handling...
[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 #ifdef SAP_PORT_MCASP
71 #include "sap_mcasp.h"
72 #else
73 #error "No port defined"
74 #endif
76 #include <pafsio.h>
78 // This works to set a breakpoint
79 #define SW_BREAKPOINT       asm( " SWBP 0" );
80 /* Software Breakpoint to Code Composer */
81 // SW_BREAKPOINT;
83 // global allocated in bios_edma3_drv_sample_init.c
84 extern EDMA3_DRV_Handle hEdma0;
85 extern EDMA3_DRV_Handle hEdma1;
87 int gStartError;
88 int gIsrInputCnt;
89 int gIsrOutputCnt;
90 int gIsrElseCnt;
91 int gIsrInErrCnt;
92 int gIsrOutErrCnt;
93 int gIsrRunCnt;
94 int gIsrNotRunCnt;
95 int gisrOutput;
96 int gSAPResetIn;
97 int gSAPResetOut;
99 typedef xdc_Short MdInt;
101 void swapHdmi(Ptr, int);
103 //#define TEST_MULTICHANNEL
106 #ifdef TEST_MULTICHANNEL
107 #define SAP_UNDER_LEN 8
108 //#define SAP_UNDER_LEN 1024 // GJ: experiment
109 #else
110 #define SAP_UNDER_LEN 1024
111 #endif
112 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
113 int sap_OVER_1LANE = 0;     // used for overrun
114 int sap_OVER_4LANE[4] = {0,0,0,0};      // used for overrun
116 #ifdef DEBUG
117 void DJDBG_SAP_EDMA_dumpParams(int tag_place)
119         //unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
120         //unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
121         unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
122         unsigned int *ptrPARAM0x41 = (unsigned int *)0x027048A0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
123         unsigned int *ptrPARAM0x42 = (unsigned int *)0x027048C0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
124         unsigned int *ptrPARAM0x43 = (unsigned int *)0x027048E0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
125         unsigned int *ptrPARAM0x44 = (unsigned int *)0x02704910; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
127         //Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
128         //Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
130         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));
131         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]);
132         Log_info4("PARAM0x19b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
134         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));
135         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]);
136         Log_info4("PARAM0x41b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x41[5], ptrPARAM0x41[6], ptrPARAM0x41[7]);
138         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));
139         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]);
140         Log_info4("PARAM0x42b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x42[5], ptrPARAM0x42[6], ptrPARAM0x42[7]);
142         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));
143         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]);
144         Log_info4("PARAM0x43b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x43[5], ptrPARAM0x43[6], ptrPARAM0x43[7]);
146         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));
147         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]);
148         Log_info4("PARAM0x44b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x44[5], ptrPARAM0x44[6], ptrPARAM0x44[7]);
149     //Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120)); //DJDBG
151 #endif
152 // .............................................................................
153 // notes:
154 //  . add control function to PORT table
155 //  . how to handle DMA/PORT specifics in parameter entries
156 //      can assume numSers = numChans is general and can be applied by DMA
157 //      same for wordSize?
158 //  . why are two idle stages needed (seems like 1 is enough)?
160 // .............................................................................
161 // only one global variable, not static so that DMA and port functions
162 // can access. We cant just store the address in devExt since the ISR has
163 // no context.
165 SAP_DriverObject sapDrv;
167 // needed since SAP_watchDog is called before SAP_init
168 Int SAP_initialized = 0;
170 //Int  SAP_close(DEV2_Handle);
171 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
172 Int  SAP_idle(DEV2_Handle, Bool);
173 Int  SAP_issue(DEV2_Handle);
174 Int  SAP_open(DEV2_Handle, String);
175 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
176 //Bool SAP_ready(DEV2_Handle, SEM_Handle);
177 Int  SAP_reclaim(DEV2_Handle);
178 Int  SAP_shutdown(DEV2_Handle);
179 Int  SAP_start(DEV2_Handle);
180 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
181 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size);
182 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
184 // .............................................................................
186 // .............................................................................
188 SAP_DMA_Fxns SAP_EDMA_FXNS =
190         SAP_EDMA_setupParam,
191         SAP_EDMA_setupXfer,
192 };
195 SAP_Fxns SAP_FXNS =
197     NULL, //SAP_close, -- remove for IROM since not using
198     SAP_ctrl,
199     SAP_idle,
200     SAP_issue,
201     SAP_open,
202     NULL, //SAP_ready, -- remove for IROM since not using
203     SAP_reclaim,
204     SAP_shutdown,
205     SAP_start,
206     SAP_config,
208 #ifdef SAP_PORT_MCASP
209     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
210 #endif
211 #ifdef SAP_DMA_EDMA
212     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
213 #endif
214 };
216 // -----------------------------------------------------------------------------
217 // This function is not in the driver function table.
218 // Must be pointed at in GUI config tool.
219 //
220 Void SAP_init (Void)
222     DEV2_Device  *entry;
223     SAP_Fxns    *pFxns;
225     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
227     // find function table pointer (used by SAP_XX_FTABLE_init macros)
228     DEV2_match(SAP_NAME, &entry);
229     if (entry == NULL) {
230         Log_error1 ("SAP", SIO2_ENODEV);
231         return;
232     }
233     pFxns = (SAP_Fxns *) entry->fxns;
235     //SAP_DMA_FTABLE_init ();
236     SAP_PORT_FTABLE_init ();
238     sapDrv.numDevices = 0;
239     SAP_initialized = 1;
241     return;
242 } // SAP_init
244 // -----------------------------------------------------------------------------
246 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
248     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
249     const SAP_Params *pParams;
250     Int result = SIO2_OK;
251     EDMA3_DRV_Handle    hEdma;
252     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
254     switch (code) {
256 /* .......................................................................... */
258         case PAF_SIO_CONTROL_MUTE:
259         case PAF_SIO_CONTROL_UNMUTE:
260             pParams = pDevExt->pParams;
261             if (pParams == NULL)
262                 return SIO2_OK;
264             if (pParams->sio.control != NULL)
265                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
266             break;
268 /* .......................................................................... */
270         case PAF_SIO_CONTROL_OPEN:
271             if (pDevExt->runState)
272                 return SIO2_EBUSY;
274             if (!( pParams = (const SAP_Params *) arg ))
275                 return SIO2_OK;
277             if (result = SAP_FTABLE_config (device, pParams))
278                 return result;
280             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
281                 return result;
283             break;
285 /* .......................................................................... */
287         case PAF_SIO_CONTROL_CLOSE:
288             if (pDevExt->runState)
289                 return SIO2_EBUSY;
291             if (pDevExt->pParams == NULL)
292                                 return SIO2_EINVAL;
294             pParams = pDevExt->pParams;
296                         if (pParams->sio.moduleNum == 0)
297                                 hEdma = hEdma0;
298                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
299                                 hEdma = hEdma1;
300             if (pDevExt->activeEdma != EDMA_HINV) {
301                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
302                             pDevExt->activeEdma = EDMA_HINV;
303                         }
305             if (!(pParams = pDevExt->pParams))
306                 return SIO2_OK;
308             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
309                 return result;
311             result = SAP_PORT_FTABLE_close (device);
312             if (result)
313                 return result;
315             pDevExt->pParams = NULL;
316             break;
318 /* .......................................................................... */
320         case PAF_SIO_CONTROL_GET_WORDSIZE:
321                 if (!arg)
322                                 return SIO2_EINVAL;
323                         *((int *) arg) = pDevExt->edmaWordSize;
324             break;
326         case PAF_SIO_CONTROL_SET_WORDSIZE:
327             // defer to DMA processing
328                 // currently only supported for input
329                         if (device->mode != DEV2_INPUT)
330                                 return SIO2_EINVAL;
332                         // can't be running
333                         if (pDevExt->runState)
334                                 return SIO2_EBUSY;
336                         // driver only supports 2 or 4 bytes
337                    if ((arg != 2) && (arg != 4))
338                                 return SIO2_EINVAL;
340                         // return success for unconfigured devices?
341                         if (!pDevExt->pParams)
342                                 return SIO2_OK;
344                         // ask platform if size is supported
345                         pParams = pDevExt->pParams;
346                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
347                                 return result;
349                         pDevExt->edmaWordSize = arg;
350                         break;
352         case PAF_SIO_CONTROL_GET_PRECISION:
353             if (arg == 0)
354                 return SIO2_EINVAL;
356             pParams = pDevExt->pParams;
357             if (pParams == NULL)
358                 return( SIO2_EINVAL );
360             *((int *) arg) = pParams->sio.precision;
361             break;
363         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
364             if (arg == 0)
365                 return SIO2_EINVAL;
367             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
368             break;
370         case PAF_SIO_CONTROL_SET_RATEX:
371             pParams = pDevExt->pParams;
372             if (pParams == NULL)
373                 return SIO2_OK ;
375             if (pParams->sio.control == NULL)
376                 return SIO2_EINVAL;
378             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
379             break;
381 /* .......................................................................... */
383         case PAF_SIO_CONTROL_IDLE:
384             pParams = pDevExt->pParams;
385             if (pParams == NULL)
386                 return SIO2_OK ;
388             if (pParams->sio.control == NULL)
389                 return SIO2_EINVAL;
391             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
392             break;
394         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
395             // 1. Here we are intentionally not using SIO_Idle() and
396             //    leaving the Tx clock running. We need this to avoid DAC noise,
397             //    as well as provide a DIT clock when using digital output.
398             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
399                 return SIO2_EINVAL;
401             pParams = pDevExt->pParams;
403             if (pParams->sio.moduleNum == 0)
404                 hEdma = hEdma0;
405             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
406                                 hEdma = hEdma1;
408             result = SAP_FTABLE_shutdown (device);
409             if (result)
410                 return result;
412             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
413             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
415 #if 1
416             //DJDBG, if below enableTransfer() is commented, input side continuous working.
417      if (pDevExt->activeEdma != EDMA_HINV) {
418                 //EDMA3_DRV_disableTransfer (hEdma0, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
419             //if(*((unsigned int *)0x02701000) & 0x01000000) *((unsigned int *)0x02701008) = 0x01000000; //Clear pending even in bit 24! //DJDBG
420             EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
421      }
422 #endif
423             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
425             break;
427 /* .......................................................................... */
429         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
430             // needs to be attached
431             pParams = pDevExt->pParams;
432             if (pParams == NULL)
433                 return SIO2_OK;
435             if (pParams->sio.control == NULL)
436                 return SIO2_EINVAL;
438             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
439             break;
441         case PAF_SIO_CONTROL_WATCHDOG:
442             pParams = pDevExt->pParams;
443             if (pParams == NULL)
444                 return SIO2_OK;
445             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
446                 return result;
447             break;
448             
449 /* .......................................................................... */
451         // Timing stats specific to DMA engine
452         case PAF_SIO_CONTROL_ENABLE_STATS:
453         case PAF_SIO_CONTROL_DISABLE_STATS:
454         case PAF_SIO_CONTROL_GET_STATS:
455         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
456         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
457             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
458             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
459             break;
461 /* .......................................................................... */
463         case PAF_SIO_CONTROL_SET_DITSTATUS:
464             if(device->mode == DEV2_OUTPUT)
465             {
466                 const SAP_Params *pParams = pDevExt->pParams;
467                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
468                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
469                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
470                 int encSelect = *((int *) arg);
472                 // HACK -- determine DIT need by FXWID
473                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
474                 {
475                     if ( (encSelect == 0x13) ||
476                          (encSelect == 0xa)  || 
477                          (encSelect == 0x6)) // DTE, DDE, MPE 
478                     {
479                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
480                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
481                     }
482                     else
483                     {
484                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
485                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
486                     }
487                 }
489                 pParams = pDevExt->pParams;
490                 if (pParams == NULL)
491                     return SIO2_OK;
493                 if (pParams->sio.control != NULL)
494                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
495             }
496             break;
498 /* .......................................................................... */
500     }
502     return result;
503 } // SAP_ctrl
505 int gSAPIdleShutdownIn=0;
506 int gSAPIdleShutdownOut=0;
508 // -----------------------------------------------------------------------------
510 Int SAP_idle (DEV2_Handle device, Bool flush)
512     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
513     Int result = SIO2_OK;
514     EDMA3_DRV_Handle hEdma;
516     // do nothing if already idled or unattached
517     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
518         return result;
520         if (pDevExt->pParams->sio.moduleNum == 0)
521                 hEdma = hEdma0;
522         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
523                 hEdma = hEdma1;
525     // reset serial port -- stop generating sync events
526     result = SAP_PORT_FTABLE_reset (device);
527     if(device->mode == DEV2_OUTPUT)
528         gSAPResetOut++;
529     else
530         gSAPResetIn++;
531     if (result)
532     {
533         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
534         return result;
535     }
537     pDevExt->shutDown = 0; // force shutdown to run
538     result = SAP_FTABLE_shutdown (device);
539     if(device->mode == DEV2_OUTPUT)
540         gSAPIdleShutdownOut++;
541     else
542         gSAPIdleShutdownIn++;
544     if (result)
545     {
546         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
547         return result;
548     }
550     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
552     // disable interrupts and EDMA servicing
553    if (pDevExt->activeEdma != EDMA_HINV)
554            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
556     pDevExt->numQueued = 0;
558     // signal stopped
559     pDevExt->runState = 0;
561     // reset errorState
562     pDevExt->errorState = PAF_SIO_ERROR_NONE;
563     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
565     // place call to physical device
566     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
567         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
569     return result;
570 } // SAP_idle
572 // -----------------------------------------------------------------------------
574 Int SAP_start (DEV2_Handle device)
576     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
577     DEV2_Frame *pFrame;
578     int result;
579     EDMA3_DRV_Handle hEdma;
581     //TRACE_GEN((&TR_MOD, "SAP_start.%d (0x%x)", __LINE__, device));
583     // signal we have started
584     //    we change the state here since we have already moved a frame from the 
585     //    todevice queue to the xferQue. If an error occurs during one of the 
586     //    following resets/enables then we need to have runState !=0 in order
587     //    for SAP_idle to properly cleanup. Moreover, the following resets/enables
588     //    do not (and are now required not to) depend on runState being 0.
589     //pDevExt->runState = 1;
590     // Assume todevice queue is not empty -- how else could we be here?
591     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
593     // inidicate this xfer did not use param entry - just the active one
594     pFrame->misc = NULL;
595     if (pDevExt->pParams->sio.moduleNum == 0)
596         hEdma = hEdma0;
597     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
598                 hEdma = hEdma1;
600     // non-atomic functions since not running yet.
601     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
603     // initialize count
604     pDevExt->numQueued = 1;
606     result = SAP_PORT_FTABLE_reset (device);
607     if (result)
608     {
609         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
610         return result;
611     }
613     // enable DMA processing
615     // config active xfer for this buffer
616     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
618     //Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
619       //              __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
620         // signal we have started -- this must come before last enable to prevent a race
621         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
622         // and completes before any further instructions in this thread are executed.
623         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
624         // will be serviced and generate an interrupt even before the McASP is enabled.
625         pDevExt->runState = 1;
626         pDevExt->shutDown = 0;
627         Log_info1 ("SAP: %d, SAP_start runState=1 & ENABLE TRANSFERS", __LINE__);
628         // enable interrupts and event servicing for this channel
629         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
631     // enable peripheral
632     result = SAP_PORT_FTABLE_enable (device);
634     if (result)
635     {
636         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
637         return result;
638     }
640     return SIO2_OK;
641 } // SAP_start
643 int gDmaParamsarray[17][3];
644 int gDmaParamsidx=0, gSAPSpecialCase=0;
645 // -----------------------------------------------------------------------------
647 Int SAP_issue (DEV2_Handle device)
649     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
650     DEV2_Frame *pFrame;
651     Int result;
652     SAP_EDMA_Param *pParam;
653     XDAS_UInt32 parentEdma;
655     //TRACE_GEN((&TR_MOD, "SAP_issue.%d (0x%x)", __LINE__, device));
657     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
658     {
659         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
660             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
661         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
662                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
663         return SIO2_EBADIO;
664     }
666     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
667         {
668                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
669             return SIO2_EBADIO;
670         }
672     // if not yet running then configure active xfer and start
673     if (pDevExt->runState == 0)
674         return (SAP_FTABLE_start(device));
676     // .........................................................................
677     // here if running
679     // disable device interrupts
680     // TODO: is there an API to just disable the IER bit for this tcc?
681     unsigned int key = Hwi_disable ();
682        /* determine parent EDMA
683           if no xfers in queue and we are running then must be in the
684           error state so link to active channel otherwise link to last
685           transfer queued.
686        */
688        /* here we assume after Tx SIO_idle or overrun, the user
689           will issue, at least, back-to-back issue requests so
690           there should be no problem here.
691        */
692        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
693            parentEdma = pDevExt->activeEdma;
694        else {
695            // if here then xferQue has more than one element so ok to use tail
696            // last scheduled transfer must be queue->prev
697            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
698            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
699        }
701     // get frame and parameter table to use; ints off => non-atomic OK
702     //     dont need to check for empty queues since were here then todevice
703     //     must have a frame placed there by the SIO_issue layer.
704     //     paramQue must be valid since it is accessed the same as todevice.
705     //     (indirectly -- isr places used items onto paramQue and fromdevice que
706     //      at the same time)
707     // set misc argument to pParam so get enqueue later
708     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
709     pFrame = Queue_dequeue (device->todevice);
710     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
712     if (pParam->hEdmaParam == NULL)
713         Log_info0("SAP_issue: hEdma value is NULL");
714     // set misc argument to pParam so get enqueue later
715     pFrame->misc = (Arg) pParam;
717     // place on holder queue, ints off => non-atomic OK
718     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
719     if (pFrame->addr) {
720                 if (device->mode == DEV2_INPUT)
721                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
722                 else
723                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
724         }
726     // increment count
727     pDevExt->numQueued += 1;
729     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
730     Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
731                     __LINE__, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma);
733     /*if ((device->mode != DEV2_INPUT) && (gDmaParamsidx <=16))
734         {
735         gDmaParamsarray[gDmaParamsidx][0] = pParam->hEdma;
736                 gDmaParamsarray[gDmaParamsidx][1] = parentEdma;
737                 gDmaParamsarray[gDmaParamsidx++][2] = gisrOutput;
738         } */
740         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
741                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
743         pDevExt->shutDown = 0;
745     // special case enables when not yet started
746     if (pDevExt->runState == 0) {
747         gSAPSpecialCase++;
748         result = SAP_FTABLE_start (device);
749         if (result) {
750             //SAP_DMA_FTABLE_unlock (device);
751                   Hwi_restore (key);
752             return result;
753         }
754     }
755     Hwi_restore (key); //DJDBG
757     return result;
758 } // SAP_issue
760 // -----------------------------------------------------------------------------
762 void swapHdmi(Ptr Input, int size)
765         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
766         MdInt *p1, *p2;
767         int i=0;
769         for (i=0; i< size; i+=16)
770         {
771                         p1 = (MdInt *)&Input[i];
772                         p2 = p1;
774                         L0 = *p1++;
775                         L1 = *p1++;
776                         L2 = *p1++;
777                         L3 = *p1++;
778                         R0 = *p1++;
779                         R1 = *p1++;
780                         R2 = *p1++;
781                         R3 = *p1++;
783                         *p2++ = L0;
784                         *p2++ = R0;
785                         *p2++ = L1;
786                         *p2++ = R1;
787                         *p2++ = L2;
788                         *p2++ = R2;
789                         *p2++ = L3;
790                         *p2++ = R3;
792         }
794         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (xdc_IArg)Input, p1, p2);
796         return;
799 Int SAP_reclaim (DEV2_Handle device)
801     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
802 #ifdef SAP_CACHE_SUPPORT
803     DEV2_Frame *pFrame;
804 #endif
806     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
808     // must be running and  error free 
809     if ((!pDevExt->runState) || (pDevExt->errorState))
810     {
811         //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d, not runState: 0x%x", __LINE__, pDevExt->errorState));
812         return SIO2_EBADIO;
813     }
815     // idle if necessary
816         if (pDevExt->errorState == PAF_SIO_ERROR_FATAL) {
817                 Log_info1("SAP_reclaim: PAF_SIO_ERROR_FATAL,  Before Idle for device 0x%x  ", device->mode);
818             DEV2_idle (device, 1);
819             return SIO2_EBADIO;
820         }
822        // Log_info0("SAP_reclaim: Before SEM Pend");
824     // wait for ISR to signal block completion
825     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
826     if (!Semaphore_pend(pDevExt->sync, device->timeout))
827     {
828         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
829         return SIO2_ETIMEOUT;
830     }
831     //Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
833 #if 0
834     // return error (owner must idle)
835     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
836     {
837         DEV2_idle (device, 1);
838         //TRACE_TERSE((&TR_MOD, "SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
839         return PAF_SIO_ERROR_FATAL;
840     }
841 #endif
843 #ifdef SAP_CACHE_SUPPORT
844     // invalidate CACHE region if input -- use clean since
845     //    Dont clean if was for fill.
846     // since pend returned we know that head of fromdevice is valid
847     pFrame = Queue_head (device->fromdevice);
848     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", pFrame->addr, pFrame->size);
849     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
850     {
851         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
852         {
853             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
854             Cache_wait();
856             // max HWI disable duration ~1ms observed
857             //unsigned int key = Hwi_disable ();                    // GJ: Revisit, along with other context protections here.
858             swapHdmi(pFrame->addr, pFrame->size);
859             //Hwi_restore(key);
861             Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
862             Cache_wait();
863         }
864     }
866 #endif
867     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
868         SW_BREAKPOINT; */
870     Log_info1("SAP_reclaim: Exiting with SIO2_OK for device 0x%x  ", device->mode);
871     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
872     return SIO2_OK;
873 } // SAP_reclaim
876 // -----------------------------------------------------------------------------
878 Int SAP_open (DEV2_Handle device, String name)
880     SAP_DeviceExtension   *pDevExt;
881     DEV2_Device            *entry;
882     Int                    oldMask, result;
883     Error_Block                         eb;
884     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
886     // check SIO mode 
887     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
888         return SIO2_EMODE;
890     // allocate memory for device extension
891     device->object = NULL;
892     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
893     if (pDevExt == NULL)
894     {
895         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
896         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
897         asm( " SWBP 0" );  // SW Breakpoint
898         return SIO2_EALLOC;
899     }
900     device->object = (Ptr)pDevExt;
902     // inits
903     pDevExt->device = device;
904     pDevExt->sync = NULL;
905     pDevExt->pParams = NULL;
906     pDevExt->runState = 0;  // not yet started
907     pDevExt->errorState = PAF_SIO_ERROR_NONE;
908     pDevExt->shutDown = 1;
909     pDevExt->numQueued = 0;
910     pDevExt->activeEdma = EDMA_HINV;
911     pDevExt->errorEdma = EDMA_HINV;
912     pDevExt->firstTCC = 0;
913     pDevExt->optLevel = 0;
914     pDevExt->numParamSetup = 0;
915     pDevExt->numEdmaParams = 4;
917     // use dev match to fetch function table pointer for SAP
918     DEV2_match(SAP_NAME, &entry);
919     if (entry == NULL) {
920         Log_error1("SAP", SIO2_ENODEV);
921         return SIO2_ENODEV;
922     }
923     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
925     // create semaphore for device
926     pDevExt->sync = Semaphore_create (0, NULL, NULL);
927     if (pDevExt->sync == NULL)
928     {
929         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
930         return SIO2_EALLOC;
931     }
933     // queue inits
934     Queue_construct (&pDevExt->xferQue, NULL);
935     Queue_construct (&pDevExt->paramQue, NULL);
937     // update driver global (need to protect context)
938     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
939     {
940         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
941             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
942         SW_BREAKPOINT;
943     }
944     oldMask = Hwi_disable ();
945     sapDrv.device[sapDrv.numDevices] = device;
946     pDevExt->deviceNum = sapDrv.numDevices++;
947     Hwi_restore (oldMask);
949     // PORT init
950     result = SAP_PORT_FTABLE_open (device);
951     if (result)
952     {
953         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
954         return result;
955     }
957     return result;
958 } // SAP_open
960 // -----------------------------------------------------------------------------
962 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
964     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
965     Int                  result, Que_num, i;
966     EDMA3_DRV_Result     edmaResult;
967     Uint32                                      reqTcc;
968     EDMA3_DRV_Handle    hEdma;
969     Log_info2("SAP_config.%d (0x%x)", __LINE__, device);
971     // cannot configure if transfer started
972     if (pDevExt->runState == 1)
973         return SIO2_EBADIO;
975     // save pointer to config structure in device extension. here so that
976     //   forthcoming functions can use/modify config structure.
977     pDevExt->pParams = pParams;
978     pDevExt->edmaWordSize = pParams->sio.wordSize;
980     // allocate Port resources.
981     //    This must come before DMA configuration
982     result = SAP_PORT_FTABLE_alloc (device);
983     if (result)
984     {
985         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
986         return result;
987     }
989     // .............................................................................
990     // EDMA configuration
992     // DA10x McASP0 Specific
993     if (pParams->sio.moduleNum == 0)
994     {
995         hEdma = hEdma0;
996         if (device->mode == DEV2_INPUT)
997         {
998                 Que_num = 0;
999                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
1000         }
1001         else
1002         {
1003                 Que_num = 1;
1004                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
1005         }
1006     }
1007     // DA10x McASP1 Specific
1008     else if (pParams->sio.moduleNum == 1)
1009     {
1010         hEdma = hEdma1;
1011         if (device->mode == DEV2_INPUT)
1012                 {
1013                 Que_num = 0;
1014                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
1015                 }
1016                 else
1017                 {
1018                         Que_num = 1;
1019                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
1020                 }
1021     }
1022     // DA10x McASP2 Specific
1023     else if (pParams->sio.moduleNum == 2)
1024     {
1025         hEdma = hEdma1;
1026         if (device->mode == DEV2_INPUT)
1027                 {
1028                         Que_num = 0;
1029                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1030                 }
1031                 else
1032                 {
1033                         Que_num = 1;
1034                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1035                 }
1036     }
1039     for (i=0; i < pDevExt->numEdmaParams; i++) {
1041         reqTcc = EDMA3_DRV_TCC_ANY;
1042         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1043         edmaResult = EDMA3_DRV_requestChannel (
1044                 hEdma,
1045             &pDevExt->edmaParams[i].hEdmaParam,
1046             &reqTcc,
1047             (EDMA3_RM_EventQueue) Que_num,
1048             SAP_isrCallback,
1049             (void *) device);
1051         if (edmaResult != EDMA3_DRV_SOK)
1052             return SIO2_EALLOC;
1054         //not running => can use non-atomic functions
1055         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1057     }
1059     reqTcc = EDMA3_DRV_TCC_ANY;
1060         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1061         edmaResult = EDMA3_DRV_requestChannel (
1062             hEdma,
1063             &pDevExt->errorEdma,
1064             &reqTcc,
1065             (EDMA3_RM_EventQueue)Que_num,
1066             SAP_isrCallback,
1067             (void *) device);
1068         if (edmaResult != EDMA3_DRV_SOK)
1069             return SIO2_EALLOC;
1071         // allocate edma channel -- also disable and clear the interrupt
1074         pDevExt->firstTCC = pDevExt->activeEdma ;
1075         edmaResult = EDMA3_DRV_requestChannel (
1076                 hEdma,
1077                 &pDevExt->activeEdma,
1078                 &pDevExt->firstTCC,
1079                 (EDMA3_RM_EventQueue) 0,
1080                 SAP_isrCallback,
1081                 (void *) device);
1082         if (edmaResult != EDMA3_DRV_SOK)
1083                     {
1084                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1085                         return SIO2_EALLOC;
1086                     }
1088         // Configure error transfer
1089         //   make cnt same as # of channels in order to maintain alignment
1090         //   and the error transfer small so that we never have to wait
1091         //   long for it to complete and trigger a linked transfer. This is
1092         //   important for establishing output timing when we are idling with
1093         //   clocks still running. Is fine for Rx as well.
1094         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1096         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1098     return SIO2_OK;
1099 } // SAP_config
1101 // -----------------------------------------------------------------------------
1103 Int SAP_shutdown (DEV2_Handle device)
1105     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1106     SIO2_Handle stream = (SIO2_Handle) device;
1107     DEV2_Frame *pFrame;
1108     Int i;
1109     EDMA3_DRV_Handle hEdma;
1110     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1112     if (pDevExt->shutDown)
1113         return SIO2_EBADIO;
1115     if (pDevExt->pParams == NULL)
1116         return SIO2_EINVAL;
1118     if (pDevExt->pParams->sio.moduleNum == 0)
1119         hEdma = hEdma0;
1120     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1121         hEdma = hEdma1;
1122     if (pDevExt->activeEdma != EDMA_HINV)
1123         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1125     // reset queues
1126     while (!Queue_empty(device->todevice)) {
1127        // place oustanding requests onto holding queue
1128        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1129        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1130     }
1132     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1133         // pull frame from holding queue and place on user queue
1134         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1135         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1136     }
1139     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1140         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1142     // not running => can use non-atomic functions
1143     for (i=0; i < pDevExt->numEdmaParams; i++)
1144         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1146     // reset counter
1147     pDevExt->numQueued = 0;
1149     //DJDBG_SAP_EDMA_dumpParams(1);
1150     // make sure active is linked to error
1151         EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1153     // think this is better (from SIO_idle for standard model )
1154     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1155     while (!Queue_empty(device->fromdevice)) {
1156         /* place oustanding requests onto holding queue */
1157         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1158         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1159     }
1160     Semaphore_reset (pDevExt->sync, 0);
1161     
1162     pDevExt->shutDown = 1;
1163     pDevExt->numParamSetup = 0;
1164     
1165     /*result = SAP_DMA_FTABLE_unlock (device);
1166     if (result)
1167     {
1168         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_DMA_FTABLE_unlock returned %d.\n", __FUNCTION__, __LINE__, result));
1169         return result;
1170     } */
1172     return SIO2_OK;
1173 } // SAP_shutdown
1175 // -----------------------------------------------------------------------------
1176 int gSapWatchDogThrottle = 0; //DJDBG
1177 int gSapWatchDogIn =0;
1178 int gSapWatchDogOut = 0;
1179 int gSapWatchDogInSemPost = 0;
1180 int gSapWatchDogOutSemPost = 0;
1182 Void SAP_watchDog (Void)
1184     DEV2_Handle device;
1185     SAP_DeviceExtension *pDevExt;
1186     int i, oldMask, result;
1188     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1190     // do nothing if SAP_init not yet called
1191     if (!SAP_initialized)
1192     {
1193         Log_info2("%s.%d: SAP_init not yet called.\n", __FUNCTION__, __LINE__);
1194         return;
1195     }
1198     // protect context
1199     Task_disable (); // needed since we may call SEM_post
1200     //oldMask = Hwi_disable ();
1203     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1205     for (i=0; i < sapDrv.numDevices; i++) {
1206         device  = sapDrv.device[i];
1208         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1210         pDevExt = (SAP_DeviceExtension *) device->object;
1212         // do nothing if not running
1213         if (!pDevExt->runState)
1214             continue;
1216         // call board specific watchdog
1217         // TODO: handle return value
1218         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1219         
1220         // if port layer returns error then must need to clean up
1221         result = SAP_PORT_FTABLE_watchDog (device);
1222         if (result) {
1223             // set errorState which will force owner thread
1224             //   to clean up via SIO_idle()
1225             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1226             if(device->mode == DEV2_INPUT)
1227                 gSapWatchDogIn++;
1228             else
1229                 gSapWatchDogOut++;
1231             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1232            /* if(gSapWatchDogThrottle == 0) //DJDBG
1233             {
1234                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1235             }
1236             gSapWatchDogThrottle ++;
1237             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1238             // if outstanding pend then post to free owner thead
1239             if (!Semaphore_pend(pDevExt->sync, 0))
1240             {
1241                 if(device->mode == DEV2_INPUT)
1242                         gSapWatchDogInSemPost++;
1243                 else
1244                         gSapWatchDogOutSemPost++;
1245                 Semaphore_post (pDevExt->sync);
1246             }
1247         }
1248     }
1251     // renable interrupts and task manager.
1252     // If we posted to the semaphore then the TSK_enable call will lead to
1253     // an immediate task switch to the associated audio thread.
1254     //Hwi_restore (oldMask);
1255     Task_enable ();
1257 } // SAP_watchDog
1259 // -----------------------------------------------------------------------------
1260 // Assumes that EDMA3 dispatcher handles TCC clearing.
1262 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1264     DEV2_Handle                 device;
1265     SAP_DeviceExtension       *pDevExt;
1266     DEV2_Frame                 *pFrame;
1267     unsigned int               opt;
1268     EDMA3_DRV_Handle                    hEdma;
1270     // could be here after Tx idle/overrun and this is the interrupt
1271     // for the last occuring error transfer so there is no transfer
1272     // to release, we just clear the int and exit.
1274     device = (DEV2_Handle) context;
1275     pDevExt = (SAP_DeviceExtension *)(device->object);
1276     //if (pDevExt->pParams == NULL)
1277         //return SIO2_EINVAL;
1279     if (pDevExt->pParams->sio.moduleNum == 0)
1280         hEdma = hEdma0;
1281     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1282         hEdma = hEdma1;
1284     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1285         // if here then an interrupt occured due to errorEdma or valid
1286         // transfer, we assume the xfer is long enough so it will not complete
1287         // before we are finished here.
1289         // if last transfer was valid then complete it
1290         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1292             // pull frame from holding queue
1293             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1295             // if used param entry then return it to queue
1296             if (pFrame->misc != NULL)
1297             {
1298                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1299                 if (device->mode == 1)
1300                         gisrOutput+=100;
1301             }
1303             // decrement count
1304             pDevExt->numQueued -= 1;
1305             //gIsrCnt++;
1306             if (device->mode == 1)
1307                 gIsrOutputCnt++;
1308             else
1309                 gIsrInputCnt++;
1310             // place frame onto user queue and signal user thread
1311             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1313             //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1314             // signal user thread
1315             Semaphore_post (pDevExt->sync);
1316 #if 0
1317             if(gIsrCnt > 10) { //DJDBG
1318                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1320             }
1321 #endif
1322         }
1323         else
1324                 gIsrElseCnt++;
1326         // determine if currently transferring buffer is valid based on interrupt enable bit
1327         // only valid transfers will generate interrupts
1328         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1330         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1331         {
1332                 if (device->mode == 1)
1333                         gIsrOutErrCnt++;
1334                 else
1335                         gIsrInErrCnt++;
1336                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1337         }
1339     } // runState
1340     else
1341     {
1342                 if (pDevExt->runState != 1)
1343                         gIsrRunCnt++;
1344                 else
1345                         gIsrNotRunCnt++;
1346     }
1348     return;
1349 } //SAP_isrCallback
1351 // -----------------------------------------------------------------------------
1353 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1355     EDMA3_DRV_Handle            hEdma;
1356     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1357 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1359         if (pDevExt->pParams == NULL)
1360                 return SIO2_EINVAL;
1362             if (pDevExt->pParams->sio.moduleNum == 0)
1363                 hEdma = hEdma0;
1364             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1365                 hEdma = hEdma1;
1367     // TODO: shouldn't this just be tcc interrupt disable?
1368     // at least until linkage phase...
1369     unsigned int key = Hwi_disable (); //DJDBG
1371     if(targetEdma == NULL)
1372     {
1373         Log_info0("targetEdma is NULL");
1374     }
1375     // configure transfer
1376     if(pFrame->addr == NULL) //DJDBG
1377     {
1378         Log_info0("pFrame has NULL address?");
1379     }
1380     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1382     if (parentEdma != EDMA_HINV)
1383         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1386     Hwi_restore (key); //DJDBG
1388     return SIO2_OK;
1389 } // SAP_setupXfer
1391 // -----------------------------------------------------------------------------
1392 // Configure EDMA3 parameter entry
1394 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1396     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1397     EDMA3_DRV_Handle            hEdma;
1398     EDMA3_DRV_PaRAMRegs  edmaConfig;
1400     if (pDevExt->pParams == NULL)
1401                 return SIO2_EINVAL;
1403         if (pDevExt->pParams->sio.moduleNum == 0)
1404                 hEdma = hEdma0;
1405         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1406                 hEdma = hEdma1;
1407     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1408    // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1410    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1412     // Init opt parameter to 0 which, without being overriden, configures as:
1413     //    A synchronized transfer (no FIFO mode on src or dst)
1414     //    no chaining or intermediate interrupts
1415     //    param is not static
1416     //    normal completion
1417     //    don't generate an interrupt (overriden below for regular xfers)
1418     edmaConfig.opt = 0;
1420     // not transferring blocks so c index is 0
1421     edmaConfig.destCIdx = 0;
1422     edmaConfig.srcCIdx = 0;
1424     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1425     if (device->mode == DEV2_OUTPUT) {
1426       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1427       edmaConfig.opt |= 2;
1428     }
1429     else {
1430         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1431         edmaConfig.opt |= 1;
1432     }
1434     // if regular transfer then enable interrupt with tcc code
1435     if (targetEdma != pDevExt->errorEdma) {
1436         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1437         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1438         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1439     }
1442     edmaConfig.aCnt = 4;
1443         edmaConfig.bCnt = pDevExt->numSers;
1444         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1445     edmaConfig.bCntReload = edmaConfig.bCnt;
1448     // handle direction specific requirements
1449     if (device->mode == DEV2_INPUT) {
1450         edmaConfig.srcBIdx  = 0;
1451                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1453         if (addr) {
1454             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1455             edmaConfig.destAddr = addr;
1456             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1457             if(pDevExt->edmaWordSize == 2)
1458                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1459         }
1460         else {
1461                 //if(pDevExt->edmaWordSize == 2)
1462                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1463             edmaConfig.destBIdx = 0;
1464             edmaConfig.destAddr = (unsigned int) &sap_OVER_4LANE;
1465             edmaConfig.cCnt = 1;
1466         }
1467     }
1468     else {
1469         edmaConfig.destBIdx = 0;
1470         edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1471         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1472         if (addr) {
1473             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1474             edmaConfig.srcAddr  = addr;
1475             Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1476         }
1477         else {
1478             edmaConfig.srcBIdx  = 0;
1479             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1480 #if 1
1481             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1482             edmaConfig.cCnt = SAP_UNDER_LEN; //DJDBG, if underrun have frame of silence
1483 #endif
1484         }
1485     }
1486     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1487     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1489     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);
1490     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);
1492     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1494     // link child xfer
1495     if (childEdma != EDMA_HINV)
1496         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1498     return SIO2_OK;
1499 } //SAP_setupParam