sunxi_ccu.h revision 1.1
1/* $NetBSD: sunxi_ccu.h,v 1.1 2017/06/28 23:51:29 jmcneill Exp $ */ 2 3/*- 4 * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#ifndef _ARM_SUNXI_CCU_H 30#define _ARM_SUNXI_CCU_H 31 32#include <dev/clk/clk_backend.h> 33 34struct sunxi_ccu_softc; 35struct sunxi_ccu_clk; 36struct sunxi_ccu_reset; 37 38/* 39 * Resets 40 */ 41 42struct sunxi_ccu_reset { 43 bus_size_t reg; 44 uint32_t mask; 45}; 46 47#define SUNXI_CCU_RESET(_id, _reg, _bit) \ 48 [_id] = { \ 49 .reg = (_reg), \ 50 .mask = __BIT(_bit), \ 51 } 52 53/* 54 * Clocks 55 */ 56 57enum sunxi_ccu_clktype { 58 SUNXI_CCU_UNKNOWN, 59 SUNXI_CCU_GATE, 60 SUNXI_CCU_NM, 61}; 62 63struct sunxi_ccu_gate { 64 bus_size_t reg; 65 uint32_t mask; 66 const char *parent; 67}; 68 69int sunxi_ccu_gate_enable(struct sunxi_ccu_softc *, 70 struct sunxi_ccu_clk *, int); 71const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *, 72 struct sunxi_ccu_clk *); 73 74#define SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit) \ 75 [_id] = { \ 76 .type = SUNXI_CCU_GATE, \ 77 .base.name = (_name), \ 78 .u.gate.parent = (_pname), \ 79 .u.gate.reg = (_reg), \ 80 .u.gate.mask = __BIT(_bit), \ 81 .enable = sunxi_ccu_gate_enable, \ 82 .get_parent = sunxi_ccu_gate_get_parent, \ 83 } 84 85struct sunxi_ccu_nm { 86 bus_size_t reg; 87 const char **parents; 88 u_int nparents; 89 uint32_t n; 90 uint32_t m; 91 uint32_t sel; 92 uint32_t flags; 93#define SUNXI_CCU_NM_POWER_OF_TWO __BIT(0) 94}; 95 96u_int sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *, 97 struct sunxi_ccu_clk *); 98int sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *, 99 struct sunxi_ccu_clk *, u_int); 100int sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *, 101 struct sunxi_ccu_clk *, 102 const char *); 103const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *, 104 struct sunxi_ccu_clk *); 105 106#define SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel, \ 107 _flags) \ 108 [_id] = { \ 109 .type = SUNXI_CCU_NM, \ 110 .base.name = (_name), \ 111 .u.nm.reg = (_reg), \ 112 .u.nm.parents = (_parents), \ 113 .u.nm.nparents = __arraycount(_parents), \ 114 .u.nm.n = (_n), \ 115 .u.nm.m = (_m), \ 116 .u.nm.sel = (_sel), \ 117 .u.nm.flags = (_flags), \ 118 .set_parent = sunxi_ccu_nm_set_parent, \ 119 .get_parent = sunxi_ccu_nm_get_parent, \ 120 } 121 122struct sunxi_ccu_clk { 123 struct clk base; 124 enum sunxi_ccu_clktype type; 125 union { 126 struct sunxi_ccu_gate gate; 127 struct sunxi_ccu_nm nm; 128 } u; 129 130 int (*enable)(struct sunxi_ccu_softc *, 131 struct sunxi_ccu_clk *, int); 132 u_int (*get_rate)(struct sunxi_ccu_softc *, 133 struct sunxi_ccu_clk *); 134 int (*set_rate)(struct sunxi_ccu_softc *, 135 struct sunxi_ccu_clk *, u_int); 136 const char * (*get_parent)(struct sunxi_ccu_softc *, 137 struct sunxi_ccu_clk *); 138 int (*set_parent)(struct sunxi_ccu_softc *, 139 struct sunxi_ccu_clk *, 140 const char *); 141}; 142 143struct sunxi_ccu_softc { 144 device_t sc_dev; 145 int sc_phandle; 146 bus_space_tag_t sc_bst; 147 bus_space_handle_t sc_bsh; 148 149 struct clk_domain sc_clkdom; 150 151 struct sunxi_ccu_reset *sc_resets; 152 u_int sc_nresets; 153 154 struct sunxi_ccu_clk *sc_clks; 155 u_int sc_nclks; 156}; 157 158int sunxi_ccu_attach(struct sunxi_ccu_softc *); 159struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *, 160 const char *); 161void sunxi_ccu_print(struct sunxi_ccu_softc *); 162 163#define CCU_READ(sc, reg) \ 164 bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) 165#define CCU_WRITE(sc, reg, val) \ 166 bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) 167 168#endif /* _ARM_SUNXI_CCU_H */ 169