1 /* 2 * 3 * (C) COPYRIGHT 2019 ARM Limited. All rights reserved. 4 * 5 * This program is free software and is provided to you under the terms of the 6 * GNU General Public License version 2 as published by the Free Software 7 * Foundation, and any use by you of this program is subject to the terms 8 * of such GNU licence. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, you can access it online at 17 * http://www.gnu.org/licenses/gpl-2.0.html. 18 * 19 * SPDX-License-Identifier: GPL-2.0 20 * 21 */ 22 23 #ifndef _MEMORY_GROUP_MANAGER_H_ 24 #define _MEMORY_GROUP_MANAGER_H_ 25 26 #include <linux/mm.h> 27 #include <linux/of.h> 28 #include <linux/version.h> 29 30 #if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE) 31 typedef int (vm_fault_t); 32 #endif 33 #define MEMORY_GROUP_MANAGER_NR_GROUPS (16) 34 35 struct memory_group_manager_device; 36 struct memory_group_manager_import_data; 37 38 /** 39 * struct memory_group_manager_ops - Callbacks for memory group manager 40 * operations 41 * 42 * @mgm_alloc_page: Callback to allocate physical memory in a group 43 * @mgm_free_page: Callback to free physical memory in a group 44 * @mgm_get_import_memory_id: Callback to get the group ID for imported memory 45 * @mgm_update_gpu_pte: Callback to modify a GPU page table entry 46 * @mgm_vmf_insert_pfn_prot: Callback to map a physical memory page for the CPU 47 */ 48 struct memory_group_manager_ops { 49 /** 50 * mgm_alloc_page - Allocate a physical memory page in a group 51 * 52 * @mgm_dev: The memory group manager through which the request is 53 * being made. 54 * @group_id: A physical memory group ID. The meaning of this is defined 55 * by the systems integrator. Its valid range is 56 * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. 57 * @gfp_mask: Bitmask of Get Free Page flags affecting allocator 58 * behavior. 59 * @order: Page order for physical page size (order=0 means 4 KiB, 60 * order=9 means 2 MiB). 61 * 62 * Return: Pointer to allocated page, or NULL if allocation failed. 63 */ 64 struct page *(*mgm_alloc_page)(struct memory_group_manager_device *mgm_dev, int group_id, gfp_t gfp_mask, 65 unsigned int order); 66 67 /** 68 * mgm_free_page - Free a physical memory page in a group 69 * 70 * @mgm_dev: The memory group manager through which the request 71 * is being made. 72 * @group_id: A physical memory group ID. The meaning of this is 73 * defined by the systems integrator. Its valid range is 74 * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. 75 * @page: Address of the struct associated with a page of physical 76 * memory that was allocated by calling the mgm_alloc_page 77 * method of the same memory pool with the same values of 78 * @group_id and @order. 79 * @order: Page order for physical page size (order=0 means 4 KiB, 80 * order=9 means 2 MiB). 81 */ 82 void (*mgm_free_page)(struct memory_group_manager_device *mgm_dev, int group_id, struct page *page, 83 unsigned int order); 84 85 /** 86 * mgm_get_import_memory_id - Get the physical memory group ID for the 87 * imported memory 88 * 89 * @mgm_dev: The memory group manager through which the request 90 * is being made. 91 * @import_data: Pointer to the data which describes imported memory. 92 * 93 * Note that provision of this call back is optional, where it is not 94 * provided this call back pointer must be set to NULL to indicate it 95 * is not in use. 96 * 97 * Return: The memory group ID to use when mapping pages from this 98 * imported memory. 99 */ 100 int (*mgm_get_import_memory_id)(struct memory_group_manager_device *mgm_dev, 101 struct memory_group_manager_import_data *import_data); 102 103 /** 104 * mgm_update_gpu_pte - Modify a GPU page table entry for a memory group 105 * 106 * @mgm_dev: The memory group manager through which the request 107 * is being made. 108 * @group_id: A physical memory group ID. The meaning of this is 109 * defined by the systems integrator. Its valid range is 110 * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. 111 * @mmu_level: The level of the page table entry in @ate. 112 * @pte: The page table entry to modify, in LPAE or AArch64 format 113 * (depending on the driver's configuration). This should be 114 * decoded to determine the physical address and any other 115 * properties of the mapping the manager requires. 116 * 117 * This function allows the memory group manager to modify a GPU page 118 * table entry before it is stored by the kbase module (controller 119 * driver). It may set certain bits in the page table entry attributes 120 * or in the physical address, based on the physical memory group ID. 121 * 122 * Return: A modified GPU page table entry to be stored in a page table. 123 */ 124 u64 (*mgm_update_gpu_pte)(struct memory_group_manager_device *mgm_dev, int group_id, int mmu_level, u64 pte); 125 126 /** 127 * mgm_vmf_insert_pfn_prot - Map a physical page in a group for the CPU 128 * 129 * @mgm_dev: The memory group manager through which the request 130 * is being made. 131 * @group_id: A physical memory group ID. The meaning of this is 132 * defined by the systems integrator. Its valid range is 133 * 0 .. MEMORY_GROUP_MANAGER_NR_GROUPS-1. 134 * @vma: The virtual memory area to insert the page into. 135 * @addr: A virtual address (in @vma) to assign to the page. 136 * @pfn: The kernel Page Frame Number to insert at @addr in @vma. 137 * @pgprot: Protection flags for the inserted page. 138 * 139 * Called from a CPU virtual memory page fault handler. This function 140 * creates a page table entry from the given parameter values and stores 141 * it at the appropriate location (unlike mgm_update_gpu_pte, which 142 * returns a modified entry). 143 * 144 * Return: Type of fault that occurred or VM_FAULT_NOPAGE if the page 145 * table entry was successfully installed. 146 */ 147 vm_fault_t (*mgm_vmf_insert_pfn_prot)(struct memory_group_manager_device *mgm_dev, int group_id, 148 struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, 149 pgprot_t pgprot); 150 }; 151 152 /** 153 * struct memory_group_manager_device - Device structure for a memory group 154 * manager 155 * 156 * @ops - Callbacks associated with this device 157 * @data - Pointer to device private data 158 * 159 * In order for a systems integrator to provide custom behaviors for memory 160 * operations performed by the kbase module (controller driver), they must 161 * provide a platform-specific driver module which implements this interface. 162 * 163 * This structure should be registered with the platform device using 164 * platform_set_drvdata(). 165 */ 166 struct memory_group_manager_device { 167 struct memory_group_manager_ops ops; 168 void *data; 169 struct module *owner; 170 }; 171 172 enum memory_group_manager_import_type { MEMORY_GROUP_MANAGER_IMPORT_TYPE_DMA_BUF }; 173 174 /** 175 * struct memory_group_manager_import_data - Structure describing the imported 176 * memory 177 * 178 * @type - type of imported memory 179 * @u - Union describing the imported memory 180 * 181 */ 182 struct memory_group_manager_import_data { 183 enum memory_group_manager_import_type type; 184 union { 185 struct dma_buf *dma_buf; 186 } u; 187 }; 188 189 #endif /* _MEMORY_GROUP_MANAGER_H_ */ 190