MAJOR=4
MINOR=1
DEVNAME=tty1
     	ˆ¿ÀƒyæA_†I|¥�+ÄÃ "~    	/* 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>

#define NR_PAGES(order) (1U << (order))

struct dma_fence;
struct drm_pagemap;
struct drm_pagemap_zdd;
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_addr - 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_addr {
	dma_addr_t addr;
	u64 proto : 54;
	u64 order : 8;
	u64 dir : 2;
};

/**
 * drm_pagemap_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_addr encoding the above information.
 */
static inline struct drm_pagemap_addr
drm_pagemap_addr_encode(dma_addr_t addr,
			enum drm_interconnect_protocol proto,
			unsigned int order,
			enum dma_data_direction dir)
{
	return (struct drm_pagemap_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_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_addr addr);

	/**
	 * @populate_mm: Populate part of the mm with @dpagemap memory,
	 * migrating existing data.
	 * @dpagemap: The struct drm_pagemap managing the memory.
	 * @start: The virtual start address in @mm
	 * @end: The virtual end address in @mm
	 * @mm: Pointer to a live mm. The caller must have an mmget()
	 * reference.
	 *
	 * The caller will have the mm lock at least in read mode.
	 * Note that there is no guarantee that the memory is resident
	 * after the function returns, it's best effort only.
	 * When the mm is not using the memory anymore,
	 * it will be released. The struct drm_pagemap might have a
	 * mechanism in place to reclaim the memory and the data will
	 * then be migrated. Typically to system memory.
	 * The implementation should hold sufficient runtime power-
	 * references while pages are used in an address space and
	 * should ideally guard against hardware device unbind in
	 * a way such that device pages are migrated back to system
	 * followed by device page removal. The implementation should
	 * return -ENODEV after device removal.
	 *
	 * Return: 0 if successful. Negative error code on error.
	 */
	int (*populate_mm)(struct drm_pagemap *dpagemap,
			   unsigned long start, unsigned long end,
			   struct mm_struct *mm,
			   unsigned long timesli