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 }
232 } // SAP_MCASP_init
234 // -----------------------------------------------------------------------------
235 // TODO:
236 // Add control for:
237 // 1. DLB
238 // 2. DIT
239 // 3. AMUTE?
241 Int SAP_MCASP_alloc (DEV2_Handle device)
242 {
243 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
244 const SAP_Params *pParams = pDevExt->pParams;
245 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
246 volatile Uint32 *base = (volatile Uint32 *) hPort->baseAddr;
247 volatile Uint32 *pSers =&base[_MCASP_SRCTL0_OFFSET];
248 Int i, oldMask, tdmMask;
250 //TRACE_TERSE1(("SAP_MCASP_alloc(0x%x)", device));
252 // validate mcasp number
253 if (pParams->sio.moduleNum >= _MCASP_PORT_CNT)
254 return DEV2_EINVAL;
256 // Could/should validate pin mask here.
257 // Check: McAsp0 has 16 pins. McAsp1 has 10. McAsp2 has 6.
258 // !!!! This code is DA10x specific !!!!!!!!!!
259 switch (pParams->sio.moduleNum)
260 {
261 case 0:
262 if (pParams->sap.pinMask & 0x00FF0000)
263 {
264 //TRACE_TERSE1(("ERROR. McAsp0 has only 16 pins. PinMask requests 0x%x.\n", pParams->sap.pinMask));
265 System_printf("ERROR. McAsp0 has only 16 pins. PinMask requests 0x%x.\n", pParams->sap.pinMask);
266 System_abort("ABORT. McAsp0 has only 16 pins.");
267 }
268 break;
269 case 1:
270 if (pParams->sap.pinMask & 0x00FFFC00)
271 {
272 //TRACE_TERSE1(("ERROR. McAsp1 has only 10 pins. PinMask requests 0x%x.\n", pParams->sap.pinMask));
273 System_printf("ERROR. McAsp1 has only 10 pins. PinMask requests 0x%x.\n", pParams->sap.pinMask);
274 System_abort("ABORT. McAsp1 has only 10 pins.");
275 }
276 break;
277 case 2:
278 if (pParams->sap.pinMask & 0x00FFFFC0)
279 {
280 //TRACE_TERSE1(("ERROR. McAsp2 has only 6 pins. PinMask requests 0x%x.\n", pParams->sap.pinMask));
281 System_printf("ERROR. McAsp2 has only 6 pins. PinMask requests 0x%x.\n", pParams->sap.pinMask);
282 System_abort("ABORT. McAsp2 has only 6 pins.");
283 }
284 break;
285 }
287 // lock context -- see class (A) above
288 oldMask = Hwi_disable ();
290 // use pinMask to configure MCASP vs. GPIO functionality
291 base[_MCASP_PFUNC_OFFSET] &= ~(pParams->sap.pinMask & 0xFE00FFFF);
293 // infer serializer config from pinMask and mode
294 //TRACE_TERSE2(("SAP_MCASP_alloc(): serializer: pinMask : 0x%x PDIR on entry: 0x%x.", pParams->sap.pinMask, base[_MCASP_PDIR_OFFSET]));
295 pDevExt->numSers = 0;
296 for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
297 if (pParams->sap.pinMask & (1 << i)) {
298 pDevExt->numSers += 1;
299 if (device->mode == DEV2_INPUT) {
300 *pSers = MCASP_SRCTL_SRMOD_RCV;
301 if (*pSers != MCASP_SRCTL_SRMOD_RCV) {
302 //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer input: write to pSers failed: 0x%x. *pSers: 0x%x", pSers, *pSers));
303 }
304 else {
305 //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer input: pSers: 0x%x. *pSers: 0x%x", pSers, *pSers));
306 }
307 base[_MCASP_PDIR_OFFSET] &= ~(1 << i);
308 //TRACE_TERSE1(("SAP_MCASP_alloc(): serializer input: clear pin %d.", i));
309 }
310 else {
311 *pSers = MCASP_SRCTL_SRMOD_XMT;
312 if (*pSers != MCASP_SRCTL_SRMOD_XMT) {
313 //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer output: write to pSers failed: 0x%x. *pSers: 0x%x", pSers, *pSers));
314 }
315 else {
316 //TRACE_TERSE2(( "SAP_MCASP_alloc(): serializer output: pSers: 0x%x. *pSers: 0x%x", pSers, *pSers));
317 }
318 base[_MCASP_PDIR_OFFSET] |= (1 << i);
319 //TRACE_TERSE1(( "SAP_MCASP_alloc(): serializer output: set pin %d.", i));
320 }
321 }
322 *pSers++;
323 }
324 //TRACE_TERSE3(("SAP_MCASP_alloc(): serializer PDIR: 0x%x, numSers %d, *pSers: 0x%x", base[_MCASP_PDIR_OFFSET], pDevExt->numSers, *pSers));
327 if (device->mode == DEV2_INPUT) {
328 MCASP_ConfigRcv *pRxConfig = (MCASP_ConfigRcv *)pParams->sio.pConfig;
330 // infer clock pin directions
331 if (pParams->sap.pinMask & _MCASP_PFUNC_ACLKR_MASK)
332 if (pRxConfig->aclkrctl & _MCASP_ACLKRCTL_CLKRM_MASK)
333 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_ACLKR_MASK;
334 else
335 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_ACLKR_MASK;
336 if (pParams->sap.pinMask & _MCASP_PFUNC_AHCLKR_MASK)
337 if (pRxConfig->ahclkrctl & _MCASP_AHCLKRCTL_HCLKRM_MASK)
338 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AHCLKR_MASK;
339 else
340 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AHCLKR_MASK;
341 if (pParams->sap.pinMask & _MCASP_PFUNC_AFSR_MASK)
342 if (pRxConfig->afsrctl & _MCASP_AFSRCTL_FSRM_MASK)
343 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AFSR_MASK;
344 else
345 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AFSR_MASK;
347 //TRACE_TERSE1(( "SAP_MCASP_alloc(): rx clock: 0x%x", base[_MCASP_PDIR_OFFSET]));
348 MCASP_configRcv (hPort, pRxConfig);
349 }
350 else {
351 MCASP_ConfigXmt *pTxConfig = (MCASP_ConfigXmt *)pParams->sio.pConfig;
353 // infer clock pin directions
354 if (pParams->sap.pinMask & _MCASP_PFUNC_ACLKX_MASK)
355 if (pTxConfig->aclkxctl & _MCASP_ACLKXCTL_CLKXM_MASK)
356 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_ACLKX_MASK;
357 else
358 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_ACLKX_MASK;
359 if (pParams->sap.pinMask & _MCASP_PFUNC_AHCLKX_MASK)
360 if( pTxConfig->ahclkxctl & _MCASP_AHCLKXCTL_HCLKXM_MASK )
361 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AHCLKX_MASK;
362 else
363 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AHCLKX_MASK;
364 if (pParams->sap.pinMask & _MCASP_PFUNC_AFSX_MASK)
365 if( pTxConfig->afsxctl & _MCASP_AFSXCTL_FSXM_MASK )
366 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AFSX_MASK;
367 else
368 base[_MCASP_PDIR_OFFSET] &= ~_MCASP_PDIR_AFSX_MASK;
370 if (pParams->sap.pinMask & _MCASP_PFUNC_AMUTE_MASK)
371 base[_MCASP_PDIR_OFFSET] |= _MCASP_PDIR_AMUTE_MASK;
372 // HACK -- determine DIT need by FXWID
373 if (((pTxConfig->afsxctl & _MCASP_AFSXCTL_FXWID_MASK)>> _MCASP_AFSXCTL_FXWID_SHIFT) == MCASP_AFSXCTL_FXWID_BIT)
374 base[_MCASP_DITCTL_OFFSET] = MCASP_DITCTL_RMK (MCASP_DITCTL_VB_ZERO, MCASP_DITCTL_VA_ZERO, MCASP_DITCTL_DITEN_DIT);
375 else
376 base[_MCASP_DITCTL_OFFSET] = MCASP_DITCTL_DEFAULT;
378 //TRACE_TERSE1(( "SAP_MCASP_alloc(): tx clock: 0x%x", base[_MCASP_PDIR_OFFSET]));
379 MCASP_configXmt (hPort, pTxConfig);
380 }
381 SAP_PORT_FTABLE_reset (device);
383 // unlock context
384 Hwi_restore (oldMask);
386 // determine number of TDM slots (32 max), if DIT must be 2, must be
387 // done after MCASP_config since the registers are referenced directly
388 if (device->mode == DEV2_OUTPUT) {
389 if ((base[_MCASP_AFSXCTL_OFFSET] & _MCASP_AFSXCTL_XMOD_MASK) ==
390 (MCASP_AFSXCTL_XMOD_OF(0x180) << _MCASP_AFSXCTL_XMOD_SHIFT) )
391 tdmMask = 0x3;
392 else
393 tdmMask = base[_MCASP_XTDM_OFFSET];
394 }
395 else
396 tdmMask = base[_MCASP_RTDM_OFFSET];
398 pDevExt->numSlots = 0;
399 for (i=0; i < 32; i++)
400 if (tdmMask & (1 << i))
401 pDevExt->numSlots +=1;
403 //Log_info2("Leaving SAP_MCASP_alloc: tdmMask: 0x%x. numSlots: %d", tdmMask, pDevExt->numSlots);
404 return DEV2_OK;
405 } // SAP_MCASP_alloc
407 // -----------------------------------------------------------------------------
409 Int SAP_MCASP_close (DEV2_Handle device)
410 {
411 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)(device->object);
412 const SAP_Params *pParams = pDevExt->pParams;
413 MCASP_Handle hPort = sapMcaspDrv.hPort[pParams->sio.moduleNum];
414 volatile Uint32 *base = (volatile Uint32 *) hPort->baseAddr;
415 volatile Uint32 *pSers =&base[_MCASP_SRCTL0_OFFSET];
416 Int i;
418 //TRACE_TERSE1(( "SAP_MCASP_close(0x%x)", device));
420 for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
421 if (pParams->sap.pinMask & (1 << i))
422 *pSers = (MCASP_SRCTL_SRMOD_INACTIVE | ( MCASP_SRCTL_DISMOD_LOW << _MCASP_SRCTL_DISMOD_SHIFT ));
423 *pSers++;
424 }
426 return DEV2_OK;
427 } //SAP_MCASP_close
429 // -----------------------------------------------------------------------------
430 // Enable appropriate section of McASP. See McASP data sheet (Operation) for
431 // more info on the steps.
433 Int SAP_MCASP_enable (DEV2_Handle device)
434 {
435 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *)device->object;
436 const SAP_Params *pParams = pDevExt->pParams;
437 Int mcaspNum = pParams->sio.moduleNum;
438 MCASP_Handle hPort = sapMcaspDrv.hPort[mcaspNum];
439 volatile Uint32 *base = (volatile Uint32 *)(hPort->baseAddr);
440 volatile Uint32 *fifoBase = base + _MCASP_FIFO_OFFSET;
441 int i, mask0, mask1, mask2, mask3, mask4;
442 Uint32 wrReg, rdReg;
443 Int result = 0;
445 //TRACE_TERSE1(( "SAP_MCASP_enable(0x%x)", device));
447 // STEP 1: Reset McASP to default values
448 // This was done in preceding function call.
450 // STEP 2: Enable FIFO
451 // If present, for input and output. Set NUMEVT = NUMDMA to disable pacing
452 // so that the same DMA setup can be used with FIFO enabled or disbaled
453 if (sapMcaspDrv.fifoPresent[mcaspNum]) {
454 if (device->mode == DEV2_OUTPUT) {
455 fifoBase[_MCASP_WFIFOCTL_OFFSET] =
456 (pDevExt->numSers << _MCASP_WFIFOCTL_WNUMEVT_SHIFT) |
457 (pDevExt->numSers << _MCASP_WFIFOCTL_WNUMDMA_SHIFT);
458 fifoBase[_MCASP_WFIFOCTL_OFFSET] |=
459 (MCASP_WFIFOCTL_WENA_ENABLE << _MCASP_WFIFOCTL_WENA_SHIFT);
461 //TRACE_TERSE1(( "SAP_MCASP_enable(): output fifos: numSers %d", pDevExt->numSers));
462 }
463 else {
464 fifoBase[_MCASP_RFIFOCTL_OFFSET] =
465 (pDevExt->numSers << _MCASP_RFIFOCTL_RNUMEVT_SHIFT) |
466 (pDevExt->numSers << _MCASP_RFIFOCTL_RNUMDMA_SHIFT);
467 fifoBase[_MCASP_RFIFOCTL_OFFSET] |=
468 (MCASP_RFIFOCTL_RENA_ENABLE << _MCASP_RFIFOCTL_RENA_SHIFT);
469 // TRACE_TERSE1(( "SAP_MCASP_enable(): input fifos: numSers %d", pDevExt->numSers));
470 }
471 }
473 mask1 = 0;
474 rdReg = _MCASP_GBLCTL_OFFSET;
475 if (device->mode == DEV2_INPUT) {
476 wrReg = _MCASP_RGBLCTL_OFFSET;
477 mask0 = MCASP_FMKS (GBLCTL,RHCLKRST,ACTIVE);
478 if (base[_MCASP_ACLKRCTL_OFFSET] & _MCASP_ACLKRCTL_CLKRM_MASK)
479 mask1 = MCASP_FMKS (GBLCTL,RCLKRST,ACTIVE);
480 mask2 = MCASP_FMKS (GBLCTL,RSRCLR,ACTIVE);
481 mask3 = MCASP_FMKS (GBLCTL,RSMRST,ACTIVE);
482 mask4 = MCASP_FMKS (GBLCTL,RFRST,ACTIVE);
483 }
484 else {
485 wrReg = _MCASP_XGBLCTL_OFFSET;
486 mask0 = MCASP_FMKS (GBLCTL,XHCLKRST,ACTIVE);
487 if (base[_MCASP_ACLKXCTL_OFFSET] & _MCASP_ACLKXCTL_CLKXM_MASK)
488 mask1 = MCASP_FMKS (GBLCTL,XCLKRST,ACTIVE);
489 mask2 = MCASP_FMKS (GBLCTL,XSRCLR,ACTIVE);
490 mask3 = MCASP_FMKS (GBLCTL,XSMRST,ACTIVE);
491 mask4 = MCASP_FMKS (GBLCTL,XFRST,ACTIVE);
492 }
494 // STEP 4: Start high-frequency clocks
495 // According to McASP datasheet this step is necessary even if the high-
496 // frequency clocks are external.
497 if (mask0) {
498 //TRACE_TERSE1(( "SAP_MCASP_enable(): HF clock mask 0: 0x%x. ", mask0));
499 result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask0, REGISTER_SET_TIMEOUT);
500 if (result)
501 return result;
502 }
504 // STEP 5: Enable bit clock generator if internally generated
505 if (mask1) {
506 //TRACE_TERSE1(( "SAP_MCASP_enable(): bit clock mask 1: 0x%x. ", mask1));
507 result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask1, REGISTER_SET_TIMEOUT);
508 if (result)
509 return result;
510 }
512 // STEP 6: Setup DMA (this was done earlier -- out of order OK)
514 // STEP 7: Activate serializers
515 //TRACE_TERSE1(( "SAP_MCASP_enable(): serializers mask 2: 0x%x. ", mask2));
516 result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask2, REGISTER_SET_TIMEOUT);
517 if (result)
518 return result;
520 // STEP 8: Verify that all transmit buffers are serviced.
521 // This is guaranteed to succeed since by now we now that there is a clock
522 // and hence XDATA empty will be generated
524 if (device->mode == DEV2_OUTPUT)
525 {
526 volatile Uint32 *pSers;
527 volatile int timeout;
529 result = 0;
530 // configure serializers and associated pins
531 pSers =&base[_MCASP_SRCTL0_OFFSET];
532 for (i=0; i < _MCASP_CHANNEL_CNT; i++)
533 {
534 if (pDevExt->pParams->sap.pinMask & (1 << i))
535 {
536 //Log_info3(( "SAP_MCASP_enable(): wait for serializer %d. pSers: 0x%x, *pSers: 0x%x", i, pSers, *pSers));
537 while ((*pSers & _MCASP_SRCTL_XRDY_MASK) != 0);
538 }
539 *pSers++;
540 }
541 if (result)
542 {
543 #ifdef ENABLE_TRACE
544 TRACE_TERSE0(( "SAP_MCASP_enable(): Stopping trace on serializer error."));
545 //Log_disable(&trace);
546 #endif
547 return result;
548 }
549 }
551 // STEP 9: Release state machine from reset
552 //TRACE_TERSE1(( "SAP_MCASP_enable(): reset state machine, mask 3: 0x%x.", mask3));
553 result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask3, REGISTER_SET_TIMEOUT);
554 if (result)
555 return result;
557 // STEP 10: Release FS generators from reset
558 // This needs to be enabled even if external frame sync because counter
559 // for frame sync errors is in frame sync generator.
560 //TRACE_TERSE1(( "SAP_MCASP_enable(): release FS generators, mask 4: 0x%x.", mask4));
561 result = SAP_MCASP_FTABLE_waitSet (hPort, wrReg, rdReg, mask4, REGISTER_SET_TIMEOUT);
563 //TRACE_TERSE1(( "SAP_MCASP_enable(): SAP_MCASP_enable(0x%x) complete.", device));
564 return result;
565 } //SAP_MCASP_enable
567 // -----------------------------------------------------------------------------
569 Int SAP_MCASP_open (DEV2_Handle device)
570 {
571 return DEV2_OK;
572 } // SAP_MCASP_open
574 // -----------------------------------------------------------------------------
576 Int SAP_MCASP_reset (DEV2_Handle device)
577 {
578 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *) device->object;
579 const SAP_Params *pParams = pDevExt->pParams;
580 Int mcaspNum = pParams->sio.moduleNum;
581 MCASP_Handle hPort = sapMcaspDrv.hPort[mcaspNum];
582 int oldhclk, oldclk, newhclk, newclk;
583 volatile int * base = (volatile int *) hPort->baseAddr;
584 volatile Uint32 *fifoBase = (volatile Uint32 *) (base + _MCASP_FIFO_OFFSET);
587 if (device->mode == DEV2_INPUT)
588 {
589 //TRACE_TERSE1(( "SAP_MCASP_reset(0x%x) input device.", device));
590 // disable FIFO if present
591 Log_info1("SAP_MCASP_reset(0x%x) input device.", device);
592 if (sapMcaspDrv.fifoPresent[mcaspNum])
593 fifoBase[_MCASP_RFIFOCTL_OFFSET] &=
594 ~(MCASP_RFIFOCTL_RENA_ENABLE << _MCASP_RFIFOCTL_RENA_SHIFT);
596 // set to internal clock source (see spru041d.pdf page 117)
597 oldhclk = base[_MCASP_AHCLKRCTL_OFFSET];
598 oldclk = base[_MCASP_ACLKRCTL_OFFSET];
599 newhclk = (oldhclk & ~_MCASP_AHCLKRCTL_HCLKRM_MASK) | (MCASP_AHCLKRCTL_HCLKRM_INTERNAL << _MCASP_AHCLKRCTL_HCLKRM_SHIFT);
600 newclk = (oldclk & ~_MCASP_ACLKRCTL_CLKRM_MASK) | (MCASP_ACLKRCTL_CLKRM_INTERNAL << _MCASP_ACLKRCTL_CLKRM_SHIFT);
601 base[_MCASP_AHCLKRCTL_OFFSET] = newhclk;
602 base[_MCASP_ACLKRCTL_OFFSET] = newclk;
604 // assert RHCLKRST,RCLKRST to force signals to pass through with divide by 1
605 base[_MCASP_RGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_RHCLKRST_MASK;
606 base[_MCASP_RGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_RCLKRST_MASK;
607 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RHCLKRST_MASK);
608 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RCLKRST_MASK);
610 // Reset all other transmitter functions
611 base[_MCASP_RGBLCTL_OFFSET] = 0;
612 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RSMRST_MASK);
613 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RFRST_MASK);
614 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_RSRCLR_MASK);
616 // clear status register by writing ones
617 // don't write to the RTDMSLOT register since it is read only and
618 // causes a simulator warning when written
619 base[_MCASP_RSTAT_OFFSET] = 0x1F7;
620 while (base[_MCASP_RSTAT_OFFSET] & _MCASP_RSTAT_RDATA_MASK);
622 // restore clock settings
623 base[_MCASP_AHCLKRCTL_OFFSET] = oldhclk;
624 base[_MCASP_ACLKRCTL_OFFSET] = oldclk;
625 }
626 else
627 {
628 //TRACE_TERSE1(("SAP_MCASP_reset(0x%x) output device.", device));
629 Log_info1("SAP_MCASP_reset(0x%x) output device.", device);
630 // disable FIFO if present
631 if (sapMcaspDrv.fifoPresent[mcaspNum])
632 fifoBase[_MCASP_WFIFOCTL_OFFSET] &=
633 ~(MCASP_WFIFOCTL_WENA_ENABLE << _MCASP_WFIFOCTL_WENA_SHIFT);
635 {
636 volatile Uint32 *pSers = (volatile Uint32 *)(&base[_MCASP_SRCTL0_OFFSET]);
637 Int i;
639 for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
640 if (pParams->sap.pinMask & (1 << i))
641 *pSers = (MCASP_SRCTL_SRMOD_INACTIVE | ( MCASP_SRCTL_DISMOD_LOW << _MCASP_SRCTL_DISMOD_SHIFT ));
642 *pSers++;
643 }
644 }
645 // set to internal clock source (see spru041d.pdf page 117)
646 oldhclk = base[_MCASP_AHCLKXCTL_OFFSET];
647 oldclk = base[_MCASP_ACLKXCTL_OFFSET];
648 newhclk = (oldhclk & ~_MCASP_AHCLKXCTL_HCLKXM_MASK) | (MCASP_AHCLKXCTL_HCLKXM_INTERNAL << _MCASP_AHCLKXCTL_HCLKXM_SHIFT);
649 newclk = (oldclk & ~_MCASP_ACLKXCTL_CLKXM_MASK) | (MCASP_ACLKXCTL_CLKXM_INTERNAL << _MCASP_ACLKXCTL_CLKXM_SHIFT);
650 base[_MCASP_AHCLKXCTL_OFFSET] = newhclk;
651 base[_MCASP_ACLKXCTL_OFFSET] = newclk;
653 // assert XHCLKRST,XCLKRST to force signals to pass through with divide by 1
654 base[_MCASP_XGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_XHCLKRST_MASK;
655 base[_MCASP_XGBLCTL_OFFSET] &= ~ _MCASP_GBLCTL_XCLKRST_MASK;
656 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XHCLKRST_MASK);
657 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XCLKRST_MASK);
659 // Reset all other transmitter functions
660 base[_MCASP_XGBLCTL_OFFSET] = 0;
661 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XSMRST_MASK);
662 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XFRST_MASK);
663 while (base[_MCASP_GBLCTL_OFFSET] & _MCASP_GBLCTL_XSRCLR_MASK);
665 // clear status register by writing ones
666 // don't write to the RTDMSLOT register since it is read only and
667 // causes a simulator warning when written
668 base[_MCASP_XSTAT_OFFSET] = 0x1F7;
669 while (base[_MCASP_XSTAT_OFFSET] & _MCASP_XSTAT_XDATA_MASK);
671 {
672 volatile Uint32 *pSers = (volatile Uint32 *)(&base[_MCASP_SRCTL0_OFFSET]);
673 Int i;
675 for (i=0; i < _MCASP_CHANNEL_CNT; i++) {
676 if (pParams->sap.pinMask & (1 << i))
677 *pSers = MCASP_SRCTL_SRMOD_XMT;
678 *pSers++;
679 }
680 }
681 // restore clock settings
682 base[_MCASP_AHCLKXCTL_OFFSET] = oldhclk;
683 base[_MCASP_ACLKXCTL_OFFSET] = oldclk;
684 }
686 //TRACE_TERSE1(( "SAP_MCASP_reset(0x%x) complete.", device));
688 return DEV2_OK;
689 } // SAP_MCASP_reset
691 // -----------------------------------------------------------------------------
692 // Set and wait for settings to registers (e.g. GBLCTL) to take effect
693 // we nee such a timeout since if the clocks are not available then
694 // the settings will never take affect which would lead to a lockup condition.
696 #define INT_MAX 0xFFFFFFFF // maximum value returned by Clock_getTicks
698 Int SAP_MCASP_waitSet (MCASP_Handle hMcasp, Uint32 wrReg, Uint32 rdReg, Uint32 mask, Uint32 timeout)
699 {
700 volatile Uint32 *base = (volatile Uint32 *)(hMcasp->baseAddr);
701 Uint32 timeStart, timeNow, elapsed, resMask;
703 //TRACE_TERSE3(("SAP_MCASP_waitSet(0x%x, 0x%x, 0x%x).", hMcasp, wrReg, rdReg));
705 // configure reserved mask to eliminate debug messages from simulator when
706 // writing to read only bits. Set default to all ones so that this function
707 // can be, although is not at this time, used by registers other than
708 // R/XGBCTL.
709 resMask = 0xFFFFFFFF;
710 if (wrReg == _MCASP_RGBLCTL_OFFSET)
711 resMask = 0x1F;
712 else if (wrReg == _MCASP_XGBLCTL_OFFSET)
713 resMask = 0x1F00;
715 // set register with mask value
716 base[wrReg] = (base[rdReg] | mask) & resMask;
718 timeStart = Clock_getTicks();
719 while (1) {
720 if ((base[rdReg] & mask) == mask)
721 break;
722 timeNow = Clock_getTicks();
723 elapsed = timeNow - timeStart;
725 // check for wrap aound
726 if (timeNow < timeStart)
727 elapsed = INT_MAX - timeStart + timeNow;
729 // return error if timeout reached;
730 //note: tick period = 1 ms; so timeout in ms = nticks
731 if (elapsed > timeout)
732 return SIO2_ETIMEOUT;
733 }
735 return DEV2_OK;
736 } //SAP_MCASP_waitSet
738 int gMcASPWatchDogInCnt=0;
739 int gMcASPWatchDogOutCnt=0;
740 // -----------------------------------------------------------------------------
742 Int SAP_MCASP_watchDog (DEV2_Handle device)
743 {
744 SAP_DeviceExtension *pDevExt = (SAP_DeviceExtension *) device->object;
745 MCASP_Handle hPort = sapMcaspDrv.hPort[pDevExt->pParams->sio.moduleNum];
746 int stat;
748 if (device->mode == DEV2_INPUT) {
749 stat = MCASP_RGETH (hPort, RSTAT);
750 if ((stat & _MCASP_RSTAT_ROVRN_MASK) ||
751 (stat & _MCASP_RSTAT_RDMAERR_MASK))
752 {
753 gMcASPWatchDogInCnt++;
754 return DEV2_EBADIO;
755 }
756 }
757 else {
758 stat = MCASP_RGETH (hPort, XSTAT);
759 if ((stat & _MCASP_XSTAT_XUNDRN_MASK) ||
760 (stat & _MCASP_XSTAT_XDMAERR_MASK))
761 {
762 gMcASPWatchDogOutCnt++;
763 return DEV2_EBADIO;
764 }
765 }
767 return DEV2_OK;
768 } // SAP_MCASP_watchDog
770 // -----------------------------------------------------------------------------