1 /*
2 * Copyright (c) Texas Instruments Incorporated 2018
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 */
33 /**
34 * \ingroup DRV_UDMA_MODULE
35 * \defgroup DRV_UDMA_EVENT_MODULE UDMA Driver Event API
36 * This is UDMA driver event related configuration parameters and
37 * API
38 *
39 * @{
40 */
42 /**
43 * \file udma_event.h
44 *
45 * \brief UDMA event related parameters and API.
46 */
48 #ifndef UDMA_EVENT_H_
49 #define UDMA_EVENT_H_
51 /* ========================================================================== */
52 /* Include Files */
53 /* ========================================================================== */
55 /* None */
57 #ifdef __cplusplus
58 extern "C" {
59 #endif
61 /* ========================================================================== */
62 /* Macros & Typedefs */
63 /* ========================================================================== */
65 /** \brief Macro used to specify that event ID is invalid. */
66 #define UDMA_EVENT_INVALID ((uint32_t) CSL_UDMAP_NO_EVENT)
67 /** \brief Macro used to specify that interrupt number is invalid. */
68 #define UDMA_INTR_INVALID ((uint32_t) 0xFFFF0000U)
69 /**
70 * \brief Macro used to specify any available free core interrupt while
71 * requesting one. Used in the API #Udma_eventRegister.
72 */
73 #define UDMA_CORE_INTR_ANY ((uint32_t) 0xFFFF0001U)
75 /** \brief Max events per IA VINTR */
76 #define UDMA_MAX_EVENTS_PER_VINTR (64U)
78 /**
79 * \anchor Udma_EventType
80 * \name UDMA Event Type
81 *
82 * UDMA events supported.
83 *
84 * @{
85 */
86 /**
87 * \brief DMA completion event.
88 * Incase of TX/RX channel usage through ring, this represents the
89 * completion queue ring event and the application can dequeue the descriptor
90 * post this event.
91 */
92 #define UDMA_EVENT_TYPE_DMA_COMPLETION ((uint32_t) 0x0001U)
93 /**
94 * \brief DMA teardown completion event.
95 * Incase of TX/RX channel usage through ring, this represents the
96 * in-complete descriptor queued to the TD CQ ring during teardown operation.
97 * Note: This doesn't represent teardown completion of the channel.
98 */
99 #define UDMA_EVENT_TYPE_TEARDOWN_PACKET ((uint32_t) 0x0002U)
100 /**
101 * \brief TR event to IA.
102 *
103 * This programs the channels event steering register with IA global event
104 * number to generate anytime the required event generation criteria
105 * specified in a TR are met.
106 * This can be used to get intermediate event or interrupt based on the
107 * event type programmed in the TR.
108 *
109 * In case of TX and RX channel, this programs the correspinding UDMAP
110 * channel OES register.
111 * In case of blockcopy, this programs the UDMAP RX channel OES register.
112 * In case of external DRU channel, this programs the DRU OES register.
113 */
114 #define UDMA_EVENT_TYPE_TR ((uint32_t) 0x0003U)
115 /**
116 * \brief Ring event used for getting callback when entries are there to be
117 * popped from ring.
118 * This is added to support usecases where the user can independently allocate
119 * and configure ring and requires callback when hardware occupancy in the
120 * ring goes to non-zero.
121 * Note: This is not tied to any channel handle. And hence the chHandle in
122 * the event params can be set to NULL (Ignored by driver)
123 *
124 * Caution: Ring event will be triggered only when a transition from empty
125 * to non-empty ring occupancy occurs. Subsequent increment in ring occupancy
126 * will not trigger an event/interrupt. The user should take care of this
127 * behavior when dealing with multiple entires in a ring i.e. when a callback
128 * occurs, the user should dequeue as much as possible till the dequeue returns
129 * UDMA_ETIMEOUT and should not assume multiple callbacks will occur for
130 * each ring element (push from HW/SW).
131 */
132 #define UDMA_EVENT_TYPE_RING ((uint32_t) 0x0004U)
133 /**
134 * \brief Event type used to register master event without providing
135 * source type like ring, DMA etc... This event type can be used to register
136 * the master event which reserves the IA and IR interrupt to a core
137 * without reserving global event ID and IMAP programming.
138 * Post this, the handle can be passed to masterEventHandle for other event
139 * registeration to share the same IA and IR.
140 */
141 #define UDMA_EVENT_TYPE_MASTER ((uint32_t) 0x0005U)
142 /**
143 * \brief Event type used to register an event for trapping an out of range
144 * flow ID received on a packet.
145 *
146 * Note: This is a global event per UDMA instance (Main and MCU separately)
147 * and is common for all flow/channel in an UDMA instance. Hence this should
148 * be registered only once per system (by a master core) to handle flow error
149 * events.
150 */
151 #define UDMA_EVENT_TYPE_ERR_OUT_OF_RANGE_FLOW ((uint32_t) 0x0006U)
152 /**
153 * \brief Ring monitor event used for getting callback when ring monitor
154 * event criteria is met.
155 *
156 * Note: Not all modes of ring monitor generate events. Only the mode
157 * TISCI_MSG_VALUE_RM_MON_MODE_THRESHOLD generate event based on the
158 * low and high threshold programmed. In this case, the same event gets
159 * generated when both low and high thresholds are crossed.
160 *
161 * When user want to get only the low threshold event, the high threshold
162 * can be programmed a value which is greater than than the ring element count
163 * When user want to get only the high threshold event, the low threshold
164 * can be programmed zero.
165 *
166 */
167 #define UDMA_EVENT_TYPE_RING_MON ((uint32_t) 0x0007U)
168 /* @} */
170 /**
171 * \anchor Udma_EventMode
172 * \name UDMA Event Mode
173 *
174 * UDMA event mode.
175 *
176 * @{
177 */
178 /** \brief Event is exclusively allocated at Interrupt Aggregator */
179 #define UDMA_EVENT_MODE_EXCLUSIVE ((uint32_t) 0x0001U)
180 /**
181 * \brief Event is shared at Interrupt Aggregator and could be shared with
182 * any other events.
183 */
184 #define UDMA_EVENT_MODE_SHARED ((uint32_t) 0x0002U)
185 /* @} */
187 /**
188 * \brief UDMA event callback function.
189 *
190 * \param eventHandle [IN] UDMA event handle
191 * \param eventType [IN] Event that occurred
192 * \param appData [IN] Callback pointer passed during event register
193 */
194 typedef void (*Udma_EventCallback)(Udma_EventHandle eventHandle,
195 uint32_t eventType,
196 void *appData);
198 /* ========================================================================== */
199 /* Structure Declarations */
200 /* ========================================================================== */
202 /**
203 * \brief UDMA event related parameters.
204 *
205 * Requirement: DOX_REQ_TAG(PDK-2628), DOX_REQ_TAG(PDK-2627)
206 * DOX_REQ_TAG(PDK-2626), DOX_REQ_TAG(PDK-2625)
207 */
208 typedef struct
209 {
210 uint32_t eventType;
211 /**< [IN] Event type to register. Refer \ref Udma_EventType */
212 uint32_t eventMode;
213 /**< [IN] Event mode - exclusive or shared. Refer \ref Udma_EventMode.
214 * This parameter should be set to #UDMA_EVENT_MODE_SHARED for
215 * #UDMA_EVENT_TYPE_MASTER event type. */
216 Udma_ChHandle chHandle;
217 /**< [IN] Channel handle when the event type is one of below
218 * - #UDMA_EVENT_TYPE_DMA_COMPLETION
219 * - #UDMA_EVENT_TYPE_TEARDOWN_PACKET
220 * - #UDMA_EVENT_TYPE_TR.
221 * This parameter can be NULL for other types. */
222 Udma_RingHandle ringHandle;
223 /**< [IN] Ring handle when the event type is one of below
224 * - #UDMA_EVENT_TYPE_RING
225 * This parameter can be NULL for other types. */
226 Udma_EventHandle masterEventHandle;
227 /**< [IN] Master event handle used to share the IA register when the event
228 * mode is set to #UDMA_EVENT_MODE_SHARED.
229 * This is typically used to share multiple events from same source
230 * like same peripheral to one IA register which eventually routes to
231 * a single core interrupt.
232 * For the first(or master) event this should be set to NULL. The driver
233 * will allocate the required resources (IA/IR) for the first event.
234 * For the subsequent shared event registration, the master event handle
235 * should be passed as reference and the driver will allocate only the
236 * IA status bits. At a maximum #UDMA_MAX_EVENTS_PER_VINTR number of
237 * events can be shared. Beyond that the driver will return error.
238 * This parameter should be set to NULL for #UDMA_EVENT_TYPE_MASTER
239 * event type. */
240 Udma_EventCallback eventCb;
241 /**< [IN] When callback function is set (non-NULL), the driver will allocate
242 * core level interrupt through Interrupt Router and the function
243 * will be called when the registered event occurs.
244 * When set to NULL, the API will only allocate event and no interrupt
245 * routing is performed.
246 * Note: In case of shared events (multiple events mapped to same
247 * interrupt), the driver will call the callbacks in the order
248 * of event registration.
249 * This parameter should be set to NULL for #UDMA_EVENT_TYPE_MASTER
250 * event type. */
251 uint32_t intrPriority;
252 /**< [IN] Priority of interrupt to register with OSAL. The interpretation
253 * depends on the OSAL implementation */
254 void *appData;
255 /**< [IN] Application/caller context pointer passed back in the event
256 * callback function. This could be used by the caller to identify
257 * the channel/event for which the callback is called.
258 * This can be set to NULL, if not required by caller. */
259 uint32_t osalRegisterDisable;
260 /**< [IN] This flag is used to control whether the the interrupt
261 * needs to be registered with OSAL. In case AUTOSAR MCAL, interrupt
262 * registration is done by the integration layer at the start
263 * of the system init. Hence this flag is provided.
264 *
265 * Note: The osal interrupt registration is expected only for the master
266 * event.
267 *
268 * eventCb parameter can be NULL when this flag is set to TRUE as no
269 * interrupt registration is done
270 *
271 * TRUE - Disable osal registration
272 * FALSE - Enable osal registration. This should be used by all
273 * TI-RTOS application.
274 */
275 uint32_t preferredCoreIntrNum;
276 /**< [IN] Preferred core interrupt number which goes to a core.
277 * If set to #UDMA_CORE_INTR_ANY, will allocate from free pool.
278 * Else will try to allocate the mentioned interrupt itself. */
279 Udma_RingMonHandle monHandle;
280 /**< [IN] Ring monitor handle when the event type is one of below
281 * - #UDMA_EVENT_TYPE_RING_MON
282 * This parameter can be NULL for other types. */
284 /*
285 * Output parameters
286 */
287 volatile uint64_t *intrStatusReg;
288 /**< [OUT] Interrupt status register address of the allocated IA VINT
289 * register. This is used to check if interrupt occurred */
290 volatile uint64_t *intrClearReg;
291 /**< [OUT] Interrupt clear register address of the allocated IA VINT
292 * register. This is used to clear if interrupt occurred */
293 uint64_t intrMask;
294 /**< [OUT] Interrupt mask to check and clear */
295 uint32_t coreIntrNum;
296 /**< [OUT] Core interrupt number allocated.
297 * This number can be used to register with the OSAL */
298 } Udma_EventPrms;
300 /**
301 * \brief UDMAP receive flow id firewall status
302 *
303 * This structure contains status information collected whenever the receive
304 * flow ID firewall detects a flow ID that is out of range for an incoming
305 * packet.
306 */
307 typedef struct
308 {
309 uint32_t isException;
310 /**< This is set whenever the Flow ID firewall detects a Flow ID is out of
311 * range for an incoming packet. */
312 uint32_t flowId;
313 /**< [OUT] The flow ID that was received on the trapped packet */
314 uint32_t chNum;
315 /**< [OUT] The channel index on which the trapped packet was received */
316 } Udma_EventRxFlowIdFwStatus;
318 /* ========================================================================== */
319 /* Function Declarations */
320 /* ========================================================================== */
322 /**
323 * \brief UDMA event registration.
324 *
325 * Register event based on UDMA channel based and event parameters.
326 *
327 * Requirement: DOX_REQ_TAG(PDK-2596)
328 *
329 * \param drvHandle [IN] UDMA driver handle pointer passed during
330 * #Udma_init
331 * \param eventHandle [IN/OUT] UDMA event handle. The caller need to
332 * allocate memory for this object and pass this
333 * pointer to all further APIs. The caller should
334 * not change any parameters as this is owned and
335 * maintained by the driver.
336 * \param eventPrms [IN] UDMA event parameters.
337 * This parameter can't be NULL.
338 *
339 * \return \ref Udma_ErrorCodes
340 */
341 int32_t Udma_eventRegister(Udma_DrvHandle drvHandle,
342 Udma_EventHandle eventHandle,
343 Udma_EventPrms *eventPrms);
345 /**
346 * \brief UDMA unregister event.
347 *
348 * Unregister the event and frees all associated resources.
349 *
350 * Note: In case of shared event, the master event should be unregistered last
351 * compared to other shared events since the resource is owned by the master
352 * event. This function returns error for master event if any other shared
353 * resource is still not unregistered.
354 *
355 * Requirement: DOX_REQ_TAG(PDK-2597)
356 *
357 * \param eventHandle [IN] UDMA event handle.
358 * This parameter can't be NULL.
359 *
360 * \return \ref Udma_ErrorCodes
361 */
362 int32_t Udma_eventUnRegister(Udma_EventHandle eventHandle);
364 /**
365 * \brief Returns the event ID allocated for this event.
366 *
367 * Requirement: DOX_REQ_TAG(PDK-2598)
368 *
369 * \param eventHandle [IN] UDMA event handle.
370 * This parameter can't be NULL.
371 *
372 * \return the event ID on success or #UDMA_EVENT_INVALID on error
373 */
374 uint32_t Udma_eventGetId(Udma_EventHandle eventHandle);
376 /**
377 * \brief Disable the event at interrupt aggregator
378 *
379 * Requirement: DOX_REQ_TAG(PDK-3583)
380 *
381 * \param eventHandle [IN] UDMA event handle.
382 * This parameter can't be NULL.
383 *
384 * \return \ref Udma_ErrorCodes
385 */
386 int32_t Udma_eventDisable(Udma_EventHandle eventHandle);
388 /**
389 * \brief Enable the event at interrupt aggregator
390 *
391 * Note: By default the event will be enabled at the time of registration.
392 * This is API is used to enable the event again after a call to
393 * #Udma_eventDisable API
394 *
395 * Requirement: DOX_REQ_TAG(PDK-3583)
396 *
397 * \param eventHandle [IN] UDMA event handle.
398 * This parameter can't be NULL.
399 *
400 * \return \ref Udma_ErrorCodes
401 */
402 int32_t Udma_eventEnable(Udma_EventHandle eventHandle);
404 /**
405 * \brief Get the global event handle of the driver handle.
406 *
407 * Requirement: DOX_REQ_TAG(PDK-2621)
408 *
409 * \param drvHandle [IN] UDMA driver handle pointer passed during
410 * #Udma_init
411 *
412 * \return Returns global event handle else NULL on error
413 */
414 Udma_EventHandle Udma_eventGetGlobalHandle(Udma_DrvHandle drvHandle);
416 /**
417 * \brief Get the UDMA flow ID firewall status. This API will clear the status
418 * bit (RFLOWFWSTAT) by calling TISCI API
419 *
420 * Requirement: DOX_REQ_TAG(PDK-3706)
421 *
422 * \param eventHandle [IN] UDMA event handle.
423 * This parameter can't be NULL.
424 * \param status [OUT] RX flow ID firewall status return structure.
425 * This parameter can't be NULL.
426 *
427 * \return \ref Udma_ErrorCodes
428 */
429 int32_t Udma_eventGetRxFlowIdFwStatus(Udma_EventHandle eventHandle,
430 Udma_EventRxFlowIdFwStatus *status);
432 /*
433 * Structure Init functions
434 */
435 /**
436 * \brief Udma_EventPrms structure init function.
437 *
438 * \param eventPrms [IN] Pointer to #Udma_EventPrms structure.
439 *
440 */
441 void UdmaEventPrms_init(Udma_EventPrms *eventPrms);
443 /* ========================================================================== */
444 /* Static Function Definitions */
445 /* ========================================================================== */
447 /* None */
449 /* ========================================================================== */
450 /* Internal/Private Structure Declarations */
451 /* ========================================================================== */
453 /**
454 * \brief UDMA event object.
455 *
456 * Note: This is an internal/private driver structure and should not be
457 * used or modified by caller.
458 */
459 struct Udma_EventObj
460 {
461 Udma_DrvHandle drvHandle;
462 /**< Pointer to global driver handle. */
463 Udma_EventPrms eventPrms;
464 /**< Event parameters passed during event registeration. */
466 uint32_t globalEvent;
467 /**< Allocated IA global event. */
468 uint32_t vintrNum;
469 /**< Allocated IA VINT register. */
470 uint32_t vintrBitNum;
471 /**< Allocated IA VINT bit number - 0 to 63. */
472 uint32_t coreIntrNum;
473 /**< Allocated core interrupt number. */
475 Udma_EventHandle nextEvent;
476 /**< Pointer to next event - used in shared event for traversing in ISR */
477 Udma_EventHandle prevEvent;
478 /**< Pointer to previous event - used in shared event for traversing during
479 * event un-registration */
481 HwiP_Handle hwiHandle;
482 /**< HWI handle. */
483 uint64_t vintrBitAllocFlag;
484 /**< For master event, this stores the alloc flag for each bit within
485 * IA register. This is not used for slave events and is always set to
486 * zero */
488 /* Below register overlay pointers provided for debug purpose to
489 * readily view the registers */
490 volatile CSL_intaggr_imapRegs_gevi *pIaGeviRegs;
491 /**< Pointer to IA global event register overlay */
492 volatile CSL_intaggr_intrRegs_vint *pIaVintrRegs;
493 /**< Pointer to IA virtual interrupt register overlay */
495 uint32_t eventInitDone;
496 /**< Flag to set the event object is init. */
497 };
499 #ifdef __cplusplus
500 }
501 #endif
503 #endif /* #ifndef UDMA_EVENT_H_ */
505 /* @} */