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 =
186 {
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)
202 {
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 }
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)
244 {
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)
412 {
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)
436 {
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)
583 {
584 return DEV2_OK;
585 } // SAP_MCASP_open
587 // -----------------------------------------------------------------------------
589 Int SAP_MCASP_reset (DEV2_Handle device)
590 {
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)
713 {
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;
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)
778 {
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 }
802 return DEV2_OK;
803 } // SAP_MCASP_watchDog
805 // -----------------------------------------------------------------------------