summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-08-12 23:03:33 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-08-12 23:03:33 -0400
commita9ac2d0ba3b01de26944dc6a93c490c89c4ead70 (patch)
treef2e07fe743fa97093b345490ee68c2e85a3fcbb8 /firmware
parent7ed126386a2d1383ac331590c3662d720067b100 (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.c29
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