|
| 1 | +/* SPDX-License-Identifier: MIT */ |
| 2 | +#ifndef _DRM_PAGEMAP_H_ |
| 3 | +#define _DRM_PAGEMAP_H_ |
| 4 | + |
| 5 | +#include <linux/dma-direction.h> |
| 6 | +#include <linux/hmm.h> |
| 7 | +#include <linux/types.h> |
| 8 | + |
| 9 | +struct drm_pagemap; |
| 10 | +struct device; |
| 11 | + |
| 12 | +/** |
| 13 | + * enum drm_interconnect_protocol - Used to identify an interconnect protocol. |
| 14 | + * |
| 15 | + * @DRM_INTERCONNECT_SYSTEM: DMA map is system pages |
| 16 | + * @DRM_INTERCONNECT_DRIVER: DMA map is driver defined |
| 17 | + */ |
| 18 | +enum drm_interconnect_protocol { |
| 19 | + DRM_INTERCONNECT_SYSTEM, |
| 20 | + DRM_INTERCONNECT_DRIVER, |
| 21 | + /* A driver can add private values beyond DRM_INTERCONNECT_DRIVER */ |
| 22 | +}; |
| 23 | + |
| 24 | +/** |
| 25 | + * struct drm_pagemap_device_addr - Device address representation. |
| 26 | + * @addr: The dma address or driver-defined address for driver private interconnects. |
| 27 | + * @proto: The interconnect protocol. |
| 28 | + * @order: The page order of the device mapping. (Size is PAGE_SIZE << order). |
| 29 | + * @dir: The DMA direction. |
| 30 | + * |
| 31 | + * Note: There is room for improvement here. We should be able to pack into |
| 32 | + * 64 bits. |
| 33 | + */ |
| 34 | +struct drm_pagemap_device_addr { |
| 35 | + dma_addr_t addr; |
| 36 | + u64 proto : 54; |
| 37 | + u64 order : 8; |
| 38 | + u64 dir : 2; |
| 39 | +}; |
| 40 | + |
| 41 | +/** |
| 42 | + * drm_pagemap_device_addr_encode() - Encode a dma address with metadata |
| 43 | + * @addr: The dma address or driver-defined address for driver private interconnects. |
| 44 | + * @proto: The interconnect protocol. |
| 45 | + * @order: The page order of the dma mapping. (Size is PAGE_SIZE << order). |
| 46 | + * @dir: The DMA direction. |
| 47 | + * |
| 48 | + * Return: A struct drm_pagemap_device_addr encoding the above information. |
| 49 | + */ |
| 50 | +static inline struct drm_pagemap_device_addr |
| 51 | +drm_pagemap_device_addr_encode(dma_addr_t addr, |
| 52 | + enum drm_interconnect_protocol proto, |
| 53 | + unsigned int order, |
| 54 | + enum dma_data_direction dir) |
| 55 | +{ |
| 56 | + return (struct drm_pagemap_device_addr) { |
| 57 | + .addr = addr, |
| 58 | + .proto = proto, |
| 59 | + .order = order, |
| 60 | + .dir = dir, |
| 61 | + }; |
| 62 | +} |
| 63 | + |
| 64 | +/** |
| 65 | + * struct drm_pagemap_ops: Ops for a drm-pagemap. |
| 66 | + */ |
| 67 | +struct drm_pagemap_ops { |
| 68 | + /** |
| 69 | + * @device_map: Map for device access or provide a virtual address suitable for |
| 70 | + * |
| 71 | + * @dpagemap: The struct drm_pagemap for the page. |
| 72 | + * @dev: The device mapper. |
| 73 | + * @page: The page to map. |
| 74 | + * @order: The page order of the device mapping. (Size is PAGE_SIZE << order). |
| 75 | + * @dir: The transfer direction. |
| 76 | + */ |
| 77 | + struct drm_pagemap_device_addr (*device_map)(struct drm_pagemap *dpagemap, |
| 78 | + struct device *dev, |
| 79 | + struct page *page, |
| 80 | + unsigned int order, |
| 81 | + enum dma_data_direction dir); |
| 82 | + |
| 83 | + /** |
| 84 | + * @device_unmap: Unmap a device address previously obtained using @device_map. |
| 85 | + * |
| 86 | + * @dpagemap: The struct drm_pagemap for the mapping. |
| 87 | + * @dev: The device unmapper. |
| 88 | + * @addr: The device address obtained when mapping. |
| 89 | + */ |
| 90 | + void (*device_unmap)(struct drm_pagemap *dpagemap, |
| 91 | + struct device *dev, |
| 92 | + struct drm_pagemap_device_addr addr); |
| 93 | + |
| 94 | +}; |
| 95 | + |
| 96 | +/** |
| 97 | + * struct drm_pagemap: Additional information for a struct dev_pagemap |
| 98 | + * used for device p2p handshaking. |
| 99 | + * @ops: The struct drm_pagemap_ops. |
| 100 | + * @dev: The struct drevice owning the device-private memory. |
| 101 | + */ |
| 102 | +struct drm_pagemap { |
| 103 | + const struct drm_pagemap_ops *ops; |
| 104 | + struct device *dev; |
| 105 | +}; |
| 106 | + |
| 107 | +#endif |
0 commit comments