Browse Source

disp: msm: sde: defer S2-only and tvm dma_buf_map_attachment

For usecase with S2-only or TVM buffers, the mapping needs to be done
after the SCM call. This is required to ensure the mapping is done to
the correct SID. Previously with S2-only usecase, the map was returning
the PA which would remain the same, so there were no issues even though
the map sequence was incorrect. But this sequence will cause issues with
CSF-2.5 as it uses 2-stage with TVM, and requires the mapping to be done
after the scm-call. Fix the sequence for legacy secure-camera preview,
legacy secure-display and CSF 2.5 solution.

Change-Id: Id663d30fdbf8725f43f61e67d2d7ce72aa9f9506
Signed-off-by: Veera Sundaram Sankaran <[email protected]>
Veera Sundaram Sankaran 2 years ago
parent
commit
d867d748ab
2 changed files with 38 additions and 15 deletions
  1. 22 8
      msm/msm_gem_prime.c
  2. 16 7
      msm/sde/sde_plane.c

+ 22 - 8
msm/msm_gem_prime.c

@@ -118,7 +118,8 @@ struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
 	struct msm_drm_private *priv;
 	struct msm_kms *kms;
 	bool lazy_unmap = true;
-	bool is_vmid_tvm = false, is_vmid_cp_pixel = false, is_vmid_cam_preview = false;
+	bool is_vmid_tvm = false, is_vmid_cp_pixel = false;
+	bool is_vmid_sec_display = false, is_vmid_cam_preview = false;
 	int *vmid_list, *perms_list;
 	int nelems = 0, i, ret;
 	unsigned long dma_map_attrs = 0;
@@ -177,7 +178,11 @@ struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
 		} else if (vmid_list[i] == VMID_CP_CAMERA_PREVIEW) {
 			is_vmid_cam_preview = true;
 			break;
+		} else if (vmid_list[i] == VMID_CP_SEC_DISPLAY) {
+			is_vmid_sec_display = true;
+			break;
 		}
+
 	}
 
 	/* mem_buf_dma_buf_copy_vmperm uses kmemdup, do kfree to free up the memory */
@@ -190,7 +195,8 @@ struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
 	 */
 	if (is_vmid_cp_pixel) {
 		attach_dev = kms->funcs->get_address_space_device(kms, MSM_SMMU_DOMAIN_SECURE);
-	} else if (!iommu_present(&platform_bus_type) || is_vmid_tvm || is_vmid_cam_preview) {
+	} else if (!iommu_present(&platform_bus_type) || is_vmid_tvm || is_vmid_cam_preview
+			|| is_vmid_sec_display) {
 		attach_dev = dev->dev;
 		lazy_unmap = false;
 	} else {
@@ -225,12 +231,20 @@ struct drm_gem_object *msm_gem_prime_import(struct drm_device *dev,
 
 	attach->dma_map_attrs |= dma_map_attrs;
 
-	sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
-	if (IS_ERR(sgt)) {
-		ret = PTR_ERR(sgt);
-		DRM_ERROR(
-		"dma_buf_map_attachment failure, err=%d\n", ret);
-		goto fail_detach;
+	/*
+	 * avoid map_attachment for S2-only buffers and TVM buffers as it needs to be mapped
+	 * after the SID switch scm_call and will be handled during msm_gem_get_dma_addr
+	 */
+	if (!is_vmid_tvm && !is_vmid_cam_preview && !is_vmid_sec_display) {
+		sgt = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL);
+		if (IS_ERR(sgt)) {
+			ret = PTR_ERR(sgt);
+			DRM_ERROR("dma_buf_map_attachment failure, err=%d\n", ret);
+			goto fail_detach;
+		}
+	} else {
+		DRM_DEBUG("deferring dma_buf_map_attachment; tvm:%d, sec_cam:%d, sec_disp:%d\n",
+				is_vmid_tvm, is_vmid_cam_preview, is_vmid_sec_display);
 	}
 
 	/*

+ 16 - 7
msm/sde/sde_plane.c

@@ -2059,7 +2059,7 @@ static int sde_plane_prepare_fb(struct drm_plane *plane,
 	struct sde_plane_state *pstate = to_sde_plane_state(new_state);
 	struct sde_hw_fmt_layout layout;
 	struct msm_gem_address_space *aspace;
-	int ret;
+	int ret, mode;
 
 	if (!fb)
 		return 0;
@@ -2102,12 +2102,21 @@ static int sde_plane_prepare_fb(struct drm_plane *plane,
 		}
 	}
 
-	/* validate framebuffer layout before commit */
-	ret = sde_format_populate_layout(pstate->aspace,
-			fb, &layout);
-	if (ret) {
-		SDE_ERROR_PLANE(psde, "failed to get format layout, %d\n", ret);
-		return ret;
+	/*
+	 * Avoid mapping during the validate phase for S2-only buffer & CSF-2.5.
+	 * _sde_plane_set_scanout can handle the mapping after the scm_call during commit.
+	 */
+	mode = sde_plane_get_property(pstate, PLANE_PROP_FB_TRANSLATION_MODE);
+	if (mode != SDE_DRM_FB_SEC_DIR_TRANS) {
+		/* validate framebuffer layout before commit */
+		ret = sde_format_populate_layout(pstate->aspace, fb, &layout);
+		if (ret) {
+			SDE_ERROR_PLANE(psde, "failed to get format layout, %d\n", ret);
+			return ret;
+		}
+	} else {
+		SDE_DEBUG("deferring dma-buf mapping to commit phase\n");
+		SDE_EVT32(DRMID(plane), fb->base.id, mode);
 	}
 
 	return 0;