104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| --- a/arch/arm/mach-cns3xxx/core.c
 | |
| +++ b/arch/arm/mach-cns3xxx/core.c
 | |
| @@ -138,6 +138,7 @@ static int cns3xxx_set_oneshot(struct cl
 | |
|  
 | |
|  	/* period set, and timer enabled in 'next_event' hook */
 | |
|  	ctrl |= (1 << 2) | (1 << 9);
 | |
| +	writel(0, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
 | |
|  	writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | |
|  	return 0;
 | |
|  }
 | |
| @@ -148,7 +149,7 @@ static int cns3xxx_set_periodic(struct c
 | |
|  	int pclk = cns3xxx_cpu_clock() / 8;
 | |
|  	int reload;
 | |
|  
 | |
| -	reload = pclk * 20 / (3 * HZ) * 0x25000;
 | |
| +	reload = pclk * 1000000 / HZ;
 | |
|  	writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
 | |
|  	ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
 | |
|  	writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | |
| @@ -175,7 +176,7 @@ static struct clock_event_device cns3xxx
 | |
|  	.set_state_oneshot	= cns3xxx_set_oneshot,
 | |
|  	.tick_resume		= cns3xxx_shutdown,
 | |
|  	.set_next_event		= cns3xxx_timer_set_next_event,
 | |
| -	.rating			= 350,
 | |
| +	.rating			= 300,
 | |
|  	.cpumask		= cpu_all_mask,
 | |
|  };
 | |
|  
 | |
| @@ -220,6 +221,32 @@ static void __init cns3xxx_init_twd(void
 | |
|  	twd_local_timer_register(&cns3xx_twd_local_timer);
 | |
|  }
 | |
|  
 | |
| +static u64 cns3xxx_get_cycles(struct clocksource *cs)
 | |
| +{
 | |
| +  u64 val;
 | |
| +
 | |
| +  val = readl(cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
 | |
| +  val &= 0xffff;
 | |
| +
 | |
| +  return ((val << 32) | readl(cns3xxx_tmr1 + TIMER_FREERUN_OFFSET));
 | |
| +}
 | |
| +
 | |
| +static struct clocksource clocksource_cns3xxx = {
 | |
| +	.name = "freerun",
 | |
| +	.rating = 200,
 | |
| +	.read = cns3xxx_get_cycles,
 | |
| +	.mask = CLOCKSOURCE_MASK(48),
 | |
| +	.flags  = CLOCK_SOURCE_IS_CONTINUOUS,
 | |
| +};
 | |
| +
 | |
| +static void __init cns3xxx_clocksource_init(void)
 | |
| +{
 | |
| +	/* Reset the FreeRunning counter */
 | |
| +	writel((1 << 16), cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
 | |
| +
 | |
| +	clocksource_register_khz(&clocksource_cns3xxx, 100);
 | |
| +}
 | |
| +
 | |
|  /*
 | |
|   * Set up the clock source and clock events devices
 | |
|   */
 | |
| @@ -237,13 +264,12 @@ static void __init __cns3xxx_timer_init(
 | |
|  	/* stop free running timer3 */
 | |
|  	writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
 | |
|  
 | |
| -	/* timer1 */
 | |
| -	writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
 | |
| -	writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
 | |
| -
 | |
|  	writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
 | |
|  	writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
 | |
|  
 | |
| +	val = (cns3xxx_cpu_clock() >> 3) * 1000000 / HZ;
 | |
| +	writel(val, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
 | |
| +
 | |
|  	/* mask irq, non-mask timer1 overflow */
 | |
|  	irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
 | |
|  	irq_mask &= ~(1 << 2);
 | |
| @@ -255,23 +281,9 @@ static void __init __cns3xxx_timer_init(
 | |
|  	val |= (1 << 9);
 | |
|  	writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | |
|  
 | |
| -	/* timer2 */
 | |
| -	writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
 | |
| -	writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
 | |
| -
 | |
| -	/* mask irq */
 | |
| -	irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
 | |
| -	irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
 | |
| -	writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
 | |
| -
 | |
| -	/* down counter */
 | |
| -	val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | |
| -	val |= (1 << 10);
 | |
| -	writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
 | |
| -
 | |
| -	/* Make irqs happen for the system timer */
 | |
|  	setup_irq(timer_irq, &cns3xxx_timer_irq);
 | |
|  
 | |
| +	cns3xxx_clocksource_init();
 | |
|  	cns3xxx_clockevents_init(timer_irq);
 | |
|  	cns3xxx_init_twd();
 | |
|  }
 | 
