1 /* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved. 2 * 3 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in 4 *the the People's Republic of China and other countries. 5 * All Allwinner Technology Co.,Ltd. trademarks are used with permission. 6 * 7 * DISCLAIMER 8 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT. 9 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.) 10 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN 11 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES. 12 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS 13 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE. 14 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY. 15 * 16 * 17 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT 18 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND, 19 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING 20 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE 21 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 29 * OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef __CLK_PERIPH_H__ 33 #define __CLK_PERIPH_H__ 34 35 #include "clk.h" 36 37 #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0]) 38 39 #define SUNXI_CLK_PERIPH_CONFIG(name, _mux_reg, _mux_shift, _mux_width, \ 40 _div_reg, _div_mshift, _div_mwidth, _div_nshift, _div_nwidth, \ 41 _gate_flags, _enable_reg, _reset_reg, _bus_gate_reg, _drm_gate_reg, \ 42 _enable_shift, _reset_shift, _bus_gate_shift, _dram_gate_shift, _com_gate, _com_gate_off) \ 43 struct sunxi_clk_periph sunxi_clk_periph_config_##name = { \ 44 .mux = { \ 45 .reg = (volatile uint32_t *)_mux_reg, \ 46 .shift = _mux_shift, \ 47 .width = _mux_width, \ 48 }, \ 49 .divider = { \ 50 .reg = (volatile uint32_t *)_div_reg, \ 51 .mshift = _div_mshift, \ 52 .mwidth = _div_mwidth, \ 53 .nshift = _div_nshift, \ 54 .nwidth = _div_nwidth, \ 55 }, \ 56 .gate = { \ 57 .flags = _gate_flags, \ 58 .enable = (volatile uint32_t *)_enable_reg, \ 59 .reset = (volatile uint32_t *)_reset_reg, \ 60 .bus = (volatile uint32_t *)_bus_gate_reg, \ 61 .dram = (volatile uint32_t *)_drm_gate_reg, \ 62 .enb_shift = _enable_shift, \ 63 .rst_shift = _reset_shift, \ 64 .bus_shift = _bus_gate_shift, \ 65 .ddr_shift = _dram_gate_shift, \ 66 }, \ 67 .com_gate = _com_gate, \ 68 .com_gate_off = _com_gate_off, \ 69 } 70 71 #define SUNXI_CLK_PERIPH(_name, _clk, _parent_arry) \ 72 clk_periph_t sunxi_clk_periph_##_name = { \ 73 .clk_core = { \ 74 .clk = _clk, \ 75 .clk_type = HAL_CLK_PERIPH, \ 76 .current_parent = HAL_CLK_UNINITIALIZED, \ 77 .current_parent_type = 0, \ 78 .clk_rate = 0, \ 79 .parent_rate = 0, \ 80 .clk_enbale = HAL_CLK_STATUS_DISABLED, \ 81 }, \ 82 .parent_arry = _parent_arry, \ 83 .parent_arry_size = ARRAY_SIZE(_parent_arry), \ 84 .config = &sunxi_clk_periph_config_##_name, \ 85 } 86 87 #define SUNXI_PERIPH_INIT(_name, _clk, _parent_clk, _clk_rate) \ 88 clk_base_t sunxi_periph_clk_init_##_name = { \ 89 .clk = _clk, \ 90 .parent = _parent_clk, \ 91 .clk_rate = _clk_rate, \ 92 } 93 94 95 /** 96 * struct sunxi_clk_periph_gate - peripheral gate clock 97 * 98 * @flags: hardware-specific flags 99 * @enable: enable register 100 * @reset: reset register 101 * @bus: bus gating resiter 102 * @dram: dram gating register 103 * @enb_shift: enable gate bit shift 104 * @rst_shift: reset gate bit shift 105 * @bus_shift: bus gate bit shift 106 * @ddr_shift: dram gate bit shift 107 * 108 * Flags: 109 * SUNXI_PERIPH_NO_GATE - this flag indicates that module gate is not allowed for this module. 110 * SUNXI_PERIPH_NO_RESET - This flag indicates that reset is not allowed for this module. 111 * SUNXI_PERIPH_NO_BUS_GATE - This flag indicates that bus gate is not allowed for this module. 112 * SUNXI_PERIPH_NO_DDR_GATE - This flag indicates that dram gate is not allowed for this module. 113 */ 114 struct sunxi_clk_periph_gate 115 { 116 u32 flags; 117 volatile uint32_t *enable; 118 volatile uint32_t *reset; 119 volatile uint32_t *bus; 120 volatile uint32_t *dram; 121 u8 enb_shift; 122 u8 rst_shift; 123 u8 bus_shift; 124 u8 ddr_shift; 125 }; 126 127 /** 128 * struct sunxi_clk_periph_div - periph divider clock 129 * 130 * @reg: register containing divider 131 * @mshift: shift to the divider-m bit field, div = (m+1) 132 * @mwidth: width of the divider-m bit field 133 * @nshift: shift to the divider-n bit field, div = (1<<n) 134 * @nwidth: width of the divider-n bit field 135 * @lock: register lock 136 * 137 * Flags: 138 */ 139 struct sunxi_clk_periph_div 140 { 141 volatile uint32_t *reg; 142 u8 mshift; 143 u8 mwidth; 144 u8 nshift; 145 u8 nwidth; 146 //spinlock_t *lock; 147 }; 148 149 150 /** 151 * struct sunxi_clk_periph_mux - multiplexer clock 152 * 153 * @reg: register controlling multiplexer 154 * @shift: shift to multiplexer bit field 155 * @width: width of mutliplexer bit field 156 * @lock: register lock 157 * 158 * Clock with multiple selectable parents. Implements .get_parent, .set_parent 159 * and .recalc_rate 160 * 161 */ 162 struct sunxi_clk_periph_mux 163 { 164 volatile uint32_t *reg; 165 u8 shift; 166 u8 width; 167 //spinlock_t *lock; 168 }; 169 170 struct sunxi_clk_comgate 171 { 172 const u8 *name; 173 u16 val; 174 u16 mask; 175 u8 share; 176 u8 res; 177 }; 178 179 #define BUS_GATE_SHARE 0x01 180 #define RST_GATE_SHARE 0x02 181 #define MBUS_GATE_SHARE 0x04 182 #define MOD_GATE_SHARE 0x08 183 184 #define IS_SHARE_BUS_GATE(x) (x->com_gate?((x->com_gate->share & BUS_GATE_SHARE)?1:0):0) 185 #define IS_SHARE_RST_GATE(x) (x->com_gate?((x->com_gate->share & RST_GATE_SHARE)?1:0):0) 186 #define IS_SHARE_MBUS_GATE(x) (x->com_gate?((x->com_gate->share & MBUS_GATE_SHARE)?1:0):0) 187 #define IS_SHARE_MOD_GATE(x) (x->com_gate?((x->com_gate->share & MOD_GATE_SHARE)?1:0):0) 188 189 /** 190 * struct sunxi-clk-periph - peripheral clock 191 * 192 * @hw: handle between common and hardware-specific interfaces 193 * @flags: flags used across common struct clk, please take refference of the clk-provider.h 194 * @lock: lock for protecting the periph clock operations 195 * @mux: mux clock 196 * @gate: gate clock 197 * @divider: divider clock 198 * @com_gate: the shared clock 199 * @com_gate_off: bit shift to mark the flag in the com_gate 200 * @priv_clkops: divider clock ops 201 * @priv_regops: gate clock ops 202 */ 203 struct sunxi_clk_periph 204 { 205 //struct clk_hw hw; 206 //unsigned long flags; 207 //spinlock_t *lock; 208 209 struct sunxi_clk_periph_mux mux; 210 struct sunxi_clk_periph_gate gate; 211 struct sunxi_clk_periph_div divider; 212 struct sunxi_clk_comgate *com_gate; 213 u8 com_gate_off; 214 //struct clk_ops *priv_clkops; 215 //struct sunxi_reg_ops *priv_regops; 216 }; 217 218 219 hal_clk_status_t sunxi_clk_periph_get_parent(clk_periph_pt clk, u8 *parent_index); 220 hal_clk_status_t sunxi_clk_periph_set_parent(clk_periph_pt clk, u8 index); 221 hal_clk_status_t sunxi_clk_periph_enable(clk_periph_pt clk); 222 hal_clk_status_t sunxi_clk_periph_is_enabled(clk_periph_pt clk); 223 hal_clk_status_t sunxi_clk_periph_disable(clk_periph_pt clk); 224 hal_clk_status_t sunxi_clk_periph_recalc_rate(clk_periph_pt clk, u32 *rate); 225 u32 sunxi_clk_periph_round_rate(clk_periph_pt clk, u32 rate, u32 prate); 226 hal_clk_status_t sunxi_clk_periph_set_rate(clk_periph_pt clk, u32 rate); 227 228 229 #endif /* __MACH_SUNXI_CLK_PERIPH_H */ 230