aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/plat-omap
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap')
-rw-r--r--arch/arm/plat-omap/Kconfig112
-rw-r--r--arch/arm/plat-omap/Makefile17
-rw-r--r--arch/arm/plat-omap/clock.c1323
-rw-r--r--arch/arm/plat-omap/clock.h120
-rw-r--r--arch/arm/plat-omap/common.c135
-rw-r--r--arch/arm/plat-omap/cpu-omap.c128
-rw-r--r--arch/arm/plat-omap/dma.c1116
-rw-r--r--arch/arm/plat-omap/gpio.c762
-rw-r--r--arch/arm/plat-omap/mcbsp.c758
-rw-r--r--arch/arm/plat-omap/mux.c160
-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
14 files changed, 6284 insertions, 0 deletions
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
new file mode 100644
index 000000000000..345365852f8c
--- /dev/null
+++ b/arch/arm/plat-omap/Kconfig
@@ -0,0 +1,112 @@
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_RESET_CLOCKS
23 bool "Reset unused clocks during boot"
24 depends on ARCH_OMAP
25 default n
26 help
27 Say Y if you want to reset unused clocks during boot.
28 This option saves power, but assumes all drivers are
29 using the clock framework. Broken drivers that do not
30 yet use clock framework may not work with this option.
31 If you are booting from another operating system, you
32 probably do not want this option enabled until your
33 device drivers work properly.
34
35config OMAP_MUX
36 bool "OMAP multiplexing support"
37 depends on ARCH_OMAP
38 default y
39 help
40 Pin multiplexing support for OMAP boards. If your bootloader
41 sets the multiplexing correctly, say N. Otherwise, or if unsure,
42 say Y.
43
44config OMAP_MUX_DEBUG
45 bool "Multiplexing debug output"
46 depends on OMAP_MUX
47 default n
48 help
49 Makes the multiplexing functions print out a lot of debug info.
50 This is useful if you want to find out the correct values of the
51 multiplexing registers.
52
53config OMAP_MUX_WARNINGS
54 bool "Warn about pins the bootloader didn't set up"
55 depends on OMAP_MUX
56 default y
57 help
58 Choose Y here to warn whenever driver initialization logic needs
59 to change the pin multiplexing setup. When there are no warnings
60 printed, it's safe to deselect OMAP_MUX for your product.
61
62choice
63 prompt "System timer"
64 default OMAP_MPU_TIMER
65
66config OMAP_MPU_TIMER
67 bool "Use mpu timer"
68 help
69 Select this option if you want to use the OMAP mpu timer. This
70 timer provides more intra-tick resolution than the 32KHz timer,
71 but consumes more power.
72
73config OMAP_32K_TIMER
74 bool "Use 32KHz timer"
75 depends on ARCH_OMAP16XX
76 help
77 Select this option if you want to enable the OMAP 32KHz timer.
78 This timer saves power compared to the OMAP_MPU_TIMER, and has
79 support for no tick during idle. The 32KHz timer provides less
80 intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is
81 currently only available for OMAP-16xx.
82
83endchoice
84
85config OMAP_32K_TIMER_HZ
86 int "Kernel internal timer frequency for 32KHz timer"
87 range 32 1024
88 depends on OMAP_32K_TIMER
89 default "128"
90 help
91 Kernel internal timer frequency should be a divisor of 32768,
92 such as 64 or 128.
93
94choice
95 prompt "Low-level debug console UART"
96 depends on ARCH_OMAP
97 default OMAP_LL_DEBUG_UART1
98
99config OMAP_LL_DEBUG_UART1
100 bool "UART1"
101
102config OMAP_LL_DEBUG_UART2
103 bool "UART2"
104
105config OMAP_LL_DEBUG_UART3
106 bool "UART3"
107
108endchoice
109
110endmenu
111
112endif
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
new file mode 100644
index 000000000000..531e11af54d4
--- /dev/null
+++ b/arch/arm/plat-omap/Makefile
@@ -0,0 +1,17 @@
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
17obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
diff --git a/arch/arm/plat-omap/clock.c b/arch/arm/plat-omap/clock.c
new file mode 100644
index 000000000000..59d91b3262ba
--- /dev/null
+++ b/arch/arm/plat-omap/clock.c
@@ -0,0 +1,1323 @@
1/*
2 * linux/arch/arm/plat-omap/clock.c
3 *
4 * Copyright (C) 2004 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/module.h>
12#include <linux/kernel.h>
13#include <linux/list.h>
14#include <linux/errno.h>
15#include <linux/err.h>
16
17#include <asm/io.h>
18#include <asm/semaphore.h>
19#include <asm/hardware/clock.h>
20#include <asm/arch/board.h>
21#include <asm/arch/usb.h>
22
23#include "clock.h"
24
25static LIST_HEAD(clocks);
26static DECLARE_MUTEX(clocks_sem);
27static DEFINE_SPINLOCK(clockfw_lock);
28static void propagate_rate(struct clk * clk);
29/* UART clock function */
30static int set_uart_rate(struct clk * clk, unsigned long rate);
31/* External clock (MCLK & BCLK) functions */
32static int set_ext_clk_rate(struct clk * clk, unsigned long rate);
33static long round_ext_clk_rate(struct clk * clk, unsigned long rate);
34static void init_ext_clk(struct clk * clk);
35/* MPU virtual clock functions */
36static int select_table_rate(struct clk * clk, unsigned long rate);
37static long round_to_table_rate(struct clk * clk, unsigned long rate);
38void clk_setdpll(__u16, __u16);
39
40static struct mpu_rate rate_table[] = {
41 /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
42 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
43 */
44#if defined(CONFIG_OMAP_ARM_216MHZ)
45 { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
46#endif
47#if defined(CONFIG_OMAP_ARM_195MHZ)
48 { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
49#endif
50#if defined(CONFIG_OMAP_ARM_192MHZ)
51 { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
52 { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
53 { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
54 { 48000000, 12000000, 192000000, 0x0baf, 0x2810 }, /* 4/8/4/4/8/8 */
55 { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
56#endif
57#if defined(CONFIG_OMAP_ARM_182MHZ)
58 { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
59#endif
60#if defined(CONFIG_OMAP_ARM_168MHZ)
61 { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
62#endif
63#if defined(CONFIG_OMAP_ARM_150MHZ)
64 { 150000000, 12000000, 150000000, 0x010a, 0x2cb0 }, /* 1/1/1/2/4/4 */
65#endif
66#if defined(CONFIG_OMAP_ARM_120MHZ)
67 { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
68#endif
69#if defined(CONFIG_OMAP_ARM_96MHZ)
70 { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
71#endif
72#if defined(CONFIG_OMAP_ARM_60MHZ)
73 { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
74#endif
75#if defined(CONFIG_OMAP_ARM_30MHZ)
76 { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
77#endif
78 { 0, 0, 0, 0, 0 },
79};
80
81
82static void ckctl_recalc(struct clk * clk);
83int __clk_enable(struct clk *clk);
84void __clk_disable(struct clk *clk);
85void __clk_unuse(struct clk *clk);
86int __clk_use(struct clk *clk);
87
88
89static void followparent_recalc(struct clk * clk)
90{
91 clk->rate = clk->parent->rate;
92}
93
94
95static void watchdog_recalc(struct clk * clk)
96{
97 clk->rate = clk->parent->rate / 14;
98}
99
100static void uart_recalc(struct clk * clk)
101{
102 unsigned int val = omap_readl(clk->enable_reg);
103 if (val & clk->enable_bit)
104 clk->rate = 48000000;
105 else
106 clk->rate = 12000000;
107}
108
109static struct clk ck_ref = {
110 .name = "ck_ref",
111 .rate = 12000000,
112 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
113 ALWAYS_ENABLED,
114};
115
116static struct clk ck_dpll1 = {
117 .name = "ck_dpll1",
118 .parent = &ck_ref,
119 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
120 RATE_PROPAGATES | ALWAYS_ENABLED,
121};
122
123static struct clk ck_dpll1out = {
124 .name = "ck_dpll1out",
125 .parent = &ck_dpll1,
126 .flags = CLOCK_IN_OMAP16XX,
127 .enable_reg = ARM_IDLECT2,
128 .enable_bit = EN_CKOUT_ARM,
129 .recalc = &followparent_recalc,
130};
131
132static struct clk arm_ck = {
133 .name = "arm_ck",
134 .parent = &ck_dpll1,
135 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
136 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
137 .rate_offset = CKCTL_ARMDIV_OFFSET,
138 .recalc = &ckctl_recalc,
139};
140
141static struct clk armper_ck = {
142 .name = "armper_ck",
143 .parent = &ck_dpll1,
144 .flags = CLOCK_IN_OMAP730 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
145 RATE_CKCTL,
146 .enable_reg = ARM_IDLECT2,
147 .enable_bit = EN_PERCK,
148 .rate_offset = CKCTL_PERDIV_OFFSET,
149 .recalc = &ckctl_recalc,
150};
151
152static struct clk arm_gpio_ck = {
153 .name = "arm_gpio_ck",
154 .parent = &ck_dpll1,
155 .flags = CLOCK_IN_OMAP1510,
156 .enable_reg = ARM_IDLECT2,
157 .enable_bit = EN_GPIOCK,
158 .recalc = &followparent_recalc,
159};
160
161static struct clk armxor_ck = {
162 .name = "armxor_ck",
163 .parent = &ck_ref,
164 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
165 .enable_reg = ARM_IDLECT2,
166 .enable_bit = EN_XORPCK,
167 .recalc = &followparent_recalc,
168};
169
170static struct clk armtim_ck = {
171 .name = "armtim_ck",
172 .parent = &ck_ref,
173 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
174 .enable_reg = ARM_IDLECT2,
175 .enable_bit = EN_TIMCK,
176 .recalc = &followparent_recalc,
177};
178
179static struct clk armwdt_ck = {
180 .name = "armwdt_ck",
181 .parent = &ck_ref,
182 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
183 .enable_reg = ARM_IDLECT2,
184 .enable_bit = EN_WDTCK,
185 .recalc = &watchdog_recalc,
186};
187
188static struct clk arminth_ck16xx = {
189 .name = "arminth_ck",
190 .parent = &arm_ck,
191 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
192 .recalc = &followparent_recalc,
193 /* Note: On 16xx the frequency can be divided by 2 by programming
194 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
195 *
196 * 1510 version is in TC clocks.
197 */
198};
199
200static struct clk dsp_ck = {
201 .name = "dsp_ck",
202 .parent = &ck_dpll1,
203 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
204 RATE_CKCTL,
205 .enable_reg = ARM_CKCTL,
206 .enable_bit = EN_DSPCK,
207 .rate_offset = CKCTL_DSPDIV_OFFSET,
208 .recalc = &ckctl_recalc,
209};
210
211static struct clk dspmmu_ck = {
212 .name = "dspmmu_ck",
213 .parent = &ck_dpll1,
214 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
215 RATE_CKCTL | ALWAYS_ENABLED,
216 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
217 .recalc = &ckctl_recalc,
218};
219
220static struct clk dspper_ck = {
221 .name = "dspper_ck",
222 .parent = &ck_dpll1,
223 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
224 RATE_CKCTL | DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
225 .enable_reg = DSP_IDLECT2,
226 .enable_bit = EN_PERCK,
227 .rate_offset = CKCTL_PERDIV_OFFSET,
228 .recalc = &followparent_recalc,
229 //.recalc = &ckctl_recalc,
230};
231
232static struct clk dspxor_ck = {
233 .name = "dspxor_ck",
234 .parent = &ck_ref,
235 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
236 DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
237 .enable_reg = DSP_IDLECT2,
238 .enable_bit = EN_XORPCK,
239 .recalc = &followparent_recalc,
240};
241
242static struct clk dsptim_ck = {
243 .name = "dsptim_ck",
244 .parent = &ck_ref,
245 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
246 DSP_DOMAIN_CLOCK | VIRTUAL_IO_ADDRESS,
247 .enable_reg = DSP_IDLECT2,
248 .enable_bit = EN_DSPTIMCK,
249 .recalc = &followparent_recalc,
250};
251
252static struct clk tc_ck = {
253 .name = "tc_ck",
254 .parent = &ck_dpll1,
255 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
256 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
257 .rate_offset = CKCTL_TCDIV_OFFSET,
258 .recalc = &ckctl_recalc,
259};
260
261static struct clk arminth_ck1510 = {
262 .name = "arminth_ck",
263 .parent = &tc_ck,
264 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
265 .recalc = &followparent_recalc,
266 /* Note: On 1510 the frequency follows TC_CK
267 *
268 * 16xx version is in MPU clocks.
269 */
270};
271
272static struct clk tipb_ck = {
273 .name = "tibp_ck",
274 .parent = &tc_ck,
275 .flags = CLOCK_IN_OMAP1510 | ALWAYS_ENABLED,
276 .recalc = &followparent_recalc,
277};
278
279static struct clk l3_ocpi_ck = {
280 .name = "l3_ocpi_ck",
281 .parent = &tc_ck,
282 .flags = CLOCK_IN_OMAP16XX,
283 .enable_reg = ARM_IDLECT3,
284 .enable_bit = EN_OCPI_CK,
285 .recalc = &followparent_recalc,
286};
287
288static struct clk tc1_ck = {
289 .name = "tc1_ck",
290 .parent = &tc_ck,
291 .flags = CLOCK_IN_OMAP16XX,
292 .enable_reg = ARM_IDLECT3,
293 .enable_bit = EN_TC1_CK,
294 .recalc = &followparent_recalc,
295};
296
297static struct clk tc2_ck = {
298 .name = "tc2_ck",
299 .parent = &tc_ck,
300 .flags = CLOCK_IN_OMAP16XX,
301 .enable_reg = ARM_IDLECT3,
302 .enable_bit = EN_TC2_CK,
303 .recalc = &followparent_recalc,
304};
305
306static struct clk dma_ck = {
307 .name = "dma_ck",
308 .parent = &tc_ck,
309 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
310 ALWAYS_ENABLED,
311 .recalc = &followparent_recalc,
312};
313
314static struct clk dma_lcdfree_ck = {
315 .name = "dma_lcdfree_ck",
316 .parent = &tc_ck,
317 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
318 .recalc = &followparent_recalc,
319};
320
321static struct clk api_ck = {
322 .name = "api_ck",
323 .parent = &tc_ck,
324 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
325 .enable_reg = ARM_IDLECT2,
326 .enable_bit = EN_APICK,
327 .recalc = &followparent_recalc,
328};
329
330static struct clk lb_ck = {
331 .name = "lb_ck",
332 .parent = &tc_ck,
333 .flags = CLOCK_IN_OMAP1510,
334 .enable_reg = ARM_IDLECT2,
335 .enable_bit = EN_LBCK,
336 .recalc = &followparent_recalc,
337};
338
339static struct clk rhea1_ck = {
340 .name = "rhea1_ck",
341 .parent = &tc_ck,
342 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
343 .recalc = &followparent_recalc,
344};
345
346static struct clk rhea2_ck = {
347 .name = "rhea2_ck",
348 .parent = &tc_ck,
349 .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED,
350 .recalc = &followparent_recalc,
351};
352
353static struct clk lcd_ck = {
354 .name = "lcd_ck",
355 .parent = &ck_dpll1,
356 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 |
357 RATE_CKCTL,
358 .enable_reg = ARM_IDLECT2,
359 .enable_bit = EN_LCDCK,
360 .rate_offset = CKCTL_LCDDIV_OFFSET,
361 .recalc = &ckctl_recalc,
362};
363
364static struct clk uart1_1510 = {
365 .name = "uart1_ck",
366 /* Direct from ULPD, no parent */
367 .rate = 12000000,
368 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
369 .enable_reg = MOD_CONF_CTRL_0,
370 .enable_bit = 29, /* Chooses between 12MHz and 48MHz */
371 .set_rate = &set_uart_rate,
372 .recalc = &uart_recalc,
373};
374
375static struct clk uart1_16xx = {
376 .name = "uart1_ck",
377 /* Direct from ULPD, no parent */
378 .rate = 48000000,
379 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
380 .enable_reg = MOD_CONF_CTRL_0,
381 .enable_bit = 29,
382};
383
384static struct clk uart2_ck = {
385 .name = "uart2_ck",
386 /* Direct from ULPD, no parent */
387 .rate = 12000000,
388 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ENABLE_REG_32BIT,
389 .enable_reg = MOD_CONF_CTRL_0,
390 .enable_bit = 30, /* Chooses between 12MHz and 48MHz */
391 .set_rate = &set_uart_rate,
392 .recalc = &uart_recalc,
393};
394
395static struct clk uart3_1510 = {
396 .name = "uart3_ck",
397 /* Direct from ULPD, no parent */
398 .rate = 12000000,
399 .flags = CLOCK_IN_OMAP1510 | ENABLE_REG_32BIT | ALWAYS_ENABLED,
400 .enable_reg = MOD_CONF_CTRL_0,
401 .enable_bit = 31, /* Chooses between 12MHz and 48MHz */
402 .set_rate = &set_uart_rate,
403 .recalc = &uart_recalc,
404};
405
406static struct clk uart3_16xx = {
407 .name = "uart3_ck",
408 /* Direct from ULPD, no parent */
409 .rate = 48000000,
410 .flags = CLOCK_IN_OMAP16XX | RATE_FIXED | ENABLE_REG_32BIT,
411 .enable_reg = MOD_CONF_CTRL_0,
412 .enable_bit = 31,
413};
414
415static struct clk usb_clko = { /* 6 MHz output on W4_USB_CLKO */
416 .name = "usb_clko",
417 /* Direct from ULPD, no parent */
418 .rate = 6000000,
419 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
420 RATE_FIXED | ENABLE_REG_32BIT,
421 .enable_reg = ULPD_CLOCK_CTRL,
422 .enable_bit = USB_MCLK_EN_BIT,
423};
424
425static struct clk usb_hhc_ck1510 = {
426 .name = "usb_hhc_ck",
427 /* Direct from ULPD, no parent */
428 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
429 .flags = CLOCK_IN_OMAP1510 |
430 RATE_FIXED | ENABLE_REG_32BIT,
431 .enable_reg = MOD_CONF_CTRL_0,
432 .enable_bit = USB_HOST_HHC_UHOST_EN,
433};
434
435static struct clk usb_hhc_ck16xx = {
436 .name = "usb_hhc_ck",
437 /* Direct from ULPD, no parent */
438 .rate = 48000000,
439 /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */
440 .flags = CLOCK_IN_OMAP16XX |
441 RATE_FIXED | ENABLE_REG_32BIT,
442 .enable_reg = OTG_BASE + 0x08 /* OTG_SYSCON_2 */,
443 .enable_bit = 8 /* UHOST_EN */,
444};
445
446static struct clk mclk_1510 = {
447 .name = "mclk",
448 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
449 .rate = 12000000,
450 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
451};
452
453static struct clk mclk_16xx = {
454 .name = "mclk",
455 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
456 .flags = CLOCK_IN_OMAP16XX,
457 .enable_reg = COM_CLK_DIV_CTRL_SEL,
458 .enable_bit = COM_ULPD_PLL_CLK_REQ,
459 .set_rate = &set_ext_clk_rate,
460 .round_rate = &round_ext_clk_rate,
461 .init = &init_ext_clk,
462};
463
464static struct clk bclk_1510 = {
465 .name = "bclk",
466 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
467 .rate = 12000000,
468 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
469};
470
471static struct clk bclk_16xx = {
472 .name = "bclk",
473 /* Direct from ULPD, no parent. May be enabled by ext hardware. */
474 .flags = CLOCK_IN_OMAP16XX,
475 .enable_reg = SWD_CLK_DIV_CTRL_SEL,
476 .enable_bit = SWD_ULPD_PLL_CLK_REQ,
477 .set_rate = &set_ext_clk_rate,
478 .round_rate = &round_ext_clk_rate,
479 .init = &init_ext_clk,
480};
481
482static struct clk mmc1_ck = {
483 .name = "mmc1_ck",
484 /* Functional clock is direct from ULPD, interface clock is ARMPER */
485 .parent = &armper_ck,
486 .rate = 48000000,
487 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
488 RATE_FIXED | ENABLE_REG_32BIT,
489 .enable_reg = MOD_CONF_CTRL_0,
490 .enable_bit = 23,
491};
492
493static struct clk mmc2_ck = {
494 .name = "mmc2_ck",
495 /* Functional clock is direct from ULPD, interface clock is ARMPER */
496 .parent = &armper_ck,
497 .rate = 48000000,
498 .flags = CLOCK_IN_OMAP16XX |
499 RATE_FIXED | ENABLE_REG_32BIT,
500 .enable_reg = MOD_CONF_CTRL_0,
501 .enable_bit = 20,
502};
503
504static struct clk virtual_ck_mpu = {
505 .name = "mpu",
506 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
507 VIRTUAL_CLOCK | ALWAYS_ENABLED,
508 .parent = &arm_ck, /* Is smarter alias for */
509 .recalc = &followparent_recalc,
510 .set_rate = &select_table_rate,
511 .round_rate = &round_to_table_rate,
512};
513
514
515static struct clk * onchip_clks[] = {
516 /* non-ULPD clocks */
517 &ck_ref,
518 &ck_dpll1,
519 /* CK_GEN1 clocks */
520 &ck_dpll1out,
521 &arm_ck,
522 &armper_ck,
523 &arm_gpio_ck,
524 &armxor_ck,
525 &armtim_ck,
526 &armwdt_ck,
527 &arminth_ck1510, &arminth_ck16xx,
528 /* CK_GEN2 clocks */
529 &dsp_ck,
530 &dspmmu_ck,
531 &dspper_ck,
532 &dspxor_ck,
533 &dsptim_ck,
534 /* CK_GEN3 clocks */
535 &tc_ck,
536 &tipb_ck,
537 &l3_ocpi_ck,
538 &tc1_ck,
539 &tc2_ck,
540 &dma_ck,
541 &dma_lcdfree_ck,
542 &api_ck,
543 &lb_ck,
544 &rhea1_ck,
545 &rhea2_ck,
546 &lcd_ck,
547 /* ULPD clocks */
548 &uart1_1510,
549 &uart1_16xx,
550 &uart2_ck,
551 &uart3_1510,
552 &uart3_16xx,
553 &usb_clko,
554 &usb_hhc_ck1510, &usb_hhc_ck16xx,
555 &mclk_1510, &mclk_16xx,
556 &bclk_1510, &bclk_16xx,
557 &mmc1_ck,
558 &mmc2_ck,
559 /* Virtual clocks */
560 &virtual_ck_mpu,
561};
562
563struct clk *clk_get(struct device *dev, const char *id)
564{
565 struct clk *p, *clk = ERR_PTR(-ENOENT);
566
567 down(&clocks_sem);
568 list_for_each_entry(p, &clocks, node) {
569 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
570 clk = p;
571 break;
572 }
573 }
574 up(&clocks_sem);
575
576 return clk;
577}
578EXPORT_SYMBOL(clk_get);
579
580
581void clk_put(struct clk *clk)
582{
583 if (clk && !IS_ERR(clk))
584 module_put(clk->owner);
585}
586EXPORT_SYMBOL(clk_put);
587
588
589int __clk_enable(struct clk *clk)
590{
591 __u16 regval16;
592 __u32 regval32;
593
594 if (clk->flags & ALWAYS_ENABLED)
595 return 0;
596
597 if (unlikely(clk->enable_reg == 0)) {
598 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
599 clk->name);
600 return 0;
601 }
602
603 if (clk->flags & DSP_DOMAIN_CLOCK) {
604 __clk_use(&api_ck);
605 }
606
607 if (clk->flags & ENABLE_REG_32BIT) {
608 if (clk->flags & VIRTUAL_IO_ADDRESS) {
609 regval32 = __raw_readl(clk->enable_reg);
610 regval32 |= (1 << clk->enable_bit);
611 __raw_writel(regval32, clk->enable_reg);
612 } else {
613 regval32 = omap_readl(clk->enable_reg);
614 regval32 |= (1 << clk->enable_bit);
615 omap_writel(regval32, clk->enable_reg);
616 }
617 } else {
618 if (clk->flags & VIRTUAL_IO_ADDRESS) {
619 regval16 = __raw_readw(clk->enable_reg);
620 regval16 |= (1 << clk->enable_bit);
621 __raw_writew(regval16, clk->enable_reg);
622 } else {
623 regval16 = omap_readw(clk->enable_reg);
624 regval16 |= (1 << clk->enable_bit);
625 omap_writew(regval16, clk->enable_reg);
626 }
627 }
628
629 if (clk->flags & DSP_DOMAIN_CLOCK) {
630 __clk_unuse(&api_ck);
631 }
632
633 return 0;
634}
635
636
637void __clk_disable(struct clk *clk)
638{
639 __u16 regval16;
640 __u32 regval32;
641
642 if (clk->enable_reg == 0)
643 return;
644
645 if (clk->flags & DSP_DOMAIN_CLOCK) {
646 __clk_use(&api_ck);
647 }
648
649 if (clk->flags & ENABLE_REG_32BIT) {
650 if (clk->flags & VIRTUAL_IO_ADDRESS) {
651 regval32 = __raw_readl(clk->enable_reg);
652 regval32 &= ~(1 << clk->enable_bit);
653 __raw_writel(regval32, clk->enable_reg);
654 } else {
655 regval32 = omap_readl(clk->enable_reg);
656 regval32 &= ~(1 << clk->enable_bit);
657 omap_writel(regval32, clk->enable_reg);
658 }
659 } else {
660 if (clk->flags & VIRTUAL_IO_ADDRESS) {
661 regval16 = __raw_readw(clk->enable_reg);
662 regval16 &= ~(1 << clk->enable_bit);
663 __raw_writew(regval16, clk->enable_reg);
664 } else {
665 regval16 = omap_readw(clk->enable_reg);
666 regval16 &= ~(1 << clk->enable_bit);
667 omap_writew(regval16, clk->enable_reg);
668 }
669 }
670
671 if (clk->flags & DSP_DOMAIN_CLOCK) {
672 __clk_unuse(&api_ck);
673 }
674}
675
676
677void __clk_unuse(struct clk *clk)
678{
679 if (clk->usecount > 0 && !(--clk->usecount)) {
680 __clk_disable(clk);
681 if (likely(clk->parent))
682 __clk_unuse(clk->parent);
683 }
684}
685
686
687int __clk_use(struct clk *clk)
688{
689 int ret = 0;
690 if (clk->usecount++ == 0) {
691 if (likely(clk->parent))
692 ret = __clk_use(clk->parent);
693
694 if (unlikely(ret != 0)) {
695 clk->usecount--;
696 return ret;
697 }
698
699 ret = __clk_enable(clk);
700
701 if (unlikely(ret != 0) && clk->parent) {
702 __clk_unuse(clk->parent);
703 clk->usecount--;
704 }
705 }
706
707 return ret;
708}
709
710
711int clk_enable(struct clk *clk)
712{
713 unsigned long flags;
714 int ret;
715
716 spin_lock_irqsave(&clockfw_lock, flags);
717 ret = __clk_enable(clk);
718 spin_unlock_irqrestore(&clockfw_lock, flags);
719 return ret;
720}
721EXPORT_SYMBOL(clk_enable);
722
723
724void clk_disable(struct clk *clk)
725{
726 unsigned long flags;
727
728 spin_lock_irqsave(&clockfw_lock, flags);
729 __clk_disable(clk);
730 spin_unlock_irqrestore(&clockfw_lock, flags);
731}
732EXPORT_SYMBOL(clk_disable);
733
734
735int clk_use(struct clk *clk)
736{
737 unsigned long flags;
738 int ret = 0;
739
740 spin_lock_irqsave(&clockfw_lock, flags);
741 ret = __clk_use(clk);
742 spin_unlock_irqrestore(&clockfw_lock, flags);
743 return ret;
744}
745EXPORT_SYMBOL(clk_use);
746
747
748void clk_unuse(struct clk *clk)
749{
750 unsigned long flags;
751
752 spin_lock_irqsave(&clockfw_lock, flags);
753 __clk_unuse(clk);
754 spin_unlock_irqrestore(&clockfw_lock, flags);
755}
756EXPORT_SYMBOL(clk_unuse);
757
758
759int clk_get_usecount(struct clk *clk)
760{
761 return clk->usecount;
762}
763EXPORT_SYMBOL(clk_get_usecount);
764
765
766unsigned long clk_get_rate(struct clk *clk)
767{
768 return clk->rate;
769}
770EXPORT_SYMBOL(clk_get_rate);
771
772
773static __u16 verify_ckctl_value(__u16 newval)
774{
775 /* This function checks for following limitations set
776 * by the hardware (all conditions must be true):
777 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
778 * ARM_CK >= TC_CK
779 * DSP_CK >= TC_CK
780 * DSPMMU_CK >= TC_CK
781 *
782 * In addition following rules are enforced:
783 * LCD_CK <= TC_CK
784 * ARMPER_CK <= TC_CK
785 *
786 * However, maximum frequencies are not checked for!
787 */
788 __u8 per_exp;
789 __u8 lcd_exp;
790 __u8 arm_exp;
791 __u8 dsp_exp;
792 __u8 tc_exp;
793 __u8 dspmmu_exp;
794
795 per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
796 lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
797 arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
798 dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
799 tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
800 dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
801
802 if (dspmmu_exp < dsp_exp)
803 dspmmu_exp = dsp_exp;
804 if (dspmmu_exp > dsp_exp+1)
805 dspmmu_exp = dsp_exp+1;
806 if (tc_exp < arm_exp)
807 tc_exp = arm_exp;
808 if (tc_exp < dspmmu_exp)
809 tc_exp = dspmmu_exp;
810 if (tc_exp > lcd_exp)
811 lcd_exp = tc_exp;
812 if (tc_exp > per_exp)
813 per_exp = tc_exp;
814
815 newval &= 0xf000;
816 newval |= per_exp << CKCTL_PERDIV_OFFSET;
817 newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
818 newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
819 newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
820 newval |= tc_exp << CKCTL_TCDIV_OFFSET;
821 newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
822
823 return newval;
824}
825
826
827static int calc_dsor_exp(struct clk *clk, unsigned long rate)
828{
829 /* Note: If target frequency is too low, this function will return 4,
830 * which is invalid value. Caller must check for this value and act
831 * accordingly.
832 *
833 * Note: This function does not check for following limitations set
834 * by the hardware (all conditions must be true):
835 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
836 * ARM_CK >= TC_CK
837 * DSP_CK >= TC_CK
838 * DSPMMU_CK >= TC_CK
839 */
840 unsigned long realrate;
841 struct clk * parent;
842 unsigned dsor_exp;
843
844 if (unlikely(!(clk->flags & RATE_CKCTL)))
845 return -EINVAL;
846
847 parent = clk->parent;
848 if (unlikely(parent == 0))
849 return -EIO;
850
851 realrate = parent->rate;
852 for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
853 if (realrate <= rate)
854 break;
855
856 realrate /= 2;
857 }
858
859 return dsor_exp;
860}
861
862
863static void ckctl_recalc(struct clk * clk)
864{
865 int dsor;
866
867 /* Calculate divisor encoded as 2-bit exponent */
868 if (clk->flags & DSP_DOMAIN_CLOCK) {
869 /* The clock control bits are in DSP domain,
870 * so api_ck is needed for access.
871 * Note that DSP_CKCTL virt addr = phys addr, so
872 * we must use __raw_readw() instead of omap_readw().
873 */
874 __clk_use(&api_ck);
875 dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
876 __clk_unuse(&api_ck);
877 } else {
878 dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
879 }
880 if (unlikely(clk->rate == clk->parent->rate / dsor))
881 return; /* No change, quick exit */
882 clk->rate = clk->parent->rate / dsor;
883
884 if (unlikely(clk->flags & RATE_PROPAGATES))
885 propagate_rate(clk);
886}
887
888
889long clk_round_rate(struct clk *clk, unsigned long rate)
890{
891 int dsor_exp;
892
893 if (clk->flags & RATE_FIXED)
894 return clk->rate;
895
896 if (clk->flags & RATE_CKCTL) {
897 dsor_exp = calc_dsor_exp(clk, rate);
898 if (dsor_exp < 0)
899 return dsor_exp;
900 if (dsor_exp > 3)
901 dsor_exp = 3;
902 return clk->parent->rate / (1 << dsor_exp);
903 }
904
905 if(clk->round_rate != 0)
906 return clk->round_rate(clk, rate);
907
908 return clk->rate;
909}
910EXPORT_SYMBOL(clk_round_rate);
911
912
913static void propagate_rate(struct clk * clk)
914{
915 struct clk ** clkp;
916
917 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
918 if (likely((*clkp)->parent != clk)) continue;
919 if (likely((*clkp)->recalc))
920 (*clkp)->recalc(*clkp);
921 }
922}
923
924
925static int select_table_rate(struct clk * clk, unsigned long rate)
926{
927 /* Find the highest supported frequency <= rate and switch to it */
928 struct mpu_rate * ptr;
929
930 if (clk != &virtual_ck_mpu)
931 return -EINVAL;
932
933 for (ptr = rate_table; ptr->rate; ptr++) {
934 if (ptr->xtal != ck_ref.rate)
935 continue;
936
937 /* DPLL1 cannot be reprogrammed without risking system crash */
938 if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
939 continue;
940
941 /* Can check only after xtal frequency check */
942 if (ptr->rate <= rate)
943 break;
944 }
945
946 if (!ptr->rate)
947 return -EINVAL;
948
949 if (!ptr->rate)
950 return -EINVAL;
951
952 if (unlikely(ck_dpll1.rate == 0)) {
953 omap_writew(ptr->dpllctl_val, DPLL_CTL);
954 ck_dpll1.rate = ptr->pll_rate;
955 }
956 omap_writew(ptr->ckctl_val, ARM_CKCTL);
957 propagate_rate(&ck_dpll1);
958 return 0;
959}
960
961
962static long round_to_table_rate(struct clk * clk, unsigned long rate)
963{
964 /* Find the highest supported frequency <= rate */
965 struct mpu_rate * ptr;
966 long highest_rate;
967
968 if (clk != &virtual_ck_mpu)
969 return -EINVAL;
970
971 highest_rate = -EINVAL;
972
973 for (ptr = rate_table; ptr->rate; ptr++) {
974 if (ptr->xtal != ck_ref.rate)
975 continue;
976
977 highest_rate = ptr->rate;
978
979 /* Can check only after xtal frequency check */
980 if (ptr->rate <= rate)
981 break;
982 }
983
984 return highest_rate;
985}
986
987
988int clk_set_rate(struct clk *clk, unsigned long rate)
989{
990 int ret = -EINVAL;
991 int dsor_exp;
992 __u16 regval;
993 unsigned long flags;
994
995 if (clk->flags & RATE_CKCTL) {
996 dsor_exp = calc_dsor_exp(clk, rate);
997 if (dsor_exp > 3)
998 dsor_exp = -EINVAL;
999 if (dsor_exp < 0)
1000 return dsor_exp;
1001
1002 spin_lock_irqsave(&clockfw_lock, flags);
1003 regval = omap_readw(ARM_CKCTL);
1004 regval &= ~(3 << clk->rate_offset);
1005 regval |= dsor_exp << clk->rate_offset;
1006 regval = verify_ckctl_value(regval);
1007 omap_writew(regval, ARM_CKCTL);
1008 clk->rate = clk->parent->rate / (1 << dsor_exp);
1009 spin_unlock_irqrestore(&clockfw_lock, flags);
1010 ret = 0;
1011 } else if(clk->set_rate != 0) {
1012 spin_lock_irqsave(&clockfw_lock, flags);
1013 ret = clk->set_rate(clk, rate);
1014 spin_unlock_irqrestore(&clockfw_lock, flags);
1015 }
1016
1017 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
1018 propagate_rate(clk);
1019
1020 return ret;
1021}
1022EXPORT_SYMBOL(clk_set_rate);
1023
1024
1025static unsigned calc_ext_dsor(unsigned long rate)
1026{
1027 unsigned dsor;
1028
1029 /* MCLK and BCLK divisor selection is not linear:
1030 * freq = 96MHz / dsor
1031 *
1032 * RATIO_SEL range: dsor <-> RATIO_SEL
1033 * 0..6: (RATIO_SEL+2) <-> (dsor-2)
1034 * 6..48: (8+(RATIO_SEL-6)*2) <-> ((dsor-8)/2+6)
1035 * Minimum dsor is 2 and maximum is 96. Odd divisors starting from 9
1036 * can not be used.
1037 */
1038 for (dsor = 2; dsor < 96; ++dsor) {
1039 if ((dsor & 1) && dsor > 8)
1040 continue;
1041 if (rate >= 96000000 / dsor)
1042 break;
1043 }
1044 return dsor;
1045}
1046
1047/* Only needed on 1510 */
1048static int set_uart_rate(struct clk * clk, unsigned long rate)
1049{
1050 unsigned int val;
1051
1052 val = omap_readl(clk->enable_reg);
1053 if (rate == 12000000)
1054 val &= ~(1 << clk->enable_bit);
1055 else if (rate == 48000000)
1056 val |= (1 << clk->enable_bit);
1057 else
1058 return -EINVAL;
1059 omap_writel(val, clk->enable_reg);
1060 clk->rate = rate;
1061
1062 return 0;
1063}
1064
1065static int set_ext_clk_rate(struct clk * clk, unsigned long rate)
1066{
1067 unsigned dsor;
1068 __u16 ratio_bits;
1069
1070 dsor = calc_ext_dsor(rate);
1071 clk->rate = 96000000 / dsor;
1072 if (dsor > 8)
1073 ratio_bits = ((dsor - 8) / 2 + 6) << 2;
1074 else
1075 ratio_bits = (dsor - 2) << 2;
1076
1077 ratio_bits |= omap_readw(clk->enable_reg) & ~0xfd;
1078 omap_writew(ratio_bits, clk->enable_reg);
1079
1080 return 0;
1081}
1082
1083
1084static long round_ext_clk_rate(struct clk * clk, unsigned long rate)
1085{
1086 return 96000000 / calc_ext_dsor(rate);
1087}
1088
1089
1090static void init_ext_clk(struct clk * clk)
1091{
1092 unsigned dsor;
1093 __u16 ratio_bits;
1094
1095 /* Determine current rate and ensure clock is based on 96MHz APLL */
1096 ratio_bits = omap_readw(clk->enable_reg) & ~1;
1097 omap_writew(ratio_bits, clk->enable_reg);
1098
1099 ratio_bits = (ratio_bits & 0xfc) >> 2;
1100 if (ratio_bits > 6)
1101 dsor = (ratio_bits - 6) * 2 + 8;
1102 else
1103 dsor = ratio_bits + 2;
1104
1105 clk-> rate = 96000000 / dsor;
1106}
1107
1108
1109int clk_register(struct clk *clk)
1110{
1111 down(&clocks_sem);
1112 list_add(&clk->node, &clocks);
1113 if (clk->init)
1114 clk->init(clk);
1115 up(&clocks_sem);
1116 return 0;
1117}
1118EXPORT_SYMBOL(clk_register);
1119
1120void clk_unregister(struct clk *clk)
1121{
1122 down(&clocks_sem);
1123 list_del(&clk->node);
1124 up(&clocks_sem);
1125}
1126EXPORT_SYMBOL(clk_unregister);
1127
1128#ifdef CONFIG_OMAP_RESET_CLOCKS
1129/*
1130 * Resets some clocks that may be left on from bootloader,
1131 * but leaves serial clocks on. See also omap_late_clk_reset().
1132 */
1133static inline void omap_early_clk_reset(void)
1134{
1135 //omap_writel(0x3 << 29, MOD_CONF_CTRL_0);
1136}
1137#else
1138#define omap_early_clk_reset() {}
1139#endif
1140
1141int __init clk_init(void)
1142{
1143 struct clk ** clkp;
1144 const struct omap_clock_config *info;
1145 int crystal_type = 0; /* Default 12 MHz */
1146
1147 omap_early_clk_reset();
1148
1149 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
1150 if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
1151 clk_register(*clkp);
1152 continue;
1153 }
1154
1155 if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
1156 clk_register(*clkp);
1157 continue;
1158 }
1159
1160 if (((*clkp)->flags &CLOCK_IN_OMAP730) && cpu_is_omap730()) {
1161 clk_register(*clkp);
1162 continue;
1163 }
1164 }
1165
1166 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
1167 if (info != NULL) {
1168 if (!cpu_is_omap1510())
1169 crystal_type = info->system_clock_type;
1170 }
1171
1172#if defined(CONFIG_ARCH_OMAP730)
1173 ck_ref.rate = 13000000;
1174#elif defined(CONFIG_ARCH_OMAP16XX)
1175 if (crystal_type == 2)
1176 ck_ref.rate = 19200000;
1177#endif
1178
1179 printk("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n",
1180 omap_readw(ARM_SYSST), omap_readw(DPLL_CTL),
1181 omap_readw(ARM_CKCTL));
1182
1183 /* We want to be in syncronous scalable mode */
1184 omap_writew(0x1000, ARM_SYSST);
1185
1186#ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER
1187 /* Use values set by bootloader. Determine PLL rate and recalculate
1188 * dependent clocks as if kernel had changed PLL or divisors.
1189 */
1190 {
1191 unsigned pll_ctl_val = omap_readw(DPLL_CTL);
1192
1193 ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */
1194 if (pll_ctl_val & 0x10) {
1195 /* PLL enabled, apply multiplier and divisor */
1196 if (pll_ctl_val & 0xf80)
1197 ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7;
1198 ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1;
1199 } else {
1200 /* PLL disabled, apply bypass divisor */
1201 switch (pll_ctl_val & 0xc) {
1202 case 0:
1203 break;
1204 case 0x4:
1205 ck_dpll1.rate /= 2;
1206 break;
1207 default:
1208 ck_dpll1.rate /= 4;
1209 break;
1210 }
1211 }
1212 }
1213 propagate_rate(&ck_dpll1);
1214#else
1215 /* Find the highest supported frequency and enable it */
1216 if (select_table_rate(&virtual_ck_mpu, ~0)) {
1217 printk(KERN_ERR "System frequencies not set. Check your config.\n");
1218 /* Guess sane values (60MHz) */
1219 omap_writew(0x2290, DPLL_CTL);
1220 omap_writew(0x1005, ARM_CKCTL);
1221 ck_dpll1.rate = 60000000;
1222 propagate_rate(&ck_dpll1);
1223 }
1224#endif
1225 /* Cache rates for clocks connected to ck_ref (not dpll1) */
1226 propagate_rate(&ck_ref);
1227 printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld.%01ld/%ld/%ld MHz\n",
1228 ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,
1229 ck_dpll1.rate, arm_ck.rate);
1230
1231#ifdef CONFIG_MACH_OMAP_PERSEUS2
1232 /* Select slicer output as OMAP input clock */
1233 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
1234#endif
1235
1236 /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
1237 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
1238
1239 /* Put DSP/MPUI into reset until needed */
1240 omap_writew(0, ARM_RSTCT1);
1241 omap_writew(1, ARM_RSTCT2);
1242 omap_writew(0x400, ARM_IDLECT1);
1243
1244 /*
1245 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
1246 * of the ARM_IDLECT2 register must be set to zero. The power-on
1247 * default value of this bit is one.
1248 */
1249 omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
1250
1251 /*
1252 * Only enable those clocks we will need, let the drivers
1253 * enable other clocks as necessary
1254 */
1255 clk_use(&armper_ck);
1256 clk_use(&armxor_ck);
1257 clk_use(&armtim_ck);
1258
1259 if (cpu_is_omap1510())
1260 clk_enable(&arm_gpio_ck);
1261
1262 return 0;
1263}
1264
1265
1266#ifdef CONFIG_OMAP_RESET_CLOCKS
1267
1268static int __init omap_late_clk_reset(void)
1269{
1270 /* Turn off all unused clocks */
1271 struct clk *p;
1272 __u32 regval32;
1273
1274 omap_writew(0, SOFT_REQ_REG);
1275 omap_writew(0, SOFT_REQ_REG2);
1276
1277 list_for_each_entry(p, &clocks, node) {
1278 if (p->usecount > 0 || (p->flags & ALWAYS_ENABLED) ||
1279 p->enable_reg == 0)
1280 continue;
1281
1282 /* Assume no DSP clocks have been activated by bootloader */
1283 if (p->flags & DSP_DOMAIN_CLOCK)
1284 continue;
1285
1286 /* Is the clock already disabled? */
1287 if (p->flags & ENABLE_REG_32BIT) {
1288 if (p->flags & VIRTUAL_IO_ADDRESS)
1289 regval32 = __raw_readl(p->enable_reg);
1290 else
1291 regval32 = omap_readl(p->enable_reg);
1292 } else {
1293 if (p->flags & VIRTUAL_IO_ADDRESS)
1294 regval32 = __raw_readw(p->enable_reg);
1295 else
1296 regval32 = omap_readw(p->enable_reg);
1297 }
1298
1299 if ((regval32 & (1 << p->enable_bit)) == 0)
1300 continue;
1301
1302 /* FIXME: This clock seems to be necessary but no-one
1303 * has asked for its activation. */
1304 if (p == &tc2_ck // FIX: pm.c (SRAM), CCP, Camera
1305 || p == &ck_dpll1out // FIX: SoSSI, SSR
1306 || p == &arm_gpio_ck // FIX: GPIO code for 1510
1307 ) {
1308 printk(KERN_INFO "FIXME: Clock \"%s\" seems unused\n",
1309 p->name);
1310 continue;
1311 }
1312
1313 printk(KERN_INFO "Disabling unused clock \"%s\"... ", p->name);
1314 __clk_disable(p);
1315 printk(" done\n");
1316 }
1317
1318 return 0;
1319}
1320
1321late_initcall(omap_late_clk_reset);
1322
1323#endif
diff --git a/arch/arm/plat-omap/clock.h b/arch/arm/plat-omap/clock.h
new file mode 100644
index 000000000000..a89e1e8c2519
--- /dev/null
+++ b/arch/arm/plat-omap/clock.h
@@ -0,0 +1,120 @@
1/*
2 * linux/arch/arm/plat-omap/clock.h
3 *
4 * Copyright (C) 2004 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
6 * Based on clocks.h by Tony Lindgren, Gordon McNutt and RidgeRun, Inc
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
13#ifndef __ARCH_ARM_OMAP_CLOCK_H
14#define __ARCH_ARM_OMAP_CLOCK_H
15
16struct module;
17
18struct clk {
19 struct list_head node;
20 struct module *owner;
21 const char *name;
22 struct clk *parent;
23 unsigned long rate;
24 __s8 usecount;
25 __u16 flags;
26 __u32 enable_reg;
27 __u8 enable_bit;
28 __u8 rate_offset;
29 void (*recalc)(struct clk *);
30 int (*set_rate)(struct clk *, unsigned long);
31 long (*round_rate)(struct clk *, unsigned long);
32 void (*init)(struct clk *);
33};
34
35
36struct mpu_rate {
37 unsigned long rate;
38 unsigned long xtal;
39 unsigned long pll_rate;
40 __u16 ckctl_val;
41 __u16 dpllctl_val;
42};
43
44
45/* Clock flags */
46#define RATE_CKCTL 1
47#define RATE_FIXED 2
48#define RATE_PROPAGATES 4
49#define VIRTUAL_CLOCK 8
50#define ALWAYS_ENABLED 16
51#define ENABLE_REG_32BIT 32
52#define CLOCK_IN_OMAP16XX 64
53#define CLOCK_IN_OMAP1510 128
54#define CLOCK_IN_OMAP730 256
55#define DSP_DOMAIN_CLOCK 512
56#define VIRTUAL_IO_ADDRESS 1024
57
58/* ARM_CKCTL bit shifts */
59#define CKCTL_PERDIV_OFFSET 0
60#define CKCTL_LCDDIV_OFFSET 2
61#define CKCTL_ARMDIV_OFFSET 4
62#define CKCTL_DSPDIV_OFFSET 6
63#define CKCTL_TCDIV_OFFSET 8
64#define CKCTL_DSPMMUDIV_OFFSET 10
65/*#define ARM_TIMXO 12*/
66#define EN_DSPCK 13
67/*#define ARM_INTHCK_SEL 14*/ /* Divide-by-2 for mpu inth_ck */
68/* DSP_CKCTL bit shifts */
69#define CKCTL_DSPPERDIV_OFFSET 0
70
71/* ARM_IDLECT1 bit shifts */
72/*#define IDLWDT_ARM 0*/
73/*#define IDLXORP_ARM 1*/
74/*#define IDLPER_ARM 2*/
75/*#define IDLLCD_ARM 3*/
76/*#define IDLLB_ARM 4*/
77/*#define IDLHSAB_ARM 5*/
78/*#define IDLIF_ARM 6*/
79/*#define IDLDPLL_ARM 7*/
80/*#define IDLAPI_ARM 8*/
81/*#define IDLTIM_ARM 9*/
82/*#define SETARM_IDLE 11*/
83
84/* ARM_IDLECT2 bit shifts */
85#define EN_WDTCK 0
86#define EN_XORPCK 1
87#define EN_PERCK 2
88#define EN_LCDCK 3
89#define EN_LBCK 4 /* Not on 1610/1710 */
90/*#define EN_HSABCK 5*/
91#define EN_APICK 6
92#define EN_TIMCK 7
93#define DMACK_REQ 8
94#define EN_GPIOCK 9 /* Not on 1610/1710 */
95/*#define EN_LBFREECK 10*/
96#define EN_CKOUT_ARM 11
97
98/* ARM_IDLECT3 bit shifts */
99#define EN_OCPI_CK 0
100#define EN_TC1_CK 2
101#define EN_TC2_CK 4
102
103/* DSP_IDLECT2 bit shifts (0,1,2 are same as for ARM_IDLECT2) */
104#define EN_DSPTIMCK 5
105
106/* Various register defines for clock controls scattered around OMAP chip */
107#define USB_MCLK_EN_BIT 4 /* In ULPD_CLKC_CTRL */
108#define USB_HOST_HHC_UHOST_EN 9 /* In MOD_CONF_CTRL_0 */
109#define SWD_ULPD_PLL_CLK_REQ 1 /* In SWD_CLK_DIV_CTRL_SEL */
110#define COM_ULPD_PLL_CLK_REQ 1 /* In COM_CLK_DIV_CTRL_SEL */
111#define SWD_CLK_DIV_CTRL_SEL 0xfffe0874
112#define COM_CLK_DIV_CTRL_SEL 0xfffe0878
113#define SOFT_REQ_REG 0xfffe0834
114#define SOFT_REQ_REG2 0xfffe0880
115
116int clk_register(struct clk *clk);
117void clk_unregister(struct clk *clk);
118int clk_init(void);
119
120#endif
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/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
new file mode 100644
index 000000000000..409aac2c4b9d
--- /dev/null
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -0,0 +1,128 @@
1/*
2 * linux/arch/arm/plat-omap/cpu-omap.c
3 *
4 * CPU frequency scaling for OMAP
5 *
6 * Copyright (C) 2005 Nokia Corporation
7 * Written by Tony Lindgren <tony@atomide.com>
8 *
9 * Based on cpu-sa1110.c, Copyright (C) 2001 Russell King
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 version 2 as
13 * published by the Free Software Foundation.
14 */
15#include <linux/types.h>
16#include <linux/kernel.h>
17#include <linux/sched.h>
18#include <linux/cpufreq.h>
19#include <linux/delay.h>
20#include <linux/init.h>
21#include <linux/err.h>
22
23#include <asm/hardware.h>
24#include <asm/mach-types.h>
25#include <asm/io.h>
26#include <asm/system.h>
27
28#include <asm/hardware/clock.h>
29
30/* TODO: Add support for SDRAM timing changes */
31
32int omap_verify_speed(struct cpufreq_policy *policy)
33{
34 struct clk * mpu_clk;
35
36 if (policy->cpu)
37 return -EINVAL;
38
39 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
40 policy->cpuinfo.max_freq);
41 mpu_clk = clk_get(NULL, "mpu");
42 if (IS_ERR(mpu_clk))
43 return PTR_ERR(mpu_clk);
44 policy->min = clk_round_rate(mpu_clk, policy->min * 1000) / 1000;
45 policy->max = clk_round_rate(mpu_clk, policy->max * 1000) / 1000;
46 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
47 policy->cpuinfo.max_freq);
48 clk_put(mpu_clk);
49
50 return 0;
51}
52
53unsigned int omap_getspeed(unsigned int cpu)
54{
55 struct clk * mpu_clk;
56 unsigned long rate;
57
58 if (cpu)
59 return 0;
60
61 mpu_clk = clk_get(NULL, "mpu");
62 if (IS_ERR(mpu_clk))
63 return 0;
64 rate = clk_get_rate(mpu_clk) / 1000;
65 clk_put(mpu_clk);
66
67 return rate;
68}
69
70static int omap_target(struct cpufreq_policy *policy,
71 unsigned int target_freq,
72 unsigned int relation)
73{
74 struct clk * mpu_clk;
75 struct cpufreq_freqs freqs;
76 int ret = 0;
77
78 mpu_clk = clk_get(NULL, "mpu");
79 if (IS_ERR(mpu_clk))
80 return PTR_ERR(mpu_clk);
81
82 freqs.old = omap_getspeed(0);
83 freqs.new = clk_round_rate(mpu_clk, target_freq * 1000) / 1000;
84 freqs.cpu = 0;
85
86 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
87 ret = clk_set_rate(mpu_clk, target_freq * 1000);
88 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
89 clk_put(mpu_clk);
90
91 return ret;
92}
93
94static int __init omap_cpu_init(struct cpufreq_policy *policy)
95{
96 struct clk * mpu_clk;
97
98 mpu_clk = clk_get(NULL, "mpu");
99 if (IS_ERR(mpu_clk))
100 return PTR_ERR(mpu_clk);
101
102 if (policy->cpu != 0)
103 return -EINVAL;
104 policy->cur = policy->min = policy->max = omap_getspeed(0);
105 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
106 policy->cpuinfo.min_freq = clk_round_rate(mpu_clk, 0) / 1000;
107 policy->cpuinfo.max_freq = clk_round_rate(mpu_clk, 216000000) / 1000;
108 policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
109 clk_put(mpu_clk);
110
111 return 0;
112}
113
114static struct cpufreq_driver omap_driver = {
115 .flags = CPUFREQ_STICKY,
116 .verify = omap_verify_speed,
117 .target = omap_target,
118 .get = omap_getspeed,
119 .init = omap_cpu_init,
120 .name = "omap",
121};
122
123static int __init omap_cpufreq_init(void)
124{
125 return cpufreq_register_driver(&omap_driver);
126}
127
128arch_initcall(omap_cpufreq_init);
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
new file mode 100644
index 000000000000..c0a5c2fa42bd
--- /dev/null
+++ b/arch/arm/plat-omap/dma.c
@@ -0,0 +1,1116 @@
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.callback != NULL)
798 w |= 1 << 1; /* Block interrupt enable */
799 else
800 w &= ~(1 << 1);
801 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
802
803 if (!(lcd_dma.rotate || lcd_dma.mirror ||
804 lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
805 return;
806
807 w = omap_readw(OMAP1610_DMA_LCD_CCR);
808 /* Set the double-indexed addressing mode */
809 w |= (0x03 << 12);
810 omap_writew(w, OMAP1610_DMA_LCD_CCR);
811
812 omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
813 omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
814 omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
815}
816
817static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
818{
819 u16 w;
820
821 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
822 if (unlikely(!(w & (1 << 3)))) {
823 printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
824 return IRQ_NONE;
825 }
826 /* Ack the IRQ */
827 w |= (1 << 3);
828 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
829 lcd_dma.active = 0;
830 if (lcd_dma.callback != NULL)
831 lcd_dma.callback(w, lcd_dma.cb_data);
832
833 return IRQ_HANDLED;
834}
835
836int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
837 void *data)
838{
839 spin_lock_irq(&lcd_dma.lock);
840 if (lcd_dma.reserved) {
841 spin_unlock_irq(&lcd_dma.lock);
842 printk(KERN_ERR "LCD DMA channel already reserved\n");
843 BUG();
844 return -EBUSY;
845 }
846 lcd_dma.reserved = 1;
847 spin_unlock_irq(&lcd_dma.lock);
848 lcd_dma.callback = callback;
849 lcd_dma.cb_data = data;
850 lcd_dma.active = 0;
851 lcd_dma.single_transfer = 0;
852 lcd_dma.rotate = 0;
853 lcd_dma.vxres = 0;
854 lcd_dma.mirror = 0;
855 lcd_dma.xscale = 0;
856 lcd_dma.yscale = 0;
857 lcd_dma.ext_ctrl = 0;
858 lcd_dma.src_port = 0;
859
860 return 0;
861}
862
863void omap_free_lcd_dma(void)
864{
865 spin_lock(&lcd_dma.lock);
866 if (!lcd_dma.reserved) {
867 spin_unlock(&lcd_dma.lock);
868 printk(KERN_ERR "LCD DMA is not reserved\n");
869 BUG();
870 return;
871 }
872 if (!enable_1510_mode)
873 omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1, OMAP1610_DMA_LCD_CCR);
874 lcd_dma.reserved = 0;
875 spin_unlock(&lcd_dma.lock);
876}
877
878void omap_enable_lcd_dma(void)
879{
880 u16 w;
881
882 /* Set the Enable bit only if an external controller is
883 * connected. Otherwise the OMAP internal controller will
884 * start the transfer when it gets enabled.
885 */
886 if (enable_1510_mode || !lcd_dma.ext_ctrl)
887 return;
888
889 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
890 w |= 1 << 8;
891 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
892
893 w = omap_readw(OMAP1610_DMA_LCD_CCR);
894 w |= 1 << 7;
895 omap_writew(w, OMAP1610_DMA_LCD_CCR);
896
897 lcd_dma.active = 1;
898}
899
900void omap_setup_lcd_dma(void)
901{
902 BUG_ON(lcd_dma.active);
903 if (!enable_1510_mode) {
904 /* Set some reasonable defaults */
905 omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
906 omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
907 omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
908 }
909 set_b1_regs();
910 if (!enable_1510_mode) {
911 u16 w;
912
913 w = omap_readw(OMAP1610_DMA_LCD_CCR);
914 /* If DMA was already active set the end_prog bit to have
915 * the programmed register set loaded into the active
916 * register set.
917 */
918 w |= 1 << 11; /* End_prog */
919 if (!lcd_dma.single_transfer)
920 w |= (3 << 8); /* Auto_init, repeat */
921 omap_writew(w, OMAP1610_DMA_LCD_CCR);
922 }
923}
924
925void omap_stop_lcd_dma(void)
926{
927 u16 w;
928
929 lcd_dma.active = 0;
930 if (enable_1510_mode || !lcd_dma.ext_ctrl)
931 return;
932
933 w = omap_readw(OMAP1610_DMA_LCD_CCR);
934 w &= ~(1 << 7);
935 omap_writew(w, OMAP1610_DMA_LCD_CCR);
936
937 w = omap_readw(OMAP1610_DMA_LCD_CTRL);
938 w &= ~(1 << 8);
939 omap_writew(w, OMAP1610_DMA_LCD_CTRL);
940}
941
942/*
943 * Clears any DMA state so the DMA engine is ready to restart with new buffers
944 * through omap_start_dma(). Any buffers in flight are discarded.
945 */
946void omap_clear_dma(int lch)
947{
948 unsigned long flags;
949 int status;
950
951 local_irq_save(flags);
952 omap_writew(omap_readw(OMAP_DMA_CCR(lch)) & ~OMAP_DMA_CCR_EN,
953 OMAP_DMA_CCR(lch));
954 status = OMAP_DMA_CSR(lch); /* clear pending interrupts */
955 local_irq_restore(flags);
956}
957
958/*
959 * Returns current physical source address for the given DMA channel.
960 * If the channel is running the caller must disable interrupts prior calling
961 * this function and process the returned value before re-enabling interrupt to
962 * prevent races with the interrupt handler. Note that in continuous mode there
963 * is a chance for CSSA_L register overflow inbetween the two reads resulting
964 * in incorrect return value.
965 */
966dma_addr_t omap_get_dma_src_pos(int lch)
967{
968 return (dma_addr_t) (OMAP_DMA_CSSA_L(lch) |
969 (OMAP_DMA_CSSA_U(lch) << 16));
970}
971
972/*
973 * Returns current physical destination address for the given DMA channel.
974 * If the channel is running the caller must disable interrupts prior calling
975 * this function and process the returned value before re-enabling interrupt to
976 * prevent races with the interrupt handler. Note that in continuous mode there
977 * is a chance for CDSA_L register overflow inbetween the two reads resulting
978 * in incorrect return value.
979 */
980dma_addr_t omap_get_dma_dst_pos(int lch)
981{
982 return (dma_addr_t) (OMAP_DMA_CDSA_L(lch) |
983 (OMAP_DMA_CDSA_U(lch) << 16));
984}
985
986int omap_dma_running(void)
987{
988 int lch;
989
990 /* Check if LCD DMA is running */
991 if (cpu_is_omap16xx())
992 if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
993 return 1;
994
995 for (lch = 0; lch < dma_chan_count; lch++) {
996 u16 w;
997
998 w = omap_readw(OMAP_DMA_CCR(lch));
999 if (w & OMAP_DMA_CCR_EN)
1000 return 1;
1001 }
1002 return 0;
1003}
1004
1005static int __init omap_init_dma(void)
1006{
1007 int ch, r;
1008
1009 if (cpu_is_omap1510()) {
1010 printk(KERN_INFO "DMA support for OMAP1510 initialized\n");
1011 dma_chan_count = 9;
1012 enable_1510_mode = 1;
1013 } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
1014 printk(KERN_INFO "OMAP DMA hardware version %d\n",
1015 omap_readw(OMAP_DMA_HW_ID));
1016 printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
1017 (omap_readw(OMAP_DMA_CAPS_0_U) << 16) | omap_readw(OMAP_DMA_CAPS_0_L),
1018 (omap_readw(OMAP_DMA_CAPS_1_U) << 16) | omap_readw(OMAP_DMA_CAPS_1_L),
1019 omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
1020 omap_readw(OMAP_DMA_CAPS_4));
1021 if (!enable_1510_mode) {
1022 u16 w;
1023
1024 /* Disable OMAP 3.0/3.1 compatibility mode. */
1025 w = omap_readw(OMAP_DMA_GSCR);
1026 w |= 1 << 3;
1027 omap_writew(w, OMAP_DMA_GSCR);
1028 dma_chan_count = 16;
1029 } else
1030 dma_chan_count = 9;
1031 } else {
1032 dma_chan_count = 0;
1033 return 0;
1034 }
1035
1036 memset(&lcd_dma, 0, sizeof(lcd_dma));
1037 spin_lock_init(&lcd_dma.lock);
1038 spin_lock_init(&dma_chan_lock);
1039 memset(&dma_chan, 0, sizeof(dma_chan));
1040
1041 for (ch = 0; ch < dma_chan_count; ch++) {
1042 dma_chan[ch].dev_id = -1;
1043 dma_chan[ch].next_lch = -1;
1044
1045 if (ch >= 6 && enable_1510_mode)
1046 continue;
1047
1048 /* request_irq() doesn't like dev_id (ie. ch) being zero,
1049 * so we have to kludge around this. */
1050 r = request_irq(dma_irq[ch], dma_irq_handler, 0, "DMA",
1051 (void *) (ch + 1));
1052 if (r != 0) {
1053 int i;
1054
1055 printk(KERN_ERR "unable to request IRQ %d for DMA (error %d)\n",
1056 dma_irq[ch], r);
1057 for (i = 0; i < ch; i++)
1058 free_irq(dma_irq[i], (void *) (i + 1));
1059 return r;
1060 }
1061 }
1062 r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0, "LCD DMA", NULL);
1063 if (r != 0) {
1064 int i;
1065
1066 printk(KERN_ERR "unable to request IRQ for LCD DMA (error %d)\n", r);
1067 for (i = 0; i < dma_chan_count; i++)
1068 free_irq(dma_irq[i], (void *) (i + 1));
1069 return r;
1070 }
1071 return 0;
1072}
1073
1074arch_initcall(omap_init_dma);
1075
1076
1077EXPORT_SYMBOL(omap_get_dma_src_pos);
1078EXPORT_SYMBOL(omap_get_dma_dst_pos);
1079EXPORT_SYMBOL(omap_clear_dma);
1080EXPORT_SYMBOL(omap_set_dma_priority);
1081EXPORT_SYMBOL(omap_request_dma);
1082EXPORT_SYMBOL(omap_free_dma);
1083EXPORT_SYMBOL(omap_start_dma);
1084EXPORT_SYMBOL(omap_stop_dma);
1085EXPORT_SYMBOL(omap_enable_dma_irq);
1086EXPORT_SYMBOL(omap_disable_dma_irq);
1087
1088EXPORT_SYMBOL(omap_set_dma_transfer_params);
1089EXPORT_SYMBOL(omap_set_dma_color_mode);
1090
1091EXPORT_SYMBOL(omap_set_dma_src_params);
1092EXPORT_SYMBOL(omap_set_dma_src_index);
1093EXPORT_SYMBOL(omap_set_dma_src_data_pack);
1094EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
1095
1096EXPORT_SYMBOL(omap_set_dma_dest_params);
1097EXPORT_SYMBOL(omap_set_dma_dest_index);
1098EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
1099EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
1100
1101EXPORT_SYMBOL(omap_dma_link_lch);
1102EXPORT_SYMBOL(omap_dma_unlink_lch);
1103
1104EXPORT_SYMBOL(omap_request_lcd_dma);
1105EXPORT_SYMBOL(omap_free_lcd_dma);
1106EXPORT_SYMBOL(omap_enable_lcd_dma);
1107EXPORT_SYMBOL(omap_setup_lcd_dma);
1108EXPORT_SYMBOL(omap_stop_lcd_dma);
1109EXPORT_SYMBOL(omap_set_lcd_dma_b1);
1110EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
1111EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
1112EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
1113EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
1114EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
1115EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
1116
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..43567d5edddb
--- /dev/null
+++ b/arch/arm/plat-omap/mcbsp.c
@@ -0,0 +1,758 @@
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;
69static struct clk *mcbsp_dspxor_ck = 0;
70
71
72static void omap_mcbsp_dump_reg(u8 id)
73{
74 DBG("**** MCBSP%d regs ****\n", mcbsp[id].id);
75 DBG("DRR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR2));
76 DBG("DRR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DRR1));
77 DBG("DXR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR2));
78 DBG("DXR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, DXR1));
79 DBG("SPCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR2));
80 DBG("SPCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SPCR1));
81 DBG("RCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR2));
82 DBG("RCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, RCR1));
83 DBG("XCR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR2));
84 DBG("XCR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, XCR1));
85 DBG("SRGR2: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR2));
86 DBG("SRGR1: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, SRGR1));
87 DBG("PCR0: 0x%04x\n", OMAP_MCBSP_READ(mcbsp[id].io_base, PCR0));
88 DBG("***********************\n");
89}
90
91
92static irqreturn_t omap_mcbsp_tx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
93{
94 struct omap_mcbsp * mcbsp_tx = (struct omap_mcbsp *)(dev_id);
95
96 DBG("TX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_tx->io_base, SPCR2));
97
98 complete(&mcbsp_tx->tx_irq_completion);
99 return IRQ_HANDLED;
100}
101
102static irqreturn_t omap_mcbsp_rx_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
103{
104 struct omap_mcbsp * mcbsp_rx = (struct omap_mcbsp *)(dev_id);
105
106 DBG("RX IRQ callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_rx->io_base, SPCR2));
107
108 complete(&mcbsp_rx->rx_irq_completion);
109 return IRQ_HANDLED;
110}
111
112
113static void omap_mcbsp_tx_dma_callback(int lch, u16 ch_status, void *data)
114{
115 struct omap_mcbsp * mcbsp_dma_tx = (struct omap_mcbsp *)(data);
116
117 DBG("TX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_tx->io_base, SPCR2));
118
119 /* We can free the channels */
120 omap_free_dma(mcbsp_dma_tx->dma_tx_lch);
121 mcbsp_dma_tx->dma_tx_lch = -1;
122
123 complete(&mcbsp_dma_tx->tx_dma_completion);
124}
125
126static void omap_mcbsp_rx_dma_callback(int lch, u16 ch_status, void *data)
127{
128 struct omap_mcbsp * mcbsp_dma_rx = (struct omap_mcbsp *)(data);
129
130 DBG("RX DMA callback : 0x%x\n", OMAP_MCBSP_READ(mcbsp_dma_rx->io_base, SPCR2));
131
132 /* We can free the channels */
133 omap_free_dma(mcbsp_dma_rx->dma_rx_lch);
134 mcbsp_dma_rx->dma_rx_lch = -1;
135
136 complete(&mcbsp_dma_rx->rx_dma_completion);
137}
138
139
140/*
141 * omap_mcbsp_config simply write a config to the
142 * appropriate McBSP.
143 * You either call this function or set the McBSP registers
144 * by yourself before calling omap_mcbsp_start().
145 */
146
147void omap_mcbsp_config(unsigned int id, const struct omap_mcbsp_reg_cfg * config)
148{
149 u32 io_base = mcbsp[id].io_base;
150
151 DBG("OMAP-McBSP: McBSP%d io_base: 0x%8x\n", id+1, io_base);
152
153 /* We write the given config */
154 OMAP_MCBSP_WRITE(io_base, SPCR2, config->spcr2);
155 OMAP_MCBSP_WRITE(io_base, SPCR1, config->spcr1);
156 OMAP_MCBSP_WRITE(io_base, RCR2, config->rcr2);
157 OMAP_MCBSP_WRITE(io_base, RCR1, config->rcr1);
158 OMAP_MCBSP_WRITE(io_base, XCR2, config->xcr2);
159 OMAP_MCBSP_WRITE(io_base, XCR1, config->xcr1);
160 OMAP_MCBSP_WRITE(io_base, SRGR2, config->srgr2);
161 OMAP_MCBSP_WRITE(io_base, SRGR1, config->srgr1);
162 OMAP_MCBSP_WRITE(io_base, MCR2, config->mcr2);
163 OMAP_MCBSP_WRITE(io_base, MCR1, config->mcr1);
164 OMAP_MCBSP_WRITE(io_base, PCR0, config->pcr0);
165}
166
167
168
169static int omap_mcbsp_check(unsigned int id)
170{
171 if (cpu_is_omap730()) {
172 if (id > OMAP_MAX_MCBSP_COUNT - 1) {
173 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
174 return -1;
175 }
176 return 0;
177 }
178
179 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
180 if (id > OMAP_MAX_MCBSP_COUNT) {
181 printk(KERN_ERR "OMAP-McBSP: McBSP%d doesn't exist\n", id + 1);
182 return -1;
183 }
184 return 0;
185 }
186
187 return -1;
188}
189
190#define EN_XORPCK 1
191#define DSP_RSTCT2 0xe1008014
192
193static void omap_mcbsp_dsp_request(void)
194{
195 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
196 clk_use(mcbsp_dsp_ck);
197 clk_use(mcbsp_api_ck);
198
199 /* enable 12MHz clock to mcbsp 1 & 3 */
200 clk_use(mcbsp_dspxor_ck);
201 __raw_writew(__raw_readw(DSP_RSTCT2) | 1 | 1 << 1,
202 DSP_RSTCT2);
203 }
204}
205
206static void omap_mcbsp_dsp_free(void)
207{
208 if (cpu_is_omap1510() || cpu_is_omap16xx()) {
209 clk_unuse(mcbsp_dspxor_ck);
210 clk_unuse(mcbsp_dsp_ck);
211 clk_unuse(mcbsp_api_ck);
212 }
213}
214
215int omap_mcbsp_request(unsigned int id)
216{
217 int err;
218
219 if (omap_mcbsp_check(id) < 0)
220 return -EINVAL;
221
222 /*
223 * On 1510, 1610 and 1710, McBSP1 and McBSP3
224 * are DSP public peripherals.
225 */
226 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
227 omap_mcbsp_dsp_request();
228
229 spin_lock(&mcbsp[id].lock);
230 if (!mcbsp[id].free) {
231 printk (KERN_ERR "OMAP-McBSP: McBSP%d is currently in use\n", id + 1);
232 spin_unlock(&mcbsp[id].lock);
233 return -1;
234 }
235
236 mcbsp[id].free = 0;
237 spin_unlock(&mcbsp[id].lock);
238
239 /* We need to get IRQs here */
240 err = request_irq(mcbsp[id].tx_irq, omap_mcbsp_tx_irq_handler, 0,
241 "McBSP",
242 (void *) (&mcbsp[id]));
243 if (err != 0) {
244 printk(KERN_ERR "OMAP-McBSP: Unable to request TX IRQ %d for McBSP%d\n",
245 mcbsp[id].tx_irq, mcbsp[id].id);
246 return err;
247 }
248
249 init_completion(&(mcbsp[id].tx_irq_completion));
250
251
252 err = request_irq(mcbsp[id].rx_irq, omap_mcbsp_rx_irq_handler, 0,
253 "McBSP",
254 (void *) (&mcbsp[id]));
255 if (err != 0) {
256 printk(KERN_ERR "OMAP-McBSP: Unable to request RX IRQ %d for McBSP%d\n",
257 mcbsp[id].rx_irq, mcbsp[id].id);
258 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
259 return err;
260 }
261
262 init_completion(&(mcbsp[id].rx_irq_completion));
263 return 0;
264
265}
266
267void omap_mcbsp_free(unsigned int id)
268{
269 if (omap_mcbsp_check(id) < 0)
270 return;
271
272 if (id == OMAP_MCBSP1 || id == OMAP_MCBSP3)
273 omap_mcbsp_dsp_free();
274
275 spin_lock(&mcbsp[id].lock);
276 if (mcbsp[id].free) {
277 printk (KERN_ERR "OMAP-McBSP: McBSP%d was not reserved\n", id + 1);
278 spin_unlock(&mcbsp[id].lock);
279 return;
280 }
281
282 mcbsp[id].free = 1;
283 spin_unlock(&mcbsp[id].lock);
284
285 /* Free IRQs */
286 free_irq(mcbsp[id].rx_irq, (void *) (&mcbsp[id]));
287 free_irq(mcbsp[id].tx_irq, (void *) (&mcbsp[id]));
288}
289
290/*
291 * Here we start the McBSP, by enabling the sample
292 * generator, both transmitter and receivers,
293 * and the frame sync.
294 */
295void omap_mcbsp_start(unsigned int id)
296{
297 u32 io_base;
298 u16 w;
299
300 if (omap_mcbsp_check(id) < 0)
301 return;
302
303 io_base = mcbsp[id].io_base;
304
305 mcbsp[id].rx_word_length = ((OMAP_MCBSP_READ(io_base, RCR1) >> 5) & 0x7);
306 mcbsp[id].tx_word_length = ((OMAP_MCBSP_READ(io_base, XCR1) >> 5) & 0x7);
307
308 /* Start the sample generator */
309 w = OMAP_MCBSP_READ(io_base, SPCR2);
310 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 6));
311
312 /* Enable transmitter and receiver */
313 w = OMAP_MCBSP_READ(io_base, SPCR2);
314 OMAP_MCBSP_WRITE(io_base, SPCR2, w | 1);
315
316 w = OMAP_MCBSP_READ(io_base, SPCR1);
317 OMAP_MCBSP_WRITE(io_base, SPCR1, w | 1);
318
319 udelay(100);
320
321 /* Start frame sync */
322 w = OMAP_MCBSP_READ(io_base, SPCR2);
323 OMAP_MCBSP_WRITE(io_base, SPCR2, w | (1 << 7));
324
325 /* Dump McBSP Regs */
326 omap_mcbsp_dump_reg(id);
327
328}
329
330void omap_mcbsp_stop(unsigned int id)
331{
332 u32 io_base;
333 u16 w;
334
335 if (omap_mcbsp_check(id) < 0)
336 return;
337
338 io_base = mcbsp[id].io_base;
339
340 /* Reset transmitter */
341 w = OMAP_MCBSP_READ(io_base, SPCR2);
342 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1));
343
344 /* Reset receiver */
345 w = OMAP_MCBSP_READ(io_base, SPCR1);
346 OMAP_MCBSP_WRITE(io_base, SPCR1, w & ~(1));
347
348 /* Reset the sample rate generator */
349 w = OMAP_MCBSP_READ(io_base, SPCR2);
350 OMAP_MCBSP_WRITE(io_base, SPCR2, w & ~(1 << 6));
351}
352
353
354/* polled mcbsp i/o operations */
355int omap_mcbsp_pollwrite(unsigned int id, u16 buf)
356{
357 u32 base = mcbsp[id].io_base;
358 writew(buf, base + OMAP_MCBSP_REG_DXR1);
359 /* if frame sync error - clear the error */
360 if (readw(base + OMAP_MCBSP_REG_SPCR2) & XSYNC_ERR) {
361 /* clear error */
362 writew(readw(base + OMAP_MCBSP_REG_SPCR2) & (~XSYNC_ERR),
363 base + OMAP_MCBSP_REG_SPCR2);
364 /* resend */
365 return -1;
366 } else {
367 /* wait for transmit confirmation */
368 int attemps = 0;
369 while (!(readw(base + OMAP_MCBSP_REG_SPCR2) & XRDY)) {
370 if (attemps++ > 1000) {
371 writew(readw(base + OMAP_MCBSP_REG_SPCR2) &
372 (~XRST),
373 base + OMAP_MCBSP_REG_SPCR2);
374 udelay(10);
375 writew(readw(base + OMAP_MCBSP_REG_SPCR2) |
376 (XRST),
377 base + OMAP_MCBSP_REG_SPCR2);
378 udelay(10);
379 printk(KERN_ERR
380 " Could not write to McBSP Register\n");
381 return -2;
382 }
383 }
384 }
385 return 0;
386}
387
388int omap_mcbsp_pollread(unsigned int id, u16 * buf)
389{
390 u32 base = mcbsp[id].io_base;
391 /* if frame sync error - clear the error */
392 if (readw(base + OMAP_MCBSP_REG_SPCR1) & RSYNC_ERR) {
393 /* clear error */
394 writew(readw(base + OMAP_MCBSP_REG_SPCR1) & (~RSYNC_ERR),
395 base + OMAP_MCBSP_REG_SPCR1);
396 /* resend */
397 return -1;
398 } else {
399 /* wait for recieve confirmation */
400 int attemps = 0;
401 while (!(readw(base + OMAP_MCBSP_REG_SPCR1) & RRDY)) {
402 if (attemps++ > 1000) {
403 writew(readw(base + OMAP_MCBSP_REG_SPCR1) &
404 (~RRST),
405 base + OMAP_MCBSP_REG_SPCR1);
406 udelay(10);
407 writew(readw(base + OMAP_MCBSP_REG_SPCR1) |
408 (RRST),
409 base + OMAP_MCBSP_REG_SPCR1);
410 udelay(10);
411 printk(KERN_ERR
412 " Could not read from McBSP Register\n");
413 return -2;
414 }
415 }
416 }
417 *buf = readw(base + OMAP_MCBSP_REG_DRR1);
418 return 0;
419}
420
421/*
422 * IRQ based word transmission.
423 */
424void omap_mcbsp_xmit_word(unsigned int id, u32 word)
425{
426 u32 io_base;
427 omap_mcbsp_word_length word_length = mcbsp[id].tx_word_length;
428
429 if (omap_mcbsp_check(id) < 0)
430 return;
431
432 io_base = mcbsp[id].io_base;
433
434 wait_for_completion(&(mcbsp[id].tx_irq_completion));
435
436 if (word_length > OMAP_MCBSP_WORD_16)
437 OMAP_MCBSP_WRITE(io_base, DXR2, word >> 16);
438 OMAP_MCBSP_WRITE(io_base, DXR1, word & 0xffff);
439}
440
441u32 omap_mcbsp_recv_word(unsigned int id)
442{
443 u32 io_base;
444 u16 word_lsb, word_msb = 0;
445 omap_mcbsp_word_length word_length = mcbsp[id].rx_word_length;
446
447 if (omap_mcbsp_check(id) < 0)
448 return -EINVAL;
449
450 io_base = mcbsp[id].io_base;
451
452 wait_for_completion(&(mcbsp[id].rx_irq_completion));
453
454 if (word_length > OMAP_MCBSP_WORD_16)
455 word_msb = OMAP_MCBSP_READ(io_base, DRR2);
456 word_lsb = OMAP_MCBSP_READ(io_base, DRR1);
457
458 return (word_lsb | (word_msb << 16));
459}
460
461
462/*
463 * Simple DMA based buffer rx/tx routines.
464 * Nothing fancy, just a single buffer tx/rx through DMA.
465 * The DMA resources are released once the transfer is done.
466 * For anything fancier, you should use your own customized DMA
467 * routines and callbacks.
468 */
469int omap_mcbsp_xmit_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
470{
471 int dma_tx_ch;
472
473 if (omap_mcbsp_check(id) < 0)
474 return -EINVAL;
475
476 if (omap_request_dma(mcbsp[id].dma_tx_sync, "McBSP TX", omap_mcbsp_tx_dma_callback,
477 &mcbsp[id],
478 &dma_tx_ch)) {
479 printk("OMAP-McBSP: Unable to request DMA channel for McBSP%d TX. Trying IRQ based TX\n", id+1);
480 return -EAGAIN;
481 }
482 mcbsp[id].dma_tx_lch = dma_tx_ch;
483
484 DBG("TX DMA on channel %d\n", dma_tx_ch);
485
486 init_completion(&(mcbsp[id].tx_dma_completion));
487
488 omap_set_dma_transfer_params(mcbsp[id].dma_tx_lch,
489 OMAP_DMA_DATA_TYPE_S16,
490 length >> 1, 1,
491 OMAP_DMA_SYNC_ELEMENT);
492
493 omap_set_dma_dest_params(mcbsp[id].dma_tx_lch,
494 OMAP_DMA_PORT_TIPB,
495 OMAP_DMA_AMODE_CONSTANT,
496 mcbsp[id].io_base + OMAP_MCBSP_REG_DXR1);
497
498 omap_set_dma_src_params(mcbsp[id].dma_tx_lch,
499 OMAP_DMA_PORT_EMIFF,
500 OMAP_DMA_AMODE_POST_INC,
501 buffer);
502
503 omap_start_dma(mcbsp[id].dma_tx_lch);
504 wait_for_completion(&(mcbsp[id].tx_dma_completion));
505 return 0;
506}
507
508
509int omap_mcbsp_recv_buffer(unsigned int id, dma_addr_t buffer, unsigned int length)
510{
511 int dma_rx_ch;
512
513 if (omap_mcbsp_check(id) < 0)
514 return -EINVAL;
515
516 if (omap_request_dma(mcbsp[id].dma_rx_sync, "McBSP RX", omap_mcbsp_rx_dma_callback,
517 &mcbsp[id],
518 &dma_rx_ch)) {
519 printk("Unable to request DMA channel for McBSP%d RX. Trying IRQ based RX\n", id+1);
520 return -EAGAIN;
521 }
522 mcbsp[id].dma_rx_lch = dma_rx_ch;
523
524 DBG("RX DMA on channel %d\n", dma_rx_ch);
525
526 init_completion(&(mcbsp[id].rx_dma_completion));
527
528 omap_set_dma_transfer_params(mcbsp[id].dma_rx_lch,
529 OMAP_DMA_DATA_TYPE_S16,
530 length >> 1, 1,
531 OMAP_DMA_SYNC_ELEMENT);
532
533 omap_set_dma_src_params(mcbsp[id].dma_rx_lch,
534 OMAP_DMA_PORT_TIPB,
535 OMAP_DMA_AMODE_CONSTANT,
536 mcbsp[id].io_base + OMAP_MCBSP_REG_DRR1);
537
538 omap_set_dma_dest_params(mcbsp[id].dma_rx_lch,
539 OMAP_DMA_PORT_EMIFF,
540 OMAP_DMA_AMODE_POST_INC,
541 buffer);
542
543 omap_start_dma(mcbsp[id].dma_rx_lch);
544 wait_for_completion(&(mcbsp[id].rx_dma_completion));
545 return 0;
546}
547
548
549/*
550 * SPI wrapper.
551 * Since SPI setup is much simpler than the generic McBSP one,
552 * this wrapper just need an omap_mcbsp_spi_cfg structure as an input.
553 * Once this is done, you can call omap_mcbsp_start().
554 */
555void omap_mcbsp_set_spi_mode(unsigned int id, const struct omap_mcbsp_spi_cfg * spi_cfg)
556{
557 struct omap_mcbsp_reg_cfg mcbsp_cfg;
558
559 if (omap_mcbsp_check(id) < 0)
560 return;
561
562 memset(&mcbsp_cfg, 0, sizeof(struct omap_mcbsp_reg_cfg));
563
564 /* SPI has only one frame */
565 mcbsp_cfg.rcr1 |= (RWDLEN1(spi_cfg->word_length) | RFRLEN1(0));
566 mcbsp_cfg.xcr1 |= (XWDLEN1(spi_cfg->word_length) | XFRLEN1(0));
567
568 /* Clock stop mode */
569 if (spi_cfg->clk_stp_mode == OMAP_MCBSP_CLK_STP_MODE_NO_DELAY)
570 mcbsp_cfg.spcr1 |= (1 << 12);
571 else
572 mcbsp_cfg.spcr1 |= (3 << 11);
573
574 /* Set clock parities */
575 if (spi_cfg->rx_clock_polarity == OMAP_MCBSP_CLK_RISING)
576 mcbsp_cfg.pcr0 |= CLKRP;
577 else
578 mcbsp_cfg.pcr0 &= ~CLKRP;
579
580 if (spi_cfg->tx_clock_polarity == OMAP_MCBSP_CLK_RISING)
581 mcbsp_cfg.pcr0 &= ~CLKXP;
582 else
583 mcbsp_cfg.pcr0 |= CLKXP;
584
585 /* Set SCLKME to 0 and CLKSM to 1 */
586 mcbsp_cfg.pcr0 &= ~SCLKME;
587 mcbsp_cfg.srgr2 |= CLKSM;
588
589 /* Set FSXP */
590 if (spi_cfg->fsx_polarity == OMAP_MCBSP_FS_ACTIVE_HIGH)
591 mcbsp_cfg.pcr0 &= ~FSXP;
592 else
593 mcbsp_cfg.pcr0 |= FSXP;
594
595 if (spi_cfg->spi_mode == OMAP_MCBSP_SPI_MASTER) {
596 mcbsp_cfg.pcr0 |= CLKXM;
597 mcbsp_cfg.srgr1 |= CLKGDV(spi_cfg->clk_div -1);
598 mcbsp_cfg.pcr0 |= FSXM;
599 mcbsp_cfg.srgr2 &= ~FSGM;
600 mcbsp_cfg.xcr2 |= XDATDLY(1);
601 mcbsp_cfg.rcr2 |= RDATDLY(1);
602 }
603 else {
604 mcbsp_cfg.pcr0 &= ~CLKXM;
605 mcbsp_cfg.srgr1 |= CLKGDV(1);
606 mcbsp_cfg.pcr0 &= ~FSXM;
607 mcbsp_cfg.xcr2 &= ~XDATDLY(3);
608 mcbsp_cfg.rcr2 &= ~RDATDLY(3);
609 }
610
611 mcbsp_cfg.xcr2 &= ~XPHASE;
612 mcbsp_cfg.rcr2 &= ~RPHASE;
613
614 omap_mcbsp_config(id, &mcbsp_cfg);
615}
616
617
618/*
619 * McBSP1 and McBSP3 are directly mapped on 1610 and 1510.
620 * 730 has only 2 McBSP, and both of them are MPU peripherals.
621 */
622struct omap_mcbsp_info {
623 u32 virt_base;
624 u8 dma_rx_sync, dma_tx_sync;
625 u16 rx_irq, tx_irq;
626};
627
628#ifdef CONFIG_ARCH_OMAP730
629static const struct omap_mcbsp_info mcbsp_730[] = {
630 [0] = { .virt_base = io_p2v(OMAP730_MCBSP1_BASE),
631 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
632 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
633 .rx_irq = INT_730_McBSP1RX,
634 .tx_irq = INT_730_McBSP1TX },
635 [1] = { .virt_base = io_p2v(OMAP730_MCBSP2_BASE),
636 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
637 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
638 .rx_irq = INT_730_McBSP2RX,
639 .tx_irq = INT_730_McBSP2TX },
640};
641#endif
642
643#ifdef CONFIG_ARCH_OMAP1510
644static const struct omap_mcbsp_info mcbsp_1510[] = {
645 [0] = { .virt_base = OMAP1510_MCBSP1_BASE,
646 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
647 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
648 .rx_irq = INT_McBSP1RX,
649 .tx_irq = INT_McBSP1TX },
650 [1] = { .virt_base = io_p2v(OMAP1510_MCBSP2_BASE),
651 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
652 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
653 .rx_irq = INT_1510_SPI_RX,
654 .tx_irq = INT_1510_SPI_TX },
655 [2] = { .virt_base = OMAP1510_MCBSP3_BASE,
656 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
657 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
658 .rx_irq = INT_McBSP3RX,
659 .tx_irq = INT_McBSP3TX },
660};
661#endif
662
663#if defined(CONFIG_ARCH_OMAP16XX)
664static const struct omap_mcbsp_info mcbsp_1610[] = {
665 [0] = { .virt_base = OMAP1610_MCBSP1_BASE,
666 .dma_rx_sync = OMAP_DMA_MCBSP1_RX,
667 .dma_tx_sync = OMAP_DMA_MCBSP1_TX,
668 .rx_irq = INT_McBSP1RX,
669 .tx_irq = INT_McBSP1TX },
670 [1] = { .virt_base = io_p2v(OMAP1610_MCBSP2_BASE),
671 .dma_rx_sync = OMAP_DMA_MCBSP2_RX,
672 .dma_tx_sync = OMAP_DMA_MCBSP2_TX,
673 .rx_irq = INT_1610_McBSP2_RX,
674 .tx_irq = INT_1610_McBSP2_TX },
675 [2] = { .virt_base = OMAP1610_MCBSP3_BASE,
676 .dma_rx_sync = OMAP_DMA_MCBSP3_RX,
677 .dma_tx_sync = OMAP_DMA_MCBSP3_TX,
678 .rx_irq = INT_McBSP3RX,
679 .tx_irq = INT_McBSP3TX },
680};
681#endif
682
683static int __init omap_mcbsp_init(void)
684{
685 int mcbsp_count = 0, i;
686 static const struct omap_mcbsp_info *mcbsp_info;
687
688 printk("Initializing OMAP McBSP system\n");
689
690 mcbsp_dsp_ck = clk_get(0, "dsp_ck");
691 if (IS_ERR(mcbsp_dsp_ck)) {
692 printk(KERN_ERR "mcbsp: could not acquire dsp_ck handle.\n");
693 return PTR_ERR(mcbsp_dsp_ck);
694 }
695 mcbsp_api_ck = clk_get(0, "api_ck");
696 if (IS_ERR(mcbsp_api_ck)) {
697 printk(KERN_ERR "mcbsp: could not acquire api_ck handle.\n");
698 return PTR_ERR(mcbsp_api_ck);
699 }
700 mcbsp_dspxor_ck = clk_get(0, "dspxor_ck");
701 if (IS_ERR(mcbsp_dspxor_ck)) {
702 printk(KERN_ERR "mcbsp: could not acquire dspxor_ck handle.\n");
703 return PTR_ERR(mcbsp_dspxor_ck);
704 }
705
706#ifdef CONFIG_ARCH_OMAP730
707 if (cpu_is_omap730()) {
708 mcbsp_info = mcbsp_730;
709 mcbsp_count = ARRAY_SIZE(mcbsp_730);
710 }
711#endif
712#ifdef CONFIG_ARCH_OMAP1510
713 if (cpu_is_omap1510()) {
714 mcbsp_info = mcbsp_1510;
715 mcbsp_count = ARRAY_SIZE(mcbsp_1510);
716 }
717#endif
718#if defined(CONFIG_ARCH_OMAP16XX)
719 if (cpu_is_omap16xx()) {
720 mcbsp_info = mcbsp_1610;
721 mcbsp_count = ARRAY_SIZE(mcbsp_1610);
722 }
723#endif
724 for (i = 0; i < OMAP_MAX_MCBSP_COUNT ; i++) {
725 if (i >= mcbsp_count) {
726 mcbsp[i].io_base = 0;
727 mcbsp[i].free = 0;
728 continue;
729 }
730 mcbsp[i].id = i + 1;
731 mcbsp[i].free = 1;
732 mcbsp[i].dma_tx_lch = -1;
733 mcbsp[i].dma_rx_lch = -1;
734
735 mcbsp[i].io_base = mcbsp_info[i].virt_base;
736 mcbsp[i].tx_irq = mcbsp_info[i].tx_irq;
737 mcbsp[i].rx_irq = mcbsp_info[i].rx_irq;
738 mcbsp[i].dma_rx_sync = mcbsp_info[i].dma_rx_sync;
739 mcbsp[i].dma_tx_sync = mcbsp_info[i].dma_tx_sync;
740 spin_lock_init(&mcbsp[i].lock);
741 }
742
743 return 0;
744}
745
746
747arch_initcall(omap_mcbsp_init);
748
749EXPORT_SYMBOL(omap_mcbsp_config);
750EXPORT_SYMBOL(omap_mcbsp_request);
751EXPORT_SYMBOL(omap_mcbsp_free);
752EXPORT_SYMBOL(omap_mcbsp_start);
753EXPORT_SYMBOL(omap_mcbsp_stop);
754EXPORT_SYMBOL(omap_mcbsp_xmit_word);
755EXPORT_SYMBOL(omap_mcbsp_recv_word);
756EXPORT_SYMBOL(omap_mcbsp_xmit_buffer);
757EXPORT_SYMBOL(omap_mcbsp_recv_buffer);
758EXPORT_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..ea7b955b9c81
--- /dev/null
+++ b/arch/arm/plat-omap/mux.c
@@ -0,0 +1,160 @@
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_set *)&reg_cfg_table[reg_cfg];
57
58 /* Check the mux register in question */
59 if (cfg->mux_reg) {
60 unsigned tmp1, tmp2;
61
62 spin_lock_irqsave(&mux_spin_lock, flags);
63 reg_orig = omap_readl(cfg->mux_reg);
64
65 /* The mux registers always seem to be 3 bits long */
66 mask = (0x7 << cfg->mask_offset);
67 tmp1 = reg_orig & mask;
68 reg = reg_orig & ~mask;
69
70 tmp2 = (cfg->mask << cfg->mask_offset);
71 reg |= tmp2;
72
73 if (tmp1 != tmp2)
74 warn = 1;
75
76 omap_writel(reg, cfg->mux_reg);
77 spin_unlock_irqrestore(&mux_spin_lock, flags);
78 }
79
80 /* Check for pull up or pull down selection on 1610 */
81 if (!cpu_is_omap1510()) {
82 if (cfg->pu_pd_reg && cfg->pull_val) {
83 spin_lock_irqsave(&mux_spin_lock, flags);
84 pu_pd_orig = omap_readl(cfg->pu_pd_reg);
85 mask = 1 << cfg->pull_bit;
86
87 if (cfg->pu_pd_val) {
88 if (!(pu_pd_orig & mask))
89 warn = 1;
90 /* Use pull up */
91 pu_pd = pu_pd_orig | mask;
92 } else {
93 if (pu_pd_orig & mask)
94 warn = 1;
95 /* Use pull down */
96 pu_pd = pu_pd_orig & ~mask;
97 }
98 omap_writel(pu_pd, cfg->pu_pd_reg);
99 spin_unlock_irqrestore(&mux_spin_lock, flags);
100 }
101 }
102
103 /* Check for an associated pull down register */
104 if (cfg->pull_reg) {
105 spin_lock_irqsave(&mux_spin_lock, flags);
106 pull_orig = omap_readl(cfg->pull_reg);
107 mask = 1 << cfg->pull_bit;
108
109 if (cfg->pull_val) {
110 if (pull_orig & mask)
111 warn = 1;
112 /* Low bit = pull enabled */
113 pull = pull_orig & ~mask;
114 } else {
115 if (!(pull_orig & mask))
116 warn = 1;
117 /* High bit = pull disabled */
118 pull = pull_orig | mask;
119 }
120
121 omap_writel(pull, cfg->pull_reg);
122 spin_unlock_irqrestore(&mux_spin_lock, flags);
123 }
124
125 if (warn) {
126#ifdef CONFIG_OMAP_MUX_WARNINGS
127 printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
128#endif
129 }
130
131#ifdef CONFIG_OMAP_MUX_DEBUG
132 if (cfg->debug || warn) {
133 printk("MUX: Setting register %s\n", cfg->name);
134 printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
135 cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
136
137 if (!cpu_is_omap1510()) {
138 if (cfg->pu_pd_reg && cfg->pull_val) {
139 printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
140 cfg->pu_pd_name, cfg->pu_pd_reg,
141 pu_pd_orig, pu_pd);
142 }
143 }
144
145 if (cfg->pull_reg)
146 printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n",
147 cfg->pull_name, cfg->pull_reg, pull_orig, pull);
148 }
149#endif
150
151#ifdef CONFIG_OMAP_MUX_ERRORS
152 return warn ? -ETXTBSY : 0;
153#else
154 return 0;
155#endif
156}
157
158EXPORT_SYMBOL(omap_cfg_reg);
159
160#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..25bc4a8dd763
--- /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 - 1,
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);