From 101b3d4c558bae420cbeba634f4deeae27c3b905 Mon Sep 17 00:00:00 2001
From: Afzal Mohammed <afzal@ti.com>
Date: Wed, 12 Sep 2012 19:30:27 +0530
Subject: [PATCH] gpmc: rounding error fix

Signed-off-by: Afzal Mohammed <afzal@ti.com>
---
 arch/arm/mach-omap2/gpmc.c             |  150 +++++++++++++++-----------------
 arch/arm/plat-omap/include/plat/gpmc.h |   40 ++++----
 2 files changed, 90 insertions(+), 100 deletions(-)

diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index d8e5b08..e9d57db 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -289,11 +289,11 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	if (time == 0)
 		ticks = 0;
 	else
-		ticks = gpmc_ns_to_ticks(time);
+		ticks = gpmc_ps_to_ticks(time);
 	nr_bits = end_bit - st_bit + 1;
 	if (ticks >= 1 << nr_bits) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d: %-10s* %3d ns, %3d ticks >= %d\n",
+		pr_info("GPMC CS%d: %-10s* %3d ps, %3d ticks >= %d\n",
 				cs, name, time, ticks, 1 << nr_bits);
 #endif
 		return -1;
@@ -302,10 +302,9 @@ static int set_gpmc_timing_reg(int cs, int reg, int st_bit, int end_bit,
 	mask = (1 << nr_bits) - 1;
 	l = gpmc_cs_read_reg(cs, reg);
 #ifdef DEBUG
-	printk(KERN_INFO
-		"GPMC CS%d: %-10s: %3d ticks, %3lu ns (was %3i ticks) %3d ns\n",
-	       cs, name, ticks, gpmc_get_fclk_period() * ticks / 1000,
-			(l >> st_bit) & mask, time);
+	pr_info("GPMC CS%d: %-10s: %3d ticks, %3lu ps (was %3i ticks) %3d ps\n",
+		cs, name, ticks, gpmc_get_fclk_period() * ticks,
+		(l >> st_bit) & mask, time);
 #endif
 	l &= ~(mask << st_bit);
 	l |= ticks << st_bit;
@@ -385,8 +384,8 @@ int gpmc_cs_set_timings(int cs, const struct gpmc_timings *t)
 	l = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1);
 	if (l & (GPMC_CONFIG1_READTYPE_SYNC | GPMC_CONFIG1_WRITETYPE_SYNC)) {
 #ifdef DEBUG
-		printk(KERN_INFO "GPMC CS%d CLK period is %lu ns (div %d)\n",
-				cs, (div * gpmc_get_fclk_period()) / 1000, div);
+		pr_info("GPMC CS%d CLK period is %lu ps (div %d)\n",
+				cs, div * gpmc_get_fclk_period(), div);
 #endif
 		l &= ~0x03;
 		l |= (div - 1);
@@ -922,46 +921,42 @@ static int gpmc_calc_sync_read_timings(struct gpmc_timings *gpmc_t,
 		 * indirectly necessitates requirement of t_avdp_r & t_avdp_w
 		 * instead of having a single t_avdp
 		 */
-		temp = max_t(u32, temp,	gpmc_t->clk_activation * 1000 +
-							dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu; /* remove this ? */
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_ach);
-		temp = max_t(u32, temp, (gpmc_t->adv_rd_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_oe)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->clk_activation + dev_t->t_ach);
+		temp = max_t(u32, temp, gpmc_t->adv_rd_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_oe));
 	}
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	/* any scope for improvement ?, by combining oe_on & clk_activation,
 	 * need to check whether access = clk_activation + round to sync clk ?
 	 */
 	temp = max_t(u32, dev_t->t_iaa,	dev_t->cyc_iaa * gpmc_t->sync_clk);
-	temp += gpmc_t->clk_activation * 1000;
+	temp += gpmc_t->clk_activation;
 	if (dev_t->cyc_oe)
-		temp = max_t(u32, temp, (gpmc_t->oe_on +
-				gpmc_ticks_to_ns(dev_t->cyc_oe)) * 1000);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp, gpmc_t->oe_on +
+				gpmc_ticks_to_ps(dev_t->cyc_oe));
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_cez_r, dev_t->t_oez);
 	temp = gpmc_round_ps_to_sync_clk(temp, gpmc_t->sync_clk) +
-							gpmc_t->access * 1000;
+							gpmc_t->access;
 	/* barter t_ce_rdyz with t_cez_r ? */
 	if (dev_t->t_ce_rdyz)
-		temp = max_t(u32, temp,
-				gpmc_t->cs_rd_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, temp,	gpmc_t->cs_rd_off + dev_t->t_ce_rdyz);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -976,29 +971,28 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	temp = dev_t->t_avdp_w;
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->clk_activation * 1000 + dev_t->t_avdh);
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
+			gpmc_t->clk_activation + dev_t->t_avdh);
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
 	}
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = max_t(u32, dev_t->t_weasu,
-			gpmc_t->clk_activation * 1000 + dev_t->t_rdyo);
+			gpmc_t->clk_activation + dev_t->t_rdyo);
 	/* shouldn't mux be kept as a whole for wr_data_mux_bus ?,
 	 * and in that case remember to handle we_on properly
 	 */
 	if (mux) {
 		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+			gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
@@ -1007,24 +1001,24 @@ static int gpmc_calc_sync_write_timings(struct gpmc_timings *gpmc_t,
 	gpmc_t->wr_access = gpmc_t->access;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
 	temp = max_t(u32, temp,
-			(gpmc_t->wr_access + gpmc_ticks_to_ns(1)) * 1000);
+			gpmc_t->wr_access + gpmc_ticks_to_ps(1));
 	temp = max_t(u32, temp,
-		(gpmc_t->we_on + gpmc_ticks_to_ns(dev_t->cyc_wpl)) * 1000);
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		gpmc_t->we_on + gpmc_ticks_to_ps(dev_t->cyc_wpl));
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off * 1000 +
-							dev_t->t_wph) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = gpmc_round_ps_to_sync_clk(dev_t->t_cez_w, gpmc_t->sync_clk);
-	temp += gpmc_t->wr_access * 1000;
+	temp += gpmc_t->wr_access;
 	/* barter t_ce_rdyz with t_cez_w ? */
 	if (dev_t->t_ce_rdyz)
 		temp = max_t(u32, temp,
-				 gpmc_t->cs_wr_off * 1000 + dev_t->t_ce_rdyz);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				 gpmc_t->cs_wr_off + dev_t->t_ce_rdyz);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1038,35 +1032,33 @@ static int gpmc_calc_async_read_timings(struct gpmc_timings *gpmc_t,
 	/* adv_rd_off */
 	temp = dev_t->t_avdp_r;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_rd_off = gpmc_round_ps_to_ticks(temp);
 
 	/* oe_on */
 	temp = dev_t->t_oeasu;
 	if (mux)
 		temp = max_t(u32, temp,
-			gpmc_t->adv_rd_off * 1000 + dev_t->t_aavdh);
-	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->adv_rd_off + dev_t->t_aavdh);
+	gpmc_t->oe_on = gpmc_round_ps_to_ticks(temp);
 
 	/* access */
 	temp = max_t(u32, dev_t->t_iaa, /* remove t_iaa in async ? */
-				gpmc_t->oe_on * 1000 + dev_t->t_oe);
+				gpmc_t->oe_on + dev_t->t_oe);
 	temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce);
+				gpmc_t->cs_on + dev_t->t_ce);
 	temp = max_t(u32, temp,
-				gpmc_t->adv_on * 1000 + dev_t->t_aa);
-	gpmc_t->access = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->adv_on + dev_t->t_aa);
+	gpmc_t->access = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ns(1);
+	gpmc_t->oe_off = gpmc_t->access + gpmc_ticks_to_ps(1);
 	gpmc_t->cs_rd_off = gpmc_t->oe_off;
 
 	/* rd_cycle */
 	temp = max_t(u32, dev_t->t_rd_cycle,
-			gpmc_t->cs_rd_off * 1000 + dev_t->t_cez_r);
-	temp = max_t(u32, temp,
-			gpmc_t->oe_off * 1000 + dev_t->t_oez);
-	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+			gpmc_t->cs_rd_off + dev_t->t_cez_r);
+	temp = max_t(u32, temp, gpmc_t->oe_off + dev_t->t_oez);
+	gpmc_t->rd_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1080,37 +1072,35 @@ static int gpmc_calc_async_write_timings(struct gpmc_timings *gpmc_t,
 	/* adv_wr_off */
 	temp = dev_t->t_avdp_w;
 	if (mux)
-		temp = max_t(u32,
-			(gpmc_t->adv_on + gpmc_ticks_to_ns(1)) * 1000, temp);
-	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp) / 1000;
+		temp = max_t(u32, gpmc_t->adv_on + gpmc_ticks_to_ps(1), temp);
+	gpmc_t->adv_wr_off = gpmc_round_ps_to_ticks(temp);
 
 	/* wr_data_mux_bus */
 	temp = dev_t->t_weasu;
 	if (mux) {
-		temp = max_t(u32, temp,
-			gpmc_t->adv_wr_off * 1000 + dev_t->t_aavdh);
-		temp = max_t(u32, temp, (gpmc_t->adv_wr_off +
-				gpmc_ticks_to_ns(dev_t->cyc_aavdh_we)) * 1000);
+		temp = max_t(u32, temp,	gpmc_t->adv_wr_off + dev_t->t_aavdh);
+		temp = max_t(u32, temp, gpmc_t->adv_wr_off +
+				gpmc_ticks_to_ps(dev_t->cyc_aavdh_we));
 	}
-	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->wr_data_mux_bus = gpmc_round_ps_to_ticks(temp);
 
 	/* we_on */
 	if (gpmc_capability & GPMC_HAS_WR_DATA_MUX_BUS)
-		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu) / 1000;
+		gpmc_t->we_on = gpmc_round_ps_to_ticks(dev_t->t_weasu);
 	else
 		gpmc_t->we_on = gpmc_t->wr_data_mux_bus;
 
 	/* we_off */
-	temp = gpmc_t->we_on * 1000 + dev_t->t_wpl;
-	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp) / 1000;
+	temp = gpmc_t->we_on + dev_t->t_wpl;
+	gpmc_t->we_off = gpmc_round_ps_to_ticks(temp);
 
-	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks((gpmc_t->we_off * 1000 +
-				dev_t->t_wph)) / 1000;
+	gpmc_t->cs_wr_off = gpmc_round_ps_to_ticks(gpmc_t->we_off +
+							dev_t->t_wph);
 
 	/* wr_cycle */
 	temp = max_t(u32, dev_t->t_wr_cycle,
-				gpmc_t->cs_wr_off * 1000 + dev_t->t_cez_w);
-	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp) / 1000;
+				gpmc_t->cs_wr_off + dev_t->t_cez_w);
+	gpmc_t->wr_cycle = gpmc_round_ps_to_ticks(temp);
 
 	return 0;
 }
@@ -1125,10 +1115,10 @@ static int gpmc_calc_sync_common_timings(struct gpmc_timings *gpmc_t,
 
 	gpmc_t->page_burst_access = gpmc_round_ps_to_sync_clk(
 					dev_t->t_bacc,
-					gpmc_t->sync_clk) / 1000;
+					gpmc_t->sync_clk);
 
 	temp = max_t(u32, dev_t->t_ces, dev_t->t_avds);
-	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp) / 1000;
+	gpmc_t->clk_activation = gpmc_round_ps_to_ticks(temp);
 
 	if (gpmc_calc_divider(gpmc_t->sync_clk) != 1)
 		return 0;
@@ -1151,14 +1141,14 @@ static int gpmc_calc_common_timings(struct gpmc_timings *gpmc_t,
 	u32 temp;
 
 	/* cs_on */
-	gpmc_t->cs_on = gpmc_round_ns_to_ticks(dev_t->t_ceasu / 1000);
+	gpmc_t->cs_on = gpmc_round_ps_to_ticks(dev_t->t_ceasu);
 
 	/* adv_on */
 	temp = dev_t->t_avdasu;
 	if (dev_t->t_ce_avd)
 		temp = max_t(u32, temp,
-				gpmc_t->cs_on * 1000 + dev_t->t_ce_avd);
-	gpmc_t->adv_on = gpmc_round_ns_to_ticks(temp / 1000);
+				gpmc_t->cs_on + dev_t->t_ce_avd);
+	gpmc_t->adv_on = gpmc_round_ps_to_ticks(temp);
 
 	if (dev_t->sync_write || dev_t->sync_read)
 		gpmc_calc_sync_common_timings(gpmc_t, dev_t);
diff --git a/arch/arm/plat-omap/include/plat/gpmc.h b/arch/arm/plat-omap/include/plat/gpmc.h
index e59a932..f1d1d2e 100644
--- a/arch/arm/plat-omap/include/plat/gpmc.h
+++ b/arch/arm/plat-omap/include/plat/gpmc.h
@@ -116,38 +116,38 @@ struct gpmc_timings {
 	u32 sync_clk;
 
 	/* Chip-select signal timings corresponding to GPMC_CS_CONFIG2 */
-	u16 cs_on;		/* Assertion time */
-	u16 cs_rd_off;		/* Read deassertion time */
-	u16 cs_wr_off;		/* Write deassertion time */
+	u32 cs_on;		/* Assertion time */
+	u32 cs_rd_off;		/* Read deassertion time */
+	u32 cs_wr_off;		/* Write deassertion time */
 
 	/* ADV signal timings corresponding to GPMC_CONFIG3 */
-	u16 adv_on;		/* Assertion time */
-	u16 adv_rd_off;		/* Read deassertion time */
-	u16 adv_wr_off;		/* Write deassertion time */
+	u32 adv_on;		/* Assertion time */
+	u32 adv_rd_off;		/* Read deassertion time */
+	u32 adv_wr_off;		/* Write deassertion time */
 
 	/* WE signals timings corresponding to GPMC_CONFIG4 */
-	u16 we_on;		/* WE assertion time */
-	u16 we_off;		/* WE deassertion time */
+	u32 we_on;		/* WE assertion time */
+	u32 we_off;		/* WE deassertion time */
 
 	/* OE signals timings corresponding to GPMC_CONFIG4 */
-	u16 oe_on;		/* OE assertion time */
-	u16 oe_off;		/* OE deassertion time */
+	u32 oe_on;		/* OE assertion time */
+	u32 oe_off;		/* OE deassertion time */
 
 	/* Access time and cycle time timings corresponding to GPMC_CONFIG5 */
-	u16 page_burst_access;	/* Multiple access word delay */
-	u16 access;		/* Start-cycle to first data valid delay */
-	u16 rd_cycle;		/* Total read cycle time */
-	u16 wr_cycle;		/* Total write cycle time */
+	u32 page_burst_access;	/* Multiple access word delay */
+	u32 access;		/* Start-cycle to first data valid delay */
+	u32 rd_cycle;		/* Total read cycle time */
+	u32 wr_cycle;		/* Total write cycle time */
 
-	u16 bus_turnaround;
-	u16 cycle2cycle_delay;
+	u32 bus_turnaround;
+	u32 cycle2cycle_delay;
 
-	u16 wait_monitoring;
-	u16 clk_activation;
+	u32 wait_monitoring;
+	u32 clk_activation;
 
 	/* The following are only on OMAP3430 */
-	u16 wr_access;		/* WRACCESSTIME */
-	u16 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
+	u32 wr_access;		/* WRACCESSTIME */
+	u32 wr_data_mux_bus;	/* WRDATAONADMUXBUS */
 
 	struct gpmc_bool_timings bool_timings;
 };
-- 
1.7.0.4

