Merge remote-tracking branch 'lsk/v3.10/topic/mm-timer' into linux-linaro-lsk
authorMark Brown <broonie@linaro.org>
Fri, 13 Jun 2014 19:59:53 +0000 (20:59 +0100)
committerMark Brown <broonie@linaro.org>
Fri, 13 Jun 2014 19:59:53 +0000 (20:59 +0100)
Conflicts:
drivers/clocksource/arm_arch_timer.c

1  2 
arch/arm/include/asm/arch_timer.h
arch/arm64/include/asm/arch_timer.h
drivers/clocksource/arm_arch_timer.c
include/clocksource/arm_arch_timer.h

Simple merge
Simple merge
index 958591e94f2aac7f16e7184ec8a3b6c777a47e54,89affb5606b5875b5455d7ee01904ced94460cfc..67bbbd8ae507b5e4e937abcf616288861d430182
@@@ -124,40 -240,62 +241,75 @@@ static int arch_timer_set_next_event_ph
        return 0;
  }
  
- static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
 +static void arch_timer_configure_evtstream(void)
 +{
 +      int evt_stream_div, pos;
 +
 +      /* Find the closest power of two to the divisor */
 +      evt_stream_div = arch_timer_rate / ARCH_TIMER_EVT_STREAM_FREQ;
 +      pos = fls(evt_stream_div);
 +      if (pos > 1 && !(evt_stream_div & (1 << (pos - 2))))
 +              pos--;
 +      /* enable event stream */
 +      arch_timer_evtstrm_enable(min(pos, 15));
 +}
 +
+ static int arch_timer_set_next_event_virt_mem(unsigned long evt,
+                                             struct clock_event_device *clk)
  {
-       clk->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_C3STOP;
-       clk->name = "arch_sys_timer";
-       clk->rating = 450;
-       if (arch_timer_use_virtual) {
-               clk->irq = arch_timer_ppi[VIRT_PPI];
-               clk->set_mode = arch_timer_set_mode_virt;
-               clk->set_next_event = arch_timer_set_next_event_virt;
+       set_next_event(ARCH_TIMER_MEM_VIRT_ACCESS, evt, clk);
+       return 0;
+ }
+ static int arch_timer_set_next_event_phys_mem(unsigned long evt,
+                                             struct clock_event_device *clk)
+ {
+       set_next_event(ARCH_TIMER_MEM_PHYS_ACCESS, evt, clk);
+       return 0;
+ }
+ static void __cpuinit __arch_timer_setup(unsigned type,
+                                      struct clock_event_device *clk)
+ {
+       clk->features = CLOCK_EVT_FEAT_ONESHOT;
+       if (type == ARCH_CP15_TIMER) {
+               clk->features |= CLOCK_EVT_FEAT_C3STOP;
+               clk->name = "arch_sys_timer";
+               clk->rating = 450;
+               clk->cpumask = cpumask_of(smp_processor_id());
+               if (arch_timer_use_virtual) {
+                       clk->irq = arch_timer_ppi[VIRT_PPI];
+                       clk->set_mode = arch_timer_set_mode_virt;
+                       clk->set_next_event = arch_timer_set_next_event_virt;
+               } else {
+                       clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
+                       clk->set_mode = arch_timer_set_mode_phys;
+                       clk->set_next_event = arch_timer_set_next_event_phys;
+               }
        } else {
-               clk->irq = arch_timer_ppi[PHYS_SECURE_PPI];
-               clk->set_mode = arch_timer_set_mode_phys;
-               clk->set_next_event = arch_timer_set_next_event_phys;
+               clk->name = "arch_mem_timer";
+               clk->rating = 400;
+               clk->cpumask = cpu_all_mask;
+               if (arch_timer_mem_use_virtual) {
+                       clk->set_mode = arch_timer_set_mode_virt_mem;
+                       clk->set_next_event =
+                               arch_timer_set_next_event_virt_mem;
+               } else {
+                       clk->set_mode = arch_timer_set_mode_phys_mem;
+                       clk->set_next_event =
+                               arch_timer_set_next_event_phys_mem;
+               }
        }
  
-       clk->cpumask = cpumask_of(smp_processor_id());
+       clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, clk);
  
-       clk->set_mode(CLOCK_EVT_MODE_SHUTDOWN, NULL);
+       clockevents_config_and_register(clk, arch_timer_rate, 0xf, 0x7fffffff);
+ }
  
-       clockevents_config_and_register(clk, arch_timer_rate,
-                                       0xf, 0x7fffffff);
+ static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
+ {
+       __arch_timer_setup(ARCH_CP15_TIMER, clk);
  
        if (arch_timer_use_virtual)
                enable_percpu_irq(arch_timer_ppi[VIRT_PPI], 0);
@@@ -202,14 -352,30 +368,30 @@@ u32 arch_timer_get_rate(void
        return arch_timer_rate;
  }
  
u64 arch_timer_read_counter(void)
static u64 arch_counter_get_cntvct_mem(void)
  {
-       return arch_counter_get_cntvct();
+       u32 vct_lo, vct_hi, tmp_hi;
+       do {
+               vct_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
+               vct_lo = readl_relaxed(arch_counter_base + CNTVCT_LO);
+               tmp_hi = readl_relaxed(arch_counter_base + CNTVCT_HI);
+       } while (vct_hi != tmp_hi);
+       return ((u64) vct_hi << 32) | vct_lo;
  }
  
+ /*
+  * Default to cp15 based access because arm64 uses this function for
+  * sched_clock() before DT is probed and the cp15 method is guaranteed
+  * to exist on arm64. arm doesn't use this before DT is probed so even
+  * if we don't have the cp15 accessors we won't have a problem.
+  */
+ u64 (*arch_timer_read_counter)(void) = arch_counter_get_cntvct;
  static cycle_t arch_counter_read(struct clocksource *cs)
  {
 -      return arch_timer_read_counter();
 +      return arch_counter_get_cntvct();
  }
  
  static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
@@@ -237,6 -403,26 +419,23 @@@ struct timecounter *arch_timer_get_time
        return &timecounter;
  }
  
 -
 -      /* 56 bits minimum, so we assume worst case rollover */
 -      sched_clock_register(arch_timer_read_counter, 56, arch_timer_rate);
+ static void __init arch_counter_register(unsigned type)
+ {
+       u64 start_count;
+       /* Register the CP15 based counter if we have one */
+       if (type & ARCH_CP15_TIMER)
+               arch_timer_read_counter = arch_counter_get_cntvct;
+       else
+               arch_timer_read_counter = arch_counter_get_cntvct_mem;
+       start_count = arch_timer_read_counter();
+       clocksource_register_hz(&clocksource_counter, arch_timer_rate);
+       cyclecounter.mult = clocksource_counter.mult;
+       cyclecounter.shift = clocksource_counter.shift;
+       timecounter_init(&timecounter, &cyclecounter, start_count);
+ }
  static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
  {
        pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
@@@ -417,8 -613,13 +659,8 @@@ static void __init arch_timer_init(stru
                }
        }
  
 -      if (arch_timer_use_virtual)
 -              arch_timer_read_counter = arch_counter_get_cntvct;
 -      else
 -              arch_timer_read_counter = arch_counter_get_cntpct;
 -
        arch_timer_register();
-       arch_timer_arch_init();
+       arch_timer_common_init();
  }
  CLOCKSOURCE_OF_DECLARE(armv7_arch_timer, "arm,armv7-timer", arch_timer_init);
  CLOCKSOURCE_OF_DECLARE(armv8_arch_timer, "arm,armv8-timer", arch_timer_init);
index c4d0fc4855ab0b7ad6cf3213477887f8d5411dce,93b7f96f9c59f354be61ce529f90f8fda305f376..6d26b40cbf5d29c7d80c83a9fe22b4f9e85a0b70
@@@ -28,17 -30,9 +30,19 @@@ enum arch_timer_reg 
  
  #define ARCH_TIMER_PHYS_ACCESS                0
  #define ARCH_TIMER_VIRT_ACCESS                1
+ #define ARCH_TIMER_MEM_PHYS_ACCESS    2
+ #define ARCH_TIMER_MEM_VIRT_ACCESS    3
  
 +#define ARCH_TIMER_USR_PCT_ACCESS_EN  (1 << 0) /* physical counter */
 +#define ARCH_TIMER_USR_VCT_ACCESS_EN  (1 << 1) /* virtual counter */
 +#define ARCH_TIMER_VIRT_EVT_EN                (1 << 2)
 +#define ARCH_TIMER_EVT_TRIGGER_SHIFT  (4)
 +#define ARCH_TIMER_EVT_TRIGGER_MASK   (0xF << ARCH_TIMER_EVT_TRIGGER_SHIFT)
 +#define ARCH_TIMER_USR_VT_ACCESS_EN   (1 << 8) /* virtual timer registers */
 +#define ARCH_TIMER_USR_PT_ACCESS_EN   (1 << 9) /* physical timer registers */
 +
 +#define ARCH_TIMER_EVT_STREAM_FREQ    10000   /* 100us */
 +
  #ifdef CONFIG_ARM_ARCH_TIMER
  
  extern u32 arch_timer_get_rate(void);