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