From patchwork Wed Mar 16 17:18:33 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 8602971 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 10656C0553 for ; Wed, 16 Mar 2016 17:23:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 1465620166 for ; Wed, 16 Mar 2016 17:23:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E171A202A1 for ; Wed, 16 Mar 2016 17:23:33 +0000 (UTC) Received: from localhost ([::1]:57688 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agFAT-0005HZ-7h for patchwork-qemu-devel@patchwork.kernel.org; Wed, 16 Mar 2016 13:23:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35563) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agF5v-0002Jl-Fb for qemu-devel@nongnu.org; Wed, 16 Mar 2016 13:18:53 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1agF5s-0001Jr-BX for qemu-devel@nongnu.org; Wed, 16 Mar 2016 13:18:51 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:56206) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1agF5r-0001J1-QF for qemu-devel@nongnu.org; Wed, 16 Mar 2016 13:18:48 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1agF5r-00010l-6L for qemu-devel@nongnu.org; Wed, 16 Mar 2016 17:18:47 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Wed, 16 Mar 2016 17:18:33 +0000 Message-Id: <1458148715-16864-20-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1458148715-16864-1-git-send-email-peter.maydell@linaro.org> References: <1458148715-16864-1-git-send-email-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 19/21] bcm2835_property: implement framebuffer control/configuration properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: GrĂ©gory 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Ă©gory ESTRADE Reviewed-by: Peter Maydell Signed-off-by: Andrew Baumann Message-id: 1457467526-8840-5-git-send-email-Andrew.Baumann@microsoft.com [AB: cleanup/refactoring for upstream submission] Signed-off-by: Andrew Baumann Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- 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()); + 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); @@ -211,12 +213,6 @@ static void bcm2835_peripherals_realize(DeviceState *dev, Error **errp) qdev_get_gpio_in(DEVICE(&s->mboxes), MBOX_CHAN_FB)); /* Property channel */ - object_property_set_int(OBJECT(&s->property), ram_size, "ram-size", &err); - 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 = 1; mc->no_cdrom = 1; mc->max_cpus = 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 = 0x3F000000; /* BCM2836_PERI_BASE */ + mc->default_ram_size = 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(BCM2835PropertyState *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 = NULL, *newyres = NULL, *newxoffset = NULL, + *newyoffset = NULL, *newbpp = NULL, *newpixo = NULL, *newalpha = NULL; value &= ~0xf; @@ -60,7 +65,14 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *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 = 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 = 8; break; case 0x00028001: /* Set power state */ @@ -122,6 +134,114 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 8; break; + /* 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 = 8; + break; + case 0x00048001: /* Release buffer */ + resplen = 0; + break; + case 0x00040002: /* Blank screen */ + resplen = 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 = 8; + break; + case 0x00044003: /* Test display width/height */ + case 0x00044004: + resplen = 8; + break; + case 0x00048003: /* Set display width/height */ + case 0x00048004: + xres = ldl_le_phys(&s->dma_as, value + 12); + newxres = &xres; + yres = ldl_le_phys(&s->dma_as, value + 16); + newyres = &yres; + resplen = 8; + break; + case 0x00040005: /* Get depth */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->bpp); + resplen = 4; + break; + case 0x00044005: /* Test depth */ + resplen = 4; + break; + case 0x00048005: /* Set depth */ + bpp = ldl_le_phys(&s->dma_as, value + 12); + newbpp = &bpp; + resplen = 4; + break; + case 0x00040006: /* Get pixel order */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->pixo); + resplen = 4; + break; + case 0x00044006: /* Test pixel order */ + resplen = 4; + break; + case 0x00048006: /* Set pixel order */ + pixo = ldl_le_phys(&s->dma_as, value + 12); + newpixo = &pixo; + resplen = 4; + break; + case 0x00040007: /* Get alpha */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->alpha); + resplen = 4; + break; + case 0x00044007: /* Test pixel alpha */ + resplen = 4; + break; + case 0x00048007: /* Set alpha */ + alpha = ldl_le_phys(&s->dma_as, value + 12); + newalpha = α + resplen = 4; + break; + case 0x00040008: /* Get pitch */ + stl_le_phys(&s->dma_as, value + 12, s->fbdev->pitch); + resplen = 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 = 8; + break; + case 0x00044009: /* Test virtual offset */ + resplen = 8; + break; + case 0x00048009: /* Set virtual offset */ + xoffset = ldl_le_phys(&s->dma_as, value + 12); + newxoffset = &xoffset; + yoffset = ldl_le_phys(&s->dma_as, value + 16); + newyoffset = &yoffset; + resplen = 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 = 16; + break; + case 0x0004800b: /* Set palette */ + offset = ldl_le_phys(&s->dma_as, value + 12); + length = ldl_le_phys(&s->dma_as, value + 16); + n = 0; + while (n < length - offset) { + color = ldl_le_phys(&s->dma_as, value + 20 + (n << 2)); + stl_le_phys(&s->dma_as, + s->fbdev->vcram_base + ((offset + n) << 2), color); + n++; + } + stl_le_phys(&s->dma_as, value + 12, 0); + resplen = 4; + break; case 0x00060001: /* Get DMA channels */ /* channels 2-5 */ @@ -147,6 +267,13 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) value += bufsize + 12; } + /* Reconfigure framebuffer if required */ + if (newxres || newyres || newxoffset || newyoffset || newbpp || newpixo + || 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 = NULL; + obj = object_property_get_link(OBJECT(dev), "fb", &err); + if (obj == NULL) { + error_setg(errp, "%s: required fb link not found: %s", + __func__, error_get_pretty(err)); + return; + } + + s->fbdev = BCM2835_FB(obj); + obj = object_property_get_link(OBJECT(dev), "dma-mr", &err); if (obj == 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) static Property bcm2835_property_props[] = { DEFINE_PROP_UINT32("board-rev", BCM2835PropertyState, board_rev, 0), - DEFINE_PROP_UINT32("ram-size", BCM2835PropertyState, ram_size, 0), DEFINE_PROP_END_OF_LIST() }; diff --git a/include/hw/misc/bcm2835_property.h b/include/hw/misc/bcm2835_property.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" #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;