Created
August 9, 2019 04:05
-
-
Save gort818/3ab8ef71fb09d41df7f734840fec1e1d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c | |
index 2fbdde239936..48d863736b3c 100644 | |
--- a/sound/pci/hda/hda_controller.c | |
+++ b/sound/pci/hda/hda_controller.c | |
@@ -613,6 +613,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) | |
20, | |
178000000); | |
+ /* by some reason, the playback stream stalls on PulseAudio with | |
+ * tsched=1 when a capture stream triggers. Until we figure out the | |
+ * real cause, disable tsched mode by telling the PCM info flag. | |
+ */ | |
+ if (chip->driver_caps & AZX_DCAPS_AMD_WORKAROUND) | |
+ runtime->hw.info |= SNDRV_PCM_INFO_BATCH; | |
+ | |
if (chip->align_buffer_size) | |
/* constrain buffer sizes to be multiple of 128 | |
bytes. This is more efficient in terms of memory | |
diff --git a/sound/pci/hda/hda_controller.h b/sound/pci/hda/hda_controller.h | |
index baa15374fbcb..f2a6df5e6bcb 100644 | |
--- a/sound/pci/hda/hda_controller.h | |
+++ b/sound/pci/hda/hda_controller.h | |
@@ -31,7 +31,7 @@ | |
/* 14 unused */ | |
#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ | |
#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ | |
-/* 17 unused */ | |
+#define AZX_DCAPS_AMD_WORKAROUND (1 << 17) /* AMD-specific workaround */ | |
#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ | |
#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ | |
#define AZX_DCAPS_OLD_SSYNC (1 << 20) /* Old SSYNC reg for ICH */ | |
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 +2508,12 @@ 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, X570 & co */ | |
+ { PCI_DEVICE(0x1022, 0x1487), | |
+ .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 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment