2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (c) 2018 Emmanuel Vadot <manu@freebsd.org>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include <dev/extres/clk/clk.h>
35 #include <dev/extres/clk/clk_div.h>
36 #include <dev/extres/clk/clk_gate.h>
37 #include <dev/extres/clk/clk_fixed.h>
38 #include <dev/extres/clk/clk_link.h>
40 #include <arm64/rockchip/clk/rk_clk_armclk.h>
41 #include <arm64/rockchip/clk/rk_clk_composite.h>
42 #include <arm64/rockchip/clk/rk_clk_fract.h>
43 #include <arm64/rockchip/clk/rk_clk_gate.h>
44 #include <arm64/rockchip/clk/rk_clk_mux.h>
45 #include <arm64/rockchip/clk/rk_clk_pll.h>
47 /* Macro for defining various types of clocks. */
49 #define GATE(_idx, _clkname, _pname, _o, _s) \
53 .parent_name = _pname, \
54 .offset = CRU_CLKGATE_CON(_o), \
58 /* Fixed rate clock. */
59 #define FRATE(_id, _name, _freq) \
61 .type = RK_CLK_FIXED, \
62 .clk.fixed = &(struct clk_fixed_def) { \
64 .clkdef.name = _name, \
65 .clkdef.parent_names = NULL, \
66 .clkdef.parent_cnt = 0, \
67 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
72 /* Fixed factor multipier/divider. */
73 #define FFACT(_id, _name, _pname, _mult, _div) \
75 .type = RK_CLK_FIXED, \
76 .clk.fixed = &(struct clk_fixed_def) { \
78 .clkdef.name = _name, \
79 .clkdef.parent_names = (const char *[]){_pname}, \
80 .clkdef.parent_cnt = 1, \
81 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
90 .type = RK_CLK_LINK, \
91 .clk.link = &(struct clk_link_def) { \
93 .clkdef.name = _name, \
94 .clkdef.parent_names = NULL, \
95 .clkdef.parent_cnt = 0, \
96 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
100 /* Complex clock fo ARM cores. */
101 #define ARMDIV(_id, _name, _pn, _r, _o, _ds, _dw, _ms, _mw, _mp, _ap) \
103 .type = RK_CLK_ARMCLK, \
104 .clk.armclk = &(struct rk_clk_armclk_def) { \
106 .clkdef.name = _name, \
107 .clkdef.parent_names = _pn, \
108 .clkdef.parent_cnt = nitems(_pn), \
109 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
110 .muxdiv_offset = CRU_CLKSEL_CON(_o), \
115 .main_parent = _mp, \
118 .nrates = nitems(_r), \
122 /* Fractional rate multipier/divider. */
123 #define FRACT(_id, _name, _pname, _f, _o) \
125 .type = RK_CLK_FRACT, \
126 .clk.fract = &(struct rk_clk_fract_def) { \
128 .clkdef.name = _name, \
129 .clkdef.parent_names = (const char *[]){_pname}, \
130 .clkdef.parent_cnt = 1, \
131 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
132 .offset = CRU_CLKSEL_CON(_o), \
137 /* Full composite clock. */
138 #define COMP(_id, _name, _pnames, _f, _o, _ds, _dw, _ms, _mw) \
140 .type = RK_CLK_COMPOSITE, \
141 .clk.composite = &(struct rk_clk_composite_def) { \
143 .clkdef.name = _name, \
144 .clkdef.parent_names = _pnames, \
145 .clkdef.parent_cnt = nitems(_pnames), \
146 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
147 .muxdiv_offset = CRU_CLKSEL_CON(_o), \
152 .flags = RK_CLK_COMPOSITE_HAVE_MUX | _f, \
156 /* Composite clock without mux (divider only). */
157 #define CDIV(_id, _name, _pname, _f, _o, _ds, _dw) \
159 .type = RK_CLK_COMPOSITE, \
160 .clk.composite = &(struct rk_clk_composite_def) { \
162 .clkdef.name = _name, \
163 .clkdef.parent_names = (const char *[]){_pname}, \
164 .clkdef.parent_cnt = 1, \
165 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
166 .muxdiv_offset = CRU_CLKSEL_CON(_o), \
173 /* Complex clock without divider (multiplexer only). */
174 #define MUX(_id, _name, _pn, _f, _mo, _ms, _mw) \
176 .type = RK_CLK_MUX, \
177 .clk.mux = &(struct rk_clk_mux_def) { \
179 .clkdef.name = _name, \
180 .clkdef.parent_names = _pn, \
181 .clkdef.parent_cnt = nitems(_pn), \
182 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \
183 .offset = CRU_CLKSEL_CON(_mo), \
192 const char *parent_name;
198 #define CRU_GATE(idx, clkname, pname, o, s) \
202 .parent_name = pname, \
208 RK_CLK_UNDEFINED = 0,
220 enum rk_clk_type type;
222 struct rk_clk_pll_def *pll;
223 struct rk_clk_composite_def *composite;
224 struct rk_clk_mux_def *mux;
225 struct rk_clk_armclk_def *armclk;
226 struct clk_fixed_def *fixed;
227 struct rk_clk_fract_def *fract;
228 struct clk_link_def *link;
232 struct rk_cru_softc {
234 struct resource *res;
235 struct clkdom *clkdom;
238 uint32_t reset_offset;
240 struct rk_cru_gate *gates;
244 struct rk_clk_armclk_def *armclk;
245 struct rk_clk_armclk_rates *armclk_rates;
249 DECLARE_CLASS(rk_cru_driver);
251 int rk_cru_attach(device_t dev);
253 #endif /* __RK_CRU_H__ */