summaryrefslogtreecommitdiff
path: root/ext/nomali/lib/gpucontrol.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ext/nomali/lib/gpucontrol.cc')
-rw-r--r--ext/nomali/lib/gpucontrol.cc177
1 files changed, 177 insertions, 0 deletions
diff --git a/ext/nomali/lib/gpucontrol.cc b/ext/nomali/lib/gpucontrol.cc
new file mode 100644
index 000000000..688f5867e
--- /dev/null
+++ b/ext/nomali/lib/gpucontrol.cc
@@ -0,0 +1,177 @@
+/*
+ * 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);
+}
+
+}