Unverified Commit d2be77b3 authored by Ajit Kumar Pandey's avatar Ajit Kumar Pandey Committed by Mark Brown
Browse files

ASoC: SOF: amd: Use dedicated MBOX for ACP and PSP communication



We are currently using generic PSP Mailbox register for sending SHA
complete command to PSP but observe random arbitration issue during
PSP validation as MP0_C2PMSG_26_REG used by other kernel modules.

Use separate mailbox registers and doorbell mechanism to send SHA_DMA
complete command to PSP. This fixes such validation issues and added
flexibility for sending more ACP commands to PSP in future as new mbox
registers i.e MP0_C2PMSG_114_REG and MP0_C2PMSG_73_REG are dedicated
by PSP for ACP communications.

Reviewed-by: default avatarRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: default avatarBard Liao <yung-chuan.liao@linux.intel.com>
Signed-off-by: default avatarAjit Kumar Pandey <AjitKumar.Pandey@amd.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220421165820.337207-3-pierre-louis.bossart@linux.intel.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent bbdcd3d5
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -152,7 +152,7 @@ static int psp_mbox_ready(struct acp_dev_data *adata, bool ack)

	for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
		msleep(20);
		smn_read(adata->smn_dev, MP0_C2PMSG_26_REG, &data);
		smn_read(adata->smn_dev, MP0_C2PMSG_114_REG, &data);
		if (data & MBOX_READY_MASK)
			return 0;
	}
@@ -173,17 +173,35 @@ static int psp_mbox_ready(struct acp_dev_data *adata, bool ack)

static int psp_send_cmd(struct acp_dev_data *adata, int cmd)
{
	int ret;
	struct snd_sof_dev *sdev = adata->dev;
	int ret, timeout;
	u32 data;

	if (!cmd)
		return -EINVAL;

	/* Get a non-zero Doorbell value from PSP */
	for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
		msleep(MBOX_DELAY);
		smn_read(adata->smn_dev, MP0_C2PMSG_73_REG, &data);
		if (data)
			break;
	}

	if (!timeout) {
		dev_err(sdev->dev, "Failed to get Doorbell from MBOX %x\n", MP0_C2PMSG_73_REG);
		return -EINVAL;
	}

	/* Check if PSP is ready for new command */
	ret = psp_mbox_ready(adata, 0);
	if (ret)
		return ret;

	smn_write(adata->smn_dev, MP0_C2PMSG_26_REG, cmd);
	smn_write(adata->smn_dev, MP0_C2PMSG_114_REG, cmd);

	/* Ring the Doorbell for PSP */
	smn_write(adata->smn_dev, MP0_C2PMSG_73_REG, data);

	/* Check MBOX ready as PSP ack */
	ret = psp_mbox_ready(adata, 1);
+4 −2
Original line number Diff line number Diff line
@@ -57,8 +57,10 @@
#define ACP_SHA_STAT				0x8000
#define ACP_PSP_TIMEOUT_COUNTER			5
#define ACP_EXT_INTR_ERROR_STAT			0x20000000
#define MP0_C2PMSG_26_REG			0x03810570
#define MBOX_ACP_SHA_DMA_COMMAND		0x330000
#define MP0_C2PMSG_114_REG			0x3810AC8
#define MP0_C2PMSG_73_REG			0x3810A24
#define MBOX_ACP_SHA_DMA_COMMAND		0x70000
#define MBOX_DELAY				1000
#define MBOX_READY_MASK				0x80000000
#define MBOX_STATUS_MASK			0xFFFF