diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc.c b/drivers/gpu/drm/rockchip/rockchip_ebc.c index 14ef79a37566..aa10d712bdef 100644 --- a/drivers/gpu/drm/rockchip/rockchip_ebc.c +++ b/drivers/gpu/drm/rockchip/rockchip_ebc.c @@ -785,7 +785,7 @@ static void rockchip_ebc_partial_refresh(struct rockchip_ebc *ebc, bool skip_advance = false; time_start_advance = ktime_get(); - // All currently scheduled pixels have finished and we have a work item + // All currently scheduled pixels are IDLE or WAITING have finished and we have a work item if (drm_rect_width(&clip_ongoing) <= 0 && work_item) { // Refresh work item spin_lock(&ebc->work_item_lock); @@ -840,6 +840,12 @@ static void rockchip_ebc_partial_refresh(struct rockchip_ebc *ebc, if (work_item & ROCKCHIP_EBC_WORK_ITEM_CHANGE_LUT) { rockchip_ebc_change_lut(ebc); print_lut(ebc); + // Reset inner and outer to make sure + // pixels that were WAITING stay + // valid. For simplicity, set to IDLE. + kernel_neon_begin(); + rockchip_ebc_reset_inner_outer_neon(ebc); + kernel_neon_end(); } if (work_item & ROCKCHIP_EBC_WORK_ITEM_INIT) { clip_ongoing_or_waiting = ebc->screen_rect; @@ -912,23 +918,28 @@ static void rockchip_ebc_partial_refresh(struct rockchip_ebc *ebc, pr_debug("%s ebc->driver_mode=%d enabling_mode=%d", __func__, ebc->driver_mode, enabling_mode); if (drm_rect_width(&clip_ongoing_or_waiting) > 0 && !skip_advance) { + u8 force_hint = 0; + // Disable redraws of redraw_delay <= 0 + u8 force_hint_mask = ebc->redraw_delay > 0 ? 0 : ROCKCHIP_EBC_HINT_REDRAW; if (ebc->driver_mode == ROCKCHIP_EBC_DRIVER_MODE_FAST) { kernel_neon_begin(); rockchip_ebc_schedule_advance_fast_neon( - ebc, prelim_target, hints, - phase_buffer, &clip_ongoing, - &clip_ongoing_or_waiting, - early_cancellation_addition, 0, 0, 0, - !no_schedule_until_clip_empty && !work_item); + ebc, prelim_target, hints, phase_buffer, + &clip_ongoing, &clip_ongoing_or_waiting, + early_cancellation_addition, 0, + force_hint, force_hint_mask, + !no_schedule_until_clip_empty && + !work_item); kernel_neon_end(); } else if (ebc->driver_mode == ROCKCHIP_EBC_DRIVER_MODE_NORMAL) { kernel_neon_begin(); rockchip_ebc_schedule_advance_neon( - ebc, prelim_target, hints, - phase_buffer, &clip_ongoing, - &clip_ongoing_or_waiting, - early_cancellation_addition, 0, 0, 0, - !no_schedule_until_clip_empty && !work_item); + ebc, prelim_target, hints, phase_buffer, + &clip_ongoing, &clip_ongoing_or_waiting, + early_cancellation_addition, 0, + force_hint, force_hint_mask, + !no_schedule_until_clip_empty && + !work_item); kernel_neon_end(); } } diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc.h b/drivers/gpu/drm/rockchip/rockchip_ebc.h index 836a06afefa5..88d9d3975171 100644 --- a/drivers/gpu/drm/rockchip/rockchip_ebc.h +++ b/drivers/gpu/drm/rockchip/rockchip_ebc.h @@ -243,6 +243,7 @@ void rockchip_ebc_blit_fb_r8_y4_hints_neon(const struct rockchip_ebc *ebc, const struct drm_framebuffer *fb, const struct drm_rect *src_clip); +void rockchip_ebc_reset_inner_outer_neon(const struct rockchip_ebc *ebc); #define DRM_RECT_EMPTY_EXTANDABLE DRM_RECT_INIT(100000, 100000, -100000, -100000); diff --git a/drivers/gpu/drm/rockchip/rockchip_ebc_blit_neon.c b/drivers/gpu/drm/rockchip/rockchip_ebc_blit_neon.c index d53624ee30df..76b1b6d7d1bf 100644 --- a/drivers/gpu/drm/rockchip/rockchip_ebc_blit_neon.c +++ b/drivers/gpu/drm/rockchip/rockchip_ebc_blit_neon.c @@ -1231,6 +1231,22 @@ void rockchip_ebc_blit_fb_r8_y4_hints_neon(const struct rockchip_ebc *ebc, } EXPORT_SYMBOL(rockchip_ebc_blit_fb_r8_y4_hints_neon); +void rockchip_ebc_reset_inner_outer_neon(const struct rockchip_ebc *ebc) +{ + u8 *packed_inner_outer_nextprev_line = ebc->packed_inner_outer_nextprev; + uint8x16_t q8_0x00 = vdupq_n_u8(0x00); + for (int i = 0; i < ebc->num_pixels; i += 16) { + uint8x16x3_t q8_inner_outer_nextprev = vld3q_u8(packed_inner_outer_nextprev_line); + uint8x16x3_t q8_inner_outer_nextprev_new = { + { q8_0x00, q8_0x00, q8_inner_outer_nextprev.val[2] } + }; + vst3q_u8(packed_inner_outer_nextprev_line, + q8_inner_outer_nextprev_new); + packed_inner_outer_nextprev_line += 48; + } +} +EXPORT_SYMBOL(rockchip_ebc_reset_inner_outer_neon); + MODULE_AUTHOR("hrdl "); MODULE_DESCRIPTION("Rockchip EBC NEON functions"); MODULE_LICENSE("GPL v2");