hdlcd.hh revision 10839:10cac0f0f419
12SN/A/*
29608Sandreas.hansson@arm.com * Copyright (c) 2010-2013, 2015 ARM Limited
38707Sandreas.hansson@arm.com * All rights reserved
48707Sandreas.hansson@arm.com *
58707Sandreas.hansson@arm.com * The license below extends only to copyright in the software and shall
68707Sandreas.hansson@arm.com * not be construed as granting a license to any other intellectual
78707Sandreas.hansson@arm.com * property including but not limited to intellectual property relating
88707Sandreas.hansson@arm.com * to a hardware implementation of the functionality of the software
98707Sandreas.hansson@arm.com * licensed hereunder.  You may use the software subject to the license
108707Sandreas.hansson@arm.com * terms below provided that you ensure that this notice is replicated
118707Sandreas.hansson@arm.com * unmodified and in its entirety in all distributions of the software,
128707Sandreas.hansson@arm.com * modified or unmodified, in source code or in binary form.
138707Sandreas.hansson@arm.com *
141762SN/A * Redistribution and use in source and binary forms, with or without
157897Shestness@cs.utexas.edu * modification, are permitted provided that the following conditions are
162SN/A * met: redistributions of source code must retain the above copyright
172SN/A * notice, this list of conditions and the following disclaimer;
182SN/A * redistributions in binary form must reproduce the above copyright
192SN/A * notice, this list of conditions and the following disclaimer in the
202SN/A * documentation and/or other materials provided with the distribution;
212SN/A * neither the name of the copyright holders nor the names of its
222SN/A * contributors may be used to endorse or promote products derived from
232SN/A * this software without specific prior written permission.
242SN/A *
252SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
262SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
272SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
282SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
292SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
302SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
312SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
322SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
332SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
352SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
362SN/A *
372SN/A * Authors: Chris Emmons
382SN/A */
392SN/A
402665Ssaidi@eecs.umich.edu
412665Ssaidi@eecs.umich.edu/** @file
422665Ssaidi@eecs.umich.edu * Implementiation of the ARM HDLcd controller.
437897Shestness@cs.utexas.edu *
442SN/A * This implementation aims to have sufficient detail such that underrun
452SN/A * conditions are reasonable / behave similar to reality.  There are two
461717SN/A * 'engines' going at once.  First, the DMA engine running at LCD clock
471717SN/A * frequency is responsible for filling the controller's internal buffer.
482SN/A * The second engine runs at the pixel clock frequency and reads the pixels
492SN/A * out of the internal buffer.  The pixel rendering engine uses front / back
502SN/A * porch and sync delays between lines and frames.
519850Sandreas.hansson@arm.com *
529850Sandreas.hansson@arm.com * If the pixel rendering engine does not have a pixel to display, it will
539850Sandreas.hansson@arm.com * cause an underrun event.  The HDLcd controller, per spec, will stop
549850Sandreas.hansson@arm.com * issuing DMA requests for the rest of the frame and resume normal behavior
559850Sandreas.hansson@arm.com * on the subsequent frame.  What pixels are rendered upon an underrun
569850Sandreas.hansson@arm.com * condition is different than the real hardware; while the user will see
578745Sgblack@eecs.umich.edu * artifacts (previous frame mixed with current frame), it is not the same
584182Sgblack@eecs.umich.edu * behavior as real hardware which repeats the last pixel value for the rest
595664Sgblack@eecs.umich.edu * of the current frame.  This compromise was made to save on memory and
60707SN/A * complexity and assumes that it is not important to accurately model the
618229Snate@binkert.org * content of an underrun frame.
6256SN/A *
638779Sgblack@eecs.umich.edu * KNOWN ISSUES
644776Sgblack@eecs.umich.edu * 1.  The default kernel driver used in testing sets the line count to one
6510464SAndreas.Sandberg@ARM.com * less than the expected 768.  However, it also sets the v_count to 767.
669814Sandreas.hansson@arm.com * The controller specifies that 1 should be added to v_count but does not
6710529Smorr@cs.wisc.edu * specify adding 1 to the line count.  The driver is probably wrong.
682SN/A * However, to sync these two numbers up, this model uses fb_line_count and
6910529Smorr@cs.wisc.edu * fb_line_length rather than using v_data or h_data values to determine the
708901Sandreas.hansson@arm.com * width and height of the frame; those values are ignored.
712315SN/A * 2.  The HDLcd is implemented here as an AmbaDmaDevice, but it doesn't have
722680Sktlim@umich.edu * an AMBA ID as far as I know.  That is the only bit of the AmbaDmaDevice
732SN/A * interface that is irrelevant to it, so a fake AMBA ID is used for now.
7410529Smorr@cs.wisc.edu * I didn't think inserting an extra layer of hierachy between AmbaDmaDevice
7510529Smorr@cs.wisc.edu * and DmaDevice would be helpful to anyone else, but that may be the right
7610529Smorr@cs.wisc.edu * answer.
7710529Smorr@cs.wisc.edu * 3.  The internal buffer size is either 1 or 2 KB depending on which
7810529Smorr@cs.wisc.edu * specification is referenced for the different Versatile Express tiles.
7910529Smorr@cs.wisc.edu * This implementation uses the larger 2 KB buffer by default.
8010529Smorr@cs.wisc.edu */
8110529Smorr@cs.wisc.edu
8210529Smorr@cs.wisc.edu#ifndef __DEV_ARM_HDLCD_HH__
8310529Smorr@cs.wisc.edu#define __DEV_ARM_HDLCD_HH__
8410529Smorr@cs.wisc.edu
8510529Smorr@cs.wisc.edu#include <fstream>
8610529Smorr@cs.wisc.edu#include <memory>
872356SN/A
882356SN/A#include "base/bitmap.hh"
892356SN/A#include "base/framebuffer.hh"
906144Sksewell@umich.edu#include "dev/arm/amba_device.hh"
912356SN/A#include "params/HDLcd.hh"
922356SN/A#include "sim/serialize.hh"
936144Sksewell@umich.edu
942356SN/Aclass VncInput;
952356SN/A
966144Sksewell@umich.educlass HDLcd: public AmbaDmaDevice
972356SN/A{
982356SN/A  protected:
992356SN/A    /** fake AMBA ID -- unused */
1006144Sksewell@umich.edu    static const uint64_t AMBA_ID       = ULL(0xb105f00d00141000);
1016144Sksewell@umich.edu
1026144Sksewell@umich.edu    /** ARM HDLcd register offsets */
1036144Sksewell@umich.edu    enum RegisterOffset {
1046144Sksewell@umich.edu        Version          = 0x0000,
1055336Shines@cs.fsu.edu        Int_RawStat      = 0x0010,
1062356SN/A        Int_Clear        = 0x0014,
1072356SN/A        Int_Mask         = 0x0018,
1082856Srdreslin@umich.edu        Int_Status       = 0x001C,
1092SN/A        Fb_Base          = 0x0100,
1101634SN/A        Fb_Line_Length   = 0x0104,
1119157Sandreas.hansson@arm.com        Fb_Line_Count    = 0x0108,
11210662SAli.Saidi@ARM.com        Fb_Line_Pitch    = 0x010C,
11310662SAli.Saidi@ARM.com        Bus_Options      = 0x0110,
1143814Ssaidi@eecs.umich.edu        V_Sync           = 0x0200,
11510662SAli.Saidi@ARM.com        V_Back_Porch     = 0x0204,
1165712Shsul@eecs.umich.edu        V_Data           = 0x0208,
1175712Shsul@eecs.umich.edu        V_Front_Porch    = 0x020C,
1185715Shsul@eecs.umich.edu        H_Sync           = 0x0210,
1195712Shsul@eecs.umich.edu        H_Back_Porch     = 0x0214,
1205712Shsul@eecs.umich.edu        H_Data           = 0x0218,
1211634SN/A        H_Front_Porch    = 0x021C,
12210190Sakash.bagdia@arm.com        Polarities       = 0x0220,
12310190Sakash.bagdia@arm.com        Command          = 0x0230,
12410190Sakash.bagdia@arm.com        Pixel_Format     = 0x0240,
12510190Sakash.bagdia@arm.com        Red_Select       = 0x0244,
12610190Sakash.bagdia@arm.com        Green_Select     = 0x0248,
12710190Sakash.bagdia@arm.com        Blue_Select      = 0x024C };
12810190Sakash.bagdia@arm.com
1298832SAli.Saidi@ARM.com    /** Reset value for Bus_Options register */
1308832SAli.Saidi@ARM.com    static const size_t BUS_OPTIONS_RESETV = 0x408;
1318832SAli.Saidi@ARM.com
1328832SAli.Saidi@ARM.com    /** Reset value for Version register */
1338832SAli.Saidi@ARM.com    static const size_t VERSION_RESETV = 0x1CDC0000;
1348832SAli.Saidi@ARM.com
1359332Sdam.sunwoo@arm.com    /** max number of outstanding DMA requests possible */
1369332Sdam.sunwoo@arm.com    static const size_t MAX_OUTSTANDING_DMA_REQ_CAPACITY = 16;
1379332Sdam.sunwoo@arm.com
1389332Sdam.sunwoo@arm.com    /** max number of beats delivered in one dma burst */
1399332Sdam.sunwoo@arm.com    static const size_t MAX_BURST_LEN = 16;
1409332Sdam.sunwoo@arm.com
1419332Sdam.sunwoo@arm.com    /** size of internal buffer in bytes */
1429332Sdam.sunwoo@arm.com    static const size_t PIXEL_BUFFER_CAPACITY = 2048;
1439332Sdam.sunwoo@arm.com
1449332Sdam.sunwoo@arm.com    /** AXI port width in bytes */
1459332Sdam.sunwoo@arm.com    static const size_t AXI_PORT_WIDTH = 8;
1469430SAndreas.Sandberg@ARM.com
1479430SAndreas.Sandberg@ARM.com    static const size_t MAX_BURST_SIZE = MAX_BURST_LEN * AXI_PORT_WIDTH;
1489430SAndreas.Sandberg@ARM.com
1499814Sandreas.hansson@arm.com    /**
1509814Sandreas.hansson@arm.com     * @name RegisterFieldLayouts
1519814Sandreas.hansson@arm.com     * Bit layout declarations for multi-field registers.
1521634SN/A     */
1538850Sandreas.hansson@arm.com    /**@{*/
1548850Sandreas.hansson@arm.com    BitUnion32(VersionReg)
1558850Sandreas.hansson@arm.com        Bitfield<7,0>   version_minor;
1568850Sandreas.hansson@arm.com        Bitfield<15,8>  version_major;
1578850Sandreas.hansson@arm.com        Bitfield<31,16> product_id;
1588850Sandreas.hansson@arm.com    EndBitUnion(VersionReg)
1598850Sandreas.hansson@arm.com
1609608Sandreas.hansson@arm.com    BitUnion32(InterruptReg)
1618850Sandreas.hansson@arm.com        Bitfield<0> dma_end;
1628850Sandreas.hansson@arm.com        Bitfield<1> bus_error;
1638850Sandreas.hansson@arm.com        Bitfield<2> vsync;
1648850Sandreas.hansson@arm.com        Bitfield<3> underrun;
1658850Sandreas.hansson@arm.com    EndBitUnion(InterruptReg)
1668850Sandreas.hansson@arm.com
1678850Sandreas.hansson@arm.com    BitUnion32(FbLineCountReg)
1689608Sandreas.hansson@arm.com        Bitfield<11,0>  fb_line_count;
1698850Sandreas.hansson@arm.com        Bitfield<31,12> reserved_31_12;
1705712Shsul@eecs.umich.edu    EndBitUnion(FbLineCountReg)
17110110Sandreas.hansson@arm.com
1725712Shsul@eecs.umich.edu    BitUnion32(BusOptsReg)
17310190Sakash.bagdia@arm.com        Bitfield<4,0>   burst_len;
17410190Sakash.bagdia@arm.com        Bitfield<7,5>   reserved_7_5;
17510190Sakash.bagdia@arm.com        Bitfield<11,8>  max_outstanding;
1768832SAli.Saidi@ARM.com        Bitfield<31,12> reserved_31_12;
1778832SAli.Saidi@ARM.com    EndBitUnion(BusOptsReg)
1788832SAli.Saidi@ARM.com
1798832SAli.Saidi@ARM.com    BitUnion32(TimingReg)
1808832SAli.Saidi@ARM.com        Bitfield<11,0>  val;
1818850Sandreas.hansson@arm.com        Bitfield<31,12> reserved_31_12;
1828926Sandreas.hansson@arm.com    EndBitUnion(TimingReg)
1838926Sandreas.hansson@arm.com
1848926Sandreas.hansson@arm.com    BitUnion32(PolaritiesReg)
1858850Sandreas.hansson@arm.com        Bitfield<0>    vsync_polarity;
1868850Sandreas.hansson@arm.com        Bitfield<1>    hsync_polarity;
1878850Sandreas.hansson@arm.com        Bitfield<2>    dataen_polarity;
1888850Sandreas.hansson@arm.com        Bitfield<3>    data_polarity;
1898922Swilliam.wang@arm.com        Bitfield<4>    pxlclk_polarity;
1908850Sandreas.hansson@arm.com        Bitfield<31,5> reserved_31_5;
1919294Sandreas.hansson@arm.com    EndBitUnion(PolaritiesReg)
1929294Sandreas.hansson@arm.com
1938850Sandreas.hansson@arm.com    BitUnion32(CommandReg)
1949332Sdam.sunwoo@arm.com        Bitfield<0>    enable;
1959332Sdam.sunwoo@arm.com        Bitfield<31,1> reserved_31_1;
1969332Sdam.sunwoo@arm.com    EndBitUnion(CommandReg)
1979332Sdam.sunwoo@arm.com
1989332Sdam.sunwoo@arm.com    BitUnion32(PixelFormatReg)
1999332Sdam.sunwoo@arm.com        Bitfield<2,0>  reserved_2_0;
2009332Sdam.sunwoo@arm.com        Bitfield<4,3>  bytes_per_pixel;
2019332Sdam.sunwoo@arm.com        Bitfield<30,5> reserved_30_5;
2027914SBrad.Beckmann@amd.com        Bitfield<31>   big_endian;
2037914SBrad.Beckmann@amd.com    EndBitUnion(PixelFormatReg)
2043814Ssaidi@eecs.umich.edu
2053814Ssaidi@eecs.umich.edu    BitUnion32(ColorSelectReg)
2061634SN/A        Bitfield<4,0>   offset;
2075664Sgblack@eecs.umich.edu        Bitfield<7,5>   reserved_7_5;
2085664Sgblack@eecs.umich.edu        Bitfield<11,8>  size;
2092SN/A        Bitfield<15,12> reserved_15_12;
21011150Smitch.hayenga@arm.com        Bitfield<23,16> default_color;
2112SN/A        Bitfield<31,24> reserved_31_24;
2122SN/A    EndBitUnion(ColorSelectReg)
2135645Sgblack@eecs.umich.edu    /**@}*/
21411150Smitch.hayenga@arm.com
2155645Sgblack@eecs.umich.edu    /**
21611150Smitch.hayenga@arm.com     * @name HDLCDRegisters
21711150Smitch.hayenga@arm.com     * HDLCD register contents.
21811150Smitch.hayenga@arm.com     */
21911150Smitch.hayenga@arm.com    /**@{*/
22011150Smitch.hayenga@arm.com    VersionReg version;             /**< Version register */
2215645Sgblack@eecs.umich.edu    InterruptReg int_rawstat;       /**< Interrupt raw status register */
2225645Sgblack@eecs.umich.edu    InterruptReg int_clear;         /**< Interrupt clear register */
22311151Smitch.hayenga@arm.com    InterruptReg int_mask;          /**< Interrupt mask register */
2245807Snate@binkert.org    InterruptReg int_status;        /**< Interrupt status register */
2255807Snate@binkert.org    uint32_t fb_base;               /**< Frame buffer base address register */
22611150Smitch.hayenga@arm.com    uint32_t fb_line_length;        /**< Frame buffer Line length register */
2275807Snate@binkert.org    FbLineCountReg fb_line_count;   /**< Frame buffer Line count register */
22811150Smitch.hayenga@arm.com    uint32_t fb_line_pitch;         /**< Frame buffer Line pitch register */
2298779Sgblack@eecs.umich.edu    BusOptsReg bus_options;         /**< Bus options register */
23011151Smitch.hayenga@arm.com    TimingReg v_sync;               /**< Vertical sync width register */
2315807Snate@binkert.org    TimingReg v_back_porch;         /**< Vertical back porch width register */
2325807Snate@binkert.org    TimingReg v_data;               /**< Vertical data width register */
2335807Snate@binkert.org    TimingReg v_front_porch;        /**< Vertical front porch width register */
23411150Smitch.hayenga@arm.com    TimingReg h_sync;               /**< Horizontal sync width register */
2355807Snate@binkert.org    TimingReg h_back_porch;         /**< Horizontal back porch width register */
23611150Smitch.hayenga@arm.com    TimingReg h_data;               /**< Horizontal data width register */
2375807Snate@binkert.org    TimingReg h_front_porch;        /**< Horizontal front porch width reg */
2385807Snate@binkert.org    PolaritiesReg polarities;       /**< Polarities register */
2395807Snate@binkert.org    CommandReg command;             /**< Command register */
24011150Smitch.hayenga@arm.com    PixelFormatReg pixel_format;    /**< Pixel format register */
2415807Snate@binkert.org    ColorSelectReg red_select;      /**< Red color select register */
24211150Smitch.hayenga@arm.com    ColorSelectReg green_select;    /**< Green color select register */
2435807Snate@binkert.org    ColorSelectReg blue_select;     /**< Blue color select register */
2442SN/A    /** @} */
2455704Snate@binkert.org
2465704Snate@binkert.org    /** Pixel clock period */
2475704Snate@binkert.org    const Tick pixelClock;
24811150Smitch.hayenga@arm.com
2495704Snate@binkert.org    FrameBuffer fb;
2501917SN/A
2511917SN/A    /** VNC server */
2521917SN/A    VncInput *vnc;
2531917SN/A
2541917SN/A    /** Helper to write out bitmaps */
2555536Srstrong@hp.com    Bitmap bmp;
2561917SN/A
2571917SN/A    /** Picture of what the current frame buffer looks like */
2585536Srstrong@hp.com    std::ostream *pic;
2591917SN/A
2601917SN/A    /**
2611917SN/A     * Event wrapper for dmaDone()
2622SN/A     *
2632SN/A     * This event call pushes its this pointer onto the freeDoneEvent vector
2642680Sktlim@umich.edu     * and calls dmaDone() when triggered.  While most of the time the burst
2652SN/A     * length of a transaction will be the max burst length set by the driver,
2664776Sgblack@eecs.umich.edu     * any trailing bytes must be handled with smaller lengths thus requiring
2674776Sgblack@eecs.umich.edu     * the configurable burst length option.
2682SN/A     */
269393SN/A    class DmaDoneEvent : public Event
27011050Sandreas.hansson@arm.com    {
27111050Sandreas.hansson@arm.com      private:
27211050Sandreas.hansson@arm.com        /** Reference to HDLCD that issued the corresponding DMA transaction */
27311050Sandreas.hansson@arm.com        HDLcd &obj;
27411050Sandreas.hansson@arm.com
2757764Sgblack@eecs.umich.edu        /** Transaction size */
2767764Sgblack@eecs.umich.edu        size_t transSize;
2777764Sgblack@eecs.umich.edu
2784776Sgblack@eecs.umich.edu      public:
2794776Sgblack@eecs.umich.edu        /**
2804776Sgblack@eecs.umich.edu         * Constructor.
28110407Smitch.hayenga@arm.com         *
28210407Smitch.hayenga@arm.com         * @param _obj HDLCD that issued the corresponding DMA transaction
283393SN/A         */
284393SN/A        DmaDoneEvent(HDLcd *_obj)
2858737Skoansin.tan@gmail.com            : Event(), obj(*_obj), transSize(0) {}
286393SN/A
287393SN/A        /**
2888737Skoansin.tan@gmail.com         * Sets the size of this transaction.
2892SN/A         *
2904000Ssaidi@eecs.umich.edu         * @param len size of the transaction in bytes
2914000Ssaidi@eecs.umich.edu         */
2924000Ssaidi@eecs.umich.edu        void setTransactionSize(size_t len) {
2934000Ssaidi@eecs.umich.edu            transSize = len;
2949652SAndreas.Sandberg@ARM.com        }
2954000Ssaidi@eecs.umich.edu
29610030SAli.Saidi@ARM.com        /**
29710030SAli.Saidi@ARM.com         * Gets the size of this transaction.
29810030SAli.Saidi@ARM.com         *
2992SN/A         * @return size of this transaction in bytes
3005529Snate@binkert.org         */
3015529Snate@binkert.org        size_t getTransactionSize() const {
3025529Snate@binkert.org            return transSize;
3038876Sandreas.hansson@arm.com        }
3041191SN/A
3052SN/A        void process() {
3061129SN/A            obj.dmaDone(this);
3071917SN/A        }
3082SN/A
3092SN/A        const std::string name() const {
31011168Sandreas.hansson@arm.com            return obj.name() + ".DmaDoneEvent";
31110464SAndreas.Sandberg@ARM.com        }
3122680Sktlim@umich.edu    };
313180SN/A
3149254SAndreas.Sandberg@arm.com    /** Start time for frame buffer dma read */
3159254SAndreas.Sandberg@arm.com    Tick frameReadStartTime;
3169254SAndreas.Sandberg@arm.com
3179254SAndreas.Sandberg@arm.com    /** Starting address for the current frame */
3189254SAndreas.Sandberg@arm.com    Addr dmaStartAddr;
3199254SAndreas.Sandberg@arm.com
3209254SAndreas.Sandberg@arm.com    /** Next address the dma should read from */
3212798Sktlim@umich.edu    Addr dmaCurAddr;
322180SN/A
3239254SAndreas.Sandberg@arm.com    /** One byte past the address of the last byte the dma should read
3249254SAndreas.Sandberg@arm.com      * from */
3259254SAndreas.Sandberg@arm.com    Addr dmaMaxAddr;
3269254SAndreas.Sandberg@arm.com
3279254SAndreas.Sandberg@arm.com    /** Number of pending dma reads */
3289254SAndreas.Sandberg@arm.com    size_t dmaPendingNum;
3299254SAndreas.Sandberg@arm.com
3309254SAndreas.Sandberg@arm.com    /** Flag indicating whether current frame has underrun */
3319254SAndreas.Sandberg@arm.com    bool frameUnderrun;
3329254SAndreas.Sandberg@arm.com
3339254SAndreas.Sandberg@arm.com    /** HDLcd virtual display buffer */
3349254SAndreas.Sandberg@arm.com    std::vector<uint8_t> virtualDisplayBuffer;
335180SN/A
336124SN/A    /** Size of the pixel buffer */
3379446SAndreas.Sandberg@ARM.com    size_t pixelBufferSize;
3389446SAndreas.Sandberg@ARM.com
3399446SAndreas.Sandberg@ARM.com    /** Index of the next pixel to render */
3409446SAndreas.Sandberg@ARM.com    size_t pixelIndex;
3419446SAndreas.Sandberg@ARM.com
3429446SAndreas.Sandberg@ARM.com    /** Flag indicating whether video parameters need updating */
3439446SAndreas.Sandberg@ARM.com    bool doUpdateParams;
3449446SAndreas.Sandberg@ARM.com
3459446SAndreas.Sandberg@ARM.com    /** Flag indicating whether a frame read / display is in progress */
3469446SAndreas.Sandberg@ARM.com    bool frameUnderway;
3479446SAndreas.Sandberg@ARM.com
3489430SAndreas.Sandberg@ARM.com    /**
3499430SAndreas.Sandberg@ARM.com     * Number of bytes in flight from DMA that have not reached the pixel
3509430SAndreas.Sandberg@ARM.com     * buffer yet
3519430SAndreas.Sandberg@ARM.com     */
3529430SAndreas.Sandberg@ARM.com    uint32_t dmaBytesInFlight;
3539430SAndreas.Sandberg@ARM.com
3549430SAndreas.Sandberg@ARM.com    /**
3559523SAndreas.Sandberg@ARM.com     * Gets the number of oustanding DMA transactions allowed on the bus at a
3569523SAndreas.Sandberg@ARM.com     * time.
3579523SAndreas.Sandberg@ARM.com     *
3589523SAndreas.Sandberg@ARM.com     * @return gets the driver-specified number of outstanding DMA transactions
3599523SAndreas.Sandberg@ARM.com     *         from the hdlcd controller that are allowed on the bus at a time
3609523SAndreas.Sandberg@ARM.com     */
3619523SAndreas.Sandberg@ARM.com    inline uint16_t maxOutstandingDma() const {
3629523SAndreas.Sandberg@ARM.com        return bus_options.max_outstanding;
3639523SAndreas.Sandberg@ARM.com    }
3649523SAndreas.Sandberg@ARM.com
3659523SAndreas.Sandberg@ARM.com    /**
366124SN/A     * Gets the number of bytes free in the pixel buffer.
367124SN/A     *
368124SN/A     * @return number of bytes free in the internal pixel buffer
3696221Snate@binkert.org     */
3702SN/A    inline uint32_t bytesFreeInPixelBuffer() const {
371124SN/A        return PIXEL_BUFFER_CAPACITY - (pixelBufferSize + dmaBytesInFlight);
372124SN/A    }
373124SN/A
374124SN/A    /**
375124SN/A     * Gets the number of beats-per-burst for bus transactions.
376503SN/A     *
3772SN/A     * @return number of beats-per-burst per HDLcd DMA transaction
378124SN/A     */
379124SN/A    inline size_t dmaBurstLength() const {
380124SN/A        assert(bus_options.burst_len <= MAX_BURST_LEN);
381124SN/A        return bus_options.burst_len;
382124SN/A    }
383124SN/A
384124SN/A    /**
3852SN/A     * Gets the number of bytes per pixel.
386921SN/A     *
387921SN/A     * @return bytes per pixel
3889814Sandreas.hansson@arm.com     */
3899814Sandreas.hansson@arm.com    inline size_t bytesPerPixel() const {
3909814Sandreas.hansson@arm.com        return pixel_format.bytes_per_pixel + 1;
3919814Sandreas.hansson@arm.com    }
3929814Sandreas.hansson@arm.com
393921SN/A    /**
3949448SAndreas.Sandberg@ARM.com     * Gets frame buffer width.
3959448SAndreas.Sandberg@ARM.com     *
3969448SAndreas.Sandberg@ARM.com     * @return frame buffer width (pixels per line)
3979448SAndreas.Sandberg@ARM.com     */
3989448SAndreas.Sandberg@ARM.com    inline size_t width() const {
3999448SAndreas.Sandberg@ARM.com        return fb_line_length / bytesPerPixel();
400921SN/A    }
401921SN/A
40211168Sandreas.hansson@arm.com    /**
403921SN/A     * Gets frame buffer height.
404921SN/A     *
405921SN/A     * @return frame buffer height (lines per panel)
4069448SAndreas.Sandberg@ARM.com     */
4079448SAndreas.Sandberg@ARM.com    inline size_t height() const {
4089448SAndreas.Sandberg@ARM.com        return fb_line_count.fb_line_count;
4099448SAndreas.Sandberg@ARM.com    }
4109448SAndreas.Sandberg@ARM.com
4119448SAndreas.Sandberg@ARM.com    inline size_t area() const { return height() * width(); }
412921SN/A
4139448SAndreas.Sandberg@ARM.com    /**
414921SN/A     * Gets the total number of pixel clocks per display line.
41511168Sandreas.hansson@arm.com     *
416921SN/A     * @return number of pixel clocks per display line including porch delays
417124SN/A     *         and horizontal sync time
4189448SAndreas.Sandberg@ARM.com     */
4199448SAndreas.Sandberg@ARM.com    inline uint64_t PClksPerLine() const {
4209448SAndreas.Sandberg@ARM.com        return h_back_porch.val + 1 +
4219448SAndreas.Sandberg@ARM.com               h_data.val + 1 +
4229448SAndreas.Sandberg@ARM.com               h_front_porch.val + 1 +
42310905Sandreas.sandberg@arm.com               h_sync.val + 1;
4249448SAndreas.Sandberg@ARM.com    }
4259448SAndreas.Sandberg@ARM.com
4269448SAndreas.Sandberg@ARM.com    /** Send updated parameters to the vnc server */
4279448SAndreas.Sandberg@ARM.com    void updateVideoParams(bool unserializing);
4289448SAndreas.Sandberg@ARM.com
4299448SAndreas.Sandberg@ARM.com    /** Generates an interrupt */
4309448SAndreas.Sandberg@ARM.com    void generateInterrupt();
4319448SAndreas.Sandberg@ARM.com
43210905Sandreas.sandberg@arm.com    /** Start reading the next frame */
4339448SAndreas.Sandberg@ARM.com    void startFrame();
4348834Satgutier@umich.edu
4358834Satgutier@umich.edu    /** End of frame reached */
4368834Satgutier@umich.edu    void endFrame();
437707SN/A
4389749Sandreas@sandberg.pp.se    /** Generate DMA read requests from frame buffer into pixel buffer */
4399749Sandreas@sandberg.pp.se    void fillPixelBuffer();
4409749Sandreas@sandberg.pp.se
4419749Sandreas@sandberg.pp.se    /** DMA done event */
4429749Sandreas@sandberg.pp.se    void dmaDone(DmaDoneEvent *event);
4439749Sandreas@sandberg.pp.se
4449749Sandreas@sandberg.pp.se    /** Called when it is time to render a pixel */
4459749Sandreas@sandberg.pp.se    void renderPixel();
4469749Sandreas@sandberg.pp.se
4479749Sandreas@sandberg.pp.se    PixelConverter pixelConverter() const;
4489749Sandreas@sandberg.pp.se
4499749Sandreas@sandberg.pp.se    /** Start of frame event */
4509749Sandreas@sandberg.pp.se    EventWrapper<HDLcd, &HDLcd::startFrame> startFrameEvent;
4519749Sandreas@sandberg.pp.se
4529749Sandreas@sandberg.pp.se    /** End of frame event */
4539749Sandreas@sandberg.pp.se    EventWrapper<HDLcd, &HDLcd::endFrame> endFrameEvent;
4549749Sandreas@sandberg.pp.se
4559749Sandreas@sandberg.pp.se    /** Pixel render event */
4569749Sandreas@sandberg.pp.se    EventWrapper<HDLcd, &HDLcd::renderPixel> renderPixelEvent;
4579749Sandreas@sandberg.pp.se
4589749Sandreas@sandberg.pp.se    /** Fill fifo */
4599749Sandreas@sandberg.pp.se    EventWrapper<HDLcd, &HDLcd::fillPixelBuffer> fillPixelBufferEvent;
4609749Sandreas@sandberg.pp.se
4619749Sandreas@sandberg.pp.se    /** Wrapper to create an event out of the interrupt */
4629749Sandreas@sandberg.pp.se    EventWrapper<HDLcd, &HDLcd::generateInterrupt> intEvent;
4639749Sandreas@sandberg.pp.se
4649749Sandreas@sandberg.pp.se    /**@{*/
4659749Sandreas@sandberg.pp.se    /**
4669749Sandreas@sandberg.pp.se     * All pre-allocated DMA done events
4679749Sandreas@sandberg.pp.se     *
46810464SAndreas.Sandberg@ARM.com     * The HDLCD model preallocates maxOutstandingDma() number of
46910464SAndreas.Sandberg@ARM.com     * DmaDoneEvents to avoid having to heap allocate every single
47010464SAndreas.Sandberg@ARM.com     * event when it is needed. In order to keep track of which events
47110464SAndreas.Sandberg@ARM.com     * are in flight and which are ready to be used, we use two
47210464SAndreas.Sandberg@ARM.com     * different vectors. dmaDoneEventAll contains <i>all</i>
47310464SAndreas.Sandberg@ARM.com     * DmaDoneEvents that the object may use, while dmaDoneEventFree
47410464SAndreas.Sandberg@ARM.com     * contains a list of currently <i>unused</i> events. When an
47510464SAndreas.Sandberg@ARM.com     * event needs to be scheduled, the last element of the
47610464SAndreas.Sandberg@ARM.com     * dmaDoneEventFree is used and removed from the list. When an
47710464SAndreas.Sandberg@ARM.com     * event fires, it is added to the end of the
47810464SAndreas.Sandberg@ARM.com     * dmaEventFreeList. dmaDoneEventAll is never used except for in
47910464SAndreas.Sandberg@ARM.com     * initialization and serialization.
48010464SAndreas.Sandberg@ARM.com     */
48110464SAndreas.Sandberg@ARM.com    std::vector<DmaDoneEvent> dmaDoneEventAll;
48210464SAndreas.Sandberg@ARM.com
48310464SAndreas.Sandberg@ARM.com    /** Unused DMA done events that are ready to be scheduled */
48410464SAndreas.Sandberg@ARM.com    std::vector<DmaDoneEvent *> dmaDoneEventFree;
48510464SAndreas.Sandberg@ARM.com    /**@}*/
48610464SAndreas.Sandberg@ARM.com
48710464SAndreas.Sandberg@ARM.com    bool enableCapture;
48810464SAndreas.Sandberg@ARM.com
48910464SAndreas.Sandberg@ARM.com  public:
49010464SAndreas.Sandberg@ARM.com    typedef HDLcdParams Params;
49110464SAndreas.Sandberg@ARM.com
49210464SAndreas.Sandberg@ARM.com    const Params *
49310464SAndreas.Sandberg@ARM.com    params() const
49410464SAndreas.Sandberg@ARM.com    {
49510464SAndreas.Sandberg@ARM.com        return dynamic_cast<const Params *>(_params);
49610464SAndreas.Sandberg@ARM.com    }
49710464SAndreas.Sandberg@ARM.com    HDLcd(const Params *p);
49810464SAndreas.Sandberg@ARM.com    ~HDLcd();
49910464SAndreas.Sandberg@ARM.com
50010464SAndreas.Sandberg@ARM.com    virtual Tick read(PacketPtr pkt);
50110464SAndreas.Sandberg@ARM.com    virtual Tick write(PacketPtr pkt);
50210464SAndreas.Sandberg@ARM.com
50310464SAndreas.Sandberg@ARM.com    virtual void serialize(std::ostream &os);
50410464SAndreas.Sandberg@ARM.com    virtual void unserialize(Checkpoint *cp, const std::string &section);
50510464SAndreas.Sandberg@ARM.com
50610464SAndreas.Sandberg@ARM.com    /**
50710464SAndreas.Sandberg@ARM.com     * Determine the address ranges that this device responds to.
50810464SAndreas.Sandberg@ARM.com     *
50910464SAndreas.Sandberg@ARM.com     * @return a list of non-overlapping address ranges
51010464SAndreas.Sandberg@ARM.com     */
51110464SAndreas.Sandberg@ARM.com    AddrRangeList getAddrRanges() const;
51210464SAndreas.Sandberg@ARM.com};
51310464SAndreas.Sandberg@ARM.com
51410464SAndreas.Sandberg@ARM.com#endif
51510464SAndreas.Sandberg@ARM.com