Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F168022229
D25316.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D25316.diff
View Options
Index: sys/dev/dmaengine/dmaengine.h
===================================================================
--- /dev/null
+++ sys/dev/dmaengine/dmaengine.h
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (C) 2020 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of AMD corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Contact Information :
+ * Rajesh Kumar <rajesh1.kumar@amd.com>
+ *
+ */
+
+#ifndef _DMAENGINE_H_
+#define _DMAENGINE_H_
+
+#include "dmaengine_if.h"
+
+extern devclass_t dmaengine_hw_devclass;
+SYSCTL_DECL(_hw_dmaengine);
+
+int dmaengine_register_device(device_t);
+int dmaengine_unregister_device(device_t);
+int dmaengine_child_location_str(device_t, device_t, char *, size_t);
+int dmaengine_print_child(device_t, device_t);
+
+/*
+ * dmaengine_get_chan_idx() - get the index of an available dma channel from
+ * the dmaengine
+ * @chan_cnt: Total number of dma channels needed
+ *
+ * Test applications can obtain the index of the available dma channel from
+ * the dmaengine based on the total number of dma channels needed.
+ */
+int dmaengine_get_chan_idx(ssize_t chan_cnt);
+
+/*
+ * dmaengine_get_channel() - get the reference of the pointed dma channel from
+ * the dmaengine
+ * @chan_idx: Index of the channel to get reference
+ * @flags: Additional optional params
+ *
+ * Test applications can obtain the reference of the pointed dma channel from
+ * the dmaengine.
+ */
+bus_dmaengine_t dmaengine_get_channel(uint32_t chan_idx, int flags);
+
+/*
+ * dmaengine_put_channel() - free the reference of the pointed dma channel from
+ * the dmaengine
+ * @channel: Reference of the channel to be freed.
+ *
+ * Test applications can free the reference of the pointed dma channel from
+ * the dmaengine.
+ */
+void dmaengine_put_channel(bus_dmaengine_t dmaengine);
+
+/* dmaengine_copy() - copy from source to destination using the specified
+ * dmaengine.
+ * @dmaengine: DMA engine to use for copy
+ * @dst: Destination address
+ * @src: Source address
+ * @len: Length of the data to be copied
+ * @callback_fn: Callback funtion to notify copy completion
+ * @callback_arg: Argument to be passed to @callback_fn
+ * @flags: Additional optional params
+ */
+int dmaengine_copy(bus_dmaengine_t dmaengine, bus_addr_t dst, bus_addr_t src,
+ bus_size_t len, bus_dmaengine_callback_t callback_fn, void *callback_arg,
+ uint32_t flags);
+
+#endif /* _DMAENGINE_H_ */
Index: sys/dev/dmaengine/dmaengine.c
===================================================================
--- /dev/null
+++ sys/dev/dmaengine/dmaengine.c
@@ -0,0 +1,274 @@
+/*-
+ * Copyright (C) 2020 Advanced Micro Devices, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of AMD corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Contact Information :
+ * Rajesh Kumar <rajesh1.kumar@amd.com>
+ *
+ */
+
+/*
+ * This is a generic interface driver for any DMA ENGINE devices. This can
+ * be used by any test applications or drivers to request and release DMA
+ * channels, and to initiate the DMA operations without the knowledge of the
+ * underlying vendor specific DMA hardware.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rmlock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/sysctl.h>
+
+#include "dmaengine.h"
+
+devclass_t dmaengine_hw_devclass;
+
+struct dmaengine_child {
+
+ TAILQ_ENTRY(dmaengine_child) entry;
+
+ device_t dmadev;
+ device_t parent;
+ int function;
+ int chan_idx;
+ int refcnt;
+ bus_dmaengine_t dmaengine;
+ struct dmaengine_child *next;
+};
+
+struct mtx dma_channel_lock;
+
+/* List of registered DMA channels */
+TAILQ_HEAD(dma_channel, dmaengine_child) dma_channel;
+
+SYSCTL_NODE(_hw, OID_AUTO, dmaengine, CTLFLAG_RW, 0, "DMA engine sysctls");
+
+static unsigned dma_channel_idx = 0;
+SYSCTL_UINT(_hw_dmaengine, OID_AUTO, channels, CTLFLAG_RD, &dma_channel_idx, 0,
+ "Number of DMA channels registered");
+
+/*
+ * Register a DMA channel
+ *
+ */
+int
+dmaengine_register_device(device_t dmadev)
+{
+ struct dmaengine_child **cpp = device_get_softc(dmadev);
+ struct dmaengine_child *dc;
+
+ device_printf(dmadev, "Registering DMA Engine\n");
+
+ if (dma_channel.tqh_last == NULL) {
+ mtx_init(&dma_channel_lock, "DMA Channel list lock", 0, MTX_DEF);
+ TAILQ_INIT(&dma_channel);
+ }
+
+ mtx_lock(&dma_channel_lock);
+
+ dc = malloc(sizeof(*dc), M_DEVBUF, M_WAITOK | M_ZERO);
+ if (dc == NULL)
+ return (ENOMEM);
+
+ dc->function = 0;
+ dc->chan_idx = dma_channel_idx;
+ dc->refcnt = 0;
+ dc->parent = dmadev;
+ dc->dmadev = device_add_child(dmadev, NULL, -1);
+ if (dc->dmadev == NULL) {
+ free(dc, M_DEVBUF);
+ return (ENOMEM);
+ }
+ device_set_ivars(dc->dmadev, dc);
+ *cpp = dc;
+ dma_channel_idx++;
+
+ TAILQ_INSERT_TAIL(&dma_channel, dc, entry);
+
+ mtx_unlock(&dma_channel_lock);
+
+ bus_generic_attach(dmadev);
+ return (0);
+}
+
+/*
+ * UnRegister a DMA channel
+ *
+ */
+int
+dmaengine_unregister_device(device_t dmadev)
+{
+ struct dmaengine_child **cpp = device_get_softc(dmadev);
+ struct dmaengine_child *dc = *cpp;
+ int error = 0;
+
+ device_printf(dmadev, "Registering DMA Engine\n");
+
+ mtx_lock(&dma_channel_lock);
+
+ TAILQ_REMOVE(&dma_channel, dc, entry);
+
+ error = device_delete_child(dmadev, dc->dmadev);
+ if (error)
+ goto out;
+
+ free(dc, M_DEVBUF);
+ dma_channel_idx--;
+
+ mtx_unlock(&dma_channel_lock);
+out:
+
+ return (0);
+}
+
+int
+dmaengine_child_location_str(device_t dmadev, device_t child, char *buf,
+ size_t buflen)
+{
+ struct dmaengine_child *dc = device_get_ivars(child);
+
+ snprintf(buf, buflen, "function=%d", dc->function);
+ return (0);
+}
+
+int
+dmaengine_print_child(device_t dmadev, device_t child)
+{
+ struct dmaengine_child *dc = device_get_ivars(child);
+ int retval;
+
+ retval = bus_print_child_header(dmadev, child);
+ retval += printf(" at function %d", dc->function);
+ retval += bus_print_child_domain(dmadev, child);
+ retval += bus_print_child_footer(dmadev, child);
+
+ return (retval);
+}
+
+/*
+ * Get a reference to the child of a registered DMA channel
+ *
+ */
+static struct dmaengine_child *
+dmaengine_get_dc(int chan_idx, bus_dmaengine_t dmaengine, int tcnt)
+{
+ struct dmaengine_child *dc = NULL, *dc_tmp = NULL;
+
+ mtx_lock(&dma_channel_lock);
+
+ TAILQ_FOREACH_SAFE(dc, &dma_channel, entry, dc_tmp) {
+ if (chan_idx >= 0) {
+ if (dc->chan_idx == chan_idx)
+ break;
+ }
+
+ if (dmaengine != NULL) {
+ if (dc->dmaengine == dmaengine)
+ break;
+ }
+
+ if (tcnt > 0) {
+ if (dc->refcnt == 0) {
+ atomic_add_int(&dc->refcnt, 1);
+ break;
+ }
+ }
+ }
+
+ mtx_unlock(&dma_channel_lock);
+
+ return (dc);
+}
+
+/*
+ * Get the index of a DMA channel to be used
+ *
+ */
+int
+dmaengine_get_chan_idx(ssize_t tcnt)
+{
+ struct dmaengine_child *dc;
+
+ dc = dmaengine_get_dc(-1, NULL, tcnt);
+
+ return (dc->chan_idx);
+}
+
+/*
+ * Take a reference to the DMA channel of the specified index
+ *
+ */
+bus_dmaengine_t
+dmaengine_get_channel(uint32_t chan_idx, int flags)
+{
+ struct dmaengine_child *dc;
+
+ dc = dmaengine_get_dc(chan_idx, NULL, 0);
+ dc->dmaengine = DMAENGINE_GET_CHANNEL(dc->parent, chan_idx, flags);
+
+ return (dc->dmaengine);
+}
+
+/*
+ * Free the reference of the specified DMA channel
+ *
+ */
+void
+dmaengine_put_channel(bus_dmaengine_t dmaengine)
+{
+ struct dmaengine_child *dc;
+
+ dc = dmaengine_get_dc(-1, dmaengine, 0);
+ dc->dmaengine = NULL;
+ DMAENGINE_PUT_CHANNEL(dc->parent, dmaengine);
+}
+
+/*
+ * Initiate a DMA copy on the specified DMA channel with the specified
+ * parameters along with a callback function to notify the completion.
+ *
+ */
+int
+dmaengine_copy(bus_dmaengine_t dmaengine, bus_addr_t dst,
+ bus_addr_t src, bus_size_t len, bus_dmaengine_callback_t callback_fn,
+ void *callback_arg, uint32_t flags)
+{
+ struct dmaengine_child *dc;
+
+ dc = dmaengine_get_dc(-1, dmaengine, 0);
+ return DMAENGINE_COPY(dc->parent, dmaengine, dst, src, len, callback_fn,
+ callback_arg, flags);
+}
+
+MODULE_VERSION(dmaengine, 1);
Index: sys/dev/dmaengine/dmaengine_if.m
===================================================================
--- /dev/null
+++ sys/dev/dmaengine/dmaengine_if.m
@@ -0,0 +1,69 @@
+#-
+# Copyright (C) 2020 Advanced Micro Devices, Inc.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+# 3. Neither the name of AMD corporation nor the names of its
+# contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# Contact Information :
+# Rajesh Kumar <rajesh1.kumar@amd.com>
+#
+# $FreeBSD$
+#
+
+#include <sys/bus.h>
+#include <machine/bus.h>
+
+INTERFACE dmaengine;
+
+HEADER {
+ typedef void *bus_dmaengine_t;
+ typedef void (*bus_dmaengine_callback_t)(void *arg, int error);
+};
+
+METHOD int get_chan_idx {
+ device_t dmadev;
+ ssize_t chan_cnt;
+};
+
+METHOD bus_dmaengine_t get_channel {
+ device_t dmadev;
+ uint32_t chan_idx;
+ int flags;
+};
+
+METHOD void put_channel {
+ device_t dmadev;
+ bus_dmaengine_t dmaengine;
+};
+
+METHOD int copy {
+ device_t dmadev;
+ bus_dmaengine_t dmaengine;
+ bus_addr_t dst;
+ bus_addr_t src;
+ bus_size_t len;
+ bus_dmaengine_callback_t callback_fn;
+ void *callback_arg;
+ uint32_t flags;
+};
Index: sys/modules/dmaengine/Makefile
===================================================================
--- /dev/null
+++ sys/modules/dmaengine/Makefile
@@ -0,0 +1,5 @@
+# $FreeBSD$
+
+SUBDIR= dmaengine
+
+.include <bsd.subdir.mk>
Index: sys/modules/dmaengine/dmaengine/Makefile
===================================================================
--- /dev/null
+++ sys/modules/dmaengine/dmaengine/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+.PATH: ${SRCTOP}/sys/dev/dmaengine
+
+KMOD = dmaengine
+SRCS = dmaengine.c dmaengine_if.c
+SRCS += device_if.h bus_if.h dmaengine_if.h
+
+.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Aug 26, 11:31 PM (1 h, 24 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37335443
Default Alt Text
D25316.diff (13 KB)
Attached To
Mode
D25316: Generic interface driver for dmaengine devices
Attached
Detach File
Event Timeline
Log In to Comment