1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0 */ 2*4882a593Smuzhiyun /* Copyright (c) 2013, 2018, The Linux Foundation. All rights reserved. */ 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun #ifndef __QCOM_CLK_RCG_H__ 5*4882a593Smuzhiyun #define __QCOM_CLK_RCG_H__ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #include <linux/clk-provider.h> 8*4882a593Smuzhiyun #include "clk-regmap.h" 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) } 11*4882a593Smuzhiyun 12*4882a593Smuzhiyun struct freq_tbl { 13*4882a593Smuzhiyun unsigned long freq; 14*4882a593Smuzhiyun u8 src; 15*4882a593Smuzhiyun u8 pre_div; 16*4882a593Smuzhiyun u16 m; 17*4882a593Smuzhiyun u16 n; 18*4882a593Smuzhiyun }; 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun /** 21*4882a593Smuzhiyun * struct mn - M/N:D counter 22*4882a593Smuzhiyun * @mnctr_en_bit: bit to enable mn counter 23*4882a593Smuzhiyun * @mnctr_reset_bit: bit to assert mn counter reset 24*4882a593Smuzhiyun * @mnctr_mode_shift: lowest bit of mn counter mode field 25*4882a593Smuzhiyun * @n_val_shift: lowest bit of n value field 26*4882a593Smuzhiyun * @m_val_shift: lowest bit of m value field 27*4882a593Smuzhiyun * @width: number of bits in m/n/d values 28*4882a593Smuzhiyun * @reset_in_cc: true if the mnctr_reset_bit is in the CC register 29*4882a593Smuzhiyun */ 30*4882a593Smuzhiyun struct mn { 31*4882a593Smuzhiyun u8 mnctr_en_bit; 32*4882a593Smuzhiyun u8 mnctr_reset_bit; 33*4882a593Smuzhiyun u8 mnctr_mode_shift; 34*4882a593Smuzhiyun #define MNCTR_MODE_DUAL 0x2 35*4882a593Smuzhiyun #define MNCTR_MODE_MASK 0x3 36*4882a593Smuzhiyun u8 n_val_shift; 37*4882a593Smuzhiyun u8 m_val_shift; 38*4882a593Smuzhiyun u8 width; 39*4882a593Smuzhiyun bool reset_in_cc; 40*4882a593Smuzhiyun }; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /** 43*4882a593Smuzhiyun * struct pre_div - pre-divider 44*4882a593Smuzhiyun * @pre_div_shift: lowest bit of pre divider field 45*4882a593Smuzhiyun * @pre_div_width: number of bits in predivider 46*4882a593Smuzhiyun */ 47*4882a593Smuzhiyun struct pre_div { 48*4882a593Smuzhiyun u8 pre_div_shift; 49*4882a593Smuzhiyun u8 pre_div_width; 50*4882a593Smuzhiyun }; 51*4882a593Smuzhiyun 52*4882a593Smuzhiyun /** 53*4882a593Smuzhiyun * struct src_sel - source selector 54*4882a593Smuzhiyun * @src_sel_shift: lowest bit of source selection field 55*4882a593Smuzhiyun * @parent_map: map from software's parent index to hardware's src_sel field 56*4882a593Smuzhiyun */ 57*4882a593Smuzhiyun struct src_sel { 58*4882a593Smuzhiyun u8 src_sel_shift; 59*4882a593Smuzhiyun #define SRC_SEL_MASK 0x7 60*4882a593Smuzhiyun const struct parent_map *parent_map; 61*4882a593Smuzhiyun }; 62*4882a593Smuzhiyun 63*4882a593Smuzhiyun /** 64*4882a593Smuzhiyun * struct clk_rcg - root clock generator 65*4882a593Smuzhiyun * 66*4882a593Smuzhiyun * @ns_reg: NS register 67*4882a593Smuzhiyun * @md_reg: MD register 68*4882a593Smuzhiyun * @mn: mn counter 69*4882a593Smuzhiyun * @p: pre divider 70*4882a593Smuzhiyun * @s: source selector 71*4882a593Smuzhiyun * @freq_tbl: frequency table 72*4882a593Smuzhiyun * @clkr: regmap clock handle 73*4882a593Smuzhiyun * @lock: register lock 74*4882a593Smuzhiyun */ 75*4882a593Smuzhiyun struct clk_rcg { 76*4882a593Smuzhiyun u32 ns_reg; 77*4882a593Smuzhiyun u32 md_reg; 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun struct mn mn; 80*4882a593Smuzhiyun struct pre_div p; 81*4882a593Smuzhiyun struct src_sel s; 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun const struct freq_tbl *freq_tbl; 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun struct clk_regmap clkr; 86*4882a593Smuzhiyun }; 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun extern const struct clk_ops clk_rcg_ops; 89*4882a593Smuzhiyun extern const struct clk_ops clk_rcg_bypass_ops; 90*4882a593Smuzhiyun extern const struct clk_ops clk_rcg_bypass2_ops; 91*4882a593Smuzhiyun extern const struct clk_ops clk_rcg_pixel_ops; 92*4882a593Smuzhiyun extern const struct clk_ops clk_rcg_esc_ops; 93*4882a593Smuzhiyun extern const struct clk_ops clk_rcg_lcc_ops; 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun #define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr) 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /** 98*4882a593Smuzhiyun * struct clk_dyn_rcg - root clock generator with glitch free mux 99*4882a593Smuzhiyun * 100*4882a593Smuzhiyun * @mux_sel_bit: bit to switch glitch free mux 101*4882a593Smuzhiyun * @ns_reg: NS0 and NS1 register 102*4882a593Smuzhiyun * @md_reg: MD0 and MD1 register 103*4882a593Smuzhiyun * @bank_reg: register to XOR @mux_sel_bit into to switch glitch free mux 104*4882a593Smuzhiyun * @mn: mn counter (banked) 105*4882a593Smuzhiyun * @s: source selector (banked) 106*4882a593Smuzhiyun * @freq_tbl: frequency table 107*4882a593Smuzhiyun * @clkr: regmap clock handle 108*4882a593Smuzhiyun * @lock: register lock 109*4882a593Smuzhiyun */ 110*4882a593Smuzhiyun struct clk_dyn_rcg { 111*4882a593Smuzhiyun u32 ns_reg[2]; 112*4882a593Smuzhiyun u32 md_reg[2]; 113*4882a593Smuzhiyun u32 bank_reg; 114*4882a593Smuzhiyun 115*4882a593Smuzhiyun u8 mux_sel_bit; 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun struct mn mn[2]; 118*4882a593Smuzhiyun struct pre_div p[2]; 119*4882a593Smuzhiyun struct src_sel s[2]; 120*4882a593Smuzhiyun 121*4882a593Smuzhiyun const struct freq_tbl *freq_tbl; 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun struct clk_regmap clkr; 124*4882a593Smuzhiyun }; 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun extern const struct clk_ops clk_dyn_rcg_ops; 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun #define to_clk_dyn_rcg(_hw) \ 129*4882a593Smuzhiyun container_of(to_clk_regmap(_hw), struct clk_dyn_rcg, clkr) 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /** 132*4882a593Smuzhiyun * struct clk_rcg2 - root clock generator 133*4882a593Smuzhiyun * 134*4882a593Smuzhiyun * @cmd_rcgr: corresponds to *_CMD_RCGR 135*4882a593Smuzhiyun * @mnd_width: number of bits in m/n/d values 136*4882a593Smuzhiyun * @hid_width: number of bits in half integer divider 137*4882a593Smuzhiyun * @safe_src_index: safe src index value 138*4882a593Smuzhiyun * @parent_map: map from software's parent index to hardware's src_sel field 139*4882a593Smuzhiyun * @freq_tbl: frequency table 140*4882a593Smuzhiyun * @clkr: regmap clock handle 141*4882a593Smuzhiyun * @cfg_off: defines the cfg register offset from the CMD_RCGR + CFG_REG 142*4882a593Smuzhiyun */ 143*4882a593Smuzhiyun struct clk_rcg2 { 144*4882a593Smuzhiyun u32 cmd_rcgr; 145*4882a593Smuzhiyun u8 mnd_width; 146*4882a593Smuzhiyun u8 hid_width; 147*4882a593Smuzhiyun u8 safe_src_index; 148*4882a593Smuzhiyun const struct parent_map *parent_map; 149*4882a593Smuzhiyun const struct freq_tbl *freq_tbl; 150*4882a593Smuzhiyun struct clk_regmap clkr; 151*4882a593Smuzhiyun u8 cfg_off; 152*4882a593Smuzhiyun }; 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #define to_clk_rcg2(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg2, clkr) 155*4882a593Smuzhiyun 156*4882a593Smuzhiyun extern const struct clk_ops clk_rcg2_ops; 157*4882a593Smuzhiyun extern const struct clk_ops clk_rcg2_floor_ops; 158*4882a593Smuzhiyun extern const struct clk_ops clk_edp_pixel_ops; 159*4882a593Smuzhiyun extern const struct clk_ops clk_byte_ops; 160*4882a593Smuzhiyun extern const struct clk_ops clk_byte2_ops; 161*4882a593Smuzhiyun extern const struct clk_ops clk_pixel_ops; 162*4882a593Smuzhiyun extern const struct clk_ops clk_gfx3d_ops; 163*4882a593Smuzhiyun extern const struct clk_ops clk_rcg2_shared_ops; 164*4882a593Smuzhiyun extern const struct clk_ops clk_dp_ops; 165*4882a593Smuzhiyun 166*4882a593Smuzhiyun struct clk_rcg_dfs_data { 167*4882a593Smuzhiyun struct clk_rcg2 *rcg; 168*4882a593Smuzhiyun struct clk_init_data *init; 169*4882a593Smuzhiyun }; 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun #define DEFINE_RCG_DFS(r) \ 172*4882a593Smuzhiyun { .rcg = &r, .init = &r##_init } 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, 175*4882a593Smuzhiyun const struct clk_rcg_dfs_data *rcgs, 176*4882a593Smuzhiyun size_t len); 177*4882a593Smuzhiyun #endif 178