diff options
| author | Neil Armstrong <neil.armstrong@linaro.org> | 2024-09-03 18:13:30 +0200 |
|---|---|---|
| committer | Caleb Connolly <caleb.connolly@linaro.org> | 2024-09-06 10:47:46 +0200 |
| commit | fdbd2fa400f5cb994d7c686cdb665b4c601796d8 (patch) | |
| tree | 7451ecee157f37ecb04dd07ac8942feaba9cd812 /drivers/soc | |
| parent | a01ed791c9d16ec07c02deb94dd9732df6eab96a (diff) | |
soc: qcom: rpmh-rsc: add back __tcs_set_trigger() for SM8550/SM8650
The TCS writes has no effect after the removal of the __tcs_set_trigger()
call, obviously it seems the RSC version 3 requires it to complete the transactions.
Fixes: 80c5be164ad ("soc: qcom: rpmh-rsc: drop unused multi-threading and non-active TCS support")
Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
Tested-by: Caleb Connolly <caleb.connolly@linaro.org> # sm8250 rb5
Reviewed-by: Caleb Connolly <caleb.connolly@linaro.org>
Diffstat (limited to 'drivers/soc')
| -rw-r--r-- | drivers/soc/qcom/rpmh-rsc.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index 61fb2e69558..aee9e55194e 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -294,6 +294,48 @@ static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id, } /** + * __tcs_set_trigger() - Start xfer on a TCS or unset trigger on a borrowed TCS + * @drv: The controller. + * @tcs_id: The global ID of this TCS. + * @trigger: If true then untrigger/retrigger. If false then just untrigger. + * + * In the normal case we only ever call with "trigger=true" to start a + * transfer. That will un-trigger/disable the TCS from the last transfer + * then trigger/enable for this transfer. + * + * If we borrowed a wake TCS for an active-only transfer we'll also call + * this function with "trigger=false" to just do the un-trigger/disable + * before using the TCS for wake purposes again. + * + * Note that the AP is only in charge of triggering active-only transfers. + * The AP never triggers sleep/wake values using this function. + */ +static void __tcs_set_trigger(struct rsc_drv *drv, int tcs_id, bool trigger) +{ + u32 enable; + u32 reg = drv->regs[RSC_DRV_CONTROL]; + + /* + * HW req: Clear the DRV_CONTROL and enable TCS again + * While clearing ensure that the AMC mode trigger is cleared + * and then the mode enable is cleared. + */ + enable = read_tcs_reg(drv, reg, tcs_id); + enable &= ~TCS_AMC_MODE_TRIGGER; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable &= ~TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + + if (trigger) { + /* Enable the AMC mode on the TCS and then trigger the TCS */ + enable = TCS_AMC_MODE_ENABLE; + write_tcs_reg_sync(drv, reg, tcs_id, enable); + enable |= TCS_AMC_MODE_TRIGGER; + write_tcs_reg(drv, reg, tcs_id, enable); + } +} + +/** * rpmh_rsc_send_data() - Write / trigger active-only message. * @drv: The controller. * @msg: The data to be sent. @@ -348,6 +390,7 @@ int rpmh_rsc_send_data(struct rsc_drv *drv, const struct tcs_request *msg) * of __tcs_set_trigger() below. */ __tcs_buffer_write(drv, tcs_id, 0, msg); + __tcs_set_trigger(drv, tcs_id, true); /* U-Boot: Now wait for the TCS to be cleared, indicating that we're done */ for (i = 0; i < USEC_PER_SEC; i++) { |
