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 <jsanka@codeaurora.org>
This commit is contained in:
@@ -119,6 +119,26 @@ struct sde_vm_ops {
|
|||||||
* @ops - primary VM specific ops functions
|
* @ops - primary VM specific ops functions
|
||||||
*/
|
*/
|
||||||
void (*vm_deinit)(struct sde_kms *kms, struct sde_vm_ops *ops);
|
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -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_mem(&io_res->mem);
|
||||||
msm_dss_clean_io_irq(&io_res->irq);
|
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;
|
||||||
|
}
|
||||||
|
@@ -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);
|
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__ */
|
#endif /* __SDE_VM_COMMON_H__ */
|
||||||
|
@@ -254,6 +254,8 @@ static void _sde_vm_set_ops(struct sde_vm_ops *ops)
|
|||||||
{
|
{
|
||||||
memset(ops, 0, sizeof(*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_release = _sde_vm_release;
|
||||||
ops->vm_owns_hw = sde_vm_owns_hw;
|
ops->vm_owns_hw = sde_vm_owns_hw;
|
||||||
ops->vm_deinit = _sde_vm_deinit;
|
ops->vm_deinit = _sde_vm_deinit;
|
||||||
|
@@ -332,6 +332,8 @@ static void _sde_vm_set_ops(struct sde_vm_ops *ops)
|
|||||||
{
|
{
|
||||||
memset(ops, 0, sizeof(*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_release = _sde_vm_release;
|
||||||
ops->vm_owns_hw = sde_vm_owns_hw;
|
ops->vm_owns_hw = sde_vm_owns_hw;
|
||||||
ops->vm_deinit = _sde_vm_deinit;
|
ops->vm_deinit = _sde_vm_deinit;
|
||||||
|
Reference in New Issue
Block a user