090-timers.patch 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. --- a/arch/arm/mach-cns3xxx/core.c
  2. +++ b/arch/arm/mach-cns3xxx/core.c
  3. @@ -138,6 +138,7 @@ static int cns3xxx_set_oneshot(struct cl
  4. /* period set, and timer enabled in 'next_event' hook */
  5. ctrl |= (1 << 2) | (1 << 9);
  6. + writel(0, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
  7. writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  8. return 0;
  9. }
  10. @@ -148,7 +149,7 @@ static int cns3xxx_set_periodic(struct c
  11. int pclk = cns3xxx_cpu_clock() / 8;
  12. int reload;
  13. - reload = pclk * 20 / (3 * HZ) * 0x25000;
  14. + reload = pclk * 1000000 / HZ;
  15. writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
  16. ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
  17. writel(ctrl, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  18. @@ -175,7 +176,7 @@ static struct clock_event_device cns3xxx
  19. .set_state_oneshot = cns3xxx_set_oneshot,
  20. .tick_resume = cns3xxx_shutdown,
  21. .set_next_event = cns3xxx_timer_set_next_event,
  22. - .rating = 350,
  23. + .rating = 300,
  24. .cpumask = cpu_all_mask,
  25. };
  26. @@ -220,6 +221,32 @@ static void __init cns3xxx_init_twd(void
  27. twd_local_timer_register(&cns3xx_twd_local_timer);
  28. }
  29. +static cycle_t cns3xxx_get_cycles(struct clocksource *cs)
  30. +{
  31. + u64 val;
  32. +
  33. + val = readl(cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
  34. + val &= 0xffff;
  35. +
  36. + return ((val << 32) | readl(cns3xxx_tmr1 + TIMER_FREERUN_OFFSET));
  37. +}
  38. +
  39. +static struct clocksource clocksource_cns3xxx = {
  40. + .name = "freerun",
  41. + .rating = 200,
  42. + .read = cns3xxx_get_cycles,
  43. + .mask = CLOCKSOURCE_MASK(48),
  44. + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
  45. +};
  46. +
  47. +static void __init cns3xxx_clocksource_init(void)
  48. +{
  49. + /* Reset the FreeRunning counter */
  50. + writel((1 << 16), cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
  51. +
  52. + clocksource_register_khz(&clocksource_cns3xxx, 100);
  53. +}
  54. +
  55. /*
  56. * Set up the clock source and clock events devices
  57. */
  58. @@ -237,13 +264,12 @@ static void __init __cns3xxx_timer_init(
  59. /* stop free running timer3 */
  60. writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
  61. - /* timer1 */
  62. - writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
  63. - writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
  64. -
  65. writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
  66. writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
  67. + val = (cns3xxx_cpu_clock() >> 3) * 1000000 / HZ;
  68. + writel(val, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
  69. +
  70. /* mask irq, non-mask timer1 overflow */
  71. irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
  72. irq_mask &= ~(1 << 2);
  73. @@ -255,23 +281,9 @@ static void __init __cns3xxx_timer_init(
  74. val |= (1 << 9);
  75. writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  76. - /* timer2 */
  77. - writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
  78. - writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
  79. -
  80. - /* mask irq */
  81. - irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
  82. - irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
  83. - writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
  84. -
  85. - /* down counter */
  86. - val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  87. - val |= (1 << 10);
  88. - writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  89. -
  90. - /* Make irqs happen for the system timer */
  91. setup_irq(timer_irq, &cns3xxx_timer_irq);
  92. + cns3xxx_clocksource_init();
  93. cns3xxx_clockevents_init(timer_irq);
  94. cns3xxx_init_twd();
  95. }