1/*
2 * Copyright © 2020 Valve 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 FREEDRENO_DEVICE_INFO_H
26#define FREEDRENO_DEVICE_INFO_H
27
28#include <assert.h>
29#include <stdbool.h>
30#include <stdint.h>
31
32#ifdef __cplusplus
33extern "C" {
34#endif
35
36/**
37 * Freedreno hardware description and quirks
38 */
39
40struct fd_dev_info {
41   /* alignment for size of tiles */
42   uint32_t tile_align_w, tile_align_h;
43   /* gmem load/store granularity */
44   uint32_t gmem_align_w, gmem_align_h;
45   /* max tile size */
46   uint32_t tile_max_w, tile_max_h;
47
48   uint32_t num_vsc_pipes;
49
50   /* number of CCU is always equal to the number of SP */
51   union {
52      uint32_t num_sp_cores;
53      uint32_t num_ccu;
54   };
55
56   union {
57      struct {
58         /* Information for private memory calculations */
59         uint32_t fibers_per_sp;
60
61         uint32_t reg_size_vec4;
62
63         /* Whether the PC_MULTIVIEW_MASK register exists. */
64         bool supports_multiview_mask;
65
66         /* info for setting RB_CCU_CNTL */
67         bool ccu_cntl_gmem_unk2;
68         bool has_z24uint_s8uint;
69
70         bool tess_use_shared;
71
72         /* Does the hw support GL_QCOM_shading_rate? */
73         bool has_shading_rate;
74
75         /* newer a6xx allows using 16-bit descriptor for both 16-bit
76          * and 32-bit access
77          */
78         bool storage_16bit;
79
80         /* The latest known a630_sqe.fw fails to wait for WFI before
81          * reading the indirect buffer when using CP_DRAW_INDIRECT_MULTI,
82          * so we have to fall back to CP_WAIT_FOR_ME except for a650
83          * which has a fixed firmware.
84          *
85          * TODO: There may be newer a630_sqe.fw released in the future
86          * which fixes this, if so we should detect it and avoid this
87          * workaround.  Once we have uapi to query fw version, we can
88          * replace this with minimum fw version.
89          */
90         bool indirect_draw_wfm_quirk;
91
92         /* On some GPUs, the depth test needs to be enabled when the
93          * depth bounds test is enabled and the depth attachment uses UBWC.
94          */
95         bool depth_bounds_require_depth_test_quirk;
96
97         bool has_tex_filter_cubic;
98
99         bool has_sample_locations;
100
101         /* The firmware on newer a6xx drops CP_REG_WRITE support as we
102          * can now use direct register writes for these regs.
103          */
104         bool has_cp_reg_write;
105
106         bool has_8bpp_ubwc;
107
108         /* a650 seems to be affected by a bug where flushing CCU color into
109          * depth or vice-versa requires a WFI. In particular, clearing a
110          * depth attachment (which writes to it as a color attachment) then
111          * using it as a normal depth attachment requires a WFI in addition
112          * to the expected CCU_FLUSH_COLOR + CCU_INVALIDATE_DEPTH, even
113          * though all those operations happen in the same stage. As this is
114          * usually the only scenario where a CCU flush doesn't require a WFI
115          * we just insert a WFI after every CCU flush.
116          *
117          * Tests affected include
118          * dEQP-VK.renderpass.suballocation.formats.d16_unorm.* in sysmem
119          * mode (a few tests flake when the entire series is run).
120          */
121         bool has_ccu_flush_bug;
122
123         bool has_lpac;
124
125         struct {
126            uint32_t RB_UNKNOWN_8E04_blit;
127            uint32_t PC_POWER_CNTL;
128            uint32_t TPL1_DBG_ECO_CNTL;
129         } magic;
130      } a6xx;
131   };
132};
133
134struct fd_dev_id {
135   uint32_t gpu_id;
136   uint64_t chip_id;
137};
138
139/**
140 * Note that gpu-id should be considered deprecated.  For newer a6xx, if
141 * there is no gpu-id, this attempts to generate one from the chip-id.
142 * But that may not work forever, so avoid depending on this for newer
143 * gens
144 */
145static inline uint32_t
146fd_dev_gpu_id(const struct fd_dev_id *id)
147{
148   assert(id->gpu_id || id->chip_id);
149   if (!id->gpu_id) {
150      return ((id->chip_id >> 24) & 0xff) * 100 +
151             ((id->chip_id >> 16) & 0xff) * 10 +
152             ((id->chip_id >>  8) & 0xff);
153
154   }
155   return id->gpu_id;
156}
157
158static uint8_t
159fd_dev_gen(const struct fd_dev_id *id)
160{
161   return fd_dev_gpu_id(id) / 100;
162}
163
164static inline bool
165fd_dev_64b(const struct fd_dev_id *id)
166{
167   return fd_dev_gen(id) >= 5;
168}
169
170/* per CCU GMEM amount reserved for depth cache for direct rendering */
171#define A6XX_CCU_DEPTH_SIZE (64 * 1024)
172/* per CCU GMEM amount reserved for color cache used by GMEM resolves
173 * which require color cache (non-BLIT event case).
174 * this is smaller than what is normally used by direct rendering
175 * (RB_CCU_CNTL.GMEM bit enables this smaller size)
176 * if a GMEM resolve requires color cache, the driver needs to make sure
177 * it will not overwrite pixel data in GMEM that is still needed
178 */
179#define A6XX_CCU_GMEM_COLOR_SIZE (16 * 1024)
180
181const struct fd_dev_info * fd_dev_info(const struct fd_dev_id *id);
182const char * fd_dev_name(const struct fd_dev_id *id);
183
184#ifdef __cplusplus
185} /* end of extern "C" */
186#endif
187
188#endif /* FREEDRENO_DEVICE_INFO_H */
189