diff mbox series

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

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

Commit Message

Yanteng Si June 6, 2023, 1:25 p.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>
Signed-off-by: Yingkun Meng <mengyingkun@loongson.cn>
---
 include/sound/hdaudio.h   | 1 +
 sound/hda/hdac_stream.c   | 6 +++++-
 sound/pci/hda/hda_intel.c | 1 +
 3 files changed, 7 insertions(+), 1 deletion(-)

Comments

Takashi Iwai June 6, 2023, 1:39 p.m. UTC | #1
On Tue, 06 Jun 2023 15:25:29 +0200,
Yanteng Si wrote:
> 
> 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>
> Signed-off-by: Yingkun Meng <mengyingkun@loongson.cn>
> ---
>  include/sound/hdaudio.h   | 1 +
>  sound/hda/hdac_stream.c   | 6 +++++-
>  sound/pci/hda/hda_intel.c | 1 +
>  3 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
> index a1dcc7f97d08..859becb0eaba 100644
> --- a/include/sound/hdaudio.h
> +++ b/include/sound/hdaudio.h
> @@ -348,6 +348,7 @@ struct hdac_bus {
>  	bool polling_mode:1;
>  	bool no_intr_polling_mode:1;
>  	bool needs_damn_long_delay:1;
> +	bool access_sdnctl_in_dword:1;

It's worth for the comment here, too.


thanks,

Takashi
diff mbox series

Patch

diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h
index a1dcc7f97d08..859becb0eaba 100644
--- a/include/sound/hdaudio.h
+++ b/include/sound/hdaudio.h
@@ -348,6 +348,7 @@  struct hdac_bus {
 	bool polling_mode:1;
 	bool no_intr_polling_mode:1;
 	bool needs_damn_long_delay:1;
+	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 1e8993836fc6..0222a1721b4d 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1877,6 +1877,7 @@  static int azx_first_init(struct azx *chip)
 
 	if (chip->driver_type == AZX_DRIVER_LOONGSON) {
 		bus->no_intr_polling_mode = 1;
+		bus->access_sdnctl_in_dword = 1;
 	}
 
 	err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");