1/*-
2 * Copyright (c) 2011 The FreeBSD Foundation
3 * Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
4 * All rights reserved.
5 *
6 * Based on mpcore_timer.c developed by Ben Gray <ben.r.gray@gmail.com>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. The name of the company nor the name of the author may be used to
17 *    endorse or promote products derived from this software without specific
18 *    prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/**
34 *      Cortex-A7, Cortex-A15, ARMv8 and later Generic Timer
35 */
36
37#include "opt_acpi.h"
38#include "opt_platform.h"
39
40#include <sys/cdefs.h>
41__FBSDID("$FreeBSD: stable/11/sys/arm/arm/generic_timer.c 346561 2019-04-22 15:23:06Z ian $");
42
43#include <sys/param.h>
44#include <sys/systm.h>
45#include <sys/bus.h>
46#include <sys/kernel.h>
47#include <sys/module.h>
48#include <sys/malloc.h>
49#include <sys/rman.h>
50#include <sys/timeet.h>
51#include <sys/timetc.h>
52#include <sys/smp.h>
53#include <sys/vdso.h>
54#include <sys/watchdog.h>
55#include <machine/bus.h>
56#include <machine/cpu.h>
57#include <machine/intr.h>
58#include <machine/md_var.h>
59
60#ifdef MULTIDELAY
61#include <machine/machdep.h> /* For arm_set_delay */
62#endif
63
64#ifdef FDT
65#include <dev/fdt/fdt_common.h>
66#include <dev/ofw/openfirm.h>
67#include <dev/ofw/ofw_bus.h>
68#include <dev/ofw/ofw_bus_subr.h>
69#endif
70
71#ifdef DEV_ACPI
72#include <contrib/dev/acpica/include/acpi.h>
73#include <dev/acpica/acpivar.h>
74#endif
75
76#define	GT_CTRL_ENABLE		(1 << 0)
77#define	GT_CTRL_INT_MASK	(1 << 1)
78#define	GT_CTRL_INT_STAT	(1 << 2)
79#define	GT_REG_CTRL		0
80#define	GT_REG_TVAL		1
81
82#define	GT_CNTKCTL_PL0PTEN	(1 << 9) /* PL0 Physical timer reg access */
83#define	GT_CNTKCTL_PL0VTEN	(1 << 8) /* PL0 Virtual timer reg access */
84#define	GT_CNTKCTL_EVNTI	(0xf << 4) /* Virtual counter event bits */
85#define	GT_CNTKCTL_EVNTDIR	(1 << 3) /* Virtual counter event transition */
86#define	GT_CNTKCTL_EVNTEN	(1 << 2) /* Enables virtual counter events */
87#define	GT_CNTKCTL_PL0VCTEN	(1 << 1) /* PL0 CNTVCT and CNTFRQ access */
88#define	GT_CNTKCTL_PL0PCTEN	(1 << 0) /* PL0 CNTPCT and CNTFRQ access */
89
90struct arm_tmr_softc {
91	struct resource		*res[4];
92	void			*ihl[4];
93	uint32_t		clkfreq;
94	struct eventtimer	et;
95	bool			physical;
96};
97
98static struct arm_tmr_softc *arm_tmr_sc = NULL;
99
100static struct resource_spec timer_spec[] = {
101	{ SYS_RES_IRQ,		0,	RF_ACTIVE },	/* Secure */
102	{ SYS_RES_IRQ,		1,	RF_ACTIVE },	/* Non-secure */
103	{ SYS_RES_IRQ,		2,	RF_ACTIVE | RF_OPTIONAL }, /* Virt */
104	{ SYS_RES_IRQ,		3,	RF_ACTIVE | RF_OPTIONAL	}, /* Hyp */
105	{ -1, 0 }
106};
107
108static uint32_t arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th,
109    struct timecounter *tc);
110static void arm_tmr_do_delay(int usec, void *);
111
112static timecounter_get_t arm_tmr_get_timecount;
113
114static struct timecounter arm_tmr_timecount = {
115	.tc_name           = "ARM MPCore Timecounter",
116	.tc_get_timecount  = arm_tmr_get_timecount,
117	.tc_poll_pps       = NULL,
118	.tc_counter_mask   = ~0u,
119	.tc_frequency      = 0,
120	.tc_quality        = 1000,
121	.tc_fill_vdso_timehands = arm_tmr_fill_vdso_timehands,
122};
123
124#ifdef __arm__
125#define	get_el0(x)	cp15_## x ##_get()
126#define	get_el1(x)	cp15_## x ##_get()
127#define	set_el0(x, val)	cp15_## x ##_set(val)
128#define	set_el1(x, val)	cp15_## x ##_set(val)
129#else /* __aarch64__ */
130#define	get_el0(x)	READ_SPECIALREG(x ##_el0)
131#define	get_el1(x)	READ_SPECIALREG(x ##_el1)
132#define	set_el0(x, val)	WRITE_SPECIALREG(x ##_el0, val)
133#define	set_el1(x, val)	WRITE_SPECIALREG(x ##_el1, val)
134#endif
135
136static int
137get_freq(void)
138{
139	return (get_el0(cntfrq));
140}
141
142static long
143get_cntxct(bool physical)
144{
145	uint64_t val;
146
147	isb();
148	if (physical)
149		val = get_el0(cntpct);
150	else
151		val = get_el0(cntvct);
152
153	return (val);
154}
155
156static int
157set_ctrl(uint32_t val, bool physical)
158{
159
160	if (physical)
161		set_el0(cntp_ctl, val);
162	else
163		set_el0(cntv_ctl, val);
164	isb();
165
166	return (0);
167}
168
169static int
170set_tval(uint32_t val, bool physical)
171{
172
173	if (physical)
174		set_el0(cntp_tval, val);
175	else
176		set_el0(cntv_tval, val);
177	isb();
178
179	return (0);
180}
181
182static int
183get_ctrl(bool physical)
184{
185	uint32_t val;
186
187	if (physical)
188		val = get_el0(cntp_ctl);
189	else
190		val = get_el0(cntv_ctl);
191
192	return (val);
193}
194
195static void
196setup_user_access(void *arg __unused)
197{
198	uint32_t cntkctl;
199
200	cntkctl = get_el1(cntkctl);
201	cntkctl &= ~(GT_CNTKCTL_PL0PTEN | GT_CNTKCTL_PL0VTEN |
202	    GT_CNTKCTL_EVNTEN);
203	if (arm_tmr_sc->physical) {
204		cntkctl |= GT_CNTKCTL_PL0PCTEN;
205		cntkctl &= ~GT_CNTKCTL_PL0VCTEN;
206	} else {
207		cntkctl |= GT_CNTKCTL_PL0VCTEN;
208		cntkctl &= ~GT_CNTKCTL_PL0PCTEN;
209	}
210	set_el1(cntkctl, cntkctl);
211	isb();
212}
213
214static void
215tmr_setup_user_access(void *arg __unused)
216{
217
218	if (arm_tmr_sc != NULL)
219		smp_rendezvous(NULL, setup_user_access, NULL, NULL);
220}
221SYSINIT(tmr_ua, SI_SUB_SMP, SI_ORDER_SECOND, tmr_setup_user_access, NULL);
222
223static unsigned
224arm_tmr_get_timecount(struct timecounter *tc)
225{
226
227	return (get_cntxct(arm_tmr_sc->physical));
228}
229
230static int
231arm_tmr_start(struct eventtimer *et, sbintime_t first,
232    sbintime_t period __unused)
233{
234	struct arm_tmr_softc *sc;
235	int counts, ctrl;
236
237	sc = (struct arm_tmr_softc *)et->et_priv;
238
239	if (first != 0) {
240		counts = ((uint32_t)et->et_frequency * first) >> 32;
241		ctrl = get_ctrl(sc->physical);
242		ctrl &= ~GT_CTRL_INT_MASK;
243		ctrl |= GT_CTRL_ENABLE;
244		set_tval(counts, sc->physical);
245		set_ctrl(ctrl, sc->physical);
246		return (0);
247	}
248
249	return (EINVAL);
250
251}
252
253static int
254arm_tmr_stop(struct eventtimer *et)
255{
256	struct arm_tmr_softc *sc;
257	int ctrl;
258
259	sc = (struct arm_tmr_softc *)et->et_priv;
260
261	ctrl = get_ctrl(sc->physical);
262	ctrl &= ~GT_CTRL_ENABLE;
263	set_ctrl(ctrl, sc->physical);
264
265	return (0);
266}
267
268static int
269arm_tmr_intr(void *arg)
270{
271	struct arm_tmr_softc *sc;
272	int ctrl;
273
274	sc = (struct arm_tmr_softc *)arg;
275	ctrl = get_ctrl(sc->physical);
276	if (ctrl & GT_CTRL_INT_STAT) {
277		ctrl |= GT_CTRL_INT_MASK;
278		set_ctrl(ctrl, sc->physical);
279	}
280
281	if (sc->et.et_active)
282		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
283
284	return (FILTER_HANDLED);
285}
286
287#ifdef FDT
288static int
289arm_tmr_fdt_probe(device_t dev)
290{
291
292	if (!ofw_bus_status_okay(dev))
293		return (ENXIO);
294
295	if (ofw_bus_is_compatible(dev, "arm,armv7-timer")) {
296		device_set_desc(dev, "ARMv7 Generic Timer");
297		return (BUS_PROBE_DEFAULT);
298	} else if (ofw_bus_is_compatible(dev, "arm,armv8-timer")) {
299		device_set_desc(dev, "ARMv8 Generic Timer");
300		return (BUS_PROBE_DEFAULT);
301	}
302
303	return (ENXIO);
304}
305#endif
306
307#ifdef DEV_ACPI
308static void
309arm_tmr_acpi_identify(driver_t *driver, device_t parent)
310{
311	ACPI_TABLE_GTDT *gtdt;
312	vm_paddr_t physaddr;
313	device_t dev;
314
315	physaddr = acpi_find_table(ACPI_SIG_GTDT);
316	if (physaddr == 0)
317		return;
318
319	gtdt = acpi_map_table(physaddr, ACPI_SIG_GTDT);
320	if (gtdt == NULL) {
321		device_printf(parent, "gic: Unable to map the GTDT\n");
322		return;
323	}
324
325	dev = BUS_ADD_CHILD(parent, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE,
326	    "generic_timer", -1);
327	if (dev == NULL) {
328		device_printf(parent, "add gic child failed\n");
329		goto out;
330	}
331
332	BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0,
333	    gtdt->SecureEl1Interrupt, 1);
334	BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 1,
335	    gtdt->NonSecureEl1Interrupt, 1);
336	BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 2,
337	    gtdt->VirtualTimerInterrupt, 1);
338
339out:
340	acpi_unmap_table(gtdt);
341}
342
343static int
344arm_tmr_acpi_probe(device_t dev)
345{
346
347	device_set_desc(dev, "ARM Generic Timer");
348	return (BUS_PROBE_NOWILDCARD);
349}
350#endif
351
352
353static int
354arm_tmr_attach(device_t dev)
355{
356	struct arm_tmr_softc *sc;
357#ifdef FDT
358	phandle_t node;
359	pcell_t clock;
360#endif
361	int error;
362	int i, first_timer, last_timer;
363
364	sc = device_get_softc(dev);
365	if (arm_tmr_sc)
366		return (ENXIO);
367
368#ifdef FDT
369	/* Get the base clock frequency */
370	node = ofw_bus_get_node(dev);
371	if (node > 0) {
372		error = OF_getencprop(node, "clock-frequency", &clock,
373		    sizeof(clock));
374		if (error > 0)
375			sc->clkfreq = clock;
376	}
377#endif
378
379	if (sc->clkfreq == 0) {
380		/* Try to get clock frequency from timer */
381		sc->clkfreq = get_freq();
382	}
383
384	if (sc->clkfreq == 0) {
385		device_printf(dev, "No clock frequency specified\n");
386		return (ENXIO);
387	}
388
389	if (bus_alloc_resources(dev, timer_spec, sc->res)) {
390		device_printf(dev, "could not allocate resources\n");
391		return (ENXIO);
392	}
393
394#ifdef __aarch64__
395	/* Use the virtual timer if we have one. */
396	if (sc->res[2] != NULL) {
397		sc->physical = false;
398		first_timer = 2;
399		last_timer = 2;
400	} else
401#endif
402	/* Otherwise set up the secure and non-secure physical timers. */
403	{
404		sc->physical = true;
405		first_timer = 0;
406		last_timer = 1;
407	}
408
409	arm_tmr_sc = sc;
410
411	/* Setup secure, non-secure and virtual IRQs handler */
412	for (i = first_timer; i <= last_timer; i++) {
413		/* If we do not have the interrupt, skip it. */
414		if (sc->res[i] == NULL)
415			continue;
416		error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
417		    arm_tmr_intr, NULL, sc, &sc->ihl[i]);
418		if (error) {
419			device_printf(dev, "Unable to alloc int resource.\n");
420			return (ENXIO);
421		}
422	}
423
424	arm_tmr_timecount.tc_frequency = sc->clkfreq;
425	tc_init(&arm_tmr_timecount);
426
427	sc->et.et_name = "ARM MPCore Eventtimer";
428	sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERCPU;
429	sc->et.et_quality = 1000;
430
431	sc->et.et_frequency = sc->clkfreq;
432	sc->et.et_min_period = (0x00000010LLU << 32) / sc->et.et_frequency;
433	sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
434	sc->et.et_start = arm_tmr_start;
435	sc->et.et_stop = arm_tmr_stop;
436	sc->et.et_priv = sc;
437	et_register(&sc->et);
438
439#ifdef MULTIDELAY
440	arm_set_delay(arm_tmr_do_delay, sc);
441#endif
442
443	return (0);
444}
445
446#ifdef FDT
447static device_method_t arm_tmr_fdt_methods[] = {
448	DEVMETHOD(device_probe,		arm_tmr_fdt_probe),
449	DEVMETHOD(device_attach,	arm_tmr_attach),
450	{ 0, 0 }
451};
452
453static driver_t arm_tmr_fdt_driver = {
454	"generic_timer",
455	arm_tmr_fdt_methods,
456	sizeof(struct arm_tmr_softc),
457};
458
459static devclass_t arm_tmr_fdt_devclass;
460
461EARLY_DRIVER_MODULE(timer, simplebus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
462    0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
463EARLY_DRIVER_MODULE(timer, ofwbus, arm_tmr_fdt_driver, arm_tmr_fdt_devclass,
464    0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
465#endif
466
467#ifdef DEV_ACPI
468static device_method_t arm_tmr_acpi_methods[] = {
469	DEVMETHOD(device_identify,	arm_tmr_acpi_identify),
470	DEVMETHOD(device_probe,		arm_tmr_acpi_probe),
471	DEVMETHOD(device_attach,	arm_tmr_attach),
472	{ 0, 0 }
473};
474
475static driver_t arm_tmr_acpi_driver = {
476	"generic_timer",
477	arm_tmr_acpi_methods,
478	sizeof(struct arm_tmr_softc),
479};
480
481static devclass_t arm_tmr_acpi_devclass;
482
483EARLY_DRIVER_MODULE(timer, acpi, arm_tmr_acpi_driver, arm_tmr_acpi_devclass,
484    0, 0, BUS_PASS_TIMER + BUS_PASS_ORDER_MIDDLE);
485#endif
486
487static void
488arm_tmr_do_delay(int usec, void *arg)
489{
490	struct arm_tmr_softc *sc = arg;
491	int32_t counts, counts_per_usec;
492	uint32_t first, last;
493
494	/* Get the number of times to count */
495	counts_per_usec = ((arm_tmr_timecount.tc_frequency / 1000000) + 1);
496
497	/*
498	 * Clamp the timeout at a maximum value (about 32 seconds with
499	 * a 66MHz clock). *Nobody* should be delay()ing for anywhere
500	 * near that length of time and if they are, they should be hung
501	 * out to dry.
502	 */
503	if (usec >= (0x80000000U / counts_per_usec))
504		counts = (0x80000000U / counts_per_usec) - 1;
505	else
506		counts = usec * counts_per_usec;
507
508	first = get_cntxct(sc->physical);
509
510	while (counts > 0) {
511		last = get_cntxct(sc->physical);
512		counts -= (int32_t)(last - first);
513		first = last;
514	}
515}
516
517#ifndef MULTIDELAY
518void
519DELAY(int usec)
520{
521	int32_t counts;
522
523	/*
524	 * Check the timers are setup, if not just
525	 * use a for loop for the meantime
526	 */
527	if (arm_tmr_sc == NULL) {
528		for (; usec > 0; usec--)
529			for (counts = 200; counts > 0; counts--)
530				/*
531				 * Prevent the compiler from optimizing
532				 * out the loop
533				 */
534				cpufunc_nullop();
535	} else
536		arm_tmr_do_delay(usec, arm_tmr_sc);
537}
538#endif
539
540static uint32_t
541arm_tmr_fill_vdso_timehands(struct vdso_timehands *vdso_th,
542    struct timecounter *tc)
543{
544
545	vdso_th->th_algo = VDSO_TH_ALGO_ARM_GENTIM;
546	vdso_th->th_physical = arm_tmr_sc->physical;
547	bzero(vdso_th->th_res, sizeof(vdso_th->th_res));
548	return (1);
549}
550