4 * Copyright (C) 2006 Nokia Corporation. All rights reserved.
6 * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
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.
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.
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
24 #include <linux/init.h>
25 #include <linux/module.h>
26 #include <linux/sched.h>
27 #include <linux/interrupt.h>
28 #include <linux/err.h>
29 #ifdef CONFIG_ARCH_OMAP2
30 #include <linux/clk.h>
33 #ifdef CONFIG_ARCH_OMAP1
34 #include <asm/delay.h>
36 #include <asm/arch/mailbox.h>
37 #include "mailbox_hw.h"
39 #if defined(CONFIG_ARCH_OMAP1)
41 #define read_mbx(m, msgp) \
43 *(msgp) = omap_readw((m)->data_r); \
44 *(msgp) |= ((mbx_msg_t)omap_readw((m)->cmd_r)) << 16; \
46 #define write_mbx(m, msg) \
48 omap_writew((msg) & 0xffff, (m)->data_w); \
49 omap_writew((msg) >> 16, (m)->cmd_w); \
51 #define enable_newmsg_irq(m) enable_irq((m)->irq)
52 #define disable_newmsg_irq(m) disable_irq((m)->irq)
53 #define mbx_is_notfull(m) (omap_readw((m)->flag_w) == 0)
55 #elif defined(CONFIG_ARCH_OMAP2)
57 #define omap_bit_setl(b,r) \
58 do { omap_writel(omap_readl(r) | (b), (r)); } while(0)
59 #define omap_bit_clrl(b,r) \
60 do { omap_writel(omap_readl(r) & ~(b), (r)); } while(0)
62 #define read_mbx(m, msgp) \
63 do { *(msgp) = omap_readl((m)->message_r); } while (0)
64 #define write_mbx(m, msg) omap_writel(msg, (m)->message_w)
65 #define enable_newmsg_irq(m) omap_bit_setl((m)->newmsg_bit, (m)->irqenable)
66 #define disable_newmsg_irq(m) omap_bit_clrl((m)->newmsg_bit, (m)->irqenable)
67 #define enable_notfull_irq(m) omap_bit_setl((m)->notfull_bit, (m)->irqenable)
68 #define disable_notfull_irq(m) omap_bit_clrl((m)->notfull_bit, (m)->irqenable)
69 #define clear_newmsg_irq(m) omap_writel((m)->newmsg_bit, (m)->irqstatus)
70 #define clear_notfull_irq(m) omap_writel((m)->notfull_bit, (m)->irqstatus)
71 #define notfull_irq_enabled(m) (omap_readl((m)->irqenable) & (m)->notfull_bit)
72 #define has_newmsg_irq(m) (omap_readl((m)->irqstatus) & (m)->newmsg_bit)
73 #define has_notfull_irq(m) (omap_readl((m)->irqstatus) & (m)->notfull_bit)
74 #define mbx_nomsg(m) (omap_readl((m)->msgstatus_r) == 0)
75 #define mbx_is_notfull(m) (omap_readl((m)->fifostatus_w) == 0)
77 #endif /* CONFIG_ARCH_OMAP2 */
79 static void do_mbx(void *p);
83 mbx_msg_t msg[MBQ_DEPTH];
87 #define mbq_inc(p) do { if (++(p) == MBQ_DEPTH) (p) = 0; } while(0)
89 #if defined(CONFIG_ARCH_OMAP1)
90 # define MBX_USE_SEQ_BIT /* XXX */
91 #elif defined(CONFIG_ARCH_OMAP2)
92 # undef MBX_USE_SEQ_BIT
98 char irq_devid_newmsg;
99 #ifdef CONFIG_ARCH_OMAP2
100 char irq_devid_notfull;
102 #ifdef MBX_USE_SEQ_BIT
105 /* seq_rcv should be initialized with any value other than
106 * 0 and 1 << 31, to allow either value for the first
109 mbx_receiver_t *receiver_map[MBX_CMD_MAX];
110 struct work_struct work;
112 #ifdef CONFIG_ARCH_OMAP2
113 wait_queue_head_t full_wait_q;
116 #if defined(CONFIG_ARCH_OMAP1)
122 #elif defined(CONFIG_ARCH_OMAP2)
134 #if defined(CONFIG_ARCH_OMAP1)
136 #if defined(CONFIG_ARCH_OMAP15XX)
137 #define INT_DSP_MAILBOX1 INT_1510_DSP_MAILBOX1
138 #elif defined(CONFIG_ARCH_OMAP16XX)
139 #define INT_DSP_MAILBOX1 INT_1610_DSP_MAILBOX1
142 static struct mbx mbx_dsp = {
144 .irq = INT_DSP_MAILBOX1,
145 .work = __WORK_INITIALIZER(mbx_dsp.work, do_mbx, &mbx_dsp),
147 .cmd_w = (void *)MAILBOX_ARM2DSP1b,
148 .data_w = (void *)MAILBOX_ARM2DSP1,
149 .flag_w = (void *)MAILBOX_ARM2DSP1_Flag,
150 .cmd_r = (void *)MAILBOX_DSP2ARM1b,
151 .data_r = (void *)MAILBOX_DSP2ARM1,
154 #elif defined(CONFIG_ARCH_OMAP2)
157 * MAILBOX 0: ARM -> DSP,
158 * MAILBOX 1: ARM <- DSP.
159 * MAILBOX 2: ARM -> IVA,
160 * MAILBOX 3: ARM <- IVA.
162 static struct mbx mbx_dsp = {
164 .irq = INT_24XX_MAIL_U0_MPU,
165 .work = __WORK_INITIALIZER(mbx_dsp.work, do_mbx, &mbx_dsp),
166 .full_wait_q = __WAIT_QUEUE_HEAD_INITIALIZER(mbx_dsp.full_wait_q),
168 .irqenable = (void *)MAILBOX_IRQENABLE_0,
169 .irqstatus = (void *)MAILBOX_IRQSTATUS_0,
170 .message_w = (void *)MAILBOX_MESSAGE_0,
171 .message_r = (void *)MAILBOX_MESSAGE_1,
172 .fifostatus_w = (void *)MAILBOX_FIFOSTATUS_0,
173 .msgstatus_r = (void *)MAILBOX_MSGSTATUS_1,
174 .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
175 .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
177 static struct mbx mbx_iva = {
179 .irq = INT_24XX_MAIL_U3_MPU,
180 .work = __WORK_INITIALIZER(mbx_iva.work, do_mbx, &mbx_iva),
181 .full_wait_q = __WAIT_QUEUE_HEAD_INITIALIZER(mbx_iva.full_wait_q),
183 .irqenable = (void *)MAILBOX_IRQENABLE_3,
184 .irqstatus = (void *)MAILBOX_IRQSTATUS_3,
185 .message_w = (void *)MAILBOX_MESSAGE_2,
186 .message_r = (void *)MAILBOX_MESSAGE_3,
187 .fifostatus_w = (void *)MAILBOX_FIFOSTATUS_2,
188 .msgstatus_r = (void *)MAILBOX_MSGSTATUS_3,
189 .notfull_bit = MAILBOX_IRQ_NOTFULL(2),
190 .newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
193 #endif /* CONFIG_ARCH_OMAP2 */
195 static struct mbx *mbxes[] = {
197 #ifdef CONFIG_ARCH_OMAP2
202 struct mbx *mbx_get(const char *id)
206 for (i = 0; i < ARRAY_SIZE(mbxes); i++) {
207 if (!strcmp(id, mbxes[i]->name))
211 return ERR_PTR(-ENOENT);
214 #if defined(CONFIG_ARCH_OMAP1)
215 static __inline__ int mbsync_irq_save(struct mbx *mbx, unsigned long *flags,
220 local_irq_save(*flags);
221 if (mbx_is_notfull(mbx))
224 * mailbox is busy. wait for some usecs...
226 local_irq_restore(*flags);
227 for (cnt = 0; cnt < try_cnt; cnt++) {
229 local_irq_save(*flags);
230 if (mbx_is_notfull(mbx)) /* success! */
232 local_irq_restore(*flags);
238 #elif defined(CONFIG_ARCH_OMAP2)
239 static __inline__ int mbsync_irq_save(struct mbx *mbx, unsigned long *flags)
242 DECLARE_WAITQUEUE(wait, current);
245 local_irq_save(*flags);
246 if (mbx_is_notfull(mbx))
252 local_irq_restore(*flags);
253 enable_notfull_irq(mbx);
255 /* wait until the FIFO becomes not-full */
256 add_wait_queue(&mbx->full_wait_q, &wait);
257 current_state = current->state;
258 set_current_state(TASK_INTERRUPTIBLE);
259 if (!mbx_is_notfull(mbx)) /* last check */
261 set_current_state(current_state);
262 remove_wait_queue(&mbx->full_wait_q, &wait);
264 if (signal_pending(current))
271 * message dispatcher API
273 int mbx_send(struct mbx *mbx, mbx_msg_t msg)
277 #if defined(CONFIG_ARCH_OMAP1)
279 * DSP mailbox interrupt latency must be less than 1ms.
281 if (mbsync_irq_save(mbx, &flags, 1000) < 0) {
283 "mailbox(%s) is busy. message 0x%08x is aborting.\n",
287 #elif defined(CONFIG_ARCH_OMAP2)
288 if (mbsync_irq_save(mbx, &flags) < 0)
292 #ifdef MBX_USE_SEQ_BIT
293 /* add seq_snd to msg */
294 msg = (msg & 0x7fffffff) | mbx->seq_snd;
296 mbx->seq_snd ^= 1 << 31;
301 local_irq_restore(flags);
306 * register / unregister API
308 int register_mbx_receiver(struct mbx *mbx, unsigned char cmd,
311 if (cmd >= MBX_CMD_MAX) {
312 printk(KERN_ERR "register_mbx_receiver(): "
313 "bad cmd (0x%x)\n", cmd);
316 if (mbx->receiver_map[cmd] != NULL) {
317 printk(KERN_ERR "register_mbx_receiver(): cmd 0x%x is "
318 "already reserved.\n", cmd);
322 mbx->receiver_map[cmd] = rcv;
326 int unregister_mbx_receiver(struct mbx *mbx, unsigned char cmd,
329 if (cmd >= MBX_CMD_MAX) {
330 printk(KERN_ERR "unregister_mbx_receiver(): "
331 "bad cmd (0x%x)\n", cmd);
334 if (mbx->receiver_map[cmd] != rcv) {
335 printk(KERN_ERR "unregister_mbx_receiver(): cmd 0x%x and "
336 "receiver function mismatch!\n", cmd);
340 mbx->receiver_map[cmd] = NULL;
345 * IRQ disable / enable API
347 void disable_mbx_irq(struct mbx *mbx)
349 disable_irq(mbx->irq);
352 void enable_mbx_irq(struct mbx *mbx)
354 enable_irq(mbx->irq);
360 void mbx_init_seq(struct mbx *mbx)
362 #ifdef MBX_USE_SEQ_BIT
363 /* backward compatibility */
364 mbx->seq_snd = 0x80000000;
366 /* any value other than 0 and 1 << 31 */
367 mbx->seq_rcv = 0xffffffff;
368 #endif /* MBX_USE_SEQ_BIT */
374 static void do_mbx(void *p)
377 struct mbx *mbx = (struct mbx *)p;
378 struct mbq *mbq = &mbx->mbq;
379 mbx_receiver_t *receiver;
381 #ifdef MBX_USE_SEQ_BIT
385 disable_newmsg_irq(mbx);
386 if ((mbq->rp == mbq->wp) && !mbq->full)
388 enable_newmsg_irq(mbx);
391 msg = mbq->msg[mbq->rp];
392 #ifdef MBX_USE_SEQ_BIT
393 seq = msg & (1 << 31);
395 if (seq == mbx->seq_rcv) {
397 "mbx: illegal seq bit! ignoring this command. "
404 /* call receiver function */
405 if ((receiver = mbx->receiver_map[(msg >> 24) & 0x7f]) == NULL)
407 "mbx: unknown message (%08x) received from "
408 "%s.\n", msg, mbx->name);
412 #ifdef MBX_USE_SEQ_BIT
415 disable_newmsg_irq(mbx);
417 if (mbq->rp == mbq->wp)
419 /* if mbq has been full, now we have a room. */
422 enable_newmsg_irq(mbx);
424 enable_newmsg_irq(mbx);
431 static irqreturn_t mbx_int_newmsg(int irq, void *p, struct pt_regs *regs)
433 struct mbx *mbx = container_of(p, struct mbx, irq_devid_newmsg);
434 struct mbq *mbq = &mbx->mbq;
437 #ifdef CONFIG_ARCH_OMAP2
439 * mailbox IRQ can be muxed.
440 * if it is not a newmsg interrupt, do nothing.
442 if (!has_newmsg_irq(mbx))
447 #ifdef CONFIG_ARCH_OMAP2
448 if (mbx_nomsg(mbx)) {
449 /* no more messages in the fifo. clear IRQ source. */
450 clear_newmsg_irq(mbx);
455 msg = &mbq->msg[mbq->wp];
459 if (mbq->wp == mbq->rp) { /* mbq is full */
461 disable_newmsg_irq(mbx);
464 #if defined(CONFIG_ARCH_OMAP1)
465 } while (0); /* do it once */
466 #elif defined(CONFIG_ARCH_OMAP2)
470 schedule_work(&mbx->work);
474 #ifdef CONFIG_ARCH_OMAP2
475 static irqreturn_t mbx_int_notfull(int irq, void *p, struct pt_regs *regs)
477 struct mbx *mbx = container_of(p, struct mbx, irq_devid_notfull);
480 * mailbox IRQ can be muxed.
481 * if it is not a notfull interrupt, we do nothing.
484 if (!has_notfull_irq(mbx))
486 if (!(has_notfull_irq(mbx) && notfull_irq_enabled(mbx)))
490 disable_notfull_irq(mbx);
493 * note: this doesn't seeem to work as explained in the manual.
494 * IRQSTATUS:NOTFULL can't be cleared even we write 1 to that bit.
495 * It is always set when it's not full, regardless of IRQENABLE setting.
497 clear_notfull_irq(mbx);
500 wake_up_interruptible_all(&mbx->full_wait_q);
503 #endif /* CONFIG_ARCH_OMAP2 */
505 static int __init mbx_request_irq(struct mbx *mbx, const char *devname)
509 #ifdef CONFIG_ARCH_OMAP2
510 enable_newmsg_irq(mbx);
513 ret = request_irq(mbx->irq, mbx_int_newmsg, SA_INTERRUPT | SA_SHIRQ,
514 devname, &mbx->irq_devid_newmsg);
517 "failed to register DSP mailbox newmsg interrupt: "
522 #ifdef CONFIG_ARCH_OMAP2
523 ret = request_irq(mbx->irq, mbx_int_notfull, SA_INTERRUPT | SA_SHIRQ,
524 devname, &mbx->irq_devid_notfull);
527 "failed to register DSP mailbox notfull interrupt: "
536 static int __init omap_mailbox_init(void)
539 #ifdef CONFIG_ARCH_OMAP2
540 struct clk *mbx_ick_handle;
543 printk(KERN_INFO "Initializing OMAP Mailboxes\n");
544 #ifdef CONFIG_ARCH_OMAP2
546 * FIXME: mbx_ick will never unsed
548 mbx_ick_handle = clk_get(NULL, "mailboxes_ick");
549 if (IS_ERR(mbx_ick_handle)) {
550 printk("Could not get mailboxes_ick\n");
553 clk_enable(mbx_ick_handle);
556 if ((ret = mbx_request_irq(&mbx_dsp, "mbx_dsp")) != 0)
558 #ifdef CONFIG_ARCH_OMAP2
559 if ((ret = mbx_request_irq(&mbx_iva, "mbx_iva")) != 0)
566 arch_initcall(omap_mailbox_init);
568 EXPORT_SYMBOL(mbx_get);
569 EXPORT_SYMBOL(mbx_send);
570 EXPORT_SYMBOL(register_mbx_receiver);
571 EXPORT_SYMBOL(unregister_mbx_receiver);
572 EXPORT_SYMBOL(disable_mbx_irq);
573 EXPORT_SYMBOL(enable_mbx_irq);
574 EXPORT_SYMBOL(mbx_init_seq);