From c249858e2b1a159ee807325da9f2ee0ae44d78d6 Mon Sep 17 00:00:00 2001 From: Jeykumar Sankaran Date: Fri, 22 May 2020 12:50:42 -0700 Subject: [PATCH] disp: msm: sde: add client pre_release/post_acquire handles for VM layers client_pre_release/client_post_acquire hooks in vm_ops allows non-SDE clients to register for callbacks to be invoked - before releasing the resources from the current VM so that the client can updates the respective sw state to indicate the absence of HW ownership - before the first frame push after acquiring the HW to update reset the respective sw state to indicate the presence of HW ownership and resume operations Change-Id: I93e5a2b43c79b4e7cc28e6e0129d8091aa0e508d Signed-off-by: Jeykumar Sankaran --- msm/sde/sde_vm.h | 20 +++++++++++ msm/sde/sde_vm_common.c | 76 ++++++++++++++++++++++++++++++++++++++++ msm/sde/sde_vm_common.h | 12 +++++++ msm/sde/sde_vm_primary.c | 2 ++ msm/sde/sde_vm_trusted.c | 2 ++ 5 files changed, 112 insertions(+) diff --git a/msm/sde/sde_vm.h b/msm/sde/sde_vm.h index 366b116aadfe..1e7ae95de59d 100644 --- a/msm/sde/sde_vm.h +++ b/msm/sde/sde_vm.h @@ -119,6 +119,26 @@ struct sde_vm_ops { * @ops - primary VM specific ops functions */ void (*vm_deinit)(struct sde_kms *kms, struct sde_vm_ops *ops); + + /** + * vm_check - hook to check with vm_clients for its readiness to release + the HW reasources + */ + int (*vm_check)(void); + + /** + * vm_client_pre_release - hook to invoke vm_client list for pre_release + handling + * @kms - handle to sde_kms + */ + int (*vm_client_pre_release)(struct sde_kms *kms); + + /** + * vm_client_post_acquire - hook to invoke vm_client list for + * post_acquire resource handling + * @kms - handle to sde_kms + */ + int (*vm_client_post_acquire)(struct sde_kms *kms); }; /** diff --git a/msm/sde/sde_vm_common.c b/msm/sde/sde_vm_common.c index 5e59aa9af6de..0eac9a24cc5f 100644 --- a/msm/sde/sde_vm_common.c +++ b/msm/sde/sde_vm_common.c @@ -211,3 +211,79 @@ void sde_vm_free_resources(struct msm_io_res *io_res) msm_dss_clean_io_mem(&io_res->mem); msm_dss_clean_io_irq(&io_res->irq); } + +int sde_vm_post_acquire(struct sde_kms *kms) +{ + struct msm_drm_private *priv = kms->dev->dev_private; + struct msm_vm_client_entry *entry; + int rc = 0; + + list_for_each_entry(entry, &priv->vm_client_list, list) { + if (!entry->ops.vm_post_hw_acquire) + continue; + + rc = entry->ops.vm_post_hw_acquire(entry->data); + if (rc) { + SDE_ERROR("post_acquire failed for device: %d\n", + entry->dev->id); + goto post_acquire_rollback; + } + } + + return rc; + +post_acquire_rollback: + list_for_each_entry_continue_reverse(entry, &priv->vm_client_list, + list) { + if (!entry->ops.vm_pre_hw_release) + continue; + + rc = entry->ops.vm_pre_hw_release(entry->data); + if (rc) { + SDE_ERROR( + "post_acquire failed during rollback for device: %d\n", + entry->dev->id); + break; + } + } + + return rc; +} + +int sde_vm_pre_release(struct sde_kms *kms) +{ + struct msm_drm_private *priv = kms->dev->dev_private; + struct msm_vm_client_entry *entry; + int rc = 0; + + list_for_each_entry(entry, &priv->vm_client_list, list) { + if (!entry->ops.vm_pre_hw_release) + continue; + + rc = entry->ops.vm_pre_hw_release(entry->data); + if (rc) { + SDE_ERROR("pre_release failed for device: %d\n", + entry->dev->id); + goto pre_release_rollback; + } + } + + return rc; + +pre_release_rollback: + list_for_each_entry_continue_reverse(entry, &priv->vm_client_list, + list) { + if (!entry->ops.vm_post_hw_acquire) + continue; + + rc = entry->ops.vm_post_hw_acquire(entry->data); + if (rc) { + SDE_ERROR( + "post_acquire failed during rollback for device: %d\n", + entry->dev->id); + break; + } + } + + return rc; +} diff --git a/msm/sde/sde_vm_common.h b/msm/sde/sde_vm_common.h index ef9e389e5a2e..8914688be8ac 100644 --- a/msm/sde/sde_vm_common.h +++ b/msm/sde/sde_vm_common.h @@ -63,4 +63,16 @@ int sde_vm_get_resources(struct sde_kms *sde_kms, struct msm_io_res *io_res); */ void sde_vm_free_resources(struct msm_io_res *io_res); +/** + * sde_vm_post_acquire - handle post_acquire events with all the VM clients + * @kms: handle to sde_kms + */ +int sde_vm_post_acquire(struct sde_kms *kms); + +/** + * sde_vm_pre_release - handle pre_release events with all the VM clients + * @kms: handle to sde_kms + */ +int sde_vm_pre_release(struct sde_kms *kms); + #endif /* __SDE_VM_COMMON_H__ */ diff --git a/msm/sde/sde_vm_primary.c b/msm/sde/sde_vm_primary.c index 984917243c42..21544014e732 100644 --- a/msm/sde/sde_vm_primary.c +++ b/msm/sde/sde_vm_primary.c @@ -254,6 +254,8 @@ static void _sde_vm_set_ops(struct sde_vm_ops *ops) { memset(ops, 0, sizeof(*ops)); + ops->vm_client_pre_release = sde_vm_pre_release; + ops->vm_client_post_acquire = sde_vm_post_acquire; ops->vm_release = _sde_vm_release; ops->vm_owns_hw = sde_vm_owns_hw; ops->vm_deinit = _sde_vm_deinit; diff --git a/msm/sde/sde_vm_trusted.c b/msm/sde/sde_vm_trusted.c index 0f59e5145338..8a21593619d1 100644 --- a/msm/sde/sde_vm_trusted.c +++ b/msm/sde/sde_vm_trusted.c @@ -332,6 +332,8 @@ static void _sde_vm_set_ops(struct sde_vm_ops *ops) { memset(ops, 0, sizeof(*ops)); + ops->vm_client_pre_release = sde_vm_pre_release; + ops->vm_client_post_acquire = sde_vm_post_acquire; ops->vm_release = _sde_vm_release; ops->vm_owns_hw = sde_vm_owns_hw; ops->vm_deinit = _sde_vm_deinit;