/* * Disabling CPUXGPT timer will crash the platform, especially * if Trusted Firmware is using it (usually, for sleep states), * so we only mask the IRQ and call it a day.
*/ return 0;
}
staticstruct timer_of to = { /* * There are per-cpu interrupts for the CPUX General Purpose Timer * but since this timer feeds the AArch64 System Timer we can rely * on the CPU timer PPIs as well, so we don't declare TIMER_OF_IRQ.
*/
.flags = TIMER_OF_BASE | TIMER_OF_CLOCK,
/* If this fails, bad things are about to happen... */
ret = timer_of_init(node, &to); if (ret) {
WARN(1, "Cannot start CPUX timers.\n"); return ret;
}
/* * Check if we're given a clock with the right frequency for this * timer, otherwise warn but keep going with the setup anyway, as * that makes it possible to still boot the kernel, even though * it may not work correctly (random lockups, etc). * The reason behind this is that having an early UART may not be * possible for everyone and this gives a chance to retrieve kmsg * for eventual debugging even on consumer devices.
*/
freq = timer_of_rate(&to); if (freq > 13000000)
WARN(1, "Requested unsupported timer frequency %u\n", freq);
/* Clock input is 26MHz, set DIV2 to achieve 13MHz clock */
val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to);
val &= ~CPUX_CLK_DIV_MASK;
val |= CPUX_CLK_DIV2;
mtk_cpux_writel(val, CPUX_IDX_GLOBAL_CTRL, &to);
/* Enable all CPUXGPT timers */
val = mtk_cpux_readl(CPUX_IDX_GLOBAL_CTRL, &to);
mtk_cpux_writel(val | CPUX_ENABLE, CPUX_IDX_GLOBAL_CTRL, &to);
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.