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_dp_ops; |
180 | |
181 | struct clk_rcg_dfs_data { |
182 | struct clk_rcg2 *rcg; |
183 | struct clk_init_data *init; |
184 | }; |
185 | |
186 | #define DEFINE_RCG_DFS(r) \ |
187 | { .rcg = &r, .init = &r##_init } |
188 | |
189 | extern int qcom_cc_register_rcg_dfs(struct regmap *regmap, |
190 | const struct clk_rcg_dfs_data *rcgs, |
191 | size_t len); |
192 | #endif |
193 | |