Skip to content

Commit 671ca2e

Browse files
Srinivas-Kandagatlavinodkoul
authored andcommitted
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>
1 parent 9ac4a44 commit 671ca2e

1 file changed

Lines changed: 34 additions & 22 deletions

File tree

drivers/soundwire/qcom.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,26 @@ static irqreturn_t qcom_swrm_irq_handler(int irq, void *dev_id)
790790
return ret;
791791
}
792792

793+
static bool swrm_wait_for_frame_gen_enabled(struct qcom_swrm_ctrl *ctrl)
794+
{
795+
int retry = SWRM_LINK_STATUS_RETRY_CNT;
796+
int comp_sts;
797+
798+
do {
799+
ctrl->reg_read(ctrl, SWRM_COMP_STATUS, &comp_sts);
800+
801+
if (comp_sts & SWRM_FRM_GEN_ENABLED)
802+
return true;
803+
804+
usleep_range(500, 510);
805+
} while (retry--);
806+
807+
dev_err(ctrl->dev, "%s: link status not %s\n", __func__,
808+
comp_sts & SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
809+
810+
return false;
811+
}
812+
793813
static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
794814
{
795815
u32 val;
@@ -838,16 +858,28 @@ static int qcom_swrm_init(struct qcom_swrm_ctrl *ctrl)
838858
SWRM_RD_WR_CMD_RETRIES);
839859
}
840860

861+
/* COMP Enable */
862+
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR, SWRM_COMP_CFG_ENABLE_MSK);
863+
841864
/* Set IRQ to PULSE */
842865
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
843-
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK |
844-
SWRM_COMP_CFG_ENABLE_MSK);
866+
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK);
867+
868+
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CLEAR],
869+
0xFFFFFFFF);
845870

846871
/* enable CPU IRQs */
847872
if (ctrl->mmio) {
848873
ctrl->reg_write(ctrl, ctrl->reg_layout[SWRM_REG_INTERRUPT_CPU_EN],
849874
SWRM_INTERRUPT_STATUS_RMSK);
850875
}
876+
877+
/* Set IRQ to PULSE */
878+
ctrl->reg_write(ctrl, SWRM_COMP_CFG_ADDR,
879+
SWRM_COMP_CFG_IRQ_LEVEL_OR_PULSE_MSK |
880+
SWRM_COMP_CFG_ENABLE_MSK);
881+
882+
swrm_wait_for_frame_gen_enabled(ctrl);
851883
ctrl->slave_status = 0;
852884
ctrl->reg_read(ctrl, SWRM_COMP_PARAMS, &val);
853885
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)
16231655
return 0;
16241656
}
16251657

1626-
static bool swrm_wait_for_frame_gen_enabled(struct qcom_swrm_ctrl *ctrl)
1627-
{
1628-
int retry = SWRM_LINK_STATUS_RETRY_CNT;
1629-
int comp_sts;
1630-
1631-
do {
1632-
ctrl->reg_read(ctrl, SWRM_COMP_STATUS, &comp_sts);
1633-
1634-
if (comp_sts & SWRM_FRM_GEN_ENABLED)
1635-
return true;
1636-
1637-
usleep_range(500, 510);
1638-
} while (retry--);
1639-
1640-
dev_err(ctrl->dev, "%s: link status not %s\n", __func__,
1641-
comp_sts & SWRM_FRM_GEN_ENABLED ? "connected" : "disconnected");
1642-
1643-
return false;
1644-
}
1645-
16461658
static int __maybe_unused swrm_runtime_resume(struct device *dev)
16471659
{
16481660
struct qcom_swrm_ctrl *ctrl = dev_get_drvdata(dev);

0 commit comments

Comments
 (0)