aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/gpmc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/gpmc.c')
-rw-r--r--arch/arm/mach-omap2/gpmc.c47
1 files changed, 36 insertions, 11 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index e290b989aa94..5a4cc2076a7d 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -22,7 +22,14 @@
22 22
23#undef DEBUG 23#undef DEBUG
24 24
25#ifdef CONFIG_ARCH_OMAP2420
25#define GPMC_BASE 0x6800a000 26#define GPMC_BASE 0x6800a000
27#endif
28
29#ifdef CONFIG_ARCH_OMAP2430
30#define GPMC_BASE 0x6E000000
31#endif
32
26#define GPMC_REVISION 0x00 33#define GPMC_REVISION 0x00
27#define GPMC_SYSCONFIG 0x10 34#define GPMC_SYSCONFIG 0x10
28#define GPMC_SYSSTATUS 0x14 35#define GPMC_SYSSTATUS 0x14
@@ -88,7 +95,7 @@ u32 gpmc_cs_read_reg(int cs, int idx)
88} 95}
89 96
90/* TODO: Add support for gpmc_fck to clock framework and use it */ 97/* TODO: Add support for gpmc_fck to clock framework and use it */
91static unsigned long gpmc_get_fclk_period(void) 98unsigned long gpmc_get_fclk_period(void)
92{ 99{
93 /* In picoseconds */ 100 /* In picoseconds */
94 return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000); 101 return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000);
@@ -104,6 +111,13 @@ unsigned int gpmc_ns_to_ticks(unsigned int time_ns)
104 return (time_ns * 1000 + tick_ps - 1) / tick_ps; 111 return (time_ns * 1000 + tick_ps - 1) / tick_ps;
105} 112}
106 113
114unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
115{
116 unsigned long ticks = gpmc_ns_to_ticks(time_ns);
117
118 return ticks * gpmc_get_fclk_period() / 1000;
119}
120
107#ifdef DEBUG 121#ifdef DEBUG
108static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 122static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
109 int time, const char *name) 123 int time, const char *name)
@@ -120,15 +134,21 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
120 else 134 else
121 ticks = gpmc_ns_to_ticks(time); 135 ticks = gpmc_ns_to_ticks(time);
122 nr_bits = end_bit - st_bit + 1; 136 nr_bits = end_bit - st_bit + 1;
123 if (ticks >= 1 << nr_bits) 137 if (ticks >= 1 << nr_bits) {
138#ifdef DEBUG
139 printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
140 cs, name, time, ticks, 1 << nr_bits);
141#endif
124 return -1; 142 return -1;
143 }
125 144
126 mask = (1 << nr_bits) - 1; 145 mask = (1 << nr_bits) - 1;
127 l = gpmc_cs_read_reg(cs, reg); 146 l = gpmc_cs_read_reg(cs, reg);
128#ifdef DEBUG 147#ifdef DEBUG
129 printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n", 148 printk(KERN_INFO
149 "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
130 cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, 150 cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
131 (l >> st_bit) & mask); 151 (l >> st_bit) & mask, time);
132#endif 152#endif
133 l &= ~(mask << st_bit); 153 l &= ~(mask << st_bit);
134 l |= ticks << st_bit; 154 l |= ticks << st_bit;
@@ -157,7 +177,7 @@ int gpmc_cs_calc_divider(int cs, unsigned int sync_clk)
157 div = l / gpmc_get_fclk_period(); 177 div = l / gpmc_get_fclk_period();
158 if (div > 4) 178 if (div > 4)
159 return -1; 179 return -1;
160 if (div < 0) 180 if (div <= 0)
161 div = 1; 181 div = 1;
162 182
163 return div; 183 return div;
@@ -191,14 +211,19 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
191 211
192 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); 212 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
193 213
214 /* caller is expected to have initialized CONFIG1 to cover
215 * at least sync vs async
216 */
217 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
218 if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
194#ifdef DEBUG 219#ifdef DEBUG
195 printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n", 220 printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
196 cs, gpmc_get_fclk_period(), div); 221 cs, (div * gpmc_get_fclk_period()) / 1000, div);
197#endif 222#endif
198 223 l &= ~0x03;
199 l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); 224 l |= (div - 1);
200 l &= ~0x03; 225 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
201 l |= (div - 1); 226 }
202 227
203 return 0; 228 return 0;
204} 229}