ALSA: hda: Workaround for SDnCTL register on loongson
authorYanteng Si <siyanteng@loongson.cn>
Wed, 7 Jun 2023 09:21:51 +0000 (17:21 +0800)
committerTakashi Iwai <tiwai@suse.de>
Wed, 7 Jun 2023 10:41:21 +0000 (12:41 +0200)
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>
Acked-by: Huacai Chen <chenhuacai@loongson.cn>
Link: https://lore.kernel.org/r/27aeddf5ebbe7c69631cec0e489c1b264be94990.1686128807.git.siyanteng@loongson.cn
Signed-off-by: Takashi Iwai <tiwai@suse.de>
include/sound/hdaudio.h
sound/hda/hdac_stream.c
sound/pci/hda/hda_intel.c

index a0bb40a..2ffdf58 100644 (file)
@@ -348,6 +348,7 @@ struct hdac_bus {
        bool polling_mode:1;
        bool needs_damn_long_delay:1;
        bool not_use_interrupts:1;      /* prohibiting the RIRB IRQ */
+       bool access_sdnctl_in_dword:1;  /* accessing the sdnctl register by dword */
 
        int poll_count;
 
index 1f56fd3..2633a4b 100644 (file)
@@ -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;
 }
index b7a7a92..fc4787c 100644 (file)
@@ -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_use_interrupts = 1;
+               bus->access_sdnctl_in_dword = 1;
        }
 
        err = pcim_iomap_regions(pci, 1 << 0, "ICH HD audio");