linux/sound/soc/sof/intel/hda-loader.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (GPL-2.0-only 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 HDA DSP code loader
  16 */
  17
  18#include <linux/firmware.h>
  19#include <sound/hdaudio_ext.h>
  20#include <sound/hda_register.h>
  21#include <sound/sof.h>
  22#include "ext_manifest.h"
  23#include "../ops.h"
  24#include "hda.h"
  25
  26#define HDA_FW_BOOT_ATTEMPTS    3
  27#define HDA_CL_STREAM_FORMAT 0x40
  28
  29static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
  30                                                 unsigned int size, struct snd_dma_buffer *dmab,
  31                                                 int direction)
  32{
  33        struct hdac_ext_stream *dsp_stream;
  34        struct hdac_stream *hstream;
  35        struct pci_dev *pci = to_pci_dev(sdev->dev);
  36        int ret;
  37
  38        dsp_stream = hda_dsp_stream_get(sdev, direction, 0);
  39
  40        if (!dsp_stream) {
  41                dev_err(sdev->dev, "error: no stream available\n");
  42                return ERR_PTR(-ENODEV);
  43        }
  44        hstream = &dsp_stream->hstream;
  45        hstream->substream = NULL;
  46
  47        /* allocate DMA buffer */
  48        ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV_SG, &pci->dev, size, dmab);
  49        if (ret < 0) {
  50                dev_err(sdev->dev, "error: memory alloc failed: %d\n", ret);
  51                goto error;
  52        }
  53
  54        hstream->period_bytes = 0;/* initialize period_bytes */
  55        hstream->format_val = format;
  56        hstream->bufsize = size;
  57
  58        if (direction == SNDRV_PCM_STREAM_CAPTURE) {
  59                ret = hda_dsp_iccmax_stream_hw_params(sdev, dsp_stream, dmab, NULL);
  60                if (ret < 0) {
  61                        dev_err(sdev->dev, "error: iccmax stream prepare failed: %d\n", ret);
  62                        goto error;
  63                }
  64        } else {
  65                ret = hda_dsp_stream_hw_params(sdev, dsp_stream, dmab, NULL);
  66                if (ret < 0) {
  67                        dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret);
  68                        goto error;
  69                }
  70                hda_dsp_stream_spib_config(sdev, dsp_stream, HDA_DSP_SPIB_ENABLE, size);
  71        }
  72
  73        return dsp_stream;
  74
  75error:
  76        hda_dsp_stream_put(sdev, direction, hstream->stream_tag);
  77        snd_dma_free_pages(dmab);
  78        return ERR_PTR(ret);
  79}
  80
  81/*
  82 * first boot sequence has some extra steps. core 0 waits for power
  83 * status on core 1, so power up core 1 also momentarily, keep it in
  84 * reset/stall and then turn it off
  85 */
  86static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag)
  87{
  88        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
  89        const struct sof_intel_dsp_desc *chip = hda->desc;
  90        unsigned int status;
  91        u32 flags;
  92        int ret;
  93        int i;
  94
  95        /* step 1: power up corex */
  96        ret = snd_sof_dsp_core_power_up(sdev, chip->host_managed_cores_mask);
  97        if (ret < 0) {
  98                if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
  99                        dev_err(sdev->dev, "error: dsp core 0/1 power up failed\n");
 100                goto err;
 101        }
 102
 103        /* DSP is powered up, set all SSPs to slave mode */
 104        for (i = 0; i < chip->ssp_count; i++) {
 105                snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
 106                                                 chip->ssp_base_offset
 107                                                 + i * SSP_DEV_MEM_SIZE
 108                                                 + SSP_SSC1_OFFSET,
 109                                                 SSP_SET_SLAVE,
 110                                                 SSP_SET_SLAVE);
 111        }
 112
 113        /* step 2: purge FW request */
 114        snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req,
 115                          chip->ipc_req_mask | (HDA_DSP_IPC_PURGE_FW |
 116                          ((stream_tag - 1) << 9)));
 117
 118        /* step 3: unset core 0 reset state & unstall/run core 0 */
 119        ret = hda_dsp_core_run(sdev, BIT(0));
 120        if (ret < 0) {
 121                if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 122                        dev_err(sdev->dev,
 123                                "error: dsp core start failed %d\n", ret);
 124                ret = -EIO;
 125                goto err;
 126        }
 127
 128        /* step 4: wait for IPC DONE bit from ROM */
 129        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
 130                                            chip->ipc_ack, status,
 131                                            ((status & chip->ipc_ack_mask)
 132                                                    == chip->ipc_ack_mask),
 133                                            HDA_DSP_REG_POLL_INTERVAL_US,
 134                                            HDA_DSP_INIT_TIMEOUT_US);
 135
 136        if (ret < 0) {
 137                if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 138                        dev_err(sdev->dev,
 139                                "error: %s: timeout for HIPCIE done\n",
 140                                __func__);
 141                goto err;
 142        }
 143
 144        /* set DONE bit to clear the reply IPC message */
 145        snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR,
 146                                       chip->ipc_ack,
 147                                       chip->ipc_ack_mask,
 148                                       chip->ipc_ack_mask);
 149
 150        /* step 5: power down cores that are no longer needed */
 151        ret = snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask &
 152                                          ~(chip->init_core_mask));
 153        if (ret < 0) {
 154                if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 155                        dev_err(sdev->dev,
 156                                "error: dsp core x power down failed\n");
 157                goto err;
 158        }
 159
 160        /* step 6: enable IPC interrupts */
 161        hda_dsp_ipc_int_enable(sdev);
 162
 163        /* step 7: wait for ROM init */
 164        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
 165                                        HDA_DSP_SRAM_REG_ROM_STATUS, status,
 166                                        ((status & HDA_DSP_ROM_STS_MASK)
 167                                                == HDA_DSP_ROM_INIT),
 168                                        HDA_DSP_REG_POLL_INTERVAL_US,
 169                                        chip->rom_init_timeout *
 170                                        USEC_PER_MSEC);
 171        if (!ret)
 172                return 0;
 173
 174        if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 175                dev_err(sdev->dev,
 176                        "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n",
 177                        __func__);
 178
 179err:
 180        flags = SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX;
 181
 182        /* force error log level after max boot attempts */
 183        if (hda->boot_iteration == HDA_FW_BOOT_ATTEMPTS)
 184                flags |= SOF_DBG_DUMP_FORCE_ERR_LEVEL;
 185
 186        hda_dsp_dump(sdev, flags);
 187        snd_sof_dsp_core_power_down(sdev, chip->host_managed_cores_mask);
 188
 189        return ret;
 190}
 191
 192static int cl_trigger(struct snd_sof_dev *sdev,
 193                      struct hdac_ext_stream *stream, int cmd)
 194{
 195        struct hdac_stream *hstream = &stream->hstream;
 196        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 197
 198        /* code loader is special case that reuses stream ops */
 199        switch (cmd) {
 200        case SNDRV_PCM_TRIGGER_START:
 201                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
 202                                        1 << hstream->index,
 203                                        1 << hstream->index);
 204
 205                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 206                                        sd_offset,
 207                                        SOF_HDA_SD_CTL_DMA_START |
 208                                        SOF_HDA_CL_DMA_SD_INT_MASK,
 209                                        SOF_HDA_SD_CTL_DMA_START |
 210                                        SOF_HDA_CL_DMA_SD_INT_MASK);
 211
 212                hstream->running = true;
 213                return 0;
 214        default:
 215                return hda_dsp_stream_trigger(sdev, stream, cmd);
 216        }
 217}
 218
 219static int cl_cleanup(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab,
 220                      struct hdac_ext_stream *stream)
 221{
 222        struct hdac_stream *hstream = &stream->hstream;
 223        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 224        int ret = 0;
 225
 226        if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK)
 227                ret = hda_dsp_stream_spib_config(sdev, stream, HDA_DSP_SPIB_DISABLE, 0);
 228        else
 229                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 230                                        SOF_HDA_SD_CTL_DMA_START, 0);
 231
 232        hda_dsp_stream_put(sdev, hstream->direction, hstream->stream_tag);
 233        hstream->running = 0;
 234        hstream->substream = NULL;
 235
 236        /* reset BDL address */
 237        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 238                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL, 0);
 239        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 240                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU, 0);
 241
 242        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset, 0);
 243        snd_dma_free_pages(dmab);
 244        dmab->area = NULL;
 245        hstream->bufsize = 0;
 246        hstream->format_val = 0;
 247
 248        return ret;
 249}
 250
 251static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream)
 252{
 253        unsigned int reg;
 254        int ret, status;
 255
 256        ret = cl_trigger(sdev, stream, SNDRV_PCM_TRIGGER_START);
 257        if (ret < 0) {
 258                dev_err(sdev->dev, "error: DMA trigger start failed\n");
 259                return ret;
 260        }
 261
 262        status = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_BAR,
 263                                        HDA_DSP_SRAM_REG_ROM_STATUS, reg,
 264                                        ((reg & HDA_DSP_ROM_STS_MASK)
 265                                                == HDA_DSP_ROM_FW_ENTERED),
 266                                        HDA_DSP_REG_POLL_INTERVAL_US,
 267                                        HDA_DSP_BASEFW_TIMEOUT_US);
 268
 269        /*
 270         * even in case of errors we still need to stop the DMAs,
 271         * but we return the initial error should the DMA stop also fail
 272         */
 273
 274        if (status < 0) {
 275                dev_err(sdev->dev,
 276                        "error: %s: timeout HDA_DSP_SRAM_REG_ROM_STATUS read\n",
 277                        __func__);
 278        }
 279
 280        ret = cl_trigger(sdev, stream, SNDRV_PCM_TRIGGER_STOP);
 281        if (ret < 0) {
 282                dev_err(sdev->dev, "error: DMA trigger stop failed\n");
 283                if (!status)
 284                        status = ret;
 285        }
 286
 287        return status;
 288}
 289
 290int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
 291{
 292        struct snd_sof_pdata *plat_data = sdev->pdata;
 293        struct hdac_ext_stream *iccmax_stream;
 294        struct hdac_bus *bus = sof_to_bus(sdev);
 295        struct firmware stripped_firmware;
 296        int ret, ret1;
 297        u8 original_gb;
 298
 299        /* save the original LTRP guardband value */
 300        original_gb = snd_hdac_chip_readb(bus, VS_LTRP) & HDA_VS_INTEL_LTRP_GB_MASK;
 301
 302        if (plat_data->fw->size <= plat_data->fw_offset) {
 303                dev_err(sdev->dev, "error: firmware size must be greater than firmware offset\n");
 304                return -EINVAL;
 305        }
 306
 307        stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
 308
 309        /* prepare capture stream for ICCMAX */
 310        iccmax_stream = cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
 311                                          &sdev->dmab_bdl, SNDRV_PCM_STREAM_CAPTURE);
 312        if (IS_ERR(iccmax_stream)) {
 313                dev_err(sdev->dev, "error: dma prepare for ICCMAX stream failed\n");
 314                return PTR_ERR(iccmax_stream);
 315        }
 316
 317        ret = hda_dsp_cl_boot_firmware(sdev);
 318
 319        /*
 320         * Perform iccmax stream cleanup. This should be done even if firmware loading fails.
 321         * If the cleanup also fails, we return the initial error
 322         */
 323        ret1 = cl_cleanup(sdev, &sdev->dmab_bdl, iccmax_stream);
 324        if (ret1 < 0) {
 325                dev_err(sdev->dev, "error: ICCMAX stream cleanup failed\n");
 326
 327                /* set return value to indicate cleanup failure */
 328                if (!ret)
 329                        ret = ret1;
 330        }
 331
 332        /* restore the original guardband value after FW boot */
 333        snd_hdac_chip_updateb(bus, VS_LTRP, HDA_VS_INTEL_LTRP_GB_MASK, original_gb);
 334
 335        return ret;
 336}
 337
 338int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
 339{
 340        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 341        struct snd_sof_pdata *plat_data = sdev->pdata;
 342        const struct sof_dev_desc *desc = plat_data->desc;
 343        const struct sof_intel_dsp_desc *chip_info;
 344        struct hdac_ext_stream *stream;
 345        struct firmware stripped_firmware;
 346        int ret, ret1, i;
 347
 348        chip_info = desc->chip_info;
 349
 350        if (plat_data->fw->size <= plat_data->fw_offset) {
 351                dev_err(sdev->dev, "error: firmware size must be greater than firmware offset\n");
 352                return -EINVAL;
 353        }
 354
 355        stripped_firmware.data = plat_data->fw->data + plat_data->fw_offset;
 356        stripped_firmware.size = plat_data->fw->size - plat_data->fw_offset;
 357
 358        /* init for booting wait */
 359        init_waitqueue_head(&sdev->boot_wait);
 360
 361        /* prepare DMA for code loader stream */
 362        stream = cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
 363                                   &sdev->dmab, SNDRV_PCM_STREAM_PLAYBACK);
 364        if (IS_ERR(stream)) {
 365                dev_err(sdev->dev, "error: dma prepare for fw loading failed\n");
 366                return PTR_ERR(stream);
 367        }
 368
 369        memcpy(sdev->dmab.area, stripped_firmware.data,
 370               stripped_firmware.size);
 371
 372        /* try ROM init a few times before giving up */
 373        for (i = 0; i < HDA_FW_BOOT_ATTEMPTS; i++) {
 374                dev_dbg(sdev->dev,
 375                        "Attempting iteration %d of Core En/ROM load...\n", i);
 376
 377                hda->boot_iteration = i + 1;
 378                ret = cl_dsp_init(sdev, stream->hstream.stream_tag);
 379
 380                /* don't retry anymore if successful */
 381                if (!ret)
 382                        break;
 383        }
 384
 385        if (i == HDA_FW_BOOT_ATTEMPTS) {
 386                dev_err(sdev->dev, "error: dsp init failed after %d attempts with err: %d\n",
 387                        i, ret);
 388                goto cleanup;
 389        }
 390
 391        /*
 392         * When a SoundWire link is in clock stop state, a Slave
 393         * device may trigger in-band wakes for events such as jack
 394         * insertion or acoustic event detection. This event will lead
 395         * to a WAKEEN interrupt, handled by the PCI device and routed
 396         * to PME if the PCI device is in D3. The resume function in
 397         * audio PCI driver will be invoked by ACPI for PME event and
 398         * initialize the device and process WAKEEN interrupt.
 399         *
 400         * The WAKEEN interrupt should be processed ASAP to prevent an
 401         * interrupt flood, otherwise other interrupts, such IPC,
 402         * cannot work normally.  The WAKEEN is handled after the ROM
 403         * is initialized successfully, which ensures power rails are
 404         * enabled before accessing the SoundWire SHIM registers
 405         */
 406        if (!sdev->first_boot)
 407                hda_sdw_process_wakeen(sdev);
 408
 409        /*
 410         * at this point DSP ROM has been initialized and
 411         * should be ready for code loading and firmware boot
 412         */
 413        ret = cl_copy_fw(sdev, stream);
 414        if (!ret) {
 415                dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
 416        } else {
 417                hda_dsp_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_PCI | SOF_DBG_DUMP_MBOX |
 418                             SOF_DBG_DUMP_FORCE_ERR_LEVEL);
 419                dev_err(sdev->dev, "error: load fw failed ret: %d\n", ret);
 420        }
 421
 422cleanup:
 423        /*
 424         * Perform codeloader stream cleanup.
 425         * This should be done even if firmware loading fails.
 426         * If the cleanup also fails, we return the initial error
 427         */
 428        ret1 = cl_cleanup(sdev, &sdev->dmab, stream);
 429        if (ret1 < 0) {
 430                dev_err(sdev->dev, "error: Code loader DSP cleanup failed\n");
 431
 432                /* set return value to indicate cleanup failure */
 433                if (!ret)
 434                        ret = ret1;
 435        }
 436
 437        /*
 438         * return primary core id if both fw copy
 439         * and stream clean up are successful
 440         */
 441        if (!ret)
 442                return chip_info->init_core_mask;
 443
 444        /* disable DSP */
 445        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR,
 446                                SOF_HDA_REG_PP_PPCTL,
 447                                SOF_HDA_PPCTL_GPROCEN, 0);
 448        return ret;
 449}
 450
 451/* pre fw run operations */
 452int hda_dsp_pre_fw_run(struct snd_sof_dev *sdev)
 453{
 454        /* disable clock gating and power gating */
 455        return hda_dsp_ctrl_clock_power_gating(sdev, false);
 456}
 457
 458/* post fw run operations */
 459int hda_dsp_post_fw_run(struct snd_sof_dev *sdev)
 460{
 461        int ret;
 462
 463        if (sdev->first_boot) {
 464                ret = hda_sdw_startup(sdev);
 465                if (ret < 0) {
 466                        dev_err(sdev->dev,
 467                                "error: could not startup SoundWire links\n");
 468                        return ret;
 469                }
 470        }
 471
 472        hda_sdw_int_enable(sdev, true);
 473
 474        /* re-enable clock gating and power gating */
 475        return hda_dsp_ctrl_clock_power_gating(sdev, true);
 476}
 477
 478/*
 479 * post fw run operations for ICL,
 480 * Core 3 will be powered up and in stall when HPRO is enabled
 481 */
 482int hda_dsp_post_fw_run_icl(struct snd_sof_dev *sdev)
 483{
 484        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 485        int ret;
 486
 487        if (sdev->first_boot) {
 488                ret = hda_sdw_startup(sdev);
 489                if (ret < 0) {
 490                        dev_err(sdev->dev,
 491                                "error: could not startup SoundWire links\n");
 492                        return ret;
 493                }
 494        }
 495
 496        hda_sdw_int_enable(sdev, true);
 497
 498        /*
 499         * The recommended HW programming sequence for ICL is to
 500         * power up core 3 and keep it in stall if HPRO is enabled.
 501         * Major difference between ICL and TGL, on ICL core 3 is managed by
 502         * the host whereas on TGL it is handled by the firmware.
 503         */
 504        if (!hda->clk_config_lpro) {
 505                ret = snd_sof_dsp_core_power_up(sdev, BIT(3));
 506                if (ret < 0) {
 507                        dev_err(sdev->dev, "error: dsp core power up failed on core 3\n");
 508                        return ret;
 509                }
 510
 511                snd_sof_dsp_stall(sdev, BIT(3));
 512        }
 513
 514        /* re-enable clock gating and power gating */
 515        return hda_dsp_ctrl_clock_power_gating(sdev, true);
 516}
 517
 518int hda_dsp_ext_man_get_cavs_config_data(struct snd_sof_dev *sdev,
 519                                         const struct sof_ext_man_elem_header *hdr)
 520{
 521        const struct sof_ext_man_cavs_config_data *config_data =
 522                container_of(hdr, struct sof_ext_man_cavs_config_data, hdr);
 523        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 524        int i, elem_num;
 525
 526        /* calculate total number of config data elements */
 527        elem_num = (hdr->size - sizeof(struct sof_ext_man_elem_header))
 528                   / sizeof(struct sof_config_elem);
 529        if (elem_num <= 0) {
 530                dev_err(sdev->dev, "cavs config data is inconsistent: %d\n", elem_num);
 531                return -EINVAL;
 532        }
 533
 534        for (i = 0; i < elem_num; i++)
 535                switch (config_data->elems[i].token) {
 536                case SOF_EXT_MAN_CAVS_CONFIG_EMPTY:
 537                        /* skip empty token */
 538                        break;
 539                case SOF_EXT_MAN_CAVS_CONFIG_CAVS_LPRO:
 540                        hda->clk_config_lpro = config_data->elems[i].value;
 541                        dev_dbg(sdev->dev, "FW clock config: %s\n",
 542                                hda->clk_config_lpro ? "LPRO" : "HPRO");
 543                        break;
 544                case SOF_EXT_MAN_CAVS_CONFIG_OUTBOX_SIZE:
 545                case SOF_EXT_MAN_CAVS_CONFIG_INBOX_SIZE:
 546                        /* These elements are defined but not being used yet. No warn is required */
 547                        break;
 548                default:
 549                        dev_info(sdev->dev, "unsupported token type: %d\n",
 550                                 config_data->elems[i].token);
 551                }
 552
 553        return 0;
 554}
 555
 556int hda_dsp_core_stall_icl(struct snd_sof_dev *sdev, unsigned int core_mask)
 557{
 558        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
 559        const struct sof_intel_dsp_desc *chip = hda->desc;
 560
 561        /* make sure core_mask in host managed cores */
 562        core_mask &= chip->host_managed_cores_mask;
 563        if (!core_mask) {
 564                dev_err(sdev->dev, "error: core_mask is not in host managed cores\n");
 565                return -EINVAL;
 566        }
 567
 568        /* stall core */
 569        snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
 570                                         HDA_DSP_REG_ADSPCS,
 571                                         HDA_DSP_ADSPCS_CSTALL_MASK(core_mask),
 572                                         HDA_DSP_ADSPCS_CSTALL_MASK(core_mask));
 573
 574        return 0;
 575}
 576