jobcontrol.cc revision 10915
11689SN/A/*
22325SN/A * Copyright (c) 2014-2015 ARM Limited
31689SN/A * All rights reserved
41689SN/A *
51689SN/A * Licensed under the Apache License, Version 2.0 (the "License");
61689SN/A * you may not use this file except in compliance with the License.
71689SN/A * You may obtain a copy of the License at
81689SN/A *
91689SN/A *     http://www.apache.org/licenses/LICENSE-2.0
101689SN/A *
111689SN/A * Unless required by applicable law or agreed to in writing, software
121689SN/A * distributed under the License is distributed on an "AS IS" BASIS,
131689SN/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
141689SN/A * See the License for the specific language governing permissions and
151689SN/A * limitations under the License.
161689SN/A *
171689SN/A * Authors: Andreas Sandberg
181689SN/A */
191689SN/A
201689SN/A#include "jobcontrol.hh"
211689SN/A
221689SN/A#include "gpu.hh"
231689SN/A#include "regutils.hh"
241689SN/A
251689SN/Anamespace NoMali {
261689SN/A
272665Ssaidi@eecs.umich.eduJobControl::JobControl(GPU &_gpu)
282665Ssaidi@eecs.umich.edu    : GPUBlockInt(_gpu,
292756Sksewell@umich.edu                  RegAddr(JOB_IRQ_RAWSTAT),
301689SN/A                  RegAddr(JOB_IRQ_CLEAR),
311689SN/A                  RegAddr(JOB_IRQ_MASK),
321858SN/A                  RegAddr(JOB_IRQ_STATUS))
332733Sktlim@umich.edu{
341858SN/A    slots.reserve(16);
351858SN/A    for (int i = 0; i < 16; ++i)
362356SN/A        slots.emplace_back(_gpu, *this, i);
371060SN/A
381060SN/A}
391060SN/A
401060SN/AJobControl::~JobControl()
411060SN/A{
422325SN/A}
432683Sktlim@umich.edu
442680Sktlim@umich.eduuint32_t
452817Sksewell@umich.eduJobControl::readReg(RegAddr addr)
461717SN/A{
471060SN/A    if (addr >= RegAddr(JOB_SLOT0)) {
484167Sbinkertn@umich.edu        return slots[getJobSlotNo(addr)].readReg(getJobSlotAddr(addr));
492292SN/A    } else {
502292SN/A        return GPUBlockInt::readReg(addr);
512794Sktlim@umich.edu    }
522794Sktlim@umich.edu}
532794Sktlim@umich.edu
542794Sktlim@umich.eduvoid
551060SN/AJobControl::writeReg(RegAddr addr, uint32_t value)
562669Sktlim@umich.edu{
571060SN/A    switch(addr.value) {
582733Sktlim@umich.edu      case JOB_IRQ_CLEAR:
592292SN/A        // Update JS state for all jobs that were affected by the IRQ
601060SN/A        // clear
611060SN/A        updateJsState((value & 0xFFFF) | ((value & 0xFFFF0000) >> 16));
621060SN/A
632292SN/A        // FALLTHROUGH - IRQ handling in base class
642733Sktlim@umich.edu      case JOB_IRQ_RAWSTAT:
652292SN/A      case JOB_IRQ_MASK:
662292SN/A      case JOB_IRQ_STATUS:
672292SN/A        GPUBlockInt::writeReg(addr, value);
682292SN/A        break;
691060SN/A
701755SN/A      default:
711060SN/A        if (addr >= RegAddr(JOB_SLOT0))
721060SN/A            slots[getJobSlotNo(addr)].writeReg(getJobSlotAddr(addr), value);
731060SN/A        break;
741060SN/A    }
751060SN/A}
761060SN/A
771755SN/Auint32_t
781060SN/AJobControl::readRegRaw(RegAddr addr)
791060SN/A{
801060SN/A    if (addr >= RegAddr(JOB_SLOT0)) {
811060SN/A        return slots[getJobSlotNo(addr)].readRegRaw(getJobSlotAddr(addr));
821060SN/A    } else {
831060SN/A        return GPUBlockInt::readRegRaw(addr);
841755SN/A    }
851060SN/A}
864873Sstever@eecs.umich.edu
871060SN/A
881060SN/Avoid
891060SN/AJobControl::writeRegRaw(RegAddr addr, uint32_t value)
902829Sksewell@umich.edu{
913221Sktlim@umich.edu    if (addr >= RegAddr(JOB_SLOT0)) {
922829Sksewell@umich.edu        slots[getJobSlotNo(addr)].writeRegRaw(getJobSlotAddr(addr), value);
932829Sksewell@umich.edu    } else {
942829Sksewell@umich.edu        GPUBlockInt::writeRegRaw(addr, value);
952829Sksewell@umich.edu    }
962829Sksewell@umich.edu}
972829Sksewell@umich.edu
982829Sksewell@umich.eduvoid
992829Sksewell@umich.eduJobControl::jobDone(uint8_t slot)
1002829Sksewell@umich.edu{
1012829Sksewell@umich.edu    assert(slot <= 15);
1022829Sksewell@umich.edu    raiseInterrupt(1 << slot);
1032829Sksewell@umich.edu}
1042829Sksewell@umich.edu
1052829Sksewell@umich.eduvoid
1062829Sksewell@umich.eduJobControl::jobFailed(uint8_t slot)
1072829Sksewell@umich.edu{
1082829Sksewell@umich.edu    assert(slot <= 15);
1092829Sksewell@umich.edu    raiseInterrupt(0x10000 << slot);
1102829Sksewell@umich.edu}
1112829Sksewell@umich.edu
1122829Sksewell@umich.eduvoid
1132829Sksewell@umich.eduJobControl::updateJsState(uint16_t jobs)
1142829Sksewell@umich.edu{
1154873Sstever@eecs.umich.edu    // The JS_STATE register contains two bits per job slot; one bit
1162829Sksewell@umich.edu    // representing an active job and one bit representing the queued
1172829Sksewell@umich.edu    // job. We need to mask out bits of the jobs affected by this update.
1182829Sksewell@umich.edu    const uint32_t job_mask(jobs | (jobs << 16));
1192875Sksewell@umich.edu    uint16_t js_state(regs[RegAddr(JOB_IRQ_JS_STATE)] & ~job_mask);
1203859Sbinkertn@umich.edu
1212875Sksewell@umich.edu    // Find if there is an active or active next job for all jobs in
1222875Sksewell@umich.edu    // the job mask.
1232875Sksewell@umich.edu    for (int i = 0; i < 16; ++i) {
1242875Sksewell@umich.edu        const JobSlot &slot(slots[i]);
1252875Sksewell@umich.edu        if (jobs & (1 << i)) {
1262875Sksewell@umich.edu            js_state |= slot.active() ? (1 << i) : 0 |
1273859Sbinkertn@umich.edu                slot.activeNext() ? (0x10000 << i) : 0;
1282875Sksewell@umich.edu        }
1292875Sksewell@umich.edu    }
1302875Sksewell@umich.edu    regs[RegAddr(JOB_IRQ_JS_STATE)] = js_state;
1313859Sbinkertn@umich.edu}
1322875Sksewell@umich.edu
1332875Sksewell@umich.eduvoid
1342875Sksewell@umich.eduJobControl::onInterrupt(int set)
1352875Sksewell@umich.edu{
1362875Sksewell@umich.edu    gpu.intJob(set);
1372875Sksewell@umich.edu}
1382875Sksewell@umich.edu
1393221Sktlim@umich.edu}
1403221Sktlim@umich.edu