Lines Matching +full:- +full:3
1 // SPDX-License-Identifier: GPL-2.0
5 * Copyright (C) 2016 - 2017 Xilinx, Inc.
11 #include <linux/clk-provider.h>
17 #include <linux/mfd/syscon/xlnx-vcu.h>
23 #include <dt-bindings/clock/xlnx-vcu.h>
29 #define VCU_PLL_CTRL_BYPASS BIT(3)
34 #define VCU_PLL_CFG_RES GENMASK(3, 0)
51 * struct xvcu_device - Xilinx VCU init device structure
84 * struct xvcu_pll_cfg - Helper data
102 { 25, 3, 10, 3, 63, 1000 },
103 { 26, 3, 10, 3, 63, 1000 },
104 { 27, 4, 6, 3, 63, 1000 },
105 { 28, 4, 6, 3, 63, 1000 },
106 { 29, 4, 6, 3, 63, 1000 },
107 { 30, 4, 6, 3, 63, 1000 },
108 { 31, 6, 1, 3, 63, 1000 },
109 { 32, 6, 1, 3, 63, 1000 },
110 { 33, 4, 10, 3, 63, 1000 },
111 { 34, 5, 6, 3, 63, 1000 },
112 { 35, 5, 6, 3, 63, 1000 },
113 { 36, 5, 6, 3, 63, 1000 },
114 { 37, 5, 6, 3, 63, 1000 },
115 { 38, 5, 6, 3, 63, 975 },
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 },
128 { 51, 3, 2, 3, 63, 725 },
129 { 52, 3, 2, 3, 63, 700 },
130 { 53, 3, 2, 3, 63, 700 },
131 { 54, 3, 2, 3, 63, 675 },
132 { 55, 3, 2, 3, 63, 675 },
133 { 56, 3, 2, 3, 63, 650 },
134 { 57, 3, 2, 3, 63, 650 },
135 { 58, 3, 2, 3, 63, 625 },
136 { 59, 3, 2, 3, 63, 625 },
137 { 60, 3, 2, 3, 63, 625 },
138 { 61, 3, 2, 3, 63, 600 },
139 { 62, 3, 2, 3, 63, 600 },
140 { 63, 3, 2, 3, 63, 600 },
141 { 64, 3, 2, 3, 63, 600 },
142 { 65, 3, 2, 3, 63, 600 },
143 { 66, 3, 2, 3, 63, 600 },
144 { 67, 3, 2, 3, 63, 600 },
145 { 68, 3, 2, 3, 63, 600 },
146 { 69, 3, 2, 3, 63, 600 },
147 { 70, 3, 2, 3, 63, 600 },
148 { 71, 3, 2, 3, 63, 600 },
149 { 72, 3, 2, 3, 63, 600 },
150 { 73, 3, 2, 3, 63, 600 },
151 { 74, 3, 2, 3, 63, 600 },
152 { 75, 3, 2, 3, 63, 600 },
153 { 76, 3, 2, 3, 63, 600 },
154 { 77, 3, 2, 3, 63, 600 },
155 { 78, 3, 2, 3, 63, 600 },
156 { 79, 3, 2, 3, 63, 600 },
157 { 80, 3, 2, 3, 63, 600 },
158 { 81, 3, 2, 3, 63, 600 },
159 { 82, 3, 2, 3, 63, 600 },
160 { 83, 4, 2, 3, 63, 600 },
161 { 84, 4, 2, 3, 63, 600 },
162 { 85, 4, 2, 3, 63, 600 },
163 { 86, 4, 2, 3, 63, 600 },
164 { 87, 4, 2, 3, 63, 600 },
165 { 88, 4, 2, 3, 63, 600 },
166 { 89, 4, 2, 3, 63, 600 },
167 { 90, 4, 2, 3, 63, 600 },
168 { 91, 4, 2, 3, 63, 600 },
169 { 92, 4, 2, 3, 63, 600 },
170 { 93, 4, 2, 3, 63, 600 },
171 { 94, 4, 2, 3, 63, 600 },
172 { 95, 4, 2, 3, 63, 600 },
173 { 96, 4, 2, 3, 63, 600 },
174 { 97, 4, 2, 3, 63, 600 },
175 { 98, 4, 2, 3, 63, 600 },
176 { 99, 4, 2, 3, 63, 600 },
177 { 100, 4, 2, 3, 63, 600 },
178 { 101, 4, 2, 3, 63, 600 },
179 { 102, 4, 2, 3, 63, 600 },
180 { 103, 5, 2, 3, 63, 600 },
181 { 104, 5, 2, 3, 63, 600 },
182 { 105, 5, 2, 3, 63, 600 },
183 { 106, 5, 2, 3, 63, 600 },
184 { 107, 3, 4, 3, 63, 600 },
185 { 108, 3, 4, 3, 63, 600 },
186 { 109, 3, 4, 3, 63, 600 },
187 { 110, 3, 4, 3, 63, 600 },
188 { 111, 3, 4, 3, 63, 600 },
189 { 112, 3, 4, 3, 63, 600 },
190 { 113, 3, 4, 3, 63, 600 },
191 { 114, 3, 4, 3, 63, 600 },
192 { 115, 3, 4, 3, 63, 600 },
193 { 116, 3, 4, 3, 63, 600 },
194 { 117, 3, 4, 3, 63, 600 },
195 { 118, 3, 4, 3, 63, 600 },
196 { 119, 3, 4, 3, 63, 600 },
197 { 120, 3, 4, 3, 63, 600 },
198 { 121, 3, 4, 3, 63, 600 },
199 { 122, 3, 4, 3, 63, 600 },
200 { 123, 3, 4, 3, 63, 600 },
201 { 124, 3, 4, 3, 63, 600 },
202 { 125, 3, 4, 3, 63, 600 },
206 * xvcu_read - Read from the VCU register space
219 * xvcu_write - Write to the VCU register space
240 void __iomem *base = pll->reg_base; in xvcu_pll_wait_for_lock()
251 return -ETIMEDOUT; in xvcu_pll_wait_for_lock()
269 return ERR_PTR(-EINVAL); in xvcu_register_pll_post()
281 for (i = 0; i < ARRAY_SIZE(xvcu_pll_cfg) - 1; i++) in xvcu_find_cfg()
290 void __iomem *base = pll->reg_base; in xvcu_pll_set_div()
297 return -EINVAL; in xvcu_pll_set_div()
301 vcu_pll_ctrl |= FIELD_PREP(VCU_PLL_CTRL_FBDIV, cfg->fbdiv); in xvcu_pll_set_div()
304 cfg_val = FIELD_PREP(VCU_PLL_CFG_RES, cfg->res) | in xvcu_pll_set_div()
305 FIELD_PREP(VCU_PLL_CFG_CP, cfg->cp) | in xvcu_pll_set_div()
306 FIELD_PREP(VCU_PLL_CFG_LFHF, cfg->lfhf) | in xvcu_pll_set_div()
307 FIELD_PREP(VCU_PLL_CFG_LOCK_CNT, cfg->lock_cnt) | in xvcu_pll_set_div()
308 FIELD_PREP(VCU_PLL_CFG_LOCK_DLY, cfg->lock_dly); in xvcu_pll_set_div()
320 req->rate = clamp_t(unsigned long, req->rate, pll->fvco_min, in xvcu_pll_determine_rate()
321 pll->fvco_max); in xvcu_pll_determine_rate()
323 feedback_div = DIV_ROUND_CLOSEST_ULL(req->rate, req->best_parent_rate); in xvcu_pll_determine_rate()
326 req->rate = req->best_parent_rate * feedback_div; in xvcu_pll_determine_rate()
335 void __iomem *base = pll->reg_base; in xvcu_pll_recalc_rate()
356 void __iomem *base = pll->reg_base; in xvcu_pll_enable()
387 void __iomem *base = pll->reg_base; in xvcu_pll_disable()
423 return ERR_PTR(-ENOMEM); in xvcu_register_pll()
425 pll->hw.init = &init; in xvcu_register_pll()
426 pll->reg_base = reg_base; in xvcu_register_pll()
427 pll->fvco_min = FVCO_MIN; in xvcu_register_pll()
428 pll->fvco_max = FVCO_MAX; in xvcu_register_pll()
430 hw = &pll->hw; in xvcu_register_pll()
435 clk_hw_set_rate_range(hw, pll->fvco_min, pll->fvco_max); in xvcu_register_pll()
460 return ERR_PTR(-ENOMEM); in xvcu_clk_hw_register_leaf()
465 return ERR_PTR(-ENOMEM); in xvcu_clk_hw_register_leaf()
475 err = -ENOMEM; in xvcu_clk_hw_register_leaf()
529 struct device *dev = xvcu->dev; in xvcu_register_clock_provider()
534 void __iomem *reg_base = xvcu->vcu_slcr_ba; in xvcu_register_clock_provider()
538 return -ENOMEM; in xvcu_register_clock_provider()
539 data->num = CLK_XVCU_NUM_CLOCKS; in xvcu_register_clock_provider()
540 hws = data->hws; in xvcu_register_clock_provider()
542 xvcu->clk_data = data; in xvcu_register_clock_provider()
545 "vcu_pll", __clk_get_name(xvcu->pll_ref), in xvcu_register_clock_provider()
549 xvcu->pll = hw; in xvcu_register_clock_provider()
551 hw = xvcu_register_pll_post(dev, "vcu_pll_post", xvcu->pll, reg_base); in xvcu_register_clock_provider()
554 xvcu->pll_post = hw; in xvcu_register_clock_provider()
557 parent_data[1].hw = xvcu->pll_post; in xvcu_register_clock_provider()
585 struct clk_hw_onecell_data *data = xvcu->clk_data; in xvcu_unregister_clock_provider()
586 struct clk_hw **hws = data->hws; in xvcu_unregister_clock_provider()
596 if (!IS_ERR_OR_NULL(xvcu->pll_post)) in xvcu_unregister_clock_provider()
597 clk_hw_unregister_fixed_factor(xvcu->pll_post); in xvcu_unregister_clock_provider()
601 * xvcu_probe - Probe existence of the logicoreIP
616 xvcu = devm_kzalloc(&pdev->dev, sizeof(*xvcu), GFP_KERNEL); in xvcu_probe()
618 return -ENOMEM; in xvcu_probe()
620 xvcu->dev = &pdev->dev; in xvcu_probe()
623 dev_err(&pdev->dev, "get vcu_slcr memory resource failed.\n"); in xvcu_probe()
624 return -ENODEV; in xvcu_probe()
627 xvcu->vcu_slcr_ba = devm_ioremap(&pdev->dev, res->start, in xvcu_probe()
629 if (!xvcu->vcu_slcr_ba) { in xvcu_probe()
630 dev_err(&pdev->dev, "vcu_slcr register mapping failed.\n"); in xvcu_probe()
631 return -ENOMEM; in xvcu_probe()
634 xvcu->logicore_reg_ba = in xvcu_probe()
635 syscon_regmap_lookup_by_compatible("xlnx,vcu-settings"); in xvcu_probe()
636 if (IS_ERR(xvcu->logicore_reg_ba)) { in xvcu_probe()
637 dev_info(&pdev->dev, in xvcu_probe()
638 "could not find xlnx,vcu-settings: trying direct register access\n"); in xvcu_probe()
643 dev_err(&pdev->dev, "get logicore memory resource failed.\n"); in xvcu_probe()
644 return -ENODEV; in xvcu_probe()
647 regs = devm_ioremap(&pdev->dev, res->start, resource_size(res)); in xvcu_probe()
649 dev_err(&pdev->dev, "logicore register mapping failed.\n"); in xvcu_probe()
650 return -ENOMEM; in xvcu_probe()
653 xvcu->logicore_reg_ba = in xvcu_probe()
654 devm_regmap_init_mmio(&pdev->dev, regs, in xvcu_probe()
656 if (IS_ERR(xvcu->logicore_reg_ba)) { in xvcu_probe()
657 dev_err(&pdev->dev, "failed to init regmap\n"); in xvcu_probe()
658 return PTR_ERR(xvcu->logicore_reg_ba); in xvcu_probe()
662 xvcu->aclk = devm_clk_get(&pdev->dev, "aclk"); in xvcu_probe()
663 if (IS_ERR(xvcu->aclk)) { in xvcu_probe()
664 dev_err(&pdev->dev, "Could not get aclk clock\n"); in xvcu_probe()
665 return PTR_ERR(xvcu->aclk); in xvcu_probe()
668 xvcu->pll_ref = devm_clk_get(&pdev->dev, "pll_ref"); in xvcu_probe()
669 if (IS_ERR(xvcu->pll_ref)) { in xvcu_probe()
670 dev_err(&pdev->dev, "Could not get pll_ref clock\n"); in xvcu_probe()
671 return PTR_ERR(xvcu->pll_ref); in xvcu_probe()
674 ret = clk_prepare_enable(xvcu->aclk); in xvcu_probe()
676 dev_err(&pdev->dev, "aclk clock enable failed\n"); in xvcu_probe()
685 xvcu->reset_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", in xvcu_probe()
687 if (IS_ERR(xvcu->reset_gpio)) { in xvcu_probe()
688 ret = PTR_ERR(xvcu->reset_gpio); in xvcu_probe()
689 dev_err_probe(&pdev->dev, ret, "failed to get reset gpio for vcu.\n"); in xvcu_probe()
693 if (xvcu->reset_gpio) { in xvcu_probe()
694 gpiod_set_value(xvcu->reset_gpio, 0); in xvcu_probe()
697 gpiod_set_value(xvcu->reset_gpio, 1); in xvcu_probe()
700 …dev_dbg(&pdev->dev, "No reset gpio info found in dts for VCU. This may result in incorrect functio… in xvcu_probe()
703 regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, VCU_GASKET_VALUE); in xvcu_probe()
707 dev_err(&pdev->dev, "failed to register clock provider\n"); in xvcu_probe()
711 dev_set_drvdata(&pdev->dev, xvcu); in xvcu_probe()
718 clk_disable_unprepare(xvcu->aclk); in xvcu_probe()
723 * xvcu_remove - Insert gasket isolation
739 if (xvcu->reset_gpio) { in xvcu_remove()
740 gpiod_set_value(xvcu->reset_gpio, 0); in xvcu_remove()
743 gpiod_set_value(xvcu->reset_gpio, 1); in xvcu_remove()
746 regmap_write(xvcu->logicore_reg_ba, VCU_GASKET_INIT, 0); in xvcu_remove()
748 clk_disable_unprepare(xvcu->aclk); in xvcu_remove()
753 { .compatible = "xlnx,vcu-logicoreip-1.0" },
760 .name = "xilinx-vcu",