linux/sound/soc/sof/intel/hda-stream.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 <linux/pm_runtime.h>
  19#include <sound/hdaudio_ext.h>
  20#include <sound/hda_register.h>
  21#include <sound/sof.h>
  22#include "../ops.h"
  23#include "hda.h"
  24
  25/*
  26 * set up one of BDL entries for a stream
  27 */
  28static int hda_setup_bdle(struct snd_sof_dev *sdev,
  29                          struct snd_dma_buffer *dmab,
  30                          struct hdac_stream *stream,
  31                          struct sof_intel_dsp_bdl **bdlp,
  32                          int offset, int size, int ioc)
  33{
  34        struct hdac_bus *bus = sof_to_bus(sdev);
  35        struct sof_intel_dsp_bdl *bdl = *bdlp;
  36
  37        while (size > 0) {
  38                dma_addr_t addr;
  39                int chunk;
  40
  41                if (stream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
  42                        dev_err(sdev->dev, "error: stream frags exceeded\n");
  43                        return -EINVAL;
  44                }
  45
  46                addr = snd_sgbuf_get_addr(dmab, offset);
  47                /* program BDL addr */
  48                bdl->addr_l = cpu_to_le32(lower_32_bits(addr));
  49                bdl->addr_h = cpu_to_le32(upper_32_bits(addr));
  50                /* program BDL size */
  51                chunk = snd_sgbuf_get_chunk_size(dmab, offset, size);
  52                /* one BDLE should not cross 4K boundary */
  53                if (bus->align_bdle_4k) {
  54                        u32 remain = 0x1000 - (offset & 0xfff);
  55
  56                        if (chunk > remain)
  57                                chunk = remain;
  58                }
  59                bdl->size = cpu_to_le32(chunk);
  60                /* only program IOC when the whole segment is processed */
  61                size -= chunk;
  62                bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01);
  63                bdl++;
  64                stream->frags++;
  65                offset += chunk;
  66
  67                dev_vdbg(sdev->dev, "bdl, frags:%d, chunk size:0x%x;\n",
  68                         stream->frags, chunk);
  69        }
  70
  71        *bdlp = bdl;
  72        return offset;
  73}
  74
  75/*
  76 * set up Buffer Descriptor List (BDL) for host memory transfer
  77 * BDL describes the location of the individual buffers and is little endian.
  78 */
  79int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
  80                             struct snd_dma_buffer *dmab,
  81                             struct hdac_stream *stream)
  82{
  83        struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
  84        struct sof_intel_dsp_bdl *bdl;
  85        int i, offset, period_bytes, periods;
  86        int remain, ioc;
  87
  88        period_bytes = stream->period_bytes;
  89        dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes);
  90        if (!period_bytes)
  91                period_bytes = stream->bufsize;
  92
  93        periods = stream->bufsize / period_bytes;
  94
  95        dev_dbg(sdev->dev, "periods:%d\n", periods);
  96
  97        remain = stream->bufsize % period_bytes;
  98        if (remain)
  99                periods++;
 100
 101        /* program the initial BDL entries */
 102        bdl = (struct sof_intel_dsp_bdl *)stream->bdl.area;
 103        offset = 0;
 104        stream->frags = 0;
 105
 106        /*
 107         * set IOC if don't use position IPC
 108         * and period_wakeup needed.
 109         */
 110        ioc = hda->no_ipc_position ?
 111              !stream->no_period_wakeup : 0;
 112
 113        for (i = 0; i < periods; i++) {
 114                if (i == (periods - 1) && remain)
 115                        /* set the last small entry */
 116                        offset = hda_setup_bdle(sdev, dmab,
 117                                                stream, &bdl, offset,
 118                                                remain, 0);
 119                else
 120                        offset = hda_setup_bdle(sdev, dmab,
 121                                                stream, &bdl, offset,
 122                                                period_bytes, ioc);
 123        }
 124
 125        return offset;
 126}
 127
 128int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
 129                               struct hdac_ext_stream *stream,
 130                               int enable, u32 size)
 131{
 132        struct hdac_stream *hstream = &stream->hstream;
 133        u32 mask;
 134
 135        if (!sdev->bar[HDA_DSP_SPIB_BAR]) {
 136                dev_err(sdev->dev, "error: address of spib capability is NULL\n");
 137                return -EINVAL;
 138        }
 139
 140        mask = (1 << hstream->index);
 141
 142        /* enable/disable SPIB for the stream */
 143        snd_sof_dsp_update_bits(sdev, HDA_DSP_SPIB_BAR,
 144                                SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL, mask,
 145                                enable << hstream->index);
 146
 147        /* set the SPIB value */
 148        sof_io_write(sdev, stream->spib_addr, size);
 149
 150        return 0;
 151}
 152
 153/* get next unused stream */
 154struct hdac_ext_stream *
 155hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
 156{
 157        struct hdac_bus *bus = sof_to_bus(sdev);
 158        struct hdac_ext_stream *stream = NULL;
 159        struct hdac_stream *s;
 160
 161        spin_lock_irq(&bus->reg_lock);
 162
 163        /* get an unused stream */
 164        list_for_each_entry(s, &bus->stream_list, list) {
 165                if (s->direction == direction && !s->opened) {
 166                        s->opened = true;
 167                        stream = stream_to_hdac_ext_stream(s);
 168                        break;
 169                }
 170        }
 171
 172        spin_unlock_irq(&bus->reg_lock);
 173
 174        /* stream found ? */
 175        if (!stream)
 176                dev_err(sdev->dev, "error: no free %s streams\n",
 177                        direction == SNDRV_PCM_STREAM_PLAYBACK ?
 178                        "playback" : "capture");
 179
 180        return stream;
 181}
 182
 183/* free a stream */
 184int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
 185{
 186        struct hdac_bus *bus = sof_to_bus(sdev);
 187        struct hdac_stream *s;
 188
 189        spin_lock_irq(&bus->reg_lock);
 190
 191        /* find used stream */
 192        list_for_each_entry(s, &bus->stream_list, list) {
 193                if (s->direction == direction &&
 194                    s->opened && s->stream_tag == stream_tag) {
 195                        s->opened = false;
 196                        spin_unlock_irq(&bus->reg_lock);
 197                        return 0;
 198                }
 199        }
 200
 201        spin_unlock_irq(&bus->reg_lock);
 202
 203        dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag);
 204        return -ENODEV;
 205}
 206
 207int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
 208                           struct hdac_ext_stream *stream, int cmd)
 209{
 210        struct hdac_stream *hstream = &stream->hstream;
 211        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 212
 213        /* cmd must be for audio stream */
 214        switch (cmd) {
 215        case SNDRV_PCM_TRIGGER_RESUME:
 216        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 217        case SNDRV_PCM_TRIGGER_START:
 218                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
 219                                        1 << hstream->index,
 220                                        1 << hstream->index);
 221
 222                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 223                                        sd_offset,
 224                                        SOF_HDA_SD_CTL_DMA_START |
 225                                        SOF_HDA_CL_DMA_SD_INT_MASK,
 226                                        SOF_HDA_SD_CTL_DMA_START |
 227                                        SOF_HDA_CL_DMA_SD_INT_MASK);
 228
 229                hstream->running = true;
 230                break;
 231        case SNDRV_PCM_TRIGGER_SUSPEND:
 232        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 233        case SNDRV_PCM_TRIGGER_STOP:
 234                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 235                                        sd_offset,
 236                                        SOF_HDA_SD_CTL_DMA_START |
 237                                        SOF_HDA_CL_DMA_SD_INT_MASK, 0x0);
 238
 239                snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset +
 240                                  SOF_HDA_ADSP_REG_CL_SD_STS,
 241                                  SOF_HDA_CL_DMA_SD_INT_MASK);
 242
 243                hstream->running = false;
 244                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
 245                                        1 << hstream->index, 0x0);
 246                break;
 247        default:
 248                dev_err(sdev->dev, "error: unknown command: %d\n", cmd);
 249                return -EINVAL;
 250        }
 251
 252        return 0;
 253}
 254
 255/*
 256 * prepare for common hdac registers settings, for both code loader
 257 * and normal stream.
 258 */
 259int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
 260                             struct hdac_ext_stream *stream,
 261                             struct snd_dma_buffer *dmab,
 262                             struct snd_pcm_hw_params *params)
 263{
 264        struct hdac_bus *bus = sof_to_bus(sdev);
 265        struct hdac_stream *hstream = &stream->hstream;
 266        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 267        int ret, timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
 268        u32 val, mask;
 269
 270        if (!stream) {
 271                dev_err(sdev->dev, "error: no stream available\n");
 272                return -ENODEV;
 273        }
 274
 275        /* decouple host and link DMA */
 276        mask = 0x1 << hstream->index;
 277        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
 278                                mask, mask);
 279
 280        if (!dmab) {
 281                dev_err(sdev->dev, "error: no dma buffer allocated!\n");
 282                return -ENODEV;
 283        }
 284
 285        /* clear stream status */
 286        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 287                                SOF_HDA_CL_DMA_SD_INT_MASK |
 288                                SOF_HDA_SD_CTL_DMA_START, 0);
 289        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 290                                sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
 291                                SOF_HDA_CL_DMA_SD_INT_MASK,
 292                                SOF_HDA_CL_DMA_SD_INT_MASK);
 293
 294        /* stream reset */
 295        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
 296                                0x1);
 297        udelay(3);
 298        do {
 299                val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
 300                                       sd_offset);
 301                if (val & 0x1)
 302                        break;
 303        } while (--timeout);
 304        if (timeout == 0) {
 305                dev_err(sdev->dev, "error: stream reset failed\n");
 306                return -ETIMEDOUT;
 307        }
 308
 309        timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
 310        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
 311                                0x0);
 312
 313        /* wait for hardware to report that stream is out of reset */
 314        udelay(3);
 315        do {
 316                val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
 317                                       sd_offset);
 318                if ((val & 0x1) == 0)
 319                        break;
 320        } while (--timeout);
 321        if (timeout == 0) {
 322                dev_err(sdev->dev, "error: timeout waiting for stream reset\n");
 323                return -ETIMEDOUT;
 324        }
 325
 326        if (hstream->posbuf)
 327                *hstream->posbuf = 0;
 328
 329        /* reset BDL address */
 330        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 331                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
 332                          0x0);
 333        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 334                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
 335                          0x0);
 336
 337        /* clear stream status */
 338        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 339                                SOF_HDA_CL_DMA_SD_INT_MASK |
 340                                SOF_HDA_SD_CTL_DMA_START, 0);
 341        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 342                                sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
 343                                SOF_HDA_CL_DMA_SD_INT_MASK,
 344                                SOF_HDA_CL_DMA_SD_INT_MASK);
 345
 346        hstream->frags = 0;
 347
 348        ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
 349        if (ret < 0) {
 350                dev_err(sdev->dev, "error: set up of BDL failed\n");
 351                return ret;
 352        }
 353
 354        /* program stream tag to set up stream descriptor for DMA */
 355        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 356                                SOF_HDA_CL_SD_CTL_STREAM_TAG_MASK,
 357                                hstream->stream_tag <<
 358                                SOF_HDA_CL_SD_CTL_STREAM_TAG_SHIFT);
 359
 360        /* program cyclic buffer length */
 361        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 362                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
 363                          hstream->bufsize);
 364
 365        /*
 366         * Recommended hardware programming sequence for HDAudio DMA format
 367         *
 368         * 1. Put DMA into coupled mode by clearing PPCTL.PROCEN bit
 369         *    for corresponding stream index before the time of writing
 370         *    format to SDxFMT register.
 371         * 2. Write SDxFMT
 372         * 3. Set PPCTL.PROCEN bit for corresponding stream index to
 373         *    enable decoupled mode
 374         */
 375
 376        /* couple host and link DMA, disable DSP features */
 377        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
 378                                mask, 0);
 379
 380        /* program stream format */
 381        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 382                                sd_offset +
 383                                SOF_HDA_ADSP_REG_CL_SD_FORMAT,
 384                                0xffff, hstream->format_val);
 385
 386        /* decouple host and link DMA, enable DSP features */
 387        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
 388                                mask, mask);
 389
 390        /* program last valid index */
 391        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 392                                sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
 393                                0xffff, (hstream->frags - 1));
 394
 395        /* program BDL address */
 396        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 397                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
 398                          (u32)hstream->bdl.addr);
 399        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 400                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
 401                          upper_32_bits(hstream->bdl.addr));
 402
 403        /* enable position buffer */
 404        if (!(snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE)
 405                                & SOF_HDA_ADSP_DPLBASE_ENABLE)) {
 406                snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
 407                                  upper_32_bits(bus->posbuf.addr));
 408                snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
 409                                  (u32)bus->posbuf.addr |
 410                                  SOF_HDA_ADSP_DPLBASE_ENABLE);
 411        }
 412
 413        /* set interrupt enable bits */
 414        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 415                                SOF_HDA_CL_DMA_SD_INT_MASK,
 416                                SOF_HDA_CL_DMA_SD_INT_MASK);
 417
 418        /* read FIFO size */
 419        if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) {
 420                hstream->fifo_size =
 421                        snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
 422                                         sd_offset +
 423                                         SOF_HDA_ADSP_REG_CL_SD_FIFOSIZE);
 424                hstream->fifo_size &= 0xffff;
 425                hstream->fifo_size += 1;
 426        } else {
 427                hstream->fifo_size = 0;
 428        }
 429
 430        return ret;
 431}
 432
 433irqreturn_t hda_dsp_stream_interrupt(int irq, void *context)
 434{
 435        struct hdac_bus *bus = context;
 436        struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
 437        u32 stream_mask;
 438        u32 status;
 439
 440        if (!pm_runtime_active(bus->dev))
 441                return IRQ_NONE;
 442
 443        spin_lock(&bus->reg_lock);
 444
 445        status = snd_hdac_chip_readl(bus, INTSTS);
 446        stream_mask = GENMASK(sof_hda->stream_max - 1, 0) | AZX_INT_CTRL_EN;
 447
 448        /* Not stream interrupt or register inaccessible, ignore it.*/
 449        if (!(status & stream_mask) || status == 0xffffffff) {
 450                spin_unlock(&bus->reg_lock);
 451                return IRQ_NONE;
 452        }
 453
 454#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 455        /* clear rirb int */
 456        status = snd_hdac_chip_readb(bus, RIRBSTS);
 457        if (status & RIRB_INT_MASK) {
 458                if (status & RIRB_INT_RESPONSE)
 459                        snd_hdac_bus_update_rirb(bus);
 460                snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK);
 461        }
 462#endif
 463
 464        spin_unlock(&bus->reg_lock);
 465
 466        return snd_hdac_chip_readl(bus, INTSTS) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
 467}
 468
 469irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
 470{
 471        struct hdac_bus *bus = context;
 472        struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
 473        u32 status = snd_hdac_chip_readl(bus, INTSTS);
 474        struct hdac_stream *s;
 475        u32 sd_status;
 476
 477        /* check streams */
 478        list_for_each_entry(s, &bus->stream_list, list) {
 479                if (status & (1 << s->index) && s->opened) {
 480                        sd_status = snd_hdac_stream_readb(s, SD_STS);
 481
 482                        dev_vdbg(bus->dev, "stream %d status 0x%x\n",
 483                                 s->index, sd_status);
 484
 485                        snd_hdac_stream_writeb(s, SD_STS, SD_INT_MASK);
 486
 487                        if (!s->substream ||
 488                            !s->running ||
 489                            (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
 490                                continue;
 491
 492                        /* Inform ALSA only in case not do that with IPC */
 493                        if (sof_hda->no_ipc_position)
 494                                snd_sof_pcm_period_elapsed(s->substream);
 495
 496                }
 497        }
 498
 499        return IRQ_HANDLED;
 500}
 501
 502int hda_dsp_stream_init(struct snd_sof_dev *sdev)
 503{
 504        struct hdac_bus *bus = sof_to_bus(sdev);
 505        struct hdac_ext_stream *stream;
 506        struct hdac_stream *hstream;
 507        struct pci_dev *pci = to_pci_dev(sdev->dev);
 508        struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
 509        int sd_offset;
 510        int i, num_playback, num_capture, num_total, ret;
 511        u32 gcap;
 512
 513        gcap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCAP);
 514        dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap);
 515
 516        /* get stream count from GCAP */
 517        num_capture = (gcap >> 8) & 0x0f;
 518        num_playback = (gcap >> 12) & 0x0f;
 519        num_total = num_playback + num_capture;
 520
 521        dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n",
 522                num_playback, num_capture);
 523
 524        if (num_playback >= SOF_HDA_PLAYBACK_STREAMS) {
 525                dev_err(sdev->dev, "error: too many playback streams %d\n",
 526                        num_playback);
 527                return -EINVAL;
 528        }
 529
 530        if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
 531                dev_err(sdev->dev, "error: too many capture streams %d\n",
 532                        num_playback);
 533                return -EINVAL;
 534        }
 535
 536        /*
 537         * mem alloc for the position buffer
 538         * TODO: check position buffer update
 539         */
 540        ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 541                                  SOF_HDA_DPIB_ENTRY_SIZE * num_total,
 542                                  &bus->posbuf);
 543        if (ret < 0) {
 544                dev_err(sdev->dev, "error: posbuffer dma alloc failed\n");
 545                return -ENOMEM;
 546        }
 547
 548#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 549        /* mem alloc for the CORB/RIRB ringbuffers */
 550        ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 551                                  PAGE_SIZE, &bus->rb);
 552        if (ret < 0) {
 553                dev_err(sdev->dev, "error: RB alloc failed\n");
 554                return -ENOMEM;
 555        }
 556#endif
 557
 558        /* create capture streams */
 559        for (i = 0; i < num_capture; i++) {
 560                struct sof_intel_hda_stream *hda_stream;
 561
 562                hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
 563                                          GFP_KERNEL);
 564                if (!hda_stream)
 565                        return -ENOMEM;
 566
 567                stream = &hda_stream->hda_stream;
 568
 569                stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 570                        SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
 571
 572                stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 573                        SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
 574                        SOF_HDA_PPLC_INTERVAL * i;
 575
 576                /* do we support SPIB */
 577                if (sdev->bar[HDA_DSP_SPIB_BAR]) {
 578                        stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 579                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 580                                SOF_HDA_SPIB_SPIB;
 581
 582                        stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 583                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 584                                SOF_HDA_SPIB_MAXFIFO;
 585                }
 586
 587                hstream = &stream->hstream;
 588                hstream->bus = bus;
 589                hstream->sd_int_sta_mask = 1 << i;
 590                hstream->index = i;
 591                sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 592                hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
 593                hstream->stream_tag = i + 1;
 594                hstream->opened = false;
 595                hstream->running = false;
 596                hstream->direction = SNDRV_PCM_STREAM_CAPTURE;
 597
 598                /* memory alloc for stream BDL */
 599                ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 600                                          HDA_DSP_BDL_SIZE, &hstream->bdl);
 601                if (ret < 0) {
 602                        dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
 603                        return -ENOMEM;
 604                }
 605                hstream->posbuf = (__le32 *)(bus->posbuf.area +
 606                        (hstream->index) * 8);
 607
 608                list_add_tail(&hstream->list, &bus->stream_list);
 609        }
 610
 611        /* create playback streams */
 612        for (i = num_capture; i < num_total; i++) {
 613                struct sof_intel_hda_stream *hda_stream;
 614
 615                hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
 616                                          GFP_KERNEL);
 617                if (!hda_stream)
 618                        return -ENOMEM;
 619
 620                stream = &hda_stream->hda_stream;
 621
 622                /* we always have DSP support */
 623                stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 624                        SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
 625
 626                stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 627                        SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
 628                        SOF_HDA_PPLC_INTERVAL * i;
 629
 630                /* do we support SPIB */
 631                if (sdev->bar[HDA_DSP_SPIB_BAR]) {
 632                        stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 633                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 634                                SOF_HDA_SPIB_SPIB;
 635
 636                        stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 637                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 638                                SOF_HDA_SPIB_MAXFIFO;
 639                }
 640
 641                hstream = &stream->hstream;
 642                hstream->bus = bus;
 643                hstream->sd_int_sta_mask = 1 << i;
 644                hstream->index = i;
 645                sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 646                hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
 647                hstream->stream_tag = i - num_capture + 1;
 648                hstream->opened = false;
 649                hstream->running = false;
 650                hstream->direction = SNDRV_PCM_STREAM_PLAYBACK;
 651
 652                /* mem alloc for stream BDL */
 653                ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 654                                          HDA_DSP_BDL_SIZE, &hstream->bdl);
 655                if (ret < 0) {
 656                        dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
 657                        return -ENOMEM;
 658                }
 659
 660                hstream->posbuf = (__le32 *)(bus->posbuf.area +
 661                        (hstream->index) * 8);
 662
 663                list_add_tail(&hstream->list, &bus->stream_list);
 664        }
 665
 666        /* store total stream count (playback + capture) from GCAP */
 667        sof_hda->stream_max = num_total;
 668
 669        return 0;
 670}
 671
 672void hda_dsp_stream_free(struct snd_sof_dev *sdev)
 673{
 674        struct hdac_bus *bus = sof_to_bus(sdev);
 675        struct hdac_stream *s, *_s;
 676        struct hdac_ext_stream *stream;
 677        struct sof_intel_hda_stream *hda_stream;
 678
 679        /* free position buffer */
 680        if (bus->posbuf.area)
 681                snd_dma_free_pages(&bus->posbuf);
 682
 683#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 684        /* free position buffer */
 685        if (bus->rb.area)
 686                snd_dma_free_pages(&bus->rb);
 687#endif
 688
 689        list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
 690                /* TODO: decouple */
 691
 692                /* free bdl buffer */
 693                if (s->bdl.area)
 694                        snd_dma_free_pages(&s->bdl);
 695                list_del(&s->list);
 696                stream = stream_to_hdac_ext_stream(s);
 697                hda_stream = container_of(stream, struct sof_intel_hda_stream,
 698                                          hda_stream);
 699                devm_kfree(sdev->dev, hda_stream);
 700        }
 701}
 702