clk: qcom: gdsc: Fix the handling of PWRSTS_RET support
authorRajendra Nayak <quic_rjendra@quicinc.com>
Tue, 20 Sep 2022 11:15:15 +0000 (16:45 +0530)
committerBjorn Andersson <andersson@kernel.org>
Wed, 28 Sep 2022 02:58:38 +0000 (21:58 -0500)
GDSCs cannot be transitioned into a Retention state in SW.
When either the RETAIN_MEM bit, or both the RETAIN_MEM and
RETAIN_PERIPH bits are set, and the GDSC is left ON, the HW
takes care of retaining the memory/logic for the domain when
the parent domain transitions to power collapse/power off state.

On some platforms where the parent domains lowest power state
itself is Retention, just leaving the GDSC in ON (without any
RETAIN_MEM/RETAIN_PERIPH bits being set) will also transition
it to Retention.

The existing logic handling the PWRSTS_RET seems to set the
RETAIN_MEM/RETAIN_PERIPH bits if the cxcs offsets are specified
but then explicitly turns the GDSC OFF as part of _gdsc_disable().
Fix that by leaving the GDSC in ON state.

Signed-off-by: Rajendra Nayak <quic_rjendra@quicinc.com>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Bjorn Andersson <andersson@kernel.org>
Link: https://lore.kernel.org/r/20220920111517.10407-1-quic_rjendra@quicinc.com
drivers/clk/qcom/gdsc.c
drivers/clk/qcom/gdsc.h

index d3244006c661a90eb4d00763fefc15cfa6f75142..ccf63771e852da1af5d2b4e8715447a57debb402 100644 (file)
@@ -368,6 +368,16 @@ static int _gdsc_disable(struct gdsc *sc)
        if (sc->pwrsts & PWRSTS_OFF)
                gdsc_clear_mem_on(sc);
 
+       /*
+        * If the GDSC supports only a Retention state, apart from ON,
+        * leave it in ON state.
+        * There is no SW control to transition the GDSC into
+        * Retention state. This happens in HW when the parent
+        * domain goes down to a Low power state
+        */
+       if (sc->pwrsts == PWRSTS_RET_ON)
+               return 0;
+
        ret = gdsc_toggle_logic(sc, GDSC_OFF);
        if (ret)
                return ret;
index 5de48c9439b29af03d208bef151a61f0d024bee6..981a12c8502d9c4b353657ee96467f8883cf875a 100644 (file)
@@ -49,6 +49,11 @@ struct gdsc {
        const u8                        pwrsts;
 /* Powerdomain allowable state bitfields */
 #define PWRSTS_OFF             BIT(0)
+/*
+ * There is no SW control to transition a GDSC into
+ * PWRSTS_RET. This happens in HW when the parent
+ * domain goes down to a low power state
+ */
 #define PWRSTS_RET             BIT(1)
 #define PWRSTS_ON              BIT(2)
 #define PWRSTS_OFF_ON          (PWRSTS_OFF | PWRSTS_ON)