summaryrefslogtreecommitdiff
path: root/drivers/soc/bcm
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/soc/bcm')
-rw-r--r--drivers/soc/bcm/bcm2835-power.c72
-rw-r--r--drivers/soc/bcm/brcmstb/biuctrl.c9
-rw-r--r--drivers/soc/bcm/brcmstb/pm/pm-arm.c2
3 files changed, 55 insertions, 28 deletions
diff --git a/drivers/soc/bcm/bcm2835-power.c b/drivers/soc/bcm/bcm2835-power.c
index 1e0041ec8132..5bcd047768b6 100644
--- a/drivers/soc/bcm/bcm2835-power.c
+++ b/drivers/soc/bcm/bcm2835-power.c
@@ -126,8 +126,7 @@
#define ASB_AXI_BRDG_ID 0x20
-#define ASB_READ(reg) readl(power->asb + (reg))
-#define ASB_WRITE(reg, val) writel(PM_PASSWORD | (val), power->asb + (reg))
+#define BCM2835_BRDG_ID 0x62726467
struct bcm2835_power_domain {
struct generic_pm_domain base;
@@ -142,24 +141,41 @@ 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];
struct reset_controller_dev reset;
};
-static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg)
+static int bcm2835_asb_control(struct bcm2835_power *power, u32 reg, bool enable)
{
+ void __iomem *base = power->asb;
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();
/* Enable the module's async AXI bridges. */
- ASB_WRITE(reg, ASB_READ(reg) & ~ASB_REQ_STOP);
- while (ASB_READ(reg) & ASB_ACK) {
+ if (enable) {
+ val = readl(base + reg) & ~ASB_REQ_STOP;
+ } else {
+ val = readl(base + reg) | ASB_REQ_STOP;
+ }
+ writel(PM_PASSWORD | val, base + reg);
+
+ while (readl(base + reg) & ASB_ACK) {
cpu_relax();
if (ktime_get_ns() - start >= 1000)
return -ETIMEDOUT;
@@ -168,30 +184,24 @@ static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg)
return 0;
}
-static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg)
+static int bcm2835_asb_enable(struct bcm2835_power *power, u32 reg)
{
- u64 start;
-
- if (!reg)
- return 0;
-
- start = ktime_get_ns();
-
- /* Enable the module's async AXI bridges. */
- ASB_WRITE(reg, ASB_READ(reg) | ASB_REQ_STOP);
- while (!(ASB_READ(reg) & ASB_ACK)) {
- cpu_relax();
- if (ktime_get_ns() - start >= 1000)
- return -ETIMEDOUT;
- }
+ return bcm2835_asb_control(power, reg, true);
+}
- return 0;
+static int bcm2835_asb_disable(struct bcm2835_power *power, u32 reg)
+{
+ return bcm2835_asb_control(power, reg, false);
}
static int bcm2835_power_power_off(struct bcm2835_power_domain *pd, u32 pm_reg)
{
struct bcm2835_power *power = pd->power;
+ /* We don't run this on BCM2711 */
+ if (power->rpivid_asb)
+ return 0;
+
/* Enable functional isolation */
PM_WRITE(pm_reg, PM_READ(pm_reg) & ~PM_ISFUNC);
@@ -213,6 +223,10 @@ static int bcm2835_power_power_on(struct bcm2835_power_domain *pd, u32 pm_reg)
int inrush;
bool powok;
+ /* We don't run this on BCM2711 */
+ if (power->rpivid_asb)
+ return 0;
+
/* If it was already powered on by the fw, leave it that way. */
if (PM_READ(pm_reg) & PM_POWUP)
return 0;
@@ -626,13 +640,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 = ASB_READ(ASB_AXI_BRDG_ID);
- if (id != 0x62726467 /* "BRDG" */) {
+ id = readl(power->asb + ASB_AXI_BRDG_ID);
+ 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),
diff --git a/drivers/soc/bcm/brcmstb/biuctrl.c b/drivers/soc/bcm/brcmstb/biuctrl.c
index 2c975d79fe8e..1467bbd59690 100644
--- a/drivers/soc/bcm/brcmstb/biuctrl.c
+++ b/drivers/soc/bcm/brcmstb/biuctrl.c
@@ -340,12 +340,12 @@ static int __init brcmstb_biuctrl_init(void)
ret = setup_hifcpubiuctrl_regs(np);
if (ret)
- return ret;
+ goto out_put;
ret = mcp_write_pairing_set();
if (ret) {
pr_err("MCP: Unable to disable write pairing!\n");
- return ret;
+ goto out_put;
}
a72_b53_rac_enable_all(np);
@@ -353,6 +353,9 @@ static int __init brcmstb_biuctrl_init(void)
#ifdef CONFIG_PM_SLEEP
register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
#endif
- return 0;
+ ret = 0;
+out_put:
+ of_node_put(np);
+ return ret;
}
early_initcall(brcmstb_biuctrl_init);
diff --git a/drivers/soc/bcm/brcmstb/pm/pm-arm.c b/drivers/soc/bcm/brcmstb/pm/pm-arm.c
index 70ad0f3dce28..d6b30d521307 100644
--- a/drivers/soc/bcm/brcmstb/pm/pm-arm.c
+++ b/drivers/soc/bcm/brcmstb/pm/pm-arm.c
@@ -721,7 +721,7 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
ctrl.phy_a_standby_ctrl_offs = ddr_phy_data->phy_a_standby_ctrl_offs;
ctrl.phy_b_standby_ctrl_offs = ddr_phy_data->phy_b_standby_ctrl_offs;
/*
- * Slightly grosss to use the phy ver to get a memc,
+ * Slightly gross to use the phy ver to get a memc,
* offset but that is the only versioned things so far
* we can test for.
*/