mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 22:26:55 +00:00
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: Srinivas Kandagatla <srinivas.kandagatla@linaro.org> Link: https://lore.kernel.org/r/20230525133812.30841-4-srinivas.kandagatla@linaro.org Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
9ac4a4441a
commit
671ca2ef12
1 changed files with 34 additions and 22 deletions
|
@ -790,6 +790,26 @@ static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
|
||||||
return ret;
|
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)
|
static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
|
||||||
{
|
{
|
||||||
u32 val;
|
u32 val;
|
||||||
|
@ -838,16 +858,28 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
|
||||||
SWRM_RD_WR_CMD_RETRIES);
|
SWRM_RD_WR_CMD_RETRIES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* COMP Enable */
|
||||||
|
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR, SWRM_COMP_CFG_ENABLE_MSK);
|
||||||
|
|
||||||
/* Set IRQ to PULSE */
|
/* Set IRQ to PULSE */
|
||||||
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
|
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
|
||||||
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK |
|
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK);
|
||||||
SWRM_COMP_CFG_ENABLE_MSK);
|
|
||||||
|
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CLEAR],
|
||||||
|
0xFFFFFFFF);
|
||||||
|
|
||||||
/* enable CPU IRQs */
|
/* enable CPU IRQs */
|
||||||
if (ctrl->mmio) {
|
if (ctrl->mmio) {
|
||||||
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CPU_EN],
|
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CPU_EN],
|
||||||
SWRM_INTERRUPT_STATUS_RMSK);
|
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->slave_status = 0;
|
||||||
ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
|
ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
|
||||||
ctrl->rd_fifo_depth = FIELD_GET(SWRM_COMP_PARAMS_RD_FIFO_DEPTH, 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;
|
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)
|
static int __maybe_unused swrm_runtime_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
|
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);
|
||||||
|
|
Loading…
Reference in a new issue