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