From fde084bc490daf99da85292ef87d6dcf3446c212 Mon Sep 17 00:00:00 2001 From: Sam Lewis Date: Tue, 4 Aug 2020 19:47:50 +1000 Subject: soc/ti/am335x: Fix timer implementation Implements the monotonic timer using the am335x dmtimer peripheral. Change-Id: I4736b6d3b6e26370be9e8f369fc02285ad519223 Signed-off-by: Sam Lewis Reviewed-on: https://review.coreboot.org/c/coreboot/+/44383 Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/soc/ti/am335x/Makefile.inc | 9 +++------ src/soc/ti/am335x/dmtimer.c | 12 ----------- src/soc/ti/am335x/dmtimer.h | 30 +++++++++++++++++++++++++--- src/soc/ti/am335x/monotonic_timer.c | 40 ------------------------------------- src/soc/ti/am335x/timer.c | 31 ++++++++++++++++++++++++++++ 5 files changed, 61 insertions(+), 61 deletions(-) delete mode 100644 src/soc/ti/am335x/dmtimer.c delete mode 100644 src/soc/ti/am335x/monotonic_timer.c create mode 100644 src/soc/ti/am335x/timer.c diff --git a/src/soc/ti/am335x/Makefile.inc b/src/soc/ti/am335x/Makefile.inc index e744c72526..60e00fbbcc 100644 --- a/src/soc/ti/am335x/Makefile.inc +++ b/src/soc/ti/am335x/Makefile.inc @@ -1,18 +1,15 @@ ifeq ($(CONFIG_SOC_TI_AM335X),y) bootblock-y += bootblock.c bootblock-y += bootblock_media.c -bootblock-y += dmtimer.c +bootblock-y += timer.c bootblock-y += gpio.c bootblock-y += pinmux.c -bootblock-y += monotonic_timer.c romstage-y += nand.c romstage-y += cbmem.c -romstage-y += dmtimer.c -romstage-y += monotonic_timer.c +romstage-y += timer.c -ramstage-y += dmtimer.c -ramstage-y += monotonic_timer.c +ramstage-y += timer.c ramstage-y += nand.c ramstage-y += soc.c diff --git a/src/soc/ti/am335x/dmtimer.c b/src/soc/ti/am335x/dmtimer.c deleted file mode 100644 index b3aa7a18ba..0000000000 --- a/src/soc/ti/am335x/dmtimer.c +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include "dmtimer.h" - -void dmtimer_start(int num) -{ -} - -uint64_t dmtimer_raw_value(int num) -{ - return 0; -} diff --git a/src/soc/ti/am335x/dmtimer.h b/src/soc/ti/am335x/dmtimer.h index ad8515fbba..56f3d0f011 100644 --- a/src/soc/ti/am335x/dmtimer.h +++ b/src/soc/ti/am335x/dmtimer.h @@ -5,9 +5,33 @@ #include -#define OSC_HZ 24000000 +#define M_OSC_MHZ (24) -void dmtimer_start(int num); -uint64_t dmtimer_raw_value(int num); +struct am335x_dmtimer { + uint32_t tidr; + uint8_t res1[12]; + uint32_t tiocp_cfg; + uint8_t res2[12]; + uint32_t irq_eoi; + uint32_t irqstatus_raw; + uint32_t irqstatus; + uint32_t irqenable_set; + uint32_t irqenable_clr; + uint32_t irqwakeen; + uint32_t tclr; + uint32_t tcrr; + uint32_t tldr; + uint32_t ttgr; + uint32_t twps; + uint32_t tmar; + uint32_t tcar1; + uint32_t tsicr; + uint32_t tcar2; +}; + +#define TCLR_ST (0x01 << 0) +#define TCLR_AR (0x01 << 1) + +#define DMTIMER_2 (0x48040000) #endif diff --git a/src/soc/ti/am335x/monotonic_timer.c b/src/soc/ti/am335x/monotonic_timer.c deleted file mode 100644 index b57258b6c8..0000000000 --- a/src/soc/ti/am335x/monotonic_timer.c +++ /dev/null @@ -1,40 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include -#include -#include - -#include "dmtimer.h" - -static struct monotonic_counter { - int initialized; - struct mono_time time; - uint64_t last_value; -} mono_counter; - -static const uint32_t clocks_per_usec = OSC_HZ/1000000; - -void timer_monotonic_get(struct mono_time *mt) -{ - uint64_t current_tick; - uint64_t usecs_elapsed; - - if (!mono_counter.initialized) { - init_timer(); - mono_counter.last_value = dmtimer_raw_value(0); - mono_counter.initialized = 1; - } - - current_tick = dmtimer_raw_value(0); - usecs_elapsed = (current_tick - mono_counter.last_value) / - clocks_per_usec; - - /* Update current time and tick values only if a full tick occurred. */ - if (usecs_elapsed) { - mono_time_add_usecs(&mono_counter.time, usecs_elapsed); - mono_counter.last_value = current_tick; - } - - /* Save result. */ - *mt = mono_counter.time; -} diff --git a/src/soc/ti/am335x/timer.c b/src/soc/ti/am335x/timer.c new file mode 100644 index 0000000000..4ed98a3541 --- /dev/null +++ b/src/soc/ti/am335x/timer.c @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +#include "dmtimer.h" +#include "clock.h" + +struct am335x_dmtimer *dmtimer_2 = (struct am335x_dmtimer *)DMTIMER_2; + +#define CLKSEL_M_OSC (0x01 << 0) + +static uint32_t timer_raw_value(void) +{ + return read32(&dmtimer_2->tcrr); +} + +void timer_monotonic_get(struct mono_time *mt) +{ + mono_time_set_usecs(mt, timer_raw_value() / M_OSC_MHZ); +} + +void init_timer(void) +{ + write32(&am335x_cm_dpll->clksel_timer2_clk, CLKSEL_M_OSC); + + // Start the dmtimer in autoreload mode without any prescalers + // With M_OSC at 24MHz, this gives a few minutes before the timer overflows + write32(&dmtimer_2->tclr, TCLR_ST | TCLR_AR); +} -- cgit v1.2.3