/*
 * 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.
 *
 * Authors: Chris Emmons
 *          Andreas Sandberg
 */

#include "dev/arm/hdlcd.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 "mem/packet.hh"
#include "mem/packet_access.hh"
#include "params/HDLcd.hh"
#include "sim/system.hh"

using std::vector;


// 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),

      // Registers
      version(VERSION_RESETV),
      int_rawstat(0), int_mask(0),

      fb_base(0), fb_line_length(0), fb_line_count(0), fb_line_pitch(0),
      bus_options(BUS_OPTIONS_RESETV),

      v_sync(0), v_back_porch(0), v_data(0), v_front_porch(0),
      h_sync(0), h_back_porch(0), h_data(0), h_front_porch(0),
      polarities(0),

      command(0),

      pixel_format(0),
      red_select(0), green_select(0), blue_select(0),

      virtRefreshEvent([this]{ virtRefresh(); }, name()),
      // Other
      bmp(&pixelPump.fb), pic(NULL), conv(PixelConverter::rgba8888_le),
      pixelPump(*this, *p->pxl_clk, p->pixel_chunk)
{
    if (vnc)
        vnc->setFrameBuffer(&pixelPump.fb);
}

HDLcd::~HDLcd()
{
}

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

    using namespace Stats;

    stats.underruns
        .name(name() + ".underruns")
        .desc("number of buffer 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->set<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->get<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 ? BigEndianByteOrder : LittleEndianByteOrder);

    /* 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;
    }
}

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

void
HDLcd::pxlVSyncEnd()
{
    DPRINTF(HDLcd, "End of VSYNC, starting DMA engine\n");
    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.bmp", sys->name()),
                true);
        }

        assert(pic);
        pic->stream()->seekp(0);
        bmp.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()) {
        gic->sendInt(intNum);
    } else if (old_ints && !intStatus()) {
        gic->clearInt(intNum);
    }
}

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);
}


HDLcd *
HDLcdParams::create()
{
    return new HDLcd(this);
}
