summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/dev/arm/RealView.py2
-rw-r--r--src/dev/arm/hdlcd.cc41
-rw-r--r--src/dev/arm/hdlcd.hh7
3 files changed, 41 insertions, 9 deletions
diff --git a/src/dev/arm/RealView.py b/src/dev/arm/RealView.py
index 4db732d38..20112d426 100644
--- a/src/dev/arm/RealView.py
+++ b/src/dev/arm/RealView.py
@@ -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'
diff --git a/src/dev/arm/hdlcd.cc b/src/dev/arm/hdlcd.cc
index a92ae4627..081fec2ff 100644
--- a/src/dev/arm/hdlcd.cc
+++ b/src/dev/arm/hdlcd.cc
@@ -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());
- pixelPump.start();
+
+ 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();
}
diff --git a/src/dev/arm/hdlcd.hh b/src/dev/arm/hdlcd.hh
index acce6f191..4bca0bbbf 100644
--- a/src/dev/arm/hdlcd.hh
+++ b/src/dev/arm/hdlcd.hh
@@ -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;