[coreboot-gerrit] Patch set updated for coreboot: b88addc soc/ipq806x: Replace GPT with fine grained DGT timer.

Marc Jones (marc.jones@se-eng.com) gerrit at coreboot.org
Fri Mar 13 18:42:58 CET 2015


Marc Jones (marc.jones at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8596

-gerrit

commit b88addcd03c49f1009595dd42d04f576d3fedd37
Author: Deepa Dinamani <deepad at codeaurora.org>
Date:   Mon Jul 14 16:26:11 2014 -0700

    soc/ipq806x: Replace GPT with fine grained DGT timer.
    
    Support 1MHz libpayload restriction on timer implementation
    by using DGT (debug) timer instead of GPT (general purpose) timer.
    
    BUG=chrome-os-partner:28880
    TEST=manual
      verified DGT timer functions in coreboot and depthcharge.
    
    Original-Change-Id: Iab322d7e863e3959c027e9ce876223a64eb7e257
    Original-Signed-off-by: Deepa Dinamani <deepad at codeaurora.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/201574
    Original-Reviewed-by: Vadim Bendebury <vbendeb at chromium.org>
    Original-Commit-Queue: Vadim Bendebury <vbendeb at chromium.org>
    Original-Tested-by: Vadim Bendebury <vbendeb at chromium.org>
    (cherry picked from commit ddf11eee5ec2d86a62095e932dbec9313b8fb9e1)
    Signed-off-by: Marc Jones <marc.jones at se-eng.com>
    
    Change-Id: Id73e805801fd8d135b607df9f4f8caf567ec5b83
---
 src/soc/qualcomm/ipq806x/timer.c | 125 ++++++++++++++-------------------------
 1 file changed, 43 insertions(+), 82 deletions(-)

diff --git a/src/soc/qualcomm/ipq806x/timer.c b/src/soc/qualcomm/ipq806x/timer.c
index 3cb9531..ce11126 100644
--- a/src/soc/qualcomm/ipq806x/timer.c
+++ b/src/soc/qualcomm/ipq806x/timer.c
@@ -1,8 +1,5 @@
 /*
- * Copyright (c) 2012 - 2013 The Linux Foundation. All rights reserved.
- * Source : APQ8064 LK boot
- *
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 - 2014 The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,103 +33,67 @@
 #include <ipq_timer.h>
 #include <timer.h>
 
-#define GPT_FREQ_KHZ    32
-#define GPT_FREQ	(GPT_FREQ_KHZ * 1000)	/* 32 KHz */
+/*
+ * DGT runs at 25 MHz / 4, or 6.25 ticks per microsecond
+ */
+#define DGT_MHZ_NUM         25
+#define DGT_MHZ_DEN         4
+
+#define TIMER_TICKS(us) ((DGT_MHZ_NUM*(us)+(DGT_MHZ_DEN-1))/DGT_MHZ_DEN)
+#define TIMER_USECS(ticks) (DGT_MHZ_DEN*(ticks)/DGT_MHZ_NUM)
+
+/* Clock divider values for the timer. */
+#define DGT_CLK_DIV_1      0
+#define DGT_CLK_DIV_2      1
+#define DGT_CLK_DIV_3      2
+#define DGT_CLK_DIV_4      3
 
 /**
  * init_timer - initialize timer
  */
 void init_timer(void)
 {
-	writel(0, GPT_ENABLE);
-	writel(GPT_ENABLE_EN, GPT_ENABLE);
+	/* disable timer */
+	writel_i(0, DGT_ENABLE);
+
+	/* DGT uses TCXO source which is 25MHz.
+	 * The timer should run at 1/4th the frequency of TCXO
+	 * according to clock plan.
+	 * Set clock divider to 4.
+	 */
+	writel_i(DGT_CLK_DIV_4, DGT_CLK_CTL);
+
+	/* Enable timer */
+	writel_i(0, DGT_CLEAR);
+	writel_i(DGT_ENABLE_EN, DGT_ENABLE);
 }
 
 /**
  * udelay -  generates micro second delay.
  * @param usec: delay duration in microseconds
- *
- * With 32KHz clock, minimum possible delay is 31.25 Micro seconds and
- * its multiples. In Rumi GPT clock is 32 KHz
  */
 void udelay(unsigned usec)
 {
-	unsigned val;
-	unsigned now, last;
-	unsigned runcount;
+	uint32_t now;
+	uint32_t last;
+	uint32_t ticks;
+	uint32_t curr_ticks = 0;
 
-	usec = (usec + GPT_FREQ_KHZ - 1) / GPT_FREQ_KHZ;
-	last = readl(GPT_COUNT_VAL);
-	runcount = last;
-	val = usec + last;
+	/* Calculate number of ticks required. */
+	ticks = TIMER_TICKS(usec);
 
-	do {
-		now = readl(GPT_COUNT_VAL);
-		if (last > now)
-			runcount += ((GPT_FREQ - last) + now);
-		else
-			runcount += (now - last);
-		last = now;
-	} while (runcount < val);
-}
-
-void timer_monotonic_get(struct mono_time *mt)
-{
-	mono_time_set_usecs(mt, (readl(GPT_COUNT_VAL) * 1000) / GPT_FREQ_KHZ);
-}
-
-#if 0
-
-/*
- * TODO(vbendeb) clean it up later.
- * Compile out the below code but leave it for now in case it will become
- * necessary later in order to make the platform fully functional.
- */
-static unsigned long timestamp;
-static unsigned long lastinc;
+	/* Obtain the current timer value. */
+	last = readl_i(DGT_COUNT_VAL);
 
-inline ulong gpt_to_sys_freq(unsigned int gpt)
-{
-	/*
-	 * get_timer() expects the timer increments to be in terms
-	 * of CONFIG_SYS_HZ. Convert GPT timer values to CONFIG_SYS_HZ
-	 * units.
-	 */
-	return (((ulong)gpt) / (GPT_FREQ / CONFIG_SYS_HZ));
-}
-
-/**
- * get_timer_masked - returns current ticks
- *
- * Returns the current timer ticks, since boot.
- */
-ulong get_timer_masked(void)
-{
-	ulong now = gpt_to_sys_freq(readl(GPT_COUNT_VAL));
-
-	if (lastinc <= now) {	/* normal mode (non roll) */
-		/* normal mode */
-		timestamp += now - lastinc;
-		/* move stamp forward with absolute diff ticks */
-	} else {		/* we have overflow of the count down timer */
-		timestamp += now + (TIMER_LOAD_VAL - lastinc);
+	/* Loop until the right number of ticks. */
+	while (curr_ticks < ticks) {
+		now = readl_i(DGT_COUNT_VAL);
+		curr_ticks += now - last;
+		last = now;
 	}
-
-	lastinc = now;
-
-	return timestamp;
 }
 
-unsigned long long get_ticks(void)
-{
-	return readl(GPT_COUNT_VAL);
-}
-
-/*
- * Return the number of timer ticks per second.
- */
-ulong get_tbclk(void)
+void timer_monotonic_get(struct mono_time *mt)
 {
-        return GPT_FREQ;
+	mono_time_set_usecs(mt, TIMER_USECS(readl_i(DGT_COUNT_VAL)));
 }
-#endif



More information about the coreboot-gerrit mailing list