178 lines
4 KiB
C++
178 lines
4 KiB
C++
|
/*
|
||
|
* Copyright (c) 2014-2015 ARM Limited
|
||
|
* All rights reserved
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* Authors: Andreas Sandberg
|
||
|
*/
|
||
|
|
||
|
#include "gpucontrol.hh"
|
||
|
#include "gpu.hh"
|
||
|
#include "regutils.hh"
|
||
|
|
||
|
namespace NoMali {
|
||
|
|
||
|
typedef void (GPUControl::*GpuCmdHandler)(uint32_t);
|
||
|
|
||
|
const std::vector<GpuCmdHandler> GPUControl::cmds {
|
||
|
&GPUControl::cmdNop, // GPU_COMMAND_NOP
|
||
|
&GPUControl::cmdSoftReset, // GPU_COMMAND_SOFT_RESET
|
||
|
&GPUControl::cmdHardReset, // GPU_COMMAND_HARD_RESET
|
||
|
&GPUControl::cmdPerfCntClear, // GPU_COMMAND_PRFCNT_CLEAR
|
||
|
&GPUControl::cmdPerfCntSample, // GPU_COMMAND_PRFCNT_SAMPLE
|
||
|
&GPUControl::cmdCycleCountStart, // GPU_COMMAND_CYCLE_COUNT_START
|
||
|
&GPUControl::cmdCycleCountStop, // GPU_COMMAND_COUNT_STOP
|
||
|
&GPUControl::cmdCleanCaches, // GPU_COMMAND_CLEAN_CACHES
|
||
|
&GPUControl::cmdCleanInvCaches, // GPU_COMMAND_CLEAN_INV_CACHES
|
||
|
};
|
||
|
|
||
|
GPUControl::GPUControl(GPU &_gpu)
|
||
|
: GPUBlockInt(_gpu,
|
||
|
RegAddr(GPU_IRQ_RAWSTAT),
|
||
|
RegAddr(GPU_IRQ_CLEAR),
|
||
|
RegAddr(GPU_IRQ_MASK),
|
||
|
RegAddr(GPU_IRQ_STATUS))
|
||
|
{
|
||
|
}
|
||
|
|
||
|
GPUControl::~GPUControl()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::reset()
|
||
|
{
|
||
|
GPUBlock::reset();
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::writeReg(RegAddr addr, uint32_t value)
|
||
|
{
|
||
|
switch (addr.value) {
|
||
|
case GPU_IRQ_RAWSTAT:
|
||
|
case GPU_IRQ_CLEAR:
|
||
|
case GPU_IRQ_MASK:
|
||
|
case GPU_IRQ_STATUS:
|
||
|
GPUBlockInt::writeReg(addr, value);
|
||
|
break;
|
||
|
|
||
|
case GPU_COMMAND:
|
||
|
gpuCommand(value);
|
||
|
break;
|
||
|
|
||
|
case SHADER_PWRON_LO:
|
||
|
case SHADER_PWRON_HI:
|
||
|
case TILER_PWRON_LO:
|
||
|
case TILER_PWRON_HI:
|
||
|
case L2_PWRON_LO:
|
||
|
case L2_PWRON_HI:
|
||
|
case L3_PWRON_LO:
|
||
|
case L3_PWRON_HI: {
|
||
|
const RegAddr ready_reg(SHADER_READY_LO +
|
||
|
(addr.value - SHADER_PWRON_LO));
|
||
|
const RegAddr present_reg(SHADER_PRESENT_LO +
|
||
|
(addr.value - SHADER_PWRON_LO));
|
||
|
|
||
|
regs[ready_reg] |= value & regs[present_reg];
|
||
|
raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL);
|
||
|
} break;
|
||
|
|
||
|
case SHADER_PWROFF_LO:
|
||
|
case SHADER_PWROFF_HI:
|
||
|
case TILER_PWROFF_LO:
|
||
|
case TILER_PWROFF_HI:
|
||
|
case L2_PWROFF_LO:
|
||
|
case L2_PWROFF_HI:
|
||
|
case L3_PWROFF_LO:
|
||
|
case L3_PWROFF_HI: {
|
||
|
const RegAddr ready_reg(SHADER_READY_LO +
|
||
|
(addr.value - SHADER_PWROFF_LO));
|
||
|
|
||
|
regs[ready_reg] &= ~value;
|
||
|
raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL);
|
||
|
} break;
|
||
|
|
||
|
default:
|
||
|
// Ignore writes by default
|
||
|
break;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::onInterrupt(int set)
|
||
|
{
|
||
|
gpu.intGPU(set);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::gpuCommand(uint32_t cmd)
|
||
|
{
|
||
|
if (cmd < cmds.size())
|
||
|
(this->*cmds[cmd])(cmd);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdNop(uint32_t cmd)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdHardReset(uint32_t cmd)
|
||
|
{
|
||
|
gpu.reset();
|
||
|
raiseInterrupt(RESET_COMPLETED);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdSoftReset(uint32_t cmd)
|
||
|
{
|
||
|
gpu.reset();
|
||
|
raiseInterrupt(RESET_COMPLETED);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdPerfCntClear(uint32_t cmd)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdPerfCntSample(uint32_t cmd)
|
||
|
{
|
||
|
raiseInterrupt(PRFCNT_SAMPLE_COMPLETED);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdCycleCountStart(uint32_t cmd)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdCycleCountStop(uint32_t cmd)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdCleanCaches(uint32_t cmd)
|
||
|
{
|
||
|
raiseInterrupt(CLEAN_CACHES_COMPLETED);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
GPUControl::cmdCleanInvCaches(uint32_t cmd)
|
||
|
{
|
||
|
raiseInterrupt(CLEAN_CACHES_COMPLETED);
|
||
|
}
|
||
|
|
||
|
}
|