diff options
author | AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org> | 2021-01-13 21:38:15 +0300 |
---|---|---|
committer | Stephen Boyd <sboyd@kernel.org> | 2021-02-14 23:56:54 +0300 |
commit | 785c02eb35009a4be6dbc68f4f7d916e90b7177d (patch) | |
tree | 412f80bb07a98cf6bbf967a5de6eca05213b1c63 /drivers/clk/qcom/gdsc.c | |
parent | 68e1d106eb4dceb61bc2818d829786b364fd502b (diff) | |
download | linux-785c02eb35009a4be6dbc68f4f7d916e90b7177d.tar.xz |
clk: qcom: gdsc: Implement NO_RET_PERIPH flag
In some rare occasions, we want to only set the RETAIN_MEM bit, but
not the RETAIN_PERIPH one: this is seen on at least SDM630/636/660's
GPU-GX GDSC, where unsetting and setting back the RETAIN_PERIPH bit
will generate chaos and panics during GPU suspend time (mainly, the
chaos is unaligned access).
For this reason, introduce a new NO_RET_PERIPH flag to the GDSC
driver to address this corner case.
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@somainline.org>
Link: https://lore.kernel.org/r/20210113183817.447866-8-angelogioacchino.delregno@somainline.org
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Diffstat (limited to 'drivers/clk/qcom/gdsc.c')
-rw-r--r-- | drivers/clk/qcom/gdsc.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c index af26e0695b86..51ed640e527b 100644 --- a/drivers/clk/qcom/gdsc.c +++ b/drivers/clk/qcom/gdsc.c @@ -183,7 +183,10 @@ static inline int gdsc_assert_reset(struct gdsc *sc) static inline void gdsc_force_mem_on(struct gdsc *sc) { int i; - u32 mask = RETAIN_MEM | RETAIN_PERIPH; + u32 mask = RETAIN_MEM; + + if (!(sc->flags & NO_RET_PERIPH)) + mask |= RETAIN_PERIPH; for (i = 0; i < sc->cxc_count; i++) regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask); @@ -192,7 +195,10 @@ static inline void gdsc_force_mem_on(struct gdsc *sc) static inline void gdsc_clear_mem_on(struct gdsc *sc) { int i; - u32 mask = RETAIN_MEM | RETAIN_PERIPH; + u32 mask = RETAIN_MEM; + + if (!(sc->flags & NO_RET_PERIPH)) + mask |= RETAIN_PERIPH; for (i = 0; i < sc->cxc_count; i++) regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0); |