xref: /linux/drivers/gpu/drm/imagination/pvr_mmu.h (revision 2b0cfa6e49566c8fa6759734cf821aa6e8271a9e)
1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
2 /* Copyright (c) 2023 Imagination Technologies Ltd. */
3 
4 #ifndef PVR_MMU_H
5 #define PVR_MMU_H
6 
7 #include <linux/memory.h>
8 #include <linux/types.h>
9 
10 /* Forward declaration from "pvr_device.h" */
11 struct pvr_device;
12 
13 /* Forward declaration from "pvr_mmu.c" */
14 struct pvr_mmu_context;
15 struct pvr_mmu_op_context;
16 
17 /* Forward declaration from "pvr_vm.c" */
18 struct pvr_vm_context;
19 
20 /* Forward declaration from <linux/scatterlist.h> */
21 struct sg_table;
22 
23 /**
24  * DOC: Public API (constants)
25  *
26  * .. c:macro:: PVR_DEVICE_PAGE_SIZE
27  *
28  *    Fixed page size referenced by leaf nodes in the page table tree
29  *    structure. In the current implementation, this value is pegged to the
30  *    CPU page size (%PAGE_SIZE). It is therefore an error to specify a CPU
31  *    page size which is not also a supported device page size. The supported
32  *    device page sizes are: 4KiB, 16KiB, 64KiB, 256KiB, 1MiB and 2MiB.
33  *
34  * .. c:macro:: PVR_DEVICE_PAGE_SHIFT
35  *
36  *    Shift value used to efficiently multiply or divide by
37  *    %PVR_DEVICE_PAGE_SIZE.
38  *
39  *    This value is derived from %PVR_DEVICE_PAGE_SIZE.
40  *
41  * .. c:macro:: PVR_DEVICE_PAGE_MASK
42  *
43  *    Mask used to round a value down to the nearest multiple of
44  *    %PVR_DEVICE_PAGE_SIZE. When bitwise negated, it will indicate whether a
45  *    value is already a multiple of %PVR_DEVICE_PAGE_SIZE.
46  *
47  *    This value is derived from %PVR_DEVICE_PAGE_SIZE.
48  */
49 
50 /* PVR_DEVICE_PAGE_SIZE determines the page size */
51 #define PVR_DEVICE_PAGE_SIZE (PAGE_SIZE)
52 #define PVR_DEVICE_PAGE_SHIFT (PAGE_SHIFT)
53 #define PVR_DEVICE_PAGE_MASK (PAGE_MASK)
54 
55 /**
56  * DOC: Page table index utilities (constants)
57  *
58  * .. c:macro:: PVR_PAGE_TABLE_ADDR_SPACE_SIZE
59  *
60  *    Size of device-virtual address space which can be represented in the page
61  *    table structure.
62  *
63  *    This value is checked at runtime against
64  *    &pvr_device_features.virtual_address_space_bits by
65  *    pvr_vm_create_context(), which will return an error if the feature value
66  *    does not match this constant.
67  *
68  *    .. admonition:: Future work
69  *
70  *       It should be possible to support other values of
71  *       &pvr_device_features.virtual_address_space_bits, but so far no
72  *       hardware has been created which advertises an unsupported value.
73  *
74  * .. c:macro:: PVR_PAGE_TABLE_ADDR_BITS
75  *
76  *    Number of bits needed to represent any value less than
77  *    %PVR_PAGE_TABLE_ADDR_SPACE_SIZE exactly.
78  *
79  * .. c:macro:: PVR_PAGE_TABLE_ADDR_MASK
80  *
81  *    Bitmask of device-virtual addresses which are valid in the page table
82  *    structure.
83  *
84  *    This value is derived from %PVR_PAGE_TABLE_ADDR_SPACE_SIZE, so the same
85  *    notes on that constant apply here.
86  */
87 #define PVR_PAGE_TABLE_ADDR_SPACE_SIZE SZ_1T
88 #define PVR_PAGE_TABLE_ADDR_BITS __ffs(PVR_PAGE_TABLE_ADDR_SPACE_SIZE)
89 #define PVR_PAGE_TABLE_ADDR_MASK (PVR_PAGE_TABLE_ADDR_SPACE_SIZE - 1)
90 
91 void pvr_mmu_flush_request_all(struct pvr_device *pvr_dev);
92 int pvr_mmu_flush_exec(struct pvr_device *pvr_dev, bool wait);
93 
94 struct pvr_mmu_context *pvr_mmu_context_create(struct pvr_device *pvr_dev);
95 void pvr_mmu_context_destroy(struct pvr_mmu_context *ctx);
96 
97 dma_addr_t pvr_mmu_get_root_table_dma_addr(struct pvr_mmu_context *ctx);
98 
99 void pvr_mmu_op_context_destroy(struct pvr_mmu_op_context *op_ctx);
100 struct pvr_mmu_op_context *
101 pvr_mmu_op_context_create(struct pvr_mmu_context *ctx,
102 			  struct sg_table *sgt, u64 sgt_offset, u64 size);
103 
104 int pvr_mmu_map(struct pvr_mmu_op_context *op_ctx, u64 size, u64 flags,
105 		u64 device_addr);
106 int pvr_mmu_unmap(struct pvr_mmu_op_context *op_ctx, u64 device_addr, u64 size);
107 
108 #endif /* PVR_MMU_H */
109