Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/dev/clk/starfive/jh7110_clk_stg.c
39536 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2024 Jari Sihvola <[email protected]>
5
*/
6
7
/* Clocks for STG group. PLL_OUT & SYS clocks must be registered first. */
8
9
#include <sys/param.h>
10
#include <sys/systm.h>
11
#include <sys/bus.h>
12
#include <sys/mutex.h>
13
#include <sys/kernel.h>
14
#include <sys/module.h>
15
#include <sys/resource.h>
16
#include <sys/rman.h>
17
#include <machine/bus.h>
18
19
#include <dev/fdt/simplebus.h>
20
#include <dev/hwreset/hwreset.h>
21
#include <dev/ofw/ofw_bus.h>
22
#include <dev/ofw/ofw_bus_subr.h>
23
24
#include <dev/clk/clk.h>
25
#include <dev/clk/starfive/jh7110_clk.h>
26
27
#include <dt-bindings/clock/starfive,jh7110-crg.h>
28
29
#include "clkdev_if.h"
30
#include "hwreset_if.h"
31
32
static struct ofw_compat_data compat_data[] = {
33
{ "starfive,jh7110-stgcrg", 1 },
34
{ NULL, 0 }
35
};
36
37
static struct resource_spec res_spec[] = {
38
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
39
RESOURCE_SPEC_END
40
};
41
42
/* parents */
43
static const char *e2_rtc_p[] = { "osc" };
44
static const char *e2_core_p[] = { "stg_axiahb" };
45
static const char *e2_dbg_p[] = { "stg_axiahb" };
46
47
static const char *pcie_slv_main_p[] = { "stg_axiahb" };
48
static const char *pcie0_tl_p[] = { "stg_axiahb" };
49
static const char *pcie1_tl_p[] = { "stg_axiahb" };
50
static const char *pcie0_axi_mst0_p[] = { "stg_axiahb" };
51
static const char *pcie1_axi_mst0_p[] = { "stg_axiahb" };
52
static const char *pcie0_apb_p[] = { "apb_bus" };
53
static const char *pcie1_apb_p[] = { "apb_bus" };
54
55
static const char *usb0_lpm_p[] = { "osc" };
56
static const char *usb0_stb_p[] = { "osc" };
57
static const char *usb0_apb_p[] = { "apb_bus" };
58
static const char *usb0_utmi_apb_p[] = { "apb_bus" };
59
static const char *usb0_axi_p[] = { "stg_axiahb" };
60
static const char *usb0_app_125_p[] = { "usb_125m" };
61
static const char *usb0_refclk_p[] = { "osc" };
62
63
static const char *dma1p_axi_p[] = { "stg_axiahb" };
64
static const char *dma1p_ahb_p[] = { "stg_axiahb" };
65
66
/* STG clocks */
67
static const struct jh7110_clk_def stg_clks[] = {
68
JH7110_GATE(JH7110_STGCLK_USB0_APB, "usb0_apb", usb0_apb_p),
69
JH7110_GATE(JH7110_STGCLK_USB0_UTMI_APB, "usb0_utmi_apb",
70
usb0_utmi_apb_p),
71
JH7110_GATE(JH7110_STGCLK_USB0_AXI, "usb0_axi", usb0_axi_p),
72
JH7110_GATEDIV(JH7110_STGCLK_USB0_LPM, "usb0_lpm", usb0_lpm_p, 2),
73
JH7110_GATEDIV(JH7110_STGCLK_USB0_STB, "usb0_stb", usb0_stb_p, 4),
74
JH7110_GATE(JH7110_STGCLK_USB0_APP_125, "usb0_app_125", usb0_app_125_p),
75
JH7110_DIV(JH7110_STGCLK_USB0_REFCLK, "usb0_refclk", usb0_refclk_p, 2),
76
77
JH7110_GATE(JH7110_STGCLK_PCIE0_AXI_MST0, "pcie0_axi_mst0",
78
pcie0_axi_mst0_p),
79
JH7110_GATE(JH7110_STGCLK_PCIE0_APB, "pcie0_apb", pcie0_apb_p),
80
JH7110_GATE(JH7110_STGCLK_PCIE0_TL, "pcie0_tl", pcie0_tl_p),
81
JH7110_GATE(JH7110_STGCLK_PCIE1_AXI_MST0, "pcie1_axi_mst0",
82
pcie1_axi_mst0_p),
83
84
JH7110_GATE(JH7110_STGCLK_PCIE1_APB, "pcie1_apb", pcie1_apb_p),
85
JH7110_GATE(JH7110_STGCLK_PCIE1_TL, "pcie1_tl", pcie1_tl_p),
86
JH7110_GATE(JH7110_STGCLK_PCIE_SLV_MAIN, "pcie_slv_main",
87
pcie_slv_main_p),
88
89
JH7110_GATEDIV(JH7110_STGCLK_E2_RTC, "e2_rtc", e2_rtc_p, 24),
90
JH7110_GATE(JH7110_STGCLK_E2_CORE, "e2_core", e2_core_p),
91
JH7110_GATE(JH7110_STGCLK_E2_DBG, "e2_dbg", e2_dbg_p),
92
93
JH7110_GATE(JH7110_STGCLK_DMA1P_AXI, "dma1p_axi", dma1p_axi_p),
94
JH7110_GATE(JH7110_STGCLK_DMA1P_AHB, "dma1p_ahb", dma1p_ahb_p),
95
};
96
97
static int
98
jh7110_clk_stg_probe(device_t dev)
99
{
100
if (!ofw_bus_status_okay(dev))
101
return (ENXIO);
102
103
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
104
return (ENXIO);
105
106
device_set_desc(dev, "StarFive JH7110 STG clock generator");
107
108
return (BUS_PROBE_DEFAULT);
109
}
110
111
static int
112
jh7110_clk_stg_attach(device_t dev)
113
{
114
struct jh7110_clkgen_softc *sc;
115
int err;
116
117
sc = device_get_softc(dev);
118
119
sc->reset_status_offset = STGCRG_RESET_STATUS;
120
sc->reset_selector_offset = STGCRG_RESET_SELECTOR;
121
122
mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
123
124
err = bus_alloc_resources(dev, res_spec, &sc->mem_res);
125
if (err != 0) {
126
device_printf(dev, "Couldn't allocate resources, error %d\n",
127
err);
128
return (ENXIO);
129
}
130
131
sc->clkdom = clkdom_create(dev);
132
if (sc->clkdom == NULL) {
133
device_printf(dev, "Couldn't create clkdom, error %d\n", err);
134
return (ENXIO);
135
}
136
137
for (int i = 0; i < nitems(stg_clks); i++) {
138
err = jh7110_clk_register(sc->clkdom, &stg_clks[i]);
139
if (err != 0) {
140
device_printf(dev,
141
"Couldn't register clk %s, error %d\n",
142
stg_clks[i].clkdef.name, err);
143
return (ENXIO);
144
}
145
}
146
147
if (clkdom_finit(sc->clkdom) != 0)
148
panic("Cannot finalize clkdom initialization\n");
149
150
if (bootverbose)
151
clkdom_dump(sc->clkdom);
152
153
hwreset_register_ofw_provider(dev);
154
155
return (0);
156
}
157
158
static void
159
jh7110_clk_stg_device_lock(device_t dev)
160
{
161
struct jh7110_clkgen_softc *sc;
162
163
sc = device_get_softc(dev);
164
mtx_lock(&sc->mtx);
165
}
166
167
static void
168
jh7110_clk_stg_device_unlock(device_t dev)
169
{
170
struct jh7110_clkgen_softc *sc;
171
172
sc = device_get_softc(dev);
173
mtx_unlock(&sc->mtx);
174
}
175
176
static int
177
jh7110_clk_stg_detach(device_t dev)
178
{
179
/* Detach not supported */
180
return (EBUSY);
181
}
182
183
static device_method_t jh7110_clk_stg_methods[] = {
184
/* Device interface */
185
DEVMETHOD(device_probe, jh7110_clk_stg_probe),
186
DEVMETHOD(device_attach, jh7110_clk_stg_attach),
187
DEVMETHOD(device_detach, jh7110_clk_stg_detach),
188
189
/* clkdev interface */
190
DEVMETHOD(clkdev_device_lock, jh7110_clk_stg_device_lock),
191
DEVMETHOD(clkdev_device_unlock, jh7110_clk_stg_device_unlock),
192
193
/* Reset interface */
194
DEVMETHOD(hwreset_assert, jh7110_reset_assert),
195
DEVMETHOD(hwreset_is_asserted, jh7110_reset_is_asserted),
196
197
DEVMETHOD_END
198
};
199
200
DEFINE_CLASS_0(jh7110_stg, jh7110_stg_driver, jh7110_clk_stg_methods,
201
sizeof(struct jh7110_clkgen_softc));
202
EARLY_DRIVER_MODULE(jh7110_stg, simplebus, jh7110_stg_driver, 0, 0,
203
BUS_PASS_BUS + BUS_PASS_ORDER_LATE + 1);
204
MODULE_VERSION(jh7110_stg, 1);
205
206