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" */
11struct pvr_device;
12
13/* Forward declaration from "pvr_mmu.c" */
14struct pvr_mmu_context;
15struct pvr_mmu_op_context;
16
17/* Forward declaration from "pvr_vm.c" */
18struct pvr_vm_context;
19
20/* Forward declaration from <linux/scatterlist.h> */
21struct 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
91void pvr_mmu_flush_request_all(struct pvr_device *pvr_dev);
92int pvr_mmu_flush_exec(struct pvr_device *pvr_dev, bool wait);
93
94struct pvr_mmu_context *pvr_mmu_context_create(struct pvr_device *pvr_dev);
95void pvr_mmu_context_destroy(struct pvr_mmu_context *ctx);
96
97dma_addr_t pvr_mmu_get_root_table_dma_addr(struct pvr_mmu_context *ctx);
98
99void pvr_mmu_op_context_destroy(struct pvr_mmu_op_context *op_ctx);
100struct pvr_mmu_op_context *
101pvr_mmu_op_context_create(struct pvr_mmu_context *ctx,
102			  struct sg_table *sgt, u64 sgt_offset, u64 size);
103
104int pvr_mmu_map(struct pvr_mmu_op_context *op_ctx, u64 size, u64 flags,
105		u64 device_addr);
106int pvr_mmu_unmap(struct pvr_mmu_op_context *op_ctx, u64 device_addr, u64 size);
107
108#endif /* PVR_MMU_H */
109