111012Sandreas.sandberg@arm.com/* 211897Ssudhanshu.jha@arm.com * Copyright (c) 2015, 2017 ARM Limited 311012Sandreas.sandberg@arm.com * All rights reserved 411012Sandreas.sandberg@arm.com * 511012Sandreas.sandberg@arm.com * The license below extends only to copyright in the software and shall 611012Sandreas.sandberg@arm.com * not be construed as granting a license to any other intellectual 711012Sandreas.sandberg@arm.com * property including but not limited to intellectual property relating 811012Sandreas.sandberg@arm.com * to a hardware implementation of the functionality of the software 911012Sandreas.sandberg@arm.com * licensed hereunder. You may use the software subject to the license 1011012Sandreas.sandberg@arm.com * terms below provided that you ensure that this notice is replicated 1111012Sandreas.sandberg@arm.com * unmodified and in its entirety in all distributions of the software, 1211012Sandreas.sandberg@arm.com * modified or unmodified, in source code or in binary form. 1311012Sandreas.sandberg@arm.com * 1411012Sandreas.sandberg@arm.com * Redistribution and use in source and binary forms, with or without 1511012Sandreas.sandberg@arm.com * modification, are permitted provided that the following conditions are 1611012Sandreas.sandberg@arm.com * met: redistributions of source code must retain the above copyright 1711012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer; 1811012Sandreas.sandberg@arm.com * redistributions in binary form must reproduce the above copyright 1911012Sandreas.sandberg@arm.com * notice, this list of conditions and the following disclaimer in the 2011012Sandreas.sandberg@arm.com * documentation and/or other materials provided with the distribution; 2111012Sandreas.sandberg@arm.com * neither the name of the copyright holders nor the names of its 2211012Sandreas.sandberg@arm.com * contributors may be used to endorse or promote products derived from 2311012Sandreas.sandberg@arm.com * this software without specific prior written permission. 2411012Sandreas.sandberg@arm.com * 2511012Sandreas.sandberg@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2611012Sandreas.sandberg@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2711012Sandreas.sandberg@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2811012Sandreas.sandberg@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2911012Sandreas.sandberg@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3011012Sandreas.sandberg@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3111012Sandreas.sandberg@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3211012Sandreas.sandberg@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3311012Sandreas.sandberg@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3411012Sandreas.sandberg@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3511012Sandreas.sandberg@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3611012Sandreas.sandberg@arm.com * 3711012Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 3811012Sandreas.sandberg@arm.com */ 3911012Sandreas.sandberg@arm.com 4011012Sandreas.sandberg@arm.com#ifndef __DEV_PIXELPUMP_HH__ 4111012Sandreas.sandberg@arm.com#define __DEV_PIXELPUMP_HH__ 4211012Sandreas.sandberg@arm.com 4311012Sandreas.sandberg@arm.com#include "base/framebuffer.hh" 4411012Sandreas.sandberg@arm.com#include "sim/clocked_object.hh" 4511012Sandreas.sandberg@arm.com 4611012Sandreas.sandberg@arm.comstruct BasePixelPumpParams; 4711012Sandreas.sandberg@arm.com 4811012Sandreas.sandberg@arm.comstruct DisplayTimings : public Serializable 4911012Sandreas.sandberg@arm.com{ 5011012Sandreas.sandberg@arm.com /** 5111012Sandreas.sandberg@arm.com * Create a display timing configuration struct 5211012Sandreas.sandberg@arm.com * 5311012Sandreas.sandberg@arm.com * @param width Width of the visible area of the screen. 5411012Sandreas.sandberg@arm.com * @param height Height of the visible area of the screen. 5511012Sandreas.sandberg@arm.com * @param hfp Horizontal front porch in pixel clocks. 5611012Sandreas.sandberg@arm.com * @param h_sync Horizontal sync in pixel clocks. 5711012Sandreas.sandberg@arm.com * @param hbp Horizontal back porch in pixel clocks. 5811012Sandreas.sandberg@arm.com * @param vfp Vertical front porch in scan lines. 5911012Sandreas.sandberg@arm.com * @param v_sync Vertical sync in scan lines. 6011012Sandreas.sandberg@arm.com * @param vbp Vertical back porch in scan lines. 6111012Sandreas.sandberg@arm.com */ 6211012Sandreas.sandberg@arm.com DisplayTimings(unsigned width, unsigned height, 6311012Sandreas.sandberg@arm.com unsigned hbp, unsigned h_sync, unsigned hfp, 6411012Sandreas.sandberg@arm.com unsigned vbp, unsigned v_sync, unsigned vfp); 6511012Sandreas.sandberg@arm.com 6611168Sandreas.hansson@arm.com void serialize(CheckpointOut &cp) const override; 6711168Sandreas.hansson@arm.com void unserialize(CheckpointIn &cp) override; 6811012Sandreas.sandberg@arm.com 6911012Sandreas.sandberg@arm.com /** How many pixel clocks are required for one line? */ 7011012Sandreas.sandberg@arm.com Cycles cyclesPerLine() const { 7111012Sandreas.sandberg@arm.com return Cycles(hSync + hBackPorch + width + hBackPorch); 7211012Sandreas.sandberg@arm.com } 7311012Sandreas.sandberg@arm.com 7411012Sandreas.sandberg@arm.com /** How many pixel clocks are required for one frame? */ 7511012Sandreas.sandberg@arm.com Cycles cyclesPerFrame() const { 7611012Sandreas.sandberg@arm.com return Cycles(cyclesPerLine() * linesPerFrame()); 7711012Sandreas.sandberg@arm.com } 7811012Sandreas.sandberg@arm.com 7911012Sandreas.sandberg@arm.com /** Calculate the first line of the vsync signal */ 8011012Sandreas.sandberg@arm.com unsigned lineVSyncStart() const { 8111012Sandreas.sandberg@arm.com return 0; 8211012Sandreas.sandberg@arm.com } 8311012Sandreas.sandberg@arm.com 8411012Sandreas.sandberg@arm.com /** Calculate the first line of the vertical back porch */ 8511012Sandreas.sandberg@arm.com unsigned lineVBackPorchStart() const { 8611012Sandreas.sandberg@arm.com return lineVSyncStart() + vSync; 8711012Sandreas.sandberg@arm.com } 8811012Sandreas.sandberg@arm.com 8911012Sandreas.sandberg@arm.com /** Calculate the first line of the visible region */ 9011012Sandreas.sandberg@arm.com unsigned lineFirstVisible() const { 9111012Sandreas.sandberg@arm.com return lineVBackPorchStart() + vBackPorch; 9211012Sandreas.sandberg@arm.com } 9311012Sandreas.sandberg@arm.com 9411012Sandreas.sandberg@arm.com /** Calculate the first line of the back porch */ 9511012Sandreas.sandberg@arm.com unsigned lineFrontPorchStart() const { 9611012Sandreas.sandberg@arm.com return lineFirstVisible() + height; 9711012Sandreas.sandberg@arm.com } 9811012Sandreas.sandberg@arm.com 9911012Sandreas.sandberg@arm.com /** Calculate the total number of lines in a frame */ 10011012Sandreas.sandberg@arm.com unsigned linesPerFrame() const { 10111012Sandreas.sandberg@arm.com return lineFrontPorchStart() + vFrontPorch; 10211012Sandreas.sandberg@arm.com } 10311012Sandreas.sandberg@arm.com 10411012Sandreas.sandberg@arm.com /** Display width in pixels */ 10511012Sandreas.sandberg@arm.com unsigned width; 10611012Sandreas.sandberg@arm.com /** Display height in pixels */ 10711012Sandreas.sandberg@arm.com unsigned height; 10811012Sandreas.sandberg@arm.com 10911012Sandreas.sandberg@arm.com /** Horizontal back porch in pixels */ 11011012Sandreas.sandberg@arm.com unsigned hBackPorch; 11111012Sandreas.sandberg@arm.com /** Horizontal front porch in pixels */ 11211012Sandreas.sandberg@arm.com unsigned hFrontPorch; 11311012Sandreas.sandberg@arm.com /** Horizontal sync signal length in pixels */ 11411012Sandreas.sandberg@arm.com unsigned hSync; 11511012Sandreas.sandberg@arm.com 11611012Sandreas.sandberg@arm.com /** Vertical back porch in lines */ 11711012Sandreas.sandberg@arm.com unsigned vBackPorch; 11811012Sandreas.sandberg@arm.com /** Vertical front porch in lines */ 11911012Sandreas.sandberg@arm.com unsigned vFrontPorch; 12011012Sandreas.sandberg@arm.com /** Vertical sync signal in lines */ 12111012Sandreas.sandberg@arm.com unsigned vSync; 12211012Sandreas.sandberg@arm.com 12311012Sandreas.sandberg@arm.com static const DisplayTimings vga; 12411012Sandreas.sandberg@arm.com}; 12511012Sandreas.sandberg@arm.com 12611012Sandreas.sandberg@arm.com/** 12711012Sandreas.sandberg@arm.com * Timing generator for a pixel-based display. 12811012Sandreas.sandberg@arm.com * 12911012Sandreas.sandberg@arm.com * Pixels are ordered relative to the top left corner of the 13011012Sandreas.sandberg@arm.com * display. Scan lines appear in the following order: 13111012Sandreas.sandberg@arm.com * <ol> 13211012Sandreas.sandberg@arm.com * <li>Vertical Sync (starting at line 0) 13311012Sandreas.sandberg@arm.com * <li>Vertical back porch 13411012Sandreas.sandberg@arm.com * <li>Visible lines 13511012Sandreas.sandberg@arm.com * <li>Vertical front porch 13611012Sandreas.sandberg@arm.com * </ol> 13711012Sandreas.sandberg@arm.com * 13811012Sandreas.sandberg@arm.com * Pixel order within a scan line: 13911012Sandreas.sandberg@arm.com * <ol> 14011012Sandreas.sandberg@arm.com * <li>Horizontal Sync 14111012Sandreas.sandberg@arm.com * <li>Horizontal Back Porch 14211012Sandreas.sandberg@arm.com * <li>Visible pixels 14311012Sandreas.sandberg@arm.com * <li>Horizontal Front Porch 14411012Sandreas.sandberg@arm.com * </ol> 14511012Sandreas.sandberg@arm.com */ 14611012Sandreas.sandberg@arm.comclass BasePixelPump 14711012Sandreas.sandberg@arm.com : public EventManager, public Clocked, 14811012Sandreas.sandberg@arm.com public Serializable 14911012Sandreas.sandberg@arm.com{ 15011012Sandreas.sandberg@arm.com public: 15111897Ssudhanshu.jha@arm.com BasePixelPump(EventManager &em, ClockDomain &pxl_clk, 15211897Ssudhanshu.jha@arm.com unsigned pixel_chunk); 15311012Sandreas.sandberg@arm.com virtual ~BasePixelPump(); 15411012Sandreas.sandberg@arm.com 15511168Sandreas.hansson@arm.com void serialize(CheckpointOut &cp) const override; 15611168Sandreas.hansson@arm.com void unserialize(CheckpointIn &cp) override; 15711012Sandreas.sandberg@arm.com 15811012Sandreas.sandberg@arm.com public: // Public API 15911897Ssudhanshu.jha@arm.com /** Update frame size using display timing */ 16011897Ssudhanshu.jha@arm.com void updateTimings(const DisplayTimings &timings); 16111897Ssudhanshu.jha@arm.com 16211897Ssudhanshu.jha@arm.com /** Render an entire frame in KVM execution mode */ 16311897Ssudhanshu.jha@arm.com void renderFrame(); 16411897Ssudhanshu.jha@arm.com 16511897Ssudhanshu.jha@arm.com /** Starting pushing pixels in timing mode */ 16611897Ssudhanshu.jha@arm.com void start(); 16711012Sandreas.sandberg@arm.com 16811012Sandreas.sandberg@arm.com /** Immediately stop pushing pixels */ 16911012Sandreas.sandberg@arm.com void stop(); 17011012Sandreas.sandberg@arm.com 17111012Sandreas.sandberg@arm.com /** Get a constant reference of the current display timings */ 17211012Sandreas.sandberg@arm.com const DisplayTimings &timings() const { return _timings; } 17311012Sandreas.sandberg@arm.com 17411012Sandreas.sandberg@arm.com /** Is the pixel pump active and refreshing the display? */ 17511012Sandreas.sandberg@arm.com bool active() const { return evBeginLine.active(); } 17611012Sandreas.sandberg@arm.com 17711012Sandreas.sandberg@arm.com /** Did a buffer underrun occur within this refresh interval? */ 17811012Sandreas.sandberg@arm.com bool underrun() const { return _underrun; } 17911012Sandreas.sandberg@arm.com 18011012Sandreas.sandberg@arm.com /** Is the current line within the visible range? */ 18111012Sandreas.sandberg@arm.com bool visibleLine() const { 18211012Sandreas.sandberg@arm.com return line >= _timings.lineFirstVisible() && 18311012Sandreas.sandberg@arm.com line < _timings.lineFrontPorchStart(); 18411012Sandreas.sandberg@arm.com } 18511012Sandreas.sandberg@arm.com 18611012Sandreas.sandberg@arm.com /** Current pixel position within the visible area */ 18711012Sandreas.sandberg@arm.com unsigned posX() const { return _posX; } 18811012Sandreas.sandberg@arm.com 18911012Sandreas.sandberg@arm.com /** Current pixel position within the visible area */ 19011012Sandreas.sandberg@arm.com unsigned posY() const { 19111012Sandreas.sandberg@arm.com return visibleLine() ? line - _timings.lineFirstVisible() : 0; 19211012Sandreas.sandberg@arm.com } 19311012Sandreas.sandberg@arm.com 19411012Sandreas.sandberg@arm.com /** Output frame buffer */ 19511012Sandreas.sandberg@arm.com FrameBuffer fb; 19611012Sandreas.sandberg@arm.com 19711012Sandreas.sandberg@arm.com protected: // Callbacks 19811012Sandreas.sandberg@arm.com /** 19911012Sandreas.sandberg@arm.com * Get the next pixel from the scan line buffer. 20011012Sandreas.sandberg@arm.com * 20111012Sandreas.sandberg@arm.com * @param p Output pixel value, undefined on underrun 20211012Sandreas.sandberg@arm.com * @return true on success, false on buffer underrun 20311012Sandreas.sandberg@arm.com */ 20411012Sandreas.sandberg@arm.com virtual bool nextPixel(Pixel &p) = 0; 20511012Sandreas.sandberg@arm.com 20611012Sandreas.sandberg@arm.com /** First pixel clock of the first VSync line. */ 20711012Sandreas.sandberg@arm.com virtual void onVSyncBegin() {}; 20811012Sandreas.sandberg@arm.com 20911012Sandreas.sandberg@arm.com /** 21011012Sandreas.sandberg@arm.com * Callback on the first pixel of the line after the end VSync 21111012Sandreas.sandberg@arm.com * region (typically the first pixel of the vertical back porch). 21211012Sandreas.sandberg@arm.com */ 21311012Sandreas.sandberg@arm.com virtual void onVSyncEnd() {}; 21411012Sandreas.sandberg@arm.com 21511012Sandreas.sandberg@arm.com /** 21611012Sandreas.sandberg@arm.com * Start of the HSync region. 21711012Sandreas.sandberg@arm.com * 21811012Sandreas.sandberg@arm.com * @note This is called even for scan lines outside of the visible 21911012Sandreas.sandberg@arm.com * region. 22011012Sandreas.sandberg@arm.com */ 22111012Sandreas.sandberg@arm.com virtual void onHSyncBegin() {}; 22211012Sandreas.sandberg@arm.com 22311012Sandreas.sandberg@arm.com /** 22411012Sandreas.sandberg@arm.com * Start of the first pixel after the HSync region. 22511012Sandreas.sandberg@arm.com * 22611012Sandreas.sandberg@arm.com * @note This is called even for scan lines outside of the visible 22711012Sandreas.sandberg@arm.com * region. 22811012Sandreas.sandberg@arm.com */ 22911012Sandreas.sandberg@arm.com virtual void onHSyncEnd() {}; 23011012Sandreas.sandberg@arm.com 23111012Sandreas.sandberg@arm.com /** 23211012Sandreas.sandberg@arm.com * Buffer underrun occurred on a frame. 23311012Sandreas.sandberg@arm.com * 23411012Sandreas.sandberg@arm.com * This method is called once if there is buffer underrun while 23511012Sandreas.sandberg@arm.com * refreshing the display. The underrun state is reset on the next 23611012Sandreas.sandberg@arm.com * refresh. 23711012Sandreas.sandberg@arm.com * 23811012Sandreas.sandberg@arm.com * @param x Coordinate within the visible region. 23911012Sandreas.sandberg@arm.com * @param y Coordinate within the visible region. 24011012Sandreas.sandberg@arm.com */ 24111012Sandreas.sandberg@arm.com virtual void onUnderrun(unsigned x, unsigned y) {}; 24211012Sandreas.sandberg@arm.com 24311012Sandreas.sandberg@arm.com /** Finished displaying the visible region of a frame */ 24411012Sandreas.sandberg@arm.com virtual void onFrameDone() {}; 24511012Sandreas.sandberg@arm.com 24611012Sandreas.sandberg@arm.com private: // Params 24711012Sandreas.sandberg@arm.com /** Maximum number of pixels to handle per render callback */ 24811012Sandreas.sandberg@arm.com const unsigned pixelChunk; 24911012Sandreas.sandberg@arm.com 25011012Sandreas.sandberg@arm.com private: 25111012Sandreas.sandberg@arm.com /** 25211012Sandreas.sandberg@arm.com * Callback helper class with suspend support. 25311012Sandreas.sandberg@arm.com * 25411012Sandreas.sandberg@arm.com * Unlike a normal EventWrapper, this class suspends an event on 25511012Sandreas.sandberg@arm.com * drain() and restarts it at drainResume(). The suspend operation 25611012Sandreas.sandberg@arm.com * stores the tick relative to curTick() and then deschedules the 25711012Sandreas.sandberg@arm.com * event. The resume operation schedules the event at curTick() 25811012Sandreas.sandberg@arm.com * plus the relative tick stored when the event was suspended. 25911012Sandreas.sandberg@arm.com */ 26011012Sandreas.sandberg@arm.com class PixelEvent : public Event, public Drainable 26111012Sandreas.sandberg@arm.com { 26211012Sandreas.sandberg@arm.com typedef void (BasePixelPump::* CallbackType)(); 26311012Sandreas.sandberg@arm.com 26411012Sandreas.sandberg@arm.com public: 26511012Sandreas.sandberg@arm.com PixelEvent(const char *name, BasePixelPump *parent, CallbackType func); 26611012Sandreas.sandberg@arm.com 26711168Sandreas.hansson@arm.com DrainState drain() override; 26811168Sandreas.hansson@arm.com void drainResume() override; 26911012Sandreas.sandberg@arm.com 27011168Sandreas.hansson@arm.com void serialize(CheckpointOut &cp) const override; 27111168Sandreas.hansson@arm.com void unserialize(CheckpointIn &cp) override; 27211012Sandreas.sandberg@arm.com 27311168Sandreas.hansson@arm.com const std::string name() const override { return _name; } 27411168Sandreas.hansson@arm.com void process() override { 27511012Sandreas.sandberg@arm.com (parent.*func)(); 27611012Sandreas.sandberg@arm.com } 27711012Sandreas.sandberg@arm.com 27811012Sandreas.sandberg@arm.com bool active() const { return scheduled() || suspended; } 27911012Sandreas.sandberg@arm.com 28011012Sandreas.sandberg@arm.com private: 28111012Sandreas.sandberg@arm.com void suspend(); 28211012Sandreas.sandberg@arm.com void resume(); 28311012Sandreas.sandberg@arm.com 28411012Sandreas.sandberg@arm.com const std::string _name; 28511012Sandreas.sandberg@arm.com BasePixelPump &parent; 28611012Sandreas.sandberg@arm.com const CallbackType func; 28711012Sandreas.sandberg@arm.com 28811012Sandreas.sandberg@arm.com bool suspended; 28911012Sandreas.sandberg@arm.com Tick relativeTick; 29011012Sandreas.sandberg@arm.com }; 29111012Sandreas.sandberg@arm.com 29211012Sandreas.sandberg@arm.com void beginLine(); 29311012Sandreas.sandberg@arm.com void renderPixels(); 29411012Sandreas.sandberg@arm.com 29511897Ssudhanshu.jha@arm.com /** Fast and event-free line rendering function */ 29611897Ssudhanshu.jha@arm.com void renderLine(); 29711897Ssudhanshu.jha@arm.com 29811012Sandreas.sandberg@arm.com /** Convenience vector when doing operations on all events */ 29911012Sandreas.sandberg@arm.com std::vector<PixelEvent *> pixelEvents; 30011012Sandreas.sandberg@arm.com 30111012Sandreas.sandberg@arm.com PixelEvent evVSyncBegin; 30211012Sandreas.sandberg@arm.com PixelEvent evVSyncEnd; 30311012Sandreas.sandberg@arm.com PixelEvent evHSyncBegin; 30411012Sandreas.sandberg@arm.com PixelEvent evHSyncEnd; 30511012Sandreas.sandberg@arm.com PixelEvent evBeginLine; 30611012Sandreas.sandberg@arm.com PixelEvent evRenderPixels; 30711012Sandreas.sandberg@arm.com 30811012Sandreas.sandberg@arm.com DisplayTimings _timings; 30911012Sandreas.sandberg@arm.com 31011012Sandreas.sandberg@arm.com /** 31111012Sandreas.sandberg@arm.com * Current line (including back porch, front porch, and vsync) 31211012Sandreas.sandberg@arm.com * within a frame. 31311012Sandreas.sandberg@arm.com */ 31411012Sandreas.sandberg@arm.com unsigned line; 31511012Sandreas.sandberg@arm.com /** X-coordinate within the visible region of a frame */ 31611012Sandreas.sandberg@arm.com unsigned _posX; 31711012Sandreas.sandberg@arm.com 31811012Sandreas.sandberg@arm.com /** Did a buffer underrun occur within this refresh interval? */ 31911012Sandreas.sandberg@arm.com bool _underrun; 32011012Sandreas.sandberg@arm.com}; 32111012Sandreas.sandberg@arm.com 32211012Sandreas.sandberg@arm.com#endif // __DEV_PIXELPUMP_HH__ 323