From patchwork Fri Feb 9 11:03:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 127787 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp501450ljc; Fri, 9 Feb 2018 03:10:29 -0800 (PST) X-Google-Smtp-Source: AH8x22639TyvO/oYEQK7whbYzDmsBpiuE29sMSCDkJme3J/XcuexBufzGJyuZJzj54Fhj2LABeC2 X-Received: by 10.13.235.135 with SMTP id u129mr1016652ywe.271.1518174629443; Fri, 09 Feb 2018 03:10:29 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518174629; cv=none; d=google.com; s=arc-20160816; b=xxDHtznyBJVCFoqXSq8fT+LhpK/moc5UX+NW1rFHNnYKXwc62k9gkcofMMgIgbFNlA dAW6fjECIu3+Tvg2Ffe85fAirJa6Ut2Os07VWl3OF5vti6g97Stb6NnZhx2ELwnBybqS Rx8bz18TVZ2ADfAcljtIq77KYBSoZIOBL9+pUqqrCI74UsZslY9XTIbeY7GoJFHBm/fb lQsrzm9g6ZBcKshXASgYcWgwWersCrDB3u4UCEX/n/g1gbYrV4pHILp49RXwL9vwxanK 2tyd2F4r4D0RP08pJ4wqlSTNO7TgiT/MsXu0bXgj0R8qK6/PqRQC3KEWkMq900T+o1R2 +WPA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject :content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=wEt1NQGBvA3D6kDwEoP9IeayJy3VDTY0uDfUcZwX6sM=; b=DEQ2+sOTQltLy0ghEuhuvM0dDyKMSEJVnderwQ8rVpKREvjzqDxR2lSYHdGbHB41UW kCN7gw3l4wKLh7hjsqoSkrdLborGqmstb52NistvfSq4OX1QRCXVIY1WVwgmqf5GFSeP VB6TBs5Dr/M2F7Z3TPHx9MdoYusc+sGeT7Q/dPTq1CMn7dZCA3eMeJ/GKYYBvR7HgEcg v/PzX3JBbp9weL3TfTR9FIAWrjHndUOFvNBGtRqzFlNdSaYhFD/poTD3p116VIn3Jm3D 6V14+25p8FXwG/0okvOcbi7wApQifJcoGa7tM5KOvc/JerzVewSi5KTeor7E37t1uY+G NjtQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id d12si368435ybg.270.2018.02.09.03.10.29 for (version=TLS1 cipher=AES128-SHA bits=128/128); Fri, 09 Feb 2018 03:10:29 -0800 (PST) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:34881 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ek6ZY-0006gr-HW for patch@linaro.org; Fri, 09 Feb 2018 06:10:28 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39799) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ek6Sp-00011e-Qj for qemu-devel@nongnu.org; Fri, 09 Feb 2018 06:03:33 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ek6So-0001xp-3y for qemu-devel@nongnu.org; Fri, 09 Feb 2018 06:03:31 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:46258) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ek6Sn-0001wn-RM for qemu-devel@nongnu.org; Fri, 09 Feb 2018 06:03:30 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1ek6Sm-0002c7-Ig for qemu-devel@nongnu.org; Fri, 09 Feb 2018 11:03:28 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Fri, 9 Feb 2018 11:03:02 +0000 Message-Id: <20180209110314.11766-19-peter.maydell@linaro.org> X-Mailer: git-send-email 2.16.1 In-Reply-To: <20180209110314.11766-1-peter.maydell@linaro.org> References: <20180209110314.11766-1-peter.maydell@linaro.org> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 18/30] i.MX: Add code to emulate GPCv2 IP block X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" From: Andrey Smirnov Add minimal code needed to allow upstream Linux guest to boot. Cc: Peter Maydell Cc: Jason Wang Cc: Philippe Mathieu-Daudé Cc: Marcel Apfelbaum Cc: Michael S. Tsirkin Cc: qemu-devel@nongnu.org Cc: qemu-arm@nongnu.org Cc: yurovsky@gmail.com Reviewed-by: Peter Maydell Signed-off-by: Andrey Smirnov Signed-off-by: Peter Maydell --- hw/intc/Makefile.objs | 2 +- include/hw/intc/imx_gpcv2.h | 22 ++++++++ hw/intc/imx_gpcv2.c | 125 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 include/hw/intc/imx_gpcv2.h create mode 100644 hw/intc/imx_gpcv2.c -- 2.16.1 diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs index 571e094a14..0e9963f5ee 100644 --- a/hw/intc/Makefile.objs +++ b/hw/intc/Makefile.objs @@ -6,7 +6,7 @@ common-obj-$(CONFIG_XILINX) += xilinx_intc.o common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-pmu-iomod-intc.o common-obj-$(CONFIG_XLNX_ZYNQMP) += xlnx-zynqmp-ipi.o common-obj-$(CONFIG_ETRAXFS) += etraxfs_pic.o -common-obj-$(CONFIG_IMX) += imx_avic.o +common-obj-$(CONFIG_IMX) += imx_avic.o imx_gpcv2.o common-obj-$(CONFIG_LM32) += lm32_pic.o common-obj-$(CONFIG_REALVIEW) += realview_gic.o common-obj-$(CONFIG_SLAVIO) += slavio_intctl.o diff --git a/include/hw/intc/imx_gpcv2.h b/include/hw/intc/imx_gpcv2.h new file mode 100644 index 0000000000..ed978b24bb --- /dev/null +++ b/include/hw/intc/imx_gpcv2.h @@ -0,0 +1,22 @@ +#ifndef IMX_GPCV2_H +#define IMX_GPCV2_H + +#include "hw/sysbus.h" + +enum IMXGPCv2Registers { + GPC_NUM = 0xE00 / sizeof(uint32_t), +}; + +typedef struct IMXGPCv2State { + /*< private >*/ + SysBusDevice parent_obj; + + /*< public >*/ + MemoryRegion iomem; + uint32_t regs[GPC_NUM]; +} IMXGPCv2State; + +#define TYPE_IMX_GPCV2 "imx-gpcv2" +#define IMX_GPCV2(obj) OBJECT_CHECK(IMXGPCv2State, (obj), TYPE_IMX_GPCV2) + +#endif /* IMX_GPCV2_H */ diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c new file mode 100644 index 0000000000..4eb9ce2668 --- /dev/null +++ b/hw/intc/imx_gpcv2.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2018, Impinj, Inc. + * + * i.MX7 GPCv2 block emulation code + * + * Author: Andrey Smirnov + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "hw/intc/imx_gpcv2.h" +#include "qemu/log.h" + +#define GPC_PU_PGC_SW_PUP_REQ 0x0f8 +#define GPC_PU_PGC_SW_PDN_REQ 0x104 + +#define USB_HSIC_PHY_SW_Pxx_REQ BIT(4) +#define USB_OTG2_PHY_SW_Pxx_REQ BIT(3) +#define USB_OTG1_PHY_SW_Pxx_REQ BIT(2) +#define PCIE_PHY_SW_Pxx_REQ BIT(1) +#define MIPI_PHY_SW_Pxx_REQ BIT(0) + + +static void imx_gpcv2_reset(DeviceState *dev) +{ + IMXGPCv2State *s = IMX_GPCV2(dev); + + memset(s->regs, 0, sizeof(s->regs)); +} + +static uint64_t imx_gpcv2_read(void *opaque, hwaddr offset, + unsigned size) +{ + IMXGPCv2State *s = opaque; + + return s->regs[offset / sizeof(uint32_t)]; +} + +static void imx_gpcv2_write(void *opaque, hwaddr offset, + uint64_t value, unsigned size) +{ + IMXGPCv2State *s = opaque; + const size_t idx = offset / sizeof(uint32_t); + + s->regs[idx] = value; + + /* + * Real HW will clear those bits once as a way to indicate that + * power up request is complete + */ + if (offset == GPC_PU_PGC_SW_PUP_REQ || + offset == GPC_PU_PGC_SW_PDN_REQ) { + s->regs[idx] &= ~(USB_HSIC_PHY_SW_Pxx_REQ | + USB_OTG2_PHY_SW_Pxx_REQ | + USB_OTG1_PHY_SW_Pxx_REQ | + PCIE_PHY_SW_Pxx_REQ | + MIPI_PHY_SW_Pxx_REQ); + } +} + +static const struct MemoryRegionOps imx_gpcv2_ops = { + .read = imx_gpcv2_read, + .write = imx_gpcv2_write, + .endianness = DEVICE_NATIVE_ENDIAN, + .impl = { + /* + * Our device would not work correctly if the guest was doing + * unaligned access. This might not be a limitation on the real + * device but in practice there is no reason for a guest to access + * this device unaligned. + */ + .min_access_size = 4, + .max_access_size = 4, + .unaligned = false, + }, +}; + +static void imx_gpcv2_init(Object *obj) +{ + SysBusDevice *sd = SYS_BUS_DEVICE(obj); + IMXGPCv2State *s = IMX_GPCV2(obj); + + memory_region_init_io(&s->iomem, + obj, + &imx_gpcv2_ops, + s, + TYPE_IMX_GPCV2 ".iomem", + sizeof(s->regs)); + sysbus_init_mmio(sd, &s->iomem); +} + +static const VMStateDescription vmstate_imx_gpcv2 = { + .name = TYPE_IMX_GPCV2, + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32_ARRAY(regs, IMXGPCv2State, GPC_NUM), + VMSTATE_END_OF_LIST() + }, +}; + +static void imx_gpcv2_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->reset = imx_gpcv2_reset; + dc->vmsd = &vmstate_imx_gpcv2; + dc->desc = "i.MX GPCv2 Module"; +} + +static const TypeInfo imx_gpcv2_info = { + .name = TYPE_IMX_GPCV2, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(IMXGPCv2State), + .instance_init = imx_gpcv2_init, + .class_init = imx_gpcv2_class_init, +}; + +static void imx_gpcv2_register_type(void) +{ + type_register_static(&imx_gpcv2_info); +} +type_init(imx_gpcv2_register_type)