diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-10-14 17:24:42 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-10-14 17:24:42 -0400 |
commit | b6825d2df55aa7d7341c715b577b73a6a03dc944 (patch) | |
tree | ae4f0f52f4c2ad4e501dd323318486ccdd7fcd93 /arch/arm/mach-omap2/gpmc.c | |
parent | 6defd90433729c2d795865165cb34d938d8ff07c (diff) | |
parent | aa59e19d05114f9fb7718d6bc8398255476fb4f5 (diff) |
Merge branch 'omap-all' into devel
Conflicts:
arch/arm/mach-omap2/gpmc.c
arch/arm/mach-omap2/irq.c
Diffstat (limited to 'arch/arm/mach-omap2/gpmc.c')
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 88 |
1 files changed, 63 insertions, 25 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index af1081a0b27c..763bdbeaf681 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -9,6 +9,8 @@ | |||
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
10 | * published by the Free Software Foundation. | 10 | * published by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | #undef DEBUG | ||
13 | |||
12 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
13 | #include <linux/init.h> | 15 | #include <linux/init.h> |
14 | #include <linux/err.h> | 16 | #include <linux/err.h> |
@@ -16,20 +18,14 @@ | |||
16 | #include <linux/ioport.h> | 18 | #include <linux/ioport.h> |
17 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
18 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/module.h> | ||
19 | 22 | ||
20 | #include <asm/mach-types.h> | 23 | #include <asm/mach-types.h> |
21 | #include <mach/gpmc.h> | 24 | #include <mach/gpmc.h> |
22 | 25 | ||
23 | #undef DEBUG | 26 | #include <mach/sdrc.h> |
24 | |||
25 | #ifdef CONFIG_ARCH_OMAP2420 | ||
26 | #define GPMC_BASE 0x6800a000 | ||
27 | #endif | ||
28 | |||
29 | #ifdef CONFIG_ARCH_OMAP2430 | ||
30 | #define GPMC_BASE 0x6E000000 | ||
31 | #endif | ||
32 | 27 | ||
28 | /* GPMC register offsets */ | ||
33 | #define GPMC_REVISION 0x00 | 29 | #define GPMC_REVISION 0x00 |
34 | #define GPMC_SYSCONFIG 0x10 | 30 | #define GPMC_SYSCONFIG 0x10 |
35 | #define GPMC_SYSSTATUS 0x14 | 31 | #define GPMC_SYSSTATUS 0x14 |
@@ -51,7 +47,6 @@ | |||
51 | #define GPMC_CS0 0x60 | 47 | #define GPMC_CS0 0x60 |
52 | #define GPMC_CS_SIZE 0x30 | 48 | #define GPMC_CS_SIZE 0x30 |
53 | 49 | ||
54 | #define GPMC_CS_NUM 8 | ||
55 | #define GPMC_MEM_START 0x00000000 | 50 | #define GPMC_MEM_START 0x00000000 |
56 | #define GPMC_MEM_END 0x3FFFFFFF | 51 | #define GPMC_MEM_END 0x3FFFFFFF |
57 | #define BOOT_ROM_SPACE 0x100000 /* 1MB */ | 52 | #define BOOT_ROM_SPACE 0x100000 /* 1MB */ |
@@ -64,12 +59,9 @@ static struct resource gpmc_cs_mem[GPMC_CS_NUM]; | |||
64 | static DEFINE_SPINLOCK(gpmc_mem_lock); | 59 | static DEFINE_SPINLOCK(gpmc_mem_lock); |
65 | static unsigned gpmc_cs_map; | 60 | static unsigned gpmc_cs_map; |
66 | 61 | ||
67 | static void __iomem *gpmc_base = | 62 | static void __iomem *gpmc_base; |
68 | (void __iomem *) IO_ADDRESS(GPMC_BASE); | ||
69 | static void __iomem *gpmc_cs_base = | ||
70 | (void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0; | ||
71 | 63 | ||
72 | static struct clk *gpmc_fck; | 64 | static struct clk *gpmc_l3_clk; |
73 | 65 | ||
74 | static void gpmc_write_reg(int idx, u32 val) | 66 | static void gpmc_write_reg(int idx, u32 val) |
75 | { | 67 | { |
@@ -85,19 +77,32 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val) | |||
85 | { | 77 | { |
86 | void __iomem *reg_addr; | 78 | void __iomem *reg_addr; |
87 | 79 | ||
88 | reg_addr = gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx; | 80 | reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; |
89 | __raw_writel(val, reg_addr); | 81 | __raw_writel(val, reg_addr); |
90 | } | 82 | } |
91 | 83 | ||
92 | u32 gpmc_cs_read_reg(int cs, int idx) | 84 | u32 gpmc_cs_read_reg(int cs, int idx) |
93 | { | 85 | { |
94 | return __raw_readl(gpmc_cs_base + (cs * GPMC_CS_SIZE) + idx); | 86 | void __iomem *reg_addr; |
87 | |||
88 | reg_addr = gpmc_base + GPMC_CS0 + (cs * GPMC_CS_SIZE) + idx; | ||
89 | return __raw_readl(reg_addr); | ||
95 | } | 90 | } |
96 | 91 | ||
92 | /* TODO: Add support for gpmc_fck to clock framework and use it */ | ||
97 | unsigned long gpmc_get_fclk_period(void) | 93 | unsigned long gpmc_get_fclk_period(void) |
98 | { | 94 | { |
99 | /* In picoseconds */ | 95 | unsigned long rate = clk_get_rate(gpmc_l3_clk); |
100 | return 1000000000 / ((clk_get_rate(gpmc_fck)) / 1000); | 96 | |
97 | if (rate == 0) { | ||
98 | printk(KERN_WARNING "gpmc_l3_clk not enabled\n"); | ||
99 | return 0; | ||
100 | } | ||
101 | |||
102 | rate /= 1000; | ||
103 | rate = 1000000000 / rate; /* In picoseconds */ | ||
104 | |||
105 | return rate; | ||
101 | } | 106 | } |
102 | 107 | ||
103 | unsigned int gpmc_ns_to_ticks(unsigned int time_ns) | 108 | unsigned int gpmc_ns_to_ticks(unsigned int time_ns) |
@@ -110,6 +115,11 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns) | |||
110 | return (time_ns * 1000 + tick_ps - 1) / tick_ps; | 115 | return (time_ns * 1000 + tick_ps - 1) / tick_ps; |
111 | } | 116 | } |
112 | 117 | ||
118 | unsigned int gpmc_ticks_to_ns(unsigned int ticks) | ||
119 | { | ||
120 | return ticks * gpmc_get_fclk_period() / 1000; | ||
121 | } | ||
122 | |||
113 | unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) | 123 | unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) |
114 | { | 124 | { |
115 | unsigned long ticks = gpmc_ns_to_ticks(time_ns); | 125 | unsigned long ticks = gpmc_ns_to_ticks(time_ns); |
@@ -210,6 +220,11 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) | |||
210 | 220 | ||
211 | GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); | 221 | GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); |
212 | 222 | ||
223 | if (cpu_is_omap34xx()) { | ||
224 | GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); | ||
225 | GPMC_SET_ONE(GPMC_CS_CONFIG6, 24, 28, wr_access); | ||
226 | } | ||
227 | |||
213 | /* caller is expected to have initialized CONFIG1 to cover | 228 | /* caller is expected to have initialized CONFIG1 to cover |
214 | * at least sync vs async | 229 | * at least sync vs async |
215 | */ | 230 | */ |
@@ -350,6 +365,7 @@ out: | |||
350 | spin_unlock(&gpmc_mem_lock); | 365 | spin_unlock(&gpmc_mem_lock); |
351 | return r; | 366 | return r; |
352 | } | 367 | } |
368 | EXPORT_SYMBOL(gpmc_cs_request); | ||
353 | 369 | ||
354 | void gpmc_cs_free(int cs) | 370 | void gpmc_cs_free(int cs) |
355 | { | 371 | { |
@@ -365,8 +381,9 @@ void gpmc_cs_free(int cs) | |||
365 | gpmc_cs_set_reserved(cs, 0); | 381 | gpmc_cs_set_reserved(cs, 0); |
366 | spin_unlock(&gpmc_mem_lock); | 382 | spin_unlock(&gpmc_mem_lock); |
367 | } | 383 | } |
384 | EXPORT_SYMBOL(gpmc_cs_free); | ||
368 | 385 | ||
369 | void __init gpmc_mem_init(void) | 386 | static void __init gpmc_mem_init(void) |
370 | { | 387 | { |
371 | int cs; | 388 | int cs; |
372 | unsigned long boot_rom_space = 0; | 389 | unsigned long boot_rom_space = 0; |
@@ -396,12 +413,33 @@ void __init gpmc_mem_init(void) | |||
396 | void __init gpmc_init(void) | 413 | void __init gpmc_init(void) |
397 | { | 414 | { |
398 | u32 l; | 415 | u32 l; |
416 | char *ck; | ||
417 | |||
418 | if (cpu_is_omap24xx()) { | ||
419 | ck = "core_l3_ck"; | ||
420 | if (cpu_is_omap2420()) | ||
421 | l = OMAP2420_GPMC_BASE; | ||
422 | else | ||
423 | l = OMAP34XX_GPMC_BASE; | ||
424 | } else if (cpu_is_omap34xx()) { | ||
425 | ck = "gpmc_fck"; | ||
426 | l = OMAP34XX_GPMC_BASE; | ||
427 | } | ||
399 | 428 | ||
400 | gpmc_fck = clk_get(NULL, "gpmc_fck"); /* Always on ENABLE_ON_INIT */ | 429 | gpmc_l3_clk = clk_get(NULL, ck); |
401 | if (IS_ERR(gpmc_fck)) | 430 | if (IS_ERR(gpmc_l3_clk)) { |
402 | WARN_ON(1); | 431 | printk(KERN_ERR "Could not get GPMC clock %s\n", ck); |
403 | else | 432 | return -ENODEV; |
404 | clk_enable(gpmc_fck); | 433 | } |
434 | |||
435 | gpmc_base = ioremap(l, SZ_4K); | ||
436 | if (!gpmc_base) { | ||
437 | clk_put(gpmc_l3_clk); | ||
438 | printk(KERN_ERR "Could not get GPMC register memory\n"); | ||
439 | return -ENOMEM; | ||
440 | } | ||
441 | |||
442 | BUG_ON(IS_ERR(gpmc_l3_clk)); | ||
405 | 443 | ||
406 | l = gpmc_read_reg(GPMC_REVISION); | 444 | l = gpmc_read_reg(GPMC_REVISION); |
407 | printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); | 445 | printk(KERN_INFO "GPMC revision %d.%d\n", (l >> 4) & 0x0f, l & 0x0f); |