From 26b6ae2d211baa80c9b22bd3dcbf559fdf7fd7a9 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Thu, 22 Oct 2020 11:07:31 -0700 Subject: [PATCH] disp: msm: sde: fix Trusted-ui state transition check Fix the checks done as part of the trsuted-ui transition. Allow full validation to go through whenever the new vm request or old vm request is not NONE. Split the checks and the vm acquire, so vm acquire can be done after all necessary checks are over. Change-Id: I91165010ad110193c2ca3947af8c6504cd259919 Signed-off-by: Veera Sundaram Sankaran --- msm/sde/sde_kms.c | 68 +++++++++++++++++++++++++++++------------ msm/sde/sde_vm_common.c | 8 +---- 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 8e5fe0c25892..6c720ceb24e6 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -2502,6 +2502,12 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, if (!vm_ops) return 0; + if (!vm_ops->vm_request_valid || !vm_ops->vm_owns_hw || + !vm_ops->vm_acquire) + return -EINVAL; + + sde_vm_lock(sde_kms); + for_each_oldnew_crtc_in_state(state, crtc, old_cstate, new_cstate, i) { struct sde_crtc_state *old_state = NULL, *new_state = NULL; @@ -2516,12 +2522,27 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, 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 (new_vm_req || old_vm_req) - vm_req_active = true; + if (old_vm_req || new_vm_req) { + rc = vm_ops->vm_request_valid(sde_kms, + old_vm_req, new_vm_req); + if (rc) { + SDE_ERROR( + "VM transition check failed; o_state:%d, n_state:%d, hw_owner:%d, rc:%d\n", + old_vm_req, new_vm_req, + vm_ops->vm_owns_hw(sde_kms), rc); + goto end; + } else if (old_vm_req == VM_REQ_ACQUIRE && + new_vm_req == VM_REQ_NONE) { + SDE_DEBUG( + "VM transition valid; ignore further checks\n"); + } else { + vm_req_active = true; + } + } idle_pc_state = sde_crtc_get_property(new_state, CRTC_PROP_IDLE_PC_STATE); @@ -2530,6 +2551,10 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, commit_crtc_cnt++; } + /* return early if no active vm request */ + if (!vm_req_active) + goto end; + list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { if (!crtc->state->active) continue; @@ -2539,36 +2564,39 @@ static int sde_kms_check_vm_request(struct msm_kms *kms, } /* Check for single crtc commits only on valid VM requests */ - if (vm_req_active && active_crtc && global_active_crtc && + if (active_crtc && global_active_crtc && (commit_crtc_cnt > sde_kms->catalog->max_trusted_vm_displays || global_crtc_cnt > sde_kms->catalog->max_trusted_vm_displays || active_crtc != global_active_crtc)) { SDE_ERROR( - "failed to switch VM due to CRTC concurrencies: MAX_CNT: %d active_cnt: %d global_cnt: %d active_crtc: %d global_crtc: %d\n", + "VM switch failed; MAX:%d a_cnt:%d g_cnt:%d a_crtc:%d g_crtc:%d\n", sde_kms->catalog->max_trusted_vm_displays, - commit_crtc_cnt, global_crtc_cnt, active_crtc, - global_active_crtc); - return -E2BIG; + commit_crtc_cnt, global_crtc_cnt, DRMID(active_crtc), + DRMID(global_active_crtc)); + rc = -E2BIG; + goto end; } - if (!vm_req_active) - return 0; - /* disable idle-pc before releasing the HW */ if ((new_vm_req == VM_REQ_RELEASE) && (idle_pc_state == IDLE_PC_ENABLE)) { - SDE_ERROR("failed to switch VM since idle-pc is enabled\n"); - return -EINVAL; + SDE_ERROR("VM switch failed since idle-pc is enabled\n"); + rc = -EINVAL; + goto end; } - sde_vm_lock(sde_kms); + if ((new_vm_req == VM_REQ_ACQUIRE) && !vm_ops->vm_owns_hw(sde_kms)) { + rc = vm_ops->vm_acquire(sde_kms); + if (rc) { + SDE_ERROR( + "VM acquire failed; o_state:%d, n_state:%d, hw_owner:%d, rc:%d\n", + old_vm_req, new_vm_req, + vm_ops->vm_owns_hw(sde_kms), rc); + goto end; + } + } - if (vm_ops->vm_request_valid) - rc = vm_ops->vm_request_valid(sde_kms, old_vm_req, new_vm_req); - if (rc) - SDE_ERROR( - "failed to complete vm transition request. old_state = %d, new_state = %d, hw_ownership: %d\n", - old_vm_req, new_vm_req, vm_ops->vm_owns_hw(sde_kms)); +end: sde_vm_unlock(sde_kms); return rc; diff --git a/msm/sde/sde_vm_common.c b/msm/sde/sde_vm_common.c index d48ce18ec0c3..5026a8aa64c2 100644 --- a/msm/sde/sde_vm_common.c +++ b/msm/sde/sde_vm_common.c @@ -306,14 +306,8 @@ int sde_vm_request_valid(struct sde_kms *sde_kms, rc = -EINVAL; break; case VM_REQ_ACQUIRE: - if (old_state != VM_REQ_RELEASE) { + if (old_state != VM_REQ_RELEASE) rc = -EINVAL; - } else if (!vm_ops->vm_owns_hw(sde_kms)) { - if (vm_ops->vm_acquire) - rc = vm_ops->vm_acquire(sde_kms); - else - rc = -EINVAL; - } break; default: SDE_ERROR("invalid vm request\n");