| /* | |
| * 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); | |
| } | |
| } |