aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/gpmc.c
diff options
context:
space:
mode:
authorRussell King <rmk@dyn-67.arm.linux.org.uk>2008-10-14 17:24:42 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-10-14 17:24:42 -0400
commitb6825d2df55aa7d7341c715b577b73a6a03dc944 (patch)
treeae4f0f52f4c2ad4e501dd323318486ccdd7fcd93 /arch/arm/mach-omap2/gpmc.c
parent6defd90433729c2d795865165cb34d938d8ff07c (diff)
parentaa59e19d05114f9fb7718d6bc8398255476fb4f5 (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.c88
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];
64static DEFINE_SPINLOCK(gpmc_mem_lock); 59static DEFINE_SPINLOCK(gpmc_mem_lock);
65static unsigned gpmc_cs_map; 60static unsigned gpmc_cs_map;
66 61
67static void __iomem *gpmc_base = 62static void __iomem *gpmc_base;
68 (void __iomem *) IO_ADDRESS(GPMC_BASE);
69static void __iomem *gpmc_cs_base =
70 (void __iomem *) IO_ADDRESS(GPMC_BASE) + GPMC_CS0;
71 63
72static struct clk *gpmc_fck; 64static struct clk *gpmc_l3_clk;
73 65
74static void gpmc_write_reg(int idx, u32 val) 66static 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
92u32 gpmc_cs_read_reg(int cs, int idx) 84u32 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 */
97unsigned long gpmc_get_fclk_period(void) 93unsigned 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
103unsigned int gpmc_ns_to_ticks(unsigned int time_ns) 108unsigned 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
118unsigned int gpmc_ticks_to_ns(unsigned int ticks)
119{
120 return ticks * gpmc_get_fclk_period() / 1000;
121}
122
113unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns) 123unsigned 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}
368EXPORT_SYMBOL(gpmc_cs_request);
353 369
354void gpmc_cs_free(int cs) 370void 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}
384EXPORT_SYMBOL(gpmc_cs_free);
368 385
369void __init gpmc_mem_init(void) 386static 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)
396void __init gpmc_init(void) 413void __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);