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, int state)
 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        /* power down all hda link */
 299        snd_hdac_ext_bus_link_power_down_all(bus);
 300#endif
 301
 302        /* power down DSP */
 303        ret = hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
 304        if (ret < 0) {
 305                dev_err(sdev->dev,
 306                        "error: failed to power down core during suspend\n");
 307                return ret;
 308        }
 309
 310        /* disable ppcap interrupt */
 311        hda_dsp_ctrl_ppcap_enable(sdev, false);
 312        hda_dsp_ctrl_ppcap_int_enable(sdev, false);
 313
 314        /* disable hda bus irq and streams */
 315        hda_dsp_ctrl_stop_chip(sdev);
 316
 317        /* disable LP retention mode */
 318        snd_sof_pci_update_bits(sdev, PCI_PGCTL,
 319                                PCI_PGCTL_LSRMD_MASK, PCI_PGCTL_LSRMD_MASK);
 320
 321        /* reset controller */
 322        ret = hda_dsp_ctrl_link_reset(sdev, true);
 323        if (ret < 0) {
 324                dev_err(sdev->dev,
 325                        "error: failed to reset controller during suspend\n");
 326                return ret;
 327        }
 328
 329        return 0;
 330}
 331
 332static int hda_resume(struct snd_sof_dev *sdev)
 333{
 334#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 335        struct hdac_bus *bus = sof_to_bus(sdev);
 336        struct hdac_ext_link *hlink = NULL;
 337#endif
 338        int ret;
 339
 340        /*
 341         * clear TCSEL to clear playback on some HD Audio
 342         * codecs. PCI TCSEL is defined in the Intel manuals.
 343         */
 344        snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
 345
 346#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 347        /* reset and start hda controller */
 348        ret = hda_dsp_ctrl_init_chip(sdev, true);
 349        if (ret < 0) {
 350                dev_err(sdev->dev,
 351                        "error: failed to start controller after resume\n");
 352                return ret;
 353        }
 354
 355        hda_dsp_ctrl_misc_clock_gating(sdev, false);
 356
 357        /* Reset stream-to-link mapping */
 358        list_for_each_entry(hlink, &bus->hlink_list, list)
 359                bus->io_ops->reg_writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV);
 360
 361        hda_dsp_ctrl_misc_clock_gating(sdev, true);
 362#else
 363
 364        hda_dsp_ctrl_misc_clock_gating(sdev, false);
 365
 366        /* reset controller */
 367        ret = hda_dsp_ctrl_link_reset(sdev, true);
 368        if (ret < 0) {
 369                dev_err(sdev->dev,
 370                        "error: failed to reset controller during resume\n");
 371                return ret;
 372        }
 373
 374        /* take controller out of reset */
 375        ret = hda_dsp_ctrl_link_reset(sdev, false);
 376        if (ret < 0) {
 377                dev_err(sdev->dev,
 378                        "error: failed to ready controller during resume\n");
 379                return ret;
 380        }
 381
 382        /* enable hda bus irq */
 383        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
 384                                SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
 385                                SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
 386
 387        hda_dsp_ctrl_misc_clock_gating(sdev, true);
 388#endif
 389
 390        /* enable ppcap interrupt */
 391        hda_dsp_ctrl_ppcap_enable(sdev, true);
 392        hda_dsp_ctrl_ppcap_int_enable(sdev, true);
 393
 394#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 395        /* turn off the links that were off before suspend */
 396        list_for_each_entry(hlink, &bus->hlink_list, list) {
 397                if (!hlink->ref_count)
 398                        snd_hdac_ext_bus_link_power_down(hlink);
 399        }
 400
 401        /* check dma status and clean up CORB/RIRB buffers */
 402        if (!bus->cmd_dma_state)
 403                snd_hdac_bus_stop_cmd_io(bus);
 404#endif
 405
 406        return 0;
 407}
 408
 409int hda_dsp_resume(struct snd_sof_dev *sdev)
 410{
 411        /* init hda controller. DSP cores will be powered up during fw boot */
 412        return hda_resume(sdev);
 413}
 414
 415int hda_dsp_runtime_resume(struct snd_sof_dev *sdev)
 416{
 417        /* init hda controller. DSP cores will be powered up during fw boot */
 418        return hda_resume(sdev);
 419}
 420
 421int hda_dsp_runtime_idle(struct snd_sof_dev *sdev)
 422{
 423        struct hdac_bus *hbus = sof_to_bus(sdev);
 424
 425        if (hbus->codec_powered) {
 426                dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n",
 427                        (unsigned int)hbus->codec_powered);
 428                return -EBUSY;
 429        }
 430
 431        return 0;
 432}
 433
 434int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state)
 435{
 436        /* stop hda controller and power dsp off */
 437        return hda_suspend(sdev, state);
 438}
 439
 440int hda_dsp_suspend(struct snd_sof_dev *sdev, int state)
 441{
 442        struct hdac_bus *bus = sof_to_bus(sdev);
 443        int ret;
 444
 445        /* stop hda controller and power dsp off */
 446        ret = hda_suspend(sdev, state);
 447        if (ret < 0) {
 448                dev_err(bus->dev, "error: suspending dsp\n");
 449                return ret;
 450        }
 451
 452        return 0;
 453}
 454
 455int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
 456{
 457        struct hdac_bus *bus = sof_to_bus(sdev);
 458        struct sof_intel_hda_stream *hda_stream;
 459        struct hdac_ext_stream *stream;
 460        struct hdac_stream *s;
 461
 462#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 463        struct snd_soc_pcm_runtime *rtd;
 464        struct hdac_ext_link *link;
 465        const char *name;
 466        int stream_tag;
 467#endif
 468
 469        /* set internal flag for BE */
 470        list_for_each_entry(s, &bus->stream_list, list) {
 471                stream = stream_to_hdac_ext_stream(s);
 472                hda_stream = container_of(stream, struct sof_intel_hda_stream,
 473                                          hda_stream);
 474                hda_stream->hw_params_upon_resume = 1;
 475#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 476                /*
 477                 * clear and release stream. This should already be taken care
 478                 * for running streams when the SUSPEND trigger is called.
 479                 * But paused streams do not get suspended, so this needs to be
 480                 * done explicitly during suspend.
 481                 */
 482                if (stream->link_substream) {
 483                        rtd = snd_pcm_substream_chip(stream->link_substream);
 484                        name = rtd->codec_dai->component->name;
 485                        link = snd_hdac_ext_bus_get_link(bus, name);
 486                        if (!link)
 487                                return -EINVAL;
 488                        stream_tag = hdac_stream(stream)->stream_tag;
 489                        snd_hdac_ext_link_clear_stream_id(link, stream_tag);
 490                        snd_hdac_ext_stream_release(stream,
 491                                                    HDAC_EXT_STREAM_TYPE_LINK);
 492                }
 493#endif
 494        }
 495        return 0;
 496}
 497