110916Sandreas.sandberg@arm.com/*
211349Sandreas.sandberg@arm.com * Copyright (c) 2014-2016 ARM Limited
310916Sandreas.sandberg@arm.com * All rights reserved
410916Sandreas.sandberg@arm.com *
510916Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall
610916Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual
710916Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating
810916Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software
910916Sandreas.sandberg@arm.com * licensed hereunder.  You may use the software subject to the license
1010916Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated
1110916Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software,
1210916Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form.
1310916Sandreas.sandberg@arm.com *
1410916Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without
1510916Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are
1610916Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright
1710916Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer;
1810916Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright
1910916Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the
2010916Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution;
2110916Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its
2210916Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from
2310916Sandreas.sandberg@arm.com * this software without specific prior written permission.
2410916Sandreas.sandberg@arm.com *
2510916Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610916Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710916Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810916Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910916Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010916Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110916Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210916Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310916Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410916Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510916Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610916Sandreas.sandberg@arm.com *
3710916Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
3810916Sandreas.sandberg@arm.com */
3910916Sandreas.sandberg@arm.com
4010916Sandreas.sandberg@arm.com#include "dev/arm/gpu_nomali.hh"
4110916Sandreas.sandberg@arm.com
4210916Sandreas.sandberg@arm.com#include "debug/NoMali.hh"
4310916Sandreas.sandberg@arm.com#include "dev/arm/base_gic.hh"
4410916Sandreas.sandberg@arm.com#include "dev/arm/realview.hh"
4510916Sandreas.sandberg@arm.com#include "enums/MemoryMode.hh"
4610916Sandreas.sandberg@arm.com#include "mem/packet_access.hh"
4711619Sandreas.sandberg@arm.com#include "nomali/lib/mali_midg_regmap.h"
4811619Sandreas.sandberg@arm.com#include "params/CustomNoMaliGpu.hh"
4910916Sandreas.sandberg@arm.com#include "params/NoMaliGpu.hh"
5010916Sandreas.sandberg@arm.com
5111349Sandreas.sandberg@arm.comstatic const std::map<Enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{
5211349Sandreas.sandberg@arm.com    { Enums::T60x, NOMALI_GPU_T60X },
5311349Sandreas.sandberg@arm.com    { Enums::T62x, NOMALI_GPU_T62X },
5411349Sandreas.sandberg@arm.com    { Enums::T760, NOMALI_GPU_T760 },
5511349Sandreas.sandberg@arm.com};
5611349Sandreas.sandberg@arm.com
5710916Sandreas.sandberg@arm.comNoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p)
5810916Sandreas.sandberg@arm.com    : PioDevice(p),
5910916Sandreas.sandberg@arm.com      pioAddr(p->pio_addr),
6010916Sandreas.sandberg@arm.com      platform(p->platform),
6110916Sandreas.sandberg@arm.com      interruptMap{
6210916Sandreas.sandberg@arm.com          { NOMALI_INT_GPU, p->int_gpu },
6310916Sandreas.sandberg@arm.com          { NOMALI_INT_JOB, p->int_job },
6410916Sandreas.sandberg@arm.com          { NOMALI_INT_MMU, p->int_mmu },
6510916Sandreas.sandberg@arm.com      }
6610916Sandreas.sandberg@arm.com{
6710916Sandreas.sandberg@arm.com    if (nomali_api_version() != NOMALI_API_VERSION)
6810916Sandreas.sandberg@arm.com        panic("NoMali library API mismatch!\n");
6910916Sandreas.sandberg@arm.com
7010916Sandreas.sandberg@arm.com    /* Setup the GPU configuration based on our param struct */
7110916Sandreas.sandberg@arm.com    nomali_config_t cfg;
7210916Sandreas.sandberg@arm.com    memset(&cfg, 0, sizeof(cfg));
7310916Sandreas.sandberg@arm.com
7411349Sandreas.sandberg@arm.com    const auto it_gpu(gpuTypeMap.find(p->gpu_type));
7511349Sandreas.sandberg@arm.com    if (it_gpu == gpuTypeMap.end()) {
7611349Sandreas.sandberg@arm.com        fatal("Unrecognized GPU type: %s (%i)\n",
7711349Sandreas.sandberg@arm.com              Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type);
7810916Sandreas.sandberg@arm.com    }
7911349Sandreas.sandberg@arm.com    cfg.type = it_gpu->second;
8010916Sandreas.sandberg@arm.com
8110916Sandreas.sandberg@arm.com    cfg.ver_maj = p->ver_maj;
8210916Sandreas.sandberg@arm.com    cfg.ver_min = p->ver_min;
8310916Sandreas.sandberg@arm.com    cfg.ver_status = p->ver_status;
8410916Sandreas.sandberg@arm.com
8510916Sandreas.sandberg@arm.com    panicOnErr(
8610916Sandreas.sandberg@arm.com        nomali_create(&nomali, &cfg),
8710916Sandreas.sandberg@arm.com        "Failed to instantiate NoMali");
8810916Sandreas.sandberg@arm.com
8910916Sandreas.sandberg@arm.com
9010916Sandreas.sandberg@arm.com    /* Setup an interrupt callback */
9110916Sandreas.sandberg@arm.com    nomali_callback_t cbk_int;
9210916Sandreas.sandberg@arm.com    cbk_int.type = NOMALI_CALLBACK_INT;
9310916Sandreas.sandberg@arm.com    cbk_int.usr = (void *)this;
9410916Sandreas.sandberg@arm.com    cbk_int.func.interrupt = NoMaliGpu::_interrupt;
9511349Sandreas.sandberg@arm.com    setCallback(cbk_int);
9610916Sandreas.sandberg@arm.com
9711350Sandreas.sandberg@arm.com    /* Setup a reset callback */
9811350Sandreas.sandberg@arm.com    nomali_callback_t cbk_rst;
9911350Sandreas.sandberg@arm.com    cbk_rst.type = NOMALI_CALLBACK_RESET;
10011350Sandreas.sandberg@arm.com    cbk_rst.usr = (void *)this;
10111350Sandreas.sandberg@arm.com    cbk_rst.func.reset = NoMaliGpu::_reset;
10211350Sandreas.sandberg@arm.com    setCallback(cbk_rst);
10311350Sandreas.sandberg@arm.com
10410916Sandreas.sandberg@arm.com    panicOnErr(
10510916Sandreas.sandberg@arm.com        nomali_get_info(nomali, &nomaliInfo),
10610916Sandreas.sandberg@arm.com        "Failed to get NoMali information struct");
10710916Sandreas.sandberg@arm.com}
10810916Sandreas.sandberg@arm.com
10910916Sandreas.sandberg@arm.comNoMaliGpu::~NoMaliGpu()
11010916Sandreas.sandberg@arm.com{
11110916Sandreas.sandberg@arm.com    nomali_destroy(nomali);
11210916Sandreas.sandberg@arm.com}
11310916Sandreas.sandberg@arm.com
11411350Sandreas.sandberg@arm.com
11511350Sandreas.sandberg@arm.comvoid
11611350Sandreas.sandberg@arm.comNoMaliGpu::init()
11711350Sandreas.sandberg@arm.com{
11811350Sandreas.sandberg@arm.com    PioDevice::init();
11911350Sandreas.sandberg@arm.com
12011350Sandreas.sandberg@arm.com    /* Reset the GPU here since the reset callback won't have been
12111350Sandreas.sandberg@arm.com     * installed when the GPU was reset at instantiation time.
12211350Sandreas.sandberg@arm.com     */
12311350Sandreas.sandberg@arm.com    reset();
12411350Sandreas.sandberg@arm.com}
12511350Sandreas.sandberg@arm.com
12610916Sandreas.sandberg@arm.comvoid
12710916Sandreas.sandberg@arm.comNoMaliGpu::serialize(CheckpointOut &cp) const
12810916Sandreas.sandberg@arm.com{
12910916Sandreas.sandberg@arm.com    std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
13010916Sandreas.sandberg@arm.com
13110916Sandreas.sandberg@arm.com    for (int i = 0; i < nomaliInfo.reg_size; i += 4)
13210916Sandreas.sandberg@arm.com        regs[i >> 2] = readRegRaw(i);
13310916Sandreas.sandberg@arm.com
13410916Sandreas.sandberg@arm.com    SERIALIZE_CONTAINER(regs);
13510916Sandreas.sandberg@arm.com}
13610916Sandreas.sandberg@arm.com
13710916Sandreas.sandberg@arm.comvoid
13810916Sandreas.sandberg@arm.comNoMaliGpu::unserialize(CheckpointIn &cp)
13910916Sandreas.sandberg@arm.com{
14010916Sandreas.sandberg@arm.com    std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
14110916Sandreas.sandberg@arm.com
14210916Sandreas.sandberg@arm.com    UNSERIALIZE_CONTAINER(regs);
14310916Sandreas.sandberg@arm.com
14410916Sandreas.sandberg@arm.com    for (int i = 0; i < nomaliInfo.reg_size; i += 4)
14510916Sandreas.sandberg@arm.com        writeRegRaw(i, regs[i >> 2]);
14610916Sandreas.sandberg@arm.com}
14710916Sandreas.sandberg@arm.com
14810916Sandreas.sandberg@arm.comTick
14910916Sandreas.sandberg@arm.comNoMaliGpu::read(PacketPtr pkt)
15010916Sandreas.sandberg@arm.com{
15110916Sandreas.sandberg@arm.com    assert(pkt->getAddr() >= pioAddr);
15210916Sandreas.sandberg@arm.com    const Addr addr(pkt->getAddr() - pioAddr);
15310916Sandreas.sandberg@arm.com    const unsigned size(pkt->getSize());
15410916Sandreas.sandberg@arm.com
15510916Sandreas.sandberg@arm.com    if (addr + size >= nomaliInfo.reg_size)
15610916Sandreas.sandberg@arm.com        panic("GPU register '0x%x' out of range!\n", addr);
15710916Sandreas.sandberg@arm.com
15810916Sandreas.sandberg@arm.com    if (size != 4)
15910916Sandreas.sandberg@arm.com        panic("Unexpected GPU register read size: %i\n", size);
16010916Sandreas.sandberg@arm.com    else if (addr & 0x3)
16110916Sandreas.sandberg@arm.com        panic("Unaligned GPU read: %i\n", size);
16210916Sandreas.sandberg@arm.com
16313230Sgabeblack@google.com    pkt->setLE<uint32_t>(readReg(addr));
16410916Sandreas.sandberg@arm.com    pkt->makeResponse();
16510916Sandreas.sandberg@arm.com
16610916Sandreas.sandberg@arm.com    return 0;
16710916Sandreas.sandberg@arm.com}
16810916Sandreas.sandberg@arm.com
16910916Sandreas.sandberg@arm.comTick
17010916Sandreas.sandberg@arm.comNoMaliGpu::write(PacketPtr pkt)
17110916Sandreas.sandberg@arm.com{
17210916Sandreas.sandberg@arm.com    assert(pkt->getAddr() >= pioAddr);
17310916Sandreas.sandberg@arm.com    const Addr addr(pkt->getAddr() - pioAddr);
17410916Sandreas.sandberg@arm.com    const unsigned size(pkt->getSize());
17510916Sandreas.sandberg@arm.com
17610916Sandreas.sandberg@arm.com    if (addr + size >= nomaliInfo.reg_size)
17710916Sandreas.sandberg@arm.com        panic("GPU register '0x%x' out of range!\n", addr);
17810916Sandreas.sandberg@arm.com
17910916Sandreas.sandberg@arm.com    if (size != 4)
18010916Sandreas.sandberg@arm.com        panic("Unexpected GPU register write size: %i\n", size);
18110916Sandreas.sandberg@arm.com    else if (addr & 0x3)
18210916Sandreas.sandberg@arm.com        panic("Unaligned GPU write: %i\n", size);
18310916Sandreas.sandberg@arm.com
18413230Sgabeblack@google.com    writeReg(addr, pkt->getLE<uint32_t>());
18510916Sandreas.sandberg@arm.com    pkt->makeAtomicResponse();
18610916Sandreas.sandberg@arm.com
18710916Sandreas.sandberg@arm.com    return 0;
18810916Sandreas.sandberg@arm.com}
18910916Sandreas.sandberg@arm.com
19010916Sandreas.sandberg@arm.comAddrRangeList
19110916Sandreas.sandberg@arm.comNoMaliGpu::getAddrRanges() const
19210916Sandreas.sandberg@arm.com{
19310916Sandreas.sandberg@arm.com    return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) });
19410916Sandreas.sandberg@arm.com}
19510916Sandreas.sandberg@arm.com
19611349Sandreas.sandberg@arm.comvoid
19711349Sandreas.sandberg@arm.comNoMaliGpu::reset()
19811349Sandreas.sandberg@arm.com{
19911349Sandreas.sandberg@arm.com    DPRINTF(NoMali, "reset()\n");
20011349Sandreas.sandberg@arm.com
20111349Sandreas.sandberg@arm.com    panicOnErr(
20211349Sandreas.sandberg@arm.com        nomali_reset(nomali),
20311349Sandreas.sandberg@arm.com        "Failed to reset GPU");
20411349Sandreas.sandberg@arm.com}
20511349Sandreas.sandberg@arm.com
20610916Sandreas.sandberg@arm.comuint32_t
20710916Sandreas.sandberg@arm.comNoMaliGpu::readReg(nomali_addr_t reg)
20810916Sandreas.sandberg@arm.com{
20910916Sandreas.sandberg@arm.com    uint32_t value;
21010916Sandreas.sandberg@arm.com
21110916Sandreas.sandberg@arm.com    panicOnErr(
21210916Sandreas.sandberg@arm.com        nomali_reg_read(nomali, &value, reg),
21310916Sandreas.sandberg@arm.com        "GPU register read failed");
21410916Sandreas.sandberg@arm.com
21510916Sandreas.sandberg@arm.com    DPRINTF(NoMali, "readReg(0x%x): 0x%x\n",
21610916Sandreas.sandberg@arm.com            reg, value);
21710916Sandreas.sandberg@arm.com
21810916Sandreas.sandberg@arm.com    return value;
21910916Sandreas.sandberg@arm.com}
22010916Sandreas.sandberg@arm.com
22110916Sandreas.sandberg@arm.com
22210916Sandreas.sandberg@arm.comvoid
22310916Sandreas.sandberg@arm.comNoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value)
22410916Sandreas.sandberg@arm.com{
22510916Sandreas.sandberg@arm.com    DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n",
22610916Sandreas.sandberg@arm.com            reg, value);
22710916Sandreas.sandberg@arm.com
22810916Sandreas.sandberg@arm.com    panicOnErr(
22910916Sandreas.sandberg@arm.com        nomali_reg_write(nomali, reg, value),
23010916Sandreas.sandberg@arm.com        "GPU register write failed");
23110916Sandreas.sandberg@arm.com}
23210916Sandreas.sandberg@arm.com
23310916Sandreas.sandberg@arm.comuint32_t
23410916Sandreas.sandberg@arm.comNoMaliGpu::readRegRaw(nomali_addr_t reg) const
23510916Sandreas.sandberg@arm.com{
23610916Sandreas.sandberg@arm.com    uint32_t value;
23710916Sandreas.sandberg@arm.com
23810916Sandreas.sandberg@arm.com    panicOnErr(
23910916Sandreas.sandberg@arm.com        nomali_reg_read_raw(nomali, &value, reg),
24010916Sandreas.sandberg@arm.com        "GPU raw register read failed");
24110916Sandreas.sandberg@arm.com
24210916Sandreas.sandberg@arm.com    return value;
24310916Sandreas.sandberg@arm.com}
24410916Sandreas.sandberg@arm.com
24510916Sandreas.sandberg@arm.com
24610916Sandreas.sandberg@arm.comvoid
24710916Sandreas.sandberg@arm.comNoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value)
24810916Sandreas.sandberg@arm.com{
24910916Sandreas.sandberg@arm.com    panicOnErr(
25010916Sandreas.sandberg@arm.com        nomali_reg_write_raw(nomali, reg, value),
25110916Sandreas.sandberg@arm.com        "GPU raw register write failed");
25210916Sandreas.sandberg@arm.com}
25310916Sandreas.sandberg@arm.com
25411349Sandreas.sandberg@arm.combool
25511349Sandreas.sandberg@arm.comNoMaliGpu::intState(nomali_int_t intno)
25610916Sandreas.sandberg@arm.com{
25711349Sandreas.sandberg@arm.com    int state = 0;
25811349Sandreas.sandberg@arm.com    panicOnErr(
25911349Sandreas.sandberg@arm.com        nomali_int_state(nomali, &state, intno),
26011349Sandreas.sandberg@arm.com        "Failed to get interrupt state");
26110916Sandreas.sandberg@arm.com
26211349Sandreas.sandberg@arm.com    return !!state;
26310916Sandreas.sandberg@arm.com}
26410916Sandreas.sandberg@arm.com
26510916Sandreas.sandberg@arm.comvoid
26611349Sandreas.sandberg@arm.comNoMaliGpu::gpuPanic(nomali_error_t err, const char *msg)
26711349Sandreas.sandberg@arm.com{
26811349Sandreas.sandberg@arm.com    panic("%s: %s\n", msg, nomali_errstr(err));
26911349Sandreas.sandberg@arm.com}
27011349Sandreas.sandberg@arm.com
27111349Sandreas.sandberg@arm.com
27211349Sandreas.sandberg@arm.comvoid
27311349Sandreas.sandberg@arm.comNoMaliGpu::onInterrupt(nomali_int_t intno, bool set)
27410916Sandreas.sandberg@arm.com{
27510916Sandreas.sandberg@arm.com    const auto it_int(interruptMap.find(intno));
27610916Sandreas.sandberg@arm.com    if (it_int == interruptMap.end())
27710916Sandreas.sandberg@arm.com        panic("Unhandled interrupt from NoMali: %i\n", intno);
27810916Sandreas.sandberg@arm.com
27910916Sandreas.sandberg@arm.com    DPRINTF(NoMali, "Interrupt %i->%i: %i\n",
28010916Sandreas.sandberg@arm.com            intno, it_int->second, set);
28110916Sandreas.sandberg@arm.com
28210916Sandreas.sandberg@arm.com    assert(platform);
28310916Sandreas.sandberg@arm.com    assert(platform->gic);
28410916Sandreas.sandberg@arm.com
28510916Sandreas.sandberg@arm.com    if (set)
28610916Sandreas.sandberg@arm.com        platform->gic->sendInt(it_int->second);
28710916Sandreas.sandberg@arm.com    else
28810916Sandreas.sandberg@arm.com        platform->gic->clearInt(it_int->second);
28910916Sandreas.sandberg@arm.com}
29010916Sandreas.sandberg@arm.com
29110916Sandreas.sandberg@arm.comvoid
29211350Sandreas.sandberg@arm.comNoMaliGpu::onReset()
29311350Sandreas.sandberg@arm.com{
29411350Sandreas.sandberg@arm.com    DPRINTF(NoMali, "Reset\n");
29511350Sandreas.sandberg@arm.com}
29611350Sandreas.sandberg@arm.com
29711350Sandreas.sandberg@arm.comvoid
29811349Sandreas.sandberg@arm.comNoMaliGpu::setCallback(const nomali_callback_t &callback)
29910916Sandreas.sandberg@arm.com{
30011349Sandreas.sandberg@arm.com    DPRINTF(NoMali, "Registering callback %i\n",
30111349Sandreas.sandberg@arm.com            callback.type);
30211349Sandreas.sandberg@arm.com
30311349Sandreas.sandberg@arm.com    panicOnErr(
30411349Sandreas.sandberg@arm.com        nomali_set_callback(nomali, &callback),
30511349Sandreas.sandberg@arm.com        "Failed to register callback");
30611349Sandreas.sandberg@arm.com}
30711349Sandreas.sandberg@arm.com
30811349Sandreas.sandberg@arm.comvoid
30911349Sandreas.sandberg@arm.comNoMaliGpu::_interrupt(nomali_handle_t h, void *usr,
31011349Sandreas.sandberg@arm.com                      nomali_int_t intno, int set)
31111349Sandreas.sandberg@arm.com{
31211349Sandreas.sandberg@arm.com    NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
31311349Sandreas.sandberg@arm.com
31411349Sandreas.sandberg@arm.com    _this->onInterrupt(intno, !!set);
31510916Sandreas.sandberg@arm.com}
31610916Sandreas.sandberg@arm.com
31711350Sandreas.sandberg@arm.comvoid
31811350Sandreas.sandberg@arm.comNoMaliGpu::_reset(nomali_handle_t h, void *usr)
31911350Sandreas.sandberg@arm.com{
32011350Sandreas.sandberg@arm.com    NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
32111350Sandreas.sandberg@arm.com
32211350Sandreas.sandberg@arm.com    _this->onReset();
32311350Sandreas.sandberg@arm.com}
32411350Sandreas.sandberg@arm.com
32511619Sandreas.sandberg@arm.com
32611619Sandreas.sandberg@arm.comCustomNoMaliGpu::CustomNoMaliGpu(const CustomNoMaliGpuParams *p)
32711619Sandreas.sandberg@arm.com    : NoMaliGpu(p),
32811619Sandreas.sandberg@arm.com      idRegs{
32911619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(GPU_ID), p->gpu_id },
33011619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(L2_FEATURES), p->l2_features },
33111619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(TILER_FEATURES), p->tiler_features },
33211619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(MEM_FEATURES), p->mem_features },
33311619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(MMU_FEATURES), p->mmu_features },
33411619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(AS_PRESENT), p->as_present },
33511619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(JS_PRESENT), p->js_present },
33611619Sandreas.sandberg@arm.com
33711619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(THREAD_MAX_THREADS), p->thread_max_threads },
33811619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(THREAD_MAX_WORKGROUP_SIZE),
33911619Sandreas.sandberg@arm.com          p->thread_max_workgroup_size },
34011619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(THREAD_MAX_BARRIER_SIZE),
34111619Sandreas.sandberg@arm.com          p->thread_max_barrier_size },
34211619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(THREAD_FEATURES), p->thread_features },
34311619Sandreas.sandberg@arm.com
34411619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(SHADER_PRESENT_LO), bits(p->shader_present, 31, 0) },
34511619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(SHADER_PRESENT_HI), bits(p->shader_present, 63, 32) },
34611619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(TILER_PRESENT_LO), bits(p->tiler_present, 31, 0) },
34711619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(TILER_PRESENT_HI), bits(p->tiler_present, 63, 32) },
34811619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(L2_PRESENT_LO), bits(p->l2_present, 31, 0) },
34911619Sandreas.sandberg@arm.com        { GPU_CONTROL_REG(L2_PRESENT_HI), bits(p->l2_present, 63, 32) },
35011619Sandreas.sandberg@arm.com      }
35111619Sandreas.sandberg@arm.com{
35211619Sandreas.sandberg@arm.com    fatal_if(p->texture_features.size() > 3,
35311619Sandreas.sandberg@arm.com             "Too many texture feature registers specified (%i)\n",
35411619Sandreas.sandberg@arm.com             p->texture_features.size());
35511619Sandreas.sandberg@arm.com
35611619Sandreas.sandberg@arm.com    fatal_if(p->js_features.size() > 16,
35711619Sandreas.sandberg@arm.com             "Too many job slot feature registers specified (%i)\n",
35811619Sandreas.sandberg@arm.com             p->js_features.size());
35911619Sandreas.sandberg@arm.com
36011619Sandreas.sandberg@arm.com    for (int i = 0; i < p->texture_features.size(); i++)
36111619Sandreas.sandberg@arm.com        idRegs[TEXTURE_FEATURES_REG(i)] = p->texture_features[i];
36211619Sandreas.sandberg@arm.com
36311619Sandreas.sandberg@arm.com    for (int i = 0; i < p->js_features.size(); i++)
36411619Sandreas.sandberg@arm.com        idRegs[JS_FEATURES_REG(i)] = p->js_features[i];
36511619Sandreas.sandberg@arm.com}
36611619Sandreas.sandberg@arm.com
36711619Sandreas.sandberg@arm.comCustomNoMaliGpu::~CustomNoMaliGpu()
36811619Sandreas.sandberg@arm.com{
36911619Sandreas.sandberg@arm.com}
37011619Sandreas.sandberg@arm.com
37111619Sandreas.sandberg@arm.comvoid
37211619Sandreas.sandberg@arm.comCustomNoMaliGpu::onReset()
37311619Sandreas.sandberg@arm.com{
37411619Sandreas.sandberg@arm.com    NoMaliGpu::onReset();
37511619Sandreas.sandberg@arm.com
37611619Sandreas.sandberg@arm.com    for (const auto &reg : idRegs)
37711619Sandreas.sandberg@arm.com        writeRegRaw(reg.first, reg.second);
37811619Sandreas.sandberg@arm.com}
37911619Sandreas.sandberg@arm.com
38011619Sandreas.sandberg@arm.com
38111619Sandreas.sandberg@arm.com
38210916Sandreas.sandberg@arm.comNoMaliGpu *
38310916Sandreas.sandberg@arm.comNoMaliGpuParams::create()
38410916Sandreas.sandberg@arm.com{
38510916Sandreas.sandberg@arm.com    return new NoMaliGpu(this);
38610916Sandreas.sandberg@arm.com}
38711619Sandreas.sandberg@arm.com
38811619Sandreas.sandberg@arm.comCustomNoMaliGpu *
38911619Sandreas.sandberg@arm.comCustomNoMaliGpuParams::create()
39011619Sandreas.sandberg@arm.com{
39111619Sandreas.sandberg@arm.com    return new CustomNoMaliGpu(this);
39211619Sandreas.sandberg@arm.com}
393