Lines Matching +full:rk3066 +full:- +full:usb
1 // SPDX-License-Identifier: GPL-2.0-only
19 #include <dt-bindings/power/px30-power.h>
20 #include <dt-bindings/power/rk3036-power.h>
21 #include <dt-bindings/power/rk3066-power.h>
22 #include <dt-bindings/power/rk3128-power.h>
23 #include <dt-bindings/power/rk3188-power.h>
24 #include <dt-bindings/power/rk3228-power.h>
25 #include <dt-bindings/power/rk3288-power.h>
26 #include <dt-bindings/power/rk3328-power.h>
27 #include <dt-bindings/power/rk3366-power.h>
28 #include <dt-bindings/power/rk3368-power.h>
29 #include <dt-bindings/power/rk3399-power.h>
30 #include <dt-bindings/power/rk3568-power.h>
144 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_is_idle()
145 const struct rockchip_domain_info *pd_info = pd->info; in rockchip_pmu_domain_is_idle()
148 regmap_read(pmu->regmap, pmu->info->idle_offset, &val); in rockchip_pmu_domain_is_idle()
149 return (val & pd_info->idle_mask) == pd_info->idle_mask; in rockchip_pmu_domain_is_idle()
156 regmap_read(pmu->regmap, pmu->info->ack_offset, &val); in rockchip_pmu_read_ack()
163 const struct rockchip_domain_info *pd_info = pd->info; in rockchip_pmu_set_idle_request()
164 struct generic_pm_domain *genpd = &pd->genpd; in rockchip_pmu_set_idle_request()
165 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_set_idle_request()
171 if (pd_info->req_mask == 0) in rockchip_pmu_set_idle_request()
173 else if (pd_info->req_w_mask) in rockchip_pmu_set_idle_request()
174 regmap_write(pmu->regmap, pmu->info->req_offset, in rockchip_pmu_set_idle_request()
175 idle ? (pd_info->req_mask | pd_info->req_w_mask) : in rockchip_pmu_set_idle_request()
176 pd_info->req_w_mask); in rockchip_pmu_set_idle_request()
178 regmap_update_bits(pmu->regmap, pmu->info->req_offset, in rockchip_pmu_set_idle_request()
179 pd_info->req_mask, idle ? -1U : 0); in rockchip_pmu_set_idle_request()
184 target_ack = idle ? pd_info->ack_mask : 0; in rockchip_pmu_set_idle_request()
186 (val & pd_info->ack_mask) == target_ack, in rockchip_pmu_set_idle_request()
189 dev_err(pmu->dev, in rockchip_pmu_set_idle_request()
191 genpd->name, val); in rockchip_pmu_set_idle_request()
198 dev_err(pmu->dev, in rockchip_pmu_set_idle_request()
200 genpd->name, is_idle); in rockchip_pmu_set_idle_request()
211 for (i = 0; i < pd->num_qos; i++) { in rockchip_pmu_save_qos()
212 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
214 &pd->qos_save_regs[0][i]); in rockchip_pmu_save_qos()
215 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
217 &pd->qos_save_regs[1][i]); in rockchip_pmu_save_qos()
218 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
220 &pd->qos_save_regs[2][i]); in rockchip_pmu_save_qos()
221 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
223 &pd->qos_save_regs[3][i]); in rockchip_pmu_save_qos()
224 regmap_read(pd->qos_regmap[i], in rockchip_pmu_save_qos()
226 &pd->qos_save_regs[4][i]); in rockchip_pmu_save_qos()
235 for (i = 0; i < pd->num_qos; i++) { in rockchip_pmu_restore_qos()
236 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
238 pd->qos_save_regs[0][i]); in rockchip_pmu_restore_qos()
239 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
241 pd->qos_save_regs[1][i]); in rockchip_pmu_restore_qos()
242 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
244 pd->qos_save_regs[2][i]); in rockchip_pmu_restore_qos()
245 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
247 pd->qos_save_regs[3][i]); in rockchip_pmu_restore_qos()
248 regmap_write(pd->qos_regmap[i], in rockchip_pmu_restore_qos()
250 pd->qos_save_regs[4][i]); in rockchip_pmu_restore_qos()
258 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pmu_domain_is_on()
261 /* check idle status for idle-only domains */ in rockchip_pmu_domain_is_on()
262 if (pd->info->status_mask == 0) in rockchip_pmu_domain_is_on()
265 regmap_read(pmu->regmap, pmu->info->status_offset, &val); in rockchip_pmu_domain_is_on()
268 return !(val & pd->info->status_mask); in rockchip_pmu_domain_is_on()
274 struct rockchip_pmu *pmu = pd->pmu; in rockchip_do_pmu_set_power_domain()
275 struct generic_pm_domain *genpd = &pd->genpd; in rockchip_do_pmu_set_power_domain()
278 if (pd->info->pwr_mask == 0) in rockchip_do_pmu_set_power_domain()
280 else if (pd->info->pwr_w_mask) in rockchip_do_pmu_set_power_domain()
281 regmap_write(pmu->regmap, pmu->info->pwr_offset, in rockchip_do_pmu_set_power_domain()
282 on ? pd->info->pwr_w_mask : in rockchip_do_pmu_set_power_domain()
283 (pd->info->pwr_mask | pd->info->pwr_w_mask)); in rockchip_do_pmu_set_power_domain()
285 regmap_update_bits(pmu->regmap, pmu->info->pwr_offset, in rockchip_do_pmu_set_power_domain()
286 pd->info->pwr_mask, on ? 0 : -1U); in rockchip_do_pmu_set_power_domain()
292 dev_err(pmu->dev, in rockchip_do_pmu_set_power_domain()
294 genpd->name, is_on); in rockchip_do_pmu_set_power_domain()
301 struct rockchip_pmu *pmu = pd->pmu; in rockchip_pd_power()
304 mutex_lock(&pmu->mutex); in rockchip_pd_power()
307 ret = clk_bulk_enable(pd->num_clks, pd->clks); in rockchip_pd_power()
309 dev_err(pmu->dev, "failed to enable clocks\n"); in rockchip_pd_power()
310 mutex_unlock(&pmu->mutex); in rockchip_pd_power()
330 clk_bulk_disable(pd->num_clks, pd->clks); in rockchip_pd_power()
333 mutex_unlock(&pmu->mutex); in rockchip_pd_power()
358 dev_dbg(dev, "attaching to power domain '%s'\n", genpd->name); in rockchip_pd_attach_dev()
367 while ((clk = of_clk_get(dev->of_node, i++)) && !IS_ERR(clk)) { in rockchip_pd_attach_dev()
384 dev_dbg(dev, "detaching from power domain '%s'\n", genpd->name); in rockchip_pd_detach_dev()
401 dev_err(pmu->dev, in rockchip_pm_add_one_domain()
404 return -EINVAL; in rockchip_pm_add_one_domain()
407 if (id >= pmu->info->num_domains) { in rockchip_pm_add_one_domain()
408 dev_err(pmu->dev, "%pOFn: invalid domain id %d\n", in rockchip_pm_add_one_domain()
410 return -EINVAL; in rockchip_pm_add_one_domain()
413 pd_info = &pmu->info->domain_info[id]; in rockchip_pm_add_one_domain()
415 dev_err(pmu->dev, "%pOFn: undefined domain id %d\n", in rockchip_pm_add_one_domain()
417 return -EINVAL; in rockchip_pm_add_one_domain()
420 pd = devm_kzalloc(pmu->dev, sizeof(*pd), GFP_KERNEL); in rockchip_pm_add_one_domain()
422 return -ENOMEM; in rockchip_pm_add_one_domain()
424 pd->info = pd_info; in rockchip_pm_add_one_domain()
425 pd->pmu = pmu; in rockchip_pm_add_one_domain()
427 pd->num_clks = of_clk_get_parent_count(node); in rockchip_pm_add_one_domain()
428 if (pd->num_clks > 0) { in rockchip_pm_add_one_domain()
429 pd->clks = devm_kcalloc(pmu->dev, pd->num_clks, in rockchip_pm_add_one_domain()
430 sizeof(*pd->clks), GFP_KERNEL); in rockchip_pm_add_one_domain()
431 if (!pd->clks) in rockchip_pm_add_one_domain()
432 return -ENOMEM; in rockchip_pm_add_one_domain()
434 dev_dbg(pmu->dev, "%pOFn: doesn't have clocks: %d\n", in rockchip_pm_add_one_domain()
435 node, pd->num_clks); in rockchip_pm_add_one_domain()
436 pd->num_clks = 0; in rockchip_pm_add_one_domain()
439 for (i = 0; i < pd->num_clks; i++) { in rockchip_pm_add_one_domain()
440 pd->clks[i].clk = of_clk_get(node, i); in rockchip_pm_add_one_domain()
441 if (IS_ERR(pd->clks[i].clk)) { in rockchip_pm_add_one_domain()
442 error = PTR_ERR(pd->clks[i].clk); in rockchip_pm_add_one_domain()
443 dev_err(pmu->dev, in rockchip_pm_add_one_domain()
450 error = clk_bulk_prepare(pd->num_clks, pd->clks); in rockchip_pm_add_one_domain()
454 pd->num_qos = of_count_phandle_with_args(node, "pm_qos", in rockchip_pm_add_one_domain()
457 if (pd->num_qos > 0) { in rockchip_pm_add_one_domain()
458 pd->qos_regmap = devm_kcalloc(pmu->dev, pd->num_qos, in rockchip_pm_add_one_domain()
459 sizeof(*pd->qos_regmap), in rockchip_pm_add_one_domain()
461 if (!pd->qos_regmap) { in rockchip_pm_add_one_domain()
462 error = -ENOMEM; in rockchip_pm_add_one_domain()
467 pd->qos_save_regs[j] = devm_kcalloc(pmu->dev, in rockchip_pm_add_one_domain()
468 pd->num_qos, in rockchip_pm_add_one_domain()
471 if (!pd->qos_save_regs[j]) { in rockchip_pm_add_one_domain()
472 error = -ENOMEM; in rockchip_pm_add_one_domain()
477 for (j = 0; j < pd->num_qos; j++) { in rockchip_pm_add_one_domain()
480 error = -ENODEV; in rockchip_pm_add_one_domain()
483 pd->qos_regmap[j] = syscon_node_to_regmap(qos_node); in rockchip_pm_add_one_domain()
484 if (IS_ERR(pd->qos_regmap[j])) { in rockchip_pm_add_one_domain()
485 error = -ENODEV; in rockchip_pm_add_one_domain()
495 dev_err(pmu->dev, in rockchip_pm_add_one_domain()
501 if (pd->info->name) in rockchip_pm_add_one_domain()
502 pd->genpd.name = pd->info->name; in rockchip_pm_add_one_domain()
504 pd->genpd.name = kbasename(node->full_name); in rockchip_pm_add_one_domain()
505 pd->genpd.power_off = rockchip_pd_power_off; in rockchip_pm_add_one_domain()
506 pd->genpd.power_on = rockchip_pd_power_on; in rockchip_pm_add_one_domain()
507 pd->genpd.attach_dev = rockchip_pd_attach_dev; in rockchip_pm_add_one_domain()
508 pd->genpd.detach_dev = rockchip_pd_detach_dev; in rockchip_pm_add_one_domain()
509 pd->genpd.flags = GENPD_FLAG_PM_CLK; in rockchip_pm_add_one_domain()
510 if (pd_info->active_wakeup) in rockchip_pm_add_one_domain()
511 pd->genpd.flags |= GENPD_FLAG_ACTIVE_WAKEUP; in rockchip_pm_add_one_domain()
512 pm_genpd_init(&pd->genpd, NULL, false); in rockchip_pm_add_one_domain()
514 pmu->genpd_data.domains[id] = &pd->genpd; in rockchip_pm_add_one_domain()
518 clk_bulk_unprepare(pd->num_clks, pd->clks); in rockchip_pm_add_one_domain()
520 clk_bulk_put(pd->num_clks, pd->clks); in rockchip_pm_add_one_domain()
532 ret = pm_genpd_remove(&pd->genpd); in rockchip_pm_remove_one_domain()
534 dev_err(pd->pmu->dev, "failed to remove domain '%s' : %d - state may be inconsistent\n", in rockchip_pm_remove_one_domain()
535 pd->genpd.name, ret); in rockchip_pm_remove_one_domain()
537 clk_bulk_unprepare(pd->num_clks, pd->clks); in rockchip_pm_remove_one_domain()
538 clk_bulk_put(pd->num_clks, pd->clks); in rockchip_pm_remove_one_domain()
540 /* protect the zeroing of pm->num_clks */ in rockchip_pm_remove_one_domain()
541 mutex_lock(&pd->pmu->mutex); in rockchip_pm_remove_one_domain()
542 pd->num_clks = 0; in rockchip_pm_remove_one_domain()
543 mutex_unlock(&pd->pmu->mutex); in rockchip_pm_remove_one_domain()
554 for (i = 0; i < pmu->genpd_data.num_domains; i++) { in rockchip_pm_domain_cleanup()
555 genpd = pmu->genpd_data.domains[i]; in rockchip_pm_domain_cleanup()
570 regmap_write(pmu->regmap, domain_reg_offset, count); in rockchip_configure_pd_cnt()
572 regmap_write(pmu->regmap, domain_reg_offset + 4, count); in rockchip_configure_pd_cnt()
587 dev_err(pmu->dev, in rockchip_pm_add_subdomain()
592 parent_domain = pmu->genpd_data.domains[idx]; in rockchip_pm_add_subdomain()
596 dev_err(pmu->dev, "failed to handle node %pOFn: %d\n", in rockchip_pm_add_subdomain()
603 dev_err(pmu->dev, in rockchip_pm_add_subdomain()
608 child_domain = pmu->genpd_data.domains[idx]; in rockchip_pm_add_subdomain()
612 dev_err(pmu->dev, "%s failed to add subdomain %s: %d\n", in rockchip_pm_add_subdomain()
613 parent_domain->name, child_domain->name, error); in rockchip_pm_add_subdomain()
616 dev_dbg(pmu->dev, "%s add subdomain: %s\n", in rockchip_pm_add_subdomain()
617 parent_domain->name, child_domain->name); in rockchip_pm_add_subdomain()
632 struct device *dev = &pdev->dev; in rockchip_pm_domain_probe()
633 struct device_node *np = dev->of_node; in rockchip_pm_domain_probe()
643 return -ENODEV; in rockchip_pm_domain_probe()
646 match = of_match_device(dev->driver->of_match_table, dev); in rockchip_pm_domain_probe()
647 if (!match || !match->data) { in rockchip_pm_domain_probe()
649 return -EINVAL; in rockchip_pm_domain_probe()
652 pmu_info = match->data; in rockchip_pm_domain_probe()
655 struct_size(pmu, domains, pmu_info->num_domains), in rockchip_pm_domain_probe()
658 return -ENOMEM; in rockchip_pm_domain_probe()
660 pmu->dev = &pdev->dev; in rockchip_pm_domain_probe()
661 mutex_init(&pmu->mutex); in rockchip_pm_domain_probe()
663 pmu->info = pmu_info; in rockchip_pm_domain_probe()
665 pmu->genpd_data.domains = pmu->domains; in rockchip_pm_domain_probe()
666 pmu->genpd_data.num_domains = pmu_info->num_domains; in rockchip_pm_domain_probe()
668 parent = dev->parent; in rockchip_pm_domain_probe()
671 return -ENODEV; in rockchip_pm_domain_probe()
674 pmu->regmap = syscon_node_to_regmap(parent->of_node); in rockchip_pm_domain_probe()
675 if (IS_ERR(pmu->regmap)) { in rockchip_pm_domain_probe()
677 return PTR_ERR(pmu->regmap); in rockchip_pm_domain_probe()
684 if (pmu_info->core_power_transition_time) in rockchip_pm_domain_probe()
685 rockchip_configure_pd_cnt(pmu, pmu_info->core_pwrcnt_offset, in rockchip_pm_domain_probe()
686 pmu_info->core_power_transition_time); in rockchip_pm_domain_probe()
687 if (pmu_info->gpu_pwrcnt_offset) in rockchip_pm_domain_probe()
688 rockchip_configure_pd_cnt(pmu, pmu_info->gpu_pwrcnt_offset, in rockchip_pm_domain_probe()
689 pmu_info->gpu_power_transition_time); in rockchip_pm_domain_probe()
691 error = -ENODEV; in rockchip_pm_domain_probe()
716 error = of_genpd_add_provider_onecell(np, &pmu->genpd_data); in rockchip_pm_domain_probe()
730 [PX30_PD_USB] = DOMAIN_PX30("usb", BIT(5), BIT(5), BIT(10), false),
1015 .compatible = "rockchip,px30-power-controller",
1019 .compatible = "rockchip,rk3036-power-controller",
1023 .compatible = "rockchip,rk3066-power-controller",
1027 .compatible = "rockchip,rk3128-power-controller",
1031 .compatible = "rockchip,rk3188-power-controller",
1035 .compatible = "rockchip,rk3228-power-controller",
1039 .compatible = "rockchip,rk3288-power-controller",
1043 .compatible = "rockchip,rk3328-power-controller",
1047 .compatible = "rockchip,rk3366-power-controller",
1051 .compatible = "rockchip,rk3368-power-controller",
1055 .compatible = "rockchip,rk3399-power-controller",
1059 .compatible = "rockchip,rk3568-power-controller",
1068 .name = "rockchip-pm-domain",