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: Harigovindan P <harigovi@codeaurora.org>
This commit is contained in:

committed by
Satya Rama Aditya Pinapala

parent
aecc86dfb2
commit
98767bf22b
@@ -30,6 +30,7 @@ static void dsi_catalog_cmn_init(struct dsi_ctrl_hw *ctrl,
|
|||||||
ctrl->ops.reset_cmd_fifo = dsi_ctrl_hw_cmn_reset_cmd_fifo;
|
ctrl->ops.reset_cmd_fifo = dsi_ctrl_hw_cmn_reset_cmd_fifo;
|
||||||
ctrl->ops.trigger_command_dma = dsi_ctrl_hw_cmn_trigger_command_dma;
|
ctrl->ops.trigger_command_dma = dsi_ctrl_hw_cmn_trigger_command_dma;
|
||||||
ctrl->ops.get_interrupt_status = dsi_ctrl_hw_cmn_get_interrupt_status;
|
ctrl->ops.get_interrupt_status = dsi_ctrl_hw_cmn_get_interrupt_status;
|
||||||
|
ctrl->ops.poll_dma_status = dsi_ctrl_hw_cmn_poll_dma_status;
|
||||||
ctrl->ops.get_error_status = dsi_ctrl_hw_cmn_get_error_status;
|
ctrl->ops.get_error_status = dsi_ctrl_hw_cmn_get_error_status;
|
||||||
ctrl->ops.clear_error_status = dsi_ctrl_hw_cmn_clear_error_status;
|
ctrl->ops.clear_error_status = dsi_ctrl_hw_cmn_clear_error_status;
|
||||||
ctrl->ops.clear_interrupt_status =
|
ctrl->ops.clear_interrupt_status =
|
||||||
|
@@ -128,6 +128,7 @@ void dsi_phy_hw_v4_0_commit_phy_timing(struct dsi_phy_hw *phy,
|
|||||||
|
|
||||||
/* DSI controller common ops */
|
/* DSI controller common ops */
|
||||||
u32 dsi_ctrl_hw_cmn_get_interrupt_status(struct dsi_ctrl_hw *ctrl);
|
u32 dsi_ctrl_hw_cmn_get_interrupt_status(struct dsi_ctrl_hw *ctrl);
|
||||||
|
u32 dsi_ctrl_hw_cmn_poll_dma_status(struct dsi_ctrl_hw *ctrl);
|
||||||
void dsi_ctrl_hw_cmn_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints);
|
void dsi_ctrl_hw_cmn_clear_interrupt_status(struct dsi_ctrl_hw *ctrl, u32 ints);
|
||||||
void dsi_ctrl_hw_cmn_enable_status_interrupts(struct dsi_ctrl_hw *ctrl,
|
void dsi_ctrl_hw_cmn_enable_status_interrupts(struct dsi_ctrl_hw *ctrl,
|
||||||
u32 ints);
|
u32 ints);
|
||||||
|
@@ -410,24 +410,48 @@ static void dsi_ctrl_dma_cmd_wait_for_done(struct dsi_ctrl *dsi_ctrl)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* dsi_ctrl_clear_dma_status - API to clear DMA status
|
||||||
|
* @dsi_ctrl: DSI controller handle.
|
||||||
|
*/
|
||||||
|
static void dsi_ctrl_clear_dma_status(struct dsi_ctrl *dsi_ctrl)
|
||||||
|
{
|
||||||
|
struct dsi_ctrl_hw_ops dsi_hw_ops;
|
||||||
|
u32 status = 0;
|
||||||
|
|
||||||
|
if (!dsi_ctrl) {
|
||||||
|
DSI_CTRL_ERR(dsi_ctrl, "Invalid params\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
dsi_hw_ops = dsi_ctrl->hw.ops;
|
||||||
|
|
||||||
|
status = dsi_hw_ops.poll_dma_status(&dsi_ctrl->hw);
|
||||||
|
SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, status);
|
||||||
|
|
||||||
|
status |= (DSI_CMD_MODE_DMA_DONE | DSI_BTA_DONE);
|
||||||
|
dsi_hw_ops.clear_interrupt_status(&dsi_ctrl->hw, status);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static void dsi_ctrl_post_cmd_transfer(struct dsi_ctrl *dsi_ctrl)
|
static void dsi_ctrl_post_cmd_transfer(struct dsi_ctrl *dsi_ctrl)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct dsi_clk_ctrl_info clk_info;
|
struct dsi_clk_ctrl_info clk_info;
|
||||||
bool skip_wait_for_done = false;
|
|
||||||
u32 mask = BIT(DSI_FIFO_OVERFLOW);
|
u32 mask = BIT(DSI_FIFO_OVERFLOW);
|
||||||
|
|
||||||
mutex_lock(&dsi_ctrl->ctrl_lock);
|
mutex_lock(&dsi_ctrl->ctrl_lock);
|
||||||
|
|
||||||
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY, dsi_ctrl->cell_index, dsi_ctrl->pending_cmd_flags);
|
SDE_EVT32(SDE_EVTLOG_FUNC_ENTRY, dsi_ctrl->cell_index, dsi_ctrl->pending_cmd_flags);
|
||||||
|
|
||||||
/* In case of broadcast messages, we needn't wait on the slave controller */
|
/* In case of broadcast messages, we poll on the slave controller. */
|
||||||
if ((dsi_ctrl->pending_cmd_flags & DSI_CTRL_CMD_BROADCAST) &&
|
if ((dsi_ctrl->pending_cmd_flags & DSI_CTRL_CMD_BROADCAST) &&
|
||||||
!(dsi_ctrl->pending_cmd_flags & DSI_CTRL_CMD_BROADCAST_MASTER))
|
!(dsi_ctrl->pending_cmd_flags & DSI_CTRL_CMD_BROADCAST_MASTER)) {
|
||||||
skip_wait_for_done = true;
|
dsi_ctrl_clear_dma_status(dsi_ctrl);
|
||||||
|
} else {
|
||||||
if (!skip_wait_for_done)
|
|
||||||
dsi_ctrl_dma_cmd_wait_for_done(dsi_ctrl);
|
dsi_ctrl_dma_cmd_wait_for_done(dsi_ctrl);
|
||||||
|
}
|
||||||
|
|
||||||
/* Command engine disable, unmask overflow, remove vote on clocks and gdsc */
|
/* Command engine disable, unmask overflow, remove vote on clocks and gdsc */
|
||||||
rc = dsi_ctrl_set_cmd_engine_state(dsi_ctrl, DSI_CTRL_ENGINE_OFF, false);
|
rc = dsi_ctrl_set_cmd_engine_state(dsi_ctrl, DSI_CTRL_ENGINE_OFF, false);
|
||||||
|
@@ -643,6 +643,12 @@ struct dsi_ctrl_hw_ops {
|
|||||||
*/
|
*/
|
||||||
void (*clear_interrupt_status)(struct dsi_ctrl_hw *ctrl, u32 ints);
|
void (*clear_interrupt_status)(struct dsi_ctrl_hw *ctrl, u32 ints);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* poll_dma_status()- API to poll DMA status
|
||||||
|
* @ctrl: Pointer to the controller host hardware.
|
||||||
|
*/
|
||||||
|
u32 (*poll_dma_status)(struct dsi_ctrl_hw *ctrl);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enable_status_interrupts() - enable the specified interrupts
|
* enable_status_interrupts() - enable the specified interrupts
|
||||||
* @ctrl: Pointer to the controller host hardware.
|
* @ctrl: Pointer to the controller host hardware.
|
||||||
|
@@ -945,6 +945,29 @@ u32 dsi_ctrl_hw_cmn_get_cmd_read_data(struct dsi_ctrl_hw *ctrl,
|
|||||||
return rx_byte;
|
return rx_byte;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* poll_dma_status() - API to poll DMA status
|
||||||
|
* @ctrl: Pointer to the controller host hardware.
|
||||||
|
*
|
||||||
|
* Return: DMA status.
|
||||||
|
*/
|
||||||
|
u32 dsi_ctrl_hw_cmn_poll_dma_status(struct dsi_ctrl_hw *ctrl)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
u32 status;
|
||||||
|
u32 const delay_us = 10;
|
||||||
|
u32 const timeout_us = 5000;
|
||||||
|
|
||||||
|
rc = readl_poll_timeout_atomic(ctrl->base + DSI_INT_CTRL, status,
|
||||||
|
((status & DSI_CMD_MODE_DMA_DONE) > 0), delay_us, timeout_us);
|
||||||
|
if (rc) {
|
||||||
|
DSI_CTRL_HW_DBG(ctrl, "CMD_MODE_DMA_DONE failed\n");
|
||||||
|
status = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_interrupt_status() - returns the interrupt status
|
* get_interrupt_status() - returns the interrupt status
|
||||||
* @ctrl: Pointer to the controller host hardware.
|
* @ctrl: Pointer to the controller host hardware.
|
||||||
|
Reference in New Issue
Block a user