summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chip/ish/hpet.h11
-rw-r--r--chip/ish/hwtimer.c80
-rw-r--r--chip/ish/registers.h4
3 files changed, 53 insertions, 42 deletions
diff --git a/chip/ish/hpet.h b/chip/ish/hpet.h
index c14df86ffb..dac5d95b9a 100644
--- a/chip/ish/hpet.h
+++ b/chip/ish/hpet.h
@@ -26,18 +26,21 @@
#define TIMER2_COMP_VAL_REG 0x148
#define TIMER2_FSB_IR_REG 0x150
+/* ISH 4: Special status register
+ * Use this register to see HPET timer are settled after a write.
+ */
#define CONTROL_AND_STATUS_REG 0x160
+#define HPET_T_CONF_CAP_BIT 0x4
#define HPET_ENABLE_CNF (1<<0)
-#define HPET_LEGACY_RT_CNF (1<<1)
-#define HPET_Tn_INT_TYPE_CNF (1<<1)
+#define HPET_Tn_INT_TYPE_CNF (1<<1)
#define HPET_Tn_INT_ENB_CNF (1<<2)
#define HPET_Tn_TYPE_CNF (1<<3)
+#define HPET_Tn_VAL_SET_CNF (1<<6)
#define HPET_Tn_32MODE_CNF (1<<8)
+
#define HPET_Tn_INT_ROUTE_CNF_SHIFT 0x9
#define HPET_Tn_INT_ROUTE_CNF_MASK (0x1f << 9)
-#define HPET_GEN_CONF_STATUS_BIT 0x8
-#define HPET_T0_CONF_CAP_BIT 0x4
#define HPET_GENERAL_CONFIG REG32(ISH_HPET_BASE + GENERAL_CONFIG_REG)
#define HPET_MAIN_COUNTER REG32(ISH_HPET_BASE + MAIN_COUNTER_REG)
diff --git a/chip/ish/hwtimer.c b/chip/ish/hwtimer.c
index 13c07decd2..800b728fb7 100644
--- a/chip/ish/hwtimer.c
+++ b/chip/ish/hwtimer.c
@@ -5,6 +5,7 @@
/* Hardware timers driver - HPET */
+#include "console.h"
#include "hpet.h"
#include "hwtimer.h"
#include "registers.h"
@@ -14,15 +15,24 @@
#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_CLOCK, format, ## args)
+static uint32_t last_deadline;
+
+/* TODO: Conform to EC API
+ * ISH supports 32KHz and 12MHz clock sources.
+ * EC expects timer value in 1MHz.
+ * Scale the values and support it.
+ */
+
void __hw_clock_event_set(uint32_t deadline)
{
- HPET_TIMER_COMP(1) = HPET_MAIN_COUNTER + deadline;
+ last_deadline = deadline;
+ HPET_TIMER_COMP(1) = deadline;
HPET_TIMER_CONF_CAP(1) |= HPET_Tn_INT_ENB_CNF;
}
uint32_t __hw_clock_event_get(void)
{
- return 0;
+ return last_deadline;
}
void __hw_clock_event_clear(void)
@@ -38,11 +48,7 @@ uint32_t __hw_clock_source_read(void)
void __hw_clock_source_set(uint32_t ts)
{
HPET_GENERAL_CONFIG &= ~HPET_ENABLE_CNF;
- HPET_MAIN_COUNTER = 0x00;
-
- while (HPET_CTRL_STATUS & HPET_GEN_CONF_STATUS_BIT)
- ;
-
+ HPET_MAIN_COUNTER = ts;
HPET_GENERAL_CONFIG |= HPET_ENABLE_CNF;
}
@@ -77,53 +83,55 @@ int __hw_clock_source_init(uint32_t start_t)
* - Timer 1 as event timer
*/
+ uint32_t timer0_config = 0x00000000;
+ uint32_t timer1_config = 0x00000000;
+
/* Disable HPET */
HPET_GENERAL_CONFIG &= ~HPET_ENABLE_CNF;
- HPET_MAIN_COUNTER = 0x00;
+ HPET_MAIN_COUNTER = start_t;
/* Set comparator value */
- HPET_TIMER_COMP(0) = ISH_HPET_CLK_FREQ / ISH_TICKS_PER_SEC;
-
- /* Wait for timer to settle */
- while (HPET_CTRL_STATUS & HPET_GEN_CONF_STATUS_BIT)
- ;
+ HPET_TIMER_COMP(0) = 0XFFFFFFFF;
/* Timer 0 - enable periodic mode */
- HPET_TIMER_CONF_CAP(0) |= HPET_Tn_TYPE_CNF;
- HPET_TIMER_CONF_CAP(0) |= HPET_Tn_32MODE_CNF;
+ timer0_config |= HPET_Tn_TYPE_CNF;
+ timer0_config |= HPET_Tn_32MODE_CNF;
+ timer0_config |= HPET_Tn_VAL_SET_CNF;
- while (HPET_CTRL_STATUS & HPET_T0_CONF_CAP_BIT)
- ;
+ /* Timer 0 - IRQ routing */
+ timer0_config &= ~HPET_Tn_INT_ROUTE_CNF_MASK;
+ timer0_config |= (ISH_HPET_TIMER0_IRQ <<
+ HPET_Tn_INT_ROUTE_CNF_SHIFT);
- /* Set IRQ routing */
-#if ISH_HPET_TIMER0_IRQ < 32
- HPET_TIMER_CONF_CAP(0) &= ~HPET_Tn_INT_ROUTE_CNF_MASK;
- HPET_TIMER_CONF_CAP(0) |= (ISH_HPET_TIMER0_IRQ <<
- HPET_Tn_INT_ROUTE_CNF_SHIFT);
-#else
- HPET_TIMER_CONF_CAP(0) &= ~HPET_Tn_INT_ROUTE_CNF_MASK;
-#endif
+ /* Timer 1 - IRQ routing */
+ timer1_config &= ~HPET_Tn_INT_ROUTE_CNF_MASK;
+ timer1_config |= (ISH_HPET_TIMER1_IRQ <<
+ HPET_Tn_INT_ROUTE_CNF_SHIFT);
- while (HPET_CTRL_STATUS & HPET_T0_CONF_CAP_BIT)
- ;
+ /* Level triggered interrupt */
+ timer0_config |= HPET_Tn_INT_TYPE_CNF;
+ timer1_config |= HPET_Tn_INT_TYPE_CNF;
- /* Level interrupt */
- HPET_TIMER_CONF_CAP(0) |= HPET_Tn_INT_TYPE_CNF;
- HPET_TIMER_CONF_CAP(1) |= HPET_Tn_INT_TYPE_CNF;
+ /* Enable interrupt */
+ timer0_config |= HPET_Tn_INT_ENB_CNF;
+ timer1_config |= HPET_Tn_INT_ENB_CNF;
/* Unask HPET IRQ in IOAPIC */
task_enable_irq(ISH_HPET_TIMER0_IRQ);
task_enable_irq(ISH_HPET_TIMER1_IRQ);
- /* Enable interrupt */
- HPET_TIMER_CONF_CAP(0) |= HPET_Tn_INT_ENB_CNF;
- HPET_TIMER_CONF_CAP(1) |= HPET_Tn_INT_ENB_CNF;
+ /* Set timer 0/1 config */
+ HPET_TIMER_CONF_CAP(0) |= timer0_config;
+ HPET_TIMER_CONF_CAP(1) |= timer1_config;
- while (HPET_CTRL_STATUS & HPET_T0_CONF_CAP_BIT)
+#if defined CONFIG_ISH_40
+ /* Wait for timer to settle. required for ISH 4 */
+ while (HPET_CTRL_STATUS & HPET_T_CONF_CAP_BIT)
;
+#endif
- /* Enable HPET main counter */
+ /* Enable HPET main counter */
HPET_GENERAL_CONFIG |= HPET_ENABLE_CNF;
- return ISH_HPET_TIMER1_IRQ; /* One shot */
+ return ISH_HPET_TIMER1_IRQ;
}
diff --git a/chip/ish/registers.h b/chip/ish/registers.h
index f92770ddbd..32239d3975 100644
--- a/chip/ish/registers.h
+++ b/chip/ish/registers.h
@@ -39,14 +39,14 @@ enum ish_i2c_port {
/* HW interrupt pins mapped to IOAPIC, from I/O sources */
#define ISH_I2C0_IRQ 0
#define ISH_I2C1_IRQ 1
-#define ISH_HPET_TIMER1_IRQ 8
+#define ISH_HPET_TIMER0_IRQ 22
+#define ISH_HPET_TIMER1_IRQ 23
#define ISH_HPET_TIMER2_IRQ 11
#define ISH_IPC_HOST2ISH_IRQ 12
#define ISH_IPC_ISH2HOST_CLR_IRQ 24
#define ISH_UART0_IRQ 34
#define ISH_UART1_IRQ 35
#define ISH_I2C2_IRQ 40
-#define ISH_HPET_TIMER0_IRQ 55
/* Interrupt vectors 0-31 are architecture reserved.
* Vectors 32-255 are user-defined.