Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d200c2fb authored by Guodong Hu's avatar Guodong Hu Committed by Gerrit - the friendly Code Review server
Browse files

dsp: add support for CMA heap allocation during call



Add support for CMA heap allocation during call.

Mirror from: 3226736

Change-Id: I30a237b360ec6d690515682f0d98a86148acf059
Signed-off-by: default avatarKunlei Zhang <kunleiz@codeaurora.org>
Signed-off-by: default avatarGuodong Hu <guodhu@codeaurora.org>
parent 994eb4e8
Loading
Loading
Loading
Loading
+107 −9
Original line number Diff line number Diff line
@@ -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,6 +98,9 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
	unsigned long ionflag = 0;
	int rc = 0;

	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 */
@@ -161,14 +166,19 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
	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 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
}
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;