Lines Matching +full:imx8 +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0+
6 #include <dt-bindings/clock/imx8-clock.h>
7 #include <linux/clk-provider.h>
22 * struct clk_imx_acm_pm_domains - structure for multi power domain
34 * struct clk_imx8_acm_sel - for clock mux
35 * @name: clock name
36 * @clkid: clock id
37 * @parents: clock parents
38 * @num_parents: clock parents number
54 * struct imx8_acm_soc_data - soc specific data
66 * struct imx8_acm_priv - private structure
129 { .index = -1 },
176 { .index = -1 },
177 { .index = -1 },
179 { .index = -1 },
180 { .index = -1 },
212 { .index = -1 },
213 { .index = -1 },
214 { .index = -1 },
215 { .index = -1 },
228 { .index = -1 },
229 { .index = -1 },
231 { .index = -1 },
232 { .index = -1 },
233 { .index = -1 },
267 dev_pm->num_domains = of_count_phandle_with_args(dev->of_node, "power-domains", in clk_imx_acm_attach_pm_domains()
268 "#power-domain-cells"); in clk_imx_acm_attach_pm_domains()
269 if (dev_pm->num_domains <= 1) in clk_imx_acm_attach_pm_domains()
272 dev_pm->pd_dev = devm_kmalloc_array(dev, dev_pm->num_domains, in clk_imx_acm_attach_pm_domains()
273 sizeof(*dev_pm->pd_dev), in clk_imx_acm_attach_pm_domains()
275 if (!dev_pm->pd_dev) in clk_imx_acm_attach_pm_domains()
276 return -ENOMEM; in clk_imx_acm_attach_pm_domains()
278 dev_pm->pd_dev_link = devm_kmalloc_array(dev, in clk_imx_acm_attach_pm_domains()
279 dev_pm->num_domains, in clk_imx_acm_attach_pm_domains()
280 sizeof(*dev_pm->pd_dev_link), in clk_imx_acm_attach_pm_domains()
282 if (!dev_pm->pd_dev_link) in clk_imx_acm_attach_pm_domains()
283 return -ENOMEM; in clk_imx_acm_attach_pm_domains()
285 for (i = 0; i < dev_pm->num_domains; i++) { in clk_imx_acm_attach_pm_domains()
286 dev_pm->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i); in clk_imx_acm_attach_pm_domains()
287 if (IS_ERR(dev_pm->pd_dev[i])) { in clk_imx_acm_attach_pm_domains()
288 ret = PTR_ERR(dev_pm->pd_dev[i]); in clk_imx_acm_attach_pm_domains()
292 dev_pm->pd_dev_link[i] = device_link_add(dev, in clk_imx_acm_attach_pm_domains()
293 dev_pm->pd_dev[i], in clk_imx_acm_attach_pm_domains()
297 if (!dev_pm->pd_dev_link[i]) { in clk_imx_acm_attach_pm_domains()
298 dev_pm_domain_detach(dev_pm->pd_dev[i], false); in clk_imx_acm_attach_pm_domains()
299 ret = -EINVAL; in clk_imx_acm_attach_pm_domains()
306 while (--i >= 0) { in clk_imx_acm_attach_pm_domains()
307 device_link_del(dev_pm->pd_dev_link[i]); in clk_imx_acm_attach_pm_domains()
308 dev_pm_domain_detach(dev_pm->pd_dev[i], false); in clk_imx_acm_attach_pm_domains()
323 if (dev_pm->num_domains <= 1) in clk_imx_acm_detach_pm_domains()
326 for (i = 0; i < dev_pm->num_domains; i++) { in clk_imx_acm_detach_pm_domains()
327 device_link_del(dev_pm->pd_dev_link[i]); in clk_imx_acm_detach_pm_domains()
328 dev_pm_domain_detach(dev_pm->pd_dev[i], false); in clk_imx_acm_detach_pm_domains()
335 struct device *dev = &pdev->dev; in imx8_acm_clk_probe()
343 base = devm_of_iomap(dev, dev->of_node, 0, NULL); in imx8_acm_clk_probe()
347 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in imx8_acm_clk_probe()
349 return -ENOMEM; in imx8_acm_clk_probe()
351 priv->reg = base; in imx8_acm_clk_probe()
352 priv->soc_data = of_device_get_match_data(dev); in imx8_acm_clk_probe()
355 clk_hw_data = devm_kzalloc(&pdev->dev, struct_size(clk_hw_data, hws, IMX_ADMA_ACM_CLK_END), in imx8_acm_clk_probe()
358 return -ENOMEM; in imx8_acm_clk_probe()
360 clk_hw_data->num = IMX_ADMA_ACM_CLK_END; in imx8_acm_clk_probe()
361 hws = clk_hw_data->hws; in imx8_acm_clk_probe()
363 ret = clk_imx_acm_attach_pm_domains(&pdev->dev, &priv->dev_pm); in imx8_acm_clk_probe()
367 pm_runtime_enable(&pdev->dev); in imx8_acm_clk_probe()
368 pm_runtime_get_sync(&pdev->dev); in imx8_acm_clk_probe()
370 sels = priv->soc_data->sels; in imx8_acm_clk_probe()
371 for (i = 0; i < priv->soc_data->num_sels; i++) { in imx8_acm_clk_probe()
390 priv->soc_data->mclk_sels[ACM_AUD_CLK0_SEL_INDEX].hw = in imx8_acm_clk_probe()
393 priv->soc_data->mclk_sels[ACM_AUD_CLK1_SEL_INDEX].hw = in imx8_acm_clk_probe()
403 pm_runtime_put_sync(&pdev->dev); in imx8_acm_clk_probe()
407 pm_runtime_put_sync(&pdev->dev); in imx8_acm_clk_probe()
408 pm_runtime_disable(&pdev->dev); in imx8_acm_clk_probe()
409 clk_imx_acm_detach_pm_domains(&pdev->dev, &priv->dev_pm); in imx8_acm_clk_probe()
416 struct imx8_acm_priv *priv = dev_get_drvdata(&pdev->dev); in imx8_acm_clk_remove()
418 pm_runtime_disable(&pdev->dev); in imx8_acm_clk_remove()
420 clk_imx_acm_detach_pm_domains(&pdev->dev, &priv->dev_pm); in imx8_acm_clk_remove()
442 { .compatible = "fsl,imx8qm-acm", .data = &imx8qm_acm_data },
443 { .compatible = "fsl,imx8qxp-acm", .data = &imx8qxp_acm_data },
444 { .compatible = "fsl,imx8dxl-acm", .data = &imx8dxl_acm_data },
455 sels = priv->soc_data->sels; in imx8_acm_runtime_suspend()
457 for (i = 0; i < priv->soc_data->num_sels; i++) in imx8_acm_runtime_suspend()
458 priv->regs[i] = readl_relaxed(priv->reg + sels[i].reg); in imx8_acm_runtime_suspend()
469 sels = priv->soc_data->sels; in imx8_acm_runtime_resume()
471 for (i = 0; i < priv->soc_data->num_sels; i++) in imx8_acm_runtime_resume()
472 writel_relaxed(priv->regs[i], priv->reg + sels[i].reg); in imx8_acm_runtime_resume()
486 .name = "imx8-acm",
496 MODULE_DESCRIPTION("Freescale i.MX8 Audio Clock Mux driver");