-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce drm_pagemap ops to map and unmap dma to VRAM resources. In the local memory case it's a matter of merely providing an offset into the device's physical address. For future p2p the map and unmap functions may encode as needed. Similar to how dma-buf works, let the memory provider (drm_pagemap) provide the mapping functionality. v3: - Move to drm level include v4: - Fix kernel doc (G.G.) v5: - s/map_dma/device_map (Thomas) - s/unmap_dma/device_unmap (Thomas) v7: - Fix kernel doc (CI, Auld) - Drop P2P define (Thomas) Signed-off-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250306012657.3505757-5-matthew.brost@intel.com
- Loading branch information
Thomas Hellström
authored and
Matthew Brost
committed
Mar 6, 2025
1 parent
1afaeb8
commit 73463da
Showing
1 changed file
with
107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* SPDX-License-Identifier: MIT */ | ||
#ifndef _DRM_PAGEMAP_H_ | ||
#define _DRM_PAGEMAP_H_ | ||
|
||
#include <linux/dma-direction.h> | ||
#include <linux/hmm.h> | ||
#include <linux/types.h> | ||
|
||
struct drm_pagemap; | ||
struct device; | ||
|
||
/** | ||
* enum drm_interconnect_protocol - Used to identify an interconnect protocol. | ||
* | ||
* @DRM_INTERCONNECT_SYSTEM: DMA map is system pages | ||
* @DRM_INTERCONNECT_DRIVER: DMA map is driver defined | ||
*/ | ||
enum drm_interconnect_protocol { | ||
DRM_INTERCONNECT_SYSTEM, | ||
DRM_INTERCONNECT_DRIVER, | ||
/* A driver can add private values beyond DRM_INTERCONNECT_DRIVER */ | ||
}; | ||
|
||
/** | ||
* struct drm_pagemap_device_addr - Device address representation. | ||
* @addr: The dma address or driver-defined address for driver private interconnects. | ||
* @proto: The interconnect protocol. | ||
* @order: The page order of the device mapping. (Size is PAGE_SIZE << order). | ||
* @dir: The DMA direction. | ||
* | ||
* Note: There is room for improvement here. We should be able to pack into | ||
* 64 bits. | ||
*/ | ||
struct drm_pagemap_device_addr { | ||
dma_addr_t addr; | ||
u64 proto : 54; | ||
u64 order : 8; | ||
u64 dir : 2; | ||
}; | ||
|
||
/** | ||
* drm_pagemap_device_addr_encode() - Encode a dma address with metadata | ||
* @addr: The dma address or driver-defined address for driver private interconnects. | ||
* @proto: The interconnect protocol. | ||
* @order: The page order of the dma mapping. (Size is PAGE_SIZE << order). | ||
* @dir: The DMA direction. | ||
* | ||
* Return: A struct drm_pagemap_device_addr encoding the above information. | ||
*/ | ||
static inline struct drm_pagemap_device_addr | ||
drm_pagemap_device_addr_encode(dma_addr_t addr, | ||
enum drm_interconnect_protocol proto, | ||
unsigned int order, | ||
enum dma_data_direction dir) | ||
{ | ||
return (struct drm_pagemap_device_addr) { | ||
.addr = addr, | ||
.proto = proto, | ||
.order = order, | ||
.dir = dir, | ||
}; | ||
} | ||
|
||
/** | ||
* struct drm_pagemap_ops: Ops for a drm-pagemap. | ||
*/ | ||
struct drm_pagemap_ops { | ||
/** | ||
* @device_map: Map for device access or provide a virtual address suitable for | ||
* | ||
* @dpagemap: The struct drm_pagemap for the page. | ||
* @dev: The device mapper. | ||
* @page: The page to map. | ||
* @order: The page order of the device mapping. (Size is PAGE_SIZE << order). | ||
* @dir: The transfer direction. | ||
*/ | ||
struct drm_pagemap_device_addr (*device_map)(struct drm_pagemap *dpagemap, | ||
struct device *dev, | ||
struct page *page, | ||
unsigned int order, | ||
enum dma_data_direction dir); | ||
|
||
/** | ||
* @device_unmap: Unmap a device address previously obtained using @device_map. | ||
* | ||
* @dpagemap: The struct drm_pagemap for the mapping. | ||
* @dev: The device unmapper. | ||
* @addr: The device address obtained when mapping. | ||
*/ | ||
void (*device_unmap)(struct drm_pagemap *dpagemap, | ||
struct device *dev, | ||
struct drm_pagemap_device_addr addr); | ||
|
||
}; | ||
|
||
/** | ||
* struct drm_pagemap: Additional information for a struct dev_pagemap | ||
* used for device p2p handshaking. | ||
* @ops: The struct drm_pagemap_ops. | ||
* @dev: The struct drevice owning the device-private memory. | ||
*/ | ||
struct drm_pagemap { | ||
const struct drm_pagemap_ops *ops; | ||
struct device *dev; | ||
}; | ||
|
||
#endif |