• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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