Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/mv/clk/armada38x_coreclk.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
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/param.h>
28
#include <sys/bus.h>
29
#include <sys/kernel.h>
30
#include <sys/module.h>
31
#include <sys/mutex.h>
32
#include <sys/rman.h>
33
34
#include <machine/bus.h>
35
#include <machine/fdt.h>
36
37
#include <dev/fdt/simplebus.h>
38
#include <dev/ofw/ofw_bus.h>
39
#include <dev/ofw/ofw_bus_subr.h>
40
#include <dev/clk/clk.h>
41
42
#include <arm/mv/mvwin.h>
43
#include <arm/mv/mvreg.h>
44
#include <arm/mv/mvvar.h>
45
46
#include <arm/mv/clk/armada38x_gen.h>
47
48
#include "clkdev_if.h"
49
50
#define ARMADA38X_CORECLK_MAXREG 0
51
52
static struct resource_spec armada38x_coreclk_specs[] = {
53
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
54
{ -1, 0 }
55
};
56
57
struct armada38x_coreclk_softc {
58
struct resource *res;
59
struct clkdom *clkdom;
60
struct mtx mtx;
61
};
62
63
static int armada38x_coreclk_attach(device_t dev);
64
static int armada38x_coreclk_probe(device_t dev);
65
66
static struct armada38x_gen_clknode_def gen_nodes[] =
67
{
68
{
69
.def = {
70
.name = "coreclk_0",
71
.id = 0,
72
.parent_cnt = 0,
73
},
74
},
75
{
76
.def = {
77
.name = "coreclk_2",
78
.id = 1,
79
.parent_cnt = 0,
80
},
81
}
82
};
83
84
static int
85
armada38x_coreclk_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
86
{
87
struct armada38x_coreclk_softc *sc;
88
89
sc = device_get_softc(dev);
90
91
if (addr > ARMADA38X_CORECLK_MAXREG)
92
return (EINVAL);
93
94
*val = bus_read_4(sc->res, addr);
95
96
return (0);
97
}
98
99
static int
100
armada38x_coreclk_write_4(device_t dev, bus_addr_t addr, uint32_t val)
101
{
102
struct armada38x_coreclk_softc *sc;
103
104
sc = device_get_softc(dev);
105
106
if (addr > ARMADA38X_CORECLK_MAXREG)
107
return (EINVAL);
108
109
bus_write_4(sc->res, addr, val);
110
111
return (0);
112
}
113
114
static void
115
armada38x_coreclk_device_lock(device_t dev)
116
{
117
struct armada38x_coreclk_softc *sc;
118
119
sc = device_get_softc(dev);
120
mtx_lock(&sc->mtx);
121
}
122
123
static void
124
armada38x_coreclk_device_unlock(device_t dev)
125
{
126
struct armada38x_coreclk_softc *sc;
127
128
sc = device_get_softc(dev);
129
mtx_unlock(&sc->mtx);
130
}
131
132
static int
133
armada38x_coreclk_probe(device_t dev)
134
{
135
136
if (!ofw_bus_status_okay(dev))
137
return (ENXIO);
138
139
if (!ofw_bus_is_compatible(dev, "marvell,armada-380-core-clock"))
140
return (ENXIO);
141
142
device_set_desc(dev, "ARMADA38X core-clock");
143
144
return (BUS_PROBE_DEFAULT);
145
}
146
147
static int
148
armada38x_coreclk_create_coreclk(device_t dev)
149
{
150
struct armada38x_coreclk_softc *sc;
151
int rv, i;
152
153
sc = device_get_softc(dev);
154
155
for (i = 0; i < nitems(gen_nodes); ++i) {
156
rv = armada38x_gen_register(sc->clkdom, &gen_nodes[i]);
157
if (rv)
158
return (rv);
159
}
160
161
return (rv);
162
}
163
164
static int
165
armada38x_coreclk_attach(device_t dev)
166
{
167
struct armada38x_coreclk_softc *sc;
168
int error;
169
170
sc = device_get_softc(dev);
171
172
if (bus_alloc_resources(dev, armada38x_coreclk_specs, &sc->res) != 0) {
173
device_printf(dev, "Cannot allocate resources.\n");
174
return (ENXIO);
175
}
176
177
mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
178
179
sc->clkdom = clkdom_create(dev);
180
if (NULL == sc->clkdom) {
181
device_printf(dev, "Cannot create clkdom\n");
182
return (ENXIO);
183
}
184
185
error = armada38x_coreclk_create_coreclk(dev);
186
if (0 != error) {
187
device_printf(dev, "Cannot create coreclk.\n");
188
return (error);
189
}
190
191
if (clkdom_finit(sc->clkdom) != 0)
192
panic("Cannot finalize clock domain initialization.\n");
193
194
if (bootverbose)
195
clkdom_dump(sc->clkdom);
196
197
return (0);
198
}
199
200
static device_method_t amada38x_coreclk_methods[] = {
201
DEVMETHOD(clkdev_write_4, armada38x_coreclk_write_4),
202
DEVMETHOD(clkdev_read_4, armada38x_coreclk_read_4),
203
DEVMETHOD(clkdev_device_lock, armada38x_coreclk_device_lock),
204
DEVMETHOD(clkdev_device_unlock, armada38x_coreclk_device_unlock),
205
206
DEVMETHOD(device_attach, armada38x_coreclk_attach),
207
DEVMETHOD(device_probe, armada38x_coreclk_probe),
208
209
DEVMETHOD_END
210
};
211
212
static driver_t armada38x_coreclk_driver = {
213
"armada38x_coreclk",
214
amada38x_coreclk_methods,
215
sizeof(struct armada38x_coreclk_softc),
216
};
217
218
EARLY_DRIVER_MODULE(armada38x_coreclk, simplebus, armada38x_coreclk_driver, 0, 0,
219
BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
220
221