aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/plat-omap/Kconfig99
-rw-r--r--arch/arm/plat-omap/Makefile16
-rw-r--r--arch/arm/plat-omap/common.c135
-rw-r--r--arch/arm/plat-omap/common.h36
-rw-r--r--arch/arm/plat-omap/dma.c1086
-rw-r--r--arch/arm/plat-omap/gpio.c762
-rw-r--r--arch/arm/plat-omap/mcbsp.c685
-rw-r--r--arch/arm/plat-omap/mux.c163
-rw-r--r--arch/arm/plat-omap/ocpi.c114
-rw-r--r--arch/arm/plat-omap/pm.c632
-rw-r--r--arch/arm/plat-omap/sleep.S314
-rw-r--r--arch/arm/plat-omap/usb.c593
12 files changed, 4635 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
new file mode 100644
index 000000000000..a72fe55b513b
--- /dev/null
+++ b/arch/arm/plat-omap/Kconfig
@@ -0,0 +1,99 @@
1if ARCH_OMAP
2
3menu "TI OMAP Implementations"
4
5config ARCH_OMAP_OTG
6 bool
7
8choice
9 prompt "OMAP System Type"
10 default ARCH_OMAP1
11
12config ARCH_OMAP1
13 bool "TI OMAP1"
14
15config ARCH_OMAP2
16 bool "TI OMAP2"
17
18endchoice
19
20comment "OMAP Feature Selections"
21
22config OMAP_MUX
23 bool "OMAP multiplexing support"
24 depends on ARCH_OMAP
25 default y
26 help
27 Pin multiplexing support for OMAP boards. If your bootloader
28 sets the multiplexing correctly, say N. Otherwise, or if unsure,
29 say Y.
30
31config OMAP_MUX_DEBUG
32 bool "Multiplexing debug output"
33 depends on OMAP_MUX
34 default n
35 help
36 Makes the multiplexing functions print out a lot of debug info.
37 This is useful if you want to find out the correct values of the
38 multiplexing registers.
39
40config OMAP_MUX_WARNINGS
41 bool "Warn about pins the bootloader didn't set up"
42 depends on OMAP_MUX
43 default y
44 help
45 Choose Y here to warn whenever driver initialization logic needs
46 to change the pin multiplexing setup. When there are no warnings
47 printed, it's safe to deselect OMAP_MUX for your product.
48
49choice
50 prompt "System timer"
51 default OMAP_MPU_TIMER
52
53config OMAP_MPU_TIMER
54 bool "Use mpu timer"
55 help
56 Select this option if you want to use the OMAP mpu timer. This
57 timer provides more intra-tick resolution than the 32KHz timer,
58 but consumes more power.
59
60config OMAP_32K_TIMER
61 bool "Use 32KHz timer"
62 depends on ARCH_OMAP16XX
63 help
64 Select this option if you want to enable the OMAP 32KHz timer.
65 This timer saves power compared to the OMAP_MPU_TIMER, and has
66 support for no tick during idle. The 32KHz timer provides less
67 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
68 currently only available for OMAP-16xx.
69
70endchoice
71
72config OMAP_32K_TIMER_HZ
73 int "Kernel internal timer frequency for 32KHz timer"
74 range 32 1024
75 depends on OMAP_32K_TIMER
76 default "128"
77 help
78 Kernel internal timer frequency should be a divisor of 32768,
79 such as 64 or 128.
80
81choice
82 prompt "Low-level debug console UART"
83 depends on ARCH_OMAP
84 default OMAP_LL_DEBUG_UART1
85
86config OMAP_LL_DEBUG_UART1
87 bool "UART1"
88
89config OMAP_LL_DEBUG_UART2
90 bool "UART2"
91
92config OMAP_LL_DEBUG_UART3
93 bool "UART3"
94
95endchoice
96
97endmenu
98
99endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
new file mode 100644
index 000000000000..3be25ebfc45e
--- /dev/null
+++ b/arch/arm/plat-omap/Makefile
@@ -0,0 +1,16 @@
1#
2# Makefile for the linux kernel.
3#
4
5# Common support
6obj-y := common.o dma.o clock.o mux.o gpio.o mcbsp.o usb.o
7obj-m :=
8obj-n :=
9obj- :=
10
11# OCPI interconnect support for 1710, 1610 and 5912
12obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
13
14# Power Management
15obj-$(CONFIG_PM) += pm.o sleep.o
16
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
new file mode 100644
index 000000000000..ea967a8f6ce5
--- /dev/null
+++ b/arch/arm/plat-omap/common.c
@@ -0,0 +1,135 @@
1/*
2 * linux/arch/arm/plat-omap/common.c
3 *
4 * Code common to all OMAP machines.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 */
10#include <linux/config.h>
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/init.h>
14#include <linux/delay.h>
15#include <linux/pm.h>
16#include <linux/console.h>
17#include <linux/serial.h>
18#include <linux/tty.h>
19#include <linux/serial_8250.h>
20#include <linux/serial_reg.h>
21
22#include <asm/hardware.h>
23#include <asm/system.h>
24#include <asm/pgtable.h>
25#include <asm/mach/map.h>
26#include <asm/hardware/clock.h>
27#include <asm/io.h>
28#include <asm/mach-types.h>
29
30#include <asm/arch/board.h>
31#include <asm/arch/mux.h>
32#include <asm/arch/fpga.h>
33
34#include "clock.h"
35
36#define NO_LENGTH_CHECK 0xffffffff
37
38extern int omap_bootloader_tag_len;
39extern u8 omap_bootloader_tag[];
40
41struct omap_board_config_kernel *omap_board_config;
42int omap_board_config_size = 0;
43
44static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
45{
46 struct omap_board_config_kernel *kinfo = NULL;
47 int i;
48
49#ifdef CONFIG_OMAP_BOOT_TAG
50 struct omap_board_config_entry *info = NULL;
51
52 if (omap_bootloader_tag_len > 4)
53 info = (struct omap_board_config_entry *) omap_bootloader_tag;
54 while (info != NULL) {
55 u8 *next;
56
57 if (info->tag == tag) {
58 if (skip == 0)
59 break;
60 skip--;
61 }
62
63 if ((info->len & 0x03) != 0) {
64 /* We bail out to avoid an alignment fault */
65 printk(KERN_ERR "OMAP peripheral config: Length (%d) not word-aligned (tag %04x)\n",
66 info->len, info->tag);
67 return NULL;
68 }
69 next = (u8 *) info + sizeof(*info) + info->len;
70 if (next >= omap_bootloader_tag + omap_bootloader_tag_len)
71 info = NULL;
72 else
73 info = (struct omap_board_config_entry *) next;
74 }
75 if (info != NULL) {
76 /* Check the length as a lame attempt to check for
77 * binary inconsistancy. */
78 if (len != NO_LENGTH_CHECK) {
79 /* Word-align len */
80 if (len & 0x03)
81 len = (len + 3) & ~0x03;
82 if (info->len != len) {
83 printk(KERN_ERR "OMAP peripheral config: Length mismatch with tag %x (want %d, got %d)\n",
84 tag, len, info->len);
85 return NULL;
86 }
87 }
88 if (len_out != NULL)
89 *len_out = info->len;
90 return info->data;
91 }
92#endif
93 /* Try to find the config from the board-specific structures
94 * in the kernel. */
95 for (i = 0; i < omap_board_config_size; i++) {
96 if (omap_board_config[i].tag == tag) {
97 kinfo = &omap_board_config[i];
98 break;
99 }
100 }
101 if (kinfo == NULL)
102 return NULL;
103 return kinfo->data;
104}
105
106const void *__omap_get_config(u16 tag, size_t len, int nr)
107{
108 return get_config(tag, len, nr, NULL);
109}
110EXPORT_SYMBOL(__omap_get_config);
111
112const void *omap_get_var_config(u16 tag, size_t *len)
113{
114 return get_config(tag, NO_LENGTH_CHECK, 0, len);
115}
116EXPORT_SYMBOL(omap_get_var_config);
117
118static int __init omap_add_serial_console(void)
119{
120 const struct omap_serial_console_config *info;
121
122 info = omap_get_config(OMAP_TAG_SERIAL_CONSOLE,
123 struct omap_serial_console_config);
124 if (info != NULL && info->console_uart) {
125 static char speed[11], *opt = NULL;
126
127 if (info->console_speed) {
128 snprintf(speed, sizeof(speed), "%u", info->console_speed);
129 opt = speed;
130 }
131 return add_preferred_console("ttyS", info->console_uart - 1, opt);
132 }
133 return 0;
134}
135console_initcall(omap_add_serial_console);
diff --git a/arch/arm/plat-omap/common.h b/arch/arm/plat-omap/common.h
new file mode 100644
index 000000000000..893964dfe18e
--- /dev/null
+++ b/arch/arm/plat-omap/common.h
@@ -0,0 +1,36 @@
1/*
2 * linux/arch/arm/plat-omap/common.h
3 *
4 * Header for code common to all OMAP machines.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
14 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
16 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
18 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
19 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
20 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21 *
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#ifndef __ARCH_ARM_MACH_OMAP_COMMON_H
28#define __ARCH_ARM_MACH_OMAP_COMMON_H
29
30struct sys_timer;
31
32extern void omap_map_common_io(void);
33extern struct sys_timer omap_timer;
34extern void omap_serial_init(int ports[]);
35
36#endif /* __ARCH_ARM_MACH_OMAP_COMMON_H */
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
new file mode 100644
index 000000000000..015bd2cf869f
--- /dev/null
+++ b/arch/arm/plat-omap/dma.c
@@ -0,0 +1,1086 @@
1/*
2 * linux/arch/arm/plat-omap/dma.c
3 *
4 * Copyright (C) 2003 Nokia Corporation
5 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
6 * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
7 * Graphics DMA and LCD DMA graphics tranformations
8 * by Imre Deak <imre.deak@nokia.com>
9 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
10 *
11 * Support functions for the OMAP internal DMA channels.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/sched.h>
22#include <linux/spinlock.h>
23#include <linux/errno.h>
24#include <linux/interrupt.h>
25
26#include <asm/system.h>
27#include <asm/irq.h>
28#include <asm/hardware.h>
29#include <asm/dma.h>
30#include <asm/io.h>
31
32#include <asm/arch/tc.h>
33
34#define OMAP_DMA_ACTIVE 0x01
35
36#define OMAP_DMA_CCR_EN (1 << 7)
37
38#define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec)
39
40static int enable_1510_mode = 0;
41
42struct omap_dma_lch {
43 int next_lch;
44 int dev_id;
45 u16 saved_csr;
46 u16 enabled_irqs;
47 const char *dev_name;
48 void (* callback)(int lch, u16 ch_status, void *data);
49 void *data;
50 long flags;
51};
52
53static int dma_chan_count;
54
55static spinlock_t dma_chan_lock;
56static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
57
58const static u8 dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
59 INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
60 INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
61 INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
62 INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
63 INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
64};
65
66static inline int get_gdma_dev(int req)
67{
68 u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
69 int shift = ((req - 1) % 5) * 6;
70
71 return ((omap_readl(reg) >> shift) & 0x3f) + 1;
72}
73
74static inline void set_gdma_dev(int req, int dev)
75{
76 u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
77 int shift = ((req - 1) % 5) * 6;
78 u32 l;
79
80 l = omap_readl(reg);
81 l &= ~(0x3f << shift);
82 l |= (dev - 1) << shift;
83 omap_writel(l, reg);
84}
85
86static void clear_lch_regs(int lch)
87{
88 int i;
89 u32 lch_base = OMAP_DMA_BASE + lch * 0x40;
90
91 for (i = 0; i < 0x2c; i += 2)
92 omap_writew(0, lch_base + i);
93}
94
95void omap_set_dma_priority(int dst_port, int priority)
96{
97 unsigned long reg;
98 u32 l;
99
100 switch (dst_port) {
101 case OMAP_DMA_PORT_OCP_T1: /* FFFECC00 */
102 reg = OMAP_TC_OCPT1_PRIOR;
103 break;
104 case OMAP_DMA_PORT_OCP_T2: /* FFFECCD0 */
105 reg = OMAP_TC_OCPT2_PRIOR;
106 break;
107 case OMAP_DMA_PORT_EMIFF: /* FFFECC08 */
108 reg = OMAP_TC_EMIFF_PRIOR;
109 break;
110 case OMAP_DMA_PORT_EMIFS: /* FFFECC04 */
111 reg = OMAP_TC_EMIFS_PRIOR;
112 break;
113 default:
114 BUG();
115 return;
116 }
117 l = omap_readl(reg);
118 l &= ~(0xf << 8);
119 l |= (priority & 0xf) << 8;
120 omap_writel(l, reg);
121}
122
123void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
124 int frame_count, int sync_mode)
125{
126 u16 w;
127
128 w = omap_readw(OMAP_DMA_CSDP(lch));
129 w &= ~0x03;
130 w |= data_type;
131 omap_writew(w, OMAP_DMA_CSDP(lch));
132
133 w = omap_readw(OMAP_DMA_CCR(lch));
134 w &= ~(1 << 5);
135 if (sync_mode == OMAP_DMA_SYNC_FRAME)
136 w |= 1 << 5;
137 omap_writew(w, OMAP_DMA_CCR(lch));
138
139 w = omap_readw(OMAP_DMA_CCR2(lch));
140 w &= ~(1 << 2);
141 if (sync_mode == OMAP_DMA_SYNC_BLOCK)
142 w |= 1 << 2;
143 omap_writew(w, OMAP_DMA_CCR2(lch));
144
145 omap_writew(elem_count, OMAP_DMA_CEN(lch));
146 omap_writew(frame_count, OMAP_DMA_CFN(lch));
147
148}
149void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
150{
151 u16 w;
152
153 BUG_ON(omap_dma_in_1510_mode());
154
155 w = omap_readw(OMAP_DMA_CCR2(lch)) & ~0x03;
156 switch (mode) {
157 case OMAP_DMA_CONSTANT_FILL:
158 w |= 0x01;
159 break;
160 case OMAP_DMA_TRANSPARENT_COPY:
161 w |= 0x02;
162 break;
163 case OMAP_DMA_COLOR_DIS:
164 break;
165 default:
166 BUG();
167 }
168 omap_writew(w, OMAP_DMA_CCR2(lch));
169
170 w = omap_readw(OMAP_DMA_LCH_CTRL(lch)) & ~0x0f;
171 /* Default is channel type 2D */
172 if (mode) {
173 omap_writew((u16)color, OMAP_DMA_COLOR_L(lch));
174 omap_writew((u16)(color >> 16), OMAP_DMA_COLOR_U(lch));
175 w |= 1; /* Channel type G */
176 }
177 omap_writew(w, OMAP_DMA_LCH_CTRL(lch));
178}
179
180
181void omap_set_dma_src_params(int lch, int src_port, int src_amode,
182 unsigned long src_start)
183{
184 u16 w;
185
186 w = omap_readw(OMAP_DMA_CSDP(lch));
187 w &= ~(0x1f << 2);
188 w |= src_port << 2;
189 omap_writew(w, OMAP_DMA_CSDP(lch));
190
191 w = omap_readw(OMAP_DMA_CCR(lch));
192 w &= ~(0x03 << 12);
193 w |= src_amode << 12;
194 omap_writew(w, OMAP_DMA_CCR(lch));
195
196 omap_writew(src_start >> 16, OMAP_DMA_CSSA_U(lch));
197 omap_writew(src_start, OMAP_DMA_CSSA_L(lch));
198}
199
200void omap_set_dma_src_index(int lch, int eidx, int fidx)
201{
202 omap_writew(eidx, OMAP_DMA_CSEI(lch));
203 omap_writew(fidx, OMAP_DMA_CSFI(lch));
204}
205
206void omap_set_dma_src_data_pack(int lch, int enable)
207{
208 u16 w;
209
210 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 6);
211 w |= enable ? (1 << 6) : 0;
212 omap_writew(w, OMAP_DMA_CSDP(lch));
213}
214
215void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
216{
217 u16 w;
218
219 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 7);
220 switch (burst_mode) {
221 case OMAP_DMA_DATA_BURST_DIS:
222 break;
223 case OMAP_DMA_DATA_BURST_4:
224 w |= (0x01 << 7);
225 break;
226 case OMAP_DMA_DATA_BURST_8:
227 /* not supported by current hardware
228 * w |= (0x03 << 7);
229 * fall through
230 */
231 default:
232 BUG();
233 }
234 omap_writew(w, OMAP_DMA_CSDP(lch));
235}
236
237void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
238 unsigned long dest_start)
239{
240 u16 w;
241
242 w = omap_readw(OMAP_DMA_CSDP(lch));
243 w &= ~(0x1f << 9);
244 w |= dest_port << 9;
245 omap_writew(w, OMAP_DMA_CSDP(lch));
246
247 w = omap_readw(OMAP_DMA_CCR(lch));
248 w &= ~(0x03 << 14);
249 w |= dest_amode << 14;
250 omap_writew(w, OMAP_DMA_CCR(lch));
251
252 omap_writew(dest_start >> 16, OMAP_DMA_CDSA_U(lch));
253 omap_writew(dest_start, OMAP_DMA_CDSA_L(lch));
254}
255
256void omap_set_dma_dest_index(int lch, int eidx, int fidx)
257{
258 omap_writew(eidx, OMAP_DMA_CDEI(lch));
259 omap_writew(fidx, OMAP_DMA_CDFI(lch));
260}
261
262void omap_set_dma_dest_data_pack(int lch, int enable)
263{
264 u16 w;
265
266 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(1 << 13);
267 w |= enable ? (1 << 13) : 0;
268 omap_writew(w, OMAP_DMA_CSDP(lch));
269}
270
271void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
272{
273 u16 w;
274
275 w = omap_readw(OMAP_DMA_CSDP(lch)) & ~(0x03 << 14);
276 switch (burst_mode) {
277 case OMAP_DMA_DATA_BURST_DIS:
278 break;
279 case OMAP_DMA_DATA_BURST_4:
280 w |= (0x01 << 14);
281 break;
282 case OMAP_DMA_DATA_BURST_8:
283 w |= (0x03 << 14);
284 break;
285 default:
286 printk(KERN_ERR "Invalid DMA burst mode\n");
287 BUG();
288 return;
289 }
290 omap_writew(w, OMAP_DMA_CSDP(lch));
291}
292
293static inline void init_intr(int lch)
294{
295 u16 w;
296
297 /* Read CSR to make sure it's cleared. */
298 w = omap_readw(OMAP_DMA_CSR(lch));
299 /* Enable some nice interrupts. */
300 omap_writew(dma_chan[lch].enabled_irqs, OMAP_DMA_CICR(lch));
301 dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
302}
303
304static inline void enable_lnk(int lch)
305{
306 u16 w;
307
308 /* Clear the STOP_LNK bits */
309 w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
310 w &= ~(1 << 14);
311 omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
312
313 /* And set the ENABLE_LNK bits */
314 if (dma_chan[lch].next_lch != -1)
315 omap_writew(dma_chan[lch].next_lch | (1 << 15),
316 OMAP_DMA_CLNK_CTRL(lch));
317}
318
319static inline void disable_lnk(int lch)
320{
321 u16 w;
322
323 /* Disable interrupts */
324 omap_writew(0, OMAP_DMA_CICR(lch));
325
326 /* Set the STOP_LNK bit */
327 w = omap_readw(OMAP_DMA_CLNK_CTRL(lch));
328 w |= (1 << 14);
329 w = omap_writew(w, OMAP_DMA_CLNK_CTRL(lch));
330
331 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
332}
333
334void omap_start_dma(int lch)
335{
336 u16 w;
337
338 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
339 int next_lch, cur_lch;
340 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
341
342 dma_chan_link_map[lch] = 1;
343 /* Set the link register of the first channel */
344 enable_lnk(lch);
345
346 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
347 cur_lch = dma_chan[lch].next_lch;
348 do {
349 next_lch = dma_chan[cur_lch].next_lch;
350
351 /* The loop case: we've been here already */
352 if (dma_chan_link_map[cur_lch])
353 break;
354 /* Mark the current channel */
355 dma_chan_link_map[cur_lch] = 1;
356
357 enable_lnk(cur_lch);
358 init_intr(cur_lch);
359
360 cur_lch = next_lch;
361 } while (next_lch != -1);
362 }
363
364 init_intr(lch);
365
366 w = omap_readw(OMAP_DMA_CCR(lch));
367 w |= OMAP_DMA_CCR_EN;
368 omap_writew(w, OMAP_DMA_CCR(lch));
369 dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
370}
371
372void omap_stop_dma(int lch)
373{
374 u16 w;
375
376 if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
377 int next_lch, cur_lch = lch;
378 char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
379
380 memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
381 do {
382 /* The loop case: we've been here already */
383 if (dma_chan_link_map[cur_lch])
384 break;
385 /* Mark the current channel */
386 dma_chan_link_map[cur_lch] = 1;
387
388 disable_lnk(cur_lch);
389
390 next_lch = dma_chan[cur_lch].next_lch;
391 cur_lch = next_lch;
392 } while (next_lch != -1);
393
394 return;
395 }
396 /* Disable all interrupts on the channel */
397 omap_writew(0, OMAP_DMA_CICR(lch));
398
399 w = omap_readw(OMAP_DMA_CCR(lch));
400 w &= ~OMAP_DMA_CCR_EN;
401 omap_writew(w, OMAP_DMA_CCR(lch));
402 dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
403}
404
405void omap_enable_dma_irq(int lch, u16 bits)
406{
407 dma_chan[lch].enabled_irqs |= bits;
408}
409
410void omap_disable_dma_irq(int lch, u16 bits)
411{
412 dma_chan[lch].enabled_irqs &= ~bits;
413}
414
415static int dma_handle_ch(int ch)
416{
417 u16 csr;
418
419 if (enable_1510_mode && ch >= 6) {
420 csr = dma_chan[ch].saved_csr;
421 dma_chan[ch].saved_csr = 0;
422 } else
423 csr = omap_readw(OMAP_DMA_CSR(ch));
424 if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
425 dma_chan[ch + 6].saved_csr = csr >> 7;
426 csr &= 0x7f;
427 }
428 if (!csr)
429 return 0;
430 if (unlikely(dma_chan[ch].dev_id == -1)) {
431 printk(KERN_WARNING "Spurious interrupt from DMA channel %d (CSR %04x)\n",
432 ch, csr);
433 return 0;
434 }
435 if (unlikely(csr & OMAP_DMA_TOUT_IRQ))
436 printk(KERN_WARNING "DMA timeout with device %d\n", dma_chan[ch].dev_id);
437 if (unlikely(csr & OMAP_DMA_DROP_IRQ))
438 printk(KERN_WARNING "DMA synchronization event drop occurred with device %d\n",
439 dma_chan[ch].dev_id);
440 if (likely(csr & OMAP_DMA_BLOCK_IRQ))
441 dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
442 if (likely(dma_chan[ch].callback != NULL))
443 dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
444 return 1;
445}
446
447static irqreturn_t dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
448{
449 int ch = ((int) dev_id) - 1;
450 int handled = 0;
451
452 for (;;) {
453 int handled_now = 0;
454
455 handled_now += dma_handle_ch(ch);
456 if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
457 handled_now += dma_handle_ch(ch + 6);
458 if (!handled_now)
459 break;
460 handled += handled_now;
461 }
462
463 return handled ? IRQ_HANDLED : IRQ_NONE;
464}
465
466int omap_request_dma(int dev_id, const char *dev_name,
467 void (* callback)(int lch, u16 ch_status, void *data),
468 void *data, int *dma_ch_out)
469{
470 int ch, free_ch = -1;
471 unsigned long flags;
472 struct omap_dma_lch *chan;
473
474 spin_lock_irqsave(&dma_chan_lock, flags);
475 for (ch = 0; ch < dma_chan_count; ch++) {
476 if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
477 free_ch = ch;
478 if (dev_id == 0)
479 break;
480 }
481 }
482 if (free_ch == -1) {
483 spin_unlock_irqrestore(&dma_chan_lock, flags);
484 return -EBUSY;
485 }
486 chan = dma_chan + free_ch;
487 chan->dev_id = dev_id;
488 clear_lch_regs(free_ch);
489 spin_unlock_irqrestore(&dma_chan_lock, flags);
490
491 chan->dev_id = dev_id;
492 chan->dev_name = dev_name;
493 chan->callback = callback;
494 chan->data = data;
495 chan->enabled_irqs = OMAP_DMA_TOUT_IRQ | OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
496
497 if (cpu_is_omap16xx()) {
498 /* If the sync device is set, configure it dynamically. */
499 if (dev_id != 0) {
500 set_gdma_dev(free_ch + 1, dev_id);
501 dev_id = free_ch + 1;
502 }
503 /* Disable the 1510 compatibility mode and set the sync device
504 * id. */
505 omap_writew(dev_id | (1 << 10), OMAP_DMA_CCR(free_ch));
506 } else {
507 omap_writew(dev_id, OMAP_DMA_CCR(free_ch));
508 }
509 *dma_ch_out = free_ch;
510
511 return 0;
512}
513
514void omap_free_dma(int ch)
515{
516 unsigned long flags;
517
518 spin_lock_irqsave(&dma_chan_lock, flags);
519 if (dma_chan[ch].dev_id == -1) {
520 printk("omap_dma: trying to free nonallocated DMA channel %d\n", ch);
521 spin_unlock_irqrestore(&dma_chan_lock, flags);
522 return;
523 }
524 dma_chan[ch].dev_id = -1;
525 spin_unlock_irqrestore(&dma_chan_lock, flags);
526
527 /* Disable all DMA interrupts for the channel. */
528 omap_writew(0, OMAP_DMA_CICR(ch));
529 /* Make sure the DMA transfer is stopped. */
530 omap_writew(0, OMAP_DMA_CCR(ch));
531}
532
533int omap_dma_in_1510_mode(void)
534{
535 return enable_1510_mode;
536}
537
538/*
539 * lch_queue DMA will start right after lch_head one is finished.
540 * For this DMA link to start, you still need to start (see omap_start_dma)
541 * the first one. That will fire up the entire queue.
542 */
543void omap_dma_link_lch (int lch_head, int lch_queue)
544{
545 if (omap_dma_in_1510_mode()) {
546 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
547 BUG();
548 return;
549 }
550
551 if ((dma_chan[lch_head].dev_id == -1) ||
552 (dma_chan[lch_queue].dev_id == -1)) {
553 printk(KERN_ERR "omap_dma: trying to link non requested channels\n");
554 dump_stack();
555 }
556
557 dma_chan[lch_head].next_lch = lch_queue;
558}
559
560/*
561 * Once the DMA queue is stopped, we can destroy it.
562 */
563void omap_dma_unlink_lch (int lch_head, int lch_queue)
564{
565 if (omap_dma_in_1510_mode()) {
566 printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
567 BUG();
568 return;
569 }
570
571 if (dma_chan[lch_head].next_lch != lch_queue ||
572 dma_chan[lch_head].next_lch == -1) {
573 printk(KERN_ERR "omap_dma: trying to unlink non linked channels\n");
574 dump_stack();
575 }
576
577
578 if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
579 (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
580 printk(KERN_ERR "omap_dma: You need to stop the DMA channels before unlinking\n");
581 dump_stack();
582 }
583
584 dma_chan[lch_head].next_lch = -1;
585}
586
587
588static struct lcd_dma_info {
589 spinlock_t lock;
590 int reserved;
591 void (* callback)(u16 status, void *data);
592 void *cb_data;
593
594 int active;
595 unsigned long addr, size;
596 int rotate, data_type, xres, yres;
597 int vxres;
598 int mirror;
599 int xscale, yscale;
600 int ext_ctrl;
601 int src_port;
602 int single_transfer;
603} lcd_dma;
604
605void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
606 int data_type)
607{
608 lcd_dma.addr = addr;
609 lcd_dma.data_type = data_type;
610 lcd_dma.xres = fb_xres;
611 lcd_dma.yres = fb_yres;
612}
613
614void omap_set_lcd_dma_src_port(int port)
615{
616 lcd_dma.src_port = port;
617}
618
619void omap_set_lcd_dma_ext_controller(int external)
620{
621 lcd_dma.ext_ctrl = external;
622}
623
624void omap_set_lcd_dma_single_transfer(int single)
625{
626 lcd_dma.single_transfer = single;
627}
628
629
630void omap_set_lcd_dma_b1_rotation(int rotate)
631{
632 if (omap_dma_in_1510_mode()) {
633 printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
634 BUG();
635 return;
636 }
637 lcd_dma.rotate = rotate;
638}
639
640void omap_set_lcd_dma_b1_mirror(int mirror)
641{
642 if (omap_dma_in_1510_mode()) {
643 printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
644 BUG();
645 }
646 lcd_dma.mirror = mirror;
647}
648
649void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
650{
651 if (omap_dma_in_1510_mode()) {
652 printk(KERN_ERR "DMA virtual resulotion is not supported "
653 "in 1510 mode\n");
654 BUG();
655 }
656 lcd_dma.vxres = vxres;
657}
658
659void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
660{
661 if (omap_dma_in_1510_mode()) {
662 printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
663 BUG();
664 }
665 lcd_dma.xscale = xscale;
666 lcd_dma.yscale = yscale;
667}
668
669static void set_b1_regs(void)
670{
671 unsigned long top, bottom;
672 int es;
673 u16 w;
674 unsigned long en, fn;
675 long ei, fi;
676 unsigned long vxres;
677 unsigned int xscale, yscale;
678
679 switch (lcd_dma.data_type) {
680 case OMAP_DMA_DATA_TYPE_S8:
681 es = 1;
682 break;
683 case OMAP_DMA_DATA_TYPE_S16:
684 es = 2;
685 break;
686 case OMAP_DMA_DATA_TYPE_S32:
687 es = 4;
688 break;
689 default:
690 BUG();
691 return;
692 }
693
694 vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
695 xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
696 yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
697 BUG_ON(vxres < lcd_dma.xres);
698#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
699#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
700 switch (lcd_dma.rotate) {
701 case 0:
702 if (!lcd_dma.mirror) {
703 top = PIXADDR(0, 0);
704 bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
705 /* 1510 DMA requires the bottom address to be 2 more
706 * than the actual last memory access location. */
707 if (omap_dma_in_1510_mode() &&
708 lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
709 bottom += 2;
710 ei = PIXSTEP(0, 0, 1, 0);
711 fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
712 } else {
713 top = PIXADDR(lcd_dma.xres - 1, 0);
714 bottom = PIXADDR(0, lcd_dma.yres - 1);
715 ei = PIXSTEP(1, 0, 0, 0);
716 fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
717 }
718 en = lcd_dma.xres;
719 fn = lcd_dma.yres;
720 break;
721 case 90:
722 if (!lcd_dma.mirror) {
723 top = PIXADDR(0, lcd_dma.yres - 1);
724 bottom = PIXADDR(lcd_dma.xres - 1, 0);
725 ei = PIXSTEP(0, 1, 0, 0);
726 fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
727 } else {
728 top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
729 bottom = PIXADDR(0, 0);
730 ei = PIXSTEP(0, 1, 0, 0);
731 fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
732 }
733 en = lcd_dma.yres;
734 fn = lcd_dma.xres;
735 break;
736 case 180:
737 if (!lcd_dma.mirror) {
738 top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
739 bottom = PIXADDR(0, 0);
740 ei = PIXSTEP(1, 0, 0, 0);
741 fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
742 } else {
743 top = PIXADDR(0, lcd_dma.yres - 1);
744 bottom = PIXADDR(lcd_dma.xres - 1, 0);
745 ei = PIXSTEP(0, 0, 1, 0);
746 fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
747 }
748 en = lcd_dma.xres;
749 fn = lcd_dma.yres;
750 break;
751 case 270:
752 if (!lcd_dma.mirror) {
753 top = PIXADDR(lcd_dma.xres - 1, 0);
754 bottom = PIXADDR(0, lcd_dma.yres - 1);
755 ei = PIXSTEP(0, 0, 0, 1);
756 fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
757 } else {
758 top = PIXADDR(0, 0);
759 bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
760 ei = PIXSTEP(0, 0, 0, 1);
761 fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
762 }
763 en = lcd_dma.yres;
764 fn = lcd_dma.xres;
765 break;
766 default:
767 BUG();
768 return; /* Supress warning about uninitialized vars */
769 }
770
771 if (omap_dma_in_1510_mode()) {
772 omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
773 omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
774 omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
775 omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
776
777 return;
778 }
779
780 /* 1610 regs */
781 omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
782 omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
783 omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
784 omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
785
786 omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
787 omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
788
789 w = omap_readw(OMAP1610_DMA_LCD_CSDP);
790 w &= ~0x03;
791 w |= lcd_dma.data_type;
792 omap_writew(w, OMAP1610_DMA_LCD_CSDP);
793
794 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
795 /* Always set the source port as SDRAM for now*/
796 w &= ~(0x03 << 6);
797 if (lcd_dma.ext_ctrl)
798 w |= 1 << 8;
799 else
800 w &= ~(1 << 8);
801 if (lcd_dma.callback != NULL)
802 w |= 1 << 1; /* Block interrupt enable */
803 else
804 w &= ~(1 << 1);
805 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
806
807 if (!(lcd_dma.rotate || lcd_dma.mirror ||
808 lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
809 return;
810
811 w = omap_readw(OMAP1610_DMA_LCD_CCR);
812 /* Set the double-indexed addressing mode */
813 w |= (0x03 << 12);
814 omap_writew(w, OMAP1610_DMA_LCD_CCR);
815
816 omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
817 omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
818 omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
819}
820
821static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
822{
823 u16 w;
824
825 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
826 if (unlikely(!(w & (1 << 3)))) {
827 printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
828 return IRQ_NONE;
829 }
830 /* Ack the IRQ */
831 w |= (1 << 3);
832 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
833 lcd_dma.active = 0;
834 if (lcd_dma.callback != NULL)
835 lcd_dma.callback(w, lcd_dma.cb_data);
836
837 return IRQ_HANDLED;
838}
839
840int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
841 void *data)
842{
843 spin_lock_irq(&lcd_dma.lock);
844 if (lcd_dma.reserved) {
845 spin_unlock_irq(&lcd_dma.lock);
846 printk(KERN_ERR "LCD DMA channel already reserved\n");
847 BUG();
848 return -EBUSY;
849 }
850 lcd_dma.reserved = 1;
851 spin_unlock_irq(&lcd_dma.lock);
852 lcd_dma.callback = callback;
853 lcd_dma.cb_data = data;
854 lcd_dma.active = 0;
855 lcd_dma.single_transfer = 0;
856 lcd_dma.rotate = 0;
857 lcd_dma.vxres = 0;
858 lcd_dma.mirror = 0;
859 lcd_dma.xscale = 0;
860 lcd_dma.yscale = 0;
861 lcd_dma.ext_ctrl = 0;
862 lcd_dma.src_port = 0;
863
864 return 0;
865}
866
867void omap_free_lcd_dma(void)
868{
869 spin_lock(&lcd_dma.lock);
870 if (!lcd_dma.reserved) {
871 spin_unlock(&lcd_dma.lock);
872 printk(KERN_ERR "LCD DMA is not reserved\n");
873 BUG();
874 return;
875 }
876 if (!enable_1510_mode)
877 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
878 lcd_dma.reserved = 0;
879 spin_unlock(&lcd_dma.lock);
880}
881
882void omap_enable_lcd_dma(void)
883{
884 u16 w;
885
886 /* Set the Enable bit only if an external controller is
887 * connected. Otherwise the OMAP internal controller will
888 * start the transfer when it gets enabled.
889 */
890 if (enable_1510_mode || !lcd_dma.ext_ctrl)
891 return;
892 w = omap_readw(OMAP1610_DMA_LCD_CCR);
893 w |= 1 << 7;
894 omap_writew(w, OMAP1610_DMA_LCD_CCR);
895 lcd_dma.active = 1;
896}
897
898void omap_setup_lcd_dma(void)
899{
900 BUG_ON(lcd_dma.active);
901 if (!enable_1510_mode) {
902 /* Set some reasonable defaults */
903 omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
904 omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
905 omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
906 }
907 set_b1_regs();
908 if (!enable_1510_mode) {
909 u16 w;
910
911 w = omap_readw(OMAP1610_DMA_LCD_CCR);
912 /* If DMA was already active set the end_prog bit to have
913 * the programmed register set loaded into the active
914 * register set.
915 */
916 w |= 1 << 11; /* End_prog */
917 if (!lcd_dma.single_transfer)
918 w |= (3 << 8); /* Auto_init, repeat */
919 omap_writew(w, OMAP1610_DMA_LCD_CCR);
920 }
921}
922
923void omap_stop_lcd_dma(void)
924{
925 lcd_dma.active = 0;
926 if (!enable_1510_mode && lcd_dma.ext_ctrl)
927 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~(1 << 7),
928 OMAP1610_DMA_LCD_CCR);
929}
930
931/*
932 * Clears any DMA state so the DMA engine is ready to restart with new buffers
933 * through omap_start_dma(). Any buffers in flight are discarded.
934 */
935void omap_clear_dma(int lch)
936{
937 unsigned long flags;
938 int status;
939
940 local_irq_save(flags);
941 omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
942 OMAP_DMA_CCR(lch));
943 status = OMAP_DMA_CSR(lch); /* clear pending interrupts */
944 local_irq_restore(flags);
945}
946
947/*
948 * Returns current physical source address for the given DMA channel.
949 * If the channel is running the caller must disable interrupts prior calling
950 * this function and process the returned value before re-enabling interrupt to
951 * prevent races with the interrupt handler. Note that in continuous mode there
952 * is a chance for CSSA_L register overflow inbetween the two reads resulting
953 * in incorrect return value.
954 */
955dma_addr_t omap_get_dma_src_pos(int lch)
956{
957 return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
958 (OMAP_DMA_CSSA_U(lch) << 16));
959}
960
961/*
962 * Returns current physical destination address for the given DMA channel.
963 * If the channel is running the caller must disable interrupts prior calling
964 * this function and process the returned value before re-enabling interrupt to
965 * prevent races with the interrupt handler. Note that in continuous mode there
966 * is a chance for CDSA_L register overflow inbetween the two reads resulting
967 * in incorrect return value.
968 */
969dma_addr_t omap_get_dma_dst_pos(int lch)
970{
971 return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
972 (OMAP_DMA_CDSA_U(lch) << 16));
973}
974
975static int __init omap_init_dma(void)
976{
977 int ch, r;
978
979 if (cpu_is_omap1510()) {
980 printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
981 dma_chan_count = 9;
982 enable_1510_mode = 1;
983 } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
984 printk(KERN_INFO "OMAP DMA hardware version %d\n",
985 omap_readw(OMAP_DMA_HW_ID));
986 printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
987 (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
988 (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
989 omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
990 omap_readw(OMAP_DMA_CAPS_4));
991 if (!enable_1510_mode) {
992 u16 w;
993
994 /* Disable OMAP 3.0/3.1 compatibility mode. */
995 w = omap_readw(OMAP_DMA_GSCR);
996 w |= 1 << 3;
997 omap_writew(w, OMAP_DMA_GSCR);
998 dma_chan_count = 16;
999 } else
1000 dma_chan_count = 9;
1001 } else {
1002 dma_chan_count = 0;
1003 return 0;
1004 }
1005
1006 memset(&lcd_dma, 0, sizeof(lcd_dma));
1007 spin_lock_init(&lcd_dma.lock);
1008 spin_lock_init(&dma_chan_lock);
1009 memset(&dma_chan, 0, sizeof(dma_chan));
1010
1011 for (ch = 0; ch < dma_chan_count; ch++) {
1012 dma_chan[ch].dev_id = -1;
1013 dma_chan[ch].next_lch = -1;
1014
1015 if (ch >= 6 && enable_1510_mode)
1016 continue;
1017
1018 /* request_irq() doesn't like dev_id (ie. ch) being zero,
1019 * so we have to kludge around this. */
1020 r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA",
1021 (void *) (ch + 1));
1022 if (r != 0) {
1023 int i;
1024
1025 printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n",
1026 dma_irq[ch], r);
1027 for (i = 0; i < ch; i++)
1028 free_irq(dma_irq[i], (void *) (i + 1));
1029 return r;
1030 }
1031 }
1032 r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
1033 if (r != 0) {
1034 int i;
1035
1036 printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
1037 for (i = 0; i < dma_chan_count; i++)
1038 free_irq(dma_irq[i], (void *) (i + 1));
1039 return r;
1040 }
1041 return 0;
1042}
1043
1044arch_initcall(omap_init_dma);
1045
1046
1047EXPORT_SYMBOL(omap_get_dma_src_pos);
1048EXPORT_SYMBOL(omap_get_dma_dst_pos);
1049EXPORT_SYMBOL(omap_clear_dma);
1050EXPORT_SYMBOL(omap_set_dma_priority);
1051EXPORT_SYMBOL(omap_request_dma);
1052EXPORT_SYMBOL(omap_free_dma);
1053EXPORT_SYMBOL(omap_start_dma);
1054EXPORT_SYMBOL(omap_stop_dma);
1055EXPORT_SYMBOL(omap_enable_dma_irq);
1056EXPORT_SYMBOL(omap_disable_dma_irq);
1057
1058EXPORT_SYMBOL(omap_set_dma_transfer_params);
1059EXPORT_SYMBOL(omap_set_dma_color_mode);
1060
1061EXPORT_SYMBOL(omap_set_dma_src_params);
1062EXPORT_SYMBOL(omap_set_dma_src_index);
1063EXPORT_SYMBOL(omap_set_dma_src_data_pack);
1064EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
1065
1066EXPORT_SYMBOL(omap_set_dma_dest_params);
1067EXPORT_SYMBOL(omap_set_dma_dest_index);
1068EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
1069EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
1070
1071EXPORT_SYMBOL(omap_dma_link_lch);
1072EXPORT_SYMBOL(omap_dma_unlink_lch);
1073
1074EXPORT_SYMBOL(omap_request_lcd_dma);
1075EXPORT_SYMBOL(omap_free_lcd_dma);
1076EXPORT_SYMBOL(omap_enable_lcd_dma);
1077EXPORT_SYMBOL(omap_setup_lcd_dma);
1078EXPORT_SYMBOL(omap_stop_lcd_dma);
1079EXPORT_SYMBOL(omap_set_lcd_dma_b1);
1080EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
1081EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
1082EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
1083EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
1084EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
1085EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
1086
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
new file mode 100644
index 000000000000..1c85b4e536c2
--- /dev/null
+++ b/arch/arm/plat-omap/gpio.c
@@ -0,0 +1,762 @@
1/*
2 * linux/arch/arm/plat-omap/gpio.c
3 *
4 * Support functions for OMAP GPIO
5 *
6 * Copyright (C) 2003 Nokia Corporation
7 * Written by Juha Yrjölä <juha.yrjola@nokia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <linux/config.h>
15#include <linux/init.h>
16#include <linux/module.h>
17#include <linux/sched.h>
18#include <linux/interrupt.h>
19#include <linux/ptrace.h>
20
21#include <asm/hardware.h>
22#include <asm/irq.h>
23#include <asm/arch/irqs.h>
24#include <asm/arch/gpio.h>
25#include <asm/mach/irq.h>
26
27#include <asm/io.h>
28
29/*
30 * OMAP1510 GPIO registers
31 */
32#define OMAP1510_GPIO_BASE 0xfffce000
33#define OMAP1510_GPIO_DATA_INPUT 0x00
34#define OMAP1510_GPIO_DATA_OUTPUT 0x04
35#define OMAP1510_GPIO_DIR_CONTROL 0x08
36#define OMAP1510_GPIO_INT_CONTROL 0x0c
37#define OMAP1510_GPIO_INT_MASK 0x10
38#define OMAP1510_GPIO_INT_STATUS 0x14
39#define OMAP1510_GPIO_PIN_CONTROL 0x18
40
41#define OMAP1510_IH_GPIO_BASE 64
42
43/*
44 * OMAP1610 specific GPIO registers
45 */
46#define OMAP1610_GPIO1_BASE 0xfffbe400
47#define OMAP1610_GPIO2_BASE 0xfffbec00
48#define OMAP1610_GPIO3_BASE 0xfffbb400
49#define OMAP1610_GPIO4_BASE 0xfffbbc00
50#define OMAP1610_GPIO_REVISION 0x0000
51#define OMAP1610_GPIO_SYSCONFIG 0x0010
52#define OMAP1610_GPIO_SYSSTATUS 0x0014
53#define OMAP1610_GPIO_IRQSTATUS1 0x0018
54#define OMAP1610_GPIO_IRQENABLE1 0x001c
55#define OMAP1610_GPIO_DATAIN 0x002c
56#define OMAP1610_GPIO_DATAOUT 0x0030
57#define OMAP1610_GPIO_DIRECTION 0x0034
58#define OMAP1610_GPIO_EDGE_CTRL1 0x0038
59#define OMAP1610_GPIO_EDGE_CTRL2 0x003c
60#define OMAP1610_GPIO_CLEAR_IRQENABLE1 0x009c
61#define OMAP1610_GPIO_CLEAR_DATAOUT 0x00b0
62#define OMAP1610_GPIO_SET_IRQENABLE1 0x00dc
63#define OMAP1610_GPIO_SET_DATAOUT 0x00f0
64
65/*
66 * OMAP730 specific GPIO registers
67 */
68#define OMAP730_GPIO1_BASE 0xfffbc000
69#define OMAP730_GPIO2_BASE 0xfffbc800
70#define OMAP730_GPIO3_BASE 0xfffbd000
71#define OMAP730_GPIO4_BASE 0xfffbd800
72#define OMAP730_GPIO5_BASE 0xfffbe000
73#define OMAP730_GPIO6_BASE 0xfffbe800
74#define OMAP730_GPIO_DATA_INPUT 0x00
75#define OMAP730_GPIO_DATA_OUTPUT 0x04
76#define OMAP730_GPIO_DIR_CONTROL 0x08
77#define OMAP730_GPIO_INT_CONTROL 0x0c
78#define OMAP730_GPIO_INT_MASK 0x10
79#define OMAP730_GPIO_INT_STATUS 0x14
80
81#define OMAP_MPUIO_MASK (~OMAP_MAX_GPIO_LINES & 0xff)
82
83struct gpio_bank {
84 u32 base;
85 u16 irq;
86 u16 virtual_irq_start;
87 u8 method;
88 u32 reserved_map;
89 spinlock_t lock;
90};
91
92#define METHOD_MPUIO 0
93#define METHOD_GPIO_1510 1
94#define METHOD_GPIO_1610 2
95#define METHOD_GPIO_730 3
96
97#if defined(CONFIG_ARCH_OMAP16XX)
98static struct gpio_bank gpio_bank_1610[5] = {
99 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO},
100 { OMAP1610_GPIO1_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1610 },
101 { OMAP1610_GPIO2_BASE, INT_1610_GPIO_BANK2, IH_GPIO_BASE + 16, METHOD_GPIO_1610 },
102 { OMAP1610_GPIO3_BASE, INT_1610_GPIO_BANK3, IH_GPIO_BASE + 32, METHOD_GPIO_1610 },
103 { OMAP1610_GPIO4_BASE, INT_1610_GPIO_BANK4, IH_GPIO_BASE + 48, METHOD_GPIO_1610 },
104};
105#endif
106
107#ifdef CONFIG_ARCH_OMAP1510
108static struct gpio_bank gpio_bank_1510[2] = {
109 { OMAP_MPUIO_BASE, INT_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
110 { OMAP1510_GPIO_BASE, INT_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_1510 }
111};
112#endif
113
114#ifdef CONFIG_ARCH_OMAP730
115static struct gpio_bank gpio_bank_730[7] = {
116 { OMAP_MPUIO_BASE, INT_730_MPUIO, IH_MPUIO_BASE, METHOD_MPUIO },
117 { OMAP730_GPIO1_BASE, INT_730_GPIO_BANK1, IH_GPIO_BASE, METHOD_GPIO_730 },
118 { OMAP730_GPIO2_BASE, INT_730_GPIO_BANK2, IH_GPIO_BASE + 32, METHOD_GPIO_730 },
119 { OMAP730_GPIO3_BASE, INT_730_GPIO_BANK3, IH_GPIO_BASE + 64, METHOD_GPIO_730 },
120 { OMAP730_GPIO4_BASE, INT_730_GPIO_BANK4, IH_GPIO_BASE + 96, METHOD_GPIO_730 },
121 { OMAP730_GPIO5_BASE, INT_730_GPIO_BANK5, IH_GPIO_BASE + 128, METHOD_GPIO_730 },
122 { OMAP730_GPIO6_BASE, INT_730_GPIO_BANK6, IH_GPIO_BASE + 160, METHOD_GPIO_730 },
123};
124#endif
125
126static struct gpio_bank *gpio_bank;
127static int gpio_bank_count;
128
129static inline struct gpio_bank *get_gpio_bank(int gpio)
130{
131#ifdef CONFIG_ARCH_OMAP1510
132 if (cpu_is_omap1510()) {
133 if (OMAP_GPIO_IS_MPUIO(gpio))
134 return &gpio_bank[0];
135 return &gpio_bank[1];
136 }
137#endif
138#if defined(CONFIG_ARCH_OMAP16XX)
139 if (cpu_is_omap16xx()) {
140 if (OMAP_GPIO_IS_MPUIO(gpio))
141 return &gpio_bank[0];
142 return &gpio_bank[1 + (gpio >> 4)];
143 }
144#endif
145#ifdef CONFIG_ARCH_OMAP730
146 if (cpu_is_omap730()) {
147 if (OMAP_GPIO_IS_MPUIO(gpio))
148 return &gpio_bank[0];
149 return &gpio_bank[1 + (gpio >> 5)];
150 }
151#endif
152}
153
154static inline int get_gpio_index(int gpio)
155{
156 if (cpu_is_omap730())
157 return gpio & 0x1f;
158 else
159 return gpio & 0x0f;
160}
161
162static inline int gpio_valid(int gpio)
163{
164 if (gpio < 0)
165 return -1;
166 if (OMAP_GPIO_IS_MPUIO(gpio)) {
167 if ((gpio & OMAP_MPUIO_MASK) > 16)
168 return -1;
169 return 0;
170 }
171#ifdef CONFIG_ARCH_OMAP1510
172 if (cpu_is_omap1510() && gpio < 16)
173 return 0;
174#endif
175#if defined(CONFIG_ARCH_OMAP16XX)
176 if ((cpu_is_omap16xx()) && gpio < 64)
177 return 0;
178#endif
179#ifdef CONFIG_ARCH_OMAP730
180 if (cpu_is_omap730() && gpio < 192)
181 return 0;
182#endif
183 return -1;
184}
185
186static int check_gpio(int gpio)
187{
188 if (unlikely(gpio_valid(gpio)) < 0) {
189 printk(KERN_ERR "omap-gpio: invalid GPIO %d\n", gpio);
190 dump_stack();
191 return -1;
192 }
193 return 0;
194}
195
196static void _set_gpio_direction(struct gpio_bank *bank, int gpio, int is_input)
197{
198 u32 reg = bank->base;
199 u32 l;
200
201 switch (bank->method) {
202 case METHOD_MPUIO:
203 reg += OMAP_MPUIO_IO_CNTL;
204 break;
205 case METHOD_GPIO_1510:
206 reg += OMAP1510_GPIO_DIR_CONTROL;
207 break;
208 case METHOD_GPIO_1610:
209 reg += OMAP1610_GPIO_DIRECTION;
210 break;
211 case METHOD_GPIO_730:
212 reg += OMAP730_GPIO_DIR_CONTROL;
213 break;
214 }
215 l = __raw_readl(reg);
216 if (is_input)
217 l |= 1 << gpio;
218 else
219 l &= ~(1 << gpio);
220 __raw_writel(l, reg);
221}
222
223void omap_set_gpio_direction(int gpio, int is_input)
224{
225 struct gpio_bank *bank;
226
227 if (check_gpio(gpio) < 0)
228 return;
229 bank = get_gpio_bank(gpio);
230 spin_lock(&bank->lock);
231 _set_gpio_direction(bank, get_gpio_index(gpio), is_input);
232 spin_unlock(&bank->lock);
233}
234
235static void _set_gpio_dataout(struct gpio_bank *bank, int gpio, int enable)
236{
237 u32 reg = bank->base;
238 u32 l = 0;
239
240 switch (bank->method) {
241 case METHOD_MPUIO:
242 reg += OMAP_MPUIO_OUTPUT;
243 l = __raw_readl(reg);
244 if (enable)
245 l |= 1 << gpio;
246 else
247 l &= ~(1 << gpio);
248 break;
249 case METHOD_GPIO_1510:
250 reg += OMAP1510_GPIO_DATA_OUTPUT;
251 l = __raw_readl(reg);
252 if (enable)
253 l |= 1 << gpio;
254 else
255 l &= ~(1 << gpio);
256 break;
257 case METHOD_GPIO_1610:
258 if (enable)
259 reg += OMAP1610_GPIO_SET_DATAOUT;
260 else
261 reg += OMAP1610_GPIO_CLEAR_DATAOUT;
262 l = 1 << gpio;
263 break;
264 case METHOD_GPIO_730:
265 reg += OMAP730_GPIO_DATA_OUTPUT;
266 l = __raw_readl(reg);
267 if (enable)
268 l |= 1 << gpio;
269 else
270 l &= ~(1 << gpio);
271 break;
272 default:
273 BUG();
274 return;
275 }
276 __raw_writel(l, reg);
277}
278
279void omap_set_gpio_dataout(int gpio, int enable)
280{
281 struct gpio_bank *bank;
282
283 if (check_gpio(gpio) < 0)
284 return;
285 bank = get_gpio_bank(gpio);
286 spin_lock(&bank->lock);
287 _set_gpio_dataout(bank, get_gpio_index(gpio), enable);
288 spin_unlock(&bank->lock);
289}
290
291int omap_get_gpio_datain(int gpio)
292{
293 struct gpio_bank *bank;
294 u32 reg;
295
296 if (check_gpio(gpio) < 0)
297 return -1;
298 bank = get_gpio_bank(gpio);
299 reg = bank->base;
300 switch (bank->method) {
301 case METHOD_MPUIO:
302 reg += OMAP_MPUIO_INPUT_LATCH;
303 break;
304 case METHOD_GPIO_1510:
305 reg += OMAP1510_GPIO_DATA_INPUT;
306 break;
307 case METHOD_GPIO_1610:
308 reg += OMAP1610_GPIO_DATAIN;
309 break;
310 case METHOD_GPIO_730:
311 reg += OMAP730_GPIO_DATA_INPUT;
312 break;
313 default:
314 BUG();
315 return -1;
316 }
317 return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
318}
319
320static void _set_gpio_edge_ctrl(struct gpio_bank *bank, int gpio, int edge)
321{
322 u32 reg = bank->base;
323 u32 l;
324
325 switch (bank->method) {
326 case METHOD_MPUIO:
327 reg += OMAP_MPUIO_GPIO_INT_EDGE;
328 l = __raw_readl(reg);
329 if (edge == OMAP_GPIO_RISING_EDGE)
330 l |= 1 << gpio;
331 else
332 l &= ~(1 << gpio);
333 __raw_writel(l, reg);
334 break;
335 case METHOD_GPIO_1510:
336 reg += OMAP1510_GPIO_INT_CONTROL;
337 l = __raw_readl(reg);
338 if (edge == OMAP_GPIO_RISING_EDGE)
339 l |= 1 << gpio;
340 else
341 l &= ~(1 << gpio);
342 __raw_writel(l, reg);
343 break;
344 case METHOD_GPIO_1610:
345 edge &= 0x03;
346 if (gpio & 0x08)
347 reg += OMAP1610_GPIO_EDGE_CTRL2;
348 else
349 reg += OMAP1610_GPIO_EDGE_CTRL1;
350 gpio &= 0x07;
351 l = __raw_readl(reg);
352 l &= ~(3 << (gpio << 1));
353 l |= edge << (gpio << 1);
354 __raw_writel(l, reg);
355 break;
356 case METHOD_GPIO_730:
357 reg += OMAP730_GPIO_INT_CONTROL;
358 l = __raw_readl(reg);
359 if (edge == OMAP_GPIO_RISING_EDGE)
360 l |= 1 << gpio;
361 else
362 l &= ~(1 << gpio);
363 __raw_writel(l, reg);
364 break;
365 default:
366 BUG();
367 return;
368 }
369}
370
371void omap_set_gpio_edge_ctrl(int gpio, int edge)
372{
373 struct gpio_bank *bank;
374
375 if (check_gpio(gpio) < 0)
376 return;
377 bank = get_gpio_bank(gpio);
378 spin_lock(&bank->lock);
379 _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), edge);
380 spin_unlock(&bank->lock);
381}
382
383
384static int _get_gpio_edge_ctrl(struct gpio_bank *bank, int gpio)
385{
386 u32 reg = bank->base, l;
387
388 switch (bank->method) {
389 case METHOD_MPUIO:
390 l = __raw_readl(reg + OMAP_MPUIO_GPIO_INT_EDGE);
391 return (l & (1 << gpio)) ?
392 OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
393 case METHOD_GPIO_1510:
394 l = __raw_readl(reg + OMAP1510_GPIO_INT_CONTROL);
395 return (l & (1 << gpio)) ?
396 OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
397 case METHOD_GPIO_1610:
398 if (gpio & 0x08)
399 reg += OMAP1610_GPIO_EDGE_CTRL2;
400 else
401 reg += OMAP1610_GPIO_EDGE_CTRL1;
402 return (__raw_readl(reg) >> ((gpio & 0x07) << 1)) & 0x03;
403 case METHOD_GPIO_730:
404 l = __raw_readl(reg + OMAP730_GPIO_INT_CONTROL);
405 return (l & (1 << gpio)) ?
406 OMAP_GPIO_RISING_EDGE : OMAP_GPIO_FALLING_EDGE;
407 default:
408 BUG();
409 return -1;
410 }
411}
412
413static void _clear_gpio_irqbank(struct gpio_bank *bank, int gpio_mask)
414{
415 u32 reg = bank->base;
416
417 switch (bank->method) {
418 case METHOD_MPUIO:
419 /* MPUIO irqstatus is reset by reading the status register,
420 * so do nothing here */
421 return;
422 case METHOD_GPIO_1510:
423 reg += OMAP1510_GPIO_INT_STATUS;
424 break;
425 case METHOD_GPIO_1610:
426 reg += OMAP1610_GPIO_IRQSTATUS1;
427 break;
428 case METHOD_GPIO_730:
429 reg += OMAP730_GPIO_INT_STATUS;
430 break;
431 default:
432 BUG();
433 return;
434 }
435 __raw_writel(gpio_mask, reg);
436}
437
438static inline void _clear_gpio_irqstatus(struct gpio_bank *bank, int gpio)
439{
440 _clear_gpio_irqbank(bank, 1 << get_gpio_index(gpio));
441}
442
443static void _enable_gpio_irqbank(struct gpio_bank *bank, int gpio_mask, int enable)
444{
445 u32 reg = bank->base;
446 u32 l;
447
448 switch (bank->method) {
449 case METHOD_MPUIO:
450 reg += OMAP_MPUIO_GPIO_MASKIT;
451 l = __raw_readl(reg);
452 if (enable)
453 l &= ~(gpio_mask);
454 else
455 l |= gpio_mask;
456 break;
457 case METHOD_GPIO_1510:
458 reg += OMAP1510_GPIO_INT_MASK;
459 l = __raw_readl(reg);
460 if (enable)
461 l &= ~(gpio_mask);
462 else
463 l |= gpio_mask;
464 break;
465 case METHOD_GPIO_1610:
466 if (enable)
467 reg += OMAP1610_GPIO_SET_IRQENABLE1;
468 else
469 reg += OMAP1610_GPIO_CLEAR_IRQENABLE1;
470 l = gpio_mask;
471 break;
472 case METHOD_GPIO_730:
473 reg += OMAP730_GPIO_INT_MASK;
474 l = __raw_readl(reg);
475 if (enable)
476 l &= ~(gpio_mask);
477 else
478 l |= gpio_mask;
479 break;
480 default:
481 BUG();
482 return;
483 }
484 __raw_writel(l, reg);
485}
486
487static inline void _set_gpio_irqenable(struct gpio_bank *bank, int gpio, int enable)
488{
489 _enable_gpio_irqbank(bank, 1 << get_gpio_index(gpio), enable);
490}
491
492int omap_request_gpio(int gpio)
493{
494 struct gpio_bank *bank;
495
496 if (check_gpio(gpio) < 0)
497 return -EINVAL;
498
499 bank = get_gpio_bank(gpio);
500 spin_lock(&bank->lock);
501 if (unlikely(bank->reserved_map & (1 << get_gpio_index(gpio)))) {
502 printk(KERN_ERR "omap-gpio: GPIO %d is already reserved!\n", gpio);
503 dump_stack();
504 spin_unlock(&bank->lock);
505 return -1;
506 }
507 bank->reserved_map |= (1 << get_gpio_index(gpio));
508#ifdef CONFIG_ARCH_OMAP1510
509 if (bank->method == METHOD_GPIO_1510) {
510 u32 reg;
511
512 /* Claim the pin for the ARM */
513 reg = bank->base + OMAP1510_GPIO_PIN_CONTROL;
514 __raw_writel(__raw_readl(reg) | (1 << get_gpio_index(gpio)), reg);
515 }
516#endif
517 spin_unlock(&bank->lock);
518
519 return 0;
520}
521
522void omap_free_gpio(int gpio)
523{
524 struct gpio_bank *bank;
525
526 if (check_gpio(gpio) < 0)
527 return;
528 bank = get_gpio_bank(gpio);
529 spin_lock(&bank->lock);
530 if (unlikely(!(bank->reserved_map & (1 << get_gpio_index(gpio))))) {
531 printk(KERN_ERR "omap-gpio: GPIO %d wasn't reserved!\n", gpio);
532 dump_stack();
533 spin_unlock(&bank->lock);
534 return;
535 }
536 bank->reserved_map &= ~(1 << get_gpio_index(gpio));
537 _set_gpio_direction(bank, get_gpio_index(gpio), 1);
538 _set_gpio_irqenable(bank, gpio, 0);
539 _clear_gpio_irqstatus(bank, gpio);
540 spin_unlock(&bank->lock);
541}
542
543/*
544 * We need to unmask the GPIO bank interrupt as soon as possible to
545 * avoid missing GPIO interrupts for other lines in the bank.
546 * Then we need to mask-read-clear-unmask the triggered GPIO lines
547 * in the bank to avoid missing nested interrupts for a GPIO line.
548 * If we wait to unmask individual GPIO lines in the bank after the
549 * line's interrupt handler has been run, we may miss some nested
550 * interrupts.
551 */
552static void gpio_irq_handler(unsigned int irq, struct irqdesc *desc,
553 struct pt_regs *regs)
554{
555 u32 isr_reg = 0;
556 u32 isr;
557 unsigned int gpio_irq;
558 struct gpio_bank *bank;
559
560 desc->chip->ack(irq);
561
562 bank = (struct gpio_bank *) desc->data;
563 if (bank->method == METHOD_MPUIO)
564 isr_reg = bank->base + OMAP_MPUIO_GPIO_INT;
565#ifdef CONFIG_ARCH_OMAP1510
566 if (bank->method == METHOD_GPIO_1510)
567 isr_reg = bank->base + OMAP1510_GPIO_INT_STATUS;
568#endif
569#if defined(CONFIG_ARCH_OMAP16XX)
570 if (bank->method == METHOD_GPIO_1610)
571 isr_reg = bank->base + OMAP1610_GPIO_IRQSTATUS1;
572#endif
573#ifdef CONFIG_ARCH_OMAP730
574 if (bank->method == METHOD_GPIO_730)
575 isr_reg = bank->base + OMAP730_GPIO_INT_STATUS;
576#endif
577
578 isr = __raw_readl(isr_reg);
579 _enable_gpio_irqbank(bank, isr, 0);
580 _clear_gpio_irqbank(bank, isr);
581 _enable_gpio_irqbank(bank, isr, 1);
582 desc->chip->unmask(irq);
583
584 if (unlikely(!isr))
585 return;
586
587 gpio_irq = bank->virtual_irq_start;
588 for (; isr != 0; isr >>= 1, gpio_irq++) {
589 struct irqdesc *d;
590 if (!(isr & 1))
591 continue;
592 d = irq_desc + gpio_irq;
593 d->handle(gpio_irq, d, regs);
594 }
595}
596
597static void gpio_ack_irq(unsigned int irq)
598{
599 unsigned int gpio = irq - IH_GPIO_BASE;
600 struct gpio_bank *bank = get_gpio_bank(gpio);
601
602 _clear_gpio_irqstatus(bank, gpio);
603}
604
605static void gpio_mask_irq(unsigned int irq)
606{
607 unsigned int gpio = irq - IH_GPIO_BASE;
608 struct gpio_bank *bank = get_gpio_bank(gpio);
609
610 _set_gpio_irqenable(bank, gpio, 0);
611}
612
613static void gpio_unmask_irq(unsigned int irq)
614{
615 unsigned int gpio = irq - IH_GPIO_BASE;
616 struct gpio_bank *bank = get_gpio_bank(gpio);
617
618 if (_get_gpio_edge_ctrl(bank, get_gpio_index(gpio)) == OMAP_GPIO_NO_EDGE) {
619 printk(KERN_ERR "OMAP GPIO %d: trying to enable GPIO IRQ while no edge is set\n",
620 gpio);
621 _set_gpio_edge_ctrl(bank, get_gpio_index(gpio), OMAP_GPIO_RISING_EDGE);
622 }
623 _set_gpio_irqenable(bank, gpio, 1);
624}
625
626static void mpuio_ack_irq(unsigned int irq)
627{
628 /* The ISR is reset automatically, so do nothing here. */
629}
630
631static void mpuio_mask_irq(unsigned int irq)
632{
633 unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
634 struct gpio_bank *bank = get_gpio_bank(gpio);
635
636 _set_gpio_irqenable(bank, gpio, 0);
637}
638
639static void mpuio_unmask_irq(unsigned int irq)
640{
641 unsigned int gpio = OMAP_MPUIO(irq - IH_MPUIO_BASE);
642 struct gpio_bank *bank = get_gpio_bank(gpio);
643
644 _set_gpio_irqenable(bank, gpio, 1);
645}
646
647static struct irqchip gpio_irq_chip = {
648 .ack = gpio_ack_irq,
649 .mask = gpio_mask_irq,
650 .unmask = gpio_unmask_irq,
651};
652
653static struct irqchip mpuio_irq_chip = {
654 .ack = mpuio_ack_irq,
655 .mask = mpuio_mask_irq,
656 .unmask = mpuio_unmask_irq
657};
658
659static int initialized = 0;
660
661static int __init _omap_gpio_init(void)
662{
663 int i;
664 struct gpio_bank *bank;
665
666 initialized = 1;
667
668#ifdef CONFIG_ARCH_OMAP1510
669 if (cpu_is_omap1510()) {
670 printk(KERN_INFO "OMAP1510 GPIO hardware\n");
671 gpio_bank_count = 2;
672 gpio_bank = gpio_bank_1510;
673 }
674#endif
675#if defined(CONFIG_ARCH_OMAP16XX)
676 if (cpu_is_omap16xx()) {
677 int rev;
678
679 gpio_bank_count = 5;
680 gpio_bank = gpio_bank_1610;
681 rev = omap_readw(gpio_bank[1].base + OMAP1610_GPIO_REVISION);
682 printk(KERN_INFO "OMAP GPIO hardware version %d.%d\n",
683 (rev >> 4) & 0x0f, rev & 0x0f);
684 }
685#endif
686#ifdef CONFIG_ARCH_OMAP730
687 if (cpu_is_omap730()) {
688 printk(KERN_INFO "OMAP730 GPIO hardware\n");
689 gpio_bank_count = 7;
690 gpio_bank = gpio_bank_730;
691 }
692#endif
693 for (i = 0; i < gpio_bank_count; i++) {
694 int j, gpio_count = 16;
695
696 bank = &gpio_bank[i];
697 bank->reserved_map = 0;
698 bank->base = IO_ADDRESS(bank->base);
699 spin_lock_init(&bank->lock);
700 if (bank->method == METHOD_MPUIO) {
701 omap_writew(0xFFFF, OMAP_MPUIO_BASE + OMAP_MPUIO_GPIO_MASKIT);
702 }
703#ifdef CONFIG_ARCH_OMAP1510
704 if (bank->method == METHOD_GPIO_1510) {
705 __raw_writew(0xffff, bank->base + OMAP1510_GPIO_INT_MASK);
706 __raw_writew(0x0000, bank->base + OMAP1510_GPIO_INT_STATUS);
707 }
708#endif
709#if defined(CONFIG_ARCH_OMAP16XX)
710 if (bank->method == METHOD_GPIO_1610) {
711 __raw_writew(0x0000, bank->base + OMAP1610_GPIO_IRQENABLE1);
712 __raw_writew(0xffff, bank->base + OMAP1610_GPIO_IRQSTATUS1);
713 }
714#endif
715#ifdef CONFIG_ARCH_OMAP730
716 if (bank->method == METHOD_GPIO_730) {
717 __raw_writel(0xffffffff, bank->base + OMAP730_GPIO_INT_MASK);
718 __raw_writel(0x00000000, bank->base + OMAP730_GPIO_INT_STATUS);
719
720 gpio_count = 32; /* 730 has 32-bit GPIOs */
721 }
722#endif
723 for (j = bank->virtual_irq_start;
724 j < bank->virtual_irq_start + gpio_count; j++) {
725 if (bank->method == METHOD_MPUIO)
726 set_irq_chip(j, &mpuio_irq_chip);
727 else
728 set_irq_chip(j, &gpio_irq_chip);
729 set_irq_handler(j, do_simple_IRQ);
730 set_irq_flags(j, IRQF_VALID);
731 }
732 set_irq_chained_handler(bank->irq, gpio_irq_handler);
733 set_irq_data(bank->irq, bank);
734 }
735
736 /* Enable system clock for GPIO module.
737 * The CAM_CLK_CTRL *is* really the right place. */
738 if (cpu_is_omap1610() || cpu_is_omap1710())
739 omap_writel(omap_readl(ULPD_CAM_CLK_CTRL) | 0x04, ULPD_CAM_CLK_CTRL);
740
741 return 0;
742}
743
744/*
745 * This may get called early from board specific init
746 */
747int omap_gpio_init(void)
748{
749 if (!initialized)
750 return _omap_gpio_init();
751 else
752 return 0;
753}
754
755EXPORT_SYMBOL(omap_request_gpio);
756EXPORT_SYMBOL(omap_free_gpio);
757EXPORT_SYMBOL(omap_set_gpio_direction);
758EXPORT_SYMBOL(omap_set_gpio_dataout);
759EXPORT_SYMBOL(omap_get_gpio_datain);
760EXPORT_SYMBOL(omap_set_gpio_edge_ctrl);
761
762arch_initcall(omap_gpio_init);
diff --git a/arch/arm/plat-omap/mcbsp.c b/arch/arm/plat-omap/mcbsp.c
new file mode 100644
index 000000000000..10c3f22f9c6a
--- /dev/null
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -0,0 +1,685 @@
1/*
2 * linux/arch/arm/plat-omap/mcbsp.c
3 *
4 * Copyright (C) 2004 Nokia Corporation
5 * Author: Samuel Ortiz <samuel.ortiz@nokia.com>
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * Multichannel mode not supported.
13 */
14
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/device.h>
18#include <linux/wait.h>
19#include <linux/completion.h>
20#include <linux/interrupt.h>
21#include <linux/err.h>
22
23#include <asm/delay.h>
24#include <asm/io.h>
25#include <asm/irq.h>
26
27#include <asm/arch/dma.h>
28#include <asm/arch/mux.h>
29#include <asm/arch/irqs.h>
30#include <asm/arch/mcbsp.h>
31
32#include <asm/hardware/clock.h>
33
34#ifdef CONFIG_MCBSP_DEBUG
35#define DBG(x...) printk(x)
36#else
37#define DBG(x...) do { } while (0)
38#endif
39
40struct omap_mcbsp {
41 u32 io_base;
42 u8 id;
43 u8 free;
44 omap_mcbsp_word_length rx_word_length;
45 omap_mcbsp_word_length tx_word_length;
46
47 /* IRQ based TX/RX */
48 int rx_irq;
49 int tx_irq;
50
51 /* DMA stuff */
52 u8 dma_rx_sync;
53 short dma_rx_lch;
54 u8 dma_tx_sync;
55 short dma_tx_lch;
56
57 /* Completion queues */
58 struct completion tx_irq_completion;
59 struct completion rx_irq_completion;
60 struct completion tx_dma_completion;
61 struct completion rx_dma_completion;
62
63 spinlock_t lock;
64};
65
66static struct omap_mcbsp mcbsp[OMAP_MAX_MCBSP_COUNT];
67static struct clk *mcbsp_dsp_ck = 0;
68static struct clk *mcbsp_api_ck = 0;
69
70
71static void omap_mcbsp_dump_reg(u8 id)
72{
73 DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
74 DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
75 DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
76 DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
77 DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
78 DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
79 DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
80 DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
81 DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
82 DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
83 DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
84 DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
85 DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
86 DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
87 DBG("***********************\n");
88}
89
90
91static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
92{
93 struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
94
95 DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
96
97 complete(&mcbsp_tx->tx_irq_completion);
98 return IRQ_HANDLED;
99}
100
101static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
102{
103 struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
104
105 DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
106
107 complete(&mcbsp_rx->rx_irq_completion);
108 return IRQ_HANDLED;
109}
110
111
112static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
113{
114 struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
115
116 DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
117
118 /* We can free the channels */
119 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
120 mcbsp_dma_tx->dma_tx_lch = -1;
121
122 complete(&mcbsp_dma_tx->tx_dma_completion);
123}
124
125static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
126{
127 struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
128
129 DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
130
131 /* We can free the channels */
132 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
133 mcbsp_dma_rx->dma_rx_lch = -1;
134
135 complete(&mcbsp_dma_rx->rx_dma_completion);
136}
137
138
139/*
140 * omap_mcbsp_config simply write a config to the
141 * appropriate McBSP.
142 * You either call this function or set the McBSP registers
143 * by yourself before calling omap_mcbsp_start().
144 */
145
146void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
147{
148 u32 io_base = mcbsp[id].io_base;
149
150 DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base);
151
152 /* We write the given config */
153 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
154 OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
155 OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
156 OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
157 OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
158 OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
159 OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
160 OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
161 OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
162 OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
163 OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
164}
165
166
167
168static int omap_mcbsp_check(unsigned int id)
169{
170 if (cpu_is_omap730()) {
171 if (id > OMAP_MAX_MCBSP_COUNT - 1) {
172 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
173 return -1;
174 }
175 return 0;
176 }
177
178 if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
179 if (id > OMAP_MAX_MCBSP_COUNT) {
180 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
181 return -1;
182 }
183 return 0;
184 }
185
186 return -1;
187}
188
189#define EN_XORPCK 1
190#define DSP_RSTCT2 0xe1008014
191
192static void omap_mcbsp_dsp_request(void)
193{
194 if (cpu_is_omap1510() || cpu_is_omap1610() || cpu_is_omap1710()) {
195 omap_writew((omap_readw(ARM_RSTCT1) | (1 << 1) | (1 << 2)),
196 ARM_RSTCT1);
197 clk_enable(mcbsp_dsp_ck);
198 clk_enable(mcbsp_api_ck);
199
200 /* enable 12MHz clock to mcbsp 1 & 3 */
201 __raw_writew(__raw_readw(DSP_IDLECT2) | (1 << EN_XORPCK),
202 DSP_IDLECT2);
203 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
204 DSP_RSTCT2);
205 }
206}
207
208static void omap_mcbsp_dsp_free(void)
209{
210 /* Useless for now */
211}
212
213
214int omap_mcbsp_request(unsigned int id)
215{
216 int err;
217
218 if (omap_mcbsp_check(id) < 0)
219 return -EINVAL;
220
221 /*
222 * On 1510, 1610 and 1710, McBSP1 and McBSP3
223 * are DSP public peripherals.
224 */
225 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
226 omap_mcbsp_dsp_request();
227
228 spin_lock(&mcbsp[id].lock);
229 if (!mcbsp[id].free) {
230 printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
231 spin_unlock(&mcbsp[id].lock);
232 return -1;
233 }
234
235 mcbsp[id].free = 0;
236 spin_unlock(&mcbsp[id].lock);
237
238 /* We need to get IRQs here */
239 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
240 "McBSP",
241 (void *) (&mcbsp[id]));
242 if (err != 0) {
243 printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
244 mcbsp[id].tx_irq, mcbsp[id].id);
245 return err;
246 }
247
248 init_completion(&(mcbsp[id].tx_irq_completion));
249
250
251 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
252 "McBSP",
253 (void *) (&mcbsp[id]));
254 if (err != 0) {
255 printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
256 mcbsp[id].rx_irq, mcbsp[id].id);
257 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
258 return err;
259 }
260
261 init_completion(&(mcbsp[id].rx_irq_completion));
262 return 0;
263
264}
265
266void omap_mcbsp_free(unsigned int id)
267{
268 if (omap_mcbsp_check(id) < 0)
269 return;
270
271 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
272 omap_mcbsp_dsp_free();
273
274 spin_lock(&mcbsp[id].lock);
275 if (mcbsp[id].free) {
276 printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
277 spin_unlock(&mcbsp[id].lock);
278 return;
279 }
280
281 mcbsp[id].free = 1;
282 spin_unlock(&mcbsp[id].lock);
283
284 /* Free IRQs */
285 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
286 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
287}
288
289/*
290 * Here we start the McBSP, by enabling the sample
291 * generator, both transmitter and receivers,
292 * and the frame sync.
293 */
294void omap_mcbsp_start(unsigned int id)
295{
296 u32 io_base;
297 u16 w;
298
299 if (omap_mcbsp_check(id) < 0)
300 return;
301
302 io_base = mcbsp[id].io_base;
303
304 mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
305 mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
306
307 /* Start the sample generator */
308 w = OMAP_MCBSP_READ(io_base, SPCR2);
309 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
310
311 /* Enable transmitter and receiver */
312 w = OMAP_MCBSP_READ(io_base, SPCR2);
313 OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
314
315 w = OMAP_MCBSP_READ(io_base, SPCR1);
316 OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
317
318 udelay(100);
319
320 /* Start frame sync */
321 w = OMAP_MCBSP_READ(io_base, SPCR2);
322 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
323
324 /* Dump McBSP Regs */
325 omap_mcbsp_dump_reg(id);
326
327}
328
329void omap_mcbsp_stop(unsigned int id)
330{
331 u32 io_base;
332 u16 w;
333
334 if (omap_mcbsp_check(id) < 0)
335 return;
336
337 io_base = mcbsp[id].io_base;
338
339 /* Reset transmitter */
340 w = OMAP_MCBSP_READ(io_base, SPCR2);
341 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
342
343 /* Reset receiver */
344 w = OMAP_MCBSP_READ(io_base, SPCR1);
345 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
346
347 /* Reset the sample rate generator */
348 w = OMAP_MCBSP_READ(io_base, SPCR2);
349 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
350}
351
352
353/*
354 * IRQ based word transmission.
355 */
356void omap_mcbsp_xmit_word(unsigned int id, u32 word)
357{
358 u32 io_base;
359 omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
360
361 if (omap_mcbsp_check(id) < 0)
362 return;
363
364 io_base = mcbsp[id].io_base;
365
366 wait_for_completion(&(mcbsp[id].tx_irq_completion));
367
368 if (word_length > OMAP_MCBSP_WORD_16)
369 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
370 OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
371}
372
373u32 omap_mcbsp_recv_word(unsigned int id)
374{
375 u32 io_base;
376 u16 word_lsb, word_msb = 0;
377 omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
378
379 if (omap_mcbsp_check(id) < 0)
380 return -EINVAL;
381
382 io_base = mcbsp[id].io_base;
383
384 wait_for_completion(&(mcbsp[id].rx_irq_completion));
385
386 if (word_length > OMAP_MCBSP_WORD_16)
387 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
388 word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
389
390 return (word_lsb | (word_msb << 16));
391}
392
393
394/*
395 * Simple DMA based buffer rx/tx routines.
396 * Nothing fancy, just a single buffer tx/rx through DMA.
397 * The DMA resources are released once the transfer is done.
398 * For anything fancier, you should use your own customized DMA
399 * routines and callbacks.
400 */
401int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
402{
403 int dma_tx_ch;
404
405 if (omap_mcbsp_check(id) < 0)
406 return -EINVAL;
407
408 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
409 &mcbsp[id],
410 &dma_tx_ch)) {
411 printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
412 return -EAGAIN;
413 }
414 mcbsp[id].dma_tx_lch = dma_tx_ch;
415
416 DBG("TX DMA on channel %d\n", dma_tx_ch);
417
418 init_completion(&(mcbsp[id].tx_dma_completion));
419
420 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
421 OMAP_DMA_DATA_TYPE_S16,
422 length >> 1, 1,
423 OMAP_DMA_SYNC_ELEMENT);
424
425 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
426 OMAP_DMA_PORT_TIPB,
427 OMAP_DMA_AMODE_CONSTANT,
428 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
429
430 omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
431 OMAP_DMA_PORT_EMIFF,
432 OMAP_DMA_AMODE_POST_INC,
433 buffer);
434
435 omap_start_dma(mcbsp[id].dma_tx_lch);
436 wait_for_completion(&(mcbsp[id].tx_dma_completion));
437 return 0;
438}
439
440
441int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
442{
443 int dma_rx_ch;
444
445 if (omap_mcbsp_check(id) < 0)
446 return -EINVAL;
447
448 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
449 &mcbsp[id],
450 &dma_rx_ch)) {
451 printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
452 return -EAGAIN;
453 }
454 mcbsp[id].dma_rx_lch = dma_rx_ch;
455
456 DBG("RX DMA on channel %d\n", dma_rx_ch);
457
458 init_completion(&(mcbsp[id].rx_dma_completion));
459
460 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
461 OMAP_DMA_DATA_TYPE_S16,
462 length >> 1, 1,
463 OMAP_DMA_SYNC_ELEMENT);
464
465 omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
466 OMAP_DMA_PORT_TIPB,
467 OMAP_DMA_AMODE_CONSTANT,
468 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
469
470 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
471 OMAP_DMA_PORT_EMIFF,
472 OMAP_DMA_AMODE_POST_INC,
473 buffer);
474
475 omap_start_dma(mcbsp[id].dma_rx_lch);
476 wait_for_completion(&(mcbsp[id].rx_dma_completion));
477 return 0;
478}
479
480
481/*
482 * SPI wrapper.
483 * Since SPI setup is much simpler than the generic McBSP one,
484 * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
485 * Once this is done, you can call omap_mcbsp_start().
486 */
487void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
488{
489 struct omap_mcbsp_reg_cfg mcbsp_cfg;
490
491 if (omap_mcbsp_check(id) < 0)
492 return;
493
494 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
495
496 /* SPI has only one frame */
497 mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
498 mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
499
500 /* Clock stop mode */
501 if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
502 mcbsp_cfg.spcr1 |= (1 << 12);
503 else
504 mcbsp_cfg.spcr1 |= (3 << 11);
505
506 /* Set clock parities */
507 if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
508 mcbsp_cfg.pcr0 |= CLKRP;
509 else
510 mcbsp_cfg.pcr0 &= ~CLKRP;
511
512 if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
513 mcbsp_cfg.pcr0 &= ~CLKXP;
514 else
515 mcbsp_cfg.pcr0 |= CLKXP;
516
517 /* Set SCLKME to 0 and CLKSM to 1 */
518 mcbsp_cfg.pcr0 &= ~SCLKME;
519 mcbsp_cfg.srgr2 |= CLKSM;
520
521 /* Set FSXP */
522 if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
523 mcbsp_cfg.pcr0 &= ~FSXP;
524 else
525 mcbsp_cfg.pcr0 |= FSXP;
526
527 if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
528 mcbsp_cfg.pcr0 |= CLKXM;
529 mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
530 mcbsp_cfg.pcr0 |= FSXM;
531 mcbsp_cfg.srgr2 &= ~FSGM;
532 mcbsp_cfg.xcr2 |= XDATDLY(1);
533 mcbsp_cfg.rcr2 |= RDATDLY(1);
534 }
535 else {
536 mcbsp_cfg.pcr0 &= ~CLKXM;
537 mcbsp_cfg.srgr1 |= CLKGDV(1);
538 mcbsp_cfg.pcr0 &= ~FSXM;
539 mcbsp_cfg.xcr2 &= ~XDATDLY(3);
540 mcbsp_cfg.rcr2 &= ~RDATDLY(3);
541 }
542
543 mcbsp_cfg.xcr2 &= ~XPHASE;
544 mcbsp_cfg.rcr2 &= ~RPHASE;
545
546 omap_mcbsp_config(id, &mcbsp_cfg);
547}
548
549
550/*
551 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
552 * 730 has only 2 McBSP, and both of them are MPU peripherals.
553 */
554struct omap_mcbsp_info {
555 u32 virt_base;
556 u8 dma_rx_sync, dma_tx_sync;
557 u16 rx_irq, tx_irq;
558};
559
560#ifdef CONFIG_ARCH_OMAP730
561static const struct omap_mcbsp_info mcbsp_730[] = {
562 [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
563 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
564 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
565 .rx_irq = INT_730_McBSP1RX,
566 .tx_irq = INT_730_McBSP1TX },
567 [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
568 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
569 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
570 .rx_irq = INT_730_McBSP2RX,
571 .tx_irq = INT_730_McBSP2TX },
572};
573#endif
574
575#ifdef CONFIG_ARCH_OMAP1510
576static const struct omap_mcbsp_info mcbsp_1510[] = {
577 [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
578 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
579 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
580 .rx_irq = INT_McBSP1RX,
581 .tx_irq = INT_McBSP1TX },
582 [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
583 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
584 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
585 .rx_irq = INT_1510_SPI_RX,
586 .tx_irq = INT_1510_SPI_TX },
587 [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
588 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
589 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
590 .rx_irq = INT_McBSP3RX,
591 .tx_irq = INT_McBSP3TX },
592};
593#endif
594
595#if defined(CONFIG_ARCH_OMAP16XX)
596static const struct omap_mcbsp_info mcbsp_1610[] = {
597 [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
598 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
599 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
600 .rx_irq = INT_McBSP1RX,
601 .tx_irq = INT_McBSP1TX },
602 [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
603 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
604 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
605 .rx_irq = INT_1610_McBSP2_RX,
606 .tx_irq = INT_1610_McBSP2_TX },
607 [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
608 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
609 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
610 .rx_irq = INT_McBSP3RX,
611 .tx_irq = INT_McBSP3TX },
612};
613#endif
614
615static int __init omap_mcbsp_init(void)
616{
617 int mcbsp_count = 0, i;
618 static const struct omap_mcbsp_info *mcbsp_info;
619
620 printk("Initializing OMAP McBSP system\n");
621
622 mcbsp_dsp_ck = clk_get(0, "dsp_ck");
623 if (IS_ERR(mcbsp_dsp_ck)) {
624 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
625 return PTR_ERR(mcbsp_dsp_ck);
626 }
627 mcbsp_api_ck = clk_get(0, "api_ck");
628 if (IS_ERR(mcbsp_dsp_ck)) {
629 printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
630 return PTR_ERR(mcbsp_api_ck);
631 }
632
633#ifdef CONFIG_ARCH_OMAP730
634 if (cpu_is_omap730()) {
635 mcbsp_info = mcbsp_730;
636 mcbsp_count = ARRAY_SIZE(mcbsp_730);
637 }
638#endif
639#ifdef CONFIG_ARCH_OMAP1510
640 if (cpu_is_omap1510()) {
641 mcbsp_info = mcbsp_1510;
642 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
643 }
644#endif
645#if defined(CONFIG_ARCH_OMAP16XX)
646 if (cpu_is_omap1610() || cpu_is_omap1710()) {
647 mcbsp_info = mcbsp_1610;
648 mcbsp_count = ARRAY_SIZE(mcbsp_1610);
649 }
650#endif
651 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
652 if (i >= mcbsp_count) {
653 mcbsp[i].io_base = 0;
654 mcbsp[i].free = 0;
655 continue;
656 }
657 mcbsp[i].id = i + 1;
658 mcbsp[i].free = 1;
659 mcbsp[i].dma_tx_lch = -1;
660 mcbsp[i].dma_rx_lch = -1;
661
662 mcbsp[i].io_base = mcbsp_info[i].virt_base;
663 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
664 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
665 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
666 mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
667 spin_lock_init(&mcbsp[i].lock);
668 }
669
670 return 0;
671}
672
673
674arch_initcall(omap_mcbsp_init);
675
676EXPORT_SYMBOL(omap_mcbsp_config);
677EXPORT_SYMBOL(omap_mcbsp_request);
678EXPORT_SYMBOL(omap_mcbsp_free);
679EXPORT_SYMBOL(omap_mcbsp_start);
680EXPORT_SYMBOL(omap_mcbsp_stop);
681EXPORT_SYMBOL(omap_mcbsp_xmit_word);
682EXPORT_SYMBOL(omap_mcbsp_recv_word);
683EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
684EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
685EXPORT_SYMBOL(omap_mcbsp_set_spi_mode);
diff --git a/arch/arm/plat-omap/mux.c b/arch/arm/plat-omap/mux.c
new file mode 100644
index 000000000000..cbecd10d0b6c
--- /dev/null
+++ b/arch/arm/plat-omap/mux.c
@@ -0,0 +1,163 @@
1/*
2 * linux/arch/arm/plat-omap/mux.c
3 *
4 * Utility to set the Omap MUX and PULL_DWN registers from a table in mux.h
5 *
6 * Copyright (C) 2003 Nokia Corporation
7 *
8 * Written by Tony Lindgren <tony.lindgren@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25#include <linux/config.h>
26#include <linux/module.h>
27#include <linux/init.h>
28#include <asm/system.h>
29#include <asm/io.h>
30#include <linux/spinlock.h>
31
32#define __MUX_C__
33#include <asm/arch/mux.h>
34
35#ifdef CONFIG_OMAP_MUX
36
37/*
38 * Sets the Omap MUX and PULL_DWN registers based on the table
39 */
40int __init_or_module
41omap_cfg_reg(const reg_cfg_t reg_cfg)
42{
43 static DEFINE_SPINLOCK(mux_spin_lock);
44
45 unsigned long flags;
46 reg_cfg_set *cfg;
47 unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0,
48 pull_orig = 0, pull = 0;
49 unsigned int mask, warn = 0;
50
51 if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) {
52 printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg);
53 return -EINVAL;
54 }
55
56 cfg = &reg_cfg_table[reg_cfg];
57
58 /*
59 * We do a pretty long section here with lock on, but pin muxing
60 * should only happen on driver init for each driver, so it's not time
61 * critical.
62 */
63 spin_lock_irqsave(&mux_spin_lock, flags);
64
65 /* Check the mux register in question */
66 if (cfg->mux_reg) {
67 unsigned tmp1, tmp2;
68
69 reg_orig = omap_readl(cfg->mux_reg);
70
71 /* The mux registers always seem to be 3 bits long */
72 mask = (0x7 << cfg->mask_offset);
73 tmp1 = reg_orig & mask;
74 reg = reg_orig & ~mask;
75
76 tmp2 = (cfg->mask << cfg->mask_offset);
77 reg |= tmp2;
78
79 if (tmp1 != tmp2)
80 warn = 1;
81
82 omap_writel(reg, cfg->mux_reg);
83 }
84
85 /* Check for pull up or pull down selection on 1610 */
86 if (!cpu_is_omap1510()) {
87 if (cfg->pu_pd_reg && cfg->pull_val) {
88 pu_pd_orig = omap_readl(cfg->pu_pd_reg);
89 mask = 1 << cfg->pull_bit;
90
91 if (cfg->pu_pd_val) {
92 if (!(pu_pd_orig & mask))
93 warn = 1;
94 /* Use pull up */
95 pu_pd = pu_pd_orig | mask;
96 } else {
97 if (pu_pd_orig & mask)
98 warn = 1;
99 /* Use pull down */
100 pu_pd = pu_pd_orig & ~mask;
101 }
102 omap_writel(pu_pd, cfg->pu_pd_reg);
103 }
104 }
105
106 /* Check for an associated pull down register */
107 if (cfg->pull_reg) {
108 pull_orig = omap_readl(cfg->pull_reg);
109 mask = 1 << cfg->pull_bit;
110
111 if (cfg->pull_val) {
112 if (pull_orig & mask)
113 warn = 1;
114 /* Low bit = pull enabled */
115 pull = pull_orig & ~mask;
116 } else {
117 if (!(pull_orig & mask))
118 warn = 1;
119 /* High bit = pull disabled */
120 pull = pull_orig | mask;
121 }
122
123 omap_writel(pull, cfg->pull_reg);
124 }
125
126 if (warn) {
127#ifdef CONFIG_OMAP_MUX_WARNINGS
128 printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
129#endif
130 }
131
132#ifdef CONFIG_OMAP_MUX_DEBUG
133 if (cfg->debug || warn) {
134 printk("MUX: Setting register %s\n", cfg->name);
135 printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
136 cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
137
138 if (!cpu_is_omap1510()) {
139 if (cfg->pu_pd_reg && cfg->pull_val) {
140 printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
141 cfg->pu_pd_name, cfg->pu_pd_reg,
142 pu_pd_orig, pu_pd);
143 }
144 }
145
146 if (cfg->pull_reg)
147 printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
148 cfg->pull_name, cfg->pull_reg, pull_orig, pull);
149 }
150#endif
151
152 spin_unlock_irqrestore(&mux_spin_lock, flags);
153
154#ifdef CONFIG_OMAP_MUX_ERRORS
155 return warn ? -ETXTBSY : 0;
156#else
157 return 0;
158#endif
159}
160
161EXPORT_SYMBOL(omap_cfg_reg);
162
163#endif /* CONFIG_OMAP_MUX */
diff --git a/arch/arm/plat-omap/ocpi.c b/arch/arm/plat-omap/ocpi.c
new file mode 100644
index 000000000000..1fb16f9edfd5
--- /dev/null
+++ b/arch/arm/plat-omap/ocpi.c
@@ -0,0 +1,114 @@
1/*
2 * linux/arch/arm/plat-omap/ocpi.c
3 *
4 * Minimal OCP bus support for omap16xx
5 *
6 * Copyright (C) 2003 - 2005 Nokia Corporation
7 * Written by Tony Lindgren <tony@atomide.com>
8 *
9 * Modified for clock framework by Paul Mundt <paul.mundt@nokia.com>.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 */
25
26#include <linux/config.h>
27#include <linux/module.h>
28#include <linux/version.h>
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
32#include <linux/init.h>
33#include <linux/spinlock.h>
34#include <linux/err.h>
35
36#include <asm/io.h>
37#include <asm/hardware/clock.h>
38#include <asm/arch/hardware.h>
39
40#define OCPI_BASE 0xfffec320
41#define OCPI_FAULT (OCPI_BASE + 0x00)
42#define OCPI_CMD_FAULT (OCPI_BASE + 0x04)
43#define OCPI_SINT0 (OCPI_BASE + 0x08)
44#define OCPI_TABORT (OCPI_BASE + 0x0c)
45#define OCPI_SINT1 (OCPI_BASE + 0x10)
46#define OCPI_PROT (OCPI_BASE + 0x14)
47#define OCPI_SEC (OCPI_BASE + 0x18)
48
49/* USB OHCI OCPI access error registers */
50#define HOSTUEADDR 0xfffba0e0
51#define HOSTUESTATUS 0xfffba0e4
52
53static struct clk *ocpi_ck;
54
55/*
56 * Enables device access to OMAP buses via the OCPI bridge
57 * FIXME: Add locking
58 */
59int ocpi_enable(void)
60{
61 unsigned int val;
62
63 if (!cpu_is_omap16xx())
64 return -ENODEV;
65
66 /* Make sure there's clock for OCPI */
67 clk_enable(ocpi_ck);
68
69 /* Enable access for OHCI in OCPI */
70 val = omap_readl(OCPI_PROT);
71 val &= ~0xff;
72 //val &= (1 << 0); /* Allow access only to EMIFS */
73 omap_writel(val, OCPI_PROT);
74
75 val = omap_readl(OCPI_SEC);
76 val &= ~0xff;
77 omap_writel(val, OCPI_SEC);
78
79 return 0;
80}
81EXPORT_SYMBOL(ocpi_enable);
82
83static int __init omap_ocpi_init(void)
84{
85 if (!cpu_is_omap16xx())
86 return -ENODEV;
87
88 ocpi_ck = clk_get(NULL, "l3_ocpi_ck");
89 if (IS_ERR(ocpi_ck))
90 return PTR_ERR(ocpi_ck);
91
92 clk_use(ocpi_ck);
93 ocpi_enable();
94 printk("OMAP OCPI interconnect driver loaded\n");
95
96 return 0;
97}
98
99static void __exit omap_ocpi_exit(void)
100{
101 /* REVISIT: Disable OCPI */
102
103 if (!cpu_is_omap16xx())
104 return;
105
106 clk_unuse(ocpi_ck);
107 clk_put(ocpi_ck);
108}
109
110MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>");
111MODULE_DESCRIPTION("OMAP OCPI bus controller module");
112MODULE_LICENSE("GPL");
113module_init(omap_ocpi_init);
114module_exit(omap_ocpi_exit);
diff --git a/arch/arm/plat-omap/pm.c b/arch/arm/plat-omap/pm.c
new file mode 100644
index 000000000000..e6536b16c385
--- /dev/null
+++ b/arch/arm/plat-omap/pm.c
@@ -0,0 +1,632 @@
1/*
2 * linux/arch/arm/plat-omap/pm.c
3 *
4 * OMAP Power Management Routines
5 *
6 * Original code for the SA11x0:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8 *
9 * Modified for the PXA250 by Nicolas Pitre:
10 * Copyright (c) 2002 Monta Vista Software, Inc.
11 *
12 * Modified for the OMAP1510 by David Singleton:
13 * Copyright (c) 2002 Monta Vista Software, Inc.
14 *
15 * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License as published by the
19 * Free Software Foundation; either version 2 of the License, or (at your
20 * option) any later version.
21 *
22 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
23 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
25 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
28 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
29 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * You should have received a copy of the GNU General Public License along
34 * with this program; if not, write to the Free Software Foundation, Inc.,
35 * 675 Mass Ave, Cambridge, MA 02139, USA.
36 */
37
38#include <linux/pm.h>
39#include <linux/sched.h>
40#include <linux/proc_fs.h>
41#include <linux/pm.h>
42
43#include <asm/io.h>
44#include <asm/mach/time.h>
45#include <asm/mach-types.h>
46
47#include <asm/arch/omap16xx.h>
48#include <asm/arch/pm.h>
49#include <asm/arch/mux.h>
50#include <asm/arch/tc.h>
51#include <asm/arch/tps65010.h>
52
53#include "clock.h"
54
55static unsigned int arm_sleep_save[ARM_SLEEP_SAVE_SIZE];
56static unsigned short ulpd_sleep_save[ULPD_SLEEP_SAVE_SIZE];
57static unsigned int mpui1510_sleep_save[MPUI1510_SLEEP_SAVE_SIZE];
58static unsigned int mpui1610_sleep_save[MPUI1610_SLEEP_SAVE_SIZE];
59
60/*
61 * Let's power down on idle, but only if we are really
62 * idle, because once we start down the path of
63 * going idle we continue to do idle even if we get
64 * a clock tick interrupt . .
65 */
66void omap_pm_idle(void)
67{
68 int (*func_ptr)(void) = 0;
69 unsigned int mask32 = 0;
70
71 /*
72 * If the DSP is being used let's just idle the CPU, the overhead
73 * to wake up from Big Sleep is big, milliseconds versus micro
74 * seconds for wait for interrupt.
75 */
76
77 local_irq_disable();
78 local_fiq_disable();
79 if (need_resched()) {
80 local_fiq_enable();
81 local_irq_enable();
82 return;
83 }
84 mask32 = omap_readl(ARM_SYSST);
85
86 /*
87 * Since an interrupt may set up a timer, we don't want to
88 * reprogram the hardware timer with interrupts enabled.
89 * Re-enable interrupts only after returning from idle.
90 */
91 timer_dyn_reprogram();
92
93 if ((mask32 & DSP_IDLE) == 0) {
94 __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4");
95 } else {
96
97 if (cpu_is_omap1510()) {
98 func_ptr = (void *)(OMAP1510_SRAM_IDLE_SUSPEND);
99 } else if (cpu_is_omap1610() || cpu_is_omap1710()) {
100 func_ptr = (void *)(OMAP1610_SRAM_IDLE_SUSPEND);
101 } else if (cpu_is_omap5912()) {
102 func_ptr = (void *)(OMAP5912_SRAM_IDLE_SUSPEND);
103 }
104
105 func_ptr();
106 }
107 local_fiq_enable();
108 local_irq_enable();
109}
110
111/*
112 * Configuration of the wakeup event is board specific. For the
113 * moment we put it into this helper function. Later it may move
114 * to board specific files.
115 */
116static void omap_pm_wakeup_setup(void)
117{
118 /*
119 * Enable ARM XOR clock and release peripheral from reset by
120 * writing 1 to PER_EN bit in ARM_RSTCT2, this is required
121 * for UART configuration to use UART2 to wake up.
122 */
123
124 omap_writel(omap_readl(ARM_IDLECT2) | ENABLE_XORCLK, ARM_IDLECT2);
125 omap_writel(omap_readl(ARM_RSTCT2) | PER_EN, ARM_RSTCT2);
126 omap_writew(MODEM_32K_EN, ULPD_CLOCK_CTRL);
127
128 /*
129 * Turn off all interrupts except L1-2nd level cascade,
130 * and the L2 wakeup interrupts: keypad and UART2.
131 */
132
133 omap_writel(~IRQ_LEVEL2, OMAP_IH1_MIR);
134
135 if (cpu_is_omap1510()) {
136 omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_MIR);
137 }
138
139 if (cpu_is_omap16xx()) {
140 omap_writel(~(IRQ_UART2 | IRQ_KEYBOARD), OMAP_IH2_0_MIR);
141
142 omap_writel(~0x0, OMAP_IH2_1_MIR);
143 omap_writel(~0x0, OMAP_IH2_2_MIR);
144 omap_writel(~0x0, OMAP_IH2_3_MIR);
145 }
146
147 /* New IRQ agreement */
148 omap_writel(1, OMAP_IH1_CONTROL);
149
150 /* external PULL to down, bit 22 = 0 */
151 omap_writel(omap_readl(PULL_DWN_CTRL_2) & ~(1<<22), PULL_DWN_CTRL_2);
152}
153
154void omap_pm_suspend(void)
155{
156 unsigned int mask32 = 0;
157 unsigned long arg0 = 0, arg1 = 0;
158 int (*func_ptr)(unsigned short, unsigned short) = 0;
159 unsigned short save_dsp_idlect2;
160
161 printk("PM: OMAP%x is entering deep sleep now ...\n", system_rev);
162
163 if (machine_is_omap_osk()) {
164 /* Stop LED1 (D9) blink */
165 tps65010_set_led(LED1, OFF);
166 }
167
168 /*
169 * Step 1: turn off interrupts
170 */
171
172 local_irq_disable();
173 local_fiq_disable();
174
175 /*
176 * Step 2: save registers
177 *
178 * The omap is a strange/beautiful device. The caches, memory
179 * and register state are preserved across power saves.
180 * We have to save and restore very little register state to
181 * idle the omap.
182 *
183 * Save interrupt, MPUI, ARM and UPLD control registers.
184 */
185
186 if (cpu_is_omap1510()) {
187 MPUI1510_SAVE(OMAP_IH1_MIR);
188 MPUI1510_SAVE(OMAP_IH2_MIR);
189 MPUI1510_SAVE(MPUI_CTRL);
190 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
191 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
192 MPUI1510_SAVE(EMIFS_CONFIG);
193 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
194 } else if (cpu_is_omap16xx()) {
195 MPUI1610_SAVE(OMAP_IH1_MIR);
196 MPUI1610_SAVE(OMAP_IH2_0_MIR);
197 MPUI1610_SAVE(OMAP_IH2_1_MIR);
198 MPUI1610_SAVE(OMAP_IH2_2_MIR);
199 MPUI1610_SAVE(OMAP_IH2_3_MIR);
200 MPUI1610_SAVE(MPUI_CTRL);
201 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
202 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
203 MPUI1610_SAVE(EMIFS_CONFIG);
204 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
205 }
206
207 ARM_SAVE(ARM_CKCTL);
208 ARM_SAVE(ARM_IDLECT1);
209 ARM_SAVE(ARM_IDLECT2);
210 ARM_SAVE(ARM_EWUPCT);
211 ARM_SAVE(ARM_RSTCT1);
212 ARM_SAVE(ARM_RSTCT2);
213 ARM_SAVE(ARM_SYSST);
214 ULPD_SAVE(ULPD_CLOCK_CTRL);
215 ULPD_SAVE(ULPD_STATUS_REQ);
216
217 /*
218 * Step 3: LOW_PWR signal enabling
219 *
220 * Allow the LOW_PWR signal to be visible on MPUIO5 ball.
221 */
222 if (cpu_is_omap1510()) {
223 /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
224 omap_writew(omap_readw(ULPD_POWER_CTRL) |
225 OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
226 } else if (cpu_is_omap16xx()) {
227 /* POWER_CTRL_REG = 0x1 (LOW_POWER is available) */
228 omap_writew(omap_readw(ULPD_POWER_CTRL) |
229 OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
230 }
231
232 /* configure LOW_PWR pin */
233 omap_cfg_reg(T20_1610_LOW_PWR);
234
235 /*
236 * Step 4: OMAP DSP Shutdown
237 */
238
239 /* Set DSP_RST = 1 and DSP_EN = 0, put DSP block into reset */
240 omap_writel((omap_readl(ARM_RSTCT1) | DSP_RST) & ~DSP_ENABLE,
241 ARM_RSTCT1);
242
243 /* Set DSP boot mode to DSP-IDLE, DSP_BOOT_MODE = 0x2 */
244 omap_writel(DSP_IDLE_MODE, MPUI_DSP_BOOT_CONFIG);
245
246 /* Set EN_DSPCK = 0, stop DSP block clock */
247 omap_writel(omap_readl(ARM_CKCTL) & ~DSP_CLOCK_ENABLE, ARM_CKCTL);
248
249 /* Stop any DSP domain clocks */
250 omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
251 save_dsp_idlect2 = __raw_readw(DSP_IDLECT2);
252 __raw_writew(0, DSP_IDLECT2);
253
254 /*
255 * Step 5: Wakeup Event Setup
256 */
257
258 omap_pm_wakeup_setup();
259
260 /*
261 * Step 6a: ARM and Traffic controller shutdown
262 *
263 * Step 6 starts here with clock and watchdog disable
264 */
265
266 /* stop clocks */
267 mask32 = omap_readl(ARM_IDLECT2);
268 mask32 &= ~(1<<EN_WDTCK); /* bit 0 -> 0 (WDT clock) */
269 mask32 |= (1<<EN_XORPCK); /* bit 1 -> 1 (XORPCK clock) */
270 mask32 &= ~(1<<EN_PERCK); /* bit 2 -> 0 (MPUPER_CK clock) */
271 mask32 &= ~(1<<EN_LCDCK); /* bit 3 -> 0 (LCDC clock) */
272 mask32 &= ~(1<<EN_LBCK); /* bit 4 -> 0 (local bus clock) */
273 mask32 |= (1<<EN_APICK); /* bit 6 -> 1 (MPUI clock) */
274 mask32 &= ~(1<<EN_TIMCK); /* bit 7 -> 0 (MPU timer clock) */
275 mask32 &= ~(1<<DMACK_REQ); /* bit 8 -> 0 (DMAC clock) */
276 mask32 &= ~(1<<EN_GPIOCK); /* bit 9 -> 0 (GPIO clock) */
277 omap_writel(mask32, ARM_IDLECT2);
278
279 /* disable ARM watchdog */
280 omap_writel(0x00F5, OMAP_WDT_TIMER_MODE);
281 omap_writel(0x00A0, OMAP_WDT_TIMER_MODE);
282
283 /*
284 * Step 6b: ARM and Traffic controller shutdown
285 *
286 * Step 6 continues here. Prepare jump to power management
287 * assembly code in internal SRAM.
288 *
289 * Since the omap_cpu_suspend routine has been copied to
290 * SRAM, we'll do an indirect procedure call to it and pass the
291 * contents of arm_idlect1 and arm_idlect2 so it can restore
292 * them when it wakes up and it will return.
293 */
294
295 arg0 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT1];
296 arg1 = arm_sleep_save[ARM_SLEEP_SAVE_ARM_IDLECT2];
297
298 if (cpu_is_omap1510()) {
299 func_ptr = (void *)(OMAP1510_SRAM_API_SUSPEND);
300 } else if (cpu_is_omap1610() || cpu_is_omap1710()) {
301 func_ptr = (void *)(OMAP1610_SRAM_API_SUSPEND);
302 } else if (cpu_is_omap5912()) {
303 func_ptr = (void *)(OMAP5912_SRAM_API_SUSPEND);
304 }
305
306 /*
307 * Step 6c: ARM and Traffic controller shutdown
308 *
309 * Jump to assembly code. The processor will stay there
310 * until wake up.
311 */
312
313 func_ptr(arg0, arg1);
314
315 /*
316 * If we are here, processor is woken up!
317 */
318
319 if (cpu_is_omap1510()) {
320 /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
321 omap_writew(omap_readw(ULPD_POWER_CTRL) &
322 ~OMAP1510_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
323 } else if (cpu_is_omap16xx()) {
324 /* POWER_CTRL_REG = 0x0 (LOW_POWER is disabled) */
325 omap_writew(omap_readw(ULPD_POWER_CTRL) &
326 ~OMAP1610_ULPD_LOW_POWER_REQ, ULPD_POWER_CTRL);
327 }
328
329
330 /* Restore DSP clocks */
331 omap_writel(omap_readl(ARM_IDLECT2) | (1<<EN_APICK), ARM_IDLECT2);
332 __raw_writew(save_dsp_idlect2, DSP_IDLECT2);
333 ARM_RESTORE(ARM_IDLECT2);
334
335 /*
336 * Restore ARM state, except ARM_IDLECT1/2 which omap_cpu_suspend did
337 */
338
339 ARM_RESTORE(ARM_CKCTL);
340 ARM_RESTORE(ARM_EWUPCT);
341 ARM_RESTORE(ARM_RSTCT1);
342 ARM_RESTORE(ARM_RSTCT2);
343 ARM_RESTORE(ARM_SYSST);
344 ULPD_RESTORE(ULPD_CLOCK_CTRL);
345 ULPD_RESTORE(ULPD_STATUS_REQ);
346
347 if (cpu_is_omap1510()) {
348 MPUI1510_RESTORE(MPUI_CTRL);
349 MPUI1510_RESTORE(MPUI_DSP_BOOT_CONFIG);
350 MPUI1510_RESTORE(MPUI_DSP_API_CONFIG);
351 MPUI1510_RESTORE(EMIFS_CONFIG);
352 MPUI1510_RESTORE(EMIFF_SDRAM_CONFIG);
353 MPUI1510_RESTORE(OMAP_IH1_MIR);
354 MPUI1510_RESTORE(OMAP_IH2_MIR);
355 } else if (cpu_is_omap16xx()) {
356 MPUI1610_RESTORE(MPUI_CTRL);
357 MPUI1610_RESTORE(MPUI_DSP_BOOT_CONFIG);
358 MPUI1610_RESTORE(MPUI_DSP_API_CONFIG);
359 MPUI1610_RESTORE(EMIFS_CONFIG);
360 MPUI1610_RESTORE(EMIFF_SDRAM_CONFIG);
361
362 MPUI1610_RESTORE(OMAP_IH1_MIR);
363 MPUI1610_RESTORE(OMAP_IH2_0_MIR);
364 MPUI1610_RESTORE(OMAP_IH2_1_MIR);
365 MPUI1610_RESTORE(OMAP_IH2_2_MIR);
366 MPUI1610_RESTORE(OMAP_IH2_3_MIR);
367 }
368
369 /*
370 * Reenable interrupts
371 */
372
373 local_irq_enable();
374 local_fiq_enable();
375
376 printk("PM: OMAP%x is re-starting from deep sleep...\n", system_rev);
377
378 if (machine_is_omap_osk()) {
379 /* Let LED1 (D9) blink again */
380 tps65010_set_led(LED1, BLINK);
381 }
382}
383
384#if defined(DEBUG) && defined(CONFIG_PROC_FS)
385static int g_read_completed;
386
387/*
388 * Read system PM registers for debugging
389 */
390static int omap_pm_read_proc(
391 char *page_buffer,
392 char **my_first_byte,
393 off_t virtual_start,
394 int length,
395 int *eof,
396 void *data)
397{
398 int my_buffer_offset = 0;
399 char * const my_base = page_buffer;
400
401 ARM_SAVE(ARM_CKCTL);
402 ARM_SAVE(ARM_IDLECT1);
403 ARM_SAVE(ARM_IDLECT2);
404 ARM_SAVE(ARM_EWUPCT);
405 ARM_SAVE(ARM_RSTCT1);
406 ARM_SAVE(ARM_RSTCT2);
407 ARM_SAVE(ARM_SYSST);
408
409 ULPD_SAVE(ULPD_IT_STATUS);
410 ULPD_SAVE(ULPD_CLOCK_CTRL);
411 ULPD_SAVE(ULPD_SOFT_REQ);
412 ULPD_SAVE(ULPD_STATUS_REQ);
413 ULPD_SAVE(ULPD_DPLL_CTRL);
414 ULPD_SAVE(ULPD_POWER_CTRL);
415
416 if (cpu_is_omap1510()) {
417 MPUI1510_SAVE(MPUI_CTRL);
418 MPUI1510_SAVE(MPUI_DSP_STATUS);
419 MPUI1510_SAVE(MPUI_DSP_BOOT_CONFIG);
420 MPUI1510_SAVE(MPUI_DSP_API_CONFIG);
421 MPUI1510_SAVE(EMIFF_SDRAM_CONFIG);
422 MPUI1510_SAVE(EMIFS_CONFIG);
423 } else if (cpu_is_omap16xx()) {
424 MPUI1610_SAVE(MPUI_CTRL);
425 MPUI1610_SAVE(MPUI_DSP_STATUS);
426 MPUI1610_SAVE(MPUI_DSP_BOOT_CONFIG);
427 MPUI1610_SAVE(MPUI_DSP_API_CONFIG);
428 MPUI1610_SAVE(EMIFF_SDRAM_CONFIG);
429 MPUI1610_SAVE(EMIFS_CONFIG);
430 }
431
432 if (virtual_start == 0) {
433 g_read_completed = 0;
434
435 my_buffer_offset += sprintf(my_base + my_buffer_offset,
436 "ARM_CKCTL_REG: 0x%-8x \n"
437 "ARM_IDLECT1_REG: 0x%-8x \n"
438 "ARM_IDLECT2_REG: 0x%-8x \n"
439 "ARM_EWUPCT_REG: 0x%-8x \n"
440 "ARM_RSTCT1_REG: 0x%-8x \n"
441 "ARM_RSTCT2_REG: 0x%-8x \n"
442 "ARM_SYSST_REG: 0x%-8x \n"
443 "ULPD_IT_STATUS_REG: 0x%-4x \n"
444 "ULPD_CLOCK_CTRL_REG: 0x%-4x \n"
445 "ULPD_SOFT_REQ_REG: 0x%-4x \n"
446 "ULPD_DPLL_CTRL_REG: 0x%-4x \n"
447 "ULPD_STATUS_REQ_REG: 0x%-4x \n"
448 "ULPD_POWER_CTRL_REG: 0x%-4x \n",
449 ARM_SHOW(ARM_CKCTL),
450 ARM_SHOW(ARM_IDLECT1),
451 ARM_SHOW(ARM_IDLECT2),
452 ARM_SHOW(ARM_EWUPCT),
453 ARM_SHOW(ARM_RSTCT1),
454 ARM_SHOW(ARM_RSTCT2),
455 ARM_SHOW(ARM_SYSST),
456 ULPD_SHOW(ULPD_IT_STATUS),
457 ULPD_SHOW(ULPD_CLOCK_CTRL),
458 ULPD_SHOW(ULPD_SOFT_REQ),
459 ULPD_SHOW(ULPD_DPLL_CTRL),
460 ULPD_SHOW(ULPD_STATUS_REQ),
461 ULPD_SHOW(ULPD_POWER_CTRL));
462
463 if (cpu_is_omap1510()) {
464 my_buffer_offset += sprintf(my_base + my_buffer_offset,
465 "MPUI1510_CTRL_REG 0x%-8x \n"
466 "MPUI1510_DSP_STATUS_REG: 0x%-8x \n"
467 "MPUI1510_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
468 "MPUI1510_DSP_API_CONFIG_REG: 0x%-8x \n"
469 "MPUI1510_SDRAM_CONFIG_REG: 0x%-8x \n"
470 "MPUI1510_EMIFS_CONFIG_REG: 0x%-8x \n",
471 MPUI1510_SHOW(MPUI_CTRL),
472 MPUI1510_SHOW(MPUI_DSP_STATUS),
473 MPUI1510_SHOW(MPUI_DSP_BOOT_CONFIG),
474 MPUI1510_SHOW(MPUI_DSP_API_CONFIG),
475 MPUI1510_SHOW(EMIFF_SDRAM_CONFIG),
476 MPUI1510_SHOW(EMIFS_CONFIG));
477 } else if (cpu_is_omap16xx()) {
478 my_buffer_offset += sprintf(my_base + my_buffer_offset,
479 "MPUI1610_CTRL_REG 0x%-8x \n"
480 "MPUI1610_DSP_STATUS_REG: 0x%-8x \n"
481 "MPUI1610_DSP_BOOT_CONFIG_REG: 0x%-8x \n"
482 "MPUI1610_DSP_API_CONFIG_REG: 0x%-8x \n"
483 "MPUI1610_SDRAM_CONFIG_REG: 0x%-8x \n"
484 "MPUI1610_EMIFS_CONFIG_REG: 0x%-8x \n",
485 MPUI1610_SHOW(MPUI_CTRL),
486 MPUI1610_SHOW(MPUI_DSP_STATUS),
487 MPUI1610_SHOW(MPUI_DSP_BOOT_CONFIG),
488 MPUI1610_SHOW(MPUI_DSP_API_CONFIG),
489 MPUI1610_SHOW(EMIFF_SDRAM_CONFIG),
490 MPUI1610_SHOW(EMIFS_CONFIG));
491 }
492
493 g_read_completed++;
494 } else if (g_read_completed >= 1) {
495 *eof = 1;
496 return 0;
497 }
498 g_read_completed++;
499
500 *my_first_byte = page_buffer;
501 return my_buffer_offset;
502}
503
504static void omap_pm_init_proc(void)
505{
506 struct proc_dir_entry *entry;
507
508 entry = create_proc_read_entry("driver/omap_pm",
509 S_IWUSR | S_IRUGO, NULL,
510 omap_pm_read_proc, 0);
511}
512
513#endif /* DEBUG && CONFIG_PROC_FS */
514
515/*
516 * omap_pm_prepare - Do preliminary suspend work.
517 * @state: suspend state we're entering.
518 *
519 */
520//#include <asm/arch/hardware.h>
521
522static int omap_pm_prepare(suspend_state_t state)
523{
524 int error = 0;
525
526 switch (state)
527 {
528 case PM_SUSPEND_STANDBY:
529 case PM_SUSPEND_MEM:
530 break;
531
532 case PM_SUSPEND_DISK:
533 return -ENOTSUPP;
534
535 default:
536 return -EINVAL;
537 }
538
539 return error;
540}
541
542
543/*
544 * omap_pm_enter - Actually enter a sleep state.
545 * @state: State we're entering.
546 *
547 */
548
549static int omap_pm_enter(suspend_state_t state)
550{
551 switch (state)
552 {
553 case PM_SUSPEND_STANDBY:
554 case PM_SUSPEND_MEM:
555 omap_pm_suspend();
556 break;
557
558 case PM_SUSPEND_DISK:
559 return -ENOTSUPP;
560
561 default:
562 return -EINVAL;
563 }
564
565 return 0;
566}
567
568
569/**
570 * omap_pm_finish - Finish up suspend sequence.
571 * @state: State we're coming out of.
572 *
573 * This is called after we wake back up (or if entering the sleep state
574 * failed).
575 */
576
577static int omap_pm_finish(suspend_state_t state)
578{
579 return 0;
580}
581
582
583struct pm_ops omap_pm_ops ={
584 .pm_disk_mode = 0,
585 .prepare = omap_pm_prepare,
586 .enter = omap_pm_enter,
587 .finish = omap_pm_finish,
588};
589
590static int __init omap_pm_init(void)
591{
592 printk("Power Management for TI OMAP.\n");
593 pm_idle = omap_pm_idle;
594 /*
595 * We copy the assembler sleep/wakeup routines to SRAM.
596 * These routines need to be in SRAM as that's the only
597 * memory the MPU can see when it wakes up.
598 */
599
600#ifdef CONFIG_ARCH_OMAP1510
601 if (cpu_is_omap1510()) {
602 memcpy((void *)OMAP1510_SRAM_IDLE_SUSPEND,
603 omap1510_idle_loop_suspend,
604 omap1510_idle_loop_suspend_sz);
605 memcpy((void *)OMAP1510_SRAM_API_SUSPEND, omap1510_cpu_suspend,
606 omap1510_cpu_suspend_sz);
607 } else
608#endif
609 if (cpu_is_omap1610() || cpu_is_omap1710()) {
610 memcpy((void *)OMAP1610_SRAM_IDLE_SUSPEND,
611 omap1610_idle_loop_suspend,
612 omap1610_idle_loop_suspend_sz);
613 memcpy((void *)OMAP1610_SRAM_API_SUSPEND, omap1610_cpu_suspend,
614 omap1610_cpu_suspend_sz);
615 } else if (cpu_is_omap5912()) {
616 memcpy((void *)OMAP5912_SRAM_IDLE_SUSPEND,
617 omap1610_idle_loop_suspend,
618 omap1610_idle_loop_suspend_sz);
619 memcpy((void *)OMAP5912_SRAM_API_SUSPEND, omap1610_cpu_suspend,
620 omap1610_cpu_suspend_sz);
621 }
622
623 pm_set_ops(&omap_pm_ops);
624
625#if defined(DEBUG) && defined(CONFIG_PROC_FS)
626 omap_pm_init_proc();
627#endif
628
629 return 0;
630}
631__initcall(omap_pm_init);
632
diff --git a/arch/arm/plat-omap/sleep.S b/arch/arm/plat-omap/sleep.S
new file mode 100644
index 000000000000..279490ce772b
--- /dev/null
+++ b/arch/arm/plat-omap/sleep.S
@@ -0,0 +1,314 @@
1/*
2 * linux/arch/arm/plat-omap/sleep.S
3 *
4 * Low-level OMAP1510/1610 sleep/wakeUp support
5 *
6 * Initial SA1110 code:
7 * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
8 *
9 * Adapted for PXA by Nicolas Pitre:
10 * Copyright (c) 2002 Monta Vista Software, Inc.
11 *
12 * Support for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
13 *
14 * This program is free software; you can redistribute it and/or modify it
15 * under the terms of the GNU General Public License as published by the
16 * Free Software Foundation; either version 2 of the License, or (at your
17 * option) any later version.
18 *
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
22 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
25 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * You should have received a copy of the GNU General Public License along
31 * with this program; if not, write to the Free Software Foundation, Inc.,
32 * 675 Mass Ave, Cambridge, MA 02139, USA.
33 */
34
35#include <linux/config.h>
36#include <linux/linkage.h>
37#include <asm/assembler.h>
38#include <asm/arch/io.h>
39#include <asm/arch/pm.h>
40
41 .text
42
43/*
44 * Forces OMAP into idle state
45 *
46 * omapXXXX_idle_loop_suspend()
47 *
48 * Note: This code get's copied to internal SRAM at boot. When the OMAP
49 * wakes up it continues execution at the point it went to sleep.
50 *
51 * Note: Because of slightly different configuration values we have
52 * processor specific functions here.
53 */
54
55#ifdef CONFIG_ARCH_OMAP1510
56ENTRY(omap1510_idle_loop_suspend)
57
58 stmfd sp!, {r0 - r12, lr} @ save registers on stack
59
60 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
61 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
62 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
63 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
64
65 @ turn off clock domains
66 @ get ARM_IDLECT2 into r2
67 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
68 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
69 orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
70 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
71
72 @ request ARM idle
73 @ get ARM_IDLECT1 into r1
74 ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
75 orr r3, r1, #OMAP1510_IDLE_LOOP_REQUEST & 0xffff
76 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
77
78 mov r5, #IDLE_WAIT_CYCLES & 0xff
79 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
80l_1510: subs r5, r5, #1
81 bne l_1510
82/*
83 * Let's wait for the next clock tick to wake us up.
84 */
85 mov r0, #0
86 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
87/*
88 * omap1510_idle_loop_suspend()'s resume point.
89 *
90 * It will just start executing here, so we'll restore stuff from the
91 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
92 */
93
94 @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
95 @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
96 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
97 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
98
99 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
100
101ENTRY(omap1510_idle_loop_suspend_sz)
102 .word . - omap1510_idle_loop_suspend
103#endif /* CONFIG_ARCH_OMAP1510 */
104
105#if defined(CONFIG_ARCH_OMAP16XX)
106ENTRY(omap1610_idle_loop_suspend)
107
108 stmfd sp!, {r0 - r12, lr} @ save registers on stack
109
110 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
111 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
112 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
113 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
114
115 @ turn off clock domains
116 @ get ARM_IDLECT2 into r2
117 ldrh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
118 mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
119 orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
120 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
121
122 @ request ARM idle
123 @ get ARM_IDLECT1 into r1
124 ldrh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
125 orr r3, r1, #OMAP1610_IDLE_LOOP_REQUEST & 0xffff
126 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
127
128 mov r5, #IDLE_WAIT_CYCLES & 0xff
129 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
130l_1610: subs r5, r5, #1
131 bne l_1610
132/*
133 * Let's wait for the next clock tick to wake us up.
134 */
135 mov r0, #0
136 mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt
137/*
138 * omap1610_idle_loop_suspend()'s resume point.
139 *
140 * It will just start executing here, so we'll restore stuff from the
141 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
142 */
143
144 @ restore ARM_IDLECT1 and ARM_IDLECT2 and return
145 @ r1 has ARM_IDLECT1 and r2 still has ARM_IDLECT2
146 strh r2, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
147 strh r1, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
148
149 ldmfd sp!, {r0 - r12, pc} @ restore regs and return
150
151ENTRY(omap1610_idle_loop_suspend_sz)
152 .word . - omap1610_idle_loop_suspend
153#endif /* CONFIG_ARCH_OMAP16XX */
154
155/*
156 * Forces OMAP into deep sleep state
157 *
158 * omapXXXX_cpu_suspend()
159 *
160 * The values of the registers ARM_IDLECT1 and ARM_IDLECT2 are passed
161 * as arg0 and arg1 from caller. arg0 is stored in register r0 and arg1
162 * in register r1.
163 *
164 * Note: This code get's copied to internal SRAM at boot. When the OMAP
165 * wakes up it continues execution at the point it went to sleep.
166 *
167 * Note: Because of errata work arounds we have processor specific functions
168 * here. They are mostly the same, but slightly different.
169 *
170 */
171
172#ifdef CONFIG_ARCH_OMAP1510
173ENTRY(omap1510_cpu_suspend)
174
175 @ save registers on stack
176 stmfd sp!, {r0 - r12, lr}
177
178 @ load base address of Traffic Controller
179 mov r4, #TCMIF_ASM_BASE & 0xff000000
180 orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
181 orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
182
183 @ work around errata of OMAP1510 PDE bit for TC shut down
184 @ clear PDE bit
185 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
186 bic r5, r5, #PDE_BIT & 0xff
187 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
188
189 @ set PWD_EN bit
190 and r5, r5, #PWD_EN_BIT & 0xff
191 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
192
193 @ prepare to put SDRAM into self-refresh manually
194 ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
195 orr r5, r5, #SELF_REFRESH_MODE & 0xff000000
196 orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff
197 str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
198
199 @ prepare to put EMIFS to Sleep
200 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
201 orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff
202 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
203
204 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
205 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
206 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
207 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
208
209 @ turn off clock domains
210 mov r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff
211 orr r5,r5, #OMAP1510_IDLE_CLOCK_DOMAINS & 0xff00
212 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
213
214 @ request ARM idle
215 mov r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff
216 orr r3, r3, #OMAP1510_DEEP_SLEEP_REQUEST & 0xff00
217 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
218
219 mov r5, #IDLE_WAIT_CYCLES & 0xff
220 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
221l_1510_2:
222 subs r5, r5, #1
223 bne l_1510_2
224/*
225 * Let's wait for the next wake up event to wake us up. r0 can't be
226 * used here because r0 holds ARM_IDLECT1
227 */
228 mov r2, #0
229 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
230/*
231 * omap1510_cpu_suspend()'s resume point.
232 *
233 * It will just start executing here, so we'll restore stuff from the
234 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
235 */
236 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
237 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
238
239 @ restore regs and return
240 ldmfd sp!, {r0 - r12, pc}
241
242ENTRY(omap1510_cpu_suspend_sz)
243 .word . - omap1510_cpu_suspend
244#endif /* CONFIG_ARCH_OMAP1510 */
245
246#if defined(CONFIG_ARCH_OMAP16XX)
247ENTRY(omap1610_cpu_suspend)
248
249 @ save registers on stack
250 stmfd sp!, {r0 - r12, lr}
251
252 @ load base address of Traffic Controller
253 mov r4, #TCMIF_ASM_BASE & 0xff000000
254 orr r4, r4, #TCMIF_ASM_BASE & 0x00ff0000
255 orr r4, r4, #TCMIF_ASM_BASE & 0x0000ff00
256
257 @ prepare to put SDRAM into self-refresh manually
258 ldr r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
259 orr r5, r5, #SELF_REFRESH_MODE & 0xff000000
260 orr r5, r5, #SELF_REFRESH_MODE & 0x000000ff
261 str r5, [r4, #EMIFF_SDRAM_CONFIG_ASM_OFFSET & 0xff]
262
263 @ prepare to put EMIFS to Sleep
264 ldr r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
265 orr r5, r5, #IDLE_EMIFS_REQUEST & 0xff
266 str r5, [r4, #EMIFS_CONFIG_ASM_OFFSET & 0xff]
267
268 @ load base address of ARM_IDLECT1 and ARM_IDLECT2
269 mov r4, #CLKGEN_REG_ASM_BASE & 0xff000000
270 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x00ff0000
271 orr r4, r4, #CLKGEN_REG_ASM_BASE & 0x0000ff00
272
273 @ turn off clock domains
274 mov r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff
275 orr r5,r5, #OMAP1610_IDLE_CLOCK_DOMAINS & 0xff00
276 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
277
278 @ work around errata of OMAP1610/5912. Enable (!) peripheral
279 @ clock to let the chip go into deep sleep
280 ldrh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
281 orr r5,r5, #EN_PERCK_BIT & 0xff
282 strh r5, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
283
284 @ request ARM idle
285 mov r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff
286 orr r3, r3, #OMAP1610_DEEP_SLEEP_REQUEST & 0xff00
287 strh r3, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
288
289 mov r5, #IDLE_WAIT_CYCLES & 0xff
290 orr r5, r5, #IDLE_WAIT_CYCLES & 0xff00
291l_1610_2:
292 subs r5, r5, #1
293 bne l_1610_2
294/*
295 * Let's wait for the next wake up event to wake us up. r0 can't be
296 * used here because r0 holds ARM_IDLECT1
297 */
298 mov r2, #0
299 mcr p15, 0, r2, c7, c0, 4 @ wait for interrupt
300/*
301 * omap1610_cpu_suspend()'s resume point.
302 *
303 * It will just start executing here, so we'll restore stuff from the
304 * stack, reset the ARM_IDLECT1 and ARM_IDLECT2.
305 */
306 strh r1, [r4, #ARM_IDLECT2_ASM_OFFSET & 0xff]
307 strh r0, [r4, #ARM_IDLECT1_ASM_OFFSET & 0xff]
308
309 @ restore regs and return
310 ldmfd sp!, {r0 - r12, pc}
311
312ENTRY(omap1610_cpu_suspend_sz)
313 .word . - omap1610_cpu_suspend
314#endif /* CONFIG_ARCH_OMAP16XX */
diff --git a/arch/arm/plat-omap/usb.c b/arch/arm/plat-omap/usb.c
new file mode 100644
index 000000000000..ab38e4eb3130
--- /dev/null
+++ b/arch/arm/plat-omap/usb.c
@@ -0,0 +1,593 @@
1/*
2 * arch/arm/plat-omap/usb.c -- platform level USB initialization
3 *
4 * Copyright (C) 2004 Texas Instruments, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#undef DEBUG
22
23#include <linux/config.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/types.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29#include <linux/device.h>
30#include <linux/usb_otg.h>
31
32#include <asm/io.h>
33#include <asm/irq.h>
34#include <asm/system.h>
35#include <asm/hardware.h>
36#include <asm/mach-types.h>
37
38#include <asm/arch/mux.h>
39#include <asm/arch/usb.h>
40#include <asm/arch/board.h>
41
42/* These routines should handle the standard chip-specific modes
43 * for usb0/1/2 ports, covering basic mux and transceiver setup.
44 *
45 * Some board-*.c files will need to set up additional mux options,
46 * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup.
47 */
48
49/* TESTED ON:
50 * - 1611B H2 (with usb1 mini-AB) using standard Mini-B or OTG cables
51 * - 5912 OSK OHCI (with usb0 standard-A), standard A-to-B cables
52 * - 5912 OSK UDC, with *nonstandard* A-to-A cable
53 * - 1510 Innovator UDC with bundled usb0 cable
54 * - 1510 Innovator OHCI with bundled usb1/usb2 cable
55 * - 1510 Innovator OHCI with custom usb0 cable, feeding 5V VBUS
56 * - 1710 custom development board using alternate pin group
57 * - 1710 H3 (with usb1 mini-AB) using standard Mini-B or OTG cables
58 */
59
60/*-------------------------------------------------------------------------*/
61
62#ifdef CONFIG_ARCH_OMAP_OTG
63
64static struct otg_transceiver *xceiv;
65
66/**
67 * otg_get_transceiver - find the (single) OTG transceiver driver
68 *
69 * Returns the transceiver driver, after getting a refcount to it; or
70 * null if there is no such transceiver. The caller is responsible for
71 * releasing that count.
72 */
73struct otg_transceiver *otg_get_transceiver(void)
74{
75 if (xceiv)
76 get_device(xceiv->dev);
77 return xceiv;
78}
79EXPORT_SYMBOL(otg_get_transceiver);
80
81int otg_set_transceiver(struct otg_transceiver *x)
82{
83 if (xceiv && x)
84 return -EBUSY;
85 xceiv = x;
86 return 0;
87}
88EXPORT_SYMBOL(otg_set_transceiver);
89
90#endif
91
92/*-------------------------------------------------------------------------*/
93
94static u32 __init omap_usb0_init(unsigned nwires, unsigned is_device)
95{
96 u32 syscon1 = 0;
97
98 if (nwires == 0) {
99 if (!cpu_is_omap15xx()) {
100 /* pulldown D+/D- */
101 USB_TRANSCEIVER_CTRL_REG &= ~(3 << 1);
102 }
103 return 0;
104 }
105
106 if (is_device)
107 omap_cfg_reg(W4_USB_PUEN);
108
109 /* internal transceiver */
110 if (nwires == 2) {
111 // omap_cfg_reg(P9_USB_DP);
112 // omap_cfg_reg(R8_USB_DM);
113
114 if (cpu_is_omap15xx()) {
115 /* This works on 1510-Innovator */
116 return 0;
117 }
118
119 /* NOTES:
120 * - peripheral should configure VBUS detection!
121 * - only peripherals may use the internal D+/D- pulldowns
122 * - OTG support on this port not yet written
123 */
124
125 USB_TRANSCEIVER_CTRL_REG &= ~(7 << 4);
126 if (!is_device)
127 USB_TRANSCEIVER_CTRL_REG |= (3 << 1);
128
129 return 3 << 16;
130 }
131
132 /* alternate pin config, external transceiver */
133 if (cpu_is_omap15xx()) {
134 printk(KERN_ERR "no usb0 alt pin config on 15xx\n");
135 return 0;
136 }
137
138 omap_cfg_reg(V6_USB0_TXD);
139 omap_cfg_reg(W9_USB0_TXEN);
140 omap_cfg_reg(W5_USB0_SE0);
141
142 /* NOTE: SPEED and SUSP aren't configured here */
143
144 if (nwires != 3)
145 omap_cfg_reg(Y5_USB0_RCV);
146 if (nwires != 6)
147 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
148
149 switch (nwires) {
150 case 3:
151 syscon1 = 2;
152 break;
153 case 4:
154 syscon1 = 1;
155 break;
156 case 6:
157 syscon1 = 3;
158 omap_cfg_reg(AA9_USB0_VP);
159 omap_cfg_reg(R9_USB0_VM);
160 USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
161 break;
162 default:
163 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
164 0, nwires);
165 }
166 return syscon1 << 16;
167}
168
169static u32 __init omap_usb1_init(unsigned nwires)
170{
171 u32 syscon1 = 0;
172
173 if (nwires != 6 && !cpu_is_omap15xx())
174 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB1_UNI_R;
175 if (nwires == 0)
176 return 0;
177
178 /* external transceiver */
179 omap_cfg_reg(USB1_TXD);
180 omap_cfg_reg(USB1_TXEN);
181 if (cpu_is_omap15xx()) {
182 omap_cfg_reg(USB1_SEO);
183 omap_cfg_reg(USB1_SPEED);
184 // SUSP
185 } else if (cpu_is_omap1610() || cpu_is_omap5912()) {
186 omap_cfg_reg(W13_1610_USB1_SE0);
187 omap_cfg_reg(R13_1610_USB1_SPEED);
188 // SUSP
189 } else if (cpu_is_omap1710()) {
190 omap_cfg_reg(R13_1710_USB1_SE0);
191 // SUSP
192 } else {
193 pr_debug("usb unrecognized\n");
194 }
195 if (nwires != 3)
196 omap_cfg_reg(USB1_RCV);
197
198 switch (nwires) {
199 case 3:
200 syscon1 = 2;
201 break;
202 case 4:
203 syscon1 = 1;
204 break;
205 case 6:
206 syscon1 = 3;
207 omap_cfg_reg(USB1_VP);
208 omap_cfg_reg(USB1_VM);
209 if (!cpu_is_omap15xx())
210 USB_TRANSCEIVER_CTRL_REG |= CONF_USB1_UNI_R;
211 break;
212 default:
213 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
214 1, nwires);
215 }
216 return syscon1 << 20;
217}
218
219static u32 __init omap_usb2_init(unsigned nwires, unsigned alt_pingroup)
220{
221 u32 syscon1 = 0;
222
223 /* NOTE erratum: must leave USB2_UNI_R set if usb0 in use */
224 if (alt_pingroup || nwires == 0)
225 return 0;
226 if (nwires != 6 && !cpu_is_omap15xx())
227 USB_TRANSCEIVER_CTRL_REG &= ~CONF_USB2_UNI_R;
228
229 /* external transceiver */
230 if (cpu_is_omap15xx()) {
231 omap_cfg_reg(USB2_TXD);
232 omap_cfg_reg(USB2_TXEN);
233 omap_cfg_reg(USB2_SEO);
234 if (nwires != 3)
235 omap_cfg_reg(USB2_RCV);
236 /* there is no USB2_SPEED */
237 } else if (cpu_is_omap16xx()) {
238 omap_cfg_reg(V6_USB2_TXD);
239 omap_cfg_reg(W9_USB2_TXEN);
240 omap_cfg_reg(W5_USB2_SE0);
241 if (nwires != 3)
242 omap_cfg_reg(Y5_USB2_RCV);
243 // FIXME omap_cfg_reg(USB2_SPEED);
244 } else {
245 pr_debug("usb unrecognized\n");
246 }
247 // omap_cfg_reg(USB2_SUSP);
248
249 switch (nwires) {
250 case 3:
251 syscon1 = 2;
252 break;
253 case 4:
254 syscon1 = 1;
255 break;
256 case 6:
257 syscon1 = 3;
258 if (cpu_is_omap15xx()) {
259 omap_cfg_reg(USB2_VP);
260 omap_cfg_reg(USB2_VM);
261 } else {
262 omap_cfg_reg(AA9_USB2_VP);
263 omap_cfg_reg(R9_USB2_VM);
264 USB_TRANSCEIVER_CTRL_REG |= CONF_USB2_UNI_R;
265 }
266 break;
267 default:
268 printk(KERN_ERR "illegal usb%d %d-wire transceiver\n",
269 2, nwires);
270 }
271 return syscon1 << 24;
272}
273
274/*-------------------------------------------------------------------------*/
275
276#if defined(CONFIG_USB_GADGET_OMAP) || \
277 defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) || \
278 (defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG))
279static void usb_release(struct device *dev)
280{
281 /* normally not freed */
282}
283#endif
284
285#ifdef CONFIG_USB_GADGET_OMAP
286
287static struct resource udc_resources[] = {
288 /* order is significant! */
289 { /* registers */
290 .start = UDC_BASE,
291 .end = UDC_BASE + 0xff,
292 .flags = IORESOURCE_MEM,
293 }, { /* general IRQ */
294 .start = IH2_BASE + 20,
295 .flags = IORESOURCE_IRQ,
296 }, { /* PIO IRQ */
297 .start = IH2_BASE + 30,
298 .flags = IORESOURCE_IRQ,
299 }, { /* SOF IRQ */
300 .start = IH2_BASE + 29,
301 .flags = IORESOURCE_IRQ,
302 },
303};
304
305static u64 udc_dmamask = ~(u32)0;
306
307static struct platform_device udc_device = {
308 .name = "omap_udc",
309 .id = -1,
310 .dev = {
311 .release = usb_release,
312 .dma_mask = &udc_dmamask,
313 .coherent_dma_mask = 0xffffffff,
314 },
315 .num_resources = ARRAY_SIZE(udc_resources),
316 .resource = udc_resources,
317};
318
319#endif
320
321#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
322
323/* The dmamask must be set for OHCI to work */
324static u64 ohci_dmamask = ~(u32)0;
325
326static struct resource ohci_resources[] = {
327 {
328 .start = OMAP_OHCI_BASE,
329 .end = OMAP_OHCI_BASE + 4096,
330 .flags = IORESOURCE_MEM,
331 },
332 {
333 .start = INT_USB_HHC_1,
334 .flags = IORESOURCE_IRQ,
335 },
336};
337
338static struct platform_device ohci_device = {
339 .name = "ohci",
340 .id = -1,
341 .dev = {
342 .release = usb_release,
343 .dma_mask = &ohci_dmamask,
344 .coherent_dma_mask = 0xffffffff,
345 },
346 .num_resources = ARRAY_SIZE(ohci_resources),
347 .resource = ohci_resources,
348};
349
350#endif
351
352#if defined(CONFIG_USB_OTG) && defined(CONFIG_ARCH_OMAP_OTG)
353
354static struct resource otg_resources[] = {
355 /* order is significant! */
356 {
357 .start = OTG_BASE,
358 .end = OTG_BASE + 0xff,
359 .flags = IORESOURCE_MEM,
360 }, {
361 .start = IH2_BASE + 8,
362 .flags = IORESOURCE_IRQ,
363 },
364};
365
366static struct platform_device otg_device = {
367 .name = "omap_otg",
368 .id = -1,
369 .dev = {
370 .release = usb_release,
371 },
372 .num_resources = ARRAY_SIZE(otg_resources),
373 .resource = otg_resources,
374};
375
376#endif
377
378/*-------------------------------------------------------------------------*/
379
380#define ULPD_CLOCK_CTRL_REG __REG16(ULPD_CLOCK_CTRL)
381#define ULPD_SOFT_REQ_REG __REG16(ULPD_SOFT_REQ)
382
383
384// FIXME correct answer depends on hmc_mode,
385// as does any nonzero value for config->otg port number
386#ifdef CONFIG_USB_GADGET_OMAP
387#define is_usb0_device(config) 1
388#else
389#define is_usb0_device(config) 0
390#endif
391
392/*-------------------------------------------------------------------------*/
393
394#ifdef CONFIG_ARCH_OMAP_OTG
395
396void __init
397omap_otg_init(struct omap_usb_config *config)
398{
399 u32 syscon = OTG_SYSCON_1_REG & 0xffff;
400 int status;
401 int alt_pingroup = 0;
402
403 /* NOTE: no bus or clock setup (yet?) */
404
405 syscon = OTG_SYSCON_1_REG & 0xffff;
406 if (!(syscon & OTG_RESET_DONE))
407 pr_debug("USB resets not complete?\n");
408
409 // OTG_IRQ_EN_REG = 0;
410
411 /* pin muxing and transceiver pinouts */
412 if (config->pins[0] > 2) /* alt pingroup 2 */
413 alt_pingroup = 1;
414 syscon |= omap_usb0_init(config->pins[0], is_usb0_device(config));
415 syscon |= omap_usb1_init(config->pins[1]);
416 syscon |= omap_usb2_init(config->pins[2], alt_pingroup);
417 pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
418 OTG_SYSCON_1_REG = syscon;
419
420 syscon = config->hmc_mode;
421 syscon |= USBX_SYNCHRO | (4 << 16) /* B_ASE0_BRST */;
422#ifdef CONFIG_USB_OTG
423 if (config->otg)
424 syscon |= OTG_EN;
425#endif
426 pr_debug("USB_TRANSCEIVER_CTRL_REG = %03x\n", USB_TRANSCEIVER_CTRL_REG);
427 pr_debug("OTG_SYSCON_2_REG = %08x\n", syscon);
428 OTG_SYSCON_2_REG = syscon;
429
430 printk("USB: hmc %d", config->hmc_mode);
431 if (alt_pingroup)
432 printk(", usb2 alt %d wires", config->pins[2]);
433 else if (config->pins[0])
434 printk(", usb0 %d wires%s", config->pins[0],
435 is_usb0_device(config) ? " (dev)" : "");
436 if (config->pins[1])
437 printk(", usb1 %d wires", config->pins[1]);
438 if (!alt_pingroup && config->pins[2])
439 printk(", usb2 %d wires", config->pins[2]);
440 if (config->otg)
441 printk(", Mini-AB on usb%d", config->otg - 1);
442 printk("\n");
443
444 /* leave USB clocks/controllers off until needed */
445 ULPD_SOFT_REQ_REG &= ~SOFT_USB_CLK_REQ;
446 ULPD_CLOCK_CTRL_REG &= ~USB_MCLK_EN;
447 ULPD_CLOCK_CTRL_REG |= DIS_USB_PVCI_CLK;
448 syscon = OTG_SYSCON_1_REG;
449 syscon |= HST_IDLE_EN|DEV_IDLE_EN|OTG_IDLE_EN;
450
451#ifdef CONFIG_USB_GADGET_OMAP
452 if (config->otg || config->register_dev) {
453 syscon &= ~DEV_IDLE_EN;
454 udc_device.dev.platform_data = config;
455 /* FIXME patch IRQ numbers for omap730 */
456 status = platform_device_register(&udc_device);
457 if (status)
458 pr_debug("can't register UDC device, %d\n", status);
459 }
460#endif
461
462#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
463 if (config->otg || config->register_host) {
464 syscon &= ~HST_IDLE_EN;
465 ohci_device.dev.platform_data = config;
466 if (cpu_is_omap730())
467 ohci_resources[1].start = INT_730_USB_HHC_1;
468 status = platform_device_register(&ohci_device);
469 if (status)
470 pr_debug("can't register OHCI device, %d\n", status);
471 }
472#endif
473
474#ifdef CONFIG_USB_OTG
475 if (config->otg) {
476 syscon &= ~OTG_IDLE_EN;
477 otg_device.dev.platform_data = config;
478 if (cpu_is_omap730())
479 otg_resources[1].start = INT_730_USB_OTG;
480 status = platform_device_register(&otg_device);
481 if (status)
482 pr_debug("can't register OTG device, %d\n", status);
483 }
484#endif
485 pr_debug("OTG_SYSCON_1_REG = %08x\n", syscon);
486 OTG_SYSCON_1_REG = syscon;
487
488 status = 0;
489}
490
491#else
492static inline void omap_otg_init(struct omap_usb_config *config) {}
493#endif
494
495/*-------------------------------------------------------------------------*/
496
497#ifdef CONFIG_ARCH_OMAP1510
498
499#define ULPD_DPLL_CTRL_REG __REG16(ULPD_DPLL_CTRL)
500#define DPLL_IOB (1 << 13)
501#define DPLL_PLL_ENABLE (1 << 4)
502#define DPLL_LOCK (1 << 0)
503
504#define ULPD_APLL_CTRL_REG __REG16(ULPD_APLL_CTRL)
505#define APLL_NDPLL_SWITCH (1 << 0)
506
507
508static void __init omap_1510_usb_init(struct omap_usb_config *config)
509{
510 int status;
511 unsigned int val;
512
513 omap_usb0_init(config->pins[0], is_usb0_device(config));
514 omap_usb1_init(config->pins[1]);
515 omap_usb2_init(config->pins[2], 0);
516
517 val = omap_readl(MOD_CONF_CTRL_0) & ~(0x3f << 1);
518 val |= (config->hmc_mode << 1);
519 omap_writel(val, MOD_CONF_CTRL_0);
520
521 printk("USB: hmc %d", config->hmc_mode);
522 if (config->pins[0])
523 printk(", usb0 %d wires%s", config->pins[0],
524 is_usb0_device(config) ? " (dev)" : "");
525 if (config->pins[1])
526 printk(", usb1 %d wires", config->pins[1]);
527 if (config->pins[2])
528 printk(", usb2 %d wires", config->pins[2]);
529 printk("\n");
530
531 /* use DPLL for 48 MHz function clock */
532 pr_debug("APLL %04x DPLL %04x REQ %04x\n", ULPD_APLL_CTRL_REG,
533 ULPD_DPLL_CTRL_REG, ULPD_SOFT_REQ_REG);
534 ULPD_APLL_CTRL_REG &= ~APLL_NDPLL_SWITCH;
535 ULPD_DPLL_CTRL_REG |= DPLL_IOB | DPLL_PLL_ENABLE;
536 ULPD_SOFT_REQ_REG |= SOFT_UDC_REQ | SOFT_DPLL_REQ;
537 while (!(ULPD_DPLL_CTRL_REG & DPLL_LOCK))
538 cpu_relax();
539
540#ifdef CONFIG_USB_GADGET_OMAP
541 if (config->register_dev) {
542 udc_device.dev.platform_data = config;
543 status = platform_device_register(&udc_device);
544 if (status)
545 pr_debug("can't register UDC device, %d\n", status);
546 /* udc driver gates 48MHz by D+ pullup */
547 }
548#endif
549
550#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
551 if (config->register_host) {
552 ohci_device.dev.platform_data = config;
553 status = platform_device_register(&ohci_device);
554 if (status)
555 pr_debug("can't register OHCI device, %d\n", status);
556 /* hcd explicitly gates 48MHz */
557 }
558#endif
559}
560
561#else
562static inline void omap_1510_usb_init(struct omap_usb_config *config) {}
563#endif
564
565/*-------------------------------------------------------------------------*/
566
567static struct omap_usb_config platform_data;
568
569static int __init
570omap_usb_init(void)
571{
572 const struct omap_usb_config *config;
573
574 config = omap_get_config(OMAP_TAG_USB, struct omap_usb_config);
575 if (config == NULL) {
576 printk(KERN_ERR "USB: No board-specific "
577 "platform config found\n");
578 return -ENODEV;
579 }
580 platform_data = *config;
581
582 if (cpu_is_omap730() || cpu_is_omap16xx())
583 omap_otg_init(&platform_data);
584 else if (cpu_is_omap15xx())
585 omap_1510_usb_init(&platform_data);
586 else {
587 printk(KERN_ERR "USB: No init for your chip yet\n");
588 return -ENODEV;
589 }
590 return 0;
591}
592
593subsys_initcall(omap_usb_init);