Lines Matching +full:lpc3220 +full:- +full:adc
1 // SPDX-License-Identifier: GPL-2.0-or-later
7 #include <linux/clk-provider.h>
12 #include <dt-bindings/clock/lpc32xx-clock.h>
283 LPC32XX_CLK_DEFINE(ADC, "adc", 0x0,
392 regmap_read(clk_regmap, clk->reg, &val); in clk_mask_enable()
394 if (clk->busy_mask && (val & clk->busy_mask) == clk->busy) in clk_mask_enable()
395 return -EBUSY; in clk_mask_enable()
397 return regmap_update_bits(clk_regmap, clk->reg, in clk_mask_enable()
398 clk->enable_mask, clk->enable); in clk_mask_enable()
405 regmap_update_bits(clk_regmap, clk->reg, in clk_mask_disable()
406 clk->disable_mask, clk->disable); in clk_mask_disable()
414 regmap_read(clk_regmap, clk->reg, &val); in clk_mask_is_enabled()
416 return ((val & clk->enable_mask) == clk->enable); in clk_mask_is_enabled()
430 regmap_update_bits(clk_regmap, clk->reg, clk->enable, clk->enable); in clk_pll_enable()
433 regmap_read(clk_regmap, clk->reg, &val); in clk_pll_enable()
441 return -ETIMEDOUT; in clk_pll_enable()
448 regmap_update_bits(clk_regmap, clk->reg, clk->enable, 0x0); in clk_pll_disable()
456 regmap_read(clk_regmap, clk->reg, &val); in clk_pll_is_enabled()
458 val &= clk->enable | PLL_CTRL_LOCK; in clk_pll_is_enabled()
459 if (val == (clk->enable | PLL_CTRL_LOCK)) in clk_pll_is_enabled()
479 regmap_read(clk_regmap, clk->reg, &val); in clk_pll_recalc_rate()
484 clk->m_div = ((val & PLL_CTRL_FEEDDIV) >> 1) + 1; in clk_pll_recalc_rate()
485 clk->n_div = ((val & PLL_CTRL_PREDIV) >> 9) + 1; in clk_pll_recalc_rate()
486 clk->p_div = ((val & PLL_CTRL_POSTDIV) >> 11) + 1; in clk_pll_recalc_rate()
489 clk->p_div = 0; in clk_pll_recalc_rate()
490 clk->mode = PLL_DIRECT_BYPASS; in clk_pll_recalc_rate()
494 clk->mode = PLL_BYPASS; in clk_pll_recalc_rate()
495 return parent_rate / (1 << clk->p_div); in clk_pll_recalc_rate()
498 clk->p_div = 0; in clk_pll_recalc_rate()
499 clk->mode = PLL_DIRECT; in clk_pll_recalc_rate()
502 ref_rate = parent_rate / clk->n_div; in clk_pll_recalc_rate()
503 rate = cco_rate = ref_rate * clk->m_div; in clk_pll_recalc_rate()
507 cco_rate *= (1 << clk->p_div); in clk_pll_recalc_rate()
508 clk->mode = PLL_INTEGER; in clk_pll_recalc_rate()
510 rate /= (1 << clk->p_div); in clk_pll_recalc_rate()
511 clk->mode = PLL_NON_INTEGER; in clk_pll_recalc_rate()
518 clk->n_div, clk->m_div, (1 << clk->p_div), rate); in clk_pll_recalc_rate()
539 switch (clk->mode) { in clk_pll_set_rate()
542 val |= (clk->m_div - 1) << 1; in clk_pll_set_rate()
543 val |= (clk->n_div - 1) << 9; in clk_pll_set_rate()
544 new_rate = (parent_rate * clk->m_div) / clk->n_div; in clk_pll_set_rate()
548 val |= (clk->p_div - 1) << 11; in clk_pll_set_rate()
549 new_rate = parent_rate / (1 << (clk->p_div)); in clk_pll_set_rate()
557 val |= (clk->m_div - 1) << 1; in clk_pll_set_rate()
558 val |= (clk->n_div - 1) << 9; in clk_pll_set_rate()
559 val |= (clk->p_div - 1) << 11; in clk_pll_set_rate()
560 new_rate = (parent_rate * clk->m_div) / clk->n_div; in clk_pll_set_rate()
564 val |= (clk->m_div - 1) << 1; in clk_pll_set_rate()
565 val |= (clk->n_div - 1) << 9; in clk_pll_set_rate()
566 val |= (clk->p_div - 1) << 11; in clk_pll_set_rate()
567 new_rate = (parent_rate * clk->m_div) / in clk_pll_set_rate()
568 (clk->n_div * (1 << clk->p_div)); in clk_pll_set_rate()
571 return -EINVAL; in clk_pll_set_rate()
576 return -EINVAL; in clk_pll_set_rate()
578 return regmap_update_bits(clk_regmap, clk->reg, 0x1FFFF, val); in clk_pll_set_rate()
585 u64 m_i, o = req->rate, i = req->best_parent_rate, d = (u64)req->rate << 6; in clk_hclk_pll_determine_rate()
589 pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), req->best_parent_rate, req->rate); in clk_hclk_pll_determine_rate()
591 if (req->rate > 266500000) in clk_hclk_pll_determine_rate()
592 return -EINVAL; in clk_hclk_pll_determine_rate()
595 for (p_i = 4; p_i >= 0; p_i--) { in clk_hclk_pll_determine_rate()
596 for (n_i = 4; n_i > 0; n_i--) { in clk_hclk_pll_determine_rate()
607 if (o * n_i * (1 << p_i) - i * m_i <= d) { in clk_hclk_pll_determine_rate()
611 d = o * n_i * (1 << p_i) - i * m_i; in clk_hclk_pll_determine_rate()
616 if (d == (u64)req->rate << 6) { in clk_hclk_pll_determine_rate()
618 clk_hw_get_name(hw), req->rate); in clk_hclk_pll_determine_rate()
619 return -EINVAL; in clk_hclk_pll_determine_rate()
622 clk->m_div = m; in clk_hclk_pll_determine_rate()
623 clk->n_div = n; in clk_hclk_pll_determine_rate()
624 clk->p_div = p; in clk_hclk_pll_determine_rate()
626 /* Set only direct or non-integer mode of PLL */ in clk_hclk_pll_determine_rate()
628 clk->mode = PLL_DIRECT; in clk_hclk_pll_determine_rate()
630 clk->mode = PLL_NON_INTEGER; in clk_hclk_pll_determine_rate()
636 clk_hw_get_name(hw), req->rate, m, n, p); in clk_hclk_pll_determine_rate()
638 pr_debug("%s: %lu: found closest: %llu/%llu/%llu - %llu\n", in clk_hclk_pll_determine_rate()
639 clk_hw_get_name(hw), req->rate, m, n, p, o); in clk_hclk_pll_determine_rate()
641 req->rate = o; in clk_hclk_pll_determine_rate()
653 pr_debug("%s: %lu/%lu\n", clk_hw_get_name(hw), req->best_parent_rate, in clk_usb_pll_determine_rate()
654 req->rate); in clk_usb_pll_determine_rate()
659 * and post-divider must be 4, this slightly simplifies calculation of in clk_usb_pll_determine_rate()
662 if (req->rate != 48000000) in clk_usb_pll_determine_rate()
663 return -EINVAL; in clk_usb_pll_determine_rate()
668 return -EINVAL; in clk_usb_pll_determine_rate()
673 return -EINVAL; in clk_usb_pll_determine_rate()
677 for (d_i = 16; d_i >= 1; d_i--) { in clk_usb_pll_determine_rate()
686 clk->n_div = n_i; in clk_usb_pll_determine_rate()
687 clk->m_div = m; in clk_usb_pll_determine_rate()
688 clk->p_div = 2; in clk_usb_pll_determine_rate()
689 clk->mode = PLL_NON_INTEGER; in clk_usb_pll_determine_rate()
690 req->best_parent_rate = div64_u64(o, d_i); in clk_usb_pll_determine_rate()
696 return -EINVAL; in clk_usb_pll_determine_rate()
720 regmap_read(clk_regmap, clk->reg, &val); in clk_ddram_is_enabled()
721 val &= clk->enable_mask | clk->busy_mask; in clk_ddram_is_enabled()
732 regmap_read(clk_regmap, clk->reg, &val); in clk_ddram_enable()
733 hclk_div = val & clk->busy_mask; in clk_ddram_enable()
741 return -EINVAL; in clk_ddram_enable()
743 return regmap_update_bits(clk_regmap, clk->reg, in clk_ddram_enable()
744 clk->enable_mask, hclk_div << 7); in clk_ddram_enable()
756 regmap_read(clk_regmap, clk->reg, &val); in clk_ddram_recalc_rate()
757 val &= clk->enable_mask; in clk_ddram_recalc_rate()
775 regmap_read(clk_regmap, clk->reg, &val); in lpc32xx_clk_uart_recalc_rate()
804 pr_debug("%s: 0x%x\n", clk_hw_get_name(hw), clk->enable); in clk_usb_enable()
806 if (clk->ctrl_mask) { in clk_usb_enable()
809 clk->ctrl_mask, clk->ctrl_enable); in clk_usb_enable()
813 if (clk->busy && (val & clk->busy) == clk->busy) { in clk_usb_enable()
814 if (clk->ctrl_mask) in clk_usb_enable()
817 return -EBUSY; in clk_usb_enable()
820 val |= clk->enable; in clk_usb_enable()
825 if ((val & clk->enable) == clk->enable) in clk_usb_enable()
829 if ((val & clk->enable) == clk->enable) in clk_usb_enable()
832 if (clk->ctrl_mask) in clk_usb_enable()
835 return -ETIMEDOUT; in clk_usb_enable()
843 val &= ~clk->enable; in clk_usb_disable()
846 if (clk->ctrl_mask) in clk_usb_disable()
848 clk->ctrl_mask, clk->ctrl_disable); in clk_usb_disable()
856 if (clk->ctrl_mask) { in clk_usb_is_enabled()
858 if ((ctrl_val & clk->ctrl_mask) != clk->ctrl_enable) in clk_usb_is_enabled()
864 return ((val & clk->enable) == clk->enable); in clk_usb_is_enabled()
889 u32 mask = BIT(clk->bit_idx); in lpc32xx_clk_gate_enable()
890 u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? 0x0 : mask); in lpc32xx_clk_gate_enable()
892 return regmap_update_bits(clk_regmap, clk->reg, mask, val); in lpc32xx_clk_gate_enable()
898 u32 mask = BIT(clk->bit_idx); in lpc32xx_clk_gate_disable()
899 u32 val = (clk->flags & CLK_GATE_SET_TO_DISABLE ? mask : 0x0); in lpc32xx_clk_gate_disable()
901 regmap_update_bits(clk_regmap, clk->reg, mask, val); in lpc32xx_clk_gate_disable()
910 regmap_read(clk_regmap, clk->reg, &val); in lpc32xx_clk_gate_is_enabled()
911 is_set = val & BIT(clk->bit_idx); in lpc32xx_clk_gate_is_enabled()
913 return (clk->flags & CLK_GATE_SET_TO_DISABLE ? !is_set : is_set); in lpc32xx_clk_gate_is_enabled()
922 #define div_mask(width) ((1 << (width)) - 1)
929 for (clkt = table; clkt->div; clkt++) in _get_table_div()
930 if (clkt->val == val) in _get_table_div()
931 return clkt->div; in _get_table_div()
951 regmap_read(clk_regmap, divider->reg, &val); in clk_divider_recalc_rate()
953 val >>= divider->shift; in clk_divider_recalc_rate()
954 val &= div_mask(divider->width); in clk_divider_recalc_rate()
956 return divider_recalc_rate(hw, parent_rate, val, divider->table, in clk_divider_recalc_rate()
957 divider->flags, divider->width); in clk_divider_recalc_rate()
967 if (divider->flags & CLK_DIVIDER_READ_ONLY) { in clk_divider_determine_rate()
968 regmap_read(clk_regmap, divider->reg, &bestdiv); in clk_divider_determine_rate()
969 bestdiv >>= divider->shift; in clk_divider_determine_rate()
970 bestdiv &= div_mask(divider->width); in clk_divider_determine_rate()
971 bestdiv = _get_div(divider->table, bestdiv, divider->flags, in clk_divider_determine_rate()
972 divider->width); in clk_divider_determine_rate()
973 req->rate = DIV_ROUND_UP(req->best_parent_rate, bestdiv); in clk_divider_determine_rate()
978 req->rate = divider_round_rate(hw, req->rate, &req->best_parent_rate, in clk_divider_determine_rate()
979 divider->table, divider->width, divider->flags); in clk_divider_determine_rate()
990 value = divider_get_val(rate, parent_rate, divider->table, in clk_divider_set_rate()
991 divider->width, divider->flags); in clk_divider_set_rate()
993 return regmap_update_bits(clk_regmap, divider->reg, in clk_divider_set_rate()
994 div_mask(divider->width) << divider->shift, in clk_divider_set_rate()
995 value << divider->shift); in clk_divider_set_rate()
1010 regmap_read(clk_regmap, mux->reg, &val); in clk_mux_get_parent()
1011 val >>= mux->shift; in clk_mux_get_parent()
1012 val &= mux->mask; in clk_mux_get_parent()
1014 if (mux->table) { in clk_mux_get_parent()
1018 if (mux->table[i] == val) in clk_mux_get_parent()
1020 return -EINVAL; in clk_mux_get_parent()
1024 return -EINVAL; in clk_mux_get_parent()
1033 if (mux->table) in clk_mux_set_parent()
1034 index = mux->table[index]; in clk_mux_set_parent()
1036 return regmap_update_bits(clk_regmap, mux->reg, in clk_mux_set_parent()
1037 mux->mask << mux->shift, index << mux->shift); in clk_mux_set_parent()
1240 /* Register 3 read-only muxes with a single control PWR_CTRL[2] */
1247 /* Register 2 read-only muxes with a single control PWR_CTRL[10] */
1359 * ADC/TS clock unfortunately cannot be registered as a composite one
1363 * rtc-->[gate]-->| |
1364 * | mux |--> adc/ts
1365 * pclk-->[div]-->| |
1368 * ADC --- resulting clock must be <= 4.5 MHz
1369 * TS --- resulting clock must be <= 400 KHz
1373 LPC32XX_DEFINE_MUX(ADC, ADCCLK_CTRL1, 8, 0x1, NULL, 0),
1396 for (i = 0; i < lpc32xx_clk->num_parents; i++) in lpc32xx_clk_register()
1397 parents[i] = clk_proto[lpc32xx_clk->parents[i]].name; in lpc32xx_clk_register()
1399 pr_debug("%s: derived from '%s', clock type %d\n", lpc32xx_clk->name, in lpc32xx_clk_register()
1400 parents[0], clk_hw->type); in lpc32xx_clk_register()
1402 switch (clk_hw->type) { in lpc32xx_clk_register()
1411 .name = lpc32xx_clk->name, in lpc32xx_clk_register()
1413 .num_parents = lpc32xx_clk->num_parents, in lpc32xx_clk_register()
1414 .flags = lpc32xx_clk->flags, in lpc32xx_clk_register()
1415 .ops = clk_hw->hw0.ops, in lpc32xx_clk_register()
1419 if (clk_hw->type == CLK_LPC32XX) in lpc32xx_clk_register()
1420 hw = &clk_hw->hw0.clk.hw; in lpc32xx_clk_register()
1421 else if (clk_hw->type == CLK_LPC32XX_PLL) in lpc32xx_clk_register()
1422 hw = &clk_hw->hw0.pll.hw; in lpc32xx_clk_register()
1423 else if (clk_hw->type == CLK_LPC32XX_USB) in lpc32xx_clk_register()
1424 hw = &clk_hw->hw0.usb_clk.hw; in lpc32xx_clk_register()
1425 else if (clk_hw->type == CLK_MUX) in lpc32xx_clk_register()
1426 hw = &clk_hw->hw0.mux.hw; in lpc32xx_clk_register()
1427 else if (clk_hw->type == CLK_DIV) in lpc32xx_clk_register()
1428 hw = &clk_hw->hw0.div.hw; in lpc32xx_clk_register()
1429 else if (clk_hw->type == CLK_GATE) in lpc32xx_clk_register()
1430 hw = &clk_hw->hw0.gate.hw; in lpc32xx_clk_register()
1432 return ERR_PTR(-EINVAL); in lpc32xx_clk_register()
1434 hw->init = &clk_init; in lpc32xx_clk_register()
1444 mux0 = clk_hw->hw1.mux; in lpc32xx_clk_register()
1445 div0 = clk_hw->hw1.div; in lpc32xx_clk_register()
1446 gate0 = clk_hw->hw1.gate; in lpc32xx_clk_register()
1448 mops = mux0->ops; in lpc32xx_clk_register()
1449 mux_hw = &mux0->clk.hw; in lpc32xx_clk_register()
1452 dops = div0->ops; in lpc32xx_clk_register()
1453 div_hw = &div0->clk.hw; in lpc32xx_clk_register()
1456 gops = gate0->ops; in lpc32xx_clk_register()
1457 gate_hw = &gate0->clk.hw; in lpc32xx_clk_register()
1460 clk = clk_register_composite(NULL, lpc32xx_clk->name, in lpc32xx_clk_register()
1461 parents, lpc32xx_clk->num_parents, in lpc32xx_clk_register()
1463 gate_hw, gops, lpc32xx_clk->flags); in lpc32xx_clk_register()
1468 struct clk_fixed_rate *fixed = &clk_hw->f; in lpc32xx_clk_register()
1470 clk = clk_register_fixed_rate(NULL, lpc32xx_clk->name, in lpc32xx_clk_register()
1471 parents[0], 0, fixed->fixed_rate); in lpc32xx_clk_register()
1475 clk = ERR_PTR(-EINVAL); in lpc32xx_clk_register()
1570 CLK_OF_DECLARE(lpc32xx_clk, "nxp,lpc3220-clk", lpc32xx_clk_init);
1593 CLK_OF_DECLARE(lpc32xx_usb_clk, "nxp,lpc3220-usb-clk", lpc32xx_usb_clk_init);