Эх сурвалжийг харах

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 <[email protected]>
Jeykumar Sankaran 5 жил өмнө
parent
commit
c249858e2b

+ 20 - 0
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);
 };
 
 /**

+ 76 - 0
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;
+}

+ 12 - 0
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__ */

+ 2 - 0
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;

+ 2 - 0
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;