summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx233
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2016-05-02 21:37:38 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2016-05-28 17:18:32 +0200
commit643c0a1e0e80ee6010353201792ba6e2be7e1ced (patch)
tree0b039050be720483935978575f77351db143463f /firmware/target/arm/imx233
parent423c64770c04a62e34775c37a7e09a60f6ccbc4c (diff)
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
Diffstat (limited to 'firmware/target/arm/imx233')
-rw-r--r--firmware/target/arm/imx233/kernel-imx233.c4
-rw-r--r--firmware/target/arm/imx233/system-imx233.c5
-rw-r--r--firmware/target/arm/imx233/timer-imx233.c7
-rw-r--r--firmware/target/arm/imx233/timrot-imx233.c43
-rw-r--r--firmware/target/arm/imx233/timrot-imx233.h26
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 */