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