hdlcd.hh revision 9939
19646SChris.Emmons@arm.com/* 29646SChris.Emmons@arm.com * Copyright (c) 2010-2013 ARM Limited 39646SChris.Emmons@arm.com * All rights reserved 49646SChris.Emmons@arm.com * 59646SChris.Emmons@arm.com * The license below extends only to copyright in the software and shall 69646SChris.Emmons@arm.com * not be construed as granting a license to any other intellectual 79646SChris.Emmons@arm.com * property including but not limited to intellectual property relating 89646SChris.Emmons@arm.com * to a hardware implementation of the functionality of the software 99646SChris.Emmons@arm.com * licensed hereunder. You may use the software subject to the license 109646SChris.Emmons@arm.com * terms below provided that you ensure that this notice is replicated 119646SChris.Emmons@arm.com * unmodified and in its entirety in all distributions of the software, 129646SChris.Emmons@arm.com * modified or unmodified, in source code or in binary form. 139646SChris.Emmons@arm.com * 149646SChris.Emmons@arm.com * Redistribution and use in source and binary forms, with or without 159646SChris.Emmons@arm.com * modification, are permitted provided that the following conditions are 169646SChris.Emmons@arm.com * met: redistributions of source code must retain the above copyright 179646SChris.Emmons@arm.com * notice, this list of conditions and the following disclaimer; 189646SChris.Emmons@arm.com * redistributions in binary form must reproduce the above copyright 199646SChris.Emmons@arm.com * notice, this list of conditions and the following disclaimer in the 209646SChris.Emmons@arm.com * documentation and/or other materials provided with the distribution; 219646SChris.Emmons@arm.com * neither the name of the copyright holders nor the names of its 229646SChris.Emmons@arm.com * contributors may be used to endorse or promote products derived from 239646SChris.Emmons@arm.com * this software without specific prior written permission. 249646SChris.Emmons@arm.com * 259646SChris.Emmons@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 269646SChris.Emmons@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 279646SChris.Emmons@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 289646SChris.Emmons@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 299646SChris.Emmons@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 309646SChris.Emmons@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 319646SChris.Emmons@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 329646SChris.Emmons@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 339646SChris.Emmons@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 349646SChris.Emmons@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 359646SChris.Emmons@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 369646SChris.Emmons@arm.com * 379646SChris.Emmons@arm.com * Authors: Chris Emmons 389646SChris.Emmons@arm.com */ 399646SChris.Emmons@arm.com 409646SChris.Emmons@arm.com 419646SChris.Emmons@arm.com/** @file 429646SChris.Emmons@arm.com * Implementiation of the ARM HDLcd controller. 439646SChris.Emmons@arm.com * 449646SChris.Emmons@arm.com * This implementation aims to have sufficient detail such that underrun 459646SChris.Emmons@arm.com * conditions are reasonable / behave similar to reality. There are two 469646SChris.Emmons@arm.com * 'engines' going at once. First, the DMA engine running at LCD clock 479646SChris.Emmons@arm.com * frequency is responsible for filling the controller's internal buffer. 489646SChris.Emmons@arm.com * The second engine runs at the pixel clock frequency and reads the pixels 499646SChris.Emmons@arm.com * out of the internal buffer. The pixel rendering engine uses front / back 509646SChris.Emmons@arm.com * porch and sync delays between lines and frames. 519646SChris.Emmons@arm.com * 529646SChris.Emmons@arm.com * If the pixel rendering engine does not have a pixel to display, it will 539646SChris.Emmons@arm.com * cause an underrun event. The HDLcd controller, per spec, will stop 549646SChris.Emmons@arm.com * issuing DMA requests for the rest of the frame and resume normal behavior 559646SChris.Emmons@arm.com * on the subsequent frame. What pixels are rendered upon an underrun 569646SChris.Emmons@arm.com * condition is different than the real hardware; while the user will see 579646SChris.Emmons@arm.com * artifacts (previous frame mixed with current frame), it is not the same 589646SChris.Emmons@arm.com * behavior as real hardware which repeats the last pixel value for the rest 599646SChris.Emmons@arm.com * of the current frame. This compromise was made to save on memory and 609646SChris.Emmons@arm.com * complexity and assumes that it is not important to accurately model the 619646SChris.Emmons@arm.com * content of an underrun frame. 629646SChris.Emmons@arm.com * 639646SChris.Emmons@arm.com * KNOWN ISSUES 649646SChris.Emmons@arm.com * 1. The default kernel driver used in testing sets the line count to one 659646SChris.Emmons@arm.com * less than the expected 768. However, it also sets the v_count to 767. 669646SChris.Emmons@arm.com * The controller specifies that 1 should be added to v_count but does not 679646SChris.Emmons@arm.com * specify adding 1 to the line count. The driver is probably wrong. 689646SChris.Emmons@arm.com * However, to sync these two numbers up, this model uses fb_line_count and 699646SChris.Emmons@arm.com * fb_line_length rather than using v_data or h_data values to determine the 709646SChris.Emmons@arm.com * width and height of the frame; those values are ignored. 719646SChris.Emmons@arm.com * 2. The HDLcd is implemented here as an AmbaDmaDevice, but it doesn't have 729646SChris.Emmons@arm.com * an AMBA ID as far as I know. That is the only bit of the AmbaDmaDevice 739646SChris.Emmons@arm.com * interface that is irrelevant to it, so a fake AMBA ID is used for now. 749646SChris.Emmons@arm.com * I didn't think inserting an extra layer of hierachy between AmbaDmaDevice 759646SChris.Emmons@arm.com * and DmaDevice would be helpful to anyone else, but that may be the right 769646SChris.Emmons@arm.com * answer. 779646SChris.Emmons@arm.com * 3. The internal buffer size is either 1 or 2 KB depending on which 789646SChris.Emmons@arm.com * specification is referenced for the different Versatile Express tiles. 799646SChris.Emmons@arm.com * This implementation uses the larger 2 KB buffer by default. 809646SChris.Emmons@arm.com */ 819646SChris.Emmons@arm.com 829646SChris.Emmons@arm.com#ifndef __DEV_ARM_HDLCD_HH__ 839646SChris.Emmons@arm.com#define __DEV_ARM_HDLCD_HH__ 849646SChris.Emmons@arm.com 859646SChris.Emmons@arm.com#include <fstream> 869646SChris.Emmons@arm.com 879646SChris.Emmons@arm.com#include "dev/arm/amba_device.hh" 889646SChris.Emmons@arm.com#include "params/HDLcd.hh" 899646SChris.Emmons@arm.com#include "sim/serialize.hh" 909646SChris.Emmons@arm.com 919646SChris.Emmons@arm.comclass VncInput; 929646SChris.Emmons@arm.comclass Bitmap; 939646SChris.Emmons@arm.com 949646SChris.Emmons@arm.comclass HDLcd: public AmbaDmaDevice 959646SChris.Emmons@arm.com{ 969646SChris.Emmons@arm.com protected: 979646SChris.Emmons@arm.com /** fake AMBA ID -- unused */ 989646SChris.Emmons@arm.com static const uint64_t AMBA_ID = ULL(0xb105f00d00141000); 999646SChris.Emmons@arm.com 1009646SChris.Emmons@arm.com /** ARM HDLcd register offsets */ 1019646SChris.Emmons@arm.com enum RegisterOffset { 1029646SChris.Emmons@arm.com Version = 0x0000, 1039646SChris.Emmons@arm.com Int_RawStat = 0x0010, 1049646SChris.Emmons@arm.com Int_Clear = 0x0014, 1059646SChris.Emmons@arm.com Int_Mask = 0x0018, 1069646SChris.Emmons@arm.com Int_Status = 0x001C, 1079646SChris.Emmons@arm.com Fb_Base = 0x0100, 1089646SChris.Emmons@arm.com Fb_Line_Length = 0x0104, 1099646SChris.Emmons@arm.com Fb_Line_Count = 0x0108, 1109646SChris.Emmons@arm.com Fb_Line_Pitch = 0x010C, 1119646SChris.Emmons@arm.com Bus_Options = 0x0110, 1129646SChris.Emmons@arm.com V_Sync = 0x0200, 1139646SChris.Emmons@arm.com V_Back_Porch = 0x0204, 1149646SChris.Emmons@arm.com V_Data = 0x0208, 1159646SChris.Emmons@arm.com V_Front_Porch = 0x020C, 1169646SChris.Emmons@arm.com H_Sync = 0x0210, 1179646SChris.Emmons@arm.com H_Back_Porch = 0x0214, 1189646SChris.Emmons@arm.com H_Data = 0x0218, 1199646SChris.Emmons@arm.com H_Front_Porch = 0x021C, 1209646SChris.Emmons@arm.com Polarities = 0x0220, 1219646SChris.Emmons@arm.com Command = 0x0230, 1229646SChris.Emmons@arm.com Pixel_Format = 0x0240, 1239646SChris.Emmons@arm.com Red_Select = 0x0244, 1249646SChris.Emmons@arm.com Green_Select = 0x0248, 1259646SChris.Emmons@arm.com Blue_Select = 0x024C }; 1269646SChris.Emmons@arm.com 1279646SChris.Emmons@arm.com /** Reset value for Bus_Options register */ 1289646SChris.Emmons@arm.com static const size_t BUS_OPTIONS_RESETV = 0x408; 1299646SChris.Emmons@arm.com 1309646SChris.Emmons@arm.com /** Reset value for Version register */ 1319646SChris.Emmons@arm.com static const size_t VERSION_RESETV = 0x1CDC0000; 1329646SChris.Emmons@arm.com 1339646SChris.Emmons@arm.com /** max number of outstanding DMA requests possible */ 1349646SChris.Emmons@arm.com static const size_t MAX_OUTSTANDING_DMA_REQ_CAPACITY = 16; 1359646SChris.Emmons@arm.com 1369646SChris.Emmons@arm.com /** max number of beats delivered in one dma burst */ 1379646SChris.Emmons@arm.com static const size_t MAX_BURST_LEN = 16; 1389646SChris.Emmons@arm.com 1399646SChris.Emmons@arm.com /** size of internal buffer in bytes */ 1409646SChris.Emmons@arm.com static const size_t PIXEL_BUFFER_CAPACITY = 2048; 1419646SChris.Emmons@arm.com 1429646SChris.Emmons@arm.com /** AXI port width in bytes */ 1439646SChris.Emmons@arm.com static const size_t AXI_PORT_WIDTH = 8; 1449646SChris.Emmons@arm.com 1459646SChris.Emmons@arm.com /** 1469646SChris.Emmons@arm.com * @name RegisterFieldLayouts 1479646SChris.Emmons@arm.com * Bit layout declarations for multi-field registers. 1489646SChris.Emmons@arm.com */ 1499646SChris.Emmons@arm.com /**@{*/ 1509646SChris.Emmons@arm.com BitUnion32(VersionReg) 1519646SChris.Emmons@arm.com Bitfield<7,0> version_minor; 1529646SChris.Emmons@arm.com Bitfield<15,8> version_major; 1539646SChris.Emmons@arm.com Bitfield<31,16> product_id; 1549646SChris.Emmons@arm.com EndBitUnion(VersionReg) 1559646SChris.Emmons@arm.com 1569646SChris.Emmons@arm.com BitUnion32(InterruptReg) 1579646SChris.Emmons@arm.com Bitfield<0> dma_end; 1589646SChris.Emmons@arm.com Bitfield<1> bus_error; 1599646SChris.Emmons@arm.com Bitfield<2> vsync; 1609646SChris.Emmons@arm.com Bitfield<3> underrun; 1619646SChris.Emmons@arm.com EndBitUnion(InterruptReg) 1629646SChris.Emmons@arm.com 1639646SChris.Emmons@arm.com BitUnion32(FbLineCountReg) 1649646SChris.Emmons@arm.com Bitfield<11,0> fb_line_count; 1659646SChris.Emmons@arm.com Bitfield<31,12> reserved_31_12; 1669646SChris.Emmons@arm.com EndBitUnion(FbLineCountReg) 1679646SChris.Emmons@arm.com 1689646SChris.Emmons@arm.com BitUnion32(BusOptsReg) 1699646SChris.Emmons@arm.com Bitfield<4,0> burst_len; 1709646SChris.Emmons@arm.com Bitfield<7,5> reserved_7_5; 1719646SChris.Emmons@arm.com Bitfield<11,8> max_outstanding; 1729646SChris.Emmons@arm.com Bitfield<31,12> reserved_31_12; 1739646SChris.Emmons@arm.com EndBitUnion(BusOptsReg) 1749646SChris.Emmons@arm.com 1759646SChris.Emmons@arm.com BitUnion32(TimingReg) 1769646SChris.Emmons@arm.com Bitfield<11,0> val; 1779646SChris.Emmons@arm.com Bitfield<31,12> reserved_31_12; 1789646SChris.Emmons@arm.com EndBitUnion(TimingReg) 1799646SChris.Emmons@arm.com 1809646SChris.Emmons@arm.com BitUnion32(PolaritiesReg) 1819646SChris.Emmons@arm.com Bitfield<0> vsync_polarity; 1829646SChris.Emmons@arm.com Bitfield<1> hsync_polarity; 1839646SChris.Emmons@arm.com Bitfield<2> dataen_polarity; 1849646SChris.Emmons@arm.com Bitfield<3> data_polarity; 1859646SChris.Emmons@arm.com Bitfield<4> pxlclk_polarity; 1869646SChris.Emmons@arm.com Bitfield<31,5> reserved_31_5; 1879646SChris.Emmons@arm.com EndBitUnion(PolaritiesReg) 1889646SChris.Emmons@arm.com 1899646SChris.Emmons@arm.com BitUnion32(CommandReg) 1909646SChris.Emmons@arm.com Bitfield<0> enable; 1919646SChris.Emmons@arm.com Bitfield<31,1> reserved_31_1; 1929646SChris.Emmons@arm.com EndBitUnion(CommandReg) 1939646SChris.Emmons@arm.com 1949646SChris.Emmons@arm.com BitUnion32(PixelFormatReg) 1959646SChris.Emmons@arm.com Bitfield<2,0> reserved_2_0; 1969646SChris.Emmons@arm.com Bitfield<4,3> bytes_per_pixel; 1979646SChris.Emmons@arm.com Bitfield<30,5> reserved_30_5; 1989646SChris.Emmons@arm.com Bitfield<31> big_endian; 1999646SChris.Emmons@arm.com EndBitUnion(PixelFormatReg) 2009646SChris.Emmons@arm.com 2019646SChris.Emmons@arm.com BitUnion32(ColorSelectReg) 2029646SChris.Emmons@arm.com Bitfield<4,0> offset; 2039646SChris.Emmons@arm.com Bitfield<7,5> reserved_7_5; 2049646SChris.Emmons@arm.com Bitfield<11,8> size; 2059646SChris.Emmons@arm.com Bitfield<15,12> reserved_15_12; 2069646SChris.Emmons@arm.com Bitfield<23,16> default_color; 2079646SChris.Emmons@arm.com Bitfield<31,24> reserved_31_24; 2089646SChris.Emmons@arm.com EndBitUnion(ColorSelectReg) 2099646SChris.Emmons@arm.com /**@}*/ 2109646SChris.Emmons@arm.com 2119646SChris.Emmons@arm.com /** 2129646SChris.Emmons@arm.com * @name HDLCDRegisters 2139646SChris.Emmons@arm.com * HDLCD register contents. 2149646SChris.Emmons@arm.com */ 2159646SChris.Emmons@arm.com /**@{*/ 2169646SChris.Emmons@arm.com VersionReg version; /**< Version register */ 2179646SChris.Emmons@arm.com InterruptReg int_rawstat; /**< Interrupt raw status register */ 2189646SChris.Emmons@arm.com InterruptReg int_clear; /**< Interrupt clear register */ 2199646SChris.Emmons@arm.com InterruptReg int_mask; /**< Interrupt mask register */ 2209646SChris.Emmons@arm.com InterruptReg int_status; /**< Interrupt status register */ 2219646SChris.Emmons@arm.com uint32_t fb_base; /**< Frame buffer base address register */ 2229646SChris.Emmons@arm.com uint32_t fb_line_length; /**< Frame buffer Line length register */ 2239646SChris.Emmons@arm.com FbLineCountReg fb_line_count; /**< Frame buffer Line count register */ 2249646SChris.Emmons@arm.com uint32_t fb_line_pitch; /**< Frame buffer Line pitch register */ 2259646SChris.Emmons@arm.com BusOptsReg bus_options; /**< Bus options register */ 2269646SChris.Emmons@arm.com TimingReg v_sync; /**< Vertical sync width register */ 2279646SChris.Emmons@arm.com TimingReg v_back_porch; /**< Vertical back porch width register */ 2289646SChris.Emmons@arm.com TimingReg v_data; /**< Vertical data width register */ 2299646SChris.Emmons@arm.com TimingReg v_front_porch; /**< Vertical front porch width register */ 2309646SChris.Emmons@arm.com TimingReg h_sync; /**< Horizontal sync width register */ 2319646SChris.Emmons@arm.com TimingReg h_back_porch; /**< Horizontal back porch width register */ 2329646SChris.Emmons@arm.com TimingReg h_data; /**< Horizontal data width register */ 2339646SChris.Emmons@arm.com TimingReg h_front_porch; /**< Horizontal front porch width reg */ 2349646SChris.Emmons@arm.com PolaritiesReg polarities; /**< Polarities register */ 2359646SChris.Emmons@arm.com CommandReg command; /**< Command register */ 2369646SChris.Emmons@arm.com PixelFormatReg pixel_format; /**< Pixel format register */ 2379646SChris.Emmons@arm.com ColorSelectReg red_select; /**< Red color select register */ 2389646SChris.Emmons@arm.com ColorSelectReg green_select; /**< Green color select register */ 2399646SChris.Emmons@arm.com ColorSelectReg blue_select; /**< Blue color select register */ 2409646SChris.Emmons@arm.com /** @} */ 2419646SChris.Emmons@arm.com 2429646SChris.Emmons@arm.com /** Pixel clock period */ 2439646SChris.Emmons@arm.com const Tick pixelClock; 2449646SChris.Emmons@arm.com 2459646SChris.Emmons@arm.com /** VNC server */ 2469646SChris.Emmons@arm.com VncInput *vnc; 2479646SChris.Emmons@arm.com 2489646SChris.Emmons@arm.com /** Helper to write out bitmaps */ 2499646SChris.Emmons@arm.com Bitmap *bmp; 2509646SChris.Emmons@arm.com 2519646SChris.Emmons@arm.com /** Picture of what the current frame buffer looks like */ 2529646SChris.Emmons@arm.com std::ostream *pic; 2539646SChris.Emmons@arm.com 2549646SChris.Emmons@arm.com /** 2559646SChris.Emmons@arm.com * Event wrapper for dmaDone() 2569646SChris.Emmons@arm.com * 2579646SChris.Emmons@arm.com * This event call pushes its this pointer onto the freeDoneEvent vector 2589646SChris.Emmons@arm.com * and calls dmaDone() when triggered. While most of the time the burst 2599646SChris.Emmons@arm.com * length of a transaction will be the max burst length set by the driver, 2609646SChris.Emmons@arm.com * any trailing bytes must be handled with smaller lengths thus requiring 2619646SChris.Emmons@arm.com * the configurable burst length option. 2629646SChris.Emmons@arm.com */ 2639646SChris.Emmons@arm.com class DmaDoneEvent : public Event 2649646SChris.Emmons@arm.com { 2659646SChris.Emmons@arm.com private: 2669646SChris.Emmons@arm.com /** Reference to HDLCD that issued the corresponding DMA transaction */ 2679646SChris.Emmons@arm.com HDLcd &obj; 2689646SChris.Emmons@arm.com 2699646SChris.Emmons@arm.com /** Transaction size */ 2709646SChris.Emmons@arm.com size_t transSize; 2719646SChris.Emmons@arm.com 2729646SChris.Emmons@arm.com public: 2739646SChris.Emmons@arm.com /** 2749646SChris.Emmons@arm.com * Constructor. 2759646SChris.Emmons@arm.com * 2769646SChris.Emmons@arm.com * @param _obj HDLCD that issued the corresponding DMA transaction 2779646SChris.Emmons@arm.com */ 2789646SChris.Emmons@arm.com DmaDoneEvent(HDLcd *_obj) 2799646SChris.Emmons@arm.com : Event(), obj(*_obj), transSize(0) {} 2809646SChris.Emmons@arm.com 2819646SChris.Emmons@arm.com /** 2829646SChris.Emmons@arm.com * Sets the size of this transaction. 2839646SChris.Emmons@arm.com * 2849646SChris.Emmons@arm.com * @param len size of the transaction in bytes 2859646SChris.Emmons@arm.com */ 2869646SChris.Emmons@arm.com void setTransactionSize(size_t len) { 2879646SChris.Emmons@arm.com transSize = len; 2889646SChris.Emmons@arm.com } 2899646SChris.Emmons@arm.com 2909646SChris.Emmons@arm.com /** 2919646SChris.Emmons@arm.com * Gets the size of this transaction. 2929646SChris.Emmons@arm.com * 2939646SChris.Emmons@arm.com * @return size of this transaction in bytes 2949646SChris.Emmons@arm.com */ 2959646SChris.Emmons@arm.com size_t getTransactionSize() const { 2969646SChris.Emmons@arm.com return transSize; 2979646SChris.Emmons@arm.com } 2989646SChris.Emmons@arm.com 2999646SChris.Emmons@arm.com void process() { 3009646SChris.Emmons@arm.com obj.dmaDone(this); 3019646SChris.Emmons@arm.com } 3029646SChris.Emmons@arm.com 3039646SChris.Emmons@arm.com const std::string name() const { 3049646SChris.Emmons@arm.com return obj.name() + ".DmaDoneEvent"; 3059646SChris.Emmons@arm.com } 3069646SChris.Emmons@arm.com }; 3079646SChris.Emmons@arm.com 3089646SChris.Emmons@arm.com /** Start time for frame buffer dma read */ 3099646SChris.Emmons@arm.com Tick frameReadStartTime; 3109646SChris.Emmons@arm.com 3119646SChris.Emmons@arm.com /** Starting address for the current frame */ 3129646SChris.Emmons@arm.com Addr dmaStartAddr; 3139646SChris.Emmons@arm.com 3149646SChris.Emmons@arm.com /** Next address the dma should read from */ 3159646SChris.Emmons@arm.com Addr dmaCurAddr; 3169646SChris.Emmons@arm.com 3179646SChris.Emmons@arm.com /** One byte past the address of the last byte the dma should read 3189646SChris.Emmons@arm.com * from */ 3199646SChris.Emmons@arm.com Addr dmaMaxAddr; 3209646SChris.Emmons@arm.com 3219646SChris.Emmons@arm.com /** Number of pending dma reads */ 3229646SChris.Emmons@arm.com size_t dmaPendingNum; 3239646SChris.Emmons@arm.com 3249646SChris.Emmons@arm.com /** Flag indicating whether current frame has underrun */ 3259646SChris.Emmons@arm.com bool frameUnderrun; 3269646SChris.Emmons@arm.com 3279646SChris.Emmons@arm.com /** HDLcd virtual display buffer */ 3289646SChris.Emmons@arm.com uint8_t *virtualDisplayBuffer; 3299646SChris.Emmons@arm.com 3309646SChris.Emmons@arm.com /** Size of the pixel buffer */ 3319646SChris.Emmons@arm.com size_t pixelBufferSize; 3329646SChris.Emmons@arm.com 3339646SChris.Emmons@arm.com /** Index of the next pixel to render */ 3349646SChris.Emmons@arm.com size_t pixelIndex; 3359646SChris.Emmons@arm.com 3369646SChris.Emmons@arm.com /** Flag indicating whether video parameters need updating */ 3379646SChris.Emmons@arm.com bool doUpdateParams; 3389646SChris.Emmons@arm.com 3399646SChris.Emmons@arm.com /** Flag indicating whether a frame read / display is in progress */ 3409646SChris.Emmons@arm.com bool frameUnderway; 3419646SChris.Emmons@arm.com 3429646SChris.Emmons@arm.com /** 3439646SChris.Emmons@arm.com * Number of bytes in flight from DMA that have not reached the pixel 3449646SChris.Emmons@arm.com * buffer yet 3459646SChris.Emmons@arm.com */ 3469646SChris.Emmons@arm.com uint32_t dmaBytesInFlight; 3479646SChris.Emmons@arm.com 3489646SChris.Emmons@arm.com /** 3499646SChris.Emmons@arm.com * Gets the number of oustanding DMA transactions allowed on the bus at a 3509646SChris.Emmons@arm.com * time. 3519646SChris.Emmons@arm.com * 3529646SChris.Emmons@arm.com * @return gets the driver-specified number of outstanding DMA transactions 3539646SChris.Emmons@arm.com * from the hdlcd controller that are allowed on the bus at a time 3549646SChris.Emmons@arm.com */ 3559646SChris.Emmons@arm.com inline uint16_t maxOutstandingDma() const { 3569646SChris.Emmons@arm.com return bus_options.max_outstanding; 3579646SChris.Emmons@arm.com } 3589646SChris.Emmons@arm.com 3599646SChris.Emmons@arm.com /** 3609646SChris.Emmons@arm.com * Gets the number of bytes free in the pixel buffer. 3619646SChris.Emmons@arm.com * 3629646SChris.Emmons@arm.com * @return number of bytes free in the internal pixel buffer 3639646SChris.Emmons@arm.com */ 3649646SChris.Emmons@arm.com inline uint32_t bytesFreeInPixelBuffer() const { 3659646SChris.Emmons@arm.com return PIXEL_BUFFER_CAPACITY - (pixelBufferSize + dmaBytesInFlight); 3669646SChris.Emmons@arm.com } 3679646SChris.Emmons@arm.com 3689646SChris.Emmons@arm.com /** 3699646SChris.Emmons@arm.com * Gets the number of beats-per-burst for bus transactions. 3709646SChris.Emmons@arm.com * 3719646SChris.Emmons@arm.com * @return number of beats-per-burst per HDLcd DMA transaction 3729646SChris.Emmons@arm.com */ 3739646SChris.Emmons@arm.com inline size_t dmaBurstLength() const { 3749646SChris.Emmons@arm.com assert(bus_options.burst_len <= MAX_BURST_LEN); 3759646SChris.Emmons@arm.com return bus_options.burst_len; 3769646SChris.Emmons@arm.com } 3779646SChris.Emmons@arm.com 3789646SChris.Emmons@arm.com /** 3799646SChris.Emmons@arm.com * Gets the number of bytes per pixel. 3809646SChris.Emmons@arm.com * 3819646SChris.Emmons@arm.com * @return bytes per pixel 3829646SChris.Emmons@arm.com */ 3839646SChris.Emmons@arm.com inline size_t bytesPerPixel() const { 3849646SChris.Emmons@arm.com return pixel_format.bytes_per_pixel + 1; 3859646SChris.Emmons@arm.com } 3869646SChris.Emmons@arm.com 3879646SChris.Emmons@arm.com /** 3889646SChris.Emmons@arm.com * Gets frame buffer width. 3899646SChris.Emmons@arm.com * 3909646SChris.Emmons@arm.com * @return frame buffer width (pixels per line) 3919646SChris.Emmons@arm.com */ 3929646SChris.Emmons@arm.com inline size_t width() const { 3939646SChris.Emmons@arm.com return fb_line_length / bytesPerPixel(); 3949646SChris.Emmons@arm.com } 3959646SChris.Emmons@arm.com 3969646SChris.Emmons@arm.com /** 3979646SChris.Emmons@arm.com * Gets frame buffer height. 3989646SChris.Emmons@arm.com * 3999646SChris.Emmons@arm.com * @return frame buffer height (lines per panel) 4009646SChris.Emmons@arm.com */ 4019646SChris.Emmons@arm.com inline size_t height() const { 4029646SChris.Emmons@arm.com return fb_line_count.fb_line_count; 4039646SChris.Emmons@arm.com } 4049646SChris.Emmons@arm.com 4059646SChris.Emmons@arm.com /** 4069646SChris.Emmons@arm.com * Gets the total number of pixel clocks per display line. 4079646SChris.Emmons@arm.com * 4089646SChris.Emmons@arm.com * @return number of pixel clocks per display line including porch delays 4099646SChris.Emmons@arm.com * and horizontal sync time 4109646SChris.Emmons@arm.com */ 4119646SChris.Emmons@arm.com inline uint64_t PClksPerLine() const { 4129646SChris.Emmons@arm.com return h_back_porch.val + 1 + 4139646SChris.Emmons@arm.com h_data.val + 1 + 4149646SChris.Emmons@arm.com h_front_porch.val + 1 + 4159646SChris.Emmons@arm.com h_sync.val + 1; 4169646SChris.Emmons@arm.com } 4179646SChris.Emmons@arm.com 4189646SChris.Emmons@arm.com /** Send updated parameters to the vnc server */ 4199646SChris.Emmons@arm.com void updateVideoParams(bool unserializing); 4209646SChris.Emmons@arm.com 4219646SChris.Emmons@arm.com /** Generates an interrupt */ 4229646SChris.Emmons@arm.com void generateInterrupt(); 4239646SChris.Emmons@arm.com 4249646SChris.Emmons@arm.com /** Start reading the next frame */ 4259646SChris.Emmons@arm.com void startFrame(); 4269646SChris.Emmons@arm.com 4279646SChris.Emmons@arm.com /** End of frame reached */ 4289646SChris.Emmons@arm.com void endFrame(); 4299646SChris.Emmons@arm.com 4309646SChris.Emmons@arm.com /** Generate DMA read requests from frame buffer into pixel buffer */ 4319646SChris.Emmons@arm.com void fillPixelBuffer(); 4329646SChris.Emmons@arm.com 4339646SChris.Emmons@arm.com /** DMA done event */ 4349646SChris.Emmons@arm.com void dmaDone(DmaDoneEvent *event); 4359646SChris.Emmons@arm.com 4369646SChris.Emmons@arm.com /** Called when it is time to render a pixel */ 4379646SChris.Emmons@arm.com void renderPixel(); 4389646SChris.Emmons@arm.com 4399646SChris.Emmons@arm.com /** Start of frame event */ 4409646SChris.Emmons@arm.com EventWrapper<HDLcd, &HDLcd::startFrame> startFrameEvent; 4419646SChris.Emmons@arm.com 4429646SChris.Emmons@arm.com /** End of frame event */ 4439646SChris.Emmons@arm.com EventWrapper<HDLcd, &HDLcd::endFrame> endFrameEvent; 4449646SChris.Emmons@arm.com 4459646SChris.Emmons@arm.com /** Pixel render event */ 4469646SChris.Emmons@arm.com EventWrapper<HDLcd, &HDLcd::renderPixel> renderPixelEvent; 4479646SChris.Emmons@arm.com 4489646SChris.Emmons@arm.com /** Fill fifo */ 4499646SChris.Emmons@arm.com EventWrapper<HDLcd, &HDLcd::fillPixelBuffer> fillPixelBufferEvent; 4509646SChris.Emmons@arm.com 4519646SChris.Emmons@arm.com /** Wrapper to create an event out of the interrupt */ 4529646SChris.Emmons@arm.com EventWrapper<HDLcd, &HDLcd::generateInterrupt> intEvent; 4539646SChris.Emmons@arm.com 4549646SChris.Emmons@arm.com /**@{*/ 4559646SChris.Emmons@arm.com /** 4569646SChris.Emmons@arm.com * All pre-allocated DMA done events 4579646SChris.Emmons@arm.com * 4589646SChris.Emmons@arm.com * The HDLCD model preallocates maxOutstandingDma() number of 4599646SChris.Emmons@arm.com * DmaDoneEvents to avoid having to heap allocate every single 4609646SChris.Emmons@arm.com * event when it is needed. In order to keep track of which events 4619646SChris.Emmons@arm.com * are in flight and which are ready to be used, we use two 4629646SChris.Emmons@arm.com * different vectors. dmaDoneEventAll contains <i>all</i> 4639646SChris.Emmons@arm.com * DmaDoneEvents that the object may use, while dmaDoneEventFree 4649646SChris.Emmons@arm.com * contains a list of currently <i>unused</i> events. When an 4659646SChris.Emmons@arm.com * event needs to be scheduled, the last element of the 4669646SChris.Emmons@arm.com * dmaDoneEventFree is used and removed from the list. When an 4679646SChris.Emmons@arm.com * event fires, it is added to the end of the 4689646SChris.Emmons@arm.com * dmaEventFreeList. dmaDoneEventAll is never used except for in 4699646SChris.Emmons@arm.com * initialization and serialization. 4709646SChris.Emmons@arm.com */ 4719646SChris.Emmons@arm.com std::vector<DmaDoneEvent> dmaDoneEventAll; 4729646SChris.Emmons@arm.com 4739646SChris.Emmons@arm.com /** Unused DMA done events that are ready to be scheduled */ 4749646SChris.Emmons@arm.com std::vector<DmaDoneEvent *> dmaDoneEventFree; 4759646SChris.Emmons@arm.com /**@}*/ 4769646SChris.Emmons@arm.com 4779939Sdam.sunwoo@arm.com bool enableCapture; 4789939Sdam.sunwoo@arm.com 4799646SChris.Emmons@arm.com public: 4809646SChris.Emmons@arm.com typedef HDLcdParams Params; 4819646SChris.Emmons@arm.com 4829646SChris.Emmons@arm.com const Params * 4839646SChris.Emmons@arm.com params() const 4849646SChris.Emmons@arm.com { 4859646SChris.Emmons@arm.com return dynamic_cast<const Params *>(_params); 4869646SChris.Emmons@arm.com } 4879646SChris.Emmons@arm.com HDLcd(const Params *p); 4889646SChris.Emmons@arm.com ~HDLcd(); 4899646SChris.Emmons@arm.com 4909646SChris.Emmons@arm.com virtual Tick read(PacketPtr pkt); 4919646SChris.Emmons@arm.com virtual Tick write(PacketPtr pkt); 4929646SChris.Emmons@arm.com 4939646SChris.Emmons@arm.com virtual void serialize(std::ostream &os); 4949646SChris.Emmons@arm.com virtual void unserialize(Checkpoint *cp, const std::string §ion); 4959646SChris.Emmons@arm.com 4969646SChris.Emmons@arm.com /** 4979646SChris.Emmons@arm.com * Determine the address ranges that this device responds to. 4989646SChris.Emmons@arm.com * 4999646SChris.Emmons@arm.com * @return a list of non-overlapping address ranges 5009646SChris.Emmons@arm.com */ 5019646SChris.Emmons@arm.com AddrRangeList getAddrRanges() const; 5029646SChris.Emmons@arm.com}; 5039646SChris.Emmons@arm.com 5049646SChris.Emmons@arm.com#endif 505