From 785c02eb35009a4be6dbc68f4f7d916e90b7177d Mon Sep 17 00:00:00 2001 From: AngeloGioacchino Del Regno Date: Wed, 13 Jan 2021 19:38:15 +0100 Subject: 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 Link: https://lore.kernel.org/r/20210113183817.447866-8-angelogioacchino.delregno@somainline.org Signed-off-by: Stephen Boyd --- drivers/clk/qcom/gdsc.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers/clk/qcom/gdsc.c') 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); -- cgit v1.2.3