|
@@ -272,3 +272,79 @@ static int arch_timer_available(void)
|
|
|
|
|
|
if (!local_timer_is_architected())
|
|
if (!local_timer_is_architected())
|
|
return -ENXIO;
|
|
return -ENXIO;
|
|
|
|
+
|
|
|
|
+ if (arch_timer_rate == 0) {
|
|
|
|
+ freq = arch_timer_reg_read(ARCH_TIMER_PHYS_ACCESS,
|
|
|
|
+ ARCH_TIMER_REG_FREQ);
|
|
|
|
+
|
|
|
|
+ /* Check the timer frequency. */
|
|
|
|
+ if (freq == 0) {
|
|
|
|
+ pr_warn("Architected timer frequency not available\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ arch_timer_rate = freq;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pr_info_once("Architected local timer running at %lu.%02luMHz (%s).\n",
|
|
|
|
+ arch_timer_rate / 1000000, (arch_timer_rate / 10000) % 100,
|
|
|
|
+ arch_timer_use_virtual ? "virt" : "phys");
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static u32 notrace arch_counter_get_cntpct32(void)
|
|
|
|
+{
|
|
|
|
+ cycle_t cnt = arch_counter_get_cntpct();
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The sched_clock infrastructure only knows about counters
|
|
|
|
+ * with at most 32bits. Forget about the upper 24 bits for the
|
|
|
|
+ * time being...
|
|
|
|
+ */
|
|
|
|
+ return (u32)cnt;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static u32 notrace arch_counter_get_cntvct32(void)
|
|
|
|
+{
|
|
|
|
+ cycle_t cnt = arch_counter_get_cntvct();
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * The sched_clock infrastructure only knows about counters
|
|
|
|
+ * with at most 32bits. Forget about the upper 24 bits for the
|
|
|
|
+ * time being...
|
|
|
|
+ */
|
|
|
|
+ return (u32)cnt;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static cycle_t arch_counter_read(struct clocksource *cs)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * Always use the physical counter for the clocksource.
|
|
|
|
+ * CNTHCTL.PL1PCTEN must be set to 1.
|
|
|
|
+ */
|
|
|
|
+ return arch_counter_get_cntpct();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static unsigned long arch_timer_read_current_timer(void)
|
|
|
|
+{
|
|
|
|
+ return arch_counter_get_cntpct();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
|
|
|
|
+{
|
|
|
|
+ /*
|
|
|
|
+ * Always use the physical counter for the clocksource.
|
|
|
|
+ * CNTHCTL.PL1PCTEN must be set to 1.
|
|
|
|
+ */
|
|
|
|
+ return arch_counter_get_cntpct();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static struct clocksource clocksource_counter = {
|
|
|
|
+ .name = "arch_sys_counter",
|
|
|
|
+ .rating = 400,
|
|
|
|
+ .read = arch_counter_read,
|
|
|
|
+ .mask = CLOCKSOURCE_MASK(56),
|
|
|
|
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+static struct cyclecounter cyclecounter = {
|