diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-01-25 17:04:47 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-01-25 17:04:47 +0000 |
commit | 2077fef91d5eb8e3745a84fabd87a5ee7d2b535d (patch) | |
tree | 99dbdca9cf5c1ef16e06c57661898b3584ba81ea /hw/display | |
parent | a3f9362af5c7071036fafb66665b85fda1e49bcc (diff) | |
parent | 24da047af0e99a83fcc0d50b86c0f2627f7418b3 (diff) |
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.c | 30 |
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); } |