Quellcode durchsuchen

disp: msm: sde: add helper to check VM hw availability

Add a utility function to check if HW has been handed over to
another VM.

Change-Id: Ic36ca1e7f15f7608e69d69fc3f4e7ad40be15704
Signed-off-by: Steve Cohen <[email protected]>
Steve Cohen vor 3 Jahren
Ursprung
Commit
7f3b2f0a4b
6 geänderte Dateien mit 40 neuen und 36 gelöschten Zeilen
  1. 2 6
      msm/sde/sde_connector.c
  2. 1 3
      msm/sde/sde_crtc.c
  3. 2 6
      msm/sde/sde_encoder.c
  4. 8 12
      msm/sde/sde_kms.c
  5. 23 1
      msm/sde/sde_vm.h
  6. 4 8
      msm/sde/sde_vm_common.c

+ 2 - 6
msm/sde/sde_connector.c

@@ -131,7 +131,6 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
 	struct drm_event event;
 	int rc = 0;
 	struct sde_kms *sde_kms;
-	struct sde_vm_ops *vm_ops;
 
 	sde_kms = _sde_connector_get_kms(&c_conn->base);
 	if (!sde_kms) {
@@ -167,8 +166,7 @@ static int sde_backlight_device_update_status(struct backlight_device *bd)
 
 	sde_vm_lock(sde_kms);
 
-	vm_ops = sde_vm_get_ops(sde_kms);
-	if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) {
+	if (!sde_vm_owns_hw(sde_kms)) {
 		SDE_DEBUG("skipping bl update due to HW unavailablity\n");
 		goto done;
 	}
@@ -2077,7 +2075,6 @@ static ssize_t _sde_debugfs_conn_cmd_tx_write(struct file *file,
 {
 	struct drm_connector *connector = file->private_data;
 	struct sde_connector *c_conn = NULL;
-	struct sde_vm_ops *vm_ops;
 	struct sde_kms *sde_kms;
 	char *input, *token, *input_copy, *input_dup = NULL;
 	const char *delim = " ";
@@ -2107,9 +2104,8 @@ static ssize_t _sde_debugfs_conn_cmd_tx_write(struct file *file,
 	if (!input)
 		return -ENOMEM;
 
-	vm_ops = sde_vm_get_ops(sde_kms);
 	sde_vm_lock(sde_kms);
-	if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) {
+	if (!sde_vm_owns_hw(sde_kms)) {
 		SDE_DEBUG("op not supported due to HW unavailablity\n");
 		rc = -EOPNOTSUPP;
 		goto end;

+ 1 - 3
msm/sde/sde_crtc.c

@@ -6451,7 +6451,6 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
 	struct sde_crtc *sde_crtc;
 	struct sde_kms *sde_kms;
 	struct sde_crtc_mixer *m;
-	struct sde_vm_ops *vm_ops;
 	int i = 0, rc;
 	ssize_t len = 0;
 	char buf[MISR_BUFF_SIZE + 1] = {'\0'};
@@ -6472,9 +6471,8 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
 	if (rc < 0)
 		return rc;
 
-	vm_ops = sde_vm_get_ops(sde_kms);
 	sde_vm_lock(sde_kms);
-	if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) {
+	if (!sde_vm_owns_hw(sde_kms)) {
 		SDE_DEBUG("op not supported due to HW unavailability\n");
 		rc = -EOPNOTSUPP;
 		goto end;

+ 2 - 6
msm/sde/sde_encoder.c

@@ -4046,12 +4046,10 @@ static void sde_encoder_early_wakeup_work_handler(struct kthread_work *work)
 {
 	struct sde_encoder_virt *sde_enc = container_of(work,
 			struct sde_encoder_virt, early_wakeup_work);
-	struct sde_vm_ops *vm_ops;
 	struct sde_kms *sde_kms = to_sde_kms(ddev_to_msm_kms(sde_enc->base.dev));
 
-	vm_ops = sde_vm_get_ops(sde_kms);
 	sde_vm_lock(sde_kms);
-	if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) {
+	if (!sde_vm_owns_hw(sde_kms)) {
 		sde_vm_unlock(sde_kms);
 		SDE_DEBUG("skip early wakeup for ENC-%d, HW is owned by other VM\n",
 				DRMID(&sde_enc->base));
@@ -4751,7 +4749,6 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
 	struct sde_encoder_virt *sde_enc;
 	struct sde_kms *sde_kms = NULL;
 	struct drm_encoder *drm_enc;
-	struct sde_vm_ops *vm_ops;
 	int i = 0, len = 0;
 	char buf[MISR_BUFF_SIZE + 1] = {'\0'};
 	int rc;
@@ -4777,9 +4774,8 @@ static ssize_t _sde_encoder_misr_read(struct file *file,
 	if (rc < 0)
 		return rc;
 
-	vm_ops = sde_vm_get_ops(sde_kms);
 	sde_vm_lock(sde_kms);
-	if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) {
+	if (!sde_vm_owns_hw(sde_kms)) {
 		SDE_DEBUG("op not supported due to HW unavailablity\n");
 		rc = -EOPNOTSUPP;
 		goto end;

+ 8 - 12
msm/sde/sde_kms.c

@@ -2765,6 +2765,7 @@ static int sde_kms_check_vm_request(struct msm_kms *kms,
 	enum sde_crtc_vm_req old_vm_req = VM_REQ_NONE, new_vm_req = VM_REQ_NONE;
 	struct sde_vm_ops *vm_ops;
 	bool vm_req_active = false;
+	bool vm_owns_hw;
 	enum sde_crtc_idle_pc_state idle_pc_state;
 	struct sde_mdss_cfg *catalog;
 	int rc = 0;
@@ -2789,7 +2790,7 @@ static int sde_kms_check_vm_request(struct msm_kms *kms,
 		return -EINVAL;
 
 	sde_vm_lock(sde_kms);
-
+	vm_owns_hw = sde_vm_owns_hw(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;
 
@@ -2814,8 +2815,7 @@ static int sde_kms_check_vm_request(struct msm_kms *kms,
 			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);
+					old_vm_req, new_vm_req, vm_owns_hw, rc);
 				goto end;
 			} else if (old_vm_req == VM_REQ_ACQUIRE &&
 					new_vm_req == VM_REQ_NONE) {
@@ -2852,9 +2852,8 @@ static int sde_kms_check_vm_request(struct msm_kms *kms,
 			crtc_encoder_cnt++;
 	}
 
-	SDE_EVT32(old_vm_req, new_vm_req, vm_ops->vm_owns_hw(sde_kms));
-	SDE_DEBUG("VM  o_state:%d, n_state:%d, hw_owner:%d\n", old_vm_req,
-			new_vm_req, vm_ops->vm_owns_hw(sde_kms));
+	SDE_EVT32(old_vm_req, new_vm_req, vm_owns_hw);
+	SDE_DEBUG("VM  o_state:%d, n_state:%d, hw_owner:%d\n", old_vm_req, new_vm_req, vm_owns_hw);
 
 	for_each_new_connector_in_state(state, connector, new_connstate, i) {
 		int conn_mask = active_cstate->connector_mask;
@@ -2903,13 +2902,12 @@ static int sde_kms_check_vm_request(struct msm_kms *kms,
 		goto end;
 	}
 
-	if ((new_vm_req == VM_REQ_ACQUIRE) && !vm_ops->vm_owns_hw(sde_kms)) {
+	if ((new_vm_req == VM_REQ_ACQUIRE) && !vm_owns_hw) {
 		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);
+				old_vm_req, new_vm_req, vm_owns_hw, rc);
 			goto end;
 		}
 
@@ -5065,7 +5063,6 @@ static int _sde_kms_register_events(struct msm_kms *kms,
 	struct drm_crtc *crtc;
 	struct drm_connector *conn;
 	struct sde_kms *sde_kms;
-	struct sde_vm_ops *vm_ops;
 
 	if (!kms || !obj) {
 		SDE_ERROR("invalid argument kms %pK obj %pK\n", kms, obj);
@@ -5073,9 +5070,8 @@ static int _sde_kms_register_events(struct msm_kms *kms,
 	}
 
 	sde_kms = to_sde_kms(kms);
-	vm_ops = sde_vm_get_ops(sde_kms);
 	sde_vm_lock(sde_kms);
-	if (vm_ops && vm_ops->vm_owns_hw && !vm_ops->vm_owns_hw(sde_kms)) {
+	if (!sde_vm_owns_hw(sde_kms)) {
 		sde_vm_unlock(sde_kms);
 		SDE_DEBUG("HW is owned by other VM\n");
 		return -EACCES;

+ 23 - 1
msm/sde/sde_vm.h

@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
- * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
  */
 
 #ifndef __SDE_VM_H__
@@ -285,6 +285,23 @@ static inline struct sde_vm_ops *sde_vm_get_ops(struct sde_kms *sde_kms)
 
 	return &sde_kms->vm->vm_ops;
 }
+
+/**
+ * sde_vm_owns_hw - checks if the executing VM currently has HW ownership (caller must be holding
+ *                  the sde_vm_lock)
+ * @sde_kms - pointer to sde_kms
+ * @return - true if this VM currently owns the HW
+ */
+static inline bool sde_vm_owns_hw(struct sde_kms *sde_kms)
+{
+	struct sde_vm_ops *vm_ops = sde_kms ? sde_vm_get_ops(sde_kms) : NULL;
+
+	if (vm_ops && vm_ops->vm_owns_hw)
+		return vm_ops->vm_owns_hw(sde_kms);
+
+	return true;
+}
+
 #else
 static inline int sde_vm_primary_init(struct sde_kms *kms)
 {
@@ -314,5 +331,10 @@ static inline struct sde_vm_ops *sde_vm_get_ops(struct sde_kms *sde_kms)
 	return NULL;
 }
 
+static inline bool sde_vm_owns_hw(struct sde_kms *sde_kms)
+{
+	return true;
+}
+
 #endif /* IS_ENABLED(CONFIG_DRM_SDE_VM) */
 #endif /* __SDE_VM_H__ */

+ 4 - 8
msm/sde/sde_vm_common.c

@@ -296,16 +296,13 @@ int sde_vm_request_valid(struct sde_kms *sde_kms,
 			  enum sde_crtc_vm_req old_state,
 			  enum sde_crtc_vm_req new_state)
 {
-	struct sde_vm_ops *vm_ops;
 	int rc = 0;
-
-	vm_ops = &sde_kms->vm->vm_ops;
+	bool vm_owns_hw = sde_vm_owns_hw(sde_kms);
 
 	switch (new_state) {
 	case VM_REQ_RELEASE:
 	case VM_REQ_NONE:
-		if ((old_state == VM_REQ_RELEASE) ||
-			!vm_ops->vm_owns_hw(sde_kms))
+		if ((old_state == VM_REQ_RELEASE) || !vm_owns_hw)
 			rc = -EINVAL;
 		break;
 	case VM_REQ_ACQUIRE:
@@ -318,9 +315,8 @@ int sde_vm_request_valid(struct sde_kms *sde_kms,
 	};
 
 	SDE_DEBUG("old req: %d new req: %d owns_hw: %d, rc: %d\n",
-			old_state, new_state,
-			vm_ops->vm_owns_hw(sde_kms), rc);
-	SDE_EVT32(old_state, new_state, vm_ops->vm_owns_hw(sde_kms), rc);
+			old_state, new_state, vm_owns_hw, rc);
+	SDE_EVT32(old_state, new_state, vm_owns_hw, rc);
 
 	return rc;
 }