diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 16:05:57 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-09 16:05:57 -0400 |
commit | 932c37c375cca25175f9b6acee4c75d7a96d985f (patch) | |
tree | d7ba3620cd9a7a21c2de1bdfc7badd7637ed635e /arch/arm/mach-omap2 | |
parent | c855ff3718e5f667b463b20b9de516b4cd7625ad (diff) | |
parent | 805f53f085346b6765eda02820721a14ce0d644f (diff) |
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
* 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm: (28 commits)
ARM: OMAP: Fix GCC-reported compile time bug
ARM: OMAP: restore CONFIG_GENERIC_TIME
ARM: OMAP: partial LED fixes
ARM: OMAP: add SoSSI clock (call propagate_rate for childrens)
ARM: OMAP: FB sync with N800 tree (support for dynamic SRAM allocations)
ARM: OMAP: Sync framebuffer headers with N800 tree
ARM: OMAP: Mostly cosmetic to sync up with linux-omap tree
ARM: OMAP: Fix gpmc header
ARM: OMAP: Add mailbox support for IVA
[ARM] armv7: add Makefile and Kconfig entries
[ARM] armv7: add support for asid-tagged VIVT I-cache
[ARM] armv7: add dedicated ARMv7 barrier instructions
[ARM] armv7: Add ARMv7 cacheid macros
[ARM] armv7: add support for ARMv7 cores.
[ARM] Fix ARM branch relocation range
[ARM] 4363/1: AT91: Remove legacy PIO definitions
[ARM] 4361/1: AT91: Build error
ARM: OMAP: Sync core code with linux-omap
ARM: OMAP: Sync headers with linux-omap
ARM: OMAP: h4 must have blinky leds!!
...
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-omap2/board-h4.c | 14 | ||||
-rw-r--r-- | arch/arm/mach-omap2/devices.c | 66 | ||||
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 12 | ||||
-rw-r--r-- | arch/arm/mach-omap2/io.c | 21 | ||||
-rw-r--r-- | arch/arm/mach-omap2/mailbox.c | 318 |
6 files changed, 419 insertions, 14 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index aab97ccf1e63..7393109f5c30 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -9,6 +9,7 @@ config ARCH_OMAP2420 | |||
9 | bool "OMAP2420 support" | 9 | bool "OMAP2420 support" |
10 | depends on ARCH_OMAP24XX | 10 | depends on ARCH_OMAP24XX |
11 | select OMAP_DM_TIMER | 11 | select OMAP_DM_TIMER |
12 | select ARCH_OMAP_OTG | ||
12 | 13 | ||
13 | comment "OMAP Board Type" | 14 | comment "OMAP Board Type" |
14 | depends on ARCH_OMAP2 | 15 | depends on ARCH_OMAP2 |
@@ -20,6 +21,7 @@ config MACH_OMAP_GENERIC | |||
20 | config MACH_OMAP_H4 | 21 | config MACH_OMAP_H4 |
21 | bool "OMAP 2420 H4 board" | 22 | bool "OMAP 2420 H4 board" |
22 | depends on ARCH_OMAP2 && ARCH_OMAP24XX | 23 | depends on ARCH_OMAP2 && ARCH_OMAP24XX |
24 | select OMAP_DEBUG_LEDS if LEDS || LEDS_OMAP_DEBUG | ||
23 | 25 | ||
24 | config MACH_OMAP_APOLLON | 26 | config MACH_OMAP_APOLLON |
25 | bool "OMAP 2420 Apollon board" | 27 | bool "OMAP 2420 Apollon board" |
diff --git a/arch/arm/mach-omap2/board-h4.c b/arch/arm/mach-omap2/board-h4.c index 1e7ed6d22ca9..452193f01531 100644 --- a/arch/arm/mach-omap2/board-h4.c +++ b/arch/arm/mach-omap2/board-h4.c | |||
@@ -266,12 +266,26 @@ static struct platform_device h4_lcd_device = { | |||
266 | .id = -1, | 266 | .id = -1, |
267 | }; | 267 | }; |
268 | 268 | ||
269 | static struct resource h4_led_resources[] = { | ||
270 | [0] = { | ||
271 | .flags = IORESOURCE_MEM, | ||
272 | }, | ||
273 | }; | ||
274 | |||
275 | static struct platform_device h4_led_device = { | ||
276 | .name = "omap_dbg_led", | ||
277 | .id = -1, | ||
278 | .num_resources = ARRAY_SIZE(h4_led_resources), | ||
279 | .resource = h4_led_resources, | ||
280 | }; | ||
281 | |||
269 | static struct platform_device *h4_devices[] __initdata = { | 282 | static struct platform_device *h4_devices[] __initdata = { |
270 | &h4_smc91x_device, | 283 | &h4_smc91x_device, |
271 | &h4_flash_device, | 284 | &h4_flash_device, |
272 | &h4_irda_device, | 285 | &h4_irda_device, |
273 | &h4_kp_device, | 286 | &h4_kp_device, |
274 | &h4_lcd_device, | 287 | &h4_lcd_device, |
288 | &h4_led_device, | ||
275 | }; | 289 | }; |
276 | 290 | ||
277 | static inline void __init h4_init_smc91x(void) | 291 | static inline void __init h4_init_smc91x(void) |
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index aa4322451e8b..52ec2f2d6360 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <asm/arch/mux.h> | 24 | #include <asm/arch/mux.h> |
25 | #include <asm/arch/gpio.h> | 25 | #include <asm/arch/gpio.h> |
26 | 26 | ||
27 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) | 27 | #if defined(CONFIG_I2C_OMAP) || defined(CONFIG_I2C_OMAP_MODULE) |
28 | 28 | ||
29 | #define OMAP2_I2C_BASE2 0x48072000 | 29 | #define OMAP2_I2C_BASE2 0x48072000 |
30 | #define OMAP2_I2C_INT2 57 | 30 | #define OMAP2_I2C_INT2 57 |
@@ -42,8 +42,8 @@ static struct resource i2c_resources2[] = { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | static struct platform_device omap_i2c_device2 = { | 44 | static struct platform_device omap_i2c_device2 = { |
45 | .name = "i2c_omap", | 45 | .name = "i2c_omap", |
46 | .id = 2, | 46 | .id = 2, |
47 | .num_resources = ARRAY_SIZE(i2c_resources2), | 47 | .num_resources = ARRAY_SIZE(i2c_resources2), |
48 | .resource = i2c_resources2, | 48 | .resource = i2c_resources2, |
49 | }; | 49 | }; |
@@ -66,6 +66,40 @@ static void omap_init_i2c(void) {} | |||
66 | 66 | ||
67 | #endif | 67 | #endif |
68 | 68 | ||
69 | #if defined(CONFIG_OMAP_DSP) || defined(CONFIG_OMAP_DSP_MODULE) | ||
70 | #define OMAP2_MBOX_BASE IO_ADDRESS(OMAP24XX_MAILBOX_BASE) | ||
71 | |||
72 | static struct resource mbox_resources[] = { | ||
73 | { | ||
74 | .start = OMAP2_MBOX_BASE, | ||
75 | .end = OMAP2_MBOX_BASE + 0x11f, | ||
76 | .flags = IORESOURCE_MEM, | ||
77 | }, | ||
78 | { | ||
79 | .start = INT_24XX_MAIL_U0_MPU, | ||
80 | .flags = IORESOURCE_IRQ, | ||
81 | }, | ||
82 | { | ||
83 | .start = INT_24XX_MAIL_U3_MPU, | ||
84 | .flags = IORESOURCE_IRQ, | ||
85 | }, | ||
86 | }; | ||
87 | |||
88 | static struct platform_device mbox_device = { | ||
89 | .name = "mailbox", | ||
90 | .id = -1, | ||
91 | .num_resources = ARRAY_SIZE(mbox_resources), | ||
92 | .resource = mbox_resources, | ||
93 | }; | ||
94 | |||
95 | static inline void omap_init_mbox(void) | ||
96 | { | ||
97 | platform_device_register(&mbox_device); | ||
98 | } | ||
99 | #else | ||
100 | static inline void omap_init_mbox(void) { } | ||
101 | #endif | ||
102 | |||
69 | #if defined(CONFIG_OMAP_STI) | 103 | #if defined(CONFIG_OMAP_STI) |
70 | 104 | ||
71 | #define OMAP2_STI_BASE IO_ADDRESS(0x48068000) | 105 | #define OMAP2_STI_BASE IO_ADDRESS(0x48068000) |
@@ -111,29 +145,45 @@ static inline void omap_init_sti(void) {} | |||
111 | #define OMAP2_MCSPI1_BASE 0x48098000 | 145 | #define OMAP2_MCSPI1_BASE 0x48098000 |
112 | #define OMAP2_MCSPI2_BASE 0x4809a000 | 146 | #define OMAP2_MCSPI2_BASE 0x4809a000 |
113 | 147 | ||
114 | /* FIXME: use resources instead */ | ||
115 | |||
116 | static struct omap2_mcspi_platform_config omap2_mcspi1_config = { | 148 | static struct omap2_mcspi_platform_config omap2_mcspi1_config = { |
117 | .base = io_p2v(OMAP2_MCSPI1_BASE), | ||
118 | .num_cs = 4, | 149 | .num_cs = 4, |
119 | }; | 150 | }; |
120 | 151 | ||
152 | static struct resource omap2_mcspi1_resources[] = { | ||
153 | { | ||
154 | .start = OMAP2_MCSPI1_BASE, | ||
155 | .end = OMAP2_MCSPI1_BASE + 0xff, | ||
156 | .flags = IORESOURCE_MEM, | ||
157 | }, | ||
158 | }; | ||
159 | |||
121 | struct platform_device omap2_mcspi1 = { | 160 | struct platform_device omap2_mcspi1 = { |
122 | .name = "omap2_mcspi", | 161 | .name = "omap2_mcspi", |
123 | .id = 1, | 162 | .id = 1, |
163 | .num_resources = ARRAY_SIZE(omap2_mcspi1_resources), | ||
164 | .resource = omap2_mcspi1_resources, | ||
124 | .dev = { | 165 | .dev = { |
125 | .platform_data = &omap2_mcspi1_config, | 166 | .platform_data = &omap2_mcspi1_config, |
126 | }, | 167 | }, |
127 | }; | 168 | }; |
128 | 169 | ||
129 | static struct omap2_mcspi_platform_config omap2_mcspi2_config = { | 170 | static struct omap2_mcspi_platform_config omap2_mcspi2_config = { |
130 | .base = io_p2v(OMAP2_MCSPI2_BASE), | ||
131 | .num_cs = 2, | 171 | .num_cs = 2, |
132 | }; | 172 | }; |
133 | 173 | ||
174 | static struct resource omap2_mcspi2_resources[] = { | ||
175 | { | ||
176 | .start = OMAP2_MCSPI2_BASE, | ||
177 | .end = OMAP2_MCSPI2_BASE + 0xff, | ||
178 | .flags = IORESOURCE_MEM, | ||
179 | }, | ||
180 | }; | ||
181 | |||
134 | struct platform_device omap2_mcspi2 = { | 182 | struct platform_device omap2_mcspi2 = { |
135 | .name = "omap2_mcspi", | 183 | .name = "omap2_mcspi", |
136 | .id = 2, | 184 | .id = 2, |
185 | .num_resources = ARRAY_SIZE(omap2_mcspi2_resources), | ||
186 | .resource = omap2_mcspi2_resources, | ||
137 | .dev = { | 187 | .dev = { |
138 | .platform_data = &omap2_mcspi2_config, | 188 | .platform_data = &omap2_mcspi2_config, |
139 | }, | 189 | }, |
@@ -157,10 +207,10 @@ static int __init omap2_init_devices(void) | |||
157 | * in alphabetical order so they're easier to sort through. | 207 | * in alphabetical order so they're easier to sort through. |
158 | */ | 208 | */ |
159 | omap_init_i2c(); | 209 | omap_init_i2c(); |
210 | omap_init_mbox(); | ||
160 | omap_init_mcspi(); | 211 | omap_init_mcspi(); |
161 | omap_init_sti(); | 212 | omap_init_sti(); |
162 | 213 | ||
163 | return 0; | 214 | return 0; |
164 | } | 215 | } |
165 | arch_initcall(omap2_init_devices); | 216 | arch_initcall(omap2_init_devices); |
166 | |||
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index d8f57824423f..54c836a98456 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -246,14 +246,22 @@ static int gpmc_cs_mem_enabled(int cs) | |||
246 | return l & (1 << 6); | 246 | return l & (1 << 6); |
247 | } | 247 | } |
248 | 248 | ||
249 | static void gpmc_cs_set_reserved(int cs, int reserved) | 249 | int gpmc_cs_set_reserved(int cs, int reserved) |
250 | { | 250 | { |
251 | if (cs > GPMC_CS_NUM) | ||
252 | return -ENODEV; | ||
253 | |||
251 | gpmc_cs_map &= ~(1 << cs); | 254 | gpmc_cs_map &= ~(1 << cs); |
252 | gpmc_cs_map |= (reserved ? 1 : 0) << cs; | 255 | gpmc_cs_map |= (reserved ? 1 : 0) << cs; |
256 | |||
257 | return 0; | ||
253 | } | 258 | } |
254 | 259 | ||
255 | static int gpmc_cs_reserved(int cs) | 260 | int gpmc_cs_reserved(int cs) |
256 | { | 261 | { |
262 | if (cs > GPMC_CS_NUM) | ||
263 | return -ENODEV; | ||
264 | |||
257 | return gpmc_cs_map & (1 << cs); | 265 | return gpmc_cs_map & (1 << cs); |
258 | } | 266 | } |
259 | 267 | ||
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index a0728c33e5d9..82dc70f6b779 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -27,6 +27,7 @@ extern void omap_sram_init(void); | |||
27 | extern int omap2_clk_init(void); | 27 | extern int omap2_clk_init(void); |
28 | extern void omap2_check_revision(void); | 28 | extern void omap2_check_revision(void); |
29 | extern void gpmc_init(void); | 29 | extern void gpmc_init(void); |
30 | extern void omapfb_reserve_sdram(void); | ||
30 | 31 | ||
31 | /* | 32 | /* |
32 | * The machine specific code may provide the extra mapping besides the | 33 | * The machine specific code may provide the extra mapping besides the |
@@ -40,9 +41,21 @@ static struct map_desc omap2_io_desc[] __initdata = { | |||
40 | .type = MT_DEVICE | 41 | .type = MT_DEVICE |
41 | }, | 42 | }, |
42 | { | 43 | { |
43 | .virtual = L4_24XX_VIRT, | 44 | .virtual = DSP_MEM_24XX_VIRT, |
44 | .pfn = __phys_to_pfn(L4_24XX_PHYS), | 45 | .pfn = __phys_to_pfn(DSP_MEM_24XX_PHYS), |
45 | .length = L4_24XX_SIZE, | 46 | .length = DSP_MEM_24XX_SIZE, |
47 | .type = MT_DEVICE | ||
48 | }, | ||
49 | { | ||
50 | .virtual = DSP_IPI_24XX_VIRT, | ||
51 | .pfn = __phys_to_pfn(DSP_IPI_24XX_PHYS), | ||
52 | .length = DSP_IPI_24XX_SIZE, | ||
53 | .type = MT_DEVICE | ||
54 | }, | ||
55 | { | ||
56 | .virtual = DSP_MMU_24XX_VIRT, | ||
57 | .pfn = __phys_to_pfn(DSP_MMU_24XX_PHYS), | ||
58 | .length = DSP_MMU_24XX_SIZE, | ||
46 | .type = MT_DEVICE | 59 | .type = MT_DEVICE |
47 | } | 60 | } |
48 | }; | 61 | }; |
@@ -60,7 +73,7 @@ void __init omap2_map_common_io(void) | |||
60 | 73 | ||
61 | omap2_check_revision(); | 74 | omap2_check_revision(); |
62 | omap_sram_init(); | 75 | omap_sram_init(); |
63 | omapfb_reserve_mem(); | 76 | omapfb_reserve_sdram(); |
64 | } | 77 | } |
65 | 78 | ||
66 | void __init omap2_init_common_hw(void) | 79 | void __init omap2_init_common_hw(void) |
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c new file mode 100644 index 000000000000..b03cd06e055b --- /dev/null +++ b/arch/arm/mach-omap2/mailbox.c | |||
@@ -0,0 +1,318 @@ | |||
1 | /* | ||
2 | * Mailbox reservation modules for OMAP2 | ||
3 | * | ||
4 | * Copyright (C) 2006 Nokia Corporation | ||
5 | * Written by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com> | ||
6 | * and Paul Mundt <paul.mundt@nokia.com> | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <asm/arch/mailbox.h> | ||
18 | #include <asm/arch/irqs.h> | ||
19 | #include <asm/io.h> | ||
20 | |||
21 | #define MAILBOX_REVISION 0x00 | ||
22 | #define MAILBOX_SYSCONFIG 0x10 | ||
23 | #define MAILBOX_SYSSTATUS 0x14 | ||
24 | #define MAILBOX_MESSAGE_0 0x40 | ||
25 | #define MAILBOX_MESSAGE_1 0x44 | ||
26 | #define MAILBOX_MESSAGE_2 0x48 | ||
27 | #define MAILBOX_MESSAGE_3 0x4c | ||
28 | #define MAILBOX_MESSAGE_4 0x50 | ||
29 | #define MAILBOX_MESSAGE_5 0x54 | ||
30 | #define MAILBOX_FIFOSTATUS_0 0x80 | ||
31 | #define MAILBOX_FIFOSTATUS_1 0x84 | ||
32 | #define MAILBOX_FIFOSTATUS_2 0x88 | ||
33 | #define MAILBOX_FIFOSTATUS_3 0x8c | ||
34 | #define MAILBOX_FIFOSTATUS_4 0x90 | ||
35 | #define MAILBOX_FIFOSTATUS_5 0x94 | ||
36 | #define MAILBOX_MSGSTATUS_0 0xc0 | ||
37 | #define MAILBOX_MSGSTATUS_1 0xc4 | ||
38 | #define MAILBOX_MSGSTATUS_2 0xc8 | ||
39 | #define MAILBOX_MSGSTATUS_3 0xcc | ||
40 | #define MAILBOX_MSGSTATUS_4 0xd0 | ||
41 | #define MAILBOX_MSGSTATUS_5 0xd4 | ||
42 | #define MAILBOX_IRQSTATUS_0 0x100 | ||
43 | #define MAILBOX_IRQENABLE_0 0x104 | ||
44 | #define MAILBOX_IRQSTATUS_1 0x108 | ||
45 | #define MAILBOX_IRQENABLE_1 0x10c | ||
46 | #define MAILBOX_IRQSTATUS_2 0x110 | ||
47 | #define MAILBOX_IRQENABLE_2 0x114 | ||
48 | #define MAILBOX_IRQSTATUS_3 0x118 | ||
49 | #define MAILBOX_IRQENABLE_3 0x11c | ||
50 | |||
51 | static unsigned long mbox_base; | ||
52 | |||
53 | #define MAILBOX_IRQ_NOTFULL(n) (1 << (2 * (n) + 1)) | ||
54 | #define MAILBOX_IRQ_NEWMSG(n) (1 << (2 * (n))) | ||
55 | |||
56 | struct omap_mbox2_fifo { | ||
57 | unsigned long msg; | ||
58 | unsigned long fifo_stat; | ||
59 | unsigned long msg_stat; | ||
60 | }; | ||
61 | |||
62 | struct omap_mbox2_priv { | ||
63 | struct omap_mbox2_fifo tx_fifo; | ||
64 | struct omap_mbox2_fifo rx_fifo; | ||
65 | unsigned long irqenable; | ||
66 | unsigned long irqstatus; | ||
67 | u32 newmsg_bit; | ||
68 | u32 notfull_bit; | ||
69 | }; | ||
70 | |||
71 | static struct clk *mbox_ick_handle; | ||
72 | |||
73 | static inline unsigned int mbox_read_reg(unsigned int reg) | ||
74 | { | ||
75 | return __raw_readl(mbox_base + reg); | ||
76 | } | ||
77 | |||
78 | static inline void mbox_write_reg(unsigned int val, unsigned int reg) | ||
79 | { | ||
80 | __raw_writel(val, mbox_base + reg); | ||
81 | } | ||
82 | |||
83 | /* Mailbox H/W preparations */ | ||
84 | static inline int omap2_mbox_startup(struct omap_mbox *mbox) | ||
85 | { | ||
86 | unsigned int l; | ||
87 | |||
88 | mbox_ick_handle = clk_get(NULL, "mailboxes_ick"); | ||
89 | if (IS_ERR(mbox_ick_handle)) { | ||
90 | printk("Could not get mailboxes_ick\n"); | ||
91 | return -ENODEV; | ||
92 | } | ||
93 | clk_enable(mbox_ick_handle); | ||
94 | |||
95 | /* set smart-idle & autoidle */ | ||
96 | l = mbox_read_reg(MAILBOX_SYSCONFIG); | ||
97 | l |= 0x00000011; | ||
98 | mbox_write_reg(l, MAILBOX_SYSCONFIG); | ||
99 | |||
100 | return 0; | ||
101 | } | ||
102 | |||
103 | static inline void omap2_mbox_shutdown(struct omap_mbox *mbox) | ||
104 | { | ||
105 | clk_disable(mbox_ick_handle); | ||
106 | clk_put(mbox_ick_handle); | ||
107 | } | ||
108 | |||
109 | /* Mailbox FIFO handle functions */ | ||
110 | static inline mbox_msg_t omap2_mbox_fifo_read(struct omap_mbox *mbox) | ||
111 | { | ||
112 | struct omap_mbox2_fifo *fifo = | ||
113 | &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; | ||
114 | return (mbox_msg_t) mbox_read_reg(fifo->msg); | ||
115 | } | ||
116 | |||
117 | static inline void omap2_mbox_fifo_write(struct omap_mbox *mbox, mbox_msg_t msg) | ||
118 | { | ||
119 | struct omap_mbox2_fifo *fifo = | ||
120 | &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; | ||
121 | mbox_write_reg(msg, fifo->msg); | ||
122 | } | ||
123 | |||
124 | static inline int omap2_mbox_fifo_empty(struct omap_mbox *mbox) | ||
125 | { | ||
126 | struct omap_mbox2_fifo *fifo = | ||
127 | &((struct omap_mbox2_priv *)mbox->priv)->rx_fifo; | ||
128 | return (mbox_read_reg(fifo->msg_stat) == 0); | ||
129 | } | ||
130 | |||
131 | static inline int omap2_mbox_fifo_full(struct omap_mbox *mbox) | ||
132 | { | ||
133 | struct omap_mbox2_fifo *fifo = | ||
134 | &((struct omap_mbox2_priv *)mbox->priv)->tx_fifo; | ||
135 | return (mbox_read_reg(fifo->fifo_stat)); | ||
136 | } | ||
137 | |||
138 | /* Mailbox IRQ handle functions */ | ||
139 | static inline void omap2_mbox_enable_irq(struct omap_mbox *mbox, | ||
140 | omap_mbox_type_t irq) | ||
141 | { | ||
142 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | ||
143 | u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | ||
144 | |||
145 | l = mbox_read_reg(p->irqenable); | ||
146 | l |= bit; | ||
147 | mbox_write_reg(l, p->irqenable); | ||
148 | } | ||
149 | |||
150 | static inline void omap2_mbox_disable_irq(struct omap_mbox *mbox, | ||
151 | omap_mbox_type_t irq) | ||
152 | { | ||
153 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | ||
154 | u32 l, bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | ||
155 | |||
156 | l = mbox_read_reg(p->irqenable); | ||
157 | l &= ~bit; | ||
158 | mbox_write_reg(l, p->irqenable); | ||
159 | } | ||
160 | |||
161 | static inline void omap2_mbox_ack_irq(struct omap_mbox *mbox, | ||
162 | omap_mbox_type_t irq) | ||
163 | { | ||
164 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | ||
165 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | ||
166 | |||
167 | mbox_write_reg(bit, p->irqstatus); | ||
168 | } | ||
169 | |||
170 | static inline int omap2_mbox_is_irq(struct omap_mbox *mbox, | ||
171 | omap_mbox_type_t irq) | ||
172 | { | ||
173 | struct omap_mbox2_priv *p = (struct omap_mbox2_priv *)mbox->priv; | ||
174 | u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit; | ||
175 | u32 enable = mbox_read_reg(p->irqenable); | ||
176 | u32 status = mbox_read_reg(p->irqstatus); | ||
177 | |||
178 | return (enable & status & bit); | ||
179 | } | ||
180 | |||
181 | static struct omap_mbox_ops omap2_mbox_ops = { | ||
182 | .type = OMAP_MBOX_TYPE2, | ||
183 | .startup = omap2_mbox_startup, | ||
184 | .shutdown = omap2_mbox_shutdown, | ||
185 | .fifo_read = omap2_mbox_fifo_read, | ||
186 | .fifo_write = omap2_mbox_fifo_write, | ||
187 | .fifo_empty = omap2_mbox_fifo_empty, | ||
188 | .fifo_full = omap2_mbox_fifo_full, | ||
189 | .enable_irq = omap2_mbox_enable_irq, | ||
190 | .disable_irq = omap2_mbox_disable_irq, | ||
191 | .ack_irq = omap2_mbox_ack_irq, | ||
192 | .is_irq = omap2_mbox_is_irq, | ||
193 | }; | ||
194 | |||
195 | /* | ||
196 | * MAILBOX 0: ARM -> DSP, | ||
197 | * MAILBOX 1: ARM <- DSP. | ||
198 | * MAILBOX 2: ARM -> IVA, | ||
199 | * MAILBOX 3: ARM <- IVA. | ||
200 | */ | ||
201 | |||
202 | /* FIXME: the following structs should be filled automatically by the user id */ | ||
203 | |||
204 | /* DSP */ | ||
205 | static struct omap_mbox2_priv omap2_mbox_dsp_priv = { | ||
206 | .tx_fifo = { | ||
207 | .msg = MAILBOX_MESSAGE_0, | ||
208 | .fifo_stat = MAILBOX_FIFOSTATUS_0, | ||
209 | }, | ||
210 | .rx_fifo = { | ||
211 | .msg = MAILBOX_MESSAGE_1, | ||
212 | .msg_stat = MAILBOX_MSGSTATUS_1, | ||
213 | }, | ||
214 | .irqenable = MAILBOX_IRQENABLE_0, | ||
215 | .irqstatus = MAILBOX_IRQSTATUS_0, | ||
216 | .notfull_bit = MAILBOX_IRQ_NOTFULL(0), | ||
217 | .newmsg_bit = MAILBOX_IRQ_NEWMSG(1), | ||
218 | }; | ||
219 | |||
220 | struct omap_mbox mbox_dsp_info = { | ||
221 | .name = "dsp", | ||
222 | .ops = &omap2_mbox_ops, | ||
223 | .priv = &omap2_mbox_dsp_priv, | ||
224 | }; | ||
225 | EXPORT_SYMBOL(mbox_dsp_info); | ||
226 | |||
227 | /* IVA */ | ||
228 | static struct omap_mbox2_priv omap2_mbox_iva_priv = { | ||
229 | .tx_fifo = { | ||
230 | .msg = MAILBOX_MESSAGE_2, | ||
231 | .fifo_stat = MAILBOX_FIFOSTATUS_2, | ||
232 | }, | ||
233 | .rx_fifo = { | ||
234 | .msg = MAILBOX_MESSAGE_3, | ||
235 | .msg_stat = MAILBOX_MSGSTATUS_3, | ||
236 | }, | ||
237 | .irqenable = MAILBOX_IRQENABLE_3, | ||
238 | .irqstatus = MAILBOX_IRQSTATUS_3, | ||
239 | .notfull_bit = MAILBOX_IRQ_NOTFULL(2), | ||
240 | .newmsg_bit = MAILBOX_IRQ_NEWMSG(3), | ||
241 | }; | ||
242 | |||
243 | static struct omap_mbox mbox_iva_info = { | ||
244 | .name = "iva", | ||
245 | .ops = &omap2_mbox_ops, | ||
246 | .priv = &omap2_mbox_iva_priv, | ||
247 | }; | ||
248 | |||
249 | static int __init omap2_mbox_probe(struct platform_device *pdev) | ||
250 | { | ||
251 | struct resource *res; | ||
252 | int ret = 0; | ||
253 | |||
254 | if (pdev->num_resources != 3) { | ||
255 | dev_err(&pdev->dev, "invalid number of resources: %d\n", | ||
256 | pdev->num_resources); | ||
257 | return -ENODEV; | ||
258 | } | ||
259 | |||
260 | /* MBOX base */ | ||
261 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
262 | if (unlikely(!res)) { | ||
263 | dev_err(&pdev->dev, "invalid mem resource\n"); | ||
264 | return -ENODEV; | ||
265 | } | ||
266 | mbox_base = res->start; | ||
267 | |||
268 | /* DSP IRQ */ | ||
269 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
270 | if (unlikely(!res)) { | ||
271 | dev_err(&pdev->dev, "invalid irq resource\n"); | ||
272 | return -ENODEV; | ||
273 | } | ||
274 | mbox_dsp_info.irq = res->start; | ||
275 | |||
276 | ret = omap_mbox_register(&mbox_dsp_info); | ||
277 | |||
278 | /* IVA IRQ */ | ||
279 | res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); | ||
280 | if (unlikely(!res)) { | ||
281 | dev_err(&pdev->dev, "invalid irq resource\n"); | ||
282 | return -ENODEV; | ||
283 | } | ||
284 | mbox_iva_info.irq = res->start; | ||
285 | |||
286 | ret = omap_mbox_register(&mbox_iva_info); | ||
287 | |||
288 | return ret; | ||
289 | } | ||
290 | |||
291 | static int omap2_mbox_remove(struct platform_device *pdev) | ||
292 | { | ||
293 | omap_mbox_unregister(&mbox_dsp_info); | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static struct platform_driver omap2_mbox_driver = { | ||
298 | .probe = omap2_mbox_probe, | ||
299 | .remove = omap2_mbox_remove, | ||
300 | .driver = { | ||
301 | .name = "mailbox", | ||
302 | }, | ||
303 | }; | ||
304 | |||
305 | static int __init omap2_mbox_init(void) | ||
306 | { | ||
307 | return platform_driver_register(&omap2_mbox_driver); | ||
308 | } | ||
309 | |||
310 | static void __exit omap2_mbox_exit(void) | ||
311 | { | ||
312 | platform_driver_unregister(&omap2_mbox_driver); | ||
313 | } | ||
314 | |||
315 | module_init(omap2_mbox_init); | ||
316 | module_exit(omap2_mbox_exit); | ||
317 | |||
318 | MODULE_LICENSE("GPL"); | ||