Commit e6937b6d authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: SOF: small fixes for 5.10" from Kai Vehmanen <kai.vehmanen@linux.intel.com>:

Series that adds debug support for IMX platforms, more details to
FW version information, adds missing -EACCESS handling to
pm_runtime_get_sync() calls and a set of minor cosmetic, trace
verbosity and coding style issues.

Guennadi Liakhovetski (3):
  ASoC: SOF: (cosmetic) remove redundant "ret" variable uses
  ASoC: SOF: remove several superfluous type-casts
  ASoC: SOF: fix range checks

Iulian Olaru (1):
  ASoC: SOF: imx: Add debug support for imx platforms

Karol Trzcinski (1):
  ASoC: SOF: Add `src_hash` to `sof_ipc_fw_version` structure

Pierre-Louis Bossart (3):
  ASoC: SOF: debug: update test for pm_runtime_get_sync()
  ASoC: SOF: control: update test for pm_runtime_get_sync()
  ASoC: SOF: Intel: hda: reduce verbosity of boot error logs

 include/sound/sof/info.h         |  4 +-
 sound/soc/sof/control.c          | 62 +++++++++++++--------------
 sound/soc/sof/debug.c            |  2 +-
 sound/soc/sof/imx/Kconfig        |  8 ++++
 sound/soc/sof/imx/Makefile       |  3 ++
 sound/soc/sof/imx/imx-common.c   | 72 ++++++++++++++++++++++++++++++++
 sound/soc/sof/imx/imx-common.h   | 16 +++++++
 sound/soc/sof/imx/imx8.c         | 23 +++++++++-
 sound/soc/sof/imx/imx8m.c        | 17 +++++++-
 sound/soc/sof/intel/hda-loader.c | 16 +++----
 sound/soc/sof/intel/hda.c        | 12 ++++--
 sound/soc/sof/intel/hda.h        |  2 +
 sound/soc/sof/sof-audio.c        |  6 +--
 sound/soc/sof/sof-priv.h         |  8 ++++
 sound/soc/sof/topology.c         | 44 ++++++++++---------
 15 files changed, 226 insertions(+), 69 deletions(-)
 create mode 100644 sound/soc/sof/imx/imx-common.c
 create mode 100644 sound/soc/sof/imx/imx-common.h

--
2.27.0
parents 4c3021f0 776100a4
...@@ -46,9 +46,11 @@ struct sof_ipc_fw_version { ...@@ -46,9 +46,11 @@ struct sof_ipc_fw_version {
uint8_t time[10]; uint8_t time[10];
uint8_t tag[6]; uint8_t tag[6];
uint32_t abi_version; uint32_t abi_version;
/* used to check FW and ldc file compatibility, reproducible value */
uint32_t src_hash;
/* reserved for future use */ /* reserved for future use */
uint32_t reserved[4]; uint32_t reserved[3];
} __packed; } __packed;
/* FW ready Message - sent by firmware when boot has completed */ /* FW ready Message - sent by firmware when boot has completed */
......
...@@ -221,7 +221,6 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, ...@@ -221,7 +221,6 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
struct sof_ipc_ctrl_data *cdata = scontrol->control_data; struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
struct sof_abi_hdr *data = cdata->data; struct sof_abi_hdr *data = cdata->data;
size_t size; size_t size;
int ret = 0;
if (be->max > sizeof(ucontrol->value.bytes.data)) { if (be->max > sizeof(ucontrol->value.bytes.data)) {
dev_err_ratelimited(scomp->dev, dev_err_ratelimited(scomp->dev,
...@@ -230,20 +229,20 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol, ...@@ -230,20 +229,20 @@ int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
return -EINVAL; return -EINVAL;
} }
size = data->size + sizeof(*data); /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
if (size > be->max) { if (data->size > be->max - sizeof(*data)) {
dev_err_ratelimited(scomp->dev, dev_err_ratelimited(scomp->dev,
"error: DSP sent %zu bytes max is %d\n", "error: %u bytes of control data is invalid, max is %zu\n",
size, be->max); data->size, be->max - sizeof(*data));
ret = -EINVAL; return -EINVAL;
goto out;
} }
size = data->size + sizeof(*data);
/* copy back to kcontrol */ /* copy back to kcontrol */
memcpy(ucontrol->value.bytes.data, data, size); memcpy(ucontrol->value.bytes.data, data, size);
out: return 0;
return ret;
} }
int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
...@@ -255,7 +254,7 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, ...@@ -255,7 +254,7 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
struct snd_soc_component *scomp = scontrol->scomp; struct snd_soc_component *scomp = scontrol->scomp;
struct sof_ipc_ctrl_data *cdata = scontrol->control_data; struct sof_ipc_ctrl_data *cdata = scontrol->control_data;
struct sof_abi_hdr *data = cdata->data; struct sof_abi_hdr *data = cdata->data;
size_t size = data->size + sizeof(*data); size_t size;
if (be->max > sizeof(ucontrol->value.bytes.data)) { if (be->max > sizeof(ucontrol->value.bytes.data)) {
dev_err_ratelimited(scomp->dev, dev_err_ratelimited(scomp->dev,
...@@ -264,13 +263,16 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol, ...@@ -264,13 +263,16 @@ int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
return -EINVAL; return -EINVAL;
} }
if (size > be->max) { /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
if (data->size > be->max - sizeof(*data)) {
dev_err_ratelimited(scomp->dev, dev_err_ratelimited(scomp->dev,
"error: size too big %zu bytes max is %d\n", "error: data size too big %u bytes max is %zu\n",
size, be->max); data->size, be->max - sizeof(*data));
return -EINVAL; return -EINVAL;
} }
size = data->size + sizeof(*data);
/* copy from kcontrol */ /* copy from kcontrol */
memcpy(data, ucontrol->value.bytes.data, size); memcpy(data, ucontrol->value.bytes.data, size);
...@@ -337,7 +339,8 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol, ...@@ -337,7 +339,8 @@ int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
return -EINVAL; return -EINVAL;
} }
if (cdata->data->size + sizeof(const struct sof_abi_hdr) > be->max) { /* be->max has been verified to be >= sizeof(struct sof_abi_hdr) */
if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) {
dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n"); dev_err_ratelimited(scomp->dev, "error: Mismatch in ABI data size (truncated?).\n");
return -EINVAL; return -EINVAL;
} }
...@@ -367,7 +370,7 @@ int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int _ ...@@ -367,7 +370,7 @@ int snd_sof_bytes_ext_volatile_get(struct snd_kcontrol *kcontrol, unsigned int _
int err; int err;
ret = pm_runtime_get_sync(scomp->dev); ret = pm_runtime_get_sync(scomp->dev);
if (ret < 0) { if (ret < 0 && ret != -EACCES) {
dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret); dev_err_ratelimited(scomp->dev, "error: bytes_ext get failed to resume %d\n", ret);
pm_runtime_put_noidle(scomp->dev); pm_runtime_put_noidle(scomp->dev);
return ret; return ret;
...@@ -423,8 +426,7 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, ...@@ -423,8 +426,7 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_tlv header; struct snd_ctl_tlv header;
struct snd_ctl_tlv __user *tlvd = struct snd_ctl_tlv __user *tlvd =
(struct snd_ctl_tlv __user *)binary_data; (struct snd_ctl_tlv __user *)binary_data;
int data_size; size_t data_size;
int ret = 0;
/* /*
* Decrement the limit by ext bytes header size to * Decrement the limit by ext bytes header size to
...@@ -436,27 +438,23 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol, ...@@ -436,27 +438,23 @@ int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
cdata->data->magic = SOF_ABI_MAGIC; cdata->data->magic = SOF_ABI_MAGIC;
cdata->data->abi = SOF_ABI_VERSION; cdata->data->abi = SOF_ABI_VERSION;
/* Prevent read of other kernel data or possibly corrupt response */
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
/* check data size doesn't exceed max coming from topology */ /* check data size doesn't exceed max coming from topology */
if (data_size > be->max) { if (cdata->data->size > be->max - sizeof(const struct sof_abi_hdr)) {
dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %d.\n", dev_err_ratelimited(scomp->dev, "error: user data size %d exceeds max size %zu.\n",
data_size, be->max); cdata->data->size,
ret = -EINVAL; be->max - sizeof(const struct sof_abi_hdr));
goto out; return -EINVAL;
} }
data_size = cdata->data->size + sizeof(const struct sof_abi_hdr);
header.numid = scontrol->cmd; header.numid = scontrol->cmd;
header.length = data_size; header.length = data_size;
if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv))) { if (copy_to_user(tlvd, &header, sizeof(const struct snd_ctl_tlv)))
ret = -EFAULT; return -EFAULT;
goto out;
}
if (copy_to_user(tlvd->tlv, cdata->data, data_size)) if (copy_to_user(tlvd->tlv, cdata->data, data_size))
ret = -EFAULT; return -EFAULT;
out: return 0;
return ret;
} }
...@@ -405,7 +405,7 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer, ...@@ -405,7 +405,7 @@ static ssize_t sof_dfsentry_write(struct file *file, const char __user *buffer,
} }
ret = pm_runtime_get_sync(sdev->dev); ret = pm_runtime_get_sync(sdev->dev);
if (ret < 0) { if (ret < 0 && ret != -EACCES) {
dev_err_ratelimited(sdev->dev, dev_err_ratelimited(sdev->dev,
"error: debugfs write failed to resume %d\n", "error: debugfs write failed to resume %d\n",
ret); ret);
......
...@@ -19,6 +19,12 @@ config SND_SOC_SOF_IMX_OF ...@@ -19,6 +19,12 @@ config SND_SOC_SOF_IMX_OF
This option is not user-selectable but automagically handled by This option is not user-selectable but automagically handled by
'select' statements at a higher level 'select' statements at a higher level
config SND_SOC_SOF_IMX_COMMON
tristate
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level.
config SND_SOC_SOF_IMX8_SUPPORT config SND_SOC_SOF_IMX8_SUPPORT
bool "SOF support for i.MX8" bool "SOF support for i.MX8"
depends on IMX_SCU=y || IMX_SCU=SND_SOC_SOF_IMX_OF depends on IMX_SCU=y || IMX_SCU=SND_SOC_SOF_IMX_OF
...@@ -30,6 +36,7 @@ config SND_SOC_SOF_IMX8_SUPPORT ...@@ -30,6 +36,7 @@ config SND_SOC_SOF_IMX8_SUPPORT
config SND_SOC_SOF_IMX8 config SND_SOC_SOF_IMX8
tristate tristate
select SND_SOC_SOF_IMX_COMMON
select SND_SOC_SOF_XTENSA select SND_SOC_SOF_XTENSA
help help
This option is not user-selectable but automagically handled by This option is not user-selectable but automagically handled by
...@@ -45,6 +52,7 @@ config SND_SOC_SOF_IMX8M_SUPPORT ...@@ -45,6 +52,7 @@ config SND_SOC_SOF_IMX8M_SUPPORT
config SND_SOC_SOF_IMX8M config SND_SOC_SOF_IMX8M
tristate tristate
select SND_SOC_SOF_IMX_COMMON
select SND_SOC_SOF_XTENSA select SND_SOC_SOF_XTENSA
help help
This option is not user-selectable but automagically handled by This option is not user-selectable but automagically handled by
......
...@@ -2,5 +2,8 @@ ...@@ -2,5 +2,8 @@
snd-sof-imx8-objs := imx8.o snd-sof-imx8-objs := imx8.o
snd-sof-imx8m-objs := imx8m.o snd-sof-imx8m-objs := imx8m.o
snd-sof-imx-common-objs := imx-common.o
obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o obj-$(CONFIG_SND_SOC_SOF_IMX8M) += snd-sof-imx8m.o
obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
//
// Copyright 2020 NXP
//
// Common helpers for the audio DSP on i.MX8
#include <sound/sof/xtensa.h>
#include "../ops.h"
#include "imx-common.h"
/**
* imx8_get_registers() - This function is called in case of DSP oops
* in order to gather information about the registers, filename and
* linenumber and stack.
* @sdev: SOF device
* @xoops: Stores information about registers.
* @panic_info: Stores information about filename and line number.
* @stack: Stores the stack dump.
* @stack_words: Size of the stack dump.
*/
void imx8_get_registers(struct snd_sof_dev *sdev,
struct sof_ipc_dsp_oops_xtensa *xoops,
struct sof_ipc_panic_info *panic_info,
u32 *stack, size_t stack_words)
{
u32 offset = sdev->dsp_oops_offset;
/* first read registers */
sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
/* then get panic info */
if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
xoops->arch_hdr.totalsize);
return;
}
offset += xoops->arch_hdr.totalsize;
sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
/* then get the stack */
offset += sizeof(*panic_info);
sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
}
/**
* imx8_dump() - This function is called when a panic message is
* received from the firmware.
*/
void imx8_dump(struct snd_sof_dev *sdev, u32 flags)
{
struct sof_ipc_dsp_oops_xtensa xoops;
struct sof_ipc_panic_info panic_info;
u32 stack[IMX8_STACK_DUMP_SIZE];
u32 status;
/* Get information about the panic status from the debug box area.
* Compute the trace point based on the status.
*/
sof_mailbox_read(sdev, sdev->debug_box.offset + 0x4, &status, 4);
/* Get information about the registers, the filename and line
* number and the stack.
*/
imx8_get_registers(sdev, &xoops, &panic_info, stack,
IMX8_STACK_DUMP_SIZE);
/* Print the information to the console */
snd_sof_get_status(sdev, status, status, &xoops, &panic_info, stack,
IMX8_STACK_DUMP_SIZE);
}
EXPORT_SYMBOL(imx8_dump);
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
#ifndef __IMX_COMMON_H__
#define __IMX_COMMON_H__
#define EXCEPT_MAX_HDR_SIZE 0x400
#define IMX8_STACK_DUMP_SIZE 32
void imx8_get_registers(struct snd_sof_dev *sdev,
struct sof_ipc_dsp_oops_xtensa *xoops,
struct sof_ipc_panic_info *panic_info,
u32 *stack, size_t stack_words);
void imx8_dump(struct snd_sof_dev *sdev, u32 flags);
#endif
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <linux/firmware/imx/svc/misc.h> #include <linux/firmware/imx/svc/misc.h>
#include <dt-bindings/firmware/imx/rsrc.h> #include <dt-bindings/firmware/imx/rsrc.h>
#include "../ops.h" #include "../ops.h"
#include "imx-common.h"
/* DSP memories */ /* DSP memories */
#define IRAM_OFFSET 0x10000 #define IRAM_OFFSET 0x10000
...@@ -115,8 +116,16 @@ static void imx8_dsp_handle_reply(struct imx_dsp_ipc *ipc) ...@@ -115,8 +116,16 @@ static void imx8_dsp_handle_reply(struct imx_dsp_ipc *ipc)
static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc) static void imx8_dsp_handle_request(struct imx_dsp_ipc *ipc)
{ {
struct imx8_priv *priv = imx_dsp_get_data(ipc); struct imx8_priv *priv = imx_dsp_get_data(ipc);
u32 p; /* panic code */
snd_sof_ipc_msgs_rx(priv->sdev); /* Read the message from the debug box. */
sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p));
/* Check to see if the message is a panic code (0x0dead***) */
if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC)
snd_sof_dsp_panic(priv->sdev, p);
else
snd_sof_ipc_msgs_rx(priv->sdev);
} }
static struct imx_dsp_ops dsp_ops = { static struct imx_dsp_ops dsp_ops = {
...@@ -409,6 +418,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = { ...@@ -409,6 +418,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = {
.block_read = sof_block_read, .block_read = sof_block_read,
.block_write = sof_block_write, .block_write = sof_block_write,
/* Module IO */
.read64 = sof_io_read64,
/* ipc */ /* ipc */
.send_msg = imx8_send_msg, .send_msg = imx8_send_msg,
.fw_ready = sof_fw_ready, .fw_ready = sof_fw_ready,
...@@ -424,6 +436,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = { ...@@ -424,6 +436,9 @@ struct snd_sof_dsp_ops sof_imx8_ops = {
/* firmware loading */ /* firmware loading */
.load_firmware = snd_sof_load_firmware_memcpy, .load_firmware = snd_sof_load_firmware_memcpy,
/* Debug information */
.dbg_dump = imx8_dump,
/* Firmware ops */ /* Firmware ops */
.arch_ops = &sof_xtensa_arch_ops, .arch_ops = &sof_xtensa_arch_ops,
...@@ -452,6 +467,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { ...@@ -452,6 +467,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = {
.block_read = sof_block_read, .block_read = sof_block_read,
.block_write = sof_block_write, .block_write = sof_block_write,
/* Module IO */
.read64 = sof_io_read64,
/* ipc */ /* ipc */
.send_msg = imx8_send_msg, .send_msg = imx8_send_msg,
.fw_ready = sof_fw_ready, .fw_ready = sof_fw_ready,
...@@ -467,6 +485,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = { ...@@ -467,6 +485,9 @@ struct snd_sof_dsp_ops sof_imx8x_ops = {
/* firmware loading */ /* firmware loading */
.load_firmware = snd_sof_load_firmware_memcpy, .load_firmware = snd_sof_load_firmware_memcpy,
/* Debug information */
.dbg_dump = imx8_dump,
/* Firmware ops */ /* Firmware ops */
.arch_ops = &sof_xtensa_arch_ops, .arch_ops = &sof_xtensa_arch_ops,
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/firmware/imx/dsp.h> #include <linux/firmware/imx/dsp.h>
#include "../ops.h" #include "../ops.h"
#include "imx-common.h"
#define MBOX_OFFSET 0x800000 #define MBOX_OFFSET 0x800000
#define MBOX_SIZE 0x1000 #define MBOX_SIZE 0x1000
...@@ -88,8 +89,16 @@ static void imx8m_dsp_handle_reply(struct imx_dsp_ipc *ipc) ...@@ -88,8 +89,16 @@ static void imx8m_dsp_handle_reply(struct imx_dsp_ipc *ipc)
static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc) static void imx8m_dsp_handle_request(struct imx_dsp_ipc *ipc)
{ {
struct imx8m_priv *priv = imx_dsp_get_data(ipc); struct imx8m_priv *priv = imx_dsp_get_data(ipc);
u32 p; /* Panic code */
snd_sof_ipc_msgs_rx(priv->sdev); /* Read the message from the debug box. */
sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p));
/* Check to see if the message is a panic code (0x0dead***) */
if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC)
snd_sof_dsp_panic(priv->sdev, p);
else
snd_sof_ipc_msgs_rx(priv->sdev);
} }
static struct imx_dsp_ops imx8m_dsp_ops = { static struct imx_dsp_ops imx8m_dsp_ops = {
...@@ -262,6 +271,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { ...@@ -262,6 +271,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = {
.block_read = sof_block_read, .block_read = sof_block_read,
.block_write = sof_block_write, .block_write = sof_block_write,
/* Module IO */
.read64 = sof_io_read64,
/* ipc */ /* ipc */
.send_msg = imx8m_send_msg, .send_msg = imx8m_send_msg,
.fw_ready = sof_fw_ready, .fw_ready = sof_fw_ready,
...@@ -277,6 +289,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = { ...@@ -277,6 +289,9 @@ struct snd_sof_dsp_ops sof_imx8m_ops = {
/* firmware loading */ /* firmware loading */
.load_firmware = snd_sof_load_firmware_memcpy, .load_firmware = snd_sof_load_firmware_memcpy,
/* Debug information */
.dbg_dump = imx8_dump,
/* Firmware ops */ /* Firmware ops */
.arch_ops = &sof_xtensa_arch_ops, .arch_ops = &sof_xtensa_arch_ops,
......
...@@ -82,7 +82,7 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig ...@@ -82,7 +82,7 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig
* status on core 1, so power up core 1 also momentarily, keep it in * status on core 1, so power up core 1 also momentarily, keep it in
* reset/stall and then turn it off * reset/stall and then turn it off
*/ */
static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration) static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
const struct sof_intel_dsp_desc *chip = hda->desc; const struct sof_intel_dsp_desc *chip = hda->desc;
...@@ -93,7 +93,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration) ...@@ -93,7 +93,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
/* step 1: power up corex */ /* step 1: power up corex */
ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask); ret = hda_dsp_core_power_up(sdev, chip->host_managed_cores_mask);
if (ret < 0) { if (ret < 0) {
if (iteration == HDA_FW_BOOT_ATTEMPTS) if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n"); dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n");
goto err; goto err;
} }
...@@ -116,7 +116,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration) ...@@ -116,7 +116,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
/* step 3: unset core 0 reset state & unstall/run core 0 */ /* step 3: unset core 0 reset state & unstall/run core 0 */
ret = hda_dsp_core_run(sdev, BIT(0)); ret = hda_dsp_core_run(sdev, BIT(0));
if (ret < 0) { if (ret < 0) {
if (iteration == HDA_FW_BOOT_ATTEMPTS) if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
dev_err(sdev->dev, dev_err(sdev->dev,
"error: dsp core start failed %d\n", ret); "error: dsp core start failed %d\n", ret);
ret = -EIO; ret = -EIO;
...@@ -132,7 +132,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration) ...@@ -132,7 +132,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
HDA_DSP_INIT_TIMEOUT_US); HDA_DSP_INIT_TIMEOUT_US);
if (ret < 0) { if (ret < 0) {
if (iteration == HDA_FW_BOOT_ATTEMPTS) if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
dev_err(sdev->dev, dev_err(sdev->dev,
"error: %s: timeout for HIPCIE done\n", "error: %s: timeout for HIPCIE done\n",
__func__); __func__);
...@@ -148,7 +148,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration) ...@@ -148,7 +148,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
/* step 5: power down corex */ /* step 5: power down corex */
ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & ~(BIT(0))); ret = hda_dsp_core_power_down(sdev, chip->host_managed_cores_mask & ~(BIT(0)));
if (ret < 0) { if (ret < 0) {
if (iteration == HDA_FW_BOOT_ATTEMPTS) if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
dev_err(sdev->dev, dev_err(sdev->dev,
"error: dsp core x power down failed\n"); "error: dsp core x power down failed\n");
goto err; goto err;
...@@ -168,7 +168,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration) ...@@ -168,7 +168,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag, int iteration)
if (!ret) if (!ret)
return 0; return 0;
if (iteration == HDA_FW_BOOT_ATTEMPTS) if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
dev_err(sdev->dev, dev_err(sdev->dev,
"error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n", "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n",
__func__); __func__);
...@@ -328,6 +328,7 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev) ...@@ -328,6 +328,7 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct snd_sof_pdata *plat_data = sdev->pdata; struct snd_sof_pdata *plat_data = sdev->pdata;
const struct sof_dev_desc *desc = plat_data->desc; const struct sof_dev_desc *desc = plat_data->desc;
const struct sof_intel_dsp_desc *chip_info; const struct sof_intel_dsp_desc *chip_info;
...@@ -364,7 +365,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev) ...@@ -364,7 +365,8 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
dev_dbg(sdev->dev, dev_dbg(sdev->dev,
"Attempting iteration %d of Core En/ROM load...\n", i); "Attempting iteration %d of Core En/ROM load...\n", i);
ret = cl_dsp_init(sdev, stream->hstream.stream_tag, i + 1); hda->boot_iteration = i + 1;
ret = cl_dsp_init(sdev, stream->hstream.stream_tag);
/* don't retry anymore if successful */ /* don't retry anymore if successful */
if (!ret) if (!ret)
......
...@@ -418,6 +418,7 @@ void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags) ...@@ -418,6 +418,7 @@ void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags)
/* dump the first 8 dwords representing the extended ROM status */ /* dump the first 8 dwords representing the extended ROM status */
static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev) static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
char msg[128]; char msg[128];
int len = 0; int len = 0;
u32 value; u32 value;
...@@ -428,11 +429,14 @@ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev) ...@@ -428,11 +429,14 @@ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev)
len += snprintf(msg + len, sizeof(msg) - len, " 0x%x", value); len += snprintf(msg + len, sizeof(msg) - len, " 0x%x", value);
} }
dev_err(sdev->dev, "error: extended rom status:%s", msg); sof_dev_dbg_or_err(sdev->dev, hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS,
"extended rom status: %s", msg);
} }
void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
{ {
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct sof_ipc_dsp_oops_xtensa xoops; struct sof_ipc_dsp_oops_xtensa xoops;
struct sof_ipc_panic_info panic_info; struct sof_ipc_panic_info panic_info;
u32 stack[HDA_DSP_STACK_DUMP_SIZE]; u32 stack[HDA_DSP_STACK_DUMP_SIZE];
...@@ -452,8 +456,10 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) ...@@ -452,8 +456,10 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
stack, HDA_DSP_STACK_DUMP_SIZE); stack, HDA_DSP_STACK_DUMP_SIZE);
} else { } else {
dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", sof_dev_dbg_or_err(sdev->dev, hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS,
status, panic); "status = 0x%8.8x panic = 0x%8.8x\n",
status, panic);
hda_dsp_dump_ext_rom_status(sdev); hda_dsp_dump_ext_rom_status(sdev);
hda_dsp_get_status(sdev); hda_dsp_get_status(sdev);
} }
......
...@@ -274,6 +274,7 @@ ...@@ -274,6 +274,7 @@
#define BXT_D0I3_DELAY 5000 #define BXT_D0I3_DELAY 5000
#define FW_CL_STREAM_NUMBER 0x1 #define FW_CL_STREAM_NUMBER 0x1
#define HDA_FW_BOOT_ATTEMPTS 3
/* ADSPCS - Audio DSP Control & Status */ /* ADSPCS - Audio DSP Control & Status */
...@@ -416,6 +417,7 @@ enum sof_hda_D0_substate { ...@@ -416,6 +417,7 @@ enum sof_hda_D0_substate {
/* represents DSP HDA controller frontend - i.e. host facing control */ /* represents DSP HDA controller frontend - i.e. host facing control */
struct sof_intel_hda_dev { struct sof_intel_hda_dev {
int boot_iteration;
struct hda_bus hbus; struct hda_bus hbus;
......
...@@ -485,13 +485,13 @@ EXPORT_SYMBOL(sof_machine_check); ...@@ -485,13 +485,13 @@ EXPORT_SYMBOL(sof_machine_check);
int sof_machine_register(struct snd_sof_dev *sdev, void *pdata) int sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
{ {
struct snd_sof_pdata *plat_data = (struct snd_sof_pdata *)pdata; struct snd_sof_pdata *plat_data = pdata;
const char *drv_name; const char *drv_name;
const void *mach; const void *mach;
int size; int size;
drv_name = plat_data->machine->drv_name; drv_name = plat_data->machine->drv_name;
mach = (const void *)plat_data->machine; mach = plat_data->machine;
size = sizeof(*plat_data->machine); size = sizeof(*plat_data->machine);
/* register machine driver, pass machine info as pdata */ /* register machine driver, pass machine info as pdata */
...@@ -510,7 +510,7 @@ EXPORT_SYMBOL(sof_machine_register); ...@@ -510,7 +510,7 @@ EXPORT_SYMBOL(sof_machine_register);
void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata) void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
{ {
struct snd_sof_pdata *plat_data = (struct snd_sof_pdata *)pdata; struct snd_sof_pdata *plat_data = pdata;
if (!IS_ERR_OR_NULL(plat_data->pdev_mach)) if (!IS_ERR_OR_NULL(plat_data->pdev_mach))
platform_device_unregister(plat_data->pdev_mach); platform_device_unregister(plat_data->pdev_mach);
......
...@@ -578,4 +578,12 @@ int intel_pcm_close(struct snd_sof_dev *sdev, ...@@ -578,4 +578,12 @@ int intel_pcm_close(struct snd_sof_dev *sdev,
int sof_machine_check(struct snd_sof_dev *sdev); int sof_machine_check(struct snd_sof_dev *sdev);
#define sof_dev_dbg_or_err(dev, is_err, fmt, ...) \
do { \
if (is_err) \
dev_err(dev, "error: " fmt, __VA_ARGS__); \
else \
dev_dbg(dev, fmt, __VA_ARGS__); \
} while (0)
#endif #endif
...@@ -63,7 +63,7 @@ static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir) ...@@ -63,7 +63,7 @@ static int ipc_pcm_params(struct snd_sof_widget *swidget, int dir)
struct sof_ipc_pcm_params pcm; struct sof_ipc_pcm_params pcm;
struct snd_pcm_hw_params *params; struct snd_pcm_hw_params *params;
struct snd_sof_pcm *spcm; struct snd_sof_pcm *spcm;
int ret = 0; int ret;
memset(&pcm, 0, sizeof(pcm)); memset(&pcm, 0, sizeof(pcm));
...@@ -121,7 +121,7 @@ static int ipc_trigger(struct snd_sof_widget *swidget, int cmd) ...@@ -121,7 +121,7 @@ static int ipc_trigger(struct snd_sof_widget *swidget, int cmd)
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct sof_ipc_stream stream; struct sof_ipc_stream stream;
struct sof_ipc_reply reply; struct sof_ipc_reply reply;
int ret = 0; int ret;
/* set IPC stream params */ /* set IPC stream params */
stream.hdr.size = sizeof(stream); stream.hdr.size = sizeof(stream);
...@@ -1033,7 +1033,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, ...@@ -1033,7 +1033,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp,
struct sof_ipc_ctrl_data *cdata; struct sof_ipc_ctrl_data *cdata;
int tlv[TLV_ITEMS]; int tlv[TLV_ITEMS];
unsigned int i; unsigned int i;
int ret = 0; int ret;
/* validate topology data */ /* validate topology data */
if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) { if (le32_to_cpu(mc->num_channels) > SND_SOC_TPLG_MAX_CHAN) {
...@@ -1098,7 +1098,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp, ...@@ -1098,7 +1098,7 @@ static int sof_control_load_volume(struct snd_soc_component *scomp,
dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n", dev_dbg(scomp->dev, "tplg: load kcontrol index %d chans %d\n",
scontrol->comp_id, scontrol->num_channels); scontrol->comp_id, scontrol->num_channels);
return ret; return 0;
out_free_table: out_free_table:
if (le32_to_cpu(mc->max) > 1) if (le32_to_cpu(mc->max) > 1)
...@@ -1150,20 +1150,26 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp, ...@@ -1150,20 +1150,26 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
struct snd_soc_tplg_bytes_control *control = struct snd_soc_tplg_bytes_control *control =
container_of(hdr, struct snd_soc_tplg_bytes_control, hdr); container_of(hdr, struct snd_soc_tplg_bytes_control, hdr);
struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value; struct soc_bytes_ext *sbe = (struct soc_bytes_ext *)kc->private_value;
int max_size = sbe->max; size_t max_size = sbe->max;
int ret = 0; size_t priv_size = le32_to_cpu(control->priv.size);
int ret;
/* init the get/put bytes data */ if (max_size < sizeof(struct sof_ipc_ctrl_data) ||
scontrol->size = sizeof(struct sof_ipc_ctrl_data) + max_size < sizeof(struct sof_abi_hdr)) {
le32_to_cpu(control->priv.size); ret = -EINVAL;
goto out;
}
if (scontrol->size > max_size) { /* init the get/put bytes data */
dev_err(scomp->dev, "err: bytes data size %d exceeds max %d.\n", if (priv_size > max_size - sizeof(struct sof_ipc_ctrl_data)) {
scontrol->size, max_size); dev_err(scomp->dev, "err: bytes data size %zu exceeds max %zu.\n",
priv_size, max_size - sizeof(struct sof_ipc_ctrl_data));
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
scontrol->size = sizeof(struct sof_ipc_ctrl_data) + priv_size;
scontrol->control_data = kzalloc(max_size, GFP_KERNEL); scontrol->control_data = kzalloc(max_size, GFP_KERNEL);
cdata = scontrol->control_data; cdata = scontrol->control_data;
if (!scontrol->control_data) { if (!scontrol->control_data) {
...@@ -1204,7 +1210,7 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp, ...@@ -1204,7 +1210,7 @@ static int sof_control_load_bytes(struct snd_soc_component *scomp,
} }
} }
return ret; return 0;
out_free: out_free:
kfree(scontrol->control_data); kfree(scontrol->control_data);
...@@ -1223,7 +1229,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index, ...@@ -1223,7 +1229,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp);
struct snd_soc_dobj *dobj; struct snd_soc_dobj *dobj;
struct snd_sof_control *scontrol; struct snd_sof_control *scontrol;
int ret = -EINVAL; int ret;
dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n", dev_dbg(scomp->dev, "tplg: load control type %d name : %s\n",
hdr->type, hdr->name); hdr->type, hdr->name);
...@@ -1276,7 +1282,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index, ...@@ -1276,7 +1282,7 @@ static int sof_control_load(struct snd_soc_component *scomp, int index,
dobj->private = scontrol; dobj->private = scontrol;
list_add(&scontrol->list, &sdev->kcontrol_list); list_add(&scontrol->list, &sdev->kcontrol_list);
return ret; return 0;
} }
static int sof_control_unload(struct snd_soc_component *scomp, static int sof_control_unload(struct snd_soc_component *scomp,
...@@ -2659,7 +2665,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index, ...@@ -2659,7 +2665,7 @@ static int sof_dai_load(struct snd_soc_component *scomp, int index,
struct snd_soc_tplg_private *private = &pcm->priv; struct snd_soc_tplg_private *private = &pcm->priv;
struct snd_sof_pcm *spcm; struct snd_sof_pcm *spcm;
int stream; int stream;
int ret = 0; int ret;
/* nothing to do for BEs atm */ /* nothing to do for BEs atm */
if (!pcm) if (!pcm)
...@@ -3350,7 +3356,6 @@ static int sof_link_hda_unload(struct snd_sof_dev *sdev, ...@@ -3350,7 +3356,6 @@ static int sof_link_hda_unload(struct snd_sof_dev *sdev,
struct snd_soc_dai_link *link) struct snd_soc_dai_link *link)
{ {
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
int ret = 0;
dai = snd_soc_find_dai(link->cpus); dai = snd_soc_find_dai(link->cpus);
if (!dai) { if (!dai) {
...@@ -3359,7 +3364,7 @@ static int sof_link_hda_unload(struct snd_sof_dev *sdev, ...@@ -3359,7 +3364,7 @@ static int sof_link_hda_unload(struct snd_sof_dev *sdev,
return -EINVAL; return -EINVAL;
} }
return ret; return 0;
} }
static int sof_link_unload(struct snd_soc_component *scomp, static int sof_link_unload(struct snd_soc_component *scomp,
...@@ -3492,7 +3497,6 @@ static int sof_route_load(struct snd_soc_component *scomp, int index, ...@@ -3492,7 +3497,6 @@ static int sof_route_load(struct snd_soc_component *scomp, int index,
sink_swidget->id != snd_soc_dapm_buffer) { sink_swidget->id != snd_soc_dapm_buffer) {
dev_dbg(scomp->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n", dev_dbg(scomp->dev, "warning: neither Linked source component %s nor sink component %s is of buffer type, ignoring link\n",
route->source, route->sink); route->source, route->sink);
ret = 0;
goto err; goto err;
} else { } else {
ret = sof_ipc_tx_message(sdev->ipc, ret = sof_ipc_tx_message(sdev->ipc,
...@@ -3526,7 +3530,7 @@ static int sof_route_load(struct snd_soc_component *scomp, int index, ...@@ -3526,7 +3530,7 @@ static int sof_route_load(struct snd_soc_component *scomp, int index,
/* add route to route list */ /* add route to route list */
list_add(&sroute->list, &sdev->route_list); list_add(&sroute->list, &sdev->route_list);
return ret; return 0;
} }
err: err:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment