From 80e6645b2d9876be58102c454cb0cf188f1d1eff Mon Sep 17 00:00:00 2001 From: Sadashiva Rao Pv Date: Wed, 27 Sep 2017 10:23:54 +0530 Subject: ISH3.0: Scaling timer from 12MHz to 1MHz -Added support to scale 12MHz to 1MHz -Fixes the timestamp issue -Changes under CONFIG_ISH_30 ISH 3.0 has 12MHz Main counter ISH 4.0 has 32KHz Main counter BUG=none BRANCH=master TEST=On Soraka board modified for ISH, ensure clock tick happens correctly. Ensure ISH probe and sensor info is seen in kernel logs Change-Id: Ib5d8a48bf99d1398a0424596399abd7df431e07a Signed-off-by: Naresh Solakni Signed-off-by: Sadashiva Rao Pv Signed-off-by: Kyoung Kim Reviewed-on: https://chromium-review.googlesource.com/686434 Commit-Ready: Caveh Jalali Tested-by: Kyoung Il Kim Reviewed-by: Jett Rink Reviewed-by: Kyoung Il Kim --- chip/ish/hpet.h | 14 ++++++++++++-- chip/ish/hwtimer.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- include/common.h | 2 ++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/chip/ish/hpet.h b/chip/ish/hpet.h index 086adfaa88..0ad374350e 100644 --- a/chip/ish/hpet.h +++ b/chip/ish/hpet.h @@ -45,14 +45,24 @@ #define HPET_Tn_INT_ROUTE_CNF_MASK (0x1f << 9) #define HPET_GENERAL_CONFIG REG32(ISH_HPET_BASE + GENERAL_CONFIG_REG) +#if defined CONFIG_ISH_30 +#define HPET_MAIN_COUNTER_64 REG64(ISH_HPET_BASE + MAIN_COUNTER_REG) +#else #define HPET_MAIN_COUNTER REG32(ISH_HPET_BASE + MAIN_COUNTER_REG) +#endif #define HPET_INTR_CLEAR REG32(ISH_HPET_BASE + GENERAL_INT_STAT_REG) #define HPET_CTRL_STATUS REG32(ISH_HPET_BASE + CONTROL_AND_STATUS_REG) #define HPET_TIMER_CONF_CAP(x) \ - REG32(ISH_HPET_BASE + TIMER0_CONF_CAP_REG + (x * 0x20)) + REG32(ISH_HPET_BASE + TIMER0_CONF_CAP_REG + ((x) * 0x20)) +/* HPET1/2 are 32 bit only. HPET0 is 32bit/64bit from configuration register + * HPET_TIMER_CONFIG_CAP(0) */ #define HPET_TIMER_COMP(x) \ - REG32(ISH_HPET_BASE + TIMER0_COMP_VAL_REG + (x * 0x20)) + REG32(ISH_HPET_BASE + TIMER0_COMP_VAL_REG + ((x) * 0x20)) +#if defined CONFIG_ISH_30 +#define HPET_TIMER_COMP_64(x) \ + REG64(ISH_HPET_BASE + TIMER0_COMP_VAL_REG + ((x) * 0x20)) +#endif #if defined CONFIG_ISH_20 #define ISH_HPET_CLK_FREQ 1000000 /* 1 MHz clock */ diff --git a/chip/ish/hwtimer.c b/chip/ish/hwtimer.c index ed34be583a..1ba08f048f 100644 --- a/chip/ish/hwtimer.c +++ b/chip/ish/hwtimer.c @@ -10,6 +10,11 @@ #include "hwtimer.h" #include "registers.h" #include "task.h" +#include "util.h" + +#ifdef CONFIG_ISH_30 +#define CLOCK_FACTOR 12 +#endif #define CPUTS(outstr) cputs(CC_CLOCK, outstr) #define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args) @@ -26,7 +31,11 @@ static uint32_t last_deadline; void __hw_clock_event_set(uint32_t deadline) { last_deadline = deadline; +#ifdef CONFIG_ISH_30 + HPET_TIMER_COMP(1) = deadline * CLOCK_FACTOR; +#else HPET_TIMER_COMP(1) = deadline; +#endif HPET_TIMER_CONF_CAP(1) |= HPET_Tn_INT_ENB_CNF; } @@ -42,13 +51,27 @@ void __hw_clock_event_clear(void) uint32_t __hw_clock_source_read(void) { +#ifdef CONFIG_ISH_30 + uint64_t tmp = HPET_MAIN_COUNTER_64; + uint32_t hi = tmp >> 32; + uint32_t lo = tmp; + uint32_t q, r; + const uint32_t d = CLOCK_FACTOR; + asm ("divl %4" : "=d" (r), "=a" (q) : "0" (hi), "1" (lo), "rm" (d) : "cc"); + return q; +#else return HPET_MAIN_COUNTER; +#endif } void __hw_clock_source_set(uint32_t ts) { HPET_GENERAL_CONFIG &= ~HPET_ENABLE_CNF; +#ifdef CONFIG_ISH_30 + HPET_MAIN_COUNTER_64 = (uint64_t)ts * CLOCK_FACTOR; +#else HPET_MAIN_COUNTER = ts; +#endif HPET_GENERAL_CONFIG |= HPET_ENABLE_CNF; } @@ -88,14 +111,31 @@ int __hw_clock_source_init(uint32_t start_t) /* Disable HPET */ HPET_GENERAL_CONFIG &= ~HPET_ENABLE_CNF; +#ifdef CONFIG_ISH_30 + HPET_MAIN_COUNTER_64 = (uint64_t)start_t * CLOCK_FACTOR; +#else HPET_MAIN_COUNTER = start_t; +#endif +#ifdef CONFIG_ISH_30 + /* + * Set comparator value. HMC will operate in 64 bit mode. + * HMC is 12MHz, Hence set COMP to 12x of 1MHz. + */ + HPET_TIMER_COMP_64(0) = (uint64_t)CLOCK_FACTOR << 32; /*0xC00000000ULL;*/ +#else /* Set comparator value */ HPET_TIMER_COMP(0) = 0XFFFFFFFF; - +#endif /* Timer 0 - enable periodic mode */ timer0_config |= HPET_Tn_TYPE_CNF; +#ifdef CONFIG_ISH_30 + /* TIMER0 in 64-bit mode */ + timer0_config &= ~HPET_Tn_32MODE_CNF; +#else + /*TIMER0 in 32-bit mode*/ timer0_config |= HPET_Tn_32MODE_CNF; +#endif timer0_config |= HPET_Tn_VAL_SET_CNF; /* Timer 0 - IRQ routing, no need IRQ set for HPET0 */ @@ -122,7 +162,7 @@ int __hw_clock_source_init(uint32_t start_t) HPET_TIMER_CONF_CAP(0) |= timer0_config; HPET_TIMER_CONF_CAP(1) |= timer1_config; -#if defined CONFIG_ISH_40 +#ifdef CONFIG_ISH_40 /* Wait for timer to settle. required for ISH 4 */ while (HPET_CTRL_STATUS & HPET_T_CONF_CAP_BIT) ; diff --git a/include/common.h b/include/common.h index f6bf9b1308..4f1b1f76a4 100644 --- a/include/common.h +++ b/include/common.h @@ -37,10 +37,12 @@ #define STRINGIFY(name) STRINGIFY0(name) /* Macros to access registers */ +#define REG64_ADDR(addr) ((volatile uint64_t *)(addr)) #define REG32_ADDR(addr) ((volatile uint32_t *)(addr)) #define REG16_ADDR(addr) ((volatile uint16_t *)(addr)) #define REG8_ADDR(addr) ((volatile uint8_t *)(addr)) +#define REG64(addr) (*REG64_ADDR(addr)) #define REG32(addr) (*REG32_ADDR(addr)) #define REG16(addr) (*REG16_ADDR(addr)) #define REG8(addr) (*REG8_ADDR(addr)) -- cgit v1.2.1