1/*
2 * Copyright © 2022 Imagination Technologies Ltd.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * 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 THE
18 * 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
24#ifndef PVR_DEVICE_INFO_H
25#define PVR_DEVICE_INFO_H
26
27/* TODO: This file is currently hand-maintained. However, the intention is to
28 * auto-generate it in the future based on the hwdefs.
29 */
30
31#include <assert.h>
32#include <errno.h>
33#include <stdbool.h>
34#include <stdint.h>
35
36#include "util/log.h"
37#include "util/macros.h"
38
39#define PVR_BVNC_PACK_SHIFT_B 48
40#define PVR_BVNC_PACK_SHIFT_V 32
41#define PVR_BVNC_PACK_SHIFT_N 16
42#define PVR_BVNC_PACK_SHIFT_C 0
43
44#define PVR_BVNC_PACK_MASK_B UINT64_C(0xFFFF000000000000)
45#define PVR_BVNC_PACK_MASK_V UINT64_C(0x0000FFFF00000000)
46#define PVR_BVNC_PACK_MASK_N UINT64_C(0x00000000FFFF0000)
47#define PVR_BVNC_PACK_MASK_C UINT64_C(0x000000000000FFFF)
48
49/**
50 * Packs B, V, N and C values into a 64-bit unsigned integer.
51 *
52 * The packed layout is as follows:
53 *
54 * \verbatim
55 *    +--------+--------+--------+-------+
56 *    | 63..48 | 47..32 | 31..16 | 15..0 |
57 *    +========+========+========+=======+
58 *    | B      | V      | N      | C     |
59 *    +--------+--------+--------+-------+
60 * \endverbatim
61 *
62 * #pvr_get_packed_bvnc() should be used instead of this macro when a
63 * #pvr_device_information is available in order to ensure proper type checking.
64 *
65 * \param b Branch ID.
66 * \param v Version ID.
67 * \param n Number of scalable units.
68 * \param c Config ID.
69 * \return Packed BVNC.
70 *
71 * \sa #pvr_get_packed_bvnc(), #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_V(),
72 * #PVR_BVNC_UNPACK_N() and #PVR_BVNC_UNPACK_C()
73 */
74#define PVR_BVNC_PACK(b, v, n, c)                                       \
75   ((((uint64_t)(b) << PVR_BVNC_PACK_SHIFT_B) & PVR_BVNC_PACK_MASK_B) | \
76    (((uint64_t)(v) << PVR_BVNC_PACK_SHIFT_V) & PVR_BVNC_PACK_MASK_V) | \
77    (((uint64_t)(n) << PVR_BVNC_PACK_SHIFT_N) & PVR_BVNC_PACK_MASK_N) | \
78    (((uint64_t)(c) << PVR_BVNC_PACK_SHIFT_C) & PVR_BVNC_PACK_MASK_C))
79
80/**
81 * Unpacks B value (branch ID) from packed BVNC.
82 *
83 * \param bvnc Packed BVNC.
84 * \return Branch ID.
85 *
86 * \sa #PVR_BVNC_UNPACK_V(), #PVR_BVNC_UNPACK_N(), #PVR_BVNC_UNPACK_C(),
87 * #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
88 */
89#define PVR_BVNC_UNPACK_B(bvnc) \
90   ((uint16_t)(((bvnc)&PVR_BVNC_PACK_MASK_B) >> PVR_BVNC_PACK_SHIFT_B))
91
92/**
93 * Unpacks V value (version ID) from packed BVNC.
94 *
95 * \param bvnc Packed BVNC.
96 * \return Version ID.
97 *
98 * \sa #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_N(), #PVR_BVNC_UNPACK_C(),
99 * #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
100 */
101#define PVR_BVNC_UNPACK_V(bvnc) \
102   ((uint16_t)(((bvnc)&PVR_BVNC_PACK_MASK_V) >> PVR_BVNC_PACK_SHIFT_V))
103
104/**
105 * Unpacks N value (number of scalable units) from packed BVNC.
106 *
107 * \param bvnc Packed BVNC.
108 * \return Number of scalable units.
109 *
110 * \sa #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_V(), #PVR_BVNC_UNPACK_C(),
111 * #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
112 */
113#define PVR_BVNC_UNPACK_N(bvnc) \
114   ((uint16_t)(((bvnc)&PVR_BVNC_PACK_MASK_N) >> PVR_BVNC_PACK_SHIFT_N))
115
116/**
117 * Unpacks C value (config ID) from packed BVNC.
118 *
119 * \param bvnc Packed BVNC.
120 * \return Config ID.
121 *
122 * \sa #PVR_BVNC_UNPACK_B(), #PVR_BVNC_UNPACK_V(), #PVR_BVNC_UNPACK_N(),
123 * #pvr_get_packed_bvnc() and #PVR_BVNC_PACK()
124 */
125#define PVR_BVNC_UNPACK_C(bvnc) \
126   ((uint16_t)(((bvnc)&PVR_BVNC_PACK_MASK_C) >> PVR_BVNC_PACK_SHIFT_C))
127
128/**
129 * Tests whether a physical device has a given feature.
130 *
131 * Feature names are derived from those found in #pvr_device_features by
132 * dropping the 'has_' prefix, which is applied by this macro.
133 *
134 * \param dev_info #pvr_device_info object associated with the target physical
135 *                 device.
136 * \param feature  Device feature name.
137 *
138 * \return
139 *  * true if the named feature is present in the hardware.
140 *  * false if the named feature is not present in the hardware.
141 *
142 * \sa #PVR_FEATURE_VALUE() and #PVR_GET_FEATURE_VALUE()
143 */
144#define PVR_HAS_FEATURE(dev_info, feature) ((dev_info)->features.has_##feature)
145
146/**
147 * Gets a physical device feature value if feature is supported.
148 *
149 * Feature names are derived from those found in #pvr_device_features by
150 * dropping the 'has_' prefix.
151 *
152 * This macro should be used in preference to #PVR_GET_FEATURE_VALUE() as it has
153 * proper error handling.
154 *
155 * \param dev_info  #pvr_device_info object associated with the target physical
156 *                  device.
157 * \param feature   Feature name.
158 * \param value_out Feature value.
159 *
160 * \return
161 *  * 0 on success, or
162 *  * -%EINVAL if the named feature is not present in the hardware.
163 *
164 * \sa #PVR_HAS_FEATURE() and #PVR_GET_FEATURE_VALUE()
165 */
166#define PVR_FEATURE_VALUE(dev_info, feature, value_out)    \
167   ({                                                      \
168      const struct pvr_device_info *__dev_info = dev_info; \
169      int __ret = -EINVAL;                                 \
170      if (__dev_info->features.has_##feature) {            \
171         *(value_out) = __dev_info->features.feature;      \
172         __ret = 0;                                        \
173      }                                                    \
174      __ret;                                               \
175   })
176
177/**
178 * Gets a physical device feature value if supported, but otherwise returns a
179 * default value.
180 *
181 * Feature names are derived from those found in #pvr_device_features by
182 * dropping the 'has_' prefix.
183 *
184 * #PVR_FEATURE_VALUE() should be used in preference to this macro when errors
185 * can be returned by the caller. This macro is intended for cases where errors
186 * can't be returned.
187 *
188 * \param dev_info      #pvr_device_info object associated with the target
189 *                      physical device.
190 * \param feature       Feature name.
191 * \param default_value Default feature value.
192 *
193 * \return Feature value.
194 *
195 * \sa #PVR_HAS_FEATURE() and #PVR_FEATURE_VALUE()
196 */
197#define PVR_GET_FEATURE_VALUE(dev_info, feature, default_value)     \
198   ({                                                               \
199      const struct pvr_device_info *__dev_info = dev_info;          \
200      __typeof__(default_value) __ret = default_value;              \
201      if (__dev_info->features.has_##feature) {                     \
202         __ret = __dev_info->features.feature;                      \
203      } else {                                                      \
204         mesa_logw("Missing " #feature                              \
205                   " feature (defaulting to: " #default_value ")"); \
206         assert(0);                                                 \
207      }                                                             \
208      __ret;                                                        \
209   })
210
211/**
212 * Tests whether a physical device has a given enhancement.
213 *
214 * Enhancement numbers are derived from those found in #pvr_device_enhancements
215 * by dropping the 'has_ern' prefix, which is applied by this macro.
216 *
217 * \param dev_info #pvr_device_info object associated with the target physical
218 *                 device.
219 * \param number   Enhancement number.
220 *
221 * \return
222 *  * true if the enhancement is present in the hardware.
223 *  * false if the enhancement is not present in the hardware.
224 */
225#define PVR_HAS_ERN(dev_info, number) ((dev_info)->enhancements.has_ern##number)
226
227/**
228 * Tests whether a physical device has a given quirk.
229 *
230 * Quirk numbers are derived from those found in #pvr_device_quirks by
231 * dropping the 'has_brn' prefix, which is applied by this macro.
232 *
233 * \param dev_info #pvr_device_info object associated with the target physical
234 *                 device.
235 * \param number   Quirk number.
236 *
237 * \return
238 *  * true if the quirk is present in the hardware.
239 *  * false if the quirk is not present in the hardware.
240 */
241#define PVR_HAS_QUIRK(dev_info, number) ((dev_info)->quirks.has_brn##number)
242
243struct pvr_device_ident {
244   uint16_t b, v, n, c;
245   uint32_t device_id;
246   const char *series_name;
247   const char *public_name;
248};
249
250struct pvr_device_features {
251   bool has_astc : 1;
252   bool has_cluster_grouping : 1;
253   bool has_common_store_size_in_dwords : 1;
254   bool has_compute : 1;
255   bool has_compute_morton_capable : 1;
256   bool has_compute_overlap : 1;
257   bool has_eight_output_registers : 1;
258   bool has_gpu_multicore_support : 1;
259   bool has_gs_rta_support : 1;
260   bool has_isp_max_tiles_in_flight : 1;
261   bool has_isp_samples_per_pixel : 1;
262   bool has_max_instances_per_pds_task : 1;
263   bool has_max_multisample : 1;
264   bool has_max_partitions : 1;
265   bool has_max_usc_tasks : 1;
266   bool has_num_clusters : 1;
267   bool has_num_raster_pipes : 1;
268   bool has_num_user_clip_planes : 1;
269   bool has_paired_tiles : 1;
270   bool has_pds_ddmadt : 1;
271   bool has_robust_buffer_access : 1;
272   bool has_roguexe : 1;
273   bool has_screen_size8K : 1;
274   bool has_simple_internal_parameter_format : 1;
275   bool has_simple_internal_parameter_format_v2 : 1;
276   bool has_simple_parameter_format_version : 1;
277   bool has_slc_cache_line_size_bits : 1;
278   bool has_slc_mcu_cache_controls : 1;
279   bool has_tf_bicubic_filter : 1;
280   bool has_tile_size_16x16 : 1;
281   bool has_tile_size_x : 1;
282   bool has_tile_size_y : 1;
283   bool has_tpu_array_textures : 1;
284   bool has_tpu_extended_integer_lookup : 1;
285   bool has_tpu_image_state_v2 : 1;
286   bool has_usc_f16sop_u8 : 1;
287   bool has_usc_min_output_registers_per_pix : 1;
288   bool has_usc_pixel_partition_mask : 1;
289   bool has_usc_slots : 1;
290   bool has_uvs_banks : 1;
291   bool has_uvs_pba_entries : 1;
292   bool has_uvs_vtx_entries : 1;
293   bool has_vdm_cam_size : 1;
294   bool has_vdm_degenerate_culling : 1;
295   bool has_xpu_max_slaves : 1;
296   bool has_xt_top_infrastructure : 1;
297   bool has_zls_subtile : 1;
298
299   uint32_t common_store_size_in_dwords;
300   uint32_t isp_max_tiles_in_flight;
301   uint32_t isp_samples_per_pixel;
302   uint32_t max_instances_per_pds_task;
303   uint32_t max_multisample;
304   uint32_t max_partitions;
305   uint32_t max_usc_tasks;
306   uint32_t num_clusters;
307   uint32_t num_raster_pipes;
308   uint32_t num_user_clip_planes;
309   uint32_t simple_parameter_format_version;
310   uint32_t slc_cache_line_size_bits;
311   uint32_t tile_size_x;
312   uint32_t tile_size_y;
313   uint32_t usc_min_output_registers_per_pix;
314   uint32_t usc_slots;
315   uint32_t uvs_banks;
316   uint32_t uvs_pba_entries;
317   uint32_t uvs_vtx_entries;
318   uint32_t vdm_cam_size;
319   uint32_t xpu_max_slaves;
320
321   /* Derived features. */
322   bool has_s8xe : 1;
323};
324
325struct pvr_device_enhancements {
326   bool has_ern35421 : 1;
327   bool has_ern38020 : 1;
328   bool has_ern38748 : 1;
329   bool has_ern42307 : 1;
330   bool has_ern45493 : 1;
331};
332
333struct pvr_device_quirks {
334   bool has_brn44079 : 1;
335   bool has_brn47727 : 1;
336   bool has_brn48492 : 1;
337   bool has_brn48545 : 1;
338   bool has_brn49032 : 1;
339   bool has_brn49927 : 1;
340   bool has_brn51025 : 1;
341   bool has_brn51210 : 1;
342   bool has_brn51764 : 1;
343   bool has_brn52354 : 1;
344   bool has_brn52942 : 1;
345   bool has_brn56279 : 1;
346   bool has_brn58839 : 1;
347   bool has_brn62269 : 1;
348   bool has_brn66011 : 1;
349   bool has_brn70165 : 1;
350};
351
352struct pvr_device_info {
353   struct pvr_device_ident ident;
354   struct pvr_device_features features;
355   struct pvr_device_enhancements enhancements;
356   struct pvr_device_quirks quirks;
357};
358
359struct pvr_device_runtime_info {
360   uint64_t min_free_list_size;
361   uint64_t reserved_shared_size;
362   uint64_t total_reserved_partition_size;
363   uint64_t num_phantoms;
364   uint64_t max_coeffs;
365   uint64_t cdm_max_local_mem_size_regs;
366   uint32_t core_count;
367};
368
369/**
370 * Packs B, V, N and C values into a 64-bit unsigned integer.
371 *
372 * The packed layout is as follows:
373 *
374 * \verbatim
375 *    +--------+--------+--------+-------+
376 *    | 63..48 | 47..32 | 31..16 | 15..0 |
377 *    +========+========+========+=======+
378 *    | B      | V      | N      | C     |
379 *    +--------+--------+--------+-------+
380 * \endverbatim
381 *
382 * This should be used in preference to #PVR_BVNC_PACK() when a
383 * #pvr_device_info is available in order to ensure proper type checking.
384 *
385 * \param dev_info Device information.
386 * \return Packed BVNC.
387 */
388static ALWAYS_INLINE uint64_t
389pvr_get_packed_bvnc(const struct pvr_device_info *dev_info)
390{
391   return PVR_BVNC_PACK(dev_info->ident.b,
392                        dev_info->ident.v,
393                        dev_info->ident.n,
394                        dev_info->ident.c);
395}
396
397int pvr_device_info_init(struct pvr_device_info *info, uint64_t bvnc);
398
399#endif /* PVR_DEVICE_INFO_H */
400