summaryrefslogtreecommitdiff
path: root/gxp-dma.h
diff options
context:
space:
mode:
authorJohn Scheible <johnscheible@google.com>2021-10-26 13:45:19 -0700
committerJohn Scheible <johnscheible@google.com>2021-10-28 16:14:12 -0700
commitde16475969ca7dfaecf7144ece32b929cf193861 (patch)
tree962335a74133193541bf8c398a7cdf445f79a610 /gxp-dma.h
parent497cbdab5ea4f505beac7bb6d686bb4c3c504e8c (diff)
downloadgs201-de16475969ca7dfaecf7144ece32b929cf193861.tar.gz
gxp: First import from development branch
Squash at commit 48fe5786f1779890538d14f709b26063698c3711 Signed-off-by: John Scheible <johnscheible@google.com> Change-Id: I208434dddde40c08b9fc4d5da072ba10541992a2
Diffstat (limited to 'gxp-dma.h')
-rw-r--r--gxp-dma.h264
1 files changed, 264 insertions, 0 deletions
diff --git a/gxp-dma.h b/gxp-dma.h
new file mode 100644
index 0000000..37692af
--- /dev/null
+++ b/gxp-dma.h
@@ -0,0 +1,264 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * GXP DMA interface.
+ *
+ * Copyright (C) 2021 Google LLC
+ */
+#ifndef __GXP_DMA_H__
+#define __GXP_DMA_H__
+
+#include <linux/dma-direction.h>
+#include <linux/dma-mapping.h>
+#include <linux/types.h>
+
+#include "gxp-internal.h"
+
+struct gxp_dma_manager {
+ struct rb_root mapping_tree;
+};
+
+/*
+ * Error value to be returned in place of a dma_addr_t when a mapping fails.
+ *
+ * On newer kernels, this is defined in <linux/dma-mapping.h>. Redefined here
+ * for older kernels, so clients can check for this value without worrying
+ * which kernel version they're compiled for.
+ */
+#ifndef DMA_MAPPING_ERROR
+#define DMA_MAPPING_ERROR (~(dma_addr_t)0)
+#endif
+
+/**
+ * gxp_dma_init() - Initialize the GXP DMA subsystem
+ * @gxp: The GXP device to initialize DMA for
+ *
+ * Return:
+ * * 0 - DMA initialized successfully
+ * * -EIO - Failed to initialize underlying IOMMU hardware
+ * * -ENODEV - The necessary hardware or device tree entries are missing
+ * * -ENOMEM - Insufficient memory is available to initialize the interface
+ */
+int gxp_dma_init(struct gxp_dev *gxp);
+
+/**
+ * gxp_dma_exit() - Tear down the GXP DMA subsystem and release hardware
+ * @gxp: The GXP device to tear down DMA for
+ */
+void gxp_dma_exit(struct gxp_dev *gxp);
+
+/**
+ * gxp_dma_map_resources() - Map the various buffers/registers with fixed IOVAs
+ * @gxp: The GXP device to setup the mappings for
+ *
+ * GXP firmware expects several buffers and registers to be mapped to fixed
+ * locations in their IOVA space. This function initializes all those mappings.
+ *
+ * This function must not be called until after all the `vaddr` and `size`
+ * fields of every `struct gxp_mapped_resource` inside of @gxp have been
+ * initialized.
+ *
+ * Return:
+ * * 0 - Mappings created successfully
+ * * -EIO - Failed to create one or more of the mappings
+ */
+int gxp_dma_map_resources(struct gxp_dev *gxp);
+
+/**
+ * gxp_dma_unmap_resources() - Unmap the IOVAs mapped by gxp_dma_map_resources
+ * @gxp: The GXP device that was passed to gxp_dma_map_resources()
+ *
+ * GXP firmware expects several buffers and registers to be mapped to fixed
+ * locations in their IOVA space. This function releases all those mappings.
+ *
+ * This function should be called after gxp_dma_map_resources().
+ */
+void gxp_dma_unmap_resources(struct gxp_dev *gxp);
+
+/**
+ * gxp_dma_alloc_coherent() - Allocate and map a coherent buffer for a GXP core
+ * @gxp: The GXP device to map the allocated buffer for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @size: The size of the buffer to be allocated, in bytes
+ * @dma_handle: Reference to a variable to be set to the allocated IOVA
+ * @flag: The type of memory to allocate (see kmalloc)
+ * @gxp_dma_flags: The type of mapping to create; Currently unused
+ *
+ * Return: Kernel virtual address of the allocated/mapped buffer
+ */
+void *gxp_dma_alloc_coherent(struct gxp_dev *gxp, uint core_list, size_t size,
+ dma_addr_t *dma_handle, gfp_t flag,
+ uint gxp_dma_flags);
+/**
+ * gxp_dma_free_coherent() - Unmap and free a coherent buffer
+ * @gxp: The GXP device the buffer was allocated and mapped for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @size: The size of the buffer, in bytes, passed to `gxp_dma_alloc()`
+ * @cpu_addr: The kernel virtual address returned by `gxp_dma_alloc()`
+ * @dma_handle: The device IOVA, set by `gxp_dma_alloc()`
+ *
+ * If the buffer has been mirror-mapped via `gxp_dma_mirror_map()`, the buffer
+ * will not be freed until all mappings have been unmapped.
+ */
+void gxp_dma_free_coherent(struct gxp_dev *gxp, uint core_list, size_t size,
+ void *cpu_addr, dma_addr_t dma_handle);
+
+/**
+ * gxp_dma_map_single() - Create a mapping for a kernel buffer
+ * @gxp: The GXP device to map the buffer for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @cpu_addr: The kernel virtual address of the buffer to map
+ * @size: The size of the buffer to map, in bytes
+ * @direction: DMA direction
+ * @attrs: The same set of flags used by the base DMA API
+ * @gxp_dma_flags: The type of mapping to create; Currently unused
+ *
+ * Return: The IOVA the buffer was mapped to
+ */
+dma_addr_t gxp_dma_map_single(struct gxp_dev *gxp, uint core_list,
+ void *cpu_addr, size_t size,
+ enum dma_data_direction direction,
+ unsigned long attrs, uint gxp_dma_flags);
+/**
+ * gxp_dma_unmap_single() - Unmap a kernel buffer
+ * @gxp: The GXP device the buffer was mapped for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @dma_addr: The device IOVA, returned by `gxp_dma_map_single()`
+ * @size: The size of the mapping, which was passed to `gxp_dma_map_single()`
+ * @direction: DMA direction; same as passed to `gxp_dma_map_single()`
+ * @attrs: The same set of flags used by the base DMA API
+ */
+void gxp_dma_unmap_single(struct gxp_dev *gxp, uint core_list,
+ dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction,
+ unsigned long attrs);
+
+/**
+ * gxp_dma_map_page() - Create a mapping for a physical page of memory
+ * @gxp: The GXP device to map the page for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @page: The `struct page` of the physical page to create a mapping for
+ * @offset: The offset into @page to begin the mapping at
+ * @size: The number of bytes in @page to map
+ * @direction: DMA direction
+ * @attrs: The same set of flags used by the base DMA API
+ * @gxp_dma_flags: The type of mapping to create; Currently unused
+ *
+ * Return: The IOVA the page was mapped to
+ */
+dma_addr_t gxp_dma_map_page(struct gxp_dev *gxp, uint core_list,
+ struct page *page, unsigned long offset,
+ size_t size, enum dma_data_direction direction,
+ unsigned long attrs, uint gxp_dma_flags);
+/**
+ * gxp_dma_unmap_page() - Unmap a physical page of memory
+ * @gxp: The GXP device the page was mapped for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @dma_addr: The device IOVA, returned by `gxp_dma_map_page()`
+ * @size: The size of the mapping, which was passed to `gxp_dma_map_page()`
+ * @direction: DMA direction; Same as passed to `gxp_dma_map_page()`
+ * @attrs: The same set of flags used by the base DMA API
+ */
+void gxp_dma_unmap_page(struct gxp_dev *gxp, uint core_list,
+ dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction, unsigned long attrs);
+
+/**
+ * gxp_dma_map_resource() - Create a mapping for an MMIO resource
+ * @gxp: The GXP device to map the resource for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @phys_addr: The physical address of the MMIO resource to map
+ * @size: The size of the MMIO region to map, in bytes
+ * @direction: DMA direction
+ * @attrs: The same set of flags used by the base DMA API
+ * @gxp_dma_flags: The type of mapping to create; Currently unused
+ *
+ * Return: The IOVA the MMIO resource was mapped to
+ */
+dma_addr_t gxp_dma_map_resource(struct gxp_dev *gxp, uint core_list,
+ phys_addr_t phys_addr, size_t size,
+ enum dma_data_direction direction,
+ unsigned long attrs, uint gxp_dma_flags);
+/**
+ * gxp_dma_unmap_resource() - Unmap an MMIO resource
+ * @gxp: The GXP device the MMIO resource was mapped for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @dma_addr: The device IOVA, returned by `gxp_dma_map_resource()`
+ * @size: The size of the mapping, which was passed to `gxp_dma_map_resource()`
+ * @direction: DMA direction; Same as passed to `gxp_dma_map_resource()`
+ * @attrs: The same set of flags used by the base DMA API
+ */
+void gxp_dma_unmap_resource(struct gxp_dev *gxp, uint core_list,
+ dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction,
+ unsigned long attrs);
+
+/**
+ * gxp_dma_map_sg() - Create a mapping for a scatter-gather list
+ * @gxp: The GXP device to map the scatter-gather list for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @sg: The scatter-gather list of the buffer to be mapped
+ * @nents: The number of entries in @sg
+ * @direction: DMA direction
+ * @attrs: The same set of flags used by the base DMA API
+ * @gxp_dma_flags: The type of mapping to create; Currently unused
+ *
+ * Return: The number of scatter-gather entries mapped to
+ */
+int gxp_dma_map_sg(struct gxp_dev *gxp, uint core_list, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction,
+ unsigned long attrs, uint gxp_dma_flags);
+/**
+ * gxp_dma_unmap_sg() - Unmap a scatter-gather list
+ * @gxp: The GXP device the scatter-gather list was mapped for
+ * @core_list: A bitfield enumerating the physical cores the mapping is for
+ * @sg: The scatter-gather list to unmap; The same one passed to
+ * `gxp_dma_map_sg()`
+ * @nents: The number of entries in @sg; Same value passed to `gxp_dma_map_sg()`
+ * @direction: DMA direction; Same as passed to `gxp_dma_map_sg()`
+ * @attrs: The same set of flags used by the base DMA API
+ */
+void gxp_dma_unmap_sg(struct gxp_dev *gxp, uint core_list,
+ struct scatterlist *sg, int nents,
+ enum dma_data_direction direction, unsigned long attrs);
+
+/**
+ * gxp_dma_sync_single_for_cpu() - Sync buffer for reading by the CPU
+ * @gxp: The GXP device the mapping was created for
+ * @dma_handle: The device IOVA, obtained from one of the `gxp_dma_map_*` APIs
+ * @size: The size of the mapped region to sync
+ * @direction: DMA direction
+ */
+void gxp_dma_sync_single_for_cpu(struct gxp_dev *gxp, dma_addr_t dma_handle,
+ size_t size,
+ enum dma_data_direction direction);
+/**
+ * gxp_dma_sync_single_for_device() - Sync buffer for reading by the device
+ * @gxp: The GXP device the mapping was created for
+ * @dma_handle: The device IOVA, obtained from one of the `gxp_dma_map_*` APIs
+ * @size: The size of the mapped region to sync
+ * @direction: DMA direction
+ */
+void gxp_dma_sync_single_for_device(struct gxp_dev *gxp, dma_addr_t dma_handle,
+ size_t size,
+ enum dma_data_direction direction);
+
+/**
+ * gxp_dma_sync_sg_for_cpu() - Sync sg list for reading by the CPU
+ * @gxp: The GXP device the mapping was created for
+ * @sg: The mapped scatter-gather list to be synced
+ * @nents: The number of entries in @sg
+ * @direction: DMA direction
+ */
+void gxp_dma_sync_sg_for_cpu(struct gxp_dev *gxp, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction);
+/**
+ * gxp_dma_sync_sg_for_device() - Sync sg list for reading by the device
+ * @gxp: The GXP device the mapping was created for
+ * @sg: The mapped scatter-gather list to be synced
+ * @nents: The number of entries in @sg
+ * @direction: DMA direction
+ */
+void gxp_dma_sync_sg_for_device(struct gxp_dev *gxp, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction);
+
+#endif /* __GXP_DMA_H__ */