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 sof_intel_hda_stream *hda_stream;
 159        struct hdac_ext_stream *stream = NULL;
 160        struct hdac_stream *s;
 161
 162        spin_lock_irq(&bus->reg_lock);
 163
 164        /* get an unused stream */
 165        list_for_each_entry(s, &bus->stream_list, list) {
 166                if (s->direction == direction && !s->opened) {
 167                        stream = stream_to_hdac_ext_stream(s);
 168                        hda_stream = container_of(stream,
 169                                                  struct sof_intel_hda_stream,
 170                                                  hda_stream);
 171                        /* check if the host DMA channel is reserved */
 172                        if (hda_stream->host_reserved)
 173                                continue;
 174
 175                        s->opened = true;
 176                        break;
 177                }
 178        }
 179
 180        spin_unlock_irq(&bus->reg_lock);
 181
 182        /* stream found ? */
 183        if (!stream)
 184                dev_err(sdev->dev, "error: no free %s streams\n",
 185                        direction == SNDRV_PCM_STREAM_PLAYBACK ?
 186                        "playback" : "capture");
 187
 188        /*
 189         * Disable DMI Link L1 entry when capture stream is opened.
 190         * Workaround to address a known issue with host DMA that results
 191         * in xruns during pause/release in capture scenarios.
 192         */
 193        if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
 194                if (stream && direction == SNDRV_PCM_STREAM_CAPTURE)
 195                        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 196                                                HDA_VS_INTEL_EM2,
 197                                                HDA_VS_INTEL_EM2_L1SEN, 0);
 198
 199        return stream;
 200}
 201
 202/* free a stream */
 203int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
 204{
 205        struct hdac_bus *bus = sof_to_bus(sdev);
 206        struct hdac_stream *s;
 207        bool active_capture_stream = false;
 208        bool found = false;
 209
 210        spin_lock_irq(&bus->reg_lock);
 211
 212        /*
 213         * close stream matching the stream tag
 214         * and check if there are any open capture streams.
 215         */
 216        list_for_each_entry(s, &bus->stream_list, list) {
 217                if (!s->opened)
 218                        continue;
 219
 220                if (s->direction == direction && s->stream_tag == stream_tag) {
 221                        s->opened = false;
 222                        found = true;
 223                } else if (s->direction == SNDRV_PCM_STREAM_CAPTURE) {
 224                        active_capture_stream = true;
 225                }
 226        }
 227
 228        spin_unlock_irq(&bus->reg_lock);
 229
 230        /* Enable DMI L1 entry if there are no capture streams open */
 231        if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
 232                if (!active_capture_stream)
 233                        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 234                                                HDA_VS_INTEL_EM2,
 235                                                HDA_VS_INTEL_EM2_L1SEN,
 236                                                HDA_VS_INTEL_EM2_L1SEN);
 237
 238        if (!found) {
 239                dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag);
 240                return -ENODEV;
 241        }
 242
 243        return 0;
 244}
 245
 246int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
 247                           struct hdac_ext_stream *stream, int cmd)
 248{
 249        struct hdac_stream *hstream = &stream->hstream;
 250        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 251        u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
 252        int ret;
 253        u32 run;
 254
 255        /* cmd must be for audio stream */
 256        switch (cmd) {
 257        case SNDRV_PCM_TRIGGER_RESUME:
 258        case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 259        case SNDRV_PCM_TRIGGER_START:
 260                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
 261                                        1 << hstream->index,
 262                                        1 << hstream->index);
 263
 264                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 265                                        sd_offset,
 266                                        SOF_HDA_SD_CTL_DMA_START |
 267                                        SOF_HDA_CL_DMA_SD_INT_MASK,
 268                                        SOF_HDA_SD_CTL_DMA_START |
 269                                        SOF_HDA_CL_DMA_SD_INT_MASK);
 270
 271                ret = snd_sof_dsp_read_poll_timeout(sdev,
 272                                        HDA_DSP_HDA_BAR,
 273                                        sd_offset, run,
 274                                        ((run & dma_start) == dma_start),
 275                                        HDA_DSP_REG_POLL_INTERVAL_US,
 276                                        HDA_DSP_STREAM_RUN_TIMEOUT);
 277
 278                if (ret)
 279                        return ret;
 280
 281                hstream->running = true;
 282                break;
 283        case SNDRV_PCM_TRIGGER_SUSPEND:
 284        case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 285        case SNDRV_PCM_TRIGGER_STOP:
 286                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 287                                        sd_offset,
 288                                        SOF_HDA_SD_CTL_DMA_START |
 289                                        SOF_HDA_CL_DMA_SD_INT_MASK, 0x0);
 290
 291                ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
 292                                                sd_offset, run,
 293                                                !(run & dma_start),
 294                                                HDA_DSP_REG_POLL_INTERVAL_US,
 295                                                HDA_DSP_STREAM_RUN_TIMEOUT);
 296
 297                if (ret)
 298                        return ret;
 299
 300                snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset +
 301                                  SOF_HDA_ADSP_REG_CL_SD_STS,
 302                                  SOF_HDA_CL_DMA_SD_INT_MASK);
 303
 304                hstream->running = false;
 305                snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
 306                                        1 << hstream->index, 0x0);
 307                break;
 308        default:
 309                dev_err(sdev->dev, "error: unknown command: %d\n", cmd);
 310                return -EINVAL;
 311        }
 312
 313        return 0;
 314}
 315
 316/*
 317 * prepare for common hdac registers settings, for both code loader
 318 * and normal stream.
 319 */
 320int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
 321                             struct hdac_ext_stream *stream,
 322                             struct snd_dma_buffer *dmab,
 323                             struct snd_pcm_hw_params *params)
 324{
 325        struct hdac_bus *bus = sof_to_bus(sdev);
 326        struct hdac_stream *hstream = &stream->hstream;
 327        int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 328        int ret, timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
 329        u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
 330        u32 val, mask;
 331        u32 run;
 332
 333        if (!stream) {
 334                dev_err(sdev->dev, "error: no stream available\n");
 335                return -ENODEV;
 336        }
 337
 338        /* decouple host and link DMA */
 339        mask = 0x1 << hstream->index;
 340        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
 341                                mask, mask);
 342
 343        if (!dmab) {
 344                dev_err(sdev->dev, "error: no dma buffer allocated!\n");
 345                return -ENODEV;
 346        }
 347
 348        /* clear stream status */
 349        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 350                                SOF_HDA_CL_DMA_SD_INT_MASK |
 351                                SOF_HDA_SD_CTL_DMA_START, 0);
 352
 353        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
 354                                            sd_offset, run,
 355                                            !(run & dma_start),
 356                                            HDA_DSP_REG_POLL_INTERVAL_US,
 357                                            HDA_DSP_STREAM_RUN_TIMEOUT);
 358
 359        if (ret)
 360                return ret;
 361
 362        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 363                                sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
 364                                SOF_HDA_CL_DMA_SD_INT_MASK,
 365                                SOF_HDA_CL_DMA_SD_INT_MASK);
 366
 367        /* stream reset */
 368        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
 369                                0x1);
 370        udelay(3);
 371        do {
 372                val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
 373                                       sd_offset);
 374                if (val & 0x1)
 375                        break;
 376        } while (--timeout);
 377        if (timeout == 0) {
 378                dev_err(sdev->dev, "error: stream reset failed\n");
 379                return -ETIMEDOUT;
 380        }
 381
 382        timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
 383        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
 384                                0x0);
 385
 386        /* wait for hardware to report that stream is out of reset */
 387        udelay(3);
 388        do {
 389                val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
 390                                       sd_offset);
 391                if ((val & 0x1) == 0)
 392                        break;
 393        } while (--timeout);
 394        if (timeout == 0) {
 395                dev_err(sdev->dev, "error: timeout waiting for stream reset\n");
 396                return -ETIMEDOUT;
 397        }
 398
 399        if (hstream->posbuf)
 400                *hstream->posbuf = 0;
 401
 402        /* reset BDL address */
 403        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 404                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
 405                          0x0);
 406        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 407                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
 408                          0x0);
 409
 410        /* clear stream status */
 411        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 412                                SOF_HDA_CL_DMA_SD_INT_MASK |
 413                                SOF_HDA_SD_CTL_DMA_START, 0);
 414
 415        ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
 416                                            sd_offset, run,
 417                                            !(run & dma_start),
 418                                            HDA_DSP_REG_POLL_INTERVAL_US,
 419                                            HDA_DSP_STREAM_RUN_TIMEOUT);
 420
 421        if (ret)
 422                return ret;
 423
 424        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 425                                sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
 426                                SOF_HDA_CL_DMA_SD_INT_MASK,
 427                                SOF_HDA_CL_DMA_SD_INT_MASK);
 428
 429        hstream->frags = 0;
 430
 431        ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
 432        if (ret < 0) {
 433                dev_err(sdev->dev, "error: set up of BDL failed\n");
 434                return ret;
 435        }
 436
 437        /* program stream tag to set up stream descriptor for DMA */
 438        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 439                                SOF_HDA_CL_SD_CTL_STREAM_TAG_MASK,
 440                                hstream->stream_tag <<
 441                                SOF_HDA_CL_SD_CTL_STREAM_TAG_SHIFT);
 442
 443        /* program cyclic buffer length */
 444        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 445                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
 446                          hstream->bufsize);
 447
 448        /*
 449         * Recommended hardware programming sequence for HDAudio DMA format
 450         *
 451         * 1. Put DMA into coupled mode by clearing PPCTL.PROCEN bit
 452         *    for corresponding stream index before the time of writing
 453         *    format to SDxFMT register.
 454         * 2. Write SDxFMT
 455         * 3. Set PPCTL.PROCEN bit for corresponding stream index to
 456         *    enable decoupled mode
 457         */
 458
 459        /* couple host and link DMA, disable DSP features */
 460        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
 461                                mask, 0);
 462
 463        /* program stream format */
 464        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 465                                sd_offset +
 466                                SOF_HDA_ADSP_REG_CL_SD_FORMAT,
 467                                0xffff, hstream->format_val);
 468
 469        /* decouple host and link DMA, enable DSP features */
 470        snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
 471                                mask, mask);
 472
 473        /* program last valid index */
 474        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
 475                                sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
 476                                0xffff, (hstream->frags - 1));
 477
 478        /* program BDL address */
 479        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 480                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
 481                          (u32)hstream->bdl.addr);
 482        snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
 483                          sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
 484                          upper_32_bits(hstream->bdl.addr));
 485
 486        /* enable position buffer */
 487        if (!(snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE)
 488                                & SOF_HDA_ADSP_DPLBASE_ENABLE)) {
 489                snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
 490                                  upper_32_bits(bus->posbuf.addr));
 491                snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
 492                                  (u32)bus->posbuf.addr |
 493                                  SOF_HDA_ADSP_DPLBASE_ENABLE);
 494        }
 495
 496        /* set interrupt enable bits */
 497        snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
 498                                SOF_HDA_CL_DMA_SD_INT_MASK,
 499                                SOF_HDA_CL_DMA_SD_INT_MASK);
 500
 501        /* read FIFO size */
 502        if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) {
 503                hstream->fifo_size =
 504                        snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
 505                                         sd_offset +
 506                                         SOF_HDA_ADSP_REG_CL_SD_FIFOSIZE);
 507                hstream->fifo_size &= 0xffff;
 508                hstream->fifo_size += 1;
 509        } else {
 510                hstream->fifo_size = 0;
 511        }
 512
 513        return ret;
 514}
 515
 516int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
 517                           struct snd_pcm_substream *substream)
 518{
 519        struct hdac_stream *stream = substream->runtime->private_data;
 520        struct hdac_ext_stream *link_dev = container_of(stream,
 521                                                        struct hdac_ext_stream,
 522                                                        hstream);
 523        struct hdac_bus *bus = sof_to_bus(sdev);
 524        u32 mask = 0x1 << stream->index;
 525
 526        spin_lock_irq(&bus->reg_lock);
 527        /* couple host and link DMA if link DMA channel is idle */
 528        if (!link_dev->link_locked)
 529                snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR,
 530                                        SOF_HDA_REG_PP_PPCTL, mask, 0);
 531        spin_unlock_irq(&bus->reg_lock);
 532
 533        return 0;
 534}
 535
 536irqreturn_t hda_dsp_stream_interrupt(int irq, void *context)
 537{
 538        struct hdac_bus *bus = context;
 539        int ret = IRQ_WAKE_THREAD;
 540        u32 status;
 541
 542        spin_lock(&bus->reg_lock);
 543
 544        status = snd_hdac_chip_readl(bus, INTSTS);
 545        dev_vdbg(bus->dev, "stream irq, INTSTS status: 0x%x\n", status);
 546
 547        /* Register inaccessible, ignore it.*/
 548        if (status == 0xffffffff)
 549                ret = IRQ_NONE;
 550
 551        spin_unlock(&bus->reg_lock);
 552
 553        return ret;
 554}
 555
 556static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
 557{
 558        struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
 559        struct hdac_stream *s;
 560        bool active = false;
 561        u32 sd_status;
 562
 563        list_for_each_entry(s, &bus->stream_list, list) {
 564                if (status & BIT(s->index) && s->opened) {
 565                        sd_status = snd_hdac_stream_readb(s, SD_STS);
 566
 567                        dev_vdbg(bus->dev, "stream %d status 0x%x\n",
 568                                 s->index, sd_status);
 569
 570                        snd_hdac_stream_writeb(s, SD_STS, sd_status);
 571
 572                        active = true;
 573                        if (!s->substream ||
 574                            !s->running ||
 575                            (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
 576                                continue;
 577
 578                        /* Inform ALSA only in case not do that with IPC */
 579                        if (sof_hda->no_ipc_position)
 580                                snd_sof_pcm_period_elapsed(s->substream);
 581                }
 582        }
 583
 584        return active;
 585}
 586
 587irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
 588{
 589        struct hdac_bus *bus = context;
 590#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 591        u32 rirb_status;
 592#endif
 593        bool active;
 594        u32 status;
 595        int i;
 596
 597        /*
 598         * Loop 10 times to handle missed interrupts caused by
 599         * unsolicited responses from the codec
 600         */
 601        for (i = 0, active = true; i < 10 && active; i++) {
 602                spin_lock_irq(&bus->reg_lock);
 603
 604                status = snd_hdac_chip_readl(bus, INTSTS);
 605
 606                /* check streams */
 607                active = hda_dsp_stream_check(bus, status);
 608
 609                /* check and clear RIRB interrupt */
 610#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 611                if (status & AZX_INT_CTRL_EN) {
 612                        rirb_status = snd_hdac_chip_readb(bus, RIRBSTS);
 613                        if (rirb_status & RIRB_INT_MASK) {
 614                                active = true;
 615                                if (rirb_status & RIRB_INT_RESPONSE)
 616                                        snd_hdac_bus_update_rirb(bus);
 617                                snd_hdac_chip_writeb(bus, RIRBSTS,
 618                                                     RIRB_INT_MASK);
 619                        }
 620                }
 621#endif
 622                spin_unlock_irq(&bus->reg_lock);
 623        }
 624
 625        return IRQ_HANDLED;
 626}
 627
 628int hda_dsp_stream_init(struct snd_sof_dev *sdev)
 629{
 630        struct hdac_bus *bus = sof_to_bus(sdev);
 631        struct hdac_ext_stream *stream;
 632        struct hdac_stream *hstream;
 633        struct pci_dev *pci = to_pci_dev(sdev->dev);
 634        struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
 635        int sd_offset;
 636        int i, num_playback, num_capture, num_total, ret;
 637        u32 gcap;
 638
 639        gcap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCAP);
 640        dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap);
 641
 642        /* get stream count from GCAP */
 643        num_capture = (gcap >> 8) & 0x0f;
 644        num_playback = (gcap >> 12) & 0x0f;
 645        num_total = num_playback + num_capture;
 646
 647        dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n",
 648                num_playback, num_capture);
 649
 650        if (num_playback >= SOF_HDA_PLAYBACK_STREAMS) {
 651                dev_err(sdev->dev, "error: too many playback streams %d\n",
 652                        num_playback);
 653                return -EINVAL;
 654        }
 655
 656        if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
 657                dev_err(sdev->dev, "error: too many capture streams %d\n",
 658                        num_playback);
 659                return -EINVAL;
 660        }
 661
 662        /*
 663         * mem alloc for the position buffer
 664         * TODO: check position buffer update
 665         */
 666        ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 667                                  SOF_HDA_DPIB_ENTRY_SIZE * num_total,
 668                                  &bus->posbuf);
 669        if (ret < 0) {
 670                dev_err(sdev->dev, "error: posbuffer dma alloc failed\n");
 671                return -ENOMEM;
 672        }
 673
 674#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 675        /* mem alloc for the CORB/RIRB ringbuffers */
 676        ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 677                                  PAGE_SIZE, &bus->rb);
 678        if (ret < 0) {
 679                dev_err(sdev->dev, "error: RB alloc failed\n");
 680                return -ENOMEM;
 681        }
 682#endif
 683
 684        /* create capture streams */
 685        for (i = 0; i < num_capture; i++) {
 686                struct sof_intel_hda_stream *hda_stream;
 687
 688                hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
 689                                          GFP_KERNEL);
 690                if (!hda_stream)
 691                        return -ENOMEM;
 692
 693                hda_stream->sdev = sdev;
 694
 695                stream = &hda_stream->hda_stream;
 696
 697                stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 698                        SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
 699
 700                stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 701                        SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
 702                        SOF_HDA_PPLC_INTERVAL * i;
 703
 704                /* do we support SPIB */
 705                if (sdev->bar[HDA_DSP_SPIB_BAR]) {
 706                        stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 707                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 708                                SOF_HDA_SPIB_SPIB;
 709
 710                        stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 711                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 712                                SOF_HDA_SPIB_MAXFIFO;
 713                }
 714
 715                hstream = &stream->hstream;
 716                hstream->bus = bus;
 717                hstream->sd_int_sta_mask = 1 << i;
 718                hstream->index = i;
 719                sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 720                hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
 721                hstream->stream_tag = i + 1;
 722                hstream->opened = false;
 723                hstream->running = false;
 724                hstream->direction = SNDRV_PCM_STREAM_CAPTURE;
 725
 726                /* memory alloc for stream BDL */
 727                ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 728                                          HDA_DSP_BDL_SIZE, &hstream->bdl);
 729                if (ret < 0) {
 730                        dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
 731                        return -ENOMEM;
 732                }
 733                hstream->posbuf = (__le32 *)(bus->posbuf.area +
 734                        (hstream->index) * 8);
 735
 736                list_add_tail(&hstream->list, &bus->stream_list);
 737        }
 738
 739        /* create playback streams */
 740        for (i = num_capture; i < num_total; i++) {
 741                struct sof_intel_hda_stream *hda_stream;
 742
 743                hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
 744                                          GFP_KERNEL);
 745                if (!hda_stream)
 746                        return -ENOMEM;
 747
 748                hda_stream->sdev = sdev;
 749
 750                stream = &hda_stream->hda_stream;
 751
 752                /* we always have DSP support */
 753                stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 754                        SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
 755
 756                stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
 757                        SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
 758                        SOF_HDA_PPLC_INTERVAL * i;
 759
 760                /* do we support SPIB */
 761                if (sdev->bar[HDA_DSP_SPIB_BAR]) {
 762                        stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 763                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 764                                SOF_HDA_SPIB_SPIB;
 765
 766                        stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
 767                                SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
 768                                SOF_HDA_SPIB_MAXFIFO;
 769                }
 770
 771                hstream = &stream->hstream;
 772                hstream->bus = bus;
 773                hstream->sd_int_sta_mask = 1 << i;
 774                hstream->index = i;
 775                sd_offset = SOF_STREAM_SD_OFFSET(hstream);
 776                hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
 777                hstream->stream_tag = i - num_capture + 1;
 778                hstream->opened = false;
 779                hstream->running = false;
 780                hstream->direction = SNDRV_PCM_STREAM_PLAYBACK;
 781
 782                /* mem alloc for stream BDL */
 783                ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
 784                                          HDA_DSP_BDL_SIZE, &hstream->bdl);
 785                if (ret < 0) {
 786                        dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
 787                        return -ENOMEM;
 788                }
 789
 790                hstream->posbuf = (__le32 *)(bus->posbuf.area +
 791                        (hstream->index) * 8);
 792
 793                list_add_tail(&hstream->list, &bus->stream_list);
 794        }
 795
 796        /* store total stream count (playback + capture) from GCAP */
 797        sof_hda->stream_max = num_total;
 798
 799        return 0;
 800}
 801
 802void hda_dsp_stream_free(struct snd_sof_dev *sdev)
 803{
 804        struct hdac_bus *bus = sof_to_bus(sdev);
 805        struct hdac_stream *s, *_s;
 806        struct hdac_ext_stream *stream;
 807        struct sof_intel_hda_stream *hda_stream;
 808
 809        /* free position buffer */
 810        if (bus->posbuf.area)
 811                snd_dma_free_pages(&bus->posbuf);
 812
 813#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
 814        /* free position buffer */
 815        if (bus->rb.area)
 816                snd_dma_free_pages(&bus->rb);
 817#endif
 818
 819        list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
 820                /* TODO: decouple */
 821
 822                /* free bdl buffer */
 823                if (s->bdl.area)
 824                        snd_dma_free_pages(&s->bdl);
 825                list_del(&s->list);
 826                stream = stream_to_hdac_ext_stream(s);
 827                hda_stream = container_of(stream, struct sof_intel_hda_stream,
 828                                          hda_stream);
 829                devm_kfree(sdev->dev, hda_stream);
 830        }
 831}
 832