Lines Matching +full:tbg +full:- +full:a +full:- +full:p
1 // SPDX-License-Identifier: GPL-2.0+
8 * Gregory CLEMENT <gregory.clement@free-electrons.com>
13 #include <clk-uclass.h>
40 { "TBG-A-P", TBG_A_P },
41 { "TBG-B-P", TBG_B_P },
42 { "TBG-A-S", TBG_A_S },
43 { "TBG-B-S", TBG_B_S },
200 CLK_GATE_DIV(ddr_phy, 19, DIV_SEL0, 18, 1, div_table2, "TBG-A-S"),
229 return (readl(priv->reg + TBG_SEL) >> shift) & 3; in get_mux()
236 reg = readl(priv->reg + TBG_SEL); in set_mux()
239 writel(reg, priv->reg + TBG_SEL); in set_mux()
246 const struct clk_periph *clk = &priv->clks[id]; in get_parent_rate()
249 if (clk->can_mux) { in get_parent_rate()
250 /* parent is one of TBG clocks */ in get_parent_rate()
251 int tbg = get_mux(priv, clk->mux_shift); in get_parent_rate() local
253 res = priv->parents[tbg]; in get_parent_rate()
254 } else if (priv->clk_has_periph_parent[id]) { in get_parent_rate()
257 if (priv->clk_parent[id] >= priv->count) in get_parent_rate()
258 return -EINVAL; in get_parent_rate()
260 res = periph_clk_get_rate(priv, priv->clk_parent[id]); in get_parent_rate()
264 if (priv->clk_parent[id] >= MAX_PARENTS) in get_parent_rate()
265 return -EINVAL; in get_parent_rate()
267 res = priv->parents[priv->clk_parent[id]]; in get_parent_rate()
279 reg = readl(priv->reg + clk->div_reg_off[idx]); in get_div()
280 reg = (reg >> clk->div_shift[idx]) & clk->div_mask[idx]; in get_div()
283 for (i = clk->div_table[idx]; i && i->div != 0; ++i) in get_div()
284 if (i->val == reg) in get_div()
285 return i->div; in get_div()
295 reg = readl(priv->reg + clk->div_reg_off[idx]); in set_div_val()
296 reg &= ~(clk->div_mask[idx] << clk->div_shift[idx]); in set_div_val()
297 reg |= (val & clk->div_mask[idx]) << clk->div_shift[idx]; in set_div_val()
298 writel(reg, priv->reg + clk->div_reg_off[idx]); in set_div_val()
303 const struct clk_periph *clk = &priv->clks[id]; in periph_clk_get_rate()
308 if (rate == -EINVAL) in periph_clk_get_rate()
309 return -EINVAL; in periph_clk_get_rate()
313 for (i = 0; i < clk->dividers; ++i) in periph_clk_get_rate()
324 struct a37xx_periphclk *priv = dev_get_priv(clk->dev); in armada_37xx_periph_clk_get_rate()
326 if (clk->id >= priv->count) in armada_37xx_periph_clk_get_rate()
327 return -EINVAL; in armada_37xx_periph_clk_get_rate()
329 return periph_clk_get_rate(priv, clk->id); in armada_37xx_periph_clk_get_rate()
334 struct a37xx_periphclk *priv = dev_get_priv(clk->dev); in periph_clk_enable()
335 const struct clk_periph *periph_clk = &priv->clks[clk->id]; in periph_clk_enable()
337 if (clk->id >= priv->count) in periph_clk_enable()
338 return -EINVAL; in periph_clk_enable()
340 if (!periph_clk->can_gate) in periph_clk_enable()
341 return -ENOTSUPP; in periph_clk_enable()
344 clrbits_le32(priv->reg + CLK_DIS, periph_clk->disable_bit); in periph_clk_enable()
346 setbits_le32(priv->reg + CLK_DIS, periph_clk->disable_bit); in periph_clk_enable()
361 #define diff(a, b) abs((long)(a) - (long)(b)) argument
370 for (i = t0; i && i->div; ++i) { in find_best_div()
371 for (j = t1; j && j->div; ++j) { in find_best_div()
372 rate = DIV_ROUND_UP(parent_rate, i->div * j->div); in find_best_div()
377 *v0 = i->val; in find_best_div()
378 *v1 = j->val; in find_best_div()
388 struct a37xx_periphclk *priv = dev_get_priv(clk->dev); in armada_37xx_periph_clk_set_rate()
389 const struct clk_periph *periph_clk = &priv->clks[clk->id]; in armada_37xx_periph_clk_set_rate()
398 if (clk->id > priv->count) in armada_37xx_periph_clk_set_rate()
399 return -EINVAL; in armada_37xx_periph_clk_set_rate()
401 old_rate = periph_clk_get_rate(priv, clk->id); in armada_37xx_periph_clk_set_rate()
402 if (old_rate == -EINVAL) in armada_37xx_periph_clk_set_rate()
403 return -EINVAL; in armada_37xx_periph_clk_set_rate()
408 if (!periph_clk->can_gate || !periph_clk->dividers) in armada_37xx_periph_clk_set_rate()
409 return -ENOTSUPP; in armada_37xx_periph_clk_set_rate()
411 parent_rate = get_parent_rate(priv, clk->id); in armada_37xx_periph_clk_set_rate()
412 if (parent_rate == -EINVAL) in armada_37xx_periph_clk_set_rate()
413 return -EINVAL; in armada_37xx_periph_clk_set_rate()
416 if (periph_clk->dividers > 1) in armada_37xx_periph_clk_set_rate()
417 t1 = periph_clk->div_table[1]; in armada_37xx_periph_clk_set_rate()
419 rate = find_best_div(periph_clk->div_table[0], t1, parent_rate, in armada_37xx_periph_clk_set_rate()
425 if (periph_clk->dividers > 1) in armada_37xx_periph_clk_set_rate()
436 struct a37xx_periphclk *priv = dev_get_priv(clk->dev); in armada_37xx_periph_clk_set_parent()
437 const struct clk_periph *periph_clk = &priv->clks[clk->id]; in armada_37xx_periph_clk_set_parent()
441 /* We also check if parent is our TBG clock */ in armada_37xx_periph_clk_set_parent()
442 if (clk->id > priv->count || parent->id >= MAX_TBG_PARENTS) in armada_37xx_periph_clk_set_parent()
443 return -EINVAL; in armada_37xx_periph_clk_set_parent()
445 if (!periph_clk->can_mux || !periph_clk->can_gate) in armada_37xx_periph_clk_set_parent()
446 return -ENOTSUPP; in armada_37xx_periph_clk_set_parent()
448 ret = clk_get_by_index(clk->dev, 0, &check_parent); in armada_37xx_periph_clk_set_parent()
452 if (parent->dev != check_parent.dev) in armada_37xx_periph_clk_set_parent()
453 ret = -EINVAL; in armada_37xx_periph_clk_set_parent()
460 set_mux(priv, periph_clk->mux_shift, parent->id); in armada_37xx_periph_clk_set_parent()
474 return -ENODEV; in armada_37xx_periph_clk_dump()
476 clks = priv->clks; in armada_37xx_periph_clk_dump()
478 for (i = 0; i < priv->count; ++i) in armada_37xx_periph_clk_dump()
492 return -ENODEV; in clk_dump()
504 if (clk_dump("tbg@13200", armada_37xx_tbg_clk_dump)) in soc_clk_dump()
507 if (clk_dump("nb-periph-clk@13000", in soc_clk_dump()
511 if (clk_dump("sb-periph-clk@18000", in soc_clk_dump()
527 return -ENODEV; in armada_37xx_periph_clk_probe()
529 priv->reg = dev_read_addr_ptr(dev); in armada_37xx_periph_clk_probe()
530 if (!priv->reg) { in armada_37xx_periph_clk_probe()
532 return -ENODEV; in armada_37xx_periph_clk_probe()
536 priv->count = 0; in armada_37xx_periph_clk_probe()
537 while (clks[priv->count].name) in armada_37xx_periph_clk_probe()
538 priv->count++; in armada_37xx_periph_clk_probe()
540 priv->clks = clks; in armada_37xx_periph_clk_probe()
542 /* assign parent IDs to nodes which have non-NULL parent_name */ in armada_37xx_periph_clk_probe()
543 for (i = 0; i < priv->count; ++i) { in armada_37xx_periph_clk_probe()
556 priv->clk_has_periph_parent[i] = false; in armada_37xx_periph_clk_probe()
557 priv->clk_parent[i] = in armada_37xx_periph_clk_probe()
563 for (j = 0; j < priv->count; ++j) { in armada_37xx_periph_clk_probe()
568 if (j < priv->count) { in armada_37xx_periph_clk_probe()
569 priv->clk_has_periph_parent[i] = true; in armada_37xx_periph_clk_probe()
570 priv->clk_parent[i] = j; in armada_37xx_periph_clk_probe()
575 return -EINVAL; in armada_37xx_periph_clk_probe()
582 priv->parents[i] = get_ref_clk() * 1000000; in armada_37xx_periph_clk_probe()
590 return -ENODEV; in armada_37xx_periph_clk_probe()
593 priv->parents[i] = clk_get_rate(&clk); in armada_37xx_periph_clk_probe()
610 .compatible = "marvell,armada-3700-periph-clock-nb",
614 .compatible = "marvell,armada-3700-periph-clock-sb",