Skip to content

Commit 984e62d

Browse files
committed
evbarm/am18: add timer
1 parent 861e1b8 commit 984e62d

3 files changed

Lines changed: 161 additions & 0 deletions

File tree

sys/arch/arm/ti/am18_timer.c

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/* $NetBSD $ */
2+
3+
/*-
4+
* Copyright (c) 2025 The NetBSD Foundation, Inc.
5+
* All rights reserved.
6+
*
7+
* This code is derived from software contributed to The NetBSD Foundation
8+
* by Yuri Honegger.
9+
*
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions
12+
* are met:
13+
* 1. Redistributions of source code must retain the above copyright
14+
* notice, this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright
16+
* notice, this list of conditions and the following disclaimer in the
17+
* documentation and/or other materials provided with the distribution.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20+
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
/*
33+
* Timer Interrupts for the TI AM18XX SOC
34+
*/
35+
36+
#include <sys/param.h>
37+
#include <sys/cdefs.h>
38+
#include <sys/device.h>
39+
40+
#include <dev/fdt/fdtvar.h>
41+
42+
#include <arm/fdt/arm_fdtvar.h>
43+
44+
struct am18_timer_softc {
45+
bus_space_tag_t sc_bst;
46+
bus_space_handle_t sc_bsh;
47+
};
48+
49+
static int am18_timer_match(device_t, cfdata_t, void *);
50+
static void am18_timer_attach(device_t, device_t, void *);
51+
static void am18_timer_cpu_initclocks(void);
52+
static int am18_timer_irq(void *);
53+
54+
static struct am18_timer_softc *timer_sc;
55+
56+
CFATTACH_DECL_NEW(am18timer, sizeof(struct am18_timer_softc),
57+
am18_timer_match, am18_timer_attach, NULL, NULL);
58+
59+
#define AM18_TIMER_TIM12 0x10
60+
#define AM18_TIMER_TIM34 0x14
61+
#define AM18_TIMER_PRD12 0x18
62+
#define AM18_TIMER_PRD34 0x1C
63+
#define AM18_TIMER_TCR 0x20
64+
#define AM18_TIMER_TGCR 0x24
65+
66+
#define AM18_TIMER_TCR_ENAMODE12_CONTINUOUS 0x80
67+
#define AM18_TIMER_TGCR_TIMMODE32_UNCHAINED 0x4
68+
#define AM18_TIMER_TGCR_TIM12EN 0x1
69+
70+
#define TIMER_READ(sc, reg) \
71+
bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, reg)
72+
#define TIMER_WRITE(sc, reg, val) \
73+
bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, reg, val)
74+
75+
static const struct device_compatible_entry compat_data[] = {
76+
{ .compat = "ti,da830-timer" },
77+
DEVICE_COMPAT_EOL
78+
};
79+
80+
static void
81+
am18_timer_cpu_initclocks(void)
82+
{
83+
struct am18_timer_softc *sc = timer_sc;
84+
uint32_t timer_interval = 24000000/hz;
85+
86+
/* disable counter to allow changing mode */
87+
TIMER_WRITE(sc, AM18_TIMER_TCR, 0);
88+
/* set mode to 32-bit unchained */
89+
TIMER_WRITE(sc, AM18_TIMER_TGCR, AM18_TIMER_TGCR_TIMMODE32_UNCHAINED |
90+
AM18_TIMER_TGCR_TIM12EN);
91+
/* start counting from zero */
92+
TIMER_WRITE(sc, AM18_TIMER_TIM12, 0);
93+
TIMER_WRITE(sc, AM18_TIMER_TIM34, 0);
94+
/* load period registers with maximum period */
95+
TIMER_WRITE(sc, AM18_TIMER_PRD12, timer_interval);
96+
TIMER_WRITE(sc, AM18_TIMER_PRD34, 0);
97+
/* enable timer */
98+
TIMER_WRITE(sc, AM18_TIMER_TCR, AM18_TIMER_TCR_ENAMODE12_CONTINUOUS);
99+
}
100+
101+
int
102+
am18_timer_irq(void *frame)
103+
{
104+
hardclock(frame);
105+
106+
return 1;
107+
}
108+
109+
int
110+
am18_timer_match(device_t parent, cfdata_t cf, void *aux)
111+
{
112+
struct fdt_attach_args * const faa = aux;
113+
114+
return of_compatible_match(faa->faa_phandle, compat_data);
115+
}
116+
117+
void
118+
am18_timer_attach(device_t parent, device_t self, void *aux)
119+
{
120+
struct am18_timer_softc * const sc = device_private(self);
121+
struct fdt_attach_args * const faa = aux;
122+
const int phandle = faa->faa_phandle;
123+
bus_addr_t addr;
124+
bus_size_t size;
125+
char intrstr[128];
126+
127+
sc->sc_bst = faa->faa_bst;
128+
timer_sc = sc;
129+
130+
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
131+
aprint_error(": couldn't get registers\n");
132+
return;
133+
}
134+
if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
135+
aprint_error(": couldn't map registers\n");
136+
return;
137+
}
138+
139+
/* establish interrupt */
140+
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
141+
aprint_error(": failed to decode interrupt\n");
142+
return;
143+
}
144+
void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_CLOCK, 0,
145+
am18_timer_irq, NULL,
146+
device_xname(self));
147+
if (ih == NULL) {
148+
aprint_error_dev(self, "couldn't install timer interrupt\n");
149+
return;
150+
}
151+
152+
arm_fdt_timer_register(am18_timer_cpu_initclocks);
153+
154+
aprint_normal(": timer on %s\n", intrstr);
155+
}
156+

sys/arch/arm/ti/files.ti

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ device omaptimer
8080
attach omaptimer at fdt
8181
file arch/arm/ti/ti_omaptimer.c omaptimer
8282

83+
device am18timer
84+
attach am18timer at fdt
85+
file arch/arm/ti/am18_timer.c am18timer
86+
8387
# GPIO
8488
device tigpio: fdt_gpio, gpiobus
8589
attach tigpio at fdt with ti_gpio

sys/arch/evbarm/conf/GENERIC_V5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ am18intc* at fdt? pass 1 # am18 interrupt controller
6565

6666
# Timers
6767
imx23timrot* at fdt? pass 2 # imx23 timer
68+
am18timer* at fdt? pass 2 # am18 timer
6869

6970
# DMA controller
7071
imx23apbdma* at fdt? pass 1 # NXP i.MX23 DMA controller

0 commit comments

Comments
 (0)