소스 검색

disp msm: sde: add get gem buffer utility

This change adds a utility for mapping gem buffer objects based
on a frame buffer object. This utility will be used as
a basis for different driver components.

Change-Id: Ia9f2a42a9f8898c98478091b8e1cd06849145417
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 4 년 전
부모
커밋
9f954a19ff
2개의 변경된 파일93개의 추가작업 그리고 0개의 파일을 삭제
  1. 72 0
      msm/msm_gem.c
  2. 21 0
      msm/msm_gem.h

+ 72 - 0
msm/msm_gem.c

@@ -28,6 +28,9 @@
 #include "msm_mmu.h"
 #include "sde_dbg.h"
 
+#define GUARD_BYTES (BIT(8) - 1)
+#define ALIGNED_OFFSET (U32_MAX & ~(GUARD_BYTES))
+
 static void msm_gem_vunmap_locked(struct drm_gem_object *obj);
 
 
@@ -1395,3 +1398,72 @@ void msm_gem_object_set_name(struct drm_gem_object *bo, const char *fmt, ...)
 	vsnprintf(msm_obj->name, sizeof(msm_obj->name), fmt, ap);
 	va_end(ap);
 }
+
+void msm_gem_put_buffer(struct drm_gem_object *gem)
+{
+	struct msm_gem_object *msm_gem;
+
+	if (!gem)
+		return;
+
+	msm_gem = to_msm_bo(gem);
+
+	msm_gem_put_iova(gem, msm_gem->aspace);
+	msm_gem_put_vaddr(gem);
+}
+
+int msm_gem_get_buffer(struct drm_gem_object *gem,
+		struct drm_device *dev, struct drm_framebuffer *fb,
+		uint32_t align_size)
+{
+	struct msm_gem_object *msm_gem;
+	uint32_t size;
+	uint64_t iova_aligned;
+	int ret = -EINVAL;
+
+	if (!gem) {
+		DRM_ERROR("invalid drm gem");
+		return ret;
+	}
+
+	msm_gem = to_msm_bo(gem);
+
+	size = PAGE_ALIGN(gem->size);
+	if (size < (align_size + GUARD_BYTES)) {
+		DRM_ERROR("invalid gem size");
+		goto exit;
+	}
+
+	msm_gem_smmu_address_space_get(dev, MSM_SMMU_DOMAIN_UNSECURE);
+
+	if (PTR_ERR(msm_gem->aspace) == -ENODEV) {
+		DRM_DEBUG("IOMMU not present, relying on VRAM.");
+	} else if (IS_ERR_OR_NULL(msm_gem->aspace)) {
+		ret = PTR_ERR(msm_gem->aspace);
+		DRM_ERROR("failed to get aspace");
+		goto exit;
+	}
+
+	ret = msm_gem_get_iova(gem, msm_gem->aspace, &msm_gem->iova);
+	if (ret) {
+		DRM_ERROR("failed to get the iova ret %d", ret);
+		goto exit;
+	}
+
+	msm_gem_get_vaddr(gem);
+	if (IS_ERR_OR_NULL(msm_gem->vaddr)) {
+		DRM_ERROR("failed to get vaddr");
+		goto exit;
+	}
+
+	iova_aligned = (msm_gem->iova + GUARD_BYTES) & ALIGNED_OFFSET;
+	msm_gem->offset = iova_aligned - msm_gem->iova;
+	msm_gem->iova = msm_gem->iova + msm_gem->offset;
+
+	return 0;
+
+exit:
+	msm_gem_put_buffer(gem);
+
+	return ret;
+}

+ 21 - 0
msm/msm_gem.h

@@ -146,6 +146,10 @@ struct msm_gem_object {
 	 * new pagetables due to cb switch
 	 */
 	bool obj_dirty;
+
+	/* iova address and aligned offset */
+	uint64_t iova;
+	uint32_t offset;
 };
 #define to_msm_bo(x) container_of(x, struct msm_gem_object, base)
 
@@ -219,4 +223,21 @@ struct msm_gem_submit {
 	} bos[0];
 };
 
+/**
+ * msm_gem_put_buffer - put gem buffer
+ * @gem: pointer to gem buffer object
+ */
+void msm_gem_put_buffer(struct drm_gem_object *gem);
+
+/**
+ * msm_gem_gem_buffer - get a gem buffer
+ * @gem: drm gem object
+ * @drm_device: pointer to drm device
+ * @fb: frame buffer object
+ * @align_size: size to align the buffer to
+ */
+int msm_gem_get_buffer(struct drm_gem_object *gem,
+		struct drm_device *dev, struct drm_framebuffer *fb,
+		uint32_t align_size);
+
 #endif /* __MSM_GEM_H__ */