/*
 * Copyright (c) 2014-2015 ARM Limited
 * All rights reserved
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Authors: Andreas Sandberg
 */

#include "jobcontrol.hh"

#include "gpu.hh"
#include "regutils.hh"

namespace NoMali {

JobControl::JobControl(GPU &_gpu)
    : GPUBlockInt(_gpu,
                  RegAddr(JOB_IRQ_RAWSTAT),
                  RegAddr(JOB_IRQ_CLEAR),
                  RegAddr(JOB_IRQ_MASK),
                  RegAddr(JOB_IRQ_STATUS))
{
    slots.reserve(16);
    for (int i = 0; i < 16; ++i)
        slots.emplace_back(_gpu, *this, i);

}

JobControl::~JobControl()
{
}

void
JobControl::reset()
{
    GPUBlockInt::reset();

    for (auto &js : slots)
        js.reset();
}

uint32_t
JobControl::readReg(RegAddr addr)
{
    if (addr >= RegAddr(JOB_SLOT0)) {
        return slots[getJobSlotNo(addr)].readReg(getJobSlotAddr(addr));
    } else {
        return GPUBlockInt::readReg(addr);
    }
}

void
JobControl::writeReg(RegAddr addr, uint32_t value)
{
    switch(addr.value) {
      case JOB_IRQ_CLEAR:
        // Update JS state for all jobs that were affected by the IRQ
        // clear
        updateJsState((value & 0xFFFF) | ((value & 0xFFFF0000) >> 16));

        // FALLTHROUGH - IRQ handling in base class
      case JOB_IRQ_RAWSTAT:
      case JOB_IRQ_MASK:
      case JOB_IRQ_STATUS:
        GPUBlockInt::writeReg(addr, value);
        break;

      default:
        if (addr >= RegAddr(JOB_SLOT0))
            slots[getJobSlotNo(addr)].writeReg(getJobSlotAddr(addr), value);
        break;
    }
}

uint32_t
JobControl::readRegRaw(RegAddr addr)
{
    if (addr >= RegAddr(JOB_SLOT0)) {
        return slots[getJobSlotNo(addr)].readRegRaw(getJobSlotAddr(addr));
    } else {
        return GPUBlockInt::readRegRaw(addr);
    }
}


void
JobControl::writeRegRaw(RegAddr addr, uint32_t value)
{
    if (addr >= RegAddr(JOB_SLOT0)) {
        slots[getJobSlotNo(addr)].writeRegRaw(getJobSlotAddr(addr), value);
    } else {
        GPUBlockInt::writeRegRaw(addr, value);
    }
}

void
JobControl::jobDone(uint8_t slot)
{
    assert(slot <= 15);
    raiseInterrupt(1 << slot);
}

void
JobControl::jobFailed(uint8_t slot)
{
    assert(slot <= 15);
    raiseInterrupt(0x10000 << slot);
}

void
JobControl::updateJsState(uint16_t jobs)
{
    // The JS_STATE register contains two bits per job slot; one bit
    // representing an active job and one bit representing the queued
    // job. We need to mask out bits of the jobs affected by this update.
    const uint32_t job_mask(jobs | (jobs << 16));
    uint16_t js_state(regs[RegAddr(JOB_IRQ_JS_STATE)] & ~job_mask);

    // Find if there is an active or active next job for all jobs in
    // the job mask.
    for (int i = 0; i < 16; ++i) {
        const JobSlot &slot(slots[i]);
        if (jobs & (1 << i)) {
            js_state |= slot.active() ? (1 << i) : 0 |
                slot.activeNext() ? (0x10000 << i) : 0;
        }
    }
    regs[RegAddr(JOB_IRQ_JS_STATE)] = js_state;
}

void
JobControl::onInterrupt(int set)
{
    gpu.intJob(set);
}

}
