Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
0002 //
0003 // This file is provided under a dual BSD/GPLv2 license. When using or
0004 // redistributing this file, you may do so under either license.
0005 //
0006 // Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.
0007 //
0008 // Authors: Vijendar Mukunda <Vijendar.Mukunda@amd.com>
0009 //      Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
0010 
0011 /*
0012  * Hardware interface for generic AMD ACP processor
0013  */
0014 
0015 #include <linux/io.h>
0016 #include <linux/module.h>
0017 #include <linux/pci.h>
0018 
0019 #include "../ops.h"
0020 #include "acp.h"
0021 #include "acp-dsp-offset.h"
0022 
0023 static int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data)
0024 {
0025     pci_write_config_dword(dev, 0x60, smn_addr);
0026     pci_write_config_dword(dev, 0x64, data);
0027 
0028     return 0;
0029 }
0030 
0031 static int smn_read(struct pci_dev *dev, u32 smn_addr, u32 *data)
0032 {
0033     pci_write_config_dword(dev, 0x60, smn_addr);
0034     pci_read_config_dword(dev, 0x64, data);
0035 
0036     return 0;
0037 }
0038 
0039 static void init_dma_descriptor(struct acp_dev_data *adata)
0040 {
0041     struct snd_sof_dev *sdev = adata->dev;
0042     unsigned int addr;
0043 
0044     addr = ACP_SRAM_PTE_OFFSET + offsetof(struct scratch_reg_conf, dma_desc);
0045 
0046     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_BASE_ADDR, addr);
0047     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DESC_MAX_NUM_DSCR, ACP_MAX_DESC_CNT);
0048 }
0049 
0050 static void configure_dma_descriptor(struct acp_dev_data *adata, unsigned short idx,
0051                      struct dma_descriptor *dscr_info)
0052 {
0053     struct snd_sof_dev *sdev = adata->dev;
0054     unsigned int offset;
0055 
0056     offset = ACP_SCRATCH_REG_0 + offsetof(struct scratch_reg_conf, dma_desc) +
0057          idx * sizeof(struct dma_descriptor);
0058 
0059     snd_sof_dsp_write(sdev, ACP_DSP_BAR, offset, dscr_info->src_addr);
0060     snd_sof_dsp_write(sdev, ACP_DSP_BAR, offset + 0x4, dscr_info->dest_addr);
0061     snd_sof_dsp_write(sdev, ACP_DSP_BAR, offset + 0x8, dscr_info->tx_cnt.u32_all);
0062 }
0063 
0064 static int config_dma_channel(struct acp_dev_data *adata, unsigned int ch,
0065                   unsigned int idx, unsigned int dscr_count)
0066 {
0067     struct snd_sof_dev *sdev = adata->dev;
0068     unsigned int val, status;
0069     int ret;
0070 
0071     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32),
0072               ACP_DMA_CH_RST | ACP_DMA_CH_GRACEFUL_RST_EN);
0073 
0074     ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_DMA_CH_RST_STS, val,
0075                         val & (1 << ch), ACP_REG_POLL_INTERVAL,
0076                         ACP_REG_POLL_TIMEOUT_US);
0077     if (ret < 0) {
0078         status = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_ERROR_STATUS);
0079         val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_ERR_STS_0 + ch * sizeof(u32));
0080 
0081         dev_err(sdev->dev, "ACP_DMA_ERR_STS :0x%x ACP_ERROR_STATUS :0x%x\n", val, status);
0082         return ret;
0083     }
0084 
0085     snd_sof_dsp_write(sdev, ACP_DSP_BAR, (ACP_DMA_CNTL_0 + ch * sizeof(u32)), 0);
0086     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_CNT_0 + ch * sizeof(u32), dscr_count);
0087     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_DSCR_STRT_IDX_0 + ch * sizeof(u32), idx);
0088     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_PRIO_0 + ch * sizeof(u32), 0);
0089     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32), ACP_DMA_CH_RUN);
0090 
0091     return ret;
0092 }
0093 
0094 static int acpbus_dma_start(struct acp_dev_data *adata, unsigned int ch,
0095                 unsigned int dscr_count, struct dma_descriptor *dscr_info)
0096 {
0097     struct snd_sof_dev *sdev = adata->dev;
0098     int ret;
0099     u16 dscr;
0100 
0101     if (!dscr_info || !dscr_count)
0102         return -EINVAL;
0103 
0104     for (dscr = 0; dscr < dscr_count; dscr++)
0105         configure_dma_descriptor(adata, dscr, dscr_info++);
0106 
0107     ret = config_dma_channel(adata, ch, 0, dscr_count);
0108     if (ret < 0)
0109         dev_err(sdev->dev, "config dma ch failed:%d\n", ret);
0110 
0111     return ret;
0112 }
0113 
0114 int configure_and_run_dma(struct acp_dev_data *adata, unsigned int src_addr,
0115               unsigned int dest_addr, int dsp_data_size)
0116 {
0117     struct snd_sof_dev *sdev = adata->dev;
0118     unsigned int desc_count, index;
0119     int ret;
0120 
0121     for (desc_count = 0; desc_count < ACP_MAX_DESC && dsp_data_size >= 0;
0122          desc_count++, dsp_data_size -= ACP_PAGE_SIZE) {
0123         adata->dscr_info[desc_count].src_addr = src_addr + desc_count * ACP_PAGE_SIZE;
0124         adata->dscr_info[desc_count].dest_addr = dest_addr + desc_count * ACP_PAGE_SIZE;
0125         adata->dscr_info[desc_count].tx_cnt.bits.count = ACP_PAGE_SIZE;
0126         if (dsp_data_size < ACP_PAGE_SIZE)
0127             adata->dscr_info[desc_count].tx_cnt.bits.count = dsp_data_size;
0128     }
0129 
0130     ret = acpbus_dma_start(adata, 0, desc_count, adata->dscr_info);
0131     if (ret)
0132         dev_err(sdev->dev, "acpbus_dma_start failed\n");
0133 
0134     /* Clear descriptor array */
0135     for (index = 0; index < desc_count; index++)
0136         memset(&adata->dscr_info[index], 0x00, sizeof(struct dma_descriptor));
0137 
0138     return ret;
0139 }
0140 
0141 /*
0142  * psp_mbox_ready- function to poll ready bit of psp mbox
0143  * @adata: acp device data
0144  * @ack: bool variable to check ready bit status or psp ack
0145  */
0146 
0147 static int psp_mbox_ready(struct acp_dev_data *adata, bool ack)
0148 {
0149     struct snd_sof_dev *sdev = adata->dev;
0150     int timeout;
0151     u32 data;
0152 
0153     for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
0154         msleep(20);
0155         smn_read(adata->smn_dev, MP0_C2PMSG_114_REG, &data);
0156         if (data & MBOX_READY_MASK)
0157             return 0;
0158     }
0159 
0160     dev_err(sdev->dev, "PSP error status %x\n", data & MBOX_STATUS_MASK);
0161 
0162     if (ack)
0163         return -ETIMEDOUT;
0164 
0165     return -EBUSY;
0166 }
0167 
0168 /*
0169  * psp_send_cmd - function to send psp command over mbox
0170  * @adata: acp device data
0171  * @cmd: non zero integer value for command type
0172  */
0173 
0174 static int psp_send_cmd(struct acp_dev_data *adata, int cmd)
0175 {
0176     struct snd_sof_dev *sdev = adata->dev;
0177     int ret, timeout;
0178     u32 data;
0179 
0180     if (!cmd)
0181         return -EINVAL;
0182 
0183     /* Get a non-zero Doorbell value from PSP */
0184     for (timeout = ACP_PSP_TIMEOUT_COUNTER; timeout > 0; timeout--) {
0185         msleep(MBOX_DELAY);
0186         smn_read(adata->smn_dev, MP0_C2PMSG_73_REG, &data);
0187         if (data)
0188             break;
0189     }
0190 
0191     if (!timeout) {
0192         dev_err(sdev->dev, "Failed to get Doorbell from MBOX %x\n", MP0_C2PMSG_73_REG);
0193         return -EINVAL;
0194     }
0195 
0196     /* Check if PSP is ready for new command */
0197     ret = psp_mbox_ready(adata, 0);
0198     if (ret)
0199         return ret;
0200 
0201     smn_write(adata->smn_dev, MP0_C2PMSG_114_REG, cmd);
0202 
0203     /* Ring the Doorbell for PSP */
0204     smn_write(adata->smn_dev, MP0_C2PMSG_73_REG, data);
0205 
0206     /* Check MBOX ready as PSP ack */
0207     ret = psp_mbox_ready(adata, 1);
0208 
0209     return ret;
0210 }
0211 
0212 int configure_and_run_sha_dma(struct acp_dev_data *adata, void *image_addr,
0213                   unsigned int start_addr, unsigned int dest_addr,
0214                   unsigned int image_length)
0215 {
0216     struct snd_sof_dev *sdev = adata->dev;
0217     unsigned int tx_count, fw_qualifier, val;
0218     int ret;
0219 
0220     if (!image_addr) {
0221         dev_err(sdev->dev, "SHA DMA image address is NULL\n");
0222         return -EINVAL;
0223     }
0224 
0225     val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD);
0226     if (val & ACP_SHA_RUN) {
0227         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD, ACP_SHA_RESET);
0228         ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD_STS,
0229                             val, val & ACP_SHA_RESET,
0230                             ACP_REG_POLL_INTERVAL,
0231                             ACP_REG_POLL_TIMEOUT_US);
0232         if (ret < 0) {
0233             dev_err(sdev->dev, "SHA DMA Failed to Reset\n");
0234             return ret;
0235         }
0236     }
0237 
0238     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_STRT_ADDR, start_addr);
0239     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_DESTINATION_ADDR, dest_addr);
0240     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_MSG_LENGTH, image_length);
0241     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SHA_DMA_CMD, ACP_SHA_RUN);
0242 
0243     ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SHA_TRANSFER_BYTE_CNT,
0244                         tx_count, tx_count == image_length,
0245                         ACP_REG_POLL_INTERVAL, ACP_DMA_COMPLETE_TIMEOUT_US);
0246     if (ret < 0) {
0247         dev_err(sdev->dev, "SHA DMA Failed to Transfer Length %x\n", tx_count);
0248         return ret;
0249     }
0250 
0251     ret = psp_send_cmd(adata, MBOX_ACP_SHA_DMA_COMMAND);
0252     if (ret)
0253         return ret;
0254 
0255     fw_qualifier = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_SHA_DSP_FW_QUALIFIER);
0256     if (!(fw_qualifier & DSP_FW_RUN_ENABLE)) {
0257         dev_err(sdev->dev, "PSP validation failed\n");
0258         return -EINVAL;
0259     }
0260 
0261     return 0;
0262 }
0263 
0264 int acp_dma_status(struct acp_dev_data *adata, unsigned char ch)
0265 {
0266     struct snd_sof_dev *sdev = adata->dev;
0267     unsigned int val;
0268     int ret = 0;
0269 
0270     val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DMA_CNTL_0 + ch * sizeof(u32));
0271     if (val & ACP_DMA_CH_RUN) {
0272         ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_DMA_CH_STS, val, !val,
0273                             ACP_REG_POLL_INTERVAL,
0274                             ACP_DMA_COMPLETE_TIMEOUT_US);
0275         if (ret < 0)
0276             dev_err(sdev->dev, "DMA_CHANNEL %d status timeout\n", ch);
0277     }
0278 
0279     return ret;
0280 }
0281 
0282 void memcpy_from_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *dst, size_t bytes)
0283 {
0284     unsigned int reg_offset = offset + ACP_SCRATCH_REG_0;
0285     int i, j;
0286 
0287     for (i = 0, j = 0; i < bytes; i = i + 4, j++)
0288         dst[j] = snd_sof_dsp_read(sdev, ACP_DSP_BAR, reg_offset + i);
0289 }
0290 
0291 void memcpy_to_scratch(struct snd_sof_dev *sdev, u32 offset, unsigned int *src, size_t bytes)
0292 {
0293     unsigned int reg_offset = offset + ACP_SCRATCH_REG_0;
0294     int i, j;
0295 
0296     for (i = 0, j = 0; i < bytes; i = i + 4, j++)
0297         snd_sof_dsp_write(sdev, ACP_DSP_BAR, reg_offset + i, src[j]);
0298 }
0299 
0300 static int acp_memory_init(struct snd_sof_dev *sdev)
0301 {
0302     struct acp_dev_data *adata = sdev->pdata->hw_pdata;
0303 
0304     snd_sof_dsp_update_bits(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_CNTL,
0305                 ACP_DSP_INTR_EN_MASK, ACP_DSP_INTR_EN_MASK);
0306     init_dma_descriptor(adata);
0307 
0308     return 0;
0309 }
0310 
0311 static irqreturn_t acp_irq_thread(int irq, void *context)
0312 {
0313     struct snd_sof_dev *sdev = context;
0314     unsigned int val, count = ACP_HW_SEM_RETRY_COUNT;
0315 
0316     val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT);
0317     if (val & ACP_SHA_STAT) {
0318         /* Clear SHA interrupt raised by PSP */
0319         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_EXTERNAL_INTR_STAT, val);
0320         return IRQ_HANDLED;
0321     }
0322 
0323     val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
0324     if (val & ACP_DSP_TO_HOST_IRQ) {
0325         while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0)) {
0326             /* Wait until acquired HW Semaphore lock or timeout */
0327             count--;
0328             if (!count) {
0329                 dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__);
0330                 return IRQ_NONE;
0331             }
0332         }
0333 
0334         sof_ops(sdev)->irq_thread(irq, sdev);
0335         val |= ACP_DSP_TO_HOST_IRQ;
0336         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT, val);
0337 
0338         /* Unlock or Release HW Semaphore */
0339         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_AXI2DAGB_SEM_0, 0x0);
0340 
0341         return IRQ_HANDLED;
0342     }
0343 
0344     return IRQ_NONE;
0345 };
0346 
0347 static irqreturn_t acp_irq_handler(int irq, void *dev_id)
0348 {
0349     struct snd_sof_dev *sdev = dev_id;
0350     unsigned int val;
0351 
0352     val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_DSP_SW_INTR_STAT);
0353     if (val)
0354         return IRQ_WAKE_THREAD;
0355 
0356     return IRQ_NONE;
0357 }
0358 
0359 static int acp_power_on(struct snd_sof_dev *sdev)
0360 {
0361     unsigned int val;
0362     int ret;
0363 
0364     val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, ACP_PGFSM_STATUS);
0365 
0366     if (val == ACP_POWERED_ON)
0367         return 0;
0368 
0369     if (val & ACP_PGFSM_STATUS_MASK)
0370         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_PGFSM_CONTROL,
0371                   ACP_PGFSM_CNTL_POWER_ON_MASK);
0372 
0373     ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_PGFSM_STATUS, val, !val,
0374                         ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
0375     if (ret < 0)
0376         dev_err(sdev->dev, "timeout in ACP_PGFSM_STATUS read\n");
0377 
0378     return ret;
0379 }
0380 
0381 static int acp_reset(struct snd_sof_dev *sdev)
0382 {
0383     unsigned int val;
0384     int ret;
0385 
0386     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, ACP_ASSERT_RESET);
0387 
0388     ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, val,
0389                         val & ACP_SOFT_RESET_DONE_MASK,
0390                         ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
0391     if (ret < 0) {
0392         dev_err(sdev->dev, "timeout asserting reset\n");
0393         return ret;
0394     }
0395 
0396     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, ACP_RELEASE_RESET);
0397 
0398     ret = snd_sof_dsp_read_poll_timeout(sdev, ACP_DSP_BAR, ACP_SOFT_RESET, val, !val,
0399                         ACP_REG_POLL_INTERVAL, ACP_REG_POLL_TIMEOUT_US);
0400     if (ret < 0)
0401         dev_err(sdev->dev, "timeout in releasing reset\n");
0402 
0403     return ret;
0404 }
0405 
0406 static int acp_init(struct snd_sof_dev *sdev)
0407 {
0408     int ret;
0409 
0410     /* power on */
0411     ret = acp_power_on(sdev);
0412     if (ret) {
0413         dev_err(sdev->dev, "ACP power on failed\n");
0414         return ret;
0415     }
0416 
0417     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x01);
0418     /* Reset */
0419     return acp_reset(sdev);
0420 }
0421 
0422 int amd_sof_acp_suspend(struct snd_sof_dev *sdev, u32 target_state)
0423 {
0424     int ret;
0425 
0426     ret = acp_reset(sdev);
0427     if (ret) {
0428         dev_err(sdev->dev, "ACP Reset failed\n");
0429         return ret;
0430     }
0431 
0432     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CONTROL, 0x00);
0433 
0434     return 0;
0435 }
0436 EXPORT_SYMBOL_NS(amd_sof_acp_suspend, SND_SOC_SOF_AMD_COMMON);
0437 
0438 int amd_sof_acp_resume(struct snd_sof_dev *sdev)
0439 {
0440     int ret;
0441 
0442     ret = acp_init(sdev);
0443     if (ret) {
0444         dev_err(sdev->dev, "ACP Init failed\n");
0445         return ret;
0446     }
0447 
0448     snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_CLKMUX_SEL, 0x03);
0449 
0450     ret = acp_memory_init(sdev);
0451 
0452     return ret;
0453 }
0454 EXPORT_SYMBOL_NS(amd_sof_acp_resume, SND_SOC_SOF_AMD_COMMON);
0455 
0456 int amd_sof_acp_probe(struct snd_sof_dev *sdev)
0457 {
0458     struct pci_dev *pci = to_pci_dev(sdev->dev);
0459     struct acp_dev_data *adata;
0460     const struct sof_amd_acp_desc *chip;
0461     unsigned int addr;
0462     int ret;
0463 
0464     adata = devm_kzalloc(sdev->dev, sizeof(struct acp_dev_data),
0465                  GFP_KERNEL);
0466     if (!adata)
0467         return -ENOMEM;
0468 
0469     adata->dev = sdev;
0470     addr = pci_resource_start(pci, ACP_DSP_BAR);
0471     sdev->bar[ACP_DSP_BAR] = devm_ioremap(sdev->dev, addr, pci_resource_len(pci, ACP_DSP_BAR));
0472     if (!sdev->bar[ACP_DSP_BAR]) {
0473         dev_err(sdev->dev, "ioremap error\n");
0474         return -ENXIO;
0475     }
0476 
0477     pci_set_master(pci);
0478 
0479     sdev->pdata->hw_pdata = adata;
0480 
0481     chip = get_chip_info(sdev->pdata);
0482     if (!chip) {
0483         dev_err(sdev->dev, "no such device supported, chip id:%x\n", pci->device);
0484         return -EIO;
0485     }
0486 
0487     adata->smn_dev = pci_get_device(PCI_VENDOR_ID_AMD, chip->host_bridge_id, NULL);
0488     if (!adata->smn_dev) {
0489         dev_err(sdev->dev, "Failed to get host bridge device\n");
0490         return -ENODEV;
0491     }
0492 
0493     sdev->ipc_irq = pci->irq;
0494     ret = request_threaded_irq(sdev->ipc_irq, acp_irq_handler, acp_irq_thread,
0495                    IRQF_SHARED, "AudioDSP", sdev);
0496     if (ret < 0) {
0497         dev_err(sdev->dev, "failed to register IRQ %d\n",
0498             sdev->ipc_irq);
0499         pci_dev_put(adata->smn_dev);
0500         return ret;
0501     }
0502 
0503     ret = acp_init(sdev);
0504     if (ret < 0) {
0505         free_irq(sdev->ipc_irq, sdev);
0506         pci_dev_put(adata->smn_dev);
0507         return ret;
0508     }
0509 
0510     acp_memory_init(sdev);
0511 
0512     acp_dsp_stream_init(sdev);
0513 
0514     return 0;
0515 }
0516 EXPORT_SYMBOL_NS(amd_sof_acp_probe, SND_SOC_SOF_AMD_COMMON);
0517 
0518 int amd_sof_acp_remove(struct snd_sof_dev *sdev)
0519 {
0520     struct acp_dev_data *adata = sdev->pdata->hw_pdata;
0521 
0522     if (adata->smn_dev)
0523         pci_dev_put(adata->smn_dev);
0524 
0525     if (sdev->ipc_irq)
0526         free_irq(sdev->ipc_irq, sdev);
0527 
0528     return acp_reset(sdev);
0529 }
0530 EXPORT_SYMBOL_NS(amd_sof_acp_remove, SND_SOC_SOF_AMD_COMMON);
0531 
0532 MODULE_DESCRIPTION("AMD ACP sof driver");
0533 MODULE_LICENSE("Dual BSD/GPL");