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