summary refs log tree commit diff stats
path: root/hw/display
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-01-25 17:04:47 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-25 17:04:47 +0000
commit2077fef91d5eb8e3745a84fabd87a5ee7d2b535d (patch)
tree99dbdca9cf5c1ef16e06c57661898b3584ba81ea /hw/display
parenta3f9362af5c7071036fafb66665b85fda1e49bcc (diff)
parent24da047af0e99a83fcc0d50b86c0f2627f7418b3 (diff)
downloadfocaccia-qemu-2077fef91d5eb8e3745a84fabd87a5ee7d2b535d.tar.gz
focaccia-qemu-2077fef91d5eb8e3745a84fabd87a5ee7d2b535d.zip
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20180125' into staging
target-arm queue:
 * target/arm: Fix address truncation in 64-bit pagetable walks
 * i.MX: Fix FEC/ENET receive functions
 * target/arm: preparatory refactoring for SVE emulation
 * hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
 * hw/intc/arm_gic: Fix C_RPR value on idle priority
 * hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
 * hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
 * hw/arm/virt: Check that the CPU realize method succeeded
 * sdhci: fix a NULL pointer dereference due to uninitialized AddressSpace object
 * xilinx_spips: Correct usage of an uninitialized local variable
 * pl110: Implement vertical compare/next base interrupts

# gpg: Signature made Thu 25 Jan 2018 12:59:25 GMT
# gpg:                using RSA key 0x3C2525ED14360CDE
# gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>"
# gpg:                 aka "Peter Maydell <pmaydell@gmail.com>"
# gpg:                 aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>"
# Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83  15CF 3C25 25ED 1436 0CDE

* remotes/pmaydell/tags/pull-target-arm-20180125: (21 commits)
  pl110: Implement vertical compare/next base interrupts
  xilinx_spips: Correct usage of an uninitialized local variable
  sdhci: fix a NULL pointer dereference due to uninitialized AddresSpace object
  hw/arm/virt: Check that the CPU realize method succeeded
  hw/intc/arm_gic: Fix the NS view of C_BPR when C_CTRL.CBPR is 1
  hw/intc/arm_gic: Fix group priority computation for group 1 IRQs
  hw/intc/arm_gic: Fix C_RPR value on idle priority
  hw/intc/arm_gic: Prevent the GIC from signaling an IRQ when it's "active and pending"
  target/arm: Simplify fp_exception_el for user-only
  target/arm: Hoist store to flags output in cpu_get_tb_cpu_state
  target/arm: Move cpu_get_tb_cpu_state out of line
  target/arm: Add ARM_FEATURE_SVE
  vmstate: Add VMSTATE_UINT64_SUB_ARRAY
  target/arm: Add aa{32, 64}_vfp_{dreg, qreg} helpers
  target/arm: Change the type of vfp.regs
  target/arm: Use pointers in neon tbl helper
  target/arm: Use pointers in neon zip/uzp helpers
  target/arm: Use pointers in crypto helpers
  target/arm: Mark disas_set_insn_syndrome inline
  i.MX: Fix FEC/ENET receive funtions
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/display')
-rw-r--r--hw/display/pl110.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index 8c7dcc6f0a..cf68457fd1 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -12,6 +12,7 @@
 #include "ui/console.h"
 #include "framebuffer.h"
 #include "ui/pixel_ops.h"
+#include "qemu/timer.h"
 #include "qemu/log.h"
 
 #define PL110_CR_EN   0x001
@@ -19,6 +20,8 @@
 #define PL110_CR_BEBO 0x200
 #define PL110_CR_BEPO 0x400
 #define PL110_CR_PWR  0x800
+#define PL110_IE_NB   0x004
+#define PL110_IE_VC   0x008
 
 enum pl110_bppmode
 {
@@ -50,6 +53,7 @@ typedef struct PL110State {
     MemoryRegion iomem;
     MemoryRegionSection fbsection;
     QemuConsole *con;
+    QEMUTimer *vblank_timer;
 
     int version;
     uint32_t timing[4];
@@ -320,7 +324,24 @@ static void pl110_resize(PL110State *s, int width, int height)
 /* Update interrupts.  */
 static void pl110_update(PL110State *s)
 {
-  /* TODO: Implement interrupts.  */
+    /* Raise IRQ if enabled and any status bit is 1 */
+    if (s->int_status & s->int_mask) {
+        qemu_irq_raise(s->irq);
+    } else {
+        qemu_irq_lower(s->irq);
+    }
+}
+
+static void pl110_vblank_interrupt(void *opaque)
+{
+    PL110State *s = opaque;
+
+    /* Fire the vertical compare and next base IRQs and re-arm */
+    s->int_status |= (PL110_IE_NB | PL110_IE_VC);
+    timer_mod(s->vblank_timer,
+              qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                                NANOSECONDS_PER_SECOND / 60);
+    pl110_update(s);
 }
 
 static uint64_t pl110_read(void *opaque, hwaddr offset,
@@ -429,6 +450,11 @@ static void pl110_write(void *opaque, hwaddr offset,
         s->bpp = (val >> 1) & 7;
         if (pl110_enabled(s)) {
             qemu_console_resize(s->con, s->cols, s->rows);
+            timer_mod(s->vblank_timer,
+                      qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+                                        NANOSECONDS_PER_SECOND / 60);
+        } else {
+            timer_del(s->vblank_timer);
         }
         break;
     case 10: /* LCDICR */
@@ -474,6 +500,8 @@ static void pl110_realize(DeviceState *dev, Error **errp)
     memory_region_init_io(&s->iomem, OBJECT(s), &pl110_ops, s, "pl110", 0x1000);
     sysbus_init_mmio(sbd, &s->iomem);
     sysbus_init_irq(sbd, &s->irq);
+    s->vblank_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+                                   pl110_vblank_interrupt, s);
     qdev_init_gpio_in(dev, pl110_mux_ctrl_set, 1);
     s->con = graphic_console_init(dev, 0, &pl110_gfx_ops, s);
 }