Lines Matching +full:imx8m +full:- +full:clock

1 // SPDX-License-Identifier: GPL-2.0+
19 #include <dt-bindings/power/imx8mm-power.h>
20 #include <dt-bindings/power/imx8mn-power.h>
21 #include <dt-bindings/power/imx8mp-power.h>
22 #include <dt-bindings/power/imx8mq-power.h>
53 * an if-statement should be used before setting and clearing this
88 const struct imx8m_blk_ctrl_domain_data *data = domain->data; in imx8m_blk_ctrl_power_on()
89 struct imx8m_blk_ctrl *bc = domain->bc; in imx8m_blk_ctrl_power_on()
93 ret = pm_runtime_get_sync(bc->bus_power_dev); in imx8m_blk_ctrl_power_on()
95 pm_runtime_put_noidle(bc->bus_power_dev); in imx8m_blk_ctrl_power_on()
96 dev_err(bc->dev, "failed to power up bus domain\n"); in imx8m_blk_ctrl_power_on()
101 regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); in imx8m_blk_ctrl_power_on()
102 if (data->mipi_phy_rst_mask) in imx8m_blk_ctrl_power_on()
103 regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); in imx8m_blk_ctrl_power_on()
105 /* enable upstream and blk-ctrl clocks to allow reset to propagate */ in imx8m_blk_ctrl_power_on()
106 ret = clk_bulk_prepare_enable(data->num_clks, domain->clks); in imx8m_blk_ctrl_power_on()
108 dev_err(bc->dev, "failed to enable clocks\n"); in imx8m_blk_ctrl_power_on()
111 regmap_set_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); in imx8m_blk_ctrl_power_on()
114 ret = pm_runtime_get_sync(domain->power_dev); in imx8m_blk_ctrl_power_on()
116 dev_err(bc->dev, "failed to power up peripheral domain\n"); in imx8m_blk_ctrl_power_on()
124 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); in imx8m_blk_ctrl_power_on()
125 if (data->mipi_phy_rst_mask) in imx8m_blk_ctrl_power_on()
126 regmap_set_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); in imx8m_blk_ctrl_power_on()
128 ret = icc_bulk_set_bw(domain->num_paths, domain->paths); in imx8m_blk_ctrl_power_on()
130 dev_err(bc->dev, "failed to set icc bw\n"); in imx8m_blk_ctrl_power_on()
133 clk_bulk_disable_unprepare(data->num_clks, domain->clks); in imx8m_blk_ctrl_power_on()
138 clk_bulk_disable_unprepare(data->num_clks, domain->clks); in imx8m_blk_ctrl_power_on()
140 pm_runtime_put(bc->bus_power_dev); in imx8m_blk_ctrl_power_on()
148 const struct imx8m_blk_ctrl_domain_data *data = domain->data; in imx8m_blk_ctrl_power_off()
149 struct imx8m_blk_ctrl *bc = domain->bc; in imx8m_blk_ctrl_power_off()
152 if (data->mipi_phy_rst_mask) in imx8m_blk_ctrl_power_off()
153 regmap_clear_bits(bc->regmap, BLK_MIPI_RESET_DIV, data->mipi_phy_rst_mask); in imx8m_blk_ctrl_power_off()
155 regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, data->rst_mask); in imx8m_blk_ctrl_power_off()
156 regmap_clear_bits(bc->regmap, BLK_CLK_EN, data->clk_mask); in imx8m_blk_ctrl_power_off()
159 pm_runtime_put(domain->power_dev); in imx8m_blk_ctrl_power_off()
162 pm_runtime_put(bc->bus_power_dev); in imx8m_blk_ctrl_power_off()
172 struct device *dev = &pdev->dev; in imx8m_blk_ctrl_probe()
185 return -ENOMEM; in imx8m_blk_ctrl_probe()
187 bc->dev = dev; in imx8m_blk_ctrl_probe()
195 regmap_config.max_register = bc_data->max_reg; in imx8m_blk_ctrl_probe()
196 bc->regmap = devm_regmap_init_mmio(dev, base, &regmap_config); in imx8m_blk_ctrl_probe()
197 if (IS_ERR(bc->regmap)) in imx8m_blk_ctrl_probe()
198 return dev_err_probe(dev, PTR_ERR(bc->regmap), in imx8m_blk_ctrl_probe()
201 bc->domains = devm_kcalloc(dev, bc_data->num_domains, in imx8m_blk_ctrl_probe()
204 if (!bc->domains) in imx8m_blk_ctrl_probe()
205 return -ENOMEM; in imx8m_blk_ctrl_probe()
207 bc->onecell_data.num_domains = bc_data->num_domains; in imx8m_blk_ctrl_probe()
208 bc->onecell_data.domains = in imx8m_blk_ctrl_probe()
209 devm_kcalloc(dev, bc_data->num_domains, in imx8m_blk_ctrl_probe()
211 if (!bc->onecell_data.domains) in imx8m_blk_ctrl_probe()
212 return -ENOMEM; in imx8m_blk_ctrl_probe()
214 bc->bus_power_dev = dev_pm_domain_attach_by_name(dev, "bus"); in imx8m_blk_ctrl_probe()
215 if (IS_ERR(bc->bus_power_dev)) { in imx8m_blk_ctrl_probe()
216 if (PTR_ERR(bc->bus_power_dev) == -ENODEV) in imx8m_blk_ctrl_probe()
217 return dev_err_probe(dev, -EPROBE_DEFER, in imx8m_blk_ctrl_probe()
220 return dev_err_probe(dev, PTR_ERR(bc->bus_power_dev), in imx8m_blk_ctrl_probe()
224 for (i = 0; i < bc_data->num_domains; i++) { in imx8m_blk_ctrl_probe()
225 const struct imx8m_blk_ctrl_domain_data *data = &bc_data->domains[i]; in imx8m_blk_ctrl_probe()
226 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; in imx8m_blk_ctrl_probe()
229 domain->data = data; in imx8m_blk_ctrl_probe()
230 domain->num_paths = data->num_paths; in imx8m_blk_ctrl_probe()
232 for (j = 0; j < data->num_clks; j++) in imx8m_blk_ctrl_probe()
233 domain->clks[j].id = data->clk_names[j]; in imx8m_blk_ctrl_probe()
235 for (j = 0; j < data->num_paths; j++) { in imx8m_blk_ctrl_probe()
236 domain->paths[j].name = data->path_names[j]; in imx8m_blk_ctrl_probe()
238 domain->paths[j].avg_bw = 1; in imx8m_blk_ctrl_probe()
239 domain->paths[j].peak_bw = 1; in imx8m_blk_ctrl_probe()
242 ret = devm_of_icc_bulk_get(dev, data->num_paths, domain->paths); in imx8m_blk_ctrl_probe()
244 if (ret != -EPROBE_DEFER) { in imx8m_blk_ctrl_probe()
246 domain->num_paths = 0; in imx8m_blk_ctrl_probe()
253 ret = devm_clk_bulk_get(dev, data->num_clks, domain->clks); in imx8m_blk_ctrl_probe()
255 dev_err_probe(dev, ret, "failed to get clock\n"); in imx8m_blk_ctrl_probe()
259 domain->power_dev = in imx8m_blk_ctrl_probe()
260 dev_pm_domain_attach_by_name(dev, data->gpc_name); in imx8m_blk_ctrl_probe()
261 if (IS_ERR_OR_NULL(domain->power_dev)) { in imx8m_blk_ctrl_probe()
262 if (!domain->power_dev) in imx8m_blk_ctrl_probe()
263 ret = -ENODEV; in imx8m_blk_ctrl_probe()
265 ret = PTR_ERR(domain->power_dev); in imx8m_blk_ctrl_probe()
268 data->gpc_name); in imx8m_blk_ctrl_probe()
272 domain->genpd.name = data->name; in imx8m_blk_ctrl_probe()
273 domain->genpd.power_on = imx8m_blk_ctrl_power_on; in imx8m_blk_ctrl_probe()
274 domain->genpd.power_off = imx8m_blk_ctrl_power_off; in imx8m_blk_ctrl_probe()
275 domain->bc = bc; in imx8m_blk_ctrl_probe()
277 ret = pm_genpd_init(&domain->genpd, NULL, true); in imx8m_blk_ctrl_probe()
281 data->gpc_name); in imx8m_blk_ctrl_probe()
282 dev_pm_domain_detach(domain->power_dev, true); in imx8m_blk_ctrl_probe()
294 * self-deadlock. in imx8m_blk_ctrl_probe()
296 lockdep_set_class(&domain->genpd.mlock, in imx8m_blk_ctrl_probe()
299 bc->onecell_data.domains[i] = &domain->genpd; in imx8m_blk_ctrl_probe()
302 ret = of_genpd_add_provider_onecell(dev->of_node, &bc->onecell_data); in imx8m_blk_ctrl_probe()
308 bc->power_nb.notifier_call = bc_data->power_notifier_fn; in imx8m_blk_ctrl_probe()
309 ret = dev_pm_genpd_add_notifier(bc->bus_power_dev, &bc->power_nb); in imx8m_blk_ctrl_probe()
324 of_genpd_del_provider(dev->of_node); in imx8m_blk_ctrl_probe()
326 for (i--; i >= 0; i--) { in imx8m_blk_ctrl_probe()
327 pm_genpd_remove(&bc->domains[i].genpd); in imx8m_blk_ctrl_probe()
328 dev_pm_domain_detach(bc->domains[i].power_dev, true); in imx8m_blk_ctrl_probe()
331 dev_pm_domain_detach(bc->bus_power_dev, true); in imx8m_blk_ctrl_probe()
338 struct imx8m_blk_ctrl *bc = dev_get_drvdata(&pdev->dev); in imx8m_blk_ctrl_remove()
341 of_genpd_del_provider(pdev->dev.of_node); in imx8m_blk_ctrl_remove()
343 for (i = 0; bc->onecell_data.num_domains; i++) { in imx8m_blk_ctrl_remove()
344 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; in imx8m_blk_ctrl_remove()
346 pm_genpd_remove(&domain->genpd); in imx8m_blk_ctrl_remove()
347 dev_pm_domain_detach(domain->power_dev, true); in imx8m_blk_ctrl_remove()
350 dev_pm_genpd_remove_notifier(bc->bus_power_dev); in imx8m_blk_ctrl_remove()
352 dev_pm_domain_detach(bc->bus_power_dev, true); in imx8m_blk_ctrl_remove()
369 ret = pm_runtime_get_sync(bc->bus_power_dev); in imx8m_blk_ctrl_suspend()
371 pm_runtime_put_noidle(bc->bus_power_dev); in imx8m_blk_ctrl_suspend()
375 for (i = 0; i < bc->onecell_data.num_domains; i++) { in imx8m_blk_ctrl_suspend()
376 struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; in imx8m_blk_ctrl_suspend()
378 ret = pm_runtime_get_sync(domain->power_dev); in imx8m_blk_ctrl_suspend()
380 pm_runtime_put_noidle(domain->power_dev); in imx8m_blk_ctrl_suspend()
388 for (i--; i >= 0; i--) in imx8m_blk_ctrl_suspend()
389 pm_runtime_put(bc->domains[i].power_dev); in imx8m_blk_ctrl_suspend()
391 pm_runtime_put(bc->bus_power_dev); in imx8m_blk_ctrl_suspend()
401 for (i = 0; i < bc->onecell_data.num_domains; i++) in imx8m_blk_ctrl_resume()
402 pm_runtime_put(bc->domains[i].power_dev); in imx8m_blk_ctrl_resume()
404 pm_runtime_put(bc->bus_power_dev); in imx8m_blk_ctrl_resume()
424 * The ADB in the VPUMIX domain has no separate reset and clock in imx8mm_vpu_power_notifier()
429 regmap_clear_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1) | BIT(2)); in imx8mm_vpu_power_notifier()
430 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1) | BIT(2)); in imx8mm_vpu_power_notifier()
441 regmap_set_bits(bc->regmap, 0x8, 0xffffffff); in imx8mm_vpu_power_notifier()
442 regmap_set_bits(bc->regmap, 0xc, 0xffffffff); in imx8mm_vpu_power_notifier()
443 regmap_set_bits(bc->regmap, 0x10, 0xffffffff); in imx8mm_vpu_power_notifier()
444 regmap_set_bits(bc->regmap, 0x14, 0xffffffff); in imx8mm_vpu_power_notifier()
452 .name = "vpublk-g1",
460 .name = "vpublk-g2",
468 .name = "vpublk-h1",
486 .name = "vpublk-g1",
496 .name = "vpublk-g2",
506 .name = "vpublk-vc8000e",
533 /* Enable bus clock and deassert bus reset */ in imx8mm_disp_power_notifier()
534 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(12)); in imx8mm_disp_power_notifier()
535 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(6)); in imx8mm_disp_power_notifier()
551 .name = "dispblk-csi-bridge",
552 .clk_names = (const char *[]){ "csi-bridge-axi", "csi-bridge-apb",
553 "csi-bridge-core", },
555 .gpc_name = "csi-bridge",
560 .name = "dispblk-lcdif",
561 .clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
567 .name = "dispblk-mipi-dsi",
568 .clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
570 .gpc_name = "mipi-dsi",
576 .name = "dispblk-mipi-csi",
577 .clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
579 .gpc_name = "mipi-csi",
603 /* Enable bus clock and deassert bus reset */ in imx8mn_disp_power_notifier()
604 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8)); in imx8mn_disp_power_notifier()
605 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8)); in imx8mn_disp_power_notifier()
621 .name = "dispblk-mipi-dsi",
622 .clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", },
624 .gpc_name = "mipi-dsi",
630 .name = "dispblk-mipi-csi",
631 .clk_names = (const char *[]){ "csi-aclk", "csi-pclk" },
633 .gpc_name = "mipi-csi",
639 .name = "dispblk-lcdif",
640 .clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", },
647 .name = "dispblk-isi",
677 /* Enable bus clock and deassert bus reset */ in imx8mp_media_power_notifier()
678 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8)); in imx8mp_media_power_notifier()
679 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8)); in imx8mp_media_power_notifier()
694 regmap_set_bits(bc->regmap, LCDIF_ARCACHE_CTRL, in imx8mp_media_power_notifier()
705 * isp-ahb and dwe are not in Figure 13-5. Media BLK_CTRL Clocks
709 .name = "mediablk-mipi-dsi-1",
712 .gpc_name = "mipi-dsi1",
718 .name = "mediablk-mipi-csi2-1",
721 .gpc_name = "mipi-csi1",
727 .name = "mediablk-lcdif-1",
733 .path_names = (const char *[]){"lcdif-rd", "lcdif-wr"},
737 .name = "mediablk-isi",
747 .name = "mediablk-mipi-csi2-2",
750 .gpc_name = "mipi-csi2",
756 .name = "mediablk-lcdif-2",
762 .path_names = (const char *[]){"lcdif-rd", "lcdif-wr"},
766 .name = "mediablk-isp",
776 .name = "mediablk-dwe",
786 .name = "mediablk-mipi-dsi-2",
789 .gpc_name = "mipi-dsi2",
813 * The ADB in the VPUMIX domain has no separate reset and clock in imx8mq_vpu_power_notifier()
815 * reset and clock enable inputs to the ADB is a logical OR of the in imx8mq_vpu_power_notifier()
816 * VPU bits. In order to set the G2 fuse bits, the G2 clock must in imx8mq_vpu_power_notifier()
819 regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(0) | BIT(1)); in imx8mq_vpu_power_notifier()
820 regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(0) | BIT(1)); in imx8mq_vpu_power_notifier()
831 regmap_set_bits(bc->regmap, 0x8, 0xffffffff); in imx8mq_vpu_power_notifier()
832 regmap_set_bits(bc->regmap, 0xc, 0xffffffff); in imx8mq_vpu_power_notifier()
833 regmap_set_bits(bc->regmap, 0x10, 0xffffffff); in imx8mq_vpu_power_notifier()
841 .name = "vpublk-g1",
849 .name = "vpublk-g2",
867 .compatible = "fsl,imx8mm-vpu-blk-ctrl",
870 .compatible = "fsl,imx8mm-disp-blk-ctrl",
873 .compatible = "fsl,imx8mn-disp-blk-ctrl",
876 .compatible = "fsl,imx8mp-media-blk-ctrl",
879 .compatible = "fsl,imx8mq-vpu-blk-ctrl",
882 .compatible = "fsl,imx8mp-vpu-blk-ctrl",
894 .name = "imx8m-blk-ctrl",