From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52771) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1adNtB-0003vl-3l for qemu-devel@nongnu.org; Tue, 08 Mar 2016 15:05:54 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1adNt6-0004I0-8K for qemu-devel@nongnu.org; Tue, 08 Mar 2016 15:05:53 -0500 From: Andrew Baumann Date: Tue, 8 Mar 2016 12:05:25 -0800 Message-ID: <1457467526-8840-5-git-send-email-Andrew.Baumann@microsoft.com> In-Reply-To: <1457467526-8840-1-git-send-email-Andrew.Baumann@microsoft.com> References: <1457467526-8840-1-git-send-email-Andrew.Baumann@microsoft.com> MIME-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v3 4/5] bcm2835_property: implement framebuffer control/configuration properties List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , =?UTF-8?q?Gr=C3=A9gory=20ESTRADE?= , Stefan Weil , Peter Crosthwaite , Andrew Baumann , qemu-arm@nongnu.org, Paolo Bonzini From: Gr=C3=A9gory ESTRADE The property channel driver now interfaces with the framebuffer device to query and set framebuffer parameters. As a result of this, the "get ARM RAM size" query now correctly returns the video RAM base address (not total RAM size), and the ram-size property is no longer relevant here. Signed-off-by: Gr=C3=A9gory ESTRADE [AB: cleanup/refactoring for upstream submission] Signed-off-by: Andrew Baumann Reviewed-by: Peter Maydell --- Notes: v2: * avoid ldl/stl_phys * move code to increase default pi2 memory size from preceding patch h= ere (it was incorrect without the property channel implementation change= s) hw/arm/bcm2835_peripherals.c | 8 +-- hw/arm/raspi.c | 7 +- hw/misc/bcm2835_property.c | 139 +++++++++++++++++++++++++++++++++= +++- include/hw/misc/bcm2835_property.h | 5 +- 4 files changed, 144 insertions(+), 15 deletions(-) diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index c2fe6b7..4d74a18 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -79,6 +79,8 @@ static void bcm2835_peripherals_init(Object *obj) "board-rev", &error_abort); qdev_set_parent_bus(DEVICE(&s->property), sysbus_get_default()); =20 + object_property_add_const_link(OBJECT(&s->property), "fb", + OBJECT(&s->fb), &error_abort); object_property_add_const_link(OBJECT(&s->property), "dma-mr", OBJECT(&s->gpu_bus_mr), &error_abort); =20 @@ -211,12 +213,6 @@ static void bcm2835_peripherals_realize(DeviceState *d= ev, Error **errp) qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB))= ; =20 /* Property channel */ - object_property_set_int(OBJECT(&s->property), ram_size, "ram-size", &e= rr); - if (err) { - error_propagate(errp, err); - return; - } - object_property_set_bool(OBJECT(&s->property), true, "realized", &err)= ; if (err) { error_propagate(errp, err); diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index 5498209..83fe809 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -164,11 +164,6 @@ static void raspi2_machine_init(MachineClass *mc) mc->no_floppy =3D 1; mc->no_cdrom =3D 1; mc->max_cpus =3D BCM2836_NCPUS; - - /* XXX: Temporary restriction in RAM size from the full 1GB. Since - * we do not yet support the framebuffer / GPU, we need to limit - * RAM usable by the OS to sit below the peripherals. - */ - mc->default_ram_size =3D 0x3F000000; /* BCM2836_PERI_BASE */ + mc->default_ram_size =3D 1024 * 1024 * 1024; }; DEFINE_MACHINE("raspi2", raspi2_machine_init) diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index 41fbbe3..15dcc02 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -17,6 +17,11 @@ static void bcm2835_property_mbox_push(BCM2835PropertySt= ate *s, uint32_t value) uint32_t tot_len; size_t resplen; uint32_t tmp; + int n; + uint32_t offset, length, color; + uint32_t xres, yres, xoffset, yoffset, bpp, pixo, alpha; + uint32_t *newxres =3D NULL, *newyres =3D NULL, *newxoffset =3D NULL, + *newyoffset =3D NULL, *newbpp =3D NULL, *newpixo =3D NULL, *newalp= ha =3D NULL; =20 value &=3D ~0xf; =20 @@ -60,7 +65,14 @@ static void bcm2835_property_mbox_push(BCM2835PropertySt= ate *s, uint32_t value) /* base */ stl_le_phys(&s->dma_as, value + 12, 0); /* size */ - stl_le_phys(&s->dma_as, value + 16, s->ram_size); + stl_le_phys(&s->dma_as, value + 16, s->fbdev->vcram_base); + resplen =3D 8; + break; + case 0x00010006: /* Get VC memory */ + /* base */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->vcram_base); + /* size */ + stl_le_phys(&s->dma_as, value + 16, s->fbdev->vcram_size); resplen =3D 8; break; case 0x00028001: /* Set power state */ @@ -122,6 +134,114 @@ static void bcm2835_property_mbox_push(BCM2835Propert= yState *s, uint32_t value) resplen =3D 8; break; =20 + /* Frame buffer */ + + case 0x00040001: /* Allocate buffer */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->base); + stl_le_phys(&s->dma_as, value + 16, s->fbdev->size); + resplen =3D 8; + break; + case 0x00048001: /* Release buffer */ + resplen =3D 0; + break; + case 0x00040002: /* Blank screen */ + resplen =3D 4; + break; + case 0x00040003: /* Get display width/height */ + case 0x00040004: + stl_le_phys(&s->dma_as, value + 12, s->fbdev->xres); + stl_le_phys(&s->dma_as, value + 16, s->fbdev->yres); + resplen =3D 8; + break; + case 0x00044003: /* Test display width/height */ + case 0x00044004: + resplen =3D 8; + break; + case 0x00048003: /* Set display width/height */ + case 0x00048004: + xres =3D ldl_le_phys(&s->dma_as, value + 12); + newxres =3D &xres; + yres =3D ldl_le_phys(&s->dma_as, value + 16); + newyres =3D &yres; + resplen =3D 8; + break; + case 0x00040005: /* Get depth */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->bpp); + resplen =3D 4; + break; + case 0x00044005: /* Test depth */ + resplen =3D 4; + break; + case 0x00048005: /* Set depth */ + bpp =3D ldl_le_phys(&s->dma_as, value + 12); + newbpp =3D &bpp; + resplen =3D 4; + break; + case 0x00040006: /* Get pixel order */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->pixo); + resplen =3D 4; + break; + case 0x00044006: /* Test pixel order */ + resplen =3D 4; + break; + case 0x00048006: /* Set pixel order */ + pixo =3D ldl_le_phys(&s->dma_as, value + 12); + newpixo =3D &pixo; + resplen =3D 4; + break; + case 0x00040007: /* Get alpha */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->alpha); + resplen =3D 4; + break; + case 0x00044007: /* Test pixel alpha */ + resplen =3D 4; + break; + case 0x00048007: /* Set alpha */ + alpha =3D ldl_le_phys(&s->dma_as, value + 12); + newalpha =3D α + resplen =3D 4; + break; + case 0x00040008: /* Get pitch */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->pitch); + resplen =3D 4; + break; + case 0x00040009: /* Get virtual offset */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->xoffset); + stl_le_phys(&s->dma_as, value + 16, s->fbdev->yoffset); + resplen =3D 8; + break; + case 0x00044009: /* Test virtual offset */ + resplen =3D 8; + break; + case 0x00048009: /* Set virtual offset */ + xoffset =3D ldl_le_phys(&s->dma_as, value + 12); + newxoffset =3D &xoffset; + yoffset =3D ldl_le_phys(&s->dma_as, value + 16); + newyoffset =3D &yoffset; + resplen =3D 8; + break; + case 0x0004000a: /* Get/Test/Set overscan */ + case 0x0004400a: + case 0x0004800a: + stl_le_phys(&s->dma_as, value + 12, 0); + stl_le_phys(&s->dma_as, value + 16, 0); + stl_le_phys(&s->dma_as, value + 20, 0); + stl_le_phys(&s->dma_as, value + 24, 0); + resplen =3D 16; + break; + case 0x0004800b: /* Set palette */ + offset =3D ldl_le_phys(&s->dma_as, value + 12); + length =3D ldl_le_phys(&s->dma_as, value + 16); + n =3D 0; + while (n < length - offset) { + color =3D ldl_le_phys(&s->dma_as, value + 20 + (n << 2)); + stl_le_phys(&s->dma_as, + s->fbdev->vcram_base + ((offset + n) << 2), co= lor); + n++; + } + stl_le_phys(&s->dma_as, value + 12, 0); + resplen =3D 4; + break; =20 case 0x00060001: /* Get DMA channels */ /* channels 2-5 */ @@ -147,6 +267,13 @@ static void bcm2835_property_mbox_push(BCM2835Property= State *s, uint32_t value) value +=3D bufsize + 12; } =20 + /* Reconfigure framebuffer if required */ + if (newxres || newyres || newxoffset || newyoffset || newbpp || newpix= o + || newalpha) { + bcm2835_fb_reconfigure(s->fbdev, newxres, newyres, newxoffset, + newyoffset, newbpp, newpixo, newalpha); + } + /* Buffer response code */ stl_le_phys(&s->dma_as, s->addr + 4, (1 << 31)); } @@ -241,6 +368,15 @@ static void bcm2835_property_realize(DeviceState *dev,= Error **errp) Object *obj; Error *err =3D NULL; =20 + obj =3D object_property_get_link(OBJECT(dev), "fb", &err); + if (obj =3D=3D NULL) { + error_setg(errp, "%s: required fb link not found: %s", + __func__, error_get_pretty(err)); + return; + } + + s->fbdev =3D BCM2835_FB(obj); + obj =3D object_property_get_link(OBJECT(dev), "dma-mr", &err); if (obj =3D=3D NULL) { error_setg(errp, "%s: required dma-mr link not found: %s", @@ -259,7 +395,6 @@ static void bcm2835_property_realize(DeviceState *dev, = Error **errp) =20 static Property bcm2835_property_props[] =3D { DEFINE_PROP_UINT32("board-rev", BCM2835PropertyState, board_rev, 0), - DEFINE_PROP_UINT32("ram-size", BCM2835PropertyState, ram_size, 0), DEFINE_PROP_END_OF_LIST() }; =20 diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_p= roperty.h index df889ea..edcab60 100644 --- a/include/hw/misc/bcm2835_property.h +++ b/include/hw/misc/bcm2835_property.h @@ -9,6 +9,7 @@ #include "hw/sysbus.h" #include "exec/address-spaces.h" #include "net/net.h" +#include "hw/display/bcm2835_fb.h" =20 #define TYPE_BCM2835_PROPERTY "bcm2835-property" #define BCM2835_PROPERTY(obj) \ @@ -18,13 +19,15 @@ typedef struct { /*< private >*/ SysBusDevice busdev; /*< public >*/ + MemoryRegion *dma_mr; AddressSpace dma_as; MemoryRegion iomem; qemu_irq mbox_irq; + BCM2835FBState *fbdev; + MACAddr macaddr; uint32_t board_rev; - uint32_t ram_size; uint32_t addr; bool pending; } BCM2835PropertyState; --=20 2.7.0