]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/plat-omap/dsp/ipbuf.h
3ceaa3c4d19f3924208c7e4ec72a1a133d76a0cb
[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_mbox_irq(mbox_dsp);     \
67                 (ipbcfg)->bsycnt++;             \
68                 enable_mbox_irq(mbox_dsp);      \
69         } while(0)
70
71 #define ipb_bsycnt_dec(ipbcfg)                  \
72         do {                                    \
73                 disable_mbox_irq(mbox_dsp);     \
74                 (ipbcfg)->bsycnt--;             \
75                 enable_mbox_irq(mbox_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)