110915Sandreas.sandberg@arm.com/*
210915Sandreas.sandberg@arm.com * Copyright (c) 2014-2015 ARM Limited
310915Sandreas.sandberg@arm.com * All rights reserved
410915Sandreas.sandberg@arm.com *
510915Sandreas.sandberg@arm.com * Licensed under the Apache License, Version 2.0 (the "License");
610915Sandreas.sandberg@arm.com * you may not use this file except in compliance with the License.
710915Sandreas.sandberg@arm.com * You may obtain a copy of the License at
810915Sandreas.sandberg@arm.com *
910915Sandreas.sandberg@arm.com *     http://www.apache.org/licenses/LICENSE-2.0
1010915Sandreas.sandberg@arm.com *
1110915Sandreas.sandberg@arm.com * Unless required by applicable law or agreed to in writing, software
1210915Sandreas.sandberg@arm.com * distributed under the License is distributed on an "AS IS" BASIS,
1310915Sandreas.sandberg@arm.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1410915Sandreas.sandberg@arm.com * See the License for the specific language governing permissions and
1510915Sandreas.sandberg@arm.com * limitations under the License.
1610915Sandreas.sandberg@arm.com *
1710915Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
1810915Sandreas.sandberg@arm.com */
1910915Sandreas.sandberg@arm.com
2010915Sandreas.sandberg@arm.com#include "gpucontrol.hh"
2110915Sandreas.sandberg@arm.com#include "gpu.hh"
2210915Sandreas.sandberg@arm.com#include "regutils.hh"
2310915Sandreas.sandberg@arm.com
2410915Sandreas.sandberg@arm.comnamespace NoMali {
2510915Sandreas.sandberg@arm.com
2610915Sandreas.sandberg@arm.comtypedef void (GPUControl::*GpuCmdHandler)(uint32_t);
2710915Sandreas.sandberg@arm.com
2810915Sandreas.sandberg@arm.comconst std::vector<GpuCmdHandler> GPUControl::cmds {
2910915Sandreas.sandberg@arm.com    &GPUControl::cmdNop,                     // GPU_COMMAND_NOP
3010915Sandreas.sandberg@arm.com    &GPUControl::cmdSoftReset,               // GPU_COMMAND_SOFT_RESET
3110915Sandreas.sandberg@arm.com    &GPUControl::cmdHardReset,               // GPU_COMMAND_HARD_RESET
3210915Sandreas.sandberg@arm.com    &GPUControl::cmdPerfCntClear,            // GPU_COMMAND_PRFCNT_CLEAR
3310915Sandreas.sandberg@arm.com    &GPUControl::cmdPerfCntSample,           // GPU_COMMAND_PRFCNT_SAMPLE
3410915Sandreas.sandberg@arm.com    &GPUControl::cmdCycleCountStart,         // GPU_COMMAND_CYCLE_COUNT_START
3510915Sandreas.sandberg@arm.com    &GPUControl::cmdCycleCountStop,          // GPU_COMMAND_COUNT_STOP
3610915Sandreas.sandberg@arm.com    &GPUControl::cmdCleanCaches,             // GPU_COMMAND_CLEAN_CACHES
3710915Sandreas.sandberg@arm.com    &GPUControl::cmdCleanInvCaches,          // GPU_COMMAND_CLEAN_INV_CACHES
3810915Sandreas.sandberg@arm.com};
3910915Sandreas.sandberg@arm.com
4010915Sandreas.sandberg@arm.comGPUControl::GPUControl(GPU &_gpu)
4110915Sandreas.sandberg@arm.com    : GPUBlockInt(_gpu,
4210915Sandreas.sandberg@arm.com                  RegAddr(GPU_IRQ_RAWSTAT),
4310915Sandreas.sandberg@arm.com                  RegAddr(GPU_IRQ_CLEAR),
4410915Sandreas.sandberg@arm.com                  RegAddr(GPU_IRQ_MASK),
4510915Sandreas.sandberg@arm.com                  RegAddr(GPU_IRQ_STATUS))
4610915Sandreas.sandberg@arm.com{
4710915Sandreas.sandberg@arm.com}
4810915Sandreas.sandberg@arm.com
4910915Sandreas.sandberg@arm.comGPUControl::~GPUControl()
5010915Sandreas.sandberg@arm.com{
5110915Sandreas.sandberg@arm.com}
5210915Sandreas.sandberg@arm.com
5310915Sandreas.sandberg@arm.comvoid
5410915Sandreas.sandberg@arm.comGPUControl::reset()
5510915Sandreas.sandberg@arm.com{
5610915Sandreas.sandberg@arm.com    GPUBlock::reset();
5710915Sandreas.sandberg@arm.com}
5810915Sandreas.sandberg@arm.com
5910915Sandreas.sandberg@arm.comvoid
6010915Sandreas.sandberg@arm.comGPUControl::writeReg(RegAddr addr, uint32_t value)
6110915Sandreas.sandberg@arm.com{
6210915Sandreas.sandberg@arm.com    switch (addr.value) {
6310915Sandreas.sandberg@arm.com      case GPU_IRQ_RAWSTAT:
6410915Sandreas.sandberg@arm.com      case GPU_IRQ_CLEAR:
6510915Sandreas.sandberg@arm.com      case GPU_IRQ_MASK:
6610915Sandreas.sandberg@arm.com      case GPU_IRQ_STATUS:
6710915Sandreas.sandberg@arm.com        GPUBlockInt::writeReg(addr, value);
6810915Sandreas.sandberg@arm.com        break;
6910915Sandreas.sandberg@arm.com
7010915Sandreas.sandberg@arm.com      case GPU_COMMAND:
7110915Sandreas.sandberg@arm.com        gpuCommand(value);
7210915Sandreas.sandberg@arm.com        break;
7310915Sandreas.sandberg@arm.com
7410915Sandreas.sandberg@arm.com      case SHADER_PWRON_LO:
7510915Sandreas.sandberg@arm.com      case SHADER_PWRON_HI:
7610915Sandreas.sandberg@arm.com      case TILER_PWRON_LO:
7710915Sandreas.sandberg@arm.com      case TILER_PWRON_HI:
7810915Sandreas.sandberg@arm.com      case L2_PWRON_LO:
7910915Sandreas.sandberg@arm.com      case L2_PWRON_HI:
8010915Sandreas.sandberg@arm.com      case L3_PWRON_LO:
8110915Sandreas.sandberg@arm.com      case L3_PWRON_HI: {
8210915Sandreas.sandberg@arm.com          const RegAddr ready_reg(SHADER_READY_LO +
8310915Sandreas.sandberg@arm.com                                  (addr.value - SHADER_PWRON_LO));
8410915Sandreas.sandberg@arm.com          const RegAddr present_reg(SHADER_PRESENT_LO +
8510915Sandreas.sandberg@arm.com                                    (addr.value - SHADER_PWRON_LO));
8610915Sandreas.sandberg@arm.com
8710915Sandreas.sandberg@arm.com          regs[ready_reg] |= value & regs[present_reg];
8810915Sandreas.sandberg@arm.com          raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL);
8910915Sandreas.sandberg@arm.com      } break;
9010915Sandreas.sandberg@arm.com
9110915Sandreas.sandberg@arm.com      case SHADER_PWROFF_LO:
9210915Sandreas.sandberg@arm.com      case SHADER_PWROFF_HI:
9310915Sandreas.sandberg@arm.com      case TILER_PWROFF_LO:
9410915Sandreas.sandberg@arm.com      case TILER_PWROFF_HI:
9510915Sandreas.sandberg@arm.com      case L2_PWROFF_LO:
9610915Sandreas.sandberg@arm.com      case L2_PWROFF_HI:
9710915Sandreas.sandberg@arm.com      case L3_PWROFF_LO:
9810915Sandreas.sandberg@arm.com      case L3_PWROFF_HI: {
9910915Sandreas.sandberg@arm.com          const RegAddr ready_reg(SHADER_READY_LO +
10010915Sandreas.sandberg@arm.com                                  (addr.value - SHADER_PWROFF_LO));
10110915Sandreas.sandberg@arm.com
10210915Sandreas.sandberg@arm.com          regs[ready_reg] &= ~value;
10310915Sandreas.sandberg@arm.com          raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL);
10410915Sandreas.sandberg@arm.com      } break;
10510915Sandreas.sandberg@arm.com
10610915Sandreas.sandberg@arm.com      default:
10710915Sandreas.sandberg@arm.com        // Ignore writes by default
10810915Sandreas.sandberg@arm.com        break;
10910915Sandreas.sandberg@arm.com    };
11010915Sandreas.sandberg@arm.com}
11110915Sandreas.sandberg@arm.com
11210915Sandreas.sandberg@arm.comvoid
11310915Sandreas.sandberg@arm.comGPUControl::onInterrupt(int set)
11410915Sandreas.sandberg@arm.com{
11510915Sandreas.sandberg@arm.com    gpu.intGPU(set);
11610915Sandreas.sandberg@arm.com}
11710915Sandreas.sandberg@arm.com
11810915Sandreas.sandberg@arm.comvoid
11910915Sandreas.sandberg@arm.comGPUControl::gpuCommand(uint32_t cmd)
12010915Sandreas.sandberg@arm.com{
12110915Sandreas.sandberg@arm.com    if (cmd < cmds.size())
12210915Sandreas.sandberg@arm.com        (this->*cmds[cmd])(cmd);
12310915Sandreas.sandberg@arm.com}
12410915Sandreas.sandberg@arm.com
12510915Sandreas.sandberg@arm.comvoid
12610915Sandreas.sandberg@arm.comGPUControl::cmdNop(uint32_t cmd)
12710915Sandreas.sandberg@arm.com{
12810915Sandreas.sandberg@arm.com}
12910915Sandreas.sandberg@arm.com
13010915Sandreas.sandberg@arm.comvoid
13110915Sandreas.sandberg@arm.comGPUControl::cmdHardReset(uint32_t cmd)
13210915Sandreas.sandberg@arm.com{
13310915Sandreas.sandberg@arm.com    gpu.reset();
13410915Sandreas.sandberg@arm.com    raiseInterrupt(RESET_COMPLETED);
13510915Sandreas.sandberg@arm.com}
13610915Sandreas.sandberg@arm.com
13710915Sandreas.sandberg@arm.comvoid
13810915Sandreas.sandberg@arm.comGPUControl::cmdSoftReset(uint32_t cmd)
13910915Sandreas.sandberg@arm.com{
14010915Sandreas.sandberg@arm.com    gpu.reset();
14110915Sandreas.sandberg@arm.com    raiseInterrupt(RESET_COMPLETED);
14210915Sandreas.sandberg@arm.com}
14310915Sandreas.sandberg@arm.com
14410915Sandreas.sandberg@arm.comvoid
14510915Sandreas.sandberg@arm.comGPUControl::cmdPerfCntClear(uint32_t cmd)
14610915Sandreas.sandberg@arm.com{
14710915Sandreas.sandberg@arm.com}
14810915Sandreas.sandberg@arm.com
14910915Sandreas.sandberg@arm.comvoid
15010915Sandreas.sandberg@arm.comGPUControl::cmdPerfCntSample(uint32_t cmd)
15110915Sandreas.sandberg@arm.com{
15210915Sandreas.sandberg@arm.com    raiseInterrupt(PRFCNT_SAMPLE_COMPLETED);
15310915Sandreas.sandberg@arm.com}
15410915Sandreas.sandberg@arm.com
15510915Sandreas.sandberg@arm.comvoid
15610915Sandreas.sandberg@arm.comGPUControl::cmdCycleCountStart(uint32_t cmd)
15710915Sandreas.sandberg@arm.com{
15810915Sandreas.sandberg@arm.com}
15910915Sandreas.sandberg@arm.com
16010915Sandreas.sandberg@arm.comvoid
16110915Sandreas.sandberg@arm.comGPUControl::cmdCycleCountStop(uint32_t cmd)
16210915Sandreas.sandberg@arm.com{
16310915Sandreas.sandberg@arm.com}
16410915Sandreas.sandberg@arm.com
16510915Sandreas.sandberg@arm.comvoid
16610915Sandreas.sandberg@arm.comGPUControl::cmdCleanCaches(uint32_t cmd)
16710915Sandreas.sandberg@arm.com{
16810915Sandreas.sandberg@arm.com    raiseInterrupt(CLEAN_CACHES_COMPLETED);
16910915Sandreas.sandberg@arm.com}
17010915Sandreas.sandberg@arm.com
17110915Sandreas.sandberg@arm.comvoid
17210915Sandreas.sandberg@arm.comGPUControl::cmdCleanInvCaches(uint32_t cmd)
17310915Sandreas.sandberg@arm.com{
17410915Sandreas.sandberg@arm.com    raiseInterrupt(CLEAN_CACHES_COMPLETED);
17510915Sandreas.sandberg@arm.com}
17610915Sandreas.sandberg@arm.com
17710915Sandreas.sandberg@arm.com}
178