1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3 *
4 * Copyright (c) 2022 Semihalf.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/bus.h>
33 #include <sys/rman.h>
34 #include <sys/kernel.h>
35 #include <sys/lock.h>
36 #include <sys/module.h>
37 #include <sys/mutex.h>
38
39 #include <machine/bus.h>
40
41 #include <dev/fdt/simplebus.h>
42 #include <dev/ofw/ofw_bus.h>
43 #include <dev/ofw/ofw_bus_subr.h>
44 #include <dev/extres/clk/clk.h>
45 #include <dev/extres/clk/clk_gate.h>
46
47 #include "clkdev_if.h"
48
49 struct armada38x_gateclk_softc
50 {
51 struct clkdom *clkdom;
52 struct mtx mtx;
53 const char* parent;
54 };
55
56 static struct clk_gate_def gateclk_nodes[] =
57 {
58 {
59 .clkdef = {
60 .name = "gateclk-audio",
61 .id = 0,
62 .parent_cnt = 1,
63 .flags = 0,
64 },
65 .shift = 0,
66 },
67 {
68 .clkdef = {
69 .name = "gateclk-eth2",
70 .id = 2,
71 .parent_cnt = 1,
72 .flags = 0,
73 },
74 .shift = 2,
75 },
76 {
77 .clkdef = {
78 .name = "gateclk-eth1",
79 .id = 3,
80 .parent_cnt = 1,
81 .flags = 0,
82 },
83 .shift = 3,
84 },
85 {
86 .clkdef = {
87 .name = "gateclk-eth0",
88 .id = 4,
89 .parent_cnt = 1,
90 .flags = 0,
91 },
92 .shift = 4,
93 },
94 {
95 .clkdef = {
96 .name = "gateclk-mdio",
97 .id = 4,
98 .parent_cnt = 1,
99 .flags = 0,
100 },
101 .shift = 4,
102 },
103 {
104 .clkdef = {
105 .name = "gateclk-usb3h0",
106 .id = 9,
107 .parent_cnt = 1,
108 .flags = 0,
109 },
110 .shift = 9,
111 },
112 {
113 .clkdef = {
114 .name = "gateclk-usb3h1",
115 .id = 10,
116 .parent_cnt = 1,
117 .flags = 0,
118 },
119 .shift = 10,
120 },
121 {
122 .clkdef = {
123 .name = "gateclk-bm",
124 .id = 13,
125 .parent_cnt = 1,
126 .flags = 0,
127 },
128 .shift = 13,
129 },
130 {
131 .clkdef = {
132 .name = "gateclk-crypto0z",
133 .id = 14,
134 .parent_cnt = 1,
135 .flags = 0,
136 },
137 .shift = 14,
138 },
139 {
140 .clkdef = {
141 .name = "gateclk-sata0",
142 .id = 15,
143 .parent_cnt = 1,
144 .flags = 0,
145 },
146 .shift = 15,
147 },
148 {
149 .clkdef = {
150 .name = "gateclk-crypto1z",
151 .id = 16,
152 .parent_cnt = 1,
153 .flags = 0,
154 },
155 .shift = 16,
156 },
157 {
158 .clkdef = {
159 .name = "gateclk-sdio",
160 .id = 17,
161 .parent_cnt = 1,
162 .flags = 0,
163 },
164 .shift = 17,
165 },
166 {
167 .clkdef = {
168 .name = "gateclk-usb2",
169 .id = 18,
170 .parent_cnt = 1,
171 .flags = 0,
172 },
173 .shift = 18,
174 },
175 {
176 .clkdef = {
177 .name = "gateclk-crypto1",
178 .id = 21,
179 .parent_cnt = 1,
180 .flags = 0,
181 },
182 .shift = 21,
183 },
184 {
185 .clkdef = {
186 .name = "gateclk-xor0",
187 .id = 22,
188 .parent_cnt = 1,
189 .flags = 0,
190 },
191 .shift = 22,
192 },
193 {
194 .clkdef = {
195 .name = "gateclk-crypto0",
196 .id = 23,
197 .parent_cnt = 1,
198 .flags = 0,
199 },
200 .shift = 23,
201 },
202 {
203 .clkdef = {
204 .name = "gateclk-xor1",
205 .id = 28,
206 .parent_cnt = 1,
207 .flags = 0,
208 },
209 .shift = 28,
210 },
211 {
212 .clkdef = {
213 .name = "gateclk-sata1",
214 .id = 30,
215 .parent_cnt = 1,
216 .flags = 0,
217 },
218 .shift = 30,
219 }
220 };
221
222 static int armada38x_gateclk_probe(device_t dev);
223 static int armada38x_gateclk_attach(device_t dev);
224
225 static device_method_t armada38x_gateclk_methods[] = {
226 DEVMETHOD(device_probe, armada38x_gateclk_probe),
227 DEVMETHOD(device_attach, armada38x_gateclk_attach),
228
229 DEVMETHOD_END
230 };
231
232 static driver_t armada38x_gateclk_driver = {
233 "armada38x_gateclk",
234 armada38x_gateclk_methods,
235 sizeof(struct armada38x_gateclk_softc),
236 };
237
238 EARLY_DRIVER_MODULE(armada38x_gateclk, simplebus, armada38x_gateclk_driver, 0, 0,
239 BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE + 1);
240
241 static int
242 armada38x_gateclk_probe(device_t dev)
243 {
244
245 if (!ofw_bus_status_okay(dev))
246 return (ENXIO);
247
248 if(!ofw_bus_is_compatible(dev, "marvell,armada-380-gating-clock"))
249 return (ENXIO);
250
251 device_set_desc(dev, "ARMADA38X gateclk");
252
253 return (BUS_PROBE_DEFAULT);
254 }
255
256 static int
257 armada38x_gateclk_attach(device_t dev)
258 {
259 struct armada38x_gateclk_softc *sc;
260 phandle_t node;
261 int i, error;
262 clk_t clock;
263
264 sc = device_get_softc(dev);
265 node = ofw_bus_get_node(dev);
266
267 mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
268
269 sc->clkdom = clkdom_create(dev);
270 if (sc->clkdom == NULL) {
271 device_printf(dev, "Cannot create clock domain.\n");
272 return (ENXIO);
273 }
274
275 error = clk_get_by_ofw_index(dev, node, 0, &clock);
276 if (error > 0)
277 return (error);
278
279 sc->parent = clk_get_name(clock);
280
281 for (i = 0; i < nitems(gateclk_nodes); ++i) {
282 gateclk_nodes[i].clkdef.parent_names = &sc->parent;
283 error = clknode_gate_register(sc->clkdom, &gateclk_nodes[i]);
284 if (error != 0) {
285 device_printf(dev, "Cannot create gate nodes\n");
286 return (error);
287 }
288 }
289
290 if (clkdom_finit(sc->clkdom) != 0)
291 panic("Cannot finalize clock domain initialization.\n");
292
293 return (0);
294 }
Cache object: 4fffa419b7610f20cdec3b509c295ce6
|