driver: itim: npcx: use timeout mechanism instead of unbounded loop.
Use timeout mechanism instead of unbounded loop during enabling ITIM32 module which source clock is LFCLK (32KHz). Signed-off-by: Mulin Chao <mlchao@nuvoton.com>
This commit is contained in:
parent
30dbc40909
commit
db87ee2039
1 changed files with 21 additions and 6 deletions
|
@ -48,10 +48,13 @@ LOG_MODULE_REGISTER(itim, LOG_LEVEL_ERR);
|
|||
#define EVT_CYCLES_PER_SEC LFCLK /* 32768 Hz */
|
||||
#define SYS_CYCLES_PER_TICK (sys_clock_hw_cycles_per_sec() \
|
||||
/ CONFIG_SYS_CLOCK_TICKS_PER_SEC)
|
||||
#define SYS_CYCLES_PER_USEC (sys_clock_hw_cycles_per_sec() / 1000000)
|
||||
#define EVT_CYCLES_FROM_TICKS(ticks) \
|
||||
ceiling_fraction(ticks * EVT_CYCLES_PER_SEC, \
|
||||
CONFIG_SYS_CLOCK_TICKS_PER_SEC)
|
||||
#define NPCX_ITIM_CLK_SEL_DELAY 92 /* Delay for clock selection (Unit:us) */
|
||||
/* Timeout for enabling ITIM module: 100us (Unit:cycles) */
|
||||
#define NPCX_ITIM_EN_TIMEOUT_CYCLES (100 * SYS_CYCLES_PER_USEC)
|
||||
|
||||
/* Instance of system and event timers */
|
||||
static struct itim64_reg *const sys_tmr = (struct itim64_reg *)
|
||||
|
@ -79,7 +82,7 @@ static inline uint64_t npcx_itim_get_sys_cyc64(void)
|
|||
/* Read 64-bit counter value from two 32-bit registers */
|
||||
do {
|
||||
cnt64h_check = sys_tmr->ITCNT64H;
|
||||
cnt64l = sys_tmr->ITCNT64L;
|
||||
cnt64l = sys_tmr->ITCNT64L;
|
||||
cnt64h = sys_tmr->ITCNT64H;
|
||||
} while (cnt64h != cnt64h_check);
|
||||
|
||||
|
@ -95,8 +98,10 @@ static inline uint64_t npcx_itim_get_sys_cyc64(void)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void npcx_itim_evt_enable(void)
|
||||
static inline int npcx_itim_evt_enable(void)
|
||||
{
|
||||
uint64_t cyc_start;
|
||||
|
||||
/* Enable event timer and wait for it to take effect */
|
||||
evt_tmr->ITCTS32 |= BIT(NPCX_ITCTSXX_ITEN);
|
||||
|
||||
|
@ -104,9 +109,16 @@ static inline void npcx_itim_evt_enable(void)
|
|||
* Usually, it need one clock (30.5 us) to take effect since
|
||||
* asynchronization between core and itim32's source clock (LFCLK).
|
||||
*/
|
||||
cyc_start = npcx_itim_get_sys_cyc64();
|
||||
while (!IS_BIT_SET(evt_tmr->ITCTS32, NPCX_ITCTSXX_ITEN)) {
|
||||
continue;
|
||||
if (npcx_itim_get_sys_cyc64() - cyc_start >
|
||||
NPCX_ITIM_EN_TIMEOUT_CYCLES) {
|
||||
LOG_ERR("Timeout: enabling EVT timer!");
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void npcx_itim_evt_disable(void)
|
||||
|
@ -116,7 +128,7 @@ static inline void npcx_itim_evt_disable(void)
|
|||
}
|
||||
|
||||
/* ITIM local functions */
|
||||
static void npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
|
||||
static int npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
|
||||
{
|
||||
/*
|
||||
* Get desired cycles of event timer from the requested ticks which
|
||||
|
@ -143,7 +155,7 @@ static void npcx_itim_start_evt_tmr_by_tick(int32_t ticks)
|
|||
evt_tmr->ITCNT32 = MAX(cyc_evt_timeout - 1, 1);
|
||||
|
||||
/* Enable event timer and start ticking */
|
||||
npcx_itim_evt_enable();
|
||||
return npcx_itim_evt_enable();
|
||||
|
||||
}
|
||||
|
||||
|
@ -309,7 +321,10 @@ int z_clock_driver_init(const struct device *device)
|
|||
|
||||
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
|
||||
/* Start a event timer in one tick */
|
||||
npcx_itim_start_evt_tmr_by_tick(1);
|
||||
ret = npcx_itim_start_evt_tmr_by_tick(1);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue