/*
 * 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.
 */


/** @file
 * Implementiation of the ARM HDLcd controller.
 *
 * This implementation aims to have sufficient detail such that underrun
 * conditions are reasonable / behave similar to reality.  There are two
 * 'engines' going at once.  First, the DMA engine running at LCD clock
 * frequency is responsible for filling the controller's internal buffer.
 * The second engine runs at the pixel clock frequency and reads the pixels
 * out of the internal buffer.  The pixel rendering engine uses front / back
 * porch and sync delays between lines and frames.
 *
 * If the pixel rendering engine does not have a pixel to display, it will
 * cause an underrun event.  The HDLcd controller, per spec, will stop
 * issuing DMA requests for the rest of the frame and resume normal behavior
 * on the subsequent frame.  What pixels are rendered upon an underrun
 * condition is different than the real hardware; while the user will see
 * artifacts (previous frame mixed with current frame), it is not the same
 * behavior as real hardware which repeats the last pixel value for the rest
 * of the current frame.  This compromise was made to save on memory and
 * complexity and assumes that it is not important to accurately model the
 * content of an underrun frame.
 *
 * KNOWN ISSUES
 * <ul>
 *   <li>The HDLcd is implemented here as an AmbaDmaDevice, but it
 *       doesn't have an AMBA ID as far as I know.  That is the only
 *       bit of the AmbaDmaDevice interface that is irrelevant to it,
 *       so a fake AMBA ID is used for now.  I didn't think inserting
 *       an extra layer of hierachy between AmbaDmaDevice and
 *       DmaDevice would be helpful to anyone else, but that may be
 *       the right answer.
 * </ul>
 */

#ifndef __DEV_ARM_HDLCD_HH__
#define __DEV_ARM_HDLCD_HH__

#include <fstream>
#include <memory>
#include <vector>

#include "base/framebuffer.hh"
#include "base/imgwriter.hh"
#include "base/output.hh"
#include "dev/arm/amba_device.hh"
#include "dev/pixelpump.hh"
#include "sim/serialize.hh"

class VncInput;
struct HDLcdParams;
class HDLcdPixelPump;

class HDLcd: public AmbaDmaDevice
{
  public:
    HDLcd(const HDLcdParams &p);

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

    void drainResume() override;

  public: // IO device interface
    Tick read(PacketPtr pkt) override;
    Tick write(PacketPtr pkt) override;

    AddrRangeList getAddrRanges() const override { return addrRanges; }

  protected: // Parameters
    VncInput *vnc;
    const bool workaroundSwapRB;
    const bool workaroundDmaLineCount;
    const AddrRangeList addrRanges;
    const bool enableCapture;
    const Addr pixelBufferSize;
    const Tick virtRefreshRate;

  protected: // Register handling
    /** ARM HDLcd register offsets */
    enum RegisterOffset {
        Version          = 0x0000,
        Int_RawStat      = 0x0010,
        Int_Clear        = 0x0014,
        Int_Mask         = 0x0018,
        Int_Status       = 0x001C,
        Fb_Base          = 0x0100,
        Fb_Line_Length   = 0x0104,
        Fb_Line_Count    = 0x0108,
        Fb_Line_Pitch    = 0x010C,
        Bus_Options      = 0x0110,
        V_Sync           = 0x0200,
        V_Back_Porch     = 0x0204,
        V_Data           = 0x0208,
        V_Front_Porch    = 0x020C,
        H_Sync           = 0x0210,
        H_Back_Porch     = 0x0214,
        H_Data           = 0x0218,
        H_Front_Porch    = 0x021C,
        Polarities       = 0x0220,
        Command          = 0x0230,
        Pixel_Format     = 0x0240,
        Red_Select       = 0x0244,
        Green_Select     = 0x0248,
        Blue_Select      = 0x024C,
    };

    /** Reset value for Bus_Options register */
    static constexpr size_t BUS_OPTIONS_RESETV = 0x408;

    /** Reset value for Version register */
    static constexpr size_t VERSION_RESETV = 0x1CDC0000;

    /** AXI port width in bytes */
    static constexpr size_t AXI_PORT_WIDTH = 8;

    /** max number of beats delivered in one dma burst */
    static constexpr size_t MAX_BURST_LEN = 16;

    /** Maximum number of bytes per pixel */
    static constexpr size_t MAX_PIXEL_SIZE = 4;

    /**
     * @name RegisterFieldLayouts
     * Bit layout declarations for multi-field registers.
     */
    /**@{*/
    BitUnion32(VersionReg)
        Bitfield<7,0>   version_minor;
        Bitfield<15,8>  version_major;
        Bitfield<31,16> product_id;
    EndBitUnion(VersionReg)

    static constexpr uint32_t INT_DMA_END = (1UL << 0);
    static constexpr uint32_t INT_BUS_ERROR = (1UL << 1);
    static constexpr uint32_t INT_VSYNC = (1UL << 2);
    static constexpr uint32_t INT_UNDERRUN = (1UL << 3);

    BitUnion32(FbLineCountReg)
        Bitfield<11,0>  fb_line_count;
        Bitfield<31,12> reserved_31_12;
    EndBitUnion(FbLineCountReg)

    BitUnion32(BusOptsReg)
        Bitfield<4,0>   burst_len;
        Bitfield<7,5>   reserved_7_5;
        Bitfield<11,8>  max_outstanding;
        Bitfield<31,12> reserved_31_12;
    EndBitUnion(BusOptsReg)

    BitUnion32(TimingReg)
        Bitfield<11,0>  val;
        Bitfield<31,12> reserved_31_12;
    EndBitUnion(TimingReg)

    BitUnion32(PolaritiesReg)
        Bitfield<0>    vsync_polarity;
        Bitfield<1>    hsync_polarity;
        Bitfield<2>    dataen_polarity;
        Bitfield<3>    data_polarity;
        Bitfield<4>    pxlclk_polarity;
        Bitfield<31,5> reserved_31_5;
    EndBitUnion(PolaritiesReg)

    BitUnion32(CommandReg)
        Bitfield<0>    enable;
        Bitfield<31,1> reserved_31_1;
    EndBitUnion(CommandReg)

    BitUnion32(PixelFormatReg)
        Bitfield<2,0>  reserved_2_0;
        Bitfield<4,3>  bytes_per_pixel;
        Bitfield<30,5> reserved_30_5;
        Bitfield<31>   big_endian;
    EndBitUnion(PixelFormatReg)

    BitUnion32(ColorSelectReg)
        Bitfield<4,0>   offset;
        Bitfield<7,5>   reserved_7_5;
        Bitfield<11,8>  size;
        Bitfield<15,12> reserved_15_12;
        Bitfield<23,16> default_color;
        Bitfield<31,24> reserved_31_24;
    EndBitUnion(ColorSelectReg)
    /**@}*/

    /**
     * @name HDLCDRegisters
     * HDLCD register contents.
     */
    /**@{*/
    const VersionReg version = VERSION_RESETV;
                                    /**< Version register */
    uint32_t int_rawstat = 0;       /**< Interrupt raw status register */
    uint32_t int_mask = 0;          /**< Interrupt mask register */
    uint32_t fb_base = 0;           /**< Frame buffer base address register */
    uint32_t fb_line_length = 0;    /**< Frame buffer Line length register */
                                    /**< Frame buffer Line count register */
    FbLineCountReg fb_line_count = 0;
    int32_t fb_line_pitch = 0;      /**< Frame buffer Line pitch register */
    BusOptsReg bus_options = BUS_OPTIONS_RESETV;
                                    /**< Bus options register */
    TimingReg v_sync = 0;           /**< Vertical sync width register */
    TimingReg v_back_porch = 0;     /**< Vertical back porch width register */
    TimingReg v_data = 0;           /**< Vertical data width register */
    TimingReg v_front_porch = 0;    /**< Vertical front porch width register */
    TimingReg h_sync = 0;           /**< Horizontal sync width register */
    TimingReg h_back_porch = 0;     /**< Horizontal back porch width reg */
    TimingReg h_data = 0;           /**< Horizontal data width register */
    TimingReg h_front_porch = 0;    /**< Horizontal front porch width reg */
    PolaritiesReg polarities = 0;   /**< Polarities register */
    CommandReg command = 0;         /**< Command register */
    PixelFormatReg pixel_format = 0;/**< Pixel format register */
    ColorSelectReg red_select = 0;  /**< Red color select register */
    ColorSelectReg green_select = 0;/**< Green color select register */
    ColorSelectReg blue_select = 0; /**< Blue color select register */
    /** @} */

    std::vector<uint8_t> lineBuffer;

    uint32_t readReg(Addr offset);
    void writeReg(Addr offset, uint32_t value);

    PixelConverter pixelConverter() const;
    DisplayTimings displayTimings() const;

    void createDmaEngine();

    void cmdEnable();
    void cmdDisable();

    bool enabled() const { return command.enable; }

  public: // Pixel pump callbacks
    bool pxlNext(Pixel &p);
    size_t lineNext(std::vector<Pixel>::iterator pixel_it, size_t line_length);
    void pxlVSyncBegin();
    void pxlVSyncEnd();
    void pxlUnderrun();
    void pxlFrameDone();

  protected: // Interrupt handling
    /**
     * Assign new interrupt values and update interrupt signals
     *
     * A new interrupt is scheduled signalled if the set of unmasked
     * interrupts goes empty to non-empty. Conversely, if the set of
     * unmasked interrupts goes from non-empty to empty, the interrupt
     * signal is cleared.
     *
     * @param ints New <i>raw</i> interrupt status
     * @param mask New interrupt mask
     */
    void setInterrupts(uint32_t ints, uint32_t mask);

    /**
     * Convenience function to update the interrupt mask
     *
     * @see setInterrupts
     * @param mask New interrupt mask
     */
    void intMask(uint32_t mask) { setInterrupts(int_rawstat, mask); }

    /**
     * Convenience function to raise a new interrupt
     *
     * @see setInterrupts
     * @param ints Set of interrupts to raise
     */
    void
    intRaise(uint32_t ints)
    {
        setInterrupts(int_rawstat | ints, int_mask);
    }

    /**
     * Convenience function to clear interrupts
     *
     * @see setInterrupts
     * @param ints Set of interrupts to clear
     */
    void
    intClear(uint32_t ints)
    {
        setInterrupts(int_rawstat & ~ints, int_mask);
    }

    /** Masked interrupt status register */
    uint32_t intStatus() const { return int_rawstat & int_mask; }

  protected: // Pixel output
    class PixelPump : public BasePixelPump
    {
      public:
        PixelPump(HDLcd &p, ClockDomain &pxl_clk, unsigned pixel_chunk)
            : BasePixelPump(p, pxl_clk, pixel_chunk), parent(p)
        {}

        void dumpSettings();

      protected:
        bool nextPixel(Pixel &p) override { return parent.pxlNext(p); }
        size_t
        nextLine(std::vector<Pixel>::iterator pixel_it,
                 size_t line_length) override
        {
            return parent.lineNext(pixel_it, line_length);
        }

        void onVSyncBegin() override { return parent.pxlVSyncBegin(); }
        void onVSyncEnd() override { return parent.pxlVSyncEnd(); }

        void
        onUnderrun(unsigned x, unsigned y) override
        {
            parent.pxlUnderrun();
        }

        void onFrameDone() override { parent.pxlFrameDone(); }

      protected:
        HDLcd &parent;
    };

    Addr bypassLineAddress = 0;

    /** Handler for fast frame refresh in KVM-mode */
    void virtRefresh();
    EventFunctionWrapper virtRefreshEvent;

    /** Helper to write out bitmaps */
    std::unique_ptr<ImgWriter> imgWriter;

    /** Image Format */
    Enums::ImageFormat imgFormat;

    /** Picture of what the current frame buffer looks like */
    OutputStream *pic = nullptr;

    /** Cached pixel converter, set when the converter is enabled. */
    PixelConverter conv = PixelConverter::rgba8888_le;

    PixelPump pixelPump;

  protected: // DMA handling
    class DmaEngine : public DmaReadFifo
    {
      public:
        DmaEngine(HDLcd &_parent, size_t size,
                  unsigned request_size, unsigned max_pending,
                  size_t line_size, ssize_t line_pitch, unsigned num_lines);

        void startFrame(Addr fb_base);
        void abortFrame();
        void dumpSettings();

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp) override;

      protected:
        void onEndOfBlock() override;
        void onIdle() override;

        HDLcd &parent;
        const size_t lineSize;
        const ssize_t linePitch;
        const unsigned numLines;

        Addr nextLineAddr;
        Addr frameEnd;
    };

    std::unique_ptr<DmaEngine> dmaEngine;

  protected: // Statistics
    struct HDLcdStats: public Stats::Group
    {
        HDLcdStats(Stats::Group *parent);
        Stats::Scalar underruns;
    } stats;
};

#endif
