From patchwork Mon Aug 6 02:16:17 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peter A. G. Crosthwaite" X-Patchwork-Id: 175230 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id C6E1F2C008F for ; Mon, 6 Aug 2012 12:18:01 +1000 (EST) Received: from localhost ([::1]:51806 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SyCtL-0007hl-Nl for incoming@patchwork.ozlabs.org; Sun, 05 Aug 2012 22:17:59 -0400 Received: from eggs.gnu.org ([208.118.235.92]:54726) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SyCsx-00077u-J2 for qemu-devel@nongnu.org; Sun, 05 Aug 2012 22:17:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SyCsw-0001c9-5G for qemu-devel@nongnu.org; Sun, 05 Aug 2012 22:17:35 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:49361) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SyCsv-0001ae-VS for qemu-devel@nongnu.org; Sun, 05 Aug 2012 22:17:34 -0400 Received: by mail-pb0-f45.google.com with SMTP id ro12so4514247pbb.4 for ; Sun, 05 Aug 2012 19:17:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references:x-gm-message-state; bh=Oo89vVXnWLpMGLRmnIIngPmNTIKpaAuqYjSwUA6MfEc=; b=mOUs/Vl5Nh6sNGSl4ZpxgXaRrWVDSUfCTwECLu5ZyGgrqjEmpan2aoeKcSW1xTmd4F Bv9rJb7lLj4Txf9grnXZS6tE/AZavdEquBmig7CwG8dBoLMAoj2Hcl66QyYw3bfNjYUg 9AwMzKLt/u61bBo1fWV3g3j0TNn6P/egqTtDyUMPRfgRwRKXu3c8Lg76gHrl1KhL1YIU h/EUk2fZIbxYLckMNtnInLn6AgQzULQlKHls+ATKxYPOd7+GxGnAhRx4yP8rQOXRAp5x cQsPH7J2Dh4H3DBf5raANMqdh7lRpZeq8O1xYLNi3vzHFCrod8BF4AhLuK8VMs9WvZPO v1/Q== Received: by 10.68.219.162 with SMTP id pp2mr15260821pbc.85.1344219453684; Sun, 05 Aug 2012 19:17:33 -0700 (PDT) Received: from localhost ([124.148.20.9]) by mx.google.com with ESMTPS id pa6sm4446213pbc.47.2012.08.05.19.17.29 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 05 Aug 2012 19:17:33 -0700 (PDT) From: "Peter A. G. Crosthwaite" To: qemu-devel@nongnu.org, paul@codesourcery.com, edgar.iglesias@gmail.com, peter.maydell@linaro.org, stefanha@gmail.com Date: Mon, 6 Aug 2012 12:16:17 +1000 Message-Id: <9086ce3f55ef0efbbae752567e13050e5f66799e.1344218410.git.peter.crosthwaite@petalogix.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: References: In-Reply-To: References: X-Gm-Message-State: ALoCoQlo7ad/585cZJEc16HaOwST0YD1aeMPUSgD7jVoP6AYLqLVhmbjyn/ttH1qkM9SsoU3Eknh X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.160.45 Cc: peter.crosthwaite@petalogix.com, i.mitsyanko@samsung.com, john.williams@petalogix.com Subject: [Qemu-devel] [PATCH v5 03/15] ssi: Implemented CS behaviour 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+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Added default CS behaviour for SSI slaves. SSI devices can set a property to enable CS behaviour which will create a GPIO on the device which is the CS. Tristating of the bus on SSI transfers is implemented. Signed-off-by: Peter A. G. Crosthwaite --- hw/ssd0323.c | 6 ++++++ hw/ssi-sd.c | 6 ++++++ hw/ssi.c | 39 ++++++++++++++++++++++++++++++++++++++- hw/ssi.h | 27 +++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 1 deletions(-) diff --git a/hw/ssd0323.c b/hw/ssd0323.c index b0b2e94..db16d20 100644 --- a/hw/ssd0323.c +++ b/hw/ssd0323.c @@ -277,6 +277,7 @@ static void ssd0323_cd(void *opaque, int n, int level) static void ssd0323_save(QEMUFile *f, void *opaque) { + SSISlave *ss = SSI_SLAVE(opaque); ssd0323_state *s = (ssd0323_state *)opaque; int i; @@ -294,10 +295,13 @@ static void ssd0323_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->remap); qemu_put_be32(f, s->mode); qemu_put_buffer(f, s->framebuffer, sizeof(s->framebuffer)); + + qemu_put_be32(f, ss->cs ? 1 : 0); } static int ssd0323_load(QEMUFile *f, void *opaque, int version_id) { + SSISlave *ss = SSI_SLAVE(opaque); ssd0323_state *s = (ssd0323_state *)opaque; int i; @@ -319,6 +323,8 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id) s->mode = qemu_get_be32(f); qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer)); + ss->cs = !!qemu_get_be32(f); + return 0; } diff --git a/hw/ssi-sd.c b/hw/ssi-sd.c index b519bdb..6fd9ab9 100644 --- a/hw/ssi-sd.c +++ b/hw/ssi-sd.c @@ -197,6 +197,7 @@ static uint32_t ssi_sd_transfer(SSISlave *dev, uint32_t val) static void ssi_sd_save(QEMUFile *f, void *opaque) { + SSISlave *ss = SSI_SLAVE(opaque); ssi_sd_state *s = (ssi_sd_state *)opaque; int i; @@ -209,10 +210,13 @@ static void ssi_sd_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->arglen); qemu_put_be32(f, s->response_pos); qemu_put_be32(f, s->stopping); + + qemu_put_be32(f, ss->cs ? 1 : 0); } static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id) { + SSISlave *ss = SSI_SLAVE(opaque); ssi_sd_state *s = (ssi_sd_state *)opaque; int i; @@ -229,6 +233,8 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id) s->response_pos = qemu_get_be32(f); s->stopping = qemu_get_be32(f); + ss->cs = !!qemu_get_be32(f); + return 0; } diff --git a/hw/ssi.c b/hw/ssi.c index 2db88fc..2e4f2fe 100644 --- a/hw/ssi.c +++ b/hw/ssi.c @@ -27,19 +27,55 @@ static const TypeInfo ssi_bus_info = { .instance_size = sizeof(SSIBus), }; +static void ssi_cs_default(void *opaque, int n, int level) +{ + SSISlave *s = SSI_SLAVE(opaque); + bool cs = !!level; + assert(n == 0); + if (s->cs != cs) { + SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s); + if (ssc->set_cs) { + ssc->set_cs(s, cs); + } + } + s->cs = cs; +} + +static uint32_t ssi_transfer_raw_default(SSISlave *dev, uint32_t val) +{ + SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(dev); + + if ((dev->cs && ssc->cs_polarity == SSI_CS_HIGH) || + (!dev->cs && ssc->cs_polarity == SSI_CS_LOW) || + ssc->cs_polarity == SSI_CS_NONE) { + return ssc->transfer(dev, val); + } + return 0; +} + static int ssi_slave_init(DeviceState *dev) { SSISlave *s = SSI_SLAVE(dev); SSISlaveClass *ssc = SSI_SLAVE_GET_CLASS(s); + if (ssc->transfer_raw == ssi_transfer_raw_default && + ssc->cs_polarity != SSI_CS_NONE) { + qdev_init_gpio_in(&s->qdev, ssi_cs_default, 1); + } + return ssc->init(s); } static void ssi_slave_class_init(ObjectClass *klass, void *data) { + SSISlaveClass *ssc = SSI_SLAVE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); + dc->init = ssi_slave_init; dc->bus_type = TYPE_SSI_BUS; + if (!ssc->transfer_raw) { + ssc->transfer_raw = ssi_transfer_raw_default; + } } static TypeInfo ssi_slave_info = { @@ -74,7 +110,7 @@ uint32_t ssi_transfer(SSIBus *bus, uint32_t val) QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { SSISlave *slave = SSI_SLAVE(kid->child); ssc = SSI_SLAVE_GET_CLASS(slave); - r |= ssc->transfer(slave, val); + r |= ssc->transfer_raw(slave, val); } return r; @@ -86,6 +122,7 @@ const VMStateDescription vmstate_ssi_slave = { .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField[]) { + VMSTATE_BOOL(cs, SSISlave), VMSTATE_END_OF_LIST() } }; diff --git a/hw/ssi.h b/hw/ssi.h index 975f9fb..5b69a3b 100644 --- a/hw/ssi.h +++ b/hw/ssi.h @@ -23,16 +23,43 @@ typedef struct SSISlave SSISlave; #define SSI_SLAVE_GET_CLASS(obj) \ OBJECT_GET_CLASS(SSISlaveClass, (obj), TYPE_SSI_SLAVE) +typedef enum { + SSI_CS_NONE = 0, + SSI_CS_LOW, + SSI_CS_HIGH, +} SSICSMode; + /* Slave devices. */ typedef struct SSISlaveClass { DeviceClass parent_class; int (*init)(SSISlave *dev); + + /* if you have standard or no CS behaviour, just override transfer. + * This is called when the device cs is active (true by default). + */ uint32_t (*transfer)(SSISlave *dev, uint32_t val); + /* called when the CS line changes. Optional, devices only need to implement + * this if they have side effects assoicated with the cs line (beyond + * tristating the txrx lines). + */ + int (*set_cs)(SSISlave *dev, bool select); + /* define whether or not CS exists and is active low/high */ + SSICSMode cs_polarity; + + /* if you have non-standard CS behvaiour override this to take control + * of the CS behvaiour at the device level. transfer, set_cs, and + * cs_polarity are unused if this is overwritten. Transfer_raw, will + * always be called for the device for every txrx access the to parent bus + */ + uint32_t (*transfer_raw)(SSISlave *dev, uint32_t val); } SSISlaveClass; struct SSISlave { DeviceState qdev; + + /* Chip select state */ + bool cs; }; #define SSI_SLAVE_FROM_QDEV(dev) DO_UPCAST(SSISlave, qdev, dev)