dev, arm: Render HDLCD frames at a fixed rate in KVM
authorSudhanshu Jha <sudhanshu.jha@arm.com>
Wed, 1 Mar 2017 17:38:51 +0000 (17:38 +0000)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 7 Mar 2017 11:14:28 +0000 (11:14 +0000)
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>
src/dev/arm/RealView.py
src/dev/arm/hdlcd.cc
src/dev/arm/hdlcd.hh

index 4db732d387f325b5949489783d2e76882b0b21fc..20112d426babf860cd1ac06e04c88f310ca65e10 100644 (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'
index a92ae46279f8f60496e10565973db3004c5cc773..081fec2ffdb5ef937fcf2474256fb75c9bd0970f 100644 (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());
-    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();
 }
 
index acce6f191d12b5cfe50b212081197b03b640c5ed..4bca0bbbf64ccacac5485685227d434db613a35a 100644 (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;