dsp: add support for CMA heap allocation during call
Add support for CMA heap allocation during call. Change-Id: I65cd291a9db56bf53d9bb9b4e6c7236da9d7288c Signed-off-by: Kunlei Zhang <kunleiz@codeaurora.org>
This commit is contained in:
@@ -449,6 +449,9 @@ static void delete_cal_block(struct cal_block_data *cal_block)
|
|||||||
kfree(cal_block->cal_info);
|
kfree(cal_block->cal_info);
|
||||||
cal_block->cal_info = NULL;
|
cal_block->cal_info = NULL;
|
||||||
if (cal_block->map_data.dma_buf != NULL) {
|
if (cal_block->map_data.dma_buf != NULL) {
|
||||||
|
if (cal_block->cma_mem)
|
||||||
|
msm_audio_ion_free_cma(cal_block->map_data.dma_buf);
|
||||||
|
else
|
||||||
msm_audio_ion_free(cal_block->map_data.dma_buf);
|
msm_audio_ion_free(cal_block->map_data.dma_buf);
|
||||||
cal_block->map_data.dma_buf = NULL;
|
cal_block->map_data.dma_buf = NULL;
|
||||||
}
|
}
|
||||||
@@ -608,12 +611,22 @@ static int cal_block_ion_alloc(struct cal_block_data *cal_block)
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cal_block->cma_mem) {
|
||||||
|
ret = msm_audio_ion_import_cma(&cal_block->map_data.dma_buf,
|
||||||
|
cal_block->map_data.ion_map_handle,
|
||||||
|
NULL, 0,
|
||||||
|
&cal_block->cal_data.paddr,
|
||||||
|
&cal_block->map_data.map_size,
|
||||||
|
&cal_block->cal_data.kvaddr);
|
||||||
|
} else {
|
||||||
ret = msm_audio_ion_import(&cal_block->map_data.dma_buf,
|
ret = msm_audio_ion_import(&cal_block->map_data.dma_buf,
|
||||||
cal_block->map_data.ion_map_handle,
|
cal_block->map_data.ion_map_handle,
|
||||||
NULL, 0,
|
NULL, 0,
|
||||||
&cal_block->cal_data.paddr,
|
&cal_block->cal_data.paddr,
|
||||||
&cal_block->map_data.map_size,
|
&cal_block->map_data.map_size,
|
||||||
&cal_block->cal_data.kvaddr);
|
&cal_block->cal_data.kvaddr);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("%s: audio ION import failed, rc = %d\n",
|
pr_err("%s: audio ION import failed, rc = %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
@@ -646,6 +659,7 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
|
|||||||
INIT_LIST_HEAD(&cal_block->list);
|
INIT_LIST_HEAD(&cal_block->list);
|
||||||
|
|
||||||
cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle;
|
cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle;
|
||||||
|
cal_block->cma_mem = basic_cal->cal_data.cma_mem;
|
||||||
if (basic_cal->cal_data.mem_handle > 0) {
|
if (basic_cal->cal_data.mem_handle > 0) {
|
||||||
if (cal_block_ion_alloc(cal_block)) {
|
if (cal_block_ion_alloc(cal_block)) {
|
||||||
pr_err("%s: cal_block_ion_alloc failed!\n",
|
pr_err("%s: cal_block_ion_alloc failed!\n",
|
||||||
@@ -738,6 +752,9 @@ static int realloc_memory(struct cal_block_data *cal_block)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
if (cal_block->cma_mem)
|
||||||
|
msm_audio_ion_free_cma(cal_block->map_data.dma_buf);
|
||||||
|
else
|
||||||
msm_audio_ion_free(cal_block->map_data.dma_buf);
|
msm_audio_ion_free(cal_block->map_data.dma_buf);
|
||||||
cal_block->map_data.dma_buf = NULL;
|
cal_block->map_data.dma_buf = NULL;
|
||||||
cal_block->cal_data.size = 0;
|
cal_block->cal_data.size = 0;
|
||||||
@@ -856,6 +873,7 @@ int cal_utils_alloc_cal(size_t data_size, void *data,
|
|||||||
cal_block = get_matching_cal_block(cal_type,
|
cal_block = get_matching_cal_block(cal_type,
|
||||||
data);
|
data);
|
||||||
if (cal_block != NULL) {
|
if (cal_block != NULL) {
|
||||||
|
cal_block->cma_mem = alloc_data->cal_data.cma_mem;
|
||||||
ret = unmap_memory(cal_type, cal_block);
|
ret = unmap_memory(cal_type, cal_block);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err;
|
goto err;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
struct msm_audio_ion_private {
|
struct msm_audio_ion_private {
|
||||||
bool smmu_enabled;
|
bool smmu_enabled;
|
||||||
struct device *cb_dev;
|
struct device *cb_dev;
|
||||||
|
struct device *cb_cma_dev;
|
||||||
u8 device_status;
|
u8 device_status;
|
||||||
struct list_head alloc_list;
|
struct list_head alloc_list;
|
||||||
struct mutex list_mutex;
|
struct mutex list_mutex;
|
||||||
@@ -64,7 +65,8 @@ static void msm_audio_ion_add_allocation(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
|
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;
|
struct msm_audio_alloc_data *alloc_data;
|
||||||
@@ -72,6 +74,9 @@ static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
|
|||||||
unsigned long ionflag = 0;
|
unsigned long ionflag = 0;
|
||||||
int rc = 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;
|
cb_dev = msm_audio_ion_data.cb_dev;
|
||||||
|
|
||||||
/* Data required per buffer mapping */
|
/* Data required per buffer mapping */
|
||||||
@@ -137,14 +142,18 @@ free_alloc_data:
|
|||||||
return rc;
|
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;
|
int rc = 0;
|
||||||
struct msm_audio_alloc_data *alloc_data = NULL;
|
struct msm_audio_alloc_data *alloc_data = NULL;
|
||||||
struct list_head *ptr, *next;
|
struct list_head *ptr, *next;
|
||||||
struct device *cb_dev = msm_audio_ion_data.cb_dev;
|
struct device *cb_dev;
|
||||||
bool found = false;
|
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
|
* Though list_for_each_safe is delete safe, lock
|
||||||
* should be explicitly acquired to avoid race condition
|
* should be explicitly acquired to avoid race condition
|
||||||
@@ -190,7 +199,7 @@ static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
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) {
|
if (rc) {
|
||||||
pr_err("%s: failed to map DMA buf, err = %d\n",
|
pr_err("%s: failed to map DMA buf, err = %d\n",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
@@ -324,7 +333,7 @@ static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
|
|||||||
if (IS_ERR_OR_NULL(*vaddr)) {
|
if (IS_ERR_OR_NULL(*vaddr)) {
|
||||||
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
|
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
msm_audio_dma_buf_unmap(dma_buf);
|
msm_audio_dma_buf_unmap(dma_buf, false);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +454,7 @@ EXPORT_SYMBOL(msm_audio_ion_dma_map);
|
|||||||
* @bufsz: buffer size
|
* @bufsz: buffer size
|
||||||
* @paddr: Physical address to be assigned with allocated region
|
* @paddr: Physical address to be assigned with allocated region
|
||||||
* @plen: length of allocated region to be assigned
|
* @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
|
* Returns 0 on success or error on failure
|
||||||
*/
|
*/
|
||||||
@@ -501,6 +510,67 @@ err:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_audio_ion_import);
|
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 -
|
* msm_audio_ion_free -
|
||||||
* fress ION memory for given client and handle
|
* fress ION memory for given client and handle
|
||||||
@@ -522,12 +592,33 @@ int msm_audio_ion_free(struct dma_buf *dma_buf)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
msm_audio_dma_buf_unmap(dma_buf);
|
msm_audio_dma_buf_unmap(dma_buf, false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(msm_audio_ion_free);
|
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 -
|
* msm_audio_ion_mmap -
|
||||||
* Audio ION memory map
|
* Audio ION memory map
|
||||||
@@ -690,6 +781,7 @@ static int msm_audio_smmu_init(struct device *dev)
|
|||||||
|
|
||||||
static const struct of_device_id msm_audio_ion_dt_match[] = {
|
static const struct of_device_id msm_audio_ion_dt_match[] = {
|
||||||
{ .compatible = "qcom,msm-audio-ion" },
|
{ .compatible = "qcom,msm-audio-ion" },
|
||||||
|
{ .compatible = "qcom,msm-audio-ion-cma"},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
|
MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
|
||||||
@@ -716,6 +808,10 @@ static int msm_audio_ion_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
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,
|
smmu_enabled = of_property_read_bool(dev->of_node,
|
||||||
msm_audio_ion_dt);
|
msm_audio_ion_dt);
|
||||||
msm_audio_ion_data.smmu_enabled = smmu_enabled;
|
msm_audio_ion_data.smmu_enabled = smmu_enabled;
|
||||||
|
124
dsp/q6adm.c
124
dsp/q6adm.c
@@ -19,6 +19,7 @@
|
|||||||
#include <dsp/q6common.h>
|
#include <dsp/q6common.h>
|
||||||
#include <ipc/apr.h>
|
#include <ipc/apr.h>
|
||||||
#include "adsp_err.h"
|
#include "adsp_err.h"
|
||||||
|
#include <soc/qcom/secure_buffer.h>
|
||||||
|
|
||||||
#define TIMEOUT_MS 1000
|
#define TIMEOUT_MS 1000
|
||||||
|
|
||||||
@@ -106,6 +107,8 @@ struct adm_ctl {
|
|||||||
int ffecns_port_id;
|
int ffecns_port_id;
|
||||||
int native_mode;
|
int native_mode;
|
||||||
uint32_t copp_token;
|
uint32_t copp_token;
|
||||||
|
int tx_port_id;
|
||||||
|
bool hyp_assigned;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct adm_ctl this_adm;
|
static struct adm_ctl this_adm;
|
||||||
@@ -2311,6 +2314,9 @@ static void send_adm_cal_type(int cal_index, int path, int port_id,
|
|||||||
{
|
{
|
||||||
struct cal_block_data *cal_block = NULL;
|
struct cal_block_data *cal_block = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
int dest_perms[2] = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE};
|
||||||
|
int source_vm[1] = {VMID_HLOS};
|
||||||
|
int dest_vm[2] = {VMID_LPASS, VMID_ADSP_HEAP};
|
||||||
|
|
||||||
pr_debug("%s: cal index %d\n", __func__, cal_index);
|
pr_debug("%s: cal index %d\n", __func__, cal_index);
|
||||||
|
|
||||||
@@ -2326,6 +2332,28 @@ static void send_adm_cal_type(int cal_index, int path, int port_id,
|
|||||||
if (cal_block == NULL)
|
if (cal_block == NULL)
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
|
||||||
|
if (cal_block->cma_mem) {
|
||||||
|
if (cal_block->cal_data.paddr == 0 ||
|
||||||
|
cal_block->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n", __func__);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
ret = hyp_assign_phys(cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size,
|
||||||
|
source_vm, 1, dest_vm, dest_perms, 2);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, ret, cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
this_adm.tx_port_id = port_id;
|
||||||
|
this_adm.hyp_assigned = true;
|
||||||
|
pr_debug("%s: hyp_assign_phys success in tx_port_id 0x%x\n",
|
||||||
|
__func__, this_adm.tx_port_id);
|
||||||
|
}
|
||||||
ret = adm_remap_and_send_cal_block(cal_index, port_id, copp_idx,
|
ret = adm_remap_and_send_cal_block(cal_index, port_id, copp_idx,
|
||||||
cal_block, perf_mode, app_type, acdb_id, sample_rate);
|
cal_block, perf_mode, app_type, acdb_id, sample_rate);
|
||||||
|
|
||||||
@@ -3849,6 +3877,12 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
|
|||||||
|
|
||||||
int ret = 0, port_idx;
|
int ret = 0, port_idx;
|
||||||
int copp_id = RESET_COPP_ID;
|
int copp_id = RESET_COPP_ID;
|
||||||
|
bool result = false;
|
||||||
|
int dest_perms[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
|
||||||
|
int source_vm[2] = {VMID_LPASS, VMID_ADSP_HEAP};
|
||||||
|
int dest_vm[1] = {VMID_HLOS};
|
||||||
|
struct cal_block_data *cal_block = NULL;
|
||||||
|
int cal_index = ADM_AUDPROC_PERSISTENT_CAL;
|
||||||
|
|
||||||
pr_debug("%s: port_id=0x%x perf_mode: %d copp_idx: %d\n", __func__,
|
pr_debug("%s: port_id=0x%x perf_mode: %d copp_idx: %d\n", __func__,
|
||||||
port_id, perf_mode, copp_idx);
|
port_id, perf_mode, copp_idx);
|
||||||
@@ -3948,6 +3982,49 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
|
|||||||
ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close);
|
ret = apr_send_pkt(this_adm.apr, (uint32_t *)&close);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s: ADM close failed %d\n", __func__, ret);
|
pr_err("%s: ADM close failed %d\n", __func__, ret);
|
||||||
|
if (this_adm.tx_port_id == port_id) {
|
||||||
|
mutex_lock(&this_adm.cal_data[cal_index]->lock);
|
||||||
|
cal_block = cal_utils_get_only_cal_block(
|
||||||
|
this_adm.cal_data[cal_index]);
|
||||||
|
if (cal_block != NULL) {
|
||||||
|
result = true;
|
||||||
|
pr_debug("%s: cma_alloc %d\n",
|
||||||
|
__func__, cal_block->cma_mem);
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
pr_debug("%s: use hyp assigned %d, use buffer %d\n",
|
||||||
|
__func__, this_adm.hyp_assigned,
|
||||||
|
cal_block->buffer_number);
|
||||||
|
if(cal_block->cma_mem &&
|
||||||
|
this_adm.hyp_assigned) {
|
||||||
|
if (cal_block->cal_data.paddr == 0 ||
|
||||||
|
cal_block->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n",
|
||||||
|
__func__);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
ret = hyp_assign_phys(
|
||||||
|
cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size,
|
||||||
|
source_vm, 2, dest_vm,
|
||||||
|
dest_perms, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, ret,
|
||||||
|
cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size);
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
pr_debug("%s: hyp_assign_phys success\n",
|
||||||
|
__func__);
|
||||||
|
this_adm.hyp_assigned = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = -EINVAL;
|
||||||
|
}
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3976,10 +4053,55 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
|
|||||||
rtac_remove_adm_device(port_id, copp_id);
|
rtac_remove_adm_device(port_id, copp_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this_adm.tx_port_id == port_id) {
|
||||||
|
mutex_lock(&this_adm.cal_data[cal_index]->lock);
|
||||||
|
cal_block = cal_utils_get_only_cal_block(
|
||||||
|
this_adm.cal_data[cal_index]);
|
||||||
|
if (cal_block != NULL) {
|
||||||
|
result = true;
|
||||||
|
pr_debug("%s: cma_alloc %d\n",
|
||||||
|
__func__, cal_block->cma_mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
pr_debug("%s: use hyp assigned %d, use buffer %d\n",
|
||||||
|
__func__, this_adm.hyp_assigned,
|
||||||
|
cal_block->buffer_number);
|
||||||
|
if(cal_block->cma_mem && this_adm.hyp_assigned) {
|
||||||
|
if (cal_block->cal_data.paddr == 0 ||
|
||||||
|
cal_block->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n",
|
||||||
|
__func__);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
ret = hyp_assign_phys(cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size,
|
||||||
|
source_vm, 2, dest_vm,
|
||||||
|
dest_perms, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, ret, cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto fail;
|
||||||
|
} else {
|
||||||
|
pr_debug("%s: hyp_assign_phys success\n",
|
||||||
|
__func__);
|
||||||
|
this_adm.hyp_assigned = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
if (port_id == this_adm.ffecns_port_id)
|
if (port_id == this_adm.ffecns_port_id)
|
||||||
this_adm.ffecns_port_id = -1;
|
this_adm.ffecns_port_id = -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
fail:
|
||||||
|
mutex_unlock(&this_adm.cal_data[cal_index]->lock);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(adm_close);
|
EXPORT_SYMBOL(adm_close);
|
||||||
|
|
||||||
@@ -5536,6 +5658,8 @@ int __init adm_init(void)
|
|||||||
|
|
||||||
this_adm.ec_ref_rx = -1;
|
this_adm.ec_ref_rx = -1;
|
||||||
this_adm.ffecns_port_id = -1;
|
this_adm.ffecns_port_id = -1;
|
||||||
|
this_adm.tx_port_id = -1;
|
||||||
|
this_adm.hyp_assigned = false;
|
||||||
init_waitqueue_head(&this_adm.matrix_map_wait);
|
init_waitqueue_head(&this_adm.matrix_map_wait);
|
||||||
init_waitqueue_head(&this_adm.adm_wait);
|
init_waitqueue_head(&this_adm.adm_wait);
|
||||||
|
|
||||||
|
143
dsp/q6voice.c
143
dsp/q6voice.c
@@ -23,6 +23,7 @@
|
|||||||
#include <ipc/apr_tal.h>
|
#include <ipc/apr_tal.h>
|
||||||
#include "adsp_err.h"
|
#include "adsp_err.h"
|
||||||
#include <dsp/voice_mhi.h>
|
#include <dsp/voice_mhi.h>
|
||||||
|
#include <soc/qcom/secure_buffer.h>
|
||||||
|
|
||||||
#define TIMEOUT_MS 300
|
#define TIMEOUT_MS 300
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ struct cvd_version_table cvd_version_table_mapping[CVD_INT_VERSION_MAX] = {
|
|||||||
|
|
||||||
static struct common_data common;
|
static struct common_data common;
|
||||||
static bool module_initialized;
|
static bool module_initialized;
|
||||||
|
static bool hyp_assigned;
|
||||||
|
|
||||||
static int voice_send_enable_vocproc_cmd(struct voice_data *v);
|
static int voice_send_enable_vocproc_cmd(struct voice_data *v);
|
||||||
static int voice_send_netid_timing_cmd(struct voice_data *v);
|
static int voice_send_netid_timing_cmd(struct voice_data *v);
|
||||||
@@ -1249,6 +1251,9 @@ static int voice_unmap_cal_block(struct voice_data *v, int cal_index)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
struct cal_block_data *cal_block;
|
struct cal_block_data *cal_block;
|
||||||
|
int dest_perms[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
|
||||||
|
int source_vm[2] = {VMID_LPASS, VMID_ADSP_HEAP};
|
||||||
|
int dest_vm[1] = {VMID_HLOS};
|
||||||
|
|
||||||
if (common.cal_data[cal_index] == NULL) {
|
if (common.cal_data[cal_index] == NULL) {
|
||||||
pr_err("%s: Cal type is NULL, index %d!\n",
|
pr_err("%s: Cal type is NULL, index %d!\n",
|
||||||
@@ -1281,6 +1286,27 @@ static int voice_unmap_cal_block(struct voice_data *v, int cal_index)
|
|||||||
pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n",
|
pr_err("%s: Voice_send_mvm_unmap_memory_physical_cmd failed for session 0x%x, err %d!\n",
|
||||||
__func__, v->session_id, result);
|
__func__, v->session_id, result);
|
||||||
|
|
||||||
|
pr_debug("%s: use hyp assigned %d\n",__func__, hyp_assigned);
|
||||||
|
if (cal_block->cma_mem && hyp_assigned) {
|
||||||
|
if (cal_block->cal_data.paddr == 0 ||
|
||||||
|
cal_block->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n", __func__);
|
||||||
|
result = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
result = hyp_assign_phys(cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size,
|
||||||
|
source_vm, 2, dest_vm, dest_perms, 1);
|
||||||
|
if (result < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, result, cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size);
|
||||||
|
result = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
hyp_assigned = false;
|
||||||
|
pr_debug("%s: hyp_assign_phys success\n", __func__);
|
||||||
|
}
|
||||||
cal_block->map_data.q6map_handle = 0;
|
cal_block->map_data.q6map_handle = 0;
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&common.cal_data[cal_index]->lock);
|
mutex_unlock(&common.cal_data[cal_index]->lock);
|
||||||
@@ -1290,12 +1316,16 @@ done:
|
|||||||
|
|
||||||
static int voice_destroy_mvm_cvs_session(struct voice_data *v)
|
static int voice_destroy_mvm_cvs_session(struct voice_data *v)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0, result = 0;
|
||||||
struct mvm_detach_stream_cmd detach_stream;
|
struct mvm_detach_stream_cmd detach_stream;
|
||||||
struct apr_hdr mvm_destroy;
|
struct apr_hdr mvm_destroy;
|
||||||
struct apr_hdr cvs_destroy;
|
struct apr_hdr cvs_destroy;
|
||||||
void *apr_mvm, *apr_cvs;
|
void *apr_mvm, *apr_cvs;
|
||||||
u16 mvm_handle, cvs_handle;
|
u16 mvm_handle, cvs_handle;
|
||||||
|
struct cal_block_data *cal_block;
|
||||||
|
int dest_perms[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
|
||||||
|
int source_vm[2] = {VMID_LPASS, VMID_ADSP_HEAP};
|
||||||
|
int dest_vm[1] = {VMID_HLOS};
|
||||||
|
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
pr_err("%s: v is NULL\n", __func__);
|
pr_err("%s: v is NULL\n", __func__);
|
||||||
@@ -1306,7 +1336,44 @@ static int voice_destroy_mvm_cvs_session(struct voice_data *v)
|
|||||||
|
|
||||||
if (!apr_mvm || !apr_cvs) {
|
if (!apr_mvm || !apr_cvs) {
|
||||||
pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
|
pr_err("%s: apr_mvm or apr_cvs is NULL\n", __func__);
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
|
|
||||||
|
pr_debug("%s: use hyp assigned %d\n",__func__, hyp_assigned);
|
||||||
|
if (hyp_assigned) {
|
||||||
|
mutex_lock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
|
||||||
|
cal_block = cal_utils_get_only_cal_block(
|
||||||
|
common.cal_data[CVP_VOCPROC_CAL]);
|
||||||
|
if (cal_block == NULL) {
|
||||||
|
pr_err("%s: Cal block NULL, CVP_VOCPROC_CAL!\n",
|
||||||
|
__func__);
|
||||||
|
mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (cal_block->cma_mem) {
|
||||||
|
if (cal_block->cal_data.paddr == 0 ||
|
||||||
|
cal_block->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n", __func__);
|
||||||
|
mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
result = hyp_assign_phys(
|
||||||
|
cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size,
|
||||||
|
source_vm, 2, dest_vm, dest_perms, 1);
|
||||||
|
if (result < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, result,
|
||||||
|
cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size);
|
||||||
|
mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
hyp_assigned = false;
|
||||||
|
pr_debug("%s: hyp_assign_phys success\n", __func__);
|
||||||
|
mutex_unlock(&common.cal_data[CVP_VOCPROC_CAL]->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
mvm_handle = voice_get_mvm_handle(v);
|
mvm_handle = voice_get_mvm_handle(v);
|
||||||
cvs_handle = voice_get_cvs_handle(v);
|
cvs_handle = voice_get_cvs_handle(v);
|
||||||
@@ -2689,7 +2756,9 @@ static int voice_get_cal(struct cal_block_data **cal_block,
|
|||||||
int col_data_idx, int session_id)
|
int col_data_idx, int session_id)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int dest_perms[2] = {PERM_READ | PERM_WRITE, PERM_READ | PERM_WRITE};
|
||||||
|
int source_vm[1] = {VMID_HLOS};
|
||||||
|
int dest_vm[2] = {VMID_LPASS, VMID_ADSP_HEAP};
|
||||||
*cal_block = cal_utils_get_only_cal_block(
|
*cal_block = cal_utils_get_only_cal_block(
|
||||||
common.cal_data[cal_block_idx]);
|
common.cal_data[cal_block_idx]);
|
||||||
if (*cal_block == NULL) {
|
if (*cal_block == NULL) {
|
||||||
@@ -2699,6 +2768,28 @@ static int voice_get_cal(struct cal_block_data **cal_block,
|
|||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((*cal_block)->cma_mem) {
|
||||||
|
if ((*cal_block)->cal_data.paddr == 0 ||
|
||||||
|
(*cal_block)->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n", __func__);
|
||||||
|
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
ret = hyp_assign_phys((*cal_block)->cal_data.paddr,
|
||||||
|
(*cal_block)->map_data.map_size,
|
||||||
|
source_vm, 1, dest_vm, dest_perms, 2);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed ret = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, ret, (*cal_block)->cal_data.paddr,
|
||||||
|
(*cal_block)->map_data.map_size);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
hyp_assigned = true;
|
||||||
|
pr_debug("%s: hyp_assign_phys success\n", __func__);
|
||||||
|
}
|
||||||
ret = remap_cal_data(*cal_block, session_id);
|
ret = remap_cal_data(*cal_block, session_id);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("%s: Remap_cal_data failed for cal %d!\n",
|
pr_err("%s: Remap_cal_data failed for cal %d!\n",
|
||||||
@@ -3279,6 +3370,11 @@ static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
|
|||||||
{
|
{
|
||||||
struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
|
struct cvp_deregister_cal_data_cmd cvp_dereg_cal_cmd;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int cal_index = CVP_VOCPROC_CAL;
|
||||||
|
struct cal_block_data *cal_block;
|
||||||
|
int dest_perms[1] = {PERM_READ | PERM_WRITE | PERM_EXEC};
|
||||||
|
int source_vm[2] = {VMID_LPASS, VMID_ADSP_HEAP};
|
||||||
|
int dest_vm[1] = {VMID_HLOS};
|
||||||
|
|
||||||
memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd));
|
memset(&cvp_dereg_cal_cmd, 0, sizeof(cvp_dereg_cal_cmd));
|
||||||
|
|
||||||
@@ -3325,15 +3421,50 @@ static int voice_send_cvp_deregister_cal_cmd(struct voice_data *v)
|
|||||||
pr_err("%s: Command timeout\n", __func__);
|
pr_err("%s: Command timeout\n", __func__);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_lock(&common.cal_data[cal_index]->lock);
|
||||||
|
cal_block = cal_utils_get_only_cal_block(
|
||||||
|
common.cal_data[cal_index]);
|
||||||
|
if (cal_block == NULL) {
|
||||||
|
pr_err("%s: Cal block is NULL, index %d!\n",
|
||||||
|
__func__, cal_index);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
pr_debug("%s: use hyp assigned %d\n",__func__, hyp_assigned);
|
||||||
|
if (cal_block->cma_mem && hyp_assigned) {
|
||||||
|
if (cal_block->cal_data.paddr == 0 ||
|
||||||
|
cal_block->map_data.map_size <= 0) {
|
||||||
|
pr_err("%s: No address to map!\n", __func__);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
}
|
||||||
|
ret = hyp_assign_phys(cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size,
|
||||||
|
source_vm, 2, dest_vm, dest_perms, 1);
|
||||||
|
if (ret < 0) {
|
||||||
|
pr_err("%s: hyp_assign_phys failed result = %d addr = 0x%pK size = %d\n",
|
||||||
|
__func__, ret, cal_block->cal_data.paddr,
|
||||||
|
cal_block->map_data.map_size);
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto unlock;
|
||||||
|
} else {
|
||||||
|
hyp_assigned = false;
|
||||||
|
pr_debug("%s: hyp_assign_phys success\n", __func__);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (v->async_err > 0) {
|
if (v->async_err > 0) {
|
||||||
pr_err("%s: DSP returned error[%s]\n",
|
pr_err("%s: DSP returned error[%s]\n",
|
||||||
__func__, adsp_err_get_err_str(
|
__func__, adsp_err_get_err_str(
|
||||||
v->async_err));
|
v->async_err));
|
||||||
ret = adsp_err_get_lnx_err_code(
|
ret = adsp_err_get_lnx_err_code(
|
||||||
v->async_err);
|
v->async_err);
|
||||||
goto done;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unlock:
|
||||||
|
mutex_unlock(&common.cal_data[cal_index]->lock);
|
||||||
done:
|
done:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -10161,8 +10292,10 @@ int __init voice_init(void)
|
|||||||
if (voice_init_cal_data())
|
if (voice_init_cal_data())
|
||||||
pr_err("%s: Could not init cal data!\n", __func__);
|
pr_err("%s: Could not init cal data!\n", __func__);
|
||||||
|
|
||||||
if (rc == 0)
|
if (rc == 0) {
|
||||||
module_initialized = true;
|
module_initialized = true;
|
||||||
|
hyp_assigned = false;
|
||||||
|
}
|
||||||
|
|
||||||
pr_debug("%s: rc=%d\n", __func__, rc);
|
pr_debug("%s: rc=%d\n", __func__, rc);
|
||||||
return rc;
|
return rc;
|
||||||
|
@@ -30,6 +30,7 @@ struct cal_block_data {
|
|||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct cal_data cal_data;
|
struct cal_data cal_data;
|
||||||
bool cal_stale;
|
bool cal_stale;
|
||||||
|
bool cma_mem;
|
||||||
struct mem_map_data map_data;
|
struct mem_map_data map_data;
|
||||||
int32_t buffer_number;
|
int32_t buffer_number;
|
||||||
};
|
};
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013-2015, 2017-2019, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2013-2015, 2017-2020, The Linux Foundation. All rights reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LINUX_MSM_AUDIO_ION_H
|
#ifndef _LINUX_MSM_AUDIO_ION_H
|
||||||
@@ -22,6 +22,10 @@ int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
|
|||||||
unsigned long *ionflag, size_t bufsz,
|
unsigned long *ionflag, size_t bufsz,
|
||||||
dma_addr_t *paddr, size_t *pa_len, void **vaddr);
|
dma_addr_t *paddr, size_t *pa_len, void **vaddr);
|
||||||
int msm_audio_ion_free(struct dma_buf *dma_buf);
|
int msm_audio_ion_free(struct dma_buf *dma_buf);
|
||||||
|
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 *pa_len, void **vaddr);
|
||||||
|
int msm_audio_ion_free_cma(struct dma_buf *dma_buf);
|
||||||
int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma);
|
int msm_audio_ion_mmap(struct audio_buffer *abuff, struct vm_area_struct *vma);
|
||||||
int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op);
|
int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user