bestcomm.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * Public header for the MPC52xx processor BestComm driver
  3. *
  4. *
  5. * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
  6. * Copyright (C) 2005 Varma Electronics Oy,
  7. * ( by Andrey Volkov <avolkov@varma-el.com> )
  8. * Copyright (C) 2003-2004 MontaVista, Software, Inc.
  9. * ( by Dale Farnsworth <dfarnsworth@mvista.com> )
  10. *
  11. * This file is licensed under the terms of the GNU General Public License
  12. * version 2. This program is licensed "as is" without any warranty of any
  13. * kind, whether express or implied.
  14. */
  15. #ifndef __BESTCOMM_H__
  16. #define __BESTCOMM_H__
  17. /**
  18. * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
  19. * @status: The current status of this buffer. Exact meaning depends on the
  20. * task type
  21. * @data: An array of u32 extra data. Size of array is task dependent.
  22. *
  23. * Note: Don't dereference a bcom_bd pointer as an array. The size of the
  24. * bcom_bd is variable. Use bcom_get_bd() instead.
  25. */
  26. struct bcom_bd {
  27. u32 status;
  28. u32 data[0]; /* variable payload size */
  29. };
  30. /* ======================================================================== */
  31. /* Generic task management */
  32. /* ======================================================================== */
  33. /**
  34. * struct bcom_task - Structure describing a loaded BestComm task
  35. *
  36. * This structure is never built by the driver it self. It's built and
  37. * filled the intermediate layer of the BestComm API, the task dependent
  38. * support code.
  39. *
  40. * Most likely you don't need to poke around inside this structure. The
  41. * fields are exposed in the header just for the sake of inline functions
  42. */
  43. struct bcom_task {
  44. unsigned int tasknum;
  45. unsigned int flags;
  46. int irq;
  47. struct bcom_bd *bd;
  48. phys_addr_t bd_pa;
  49. void **cookie;
  50. unsigned short index;
  51. unsigned short outdex;
  52. unsigned int num_bd;
  53. unsigned int bd_size;
  54. void* priv;
  55. };
  56. #define BCOM_FLAGS_NONE 0x00000000ul
  57. #define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
  58. /**
  59. * bcom_enable - Enable a BestComm task
  60. * @tsk: The BestComm task structure
  61. *
  62. * This function makes sure the given task is enabled and can be run
  63. * by the BestComm engine as needed
  64. */
  65. extern void bcom_enable(struct bcom_task *tsk);
  66. /**
  67. * bcom_disable - Disable a BestComm task
  68. * @tsk: The BestComm task structure
  69. *
  70. * This function disable a given task, making sure it's not executed
  71. * by the BestComm engine.
  72. */
  73. extern void bcom_disable(struct bcom_task *tsk);
  74. /**
  75. * bcom_get_task_irq - Returns the irq number of a BestComm task
  76. * @tsk: The BestComm task structure
  77. */
  78. static inline int
  79. bcom_get_task_irq(struct bcom_task *tsk) {
  80. return tsk->irq;
  81. }
  82. /* ======================================================================== */
  83. /* BD based tasks helpers */
  84. /* ======================================================================== */
  85. #define BCOM_BD_READY 0x40000000ul
  86. /** _bcom_next_index - Get next input index.
  87. * @tsk: pointer to task structure
  88. *
  89. * Support function; Device drivers should not call this
  90. */
  91. static inline int
  92. _bcom_next_index(struct bcom_task *tsk)
  93. {
  94. return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
  95. }
  96. /** _bcom_next_outdex - Get next output index.
  97. * @tsk: pointer to task structure
  98. *
  99. * Support function; Device drivers should not call this
  100. */
  101. static inline int
  102. _bcom_next_outdex(struct bcom_task *tsk)
  103. {
  104. return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
  105. }
  106. /**
  107. * bcom_queue_empty - Checks if a BestComm task BD queue is empty
  108. * @tsk: The BestComm task structure
  109. */
  110. static inline int
  111. bcom_queue_empty(struct bcom_task *tsk)
  112. {
  113. return tsk->index == tsk->outdex;
  114. }
  115. /**
  116. * bcom_queue_full - Checks if a BestComm task BD queue is full
  117. * @tsk: The BestComm task structure
  118. */
  119. static inline int
  120. bcom_queue_full(struct bcom_task *tsk)
  121. {
  122. return tsk->outdex == _bcom_next_index(tsk);
  123. }
  124. /**
  125. * bcom_get_bd - Get a BD from the queue
  126. * @tsk: The BestComm task structure
  127. * index: Index of the BD to fetch
  128. */
  129. static inline struct bcom_bd
  130. *bcom_get_bd(struct bcom_task *tsk, unsigned int index)
  131. {
  132. /* A cast to (void*) so the address can be incremented by the
  133. * real size instead of by sizeof(struct bcom_bd) */
  134. return ((void *)tsk->bd) + (index * tsk->bd_size);
  135. }
  136. /**
  137. * bcom_buffer_done - Checks if a BestComm
  138. * @tsk: The BestComm task structure
  139. */
  140. static inline int
  141. bcom_buffer_done(struct bcom_task *tsk)
  142. {
  143. struct bcom_bd *bd;
  144. if (bcom_queue_empty(tsk))
  145. return 0;
  146. bd = bcom_get_bd(tsk, tsk->outdex);
  147. return !(bd->status & BCOM_BD_READY);
  148. }
  149. /**
  150. * bcom_prepare_next_buffer - clear status of next available buffer.
  151. * @tsk: The BestComm task structure
  152. *
  153. * Returns pointer to next buffer descriptor
  154. */
  155. static inline struct bcom_bd *
  156. bcom_prepare_next_buffer(struct bcom_task *tsk)
  157. {
  158. struct bcom_bd *bd;
  159. bd = bcom_get_bd(tsk, tsk->index);
  160. bd->status = 0; /* cleanup last status */
  161. return bd;
  162. }
  163. static inline void
  164. bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
  165. {
  166. struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
  167. tsk->cookie[tsk->index] = cookie;
  168. mb(); /* ensure the bd is really up-to-date */
  169. bd->status |= BCOM_BD_READY;
  170. tsk->index = _bcom_next_index(tsk);
  171. if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
  172. bcom_enable(tsk);
  173. }
  174. static inline void *
  175. bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
  176. {
  177. void *cookie = tsk->cookie[tsk->outdex];
  178. struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
  179. if (p_status)
  180. *p_status = bd->status;
  181. if (p_bd)
  182. *p_bd = bd;
  183. tsk->outdex = _bcom_next_outdex(tsk);
  184. return cookie;
  185. }
  186. #endif /* __BESTCOMM_H__ */