ASoC: SOF: amd: Fix for acp init sequence
authorVijendar Mukunda <Vijendar.Mukunda@amd.com>
Fri, 16 Aug 2024 07:03:28 +0000 (12:33 +0530)
committerMark Brown <broonie@kernel.org>
Fri, 16 Aug 2024 12:04:31 +0000 (13:04 +0100)
When ACP is not powered on by default, acp power on sequence explicitly
invoked by programming pgfsm control mask. The existing implementation
checks the same PGFSM status mask and programs the same PGFSM control mask
in all ACP variants which breaks acp power on sequence for ACP6.0 and
ACP6.3 variants. So to fix this issue, update ACP pgfsm control mask and
status mask based on acp descriptor rev field, which will vary based on
acp variant.

Fixes: 846aef1d7cc0 ("ASoC: SOF: amd: Add Renoir ACP HW support")
Signed-off-by: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
Link: https://patch.msgid.link/20240816070328.610360-1-Vijendar.Mukunda@amd.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/amd/acp.c
sound/soc/sof/amd/acp.h

index d95f865669a699a704b28aa7768420febe3f97e7..85b58c8ccd0da256a515da7e22333a8d17ff60cc 100644 (file)
@@ -433,6 +433,7 @@ static int acp_power_on(struct snd_sof_dev *sdev)
        const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
        unsigned int base = desc->pgfsm_base;
        unsigned int val;
+       unsigned int acp_pgfsm_status_mask, acp_pgfsm_cntl_mask;
        int ret;
 
        val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET);
@@ -440,9 +441,23 @@ static int acp_power_on(struct snd_sof_dev *sdev)
        if (val == ACP_POWERED_ON)
                return 0;
 
-       if (val & ACP_PGFSM_STATUS_MASK)
+       switch (desc->rev) {
+       case 3:
+       case 5:
+               acp_pgfsm_status_mask = ACP3X_PGFSM_STATUS_MASK;
+               acp_pgfsm_cntl_mask = ACP3X_PGFSM_CNTL_POWER_ON_MASK;
+               break;
+       case 6:
+               acp_pgfsm_status_mask = ACP6X_PGFSM_STATUS_MASK;
+               acp_pgfsm_cntl_mask = ACP6X_PGFSM_CNTL_POWER_ON_MASK;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if (val & acp_pgfsm_status_mask)
                snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + PGFSM_CONTROL_OFFSET,
-                                 ACP_PGFSM_CNTL_POWER_ON_MASK);
+                                 acp_pgfsm_cntl_mask);
 
        ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, base + PGFSM_STATUS_OFFSET, val,
                                            !val, ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
index 1af86b5b28db8074c66aa5d80072030f7e991cbf..61b28df8c908144cb2d695e8d8be5fda2e4ece86 100644 (file)
 #define ACP_REG_POLL_TIMEOUT_US                 2000
 #define ACP_DMA_COMPLETE_TIMEOUT_US            5000
 
-#define ACP_PGFSM_CNTL_POWER_ON_MASK           0x01
-#define ACP_PGFSM_STATUS_MASK                  0x03
+#define ACP3X_PGFSM_CNTL_POWER_ON_MASK         0x01
+#define ACP3X_PGFSM_STATUS_MASK                        0x03
+#define ACP6X_PGFSM_CNTL_POWER_ON_MASK         0x07
+#define ACP6X_PGFSM_STATUS_MASK                        0x0F
+
 #define ACP_POWERED_ON                         0x00
 #define ACP_ASSERT_RESET                       0x01
 #define ACP_RELEASE_RESET                      0x00