]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_dsp/sap/sap.c
PASDK-284:Merge branch 'dev_pasdk_govind_pasdk284' of ssh://bitbucket.itg.ti.com...
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sap.c
2 /*
3 Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 //
37 //
38 // SIO driver implementation for audio I/O using McASP.
39 //
40 //
41 //
43 #ifndef SAP_CACHE_SUPPORT
44   // if you rebuild sap.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
69 #define EDMA_NUM_PARAMS 6
71 #include "sap_mcasp.h"
72 #include <pafsio.h>
74 // This works to set a breakpoint
75 #define SW_BREAKPOINT       asm( " SWBP 0" );
77 // global allocated in bios_edma3_drv_sample_init.c
78 extern EDMA3_DRV_Handle hEdma0;
79 extern EDMA3_DRV_Handle hEdma1;
81 // global variables for debug-assist
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 #pragma DATA_SECTION(sap_UNDER, ".sap_UNDER");
101 int sap_UNDER[SAP_UNDER_LEN]; // used for underrun
102 int sap_OVER_1LANE = 0;     // used for overrun
103 int sap_OVER_4LANE[4] = {0,0,0,0};      // used for overrun
105 #ifdef DEBUG
106 void SAP_EDMA_dumpParams(int tag_place)
108         //unsigned int *ptrPARAM_BASE = (unsigned int *)0x02704000;
109         unsigned int *ptrPARAM0x18 = (unsigned int *)0x02704300; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
110         //unsigned int *ptrPARAM0x19 = (unsigned int *)0x02704320; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
111         //unsigned int *ptrPARAM0x41 = (unsigned int *)0x027048A0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
112         //unsigned int *ptrPARAM0x42 = (unsigned int *)0x027048C0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
113         //unsigned int *ptrPARAM0x43 = (unsigned int *)0x027048E0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
114         //unsigned int *ptrPARAM0x48 = (unsigned int *)0x02704910; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[24]
115         unsigned int *ptrPARAM0x45 = (unsigned int *)0x027048A0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[69]
116         unsigned int *ptrPARAM0x46 = (unsigned int *)0x027048C0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[70]
117         unsigned int *ptrPARAM0x47 = (unsigned int *)0x027048E0; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[71]
118         unsigned int *ptrPARAM0x48 = (unsigned int *)0x02704900; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[72]
119         unsigned int *ptrPARAM0x49 = (unsigned int *)0x02704920; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[73]
120         unsigned int *ptrPARAM0x4A = (unsigned int *)0x02704940; // ((*((EDMA3_CCRL_Regs *) 0x02700000)).PARAMENTRY)[74]
122         //Log_info5("PARAM0x18a(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[0], ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3]);
123         //Log_info5("PARAM0x18b(%d): 0x%x 0x%x 0x%x 0x%x", tag_place, ptrPARAM0x18[4], ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
125         /*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));
126         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]);
127         Log_info4("PARAM0x19b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x19[5], ptrPARAM0x19[6], ptrPARAM0x19[7]);
129         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));
130         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]);
131         Log_info4("PARAM0x41b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x41[5], ptrPARAM0x41[6], ptrPARAM0x41[7]);
133         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));
134         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]);
135         Log_info4("PARAM0x42b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x42[5], ptrPARAM0x42[6], ptrPARAM0x42[7]);
137         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));
138         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]);
139         Log_info4("PARAM0x43b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x43[5], ptrPARAM0x43[6], ptrPARAM0x43[7]);
141         Log_info5("PARAM0x48a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x48[0] & 0x200000) >> 21), ((ptrPARAM0x48[0] & 0x100000) >> 20), ((ptrPARAM0x48[0] & 0x3F000) >> 12), ((ptrPARAM0x48[0] & 0x800) >> 11));
142         Log_info5("PARAM0x48b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x48[1], ptrPARAM0x48[2], ptrPARAM0x48[3], ptrPARAM0x48[4]);
143         Log_info4("PARAM0x48b(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x48[5], ptrPARAM0x48[6], ptrPARAM0x48[7]);*/
145         Log_info5("PARAM0x18a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x18[0] & 0x200000) >> 21), ((ptrPARAM0x18[0] & 0x100000) >> 20), ((ptrPARAM0x18[0] & 0x3F000) >> 12), ((ptrPARAM0x18[0] & 0x800) >> 11));
146         Log_info5("PARAM0x18b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x18[1], ptrPARAM0x18[2], ptrPARAM0x18[3], ptrPARAM0x18[4]);
147         Log_info4("PARAM0x18c(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x18[5], ptrPARAM0x18[6], ptrPARAM0x18[7]);
149         Log_info5("PARAM0x45a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x45[0] & 0x200000) >> 21), ((ptrPARAM0x45[0] & 0x100000) >> 20), ((ptrPARAM0x45[0] & 0x3F000) >> 12), ((ptrPARAM0x45[0] & 0x800) >> 11));
150         Log_info5("PARAM0x45b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x45[1], ptrPARAM0x45[2], ptrPARAM0x45[3], ptrPARAM0x45[4]);
151         Log_info4("PARAM0x45c(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x45[5], ptrPARAM0x45[6], ptrPARAM0x45[7]);
153         Log_info5("PARAM0x46a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x46[0] & 0x200000) >> 21), ((ptrPARAM0x46[0] & 0x100000) >> 20), ((ptrPARAM0x46[0] & 0x3F000) >> 12), ((ptrPARAM0x46[0] & 0x800) >> 11));
154         Log_info5("PARAM0x46b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x46[1], ptrPARAM0x46[2], ptrPARAM0x46[3], ptrPARAM0x46[4]);
155         Log_info4("PARAM0x46c(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x46[5], ptrPARAM0x46[6], ptrPARAM0x46[7]);
157         Log_info5("PARAM0x47a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x47[0] & 0x200000) >> 21), ((ptrPARAM0x47[0] & 0x100000) >> 20), ((ptrPARAM0x47[0] & 0x3F000) >> 12), ((ptrPARAM0x47[0] & 0x800) >> 11));
158         Log_info5("PARAM0x47b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x47[1], ptrPARAM0x47[2], ptrPARAM0x47[3], ptrPARAM0x47[4]);
159         Log_info4("PARAM0x47c(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x47[5], ptrPARAM0x47[6], ptrPARAM0x47[7]);
161         Log_info5("PARAM0x48a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x48[0] & 0x200000) >> 21), ((ptrPARAM0x48[0] & 0x100000) >> 20), ((ptrPARAM0x48[0] & 0x3F000) >> 12), ((ptrPARAM0x48[0] & 0x800) >> 11));
162         Log_info5("PARAM0x48b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x48[1], ptrPARAM0x48[2], ptrPARAM0x48[3], ptrPARAM0x48[4]);
163         Log_info4("PARAM0x48c(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x48[5], ptrPARAM0x48[6], ptrPARAM0x48[7]);
165         Log_info5("PARAM0x49a(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x49[0] & 0x200000) >> 21), ((ptrPARAM0x49[0] & 0x100000) >> 20), ((ptrPARAM0x49[0] & 0x3F000) >> 12), ((ptrPARAM0x49[0] & 0x800) >> 11));
166         Log_info5("PARAM0x49b(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x49[1], ptrPARAM0x49[2], ptrPARAM0x49[3], ptrPARAM0x49[4]);
167         Log_info4("PARAM0x49c(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x49[5], ptrPARAM0x49[6], ptrPARAM0x49[7]);
169         Log_info5("PARAM0x4Aa(%d): ITCINTEN: 0x%02x, TCINTEN: 0x%02x, TCC: 0x%02x, TCCMODE: %d", tag_place, ((ptrPARAM0x4A[0] & 0x200000) >> 21), ((ptrPARAM0x4A[0] & 0x100000) >> 20), ((ptrPARAM0x4A[0] & 0x3F000) >> 12), ((ptrPARAM0x4A[0] & 0x800) >> 11));
170         Log_info5("PARAM0x4Ab(%d): SRC: 0x%08x, A_B_CNT: 0x%08x, DST: 0x%08x,  SRC_DST_BIDX: 0x%08x", tag_place, ptrPARAM0x4A[1], ptrPARAM0x4A[2], ptrPARAM0x4A[3], ptrPARAM0x4A[4]);
171         Log_info4("PARAM0x4Ac(%d): LINK_BCNTRLD: 0x%08x, SRC_DST_CIDX: 0x%08x, CCNT: 0x%08x", tag_place, ptrPARAM0x4A[5], ptrPARAM0x4A[6], ptrPARAM0x4A[7]);
173         Log_info1("TCC0: ERR reg %x", *((unsigned int *)0x02760120));
175 #endif
176 // .............................................................................
177 // notes:
178 //  . add control function to PORT table
179 //  . how to handle DMA/PORT specifics in parameter entries
180 //      can assume numSers = numChans is general and can be applied by DMA
181 //      same for wordSize?
182 //  . why are two idle stages needed (seems like 1 is enough)?
184 // .............................................................................
185 // only one global variable, not static so that DMA and port functions
186 // can access. We cant just store the address in devExt since the ISR has
187 // no context.
189 SAP_DriverObject sapDrv;
191 // needed since SAP_watchDog is called before SAP_init
192 Int SAP_initialized = 0;
194 Int  SAP_ctrl(DEV2_Handle, Uns, Arg);
195 Int  SAP_idle(DEV2_Handle, Bool);
196 Int  SAP_issue(DEV2_Handle);
197 Int  SAP_open(DEV2_Handle, String);
198 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context);
199 Int  SAP_reclaim(DEV2_Handle);
200 Int  SAP_shutdown(DEV2_Handle);
201 Int  SAP_start(DEV2_Handle);
202 Int  SAP_config(DEV2_Handle device, const SAP_Params *pParams);
203 Int  SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size);
204 Int  SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame);
206 // .............................................................................
208 // .............................................................................
210 SAP_DMA_Fxns SAP_EDMA_FXNS =
212         SAP_EDMA_setupParam,
213         SAP_EDMA_setupXfer,
214 };
217 SAP_Fxns SAP_FXNS =
219     NULL, //SAP_close, -- remove for IROM since not using
220     SAP_ctrl,
221     SAP_idle,
222     SAP_issue,
223     SAP_open,
224     NULL, //SAP_ready, -- remove for IROM since not using
225     SAP_reclaim,
226     SAP_shutdown,
227     SAP_start,
228     SAP_config,
230 #ifdef SAP_PORT_MCASP
231     (SAP_PORT_Fxns *) &SAP_MCASP_FXNS,
232 #endif
233 #ifdef SAP_DMA_EDMA
234     (SAP_DMA_Fxns *) &SAP_EDMA_FXNS,
235 #endif
236 };
238 // -----------------------------------------------------------------------------
239 // This function is not in the driver function table.
240 // Must be pointed at in GUI config tool.
241 //
242 Void SAP_init (Void)
244     DEV2_Device  *entry;
245     SAP_Fxns    *pFxns;
247     //TRACE_GEN((&TR_MOD, "SAP_init.%d", __LINE__));
249     // find function table pointer (used by SAP_XX_FTABLE_init macros)
250     DEV2_match(SAP_NAME, &entry);
251     if (entry == NULL) {
252         Log_error1 ("SAP", SIO2_ENODEV);
253         return;
254     }
255     pFxns = (SAP_Fxns *) entry->fxns;
257     //SAP_DMA_FTABLE_init ();
258     SAP_PORT_FTABLE_init ();
260     sapDrv.numDevices = 0;
261     SAP_initialized = 1;
263     return;
264 } // SAP_init
266 // -----------------------------------------------------------------------------
268 int gSapInput_ControlOpen = 0;
269 int gSapOutput_ControlOpen = 0;
271 int gSapInput_ControlClose = 0;
272 int gSapOutput_ControlClose = 0;
274 Int SAP_ctrl (DEV2_Handle device, Uns code, Arg arg)
276     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
277     const SAP_Params *pParams;
278     Int i, result = SIO2_OK;
279     EDMA3_DRV_Handle    hEdma;
280     //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d (0x%x) code = 0x%x", __LINE__, device, code));
282     switch (code) {
284 /* .......................................................................... */
286         case PAF_SIO_CONTROL_MUTE:
287         case PAF_SIO_CONTROL_UNMUTE:
288             pParams = pDevExt->pParams;
289             if (pParams == NULL)
290                 return SIO2_OK;
292             if (pParams->sio.control != NULL)
293                 result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
294             break;
296 /* .......................................................................... */
298         case PAF_SIO_CONTROL_OPEN:
299             if (pDevExt->runState)
300                 return SIO2_EBUSY;
302             if (!( pParams = (const SAP_Params *) arg ))
303                 return SIO2_OK;
305             if(device->mode == DEV2_OUTPUT)
306                 gSapOutput_ControlOpen++;
307             else
308                 gSapInput_ControlOpen++;
310             if (result = SAP_FTABLE_config (device, pParams))
311                 return result;
313             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
314                 return result;
316             break;
318 /* .......................................................................... */
320         case PAF_SIO_CONTROL_CLOSE:
321             if (pDevExt->runState)
322                 return SIO2_EBUSY;
324             if (pDevExt->pParams == NULL)
325                                 return SIO2_EINVAL;
327             pParams = pDevExt->pParams;
329                         if (pParams->sio.moduleNum == 0)
330                                 hEdma = hEdma0;
331                         else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
332                                 hEdma = hEdma1;
334             if (pDevExt->activeEdma != EDMA_HINV) {
335                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->activeEdma);
336                                 pDevExt->activeEdma = EDMA_HINV;
337                         }
339             if(device->mode == DEV2_INPUT)
340                 gSapInput_ControlClose++;
341             else
342                 gSapOutput_ControlClose++;
344             for (i=0; i < pDevExt->numEdmaParams; i++) {
345                 if (pDevExt->edmaParams[i].hEdmaParam != EDMA_HINV)
346                 {
347                         EDMA3_DRV_freeChannel (hEdma, pDevExt->edmaParams[i].hEdmaParam);
348                         pDevExt->edmaParams[i].hEdmaParam = EDMA_HINV;
349                 }
350             }
352             if (pDevExt->errorEdma != EDMA_HINV) {
353                                 EDMA3_DRV_freeChannel (hEdma, pDevExt->errorEdma);
354                                 pDevExt->errorEdma = EDMA_HINV;
355                         }
357             if (!(pParams = pDevExt->pParams))
358                 return SIO2_OK;
360             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
361                 return result;
363             result = SAP_PORT_FTABLE_close (device);
364             if (result)
365                 return result;
367             pDevExt->pParams = NULL;
368             break;
370 /* .......................................................................... */
372         case PAF_SIO_CONTROL_GET_WORDSIZE:
373                 if (!arg)
374                                 return SIO2_EINVAL;
375                         *((int *) arg) = pDevExt->edmaWordSize;
376             break;
378         case PAF_SIO_CONTROL_SET_WORDSIZE:
379             // defer to DMA processing
380                 // currently only supported for input
381                         if (device->mode != DEV2_INPUT)
382                                 return SIO2_EINVAL;
384                         // can't be running
385                         if (pDevExt->runState)
386                                 return SIO2_EBUSY;
388                         // driver only supports 2 or 4 bytes
389                    if ((arg != 2) && (arg != 4))
390                                 return SIO2_EINVAL;
392                         // return success for unconfigured devices?
393                         if (!pDevExt->pParams)
394                                 return SIO2_OK;
396                         // ask platform if size is supported
397                         pParams = pDevExt->pParams;
398                         if (pDevExt->pParams->sio.control && (result = pDevExt->pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
399                                 return result;
401                         pDevExt->edmaWordSize = arg;
402                         break;
404         case PAF_SIO_CONTROL_GET_PRECISION:
405             if (arg == 0)
406                 return SIO2_EINVAL;
408             pParams = pDevExt->pParams;
409             if (pParams == NULL)
410                 return( SIO2_EINVAL );
412             *((int *) arg) = pParams->sio.precision;
413             break;
415         case PAF_SIO_CONTROL_GET_NUMCHANNELS:
416             if (arg == 0)
417                 return SIO2_EINVAL;
419             *((int *) arg) = pDevExt->numSlots * pDevExt->numSers;
420             break;
422         case PAF_SIO_CONTROL_SET_RATEX:
423             pParams = pDevExt->pParams;
424             if (pParams == NULL)
425                 return SIO2_OK ;
427             if (pParams->sio.control == NULL)
428                 return SIO2_EINVAL;
430             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_SET_RATEX, arg);
431             break;
433 /* .......................................................................... */
435         case PAF_SIO_CONTROL_IDLE:
436             pParams = pDevExt->pParams;
437             if (pParams == NULL)
438                 return SIO2_OK ;
440             if (pParams->sio.control == NULL)
441                 return SIO2_EINVAL;
443             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, PAF_SIO_CONTROL_IDLE, arg);
444             break;
446         case PAF_SIO_CONTROL_IDLE_WITH_CLOCKS:
447             // 1. Here we are intentionally not using SIO_Idle() and
448             //    leaving the Tx clock running. We need this to avoid DAC noise,
449             //    as well as provide a DIT clock when using digital output.
450             if (device->mode != DEV2_OUTPUT || pDevExt->pParams == NULL)
451                 return SIO2_EINVAL;
453             pParams = pDevExt->pParams;
455             if (pParams->sio.moduleNum == 0)
456                 hEdma = hEdma0;
457             else if (pParams->sio.moduleNum == 1 || pParams->sio.moduleNum == 2)
458                                 hEdma = hEdma1;
460             result = SAP_FTABLE_shutdown (device);
461             if (result)
462                 return result;
464             Log_info0 ("SAP PAF_SIO_CONTROL_IDLE_WITH_CLOCKS; PAF_SIO_ERROR_IDLE_STAGE1");
465             pDevExt->errorState = PAF_SIO_ERROR_IDLE_STAGE1;
467             if (pDevExt->activeEdma != EDMA_HINV)
468                 EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
470             //TRACE_GEN((&TR_MOD, "SAP_ctrl.%d: (0x%x) errorState = PAF_SIO_ERROR_IDLE_STAGE1 0x%x.", __LINE__, device, PAF_SIO_ERROR_IDLE_STAGE1));
472             break;
474 /* .......................................................................... */
476         case PAF_SIO_CONTROL_GET_INPUT_STATUS:
477             // needs to be attached
478             pParams = pDevExt->pParams;
479             if (pParams == NULL)
480                 return SIO2_OK;
482             if (pParams->sio.control == NULL)
483                 return SIO2_EINVAL;
485             result = pParams->sio.control( device, (const PAF_SIO_Params *)pParams, code, arg );
486             break;
488         case PAF_SIO_CONTROL_WATCHDOG:
489             pParams = pDevExt->pParams;
490             if (pParams == NULL)
491                 return SIO2_OK;
492             if (pParams->sio.control && (result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg)))
493                 return result;
494             break;
495             
496 /* .......................................................................... */
498         // Timing stats specific to DMA engine
499         case PAF_SIO_CONTROL_ENABLE_STATS:
500         case PAF_SIO_CONTROL_DISABLE_STATS:
501         case PAF_SIO_CONTROL_GET_STATS:
502         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
503         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
504             //result = SAP_DMA_FTABLE_ctrl (device, code, arg);
505             // TRACE_VERBOSE((&TR_MOD, "SAP_ctrl: (0x%x) code 0x%x.  result 0x%x.", device, code, result));
506             break;
508 /* .......................................................................... */
510         case PAF_SIO_CONTROL_SET_DITSTATUS:
511             if(device->mode == DEV2_OUTPUT)
512             {
513                 const SAP_Params *pParams = pDevExt->pParams;
514                 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
515                 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
516                 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
517                 int encSelect = *((int *) arg);
519                 // HACK -- determine DIT need by FXWID
520                 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
521                 {
522                     if ( (encSelect == 0x13) ||
523                          (encSelect == 0xa)  || 
524                          (encSelect == 0x6)) // DTE, DDE, MPE 
525                     {
526                         base[_MCASP_DITCSRA0_OFFSET] |= 2;
527                         base[_MCASP_DITCSRB0_OFFSET] |= 2;
528                     }
529                     else
530                     {
531                         base[_MCASP_DITCSRA0_OFFSET] &= 0xfffffffd;
532                         base[_MCASP_DITCSRB0_OFFSET] &= 0xfffffffd;
533                     }
534                 }
536                 pParams = pDevExt->pParams;
537                 if (pParams == NULL)
538                     return SIO2_OK;
540                 if (pParams->sio.control != NULL)
541                     result = pParams->sio.control (device, (const PAF_SIO_Params *)pParams, code, arg);
542             }
543             break;
545 /* .......................................................................... */
547     }
549     return result;
550 } // SAP_ctrl
552 int gSAPIdleShutdownIn=0;
553 int gSAPIdleShutdownOut=0;
555 // -----------------------------------------------------------------------------
557 Int SAP_idle (DEV2_Handle device, Bool flush)
559     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
560     Int result = SIO2_OK;
561     EDMA3_DRV_Handle hEdma;
563     // do nothing if already idled or unattached
564     if ((!pDevExt->runState) || (pDevExt->pParams == NULL))
565         return result;
567         if (pDevExt->pParams->sio.moduleNum == 0)
568                 hEdma = hEdma0;
569         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
570                 hEdma = hEdma1;
572     // reset serial port -- stop generating sync events
573     result = SAP_PORT_FTABLE_reset (device);
574     if(device->mode == DEV2_OUTPUT)
575         gSAPResetOut++;
576     else
577         gSAPResetIn++;
578     if (result)
579     {
580         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
581         return result;
582     }
584     pDevExt->shutDown = 0; // force shutdown to run
585     result = SAP_FTABLE_shutdown (device);
586     if(device->mode == DEV2_OUTPUT)
587         gSAPIdleShutdownOut++;
588     else
589         gSAPIdleShutdownIn++;
591     if (result)
592     {
593         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_FTABLE_shutdown returned %d.\n", __FUNCTION__, __LINE__, result));
594         return result;
595     }
597     Log_info0("SAP_idle:Before EDMA3_DRV_disableTransfer");
599     // disable interrupts and EDMA servicing
600    if (pDevExt->activeEdma != EDMA_HINV)
601            EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
603    Log_info0("SAP_idle:Before pDevExt->numQueued = 0");
604    pDevExt->numQueued = 0;
606     // signal stopped
607     pDevExt->runState = 0;
608     Log_info0("SAP_idle: runState = 0");
610     // reset errorState
611     pDevExt->errorState = PAF_SIO_ERROR_NONE;
612     //TRACE_VERBOSE((&TR_MOD, "SAP_ctrl.%d: errorState = PAF_SIO_ERROR_NONE 0x%x.", __LINE__, PAF_SIO_ERROR_NONE));
614     // place call to physical device
615     if ((pDevExt->pParams != NULL) && (pDevExt->pParams->sio.control != NULL))
616         result = pDevExt->pParams->sio.control(device, (const PAF_SIO_Params *)pDevExt->pParams, PAF_SIO_CONTROL_IDLE, 0);
618     return result;
619 } // SAP_idle
621 // -----------------------------------------------------------------------------
623 Int SAP_start (DEV2_Handle device)
625     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
626     DEV2_Frame *pFrame;
627     int result;
628     EDMA3_DRV_Handle hEdma;
630     Log_info2("SAP_start.%d (0x%x)", __LINE__, (xdc_IArg)device);
632     // Assume todevice queue is not empty -- how else could we be here?
633     pFrame = (DEV2_Frame *) Queue_get (device->todevice);
635     // inidicate this xfer did not use param entry - just the active one
636     pFrame->misc = NULL;
637     if (pDevExt->pParams->sio.moduleNum == 0)
638         hEdma = hEdma0;
639     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
640                 hEdma = hEdma1;
642     // non-atomic functions since not running yet.
643     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *)pFrame);
645     // initialize count
646     pDevExt->numQueued = 1;
648     result = SAP_PORT_FTABLE_reset (device);
649     if (result)
650     {
651         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_reset returned %d.\n", __FUNCTION__, __LINE__, result));
652         return result;
653     }
655     // enable DMA processing
656     if (device->mode == DEV2_OUTPUT)
657         Log_info3("SAP_start.%d, pDevExt->activeEdma 0x%x (pDevExt->errorEdma = 0x%x)",
658                             __LINE__, pDevExt->activeEdma, pDevExt->errorEdma);
659     // config active xfer for this buffer
660     result = SAP_EDMA_setupXfer(device, pDevExt->activeEdma, EDMA_HINV, pDevExt->errorEdma, pFrame);
663         // signal we have started -- this must come before last enable to prevent a race
664         // condition where the initial EDMA transfer is very small (e.g. due to startClocks)
665         // and completes before any further instructions in this thread are executed.
666         // This comes before the EDMA enable since, if the # of samples is 1, then the EDMA
667         // will be serviced and generate an interrupt even before the McASP is enabled.
668     pDevExt->runState = 1;
669     pDevExt->shutDown = 0;
670     if (device->mode == DEV2_OUTPUT)
671         Log_info2 ("SAP: %d, SAP_start runState=1 & ENABLE TRANSFERS for activeEdma = 0x%x", __LINE__, pDevExt->activeEdma);
672         // enable interrupts and event servicing for this channel
673         EDMA3_DRV_enableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
675     // enable peripheral
676     result = SAP_PORT_FTABLE_enable (device);
678     if (result)
679     {
680         //TRACE_VERBOSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_enable returned %d.\n", __FUNCTION__, __LINE__, result));
681         return result;
682     }
684     return SIO2_OK;
685 } // SAP_start
687 int gDmaParamsarray[17][3];
688 int gDmaParamsidx=0, gSAPSpecialCase=0;
689 // -----------------------------------------------------------------------------
691 Int SAP_issue (DEV2_Handle device)
693     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
694     DEV2_Frame *pFrame;
695     Int result;
696     SAP_EDMA_Param *pParam;
697     XDAS_UInt32 parentEdma;
699     if (device->mode == DEV2_OUTPUT)
700         Log_info3("SAP_issue for output device with pDevExt->errorState = 0x%x, pDevExt->runState = 0x%x, pDevExt->numQueued = 0x%x", pDevExt->errorState, pDevExt->runState, pDevExt->numQueued);
702     if ((device->mode == DEV2_OUTPUT) && (pDevExt->errorState >= PAF_SIO_ERROR_ERRBUF_XFER))
703     {
704         /*TRACE_TERSE((&TR_MOD, "SAP_issue.%d, errorState 0x%x (PAF_SIO_ERROR_ERRBUF_XFER = 0x%x)",
705             __LINE__, pDevExt->errorState, PAF_SIO_ERROR_ERRBUF_XFER));*/
706         Log_info3("SAP_issue.%d, PAF_SIO_ERROR_ERRBUF_XFER = 0x%x, mode = 0x%x)",
707                 __LINE__, PAF_SIO_ERROR_ERRBUF_XFER, device->mode );
708         return SIO2_EBADIO;
709     }
711     if ((device->mode == DEV2_INPUT) && pDevExt->errorState)
712         {
713                 Log_info1("SAP_issue: Input Error Trap, with errorState = 0x%x", pDevExt->errorState);
714             return SIO2_EBADIO;
715         }
717     // if not yet running then configure active xfer and start
718     if (pDevExt->runState == 0)
719         return (SAP_FTABLE_start(device));
721     // .........................................................................
722     // here if running
724     // disable device interrupts
725     // TODO: is there an API to just disable the IER bit for this tcc?
726     unsigned int key = Hwi_disable ();
727        /* determine parent EDMA
728           if no xfers in queue and we are running then must be in the
729           error state so link to active channel otherwise link to last
730           transfer queued.
731        */
733        /* here we assume after Tx SIO_idle or overrun, the user
734           will issue, at least, back-to-back issue requests so
735           there should be no problem here.
736        */
737        if ((pDevExt->numQueued <= 1) && (pDevExt->errorState != 2))
738            parentEdma = pDevExt->activeEdma;
739        else {
740            // if here then xferQue has more than one element so ok to use tail
741            // last scheduled transfer must be queue->prev
742            DEV2_Frame *tail = (DEV2_Frame *) Queue_prev ((Queue_Elem *)&pDevExt->xferQue);
743            parentEdma = ((SAP_EDMA_Param *) tail->misc)->hEdmaParam;
744        }
746        //if (device->mode == DEV2_OUTPUT)
747            Log_info2("SAP_issue: Determined Parent = 0x%x for device = 0x%x", parentEdma, device->mode );
749     // get frame and parameter table to use; ints off => non-atomic OK
750     //     dont need to check for empty queues since were here then todevice
751     //     must have a frame placed there by the SIO_issue layer.
752     //     paramQue must be valid since it is accessed the same as todevice.
753     //     (indirectly -- isr places used items onto paramQue and fromdevice que
754     //      at the same time)
755     // set misc argument to pParam so get enqueue later
756     //pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
757     pFrame = Queue_dequeue (device->todevice);
758     pParam = (SAP_EDMA_Param *) Queue_dequeue (Queue_handle(&pDevExt->paramQue));
760     if (pParam->hEdmaParam == NULL)
761         Log_info1("SAP_issue: hEdma value is NULL for device = 0x%x", device->mode);
762     // set misc argument to pParam so get enqueue later
763     pFrame->misc = (Arg) pParam;
765     // place on holder queue, ints off => non-atomic OK
766     Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
767     if (pFrame->addr) {
768                 if (device->mode == DEV2_INPUT)
769                         Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
770                 else
771                         Cache_wbInv (pFrame->addr, pFrame->size, Cache_Type_ALL, TRUE);
772         }
774     // increment count
775     pDevExt->numQueued += 1;
777     result = SAP_EDMA_setupXfer (device, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma, pFrame);
778     if (device->mode == DEV2_OUTPUT)
779     {
780         Log_info4("SAP_issue.%d, EDMA_setupXfer: Target EDMA: 0x%x, Parent Edma: 0x%x Error Edma: 0x%x",
781                             __LINE__, pParam->hEdmaParam, parentEdma, pDevExt->errorEdma);
782     }
784         if ((pDevExt->errorState == PAF_SIO_ERROR_IDLE_STAGE1) && (device->mode == DEV2_OUTPUT))
785                 pDevExt->errorState = PAF_SIO_ERROR_NONE;
787         pDevExt->shutDown = 0;
789     // special case enables when not yet started
790     if (pDevExt->runState == 0) {
791         gSAPSpecialCase++;
792         result = SAP_FTABLE_start (device);
793         if (result) {
794                   Hwi_restore (key);
795             return result;
796         }
797     }
798     Hwi_restore (key);
800     return result;
801 } // SAP_issue
803 // -----------------------------------------------------------------------------
805 void swapHdmi(Ptr Input, int size)
808         MdInt L0, L1, L2, L3, R0, R1, R2, R3 = 0;
809         MdInt *p1, *p2;
810         int i=0;
812         for (i=0; i< size; i+=16)
813         {
814                         p1 = (MdInt *)&Input[i];
815                         p2 = p1;
817                         L0 = *p1++;
818                         L1 = *p1++;
819                         L2 = *p1++;
820                         L3 = *p1++;
821                         R0 = *p1++;
822                         R1 = *p1++;
823                         R2 = *p1++;
824                         R3 = *p1++;
826                         *p2++ = L0;
827                         *p2++ = R0;
828                         *p2++ = L1;
829                         *p2++ = R1;
830                         *p2++ = L2;
831                         *p2++ = R2;
832                         *p2++ = L3;
833                         *p2++ = R3;
835         }
837         Log_info3("SAP: Exiting swapHdmi with Frame->Addr: 0x%x, p1->addr: 0x%x, p2->addr: 0x%x ", (xdc_IArg)Input, (xdc_IArg)p1, (xdc_IArg)p2);
839         return;
842 Int SAP_reclaim (DEV2_Handle device)
844     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
845 #ifdef SAP_CACHE_SUPPORT
846     DEV2_Frame *pFrame;
847 #endif
849     //TRACE_GEN((&TR_MOD, "SAP_reclaim.%d (0x%x)", __LINE__, device));
850     if (device->mode == DEV2_OUTPUT)
851                 Log_info3("SAP_reclaim for output device with pDevExt->errorState = 0x%x, runState: 0x%x & pDevExt->numQueued = 0x%x", pDevExt->errorState, pDevExt->runState, pDevExt->numQueued);
852     // must be running and  error free 
853     if ((!pDevExt->runState) || (pDevExt->errorState))
854     {
855         Log_info3("SAP_reclaim.%d, error-state: 0x%x, mode = 0x%x", __LINE__, pDevExt->errorState, device->mode);
856         return SIO2_EBADIO;
857     }
859     Log_info1("SAP_reclaim: Before SEM Pend for mode: 0x%x", device->mode);
861     // wait for ISR to signal block completion
862     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d wait for ISR to signal block completion", __LINE__));
863     if (!Semaphore_pend(pDevExt->sync, device->timeout))
864     {
865         Log_info0("SAP_reclaim, SYS_ETIMEOUT");
866         return SIO2_ETIMEOUT;
867     }
868     Log_info1("SAP_reclaim: After SEM Pend for mode: 0x%x", device->mode);
870     // return error (owner must idle)
871     if (pDevExt->errorState == PAF_SIO_ERROR_FATAL)
872     {
873         DEV2_idle (device, 1);
874         Log_info2("SAP_reclaim.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState);
875         return PAF_SIO_ERROR_FATAL;
876     }
878 #ifdef SAP_CACHE_SUPPORT
879     // invalidate CACHE region if input -- use clean since
880     //    Dont clean if was for fill.
881     // since pend returned we know that head of fromdevice is valid
882     pFrame = Queue_head (device->fromdevice);
883     Log_info2("SAP: Inside SAP_Reclaim with From Device Frame->Addr: 0x%x and Frame->Size: %d", (xdc_IArg)pFrame->addr, pFrame->size);
884     if ((device->mode == DEV2_INPUT) && (pFrame->addr != NULL))
885     {
886         if(pDevExt->edmaWordSize == 2 && pDevExt->numSers == 4)
887         {
888             Cache_inv (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
889             Cache_wait();
891             // max HWI disable duration ~1ms observed
892             //unsigned int key = Hwi_disable ();                    // GJ: Revisit, along with other context protections here.
893             swapHdmi(pFrame->addr, pFrame->size);
894             //Hwi_restore(key);
896             Cache_wb (pFrame->addr, pFrame->size, Cache_Type_ALL, 0);
897             Cache_wait();
898         }
899     }
901 #endif
902     /*if ((device->mode == DEV2_OUTPUT) && (pFrame->addr == NULL))
903         SW_BREAKPOINT; */
905     Log_info1("SAP_reclaim: Exiting with SIO2_OK for device 0x%x  ", device->mode);
906     //TRACE_VERBOSE((&TR_MOD, "SAP_reclaim.%d, exit SIO2_OK", __LINE__));
907     return SIO2_OK;
908 } // SAP_reclaim
911 // -----------------------------------------------------------------------------
913 Int SAP_open (DEV2_Handle device, String name)
915     SAP_DeviceExtension   *pDevExt;
916     DEV2_Device            *entry;
917     Int                    oldMask, result;
918     Error_Block                         eb;
919     //TRACE_GEN((&TR_MOD, "SAP_open.%d (0x%x)", __LINE__, device));
921     // check SIO mode 
922     if ((device->mode != DEV2_INPUT) && (device->mode != DEV2_OUTPUT))
923         return SIO2_EMODE;
925     // allocate memory for device extension
926     device->object = NULL;
927     pDevExt = (SAP_DeviceExtension *) Memory_alloc (device->bufSeg, (sizeof(SAP_DeviceExtension)+3)/4*4, 4, &eb);
928     if (pDevExt == NULL)
929     {
930         printf("%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__);
931         //TRACE_TERSE((&TR_MOD, "%s.%d:  MEM_alloc failed.\n", __FUNCTION__, __LINE__));
932         asm( " SWBP 0" );  // SW Breakpoint
933         return SIO2_EALLOC;
934     }
935     device->object = (Ptr)pDevExt;
937     // inits
938     pDevExt->device = device;
939     pDevExt->sync = NULL;
940     pDevExt->pParams = NULL;
941     pDevExt->runState = 0;  // not yet started
942     pDevExt->errorState = PAF_SIO_ERROR_NONE;
943     pDevExt->shutDown = 1;
944     pDevExt->numQueued = 0;
945     pDevExt->activeEdma = EDMA_HINV;
946     pDevExt->errorEdma = EDMA_HINV;
947     pDevExt->firstTCC = 0;
948     pDevExt->optLevel = 0;
949     pDevExt->numParamSetup = 0;
950     pDevExt->numEdmaParams = EDMA_NUM_PARAMS;           // We need more than 4 spare params to handle the immediate transition from Unknown
951                                                                                                 // to a Known program. Cheap resource to spend.
953     // use dev match to fetch function table pointer for SAP
954     DEV2_match(SAP_NAME, &entry);
955     if (entry == NULL) {
956         Log_error1("SAP", SIO2_ENODEV);
957         return SIO2_ENODEV;
958     }
959     pDevExt->pFxns = (SAP_Fxns *) entry->fxns;
961     // create semaphore for device
962     pDevExt->sync = Semaphore_create (0, NULL, NULL);
963     if (pDevExt->sync == NULL)
964     {
965         //TRACE_TERSE((&TR_MOD, "%s.%d: create semaphore for device failed.\n", __FUNCTION__, __LINE__));
966         return SIO2_EALLOC;
967     }
969     // queue inits
970     Queue_construct (&pDevExt->xferQue, NULL);
971     Queue_construct (&pDevExt->paramQue, NULL);
973     // update driver global (need to protect context)
974     if (sapDrv.numDevices >= MAX_SAP_DEVICES)
975     {
976         /*TRACE_TERSE((&TR_MOD, "%s.%d: add device failure: no. of devices = %d; need to increase MAX_SAP_DEVICES.\n",
977             __FUNCTION__, __LINE__, dapDrv.numDevices));*/
978         SW_BREAKPOINT;
979     }
980     oldMask = Hwi_disable ();
981     sapDrv.device[sapDrv.numDevices] = device;
982     pDevExt->deviceNum = sapDrv.numDevices++;
983     Hwi_restore (oldMask);
985     // PORT init
986     result = SAP_PORT_FTABLE_open (device);
987     if (result)
988     {
989         //TRACE_TERSE((&TR_MOD, "%s.%d: SAP_PORT_FTABLE_open returned %d.\n", __FUNCTION__, __LINE__, result));
990         return result;
991     }
993     return result;
994 } // SAP_open
996 // -----------------------------------------------------------------------------
998 Int SAP_config (DEV2_Handle device, const SAP_Params *pParams)
1000     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1001     Int                  result, Que_num, i;
1002     EDMA3_DRV_Result     edmaResult;
1003     Uint32                                      reqTcc;
1004     EDMA3_DRV_Handle    hEdma;
1005     Log_info2("SAP_config.%d (0x%x)", __LINE__, (xdc_IArg)device);
1007     // cannot configure if transfer started
1008     if (pDevExt->runState == 1)
1009         return SIO2_EBADIO;
1011     // save pointer to config structure in device extension. here so that
1012     //   forthcoming functions can use/modify config structure.
1013     pDevExt->pParams = pParams;
1014     pDevExt->edmaWordSize = pParams->sio.wordSize;
1016     // allocate Port resources.
1017     //    This must come before DMA configuration
1018     result = SAP_PORT_FTABLE_alloc (device);
1019     if (result)
1020     {
1021         Log_info3("%s.%d: SAP_PORT_FTABLE_alloc returned %d.\n", (xdc_IArg) __FUNCTION__, __LINE__, result);
1022         return result;
1023     }
1025     // .............................................................................
1026     // EDMA configuration
1028     // DA10x McASP0 Specific
1029     if (pParams->sio.moduleNum == 0)
1030     {
1031         hEdma = hEdma0;
1032         if (device->mode == DEV2_INPUT)
1033         {
1034                 Que_num = 0;
1035                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_REVT;
1036         }
1037         else
1038         {
1039                 Que_num = 0;
1040                 pDevExt->activeEdma = CSL_EDMACC_0_McASP_0_XEVT;
1041         }
1042     }
1043     // DA10x McASP1 Specific
1044     else if (pParams->sio.moduleNum == 1)
1045     {
1046         hEdma = hEdma1;
1047         if (device->mode == DEV2_INPUT)
1048                 {
1049                 Que_num = 0;
1050                 pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_REVT;
1051                 }
1052                 else
1053                 {
1054                         Que_num = 0;
1055                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_1_XEVT;
1056                 }
1057     }
1058     // DA10x McASP2 Specific
1059     else if (pParams->sio.moduleNum == 2)
1060     {
1061         hEdma = hEdma1;
1062         if (device->mode == DEV2_INPUT)
1063                 {
1064                         Que_num = 0;
1065                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_REVT;
1066                 }
1067                 else
1068                 {
1069                         Que_num = 0;
1070                         pDevExt->activeEdma = CSL_EDMACC_1_McASP_2_XEVT;
1071                 }
1072     }
1075     for (i=0; i < pDevExt->numEdmaParams; i++) {
1077         reqTcc = EDMA3_DRV_TCC_ANY;
1078         pDevExt->edmaParams[i].hEdmaParam = EDMA3_DRV_LINK_CHANNEL;
1079         edmaResult = EDMA3_DRV_requestChannel (
1080                 hEdma,
1081             &pDevExt->edmaParams[i].hEdmaParam,
1082             &reqTcc,
1083             (EDMA3_RM_EventQueue) Que_num,
1084             SAP_isrCallback,
1085             (void *) device);
1087         if (edmaResult != EDMA3_DRV_SOK)
1088             return SIO2_EALLOC;
1090         //not running => can use non-atomic functions
1091         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *)&pDevExt->edmaParams[i]);
1093     }
1095     reqTcc = EDMA3_DRV_TCC_ANY;
1096         pDevExt->errorEdma = EDMA3_DRV_LINK_CHANNEL;
1097         edmaResult = EDMA3_DRV_requestChannel (
1098             hEdma,
1099             &pDevExt->errorEdma,
1100             &reqTcc,
1101             (EDMA3_RM_EventQueue)Que_num,
1102             SAP_isrCallback,
1103             (void *) device);
1104         if (edmaResult != EDMA3_DRV_SOK)
1105             return SIO2_EALLOC;
1107         // allocate edma channel -- also disable and clear the interrupt
1110         pDevExt->firstTCC = pDevExt->activeEdma ;
1111         edmaResult = EDMA3_DRV_requestChannel (
1112                 hEdma,
1113                 &pDevExt->activeEdma,
1114                 &pDevExt->firstTCC,
1115                 (EDMA3_RM_EventQueue) 0,
1116                 SAP_isrCallback,
1117                 (void *) device);
1118         if (edmaResult != EDMA3_DRV_SOK)
1119                     {
1120                         Log_info3("%s.%d: SAP_DMA_FTABLE_alloc returned %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, edmaResult);
1121                         return SIO2_EALLOC;
1122                     }
1124         // Configure error transfer
1125         //   make cnt same as # of channels in order to maintain alignment
1126         //   and the error transfer small so that we never have to wait
1127         //   long for it to complete and trigger a linked transfer. This is
1128         //   important for establishing output timing when we are idling with
1129         //   clocks still running. Is fine for Rx as well.
1130         result = SAP_DMA_FTABLE_setupParam (device, pDevExt->errorEdma, pDevExt->errorEdma, NULL, pDevExt->edmaWordSize * pDevExt->numSers);
1132         Log_info3("%s.%d: Exiting SAP_alloc for %d.\n", (xdc_IArg)__FUNCTION__, __LINE__, pDevExt->activeEdma);
1134     return SIO2_OK;
1135 } // SAP_config
1137 // -----------------------------------------------------------------------------
1139 Int SAP_shutdown (DEV2_Handle device)
1141     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
1142     SIO2_Handle stream = (SIO2_Handle) device;
1143     DEV2_Frame *pFrame;
1144     Int i;
1145     EDMA3_DRV_Handle hEdma;
1146     //TRACE_GEN((&TR_MOD, "SAP_shutdown.%d (0x%x)", __LINE__, device));
1148     if (pDevExt->shutDown)
1149         return SIO2_EBADIO;
1151     if (pDevExt->pParams == NULL)
1152         return SIO2_EINVAL;
1154     if (pDevExt->pParams->sio.moduleNum == 0)
1155         hEdma = hEdma0;
1156     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1157         hEdma = hEdma1;
1158     if (pDevExt->activeEdma != EDMA_HINV)
1159         EDMA3_DRV_disableTransfer (hEdma, pDevExt->activeEdma, EDMA3_DRV_TRIG_MODE_EVENT);
1161     // reset queues
1162     while (!Queue_empty(device->todevice)) {
1163        // place oustanding requests onto holding queue
1164        pFrame = (DEV2_Frame *) Queue_dequeue (device->todevice);
1165        Queue_enqueue (Queue_handle(&pDevExt->xferQue), (Queue_Elem *) pFrame);
1166     }
1168     while (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1169         // pull frame from holding queue and place on user queue
1170         pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1171         Queue_enqueue (device->fromdevice, (Queue_Elem *) pFrame);
1172     }
1175     while (!Queue_empty(Queue_handle(&pDevExt->paramQue)))
1176         Queue_dequeue (Queue_handle(&pDevExt->paramQue));
1178     // not running => can use non-atomic functions
1179     for (i=0; i < pDevExt->numEdmaParams; i++)
1180         Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Queue_Elem *) &pDevExt->edmaParams[i]);
1182     // reset counter
1183     pDevExt->numQueued = 0;
1185     Log_info0("SAP_shutdown: After pDevExt->numQueued = 0 ");
1187     //SAP_EDMA_dumpParams(8);
1188     // make sure active is linked to error
1189     EDMA3_DRV_linkChannel (hEdma, pDevExt->activeEdma, pDevExt->errorEdma);
1191     // think this is better (from SIO_idle for standard model )
1192     // refill frame list -- so user needn't call reclaim, which may cause Rx underrun.
1193     while (!Queue_empty(device->fromdevice)) {
1194         /* place oustanding requests onto holding queue */
1195         pFrame = (DEV2_Frame *) Queue_dequeue (device->fromdevice);
1196         Queue_enqueue (Queue_handle(&stream->framelist), (Queue_Elem *) pFrame);
1197     }
1198     Semaphore_reset (pDevExt->sync, 0);
1199     
1200     pDevExt->shutDown = 1;
1201     pDevExt->numParamSetup = 0;
1203     return SIO2_OK;
1204 } // SAP_shutdown
1206 // -----------------------------------------------------------------------------
1207 int gSapWatchDogThrottle = 0;
1208 int gSapWatchDogIn =0;
1209 int gSapWatchDogOut = 0;
1210 int gSapWatchDogInSemPost = 0;
1211 int gSapWatchDogOutSemPost = 0;
1213 Void SAP_watchDog (Void)
1215     DEV2_Handle device;
1216     SAP_DeviceExtension *pDevExt;
1217     int i, oldMask, result;
1219     //Log_info2("SAP_watchDog.%d (0x%x)", __LINE__, device);
1221     // do nothing if SAP_init not yet called
1222     if (!SAP_initialized)
1223     {
1224         Log_info2("%s.%d: SAP_init not yet called.\n", (xdc_IArg)__FUNCTION__, __LINE__);
1225         return;
1226     }
1228     // protect context
1229     Task_disable (); // needed since we may call SEM_post
1230     //oldMask = Hwi_disable ();
1233     //Log_info3("%s.%d: devices loop, numDevices = %d", __FUNCTION__, __LINE__, sapDrv.numDevices);
1235     for (i=0; i < sapDrv.numDevices; i++) {
1236         device  = sapDrv.device[i];
1238         //Log_info3("%s.%d, devices loop start, device = 0x%x", __FUNCTION__, __LINE__, device);
1240         pDevExt = (SAP_DeviceExtension *) device->object;
1242         // do nothing if not running
1243         if (!pDevExt->runState)
1244             continue;
1246         // call board specific watchdog
1247         // TODO: handle return value
1248         SIO2_ctrl (device, PAF_SIO_CONTROL_WATCHDOG, NULL);
1249         
1250         // if port layer returns error then must need to clean up
1251         result = SAP_PORT_FTABLE_watchDog (device);
1252         if (result) {
1253             // set errorState which will force owner thread
1254             //   to clean up via SIO_idle()
1255             pDevExt->errorState = PAF_SIO_ERROR_FATAL;
1256             if(device->mode == DEV2_INPUT)
1257                 gSapWatchDogIn++;
1258             else
1259                 gSapWatchDogOut++;
1261             //TRACE_TERSE((&TR_MOD, "SAP_watchDog.%d, PAF_SIO_ERROR_FATAL: 0x%x", __LINE__, pDevExt->errorState));
1263             // if outstanding pend then post to free owner thead
1264             if (!Semaphore_pend(pDevExt->sync, 0))
1265             {
1266                 if(device->mode == DEV2_INPUT)
1267                         gSapWatchDogInSemPost++;
1268                 else
1269                         gSapWatchDogOutSemPost++;
1270                 Semaphore_post (pDevExt->sync);
1271             }
1272         }
1273     }
1276     // renable interrupts and task manager.
1277     // If we posted to the semaphore then the TSK_enable call will lead to
1278     // an immediate task switch to the associated audio thread.
1279     //Hwi_restore (oldMask);
1280     Task_enable ();
1282 } // SAP_watchDog
1284 // -----------------------------------------------------------------------------
1285 // Assumes that EDMA3 dispatcher handles TCC clearing.
1287 void SAP_isrCallback (Uint32 tcc, EDMA3_RM_TccStatus status, Ptr context)
1289     DEV2_Handle                 device;
1290     SAP_DeviceExtension       *pDevExt;
1291     DEV2_Frame                 *pFrame;
1292     unsigned int               opt;
1293     EDMA3_DRV_Handle                    hEdma;
1295     // could be here after Tx idle/overrun and this is the interrupt
1296     // for the last occuring error transfer so there is no transfer
1297     // to release, we just clear the int and exit.
1299     device = (DEV2_Handle) context;
1300     pDevExt = (SAP_DeviceExtension *)(device->object);
1301     //if (pDevExt->pParams == NULL)
1302         //return SIO2_EINVAL;
1304     if (pDevExt->pParams->sio.moduleNum == 0)
1305         hEdma = hEdma0;
1306     else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1307         hEdma = hEdma1;
1309     if ((pDevExt->runState == 1) && !pDevExt->errorState) {
1310         // if here then an interrupt occured due to errorEdma or valid
1311         // transfer, we assume the xfer is long enough so it will not complete
1312         // before we are finished here.
1314         // if last transfer was valid then complete it
1315         if (!Queue_empty(Queue_handle(&pDevExt->xferQue))) {
1317             // pull frame from holding queue
1318             pFrame = (DEV2_Frame *) Queue_dequeue (Queue_handle(&pDevExt->xferQue));
1320             // if used param entry then return it to queue
1321             if (pFrame->misc != NULL)
1322             {
1323                 Queue_enqueue (Queue_handle(&pDevExt->paramQue), (Ptr) pFrame->misc);
1324                 if (device->mode == 1)
1325                         gisrOutput+=100;
1326             }
1328             // decrement count
1329             pDevExt->numQueued -= 1;
1330             //gIsrCnt++;
1331             if (device->mode == 1)
1332                 {
1333                 gIsrOutputCnt++;
1334                 //Log_info1("SAP isrCallback for 0x%x", pDevExt->activeEdma);
1335                 }
1336             else
1337                 gIsrInputCnt++;
1338             // place frame onto user queue and signal user thread
1339             Queue_enqueue (device->fromdevice, (Ptr) pFrame);
1341             //Log_info2("Before SEM_post for device: 0x%x gIsrOutput: %d", device->mode, gisrOutput);
1342             // signal user thread
1343             Semaphore_post (pDevExt->sync);
1344         }
1345         else
1346                 gIsrElseCnt++;
1348         // determine if currently transferring buffer is valid based on interrupt enable bit
1349         // only valid transfers will generate interrupts
1350         EDMA3_DRV_getPaRAMEntry (hEdma, pDevExt->activeEdma, EDMA3_DRV_PARAM_ENTRY_OPT, &opt);
1352         if (!(opt & EDMA3_DRV_OPT_TCINTEN_SET_MASK (1)))
1353         {
1354                 if (device->mode == 1)
1355                         gIsrOutErrCnt++;
1356                 else
1357                         gIsrInErrCnt++;
1358                 pDevExt->errorState = PAF_SIO_ERROR_ERRBUF_XFER;
1359         }
1361     } // runState
1362     else
1363     {
1364                 if (pDevExt->runState != 1)
1365                         gIsrRunCnt++;
1366                 else
1367                         gIsrNotRunCnt++;
1368     }
1370     return;
1371 } //SAP_isrCallback
1373 // -----------------------------------------------------------------------------
1375 Int SAP_EDMA_setupXfer (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 parentEdma, XDAS_UInt32 childEdma, DEV2_Frame *pFrame)
1377     EDMA3_DRV_Handle            hEdma;
1378     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1379 //     int mcbspNum = pDevExt->pParams->sio.moduleNum;
1381         if (pDevExt->pParams == NULL)
1382                 return SIO2_EINVAL;
1384             if (pDevExt->pParams->sio.moduleNum == 0)
1385                 hEdma = hEdma0;
1386             else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1387                 hEdma = hEdma1;
1389     // TODO: shouldn't this just be tcc interrupt disable?
1390     // at least until linkage phase...
1391     unsigned int key = Hwi_disable ();
1393     if(targetEdma == NULL)
1394     {
1395         Log_info0("targetEdma is NULL");
1396     }
1397     // configure transfer
1398     if(pFrame->addr == NULL)
1399     {
1400         Log_info0("pFrame has NULL address?");
1401     }
1402     SAP_DMA_FTABLE_setupParam (device, targetEdma, childEdma, (XDAS_UInt32) pFrame->addr, pFrame->size);
1404     if (device->mode == DEV2_OUTPUT)
1405         Log_info4("SAP: Inside SAP_EDMA_setupXfer with childEdma=0x%x & targetEdma = 0x%x; pFrame->addr = 0x%x, pFrame->size=0x%x", childEdma, targetEdma, (xdc_IArg)pFrame->addr, pFrame->size);
1407     if (parentEdma != EDMA_HINV)
1408         EDMA3_DRV_linkChannel (hEdma, parentEdma, targetEdma);
1410     if (device->mode == DEV2_OUTPUT)
1411                 Log_info3("SAP: Inside SAP_EDMA_setupXfer linked targetEdma = 0x%x with parentEdma=0x%x on Edma=0x%x", targetEdma, parentEdma, (xdc_IArg)hEdma);
1413     Hwi_restore (key);
1415     return SIO2_OK;
1416 } // SAP_setupXfer
1418 // -----------------------------------------------------------------------------
1419 // Configure EDMA3 parameter entry
1421 Int SAP_EDMA_setupParam (DEV2_Handle device, XDAS_UInt32 targetEdma, XDAS_UInt32 childEdma, XDAS_UInt32 addr, XDAS_UInt32 size)
1423     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
1424     EDMA3_DRV_Handle            hEdma;
1425     EDMA3_DRV_PaRAMRegs  edmaConfig;
1427     if (pDevExt->pParams == NULL)
1428                 return SIO2_EINVAL;
1430         if (pDevExt->pParams->sio.moduleNum == 0)
1431                 hEdma = hEdma0;
1432         else if (pDevExt->pParams->sio.moduleNum == 1 || pDevExt->pParams->sio.moduleNum == 2)
1433                 hEdma = hEdma1;
1434     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
1435    // volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
1437    //Log_info3("%s.%d: Entered SAP_EDMA_setupParam for Target: 0x%x.\n", (xdc_IArg)__FUNCTION__, __LINE__, targetEdma);
1439     // Init opt parameter to 0 which, without being overriden, configures as:
1440     //    AB synchronized transfer
1441     //    no chaining or intermediate interrupts
1442     //    param is not static
1443     //    normal completion
1444     //    don't generate an interrupt (overriden below for regular xfers)
1445     edmaConfig.opt = 0;
1447     // not transferring blocks so c index is 0
1448     edmaConfig.destCIdx = 0;
1449     edmaConfig.srcCIdx = 0;
1451     edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1452     if (device->mode == DEV2_OUTPUT)
1453         edmaConfig.opt |= 2;            //DAM=CONST addr mode
1454     else
1455         edmaConfig.opt |= 1;            //SAM=CONST addr mode
1457     // if regular transfer then enable interrupt with tcc code
1458     if (targetEdma != pDevExt->errorEdma) {
1459         edmaConfig.opt |= EDMA3_DRV_OPT_SYNCDIM_SET_MASK (EDMA3_DRV_SYNC_AB);
1460         edmaConfig.opt |= EDMA3_DRV_OPT_TCINTEN_SET_MASK (1);
1461         edmaConfig.opt |= EDMA3_DRV_OPT_TCC_SET_MASK (pDevExt->firstTCC);
1462     }
1465     edmaConfig.aCnt = 4;
1466         edmaConfig.bCnt = pDevExt->numSers;
1467         edmaConfig.cCnt = size/(edmaConfig.aCnt * edmaConfig.bCnt);
1468     edmaConfig.bCntReload = edmaConfig.bCnt;
1471     // handle direction specific requirements
1472     if (device->mode == DEV2_INPUT) {
1473         edmaConfig.srcBIdx  = 0;
1474                 edmaConfig.srcAddr  = (unsigned int) (hPort->rbufAddr);
1476         if (addr) {
1477             edmaConfig.destBIdx = pDevExt->edmaWordSize;
1478             edmaConfig.destAddr = addr;
1479             edmaConfig.destCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1480             if(pDevExt->edmaWordSize == 2)
1481                 edmaConfig.cCnt= (size)/((edmaConfig.aCnt * edmaConfig.bCnt)/2);
1482         }
1483         else {
1484             edmaConfig.destBIdx = 0;
1485             edmaConfig.destAddr = (unsigned int) &sap_OVER_4LANE;
1486             edmaConfig.cCnt = 1;
1487         }
1488     }
1489     else {
1490         edmaConfig.destBIdx = 0;
1491         edmaConfig.srcBIdx  = pDevExt->edmaWordSize;
1492         edmaConfig.destAddr = (unsigned int) (hPort->xbufAddr);
1493         if (addr) {
1494             edmaConfig.srcCIdx  = pDevExt->edmaWordSize * pDevExt->numSers ;
1495             edmaConfig.srcAddr  = addr;
1496         }
1497         else {
1498             edmaConfig.srcBIdx  = 0;
1499             edmaConfig.srcAddr  = (unsigned int) &sap_UNDER[0];
1500         }
1501     }
1502     edmaConfig.srcAddr  = (unsigned int) getGlobalAddr(edmaConfig.srcAddr);
1503     edmaConfig.destAddr  = (unsigned int) getGlobalAddr(edmaConfig.destAddr);
1505     EDMA3_DRV_setPaRAM (hEdma, targetEdma, &edmaConfig);
1507     // link child xfer
1508     if (childEdma != EDMA_HINV)
1509         EDMA3_DRV_linkChannel (hEdma, targetEdma, childEdma);
1511     if (device->mode == DEV2_OUTPUT) {
1512         Log_info5("SAP: Inside SAP_EDMA_setupParam: 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);
1513         Log_info5("SAP: Inside SAP_EDMA_setupParam: aCnt=0x%x, bCnt = 0x%x; linked targetEdma = 0x%x with childEdma=0x%x on Edma=0x%x", edmaConfig.aCnt, edmaConfig.bCnt, targetEdma, childEdma, (xdc_IArg)hEdma );
1514         }
1516     return SIO2_OK;
1517 } //SAP_setupParam