123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- --- a/arch/arm/mach-cns3xxx/core.c
- +++ b/arch/arm/mach-cns3xxx/core.c
- @@ -135,12 +135,13 @@ static void cns3xxx_timer_set_mode(enum
-
- switch (mode) {
- case CLOCK_EVT_MODE_PERIODIC:
- - 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);
- break;
- case CLOCK_EVT_MODE_ONESHOT:
- /* period set, and timer enabled in 'next_event' hook */
- + writel(0, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
- ctrl |= (1 << 2) | (1 << 9);
- break;
- case CLOCK_EVT_MODE_UNUSED:
- @@ -168,7 +169,7 @@ static struct clock_event_device cns3xxx
- .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
- .set_mode = cns3xxx_timer_set_mode,
- .set_next_event = cns3xxx_timer_set_next_event,
- - .rating = 350,
- + .rating = 300,
- .cpumask = cpu_all_mask,
- };
-
- @@ -215,6 +216,35 @@ static void __init cns3xxx_init_twd(void
- #endif
- }
-
- +static cycle_t 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),
- + .shift = 16,
- + .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_cns3xxx.mult =
- + clocksource_khz2mult(100, clocksource_cns3xxx.shift);
- + clocksource_register(&clocksource_cns3xxx);
- +}
- +
- /*
- * Set up the clock source and clock events devices
- */
- @@ -232,13 +262,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);
- @@ -250,23 +279,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();
- }
|