Lines Matching +full:bus +full:- +full:dmc
1 // SPDX-License-Identifier: GPL-2.0-only
23 #include <dt-bindings/power/px30-power.h>
24 #include <dt-bindings/power/rockchip,rv1126-power.h>
25 #include <dt-bindings/power/rk3036-power.h>
26 #include <dt-bindings/power/rk3066-power.h>
27 #include <dt-bindings/power/rk3128-power.h>
28 #include <dt-bindings/power/rk3188-power.h>
29 #include <dt-bindings/power/rk3228-power.h>
30 #include <dt-bindings/power/rk3288-power.h>
31 #include <dt-bindings/power/rk3328-power.h>
32 #include <dt-bindings/power/rk3366-power.h>
33 #include <dt-bindings/power/rk3368-power.h>
34 #include <dt-bindings/power/rk3399-power.h>
35 #include <dt-bindings/power/rk3568-power.h>
36 #include <dt-bindings/power/rockchip,rk3576-power.h>
37 #include <dt-bindings/power/rk3588-power.h>
204 * Dynamic Memory Controller may need to coordinate with us -- see
207 * dmc_pmu_mutex protects registration-time races, so DMC driver doesn't try to
238 mutex_lock(&pmu->mutex); in rockchip_pmu_block()
242 * enabled for the duration of power-domain transitions. Most in rockchip_pmu_block()
244 * particular, DRAM DVFS / memory-controller idle) must be handled by in rockchip_pmu_block()
250 for (i = 0; i < pmu->genpd_data.num_domains; i++) { in rockchip_pmu_block()
251 genpd = pmu->genpd_data.domains[i]; in rockchip_pmu_block()
254 ret = clk_bulk_enable(pd->num_clks, pd->clks); in rockchip_pmu_block()
256 dev_err(pmu->dev, in rockchip_pmu_block()
258 genpd->name, ret); in rockchip_pmu_block()
267 for (i = i - 1; i >= 0; i--) { in rockchip_pmu_block()
268 genpd = pmu->genpd_data.domains[i]; in rockchip_pmu_block()
271 clk_bulk_disable(pd->num_clks, pd->clks); in rockchip_pmu_block()
274 mutex_unlock(&pmu->mutex); in rockchip_pmu_block()
291 for (i = 0; i < pmu->genpd_data.num_domains; i++) { in rockchip_pmu_unblock()
292 genpd = pmu->genpd_data.domains[i]; in rockchip_pmu_unblock()
295 clk_bulk_disable(pd->num_clks, pd->clks); in rockchip_pmu_unblock()
299 mutex_unlock(&pmu->mutex); in rockchip_pmu_unblock()
311 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_is_idle()
312 const struct rockchip_domain_info *pd_info = pd->info; in rockchip_pmu_domain_is_idle()
315 regmap_read(pmu->regmap, pmu->info->idle_offset, &val); in rockchip_pmu_domain_is_idle()
316 return (val & pd_info->idle_mask) == pd_info->idle_mask; in rockchip_pmu_domain_is_idle()
323 regmap_read(pmu->regmap, pmu->info->ack_offset, &val); in rockchip_pmu_read_ack()
329 const struct rockchip_domain_info *pd_info = pd->info; in rockchip_pmu_ungate_clk()
330 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_ungate_clk()
332 int clk_ungate_w_mask = pd_info->clk_ungate_mask << 16; in rockchip_pmu_ungate_clk()
334 if (!pd_info->clk_ungate_mask) in rockchip_pmu_ungate_clk()
337 if (!pmu->info->clk_ungate_offset) in rockchip_pmu_ungate_clk()
340 val = ungate ? (pd_info->clk_ungate_mask | clk_ungate_w_mask) : in rockchip_pmu_ungate_clk()
342 regmap_write(pmu->regmap, pmu->info->clk_ungate_offset, val); in rockchip_pmu_ungate_clk()
350 const struct rockchip_domain_info *pd_info = pd->info; in rockchip_pmu_set_idle_request()
351 struct generic_pm_domain *genpd = &pd->genpd; in rockchip_pmu_set_idle_request()
352 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_set_idle_request()
353 u32 pd_req_offset = pd_info->req_offset; in rockchip_pmu_set_idle_request()
359 if (pd_info->req_mask == 0) in rockchip_pmu_set_idle_request()
361 else if (pd_info->req_w_mask) in rockchip_pmu_set_idle_request()
362 regmap_write(pmu->regmap, pmu->info->req_offset + pd_req_offset, in rockchip_pmu_set_idle_request()
363 idle ? (pd_info->req_mask | pd_info->req_w_mask) : in rockchip_pmu_set_idle_request()
364 pd_info->req_w_mask); in rockchip_pmu_set_idle_request()
366 regmap_update_bits(pmu->regmap, pmu->info->req_offset + pd_req_offset, in rockchip_pmu_set_idle_request()
367 pd_info->req_mask, idle ? -1U : 0); in rockchip_pmu_set_idle_request()
372 target_ack = idle ? pd_info->ack_mask : 0; in rockchip_pmu_set_idle_request()
374 (val & pd_info->ack_mask) == target_ack, in rockchip_pmu_set_idle_request()
377 dev_err(pmu->dev, in rockchip_pmu_set_idle_request()
379 genpd->name, val); in rockchip_pmu_set_idle_request()
386 dev_err(pmu->dev, in rockchip_pmu_set_idle_request()
388 genpd->name, is_idle); in rockchip_pmu_set_idle_request()
399 for (i = 0; i < pd->num_qos; i++) { in rockchip_pmu_save_qos()
400 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
402 &pd->qos_save_regs[0][i]); in rockchip_pmu_save_qos()
403 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
405 &pd->qos_save_regs[1][i]); in rockchip_pmu_save_qos()
406 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
408 &pd->qos_save_regs[2][i]); in rockchip_pmu_save_qos()
409 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
411 &pd->qos_save_regs[3][i]); in rockchip_pmu_save_qos()
412 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
414 &pd->qos_save_regs[4][i]); in rockchip_pmu_save_qos()
423 for (i = 0; i < pd->num_qos; i++) { in rockchip_pmu_restore_qos()
424 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
426 pd->qos_save_regs[0][i]); in rockchip_pmu_restore_qos()
427 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
429 pd->qos_save_regs[1][i]); in rockchip_pmu_restore_qos()
430 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
432 pd->qos_save_regs[2][i]); in rockchip_pmu_restore_qos()
433 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
435 pd->qos_save_regs[3][i]); in rockchip_pmu_restore_qos()
436 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
438 pd->qos_save_regs[4][i]); in rockchip_pmu_restore_qos()
446 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_is_on()
449 if (pd->info->repair_status_mask) { in rockchip_pmu_domain_is_on()
450 regmap_read(pmu->regmap, pmu->info->repair_status_offset, &val); in rockchip_pmu_domain_is_on()
452 return val & pd->info->repair_status_mask; in rockchip_pmu_domain_is_on()
455 /* check idle status for idle-only domains */ in rockchip_pmu_domain_is_on()
456 if (pd->info->status_mask == 0) in rockchip_pmu_domain_is_on()
459 regmap_read(pmu->regmap, pmu->info->status_offset, &val); in rockchip_pmu_domain_is_on()
462 return !(val & pd->info->status_mask); in rockchip_pmu_domain_is_on()
467 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_is_mem_on()
470 regmap_read(pmu->regmap, in rockchip_pmu_domain_is_mem_on()
471 pmu->info->mem_status_offset + pd->info->mem_offset, &val); in rockchip_pmu_domain_is_mem_on()
474 return !(val & pd->info->mem_status_mask); in rockchip_pmu_domain_is_mem_on()
479 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_is_chain_on()
482 regmap_read(pmu->regmap, in rockchip_pmu_domain_is_chain_on()
483 pmu->info->chain_status_offset + pd->info->mem_offset, &val); in rockchip_pmu_domain_is_chain_on()
486 return val & pd->info->mem_status_mask; in rockchip_pmu_domain_is_chain_on()
491 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_mem_reset()
492 struct generic_pm_domain *genpd = &pd->genpd; in rockchip_pmu_domain_mem_reset()
499 dev_err(pmu->dev, in rockchip_pmu_domain_mem_reset()
501 genpd->name, is_on); in rockchip_pmu_domain_mem_reset()
507 regmap_write(pmu->regmap, pmu->info->mem_pwr_offset + pd->info->pwr_offset, in rockchip_pmu_domain_mem_reset()
508 (pd->info->pwr_mask | pd->info->pwr_w_mask)); in rockchip_pmu_domain_mem_reset()
514 dev_err(pmu->dev, in rockchip_pmu_domain_mem_reset()
516 genpd->name, is_on); in rockchip_pmu_domain_mem_reset()
520 regmap_write(pmu->regmap, pmu->info->mem_pwr_offset + pd->info->pwr_offset, in rockchip_pmu_domain_mem_reset()
521 pd->info->pwr_w_mask); in rockchip_pmu_domain_mem_reset()
527 dev_err(pmu->dev, in rockchip_pmu_domain_mem_reset()
529 genpd->name, is_on); in rockchip_pmu_domain_mem_reset()
539 struct rockchip_pmu *pmu = pd->pmu; in rockchip_do_pmu_set_power_domain()
540 struct generic_pm_domain *genpd = &pd->genpd; in rockchip_do_pmu_set_power_domain()
541 u32 pd_pwr_offset = pd->info->pwr_offset; in rockchip_do_pmu_set_power_domain()
544 if (pd->info->pwr_mask == 0) in rockchip_do_pmu_set_power_domain()
547 if (on && pd->info->mem_status_mask) in rockchip_do_pmu_set_power_domain()
550 if (pd->info->pwr_w_mask) in rockchip_do_pmu_set_power_domain()
551 regmap_write(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, in rockchip_do_pmu_set_power_domain()
552 on ? pd->info->pwr_w_mask : in rockchip_do_pmu_set_power_domain()
553 (pd->info->pwr_mask | pd->info->pwr_w_mask)); in rockchip_do_pmu_set_power_domain()
555 regmap_update_bits(pmu->regmap, pmu->info->pwr_offset + pd_pwr_offset, in rockchip_do_pmu_set_power_domain()
556 pd->info->pwr_mask, on ? 0 : -1U); in rockchip_do_pmu_set_power_domain()
565 dev_err(pmu->dev, in rockchip_do_pmu_set_power_domain()
567 genpd->name, is_on); in rockchip_do_pmu_set_power_domain()
574 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pd_power()
577 mutex_lock(&pmu->mutex); in rockchip_pd_power()
580 ret = clk_bulk_enable(pd->num_clks, pd->clks); in rockchip_pd_power()
582 dev_err(pmu->dev, "failed to enable clocks\n"); in rockchip_pd_power()
583 mutex_unlock(&pmu->mutex); in rockchip_pd_power()
606 clk_bulk_disable(pd->num_clks, pd->clks); in rockchip_pd_power()
609 mutex_unlock(&pmu->mutex); in rockchip_pd_power()
634 dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name); in rockchip_pd_attach_dev()
643 while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) { in rockchip_pd_attach_dev()
660 dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name); in rockchip_pd_detach_dev()
677 dev_err(pmu->dev, in rockchip_pm_add_one_domain()
680 return -EINVAL; in rockchip_pm_add_one_domain()
683 if (id >= pmu->info->num_domains) { in rockchip_pm_add_one_domain()
684 dev_err(pmu->dev, "%pOFn: invalid domain id %d\n", in rockchip_pm_add_one_domain()
686 return -EINVAL; in rockchip_pm_add_one_domain()
689 if (pmu->genpd_data.domains[id]) in rockchip_pm_add_one_domain()
692 pd_info = &pmu->info->domain_info[id]; in rockchip_pm_add_one_domain()
694 dev_err(pmu->dev, "%pOFn: undefined domain id %d\n", in rockchip_pm_add_one_domain()
696 return -EINVAL; in rockchip_pm_add_one_domain()
699 pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL); in rockchip_pm_add_one_domain()
701 return -ENOMEM; in rockchip_pm_add_one_domain()
703 pd->info = pd_info; in rockchip_pm_add_one_domain()
704 pd->pmu = pmu; in rockchip_pm_add_one_domain()
706 pd->num_clks = of_clk_get_parent_count(node); in rockchip_pm_add_one_domain()
707 if (pd->num_clks > 0) { in rockchip_pm_add_one_domain()
708 pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, in rockchip_pm_add_one_domain()
709 sizeof(*pd->clks), GFP_KERNEL); in rockchip_pm_add_one_domain()
710 if (!pd->clks) in rockchip_pm_add_one_domain()
711 return -ENOMEM; in rockchip_pm_add_one_domain()
713 dev_dbg(pmu->dev, "%pOFn: doesn't have clocks: %d\n", in rockchip_pm_add_one_domain()
714 node, pd->num_clks); in rockchip_pm_add_one_domain()
715 pd->num_clks = 0; in rockchip_pm_add_one_domain()
718 for (i = 0; i < pd->num_clks; i++) { in rockchip_pm_add_one_domain()
719 pd->clks[i].clk = of_clk_get(node, i); in rockchip_pm_add_one_domain()
720 if (IS_ERR(pd->clks[i].clk)) { in rockchip_pm_add_one_domain()
721 error = PTR_ERR(pd->clks[i].clk); in rockchip_pm_add_one_domain()
722 dev_err(pmu->dev, in rockchip_pm_add_one_domain()
729 error = clk_bulk_prepare(pd->num_clks, pd->clks); in rockchip_pm_add_one_domain()
733 pd->num_qos = of_count_phandle_with_args(node, "pm_qos", in rockchip_pm_add_one_domain()
736 if (pd->num_qos > 0) { in rockchip_pm_add_one_domain()
737 pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos, in rockchip_pm_add_one_domain()
738 sizeof(*pd->qos_regmap), in rockchip_pm_add_one_domain()
740 if (!pd->qos_regmap) { in rockchip_pm_add_one_domain()
741 error = -ENOMEM; in rockchip_pm_add_one_domain()
746 pd->qos_save_regs[j] = devm_kcalloc(pmu->dev, in rockchip_pm_add_one_domain()
747 pd->num_qos, in rockchip_pm_add_one_domain()
750 if (!pd->qos_save_regs[j]) { in rockchip_pm_add_one_domain()
751 error = -ENOMEM; in rockchip_pm_add_one_domain()
756 for (j = 0; j < pd->num_qos; j++) { in rockchip_pm_add_one_domain()
759 error = -ENODEV; in rockchip_pm_add_one_domain()
762 pd->qos_regmap[j] = syscon_node_to_regmap(qos_node); in rockchip_pm_add_one_domain()
764 if (IS_ERR(pd->qos_regmap[j])) { in rockchip_pm_add_one_domain()
765 error = -ENODEV; in rockchip_pm_add_one_domain()
771 if (pd->info->name) in rockchip_pm_add_one_domain()
772 pd->genpd.name = pd->info->name; in rockchip_pm_add_one_domain()
774 pd->genpd.name = kbasename(node->full_name); in rockchip_pm_add_one_domain()
775 pd->genpd.power_off = rockchip_pd_power_off; in rockchip_pm_add_one_domain()
776 pd->genpd.power_on = rockchip_pd_power_on; in rockchip_pm_add_one_domain()
777 pd->genpd.attach_dev = rockchip_pd_attach_dev; in rockchip_pm_add_one_domain()
778 pd->genpd.detach_dev = rockchip_pd_detach_dev; in rockchip_pm_add_one_domain()
779 pd->genpd.flags = GENPD_FLAG_PM_CLK; in rockchip_pm_add_one_domain()
780 if (pd_info->active_wakeup) in rockchip_pm_add_one_domain()
781 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; in rockchip_pm_add_one_domain()
782 pm_genpd_init(&pd->genpd, NULL, in rockchip_pm_add_one_domain()
784 (pd->info->mem_status_mask && !rockchip_pmu_domain_is_mem_on(pd))); in rockchip_pm_add_one_domain()
786 pmu->genpd_data.domains[id] = &pd->genpd; in rockchip_pm_add_one_domain()
790 clk_bulk_unprepare(pd->num_clks, pd->clks); in rockchip_pm_add_one_domain()
792 clk_bulk_put(pd->num_clks, pd->clks); in rockchip_pm_add_one_domain()
804 ret = pm_genpd_remove(&pd->genpd); in rockchip_pm_remove_one_domain()
806 dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n", in rockchip_pm_remove_one_domain()
807 pd->genpd.name, ret); in rockchip_pm_remove_one_domain()
809 clk_bulk_unprepare(pd->num_clks, pd->clks); in rockchip_pm_remove_one_domain()
810 clk_bulk_put(pd->num_clks, pd->clks); in rockchip_pm_remove_one_domain()
812 /* protect the zeroing of pm->num_clks */ in rockchip_pm_remove_one_domain()
813 mutex_lock(&pd->pmu->mutex); in rockchip_pm_remove_one_domain()
814 pd->num_clks = 0; in rockchip_pm_remove_one_domain()
815 mutex_unlock(&pd->pmu->mutex); in rockchip_pm_remove_one_domain()
826 for (i = 0; i < pmu->genpd_data.num_domains; i++) { in rockchip_pm_domain_cleanup()
827 genpd = pmu->genpd_data.domains[i]; in rockchip_pm_domain_cleanup()
842 regmap_write(pmu->regmap, domain_reg_offset, count); in rockchip_configure_pd_cnt()
844 regmap_write(pmu->regmap, domain_reg_offset + 4, count); in rockchip_configure_pd_cnt()
858 dev_err(pmu->dev, in rockchip_pm_add_subdomain()
863 parent_domain = pmu->genpd_data.domains[idx]; in rockchip_pm_add_subdomain()
867 dev_err(pmu->dev, "failed to handle node %pOFn: %d\n", in rockchip_pm_add_subdomain()
874 dev_err(pmu->dev, in rockchip_pm_add_subdomain()
879 child_domain = pmu->genpd_data.domains[idx]; in rockchip_pm_add_subdomain()
883 dev_err(pmu->dev, "%s failed to add subdomain %s: %d\n", in rockchip_pm_add_subdomain()
884 parent_domain->name, child_domain->name, error); in rockchip_pm_add_subdomain()
887 dev_dbg(pmu->dev, "%s add subdomain: %s\n", in rockchip_pm_add_subdomain()
888 parent_domain->name, child_domain->name); in rockchip_pm_add_subdomain()
899 struct device *dev = &pdev->dev; in rockchip_pm_domain_probe()
900 struct device_node *np = dev->of_node; in rockchip_pm_domain_probe()
908 return -ENODEV; in rockchip_pm_domain_probe()
914 struct_size(pmu, domains, pmu_info->num_domains), in rockchip_pm_domain_probe()
917 return -ENOMEM; in rockchip_pm_domain_probe()
919 pmu->dev = &pdev->dev; in rockchip_pm_domain_probe()
920 mutex_init(&pmu->mutex); in rockchip_pm_domain_probe()
922 pmu->info = pmu_info; in rockchip_pm_domain_probe()
924 pmu->genpd_data.domains = pmu->domains; in rockchip_pm_domain_probe()
925 pmu->genpd_data.num_domains = pmu_info->num_domains; in rockchip_pm_domain_probe()
927 parent = dev->parent; in rockchip_pm_domain_probe()
930 return -ENODEV; in rockchip_pm_domain_probe()
933 pmu->regmap = syscon_node_to_regmap(parent->of_node); in rockchip_pm_domain_probe()
934 if (IS_ERR(pmu->regmap)) { in rockchip_pm_domain_probe()
936 return PTR_ERR(pmu->regmap); in rockchip_pm_domain_probe()
943 if (pmu_info->core_power_transition_time) in rockchip_pm_domain_probe()
944 rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset, in rockchip_pm_domain_probe()
945 pmu_info->core_power_transition_time); in rockchip_pm_domain_probe()
946 if (pmu_info->gpu_pwrcnt_offset) in rockchip_pm_domain_probe()
947 rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset, in rockchip_pm_domain_probe()
948 pmu_info->gpu_power_transition_time); in rockchip_pm_domain_probe()
950 error = -ENODEV; in rockchip_pm_domain_probe()
979 error = of_genpd_add_provider_onecell(np, &pmu->genpd_data); in rockchip_pm_domain_probe()
1055 [RK3228_PD_BUS] = DOMAIN_RK3036("bus", BIT(2), BIT(2), BIT(18), true),
1076 [RK3328_PD_BUS] = DOMAIN_RK3328("bus", 0, BIT(2), BIT(2), true),
1389 .compatible = "rockchip,px30-power-controller",
1393 .compatible = "rockchip,rk3036-power-controller",
1397 .compatible = "rockchip,rk3066-power-controller",
1401 .compatible = "rockchip,rk3128-power-controller",
1405 .compatible = "rockchip,rk3188-power-controller",
1409 .compatible = "rockchip,rk3228-power-controller",
1413 .compatible = "rockchip,rk3288-power-controller",
1417 .compatible = "rockchip,rk3328-power-controller",
1421 .compatible = "rockchip,rk3366-power-controller",
1425 .compatible = "rockchip,rk3368-power-controller",
1429 .compatible = "rockchip,rk3399-power-controller",
1433 .compatible = "rockchip,rk3568-power-controller",
1437 .compatible = "rockchip,rk3576-power-controller",
1441 .compatible = "rockchip,rk3588-power-controller",
1445 .compatible = "rockchip,rv1126-power-controller",
1454 .name = "rockchip-pm-domain",