disp: msm: read mdp intf line count and trigger dma accordingly
when a broadcast DSI command is scheduled, the command can get triggered close to the schedule line. This might cause DMA timeout. This change reads the video line count from MDP_INTF_LINE_COUNT register and checks whether DMA trigger happens close to the schedule line. If it is not close to the schedule line, then DMA command transfer is triggered. Change-Id: Ida92e63e46b4cc703d57ce24097834f810776aa8 Signed-off-by: Harigovindan P <harigovi@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
7a98aa2134
commit
8dd3b42c57
@@ -1339,6 +1339,25 @@ static void dsi_configure_command_scheduling(struct dsi_ctrl *dsi_ctrl,
|
||||
sched_line_no, window);
|
||||
}
|
||||
|
||||
static u32 calculate_schedule_line(struct dsi_ctrl *dsi_ctrl, u32 flags)
|
||||
{
|
||||
u32 line_no = 0x1;
|
||||
struct dsi_mode_info *timing;
|
||||
|
||||
/* check if custom dma scheduling line needed */
|
||||
if ((dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) &&
|
||||
(flags & DSI_CTRL_CMD_CUSTOM_DMA_SCHED))
|
||||
line_no = dsi_ctrl->host_config.common_config.dma_sched_line;
|
||||
|
||||
timing = &(dsi_ctrl->host_config.video_timing);
|
||||
|
||||
if (timing)
|
||||
line_no += timing->v_back_porch + timing->v_sync_width +
|
||||
timing->v_active;
|
||||
|
||||
return line_no;
|
||||
}
|
||||
|
||||
static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl,
|
||||
const struct mipi_dsi_msg *msg,
|
||||
struct dsi_ctrl_cmd_dma_fifo_info *cmd,
|
||||
@@ -3391,6 +3410,10 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)
|
||||
{
|
||||
int rc = 0;
|
||||
struct dsi_ctrl_hw_ops dsi_hw_ops;
|
||||
u32 v_total = 0, fps = 0, cur_line = 0, mem_latency_us = 100;
|
||||
u32 line_time = 0, schedule_line = 0x1, latency_by_line = 0;
|
||||
struct dsi_mode_info *timing;
|
||||
unsigned long flag;
|
||||
|
||||
if (!dsi_ctrl) {
|
||||
DSI_CTRL_ERR(dsi_ctrl, "Invalid params\n");
|
||||
@@ -3406,6 +3429,18 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)
|
||||
|
||||
mutex_lock(&dsi_ctrl->ctrl_lock);
|
||||
|
||||
timing = &(dsi_ctrl->host_config.video_timing);
|
||||
|
||||
if (timing &&
|
||||
(dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE)) {
|
||||
v_total = timing->v_sync_width + timing->v_back_porch +
|
||||
timing->v_front_porch + timing->v_active;
|
||||
fps = timing->refresh_rate;
|
||||
schedule_line = calculate_schedule_line(dsi_ctrl, flags);
|
||||
line_time = (1000000 / fps) / v_total;
|
||||
latency_by_line = CEIL(mem_latency_us, line_time);
|
||||
}
|
||||
|
||||
if (!(flags & DSI_CTRL_CMD_BROADCAST_MASTER)) {
|
||||
dsi_hw_ops.trigger_command_dma(&dsi_ctrl->hw);
|
||||
if (dsi_ctrl->enable_cmd_dma_stats) {
|
||||
@@ -3428,7 +3463,35 @@ int dsi_ctrl_cmd_tx_trigger(struct dsi_ctrl *dsi_ctrl, u32 flags)
|
||||
reinit_completion(&dsi_ctrl->irq_info.cmd_dma_done);
|
||||
|
||||
/* trigger command */
|
||||
dsi_hw_ops.trigger_command_dma(&dsi_ctrl->hw);
|
||||
if ((dsi_ctrl->host_config.panel_mode == DSI_OP_VIDEO_MODE) &&
|
||||
dsi_hw_ops.schedule_dma_cmd &&
|
||||
(dsi_ctrl->current_state.vid_engine_state ==
|
||||
DSI_CTRL_ENGINE_ON)) {
|
||||
/*
|
||||
* This change reads the video line count from
|
||||
* MDP_INTF_LINE_COUNT register and checks whether
|
||||
* DMA trigger happens close to the schedule line.
|
||||
* If it is not close to the schedule line, then DMA
|
||||
* command transfer is triggered.
|
||||
*/
|
||||
while (1) {
|
||||
local_irq_save(flag);
|
||||
cur_line =
|
||||
dsi_hw_ops.log_line_count(&dsi_ctrl->hw,
|
||||
dsi_ctrl->cmd_mode);
|
||||
if (cur_line <
|
||||
(schedule_line - latency_by_line) ||
|
||||
cur_line > (schedule_line + 1)) {
|
||||
dsi_hw_ops.trigger_command_dma(
|
||||
&dsi_ctrl->hw);
|
||||
local_irq_restore(flag);
|
||||
break;
|
||||
}
|
||||
local_irq_restore(flag);
|
||||
udelay(1000);
|
||||
}
|
||||
} else
|
||||
dsi_hw_ops.trigger_command_dma(&dsi_ctrl->hw);
|
||||
|
||||
if (dsi_ctrl->enable_cmd_dma_stats) {
|
||||
u32 reg = dsi_hw_ops.log_line_count(&dsi_ctrl->hw,
|
||||
|
Reference in New Issue
Block a user