From: Hiroshi DOYU Date: Thu, 21 Sep 2006 14:41:43 +0000 (+0300) Subject: ARM: OMAP: mailbox restructure: omap2 specific parts X-Git-Tag: v2.6.18-omap1~47 X-Git-Url: http://www.pilppa.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=bd08e6b135ba5cf89c70dbe9d250d1a8487ab3af;p=linux-2.6-omap-h63xx.git ARM: OMAP: mailbox restructure: omap2 specific parts Signed-off-by: Hiroshi DOYU Signed-off-by: Juha Yrjola --- diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 266d88e77bd..a96b16e6ae1 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -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 - diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 6b2b3c3ddea..49d45ae0e4b 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -25,7 +25,7 @@ #include #include -#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 index 00000000000..d399c68d94e --- /dev/null +++ b/arch/arm/mach-omap2/mailbox.c @@ -0,0 +1,310 @@ +/* + * Mailbox reservation modules for OMAP2 + * + * Copyright (C) 2006 Nokia Corporation + * Written by: Hiroshi DOYU + * and Paul Mundt + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#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");