1 /* $NetBSD: imx6_ccmvar.h,v 1.3 2023/05/04 13:25:07 bouyer Exp $ */ 2 /* 3 * Copyright (c) 2012,2019 Genetec Corporation. All rights reserved. 4 * Written by Hashimoto Kenichi for Genetec Corporation. 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 GENETEC CORPORATION ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 17 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION 19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef _ARM_NXP_IMX6_CCMVAR_H_ 29 #define _ARM_NXP_IMX6_CCMVAR_H_ 30 31 #include <dev/clk/clk.h> 32 #include <dev/clk/clk_backend.h> 33 34 struct imx6ccm_softc { 35 device_t sc_dev; 36 bus_space_tag_t sc_iot; 37 bus_space_handle_t sc_ioh; 38 bus_space_handle_t sc_ioh_analog; 39 40 struct clk_domain sc_clkdom; 41 struct imx6_clk *sc_imx6_clks; 42 int sc_imx6_clksize; 43 }; 44 45 struct imxccm_init_parent; 46 47 void imx6ccm_attach_common(device_t, struct imx6_clk *, int, 48 struct imxccm_init_parent *); 49 50 struct clk *imx6_get_clock(struct imx6ccm_softc *, const char *); 51 struct imx6_clk *imx6_clk_find(struct imx6ccm_softc *sc, const char *); 52 53 struct imxccm_init_parent { 54 const char *clock; 55 const char *parent; 56 }; 57 58 59 enum imx6_clk_type { 60 IMX6_CLK_FIXED, 61 IMX6_CLK_FIXED_FACTOR, 62 IMX6_CLK_PLL, 63 IMX6_CLK_MUX, 64 IMX6_CLK_GATE, 65 IMX6_CLK_PFD, 66 IMX6_CLK_DIV, 67 }; 68 69 enum imx6_clk_reg { 70 IMX6_CLK_REG_CCM, 71 IMX6_CLK_REG_CCM_ANALOG, 72 }; 73 74 enum imx6_clk_pll_type { 75 IMX6_CLK_PLL_GENERIC, 76 IMX6_CLK_PLL_SYS, 77 IMX6_CLK_PLL_USB, 78 IMX6_CLK_PLL_AUDIO_VIDEO, 79 IMX6_CLK_PLL_ENET, 80 }; 81 82 enum imx6_clk_div_type { 83 IMX6_CLK_DIV_NORMAL, 84 IMX6_CLK_DIV_BUSY, 85 IMX6_CLK_DIV_TABLE, 86 }; 87 88 enum imx6_clk_mux_type { 89 IMX6_CLK_MUX_NORMAL, 90 IMX6_CLK_MUX_BUSY, 91 }; 92 93 struct imx6_clk_fixed { 94 u_int rate; 95 }; 96 97 struct imx6_clk_fixed_factor { 98 u_int div; 99 u_int mult; 100 }; 101 102 struct imx6_clk_pfd { 103 uint32_t reg; 104 int index; 105 }; 106 107 struct imx6_clk_pll { 108 enum imx6_clk_pll_type type; 109 uint32_t reg; 110 uint32_t mask; 111 uint32_t powerdown; 112 unsigned long ref; 113 }; 114 115 struct imx6_clk_div { 116 enum imx6_clk_div_type type; 117 enum imx6_clk_reg base; 118 uint32_t reg; 119 uint32_t mask; 120 uint32_t busy_reg; 121 uint32_t busy_mask; 122 const int *tbl; 123 }; 124 125 struct imx6_clk_mux { 126 enum imx6_clk_mux_type type; 127 enum imx6_clk_reg base; 128 uint32_t reg; 129 uint32_t mask; 130 const char **parents; 131 u_int nparents; 132 uint32_t busy_reg; 133 uint32_t busy_mask; 134 }; 135 136 struct imx6_clk_gate { 137 enum imx6_clk_reg base; 138 uint32_t reg; 139 uint32_t mask; 140 uint32_t exclusive_mask; 141 }; 142 143 struct imx6_clk { 144 struct clk base; /* must be first */ 145 146 const char *parent; 147 u_int refcnt; 148 149 enum imx6_clk_type type; 150 union { 151 struct imx6_clk_fixed fixed; 152 struct imx6_clk_fixed_factor fixed_factor; 153 struct imx6_clk_pfd pfd; 154 struct imx6_clk_pll pll; 155 struct imx6_clk_div div; 156 struct imx6_clk_mux mux; 157 struct imx6_clk_gate gate; 158 } clk; 159 }; 160 161 #define CLK_FIXED(_name, _rate) { \ 162 .base = { .name = (_name) }, \ 163 .type = IMX6_CLK_FIXED, \ 164 .clk = { \ 165 .fixed = { \ 166 .rate = (_rate), \ 167 } \ 168 } \ 169 } 170 171 #define CLK_FIXED_FACTOR(_name, _parent, _div, _mult) { \ 172 .base = { .name = (_name) }, \ 173 .type = IMX6_CLK_FIXED_FACTOR, \ 174 .parent = (_parent), \ 175 .clk = { \ 176 .fixed_factor = { \ 177 .div = (_div), \ 178 .mult = (_mult), \ 179 } \ 180 } \ 181 } 182 183 #define CLK_PFD(_name, _parent, _reg, _index) { \ 184 .base = { .name = (_name) }, \ 185 .type = IMX6_CLK_PFD, \ 186 .parent = (_parent), \ 187 .clk = { \ 188 .pfd = { \ 189 .reg = (CCM_ANALOG_##_reg), \ 190 .index = (_index), \ 191 } \ 192 } \ 193 } 194 195 #define CLK_PLL(_name, _parent, _type, _reg, _mask, _powerdown, _ref) { \ 196 .base = { .name = (_name) }, \ 197 .type = IMX6_CLK_PLL, \ 198 .parent = (_parent), \ 199 .clk = { \ 200 .pll = { \ 201 .type = (IMX6_CLK_PLL_##_type), \ 202 .reg = (CCM_ANALOG_##_reg), \ 203 .mask = (CCM_ANALOG_##_reg##_##_mask), \ 204 .powerdown = (CCM_ANALOG_##_reg##_##_powerdown), \ 205 .ref = (_ref), \ 206 } \ 207 } \ 208 } 209 210 #define CLK_DIV(_name, _parent, _reg, _mask) { \ 211 .base = { .name = (_name) }, \ 212 .type = IMX6_CLK_DIV, \ 213 .parent = (_parent), \ 214 .clk = { \ 215 .div = { \ 216 .type = (IMX6_CLK_DIV_NORMAL), \ 217 .base = (IMX6_CLK_REG_CCM), \ 218 .reg = (CCM_##_reg), \ 219 .mask = (CCM_##_reg##_##_mask), \ 220 } \ 221 } \ 222 } 223 224 #define CLK_DIV_BUSY(_name, _parent, _reg, _mask, _busy_reg, _busy_mask) { \ 225 .base = { .name = (_name) }, \ 226 .type = IMX6_CLK_DIV, \ 227 .parent = (_parent), \ 228 .clk = { \ 229 .div = { \ 230 .type = (IMX6_CLK_DIV_BUSY), \ 231 .base = (IMX6_CLK_REG_CCM), \ 232 .reg = (CCM_##_reg), \ 233 .mask = (CCM_##_reg##_##_mask), \ 234 .busy_reg = (CCM_##_busy_reg), \ 235 .busy_mask = (CCM_##_busy_reg##_##_busy_mask) \ 236 } \ 237 } \ 238 } 239 240 #define CLK_DIV_TABLE(_name, _parent, _reg, _mask, _tbl) { \ 241 .base = { .name = (_name) }, \ 242 .type = IMX6_CLK_DIV, \ 243 .parent = (_parent), \ 244 .clk = { \ 245 .div = { \ 246 .type = (IMX6_CLK_DIV_TABLE), \ 247 .base = (IMX6_CLK_REG_CCM_ANALOG), \ 248 .reg = (CCM_ANALOG_##_reg), \ 249 .mask = (CCM_ANALOG_##_reg##_##_mask), \ 250 .tbl = (_tbl) \ 251 } \ 252 } \ 253 } 254 255 #define CLK_MUX(_name, _parents, _base, _reg, _mask) { \ 256 .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \ 257 .type = IMX6_CLK_MUX, \ 258 .clk = { \ 259 .mux = { \ 260 .type = (IMX6_CLK_MUX_NORMAL), \ 261 .base = (IMX6_CLK_REG_##_base), \ 262 .reg = (_base##_##_reg), \ 263 .mask = (_base##_##_reg##_##_mask), \ 264 .parents = (_parents), \ 265 .nparents = __arraycount(_parents) \ 266 } \ 267 } \ 268 } 269 270 #define CLK_MUX_BUSY(_name, _parents, _reg, _mask, _busy_reg, _busy_mask) { \ 271 .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \ 272 .type = IMX6_CLK_MUX, \ 273 .clk = { \ 274 .mux = { \ 275 .type = (IMX6_CLK_MUX_BUSY), \ 276 .base = (IMX6_CLK_REG_CCM), \ 277 .reg = (CCM_##_reg), \ 278 .mask = (CCM_##_reg##_##_mask), \ 279 .parents = (_parents), \ 280 .nparents = __arraycount(_parents), \ 281 .busy_reg = (CCM_##_busy_reg), \ 282 .busy_mask = (CCM_##_busy_reg##_##_busy_mask) \ 283 } \ 284 } \ 285 } 286 287 #define CLK_GATE(_name, _parent, _base, _reg, _mask) { \ 288 .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \ 289 .type = IMX6_CLK_GATE, \ 290 .parent = (_parent), \ 291 .clk = { \ 292 .gate = { \ 293 .base = (IMX6_CLK_REG_##_base), \ 294 .reg = (_base##_##_reg), \ 295 .mask = (_base##_##_reg##_##_mask), \ 296 .exclusive_mask = 0 \ 297 } \ 298 } \ 299 } 300 301 #define CLK_GATE_EXCLUSIVE(_name, _parent, _base, _reg, _mask, _exclusive_mask) { \ 302 .base = { .name = (_name), .flags = CLK_SET_RATE_PARENT }, \ 303 .type = IMX6_CLK_GATE, \ 304 .parent = (_parent), \ 305 .clk = { \ 306 .gate = { \ 307 .base = (IMX6_CLK_REG_##_base), \ 308 .reg = (_base##_##_reg), \ 309 .mask = (_base##_##_reg##_##_mask), \ 310 .exclusive_mask = (_base##_##_reg##_##_exclusive_mask) \ 311 } \ 312 } \ 313 } 314 315 #endif /* _ARM_NXP_IMX6_CCMVAR_H_ */ 316