110915Sandreas.sandberg@arm.com/*
210915Sandreas.sandberg@arm.com * Copyright (c) 2014-2015 ARM Limited
310915Sandreas.sandberg@arm.com * All rights reserved
410915Sandreas.sandberg@arm.com *
510915Sandreas.sandberg@arm.com * Licensed under the Apache License, Version 2.0 (the "License");
610915Sandreas.sandberg@arm.com * you may not use this file except in compliance with the License.
710915Sandreas.sandberg@arm.com * You may obtain a copy of the License at
810915Sandreas.sandberg@arm.com *
910915Sandreas.sandberg@arm.com *     http://www.apache.org/licenses/LICENSE-2.0
1010915Sandreas.sandberg@arm.com *
1110915Sandreas.sandberg@arm.com * Unless required by applicable law or agreed to in writing, software
1210915Sandreas.sandberg@arm.com * distributed under the License is distributed on an "AS IS" BASIS,
1310915Sandreas.sandberg@arm.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1410915Sandreas.sandberg@arm.com * See the License for the specific language governing permissions and
1510915Sandreas.sandberg@arm.com * limitations under the License.
1610915Sandreas.sandberg@arm.com *
1710915Sandreas.sandberg@arm.com * Authors: Andreas Sandberg
1810915Sandreas.sandberg@arm.com */
1910915Sandreas.sandberg@arm.com
2010915Sandreas.sandberg@arm.com#include "jobcontrol.hh"
2110915Sandreas.sandberg@arm.com
2210915Sandreas.sandberg@arm.com#include "gpu.hh"
2310915Sandreas.sandberg@arm.com#include "regutils.hh"
2410915Sandreas.sandberg@arm.com
2510915Sandreas.sandberg@arm.comnamespace NoMali {
2610915Sandreas.sandberg@arm.com
2710915Sandreas.sandberg@arm.comJobControl::JobControl(GPU &_gpu)
2810915Sandreas.sandberg@arm.com    : GPUBlockInt(_gpu,
2910915Sandreas.sandberg@arm.com                  RegAddr(JOB_IRQ_RAWSTAT),
3010915Sandreas.sandberg@arm.com                  RegAddr(JOB_IRQ_CLEAR),
3110915Sandreas.sandberg@arm.com                  RegAddr(JOB_IRQ_MASK),
3210915Sandreas.sandberg@arm.com                  RegAddr(JOB_IRQ_STATUS))
3310915Sandreas.sandberg@arm.com{
3410915Sandreas.sandberg@arm.com    slots.reserve(16);
3510915Sandreas.sandberg@arm.com    for (int i = 0; i < 16; ++i)
3610915Sandreas.sandberg@arm.com        slots.emplace_back(_gpu, *this, i);
3710915Sandreas.sandberg@arm.com
3810915Sandreas.sandberg@arm.com}
3910915Sandreas.sandberg@arm.com
4010915Sandreas.sandberg@arm.comJobControl::~JobControl()
4110915Sandreas.sandberg@arm.com{
4210915Sandreas.sandberg@arm.com}
4310915Sandreas.sandberg@arm.com
4411313Sandreas.sandberg@arm.comvoid
4511313Sandreas.sandberg@arm.comJobControl::reset()
4611313Sandreas.sandberg@arm.com{
4711313Sandreas.sandberg@arm.com    GPUBlockInt::reset();
4811313Sandreas.sandberg@arm.com
4911313Sandreas.sandberg@arm.com    for (auto &js : slots)
5011313Sandreas.sandberg@arm.com        js.reset();
5111313Sandreas.sandberg@arm.com}
5211313Sandreas.sandberg@arm.com
5310915Sandreas.sandberg@arm.comuint32_t
5410915Sandreas.sandberg@arm.comJobControl::readReg(RegAddr addr)
5510915Sandreas.sandberg@arm.com{
5610915Sandreas.sandberg@arm.com    if (addr >= RegAddr(JOB_SLOT0)) {
5710915Sandreas.sandberg@arm.com        return slots[getJobSlotNo(addr)].readReg(getJobSlotAddr(addr));
5810915Sandreas.sandberg@arm.com    } else {
5910915Sandreas.sandberg@arm.com        return GPUBlockInt::readReg(addr);
6010915Sandreas.sandberg@arm.com    }
6110915Sandreas.sandberg@arm.com}
6210915Sandreas.sandberg@arm.com
6310915Sandreas.sandberg@arm.comvoid
6410915Sandreas.sandberg@arm.comJobControl::writeReg(RegAddr addr, uint32_t value)
6510915Sandreas.sandberg@arm.com{
6610915Sandreas.sandberg@arm.com    switch(addr.value) {
6710915Sandreas.sandberg@arm.com      case JOB_IRQ_CLEAR:
6810915Sandreas.sandberg@arm.com        // Update JS state for all jobs that were affected by the IRQ
6910915Sandreas.sandberg@arm.com        // clear
7010915Sandreas.sandberg@arm.com        updateJsState((value & 0xFFFF) | ((value & 0xFFFF0000) >> 16));
7110915Sandreas.sandberg@arm.com
7210915Sandreas.sandberg@arm.com        // FALLTHROUGH - IRQ handling in base class
7310915Sandreas.sandberg@arm.com      case JOB_IRQ_RAWSTAT:
7410915Sandreas.sandberg@arm.com      case JOB_IRQ_MASK:
7510915Sandreas.sandberg@arm.com      case JOB_IRQ_STATUS:
7610915Sandreas.sandberg@arm.com        GPUBlockInt::writeReg(addr, value);
7710915Sandreas.sandberg@arm.com        break;
7810915Sandreas.sandberg@arm.com
7910915Sandreas.sandberg@arm.com      default:
8010915Sandreas.sandberg@arm.com        if (addr >= RegAddr(JOB_SLOT0))
8110915Sandreas.sandberg@arm.com            slots[getJobSlotNo(addr)].writeReg(getJobSlotAddr(addr), value);
8210915Sandreas.sandberg@arm.com        break;
8310915Sandreas.sandberg@arm.com    }
8410915Sandreas.sandberg@arm.com}
8510915Sandreas.sandberg@arm.com
8610915Sandreas.sandberg@arm.comuint32_t
8710915Sandreas.sandberg@arm.comJobControl::readRegRaw(RegAddr addr)
8810915Sandreas.sandberg@arm.com{
8910915Sandreas.sandberg@arm.com    if (addr >= RegAddr(JOB_SLOT0)) {
9010915Sandreas.sandberg@arm.com        return slots[getJobSlotNo(addr)].readRegRaw(getJobSlotAddr(addr));
9110915Sandreas.sandberg@arm.com    } else {
9210915Sandreas.sandberg@arm.com        return GPUBlockInt::readRegRaw(addr);
9310915Sandreas.sandberg@arm.com    }
9410915Sandreas.sandberg@arm.com}
9510915Sandreas.sandberg@arm.com
9610915Sandreas.sandberg@arm.com
9710915Sandreas.sandberg@arm.comvoid
9810915Sandreas.sandberg@arm.comJobControl::writeRegRaw(RegAddr addr, uint32_t value)
9910915Sandreas.sandberg@arm.com{
10010915Sandreas.sandberg@arm.com    if (addr >= RegAddr(JOB_SLOT0)) {
10110915Sandreas.sandberg@arm.com        slots[getJobSlotNo(addr)].writeRegRaw(getJobSlotAddr(addr), value);
10210915Sandreas.sandberg@arm.com    } else {
10310915Sandreas.sandberg@arm.com        GPUBlockInt::writeRegRaw(addr, value);
10410915Sandreas.sandberg@arm.com    }
10510915Sandreas.sandberg@arm.com}
10610915Sandreas.sandberg@arm.com
10710915Sandreas.sandberg@arm.comvoid
10810915Sandreas.sandberg@arm.comJobControl::jobDone(uint8_t slot)
10910915Sandreas.sandberg@arm.com{
11010915Sandreas.sandberg@arm.com    assert(slot <= 15);
11110915Sandreas.sandberg@arm.com    raiseInterrupt(1 << slot);
11210915Sandreas.sandberg@arm.com}
11310915Sandreas.sandberg@arm.com
11410915Sandreas.sandberg@arm.comvoid
11510915Sandreas.sandberg@arm.comJobControl::jobFailed(uint8_t slot)
11610915Sandreas.sandberg@arm.com{
11710915Sandreas.sandberg@arm.com    assert(slot <= 15);
11810915Sandreas.sandberg@arm.com    raiseInterrupt(0x10000 << slot);
11910915Sandreas.sandberg@arm.com}
12010915Sandreas.sandberg@arm.com
12110915Sandreas.sandberg@arm.comvoid
12210915Sandreas.sandberg@arm.comJobControl::updateJsState(uint16_t jobs)
12310915Sandreas.sandberg@arm.com{
12410915Sandreas.sandberg@arm.com    // The JS_STATE register contains two bits per job slot; one bit
12510915Sandreas.sandberg@arm.com    // representing an active job and one bit representing the queued
12610915Sandreas.sandberg@arm.com    // job. We need to mask out bits of the jobs affected by this update.
12710915Sandreas.sandberg@arm.com    const uint32_t job_mask(jobs | (jobs << 16));
12810915Sandreas.sandberg@arm.com    uint16_t js_state(regs[RegAddr(JOB_IRQ_JS_STATE)] & ~job_mask);
12910915Sandreas.sandberg@arm.com
13010915Sandreas.sandberg@arm.com    // Find if there is an active or active next job for all jobs in
13110915Sandreas.sandberg@arm.com    // the job mask.
13210915Sandreas.sandberg@arm.com    for (int i = 0; i < 16; ++i) {
13310915Sandreas.sandberg@arm.com        const JobSlot &slot(slots[i]);
13410915Sandreas.sandberg@arm.com        if (jobs & (1 << i)) {
13510915Sandreas.sandberg@arm.com            js_state |= slot.active() ? (1 << i) : 0 |
13610915Sandreas.sandberg@arm.com                slot.activeNext() ? (0x10000 << i) : 0;
13710915Sandreas.sandberg@arm.com        }
13810915Sandreas.sandberg@arm.com    }
13910915Sandreas.sandberg@arm.com    regs[RegAddr(JOB_IRQ_JS_STATE)] = js_state;
14010915Sandreas.sandberg@arm.com}
14110915Sandreas.sandberg@arm.com
14210915Sandreas.sandberg@arm.comvoid
14310915Sandreas.sandberg@arm.comJobControl::onInterrupt(int set)
14410915Sandreas.sandberg@arm.com{
14510915Sandreas.sandberg@arm.com    gpu.intJob(set);
14610915Sandreas.sandberg@arm.com}
14710915Sandreas.sandberg@arm.com
14810915Sandreas.sandberg@arm.com}
149