0001
0002
0003
0004
0005
0006 #ifndef _CCU_DIV_H_
0007 #define _CCU_DIV_H_
0008
0009 #include <linux/clk-provider.h>
0010
0011 #include "ccu_common.h"
0012 #include "ccu_mux.h"
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 struct ccu_div_internal {
0032 u8 shift;
0033 u8 width;
0034
0035 u32 max;
0036 u32 offset;
0037
0038 u32 flags;
0039
0040 struct clk_div_table *table;
0041 };
0042
0043 #define _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, _flags) \
0044 { \
0045 .shift = _shift, \
0046 .width = _width, \
0047 .flags = _flags, \
0048 .table = _table, \
0049 }
0050
0051 #define _SUNXI_CCU_DIV_TABLE(_shift, _width, _table) \
0052 _SUNXI_CCU_DIV_TABLE_FLAGS(_shift, _width, _table, 0)
0053
0054 #define _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _off, _max, _flags) \
0055 { \
0056 .shift = _shift, \
0057 .width = _width, \
0058 .flags = _flags, \
0059 .max = _max, \
0060 .offset = _off, \
0061 }
0062
0063 #define _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, _flags) \
0064 _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, 1, _max, _flags)
0065
0066 #define _SUNXI_CCU_DIV_FLAGS(_shift, _width, _flags) \
0067 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, 0, _flags)
0068
0069 #define _SUNXI_CCU_DIV_MAX(_shift, _width, _max) \
0070 _SUNXI_CCU_DIV_MAX_FLAGS(_shift, _width, _max, 0)
0071
0072 #define _SUNXI_CCU_DIV_OFFSET(_shift, _width, _offset) \
0073 _SUNXI_CCU_DIV_OFFSET_MAX_FLAGS(_shift, _width, _offset, 0, 0)
0074
0075 #define _SUNXI_CCU_DIV(_shift, _width) \
0076 _SUNXI_CCU_DIV_FLAGS(_shift, _width, 0)
0077
0078 struct ccu_div {
0079 u32 enable;
0080
0081 struct ccu_div_internal div;
0082 struct ccu_mux_internal mux;
0083 struct ccu_common common;
0084 unsigned int fixed_post_div;
0085 };
0086
0087 #define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
0088 _shift, _width, \
0089 _table, _gate, _flags) \
0090 struct ccu_div _struct = { \
0091 .div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \
0092 _table), \
0093 .enable = _gate, \
0094 .common = { \
0095 .reg = _reg, \
0096 .hw.init = CLK_HW_INIT(_name, \
0097 _parent, \
0098 &ccu_div_ops, \
0099 _flags), \
0100 } \
0101 }
0102
0103
0104 #define SUNXI_CCU_DIV_TABLE(_struct, _name, _parent, _reg, \
0105 _shift, _width, \
0106 _table, _flags) \
0107 SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
0108 _shift, _width, _table, 0, \
0109 _flags)
0110
0111 #define SUNXI_CCU_DIV_TABLE_HW(_struct, _name, _parent, _reg, \
0112 _shift, _width, \
0113 _table, _flags) \
0114 struct ccu_div _struct = { \
0115 .div = _SUNXI_CCU_DIV_TABLE(_shift, _width, \
0116 _table), \
0117 .common = { \
0118 .reg = _reg, \
0119 .hw.init = CLK_HW_INIT_HW(_name, \
0120 _parent, \
0121 &ccu_div_ops, \
0122 _flags), \
0123 } \
0124 }
0125
0126
0127 #define SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
0128 _parents, _table, \
0129 _reg, \
0130 _mshift, _mwidth, \
0131 _muxshift, _muxwidth, \
0132 _gate, _flags) \
0133 struct ccu_div _struct = { \
0134 .enable = _gate, \
0135 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
0136 .mux = _SUNXI_CCU_MUX_TABLE(_muxshift, _muxwidth, _table), \
0137 .common = { \
0138 .reg = _reg, \
0139 .hw.init = CLK_HW_INIT_PARENTS(_name, \
0140 _parents, \
0141 &ccu_div_ops, \
0142 _flags), \
0143 }, \
0144 }
0145
0146 #define SUNXI_CCU_M_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
0147 _mshift, _mwidth, _muxshift, _muxwidth, \
0148 _gate, _flags) \
0149 SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
0150 _parents, NULL, \
0151 _reg, _mshift, _mwidth, \
0152 _muxshift, _muxwidth, \
0153 _gate, _flags)
0154
0155 #define SUNXI_CCU_M_WITH_MUX(_struct, _name, _parents, _reg, \
0156 _mshift, _mwidth, _muxshift, _muxwidth, \
0157 _flags) \
0158 SUNXI_CCU_M_WITH_MUX_TABLE_GATE(_struct, _name, \
0159 _parents, NULL, \
0160 _reg, _mshift, _mwidth, \
0161 _muxshift, _muxwidth, \
0162 0, _flags)
0163
0164
0165 #define SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
0166 _mshift, _mwidth, _gate, \
0167 _flags) \
0168 struct ccu_div _struct = { \
0169 .enable = _gate, \
0170 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
0171 .common = { \
0172 .reg = _reg, \
0173 .hw.init = CLK_HW_INIT(_name, \
0174 _parent, \
0175 &ccu_div_ops, \
0176 _flags), \
0177 }, \
0178 }
0179
0180 #define SUNXI_CCU_M(_struct, _name, _parent, _reg, _mshift, _mwidth, \
0181 _flags) \
0182 SUNXI_CCU_M_WITH_GATE(_struct, _name, _parent, _reg, \
0183 _mshift, _mwidth, 0, _flags)
0184
0185 #define SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
0186 _mshift, _mwidth, \
0187 _muxshift, _muxwidth, \
0188 _gate, _flags) \
0189 struct ccu_div _struct = { \
0190 .enable = _gate, \
0191 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
0192 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
0193 .common = { \
0194 .reg = _reg, \
0195 .hw.init = CLK_HW_INIT_PARENTS_DATA(_name, \
0196 _parents, \
0197 &ccu_div_ops, \
0198 _flags), \
0199 }, \
0200 }
0201
0202 #define SUNXI_CCU_M_DATA_WITH_MUX(_struct, _name, _parents, _reg, \
0203 _mshift, _mwidth, \
0204 _muxshift, _muxwidth, \
0205 _flags) \
0206 SUNXI_CCU_M_DATA_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
0207 _mshift, _mwidth, \
0208 _muxshift, _muxwidth, \
0209 0, _flags)
0210
0211 #define SUNXI_CCU_M_HW_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
0212 _mshift, _mwidth, _muxshift, _muxwidth, \
0213 _gate, _flags) \
0214 struct ccu_div _struct = { \
0215 .enable = _gate, \
0216 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
0217 .mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
0218 .common = { \
0219 .reg = _reg, \
0220 .hw.init = CLK_HW_INIT_PARENTS_HW(_name, \
0221 _parents, \
0222 &ccu_div_ops, \
0223 _flags), \
0224 }, \
0225 }
0226
0227 #define SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \
0228 _mshift, _mwidth, _gate, \
0229 _flags) \
0230 struct ccu_div _struct = { \
0231 .enable = _gate, \
0232 .div = _SUNXI_CCU_DIV(_mshift, _mwidth), \
0233 .common = { \
0234 .reg = _reg, \
0235 .hw.init = CLK_HW_INIT_HWS(_name, \
0236 _parent, \
0237 &ccu_div_ops, \
0238 _flags), \
0239 }, \
0240 }
0241
0242 #define SUNXI_CCU_M_HWS(_struct, _name, _parent, _reg, _mshift, \
0243 _mwidth, _flags) \
0244 SUNXI_CCU_M_HWS_WITH_GATE(_struct, _name, _parent, _reg, \
0245 _mshift, _mwidth, 0, _flags)
0246
0247 static inline struct ccu_div *hw_to_ccu_div(struct clk_hw *hw)
0248 {
0249 struct ccu_common *common = hw_to_ccu_common(hw);
0250
0251 return container_of(common, struct ccu_div, common);
0252 }
0253
0254 extern const struct clk_ops ccu_div_ops;
0255
0256 #endif