summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSolomon Peachy <pizza@shaftnet.org>2020-09-05 20:16:17 -0400
committerSolomon Peachy <pizza@shaftnet.org>2020-09-06 02:09:21 +0000
commit53142ae9f57306fb44870c8ea156892d15cb31a7 (patch)
tree12f4cd60849f9becd675aeaf7f9d5eba99a17c84
parent2dadb8c7d6bc4383565e0f35ef0f0a5b9520044d (diff)
downloadrockbox-53142ae9f57306fb44870c8ea156892d15cb31a7.tar.gz
rockbox-53142ae9f57306fb44870c8ea156892d15cb31a7.zip
jz4760: Fix and re-enable the hardware udelay() timer
Change-Id: I591b4f023776b3501fce03e08bfc87a355f4c69b
-rw-r--r--firmware/target/mips/ingenic_jz47xx/system-jz4760.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/system-jz4760.c b/firmware/target/mips/ingenic_jz47xx/system-jz4760.c
index 19fe0ba661..10973f3e2b 100644
--- a/firmware/target/mips/ingenic_jz47xx/system-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/system-jz4760.c
@@ -28,7 +28,7 @@
28#include "kernel.h" 28#include "kernel.h"
29#include "power.h" 29#include "power.h"
30 30
31//#define USE_HW_UDELAY // This is BROKEN. 31#define HW_UDELAY_TIMER 3
32#ifdef BOOTLOADER 32#ifdef BOOTLOADER
33#define WITH_SERIAL 33#define WITH_SERIAL
34#endif 34#endif
@@ -341,28 +341,35 @@ void tlb_refill_handler(void)
341 panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr()); 341 panicf("TLB refill handler at 0x%08lx! [0x%x]", read_c0_epc(), read_c0_badvaddr());
342} 342}
343 343
344#ifdef USE_HW_UDELAY 344#ifdef HW_UDELAY_TIMER
345/* This enables the HW timer, set to EXT_XTAL / 4 (so @ 12/4 = 3MHz, 1 us = 3 ticks) */ 345/* This enables the HW timer, set to EXT_XTAL / 4 (so @ 12/4 = 3MHz, 1 us = 3 ticks) */
346static void init_delaytimer(void) 346static void init_delaytimer(void)
347{ 347{
348 __tcu_disable_ost(); 348 __tcu_stop_counter(HW_UDELAY_TIMER);
349 REG_OST_OSTCSR = OSTCSR_EXT_EN | OSTCSR_PRESCALE4 | OSTCSR_CNT_MD; 349 __tcu_disable_pwm_output(HW_UDELAY_TIMER);
350 REG_OST_OSTCNT = 0; 350 __tcu_select_extalclk(HW_UDELAY_TIMER);
351 REG_OST_OSTDR = 0; 351 __tcu_clear_half_match_flag(HW_UDELAY_TIMER);
352 __tcu_enable_ost(); 352 __tcu_clear_full_match_flag(HW_UDELAY_TIMER);
353 __tcu_mask_half_match_irq(HW_UDELAY_TIMER);
354 __tcu_mask_full_match_irq(HW_UDELAY_TIMER);
355 __tcu_select_clk_div4(HW_UDELAY_TIMER);
356 REG_TCU_TCNT(HW_UDELAY_TIMER) = 0;
357 REG_TCU_TDFR(HW_UDELAY_TIMER) = 0xffff; /* wraps at 21.845ms */
358 __tcu_start_counter(HW_UDELAY_TIMER);
353} 359}
354 360
355void udelay(unsigned int usec) 361void udelay(unsigned int usec) /* Must be under 21845 us! */
356{ 362{
357 if (!__tcu_ost_enabled()) 363 if (!__tcu_counter_enabled(HW_UDELAY_TIMER))
358 init_delaytimer(); 364 init_delaytimer();
359 365
360 unsigned int now = REG_OST_OSTCNT; 366 unsigned short start = REG_TCU_TCNT(HW_UDELAY_TIMER);
361 367
362 /* Figure out how many ticks we need */ 368 /* Figure out how many ticks we need */
363 usec = (CFG_EXTAL / (4 * 1000 * 1000)) * (usec + 1); 369 usec = (CFG_EXTAL / (4 * 1000 * 1000)) * (usec + 1);
364 370
365 while (REG_OST_OSTCNT - now < usec) { } 371 while (((REG_TCU_TCNT(HW_UDELAY_TIMER) - start) & 0xffff) < usec) { }
372 // while (start + usec < REG_TCU_TCNT(HW_UDELAY_TIMER)) { };
366} 373}
367#else 374#else
368void udelay(unsigned int usec) 375void udelay(unsigned int usec)
@@ -681,7 +688,7 @@ void ICODE_ATTR system_main(void)
681 for(i=0; i<IRQ_INTC_MAX; i++) 688 for(i=0; i<IRQ_INTC_MAX; i++)
682 dis_irq(i); 689 dis_irq(i);
683 690
684#ifdef USE_HW_UDELAY 691#ifdef HW_UDELAY_TIMER
685 init_delaytimer(); 692 init_delaytimer();
686#endif 693#endif
687 694