aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/gpmc-onenand.c
diff options
context:
space:
mode:
authorAfzal Mohammed <afzal@ti.com>2012-11-09 07:35:17 -0500
committerAfzal Mohammed <afzal@ti.com>2012-11-09 07:37:12 -0500
commit4f4426f900bb8a9efcdbcc8bcc94708763e1ed15 (patch)
tree75cd00556ea345990739893b98a673082444fe52 /arch/arm/mach-omap2/gpmc-onenand.c
parent246da26d37311cd1b1489575f305042dcdecfd50 (diff)
ARM: OMAP2+: onenand: generic timing calculation
Generic gpmc timing calculation helper is available now, use it instead of custom timing calculation. Signed-off-by: Afzal Mohammed <afzal@ti.com>
Diffstat (limited to 'arch/arm/mach-omap2/gpmc-onenand.c')
-rw-r--r--arch/arm/mach-omap2/gpmc-onenand.c125
1 files changed, 43 insertions, 82 deletions
diff --git a/arch/arm/mach-omap2/gpmc-onenand.c b/arch/arm/mach-omap2/gpmc-onenand.c
index 206008837294..94a349e4dc96 100644
--- a/arch/arm/mach-omap2/gpmc-onenand.c
+++ b/arch/arm/mach-omap2/gpmc-onenand.c
@@ -33,7 +33,6 @@
33 33
34static unsigned onenand_flags; 34static unsigned onenand_flags;
35static unsigned latency; 35static unsigned latency;
36static int fclk_offset;
37 36
38static struct omap_onenand_platform_data *gpmc_onenand_data; 37static struct omap_onenand_platform_data *gpmc_onenand_data;
39 38
@@ -50,6 +49,7 @@ static struct platform_device gpmc_onenand_device = {
50 49
51static struct gpmc_timings omap2_onenand_calc_async_timings(void) 50static struct gpmc_timings omap2_onenand_calc_async_timings(void)
52{ 51{
52 struct gpmc_device_timings dev_t;
53 struct gpmc_timings t; 53 struct gpmc_timings t;
54 54
55 const int t_cer = 15; 55 const int t_cer = 15;
@@ -59,35 +59,24 @@ static struct gpmc_timings omap2_onenand_calc_async_timings(void)
59 const int t_aa = 76; 59 const int t_aa = 76;
60 const int t_oe = 20; 60 const int t_oe = 20;
61 const int t_cez = 20; /* max of t_cez, t_oez */ 61 const int t_cez = 20; /* max of t_cez, t_oez */
62 const int t_ds = 30;
63 const int t_wpl = 40; 62 const int t_wpl = 40;
64 const int t_wph = 30; 63 const int t_wph = 30;
65 64
66 memset(&t, 0, sizeof(t)); 65 memset(&dev_t, 0, sizeof(dev_t));
67 t.sync_clk = 0; 66
68 t.cs_on = 0; 67 dev_t.mux = true;
69 t.adv_on = 0; 68 dev_t.t_avdp_r = max_t(int, t_avdp, t_cer) * 1000;
70 69 dev_t.t_avdp_w = dev_t.t_avdp_r;
71 /* Read */ 70 dev_t.t_aavdh = t_aavdh * 1000;
72 t.adv_rd_off = gpmc_round_ns_to_ticks(max_t(int, t_avdp, t_cer)); 71 dev_t.t_aa = t_aa * 1000;
73 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(t_aavdh); 72 dev_t.t_ce = t_ce * 1000;
74 t.access = t.adv_on + gpmc_round_ns_to_ticks(t_aa); 73 dev_t.t_oe = t_oe * 1000;
75 t.access = max_t(int, t.access, t.cs_on + gpmc_round_ns_to_ticks(t_ce)); 74 dev_t.t_cez_r = t_cez * 1000;
76 t.access = max_t(int, t.access, t.oe_on + gpmc_round_ns_to_ticks(t_oe)); 75 dev_t.t_cez_w = dev_t.t_cez_r;
77 t.oe_off = t.access + gpmc_round_ns_to_ticks(1); 76 dev_t.t_wpl = t_wpl * 1000;
78 t.cs_rd_off = t.oe_off; 77 dev_t.t_wph = t_wph * 1000;
79 t.rd_cycle = t.cs_rd_off + gpmc_round_ns_to_ticks(t_cez); 78
80 79 gpmc_calc_timings(&t, &dev_t);
81 /* Write */
82 t.adv_wr_off = t.adv_rd_off;
83 t.we_on = t.oe_on;
84 if (cpu_is_omap34xx()) {
85 t.wr_data_mux_bus = t.we_on;
86 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
87 }
88 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl);
89 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
90 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
91 80
92 return t; 81 return t;
93} 82}
@@ -173,16 +162,15 @@ static struct gpmc_timings
173omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg, 162omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
174 int freq) 163 int freq)
175{ 164{
165 struct gpmc_device_timings dev_t;
176 struct gpmc_timings t; 166 struct gpmc_timings t;
177 const int t_cer = 15; 167 const int t_cer = 15;
178 const int t_avdp = 12; 168 const int t_avdp = 12;
179 const int t_cez = 20; /* max of t_cez, t_oez */ 169 const int t_cez = 20; /* max of t_cez, t_oez */
180 const int t_ds = 30;
181 const int t_wpl = 40; 170 const int t_wpl = 40;
182 const int t_wph = 30; 171 const int t_wph = 30;
183 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo; 172 int min_gpmc_clk_period, t_ces, t_avds, t_avdh, t_ach, t_aavdh, t_rdyo;
184 int div, fclk_offset_ns, gpmc_clk_ns; 173 int div, gpmc_clk_ns;
185 int ticks_cez;
186 174
187 if (cfg->flags & ONENAND_SYNC_READ) 175 if (cfg->flags & ONENAND_SYNC_READ)
188 onenand_flags = ONENAND_FLAG_SYNCREAD; 176 onenand_flags = ONENAND_FLAG_SYNCREAD;
@@ -249,62 +237,35 @@ omap2_onenand_calc_sync_timings(struct omap_onenand_platform_data *cfg,
249 latency = 4; 237 latency = 4;
250 238
251 /* Set synchronous read timings */ 239 /* Set synchronous read timings */
252 memset(&t, 0, sizeof(t)); 240 memset(&dev_t, 0, sizeof(dev_t));
253
254 if (div == 1) {
255 t.bool_timings.cs_extra_delay = true;
256 t.bool_timings.adv_extra_delay = true;
257 t.bool_timings.oe_extra_delay = true;
258 t.bool_timings.we_extra_delay = true;
259 }
260 241
261 t.sync_clk = min_gpmc_clk_period; 242 dev_t.mux = true;
262 t.cs_on = 0; 243 dev_t.sync_read = true;
263 t.adv_on = 0;
264 fclk_offset_ns = gpmc_round_ns_to_ticks(max_t(int, t_ces, t_avds));
265 fclk_offset = gpmc_ns_to_ticks(fclk_offset_ns);
266 t.page_burst_access = gpmc_clk_ns;
267
268 /* Read */
269 t.adv_rd_off = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_avdh));
270 t.oe_on = gpmc_ticks_to_ns(fclk_offset + gpmc_ns_to_ticks(t_ach));
271 /* Force at least 1 clk between AVD High to OE Low */
272 if (t.oe_on <= t.adv_rd_off)
273 t.oe_on = t.adv_rd_off + gpmc_round_ns_to_ticks(1);
274 t.access = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div);
275 t.oe_off = t.access + gpmc_round_ns_to_ticks(1);
276 t.cs_rd_off = t.oe_off;
277 ticks_cez = ((gpmc_ns_to_ticks(t_cez) + div - 1) / div) * div;
278 t.rd_cycle = gpmc_ticks_to_ns(fclk_offset + (latency + 1) * div +
279 ticks_cez);
280
281 t.clk_activation = fclk_offset_ns;
282
283 /* Write */
284 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) { 244 if (onenand_flags & ONENAND_FLAG_SYNCWRITE) {
285 t.adv_wr_off = t.adv_rd_off; 245 dev_t.sync_write = true;
286 t.we_on = 0;
287 t.we_off = t.cs_rd_off;
288 t.cs_wr_off = t.cs_rd_off;
289 t.wr_cycle = t.rd_cycle;
290 if (cpu_is_omap34xx()) {
291 t.wr_data_mux_bus = gpmc_ticks_to_ns(fclk_offset +
292 gpmc_ps_to_ticks(min_gpmc_clk_period +
293 t_rdyo * 1000));
294 t.wr_access = t.access;
295 }
296 } else { 246 } else {
297 t.adv_wr_off = gpmc_round_ns_to_ticks(max_t(int, 247 dev_t.t_avdp_w = max(t_avdp, t_cer) * 1000;
298 t_avdp, t_cer)); 248 dev_t.t_wpl = t_wpl * 1000;
299 t.we_on = t.adv_wr_off + gpmc_round_ns_to_ticks(t_aavdh); 249 dev_t.t_wph = t_wph * 1000;
300 t.we_off = t.we_on + gpmc_round_ns_to_ticks(t_wpl); 250 dev_t.t_aavdh = t_aavdh * 1000;
301 t.cs_wr_off = t.we_off + gpmc_round_ns_to_ticks(t_wph);
302 t.wr_cycle = t.cs_wr_off + gpmc_round_ns_to_ticks(t_cez);
303 if (cpu_is_omap34xx()) {
304 t.wr_data_mux_bus = t.we_on;
305 t.wr_access = t.we_on + gpmc_round_ns_to_ticks(t_ds);
306 }
307 } 251 }
252 dev_t.ce_xdelay = true;
253 dev_t.avd_xdelay = true;
254 dev_t.oe_xdelay = true;
255 dev_t.we_xdelay = true;
256 dev_t.clk = min_gpmc_clk_period;
257 dev_t.t_bacc = dev_t.clk;
258 dev_t.t_ces = t_ces * 1000;
259 dev_t.t_avds = t_avds * 1000;
260 dev_t.t_avdh = t_avdh * 1000;
261 dev_t.t_ach = t_ach * 1000;
262 dev_t.cyc_iaa = (latency + 1);
263 dev_t.t_cez_r = t_cez * 1000;
264 dev_t.t_cez_w = dev_t.t_cez_r;
265 dev_t.cyc_aavdh_oe = 1;
266 dev_t.t_rdyo = t_rdyo * 1000 + min_gpmc_clk_period;
267
268 gpmc_calc_timings(&t, &dev_t);
308 269
309 return t; 270 return t;
310} 271}