aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>2022-10-05 15:46:10 +0100
committerManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>2023-01-24 12:10:18 +0530
commit0324da1cd9e3bab828bc3000239b578d746656fe (patch)
treee3e3a030e74850341737fb5d3e3a75fc85b95e4d
parent701c1d02e9e0321c95d659b62e00a66a9559abbb (diff)
soundwire: qcom: wait for fifo to be empty before
Wait for Fifo to be empty before going to suspend or before bank switch happens. Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
-rw-r--r--drivers/soundwire/qcom.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index a2395949faaf..fcc279bd5a97 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -325,6 +325,32 @@ static int swrm_wait_for_wr_fifo_avail(struct qcom_swrm_ctrl *swrm)
return 0;
}
+static bool swrm_wait_for_wr_fifo_done(struct qcom_swrm_ctrl *swrm)
+{
+ u32 fifo_outstanding_cmds, value;
+ int fifo_retry_count = SWR_OVERFLOW_RETRY_COUNT*2;
+
+ /* Check for fifo overflow during write */
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmds = FIELD_GET(SWRM_WR_CMD_FIFO_CNT_MASK, value);
+
+ if (fifo_outstanding_cmds) {
+ while (fifo_retry_count) {
+ usleep_range(500, 510);
+ swrm->reg_read(swrm, SWRM_CMD_FIFO_STATUS, &value);
+ fifo_outstanding_cmds = FIELD_GET(SWRM_WR_CMD_FIFO_CNT_MASK, value);
+ fifo_retry_count--;
+ if (fifo_outstanding_cmds == 0)
+ return true;
+ }
+ } else {
+ return true;
+ }
+
+
+ return false;
+}
+
static int qcom_swrm_cmd_fifo_wr_cmd(struct qcom_swrm_ctrl *swrm, u8 cmd_data,
u8 dev_addr, u16 reg_addr)
{
@@ -358,6 +384,7 @@ static int qcom_swrm_cmd_fifo_wr_cmd(struct qcom_swrm_ctrl *swrm, u8 cmd_data,
swrm_wait_for_wr_fifo_done(swrm);
if (cmd_id == SWR_BROADCAST_CMD_ID) {
+ swrm_wait_for_wr_fifo_done(swrm);
/*
* sleep for 10ms for MSM soundwire variant to allow broadcast
* command to complete.
@@ -1124,6 +1151,7 @@ static void qcom_swrm_shutdown(struct snd_pcm_substream *substream,
{
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dai->dev);
+ swrm_wait_for_wr_fifo_done(ctrl);
sdw_release_stream(ctrl->sruntime[dai->id]);
ctrl->sruntime[dai->id] = NULL;
pm_runtime_mark_last_busy(ctrl->dev);
@@ -1560,6 +1588,7 @@ static int __maybe_unused swrm_runtime_suspend(struct device *dev)
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
int ret;
+ swrm_wait_for_wr_fifo_done(ctrl);
if (!ctrl->clock_stop_not_supported) {
/* Mask bus clash interrupt */
ctrl->intr_mask &= ~SWRM_INTERRUPT_STATUS_MASTER_CLASH_DET;