]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
ARM: OMAP: mailbox restructure: omap2 specific parts
authorHiroshi DOYU <Hiroshi.DOYU@nokia.com>
Thu, 21 Sep 2006 14:41:43 +0000 (17:41 +0300)
committerJuha Yrjola <juha.yrjola@solidboot.com>
Thu, 21 Sep 2006 15:45:55 +0000 (18:45 +0300)
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Signed-off-by: Juha Yrjola <juha.yrjola@solidboot.com>
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/devices.c
arch/arm/mach-omap2/mailbox.c [new file with mode: 0644]

index 266d88e77bdc7b29da1c2c7db6b6240dddd50c08..a96b16e6ae1bd68084a2814e90bbc7fcb11d16a9 100644 (file)
@@ -11,8 +11,10 @@ obj-$(CONFIG_OMAP_MPU_TIMER)         += timer-gp.o
 # Power Management
 obj-$(CONFIG_PM) += pm.o pm-domain.o sleep.o
 
+# DSP
+obj-$(CONFIG_OMAP_DSP) += mailbox.o
+
 # Specific board support
 obj-$(CONFIG_MACH_OMAP_GENERIC)                += board-generic.o
 obj-$(CONFIG_MACH_OMAP_H4)             += board-h4.o
 obj-$(CONFIG_MACH_OMAP_APOLLON)                += board-apollon.o
-
index 6b2b3c3ddea2533503c0ebaca4e464682712b4ba..49d45ae0e4bd87f8b8b9b6bfe8066a94babf57aa 100644 (file)
@@ -25,7 +25,7 @@
 #include <asm/arch/mux.h>
 #include <asm/arch/gpio.h>
 
-#if    defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
+#if    defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE)
 
 #define OMAP2_I2C_BASE2                0x48072000
 #define OMAP2_I2C_INT2         57
@@ -43,8 +43,8 @@ static struct resource i2c_resources2[] = {
 };
 
 static struct platform_device omap_i2c_device2 = {
-        .name           = "i2c_omap",
-        .id             = 2,
+       .name           = "i2c_omap",
+       .id             = 2,
        .num_resources  = ARRAY_SIZE(i2c_resources2),
        .resource       = i2c_resources2,
 };
@@ -67,6 +67,40 @@ static void omap_init_i2c(void) {}
 
 #endif
 
+#if defined(CONFIG_OMAP_DSP)
+#define OMAP2_MBOX_BASE                IO_ADDRESS(OMAP24XX_MAILBOX_BASE)
+
+static struct resource mbox_resources[] = {
+       {
+               .start          = OMAP2_MBOX_BASE,
+               .end            = OMAP2_MBOX_BASE + 0x11f,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = INT_24XX_MAIL_U0_MPU,
+               .flags          = IORESOURCE_IRQ,
+       },
+       {
+               .start          = INT_24XX_MAIL_U3_MPU,
+               .flags          = IORESOURCE_IRQ,
+       },
+};
+
+static struct platform_device mbox_device = {
+       .name           = "mailbox",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(mbox_resources),
+       .resource       = mbox_resources,
+};
+
+static inline void omap_init_mbox(void)
+{
+       platform_device_register(&mbox_device);
+}
+#else
+static inline void omap_init_mbox(void) { }
+#endif
+
 #if defined(CONFIG_OMAP_STI)
 
 #define OMAP2_STI_BASE         IO_ADDRESS(0x48068000)
@@ -174,10 +208,10 @@ static int __init omap2_init_devices(void)
         * in alphabetical order so they're easier to sort through.
         */
        omap_init_i2c();
+       omap_init_mbox();
        omap_init_mcspi();
        omap_init_sti();
 
        return 0;
 }
 arch_initcall(omap2_init_devices);
-
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
new file mode 100644 (file)
index 0000000..d399c68
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * Mailbox reservation modules for OMAP2
+ *
+ * Copyright (C) 2006 Nokia Corporation
+ * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+ *        and  Paul Mundt <paul.mundt@nokia.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <asm/arch/mailbox.h>
+#include <asm/arch/irqs.h>
+#include <asm/io.h>
+
+#define MAILBOX_REVISION               0x00
+#define MAILBOX_SYSCONFIG              0x10
+#define MAILBOX_SYSSTATUS              0x14
+#define MAILBOX_MESSAGE_0              0x40
+#define MAILBOX_MESSAGE_1              0x44
+#define MAILBOX_MESSAGE_2              0x48
+#define MAILBOX_MESSAGE_3              0x4c
+#define MAILBOX_MESSAGE_4              0x50
+#define MAILBOX_MESSAGE_5              0x54
+#define MAILBOX_FIFOSTATUS_0           0x80
+#define MAILBOX_FIFOSTATUS_1           0x84
+#define MAILBOX_FIFOSTATUS_2           0x88
+#define MAILBOX_FIFOSTATUS_3           0x8c
+#define MAILBOX_FIFOSTATUS_4           0x90
+#define MAILBOX_FIFOSTATUS_5           0x94
+#define MAILBOX_MSGSTATUS_0            0xc0
+#define MAILBOX_MSGSTATUS_1            0xc4
+#define MAILBOX_MSGSTATUS_2            0xc8
+#define MAILBOX_MSGSTATUS_3            0xcc
+#define MAILBOX_MSGSTATUS_4            0xd0
+#define MAILBOX_MSGSTATUS_5            0xd4
+#define MAILBOX_IRQSTATUS_0            0x100
+#define MAILBOX_IRQENABLE_0            0x104
+#define MAILBOX_IRQSTATUS_1            0x108
+#define MAILBOX_IRQENABLE_1            0x10c
+#define MAILBOX_IRQSTATUS_2            0x110
+#define MAILBOX_IRQENABLE_2            0x114
+#define MAILBOX_IRQSTATUS_3            0x118
+#define MAILBOX_IRQENABLE_3            0x11c
+
+unsigned long mbox_base;
+
+#define MAILBOX_IRQ_NOTFULL(n)         (1 << (2 * (n) + 1))
+#define MAILBOX_IRQ_NEWMSG(n)          (1 << (2 * (n)))
+
+struct omap_mbox2_fifo {
+       unsigned long msg;
+       unsigned long fifo_stat;
+       unsigned long msg_stat;
+};
+
+struct omap_mbox2_priv {
+       struct omap_mbox2_fifo tx_fifo;
+       struct omap_mbox2_fifo rx_fifo;
+       unsigned long irqenable;
+       unsigned long irqstatus;
+       u32 newmsg_bit;
+       u32 notfull_bit;
+};
+
+struct clk *mbox_ick_handle;
+
+static inline unsigned int mbox_read_reg(unsigned int reg)
+{
+       return __raw_readl(mbox_base + reg);
+}
+
+static inline void mbox_write_reg(unsigned int val, unsigned int reg)
+{
+       __raw_writel(val, mbox_base + reg);
+}
+
+/* Mailbox H/W preparations */
+static inline int omap2_mbox_startup(struct omap_mbox *mbox)
+{
+       unsigned int l;
+
+       mbox_ick_handle = clk_get(NULL, "mailboxes_ick");
+       if (IS_ERR(mbox_ick_handle)) {
+               printk("Could not get mailboxes_ick\n");
+               return -ENODEV;
+       }
+       clk_enable(mbox_ick_handle);
+
+       /* set smart-idle & autoidle */
+       l = mbox_read_reg(MAILBOX_SYSCONFIG);
+       l |= 0x00000011;
+       mbox_write_reg(l, MAILBOX_SYSCONFIG);
+
+       return 0;
+}
+
+static inline void omap2_mbox_shutdown(struct omap_mbox *mbox)
+{
+       clk_disable(mbox_ick_handle);
+       clk_put(mbox_ick_handle);
+}
+
+/* Mailbox FIFO handle functions */
+static inline mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox)
+{
+       struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
+       return (mbox_msg_t) mbox_read_reg(fifo->msg);
+}
+
+static inline void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg)
+{
+       struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
+       mbox_write_reg(msg, fifo->msg);
+}
+
+static inline int omap2_mbox_fifo_empty(struct omap_mbox *mbox)
+{
+       struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo;
+       return (mbox_read_reg(fifo->msg_stat) == 0);
+}
+
+static inline int omap2_mbox_fifo_full(struct omap_mbox *mbox)
+{
+       struct omap_mbox2_fifo *fifo = &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo;
+       return (mbox_read_reg(fifo->fifo_stat));
+}
+
+/* Mailbox IRQ handle functions */
+static inline void omap2_mbox_enable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+       struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+       u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+       l = mbox_read_reg(p->irqenable);
+       l |= bit;
+       mbox_write_reg(l, p->irqenable);
+}
+
+static inline void omap2_mbox_disable_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+       struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+       u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+       l = mbox_read_reg(p->irqenable);
+       l &= ~bit;
+       mbox_write_reg(l, p->irqenable);
+}
+
+static inline void omap2_mbox_ack_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+       struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+       u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+
+       mbox_write_reg(bit, p->irqstatus);
+}
+
+static inline int omap2_mbox_is_irq(struct omap_mbox *mbox, omap_mbox_type_t irq)
+{
+       struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv;
+       u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
+       u32 enable = mbox_read_reg(p->irqenable);
+       u32 status = mbox_read_reg(p->irqstatus);
+
+       return (enable & status & bit);
+}
+
+struct omap_mbox_ops omap2_mbox_ops = {
+       .type = OMAP_MBOX_TYPE2,
+       .startup = omap2_mbox_startup,
+       .shutdown = omap2_mbox_shutdown,
+       .fifo_read = omap2_mbox_fifo_read,
+       .fifo_write = omap2_mbox_fifo_write,
+       .fifo_empty = omap2_mbox_fifo_empty,
+       .fifo_full = omap2_mbox_fifo_full,
+       .enable_irq = omap2_mbox_enable_irq,
+       .disable_irq = omap2_mbox_disable_irq,
+       .ack_irq = omap2_mbox_ack_irq,
+       .is_irq = omap2_mbox_is_irq,
+};
+
+/*
+ * MAILBOX 0: ARM -> DSP,
+ * MAILBOX 1: ARM <- DSP.
+ * MAILBOX 2: ARM -> IVA,
+ * MAILBOX 3: ARM <- IVA.
+ */
+
+/* FIXME: the following structs should be filled automatically by the user id */
+
+/* DSP */
+static struct omap_mbox2_priv omap2_mbox_dsp_priv = {
+       .tx_fifo = {
+               .msg = MAILBOX_MESSAGE_0,
+               .fifo_stat = MAILBOX_FIFOSTATUS_0,
+       },
+       .rx_fifo = {
+               .msg = MAILBOX_MESSAGE_1,
+               .msg_stat = MAILBOX_MSGSTATUS_1,
+       },
+       .irqenable = MAILBOX_IRQENABLE_0,
+       .irqstatus = MAILBOX_IRQSTATUS_0,
+       .notfull_bit = MAILBOX_IRQ_NOTFULL(0),
+       .newmsg_bit = MAILBOX_IRQ_NEWMSG(1),
+};
+
+static struct omap_mbox mbox_dsp_info = {
+       .name = "dsp",
+       .ops = &omap2_mbox_ops,
+       .priv = &omap2_mbox_dsp_priv,
+};
+
+/* IVA */
+static struct omap_mbox2_priv omap2_mbox_iva_priv = {
+       .tx_fifo = {
+               .msg = MAILBOX_MESSAGE_2,
+               .fifo_stat = MAILBOX_FIFOSTATUS_2,
+       },
+       .rx_fifo = {
+               .msg = MAILBOX_MESSAGE_3,
+               .msg_stat = MAILBOX_MSGSTATUS_3,
+       },
+       .irqenable = MAILBOX_IRQENABLE_3,
+       .irqstatus = MAILBOX_IRQSTATUS_3,
+       .notfull_bit = MAILBOX_IRQ_NOTFULL(2),
+       .newmsg_bit = MAILBOX_IRQ_NEWMSG(3),
+};
+
+static struct omap_mbox mbox_iva_info = {
+       .name = "iva",
+       .ops = &omap2_mbox_ops,
+       .priv = &omap2_mbox_iva_priv,
+};
+
+static int __init omap2_mbox_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int ret = 0;
+
+       if (pdev->num_resources != 3) {
+               dev_err(&pdev->dev, "invalid number of resources: %d\n",
+                       pdev->num_resources);
+               return -ENODEV;
+       }
+
+       /* MBOX base */
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (unlikely(!res)) {
+               dev_err(&pdev->dev, "invalid mem resource\n");
+               return -ENODEV;
+       }
+       mbox_base = res->start;
+
+       /* DSP IRQ */
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+       if (unlikely(!res)) {
+               dev_err(&pdev->dev, "invalid irq resource\n");
+               return -ENODEV;
+       }
+       mbox_dsp_info.irq = res->start;
+
+       ret = omap_mbox_register(&mbox_dsp_info);
+
+       /* IVA IRQ */
+       res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+       if (unlikely(!res)) {
+               dev_err(&pdev->dev, "invalid irq resource\n");
+               return -ENODEV;
+       }
+       mbox_iva_info.irq = res->start;
+
+       ret = omap_mbox_register(&mbox_iva_info);
+
+       return ret;
+}
+
+static int omap2_mbox_remove(struct platform_device *pdev)
+{
+       omap_mbox_unregister(&mbox_dsp_info);
+       return 0;
+}
+
+static struct platform_driver omap2_mbox_driver = {
+       .probe = omap2_mbox_probe,
+       .remove = omap2_mbox_remove,
+       .driver = {
+               .name = "mailbox",
+       },
+};
+
+int __init omap2_mbox_init(void)
+{
+       return platform_driver_register(&omap2_mbox_driver);
+}
+
+static void __exit omap2_mbox_exit(void)
+{
+       platform_driver_unregister(&omap2_mbox_driver);
+}
+
+module_init(omap2_mbox_init);
+module_exit(omap2_mbox_exit);
+
+MODULE_LICENSE("GPL");