hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/drivers/clk/x86/clk-cgu.c
....@@ -1,8 +1,9 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3
+ * Copyright (C) 2020-2022 MaxLinear, Inc.
34 * Copyright (C) 2020 Intel Corporation.
4
- * Zhu YiXin <yixin.zhu@intel.com>
5
- * Rahul Tanwar <rahul.tanwar@intel.com>
5
+ * Zhu Yixin <yzhu@maxlinear.com>
6
+ * Rahul Tanwar <rtanwar@maxlinear.com>
67 */
78 #include <linux/clk-provider.h>
89 #include <linux/device.h>
....@@ -24,14 +25,10 @@
2425 static struct clk_hw *lgm_clk_register_fixed(struct lgm_clk_provider *ctx,
2526 const struct lgm_clk_branch *list)
2627 {
27
- unsigned long flags;
2828
29
- if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
30
- spin_lock_irqsave(&ctx->lock, flags);
29
+ if (list->div_flags & CLOCK_FLAG_VAL_INIT)
3130 lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
3231 list->div_width, list->div_val);
33
- spin_unlock_irqrestore(&ctx->lock, flags);
34
- }
3532
3633 return clk_hw_register_fixed_rate(NULL, list->name,
3734 list->parent_data[0].name,
....@@ -41,33 +38,27 @@
4138 static u8 lgm_clk_mux_get_parent(struct clk_hw *hw)
4239 {
4340 struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
44
- unsigned long flags;
4541 u32 val;
4642
47
- spin_lock_irqsave(&mux->lock, flags);
4843 if (mux->flags & MUX_CLK_SW)
4944 val = mux->reg;
5045 else
5146 val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift,
5247 mux->width);
53
- spin_unlock_irqrestore(&mux->lock, flags);
5448 return clk_mux_val_to_index(hw, NULL, mux->flags, val);
5549 }
5650
5751 static int lgm_clk_mux_set_parent(struct clk_hw *hw, u8 index)
5852 {
5953 struct lgm_clk_mux *mux = to_lgm_clk_mux(hw);
60
- unsigned long flags;
6154 u32 val;
6255
6356 val = clk_mux_index_to_val(NULL, mux->flags, index);
64
- spin_lock_irqsave(&mux->lock, flags);
6557 if (mux->flags & MUX_CLK_SW)
6658 mux->reg = val;
6759 else
6860 lgm_set_clk_val(mux->membase, mux->reg, mux->shift,
6961 mux->width, val);
70
- spin_unlock_irqrestore(&mux->lock, flags);
7162
7263 return 0;
7364 }
....@@ -90,7 +81,7 @@
9081 lgm_clk_register_mux(struct lgm_clk_provider *ctx,
9182 const struct lgm_clk_branch *list)
9283 {
93
- unsigned long flags, cflags = list->mux_flags;
84
+ unsigned long cflags = list->mux_flags;
9485 struct device *dev = ctx->dev;
9586 u8 shift = list->mux_shift;
9687 u8 width = list->mux_width;
....@@ -111,7 +102,6 @@
111102 init.num_parents = list->num_parents;
112103
113104 mux->membase = ctx->membase;
114
- mux->lock = ctx->lock;
115105 mux->reg = reg;
116106 mux->shift = shift;
117107 mux->width = width;
....@@ -123,11 +113,8 @@
123113 if (ret)
124114 return ERR_PTR(ret);
125115
126
- if (cflags & CLOCK_FLAG_VAL_INIT) {
127
- spin_lock_irqsave(&mux->lock, flags);
116
+ if (cflags & CLOCK_FLAG_VAL_INIT)
128117 lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val);
129
- spin_unlock_irqrestore(&mux->lock, flags);
130
- }
131118
132119 return hw;
133120 }
....@@ -136,13 +123,10 @@
136123 lgm_clk_divider_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
137124 {
138125 struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
139
- unsigned long flags;
140126 unsigned int val;
141127
142
- spin_lock_irqsave(&divider->lock, flags);
143128 val = lgm_get_clk_val(divider->membase, divider->reg,
144129 divider->shift, divider->width);
145
- spin_unlock_irqrestore(&divider->lock, flags);
146130
147131 return divider_recalc_rate(hw, parent_rate, val, divider->table,
148132 divider->flags, divider->width);
....@@ -163,7 +147,6 @@
163147 unsigned long prate)
164148 {
165149 struct lgm_clk_divider *divider = to_lgm_clk_divider(hw);
166
- unsigned long flags;
167150 int value;
168151
169152 value = divider_get_val(rate, prate, divider->table,
....@@ -171,10 +154,8 @@
171154 if (value < 0)
172155 return value;
173156
174
- spin_lock_irqsave(&divider->lock, flags);
175157 lgm_set_clk_val(divider->membase, divider->reg,
176158 divider->shift, divider->width, value);
177
- spin_unlock_irqrestore(&divider->lock, flags);
178159
179160 return 0;
180161 }
....@@ -182,12 +163,10 @@
182163 static int lgm_clk_divider_enable_disable(struct clk_hw *hw, int enable)
183164 {
184165 struct lgm_clk_divider *div = to_lgm_clk_divider(hw);
185
- unsigned long flags;
186166
187
- spin_lock_irqsave(&div->lock, flags);
188
- lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
189
- div->width_gate, enable);
190
- spin_unlock_irqrestore(&div->lock, flags);
167
+ if (div->flags != DIV_CLK_NO_MASK)
168
+ lgm_set_clk_val(div->membase, div->reg, div->shift_gate,
169
+ div->width_gate, enable);
191170 return 0;
192171 }
193172
....@@ -213,7 +192,7 @@
213192 lgm_clk_register_divider(struct lgm_clk_provider *ctx,
214193 const struct lgm_clk_branch *list)
215194 {
216
- unsigned long flags, cflags = list->div_flags;
195
+ unsigned long cflags = list->div_flags;
217196 struct device *dev = ctx->dev;
218197 struct lgm_clk_divider *div;
219198 struct clk_init_data init = {};
....@@ -236,7 +215,6 @@
236215 init.num_parents = 1;
237216
238217 div->membase = ctx->membase;
239
- div->lock = ctx->lock;
240218 div->reg = reg;
241219 div->shift = shift;
242220 div->width = width;
....@@ -251,11 +229,8 @@
251229 if (ret)
252230 return ERR_PTR(ret);
253231
254
- if (cflags & CLOCK_FLAG_VAL_INIT) {
255
- spin_lock_irqsave(&div->lock, flags);
232
+ if (cflags & CLOCK_FLAG_VAL_INIT)
256233 lgm_set_clk_val(div->membase, reg, shift, width, list->div_val);
257
- spin_unlock_irqrestore(&div->lock, flags);
258
- }
259234
260235 return hw;
261236 }
....@@ -264,7 +239,6 @@
264239 lgm_clk_register_fixed_factor(struct lgm_clk_provider *ctx,
265240 const struct lgm_clk_branch *list)
266241 {
267
- unsigned long flags;
268242 struct clk_hw *hw;
269243
270244 hw = clk_hw_register_fixed_factor(ctx->dev, list->name,
....@@ -273,12 +247,9 @@
273247 if (IS_ERR(hw))
274248 return ERR_CAST(hw);
275249
276
- if (list->div_flags & CLOCK_FLAG_VAL_INIT) {
277
- spin_lock_irqsave(&ctx->lock, flags);
250
+ if (list->div_flags & CLOCK_FLAG_VAL_INIT)
278251 lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift,
279252 list->div_width, list->div_val);
280
- spin_unlock_irqrestore(&ctx->lock, flags);
281
- }
282253
283254 return hw;
284255 }
....@@ -286,13 +257,10 @@
286257 static int lgm_clk_gate_enable(struct clk_hw *hw)
287258 {
288259 struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
289
- unsigned long flags;
290260 unsigned int reg;
291261
292
- spin_lock_irqsave(&gate->lock, flags);
293262 reg = GATE_HW_REG_EN(gate->reg);
294263 lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
295
- spin_unlock_irqrestore(&gate->lock, flags);
296264
297265 return 0;
298266 }
....@@ -300,25 +268,19 @@
300268 static void lgm_clk_gate_disable(struct clk_hw *hw)
301269 {
302270 struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
303
- unsigned long flags;
304271 unsigned int reg;
305272
306
- spin_lock_irqsave(&gate->lock, flags);
307273 reg = GATE_HW_REG_DIS(gate->reg);
308274 lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1);
309
- spin_unlock_irqrestore(&gate->lock, flags);
310275 }
311276
312277 static int lgm_clk_gate_is_enabled(struct clk_hw *hw)
313278 {
314279 struct lgm_clk_gate *gate = to_lgm_clk_gate(hw);
315280 unsigned int reg, ret;
316
- unsigned long flags;
317281
318
- spin_lock_irqsave(&gate->lock, flags);
319282 reg = GATE_HW_REG_STAT(gate->reg);
320283 ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1);
321
- spin_unlock_irqrestore(&gate->lock, flags);
322284
323285 return ret;
324286 }
....@@ -333,7 +295,7 @@
333295 lgm_clk_register_gate(struct lgm_clk_provider *ctx,
334296 const struct lgm_clk_branch *list)
335297 {
336
- unsigned long flags, cflags = list->gate_flags;
298
+ unsigned long cflags = list->gate_flags;
337299 const char *pname = list->parent_data[0].name;
338300 struct device *dev = ctx->dev;
339301 u8 shift = list->gate_shift;
....@@ -354,7 +316,6 @@
354316 init.num_parents = pname ? 1 : 0;
355317
356318 gate->membase = ctx->membase;
357
- gate->lock = ctx->lock;
358319 gate->reg = reg;
359320 gate->shift = shift;
360321 gate->flags = cflags;
....@@ -366,9 +327,7 @@
366327 return ERR_PTR(ret);
367328
368329 if (cflags & CLOCK_FLAG_VAL_INIT) {
369
- spin_lock_irqsave(&gate->lock, flags);
370330 lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val);
371
- spin_unlock_irqrestore(&gate->lock, flags);
372331 }
373332
374333 return hw;
....@@ -396,8 +355,22 @@
396355 hw = lgm_clk_register_fixed_factor(ctx, list);
397356 break;
398357 case CLK_TYPE_GATE:
399
- hw = lgm_clk_register_gate(ctx, list);
358
+ if (list->gate_flags & GATE_CLK_HW) {
359
+ hw = lgm_clk_register_gate(ctx, list);
360
+ } else {
361
+ /*
362
+ * GATE_CLKs can be controlled either from
363
+ * CGU clk driver i.e. this driver or directly
364
+ * from power management driver/daemon. It is
365
+ * dependent on the power policy/profile requirements
366
+ * of the end product. To override control of gate
367
+ * clks from this driver, provide NULL for this index
368
+ * of gate clk provider.
369
+ */
370
+ hw = NULL;
371
+ }
400372 break;
373
+
401374 default:
402375 dev_err(ctx->dev, "invalid clk type\n");
403376 return -EINVAL;
....@@ -443,24 +416,18 @@
443416 static int lgm_clk_ddiv_enable(struct clk_hw *hw)
444417 {
445418 struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
446
- unsigned long flags;
447419
448
- spin_lock_irqsave(&ddiv->lock, flags);
449420 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
450421 ddiv->width_gate, 1);
451
- spin_unlock_irqrestore(&ddiv->lock, flags);
452422 return 0;
453423 }
454424
455425 static void lgm_clk_ddiv_disable(struct clk_hw *hw)
456426 {
457427 struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
458
- unsigned long flags;
459428
460
- spin_lock_irqsave(&ddiv->lock, flags);
461429 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate,
462430 ddiv->width_gate, 0);
463
- spin_unlock_irqrestore(&ddiv->lock, flags);
464431 }
465432
466433 static int
....@@ -497,32 +464,25 @@
497464 {
498465 struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
499466 u32 div, ddiv1, ddiv2;
500
- unsigned long flags;
501467
502468 div = DIV_ROUND_CLOSEST_ULL((u64)prate, rate);
503469
504
- spin_lock_irqsave(&ddiv->lock, flags);
505470 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
506471 div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
507472 div = div * 2;
508473 }
509474
510
- if (div <= 0) {
511
- spin_unlock_irqrestore(&ddiv->lock, flags);
475
+ if (div <= 0)
512476 return -EINVAL;
513
- }
514477
515
- if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2)) {
516
- spin_unlock_irqrestore(&ddiv->lock, flags);
478
+ if (lgm_clk_get_ddiv_val(div, &ddiv1, &ddiv2))
517479 return -EINVAL;
518
- }
519480
520481 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0,
521482 ddiv1 - 1);
522483
523484 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1,
524485 ddiv2 - 1);
525
- spin_unlock_irqrestore(&ddiv->lock, flags);
526486
527487 return 0;
528488 }
....@@ -533,18 +493,15 @@
533493 {
534494 struct lgm_clk_ddiv *ddiv = to_lgm_clk_ddiv(hw);
535495 u32 div, ddiv1, ddiv2;
536
- unsigned long flags;
537496 u64 rate64;
538497
539498 div = DIV_ROUND_CLOSEST_ULL((u64)*prate, rate);
540499
541500 /* if predivide bit is enabled, modify div by factor of 2.5 */
542
- spin_lock_irqsave(&ddiv->lock, flags);
543501 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
544502 div = div * 2;
545503 div = DIV_ROUND_CLOSEST_ULL((u64)div, 5);
546504 }
547
- spin_unlock_irqrestore(&ddiv->lock, flags);
548505
549506 if (div <= 0)
550507 return *prate;
....@@ -558,12 +515,10 @@
558515 do_div(rate64, ddiv2);
559516
560517 /* if predivide bit is enabled, modify rounded rate by factor of 2.5 */
561
- spin_lock_irqsave(&ddiv->lock, flags);
562518 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) {
563519 rate64 = rate64 * 2;
564520 rate64 = DIV_ROUND_CLOSEST_ULL(rate64, 5);
565521 }
566
- spin_unlock_irqrestore(&ddiv->lock, flags);
567522
568523 return rate64;
569524 }
....@@ -600,7 +555,6 @@
600555 init.num_parents = 1;
601556
602557 ddiv->membase = ctx->membase;
603
- ddiv->lock = ctx->lock;
604558 ddiv->reg = list->reg;
605559 ddiv->shift0 = list->shift0;
606560 ddiv->width0 = list->width0;