diff mbox series

[v3,3/4] ALSA: hda: Workaround for SDnCTL register on loongson

Message ID c33ab5d06000749d8578fd57b5cbf3b29819a587.1686125797.git.siyanteng@loongson.cn
State Superseded
Headers show
Series Add Loongson HD Audio support | expand

Commit Message

Yanteng Si June 7, 2023, 8:51 a.m. UTC
On loongson controller, after calling snd_hdac_stream_updateb()
to enable DMA engine, the SDnCTL.STRM will become to zero.  We
need to access SDnCTL in dword to keep SDnCTL.STRM is not changed.

Signed-off-by: Yanteng Si <siyanteng@loongson.cn>
Yingkun Meng <mengyingkun@loongson.cn>
---
 include/sound/hdaudio.h   | 2 ++
 sound/hda/hdac_stream.c   | 6 +++++-
 sound/pci/hda/hda_intel.c | 1 +
 3 files changed, 8 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index 8d34d932956d..0484b149060d 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -348,6 +348,8 @@  struct hdac_bus {
 	bool polling_mode:1;
 	bool needs_damn_long_delay:1;
 	bool not_using_interrupts:1;	/* prohibiting the RIRB IRQ */
+	/* Accessing the sdnctl register by dword */
+	bool access_sdnctl_in_dword:1;
 
 	int poll_count;
 
diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c
index 1f56fd33b9af..2633a4bb1d85 100644
--- a/sound/hda/hdac_stream.c
+++ b/sound/hda/hdac_stream.c
@@ -150,7 +150,11 @@  void snd_hdac_stream_start(struct hdac_stream *azx_dev)
 					stripe_ctl);
 	}
 	/* set DMA start and interrupt mask */
-	snd_hdac_stream_updateb(azx_dev, SD_CTL,
+	if (bus->access_sdnctl_in_dword)
+		snd_hdac_stream_updatel(azx_dev, SD_CTL,
+				0, SD_CTL_DMA_START | SD_INT_MASK);
+	else
+		snd_hdac_stream_updateb(azx_dev, SD_CTL,
 				0, SD_CTL_DMA_START | SD_INT_MASK);
 	azx_dev->running = true;
 }
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 2173a94a3315..a1e3883b00a4 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1878,6 +1878,7 @@  static int azx_first_init(struct azx *chip)
 	if (chip->driver_type == AZX_DRIVER_LOONGSON) {
 		bus->polling_mode = 1;
 		bus->not_using_interrupts = 1;
+		bus->access_sdnctl_in_dword = 1;
 	}
 
 	err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");