^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // This file is provided under a dual BSD/GPLv2 license. When using or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // redistributing this file, you may do so under either license.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Copyright(c) 2018 Intel Corporation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) // Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) // Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) // Rander Wang <rander.wang@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) // Keyon Jie <yang.jie@linux.intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Hardware interface for generic Intel audio DSP HDA IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <sound/hdaudio_ext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <sound/hda_register.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <sound/sof.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "../ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "../sof-audio.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "hda.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define HDA_LTRP_GB_VALUE_US 95
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * set up one of BDL entries for a stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) static int hda_setup_bdle(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct snd_dma_buffer *dmab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) struct hdac_stream *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct sof_intel_dsp_bdl **bdlp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) int offset, int size, int ioc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) struct sof_intel_dsp_bdl *bdl = *bdlp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) while (size > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) dma_addr_t addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) if (stream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) dev_err(sdev->dev, "error: stream frags exceeded\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) addr = snd_sgbuf_get_addr(dmab, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* program BDL addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) bdl->addr_l = cpu_to_le32(lower_32_bits(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) bdl->addr_h = cpu_to_le32(upper_32_bits(addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /* program BDL size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) chunk = snd_sgbuf_get_chunk_size(dmab, offset, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* one BDLE should not cross 4K boundary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) if (bus->align_bdle_4k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 remain = 0x1000 - (offset & 0xfff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (chunk > remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) chunk = remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) bdl->size = cpu_to_le32(chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* only program IOC when the whole segment is processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) size -= chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) bdl++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) stream->frags++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) offset += chunk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) dev_vdbg(sdev->dev, "bdl, frags:%d, chunk size:0x%x;\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) stream->frags, chunk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) *bdlp = bdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * set up Buffer Descriptor List (BDL) for host memory transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * BDL describes the location of the individual buffers and is little endian.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct snd_dma_buffer *dmab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct hdac_stream *stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct sof_intel_dsp_bdl *bdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) int i, offset, period_bytes, periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) int remain, ioc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) period_bytes = stream->period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) dev_dbg(sdev->dev, "period_bytes:0x%x\n", period_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (!period_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) period_bytes = stream->bufsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) periods = stream->bufsize / period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dev_dbg(sdev->dev, "periods:%d\n", periods);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) remain = stream->bufsize % period_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) periods++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* program the initial BDL entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) bdl = (struct sof_intel_dsp_bdl *)stream->bdl.area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) stream->frags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * set IOC if don't use position IPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * and period_wakeup needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ioc = hda->no_ipc_position ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) !stream->no_period_wakeup : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) for (i = 0; i < periods; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (i == (periods - 1) && remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* set the last small entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) offset = hda_setup_bdle(sdev, dmab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) stream, &bdl, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) remain, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) offset = hda_setup_bdle(sdev, dmab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) stream, &bdl, offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) period_bytes, ioc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) struct hdac_ext_stream *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int enable, u32 size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct hdac_stream *hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) u32 mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (!sdev->bar[HDA_DSP_SPIB_BAR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_err(sdev->dev, "error: address of spib capability is NULL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) mask = (1 << hstream->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* enable/disable SPIB for the stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) snd_sof_dsp_update_bits(sdev, HDA_DSP_SPIB_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) SOF_HDA_ADSP_REG_CL_SPBFIFO_SPBFCCTL, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) enable << hstream->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) /* set the SPIB value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) sof_io_write(sdev, stream->spib_addr, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) /* get next unused stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) struct hdac_ext_stream *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct hdac_ext_stream *stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct hdac_stream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) spin_lock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* get an unused stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) list_for_each_entry(s, &bus->stream_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) if (s->direction == direction && !s->opened) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) stream = stream_to_hdac_ext_stream(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) hda_stream = container_of(stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct sof_intel_hda_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) hda_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* check if the host DMA channel is reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (hda_stream->host_reserved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) s->opened = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) spin_unlock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* stream found ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (!stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) dev_err(sdev->dev, "error: no free %s streams\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) direction == SNDRV_PCM_STREAM_PLAYBACK ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) "playback" : "capture");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * Disable DMI Link L1 entry when capture stream is opened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Workaround to address a known issue with host DMA that results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * in xruns during pause/release in capture scenarios.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (stream && direction == SNDRV_PCM_STREAM_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) HDA_VS_INTEL_EM2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) HDA_VS_INTEL_EM2_L1SEN, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) return stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /* free a stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) struct hdac_stream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) bool active_capture_stream = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) bool found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) spin_lock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * close stream matching the stream tag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) * and check if there are any open capture streams.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) list_for_each_entry(s, &bus->stream_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (!s->opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (s->direction == direction && s->stream_tag == stream_tag) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) s->opened = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) } else if (s->direction == SNDRV_PCM_STREAM_CAPTURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) active_capture_stream = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) spin_unlock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Enable DMI L1 entry if there are no capture streams open */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) if (!IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!active_capture_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) HDA_VS_INTEL_EM2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) HDA_VS_INTEL_EM2_L1SEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) HDA_VS_INTEL_EM2_L1SEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dev_dbg(sdev->dev, "stream_tag %d not opened!\n", stream_tag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct hdac_ext_stream *stream, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) struct hdac_stream *hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) u32 run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /* cmd must be for audio stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) case SNDRV_PCM_TRIGGER_RESUME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case SNDRV_PCM_TRIGGER_START:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 1 << hstream->index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 1 << hstream->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) SOF_HDA_SD_CTL_DMA_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) SOF_HDA_CL_DMA_SD_INT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) SOF_HDA_SD_CTL_DMA_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) SOF_HDA_CL_DMA_SD_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) ret = snd_sof_dsp_read_poll_timeout(sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) sd_offset, run,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) ((run & dma_start) == dma_start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) HDA_DSP_REG_POLL_INTERVAL_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) HDA_DSP_STREAM_RUN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) dev_err(sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) "error: %s: cmd %d: timeout on STREAM_SD_OFFSET read\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) hstream->running = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case SNDRV_PCM_TRIGGER_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) case SNDRV_PCM_TRIGGER_STOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) SOF_HDA_SD_CTL_DMA_START |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) SOF_HDA_CL_DMA_SD_INT_MASK, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) sd_offset, run,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) !(run & dma_start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) HDA_DSP_REG_POLL_INTERVAL_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) HDA_DSP_STREAM_RUN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) dev_err(sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) "error: %s: cmd %d: timeout on STREAM_SD_OFFSET read\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) __func__, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, sd_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) SOF_HDA_ADSP_REG_CL_SD_STS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) SOF_HDA_CL_DMA_SD_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) hstream->running = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 1 << hstream->index, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) dev_err(sdev->dev, "error: unknown command: %d\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* minimal recommended programming for ICCMAX stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) struct snd_dma_buffer *dmab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct hdac_stream *hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u32 mask = 0x1 << hstream->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) dev_err(sdev->dev, "error: no stream available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (hstream->posbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) *hstream->posbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) /* reset BDL address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) hstream->frags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) dev_err(sdev->dev, "error: set up of BDL failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* program BDL address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) (u32)hstream->bdl.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) upper_32_bits(hstream->bdl.addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* program cyclic buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) hstream->bufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* program last valid index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 0xffff, (hstream->frags - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) /* decouple host and link DMA, enable DSP features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) mask, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) /* Follow HW recommendation to set the guardband value to 95us during FW boot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) snd_hdac_chip_updateb(bus, VS_LTRP, HDA_VS_INTEL_LTRP_GB_MASK, HDA_LTRP_GB_VALUE_US);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* start DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) SOF_HDA_SD_CTL_DMA_START, SOF_HDA_SD_CTL_DMA_START);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * prepare for common hdac registers settings, for both code loader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * and normal stream.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct hdac_ext_stream *stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct snd_dma_buffer *dmab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct snd_pcm_hw_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct hdac_stream *hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret, timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u32 val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) u32 run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) dev_err(sdev->dev, "error: no stream available\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* decouple host and link DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) mask = 0x1 << hstream->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) mask, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (!dmab) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_err(sdev->dev, "error: no dma buffer allocated!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) /* clear stream status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) SOF_HDA_CL_DMA_SD_INT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) SOF_HDA_SD_CTL_DMA_START, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) sd_offset, run,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) !(run & dma_start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) HDA_DSP_REG_POLL_INTERVAL_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) HDA_DSP_STREAM_RUN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) dev_err(sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) "error: %s: timeout on STREAM_SD_OFFSET read1\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) SOF_HDA_CL_DMA_SD_INT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) SOF_HDA_CL_DMA_SD_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* stream reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) udelay(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) sd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (val & 0x1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) } while (--timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) dev_err(sdev->dev, "error: stream reset failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) timeout = HDA_DSP_STREAM_RESET_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset, 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* wait for hardware to report that stream is out of reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) udelay(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) val = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) sd_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if ((val & 0x1) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) } while (--timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (timeout == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) dev_err(sdev->dev, "error: timeout waiting for stream reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) return -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (hstream->posbuf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) *hstream->posbuf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* reset BDL address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) /* clear stream status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) SOF_HDA_CL_DMA_SD_INT_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) SOF_HDA_SD_CTL_DMA_START, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) ret = snd_sof_dsp_read_poll_timeout(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) sd_offset, run,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) !(run & dma_start),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) HDA_DSP_REG_POLL_INTERVAL_US,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) HDA_DSP_STREAM_RUN_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) dev_err(sdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) "error: %s: timeout on STREAM_SD_OFFSET read2\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) sd_offset + SOF_HDA_ADSP_REG_CL_SD_STS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) SOF_HDA_CL_DMA_SD_INT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) SOF_HDA_CL_DMA_SD_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) hstream->frags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = hda_dsp_stream_setup_bdl(sdev, dmab, hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dev_err(sdev->dev, "error: set up of BDL failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) /* program stream tag to set up stream descriptor for DMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) SOF_HDA_CL_SD_CTL_STREAM_TAG_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) hstream->stream_tag <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) SOF_HDA_CL_SD_CTL_STREAM_TAG_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /* program cyclic buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) sd_offset + SOF_HDA_ADSP_REG_CL_SD_CBL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) hstream->bufsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * Recommended hardware programming sequence for HDAudio DMA format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * 1. Put DMA into coupled mode by clearing PPCTL.PROCEN bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * for corresponding stream index before the time of writing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * format to SDxFMT register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * 2. Write SDxFMT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * 3. Set PPCTL.PROCEN bit for corresponding stream index to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * enable decoupled mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* couple host and link DMA, disable DSP features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* program stream format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) sd_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) SOF_HDA_ADSP_REG_CL_SD_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 0xffff, hstream->format_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) /* decouple host and link DMA, enable DSP features */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) mask, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) /* program last valid index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) sd_offset + SOF_HDA_ADSP_REG_CL_SD_LVI,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 0xffff, (hstream->frags - 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* program BDL address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) (u32)hstream->bdl.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) sd_offset + SOF_HDA_ADSP_REG_CL_SD_BDLPU,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) upper_32_bits(hstream->bdl.addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* enable position buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) if (!(snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) & SOF_HDA_ADSP_DPLBASE_ENABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPUBASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) upper_32_bits(bus->posbuf.addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_ADSP_DPLBASE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) (u32)bus->posbuf.addr |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) SOF_HDA_ADSP_DPLBASE_ENABLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* set interrupt enable bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) SOF_HDA_CL_DMA_SD_INT_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) SOF_HDA_CL_DMA_SD_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) /* read FIFO size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) hstream->fifo_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) sd_offset +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) SOF_HDA_ADSP_REG_CL_SD_FIFOSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) hstream->fifo_size &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) hstream->fifo_size += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) hstream->fifo_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) struct hdac_stream *stream = substream->runtime->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct hdac_ext_stream *link_dev = container_of(stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) struct hdac_ext_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u32 mask = 0x1 << stream->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) spin_lock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) /* couple host and link DMA if link DMA channel is idle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (!link_dev->link_locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) SOF_HDA_REG_PP_PPCTL, mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) spin_unlock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) stream->substream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) bool ret = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* The function can be called at irq thread, so use spin_lock_irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) spin_lock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) status = snd_hdac_chip_readl(bus, INTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) dev_vdbg(bus->dev, "stream irq, INTSTS status: 0x%x\n", status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) /* if Register inaccessible, ignore it.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (status != 0xffffffff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) spin_unlock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) hda_dsp_set_bytes_transferred(struct hdac_stream *hstream, u64 buffer_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) u64 prev_pos, pos, num_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) div64_u64_rem(hstream->curr_pos, buffer_size, &prev_pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) pos = snd_hdac_stream_get_pos_posbuf(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if (pos < prev_pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) num_bytes = (buffer_size - prev_pos) + pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) num_bytes = pos - prev_pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) hstream->curr_pos += num_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static bool hda_dsp_stream_check(struct hdac_bus *bus, u32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct hdac_stream *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) bool active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) u32 sd_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) list_for_each_entry(s, &bus->stream_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) if (status & BIT(s->index) && s->opened) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) sd_status = snd_hdac_stream_readb(s, SD_STS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) dev_vdbg(bus->dev, "stream %d status 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) s->index, sd_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) snd_hdac_stream_writeb(s, SD_STS, sd_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) if ((!s->substream && !s->cstream) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) !s->running ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) (sd_status & SOF_HDA_CL_DMA_SD_INT_COMPLETE) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) /* Inform ALSA only in case not do that with IPC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (s->substream && sof_hda->no_ipc_position) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) snd_sof_pcm_period_elapsed(s->substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) } else if (s->cstream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) hda_dsp_set_bytes_transferred(s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) s->cstream->runtime->buffer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) snd_compr_fragment_elapsed(s->cstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct snd_sof_dev *sdev = context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) u32 rirb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) bool active;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) u32 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * Loop 10 times to handle missed interrupts caused by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * unsolicited responses from the codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) for (i = 0, active = true; i < 10 && active; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) spin_lock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) status = snd_hdac_chip_readl(bus, INTSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) /* check streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) active = hda_dsp_stream_check(bus, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /* check and clear RIRB interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (status & AZX_INT_CTRL_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) rirb_status = snd_hdac_chip_readb(bus, RIRBSTS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (rirb_status & RIRB_INT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) * Clearing the interrupt status here ensures
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) * that no interrupt gets masked after the RIRB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) * wp is read in snd_hdac_bus_update_rirb.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) snd_hdac_chip_writeb(bus, RIRBSTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) RIRB_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (rirb_status & RIRB_INT_RESPONSE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) snd_hdac_bus_update_rirb(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) spin_unlock_irq(&bus->reg_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) int hda_dsp_stream_init(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct hdac_ext_stream *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct hdac_stream *hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct pci_dev *pci = to_pci_dev(sdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) int sd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) int i, num_playback, num_capture, num_total, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) u32 gcap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) gcap = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_GCAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) dev_dbg(sdev->dev, "hda global caps = 0x%x\n", gcap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* get stream count from GCAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) num_capture = (gcap >> 8) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) num_playback = (gcap >> 12) & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) num_total = num_playback + num_capture;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) dev_dbg(sdev->dev, "detected %d playback and %d capture streams\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) num_playback, num_capture);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (num_playback >= SOF_HDA_PLAYBACK_STREAMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) dev_err(sdev->dev, "error: too many playback streams %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) num_playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) if (num_capture >= SOF_HDA_CAPTURE_STREAMS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) dev_err(sdev->dev, "error: too many capture streams %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) num_playback);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * mem alloc for the position buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * TODO: check position buffer update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) SOF_HDA_DPIB_ENTRY_SIZE * num_total,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) &bus->posbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) dev_err(sdev->dev, "error: posbuffer dma alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) /* mem alloc for the CORB/RIRB ringbuffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) PAGE_SIZE, &bus->rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dev_err(sdev->dev, "error: RB alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) /* create capture streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) for (i = 0; i < num_capture; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (!hda_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) hda_stream->sdev = sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) stream = &hda_stream->hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) SOF_HDA_PPLC_INTERVAL * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) /* do we support SPIB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (sdev->bar[HDA_DSP_SPIB_BAR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) SOF_HDA_SPIB_SPIB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) SOF_HDA_SPIB_MAXFIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) hstream->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) hstream->sd_int_sta_mask = 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) hstream->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) sd_offset = SOF_STREAM_SD_OFFSET(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) hstream->stream_tag = i + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) hstream->opened = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) hstream->running = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) hstream->direction = SNDRV_PCM_STREAM_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) /* memory alloc for stream BDL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) HDA_DSP_BDL_SIZE, &hstream->bdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) hstream->posbuf = (__le32 *)(bus->posbuf.area +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) (hstream->index) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) list_add_tail(&hstream->list, &bus->stream_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* create playback streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) for (i = num_capture; i < num_total; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) hda_stream = devm_kzalloc(sdev->dev, sizeof(*hda_stream),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!hda_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) hda_stream->sdev = sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) stream = &hda_stream->hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* we always have DSP support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) SOF_HDA_PPLC_INTERVAL * i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) /* do we support SPIB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (sdev->bar[HDA_DSP_SPIB_BAR]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) SOF_HDA_SPIB_SPIB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) SOF_HDA_SPIB_MAXFIFO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) hstream = &stream->hstream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) hstream->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) hstream->sd_int_sta_mask = 1 << i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) hstream->index = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) sd_offset = SOF_STREAM_SD_OFFSET(hstream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) hstream->sd_addr = sdev->bar[HDA_DSP_HDA_BAR] + sd_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) hstream->stream_tag = i - num_capture + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) hstream->opened = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) hstream->running = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) hstream->direction = SNDRV_PCM_STREAM_PLAYBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) /* mem alloc for stream BDL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) HDA_DSP_BDL_SIZE, &hstream->bdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) dev_err(sdev->dev, "error: stream bdl dma alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) hstream->posbuf = (__le32 *)(bus->posbuf.area +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) (hstream->index) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) list_add_tail(&hstream->list, &bus->stream_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* store total stream count (playback + capture) from GCAP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) sof_hda->stream_max = num_total;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) void hda_dsp_stream_free(struct snd_sof_dev *sdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct hdac_bus *bus = sof_to_bus(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) struct hdac_stream *s, *_s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) struct hdac_ext_stream *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct sof_intel_hda_stream *hda_stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* free position buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (bus->posbuf.area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) snd_dma_free_pages(&bus->posbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) /* free position buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) if (bus->rb.area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) snd_dma_free_pages(&bus->rb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) list_for_each_entry_safe(s, _s, &bus->stream_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* TODO: decouple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* free bdl buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if (s->bdl.area)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) snd_dma_free_pages(&s->bdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) list_del(&s->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) stream = stream_to_hdac_ext_stream(s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) hda_stream = container_of(stream, struct sof_intel_hda_stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) hda_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) devm_kfree(sdev->dev, hda_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) }