090-timers.patch 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. --- a/arch/arm/mach-cns3xxx/core.c
  2. +++ b/arch/arm/mach-cns3xxx/core.c
  3. @@ -135,12 +135,13 @@ static void cns3xxx_timer_set_mode(enum
  4. switch (mode) {
  5. case CLOCK_EVT_MODE_PERIODIC:
  6. - reload = pclk * 20 / (3 * HZ) * 0x25000;
  7. + reload = pclk * 1000000 / HZ;
  8. writel(reload, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
  9. ctrl |= (1 << 0) | (1 << 2) | (1 << 9);
  10. break;
  11. case CLOCK_EVT_MODE_ONESHOT:
  12. /* period set, and timer enabled in 'next_event' hook */
  13. + writel(0, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
  14. ctrl |= (1 << 2) | (1 << 9);
  15. break;
  16. case CLOCK_EVT_MODE_UNUSED:
  17. @@ -168,7 +169,7 @@ static struct clock_event_device cns3xxx
  18. .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
  19. .set_mode = cns3xxx_timer_set_mode,
  20. .set_next_event = cns3xxx_timer_set_next_event,
  21. - .rating = 350,
  22. + .rating = 300,
  23. .cpumask = cpu_all_mask,
  24. };
  25. @@ -215,6 +216,35 @@ static void __init cns3xxx_init_twd(void
  26. #endif
  27. }
  28. +static cycle_t cns3xxx_get_cycles(struct clocksource *cs)
  29. +{
  30. + u64 val;
  31. +
  32. + val = readl(cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
  33. + val &= 0xffff;
  34. +
  35. + return ((val << 32) | readl(cns3xxx_tmr1 + TIMER_FREERUN_OFFSET));
  36. +}
  37. +
  38. +static struct clocksource clocksource_cns3xxx = {
  39. + .name = "freerun",
  40. + .rating = 200,
  41. + .read = cns3xxx_get_cycles,
  42. + .mask = CLOCKSOURCE_MASK(48),
  43. + .shift = 16,
  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_cns3xxx.mult =
  53. + clocksource_khz2mult(100, clocksource_cns3xxx.shift);
  54. + clocksource_register(&clocksource_cns3xxx);
  55. +}
  56. +
  57. /*
  58. * Set up the clock source and clock events devices
  59. */
  60. @@ -232,13 +262,12 @@ static void __init __cns3xxx_timer_init(
  61. /* stop free running timer3 */
  62. writel(0, cns3xxx_tmr1 + TIMER_FREERUN_CONTROL_OFFSET);
  63. - /* timer1 */
  64. - writel(0x5C800, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
  65. - writel(0x5C800, cns3xxx_tmr1 + TIMER1_AUTO_RELOAD_OFFSET);
  66. -
  67. writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V1_OFFSET);
  68. writel(0, cns3xxx_tmr1 + TIMER1_MATCH_V2_OFFSET);
  69. + val = (cns3xxx_cpu_clock() >> 3) * 1000000 / HZ;
  70. + writel(val, cns3xxx_tmr1 + TIMER1_COUNTER_OFFSET);
  71. +
  72. /* mask irq, non-mask timer1 overflow */
  73. irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
  74. irq_mask &= ~(1 << 2);
  75. @@ -250,23 +279,9 @@ static void __init __cns3xxx_timer_init(
  76. val |= (1 << 9);
  77. writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  78. - /* timer2 */
  79. - writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V1_OFFSET);
  80. - writel(0, cns3xxx_tmr1 + TIMER2_MATCH_V2_OFFSET);
  81. -
  82. - /* mask irq */
  83. - irq_mask = readl(cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
  84. - irq_mask |= ((1 << 3) | (1 << 4) | (1 << 5));
  85. - writel(irq_mask, cns3xxx_tmr1 + TIMER1_2_INTERRUPT_MASK_OFFSET);
  86. -
  87. - /* down counter */
  88. - val = readl(cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  89. - val |= (1 << 10);
  90. - writel(val, cns3xxx_tmr1 + TIMER1_2_CONTROL_OFFSET);
  91. -
  92. - /* Make irqs happen for the system timer */
  93. setup_irq(timer_irq, &cns3xxx_timer_irq);
  94. + cns3xxx_clocksource_init();
  95. cns3xxx_clockevents_init(timer_irq);
  96. cns3xxx_init_twd();
  97. }