From ee8443050b2bf06d80fdd2c78cc25cae2abdedcd Mon Sep 17 00:00:00 2001
From: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Date: Thu, 10 Feb 2022 17:05:20 +0200
Subject: [PATCH] ASoC: SOF: Split up utils.c into sof-utils and iomem-utils
Git-commit: ee8443050b2bf06d80fdd2c78cc25cae2abdedcd
Patch-mainline: v5.18-rc1
References: jsc#PED-850
The utils.c contains wrappers and implementation for accessing iomem mapped
regions and a single unrelated function to create a compressed page table
from snd_dma_buffer for firmware use.
The latter is used by the PCM and the dma trace code and it needs to be
moved to a generic source/header for the client conversion to be possible.
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
Reviewed-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Link: https://lore.kernel.org/r/20220210150525.30756-5-peter.ujfalusi@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de>
---
sound/soc/sof/Makefile | 5 +-
sound/soc/sof/compress.c | 1 +
sound/soc/sof/iomem-utils.c | 127 ++++++++++++++++++++++++
sound/soc/sof/pcm.c | 1 +
sound/soc/sof/sof-priv.h | 4 -
sound/soc/sof/sof-utils.c | 77 +++++++++++++++
sound/soc/sof/sof-utils.h | 19 ++++
sound/soc/sof/trace.c | 1 +
sound/soc/sof/utils.c | 186 ------------------------------------
9 files changed, 230 insertions(+), 191 deletions(-)
create mode 100644 sound/soc/sof/iomem-utils.c
create mode 100644 sound/soc/sof/sof-utils.c
create mode 100644 sound/soc/sof/sof-utils.h
delete mode 100644 sound/soc/sof/utils.c
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile
index 964b429146be..4b9fccacc2b7 100644
--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
- control.o trace.o utils.o sof-audio.o stream-ipc.o
+ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o
snd-sof-$(CONFIG_SND_SOC_SOF_DEBUG_PROBES) += sof-probes.o
snd-sof-$(CONFIG_SND_SOC_SOF_COMPRESS) += compress.o
@@ -12,9 +12,12 @@ snd-sof-of-objs := sof-of-dev.o
snd-sof-nocodec-objs := nocodec.o
+snd-sof-utils-objs := sof-utils.o
+
obj-$(CONFIG_SND_SOC_SOF) += snd-sof.o
obj-$(CONFIG_SND_SOC_SOF_NOCODEC) += snd-sof-nocodec.o
+obj-$(CONFIG_SND_SOC_SOF) += snd-sof-utils.o
obj-$(CONFIG_SND_SOC_SOF_ACPI_DEV) += snd-sof-acpi.o
obj-$(CONFIG_SND_SOC_SOF_OF_DEV) += snd-sof-of.o
diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c
index 91a9c95929cd..2137d1d65dd9 100644
--- a/sound/soc/sof/compress.c
+++ b/sound/soc/sof/compress.c
@@ -9,6 +9,7 @@
#include <sound/compress_driver.h>
#include "sof-audio.h"
#include "sof-priv.h"
+#include "sof-utils.h"
static void sof_set_transferred_bytes(struct snd_compr_tstamp *tstamp,
u64 host_pos, u64 buffer_size)
diff --git a/sound/soc/sof/iomem-utils.c b/sound/soc/sof/iomem-utils.c
new file mode 100644
index 000000000000..3f57f6cf6542
--- /dev/null
+++ b/sound/soc/sof/iomem-utils.c
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
+//
+// Author: Keyon Jie <yang.jie@linux.intel.com>
+//
+
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/platform_device.h>
+#include <asm/unaligned.h>
+#include <sound/soc.h>
+#include <sound/sof.h>
+#include "sof-priv.h"
+#include "ops.h"
+
+/*
+ * Register IO
+ *
+ * The sof_io_xyz() wrappers are typically referenced in snd_sof_dsp_ops
+ * structures and cannot be inlined.
+ */
+
+void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value)
+{
+ writel(value, addr);
+}
+EXPORT_SYMBOL(sof_io_write);
+
+u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr)
+{
+ return readl(addr);
+}
+EXPORT_SYMBOL(sof_io_read);
+
+void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value)
+{
+ writeq(value, addr);
+}
+EXPORT_SYMBOL(sof_io_write64);
+
+u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr)
+{
+ return readq(addr);
+}
+EXPORT_SYMBOL(sof_io_read64);
+
+/*
+ * IPC Mailbox IO
+ */
+
+void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset,
+ void *message, size_t bytes)
+{
+ void __iomem *dest = sdev->bar[sdev->mailbox_bar] + offset;
+
+ memcpy_toio(dest, message, bytes);
+}
+EXPORT_SYMBOL(sof_mailbox_write);
+
+void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset,
+ void *message, size_t bytes)
+{
+ void __iomem *src = sdev->bar[sdev->mailbox_bar] + offset;
+
+ memcpy_fromio(message, src, bytes);
+}
+EXPORT_SYMBOL(sof_mailbox_read);
+
+/*
+ * Memory copy.
+ */
+
+int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
+ u32 offset, void *src, size_t size)
+{
+ int bar = snd_sof_dsp_get_bar_index(sdev, blk_type);
+ const u8 *src_byte = src;
+ void __iomem *dest;
+ u32 affected_mask;
+ u32 tmp;
+ int m, n;
+
+ if (bar < 0)
+ return bar;
+
+ dest = sdev->bar[bar] + offset;
+
+ m = size / 4;
+ n = size % 4;
+
+ /* __iowrite32_copy use 32bit size values so divide by 4 */
+ __iowrite32_copy(dest, src, m);
+
+ if (n) {
+ affected_mask = (1 << (8 * n)) - 1;
+
+ /* first read the 32bit data of dest, then change affected
+ * bytes, and write back to dest. For unaffected bytes, it
+ * should not be changed
+ */
+ tmp = ioread32(dest + m * 4);
+ tmp &= ~affected_mask;
+
+ tmp |= *(u32 *)(src_byte + m * 4) & affected_mask;
+ iowrite32(tmp, dest + m * 4);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(sof_block_write);
+
+int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
+ u32 offset, void *dest, size_t size)
+{
+ int bar = snd_sof_dsp_get_bar_index(sdev, blk_type);
+
+ if (bar < 0)
+ return bar;
+
+ memcpy_fromio(dest, sdev->bar[bar] + offset, size);
+
+ return 0;
+}
+EXPORT_SYMBOL(sof_block_read);
diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c
index 37fb8e6cd493..62cb61655761 100644
--- a/sound/soc/sof/pcm.c
+++ b/sound/soc/sof/pcm.c
@@ -19,6 +19,7 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
#include "sof-probes.h"
#endif
+#include "sof-utils.h"
/* Create DMA buffer page table for DSP */
static int create_page_table(struct snd_soc_component *component,
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 2e474048d708..27d2f3ca2f06 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -502,10 +502,6 @@ void snd_sof_complete(struct device *dev);
void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);
-int snd_sof_create_page_table(struct device *dev,
- struct snd_dma_buffer *dmab,
- unsigned char *page_table, size_t size);
-
/*
* Firmware loading.
*/
diff --git a/sound/soc/sof/sof-utils.c b/sound/soc/sof/sof-utils.c
new file mode 100644
index 000000000000..a3300ecee062
--- /dev/null
+++ b/sound/soc/sof/sof-utils.c
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2018-2022 Intel Corporation. All rights reserved.
+//
+// Author: Keyon Jie <yang.jie@linux.intel.com>
+//
+
+#include <asm/unaligned.h>
+#include <linux/io-64-nonatomic-lo-hi.h>
+#include <linux/device.h>
+#include <sound/memalloc.h>
+#include <linux/module.h>
+#include "sof-utils.h"
+
+/*
+ * Generic buffer page table creation.
+ * Take the each physical page address and drop the least significant unused
+ * bits from each (based on PAGE_SIZE). Then pack valid page address bits
+ * into compressed page table.
+ */
+
+int snd_sof_create_page_table(struct device *dev,
+ struct snd_dma_buffer *dmab,
+ unsigned char *page_table, size_t size)
+{
+ int i, pages;
+
+ pages = snd_sgbuf_aligned_pages(size);
+
+ dev_dbg(dev, "generating page table for %p size 0x%zx pages %d\n",
+ dmab->area, size, pages);
+
+ for (i = 0; i < pages; i++) {
+ /*
+ * The number of valid address bits for each page is 20.
+ * idx determines the byte position within page_table
+ * where the current page's address is stored
+ * in the compressed page_table.
+ * This can be calculated by multiplying the page number by 2.5.
+ */
+ u32 idx = (5 * i) >> 1;
+ u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT;
+ u8 *pg_table;
+
+ dev_vdbg(dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
+
+ pg_table = (u8 *)(page_table + idx);
+
+ /*
+ * pagetable compression:
+ * byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
+ * ___________pfn 0__________ __________pfn 1___________ _pfn 2...
+ * .... .... .... .... .... .... .... .... .... .... ....
+ * It is created by:
+ * 1. set current location to 0, PFN index i to 0
+ * 2. put pfn[i] at current location in Little Endian byte order
+ * 3. calculate an intermediate value as
+ * x = (pfn[i+1] << 4) | (pfn[i] & 0xf)
+ * 4. put x at offset (current location + 2) in LE byte order
+ * 5. increment current location by 5 bytes, increment i by 2
+ * 6. continue to (2)
+ */
+ if (i & 1)
+ put_unaligned_le32((pg_table[0] & 0xf) | pfn << 4,
+ pg_table);
+ else
+ put_unaligned_le32(pfn, pg_table);
+ }
+
+ return pages;
+}
+EXPORT_SYMBOL(snd_sof_create_page_table);
+
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/sof-utils.h b/sound/soc/sof/sof-utils.h
new file mode 100644
index 000000000000..6f902893807e
--- /dev/null
+++ b/sound/soc/sof/sof-utils.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+/*
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Copyright(c) 2022 Intel Corporation. All rights reserved.
+ */
+
+#ifndef __SOC_SOF_UTILS_H
+#define __SOC_SOF_UTILS_H
+
+struct snd_dma_buffer;
+struct device;
+
+int snd_sof_create_page_table(struct device *dev,
+ struct snd_dma_buffer *dmab,
+ unsigned char *page_table, size_t size);
+
+#endif
diff --git a/sound/soc/sof/trace.c b/sound/soc/sof/trace.c
index 2335d0f06d42..104388c551cb 100644
--- a/sound/soc/sof/trace.c
+++ b/sound/soc/sof/trace.c
@@ -12,6 +12,7 @@
#include <linux/sched/signal.h>
#include "sof-priv.h"
#include "ops.h"
+#include "sof-utils.h"
#define TRACE_FILTER_ELEMENTS_PER_ENTRY 4
#define TRACE_FILTER_MAX_CONFIG_STRING_LENGTH 1024
diff --git a/sound/soc/sof/utils.c b/sound/soc/sof/utils.c
deleted file mode 100644
index 66fa6602fb67..000000000000
--- a/sound/soc/sof/utils.c
+++ /dev/null
@@ -1,186 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
-//
-// This file is provided under a dual BSD/GPLv2 license. When using or
-// redistributing this file, you may do so under either license.
-//
-// Copyright(c) 2018 Intel Corporation. All rights reserved.
-//
-// Author: Keyon Jie <yang.jie@linux.intel.com>
-//
-
-#include <linux/io-64-nonatomic-lo-hi.h>
-#include <linux/platform_device.h>
-#include <asm/unaligned.h>
-#include <sound/soc.h>
-#include <sound/sof.h>
-#include "sof-priv.h"
-#include "ops.h"
-
-/*
- * Register IO
- *
- * The sof_io_xyz() wrappers are typically referenced in snd_sof_dsp_ops
- * structures and cannot be inlined.
- */
-
-void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value)
-{
- writel(value, addr);
-}
-EXPORT_SYMBOL(sof_io_write);
-
-u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr)
-{
- return readl(addr);
-}
-EXPORT_SYMBOL(sof_io_read);
-
-void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value)
-{
- writeq(value, addr);
-}
-EXPORT_SYMBOL(sof_io_write64);
-
-u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr)
-{
- return readq(addr);
-}
-EXPORT_SYMBOL(sof_io_read64);
-
-/*
- * IPC Mailbox IO
- */
-
-void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset,
- void *message, size_t bytes)
-{
- void __iomem *dest = sdev->bar[sdev->mailbox_bar] + offset;
-
- memcpy_toio(dest, message, bytes);
-}
-EXPORT_SYMBOL(sof_mailbox_write);
-
-void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset,
- void *message, size_t bytes)
-{
- void __iomem *src = sdev->bar[sdev->mailbox_bar] + offset;
-
- memcpy_fromio(message, src, bytes);
-}
-EXPORT_SYMBOL(sof_mailbox_read);
-
-/*
- * Memory copy.
- */
-
-int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
- u32 offset, void *src, size_t size)
-{
- int bar = snd_sof_dsp_get_bar_index(sdev, blk_type);
- const u8 *src_byte = src;
- void __iomem *dest;
- u32 affected_mask;
- u32 tmp;
- int m, n;
-
- if (bar < 0)
- return bar;
-
- dest = sdev->bar[bar] + offset;
-
- m = size / 4;
- n = size % 4;
-
- /* __iowrite32_copy use 32bit size values so divide by 4 */
- __iowrite32_copy(dest, src, m);
-
- if (n) {
- affected_mask = (1 << (8 * n)) - 1;
-
- /* first read the 32bit data of dest, then change affected
- * bytes, and write back to dest. For unaffected bytes, it
- * should not be changed
- */
- tmp = ioread32(dest + m * 4);
- tmp &= ~affected_mask;
-
- tmp |= *(u32 *)(src_byte + m * 4) & affected_mask;
- iowrite32(tmp, dest + m * 4);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(sof_block_write);
-
-int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
- u32 offset, void *dest, size_t size)
-{
- int bar = snd_sof_dsp_get_bar_index(sdev, blk_type);
-
- if (bar < 0)
- return bar;
-
- memcpy_fromio(dest, sdev->bar[bar] + offset, size);
-
- return 0;
-}
-EXPORT_SYMBOL(sof_block_read);
-
-/*
- * Generic buffer page table creation.
- * Take the each physical page address and drop the least significant unused
- * bits from each (based on PAGE_SIZE). Then pack valid page address bits
- * into compressed page table.
- */
-
-int snd_sof_create_page_table(struct device *dev,
- struct snd_dma_buffer *dmab,
- unsigned char *page_table, size_t size)
-{
- int i, pages;
-
- pages = snd_sgbuf_aligned_pages(size);
-
- dev_dbg(dev, "generating page table for %p size 0x%zx pages %d\n",
- dmab->area, size, pages);
-
- for (i = 0; i < pages; i++) {
- /*
- * The number of valid address bits for each page is 20.
- * idx determines the byte position within page_table
- * where the current page's address is stored
- * in the compressed page_table.
- * This can be calculated by multiplying the page number by 2.5.
- */
- u32 idx = (5 * i) >> 1;
- u32 pfn = snd_sgbuf_get_addr(dmab, i * PAGE_SIZE) >> PAGE_SHIFT;
- u8 *pg_table;
-
- dev_vdbg(dev, "pfn i %i idx %d pfn %x\n", i, idx, pfn);
-
- pg_table = (u8 *)(page_table + idx);
-
- /*
- * pagetable compression:
- * byte 0 byte 1 byte 2 byte 3 byte 4 byte 5
- * ___________pfn 0__________ __________pfn 1___________ _pfn 2...
- * .... .... .... .... .... .... .... .... .... .... ....
- * It is created by:
- * 1. set current location to 0, PFN index i to 0
- * 2. put pfn[i] at current location in Little Endian byte order
- * 3. calculate an intermediate value as
- * x = (pfn[i+1] << 4) | (pfn[i] & 0xf)
- * 4. put x at offset (current location + 2) in LE byte order
- * 5. increment current location by 5 bytes, increment i by 2
- * 6. continue to (2)
- */
- if (i & 1)
- put_unaligned_le32((pg_table[0] & 0xf) | pfn << 4,
- pg_table);
- else
- put_unaligned_le32(pfn, pg_table);
- }
-
- return pages;
-}
-EXPORT_SYMBOL(snd_sof_create_page_table);
--
2.35.3