Commit 671ca2ef authored by Srinivas Kandagatla's avatar Srinivas Kandagatla Committed by Vinod Koul

soundwire: qcom: add software workaround for bus clash interrupt assertion

Sometimes Hard reset does not clear some of the registers,
this sometimes results in firing a bus clash interrupt.
Add workaround for this during power up sequence, as
suggested by hardware manual.
Signed-off-by: default avatarSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20230525133812.30841-4-srinivas.kandagatla@linaro.orgSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
parent 9ac4a444
......@@ -790,6 +790,26 @@ static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
return ret;
}
static bool swrm_wait_for_frame_gen_enabled(struct qcom_swrm_ctrl *ctrl)
{
int retry = SWRM_LINK_STATUS_RETRY_CNT;
int comp_sts;
do {
ctrl->reg_read(ctrl, SWRM_COMP_STATUS, &comp_sts);
if (comp_sts & SWRM_FRM_GEN_ENABLED)
return true;
usleep_range(500, 510);
} while (retry--);
dev_err(ctrl->dev, "%s: link status not %s\n", __func__,
comp_sts & SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
return false;
}
static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
{
u32 val;
......@@ -838,16 +858,28 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
SWRM_RD_WR_CMD_RETRIES);
}
/* COMP Enable */
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR, SWRM_COMP_CFG_ENABLE_MSK);
/* Set IRQ to PULSE */
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK |
SWRM_COMP_CFG_ENABLE_MSK);
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK);
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CLEAR],
0xFFFFFFFF);
/* enable CPU IRQs */
if (ctrl->mmio) {
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CPU_EN],
SWRM_INTERRUPT_STATUS_RMSK);
}
/* Set IRQ to PULSE */
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK |
SWRM_COMP_CFG_ENABLE_MSK);
swrm_wait_for_frame_gen_enabled(ctrl);
ctrl->slave_status = 0;
ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
ctrl->rd_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_RD_FIFO_DEPTH, val);
......@@ -1623,26 +1655,6 @@ static int qcom_swrm_remove(struct platform_device *pdev)
return 0;
}
static bool swrm_wait_for_frame_gen_enabled(struct qcom_swrm_ctrl *ctrl)
{
int retry = SWRM_LINK_STATUS_RETRY_CNT;
int comp_sts;
do {
ctrl->reg_read(ctrl, SWRM_COMP_STATUS, &comp_sts);
if (comp_sts & SWRM_FRM_GEN_ENABLED)
return true;
usleep_range(500, 510);
} while (retry--);
dev_err(ctrl->dev, "%s: link status not %s\n", __func__,
comp_sts & SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
return false;
}
static int __maybe_unused swrm_runtime_resume(struct device *dev)
{
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
......
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