Unverified Commit e3933683 authored by Venkata Prasad Potturu's avatar Venkata Prasad Potturu Committed by Mark Brown
Browse files

ASoC: amd: acp: Remove redundant acp_dev_data structure



Move acp_dev_data structure members to acp_chip_info structure
to avoid using common members in each structure and remove redundant
acp_dev_data structure.

Signed-off-by: default avatarVenkata Prasad Potturu <venkataprasad.potturu@amd.com>
Link: https://patch.msgid.link/20250310183201.11979-8-venkataprasad.potturu@amd.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent aaf7a668
Loading
Loading
Loading
Loading
+88 −93
Original line number Diff line number Diff line
@@ -31,14 +31,10 @@
#define	ACP63_LRCLK_DIV_FIELD		GENMASK(12, 2)
#define	ACP63_BCLK_DIV_FIELD		GENMASK(23, 13)

static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id)
static inline void acp_set_i2s_clk(struct acp_chip_info *chip, int dai_id)
{
	u32 i2s_clk_reg, val;
	struct acp_chip_info *chip;
	struct device *dev;

	dev = adata->dev;
	chip = dev_get_platdata(dev);
	switch (dai_id) {
	case I2S_SP_INSTANCE:
		i2s_clk_reg = ACP_I2STDM0_MSTRCLKGEN;
@@ -55,36 +51,37 @@ static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id)
	}

	val  = I2S_MASTER_MODE_ENABLE;
	if (adata->tdm_mode)
	if (chip->tdm_mode)
		val |= BIT(1);

	switch (chip->acp_rev) {
	case ACP63_PCI_ID:
	case ACP70_PCI_ID:
	case ACP71_PCI_ID:
		val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, adata->lrclk_div);
		val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, adata->bclk_div);
		val |= FIELD_PREP(ACP63_LRCLK_DIV_FIELD, chip->lrclk_div);
		val |= FIELD_PREP(ACP63_BCLK_DIV_FIELD, chip->bclk_div);
		break;
	default:
		val |= FIELD_PREP(LRCLK_DIV_FIELD, adata->lrclk_div);
		val |= FIELD_PREP(BCLK_DIV_FIELD, adata->bclk_div);
		val |= FIELD_PREP(LRCLK_DIV_FIELD, chip->lrclk_div);
		val |= FIELD_PREP(BCLK_DIV_FIELD, chip->bclk_div);
	}
	writel(val, adata->acp_base + i2s_clk_reg);
	writel(val, chip->base + i2s_clk_reg);
}

static int acp_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
			   unsigned int fmt)
{
	struct acp_dev_data *adata = snd_soc_dai_get_drvdata(cpu_dai);
	struct device *dev = cpu_dai->component->dev;
	struct acp_chip_info *chip = dev_get_platdata(dev);
	int mode;

	mode = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
	switch (mode) {
	case SND_SOC_DAIFMT_I2S:
		adata->tdm_mode = TDM_DISABLE;
		chip->tdm_mode = TDM_DISABLE;
		break;
	case SND_SOC_DAIFMT_DSP_A:
		adata->tdm_mode = TDM_ENABLE;
		chip->tdm_mode = TDM_ENABLE;
		break;
	default:
		return -EINVAL;
@@ -96,7 +93,6 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas
				int slots, int slot_width)
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = snd_soc_dai_get_drvdata(dai);
	struct acp_chip_info *chip;
	struct acp_stream *stream;
	int slot_len, no_of_slots;
@@ -157,35 +153,35 @@ static int acp_i2s_set_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, u32 rx_mas

	slots = no_of_slots;

	spin_lock_irq(&adata->acp_lock);
	list_for_each_entry(stream, &adata->stream_list, list) {
	spin_lock_irq(&chip->acp_lock);
	list_for_each_entry(stream, &chip->stream_list, list) {
		switch (chip->acp_rev) {
		case ACP_RN_PCI_ID:
		case ACP_RMB_PCI_ID:
			if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
				adata->tdm_tx_fmt[stream->dai_id - 1] =
				chip->tdm_tx_fmt[stream->dai_id - 1] =
					FRM_LEN | (slots << 15) | (slot_len << 18);
			else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE)
				adata->tdm_rx_fmt[stream->dai_id - 1] =
				chip->tdm_rx_fmt[stream->dai_id - 1] =
					FRM_LEN | (slots << 15) | (slot_len << 18);
			break;
		case ACP63_PCI_ID:
		case ACP70_PCI_ID:
		case ACP71_PCI_ID:
			if (tx_mask && stream->dir == SNDRV_PCM_STREAM_PLAYBACK)
				adata->tdm_tx_fmt[stream->dai_id - 1] =
				chip->tdm_tx_fmt[stream->dai_id - 1] =
						FRM_LEN | (slots << 13) | (slot_len << 18);
			else if (rx_mask && stream->dir == SNDRV_PCM_STREAM_CAPTURE)
				adata->tdm_rx_fmt[stream->dai_id - 1] =
				chip->tdm_rx_fmt[stream->dai_id - 1] =
						FRM_LEN | (slots << 13) | (slot_len << 18);
			break;
		default:
			dev_err(dev, "Unknown chip revision %d\n", chip->acp_rev);
			spin_unlock_irq(&adata->acp_lock);
			spin_unlock_irq(&chip->acp_lock);
			return -EINVAL;
		}
	}
	spin_unlock_irq(&adata->acp_lock);
	spin_unlock_irq(&chip->acp_lock);
	return 0;
}

@@ -193,15 +189,15 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
			    struct snd_soc_dai *dai)
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata;
	struct acp_chip_info *chip;
	struct acp_resource *rsrc;
	u32 val;
	u32 xfer_resolution;
	u32 reg_val, fmt_reg, tdm_fmt;
	u32 lrclk_div_val, bclk_div_val;

	adata = snd_soc_dai_get_drvdata(dai);
	rsrc = adata->rsrc;
	chip = dev_get_platdata(dev);
	rsrc = chip->rsrc;

	/* These values are as per Hardware Spec */
	switch (params_format(params)) {
@@ -240,7 +236,7 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
			dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
			return -EINVAL;
		}
		adata->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution;
		chip->xfer_tx_resolution[dai->driver->id - 1] = xfer_resolution;
	} else {
		switch (dai->driver->id) {
		case I2S_BT_INSTANCE:
@@ -259,22 +255,22 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
			dev_err(dev, "Invalid dai id %x\n", dai->driver->id);
			return -EINVAL;
		}
		adata->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution;
		chip->xfer_rx_resolution[dai->driver->id - 1] = xfer_resolution;
	}

	val = readl(adata->acp_base + reg_val);
	val = readl(chip->base + reg_val);
	val &= ~ACP3x_ITER_IRER_SAMP_LEN_MASK;
	val = val | (xfer_resolution  << 3);
	writel(val, adata->acp_base + reg_val);
	writel(val, chip->base + reg_val);

	if (adata->tdm_mode) {
		val = readl(adata->acp_base + reg_val);
		writel(val | BIT(1), adata->acp_base + reg_val);
	if (chip->tdm_mode) {
		val = readl(chip->base + reg_val);
		writel(val | BIT(1), chip->base + reg_val);
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
			tdm_fmt = adata->tdm_tx_fmt[dai->driver->id - 1];
			tdm_fmt = chip->tdm_tx_fmt[dai->driver->id - 1];
		else
			tdm_fmt = adata->tdm_rx_fmt[dai->driver->id - 1];
		writel(tdm_fmt, adata->acp_base + fmt_reg);
			tdm_fmt = chip->tdm_rx_fmt[dai->driver->id - 1];
		writel(tdm_fmt, chip->base + fmt_reg);
	}

	if (rsrc->soc_mclk) {
@@ -377,8 +373,8 @@ static int acp_i2s_hwparams(struct snd_pcm_substream *substream, struct snd_pcm_
		default:
			break;
		}
		adata->lrclk_div = lrclk_div_val;
		adata->bclk_div = bclk_div_val;
		chip->lrclk_div = lrclk_div_val;
		chip->bclk_div = bclk_div_val;
	}
	return 0;
}
@@ -387,8 +383,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
{
	struct acp_stream *stream = substream->runtime->private_data;
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	struct acp_chip_info *chip = dev_get_platdata(dev);
	struct acp_resource *rsrc = chip->rsrc;
	u32 val, period_bytes, reg_val, ier_val, water_val, buf_size, buf_reg;

	period_bytes = frames_to_bytes(substream->runtime, substream->runtime->period_size);
@@ -398,20 +394,20 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
		stream->bytescount = acp_get_byte_count(adata, stream->dai_id, substream->stream);
		stream->bytescount = acp_get_byte_count(chip, stream->dai_id, substream->stream);
		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
			switch (dai->driver->id) {
			case I2S_BT_INSTANCE:
				water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(adata);
				water_val = ACP_BT_TX_INTR_WATERMARK_SIZE(chip);
				reg_val = ACP_BTTDM_ITER;
				ier_val = ACP_BTTDM_IER;
				buf_reg = ACP_BT_TX_RINGBUFSIZE(adata);
				buf_reg = ACP_BT_TX_RINGBUFSIZE(chip);
				break;
			case I2S_SP_INSTANCE:
				water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(adata);
				water_val = ACP_I2S_TX_INTR_WATERMARK_SIZE(chip);
				reg_val = ACP_I2STDM_ITER;
				ier_val = ACP_I2STDM_IER;
				buf_reg = ACP_I2S_TX_RINGBUFSIZE(adata);
				buf_reg = ACP_I2S_TX_RINGBUFSIZE(chip);
				break;
			case I2S_HS_INSTANCE:
				water_val = ACP_HS_TX_INTR_WATERMARK_SIZE;
@@ -426,16 +422,16 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
		} else {
			switch (dai->driver->id) {
			case I2S_BT_INSTANCE:
				water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(adata);
				water_val = ACP_BT_RX_INTR_WATERMARK_SIZE(chip);
				reg_val = ACP_BTTDM_IRER;
				ier_val = ACP_BTTDM_IER;
				buf_reg = ACP_BT_RX_RINGBUFSIZE(adata);
				buf_reg = ACP_BT_RX_RINGBUFSIZE(chip);
				break;
			case I2S_SP_INSTANCE:
				water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(adata);
				water_val = ACP_I2S_RX_INTR_WATERMARK_SIZE(chip);
				reg_val = ACP_I2STDM_IRER;
				ier_val = ACP_I2STDM_IER;
				buf_reg = ACP_I2S_RX_RINGBUFSIZE(adata);
				buf_reg = ACP_I2S_RX_RINGBUFSIZE(chip);
				break;
			case I2S_HS_INSTANCE:
				water_val = ACP_HS_RX_INTR_WATERMARK_SIZE;
@@ -449,14 +445,14 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
			}
		}

		writel(period_bytes, adata->acp_base + water_val);
		writel(buf_size, adata->acp_base + buf_reg);
		writel(period_bytes, chip->base + water_val);
		writel(buf_size, chip->base + buf_reg);
		if (rsrc->soc_mclk)
			acp_set_i2s_clk(adata, dai->driver->id);
		val = readl(adata->acp_base + reg_val);
			acp_set_i2s_clk(chip, dai->driver->id);
		val = readl(chip->base + reg_val);
		val = val | BIT(0);
		writel(val, adata->acp_base + reg_val);
		writel(1, adata->acp_base + ier_val);
		writel(val, chip->base + reg_val);
		writel(1, chip->base + ier_val);
		return 0;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
@@ -493,19 +489,19 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
				return -EINVAL;
			}
		}
		val = readl(adata->acp_base + reg_val);
		val = readl(chip->base + reg_val);
		val = val & ~BIT(0);
		writel(val, adata->acp_base + reg_val);

		if (!(readl(adata->acp_base + ACP_BTTDM_ITER) & BIT(0)) &&
		    !(readl(adata->acp_base + ACP_BTTDM_IRER) & BIT(0)))
			writel(0, adata->acp_base + ACP_BTTDM_IER);
		if (!(readl(adata->acp_base + ACP_I2STDM_ITER) & BIT(0)) &&
		    !(readl(adata->acp_base + ACP_I2STDM_IRER) & BIT(0)))
			writel(0, adata->acp_base + ACP_I2STDM_IER);
		if (!(readl(adata->acp_base + ACP_HSTDM_ITER) & BIT(0)) &&
		    !(readl(adata->acp_base + ACP_HSTDM_IRER) & BIT(0)))
			writel(0, adata->acp_base + ACP_HSTDM_IER);
		writel(val, chip->base + reg_val);

		if (!(readl(chip->base + ACP_BTTDM_ITER) & BIT(0)) &&
		    !(readl(chip->base + ACP_BTTDM_IRER) & BIT(0)))
			writel(0, chip->base + ACP_BTTDM_IER);
		if (!(readl(chip->base + ACP_I2STDM_ITER) & BIT(0)) &&
		    !(readl(chip->base + ACP_I2STDM_IRER) & BIT(0)))
			writel(0, chip->base + ACP_I2STDM_IER);
		if (!(readl(chip->base + ACP_HSTDM_ITER) & BIT(0)) &&
		    !(readl(chip->base + ACP_HSTDM_IRER) & BIT(0)))
			writel(0, chip->base + ACP_HSTDM_IER);
		return 0;
	default:
		return -EINVAL;
@@ -517,9 +513,8 @@ static int acp_i2s_trigger(struct snd_pcm_substream *substream, int cmd, struct
static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_chip_info *chip;
	struct acp_resource *rsrc = adata->rsrc;
	struct acp_chip_info *chip = dev_get_platdata(dev);
	struct acp_resource *rsrc = chip->rsrc;
	struct acp_stream *stream = substream->runtime->private_data;
	u32 reg_dma_size = 0, reg_fifo_size = 0, reg_fifo_addr = 0;
	u32 phy_addr = 0, acp_fifo_addr = 0, ext_int_ctrl;
@@ -529,56 +524,56 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
	switch (dai->driver->id) {
	case I2S_SP_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
			reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
						SP_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr =	ACP_I2S_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
			reg_fifo_addr =	ACP_I2S_TX_FIFOADDR(chip);
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip);

			if (chip->acp_rev >= ACP70_PCI_ID)
				phy_addr = ACP7x_I2S_SP_TX_MEM_WINDOW_START;
			else
				phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip));
		} else {
			reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
			reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
						SP_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip);
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip);

			if (chip->acp_rev >= ACP70_PCI_ID)
				phy_addr = ACP7x_I2S_SP_RX_MEM_WINDOW_START;
			else
				phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip));
		}
		break;
	case I2S_BT_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
			reg_dma_size = ACP_BT_TX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
						BT_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip);
			reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip);

			if (chip->acp_rev >= ACP70_PCI_ID)
				phy_addr = ACP7x_I2S_BT_TX_MEM_WINDOW_START;
			else
				phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip));
		} else {
			reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
			reg_dma_size = ACP_BT_RX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
						BT_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip);
			reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip);

			if (chip->acp_rev >= ACP70_PCI_ID)
				phy_addr = ACP7x_I2S_BT_RX_MEM_WINDOW_START;
			else
				phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip));
		}
		break;
	case I2S_HS_INSTANCE:
@@ -593,7 +588,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
				phy_addr = ACP7x_I2S_HS_TX_MEM_WINDOW_START;
			else
				phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
			writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR);
		} else {
			reg_dma_size = ACP_HS_RX_DMA_SIZE;
			acp_fifo_addr = rsrc->sram_pte_offset +
@@ -605,7 +600,7 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
				phy_addr = ACP7x_I2S_HS_RX_MEM_WINDOW_START;
			else
				phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
			writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR);
		}
		break;
	default:
@@ -613,9 +608,9 @@ static int acp_i2s_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
		return -EINVAL;
	}

	writel(DMA_SIZE, adata->acp_base + reg_dma_size);
	writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
	writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
	writel(DMA_SIZE, chip->base + reg_dma_size);
	writel(acp_fifo_addr, chip->base + reg_fifo_addr);
	writel(FIFO_SIZE, chip->base + reg_fifo_size);

	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
	ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
@@ -634,8 +629,8 @@ static int acp_i2s_startup(struct snd_pcm_substream *substream, struct snd_soc_d
{
	struct acp_stream *stream = substream->runtime->private_data;
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	struct acp_chip_info *chip = dev_get_platdata(dev);
	struct acp_resource *rsrc = chip->rsrc;
	unsigned int dir = substream->stream;
	unsigned int irq_bit = 0;

+51 −56
Original line number Diff line number Diff line
@@ -38,26 +38,25 @@ EXPORT_SYMBOL_NS_GPL(acp_common_hw_ops, "SND_SOC_ACP_COMMON");
irqreturn_t acp_irq_handler(int irq, void *data)
{
	struct acp_chip_info *chip = data;
	struct acp_dev_data *adata = chip->adata;
	struct acp_resource *rsrc = adata->rsrc;
	struct acp_resource *rsrc = chip->rsrc;
	struct acp_stream *stream;
	u16 i2s_flag = 0;
	u32 ext_intr_stat, ext_intr_stat1;

	if (adata->rsrc->no_of_ctrls == 2)
	if (rsrc->no_of_ctrls == 2)
		ext_intr_stat1 = readl(ACP_EXTERNAL_INTR_STAT(chip, (rsrc->irqp_used - 1)));

	ext_intr_stat = readl(ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));

	spin_lock(&adata->acp_lock);
	list_for_each_entry(stream, &adata->stream_list, list) {
	spin_lock(&chip->acp_lock);
	list_for_each_entry(stream, &chip->stream_list, list) {
		if (ext_intr_stat & stream->irq_bit) {
			writel(stream->irq_bit,
			       ACP_EXTERNAL_INTR_STAT(chip, rsrc->irqp_used));
			snd_pcm_period_elapsed(stream->substream);
			i2s_flag = 1;
		}
		if (adata->rsrc->no_of_ctrls == 2) {
		if (chip->rsrc->no_of_ctrls == 2) {
			if (ext_intr_stat1 & stream->irq_bit) {
				writel(stream->irq_bit, ACP_EXTERNAL_INTR_STAT(chip,
				       (rsrc->irqp_used - 1)));
@@ -66,7 +65,7 @@ irqreturn_t acp_irq_handler(int irq, void *data)
			}
		}
	}
	spin_unlock(&adata->acp_lock);
	spin_unlock(&chip->acp_lock);
	if (i2s_flag)
		return IRQ_HANDLED;

@@ -106,7 +105,7 @@ static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream,
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct acp_stream *stream = runtime->private_data;
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_chip_info *chip = dev_get_platdata(dev);

	u32 physical_addr, pdm_size, period_bytes;

@@ -115,43 +114,40 @@ static void set_acp_pdm_ring_buffer(struct snd_pcm_substream *substream,
	physical_addr = stream->reg_offset + MEM_WINDOW_START;

	/* Init ACP PDM Ring buffer */
	writel(physical_addr, adata->acp_base + ACP_WOV_RX_RINGBUFADDR);
	writel(pdm_size, adata->acp_base + ACP_WOV_RX_RINGBUFSIZE);
	writel(period_bytes, adata->acp_base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
	writel(0x01, adata->acp_base + ACPAXI2AXI_ATU_CTRL);
	writel(physical_addr, chip->base + ACP_WOV_RX_RINGBUFADDR);
	writel(pdm_size, chip->base + ACP_WOV_RX_RINGBUFSIZE);
	writel(period_bytes, chip->base + ACP_WOV_RX_INTR_WATERMARK_SIZE);
	writel(0x01, chip->base + ACPAXI2AXI_ATU_CTRL);
}

static void set_acp_pdm_clk(struct snd_pcm_substream *substream,
			    struct snd_soc_dai *dai)
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_chip_info *chip = dev_get_platdata(dev);
	unsigned int pdm_ctrl;

	/* Enable default ACP PDM clk */
	writel(PDM_CLK_FREQ_MASK, adata->acp_base + ACP_WOV_CLK_CTRL);
	pdm_ctrl = readl(adata->acp_base + ACP_WOV_MISC_CTRL);
	writel(PDM_CLK_FREQ_MASK, chip->base + ACP_WOV_CLK_CTRL);
	pdm_ctrl = readl(chip->base + ACP_WOV_MISC_CTRL);
	pdm_ctrl |= PDM_MISC_CTRL_MASK;
	writel(pdm_ctrl, adata->acp_base + ACP_WOV_MISC_CTRL);
	writel(pdm_ctrl, chip->base + ACP_WOV_MISC_CTRL);
	set_acp_pdm_ring_buffer(substream, dai);
}

void restore_acp_pdm_params(struct snd_pcm_substream *substream,
			    struct acp_dev_data *adata)
			    struct acp_chip_info *chip)
{
	struct snd_soc_dai *dai;
	struct device *dev;
	struct acp_chip_info *chip;
	struct snd_soc_pcm_runtime *soc_runtime;
	u32 ext_int_ctrl;

	soc_runtime = snd_soc_substream_to_rtd(substream);
	dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
	dev = dai->component->dev;
	chip = dev_get_platdata(dev);

	/* Programming channel mask and sampling rate */
	writel(adata->ch_mask, adata->acp_base + ACP_WOV_PDM_NO_OF_CHANNELS);
	writel(PDM_DEC_64, adata->acp_base + ACP_WOV_PDM_DECIMATION_FACTOR);
	writel(chip->ch_mask, chip->base + ACP_WOV_PDM_NO_OF_CHANNELS);
	writel(PDM_DEC_64, chip->base + ACP_WOV_PDM_DECIMATION_FACTOR);

	/* Enabling ACP Pdm interuppts */
	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, 0));
@@ -165,9 +161,8 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
				struct snd_soc_dai *dai)
{
	struct device *dev = dai->component->dev;
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_resource *rsrc = adata->rsrc;
	struct acp_chip_info *chip = dev_get_platdata(dev);
	struct acp_resource *rsrc = chip->rsrc;
	struct acp_stream *stream = substream->runtime->private_data;
	u32 reg_dma_size, reg_fifo_size, reg_fifo_addr;
	u32 phy_addr, acp_fifo_addr, ext_int_ctrl;
@@ -176,40 +171,40 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
	switch (dai->driver->id) {
	case I2S_SP_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_I2S_TX_DMA_SIZE(adata);
			reg_dma_size = ACP_I2S_TX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
					SP_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_I2S_TX_FIFOADDR(chip);
			reg_fifo_size = ACP_I2S_TX_FIFOSIZE(chip);
			phy_addr = I2S_SP_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_TX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_I2S_TX_RINGBUFADDR(chip));
		} else {
			reg_dma_size = ACP_I2S_RX_DMA_SIZE(adata);
			reg_dma_size = ACP_I2S_RX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
					SP_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_I2S_RX_FIFOADDR(chip);
			reg_fifo_size = ACP_I2S_RX_FIFOSIZE(chip);
			phy_addr = I2S_SP_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_I2S_RX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_I2S_RX_RINGBUFADDR(chip));
		}
		break;
	case I2S_BT_INSTANCE:
		if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
			reg_dma_size = ACP_BT_TX_DMA_SIZE(adata);
			reg_dma_size = ACP_BT_TX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
					BT_PB_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_TX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_TX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_BT_TX_FIFOADDR(chip);
			reg_fifo_size = ACP_BT_TX_FIFOSIZE(chip);
			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_TX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_BT_TX_RINGBUFADDR(chip));
		} else {
			reg_dma_size = ACP_BT_RX_DMA_SIZE(adata);
			reg_dma_size = ACP_BT_RX_DMA_SIZE(chip);
			acp_fifo_addr = rsrc->sram_pte_offset +
					BT_CAPT_FIFO_ADDR_OFFSET;
			reg_fifo_addr = ACP_BT_RX_FIFOADDR(adata);
			reg_fifo_size = ACP_BT_RX_FIFOSIZE(adata);
			reg_fifo_addr = ACP_BT_RX_FIFOADDR(chip);
			reg_fifo_size = ACP_BT_RX_FIFOSIZE(chip);
			phy_addr = I2S_BT_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_BT_RX_RINGBUFADDR(adata));
			writel(phy_addr, chip->base + ACP_BT_RX_RINGBUFADDR(chip));
		}
		break;
	case I2S_HS_INSTANCE:
@@ -220,7 +215,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
			reg_fifo_addr = ACP_HS_TX_FIFOADDR;
			reg_fifo_size = ACP_HS_TX_FIFOSIZE;
			phy_addr = I2S_HS_TX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_HS_TX_RINGBUFADDR);
			writel(phy_addr, chip->base + ACP_HS_TX_RINGBUFADDR);
		} else {
			reg_dma_size = ACP_HS_RX_DMA_SIZE;
			acp_fifo_addr = rsrc->sram_pte_offset +
@@ -228,7 +223,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
			reg_fifo_addr = ACP_HS_RX_FIFOADDR;
			reg_fifo_size = ACP_HS_RX_FIFOSIZE;
			phy_addr = I2S_HS_RX_MEM_WINDOW_START + stream->reg_offset;
			writel(phy_addr, adata->acp_base + ACP_HS_RX_RINGBUFADDR);
			writel(phy_addr, chip->base + ACP_HS_RX_RINGBUFADDR);
		}
		break;
	default:
@@ -236,9 +231,9 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
		return -EINVAL;
	}

	writel(DMA_SIZE, adata->acp_base + reg_dma_size);
	writel(acp_fifo_addr, adata->acp_base + reg_fifo_addr);
	writel(FIFO_SIZE, adata->acp_base + reg_fifo_size);
	writel(DMA_SIZE, chip->base + reg_dma_size);
	writel(acp_fifo_addr, chip->base + reg_fifo_addr);
	writel(FIFO_SIZE, chip->base + reg_fifo_size);

	ext_int_ctrl = readl(ACP_EXTERNAL_INTR_CNTL(chip, rsrc->irqp_used));
	ext_int_ctrl |= BIT(I2S_RX_THRESHOLD(rsrc->offset)) |
@@ -253,7 +248,7 @@ static int set_acp_i2s_dma_fifo(struct snd_pcm_substream *substream,
}

int restore_acp_i2s_params(struct snd_pcm_substream *substream,
			   struct acp_dev_data *adata,
			   struct acp_chip_info *chip,
			   struct acp_stream *stream)
{
	struct snd_soc_dai *dai;
@@ -263,7 +258,7 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream,
	soc_runtime = snd_soc_substream_to_rtd(substream);
	dai = snd_soc_rtd_to_cpu(soc_runtime, 0);
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		tdm_fmt = adata->tdm_tx_fmt[stream->dai_id - 1];
		tdm_fmt = chip->tdm_tx_fmt[stream->dai_id - 1];
		switch (stream->dai_id) {
		case I2S_BT_INSTANCE:
			reg_val = ACP_BTTDM_ITER;
@@ -281,9 +276,9 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream,
			pr_err("Invalid dai id %x\n", stream->dai_id);
			return -EINVAL;
		}
		val = adata->xfer_tx_resolution[stream->dai_id - 1] << 3;
		val = chip->xfer_tx_resolution[stream->dai_id - 1] << 3;
	} else {
		tdm_fmt = adata->tdm_rx_fmt[stream->dai_id - 1];
		tdm_fmt = chip->tdm_rx_fmt[stream->dai_id - 1];
		switch (stream->dai_id) {
		case I2S_BT_INSTANCE:
			reg_val = ACP_BTTDM_IRER;
@@ -301,13 +296,13 @@ int restore_acp_i2s_params(struct snd_pcm_substream *substream,
			pr_err("Invalid dai id %x\n", stream->dai_id);
			return -EINVAL;
		}
		val = adata->xfer_rx_resolution[stream->dai_id - 1] << 3;
		val = chip->xfer_rx_resolution[stream->dai_id - 1] << 3;
	}
	writel(val, adata->acp_base + reg_val);
	if (adata->tdm_mode == TDM_ENABLE) {
		writel(tdm_fmt, adata->acp_base + fmt_reg);
		val = readl(adata->acp_base + reg_val);
		writel(val | 0x2, adata->acp_base + reg_val);
	writel(val, chip->base + reg_val);
	if (chip->tdm_mode == TDM_ENABLE) {
		writel(tdm_fmt, chip->base + fmt_reg);
		val = readl(chip->base + reg_val);
		writel(val | 0x2, chip->base + reg_val);
	}
	return set_acp_i2s_dma_fifo(substream, dai);
}
+20 −21

File changed.

Preview size limit exceeded, changes collapsed.

+32 −38

File changed.

Preview size limit exceeded, changes collapsed.

+12 −41
Original line number Diff line number Diff line
@@ -157,8 +157,6 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct acp_chip_info *chip;
	struct acp_dev_data *adata;
	struct resource *res;
	u32 ret;

	chip = dev_get_platdata(&pdev->dev);
@@ -172,37 +170,10 @@ static int rembrandt_audio_probe(struct platform_device *pdev)
		return -ENODEV;
	}

	adata = devm_kzalloc(dev, sizeof(struct acp_dev_data), GFP_KERNEL);
	if (!adata)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "acp_mem");
	if (!res) {
		dev_err(&pdev->dev, "IORESOURCE_MEM FAILED\n");
		return -ENODEV;
	}

	adata->acp_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));
	if (!adata->acp_base)
		return -ENOMEM;

	res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "acp_dai_irq");
	if (!res) {
		dev_err(&pdev->dev, "IORESOURCE_IRQ FAILED\n");
		return -ENODEV;
	}

	chip->dev = dev;
	chip->rsrc = &rsrc;
	adata->i2s_irq = res->start;
	adata->dev = dev;
	adata->dai_driver = acp_rmb_dai;
	adata->num_dai = ARRAY_SIZE(acp_rmb_dai);
	adata->rsrc = &rsrc;
	adata->acp_rev = chip->acp_rev;
	adata->flag = chip->flag;
	adata->is_i2s_config = chip->is_i2s_config;

	dev_set_drvdata(dev, adata);
	chip->dai_driver = acp_rmb_dai;
	chip->num_dai = ARRAY_SIZE(acp_rmb_dai);

	if (chip->is_i2s_config && rsrc.soc_mclk) {
		ret = acp6x_master_clock_generate(dev);
@@ -239,30 +210,30 @@ static void rembrandt_audio_remove(struct platform_device *pdev)

static int __maybe_unused rmb_pcm_resume(struct device *dev)
{
	struct acp_dev_data *adata = dev_get_drvdata(dev);
	struct acp_chip_info *chip = dev_get_platdata(dev);
	struct acp_stream *stream;
	struct snd_pcm_substream *substream;
	snd_pcm_uframes_t buf_in_frames;
	u64 buf_size;

	if (adata->is_i2s_config && adata->rsrc->soc_mclk)
	if (chip->is_i2s_config && chip->rsrc->soc_mclk)
		acp6x_master_clock_generate(dev);

	spin_lock(&adata->acp_lock);
	list_for_each_entry(stream, &adata->stream_list, list) {
	spin_lock(&chip->acp_lock);
	list_for_each_entry(stream, &chip->stream_list, list) {
		substream = stream->substream;
		if (substream && substream->runtime) {
			buf_in_frames = (substream->runtime->buffer_size);
			buf_size = frames_to_bytes(substream->runtime, buf_in_frames);
			config_pte_for_stream(adata, stream);
			config_acp_dma(adata, stream, buf_size);
			config_pte_for_stream(chip, stream);
			config_acp_dma(chip, stream, buf_size);
			if (stream->dai_id)
				restore_acp_i2s_params(substream, adata, stream);
				restore_acp_i2s_params(substream, chip, stream);
			else
				restore_acp_pdm_params(substream, adata);
				restore_acp_pdm_params(substream, chip);
		}
	}
	spin_unlock(&adata->acp_lock);
	spin_unlock(&chip->acp_lock);
	return 0;
}

Loading