1 1.24 macallan /* $NetBSD: sunxi_ccu.h,v 1.24 2024/09/16 23:37:13 macallan Exp $ */ 2 1.1 jmcneill 3 1.1 jmcneill /*- 4 1.1 jmcneill * Copyright (c) 2017 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_SUNXI_CCU_H 30 1.1 jmcneill #define _ARM_SUNXI_CCU_H 31 1.1 jmcneill 32 1.1 jmcneill #include <dev/clk/clk_backend.h> 33 1.1 jmcneill 34 1.1 jmcneill struct sunxi_ccu_softc; 35 1.1 jmcneill struct sunxi_ccu_clk; 36 1.1 jmcneill struct sunxi_ccu_reset; 37 1.1 jmcneill 38 1.1 jmcneill /* 39 1.1 jmcneill * Resets 40 1.1 jmcneill */ 41 1.1 jmcneill 42 1.1 jmcneill struct sunxi_ccu_reset { 43 1.1 jmcneill bus_size_t reg; 44 1.1 jmcneill uint32_t mask; 45 1.1 jmcneill }; 46 1.1 jmcneill 47 1.1 jmcneill #define SUNXI_CCU_RESET(_id, _reg, _bit) \ 48 1.1 jmcneill [_id] = { \ 49 1.1 jmcneill .reg = (_reg), \ 50 1.1 jmcneill .mask = __BIT(_bit), \ 51 1.1 jmcneill } 52 1.1 jmcneill 53 1.1 jmcneill /* 54 1.1 jmcneill * Clocks 55 1.1 jmcneill */ 56 1.1 jmcneill 57 1.1 jmcneill enum sunxi_ccu_clktype { 58 1.1 jmcneill SUNXI_CCU_UNKNOWN, 59 1.1 jmcneill SUNXI_CCU_GATE, 60 1.1 jmcneill SUNXI_CCU_NM, 61 1.2 jmcneill SUNXI_CCU_NKMP, 62 1.2 jmcneill SUNXI_CCU_PREDIV, 63 1.5 jmcneill SUNXI_CCU_DIV, 64 1.7 jmcneill SUNXI_CCU_PHASE, 65 1.11 jmcneill SUNXI_CCU_FIXED_FACTOR, 66 1.16 bouyer SUNXI_CCU_FRACTIONAL, 67 1.23 jmcneill SUNXI_CCU_MUX, 68 1.1 jmcneill }; 69 1.1 jmcneill 70 1.1 jmcneill struct sunxi_ccu_gate { 71 1.1 jmcneill bus_size_t reg; 72 1.1 jmcneill uint32_t mask; 73 1.1 jmcneill const char *parent; 74 1.1 jmcneill }; 75 1.1 jmcneill 76 1.1 jmcneill int sunxi_ccu_gate_enable(struct sunxi_ccu_softc *, 77 1.1 jmcneill struct sunxi_ccu_clk *, int); 78 1.1 jmcneill const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *, 79 1.1 jmcneill struct sunxi_ccu_clk *); 80 1.1 jmcneill 81 1.1 jmcneill #define SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit) \ 82 1.1 jmcneill [_id] = { \ 83 1.1 jmcneill .type = SUNXI_CCU_GATE, \ 84 1.1 jmcneill .base.name = (_name), \ 85 1.8 jmcneill .base.flags = CLK_SET_RATE_PARENT, \ 86 1.1 jmcneill .u.gate.parent = (_pname), \ 87 1.1 jmcneill .u.gate.reg = (_reg), \ 88 1.1 jmcneill .u.gate.mask = __BIT(_bit), \ 89 1.1 jmcneill .enable = sunxi_ccu_gate_enable, \ 90 1.1 jmcneill .get_parent = sunxi_ccu_gate_get_parent, \ 91 1.1 jmcneill } 92 1.1 jmcneill 93 1.8 jmcneill struct sunxi_ccu_nkmp_tbl { 94 1.8 jmcneill u_int rate; 95 1.8 jmcneill uint32_t n; 96 1.8 jmcneill uint32_t k; 97 1.8 jmcneill uint32_t m; 98 1.8 jmcneill uint32_t p; 99 1.8 jmcneill }; 100 1.8 jmcneill 101 1.2 jmcneill struct sunxi_ccu_nkmp { 102 1.2 jmcneill bus_size_t reg; 103 1.2 jmcneill const char *parent; 104 1.2 jmcneill uint32_t n; 105 1.2 jmcneill uint32_t k; 106 1.2 jmcneill uint32_t m; 107 1.2 jmcneill uint32_t p; 108 1.2 jmcneill uint32_t lock; 109 1.2 jmcneill uint32_t enable; 110 1.2 jmcneill uint32_t flags; 111 1.8 jmcneill const struct sunxi_ccu_nkmp_tbl *table; 112 1.13 jmcneill #define SUNXI_CCU_NKMP_DIVIDE_BY_TWO __BIT(0) 113 1.13 jmcneill #define SUNXI_CCU_NKMP_FACTOR_N_EXACT __BIT(1) 114 1.13 jmcneill #define SUNXI_CCU_NKMP_SCALE_CLOCK __BIT(2) 115 1.13 jmcneill #define SUNXI_CCU_NKMP_FACTOR_P_POW2 __BIT(3) 116 1.13 jmcneill #define SUNXI_CCU_NKMP_FACTOR_N_ZERO_IS_ONE __BIT(4) 117 1.19 jmcneill #define SUNXI_CCU_NKMP_FACTOR_P_X4 __BIT(5) 118 1.2 jmcneill }; 119 1.2 jmcneill 120 1.2 jmcneill int sunxi_ccu_nkmp_enable(struct sunxi_ccu_softc *, 121 1.2 jmcneill struct sunxi_ccu_clk *, int); 122 1.2 jmcneill u_int sunxi_ccu_nkmp_get_rate(struct sunxi_ccu_softc *, 123 1.2 jmcneill struct sunxi_ccu_clk *); 124 1.2 jmcneill int sunxi_ccu_nkmp_set_rate(struct sunxi_ccu_softc *, 125 1.2 jmcneill struct sunxi_ccu_clk *, u_int); 126 1.2 jmcneill const char *sunxi_ccu_nkmp_get_parent(struct sunxi_ccu_softc *, 127 1.2 jmcneill struct sunxi_ccu_clk *); 128 1.2 jmcneill 129 1.8 jmcneill #define SUNXI_CCU_NKMP_TABLE(_id, _name, _parent, _reg, _n, _k, _m, \ 130 1.8 jmcneill _p, _enable, _lock, _tbl, _flags) \ 131 1.2 jmcneill [_id] = { \ 132 1.2 jmcneill .type = SUNXI_CCU_NKMP, \ 133 1.2 jmcneill .base.name = (_name), \ 134 1.2 jmcneill .u.nkmp.reg = (_reg), \ 135 1.2 jmcneill .u.nkmp.parent = (_parent), \ 136 1.2 jmcneill .u.nkmp.n = (_n), \ 137 1.2 jmcneill .u.nkmp.k = (_k), \ 138 1.2 jmcneill .u.nkmp.m = (_m), \ 139 1.2 jmcneill .u.nkmp.p = (_p), \ 140 1.2 jmcneill .u.nkmp.enable = (_enable), \ 141 1.2 jmcneill .u.nkmp.flags = (_flags), \ 142 1.8 jmcneill .u.nkmp.lock = (_lock), \ 143 1.8 jmcneill .u.nkmp.table = (_tbl), \ 144 1.2 jmcneill .enable = sunxi_ccu_nkmp_enable, \ 145 1.2 jmcneill .get_rate = sunxi_ccu_nkmp_get_rate, \ 146 1.2 jmcneill .set_rate = sunxi_ccu_nkmp_set_rate, \ 147 1.2 jmcneill .get_parent = sunxi_ccu_nkmp_get_parent, \ 148 1.2 jmcneill } 149 1.2 jmcneill 150 1.8 jmcneill #define SUNXI_CCU_NKMP(_id, _name, _parent, _reg, _n, _k, _m, \ 151 1.8 jmcneill _p, _enable, _flags) \ 152 1.8 jmcneill SUNXI_CCU_NKMP_TABLE(_id, _name, _parent, _reg, _n, _k, _m, \ 153 1.8 jmcneill _p, _enable, 0, NULL, _flags) 154 1.8 jmcneill 155 1.8 jmcneill 156 1.1 jmcneill struct sunxi_ccu_nm { 157 1.1 jmcneill bus_size_t reg; 158 1.1 jmcneill const char **parents; 159 1.1 jmcneill u_int nparents; 160 1.1 jmcneill uint32_t n; 161 1.1 jmcneill uint32_t m; 162 1.1 jmcneill uint32_t sel; 163 1.2 jmcneill uint32_t enable; 164 1.1 jmcneill uint32_t flags; 165 1.1 jmcneill #define SUNXI_CCU_NM_POWER_OF_TWO __BIT(0) 166 1.2 jmcneill #define SUNXI_CCU_NM_ROUND_DOWN __BIT(1) 167 1.15 jmcneill #define SUNXI_CCU_NM_DIVIDE_BY_TWO __BIT(2) 168 1.1 jmcneill }; 169 1.1 jmcneill 170 1.2 jmcneill int sunxi_ccu_nm_enable(struct sunxi_ccu_softc *, 171 1.2 jmcneill struct sunxi_ccu_clk *, int); 172 1.1 jmcneill u_int sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *, 173 1.1 jmcneill struct sunxi_ccu_clk *); 174 1.1 jmcneill int sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *, 175 1.1 jmcneill struct sunxi_ccu_clk *, u_int); 176 1.1 jmcneill int sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *, 177 1.1 jmcneill struct sunxi_ccu_clk *, 178 1.1 jmcneill const char *); 179 1.1 jmcneill const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *, 180 1.1 jmcneill struct sunxi_ccu_clk *); 181 1.1 jmcneill 182 1.1 jmcneill #define SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel, \ 183 1.2 jmcneill _enable, _flags) \ 184 1.1 jmcneill [_id] = { \ 185 1.1 jmcneill .type = SUNXI_CCU_NM, \ 186 1.1 jmcneill .base.name = (_name), \ 187 1.1 jmcneill .u.nm.reg = (_reg), \ 188 1.1 jmcneill .u.nm.parents = (_parents), \ 189 1.1 jmcneill .u.nm.nparents = __arraycount(_parents), \ 190 1.1 jmcneill .u.nm.n = (_n), \ 191 1.1 jmcneill .u.nm.m = (_m), \ 192 1.1 jmcneill .u.nm.sel = (_sel), \ 193 1.2 jmcneill .u.nm.enable = (_enable), \ 194 1.1 jmcneill .u.nm.flags = (_flags), \ 195 1.2 jmcneill .enable = sunxi_ccu_nm_enable, \ 196 1.2 jmcneill .get_rate = sunxi_ccu_nm_get_rate, \ 197 1.2 jmcneill .set_rate = sunxi_ccu_nm_set_rate, \ 198 1.1 jmcneill .set_parent = sunxi_ccu_nm_set_parent, \ 199 1.1 jmcneill .get_parent = sunxi_ccu_nm_get_parent, \ 200 1.1 jmcneill } 201 1.1 jmcneill 202 1.5 jmcneill struct sunxi_ccu_div { 203 1.5 jmcneill bus_size_t reg; 204 1.5 jmcneill const char **parents; 205 1.5 jmcneill u_int nparents; 206 1.5 jmcneill uint32_t div; 207 1.5 jmcneill uint32_t sel; 208 1.12 jmcneill uint32_t enable; 209 1.5 jmcneill uint32_t flags; 210 1.5 jmcneill #define SUNXI_CCU_DIV_POWER_OF_TWO __BIT(0) 211 1.5 jmcneill #define SUNXI_CCU_DIV_ZERO_IS_ONE __BIT(1) 212 1.12 jmcneill #define SUNXI_CCU_DIV_TIMES_TWO __BIT(2) 213 1.14 jmcneill #define SUNXI_CCU_DIV_SET_RATE_PARENT __BIT(3) 214 1.5 jmcneill }; 215 1.5 jmcneill 216 1.12 jmcneill int sunxi_ccu_div_enable(struct sunxi_ccu_softc *, 217 1.12 jmcneill struct sunxi_ccu_clk *, int); 218 1.5 jmcneill u_int sunxi_ccu_div_get_rate(struct sunxi_ccu_softc *, 219 1.5 jmcneill struct sunxi_ccu_clk *); 220 1.5 jmcneill int sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *, 221 1.5 jmcneill struct sunxi_ccu_clk *, u_int); 222 1.5 jmcneill int sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *, 223 1.5 jmcneill struct sunxi_ccu_clk *, 224 1.5 jmcneill const char *); 225 1.5 jmcneill const char *sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *, 226 1.5 jmcneill struct sunxi_ccu_clk *); 227 1.5 jmcneill 228 1.5 jmcneill #define SUNXI_CCU_DIV(_id, _name, _parents, _reg, _div, \ 229 1.5 jmcneill _sel, _flags) \ 230 1.12 jmcneill SUNXI_CCU_DIV_GATE(_id, _name, _parents, _reg, _div, \ 231 1.12 jmcneill _sel, 0, _flags) 232 1.12 jmcneill 233 1.12 jmcneill #define SUNXI_CCU_DIV_GATE(_id, _name, _parents, _reg, _div, \ 234 1.12 jmcneill _sel, _enable, _flags) \ 235 1.5 jmcneill [_id] = { \ 236 1.5 jmcneill .type = SUNXI_CCU_DIV, \ 237 1.5 jmcneill .base.name = (_name), \ 238 1.5 jmcneill .u.div.reg = (_reg), \ 239 1.5 jmcneill .u.div.parents = (_parents), \ 240 1.5 jmcneill .u.div.nparents = __arraycount(_parents), \ 241 1.5 jmcneill .u.div.div = (_div), \ 242 1.5 jmcneill .u.div.sel = (_sel), \ 243 1.12 jmcneill .u.div.enable = (_enable), \ 244 1.5 jmcneill .u.div.flags = (_flags), \ 245 1.12 jmcneill .enable = sunxi_ccu_div_enable, \ 246 1.5 jmcneill .get_rate = sunxi_ccu_div_get_rate, \ 247 1.5 jmcneill .set_rate = sunxi_ccu_div_set_rate, \ 248 1.5 jmcneill .set_parent = sunxi_ccu_div_set_parent, \ 249 1.5 jmcneill .get_parent = sunxi_ccu_div_get_parent, \ 250 1.5 jmcneill } 251 1.5 jmcneill 252 1.17 bouyer /* special case of the div model for display clocks */ 253 1.17 bouyer int sunxi_ccu_lcdxch0_set_rate(struct sunxi_ccu_softc *, 254 1.17 bouyer struct sunxi_ccu_clk *, struct sunxi_ccu_clk *, 255 1.17 bouyer struct sunxi_ccu_clk *, u_int); 256 1.17 bouyer u_int sunxi_ccu_lcdxch0_round_rate(struct sunxi_ccu_softc *, 257 1.17 bouyer struct sunxi_ccu_clk *, struct sunxi_ccu_clk *, 258 1.17 bouyer struct sunxi_ccu_clk *, u_int); 259 1.17 bouyer 260 1.17 bouyer int sunxi_ccu_lcdxch1_set_rate(struct sunxi_ccu_softc *sc, 261 1.17 bouyer struct sunxi_ccu_clk *clk, struct sunxi_ccu_clk *pclk, 262 1.17 bouyer struct sunxi_ccu_clk *pclk_x2, u_int); 263 1.17 bouyer 264 1.2 jmcneill struct sunxi_ccu_prediv { 265 1.2 jmcneill bus_size_t reg; 266 1.2 jmcneill const char **parents; 267 1.2 jmcneill u_int nparents; 268 1.2 jmcneill uint32_t prediv; 269 1.2 jmcneill uint32_t prediv_sel; 270 1.10 jmcneill uint32_t prediv_fixed; 271 1.2 jmcneill uint32_t div; 272 1.2 jmcneill uint32_t sel; 273 1.2 jmcneill uint32_t flags; 274 1.2 jmcneill #define SUNXI_CCU_PREDIV_POWER_OF_TWO __BIT(0) 275 1.4 jmcneill #define SUNXI_CCU_PREDIV_DIVIDE_BY_TWO __BIT(1) 276 1.2 jmcneill }; 277 1.2 jmcneill 278 1.2 jmcneill u_int sunxi_ccu_prediv_get_rate(struct sunxi_ccu_softc *, 279 1.2 jmcneill struct sunxi_ccu_clk *); 280 1.2 jmcneill int sunxi_ccu_prediv_set_rate(struct sunxi_ccu_softc *, 281 1.2 jmcneill struct sunxi_ccu_clk *, u_int); 282 1.2 jmcneill int sunxi_ccu_prediv_set_parent(struct sunxi_ccu_softc *, 283 1.2 jmcneill struct sunxi_ccu_clk *, 284 1.2 jmcneill const char *); 285 1.2 jmcneill const char *sunxi_ccu_prediv_get_parent(struct sunxi_ccu_softc *, 286 1.2 jmcneill struct sunxi_ccu_clk *); 287 1.2 jmcneill 288 1.2 jmcneill #define SUNXI_CCU_PREDIV(_id, _name, _parents, _reg, _prediv, \ 289 1.2 jmcneill _prediv_sel, _div, _sel, _flags) \ 290 1.10 jmcneill SUNXI_CCU_PREDIV_FIXED(_id, _name, _parents, _reg, _prediv, \ 291 1.10 jmcneill _prediv_sel, 0, _div, _sel, _flags) 292 1.10 jmcneill 293 1.10 jmcneill #define SUNXI_CCU_PREDIV_FIXED(_id, _name, _parents, _reg, _prediv, \ 294 1.10 jmcneill _prediv_sel, _prediv_fixed, _div, _sel, _flags) \ 295 1.2 jmcneill [_id] = { \ 296 1.2 jmcneill .type = SUNXI_CCU_PREDIV, \ 297 1.2 jmcneill .base.name = (_name), \ 298 1.2 jmcneill .u.prediv.reg = (_reg), \ 299 1.2 jmcneill .u.prediv.parents = (_parents), \ 300 1.2 jmcneill .u.prediv.nparents = __arraycount(_parents), \ 301 1.2 jmcneill .u.prediv.prediv = (_prediv), \ 302 1.2 jmcneill .u.prediv.prediv_sel = (_prediv_sel), \ 303 1.10 jmcneill .u.prediv.prediv_fixed = (_prediv_fixed), \ 304 1.2 jmcneill .u.prediv.div = (_div), \ 305 1.2 jmcneill .u.prediv.sel = (_sel), \ 306 1.2 jmcneill .u.prediv.flags = (_flags), \ 307 1.2 jmcneill .get_rate = sunxi_ccu_prediv_get_rate, \ 308 1.2 jmcneill .set_rate = sunxi_ccu_prediv_set_rate, \ 309 1.2 jmcneill .set_parent = sunxi_ccu_prediv_set_parent, \ 310 1.2 jmcneill .get_parent = sunxi_ccu_prediv_get_parent, \ 311 1.2 jmcneill } 312 1.2 jmcneill 313 1.7 jmcneill struct sunxi_ccu_phase { 314 1.7 jmcneill bus_size_t reg; 315 1.7 jmcneill const char *parent; 316 1.7 jmcneill uint32_t mask; 317 1.7 jmcneill }; 318 1.7 jmcneill 319 1.7 jmcneill u_int sunxi_ccu_phase_get_rate(struct sunxi_ccu_softc *, 320 1.7 jmcneill struct sunxi_ccu_clk *); 321 1.7 jmcneill int sunxi_ccu_phase_set_rate(struct sunxi_ccu_softc *, 322 1.7 jmcneill struct sunxi_ccu_clk *, u_int); 323 1.7 jmcneill const char *sunxi_ccu_phase_get_parent(struct sunxi_ccu_softc *, 324 1.7 jmcneill struct sunxi_ccu_clk *); 325 1.7 jmcneill 326 1.7 jmcneill #define SUNXI_CCU_PHASE(_id, _name, _parent, _reg, _mask) \ 327 1.7 jmcneill [_id] = { \ 328 1.7 jmcneill .type = SUNXI_CCU_PHASE, \ 329 1.7 jmcneill .base.name = (_name), \ 330 1.7 jmcneill .u.phase.reg = (_reg), \ 331 1.7 jmcneill .u.phase.parent = (_parent), \ 332 1.7 jmcneill .u.phase.mask = (_mask), \ 333 1.7 jmcneill .get_rate = sunxi_ccu_phase_get_rate, \ 334 1.7 jmcneill .set_rate = sunxi_ccu_phase_set_rate, \ 335 1.7 jmcneill .get_parent = sunxi_ccu_phase_get_parent, \ 336 1.7 jmcneill } 337 1.7 jmcneill 338 1.11 jmcneill struct sunxi_ccu_fixed_factor { 339 1.11 jmcneill const char *parent; 340 1.11 jmcneill u_int div; 341 1.11 jmcneill u_int mult; 342 1.11 jmcneill }; 343 1.11 jmcneill 344 1.11 jmcneill u_int sunxi_ccu_fixed_factor_get_rate(struct sunxi_ccu_softc *, 345 1.11 jmcneill struct sunxi_ccu_clk *); 346 1.18 jmcneill int sunxi_ccu_fixed_factor_set_rate(struct sunxi_ccu_softc *, 347 1.18 jmcneill struct sunxi_ccu_clk *, u_int); 348 1.11 jmcneill const char *sunxi_ccu_fixed_factor_get_parent(struct sunxi_ccu_softc *, 349 1.11 jmcneill struct sunxi_ccu_clk *); 350 1.11 jmcneill 351 1.11 jmcneill #define SUNXI_CCU_FIXED_FACTOR(_id, _name, _parent, _div, _mult) \ 352 1.11 jmcneill [_id] = { \ 353 1.11 jmcneill .type = SUNXI_CCU_FIXED_FACTOR, \ 354 1.11 jmcneill .base.name = (_name), \ 355 1.11 jmcneill .u.fixed_factor.parent = (_parent), \ 356 1.11 jmcneill .u.fixed_factor.div = (_div), \ 357 1.11 jmcneill .u.fixed_factor.mult = (_mult), \ 358 1.11 jmcneill .get_rate = sunxi_ccu_fixed_factor_get_rate, \ 359 1.11 jmcneill .get_parent = sunxi_ccu_fixed_factor_get_parent, \ 360 1.18 jmcneill .set_rate = sunxi_ccu_fixed_factor_set_rate, \ 361 1.11 jmcneill } 362 1.11 jmcneill 363 1.16 bouyer struct sunxi_ccu_fractional { 364 1.16 bouyer bus_size_t reg; 365 1.16 bouyer const char *parent; 366 1.16 bouyer uint32_t m; 367 1.16 bouyer uint32_t m_min; 368 1.16 bouyer uint32_t m_max; 369 1.17 bouyer uint32_t div_en; 370 1.16 bouyer uint32_t frac_sel; 371 1.16 bouyer uint32_t frac[2]; 372 1.16 bouyer uint32_t prediv; 373 1.20 jmcneill uint32_t prediv_val; 374 1.16 bouyer uint32_t enable; 375 1.20 jmcneill uint32_t flags; 376 1.20 jmcneill #define SUNXI_CCU_FRACTIONAL_PLUSONE __BIT(0) 377 1.21 jmcneill #define SUNXI_CCU_FRACTIONAL_SET_ENABLE __BIT(1) 378 1.16 bouyer }; 379 1.16 bouyer 380 1.16 bouyer int sunxi_ccu_fractional_enable(struct sunxi_ccu_softc *, 381 1.16 bouyer struct sunxi_ccu_clk *, int); 382 1.16 bouyer u_int sunxi_ccu_fractional_get_rate(struct sunxi_ccu_softc *, 383 1.16 bouyer struct sunxi_ccu_clk *); 384 1.16 bouyer int sunxi_ccu_fractional_set_rate(struct sunxi_ccu_softc *, 385 1.16 bouyer struct sunxi_ccu_clk *, u_int); 386 1.17 bouyer u_int sunxi_ccu_fractional_round_rate(struct sunxi_ccu_softc *, 387 1.17 bouyer struct sunxi_ccu_clk *, u_int); 388 1.16 bouyer const char *sunxi_ccu_fractional_get_parent(struct sunxi_ccu_softc *, 389 1.16 bouyer struct sunxi_ccu_clk *); 390 1.16 bouyer 391 1.16 bouyer #define SUNXI_CCU_FRACTIONAL(_id, _name, _parent, _reg, _m, _m_min, _m_max, \ 392 1.20 jmcneill _div_en, _frac_sel, _frac0, _frac1, _prediv, _prediv_val, \ 393 1.20 jmcneill _enable, _flags) \ 394 1.16 bouyer [_id] = { \ 395 1.16 bouyer .type = SUNXI_CCU_FRACTIONAL, \ 396 1.16 bouyer .base.name = (_name), \ 397 1.16 bouyer .u.fractional.reg = (_reg), \ 398 1.16 bouyer .u.fractional.parent = (_parent), \ 399 1.16 bouyer .u.fractional.m = (_m), \ 400 1.16 bouyer .u.fractional.m_min = (_m_min), \ 401 1.16 bouyer .u.fractional.m_max = (_m_max), \ 402 1.16 bouyer .u.fractional.prediv = (_prediv), \ 403 1.20 jmcneill .u.fractional.prediv_val = (_prediv_val), \ 404 1.17 bouyer .u.fractional.div_en = (_div_en), \ 405 1.16 bouyer .u.fractional.frac_sel = (_frac_sel), \ 406 1.16 bouyer .u.fractional.frac[0] = (_frac0), \ 407 1.16 bouyer .u.fractional.frac[1] = (_frac1), \ 408 1.16 bouyer .u.fractional.enable = (_enable), \ 409 1.22 jakllsch .u.fractional.flags = (_flags), \ 410 1.16 bouyer .enable = sunxi_ccu_fractional_enable, \ 411 1.16 bouyer .get_rate = sunxi_ccu_fractional_get_rate, \ 412 1.16 bouyer .set_rate = sunxi_ccu_fractional_set_rate, \ 413 1.17 bouyer .round_rate = sunxi_ccu_fractional_round_rate, \ 414 1.16 bouyer .get_parent = sunxi_ccu_fractional_get_parent, \ 415 1.16 bouyer } 416 1.16 bouyer 417 1.23 jmcneill struct sunxi_ccu_mux { 418 1.23 jmcneill bus_size_t reg; 419 1.23 jmcneill const char **parents; 420 1.23 jmcneill u_int nparents; 421 1.23 jmcneill uint32_t sel; 422 1.23 jmcneill uint32_t flags; 423 1.23 jmcneill }; 424 1.23 jmcneill 425 1.23 jmcneill int sunxi_ccu_mux_set_parent(struct sunxi_ccu_softc *, 426 1.23 jmcneill struct sunxi_ccu_clk *, 427 1.23 jmcneill const char *); 428 1.23 jmcneill const char *sunxi_ccu_mux_get_parent(struct sunxi_ccu_softc *, 429 1.23 jmcneill struct sunxi_ccu_clk *); 430 1.23 jmcneill 431 1.23 jmcneill #define SUNXI_CCU_MUX(_id, _name, _parents, _reg, _sel, _flags) \ 432 1.23 jmcneill [_id] = { \ 433 1.23 jmcneill .type = SUNXI_CCU_MUX, \ 434 1.23 jmcneill .base.name = (_name), \ 435 1.24 macallan .base.flags = CLK_SET_RATE_PARENT, \ 436 1.23 jmcneill .u.mux.reg = (_reg), \ 437 1.23 jmcneill .u.mux.parents = (_parents), \ 438 1.23 jmcneill .u.mux.nparents = __arraycount(_parents), \ 439 1.23 jmcneill .u.mux.sel = (_sel), \ 440 1.23 jmcneill .u.mux.flags = (_flags), \ 441 1.23 jmcneill .set_parent = sunxi_ccu_mux_set_parent, \ 442 1.23 jmcneill .get_parent = sunxi_ccu_mux_get_parent, \ 443 1.23 jmcneill } 444 1.23 jmcneill 445 1.23 jmcneill 446 1.1 jmcneill struct sunxi_ccu_clk { 447 1.1 jmcneill struct clk base; 448 1.1 jmcneill enum sunxi_ccu_clktype type; 449 1.1 jmcneill union { 450 1.1 jmcneill struct sunxi_ccu_gate gate; 451 1.1 jmcneill struct sunxi_ccu_nm nm; 452 1.2 jmcneill struct sunxi_ccu_nkmp nkmp; 453 1.2 jmcneill struct sunxi_ccu_prediv prediv; 454 1.5 jmcneill struct sunxi_ccu_div div; 455 1.7 jmcneill struct sunxi_ccu_phase phase; 456 1.11 jmcneill struct sunxi_ccu_fixed_factor fixed_factor; 457 1.16 bouyer struct sunxi_ccu_fractional fractional; 458 1.23 jmcneill struct sunxi_ccu_mux mux; 459 1.1 jmcneill } u; 460 1.1 jmcneill 461 1.1 jmcneill int (*enable)(struct sunxi_ccu_softc *, 462 1.1 jmcneill struct sunxi_ccu_clk *, int); 463 1.1 jmcneill u_int (*get_rate)(struct sunxi_ccu_softc *, 464 1.1 jmcneill struct sunxi_ccu_clk *); 465 1.1 jmcneill int (*set_rate)(struct sunxi_ccu_softc *, 466 1.1 jmcneill struct sunxi_ccu_clk *, u_int); 467 1.17 bouyer u_int (*round_rate)(struct sunxi_ccu_softc *, 468 1.17 bouyer struct sunxi_ccu_clk *, u_int); 469 1.1 jmcneill const char * (*get_parent)(struct sunxi_ccu_softc *, 470 1.1 jmcneill struct sunxi_ccu_clk *); 471 1.1 jmcneill int (*set_parent)(struct sunxi_ccu_softc *, 472 1.1 jmcneill struct sunxi_ccu_clk *, 473 1.1 jmcneill const char *); 474 1.1 jmcneill }; 475 1.1 jmcneill 476 1.1 jmcneill struct sunxi_ccu_softc { 477 1.1 jmcneill device_t sc_dev; 478 1.1 jmcneill int sc_phandle; 479 1.1 jmcneill bus_space_tag_t sc_bst; 480 1.1 jmcneill bus_space_handle_t sc_bsh; 481 1.1 jmcneill 482 1.1 jmcneill struct clk_domain sc_clkdom; 483 1.1 jmcneill 484 1.1 jmcneill struct sunxi_ccu_reset *sc_resets; 485 1.1 jmcneill u_int sc_nresets; 486 1.1 jmcneill 487 1.1 jmcneill struct sunxi_ccu_clk *sc_clks; 488 1.1 jmcneill u_int sc_nclks; 489 1.1 jmcneill }; 490 1.1 jmcneill 491 1.1 jmcneill int sunxi_ccu_attach(struct sunxi_ccu_softc *); 492 1.1 jmcneill struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *, 493 1.1 jmcneill const char *); 494 1.1 jmcneill void sunxi_ccu_print(struct sunxi_ccu_softc *); 495 1.1 jmcneill 496 1.1 jmcneill #define CCU_READ(sc, reg) \ 497 1.1 jmcneill bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 498 1.1 jmcneill #define CCU_WRITE(sc, reg, val) \ 499 1.1 jmcneill bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 500 1.1 jmcneill 501 1.1 jmcneill #endif /* _ARM_SUNXI_CCU_H */ 502