1*8afae5d5Sryo /* $NetBSD: meson_clk.h,v 1.4 2021/01/01 07:21:58 ryo Exp $ */ 2912cfa14Sjmcneill 3912cfa14Sjmcneill /*- 4912cfa14Sjmcneill * Copyright (c) 2017-2019 Jared McNeill <jmcneill@invisible.ca> 5912cfa14Sjmcneill * All rights reserved. 6912cfa14Sjmcneill * 7912cfa14Sjmcneill * Redistribution and use in source and binary forms, with or without 8912cfa14Sjmcneill * modification, are permitted provided that the following conditions 9912cfa14Sjmcneill * are met: 10912cfa14Sjmcneill * 1. Redistributions of source code must retain the above copyright 11912cfa14Sjmcneill * notice, this list of conditions and the following disclaimer. 12912cfa14Sjmcneill * 2. Redistributions in binary form must reproduce the above copyright 13912cfa14Sjmcneill * notice, this list of conditions and the following disclaimer in the 14912cfa14Sjmcneill * documentation and/or other materials provided with the distribution. 15912cfa14Sjmcneill * 16912cfa14Sjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17912cfa14Sjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18912cfa14Sjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19912cfa14Sjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20912cfa14Sjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21912cfa14Sjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22912cfa14Sjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23912cfa14Sjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24912cfa14Sjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25912cfa14Sjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26912cfa14Sjmcneill * SUCH DAMAGE. 27912cfa14Sjmcneill */ 28912cfa14Sjmcneill 29912cfa14Sjmcneill #ifndef _ARM_MESON_CLK_H 30912cfa14Sjmcneill #define _ARM_MESON_CLK_H 31912cfa14Sjmcneill 32912cfa14Sjmcneill #include <dev/clk/clk_backend.h> 337e38c880Sjmcneill #include <dev/fdt/syscon.h> 34912cfa14Sjmcneill 35912cfa14Sjmcneill struct meson_clk_softc; 36912cfa14Sjmcneill struct meson_clk_clk; 37912cfa14Sjmcneill struct meson_clk_reset; 38912cfa14Sjmcneill 39912cfa14Sjmcneill /* 40912cfa14Sjmcneill * Resets 41912cfa14Sjmcneill */ 42912cfa14Sjmcneill 43912cfa14Sjmcneill struct meson_clk_reset { 44912cfa14Sjmcneill bus_size_t reg; 45912cfa14Sjmcneill uint32_t mask; 46912cfa14Sjmcneill }; 47912cfa14Sjmcneill 48912cfa14Sjmcneill #define MESON_CLK_RESET(_id, _reg, _bit) \ 49912cfa14Sjmcneill [_id] = { \ 50912cfa14Sjmcneill .reg = (_reg), \ 51912cfa14Sjmcneill .mask = __BIT(_bit), \ 52912cfa14Sjmcneill } 53912cfa14Sjmcneill 54912cfa14Sjmcneill /* 55912cfa14Sjmcneill * Clocks 56912cfa14Sjmcneill */ 57912cfa14Sjmcneill 58912cfa14Sjmcneill enum meson_clk_clktype { 59912cfa14Sjmcneill MESON_CLK_UNKNOWN, 60912cfa14Sjmcneill MESON_CLK_FIXED, 61912cfa14Sjmcneill MESON_CLK_GATE, 62912cfa14Sjmcneill MESON_CLK_PLL, 63912cfa14Sjmcneill MESON_CLK_MPLL, 64912cfa14Sjmcneill MESON_CLK_DIV, 65912cfa14Sjmcneill MESON_CLK_FIXED_FACTOR, 66912cfa14Sjmcneill MESON_CLK_MUX, 67912cfa14Sjmcneill }; 68912cfa14Sjmcneill 69912cfa14Sjmcneill /* 70912cfa14Sjmcneill * Fixed clocks 71912cfa14Sjmcneill */ 72912cfa14Sjmcneill 73912cfa14Sjmcneill struct meson_clk_fixed { 74912cfa14Sjmcneill u_int rate; 75912cfa14Sjmcneill }; 76912cfa14Sjmcneill 77912cfa14Sjmcneill u_int meson_clk_fixed_get_rate(struct meson_clk_softc *, struct meson_clk_clk *); 78912cfa14Sjmcneill 79912cfa14Sjmcneill #define MESON_CLK_FIXED(_id, _name, _rate) \ 80912cfa14Sjmcneill [_id] = { \ 81912cfa14Sjmcneill .type = MESON_CLK_FIXED, \ 82912cfa14Sjmcneill .base.name = (_name), \ 83912cfa14Sjmcneill .base.flags = 0, \ 84912cfa14Sjmcneill .u.fixed.rate = (_rate), \ 85912cfa14Sjmcneill .get_rate = meson_clk_fixed_get_rate, \ 86912cfa14Sjmcneill } 87912cfa14Sjmcneill 88912cfa14Sjmcneill /* 89912cfa14Sjmcneill * Gate clocks 90912cfa14Sjmcneill */ 91912cfa14Sjmcneill 92912cfa14Sjmcneill struct meson_clk_gate { 93912cfa14Sjmcneill bus_size_t reg; 94912cfa14Sjmcneill uint32_t mask; 95912cfa14Sjmcneill const char *parent; 96912cfa14Sjmcneill uint32_t flags; 97912cfa14Sjmcneill #define MESON_CLK_GATE_SET_TO_DISABLE __BIT(0) 98912cfa14Sjmcneill }; 99912cfa14Sjmcneill 100912cfa14Sjmcneill int meson_clk_gate_enable(struct meson_clk_softc *, 101912cfa14Sjmcneill struct meson_clk_clk *, int); 102912cfa14Sjmcneill const char *meson_clk_gate_get_parent(struct meson_clk_softc *, 103912cfa14Sjmcneill struct meson_clk_clk *); 104912cfa14Sjmcneill 105912cfa14Sjmcneill #define MESON_CLK_GATE_FLAGS(_id, _name, _pname, _reg, _bit, _flags) \ 106912cfa14Sjmcneill [_id] = { \ 107912cfa14Sjmcneill .type = MESON_CLK_GATE, \ 108912cfa14Sjmcneill .base.name = (_name), \ 109912cfa14Sjmcneill .base.flags = CLK_SET_RATE_PARENT, \ 110912cfa14Sjmcneill .u.gate.parent = (_pname), \ 111912cfa14Sjmcneill .u.gate.reg = (_reg), \ 112912cfa14Sjmcneill .u.gate.mask = __BIT(_bit), \ 113912cfa14Sjmcneill .u.gate.flags = (_flags), \ 114912cfa14Sjmcneill .enable = meson_clk_gate_enable, \ 115912cfa14Sjmcneill .get_parent = meson_clk_gate_get_parent, \ 116912cfa14Sjmcneill } 117912cfa14Sjmcneill 118912cfa14Sjmcneill #define MESON_CLK_GATE(_id, _name, _pname, _reg, _bit) \ 119912cfa14Sjmcneill MESON_CLK_GATE_FLAGS(_id, _name, _pname, _reg, _bit, 0) 120912cfa14Sjmcneill 121912cfa14Sjmcneill /* 122912cfa14Sjmcneill * Divider clocks 123912cfa14Sjmcneill */ 124912cfa14Sjmcneill 125912cfa14Sjmcneill struct meson_clk_div { 126912cfa14Sjmcneill bus_size_t reg; 127912cfa14Sjmcneill const char *parent; 128912cfa14Sjmcneill uint32_t div; 129912cfa14Sjmcneill uint32_t flags; 130912cfa14Sjmcneill #define MESON_CLK_DIV_POWER_OF_TWO __BIT(0) 131912cfa14Sjmcneill #define MESON_CLK_DIV_SET_RATE_PARENT __BIT(1) 132912cfa14Sjmcneill #define MESON_CLK_DIV_CPU_SCALE_TABLE __BIT(2) 133912cfa14Sjmcneill }; 134912cfa14Sjmcneill 135912cfa14Sjmcneill u_int meson_clk_div_get_rate(struct meson_clk_softc *, 136912cfa14Sjmcneill struct meson_clk_clk *); 137912cfa14Sjmcneill int meson_clk_div_set_rate(struct meson_clk_softc *, 138912cfa14Sjmcneill struct meson_clk_clk *, u_int); 139912cfa14Sjmcneill const char *meson_clk_div_get_parent(struct meson_clk_softc *, 140912cfa14Sjmcneill struct meson_clk_clk *); 141912cfa14Sjmcneill 142912cfa14Sjmcneill #define MESON_CLK_DIV(_id, _name, _parent, _reg, _div, _flags) \ 143912cfa14Sjmcneill [_id] = { \ 144912cfa14Sjmcneill .type = MESON_CLK_DIV, \ 145912cfa14Sjmcneill .base.name = (_name), \ 146912cfa14Sjmcneill .u.div.reg = (_reg), \ 147912cfa14Sjmcneill .u.div.parent = (_parent), \ 148912cfa14Sjmcneill .u.div.div = (_div), \ 149912cfa14Sjmcneill .u.div.flags = (_flags), \ 150912cfa14Sjmcneill .get_rate = meson_clk_div_get_rate, \ 151912cfa14Sjmcneill .set_rate = meson_clk_div_set_rate, \ 152912cfa14Sjmcneill .get_parent = meson_clk_div_get_parent, \ 153912cfa14Sjmcneill } 154912cfa14Sjmcneill 155912cfa14Sjmcneill /* 156912cfa14Sjmcneill * Fixed-factor clocks 157912cfa14Sjmcneill */ 158912cfa14Sjmcneill 159912cfa14Sjmcneill struct meson_clk_fixed_factor { 160912cfa14Sjmcneill const char *parent; 161912cfa14Sjmcneill u_int div; 162912cfa14Sjmcneill u_int mult; 163912cfa14Sjmcneill }; 164912cfa14Sjmcneill 165912cfa14Sjmcneill u_int meson_clk_fixed_factor_get_rate(struct meson_clk_softc *, 166912cfa14Sjmcneill struct meson_clk_clk *); 167912cfa14Sjmcneill int meson_clk_fixed_factor_set_rate(struct meson_clk_softc *, 168912cfa14Sjmcneill struct meson_clk_clk *, u_int); 169912cfa14Sjmcneill const char *meson_clk_fixed_factor_get_parent(struct meson_clk_softc *, 170912cfa14Sjmcneill struct meson_clk_clk *); 171912cfa14Sjmcneill 172912cfa14Sjmcneill #define MESON_CLK_FIXED_FACTOR(_id, _name, _parent, _div, _mult) \ 173912cfa14Sjmcneill [_id] = { \ 174912cfa14Sjmcneill .type = MESON_CLK_FIXED_FACTOR, \ 175912cfa14Sjmcneill .base.name = (_name), \ 176912cfa14Sjmcneill .u.fixed_factor.parent = (_parent), \ 177912cfa14Sjmcneill .u.fixed_factor.div = (_div), \ 178912cfa14Sjmcneill .u.fixed_factor.mult = (_mult), \ 179912cfa14Sjmcneill .get_rate = meson_clk_fixed_factor_get_rate, \ 180912cfa14Sjmcneill .get_parent = meson_clk_fixed_factor_get_parent, \ 181912cfa14Sjmcneill .set_rate = meson_clk_fixed_factor_set_rate, \ 182912cfa14Sjmcneill } 183912cfa14Sjmcneill 184912cfa14Sjmcneill /* 185912cfa14Sjmcneill * Mux clocks 186912cfa14Sjmcneill */ 187912cfa14Sjmcneill 188912cfa14Sjmcneill struct meson_clk_mux { 189912cfa14Sjmcneill bus_size_t reg; 190912cfa14Sjmcneill const char **parents; 191912cfa14Sjmcneill u_int nparents; 192912cfa14Sjmcneill uint32_t sel; 193912cfa14Sjmcneill uint32_t flags; 194912cfa14Sjmcneill }; 195912cfa14Sjmcneill 196912cfa14Sjmcneill const char *meson_clk_mux_get_parent(struct meson_clk_softc *, 197912cfa14Sjmcneill struct meson_clk_clk *); 198912cfa14Sjmcneill 199*8afae5d5Sryo #define MESON_CLK_MUX_RATE(_id, _name, _parents, _reg, _sel, \ 200*8afae5d5Sryo _getratefn, _setratefn, _flags) \ 201*8afae5d5Sryo [_id] = { \ 202*8afae5d5Sryo .type = MESON_CLK_MUX, \ 203*8afae5d5Sryo .base.name = (_name), \ 204*8afae5d5Sryo .base.flags = 0, \ 205*8afae5d5Sryo .u.mux.parents = (_parents), \ 206*8afae5d5Sryo .u.mux.nparents = __arraycount(_parents), \ 207*8afae5d5Sryo .u.mux.reg = (_reg), \ 208*8afae5d5Sryo .u.mux.sel = (_sel), \ 209*8afae5d5Sryo .u.mux.flags = (_flags), \ 210*8afae5d5Sryo .get_rate = _getratefn, \ 211*8afae5d5Sryo .set_rate = _setratefn, \ 212*8afae5d5Sryo .get_parent = meson_clk_mux_get_parent, \ 213*8afae5d5Sryo } 214*8afae5d5Sryo 215912cfa14Sjmcneill #define MESON_CLK_MUX(_id, _name, _parents, _reg, _sel, _flags) \ 216912cfa14Sjmcneill [_id] = { \ 217912cfa14Sjmcneill .type = MESON_CLK_MUX, \ 218912cfa14Sjmcneill .base.name = (_name), \ 219bce8d6d7Sjmcneill .base.flags = CLK_SET_RATE_PARENT, \ 220912cfa14Sjmcneill .u.mux.parents = (_parents), \ 221912cfa14Sjmcneill .u.mux.nparents = __arraycount(_parents), \ 222912cfa14Sjmcneill .u.mux.reg = (_reg), \ 223912cfa14Sjmcneill .u.mux.sel = (_sel), \ 224912cfa14Sjmcneill .u.mux.flags = (_flags), \ 225912cfa14Sjmcneill .get_parent = meson_clk_mux_get_parent, \ 226912cfa14Sjmcneill } 227912cfa14Sjmcneill 228912cfa14Sjmcneill /* 229912cfa14Sjmcneill * PLL clocks 230912cfa14Sjmcneill */ 231912cfa14Sjmcneill 232912cfa14Sjmcneill struct meson_clk_pll_reg { 233912cfa14Sjmcneill bus_size_t reg; 234912cfa14Sjmcneill uint32_t mask; 235912cfa14Sjmcneill }; 236912cfa14Sjmcneill 237912cfa14Sjmcneill #define MESON_CLK_PLL_REG(_reg, _mask) \ 238912cfa14Sjmcneill { .reg = (_reg), .mask = (_mask) } 239912cfa14Sjmcneill #define MESON_CLK_PLL_REG_INVALID MESON_CLK_PLL_REG(0,0) 240912cfa14Sjmcneill 241912cfa14Sjmcneill struct meson_clk_pll { 242912cfa14Sjmcneill struct meson_clk_pll_reg enable; 243912cfa14Sjmcneill struct meson_clk_pll_reg m; 244912cfa14Sjmcneill struct meson_clk_pll_reg n; 245912cfa14Sjmcneill struct meson_clk_pll_reg frac; 246912cfa14Sjmcneill struct meson_clk_pll_reg l; 247912cfa14Sjmcneill struct meson_clk_pll_reg reset; 248912cfa14Sjmcneill const char *parent; 249912cfa14Sjmcneill uint32_t flags; 250912cfa14Sjmcneill }; 251912cfa14Sjmcneill 252912cfa14Sjmcneill u_int meson_clk_pll_get_rate(struct meson_clk_softc *, 253912cfa14Sjmcneill struct meson_clk_clk *); 254*8afae5d5Sryo int meson_clk_pll_set_rate(struct meson_clk_softc *, 255*8afae5d5Sryo struct meson_clk_clk *, u_int new_rate); 256912cfa14Sjmcneill const char *meson_clk_pll_get_parent(struct meson_clk_softc *, 257912cfa14Sjmcneill struct meson_clk_clk *); 258*8afae5d5Sryo int meson_clk_pll_wait_lock(struct meson_clk_softc *sc, 259*8afae5d5Sryo struct meson_clk_pll *pll); 260*8afae5d5Sryo 261912cfa14Sjmcneill 262bce8d6d7Sjmcneill #define MESON_CLK_PLL_RATE(_id, _name, _parent, _enable, _m, _n, _frac, _l, \ 263bce8d6d7Sjmcneill _reset, _setratefn, _flags) \ 264bce8d6d7Sjmcneill [_id] = { \ 265bce8d6d7Sjmcneill .type = MESON_CLK_PLL, \ 266bce8d6d7Sjmcneill .base.name = (_name), \ 267bce8d6d7Sjmcneill .u.pll.parent = (_parent), \ 268bce8d6d7Sjmcneill .u.pll.enable = _enable, \ 269bce8d6d7Sjmcneill .u.pll.m = _m, \ 270bce8d6d7Sjmcneill .u.pll.n = _n, \ 271bce8d6d7Sjmcneill .u.pll.frac = _frac, \ 272bce8d6d7Sjmcneill .u.pll.l = _l, \ 273bce8d6d7Sjmcneill .u.pll.reset = _reset, \ 274bce8d6d7Sjmcneill .u.pll.flags = (_flags), \ 275bce8d6d7Sjmcneill .set_rate = (_setratefn), \ 276bce8d6d7Sjmcneill .get_rate = meson_clk_pll_get_rate, \ 277bce8d6d7Sjmcneill .get_parent = meson_clk_pll_get_parent, \ 278bce8d6d7Sjmcneill } 279bce8d6d7Sjmcneill 280912cfa14Sjmcneill #define MESON_CLK_PLL(_id, _name, _parent, _enable, _m, _n, _frac, _l, \ 281912cfa14Sjmcneill _reset, _flags) \ 282912cfa14Sjmcneill [_id] = { \ 283912cfa14Sjmcneill .type = MESON_CLK_PLL, \ 284912cfa14Sjmcneill .base.name = (_name), \ 285912cfa14Sjmcneill .u.pll.parent = (_parent), \ 286912cfa14Sjmcneill .u.pll.enable = _enable, \ 287912cfa14Sjmcneill .u.pll.m = _m, \ 288912cfa14Sjmcneill .u.pll.n = _n, \ 289912cfa14Sjmcneill .u.pll.frac = _frac, \ 290912cfa14Sjmcneill .u.pll.l = _l, \ 291912cfa14Sjmcneill .u.pll.reset = _reset, \ 292912cfa14Sjmcneill .u.pll.flags = (_flags), \ 293912cfa14Sjmcneill .get_rate = meson_clk_pll_get_rate, \ 294912cfa14Sjmcneill .get_parent = meson_clk_pll_get_parent, \ 295912cfa14Sjmcneill } 296912cfa14Sjmcneill 297912cfa14Sjmcneill /* 298912cfa14Sjmcneill * MPLL clocks 299912cfa14Sjmcneill */ 300912cfa14Sjmcneill 301912cfa14Sjmcneill struct meson_clk_mpll { 302912cfa14Sjmcneill struct meson_clk_pll_reg sdm; 303912cfa14Sjmcneill struct meson_clk_pll_reg sdm_enable; 304912cfa14Sjmcneill struct meson_clk_pll_reg n2; 305912cfa14Sjmcneill struct meson_clk_pll_reg ssen; 306912cfa14Sjmcneill const char *parent; 307912cfa14Sjmcneill uint32_t flags; 308912cfa14Sjmcneill }; 309912cfa14Sjmcneill 310912cfa14Sjmcneill u_int meson_clk_mpll_get_rate(struct meson_clk_softc *, 311912cfa14Sjmcneill struct meson_clk_clk *); 312912cfa14Sjmcneill const char *meson_clk_mpll_get_parent(struct meson_clk_softc *, 313912cfa14Sjmcneill struct meson_clk_clk *); 314912cfa14Sjmcneill 315912cfa14Sjmcneill #define MESON_CLK_MPLL(_id, _name, _parent, _sdm, _sdm_enable, _n2, \ 316912cfa14Sjmcneill _ssen, _flags) \ 317912cfa14Sjmcneill [_id] = { \ 318912cfa14Sjmcneill .type = MESON_CLK_MPLL, \ 319912cfa14Sjmcneill .base.name = (_name), \ 320912cfa14Sjmcneill .u.mpll.parent = (_parent), \ 321912cfa14Sjmcneill .u.mpll.sdm = _sdm, \ 322912cfa14Sjmcneill .u.mpll.sdm_enable = _sdm_enable, \ 323912cfa14Sjmcneill .u.mpll.n2 = _n2, \ 324912cfa14Sjmcneill .u.mpll.ssen = _ssen, \ 325912cfa14Sjmcneill .u.mpll.flags = (_flags), \ 326912cfa14Sjmcneill .get_rate = meson_clk_mpll_get_rate, \ 327912cfa14Sjmcneill .get_parent = meson_clk_mpll_get_parent, \ 328912cfa14Sjmcneill } 329912cfa14Sjmcneill 330912cfa14Sjmcneill 331912cfa14Sjmcneill 332912cfa14Sjmcneill struct meson_clk_clk { 333912cfa14Sjmcneill struct clk base; 334912cfa14Sjmcneill enum meson_clk_clktype type; 335912cfa14Sjmcneill union { 336912cfa14Sjmcneill struct meson_clk_fixed fixed; 337912cfa14Sjmcneill struct meson_clk_gate gate; 338912cfa14Sjmcneill struct meson_clk_div div; 339912cfa14Sjmcneill struct meson_clk_fixed_factor fixed_factor; 340912cfa14Sjmcneill struct meson_clk_mux mux; 341912cfa14Sjmcneill struct meson_clk_pll pll; 342912cfa14Sjmcneill struct meson_clk_mpll mpll; 343912cfa14Sjmcneill } u; 344912cfa14Sjmcneill 345912cfa14Sjmcneill int (*enable)(struct meson_clk_softc *, 346912cfa14Sjmcneill struct meson_clk_clk *, int); 347912cfa14Sjmcneill u_int (*get_rate)(struct meson_clk_softc *, 348912cfa14Sjmcneill struct meson_clk_clk *); 349912cfa14Sjmcneill int (*set_rate)(struct meson_clk_softc *, 350912cfa14Sjmcneill struct meson_clk_clk *, u_int); 351912cfa14Sjmcneill u_int (*round_rate)(struct meson_clk_softc *, 352912cfa14Sjmcneill struct meson_clk_clk *, u_int); 353912cfa14Sjmcneill const char * (*get_parent)(struct meson_clk_softc *, 354912cfa14Sjmcneill struct meson_clk_clk *); 355912cfa14Sjmcneill int (*set_parent)(struct meson_clk_softc *, 356912cfa14Sjmcneill struct meson_clk_clk *, 357912cfa14Sjmcneill const char *); 358912cfa14Sjmcneill }; 359912cfa14Sjmcneill 360912cfa14Sjmcneill struct meson_clk_softc { 361912cfa14Sjmcneill device_t sc_dev; 362912cfa14Sjmcneill int sc_phandle; 3637e38c880Sjmcneill 364912cfa14Sjmcneill bus_space_tag_t sc_bst; 365912cfa14Sjmcneill bus_space_handle_t sc_bsh; 366912cfa14Sjmcneill 3677e38c880Sjmcneill struct syscon *sc_syscon; 3687e38c880Sjmcneill 369912cfa14Sjmcneill struct clk_domain sc_clkdom; 370912cfa14Sjmcneill 371912cfa14Sjmcneill struct meson_clk_reset *sc_resets; 372912cfa14Sjmcneill u_int sc_nresets; 373912cfa14Sjmcneill 374912cfa14Sjmcneill struct meson_clk_clk *sc_clks; 375912cfa14Sjmcneill u_int sc_nclks; 376912cfa14Sjmcneill }; 377912cfa14Sjmcneill 3787e38c880Sjmcneill void meson_clk_attach(struct meson_clk_softc *); 379912cfa14Sjmcneill struct meson_clk_clk *meson_clk_clock_find(struct meson_clk_softc *, 380912cfa14Sjmcneill const char *); 381912cfa14Sjmcneill void meson_clk_print(struct meson_clk_softc *); 382912cfa14Sjmcneill 3837e38c880Sjmcneill void meson_clk_lock(struct meson_clk_softc *); 3847e38c880Sjmcneill void meson_clk_unlock(struct meson_clk_softc *); 3857e38c880Sjmcneill uint32_t meson_clk_read(struct meson_clk_softc *, bus_size_t); 3867e38c880Sjmcneill void meson_clk_write(struct meson_clk_softc *, bus_size_t, uint32_t); 3877e38c880Sjmcneill 3887e38c880Sjmcneill #define CLK_LOCK meson_clk_lock 3897e38c880Sjmcneill #define CLK_UNLOCK meson_clk_unlock 3907e38c880Sjmcneill #define CLK_READ meson_clk_read 3917e38c880Sjmcneill #define CLK_WRITE meson_clk_write 392*8afae5d5Sryo #define CLK_WRITE_BITS(sc, reg, mask, val) \ 393*8afae5d5Sryo do { \ 394*8afae5d5Sryo uint32_t _cwb_tmp_ = CLK_READ((sc), (reg)); \ 395*8afae5d5Sryo _cwb_tmp_ &= ~(mask); \ 396*8afae5d5Sryo _cwb_tmp_ |= __SHIFTIN((val), (mask)); \ 397*8afae5d5Sryo CLK_WRITE((sc), (reg), _cwb_tmp_); \ 398*8afae5d5Sryo } while (0 /*CONSTCOND*/) 399912cfa14Sjmcneill 400912cfa14Sjmcneill #endif /* _ARM_MESON_CLK_H */ 401