summaryrefslogtreecommitdiff
path: root/chip/mt_scp/mt8183/hrtimer.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/mt_scp/mt8183/hrtimer.c')
-rw-r--r--chip/mt_scp/mt8183/hrtimer.c253
1 files changed, 0 insertions, 253 deletions
diff --git a/chip/mt_scp/mt8183/hrtimer.c b/chip/mt_scp/mt8183/hrtimer.c
deleted file mode 100644
index 92887af2a7..0000000000
--- a/chip/mt_scp/mt8183/hrtimer.c
+++ /dev/null
@@ -1,253 +0,0 @@
-/* Copyright 2018 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/*
- * High-res hardware timer
- *
- * SCP hardware 32bit count down timer can be configured to source clock from
- * 32KHz, 26MHz, BCLK or PCLK. This implementation selects BCLK (ULPOSC1/8) as a
- * source, countdown mode and converts to micro second value matching common
- * timer.
- */
-
-#include "clock.h"
-#include "clock_chip.h"
-#include "common.h"
-#include "console.h"
-#include "hooks.h"
-#include "hwtimer.h"
-#include "panic.h"
-#include "registers.h"
-#include "task.h"
-#include "timer.h"
-#include "watchdog.h"
-
-#define IRQ_TIMER(n) CONCAT2(SCP_IRQ_TIMER, n)
-
-#define TIMER_SYSTEM 5
-#define TIMER_EVENT 3
-
-/* ULPOSC1 should be a multiple of 8. */
-BUILD_ASSERT((ULPOSC1_CLOCK_MHZ % 8) == 0);
-#define TIMER_CLOCK_MHZ (ULPOSC1_CLOCK_MHZ / 8)
-
-/* Common timer overflows at 0x100000000 micro seconds */
-#define OVERFLOW_TICKS (TIMER_CLOCK_MHZ * 0x100000000 - 1)
-
-static uint8_t sys_high;
-static uint8_t event_high;
-
-/* Convert hardware countdown timer to 64bit countup ticks */
-static inline uint64_t timer_read_raw_system(void)
-{
- uint32_t timer_ctrl = SCP_TIMER_IRQ_CTRL(TIMER_SYSTEM);
- uint32_t sys_high_adj = sys_high;
-
- /*
- * If an IRQ is pending, but has not been serviced yet, adjust the
- * sys_high value.
- */
- if (timer_ctrl & TIMER_IRQ_STATUS)
- sys_high_adj = sys_high ? (sys_high - 1) : (TIMER_CLOCK_MHZ-1);
-
- return OVERFLOW_TICKS - (((uint64_t)sys_high_adj << 32) |
- SCP_TIMER_VAL(TIMER_SYSTEM));
-}
-
-static inline uint64_t timer_read_raw_event(void)
-{
- return OVERFLOW_TICKS - (((uint64_t)event_high << 32) |
- SCP_TIMER_VAL(TIMER_EVENT));
-}
-
-static inline void timer_set_clock(int n, uint32_t clock_source)
-{
- SCP_TIMER_EN(n) = (SCP_TIMER_EN(n) & ~TIMER_CLK_MASK) |
- clock_source;
-}
-
-static inline void timer_ack_irq(int n)
-{
- SCP_TIMER_IRQ_CTRL(n) |= TIMER_IRQ_CLEAR;
-}
-
-/* Set hardware countdown value */
-static inline void timer_set_reset_value(int n, uint32_t reset_value)
-{
- SCP_TIMER_RESET_VAL(n) = reset_value;
-}
-
-static void timer_reset(int n)
-{
- __hw_timer_enable_clock(n, 0);
- timer_ack_irq(n);
- timer_set_reset_value(n, 0xffffffff);
- timer_set_clock(n, TIMER_CLK_32K);
-}
-
-/* Reload a new 32bit countdown value */
-static void timer_reload(int n, uint32_t value)
-{
- __hw_timer_enable_clock(n, 0);
- timer_set_reset_value(n, value);
- __hw_timer_enable_clock(n, 1);
-}
-
-static int timer_reload_event_high(void)
-{
- if (event_high) {
- if (SCP_TIMER_RESET_VAL(TIMER_EVENT) == 0xffffffff)
- __hw_timer_enable_clock(TIMER_EVENT, 1);
- else
- timer_reload(TIMER_EVENT, 0xffffffff);
- event_high--;
- return 1;
- }
-
- /* Disable event timer clock when done. */
- __hw_timer_enable_clock(TIMER_EVENT, 0);
- return 0;
-}
-
-void __hw_clock_event_clear(void)
-{
- __hw_timer_enable_clock(TIMER_EVENT, 0);
- timer_set_reset_value(TIMER_EVENT, 0x0000c1ea4);
- event_high = 0;
-}
-
-void __hw_clock_event_set(uint32_t deadline)
-{
- uint64_t deadline_raw = (uint64_t)deadline * TIMER_CLOCK_MHZ;
- uint64_t now_raw = timer_read_raw_system();
- uint32_t event_deadline;
-
- if (deadline_raw > now_raw) {
- deadline_raw -= now_raw;
- event_deadline = (uint32_t)deadline_raw;
- event_high = deadline_raw >> 32;
- } else {
- event_deadline = 1;
- event_high = 0;
- }
-
- if (event_deadline)
- timer_reload(TIMER_EVENT, event_deadline);
- else
- timer_reload_event_high();
-}
-
-void __hw_timer_enable_clock(int n, int enable)
-{
- if (enable) {
- SCP_TIMER_IRQ_CTRL(n) |= 1;
- SCP_TIMER_EN(n) |= 1;
- } else {
- SCP_TIMER_EN(n) &= ~1;
- SCP_TIMER_IRQ_CTRL(n) &= ~1;
- }
-}
-
-int __hw_clock_source_init(uint32_t start_t)
-{
- int t;
-
- /*
- * TODO(b/120169529): check clock tree to see if we need to turn on
- * MCLK and BCLK gate.
- */
- SCP_CLK_GATE |= (CG_TIMER_M | CG_TIMER_B);
-
- /* Reset all timer, select 32768Hz clock source */
- for (t = 0; t < NUM_TIMERS; t++)
- timer_reset(t);
-
- /* Enable timer IRQ wake source */
- SCP_INTC_IRQ_WAKEUP |= (1 << IRQ_TIMER(0)) | (1 << IRQ_TIMER(1)) |
- (1 << IRQ_TIMER(2)) | (1 << IRQ_TIMER(3)) |
- (1 << IRQ_TIMER(4)) | (1 << IRQ_TIMER(5));
- /*
- * Timer configuration:
- * OS TIMER - count up @ 13MHz, 64bit value with latch.
- * SYS TICK - count down @ 26MHz
- * EVENT TICK - count down @ 26MHz
- */
-
- /* Turn on OS TIMER, tick at 13MHz */
- SCP_OSTIMER_CON |= 1;
-
- /* System timestamp timer from BCLK (sourced from ULPOSC) */
- SCP_CLK_BCLK = CLK_BCLK_SEL_ULPOSC1_DIV8;
-
- timer_set_clock(TIMER_SYSTEM, TIMER_CLK_BCLK);
- sys_high = TIMER_CLOCK_MHZ-1;
- timer_set_reset_value(TIMER_SYSTEM, 0xffffffff);
- __hw_timer_enable_clock(TIMER_SYSTEM, 1);
- task_enable_irq(IRQ_TIMER(TIMER_SYSTEM));
- /* Event tick timer */
- timer_set_clock(TIMER_EVENT, TIMER_CLK_BCLK);
- task_enable_irq(IRQ_TIMER(TIMER_EVENT));
-
- return IRQ_TIMER(TIMER_SYSTEM);
-}
-
-uint32_t __hw_clock_source_read(void)
-{
- return timer_read_raw_system() / TIMER_CLOCK_MHZ;
-}
-
-uint32_t __hw_clock_event_get(void)
-{
- return (timer_read_raw_event() + timer_read_raw_system())
- / TIMER_CLOCK_MHZ;
-}
-
-static void __hw_clock_source_irq(int n)
-{
- uint32_t timer_ctrl = SCP_TIMER_IRQ_CTRL(n);
-
- /* Ack if we're hardware interrupt */
- if (timer_ctrl & TIMER_IRQ_STATUS)
- timer_ack_irq(n);
-
- switch (n) {
- case TIMER_EVENT:
- if (timer_ctrl & TIMER_IRQ_STATUS) {
- if (timer_reload_event_high())
- return;
- }
- process_timers(0);
- break;
- case TIMER_SYSTEM:
- /* If this is a hardware irq, check overflow */
- if (timer_ctrl & TIMER_IRQ_STATUS) {
- if (sys_high) {
- sys_high--;
- process_timers(0);
- } else {
- /* Overflow, reload system timer */
- sys_high = TIMER_CLOCK_MHZ-1;
- process_timers(1);
- }
- } else {
- process_timers(0);
- }
- break;
- default:
- return;
- }
-
-}
-
-#define DECLARE_TIMER_IRQ(n) \
- DECLARE_IRQ(IRQ_TIMER(n), __hw_clock_source_irq_##n, 2); \
- void __hw_clock_source_irq_##n(void) { __hw_clock_source_irq(n); }
-
-DECLARE_TIMER_IRQ(0);
-DECLARE_TIMER_IRQ(1);
-DECLARE_TIMER_IRQ(2);
-DECLARE_TIMER_IRQ(3);
-DECLARE_TIMER_IRQ(4);
-DECLARE_TIMER_IRQ(5);