imx23timrot_fdt.c revision 1.1 1 1.1 skrll /* $NetBSD: imx23timrot_fdt.c,v 1.1 2025/10/09 06:15:17 skrll Exp $ */
2 1.1 skrll
3 1.1 skrll /*-
4 1.1 skrll * Copyright (c) 2025 The NetBSD Foundation, Inc.
5 1.1 skrll * All rights reserved.
6 1.1 skrll *
7 1.1 skrll * This code is derived from software contributed to The NetBSD Foundation
8 1.1 skrll * by Yuri Honegger.
9 1.1 skrll *
10 1.1 skrll * Redistribution and use in source and binary forms, with or without
11 1.1 skrll * modification, are permitted provided that the following conditions
12 1.1 skrll * are met:
13 1.1 skrll * 1. Redistributions of source code must retain the above copyright
14 1.1 skrll * notice, this list of conditions and the following disclaimer.
15 1.1 skrll * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 skrll * notice, this list of conditions and the following disclaimer in the
17 1.1 skrll * documentation and/or other materials provided with the distribution.
18 1.1 skrll *
19 1.1 skrll * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.1 skrll * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.1 skrll * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.1 skrll * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.1 skrll * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.1 skrll * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.1 skrll * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.1 skrll * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.1 skrll * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.1 skrll * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.1 skrll * POSSIBILITY OF SUCH DAMAGE.
30 1.1 skrll */
31 1.1 skrll
32 1.1 skrll #include <sys/cdefs.h>
33 1.1 skrll __KERNEL_RCSID(0, "$NetBSD: imx23timrot_fdt.c,v 1.1 2025/10/09 06:15:17 skrll Exp $");
34 1.1 skrll
35 1.1 skrll #include <sys/param.h>
36 1.1 skrll
37 1.1 skrll #include <sys/device.h>
38 1.1 skrll
39 1.1 skrll #include <dev/fdt/fdtvar.h>
40 1.1 skrll
41 1.1 skrll #include <arm/imx/imx23var.h>
42 1.1 skrll #include <arm/imx/imx23_timrotvar.h>
43 1.1 skrll #include <arm/fdt/arm_fdtvar.h>
44 1.1 skrll
45 1.1 skrll static int imx23timrot_fdt_match(device_t, cfdata_t, void *);
46 1.1 skrll static void imx23timrot_fdt_attach(device_t, device_t, void *);
47 1.1 skrll
48 1.1 skrll struct imx23timrot_fdt_softc {
49 1.1 skrll struct timrot_softc systimer_sc;
50 1.1 skrll struct timrot_softc stattimer_sc;
51 1.1 skrll };
52 1.1 skrll
53 1.1 skrll CFATTACH_DECL_NEW(imx23timrot_fdt, sizeof(struct imx23timrot_fdt_softc),
54 1.1 skrll imx23timrot_fdt_match, imx23timrot_fdt_attach, NULL, NULL);
55 1.1 skrll
56 1.1 skrll static const struct device_compatible_entry compat_data[] = {
57 1.1 skrll { .compat = "fsl,imx23-timrot" },
58 1.1 skrll { .compat = "fsl,timrot" },
59 1.1 skrll DEVICE_COMPAT_EOL
60 1.1 skrll };
61 1.1 skrll
62 1.1 skrll static int
63 1.1 skrll imx23timrot_fdt_match(device_t parent, cfdata_t cf, void *aux)
64 1.1 skrll {
65 1.1 skrll struct fdt_attach_args * const faa = aux;
66 1.1 skrll
67 1.1 skrll return of_compatible_match(faa->faa_phandle, compat_data);
68 1.1 skrll }
69 1.1 skrll
70 1.1 skrll /*
71 1.1 skrll * The original non-FDT timrot driver instantiates one timrot device per timer.
72 1.1 skrll * Unfortunately, the device tree from linux specifies just one timrot device
73 1.1 skrll * for all timers. This driver therefore attaches "two" timrot devices from one.
74 1.1 skrll */
75 1.1 skrll static void
76 1.1 skrll imx23timrot_fdt_attach(device_t parent, device_t self, void *aux)
77 1.1 skrll {
78 1.1 skrll struct imx23timrot_fdt_softc * const sc = device_private(self);
79 1.1 skrll struct fdt_attach_args * const faa = aux;
80 1.1 skrll const int phandle = faa->faa_phandle;
81 1.1 skrll char intrstr[128];
82 1.1 skrll
83 1.1 skrll /*
84 1.1 skrll * The actual memory mapping is done inside the
85 1.1 skrll * timrot_[sys|stat]timer_init functions.
86 1.1 skrll */
87 1.1 skrll bus_addr_t addr;
88 1.1 skrll bus_size_t size;
89 1.1 skrll if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
90 1.1 skrll aprint_error(": couldn't get register address\n");
91 1.1 skrll return;
92 1.1 skrll }
93 1.1 skrll
94 1.1 skrll /* Use -1 as irq because we establish interrupts ourselves */
95 1.1 skrll imx23timrot_systimer_init(&sc->systimer_sc, faa->faa_bst, -1);
96 1.1 skrll imx23timrot_stattimer_init(&sc->stattimer_sc, faa->faa_bst, -1);
97 1.1 skrll
98 1.1 skrll
99 1.1 skrll /* System Timer Interrupt*/
100 1.1 skrll if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
101 1.1 skrll aprint_error(": failed to decode interrupt\n");
102 1.1 skrll return;
103 1.1 skrll }
104 1.1 skrll void *ih = fdtbus_intr_establish_xname(phandle, 0, IPL_CLOCK, 0,
105 1.1 skrll imx23timrot_systimer_irq, NULL,
106 1.1 skrll device_xname(self));
107 1.1 skrll if (ih == NULL) {
108 1.1 skrll aprint_error_dev(self,
109 1.1 skrll "couldn't install systimer interrupt handler\n");
110 1.1 skrll return;
111 1.1 skrll }
112 1.1 skrll aprint_normal_dev(self, ": systimer on %s", intrstr);
113 1.1 skrll
114 1.1 skrll /* Stat Timer Interrupt*/
115 1.1 skrll if (!fdtbus_intr_str(phandle, 1, intrstr, sizeof(intrstr))) {
116 1.1 skrll aprint_error(": failed to decode interrupt\n");
117 1.1 skrll return;
118 1.1 skrll }
119 1.1 skrll ih = fdtbus_intr_establish_xname(phandle, 1, IPL_CLOCK, 0,
120 1.1 skrll imx23timrot_stattimer_irq, NULL,
121 1.1 skrll device_xname(self));
122 1.1 skrll if (ih == NULL) {
123 1.1 skrll aprint_error_dev(self,
124 1.1 skrll "couldn't install stattimer interrupt handler\n");
125 1.1 skrll return;
126 1.1 skrll }
127 1.1 skrll aprint_normal_dev(self, ": stattimer on %s\n", intrstr);
128 1.1 skrll
129 1.1 skrll aprint_naive("\n");
130 1.1 skrll aprint_normal("\n");
131 1.1 skrll
132 1.1 skrll struct apb_attach_args apbaa = {
133 1.1 skrll .aa_name = "imx23timrot",
134 1.1 skrll .aa_iot = faa->faa_bst,
135 1.1 skrll .aa_dmat = faa->faa_dmat,
136 1.1 skrll .aa_addr = addr,
137 1.1 skrll .aa_size = size,
138 1.1 skrll .aa_irq = -1
139 1.1 skrll };
140 1.1 skrll
141 1.1 skrll config_found(self, &apbaa, NULL, CFARGS_NONE);
142 1.1 skrll
143 1.1 skrll arm_fdt_timer_register(imx23timrot_cpu_initclocks);
144 1.1 skrll }
145