Lines Matching +full:reg +full:- +full:init

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"
14 #define GATE_HW_REG_STAT(reg) ((reg) + 0x0) argument
15 #define GATE_HW_REG_EN(reg) ((reg) + 0x4) argument
16 #define GATE_HW_REG_DIS(reg) ((reg) + 0x8) argument
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()
88 struct clk_init_data init = {}; in lgm_clk_register_mux() local
90 u32 reg = list->mux_off; in lgm_clk_register_mux() local
96 return ERR_PTR(-ENOMEM); in lgm_clk_register_mux()
98 init.name = list->name; in lgm_clk_register_mux()
99 init.ops = &lgm_clk_mux_ops; 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()
140 req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, divider->table, in lgm_clk_divider_determine_rate()
141 divider->width, divider->flags); in lgm_clk_divider_determine_rate()
153 value = divider_get_val(rate, prate, divider->table, in lgm_clk_divider_set_rate()
154 divider->width, divider->flags); in lgm_clk_divider_set_rate()
158 lgm_set_clk_val(divider->membase, divider->reg, in lgm_clk_divider_set_rate()
159 divider->shift, divider->width, value); in lgm_clk_divider_set_rate()
168 if (div->flags != DIV_CLK_NO_MASK) in lgm_clk_divider_enable_disable()
169 lgm_set_clk_val(div->membase, div->reg, div->shift_gate, in lgm_clk_divider_enable_disable()
170 div->width_gate, enable); in lgm_clk_divider_enable_disable()
196 unsigned long cflags = list->div_flags; in lgm_clk_register_divider()
197 struct device *dev = ctx->dev; in lgm_clk_register_divider()
199 struct clk_init_data init = {}; in lgm_clk_register_divider() local
200 u8 shift = list->div_shift; in lgm_clk_register_divider()
201 u8 width = list->div_width; in lgm_clk_register_divider()
202 u8 shift_gate = list->div_shift_gate; in lgm_clk_register_divider()
203 u8 width_gate = list->div_width_gate; in lgm_clk_register_divider()
204 u32 reg = list->div_off; in lgm_clk_register_divider() local
210 return ERR_PTR(-ENOMEM); in lgm_clk_register_divider()
212 init.name = list->name; in lgm_clk_register_divider()
213 init.ops = &lgm_clk_divider_ops; in lgm_clk_register_divider()
214 init.flags = list->flags; in lgm_clk_register_divider()
215 init.parent_data = list->parent_data; in lgm_clk_register_divider()
216 init.num_parents = 1; in lgm_clk_register_divider()
218 div->membase = ctx->membase; in lgm_clk_register_divider()
219 div->reg = reg; in lgm_clk_register_divider()
220 div->shift = shift; in lgm_clk_register_divider()
221 div->width = width; in lgm_clk_register_divider()
222 div->shift_gate = shift_gate; in lgm_clk_register_divider()
223 div->width_gate = width_gate; in lgm_clk_register_divider()
224 div->flags = cflags; in lgm_clk_register_divider()
225 div->table = list->div_table; in lgm_clk_register_divider()
226 div->hw.init = &init; in lgm_clk_register_divider()
228 hw = &div->hw; in lgm_clk_register_divider()
234 lgm_set_clk_val(div->membase, reg, shift, width, list->div_val); in lgm_clk_register_divider()
245 hw = clk_hw_register_fixed_factor(ctx->dev, list->name, in lgm_clk_register_fixed_factor()
246 list->parent_data[0].name, list->flags, in lgm_clk_register_fixed_factor()
247 list->mult, list->div); in lgm_clk_register_fixed_factor()
251 if (list->div_flags & CLOCK_FLAG_VAL_INIT) in lgm_clk_register_fixed_factor()
252 lgm_set_clk_val(ctx->membase, list->div_off, list->div_shift, in lgm_clk_register_fixed_factor()
253 list->div_width, list->div_val); in lgm_clk_register_fixed_factor()
261 unsigned int reg; in lgm_clk_gate_enable() local
263 reg = GATE_HW_REG_EN(gate->reg); in lgm_clk_gate_enable()
264 lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); in lgm_clk_gate_enable()
272 unsigned int reg; in lgm_clk_gate_disable() local
274 reg = GATE_HW_REG_DIS(gate->reg); in lgm_clk_gate_disable()
275 lgm_set_clk_val(gate->membase, reg, gate->shift, 1, 1); in lgm_clk_gate_disable()
281 unsigned int reg, ret; in lgm_clk_gate_is_enabled() local
283 reg = GATE_HW_REG_STAT(gate->reg); in lgm_clk_gate_is_enabled()
284 ret = lgm_get_clk_val(gate->membase, reg, gate->shift, 1); in lgm_clk_gate_is_enabled()
299 unsigned long cflags = list->gate_flags; in lgm_clk_register_gate()
300 const char *pname = list->parent_data[0].name; in lgm_clk_register_gate()
301 struct device *dev = ctx->dev; in lgm_clk_register_gate()
302 u8 shift = list->gate_shift; in lgm_clk_register_gate()
303 struct clk_init_data init = {}; in lgm_clk_register_gate() local
305 u32 reg = list->gate_off; in lgm_clk_register_gate() local
311 return ERR_PTR(-ENOMEM); in lgm_clk_register_gate()
313 init.name = list->name; in lgm_clk_register_gate()
314 init.ops = &lgm_clk_gate_ops; in lgm_clk_register_gate()
315 init.flags = list->flags; in lgm_clk_register_gate()
316 init.parent_names = pname ? &pname : NULL; in lgm_clk_register_gate()
317 init.num_parents = pname ? 1 : 0; in lgm_clk_register_gate()
319 gate->membase = ctx->membase; in lgm_clk_register_gate()
320 gate->reg = reg; in lgm_clk_register_gate()
321 gate->shift = shift; in lgm_clk_register_gate()
322 gate->flags = cflags; in lgm_clk_register_gate()
323 gate->hw.init = &init; in lgm_clk_register_gate()
325 hw = &gate->hw; in lgm_clk_register_gate()
331 lgm_set_clk_val(gate->membase, reg, shift, 1, list->gate_val); in lgm_clk_register_gate()
345 switch (list->type) { in lgm_clk_register_branches()
359 if (list->gate_flags & GATE_CLK_HW) { in lgm_clk_register_branches()
376 dev_err(ctx->dev, "invalid clk type\n"); in lgm_clk_register_branches()
377 return -EINVAL; in lgm_clk_register_branches()
381 dev_err(ctx->dev, in lgm_clk_register_branches()
383 list->name, list->type); in lgm_clk_register_branches()
384 return -EIO; in lgm_clk_register_branches()
386 ctx->clk_data.hws[list->id] = hw; in lgm_clk_register_branches()
399 div0 = lgm_get_clk_val(ddiv->membase, ddiv->reg, in lgm_clk_ddiv_recalc_rate()
400 ddiv->shift0, ddiv->width0) + 1; in lgm_clk_ddiv_recalc_rate()
401 div1 = lgm_get_clk_val(ddiv->membase, ddiv->reg, in lgm_clk_ddiv_recalc_rate()
402 ddiv->shift1, ddiv->width1) + 1; in lgm_clk_ddiv_recalc_rate()
403 exdiv = lgm_get_clk_val(ddiv->membase, ddiv->reg, in lgm_clk_ddiv_recalc_rate()
404 ddiv->shift2, ddiv->width2); in lgm_clk_ddiv_recalc_rate()
410 do_div(prate, ddiv->div); in lgm_clk_ddiv_recalc_rate()
411 prate *= ddiv->mult; in lgm_clk_ddiv_recalc_rate()
421 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate, in lgm_clk_ddiv_enable()
422 ddiv->width_gate, 1); in lgm_clk_ddiv_enable()
430 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift_gate, in lgm_clk_ddiv_disable()
431 ddiv->width_gate, 0); in lgm_clk_ddiv_disable()
453 return -EINVAL; in lgm_clk_get_ddiv_val()
471 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { in lgm_clk_ddiv_set_rate()
477 return -EINVAL; in lgm_clk_ddiv_set_rate()
480 return -EINVAL; in lgm_clk_ddiv_set_rate()
482 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift0, ddiv->width0, in lgm_clk_ddiv_set_rate()
483 ddiv1 - 1); in lgm_clk_ddiv_set_rate()
485 lgm_set_clk_val(ddiv->membase, ddiv->reg, ddiv->shift1, ddiv->width1, in lgm_clk_ddiv_set_rate()
486 ddiv2 - 1); in lgm_clk_ddiv_set_rate()
498 div = DIV_ROUND_CLOSEST_ULL((u64)req->best_parent_rate, req->rate); in lgm_clk_ddiv_determine_rate()
501 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { in lgm_clk_ddiv_determine_rate()
507 req->rate = req->best_parent_rate; in lgm_clk_ddiv_determine_rate()
514 return -EINVAL; in lgm_clk_ddiv_determine_rate()
516 rate64 = req->best_parent_rate; in lgm_clk_ddiv_determine_rate()
521 if (lgm_get_clk_val(ddiv->membase, ddiv->reg, ddiv->shift2, 1)) { in lgm_clk_ddiv_determine_rate()
526 req->rate = rate64; in lgm_clk_ddiv_determine_rate()
543 struct device *dev = ctx->dev; in lgm_clk_register_ddiv()
549 struct clk_init_data init = {}; in lgm_clk_register_ddiv() local
554 return -ENOMEM; in lgm_clk_register_ddiv()
556 init.name = list->name; in lgm_clk_register_ddiv()
557 init.ops = &lgm_clk_ddiv_ops; in lgm_clk_register_ddiv()
558 init.flags = list->flags; in lgm_clk_register_ddiv()
559 init.parent_data = list->parent_data; in lgm_clk_register_ddiv()
560 init.num_parents = 1; in lgm_clk_register_ddiv()
562 ddiv->membase = ctx->membase; in lgm_clk_register_ddiv()
563 ddiv->reg = list->reg; in lgm_clk_register_ddiv()
564 ddiv->shift0 = list->shift0; in lgm_clk_register_ddiv()
565 ddiv->width0 = list->width0; in lgm_clk_register_ddiv()
566 ddiv->shift1 = list->shift1; in lgm_clk_register_ddiv()
567 ddiv->width1 = list->width1; in lgm_clk_register_ddiv()
568 ddiv->shift_gate = list->shift_gate; in lgm_clk_register_ddiv()
569 ddiv->width_gate = list->width_gate; in lgm_clk_register_ddiv()
570 ddiv->shift2 = list->ex_shift; in lgm_clk_register_ddiv()
571 ddiv->width2 = list->ex_width; in lgm_clk_register_ddiv()
572 ddiv->flags = list->div_flags; in lgm_clk_register_ddiv()
573 ddiv->mult = 2; in lgm_clk_register_ddiv()
574 ddiv->div = 5; in lgm_clk_register_ddiv()
575 ddiv->hw.init = &init; in lgm_clk_register_ddiv()
577 hw = &ddiv->hw; in lgm_clk_register_ddiv()
580 dev_err(dev, "register clk: %s failed!\n", list->name); in lgm_clk_register_ddiv()
583 ctx->clk_data.hws[list->id] = hw; in lgm_clk_register_ddiv()