1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (c) 2014 MediaTek Inc. 4*4882a593Smuzhiyun * Author: James Liao <jamesjj.liao@mediatek.com> 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef __DRV_CLK_MTK_H 8*4882a593Smuzhiyun #define __DRV_CLK_MTK_H 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/regmap.h> 11*4882a593Smuzhiyun #include <linux/bitops.h> 12*4882a593Smuzhiyun #include <linux/clk-provider.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun struct clk; 15*4882a593Smuzhiyun struct clk_onecell_data; 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun #define MAX_MUX_GATE_BIT 31 18*4882a593Smuzhiyun #define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1) 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #define MHZ (1000 * 1000) 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun struct mtk_fixed_clk { 23*4882a593Smuzhiyun int id; 24*4882a593Smuzhiyun const char *name; 25*4882a593Smuzhiyun const char *parent; 26*4882a593Smuzhiyun unsigned long rate; 27*4882a593Smuzhiyun }; 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define FIXED_CLK(_id, _name, _parent, _rate) { \ 30*4882a593Smuzhiyun .id = _id, \ 31*4882a593Smuzhiyun .name = _name, \ 32*4882a593Smuzhiyun .parent = _parent, \ 33*4882a593Smuzhiyun .rate = _rate, \ 34*4882a593Smuzhiyun } 35*4882a593Smuzhiyun 36*4882a593Smuzhiyun void mtk_clk_register_fixed_clks(const struct mtk_fixed_clk *clks, 37*4882a593Smuzhiyun int num, struct clk_onecell_data *clk_data); 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun struct mtk_fixed_factor { 40*4882a593Smuzhiyun int id; 41*4882a593Smuzhiyun const char *name; 42*4882a593Smuzhiyun const char *parent_name; 43*4882a593Smuzhiyun int mult; 44*4882a593Smuzhiyun int div; 45*4882a593Smuzhiyun }; 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun #define FACTOR(_id, _name, _parent, _mult, _div) { \ 48*4882a593Smuzhiyun .id = _id, \ 49*4882a593Smuzhiyun .name = _name, \ 50*4882a593Smuzhiyun .parent_name = _parent, \ 51*4882a593Smuzhiyun .mult = _mult, \ 52*4882a593Smuzhiyun .div = _div, \ 53*4882a593Smuzhiyun } 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, 56*4882a593Smuzhiyun int num, struct clk_onecell_data *clk_data); 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun struct mtk_composite { 59*4882a593Smuzhiyun int id; 60*4882a593Smuzhiyun const char *name; 61*4882a593Smuzhiyun const char * const *parent_names; 62*4882a593Smuzhiyun const char *parent; 63*4882a593Smuzhiyun unsigned flags; 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun uint32_t mux_reg; 66*4882a593Smuzhiyun uint32_t divider_reg; 67*4882a593Smuzhiyun uint32_t gate_reg; 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun signed char mux_shift; 70*4882a593Smuzhiyun signed char mux_width; 71*4882a593Smuzhiyun signed char gate_shift; 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun signed char divider_shift; 74*4882a593Smuzhiyun signed char divider_width; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun u8 mux_flags; 77*4882a593Smuzhiyun 78*4882a593Smuzhiyun signed char num_parents; 79*4882a593Smuzhiyun }; 80*4882a593Smuzhiyun 81*4882a593Smuzhiyun #define MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, _shift, \ 82*4882a593Smuzhiyun _width, _gate, _flags, _muxflags) { \ 83*4882a593Smuzhiyun .id = _id, \ 84*4882a593Smuzhiyun .name = _name, \ 85*4882a593Smuzhiyun .mux_reg = _reg, \ 86*4882a593Smuzhiyun .mux_shift = _shift, \ 87*4882a593Smuzhiyun .mux_width = _width, \ 88*4882a593Smuzhiyun .gate_reg = _reg, \ 89*4882a593Smuzhiyun .gate_shift = _gate, \ 90*4882a593Smuzhiyun .divider_shift = -1, \ 91*4882a593Smuzhiyun .parent_names = _parents, \ 92*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(_parents), \ 93*4882a593Smuzhiyun .flags = _flags, \ 94*4882a593Smuzhiyun .mux_flags = _muxflags, \ 95*4882a593Smuzhiyun } 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /* 98*4882a593Smuzhiyun * In case the rate change propagation to parent clocks is undesirable, 99*4882a593Smuzhiyun * this macro allows to specify the clock flags manually. 100*4882a593Smuzhiyun */ 101*4882a593Smuzhiyun #define MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \ 102*4882a593Smuzhiyun _gate, _flags) \ 103*4882a593Smuzhiyun MUX_GATE_FLAGS_2(_id, _name, _parents, _reg, \ 104*4882a593Smuzhiyun _shift, _width, _gate, _flags, 0) 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /* 107*4882a593Smuzhiyun * Unless necessary, all MUX_GATE clocks propagate rate changes to their 108*4882a593Smuzhiyun * parent clock by default. 109*4882a593Smuzhiyun */ 110*4882a593Smuzhiyun #define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) \ 111*4882a593Smuzhiyun MUX_GATE_FLAGS(_id, _name, _parents, _reg, _shift, _width, \ 112*4882a593Smuzhiyun _gate, CLK_SET_RATE_PARENT) 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun #define MUX(_id, _name, _parents, _reg, _shift, _width) \ 115*4882a593Smuzhiyun MUX_FLAGS(_id, _name, _parents, _reg, \ 116*4882a593Smuzhiyun _shift, _width, CLK_SET_RATE_PARENT) 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun #define MUX_FLAGS(_id, _name, _parents, _reg, _shift, _width, _flags) { \ 119*4882a593Smuzhiyun .id = _id, \ 120*4882a593Smuzhiyun .name = _name, \ 121*4882a593Smuzhiyun .mux_reg = _reg, \ 122*4882a593Smuzhiyun .mux_shift = _shift, \ 123*4882a593Smuzhiyun .mux_width = _width, \ 124*4882a593Smuzhiyun .gate_shift = -1, \ 125*4882a593Smuzhiyun .divider_shift = -1, \ 126*4882a593Smuzhiyun .parent_names = _parents, \ 127*4882a593Smuzhiyun .num_parents = ARRAY_SIZE(_parents), \ 128*4882a593Smuzhiyun .flags = _flags, \ 129*4882a593Smuzhiyun } 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun #define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, \ 132*4882a593Smuzhiyun _div_width, _div_shift) { \ 133*4882a593Smuzhiyun .id = _id, \ 134*4882a593Smuzhiyun .parent = _parent, \ 135*4882a593Smuzhiyun .name = _name, \ 136*4882a593Smuzhiyun .divider_reg = _div_reg, \ 137*4882a593Smuzhiyun .divider_shift = _div_shift, \ 138*4882a593Smuzhiyun .divider_width = _div_width, \ 139*4882a593Smuzhiyun .gate_reg = _gate_reg, \ 140*4882a593Smuzhiyun .gate_shift = _gate_shift, \ 141*4882a593Smuzhiyun .mux_shift = -1, \ 142*4882a593Smuzhiyun .flags = 0, \ 143*4882a593Smuzhiyun } 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, 146*4882a593Smuzhiyun void __iomem *base, spinlock_t *lock); 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun void mtk_clk_register_composites(const struct mtk_composite *mcs, 149*4882a593Smuzhiyun int num, void __iomem *base, spinlock_t *lock, 150*4882a593Smuzhiyun struct clk_onecell_data *clk_data); 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun struct mtk_gate_regs { 153*4882a593Smuzhiyun u32 sta_ofs; 154*4882a593Smuzhiyun u32 clr_ofs; 155*4882a593Smuzhiyun u32 set_ofs; 156*4882a593Smuzhiyun }; 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun struct mtk_gate { 159*4882a593Smuzhiyun int id; 160*4882a593Smuzhiyun const char *name; 161*4882a593Smuzhiyun const char *parent_name; 162*4882a593Smuzhiyun const struct mtk_gate_regs *regs; 163*4882a593Smuzhiyun int shift; 164*4882a593Smuzhiyun const struct clk_ops *ops; 165*4882a593Smuzhiyun unsigned long flags; 166*4882a593Smuzhiyun }; 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun int mtk_clk_register_gates(struct device_node *node, 169*4882a593Smuzhiyun const struct mtk_gate *clks, int num, 170*4882a593Smuzhiyun struct clk_onecell_data *clk_data); 171*4882a593Smuzhiyun 172*4882a593Smuzhiyun int mtk_clk_register_gates_with_dev(struct device_node *node, 173*4882a593Smuzhiyun const struct mtk_gate *clks, 174*4882a593Smuzhiyun int num, struct clk_onecell_data *clk_data, 175*4882a593Smuzhiyun struct device *dev); 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun struct mtk_clk_divider { 178*4882a593Smuzhiyun int id; 179*4882a593Smuzhiyun const char *name; 180*4882a593Smuzhiyun const char *parent_name; 181*4882a593Smuzhiyun unsigned long flags; 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun u32 div_reg; 184*4882a593Smuzhiyun unsigned char div_shift; 185*4882a593Smuzhiyun unsigned char div_width; 186*4882a593Smuzhiyun unsigned char clk_divider_flags; 187*4882a593Smuzhiyun const struct clk_div_table *clk_div_table; 188*4882a593Smuzhiyun }; 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun #define DIV_ADJ(_id, _name, _parent, _reg, _shift, _width) { \ 191*4882a593Smuzhiyun .id = _id, \ 192*4882a593Smuzhiyun .name = _name, \ 193*4882a593Smuzhiyun .parent_name = _parent, \ 194*4882a593Smuzhiyun .div_reg = _reg, \ 195*4882a593Smuzhiyun .div_shift = _shift, \ 196*4882a593Smuzhiyun .div_width = _width, \ 197*4882a593Smuzhiyun } 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun void mtk_clk_register_dividers(const struct mtk_clk_divider *mcds, 200*4882a593Smuzhiyun int num, void __iomem *base, spinlock_t *lock, 201*4882a593Smuzhiyun struct clk_onecell_data *clk_data); 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun #define HAVE_RST_BAR BIT(0) 206*4882a593Smuzhiyun #define PLL_AO BIT(1) 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun struct mtk_pll_div_table { 209*4882a593Smuzhiyun u32 div; 210*4882a593Smuzhiyun unsigned long freq; 211*4882a593Smuzhiyun }; 212*4882a593Smuzhiyun 213*4882a593Smuzhiyun struct mtk_pll_data { 214*4882a593Smuzhiyun int id; 215*4882a593Smuzhiyun const char *name; 216*4882a593Smuzhiyun uint32_t reg; 217*4882a593Smuzhiyun uint32_t pwr_reg; 218*4882a593Smuzhiyun uint32_t en_mask; 219*4882a593Smuzhiyun uint32_t pd_reg; 220*4882a593Smuzhiyun uint32_t tuner_reg; 221*4882a593Smuzhiyun uint32_t tuner_en_reg; 222*4882a593Smuzhiyun uint8_t tuner_en_bit; 223*4882a593Smuzhiyun int pd_shift; 224*4882a593Smuzhiyun unsigned int flags; 225*4882a593Smuzhiyun const struct clk_ops *ops; 226*4882a593Smuzhiyun u32 rst_bar_mask; 227*4882a593Smuzhiyun unsigned long fmin; 228*4882a593Smuzhiyun unsigned long fmax; 229*4882a593Smuzhiyun int pcwbits; 230*4882a593Smuzhiyun int pcwibits; 231*4882a593Smuzhiyun uint32_t pcw_reg; 232*4882a593Smuzhiyun int pcw_shift; 233*4882a593Smuzhiyun uint32_t pcw_chg_reg; 234*4882a593Smuzhiyun const struct mtk_pll_div_table *div_table; 235*4882a593Smuzhiyun const char *parent_name; 236*4882a593Smuzhiyun }; 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun void mtk_clk_register_plls(struct device_node *node, 239*4882a593Smuzhiyun const struct mtk_pll_data *plls, int num_plls, 240*4882a593Smuzhiyun struct clk_onecell_data *clk_data); 241*4882a593Smuzhiyun 242*4882a593Smuzhiyun struct clk *mtk_clk_register_ref2usb_tx(const char *name, 243*4882a593Smuzhiyun const char *parent_name, void __iomem *reg); 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun void mtk_register_reset_controller(struct device_node *np, 246*4882a593Smuzhiyun unsigned int num_regs, int regofs); 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun void mtk_register_reset_controller_set_clr(struct device_node *np, 249*4882a593Smuzhiyun unsigned int num_regs, int regofs); 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun #endif /* __DRV_CLK_MTK_H */ 252