2adffe09b954e3e36b7862235ebe2f1de7f250ca
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / sap / sap_mcasp.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 // McASP implementations for SAP_PORT (d10 specific)
39 //
40 //
41 //
43 #include <stdio.h>
44 #include <xdc/std.h>
46 #include <sio2.h>
47 #include "sap_mcasp.h"
49 #define ENABLE_TRACE
50 #ifdef ENABLE_TRACE
51 #include <xdc/runtime/Log.h>
52 //#define TRACE_TERSE0(a)         Log_info0(a)
53 #endif
55 // Allow a developer to selectively enable tracing.
56 // For release, you might set the mask to 0, but I'd always leave it at 1.
57 #define CURRENT_TRACE_MASK      0x01   // terse only
59 #define TRACE_MASK_TERSE        0x01   // only flag errors and show init
60 #define TRACE_MASK_GENERAL      0x02   // half dozen lines per frame
61 #define TRACE_MASK_VERBOSE      0x04   // trace full operation
62 #define TRACE_MASK_DATA         0x08   // Show data
63 #define TRACE_MASK_TIME         0x10   // Timing related traces
65 #if (CURRENT_TRACE_MASK & TRACE_MASK_TERSE)
66     //#define TRACE_TERSE(a)          LOG_printf a
67     #define TRACE_TERSE0(a)         Log_info0(a)
68     #define TRACE_TERSE1(a,b)       Log_info1(a,b)
69     #define TRACE_TERSE2(a,b,c)     Log_info2(a,b,c)
70     #define TRACE_TERSE3(a,b,c,d)   Log_info3(a,b,c,d)
71     #define TRACE_TERSE4(a,b,c,d,e) Log_info4(a,b,c,d,e)
72 #else
73     //#define TRACE_TERSE(a)
74     #define TRACE_TERSE0(a)
75     #define TRACE_TERSE1(a,b)
76     #define TRACE_TERSE2(a,b,c)
77     #define TRACE_TERSE3(a,b,c,d)
78     #define TRACE_TERSE4(a,b,c,d,e)
79 #endif
81 #if (CURRENT_TRACE_MASK & TRACE_MASK_GENERAL)
82     //#define TRACE_GEN(a)            LOG_printf a
83     #define TRACE_GEN0(a)           Log_info0(a)
84     #define TRACE_GEN1(a,b)         Log_info1(a,b)
85     #define TRACE_GEN2(a,b,c)       Log_info2(a,b,c)
86     #define TRACE_GEN3(a,b,c,d)     Log_info3(a,b,c,d)
87     #define TRACE_GEN4(a,b,c,d,e)   Log_info4(a,b,c,d,e)
88 #else
89     //#define TRACE_GEN(a)
90     #define TRACE_GEN0(a)
91     #define TRACE_GEN1(a,b)
92     #define TRACE_GEN2(a,b,c)
93     #define TRACE_GEN3(a,b,c,d)
94     #define TRACE_GEN4(a,b,c,d,e)
95 #endif
97 #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
98     #define TRACE_DATA(a) LOG_printf a
99 #else
100     #define TRACE_DATA(a)
101 #endif
103 #if (CURRENT_TRACE_MASK & TRACE_MASK_VERBOSE)
104     #define TRACE_VERBOSE(a)        LOG_printf a
105     #define TRACE_VERBOSE0(a)           Log_info0(a)
106     #define TRACE_VERBOSE1(a,b)         Log_info1(a,b)
107     #define TRACE_VERBOSE2(a,b,c)       Log_info2(a,b,c)
108     #define TRACE_VERBOSE3(a,b,c,d)     Log_info3(a,b,c,d)
109     #define TRACE_VERBOSE4(a,b,c,d,e)   Log_info4(a,b,c,d,e)
111 #else
112     #define TRACE_VERBOSE(a)
113     #define TRACE_VERBOSE0(a)
114     #define TRACE_VERBOSE1(a,b)
115     #define TRACE_VERBOSE2(a,b,c)
116     #define TRACE_VERBOSE3(a,b,c,d)
117     #define TRACE_VERBOSE4(a,b,c,d,e)
118 #endif
119 // .............................................................................
120 // Resource Access Control
121 //
122 // The resources which must be controlled here are the McASP registers. There
123 // is layer context (sapMcaspDrv) but this essentially only holds the
124 // addresses of the resources. Further this is intitialized, i.e. written to
125 // only once, before the task scheduler begins and hence need not be controlled.
126 // Therefore we focus only on the McASP registers themselves.
127 // 
128 // There are two sources of switching which must be considered:
129 //        (A) Interrupts
130 //        (B) Tasks
131 //
132 // While SAP does not access McASP registers at ISR levels, other users may 
133 // access some of the registers for other functionality, e.g. GPIO, at any
134 // priority level. Therefore all accesses to these registers must be protected
135 // using HWI disable/enable blocks. Registers in this category are:
136 //        PDIR/PFUNC/PDOUT/PDIN
137 // 
138 // Within (B) there are two types of accesses which we must consider:
139 //        (i)  Modifications to non-direction specific registers not in (A)
140 //        (ii) Modifications to direction specific registers
141 // 
142 // Within this layer there are no accesses to registers of type (i). If there
143 // were then there are at least two choices for  appropriate access control.
144 //        . HWI disable/enable macros
145 //            This is effective but inefficient since it blocks all
146 //            processing regardless of its resource usage.
147 //            
148 //        . Raise the TSK priority > max priority of all tasks using SAP.
149 //            This assumes that no tasks using SAP run at TSK_MAXPRI.
150 //
151 // For (ii) there is no need to perform resource access control since these
152 // registers are *owned* by the device and hence the calling thread and not
153 // accessed by any other context. Registers in this category are:
154 //        AFSyCTL, ACLKyCTL, AHCLKyCTL, SRCTLz, yTDM, yGBLCTL, yINTCTL,
155 //        ySTAT, ySLOTCNT, yCLKCHK, yBUFz
156 // where y is X or R and z is between 1 and 15.
157 // 
158 // Of concern maybe the ASYNC bit in the ACLKXCTL since this is arguably a
159 // receive option in a transmit register. However, to date, this bit is only
160 // modified when the transmitter is configured not when the input is
161 // configured; which would be problematic.
162 // 
163 // Also we make no assumptions about the calling priority; e.g. we do not
164 // depend on the SAP layer to disable switching before making a call to this
165 // (SAP_MCASP) layer.
166 // .............................................................................
168 // max time to wait in SAP_MCASP_enableX functions (in mS)
169 #define REGISTER_SET_TIMEOUT 2.
171 // .............................................................................
172 // Function table
174 Int  SAP_MCASP_alloc    (DEV2_Handle device);
175 Int  SAP_MCASP_close    (DEV2_Handle device);
176 Int  SAP_MCASP_enable   (DEV2_Handle device);
177 Void SAP_MCASP_init     (Void);
178 Int  SAP_MCASP_open     (DEV2_Handle device);
179 Int  SAP_MCASP_reset    (DEV2_Handle device);
180 Int  SAP_MCASP_watchDog (DEV2_Handle device);
182 Int  SAP_MCASP_waitSet (MCASP_Handle hMcasp, Uint32 wrReg, Uint32 rdReg, Uint32 mask, Uint32 timeout);
183 //Int  SAP_MCASP_updateDITRam(DEV_Handle device );
185 SAP_MCASP_Fxns SAP_MCASP_FXNS = 
187     SAP_MCASP_alloc,
188     SAP_MCASP_close,
189     SAP_MCASP_enable,
190     SAP_MCASP_init,
191     SAP_MCASP_open,
192     SAP_MCASP_reset,
193     SAP_MCASP_watchDog,
194     SAP_MCASP_waitSet
195 };
197 SAP_MCASP_DriverObject sapMcaspDrv;
199 // -----------------------------------------------------------------------------
201 Void SAP_MCASP_init (Void)
203     volatile Uint32 *base;
204     volatile Uint32 *fifoBase;
205     volatile Uint32 *pSers;
206     int i, j;
208     TRACE_TERSE0("SAP_MCASP_init");
209     // open McASP ports via CSL. This CSL call, MCASP_open, does not require
210     // CSL_init which is important since this function is called before main
211     // and hence before any chance to call CSL_init.
212     for (i=0; i < _MCASP_PORT_CNT; i++) {
213         sapMcaspDrv.hPort[i] = MCASP_open (i, MCASP_OPEN);
214         base     = (volatile Uint32 *) sapMcaspDrv.hPort[i]->baseAddr;
215         fifoBase = base + _MCASP_FIFO_OFFSET;
216         //if (fifoBase[_MCASP_AFIFOREV_OFFSET] == 0x44311100)
217             sapMcaspDrv.fifoPresent[i] = 1;
218         //else
219           //  sapMcaspDrv.fifoPresent[i] = 0;
221         // zero out all serializers
222         pSers = &base[_MCASP_SRCTL0_OFFSET];
223         for (j=0; j<_MCASP_CHANNEL_CNT; j++)
224         {
225             Uint32 save = *pSers;
226             *pSers = 0;
227             pSers++;
228         }
229         base[_MCASP_PDIR_OFFSET] = 0;  // all input by default
230     }
232     
234 } // SAP_MCASP_init
236 // -----------------------------------------------------------------------------
237 // TODO:
238 //     Add control for:
239 //        1. DLB
240 //        2. DIT
241 //        3. AMUTE?
243 Int SAP_MCASP_alloc (DEV2_Handle device)
245     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
246     const SAP_Params *pParams = pDevExt->pParams;
247     MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
248     volatile Uint32 *base = (volatile Uint32 *) hPort->baseAddr;
249     volatile Uint32 *pSers =&base[_MCASP_SRCTL0_OFFSET];
250     Int i, oldMask, tdmMask;
252     //TRACE_TERSE1(("SAP_MCASP_alloc(0x%x)", device));
254     // validate mcasp number
255     if (pParams->sio.moduleNum >= _MCASP_PORT_CNT)
256         return DEV2_EINVAL;
258     // Could/should validate pin mask here.
259     // Check: McAsp0 has 16 pins.  McAsp1 has 10.  McAsp2 has 6.
260     // !!!! This code is DA10x specific !!!!!!!!!!
261     switch (pParams->sio.moduleNum)
262     {
263     case 0:
264         if (pParams->sap.pinMask & 0x00FF0000)
265         {
266                 //TRACE_TERSE1(("ERROR. McAsp0 has only 16 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask));
267             System_printf("ERROR. McAsp0 has only 16 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask);
268             System_abort("ABORT. McAsp0 has only 16 pins.");
269         }
270         break;
271     case 1:
272         if (pParams->sap.pinMask & 0x00FFFC00)
273         {
274                 //TRACE_TERSE1(("ERROR. McAsp1 has only 10 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask));
275                 System_printf("ERROR. McAsp1 has only 10 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask);
276                 System_abort("ABORT. McAsp1 has only 10 pins.");
277         }
278         break;
279     case 2:
280         if (pParams->sap.pinMask & 0x00FFFFC0)
281         {
282                 //TRACE_TERSE1(("ERROR. McAsp2 has only 6 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask));
283                 System_printf("ERROR. McAsp2 has only 6 pins.  PinMask requests 0x%x.\n", pParams->sap.pinMask);
284             System_abort("ABORT. McAsp2 has only 6 pins.");
285         }
286         break;
287     }
289     // lock context -- see class (A) above
290     oldMask = Hwi_disable ();
292     // use pinMask to configure MCASP vs. GPIO functionality
293     base[_MCASP_PFUNC_OFFSET] &= ~(pParams->sap.pinMask & 0xFE00FFFF);
295     // infer serializer config from pinMask and mode
296     //TRACE_TERSE2(("SAP_MCASP_alloc(): serializer: pinMask : 0x%x PDIR on entry: 0x%x.", pParams->sap.pinMask, base[_MCASP_PDIR_OFFSET]));
297     pDevExt->numSers = 0;
298     for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
299         if (pParams->sap.pinMask & (1 << i)) {
300             pDevExt->numSers += 1;
301             if (device->mode == DEV2_INPUT) {
302                 *pSers = MCASP_SRCTL_SRMOD_RCV;
303                 if (*pSers != MCASP_SRCTL_SRMOD_RCV) {
304                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer input: write to pSers failed: 0x%x.  *pSers: 0x%x", pSers, *pSers));
305                 }
306                 else {
307                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer input: pSers: 0x%x.  *pSers: 0x%x", pSers, *pSers));
308                 }
309                 base[_MCASP_PDIR_OFFSET] &= ~(1 << i);
310                 //TRACE_TERSE1(("SAP_MCASP_alloc(): serializer input: clear pin %d.", i));
311             }
312             else {
313                 *pSers = MCASP_SRCTL_SRMOD_XMT;
314                 if (*pSers != MCASP_SRCTL_SRMOD_XMT) {
315                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer output: write to pSers failed: 0x%x.  *pSers: 0x%x", pSers, *pSers));
316                 }
317                 else {
318                         //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer output: pSers: 0x%x.  *pSers: 0x%x", pSers, *pSers));
319                 }
320                 base[_MCASP_PDIR_OFFSET] |= (1 << i);
321                 //TRACE_TERSE1(( "SAP_MCASP_alloc(): serializer output: set pin %d.", i));
322             }
323         }
324         *pSers++;
325     }
326     //TRACE_TERSE3(("SAP_MCASP_alloc(): serializer PDIR: 0x%x, numSers %d, *pSers: 0x%x", base[_MCASP_PDIR_OFFSET], pDevExt->numSers, *pSers));
329     if (device->mode == DEV2_INPUT) {
330         MCASP_ConfigRcv *pRxConfig = (MCASP_ConfigRcv *)pParams->sio.pConfig;
332         // infer clock pin directions
333         if (pParams->sap.pinMask & _MCASP_PFUNC_ACLKR_MASK)
334             if (pRxConfig->aclkrctl & _MCASP_ACLKRCTL_CLKRM_MASK)
335                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_ACLKR_MASK;
336             else
337                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_ACLKR_MASK;
338         if (pParams->sap.pinMask & _MCASP_PFUNC_AHCLKR_MASK)
339             if (pRxConfig->ahclkrctl & _MCASP_AHCLKRCTL_HCLKRM_MASK)
340                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AHCLKR_MASK;
341             else
342                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AHCLKR_MASK;
343         if (pParams->sap.pinMask & _MCASP_PFUNC_AFSR_MASK)
344             if (pRxConfig->afsrctl & _MCASP_AFSRCTL_FSRM_MASK)
345                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AFSR_MASK;
346             else
347                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AFSR_MASK;
349         //TRACE_TERSE1(( "SAP_MCASP_alloc(): rx clock: 0x%x", base[_MCASP_PDIR_OFFSET]));
350         MCASP_configRcv (hPort, pRxConfig);
351     }
352     else {
353         MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
355         // infer clock pin directions
356         if (pParams->sap.pinMask & _MCASP_PFUNC_ACLKX_MASK)
357             if (pTxConfig->aclkxctl & _MCASP_ACLKXCTL_CLKXM_MASK)
358                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_ACLKX_MASK;
359             else
360                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_ACLKX_MASK;
361         if (pParams->sap.pinMask & _MCASP_PFUNC_AHCLKX_MASK)
362             if( pTxConfig->ahclkxctl & _MCASP_AHCLKXCTL_HCLKXM_MASK )
363                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AHCLKX_MASK;
364             else
365                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AHCLKX_MASK;
366         if (pParams->sap.pinMask & _MCASP_PFUNC_AFSX_MASK)
367             if( pTxConfig->afsxctl & _MCASP_AFSXCTL_FSXM_MASK )
368                 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AFSX_MASK;
369             else
370                 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AFSX_MASK;
372         if (pParams->sap.pinMask & _MCASP_PFUNC_AMUTE_MASK)
373                         base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AMUTE_MASK;
374         // HACK -- determine DIT need by FXWID
375         if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
376             base[_MCASP_DITCTL_OFFSET] = MCASP_DITCTL_RMK (MCASP_DITCTL_VB_ZERO, MCASP_DITCTL_VA_ZERO, MCASP_DITCTL_DITEN_DIT);
377         else
378             base[_MCASP_DITCTL_OFFSET] = MCASP_DITCTL_DEFAULT;
380         //TRACE_TERSE1(( "SAP_MCASP_alloc(): tx clock: 0x%x", base[_MCASP_PDIR_OFFSET]));
381         MCASP_configXmt (hPort, pTxConfig);
382     }
383     SAP_PORT_FTABLE_reset (device);
385     // unlock context
386     Hwi_restore (oldMask);
388     // determine number of TDM slots (32 max), if DIT must be 2, must be
389     // done after MCASP_config since the registers are referenced directly
390     if (device->mode == DEV2_OUTPUT) {
391         if ((base[_MCASP_AFSXCTL_OFFSET] & _MCASP_AFSXCTL_XMOD_MASK) ==
392             (MCASP_AFSXCTL_XMOD_OF(0x180) << _MCASP_AFSXCTL_XMOD_SHIFT) )
393             tdmMask = 0x3;
394         else
395             tdmMask = base[_MCASP_XTDM_OFFSET];
396     }
397     else
398         tdmMask = base[_MCASP_RTDM_OFFSET];
400     pDevExt->numSlots = 0;
401     for (i=0; i < 32; i++)
402         if (tdmMask & (1 << i))
403             pDevExt->numSlots +=1;
405     //Log_info2("Leaving SAP_MCASP_alloc: tdmMask: 0x%x.  numSlots: %d", tdmMask, pDevExt->numSlots);
406     return DEV2_OK;
407 } // SAP_MCASP_alloc
409 // -----------------------------------------------------------------------------
411 Int SAP_MCASP_close (DEV2_Handle device)
413     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
414     const SAP_Params *pParams = pDevExt->pParams;
415     MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
416     volatile Uint32 *base = (volatile Uint32 *) hPort->baseAddr;
417     volatile Uint32 *pSers =&base[_MCASP_SRCTL0_OFFSET];
418     Int i;
420     //TRACE_TERSE1(( "SAP_MCASP_close(0x%x)", device));
422     for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
423         if (pParams->sap.pinMask & (1 << i))
424             *pSers = (MCASP_SRCTL_SRMOD_INACTIVE | ( MCASP_SRCTL_DISMOD_LOW << _MCASP_SRCTL_DISMOD_SHIFT ));
425         *pSers++;
426     }
428     return DEV2_OK;
429 } //SAP_MCASP_close
431 // -----------------------------------------------------------------------------
432 // Enable appropriate section of McASP. See McASP data sheet (Operation) for
433 // more info on the steps. 
435 Int SAP_MCASP_enable (DEV2_Handle device)
437     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
438     const SAP_Params *pParams = pDevExt->pParams;
439     Int mcaspNum = pParams->sio.moduleNum;
440     MCASP_Handle hPort = sapMcaspDrv.hPort[mcaspNum];
441     volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
442     volatile Uint32 *fifoBase = base + _MCASP_FIFO_OFFSET;
443     int i, mask0, mask1, mask2, mask3, mask4;
444     Uint32 wrReg, rdReg;
445     Int result = 0;
447     //TRACE_TERSE1(( "SAP_MCASP_enable(0x%x)", device));
449     // STEP 1: Reset McASP to default values
450     // This was done in preceding function call. 
452     // STEP 2: Enable FIFO
453     // If present, for input and output. Set NUMEVT = NUMDMA to disable pacing
454     // so that the same DMA setup can be used with FIFO enabled or disbaled
455     if (sapMcaspDrv.fifoPresent[mcaspNum]) {
456         if (device->mode == DEV2_OUTPUT) {
457             fifoBase[_MCASP_WFIFOCTL_OFFSET] =
458                 (pDevExt->numSers << _MCASP_WFIFOCTL_WNUMEVT_SHIFT) |
459                 (pDevExt->numSers << _MCASP_WFIFOCTL_WNUMDMA_SHIFT); 
460             fifoBase[_MCASP_WFIFOCTL_OFFSET] |=
461                 (MCASP_WFIFOCTL_WENA_ENABLE << _MCASP_WFIFOCTL_WENA_SHIFT);
463             //TRACE_TERSE1(( "SAP_MCASP_enable(): output fifos: numSers %d", pDevExt->numSers));
464         }
465         else {
466             fifoBase[_MCASP_RFIFOCTL_OFFSET] =
467                 (pDevExt->numSers << _MCASP_RFIFOCTL_RNUMEVT_SHIFT) |
468                 (pDevExt->numSers << _MCASP_RFIFOCTL_RNUMDMA_SHIFT); 
469             fifoBase[_MCASP_RFIFOCTL_OFFSET] |=
470                 (MCASP_RFIFOCTL_RENA_ENABLE << _MCASP_RFIFOCTL_RENA_SHIFT);
471            // TRACE_TERSE1(( "SAP_MCASP_enable(): input fifos: numSers %d", pDevExt->numSers));
472         }
473     }
475     mask1 = 0;
476     rdReg = _MCASP_GBLCTL_OFFSET;
477     if (device->mode == DEV2_INPUT) {
478         wrReg = _MCASP_RGBLCTL_OFFSET;
479         mask0 = MCASP_FMKS (GBLCTL,RHCLKRST,ACTIVE);
480         if (base[_MCASP_ACLKRCTL_OFFSET] & _MCASP_ACLKRCTL_CLKRM_MASK)
481             mask1 = MCASP_FMKS (GBLCTL,RCLKRST,ACTIVE);
482         mask2 = MCASP_FMKS (GBLCTL,RSRCLR,ACTIVE);
483         mask3 = MCASP_FMKS (GBLCTL,RSMRST,ACTIVE);
484         mask4 = MCASP_FMKS (GBLCTL,RFRST,ACTIVE);
485     }
486     else {
487         wrReg = _MCASP_XGBLCTL_OFFSET;
488         mask0 = MCASP_FMKS (GBLCTL,XHCLKRST,ACTIVE);
489         if (base[_MCASP_ACLKXCTL_OFFSET] & _MCASP_ACLKXCTL_CLKXM_MASK)
490             mask1 = MCASP_FMKS (GBLCTL,XCLKRST,ACTIVE);
491         mask2 = MCASP_FMKS (GBLCTL,XSRCLR,ACTIVE);
492         mask3 = MCASP_FMKS (GBLCTL,XSMRST,ACTIVE);
493         mask4 = MCASP_FMKS (GBLCTL,XFRST,ACTIVE);
494     }
496     // STEP 4: Start high-frequency clocks
497     // According to McASP datasheet this step is necessary even if the high-
498     // frequency clocks are external.
499     if (mask0) {
500         //TRACE_TERSE1(( "SAP_MCASP_enable(): HF clock mask 0: 0x%x.  ", mask0));
501         result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask0, REGISTER_SET_TIMEOUT);
502         if (result)
503             return result;
504     }
506     // STEP 5: Enable bit clock generator if internally generated
507     if (mask1) {
508         //TRACE_TERSE1(( "SAP_MCASP_enable(): bit clock mask 1: 0x%x.  ", mask1));
509         result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask1, REGISTER_SET_TIMEOUT);
510         if (result)
511             return result;
512     }
514     // STEP 6: Setup DMA (this was done earlier -- out of order OK)
516     // STEP 7: Activate serializers
517     //TRACE_TERSE1(( "SAP_MCASP_enable(): serializers mask 2: 0x%x.  ", mask2));
518     result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask2, REGISTER_SET_TIMEOUT);
519     if (result)
520         return result;
522     // STEP 8: Verify that all transmit buffers are serviced.
523     // This is guaranteed to succeed since by now we now that there is a clock
524     // and hence XDATA empty will be generated
526     if (device->mode == DEV2_OUTPUT)
527     {
528         volatile Uint32 *pSers;
529         volatile int timeout;
531         result = 0;
532         // configure serializers and associated pins
533         pSers =&base[_MCASP_SRCTL0_OFFSET];
534         for (i=0; i < _MCASP_CHANNEL_CNT; i++)
535         {
536                 timeout = 0;
537             if (pDevExt->pParams->sap.pinMask & (1 << i))
538             {
539                 //Log_info3(( "SAP_MCASP_enable(): wait for serializer %d.  pSers: 0x%x, *pSers: 0x%x", i, pSers, *pSers));
540                 while ((*pSers & _MCASP_SRCTL_XRDY_MASK) != 0)
541                 {
542                         timeout++;
543                         if (timeout > 10000)
544                         {
545                                 Log_info1("SAP_MCASP_enable(): McASP serializer %d timed out.\n", i);
546                                 result = SIO2_ETIMEOUT;
547                                 break;
548                         }
550                 }
551             }
552             *pSers++;
553         }
554         if (result)
555         {
556           #ifdef ENABLE_TRACE
557                 TRACE_TERSE0(( "SAP_MCASP_enable(): Stopping trace on serializer error."));
558                 //Log_disable(&trace);
559           #endif
560             return result;
561         }
562     }
564     // STEP 9: Release state machine from reset
565     //TRACE_TERSE1(( "SAP_MCASP_enable(): reset state machine, mask 3: 0x%x.", mask3));
566     result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask3, REGISTER_SET_TIMEOUT);
567     if (result)
568         return result;
570     // STEP 10: Release FS generators from reset
571     // This needs to be enabled even if external frame sync because counter
572     //   for frame sync errors is in frame sync generator.
573     //TRACE_TERSE1(( "SAP_MCASP_enable(): release FS generators, mask 4: 0x%x.", mask4));
574     result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask4, REGISTER_SET_TIMEOUT);
576     //TRACE_TERSE1(( "SAP_MCASP_enable(): SAP_MCASP_enable(0x%x) complete.", device));
577     return result;
578 } //SAP_MCASP_enable
580 // -----------------------------------------------------------------------------
582 Int SAP_MCASP_open (DEV2_Handle device)
584     return DEV2_OK;
585 } // SAP_MCASP_open
587 // -----------------------------------------------------------------------------
589 Int SAP_MCASP_reset (DEV2_Handle device)
591     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *) device->object;
592     const SAP_Params *pParams = pDevExt->pParams;
593     Int mcaspNum = pParams->sio.moduleNum;
594     MCASP_Handle hPort = sapMcaspDrv.hPort[mcaspNum];
595     int oldhclk, oldclk, newhclk, newclk;
596     volatile int * base = (volatile int *) hPort->baseAddr;
597     volatile Uint32 *fifoBase = (volatile Uint32 *) (base + _MCASP_FIFO_OFFSET);
600     if (device->mode == DEV2_INPUT)
601     {
602         //TRACE_TERSE1(( "SAP_MCASP_reset(0x%x) input device.", device));
603         // disable FIFO if present
604         Log_info1("SAP_MCASP_reset(0x%x) input device.", device); //DJDBG
605         if (sapMcaspDrv.fifoPresent[mcaspNum])
606             fifoBase[_MCASP_RFIFOCTL_OFFSET] &=
607                 ~(MCASP_RFIFOCTL_RENA_ENABLE << _MCASP_RFIFOCTL_RENA_SHIFT);
609         // set to internal clock source (see spru041d.pdf page 117)
610         oldhclk = base[_MCASP_AHCLKRCTL_OFFSET];
611         oldclk  = base[_MCASP_ACLKRCTL_OFFSET];
612         newhclk = (oldhclk & ~_MCASP_AHCLKRCTL_HCLKRM_MASK) | (MCASP_AHCLKRCTL_HCLKRM_INTERNAL << _MCASP_AHCLKRCTL_HCLKRM_SHIFT);
613         newclk  = (oldclk  & ~_MCASP_ACLKRCTL_CLKRM_MASK)   | (MCASP_ACLKRCTL_CLKRM_INTERNAL   << _MCASP_ACLKRCTL_CLKRM_SHIFT);
614         base[_MCASP_AHCLKRCTL_OFFSET] = newhclk;
615         base[_MCASP_ACLKRCTL_OFFSET]  = newclk;
617         // assert RHCLKRST,RCLKRST to force signals to pass through with divide by 1
618         base[_MCASP_RGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_RHCLKRST_MASK;
619         base[_MCASP_RGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_RCLKRST_MASK;
620         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RHCLKRST_MASK);
621         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RCLKRST_MASK);
623         // Reset all other transmitter functions 
624         base[_MCASP_RGBLCTL_OFFSET] = 0;
625         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RSMRST_MASK);
626         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RFRST_MASK);
627         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RSRCLR_MASK);
629         // clear status register by writing ones
630         //      don't write to the RTDMSLOT register since it is read only and
631         //      causes a simulator warning when written
632         base[_MCASP_RSTAT_OFFSET] = 0x1F7;
633         while (base[_MCASP_RSTAT_OFFSET] & _MCASP_RSTAT_RDATA_MASK);
635         // restore clock settings
636         base[_MCASP_AHCLKRCTL_OFFSET] = oldhclk;
637         base[_MCASP_ACLKRCTL_OFFSET]  = oldclk;
638     }
639     else 
640     {
641         //TRACE_TERSE1(("SAP_MCASP_reset(0x%x) output device.", device));
642         Log_info1("SAP_MCASP_reset(0x%x) output device.", device); //DJDBG
643         // disable FIFO if present
644         if (sapMcaspDrv.fifoPresent[mcaspNum])
645             fifoBase[_MCASP_WFIFOCTL_OFFSET] &=
646                 ~(MCASP_WFIFOCTL_WENA_ENABLE << _MCASP_WFIFOCTL_WENA_SHIFT);
648         {
649                 volatile Uint32 *pSers = (volatile Uint32 *)(&base[_MCASP_SRCTL0_OFFSET]);
650                 Int i;
652                 for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
653                     if (pParams->sap.pinMask & (1 << i))
654                             *pSers = (MCASP_SRCTL_SRMOD_INACTIVE | ( MCASP_SRCTL_DISMOD_LOW << _MCASP_SRCTL_DISMOD_SHIFT ));
655                     *pSers++;
656                 }
657         }
658         // set to internal clock source (see spru041d.pdf page 117)
659         oldhclk = base[_MCASP_AHCLKXCTL_OFFSET];
660         oldclk  = base[_MCASP_ACLKXCTL_OFFSET];
661         newhclk = (oldhclk & ~_MCASP_AHCLKXCTL_HCLKXM_MASK) | (MCASP_AHCLKXCTL_HCLKXM_INTERNAL << _MCASP_AHCLKXCTL_HCLKXM_SHIFT);
662         newclk  = (oldclk  & ~_MCASP_ACLKXCTL_CLKXM_MASK)   | (MCASP_ACLKXCTL_CLKXM_INTERNAL   << _MCASP_ACLKXCTL_CLKXM_SHIFT);
663         base[_MCASP_AHCLKXCTL_OFFSET] = newhclk;
664         base[_MCASP_ACLKXCTL_OFFSET]  = newclk;
666         // assert XHCLKRST,XCLKRST to force signals to pass through with divide by 1
667         base[_MCASP_XGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_XHCLKRST_MASK;
668         base[_MCASP_XGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_XCLKRST_MASK;
669         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XHCLKRST_MASK);
670         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XCLKRST_MASK);
672         // Reset all other transmitter functions 
673         base[_MCASP_XGBLCTL_OFFSET] = 0;
674         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XSMRST_MASK);
675         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XFRST_MASK);
676         while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XSRCLR_MASK);
678         // clear status register by writing ones
679         //      don't write to the RTDMSLOT register since it is read only and
680         //      causes a simulator warning when written
681         base[_MCASP_XSTAT_OFFSET] = 0x1F7;
682         while (base[_MCASP_XSTAT_OFFSET] & _MCASP_XSTAT_XDATA_MASK);
684         {
685             volatile Uint32 *pSers = (volatile Uint32 *)(&base[_MCASP_SRCTL0_OFFSET]);
686             Int i;
688             for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
689                 if (pParams->sap.pinMask & (1 << i))
690                     *pSers = MCASP_SRCTL_SRMOD_XMT;
691                 *pSers++;
692             }
693         }
694         // restore clock settings
695         base[_MCASP_AHCLKXCTL_OFFSET] = oldhclk;
696         base[_MCASP_ACLKXCTL_OFFSET]  = oldclk;
697     }
699     //TRACE_TERSE1(( "SAP_MCASP_reset(0x%x) complete.", device));
701     return DEV2_OK;
702 } // SAP_MCASP_reset
704 // -----------------------------------------------------------------------------
705 // Set and wait for settings to registers (e.g. GBLCTL) to take effect
706 // we nee such a timeout since if the clocks are not available then 
707 // the settings will never take affect which would lead to a lockup condition.
709 #define INT_MAX 0xFFFFFFFF // maximum value returned by Clock_getTicks
710 #define USEC_PER_MSEC   ( 1000 ) // microseconds per millisecond
712 Int SAP_MCASP_waitSet (MCASP_Handle hMcasp, Uint32 wrReg, Uint32 rdReg, Uint32 mask, Uint32 timeout)
714     volatile Uint32 *base = (volatile Uint32 *)(hMcasp->baseAddr);
715     Uint32 timeStart, timeNow, elapsed, resMask;
717     //TRACE_TERSE3(("SAP_MCASP_waitSet(0x%x, 0x%x, 0x%x).", hMcasp, wrReg, rdReg));
719     // configure reserved mask to eliminate debug messages from simulator when
720     // writing to read only bits. Set default to all ones so that this function
721     // can be, although is not at this time, used by registers other than
722     // R/XGBCTL.
723     resMask = 0xFFFFFFFF;
724     if (wrReg == _MCASP_RGBLCTL_OFFSET) 
725         resMask = 0x1F;
726     else if (wrReg == _MCASP_XGBLCTL_OFFSET) 
727         resMask = 0x1F00;
729     // set register with mask value
730     base[wrReg] = (base[rdReg] | mask) & resMask;
732 #if 0
733     // convert timeout from milliseconds to nTicks
734     timeout = CLK_countspms () * timeout;
736     timeStart = CLK_gethtime ();
737     while (1) {
738         // return success if register has latched value
739         if ((base[rdReg] & mask) == mask)
740             break;
741         timeNow = CLK_gethtime ();
742         elapsed = timeNow - timeStart;
743         // check for wrap aound
744         if (timeNow <= timeStart)
745             elapsed = INT_MAX - timeStart + timeNow;
746         
747         // return error if timeout reached
748         if (elapsed > timeout)
749             return SYS_ETIMEOUT;
750     }
751 #endif
753     timeStart = Clock_getTicks();
754     while (1) {
755                 if ((base[rdReg] & mask) == mask)
756                         break;
757                 timeNow = Clock_getTicks();
758                 elapsed = timeNow - timeStart;
760                 // check for wrap aound
761                 if (timeNow < timeStart)
762                         elapsed = INT_MAX - timeStart + timeNow;
764                  // return error if timeout reached;
765                  //note: tick period = 1 ms; so timeout in ms = nticks
766                 if (elapsed > timeout)
767                         return SIO2_ETIMEOUT;
768     }
770     return DEV2_OK;
771 } //SAP_MCASP_waitSet
773 int gMcASPWatchDogInCnt=0;
774 int gMcASPWatchDogOutCnt=0;
775 // -----------------------------------------------------------------------------
777 Int SAP_MCASP_watchDog (DEV2_Handle device)
779     SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *) device->object;
780     MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
781     int stat;
783     if (device->mode == DEV2_INPUT) {
784         stat = MCASP_RGETH (hPort, RSTAT);
785         if ((stat & _MCASP_RSTAT_ROVRN_MASK) ||
786             (stat & _MCASP_RSTAT_RDMAERR_MASK))
787         {
788                 gMcASPWatchDogInCnt++;
789             return DEV2_EBADIO;
790         }
791     }
792     else {
793         stat = MCASP_RGETH (hPort, XSTAT);
794         if ((stat & _MCASP_XSTAT_XUNDRN_MASK) ||
795             (stat & _MCASP_XSTAT_XDMAERR_MASK))
796         {
797                 gMcASPWatchDogOutCnt++;
798                 return DEV2_EBADIO;
799         }
800     }
801     
802     return DEV2_OK;
803 } // SAP_MCASP_watchDog
805 // -----------------------------------------------------------------------------