diff mbox series

[1/2] soc: qcom: rpmh-rsc: add back __tcs_set_trigger() for SM8550/SM8650

Message ID 20240903-topic-sm8x50-regulators-support-v1-1-0857185bddc0@linaro.org
State Accepted
Commit fdbd2fa400f5cb994d7c686cdb665b4c601796d8
Headers show
Series regulators: qcom-rpmh: support SM8550 and SM8650 platforms | expand

Commit Message

Neil Armstrong Sept. 3, 2024, 4:13 p.m. UTC
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>
---
 drivers/soc/qcom/rpmh-rsc.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)
diff mbox series

Patch

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
@@ -293,6 +293,48 @@  static void __tcs_buffer_write(struct rsc_drv *drv, int tcs_id, int cmd_id,
 	write_tcs_reg(drv, drv->regs[RSC_DRV_CMD_ENABLE], tcs_id, cmd_enable);
 }
 
+/**
+ * __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.
@@ -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++) {