diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-08-24 13:17:49 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-08-24 13:17:49 +0100 |
commit | 01f18af98b04dc3f47c37a150ae342fafd7337df (patch) | |
tree | 84db149056834e17893003550985d3f683179dda /hw/misc | |
parent | 9a1f03f4ee207d58674fc76aecff546551c9da76 (diff) |
hw/display/bcm2835_fb: Fix handling of virtual framebuffer
The raspi framebuffir in bcm2835_fb supports the definition
of a virtual "viewport", which is smaller than the full
physical framebuffer size and at an adjustable offset within
it. Only the viewport area is sent to the screen. This allows
the guest to do things like double buffering, or scrolling
by adjusting the viewport origin. Currently QEMU doesn't
implement this at all.
Add support for this feature:
* the property mailbox code needs to distinguish the
virtual width/height from the physical width/height
* the framebuffer code needs to do something with the
virtual width/height/origin information
Note that the wiki documentation on the semantics of the
virtual and physical height and width has it the wrong way
around -- the virtual size is the size of the allocated
buffer, and the physical size is the size of the display,
so the virtual size is always the same as or larger than
the physical.
If the viewport size is set smaller than the physical
screen size, we ignore the viewport settings completely
and just display the physical screen area.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20180814144436.679-7-peter.maydell@linaro.org
Diffstat (limited to 'hw/misc')
-rw-r--r-- | hw/misc/bcm2835_property.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index c8c4979bd2..e3ab677891 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -155,23 +155,32 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) case 0x00040002: /* Blank screen */ resplen = 4; break; - case 0x00040003: /* Get display width/height */ - case 0x00040004: + case 0x00040003: /* Get physical display width/height */ stl_le_phys(&s->dma_as, value + 12, fbconfig.xres); stl_le_phys(&s->dma_as, value + 16, fbconfig.yres); resplen = 8; break; - case 0x00044003: /* Test display width/height */ - case 0x00044004: + case 0x00040004: /* Get virtual display width/height */ + stl_le_phys(&s->dma_as, value + 12, fbconfig.xres_virtual); + stl_le_phys(&s->dma_as, value + 16, fbconfig.yres_virtual); resplen = 8; break; - case 0x00048003: /* Set display width/height */ - case 0x00048004: + case 0x00044003: /* Test physical display width/height */ + case 0x00044004: /* Test virtual display width/height */ + resplen = 8; + break; + case 0x00048003: /* Set physical display width/height */ fbconfig.xres = ldl_le_phys(&s->dma_as, value + 12); fbconfig.yres = ldl_le_phys(&s->dma_as, value + 16); fbconfig_updated = true; resplen = 8; break; + case 0x00048004: /* Set virtual display width/height */ + fbconfig.xres_virtual = ldl_le_phys(&s->dma_as, value + 12); + fbconfig.yres_virtual = ldl_le_phys(&s->dma_as, value + 16); + fbconfig_updated = true; + resplen = 8; + break; case 0x00040005: /* Get depth */ stl_le_phys(&s->dma_as, value + 12, fbconfig.bpp); resplen = 4; |