55 */
66
77#include <linux/clk-provider.h>
8+ #include <linux/dev_printk.h>
89#include <linux/mfd/syscon.h>
910#include <linux/module.h>
1011#include <linux/printk.h>
1112#include <linux/regmap.h>
1213#include <linux/slab.h>
1314#include <linux/types.h>
1415
16+ #include "clk-mtk.h"
1517#include "clk-gate.h"
1618
1719struct mtk_clk_gate {
1820 struct clk_hw hw ;
1921 struct regmap * regmap ;
22+ struct regmap * regmap_hwv ;
2023 const struct mtk_gate * gate ;
2124};
2225
@@ -99,6 +102,32 @@ static void mtk_cg_disable_inv(struct clk_hw *hw)
99102 mtk_cg_clr_bit (hw );
100103}
101104
105+ static int mtk_cg_hwv_set_en (struct clk_hw * hw , bool enable )
106+ {
107+ struct mtk_clk_gate * cg = to_mtk_clk_gate (hw );
108+ u32 val ;
109+
110+ regmap_write (cg -> regmap_hwv ,
111+ enable ? cg -> gate -> hwv_regs -> set_ofs :
112+ cg -> gate -> hwv_regs -> clr_ofs ,
113+ BIT (cg -> gate -> shift ));
114+
115+ return regmap_read_poll_timeout_atomic (cg -> regmap_hwv ,
116+ cg -> gate -> hwv_regs -> sta_ofs , val ,
117+ val & BIT (cg -> gate -> shift ), 0 ,
118+ MTK_WAIT_HWV_DONE_US );
119+ }
120+
121+ static int mtk_cg_hwv_enable (struct clk_hw * hw )
122+ {
123+ return mtk_cg_hwv_set_en (hw , true);
124+ }
125+
126+ static void mtk_cg_hwv_disable (struct clk_hw * hw )
127+ {
128+ mtk_cg_hwv_set_en (hw , false);
129+ }
130+
102131static int mtk_cg_enable_no_setclr (struct clk_hw * hw )
103132{
104133 mtk_cg_clr_bit_no_setclr (hw );
@@ -123,6 +152,15 @@ static void mtk_cg_disable_inv_no_setclr(struct clk_hw *hw)
123152 mtk_cg_clr_bit_no_setclr (hw );
124153}
125154
155+ static bool mtk_cg_uses_hwv (const struct clk_ops * ops )
156+ {
157+ if (ops == & mtk_clk_gate_hwv_ops_setclr ||
158+ ops == & mtk_clk_gate_hwv_ops_setclr_inv )
159+ return true;
160+
161+ return false;
162+ }
163+
126164const struct clk_ops mtk_clk_gate_ops_setclr = {
127165 .is_enabled = mtk_cg_bit_is_cleared ,
128166 .enable = mtk_cg_enable ,
@@ -137,6 +175,20 @@ const struct clk_ops mtk_clk_gate_ops_setclr_inv = {
137175};
138176EXPORT_SYMBOL_GPL (mtk_clk_gate_ops_setclr_inv );
139177
178+ const struct clk_ops mtk_clk_gate_hwv_ops_setclr = {
179+ .is_enabled = mtk_cg_bit_is_cleared ,
180+ .enable = mtk_cg_hwv_enable ,
181+ .disable = mtk_cg_hwv_disable ,
182+ };
183+ EXPORT_SYMBOL_GPL (mtk_clk_gate_hwv_ops_setclr );
184+
185+ const struct clk_ops mtk_clk_gate_hwv_ops_setclr_inv = {
186+ .is_enabled = mtk_cg_bit_is_set ,
187+ .enable = mtk_cg_hwv_enable ,
188+ .disable = mtk_cg_hwv_disable ,
189+ };
190+ EXPORT_SYMBOL_GPL (mtk_clk_gate_hwv_ops_setclr_inv );
191+
140192const struct clk_ops mtk_clk_gate_ops_no_setclr = {
141193 .is_enabled = mtk_cg_bit_is_cleared ,
142194 .enable = mtk_cg_enable_no_setclr ,
@@ -152,8 +204,9 @@ const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
152204EXPORT_SYMBOL_GPL (mtk_clk_gate_ops_no_setclr_inv );
153205
154206static struct clk_hw * mtk_clk_register_gate (struct device * dev ,
155- const struct mtk_gate * gate ,
156- struct regmap * regmap )
207+ const struct mtk_gate * gate ,
208+ struct regmap * regmap ,
209+ struct regmap * regmap_hwv )
157210{
158211 struct mtk_clk_gate * cg ;
159212 int ret ;
@@ -168,8 +221,13 @@ static struct clk_hw *mtk_clk_register_gate(struct device *dev,
168221 init .parent_names = gate -> parent_name ? & gate -> parent_name : NULL ;
169222 init .num_parents = gate -> parent_name ? 1 : 0 ;
170223 init .ops = gate -> ops ;
224+ if (mtk_cg_uses_hwv (init .ops ) && !regmap_hwv )
225+ return dev_err_ptr_probe (
226+ dev , - ENXIO ,
227+ "regmap not found for hardware voter clocks\n" );
171228
172229 cg -> regmap = regmap ;
230+ cg -> regmap_hwv = regmap_hwv ;
173231 cg -> gate = gate ;
174232 cg -> hw .init = & init ;
175233
@@ -201,6 +259,7 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node,
201259 int i ;
202260 struct clk_hw * hw ;
203261 struct regmap * regmap ;
262+ struct regmap * regmap_hwv ;
204263
205264 if (!clk_data )
206265 return - ENOMEM ;
@@ -211,6 +270,12 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node,
211270 return PTR_ERR (regmap );
212271 }
213272
273+ regmap_hwv = mtk_clk_get_hwv_regmap (node );
274+ if (IS_ERR (regmap_hwv ))
275+ return dev_err_probe (
276+ dev , PTR_ERR (regmap_hwv ),
277+ "Cannot find hardware voter regmap for %pOF\n" , node );
278+
214279 for (i = 0 ; i < num ; i ++ ) {
215280 const struct mtk_gate * gate = & clks [i ];
216281
@@ -220,7 +285,7 @@ int mtk_clk_register_gates(struct device *dev, struct device_node *node,
220285 continue ;
221286 }
222287
223- hw = mtk_clk_register_gate (dev , gate , regmap );
288+ hw = mtk_clk_register_gate (dev , gate , regmap , regmap_hwv );
224289
225290 if (IS_ERR (hw )) {
226291 pr_err ("Failed to register clk %s: %pe\n" , gate -> name ,
0 commit comments