ALSA: hda: Use new non-cached allocation for non-snoop mode
authorTakashi Iwai <tiwai@suse.de>
Wed, 8 Aug 2018 20:23:30 +0000 (22:23 +0200)
committerTakashi Iwai <tiwai@suse.de>
Tue, 28 Aug 2018 11:56:47 +0000 (13:56 +0200)
Now the ALSA memory allocator helper supports the new non-cached
pages, let's use the new type, SNDRV_DMA_TYPE_DEV_UC_SG, for HD-audio
driver.  This allows us to reduce lots of codes.

As another positive side-effect by this patch, the long-standing issue
with non-snoop mode playing in the non-mmap mode is fixed.  The core
memalloc helper does the proper pgprot setup for non-cached pages for
vmap(), which was missing in the past.

Reported-and-tested-by: Hans Hu <HansHu@zhaoxin.com>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_intel.c

index a12e594d4e3b3a23d78cc0b75531b845c7b6e331..8bc46676c278b015a45639290454e430514da164 100644 (file)
@@ -732,6 +732,7 @@ int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
        int pcm_dev = cpcm->device;
        unsigned int size;
        int s, err;
+       int type = SNDRV_DMA_TYPE_DEV_SG;
 
        list_for_each_entry(apcm, &chip->pcm_list, list) {
                if (apcm->pcm->device == pcm_dev) {
@@ -770,7 +771,9 @@ int snd_hda_attach_pcm_stream(struct hda_bus *_bus, struct hda_codec *codec,
        size = CONFIG_SND_HDA_PREALLOC_SIZE * 1024;
        if (size > MAX_PREALLOC_SIZE)
                size = MAX_PREALLOC_SIZE;
-       snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG,
+       if (chip->uc_buffer)
+               type = SNDRV_DMA_TYPE_DEV_UC_SG;
+       snd_pcm_lib_preallocate_pages_for_all(pcm, type,
                                              chip->card->dev,
                                              size, MAX_PREALLOC_SIZE);
        return 0;
index 53c3cd28bc9952be2bc898df3e9faec7b3811171..c4b3de6c42b80f3e122d0120781652295ba0dce1 100644 (file)
@@ -76,7 +76,6 @@ struct azx_dev {
         *  when link position is not greater than FIFO size
         */
        unsigned int insufficient:1;
-       unsigned int wc_marked:1;
 };
 
 #define azx_stream(dev)                (&(dev)->core)
index e5482fd215688105862300921f1a97406a818384..03ddd1abb44db0f7ba02a31c26117c17cb7f76bc 100644 (file)
@@ -397,61 +397,6 @@ static char *driver_short_names[] = {
        [AZX_DRIVER_GENERIC] = "HD-Audio Generic",
 };
 
-#ifdef CONFIG_X86
-static void __mark_pages_wc(struct azx *chip, struct snd_dma_buffer *dmab, bool on)
-{
-       int pages;
-
-       if (azx_snoop(chip))
-               return;
-       if (!dmab || !dmab->area || !dmab->bytes)
-               return;
-
-#ifdef CONFIG_SND_DMA_SGBUF
-       if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) {
-               struct snd_sg_buf *sgbuf = dmab->private_data;
-               if (!chip->uc_buffer)
-                       return; /* deal with only CORB/RIRB buffers */
-               if (on)
-                       set_pages_array_wc(sgbuf->page_table, sgbuf->pages);
-               else
-                       set_pages_array_wb(sgbuf->page_table, sgbuf->pages);
-               return;
-       }
-#endif
-
-       pages = (dmab->bytes + PAGE_SIZE - 1) >> PAGE_SHIFT;
-       if (on)
-               set_memory_wc((unsigned long)dmab->area, pages);
-       else
-               set_memory_wb((unsigned long)dmab->area, pages);
-}
-
-static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
-                                bool on)
-{
-       __mark_pages_wc(chip, buf, on);
-}
-static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
-                                  struct snd_pcm_substream *substream, bool on)
-{
-       if (azx_dev->wc_marked != on) {
-               __mark_pages_wc(chip, snd_pcm_get_dma_buf(substream), on);
-               azx_dev->wc_marked = on;
-       }
-}
-#else
-/* NOP for other archs */
-static inline void mark_pages_wc(struct azx *chip, struct snd_dma_buffer *buf,
-                                bool on)
-{
-}
-static inline void mark_runtime_wc(struct azx *chip, struct azx_dev *azx_dev,
-                                  struct snd_pcm_substream *substream, bool on)
-{
-}
-#endif
-
 static int azx_acquire_irq(struct azx *chip, int do_disconnect);
 
 /*
@@ -2054,22 +1999,14 @@ static int dma_alloc_pages(struct hdac_bus *bus,
                           struct snd_dma_buffer *buf)
 {
        struct azx *chip = bus_to_azx(bus);
-       int err;
 
-       err = snd_dma_alloc_pages(type,
-                                 bus->dev,
-                                 size, buf);
-       if (err < 0)
-               return err;
-       mark_pages_wc(chip, buf, true);
-       return 0;
+       if (!azx_snoop(chip) && type == SNDRV_DMA_TYPE_DEV)
+               type = SNDRV_DMA_TYPE_DEV_UC;
+       return snd_dma_alloc_pages(type, bus->dev, size, buf);
 }
 
 static void dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf)
 {
-       struct azx *chip = bus_to_azx(bus);
-
-       mark_pages_wc(chip, buf, false);
        snd_dma_free_pages(buf);
 }
 
@@ -2077,22 +2014,12 @@ static int substream_alloc_pages(struct azx *chip,
                                 struct snd_pcm_substream *substream,
                                 size_t size)
 {
-       struct azx_dev *azx_dev = get_azx_dev(substream);
-       int ret;
-
-       mark_runtime_wc(chip, azx_dev, substream, false);
-       ret = snd_pcm_lib_malloc_pages(substream, size);
-       if (ret < 0)
-               return ret;
-       mark_runtime_wc(chip, azx_dev, substream, true);
-       return 0;
+       return snd_pcm_lib_malloc_pages(substream, size);
 }
 
 static int substream_free_pages(struct azx *chip,
                                struct snd_pcm_substream *substream)
 {
-       struct azx_dev *azx_dev = get_azx_dev(substream);
-       mark_runtime_wc(chip, azx_dev, substream, false);
        return snd_pcm_lib_free_pages(substream);
 }