diff options
author | Linus Torvalds | 2019-08-09 18:21:27 +0200 |
---|---|---|
committer | Linus Torvalds | 2019-08-09 18:21:27 +0200 |
commit | cb42f06c9f418ec2ee56667d01e9ba965a4c61c9 (patch) | |
tree | da6a0b3ff41dc4ee67358cc0faf4139a2ab71dc5 /sound/pci/hda/hda_intel.c | |
parent | Merge tag 'media/v5.3-3' of git://git.kernel.org/pub/scm/linux/kernel/git/mch... (diff) | |
parent | ALSA: firewire: fix a memory leak bug (diff) | |
download | kernel-qcow2-linux-cb42f06c9f418ec2ee56667d01e9ba965a4c61c9.tar.gz kernel-qcow2-linux-cb42f06c9f418ec2ee56667d01e9ba965a4c61c9.tar.xz kernel-qcow2-linux-cb42f06c9f418ec2ee56667d01e9ba965a4c61c9.zip |
Merge tag 'sound-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound fixes from Takashi Iwai:
"Lots of small fixes at this time since we've received the ASoC fix
batch now.
- Some coverage in ASoC core mostly for minor issues like NULL checks
for DPCM and proper error handling in DAI instantiation
- A collection of small device-specific changes in various ASoC codec
and platform drivers
- OF-tree refcount fixes in a few ASoC drivers
- Fixes of memory leaks in the error paths of various ASoC / ALSA
drivers
- A workaround for a long-standing issue on AMD HD-audio device
- Updates of MAINTAINERS, mail addresses, file permission fixups"
* tag 'sound-5.3-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (38 commits)
ALSA: firewire: fix a memory leak bug
sound: fix a memory leak bug
ALSA: hda - Workaround for crackled sound on AMD controller (1022:1457)
ALSA: hiface: fix multiple memory leak bugs
ALSA: hda - Don't override global PCM hw info flag
ALSA: usb-audio: fix a memory leak bug
ASoC: max98373: Remove executable bits
ASoC: amd: acp3x: use dma address for acp3x dma driver
ASoC: amd: acp3x: use dma_ops of parent device for acp3x dma driver
ASoC: max98373: add 88200 and 96000 sampling rate support
ASoC: sun4i-i2s: Incorrect SR and WSS computation
MAINTAINERS: Update Intel ASoC drivers maintainers
ASoC: ti: davinci-mcasp: Correct slot_width posed constraint
ASoC: rockchip: Fix mono capture
ASoC: Intel: Fix some acpi vs apci typo in somme comments
ASoC: ti: davinci-mcasp: Fix clk PDIR handling for i2s master mode
ASoC: Fail card instantiation if DAI format setup fails
ASoC: SOF: Intel: hda: remove misleading error trace from IRQ thread
ASoC: qcom: apq8016_sbc: Fix oops with multiple DAI links
ASoC: dapm: fix a memory leak bug
...
Diffstat (limited to 'sound/pci/hda/hda_intel.c')
-rw-r--r-- | sound/pci/hda/hda_intel.c | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1e14d7270adf..a6d8c0d77b84 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -64,6 +64,7 @@ enum { POS_FIX_VIACOMBO, POS_FIX_COMBO, POS_FIX_SKL, + POS_FIX_FIFO, }; /* Defines for ATI HD Audio support in SB450 south bridge */ @@ -135,7 +136,7 @@ module_param_array(model, charp, NULL, 0444); MODULE_PARM_DESC(model, "Use the given board model."); module_param_array(position_fix, int, NULL, 0444); MODULE_PARM_DESC(position_fix, "DMA pointer read method." - "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+)."); + "(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO)."); module_param_array(bdl_pos_adj, int, NULL, 0644); MODULE_PARM_DESC(bdl_pos_adj, "BDL position adjustment offset."); module_param_array(probe_mask, int, NULL, 0444); @@ -332,6 +333,11 @@ enum { #define AZX_DCAPS_PRESET_ATI_HDMI_NS \ (AZX_DCAPS_PRESET_ATI_HDMI | AZX_DCAPS_SNOOP_OFF) +/* quirks for AMD SB */ +#define AZX_DCAPS_PRESET_AMD_SB \ + (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_AMD_WORKAROUND |\ + AZX_DCAPS_SNOOP_TYPE(ATI) | AZX_DCAPS_PM_RUNTIME) + /* quirks for Nvidia */ #define AZX_DCAPS_PRESET_NVIDIA \ (AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\ @@ -841,6 +847,49 @@ static unsigned int azx_via_get_position(struct azx *chip, return bound_pos + mod_dma_pos; } +#define AMD_FIFO_SIZE 32 + +/* get the current DMA position with FIFO size correction */ +static unsigned int azx_get_pos_fifo(struct azx *chip, struct azx_dev *azx_dev) +{ + struct snd_pcm_substream *substream = azx_dev->core.substream; + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned int pos, delay; + + pos = snd_hdac_stream_get_pos_lpib(azx_stream(azx_dev)); + if (!runtime) + return pos; + + runtime->delay = AMD_FIFO_SIZE; + delay = frames_to_bytes(runtime, AMD_FIFO_SIZE); + if (azx_dev->insufficient) { + if (pos < delay) { + delay = pos; + runtime->delay = bytes_to_frames(runtime, pos); + } else { + azx_dev->insufficient = 0; + } + } + + /* correct the DMA position for capture stream */ + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + if (pos < delay) + pos += azx_dev->core.bufsize; + pos -= delay; + } + + return pos; +} + +static int azx_get_delay_from_fifo(struct azx *chip, struct azx_dev *azx_dev, + unsigned int pos) +{ + struct snd_pcm_substream *substream = azx_dev->core.substream; + + /* just read back the calculated value in the above */ + return substream->runtime->delay; +} + static unsigned int azx_skl_get_dpib_pos(struct azx *chip, struct azx_dev *azx_dev) { @@ -1417,6 +1466,7 @@ static int check_position_fix(struct azx *chip, int fix) case POS_FIX_VIACOMBO: case POS_FIX_COMBO: case POS_FIX_SKL: + case POS_FIX_FIFO: return fix; } @@ -1433,6 +1483,10 @@ static int check_position_fix(struct azx *chip, int fix) dev_dbg(chip->card->dev, "Using VIACOMBO position fix\n"); return POS_FIX_VIACOMBO; } + if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) { + dev_dbg(chip->card->dev, "Using FIFO position fix\n"); + return POS_FIX_FIFO; + } if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) { dev_dbg(chip->card->dev, "Using LPIB position fix\n"); return POS_FIX_LPIB; @@ -1453,6 +1507,7 @@ static void assign_position_fix(struct azx *chip, int fix) [POS_FIX_VIACOMBO] = azx_via_get_position, [POS_FIX_COMBO] = azx_get_pos_lpib, [POS_FIX_SKL] = azx_get_pos_skl, + [POS_FIX_FIFO] = azx_get_pos_fifo, }; chip->get_position[0] = chip->get_position[1] = callbacks[fix]; @@ -1467,6 +1522,9 @@ static void assign_position_fix(struct azx *chip, int fix) azx_get_delay_from_lpib; } + if (fix == POS_FIX_FIFO) + chip->get_delay[0] = chip->get_delay[1] = + azx_get_delay_from_fifo; } /* @@ -2447,6 +2505,9 @@ static const struct pci_device_id azx_ids[] = { /* AMD Hudson */ { PCI_DEVICE(0x1022, 0x780d), .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, + /* AMD, X370 & co */ + { PCI_DEVICE(0x1022, 0x1457), + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_AMD_SB }, /* AMD Stoney */ { PCI_DEVICE(0x1022, 0x157a), .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB | |