aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAfzal Mohammed <afzal@ti.com>2012-05-28 08:21:37 -0400
committerAfzal Mohammed <afzal@ti.com>2012-11-09 07:37:11 -0500
commit559d94b00c4dca74b060bae1feeb81cac38628a6 (patch)
treeb5294c16ac82c6ecac29b288f29555da20e690e4
parenta1bfdc6020c2ac52fbadca11cc99c7c63b310d37 (diff)
ARM: OMAP2+: gpmc: handle additional timings
Configure busturnaround, cycle2cycledelay, waitmonitoringtime, clkactivationtime in gpmc_cs_set_timings(). This is done so that boards can configure these parameters of gpmc in Kernel instead of relying on bootloader. Also configure bool type timings like extradelay. This needed change to the existing users that were configuring clk activation time and extra delay by directly writing to registers. Thanks to Tony for making me aware of users of clk activation and being kind enough to test the modified one. Signed-off-by: Afzal Mohammed <afzal@ti.com>
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c30
-rw-r--r--arch/arm/mach-omap2/gpmc.c48
-rw-r--r--arch/arm/mach-omap2/gpmc.h19
-rw-r--r--arch/arm/mach-omap2/usb-tusb6010.c3
4 files changed, 75 insertions, 25 deletions
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index d102183ed9a5..206008837294 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -181,10 +181,8 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
181 const int t_wpl = 40; 181 const int t_wpl = 40;
182 const int t_wph = 30; 182 const int t_wph = 30;
183 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; 183 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
184 u32 reg;
185 int div, fclk_offset_ns, gpmc_clk_ns; 184 int div, fclk_offset_ns, gpmc_clk_ns;
186 int ticks_cez; 185 int ticks_cez;
187 int cs = cfg->cs;
188 186
189 if (cfg->flags & ONENAND_SYNC_READ) 187 if (cfg->flags & ONENAND_SYNC_READ)
190 onenand_flags = ONENAND_FLAG_SYNCREAD; 188 onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -254,27 +252,10 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
254 memset(&t, 0, sizeof(t)); 252 memset(&t, 0, sizeof(t));
255 253
256 if (div == 1) { 254 if (div == 1) {
257 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2); 255 t.bool_timings.cs_extra_delay = true;
258 reg |= (1 << 7); 256 t.bool_timings.adv_extra_delay = true;
259 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg); 257 t.bool_timings.oe_extra_delay = true;
260 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3); 258 t.bool_timings.we_extra_delay = true;
261 reg |= (1 << 7);
262 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
263 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
264 reg |= (1 << 7);
265 reg |= (1 << 23);
266 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
267 } else {
268 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG2);
269 reg &= ~(1 << 7);
270 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG2, reg);
271 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG3);
272 reg &= ~(1 << 7);
273 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG3, reg);
274 reg = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG4);
275 reg &= ~(1 << 7);
276 reg &= ~(1 << 23);
277 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG4, reg);
278 } 259 }
279 260
280 t.sync_clk = min_gpmc_clk_period; 261 t.sync_clk = min_gpmc_clk_period;
@@ -297,6 +278,8 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
297 t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div + 278 t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
298 ticks_cez); 279 ticks_cez);
299 280
281 t.clk_activation = fclk_offset_ns;
282
300 /* Write */ 283 /* Write */
301 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { 284 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
302 t.adv_wr_off = t.adv_rd_off; 285 t.adv_wr_off = t.adv_rd_off;
@@ -338,7 +321,6 @@ static int gpmc_set_sync_mode(int cs, struct gpmc_timings *t)
338 (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) | 321 (sync_read ? GPMC_CONFIG1_READTYPE_SYNC : 0) |
339 (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) | 322 (sync_write ? GPMC_CONFIG1_WRITEMULTIPLE_SUPP : 0) |
340 (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) | 323 (sync_write ? GPMC_CONFIG1_WRITETYPE_SYNC : 0) |
341 GPMC_CONFIG1_CLKACTIVATIONTIME(fclk_offset) |
342 GPMC_CONFIG1_PAGE_LEN(2) | 324 GPMC_CONFIG1_PAGE_LEN(2) |
343 (cpu_is_omap34xx() ? 0 : 325 (cpu_is_omap34xx() ? 0 :
344 (GPMC_CONFIG1_WAIT_READ_MON | 326 (GPMC_CONFIG1_WAIT_READ_MON |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index bf6117c32f4b..5619d1b48668 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -74,6 +74,13 @@
74#define GPMC_ECC_CTRL_ECCREG8 0x008 74#define GPMC_ECC_CTRL_ECCREG8 0x008
75#define GPMC_ECC_CTRL_ECCREG9 0x009 75#define GPMC_ECC_CTRL_ECCREG9 0x009
76 76
77#define GPMC_CONFIG2_CSEXTRADELAY BIT(7)
78#define GPMC_CONFIG3_ADVEXTRADELAY BIT(7)
79#define GPMC_CONFIG4_OEEXTRADELAY BIT(7)
80#define GPMC_CONFIG4_WEEXTRADELAY BIT(23)
81#define GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN BIT(6)
82#define GPMC_CONFIG6_CYCLE2CYCLESAMECSEN BIT(7)
83
77#define GPMC_CS0_OFFSET 0x60 84#define GPMC_CS0_OFFSET 0x60
78#define GPMC_CS_SIZE 0x30 85#define GPMC_CS_SIZE 0x30
79#define GPMC_BCH_SIZE 0x10 86#define GPMC_BCH_SIZE 0x10
@@ -223,6 +230,39 @@ unsigned int gpmc_round_ns_to_ticks(unsigned int time_ns)
223 return ticks * gpmc_get_fclk_period() / 1000; 230 return ticks * gpmc_get_fclk_period() / 1000;
224} 231}
225 232
233static inline void gpmc_cs_modify_reg(int cs, int reg, u32 mask, bool value)
234{
235 u32 l;
236
237 l = gpmc_cs_read_reg(cs, reg);
238 if (value)
239 l |= mask;
240 else
241 l &= ~mask;
242 gpmc_cs_write_reg(cs, reg, l);
243}
244
245static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
246{
247 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG1,
248 GPMC_CONFIG1_TIME_PARA_GRAN,
249 p->time_para_granularity);
250 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG2,
251 GPMC_CONFIG2_CSEXTRADELAY, p->cs_extra_delay);
252 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG3,
253 GPMC_CONFIG3_ADVEXTRADELAY, p->adv_extra_delay);
254 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
255 GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
256 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
257 GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
258 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
259 GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
260 p->cycle2cyclesamecsen);
261 gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
262 GPMC_CONFIG6_CYCLE2CYCLEDIFFCSEN,
263 p->cycle2cyclediffcsen);
264}
265
226#ifdef DEBUG 266#ifdef DEBUG
227static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit, 267static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
228 int time, const char *name) 268 int time, const char *name)
@@ -316,6 +356,12 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
316 356
317 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access); 357 GPMC_SET_ONE(GPMC_CS_CONFIG5, 24, 27, page_burst_access);
318 358
359 GPMC_SET_ONE(GPMC_CS_CONFIG6, 0, 3, bus_turnaround);
360 GPMC_SET_ONE(GPMC_CS_CONFIG6, 8, 11, cycle2cycle_delay);
361
362 GPMC_SET_ONE(GPMC_CS_CONFIG1, 18, 19, wait_monitoring);
363 GPMC_SET_ONE(GPMC_CS_CONFIG1, 25, 26, clk_activation);
364
319 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS) 365 if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
320 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus); 366 GPMC_SET_ONE(GPMC_CS_CONFIG6, 16, 19, wr_data_mux_bus);
321 if (gpmc_capability & GPMC_HAS_WR_ACCESS) 367 if (gpmc_capability & GPMC_HAS_WR_ACCESS)
@@ -335,6 +381,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
335 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l); 381 gpmc_cs_write_reg(cs, GPMC_CS_CONFIG1, l);
336 } 382 }
337 383
384 gpmc_cs_bool_timings(cs, &t->bool_timings);
385
338 return 0; 386 return 0;
339} 387}
340 388
diff --git a/arch/arm/mach-omap2/gpmc.h b/arch/arm/mach-omap2/gpmc.h
index 79f4dfc2adb3..e08a51a7a76a 100644
--- a/arch/arm/mach-omap2/gpmc.h
+++ b/arch/arm/mach-omap2/gpmc.h
@@ -74,6 +74,17 @@
74#define GPMC_IRQ_COUNT_EVENT 0x02 74#define GPMC_IRQ_COUNT_EVENT 0x02
75 75
76 76
77/* bool type time settings */
78struct gpmc_bool_timings {
79 bool cycle2cyclediffcsen;
80 bool cycle2cyclesamecsen;
81 bool we_extra_delay;
82 bool oe_extra_delay;
83 bool adv_extra_delay;
84 bool cs_extra_delay;
85 bool time_para_granularity;
86};
87
77/* 88/*
78 * Note that all values in this struct are in nanoseconds except sync_clk 89 * Note that all values in this struct are in nanoseconds except sync_clk
79 * (which is in picoseconds), while the register values are in gpmc_fck cycles. 90 * (which is in picoseconds), while the register values are in gpmc_fck cycles.
@@ -106,9 +117,17 @@ struct gpmc_timings {
106 u16 rd_cycle; /* Total read cycle time */ 117 u16 rd_cycle; /* Total read cycle time */
107 u16 wr_cycle; /* Total write cycle time */ 118 u16 wr_cycle; /* Total write cycle time */
108 119
120 u16 bus_turnaround;
121 u16 cycle2cycle_delay;
122
123 u16 wait_monitoring;
124 u16 clk_activation;
125
109 /* The following are only on OMAP3430 */ 126 /* The following are only on OMAP3430 */
110 u16 wr_access; /* WRACCESSTIME */ 127 u16 wr_access; /* WRACCESSTIME */
111 u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */ 128 u16 wr_data_mux_bus; /* WRDATAONADMUXBUS */
129
130 struct gpmc_bool_timings bool_timings;
112}; 131};
113 132
114extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs); 133extern void gpmc_update_nand_reg(struct gpmc_nand_regs *reg, int cs);
diff --git a/arch/arm/mach-omap2/usb-tusb6010.c b/arch/arm/mach-omap2/usb-tusb6010.c
index a8795ff19e6d..5be96c6e1416 100644
--- a/arch/arm/mach-omap2/usb-tusb6010.c
+++ b/arch/arm/mach-omap2/usb-tusb6010.c
@@ -175,6 +175,8 @@ static int tusb_set_sync_mode(unsigned sysclk_ps, unsigned fclk_ps)
175 tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */; 175 tmp = t.cs_wr_off * 1000 + 7000 /* t_scsn_rdy_z */;
176 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps); 176 t.wr_cycle = next_clk(t.cs_wr_off, tmp, fclk_ps);
177 177
178 t.clk_activation = gpmc_ticks_to_ns(1);
179
178 return gpmc_cs_set_timings(sync_cs, &t); 180 return gpmc_cs_set_timings(sync_cs, &t);
179} 181}
180 182
@@ -284,7 +286,6 @@ tusb6010_setup_interface(struct musb_hdrc_platform_data *data,
284 | GPMC_CONFIG1_READTYPE_SYNC 286 | GPMC_CONFIG1_READTYPE_SYNC
285 | GPMC_CONFIG1_WRITEMULTIPLE_SUPP 287 | GPMC_CONFIG1_WRITEMULTIPLE_SUPP
286 | GPMC_CONFIG1_WRITETYPE_SYNC 288 | GPMC_CONFIG1_WRITETYPE_SYNC
287 | GPMC_CONFIG1_CLKACTIVATIONTIME(1)
288 | GPMC_CONFIG1_PAGE_LEN(2) 289 | GPMC_CONFIG1_PAGE_LEN(2)
289 | GPMC_CONFIG1_WAIT_READ_MON 290 | GPMC_CONFIG1_WAIT_READ_MON
290 | GPMC_CONFIG1_WAIT_WRITE_MON 291 | GPMC_CONFIG1_WAIT_WRITE_MON