1 /********************************************************************
2 * Copyright (C) 2013 Texas Instruments Incorporated.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33 #include <ti/drv/dfe/dfe_drv.h>
34 #include <ti/drv/dfe/dfe_osal.h>
35 #include <ti/drv/dfe/dfe_internal.h>
37 /**
38 * @defgroup DFE_LLD_SYNC_FUNCTION SYNC
39 * @ingroup DFE_LLD_FUNCTION
40 */
42 /**
43 * @brief Issue a sync signal.
44 * @ingroup DFE_LLD_SYNC_FUNCTION
45 *
46 * Once the signal is issued:
47 *
48 * - If waitCnt is #DFE_FL_MISC_SYNC_NOWAIT, the function just does issue the sync
49 * and returns #DFE_ERR_NONE immediately. #Dfe_getSyncStatus() can be called later
50 * to check if the sync has come.
51 * - If waitCnt is #DFE_FL_MISC_SYNC_WAITFOREVER, the function waits until the
52 * signal has really come and then returns #DFE_ERR_NONE.
53 * - If waitCnt is #DFE_FL_MISC_SYNC_WAIT(n), 0 < n < 0xfffffffu, the function waits until
54 * - either the signal has come before n loops complete, returns #DFE_ERR_NONE;
55 * - or n loops complete but the signal not come, returns #DFE_ERR_SYNC_NOT_COME
56 *
57 * For performance and flexibility considerations, using #DFE_FL_MISC_SYNC_NOWAIT
58 * for waitCnt is recommended.
59 *
60 * @param hDfe [in] DFE device handle
61 * @param syncSig [in] sync signal to be issued
62 * @param waitCnt [in] wait loop count
63 *
64 * @return
65 * - #DFE_ERR_NONE, if issue sync done properly
66 * - #DFE_ERR_INVALID_HANDLE, if hDfe is NULL
67 * - #DFE_ERR_SYNC_NOT_COME, if sync signal not coming within waitCnt loops.
68 * - #DFE_ERR_HW_CTRL, if CSL HwControl() failed
69 *
70 * @pre
71 * - hDfe should be a valid handle opened by #Dfe_open().
72 * - DFE PLL and PSCs shall be already up running.
73 * - DFE has loaded target config and completed initialize sequence.
74 *
75 * @post
76 * - None.
77 *
78 * @b Example
79 * @verbatim
80 [to be documented]
81 @endverbatim
82 */
83 DFE_Err Dfe_issueSync
84 (
85 DFE_Handle hDfe,
86 DfeFl_MiscSyncGenSig syncSig,
87 uint32_t waitCnt
88 )
89 {
90 DfeFl_Status status;
91 DfeFl_MiscSyncGenIssueSyncConfig cfg;
93 VALID_DFE_HANDLE(hDfe);
95 cfg.syncSig = syncSig;
96 cfg.waitCnt = waitCnt;
98 CSL_HW_CTRL( dfeFl_MiscHwControl(hDfe->hDfeMisc[0], DFE_FL_MISC_CMD_ISSUE_SYNC, &cfg) );
100 return DFE_ERR_NONE;
101 }
103 /**
104 * @brief Get a sync signal status.
105 * @ingroup DFE_LLD_SYNC_FUNCTION
106 *
107 * Get status of a sync signal. When return, if *signaled is 1, the sync has come; if *signaled is 0, the sync hasn't come.
108 *
109 * @param hDfe [in] DFE device handle
110 * @param syncSig [in] sync signal to be issued
111 * @param signalled [out] pointer to signal status buffer
112 *
113 * @return
114 * - #DFE_ERR_NONE, if issue sync done properly
115 * - #DFE_ERR_INVALID_HANDLE, if hDfe is NULL
116 * - #DFE_ERR_HW_QUERY, if CSL GetHwStatus() failed
117 *
118 * @pre
119 * - hDfe should be a valid handle opened by #Dfe_open().
120 * - DFE PLL and PSCs shall be already up running.
121 * - DFE has loaded target config and completed initialize sequence.
122 *
123 * @post
124 * - None.
125 *
126 * @b Example
127 * @verbatim
128 [to be documented]
129 @endverbatim
130 */
131 DFE_Err Dfe_getSyncStatus
132 (
133 DFE_Handle hDfe,
134 DfeFl_MiscSyncGenSig syncSig,
135 uint32_t *signaled
136 )
137 {
138 DfeFl_Status status;
139 DfeFl_MiscIntrStatus intrSts;
141 VALID_DFE_HANDLE(hDfe);
143 if(signaled == NULL)
144 {
145 Dfe_osalLog("NULL pointers passed in!");
146 return DFE_ERR_INVALID_PARAMS;
147 }
149 *signaled = 0;
151 intrSts.intr = syncSig;
152 intrSts.data = 0;
153 CSL_HW_QUERY( dfeFl_MiscGetHwStatus(hDfe->hDfeMisc[0], DFE_FL_MISC_QUERY_GET_SYNC_INTR_STATUS, &intrSts) );
155 *signaled = intrSts.data;
156 return DFE_ERR_NONE;
157 }
159 /**
160 * @brief Program a sync counter.
161 * @ingroup DFE_LLD_SYNC_FUNCTION
162 *
163 * The API first resets the counter and then reprogram to specified parameters.
164 * NOTE: #Dfe_issueSyncStartSyncCounter() should be then called to start the counter.
165 *
166 * @param hDfe [in] DFE device handle
167 * @param cntr [in] sync counter number
168 * @param delay [in] number of clocks to wait after sync select source before sending
169 initial sync. If set to 0, sync counter output will be high if sync
170 select source is high
171 * @param period [in] number of clocks to wait between syncs when repeat is 1.
172 * Does nothing when repeat is 0.
173 * @param pulseWidth [in] set to X for pulse width of X clocks; 0 means it will never go high.
174 * @param repeat [in] If 0, counter counts down delay clocks once, sends a sync,
175 * and stops. If 1, it counts down delay clocks sends a sync,
176 * then continuously sends more syncs every period clocks.
177 * @param invert [in] set to 1 to invert entire bus
178 *
179 * @return
180 * - #DFE_ERR_NONE, if sync counter programmed properly
181 * - #DFE_ERR_INVALID_HANDLE, if hDfe is NULL
182 * - #DFE_ERR_HW_CTRL, if CSL HwControl() failed
183 *
184 * @pre
185 * - hDfe should be a valid handle opened by #Dfe_open().
186 * - DFE PLL and PSCs shall be already up running.
187 * - DFE has loaded target config and completed initialize sequence.
188 * - #Dfe_issueSyncStartSyncCounter() should be called later to issue sync to start the counter.
189 *
190 * @post
191 * - None.
192 *
193 * @b Example
194 * @verbatim
195 [to be documented]
196 @endverbatim
197 */
198 DFE_Err Dfe_progSyncCounter
199 (
200 DFE_Handle hDfe,
201 DfeFl_MiscSyncGenCntr cntr,
202 uint32_t delay,
203 uint32_t period,
204 uint32_t pulseWidth,
205 uint32_t repeat,
206 uint32_t invert
207 )
208 {
209 DfeFl_Status status;
210 DfeFl_MiscSyncCntrConfig syncCntrCfg;
212 VALID_DFE_HANDLE(hDfe);
214 // reset cntr
215 CSL_HW_CTRL( dfeFl_MiscHwControl(hDfe->hDfeMisc[0], DFE_FL_MISC_CMD_RST_SYNC_CNTR, &cntr) );
217 // config cntr
218 syncCntrCfg.cntr = cntr;
219 syncCntrCfg.repeat = repeat;
220 syncCntrCfg.delay = delay;
221 syncCntrCfg.invert = invert;
222 syncCntrCfg.period = period;
223 syncCntrCfg.pulse = pulseWidth;
224 CSL_HW_CTRL( dfeFl_MiscHwControl(hDfe->hDfeMisc[0], DFE_FL_MISC_CMD_CFG_SYNC_CNTR, &syncCntrCfg) );
226 return DFE_ERR_NONE;
227 }
229 /**
230 * @brief Issue sync to start the sync counter, and return without waiting.
231 * @ingroup DFE_LLD_SYNC_FUNCTION
232 *
233 * Issue sync to start the sync counter that has been previously programmed with #Dfe_progSyncCounter().
234 *
235 * It programs the counter's starting sync select with ssel (using ALWAYS sync signal) and returns
236 * immediately after issue the sync. So #Dfe_getSyncStatus() should be called later to check if
237 * the sync has come.
238 *
239 * @param hDfe [in] DFE device handle
240 * @param cntr [in] sync counter number
241 * @param ssel [in] sync select to re-start sync counter
242 *
243 * @return
244 * - #DFE_ERR_NONE, if API complete properly
245 * - #DFE_ERR_INVALID_HANDLE, if hDfe is NULL
246 * - #DFE_ERR_HW_CTRL, if CSL HwControl() failed
247 *
248 * @pre
249 * - hDfe should be a valid handle opened by #Dfe_open().
250 * - DFE PLL and PSCs shall be already up running.
251 * - DFE has loaded target config and completed initialize sequence.
252 *
253 * @post
254 * - None.
255 *
256 * @b Example
257 * @verbatim
258 [to be documented]
259 @endverbatim
260 */
261 DFE_Err Dfe_issueSyncStartSyncCounter
262 (
263 DFE_Handle hDfe,
264 DfeFl_MiscSyncGenCntr cntr,
265 DfeFl_MiscSyncGenSig ssel
266 )
267 {
268 DfeFl_Status status;
269 DfeFl_MiscSyncGenCntrSsel syncCntrSsel;
271 VALID_DFE_HANDLE(hDfe);
273 // commit to hardware by ALWAYS sync, on then off
274 syncCntrSsel.cntr = cntr;
275 syncCntrSsel.startSsel = ssel;
276 syncCntrSsel.progSsel = DFE_FL_SYNC_GEN_SIG_ALWAYS;
277 CSL_HW_CTRL( dfeFl_MiscHwControl(hDfe->hDfeMisc[0], DFE_FL_MISC_CMD_SET_SYNC_CNTR_SSEL, &syncCntrSsel) );
279 Dfe_issueSync(hDfe, DFE_FL_SYNC_GEN_SIG_ALWAYS, DFE_FL_MISC_SYNC_NOWAIT);
281 if(ssel == DFE_FL_SYNC_GEN_SIG_NEVER)
282 {
283 syncCntrSsel.progSsel = DFE_FL_SYNC_GEN_SIG_NEVER;
284 CSL_HW_CTRL( dfeFl_MiscHwControl(hDfe->hDfeMisc[0], DFE_FL_MISC_CMD_SET_SYNC_CNTR_SSEL, &syncCntrSsel) );
285 }
287 return Dfe_issueSync(hDfe, ssel, DFE_FL_MISC_SYNC_NOWAIT);
288 }