Lines Matching +full:bcm2835 +full:- +full:hdmi

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))
154 void __iomem *base = power->asb;
163 if (power->rpivid_asb)
164 base = power->rpivid_asb;
180 if (ktime_get_ns() - start >= 1000)
181 return -ETIMEDOUT;
199 struct bcm2835_power *power = pd->power;
202 if (power->rpivid_asb)
219 struct bcm2835_power *power = pd->power;
220 struct device *dev = power->dev;
227 if (power->rpivid_asb)
248 if (ktime_get_ns() - start >= 3000)
254 pd->base.name);
255 ret = -ETIMEDOUT;
267 if (ktime_get_ns() - start >= 1000) {
269 pd->base.name);
270 ret = -ETIMEDOUT;
293 struct bcm2835_power *power = pd->power;
296 ret = clk_prepare_enable(pd->clk);
298 dev_err(power->dev, "Failed to enable clock for %s\n",
299 pd->base.name);
306 clk_disable_unprepare(pd->clk);
311 ret = clk_prepare_enable(pd->clk);
313 dev_err(power->dev, "Failed to enable clock for %s\n",
314 pd->base.name);
320 dev_err(power->dev, "Failed to enable ASB master for %s\n",
321 pd->base.name);
326 dev_err(power->dev, "Failed to enable ASB slave for %s\n",
327 pd->base.name);
336 clk_disable_unprepare(pd->clk);
348 struct bcm2835_power *power = pd->power;
353 dev_warn(power->dev, "Failed to disable ASB slave for %s\n",
354 pd->base.name);
359 dev_warn(power->dev, "Failed to disable ASB master for %s\n",
360 pd->base.name);
365 clk_disable_unprepare(pd->clk);
377 struct bcm2835_power *power = pd->power;
379 switch (pd->domain) {
434 dev_err(power->dev, "Invalid domain %d\n", pd->domain);
435 return -EINVAL;
443 struct bcm2835_power *power = pd->power;
445 switch (pd->domain) {
497 dev_err(power->dev, "Invalid domain %d\n", pd->domain);
498 return -EINVAL;
506 struct device *dev = power->dev;
507 struct bcm2835_power_domain *dom = &power->domains[pd_xlate_index];
509 dom->clk = devm_clk_get(dev->parent, name);
510 if (IS_ERR(dom->clk)) {
511 int ret = PTR_ERR(dom->clk);
513 if (ret == -EPROBE_DEFER)
519 dom->clk = NULL;
522 dom->base.name = name;
523 dom->base.flags = GENPD_FLAG_ACTIVE_WAKEUP;
524 dom->base.power_on = bcm2835_power_pd_power_on;
525 dom->base.power_off = bcm2835_power_pd_power_off;
527 dom->domain = pd_xlate_index;
528 dom->power = power;
531 pm_genpd_init(&dom->base, NULL, true);
533 power->pd_xlate.domains[pd_xlate_index] = &dom->base;
538 /** bcm2835_reset_reset - Resets a block that has a reset line in the
542 * -- there's no reset ability with the power domain down. To reset
543 * the sub-block, we just disable its access to memory through the
544 * ASB, reset, and re-enable.
556 pd = &power->domains[BCM2835_POWER_DOMAIN_GRAFX_V3D];
559 pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_H264];
562 pd = &power->domains[BCM2835_POWER_DOMAIN_IMAGE_ISP];
565 dev_err(power->dev, "Bad reset id %ld\n", id);
566 return -EINVAL;
569 ret = bcm2835_power_pd_power_off(&pd->base);
573 return bcm2835_power_pd_power_on(&pd->base);
590 return -EINVAL;
614 [BCM2835_POWER_DOMAIN_HDMI] = "hdmi",
619 struct bcm2835_pm *pm = dev_get_drvdata(pdev->dev.parent);
620 struct device *dev = &pdev->dev;
638 return -ENOMEM;
641 power->dev = dev;
642 power->base = pm->base;
643 power->asb = pm->asb;
644 power->rpivid_asb = pm->rpivid_asb;
646 id = readl(power->asb + ASB_AXI_BRDG_ID);
649 return -ENODEV;
652 if (power->rpivid_asb) {
653 id = readl(power->rpivid_asb + ASB_AXI_BRDG_ID);
657 return -ENODEV;
661 power->pd_xlate.domains = devm_kcalloc(dev,
663 sizeof(*power->pd_xlate.domains),
665 if (!power->pd_xlate.domains)
666 return -ENOMEM;
668 power->pd_xlate.num_domains = ARRAY_SIZE(power_domain_names);
677 pm_genpd_add_subdomain(&power->domains[domain_deps[i].parent].base,
678 &power->domains[domain_deps[i].child].base);
681 power->reset.owner = THIS_MODULE;
682 power->reset.nr_resets = BCM2835_RESET_COUNT;
683 power->reset.ops = &bcm2835_reset_ops;
684 power->reset.of_node = dev->parent->of_node;
686 ret = devm_reset_controller_register(dev, &power->reset);
690 of_genpd_add_provider_onecell(dev->parent->of_node, &power->pd_xlate);
692 dev_info(dev, "Broadcom BCM2835 power domains driver");
697 struct generic_pm_domain *dom = &power->domains[i].base;
699 if (dom->name)
708 .name = "bcm2835-power",
714 MODULE_DESCRIPTION("Driver for Broadcom BCM2835 PM power domains and reset");