diff options
-rw-r--r-- | firmware/target/mips/ingenic_jz47xx/system-jz4760.c | 31 |
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) */ |
346 | static void init_delaytimer(void) | 346 | static 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 | ||
355 | void udelay(unsigned int usec) | 361 | void 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 |
368 | void udelay(unsigned int usec) | 375 | void 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 | ||