diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2020-08-12 23:03:33 -0400 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-08-12 23:03:33 -0400 |
commit | a9ac2d0ba3b01de26944dc6a93c490c89c4ead70 (patch) | |
tree | f2e07fe743fa97093b345490ee68c2e85a3fcbb8 /firmware | |
parent | 7ed126386a2d1383ac331590c3662d720067b100 (diff) |
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
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4760.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4760.c b/firmware/target/mips/ingenic_jz47xx/system-jz4760.c index c28aa8f967..3d4015c465 100644 --- a/firmware/target/mips/ingenic_jz47xx/system-jz4760.c +++ b/firmware/target/mips/ingenic_jz47xx/system-jz4760.c @@ -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 |