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

Commit a4896cc8 authored by raghavendra ambadas's avatar raghavendra ambadas
Browse files

fbdev: msm: wait for frame complete before triggering dma cmd



In dual dsi case while updating backlight through dcs commands
there is a chance of getting both the readptr and dma_tx interrupt
very close, due to which DSI0 may start cmd mdp transfer and
DSI1 will start cmd dma transfer and cause deadlock.
To fix the issue do not trigger dma commands close to TE.

Change-Id: I38536477a1ab71167a5e315a2b2c4a2b0c215b4a
Signed-off-by: default avatarRaghavendra Ambadas <rambad@codeaurora.org>
parent 85d75e13
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2016, 2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -101,6 +101,7 @@ struct dsi_cmd_desc {
#define CMD_CLK_CTRL    0x0004
#define CMD_REQ_UNICAST 0x0008
#define CMD_REQ_DMA_TPG 0x0040
#define CMD_REQ_DCS     0x0080
#define CMD_REQ_NO_MAX_PKT_SIZE 0x0008
#define CMD_REQ_LP_MODE 0x0010
#define CMD_REQ_HS_MODE 0x0020
+8 −6
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -2668,7 +2668,7 @@ int mdss_dsi_cmdlist_rx(struct mdss_dsi_ctrl_pdata *ctrl,
}

static inline bool mdss_dsi_delay_cmd(struct mdss_dsi_ctrl_pdata *ctrl,
	bool from_mdp)
	bool from_mdp, struct dcs_cmd_req *req)
{
	unsigned long flags;
	bool mdp_busy = false;
@@ -2678,9 +2678,9 @@ static inline bool mdss_dsi_delay_cmd(struct mdss_dsi_ctrl_pdata *ctrl,
		goto exit;

	/* delay only for split dsi, cmd mode and burst mode enabled cases */
	if (!mdss_dsi_is_hw_config_split(ctrl->shared_data) ||
	if ((!mdss_dsi_is_hw_config_split(ctrl->shared_data) ||
	    !(ctrl->panel_mode == DSI_CMD_MODE) ||
	    !ctrl->burst_mode_enabled)
	    !ctrl->burst_mode_enabled) && !(req->flags & CMD_REQ_DCS))
		goto exit;

	/* delay only if cmd is not from mdp and panel has been initialized */
@@ -2689,8 +2689,10 @@ static inline bool mdss_dsi_delay_cmd(struct mdss_dsi_ctrl_pdata *ctrl,

	/* if broadcast enabled, apply delay only if this is the ctrl trigger */
	if (mdss_dsi_sync_wait_enable(ctrl) &&
	   !mdss_dsi_sync_wait_trigger(ctrl))
	   (!mdss_dsi_sync_wait_trigger(ctrl) && !(req->flags & CMD_REQ_DCS)))
		goto exit;
	else
		need_wait = true;

	spin_lock_irqsave(&ctrl->mdp_lock, flags);
	if (ctrl->mdp_busy == true)
@@ -2830,7 +2832,7 @@ int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp)
	 * mdp path
	 */
	mutex_lock(&ctrl->mutex);
	if (mdss_dsi_delay_cmd(ctrl, from_mdp))
	if (mdss_dsi_delay_cmd(ctrl, from_mdp, req))
		ctrl->mdp_callback->fxn(ctrl->mdp_callback->data,
			MDP_INTF_CALLBACK_DSI_WAIT);
	mutex_unlock(&ctrl->mutex);
+2 −2
Original line number Diff line number Diff line
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, 2020, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -234,7 +234,7 @@ static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, int level)
	memset(&cmdreq, 0, sizeof(cmdreq));
	cmdreq.cmds = &backlight_cmd;
	cmdreq.cmds_cnt = 1;
	cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL;
	cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL | CMD_REQ_DCS;
	cmdreq.rlen = 0;
	cmdreq.cb = NULL;

+4 −3
Original line number Diff line number Diff line
@@ -1228,11 +1228,12 @@ static int mdss_mdp_cmd_intf_callback(void *data, int event)
			__func__, atomic_read(&ctx->rdptr_cnt), event);

		/*
		 * if we are going to suspended or pp split is not enabled,
		 * just return
		 * if we are going to suspended, just return
		 */
		if (ctx->intf_stopped || !is_pingpong_split(ctx->ctl->mfd))
		if (ctx->intf_stopped) {
			pr_debug("%s: Intf stopped\n", __func__);
			return -EINVAL;
		}
		atomic_inc(&ctx->rdptr_cnt);

		/* enable clks and rd_ptr interrupt */