/*
 * Copyright (c) 2010-2013, 2015, 2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dev/arm/hdlcd.hh"

#include "base/compiler.hh"
#include "base/output.hh"
#include "base/trace.hh"
#include "base/vnc/vncinput.hh"
#include "debug/Checkpoint.hh"
#include "debug/HDLcd.hh"
#include "dev/arm/amba_device.hh"
#include "dev/arm/base_gic.hh"
#include "enums/ImageFormat.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/HDLcd.hh"
#include "sim/system.hh"

using std::vector;

namespace gem5
{

// initialize hdlcd registers
HDLcd::HDLcd(const HDLcdParams &p)
    : AmbaDmaDevice(p, 0xFFFF),
      // Parameters
      vnc(p.vnc),
      workaroundSwapRB(p.workaround_swap_rb),
      workaroundDmaLineCount(p.workaround_dma_line_count),
      addrRanges{RangeSize(pioAddr, pioSize)},
      enableCapture(p.enable_capture),
      pixelBufferSize(p.pixel_buffer_size),
      virtRefreshRate(p.virt_refresh_rate),

      virtRefreshEvent([this]{ virtRefresh(); }, name()),
      // Other
      imgFormat(p.frame_format),
      pixelPump(*this, *p.pxl_clk, p.pixel_chunk),
      stats(this)
{
    if (vnc)
        vnc->setFrameBuffer(&pixelPump.fb);

    imgWriter = createImgWriter(imgFormat, &pixelPump.fb);
}

HDLcd::HDLcdStats::HDLcdStats(statistics::Group *parent)
    : statistics::Group(parent, "HDLcd"),
      ADD_STAT(underruns, statistics::units::Count::get(),
               "Number of buffer underruns")
{
    using namespace statistics;

    underruns.flags(nozero);
}

void
HDLcd::serialize(CheckpointOut &cp) const
{
    DPRINTF(Checkpoint, "Serializing ARM HDLCD\n");

    SERIALIZE_SCALAR(int_rawstat);
    SERIALIZE_SCALAR(int_mask);

    SERIALIZE_SCALAR(fb_base);
    SERIALIZE_SCALAR(fb_line_length);
    SERIALIZE_SCALAR(fb_line_count);
    SERIALIZE_SCALAR(fb_line_pitch);
    SERIALIZE_SCALAR(bus_options);

    SERIALIZE_SCALAR(v_sync);
    SERIALIZE_SCALAR(v_back_porch);
    SERIALIZE_SCALAR(v_data);
    SERIALIZE_SCALAR(v_front_porch);

    SERIALIZE_SCALAR(h_sync);
    SERIALIZE_SCALAR(h_back_porch);
    SERIALIZE_SCALAR(h_data);
    SERIALIZE_SCALAR(h_front_porch);

    SERIALIZE_SCALAR(polarities);

    SERIALIZE_SCALAR(command);
    SERIALIZE_SCALAR(pixel_format);
    SERIALIZE_SCALAR(red_select);
    SERIALIZE_SCALAR(green_select);
    SERIALIZE_SCALAR(blue_select);

    SERIALIZE_OBJ(pixelPump);
    if (enabled())
        dmaEngine->serializeSection(cp, "dmaEngine");
}

void
HDLcd::unserialize(CheckpointIn &cp)
{
    DPRINTF(Checkpoint, "Unserializing ARM HDLCD\n");

    UNSERIALIZE_SCALAR(int_rawstat);
    UNSERIALIZE_SCALAR(int_mask);

    UNSERIALIZE_SCALAR(fb_base);
    UNSERIALIZE_SCALAR(fb_line_length);
    UNSERIALIZE_SCALAR(fb_line_count);
    UNSERIALIZE_SCALAR(fb_line_pitch);
    UNSERIALIZE_SCALAR(bus_options);

    UNSERIALIZE_SCALAR(v_sync);
    UNSERIALIZE_SCALAR(v_back_porch);
    UNSERIALIZE_SCALAR(v_data);
    UNSERIALIZE_SCALAR(v_front_porch);

    UNSERIALIZE_SCALAR(h_sync);
    UNSERIALIZE_SCALAR(h_back_porch);
    UNSERIALIZE_SCALAR(h_data);
    UNSERIALIZE_SCALAR(h_front_porch);

    UNSERIALIZE_SCALAR(polarities);

    UNSERIALIZE_SCALAR(command);
    UNSERIALIZE_SCALAR(pixel_format);
    UNSERIALIZE_SCALAR(red_select);
    UNSERIALIZE_SCALAR(green_select);
    UNSERIALIZE_SCALAR(blue_select);

    {
        // Try to unserialize the pixel pump. It might not exist if
        // we're unserializing an old checkpoint.
        ScopedCheckpointSection sec(cp, "pixelPump");
        if (cp.sectionExists(Serializable::currentSection()))
            pixelPump.unserialize(cp);
    }

    if (enabled()) {
        // Create the DMA engine and read its state from the
        // checkpoint. We don't need to worry about the pixel pump as
        // it is a proper SimObject.
        createDmaEngine();
        dmaEngine->unserializeSection(cp, "dmaEngine");

        conv = pixelConverter();
    }
}

void
HDLcd::drainResume()
{
    AmbaDmaDevice::drainResume();

    if (enabled()) {
        if (sys->bypassCaches()) {
            // We restart the HDLCD if we are in KVM mode. This
            // ensures that we always use the fast refresh logic if we
            // resume in KVM mode.
            cmdDisable();
            cmdEnable();
        } else if (!pixelPump.active()) {
            // We restored from an old checkpoint without a pixel
            // pump, start an new refresh. This typically happens when
            // restoring from old checkpoints.
            cmdEnable();
        }
    }

    // We restored from a checkpoint and need to update the VNC server
    if (pixelPump.active() && vnc)
        vnc->setDirty();
}

void
HDLcd::virtRefresh()
{
    pixelPump.renderFrame();
    schedule(virtRefreshEvent, (curTick() + virtRefreshRate));
}

// read registers and frame buffer
Tick
HDLcd::read(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr &&
           pkt->getAddr() < pioAddr + pioSize);

    const Addr daddr = pkt->getAddr() - pioAddr;
    panic_if(pkt->getSize() != 4,
             "Unhandled read size (address: 0x.4x, size: %u)",
             daddr, pkt->getSize());

    const uint32_t data = readReg(daddr);
    DPRINTF(HDLcd, "read register 0x%04x: 0x%x\n", daddr, data);

    pkt->setLE<uint32_t>(data);
    pkt->makeAtomicResponse();
    return pioDelay;
}

// write registers and frame buffer
Tick
HDLcd::write(PacketPtr pkt)
{
    assert(pkt->getAddr() >= pioAddr &&
           pkt->getAddr() < pioAddr + pioSize);

    const Addr daddr = pkt->getAddr() - pioAddr;
    panic_if(pkt->getSize() != 4,
             "Unhandled read size (address: 0x.4x, size: %u)",
             daddr, pkt->getSize());
    const uint32_t data = pkt->getLE<uint32_t>();
    DPRINTF(HDLcd, "write register 0x%04x: 0x%x\n", daddr, data);

    writeReg(daddr, data);

    pkt->makeAtomicResponse();
    return pioDelay;
}

uint32_t
HDLcd::readReg(Addr offset)
{
    switch (offset) {
      case Version: return version;

      case Int_RawStat: return int_rawstat;
      case Int_Clear:
        panic("HDLCD INT_CLEAR register is Write-Only\n");
      case Int_Mask: return int_mask;
      case Int_Status: return intStatus();

      case Fb_Base: return fb_base;
      case Fb_Line_Length: return fb_line_length;
      case Fb_Line_Count: return fb_line_count;
      case Fb_Line_Pitch: return fb_line_pitch;
      case Bus_Options: return bus_options;

      case V_Sync: return v_sync;
      case V_Back_Porch: return v_back_porch;
      case V_Data: return v_data;
      case V_Front_Porch: return v_front_porch;
      case H_Sync: return h_sync;
      case H_Back_Porch: return h_back_porch;
      case H_Data: return h_data;
      case H_Front_Porch: return h_front_porch;
      case Polarities: return polarities;

      case Command: return command;
      case Pixel_Format: return pixel_format;
      case Red_Select: return red_select;
      case Green_Select: return green_select;
      case Blue_Select: return blue_select;

      default:
        panic("Tried to read HDLCD register that doesn't  exist\n", offset);
    }
}

void
HDLcd::writeReg(Addr offset, uint32_t value)
{
    switch (offset) {
      case Version:
        panic("HDLCD VERSION register is read-Only\n");

      case Int_RawStat:
        intRaise(value);
        return;
      case Int_Clear:
        intClear(value);
        return;
      case Int_Mask:
        intMask(value);
        return;
      case Int_Status:
        panic("HDLCD INT_STATUS register is read-Only\n");
        break;

      case Fb_Base:
        fb_base = value;
        return;

      case Fb_Line_Length:
        fb_line_length = value;
        return;

      case Fb_Line_Count:
        fb_line_count = value;
        return;

      case Fb_Line_Pitch:
        fb_line_pitch = value;
        return;

      case Bus_Options: {
          const BusOptsReg old_bus_options(bus_options);
          bus_options = value;

          if (bus_options.max_outstanding != old_bus_options.max_outstanding) {
              DPRINTF(HDLcd,
                      "Changing HDLcd outstanding DMA transactions: %d -> %d\n",
                      old_bus_options.max_outstanding,
                      bus_options.max_outstanding);

          }

          if (bus_options.burst_len != old_bus_options.burst_len) {
              DPRINTF(HDLcd,
                      "Changing HDLcd DMA burst flags: 0x%x -> 0x%x\n",
                      old_bus_options.burst_len, bus_options.burst_len);
          }
      } return;

      case V_Sync:
        v_sync = value;
        return;
      case V_Back_Porch:
        v_back_porch = value;
        return;
      case V_Data:
        v_data = value;
        return;
      case V_Front_Porch:
        v_front_porch = value;
        return;

      case H_Sync:
        h_sync = value;
        return;
      case H_Back_Porch:
        h_back_porch = value;
        return;
      case H_Data:
        h_data = value;
        return;
      case H_Front_Porch:
        h_front_porch = value;
        return;

      case Polarities:
        polarities = value;
        return;

      case Command: {
          const CommandReg new_command(value);

          if (new_command.enable != command.enable) {
              DPRINTF(HDLcd, "HDLCD switched %s\n",
                      new_command.enable ? "on" : "off");

              if (new_command.enable) {
                  cmdEnable();
              } else {
                  cmdDisable();
              }
          }
          command = new_command;
      } return;

      case Pixel_Format:
        pixel_format = value;
        return;

      case Red_Select:
        red_select = value;
        return;
      case Green_Select:
        green_select = value;
        return;
      case Blue_Select:
        blue_select = value;
        return;

      default:
        panic("Tried to write HDLCD register that doesn't exist\n", offset);
        return;
    }
}

PixelConverter
HDLcd::pixelConverter() const
{
    ByteOrder byte_order =
        pixel_format.big_endian ? ByteOrder::big : ByteOrder::little;

    /* Some Linux kernels have a broken driver that swaps the red and
     * blue color select registers. */
    if (!workaroundSwapRB) {
        return PixelConverter(
            pixel_format.bytes_per_pixel + 1,
            red_select.offset, green_select.offset, blue_select.offset,
            red_select.size, green_select.size, blue_select.size,
            byte_order);
    } else {
        return PixelConverter(
            pixel_format.bytes_per_pixel + 1,
            blue_select.offset, green_select.offset, red_select.offset,
            blue_select.size, green_select.size, red_select.size,
            byte_order);
    }
}

DisplayTimings
HDLcd::displayTimings() const
{
    return DisplayTimings(
        h_data.val + 1, v_data.val + 1,
        h_back_porch.val + 1, h_sync.val + 1, h_front_porch.val + 1,
        v_back_porch.val + 1, v_sync.val + 1, v_front_porch.val + 1);
}

void
HDLcd::createDmaEngine()
{
    if (bus_options.max_outstanding == 0) {
        warn("Maximum number of outstanding DMA transfers set to 0.");
        return;
    }

    const uint32_t dma_burst_flags = bus_options.burst_len;
    const uint32_t dma_burst_len = dma_burst_flags ?
        (1UL << (findMsbSet(dma_burst_flags) - 1)) : MAX_BURST_LEN;
    // Some drivers seem to set the DMA line count incorrectly. This
    // could either be a driver bug or a specification bug. Unlike for
    // timings, the specification does not require 1 to be added to
    // the DMA engine's line count.
    const uint32_t dma_lines =
        fb_line_count + (workaroundDmaLineCount ? 1 : 0);

    dmaEngine.reset(new DmaEngine(
                        *this, pixelBufferSize,
                        AXI_PORT_WIDTH * dma_burst_len,
                        bus_options.max_outstanding,
                        fb_line_length, fb_line_pitch, dma_lines));
}

void
HDLcd::cmdEnable()
{
    createDmaEngine();
    conv = pixelConverter();

    // Update timing parameter before rendering frames
    pixelPump.updateTimings(displayTimings());

    if (sys->bypassCaches()) {
        schedule(virtRefreshEvent, clockEdge());
    } else {
        pixelPump.start();
    }
}

void
HDLcd::cmdDisable()
{
    pixelPump.stop();
    // Disable the virtual refresh event
    if (virtRefreshEvent.scheduled()) {
        assert(sys->bypassCaches());
        deschedule(virtRefreshEvent);
    }
    dmaEngine->abortFrame();
}

bool
HDLcd::pxlNext(Pixel &p)
{
    uint8_t pixel_data[MAX_PIXEL_SIZE];
    assert(conv.length <= sizeof(pixel_data));
    if (dmaEngine->tryGet(pixel_data, conv.length)) {
        p = conv.toPixel(pixel_data);
        return true;
    } else {
        return false;
    }
}

size_t
HDLcd::lineNext(std::vector<Pixel>::iterator pixel_it, size_t line_length)
{
    const size_t byte_count = line_length * conv.length;

    lineBuffer.resize(byte_count);
    dmaRead(bypassLineAddress, byte_count, nullptr, lineBuffer.data());

    bypassLineAddress += fb_line_pitch;

    uint8_t *bufPtr = lineBuffer.data();
    for (size_t i = 0; i < line_length; i++) {
        *pixel_it++ = conv.toPixel(bufPtr);
        bufPtr += conv.length;
    }

    return line_length;
}

void
HDLcd::pxlVSyncBegin()
{
    DPRINTF(HDLcd, "Raising VSYNC interrupt.\n");
    intRaise(INT_VSYNC);
}

void
HDLcd::pxlVSyncEnd()
{
    DPRINTF(HDLcd, "End of VSYNC, starting DMA engine\n");
    if (sys->bypassCaches()) {
        bypassLineAddress = fb_base;
    } else {
        dmaEngine->startFrame(fb_base);
    }
}

void
HDLcd::pxlUnderrun()
{
    DPRINTF(HDLcd, "Buffer underrun, stopping DMA fill.\n");
    ++stats.underruns;
    intRaise(INT_UNDERRUN);
    dmaEngine->abortFrame();
}

void
HDLcd::pxlFrameDone()
{
    DPRINTF(HDLcd, "Reached end of last visible line.\n");

    if (dmaEngine->size()) {
        warn("HDLCD %u bytes still in FIFO after frame: Ensure that DMA "
             "and PixelPump configuration is consistent\n",
             dmaEngine->size());
        dmaEngine->dumpSettings();
        pixelPump.dumpSettings();
    }

    if (vnc)
        vnc->setDirty();

    if (enableCapture) {
        if (!pic) {
            pic = simout.create(
                csprintf("%s.framebuffer.%s",
                         sys->name(), imgWriter->getImgExtension()),
                true);
        }

        assert(pic);
        pic->stream()->seekp(0);
        imgWriter->write(*pic->stream());
    }
}

void
HDLcd::setInterrupts(uint32_t ints, uint32_t mask)
{
    const bool old_ints = intStatus();

    int_mask = mask;
    int_rawstat = ints;

    if (!old_ints && intStatus()) {
        interrupt->raise();
    } else if (old_ints && !intStatus()) {
        interrupt->clear();
    }
}

HDLcd::DmaEngine::DmaEngine(HDLcd &_parent, size_t size,
          unsigned request_size, unsigned max_pending,
          size_t line_size, ssize_t line_pitch, unsigned num_lines)
    : DmaReadFifo(
        _parent.dmaPort, size, request_size, max_pending,
        Request::UNCACHEABLE),
      parent(_parent),
      lineSize(line_size), linePitch(line_pitch), numLines(num_lines),
      nextLineAddr(0)
{
}

void
HDLcd::DmaEngine::serialize(CheckpointOut &cp) const
{
    DmaReadFifo::serialize(cp);

    SERIALIZE_SCALAR(nextLineAddr);
    SERIALIZE_SCALAR(frameEnd);
}

void
HDLcd::DmaEngine::unserialize(CheckpointIn &cp)
{
    DmaReadFifo::unserialize(cp);

    UNSERIALIZE_SCALAR(nextLineAddr);
    UNSERIALIZE_SCALAR(frameEnd);
}

void
HDLcd::DmaEngine::startFrame(Addr fb_base)
{
    nextLineAddr = fb_base;
    frameEnd = fb_base + numLines * linePitch;

    startFill(nextLineAddr, lineSize);
}

void
HDLcd::DmaEngine::abortFrame()
{
    nextLineAddr = frameEnd;
    stopFill();
    flush();
}


void
HDLcd::DmaEngine::dumpSettings()
{
    inform("DMA line size: %u bytes", lineSize);
    inform("DMA line pitch: %i bytes", linePitch);
    inform("DMA num lines: %u", numLines);
}

void
HDLcd::DmaEngine::onEndOfBlock()
{
    if (nextLineAddr == frameEnd)
        // We're done with this frame. Ignore calls to this method
        // until the next frame has been started.
        return;

    nextLineAddr += linePitch;
    if (nextLineAddr != frameEnd)
        startFill(nextLineAddr, lineSize);
}

void
HDLcd::DmaEngine::onIdle()
{
    parent.intRaise(INT_DMA_END);
}

void
HDLcd::PixelPump::dumpSettings()
{
    const DisplayTimings &t = timings();

    inform("PixelPump width: %u", t.width);
    inform("PixelPump height: %u", t.height);

    inform("PixelPump horizontal back porch: %u", t.hBackPorch);
    inform("PixelPump horizontal fron porch: %u", t.hFrontPorch);
    inform("PixelPump horizontal fron porch: %u", t.hSync);

    inform("PixelPump vertical back porch: %u", t.vBackPorch);
    inform("PixelPump vertical fron porch: %u", t.vFrontPorch);
    inform("PixelPump vertical fron porch: %u", t.vSync);
}

} // namespace gem5
