diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index c4a0ae0d8f..c4cdfc0233 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -3949,6 +3949,7 @@ void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config, struct dsi_mode_info *timing = &mode->timing; struct dsi_display_mode *display_mode; u32 jitter_numer, jitter_denom, prefill_lines; + u32 default_prefill_lines, actual_prefill_lines; u32 min_threshold_us, prefill_time_us, max_transfer_us, packet_overhead; u16 bpp; @@ -4012,8 +4013,12 @@ void dsi_panel_calc_dsi_transfer_time(struct dsi_host_common_cfg *config, * Increase the prefill_lines proportionately as recommended * 40lines for 60fps, 60 for 90fps, 120lines for 120fps, and so on. */ - prefill_lines = mult_frac(MIN_PREFILL_LINES, - timing->refresh_rate, 60); + default_prefill_lines = mult_frac(MIN_PREFILL_LINES, timing->refresh_rate, 60); + + actual_prefill_lines = timing->v_back_porch + timing->v_front_porch + timing->v_sync_width; + + /* consider the max of default prefill lines and actual prefill lines */ + prefill_lines = max(actual_prefill_lines, default_prefill_lines); prefill_time_us = mult_frac(frame_time_us, prefill_lines, (timing->v_active)); diff --git a/msm/msm_gem.c b/msm/msm_gem.c index dfc5223cd4..f7fdc8eef7 100644 --- a/msm/msm_gem.c +++ b/msm/msm_gem.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -691,7 +692,7 @@ int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev, args->pitch = align_pitch(args->width, args->bpp); args->size = PAGE_ALIGN(args->pitch * args->height); return msm_gem_new_handle(dev, file, args->size, - MSM_BO_SCANOUT | MSM_BO_WC, &args->handle, "dumb"); + MSM_BO_SCANOUT | MSM_BO_CACHED, &args->handle, "dumb"); } int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev, diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index f05602b961..3b73775238 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3615,6 +3615,10 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, test_and_clear_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask); + /* update cached_encoder_mask if new conn is added or removed */ + if (crtc->state->connectors_changed) + sde_crtc->cached_encoder_mask = crtc->state->encoder_mask; + /* * Since CP properties use AXI buffer to program the * HW, check if context bank is in attached state, @@ -5510,6 +5514,8 @@ static u32 sde_crtc_get_vblank_counter(struct drm_crtc *crtc) { struct drm_encoder *encoder; struct sde_crtc *sde_crtc; + bool is_built_in; + u32 vblank_cnt; if (!crtc) return 0; @@ -5520,7 +5526,14 @@ static u32 sde_crtc_get_vblank_counter(struct drm_crtc *crtc) if (sde_encoder_in_clone_mode(encoder)) continue; - return sde_encoder_get_frame_count(encoder); + is_built_in = sde_encoder_is_built_in_display(encoder); + vblank_cnt = sde_encoder_get_frame_count(encoder); + + SDE_EVT32(DRMID(crtc), DRMID(encoder), is_built_in, vblank_cnt); + SDE_DEBUG("crtc:%d enc:%d is_built_in:%d vblank_cnt:%d\n", + DRMID(crtc), DRMID(encoder), is_built_in, vblank_cnt); + + return vblank_cnt; } return 0; diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index 90d9dc608f..60133eae16 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -1129,12 +1129,41 @@ exit: phys_enc->enable_state = SDE_ENC_DISABLED; } +static int sde_encoder_phys_vid_poll_for_active_region(struct sde_encoder_phys *phys_enc) +{ + struct sde_encoder_phys_vid *vid_enc; + struct intf_timing_params *timing; + u32 line_cnt, v_inactive, poll_time_us, trial = 0; + + if (!phys_enc || !phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_line_count) + return -EINVAL; + + vid_enc = to_sde_encoder_phys_vid(phys_enc); + timing = &vid_enc->timing_params; + + /* if programmable fetch is not enabled return early */ + if (!programmable_fetch_get_num_lines(vid_enc, timing)) + return 0; + + poll_time_us = DIV_ROUND_UP(1000000, timing->vrefresh) / MAX_POLL_CNT; + v_inactive = timing->v_front_porch + timing->v_back_porch + timing->vsync_pulse_width; + + do { + usleep_range(poll_time_us, poll_time_us + 5); + line_cnt = phys_enc->hw_intf->ops.get_line_count(phys_enc->hw_intf); + trial++; + } while ((trial < MAX_POLL_CNT) || (line_cnt < v_inactive)); + + return (trial >= MAX_POLL_CNT) ? -ETIMEDOUT : 0; +} + static void sde_encoder_phys_vid_handle_post_kickoff( struct sde_encoder_phys *phys_enc) { unsigned long lock_flags; struct sde_encoder_phys_vid *vid_enc; u32 avr_mode; + u32 ret; if (!phys_enc) { SDE_ERROR("invalid encoder\n"); @@ -1157,6 +1186,10 @@ static void sde_encoder_phys_vid_handle_post_kickoff( 1); spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags); + + ret = sde_encoder_phys_vid_poll_for_active_region(phys_enc); + if (ret) + SDE_DEBUG_VIDENC(vid_enc, "poll for active failed ret:%d\n", ret); } phys_enc->enable_state = SDE_ENC_ENABLED; } diff --git a/msm/sde_dbg.c b/msm/sde_dbg.c index 4c9888b220..76f36915b5 100755 --- a/msm/sde_dbg.c +++ b/msm/sde_dbg.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2009-2021, The Linux Foundation. All rights reserved. */ @@ -866,6 +867,7 @@ static void _sde_dbg_vbif_disable_block(void __iomem *mem_base, u32 wr_addr) MMSS_VBIF_TEST_BUS2_CTRL0 : MMSS_VBIF_TEST_BUS1_CTRL0; writel_relaxed(0, mem_base + disable_addr); writel_relaxed(BIT(0), mem_base + MMSS_VBIF_TEST_BUS_OUT_CTRL); + wmb(); /* update test bus */ } static u32 _sde_dbg_vbif_read_test_point(void __iomem *mem_base, u32 wr_addr, u32 rd_addr, @@ -881,6 +883,7 @@ static void _sde_dbg_vbif_clear_test_point(void __iomem *mem_base, u32 wr_addr) { writel_relaxed(0, mem_base + wr_addr); writel_relaxed(0, mem_base + wr_addr + 0x4); + wmb(); /* update test point clear */ } static u32 _sde_dbg_sde_read_test_point(void __iomem *mem_base, u32 wr_addr, u32 rd_addr,