Lines Matching +full:power +full:- +full:gate

1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020-2022 MaxLinear, Inc.
8 #include <linux/clk-provider.h>
12 #include "clk-cgu.h"
29 if (list->div_flags & CLOCK_FLAG_VAL_INIT) in lgm_clk_register_fixed()
30 lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift, in lgm_clk_register_fixed()
31 list->div_width, list->div_val); in lgm_clk_register_fixed()
33 return clk_hw_register_fixed_rate(NULL, list->name, in lgm_clk_register_fixed()
34 list->parent_data[0].name, in lgm_clk_register_fixed()
35 list->flags, list->mux_flags); in lgm_clk_register_fixed()
43 if (mux->flags & MUX_CLK_SW) in lgm_clk_mux_get_parent()
44 val = mux->reg; in lgm_clk_mux_get_parent()
46 val = lgm_get_clk_val(mux->membase, mux->reg, mux->shift, in lgm_clk_mux_get_parent()
47 mux->width); in lgm_clk_mux_get_parent()
48 return clk_mux_val_to_index(hw, NULL, mux->flags, val); in lgm_clk_mux_get_parent()
56 val = clk_mux_index_to_val(NULL, mux->flags, index); in lgm_clk_mux_set_parent()
57 if (mux->flags & MUX_CLK_SW) in lgm_clk_mux_set_parent()
58 mux->reg = val; in lgm_clk_mux_set_parent()
60 lgm_set_clk_val(mux->membase, mux->reg, mux->shift, in lgm_clk_mux_set_parent()
61 mux->width, val); in lgm_clk_mux_set_parent()
71 return clk_mux_determine_rate_flags(hw, req, mux->flags); in lgm_clk_mux_determine_rate()
84 unsigned long cflags = list->mux_flags; in lgm_clk_register_mux()
85 struct device *dev = ctx->dev; in lgm_clk_register_mux()
86 u8 shift = list->mux_shift; in lgm_clk_register_mux()
87 u8 width = list->mux_width; in lgm_clk_register_mux()
90 u32 reg = list->mux_off; in lgm_clk_register_mux()
96 return ERR_PTR(-ENOMEM); in lgm_clk_register_mux()
98 init.name = list->name; in lgm_clk_register_mux()
100 init.flags = list->flags; in lgm_clk_register_mux()
101 init.parent_data = list->parent_data; in lgm_clk_register_mux()
102 init.num_parents = list->num_parents; in lgm_clk_register_mux()
104 mux->membase = ctx->membase; in lgm_clk_register_mux()
105 mux->reg = reg; in lgm_clk_register_mux()
106 mux->shift = shift; in lgm_clk_register_mux()
107 mux->width = width; in lgm_clk_register_mux()
108 mux->flags = cflags; in lgm_clk_register_mux()
109 mux->hw.init = &init; in lgm_clk_register_mux()
111 hw = &mux->hw; in lgm_clk_register_mux()
117 lgm_set_clk_val(mux->membase, reg, shift, width, list->mux_val); in lgm_clk_register_mux()
128 val = lgm_get_clk_val(divider->membase, divider->reg, in lgm_clk_divider_recalc_rate()
129 divider->shift, divider->width); in lgm_clk_divider_recalc_rate()
131 return divider_recalc_rate(hw, parent_rate, val, divider->table, in lgm_clk_divider_recalc_rate()
132 divider->flags, divider->width); in lgm_clk_divider_recalc_rate()
141 return divider_round_rate(hw, rate, prate, divider->table, in lgm_clk_divider_round_rate()
142 divider->width, divider->flags); in lgm_clk_divider_round_rate()
152 value = divider_get_val(rate, prate, divider->table, in lgm_clk_divider_set_rate()
153 divider->width, divider->flags); in lgm_clk_divider_set_rate()
157 lgm_set_clk_val(divider->membase, divider->reg, in lgm_clk_divider_set_rate()
158 divider->shift, divider->width, value); in lgm_clk_divider_set_rate()
167 if (div->flags != DIV_CLK_NO_MASK) in lgm_clk_divider_enable_disable()
168 lgm_set_clk_val(div->membase, div->reg, div->shift_gate, in lgm_clk_divider_enable_disable()
169 div->width_gate, enable); in lgm_clk_divider_enable_disable()
195 unsigned long cflags = list->div_flags; in lgm_clk_register_divider()
196 struct device *dev = ctx->dev; in lgm_clk_register_divider()
199 u8 shift = list->div_shift; in lgm_clk_register_divider()
200 u8 width = list->div_width; in lgm_clk_register_divider()
201 u8 shift_gate = list->div_shift_gate; in lgm_clk_register_divider()
202 u8 width_gate = list->div_width_gate; in lgm_clk_register_divider()
203 u32 reg = list->div_off; in lgm_clk_register_divider()
209 return ERR_PTR(-ENOMEM); in lgm_clk_register_divider()
211 init.name = list->name; in lgm_clk_register_divider()
213 init.flags = list->flags; in lgm_clk_register_divider()
214 init.parent_data = list->parent_data; in lgm_clk_register_divider()
217 div->membase = ctx->membase; in lgm_clk_register_divider()
218 div->reg = reg; in lgm_clk_register_divider()
219 div->shift = shift; in lgm_clk_register_divider()
220 div->width = width; in lgm_clk_register_divider()
221 div->shift_gate = shift_gate; in lgm_clk_register_divider()
222 div->width_gate = width_gate; in lgm_clk_register_divider()
223 div->flags = cflags; in lgm_clk_register_divider()
224 div->table = list->div_table; in lgm_clk_register_divider()
225 div->hw.init = &init; in lgm_clk_register_divider()
227 hw = &div->hw; in lgm_clk_register_divider()
233 lgm_set_clk_val(div->membase, reg, shift, width, list->div_val); in lgm_clk_register_divider()
244 hw = clk_hw_register_fixed_factor(ctx->dev, list->name, in lgm_clk_register_fixed_factor()
245 list->parent_data[0].name, list->flags, in lgm_clk_register_fixed_factor()
246 list->mult, list->div); in lgm_clk_register_fixed_factor()
250 if (list->div_flags & CLOCK_FLAG_VAL_INIT) in lgm_clk_register_fixed_factor()
251 lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift, in lgm_clk_register_fixed_factor()
252 list->div_width, list->div_val); in lgm_clk_register_fixed_factor()
259 struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); in lgm_clk_gate_enable() local
262 reg = GATE_HW_REG_EN(gate->reg); in lgm_clk_gate_enable()
263 lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); in lgm_clk_gate_enable()
270 struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); in lgm_clk_gate_disable() local
273 reg = GATE_HW_REG_DIS(gate->reg); in lgm_clk_gate_disable()
274 lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); in lgm_clk_gate_disable()
279 struct lgm_clk_gate *gate = to_lgm_clk_gate(hw); in lgm_clk_gate_is_enabled() local
282 reg = GATE_HW_REG_STAT(gate->reg); in lgm_clk_gate_is_enabled()
283 ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1); in lgm_clk_gate_is_enabled()
298 unsigned long cflags = list->gate_flags; in lgm_clk_register_gate()
299 const char *pname = list->parent_data[0].name; in lgm_clk_register_gate()
300 struct device *dev = ctx->dev; in lgm_clk_register_gate()
301 u8 shift = list->gate_shift; in lgm_clk_register_gate()
303 struct lgm_clk_gate *gate; in lgm_clk_register_gate() local
304 u32 reg = list->gate_off; in lgm_clk_register_gate()
308 gate = devm_kzalloc(dev, sizeof(*gate), GFP_KERNEL); in lgm_clk_register_gate()
309 if (!gate) in lgm_clk_register_gate()
310 return ERR_PTR(-ENOMEM); in lgm_clk_register_gate()
312 init.name = list->name; in lgm_clk_register_gate()
314 init.flags = list->flags; in lgm_clk_register_gate()
318 gate->membase = ctx->membase; in lgm_clk_register_gate()
319 gate->reg = reg; in lgm_clk_register_gate()
320 gate->shift = shift; in lgm_clk_register_gate()
321 gate->flags = cflags; in lgm_clk_register_gate()
322 gate->hw.init = &init; in lgm_clk_register_gate()
324 hw = &gate->hw; in lgm_clk_register_gate()
330 lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val); in lgm_clk_register_gate()
344 switch (list->type) { in lgm_clk_register_branches()
358 if (list->gate_flags & GATE_CLK_HW) { in lgm_clk_register_branches()
364 * from power management driver/daemon. It is in lgm_clk_register_branches()
365 * dependent on the power policy/profile requirements in lgm_clk_register_branches()
366 * of the end product. To override control of gate in lgm_clk_register_branches()
368 * of gate clk provider. in lgm_clk_register_branches()
375 dev_err(ctx->dev, "invalid clk type\n"); in lgm_clk_register_branches()
376 return -EINVAL; in lgm_clk_register_branches()
380 dev_err(ctx->dev, in lgm_clk_register_branches()
382 list->name, list->type); in lgm_clk_register_branches()
383 return -EIO; in lgm_clk_register_branches()
385 ctx->clk_data.hws[list->id] = hw; in lgm_clk_register_branches()
398 div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg, in lgm_clk_ddiv_recalc_rate()
399 ddiv->shift0, ddiv->width0) + 1; in lgm_clk_ddiv_recalc_rate()
400 div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg, in lgm_clk_ddiv_recalc_rate()
401 ddiv->shift1, ddiv->width1) + 1; in lgm_clk_ddiv_recalc_rate()
402 exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg, in lgm_clk_ddiv_recalc_rate()
403 ddiv->shift2, ddiv->width2); in lgm_clk_ddiv_recalc_rate()
409 do_div(prate, ddiv->div); in lgm_clk_ddiv_recalc_rate()
410 prate *= ddiv->mult; in lgm_clk_ddiv_recalc_rate()
420 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate, in lgm_clk_ddiv_enable()
421 ddiv->width_gate, 1); in lgm_clk_ddiv_enable()
429 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate, in lgm_clk_ddiv_disable()
430 ddiv->width_gate, 0); in lgm_clk_ddiv_disable()
452 return -EINVAL; in lgm_clk_get_ddiv_val()
470 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { in lgm_clk_ddiv_set_rate()
476 return -EINVAL; in lgm_clk_ddiv_set_rate()
479 return -EINVAL; in lgm_clk_ddiv_set_rate()
481 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0, in lgm_clk_ddiv_set_rate()
482 ddiv1 - 1); in lgm_clk_ddiv_set_rate()
484 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1, in lgm_clk_ddiv_set_rate()
485 ddiv2 - 1); in lgm_clk_ddiv_set_rate()
501 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { in lgm_clk_ddiv_round_rate()
511 return -EINVAL; in lgm_clk_ddiv_round_rate()
518 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { in lgm_clk_ddiv_round_rate()
538 struct device *dev = ctx->dev; in lgm_clk_register_ddiv()
549 return -ENOMEM; in lgm_clk_register_ddiv()
551 init.name = list->name; in lgm_clk_register_ddiv()
553 init.flags = list->flags; in lgm_clk_register_ddiv()
554 init.parent_data = list->parent_data; in lgm_clk_register_ddiv()
557 ddiv->membase = ctx->membase; in lgm_clk_register_ddiv()
558 ddiv->reg = list->reg; in lgm_clk_register_ddiv()
559 ddiv->shift0 = list->shift0; in lgm_clk_register_ddiv()
560 ddiv->width0 = list->width0; in lgm_clk_register_ddiv()
561 ddiv->shift1 = list->shift1; in lgm_clk_register_ddiv()
562 ddiv->width1 = list->width1; in lgm_clk_register_ddiv()
563 ddiv->shift_gate = list->shift_gate; in lgm_clk_register_ddiv()
564 ddiv->width_gate = list->width_gate; in lgm_clk_register_ddiv()
565 ddiv->shift2 = list->ex_shift; in lgm_clk_register_ddiv()
566 ddiv->width2 = list->ex_width; in lgm_clk_register_ddiv()
567 ddiv->flags = list->div_flags; in lgm_clk_register_ddiv()
568 ddiv->mult = 2; in lgm_clk_register_ddiv()
569 ddiv->div = 5; in lgm_clk_register_ddiv()
570 ddiv->hw.init = &init; in lgm_clk_register_ddiv()
572 hw = &ddiv->hw; in lgm_clk_register_ddiv()
575 dev_err(dev, "register clk: %s failed!\n", list->name); in lgm_clk_register_ddiv()
578 ctx->clk_data.hws[list->id] = hw; in lgm_clk_register_ddiv()