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 "../sof-audio.h"
0022 #include "../ops.h"
0023 #include "hda.h"
0024 #include "hda-ipc.h"
0025 
0026 static bool hda_enable_trace_D0I3_S0;
0027 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG)
0028 module_param_named(enable_trace_D0I3_S0, hda_enable_trace_D0I3_S0, bool, 0444);
0029 MODULE_PARM_DESC(enable_trace_D0I3_S0,
0030          "SOF HDA enable trace when the DSP is in D0I3 in S0");
0031 #endif
0032 
0033 /*
0034  * DSP Core control.
0035  */
0036 
0037 static int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, unsigned int core_mask)
0038 {
0039     u32 adspcs;
0040     u32 reset;
0041     int ret;
0042 
0043     /* set reset bits for cores */
0044     reset = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
0045     snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
0046                      HDA_DSP_REG_ADSPCS,
0047                      reset, reset);
0048 
0049     /* poll with timeout to check if operation successful */
0050     ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
0051                     HDA_DSP_REG_ADSPCS, adspcs,
0052                     ((adspcs & reset) == reset),
0053                     HDA_DSP_REG_POLL_INTERVAL_US,
0054                     HDA_DSP_RESET_TIMEOUT_US);
0055     if (ret < 0) {
0056         dev_err(sdev->dev,
0057             "error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
0058             __func__);
0059         return ret;
0060     }
0061 
0062     /* has core entered reset ? */
0063     adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
0064                   HDA_DSP_REG_ADSPCS);
0065     if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) !=
0066         HDA_DSP_ADSPCS_CRST_MASK(core_mask)) {
0067         dev_err(sdev->dev,
0068             "error: reset enter failed: core_mask %x adspcs 0x%x\n",
0069             core_mask, adspcs);
0070         ret = -EIO;
0071     }
0072 
0073     return ret;
0074 }
0075 
0076 static int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask)
0077 {
0078     unsigned int crst;
0079     u32 adspcs;
0080     int ret;
0081 
0082     /* clear reset bits for cores */
0083     snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
0084                      HDA_DSP_REG_ADSPCS,
0085                      HDA_DSP_ADSPCS_CRST_MASK(core_mask),
0086                      0);
0087 
0088     /* poll with timeout to check if operation successful */
0089     crst = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
0090     ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
0091                         HDA_DSP_REG_ADSPCS, adspcs,
0092                         !(adspcs & crst),
0093                         HDA_DSP_REG_POLL_INTERVAL_US,
0094                         HDA_DSP_RESET_TIMEOUT_US);
0095 
0096     if (ret < 0) {
0097         dev_err(sdev->dev,
0098             "error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
0099             __func__);
0100         return ret;
0101     }
0102 
0103     /* has core left reset ? */
0104     adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
0105                   HDA_DSP_REG_ADSPCS);
0106     if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) != 0) {
0107         dev_err(sdev->dev,
0108             "error: reset leave failed: core_mask %x adspcs 0x%x\n",
0109             core_mask, adspcs);
0110         ret = -EIO;
0111     }
0112 
0113     return ret;
0114 }
0115 
0116 static int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask)
0117 {
0118     /* stall core */
0119     snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
0120                      HDA_DSP_REG_ADSPCS,
0121                      HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
0122                      HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
0123 
0124     /* set reset state */
0125     return hda_dsp_core_reset_enter(sdev, core_mask);
0126 }
0127 
0128 static bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev, unsigned int core_mask)
0129 {
0130     int val;
0131     bool is_enable;
0132 
0133     val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS);
0134 
0135 #define MASK_IS_EQUAL(v, m, field) ({   \
0136     u32 _m = field(m);      \
0137     ((v) & _m) == _m;       \
0138 })
0139 
0140     is_enable = MASK_IS_EQUAL(val, core_mask, HDA_DSP_ADSPCS_CPA_MASK) &&
0141         MASK_IS_EQUAL(val, core_mask, HDA_DSP_ADSPCS_SPA_MASK) &&
0142         !(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) &&
0143         !(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
0144 
0145 #undef MASK_IS_EQUAL
0146 
0147     dev_dbg(sdev->dev, "DSP core(s) enabled? %d : core_mask %x\n",
0148         is_enable, core_mask);
0149 
0150     return is_enable;
0151 }
0152 
0153 int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask)
0154 {
0155     int ret;
0156 
0157     /* leave reset state */
0158     ret = hda_dsp_core_reset_leave(sdev, core_mask);
0159     if (ret < 0)
0160         return ret;
0161 
0162     /* run core */
0163     dev_dbg(sdev->dev, "unstall/run core: core_mask = %x\n", core_mask);
0164     snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
0165                      HDA_DSP_REG_ADSPCS,
0166                      HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
0167                      0);
0168 
0169     /* is core now running ? */
0170     if (!hda_dsp_core_is_enabled(sdev, core_mask)) {
0171         hda_dsp_core_stall_reset(sdev, core_mask);
0172         dev_err(sdev->dev, "error: DSP start core failed: core_mask %x\n",
0173             core_mask);
0174         ret = -EIO;
0175     }
0176 
0177     return ret;
0178 }
0179 
0180 /*
0181  * Power Management.
0182  */
0183 
0184 int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
0185 {
0186     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0187     const struct sof_intel_dsp_desc *chip = hda->desc;
0188     unsigned int cpa;
0189     u32 adspcs;
0190     int ret;
0191 
0192     /* restrict core_mask to host managed cores mask */
0193     core_mask &= chip->host_managed_cores_mask;
0194     /* return if core_mask is not valid */
0195     if (!core_mask)
0196         return 0;
0197 
0198     /* update bits */
0199     snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS,
0200                 HDA_DSP_ADSPCS_SPA_MASK(core_mask),
0201                 HDA_DSP_ADSPCS_SPA_MASK(core_mask));
0202 
0203     /* poll with timeout to check if operation successful */
0204     cpa = HDA_DSP_ADSPCS_CPA_MASK(core_mask);
0205     ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
0206                         HDA_DSP_REG_ADSPCS, adspcs,
0207                         (adspcs & cpa) == cpa,
0208                         HDA_DSP_REG_POLL_INTERVAL_US,
0209                         HDA_DSP_RESET_TIMEOUT_US);
0210     if (ret < 0) {
0211         dev_err(sdev->dev,
0212             "error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
0213             __func__);
0214         return ret;
0215     }
0216 
0217     /* did core power up ? */
0218     adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
0219                   HDA_DSP_REG_ADSPCS);
0220     if ((adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) !=
0221         HDA_DSP_ADSPCS_CPA_MASK(core_mask)) {
0222         dev_err(sdev->dev,
0223             "error: power up core failed core_mask %xadspcs 0x%x\n",
0224             core_mask, adspcs);
0225         ret = -EIO;
0226     }
0227 
0228     return ret;
0229 }
0230 
0231 static int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask)
0232 {
0233     u32 adspcs;
0234     int ret;
0235 
0236     /* update bits */
0237     snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
0238                      HDA_DSP_REG_ADSPCS,
0239                      HDA_DSP_ADSPCS_SPA_MASK(core_mask), 0);
0240 
0241     ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
0242                 HDA_DSP_REG_ADSPCS, adspcs,
0243                 !(adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)),
0244                 HDA_DSP_REG_POLL_INTERVAL_US,
0245                 HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC);
0246     if (ret < 0)
0247         dev_err(sdev->dev,
0248             "error: %s: timeout on HDA_DSP_REG_ADSPCS read\n",
0249             __func__);
0250 
0251     return ret;
0252 }
0253 
0254 int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
0255 {
0256     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0257     const struct sof_intel_dsp_desc *chip = hda->desc;
0258     int ret;
0259 
0260     /* restrict core_mask to host managed cores mask */
0261     core_mask &= chip->host_managed_cores_mask;
0262 
0263     /* return if core_mask is not valid or cores are already enabled */
0264     if (!core_mask || hda_dsp_core_is_enabled(sdev, core_mask))
0265         return 0;
0266 
0267     /* power up */
0268     ret = hda_dsp_core_power_up(sdev, core_mask);
0269     if (ret < 0) {
0270         dev_err(sdev->dev, "error: dsp core power up failed: core_mask %x\n",
0271             core_mask);
0272         return ret;
0273     }
0274 
0275     return hda_dsp_core_run(sdev, core_mask);
0276 }
0277 
0278 int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
0279                   unsigned int core_mask)
0280 {
0281     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0282     const struct sof_intel_dsp_desc *chip = hda->desc;
0283     int ret;
0284 
0285     /* restrict core_mask to host managed cores mask */
0286     core_mask &= chip->host_managed_cores_mask;
0287 
0288     /* return if core_mask is not valid */
0289     if (!core_mask)
0290         return 0;
0291 
0292     /* place core in reset prior to power down */
0293     ret = hda_dsp_core_stall_reset(sdev, core_mask);
0294     if (ret < 0) {
0295         dev_err(sdev->dev, "error: dsp core reset failed: core_mask %x\n",
0296             core_mask);
0297         return ret;
0298     }
0299 
0300     /* power down core */
0301     ret = hda_dsp_core_power_down(sdev, core_mask);
0302     if (ret < 0) {
0303         dev_err(sdev->dev, "error: dsp core power down fail mask %x: %d\n",
0304             core_mask, ret);
0305         return ret;
0306     }
0307 
0308     /* make sure we are in OFF state */
0309     if (hda_dsp_core_is_enabled(sdev, core_mask)) {
0310         dev_err(sdev->dev, "error: dsp core disable fail mask %x: %d\n",
0311             core_mask, ret);
0312         ret = -EIO;
0313     }
0314 
0315     return ret;
0316 }
0317 
0318 void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev)
0319 {
0320     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0321     const struct sof_intel_dsp_desc *chip = hda->desc;
0322 
0323     /* enable IPC DONE and BUSY interrupts */
0324     snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
0325             HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY,
0326             HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY);
0327 
0328     /* enable IPC interrupt */
0329     snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
0330                 HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC);
0331 }
0332 
0333 void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
0334 {
0335     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0336     const struct sof_intel_dsp_desc *chip = hda->desc;
0337 
0338     /* disable IPC interrupt */
0339     snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
0340                 HDA_DSP_ADSPIC_IPC, 0);
0341 
0342     /* disable IPC BUSY and DONE interrupt */
0343     snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
0344             HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0);
0345 }
0346 
0347 static int hda_dsp_wait_d0i3c_done(struct snd_sof_dev *sdev)
0348 {
0349     struct hdac_bus *bus = sof_to_bus(sdev);
0350     int retry = HDA_DSP_REG_POLL_RETRY_COUNT;
0351 
0352     while (snd_hdac_chip_readb(bus, VS_D0I3C) & SOF_HDA_VS_D0I3C_CIP) {
0353         if (!retry--)
0354             return -ETIMEDOUT;
0355         usleep_range(10, 15);
0356     }
0357 
0358     return 0;
0359 }
0360 
0361 static int hda_dsp_send_pm_gate_ipc(struct snd_sof_dev *sdev, u32 flags)
0362 {
0363     struct sof_ipc_pm_gate pm_gate;
0364     struct sof_ipc_reply reply;
0365 
0366     memset(&pm_gate, 0, sizeof(pm_gate));
0367 
0368     /* configure pm_gate ipc message */
0369     pm_gate.hdr.size = sizeof(pm_gate);
0370     pm_gate.hdr.cmd = SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE;
0371     pm_gate.flags = flags;
0372 
0373     /* send pm_gate ipc to dsp */
0374     return sof_ipc_tx_message_no_pm(sdev->ipc, &pm_gate, sizeof(pm_gate),
0375                     &reply, sizeof(reply));
0376 }
0377 
0378 static int hda_dsp_update_d0i3c_register(struct snd_sof_dev *sdev, u8 value)
0379 {
0380     struct hdac_bus *bus = sof_to_bus(sdev);
0381     int ret;
0382 
0383     /* Write to D0I3C after Command-In-Progress bit is cleared */
0384     ret = hda_dsp_wait_d0i3c_done(sdev);
0385     if (ret < 0) {
0386         dev_err(bus->dev, "CIP timeout before D0I3C update!\n");
0387         return ret;
0388     }
0389 
0390     /* Update D0I3C register */
0391     snd_hdac_chip_updateb(bus, VS_D0I3C, SOF_HDA_VS_D0I3C_I3, value);
0392 
0393     /* Wait for cmd in progress to be cleared before exiting the function */
0394     ret = hda_dsp_wait_d0i3c_done(sdev);
0395     if (ret < 0) {
0396         dev_err(bus->dev, "CIP timeout after D0I3C update!\n");
0397         return ret;
0398     }
0399 
0400     dev_vdbg(bus->dev, "D0I3C updated, register = 0x%x\n",
0401          snd_hdac_chip_readb(bus, VS_D0I3C));
0402 
0403     return 0;
0404 }
0405 
0406 static int hda_dsp_set_D0_state(struct snd_sof_dev *sdev,
0407                 const struct sof_dsp_power_state *target_state)
0408 {
0409     u32 flags = 0;
0410     int ret;
0411     u8 value = 0;
0412 
0413     /*
0414      * Sanity check for illegal state transitions
0415      * The only allowed transitions are:
0416      * 1. D3 -> D0I0
0417      * 2. D0I0 -> D0I3
0418      * 3. D0I3 -> D0I0
0419      */
0420     switch (sdev->dsp_power_state.state) {
0421     case SOF_DSP_PM_D0:
0422         /* Follow the sequence below for D0 substate transitions */
0423         break;
0424     case SOF_DSP_PM_D3:
0425         /* Follow regular flow for D3 -> D0 transition */
0426         return 0;
0427     default:
0428         dev_err(sdev->dev, "error: transition from %d to %d not allowed\n",
0429             sdev->dsp_power_state.state, target_state->state);
0430         return -EINVAL;
0431     }
0432 
0433     /* Set flags and register value for D0 target substate */
0434     if (target_state->substate == SOF_HDA_DSP_PM_D0I3) {
0435         value = SOF_HDA_VS_D0I3C_I3;
0436 
0437         /*
0438          * Trace DMA need to be disabled when the DSP enters
0439          * D0I3 for S0Ix suspend, but it can be kept enabled
0440          * when the DSP enters D0I3 while the system is in S0
0441          * for debug purpose.
0442          */
0443         if (!sdev->fw_trace_is_supported ||
0444             !hda_enable_trace_D0I3_S0 ||
0445             sdev->system_suspend_target != SOF_SUSPEND_NONE)
0446             flags = HDA_PM_NO_DMA_TRACE;
0447     } else {
0448         /* prevent power gating in D0I0 */
0449         flags = HDA_PM_PPG;
0450     }
0451 
0452     /* update D0I3C register */
0453     ret = hda_dsp_update_d0i3c_register(sdev, value);
0454     if (ret < 0)
0455         return ret;
0456 
0457     /*
0458      * Notify the DSP of the state change.
0459      * If this IPC fails, revert the D0I3C register update in order
0460      * to prevent partial state change.
0461      */
0462     ret = hda_dsp_send_pm_gate_ipc(sdev, flags);
0463     if (ret < 0) {
0464         dev_err(sdev->dev,
0465             "error: PM_GATE ipc error %d\n", ret);
0466         goto revert;
0467     }
0468 
0469     return ret;
0470 
0471 revert:
0472     /* fallback to the previous register value */
0473     value = value ? 0 : SOF_HDA_VS_D0I3C_I3;
0474 
0475     /*
0476      * This can fail but return the IPC error to signal that
0477      * the state change failed.
0478      */
0479     hda_dsp_update_d0i3c_register(sdev, value);
0480 
0481     return ret;
0482 }
0483 
0484 /* helper to log DSP state */
0485 static void hda_dsp_state_log(struct snd_sof_dev *sdev)
0486 {
0487     switch (sdev->dsp_power_state.state) {
0488     case SOF_DSP_PM_D0:
0489         switch (sdev->dsp_power_state.substate) {
0490         case SOF_HDA_DSP_PM_D0I0:
0491             dev_dbg(sdev->dev, "Current DSP power state: D0I0\n");
0492             break;
0493         case SOF_HDA_DSP_PM_D0I3:
0494             dev_dbg(sdev->dev, "Current DSP power state: D0I3\n");
0495             break;
0496         default:
0497             dev_dbg(sdev->dev, "Unknown DSP D0 substate: %d\n",
0498                 sdev->dsp_power_state.substate);
0499             break;
0500         }
0501         break;
0502     case SOF_DSP_PM_D1:
0503         dev_dbg(sdev->dev, "Current DSP power state: D1\n");
0504         break;
0505     case SOF_DSP_PM_D2:
0506         dev_dbg(sdev->dev, "Current DSP power state: D2\n");
0507         break;
0508     case SOF_DSP_PM_D3:
0509         dev_dbg(sdev->dev, "Current DSP power state: D3\n");
0510         break;
0511     default:
0512         dev_dbg(sdev->dev, "Unknown DSP power state: %d\n",
0513             sdev->dsp_power_state.state);
0514         break;
0515     }
0516 }
0517 
0518 /*
0519  * All DSP power state transitions are initiated by the driver.
0520  * If the requested state change fails, the error is simply returned.
0521  * Further state transitions are attempted only when the set_power_save() op
0522  * is called again either because of a new IPC sent to the DSP or
0523  * during system suspend/resume.
0524  */
0525 int hda_dsp_set_power_state(struct snd_sof_dev *sdev,
0526                 const struct sof_dsp_power_state *target_state)
0527 {
0528     int ret = 0;
0529 
0530     /*
0531      * When the DSP is already in D0I3 and the target state is D0I3,
0532      * it could be the case that the DSP is in D0I3 during S0
0533      * and the system is suspending to S0Ix. Therefore,
0534      * hda_dsp_set_D0_state() must be called to disable trace DMA
0535      * by sending the PM_GATE IPC to the FW.
0536      */
0537     if (target_state->substate == SOF_HDA_DSP_PM_D0I3 &&
0538         sdev->system_suspend_target == SOF_SUSPEND_S0IX)
0539         goto set_state;
0540 
0541     /*
0542      * For all other cases, return without doing anything if
0543      * the DSP is already in the target state.
0544      */
0545     if (target_state->state == sdev->dsp_power_state.state &&
0546         target_state->substate == sdev->dsp_power_state.substate)
0547         return 0;
0548 
0549 set_state:
0550     switch (target_state->state) {
0551     case SOF_DSP_PM_D0:
0552         ret = hda_dsp_set_D0_state(sdev, target_state);
0553         break;
0554     case SOF_DSP_PM_D3:
0555         /* The only allowed transition is: D0I0 -> D3 */
0556         if (sdev->dsp_power_state.state == SOF_DSP_PM_D0 &&
0557             sdev->dsp_power_state.substate == SOF_HDA_DSP_PM_D0I0)
0558             break;
0559 
0560         dev_err(sdev->dev,
0561             "error: transition from %d to %d not allowed\n",
0562             sdev->dsp_power_state.state, target_state->state);
0563         return -EINVAL;
0564     default:
0565         dev_err(sdev->dev, "error: target state unsupported %d\n",
0566             target_state->state);
0567         return -EINVAL;
0568     }
0569     if (ret < 0) {
0570         dev_err(sdev->dev,
0571             "failed to set requested target DSP state %d substate %d\n",
0572             target_state->state, target_state->substate);
0573         return ret;
0574     }
0575 
0576     sdev->dsp_power_state = *target_state;
0577     hda_dsp_state_log(sdev);
0578     return ret;
0579 }
0580 
0581 /*
0582  * Audio DSP states may transform as below:-
0583  *
0584  *                                         Opportunistic D0I3 in S0
0585  *     Runtime    +---------------------+  Delayed D0i3 work timeout
0586  *     suspend    |                     +--------------------+
0587  *   +------------+       D0I0(active)  |                    |
0588  *   |            |                     <---------------+    |
0589  *   |   +-------->                     |    New IPC    |    |
0590  *   |   |Runtime +--^--+---------^--+--+ (via mailbox) |    |
0591  *   |   |resume     |  |         |  |          |    |
0592  *   |   |           |  |         |  |          |    |
0593  *   |   |     System|  |         |  |          |    |
0594  *   |   |     resume|  | S3/S0IX |  |                  |    |
0595  *   |   |       |  | suspend |  | S0IX             |    |
0596  *   |   |           |  |         |  |suspend           |    |
0597  *   |   |           |  |         |  |                  |    |
0598  *   |   |           |  |         |  |                  |    |
0599  * +-v---+-----------+--v-------+ |  |           +------+----v----+
0600  * |                            | |  +----------->                |
0601  * |       D3 (suspended)       | |              |      D0I3      |
0602  * |                            | +--------------+                |
0603  * |                            |  System resume |                |
0604  * +----------------------------+        +----------------+
0605  *
0606  * S0IX suspend: The DSP is in D0I3 if any D0I3-compatible streams
0607  *       ignored the suspend trigger. Otherwise the DSP
0608  *       is in D3.
0609  */
0610 
0611 static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
0612 {
0613     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0614     const struct sof_intel_dsp_desc *chip = hda->desc;
0615 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0616     struct hdac_bus *bus = sof_to_bus(sdev);
0617 #endif
0618     int ret, j;
0619 
0620     /*
0621      * The memory used for IMR boot loses its content in deeper than S3 state
0622      * We must not try IMR boot on next power up (as it will fail).
0623      */
0624     if (sdev->system_suspend_target > SOF_SUSPEND_S3)
0625         hda->skip_imr_boot = true;
0626 
0627     hda_sdw_int_enable(sdev, false);
0628 
0629     /* disable IPC interrupts */
0630     hda_dsp_ipc_int_disable(sdev);
0631 
0632 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0633     hda_codec_jack_wake_enable(sdev, runtime_suspend);
0634 
0635     /* power down all hda link */
0636     snd_hdac_ext_bus_link_power_down_all(bus);
0637 #endif
0638 
0639     /* power down DSP */
0640     ret = hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask);
0641     if (ret < 0) {
0642         dev_err(sdev->dev,
0643             "error: failed to power down core during suspend\n");
0644         return ret;
0645     }
0646 
0647     /* reset ref counts for all cores */
0648     for (j = 0; j < chip->cores_num; j++)
0649         sdev->dsp_core_ref_count[j] = 0;
0650 
0651     /* disable ppcap interrupt */
0652     hda_dsp_ctrl_ppcap_enable(sdev, false);
0653     hda_dsp_ctrl_ppcap_int_enable(sdev, false);
0654 
0655     /* disable hda bus irq and streams */
0656     hda_dsp_ctrl_stop_chip(sdev);
0657 
0658     /* disable LP retention mode */
0659     snd_sof_pci_update_bits(sdev, PCI_PGCTL,
0660                 PCI_PGCTL_LSRMD_MASK, PCI_PGCTL_LSRMD_MASK);
0661 
0662     /* reset controller */
0663     ret = hda_dsp_ctrl_link_reset(sdev, true);
0664     if (ret < 0) {
0665         dev_err(sdev->dev,
0666             "error: failed to reset controller during suspend\n");
0667         return ret;
0668     }
0669 
0670     /* display codec can powered off after link reset */
0671     hda_codec_i915_display_power(sdev, false);
0672 
0673     return 0;
0674 }
0675 
0676 static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
0677 {
0678 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0679     struct hdac_bus *bus = sof_to_bus(sdev);
0680     struct hdac_ext_link *hlink = NULL;
0681 #endif
0682     int ret;
0683 
0684     /* display codec must be powered before link reset */
0685     hda_codec_i915_display_power(sdev, true);
0686 
0687     /*
0688      * clear TCSEL to clear playback on some HD Audio
0689      * codecs. PCI TCSEL is defined in the Intel manuals.
0690      */
0691     snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
0692 
0693     /* reset and start hda controller */
0694     ret = hda_dsp_ctrl_init_chip(sdev, true);
0695     if (ret < 0) {
0696         dev_err(sdev->dev,
0697             "error: failed to start controller after resume\n");
0698         goto cleanup;
0699     }
0700 
0701 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0702     /* check jack status */
0703     if (runtime_resume) {
0704         hda_codec_jack_wake_enable(sdev, false);
0705         if (sdev->system_suspend_target == SOF_SUSPEND_NONE)
0706             hda_codec_jack_check(sdev);
0707     }
0708 
0709     /* turn off the links that were off before suspend */
0710     list_for_each_entry(hlink, &bus->hlink_list, list) {
0711         if (!hlink->ref_count)
0712             snd_hdac_ext_bus_link_power_down(hlink);
0713     }
0714 
0715     /* check dma status and clean up CORB/RIRB buffers */
0716     if (!bus->cmd_dma_state)
0717         snd_hdac_bus_stop_cmd_io(bus);
0718 #endif
0719 
0720     /* enable ppcap interrupt */
0721     hda_dsp_ctrl_ppcap_enable(sdev, true);
0722     hda_dsp_ctrl_ppcap_int_enable(sdev, true);
0723 
0724 cleanup:
0725     /* display codec can powered off after controller init */
0726     hda_codec_i915_display_power(sdev, false);
0727 
0728     return 0;
0729 }
0730 
0731 int hda_dsp_resume(struct snd_sof_dev *sdev)
0732 {
0733     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0734     struct pci_dev *pci = to_pci_dev(sdev->dev);
0735     const struct sof_dsp_power_state target_state = {
0736         .state = SOF_DSP_PM_D0,
0737         .substate = SOF_HDA_DSP_PM_D0I0,
0738     };
0739 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0740     struct hdac_bus *bus = sof_to_bus(sdev);
0741     struct hdac_ext_link *hlink = NULL;
0742 #endif
0743     int ret;
0744 
0745     /* resume from D0I3 */
0746     if (sdev->dsp_power_state.state == SOF_DSP_PM_D0) {
0747 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0748         /* power up links that were active before suspend */
0749         list_for_each_entry(hlink, &bus->hlink_list, list) {
0750             if (hlink->ref_count) {
0751                 ret = snd_hdac_ext_bus_link_power_up(hlink);
0752                 if (ret < 0) {
0753                     dev_err(sdev->dev,
0754                         "error %d in %s: failed to power up links",
0755                         ret, __func__);
0756                     return ret;
0757                 }
0758             }
0759         }
0760 
0761         /* set up CORB/RIRB buffers if was on before suspend */
0762         if (bus->cmd_dma_state)
0763             snd_hdac_bus_init_cmd_io(bus);
0764 #endif
0765 
0766         /* Set DSP power state */
0767         ret = snd_sof_dsp_set_power_state(sdev, &target_state);
0768         if (ret < 0) {
0769             dev_err(sdev->dev, "error: setting dsp state %d substate %d\n",
0770                 target_state.state, target_state.substate);
0771             return ret;
0772         }
0773 
0774         /* restore L1SEN bit */
0775         if (hda->l1_support_changed)
0776             snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
0777                         HDA_VS_INTEL_EM2,
0778                         HDA_VS_INTEL_EM2_L1SEN, 0);
0779 
0780         /* restore and disable the system wakeup */
0781         pci_restore_state(pci);
0782         disable_irq_wake(pci->irq);
0783         return 0;
0784     }
0785 
0786     /* init hda controller. DSP cores will be powered up during fw boot */
0787     ret = hda_resume(sdev, false);
0788     if (ret < 0)
0789         return ret;
0790 
0791     return snd_sof_dsp_set_power_state(sdev, &target_state);
0792 }
0793 
0794 int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
0795 {
0796     const struct sof_dsp_power_state target_state = {
0797         .state = SOF_DSP_PM_D0,
0798     };
0799     int ret;
0800 
0801     /* init hda controller. DSP cores will be powered up during fw boot */
0802     ret = hda_resume(sdev, true);
0803     if (ret < 0)
0804         return ret;
0805 
0806     return snd_sof_dsp_set_power_state(sdev, &target_state);
0807 }
0808 
0809 int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
0810 {
0811     struct hdac_bus *hbus = sof_to_bus(sdev);
0812 
0813     if (hbus->codec_powered) {
0814         dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n",
0815             (unsigned int)hbus->codec_powered);
0816         return -EBUSY;
0817     }
0818 
0819     return 0;
0820 }
0821 
0822 int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
0823 {
0824     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0825     const struct sof_dsp_power_state target_state = {
0826         .state = SOF_DSP_PM_D3,
0827     };
0828     int ret;
0829 
0830     /* cancel any attempt for DSP D0I3 */
0831     cancel_delayed_work_sync(&hda->d0i3_work);
0832 
0833     /* stop hda controller and power dsp off */
0834     ret = hda_suspend(sdev, true);
0835     if (ret < 0)
0836         return ret;
0837 
0838     return snd_sof_dsp_set_power_state(sdev, &target_state);
0839 }
0840 
0841 int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
0842 {
0843     struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
0844     struct hdac_bus *bus = sof_to_bus(sdev);
0845     struct pci_dev *pci = to_pci_dev(sdev->dev);
0846     const struct sof_dsp_power_state target_dsp_state = {
0847         .state = target_state,
0848         .substate = target_state == SOF_DSP_PM_D0 ?
0849                 SOF_HDA_DSP_PM_D0I3 : 0,
0850     };
0851     int ret;
0852 
0853     /* cancel any attempt for DSP D0I3 */
0854     cancel_delayed_work_sync(&hda->d0i3_work);
0855 
0856     if (target_state == SOF_DSP_PM_D0) {
0857         /* Set DSP power state */
0858         ret = snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
0859         if (ret < 0) {
0860             dev_err(sdev->dev, "error: setting dsp state %d substate %d\n",
0861                 target_dsp_state.state,
0862                 target_dsp_state.substate);
0863             return ret;
0864         }
0865 
0866         /* enable L1SEN to make sure the system can enter S0Ix */
0867         hda->l1_support_changed =
0868             snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
0869                         HDA_VS_INTEL_EM2,
0870                         HDA_VS_INTEL_EM2_L1SEN,
0871                         HDA_VS_INTEL_EM2_L1SEN);
0872 
0873 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
0874         /* stop the CORB/RIRB DMA if it is On */
0875         if (bus->cmd_dma_state)
0876             snd_hdac_bus_stop_cmd_io(bus);
0877 
0878         /* no link can be powered in s0ix state */
0879         ret = snd_hdac_ext_bus_link_power_down_all(bus);
0880         if (ret < 0) {
0881             dev_err(sdev->dev,
0882                 "error %d in %s: failed to power down links",
0883                 ret, __func__);
0884             return ret;
0885         }
0886 #endif
0887 
0888         /* enable the system waking up via IPC IRQ */
0889         enable_irq_wake(pci->irq);
0890         pci_save_state(pci);
0891         return 0;
0892     }
0893 
0894     /* stop hda controller and power dsp off */
0895     ret = hda_suspend(sdev, false);
0896     if (ret < 0) {
0897         dev_err(bus->dev, "error: suspending dsp\n");
0898         return ret;
0899     }
0900 
0901     return snd_sof_dsp_set_power_state(sdev, &target_dsp_state);
0902 }
0903 
0904 int hda_dsp_shutdown(struct snd_sof_dev *sdev)
0905 {
0906     sdev->system_suspend_target = SOF_SUSPEND_S3;
0907     return snd_sof_suspend(sdev->dev);
0908 }
0909 
0910 int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
0911 {
0912     int ret;
0913 
0914     /* make sure all DAI resources are freed */
0915     ret = hda_dsp_dais_suspend(sdev);
0916     if (ret < 0)
0917         dev_warn(sdev->dev, "%s: failure in hda_dsp_dais_suspend\n", __func__);
0918 
0919     return ret;
0920 }
0921 
0922 void hda_dsp_d0i3_work(struct work_struct *work)
0923 {
0924     struct sof_intel_hda_dev *hdev = container_of(work,
0925                               struct sof_intel_hda_dev,
0926                               d0i3_work.work);
0927     struct hdac_bus *bus = &hdev->hbus.core;
0928     struct snd_sof_dev *sdev = dev_get_drvdata(bus->dev);
0929     struct sof_dsp_power_state target_state = {
0930         .state = SOF_DSP_PM_D0,
0931         .substate = SOF_HDA_DSP_PM_D0I3,
0932     };
0933     int ret;
0934 
0935     /* DSP can enter D0I3 iff only D0I3-compatible streams are active */
0936     if (!snd_sof_dsp_only_d0i3_compatible_stream_active(sdev))
0937         /* remain in D0I0 */
0938         return;
0939 
0940     /* This can fail but error cannot be propagated */
0941     ret = snd_sof_dsp_set_power_state(sdev, &target_state);
0942     if (ret < 0)
0943         dev_err_ratelimited(sdev->dev,
0944                     "error: failed to set DSP state %d substate %d\n",
0945                     target_state.state, target_state.substate);
0946 }
0947 
0948 int hda_dsp_core_get(struct snd_sof_dev *sdev, int core)
0949 {
0950     const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm;
0951     int ret, ret1;
0952 
0953     /* power up core */
0954     ret = hda_dsp_enable_core(sdev, BIT(core));
0955     if (ret < 0) {
0956         dev_err(sdev->dev, "failed to power up core %d with err: %d\n",
0957             core, ret);
0958         return ret;
0959     }
0960 
0961     /* No need to send IPC for primary core or if FW boot is not complete */
0962     if (sdev->fw_state != SOF_FW_BOOT_COMPLETE || core == SOF_DSP_PRIMARY_CORE)
0963         return 0;
0964 
0965     /* No need to continue the set_core_state ops is not available */
0966     if (!pm_ops->set_core_state)
0967         return 0;
0968 
0969     /* Now notify DSP for secondary cores */
0970     ret = pm_ops->set_core_state(sdev, core, true);
0971     if (ret < 0) {
0972         dev_err(sdev->dev, "failed to enable secondary core '%d' failed with %d\n",
0973             core, ret);
0974         goto power_down;
0975     }
0976 
0977     return ret;
0978 
0979 power_down:
0980     /* power down core if it is host managed and return the original error if this fails too */
0981     ret1 = hda_dsp_core_reset_power_down(sdev, BIT(core));
0982     if (ret1 < 0)
0983         dev_err(sdev->dev, "failed to power down core: %d with err: %d\n", core, ret1);
0984 
0985     return ret;
0986 }