xref: /aosp_15_r20/external/mesa3d/src/etnaviv/drm/etnaviv_gpu.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
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