From: Liwei Cai <cailiwei@xxxxxxxxxxxxx> The use of synchronization mechanisms to deal with the display of buffer, to solve the problem of display tearing. Signed-off-by: Wanchun Zheng <zhengwanchun@xxxxxxxxxxxxx> Signed-off-by: Liwei Cai <cailiwei@xxxxxxxxxxxxx> Signed-off-by: John Stultz <john.stultz@xxxxxxxxxx> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx> --- 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 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel