1 /*
2 * Copyright (C) 2015 Etnaviv Project
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 FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 * Authors:
24 * Christian Gmeiner <[email protected]>
25 */
26
27 #include "etnaviv_priv.h"
28 #include "etnaviv_drmif.h"
29
30 #include "hwdb/etna_hwdb.h"
31
32 #include "hw/common.xml.h"
33
34 /* Enum with indices for each of the feature words */
35 enum viv_features_word {
36 viv_chipFeatures = 0,
37 viv_chipMinorFeatures0 = 1,
38 viv_chipMinorFeatures1 = 2,
39 viv_chipMinorFeatures2 = 3,
40 viv_chipMinorFeatures3 = 4,
41 viv_chipMinorFeatures4 = 5,
42 viv_chipMinorFeatures5 = 6,
43 viv_chipMinorFeatures6 = 7,
44 viv_chipMinorFeatures7 = 8,
45 viv_chipMinorFeatures8 = 9,
46 viv_chipMinorFeatures9 = 10,
47 viv_chipMinorFeatures10 = 11,
48 viv_chipMinorFeatures11 = 12,
49 viv_chipMinorFeatures12 = 13,
50 VIV_FEATURES_WORD_COUNT /* Must be last */
51 };
52
53 #define VIV_FEATURE(word, feature) \
54 ((features[viv_ ## word] & (word ## _ ## feature)) != 0)
55
56 #define ETNA_FEATURE(word, feature) \
57 if (VIV_FEATURE(word, feature)) \
58 etna_core_enable_feature(&gpu->info, ETNA_FEATURE_## feature)
59
60 static void
query_features_from_kernel(struct etna_gpu * gpu)61 query_features_from_kernel(struct etna_gpu *gpu)
62 {
63 uint32_t features[VIV_FEATURES_WORD_COUNT];
64
65 STATIC_ASSERT(ETNA_GPU_FEATURES_0 == 0x3);
66 STATIC_ASSERT(ETNA_GPU_FEATURES_1 == 0x4);
67 STATIC_ASSERT(ETNA_GPU_FEATURES_2 == 0x5);
68 STATIC_ASSERT(ETNA_GPU_FEATURES_3 == 0x6);
69 STATIC_ASSERT(ETNA_GPU_FEATURES_4 == 0x7);
70 STATIC_ASSERT(ETNA_GPU_FEATURES_5 == 0x8);
71 STATIC_ASSERT(ETNA_GPU_FEATURES_6 == 0x9);
72 STATIC_ASSERT(ETNA_GPU_FEATURES_7 == 0xa);
73 STATIC_ASSERT(ETNA_GPU_FEATURES_8 == 0xb);
74 STATIC_ASSERT(ETNA_GPU_FEATURES_9 == 0xc);
75 STATIC_ASSERT(ETNA_GPU_FEATURES_10 == 0xd);
76 STATIC_ASSERT(ETNA_GPU_FEATURES_11 == 0xe);
77 STATIC_ASSERT(ETNA_GPU_FEATURES_12 == 0xf);
78
79 for (unsigned i = ETNA_GPU_FEATURES_0; i <= ETNA_GPU_FEATURES_12; i++) {
80 uint64_t val;
81
82 etna_gpu_get_param(gpu, i, &val);
83 features[i - ETNA_GPU_FEATURES_0] = val;
84 }
85
86 gpu->info.type = ETNA_CORE_GPU;
87
88 ETNA_FEATURE(chipFeatures, FAST_CLEAR);
89 ETNA_FEATURE(chipFeatures, PIPE_3D);
90 ETNA_FEATURE(chipFeatures, 32_BIT_INDICES);
91 ETNA_FEATURE(chipFeatures, MSAA);
92 ETNA_FEATURE(chipFeatures, DXT_TEXTURE_COMPRESSION);
93 ETNA_FEATURE(chipFeatures, ETC1_TEXTURE_COMPRESSION);
94 ETNA_FEATURE(chipFeatures, NO_EARLY_Z);
95
96 ETNA_FEATURE(chipMinorFeatures0, MC20);
97 ETNA_FEATURE(chipMinorFeatures0, RENDERTARGET_8K);
98 ETNA_FEATURE(chipMinorFeatures0, TEXTURE_8K);
99 ETNA_FEATURE(chipMinorFeatures0, HAS_SIGN_FLOOR_CEIL);
100 ETNA_FEATURE(chipMinorFeatures0, HAS_SQRT_TRIG);
101 ETNA_FEATURE(chipMinorFeatures0, 2BITPERTILE);
102 ETNA_FEATURE(chipMinorFeatures0, SUPER_TILED);
103
104 ETNA_FEATURE(chipMinorFeatures1, AUTO_DISABLE);
105 ETNA_FEATURE(chipMinorFeatures1, TEXTURE_HALIGN);
106 ETNA_FEATURE(chipMinorFeatures1, MMU_VERSION);
107 ETNA_FEATURE(chipMinorFeatures1, HALF_FLOAT);
108 ETNA_FEATURE(chipMinorFeatures1, WIDE_LINE);
109 ETNA_FEATURE(chipMinorFeatures1, HALTI0);
110 ETNA_FEATURE(chipMinorFeatures1, NON_POWER_OF_TWO);
111 ETNA_FEATURE(chipMinorFeatures1, LINEAR_TEXTURE_SUPPORT);
112
113 ETNA_FEATURE(chipMinorFeatures2, LINEAR_PE);
114 ETNA_FEATURE(chipMinorFeatures2, SUPERTILED_TEXTURE);
115 ETNA_FEATURE(chipMinorFeatures2, LOGIC_OP);
116 ETNA_FEATURE(chipMinorFeatures2, HALTI1);
117 ETNA_FEATURE(chipMinorFeatures2, SEAMLESS_CUBE_MAP);
118 ETNA_FEATURE(chipMinorFeatures2, LINE_LOOP);
119 ETNA_FEATURE(chipMinorFeatures2, TEXTURE_TILED_READ);
120 ETNA_FEATURE(chipMinorFeatures2, BUG_FIXES8);
121
122 ETNA_FEATURE(chipMinorFeatures3, PE_DITHER_FIX);
123 ETNA_FEATURE(chipMinorFeatures3, INSTRUCTION_CACHE);
124 ETNA_FEATURE(chipMinorFeatures3, HAS_FAST_TRANSCENDENTALS);
125
126 ETNA_FEATURE(chipMinorFeatures4, SMALL_MSAA);
127 ETNA_FEATURE(chipMinorFeatures4, BUG_FIXES18);
128 ETNA_FEATURE(chipMinorFeatures4, TEXTURE_ASTC);
129 ETNA_FEATURE(chipMinorFeatures4, SINGLE_BUFFER);
130 ETNA_FEATURE(chipMinorFeatures4, HALTI2);
131
132 ETNA_FEATURE(chipMinorFeatures5, BLT_ENGINE);
133 ETNA_FEATURE(chipMinorFeatures5, HALTI3);
134 ETNA_FEATURE(chipMinorFeatures5, HALTI4);
135 ETNA_FEATURE(chipMinorFeatures5, HALTI5);
136 ETNA_FEATURE(chipMinorFeatures5, RA_WRITE_DEPTH);
137
138 ETNA_FEATURE(chipMinorFeatures6, CACHE128B256BPERLINE);
139 ETNA_FEATURE(chipMinorFeatures6, NEW_GPIPE);
140 ETNA_FEATURE(chipMinorFeatures6, NO_ASTC);
141 ETNA_FEATURE(chipMinorFeatures6, V4_COMPRESSION);
142
143 ETNA_FEATURE(chipMinorFeatures7, RS_NEW_BASEADDR);
144 ETNA_FEATURE(chipMinorFeatures7, PE_NO_ALPHA_TEST);
145
146 ETNA_FEATURE(chipMinorFeatures8, SH_NO_ONECONST_LIMIT);
147
148 ETNA_FEATURE(chipMinorFeatures10, DEC400);
149 }
150
151 static void
query_limits_from_kernel(struct etna_gpu * gpu)152 query_limits_from_kernel(struct etna_gpu *gpu)
153 {
154 struct etna_core_info *info = &gpu->info;
155 uint64_t val;
156
157 assert(info->type == ETNA_CORE_GPU);
158
159 etna_gpu_get_param(gpu, ETNA_GPU_INSTRUCTION_COUNT, &val);
160 info->gpu.max_instructions = val;
161
162 etna_gpu_get_param(gpu, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE, &val);
163 info->gpu.vertex_output_buffer_size = val;
164
165 etna_gpu_get_param(gpu, ETNA_GPU_VERTEX_CACHE_SIZE, &val);
166 info->gpu.vertex_cache_size = val;
167
168 etna_gpu_get_param(gpu, ETNA_GPU_SHADER_CORE_COUNT, &val);
169 info->gpu.shader_core_count = val;
170
171 etna_gpu_get_param(gpu, ETNA_GPU_STREAM_COUNT, &val);
172 info->gpu.stream_count = val;
173
174 etna_gpu_get_param(gpu, ETNA_GPU_REGISTER_MAX, &val);
175 info->gpu.max_registers = val;
176
177 etna_gpu_get_param(gpu, ETNA_GPU_PIXEL_PIPES, &val);
178 info->gpu.pixel_pipes = val;
179
180 etna_gpu_get_param(gpu, ETNA_GPU_NUM_CONSTANTS, &val);
181 info->gpu.num_constants = val;
182
183 etna_gpu_get_param(gpu, ETNA_GPU_NUM_VARYINGS, &val);
184 info->gpu.max_varyings = val;
185 }
186
get_param(struct etna_device * dev,uint32_t core,uint32_t param)187 static uint64_t get_param(struct etna_device *dev, uint32_t core, uint32_t param)
188 {
189 struct drm_etnaviv_param req = {
190 .pipe = core,
191 .param = param,
192 };
193 int ret;
194
195 ret = drmCommandWriteRead(dev->fd, DRM_ETNAVIV_GET_PARAM, &req, sizeof(req));
196 if (ret) {
197 if (ret != -ENXIO)
198 ERROR_MSG("get-param (%x) failed! %d (%s)", param, ret,
199 strerror(errno));
200 return 0;
201 }
202
203 return req.value;
204 }
205
determine_halti(struct etna_gpu * gpu)206 static void determine_halti(struct etna_gpu *gpu)
207 {
208 struct etna_core_info *info = &gpu->info;
209
210 /* Figure out gross GPU architecture. See rnndb/common.xml for a specific
211 * description of the differences. */
212 if (etna_core_has_feature(info, ETNA_FEATURE_HALTI5))
213 info->halti = 5; /* New GC7000/GC8x00 */
214 else if (etna_core_has_feature(info, ETNA_FEATURE_HALTI4))
215 info->halti = 4; /* Old GC7000/GC7400 */
216 else if (etna_core_has_feature(info, ETNA_FEATURE_HALTI3))
217 info->halti = 3; /* None? */
218 else if (etna_core_has_feature(info, ETNA_FEATURE_HALTI2))
219 info->halti = 2; /* GC2500/GC3000/GC5000/GC6400 */
220 else if (etna_core_has_feature(info, ETNA_FEATURE_HALTI1))
221 info->halti = 1; /* GC900/GC4000/GC7000UL */
222 else if (etna_core_has_feature(info, ETNA_FEATURE_HALTI0))
223 info->halti = 0; /* GC880/GC2000/GC7000TM */
224 else
225 info->halti = -1; /* GC7000nanolite / pre-GC2000 except GC880 */
226 }
227
etna_gpu_new(struct etna_device * dev,unsigned int core)228 struct etna_gpu *etna_gpu_new(struct etna_device *dev, unsigned int core)
229 {
230 struct etna_gpu *gpu;
231 bool core_info_okay = false;
232
233 gpu = calloc(1, sizeof(*gpu));
234 if (!gpu) {
235 ERROR_MSG("allocation failed");
236 goto fail;
237 }
238
239 gpu->dev = dev;
240 gpu->core = core;
241
242 gpu->info.model = get_param(dev, core, ETNAVIV_PARAM_GPU_MODEL);
243 if (!gpu->info.model)
244 goto fail;
245
246 gpu->info.revision = get_param(dev, core, ETNAVIV_PARAM_GPU_REVISION);
247
248 DEBUG_MSG(" GPU model: 0x%x (rev %x)", gpu->info.model, gpu->info.revision);
249
250 if (dev->drm_version >= ETNA_DRM_VERSION(1, 4)) {
251 gpu->info.product_id = get_param(dev, core, ETNAVIV_PARAM_GPU_PRODUCT_ID);
252 gpu->info.customer_id = get_param(dev, core, ETNAVIV_PARAM_GPU_CUSTOMER_ID);
253 gpu->info.eco_id = get_param(dev, core, ETNAVIV_PARAM_GPU_ECO_ID);
254
255 core_info_okay = etna_query_feature_db(&gpu->info);
256 DEBUG_MSG(" Found entry in hwdb: %u\n", core_info_okay);
257 }
258
259 if (!core_info_okay) {
260 query_features_from_kernel(gpu);
261 query_limits_from_kernel(gpu);
262 }
263
264 determine_halti(gpu);
265
266 return gpu;
267 fail:
268 if (gpu)
269 etna_gpu_del(gpu);
270
271 return NULL;
272 }
273
etna_gpu_del(struct etna_gpu * gpu)274 void etna_gpu_del(struct etna_gpu *gpu)
275 {
276 free(gpu);
277 }
278
etna_gpu_get_param(struct etna_gpu * gpu,enum etna_param_id param,uint64_t * value)279 int etna_gpu_get_param(struct etna_gpu *gpu, enum etna_param_id param,
280 uint64_t *value)
281 {
282 struct etna_device *dev = gpu->dev;
283 unsigned int core = gpu->core;
284
285 switch(param) {
286 case ETNA_GPU_MODEL:
287 *value = gpu->info.model;
288 return 0;
289 case ETNA_GPU_REVISION:
290 *value = gpu->info.revision;
291 return 0;
292 case ETNA_GPU_FEATURES_0:
293 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_0);
294 return 0;
295 case ETNA_GPU_FEATURES_1:
296 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_1);
297 return 0;
298 case ETNA_GPU_FEATURES_2:
299 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_2);
300 return 0;
301 case ETNA_GPU_FEATURES_3:
302 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_3);
303 return 0;
304 case ETNA_GPU_FEATURES_4:
305 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_4);
306 return 0;
307 case ETNA_GPU_FEATURES_5:
308 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_5);
309 return 0;
310 case ETNA_GPU_FEATURES_6:
311 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_6);
312 return 0;
313 case ETNA_GPU_FEATURES_7:
314 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_7);
315 return 0;
316 case ETNA_GPU_FEATURES_8:
317 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_8);
318 return 0;
319 case ETNA_GPU_FEATURES_9:
320 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_9);
321 return 0;
322 case ETNA_GPU_FEATURES_10:
323 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_10);
324 return 0;
325 case ETNA_GPU_FEATURES_11:
326 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_11);
327 return 0;
328 case ETNA_GPU_FEATURES_12:
329 *value = get_param(dev, core, ETNAVIV_PARAM_GPU_FEATURES_12);
330 return 0;
331 case ETNA_GPU_STREAM_COUNT:
332 *value = get_param(dev, core, ETNA_GPU_STREAM_COUNT);
333 return 0;
334 case ETNA_GPU_REGISTER_MAX:
335 *value = get_param(dev, core, ETNA_GPU_REGISTER_MAX);
336 return 0;
337 case ETNA_GPU_THREAD_COUNT:
338 *value = get_param(dev, core, ETNA_GPU_THREAD_COUNT);
339 return 0;
340 case ETNA_GPU_VERTEX_CACHE_SIZE:
341 *value = get_param(dev, core, ETNA_GPU_VERTEX_CACHE_SIZE);
342 return 0;
343 case ETNA_GPU_SHADER_CORE_COUNT:
344 *value = get_param(dev, core, ETNA_GPU_SHADER_CORE_COUNT);
345 return 0;
346 case ETNA_GPU_PIXEL_PIPES:
347 *value = get_param(dev, core, ETNA_GPU_PIXEL_PIPES);
348 return 0;
349 case ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE:
350 *value = get_param(dev, core, ETNA_GPU_VERTEX_OUTPUT_BUFFER_SIZE);
351 return 0;
352 case ETNA_GPU_BUFFER_SIZE:
353 *value = get_param(dev, core, ETNA_GPU_BUFFER_SIZE);
354 return 0;
355 case ETNA_GPU_INSTRUCTION_COUNT:
356 *value = get_param(dev, core, ETNA_GPU_INSTRUCTION_COUNT);
357 return 0;
358 case ETNA_GPU_NUM_CONSTANTS:
359 *value = get_param(dev, core, ETNA_GPU_NUM_CONSTANTS);
360 return 0;
361 case ETNA_GPU_NUM_VARYINGS:
362 *value = get_param(dev, core, ETNA_GPU_NUM_VARYINGS);
363 return 0;
364 case ETNA_SOFTPIN_START_ADDR:
365 *value = get_param(dev, core, ETNA_SOFTPIN_START_ADDR);
366 return 0;
367 case ETNA_GPU_PRODUCT_ID:
368 *value = gpu->info.product_id;
369 return 0;
370 case ETNA_GPU_CUSTOMER_ID:
371 *value = gpu->info.customer_id;
372 return 0;
373 case ETNA_GPU_ECO_ID:
374 *value = gpu->info.eco_id;
375 return 0;
376
377 default:
378 ERROR_MSG("invalid param id: %d", param);
379 return -1;
380 }
381
382 return 0;
383 }
384
etna_gpu_get_core_info(struct etna_gpu * gpu)385 struct etna_core_info *etna_gpu_get_core_info(struct etna_gpu *gpu)
386 {
387 return &gpu->info;
388 }
389