]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/dsp/ipbuf.h
9a6e3db103cd034ae6b34befc7db1ef8c9a17189
[linux-2.6-omap-h63xx.git] / arch / arm / plat-omap / dsp / ipbuf.h
1 /*
2  * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
3  *
4  * Copyright (C) 2002-2006 Nokia Corporation. All rights reserved.
5  *
6  * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License 
10  * version 2 as published by the Free Software Foundation. 
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 struct ipbuf {
25         u16 c;                  /* count */
26         u16 next;               /* link */
27         u16 la;                 /* lock owner (ARM side) */
28         u16 sa;                 /* sync word (ARM->DSP) */
29         u16 ld;                 /* lock owner (DSP side) */
30         u16 sd;                 /* sync word (DSP->ARM) */
31         unsigned char d[0];     /* data */
32 };
33
34 struct ipbuf_p {
35         u16 c;          /* count */
36         u16 s;          /* sync word */
37         u16 al;         /* data address lower */
38         u16 ah;         /* data address upper */
39 };
40
41 #define IPBUF_SYS_DLEN  31
42
43 struct ipbuf_sys {
44         u16 s;                  /* sync word */
45         u16 d[IPBUF_SYS_DLEN];  /* data */
46 };
47
48 struct ipbcfg {
49         u16 ln;
50         u16 lsz;
51         void *base;
52         u16 bsycnt;
53         unsigned long cnt_full; /* count of IPBFULL error */
54 };
55
56 struct ipbuf_head {
57         u16 bid;
58         struct ipbuf *p;
59 };
60
61 extern struct ipbcfg ipbcfg;
62 extern struct ipbuf_sys *ipbuf_sys_da, *ipbuf_sys_ad;
63
64 #define ipb_bsycnt_inc(ipbcfg) \
65         do { \
66                 disable_mbx_irq(mbx_dsp); \
67                 (ipbcfg)->bsycnt++; \
68                 enable_mbx_irq(mbx_dsp); \
69         } while(0)
70
71 #define ipb_bsycnt_dec(ipbcfg) \
72         do { \
73                 disable_mbx_irq(mbx_dsp); \
74                 (ipbcfg)->bsycnt--; \
75                 enable_mbx_irq(mbx_dsp); \
76         } while(0)
77
78 #define dsp_mem_enable_ipbuf()  dsp_mem_enable(ipbcfg.base)
79 #define dsp_mem_disable_ipbuf() dsp_mem_disable(ipbcfg.base)
80
81 struct ipblink {
82         spinlock_t lock;
83         u16 top;
84         u16 tail;
85 };
86
87 #define IPBLINK_INIT { \
88                 .lock = SPIN_LOCK_UNLOCKED, \
89                 .top  = BID_NULL, \
90                 .tail = BID_NULL, \
91         }
92
93 #define INIT_IPBLINK(link) \
94         do { \
95                 spin_lock_init(&(link)->lock); \
96                 (link)->top  = BID_NULL; \
97                 (link)->tail = BID_NULL; \
98         } while(0)
99
100 #define RESET_IPBLINK(link) \
101         do { \
102                 (link)->top  = BID_NULL; \
103                 (link)->tail = BID_NULL; \
104         } while(0)
105
106 #define ipblink_empty(link)     ((link)->top == BID_NULL)
107
108 static __inline__ void __ipblink_del_top(struct ipblink *link)
109 {
110         struct ipbuf_head *ipb_h = bid_to_ipbuf(link->top);
111
112         if ((link->top = ipb_h->p->next) == BID_NULL)
113                 link->tail = BID_NULL;
114         else
115                 ipb_h->p->next = BID_NULL;
116 }
117
118 static __inline__ void ipblink_del_top(struct ipblink *link)
119 {
120         spin_lock(&link->lock);
121         __ipblink_del_top(link);
122         spin_unlock(&link->lock);
123 }
124
125 static __inline__ void __ipblink_add_tail(struct ipblink *link, u16 bid)
126 {
127         if (ipblink_empty(link))
128                 link->top = bid;
129         else
130                 bid_to_ipbuf(link->tail)->p->next = bid;
131         link->tail = bid;
132 }
133
134 static __inline__ void ipblink_add_tail(struct ipblink *link, u16 bid)
135 {
136         spin_lock(&link->lock);
137         __ipblink_add_tail(link, bid);
138         spin_unlock(&link->lock);
139 }
140
141 static __inline__ void __ipblink_flush(struct ipblink *link)
142 {
143         u16 bid;
144
145         while (!ipblink_empty(link)) {
146                 bid = link->top;
147                 __ipblink_del_top(link);
148                 unuse_ipbuf(bid_to_ipbuf(bid));
149         }
150 }
151
152 static __inline__ void ipblink_flush(struct ipblink *link)
153 {
154         spin_lock(&link->lock);
155         __ipblink_flush(link);
156         spin_unlock(&link->lock);
157 }
158
159 static __inline__ void __ipblink_add_pvt(struct ipblink *link)
160 {
161         link->top  = BID_PVT;
162         link->tail = BID_PVT;
163 }
164
165 static __inline__ void ipblink_add_pvt(struct ipblink *link)
166 {
167         spin_lock(&link->lock);
168         __ipblink_add_pvt(link);
169         spin_unlock(&link->lock);
170 }
171
172 static __inline__ void __ipblink_del_pvt(struct ipblink *link)
173 {
174         link->top  = BID_NULL;
175         link->tail = BID_NULL;
176 }
177
178 static __inline__ void ipblink_del_pvt(struct ipblink *link)
179 {
180         spin_lock(&link->lock);
181         __ipblink_del_pvt(link);
182         spin_unlock(&link->lock);
183 }
184
185 static __inline__ void __ipblink_flush_pvt(struct ipblink *link)
186 {
187         if (!ipblink_empty(link))
188                 ipblink_del_pvt(link);
189 }
190
191 static __inline__ void ipblink_flush_pvt(struct ipblink *link)
192 {
193         spin_lock(&link->lock);
194         __ipblink_flush_pvt(link);
195         spin_unlock(&link->lock);
196 }
197
198 #define ipblink_for_each(bid, link) \
199         for (bid = (link)->top; bid != BID_NULL; bid = bid_to_ipbuf(bid)->p->next)