Patchwork drm/exynos: fimd: fix trigger mode change regression

login
register
mail settings
Submitter Inki Dae
Date June 1, 2016, 5:53 a.m.
Message ID <1464760434-16709-1-git-send-email-inki.dae@samsung.com>
Download mbox | patch
Permalink /patch/9146075/
State New
Headers show

Comments

Inki Dae - June 1, 2016, 5:53 a.m.
This patch fixes a regression that Display panel doesn't work
since HW trigger mode was supported.

The trigger mode should be changed on PSR(Panel Self Refresh)
mode of Panel device according to HW guy's saying. However,
with previous HW trigger support, trigger mode could been changed
in normal mode of Panel device.

So this patch makes sure to change the trigger mode after power off
and on again. Later we need to add PSR relevant codes instead.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
---
 drivers/gpu/drm/exynos/exynos_drm_fimd.c | 35 ++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)
Marc Zyngier - June 6, 2016, 4:45 p.m.
On 2016-06-01 06:53, Inki Dae wrote:
> This patch fixes a regression that Display panel doesn't work
> since HW trigger mode was supported.
>
> The trigger mode should be changed on PSR(Panel Self Refresh)
> mode of Panel device according to HW guy's saying. However,
> with previous HW trigger support, trigger mode could been changed
> in normal mode of Panel device.
>
> So this patch makes sure to change the trigger mode after power off
> and on again. Later we need to add PSR relevant codes instead.

I'm afraid this patch doesn't fix the regression I'm seeing on my 
Exynos5250 Chromebook.

I found out that using the 4.6 device tree allows the display to 
function correctly (at least for a while), just enough to see it dying 
before reaching userspace (and it scrolls up way to quickly for me to 
read it). Adding printk_delay results in a hanging system.

Can someone with a servo-board investigate this? I'll try to bisect it 
further, but an actual backtrace would help.

Thanks,

         M.

Patch

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 3efe1aa..355149f 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -203,6 +203,11 @@  struct fimd_context {
 	atomic_t			wait_vsync_event;
 	atomic_t			win_updated;
 	atomic_t			triggering;
+	/*
+	 * fimd_setup_trigger function will try to change trigger mode
+	 * only in case that this flag is set.
+	 */
+	atomic_t			deferred_tr_mode;
 
 	const struct fimd_driver_data *driver_data;
 	struct drm_encoder *encoder;
@@ -430,11 +435,37 @@  static void fimd_setup_trigger(struct fimd_context *ctx)
 	val &= ~(TRGMODE_ENABLE);
 
 	if (trg_type == I80_HW_TRG) {
+		/*
+		 * change trigger mode after power off and on again.
+		 * deferred_tr_mode will be set when fimd_disable is called.
+		 *
+		 * TODO. Trigger mode should be changed on PSR mode of Panel
+		 * device. So we have to add relevant codes to make sure
+		 * entering into PSR mode later.
+		 */
+		if (val & TRGMODE_ENABLE &&
+		    !atomic_read(&ctx->deferred_tr_mode))
+			return;
+
 		if (ctx->driver_data->has_hw_trigger)
 			val |= HWTRGEN_ENABLE | HWTRGMASK_ENABLE;
 		if (ctx->driver_data->has_trigger_per_te)
 			val |= HWTRIGEN_PER_ENABLE;
 	} else {
+		/*
+		 * change trigger mode after power off and on again.
+		 * deferred_tr_mode will be set when fimd_disable is called.
+		 *
+		 * TODO. Trigger mode should be changed on PSR mode of Panel
+		 * device. So we have to add relevant codes to make sure
+		 * entering into PSR mode later.
+		 */
+		if (ctx->driver_data->has_hw_trigger) {
+			if (val & HWTRGEN_ENABLE &&
+			    !atomic_read(&ctx->deferred_tr_mode))
+				return;
+		}
+
 		val |= TRGMODE_ENABLE;
 	}
 
@@ -864,6 +895,10 @@  static void fimd_disable(struct exynos_drm_crtc *crtc)
 	writel(0, ctx->regs + VIDCON0);
 
 	pm_runtime_put_sync(ctx->dev);
+
+	if (ctx->i80_if)
+		atomic_set(&ctx->deferred_tr_mode, 1);
+
 	ctx->suspended = true;
 }