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) 2018 Intel Corporation. All rights reserved.
0007 //
0008 // Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
0009 //      Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
0010 //      Rander Wang <rander.wang@intel.com>
0011 //          Keyon Jie <yang.jie@linux.intel.com>
0012 //
0013 
0014 /*
0015  * Hardware interface for generic Intel audio DSP HDA IP
0016  */
0017 
0018 #include <linux/module.h>
0019 #include <sound/hdaudio_ext.h>
0020 #include <sound/hda_register.h>
0021 #include <sound/hda_component.h>
0022 #include "../ops.h"
0023 #include "hda.h"
0024 
0025 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0026 static int hda_codec_mask = -1;
0027 module_param_named(codec_mask, hda_codec_mask, int, 0444);
0028 MODULE_PARM_DESC(codec_mask, "SOF HDA codec mask for probing");
0029 #endif
0030 
0031 /*
0032  * HDA Operations.
0033  */
0034 
0035 int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev, bool reset)
0036 {
0037     unsigned long timeout;
0038     u32 gctl = 0;
0039     u32 val;
0040 
0041     /* 0 to enter reset and 1 to exit reset */
0042     val = reset ? 0 : SOF_HDA_GCTL_RESET;
0043 
0044     /* enter/exit HDA controller reset */
0045     snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCTL,
0046                 SOF_HDA_GCTL_RESET, val);
0047 
0048     /* wait to enter/exit reset */
0049     timeout = jiffies + msecs_to_jiffies(HDA_DSP_CTRL_RESET_TIMEOUT);
0050     while (time_before(jiffies, timeout)) {
0051         gctl = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCTL);
0052         if ((gctl & SOF_HDA_GCTL_RESET) == val)
0053             return 0;
0054         usleep_range(500, 1000);
0055     }
0056 
0057     /* enter/exit reset failed */
0058     dev_err(sdev->dev, "error: failed to %s HDA controller gctl 0x%x\n",
0059         reset ? "reset" : "ready", gctl);
0060     return -EIO;
0061 }
0062 
0063 int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev)
0064 {
0065     struct hdac_bus *bus = sof_to_bus(sdev);
0066     u32 cap, offset, feature;
0067     int count = 0;
0068     int ret;
0069 
0070     /*
0071      * On some devices, one reset cycle is necessary before reading
0072      * capabilities
0073      */
0074     ret = hda_dsp_ctrl_link_reset(sdev, true);
0075     if (ret < 0)
0076         return ret;
0077     ret = hda_dsp_ctrl_link_reset(sdev, false);
0078     if (ret < 0)
0079         return ret;
0080 
0081     offset = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_LLCH);
0082 
0083     do {
0084         dev_dbg(sdev->dev, "checking for capabilities at offset 0x%x\n",
0085             offset & SOF_HDA_CAP_NEXT_MASK);
0086 
0087         cap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, offset);
0088 
0089         if (cap == -1) {
0090             dev_dbg(bus->dev, "Invalid capability reg read\n");
0091             break;
0092         }
0093 
0094         feature = (cap & SOF_HDA_CAP_ID_MASK) >> SOF_HDA_CAP_ID_OFF;
0095 
0096         switch (feature) {
0097         case SOF_HDA_PP_CAP_ID:
0098             dev_dbg(sdev->dev, "found DSP capability at 0x%x\n",
0099                 offset);
0100             bus->ppcap = bus->remap_addr + offset;
0101             sdev->bar[HDA_DSP_PP_BAR] = bus->ppcap;
0102             break;
0103         case SOF_HDA_SPIB_CAP_ID:
0104             dev_dbg(sdev->dev, "found SPIB capability at 0x%x\n",
0105                 offset);
0106             bus->spbcap = bus->remap_addr + offset;
0107             sdev->bar[HDA_DSP_SPIB_BAR] = bus->spbcap;
0108             break;
0109         case SOF_HDA_DRSM_CAP_ID:
0110             dev_dbg(sdev->dev, "found DRSM capability at 0x%x\n",
0111                 offset);
0112             bus->drsmcap = bus->remap_addr + offset;
0113             sdev->bar[HDA_DSP_DRSM_BAR] = bus->drsmcap;
0114             break;
0115         case SOF_HDA_GTS_CAP_ID:
0116             dev_dbg(sdev->dev, "found GTS capability at 0x%x\n",
0117                 offset);
0118             bus->gtscap = bus->remap_addr + offset;
0119             break;
0120         case SOF_HDA_ML_CAP_ID:
0121             dev_dbg(sdev->dev, "found ML capability at 0x%x\n",
0122                 offset);
0123             bus->mlcap = bus->remap_addr + offset;
0124             break;
0125         default:
0126             dev_dbg(sdev->dev, "found capability %d at 0x%x\n",
0127                 feature, offset);
0128             break;
0129         }
0130 
0131         offset = cap & SOF_HDA_CAP_NEXT_MASK;
0132     } while (count++ <= SOF_HDA_MAX_CAPS && offset);
0133 
0134     return 0;
0135 }
0136 
0137 void hda_dsp_ctrl_ppcap_enable(struct snd_sof_dev *sdev, bool enable)
0138 {
0139     u32 val = enable ? SOF_HDA_PPCTL_GPROCEN : 0;
0140 
0141     snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
0142                 SOF_HDA_PPCTL_GPROCEN, val);
0143 }
0144 
0145 void hda_dsp_ctrl_ppcap_int_enable(struct snd_sof_dev *sdev, bool enable)
0146 {
0147     u32 val = enable ? SOF_HDA_PPCTL_PIE : 0;
0148 
0149     snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
0150                 SOF_HDA_PPCTL_PIE, val);
0151 }
0152 
0153 void hda_dsp_ctrl_misc_clock_gating(struct snd_sof_dev *sdev, bool enable)
0154 {
0155     u32 val = enable ? PCI_CGCTL_MISCBDCGE_MASK : 0;
0156 
0157     snd_sof_pci_update_bits(sdev, PCI_CGCTL, PCI_CGCTL_MISCBDCGE_MASK, val);
0158 }
0159 
0160 /*
0161  * enable/disable audio dsp clock gating and power gating bits.
0162  * This allows the HW to opportunistically power and clock gate
0163  * the audio dsp when it is idle
0164  */
0165 int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable)
0166 {
0167     u32 val;
0168 
0169     /* enable/disable audio dsp clock gating */
0170     val = enable ? PCI_CGCTL_ADSPDCGE : 0;
0171     snd_sof_pci_update_bits(sdev, PCI_CGCTL, PCI_CGCTL_ADSPDCGE, val);
0172 
0173     /* enable/disable DMI Link L1 support */
0174     val = enable ? HDA_VS_INTEL_EM2_L1SEN : 0;
0175     snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, HDA_VS_INTEL_EM2,
0176                 HDA_VS_INTEL_EM2_L1SEN, val);
0177 
0178     /* enable/disable audio dsp power gating */
0179     val = enable ? 0 : PCI_PGCTL_ADSPPGD;
0180     snd_sof_pci_update_bits(sdev, PCI_PGCTL, PCI_PGCTL_ADSPPGD, val);
0181 
0182     return 0;
0183 }
0184 
0185 int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
0186 {
0187     struct hdac_bus *bus = sof_to_bus(sdev);
0188 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0189     struct hdac_ext_link *hlink;
0190 #endif
0191     struct hdac_stream *stream;
0192     int sd_offset, ret = 0;
0193 
0194     if (bus->chip_init)
0195         return 0;
0196 
0197 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0198     snd_hdac_set_codec_wakeup(bus, true);
0199 #endif
0200     hda_dsp_ctrl_misc_clock_gating(sdev, false);
0201 
0202     if (full_reset) {
0203         /* reset HDA controller */
0204         ret = hda_dsp_ctrl_link_reset(sdev, true);
0205         if (ret < 0) {
0206             dev_err(sdev->dev, "error: failed to reset HDA controller\n");
0207             goto err;
0208         }
0209 
0210         usleep_range(500, 1000);
0211 
0212         /* exit HDA controller reset */
0213         ret = hda_dsp_ctrl_link_reset(sdev, false);
0214         if (ret < 0) {
0215             dev_err(sdev->dev, "error: failed to exit HDA controller reset\n");
0216             goto err;
0217         }
0218 
0219         usleep_range(1000, 1200);
0220     }
0221 
0222 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0223     /* check to see if controller is ready */
0224     if (!snd_hdac_chip_readb(bus, GCTL)) {
0225         dev_dbg(bus->dev, "controller not ready!\n");
0226         ret = -EBUSY;
0227         goto err;
0228     }
0229 
0230     /* Accept unsolicited responses */
0231     snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL);
0232 
0233     /* detect codecs */
0234     if (!bus->codec_mask) {
0235         bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS);
0236         dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask);
0237     }
0238 
0239     if (hda_codec_mask != -1) {
0240         bus->codec_mask &= hda_codec_mask;
0241         dev_dbg(bus->dev, "filtered codec_mask = 0x%lx\n",
0242             bus->codec_mask);
0243     }
0244 #endif
0245 
0246     /* clear stream status */
0247     list_for_each_entry(stream, &bus->stream_list, list) {
0248         sd_offset = SOF_STREAM_SD_OFFSET(stream);
0249         snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
0250                   sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
0251                   SOF_HDA_CL_DMA_SD_INT_MASK);
0252     }
0253 
0254     /* clear WAKESTS */
0255     snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
0256               SOF_HDA_WAKESTS_INT_MASK);
0257 
0258 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0259     /* clear rirb status */
0260     snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
0261 #endif
0262 
0263     /* clear interrupt status register */
0264     snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
0265               SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);
0266 
0267 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0268     /* initialize the codec command I/O */
0269     snd_hdac_bus_init_cmd_io(bus);
0270 #endif
0271 
0272     /* enable CIE and GIE interrupts */
0273     snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
0274                 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
0275                 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
0276 
0277     /* program the position buffer */
0278     if (bus->use_posbuf && bus->posbuf.addr) {
0279         snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
0280                   (u32)bus->posbuf.addr);
0281         snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
0282                   upper_32_bits(bus->posbuf.addr));
0283     }
0284 
0285 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0286     /* Reset stream-to-link mapping */
0287     list_for_each_entry(hlink, &bus->hlink_list, list)
0288         writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
0289 #endif
0290 
0291     bus->chip_init = true;
0292 
0293 err:
0294     hda_dsp_ctrl_misc_clock_gating(sdev, true);
0295 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0296     snd_hdac_set_codec_wakeup(bus, false);
0297 #endif
0298 
0299     return ret;
0300 }
0301 
0302 void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev)
0303 {
0304     struct hdac_bus *bus = sof_to_bus(sdev);
0305     struct hdac_stream *stream;
0306     int sd_offset;
0307 
0308     if (!bus->chip_init)
0309         return;
0310 
0311     /* disable interrupts in stream descriptor */
0312     list_for_each_entry(stream, &bus->stream_list, list) {
0313         sd_offset = SOF_STREAM_SD_OFFSET(stream);
0314         snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
0315                     sd_offset +
0316                     SOF_HDA_ADSP_REG_CL_SD_CTL,
0317                     SOF_HDA_CL_DMA_SD_INT_MASK,
0318                     0);
0319     }
0320 
0321     /* disable SIE for all streams */
0322     snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
0323                 SOF_HDA_INT_ALL_STREAM, 0);
0324 
0325     /* disable controller CIE and GIE */
0326     snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
0327                 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
0328                 0);
0329 
0330     /* clear stream status */
0331     list_for_each_entry(stream, &bus->stream_list, list) {
0332         sd_offset = SOF_STREAM_SD_OFFSET(stream);
0333         snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
0334                   sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
0335                   SOF_HDA_CL_DMA_SD_INT_MASK);
0336     }
0337 
0338     /* clear WAKESTS */
0339     snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
0340               SOF_HDA_WAKESTS_INT_MASK);
0341 
0342 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0343     /* clear rirb status */
0344     snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
0345 #endif
0346 
0347     /* clear interrupt status register */
0348     snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
0349               SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);
0350 
0351 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0352     /* disable CORB/RIRB */
0353     snd_hdac_bus_stop_cmd_io(bus);
0354 #endif
0355     /* disable position buffer */
0356     if (bus->use_posbuf && bus->posbuf.addr) {
0357         snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
0358                   SOF_HDA_ADSP_DPLBASE, 0);
0359         snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
0360                   SOF_HDA_ADSP_DPUBASE, 0);
0361     }
0362 
0363     bus->chip_init = false;
0364 }