Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/mv/clk/a37x0_periph_clk_driver.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2021 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 AND CONTRIBUTORS ``AS IS'' AND
16
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
* SUCH DAMAGE.
26
*/
27
28
#include <sys/param.h>
29
#include <sys/bus.h>
30
#include <sys/kernel.h>
31
#include <sys/module.h>
32
#include <sys/mutex.h>
33
#include <sys/rman.h>
34
#include <machine/bus.h>
35
36
#include <dev/fdt/simplebus.h>
37
38
#include <dev/clk/clk.h>
39
#include <dev/clk/clk_fixed.h>
40
41
#include <dev/ofw/ofw_bus.h>
42
#include <dev/ofw/ofw_bus_subr.h>
43
44
#include "clkdev_if.h"
45
#include "periph.h"
46
47
#define TBG_COUNT 4
48
#define XTAL_OFW_INDEX 4
49
50
static struct resource_spec a37x0_periph_clk_spec[] = {
51
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
52
{ -1, 0 }
53
};
54
55
int
56
a37x0_periph_clk_attach(device_t dev)
57
{
58
struct a37x0_periph_clknode_def *dev_defs;
59
struct a37x0_periph_clk_softc *sc;
60
const char *tbg_clocks[5];
61
const char *xtal_clock;
62
phandle_t node;
63
int error, i;
64
clk_t clock;
65
66
sc = device_get_softc(dev);
67
node = ofw_bus_get_node(dev);
68
sc->dev = dev;
69
70
mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
71
72
if (bus_alloc_resources(dev, a37x0_periph_clk_spec, &sc->res) != 0) {
73
device_printf(dev, "Cannot allocate resources\n");
74
return (ENXIO);
75
}
76
77
sc->clkdom = clkdom_create(dev);
78
if (sc->clkdom == NULL) {
79
device_printf(dev, "Cannot create clock domain\n");
80
return (ENXIO);
81
}
82
83
for (i = 0; i < TBG_COUNT; i++){
84
error = clk_get_by_ofw_index(dev, node, i, &clock);
85
if (error)
86
goto fail;
87
tbg_clocks[i] = clk_get_name(clock);
88
}
89
90
error = clk_get_by_ofw_index(dev, node, XTAL_OFW_INDEX, &clock);
91
if (error)
92
goto fail;
93
xtal_clock = clk_get_name(clock);
94
95
dev_defs = sc->devices;
96
97
for (i = 0; i< sc->device_count; i++) {
98
dev_defs[i].common_def.tbgs = tbg_clocks;
99
dev_defs[i].common_def.xtal = xtal_clock;
100
dev_defs[i].common_def.tbg_cnt = TBG_COUNT;
101
switch (dev_defs[i].type) {
102
case CLK_FULL_DD:
103
error = a37x0_periph_d_register_full_clk_dd(
104
sc->clkdom, &dev_defs[i]);
105
if (error)
106
goto fail;
107
break;
108
109
case CLK_FULL:
110
error = a37x0_periph_d_register_full_clk(
111
sc->clkdom, &dev_defs[i]);
112
if (error)
113
goto fail;
114
break;
115
116
case CLK_GATE:
117
error = a37x0_periph_gate_register_gate(
118
sc->clkdom, &dev_defs[i]);
119
if (error)
120
goto fail;
121
break;
122
123
case CLK_MUX_GATE:
124
error = a37x0_periph_register_mux_gate(
125
sc->clkdom, &dev_defs[i]);
126
if (error)
127
goto fail;
128
break;
129
130
case CLK_FIXED:
131
error = a37x0_periph_fixed_register_fixed(
132
sc->clkdom, &dev_defs[i]);
133
if (error)
134
goto fail;
135
break;
136
137
case CLK_CPU:
138
error = a37x0_periph_d_register_periph_cpu(
139
sc->clkdom, &dev_defs[i]);
140
if (error)
141
goto fail;
142
break;
143
144
case CLK_MDD:
145
error = a37x0_periph_d_register_mdd(
146
sc->clkdom, &dev_defs[i]);
147
if (error)
148
goto fail;
149
break;
150
151
case CLK_MUX_GATE_FIXED:
152
error = a37x0_periph_register_mux_gate_fixed(
153
sc->clkdom, &dev_defs[i]);
154
if (error)
155
goto fail;
156
break;
157
158
default:
159
return (ENXIO);
160
}
161
}
162
163
error = clkdom_finit(sc->clkdom);
164
if (error)
165
goto fail;
166
167
if (bootverbose)
168
clkdom_dump(sc->clkdom);
169
170
return (0);
171
172
fail:
173
bus_release_resources(dev, a37x0_periph_clk_spec, &sc->res);
174
175
return (error);
176
177
}
178
179
int
180
a37x0_periph_clk_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
181
{
182
struct a37x0_periph_clk_softc *sc;
183
184
sc = device_get_softc(dev);
185
*val = bus_read_4(sc->res, addr);
186
187
return (0);
188
}
189
190
void
191
a37x0_periph_clk_device_lock(device_t dev)
192
{
193
struct a37x0_periph_clk_softc *sc;
194
195
sc = device_get_softc(dev);
196
mtx_lock(&sc->mtx);
197
}
198
199
void
200
a37x0_periph_clk_device_unlock(device_t dev)
201
{
202
struct a37x0_periph_clk_softc *sc;
203
204
sc = device_get_softc(dev);
205
mtx_unlock(&sc->mtx);
206
}
207
208
int
209
a37x0_periph_clk_detach(device_t dev)
210
{
211
212
return (EBUSY);
213
}
214
215