Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Public header for the MPC52xx processor BestComm driver
0003  *
0004  *
0005  * Copyright (C) 2006      Sylvain Munaut <tnt@246tNt.com>
0006  * Copyright (C) 2005      Varma Electronics Oy,
0007  *                         ( by Andrey Volkov <avolkov@varma-el.com> )
0008  * Copyright (C) 2003-2004 MontaVista, Software, Inc.
0009  *                         ( by Dale Farnsworth <dfarnsworth@mvista.com> )
0010  *
0011  * This file is licensed under the terms of the GNU General Public License
0012  * version 2. This program is licensed "as is" without any warranty of any
0013  * kind, whether express or implied.
0014  */
0015 
0016 #ifndef __BESTCOMM_H__
0017 #define __BESTCOMM_H__
0018 
0019 /**
0020  * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
0021  * @status: The current status of this buffer. Exact meaning depends on the
0022  *          task type
0023  * @data: An array of u32 extra data.  Size of array is task dependent.
0024  *
0025  * Note: Don't dereference a bcom_bd pointer as an array.  The size of the
0026  *       bcom_bd is variable.  Use bcom_get_bd() instead.
0027  */
0028 struct bcom_bd {
0029     u32 status;
0030     u32 data[]; /* variable payload size */
0031 };
0032 
0033 /* ======================================================================== */
0034 /* Generic task management                                                   */
0035 /* ======================================================================== */
0036 
0037 /**
0038  * struct bcom_task - Structure describing a loaded BestComm task
0039  *
0040  * This structure is never built by the driver it self. It's built and
0041  * filled the intermediate layer of the BestComm API, the task dependent
0042  * support code.
0043  *
0044  * Most likely you don't need to poke around inside this structure. The
0045  * fields are exposed in the header just for the sake of inline functions
0046  */
0047 struct bcom_task {
0048     unsigned int    tasknum;
0049     unsigned int    flags;
0050     int     irq;
0051 
0052     struct bcom_bd  *bd;
0053     phys_addr_t bd_pa;
0054     void        **cookie;
0055     unsigned short  index;
0056     unsigned short  outdex;
0057     unsigned int    num_bd;
0058     unsigned int    bd_size;
0059 
0060     void*       priv;
0061 };
0062 
0063 #define BCOM_FLAGS_NONE         0x00000000ul
0064 #define BCOM_FLAGS_ENABLE_TASK  (1ul <<  0)
0065 
0066 /**
0067  * bcom_enable - Enable a BestComm task
0068  * @tsk: The BestComm task structure
0069  *
0070  * This function makes sure the given task is enabled and can be run
0071  * by the BestComm engine as needed
0072  */
0073 extern void bcom_enable(struct bcom_task *tsk);
0074 
0075 /**
0076  * bcom_disable - Disable a BestComm task
0077  * @tsk: The BestComm task structure
0078  *
0079  * This function disable a given task, making sure it's not executed
0080  * by the BestComm engine.
0081  */
0082 extern void bcom_disable(struct bcom_task *tsk);
0083 
0084 
0085 /**
0086  * bcom_get_task_irq - Returns the irq number of a BestComm task
0087  * @tsk: The BestComm task structure
0088  */
0089 static inline int
0090 bcom_get_task_irq(struct bcom_task *tsk) {
0091     return tsk->irq;
0092 }
0093 
0094 /* ======================================================================== */
0095 /* BD based tasks helpers                                                   */
0096 /* ======================================================================== */
0097 
0098 #define BCOM_BD_READY   0x40000000ul
0099 
0100 /** _bcom_next_index - Get next input index.
0101  * @tsk: pointer to task structure
0102  *
0103  * Support function; Device drivers should not call this
0104  */
0105 static inline int
0106 _bcom_next_index(struct bcom_task *tsk)
0107 {
0108     return ((tsk->index + 1) == tsk->num_bd) ? 0 : tsk->index + 1;
0109 }
0110 
0111 /** _bcom_next_outdex - Get next output index.
0112  * @tsk: pointer to task structure
0113  *
0114  * Support function; Device drivers should not call this
0115  */
0116 static inline int
0117 _bcom_next_outdex(struct bcom_task *tsk)
0118 {
0119     return ((tsk->outdex + 1) == tsk->num_bd) ? 0 : tsk->outdex + 1;
0120 }
0121 
0122 /**
0123  * bcom_queue_empty - Checks if a BestComm task BD queue is empty
0124  * @tsk: The BestComm task structure
0125  */
0126 static inline int
0127 bcom_queue_empty(struct bcom_task *tsk)
0128 {
0129     return tsk->index == tsk->outdex;
0130 }
0131 
0132 /**
0133  * bcom_queue_full - Checks if a BestComm task BD queue is full
0134  * @tsk: The BestComm task structure
0135  */
0136 static inline int
0137 bcom_queue_full(struct bcom_task *tsk)
0138 {
0139     return tsk->outdex == _bcom_next_index(tsk);
0140 }
0141 
0142 /**
0143  * bcom_get_bd - Get a BD from the queue
0144  * @tsk: The BestComm task structure
0145  * index: Index of the BD to fetch
0146  */
0147 static inline struct bcom_bd
0148 *bcom_get_bd(struct bcom_task *tsk, unsigned int index)
0149 {
0150     /* A cast to (void*) so the address can be incremented by the
0151      * real size instead of by sizeof(struct bcom_bd) */
0152     return ((void *)tsk->bd) + (index * tsk->bd_size);
0153 }
0154 
0155 /**
0156  * bcom_buffer_done - Checks if a BestComm 
0157  * @tsk: The BestComm task structure
0158  */
0159 static inline int
0160 bcom_buffer_done(struct bcom_task *tsk)
0161 {
0162     struct bcom_bd *bd;
0163     if (bcom_queue_empty(tsk))
0164         return 0;
0165 
0166     bd = bcom_get_bd(tsk, tsk->outdex);
0167     return !(bd->status & BCOM_BD_READY);
0168 }
0169 
0170 /**
0171  * bcom_prepare_next_buffer - clear status of next available buffer.
0172  * @tsk: The BestComm task structure
0173  *
0174  * Returns pointer to next buffer descriptor
0175  */
0176 static inline struct bcom_bd *
0177 bcom_prepare_next_buffer(struct bcom_task *tsk)
0178 {
0179     struct bcom_bd *bd;
0180 
0181     bd = bcom_get_bd(tsk, tsk->index);
0182     bd->status = 0; /* cleanup last status */
0183     return bd;
0184 }
0185 
0186 static inline void
0187 bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
0188 {
0189     struct bcom_bd *bd = bcom_get_bd(tsk, tsk->index);
0190 
0191     tsk->cookie[tsk->index] = cookie;
0192     mb();   /* ensure the bd is really up-to-date */
0193     bd->status |= BCOM_BD_READY;
0194     tsk->index = _bcom_next_index(tsk);
0195     if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
0196         bcom_enable(tsk);
0197 }
0198 
0199 static inline void *
0200 bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
0201 {
0202     void *cookie = tsk->cookie[tsk->outdex];
0203     struct bcom_bd *bd = bcom_get_bd(tsk, tsk->outdex);
0204 
0205     if (p_status)
0206         *p_status = bd->status;
0207     if (p_bd)
0208         *p_bd = bd;
0209     tsk->outdex = _bcom_next_outdex(tsk);
0210     return cookie;
0211 }
0212 
0213 #endif /* __BESTCOMM_H__ */