Unverified Commit aca961f1 authored by Ranjani Sridharan's avatar Ranjani Sridharan Committed by Mark Brown
Browse files

ASoC: SOF: Intel: hda: Add helper function to program ICCMAX stream



For some platforms, the recommended HW sequence for FW boot involves
starting a specially crafted capture stream before powering
on the DSP cores. Add a helper function to define the minimal
recommended stream programming sequence for this stream.

Reviewed-by: default avatarGuennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20200826184532.1612070-4-ranjani.sridharan@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 0ff06df0
Loading
Loading
Loading
Loading
+69 −0
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@
#include "../sof-audio.h"
#include "hda.h"

#define HDA_LTRP_GB_VALUE_US	95

/*
 * set up one of BDL entries for a stream
 */
@@ -322,6 +324,73 @@ int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
	return 0;
}

/* minimal recommended programming for ICCMAX stream */
int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
				    struct snd_dma_buffer *dmab,
				    struct snd_pcm_hw_params *params)
{
	struct hdac_bus *bus = sof_to_bus(sdev);
	struct hdac_stream *hstream = &stream->hstream;
	int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
	int ret;
	u32 mask = 0x1 << hstream->index;

	if (!stream) {
		dev_err(sdev->dev, "error: no stream available\n");
		return -ENODEV;
	}

	if (hstream->posbuf)
		*hstream->posbuf = 0;

	/* reset BDL address */
	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
			  0x0);
	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
			  0x0);

	hstream->frags = 0;

	ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
	if (ret < 0) {
		dev_err(sdev->dev, "error: set up of BDL failed\n");
		return ret;
	}

	/* program BDL address */
	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
			  (u32)hstream->bdl.addr);
	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
			  upper_32_bits(hstream->bdl.addr));

	/* program cyclic buffer length */
	snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
			  sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
			  hstream->bufsize);

	/* program last valid index */
	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
				sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
				0xffff, (hstream->frags - 1));

	/* decouple host and link DMA, enable DSP features */
	snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
				mask, mask);

	/* Follow HW recommendation to set the guardband value to 95us during FW boot */
	snd_hdac_chip_updateb(bus, VS_LTRP, HDA_VS_INTEL_LTRP_GB_MASK, HDA_LTRP_GB_VALUE_US);

	/* start DMA */
	snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
				SOF_HDA_SD_CTL_DMA_START, SOF_HDA_SD_CTL_DMA_START);

	return 0;
}

/*
 * prepare for common hdac registers settings, for both code loader
 * and normal stream.
+4 −0
Original line number Diff line number Diff line
@@ -246,6 +246,7 @@
/* Intel Vendor Specific Registers */
#define HDA_VS_INTEL_EM2		0x1030
#define HDA_VS_INTEL_EM2_L1SEN		BIT(13)
#define HDA_VS_INTEL_LTRP_GB_MASK	0x3F

/*  HIPCI */
#define HDA_DSP_REG_HIPCI_BUSY		BIT(31)
@@ -546,6 +547,9 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
			     struct hdac_ext_stream *stream,
			     struct snd_dma_buffer *dmab,
			     struct snd_pcm_hw_params *params);
int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
				    struct snd_dma_buffer *dmab,
				    struct snd_pcm_hw_params *params);
int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
			   struct hdac_ext_stream *stream, int cmd);
irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context);