From b9b744a123339b9b82dce7d1f142048903f19499 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Fri, 26 Nov 2021 15:07:45 +0530 Subject: [PATCH 01/46] disp: msm: sde: reset CTL_UIDLE_ACTIVE register only if uidle is disabled This change sets CTL_UIDLE_ACTIVE register whenever uidle is enabled and resets it only when uidle is disabled. Change-Id: I0393d1585df4fdb79a844d04df62ac9eda949232 Signed-off-by: Yashwanth --- msm/sde/sde_crtc.c | 2 +- msm/sde/sde_encoder.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 55c93c2eb2..94a538e2bb 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3606,7 +3606,7 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, if (crtc->state->mode_changed || sde_kms->perf.catalog->uidle_cfg.dirty) { sde_core_perf_crtc_update_uidle(crtc, true); } else if (!test_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask) && - sde_kms->perf.uidle_enabled) + !sde_kms->perf.uidle_enabled) sde_core_perf_uidle_setup_ctl(crtc, false); test_and_clear_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask); diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index d6a35dcfd8..d3ba200696 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -140,7 +140,8 @@ void sde_encoder_uidle_enable(struct drm_encoder *drm_enc, bool enable) struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->hw_ctl && phys->hw_ctl->ops.uidle_enable) { - SDE_EVT32(DRMID(drm_enc), enable); + if (enable) + SDE_EVT32(DRMID(drm_enc), enable); phys->hw_ctl->ops.uidle_enable(phys->hw_ctl, enable); } } From 093d93ed584b5fe61435a2f3133695522e18ebe3 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Wed, 1 Dec 2021 17:11:41 +0530 Subject: [PATCH 02/46] disp: msm: sde: update vm state atomic check for non-primary usecases If vm has already transitioned from primary to trusted, triggering a wb/secondary display commit will result in crash since hw is not owned by the vm. This change adds necessary changes to fail atomic check in such usecases. Change-Id: Ic9886d479726c27d1072d12304a87f3bf5deeb76 Signed-off-by: Yashwanth --- msm/sde/sde_kms.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 158f2f896e..3a104bba2f 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -2861,7 +2862,7 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, struct sde_vm_ops *vm_ops; enum sde_crtc_vm_req old_vm_req = VM_REQ_NONE, new_vm_req = VM_REQ_NONE; int i, rc = 0; - bool vm_req_active = false; + bool vm_req_active = false, prev_vm_req = false; bool vm_owns_hw; if (!kms || !state) @@ -2875,6 +2876,14 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, if (!vm_ops->vm_request_valid || !vm_ops->vm_owns_hw || !vm_ops->vm_acquire) return -EINVAL; + drm_for_each_crtc(crtc, state->dev) { + if (crtc->state && (sde_crtc_get_property(to_sde_crtc_state(crtc->state), + CRTC_PROP_VM_REQ_STATE) == VM_REQ_RELEASE)) { + prev_vm_req = true; + break; + } + } + /* check for an active vm request */ for_each_oldnew_crtc_in_state(state, crtc, old_cstate, new_cstate, i) { struct sde_crtc_state *old_state = NULL, *new_state = NULL; @@ -2888,8 +2897,12 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, old_state = to_sde_crtc_state(old_cstate); old_vm_req = sde_crtc_get_property(old_state, CRTC_PROP_VM_REQ_STATE); - /* No active request if the transition is from VM_REQ_NONE to VM_REQ_NONE */ - if (old_vm_req || new_vm_req) { + /* + * VM request should be validated in the following usecases + * - There is a vm request(other than VM_REQ_NONE) on current/prev crtc state. + * - Previously, vm transition has taken place on one of the crtc's. + */ + if (old_vm_req || new_vm_req || prev_vm_req) { if (!vm_req_active) { sde_vm_lock(sde_kms); vm_owns_hw = sde_vm_owns_hw(sde_kms); From 8b01e6124e7b411ee5f26968f1a3546212672c5c Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Fri, 3 Dec 2021 13:17:08 +0530 Subject: [PATCH 03/46] disp: msm: sde: reset mixers in crtc when ctl datapath switches This change reinitializes the sde_crtc->mixers when CTL datapath switch occurs during mode set and RM allocation of CTL hw block is changed. This initialization is required for CTL_LAYER programming to trigger on the new CTL allocated from RM. Issue case: 1. Primary Display is using CTL_0 and it is reserved. 2. Secondary Display is using CTL_1. On suspend, RM adds CTL_1 into the free list. 3. External Display is powered on, RM allocates CTL_1 hw blk. 4. Secondary Display is powered on, RM allocated CTL_2 hw blk. 5. External Display is suspended/unplugged, RM adds CTL_1 into the free list. 6. When any mode_set(say fps switch) occurs on secondary, RM allocates new resources and CTL_1 is allocated. sde_crtc->num_mixers is non zero, so all the layer programming happens on CTL_2, but CTL_1_FLUSH bits are programmed causing hw timeout issue. Change-Id: I5f1f52b7673740c48b249ab4d36e80b7a1d3db96 Signed-off-by: Jayaprakash Madisetty --- msm/sde/sde_crtc.c | 4 ++++ msm/sde/sde_crtc.h | 3 +++ msm/sde/sde_encoder.c | 6 +++++- msm/sde/sde_encoder_phys.h | 3 ++- msm/sde/sde_encoder_phys_cmd.c | 11 +++++++++-- msm/sde/sde_encoder_phys_vid.c | 11 +++++++++-- msm/sde/sde_encoder_phys_wb.c | 11 +++++++++-- 7 files changed, 41 insertions(+), 8 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 55c93c2eb2..7652b2739e 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -3578,6 +3579,9 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, _sde_crtc_setup_is_ppsplit(crtc->state); _sde_crtc_setup_lm_bounds(crtc, crtc->state); _sde_crtc_clear_all_blend_stages(sde_crtc); + } else if (sde_crtc->num_mixers && sde_crtc->reinit_crtc_mixers) { + _sde_crtc_setup_mixers(crtc); + sde_crtc->reinit_crtc_mixers = false; } list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 6ea3d62ef7..4fb361d12b 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -316,6 +317,7 @@ struct sde_frame_data { * @ltm_buffer_lock : muttx to protect ltm_buffers allcation and free * @ltm_lock : Spinlock to protect ltm buffer_cnt, hist_en and ltm lists * @needs_hw_reset : Initiate a hw ctl reset + * @reinit_crtc_mixers : Reinitialize mixers in crtc * @hist_irq_idx : hist interrupt irq idx * @disable_pending_cp : flag tracks pending color processing features force disable * @src_bpp : source bpp used to calculate compression ratio @@ -415,6 +417,7 @@ struct sde_crtc { struct mutex ltm_buffer_lock; spinlock_t ltm_lock; bool needs_hw_reset; + bool reinit_crtc_mixers; int hist_irq_idx; bool disable_pending_cp; diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index d6a35dcfd8..94dee66315 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -2487,6 +2488,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, struct drm_connector *conn; struct sde_connector_state *c_state; struct msm_display_mode *msm_mode; + struct sde_crtc *sde_crtc; int i = 0, ret; int num_lm, num_intf, num_pp_per_intf; @@ -2518,6 +2520,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, } sde_enc->crtc = drm_enc->crtc; + sde_crtc = to_sde_crtc(drm_enc->crtc); sde_crtc_set_qos_dirty(drm_enc->crtc); /* get and store the mode_info */ @@ -2577,7 +2580,8 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, phys->hw_pp = sde_enc->hw_pp[i * num_pp_per_intf]; phys->connector = conn; if (phys->ops.mode_set) - phys->ops.mode_set(phys, mode, adj_mode); + phys->ops.mode_set(phys, mode, adj_mode, + &sde_crtc->reinit_crtc_mixers); } } diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index 740b649684..353e47e570 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -146,7 +147,7 @@ struct sde_encoder_phys_ops { struct drm_display_mode *adjusted_mode); void (*mode_set)(struct sde_encoder_phys *encoder, struct drm_display_mode *mode, - struct drm_display_mode *adjusted_mode); + struct drm_display_mode *adjusted_mode, bool *reinit_mixers); void (*cont_splash_mode_set)(struct sde_encoder_phys *encoder, struct drm_display_mode *adjusted_mode); void (*enable)(struct sde_encoder_phys *encoder); diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index d48957508c..29b9005ad7 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -406,7 +407,7 @@ static void sde_encoder_phys_cmd_cont_splash_mode_set( static void sde_encoder_phys_cmd_mode_set( struct sde_encoder_phys *phys_enc, struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) + struct drm_display_mode *adj_mode, bool *reinit_mixers) { struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc); @@ -427,8 +428,14 @@ static void sde_encoder_phys_cmd_mode_set( /* Retrieve previously allocated HW Resources. Shouldn't fail */ sde_rm_init_hw_iter(&iter, phys_enc->parent->base.id, SDE_HW_BLK_CTL); for (i = 0; i <= instance; i++) { - if (sde_rm_get_hw(rm, &iter)) + if (sde_rm_get_hw(rm, &iter)) { + if (phys_enc->hw_ctl && phys_enc->hw_ctl != iter.hw) { + *reinit_mixers = true; + SDE_EVT32(phys_enc->hw_ctl->idx, + ((struct sde_hw_ctl *)iter.hw)->idx); + } phys_enc->hw_ctl = (struct sde_hw_ctl *)iter.hw; + } } if (IS_ERR_OR_NULL(phys_enc->hw_ctl)) { diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index d8a800c353..90d9dc608f 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -606,7 +607,7 @@ static void sde_encoder_phys_vid_cont_splash_mode_set( static void sde_encoder_phys_vid_mode_set( struct sde_encoder_phys *phys_enc, struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) + struct drm_display_mode *adj_mode, bool *reinit_mixers) { struct sde_rm *rm; struct sde_rm_hw_iter iter; @@ -632,8 +633,14 @@ static void sde_encoder_phys_vid_mode_set( /* Retrieve previously allocated HW Resources. Shouldn't fail */ sde_rm_init_hw_iter(&iter, phys_enc->parent->base.id, SDE_HW_BLK_CTL); for (i = 0; i <= instance; i++) { - if (sde_rm_get_hw(rm, &iter)) + if (sde_rm_get_hw(rm, &iter)) { + if (phys_enc->hw_ctl && phys_enc->hw_ctl != iter.hw) { + *reinit_mixers = true; + SDE_EVT32(phys_enc->hw_ctl->idx, + ((struct sde_hw_ctl *)iter.hw)->idx); + } phys_enc->hw_ctl = (struct sde_hw_ctl *)iter.hw; + } } if (IS_ERR_OR_NULL(phys_enc->hw_ctl)) { SDE_ERROR_VIDENC(vid_enc, "failed to init ctl, %ld\n", diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 9ac21bab89..15e16048aa 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -1355,7 +1356,7 @@ static void sde_encoder_phys_wb_irq_ctrl( static void sde_encoder_phys_wb_mode_set( struct sde_encoder_phys *phys_enc, struct drm_display_mode *mode, - struct drm_display_mode *adj_mode) + struct drm_display_mode *adj_mode, bool *reinit_mixers) { struct sde_encoder_phys_wb *wb_enc = to_sde_encoder_phys_wb(phys_enc); struct sde_rm *rm = &phys_enc->sde_kms->rm; @@ -1377,8 +1378,14 @@ static void sde_encoder_phys_wb_mode_set( sde_rm_init_hw_iter(&iter, phys_enc->parent->base.id, SDE_HW_BLK_CTL); for (i = 0; i <= instance; i++) { sde_rm_get_hw(rm, &iter); - if (i == instance) + if (i == instance) { + if (phys_enc->hw_ctl && phys_enc->hw_ctl != iter.hw) { + *reinit_mixers = true; + SDE_EVT32(phys_enc->hw_ctl->idx, + ((struct sde_hw_ctl *)iter.hw)->idx); + } phys_enc->hw_ctl = (struct sde_hw_ctl *) iter.hw; + } } if (IS_ERR_OR_NULL(phys_enc->hw_ctl)) { From e0d90143fd1139158b7510a0d25e83504d95ba34 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Thu, 2 Dec 2021 16:26:40 +0530 Subject: [PATCH 04/46] disp: msm: dsi: set qsync min fps list length to zero In certain usecase where qsync is enabled without qsync min fps list, incorrect list length might cause issues while populating modes. This change sets qsync_min_fps length to zero if its empty which resolves such issues. Change-Id: I23083d8fd9610665dad63188f5d2db7eb6b23ee1 Signed-off-by: Mahadevan --- msm/dsi/dsi_panel.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index e98822da18..81f21d200f 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -1334,8 +1335,10 @@ static int dsi_panel_parse_qsync_caps(struct dsi_panel *panel, */ qsync_caps->qsync_min_fps_list_len = utils->count_u32_elems(utils->data, "qcom,dsi-supported-qsync-min-fps-list"); - if (qsync_caps->qsync_min_fps_list_len < 1) + if (qsync_caps->qsync_min_fps_list_len < 1) { + qsync_caps->qsync_min_fps_list_len = 0; goto qsync_support; + } /** * qcom,dsi-supported-qsync-min-fps-list cannot be defined From fb1593028010dca383c5e53e625b21a39b4a788d Mon Sep 17 00:00:00 2001 From: Abhijit Kulkarni Date: Mon, 29 Nov 2021 10:38:43 -0800 Subject: [PATCH 05/46] disp: msm: sde: avoid race condition at vm release This change acquires the vm lock before pre-releasing the dependent drivers. This avoids any race condition on any parallel async commands transfers scheduled on connector drivers. Additionally the main irq line is only disabled after the pre-release to allow any ongoing transfers to complete. Change-Id: Ic0bffc93ebb1b69fbd8d1f096b320a86ad84c857 Signed-off-by: Abhijit Kulkarni --- msm/sde/sde_kms.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 158f2f896e..aebe009c9d 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -1340,9 +1341,11 @@ int sde_kms_vm_pre_release(struct sde_kms *sde_kms, /* if vm_req is enabled, once CRTC on the commit is guaranteed */ sde_kms_wait_for_frame_transfer_complete(&sde_kms->base, crtc); + sde_dbg_set_hw_ownership_status(false); + sde_kms_cancel_delayed_work(crtc); - /* disable SDE irq's */ + /* disable SDE encoder irq's */ drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) { if (sde_encoder_in_clone_mode(encoder)) @@ -1352,8 +1355,6 @@ int sde_kms_vm_pre_release(struct sde_kms *sde_kms, } if (is_primary) { - /* disable IRQ line */ - sde_irq_update(&sde_kms->base, false); /* disable vblank events */ drm_crtc_vblank_off(crtc); @@ -1362,8 +1363,6 @@ int sde_kms_vm_pre_release(struct sde_kms *sde_kms, sde_crtc_reset_sw_state(crtc); } - sde_dbg_set_hw_ownership_status(false); - return rc; } @@ -1447,17 +1446,22 @@ int sde_kms_vm_primary_post_commit(struct sde_kms *sde_kms, /* properly handoff color processing features */ sde_cp_crtc_vm_primary_handoff(crtc); + sde_vm_lock(sde_kms); + /* handle non-SDE clients pre-release */ if (vm_ops->vm_client_pre_release) { rc = vm_ops->vm_client_pre_release(sde_kms); if (rc) { SDE_ERROR("sde vm client pre_release failed, rc=%d\n", rc); + sde_vm_unlock(sde_kms); goto exit; } } - sde_vm_lock(sde_kms); + /* disable IRQ line */ + sde_irq_update(&sde_kms->base, false); + /* release HW */ if (vm_ops->vm_release) { rc = vm_ops->vm_release(sde_kms); From 00468713c6421910fba3c604d6c0e59da28c70b3 Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Fri, 19 Nov 2021 16:14:24 -0500 Subject: [PATCH 06/46] disp: msm: sde: disable ot limit for cwb Currently ot limits are being set for concurrent writeback, which is not supported. This change adds a check to correctly set wfd parameter while applying ot limit settings. Change-Id: I87c1ca756c1714fec4466cd5a5a820ddf2519975 Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_encoder_phys_wb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 15e16048aa..f1a8775267 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -88,7 +88,7 @@ static void sde_encoder_phys_wb_set_ot_limit( ot_params.num = hw_wb->idx - WB_0; ot_params.width = wb_enc->wb_roi.w; ot_params.height = wb_enc->wb_roi.h; - ot_params.is_wfd = true; + ot_params.is_wfd = !(phys_enc->in_clone_mode); ot_params.frame_rate = drm_mode_vrefresh(&phys_enc->cached_mode); ot_params.vbif_idx = hw_wb->caps->vbif_idx; ot_params.clk_ctrl = hw_wb->caps->clk_ctrl; From dddb10147f94f5e09ac5f28b3d60bac8d51baae7 Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Mon, 15 Nov 2021 20:09:23 -0800 Subject: [PATCH 07/46] 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 08/46] 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 09/46] 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 10/46] 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 11/46] 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)); From 93971106b489313c89f50d10163740b1f3f76aff Mon Sep 17 00:00:00 2001 From: Rajkumar Subbiah Date: Mon, 22 Nov 2021 20:14:53 -0500 Subject: [PATCH 12/46] disp: msm: dp: avoid dp sw reset on disconnect path In an effort to reset the DP controller states on a disconnect, the driver is issuing a SW reset to the controller. But SW reset on the controller doesn't necessarily restore the controller to its full reset state. It only resets part of the logic. So if for some reason the MST streams were not disabled properly, ie. the slot allocations were not reset properly in the controller, then a SW reset would result in the DP controller raising state interrupts. Since this SW reset is issued in the tail end of the disconnect processing, the driver turns off all the clocks and also removes the irq handler. This results in an interrupt storm at the MDSS top level. This change removes the SW reset on the disconnect path and relies on the SW reset that already exists in the connect path to restore controller state. Change-Id: Ie7115e17d3c50c46c83c6f0e333da5cb534b8227 Signed-off-by: Rajkumar Subbiah --- msm/dp/dp_ctrl.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index b564d5870e..0792d8242f 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ @@ -1421,7 +1422,7 @@ static void dp_ctrl_off(struct dp_ctrl *dp_ctrl) ctrl->catalog->fec_config(ctrl->catalog, false); dp_ctrl_configure_source_link_params(ctrl, false); - ctrl->catalog->reset(ctrl->catalog); + dp_ctrl_state_ctrl(ctrl, 0); /* Make sure DP is disabled before clk disable */ wmb(); From 31d274ebb7e12fe64a75a7ea096bdd9550cc59bd Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Mon, 6 Dec 2021 19:17:11 +0530 Subject: [PATCH 13/46] disp: msm: sde: allow qsync update along with modeset This change allows concurrent qsync updates along with DMS modeset condition. With this change, qsync can be enabled or disabled in the same atomic commit along with MSM_MODE_FLAG_SEAMLESS_DMS condition. Change-Id: I1b51a68f947126b25a578645e92d95c9a8ae26f5 Signed-off-by: Yashwanth --- msm/sde/sde_encoder.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index d6a35dcfd8..2cee23c31d 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1127,10 +1127,8 @@ static int _sde_encoder_atomic_check_qsync(struct sde_connector *sde_conn, qsync_dirty = msm_property_is_dirty(&sde_conn->property_info, &sde_conn_state->property_state, CONNECTOR_PROP_QSYNC_MODE); - if (has_modeset && qsync_dirty && - (msm_is_mode_seamless_poms(&sde_conn_state->msm_mode) || - msm_is_mode_seamless_dms(&sde_conn_state->msm_mode) || - msm_is_mode_seamless_dyn_clk(&sde_conn_state->msm_mode))) { + if (has_modeset && qsync_dirty && (msm_is_mode_seamless_poms(&sde_conn_state->msm_mode) || + msm_is_mode_seamless_dyn_clk(&sde_conn_state->msm_mode))) { SDE_ERROR("invalid qsync update during modeset priv flag:%x\n", sde_conn_state->msm_mode.private_flags); return -EINVAL; From 13e728953c945cce7779a507f410a56b804896d6 Mon Sep 17 00:00:00 2001 From: Kalyan Thota Date: Wed, 1 Dec 2021 06:08:26 -0800 Subject: [PATCH 14/46] disp: msm: sde: flush esd work before disabling the encoder Flush ESD status work before resetting the encoder state during virt_disable sequence to avoid stale pointers being used in the ESD work. Change-Id: I4bb08a7a7ae33ad6386169667692736e554141c4 Signed-off-by: Kalyan Thota --- msm/sde/sde_connector.c | 2 +- msm/sde/sde_encoder.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 765b9281e3..89ce80fedd 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -2769,7 +2769,7 @@ static void sde_connector_check_status_work(struct work_struct *work) dev = conn->base.dev->dev; if (!conn->ops.check_status || dev->power.is_suspended || - (conn->dpms_mode != DRM_MODE_DPMS_ON)) { + (conn->lp_mode == SDE_MODE_DPMS_OFF)) { SDE_DEBUG("dpms mode: %d\n", conn->dpms_mode); mutex_unlock(&conn->lock); return; diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index d6a35dcfd8..e8f212e083 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -3066,6 +3066,7 @@ void sde_encoder_virt_reset(struct drm_encoder *drm_enc) static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; + struct sde_connector *sde_conn; struct sde_kms *sde_kms; enum sde_intf_mode intf_mode; int ret, i = 0; @@ -3087,6 +3088,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) } sde_enc = to_sde_encoder_virt(drm_enc); + sde_conn = to_sde_connector(sde_enc->cur_master->connector); SDE_DEBUG_ENC(sde_enc, "\n"); sde_kms = sde_encoder_get_kms(&sde_enc->base); @@ -3103,6 +3105,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) _sde_encoder_input_handler_unregister(drm_enc); + flush_delayed_work(&sde_conn->status_work); /* * For primary command mode and video mode encoders, execute the * resource control pre-stop operations before the physical encoders From 73b252c722e35cac94b37aa05bd1cd0635aca90d Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Thu, 16 Dec 2021 11:25:43 +0530 Subject: [PATCH 15/46] disp: msm: sde: update idle_pc_enabled flag for all encoders At present, idle_pc_enabled flag will be set for encoders containing only these capabilities MSM_DISPLAY_CAP_CMD_MODE and MSM_DISPLAY_CAP_VID_MODE. When cwb is triggered,extra power vote will be taken during kickoff and vote remains till cwb is disabled. In between, if primary goes into idle power collapse, vote taken by cwb will not be removed since idle_pc_enabled flag is not set. This change updates idle_pc_enabled flag for all encoders based on catalog property. Change-Id: If4f147edbd610d0302e4d6c0a3e6b7de2c729db1 Signed-off-by: Yashwanth --- msm/sde/sde_encoder.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 7a527b164d..f3d5a807da 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -5082,9 +5082,7 @@ static int sde_encoder_setup_display(struct sde_encoder_virt *sde_enc, SDE_DEBUG("dsi_info->num_of_h_tiles %d\n", disp_info->num_of_h_tiles); - if ((disp_info->capabilities & MSM_DISPLAY_CAP_CMD_MODE) || - (disp_info->capabilities & MSM_DISPLAY_CAP_VID_MODE)) - sde_enc->idle_pc_enabled = sde_kms->catalog->has_idle_pc; + sde_enc->idle_pc_enabled = sde_kms->catalog->has_idle_pc; sde_enc->input_event_enabled = sde_kms->catalog->wakeup_with_touch; From f259cf68d1ead6fe416534454373ba12198617c4 Mon Sep 17 00:00:00 2001 From: Rajeev Nandan Date: Thu, 7 Oct 2021 23:11:32 +0530 Subject: [PATCH 16/46] disp: msm: dsi: Support uncompressed rgb101010 format Add support for uncompressed rgb101010 format. Change-Id: I60c2f7817eb2ea3e462c4692b1beb7f523836326 Signed-off-by: Rajeev Nandan Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_ctrl.c | 3 +++ msm/dsi/dsi_ctrl_hw_cmn.c | 13 ++++++++----- msm/dsi/dsi_defs.h | 4 ++++ msm/dsi/dsi_panel.c | 3 +++ msm/dsi/dsi_phy_timing_calc.c | 2 +- 5 files changed, 19 insertions(+), 6 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 659d2dacda..74ba24793f 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1008,6 +1008,9 @@ int dsi_ctrl_pixel_format_to_bpp(enum dsi_pixel_format dst_format) case DSI_PIXEL_FORMAT_RGB888: bpp = 24; break; + case DSI_PIXEL_FORMAT_RGB101010: + bpp = 30; + break; default: bpp = 24; break; diff --git a/msm/dsi/dsi_ctrl_hw_cmn.c b/msm/dsi/dsi_ctrl_hw_cmn.c index efc5bc0c9b..cfcb91821a 100644 --- a/msm/dsi/dsi_ctrl_hw_cmn.c +++ b/msm/dsi/dsi_ctrl_hw_cmn.c @@ -41,9 +41,9 @@ static bool dsi_compression_enabled(struct dsi_mode_info *mode) /* Unsupported formats default to RGB888 */ static const u8 cmd_mode_format_map[DSI_PIXEL_FORMAT_MAX] = { - 0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4 }; + 0x6, 0x7, 0x8, 0x8, 0x0, 0x3, 0x4, 0x9 }; static const u8 video_mode_format_map[DSI_PIXEL_FORMAT_MAX] = { - 0x0, 0x1, 0x2, 0x3, 0x3, 0x3, 0x3 }; + 0x0, 0x1, 0x2, 0x3, 0x3, 0x3, 0x3, 0x4 }; /** * dsi_split_link_setup() - setup dsi split link configurations @@ -543,10 +543,13 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, u32 reg = 0, offset = 0; int pic_width = 0, this_frame_slices = 0, intf_ip_w = 0; u32 pkt_per_line = 0, eol_byte_num = 0, bytes_in_slice = 0; + u32 bpp; if (roi && (!roi->w || !roi->h)) return; + bpp = dsi_pixel_format_to_bpp(cfg->dst_format); + if (dsi_dsc_compression_enabled(mode)) { struct msm_display_dsc_info dsc; @@ -580,11 +583,11 @@ void dsi_ctrl_hw_cmn_setup_cmd_stream(struct dsi_ctrl_hw *ctrl, bytes_in_slice = vdc.bytes_in_slice; } else if (roi) { width_final = roi->w; - stride_final = roi->w * 3; + stride_final = DIV_ROUND_UP(roi->w * bpp, 8); height_final = roi->h; } else { width_final = mode->h_active; - stride_final = mode->h_active * 3; + stride_final = DIV_ROUND_UP(mode->h_active * bpp, 8); height_final = mode->v_active; } @@ -701,7 +704,7 @@ void dsi_ctrl_hw_cmn_video_engine_setup(struct dsi_ctrl_hw *ctrl, reg |= (cfg->bllp_lp11_en ? BIT(12) : 0); reg |= (cfg->traffic_mode & 0x3) << 8; reg |= (cfg->vc_id & 0x3); - reg |= (video_mode_format_map[common_cfg->dst_format] & 0x3) << 4; + reg |= (video_mode_format_map[common_cfg->dst_format] & 0x7) << 4; DSI_W32(ctrl, DSI_VIDEO_MODE_CTRL, reg); reg = (common_cfg->swap_mode & 0x7) << 12; diff --git a/msm/dsi/dsi_defs.h b/msm/dsi/dsi_defs.h index 4ab7abee9a..a61bd397ef 100644 --- a/msm/dsi/dsi_defs.h +++ b/msm/dsi/dsi_defs.h @@ -39,6 +39,7 @@ * @DSI_PIXEL_FORMAT_RGB111: * @DSI_PIXEL_FORMAT_RGB332: * @DSI_PIXEL_FORMAT_RGB444: + * @DSI_PIXEL_FORMAT_RGB101010: * @DSI_PIXEL_FORMAT_MAX: */ enum dsi_pixel_format { @@ -49,6 +50,7 @@ enum dsi_pixel_format { DSI_PIXEL_FORMAT_RGB111, DSI_PIXEL_FORMAT_RGB332, DSI_PIXEL_FORMAT_RGB444, + DSI_PIXEL_FORMAT_RGB101010, DSI_PIXEL_FORMAT_MAX }; @@ -767,6 +769,8 @@ static inline int dsi_pixel_format_to_bpp(enum dsi_pixel_format fmt) return 8; case DSI_PIXEL_FORMAT_RGB444: return 12; + case DSI_PIXEL_FORMAT_RGB101010: + return 30; } return 24; } diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index 81f21d200f..c4a0ae0d8f 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -954,6 +954,9 @@ static int dsi_panel_parse_pixel_format(struct dsi_host_common_cfg *host, case 18: fmt = DSI_PIXEL_FORMAT_RGB666; break; + case 30: + fmt = DSI_PIXEL_FORMAT_RGB101010; + break; case 24: default: fmt = DSI_PIXEL_FORMAT_RGB888; diff --git a/msm/dsi/dsi_phy_timing_calc.c b/msm/dsi/dsi_phy_timing_calc.c index 2d407930d6..723022e7c6 100644 --- a/msm/dsi/dsi_phy_timing_calc.c +++ b/msm/dsi/dsi_phy_timing_calc.c @@ -6,7 +6,7 @@ #include "dsi_phy_timing_calc.h" static const u32 bits_per_pixel[DSI_PIXEL_FORMAT_MAX] = { - 16, 18, 18, 24, 3, 8, 12 }; + 16, 18, 18, 24, 3, 8, 12, 30 }; static int dsi_phy_cmn_validate_and_set(struct timing_entry *t, char const *t_name) From 374c86e91bed5501cd3952e2ba8b1af0776290bf Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Wed, 8 Dec 2021 11:18:32 +0530 Subject: [PATCH 17/46] disp: msm: sde: update TEAR_SYNC_WRCOUNT register before vsync counter During DMS, when tear check registers are updated near rd_ptr line count, it was resulting in a spurious rd_ptr_irq to which frame is getting latched and causing tearing on the screen. This change updates TEAR_SYNC_WRCOUNT register before disabling the vsync counter and adds a spinlock to avoid pre-emption. Change-Id: I986dc3ce6fb3da5fed758c2f50562df44f2ab557 Signed-off-by: Yashwanth --- msm/sde/sde_hw_intf.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/msm/sde/sde_hw_intf.c b/msm/sde/sde_hw_intf.c index e805cf29fc..bd7c40f90a 100644 --- a/msm/sde/sde_hw_intf.c +++ b/msm/sde/sde_hw_intf.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ #include @@ -616,10 +617,12 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf, { struct sde_hw_blk_reg_map *c; u32 cfg = 0; + spinlock_t tearcheck_spinlock; if (!intf) return -EINVAL; + spin_lock_init(&tearcheck_spinlock); c = &intf->hw; if (te->hw_vsync_mode) @@ -627,6 +630,14 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf, cfg |= te->vsync_count; + /* + * Local spinlock is acquired here to avoid pre-emption + * as below register programming should be completed in + * less than 2^16 vsync clk cycles. + */ + spin_lock(&tearcheck_spinlock); + SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, + (te->start_pos + te->sync_threshold_start + 1)); SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg); wmb(); /* disable vsync counter before updating single buffer registers */ SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height); @@ -637,10 +648,9 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf, SDE_REG_WRITE(c, INTF_TEAR_SYNC_THRESH, ((te->sync_threshold_continue << 16) | te->sync_threshold_start)); - SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, - (te->start_pos + te->sync_threshold_start + 1)); cfg |= BIT(19); /* VSYNC_COUNTER_EN */ SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg); + spin_unlock(&tearcheck_spinlock); return 0; } From eea04d1a31d90329c868c0b29709472e560340ab Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Tue, 14 Dec 2021 16:22:16 +0530 Subject: [PATCH 18/46] disp: msm: sde: avoid use after free in msm_lastclose This change sets kms in msm_drm_private to NULL during msm_drm_unbind as this can be accessed from msm_lastclose during msm_pdev_shutdown concurrently. Change-Id: Ic44f5cf88a96c970903f2c7d3c5b627e22b411fc Signed-off-by: Jayaprakash Madisetty --- msm/msm_drv.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/msm/msm_drv.c b/msm/msm_drv.c index e98e3a8b26..7d2b61df15 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -430,8 +431,10 @@ static int msm_drm_uninit(struct device *dev) drm_atomic_helper_shutdown(ddev); drm_irq_uninstall(ddev); - if (kms && kms->funcs) + if (kms && kms->funcs) { kms->funcs->destroy(kms); + priv->kms = NULL; + } if (priv->vram.paddr) { unsigned long attrs = DMA_ATTR_NO_KERNEL_MAPPING; @@ -1006,12 +1009,14 @@ static void msm_postclose(struct drm_device *dev, struct drm_file *file) static void msm_lastclose(struct drm_device *dev) { struct msm_drm_private *priv = dev->dev_private; - struct msm_kms *kms = priv->kms; + struct msm_kms *kms; int i, rc; - if (!kms) + if (!priv || !priv->kms) return; + kms = priv->kms; + /* check for splash status before triggering cleanup * if we end up here with splash status ON i.e before first * commit then ignore the last close call From 039d83144f4684889cfd3a6b1ff0a3b444512bc7 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Tue, 21 Dec 2021 15:48:15 +0530 Subject: [PATCH 19/46] disp: msm: sde: add cached lut flag in sde plane Below is the sequence during which issue is observed while using stale lut values: 1) Scaler block is enabled in the VIG pipe along with the valid lut configuration. 2) Idle work gets scheduled and GDSC is turned off erasing the saved lut values. 3) At the same time, userspace sends a commit assuming lut values are still valid resulting in artifacts on the screen. In the plane state scaler config, only lut flag will be reset for subsequent commits and remaining properties such as filter cfgs, lut_idx etc. remains same. This change caches the lut flag in sde plane whenever the lut is being set and reuses this flag to handle above issue. Change-Id: I7d83d5e7a22a73a2d94b100dffe60316f92ec309 Signed-off-by: Yashwanth --- msm/sde/sde_plane.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index eb90373ab7..f198ecbf7b 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -116,6 +117,7 @@ struct sde_plane { struct sde_csc_cfg *csc_usr_ptr; struct sde_csc_cfg *csc_ptr; + uint32_t cached_lut_flag; struct sde_hw_scaler3_cfg scaler3_cfg; struct sde_hw_pixel_ext pixel_ext; @@ -3235,6 +3237,20 @@ static void _sde_plane_update_properties(struct drm_plane *plane, pstate->dirty = 0x0; } +static void _sde_plane_check_lut_dirty(struct sde_plane *psde, + struct sde_plane_state *pstate) +{ + /** + * Valid configuration if scaler is not enabled or + * lut flag is set + */ + if (pstate->scaler3_cfg.lut_flag || !pstate->scaler3_cfg.enable) + return; + + pstate->scaler3_cfg.lut_flag = psde->cached_lut_flag; + SDE_EVT32(DRMID(&psde->base), pstate->scaler3_cfg.lut_flag, SDE_EVTLOG_ERROR); +} + static int sde_plane_sspp_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state) { @@ -3286,10 +3302,15 @@ static int sde_plane_sspp_atomic_update(struct drm_plane *plane, state->crtc_w, state->crtc_h, state->crtc_x, state->crtc_y); + /* Caching the valid lut flag in sde plane */ + if (pstate->scaler3_cfg.enable && pstate->scaler3_cfg.lut_flag) + psde->cached_lut_flag = pstate->scaler3_cfg.lut_flag; + /* force reprogramming of all the parameters, if the flag is set */ if (psde->revalidate) { SDE_DEBUG("plane:%d - reconfigure all the parameters\n", plane->base.id); + _sde_plane_check_lut_dirty(psde, pstate); pstate->dirty = SDE_PLANE_DIRTY_ALL | SDE_PLANE_DIRTY_CP; psde->revalidate = false; } From 9951d3c78445822b1433a13b63a54941a0e3950e Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Tue, 28 Dec 2021 09:17:02 +0530 Subject: [PATCH 20/46] disp: msm: sde: avoid setting of max vblank count This change avoids setting of max vblank count in crtc enable if accurate vsync timestamp feature is disabled. Change-Id: I6d8299359f581a162a7412da8c9b673e3aeae041 Signed-off-by: Mahadevan --- msm/sde/sde_crtc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 3b73775238..e5097a1c73 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -4595,11 +4595,18 @@ static void sde_crtc_enable(struct drm_crtc *crtc, int ret, i; struct sde_crtc_state *cstate; struct msm_display_mode *msm_mode; + struct sde_kms *kms; if (!crtc || !crtc->dev || !crtc->dev->dev_private) { SDE_ERROR("invalid crtc\n"); return; } + kms = _sde_crtc_get_kms(crtc); + if (!kms || !kms->catalog) { + SDE_ERROR("invalid kms handle\n"); + return; + } + priv = crtc->dev->dev_private; cstate = to_sde_crtc_state(crtc->state); @@ -4620,7 +4627,8 @@ static void sde_crtc_enable(struct drm_crtc *crtc, /* cache the encoder mask now for vblank work */ sde_crtc->cached_encoder_mask = crtc->state->encoder_mask; /* max possible vsync_cnt(atomic_t) soft counter */ - drm_crtc_set_max_vblank_count(crtc, INT_MAX); + if (kms->catalog->has_precise_vsync_ts) + drm_crtc_set_max_vblank_count(crtc, INT_MAX); drm_crtc_vblank_on(crtc); } From ede3f587f76439e438333f11c4b817dde62d6413 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Fri, 17 Dec 2021 15:01:41 +0530 Subject: [PATCH 21/46] disp: msm: sde: correct pp block allocation during dcwb dither programming In mid and low tier targets there is reduction in pingpong blocks and static allocation of pingpong blocks with respect to dedicated cwb ids causes mismatch failures and leads to wb kickoff timeouts. This change corrects the pingpong block id allocation for dedicated cwb in dither control register programming path. Change-Id: I98c06a2c3b49c7ea0556dcf1a921969c300fed16 Signed-off-by: Mahadevan --- msm/sde/sde_hw_wb.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/msm/sde/sde_hw_wb.c b/msm/sde/sde_hw_wb.c index 03f878c7e1..ea328596d5 100644 --- a/msm/sde/sde_hw_wb.c +++ b/msm/sde/sde_hw_wb.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -421,12 +422,7 @@ static void sde_hw_wb_program_cwb_dither_ctrl(struct sde_hw_wb *ctx, return; } - /* map to pp_id from dcwb id */ - if (dcwb_idx == DCWB_0) { - pp_id = PINGPONG_CWB_0; - } else if (dcwb_idx == DCWB_1) { - pp_id = PINGPONG_CWB_1; - } else { + if (dcwb_idx >= DCWB_MAX) { DRM_ERROR("Invalid dcwb_idx %d\n", dcwb_idx); return; } @@ -434,7 +430,8 @@ static void sde_hw_wb_program_cwb_dither_ctrl(struct sde_hw_wb *ctx, /* find pp blk with pp_id */ for (idx = 0; idx < DCWB_MAX - DCWB_0; ++idx) { pp = &ctx->dcwb_pp_hw[idx]; - if (pp && pp->idx == pp_id) { + if (pp && dcwb_idx == idx + 1) { + pp_id = pp->idx; found = true; break; } From c5c2af4297e3e98a3742d3c288f3b1ef481d9f85 Mon Sep 17 00:00:00 2001 From: Satya Rama Aditya Pinapala Date: Mon, 22 Nov 2021 16:20:23 -0800 Subject: [PATCH 22/46] disp: msm: dsi: add check for any queued DSI CMDs before clock force update During a force update of DSI clocks, the state of the byte and pclks are toggled irrespective of the ref-count. This in addition with ASYNC command wait can result in interrupt storm, if and when the clocks are being toggled a previous command that was triggered using the ASYNC wait flag fires an ISR. The interrupt status doesn't get cleared if the ISR is being serviced with the clocks are off. The change adds a check for pending queued commands before any force update of DSI clocks. Change-Id: I4ca60d0ad43767791255f00c9af8e99e74786097 Signed-off-by: Satya Rama Aditya Pinapala Signed-off-by: Rajeev Nandan --- msm/dsi/dsi_display.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 810ed48a7f..e48b9406a8 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -5381,7 +5381,22 @@ int dsi_display_splash_res_cleanup(struct dsi_display *display) static int dsi_display_force_update_dsi_clk(struct dsi_display *display) { - int rc = 0; + int rc = 0, i = 0; + struct dsi_display_ctrl *ctrl; + + /* + * The force update dsi clock, is the only clock update function that toggles the state of + * DSI clocks without any ref count protection. With the addition of ASYNC command wait, + * there is a need for adding a check for any queued waits before updating these clocks. + */ + display_for_each_ctrl(i, display) { + ctrl = &display->ctrl[i]; + if (!ctrl->ctrl || !(ctrl->ctrl->post_tx_queued)) + continue; + flush_workqueue(display->post_cmd_tx_workq); + cancel_work_sync(&ctrl->ctrl->post_cmd_tx_work); + ctrl->ctrl->post_tx_queued = false; + } rc = dsi_display_link_clk_force_update_ctrl(display->dsi_clk_handle); From 0f940276c65d4dfd0fb6a00ae3c27f6a61a4f46f Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Fri, 17 Dec 2021 20:06:14 +0530 Subject: [PATCH 23/46] disp: msm: sde: add tx wait during DMS for sim panel This change adds pp_tx during DMS switch for sim panel to prevent WD timer getting updated in middle of the frame and creating early vsync which might result in ppdone timeout. For non-sim panels, this tx wait is not required and is done similar to posted start. Change-Id: Ifec68535efa19df27e651ce0a39c03627dff2089 Signed-off-by: Yashwanth --- msm/sde/sde_encoder.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 7ddd040093..231378d9d3 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -2428,17 +2428,37 @@ static void _sde_encoder_virt_populate_hw_res(struct drm_encoder *drm_enc) } static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc, - struct msm_display_mode *msm_mode, bool pre_modeset) + struct drm_display_mode *adj_mode, struct msm_display_mode *msm_mode, bool pre_modeset) { struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); enum sde_intf_mode intf_mode; + struct drm_display_mode *old_adj_mode = NULL; int ret; - bool is_cmd_mode = false; + bool is_cmd_mode = false, res_switch = false; if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)) is_cmd_mode = true; if (pre_modeset) { + if (sde_enc->cur_master) + old_adj_mode = &sde_enc->cur_master->cached_mode; + if (old_adj_mode && is_cmd_mode) + res_switch = !drm_mode_match(old_adj_mode, adj_mode, + DRM_MODE_MATCH_TIMINGS); + + if (res_switch && sde_enc->disp_info.is_te_using_watchdog_timer) { + /* + * add tx wait for sim panel to avoid wd timer getting + * updated in middle of frame to avoid early vsync + */ + ret = sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); + if (ret && ret != -EWOULDBLOCK) { + SDE_ERROR_ENC(sde_enc, "wait for idle failed %d\n", ret); + SDE_EVT32(DRMID(drm_enc), ret, SDE_EVTLOG_ERROR); + return ret; + } + } + intf_mode = sde_encoder_get_intf_mode(drm_enc); if (msm_is_mode_seamless_dms(msm_mode) || (msm_is_mode_seamless_dyn_clk(msm_mode) && @@ -2545,7 +2565,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, /* release resources before seamless mode change */ msm_mode = &c_state->msm_mode; - ret = sde_encoder_virt_modeset_rc(drm_enc, msm_mode, true); + ret = sde_encoder_virt_modeset_rc(drm_enc, adj_mode, msm_mode, true); if (ret) return; @@ -2585,7 +2605,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc, } /* update resources after seamless mode change */ - sde_encoder_virt_modeset_rc(drm_enc, msm_mode, false); + sde_encoder_virt_modeset_rc(drm_enc, adj_mode, msm_mode, false); } void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable) From e2302903106b2e11f753bb6f308d7ff94202951d Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Mon, 27 Dec 2021 17:27:36 +0530 Subject: [PATCH 24/46] disp: msm: sde: Add support to limit DSC size to 10k With full DSC size of 20k, RT performance issues are seen due to the stress created during larger prefill needed to fill up the 20k DSC buffer. Limiting DSC size to 10k helps to mitigate these RT performace issues. This change adds support for this based on new flag has_reduced_ob_max in sde_mdss_cfg data structure. Flag has_reduced_ob_max has be set true only on targets where its recommended. Change-Id: I649d213bcd378025bd0548fb982b55c98c99224f Signed-off-by: Ritesh Kumar --- msm/sde/sde_hw_catalog.c | 7 +++++-- msm/sde/sde_hw_catalog.h | 7 ++++++- msm/sde/sde_hw_dsc_1_2.c | 13 ++++++++----- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index db9d2f4cab..6a67346b71 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2022, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -3271,7 +3272,8 @@ static int sde_dsc_parse_dt(struct device_node *np, if (PROP_VALUE_ACCESS(prop_value, DSC_422, i)) set_bit(SDE_DSC_NATIVE_422_EN, &dsc->features); - + if (sde_cfg->has_reduced_ob_max) + set_bit(SDE_DSC_REDUCED_OB_MAX, &dsc->features); } else { set_bit(SDE_DSC_HW_REV_1_1, &dsc->features); } @@ -5148,6 +5150,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_cwb_crop = true; sde_cfg->has_qsync = true; sde_cfg->perf.min_prefill_lines = 40; + sde_cfg->has_reduced_ob_max = true; sde_cfg->vbif_qos_nlvl = 8; sde_cfg->ts_prefill_rev = 2; sde_cfg->ctl_rev = SDE_CTL_CFG_VERSION_1_0_0; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 2932c703dd..f0260f5f7c 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2015-2022, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_CATALOG_H @@ -459,6 +460,7 @@ enum { * @SDE_DSC_HW_REV_1_1 dsc block supports dsc 1.1 only * @SDE_DSC_HW_REV_1_2 dsc block supports dsc 1.1 and 1.2 * @SDE_DSC_NATIVE_422_EN, Supports native422 and native420 encoding + * @SDE_DSC_REDUCED_OB_MAX, DSC size is limited to 10k * @SDE_DSC_ENC, DSC encoder sub block * @SDE_DSC_CTL, DSC ctl sub block * @SDE_DSC_MAX @@ -468,6 +470,7 @@ enum { SDE_DSC_HW_REV_1_1, SDE_DSC_HW_REV_1_2, SDE_DSC_NATIVE_422_EN, + SDE_DSC_REDUCED_OB_MAX, SDE_DSC_ENC, SDE_DSC_CTL, SDE_DSC_MAX @@ -1522,6 +1525,7 @@ struct sde_perf_cfg { * @skip_inline_rot_thresh Skip inline rotation threshold * @has_idle_pc indicate if idle power collapse feature is supported * @allowed_dsc_reservation_switch intf to which dsc reservation switch is supported + * @has_reduced_ob_max indicate if DSC size is limited to 10k * @wakeup_with_touch indicate early wake up display with input touch event * @has_hdr HDR feature support * @has_hdr_plus HDR10+ feature support @@ -1615,6 +1619,7 @@ struct sde_mdss_cfg { bool skip_inline_rot_threshold; bool has_idle_pc; u32 allowed_dsc_reservation_switch; + bool has_reduced_ob_max; bool wakeup_with_touch; u32 vbif_qos_nlvl; u32 ts_prefill_rev; diff --git a/msm/sde/sde_hw_dsc_1_2.c b/msm/sde/sde_hw_dsc_1_2.c index dee1efa3f1..8d5c7efcb3 100644 --- a/msm/sde/sde_hw_dsc_1_2.c +++ b/msm/sde/sde_hw_dsc_1_2.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2020-2022, The Linux Foundation. All rights reserved. */ #include "sde_hw_mdss.h" @@ -60,19 +61,21 @@ static int _dsc_calc_ob_max_addr(struct sde_hw_dsc *hw_dsc, int num_ss) { enum sde_dsc idx; + bool reduced_ob_max; idx = hw_dsc->idx; + reduced_ob_max = hw_dsc->caps->features & BIT(SDE_DSC_REDUCED_OB_MAX); if (!(hw_dsc->caps->features & BIT(SDE_DSC_NATIVE_422_EN))) { if (num_ss == 1) - return 2399; + return reduced_ob_max ? 1199 : 2399; else if (num_ss == 2) - return 1199; + return reduced_ob_max ? 599 : 1199; } else { if (num_ss == 1) - return 1199; + return reduced_ob_max ? 599 : 1199; else if (num_ss == 2) - return 599; + return reduced_ob_max ? 299 : 599; } return 0; } From e51018b92cb1a893bc034a8be00d0601a54b177e Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Thu, 4 Nov 2021 15:55:23 -0400 Subject: [PATCH 25/46] disp: msm: use vzalloc for large allocations Large allocations using kzalloc can lead to timeouts. This updates the allocation calls accordingly to use vzalloc to remove requirements on contiguous memory. Change-Id: I86fa0ae13277d97477210a082703514df792d8a9 Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_color_processing.c | 9 +++++---- msm/sde/sde_connector.c | 5 +++-- msm/sde/sde_crtc.c | 6 +++--- msm/sde/sde_plane.c | 6 +++--- msm/sde_dbg.c | 26 +++++++++++++------------- msm/sde_dbg_evtlog.c | 9 +++++---- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/msm/sde/sde_color_processing.c b/msm/sde/sde_color_processing.c index 9bf8ad582b..94918015a2 100644 --- a/msm/sde/sde_color_processing.c +++ b/msm/sde/sde_color_processing.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -4865,7 +4866,7 @@ void sde_cp_crtc_enable(struct drm_crtc *drm_crtc) if (!num_mixers) return; mutex_lock(&crtc->crtc_cp_lock); - info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL); + info = vzalloc(sizeof(struct sde_kms_info)); if (info) { for (i = 0; i < ARRAY_SIZE(dspp_cap_update_func); i++) dspp_cap_update_func[i](crtc, info); @@ -4874,7 +4875,7 @@ void sde_cp_crtc_enable(struct drm_crtc *drm_crtc) info->data, SDE_KMS_INFO_DATALEN(info), CRTC_PROP_DSPP_INFO); } - kfree(info); + vfree(info); mutex_unlock(&crtc->crtc_cp_lock); } @@ -4889,7 +4890,7 @@ void sde_cp_crtc_disable(struct drm_crtc *drm_crtc) } crtc = to_sde_crtc(drm_crtc); mutex_lock(&crtc->crtc_cp_lock); - info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL); + info = vzalloc(sizeof(struct sde_kms_info)); if (info) msm_property_set_blob(&crtc->property_info, &crtc->dspp_blob_info, @@ -4900,7 +4901,7 @@ void sde_cp_crtc_disable(struct drm_crtc *drm_crtc) crtc->skip_blend_plane_h = 0; crtc->skip_blend_plane_w = 0; mutex_unlock(&crtc->crtc_cp_lock); - kfree(info); + vfree(info); } void sde_cp_clear_state_info(struct drm_crtc_state *state) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index 89ce80fedd..b11183a139 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -2912,7 +2913,7 @@ int sde_connector_set_blob_data(struct drm_connector *conn, return -EINVAL; } - info = kzalloc(sizeof(*info), GFP_KERNEL); + info = vzalloc(sizeof(*info)); if (!info) return -ENOMEM; @@ -2970,7 +2971,7 @@ int sde_connector_set_blob_data(struct drm_connector *conn, SDE_KMS_INFO_DATALEN(info), prop_id); exit: - kfree(info); + vfree(info); return rc; } diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index e5097a1c73..4ec7eccc00 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -5823,7 +5823,7 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, return; } - info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL); + info = vzalloc(sizeof(struct sde_kms_info)); if (!info) { SDE_ERROR("failed to allocate info memory\n"); return; @@ -5927,7 +5927,7 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc, msm_property_install_range(&sde_crtc->property_info, "frame_data", 0x0, 0, ~0, 0, CRTC_PROP_FRAME_DATA_BUF); - kfree(info); + vfree(info); } static int _sde_crtc_get_output_fence(struct drm_crtc *crtc, diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index f198ecbf7b..16dabee984 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (C) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -3818,7 +3818,7 @@ static void _sde_plane_install_properties(struct drm_plane *plane, psde->catalog = catalog; is_master = !psde->is_virtual; - info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL); + info = vzalloc(sizeof(struct sde_kms_info)); if (!info) { SDE_ERROR("failed to allocate info memory\n"); return; @@ -3900,7 +3900,7 @@ static void _sde_plane_install_properties(struct drm_plane *plane, if (psde->pipe_hw->ops.set_ubwc_stats_roi) msm_property_install_range(&psde->property_info, "ubwc_stats_roi", 0, 0, 0xFFFFFFFF, 0, PLANE_PROP_UBWC_STATS_ROI); - kfree(info); + vfree(info); } static inline void _sde_plane_set_csc_v1(struct sde_plane *psde, diff --git a/msm/sde_dbg.c b/msm/sde_dbg.c index 76f36915b5..96bd7e918b 100755 --- a/msm/sde_dbg.c +++ b/msm/sde_dbg.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2009-2021, The Linux Foundation. All rights reserved. */ @@ -1060,7 +1060,7 @@ static void _sde_dbg_dump_sde_dbg_bus(struct sde_dbg_sde_debug_bus *bus, u32 ena SDE_DBG_LOG_MARKER(name, SDE_DBG_LOG_START, in_log); if (in_mem && (!(*dump_mem))) { - *dump_mem = kvzalloc(list_size, GFP_KERNEL); + *dump_mem = vzalloc(list_size); bus->cmn.content_size = list_size / sizeof(u32); } dump_addr = *dump_mem; @@ -1104,7 +1104,7 @@ static void _sde_dbg_dump_dsi_dbg_bus(struct sde_dbg_sde_debug_bus *bus, u32 ena mutex_lock(&sde_dbg_dsi_mutex); if (in_mem && (!(*dump_mem))) { - *dump_mem = kvzalloc(list_size, GFP_KERNEL); + *dump_mem = vzalloc(list_size); bus->cmn.content_size = list_size / sizeof(u32); } dump_addr = *dump_mem; @@ -1139,7 +1139,7 @@ static void _sde_dump_array(bool do_panic, const char *name, bool dump_secure, u reg_dump_size = _sde_dbg_get_reg_dump_size(); if (!dbg_base->reg_dump_base) - dbg_base->reg_dump_base = kvzalloc(reg_dump_size, GFP_KERNEL); + dbg_base->reg_dump_base = vzalloc(reg_dump_size); dbg_base->reg_dump_addr = dbg_base->reg_dump_base; @@ -1624,7 +1624,7 @@ static ssize_t sde_recovery_regdump_read(struct file *file, char __user *ubuf, if (!rbuf->dump_done && !rbuf->cur_blk) { if (!rbuf->buf) - rbuf->buf = kvzalloc(DUMP_BUF_SIZE, GFP_KERNEL); + rbuf->buf = vzalloc(DUMP_BUF_SIZE); if (!rbuf->buf) { len = -ENOMEM; goto err; @@ -2431,7 +2431,7 @@ static void sde_dbg_reg_base_destroy(void) list_del(&blk_base->reg_base_head); kfree(blk_base); } - kvfree(dbg_base->reg_dump_base); + vfree(dbg_base->reg_dump_base); } static void sde_dbg_dsi_ctrl_destroy(void) @@ -2450,12 +2450,12 @@ static void sde_dbg_buses_destroy(void) { struct sde_dbg_base *dbg_base = &sde_dbg_base; - kvfree(dbg_base->dbgbus_sde.cmn.dumped_content); - kvfree(dbg_base->dbgbus_vbif_rt.cmn.dumped_content); - kvfree(dbg_base->dbgbus_dsi.cmn.dumped_content); - kvfree(dbg_base->dbgbus_lutdma.cmn.dumped_content); - kvfree(dbg_base->dbgbus_rsc.cmn.dumped_content); - kvfree(dbg_base->dbgbus_dp.cmn.dumped_content); + vfree(dbg_base->dbgbus_sde.cmn.dumped_content); + vfree(dbg_base->dbgbus_vbif_rt.cmn.dumped_content); + vfree(dbg_base->dbgbus_dsi.cmn.dumped_content); + vfree(dbg_base->dbgbus_lutdma.cmn.dumped_content); + vfree(dbg_base->dbgbus_rsc.cmn.dumped_content); + vfree(dbg_base->dbgbus_dp.cmn.dumped_content); } /** @@ -2463,7 +2463,7 @@ static void sde_dbg_buses_destroy(void) */ void sde_dbg_destroy(void) { - kvfree(sde_dbg_base.regbuf.buf); + vfree(sde_dbg_base.regbuf.buf); memset(&sde_dbg_base.regbuf, 0, sizeof(sde_dbg_base.regbuf)); _sde_dbg_debugfs_destroy(); sde_dbg_base_evtlog = NULL; diff --git a/msm/sde_dbg_evtlog.c b/msm/sde_dbg_evtlog.c index 1c945205a4..abd57cba80 100644 --- a/msm/sde_dbg_evtlog.c +++ b/msm/sde_dbg_evtlog.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -211,7 +212,7 @@ struct sde_dbg_evtlog *sde_evtlog_init(void) { struct sde_dbg_evtlog *evtlog; - evtlog = kvzalloc(sizeof(*evtlog), GFP_KERNEL); + evtlog = vzalloc(sizeof(*evtlog)); if (!evtlog) return ERR_PTR(-ENOMEM); @@ -229,7 +230,7 @@ struct sde_dbg_reglog *sde_reglog_init(void) { struct sde_dbg_reglog *reglog; - reglog = kvzalloc(sizeof(*reglog), GFP_KERNEL); + reglog = vzalloc(sizeof(*reglog)); if (!reglog) return ERR_PTR(-ENOMEM); @@ -337,7 +338,7 @@ void sde_evtlog_destroy(struct sde_dbg_evtlog *evtlog) list_del(&filter_node->list); kfree(filter_node); } - kvfree(evtlog); + vfree(evtlog); } void sde_reglog_destroy(struct sde_dbg_reglog *reglog) @@ -345,5 +346,5 @@ void sde_reglog_destroy(struct sde_dbg_reglog *reglog) if (!reglog) return; - kvfree(reglog); + vfree(reglog); } From cf0f2627c483266f3f3d1cfca9d212e584fcefed Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Mon, 3 Jan 2022 15:37:12 +0530 Subject: [PATCH 26/46] disp: msm: sde: always set CTL_x_UIDLE_ACTIVE register to "1" As per HW recommendation, FAL10_VETO_OVERRIDE register can be programmed to disable FAL10 in alternate to disabling uidle at the sspp level as disabling UIDLE controller will only disable DPU traffic shaping and will not stop the system from entering FAL10 state. This change programs FAL10_VETO_OVERRIDE register during uidle disable and also sets CTL_x_UIDLE_ACTIVE register to always one to avoid race condition between different CTL paths. Change-Id: I9c55f5da2037cb8c448cc978eac0a04608a93650 Signed-off-by: Yashwanth --- msm/sde/sde_crtc.c | 10 ++-------- msm/sde/sde_crtc.h | 3 +-- msm/sde/sde_hw_uidle.c | 7 ++++++- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 3b73775238..e3421b330a 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -3607,13 +3607,8 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, _sde_crtc_dest_scaler_setup(crtc); sde_cp_crtc_apply_noise(crtc, old_state); - if (crtc->state->mode_changed || sde_kms->perf.catalog->uidle_cfg.dirty) { + if (crtc->state->mode_changed || sde_kms->perf.catalog->uidle_cfg.dirty) sde_core_perf_crtc_update_uidle(crtc, true); - } else if (!test_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask) && - !sde_kms->perf.uidle_enabled) - sde_core_perf_uidle_setup_ctl(crtc, false); - - 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) @@ -4301,7 +4296,6 @@ void sde_crtc_reset_sw_state(struct drm_crtc *crtc) /* mark other properties which need to be dirty for next update */ set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, &sde_crtc->revalidate_mask); - set_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask); if (cstate->num_ds_enabled) set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty); } diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 4fb361d12b..004118d726 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021 The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -443,7 +443,6 @@ enum sde_crtc_dirty_flags { SDE_CRTC_DIRTY_DEST_SCALER, SDE_CRTC_DIRTY_DIM_LAYERS, SDE_CRTC_NOISE_LAYER, - SDE_CRTC_DIRTY_UIDLE, SDE_CRTC_DIRTY_MAX, }; diff --git a/msm/sde/sde_hw_uidle.c b/msm/sde/sde_hw_uidle.c index a3ae742f21..875662099f 100644 --- a/msm/sde/sde_hw_uidle.c +++ b/msm/sde/sde_hw_uidle.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -162,7 +163,7 @@ void sde_hw_uidle_setup_ctl(struct sde_hw_uidle *uidle, { struct sde_hw_blk_reg_map *c = &uidle->hw; bool enable = false; - u32 reg_val; + u32 reg_val, fal10_veto_regval = 0; reg_val = SDE_REG_READ(c, UIDLE_CTL); @@ -183,6 +184,10 @@ void sde_hw_uidle_setup_ctl(struct sde_hw_uidle *uidle, FAL10_EXIT_CNT_MSK); SDE_REG_WRITE(c, UIDLE_CTL, reg_val); + if (!enable) + fal10_veto_regval |= (BIT(31) | BIT(0)); + + SDE_REG_WRITE(c, UIDLE_FAL10_VETO_OVERRIDE, fal10_veto_regval); } static void sde_hw_uilde_active_override(struct sde_hw_uidle *uidle, From 31eaf2f9394acc69864d434cd051cc91b446311d Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Tue, 7 Dec 2021 15:25:23 -0500 Subject: [PATCH 27/46] disp: msm: sde: send power on event for cont. splash During the first commit, crtc state will be duplicated from the crtc state populated with splash data. In this case, crtc will already be set to active, but active_changed will remain cleared. This will skip the power on event being set during complete commit phase. This change checks for the cont. splash enabled before sending the power on event. Change-Id: I9964317d96468213e9abe9b029e64aa2981fb359 Signed-off-by: Nilaan Gunabalachandran --- 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 4ec7eccc00..3890609886 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2830,6 +2830,10 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc, struct drm_crtc_state *old_state) { struct sde_crtc *sde_crtc; + struct sde_splash_display *splash_display = NULL; + struct sde_kms *sde_kms; + bool cont_splash_enabled = false; + int i; u32 power_on = 1; if (!crtc || !crtc->state) { @@ -2840,7 +2844,16 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc, sde_crtc = to_sde_crtc(crtc); SDE_EVT32_VERBOSE(DRMID(crtc)); - if (crtc->state->active_changed && crtc->state->active) + sde_kms = _sde_crtc_get_kms(crtc); + + for (i = 0; i < MAX_DSI_DISPLAYS; i++) { + splash_display = &sde_kms->splash_data.splash_display[i]; + if (splash_display->cont_splash_enabled && + crtc == splash_display->encoder->crtc) + cont_splash_enabled = true; + } + + if ((crtc->state->active_changed || cont_splash_enabled) && crtc->state->active) sde_crtc_event_notify(crtc, DRM_EVENT_CRTC_POWER, sizeof(u32), power_on); sde_core_perf_crtc_update(crtc, 0, false); From 7bc6632eb6c8966a95395b41ce98b5463ee38559 Mon Sep 17 00:00:00 2001 From: Kalyan Thota Date: Tue, 14 Dec 2021 07:17:01 -0800 Subject: [PATCH 28/46] disp: msm: reset thread priority work on every new run Reinit thread priority work before queueing on multiple display threads as the work stores the former worker thread. Also flush work such the next init is serialized. Change-Id: I51409d4d12d100be0cb30238f812a56ec064a339 Signed-off-by: Kalyan Thota --- msm/msm_drv.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 7d2b61df15..37a35f4403 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -601,7 +601,6 @@ static int msm_drm_display_thread_create(struct msm_drm_private *priv, struct dr { int i, ret = 0; - kthread_init_work(&priv->thread_priority_work, msm_drm_display_thread_priority_worker); for (i = 0; i < priv->num_crtcs; i++) { /* initialize display thread */ priv->disp_thread[i].crtc_id = priv->crtcs[i]->base.id; @@ -611,7 +610,10 @@ static int msm_drm_display_thread_create(struct msm_drm_private *priv, struct dr kthread_run(kthread_worker_fn, &priv->disp_thread[i].worker, "crtc_commit:%d", priv->disp_thread[i].crtc_id); + kthread_init_work(&priv->thread_priority_work, + msm_drm_display_thread_priority_worker); kthread_queue_work(&priv->disp_thread[i].worker, &priv->thread_priority_work); + kthread_flush_work(&priv->thread_priority_work); if (IS_ERR(priv->disp_thread[i].thread)) { dev_err(dev, "failed to create crtc_commit kthread\n"); @@ -633,7 +635,10 @@ static int msm_drm_display_thread_create(struct msm_drm_private *priv, struct dr * frame_pending counters beyond 2. This can lead to commit * failure at crtc commit level. */ + kthread_init_work(&priv->thread_priority_work, + msm_drm_display_thread_priority_worker); kthread_queue_work(&priv->event_thread[i].worker, &priv->thread_priority_work); + kthread_flush_work(&priv->thread_priority_work); if (IS_ERR(priv->event_thread[i].thread)) { dev_err(dev, "failed to create crtc_event kthread\n"); @@ -668,7 +673,9 @@ static int msm_drm_display_thread_create(struct msm_drm_private *priv, struct dr kthread_init_worker(&priv->pp_event_worker); priv->pp_event_thread = kthread_run(kthread_worker_fn, &priv->pp_event_worker, "pp_event"); + kthread_init_work(&priv->thread_priority_work, msm_drm_display_thread_priority_worker); kthread_queue_work(&priv->pp_event_worker, &priv->thread_priority_work); + kthread_flush_work(&priv->thread_priority_work); if (IS_ERR(priv->pp_event_thread)) { dev_err(dev, "failed to create pp_event kthread\n"); From 4f88bcf2327fda6def77fdcdc7d1eba86e5b6fc1 Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Tue, 4 Jan 2022 20:19:49 +0530 Subject: [PATCH 29/46] disp: msm: sde: avoid alignment checks for linear formats This change avoids alignment condition check if the format is linear because HW can fetch without any restrictions only in linear usecase. Change-Id: Ib823a8d309f7ed579d701a4bf56772ce318fb1f5 Signed-off-by: Jayaprakash Madisetty --- msm/sde/sde_encoder_phys_wb.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index f1a8775267..b4d7e98371 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -497,7 +497,9 @@ static void sde_encoder_phys_wb_setup_fb(struct sde_encoder_phys *phys_enc, wb_cfg->dest.plane_addr[2], wb_cfg->dest.plane_size[2], wb_cfg->dest.plane_addr[3], - wb_cfg->dest.plane_size[3]); + wb_cfg->dest.plane_size[3], + wb_cfg->roi.x, wb_cfg->roi.y, + wb_cfg->roi.w, wb_cfg->roi.h); hw_wb->ops.setup_outaddress(hw_wb, wb_cfg); } } @@ -770,9 +772,10 @@ static int _sde_enc_phys_wb_validate_cwb(struct sde_encoder_phys *phys_enc, } if (((wb_roi.w < out_width) || (wb_roi.h < out_height)) && - (wb_roi.w * wb_roi.h * fmt->bpp) % 256) { - SDE_ERROR("invalid stride w = %d h = %d bpp =%d out_width = %d, out_height = %d\n", - wb_roi.w, wb_roi.h, fmt->bpp, out_width, out_height); + ((wb_roi.w * wb_roi.h * fmt->bpp) % 256) && !SDE_FORMAT_IS_LINEAR(fmt)) { + SDE_ERROR("invalid stride w=%d h=%d bpp=%d out_width=%d, out_height=%d lin=%d\n", + wb_roi.w, wb_roi.h, fmt->bpp, out_width, out_height, + SDE_FORMAT_IS_LINEAR(fmt)); return -EINVAL; } From fd2dc5be06e7f8066dd89449c1a301f93a0ce989 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Thu, 23 Dec 2021 16:25:13 +0530 Subject: [PATCH 30/46] disp: msm: dsi: enable DMA start window scheduling for broadcast commands As per the HW requirements it is highly recommended to use DMA start window to trigger broadcast commands. If not used then it can result in a hardware hang with the DSI controllers going out of sync. This behavior is even more prominent in cases of higher refresh rates. Currently, reset_trigger_controls is called as part of next command. Due to this, when unicast command is sent after broadcast command, reset_trigger_controls does not get called for slave controller, leading to issues. As part of this change, DMA start window scheduling is enabled as default for broadcast commands and reset_trigger_controls is done as part of post_cmd_transfer operations. Change-Id: I2402214ed79b376d102b88d4f7e6a06fcb5712d3 Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_ctrl.c | 10 ++++++---- msm/dsi/dsi_display.c | 7 ++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 74ba24793f..f2d6d2ea06 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -422,6 +423,7 @@ static void dsi_ctrl_clear_dma_status(struct dsi_ctrl *dsi_ctrl) static void dsi_ctrl_post_cmd_transfer(struct dsi_ctrl *dsi_ctrl) { int rc = 0; + struct dsi_ctrl_hw_ops dsi_hw_ops = dsi_ctrl->hw.ops; struct dsi_clk_ctrl_info clk_info; u32 mask = BIT(DSI_FIFO_OVERFLOW); @@ -438,6 +440,10 @@ static void dsi_ctrl_post_cmd_transfer(struct dsi_ctrl *dsi_ctrl) dsi_ctrl_dma_cmd_wait_for_done(dsi_ctrl); } + if (dsi_ctrl->hw.reset_trig_ctrl) + dsi_hw_ops.reset_trig_ctrl(&dsi_ctrl->hw, + &dsi_ctrl->host_config.common_config); + /* Command engine disable, unmask overflow, remove vote on clocks and gdsc */ rc = dsi_ctrl_set_cmd_engine_state(dsi_ctrl, DSI_CTRL_ENGINE_OFF, false); if (rc) @@ -1377,10 +1383,6 @@ static void dsi_kickoff_msg_tx(struct dsi_ctrl *dsi_ctrl, SDE_EVT32(dsi_ctrl->cell_index, SDE_EVTLOG_FUNC_ENTRY, flags, msg->flags); - if (dsi_ctrl->hw.reset_trig_ctrl) - dsi_hw_ops.reset_trig_ctrl(&dsi_ctrl->hw, - &dsi_ctrl->host_config.common_config); - if (dsi_hw_ops.splitlink_cmd_setup && split_link->enabled) dsi_hw_ops.splitlink_cmd_setup(&dsi_ctrl->hw, &dsi_ctrl->host_config.common_config, flags); diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index e48b9406a8..3ff64b8e2c 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -704,14 +705,18 @@ static void dsi_display_set_cmd_tx_ctrl_flags(struct dsi_display *display, /* * Set flags for command scheduling. * 1) In video mode command DMA scheduling is default. - * 2) In command mode command DMA scheduling depends on message + * 2) In command mode unicast command DMA scheduling depends on message * flag and TE needs to be running. + * 3) In command mode broadcast command DMA scheduling is default and + * TE needs to be running. */ if (display->panel->panel_mode == DSI_OP_VIDEO_MODE) { flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; } else { if (msg->flags & MIPI_DSI_MSG_CMD_DMA_SCHED) flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; + if (flags & DSI_CTRL_CMD_BROADCAST) + flags |= DSI_CTRL_CMD_CUSTOM_DMA_SCHED; if (!display->enabled) flags &= ~DSI_CTRL_CMD_CUSTOM_DMA_SCHED; } From 58f90960453cdd29b412030c742f68cf0fbb297f Mon Sep 17 00:00:00 2001 From: Yojana Date: Wed, 12 Jan 2022 19:10:05 +0530 Subject: [PATCH 31/46] disp: msm: sde: add null pointer check for encoder current master During virt disable call, sde_enc master was used without checking for null condition. It results in crash. This change adds required null pointer check for sde encoder current master before dereferencing to avoid crash. Change-Id: I69ee17017712ea3549bfefce5975a564a5a8c2e9 Signed-off-by: Yojana --- msm/sde/sde_encoder.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 7ddd040093..013aa721c3 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -3091,6 +3091,10 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) } sde_enc = to_sde_encoder_virt(drm_enc); + if (!sde_enc->cur_master) { + SDE_ERROR("Invalid cur_master\n"); + return; + } sde_conn = to_sde_connector(sde_enc->cur_master->connector); SDE_DEBUG_ENC(sde_enc, "\n"); From f8180b0e86706b3162ef0c59fc0a7484e63c1d08 Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Tue, 21 Dec 2021 12:09:38 +0530 Subject: [PATCH 32/46] disp: msm: sde: dump user input_fence info on spec fence timeout This change dumps the userfds input_fence info in dma_fence_array on speculative fence wait timeout. This will be helpful to isolate the real fence timeouts when spec fence bind gets successful. Change-Id: I6aa37a06025f5ea43aaed8733f0803bfadd260fd Signed-off-by: Jayaprakash Madisetty --- msm/sde/sde_fence.c | 63 +++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/msm/sde/sde_fence.c b/msm/sde/sde_fence.c index 1a1055130f..3f4f1895c4 100644 --- a/msm/sde/sde_fence.c +++ b/msm/sde/sde_fence.c @@ -1,17 +1,20 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ #include #include +#include #include "msm_drv.h" #include "sde_kms.h" #include "sde_fence.h" #define TIMELINE_VAL_LENGTH 128 #define SPEC_FENCE_FLAG_FENCE_ARRAY 0x10 +#define SPEC_FENCE_FLAG_ARRAY_BIND 0x11 void *sde_sync_get(uint64_t fd) { @@ -25,11 +28,47 @@ void sde_sync_put(void *fence) dma_fence_put(fence); } +void sde_fence_dump(struct dma_fence *fence) +{ + char timeline_str[TIMELINE_VAL_LENGTH]; + + if (fence->ops->timeline_value_str) + fence->ops->timeline_value_str(fence, timeline_str, TIMELINE_VAL_LENGTH); + + SDE_ERROR( + "fence drv name:%s timeline name:%s seqno:0x%llx timeline:%s signaled:0x%x status:%d flags:0x%x\n", + fence->ops->get_driver_name(fence), + fence->ops->get_timeline_name(fence), + fence->seqno, timeline_str, + fence->ops->signaled ? + fence->ops->signaled(fence) : 0xffffffff, + dma_fence_get_status(fence), fence->flags); +} + +static void sde_fence_dump_user_fds_info(struct dma_fence *base_fence) +{ + struct dma_fence_array *array; + struct dma_fence *user_fence; + int i; + + array = container_of(base_fence, struct dma_fence_array, base); + if (test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY, &base_fence->flags) && + test_bit(SPEC_FENCE_FLAG_ARRAY_BIND, &base_fence->flags)) { + for (i = 0; i < array->num_fences; i++) { + user_fence = array->fences[i]; + if (user_fence) { + dma_fence_get(user_fence); + sde_fence_dump(user_fence); + dma_fence_put(user_fence); + } + } + } +} + signed long sde_sync_wait(void *fnc, long timeout_ms) { struct dma_fence *fence = fnc; int rc, status = 0; - char timeline_str[TIMELINE_VAL_LENGTH]; if (!fence) return -EINVAL; @@ -39,10 +78,6 @@ signed long sde_sync_wait(void *fnc, long timeout_ms) rc = dma_fence_wait_timeout(fence, true, msecs_to_jiffies(timeout_ms)); if (!rc || (rc == -EINVAL) || fence->error) { - if (fence->ops->timeline_value_str) - fence->ops->timeline_value_str(fence, - timeline_str, TIMELINE_VAL_LENGTH); - status = dma_fence_get_status(fence); if (test_bit(SPEC_FENCE_FLAG_FENCE_ARRAY, &fence->flags)) { if (status == -EINVAL) { @@ -51,23 +86,11 @@ signed long sde_sync_wait(void *fnc, long timeout_ms) } else if (fence->ops->signaled && fence->ops->signaled(fence)) { SDE_INFO("spec fence status:%d\n", status); } else { - SDE_ERROR( - "fence driver name:%s timeline name:%s signaled:0x%x status:%d flags:0x%x rc:%d\n", - fence->ops->get_driver_name(fence), - fence->ops->get_timeline_name(fence), - fence->ops->signaled ? - fence->ops->signaled(fence) : 0xffffffff, - status, fence->flags, rc); + sde_fence_dump(fence); + sde_fence_dump_user_fds_info(fence); } } else { - SDE_ERROR( - "fence driver name:%s timeline name:%s seqno:0x%llx timeline:%s signaled:0x%x status:%d\n", - fence->ops->get_driver_name(fence), - fence->ops->get_timeline_name(fence), - fence->seqno, timeline_str, - fence->ops->signaled ? - fence->ops->signaled(fence) : 0xffffffff, - status); + sde_fence_dump(fence); } } From 64ae0c58f02c55d9d900581f5a0ad641e5e07ef4 Mon Sep 17 00:00:00 2001 From: Mahadevan Date: Tue, 11 Jan 2022 18:05:59 +0530 Subject: [PATCH 33/46] disp: msm: update cleanup during bind failure in msm_drm_component_init During msm_drm_bind if one of the sub components fails to bind and defers the probe, it used to clear the device platform device private structures which are created as part of msm_pdev_probe. When sub devices try to bind as part of probe sequence it will try to bringup master msm_drm and accesses invalid address leading to crash. This change updates the cleanup procedure which avoids such crash. Change-Id: I2d5c94cfafa3c5ec23b81bb0a080ad6e0e5b02ad Signed-off-by: Mahadevan --- msm/msm_drv.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 37a35f4403..6d5512fdca 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -829,8 +829,12 @@ static int msm_drm_component_init(struct device *dev) /* Bind all our sub-components: */ ret = msm_component_bind_all(dev, ddev); - if (ret) + if (ret == -EPROBE_DEFER) { + destroy_workqueue(priv->wq); + return ret; + } else if (ret) { goto bind_fail; + } ret = msm_init_vram(ddev); if (ret) From ecc2d6e0bab8672c571ef3bafb7269ed52078e74 Mon Sep 17 00:00:00 2001 From: Prabhanjan Kandula Date: Thu, 16 Dec 2021 12:50:55 -0800 Subject: [PATCH 34/46] disp: msm: sde: software override for fal10 in cwb enable When cwb is enabled enable software override for fal10 veto to block fal10 entry as MDSS can keep asserting uidle if there are no fetch clients like dim layer only usecase. Change-Id: Ief51499d370c20fcbdda79576aee0179578650fd Signed-off-by: Prabhanjan Kandula Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_encoder.c | 33 +++++++++++++++++++++++++++++++++ msm/sde/sde_encoder.h | 3 +++ msm/sde/sde_hw_uidle.c | 16 +++++++++++++++- msm/sde/sde_hw_uidle.h | 7 +++++++ 4 files changed, 58 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 231378d9d3..5be8f4f89e 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -215,6 +215,36 @@ ktime_t sde_encoder_calc_last_vsync_timestamp(struct drm_encoder *drm_enc) return tvblank; } +static void _sde_encoder_control_fal10_veto(struct drm_encoder *drm_enc, bool veto) +{ + bool clone_mode; + struct sde_kms *sde_kms = sde_encoder_get_kms(drm_enc); + struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); + struct sde_uidle_cfg *uidle_cfg; + + if (!sde_kms->catalog || !sde_kms->hw_uidle || + !sde_kms->hw_uidle->ops.uidle_fal10_override) { + SDE_ERROR("invalid args\n"); + return; + } + + /* + * clone mode is the only scenario where we want to enable software override + * of fal10 veto. + */ + uidle_cfg = &sde_kms->catalog->uidle_cfg; + clone_mode = sde_encoder_in_clone_mode(drm_enc); + SDE_EVT32(DRMID(drm_enc), clone_mode, veto); + + if (clone_mode && veto) { + sde_kms->hw_uidle->ops.uidle_fal10_override(sde_kms->hw_uidle, veto); + sde_enc->fal10_veto_override = true; + } else if (sde_enc->fal10_veto_override && !veto) { + sde_kms->hw_uidle->ops.uidle_fal10_override(sde_kms->hw_uidle, veto); + sde_enc->fal10_veto_override = false; + } +} + static void _sde_encoder_pm_qos_add_request(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); @@ -2802,6 +2832,7 @@ static void _sde_encoder_virt_enable_helper(struct drm_encoder *drm_enc) memset(&sde_enc->prv_conn_roi, 0, sizeof(sde_enc->prv_conn_roi)); memset(&sde_enc->cur_conn_roi, 0, sizeof(sde_enc->cur_conn_roi)); + _sde_encoder_control_fal10_veto(drm_enc, true); } static void _sde_encoder_setup_dither(struct sde_encoder_phys *phys) @@ -3065,6 +3096,8 @@ void sde_encoder_virt_reset(struct drm_encoder *drm_enc) struct sde_kms *sde_kms = sde_encoder_get_kms(drm_enc); int i = 0; + _sde_encoder_control_fal10_veto(drm_enc, false); + for (i = 0; i < sde_enc->num_phys_encs; i++) { if (sde_enc->phys_encs[i]) { sde_enc->phys_encs[i]->cont_splash_enabled = false; diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index eaf1eb24c7..4fa8f33623 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -169,6 +170,7 @@ enum sde_enc_rc_states { * @cur_conn_roi: current connector roi * @prv_conn_roi: previous connector roi to optimize if unchanged * @crtc pointer to drm_crtc + * @fal10_veto_override: software override for micro idle fal10 veto * @recovery_events_enabled: status of hw recovery feature enable by client * @elevated_ahb_vote: increase AHB bus speed for the first frame * after power collapse @@ -241,6 +243,7 @@ struct sde_encoder_virt { struct sde_rect prv_conn_roi; struct drm_crtc *crtc; + bool fal10_veto_override; bool recovery_events_enabled; bool elevated_ahb_vote; struct dev_pm_qos_request pm_qos_cpu_req[NR_CPUS]; diff --git a/msm/sde/sde_hw_uidle.c b/msm/sde/sde_hw_uidle.c index 875662099f..ce93a1c7f0 100644 --- a/msm/sde/sde_hw_uidle.c +++ b/msm/sde/sde_hw_uidle.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -202,6 +202,19 @@ static void sde_hw_uilde_active_override(struct sde_hw_uidle *uidle, SDE_REG_WRITE(c, UIDLE_QACTIVE_HF_OVERRIDE, reg_val); } +static void sde_hw_uidle_fal10_override(struct sde_hw_uidle *uidle, + bool enable) +{ + struct sde_hw_blk_reg_map *c = &uidle->hw; + u32 reg_val = 0; + + if (enable) + reg_val = BIT(0) | BIT(31); + + SDE_REG_WRITE(c, UIDLE_FAL10_VETO_OVERRIDE, reg_val); + wmb(); +} + static inline void _setup_uidle_ops(struct sde_hw_uidle_ops *ops, unsigned long cap) { @@ -212,6 +225,7 @@ static inline void _setup_uidle_ops(struct sde_hw_uidle_ops *ops, ops->uidle_get_status = sde_hw_uidle_get_status; if (cap & BIT(SDE_UIDLE_QACTIVE_OVERRIDE)) ops->active_override_enable = sde_hw_uilde_active_override; + ops->uidle_fal10_override = sde_hw_uidle_fal10_override; } struct sde_hw_uidle *sde_hw_uidle_init(enum sde_uidle idx, diff --git a/msm/sde/sde_hw_uidle.h b/msm/sde/sde_hw_uidle.h index a4ebf505a9..5c51949717 100644 --- a/msm/sde/sde_hw_uidle.h +++ b/msm/sde/sde_hw_uidle.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. * */ @@ -118,6 +119,12 @@ struct sde_hw_uidle_ops { */ void (*active_override_enable)(struct sde_hw_uidle *uidle, bool enable); + /** + * uidle_fal10_overrride - enable/disable fal10 override + * @uidle: uidle context driver + * @enable: enable/disable + */ + void (*uidle_fal10_override)(struct sde_hw_uidle *uidle, bool enable); }; struct sde_hw_uidle { From 25beb2fcccf1bf63690566e4da75f33693dcf041 Mon Sep 17 00:00:00 2001 From: Srihitha Tangudu Date: Tue, 18 Jan 2022 13:43:24 +0530 Subject: [PATCH 35/46] disp: msm: dsi: Add new phy comaptible string for cape Cape uses phy version 4.3 but requires programming of different values for vreg_ctrl_0 and vreg_ctrl_1 to configure LDO setting. Add new phy compatible string to distinguish cape from other chipsets and program the registers accordingly. Change-Id: I68b266cc6e179d211ee0fd05584a605f39b4d31d Signed-off-by: Srihitha Tangudu --- msm/dsi/dsi_catalog.c | 2 ++ msm/dsi/dsi_phy.c | 11 +++++++++++ msm/dsi/dsi_phy_hw.h | 3 +++ msm/dsi/dsi_phy_hw_v4_0.c | 19 ++++++++++++++++--- msm/dsi/dsi_phy_timing_calc.c | 2 ++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/msm/dsi/dsi_catalog.c b/msm/dsi/dsi_catalog.c index 0fade39ba4..4f990bc86f 100644 --- a/msm/dsi/dsi_catalog.c +++ b/msm/dsi/dsi_catalog.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -265,6 +266,7 @@ int dsi_catalog_phy_setup(struct dsi_phy_hw *phy, case DSI_PHY_VERSION_4_1: case DSI_PHY_VERSION_4_2: case DSI_PHY_VERSION_4_3: + case DSI_PHY_VERSION_4_3_2: dsi_catalog_phy_4_0_init(phy); break; default: diff --git a/msm/dsi/dsi_phy.c b/msm/dsi/dsi_phy.c index a6160a24a3..d06b50b0e1 100644 --- a/msm/dsi/dsi_phy.c +++ b/msm/dsi/dsi_phy.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -71,6 +72,14 @@ static const struct dsi_ver_spec_info dsi_phy_v4_3 = { .timing_cfg_count = 14, }; +static const struct dsi_ver_spec_info dsi_phy_v4_3_2 = { + .version = DSI_PHY_VERSION_4_3_2, + .lane_cfg_count = 4, + .strength_cfg_count = 2, + .regulator_cfg_count = 0, + .timing_cfg_count = 14, +}; + static const struct of_device_id msm_dsi_phy_of_match[] = { { .compatible = "qcom,dsi-phy-v3.0", .data = &dsi_phy_v3_0,}, @@ -82,6 +91,8 @@ static const struct of_device_id msm_dsi_phy_of_match[] = { .data = &dsi_phy_v4_2,}, { .compatible = "qcom,dsi-phy-v4.3", .data = &dsi_phy_v4_3,}, + { .compatible = "qcom,dsi-phy-v4.3.2", + .data = &dsi_phy_v4_3_2,}, {} }; diff --git a/msm/dsi/dsi_phy_hw.h b/msm/dsi/dsi_phy_hw.h index adf39e8a1e..97063514b9 100644 --- a/msm/dsi/dsi_phy_hw.h +++ b/msm/dsi/dsi_phy_hw.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DSI_PHY_HW_H_ @@ -34,6 +35,7 @@ * @DSI_PHY_VERSION_4_1: 7nm * @DSI_PHY_VERSION_4_2: 5nm * @DSI_PHY_VERSION_4_3: 5nm + * @DSI_PHY_VERSION_4_3_2: 4nm (v4.3 specific to SM8475) * @DSI_PHY_VERSION_MAX: */ enum dsi_phy_version { @@ -43,6 +45,7 @@ enum dsi_phy_version { DSI_PHY_VERSION_4_1, /* 7nm */ DSI_PHY_VERSION_4_2, /* 5nm */ DSI_PHY_VERSION_4_3, /* 5nm */ + DSI_PHY_VERSION_4_3_2, /* 4nm */ DSI_PHY_VERSION_MAX }; diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index 7d6b409966..5e43079500 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -247,6 +248,7 @@ static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, u32 minor_ver = 0; /* For C-PHY, no low power settings for lower clk rate */ u32 vreg_ctrl_0 = 0x51; + u32 vreg_ctrl_1 = 0x55; u32 glbl_str_swi_cal_sel_ctrl = 0; u32 glbl_hstx_str_ctrl_0 = 0; u32 glbl_rescode_top_ctrl = 0; @@ -272,6 +274,11 @@ static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, glbl_rescode_bot_ctrl = 0x3c; } + if (phy->version == DSI_PHY_VERSION_4_3_2) { + vreg_ctrl_0 = 0x45; + vreg_ctrl_1 = 0x41; + } + /* de-assert digital and pll power down */ data = BIT(6) | BIT(5); DSI_W32(phy, DSIPHY_CMN_CTRL_0, data); @@ -295,7 +302,7 @@ static void dsi_phy_hw_cphy_enable(struct dsi_phy_hw *phy, /* Enable LDO */ DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_0, vreg_ctrl_0); - DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, 0x55); + DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, vreg_ctrl_1); DSI_W32(phy, DSIPHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL, glbl_str_swi_cal_sel_ctrl); DSI_W32(phy, DSIPHY_CMN_GLBL_HSTX_STR_CTRL_0, glbl_hstx_str_ctrl_0); @@ -356,6 +363,7 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, u32 minor_ver = 0; bool less_than_1500_mhz = false; u32 vreg_ctrl_0 = 0; + u32 vreg_ctrl_1 = 0x5c; u32 glbl_str_swi_cal_sel_ctrl = 0; u32 glbl_hstx_str_ctrl_0 = 0; u32 glbl_rescode_top_ctrl = 0; @@ -390,6 +398,11 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, if (phy->version >= DSI_PHY_VERSION_4_3) glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01; + if (phy->version == DSI_PHY_VERSION_4_3_2){ + vreg_ctrl_0 = 0x19; + vreg_ctrl_1 = 0x44; + } + split_link_enabled = cfg->split_link.enabled; lanes_per_sublink = cfg->split_link.lanes_per_sublink; /* de-assert digital and pll power down */ @@ -418,7 +431,7 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, /* Enable LDO */ DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_0, vreg_ctrl_0); - DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, 0x5c); + DSI_W32(phy, DSIPHY_CMN_VREG_CTRL_1, vreg_ctrl_1); DSI_W32(phy, DSIPHY_CMN_CTRL_3, 0x00); DSI_W32(phy, DSIPHY_CMN_GLBL_STR_SWI_CAL_SEL_CTRL, glbl_str_swi_cal_sel_ctrl); @@ -491,7 +504,7 @@ void dsi_phy_hw_v4_0_enable(struct dsi_phy_hw *phy, pr_warn("PLL turned on before configuring PHY\n"); /* Request for REFGEN ready */ - if (phy->version == DSI_PHY_VERSION_4_3) { + if (phy->version >= DSI_PHY_VERSION_4_3) { DSI_W32(phy, DSIPHY_CMN_GLBL_DIGTOP_SPARE10, 0x1); udelay(500); } diff --git a/msm/dsi/dsi_phy_timing_calc.c b/msm/dsi/dsi_phy_timing_calc.c index 723022e7c6..3799f99e33 100644 --- a/msm/dsi/dsi_phy_timing_calc.c +++ b/msm/dsi/dsi_phy_timing_calc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ #include "dsi_phy_timing_calc.h" @@ -994,6 +995,7 @@ int dsi_phy_timing_calc_init(struct dsi_phy_hw *phy, case DSI_PHY_VERSION_4_1: case DSI_PHY_VERSION_4_2: case DSI_PHY_VERSION_4_3: + case DSI_PHY_VERSION_4_3_2: ops->get_default_phy_params = dsi_phy_hw_v4_0_get_default_phy_params; ops->calc_clk_zero = From 137938ab7ecbf1320a3a52c526a311c747f62e3d Mon Sep 17 00:00:00 2001 From: Nilaan Gunabalachandran Date: Tue, 3 Aug 2021 15:50:50 -0400 Subject: [PATCH 36/46] disp: msm: sde: update framedata event handling This change updates framedata event and ubwc stats API to align with userspace handling and expectations. This change adds the empty irq event handler required to register the frame data event. This change also adds handling to the crtc event notify to provide the payload pointer directly, required for the buffer object, ensuring pointers are not mismatched while sending drm events. This change also updates the ubwc roi plane property to process the uapi defined roi. Change-Id: I209f2b7418a0ec33aa0488119eb3fdb8ae94e8ba Signed-off-by: Nilaan Gunabalachandran --- msm/sde/sde_crtc.c | 38 +++++++++++++++++++++++++++----------- msm/sde/sde_plane.c | 34 +++++++++++++++++++++------------- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 5600ecd714..52999e99fb 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -68,6 +68,8 @@ static int sde_crtc_mmrm_interrupt_handler(struct drm_crtc *crtc_drm, bool en, struct sde_irq_callback *idle_irq); static int sde_crtc_pm_event_handler(struct drm_crtc *crtc, bool en, struct sde_irq_callback *noirq); +static int sde_crtc_frame_data_interrupt_handler(struct drm_crtc *crtc_drm, + bool en, struct sde_irq_callback *idle_irq); static int _sde_crtc_set_noise_layer(struct sde_crtc *sde_crtc, struct sde_crtc_state *cstate, void __user *usr_ptr); @@ -86,6 +88,7 @@ static struct sde_crtc_custom_events custom_events[] = { {DRM_EVENT_LTM_OFF, sde_cp_ltm_off_event_handler}, {DRM_EVENT_MMRM_CB, sde_crtc_mmrm_interrupt_handler}, {DRM_EVENT_VM_RELEASE, sde_crtc_vm_release_handler}, + {DRM_EVENT_FRAME_DATA, sde_crtc_frame_data_interrupt_handler}, }; /* default input fence timeout, in ms */ @@ -459,9 +462,10 @@ static const struct attribute_group *sde_crtc_attr_groups[] = { NULL, }; -static void sde_crtc_event_notify(struct drm_crtc *crtc, uint32_t type, uint32_t len, uint64_t val) +static void sde_crtc_event_notify(struct drm_crtc *crtc, uint32_t type, void *payload, uint32_t len) { struct drm_event event; + uint32_t *data = (uint32_t *)payload; if (!crtc) { SDE_ERROR("invalid crtc\n"); @@ -470,10 +474,12 @@ static void sde_crtc_event_notify(struct drm_crtc *crtc, uint32_t type, uint32_t event.type = type; event.length = len; - msm_mode_object_event_notify(&crtc->base, crtc->dev, &event, (u8 *)&val); + msm_mode_object_event_notify(&crtc->base, crtc->dev, &event, (u8 *)payload); - SDE_EVT32(DRMID(crtc), type, len, val >> 32, val & 0xFFFFFFFF); - SDE_DEBUG("crtc:%d event(%d) value(%llu) notified\n", DRMID(crtc), type, val); + SDE_EVT32(DRMID(crtc), type, len, *data, + ((uint64_t)payload) >> 32, ((uint64_t)payload) & 0xFFFFFFFF); + SDE_DEBUG("crtc:%d event(%lu) ptr(%pK) value(%lu) notified\n", + DRMID(crtc), type, payload, *data); } static void sde_crtc_destroy(struct drm_crtc *crtc) @@ -2365,6 +2371,7 @@ static int _sde_crtc_get_frame_data_buffer(struct drm_crtc *crtc, uint32_t fd) return -ENOMEM; sde_crtc->frame_data.buf[cur_buf] = buf; + buf->fd = fd; buf->fb = drm_framebuffer_lookup(crtc->dev, NULL, fd); if (!buf->fb) { SDE_ERROR("unable to get fb"); @@ -2438,8 +2445,8 @@ static void _sde_crtc_frame_data_notify(struct drm_crtc *crtc, buf.fd = sde_crtc->frame_data.buf[cur_buf]->fd; buf.offset = msm_gem->offset; - sde_crtc_event_notify(crtc, DRM_EVENT_FRAME_DATA, sizeof(struct sde_drm_frame_data_buf), - (uint64_t)(&buf)); + sde_crtc_event_notify(crtc, DRM_EVENT_FRAME_DATA, &buf, + sizeof(struct sde_drm_frame_data_buf)); sde_crtc->frame_data.idx = ++sde_crtc->frame_data.idx % sde_crtc->frame_data.cnt; } @@ -2854,7 +2861,7 @@ void sde_crtc_complete_commit(struct drm_crtc *crtc, } if ((crtc->state->active_changed || cont_splash_enabled) && crtc->state->active) - sde_crtc_event_notify(crtc, DRM_EVENT_CRTC_POWER, sizeof(u32), power_on); + sde_crtc_event_notify(crtc, DRM_EVENT_CRTC_POWER, &power_on, sizeof(u32)); sde_core_perf_crtc_update(crtc, 0, false); } @@ -4353,7 +4360,7 @@ static void sde_crtc_mmrm_cb_notification(struct drm_crtc *crtc) kms->perf.clk_name); /* notify user space the reduced clk rate */ - sde_crtc_event_notify(crtc, DRM_EVENT_MMRM_CB, sizeof(unsigned long), requested_clk); + sde_crtc_event_notify(crtc, DRM_EVENT_MMRM_CB, &requested_clk, sizeof(unsigned long)); SDE_DEBUG("crtc[%d]: MMRM cb notified clk:%d\n", crtc->base.id, requested_clk); @@ -4427,7 +4434,7 @@ static void sde_crtc_handle_power_event(u32 event_type, void *arg) sde_crtc_reset_sw_state(crtc); sde_cp_crtc_suspend(crtc); power_on = 0; - sde_crtc_event_notify(crtc, DRM_EVENT_SDE_POWER, sizeof(u32), power_on); + sde_crtc_event_notify(crtc, DRM_EVENT_SDE_POWER, &power_on, sizeof(u32)); break; case SDE_POWER_EVENT_MMRM_CALLBACK: sde_crtc_mmrm_cb_notification(crtc); @@ -4586,7 +4593,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc) sde_cp_crtc_disable(crtc); power_on = 0; - sde_crtc_event_notify(crtc, DRM_EVENT_CRTC_POWER, sizeof(u32), power_on); + sde_crtc_event_notify(crtc, DRM_EVENT_CRTC_POWER, &power_on, sizeof(u32)); mutex_unlock(&sde_crtc->crtc_lock); } @@ -7485,6 +7492,13 @@ static int sde_crtc_vm_release_handler(struct drm_crtc *crtc_drm, { return 0; } + +static int sde_crtc_frame_data_interrupt_handler(struct drm_crtc *crtc_drm, + bool en, struct sde_irq_callback *irq) +{ + return 0; +} + /** * sde_crtc_update_cont_splash_settings - update mixer settings * and initial clk during device bootup for cont_splash use case @@ -7644,5 +7658,7 @@ void sde_crtc_disable_cp_features(struct drm_crtc *crtc) void _sde_crtc_vm_release_notify(struct drm_crtc *crtc) { - sde_crtc_event_notify(crtc, DRM_EVENT_VM_RELEASE, sizeof(uint32_t), 1); + uint32_t val = 1; + + sde_crtc_event_notify(crtc, DRM_EVENT_VM_RELEASE, &val, sizeof(uint32_t)); } diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 16dabee984..84f16322c4 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -4116,27 +4116,34 @@ static void _sde_plane_set_excl_rect_v1(struct sde_plane *psde, } static void _sde_plane_set_ubwc_stats_roi(struct sde_plane *psde, - struct sde_plane_state *pstate, uint64_t roi) + struct sde_plane_state *pstate, void __user *usr_ptr) { - uint16_t y0, y1; + struct sde_drm_ubwc_stats_roi roi = {0}; if (!psde || !pstate) { SDE_ERROR("invalid argument(s)\n"); return; } - y0 = roi & 0xFFFF; - y1 = (roi >> 0x10) & 0xFFFF; - - if (y0 > psde->pipe_cfg.src_rect.h || y1 > psde->pipe_cfg.src_rect.h) { - SDE_ERROR_PLANE(psde, "invalid ubwc roi y0 0x%x, y1 0x%x, src height 0x%x", - y0, y1, psde->pipe_cfg.src_rect.h); - y0 = 0; - y1 = 0; + if (!usr_ptr) { + SDE_DEBUG_PLANE(psde, "ubwc roi disabled"); + goto end; } - pstate->ubwc_stats_roi.y_coord0 = y0; - pstate->ubwc_stats_roi.y_coord1 = y1; + if (copy_from_user(&roi, usr_ptr, sizeof(roi))) { + SDE_ERROR_PLANE(psde, "failed to copy ubwc stats roi"); + return; + } + + if (roi.y_coord0 > psde->pipe_cfg.src_rect.h || roi.y_coord1 > psde->pipe_cfg.src_rect.h) { + SDE_ERROR_PLANE(psde, "invalid ubwc roi y0 0x%x, y1 0x%x, src height 0x%x", + roi.y_coord0, roi.y_coord1, psde->pipe_cfg.src_rect.h); + memset(&roi, 0, sizeof(roi)); + } + +end: + SDE_EVT32(psde, roi.y_coord0, roi.y_coord1); + memcpy(&pstate->ubwc_stats_roi, &roi, sizeof(struct sde_drm_ubwc_stats_roi)); } static int sde_plane_atomic_set_property(struct drm_plane *plane, @@ -4181,7 +4188,8 @@ static int sde_plane_atomic_set_property(struct drm_plane *plane, (void *)(uintptr_t)val); break; case PLANE_PROP_UBWC_STATS_ROI: - _sde_plane_set_ubwc_stats_roi(psde, pstate, val); + _sde_plane_set_ubwc_stats_roi(psde, pstate, + (void __user *)(uintptr_t)val); break; default: /* nothing to do */ From 03b3d8d7461dddea5ee8cd6e832ea7c511f45982 Mon Sep 17 00:00:00 2001 From: Soutrik Mukhopadhyay Date: Wed, 19 Jan 2022 12:41:56 +0530 Subject: [PATCH 37/46] disp: msm: dp: updated register values for 4nm target Changes include updated register writes for DP PLL as per 4nm target. Change-Id: I2d8ddbf4af5c2c6d885c73b7c888f31ce45f4cbf Signed-off-by: Soutrik Mukhopadhyay --- msm/dp/dp_catalog_v420.c | 4 ++-- msm/dp/dp_pll_4nm.c | 26 +++++++++++++------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/msm/dp/dp_catalog_v420.c b/msm/dp/dp_catalog_v420.c index 4ae0f23f7c..1724e75d44 100644 --- a/msm/dp/dp_catalog_v420.c +++ b/msm/dp/dp_catalog_v420.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2022, The Linux Foundation. All rights reserved. */ @@ -107,7 +107,7 @@ static void dp_catalog_aux_setup_v420(struct dp_catalog_aux *aux, if (phy_version >= 0x60000000) { /* Turn on BIAS current for PHY/PLL */ io_data = catalog->io->dp_pll; - dp_write(QSERDES_COM_BIAS_EN_CLKBUFLR_EN_V600, 0x1D); + dp_write(QSERDES_COM_BIAS_EN_CLKBUFLR_EN_V600, 0x17); wmb(); /* make sure BIAS programming happened */ } else { /* Turn on BIAS current for PHY/PLL */ diff --git a/msm/dp/dp_pll_4nm.c b/msm/dp/dp_pll_4nm.c index b6bab78956..b29a789ed3 100644 --- a/msm/dp/dp_pll_4nm.c +++ b/msm/dp/dp_pll_4nm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ /* @@ -236,9 +236,9 @@ static int dp_vco_pll_init_db_4nm(struct dp_pll_db *pdb, pdb->lock_cmp2_mode0 = 0x0e; pdb->phy_vco_div = 0x1; pdb->lock_cmp_en = 0x08; - pdb->ssc_step_size1_mode0 = 0x13; + pdb->ssc_step_size1_mode0 = 0x45; pdb->ssc_step_size2_mode0 = 0x06; - pdb->ssc_per1 = 0x40; + pdb->ssc_per1 = 0x36; pdb->cmp_code1_mode0 = 0xE2; pdb->cmp_code2_mode0 = 0x18; break; @@ -252,9 +252,9 @@ static int dp_vco_pll_init_db_4nm(struct dp_pll_db *pdb, pdb->lock_cmp2_mode0 = 0x1c; pdb->phy_vco_div = 0x2; pdb->lock_cmp_en = 0x08; - pdb->ssc_step_size1_mode0 = 0x1a; + pdb->ssc_step_size1_mode0 = 0x5C; pdb->ssc_step_size2_mode0 = 0x08; - pdb->ssc_per1 = 0x40; + pdb->ssc_per1 = 0x36; pdb->cmp_code1_mode0 = 0x2E; pdb->cmp_code2_mode0 = 0x21; break; @@ -268,9 +268,9 @@ static int dp_vco_pll_init_db_4nm(struct dp_pll_db *pdb, pdb->lock_cmp2_mode0 = 0x2a; pdb->phy_vco_div = 0x0; pdb->lock_cmp_en = 0x08; - pdb->ssc_step_size1_mode0 = 0x13; + pdb->ssc_step_size1_mode0 = 0x45; pdb->ssc_step_size2_mode0 = 0x06; - pdb->ssc_per1 = 0x40; + pdb->ssc_per1 = 0x36; pdb->cmp_code1_mode0 = 0xE2; pdb->cmp_code2_mode0 = 0x18; break; @@ -354,9 +354,9 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll, if (pll->bonding_en) dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1f); else - dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x1D); + dp_pll_write(dp_pll, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x17); - dp_pll_write(dp_pll, QSERDES_COM_CORE_CLK_EN, 0x1f); + dp_pll_write(dp_pll, QSERDES_COM_CORE_CLK_EN, 0x0f); dp_pll_write(dp_pll, QSERDES_COM_BIN_VCOCAL_CMP_CODE1_MODE0, pdb->cmp_code1_mode0); dp_pll_write(dp_pll, QSERDES_COM_BIN_VCOCAL_CMP_CODE2_MODE0, pdb->cmp_code2_mode0); /* Make sure the PHY register writes are done */ @@ -393,8 +393,8 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll, dp_pll_write(dp_ln_tx0, DP_TRAN_DRVR_EMP_EN, 0xf); dp_pll_write(dp_ln_tx0, TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); dp_pll_write(dp_ln_tx0, DP_TX_INTERFACE_MODE, 0x00); - dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_TX, 0x0A); - dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, 0x11); + dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_TX, 0x0C); + dp_pll_write(dp_ln_tx0, TXn_RES_CODE_LANE_OFFSET_RX, 0x0C); dp_pll_write(dp_ln_tx0, TXn_TX_BAND, 0x04); /* Make sure the PLL register writes are done */ wmb(); @@ -409,8 +409,8 @@ static int dp_config_vco_rate_4nm(struct dp_pll *pll, dp_pll_write(dp_ln_tx1, DP_TRAN_DRVR_EMP_EN, 0xf); dp_pll_write(dp_ln_tx1, TXn_PARRATE_REC_DETECT_IDLE_EN, 0x00); dp_pll_write(dp_ln_tx1, DP_TX_INTERFACE_MODE, 0x00); - dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_TX, 0x0A); - dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, 0x11); + dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_TX, 0x0C); + dp_pll_write(dp_ln_tx1, TXn_RES_CODE_LANE_OFFSET_RX, 0x0C); dp_pll_write(dp_ln_tx1, TXn_TX_BAND, 0x04); /* Make sure the PHY register writes are done */ wmb(); From 3fb9c29953b3287280971f9d6fecec72851bbd6b Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Wed, 29 Dec 2021 17:32:03 +0530 Subject: [PATCH 38/46] disp: msm: fail commit if drm_gem_obj was found attached to a sec CB This change fails the drm_atomic_commit and avoids S2 translation fault if drm_gem_object is found attached to a secure context bank during non secure session. In the current codeflow, we are detaching the gem object from secure CB and reattaching it to non secure CB, but only S1 pagetables entries get modified and S2 pagetables entries are not corrected since hyp_unassign is not called with CP_PIXEL VMID which can only be done by client when buffer gets allocated. Change-Id: I62302064f96276ef82044ee88fb89e295fb96b4b Signed-off-by: Jayaprakash Madisetty --- msm/msm_gem.c | 13 ++++++++++++- msm/sde/sde_plane.c | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/msm/msm_gem.c b/msm/msm_gem.c index f7fdc8eef7..823367fd09 100644 --- a/msm/msm_gem.c +++ b/msm/msm_gem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 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 @@ -445,6 +445,17 @@ static int msm_gem_get_iova_locked(struct drm_gem_object *obj, if ((dev && obj->import_attach) && ((dev != obj->import_attach->dev) || msm_obj->obj_dirty)) { + + if (of_device_is_compatible(dev->of_node, "qcom,smmu_sde_unsec") && + of_device_is_compatible(obj->import_attach->dev->of_node, + "qcom,smmu_sde_sec")) { + SDE_EVT32(obj->import_attach->dev, dev, msm_obj->sgt, + msm_obj->obj_dirty); + DRM_ERROR("gem obj found mapped to %s, now requesting map on %s", + dev_name(obj->import_attach->dev), dev_name(dev)); + return -EINVAL; + } + dmabuf = obj->import_attach->dmabuf; dma_map_attrs = obj->import_attach->dma_map_attrs; diff --git a/msm/sde/sde_plane.c b/msm/sde/sde_plane.c index 84f16322c4..d4a6e0f498 100644 --- a/msm/sde/sde_plane.c +++ b/msm/sde/sde_plane.c @@ -1991,7 +1991,9 @@ static int sde_plane_prepare_fb(struct drm_plane *plane, ret = msm_framebuffer_prepare(fb, pstate->aspace); if (ret) { - SDE_ERROR("failed to prepare framebuffer\n"); + SDE_ERROR("failed to prepare framebuffer fb:%d plane:%d pipe:%d ret:%d\n", + fb->base.id, plane->base.id, psde->pipe, ret); + SDE_EVT32(fb->base.id, plane->base.id, psde->pipe, ret, SDE_EVTLOG_ERROR); return ret; } } From 41f774902662f898239ea5197dbec34858919a85 Mon Sep 17 00:00:00 2001 From: Ritesh Kumar Date: Mon, 24 Jan 2022 16:27:47 +0530 Subject: [PATCH 39/46] disp: msm: dsi: update vreg_ctrl settings for cape This change updates vreg_ctrl_0 and vreg_ctrl_1 settings for cape DPHY as per the HW recommendation. Change-Id: Ide66c62d980b57de1f826ed24d1c0747d8fb6c77 Signed-off-by: Ritesh Kumar --- msm/dsi/dsi_phy_hw_v4_0.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index 5e43079500..e7904e79a6 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -399,8 +399,8 @@ static void dsi_phy_hw_dphy_enable(struct dsi_phy_hw *phy, glbl_rescode_top_ctrl = less_than_1500_mhz ? 0x3d : 0x01; if (phy->version == DSI_PHY_VERSION_4_3_2){ - vreg_ctrl_0 = 0x19; - vreg_ctrl_1 = 0x44; + vreg_ctrl_0 = 0x44; + vreg_ctrl_1 = 0x19; } split_link_enabled = cfg->split_link.enabled; From 812a36347b9fcd9251e030fabe6a6b6fb09d2434 Mon Sep 17 00:00:00 2001 From: Rajkumar Subbiah Date: Thu, 9 Dec 2021 21:12:54 -0500 Subject: [PATCH 40/46] disp: msm: dp: avoid duplicate read of link status During link training, after the swing/preemphasis is updated, the driver is supposed to poll the link status on the sink and quit once the LINK_STATUS_UPDATED bit is set and also latch the next set of swing/preemphasis requested by the sink. But currently, the driver is exiting the loop only when the LINK_STATUS_UPDATED bit is cleared. So, it also latches the swing/emphasis request from the second read. Typically, the SW read is slow enough that the bit is set on the first read. The driver then reads the second time and exits the loop, since the bit would be cleared then. In most cases, this doesn't affect the training sequence, since the swing/preemphasis request for next attempt is retained on the second read. But, atleast in one specific case, it was observed that the swing/emphasis request gets reset along with LINK_STATUS_UPDATED and so the driver ends up missing the actual request and latches incorrect values instead. This causes link training to fail as it keep retrying with the same values that it starts with. This change fixes the exit condition check so the driver quits the loop as soon as the LINK_STATUS_UPDATED bit is set. Change-Id: I7f5d9c6b30d48e113aef628d2ab2c1bd972fe743 Signed-off-by: Rajkumar Subbiah --- msm/dp/dp_ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index 0792d8242f..4dafff3fab 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ @@ -278,7 +278,7 @@ static int dp_ctrl_read_link_status(struct dp_ctrl_private *ctrl, break; } - if (!(link_status[offset] & DP_LINK_STATUS_UPDATED)) + if (link_status[offset] & DP_LINK_STATUS_UPDATED) break; } From 998bb11a2c107c618613250ea25860ad3e9198cd Mon Sep 17 00:00:00 2001 From: Yuchao Ma Date: Wed, 26 Jan 2022 11:22:44 +0800 Subject: [PATCH 41/46] disp: msm: sde: Reset backlight scale when HWC is stopped Reset backlight scale when HWC is stopped. Change-Id: Iafcb1560a901af3428a3eae19b01580a1c69eddf Signed-off-by: Yuchao Ma --- msm/sde/sde_connector.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/msm/sde/sde_connector.c b/msm/sde/sde_connector.c index b11183a139..aaa3eb90ca 100644 --- a/msm/sde/sde_connector.c +++ b/msm/sde/sde_connector.c @@ -825,6 +825,10 @@ static int _sde_connector_update_bl_scale(struct sde_connector *c_conn) } bl_config = &dsi_display->panel->bl_config; + bl_config->bl_scale = c_conn->bl_scale > MAX_BL_SCALE_LEVEL ? + MAX_BL_SCALE_LEVEL : c_conn->bl_scale; + bl_config->bl_scale_sv = c_conn->bl_scale_sv > SV_BL_SCALE_CAP ? + SV_BL_SCALE_CAP : c_conn->bl_scale_sv; if (!c_conn->allow_bl_update) { c_conn->unset_bl_level = bl_config->bl_level; @@ -834,11 +838,6 @@ static int _sde_connector_update_bl_scale(struct sde_connector *c_conn) if (c_conn->unset_bl_level) bl_config->bl_level = c_conn->unset_bl_level; - bl_config->bl_scale = c_conn->bl_scale > MAX_BL_SCALE_LEVEL ? - MAX_BL_SCALE_LEVEL : c_conn->bl_scale; - bl_config->bl_scale_sv = c_conn->bl_scale_sv > SV_BL_SCALE_CAP ? - SV_BL_SCALE_CAP : c_conn->bl_scale_sv; - SDE_DEBUG("bl_scale = %u, bl_scale_sv = %u, bl_level = %u\n", bl_config->bl_scale, bl_config->bl_scale_sv, bl_config->bl_level); From 7db99e30d5a495475cb572fb14d7fc06409758a0 Mon Sep 17 00:00:00 2001 From: Rajeev Nandan Date: Thu, 20 Jan 2022 12:53:09 +0530 Subject: [PATCH 42/46] Revert "disp: msm: sde: consider max of actual and default prefill lines" This reverts commit 6547137f7b81b678be4d9229b1696eb6f9851653. This change can cause negative mdp_transfer_time_us for the panels with VFP as big as panel active height. Change-Id: Ibebfcacd9c4eddf80749fa55509821b332fba4cf Signed-off-by: Rajeev Nandan --- msm/dsi/dsi_panel.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/msm/dsi/dsi_panel.c b/msm/dsi/dsi_panel.c index c4cdfc0233..f3b073d004 100644 --- a/msm/dsi/dsi_panel.c +++ b/msm/dsi/dsi_panel.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -3949,7 +3949,6 @@ 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; @@ -4013,12 +4012,8 @@ 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. */ - 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_lines = mult_frac(MIN_PREFILL_LINES, + timing->refresh_rate, 60); prefill_time_us = mult_frac(frame_time_us, prefill_lines, (timing->v_active)); From 5e75a0bfc746f080310d53558194537033838f96 Mon Sep 17 00:00:00 2001 From: Soutrik Mukhopadhyay Date: Fri, 28 Jan 2022 12:52:59 +0530 Subject: [PATCH 43/46] disp: msm: dp: updated copyright set for 4nm target Changes include support to update necessary copyright information to dp file for 4nm target. Change-Id: Iebb2cc542f7b9262073936f12d55eb1be788e757 Signed-off-by: Soutrik Mukhopadhyay --- msm/dp/dp_catalog_v420.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/dp/dp_catalog_v420.c b/msm/dp/dp_catalog_v420.c index 1724e75d44..c611f31593 100644 --- a/msm/dp/dp_catalog_v420.c +++ b/msm/dp/dp_catalog_v420.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2022, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ From e9dd33dd1e6cfb1d59e04f08f3d3639474a6864b Mon Sep 17 00:00:00 2001 From: Jayaprakash Madisetty Date: Mon, 31 Jan 2022 20:42:44 +0530 Subject: [PATCH 44/46] disp: msm: sde: configure dest_scaler op_mode for two independent displays Destination scaler0 and scaler1 when operated in independent mode, by two built-in independent displays the op_mode gets modified concurrently and HW flushes new config. This leads to underruns on both the displays. This change programs the op_mode correctly to operate ds0 and ds1 independently. Change-Id: I01a3d4a986e0e7166f8a38b4cf35981d3e434686 Signed-off-by: Jayaprakash Madisetty --- msm/sde/sde_hw_ds.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/msm/sde/sde_hw_ds.c b/msm/sde/sde_hw_ds.c index ddbf68b200..023ea03eb9 100644 --- a/msm/sde/sde_hw_ds.c +++ b/msm/sde/sde_hw_ds.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. */ @@ -16,8 +17,18 @@ static void sde_hw_ds_setup_opmode(struct sde_hw_ds *hw_ds, u32 op_mode) { struct sde_hw_blk_reg_map *hw = &hw_ds->hw; + u32 op_mode_val; - SDE_REG_WRITE(hw, DEST_SCALER_OP_MODE, op_mode); + op_mode_val = SDE_REG_READ(hw, DEST_SCALER_OP_MODE); + + if (op_mode) + op_mode_val |= op_mode; + else if (!op_mode && (op_mode_val & SDE_DS_OP_MODE_DUAL)) + op_mode_val = 0; + else + op_mode_val &= ~BIT(hw_ds->idx - DS_0); + + SDE_REG_WRITE(hw, DEST_SCALER_OP_MODE, op_mode_val); } static void sde_hw_ds_setup_scaler3(struct sde_hw_ds *hw_ds, From 107f473e54dfbaf00af286d228ae1e93ba253cc1 Mon Sep 17 00:00:00 2001 From: Yashwanth Date: Thu, 20 Jan 2022 18:49:27 +0530 Subject: [PATCH 45/46] disp: msm: update copyright description This change updates copyright description with correct license marking as per the guidelines. Change-Id: Ia74b721e78afcc7f8e88bcbccfcf15430111ec37 Signed-off-by: Yashwanth --- config/gki_parrotdispconf.h | 2 +- msm/dp/dp_ctrl.c | 2 +- msm/dsi/dsi_catalog.c | 2 +- msm/dsi/dsi_ctrl.c | 2 +- msm/dsi/dsi_display.c | 2 +- msm/dsi/dsi_phy_hw.h | 2 +- msm/dsi/dsi_phy_hw_v4_0.c | 2 +- msm/dsi/dsi_phy_timing_calc.c | 2 +- msm/msm_drv.c | 2 +- msm/sde/sde_encoder.c | 2 +- msm/sde/sde_encoder_phys_wb.c | 2 +- msm/sde/sde_hw_catalog.c | 2 +- msm/sde/sde_hw_catalog.h | 2 +- msm/sde/sde_hw_dsc_1_2.c | 2 +- 14 files changed, 14 insertions(+), 14 deletions(-) diff --git a/config/gki_parrotdispconf.h b/config/gki_parrotdispconf.h index 7efc517dbc..a29ab23a4f 100644 --- a/config/gki_parrotdispconf.h +++ b/config/gki_parrotdispconf.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #define CONFIG_DRM_MSM 1 diff --git a/msm/dp/dp_ctrl.c b/msm/dp/dp_ctrl.c index 4dafff3fab..e74972916f 100644 --- a/msm/dp/dp_ctrl.c +++ b/msm/dp/dp_ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. */ diff --git a/msm/dsi/dsi_catalog.c b/msm/dsi/dsi_catalog.c index 4f990bc86f..b230678916 100644 --- a/msm/dsi/dsi_catalog.c +++ b/msm/dsi/dsi_catalog.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index f2d6d2ea06..d367ce9afe 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ diff --git a/msm/dsi/dsi_display.c b/msm/dsi/dsi_display.c index 3ff64b8e2c..9a0f65c7f9 100644 --- a/msm/dsi/dsi_display.c +++ b/msm/dsi/dsi_display.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ diff --git a/msm/dsi/dsi_phy_hw.h b/msm/dsi/dsi_phy_hw.h index 97063514b9..a259b96330 100644 --- a/msm/dsi/dsi_phy_hw.h +++ b/msm/dsi/dsi_phy_hw.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _DSI_PHY_HW_H_ diff --git a/msm/dsi/dsi_phy_hw_v4_0.c b/msm/dsi/dsi_phy_hw_v4_0.c index e7904e79a6..bb7c33ff48 100644 --- a/msm/dsi/dsi_phy_hw_v4_0.c +++ b/msm/dsi/dsi_phy_hw_v4_0.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include diff --git a/msm/dsi/dsi_phy_timing_calc.c b/msm/dsi/dsi_phy_timing_calc.c index 3799f99e33..fcee9fcc24 100644 --- a/msm/dsi/dsi_phy_timing_calc.c +++ b/msm/dsi/dsi_phy_timing_calc.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "dsi_phy_timing_calc.h" diff --git a/msm/msm_drv.c b/msm/msm_drv.c index 6d5512fdca..dc0a9382ba 100644 --- a/msm/msm_drv.c +++ b/msm/msm_drv.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index b139a4aea6..46c7fa5492 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index b4d7e98371..aa29dc3577 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 6a67346b71..21418325dc 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2022, The Linux Foundation. All rights reserved. */ diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index f0260f5f7c..53f570aed0 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2022, The Linux Foundation. All rights reserved. */ diff --git a/msm/sde/sde_hw_dsc_1_2.c b/msm/sde/sde_hw_dsc_1_2.c index 8d5c7efcb3..e8b6735435 100644 --- a/msm/sde/sde_hw_dsc_1_2.c +++ b/msm/sde/sde_hw_dsc_1_2.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2020-2022, The Linux Foundation. All rights reserved. */ From cc71f44453d1577a215397013cd1aaf4d772e9aa Mon Sep 17 00:00:00 2001 From: Yojana Juadi Date: Thu, 3 Feb 2022 15:16:03 +0530 Subject: [PATCH 46/46] disp: msm: sde: avoid error during fal10_veto override enablement This change avoids sde error during fal10_veto override enablement for targets with uidle disabled and early returns in such case. Change-Id: I491952615d7b3cbd70d35b4a90ee8d27ab56c2ad Signed-off-by: Yojana Juadi --- msm/sde/sde_encoder.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 46c7fa5492..8c16662c95 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -220,10 +220,11 @@ static void _sde_encoder_control_fal10_veto(struct drm_encoder *drm_enc, bool ve bool clone_mode; struct sde_kms *sde_kms = sde_encoder_get_kms(drm_enc); struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); - struct sde_uidle_cfg *uidle_cfg; - if (!sde_kms->catalog || !sde_kms->hw_uidle || - !sde_kms->hw_uidle->ops.uidle_fal10_override) { + if (sde_kms->catalog && !sde_kms->catalog->uidle_cfg.uidle_rev) + return; + + if (!sde_kms->hw_uidle || !sde_kms->hw_uidle->ops.uidle_fal10_override) { SDE_ERROR("invalid args\n"); return; } @@ -232,7 +233,6 @@ static void _sde_encoder_control_fal10_veto(struct drm_encoder *drm_enc, bool ve * clone mode is the only scenario where we want to enable software override * of fal10 veto. */ - uidle_cfg = &sde_kms->catalog->uidle_cfg; clone_mode = sde_encoder_in_clone_mode(drm_enc); SDE_EVT32(DRMID(drm_enc), clone_mode, veto);