1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2020 Oleksandr Tymoshenko <gonzo@FreeBSD.org> 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 * $FreeBSD$ 28 */ 29 30 #ifndef IMX6_CCM_CLK_H 31 #define IMX6_CCM_CLK_H 32 33 #include <dev/extres/clk/clk.h> 34 #include <dev/extres/clk/clk_div.h> 35 #include <dev/extres/clk/clk_fixed.h> 36 #include <dev/extres/clk/clk_gate.h> 37 #include <dev/extres/clk/clk_link.h> 38 39 enum imx_clk_type { 40 IMX_CLK_UNDEFINED = 0, 41 IMX_CLK_FIXED, 42 IMX_CLK_LINK, 43 IMX_CLK_MUX, 44 IMX_CLK_GATE, 45 IMX_CLK_COMPOSITE, 46 IMX_CLK_SSCG_PLL, 47 IMX_CLK_FRAC_PLL, 48 IMX_CLK_DIV, 49 }; 50 51 struct imx_clk { 52 enum imx_clk_type type; 53 union { 54 struct clk_fixed_def *fixed; 55 struct clk_link_def *link; 56 struct imx_clk_mux_def *mux; 57 struct imx_clk_gate_def *gate; 58 struct imx_clk_composite_def *composite; 59 struct imx_clk_sscg_pll_def *sscg_pll; 60 struct imx_clk_frac_pll_def *frac_pll; 61 struct clk_div_def *div; 62 } clk; 63 }; 64 65 /* Linked clock. */ 66 #define LINK(_id, _name) \ 67 { \ 68 .type = IMX_CLK_LINK, \ 69 .clk.link = &(struct clk_link_def) { \ 70 .clkdef.id = _id, \ 71 .clkdef.name = _name, \ 72 .clkdef.parent_names = NULL, \ 73 .clkdef.parent_cnt = 0, \ 74 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 75 }, \ 76 } 77 78 /* Complex clock without divider (multiplexer only). */ 79 #define MUX(_id, _name, _pn, _f, _mo, _ms, _mw) \ 80 { \ 81 .type = IMX_CLK_MUX, \ 82 .clk.mux = &(struct imx_clk_mux_def) { \ 83 .clkdef.id = _id, \ 84 .clkdef.name = _name, \ 85 .clkdef.parent_names = _pn, \ 86 .clkdef.parent_cnt = nitems(_pn), \ 87 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 88 .offset = _mo, \ 89 .shift = _ms, \ 90 .width = _mw, \ 91 .mux_flags = _f, \ 92 }, \ 93 } 94 95 /* Fixed frequency clock */ 96 #define FIXED(_id, _name, _freq) \ 97 { \ 98 .type = IMX_CLK_FIXED, \ 99 .clk.fixed = &(struct clk_fixed_def) { \ 100 .clkdef.id = _id, \ 101 .clkdef.name = _name, \ 102 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 103 .freq = _freq, \ 104 }, \ 105 } 106 107 /* Fixed factor multipier/divider. */ 108 #define FFACT(_id, _name, _pname, _mult, _div) \ 109 { \ 110 .type = IMX_CLK_FIXED, \ 111 .clk.fixed = &(struct clk_fixed_def) { \ 112 .clkdef.id = _id, \ 113 .clkdef.name = _name, \ 114 .clkdef.parent_names = (const char *[]){_pname}, \ 115 .clkdef.parent_cnt = 1, \ 116 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 117 .mult = _mult, \ 118 .div = _div, \ 119 }, \ 120 } 121 122 /* Clock gate */ 123 #define GATE(_id, _name, _pname, _o, _shift) \ 124 { \ 125 .type = IMX_CLK_GATE, \ 126 .clk.gate = &(struct imx_clk_gate_def) { \ 127 .clkdef.id = _id, \ 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 = _o, \ 133 .shift = _shift, \ 134 .mask = 1, \ 135 }, \ 136 } 137 138 /* Root clock gate */ 139 #define ROOT_GATE(_id, _name, _pname, _reg) \ 140 { \ 141 .type = IMX_CLK_GATE, \ 142 .clk.gate = &(struct imx_clk_gate_def) { \ 143 .clkdef.id = _id, \ 144 .clkdef.name = _name, \ 145 .clkdef.parent_names = (const char *[]){_pname}, \ 146 .clkdef.parent_cnt = 1, \ 147 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 148 .offset = _reg, \ 149 .shift = 0, \ 150 .mask = 3, \ 151 }, \ 152 } 153 154 /* Composite clock with GATE, MUX, PRE_DIV, and POST_DIV */ 155 #define COMPOSITE(_id, _name, _pn, _o, _flags) \ 156 { \ 157 .type = IMX_CLK_COMPOSITE, \ 158 .clk.composite = &(struct imx_clk_composite_def) { \ 159 .clkdef.id = _id, \ 160 .clkdef.name = _name, \ 161 .clkdef.parent_names = _pn, \ 162 .clkdef.parent_cnt = nitems(_pn), \ 163 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 164 .offset = _o, \ 165 .flags = _flags, \ 166 }, \ 167 } 168 169 /* SSCG PLL */ 170 #define SSCG_PLL(_id, _name, _pn, _o) \ 171 { \ 172 .type = IMX_CLK_SSCG_PLL, \ 173 .clk.composite = &(struct imx_clk_composite_def) { \ 174 .clkdef.id = _id, \ 175 .clkdef.name = _name, \ 176 .clkdef.parent_names = _pn, \ 177 .clkdef.parent_cnt = nitems(_pn), \ 178 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 179 .offset = _o, \ 180 }, \ 181 } 182 183 /* Fractional PLL */ 184 #define FRAC_PLL(_id, _name, _pname, _o) \ 185 { \ 186 .type = IMX_CLK_FRAC_PLL, \ 187 .clk.frac_pll = &(struct imx_clk_frac_pll_def) { \ 188 .clkdef.id = _id, \ 189 .clkdef.name = _name, \ 190 .clkdef.parent_names = (const char *[]){_pname}, \ 191 .clkdef.parent_cnt = 1, \ 192 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 193 .offset = _o, \ 194 }, \ 195 } 196 197 #define DIV(_id, _name, _pname, _o, _shift, _width) \ 198 { \ 199 .type = IMX_CLK_DIV, \ 200 .clk.div = &(struct clk_div_def) { \ 201 .clkdef.id = _id, \ 202 .clkdef.name = _name, \ 203 .clkdef.parent_names = (const char *[]){_pname}, \ 204 .clkdef.parent_cnt = 1, \ 205 .clkdef.flags = CLK_NODE_STATIC_STRINGS, \ 206 .offset = _o, \ 207 .i_shift = _shift, \ 208 .i_width = _width, \ 209 }, \ 210 } 211 212 #endif 213