jz4760: Use HW timer for more a more accurate udelay()

(More specifically, use the SoC's "OS Timer", slaved to the main XTAL so
 it doesn't matter how the main CPU is clocked)

Change-Id: I799561ac823ff7f659a05144cf03b6a13d57ea7b
This commit is contained in:
Solomon Peachy 2020-08-12 23:03:33 -04:00
parent 7ed126386a
commit a9ac2d0ba3

View file

@ -28,6 +28,8 @@
#include "kernel.h"
#include "power.h"
#define USE_HW_UDELAY
static int irq;
static void UIRQ(void)
{
@ -335,6 +337,28 @@ void tlb_refill_handler(void)
panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr());
}
#ifdef USE_HW_UDELAY
/* This enables the HW timer, set to EXT_XTAL / 16 (so @ 12MHz, 1 us = 750 ticks) */
static void init_delaytimer(void)
{
__tcu_disable_ost();
REG_OST_OSTCSR = OSTCSR_EXT_EN | OSTCSR_PRESCALE16 | OSTCSR_CNT_MD;
REG_OST_OSTCNT = 0;
REG_OST_OSTDR = 0;
__tcu_enable_ost();
}
void udelay(unsigned int usec)
{
if (!__tcu_ost_enabled())
init_delaytimer();
/* Figure out how many ticks we need */
usec = (CFG_EXTAL / 16 / 1000) * (usec + 1);
while (usec < REG_OST_OSTCNT) { }
}
#else
void udelay(unsigned int usec)
{
unsigned int i = usec * (__cpm_get_cclk() / 2000000);
@ -348,6 +372,7 @@ void udelay(unsigned int usec)
: "0" (i)
);
}
#endif
void mdelay(unsigned int msec)
{
@ -657,6 +682,10 @@ void ICODE_ATTR system_main(void)
for(i=0; i<IRQ_INTC_MAX; i++)
dis_irq(i);
#ifdef USE_HW_UDELAY
init_delaytimer();
#endif
mmu_init();
pll0_init(CPUFREQ_DEFAULT); // PLL0 drives everything but audio