Lines Matching +full:mt8365 +full:- +full:power
1 // SPDX-License-Identifier: GPL-2.0-only
6 #include <linux/clk-provider.h>
19 #include "mt6735-pm-domains.h"
20 #include "mt6795-pm-domains.h"
21 #include "mt6893-pm-domains.h"
22 #include "mt8167-pm-domains.h"
23 #include "mt8173-pm-domains.h"
24 #include "mt8183-pm-domains.h"
25 #include "mt8186-pm-domains.h"
26 #include "mt8188-pm-domains.h"
27 #include "mt8192-pm-domains.h"
28 #include "mt8195-pm-domains.h"
29 #include "mt8365-pm-domains.h"
68 struct scpsys *scpsys = pd->scpsys; in scpsys_domain_is_on()
71 regmap_read(scpsys->base, pd->data->pwr_sta_offs, &status); in scpsys_domain_is_on()
72 status &= pd->data->sta_mask; in scpsys_domain_is_on()
74 regmap_read(scpsys->base, pd->data->pwr_sta2nd_offs, &status2); in scpsys_domain_is_on()
75 status2 &= pd->data->sta_mask; in scpsys_domain_is_on()
83 u32 pdn_ack = pd->data->sram_pdn_ack_bits; in scpsys_sram_enable()
84 struct scpsys *scpsys = pd->scpsys; in scpsys_sram_enable()
88 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); in scpsys_sram_enable()
91 ret = regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp, in scpsys_sram_enable()
97 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT); in scpsys_sram_enable()
99 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_CLKISO_BIT); in scpsys_sram_enable()
107 u32 pdn_ack = pd->data->sram_pdn_ack_bits; in scpsys_sram_disable()
108 struct scpsys *scpsys = pd->scpsys; in scpsys_sram_disable()
112 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_CLKISO_BIT); in scpsys_sram_disable()
114 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_SRAM_ISOINT_B_BIT); in scpsys_sram_disable()
117 regmap_set_bits(scpsys->base, pd->data->ctl_offs, pd->data->sram_pdn_bits); in scpsys_sram_disable()
120 return regmap_read_poll_timeout(scpsys->base, pd->data->ctl_offs, tmp, in scpsys_sram_disable()
128 if (bpd->flags & BUS_PROT_COMPONENT_SMI) in scpsys_bus_protect_get_regmap()
129 return pd->smi; in scpsys_bus_protect_get_regmap()
131 return pd->infracfg; in scpsys_bus_protect_get_regmap()
137 if (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO) in scpsys_bus_protect_get_sta_regmap()
138 return pd->infracfg_nao; in scpsys_bus_protect_get_sta_regmap()
148 u32 sta_mask = bpd->bus_prot_sta_mask; in scpsys_bus_protect_clear()
152 expected_ack = (bpd->flags & BUS_PROT_STA_COMPONENT_INFRA_NAO ? sta_mask : 0); in scpsys_bus_protect_clear()
154 if (bpd->flags & BUS_PROT_REG_UPDATE) in scpsys_bus_protect_clear()
155 regmap_clear_bits(regmap, bpd->bus_prot_clr, bpd->bus_prot_set_clr_mask); in scpsys_bus_protect_clear()
157 regmap_write(regmap, bpd->bus_prot_clr, bpd->bus_prot_set_clr_mask); in scpsys_bus_protect_clear()
159 if (bpd->flags & BUS_PROT_IGNORE_CLR_ACK) in scpsys_bus_protect_clear()
162 return regmap_read_poll_timeout(sta_regmap, bpd->bus_prot_sta, in scpsys_bus_protect_clear()
172 u32 sta_mask = bpd->bus_prot_sta_mask; in scpsys_bus_protect_set()
175 if (bpd->flags & BUS_PROT_REG_UPDATE) in scpsys_bus_protect_set()
176 regmap_set_bits(regmap, bpd->bus_prot_set, bpd->bus_prot_set_clr_mask); in scpsys_bus_protect_set()
178 regmap_write(regmap, bpd->bus_prot_set, bpd->bus_prot_set_clr_mask); in scpsys_bus_protect_set()
180 return regmap_read_poll_timeout(sta_regmap, bpd->bus_prot_sta, in scpsys_bus_protect_set()
188 const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i]; in scpsys_bus_protect_enable()
191 if (!bpd->bus_prot_set_clr_mask) in scpsys_bus_protect_enable()
194 if (bpd->flags & BUS_PROT_INVERTED) in scpsys_bus_protect_enable()
207 for (int i = SPM_MAX_BUS_PROT_DATA - 1; i >= 0; i--) { in scpsys_bus_protect_disable()
208 const struct scpsys_bus_prot_data *bpd = &pd->data->bp_cfg[i]; in scpsys_bus_protect_disable()
211 if (!bpd->bus_prot_set_clr_mask) in scpsys_bus_protect_disable()
214 if (bpd->flags & BUS_PROT_INVERTED) in scpsys_bus_protect_disable()
238 struct scpsys *scpsys = pd->scpsys; in scpsys_power_on()
242 ret = scpsys_regulator_enable(pd->supply); in scpsys_power_on()
246 ret = clk_bulk_prepare_enable(pd->num_clks, pd->clks); in scpsys_power_on()
250 if (pd->data->ext_buck_iso_offs && MTK_SCPD_CAPS(pd, MTK_SCPD_EXT_BUCK_ISO)) in scpsys_power_on()
251 regmap_clear_bits(scpsys->base, pd->data->ext_buck_iso_offs, in scpsys_power_on()
252 pd->data->ext_buck_iso_mask); in scpsys_power_on()
254 /* subsys power on */ in scpsys_power_on()
255 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); in scpsys_power_on()
256 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); in scpsys_power_on()
264 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); in scpsys_power_on()
265 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); in scpsys_power_on()
266 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); in scpsys_power_on()
274 ret = clk_bulk_prepare_enable(pd->num_subsys_clks, in scpsys_power_on()
275 pd->subsys_clks); in scpsys_power_on()
289 ret = clk_bulk_prepare_enable(pd->num_subsys_clks, in scpsys_power_on()
290 pd->subsys_clks); in scpsys_power_on()
303 clk_bulk_disable_unprepare(pd->num_subsys_clks, in scpsys_power_on()
304 pd->subsys_clks); in scpsys_power_on()
306 clk_bulk_disable_unprepare(pd->num_clks, pd->clks); in scpsys_power_on()
308 scpsys_regulator_disable(pd->supply); in scpsys_power_on()
315 struct scpsys *scpsys = pd->scpsys; in scpsys_power_off()
327 if (pd->data->ext_buck_iso_offs && MTK_SCPD_CAPS(pd, MTK_SCPD_EXT_BUCK_ISO)) in scpsys_power_off()
328 regmap_set_bits(scpsys->base, pd->data->ext_buck_iso_offs, in scpsys_power_off()
329 pd->data->ext_buck_iso_mask); in scpsys_power_off()
331 clk_bulk_disable_unprepare(pd->num_subsys_clks, pd->subsys_clks); in scpsys_power_off()
333 /* subsys power off */ in scpsys_power_off()
334 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_ISO_BIT); in scpsys_power_off()
335 regmap_set_bits(scpsys->base, pd->data->ctl_offs, PWR_CLK_DIS_BIT); in scpsys_power_off()
336 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_RST_B_BIT); in scpsys_power_off()
337 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_2ND_BIT); in scpsys_power_off()
338 regmap_clear_bits(scpsys->base, pd->data->ctl_offs, PWR_ON_BIT); in scpsys_power_off()
346 clk_bulk_disable_unprepare(pd->num_clks, pd->clks); in scpsys_power_off()
348 scpsys_regulator_disable(pd->supply); in scpsys_power_off()
368 dev_err(scpsys->dev, "%pOF: failed to retrieve domain id from reg: %d\n", in scpsys_add_one_domain()
370 return ERR_PTR(-EINVAL); in scpsys_add_one_domain()
373 if (id >= scpsys->soc_data->num_domains) { in scpsys_add_one_domain()
374 dev_err(scpsys->dev, "%pOF: invalid domain id %d\n", node, id); in scpsys_add_one_domain()
375 return ERR_PTR(-EINVAL); in scpsys_add_one_domain()
378 domain_data = &scpsys->soc_data->domains_data[id]; in scpsys_add_one_domain()
379 if (domain_data->sta_mask == 0) { in scpsys_add_one_domain()
380 dev_err(scpsys->dev, "%pOF: undefined domain id %d\n", node, id); in scpsys_add_one_domain()
381 return ERR_PTR(-EINVAL); in scpsys_add_one_domain()
384 pd = devm_kzalloc(scpsys->dev, sizeof(*pd), GFP_KERNEL); in scpsys_add_one_domain()
386 return ERR_PTR(-ENOMEM); in scpsys_add_one_domain()
388 pd->data = domain_data; in scpsys_add_one_domain()
389 pd->scpsys = scpsys; in scpsys_add_one_domain()
392 pd->supply = devm_of_regulator_get_optional(scpsys->dev, node, "domain"); in scpsys_add_one_domain()
393 if (IS_ERR(pd->supply)) in scpsys_add_one_domain()
394 return dev_err_cast_probe(scpsys->dev, pd->supply, in scpsys_add_one_domain()
395 "%pOF: failed to get power supply.\n", in scpsys_add_one_domain()
399 pd->infracfg = syscon_regmap_lookup_by_phandle_optional(node, "mediatek,infracfg"); in scpsys_add_one_domain()
400 if (IS_ERR(pd->infracfg)) in scpsys_add_one_domain()
401 return dev_err_cast_probe(scpsys->dev, pd->infracfg, in scpsys_add_one_domain()
407 pd->smi = device_node_to_regmap(smi_node); in scpsys_add_one_domain()
409 if (IS_ERR(pd->smi)) in scpsys_add_one_domain()
410 return dev_err_cast_probe(scpsys->dev, pd->smi, in scpsys_add_one_domain()
416 pd->infracfg_nao = syscon_regmap_lookup_by_phandle(node, "mediatek,infracfg-nao"); in scpsys_add_one_domain()
417 if (IS_ERR(pd->infracfg_nao)) in scpsys_add_one_domain()
418 return dev_err_cast_probe(scpsys->dev, pd->infracfg_nao, in scpsys_add_one_domain()
419 "%pOF: failed to get infracfg-nao regmap\n", in scpsys_add_one_domain()
422 pd->infracfg_nao = NULL; in scpsys_add_one_domain()
428 of_property_for_each_string(node, "clock-names", prop, clk_name) { in scpsys_add_one_domain()
431 subsys = strchr(clk_name, '-'); in scpsys_add_one_domain()
433 pd->num_subsys_clks++; in scpsys_add_one_domain()
435 pd->num_clks++; in scpsys_add_one_domain()
438 pd->clks = devm_kcalloc(scpsys->dev, pd->num_clks, sizeof(*pd->clks), GFP_KERNEL); in scpsys_add_one_domain()
439 if (!pd->clks) in scpsys_add_one_domain()
440 return ERR_PTR(-ENOMEM); in scpsys_add_one_domain()
442 pd->subsys_clks = devm_kcalloc(scpsys->dev, pd->num_subsys_clks, in scpsys_add_one_domain()
443 sizeof(*pd->subsys_clks), GFP_KERNEL); in scpsys_add_one_domain()
444 if (!pd->subsys_clks) in scpsys_add_one_domain()
445 return ERR_PTR(-ENOMEM); in scpsys_add_one_domain()
449 for (i = 0; i < pd->num_clks; i++) { in scpsys_add_one_domain()
453 dev_err_probe(scpsys->dev, ret, in scpsys_add_one_domain()
458 pd->clks[clk_ind++].clk = clk; in scpsys_add_one_domain()
461 for (i = 0; i < pd->num_subsys_clks; i++) { in scpsys_add_one_domain()
465 dev_err_probe(scpsys->dev, ret, in scpsys_add_one_domain()
471 pd->subsys_clks[i].clk = clk; in scpsys_add_one_domain()
482 dev_warn(scpsys->dev, in scpsys_add_one_domain()
483 "%pOF: A default off power domain has been ON\n", node); in scpsys_add_one_domain()
485 ret = scpsys_power_on(&pd->genpd); in scpsys_add_one_domain()
487 dev_err(scpsys->dev, "%pOF: failed to power on domain: %d\n", node, ret); in scpsys_add_one_domain()
492 pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; in scpsys_add_one_domain()
495 if (scpsys->domains[id]) { in scpsys_add_one_domain()
496 ret = -EINVAL; in scpsys_add_one_domain()
497 dev_err(scpsys->dev, in scpsys_add_one_domain()
498 "power domain with id %d already exists, check your device-tree\n", id); in scpsys_add_one_domain()
502 if (!pd->data->name) in scpsys_add_one_domain()
503 pd->genpd.name = node->name; in scpsys_add_one_domain()
505 pd->genpd.name = pd->data->name; in scpsys_add_one_domain()
507 pd->genpd.power_off = scpsys_power_off; in scpsys_add_one_domain()
508 pd->genpd.power_on = scpsys_power_on; in scpsys_add_one_domain()
511 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; in scpsys_add_one_domain()
514 pm_genpd_init(&pd->genpd, NULL, true); in scpsys_add_one_domain()
516 pm_genpd_init(&pd->genpd, NULL, false); in scpsys_add_one_domain()
518 scpsys->domains[id] = &pd->genpd; in scpsys_add_one_domain()
520 return scpsys->pd_data.domains[id]; in scpsys_add_one_domain()
523 clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); in scpsys_add_one_domain()
525 clk_bulk_put(pd->num_clks, pd->clks); in scpsys_add_one_domain()
540 dev_err(scpsys->dev, "%pOF: failed to get parent domain id\n", child); in scpsys_add_subdomain()
544 if (!scpsys->pd_data.domains[id]) { in scpsys_add_subdomain()
545 ret = -EINVAL; in scpsys_add_subdomain()
546 dev_err(scpsys->dev, "power domain with id %d does not exist\n", id); in scpsys_add_subdomain()
550 parent_pd = scpsys->pd_data.domains[id]; in scpsys_add_subdomain()
555 dev_err_probe(scpsys->dev, ret, "%pOF: failed to get child domain id\n", in scpsys_add_subdomain()
567 dev_err(scpsys->dev, "failed to add %s subdomain to parent %s\n", in scpsys_add_subdomain()
568 child_pd->name, parent_pd->name); in scpsys_add_subdomain()
571 dev_dbg(scpsys->dev, "%s add subdomain: %s\n", parent_pd->name, in scpsys_add_subdomain()
572 child_pd->name); in scpsys_add_subdomain()
591 ret = pm_genpd_remove(&pd->genpd); in scpsys_remove_one_domain()
593 dev_err(pd->scpsys->dev, in scpsys_remove_one_domain()
594 "failed to remove domain '%s' : %d - state may be inconsistent\n", in scpsys_remove_one_domain()
595 pd->genpd.name, ret); in scpsys_remove_one_domain()
597 scpsys_power_off(&pd->genpd); in scpsys_remove_one_domain()
599 clk_bulk_put(pd->num_clks, pd->clks); in scpsys_remove_one_domain()
600 clk_bulk_put(pd->num_subsys_clks, pd->subsys_clks); in scpsys_remove_one_domain()
609 for (i = scpsys->pd_data.num_domains - 1; i >= 0; i--) { in scpsys_domain_cleanup()
610 genpd = scpsys->pd_data.domains[i]; in scpsys_domain_cleanup()
620 .compatible = "mediatek,mt6735-power-controller",
624 .compatible = "mediatek,mt6795-power-controller",
628 .compatible = "mediatek,mt6893-power-controller",
632 .compatible = "mediatek,mt8167-power-controller",
636 .compatible = "mediatek,mt8173-power-controller",
640 .compatible = "mediatek,mt8183-power-controller",
644 .compatible = "mediatek,mt8186-power-controller",
648 .compatible = "mediatek,mt8188-power-controller",
652 .compatible = "mediatek,mt8192-power-controller",
656 .compatible = "mediatek,mt8195-power-controller",
660 .compatible = "mediatek,mt8365-power-controller",
668 struct device *dev = &pdev->dev; in scpsys_probe()
669 struct device_node *np = dev->of_node; in scpsys_probe()
676 soc = of_device_get_match_data(&pdev->dev); in scpsys_probe()
678 dev_err(&pdev->dev, "no power controller data\n"); in scpsys_probe()
679 return -EINVAL; in scpsys_probe()
682 scpsys = devm_kzalloc(dev, struct_size(scpsys, domains, soc->num_domains), GFP_KERNEL); in scpsys_probe()
684 return -ENOMEM; in scpsys_probe()
686 scpsys->dev = dev; in scpsys_probe()
687 scpsys->soc_data = soc; in scpsys_probe()
689 scpsys->pd_data.domains = scpsys->domains; in scpsys_probe()
690 scpsys->pd_data.num_domains = soc->num_domains; in scpsys_probe()
692 parent = dev->parent; in scpsys_probe()
695 return -ENODEV; in scpsys_probe()
698 scpsys->base = syscon_node_to_regmap(parent->of_node); in scpsys_probe()
699 if (IS_ERR(scpsys->base)) { in scpsys_probe()
701 return PTR_ERR(scpsys->base); in scpsys_probe()
704 ret = -ENODEV; in scpsys_probe()
723 dev_dbg(dev, "no power domains present\n"); in scpsys_probe()
727 ret = of_genpd_add_provider_onecell(np, &scpsys->pd_data); in scpsys_probe()
743 .name = "mtk-power-controller",