sound/soc/sof/amd/acp.c

Source file repositories/reference/linux-study-clean/sound/soc/sof/amd/acp.c

File Facts

System
Linux kernel
Corpus path
sound/soc/sof/amd/acp.c
Extension
.c
Size
28940 bytes
Lines
997
Domain
Driver Families
Bucket
sound/soc
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret < 0) {
			dev_err(sdev->dev, "SHA DMA Failed to Reset\n");
			return ret;
		}
	}

	if (adata->quirks && adata->quirks->signed_fw_image)
		snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_INCLUDE_HDR, ACP_SHA_HEADER);

	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_STRT_ADDR, start_addr);
	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_DESTINATION_ADDR, dest_addr);
	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_MSG_LENGTH, image_length);

	/* psp_send_cmd only required for vangogh platform */
	if (adata->pci_rev == ACP_VANGOGH_PCI_ID &&
	    !(adata->quirks && adata->quirks->skip_iram_dram_size_mod)) {
		/* Modify IRAM and DRAM size */
		ret = psp_send_cmd(adata, MBOX_ACP_IRAM_DRAM_FENCE_COMMAND | IRAM_DRAM_FENCE_2);
		if (ret)
			return ret;
		ret = psp_send_cmd(adata, MBOX_ACP_IRAM_DRAM_FENCE_COMMAND | MBOX_ISREADY_FLAG);
		if (ret)
			return ret;
	}
	snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD, ACP_SHA_RUN);

	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_TRANSFER_BYTE_CNT,
					    tx_count, tx_count == image_length,
					    ACP_REG_POLL_INTERVAL, ACP_DMA_COMPLETE_TIMEOUT_US);
	if (ret < 0) {
		dev_err(sdev->dev, "SHA DMA Failed to Transfer Length %x\n", tx_count);
		return ret;
	}

	/* psp_send_cmd only required for renoir platform*/
	if (adata->pci_rev == ACP_RN_PCI_ID) {
		ret = psp_send_cmd(adata, MBOX_ACP_SHA_DMA_COMMAND);
		if (ret)
			return ret;
	}

	ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER,
					    fw_qualifier, fw_qualifier & DSP_FW_RUN_ENABLE,
					    ACP_REG_POLL_INTERVAL, ACP_DMA_COMPLETE_TIMEOUT_US);
	if (ret < 0) {
		val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_PSP_ACK);
		dev_err(sdev->dev, "PSP validation failed: fw_qualifier = %#x, ACP_SHA_PSP_ACK = %#x\n",
			fw_qualifier, val);
		return ret;
	}

	return 0;
}

int acp_dma_status(struct acp_dev_data *adata, unsigned char ch)
{
	struct snd_sof_dev *sdev = adata->dev;
	unsigned int val;
	unsigned int acp_dma_ch_sts;
	int ret = 0;

	switch (adata->pci_rev) {
	case ACP70_PCI_ID:
	case ACP71_PCI_ID:
	case ACP72_PCI_ID:
		acp_dma_ch_sts = ACP70_DMA_CH_STS;
		break;
	default:
		acp_dma_ch_sts = ACP_DMA_CH_STS;
	}
	val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32));
	if (val & ACP_DMA_CH_RUN) {
		ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, acp_dma_ch_sts, val, !val,
						    ACP_REG_POLL_INTERVAL,
						    ACP_DMA_COMPLETE_TIMEOUT_US);
		if (ret < 0)
			dev_err(sdev->dev, "DMA_CHANNEL %d status timeout\n", ch);
	}

	return ret;
}

void memcpy_from_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *dst, size_t bytes)
{
	unsigned int reg_offset = offset + ACP_SCRATCH_REG_0;
	int i, j;

	for (i = 0, j = 0; i < bytes; i = i + 4, j++)
		dst[j] = snd_sof_dsp_read(sdev, ACP_DSP_BAR, reg_offset + i);
}

Annotation

Implementation Notes