Lines Matching +full:imx8qxp +full:- +full:lpcg
1 // SPDX-License-Identifier: GPL-2.0+
7 #include <linux/clk-provider.h>
16 #include "clk-scu.h"
17 #include "clk-imx8qxp-lpcg.h"
19 #include <dt-bindings/clock/imx8-clock.h>
22 * struct imx8qxp_lpcg_data - Description of one LPCG clock
27 * @offset: offset of this LPCG clock
28 * @bit_idx: bit index of this LPCG clock
31 * This structure describes one LPCG clock
44 * struct imx8qxp_ss_lpcg - Description of one subsystem LPCG clocks
45 * @lpcg: LPCG clocks array of one subsystem
46 * @num_lpcg: the number of LPCG clocks
47 * @num_max: the maximum number of LPCG clocks
49 * This structure describes each subsystem LPCG clocks information
53 const struct imx8qxp_lpcg_data *lpcg;
83 .lpcg = imx8qxp_lpcg_adma,
111 .lpcg = imx8qxp_lpcg_conn,
155 .lpcg = imx8qxp_lpcg_lsio,
166 unsigned int idx = clkspec->args[0] / 4;
168 if (idx >= hw_data->num) {
170 return ERR_PTR(-EINVAL);
173 return hw_data->hws[idx];
190 if (!of_device_is_compatible(np, "fsl,imx8qxp-lpcg"))
191 return -EINVAL;
197 count = of_property_count_u32_elems(np, "clock-indices");
199 dev_err(&pdev->dev, "failed to count clocks\n");
200 return -EINVAL;
205 * of the count from clock-indices because one LPCG supports up to
207 * easily get the clock by clk-indices (bit-offset) / 4.
211 clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws,
214 return -ENOMEM;
216 clk_data->num = IMX_LPCG_MAX_CLKS;
217 clk_hws = clk_data->hws;
219 ret = of_property_read_u32_array(np, "clock-indices", bit_offset,
222 dev_err(&pdev->dev, "failed to read clock-indices\n");
223 return -EINVAL;
228 dev_err(&pdev->dev, "failed to get clock parent names\n");
232 ret = of_property_read_string_array(np, "clock-output-names",
235 dev_err(&pdev->dev, "failed to read clock-output-names\n");
236 return -EINVAL;
239 pm_runtime_get_noresume(&pdev->dev);
240 pm_runtime_set_active(&pdev->dev);
241 pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
242 pm_runtime_use_autosuspend(&pdev->dev);
243 pm_runtime_enable(&pdev->dev);
248 dev_warn(&pdev->dev, "invalid bit offset of clock %d\n",
250 ret = -EINVAL;
254 clk_hws[idx] = imx_clk_lpcg_scu_dev(&pdev->dev, output_names[i],
258 dev_warn(&pdev->dev, "failed to register clock %d\n",
265 ret = devm_of_clk_add_hw_provider(&pdev->dev, imx_lpcg_of_clk_src_get,
270 pm_runtime_put_autosuspend(&pdev->dev);
275 while (--i >= 0) {
281 pm_runtime_disable(&pdev->dev);
288 struct device *dev = &pdev->dev;
289 struct device_node *np = dev->of_node;
292 const struct imx8qxp_lpcg_data *lpcg;
306 return -ENODEV;
315 * On imx8 the LPCG nodes map entire subsystems and overlap
321 return -EINVAL;
322 base = devm_ioremap(dev, res->start, resource_size(res));
324 return -ENOMEM;
326 clk_data = devm_kzalloc(&pdev->dev, struct_size(clk_data, hws,
327 ss_lpcg->num_max), GFP_KERNEL);
329 return -ENOMEM;
331 clk_data->num = ss_lpcg->num_max;
332 clks = clk_data->hws;
334 for (i = 0; i < ss_lpcg->num_lpcg; i++) {
335 lpcg = ss_lpcg->lpcg + i;
336 clks[lpcg->id] = imx_clk_lpcg_scu(lpcg->name, lpcg->parent,
337 lpcg->flags, base + lpcg->offset,
338 lpcg->bit_idx, lpcg->hw_gate);
341 for (i = 0; i < clk_data->num; i++) {
351 { .compatible = "fsl,imx8qxp-lpcg-adma", &imx8qxp_ss_adma, },
352 { .compatible = "fsl,imx8qxp-lpcg-conn", &imx8qxp_ss_conn, },
353 { .compatible = "fsl,imx8qxp-lpcg-lsio", &imx8qxp_ss_lsio, },
354 { .compatible = "fsl,imx8qxp-lpcg", NULL },
360 .name = "imx8qxp-lpcg-clk",
371 MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver");