17ec681f3Smrg/*
27ec681f3Smrg * Copyright © 2020 Valve Corporation
37ec681f3Smrg *
47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
57ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
67ec681f3Smrg * to deal in the Software without restriction, including without limitation
77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
97ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
107ec681f3Smrg *
117ec681f3Smrg * The above copyright notice and this permission notice (including the next
127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
137ec681f3Smrg * Software.
147ec681f3Smrg *
157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
217ec681f3Smrg * IN THE SOFTWARE.
227ec681f3Smrg *
237ec681f3Smrg */
247ec681f3Smrg
257ec681f3Smrg#ifndef FREEDRENO_DEVICE_INFO_H
267ec681f3Smrg#define FREEDRENO_DEVICE_INFO_H
277ec681f3Smrg
287ec681f3Smrg#include <assert.h>
297ec681f3Smrg#include <stdbool.h>
307ec681f3Smrg#include <stdint.h>
317ec681f3Smrg
327ec681f3Smrg#ifdef __cplusplus
337ec681f3Smrgextern "C" {
347ec681f3Smrg#endif
357ec681f3Smrg
367ec681f3Smrg/**
377ec681f3Smrg * Freedreno hardware description and quirks
387ec681f3Smrg */
397ec681f3Smrg
407ec681f3Smrgstruct fd_dev_info {
417ec681f3Smrg   /* alignment for size of tiles */
427ec681f3Smrg   uint32_t tile_align_w, tile_align_h;
437ec681f3Smrg   /* gmem load/store granularity */
447ec681f3Smrg   uint32_t gmem_align_w, gmem_align_h;
457ec681f3Smrg   /* max tile size */
467ec681f3Smrg   uint32_t tile_max_w, tile_max_h;
477ec681f3Smrg
487ec681f3Smrg   uint32_t num_vsc_pipes;
497ec681f3Smrg
507ec681f3Smrg   /* number of CCU is always equal to the number of SP */
517ec681f3Smrg   union {
527ec681f3Smrg      uint32_t num_sp_cores;
537ec681f3Smrg      uint32_t num_ccu;
547ec681f3Smrg   };
557ec681f3Smrg
567ec681f3Smrg   union {
577ec681f3Smrg      struct {
587ec681f3Smrg         /* Information for private memory calculations */
597ec681f3Smrg         uint32_t fibers_per_sp;
607ec681f3Smrg
617ec681f3Smrg         uint32_t reg_size_vec4;
627ec681f3Smrg
637ec681f3Smrg         /* Whether the PC_MULTIVIEW_MASK register exists. */
647ec681f3Smrg         bool supports_multiview_mask;
657ec681f3Smrg
667ec681f3Smrg         /* info for setting RB_CCU_CNTL */
677ec681f3Smrg         bool ccu_cntl_gmem_unk2;
687ec681f3Smrg         bool has_z24uint_s8uint;
697ec681f3Smrg
707ec681f3Smrg         bool tess_use_shared;
717ec681f3Smrg
727ec681f3Smrg         /* Does the hw support GL_QCOM_shading_rate? */
737ec681f3Smrg         bool has_shading_rate;
747ec681f3Smrg
757ec681f3Smrg         /* newer a6xx allows using 16-bit descriptor for both 16-bit
767ec681f3Smrg          * and 32-bit access
777ec681f3Smrg          */
787ec681f3Smrg         bool storage_16bit;
797ec681f3Smrg
807ec681f3Smrg         /* The latest known a630_sqe.fw fails to wait for WFI before
817ec681f3Smrg          * reading the indirect buffer when using CP_DRAW_INDIRECT_MULTI,
827ec681f3Smrg          * so we have to fall back to CP_WAIT_FOR_ME except for a650
837ec681f3Smrg          * which has a fixed firmware.
847ec681f3Smrg          *
857ec681f3Smrg          * TODO: There may be newer a630_sqe.fw released in the future
867ec681f3Smrg          * which fixes this, if so we should detect it and avoid this
877ec681f3Smrg          * workaround.  Once we have uapi to query fw version, we can
887ec681f3Smrg          * replace this with minimum fw version.
897ec681f3Smrg          */
907ec681f3Smrg         bool indirect_draw_wfm_quirk;
917ec681f3Smrg
927ec681f3Smrg         /* On some GPUs, the depth test needs to be enabled when the
937ec681f3Smrg          * depth bounds test is enabled and the depth attachment uses UBWC.
947ec681f3Smrg          */
957ec681f3Smrg         bool depth_bounds_require_depth_test_quirk;
967ec681f3Smrg
977ec681f3Smrg         bool has_tex_filter_cubic;
987ec681f3Smrg
997ec681f3Smrg         bool has_sample_locations;
1007ec681f3Smrg
1017ec681f3Smrg         /* The firmware on newer a6xx drops CP_REG_WRITE support as we
1027ec681f3Smrg          * can now use direct register writes for these regs.
1037ec681f3Smrg          */
1047ec681f3Smrg         bool has_cp_reg_write;
1057ec681f3Smrg
1067ec681f3Smrg         bool has_8bpp_ubwc;
1077ec681f3Smrg
1087ec681f3Smrg         /* a650 seems to be affected by a bug where flushing CCU color into
1097ec681f3Smrg          * depth or vice-versa requires a WFI. In particular, clearing a
1107ec681f3Smrg          * depth attachment (which writes to it as a color attachment) then
1117ec681f3Smrg          * using it as a normal depth attachment requires a WFI in addition
1127ec681f3Smrg          * to the expected CCU_FLUSH_COLOR + CCU_INVALIDATE_DEPTH, even
1137ec681f3Smrg          * though all those operations happen in the same stage. As this is
1147ec681f3Smrg          * usually the only scenario where a CCU flush doesn't require a WFI
1157ec681f3Smrg          * we just insert a WFI after every CCU flush.
1167ec681f3Smrg          *
1177ec681f3Smrg          * Tests affected include
1187ec681f3Smrg          * dEQP-VK.renderpass.suballocation.formats.d16_unorm.* in sysmem
1197ec681f3Smrg          * mode (a few tests flake when the entire series is run).
1207ec681f3Smrg          */
1217ec681f3Smrg         bool has_ccu_flush_bug;
1227ec681f3Smrg
1237ec681f3Smrg         bool has_lpac;
1247ec681f3Smrg
1257ec681f3Smrg         struct {
1267ec681f3Smrg            uint32_t RB_UNKNOWN_8E04_blit;
1277ec681f3Smrg            uint32_t PC_POWER_CNTL;
1287ec681f3Smrg            uint32_t TPL1_DBG_ECO_CNTL;
1297ec681f3Smrg         } magic;
1307ec681f3Smrg      } a6xx;
1317ec681f3Smrg   };
1327ec681f3Smrg};
1337ec681f3Smrg
1347ec681f3Smrgstruct fd_dev_id {
1357ec681f3Smrg   uint32_t gpu_id;
1367ec681f3Smrg   uint64_t chip_id;
1377ec681f3Smrg};
1387ec681f3Smrg
1397ec681f3Smrg/**
1407ec681f3Smrg * Note that gpu-id should be considered deprecated.  For newer a6xx, if
1417ec681f3Smrg * there is no gpu-id, this attempts to generate one from the chip-id.
1427ec681f3Smrg * But that may not work forever, so avoid depending on this for newer
1437ec681f3Smrg * gens
1447ec681f3Smrg */
1457ec681f3Smrgstatic inline uint32_t
1467ec681f3Smrgfd_dev_gpu_id(const struct fd_dev_id *id)
1477ec681f3Smrg{
1487ec681f3Smrg   assert(id->gpu_id || id->chip_id);
1497ec681f3Smrg   if (!id->gpu_id) {
1507ec681f3Smrg      return ((id->chip_id >> 24) & 0xff) * 100 +
1517ec681f3Smrg             ((id->chip_id >> 16) & 0xff) * 10 +
1527ec681f3Smrg             ((id->chip_id >>  8) & 0xff);
1537ec681f3Smrg
1547ec681f3Smrg   }
1557ec681f3Smrg   return id->gpu_id;
1567ec681f3Smrg}
1577ec681f3Smrg
1587ec681f3Smrgstatic uint8_t
1597ec681f3Smrgfd_dev_gen(const struct fd_dev_id *id)
1607ec681f3Smrg{
1617ec681f3Smrg   return fd_dev_gpu_id(id) / 100;
1627ec681f3Smrg}
1637ec681f3Smrg
1647ec681f3Smrgstatic inline bool
1657ec681f3Smrgfd_dev_64b(const struct fd_dev_id *id)
1667ec681f3Smrg{
1677ec681f3Smrg   return fd_dev_gen(id) >= 5;
1687ec681f3Smrg}
1697ec681f3Smrg
1707ec681f3Smrg/* per CCU GMEM amount reserved for depth cache for direct rendering */
1717ec681f3Smrg#define A6XX_CCU_DEPTH_SIZE (64 * 1024)
1727ec681f3Smrg/* per CCU GMEM amount reserved for color cache used by GMEM resolves
1737ec681f3Smrg * which require color cache (non-BLIT event case).
1747ec681f3Smrg * this is smaller than what is normally used by direct rendering
1757ec681f3Smrg * (RB_CCU_CNTL.GMEM bit enables this smaller size)
1767ec681f3Smrg * if a GMEM resolve requires color cache, the driver needs to make sure
1777ec681f3Smrg * it will not overwrite pixel data in GMEM that is still needed
1787ec681f3Smrg */
1797ec681f3Smrg#define A6XX_CCU_GMEM_COLOR_SIZE (16 * 1024)
1807ec681f3Smrg
1817ec681f3Smrgconst struct fd_dev_info * fd_dev_info(const struct fd_dev_id *id);
1827ec681f3Smrgconst char * fd_dev_name(const struct fd_dev_id *id);
1837ec681f3Smrg
1847ec681f3Smrg#ifdef __cplusplus
1857ec681f3Smrg} /* end of extern "C" */
1867ec681f3Smrg#endif
1877ec681f3Smrg
1887ec681f3Smrg#endif /* FREEDRENO_DEVICE_INFO_H */
189