msm: timer: Use 32765 hz GPT and SCLK on 8960 family

In the 8960 family of chips, the 32768 Hz crystal is optional, and our
internal targets instead choose to use a divided TCXO. This runs at
32764.5051 Hz. Approximate this with 32765 Hz in the timer driver.

CRs-Fixed: 303006
Change-Id: I9f2ac8a9faf5d7ffbbddb21666f9ab6845d93743
Signed-off-by: Jeff Ohlstein <johlstei@codeaurora.org>
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 7db146c..21aa501 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -76,9 +76,8 @@
 
 #define NR_TIMERS ARRAY_SIZE(msm_clocks)
 
-#define GPT_HZ 32768
-#define SCLK_HZ 32768
-
+unsigned int gpt_hz = 32768;
+unsigned int sclk_hz = 32768;
 
 static struct msm_clock *clockevent_to_clock(struct clock_event_device *evt);
 static irqreturn_t msm_timer_interrupt(int irq, void *dev_id);
@@ -160,7 +159,7 @@
 			.irq     = INT_GP_TIMER_EXP
 		},
 		.regbase = MSM_TMR_BASE + 0x4,
-		.freq = GPT_HZ,
+		.freq = 32768,
 		.index = MSM_CLOCK_GPT,
 		.flags =
 #if defined(CONFIG_CPU_V6) || defined(CONFIG_ARCH_MSM7X27A)
@@ -429,7 +428,9 @@
 	uint32_t t1, t2;
 	int loop_count = 10;
 	int loop_zero_count = 3;
-	int tmp = USEC_PER_SEC/SCLK_HZ/(loop_zero_count-1);
+	int tmp = USEC_PER_SEC;
+	do_div(tmp, sclk_hz);
+	tmp /= (loop_zero_count-1);
 
 	while (loop_zero_count--) {
 		t1 = __raw_readl(MSM_RPM_MPM_BASE + MPM_SCLK_COUNT_VAL);
@@ -456,7 +457,7 @@
 	}
 
 	if (update != NULL)
-		update(data, t1, SCLK_HZ);
+		update(data, t1, sclk_hz);
 	return t1;
 }
 #elif defined(CONFIG_MSM_N_WAY_SMSM)
@@ -527,7 +528,7 @@
 
 	if (smem_clock_val) {
 		if (update != NULL)
-			update(data, smem_clock_val, SCLK_HZ);
+			update(data, smem_clock_val, sclk_hz);
 
 		if (msm_timer_debug_mask & MSM_TIMER_DEBUG_SYNC)
 			printk(KERN_INFO
@@ -601,7 +602,7 @@
 
 	if (smem_clock_val) {
 		if (update != NULL)
-			update(data, smem_clock_val, SCLK_HZ);
+			update(data, smem_clock_val, sclk_hz);
 	} else {
 		printk(KERN_EMERG
 			"get_smem_clock: timeout state %x clock %u\n",
@@ -721,9 +722,11 @@
 		&__get_cpu_var(msm_clocks_percpu)[clock->index];
 	struct msm_timer_sync_data_t data;
 	uint32_t gpt_clk_val;
-	u64 gpt_period = (1ULL << 32) * HZ / GPT_HZ;
+	u64 gpt_period = (1ULL << 32) * HZ;
 	u64 now = get_jiffies_64();
 
+	do_div(gpt_period, gpt_hz);
+
 	BUG_ON(clock == gpt_clk);
 
 	if (clock_state->in_sync &&
@@ -740,7 +743,7 @@
 	data.timeout = 0;
 	data.exit_sleep = exit_sleep;
 
-	msm_timer_sync_update(&data, gpt_clk_val, GPT_HZ);
+	msm_timer_sync_update(&data, gpt_clk_val, gpt_hz);
 
 	clock_state->in_sync = 1;
 	clock_state->last_sync_gpt = gpt_clk_val;
@@ -897,12 +900,14 @@
 
 	if (period) {
 		tmp = 1LL << 32;
-		tmp = tmp * NSEC_PER_SEC / SCLK_HZ;
+		tmp *= NSEC_PER_SEC;
+		do_div(tmp, sclk_hz);
 		*period = tmp;
 	}
 
 	tmp = (int64_t)clock_value;
-	tmp = tmp * NSEC_PER_SEC / SCLK_HZ;
+	tmp *= NSEC_PER_SEC;
+	do_div(tmp, sclk_hz);
 	return tmp;
 }
 
@@ -988,10 +993,16 @@
 		dgt->freq = 4800000;
 	else if (cpu_is_msm7x30() || cpu_is_msm8x55())
 		dgt->freq = 6144000;
-	else if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_msm9615() ||
-		 cpu_is_apq8064() || cpu_is_msm8x30()) {
+	else if (cpu_is_msm8x60()) {
 		dgt->freq = 6750000;
 		__raw_writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+	} else if (cpu_is_msm8960() || cpu_is_apq8064() || cpu_is_msm8x30()
+		|| cpu_is_msm9615()) {
+		dgt->freq = 6750000;
+		__raw_writel(DGT_CLK_CTL_DIV_4, MSM_TMR_BASE + DGT_CLK_CTL);
+		gpt->freq = 32765;
+		gpt_hz = 32765;
+		sclk_hz = 32765;
 	} else {
 		WARN_ON("Timer running on unknown hardware. Configure this! "
 			"Assuming default configuration.\n");
@@ -1012,14 +1023,14 @@
 		__raw_writel(0, clock->regbase + TIMER_COUNT_VAL);
 		__raw_writel(~0, clock->regbase + TIMER_MATCH_VAL);
 
-		if ((clock->freq << clock->shift) == GPT_HZ) {
+		if ((clock->freq << clock->shift) == gpt_hz) {
 			clock->rollover_offset = 0;
 		} else {
 			uint64_t temp;
 
 			temp = clock->freq << clock->shift;
 			temp <<= 32;
-			temp /= GPT_HZ;
+			do_div(temp, gpt_hz);
 
 			clock->rollover_offset = (uint32_t) temp;
 		}