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