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