From eac435a0a2a6df3199bb8ee7029ac92256283459 Mon Sep 17 00:00:00 2001 From: Abhinab Abhinab Date: Mon, 10 May 2021 17:13:45 +0530 Subject: [PATCH] msm: mhi_dev: Disabling Ch Db Intr during MHI INIT phase In order to tackle the spurious interrupts coming from the host on an invalid channel, the channel doorbell interrupts are disabled during initialization phase. These are enabled after receiving the start command for a particular channel. Change-Id: I12bb315bcd249383ed442ad969e84c9eef25a324 Signed-off-by: Abhinab Abhinab Signed-off-by: Gauri Joshi --- drivers/platform/msm/mhi_dev/mhi.c | 49 ++++++++++++++----------- drivers/platform/msm/mhi_dev/mhi_mmio.c | 27 ++++++++++++-- 2 files changed, 51 insertions(+), 25 deletions(-) diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index b9866a4182e9..b7662d475f95 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -1349,13 +1349,7 @@ static int mhi_enable_int(void) int rc = 0; mhi_log(MHI_MSG_VERBOSE, - "Enable chdb, ctrl and cmdb interrupts\n"); - - rc = mhi_dev_mmio_enable_chdb_interrupts(mhi_ctx); - if (rc) { - pr_err("Failed to enable channel db: %d\n", rc); - return rc; - } + "Enable ctrl and cmdb interrupts\n"); rc = mhi_dev_mmio_enable_ctrl_interrupt(mhi_ctx); if (rc) { @@ -1840,6 +1834,18 @@ static void mhi_dev_process_reset_cmd(struct mhi_dev *mhi, int ch_id) struct mhi_dev_channel *ch; struct mhi_addr host_addr; + rc = mhi_dev_mmio_disable_chdb_a7(mhi, ch_id); + if (rc) { + mhi_log(MHI_MSG_VERBOSE, + "Failed to disable chdb for ch %d\n", ch_id); + rc = mhi_dev_send_cmd_comp_event(mhi, + MHI_CMD_COMPL_CODE_UNDEFINED); + if (rc) + mhi_log(MHI_MSG_VERBOSE, + "Error with compl event\n"); + return; + } + ch = &mhi->ch[ch_id]; /* hard stop and set the channel to stop */ mhi->ch_ctx_cache[ch_id].ch_state = @@ -1889,7 +1895,7 @@ static int mhi_dev_process_cmd_ring(struct mhi_dev *mhi, switch (el->generic.type) { case MHI_DEV_RING_EL_START: - mhi_log(MHI_MSG_VERBOSE, "recived start cmd for channel %d\n", + mhi_log(MHI_MSG_VERBOSE, "received start cmd for channel %d\n", ch_id); if (ch_id >= (HW_CHANNEL_BASE)) { rc = mhi_hwc_chcmd(mhi, ch_id, el->generic.type); @@ -1897,13 +1903,26 @@ static int mhi_dev_process_cmd_ring(struct mhi_dev *mhi, mhi_log(MHI_MSG_ERROR, "Error with HW channel cmd %d\n", rc); rc = mhi_dev_send_cmd_comp_event(mhi, - MHI_CMD_COMPL_CODE_UNDEFINED); + MHI_CMD_COMPL_CODE_UNDEFINED); if (rc) mhi_log(MHI_MSG_ERROR, "Error with compl event\n"); return rc; } goto send_start_completion_event; + } else { + rc = mhi_dev_mmio_enable_chdb_a7(mhi, ch_id); + if (rc) { + mhi_log(MHI_MSG_VERBOSE, + "Failed to enable chdb for ch %d\n", + ch_id); + rc = mhi_dev_send_cmd_comp_event(mhi, + MHI_CMD_COMPL_CODE_UNDEFINED); + if (rc) + mhi_log(MHI_MSG_VERBOSE, + "Error with compl event\n"); + return rc; + } } /* fetch the channel context from host */ @@ -1934,18 +1953,6 @@ static int mhi_dev_process_cmd_ring(struct mhi_dev *mhi, mhi->ch[ch_id].ring = &mhi->ring[mhi->ch_ring_start + ch_id]; mhi->ch[ch_id].ch_type = mhi->ch_ctx_cache[ch_id].ch_type; - /* enable DB for event ring */ - rc = mhi_dev_mmio_enable_chdb_a7(mhi, ch_id); - if (rc) { - pr_err("Failed to enable channel db\n"); - rc = mhi_dev_send_cmd_comp_event(mhi, - MHI_CMD_COMPL_CODE_UNDEFINED); - if (rc) - mhi_log(MHI_MSG_ERROR, - "Error with compl event\n"); - return rc; - } - if (mhi->use_edma || mhi->use_ipa) { uint32_t evnt_ring_idx = mhi->ev_ring_start + mhi->ch_ctx_cache[ch_id].err_indx; diff --git a/drivers/platform/msm/mhi_dev/mhi_mmio.c b/drivers/platform/msm/mhi_dev/mhi_mmio.c index 71fa971dc8eb..a6aebc969a59 100644 --- a/drivers/platform/msm/mhi_dev/mhi_mmio.c +++ b/drivers/platform/msm/mhi_dev/mhi_mmio.c @@ -601,13 +601,18 @@ EXPORT_SYMBOL(mhi_dev_mmio_reset); int mhi_dev_restore_mmio(struct mhi_dev *dev) { + int rc = 0; uint32_t i, reg_cntl_value; void *reg_cntl_addr; if (WARN_ON(!dev)) return -EINVAL; - mhi_dev_mmio_mask_interrupts(dev); + mhi_dev_mmio_disable_ctrl_interrupt(dev); + + mhi_dev_mmio_disable_cmdb_interrupt(dev); + + mhi_dev_mmio_mask_erdb_interrupts(dev); for (i = 0; i < (MHI_DEV_MMIO_RANGE/4); i++) { reg_cntl_addr = dev->mmio_base_addr + @@ -618,12 +623,26 @@ int mhi_dev_restore_mmio(struct mhi_dev *dev) mhi_dev_mmio_clear_interrupts(dev); + for (i = 0; i < MHI_MASK_ROWS_CH_EV_DB; i++) { + /* Enable channel interrupt whose mask is enabled */ + if (dev->chdb[i].mask) { + mhi_log(MHI_MSG_VERBOSE, + "Enabling id: %d, chdb mask 0x%x\n", + i, dev->chdb[i].mask); + + rc = mhi_dev_mmio_write(dev, MHI_CHDB_INT_MASK_A7_n(i), + dev->chdb[i].mask); + if (rc) { + mhi_log(MHI_MSG_VERBOSE, + "Error writing enable for A7\n"); + return rc; + } + } + } + /* Mask and enable control interrupt */ mhi_dev_mmio_enable_ctrl_interrupt(dev); - /*Enable chdb interrupt*/ - mhi_dev_mmio_enable_chdb_interrupts(dev); - /*Enable cmdb interrupt*/ mhi_dev_mmio_enable_cmdb_interrupt(dev);