linux/sound/soc/sof/intel/hda-dsp.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
   2//
   3// This file is provided under a dual BSD/GPLv2 license.  When using or
   4// redistributing this file, you may do so under either license.
   5//
   6// Copyright(c) 2018 Intel Corporation. All rights reserved.
   7//
   8// Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
   9//          Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
  10//          Rander Wang <rander.wang@intel.com>
  11//          Keyon Jie <yang.jie@linux.intel.com>
  12//
  13
  14/*
  15 * Hardware interface for generic Intel audio DSP HDA IP
  16 */
  17
  18#include <sound/hdaudio_ext.h>
  19#include <sound/hda_register.h>
  20#include "../ops.h"
  21#include "hda.h"
  22
  23/*
  24 * DSP Core control.
  25 */
  26
  27int hda_dsp_core_reset_enter(struct snd_sof_dev *sdev, unsigned int core_mask)
  28{
  29        u32 adspcs;
  30        u32 reset;
  31        int ret;
  32
  33        /* set reset bits for cores */
  34        reset = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
  35        snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
  36                                         HDA_DSP_REG_ADSPCS,
  37                                         reset, reset),
  38
  39        /* poll with timeout to check if operation successful */
  40        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
  41                                        HDA_DSP_REG_ADSPCS, adspcs,
  42                                        ((adspcs & reset) == reset),
  43                                        HDA_DSP_REG_POLL_INTERVAL_US,
  44                                        HDA_DSP_RESET_TIMEOUT_US);
  45
  46        /* has core entered reset ? */
  47        adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
  48                                  HDA_DSP_REG_ADSPCS);
  49        if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) !=
  50                HDA_DSP_ADSPCS_CRST_MASK(core_mask)) {
  51                dev_err(sdev->dev,
  52                        "error: reset enter failed: core_mask %x adspcs 0x%x\n",
  53                        core_mask, adspcs);
  54                ret = -EIO;
  55        }
  56
  57        return ret;
  58}
  59
  60int hda_dsp_core_reset_leave(struct snd_sof_dev *sdev, unsigned int core_mask)
  61{
  62        unsigned int crst;
  63        u32 adspcs;
  64        int ret;
  65
  66        /* clear reset bits for cores */
  67        snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
  68                                         HDA_DSP_REG_ADSPCS,
  69                                         HDA_DSP_ADSPCS_CRST_MASK(core_mask),
  70                                         0);
  71
  72        /* poll with timeout to check if operation successful */
  73        crst = HDA_DSP_ADSPCS_CRST_MASK(core_mask);
  74        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
  75                                            HDA_DSP_REG_ADSPCS, adspcs,
  76                                            !(adspcs & crst),
  77                                            HDA_DSP_REG_POLL_INTERVAL_US,
  78                                            HDA_DSP_RESET_TIMEOUT_US);
  79
  80        /* has core left reset ? */
  81        adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
  82                                  HDA_DSP_REG_ADSPCS);
  83        if ((adspcs & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) != 0) {
  84                dev_err(sdev->dev,
  85                        "error: reset leave failed: core_mask %x adspcs 0x%x\n",
  86                        core_mask, adspcs);
  87                ret = -EIO;
  88        }
  89
  90        return ret;
  91}
  92
  93int hda_dsp_core_stall_reset(struct snd_sof_dev *sdev, unsigned int core_mask)
  94{
  95        /* stall core */
  96        snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
  97                                         HDA_DSP_REG_ADSPCS,
  98                                         HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
  99                                         HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
 100
 101        /* set reset state */
 102        return hda_dsp_core_reset_enter(sdev, core_mask);
 103}
 104
 105int hda_dsp_core_run(struct snd_sof_dev *sdev, unsigned int core_mask)
 106{
 107        int ret;
 108
 109        /* leave reset state */
 110        ret = hda_dsp_core_reset_leave(sdev, core_mask);
 111        if (ret < 0)
 112                return ret;
 113
 114        /* run core */
 115        dev_dbg(sdev->dev, "unstall/run core: core_mask = %x\n", core_mask);
 116        snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
 117                                         HDA_DSP_REG_ADSPCS,
 118                                         HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
 119                                         0);
 120
 121        /* is core now running ? */
 122        if (!hda_dsp_core_is_enabled(sdev, core_mask)) {
 123                hda_dsp_core_stall_reset(sdev, core_mask);
 124                dev_err(sdev->dev, "error: DSP start core failed: core_mask %x\n",
 125                        core_mask);
 126                ret = -EIO;
 127        }
 128
 129        return ret;
 130}
 131
 132/*
 133 * Power Management.
 134 */
 135
 136int hda_dsp_core_power_up(struct snd_sof_dev *sdev, unsigned int core_mask)
 137{
 138        unsigned int cpa;
 139        u32 adspcs;
 140        int ret;
 141
 142        /* update bits */
 143        snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS,
 144                                HDA_DSP_ADSPCS_SPA_MASK(core_mask),
 145                                HDA_DSP_ADSPCS_SPA_MASK(core_mask));
 146
 147        /* poll with timeout to check if operation successful */
 148        cpa = HDA_DSP_ADSPCS_CPA_MASK(core_mask);
 149        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
 150                                            HDA_DSP_REG_ADSPCS, adspcs,
 151                                            (adspcs & cpa) == cpa,
 152                                            HDA_DSP_REG_POLL_INTERVAL_US,
 153                                            HDA_DSP_RESET_TIMEOUT_US);
 154        if (ret < 0)
 155                dev_err(sdev->dev, "error: timeout on core powerup\n");
 156
 157        /* did core power up ? */
 158        adspcs = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
 159                                  HDA_DSP_REG_ADSPCS);
 160        if ((adspcs & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) !=
 161                HDA_DSP_ADSPCS_CPA_MASK(core_mask)) {
 162                dev_err(sdev->dev,
 163                        "error: power up core failed core_mask %xadspcs 0x%x\n",
 164                        core_mask, adspcs);
 165                ret = -EIO;
 166        }
 167
 168        return ret;
 169}
 170
 171int hda_dsp_core_power_down(struct snd_sof_dev *sdev, unsigned int core_mask)
 172{
 173        u32 adspcs;
 174
 175        /* update bits */
 176        snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
 177                                         HDA_DSP_REG_ADSPCS,
 178                                         HDA_DSP_ADSPCS_SPA_MASK(core_mask), 0);
 179
 180        return snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
 181                                HDA_DSP_REG_ADSPCS, adspcs,
 182                                !(adspcs & HDA_DSP_ADSPCS_SPA_MASK(core_mask)),
 183                                HDA_DSP_REG_POLL_INTERVAL_US,
 184                                HDA_DSP_PD_TIMEOUT * USEC_PER_MSEC);
 185}
 186
 187bool hda_dsp_core_is_enabled(struct snd_sof_dev *sdev,
 188                             unsigned int core_mask)
 189{
 190        int val;
 191        bool is_enable;
 192
 193        val = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPCS);
 194
 195        is_enable = ((val & HDA_DSP_ADSPCS_CPA_MASK(core_mask)) &&
 196                        (val & HDA_DSP_ADSPCS_SPA_MASK(core_mask)) &&
 197                        !(val & HDA_DSP_ADSPCS_CRST_MASK(core_mask)) &&
 198                        !(val & HDA_DSP_ADSPCS_CSTALL_MASK(core_mask)));
 199
 200        dev_dbg(sdev->dev, "DSP core(s) enabled? %d : core_mask %x\n",
 201                is_enable, core_mask);
 202
 203        return is_enable;
 204}
 205
 206int hda_dsp_enable_core(struct snd_sof_dev *sdev, unsigned int core_mask)
 207{
 208        int ret;
 209
 210        /* return if core is already enabled */
 211        if (hda_dsp_core_is_enabled(sdev, core_mask))
 212                return 0;
 213
 214        /* power up */
 215        ret = hda_dsp_core_power_up(sdev, core_mask);
 216        if (ret < 0) {
 217                dev_err(sdev->dev, "error: dsp core power up failed: core_mask %x\n",
 218                        core_mask);
 219                return ret;
 220        }
 221
 222        return hda_dsp_core_run(sdev, core_mask);
 223}
 224
 225int hda_dsp_core_reset_power_down(struct snd_sof_dev *sdev,
 226                                  unsigned int core_mask)
 227{
 228        int ret;
 229
 230        /* place core in reset prior to power down */
 231        ret = hda_dsp_core_stall_reset(sdev, core_mask);
 232        if (ret < 0) {
 233                dev_err(sdev->dev, "error: dsp core reset failed: core_mask %x\n",
 234                        core_mask);
 235                return ret;
 236        }
 237
 238        /* power down core */
 239        ret = hda_dsp_core_power_down(sdev, core_mask);
 240        if (ret < 0) {
 241                dev_err(sdev->dev, "error: dsp core power down fail mask %x: %d\n",
 242                        core_mask, ret);
 243                return ret;
 244        }
 245
 246        /* make sure we are in OFF state */
 247        if (hda_dsp_core_is_enabled(sdev, core_mask)) {
 248                dev_err(sdev->dev, "error: dsp core disable fail mask %x: %d\n",
 249                        core_mask, ret);
 250                ret = -EIO;
 251        }
 252
 253        return ret;
 254}
 255
 256void hda_dsp_ipc_int_enable(struct snd_sof_dev *sdev)
 257{
 258        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 259        const struct sof_intel_dsp_desc *chip = hda->desc;
 260
 261        /* enable IPC DONE and BUSY interrupts */
 262        snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
 263                        HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY,
 264                        HDA_DSP_REG_HIPCCTL_DONE | HDA_DSP_REG_HIPCCTL_BUSY);
 265
 266        /* enable IPC interrupt */
 267        snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
 268                                HDA_DSP_ADSPIC_IPC, HDA_DSP_ADSPIC_IPC);
 269}
 270
 271void hda_dsp_ipc_int_disable(struct snd_sof_dev *sdev)
 272{
 273        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 274        const struct sof_intel_dsp_desc *chip = hda->desc;
 275
 276        /* disable IPC interrupt */
 277        snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, HDA_DSP_REG_ADSPIC,
 278                                HDA_DSP_ADSPIC_IPC, 0);
 279
 280        /* disable IPC BUSY and DONE interrupt */
 281        snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, chip->ipc_ctl,
 282                        HDA_DSP_REG_HIPCCTL_BUSY | HDA_DSP_REG_HIPCCTL_DONE, 0);
 283}
 284
 285static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend)
 286{
 287        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 288        const struct sof_intel_dsp_desc *chip = hda->desc;
 289#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 290        struct hdac_bus *bus = sof_to_bus(sdev);
 291#endif
 292        int ret;
 293
 294        /* disable IPC interrupts */
 295        hda_dsp_ipc_int_disable(sdev);
 296
 297#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 298        if (runtime_suspend)
 299                hda_codec_jack_wake_enable(sdev);
 300
 301        /* power down all hda link */
 302        snd_hdac_ext_bus_link_power_down_all(bus);
 303#endif
 304
 305        /* power down DSP */
 306        ret = hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
 307        if (ret < 0) {
 308                dev_err(sdev->dev,
 309                        "error: failed to power down core during suspend\n");
 310                return ret;
 311        }
 312
 313        /* disable ppcap interrupt */
 314        hda_dsp_ctrl_ppcap_enable(sdev, false);
 315        hda_dsp_ctrl_ppcap_int_enable(sdev, false);
 316
 317        /* disable hda bus irq and streams */
 318        hda_dsp_ctrl_stop_chip(sdev);
 319
 320        /* disable LP retention mode */
 321        snd_sof_pci_update_bits(sdev, PCI_PGCTL,
 322                                PCI_PGCTL_LSRMD_MASK, PCI_PGCTL_LSRMD_MASK);
 323
 324        /* reset controller */
 325        ret = hda_dsp_ctrl_link_reset(sdev, true);
 326        if (ret < 0) {
 327                dev_err(sdev->dev,
 328                        "error: failed to reset controller during suspend\n");
 329                return ret;
 330        }
 331
 332        return 0;
 333}
 334
 335static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume)
 336{
 337#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 338        struct hdac_bus *bus = sof_to_bus(sdev);
 339        struct hdac_ext_link *hlink = NULL;
 340#endif
 341        int ret;
 342
 343        /*
 344         * clear TCSEL to clear playback on some HD Audio
 345         * codecs. PCI TCSEL is defined in the Intel manuals.
 346         */
 347        snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
 348
 349        /* reset and start hda controller */
 350        ret = hda_dsp_ctrl_init_chip(sdev, true);
 351        if (ret < 0) {
 352                dev_err(sdev->dev,
 353                        "error: failed to start controller after resume\n");
 354                return ret;
 355        }
 356
 357#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 358        /* check jack status */
 359        if (runtime_resume)
 360                hda_codec_jack_check(sdev);
 361
 362        /* turn off the links that were off before suspend */
 363        list_for_each_entry(hlink, &bus->hlink_list, list) {
 364                if (!hlink->ref_count)
 365                        snd_hdac_ext_bus_link_power_down(hlink);
 366        }
 367
 368        /* check dma status and clean up CORB/RIRB buffers */
 369        if (!bus->cmd_dma_state)
 370                snd_hdac_bus_stop_cmd_io(bus);
 371#endif
 372
 373        /* enable ppcap interrupt */
 374        hda_dsp_ctrl_ppcap_enable(sdev, true);
 375        hda_dsp_ctrl_ppcap_int_enable(sdev, true);
 376
 377        return 0;
 378}
 379
 380int hda_dsp_resume(struct snd_sof_dev *sdev)
 381{
 382        /* init hda controller. DSP cores will be powered up during fw boot */
 383        return hda_resume(sdev, false);
 384}
 385
 386int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
 387{
 388        /* init hda controller. DSP cores will be powered up during fw boot */
 389        return hda_resume(sdev, true);
 390}
 391
 392int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
 393{
 394        struct hdac_bus *hbus = sof_to_bus(sdev);
 395
 396        if (hbus->codec_powered) {
 397                dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n",
 398                        (unsigned int)hbus->codec_powered);
 399                return -EBUSY;
 400        }
 401
 402        return 0;
 403}
 404
 405int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev)
 406{
 407        /* stop hda controller and power dsp off */
 408        return hda_suspend(sdev, true);
 409}
 410
 411int hda_dsp_suspend(struct snd_sof_dev *sdev)
 412{
 413        struct hdac_bus *bus = sof_to_bus(sdev);
 414        int ret;
 415
 416        /* stop hda controller and power dsp off */
 417        ret = hda_suspend(sdev, false);
 418        if (ret < 0) {
 419                dev_err(bus->dev, "error: suspending dsp\n");
 420                return ret;
 421        }
 422
 423        return 0;
 424}
 425
 426int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
 427{
 428#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 429        struct hdac_bus *bus = sof_to_bus(sdev);
 430        struct snd_soc_pcm_runtime *rtd;
 431        struct hdac_ext_stream *stream;
 432        struct hdac_ext_link *link;
 433        struct hdac_stream *s;
 434        const char *name;
 435        int stream_tag;
 436
 437        /* set internal flag for BE */
 438        list_for_each_entry(s, &bus->stream_list, list) {
 439                stream = stream_to_hdac_ext_stream(s);
 440
 441                /*
 442                 * clear stream. This should already be taken care for running
 443                 * streams when the SUSPEND trigger is called. But paused
 444                 * streams do not get suspended, so this needs to be done
 445                 * explicitly during suspend.
 446                 */
 447                if (stream->link_substream) {
 448                        rtd = snd_pcm_substream_chip(stream->link_substream);
 449                        name = rtd->codec_dai->component->name;
 450                        link = snd_hdac_ext_bus_get_link(bus, name);
 451                        if (!link)
 452                                return -EINVAL;
 453
 454                        stream->link_prepared = 0;
 455
 456                        if (hdac_stream(stream)->direction ==
 457                                SNDRV_PCM_STREAM_CAPTURE)
 458                                continue;
 459
 460                        stream_tag = hdac_stream(stream)->stream_tag;
 461                        snd_hdac_ext_link_clear_stream_id(link, stream_tag);
 462                }
 463        }
 464#endif
 465        return 0;
 466}
 467