Merge remote-tracking branch 'origin/dev_pasdk_govind_pasdk53IpDataDebug' into dev_pa...
[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     }
1197     // protect context
1198     Task_disable (); // needed since we may call SEM_post
1199     //oldMask = Hwi_disable ();
1202     //TRACE_VERBOSE((&TR_MOD, "%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, dapDrv.numDevices));
1204     for (i=0; i < sapDrv.numDevices; i++) {
1205         device  = sapDrv.device[i];
1207         //TRACE_VERBOSE((&TR_MOD, "%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device));
1209         pDevExt = (SAP_DeviceExtension *) device->object;
1211         // do nothing if not running
1212         if (!pDevExt->runState)
1213             continue;
1215         // call board specific watchdog
1216         // TODO: handle return value
1217         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1218         
1219         // if port layer returns error then must need to clean up
1220         result = SAP_PORT_FTABLE_watchDog (device);
1221         if (result) {
1222             // set errorState which will force owner thread
1223             //   to clean up via SIO_idle()
1224             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1225             if(device->mode == DEV2_INPUT)
1226                 gSapWatchDogIn++;
1227             else
1228                 gSapWatchDogOut++;
1230             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1231            /* if(gSapWatchDogThrottle == 0) //DJDBG
1232             {
1233                Log_info3("SAP_watchDog.%d (0x%x); THROTTLED result = 0x%x", __LINE__, device, result);
1234             }
1235             gSapWatchDogThrottle ++;
1236             if(gSapWatchDogThrottle > 10) gSapWatchDogThrottle = 0; */
1237             // if outstanding pend then post to free owner thead
1238             if (!Semaphore_pend(pDevExt->sync, 0))
1239             {
1240                 if(device->mode == DEV2_INPUT)
1241                         gSapWatchDogInSemPost++;
1242                 else
1243                         gSapWatchDogOutSemPost++;
1244                 Semaphore_post (pDevExt->sync);
1245             }
1246         }
1247     }
1250     // renable interrupts and task manager.
1251     // If we posted to the semaphore then the TSK_enable call will lead to
1252     // an immediate task switch to the associated audio thread.
1253     //Hwi_restore (oldMask);
1254     Task_enable ();
1256 } // SAP_watchDog
1258 // -----------------------------------------------------------------------------
1259 // Assumes that EDMA3 dispatcher handles TCC clearing.
1261 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1263     DEV2_Handle                 device;
1264     SAP_DeviceExtension       *pDevExt;
1265     DEV2_Frame                 *pFrame;
1266     unsigned int               opt;
1267     EDMA3_DRV_Handle                    hEdma;
1269     // could be here after Tx idle/overrun and this is the interrupt
1270     // for the last occuring error transfer so there is no transfer
1271     // to release, we just clear the int and exit.
1273     device = (DEV2_Handle) context;
1274     pDevExt = (SAP_DeviceExtension *)(device->object);
1275     //if (pDevExt->pParams == NULL)
1276         //return SIO2_EINVAL;
1278     if (pDevExt->pParams->sio.moduleNum == 0)
1279         hEdma = hEdma0;
1280     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1281         hEdma = hEdma1;
1283     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1284         // if here then an interrupt occured due to errorEdma or valid
1285         // transfer, we assume the xfer is long enough so it will not complete
1286         // before we are finished here.
1288         // if last transfer was valid then complete it
1289         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1291             // pull frame from holding queue
1292             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1294             // if used param entry then return it to queue
1295             if (pFrame->misc != NULL)
1296             {
1297                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1298                 if (device->mode == 1)
1299                         gisrOutput+=100;
1300             }
1302             // decrement count
1303             pDevExt->numQueued -= 1;
1304             //gIsrCnt++;
1305             if (device->mode == 1)
1306                 gIsrOutputCnt++;
1307             else
1308                 gIsrInputCnt++;
1309             // place frame onto user queue and signal user thread
1310             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1312             //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1313             // signal user thread
1314             Semaphore_post (pDevExt->sync);
1315 #if 0
1316             if(gIsrCnt > 10) { //DJDBG
1317                Log_info1("SAP isrCallback enough interrupts! %d", gIsrCnt);
1319             }
1320 #endif
1321         }
1322         else
1323                 gIsrElseCnt++;
1325         // determine if currently transferring buffer is valid based on interrupt enable bit
1326         // only valid transfers will generate interrupts
1327         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1329         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1330         {
1331                 if (device->mode == 1)
1332                         gIsrOutErrCnt++;
1333                 else
1334                         gIsrInErrCnt++;
1335                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1336         }
1338     } // runState
1339     else
1340     {
1341                 if (pDevExt->runState != 1)
1342                         gIsrRunCnt++;
1343                 else
1344                         gIsrNotRunCnt++;
1345     }
1347     return;
1348 } //SAP_isrCallback
1350 // -----------------------------------------------------------------------------
1352 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1354     EDMA3_DRV_Handle            hEdma;
1355     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1356 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1358         if (pDevExt->pParams == NULL)
1359                 return SIO2_EINVAL;
1361             if (pDevExt->pParams->sio.moduleNum == 0)
1362                 hEdma = hEdma0;
1363             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1364                 hEdma = hEdma1;
1366     // TODO: shouldn't this just be tcc interrupt disable?
1367     // at least until linkage phase...
1368     unsigned int key = Hwi_disable (); //DJDBG
1370     if(targetEdma == NULL)
1371     {
1372         Log_info0("targetEdma is NULL");
1373     }
1374     // configure transfer
1375     if(pFrame->addr == NULL) //DJDBG
1376     {
1377         Log_info0("pFrame has NULL address?");
1378     }
1379     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1381     if (parentEdma != EDMA_HINV)
1382         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1385     Hwi_restore (key); //DJDBG
1387     return SIO2_OK;
1388 } // SAP_setupXfer
1390 // -----------------------------------------------------------------------------
1391 // Configure EDMA3 parameter entry
1393 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1395     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1396     EDMA3_DRV_Handle            hEdma;
1397     EDMA3_DRV_PaRAMRegs  edmaConfig;
1399     if (pDevExt->pParams == NULL)
1400                 return SIO2_EINVAL;
1402         if (pDevExt->pParams->sio.moduleNum == 0)
1403                 hEdma = hEdma0;
1404         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1405                 hEdma = hEdma1;
1406     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1407    // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1409    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1411     // Init opt parameter to 0 which, without being overriden, configures as:
1412     //    A synchronized transfer (no FIFO mode on src or dst)
1413     //    no chaining or intermediate interrupts
1414     //    param is not static
1415     //    normal completion
1416     //    don't generate an interrupt (overriden below for regular xfers)
1417     edmaConfig.opt = 0;
1419     // not transferring blocks so c index is 0
1420     edmaConfig.destCIdx = 0;
1421     edmaConfig.srcCIdx = 0;
1423     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB); //DJDBG!
1424     if (device->mode == DEV2_OUTPUT) {
1425       //edmaConfig.opt |= EDMA3_DRV_OPT_DAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1426       edmaConfig.opt |= 2;
1427     }
1428     else {
1429         //edmaConfig.opt |= EDMA3_DRV_OPT_SAM_SET_MASK (EDMA3_DRV_ADDR_MODE_FIFO); //DJDBG!!!
1430         edmaConfig.opt |= 1;
1431     }
1433     // if regular transfer then enable interrupt with tcc code
1434     if (targetEdma != pDevExt->errorEdma) {
1435         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1436         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1437         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1438     }
1441     edmaConfig.aCnt = 4;
1442         edmaConfig.bCnt = pDevExt->numSers;
1443         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1444     edmaConfig.bCntReload = edmaConfig.bCnt;
1447     // handle direction specific requirements
1448     if (device->mode == DEV2_INPUT) {
1449         edmaConfig.srcBIdx  = 0;
1450                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1452         if (addr) {
1453             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1454             edmaConfig.destAddr = addr;
1455             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1456             if(pDevExt->edmaWordSize == 2)
1457                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1458         }
1459         else {
1460                 //if(pDevExt->edmaWordSize == 2)
1461                 //edmaConfig.srcAddr= (unsigned int)edmaConfig.srcAddr+ 2;
1462             edmaConfig.destBIdx = 0;
1463             edmaConfig.destAddr = (unsigned int) &sap_OVER_4LANE;
1464             edmaConfig.cCnt = 1;
1465         }
1466     }
1467     else {
1468         edmaConfig.destBIdx = 0;
1469         edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1470         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1471         if (addr) {
1472             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1473             edmaConfig.srcAddr  = addr;
1474             //Edma3_CacheFlush ((unsigned int) addr, (size+3)/4);
1475         }
1476         else {
1477             edmaConfig.srcBIdx  = 0;
1478             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1479 #if 1
1480             //edmaConfig.cCnt = (SAP_UNDER_LEN * sizeof(int))/(edmaConfig.aCnt * edmaConfig.bCnt); //DJDBG
1481             edmaConfig.cCnt = SAP_UNDER_LEN; //DJDBG, if underrun have frame of silence
1482 #endif
1483         }
1484     }
1485     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1486     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1488     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);
1489     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);
1491     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1493     // link child xfer
1494     if (childEdma != EDMA_HINV)
1495         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1497     return SIO2_OK;
1498 } //SAP_setupParam