Commit 2a93c6cb authored by Bjorn Andersson's avatar Bjorn Andersson Committed by Ulf Hansson

pmdomain: qcom: rpmhpd: Fix enabled_corner aggregation

Commit 'e3e56c05 ("soc: qcom: rpmhpd: Make power_on actually enable
the domain")' aimed to make sure that a power-domain that is being
enabled without any particular performance-state requested will at least
turn the rail on, to avoid filling DeviceTree with otherwise unnecessary
required-opps properties.

But in the event that aggregation happens on a disabled power-domain, with
an enabled peer without performance-state, both the local and peer
corner are 0. The peer's enabled_corner is not considered, with the
result that the underlying (shared) resource is disabled.

One case where this can be observed is when the display stack keeps mmcx
enabled (but without a particular performance-state vote) in order to
access registers and sync_state happens in the rpmhpd driver. As mmcx_ao
is flushed the state of the peer (mmcx) is not considered and mmcx_ao
ends up turning off "mmcx.lvl" underneath mmcx. This has been observed
several times, but has been painted over in DeviceTree by adding an
explicit vote for the lowest non-disabled performance-state.

Fixes: e3e56c05 ("soc: qcom: rpmhpd: Make power_on actually enable the domain")
Reported-by: default avatarJohan Hovold <johan@kernel.org>
Closes: https://lore.kernel.org/linux-arm-msm/ZdMwZa98L23mu3u6@hovoldconsulting.com/
Cc:  <stable@vger.kernel.org>
Signed-off-by: default avatarBjorn Andersson <quic_bjorande@quicinc.com>
Reviewed-by: default avatarKonrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Tested-by: default avatarDmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: default avatarAbhinav Kumar <quic_abhinavk@quicinc.com>
Reviewed-by: default avatarStephen Boyd <swboyd@chromium.org>
Tested-by: default avatarJohan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20240226-rpmhpd-enable-corner-fix-v1-1-68c004cec48c@quicinc.comSigned-off-by: default avatarUlf Hansson <ulf.hansson@linaro.org>
parent eb5555d4
......@@ -692,6 +692,7 @@ static int rpmhpd_aggregate_corner(struct rpmhpd *pd, unsigned int corner)
unsigned int active_corner, sleep_corner;
unsigned int this_active_corner = 0, this_sleep_corner = 0;
unsigned int peer_active_corner = 0, peer_sleep_corner = 0;
unsigned int peer_enabled_corner;
if (pd->state_synced) {
to_active_sleep(pd, corner, &this_active_corner, &this_sleep_corner);
......@@ -701,9 +702,11 @@ static int rpmhpd_aggregate_corner(struct rpmhpd *pd, unsigned int corner)
this_sleep_corner = pd->level_count - 1;
}
if (peer && peer->enabled)
to_active_sleep(peer, peer->corner, &peer_active_corner,
if (peer && peer->enabled) {
peer_enabled_corner = max(peer->corner, peer->enable_corner);
to_active_sleep(peer, peer_enabled_corner, &peer_active_corner,
&peer_sleep_corner);
}
active_corner = max(this_active_corner, peer_active_corner);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment