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

Commit b502b286 authored by Abhijith Desai's avatar Abhijith Desai
Browse files

msm: mdss: Add support to change the dma timeout value



Add support to adjust the dma timeout value depending
on the current vsync period. When the panel goes into
idle state, the vsync period will change and hence the
timeout value should be dependent on this value instead
of a constant value.

Change-Id: Ib6d311997f3a23f998d4d02f741ee64a3abee446
Signed-off-by: default avatarKrishna Manikandan <mkrishn@codeaurora.org>
Signed-off-by: default avatarAbhijith Desai <desaia@codeaurora.org>
parent 387632bf
Loading
Loading
Loading
Loading
+37 −14
Original line number Original line Diff line number Diff line
@@ -32,8 +32,6 @@
#include "mdss_spi_panel.h"
#include "mdss_spi_panel.h"
#include "mdss_sync.h"
#include "mdss_sync.h"


#define VSYNC_EXPIRE_TICK	4

static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd);
static void mdp3_ctrl_pan_display(struct msm_fb_data_type *mfd);
static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx);
static int mdp3_overlay_unset(struct msm_fb_data_type *mfd, int ndx);
static int mdp3_histogram_stop(struct mdp3_session_data *session,
static int mdp3_histogram_stop(struct mdp3_session_data *session,
@@ -188,7 +186,8 @@ static void mdp3_dispatch_clk_off(struct work_struct *work)
		return;
		return;


	mutex_lock(&session->lock);
	mutex_lock(&session->lock);
	MDSS_XLOG(0x111);
	MDSS_XLOG(0x111, atomic_read(&session->vsync_countdown),
			session->dma->vsync_period);
	if (session->vsync_enabled ||
	if (session->vsync_enabled ||
		atomic_read(&session->vsync_countdown) > 0) {
		atomic_read(&session->vsync_countdown) > 0) {
		mutex_unlock(&session->lock);
		mutex_unlock(&session->lock);
@@ -206,14 +205,14 @@ static void mdp3_dispatch_clk_off(struct work_struct *work)
	if (session->intf->active) {
	if (session->intf->active) {
retry_dma_done:
retry_dma_done:
		rc = wait_for_completion_timeout(&session->dma_completion,
		rc = wait_for_completion_timeout(&session->dma_completion,
							WAIT_DMA_TIMEOUT);
					dma_timeout_value(session->dma));
		MDSS_XLOG(0x222);
		if (rc <= 0) {
		if (rc <= 0) {
			struct mdss_panel_data *panel;
			struct mdss_panel_data *panel;


			panel = session->panel;
			panel = session->panel;
			pr_debug("cmd kickoff timed out (%d)\n", rc);
			pr_debug("cmd kickoff timed out (%d)\n", rc);
			dmap_busy = session->dma->busy();
			dmap_busy = session->dma->busy();
			MDSS_XLOG(0x222, dmap_busy);
			if (dmap_busy) {
			if (dmap_busy) {
				if (--retry_count) {
				if (--retry_count) {
					pr_err("dmap is busy, retry %d\n",
					pr_err("dmap is busy, retry %d\n",
@@ -222,7 +221,7 @@ static void mdp3_dispatch_clk_off(struct work_struct *work)
					goto retry_dma_done;
					goto retry_dma_done;
				}
				}
				pr_err("dmap is still busy, bug_on\n");
				pr_err("dmap is still busy, bug_on\n");
				WARN_ON(1);
				BUG_ON(1);
			} else {
			} else {
				pr_debug("dmap is not busy, continue\n");
				pr_debug("dmap is not busy, continue\n");
			}
			}
@@ -303,17 +302,22 @@ void vsync_count_down(void *arg)
	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;
	struct mdp3_session_data *session = (struct mdp3_session_data *)arg;


	/* We are counting down to turn off clocks */
	/* We are counting down to turn off clocks */
	if (atomic_read(&session->vsync_countdown) > 0)
	if (atomic_read(&session->vsync_countdown) > 0) {
		atomic_dec(&session->vsync_countdown);
		atomic_dec(&session->vsync_countdown);
		MDSS_XLOG(atomic_read(&session->vsync_countdown),
				session->dma->vsync_period);
	if (atomic_read(&session->vsync_countdown) == 0)
	if (atomic_read(&session->vsync_countdown) == 0)
		schedule_work(&session->clk_off_work);
		schedule_work(&session->clk_off_work);
	}
	}
}


void mdp3_ctrl_reset_countdown(struct mdp3_session_data *session,
void mdp3_ctrl_reset_countdown(struct mdp3_session_data *session,
		struct msm_fb_data_type *mfd)
		struct msm_fb_data_type *mfd)
{
{
	if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
	if (mdp3_ctrl_get_intf_type(mfd) == MDP3_DMA_OUTPUT_SEL_DSI_CMD)
		atomic_set(&session->vsync_countdown, VSYNC_EXPIRE_TICK);
		atomic_set(&session->vsync_countdown, VSYNC_EXPIRE_TICK);

	MDSS_XLOG(atomic_read(&session->vsync_countdown));
}
}


static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
@@ -378,7 +382,7 @@ static int mdp3_ctrl_vsync_enable(struct msm_fb_data_type *mfd, int enable)
	 */
	 */
	if (mod_vsync_timer && (intf_type != MDP3_DMA_OUTPUT_SEL_SPI_CMD)) {
	if (mod_vsync_timer && (intf_type != MDP3_DMA_OUTPUT_SEL_SPI_CMD)) {
		mod_timer(&mdp3_session->vsync_timer,
		mod_timer(&mdp3_session->vsync_timer,
			jiffies + msecs_to_jiffies(mdp3_session->vsync_period));
		jiffies + msecs_to_jiffies(mdp3_session->dma->vsync_period));
	} else if (enable && !mdp3_session->clk_on) {
	} else if (enable && !mdp3_session->clk_on) {
		mdp3_ctrl_reset_countdown(mdp3_session, mfd);
		mdp3_ctrl_reset_countdown(mdp3_session, mfd);
		mdp3_ctrl_clk_enable(mfd, 1);
		mdp3_ctrl_clk_enable(mfd, 1);
@@ -398,7 +402,7 @@ void mdp3_vsync_timer_func(unsigned long arg)
		pr_debug("mdp3_vsync_timer_func trigger\n");
		pr_debug("mdp3_vsync_timer_func trigger\n");
		vsync_notify_handler(session);
		vsync_notify_handler(session);
		mod_timer(&session->vsync_timer,
		mod_timer(&session->vsync_timer,
			jiffies + msecs_to_jiffies(session->vsync_period));
			jiffies + msecs_to_jiffies(session->dma->vsync_period));
	}
	}
}
}


@@ -905,6 +909,7 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd)
	int rc = 0;
	int rc = 0;
	struct mdp3_session_data *mdp3_session;
	struct mdp3_session_data *mdp3_session;
	struct mdss_panel_data *panel;
	struct mdss_panel_data *panel;
	u32 framerate = 0;


	pr_debug("mdp3_ctrl_on\n");
	pr_debug("mdp3_ctrl_on\n");
	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -1027,7 +1032,7 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd)
		mdp3_session->status = 1;
		mdp3_session->status = 1;


	mdp3_ctrl_pp_resume(mfd);
	mdp3_ctrl_pp_resume(mfd);
	MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__, mfd->panel_power_state);

on_error:
on_error:
	if (rc || (mdp3_res->idle_pc_enabled &&
	if (rc || (mdp3_res->idle_pc_enabled &&
			(mfd->panel_info->type == MIPI_CMD_PANEL))) {
			(mfd->panel_info->type == MIPI_CMD_PANEL))) {
@@ -1038,6 +1043,12 @@ static int mdp3_ctrl_on(struct msm_fb_data_type *mfd)
		pm_runtime_put(&mdp3_res->pdev->dev);
		pm_runtime_put(&mdp3_res->pdev->dev);
	}
	}
end:
end:
	framerate = mdss_panel_get_framerate(mfd->panel_info,
			FPS_RESOLUTION_HZ);
	if (framerate != 0)
		mdp3_session->dma->vsync_period = DIV_ROUND_UP(1000, framerate);

	MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__, mfd->panel_power_state, framerate);
	mutex_unlock(&mdp3_session->lock);
	mutex_unlock(&mdp3_session->lock);
	return rc;
	return rc;
}
}
@@ -1054,6 +1065,7 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd)
	bool intf_stopped = true;
	bool intf_stopped = true;
	struct mdp3_session_data *mdp3_session;
	struct mdp3_session_data *mdp3_session;
	struct mdss_panel_data *panel;
	struct mdss_panel_data *panel;
	u32 framerate = 0;


	pr_debug("mdp3_ctrl_off\n");
	pr_debug("mdp3_ctrl_off\n");
	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
	mdp3_session = (struct mdp3_session_data *)mfd->mdp.private1;
@@ -1242,7 +1254,13 @@ static int mdp3_ctrl_off(struct msm_fb_data_type *mfd)
		mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
		mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
		mdp3_bufq_deinit(&mdp3_session->bufq_in, client);
		mdp3_bufq_deinit(&mdp3_session->bufq_in, client);
	}
	}
	MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__);

	framerate = mdss_panel_get_framerate(mfd->panel_info,
			FPS_RESOLUTION_HZ);
	if (framerate != 0)
		mdp3_session->dma->vsync_period = DIV_ROUND_UP(1000, framerate);

	MDSS_XLOG(XLOG_FUNC_EXIT, __LINE__, framerate);
	mutex_unlock(&mdp3_session->lock);
	mutex_unlock(&mdp3_session->lock);
	/* Release the last reference to the runtime device */
	/* Release the last reference to the runtime device */
	pm_runtime_put(&mdp3_res->pdev->dev);
	pm_runtime_put(&mdp3_res->pdev->dev);
@@ -1567,7 +1585,8 @@ static int mdp3_ctrl_display_commit_kickoff(struct msm_fb_data_type *mfd,
		mutex_unlock(&mdp3_session->lock);
		mutex_unlock(&mdp3_session->lock);
		return -EPERM;
		return -EPERM;
	}
	}
	MDSS_XLOG(0x111);
	MDSS_XLOG(0x111, mdp3_session->dma->vsync_period);

	mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
	mdp3_ctrl_notify(mdp3_session, MDP_NOTIFY_FRAME_BEGIN);
	data = mdp3_bufq_pop(&mdp3_session->bufq_in);
	data = mdp3_bufq_pop(&mdp3_session->bufq_in);
	if (data) {
	if (data) {
@@ -2894,7 +2913,7 @@ int mdp3_wait_for_dma_done(struct mdp3_session_data *session)


	if (session->dma_active) {
	if (session->dma_active) {
		rc = wait_for_completion_timeout(&session->dma_completion,
		rc = wait_for_completion_timeout(&session->dma_completion,
			KOFF_TIMEOUT);
			 dma_timeout_value(session->dma));
		if (rc > 0) {
		if (rc > 0) {
			session->dma_active = 0;
			session->dma_active = 0;
			rc = 0;
			rc = 0;
@@ -3071,7 +3090,11 @@ int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
	init_timer(&mdp3_session->vsync_timer);
	init_timer(&mdp3_session->vsync_timer);
	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
	mdp3_session->vsync_timer.data = (u32)mdp3_session;
	mdp3_session->vsync_timer.data = (u32)mdp3_session;
	mdp3_session->vsync_period = 1000 / frame_rate;

	if (frame_rate != 0)
		mdp3_session->dma->vsync_period =
				DIV_ROUND_UP(1000, frame_rate);

	mfd->mdp.private1 = mdp3_session;
	mfd->mdp.private1 = mdp3_session;
	init_completion(&mdp3_session->dma_completion);
	init_completion(&mdp3_session->dma_completion);
	if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO ||
	if (intf_type != MDP3_DMA_OUTPUT_SEL_DSI_VIDEO ||
+0 −1
Original line number Original line Diff line number Diff line
@@ -45,7 +45,6 @@ struct mdp3_session_data {
	struct msm_fb_data_type *mfd;
	struct msm_fb_data_type *mfd;
	ktime_t vsync_time;
	ktime_t vsync_time;
	struct timer_list vsync_timer;
	struct timer_list vsync_timer;
	int vsync_period;
	struct kernfs_node *vsync_event_sd;
	struct kernfs_node *vsync_event_sd;
	struct kernfs_node *bl_event_sd;
	struct kernfs_node *bl_event_sd;
	struct mdp_overlay overlay;
	struct mdp_overlay overlay;
+18 −2
Original line number Original line Diff line number Diff line
@@ -36,7 +36,13 @@ static void mdp3_vsync_intr_handler(int type, void *arg)
	struct mdp3_notification retire_client;
	struct mdp3_notification retire_client;
	unsigned int wait_for_next_vs;
	unsigned int wait_for_next_vs;


	if (!dma) {
		pr_err("dma is null\n");
		return;
	}

	pr_debug("mdp3_vsync_intr_handler\n");
	pr_debug("mdp3_vsync_intr_handler\n");
	MDSS_XLOG(0x111, dma->vsync_period);
	spin_lock(&dma->dma_lock);
	spin_lock(&dma->dma_lock);
	vsync_client = dma->vsync_client;
	vsync_client = dma->vsync_client;
	retire_client = dma->retire_client;
	retire_client = dma->retire_client;
@@ -61,6 +67,11 @@ static void mdp3_dma_done_intr_handler(int type, void *arg)
	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
	struct mdp3_notification dma_client;
	struct mdp3_notification dma_client;


	if (!dma) {
		pr_err("dma is null\n");
		return;
	}

	pr_debug("mdp3_dma_done_intr_handler\n");
	pr_debug("mdp3_dma_done_intr_handler\n");
	spin_lock(&dma->dma_lock);
	spin_lock(&dma->dma_lock);
	dma_client = dma->dma_notifier_client;
	dma_client = dma->dma_notifier_client;
@@ -76,6 +87,11 @@ static void mdp3_hist_done_intr_handler(int type, void *arg)
	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
	struct mdp3_dma *dma = (struct mdp3_dma *)arg;
	u32 isr, mask;
	u32 isr, mask;


	if (!dma) {
		pr_err("dma is null\n");
		return;
	}

	isr = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_STATUS);
	isr = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_STATUS);
	mask = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_ENABLE);
	mask = MDP3_REG_READ(MDP3_REG_DMA_P_HIST_INTR_ENABLE);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_INTR_CLEAR, isr);
	MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_INTR_CLEAR, isr);
@@ -674,7 +690,7 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf,
			ATRACE_BEGIN("mdp3_wait_for_dma_comp");
			ATRACE_BEGIN("mdp3_wait_for_dma_comp");
retry_dma_done:
retry_dma_done:
			rc = wait_for_completion_timeout(&dma->dma_comp,
			rc = wait_for_completion_timeout(&dma->dma_comp,
				KOFF_TIMEOUT);
			 dma_timeout_value(dma));
			if (rc <= 0 && --retry_count) {
			if (rc <= 0 && --retry_count) {
				int  vsync_status;
				int  vsync_status;


@@ -735,7 +751,7 @@ static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf,
		ATRACE_BEGIN("mdp3_wait_for_vsync_comp");
		ATRACE_BEGIN("mdp3_wait_for_vsync_comp");
retry_vsync:
retry_vsync:
		rc = wait_for_completion_timeout(&dma->vsync_comp,
		rc = wait_for_completion_timeout(&dma->vsync_comp,
			KOFF_TIMEOUT);
			 dma_timeout_value(dma));
		if (rc <= 0 && --retry_count) {
		if (rc <= 0 && --retry_count) {
			int vsync = MDP3_REG_READ(MDP3_REG_INTR_STATUS) &
			int vsync = MDP3_REG_READ(MDP3_REG_INTR_STATUS) &
					(1 << MDP3_INTR_LCDC_START_OF_FRAME);
					(1 << MDP3_INTR_LCDC_START_OF_FRAME);
+10 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@
#define MDP_HISTOGRAM_CSC_VECTOR_MAX 0x200
#define MDP_HISTOGRAM_CSC_VECTOR_MAX 0x200
#define MDP_HISTOGRAM_BIN_NUM	32
#define MDP_HISTOGRAM_BIN_NUM	32
#define MDP_LUT_SIZE 256
#define MDP_LUT_SIZE 256
#define VSYNC_EXPIRE_TICK     4


enum {
enum {
	MDP3_DMA_P,
	MDP3_DMA_P,
@@ -255,6 +256,7 @@ struct mdp3_dma {
	u32 capability;
	u32 capability;
	int in_use;
	int in_use;
	int available;
	int available;
	int vsync_period;


	spinlock_t dma_lock;
	spinlock_t dma_lock;
	spinlock_t histo_lock;
	spinlock_t histo_lock;
@@ -384,6 +386,14 @@ struct mdp3_intf {
	int (*stop)(struct mdp3_intf *intf);
	int (*stop)(struct mdp3_intf *intf);
};
};


static inline unsigned long dma_timeout_value(struct mdp3_dma *dma)
{
	if (dma->vsync_period)
		return msecs_to_jiffies(VSYNC_EXPIRE_TICK * dma->vsync_period);
	else
		return msecs_to_jiffies(84);
}

int mdp3_dma_init(struct mdp3_dma *dma);
int mdp3_dma_init(struct mdp3_dma *dma);


int mdp3_intf_init(struct mdp3_intf *intf);
int mdp3_intf_init(struct mdp3_intf *intf);