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