Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f9a97f1 authored by Harigovindan P's avatar Harigovindan P
Browse files

disp: msm: clear dma done interrupt status for slave controller



When Broadcast is enabled, DMA_DONE bit gets set for slave
controller on command transfer completion but it is not
getting cleared. Due to this, DMA transfer failures on slave
controller are not getting caught. This patch add supports for
clearing DMA_DONE for slave controller on every successful
transfer. This also prints error if transfer fails on slave
controller.

Change-Id: I61ce7b2d8be323adc70d888b5a2416afd9ae9fac
Signed-off-by: default avatarHarigovindan P <harigovi@codeaurora.org>
parent 71d0f6ec
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -3237,6 +3237,56 @@ void dsi_ctrl_mask_overflow(struct dsi_ctrl *dsi_ctrl, bool enable)
	}
}

/**
 * dsi_ctrl_clear_slave_dma_status -   API to clear slave DMA status
 * @dsi_ctrl:                   DSI controller handle.
 * @flags:                      Modifiers
 */
int dsi_ctrl_clear_slave_dma_status(struct dsi_ctrl *dsi_ctrl, u32 flags)
{
	struct dsi_ctrl_hw_ops dsi_hw_ops;
	u32 status;
	u32 mask = DSI_CMD_MODE_DMA_DONE;
	int rc = 0, wait_for_done = 5;

	if (!dsi_ctrl) {
		DSI_CTRL_ERR(dsi_ctrl, "Invalid params\n");
		return -EINVAL;
	}

	/* Return if this is not the last command */
	if (!(flags & DSI_CTRL_CMD_LAST_COMMAND))
		return rc;

	SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY);

	mutex_lock(&dsi_ctrl->ctrl_lock);

	dsi_hw_ops = dsi_ctrl->hw.ops;

	while (wait_for_done > 0) {
		status = dsi_hw_ops.get_interrupt_status(&dsi_ctrl->hw);
		if (status & mask) {
			status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE);
			dsi_hw_ops.clear_interrupt_status(&dsi_ctrl->hw,
				status);
			SDE_EVT32(dsi_ctrl->cell_index, status);
			wait_for_done = 1;
			break;
		}
		udelay(10);
		wait_for_done--;
	}

	if (wait_for_done == 0)
		DSI_CTRL_ERR(dsi_ctrl,
				"DSI1 CMD_MODE_DMA_DONE failed\n");

	mutex_unlock(&dsi_ctrl->ctrl_lock);

	return rc;
}

/**
 * dsi_ctrl_cmd_tx_trigger() - Trigger a deferred command.
 * @dsi_ctrl:              DSI controller handle.
+7 −0
Original line number Diff line number Diff line
@@ -868,4 +868,11 @@ int dsi_ctrl_wait4dynamic_refresh_done(struct dsi_ctrl *ctrl);
 * @enable:			variable to control masking/unmasking.
 */
void dsi_ctrl_mask_overflow(struct dsi_ctrl *dsi_ctrl, bool enable);

/**
 * dsi_ctrl_clear_slave_dma_status -   API to clear slave DMA status
 * @dsi_ctrl:                   DSI controller handle.
 * @flags:                      Modifiers
 */
int dsi_ctrl_clear_slave_dma_status(struct dsi_ctrl *dsi_ctrl, u32 flags);
#endif /* _DSI_CTRL_H_ */
+13 −0
Original line number Diff line number Diff line
@@ -2803,6 +2803,19 @@ static int dsi_display_broadcast_cmd(struct dsi_display *display,
		goto error;
	}

	display_for_each_ctrl(i, display) {
		ctrl = &display->ctrl[i];
		if (ctrl == m_ctrl)
			continue;

		rc = dsi_ctrl_clear_slave_dma_status(ctrl->ctrl, flags);
		if (rc) {
			DSI_ERR("[%s] clear interrupt status failed, rc=%d\n",
				display->name, rc);
			goto error;
		}
	}

error:
	dsi_display_mask_overflow(display, m_flags, false);
	return rc;