Home | History | Annotate | Line # | Download | only in common
      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
     33 extern "C" {
     34 #endif
     35 
     36 /**
     37  * Freedreno hardware description and quirks
     38  */
     39 
     40 struct 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 
    134 struct 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  */
    145 static inline uint32_t
    146 fd_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 
    158 static uint8_t
    159 fd_dev_gen(const struct fd_dev_id *id)
    160 {
    161    return fd_dev_gpu_id(id) / 100;
    162 }
    163 
    164 static inline bool
    165 fd_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 
    181 const struct fd_dev_info * fd_dev_info(const struct fd_dev_id *id);
    182 const 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