Lines Matching +full:bcm2835 +full:- +full:dsi1
1 // SPDX-License-Identifier: GPL-2.0+
3 * Power domain driver for Broadcom BCM2835
8 #include <dt-bindings/soc/bcm2835-pm.h>
12 #include <linux/mfd/bcm2835-pm.h>
16 #include <linux/reset-controller.h>
109 #define PM_READ(reg) readl(power->base + (reg))
110 #define PM_WRITE(reg, val) writel(PM_PASSWORD | (val), power->base + (reg))
129 #define ASB_READ(reg) readl(power->asb + (reg))
130 #define ASB_WRITE(reg, val) writel(PM_PASSWORD | (val), power->asb + (reg))
164 if (ktime_get_ns() - start >= 1000) in bcm2835_asb_enable()
165 return -ETIMEDOUT; in bcm2835_asb_enable()
184 if (ktime_get_ns() - start >= 1000) in bcm2835_asb_disable()
185 return -ETIMEDOUT; in bcm2835_asb_disable()
193 struct bcm2835_power *power = pd->power; in bcm2835_power_power_off()
209 struct bcm2835_power *power = pd->power; in bcm2835_power_power_on()
210 struct device *dev = power->dev; in bcm2835_power_power_on()
234 if (ktime_get_ns() - start >= 3000) in bcm2835_power_power_on()
240 pd->base.name); in bcm2835_power_power_on()
241 ret = -ETIMEDOUT; in bcm2835_power_power_on()
253 if (ktime_get_ns() - start >= 1000) { in bcm2835_power_power_on()
255 pd->base.name); in bcm2835_power_power_on()
256 ret = -ETIMEDOUT; in bcm2835_power_power_on()
279 struct bcm2835_power *power = pd->power; in bcm2835_asb_power_on()
282 ret = clk_prepare_enable(pd->clk); in bcm2835_asb_power_on()
284 dev_err(power->dev, "Failed to enable clock for %s\n", in bcm2835_asb_power_on()
285 pd->base.name); in bcm2835_asb_power_on()
292 clk_disable_unprepare(pd->clk); in bcm2835_asb_power_on()
297 ret = clk_prepare_enable(pd->clk); in bcm2835_asb_power_on()
299 dev_err(power->dev, "Failed to enable clock for %s\n", in bcm2835_asb_power_on()
300 pd->base.name); in bcm2835_asb_power_on()
306 dev_err(power->dev, "Failed to enable ASB master for %s\n", in bcm2835_asb_power_on()
307 pd->base.name); in bcm2835_asb_power_on()
312 dev_err(power->dev, "Failed to enable ASB slave for %s\n", in bcm2835_asb_power_on()
313 pd->base.name); in bcm2835_asb_power_on()
322 clk_disable_unprepare(pd->clk); in bcm2835_asb_power_on()
334 struct bcm2835_power *power = pd->power; in bcm2835_asb_power_off()
339 dev_warn(power->dev, "Failed to disable ASB slave for %s\n", in bcm2835_asb_power_off()
340 pd->base.name); in bcm2835_asb_power_off()
345 dev_warn(power->dev, "Failed to disable ASB master for %s\n", in bcm2835_asb_power_off()
346 pd->base.name); in bcm2835_asb_power_off()
351 clk_disable_unprepare(pd->clk); in bcm2835_asb_power_off()
363 struct bcm2835_power *power = pd->power; in bcm2835_power_pd_power_on()
365 switch (pd->domain) { in bcm2835_power_pd_power_on()
420 dev_err(power->dev, "Invalid domain %d\n", pd->domain); in bcm2835_power_pd_power_on()
421 return -EINVAL; in bcm2835_power_pd_power_on()
429 struct bcm2835_power *power = pd->power; in bcm2835_power_pd_power_off()
431 switch (pd->domain) { in bcm2835_power_pd_power_off()
483 dev_err(power->dev, "Invalid domain %d\n", pd->domain); in bcm2835_power_pd_power_off()
484 return -EINVAL; in bcm2835_power_pd_power_off()
492 struct device *dev = power->dev; in bcm2835_init_power_domain()
493 struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index]; in bcm2835_init_power_domain()
495 dom->clk = devm_clk_get(dev->parent, name); in bcm2835_init_power_domain()
496 if (IS_ERR(dom->clk)) { in bcm2835_init_power_domain()
497 int ret = PTR_ERR(dom->clk); in bcm2835_init_power_domain()
499 if (ret == -EPROBE_DEFER) in bcm2835_init_power_domain()
505 dom->clk = NULL; in bcm2835_init_power_domain()
508 dom->base.name = name; in bcm2835_init_power_domain()
509 dom->base.power_on = bcm2835_power_pd_power_on; in bcm2835_init_power_domain()
510 dom->base.power_off = bcm2835_power_pd_power_off; in bcm2835_init_power_domain()
512 dom->domain = pd_xlate_index; in bcm2835_init_power_domain()
513 dom->power = power; in bcm2835_init_power_domain()
516 pm_genpd_init(&dom->base, NULL, true); in bcm2835_init_power_domain()
518 power->pd_xlate.domains[pd_xlate_index] = &dom->base; in bcm2835_init_power_domain()
523 /** bcm2835_reset_reset - Resets a block that has a reset line in the
527 * -- there's no reset ability with the power domain down. To reset
528 * the sub-block, we just disable its access to memory through the
529 * ASB, reset, and re-enable.
541 pd = &power->domains[BCM2835_POWER_DOMAIN_GRAFX_V3D]; in bcm2835_reset_reset()
544 pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_H264]; in bcm2835_reset_reset()
547 pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_ISP]; in bcm2835_reset_reset()
550 dev_err(power->dev, "Bad reset id %ld\n", id); in bcm2835_reset_reset()
551 return -EINVAL; in bcm2835_reset_reset()
554 ret = bcm2835_power_pd_power_off(&pd->base); in bcm2835_reset_reset()
558 return bcm2835_power_pd_power_on(&pd->base); in bcm2835_reset_reset()
575 return -EINVAL; in bcm2835_reset_status()
595 [BCM2835_POWER_DOMAIN_DSI1] = "dsi1",
604 struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent); in bcm2835_power_probe()
605 struct device *dev = &pdev->dev; in bcm2835_power_probe()
623 return -ENOMEM; in bcm2835_power_probe()
626 power->dev = dev; in bcm2835_power_probe()
627 power->base = pm->base; in bcm2835_power_probe()
628 power->asb = pm->asb; in bcm2835_power_probe()
633 return -ENODEV; in bcm2835_power_probe()
636 power->pd_xlate.domains = devm_kcalloc(dev, in bcm2835_power_probe()
638 sizeof(*power->pd_xlate.domains), in bcm2835_power_probe()
640 if (!power->pd_xlate.domains) in bcm2835_power_probe()
641 return -ENOMEM; in bcm2835_power_probe()
643 power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names); in bcm2835_power_probe()
652 pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base, in bcm2835_power_probe()
653 &power->domains[domain_deps[i].child].base); in bcm2835_power_probe()
656 power->reset.owner = THIS_MODULE; in bcm2835_power_probe()
657 power->reset.nr_resets = BCM2835_RESET_COUNT; in bcm2835_power_probe()
658 power->reset.ops = &bcm2835_reset_ops; in bcm2835_power_probe()
659 power->reset.of_node = dev->parent->of_node; in bcm2835_power_probe()
661 ret = devm_reset_controller_register(dev, &power->reset); in bcm2835_power_probe()
665 of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate); in bcm2835_power_probe()
667 dev_info(dev, "Broadcom BCM2835 power domains driver"); in bcm2835_power_probe()
672 struct generic_pm_domain *dom = &power->domains[i].base; in bcm2835_power_probe()
674 if (dom->name) in bcm2835_power_probe()
689 .name = "bcm2835-power",
695 MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM power domains and reset");