2 * Copyright (c) 2014-2015 ARM Limited
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 * Authors: Andreas Sandberg
20 #include "jobcontrol.hh"
23 #include "regutils.hh"
27 JobControl::JobControl(GPU
&_gpu
)
29 RegAddr(JOB_IRQ_RAWSTAT
),
30 RegAddr(JOB_IRQ_CLEAR
),
31 RegAddr(JOB_IRQ_MASK
),
32 RegAddr(JOB_IRQ_STATUS
))
35 for (int i
= 0; i
< 16; ++i
)
36 slots
.emplace_back(_gpu
, *this, i
);
40 JobControl::~JobControl()
49 for (auto &js
: slots
)
54 JobControl::readReg(RegAddr addr
)
56 if (addr
>= RegAddr(JOB_SLOT0
)) {
57 return slots
[getJobSlotNo(addr
)].readReg(getJobSlotAddr(addr
));
59 return GPUBlockInt::readReg(addr
);
64 JobControl::writeReg(RegAddr addr
, uint32_t value
)
68 // Update JS state for all jobs that were affected by the IRQ
70 updateJsState((value
& 0xFFFF) | ((value
& 0xFFFF0000) >> 16));
72 // FALLTHROUGH - IRQ handling in base class
76 GPUBlockInt::writeReg(addr
, value
);
80 if (addr
>= RegAddr(JOB_SLOT0
))
81 slots
[getJobSlotNo(addr
)].writeReg(getJobSlotAddr(addr
), value
);
87 JobControl::readRegRaw(RegAddr addr
)
89 if (addr
>= RegAddr(JOB_SLOT0
)) {
90 return slots
[getJobSlotNo(addr
)].readRegRaw(getJobSlotAddr(addr
));
92 return GPUBlockInt::readRegRaw(addr
);
98 JobControl::writeRegRaw(RegAddr addr
, uint32_t value
)
100 if (addr
>= RegAddr(JOB_SLOT0
)) {
101 slots
[getJobSlotNo(addr
)].writeRegRaw(getJobSlotAddr(addr
), value
);
103 GPUBlockInt::writeRegRaw(addr
, value
);
108 JobControl::jobDone(uint8_t slot
)
111 raiseInterrupt(1 << slot
);
115 JobControl::jobFailed(uint8_t slot
)
118 raiseInterrupt(0x10000 << slot
);
122 JobControl::updateJsState(uint16_t jobs
)
124 // The JS_STATE register contains two bits per job slot; one bit
125 // representing an active job and one bit representing the queued
126 // job. We need to mask out bits of the jobs affected by this update.
127 const uint32_t job_mask(jobs
| (jobs
<< 16));
128 uint16_t js_state(regs
[RegAddr(JOB_IRQ_JS_STATE
)] & ~job_mask
);
130 // Find if there is an active or active next job for all jobs in
132 for (int i
= 0; i
< 16; ++i
) {
133 const JobSlot
&slot(slots
[i
]);
134 if (jobs
& (1 << i
)) {
135 js_state
|= slot
.active() ? (1 << i
) : 0 |
136 slot
.activeNext() ? (0x10000 << i
) : 0;
139 regs
[RegAddr(JOB_IRQ_JS_STATE
)] = js_state
;
143 JobControl::onInterrupt(int set
)