summaryrefslogtreecommitdiff
path: root/src/soc/qualcomm/ipq40xx/timer.c
diff options
context:
space:
mode:
authorVaradarajan Narayanan <varada@codeaurora.org>2016-03-03 13:30:07 +0530
committerPatrick Georgi <pgeorgi@google.com>2016-05-10 22:51:59 +0200
commit9541ba828f63eb63d91b09bb1ee29b46b9f26d6c (patch)
tree51ac97ec1f987b7130a0da58c2a13b63d49e6230 /src/soc/qualcomm/ipq40xx/timer.c
parent5df833179d0b5acd7c5598e8400f34904265b8b7 (diff)
downloadcoreboot-9541ba828f63eb63d91b09bb1ee29b46b9f26d6c.tar.xz
soc/qualcomm/ipq40xx: Enable timer
BUG=chrome-os-partner:49249 TEST=None. Initial code not sure if it will even compile BRANCH=none Original-Commit-Id: 35c0e6046899dc1af03736ae9fa77f9eeec7f668 Original-Change-Id: I681e92fa673c1d3aee2974a7bba5074e2bfd6e02 Original-Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Original-Reviewed-on: https://chromium-review.googlesource.com/333297 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> squashed: soc/qualcomm/ipq40xx: Enable UART on ipq40xx - BLSP/UART Clock configuration - GPIO Configuration BUG=chrome-os-partner:49249 TEST=None. Initial code not sure if it will even compile BRANCH=none Original-Commit-Id: 7bba1fc7f50e7aeb4e7b37f164e85771e53f47e6 Original-Change-Id: I474a0e97b24ac9b3f2cba599cd709b6801b08f91 Original-Signed-off-by: Varadarajan Narayanan <varada@codeaurora.org> Original-Reviewed-on: https://chromium-review.googlesource.com/333300 Original-Commit-Ready: David Hendricks <dhendrix@chromium.org> Original-Reviewed-by: David Hendricks <dhendrix@chromium.org> Change-Id: I5e31d036ee7ddcf72ed9739cef1f7f7d0ca6c427 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Reviewed-on: https://review.coreboot.org/14667 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc/qualcomm/ipq40xx/timer.c')
-rw-r--r--src/soc/qualcomm/ipq40xx/timer.c63
1 files changed, 25 insertions, 38 deletions
diff --git a/src/soc/qualcomm/ipq40xx/timer.c b/src/soc/qualcomm/ipq40xx/timer.c
index 7b8c1f0cf6..d5650ec2d9 100644
--- a/src/soc/qualcomm/ipq40xx/timer.c
+++ b/src/soc/qualcomm/ipq40xx/timer.c
@@ -32,20 +32,10 @@
#include <soc/ipq_timer.h>
#include <timer.h>
-/*
- * 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)
+#define GCNT_FREQ_MHZ 48
-/* 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
+#define TIMER_TICKS(us) (GCNT_FREQ_MHZ * (us))
+#define TIMER_USECS(ticks) ((ticks) / GCNT_FREQ_MHZ)
/**
* init_timer - initialize timer
@@ -53,18 +43,26 @@
void init_timer(void)
{
/* disable timer */
- writel_i(0, DGT_ENABLE);
+ write32(GCNT_CNTCR, 0);
- /* 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);
+ /* Reset the counters to zero */
+ write32(GCNT_GLB_CNTCV_LO, 0);
+ write32(GCNT_GLB_CNTCV_HI, 0);
/* Enable timer */
- writel_i(0, DGT_CLEAR);
- writel_i(DGT_ENABLE_EN, DGT_ENABLE);
+ write32(GCNT_CNTCR, 1);
+}
+
+static inline uint64_t read_gcnt_val(void)
+{
+ uint32_t hi, lo;
+
+ do {
+ hi = read32(GCNT_CNTCV_HI);
+ lo = read32(GCNT_CNTCV_LO);
+ } while (hi != read32(GCNT_CNTCV_HI));
+
+ return ((((uint64_t)hi) << 32) | lo);
}
/**
@@ -73,26 +71,15 @@ void init_timer(void)
*/
void udelay(unsigned usec)
{
- uint32_t now;
- uint32_t last;
- uint32_t ticks;
- uint32_t curr_ticks = 0;
-
- /* Calculate number of ticks required. */
- ticks = TIMER_TICKS(usec);
+ uint64_t expire;
- /* Obtain the current timer value. */
- last = readl_i(DGT_COUNT_VAL);
+ expire = read_gcnt_val() + TIMER_TICKS(usec);
- /* Loop until the right number of ticks. */
- while (curr_ticks < ticks) {
- now = readl_i(DGT_COUNT_VAL);
- curr_ticks += now - last;
- last = now;
- }
+ while (expire >= read_gcnt_val())
+ ;
}
void timer_monotonic_get(struct mono_time *mt)
{
- mono_time_set_usecs(mt, TIMER_USECS(readl_i(DGT_COUNT_VAL)));
+ mono_time_set_usecs(mt, TIMER_USECS(read_gcnt_val()));
}