diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2006-12-06 20:13:55 -0500 |
---|---|---|
committer | Tony Lindgren <tony@atomide.com> | 2007-09-20 12:59:20 -0400 |
commit | 1c22cc13256046162bb8e7b44763f6c39790af74 (patch) | |
tree | fd6b2c1dde3c3054e752fcb72d253aec5953deab | |
parent | 742c53e48e5f8e05ec9f0818281fada9c6061023 (diff) |
ARM: OMAP: omap2/gpmc updates
GPMC updates:
- bugfixes: wrong/missing flags, omitted write, wrong test
- don't map memory segments starting at zero
- improve debug messaging
- export gpmc_get_fclk_perio]d() since it's needed to calc timings
- expect gpmc_cs_set_timings() caller to have initialized sync vs async
Note that this API is glitchy; likely the best fix would be to add
a member to "struct gpmc_timings" to hold GPMC_CONFIG1, since that
holds one key aspect of the GPMC timings (the gpmc_fclk divisor,
and sync vs. async == whether that divisor matters).
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Tony Lindgren <tony@atomide.com>
-rw-r--r-- | arch/arm/mach-omap2/gpmc.c | 33 | ||||
-rw-r--r-- | include/asm-arm/arch-omap/gpmc.h | 3 |
2 files changed, 24 insertions, 12 deletions
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index e290b989aa94..6d6b25c46b1f 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -88,7 +88,7 @@ u32 gpmc_cs_read_reg(int cs, int idx) | |||
88 | } | 88 | } |
89 | 89 | ||
90 | /* TODO: Add support for gpmc_fck to clock framework and use it */ | 90 | /* TODO: Add support for gpmc_fck to clock framework and use it */ |
91 | static unsigned long gpmc_get_fclk_period(void) | 91 | unsigned long gpmc_get_fclk_period(void) |
92 | { | 92 | { |
93 | /* In picoseconds */ | 93 | /* In picoseconds */ |
94 | return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000); | 94 | return 1000000000 / ((clk_get_rate(gpmc_l3_clk)) / 1000); |
@@ -120,15 +120,21 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, | |||
120 | else | 120 | else |
121 | ticks = gpmc_ns_to_ticks(time); | 121 | ticks = gpmc_ns_to_ticks(time); |
122 | nr_bits = end_bit - st_bit + 1; | 122 | nr_bits = end_bit - st_bit + 1; |
123 | if (ticks >= 1 << nr_bits) | 123 | if (ticks >= 1 << nr_bits) { |
124 | #ifdef DEBUG | ||
125 | printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n", | ||
126 | cs, name, time, ticks, 1 << nr_bits); | ||
127 | #endif | ||
124 | return -1; | 128 | return -1; |
129 | } | ||
125 | 130 | ||
126 | mask = (1 << nr_bits) - 1; | 131 | mask = (1 << nr_bits) - 1; |
127 | l = gpmc_cs_read_reg(cs, reg); | 132 | l = gpmc_cs_read_reg(cs, reg); |
128 | #ifdef DEBUG | 133 | #ifdef DEBUG |
129 | printk(KERN_INFO "GPMC CS%d: %-10s: %d ticks, %3lu ns (was %i ticks)\n", | 134 | printk(KERN_INFO |
135 | "GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n", | ||
130 | cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, | 136 | cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000, |
131 | (l >> st_bit) & mask); | 137 | (l >> st_bit) & mask, time); |
132 | #endif | 138 | #endif |
133 | l &= ~(mask << st_bit); | 139 | l &= ~(mask << st_bit); |
134 | l |= ticks << st_bit; | 140 | l |= ticks << st_bit; |
@@ -157,7 +163,7 @@ int gpmc_cs_calc_divider(int cs, unsigned int sync_clk) | |||
157 | div = l / gpmc_get_fclk_period(); | 163 | div = l / gpmc_get_fclk_period(); |
158 | if (div > 4) | 164 | if (div > 4) |
159 | return -1; | 165 | return -1; |
160 | if (div < 0) | 166 | if (div <= 0) |
161 | div = 1; | 167 | div = 1; |
162 | 168 | ||
163 | return div; | 169 | return div; |
@@ -191,14 +197,19 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t) | |||
191 | 197 | ||
192 | GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); | 198 | GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); |
193 | 199 | ||
200 | /* caller is expected to have initialized CONFIG1 to cover | ||
201 | * at least sync vs async | ||
202 | */ | ||
203 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | ||
204 | if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) { | ||
194 | #ifdef DEBUG | 205 | #ifdef DEBUG |
195 | printk(KERN_INFO "GPMC CS%d CLK period is %lu (div %d)\n", | 206 | printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n", |
196 | cs, gpmc_get_fclk_period(), div); | 207 | cs, (div * gpmc_get_fclk_period()) / 1000, div); |
197 | #endif | 208 | #endif |
198 | 209 | l &= ~0x03; | |
199 | l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); | 210 | l |= (div - 1); |
200 | l &= ~0x03; | 211 | gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); |
201 | l |= (div - 1); | 212 | } |
202 | 213 | ||
203 | return 0; | 214 | return 0; |
204 | } | 215 | } |
diff --git a/include/asm-arm/arch-omap/gpmc.h b/include/asm-arm/arch-omap/gpmc.h index 995cc83482eb..434672df702f 100644 --- a/include/asm-arm/arch-omap/gpmc.h +++ b/include/asm-arm/arch-omap/gpmc.h | |||
@@ -23,9 +23,10 @@ | |||
23 | #define GPMC_CS_NAND_DATA 0x24 | 23 | #define GPMC_CS_NAND_DATA 0x24 |
24 | 24 | ||
25 | #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) | 25 | #define GPMC_CONFIG1_WRAPBURST_SUPP (1 << 31) |
26 | #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 20) | 26 | #define GPMC_CONFIG1_READMULTIPLE_SUPP (1 << 30) |
27 | #define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) | 27 | #define GPMC_CONFIG1_READTYPE_ASYNC (0 << 29) |
28 | #define GPMC_CONFIG1_READTYPE_SYNC (1 << 29) | 28 | #define GPMC_CONFIG1_READTYPE_SYNC (1 << 29) |
29 | #define GPMC_CONFIG1_WRITEMULTIPLE_SUPP (1 << 28) | ||
29 | #define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) | 30 | #define GPMC_CONFIG1_WRITETYPE_ASYNC (0 << 27) |
30 | #define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) | 31 | #define GPMC_CONFIG1_WRITETYPE_SYNC (1 << 27) |
31 | #define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) | 32 | #define GPMC_CONFIG1_CLKACTIVATIONTIME(val) ((val & 3) << 25) |