FILE
ccu_mix.h
File preview with syntax highlighting.
linux-6.19.14/drivers/clk/spacemit/ccu_mix.h
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * Copyright (c) 2024 SpacemiT Technology Co. Ltd 4 * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> 5 */ 6 7#ifndef _CCU_MIX_H_ 8#define _CCU_MIX_H_ 9 10#include <linux/clk-provider.h> 11 12#include "ccu_common.h" 13 14/** 15 * struct ccu_gate_config - Gate configuration 16 * 17 * @mask: Mask to enable the gate. Some clocks may have more than one bit 18 * set in this field. 19 */ 20struct ccu_gate_config { 21 u32 mask; 22}; 23 24struct ccu_factor_config { 25 u32 div; 26 u32 mul; 27}; 28 29struct ccu_mux_config { 30 u8 shift; 31 u8 width; 32}; 33 34struct ccu_div_config { 35 u8 shift; 36 u8 width; 37}; 38 39struct ccu_mix { 40 struct ccu_factor_config factor; 41 struct ccu_gate_config gate; 42 struct ccu_div_config div; 43 struct ccu_mux_config mux; 44 struct ccu_common common; 45}; 46 47#define CCU_GATE_INIT(_mask) { .mask = _mask } 48#define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul } 49#define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width } 50#define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width } 51 52#define CCU_PARENT_HW(_parent) { .hw = &_parent.common.hw } 53#define CCU_PARENT_NAME(_name) { .fw_name = #_name } 54 55#define CCU_MIX_INITHW(_name, _parent, _ops, _flags) \ 56 .hw.init = &(struct clk_init_data) { \ 57 .flags = _flags, \ 58 .name = #_name, \ 59 .parent_data = (const struct clk_parent_data[]) \ 60 { _parent }, \ 61 .num_parents = 1, \ 62 .ops = &_ops, \ 63 } 64 65#define CCU_MIX_INITHW_PARENTS(_name, _parents, _ops, _flags) \ 66 .hw.init = CLK_HW_INIT_PARENTS_DATA(#_name, _parents, &_ops, _flags) 67 68#define CCU_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _flags) \ 69static struct ccu_mix _name = { \ 70 .gate = CCU_GATE_INIT(_mask_gate), \ 71 .common = { \ 72 .reg_ctrl = _reg_ctrl, \ 73 CCU_MIX_INITHW(_name, _parent, spacemit_ccu_gate_ops, _flags), \ 74 } \ 75} 76 77#define CCU_FACTOR_DEFINE(_name, _parent, _div, _mul) \ 78static struct ccu_mix _name = { \ 79 .factor = CCU_FACTOR_INIT(_div, _mul), \ 80 .common = { \ 81 CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_ops, 0), \ 82 } \ 83} 84 85#define CCU_MUX_DEFINE(_name, _parents, _reg_ctrl, _shift, _width, _flags) \ 86static struct ccu_mix _name = { \ 87 .mux = CCU_MUX_INIT(_shift, _width), \ 88 .common = { \ 89 .reg_ctrl = _reg_ctrl, \ 90 CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops, \ 91 _flags), \ 92 } \ 93} 94 95#define CCU_DIV_DEFINE(_name, _parent, _reg_ctrl, _shift, _width, _flags) \ 96static struct ccu_mix _name = { \ 97 .div = CCU_DIV_INIT(_shift, _width), \ 98 .common = { \ 99 .reg_ctrl = _reg_ctrl, \ 100 CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_ops, _flags) \ 101 } \ 102} 103 104#define CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div, \ 105 _mul, _flags) \ 106static struct ccu_mix _name = { \ 107 .gate = CCU_GATE_INIT(_mask_gate), \ 108 .factor = CCU_FACTOR_INIT(_div, _mul), \ 109 .common = { \ 110 .reg_ctrl = _reg_ctrl, \ 111 CCU_MIX_INITHW(_name, _parent, spacemit_ccu_factor_gate_ops, _flags) \ 112 } \ 113} 114 115#define CCU_FACTOR_GATE_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div, \ 116 _mul) \ 117 CCU_FACTOR_GATE_FLAGS_DEFINE(_name, _parent, _reg_ctrl, _mask_gate, _div, \ 118 _mul, 0) 119 120#define CCU_MUX_GATE_DEFINE(_name, _parents, _reg_ctrl, _shift, _width, \ 121 _mask_gate, _flags) \ 122static struct ccu_mix _name = { \ 123 .gate = CCU_GATE_INIT(_mask_gate), \ 124 .mux = CCU_MUX_INIT(_shift, _width), \ 125 .common = { \ 126 .reg_ctrl = _reg_ctrl, \ 127 CCU_MIX_INITHW_PARENTS(_name, _parents, \ 128 spacemit_ccu_mux_gate_ops, _flags), \ 129 } \ 130} 131 132#define CCU_DIV_GATE_DEFINE(_name, _parent, _reg_ctrl, _shift, _width, \ 133 _mask_gate, _flags) \ 134static struct ccu_mix _name = { \ 135 .gate = CCU_GATE_INIT(_mask_gate), \ 136 .div = CCU_DIV_INIT(_shift, _width), \ 137 .common = { \ 138 .reg_ctrl = _reg_ctrl, \ 139 CCU_MIX_INITHW(_name, _parent, spacemit_ccu_div_gate_ops, \ 140 _flags), \ 141 } \ 142} 143 144#define CCU_MUX_DIV_GATE_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth, \ 145 _muxshift, _muxwidth, _mask_gate, _flags) \ 146static struct ccu_mix _name = { \ 147 .gate = CCU_GATE_INIT(_mask_gate), \ 148 .div = CCU_DIV_INIT(_mshift, _mwidth), \ 149 .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ 150 .common = { \ 151 .reg_ctrl = _reg_ctrl, \ 152 CCU_MIX_INITHW_PARENTS(_name, _parents, \ 153 spacemit_ccu_mux_div_gate_ops, _flags), \ 154 }, \ 155} 156 157#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_fc, \ 158 _mshift, _mwidth, _mask_fc, _muxshift, \ 159 _muxwidth, _mask_gate, _flags) \ 160static struct ccu_mix _name = { \ 161 .gate = CCU_GATE_INIT(_mask_gate), \ 162 .div = CCU_DIV_INIT(_mshift, _mwidth), \ 163 .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ 164 .common = { \ 165 .reg_ctrl = _reg_ctrl, \ 166 .reg_fc = _reg_fc, \ 167 .mask_fc = _mask_fc, \ 168 CCU_MIX_INITHW_PARENTS(_name, _parents, \ 169 spacemit_ccu_mux_div_gate_ops, _flags), \ 170 }, \ 171} 172 173#define CCU_MUX_DIV_GATE_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth,\ 174 _mask_fc, _muxshift, _muxwidth, _mask_gate, \ 175 _flags) \ 176CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_name, _parents, _reg_ctrl, _reg_ctrl, _mshift,\ 177 _mwidth, _mask_fc, _muxshift, _muxwidth, \ 178 _mask_gate, _flags) 179 180#define CCU_MUX_DIV_FC_DEFINE(_name, _parents, _reg_ctrl, _mshift, _mwidth, \ 181 _mask_fc, _muxshift, _muxwidth, _flags) \ 182static struct ccu_mix _name = { \ 183 .div = CCU_DIV_INIT(_mshift, _mwidth), \ 184 .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ 185 .common = { \ 186 .reg_ctrl = _reg_ctrl, \ 187 .reg_fc = _reg_ctrl, \ 188 .mask_fc = _mask_fc, \ 189 CCU_MIX_INITHW_PARENTS(_name, _parents, \ 190 spacemit_ccu_mux_div_ops, _flags), \ 191 }, \ 192} 193 194#define CCU_MUX_FC_DEFINE(_name, _parents, _reg_ctrl, _mask_fc, _muxshift, \ 195 _muxwidth, _flags) \ 196static struct ccu_mix _name = { \ 197 .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ 198 .common = { \ 199 .reg_ctrl = _reg_ctrl, \ 200 .reg_fc = _reg_ctrl, \ 201 .mask_fc = _mask_fc, \ 202 CCU_MIX_INITHW_PARENTS(_name, _parents, spacemit_ccu_mux_ops, \ 203 _flags) \ 204 }, \ 205} 206 207static inline struct ccu_mix *hw_to_ccu_mix(struct clk_hw *hw) 208{ 209 struct ccu_common *common = hw_to_ccu_common(hw); 210 211 return container_of(common, struct ccu_mix, common); 212} 213 214extern const struct clk_ops spacemit_ccu_gate_ops; 215extern const struct clk_ops spacemit_ccu_factor_ops; 216extern const struct clk_ops spacemit_ccu_mux_ops; 217extern const struct clk_ops spacemit_ccu_div_ops; 218extern const struct clk_ops spacemit_ccu_factor_gate_ops; 219extern const struct clk_ops spacemit_ccu_div_gate_ops; 220extern const struct clk_ops spacemit_ccu_mux_gate_ops; 221extern const struct clk_ops spacemit_ccu_mux_div_ops; 222extern const struct clk_ops spacemit_ccu_mux_div_gate_ops; 223#endif /* _CCU_MIX_H_ */
~/
Read-only file preview.