From: Liwei Cai <caili...@hisilicon.com>

The use of synchronization mechanisms to deal with the display of
buffer, to solve the problem of display tearing.

Signed-off-by: Wanchun Zheng <zhengwanc...@hisilicon.com>
Signed-off-by: Liwei Cai <caili...@hisilicon.com>
Signed-off-by: John Stultz <john.stu...@linaro.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+hua...@kernel.org>
---
 drivers/staging/hikey9xx/gpu/dw_drm_dsi.c     |  3 +-
 drivers/staging/hikey9xx/gpu/kirin_drm_dss.c  |  4 +-
 .../hikey9xx/gpu/kirin_drm_overlay_utils.c    | 90 ++++++++-----------
 3 files changed, 41 insertions(+), 56 deletions(-)

diff --git a/drivers/staging/hikey9xx/gpu/dw_drm_dsi.c 
b/drivers/staging/hikey9xx/gpu/dw_drm_dsi.c
index 9871b375416b..db408beb33ec 100644
--- a/drivers/staging/hikey9xx/gpu/dw_drm_dsi.c
+++ b/drivers/staging/hikey9xx/gpu/dw_drm_dsi.c
@@ -35,7 +35,6 @@
 
 #define DTS_COMP_DSI_NAME "hisilicon,hi3660-dsi"
 
-#define MAX_TX_ESC_CLK         10
 #define ROUND(x, y)            ((x) / (y) + \
                                ((x) % (y) * 10 / (y) >= 5 ? 1 : 0))
 #define ROUND1(x, y)   ((x) / (y) + ((x) % (y)  ? 1 : 0))
@@ -1237,7 +1236,7 @@ static int dsi_host_init(struct device *dev, struct 
dw_dsi *dsi)
        host->dev = dev;
        host->ops = &dsi_host_ops;
 
-       mipi->max_tx_esc_clk = 10;
+       mipi->max_tx_esc_clk = 10 * 1000000UL;
        mipi->vc = 0;
        mipi->color_mode = DSI_24BITS_1;
        mipi->clk_post_adjust = 120;
diff --git a/drivers/staging/hikey9xx/gpu/kirin_drm_dss.c 
b/drivers/staging/hikey9xx/gpu/kirin_drm_dss.c
index c47d860f4697..62ac1a0648cc 100644
--- a/drivers/staging/hikey9xx/gpu/kirin_drm_dss.c
+++ b/drivers/staging/hikey9xx/gpu/kirin_drm_dss.c
@@ -167,8 +167,8 @@ static int dss_power_up(struct dss_crtc *acrtc)
        dss_inner_clk_common_enable(acrtc);
        dpe_interrupt_mask(acrtc);
        dpe_interrupt_clear(acrtc);
-       dpe_irq_enable(acrtc);
-       dpe_interrupt_unmask(acrtc);
+       //dpe_irq_enable(acrtc);
+       //dpe_interrupt_unmask(acrtc);
 
        ctx->power_on = true;
        return 0;
diff --git a/drivers/staging/hikey9xx/gpu/kirin_drm_overlay_utils.c 
b/drivers/staging/hikey9xx/gpu/kirin_drm_overlay_utils.c
index 095335eba16d..917e1a7d7bdf 100644
--- a/drivers/staging/hikey9xx/gpu/kirin_drm_overlay_utils.c
+++ b/drivers/staging/hikey9xx/gpu/kirin_drm_overlay_utils.c
@@ -30,6 +30,7 @@
 
 
 #define DSS_CHN_MAX_DEFINE (DSS_COPYBIT_MAX)
+#define TIME_OUT  (16)
 
 static int mid_array[DSS_CHN_MAX_DEFINE] = {0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 
0x4, 0x2, 0x1, 0x3, 0x0};
 
@@ -1064,6 +1065,38 @@ void hisi_dss_unflow_handler(struct dss_hw_ctx *ctx, 
bool unmask)
        outp32(dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INT_MSK, tmp);
 }
 
+void hisi_dss_wait_for_complete(struct dss_hw_ctx *ctx, bool need_clear)
+{
+       void __iomem *dss_base;
+       u32 tmp = 0;
+       u32 isr_s2 = 0;
+
+       if (!ctx) {
+               DRM_ERROR("ctx is NULL!\n");
+               return;
+       }
+
+       dss_base = ctx->base;
+
+       do {
+               isr_s2 = inp32(dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INTS);
+               if (isr_s2 & BIT_VACTIVE0_END) {
+                       DRM_DEBUG("hisi_dss_wait_for_complete exit! temp = 
%d\n", tmp);
+                       if (need_clear)
+                               outp32(dss_base + DSS_LDI0_OFFSET + 
LDI_CPU_ITF_INTS, BIT_VACTIVE0_END);
+                       break;
+               } else {
+                       msleep(1);
+                       tmp++;
+               }
+       } while (tmp < TIME_OUT);
+
+       if (tmp == TIME_OUT) {
+               isr_s2 = inp32(dss_base + DSS_LDI0_OFFSET + LDI_CPU_ITF_INTS);
+               DRM_INFO("wait vactive0_end timeout: isr_s2 = 0x%x\n", isr_s2);
+       }
+}
+#if 0
 static int hisi_vactive0_start_config(struct dss_hw_ctx *ctx)
 {
        int ret = 0;
@@ -1094,6 +1127,7 @@ static int hisi_vactive0_start_config(struct dss_hw_ctx 
*ctx)
 
        return ret;
 }
+#endif
 
 void hisi_fb_pan_display(struct drm_plane *plane)
 {
@@ -1109,9 +1143,6 @@ void hisi_fb_pan_display(struct drm_plane *plane)
        struct kirin_drm_private *priv = plane->dev->dev_private;
        struct kirin_fbdev *fbdev = to_kirin_fbdev(priv->fbdev);
 
-       ktime_t prepare_timestamp;
-       u64 vsync_timediff;
-
        bool afbcd = false;
        bool mmu_enable = true;
        dss_rect_ltrb_t rect;
@@ -1164,26 +1195,7 @@ void hisi_fb_pan_display(struct drm_plane *plane)
        vbp = mode->vtotal - mode->vsync_end;
        vsw = mode->vsync_end - mode->vsync_start;
 
-       vsync_timediff = (uint64_t)(mode->hdisplay + hbp + hfp + hsw) *
-               (mode->vdisplay + vbp + vfp + vsw) *
-               1000000000UL / (adj_mode->clock * 1000);
-
-       prepare_timestamp = ktime_get();
-
-       if ((ktime_to_ns(prepare_timestamp) > 
ktime_to_ns(ctx->vsync_timestamp)) &&
-               (ktime_to_ns(prepare_timestamp) - 
ktime_to_ns(ctx->vsync_timestamp) < (vsync_timediff - 2000000)) &&
-               (ktime_to_ns(ctx->vsync_timestamp_prev) != 
ktime_to_ns(ctx->vsync_timestamp))) {
-               DRM_DEBUG("vsync_timediff=%llu, timestamp_diff=%llu!\n",
-                       vsync_timediff, ktime_to_ns(prepare_timestamp) - 
ktime_to_ns(ctx->vsync_timestamp));
-       } else {
-               DRM_DEBUG("vsync_timediff=%llu.\n", vsync_timediff);
-
-               if (hisi_vactive0_start_config(ctx) != 0) {
-                       DRM_ERROR("hisi_vactive0_start_config failed!\n");
-                       return;
-               }
-       }
-       ctx->vsync_timestamp_prev = ctx->vsync_timestamp;
+       hisi_dss_wait_for_complete(ctx, true);
 
        hisi_dss_mctl_mutex_lock(ctx);
        hisi_dss_aif_ch_config(ctx, chn_idx);
@@ -1198,9 +1210,8 @@ void hisi_fb_pan_display(struct drm_plane *plane)
        hisi_dss_mctl_sys_config(ctx, chn_idx);
        hisi_dss_mctl_mutex_unlock(ctx);
 
-       hisi_dss_unflow_handler(ctx, true);
-
        enable_ldi(acrtc);
+       hisi_dss_wait_for_complete(ctx, false);
 }
 
 void hisi_dss_online_play(struct drm_plane *plane, drm_dss_layer_t *layer)
@@ -1213,9 +1224,6 @@ void hisi_dss_online_play(struct drm_plane *plane, 
drm_dss_layer_t *layer)
        struct dss_crtc *acrtc = aplane->acrtc;
        struct dss_hw_ctx *ctx = acrtc->ctx;
 
-       ktime_t prepare_timestamp;
-       u64 vsync_timediff;
-
        bool afbcd = false;
        bool mmu_enable = true;
        dss_rect_ltrb_t rect;
@@ -1249,28 +1257,7 @@ void hisi_dss_online_play(struct drm_plane *plane, 
drm_dss_layer_t *layer)
        vfp = mode->vsync_start - mode->vdisplay;
        vbp = mode->vtotal - mode->vsync_end;
        vsw = mode->vsync_end - mode->vsync_start;
-
-       vsync_timediff = (uint64_t)(mode->hdisplay + hbp + hfp + hsw) *
-               (mode->vdisplay + vbp + vfp + vsw) *
-               1000000000UL / (adj_mode->clock * 1000);
-
-       prepare_timestamp = ktime_get();
-
-       if ((ktime_to_ns(prepare_timestamp) > 
ktime_to_ns(ctx->vsync_timestamp)) &&
-               (ktime_to_ns(prepare_timestamp) - 
ktime_to_ns(ctx->vsync_timestamp) < (vsync_timediff - 2000000)) &&
-               (ktime_to_ns(ctx->vsync_timestamp_prev) != 
ktime_to_ns(ctx->vsync_timestamp))) {
-               DRM_DEBUG("vsync_timediff=%llu, timestamp_diff=%llu!\n",
-                       vsync_timediff, ktime_to_ns(prepare_timestamp) - 
ktime_to_ns(ctx->vsync_timestamp));
-       } else {
-               DRM_DEBUG("vsync_timediff=%llu.\n", vsync_timediff);
-
-               if (hisi_vactive0_start_config(ctx) != 0) {
-                       DRM_ERROR("hisi_vactive0_start_config failed!\n");
-                       return;
-               }
-       }
-
-       ctx->vsync_timestamp_prev = ctx->vsync_timestamp;
+       hisi_dss_wait_for_complete(ctx, true);
 
        hisi_dss_mctl_mutex_lock(ctx);
        hisi_dss_aif_ch_config(ctx, chn_idx);
@@ -1285,7 +1272,6 @@ void hisi_dss_online_play(struct drm_plane *plane, 
drm_dss_layer_t *layer)
        hisi_dss_mctl_sys_config(ctx, chn_idx);
        hisi_dss_mctl_mutex_unlock(ctx);
 
-       hisi_dss_unflow_handler(ctx, true);
-
        enable_ldi(acrtc);
+       hisi_dss_wait_for_complete(ctx, false);
 }
-- 
2.26.2

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to