static void timer_set_mode(enum clock_event_mode mode, struct clock_event_device *evt) { //unsigned short ctl=TIMER_INTERRUPT; unsigned long ctl = FLAG_TIMER_PRESCALAR; switch (mode) { case CLOCK_EVT_MODE_PERIODIC: interval = (unsigned long)(GLB_TIMER_FREQ_KHZ*1000 / HZ) ; PERI_W(WDT_LOADER, interval); ctl |= FLAG_IT_ENABLE | FLAG_AUTO_RELOAD | FLAG_TIMER_ENABLE; break; case CLOCK_EVT_MODE_ONESHOT: /* period set, and timer enabled in 'next_event' hook */ PERI_W(WDT_COUNTER, 0); ctl |= FLAG_IT_ENABLE | FLAG_TIMER_ENABLE; break; case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: default: break; } PERI_W(WDT_CONTROL, ctl); }
void __init chip_init_ptimer(void){ unsigned long interval,temp; /* set up interrupt controller attributes for the timer interrupt */ #ifdef CONFIG_MSTAR_ARM_BD_FPGA GLB_TIMER_FREQ_KHZ= 24*1000/2 ; // PERIPHCLK = CPU Clock / 2 #else GLB_TIMER_FREQ_KHZ=(query_frequency()*1000)/ 2; // PERIPHCLK = CPU Clock / 2 #endif printk("CPU Clock Frequency = %d MHz\n",GLB_TIMER_FREQ_KHZ*2/1000); //clear timer event flag PERI_W(PT_STATUS,FLAG_EVENT); //set timer interrupt interval interval = ( GLB_TIMER_FREQ_KHZ * 1000 / HZ ); PERI_W(PT_LOADER,interval); //Interrupt Set Enable Register temp=PERI_R(GIC_DIST_SET_EANBLE); temp= temp | (0x1 << INT_ID_PTIMER); PERI_W(GIC_DIST_SET_EANBLE,temp); //setup timer IRQ setup_irq(INT_ID_PTIMER, &chip_ptimer_irq); //set AUTO Reload & Timer Interrupt //PERI_W(PT_CONTROL,(FLAG_IT_ENABLE | FLAG_AUTO_RELOAD)); //start timer PERI_W(PT_CONTROL,(FLAG_TIMER_PRESCALAR | FLAG_IT_ENABLE | FLAG_AUTO_RELOAD| FLAG_TIMER_ENABLE)); }
void __init chip_clocksource_init(unsigned int base) { struct clocksource *cs = &clocksource_timer; clksrc_base = base; #if USE_GLOBAL_TIMER PERI_W(GT_CONTROL,0x1); //Enable //calculate the value of mult //cycle= ( time(ns) *mult ) >> shift cs->mult = clocksource_khz2mult(GLB_TIMER_FREQ_KHZ, cs->shift);//PERICLK = CPUCLK/2 #else /* setup timer 1 as free-running clocksource */ //make sure timer 1 is disable CLRREG16(clksrc_base, TIMER_ENABLE); //set max period OUTREG16(clksrc_base+(0x2<<2),0xffff); OUTREG16(clksrc_base+(0x3<<2),0xffff); //enable timer 1 SETREG16(clksrc_base, TIMER_ENABLE); // TODO: need to double check //calculate the value of mult //cycle= ( time(ns) *mult ) >> shift cs->mult = clocksource_khz2mult(GLB_TIMER_FREQ_KHZ, cs->shift); //Mstar timer =>12Mhz, #endif clocksource_register(cs); }
static int timer_set_next_event(unsigned long next, struct clock_event_device *evt) { //set next event triiger counter PERI_W(WDT_COUNTER, next); return 0; }
static irqreturn_t chip_ptimer_interrupt(int irq, void *dev_id) { //unsigned int count; timer_tick(); tmp=PERI_R(PT_CONTROL); //stop timer PERI_W(PT_CONTROL,(tmp & ~FLAG_TIMER_ENABLE)); //clear timer event flag PERI_W(PT_STATUS,FLAG_EVENT); //start timer PERI_W(PT_CONTROL,( tmp | FLAG_TIMER_ENABLE)); return IRQ_HANDLED; }
/* * IRQ handler for the timer */ static irqreturn_t timer_interrupt(int irq, void *dev_id) { struct clock_event_device *evt = dev_id; //clear timer event flag PERI_W(WDT_STATUS, FLAG_EVENT); evt->event_handler(evt); return IRQ_HANDLED; }
void __init edison_clockevents_init(unsigned int irq) { struct clock_event_device *evt = &clockevent_timer; unsigned long temp; evt->irq = (int)irq; evt->mult = div_sc((unsigned long)GLB_TIMER_FREQ_KHZ, NSEC_PER_MSEC, (int)evt->shift); //PIU Timer FRE = 12Mhz evt->max_delta_ns = clockevent_delta2ns(0xffffffff, evt); evt->min_delta_ns = clockevent_delta2ns(0xf, evt); //clear timer event flag PERI_W(WDT_STATUS, FLAG_EVENT); //Interrupt Set Enable Register temp = PERI_R(GIC_DIST_SET_EANBLE); temp = temp | (unsigned long)(0x1 << irq); PERI_W(GIC_DIST_SET_EANBLE, temp); //setup_irq(irq, &timer_irq); setup_irq(irq, &timer_irq); clockevents_register_device(evt); }
void __init chip_init_irq(void) { unsigned long temp; #if 1 gic_init(0,29,_gic_dist_base_addr,_gic_cpu_base_addr); #else gic_dist_init(0, gic_dist_base_addr , 29); gic_cpu_init(0, gic_cpu_base_addr); #endif #if defined(CONFIG_MP_PLATFORM_MSTAR_LEGANCY_INTR) arm_interrupt_chain_setup(INT_PPI_IRQ); #else //GIC Interrupt Set Enable Register for MSTAR controller temp=PERI_R(GIC_DIST_SET_EANBLE); temp= temp | (0x1 << INT_PPI_IRQ ); PERI_W(GIC_DIST_SET_EANBLE,temp); #endif /* CONFIG_MP_PLATFORM_MSTAR_LEGANCY_INTR */ }