diff options
-rw-r--r-- | drivers/soc/bcm/bcm2835-power.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c index 9c352f66e6d5..1e06d91c0739 100644 --- a/drivers/soc/bcm/bcm2835-power.c +++ b/drivers/soc/bcm/bcm2835-power.c @@ -126,6 +126,8 @@ #define ASB_AXI_BRDG_ID 0x20 +#define BCM2835_BRDG_ID 0x62726467 + struct bcm2835_power_domain { struct generic_pm_domain base; struct bcm2835_power *power; @@ -139,6 +141,8 @@ struct bcm2835_power { void __iomem *base; /* AXI Async bridge registers. */ void __iomem *asb; + /* RPiVid bridge registers. */ + void __iomem *rpivid_asb; struct genpd_onecell_data pd_xlate; struct bcm2835_power_domain domains[BCM2835_POWER_DOMAIN_COUNT]; @@ -151,8 +155,15 @@ static int bcm2835_asb_control(struct bcm2835_power *power, u32 reg, bool enable u64 start; u32 val; - if (!reg) + switch (reg) { + case 0: return 0; + case ASB_V3D_S_CTRL: + case ASB_V3D_M_CTRL: + if (power->rpivid_asb) + base = power->rpivid_asb; + break; + } start = ktime_get_ns(); @@ -621,13 +632,23 @@ static int bcm2835_power_probe(struct platform_device *pdev) power->dev = dev; power->base = pm->base; power->asb = pm->asb; + power->rpivid_asb = pm->rpivid_asb; id = readl(power->asb + ASB_AXI_BRDG_ID); - if (id != 0x62726467 /* "BRDG" */) { + if (id != BCM2835_BRDG_ID /* "BRDG" */) { dev_err(dev, "ASB register ID returned 0x%08x\n", id); return -ENODEV; } + if (power->rpivid_asb) { + id = readl(power->rpivid_asb + ASB_AXI_BRDG_ID); + if (id != BCM2835_BRDG_ID /* "BRDG" */) { + dev_err(dev, "RPiVid ASB register ID returned 0x%08x\n", + id); + return -ENODEV; + } + } + power->pd_xlate.domains = devm_kcalloc(dev, ARRAY_SIZE(power_domain_names), sizeof(*power->pd_xlate.domains), |