From dddb10147f94f5e09ac5f28b3d60bac8d51baae7 Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Mon, 15 Nov 2021 20:09:23 -0800 Subject: [PATCH 1/5] disp: msm: enable cache flag for dumb buffer For dumb buffer allocation switch to cached flag from current use of write combine. Change-Id: Ic3dc88ff83a083e4f386c2aecc27ce71324e06f5 Signed-off-by: Prabhanjan Kandula --- msm/msm_gem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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, From 92cbd6d65413ae31d5a4ce54bae4c1cef2e9849a Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Mon, 29 Nov 2021 17:28:03 -0800 Subject: [PATCH 2/5] disp: msm: sde: while timing engine enabling poll for active region DCS commands triggered right after timing engine enable can conflict with blanking period causing command transfer failures. Right after timing engine enable poll for frame start and line count reaching active region of display before any DCS commands. Change-Id: Ia3967e01c3bb5bc82aa3549c300fa8335e00210c Signed-off-by: Prabhanjan Kandula --- msm/sde/sde_encoder_phys_vid.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) 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; } From 9ab14dedc289b73d6291cd636f936ae484771de2 Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Wed, 24 Nov 2021 17:21:46 -0800 Subject: [PATCH 3/5] disp: msm: sde: update cached encoder mask if required When a new connector is added or removed an a crtc because of clone mode enable and disable update cached encoder mask. Currently since cached encoder mask is not updated properly vblank frame counter is returning wb encoder frame counter right after clone mode disable on wb encoder. Change-Id: Ieff9dfbf0c7df3688fb1b6f9d3f3614345b494c2 Signed-off-by: Prabhanjan Kandula --- msm/sde/sde_crtc.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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; From add2cb79c915a5971dfa13fe1fcd7bcba6939adb Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Mon, 6 Dec 2021 23:53:53 -0800 Subject: [PATCH 4/5] disp: msm: ensure vbif debugbus not in use is disabled Ensure register write is complete with a write barrier while disabling other vbif debugbus when not in use and also while clearing the test point. Change-Id: I40da69027f86e13f4a71d87ad3975f94a5a1cb31 Signed-off-by: Prabhanjan Kandula --- msm/sde_dbg.c | 3 +++ 1 file changed, 3 insertions(+) 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, From 6547137f7b81b678be4d9229b1696eb6f9851653 Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Thu, 2 Dec 2021 22:52:23 -0800 Subject: [PATCH 5/5] disp: msm: sde: consider max of actual and default prefill lines In transfer-time calculation remove fixed prefill lines assumption and consider max of default prefill lines and prefill lines specified from the panel timing info. For panels with higher porches exceeding default prefill lines alternate framedrops can occur if transfer-time exceeds RSC static waketup time as actual prefill lines are considered in RSC static wakeup timer calculation. This change ensures transfer-time is with in RSC static wakeup time. Change-Id: I3663f9c9179efb7225a748f456f2a2cf167d241e Signed-off-by: Prabhanjan Kandula --- msm/dsi/dsi_panel.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 81f21d200f..084dd6c376 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -3946,6 +3946,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; @@ -4009,8 +4010,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));