Skip to content

Commit e892e17

Browse files
Amit Nischalbebarino
authored andcommitted
clk: qcom: gdsc: Add support to poll CFG register to check GDSC state
The default behavior of the GDSC enable/disable sequence is to poll the status bits of either the actual GDSCR or the corresponding HW_CTRL registers. On targets which have support for a CFG_GDSCR register, the status bits might not show the correct state of the GDSC, especially in the disable sequence, where the status bit will be cleared even before the core is completely power collapsed. On targets with this issue, poll the power on/off bits in the CFG_GDSCR register instead to correctly determine the GDSC state. Signed-off-by: Amit Nischal <anischal@codeaurora.org> Signed-off-by: Taniya Das <tdas@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@kernel.org>
1 parent 9fb38ca commit e892e17

File tree

2 files changed

+27
-16
lines changed

2 files changed

+27
-16
lines changed

drivers/clk/qcom/gdsc.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333
#define GMEM_CLAMP_IO_MASK BIT(0)
3434
#define GMEM_RESET_MASK BIT(4)
3535

36+
/* CFG_GDSCR */
37+
#define GDSC_POWER_UP_COMPLETE BIT(16)
38+
#define GDSC_POWER_DOWN_COMPLETE BIT(15)
39+
#define CFG_GDSCR_OFFSET 0x4
40+
3641
/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
3742
#define EN_REST_WAIT_VAL (0x2 << 20)
3843
#define EN_FEW_WAIT_VAL (0x8 << 16)
@@ -45,15 +50,28 @@
4550

4651
#define domain_to_gdsc(domain) container_of(domain, struct gdsc, pd)
4752

48-
static int gdsc_is_enabled(struct gdsc *sc, unsigned int reg)
53+
static int gdsc_is_enabled(struct gdsc *sc, bool en)
4954
{
55+
unsigned int reg;
5056
u32 val;
5157
int ret;
5258

59+
if (sc->flags & POLL_CFG_GDSCR)
60+
reg = sc->gdscr + CFG_GDSCR_OFFSET;
61+
else
62+
reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
63+
5364
ret = regmap_read(sc->regmap, reg, &val);
5465
if (ret)
5566
return ret;
5667

68+
if (sc->flags & POLL_CFG_GDSCR) {
69+
if (en)
70+
return !!(val & GDSC_POWER_UP_COMPLETE);
71+
else
72+
return !(val & GDSC_POWER_DOWN_COMPLETE);
73+
}
74+
5775
return !!(val & PWR_ON_MASK);
5876
}
5977

@@ -64,17 +82,17 @@ static int gdsc_hwctrl(struct gdsc *sc, bool en)
6482
return regmap_update_bits(sc->regmap, sc->gdscr, HW_CONTROL_MASK, val);
6583
}
6684

67-
static int gdsc_poll_status(struct gdsc *sc, unsigned int reg, bool en)
85+
static int gdsc_poll_status(struct gdsc *sc, bool en)
6886
{
6987
ktime_t start;
7088

7189
start = ktime_get();
7290
do {
73-
if (gdsc_is_enabled(sc, reg) == en)
91+
if (gdsc_is_enabled(sc, en) == en)
7492
return 0;
7593
} while (ktime_us_delta(ktime_get(), start) < TIMEOUT_US);
7694

77-
if (gdsc_is_enabled(sc, reg) == en)
95+
if (gdsc_is_enabled(sc, en) == en)
7896
return 0;
7997

8098
return -ETIMEDOUT;
@@ -84,7 +102,6 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
84102
{
85103
int ret;
86104
u32 val = en ? 0 : SW_COLLAPSE_MASK;
87-
unsigned int status_reg = sc->gdscr;
88105

89106
ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
90107
if (ret)
@@ -101,8 +118,7 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
101118
return 0;
102119
}
103120

104-
if (sc->gds_hw_ctrl) {
105-
status_reg = sc->gds_hw_ctrl;
121+
if (sc->gds_hw_ctrl)
106122
/*
107123
* The gds hw controller asserts/de-asserts the status bit soon
108124
* after it receives a power on/off request from a master.
@@ -114,9 +130,8 @@ static int gdsc_toggle_logic(struct gdsc *sc, bool en)
114130
* and polling the status bit.
115131
*/
116132
udelay(1);
117-
}
118133

119-
return gdsc_poll_status(sc, status_reg, en);
134+
return gdsc_poll_status(sc, en);
120135
}
121136

122137
static inline int gdsc_deassert_reset(struct gdsc *sc)
@@ -240,8 +255,6 @@ static int gdsc_disable(struct generic_pm_domain *domain)
240255

241256
/* Turn off HW trigger mode if supported */
242257
if (sc->flags & HW_CTRL) {
243-
unsigned int reg;
244-
245258
ret = gdsc_hwctrl(sc, false);
246259
if (ret < 0)
247260
return ret;
@@ -253,8 +266,7 @@ static int gdsc_disable(struct generic_pm_domain *domain)
253266
*/
254267
udelay(1);
255268

256-
reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
257-
ret = gdsc_poll_status(sc, reg, true);
269+
ret = gdsc_poll_status(sc, true);
258270
if (ret)
259271
return ret;
260272
}
@@ -276,7 +288,6 @@ static int gdsc_init(struct gdsc *sc)
276288
{
277289
u32 mask, val;
278290
int on, ret;
279-
unsigned int reg;
280291

281292
/*
282293
* Disable HW trigger: collapse/restore occur based on registers writes.
@@ -297,8 +308,7 @@ static int gdsc_init(struct gdsc *sc)
297308
return ret;
298309
}
299310

300-
reg = sc->gds_hw_ctrl ? sc->gds_hw_ctrl : sc->gdscr;
301-
on = gdsc_is_enabled(sc, reg);
311+
on = gdsc_is_enabled(sc, true);
302312
if (on < 0)
303313
return on;
304314

drivers/clk/qcom/gdsc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ struct gdsc {
5555
#define HW_CTRL BIT(2)
5656
#define SW_RESET BIT(3)
5757
#define AON_RESET BIT(4)
58+
#define POLL_CFG_GDSCR BIT(5)
5859
struct reset_controller_dev *rcdev;
5960
unsigned int *resets;
6061
unsigned int reset_count;

0 commit comments

Comments
 (0)