1/*
2 * Copyright (c) 2014-2015 ARM Limited
3 * All rights reserved
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 * Authors: Andreas Sandberg
18 */
19
20#include "gpucontrol.hh"
21#include "gpu.hh"
22#include "regutils.hh"
23
24namespace NoMali {
25
26typedef void (GPUControl::*GpuCmdHandler)(uint32_t);
27
28const std::vector<GpuCmdHandler> GPUControl::cmds {
29    &GPUControl::cmdNop,                     // GPU_COMMAND_NOP
30    &GPUControl::cmdSoftReset,               // GPU_COMMAND_SOFT_RESET
31    &GPUControl::cmdHardReset,               // GPU_COMMAND_HARD_RESET
32    &GPUControl::cmdPerfCntClear,            // GPU_COMMAND_PRFCNT_CLEAR
33    &GPUControl::cmdPerfCntSample,           // GPU_COMMAND_PRFCNT_SAMPLE
34    &GPUControl::cmdCycleCountStart,         // GPU_COMMAND_CYCLE_COUNT_START
35    &GPUControl::cmdCycleCountStop,          // GPU_COMMAND_COUNT_STOP
36    &GPUControl::cmdCleanCaches,             // GPU_COMMAND_CLEAN_CACHES
37    &GPUControl::cmdCleanInvCaches,          // GPU_COMMAND_CLEAN_INV_CACHES
38};
39
40GPUControl::GPUControl(GPU &_gpu)
41    : GPUBlockInt(_gpu,
42                  RegAddr(GPU_IRQ_RAWSTAT),
43                  RegAddr(GPU_IRQ_CLEAR),
44                  RegAddr(GPU_IRQ_MASK),
45                  RegAddr(GPU_IRQ_STATUS))
46{
47}
48
49GPUControl::~GPUControl()
50{
51}
52
53void
54GPUControl::reset()
55{
56    GPUBlock::reset();
57}
58
59void
60GPUControl::writeReg(RegAddr addr, uint32_t value)
61{
62    switch (addr.value) {
63      case GPU_IRQ_RAWSTAT:
64      case GPU_IRQ_CLEAR:
65      case GPU_IRQ_MASK:
66      case GPU_IRQ_STATUS:
67        GPUBlockInt::writeReg(addr, value);
68        break;
69
70      case GPU_COMMAND:
71        gpuCommand(value);
72        break;
73
74      case SHADER_PWRON_LO:
75      case SHADER_PWRON_HI:
76      case TILER_PWRON_LO:
77      case TILER_PWRON_HI:
78      case L2_PWRON_LO:
79      case L2_PWRON_HI:
80      case L3_PWRON_LO:
81      case L3_PWRON_HI: {
82          const RegAddr ready_reg(SHADER_READY_LO +
83                                  (addr.value - SHADER_PWRON_LO));
84          const RegAddr present_reg(SHADER_PRESENT_LO +
85                                    (addr.value - SHADER_PWRON_LO));
86
87          regs[ready_reg] |= value & regs[present_reg];
88          raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL);
89      } break;
90
91      case SHADER_PWROFF_LO:
92      case SHADER_PWROFF_HI:
93      case TILER_PWROFF_LO:
94      case TILER_PWROFF_HI:
95      case L2_PWROFF_LO:
96      case L2_PWROFF_HI:
97      case L3_PWROFF_LO:
98      case L3_PWROFF_HI: {
99          const RegAddr ready_reg(SHADER_READY_LO +
100                                  (addr.value - SHADER_PWROFF_LO));
101
102          regs[ready_reg] &= ~value;
103          raiseInterrupt(POWER_CHANGED_SINGLE | POWER_CHANGED_ALL);
104      } break;
105
106      default:
107        // Ignore writes by default
108        break;
109    };
110}
111
112void
113GPUControl::onInterrupt(int set)
114{
115    gpu.intGPU(set);
116}
117
118void
119GPUControl::gpuCommand(uint32_t cmd)
120{
121    if (cmd < cmds.size())
122        (this->*cmds[cmd])(cmd);
123}
124
125void
126GPUControl::cmdNop(uint32_t cmd)
127{
128}
129
130void
131GPUControl::cmdHardReset(uint32_t cmd)
132{
133    gpu.reset();
134    raiseInterrupt(RESET_COMPLETED);
135}
136
137void
138GPUControl::cmdSoftReset(uint32_t cmd)
139{
140    gpu.reset();
141    raiseInterrupt(RESET_COMPLETED);
142}
143
144void
145GPUControl::cmdPerfCntClear(uint32_t cmd)
146{
147}
148
149void
150GPUControl::cmdPerfCntSample(uint32_t cmd)
151{
152    raiseInterrupt(PRFCNT_SAMPLE_COMPLETED);
153}
154
155void
156GPUControl::cmdCycleCountStart(uint32_t cmd)
157{
158}
159
160void
161GPUControl::cmdCycleCountStop(uint32_t cmd)
162{
163}
164
165void
166GPUControl::cmdCleanCaches(uint32_t cmd)
167{
168    raiseInterrupt(CLEAN_CACHES_COMPLETED);
169}
170
171void
172GPUControl::cmdCleanInvCaches(uint32_t cmd)
173{
174    raiseInterrupt(CLEAN_CACHES_COMPLETED);
175}
176
177}
178