1 /*
2 * Copyright © 2013 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 *
23 */
24
25 #ifndef INTEL_DEVICE_INFO_H
26 #define INTEL_DEVICE_INFO_H
27
28 #include <stdbool.h>
29 #include <stdint.h>
30
31 #include "util/bitset.h"
32 #include "util/macros.h"
33 #include "compiler/shader_enums.h"
34 #include "intel_kmd.h"
35
36 #include "intel/dev/intel_wa.h"
37
38 #include "intel/dev/intel_device_info_gen.h"
39
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43
44 #define intel_platform_in_range(platform, platform_range) \
45 (((platform) >= INTEL_PLATFORM_ ## platform_range ## _START) && \
46 ((platform) <= INTEL_PLATFORM_ ## platform_range ## _END))
47
48 #define intel_device_info_is_atsm(devinfo) \
49 intel_platform_in_range((devinfo)->platform, ATSM)
50
51 #define intel_device_info_is_dg2(devinfo) \
52 (intel_platform_in_range((devinfo)->platform, DG2) || \
53 intel_platform_in_range((devinfo)->platform, ATSM))
54
55 #define intel_device_info_is_mtl(devinfo) \
56 intel_platform_in_range((devinfo)->platform, MTL)
57
58 #define intel_device_info_is_adln(devinfo) \
59 (devinfo->is_adl_n == true)
60
61 #define intel_device_info_is_arl(devinfo) \
62 intel_platform_in_range((devinfo)->platform, ARL)
63
64 #define intel_device_info_is_mtl_or_arl(devinfo) \
65 (intel_device_info_is_mtl(devinfo) || intel_device_info_is_arl(devinfo))
66
67 #define PAT_ENTRY(index_, mmap_, coh_) \
68 { \
69 .index = index_, \
70 .mmap = INTEL_DEVICE_INFO_MMAP_MODE_##mmap_, \
71 .coherency = INTEL_DEVICE_INFO_COHERENCY_MODE_##coh_ \
72 }
73
74 #ifdef GFX_VER
75
76 #define intel_device_info_is_9lp(devinfo) \
77 (GFX_VER == 9 && ((devinfo)->platform == INTEL_PLATFORM_BXT || \
78 (devinfo)->platform == INTEL_PLATFORM_GLK))
79
80 #else
81
82 #define intel_device_info_is_9lp(devinfo) \
83 ((devinfo)->platform == INTEL_PLATFORM_BXT || \
84 (devinfo)->platform == INTEL_PLATFORM_GLK)
85
86 #endif
87
88 static inline bool
intel_device_info_slice_available(const struct intel_device_info * devinfo,int slice)89 intel_device_info_slice_available(const struct intel_device_info *devinfo,
90 int slice)
91 {
92 assert(slice < INTEL_DEVICE_MAX_SLICES);
93 return (devinfo->slice_masks & (1U << slice)) != 0;
94 }
95
96 static inline bool
intel_device_info_subslice_available(const struct intel_device_info * devinfo,int slice,int subslice)97 intel_device_info_subslice_available(const struct intel_device_info *devinfo,
98 int slice, int subslice)
99 {
100 return (devinfo->subslice_masks[slice * devinfo->subslice_slice_stride +
101 subslice / 8] & (1U << (subslice % 8))) != 0;
102 }
103
104 static inline bool
intel_device_info_eu_available(const struct intel_device_info * devinfo,int slice,int subslice,int eu)105 intel_device_info_eu_available(const struct intel_device_info *devinfo,
106 int slice, int subslice, int eu)
107 {
108 unsigned subslice_offset = slice * devinfo->eu_slice_stride +
109 subslice * devinfo->eu_subslice_stride;
110
111 return (devinfo->eu_masks[subslice_offset + eu / 8] & (1U << eu % 8)) != 0;
112 }
113
114 static inline uint32_t
intel_device_info_subslice_total(const struct intel_device_info * devinfo)115 intel_device_info_subslice_total(const struct intel_device_info *devinfo)
116 {
117 uint32_t total = 0;
118
119 for (size_t i = 0; i < ARRAY_SIZE(devinfo->subslice_masks); i++) {
120 total += __builtin_popcount(devinfo->subslice_masks[i]);
121 }
122
123 return total;
124 }
125
126 static inline uint32_t
intel_device_info_eu_total(const struct intel_device_info * devinfo)127 intel_device_info_eu_total(const struct intel_device_info *devinfo)
128 {
129 uint32_t total = 0;
130
131 for (size_t i = 0; i < ARRAY_SIZE(devinfo->eu_masks); i++)
132 total += __builtin_popcount(devinfo->eu_masks[i]);
133
134 return total;
135 }
136
137 /**
138 * Computes the bound of dualsubslice ID that can be used on this device.
139 *
140 * You should use this number if you're going to make calculation based on the
141 * slice/dualsubslice ID provided by the SR0.0 EU register. The maximum
142 * dualsubslice ID can be superior to the total number of dualsubslices on the
143 * device, depending on fusing.
144 *
145 * On a 16 dualsubslice GPU, the maximum dualsubslice ID is 15. This function
146 * would return the exclusive bound : 16.
147 */
148 static inline unsigned
intel_device_info_dual_subslice_id_bound(const struct intel_device_info * devinfo)149 intel_device_info_dual_subslice_id_bound(const struct intel_device_info *devinfo)
150 {
151 /* Start from the last slice/subslice so we find the answer faster. */
152 for (int s = devinfo->max_slices - 1; s >= 0; s--) {
153 for (int ss = devinfo->max_subslices_per_slice - 1; ss >= 0; ss--) {
154 if (intel_device_info_subslice_available(devinfo, s, ss))
155 return s * devinfo->max_subslices_per_slice + ss + 1;
156 }
157 }
158 unreachable("Invalid topology");
159 return 0;
160 }
161
162 int intel_device_name_to_pci_device_id(const char *name);
163
164 static inline uint64_t
intel_device_info_timebase_scale(const struct intel_device_info * devinfo,uint64_t gpu_timestamp)165 intel_device_info_timebase_scale(const struct intel_device_info *devinfo,
166 uint64_t gpu_timestamp)
167 {
168 /* Try to avoid going over the 64bits when doing the scaling */
169 uint64_t upper_ts = gpu_timestamp >> 32;
170 uint64_t lower_ts = gpu_timestamp & 0xffffffff;
171 uint64_t upper_scaled_ts = upper_ts * 1000000000ull / devinfo->timestamp_frequency;
172 uint64_t lower_scaled_ts = lower_ts * 1000000000ull / devinfo->timestamp_frequency;
173 return (upper_scaled_ts << 32) + lower_scaled_ts;
174 }
175
176 static inline bool
intel_vram_all_mappable(const struct intel_device_info * devinfo)177 intel_vram_all_mappable(const struct intel_device_info *devinfo)
178 {
179 return devinfo->mem.vram.unmappable.size == 0;
180 }
181
182 bool intel_get_device_info_from_fd(int fh, struct intel_device_info *devinfo, int min_ver, int max_ver);
183 bool intel_get_device_info_from_pci_id(int pci_id,
184 struct intel_device_info *devinfo);
185
186 /* Only updates intel_device_info::regions::...::free fields. The
187 * class/instance/size should remain the same over time.
188 */
189 bool intel_device_info_update_memory_info(struct intel_device_info *devinfo,
190 int fd);
191
192 void intel_device_info_topology_reset_masks(struct intel_device_info *devinfo);
193 void intel_device_info_topology_update_counts(struct intel_device_info *devinfo);
194 void intel_device_info_update_pixel_pipes(struct intel_device_info *devinfo, uint8_t *subslice_masks);
195 void intel_device_info_update_l3_banks(struct intel_device_info *devinfo);
196 void intel_device_info_update_cs_workgroup_threads(struct intel_device_info *devinfo);
197 bool intel_device_info_compute_system_memory(struct intel_device_info *devinfo, bool update);
198 void intel_device_info_update_after_hwconfig(struct intel_device_info *devinfo);
199
200 #ifdef GFX_VERx10
201 #define intel_needs_workaround(devinfo, id) \
202 (INTEL_WA_ ## id ## _GFX_VER && \
203 BITSET_TEST(devinfo->workarounds, INTEL_WA_##id))
204 #else
205 #define intel_needs_workaround(devinfo, id) \
206 BITSET_TEST(devinfo->workarounds, INTEL_WA_##id)
207 #endif
208
209 enum intel_wa_steppings intel_device_info_wa_stepping(struct intel_device_info *devinfo);
210
211 #ifdef __cplusplus
212 }
213 #endif
214
215 #endif /* INTEL_DEVICE_INFO_H */
216