dev, arm: Render HDLCD frames at a fixed rate in KVM

Use the new fast scan-out API in the PixelPump to render frames at a
fixed frame rate in KVM mode. The refresh rate when running in KVM can
be controlled by the virt_refresh_rate parameter.

Change-Id: Ib3c78f174e3f8f4ca8a9b723c4e5d311a433b8aa
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2242
Reviewed-by: Rahul Thakur <rjthakur@google.com>
This commit is contained in:
Sudhanshu Jha 2017-03-01 17:38:51 +00:00 committed by Andreas Sandberg
parent 9dd54d10ab
commit 846a17308c
3 changed files with 41 additions and 9 deletions

View file

@ -298,6 +298,8 @@ class HDLcd(AmbaDmaDevice):
pxl_clk = Param.ClockDomain("Pixel clock source")
pixel_chunk = Param.Unsigned(32, "Number of pixels to handle in one batch")
virt_refresh_rate = Param.Frequency("20Hz", "Frame refresh rate "
"in KVM mode")
class RealView(Platform):
type = 'RealView'

View file

@ -65,6 +65,7 @@ HDLcd::HDLcd(const HDLcdParams *p)
addrRanges{RangeSize(pioAddr, pioSize)},
enableCapture(p->enable_capture),
pixelBufferSize(p->pixel_buffer_size),
virtRefreshRate(p->virt_refresh_rate),
// Registers
version(VERSION_RESETV),
@ -82,6 +83,7 @@ HDLcd::HDLcd(const HDLcdParams *p)
pixel_format(0),
red_select(0), green_select(0), blue_select(0),
virtRefreshEvent(this),
// Other
bmp(&pixelPump.fb), pic(NULL), conv(PixelConverter::rgba8888_le),
pixelPump(*this, *p->pxl_clk, p->pixel_chunk)
@ -201,13 +203,19 @@ HDLcd::drainResume()
{
AmbaDmaDevice::drainResume();
// We restored from an old checkpoint without a pixel pump, start
// an new refresh. This typically happens when restoring from old
// checkpoints.
if (enabled() && !pixelPump.active()) {
// Update timing parameter before rendering frames
pixelPump.updateTimings(displayTimings());
pixelPump.start();
if (enabled()) {
if (sys->bypassCaches()) {
// We restart the HDLCD if we are in KVM mode. This
// ensures that we always use the fast refresh logic if we
// resume in KVM mode.
cmdDisable();
cmdEnable();
} else if (!pixelPump.active()) {
// We restored from an old checkpoint without a pixel
// pump, start an new refresh. This typically happens when
// restoring from old checkpoints.
cmdEnable();
}
}
// We restored from a checkpoint and need to update the VNC server
@ -215,6 +223,13 @@ HDLcd::drainResume()
vnc->setDirty();
}
void
HDLcd::virtRefresh()
{
pixelPump.renderFrame();
schedule(virtRefreshEvent, (curTick() + virtRefreshRate));
}
// read registers and frame buffer
Tick
HDLcd::read(PacketPtr pkt)
@ -482,13 +497,23 @@ HDLcd::cmdEnable()
// Update timing parameter before rendering frames
pixelPump.updateTimings(displayTimings());
if (sys->bypassCaches()) {
schedule(virtRefreshEvent, clockEdge());
} else {
pixelPump.start();
}
}
void
HDLcd::cmdDisable()
{
pixelPump.stop();
// Disable the virtual refresh event
if (virtRefreshEvent.scheduled()) {
assert(sys->bypassCaches());
deschedule(virtRefreshEvent);
}
dmaEngine->abortFrame();
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013, 2015 ARM Limited
* Copyright (c) 2010-2013, 2015, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@ -116,6 +116,7 @@ class HDLcd: public AmbaDmaDevice
const AddrRangeList addrRanges;
const bool enableCapture;
const Addr pixelBufferSize;
const Tick virtRefreshRate;
protected: // Register handling
/** ARM HDLcd register offsets */
@ -344,6 +345,10 @@ class HDLcd: public AmbaDmaDevice
HDLcd &parent;
};
/** Handler for fast frame refresh in KVM-mode */
void virtRefresh();
EventWrapper<HDLcd, &HDLcd::virtRefresh> virtRefreshEvent;
/** Helper to write out bitmaps */
Bitmap bmp;