blob: e802cb4eb69a5c575a8849147b1be7083568e9a7 [file] [log] [blame]
Sylvain Munaut2f9ea1b2007-09-16 20:53:27 +10001/*
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
19struct bcom_bd; /* defined later on ... */
20
21
22/* ======================================================================== */
23/* Generic task managment */
24/* ======================================================================== */
25
26/**
27 * struct bcom_task - Structure describing a loaded BestComm task
28 *
29 * This structure is never built by the driver it self. It's built and
30 * filled the intermediate layer of the BestComm API, the task dependent
31 * support code.
32 *
33 * Most likely you don't need to poke around inside this structure. The
34 * fields are exposed in the header just for the sake of inline functions
35 */
36struct bcom_task {
37 unsigned int tasknum;
38 unsigned int flags;
39 int irq;
40
41 struct bcom_bd *bd;
42 phys_addr_t bd_pa;
43 void **cookie;
44 unsigned short index;
45 unsigned short outdex;
46 unsigned int num_bd;
47 unsigned int bd_size;
48
49 void* priv;
50};
51
52#define BCOM_FLAGS_NONE 0x00000000ul
53#define BCOM_FLAGS_ENABLE_TASK (1ul << 0)
54
55/**
56 * bcom_enable - Enable a BestComm task
57 * @tsk: The BestComm task structure
58 *
59 * This function makes sure the given task is enabled and can be run
60 * by the BestComm engine as needed
61 */
62extern void bcom_enable(struct bcom_task *tsk);
63
64/**
65 * bcom_disable - Disable a BestComm task
66 * @tsk: The BestComm task structure
67 *
68 * This function disable a given task, making sure it's not executed
69 * by the BestComm engine.
70 */
71extern void bcom_disable(struct bcom_task *tsk);
72
73
74/**
75 * bcom_get_task_irq - Returns the irq number of a BestComm task
76 * @tsk: The BestComm task structure
77 */
78static inline int
79bcom_get_task_irq(struct bcom_task *tsk) {
80 return tsk->irq;
81}
82
83/* ======================================================================== */
84/* BD based tasks helpers */
85/* ======================================================================== */
86
87/**
88 * struct bcom_bd - Structure describing a generic BestComm buffer descriptor
89 * @status: The current status of this buffer. Exact meaning depends on the
90 * task type
91 * @data: An array of u32 whose meaning depends on the task type.
92 */
93struct bcom_bd {
94 u32 status;
95 u32 data[1]; /* variable, but at least 1 */
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_buffer_done - Checks if a BestComm
144 * @tsk: The BestComm task structure
145 */
146static inline int
147bcom_buffer_done(struct bcom_task *tsk)
148{
149 if (bcom_queue_empty(tsk))
150 return 0;
151 return !(tsk->bd[tsk->outdex].status & BCOM_BD_READY);
152}
153
154/**
155 * bcom_prepare_next_buffer - clear status of next available buffer.
156 * @tsk: The BestComm task structure
157 *
158 * Returns pointer to next buffer descriptor
159 */
160static inline struct bcom_bd *
161bcom_prepare_next_buffer(struct bcom_task *tsk)
162{
163 tsk->bd[tsk->index].status = 0; /* cleanup last status */
164 return &tsk->bd[tsk->index];
165}
166
167static inline void
168bcom_submit_next_buffer(struct bcom_task *tsk, void *cookie)
169{
170 tsk->cookie[tsk->index] = cookie;
171 mb(); /* ensure the bd is really up-to-date */
172 tsk->bd[tsk->index].status |= BCOM_BD_READY;
173 tsk->index = _bcom_next_index(tsk);
174 if (tsk->flags & BCOM_FLAGS_ENABLE_TASK)
175 bcom_enable(tsk);
176}
177
178static inline void *
179bcom_retrieve_buffer(struct bcom_task *tsk, u32 *p_status, struct bcom_bd **p_bd)
180{
181 void *cookie = tsk->cookie[tsk->outdex];
182 if (p_status)
183 *p_status = tsk->bd[tsk->outdex].status;
184 if (p_bd)
185 *p_bd = &tsk->bd[tsk->outdex];
186 tsk->outdex = _bcom_next_outdex(tsk);
187 return cookie;
188}
189
190#endif /* __BESTCOMM_H__ */