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 | } |
