From patchwork Fri Jun 17 12:15:22 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?C=C3=A9dric_Le_Goater?= X-Patchwork-Id: 9183805 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 94CC6611BF for ; Fri, 17 Jun 2016 12:21:24 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86B7628380 for ; Fri, 17 Jun 2016 12:21:24 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7B9952839C; Fri, 17 Jun 2016 12:21:24 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id CA26128380 for ; Fri, 17 Jun 2016 12:21:23 +0000 (UTC) Received: from localhost ([::1]:56445 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDsm2-0006wD-TP for patchwork-qemu-devel@patchwork.kernel.org; Fri, 17 Jun 2016 08:21:22 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41103) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDshA-00029x-Pg for qemu-devel@nongnu.org; Fri, 17 Jun 2016 08:16:26 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bDsh4-0003C3-Uk for qemu-devel@nongnu.org; Fri, 17 Jun 2016 08:16:20 -0400 Received: from 5.mo53.mail-out.ovh.net ([46.105.48.2]:33976) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bDsh4-0003Ba-JP for qemu-devel@nongnu.org; Fri, 17 Jun 2016 08:16:14 -0400 Received: from player158.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo53.mail-out.ovh.net (Postfix) with ESMTP id B56F6FF9496 for ; Fri, 17 Jun 2016 14:16:13 +0200 (CEST) Received: from hermes.ibm.com (LFbn-1-2234-107.w90-76.abo.wanadoo.fr [90.76.55.107]) (Authenticated sender: clg@kaod.org) by player158.ha.ovh.net (Postfix) with ESMTPSA id 3B1226200A4; Fri, 17 Jun 2016 14:16:04 +0200 (CEST) From: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= To: Peter Maydell , Peter Crosthwaite Date: Fri, 17 Jun 2016 14:15:22 +0200 Message-Id: <1466165724-7620-4-git-send-email-clg@kaod.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1466165724-7620-1-git-send-email-clg@kaod.org> References: <1466165724-7620-1-git-send-email-clg@kaod.org> MIME-Version: 1.0 X-Ovh-Tracer-Id: 16865136183255796497 X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeekledrledtgdeglecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] X-Received-From: 46.105.48.2 Subject: [Qemu-devel] [PATCH v2 3/5] ast2400: add SPI flash slave object 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: , Cc: kwolf@redhat.com, Andrew Jeffery , qemu-devel@nongnu.org, armbru@redhat.com, qemu-arm@nongnu.org, Joel Stanley , =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP Each SPI flash slave can operate in two modes: Command and User. When in User mode, accesses to the memory segment of the slaves are translated in SPI transfers. When in Command mode, the HW generates the SPI commands automatically and the memory segment is accessed as if doing a MMIO. Other SPI controllers call that mode linear addressing mode. This object is a model proposal for a SPI flash module, gathering SPI slave properties and a MemoryRegion handling the memory accesses. Only the User mode is supported for now but we are preparing ground for the Command mode. The framework below is sufficient to support Linux which only uses User Mode. Signed-off-by: Cédric Le Goater --- hw/ssi/aspeed_smc.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ include/hw/ssi/aspeed_smc.h | 16 ++++++++ 2 files changed, 113 insertions(+) diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index 7937a9030903..6a02906c8f97 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -112,6 +112,21 @@ static bool aspeed_smc_is_ce_stop_active(AspeedSMCState *s, int cs) return s->regs[s->r_ctrl0 + cs] & CTRL_CE_STOP_ACTIVE; } +static inline int aspeed_smc_flash_mode(AspeedSMCState *s, int cs) +{ + return s->regs[s->r_ctrl0 + cs] & CTRL_CMD_MODE_MASK; +} + +static inline bool aspeed_smc_is_usermode(AspeedSMCState *s, int cs) +{ + return (aspeed_smc_flash_mode(s, cs) == CTRL_USERMODE); +} + +static inline bool aspeed_smc_is_writable(AspeedSMCState *s, int cs) +{ + return s->regs[s->r_conf] & (1 << (s->conf_enable_w0 + cs)); +} + static void aspeed_smc_update_cs(AspeedSMCState *s) { int i; @@ -298,3 +313,85 @@ static void aspeed_smc_register_types(void) } type_init(aspeed_smc_register_types) + +static uint64_t aspeed_smc_flash_read(void *opaque, hwaddr addr, unsigned size) +{ + AspeedSMCFlashState *fl = ASPEED_SMC_FLASH(opaque); + AspeedSMCState *s = fl->controller; + uint64_t ret = 0; + int i; + + if (aspeed_smc_is_usermode(s, fl->id)) { + for (i = 0; i < size; i++) { + ret |= ssi_transfer(s->spi, 0x0) << (8 * i); + } + } else { + error_report("%s: flash not in usermode", __func__); + ret = -1; + } + + return ret; +} + +static void aspeed_smc_flash_write(void *opaque, hwaddr addr, uint64_t data, + unsigned size) +{ + AspeedSMCFlashState *fl = ASPEED_SMC_FLASH(opaque); + AspeedSMCState *s = fl->controller; + int i; + + if (!aspeed_smc_is_writable(s, fl->id)) { + error_report("%s: flash is not writable", __func__); + return; + } + + if (!aspeed_smc_is_usermode(s, fl->id)) { + error_report("%s: flash not in usermode", __func__); + return; + } + + for (i = 0; i < size; i++) { + ssi_transfer(s->spi, (data >> (8 * i)) & 0xff); + } +} + +static const MemoryRegionOps aspeed_smc_flash_ops = { + .read = aspeed_smc_flash_read, + .write = aspeed_smc_flash_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 4, + }, +}; + +static const VMStateDescription vmstate_aspeed_smc_flash = { + .name = "aspeed.smc_flash", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(id, AspeedSMCFlashState), + VMSTATE_END_OF_LIST() + } +}; + +static void aspeed_smc_flash_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->vmsd = &vmstate_aspeed_smc_flash; +} + +static const TypeInfo aspeed_smc_flash_info = { + .name = TYPE_ASPEED_SMC_FLASH, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(AspeedSMCState), + .class_init = aspeed_smc_flash_class_init, +}; + +static void aspeed_smc_flash_register_types(void) +{ + type_register_static(&aspeed_smc_flash_info); +} + +type_init(aspeed_smc_flash_register_types) diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h index 2d3e9f6b46d5..abd0005b01c2 100644 --- a/include/hw/ssi/aspeed_smc.h +++ b/include/hw/ssi/aspeed_smc.h @@ -27,6 +27,22 @@ #include "hw/ssi/ssi.h" +struct AspeedSMCState; + +typedef struct AspeedSMCFlashState { + SysBusDevice parent_obj; + + MemoryRegion mmio; + uint8_t id; + size_t size; + struct AspeedSMCState *controller; + DeviceState *flash; +} AspeedSMCFlashState; + +#define TYPE_ASPEED_SMC_FLASH "aspeed.smc.flash" +#define ASPEED_SMC_FLASH(obj) \ + OBJECT_CHECK(AspeedSMCFlashState, (obj), TYPE_ASPEED_SMC_FLASH) + typedef struct AspeedSMCController { const char *name; uint8_t r_conf;