Lines Matching +full:power +full:- +full:domain
1 // SPDX-License-Identifier: GPL-2.0+
8 * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
20 #include <dt-bindings/power/imx7-power.h>
21 #include <dt-bindings/power/imx8mq-power.h>
22 #include <dt-bindings/power/imx8mm-power.h>
23 #include <dt-bindings/power/imx8mn-power.h>
222 struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd); in imx_pgc_power_up() local
226 ret = pm_runtime_get_sync(domain->dev); in imx_pgc_power_up()
228 pm_runtime_put_noidle(domain->dev); in imx_pgc_power_up()
232 if (!IS_ERR(domain->regulator)) { in imx_pgc_power_up()
233 ret = regulator_enable(domain->regulator); in imx_pgc_power_up()
235 dev_err(domain->dev, "failed to enable regulator\n"); in imx_pgc_power_up()
240 /* Enable reset clocks for all devices in the domain */ in imx_pgc_power_up()
241 ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks); in imx_pgc_power_up()
243 dev_err(domain->dev, "failed to enable reset clocks\n"); in imx_pgc_power_up()
247 if (domain->bits.pxx) { in imx_pgc_power_up()
248 /* request the domain to power up */ in imx_pgc_power_up()
249 regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, in imx_pgc_power_up()
250 domain->bits.pxx, domain->bits.pxx); in imx_pgc_power_up()
255 ret = regmap_read_poll_timeout(domain->regmap, in imx_pgc_power_up()
257 !(reg_val & domain->bits.pxx), in imx_pgc_power_up()
260 dev_err(domain->dev, "failed to command PGC\n"); in imx_pgc_power_up()
264 /* disable power control */ in imx_pgc_power_up()
265 regmap_clear_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), in imx_pgc_power_up()
269 reset_control_assert(domain->reset); in imx_pgc_power_up()
274 reset_control_deassert(domain->reset); in imx_pgc_power_up()
276 /* request the ADB400 to power up */ in imx_pgc_power_up()
277 if (domain->bits.hskreq) { in imx_pgc_power_up()
278 regmap_update_bits(domain->regmap, GPC_PU_PWRHSK, in imx_pgc_power_up()
279 domain->bits.hskreq, domain->bits.hskreq); in imx_pgc_power_up()
282 * ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK, reg_val, in imx_pgc_power_up()
283 * (reg_val & domain->bits.hskack), 0, in imx_pgc_power_up()
286 * the BLK-CTL module BUS clk-en bit being set. in imx_pgc_power_up()
288 * There is a separate BLK-CTL module and we will have such a driver for it, in imx_pgc_power_up()
289 * that driver will set the BUS clk-en bit and handshake will be triggered in imx_pgc_power_up()
295 /* Disable reset clocks for all devices in the domain */ in imx_pgc_power_up()
296 clk_bulk_disable_unprepare(domain->num_clks, domain->clks); in imx_pgc_power_up()
301 clk_bulk_disable_unprepare(domain->num_clks, domain->clks); in imx_pgc_power_up()
303 if (!IS_ERR(domain->regulator)) in imx_pgc_power_up()
304 regulator_disable(domain->regulator); in imx_pgc_power_up()
306 pm_runtime_put(domain->dev); in imx_pgc_power_up()
313 struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd); in imx_pgc_power_down() local
317 /* Enable reset clocks for all devices in the domain */ in imx_pgc_power_down()
318 ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks); in imx_pgc_power_down()
320 dev_err(domain->dev, "failed to enable reset clocks\n"); in imx_pgc_power_down()
324 /* request the ADB400 to power down */ in imx_pgc_power_down()
325 if (domain->bits.hskreq) { in imx_pgc_power_down()
326 regmap_clear_bits(domain->regmap, GPC_PU_PWRHSK, in imx_pgc_power_down()
327 domain->bits.hskreq); in imx_pgc_power_down()
329 ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK, in imx_pgc_power_down()
331 !(reg_val & domain->bits.hskack), in imx_pgc_power_down()
334 dev_err(domain->dev, "failed to power down ADB400\n"); in imx_pgc_power_down()
339 if (domain->bits.pxx) { in imx_pgc_power_down()
340 /* enable power control */ in imx_pgc_power_down()
341 regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc), in imx_pgc_power_down()
344 /* request the domain to power down */ in imx_pgc_power_down()
345 regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, in imx_pgc_power_down()
346 domain->bits.pxx, domain->bits.pxx); in imx_pgc_power_down()
351 ret = regmap_read_poll_timeout(domain->regmap, in imx_pgc_power_down()
353 !(reg_val & domain->bits.pxx), in imx_pgc_power_down()
356 dev_err(domain->dev, "failed to command PGC\n"); in imx_pgc_power_down()
361 /* Disable reset clocks for all devices in the domain */ in imx_pgc_power_down()
362 clk_bulk_disable_unprepare(domain->num_clks, domain->clks); in imx_pgc_power_down()
364 if (!IS_ERR(domain->regulator)) { in imx_pgc_power_down()
365 ret = regulator_disable(domain->regulator); in imx_pgc_power_down()
367 dev_err(domain->dev, "failed to disable regulator\n"); in imx_pgc_power_down()
372 pm_runtime_put(domain->dev); in imx_pgc_power_down()
377 clk_bulk_disable_unprepare(domain->num_clks, domain->clks); in imx_pgc_power_down()
385 .name = "mipi-phy",
397 .name = "pcie-phy",
409 .name = "usb-hsic-phy",
467 .name = "usb-otg1",
478 .name = "usb-otg2",
539 .name = "mipi-csi1",
550 .name = "mipi-csi2",
615 .pxx = 0, /* no power sequence control */
616 .map = 0, /* no power sequence control */
635 .name = "usb-otg1",
646 .name = "usb-otg2",
696 .name = "vpu-g1",
707 .name = "vpu-g2",
718 .name = "vpu-h1",
800 .pxx = 0, /* no power sequence control */
801 .map = 0, /* no power sequence control */
809 .name = "usb-otg1",
860 struct imx_pgc_domain *domain = pdev->dev.platform_data; in imx_pgc_domain_probe() local
863 domain->dev = &pdev->dev; in imx_pgc_domain_probe()
865 domain->regulator = devm_regulator_get_optional(domain->dev, "power"); in imx_pgc_domain_probe()
866 if (IS_ERR(domain->regulator)) { in imx_pgc_domain_probe()
867 if (PTR_ERR(domain->regulator) != -ENODEV) in imx_pgc_domain_probe()
868 return dev_err_probe(domain->dev, PTR_ERR(domain->regulator), in imx_pgc_domain_probe()
869 "Failed to get domain's regulator\n"); in imx_pgc_domain_probe()
870 } else if (domain->voltage) { in imx_pgc_domain_probe()
871 regulator_set_voltage(domain->regulator, in imx_pgc_domain_probe()
872 domain->voltage, domain->voltage); in imx_pgc_domain_probe()
875 domain->num_clks = devm_clk_bulk_get_all(domain->dev, &domain->clks); in imx_pgc_domain_probe()
876 if (domain->num_clks < 0) in imx_pgc_domain_probe()
877 return dev_err_probe(domain->dev, domain->num_clks, in imx_pgc_domain_probe()
878 "Failed to get domain's clocks\n"); in imx_pgc_domain_probe()
880 domain->reset = devm_reset_control_array_get_optional_exclusive(domain->dev); in imx_pgc_domain_probe()
881 if (IS_ERR(domain->reset)) in imx_pgc_domain_probe()
882 return dev_err_probe(domain->dev, PTR_ERR(domain->reset), in imx_pgc_domain_probe()
883 "Failed to get domain's resets\n"); in imx_pgc_domain_probe()
885 pm_runtime_enable(domain->dev); in imx_pgc_domain_probe()
887 if (domain->bits.map) in imx_pgc_domain_probe()
888 regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, in imx_pgc_domain_probe()
889 domain->bits.map, domain->bits.map); in imx_pgc_domain_probe()
891 ret = pm_genpd_init(&domain->genpd, NULL, true); in imx_pgc_domain_probe()
893 dev_err(domain->dev, "Failed to init power domain\n"); in imx_pgc_domain_probe()
897 ret = of_genpd_add_provider_simple(domain->dev->of_node, in imx_pgc_domain_probe()
898 &domain->genpd); in imx_pgc_domain_probe()
900 dev_err(domain->dev, "Failed to add genpd provider\n"); in imx_pgc_domain_probe()
907 pm_genpd_remove(&domain->genpd); in imx_pgc_domain_probe()
909 if (domain->bits.map) in imx_pgc_domain_probe()
910 regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, in imx_pgc_domain_probe()
911 domain->bits.map, 0); in imx_pgc_domain_probe()
912 pm_runtime_disable(domain->dev); in imx_pgc_domain_probe()
919 struct imx_pgc_domain *domain = pdev->dev.platform_data; in imx_pgc_domain_remove() local
921 of_genpd_del_provider(domain->dev->of_node); in imx_pgc_domain_remove()
922 pm_genpd_remove(&domain->genpd); in imx_pgc_domain_remove()
924 if (domain->bits.map) in imx_pgc_domain_remove()
925 regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, in imx_pgc_domain_remove()
926 domain->bits.map, 0); in imx_pgc_domain_remove()
928 pm_runtime_disable(domain->dev); in imx_pgc_domain_remove()
934 { "imx-pgc-domain", },
940 .name = "imx-pgc",
951 of_device_get_match_data(&pdev->dev); in builtin_platform_driver()
957 .rd_table = domain_data->reg_access_table, in builtin_platform_driver()
958 .wr_table = domain_data->reg_access_table, in builtin_platform_driver()
961 struct device *dev = &pdev->dev; in builtin_platform_driver()
967 pgc_np = of_get_child_by_name(dev->of_node, "pgc"); in builtin_platform_driver()
969 dev_err(dev, "No power domains specified in DT\n"); in builtin_platform_driver()
970 return -EINVAL; in builtin_platform_driver()
986 struct imx_pgc_domain *domain; in builtin_platform_driver() local
996 if (domain_index >= domain_data->domains_num) { in builtin_platform_driver()
998 "Domain index %d is out of bounds\n", in builtin_platform_driver()
1003 pd_pdev = platform_device_alloc("imx-pgc-domain", in builtin_platform_driver()
1008 return -ENOMEM; in builtin_platform_driver()
1012 &domain_data->domains[domain_index], in builtin_platform_driver()
1013 sizeof(domain_data->domains[domain_index])); in builtin_platform_driver()
1020 domain = pd_pdev->dev.platform_data; in builtin_platform_driver()
1021 domain->regmap = regmap; in builtin_platform_driver()
1022 domain->genpd.power_on = imx_pgc_power_up; in builtin_platform_driver()
1023 domain->genpd.power_off = imx_pgc_power_down; in builtin_platform_driver()
1025 pd_pdev->dev.parent = dev; in builtin_platform_driver()
1026 pd_pdev->dev.of_node = np; in builtin_platform_driver()
1040 { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
1041 { .compatible = "fsl,imx8mm-gpc", .data = &imx8mm_pgc_domain_data, },
1042 { .compatible = "fsl,imx8mn-gpc", .data = &imx8mn_pgc_domain_data, },
1043 { .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
1049 .name = "imx-gpcv2",