17ec681f3Smrg#
27ec681f3Smrg# Copyright © 2021 Google, Inc.
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
237ec681f3Smrgfrom mako.template import Template
247ec681f3Smrgimport sys
257ec681f3Smrg
267ec681f3Smrgdef max_bitfield_val(high, low, shift):
277ec681f3Smrg    return ((1 << (high - low)) - 1) << shift
287ec681f3Smrg
297ec681f3Smrgclass State(object):
307ec681f3Smrg    def __init__(self):
317ec681f3Smrg        # List of unique device-info structs, multiple different GPU ids
327ec681f3Smrg        # can map to a single info struct in cases where the differences
337ec681f3Smrg        # are not sw visible, or the only differences are parameters
347ec681f3Smrg        # queried from the kernel (like GMEM size)
357ec681f3Smrg        self.gpu_infos = []
367ec681f3Smrg
377ec681f3Smrg        # Table mapping GPU id to device-info struct
387ec681f3Smrg        self.gpus = {}
397ec681f3Smrg
407ec681f3Smrg    def info_index(self, gpu_info):
417ec681f3Smrg        i = 0
427ec681f3Smrg        for info in self.gpu_infos:
437ec681f3Smrg            if gpu_info == info:
447ec681f3Smrg                return i
457ec681f3Smrg            i += 1
467ec681f3Smrg        raise Error("invalid info")
477ec681f3Smrg
487ec681f3Smrgs = State()
497ec681f3Smrg
507ec681f3Smrgdef add_gpus(ids, info):
517ec681f3Smrg    for id in ids:
527ec681f3Smrg        s.gpus[id] = info
537ec681f3Smrg
547ec681f3Smrgclass GPUId(object):
557ec681f3Smrg    def __init__(self, gpu_id = None, chip_id = None, name=None):
567ec681f3Smrg        if chip_id == None:
577ec681f3Smrg            assert(gpu_id != None)
587ec681f3Smrg            val = gpu_id
597ec681f3Smrg            core = int(val / 100)
607ec681f3Smrg            val -= (core * 100);
617ec681f3Smrg            major = int(val / 10);
627ec681f3Smrg            val -= (major * 10)
637ec681f3Smrg            minor = val
647ec681f3Smrg            chip_id = (core << 24) | (major << 16) | (minor << 8) | 0xff
657ec681f3Smrg        self.chip_id = chip_id
667ec681f3Smrg        if gpu_id == None:
677ec681f3Smrg            gpu_id = 0
687ec681f3Smrg        self.gpu_id = gpu_id
697ec681f3Smrg        if name == None:
707ec681f3Smrg            assert(gpu_id != 0)
717ec681f3Smrg            name = "FD%d" % gpu_id
727ec681f3Smrg        self.name = name
737ec681f3Smrg
747ec681f3Smrgclass Struct(object):
757ec681f3Smrg    """A helper class that stringifies itself to a 'C' struct initializer
767ec681f3Smrg    """
777ec681f3Smrg    def __str__(self):
787ec681f3Smrg        s = "{"
797ec681f3Smrg        for name, value in vars(self).items():
807ec681f3Smrg            s += "." + name + "=" + str(value) + ","
817ec681f3Smrg        return s + "}"
827ec681f3Smrg
837ec681f3Smrgclass GPUInfo(Struct):
847ec681f3Smrg    """Base class for any generation of adreno, consists of GMEM layout
857ec681f3Smrg       related parameters
867ec681f3Smrg
877ec681f3Smrg       Note that tile_max_h is normally only constrained by corresponding
887ec681f3Smrg       bitfield size/shift (ie. VSC_BIN_SIZE, or similar), but tile_max_h
897ec681f3Smrg       tends to have lower limits, in which case a comment will describe
907ec681f3Smrg       the bitfield size/shift
917ec681f3Smrg    """
927ec681f3Smrg    def __init__(self, gmem_align_w, gmem_align_h,
937ec681f3Smrg                 tile_align_w, tile_align_h,
947ec681f3Smrg                 tile_max_w, tile_max_h, num_vsc_pipes):
957ec681f3Smrg        self.gmem_align_w  = gmem_align_w
967ec681f3Smrg        self.gmem_align_h  = gmem_align_h
977ec681f3Smrg        self.tile_align_w  = tile_align_w
987ec681f3Smrg        self.tile_align_h  = tile_align_h
997ec681f3Smrg        self.tile_max_w    = tile_max_w
1007ec681f3Smrg        self.tile_max_h    = tile_max_h
1017ec681f3Smrg        self.num_vsc_pipes = num_vsc_pipes
1027ec681f3Smrg
1037ec681f3Smrg        s.gpu_infos.append(self)
1047ec681f3Smrg
1057ec681f3Smrg
1067ec681f3Smrgclass A6xxGPUInfo(GPUInfo):
1077ec681f3Smrg    """The a6xx generation has a lot more parameters, and is broken down
1087ec681f3Smrg       into distinct sub-generations.  The template parameter avoids
1097ec681f3Smrg       duplication of parameters that are unique to the sub-generation.
1107ec681f3Smrg    """
1117ec681f3Smrg    def __init__(self, template, num_sp_cores, num_ccu,
1127ec681f3Smrg                 RB_UNKNOWN_8E04_blit, PC_POWER_CNTL):
1137ec681f3Smrg        super().__init__(gmem_align_w = 16, gmem_align_h = 4,
1147ec681f3Smrg                         tile_align_w = 32, tile_align_h = 32,
1157ec681f3Smrg                         tile_max_w   = 1024, # max_bitfield_val(5, 0, 5)
1167ec681f3Smrg                         tile_max_h   = max_bitfield_val(14, 8, 4),
1177ec681f3Smrg                         num_vsc_pipes = 32)
1187ec681f3Smrg        assert(num_sp_cores == num_ccu)
1197ec681f3Smrg
1207ec681f3Smrg        self.num_sp_cores = num_sp_cores
1217ec681f3Smrg
1227ec681f3Smrg        # 96 tile alignment seems correlated to 3 CCU
1237ec681f3Smrg        if num_ccu == 3:
1247ec681f3Smrg            self.tile_align_w = 96
1257ec681f3Smrg
1267ec681f3Smrg        self.a6xx = Struct()
1277ec681f3Smrg        self.a6xx.magic = Struct()
1287ec681f3Smrg
1297ec681f3Smrg        for name, val in template["magic"].items():
1307ec681f3Smrg            setattr(self.a6xx.magic, name, val)
1317ec681f3Smrg
1327ec681f3Smrg        # Various "magic" register values:
1337ec681f3Smrg        self.a6xx.magic.RB_UNKNOWN_8E04_blit = RB_UNKNOWN_8E04_blit
1347ec681f3Smrg        self.a6xx.magic.PC_POWER_CNTL = PC_POWER_CNTL
1357ec681f3Smrg
1367ec681f3Smrg        # Things that earlier gens have and later gens remove, provide
1377ec681f3Smrg        # defaults here and let them be overridden by sub-gen template:
1387ec681f3Smrg        self.a6xx.has_cp_reg_write = True
1397ec681f3Smrg        self.a6xx.has_8bpp_ubwc = True
1407ec681f3Smrg
1417ec681f3Smrg        for name, val in template.items():
1427ec681f3Smrg            if name == "magic": # handled above
1437ec681f3Smrg                continue
1447ec681f3Smrg            setattr(self.a6xx, name, val)
1457ec681f3Smrg
1467ec681f3Smrg# a2xx is really two sub-generations, a20x and a22x, but we don't currently
1477ec681f3Smrg# capture that in the device-info tables
1487ec681f3Smrgadd_gpus([
1497ec681f3Smrg        GPUId(200),
1507ec681f3Smrg        GPUId(201),
1517ec681f3Smrg        GPUId(205),
1527ec681f3Smrg        GPUId(220),
1537ec681f3Smrg    ], GPUInfo(
1547ec681f3Smrg        gmem_align_w = 32,  gmem_align_h = 32,
1557ec681f3Smrg        tile_align_w = 32,  tile_align_h = 32,
1567ec681f3Smrg        tile_max_w   = 512,
1577ec681f3Smrg        tile_max_h   = ~0, # TODO
1587ec681f3Smrg        num_vsc_pipes = 8,
1597ec681f3Smrg    ))
1607ec681f3Smrg
1617ec681f3Smrgadd_gpus([
1627ec681f3Smrg        GPUId(305),
1637ec681f3Smrg        GPUId(307),
1647ec681f3Smrg        GPUId(320),
1657ec681f3Smrg        GPUId(330),
1667ec681f3Smrg    ], GPUInfo(
1677ec681f3Smrg        gmem_align_w = 32,  gmem_align_h = 32,
1687ec681f3Smrg        tile_align_w = 32,  tile_align_h = 32,
1697ec681f3Smrg        tile_max_w   = 992, # max_bitfield_val(4, 0, 5)
1707ec681f3Smrg        tile_max_h   = max_bitfield_val(9, 5, 5),
1717ec681f3Smrg        num_vsc_pipes = 8,
1727ec681f3Smrg    ))
1737ec681f3Smrg
1747ec681f3Smrgadd_gpus([
1757ec681f3Smrg        GPUId(405),
1767ec681f3Smrg        GPUId(420),
1777ec681f3Smrg        GPUId(430),
1787ec681f3Smrg    ], GPUInfo(
1797ec681f3Smrg        gmem_align_w = 32,  gmem_align_h = 32,
1807ec681f3Smrg        tile_align_w = 32,  tile_align_h = 32,
1817ec681f3Smrg        tile_max_w   = 1024, # max_bitfield_val(4, 0, 5)
1827ec681f3Smrg        tile_max_h   = max_bitfield_val(9, 5, 5),
1837ec681f3Smrg        num_vsc_pipes = 8,
1847ec681f3Smrg    ))
1857ec681f3Smrg
1867ec681f3Smrgadd_gpus([
1877ec681f3Smrg        GPUId(508),
1887ec681f3Smrg        GPUId(509),
1897ec681f3Smrg        GPUId(510),
1907ec681f3Smrg        GPUId(512),
1917ec681f3Smrg        GPUId(530),
1927ec681f3Smrg        GPUId(540),
1937ec681f3Smrg    ], GPUInfo(
1947ec681f3Smrg        gmem_align_w = 64,  gmem_align_h = 32,
1957ec681f3Smrg        tile_align_w = 64,  tile_align_h = 32,
1967ec681f3Smrg        tile_max_w   = 1024, # max_bitfield_val(7, 0, 5)
1977ec681f3Smrg        tile_max_h   = max_bitfield_val(16, 9, 5),
1987ec681f3Smrg        num_vsc_pipes = 16,
1997ec681f3Smrg    ))
2007ec681f3Smrg
2017ec681f3Smrg# a6xx can be divided into distinct sub-generations, where certain device-
2027ec681f3Smrg# info parameters are keyed to the sub-generation.  These templates reduce
2037ec681f3Smrg# the copypaste
2047ec681f3Smrg
2057ec681f3Smrg# a615, a618, a630:
2067ec681f3Smrga6xx_gen1 = dict(
2077ec681f3Smrg        fibers_per_sp = 128 * 16,
2087ec681f3Smrg        reg_size_vec4 = 96,
2097ec681f3Smrg        ccu_cntl_gmem_unk2 = True,
2107ec681f3Smrg        indirect_draw_wfm_quirk = True,
2117ec681f3Smrg        depth_bounds_require_depth_test_quirk = True,
2127ec681f3Smrg        magic = dict(
2137ec681f3Smrg            TPL1_DBG_ECO_CNTL = 0x100000,
2147ec681f3Smrg        )
2157ec681f3Smrg    )
2167ec681f3Smrg
2177ec681f3Smrg# a640, a680:
2187ec681f3Smrga6xx_gen2 = dict(
2197ec681f3Smrg        fibers_per_sp = 128 * 4 * 16,
2207ec681f3Smrg        reg_size_vec4 = 96,
2217ec681f3Smrg        supports_multiview_mask = True,
2227ec681f3Smrg        has_z24uint_s8uint = True,
2237ec681f3Smrg        indirect_draw_wfm_quirk = True,
2247ec681f3Smrg        depth_bounds_require_depth_test_quirk = True, # TODO: check if true
2257ec681f3Smrg        magic = dict(
2267ec681f3Smrg            TPL1_DBG_ECO_CNTL = 0,
2277ec681f3Smrg        ),
2287ec681f3Smrg    )
2297ec681f3Smrg
2307ec681f3Smrg# a650:
2317ec681f3Smrga6xx_gen3 = dict(
2327ec681f3Smrg        fibers_per_sp = 128 * 2 * 16,
2337ec681f3Smrg        reg_size_vec4 = 64,
2347ec681f3Smrg        supports_multiview_mask = True,
2357ec681f3Smrg        has_z24uint_s8uint = True,
2367ec681f3Smrg        tess_use_shared = True,
2377ec681f3Smrg        storage_16bit = True,
2387ec681f3Smrg        has_tex_filter_cubic = True,
2397ec681f3Smrg        has_sample_locations = True,
2407ec681f3Smrg        has_ccu_flush_bug = True,
2417ec681f3Smrg        has_8bpp_ubwc = False,
2427ec681f3Smrg        magic = dict(
2437ec681f3Smrg            # this seems to be a chicken bit that fixes cubic filtering:
2447ec681f3Smrg            TPL1_DBG_ECO_CNTL = 0x1000000,
2457ec681f3Smrg        ),
2467ec681f3Smrg    )
2477ec681f3Smrg
2487ec681f3Smrg# a635, a660:
2497ec681f3Smrga6xx_gen4 = dict(
2507ec681f3Smrg        fibers_per_sp = 128 * 2 * 16,
2517ec681f3Smrg        reg_size_vec4 = 64,
2527ec681f3Smrg        supports_multiview_mask = True,
2537ec681f3Smrg        has_z24uint_s8uint = True,
2547ec681f3Smrg        tess_use_shared = True,
2557ec681f3Smrg        storage_16bit = True,
2567ec681f3Smrg        has_tex_filter_cubic = True,
2577ec681f3Smrg        has_sample_locations = True,
2587ec681f3Smrg        has_cp_reg_write = False,
2597ec681f3Smrg        has_8bpp_ubwc = False,
2607ec681f3Smrg        has_lpac = True,
2617ec681f3Smrg        has_shading_rate = True,
2627ec681f3Smrg        magic = dict(
2637ec681f3Smrg            TPL1_DBG_ECO_CNTL = 0x5008000,
2647ec681f3Smrg        ),
2657ec681f3Smrg    )
2667ec681f3Smrg
2677ec681f3Smrgadd_gpus([
2687ec681f3Smrg        GPUId(615),
2697ec681f3Smrg        GPUId(618),
2707ec681f3Smrg    ], A6xxGPUInfo(
2717ec681f3Smrg        a6xx_gen1,
2727ec681f3Smrg        num_sp_cores = 1,
2737ec681f3Smrg        num_ccu = 1,
2747ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x00100000,
2757ec681f3Smrg        PC_POWER_CNTL = 0,
2767ec681f3Smrg    ))
2777ec681f3Smrg
2787ec681f3Smrgadd_gpus([
2797ec681f3Smrg        GPUId(630),
2807ec681f3Smrg    ], A6xxGPUInfo(
2817ec681f3Smrg        a6xx_gen1,
2827ec681f3Smrg        num_sp_cores = 2,
2837ec681f3Smrg        num_ccu = 2,
2847ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x01000000,
2857ec681f3Smrg        PC_POWER_CNTL = 1,
2867ec681f3Smrg    ))
2877ec681f3Smrg
2887ec681f3Smrgadd_gpus([
2897ec681f3Smrg        GPUId(640),
2907ec681f3Smrg    ], A6xxGPUInfo(
2917ec681f3Smrg        a6xx_gen2,
2927ec681f3Smrg        num_sp_cores = 2,
2937ec681f3Smrg        num_ccu = 2,
2947ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x00100000,
2957ec681f3Smrg        PC_POWER_CNTL = 1,
2967ec681f3Smrg    ))
2977ec681f3Smrg
2987ec681f3Smrgadd_gpus([
2997ec681f3Smrg        GPUId(680),
3007ec681f3Smrg    ], A6xxGPUInfo(
3017ec681f3Smrg        a6xx_gen2,
3027ec681f3Smrg        num_sp_cores = 4,
3037ec681f3Smrg        num_ccu = 4,
3047ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x04100000,
3057ec681f3Smrg        PC_POWER_CNTL = 3,
3067ec681f3Smrg    ))
3077ec681f3Smrg
3087ec681f3Smrgadd_gpus([
3097ec681f3Smrg        GPUId(650),
3107ec681f3Smrg    ], A6xxGPUInfo(
3117ec681f3Smrg        a6xx_gen3,
3127ec681f3Smrg        num_sp_cores = 3,
3137ec681f3Smrg        num_ccu = 3,
3147ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x04100000,
3157ec681f3Smrg        PC_POWER_CNTL = 2,
3167ec681f3Smrg    ))
3177ec681f3Smrg
3187ec681f3Smrgadd_gpus([
3197ec681f3Smrg        GPUId(chip_id=0x06030500, name="Adreno 7c Gen 3"),
3207ec681f3Smrg    ], A6xxGPUInfo(
3217ec681f3Smrg        a6xx_gen4,
3227ec681f3Smrg        num_sp_cores = 2,
3237ec681f3Smrg        num_ccu = 2,
3247ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x00100000,
3257ec681f3Smrg        PC_POWER_CNTL = 1,
3267ec681f3Smrg    ))
3277ec681f3Smrg
3287ec681f3Smrgadd_gpus([
3297ec681f3Smrg        GPUId(660),
3307ec681f3Smrg    ], A6xxGPUInfo(
3317ec681f3Smrg        a6xx_gen4,
3327ec681f3Smrg        num_sp_cores = 3,
3337ec681f3Smrg        num_ccu = 3,
3347ec681f3Smrg        RB_UNKNOWN_8E04_blit = 0x04100000,
3357ec681f3Smrg        PC_POWER_CNTL = 2,
3367ec681f3Smrg    ))
3377ec681f3Smrg
3387ec681f3Smrgtemplate = """\
3397ec681f3Smrg/* Copyright (C) 2021 Google, Inc.
3407ec681f3Smrg *
3417ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a
3427ec681f3Smrg * copy of this software and associated documentation files (the "Software"),
3437ec681f3Smrg * to deal in the Software without restriction, including without limitation
3447ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3457ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the
3467ec681f3Smrg * Software is furnished to do so, subject to the following conditions:
3477ec681f3Smrg *
3487ec681f3Smrg * The above copyright notice and this permission notice (including the next
3497ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the
3507ec681f3Smrg * Software.
3517ec681f3Smrg *
3527ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3537ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3547ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
3557ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3567ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3577ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
3587ec681f3Smrg * IN THE SOFTWARE.
3597ec681f3Smrg */
3607ec681f3Smrg
3617ec681f3Smrg#include "freedreno_dev_info.h"
3627ec681f3Smrg
3637ec681f3Smrg/* Map python to C: */
3647ec681f3Smrg#define True true
3657ec681f3Smrg#define False false
3667ec681f3Smrg
3677ec681f3Smrg%for info in s.gpu_infos:
3687ec681f3Smrgstatic const struct fd_dev_info __info${s.info_index(info)} = ${str(info)};
3697ec681f3Smrg%endfor
3707ec681f3Smrg
3717ec681f3Smrgstatic const struct fd_dev_rec fd_dev_recs[] = {
3727ec681f3Smrg%for id, info in s.gpus.items():
3737ec681f3Smrg   { {${id.gpu_id}, ${hex(id.chip_id)}}, "${id.name}", &__info${s.info_index(info)} },
3747ec681f3Smrg%endfor
3757ec681f3Smrg};
3767ec681f3Smrg"""
3777ec681f3Smrg
3787ec681f3Smrgprint(Template(template).render(s=s))
3797ec681f3Smrg
380