Unverified Commit 388fe2b8 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: Intel: avs: Updates and cleanups

Merge series from Cezary Rojewski <cezary.rojewski@intel.com>:

Series consists of loosely connected patches and does not concentrate on
one specific subject.

First, as generic HDAudio codec driver is now part of ASoC, avs-driver
core is updated to register missing ext_bus operations. This completes
driver's core implementation.

The next change adds the last missing piece for port descriptions coming
from topology in formatted string format e.g.: ssp%d have full
effect. To do that, the port value needs to be provided to respective
copier configuration.

Third change relaxes core transition timings so that scenarios where
modules are interfering with each other while being on separate cores
are not occasionally causing trouble.

All other changes are addressing warnings, cleaning things up a little
and protecting driver from invalid firmware behavior - while not
expected in release binaries, does not hurt to add them.
parents 2551b6e8 f1eea115
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -216,7 +216,7 @@ config SND_SOC_INTEL_AVS
	depends on COMMON_CLK
	select SND_SOC_ACPI if ACPI
	select SND_SOC_TOPOLOGY
	select SND_HDA
	select SND_SOC_HDA
	select SND_HDA_EXT_CORE
	select SND_HDA_DSP_LOADER
	select SND_INTEL_DSP_CONFIG
+6 −6
Original line number Diff line number Diff line
@@ -176,17 +176,17 @@ int hda_cldma_reset(struct hda_cldma *cl)
		return ret;
	}

	snd_hdac_stream_updateb(cl, SD_CTL, 1, 1);
	ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, (reg & 1), AVS_CL_OP_INTERVAL_US,
					 AVS_CL_OP_TIMEOUT_US);
	snd_hdac_stream_updateb(cl, SD_CTL, SD_CTL_STREAM_RESET, SD_CTL_STREAM_RESET);
	ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, (reg & SD_CTL_STREAM_RESET),
					 AVS_CL_OP_INTERVAL_US, AVS_CL_OP_TIMEOUT_US);
	if (ret < 0) {
		dev_err(cl->dev, "cldma set SRST failed: %d\n", ret);
		return ret;
	}

	snd_hdac_stream_updateb(cl, SD_CTL, 1, 0);
	ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, !(reg & 1), AVS_CL_OP_INTERVAL_US,
					 AVS_CL_OP_TIMEOUT_US);
	snd_hdac_stream_updateb(cl, SD_CTL, SD_CTL_STREAM_RESET, 0);
	ret = snd_hdac_stream_readb_poll(cl, SD_CTL, reg, !(reg & SD_CTL_STREAM_RESET),
					 AVS_CL_OP_INTERVAL_US, AVS_CL_OP_TIMEOUT_US);
	if (ret < 0) {
		dev_err(cl->dev, "cldma unset SRST failed: %d\n", ret);
		return ret;
+6 −7
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <sound/hdaudio_ext.h>
#include <sound/intel-dsp-config.h>
#include <sound/intel-nhlt.h>
#include "../../codecs/hda.h"
#include "avs.h"
#include "cldma.h"

@@ -356,7 +357,7 @@ static int avs_bus_init(struct avs_dev *adev, struct pci_dev *pci, const struct
	struct device *dev = &pci->dev;
	int ret;

	ret = snd_hdac_ext_bus_init(&bus->core, dev, NULL, NULL);
	ret = snd_hdac_ext_bus_init(&bus->core, dev, NULL, &soc_hda_ext_bus_ops);
	if (ret < 0)
		return ret;

@@ -439,12 +440,9 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
	if (bus->mlcap)
		snd_hdac_ext_bus_get_ml_capabilities(bus);

	if (!dma_set_mask(dev, DMA_BIT_MASK(64))) {
		dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
	} else {
		dma_set_mask(dev, DMA_BIT_MASK(32));
		dma_set_coherent_mask(dev, DMA_BIT_MASK(32));
	}
	if (!dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
		dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
	dma_set_max_seg_size(dev, UINT_MAX);

	ret = avs_hdac_bus_init_streams(bus);
	if (ret < 0) {
@@ -555,6 +553,7 @@ static int __maybe_unused avs_suspend_common(struct avs_dev *adev)
		return AVS_IPC_RET(ret);
	}

	avs_ipc_block(adev->ipc);
	avs_dsp_op(adev, int_control, false);
	snd_hdac_ext_bus_ppcap_int_enable(bus, false);

+9 −2
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@

#define AVS_ADSPCS_INTERVAL_US		500
#define AVS_ADSPCS_TIMEOUT_US		50000
#define AVS_ADSPCS_DELAY_US		1000

int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power)
{
@@ -26,6 +27,8 @@ int avs_dsp_core_power(struct avs_dev *adev, u32 core_mask, bool power)
	value = power ? mask : 0;

	snd_hdac_adsp_updatel(adev, AVS_ADSP_REG_ADSPCS, mask, value);
	/* Delay the polling to avoid false positives. */
	usleep_range(AVS_ADSPCS_DELAY_US, 2 * AVS_ADSPCS_DELAY_US);

	mask = AVS_ADSPCS_CPA_MASK(core_mask);
	value = power ? mask : 0;
@@ -82,13 +85,17 @@ int avs_dsp_core_stall(struct avs_dev *adev, u32 core_mask, bool stall)
				       reg, (reg & mask) == value,
				       AVS_ADSPCS_INTERVAL_US,
				       AVS_ADSPCS_TIMEOUT_US);
	if (ret)
	if (ret) {
		dev_err(adev->dev, "core_mask %d %sstall failed: %d\n",
			core_mask, stall ? "" : "un", ret);

		return ret;
	}

	/* Give HW time to propagate the change. */
	usleep_range(AVS_ADSPCS_DELAY_US, 2 * AVS_ADSPCS_DELAY_US);
	return 0;
}

int avs_dsp_core_enable(struct avs_dev *adev, u32 core_mask)
{
	int ret;
+1 −0
Original line number Diff line number Diff line
@@ -480,6 +480,7 @@ static int avs_dsp_do_send_msg(struct avs_dev *adev, struct avs_ipc_msg *request
	ret = ipc->rx.rsp.status;
	if (reply) {
		reply->header = ipc->rx.header;
		reply->size = ipc->rx.size;
		if (reply->data && ipc->rx.size)
			memcpy(reply->data, ipc->rx.data, reply->size);
	}
Loading