/* *Fix errata A-007728 for flextimer * If the FTM counter reaches the FTM_MOD value between * the reading of the TOF bit and the writing of 0 to * the TOF bit, the process of clearing the TOF bit * does not work as expected when FTMx_CONF[NUMTOF] != 0 * and the current TOF count is less than FTMx_CONF[NUMTOF]. * If the above condition is met, the TOF bit remains set. * If the TOF interrupt is enabled (FTMx_SC[TOIE] = 1),the * TOF interrupt also remains asserted. * * Above is the errata discription * * In one word: software clearing TOF bit not works when * FTMx_CONF[NUMTOF] was seted as nonzero and FTM counter * reaches the FTM_MOD value. * * The workaround is clearing TOF bit until it works * (FTM counter doesn't always reache the FTM_MOD anyway), * which may cost some cycles.
*/ while ((FTM_SC_TOF & rtc_readl(rtc, FTM_SC)) && timeout--)
rtc_writel(rtc, FTM_SC, rtc_readl(rtc, FTM_SC) & (~FTM_SC_TOF));
}
val = rtc_readl(rtc, FTM_SC);
val &= ~FTM_SC_TOIE;
rtc_writel(rtc, FTM_SC, val);
}
staticinlinevoid ftm_reset_counter(struct ftm_rtc *rtc)
{ /* * The CNT register contains the FTM counter value. * Reset clears the CNT register. Writing any value to COUNT * updates the counter with its initial value, CNTIN.
*/
rtc_writel(rtc, FTM_CNT, 0x00);
}
if (enabled)
ftm_irq_enable(rtc); else
ftm_irq_disable(rtc);
return 0;
}
/* * Note: * The function is not really getting time from the RTC * since FlexTimer is not a RTC device, but we need to * get time to setup alarm, so we are using system time * for now.
*/ staticint ftm_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
rtc_time64_to_tm(ktime_get_real_seconds(), tm);
/* * 1. Select fixed frequency clock (32KHz) as clock source; * 2. Select 128 (2^7) as divider factor; * So clock is 250 Hz (32KHz/128). * * 3. FlexTimer's CNT register is a 32bit register, * but the register's 16 bit as counter value,it's other 16 bit * is reserved.So minimum counter value is 0x0,maximum counter * value is 0xffff. * So max alarm value is 262 (65536 / 250) seconds
*/ staticint ftm_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm)
{
time64_t alm_time; unsignedlonglong cycle; struct ftm_rtc *rtc = dev_get_drvdata(dev);
alm_time = rtc_tm_to_time64(&alm->time);
ftm_clean_alarm(rtc);
cycle = (alm_time - ktime_get_real_seconds()) * rtc->alarm_freq; if (cycle > MAX_COUNT_VAL) {
pr_err("Out of alarm range {0~262} seconds.\n"); return -ERANGE;
}
ftm_irq_disable(rtc);
/* * The counter increments until the value of MOD is reached, * at which point the counter is reloaded with the value of CNTIN. * The TOF (the overflow flag) bit is set when the FTM counter * changes from MOD to CNTIN. So we should using the cycle - 1.
*/
rtc_writel(rtc, FTM_MOD, cycle - 1);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.