1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * Copyright (C) 2015-2018 Etnaviv Project |
4 | */ |
5 | |
6 | #ifndef __ETNAVIV_DRV_H__ |
7 | #define __ETNAVIV_DRV_H__ |
8 | |
9 | #include <linux/io.h> |
10 | #include <linux/list.h> |
11 | #include <linux/mm_types.h> |
12 | #include <linux/sizes.h> |
13 | #include <linux/time64.h> |
14 | #include <linux/types.h> |
15 | #include <linux/xarray.h> |
16 | |
17 | #include <drm/drm_drv.h> |
18 | #include <drm/drm_gem.h> |
19 | #include <drm/etnaviv_drm.h> |
20 | #include <drm/gpu_scheduler.h> |
21 | |
22 | struct etnaviv_cmdbuf; |
23 | struct etnaviv_gpu; |
24 | struct etnaviv_mmu; |
25 | struct etnaviv_gem_object; |
26 | struct etnaviv_gem_submit; |
27 | struct etnaviv_iommu_global; |
28 | |
29 | #define ETNAVIV_SOFTPIN_START_ADDRESS SZ_4M /* must be >= SUBALLOC_SIZE */ |
30 | |
31 | struct etnaviv_file_private { |
32 | int id; |
33 | struct etnaviv_iommu_context *mmu; |
34 | struct drm_sched_entity sched_entity[ETNA_MAX_PIPES]; |
35 | }; |
36 | |
37 | struct etnaviv_drm_private { |
38 | int num_gpus; |
39 | struct etnaviv_gpu *gpu[ETNA_MAX_PIPES]; |
40 | gfp_t shm_gfp_mask; |
41 | |
42 | struct etnaviv_cmdbuf_suballoc *cmdbuf_suballoc; |
43 | struct etnaviv_iommu_global *mmu_global; |
44 | |
45 | struct xarray active_contexts; |
46 | u32 next_context_id; |
47 | |
48 | /* list of GEM objects: */ |
49 | struct mutex gem_lock; |
50 | struct list_head gem_list; |
51 | }; |
52 | |
53 | int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, |
54 | struct drm_file *file); |
55 | |
56 | int etnaviv_gem_mmap_offset(struct drm_gem_object *obj, u64 *offset); |
57 | struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj); |
58 | int etnaviv_gem_prime_vmap(struct drm_gem_object *obj, struct iosys_map *map); |
59 | struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, |
60 | struct dma_buf_attachment *attach, struct sg_table *sg); |
61 | int etnaviv_gem_prime_pin(struct drm_gem_object *obj); |
62 | void etnaviv_gem_prime_unpin(struct drm_gem_object *obj); |
63 | void *etnaviv_gem_vmap(struct drm_gem_object *obj); |
64 | int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op, |
65 | struct drm_etnaviv_timespec *timeout); |
66 | int etnaviv_gem_cpu_fini(struct drm_gem_object *obj); |
67 | void etnaviv_gem_free_object(struct drm_gem_object *obj); |
68 | int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, |
69 | u32 size, u32 flags, u32 *handle); |
70 | int etnaviv_gem_new_userptr(struct drm_device *dev, struct drm_file *file, |
71 | uintptr_t ptr, u32 size, u32 flags, u32 *handle); |
72 | u16 etnaviv_buffer_init(struct etnaviv_gpu *gpu); |
73 | u16 etnaviv_buffer_config_mmuv2(struct etnaviv_gpu *gpu, u32 mtlb_addr, u32 safe_addr); |
74 | u16 etnaviv_buffer_config_pta(struct etnaviv_gpu *gpu, unsigned short id); |
75 | void etnaviv_buffer_end(struct etnaviv_gpu *gpu); |
76 | void etnaviv_sync_point_queue(struct etnaviv_gpu *gpu, unsigned int event); |
77 | void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state, |
78 | struct etnaviv_iommu_context *mmu, |
79 | unsigned int event, struct etnaviv_cmdbuf *cmdbuf); |
80 | void etnaviv_validate_init(void); |
81 | bool etnaviv_cmd_validate_one(struct etnaviv_gpu *gpu, |
82 | u32 *stream, unsigned int size, |
83 | struct drm_etnaviv_gem_submit_reloc *relocs, unsigned int reloc_size); |
84 | |
85 | #ifdef CONFIG_DEBUG_FS |
86 | void etnaviv_gem_describe_objects(struct etnaviv_drm_private *priv, |
87 | struct seq_file *m); |
88 | #endif |
89 | |
90 | #define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) |
91 | #define VERB(fmt, ...) if (0) DRM_DEBUG(fmt"\n", ##__VA_ARGS__) |
92 | |
93 | /* |
94 | * Return the storage size of a structure with a variable length array. |
95 | * The array is nelem elements of elem_size, where the base structure |
96 | * is defined by base. If the size overflows size_t, return zero. |
97 | */ |
98 | static inline size_t size_vstruct(size_t nelem, size_t elem_size, size_t base) |
99 | { |
100 | if (elem_size && nelem > (SIZE_MAX - base) / elem_size) |
101 | return 0; |
102 | return base + nelem * elem_size; |
103 | } |
104 | |
105 | /* |
106 | * Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies. |
107 | * We need to calculate the timeout in terms of number of jiffies |
108 | * between the specified timeout and the current CLOCK_MONOTONIC time. |
109 | */ |
110 | static inline unsigned long etnaviv_timeout_to_jiffies( |
111 | const struct drm_etnaviv_timespec *timeout) |
112 | { |
113 | struct timespec64 ts, to = { |
114 | .tv_sec = timeout->tv_sec, |
115 | .tv_nsec = timeout->tv_nsec, |
116 | }; |
117 | |
118 | ktime_get_ts64(ts: &ts); |
119 | |
120 | /* timeouts before "now" have already expired */ |
121 | if (timespec64_compare(lhs: &to, rhs: &ts) <= 0) |
122 | return 0; |
123 | |
124 | ts = timespec64_sub(lhs: to, rhs: ts); |
125 | |
126 | return timespec64_to_jiffies(value: &ts); |
127 | } |
128 | |
129 | #endif /* __ETNAVIV_DRV_H__ */ |
130 | |