From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Ramesh Babu Date: Tue, 17 Nov 2015 02:33:39 +0530 Subject: [PATCH] ASoC: HDA: EXT: Mark dma buffers as un-cacheble Driver shouldn't not assume HDA DMA has snooping enabled. Driver should always allocate non-cached memory. Change-Id: I5b21643d88d7692967c83f4696eb9e3eb7a90178 Signed-off-by: Ramesh Babu Signed-off-by: Hardik T Shah Reviewed-on: --- include/sound/hdaudio.h | 2 ++ sound/hda/ext/hdac_ext_bus.c | 37 +++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index cd1773d0e08f..0aa0189017ba 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -265,6 +265,8 @@ struct hdac_io_ops { struct snd_dma_buffer *buf); void (*dma_free_pages)(struct hdac_bus *bus, struct snd_dma_buffer *buf); + /* mark memory region as non-cache */ + void (*mark_pages_uc)(struct snd_dma_buffer *buf, bool enable); }; #define HDA_UNSOL_QUEUE_SIZE 64 diff --git a/sound/hda/ext/hdac_ext_bus.c b/sound/hda/ext/hdac_ext_bus.c index 08cc0ce3b924..394e8d838250 100644 --- a/sound/hda/ext/hdac_ext_bus.c +++ b/sound/hda/ext/hdac_ext_bus.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include #include MODULE_DESCRIPTION("HDA extended core"); @@ -55,14 +57,46 @@ static u8 hdac_ext_readb(u8 __iomem *addr) return readb(addr); } +static void hdac_ext_mark_pages_uc(struct snd_dma_buffer *dmab, bool enable) +{ + int pages; + + 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 (enable) + set_pages_array_uc(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 (enable) + set_memory_uc((unsigned long)dmab->area, pages); + else + set_memory_wb((unsigned long)dmab->area, pages); +} + static int hdac_ext_dma_alloc_pages(struct hdac_bus *bus, int type, size_t size, struct snd_dma_buffer *buf) { - return snd_dma_alloc_pages(type, bus->dev, size, buf); + int ret; + + ret = snd_dma_alloc_pages(type, bus->dev, size, buf); + if (ret < 0) + return ret; + hdac_ext_mark_pages_uc(buf, true); + return ret; } static void hdac_ext_dma_free_pages(struct hdac_bus *bus, struct snd_dma_buffer *buf) { + hdac_ext_mark_pages_uc(buf, false); snd_dma_free_pages(buf); } @@ -75,6 +109,7 @@ static const struct hdac_io_ops hdac_ext_default_io = { .reg_readb = hdac_ext_readb, .dma_alloc_pages = hdac_ext_dma_alloc_pages, .dma_free_pages = hdac_ext_dma_free_pages, + .mark_pages_uc = hdac_ext_mark_pages_uc, }; /** -- https://clearlinux.org