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>
17 #include <linux/mfd/syscon/xlnx-vcu.h>
23 #include <dt-bindings/clock/xlnx-vcu.h>
26 #define VCU_PLL_CTRL_RESET BIT(0)
27 #define VCU_PLL_CTRL_POR_IN BIT(1)
28 #define VCU_PLL_CTRL_PWR_POR BIT(2)
29 #define VCU_PLL_CTRL_BYPASS BIT(3)
36 #define VCU_PLL_CFG_LFHF GENMASK(12, 10)
44 #define VCU_PLL_STATUS_LOCK_STATUS BIT(0)
51 * struct xvcu_device - Xilinx VCU init device structure
59 * @pll_post: handle for the VCU PLL post divider
64 struct clk *pll_ref;
65 struct clk *aclk;
84 * struct xvcu_pll_cfg - Helper data
85 * @fbdiv: The integer portion of the feedback divider to the PLL
116 { 39, 3, 12, 3, 63, 950 },
117 { 40, 3, 12, 3, 63, 925 },
118 { 41, 3, 12, 3, 63, 900 },
119 { 42, 3, 12, 3, 63, 875 },
120 { 43, 3, 12, 3, 63, 850 },
121 { 44, 3, 12, 3, 63, 850 },
122 { 45, 3, 12, 3, 63, 825 },
123 { 46, 3, 12, 3, 63, 800 },
124 { 47, 3, 12, 3, 63, 775 },
125 { 48, 3, 12, 3, 63, 775 },
126 { 49, 3, 12, 3, 63, 750 },
127 { 50, 3, 12, 3, 63, 750 },
206 * xvcu_read - Read from the VCU register space
210 * Return: Returns 32bit value from VCU register specified
219 * xvcu_write - Write to the VCU register space
240 void __iomem *base = pll->reg_base;
251 return -ETIMEDOUT;
263 * The output divider of the PLL must be set to 1/2 to meet the
269 return ERR_PTR(-EINVAL);
281 for (i = 0; i < ARRAY_SIZE(xvcu_pll_cfg) - 1; i++)
290 void __iomem *base = pll->reg_base;
297 return -EINVAL;
301 vcu_pll_ctrl |= FIELD_PREP(VCU_PLL_CTRL_FBDIV, cfg->fbdiv);
304 cfg_val = FIELD_PREP(VCU_PLL_CFG_RES, cfg->res) |
305 FIELD_PREP(VCU_PLL_CFG_CP, cfg->cp) |
306 FIELD_PREP(VCU_PLL_CFG_LFHF, cfg->lfhf) |
307 FIELD_PREP(VCU_PLL_CFG_LOCK_CNT, cfg->lock_cnt) |
308 FIELD_PREP(VCU_PLL_CFG_LOCK_DLY, cfg->lock_dly);
320 rate = clamp_t(unsigned long, rate, pll->fvco_min, pll->fvco_max);
332 void __iomem *base = pll->reg_base;
353 void __iomem *base = pll->reg_base;
384 void __iomem *base = pll->reg_base;
420 return ERR_PTR(-ENOMEM);
422 pll->hw.init = &init;
423 pll->reg_base = reg_base;
424 pll->fvco_min = FVCO_MIN;
425 pll->fvco_max = FVCO_MAX;
427 hw = &pll->hw;
432 clk_hw_set_rate_range(hw, pll->fvco_min, pll->fvco_max);
447 struct clk_hw *divider = NULL;
457 return ERR_PTR(-ENOMEM);
462 return ERR_PTR(-ENOMEM);
472 err = -ENOMEM;
475 divider = clk_hw_register_divider_parent_hw(dev, name_div, mux,
479 if (IS_ERR(divider)) {
480 err = PTR_ERR(divider);
484 gate = clk_hw_register_gate_parent_hw(dev, name, divider,
485 CLK_SET_RATE_PARENT, reg, 12, 0,
495 clk_hw_unregister_divider(divider);
505 struct clk_hw *divider;
511 divider = clk_hw_get_parent(gate);
513 if (!divider)
516 mux = clk_hw_get_parent(divider);
518 if (!divider)
521 clk_hw_unregister_divider(divider);
526 struct device *dev = xvcu->dev;
531 void __iomem *reg_base = xvcu->vcu_slcr_ba;
535 return -ENOMEM;
536 data->num = CLK_XVCU_NUM_CLOCKS;
537 hws = data->hws;
539 xvcu->clk_data = data;
542 "vcu_pll", __clk_get_name(xvcu->pll_ref),
546 xvcu->pll = hw;
548 hw = xvcu_register_pll_post(dev, "vcu_pll_post", xvcu->pll, reg_base);
551 xvcu->pll_post = hw;
554 parent_data[1].hw = xvcu->pll_post;
582 struct clk_hw_onecell_data *data = xvcu->clk_data;
583 struct clk_hw **hws = data->hws;
593 if (!IS_ERR_OR_NULL(xvcu->pll_post))
594 clk_hw_unregister_fixed_factor(xvcu->pll_post);
598 * xvcu_probe - Probe existence of the logicoreIP
613 xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL);
615 return -ENOMEM;
617 xvcu->dev = &pdev->dev;
620 dev_err(&pdev->dev, "get vcu_slcr memory resource failed.\n");
621 return -ENODEV;
624 xvcu->vcu_slcr_ba = devm_ioremap(&pdev->dev, res->start,
626 if (!xvcu->vcu_slcr_ba) {
627 dev_err(&pdev->dev, "vcu_slcr register mapping failed.\n");
628 return -ENOMEM;
631 xvcu->logicore_reg_ba =
632 syscon_regmap_lookup_by_compatible("xlnx,vcu-settings");
633 if (IS_ERR(xvcu->logicore_reg_ba)) {
634 dev_info(&pdev->dev,
635 "could not find xlnx,vcu-settings: trying direct register access\n");
640 dev_err(&pdev->dev, "get logicore memory resource failed.\n");
641 return -ENODEV;
644 regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
646 dev_err(&pdev->dev, "logicore register mapping failed.\n");
647 return -ENOMEM;
650 xvcu->logicore_reg_ba =
651 devm_regmap_init_mmio(&pdev->dev, regs,
653 if (IS_ERR(xvcu->logicore_reg_ba)) {
654 dev_err(&pdev->dev, "failed to init regmap\n");
655 return PTR_ERR(xvcu->logicore_reg_ba);
659 xvcu->aclk = devm_clk_get(&pdev->dev, "aclk");
660 if (IS_ERR(xvcu->aclk)) {
661 dev_err(&pdev->dev, "Could not get aclk clock\n");
662 return PTR_ERR(xvcu->aclk);
665 xvcu->pll_ref = devm_clk_get(&pdev->dev, "pll_ref");
666 if (IS_ERR(xvcu->pll_ref)) {
667 dev_err(&pdev->dev, "Could not get pll_ref clock\n");
668 return PTR_ERR(xvcu->pll_ref);
671 ret = clk_prepare_enable(xvcu->aclk);
673 dev_err(&pdev->dev, "aclk clock enable failed\n");
679 * Bit 0 : Gasket isolation
680 * Bit 1 : put VCU out of reset
682 xvcu->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset",
684 if (IS_ERR(xvcu->reset_gpio)) {
685 ret = PTR_ERR(xvcu->reset_gpio);
686 dev_err_probe(&pdev->dev, ret, "failed to get reset gpio for vcu.\n");
690 if (xvcu->reset_gpio) {
691 gpiod_set_value(xvcu->reset_gpio, 0);
694 gpiod_set_value(xvcu->reset_gpio, 1);
697 dev_dbg(&pdev->dev, "No reset gpio info found in dts for VCU. This may result in incorrect functionality if VCU isolation is removed after initialization in designs where the VCU reset is driven by gpio.\n");
700 regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE);
704 dev_err(&pdev->dev, "failed to register clock provider\n");
708 dev_set_drvdata(&pdev->dev, xvcu);
715 clk_disable_unprepare(xvcu->aclk);
720 * xvcu_remove - Insert gasket isolation
736 if (xvcu->reset_gpio) {
737 gpiod_set_value(xvcu->reset_gpio, 0);
740 gpiod_set_value(xvcu->reset_gpio, 1);
743 regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0);
745 clk_disable_unprepare(xvcu->aclk);
750 { .compatible = "xlnx,vcu-logicoreip-1.0" },
757 .name = "xilinx-vcu",