Skip to content

Commit b8cb082

Browse files
hoshinolinajannau
authored andcommitted
soc: apple: pmgr: Add force-disable/force-reset
It seems some ISP power states should have their force disable device access flag set when powered down (which may avoid this problem, but we're still figuring that out), and on some bit 12 is also explicitly set before shutdown. Add two properties to handle this case. Signed-off-by: Asahi Lina <lina@asahilina.net>
1 parent 6ca292e commit b8cb082

1 file changed

Lines changed: 37 additions & 6 deletions

File tree

drivers/pmdomain/apple/pmgr-pwrstate.c

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
#define APPLE_PMGR_AUTO_ENABLE BIT(28)
2222
#define APPLE_PMGR_PS_AUTO GENMASK(27, 24)
2323
#define APPLE_PMGR_PS_MIN GENMASK(19, 16)
24-
#define APPLE_PMGR_PARENT_OFF BIT(11)
24+
#define APPLE_PMGR_PS_RESET BIT(12)
25+
#define APPLE_PMGR_BUSY BIT(11)
2526
#define APPLE_PMGR_DEV_DISABLE BIT(10)
2627
#define APPLE_PMGR_WAS_CLKGATED BIT(9)
2728
#define APPLE_PMGR_WAS_PWRGATED BIT(8)
@@ -44,6 +45,8 @@ struct apple_pmgr_ps {
4445
struct regmap *regmap;
4546
u32 offset;
4647
u32 min_state;
48+
bool force_disable;
49+
bool force_reset;
4750
};
4851

4952
#define genpd_to_apple_pmgr_ps(_genpd) container_of(_genpd, struct apple_pmgr_ps, genpd)
@@ -53,7 +56,7 @@ static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool a
5356
{
5457
int ret;
5558
struct apple_pmgr_ps *ps = genpd_to_apple_pmgr_ps(genpd);
56-
u32 reg;
59+
u32 reg, cur;
5760

5861
ret = regmap_read(ps->regmap, ps->offset, &reg);
5962
if (ret < 0)
@@ -64,24 +67,46 @@ static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool a
6467
dev_err(ps->dev, "PS %s: powering off with RESET active\n",
6568
genpd->name);
6669

67-
reg &= ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET);
70+
if (pstate != APPLE_PMGR_PS_ACTIVE && (ps->force_disable || ps->force_reset)) {
71+
u32 reg_pre = reg & ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS);
72+
73+
if (ps->force_disable)
74+
reg_pre |= APPLE_PMGR_DEV_DISABLE;
75+
if (ps->force_reset)
76+
reg_pre |= APPLE_PMGR_PS_RESET;
77+
78+
regmap_write(ps->regmap, ps->offset, reg_pre);
79+
80+
ret = regmap_read_poll_timeout_atomic(
81+
ps->regmap, ps->offset, cur,
82+
(cur & (APPLE_PMGR_DEV_DISABLE | APPLE_PMGR_PS_RESET)) ==
83+
(reg_pre & (APPLE_PMGR_DEV_DISABLE | APPLE_PMGR_PS_RESET)), 1,
84+
APPLE_PMGR_PS_SET_TIMEOUT);
85+
86+
if (ret < 0)
87+
dev_err(ps->dev, "PS %s: Failed to set reset/disable bits (now: 0x%x)\n",
88+
genpd->name, reg);
89+
}
90+
91+
reg &= ~(APPLE_PMGR_DEV_DISABLE | APPLE_PMGR_PS_RESET |
92+
APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET);
6893
reg |= FIELD_PREP(APPLE_PMGR_PS_TARGET, pstate);
6994

7095
dev_dbg(ps->dev, "PS %s: pwrstate = 0x%x: 0x%x\n", genpd->name, pstate, reg);
7196

7297
regmap_write(ps->regmap, ps->offset, reg);
7398

7499
ret = regmap_read_poll_timeout_atomic(
75-
ps->regmap, ps->offset, reg,
76-
(FIELD_GET(APPLE_PMGR_PS_ACTUAL, reg) == pstate), 1,
100+
ps->regmap, ps->offset, cur,
101+
FIELD_GET(APPLE_PMGR_PS_ACTUAL, cur) == pstate, 1,
77102
APPLE_PMGR_PS_SET_TIMEOUT);
103+
78104
if (ret < 0)
79105
dev_err(ps->dev, "PS %s: Failed to reach power state 0x%x (now: 0x%x)\n",
80106
genpd->name, pstate, reg);
81107

82108
if (auto_enable) {
83109
/* Not all devices implement this; this is a no-op where not implemented. */
84-
reg &= ~APPLE_PMGR_FLAGS;
85110
reg |= APPLE_PMGR_AUTO_ENABLE;
86111
regmap_write(ps->regmap, ps->offset, reg);
87112
}
@@ -244,6 +269,12 @@ static int apple_pmgr_ps_probe(struct platform_device *pdev)
244269
}
245270
}
246271

272+
if (of_property_read_bool(node, "apple,force-disable"))
273+
ps->force_disable = true;
274+
275+
if (of_property_read_bool(node, "apple,force-reset"))
276+
ps->force_reset = true;
277+
247278
/* Turn on auto-PM if the domain is already on */
248279
if (active)
249280
regmap_update_bits(regmap, ps->offset, APPLE_PMGR_FLAGS | APPLE_PMGR_AUTO_ENABLE,

0 commit comments

Comments
 (0)