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
This commit is contained in:
Amaury Pouly 2016-05-02 21:37:38 +01:00
parent 423c64770c
commit 643c0a1e0e
5 changed files with 74 additions and 11 deletions

View file

@ -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)

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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 */