drm/msm/sde: enable ion for framebuffer object allocation

Enable internal framebuffer object allocation to use ion
allocator to support internal secure buffer allocation.

CRs-Fixed: 2009714
Change-Id: I3ea30ec6c495624d892c467b159a8584b0f0f82f
Signed-off-by: Alan Kwong <akwong@codeaurora.org>
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.c b/drivers/gpu/drm/msm/sde/sde_kms.c
index 3add5e5..ef2c80e 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.c
+++ b/drivers/gpu/drm/msm/sde/sde_kms.c
@@ -929,13 +929,9 @@
 		fbo->dma_buf = NULL;
 	}
 
-	for (i = 0; i < fbo->layout.num_planes; i++) {
-		if (fbo->bo[i]) {
-			mutex_lock(&dev->struct_mutex);
-			drm_gem_object_unreference(fbo->bo[i]);
-			mutex_unlock(&dev->struct_mutex);
-			fbo->bo[i] = NULL;
-		}
+	if (sde_kms->iclient && fbo->ihandle) {
+		ion_free(sde_kms->iclient, fbo->ihandle);
+		fbo->ihandle = NULL;
 	}
 }
 
@@ -994,17 +990,52 @@
 	}
 
 	/* allocate backing buffer object */
-	mutex_lock(&dev->struct_mutex);
-	fbo->bo[0] = msm_gem_new(dev, fbo->layout.total_size,
-			MSM_BO_SCANOUT | MSM_BO_WC);
-	if (IS_ERR(fbo->bo[0])) {
+	if (sde_kms->iclient) {
+		u32 heap_id = fbo->flags & DRM_MODE_FB_SECURE ?
+				ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID) :
+				ION_HEAP(ION_SYSTEM_HEAP_ID);
+
+		fbo->ihandle = ion_alloc(sde_kms->iclient,
+				fbo->layout.total_size, SZ_4K, heap_id, 0);
+		if (IS_ERR_OR_NULL(fbo->ihandle)) {
+			SDE_ERROR("failed to alloc ion memory\n");
+			ret = PTR_ERR(fbo->ihandle);
+			fbo->ihandle = NULL;
+			goto done;
+		}
+
+		fbo->dma_buf = ion_share_dma_buf(sde_kms->iclient,
+				fbo->ihandle);
+		if (IS_ERR(fbo->dma_buf)) {
+			SDE_ERROR("failed to share ion memory\n");
+			ret = -ENOMEM;
+			fbo->dma_buf = NULL;
+			goto done;
+		}
+
+		fbo->bo[0] = dev->driver->gem_prime_import(dev,
+				fbo->dma_buf);
+		if (IS_ERR(fbo->bo[0])) {
+			SDE_ERROR("failed to import ion memory\n");
+			ret = PTR_ERR(fbo->bo[0]);
+			fbo->bo[0] = NULL;
+			goto done;
+		}
+	} else {
+		mutex_lock(&dev->struct_mutex);
+		fbo->bo[0] = msm_gem_new(dev, fbo->layout.total_size,
+				MSM_BO_SCANOUT | MSM_BO_WC);
+		if (IS_ERR(fbo->bo[0])) {
+			mutex_unlock(&dev->struct_mutex);
+			SDE_ERROR("failed to new gem buffer\n");
+			ret = PTR_ERR(fbo->bo[0]);
+			fbo->bo[0] = NULL;
+			goto done;
+		}
 		mutex_unlock(&dev->struct_mutex);
-		SDE_ERROR("failed to new gem buffer\n");
-		ret = PTR_ERR(fbo->bo[0]);
-		fbo->bo[0] = NULL;
-		goto done;
 	}
 
+	mutex_lock(&dev->struct_mutex);
 	for (i = 1; i < fbo->layout.num_planes; i++) {
 		fbo->bo[i] = fbo->bo[0];
 		drm_gem_object_reference(fbo->bo[i]);
@@ -1110,6 +1141,11 @@
 	_sde_debugfs_destroy(sde_kms);
 	_sde_kms_mmu_destroy(sde_kms);
 
+	if (sde_kms->iclient) {
+		ion_client_destroy(sde_kms->iclient);
+		sde_kms->iclient = NULL;
+	}
+
 	if (sde_kms->catalog) {
 		for (i = 0; i < sde_kms->catalog->vbif_count; i++) {
 			u32 vbif_idx = sde_kms->catalog->vbif[i].id;
@@ -1462,6 +1498,13 @@
 		}
 	}
 
+	sde_kms->iclient = msm_ion_client_create(dev->unique);
+	if (IS_ERR(sde_kms->iclient)) {
+		rc = PTR_ERR(sde_kms->iclient);
+		SDE_DEBUG("msm_ion_client not available: %d\n", rc);
+		sde_kms->iclient = NULL;
+	}
+
 	/*
 	 * Now we need to read the HW catalog and initialize resources such as
 	 * clocks, regulators, GDSC/MMAGIC, ioremap the register ranges etc
diff --git a/drivers/gpu/drm/msm/sde/sde_kms.h b/drivers/gpu/drm/msm/sde/sde_kms.h
index 83edde3..ebc277e 100644
--- a/drivers/gpu/drm/msm/sde/sde_kms.h
+++ b/drivers/gpu/drm/msm/sde/sde_kms.h
@@ -19,6 +19,8 @@
 #ifndef __SDE_KMS_H__
 #define __SDE_KMS_H__
 
+#include <linux/msm_ion.h>
+
 #include "msm_drv.h"
 #include "msm_kms.h"
 #include "msm_mmu.h"
@@ -140,6 +142,7 @@
 	int nplane;
 	const struct sde_format *fmt;
 	struct sde_hw_fmt_layout layout;
+	struct ion_handle *ihandle;
 	struct dma_buf *dma_buf;
 	struct drm_gem_object *bo[4];
 	struct list_head fb_list;
@@ -155,6 +158,8 @@
 	int mmu_id[MSM_SMMU_DOMAIN_MAX];
 	struct sde_power_client *core_client;
 
+	struct ion_client *iclient;
+
 	/* directory entry for debugfs */
 	struct dentry *debugfs_danger;
 	struct dentry *debugfs_vbif;