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 */ 28struct 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 */ 47struct 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 */ 73extern 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 */ 82extern 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 */ 89static inline int 90bcom_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 */ 105static 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 */ 116static 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 */ 126static inline int 127bcom_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 */ 136static inline int 137bcom_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 */ 147static 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 */ 159static inline int 160bcom_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 */ 176static inline struct bcom_bd * 177bcom_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 186static inline void 187bcom_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 199static inline void * 200bcom_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