Lines Matching +full:pll1 +full:- +full:div2
1 // SPDX-License-Identifier: GPL-2.0+
8 #include <linux/clk-provider.h>
85 #define VC3_DIV_MASK(width) ((1 << (width)) - 1)
128 VC3_SE1_MUX = VC3_SE1 - 1,
129 VC3_SE2_MUX = VC3_SE2 - 1,
130 VC3_SE3_MUX = VC3_SE3 - 1,
131 VC3_DIFF1_MUX = VC3_DIFF1 - 1,
132 VC3_DIFF2_MUX = VC3_DIFF2 - 1,
222 const struct vc3_clk_data *pfd_mux = vc3->data; in vc3_pfd_mux_get_parent()
225 regmap_read(vc3->regmap, pfd_mux->offs, &src); in vc3_pfd_mux_get_parent()
227 return !!(src & pfd_mux->bitmsk); in vc3_pfd_mux_get_parent()
233 const struct vc3_clk_data *pfd_mux = vc3->data; in vc3_pfd_mux_set_parent()
235 return regmap_update_bits(vc3->regmap, pfd_mux->offs, pfd_mux->bitmsk, in vc3_pfd_mux_set_parent()
236 index ? pfd_mux->bitmsk : 0); in vc3_pfd_mux_set_parent()
249 const struct vc3_pfd_data *pfd = vc3->data; in vc3_pfd_recalc_rate()
254 regmap_read(vc3->regmap, pfd->offs, &prediv); in vc3_pfd_recalc_rate()
255 if (pfd->num == VC3_PFD1) { in vc3_pfd_recalc_rate()
257 if (prediv & pfd->mdiv1_bitmsk) { in vc3_pfd_recalc_rate()
259 regmap_read(vc3->regmap, VC3_PLL1_CTRL_OUTDIV5, &premul); in vc3_pfd_recalc_rate()
265 } else if (pfd->num == VC3_PFD2) { in vc3_pfd_recalc_rate()
267 if (prediv & pfd->mdiv1_bitmsk) { in vc3_pfd_recalc_rate()
268 regmap_read(vc3->regmap, VC3_PLL2_M_DIVIDER, &premul); in vc3_pfd_recalc_rate()
278 if (prediv & pfd->mdiv1_bitmsk) in vc3_pfd_recalc_rate()
284 if (prediv & pfd->mdiv2_bitmsk) in vc3_pfd_recalc_rate()
296 const struct vc3_pfd_data *pfd = vc3->data; in vc3_pfd_determine_rate()
300 if (req->rate > 50000000) in vc3_pfd_determine_rate()
301 return -EINVAL; in vc3_pfd_determine_rate()
304 if (req->best_parent_rate <= 50000000) { in vc3_pfd_determine_rate()
305 req->rate = req->best_parent_rate; in vc3_pfd_determine_rate()
310 idiv = DIV_ROUND_UP(req->best_parent_rate, req->rate); in vc3_pfd_determine_rate()
311 if (pfd->num == VC3_PFD1 || pfd->num == VC3_PFD3) { in vc3_pfd_determine_rate()
313 return -EINVAL; in vc3_pfd_determine_rate()
316 return -EINVAL; in vc3_pfd_determine_rate()
319 req->rate = req->best_parent_rate / idiv; in vc3_pfd_determine_rate()
328 const struct vc3_pfd_data *pfd = vc3->data; in vc3_pfd_set_rate()
334 regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv1_bitmsk, in vc3_pfd_set_rate()
335 pfd->mdiv1_bitmsk); in vc3_pfd_set_rate()
336 regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv2_bitmsk, 0); in vc3_pfd_set_rate()
341 /* We have dedicated div-2 predivider. */ in vc3_pfd_set_rate()
343 regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv2_bitmsk, in vc3_pfd_set_rate()
344 pfd->mdiv2_bitmsk); in vc3_pfd_set_rate()
345 regmap_update_bits(vc3->regmap, pfd->offs, pfd->mdiv1_bitmsk, 0); in vc3_pfd_set_rate()
347 if (pfd->num == VC3_PFD1) in vc3_pfd_set_rate()
349 else if (pfd->num == VC3_PFD2) in vc3_pfd_set_rate()
354 regmap_write(vc3->regmap, pfd->offs, div); in vc3_pfd_set_rate()
370 const struct vc3_pll_data *pll = vc3->data; in vc3_pll_recalc_rate()
374 regmap_read(vc3->regmap, pll->int_div_msb_offs, &val); in vc3_pll_recalc_rate()
376 regmap_read(vc3->regmap, pll->int_div_lsb_offs, &val); in vc3_pll_recalc_rate()
379 if (pll->num == VC3_PLL2) { in vc3_pll_recalc_rate()
380 regmap_read(vc3->regmap, VC3_PLL2_FB_FRC_DIV_MSB, &val); in vc3_pll_recalc_rate()
382 regmap_read(vc3->regmap, VC3_PLL2_FB_FRC_DIV_LSB, &val); in vc3_pll_recalc_rate()
397 const struct vc3_pll_data *pll = vc3->data; in vc3_pll_determine_rate()
400 if (req->rate < pll->vco.min) in vc3_pll_determine_rate()
401 req->rate = pll->vco.min; in vc3_pll_determine_rate()
402 if (req->rate > pll->vco.max) in vc3_pll_determine_rate()
403 req->rate = pll->vco.max; in vc3_pll_determine_rate()
405 vc3->div_int = req->rate / req->best_parent_rate; in vc3_pll_determine_rate()
407 if (pll->num == VC3_PLL2) { in vc3_pll_determine_rate()
408 if (vc3->div_int > 0x7ff) in vc3_pll_determine_rate()
409 req->rate = req->best_parent_rate * 0x7ff; in vc3_pll_determine_rate()
412 div_frc = req->rate % req->best_parent_rate; in vc3_pll_determine_rate()
413 div_frc *= BIT(16) - 1; in vc3_pll_determine_rate()
415 vc3->div_frc = min_t(u64, in vc3_pll_determine_rate()
416 div64_ul(div_frc, req->best_parent_rate), in vc3_pll_determine_rate()
418 req->rate = (req->best_parent_rate * in vc3_pll_determine_rate()
419 (vc3->div_int * VC3_2_POW_16 + vc3->div_frc) / VC3_2_POW_16); in vc3_pll_determine_rate()
421 req->rate = req->best_parent_rate * vc3->div_int; in vc3_pll_determine_rate()
431 const struct vc3_pll_data *pll = vc3->data; in vc3_pll_set_rate()
434 regmap_read(vc3->regmap, pll->int_div_msb_offs, &val); in vc3_pll_set_rate()
435 val = (val & 0xf8) | ((vc3->div_int >> 8) & 0x7); in vc3_pll_set_rate()
436 regmap_write(vc3->regmap, pll->int_div_msb_offs, val); in vc3_pll_set_rate()
437 regmap_write(vc3->regmap, pll->int_div_lsb_offs, vc3->div_int & 0xff); in vc3_pll_set_rate()
439 if (pll->num == VC3_PLL2) { in vc3_pll_set_rate()
440 regmap_write(vc3->regmap, VC3_PLL2_FB_FRC_DIV_MSB, in vc3_pll_set_rate()
441 vc3->div_frc >> 8); in vc3_pll_set_rate()
442 regmap_write(vc3->regmap, VC3_PLL2_FB_FRC_DIV_LSB, in vc3_pll_set_rate()
443 vc3->div_frc & 0xff); in vc3_pll_set_rate()
458 const struct vc3_clk_data *div_mux = vc3->data; in vc3_div_mux_get_parent()
461 regmap_read(vc3->regmap, div_mux->offs, &src); in vc3_div_mux_get_parent()
463 return !!(src & div_mux->bitmsk); in vc3_div_mux_get_parent()
469 const struct vc3_clk_data *div_mux = vc3->data; in vc3_div_mux_set_parent()
471 return regmap_update_bits(vc3->regmap, div_mux->offs, div_mux->bitmsk, in vc3_div_mux_set_parent()
472 index ? div_mux->bitmsk : 0); in vc3_div_mux_set_parent()
486 for (clkt = table; clkt->div; clkt++) in vc3_get_div()
487 if (clkt->val == val) in vc3_get_div()
488 return clkt->div; in vc3_get_div()
497 const struct vc3_div_data *div_data = vc3->data; in vc3_div_recalc_rate()
500 regmap_read(vc3->regmap, div_data->offs, &val); in vc3_div_recalc_rate()
501 val >>= div_data->shift; in vc3_div_recalc_rate()
502 val &= VC3_DIV_MASK(div_data->width); in vc3_div_recalc_rate()
504 return divider_recalc_rate(hw, parent_rate, val, div_data->table, in vc3_div_recalc_rate()
505 div_data->flags, div_data->width); in vc3_div_recalc_rate()
512 const struct vc3_div_data *div_data = vc3->data; in vc3_div_determine_rate()
516 if (div_data->flags & CLK_DIVIDER_READ_ONLY) { in vc3_div_determine_rate()
517 regmap_read(vc3->regmap, div_data->offs, &bestdiv); in vc3_div_determine_rate()
518 bestdiv >>= div_data->shift; in vc3_div_determine_rate()
519 bestdiv &= VC3_DIV_MASK(div_data->width); in vc3_div_determine_rate()
520 bestdiv = vc3_get_div(div_data->table, bestdiv, div_data->flags); in vc3_div_determine_rate()
521 req->rate = DIV_ROUND_UP(req->best_parent_rate, bestdiv); in vc3_div_determine_rate()
526 req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, in vc3_div_determine_rate()
527 div_data->table, in vc3_div_determine_rate()
528 div_data->width, div_data->flags); in vc3_div_determine_rate()
537 const struct vc3_div_data *div_data = vc3->data; in vc3_div_set_rate()
540 value = divider_get_val(rate, parent_rate, div_data->table, in vc3_div_set_rate()
541 div_data->width, div_data->flags); in vc3_div_set_rate()
542 return regmap_update_bits(vc3->regmap, div_data->offs, in vc3_div_set_rate()
543 VC3_DIV_MASK(div_data->width) << div_data->shift, in vc3_div_set_rate()
544 value << div_data->shift); in vc3_div_set_rate()
560 if (req->best_parent_rate >= req->rate) { in vc3_clk_mux_determine_rate()
561 frc = DIV_ROUND_CLOSEST_ULL(req->best_parent_rate, in vc3_clk_mux_determine_rate()
562 req->rate); in vc3_clk_mux_determine_rate()
563 req->rate *= frc; in vc3_clk_mux_determine_rate()
575 const struct vc3_clk_data *clk_mux = vc3->data; in vc3_clk_mux_get_parent()
578 regmap_read(vc3->regmap, clk_mux->offs, &val); in vc3_clk_mux_get_parent()
580 return !!(val & clk_mux->bitmsk); in vc3_clk_mux_get_parent()
586 const struct vc3_clk_data *clk_mux = vc3->data; in vc3_clk_mux_set_parent()
588 return regmap_update_bits(vc3->regmap, clk_mux->offs, clk_mux->bitmsk, in vc3_clk_mux_set_parent()
589 index ? clk_mux->bitmsk : 0); in vc3_clk_mux_set_parent()
707 .name = "pll1",
839 .name = "div2",
989 unsigned int idx = clkspec->args[0]; in vc3_of_clk_get()
993 pr_err("invalid clk index %u for provider %pOF\n", idx, clkspec->np); in vc3_of_clk_get()
994 return ERR_PTR(-EINVAL); in vc3_of_clk_get()
1002 struct device *dev = &client->dev; in vc3_probe()
1014 ret = of_property_read_u8_array(dev->of_node, "renesas,settings", in vc3_probe()
1028 } else if (ret == -EOVERFLOW) { in vc3_probe()
1029 dev_err(&client->dev, "EOVERFLOW reg settings. ARRAY_SIZE: %zu\n", in vc3_probe()
1040 clk_pfd_mux[i].hw.init->name); in vc3_probe()
1049 clk_pfd[i].hw.init->name); in vc3_probe()
1060 pll_data->vco = data->pll2_vco; in vc3_probe()
1065 clk_pll[i].hw.init->name); in vc3_probe()
1074 clk_div_mux[i].hw.init->name); in vc3_probe()
1083 clk_div[i].hw.init->name); in vc3_probe()
1092 clk_data->bitmsk = data->se2_clk_sel_msk; in vc3_probe()
1097 clk_mux[i].hw.init->name); in vc3_probe()
1122 return dev_err_probe(dev, -EINVAL, "invalid clk output %d\n", i); in vc3_probe()
1130 name, &clk_mux[i - 1].hw, CLK_SET_RATE_PARENT, 1, 1); in vc3_probe()