Lines Matching +full:12 +full:bit +full:- +full:clk +full:- +full:divider

1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2016 - 2017 Xilinx, Inc.
10 #include <linux/clk.h>
11 #include <linux/clk-provider.h>
16 #include <linux/mfd/syscon/xlnx-vcu.h>
22 #include <dt-bindings/clock/xlnx-vcu.h>
25 #define VCU_PLL_CTRL_RESET BIT(0)
26 #define VCU_PLL_CTRL_POR_IN BIT(1)
27 #define VCU_PLL_CTRL_PWR_POR BIT(2)
28 #define VCU_PLL_CTRL_BYPASS BIT(3)
35 #define VCU_PLL_CFG_LFHF GENMASK(12, 10)
43 #define VCU_PLL_STATUS_LOCK_STATUS BIT(0)
50 * struct xvcu_device - Xilinx VCU init device structure
57 * @pll_post: handle for the VCU PLL post divider
62 struct clk *pll_ref;
63 struct clk *aclk;
81 * struct xvcu_pll_cfg - Helper data
82 * @fbdiv: The integer portion of the feedback divider to the PLL
113 { 39, 3, 12, 3, 63, 950 },
114 { 40, 3, 12, 3, 63, 925 },
115 { 41, 3, 12, 3, 63, 900 },
116 { 42, 3, 12, 3, 63, 875 },
117 { 43, 3, 12, 3, 63, 850 },
118 { 44, 3, 12, 3, 63, 850 },
119 { 45, 3, 12, 3, 63, 825 },
120 { 46, 3, 12, 3, 63, 800 },
121 { 47, 3, 12, 3, 63, 775 },
122 { 48, 3, 12, 3, 63, 775 },
123 { 49, 3, 12, 3, 63, 750 },
124 { 50, 3, 12, 3, 63, 750 },
203 * xvcu_read - Read from the VCU register space
207 * Return: Returns 32bit value from VCU register specified
216 * xvcu_write - Write to the VCU register space
237 void __iomem *base = pll->reg_base; in xvcu_pll_wait_for_lock()
248 return -ETIMEDOUT; in xvcu_pll_wait_for_lock()
260 * The output divider of the PLL must be set to 1/2 to meet the in xvcu_register_pll_post()
266 return ERR_PTR(-EINVAL); in xvcu_register_pll_post()
278 for (i = 0; i < ARRAY_SIZE(xvcu_pll_cfg) - 1; i++) in xvcu_find_cfg()
287 void __iomem *base = pll->reg_base; in xvcu_pll_set_div()
294 return -EINVAL; in xvcu_pll_set_div()
298 vcu_pll_ctrl |= FIELD_PREP(VCU_PLL_CTRL_FBDIV, cfg->fbdiv); in xvcu_pll_set_div()
301 cfg_val = FIELD_PREP(VCU_PLL_CFG_RES, cfg->res) | in xvcu_pll_set_div()
302 FIELD_PREP(VCU_PLL_CFG_CP, cfg->cp) | in xvcu_pll_set_div()
303 FIELD_PREP(VCU_PLL_CFG_LFHF, cfg->lfhf) | in xvcu_pll_set_div()
304 FIELD_PREP(VCU_PLL_CFG_LOCK_CNT, cfg->lock_cnt) | in xvcu_pll_set_div()
305 FIELD_PREP(VCU_PLL_CFG_LOCK_DLY, cfg->lock_dly); in xvcu_pll_set_div()
317 rate = clamp_t(unsigned long, rate, pll->fvco_min, pll->fvco_max); in xvcu_pll_round_rate()
329 void __iomem *base = pll->reg_base; in xvcu_pll_recalc_rate()
350 void __iomem *base = pll->reg_base; in xvcu_pll_enable()
381 void __iomem *base = pll->reg_base; in xvcu_pll_disable()
417 return ERR_PTR(-ENOMEM); in xvcu_register_pll()
419 pll->hw.init = &init; in xvcu_register_pll()
420 pll->reg_base = reg_base; in xvcu_register_pll()
421 pll->fvco_min = FVCO_MIN; in xvcu_register_pll()
422 pll->fvco_max = FVCO_MAX; in xvcu_register_pll()
424 hw = &pll->hw; in xvcu_register_pll()
429 clk_hw_set_rate_range(hw, pll->fvco_min, pll->fvco_max); in xvcu_register_pll()
444 struct clk_hw *divider = NULL; in xvcu_clk_hw_register_leaf() local
454 return ERR_PTR(-ENOMEM); in xvcu_clk_hw_register_leaf()
459 return ERR_PTR(-ENOMEM); in xvcu_clk_hw_register_leaf()
469 err = -ENOMEM; in xvcu_clk_hw_register_leaf()
472 divider = clk_hw_register_divider_parent_hw(dev, name_div, mux, in xvcu_clk_hw_register_leaf()
476 if (IS_ERR(divider)) { in xvcu_clk_hw_register_leaf()
477 err = PTR_ERR(divider); in xvcu_clk_hw_register_leaf()
481 gate = clk_hw_register_gate_parent_hw(dev, name, divider, in xvcu_clk_hw_register_leaf()
482 CLK_SET_RATE_PARENT, reg, 12, 0, in xvcu_clk_hw_register_leaf()
492 clk_hw_unregister_divider(divider); in xvcu_clk_hw_register_leaf()
502 struct clk_hw *divider; in xvcu_clk_hw_unregister_leaf() local
508 divider = clk_hw_get_parent(gate); in xvcu_clk_hw_unregister_leaf()
510 if (!divider) in xvcu_clk_hw_unregister_leaf()
513 mux = clk_hw_get_parent(divider); in xvcu_clk_hw_unregister_leaf()
515 if (!divider) in xvcu_clk_hw_unregister_leaf()
518 clk_hw_unregister_divider(divider); in xvcu_clk_hw_unregister_leaf()
523 struct device *dev = xvcu->dev; in xvcu_register_clock_provider()
528 void __iomem *reg_base = xvcu->vcu_slcr_ba; in xvcu_register_clock_provider()
532 return -ENOMEM; in xvcu_register_clock_provider()
533 data->num = CLK_XVCU_NUM_CLOCKS; in xvcu_register_clock_provider()
534 hws = data->hws; in xvcu_register_clock_provider()
536 xvcu->clk_data = data; in xvcu_register_clock_provider()
539 "vcu_pll", __clk_get_name(xvcu->pll_ref), in xvcu_register_clock_provider()
543 xvcu->pll = hw; in xvcu_register_clock_provider()
545 hw = xvcu_register_pll_post(dev, "vcu_pll_post", xvcu->pll, reg_base); in xvcu_register_clock_provider()
548 xvcu->pll_post = hw; in xvcu_register_clock_provider()
551 parent_data[1].hw = xvcu->pll_post; in xvcu_register_clock_provider()
579 struct clk_hw_onecell_data *data = xvcu->clk_data; in xvcu_unregister_clock_provider()
580 struct clk_hw **hws = data->hws; in xvcu_unregister_clock_provider()
591 clk_hw_unregister_fixed_factor(xvcu->pll_post); in xvcu_unregister_clock_provider()
595 * xvcu_probe - Probe existence of the logicoreIP
610 xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL); in xvcu_probe()
612 return -ENOMEM; in xvcu_probe()
614 xvcu->dev = &pdev->dev; in xvcu_probe()
617 dev_err(&pdev->dev, "get vcu_slcr memory resource failed.\n"); in xvcu_probe()
618 return -ENODEV; in xvcu_probe()
621 xvcu->vcu_slcr_ba = devm_ioremap(&pdev->dev, res->start, in xvcu_probe()
623 if (!xvcu->vcu_slcr_ba) { in xvcu_probe()
624 dev_err(&pdev->dev, "vcu_slcr register mapping failed.\n"); in xvcu_probe()
625 return -ENOMEM; in xvcu_probe()
628 xvcu->logicore_reg_ba = in xvcu_probe()
629 syscon_regmap_lookup_by_compatible("xlnx,vcu-settings"); in xvcu_probe()
630 if (IS_ERR(xvcu->logicore_reg_ba)) { in xvcu_probe()
631 dev_info(&pdev->dev, in xvcu_probe()
632 "could not find xlnx,vcu-settings: trying direct register access\n"); in xvcu_probe()
637 dev_err(&pdev->dev, "get logicore memory resource failed.\n"); in xvcu_probe()
638 return -ENODEV; in xvcu_probe()
641 regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); in xvcu_probe()
643 dev_err(&pdev->dev, "logicore register mapping failed.\n"); in xvcu_probe()
644 return -ENOMEM; in xvcu_probe()
647 xvcu->logicore_reg_ba = in xvcu_probe()
648 devm_regmap_init_mmio(&pdev->dev, regs, in xvcu_probe()
650 if (IS_ERR(xvcu->logicore_reg_ba)) { in xvcu_probe()
651 dev_err(&pdev->dev, "failed to init regmap\n"); in xvcu_probe()
652 return PTR_ERR(xvcu->logicore_reg_ba); in xvcu_probe()
656 xvcu->aclk = devm_clk_get(&pdev->dev, "aclk"); in xvcu_probe()
657 if (IS_ERR(xvcu->aclk)) { in xvcu_probe()
658 dev_err(&pdev->dev, "Could not get aclk clock\n"); in xvcu_probe()
659 return PTR_ERR(xvcu->aclk); in xvcu_probe()
662 xvcu->pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); in xvcu_probe()
663 if (IS_ERR(xvcu->pll_ref)) { in xvcu_probe()
664 dev_err(&pdev->dev, "Could not get pll_ref clock\n"); in xvcu_probe()
665 return PTR_ERR(xvcu->pll_ref); in xvcu_probe()
668 ret = clk_prepare_enable(xvcu->aclk); in xvcu_probe()
670 dev_err(&pdev->dev, "aclk clock enable failed\n"); in xvcu_probe()
676 * Bit 0 : Gasket isolation in xvcu_probe()
677 * Bit 1 : put VCU out of reset in xvcu_probe()
679 regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE); in xvcu_probe()
683 dev_err(&pdev->dev, "failed to register clock provider\n"); in xvcu_probe()
687 dev_set_drvdata(&pdev->dev, xvcu); in xvcu_probe()
693 clk_disable_unprepare(xvcu->aclk); in xvcu_probe()
698 * xvcu_remove - Insert gasket isolation
714 regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0); in xvcu_remove()
716 clk_disable_unprepare(xvcu->aclk); in xvcu_remove()
721 { .compatible = "xlnx,vcu-logicoreip-1.0" },
728 .name = "xilinx-vcu",