Browse Source

Merge "dsp: add support for CMA heap allocation during call"

qctecmdr 4 years ago
parent
commit
9c822fca10
1 changed files with 107 additions and 9 deletions
  1. 107 9
      dsp/msm_audio_ion_vm.c

+ 107 - 9
dsp/msm_audio_ion_vm.c

@@ -34,6 +34,7 @@
 struct msm_audio_ion_private {
 	bool smmu_enabled;
 	struct device *cb_dev;
+	struct device *cb_cma_dev;
 	u8 device_status;
 	struct list_head alloc_list;
 	struct mutex list_mutex;
@@ -88,7 +89,8 @@ static void msm_audio_ion_add_allocation(
 }
 
 static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
-				 dma_addr_t *addr, size_t *len)
+				 dma_addr_t *addr, size_t *len,
+				 bool cma_mem)
 {
 
 	struct msm_audio_alloc_data *alloc_data;
@@ -96,7 +98,10 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
 	unsigned long ionflag = 0;
 	int rc = 0;
 
-	cb_dev = msm_audio_ion_data.cb_dev;
+	if (cma_mem)
+		cb_dev = msm_audio_ion_data.cb_cma_dev;
+	else
+		cb_dev = msm_audio_ion_data.cb_dev;
 
 	/* Data required per buffer mapping */
 	alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
@@ -161,14 +166,19 @@ free_alloc_data:
 	return rc;
 }
 
-static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf)
+static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, bool cma_mem)
 {
 	int rc = 0;
 	struct msm_audio_alloc_data *alloc_data = NULL;
 	struct list_head *ptr, *next;
-	struct device *cb_dev = msm_audio_ion_data.cb_dev;
+	struct device *cb_dev;
 	bool found = false;
 
+	if (cma_mem)
+		cb_dev = msm_audio_ion_data.cb_cma_dev;
+	else
+		cb_dev = msm_audio_ion_data.cb_dev;
+
 	/*
 	 * Though list_for_each_safe is delete safe, lock
 	 * should be explicitly acquired to avoid race condition
@@ -401,7 +411,7 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
 {
 	int rc = 0;
 
-	rc = msm_audio_dma_buf_map(dma_buf, addr, len);
+	rc = msm_audio_dma_buf_map(dma_buf, addr, len, false);
 	if (rc) {
 		pr_err("%s: failed to map DMA buf, err = %d\n",
 			__func__, rc);
@@ -509,7 +519,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
 	if (IS_ERR_OR_NULL(*vaddr)) {
 		pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
 		rc = -ENOMEM;
-		msm_audio_dma_buf_unmap(dma_buf);
+		msm_audio_dma_buf_unmap(dma_buf, false);
 		goto err;
 	}
 
@@ -518,7 +528,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
 		if (rc) {
 			pr_err("%s: failed to do smmu map, err = %d\n",
 				__func__, rc);
-			msm_audio_dma_buf_unmap(dma_buf);
+			msm_audio_dma_buf_unmap(dma_buf, false);
 			goto err;
 		}
 	}
@@ -623,7 +633,7 @@ EXPORT_SYMBOL(msm_audio_is_hypervisor_supported);
  * @bufsz: buffer size
  * @paddr: Physical address to be assigned with allocated region
  * @plen: length of allocated region to be assigned
- * vaddr: virtual address to be assigned
+ * @vaddr: virtual address to be assigned
  *
  * Returns 0 on success or error on failure
  */
@@ -679,6 +689,67 @@ err:
 }
 EXPORT_SYMBOL(msm_audio_ion_import);
 
+/**
+ * msm_audio_ion_import_cma-
+ *        Import ION buffer with given file descriptor
+ *
+ * @dma_buf: dma_buf for the ION memory
+ * @fd: file descriptor for the ION memory
+ * @ionflag: flags associated with ION buffer
+ * @bufsz: buffer size
+ * @paddr: Physical address to be assigned with allocated region
+ * @plen: length of allocated region to be assigned
+ * @vaddr: virtual address to be assigned
+ *
+ * Returns 0 on success or error on failure
+ */
+int msm_audio_ion_import_cma(struct dma_buf **dma_buf, int fd,
+			unsigned long *ionflag, size_t bufsz,
+			dma_addr_t *paddr, size_t *plen, void **vaddr)
+{
+	int rc = 0;
+
+	if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
+		pr_debug("%s: probe is not done, deferred\n", __func__);
+		return -EPROBE_DEFER;
+	}
+
+	if (!dma_buf || !paddr || !vaddr || !plen ||
+	    !msm_audio_ion_data.cb_cma_dev) {
+		pr_err("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	/* bufsz should be 0 and fd shouldn't be 0 as of now */
+	*dma_buf = dma_buf_get(fd);
+	pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
+	if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
+		pr_err("%s: dma_buf_get failed\n", __func__);
+		rc = -EINVAL;
+		goto err;
+	}
+
+	if (ionflag != NULL) {
+		rc = dma_buf_get_flags(*dma_buf, ionflag);
+		if (rc) {
+			pr_err("%s: could not get flags for the dma_buf\n",
+				__func__);
+			goto err_ion_flag;
+		}
+	}
+
+	msm_audio_dma_buf_map(*dma_buf, paddr, plen, true);
+
+	return 0;
+
+err_ion_flag:
+	dma_buf_put(*dma_buf);
+err:
+	*dma_buf = NULL;
+	return rc;
+}
+EXPORT_SYMBOL(msm_audio_ion_import_cma);
+
 /**
  * msm_audio_ion_free -
  *        fress ION memory for given client and handle
@@ -707,12 +778,33 @@ int msm_audio_ion_free(struct dma_buf *dma_buf)
 				__func__, ret);
 	}
 
-	msm_audio_dma_buf_unmap(dma_buf);
+	msm_audio_dma_buf_unmap(dma_buf, false);
 
 	return 0;
 }
 EXPORT_SYMBOL(msm_audio_ion_free);
 
+/**
+ * msm_audio_ion_free_cma -
+ *        fress ION memory for given client and handle
+ *
+ * @dma_buf: dma_buf for the ION memory
+ *
+ * Returns 0 on success or error on failure
+ */
+int msm_audio_ion_free_cma(struct dma_buf *dma_buf)
+{
+	if (!dma_buf) {
+		pr_err("%s: dma_buf invalid\n", __func__);
+		return -EINVAL;
+	}
+
+	msm_audio_dma_buf_unmap(dma_buf, true);
+
+	return 0;
+}
+EXPORT_SYMBOL(msm_audio_ion_free_cma);
+
 /**
  * msm_audio_ion_mmap -
  *       Audio ION memory map
@@ -814,6 +906,7 @@ EXPORT_SYMBOL(msm_audio_populate_upper_32_bits);
 
 static const struct of_device_id msm_audio_ion_dt_match[] = {
 	{ .compatible = "qcom,msm-audio-ion" },
+	{ .compatible = "qcom,msm-audio-ion-cma"},
 	{ }
 };
 MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
@@ -833,6 +926,11 @@ static int msm_audio_ion_probe(struct platform_device *pdev)
 		return 0;
 	}
 
+	if (of_device_is_compatible(dev->of_node, "qcom,msm-audio-ion-cma")) {
+		msm_audio_ion_data.cb_cma_dev = dev;
+		return 0;
+	}
+
 	smmu_enabled = of_property_read_bool(dev->of_node,
 					     msm_audio_ion_dt);
 	msm_audio_ion_data.smmu_enabled = smmu_enabled;