1 /*
2 *
3 * Copyright (C) 2010-2013 Texas Instruments Incorporated - http://www.ti.com/
4 *
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 #ifdef _TMS320C6X
37 #include <c6x.h>
38 #endif
39 #include <ti/csl/csl.h>
40 #include <ti/csl/csl_chip.h>
41 #include <ti/csl/csl_tsc.h>
42 #include <ti/drv/dfe/dfe.h>
43 #include <ti/drv/dfe/dfe_osal.h>
44 #include "dfetest.h"
46 //#undef CHK_MAX_TIME
47 //
48 //#define MK_INITS(pInits, _ssel, _initClkGate, _initState, _clearData) \
49 //do { \
50 // (pInits)->ssel = (_ssel); \
51 // (pInits)->initClkGate = (_initClkGate); \
52 // (pInits)->initState = (_initState); \
53 // (pInits)->clearData = (_clearData); \
54 //} while(0);
55 //
56 //#define MK_INITS_JESD(pInits, _ssel, _initClkGate, _initState, _clearData) \
57 //do { \
58 // (pInits)->cmn.ssel = (_ssel); \
59 // (pInits)->cmn.initClkGate = (_initClkGate); \
60 // (pInits)->cmn.initState = (_initState); \
61 // (pInits)->cmn.clearData = (_clearData); \
62 // (pInits)->clearDataLane[0] = (_clearData); \
63 // (pInits)->clearDataLane[1] = (_clearData); \
64 // (pInits)->clearDataLane[2] = (_clearData); \
65 // (pInits)->clearDataLane[3] = (_clearData); \
66 //} while(0);
68 //#ifdef CHK_MAX_TIME
69 //// we don't care sync
70 //#define issueSync(a, b)
71 //// we don't care sync_cntr
72 //#define activeSyncCntr(a, b, c)
73 //// update max time used
74 //#define UPD_MAX_TIME(t_start, t_now, t_max) \
75 //do { \
76 // uint32_t t_delta; \
77 // t_now = TSCL; \
78 // t_delta = t_now - t_start; \
79 // t_start = t_now; \
80 // if(t_delta > t_max) t_max = t_delta; \
81 //} while(0);
82 //#else
83 //#define UPD_MAX_TIME(t_start, t_now, t_max)
84 //#endif
86 //uint32_t vbusp_read32 (uint32_t address)
87 //{
88 // return( *(volatile uint32_t *)address );
89 //}
90 //
91 //void vbusp_write32 (uint32_t address, uint32_t data)
92 //{
93 // *(volatile uint32_t *)address = data;
94 //}
95 //
96 //void vbusp_rmw32 (uint32_t address, uint32_t data, uint32_t mask)
97 //{
98 // uint32_t temp = *(volatile uint32_t *)address;
99 //
100 // temp = (temp & ~mask) | (data & mask);
101 //
102 // *(volatile uint32_t *)address = temp;
103 //}
105 static inline uint32_t CSL_DFESerdesPllTxlockSts
106 (
107 uint32_t base_addr
108 )
109 {
110 uint32_t data;
111 data = CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1FC0 + 0x34), 28, 28);
112 return (data);
113 }
115 static inline void CSL_DFESerdesReleaseTxIdl
116 (
117 uint32_t base_addr
118 )
119 {
120 CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1FC0 + 0x20), 25, 24, (uint32_t)0x2);
121 CSL_FINSR(*(volatile uint32_t *)(base_addr + 0x1FC0 + 0x24), 25, 24, (uint32_t)0x2);
122 }
124 static inline uint32_t CSL_DFESerdesRxSts
125 (
126 uint32_t base_addr,
127 uint32_t bias
128 )
129 {
130 uint32_t data;
131 data = CSL_FEXTR(*(volatile uint32_t *)(base_addr + 0x1FC0 + bias), 1, 0);
132 return (data);
133 }
135 DFE_Err WaitSync(DFE_CallbackContext cbkCtx, DFE_Handle hDfe, DfeFl_MiscSyncGenSig syncSig)
136 {
137 DFE_Err dfeErr;
138 uint32_t i, signaled;
139 int ct, *p;
141 p = (int *)cbkCtx;
142 ct = *p;
144 if(ct < 0) // wait forever
145 {
146 do // check the sync status
147 {
148 dfeErr = Dfe_getSyncStatus(hDfe, syncSig, &signaled);
149 } while(signaled == 0);
150 }
151 else
152 {
153 i = 0;
154 signaled = 0;
155 do // check the sync status
156 {
157 dfeErr = Dfe_getSyncStatus(hDfe, syncSig, &signaled);
158 i++;
159 } while(signaled == 0 && i < ct);
161 if(signaled == 0)
162 {
163 dfeErr = DFE_ERR_TIMEDOUT;
164 }
165 }
167 return (dfeErr);
168 }
170 DFE_Err setSyncPulseWidth(DFE_Handle hDfe, DfeFl_MiscSyncGenSig syncSig, uint32_t pulseWidth)
171 {
172 CSL_Status status;
173 DfeFl_MiscSyncGenGeneric syncGeneric;
175 syncGeneric.syncSig = syncSig;
176 syncGeneric.data = pulseWidth;
177 status = dfeFl_MiscHwControl(hDfe->hDfeMisc[0], DFE_FL_MISC_CMD_CFG_SYNC_ONE_SHOT, &syncGeneric);
178 if(status != CSL_SOK)
179 {
180 Dfe_osalLog("dfeFl_MiscHwControl() error = %d", status);
181 return DFE_ERR_HW_CTRL;
182 }
184 return DFE_ERR_NONE;
185 }
187 extern uint32_t serdes_cfg0_base;
188 extern uint32_t serdes_cfg1_base;
189 DFE_Err startDfe(DFE_Handle hDfe)
190 {
191 DFE_Err dfeErr;
192 int waitctx;
193 uint32_t lpbkSync[DFE_FL_JESD_NUM_LINK];
194 DfeFl_JesdRxLoopbackConfig rxLoopbackCfg;
195 uint32_t txLaneEnb[4], txLinkAssign[4];
196 uint32_t rxLaneEnb[4], rxLinkAssign[4];
197 uint32_t data, lane_lpbk;
199 // soft reset dfe
200 dfeErr = Dfe_softReset(hDfe);
203 if(dfeErr == DFE_ERR_NONE)
204 dfeErr = Dfe_getJesdLoopback(hDfe, &lpbkSync[0], &rxLoopbackCfg);
205 else
206 return (dfeErr);
208 if(dfeErr == DFE_ERR_NONE)
209 dfeErr = Dfe_getJesdTxLaneEnable(hDfe, &txLaneEnb[0], &txLinkAssign[0]);
210 else
211 return (dfeErr);
213 if(dfeErr == DFE_ERR_NONE)
214 dfeErr = Dfe_getJesdRxLaneEnable(hDfe, &rxLaneEnb[0], &rxLinkAssign[0]);
215 else
216 return (dfeErr);
218 dfeErr = Dfe_issueSyncUpdateBbsigGen(hDfe, DFE_FL_BB_AID_TESTGEN_A, DFE_FL_SYNC_GEN_SIG_SYNC_GEN_CNTR0);
219 if(dfeErr != DFE_ERR_NONE)
220 return (dfeErr);
222 if(dfeErr == DFE_ERR_NONE)
223 {
224 // poll for tx lock (ststx[4]) - serdes0 - lane0 & lane1 ==> pll_ok = 28th bit
225 // pll_ok is equivalent to ststx[4].
226 if (txLaneEnb[0] && !rxLoopbackCfg.lane0 && txLaneEnb[1] && !rxLoopbackCfg.lane1)
227 {
228 data = 0x0;
229 // while ( (data & 0x10000000) != 0x10000000 )
230 // {
231 // data=vbusp_read32(CSL_CSISC2_0_SERDES_CFG_REGS +0x00001FC0+0x00000034);
232 // }
233 while ( data != 1)
234 {
235 data = CSL_DFESerdesPllTxlockSts(serdes_cfg0_base);
236 }
237 }
239 // poll for tx lock (ststx[4]) - serdes1 - lane0 & lane1 ==> pll_ok = 28th bit
240 if (txLaneEnb[2] && !rxLoopbackCfg.lane2 && txLaneEnb[3] && !rxLoopbackCfg.lane3)
241 {
242 data = 0x0;
243 // while ( (data & 0x10000000) != 0x10000000 )
244 // {
245 // data=vbusp_read32(CSL_CSISC2_1_SERDES_CFG_REGS +0x00001FC0+0x00000034);
246 // }
247 while ( data != 1)
248 {
249 data = CSL_DFESerdesPllTxlockSts(serdes_cfg1_base);
250 }
251 }
252 }
253 else
254 return (dfeErr);
256 waitctx = -1;
258 dfeErr = Dfe_initTgtTx(hDfe, (DFE_CallbackContext)&waitctx, WaitSync);
260 if(dfeErr == DFE_ERR_NONE)
261 {
262 // Disabling serdes TX IDLE
263 // vbusp_rmw32(CSL_CSISC2_0_SERDES_CFG_REGS + 0x00001FC0 + 0x00000020, 0x02000000, 0x03000000);
264 // vbusp_rmw32(CSL_CSISC2_0_SERDES_CFG_REGS + 0x00001FC0 + 0x00000024, 0x02000000, 0x03000000);
265 // vbusp_rmw32(CSL_CSISC2_1_SERDES_CFG_REGS + 0x00001FC0 + 0x00000020, 0x02000000, 0x03000000);
266 // vbusp_rmw32(CSL_CSISC2_1_SERDES_CFG_REGS + 0x00001FC0 + 0x00000024, 0x02000000, 0x03000000);
267 CSL_DFESerdesReleaseTxIdl(serdes_cfg0_base);
268 CSL_DFESerdesReleaseTxIdl(serdes_cfg1_base);
269 //Released the serdes TX IDLE !!
271 //This is the gc_dfe_iqn_lamarr testbench, which has the serdes. Poll the
272 //stsrx[2] (the OK bit) and stsrx[1] (the LOSS bit) from the appropriate serdes
273 //macros.
275 // poll for rx OK (stsrx[2]) & rx LOSS (stsrx[1]) - serdes0 - lane0
276 if (rxLaneEnb[0] && !rxLoopbackCfg.lane0)
277 {
278 data = 0x0;
279 // while ( (data & 0x00000003) != 0x00000002 )
280 // data=vbusp_read32( CSL_CSISC2_0_SERDES_CFG_REGS +0x00001FC0+0x00000020);
281 while ( data != 0x2 )
282 data=CSL_DFESerdesRxSts( serdes_cfg0_base, 0x20 );
283 }
285 // poll for rx OK (stsrx[2]) & rx LOSS (stsrx[1]) - serdes0 - lane1
286 if (rxLaneEnb[1] && !rxLoopbackCfg.lane1)
287 {
288 data = 0x0;
289 // while ( (data & 0x00000003) != 0x00000002 )
290 // data=vbusp_read32( CSL_CSISC2_0_SERDES_CFG_REGS +0x00001FC0+0x00000024);
291 while ( data != 0x2 )
292 data=CSL_DFESerdesRxSts( serdes_cfg0_base, 0x24 );
293 }
295 // poll for rx OK (stsrx[2]) & rx LOSS (stsrx[1]) - serdes1 - lane0
296 if (rxLaneEnb[2] && !rxLoopbackCfg.lane2)
297 {
298 data = 0x0;
299 // while ( (data & 0x00000003) != 0x00000002 )
300 // data=vbusp_read32( CSL_CSISC2_1_SERDES_CFG_REGS+0x00001FC0+0x00000020);
301 while ( data != 0x2 )
302 data=CSL_DFESerdesRxSts( serdes_cfg1_base, 0x20 );
303 }
305 // poll for rx OK (stsrx[2]) & rx LOSS (stsrx[1]) - serdes1 - lane1
306 if (rxLaneEnb[3] && !rxLoopbackCfg.lane3)
307 {
308 data = 0x0;
309 // while ( (data & 0x00000003) != 0x00000002 )
310 // data=vbusp_read32( CSL_CSISC2_1_SERDES_CFG_REGS +0x00001FC0+0x00000024);
311 while ( data != 0x2 )
312 data=CSL_DFESerdesRxSts( serdes_cfg1_base, 0x24 );
313 }
314 }
315 else
316 return (dfeErr);
318 lane_lpbk = rxLoopbackCfg.lane0 || rxLoopbackCfg.lane1 || rxLoopbackCfg.lane2 || rxLoopbackCfg.lane3;
319 if (lane_lpbk && hDfe->bbrx_chksum_ssel && (hDfe->bbtx_siggen_ssel == hDfe->bbrx_chksum_ssel)) //checksum
320 hDfe->ulStrobe_Sync = DFE_FL_SYNC_GEN_SIG_SYNC_GEN_CNTR0;
321 else
322 hDfe->ulStrobe_Sync = DFE_FL_SYNC_GEN_SIG_UL_IQ0_FSTROBE_SYNC0;
323 dfeErr = Dfe_initTgtRx(hDfe, (DFE_CallbackContext)&waitctx, WaitSync);
325 if(dfeErr == DFE_ERR_NONE)
326 dfeErr = setSyncPulseWidth(hDfe, DFE_FL_SYNC_GEN_SIG_MPU_SYNC, 1);
327 else
328 return(dfeErr);
330 return (dfeErr);
331 }