123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223 |
- #include <kernel.h>
- #include <drivers/timer/system_timer.h>
- #include <sys_clock.h>
- #include <spinlock.h>
- #include <soc.h>
- #define USE_T2_FOR_CYCLE
- #define CYC_PER_TICK (sys_clock_hw_cycles_per_sec() \
- / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
- #define MAX_TICKS ((0x40000000 / CYC_PER_TICK) - 1)
- #define MAX_CYCLES (MAX_TICKS * CYC_PER_TICK)
- static struct k_spinlock lock;
- static uint32_t cycle_count;
- static uint32_t announced_cycles;
- static uint32_t last_cycle_count;
- static uint32_t sleep_cycle_count;
- #if defined(CONFIG_PM_DEVICE)
- static uint32_t sleep_st_cycle;
- #endif
- static uint32_t acts_timer_elapsed(void)
- {
- return sys_read32(T0_CNT)-last_cycle_count;
- }
- #ifdef USE_T2_FOR_CYCLE
- static int timer_cyc_init(const struct device *arg)
- {
- #ifdef CONFIG_SOC_SERIES_LEOPARD
- acts_clock_peripheral_enable(CLOCK_ID_TIMER2);
- acts_reset_peripheral(CLOCK_ID_TIMER2);
- #endif
- sys_write32(0x0, CMU_TIMER2CLK);
- sys_write32(0x1, T2_CTL);
- timer_reg_wait();
- sys_write32(TIMER_MAX_CYCLES_VALUE, T2_VAL);
- sys_write32(0x824, T2_CTL);
- }
- SYS_INIT(timer_cyc_init, PRE_KERNEL_1, 0);
- #endif
- static void acts_timer_set_next_irq(uint32_t cycle)
- {
- if(cycle < CYC_PER_TICK/100)
- cycle = CYC_PER_TICK/100;
- if(cycle > MAX_CYCLES)
- cycle = MAX_CYCLES;
- sys_write32(sys_read32(T0_CNT)+cycle, T0_VAL);
- }
- void acts_timer_isr(void *arg)
- {
- ARG_UNUSED(arg);
- uint32_t dticks, cycle;
-
- sys_write32(sys_read32(T0_CTL), T0_CTL);
- cycle = sys_read32(T0_CNT);
- cycle_count += cycle-last_cycle_count;
- last_cycle_count = cycle;
- if(sleep_cycle_count){
- cycle_count += sleep_cycle_count;
- sleep_cycle_count = 0;
- }
- #if defined(CONFIG_TICKLESS_KERNEL)
- dticks = (cycle_count - announced_cycles) / CYC_PER_TICK;
- announced_cycles += dticks * CYC_PER_TICK;
-
- sys_clock_announce(dticks);
- #else
- acts_timer_set_next_irq(CYC_PER_TICK);
- sys_clock_announce(1);
- #endif
-
- }
- int sys_clock_driver_init(const struct device *device)
- {
-
- sys_write32(0x0, CMU_TIMER0CLK);
- #ifdef CONFIG_SOC_SERIES_LEOPARD
- acts_clock_peripheral_enable(CLOCK_ID_TIMER0);
- #else
- acts_clock_peripheral_enable(CLOCK_ID_TIMER);
- #endif
- sys_write32(0x1, T0_CTL);
- timer_reg_wait();
- sys_write32(0xe22, T0_CTL);
- acts_timer_set_next_irq(CYC_PER_TICK);
-
- IRQ_CONNECT(IRQ_ID_TIMER0, 1, acts_timer_isr, 0, 0);
- irq_enable(IRQ_ID_TIMER0);
- return 0;
- }
- #define RC32K_MUTIPLE soc_rc32K_mutiple_hosc()
- void sys_clock_set_timeout(int32_t ticks, bool idle)
- {
- #if defined(CONFIG_TICKLESS_KERNEL)
- k_spinlock_key_t key = k_spin_lock(&lock);
- uint32_t delay;
- ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : ticks;
- if(!ticks)
- ticks = 1;
- uint32_t unannounced = cycle_count - announced_cycles + acts_timer_elapsed();
-
- delay = ticks * CYC_PER_TICK;
- if(unannounced > delay){
- acts_timer_set_next_irq(20);
- }else{
- delay = delay - unannounced + 1;
- acts_timer_set_next_irq(delay);
- }
- k_spin_unlock(&lock, key);
- #endif
- }
- #if defined(CONFIG_PM_DEVICE)
- #include <wait_q.h>
- int sys_clock_device_ctrl(const struct device *device, enum pm_device_action action)
- {
- if(action == PM_DEVICE_ACTION_RESUME){
- uint32_t cycle = 0;
- if(sleep_st_cycle){
- cycle = sys_read32(T0_CNT);
- sys_write32(0x0, CMU_TIMER0CLK);
- cycle -= sleep_st_cycle;
- sleep_cycle_count = cycle*RC32K_MUTIPLE;
- sleep_st_cycle = 0;
- printk("-t0-s=%d ms\n", cycle*1000/32768);
- #if 0
- acts_timer_set_next_irq(20);
- #else
- last_cycle_count = sys_read32(T0_CNT);
- sleep_cycle_count = 0;
- sys_clock_set_timeout(z_get_next_timeout_expiry(), 0);
- #endif
- }
- } else if (action == PM_DEVICE_ACTION_SUSPEND){
- sys_write32(0x4, CMU_TIMER0CLK);
- sleep_st_cycle = sys_read32(T0_CNT);
- if(sleep_st_cycle == 0)
- sleep_st_cycle = 1;
- }
- return 0;
- }
- #endif
- uint32_t sys_clock_elapsed(void)
- {
- #if defined(CONFIG_TICKLESS_KERNEL)
- k_spinlock_key_t key = k_spin_lock(&lock);
- uint32_t cyc = acts_timer_elapsed() + cycle_count - announced_cycles;
- k_spin_unlock(&lock, key);
- return cyc / CYC_PER_TICK;
- #else
- return 0 ;
- #endif
- }
- uint32_t sys_clock_cycle_get_32(void)
- {
- #ifdef USE_T2_FOR_CYCLE
- return sys_read32(T2_CNT);
- #else
- k_spinlock_key_t key = k_spin_lock(&lock);
- uint32_t ret = acts_timer_elapsed() + cycle_count ;
- k_spin_unlock(&lock, key);
- return ret;
- #endif
- }
- void sys_clock_idle_exit(void)
- {
- }
- void sys_clock_disable(void)
- {
- }
|