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,9 @@ struct apple_pmgr_ps {
4445 struct regmap * regmap ;
4546 u32 offset ;
4647 u32 min_state ;
48+ bool force_disable ;
49+ bool force_reset ;
50+ bool externally_clocked ;
4751};
4852
4953#define genpd_to_apple_pmgr_ps (_genpd ) container_of(_genpd, struct apple_pmgr_ps, genpd)
@@ -53,7 +57,7 @@ static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool a
5357{
5458 int ret ;
5559 struct apple_pmgr_ps * ps = genpd_to_apple_pmgr_ps (genpd );
56- u32 reg ;
60+ u32 reg , cur ;
5761
5862 ret = regmap_read (ps -> regmap , ps -> offset , & reg );
5963 if (ret < 0 )
@@ -64,24 +68,57 @@ static int apple_pmgr_ps_set(struct generic_pm_domain *genpd, u32 pstate, bool a
6468 dev_err (ps -> dev , "PS %s: powering off with RESET active\n" ,
6569 genpd -> name );
6670
67- reg &= ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET );
71+ if (pstate != APPLE_PMGR_PS_ACTIVE && (ps -> force_disable || ps -> force_reset )) {
72+ u32 reg_pre = reg & ~(APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS );
73+
74+ if (ps -> force_disable )
75+ reg_pre |= APPLE_PMGR_DEV_DISABLE ;
76+ if (ps -> force_reset )
77+ reg_pre |= APPLE_PMGR_PS_RESET ;
78+
79+ regmap_write (ps -> regmap , ps -> offset , reg_pre );
80+
81+ ret = regmap_read_poll_timeout_atomic (
82+ ps -> regmap , ps -> offset , cur ,
83+ (cur & (APPLE_PMGR_DEV_DISABLE | APPLE_PMGR_PS_RESET )) ==
84+ (reg_pre & (APPLE_PMGR_DEV_DISABLE | APPLE_PMGR_PS_RESET )), 1 ,
85+ APPLE_PMGR_PS_SET_TIMEOUT );
86+
87+ if (ret < 0 )
88+ dev_err (ps -> dev , "PS %s: Failed to set reset/disable bits (now: 0x%x)\n" ,
89+ genpd -> name , reg );
90+ }
91+
92+ reg &= ~(APPLE_PMGR_DEV_DISABLE | APPLE_PMGR_PS_RESET |
93+ APPLE_PMGR_AUTO_ENABLE | APPLE_PMGR_FLAGS | APPLE_PMGR_PS_TARGET );
6894 reg |= FIELD_PREP (APPLE_PMGR_PS_TARGET , pstate );
6995
7096 dev_dbg (ps -> dev , "PS %s: pwrstate = 0x%x: 0x%x\n" , genpd -> name , pstate , reg );
7197
7298 regmap_write (ps -> regmap , ps -> offset , reg );
7399
74- ret = regmap_read_poll_timeout_atomic (
75- ps -> regmap , ps -> offset , reg ,
76- (FIELD_GET (APPLE_PMGR_PS_ACTUAL , reg ) == pstate ), 1 ,
77- APPLE_PMGR_PS_SET_TIMEOUT );
100+ if (ps -> externally_clocked && pstate == APPLE_PMGR_PS_ACTIVE ) {
101+ /*
102+ * If this clock domain requires an external clock, then
103+ * consider the "clock gated" state to be good enough.
104+ */
105+ ret = regmap_read_poll_timeout_atomic (
106+ ps -> regmap , ps -> offset , cur ,
107+ FIELD_GET (APPLE_PMGR_PS_ACTUAL , cur ) >= APPLE_PMGR_PS_CLKGATE , 1 ,
108+ APPLE_PMGR_PS_SET_TIMEOUT );
109+ } else {
110+ ret = regmap_read_poll_timeout_atomic (
111+ ps -> regmap , ps -> offset , cur ,
112+ FIELD_GET (APPLE_PMGR_PS_ACTUAL , cur ) == pstate , 1 ,
113+ APPLE_PMGR_PS_SET_TIMEOUT );
114+ }
115+
78116 if (ret < 0 )
79117 dev_err (ps -> dev , "PS %s: Failed to reach power state 0x%x (now: 0x%x)\n" ,
80118 genpd -> name , pstate , reg );
81119
82120 if (auto_enable ) {
83121 /* Not all devices implement this; this is a no-op where not implemented. */
84- reg &= ~APPLE_PMGR_FLAGS ;
85122 reg |= APPLE_PMGR_AUTO_ENABLE ;
86123 regmap_write (ps -> regmap , ps -> offset , reg );
87124 }
@@ -234,6 +271,15 @@ static int apple_pmgr_ps_probe(struct platform_device *pdev)
234271 regmap_update_bits (regmap , ps -> offset , APPLE_PMGR_FLAGS | APPLE_PMGR_PS_MIN ,
235272 FIELD_PREP (APPLE_PMGR_PS_MIN , ps -> min_state ));
236273
274+ if (of_property_read_bool (node , "apple,force-disable" ))
275+ ps -> force_disable = true;
276+
277+ if (of_property_read_bool (node , "apple,force-reset" ))
278+ ps -> force_reset = true;
279+
280+ if (of_property_read_bool (node , "apple,externally-clocked" ))
281+ ps -> externally_clocked = true;
282+
237283 active = apple_pmgr_ps_is_active (ps );
238284 if (of_property_read_bool (node , "apple,always-on" )) {
239285 ps -> genpd .flags |= GENPD_FLAG_ALWAYS_ON ;
0 commit comments