From 643c0a1e0e80ee6010353201792ba6e2be7e1ced Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Mon, 2 May 2016 21:37:38 +0100 Subject: imx233: simplify timrot API The old timrot setup API was very low-level and unfriendly. The new one makes in easier to select the frequency source. Use to simplify timer and kernel timer code. Change-Id: Iffcdf11c00e925be9ec8d9a4efc74b197b6bd2aa --- firmware/target/arm/imx233/kernel-imx233.c | 4 +-- firmware/target/arm/imx233/system-imx233.c | 5 ++-- firmware/target/arm/imx233/timer-imx233.c | 7 ++--- firmware/target/arm/imx233/timrot-imx233.c | 43 ++++++++++++++++++++++++++++++ firmware/target/arm/imx233/timrot-imx233.h | 26 ++++++++++++++++++ 5 files changed, 74 insertions(+), 11 deletions(-) diff --git a/firmware/target/arm/imx233/kernel-imx233.c b/firmware/target/arm/imx233/kernel-imx233.c index 199015f564..0652d6e640 100644 --- a/firmware/target/arm/imx233/kernel-imx233.c +++ b/firmware/target/arm/imx233/kernel-imx233.c @@ -34,9 +34,7 @@ static void tick_timer(void) void tick_start(unsigned int interval_in_ms) { /* use the 1-kHz XTAL clock source */ - imx233_timrot_setup(TIMER_TICK, true, interval_in_ms, - BV_TIMROT_TIMCTRLn_SELECT__1KHZ_XTAL, BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1, - false, &tick_timer); + imx233_timrot_setup_simple(TIMER_TICK, true, interval_in_ms, TIMER_SRC_1KHZ, &tick_timer); } void arbiter_init(struct channel_arbiter_t *a, unsigned count) diff --git a/firmware/target/arm/imx233/system-imx233.c b/firmware/target/arm/imx233/system-imx233.c index 666b9fedf4..b2ece3be61 100644 --- a/firmware/target/arm/imx233/system-imx233.c +++ b/firmware/target/arm/imx233/system-imx233.c @@ -67,9 +67,8 @@ static void good_dog(void) { imx233_rtc_reset_watchdog(WATCHDOG_HW_DELAY * 1000 / HZ); /* ms */ imx233_rtc_enable_watchdog(true); - imx233_timrot_setup(TIMER_WATCHDOG, false, WATCHDOG_SW_DELAY * 1000 / HZ, - BV_TIMROT_TIMCTRLn_SELECT__1KHZ_XTAL, BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1, - false, &woof_woof); + imx233_timrot_setup_simple(TIMER_WATCHDOG, false, WATCHDOG_SW_DELAY * 1000 / HZ, + TIMER_SRC_1KHZ, &woof_woof); imx233_timrot_set_priority(TIMER_WATCHDOG, ICOLL_PRIO_WATCHDOG); } diff --git a/firmware/target/arm/imx233/timer-imx233.c b/firmware/target/arm/imx233/timer-imx233.c index bcadc82f2c..57d38c01a6 100644 --- a/firmware/target/arm/imx233/timer-imx233.c +++ b/firmware/target/arm/imx233/timer-imx233.c @@ -49,14 +49,11 @@ bool timer_set(long cycles, bool start) bool timer_start(IF_COP_VOID(int core)) { - imx233_timrot_setup(TIMER_USER, true, timer_cycles, - BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL, BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1, - false, &timer_fn); + imx233_timrot_setup_simple(TIMER_USER, true, timer_cycles, TIMER_SRC_32KHZ, &timer_fn); return true; } void timer_stop(void) { - imx233_timrot_setup(TIMER_USER, false, 0, BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK, - BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1, false, NULL); + imx233_timrot_setup_simple(TIMER_USER, false, 0, TIMER_SRC_STOP, NULL); } diff --git a/firmware/target/arm/imx233/timrot-imx233.c b/firmware/target/arm/imx233/timrot-imx233.c index 7c5e60c30e..91f24924d6 100644 --- a/firmware/target/arm/imx233/timrot-imx233.c +++ b/firmware/target/arm/imx233/timrot-imx233.c @@ -65,6 +65,49 @@ void imx233_timrot_set_priority(unsigned timer_nr, unsigned prio) imx233_icoll_set_priority(INT_SRC_TIMER(timer_nr), prio); } +static unsigned map_src(enum imx233_timrot_src_t src, unsigned *prescale) +{ + *prescale = BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_1; + switch(src) + { + case TIMER_SRC_24MHZ: + return BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS; + case TIMER_SRC_12MHZ: + *prescale = BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_2; + return BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS; + case TIMER_SRC_6MHZ: + *prescale = BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_4; + return BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS; + case TIMER_SRC_3MHZ: + *prescale = BV_TIMROT_TIMCTRLn_PRESCALE__DIV_BY_8; + return BV_TIMROT_TIMCTRLn_SELECT__TICK_ALWAYS; + case TIMER_SRC_32KHZ: + return BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL; + case TIMER_SRC_8KHZ: + return BV_TIMROT_TIMCTRLn_SELECT__8KHZ_XTAL; + case TIMER_SRC_4KHZ: + return BV_TIMROT_TIMCTRLn_SELECT__4KHZ_XTAL; + case TIMER_SRC_1KHZ: + return BV_TIMROT_TIMCTRLn_SELECT__1KHZ_XTAL; + case TIMER_SRC_STOP: + default: + return BV_TIMROT_TIMCTRLn_SELECT__NEVER_TICK; + } +} + +void imx233_timrot_setup_simple(unsigned timer_nr, bool periodic, unsigned count, + enum imx233_timrot_src_t src, imx233_timer_fn_t fn) +{ + unsigned prescale; + unsigned hw_src = map_src(src, &prescale); + imx233_timrot_setup(timer_nr, periodic, count, hw_src, prescale, false, fn); +} + +unsigned imx233_timrot_get_count(unsigned timer_nr) +{ + return BF_RD(TIMROT_TIMCOUNTn(timer_nr), RUNNING_COUNT); +} + struct imx233_timrot_info_t imx233_timrot_get_info(unsigned timer_nr) { struct imx233_timrot_info_t info; diff --git a/firmware/target/arm/imx233/timrot-imx233.h b/firmware/target/arm/imx233/timrot-imx233.h index 778cd1add9..0add64e9ce 100644 --- a/firmware/target/arm/imx233/timrot-imx233.h +++ b/firmware/target/arm/imx233/timrot-imx233.h @@ -25,6 +25,7 @@ #include "cpu.h" #include "icoll-imx233.h" +/* WARNING timrot code assumes APBX is running at 24MHz */ /* list of timers */ enum { @@ -33,6 +34,20 @@ enum TIMER_WATCHDOG, /* for watchdog */ }; +/* timer sources */ +enum imx233_timrot_src_t +{ + TIMER_SRC_24MHZ, + TIMER_SRC_12MHZ, + TIMER_SRC_6MHZ, + TIMER_SRC_3MHZ, + TIMER_SRC_32KHZ, + TIMER_SRC_8KHZ, + TIMER_SRC_4KHZ, + TIMER_SRC_1KHZ, + TIMER_SRC_STOP +}; + struct imx233_timrot_info_t { unsigned fixed_count, run_count; @@ -45,10 +60,21 @@ struct imx233_timrot_info_t typedef void (*imx233_timer_fn_t)(void); +/* maximum count for non-periodic timers, add one for periodic timers */ +#define IMX233_TIMROT_MAX_COUNT 0xffff + void imx233_timrot_init(void); +/* low-level function all-in-one function */ void imx233_timrot_setup(unsigned timer_nr, bool reload, unsigned count, unsigned src, unsigned prescale, bool polarity, imx233_timer_fn_t fn); +/* change interrupt priority */ void imx233_timrot_set_priority(unsigned timer_nr, unsigned prio); +/* simple setup function */ +void imx233_timrot_setup_simple(unsigned timer_nr, bool periodic, unsigned count, + enum imx233_timrot_src_t src, imx233_timer_fn_t fn); +/* get timer count */ +unsigned imx233_timrot_get_count(unsigned timer_nr); +/* update timer running count */ struct imx233_timrot_info_t imx233_timrot_get_info(unsigned timer_nr); #endif /* TIMROT_IMX233_H */ -- cgit v1.2.3