- Setup both secure and non-secure timer IRQs.
We don't know our ARM security state, so one of them will operate. - Don't set frequency, since it's unpossible in non-secure state. Only rely on DTS clock-frequency value or get clock from timer. Discussed with: ian, cognet
This commit is contained in:
parent
3651faa511
commit
12899ea195
@ -73,16 +73,23 @@ __FBSDID("$FreeBSD$");
|
||||
#define GT_CNTKCTL_PL0VCTEN (1 << 1) /* PL0 CNTVCT and CNTFRQ access */
|
||||
#define GT_CNTKCTL_PL0PCTEN (1 << 0) /* PL0 CNTPCT and CNTFRQ access */
|
||||
|
||||
#define GT_CNTPSIRQ 29
|
||||
|
||||
struct arm_tmr_softc {
|
||||
struct resource *irq_res;
|
||||
struct resource *res[4];
|
||||
void *ihl[4];
|
||||
uint32_t clkfreq;
|
||||
struct eventtimer et;
|
||||
};
|
||||
|
||||
static struct arm_tmr_softc *arm_tmr_sc = NULL;
|
||||
|
||||
static struct resource_spec timer_spec[] = {
|
||||
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* Secure */
|
||||
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* Non-secure */
|
||||
{ SYS_RES_IRQ, 2, RF_ACTIVE }, /* Virt */
|
||||
{ SYS_RES_IRQ, 3, RF_ACTIVE }, /* Hyp */
|
||||
{ -1, 0 }
|
||||
};
|
||||
|
||||
static timecounter_get_t arm_tmr_get_timecount;
|
||||
|
||||
static struct timecounter arm_tmr_timecount = {
|
||||
@ -261,9 +268,8 @@ arm_tmr_attach(device_t dev)
|
||||
struct arm_tmr_softc *sc;
|
||||
phandle_t node;
|
||||
pcell_t clock;
|
||||
void *ihl;
|
||||
int rid;
|
||||
int error;
|
||||
int i;
|
||||
|
||||
sc = device_get_softc(dev);
|
||||
if (arm_tmr_sc)
|
||||
@ -272,29 +278,37 @@ arm_tmr_attach(device_t dev)
|
||||
/* Get the base clock frequency */
|
||||
node = ofw_bus_get_node(dev);
|
||||
error = OF_getprop(node, "clock-frequency", &clock, sizeof(clock));
|
||||
if (error <= 0) {
|
||||
device_printf(dev, "missing clock-frequency "
|
||||
"attribute in FDT\n");
|
||||
if (error > 0) {
|
||||
sc->clkfreq = fdt32_to_cpu(clock);
|
||||
}
|
||||
|
||||
if (sc->clkfreq == 0) {
|
||||
/* Try to get clock frequency from timer */
|
||||
sc->clkfreq = get_freq();
|
||||
}
|
||||
|
||||
if (sc->clkfreq == 0) {
|
||||
device_printf(dev, "No clock frequency specified\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
sc->clkfreq = fdt32_to_cpu(clock);
|
||||
|
||||
rid = 0;
|
||||
sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid,
|
||||
GT_CNTPSIRQ, GT_CNTPSIRQ,
|
||||
1, RF_SHAREABLE | RF_ACTIVE);
|
||||
if (bus_alloc_resources(dev, timer_spec, sc->res)) {
|
||||
device_printf(dev, "could not allocate resources\n");
|
||||
return (ENXIO);
|
||||
};
|
||||
|
||||
arm_tmr_sc = sc;
|
||||
|
||||
/* Setup and enable the timer */
|
||||
if (bus_setup_intr(dev, sc->irq_res, INTR_TYPE_CLK, arm_tmr_intr,
|
||||
NULL, sc, &ihl) != 0) {
|
||||
bus_release_resource(dev, SYS_RES_IRQ, rid, sc->irq_res);
|
||||
device_printf(dev, "Unable to setup the CLK irq handler.\n");
|
||||
return (ENXIO);
|
||||
/* Setup secure and non-secure IRQs handler */
|
||||
for (i = 0; i < 2; i++) {
|
||||
error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
|
||||
arm_tmr_intr, NULL, sc, &sc->ihl[i]);
|
||||
if (error) {
|
||||
device_printf(dev, "Unable to alloc int resource.\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
}
|
||||
|
||||
set_freq(sc->clkfreq);
|
||||
disable_user_access();
|
||||
|
||||
arm_tmr_timecount.tc_frequency = sc->clkfreq;
|
||||
|
@ -81,6 +81,8 @@
|
||||
generic_timer {
|
||||
compatible = "arm,armv7-timer";
|
||||
clock-frequency = <24000000>;
|
||||
interrupts = < 29 30 27 26 >;
|
||||
interrupt-parent = <&GIC>;
|
||||
};
|
||||
|
||||
pwm {
|
||||
|
Loading…
x
Reference in New Issue
Block a user