mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-28 10:45:22 +00:00
it83xx: fix observation register latch issue for event timer
Adding fix of event timer for CL:358730. Signed-off-by: Dino Li <dino.li@ite.com.tw> BRANCH=none BUG=chrome-os-partner:55044 TEST=We simulate the delay time between first and second read, and prove this method can avoid latch fail. Change-Id: I82cd4ce470ffc9a8262d9303e3fd390812c89cac Reviewed-on: https://chromium-review.googlesource.com/380349 Commit-Ready: Dino Li <Dino.Li@ite.com.tw> Tested-by: Dino Li <Dino.Li@ite.com.tw> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
This commit is contained in:
@@ -310,7 +310,12 @@ static void clock_htimer_enable(void)
|
||||
uint32_t c;
|
||||
|
||||
/* change event timer clock source to 32.768 KHz */
|
||||
#if 0
|
||||
c = TIMER_CNT_8M_32P768K(IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER));
|
||||
#else
|
||||
/* TODO(crosbug.com/p/55044) */
|
||||
c = TIMER_CNT_8M_32P768K(ext_observation_reg_read(EVENT_EXT_TIMER));
|
||||
#endif
|
||||
clock_event_timer_clock_change(EXT_PSR_32P768K_HZ, c);
|
||||
}
|
||||
|
||||
@@ -323,7 +328,12 @@ static int clock_allow_low_power_idle(void)
|
||||
et_ctrl_regs[EVENT_EXT_TIMER].mask)
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
if (EVENT_TIMER_COUNT_TO_US(IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER)) <
|
||||
#else
|
||||
/* TODO(crosbug.com/p/55044) */
|
||||
if (EVENT_TIMER_COUNT_TO_US(ext_observation_reg_read(EVENT_EXT_TIMER)) <
|
||||
#endif
|
||||
SLEEP_SET_HTIMER_DELAY_USEC)
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -105,37 +105,8 @@ uint32_t __ram_code __hw_clock_source_read(void)
|
||||
*/
|
||||
return IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H);
|
||||
#else
|
||||
/* Number of CPU cycles in 125 us */
|
||||
#define CYCLES_125NS (125*(PLL_CLOCK/SECOND) / 1000)
|
||||
/*
|
||||
* TODO(crosbug.com/p/55044):
|
||||
* observation register of external timer latch issue.
|
||||
* we can remove this workaround after version change.
|
||||
*/
|
||||
uint32_t prev_mask = get_int_mask();
|
||||
uint32_t val;
|
||||
|
||||
interrupt_disable();
|
||||
asm volatile(
|
||||
/* read observation register for the first time */
|
||||
"lwi %0,[%1]\n\t"
|
||||
/*
|
||||
* the delay time between reading the first and second
|
||||
* observation registers need to be greater than 0.125us and
|
||||
* smaller than 0.250us.
|
||||
*/
|
||||
".rept %2\n\t"
|
||||
"nop\n\t"
|
||||
".endr\n\t"
|
||||
/* read for the second time */
|
||||
"lwi %0,[%1]\n\t"
|
||||
: "=&r"(val)
|
||||
: "r"((uintptr_t) &IT83XX_ETWD_ETXCNTOR(FREE_EXT_TIMER_H)),
|
||||
"i"(CYCLES_125NS));
|
||||
/* restore interrupts */
|
||||
set_int_mask(prev_mask);
|
||||
|
||||
return val;
|
||||
/* TODO(crosbug.com/p/55044) */
|
||||
return ext_observation_reg_read(FREE_EXT_TIMER_H);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -172,7 +143,12 @@ uint32_t __hw_clock_event_get(void)
|
||||
if (IT83XX_ETWD_ETXCTRL(EVENT_EXT_TIMER) & (1 << 0)) {
|
||||
/* timer counter observation value to microseconds */
|
||||
next_event_us += EVENT_TIMER_COUNT_TO_US(
|
||||
#if 0
|
||||
IT83XX_ETWD_ETXCNTOR(EVENT_EXT_TIMER));
|
||||
#else
|
||||
/* TODO(crosbug.com/p/55044) */
|
||||
ext_observation_reg_read(EVENT_EXT_TIMER));
|
||||
#endif
|
||||
}
|
||||
return next_event_us;
|
||||
}
|
||||
@@ -249,6 +225,41 @@ static void __hw_clock_source_irq(void)
|
||||
}
|
||||
DECLARE_IRQ(CPU_INT_GROUP_3, __hw_clock_source_irq, 1);
|
||||
|
||||
/*
|
||||
* TODO(crosbug.com/p/55044):
|
||||
* observation register of external timer latch issue.
|
||||
* we can remove this workaround after version change.
|
||||
*/
|
||||
/* Number of CPU cycles in 125 us */
|
||||
#define CYCLES_125NS (125*(PLL_CLOCK/SECOND) / 1000)
|
||||
uint32_t __ram_code ext_observation_reg_read(enum ext_timer_sel ext_timer)
|
||||
{
|
||||
uint32_t prev_mask = get_int_mask();
|
||||
uint32_t val;
|
||||
|
||||
interrupt_disable();
|
||||
asm volatile(
|
||||
/* read observation register for the first time */
|
||||
"lwi %0,[%1]\n\t"
|
||||
/*
|
||||
* the delay time between reading the first and second
|
||||
* observation registers need to be greater than 0.125us and
|
||||
* smaller than 0.250us.
|
||||
*/
|
||||
".rept %2\n\t"
|
||||
"nop\n\t"
|
||||
".endr\n\t"
|
||||
/* read for the second time */
|
||||
"lwi %0,[%1]\n\t"
|
||||
: "=&r"(val)
|
||||
: "r"((uintptr_t) &IT83XX_ETWD_ETXCNTOR(ext_timer)),
|
||||
"i"(CYCLES_125NS));
|
||||
/* restore interrupts */
|
||||
set_int_mask(prev_mask);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
void ext_timer_start(enum ext_timer_sel ext_timer, int en_irq)
|
||||
{
|
||||
/* enable external timer n */
|
||||
|
||||
@@ -57,6 +57,8 @@ struct ext_timer_ctrl_t {
|
||||
};
|
||||
|
||||
extern const struct ext_timer_ctrl_t et_ctrl_regs[];
|
||||
/* TODO(crosbug.com/p/55044) */
|
||||
uint32_t __ram_code ext_observation_reg_read(enum ext_timer_sel ext_timer);
|
||||
void ext_timer_start(enum ext_timer_sel ext_timer, int en_irq);
|
||||
void ext_timer_stop(enum ext_timer_sel ext_timer, int dis_irq);
|
||||
void fan_ext_timer_interrupt(void);
|
||||
|
||||
Reference in New Issue
Block a user