104 lines
3.0 KiB
Diff
104 lines
3.0 KiB
Diff
From 96ce360b20d5280f211e7e7e1aa453affcdb5ee5 Mon Sep 17 00:00:00 2001
|
|
From: Ramesh Babu <ramesh.babu@intel.com>
|
|
Date: Tue, 17 Nov 2015 02:33:39 +0530
|
|
Subject: [PATCH 054/550] 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 <ramesh.babu@intel.com>
|
|
Signed-off-by: Hardik T Shah <hardik.t.shah@intel.com>
|
|
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 9c37d9af3023..3e63fcfd6cd8 100644
|
|
--- a/sound/hda/ext/hdac_ext_bus.c
|
|
+++ b/sound/hda/ext/hdac_ext_bus.c
|
|
@@ -20,6 +20,8 @@
|
|
#include <linux/module.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/io.h>
|
|
+#include <asm/pgtable.h>
|
|
+#include <asm/set_memory.h>
|
|
#include <sound/hdaudio_ext.h>
|
|
|
|
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,
|
|
};
|
|
|
|
/**
|
|
--
|
|
2.19.1
|
|
|