Merge f1a61bc4b5 on remote branch

Change-Id: Ib55ccdefd66a9ee0ec66ded8a10f2a2c07b72a2e
This commit is contained in:
Linux Build Service Account 2020-02-10 00:35:53 -08:00
commit db88d6df81
2 changed files with 80 additions and 67 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -2371,34 +2371,6 @@ static int venus_hfi_core_release(void *dev)
return rc; return rc;
} }
static int __get_q_size(struct venus_hfi_device *dev, unsigned int q_index)
{
struct hfi_queue_header *queue;
struct vidc_iface_q_info *q_info;
u32 write_ptr, read_ptr;
if (q_index >= VIDC_IFACEQ_NUMQ) {
dprintk(VIDC_ERR, "Invalid q index: %d\n", q_index);
return -ENOENT;
}
q_info = &dev->iface_queues[q_index];
if (!q_info) {
dprintk(VIDC_ERR, "cannot read shared Q's\n");
return -ENOENT;
}
queue = (struct hfi_queue_header *)q_info->q_hdr;
if (!queue) {
dprintk(VIDC_ERR, "queue not present\n");
return -ENOENT;
}
write_ptr = (u32)queue->qhdr_write_idx;
read_ptr = (u32)queue->qhdr_read_idx;
return read_ptr - write_ptr;
}
static void __core_clear_interrupt(struct venus_hfi_device *device) static void __core_clear_interrupt(struct venus_hfi_device *device)
{ {
u32 intr_status = 0; u32 intr_status = 0;
@ -3395,9 +3367,11 @@ exit:
return; return;
} }
static void __process_sys_error(struct venus_hfi_device *device) static void print_sfr_message(struct venus_hfi_device *device)
{ {
struct hfi_sfr_struct *vsfr = NULL; struct hfi_sfr_struct *vsfr = NULL;
u32 vsfr_size = 0;
void *p = NULL;
/* Once SYS_ERROR received from HW, it is safe to halt the AXI. /* Once SYS_ERROR received from HW, it is safe to halt the AXI.
* With SYS_ERROR, Venus FW may have crashed and HW might be * With SYS_ERROR, Venus FW may have crashed and HW might be
@ -3408,12 +3382,11 @@ static void __process_sys_error(struct venus_hfi_device *device)
vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr; vsfr = (struct hfi_sfr_struct *)device->sfr.align_virtual_addr;
if (vsfr) { if (vsfr) {
void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize); vsfr_size = vsfr->bufSize - sizeof(u32);
/* SFR isn't guaranteed to be NULL terminated p = memchr(vsfr->rg_data, '\0', vsfr_size);
since SYS_ERROR indicates that Venus is in the /* SFR isn't guaranteed to be NULL terminated */
process of crashing.*/
if (p == NULL) if (p == NULL)
vsfr->rg_data[vsfr->bufSize - 1] = '\0'; vsfr->rg_data[vsfr_size - 1] = '\0';
dprintk(VIDC_ERR, "SFR Message from FW: %s\n", dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
vsfr->rg_data); vsfr->rg_data);
@ -3537,8 +3510,6 @@ static int __response_handler(struct venus_hfi_device *device)
} }
if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) { if (device->intr_status & VIDC_WRAPPER_INTR_CLEAR_A2HWD_BMSK) {
struct hfi_sfr_struct *vsfr = (struct hfi_sfr_struct *)
device->sfr.align_virtual_addr;
struct msm_vidc_cb_info info = { struct msm_vidc_cb_info info = {
.response_type = HAL_SYS_WATCHDOG_TIMEOUT, .response_type = HAL_SYS_WATCHDOG_TIMEOUT,
.response.cmd = { .response.cmd = {
@ -3546,9 +3517,7 @@ static int __response_handler(struct venus_hfi_device *device)
} }
}; };
if (vsfr) print_sfr_message(device);
dprintk(VIDC_ERR, "SFR Message from FW: %s\n",
vsfr->rg_data);
dprintk(VIDC_ERR, "Received watchdog timeout\n"); dprintk(VIDC_ERR, "Received watchdog timeout\n");
packets[packet_count++] = info; packets[packet_count++] = info;
@ -3574,7 +3543,7 @@ static int __response_handler(struct venus_hfi_device *device)
/* Process the packet types that we're interested in */ /* Process the packet types that we're interested in */
switch (info->response_type) { switch (info->response_type) {
case HAL_SYS_ERROR: case HAL_SYS_ERROR:
__process_sys_error(device); print_sfr_message(device);
break; break;
case HAL_SYS_RELEASE_RESOURCE_DONE: case HAL_SYS_RELEASE_RESOURCE_DONE:
dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n"); dprintk(VIDC_DBG, "Received SYS_RELEASE_RESOURCE\n");
@ -3671,8 +3640,7 @@ static int __response_handler(struct venus_hfi_device *device)
*session_id = session->session_id; *session_id = session->session_id;
} }
if (packet_count >= max_packets && if (packet_count >= max_packets) {
__get_q_size(device, VIDC_IFACEQ_MSGQ_IDX)) {
dprintk(VIDC_WARN, dprintk(VIDC_WARN,
"Too many packets in message queue to handle at once, deferring read\n"); "Too many packets in message queue to handle at once, deferring read\n");
break; break;

View file

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. /* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and * it under the terms of the GNU General Public License version 2 and
@ -18,6 +18,7 @@
#include <linux/time.h> #include <linux/time.h>
#include <linux/math64.h> #include <linux/math64.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <sound/core.h> #include <sound/core.h>
@ -107,6 +108,7 @@ struct msm_compr_pdata {
int32_t ion_fd[MSM_FRONTEND_DAI_MAX]; int32_t ion_fd[MSM_FRONTEND_DAI_MAX];
bool is_in_use[MSM_FRONTEND_DAI_MAX]; bool is_in_use[MSM_FRONTEND_DAI_MAX];
bool avs_ver; bool avs_ver;
struct mutex lock;
}; };
struct msm_compr_audio { struct msm_compr_audio {
@ -1851,6 +1853,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream)
} }
spin_unlock_irqrestore(&prtd->lock, flags); spin_unlock_irqrestore(&prtd->lock, flags);
mutex_lock(&pdata->lock);
pdata->cstream[soc_prtd->dai_link->be_id] = NULL; pdata->cstream[soc_prtd->dai_link->be_id] = NULL;
if (cstream->direction == SND_COMPRESS_PLAYBACK) { if (cstream->direction == SND_COMPRESS_PLAYBACK) {
msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
@ -1880,6 +1883,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream)
pdata->is_in_use[soc_prtd->dai_link->be_id] = false; pdata->is_in_use[soc_prtd->dai_link->be_id] = false;
kfree(prtd); kfree(prtd);
runtime->private_data = NULL; runtime->private_data = NULL;
mutex_unlock(&pdata->lock);
return 0; return 0;
} }
@ -1930,6 +1934,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream)
} }
spin_unlock_irqrestore(&prtd->lock, flags); spin_unlock_irqrestore(&prtd->lock, flags);
mutex_lock(&pdata->lock);
pdata->cstream[soc_prtd->dai_link->be_id] = NULL; pdata->cstream[soc_prtd->dai_link->be_id] = NULL;
msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id, msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->be_id,
SNDRV_PCM_STREAM_CAPTURE); SNDRV_PCM_STREAM_CAPTURE);
@ -1940,6 +1945,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream)
kfree(prtd); kfree(prtd);
runtime->private_data = NULL; runtime->private_data = NULL;
mutex_unlock(&pdata->lock);
return 0; return 0;
} }
@ -3228,6 +3234,7 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
struct msm_compr_audio *prtd = NULL; struct msm_compr_audio *prtd = NULL;
long *values = &(ucontrol->value.integer.value[0]); long *values = &(ucontrol->value.integer.value[0]);
int effects_module; int effects_module;
int ret = 0;
pr_debug("%s\n", __func__); pr_debug("%s\n", __func__);
if (fe_id >= MSM_FRONTEND_DAI_MAX) { if (fe_id >= MSM_FRONTEND_DAI_MAX) {
@ -3235,16 +3242,19 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
__func__, fe_id); __func__, fe_id);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&pdata->lock);
cstream = pdata->cstream[fe_id]; cstream = pdata->cstream[fe_id];
audio_effects = pdata->audio_effects[fe_id]; audio_effects = pdata->audio_effects[fe_id];
if (!cstream || !audio_effects) { if (!cstream || !audio_effects) {
pr_err("%s: stream or effects inactive\n", __func__); pr_err("%s: stream or effects inactive\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
prtd = cstream->runtime->private_data; prtd = cstream->runtime->private_data;
if (!prtd) { if (!prtd) {
pr_err("%s: cannot set audio effects\n", __func__); pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
if (prtd->compr_passthr != LEGACY_PCM) { if (prtd->compr_passthr != LEGACY_PCM) {
pr_debug("%s: No effects for compr_type[%d]\n", pr_debug("%s: No effects for compr_type[%d]\n",
@ -3310,9 +3320,11 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
break; break;
default: default:
pr_err("%s Invalid effects config module\n", __func__); pr_err("%s Invalid effects config module\n", __func__);
return -EINVAL; ret = -EINVAL;
} }
return 0; done:
mutex_unlock(&pdata->lock);
return ret;
} }
static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol, static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
@ -3325,6 +3337,7 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
struct msm_compr_audio_effects *audio_effects = NULL; struct msm_compr_audio_effects *audio_effects = NULL;
struct snd_compr_stream *cstream = NULL; struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd = NULL; struct msm_compr_audio *prtd = NULL;
int ret = 0;
pr_debug("%s\n", __func__); pr_debug("%s\n", __func__);
if (fe_id >= MSM_FRONTEND_DAI_MAX) { if (fe_id >= MSM_FRONTEND_DAI_MAX) {
@ -3332,19 +3345,23 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
__func__, fe_id); __func__, fe_id);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&pdata->lock);
cstream = pdata->cstream[fe_id]; cstream = pdata->cstream[fe_id];
audio_effects = pdata->audio_effects[fe_id]; audio_effects = pdata->audio_effects[fe_id];
if (!cstream || !audio_effects) { if (!cstream || !audio_effects) {
pr_err("%s: stream or effects inactive\n", __func__); pr_err("%s: stream or effects inactive\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
prtd = cstream->runtime->private_data; prtd = cstream->runtime->private_data;
if (!prtd) { if (!prtd) {
pr_err("%s: cannot set audio effects\n", __func__); pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
done:
return 0; mutex_unlock(&pdata->lock);
return ret;
} }
static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol, static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
@ -3357,6 +3374,7 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
struct msm_compr_audio_effects *audio_effects = NULL; struct msm_compr_audio_effects *audio_effects = NULL;
struct snd_compr_stream *cstream = NULL; struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd = NULL; struct msm_compr_audio *prtd = NULL;
int ret = 0;
long *values = &(ucontrol->value.integer.value[0]); long *values = &(ucontrol->value.integer.value[0]);
if (fe_id >= MSM_FRONTEND_DAI_MAX) { if (fe_id >= MSM_FRONTEND_DAI_MAX) {
@ -3364,28 +3382,34 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
__func__, fe_id); __func__, fe_id);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&pdata->lock);
cstream = pdata->cstream[fe_id]; cstream = pdata->cstream[fe_id];
audio_effects = pdata->audio_effects[fe_id]; audio_effects = pdata->audio_effects[fe_id];
if (!cstream || !audio_effects) { if (!cstream || !audio_effects) {
pr_err("%s: stream or effects inactive\n", __func__); pr_err("%s: stream or effects inactive\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
prtd = cstream->runtime->private_data; prtd = cstream->runtime->private_data;
if (!prtd) { if (!prtd) {
pr_err("%s: cannot set audio effects\n", __func__); pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
if (prtd->compr_passthr != LEGACY_PCM) { if (prtd->compr_passthr != LEGACY_PCM) {
pr_err("%s: No effects for compr_type[%d]\n", pr_err("%s: No effects for compr_type[%d]\n",
__func__, prtd->compr_passthr); __func__, prtd->compr_passthr);
return -EPERM; ret = -EPERM;
goto done;
} }
audio_effects->query.mod_id = (u32)*values++; audio_effects->query.mod_id = (u32)*values++;
audio_effects->query.parm_id = (u32)*values++; audio_effects->query.parm_id = (u32)*values++;
audio_effects->query.size = (u32)*values++; audio_effects->query.size = (u32)*values++;
audio_effects->query.offset = (u32)*values++; audio_effects->query.offset = (u32)*values++;
audio_effects->query.device = (u32)*values++; audio_effects->query.device = (u32)*values++;
return 0; done:
mutex_unlock(&pdata->lock);
return ret;
} }
static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol, static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
@ -3398,6 +3422,7 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
struct msm_compr_audio_effects *audio_effects = NULL; struct msm_compr_audio_effects *audio_effects = NULL;
struct snd_compr_stream *cstream = NULL; struct snd_compr_stream *cstream = NULL;
struct msm_compr_audio *prtd = NULL; struct msm_compr_audio *prtd = NULL;
int ret = 0;
long *values = &(ucontrol->value.integer.value[0]); long *values = &(ucontrol->value.integer.value[0]);
if (fe_id >= MSM_FRONTEND_DAI_MAX) { if (fe_id >= MSM_FRONTEND_DAI_MAX) {
@ -3405,23 +3430,28 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
__func__, fe_id); __func__, fe_id);
return -EINVAL; return -EINVAL;
} }
mutex_lock(&pdata->lock);
cstream = pdata->cstream[fe_id]; cstream = pdata->cstream[fe_id];
audio_effects = pdata->audio_effects[fe_id]; audio_effects = pdata->audio_effects[fe_id];
if (!cstream || !audio_effects) { if (!cstream || !audio_effects) {
pr_debug("%s: stream or effects inactive\n", __func__); pr_debug("%s: stream or effects inactive\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
prtd = cstream->runtime->private_data; prtd = cstream->runtime->private_data;
if (!prtd) { if (!prtd) {
pr_err("%s: cannot set audio effects\n", __func__); pr_err("%s: cannot set audio effects\n", __func__);
return -EINVAL; ret = -EINVAL;
goto done;
} }
values[0] = (long)audio_effects->query.mod_id; values[0] = (long)audio_effects->query.mod_id;
values[1] = (long)audio_effects->query.parm_id; values[1] = (long)audio_effects->query.parm_id;
values[2] = (long)audio_effects->query.size; values[2] = (long)audio_effects->query.size;
values[3] = (long)audio_effects->query.offset; values[3] = (long)audio_effects->query.offset;
values[4] = (long)audio_effects->query.device; values[4] = (long)audio_effects->query.device;
return 0; done:
mutex_unlock(&pdata->lock);
return ret;
} }
static int msm_compr_send_dec_params(struct snd_compr_stream *cstream, static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
@ -3489,8 +3519,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
if (fe_id >= MSM_FRONTEND_DAI_MAX) { if (fe_id >= MSM_FRONTEND_DAI_MAX) {
pr_err("%s Received out of bounds fe_id %lu\n", pr_err("%s Received out of bounds fe_id %lu\n",
__func__, fe_id); __func__, fe_id);
rc = -EINVAL; return -EINVAL;
goto end;
} }
cstream = pdata->cstream[fe_id]; cstream = pdata->cstream[fe_id];
@ -3498,16 +3527,15 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
if (!cstream || !dec_params) { if (!cstream || !dec_params) {
pr_err("%s: stream or dec_params inactive\n", __func__); pr_err("%s: stream or dec_params inactive\n", __func__);
rc = -EINVAL; return -EINVAL;
goto end;
} }
prtd = cstream->runtime->private_data; prtd = cstream->runtime->private_data;
if (!prtd) { if (!prtd) {
pr_err("%s: cannot set dec_params\n", __func__); pr_err("%s: cannot set dec_params\n", __func__);
rc = -EINVAL; return -EINVAL;
goto end;
} }
mutex_lock(&pdata->lock);
switch (prtd->codec) { switch (prtd->codec) {
case FORMAT_MP3: case FORMAT_MP3:
case FORMAT_MPEG4_AAC: case FORMAT_MPEG4_AAC:
@ -3556,6 +3584,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
} }
end: end:
pr_debug("%s: ret %d\n", __func__, rc); pr_debug("%s: ret %d\n", __func__, rc);
mutex_unlock(&pdata->lock);
return rc; return rc;
} }
@ -4093,6 +4122,7 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
if (!pdata) if (!pdata)
return -ENOMEM; return -ENOMEM;
mutex_init(&pdata->lock);
snd_soc_platform_set_drvdata(platform, pdata); snd_soc_platform_set_drvdata(platform, pdata);
for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) { for (i = 0; i < MSM_FRONTEND_DAI_MAX; i++) {
@ -4138,6 +4168,20 @@ static int msm_compr_probe(struct snd_soc_platform *platform)
return 0; return 0;
} }
static int msm_compr_remove(struct snd_soc_platform *platform)
{
struct msm_compr_pdata *pdata = (struct msm_compr_pdata *)
snd_soc_platform_get_drvdata(platform);
if (!pdata) {
pr_err("%s pdata is null\n", __func__);
return -ENOMEM;
}
mutex_destroy(&pdata->lock);
kfree(pdata);
return 0;
}
static int msm_compr_volume_info(struct snd_kcontrol *kcontrol, static int msm_compr_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
@ -4900,6 +4944,7 @@ static struct snd_soc_platform_driver msm_soc_platform = {
.probe = msm_compr_probe, .probe = msm_compr_probe,
.compr_ops = &msm_compr_ops, .compr_ops = &msm_compr_ops,
.pcm_new = msm_compr_new, .pcm_new = msm_compr_new,
.remove = msm_compr_remove,
}; };
static int msm_compr_dev_probe(struct platform_device *pdev) static int msm_compr_dev_probe(struct platform_device *pdev)
@ -4910,7 +4955,7 @@ static int msm_compr_dev_probe(struct platform_device *pdev)
&msm_soc_platform); &msm_soc_platform);
} }
static int msm_compr_remove(struct platform_device *pdev) static int msm_compr_dev_remove(struct platform_device *pdev)
{ {
snd_soc_unregister_platform(&pdev->dev); snd_soc_unregister_platform(&pdev->dev);
return 0; return 0;
@ -4929,7 +4974,7 @@ static struct platform_driver msm_compr_driver = {
.of_match_table = msm_compr_dt_match, .of_match_table = msm_compr_dt_match,
}, },
.probe = msm_compr_dev_probe, .probe = msm_compr_dev_probe,
.remove = msm_compr_remove, .remove = msm_compr_dev_remove,
}; };
static int __init msm_soc_platform_init(void) static int __init msm_soc_platform_init(void)