1 1.11 ryo /* $NetBSD: rk_cru.h,v 1.11 2022/08/23 05:39:06 ryo Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /*- 4 1.1 jmcneill * Copyright (c) 2018 Jared McNeill <jmcneill (at) invisible.ca> 5 1.1 jmcneill * All rights reserved. 6 1.1 jmcneill * 7 1.1 jmcneill * Redistribution and use in source and binary forms, with or without 8 1.1 jmcneill * modification, are permitted provided that the following conditions 9 1.1 jmcneill * are met: 10 1.1 jmcneill * 1. Redistributions of source code must retain the above copyright 11 1.1 jmcneill * notice, this list of conditions and the following disclaimer. 12 1.1 jmcneill * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 jmcneill * notice, this list of conditions and the following disclaimer in the 14 1.1 jmcneill * documentation and/or other materials provided with the distribution. 15 1.1 jmcneill * 16 1.1 jmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 jmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 jmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 jmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 jmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 1.1 jmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 1.1 jmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 1.1 jmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 1.1 jmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 1.1 jmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 1.1 jmcneill * SUCH DAMAGE. 27 1.1 jmcneill */ 28 1.1 jmcneill 29 1.1 jmcneill #ifndef _ARM_RK_CRU_H 30 1.1 jmcneill #define _ARM_RK_CRU_H 31 1.1 jmcneill 32 1.1 jmcneill #include <dev/clk/clk_backend.h> 33 1.2 jmcneill #include <dev/fdt/syscon.h> 34 1.1 jmcneill 35 1.1 jmcneill struct rk_cru_softc; 36 1.1 jmcneill struct rk_cru_clk; 37 1.1 jmcneill 38 1.1 jmcneill /* 39 1.1 jmcneill * Clocks 40 1.1 jmcneill */ 41 1.1 jmcneill 42 1.1 jmcneill enum rk_cru_clktype { 43 1.1 jmcneill RK_CRU_UNKNOWN, 44 1.1 jmcneill RK_CRU_PLL, 45 1.1 jmcneill RK_CRU_ARM, 46 1.1 jmcneill RK_CRU_COMPOSITE, 47 1.1 jmcneill RK_CRU_GATE, 48 1.1 jmcneill RK_CRU_MUX, 49 1.1 jmcneill }; 50 1.1 jmcneill 51 1.1 jmcneill /* PLL clocks */ 52 1.1 jmcneill 53 1.1 jmcneill struct rk_cru_pll_rate { 54 1.11 ryo u_int rate; 55 1.11 ryo union { 56 1.11 ryo struct { /* RK3328,3399 */ 57 1.11 ryo u_int refdiv; 58 1.11 ryo u_int fbdiv; 59 1.11 ryo u_int postdiv1; 60 1.11 ryo u_int postdiv2; 61 1.11 ryo u_int dsmpd; 62 1.11 ryo u_int fracdiv; 63 1.11 ryo }; 64 1.11 ryo struct { /* RK3588 */ 65 1.11 ryo u_int p; 66 1.11 ryo u_int m; 67 1.11 ryo u_int s; 68 1.11 ryo u_int k; 69 1.11 ryo }; 70 1.11 ryo }; 71 1.1 jmcneill }; 72 1.1 jmcneill 73 1.1 jmcneill #define RK_PLL_RATE(_rate, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _fracdiv) \ 74 1.1 jmcneill { \ 75 1.1 jmcneill .rate = (_rate), \ 76 1.1 jmcneill .refdiv = (_refdiv), \ 77 1.1 jmcneill .fbdiv = (_fbdiv), \ 78 1.1 jmcneill .postdiv1 = (_postdiv1), \ 79 1.1 jmcneill .postdiv2 = (_postdiv2), \ 80 1.1 jmcneill .dsmpd = (_dsmpd), \ 81 1.1 jmcneill .fracdiv = (_fracdiv), \ 82 1.1 jmcneill } 83 1.1 jmcneill 84 1.11 ryo #define RK3588_PLL_RATE(_rate, _p, _m, _s, _k) \ 85 1.11 ryo { \ 86 1.11 ryo .rate = (_rate), \ 87 1.11 ryo .p = (_p), \ 88 1.11 ryo .m = (_m), \ 89 1.11 ryo .s = (_s), \ 90 1.11 ryo .k = (_k), \ 91 1.11 ryo } 92 1.11 ryo 93 1.1 jmcneill struct rk_cru_pll { 94 1.1 jmcneill bus_size_t con_base; 95 1.1 jmcneill bus_size_t mode_reg; 96 1.1 jmcneill uint32_t mode_mask; 97 1.1 jmcneill uint32_t lock_mask; 98 1.1 jmcneill const struct rk_cru_pll_rate *rates; 99 1.1 jmcneill u_int nrates; 100 1.3 jmcneill const char **parents; 101 1.3 jmcneill u_int nparents; 102 1.8 jmcneill u_int flags; 103 1.8 jmcneill #define RK_PLL_RK3288 0x01 104 1.11 ryo #define RK_PLL_RK3588 0x02 105 1.1 jmcneill }; 106 1.1 jmcneill 107 1.1 jmcneill u_int rk_cru_pll_get_rate(struct rk_cru_softc *, struct rk_cru_clk *); 108 1.1 jmcneill int rk_cru_pll_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int); 109 1.1 jmcneill const char *rk_cru_pll_get_parent(struct rk_cru_softc *, struct rk_cru_clk *); 110 1.1 jmcneill 111 1.10 ryo #define RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, _flags) \ 112 1.1 jmcneill { \ 113 1.1 jmcneill .id = (_id), \ 114 1.1 jmcneill .type = RK_CRU_PLL, \ 115 1.1 jmcneill .base.name = (_name), \ 116 1.1 jmcneill .base.flags = 0, \ 117 1.3 jmcneill .u.pll.parents = (_parents), \ 118 1.3 jmcneill .u.pll.nparents = __arraycount(_parents), \ 119 1.1 jmcneill .u.pll.con_base = (_con_base), \ 120 1.1 jmcneill .u.pll.mode_reg = (_mode_reg), \ 121 1.1 jmcneill .u.pll.mode_mask = (_mode_mask), \ 122 1.1 jmcneill .u.pll.lock_mask = (_lock_mask), \ 123 1.1 jmcneill .u.pll.rates = (_rates), \ 124 1.1 jmcneill .u.pll.nrates = __arraycount(_rates), \ 125 1.10 ryo .u.pll.flags = _flags, \ 126 1.8 jmcneill .get_rate = rk_cru_pll_get_rate, \ 127 1.8 jmcneill .set_rate = rk_cru_pll_set_rate, \ 128 1.8 jmcneill .get_parent = rk_cru_pll_get_parent, \ 129 1.8 jmcneill } 130 1.8 jmcneill 131 1.10 ryo #define RK_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \ 132 1.10 ryo RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, 0) 133 1.10 ryo 134 1.8 jmcneill #define RK3288_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \ 135 1.10 ryo RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, RK_PLL_RK3288) 136 1.1 jmcneill 137 1.11 ryo #define RK3588_PLL(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates) \ 138 1.11 ryo RK_PLL_FLAGS(_id, _name, _parents, _con_base, _mode_reg, _mode_mask, _lock_mask, _rates, RK_PLL_RK3588) 139 1.11 ryo 140 1.1 jmcneill /* ARM clocks */ 141 1.1 jmcneill 142 1.1 jmcneill struct rk_cru_arm_rate { 143 1.1 jmcneill u_int rate; 144 1.1 jmcneill u_int div; 145 1.1 jmcneill }; 146 1.1 jmcneill 147 1.1 jmcneill #define RK_ARM_RATE(_rate, _div) \ 148 1.1 jmcneill { \ 149 1.1 jmcneill .rate = (_rate), \ 150 1.1 jmcneill .div = (_div), \ 151 1.1 jmcneill } 152 1.1 jmcneill 153 1.9 ryo struct rk_regmaskval { 154 1.9 ryo bus_size_t reg; 155 1.9 ryo uint32_t mask; 156 1.9 ryo uint32_t val; 157 1.9 ryo }; 158 1.9 ryo 159 1.4 jmcneill struct rk_cru_cpu_rate { 160 1.9 ryo u_int rate; 161 1.11 ryo struct rk_regmaskval divs[4]; 162 1.11 ryo struct rk_regmaskval pre_muxs[3]; 163 1.11 ryo struct rk_regmaskval post_muxs[3]; 164 1.4 jmcneill }; 165 1.4 jmcneill 166 1.10 ryo struct rk_regmask { 167 1.10 ryo bus_size_t reg; 168 1.10 ryo uint32_t mask; 169 1.10 ryo }; 170 1.10 ryo 171 1.1 jmcneill struct rk_cru_arm { 172 1.10 ryo bus_size_t mux_reg; 173 1.1 jmcneill uint32_t mux_mask; 174 1.1 jmcneill u_int mux_main; 175 1.1 jmcneill u_int mux_alt; 176 1.11 ryo struct rk_regmask divs[4]; 177 1.1 jmcneill const char **parents; 178 1.1 jmcneill u_int nparents; 179 1.1 jmcneill const struct rk_cru_arm_rate *rates; 180 1.4 jmcneill const struct rk_cru_cpu_rate *cpurates; 181 1.1 jmcneill u_int nrates; 182 1.1 jmcneill }; 183 1.1 jmcneill 184 1.1 jmcneill u_int rk_cru_arm_get_rate(struct rk_cru_softc *, struct rk_cru_clk *); 185 1.1 jmcneill int rk_cru_arm_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int); 186 1.4 jmcneill int rk_cru_arm_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int); 187 1.1 jmcneill const char *rk_cru_arm_get_parent(struct rk_cru_softc *, struct rk_cru_clk *); 188 1.1 jmcneill int rk_cru_arm_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *); 189 1.1 jmcneill 190 1.1 jmcneill #define RK_ARM(_id, _name, _parents, _reg, _mux_mask, _mux_main, _mux_alt, _div_mask, _rates) \ 191 1.1 jmcneill { \ 192 1.1 jmcneill .id = (_id), \ 193 1.1 jmcneill .type = RK_CRU_ARM, \ 194 1.1 jmcneill .base.name = (_name), \ 195 1.1 jmcneill .base.flags = 0, \ 196 1.1 jmcneill .u.arm.parents = (_parents), \ 197 1.1 jmcneill .u.arm.nparents = __arraycount(_parents), \ 198 1.10 ryo .u.arm.mux_reg = (_reg), \ 199 1.1 jmcneill .u.arm.mux_mask = (_mux_mask), \ 200 1.1 jmcneill .u.arm.mux_main = (_mux_main), \ 201 1.1 jmcneill .u.arm.mux_alt = (_mux_alt), \ 202 1.10 ryo .u.arm.divs[0].reg = (_reg), \ 203 1.10 ryo .u.arm.divs[0].mask = (_div_mask), \ 204 1.1 jmcneill .u.arm.rates = (_rates), \ 205 1.1 jmcneill .u.arm.nrates = __arraycount(_rates), \ 206 1.1 jmcneill .get_rate = rk_cru_arm_get_rate, \ 207 1.1 jmcneill .set_rate = rk_cru_arm_set_rate, \ 208 1.1 jmcneill .get_parent = rk_cru_arm_get_parent, \ 209 1.1 jmcneill .set_parent = rk_cru_arm_set_parent, \ 210 1.1 jmcneill } 211 1.1 jmcneill 212 1.10 ryo #define _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \ 213 1.10 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt, _cpurates) \ 214 1.10 ryo .id = (_id), \ 215 1.10 ryo .type = RK_CRU_ARM, \ 216 1.10 ryo .base.name = (_name), \ 217 1.10 ryo .base.flags = 0, \ 218 1.10 ryo .u.arm.parents = (_parents), \ 219 1.10 ryo .u.arm.nparents = __arraycount(_parents), \ 220 1.10 ryo .u.arm.mux_reg = (_mux_reg), \ 221 1.10 ryo .u.arm.mux_mask = (_mux_mask), \ 222 1.10 ryo .u.arm.mux_main = (_mux_main), \ 223 1.10 ryo .u.arm.mux_alt = (_mux_alt), \ 224 1.10 ryo .u.arm.cpurates = (_cpurates), \ 225 1.10 ryo .u.arm.nrates = __arraycount(_cpurates), \ 226 1.10 ryo .get_rate = rk_cru_arm_get_rate, \ 227 1.10 ryo .set_rate = rk_cru_arm_set_rate, \ 228 1.10 ryo .get_parent = rk_cru_arm_get_parent, \ 229 1.10 ryo .set_parent = rk_cru_arm_set_parent 230 1.10 ryo 231 1.10 ryo #define RK_CPU(_id, _name, _parents, _mux_reg, _mux_mask, _mux_main, _mux_alt, \ 232 1.10 ryo _div_reg, _div_mask, _cpurates) \ 233 1.10 ryo { \ 234 1.10 ryo _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \ 235 1.10 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt,_cpurates),\ 236 1.10 ryo .u.arm.divs[0].reg = (_div_reg), \ 237 1.10 ryo .u.arm.divs[0].mask = (_div_mask), \ 238 1.4 jmcneill } 239 1.4 jmcneill 240 1.11 ryo #define RK_CPU_CORE2(_id, _name, _parents, \ 241 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt, \ 242 1.11 ryo _div0_reg, _div0_mask, \ 243 1.11 ryo _div1_reg, _div1_mask, \ 244 1.11 ryo _cpurates) \ 245 1.11 ryo { \ 246 1.11 ryo _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \ 247 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt,_cpurates),\ 248 1.11 ryo .u.arm.divs[0].reg = (_div0_reg), \ 249 1.11 ryo .u.arm.divs[0].mask = (_div0_mask), \ 250 1.11 ryo .u.arm.divs[1].reg = (_div1_reg), \ 251 1.11 ryo .u.arm.divs[1].mask = (_div1_mask), \ 252 1.11 ryo } 253 1.11 ryo 254 1.11 ryo #define RK_CPU_CORE4(_id, _name, _parents, \ 255 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt, \ 256 1.11 ryo _div0_reg, _div0_mask, \ 257 1.11 ryo _div1_reg, _div1_mask, \ 258 1.11 ryo _div2_reg, _div2_mask, \ 259 1.11 ryo _div3_reg, _div3_mask, \ 260 1.11 ryo _cpurates) \ 261 1.11 ryo { \ 262 1.11 ryo _RK_CPU_COMMON_INITIALIZER(_id, _name, _parents, \ 263 1.11 ryo _mux_reg, _mux_mask, _mux_main, _mux_alt,_cpurates),\ 264 1.11 ryo .u.arm.divs[0].reg = (_div0_reg), \ 265 1.11 ryo .u.arm.divs[0].mask = (_div0_mask), \ 266 1.11 ryo .u.arm.divs[1].reg = (_div1_reg), \ 267 1.11 ryo .u.arm.divs[1].mask = (_div1_mask), \ 268 1.11 ryo .u.arm.divs[2].reg = (_div2_reg), \ 269 1.11 ryo .u.arm.divs[2].mask = (_div2_mask), \ 270 1.11 ryo .u.arm.divs[3].reg = (_div3_reg), \ 271 1.11 ryo .u.arm.divs[3].mask = (_div3_mask), \ 272 1.11 ryo } 273 1.11 ryo 274 1.1 jmcneill /* Composite clocks */ 275 1.1 jmcneill 276 1.1 jmcneill struct rk_cru_composite { 277 1.1 jmcneill bus_size_t muxdiv_reg; 278 1.1 jmcneill uint32_t mux_mask; 279 1.1 jmcneill uint32_t div_mask; 280 1.1 jmcneill bus_size_t gate_reg; 281 1.1 jmcneill uint32_t gate_mask; 282 1.7 jmcneill bus_size_t frac_reg; 283 1.1 jmcneill const char **parents; 284 1.1 jmcneill u_int nparents; 285 1.1 jmcneill u_int flags; 286 1.1 jmcneill #define RK_COMPOSITE_ROUND_DOWN 0x01 287 1.6 jmcneill #define RK_COMPOSITE_SET_RATE_PARENT 0x02 288 1.7 jmcneill #define RK_COMPOSITE_FRACDIV 0x04 289 1.8 jmcneill #define RK_COMPOSITE_POW2 0x08 290 1.11 ryo #define RK_COMPOSITE_HALFDIV 0x10 291 1.1 jmcneill }; 292 1.1 jmcneill 293 1.1 jmcneill int rk_cru_composite_enable(struct rk_cru_softc *, struct rk_cru_clk *, int); 294 1.1 jmcneill u_int rk_cru_composite_get_rate(struct rk_cru_softc *, struct rk_cru_clk *); 295 1.1 jmcneill int rk_cru_composite_set_rate(struct rk_cru_softc *, struct rk_cru_clk *, u_int); 296 1.1 jmcneill const char *rk_cru_composite_get_parent(struct rk_cru_softc *, struct rk_cru_clk *); 297 1.1 jmcneill int rk_cru_composite_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *); 298 1.1 jmcneill 299 1.7 jmcneill #define _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, _frac_reg, _flags) \ 300 1.1 jmcneill { \ 301 1.1 jmcneill .id = (_id), \ 302 1.1 jmcneill .type = RK_CRU_COMPOSITE, \ 303 1.1 jmcneill .base.name = (_name), \ 304 1.1 jmcneill .base.flags = 0, \ 305 1.1 jmcneill .u.composite.parents = (_parents), \ 306 1.1 jmcneill .u.composite.nparents = __arraycount(_parents), \ 307 1.1 jmcneill .u.composite.muxdiv_reg = (_muxdiv_reg), \ 308 1.1 jmcneill .u.composite.mux_mask = (_mux_mask), \ 309 1.1 jmcneill .u.composite.div_mask = (_div_mask), \ 310 1.1 jmcneill .u.composite.gate_reg = (_gate_reg), \ 311 1.1 jmcneill .u.composite.gate_mask = (_gate_mask), \ 312 1.7 jmcneill .u.composite.frac_reg = (_frac_reg), \ 313 1.1 jmcneill .u.composite.flags = (_flags), \ 314 1.1 jmcneill .enable = rk_cru_composite_enable, \ 315 1.1 jmcneill .get_rate = rk_cru_composite_get_rate, \ 316 1.1 jmcneill .set_rate = rk_cru_composite_set_rate, \ 317 1.1 jmcneill .get_parent = rk_cru_composite_get_parent, \ 318 1.1 jmcneill .set_parent = rk_cru_composite_set_parent, \ 319 1.1 jmcneill } 320 1.1 jmcneill 321 1.7 jmcneill #define RK_COMPOSITE(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, _flags) \ 322 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, 0, _flags) 323 1.7 jmcneill 324 1.11 ryo #define RK_COMPOSITE_HALF(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, _flags) \ 325 1.11 ryo _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _gate_reg, _gate_mask, 0, (_flags) | RK_COMPOSITE_HALFDIV) 326 1.11 ryo 327 1.3 jmcneill #define RK_COMPOSITE_NOMUX(_id, _name, _parent, _div_reg, _div_mask, _gate_reg, _gate_mask, _flags) \ 328 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, (const char *[]){ _parent }, _div_reg, 0, _div_mask, _gate_reg, _gate_mask, 0, _flags) 329 1.3 jmcneill 330 1.11 ryo #define RK_COMPOSITE_NODIV(_id, _name, _parents, _muxdiv_reg, _mux_mask, _gate_reg, _gate_mask, _flags) \ 331 1.11 ryo _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, 0, _gate_reg, _gate_mask, 0, _flags) 332 1.11 ryo 333 1.3 jmcneill #define RK_COMPOSITE_NOGATE(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, _flags) \ 334 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, _parents, _muxdiv_reg, _mux_mask, _div_mask, 0, 0, 0, _flags) 335 1.7 jmcneill 336 1.7 jmcneill #define RK_COMPOSITE_FRAC(_id, _name, _parent, _frac_reg, _flags) \ 337 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, (const char *[]){ _parent }, 0, 0, 0, 0, 0, _frac_reg, (_flags) | RK_COMPOSITE_FRACDIV) 338 1.3 jmcneill 339 1.3 jmcneill #define RK_DIV(_id, _name, _parent, _div_reg, _div_mask, _flags) \ 340 1.7 jmcneill _RK_COMPOSITE_INIT(_id, _name, (const char *[]){ _parent }, _div_reg, 0, _div_mask, 0, 0, 0, _flags) 341 1.3 jmcneill 342 1.1 jmcneill /* Gate clocks */ 343 1.1 jmcneill 344 1.1 jmcneill struct rk_cru_gate { 345 1.1 jmcneill bus_size_t reg; 346 1.1 jmcneill uint32_t mask; 347 1.1 jmcneill const char *parent; 348 1.1 jmcneill }; 349 1.1 jmcneill 350 1.1 jmcneill int rk_cru_gate_enable(struct rk_cru_softc *, 351 1.1 jmcneill struct rk_cru_clk *, int); 352 1.1 jmcneill const char *rk_cru_gate_get_parent(struct rk_cru_softc *, 353 1.1 jmcneill struct rk_cru_clk *); 354 1.1 jmcneill 355 1.1 jmcneill #define RK_GATE(_id, _name, _pname, _reg, _bit) \ 356 1.1 jmcneill { \ 357 1.1 jmcneill .id = (_id), \ 358 1.1 jmcneill .type = RK_CRU_GATE, \ 359 1.1 jmcneill .base.name = (_name), \ 360 1.1 jmcneill .base.flags = CLK_SET_RATE_PARENT, \ 361 1.1 jmcneill .u.gate.parent = (_pname), \ 362 1.1 jmcneill .u.gate.reg = (_reg), \ 363 1.1 jmcneill .u.gate.mask = __BIT(_bit), \ 364 1.1 jmcneill .enable = rk_cru_gate_enable, \ 365 1.1 jmcneill .get_parent = rk_cru_gate_get_parent, \ 366 1.1 jmcneill } 367 1.1 jmcneill 368 1.5 tnn #define RK_SECURE_GATE(_id, _name, _pname) \ 369 1.5 tnn { \ 370 1.5 tnn .id = (_id), \ 371 1.5 tnn .type = RK_CRU_GATE, \ 372 1.5 tnn .base.name = (_name), \ 373 1.5 tnn .u.gate.parent = (_pname), \ 374 1.5 tnn .get_parent = rk_cru_gate_get_parent, \ 375 1.5 tnn } 376 1.5 tnn 377 1.1 jmcneill /* Mux clocks */ 378 1.1 jmcneill 379 1.1 jmcneill struct rk_cru_mux { 380 1.1 jmcneill bus_size_t reg; 381 1.1 jmcneill uint32_t mask; 382 1.1 jmcneill const char **parents; 383 1.1 jmcneill u_int nparents; 384 1.1 jmcneill u_int flags; 385 1.1 jmcneill #define RK_MUX_GRF 0x01 386 1.1 jmcneill }; 387 1.1 jmcneill 388 1.1 jmcneill const char *rk_cru_mux_get_parent(struct rk_cru_softc *, struct rk_cru_clk *); 389 1.1 jmcneill int rk_cru_mux_set_parent(struct rk_cru_softc *, struct rk_cru_clk *, const char *); 390 1.1 jmcneill 391 1.1 jmcneill #define RK_MUX_FLAGS(_id, _name, _parents, _reg, _mask, _flags) \ 392 1.1 jmcneill { \ 393 1.1 jmcneill .id = (_id), \ 394 1.1 jmcneill .type = RK_CRU_MUX, \ 395 1.1 jmcneill .base.name = (_name), \ 396 1.1 jmcneill .base.flags = CLK_SET_RATE_PARENT, \ 397 1.1 jmcneill .u.mux.parents = (_parents), \ 398 1.1 jmcneill .u.mux.nparents = __arraycount(_parents), \ 399 1.1 jmcneill .u.mux.reg = (_reg), \ 400 1.1 jmcneill .u.mux.mask = (_mask), \ 401 1.1 jmcneill .u.mux.flags = (_flags), \ 402 1.1 jmcneill .set_parent = rk_cru_mux_set_parent, \ 403 1.1 jmcneill .get_parent = rk_cru_mux_get_parent, \ 404 1.1 jmcneill } 405 1.1 jmcneill #define RK_MUX(_id, _name, _parents, _reg, _mask) \ 406 1.1 jmcneill RK_MUX_FLAGS(_id, _name, _parents, _reg, _mask, 0) 407 1.1 jmcneill #define RK_MUXGRF(_id, _name, _parents, _reg, _mask) \ 408 1.1 jmcneill RK_MUX_FLAGS(_id, _name, _parents, _reg, _mask, RK_MUX_GRF) 409 1.1 jmcneill 410 1.1 jmcneill /* 411 1.1 jmcneill * Rockchip clock definition 412 1.1 jmcneill */ 413 1.1 jmcneill 414 1.1 jmcneill struct rk_cru_clk { 415 1.1 jmcneill struct clk base; 416 1.1 jmcneill u_int id; 417 1.1 jmcneill enum rk_cru_clktype type; 418 1.1 jmcneill union { 419 1.1 jmcneill struct rk_cru_pll pll; 420 1.1 jmcneill struct rk_cru_arm arm; 421 1.1 jmcneill struct rk_cru_composite composite; 422 1.1 jmcneill struct rk_cru_gate gate; 423 1.1 jmcneill struct rk_cru_mux mux; 424 1.1 jmcneill } u; 425 1.1 jmcneill 426 1.1 jmcneill int (*enable)(struct rk_cru_softc *, 427 1.1 jmcneill struct rk_cru_clk *, int); 428 1.1 jmcneill u_int (*get_rate)(struct rk_cru_softc *, 429 1.1 jmcneill struct rk_cru_clk *); 430 1.1 jmcneill int (*set_rate)(struct rk_cru_softc *, 431 1.1 jmcneill struct rk_cru_clk *, u_int); 432 1.1 jmcneill u_int (*round_rate)(struct rk_cru_softc *, 433 1.1 jmcneill struct rk_cru_clk *, u_int); 434 1.1 jmcneill const char * (*get_parent)(struct rk_cru_softc *, 435 1.1 jmcneill struct rk_cru_clk *); 436 1.1 jmcneill int (*set_parent)(struct rk_cru_softc *, 437 1.1 jmcneill struct rk_cru_clk *, 438 1.1 jmcneill const char *); 439 1.1 jmcneill }; 440 1.1 jmcneill 441 1.1 jmcneill /* 442 1.1 jmcneill * Driver state 443 1.1 jmcneill */ 444 1.1 jmcneill 445 1.1 jmcneill struct rk_cru_softc { 446 1.1 jmcneill device_t sc_dev; 447 1.1 jmcneill int sc_phandle; 448 1.1 jmcneill bus_space_tag_t sc_bst; 449 1.1 jmcneill bus_space_handle_t sc_bsh; 450 1.2 jmcneill struct syscon *sc_grf; 451 1.1 jmcneill 452 1.1 jmcneill struct clk_domain sc_clkdom; 453 1.1 jmcneill 454 1.1 jmcneill struct rk_cru_clk *sc_clks; 455 1.1 jmcneill u_int sc_nclks; 456 1.3 jmcneill 457 1.8 jmcneill bus_size_t sc_grf_soc_status; /* for PLL lock */ 458 1.3 jmcneill bus_size_t sc_softrst_base; 459 1.1 jmcneill }; 460 1.1 jmcneill 461 1.1 jmcneill int rk_cru_attach(struct rk_cru_softc *); 462 1.1 jmcneill struct rk_cru_clk *rk_cru_clock_find(struct rk_cru_softc *, 463 1.1 jmcneill const char *); 464 1.1 jmcneill void rk_cru_print(struct rk_cru_softc *); 465 1.1 jmcneill 466 1.1 jmcneill #define CRU_READ(sc, reg) \ 467 1.1 jmcneill bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 468 1.1 jmcneill #define CRU_WRITE(sc, reg, val) \ 469 1.1 jmcneill bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 470 1.1 jmcneill 471 1.2 jmcneill #define HAS_GRF(sc) ((sc)->sc_grf != NULL) 472 1.1 jmcneill 473 1.1 jmcneill #endif /* _ARM_RK_CRU_H */ 474