1 | #ifndef __BESTCOMM_API_H |
---|
2 | #define __BESTCOMM_API_H 1 |
---|
3 | |
---|
4 | /****************************************************************************** |
---|
5 | * |
---|
6 | * Copyright (c) 2004 Freescale Semiconductor, Inc. |
---|
7 | * |
---|
8 | * Permission is hereby granted, free of charge, to any person obtaining a |
---|
9 | * copy of this software and associated documentation files (the "Software"), |
---|
10 | * to deal in the Software without restriction, including without limitation |
---|
11 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
---|
12 | * and/or sell copies of the Software, and to permit persons to whom the |
---|
13 | * Software is furnished to do so, subject to the following conditions: |
---|
14 | * |
---|
15 | * The above copyright notice and this permission notice shall be included |
---|
16 | * in all copies or substantial portions of the Software. |
---|
17 | * |
---|
18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
---|
19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
---|
20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
---|
21 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR |
---|
22 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
---|
23 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
---|
24 | * OTHER DEALINGS IN THE SOFTWARE. |
---|
25 | * |
---|
26 | * Filename: $Source$ |
---|
27 | * Author: $Author$ |
---|
28 | * Locker: $Locker$ |
---|
29 | * State: $State$ |
---|
30 | * Revision: $Revision$ |
---|
31 | * |
---|
32 | ******************************************************************************/ |
---|
33 | |
---|
34 | /*! |
---|
35 | * \file bestcomm_api.h |
---|
36 | * |
---|
37 | * Bestcomm_api.h is the only header necessary for inclusion by user |
---|
38 | * code. The include path the C compiler searches to find .h files |
---|
39 | * should contain bestcomm/capi and one of bestcomm/code_dma/image_*. |
---|
40 | * This second entry selects which set of BestComm tasks will be used. |
---|
41 | * Of course the appropriate files in image_* must also be compiled and |
---|
42 | * linked. |
---|
43 | */ |
---|
44 | |
---|
45 | #include "../bestcomm/include/ppctypes.h" |
---|
46 | #include "../bestcomm/include/mgt5200/sdma.h" |
---|
47 | #include "../bestcomm/task_api/tasksetup_bdtable.h" |
---|
48 | #include "../bestcomm/task_api/bestcomm_cntrl.h" |
---|
49 | #include "../bestcomm/task_api/bestcomm_api_mem.h" |
---|
50 | |
---|
51 | /*! |
---|
52 | * \brief TaskSetup() debugging |
---|
53 | * |
---|
54 | * Define this macro as follows for debugging printf()s to see |
---|
55 | * what the API receives and sets from the TaskSetupParamSet_t |
---|
56 | * struct. Implemented in capi/task_api/tasksetup_general.h. |
---|
57 | * |
---|
58 | * \verbatim |
---|
59 | * >0 : print basic debug messages |
---|
60 | * >=10: also print C-API interface variables |
---|
61 | * >=20: also print task API interface variables |
---|
62 | * else: do nothing |
---|
63 | * \endverbatim |
---|
64 | */ |
---|
65 | #define DEBUG_BESTCOMM_API 0 |
---|
66 | |
---|
67 | /*! |
---|
68 | * \brief Maximum number of tasks in the system. |
---|
69 | * This number is hardware-dependent and not user configuration. |
---|
70 | */ |
---|
71 | #define MAX_TASKS 16 |
---|
72 | |
---|
73 | /* |
---|
74 | * This may need to be removed in certain implementations. |
---|
75 | */ |
---|
76 | #ifndef NULL |
---|
77 | # define NULL ((void *)0) |
---|
78 | #endif /* NULL */ |
---|
79 | |
---|
80 | typedef sint8 TaskId; |
---|
81 | typedef sint32 BDIdx; |
---|
82 | |
---|
83 | /* |
---|
84 | * Special "task IDs" for interrupt handling API functions |
---|
85 | */ |
---|
86 | /*! \brief Debug interrupt "task ID" */ |
---|
87 | #define DEBUG_INTR_ID SDMA_INT_BIT_DBG |
---|
88 | |
---|
89 | /*! \brief TEA interrupt "task ID" */ |
---|
90 | #define TEA_INTR_ID SDMA_INT_BIT_TEA |
---|
91 | |
---|
92 | /*! \brief Task start autostart enable */ |
---|
93 | #define TASK_AUTOSTART_ENABLE 1 |
---|
94 | |
---|
95 | /*! \brief Task start autostart disable */ |
---|
96 | #define TASK_AUTOSTART_DISABLE 0 |
---|
97 | |
---|
98 | /*! \brief Task start interrupt enable */ |
---|
99 | #define TASK_INTERRUPT_ENABLE 1 |
---|
100 | |
---|
101 | /*! \brief Task start interrupt disable */ |
---|
102 | #define TASK_INTERRUPT_DISABLE 0 |
---|
103 | |
---|
104 | /* |
---|
105 | * Buffer descriptor flags to pass to TaskBDAssign(). |
---|
106 | */ |
---|
107 | /*! \brief Transmit frame done */ |
---|
108 | #define TASK_BD_TFD (1 << SDMA_DRD_BIT_TFD) |
---|
109 | |
---|
110 | /*! \brief Interrupt on frame done */ |
---|
111 | #define TASK_BD_INT (1 << SDMA_DRD_BIT_INT) |
---|
112 | |
---|
113 | /*! |
---|
114 | * \brief Data transfer size |
---|
115 | */ |
---|
116 | typedef enum { |
---|
117 | SZ_FLEX = 3, /*!< invalid for TaskSetupParamSet_t */ |
---|
118 | SZ_UINT8 = 1, /*!< 1-byte */ |
---|
119 | SZ_UINT16 = 2, /*!< 2-byte */ |
---|
120 | SZ_UINT32 = 4 /*!< 4-byte */ |
---|
121 | } Sz_t; |
---|
122 | |
---|
123 | /*! |
---|
124 | * \brief API error codes |
---|
125 | */ |
---|
126 | typedef enum { |
---|
127 | TASK_ERR_NO_ERR = -1, /*!< No error */ |
---|
128 | TASK_ERR_NO_INTR = TASK_ERR_NO_ERR, |
---|
129 | /*!< No interrupt */ |
---|
130 | TASK_ERR_INVALID_ARG = -2, /*!< Invalid function argument */ |
---|
131 | TASK_ERR_BD_RING_FULL = -3, /*!< Buffer descriptor ring full*/ |
---|
132 | TASK_ERR_API_ALREADY_INITIALIZED |
---|
133 | = -4, /*!< API has already been initialized */ |
---|
134 | TASK_ERR_SIZE_TOO_LARGE = -5, /*!< Buffer descriptor cannot support size parameter */ |
---|
135 | TASK_ERR_BD_RING_EMPTY = -6, /*!< Buffer descriptor ring is empty*/ |
---|
136 | TASK_ERR_BD_BUSY = -7, /*!< The buffer descriptor is in use |
---|
137 | by the BestComm */ |
---|
138 | TASK_ERR_TASK_RUNNING = -8 /*!< The task is running. */ |
---|
139 | |
---|
140 | } TaskErr_t; |
---|
141 | |
---|
142 | /*! |
---|
143 | * \brief BestComm initiators |
---|
144 | * |
---|
145 | * These are assigned by TaskSetup(). |
---|
146 | */ |
---|
147 | typedef enum { |
---|
148 | |
---|
149 | INITIATOR_ALWAYS = 0, |
---|
150 | INITIATOR_SCTMR_0 = 1, |
---|
151 | INITIATOR_SCTMR_1 = 2, |
---|
152 | INITIATOR_FEC_RX = 3, |
---|
153 | INITIATOR_FEC_TX = 4, |
---|
154 | INITIATOR_ATA_RX = 5, |
---|
155 | INITIATOR_ATA_TX = 6, |
---|
156 | INITIATOR_SCPCI_RX = 7, |
---|
157 | INITIATOR_SCPCI_TX = 8, |
---|
158 | INITIATOR_PSC3_RX = 9, |
---|
159 | INITIATOR_PSC3_TX = 10, |
---|
160 | INITIATOR_PSC2_RX = 11, |
---|
161 | INITIATOR_PSC2_TX = 12, |
---|
162 | INITIATOR_PSC1_RX = 13, |
---|
163 | INITIATOR_PSC1_TX = 14, |
---|
164 | INITIATOR_SCTMR_2 = 15, |
---|
165 | |
---|
166 | INITIATOR_SCLPC = 16, |
---|
167 | INITIATOR_PSC5_RX = 17, |
---|
168 | INITIATOR_PSC5_TX = 18, |
---|
169 | INITIATOR_PSC4_RX = 19, |
---|
170 | INITIATOR_PSC4_TX = 20, |
---|
171 | INITIATOR_I2C2_RX = 21, |
---|
172 | INITIATOR_I2C2_TX = 22, |
---|
173 | INITIATOR_I2C1_RX = 23, |
---|
174 | INITIATOR_I2C1_TX = 24, |
---|
175 | INITIATOR_PSC6_RX = 25, |
---|
176 | INITIATOR_PSC6_TX = 26, |
---|
177 | INITIATOR_IRDA_RX = 25, |
---|
178 | INITIATOR_IRDA_TX = 26, |
---|
179 | INITIATOR_SCTMR_3 = 27, |
---|
180 | INITIATOR_SCTMR_4 = 28, |
---|
181 | INITIATOR_SCTMR_5 = 29, |
---|
182 | INITIATOR_SCTMR_6 = 30, |
---|
183 | INITIATOR_SCTMR_7 = 31 |
---|
184 | |
---|
185 | } MPC5200Initiator_t; |
---|
186 | |
---|
187 | /*! |
---|
188 | * \brief Parameters for TaskSetup() |
---|
189 | * |
---|
190 | * All parameters can be hard-coded by the task API. Hard-coded values |
---|
191 | * will be changed in the struct passed to TaskSetup() for the user to |
---|
192 | * examine later. |
---|
193 | */ |
---|
194 | typedef struct { |
---|
195 | uint32 NumBD; /*!< Number of buffer descriptors */ |
---|
196 | |
---|
197 | union { |
---|
198 | uint32 MaxBuf; /*!< Maximum buffer size */ |
---|
199 | uint32 NumBytes; /*!< Number of bytes to transfer */ |
---|
200 | } Size; /*!< Buffer size union for BD and non-BD tasks */ |
---|
201 | |
---|
202 | MPC5200Initiator_t |
---|
203 | Initiator; /*!< BestComm initiator (ignored if hard-wired) */ |
---|
204 | uint32 StartAddrSrc; /*!< Address of the DMA source (e.g. a FIFO) */ |
---|
205 | sint16 IncrSrc; /*!< Amount to increment source pointer */ |
---|
206 | Sz_t SzSrc; /*!< Size of source data access */ |
---|
207 | uint32 StartAddrDst; /*!< Address of the DMA destination (e.g. a FIFO) */ |
---|
208 | sint16 IncrDst; /*!< Amount to increment data pointer */ |
---|
209 | Sz_t SzDst; /*!< Size of destination data access */ |
---|
210 | } TaskSetupParamSet_t; |
---|
211 | |
---|
212 | /*! |
---|
213 | * \brief Parameters for TaskDebug() |
---|
214 | * |
---|
215 | * TaskDebug() and the contents of this data structure are yet to be |
---|
216 | * determined. |
---|
217 | */ |
---|
218 | typedef struct { |
---|
219 | int dummy; /* Some compilers don't like empty struct typedefs */ |
---|
220 | } TaskDebugParamSet_t; |
---|
221 | |
---|
222 | /*! |
---|
223 | * \brief Generic buffer descriptor. |
---|
224 | * |
---|
225 | * It is generally used as a pointer which should be cast to one of the |
---|
226 | * other BD types based on the number of buffers per descriptor. |
---|
227 | */ |
---|
228 | typedef struct { |
---|
229 | uint32 Status; /*!< Status and length bits */ |
---|
230 | } TaskBD_t; |
---|
231 | |
---|
232 | /*! |
---|
233 | * \brief Single buffer descriptor. |
---|
234 | */ |
---|
235 | typedef struct { |
---|
236 | uint32 Status; /*!< Status and length bits */ |
---|
237 | uint32 DataPtr[1]; /*!< Pointer to data buffer */ |
---|
238 | } TaskBD1_t; |
---|
239 | |
---|
240 | /*! |
---|
241 | * \brief Dual buffer descriptor. |
---|
242 | */ |
---|
243 | typedef struct { |
---|
244 | uint32 Status; /*!< Status and length bits */ |
---|
245 | uint32 DataPtr[2]; /*!< Pointer to data buffers */ |
---|
246 | } TaskBD2_t; |
---|
247 | |
---|
248 | |
---|
249 | |
---|
250 | /*************************** |
---|
251 | * Start of API Prototypes |
---|
252 | ***************************/ |
---|
253 | |
---|
254 | #include "../bestcomm/bestcomm_priv.h" |
---|
255 | #include "../bestcomm/dma_image.capi.h" |
---|
256 | |
---|
257 | /*! |
---|
258 | * \brief Initialize a single task. |
---|
259 | * \param TaskName Type of task to initialize. E.g. PCI transmit, |
---|
260 | * ethernet receive, general purpose dual-pointer. |
---|
261 | * Values expected can be found in the TaskName_t |
---|
262 | * enum defined in dma_image.capi.h. |
---|
263 | * \param TaskSetupParams Task-specific parameters. The user must fill out |
---|
264 | * the pertinent parts of a TaskSetupParamSet_t |
---|
265 | * data structure. |
---|
266 | * \returns TaskId task identification token which is a required |
---|
267 | * parameter for most other API functions. |
---|
268 | * |
---|
269 | * This function returns a task identification token which is a required |
---|
270 | * parameter for most other API functions. |
---|
271 | * |
---|
272 | * Certain values of the structure pointed to by TaskParams are set |
---|
273 | * as a side-effect based on task type. These may be examined after |
---|
274 | * a successful call to TaskSetup(). User-specified values may be |
---|
275 | * overridden. |
---|
276 | * |
---|
277 | * TaskId TaskSetup( TaskName_t TaskName, |
---|
278 | * TaskSetupParamSet_t *TaskSetupParams ); |
---|
279 | */ |
---|
280 | #define TaskSetup(TaskName, TaskSetupParams) \ |
---|
281 | TaskSetup_ ## TaskName (TaskName ## _api, TaskSetupParams) |
---|
282 | |
---|
283 | const char *TaskVersion(void); |
---|
284 | |
---|
285 | int TasksInitAPI(uint8 *MBarRef); |
---|
286 | |
---|
287 | int TasksInitAPI_VM(uint8 *MBarRef, uint8 *MBarPhys); |
---|
288 | |
---|
289 | void TasksLoadImage(sdma_regs *sdma); |
---|
290 | int TasksAttachImage(sdma_regs *sdma); |
---|
291 | |
---|
292 | uint32 TasksGetSramOffset(void); |
---|
293 | void TasksSetSramOffset(uint32 sram_offset); |
---|
294 | |
---|
295 | int TaskStart(TaskId taskId, uint32 autoStartEnable, |
---|
296 | TaskId autoStartTask, uint32 intrEnable); |
---|
297 | int TaskStop(TaskId taskId); |
---|
298 | static int TaskStatus(TaskId taskId); |
---|
299 | BDIdx TaskBDAssign(TaskId taskId, void *buffer0, void *buffer1, |
---|
300 | int size, uint32 bdFlags); |
---|
301 | BDIdx TaskBDRelease(TaskId taskId); |
---|
302 | BDIdx TaskBDReset(TaskId taskId); |
---|
303 | static TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd); |
---|
304 | static TaskBD_t *TaskGetBDRing(TaskId taskId); |
---|
305 | int TaskDebug(TaskId taskId, TaskDebugParamSet_t *paramSet); |
---|
306 | static int TaskIntClear(TaskId taskId); |
---|
307 | static TaskId TaskIntStatus(TaskId taskId); |
---|
308 | static int TaskIntPending(TaskId taskId); |
---|
309 | static TaskId TaskIntSource(void); |
---|
310 | static uint16 TaskBDInUse(TaskId taskId); |
---|
311 | |
---|
312 | |
---|
313 | /*! |
---|
314 | * \brief Get the enable/disable status of a task. |
---|
315 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
316 | * \returns Boolean true indicates enabled or false indicates disabled |
---|
317 | * or invalid taskId. |
---|
318 | */ |
---|
319 | static inline int TaskStatus(TaskId taskId) |
---|
320 | { |
---|
321 | return SDMA_TASK_STATUS(SDMA_TCR, taskId) & 0x8000; |
---|
322 | } |
---|
323 | |
---|
324 | /*! |
---|
325 | * \brief Return a pointer to a buffer descriptor at index BDIdx |
---|
326 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
327 | * \param bd Buffer descriptor handle returned by |
---|
328 | * TaskBDAssign() or TaskBDRelease(). |
---|
329 | * \returns Pointer to the requested buffer descriptor or NULL on error. |
---|
330 | * |
---|
331 | * The returned pointer should be cast to the appropriate buffer |
---|
332 | * descriptor type, TaskBD1_t or TaskBD2_t. |
---|
333 | */ |
---|
334 | static inline TaskBD_t *TaskGetBD(TaskId taskId, BDIdx bd) |
---|
335 | { |
---|
336 | TaskBD_t *bdTab; |
---|
337 | |
---|
338 | bdTab = TaskBDIdxTable[taskId].BDTablePtr; |
---|
339 | if (TaskBDIdxTable[taskId].numPtr == 1) { |
---|
340 | return (TaskBD_t *)&(((TaskBD1_t *)bdTab)[bd]); |
---|
341 | } else { |
---|
342 | return (TaskBD_t *)&(((TaskBD2_t *)bdTab)[bd]); |
---|
343 | } |
---|
344 | } |
---|
345 | |
---|
346 | /*! |
---|
347 | * \brief Return a pointer to the first buffer descriptor in the ring. |
---|
348 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
349 | * \returns Pointer to the array of buffer descriptors making up the |
---|
350 | * ring or NULL on error. |
---|
351 | * |
---|
352 | * A device driver author may choose to use this in lieu of |
---|
353 | * TaskBDAssign()/TaskBDRelease() to get direct access to the |
---|
354 | * BD ring with the warning that the underlying data structure may change. |
---|
355 | * Use at one's own discretion. |
---|
356 | */ |
---|
357 | static inline TaskBD_t *TaskGetBDRing(TaskId taskId) |
---|
358 | { |
---|
359 | return TaskBDIdxTable[taskId].BDTablePtr; |
---|
360 | } |
---|
361 | |
---|
362 | /*! |
---|
363 | * \brief Clear the interrupt for a given BestComm task. |
---|
364 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
365 | * \returns TASK_ERR_NO_ERR (which is not really an error) for success |
---|
366 | */ |
---|
367 | static inline int TaskIntClear(TaskId taskId) |
---|
368 | { |
---|
369 | SDMA_CLEAR_IEVENT(SDMA_INT_PEND, taskId); |
---|
370 | return TASK_ERR_NO_ERR; /* success */ |
---|
371 | } |
---|
372 | |
---|
373 | /*! |
---|
374 | * \brief Get the interrupt status for a given task. |
---|
375 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
376 | * \returns TASK_ERR_NO_INTR (which is not really an error) for no interrupt |
---|
377 | * pending, taskId for a regular interrupt, DEBUG_INTR_ID for |
---|
378 | * a debug interrupt and TEA_INTR_ID for a TEA interrupt. |
---|
379 | * \b Note: TaskIntStatus() may return 0, but this means that that |
---|
380 | * taskId 0 is interrupt pending. |
---|
381 | */ |
---|
382 | static inline TaskId TaskIntStatus(TaskId taskId) |
---|
383 | { |
---|
384 | uint32 pending; |
---|
385 | |
---|
386 | pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK); |
---|
387 | |
---|
388 | if (SDMA_INT_TEST(pending, taskId)) { |
---|
389 | return taskId; |
---|
390 | } else if (SDMA_INT_TEST(pending, DEBUG_INTR_ID)) { |
---|
391 | return DEBUG_INTR_ID; |
---|
392 | } else if (SDMA_INT_TEST(pending, TEA_INTR_ID)) { |
---|
393 | return TEA_INTR_ID; |
---|
394 | } |
---|
395 | |
---|
396 | return TASK_ERR_NO_INTR; |
---|
397 | } |
---|
398 | |
---|
399 | /*! |
---|
400 | * \brief Get the interrupt pending status for a given task. |
---|
401 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
402 | * \returns 0 if task does not have a pending interrupt. 1 if the task |
---|
403 | * has an interrupt pending. |
---|
404 | */ |
---|
405 | static inline int TaskIntPending(TaskId taskId) |
---|
406 | { |
---|
407 | uint32 pending; |
---|
408 | |
---|
409 | pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK); |
---|
410 | if (SDMA_INT_TEST(pending, taskId)) { |
---|
411 | return 1; |
---|
412 | } else { |
---|
413 | return 0; |
---|
414 | } |
---|
415 | } |
---|
416 | |
---|
417 | /*! |
---|
418 | * \brief Returns the task ID of an interrupting BestComm task. |
---|
419 | * \returns TASK_ERR_NO_INTR (which is not really an error) for no interrupt |
---|
420 | * pending or the taskId of the interrupting task. |
---|
421 | * |
---|
422 | * The user must query TaskIntStatus() to discover if this is a debug |
---|
423 | * or TEA interrupt. This function is designed for use by an operating |
---|
424 | * system interrupt handler. |
---|
425 | */ |
---|
426 | static inline TaskId TaskIntSource(void) |
---|
427 | { |
---|
428 | uint32 pending; |
---|
429 | uint32 mask = 1 << (MAX_TASKS - 1); |
---|
430 | TaskId i; |
---|
431 | |
---|
432 | pending = SDMA_INT_PENDING(SDMA_INT_PEND, SDMA_INT_MASK); |
---|
433 | |
---|
434 | if (SDMA_INT_TEST(pending, SDMA_INT_BIT_TEA)) { |
---|
435 | return (TaskId)SDMA_TEA_SOURCE(SDMA_INT_PEND); |
---|
436 | } |
---|
437 | |
---|
438 | for (i = (MAX_TASKS - 1); i >= 0; --i, mask >>= 1) { |
---|
439 | if (pending & mask) { |
---|
440 | return i; |
---|
441 | } |
---|
442 | } |
---|
443 | |
---|
444 | return TASK_ERR_NO_INTR; |
---|
445 | } |
---|
446 | |
---|
447 | /*! |
---|
448 | * \brief Get a count of in-use buffer descriptors. |
---|
449 | * \param taskId Task handle passed back from a successful TaskSetup() |
---|
450 | * \returns Count of the current number of BDs in use by the given task. |
---|
451 | */ |
---|
452 | static inline uint16 TaskBDInUse(TaskId taskId) |
---|
453 | { |
---|
454 | return TaskBDIdxTable[taskId].currBDInUse; |
---|
455 | } |
---|
456 | |
---|
457 | #endif /* __BESTCOMM_API_H */ |
---|