diff options
Diffstat (limited to 'arch/arm/mach-omap2/gpmc.c')
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 47 |
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 */ |
91 | static unsigned long gpmc_get_fclk_period(void) | 98 | unsigned 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 | ||
114 | unsigned 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 |
108 | static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, | 122 | static 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 | } |