From patchwork Mon Feb 22 08:03:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Krzeminski, Marcin (Nokia - PL/Wroclaw)" X-Patchwork-Id: 586058 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id C075F140B9C for ; Mon, 22 Feb 2016 19:08:49 +1100 (AEDT) Received: from localhost ([::1]:47598 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aXlXz-0006cP-P1 for incoming@patchwork.ozlabs.org; Mon, 22 Feb 2016 03:08:47 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36033) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aXlT4-00065l-PX for qemu-devel@nongnu.org; Mon, 22 Feb 2016 03:03:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aXlSz-0007iV-S2 for qemu-devel@nongnu.org; Mon, 22 Feb 2016 03:03:42 -0500 Received: from demumfd001.nsn-inter.net ([93.183.12.32]:54359) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aXlSz-0007gU-Fr for qemu-devel@nongnu.org; Mon, 22 Feb 2016 03:03:37 -0500 Received: from demuprx016.emea.nsn-intra.net ([10.150.129.55]) by demumfd001.nsn-inter.net (8.15.2/8.15.2) with ESMTPS id u1M83TCC027042 (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 22 Feb 2016 08:03:29 GMT Received: from CNU418C7XK.nsn-intra.net ([10.154.154.82]) by demuprx016.emea.nsn-intra.net (8.12.11.20060308/8.12.11) with ESMTP id u1M83QUj028432; Mon, 22 Feb 2016 09:03:28 +0100 From: marcin.krzeminski@nokia.com To: qemu-devel@nongnu.org Date: Mon, 22 Feb 2016 09:03:20 +0100 Message-Id: <1456128205-5092-7-git-send-email-marcin.krzeminski@nokia.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1456128205-5092-1-git-send-email-marcin.krzeminski@nokia.com> References: <1456128205-5092-1-git-send-email-marcin.krzeminski@nokia.com> X-purgate-type: clean X-purgate-Ad: Categorized by eleven eXpurgate (R) http://www.eleven.de X-purgate: clean X-purgate: This mail is considered clean (visit http://www.eleven.de for further information) X-purgate-size: 5731 X-purgate-ID: 151667::1456128209-000006B0-9657CA04/0/0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 93.183.12.32 Cc: crosthwaitepeter@gmail.com, clg@fr.ibm.com, pawel.lenkow@itlen.com, marcin.krzeminski@nokia.com Subject: [Qemu-devel] [PATCH v4 06/11] block: m25p80: Add configuration registers 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 From: Marcin Krzeminski This patch adds both volatile and non volatile configuration registers and commands to allow modify them. It is needed for proper handling dummy cycles. Initialization of those registers and flash state has been included as well. Some of this registers are used by kernel. Signed-off-by: Marcin Krzeminski Acked-by: Peter Crosthwaite --- hw/block/m25p80.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 0698e7b..9d5a071 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -26,6 +26,7 @@ #include "sysemu/block-backend.h" #include "sysemu/blockdev.h" #include "hw/ssi/ssi.h" +#include "qemu/bitops.h" #ifndef M25P80_ERR_DEBUG #define M25P80_ERR_DEBUG 0 @@ -245,6 +246,15 @@ typedef enum { RESET_ENABLE = 0x66, RESET_MEMORY = 0x99, + + RNVCR = 0xB5, + WNVCR = 0xB1, + + RVCR = 0x85, + WVCR = 0x81, + + REVCR = 0x65, + WEVCR = 0x61, } FlashCMD; typedef enum { @@ -271,6 +281,9 @@ typedef struct Flash { uint8_t needed_bytes; uint8_t cmd_in_progress; uint64_t cur_addr; + uint32_t nonvolatile_cfg; + uint32_t volatile_cfg; + uint32_t enh_volatile_cfg; bool write_enable; bool four_bytes_address_mode; bool reset_enable; @@ -459,6 +472,15 @@ static void complete_collecting_data(Flash *s) case EXTEND_ADDR_WRITE: s->ear = s->data[0]; break; + case WNVCR: + s->nonvolatile_cfg = s->data[0] | (s->data[1] << 8); + break; + case WVCR: + s->volatile_cfg = s->data[0]; + break; + case WEVCR: + s->enh_volatile_cfg = s->data[0]; + break; default: break; } @@ -477,6 +499,42 @@ static void reset_memory(Flash *s) s->write_enable = false; s->reset_enable = false; + if (((s->pi->jedec >> 16) & 0xFF) == JEDEC_NUMONYX) { + s->volatile_cfg = 0; + /* WRAP & reserved*/ + s->volatile_cfg |= 0x3; + /* XIP */ + if (extract32(s->nonvolatile_cfg, 9, 3) != 0x7) { + s->volatile_cfg |= (1 << 3); + } + /* Number of dummy cycles */ + s->volatile_cfg |= deposit32(s->volatile_cfg, + 4, 4, extract32(s->nonvolatile_cfg, 12, 4)); + s->enh_volatile_cfg = 0; + /* Output driver strength */ + s->enh_volatile_cfg |= 0x7; + /* Vpp accelerator */ + s->enh_volatile_cfg |= (1 << 3); + /* Reset/hold & reserved */ + s->enh_volatile_cfg |= (1 << 4); + /* Dual I/O protocol */ + if ((s->nonvolatile_cfg >> 1) & 0x1) { + s->enh_volatile_cfg |= (1 << 6); + } + /* Quad I/O protocol */ + if ((s->nonvolatile_cfg >> 3) & 0x1) { + s->enh_volatile_cfg |= (1 << 7); + } + + if (!(s->nonvolatile_cfg & 0x1)) { + s->four_bytes_address_mode = true; + } + + if (!((s->nonvolatile_cfg >> 1) & 0x1)) { + s->ear = 0x3; + } + } + DB_PRINT_L(0, "Reset done.\n"); } @@ -617,6 +675,49 @@ static void decode_new_cmd(Flash *s, uint32_t value) s->state = STATE_COLLECTING_DATA; } break; + case RNVCR: + s->data[0] = s->nonvolatile_cfg & 0xFF; + s->data[1] = (s->nonvolatile_cfg >> 8) & 0xFF; + s->pos = 0; + s->len = 2; + s->state = STATE_READING_DATA; + break; + case WNVCR: + if (s->write_enable) { + s->needed_bytes = 2; + s->pos = 0; + s->len = 0; + s->state = STATE_COLLECTING_DATA; + } + break; + case RVCR: + s->data[0] = s->volatile_cfg & 0xFF; + s->pos = 0; + s->len = 1; + s->state = STATE_READING_DATA; + break; + case WVCR: + if (s->write_enable) { + s->needed_bytes = 1; + s->pos = 0; + s->len = 0; + s->state = STATE_COLLECTING_DATA; + } + break; + case REVCR: + s->data[0] = s->enh_volatile_cfg & 0xFF; + s->pos = 0; + s->len = 1; + s->state = STATE_READING_DATA; + break; + case WEVCR: + if (s->write_enable) { + s->needed_bytes = 1; + s->pos = 0; + s->len = 0; + s->state = STATE_COLLECTING_DATA; + } + break; case RESET_ENABLE: s->reset_enable = true; break; @@ -738,6 +839,11 @@ static void m25p80_pre_save(void *opaque) flash_sync_dirty((Flash *)opaque, -1); } +static Property m25p80_properties[] = { + DEFINE_PROP_UINT32("nonvolatile-cfg", Flash, nonvolatile_cfg, 0x8FFF), + DEFINE_PROP_END_OF_LIST(), +}; + static const VMStateDescription vmstate_m25p80 = { .name = "xilinx_spi", .version_id = 2, @@ -755,6 +861,9 @@ static const VMStateDescription vmstate_m25p80 = { VMSTATE_BOOL(four_bytes_address_mode, Flash), VMSTATE_UINT8(ear, Flash), VMSTATE_BOOL(reset_enable, Flash), + VMSTATE_UINT32(nonvolatile_cfg, Flash), + VMSTATE_UINT32(volatile_cfg, Flash), + VMSTATE_UINT32(enh_volatile_cfg, Flash), VMSTATE_END_OF_LIST() } }; @@ -770,6 +879,7 @@ static void m25p80_class_init(ObjectClass *klass, void *data) k->set_cs = m25p80_cs; k->cs_polarity = SSI_CS_LOW; dc->vmsd = &vmstate_m25p80; + dc->props = m25p80_properties; mc->pi = data; }