Lines Matching +full:meson +full:- +full:hhi +full:- +full:sysctrl
1 // SPDX-License-Identifier: GPL-2.0+
14 #include <linux/reset-controller.h>
18 #include <dt-bindings/power/meson8-power.h>
19 #include <dt-bindings/power/meson-axg-power.h>
20 #include <dt-bindings/power/meson-g12a-power.h>
21 #include <dt-bindings/power/meson-gxbb-power.h>
22 #include <dt-bindings/power/meson-sm1-power.h>
31 * AO-bus as syscon. 0x3a from GX translates to 0x02, 0x3b translates to 0x03
37 /* HHI Offsets */
321 regmap_read(pwrc_domain->pwrc->regmap_ao, in pwrc_ee_is_powered_off()
322 pwrc_domain->desc.top_pd->sleep_reg, ®); in pwrc_ee_is_powered_off()
324 return (reg & pwrc_domain->desc.top_pd->sleep_mask); in pwrc_ee_is_powered_off()
333 if (pwrc_domain->desc.top_pd) in meson_ee_pwrc_off()
334 regmap_update_bits(pwrc_domain->pwrc->regmap_ao, in meson_ee_pwrc_off()
335 pwrc_domain->desc.top_pd->sleep_reg, in meson_ee_pwrc_off()
336 pwrc_domain->desc.top_pd->sleep_mask, in meson_ee_pwrc_off()
337 pwrc_domain->desc.top_pd->sleep_mask); in meson_ee_pwrc_off()
340 for (i = 0 ; i < pwrc_domain->desc.mem_pd_count ; ++i) in meson_ee_pwrc_off()
341 regmap_update_bits(pwrc_domain->pwrc->regmap_hhi, in meson_ee_pwrc_off()
342 pwrc_domain->desc.mem_pd[i].reg, in meson_ee_pwrc_off()
343 pwrc_domain->desc.mem_pd[i].mask, in meson_ee_pwrc_off()
344 pwrc_domain->desc.mem_pd[i].mask); in meson_ee_pwrc_off()
348 if (pwrc_domain->desc.top_pd) in meson_ee_pwrc_off()
349 regmap_update_bits(pwrc_domain->pwrc->regmap_ao, in meson_ee_pwrc_off()
350 pwrc_domain->desc.top_pd->iso_reg, in meson_ee_pwrc_off()
351 pwrc_domain->desc.top_pd->iso_mask, in meson_ee_pwrc_off()
352 pwrc_domain->desc.top_pd->iso_mask); in meson_ee_pwrc_off()
354 if (pwrc_domain->num_clks) { in meson_ee_pwrc_off()
356 clk_bulk_disable_unprepare(pwrc_domain->num_clks, in meson_ee_pwrc_off()
357 pwrc_domain->clks); in meson_ee_pwrc_off()
369 if (pwrc_domain->desc.top_pd) in meson_ee_pwrc_on()
370 regmap_update_bits(pwrc_domain->pwrc->regmap_ao, in meson_ee_pwrc_on()
371 pwrc_domain->desc.top_pd->sleep_reg, in meson_ee_pwrc_on()
372 pwrc_domain->desc.top_pd->sleep_mask, 0); in meson_ee_pwrc_on()
375 for (i = 0 ; i < pwrc_domain->desc.mem_pd_count ; ++i) in meson_ee_pwrc_on()
376 regmap_update_bits(pwrc_domain->pwrc->regmap_hhi, in meson_ee_pwrc_on()
377 pwrc_domain->desc.mem_pd[i].reg, in meson_ee_pwrc_on()
378 pwrc_domain->desc.mem_pd[i].mask, 0); in meson_ee_pwrc_on()
382 ret = reset_control_assert(pwrc_domain->rstc); in meson_ee_pwrc_on()
386 if (pwrc_domain->desc.top_pd) in meson_ee_pwrc_on()
387 regmap_update_bits(pwrc_domain->pwrc->regmap_ao, in meson_ee_pwrc_on()
388 pwrc_domain->desc.top_pd->iso_reg, in meson_ee_pwrc_on()
389 pwrc_domain->desc.top_pd->iso_mask, 0); in meson_ee_pwrc_on()
391 ret = reset_control_deassert(pwrc_domain->rstc); in meson_ee_pwrc_on()
395 return clk_bulk_prepare_enable(pwrc_domain->num_clks, in meson_ee_pwrc_on()
396 pwrc_domain->clks); in meson_ee_pwrc_on()
405 dom->pwrc = pwrc; in meson_ee_pwrc_init_domain()
406 dom->num_rstc = dom->desc.reset_names_count; in meson_ee_pwrc_init_domain()
407 dom->num_clks = dom->desc.clk_names_count; in meson_ee_pwrc_init_domain()
409 if (dom->num_rstc) { in meson_ee_pwrc_init_domain()
410 int count = reset_control_get_count(&pdev->dev); in meson_ee_pwrc_init_domain()
412 if (count != dom->num_rstc) in meson_ee_pwrc_init_domain()
413 dev_warn(&pdev->dev, "Invalid resets count %d for domain %s\n", in meson_ee_pwrc_init_domain()
414 count, dom->desc.name); in meson_ee_pwrc_init_domain()
416 dom->rstc = devm_reset_control_array_get_exclusive(&pdev->dev); in meson_ee_pwrc_init_domain()
417 if (IS_ERR(dom->rstc)) in meson_ee_pwrc_init_domain()
418 return PTR_ERR(dom->rstc); in meson_ee_pwrc_init_domain()
421 if (dom->num_clks) { in meson_ee_pwrc_init_domain()
422 int ret = devm_clk_bulk_get_all(&pdev->dev, &dom->clks); in meson_ee_pwrc_init_domain()
426 if (dom->num_clks != ret) { in meson_ee_pwrc_init_domain()
427 dev_warn(&pdev->dev, "Invalid clocks count %d for domain %s\n", in meson_ee_pwrc_init_domain()
428 ret, dom->desc.name); in meson_ee_pwrc_init_domain()
429 dom->num_clks = ret; in meson_ee_pwrc_init_domain()
433 dom->base.name = dom->desc.name; in meson_ee_pwrc_init_domain()
434 dom->base.power_on = meson_ee_pwrc_on; in meson_ee_pwrc_init_domain()
435 dom->base.power_off = meson_ee_pwrc_off; in meson_ee_pwrc_init_domain()
448 if (dom->num_clks && dom->desc.is_powered_off && !dom->desc.is_powered_off(dom)) { in meson_ee_pwrc_init_domain()
449 ret = clk_bulk_prepare_enable(dom->num_clks, dom->clks); in meson_ee_pwrc_init_domain()
453 dom->base.flags = GENPD_FLAG_ALWAYS_ON; in meson_ee_pwrc_init_domain()
454 ret = pm_genpd_init(&dom->base, NULL, false); in meson_ee_pwrc_init_domain()
458 ret = pm_genpd_init(&dom->base, NULL, in meson_ee_pwrc_init_domain()
459 (dom->desc.is_powered_off ? in meson_ee_pwrc_init_domain()
460 dom->desc.is_powered_off(dom) : true)); in meson_ee_pwrc_init_domain()
476 match = of_device_get_match_data(&pdev->dev); in meson_ee_pwrc_probe()
478 dev_err(&pdev->dev, "failed to get match data\n"); in meson_ee_pwrc_probe()
479 return -ENODEV; in meson_ee_pwrc_probe()
482 pwrc = devm_kzalloc(&pdev->dev, sizeof(*pwrc), GFP_KERNEL); in meson_ee_pwrc_probe()
484 return -ENOMEM; in meson_ee_pwrc_probe()
486 pwrc->xlate.domains = devm_kcalloc(&pdev->dev, match->count, in meson_ee_pwrc_probe()
487 sizeof(*pwrc->xlate.domains), in meson_ee_pwrc_probe()
489 if (!pwrc->xlate.domains) in meson_ee_pwrc_probe()
490 return -ENOMEM; in meson_ee_pwrc_probe()
492 pwrc->domains = devm_kcalloc(&pdev->dev, match->count, in meson_ee_pwrc_probe()
493 sizeof(*pwrc->domains), GFP_KERNEL); in meson_ee_pwrc_probe()
494 if (!pwrc->domains) in meson_ee_pwrc_probe()
495 return -ENOMEM; in meson_ee_pwrc_probe()
497 pwrc->xlate.num_domains = match->count; in meson_ee_pwrc_probe()
499 parent_np = of_get_parent(pdev->dev.of_node); in meson_ee_pwrc_probe()
503 dev_err(&pdev->dev, "failed to get HHI regmap\n"); in meson_ee_pwrc_probe()
507 regmap_ao = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, in meson_ee_pwrc_probe()
508 "amlogic,ao-sysctrl"); in meson_ee_pwrc_probe()
510 dev_err(&pdev->dev, "failed to get AO regmap\n"); in meson_ee_pwrc_probe()
514 pwrc->regmap_ao = regmap_ao; in meson_ee_pwrc_probe()
515 pwrc->regmap_hhi = regmap_hhi; in meson_ee_pwrc_probe()
519 for (i = 0 ; i < match->count ; ++i) { in meson_ee_pwrc_probe()
520 struct meson_ee_pwrc_domain *dom = &pwrc->domains[i]; in meson_ee_pwrc_probe()
522 memcpy(&dom->desc, &match->domains[i], sizeof(dom->desc)); in meson_ee_pwrc_probe()
528 pwrc->xlate.domains[i] = &dom->base; in meson_ee_pwrc_probe()
531 return of_genpd_add_provider_onecell(pdev->dev.of_node, &pwrc->xlate); in meson_ee_pwrc_probe()
539 for (i = 0 ; i < pwrc->xlate.num_domains ; ++i) { in meson_ee_pwrc_shutdown()
540 struct meson_ee_pwrc_domain *dom = &pwrc->domains[i]; in meson_ee_pwrc_shutdown()
542 if (dom->desc.is_powered_off && !dom->desc.is_powered_off(dom)) in meson_ee_pwrc_shutdown()
543 meson_ee_pwrc_off(&dom->base); in meson_ee_pwrc_shutdown()
579 .compatible = "amlogic,meson8-pwrc",
583 .compatible = "amlogic,meson8b-pwrc",
587 .compatible = "amlogic,meson8m2-pwrc",
591 .compatible = "amlogic,meson-axg-pwrc",
595 .compatible = "amlogic,meson-gxbb-pwrc",
599 .compatible = "amlogic,meson-g12a-pwrc",
603 .compatible = "amlogic,meson-sm1-pwrc",