| /* | |
| * | |
| * (C) COPYRIGHT 2019 ARM Limited. All rights reserved. | |
| * | |
| * This program is free software and is provided to you under the terms of the | |
| * GNU General Public License version 2 as published by the Free Software | |
| * Foundation, and any use by you of this program is subject to the terms | |
| * of such GNU licence. | |
| * | |
| * This program is distributed in the hope that it will be useful, | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| * GNU General Public License for more details. | |
| * | |
| * You should have received a copy of the GNU General Public License | |
| * along with this program; if not, you can access it online at | |
| * http://www.gnu.org/licenses/gpl-2.0.html. | |
| * | |
| * SPDX-License-Identifier: GPL-2.0 | |
| * | |
| */ | |
| #ifndef _MEMORY_GROUP_MANAGER_H_ | |
| #define _MEMORY_GROUP_MANAGER_H_ | |
| #include <linux/mm.h> | |
| #include <linux/of.h> | |
| #include <linux/version.h> | |
| #if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) | |
| typedef int vm_fault_t; | |
| #endif | |
| #define MEMORY_GROUP_MANAGER_NR_GROUPS (16) | |
| struct memory_group_manager_device; | |
| struct memory_group_manager_import_data; | |
| /** | |
| * struct memory_group_manager_ops - Callbacks for memory group manager | |
| * operations | |
| * | |
| * @mgm_alloc_page: Callback to allocate physical memory in a group | |
| * @mgm_free_page: Callback to free physical memory in a group | |
| * @mgm_get_import_memory_id: Callback to get the group ID for imported memory | |
| * @mgm_update_gpu_pte: Callback to modify a GPU page table entry | |
| * @mgm_vmf_insert_pfn_prot: Callback to map a physical memory page for the CPU | |
| */ | |
| struct memory_group_manager_ops { | |
| /** | |
| * mgm_alloc_page - Allocate a physical memory page in a group | |
| * | |
| * @mgm_dev: The memory group manager through which the request is | |
| * being made. | |
| * @group_id: A physical memory group ID. The meaning of this is defined | |
| * by the systems integrator. Its valid range is | |
| * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. | |
| * @gfp_mask: Bitmask of Get Free Page flags affecting allocator | |
| * behavior. | |
| * @order: Page order for physical page size (order=0 means 4 KiB, | |
| * order=9 means 2 MiB). | |
| * | |
| * Return: Pointer to allocated page, or NULL if allocation failed. | |
| */ | |
| struct page *(*mgm_alloc_page)( | |
| struct memory_group_manager_device *mgm_dev, int group_id, | |
| gfp_t gfp_mask, unsigned int order); | |
| /** | |
| * mgm_free_page - Free a physical memory page in a group | |
| * | |
| * @mgm_dev: The memory group manager through which the request | |
| * is being made. | |
| * @group_id: A physical memory group ID. The meaning of this is | |
| * defined by the systems integrator. Its valid range is | |
| * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. | |
| * @page: Address of the struct associated with a page of physical | |
| * memory that was allocated by calling the mgm_alloc_page | |
| * method of the same memory pool with the same values of | |
| * @group_id and @order. | |
| * @order: Page order for physical page size (order=0 means 4 KiB, | |
| * order=9 means 2 MiB). | |
| */ | |
| void (*mgm_free_page)( | |
| struct memory_group_manager_device *mgm_dev, int group_id, | |
| struct page *page, unsigned int order); | |
| /** | |
| * mgm_get_import_memory_id - Get the physical memory group ID for the | |
| * imported memory | |
| * | |
| * @mgm_dev: The memory group manager through which the request | |
| * is being made. | |
| * @import_data: Pointer to the data which describes imported memory. | |
| * | |
| * Note that provision of this call back is optional, where it is not | |
| * provided this call back pointer must be set to NULL to indicate it | |
| * is not in use. | |
| * | |
| * Return: The memory group ID to use when mapping pages from this | |
| * imported memory. | |
| */ | |
| int (*mgm_get_import_memory_id)( | |
| struct memory_group_manager_device *mgm_dev, | |
| struct memory_group_manager_import_data *import_data); | |
| /** | |
| * mgm_update_gpu_pte - Modify a GPU page table entry for a memory group | |
| * | |
| * @mgm_dev: The memory group manager through which the request | |
| * is being made. | |
| * @group_id: A physical memory group ID. The meaning of this is | |
| * defined by the systems integrator. Its valid range is | |
| * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. | |
| * @mmu_level: The level of the page table entry in @ate. | |
| * @pte: The page table entry to modify, in LPAE or AArch64 format | |
| * (depending on the driver's configuration). This should be | |
| * decoded to determine the physical address and any other | |
| * properties of the mapping the manager requires. | |
| * | |
| * This function allows the memory group manager to modify a GPU page | |
| * table entry before it is stored by the kbase module (controller | |
| * driver). It may set certain bits in the page table entry attributes | |
| * or in the physical address, based on the physical memory group ID. | |
| * | |
| * Return: A modified GPU page table entry to be stored in a page table. | |
| */ | |
| u64 (*mgm_update_gpu_pte)(struct memory_group_manager_device *mgm_dev, | |
| int group_id, int mmu_level, u64 pte); | |
| /** | |
| * mgm_vmf_insert_pfn_prot - Map a physical page in a group for the CPU | |
| * | |
| * @mgm_dev: The memory group manager through which the request | |
| * is being made. | |
| * @group_id: A physical memory group ID. The meaning of this is | |
| * defined by the systems integrator. Its valid range is | |
| * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. | |
| * @vma: The virtual memory area to insert the page into. | |
| * @addr: A virtual address (in @vma) to assign to the page. | |
| * @pfn: The kernel Page Frame Number to insert at @addr in @vma. | |
| * @pgprot: Protection flags for the inserted page. | |
| * | |
| * Called from a CPU virtual memory page fault handler. This function | |
| * creates a page table entry from the given parameter values and stores | |
| * it at the appropriate location (unlike mgm_update_gpu_pte, which | |
| * returns a modified entry). | |
| * | |
| * Return: Type of fault that occurred or VM_FAULT_NOPAGE if the page | |
| * table entry was successfully installed. | |
| */ | |
| vm_fault_t (*mgm_vmf_insert_pfn_prot)( | |
| struct memory_group_manager_device *mgm_dev, int group_id, | |
| struct vm_area_struct *vma, unsigned long addr, | |
| unsigned long pfn, pgprot_t pgprot); | |
| }; | |
| /** | |
| * struct memory_group_manager_device - Device structure for a memory group | |
| * manager | |
| * | |
| * @ops - Callbacks associated with this device | |
| * @data - Pointer to device private data | |
| * | |
| * In order for a systems integrator to provide custom behaviors for memory | |
| * operations performed by the kbase module (controller driver), they must | |
| * provide a platform-specific driver module which implements this interface. | |
| * | |
| * This structure should be registered with the platform device using | |
| * platform_set_drvdata(). | |
| */ | |
| struct memory_group_manager_device { | |
| struct memory_group_manager_ops ops; | |
| void *data; | |
| struct module *owner; | |
| }; | |
| enum memory_group_manager_import_type { | |
| MEMORY_GROUP_MANAGER_IMPORT_TYPE_DMA_BUF | |
| }; | |
| /** | |
| * struct memory_group_manager_import_data - Structure describing the imported | |
| * memory | |
| * | |
| * @type - type of imported memory | |
| * @u - Union describing the imported memory | |
| * | |
| */ | |
| struct memory_group_manager_import_data { | |
| enum memory_group_manager_import_type type; | |
| union { | |
| struct dma_buf *dma_buf; | |
| } u; | |
| }; | |
| #endif /* _MEMORY_GROUP_MANAGER_H_ */ |