From patchwork Mon Sep 1 11:48:25 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Marshall X-Patchwork-Id: 384780 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2001:1868:205::9]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id D99431401DE for ; Mon, 1 Sep 2014 21:50:25 +1000 (EST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1XOQ6N-0006SN-Pa; Mon, 01 Sep 2014 11:48:51 +0000 Received: from mail-qg0-x22b.google.com ([2607:f8b0:400d:c04::22b]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1XOQ6K-0006FB-Ft; Mon, 01 Sep 2014 11:48:49 +0000 Received: by mail-qg0-f43.google.com with SMTP id f51so5101617qge.30 for ; Mon, 01 Sep 2014 04:48:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=xvO7T1yy8Q178H0Qz0lnVz7NPQEXan2h7pIbGNEtOzk=; b=ZaBzh/0E19ZzRtbxLMpUp4pnfRU5Vt+WU/hNw5BkL4ed2YXyeuPF/PyoTAxzLo9bU8 h5AMwQtN1l/0IojwnI22+yRV9KCbu3NmRM5CuTHsIRYGFv5K4KrVejTaJuTIWznZM2v/ Lib3+sDw00p3nBg5kHkwLpDfjcHxjtnDNPIyU6GxkZOqAh3j9DYrapn70/YbXuOdYdZY 4dF3gtfy41/83anUiIBoJtaR3bf+5VaU/w7iRZ4K+0rCrN9h2K4LEx5Xm4ciaC0SK2Ed B0grz/dqr+LMT54g6c8kAs+TJC1gFEC4LGfX08btE3bJ949h8ejfshU26xnFwAnjseeQ uf8w== MIME-Version: 1.0 X-Received: by 10.229.62.129 with SMTP id x1mr44092395qch.16.1409572105901; Mon, 01 Sep 2014 04:48:25 -0700 (PDT) Received: by 10.140.84.244 with HTTP; Mon, 1 Sep 2014 04:48:25 -0700 (PDT) In-Reply-To: <54043FDA.4050707@gmail.com> References: <54043FDA.4050707@gmail.com> Date: Mon, 1 Sep 2014 13:48:25 +0200 Message-ID: Subject: Re: [RFC] MTD m25p80 3-byte addressing and boot problem From: Mark Marshall To: Matteo Fortini X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140901_044848_693499_3A5FE058 X-CRM114-Status: GOOD ( 37.57 ) X-Spam-Score: 0.1 (/) X-Spam-Report: SpamAssassin version 3.4.0 on bombadil.infradead.org summary: Content analysis details: (0.1 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (markmarshall14[at]gmail.com) 0.2 FREEMAIL_ENVFROM_END_DIGIT Envelope-from freemail username ends in digit (markmarshall14[at]gmail.com) -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature Cc: barebox@lists.infradead.org, linux-mtd@lists.infradead.org, mike@steroidmicros.com X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Hi. We had the same problem here, but luckily our Flash also supported a different read command that took the larger address. I made a (small) modification to the m25p80 driver to use this command when the flash supported it. I've attached the two patches that come from my tree that are relevant. The first one (42) just changes to the page size used to access the flash, and is only needed so that you don;t get conflicts wit the second. The second patch (45) is the one of interest. These patches are against v3.2.52-rt73 from the real-time tree, and there are (obviously) other patches either side of them, but they should show what I have done. At some point (!) I'll try to push these up-stream, but as ou can see, we are well behind the curve at the moment, which makes this harder. Regards, Mark Marshall. PS. On our original prototype hardware we had no reset line connected to the flash, so even a hard reset wouldn't get things back to how they should be when Linux was changing the bank register! I think that the longer commands should be used if the flash chip supports them in preference to either bank switching or "converting" the small commands to longer ones. On 1 September 2014 11:43, Matteo Fortini wrote: > If a Linux/Barebox system is using an SPI flash of size >= 16 MB, the driver > is switching to 3-byte addressing to be able to use linear access to the > whole memory. > > This leads to the impossibility to boot a board after a warm reset, because > all bootloaders use the standard 2-byte addressing (if the board doesn't > physically reset the flash or do something similar). > > Some documentation in the following links: > http://www.at91.com/discussions/viewtopic.php/f,30/t,22849.html > https://community.freescale.com/docs/DOC-93632 > > The solution proposed on freescale forums is not final: it involves > switching back to 2-byte addressing after every access, which still leaves a > small window in which a warm reset would be fatal. > > One solution would be to use the bank command in the flash, using each 16MB > bank linearly, and changing bank depending on the address. This would be > messy for accesses which are crossing the boundary, but it is doable. > > I'm asking here for comments before I start patching the code. Right now I > resorted to stick to 2-byte addressing and leave half of my NOR (32MB) > unused. > > TIA, > M > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ From 7c14b894f1884bf7915417ce8b747b11b6f603c6 Mon Sep 17 00:00:00 2001 From: Mark Marshall Date: Wed, 31 Jul 2013 15:26:12 +0200 Subject: [PATCH 45/96] m25p80: Use the 4-byte address read command It is better for some hardware platforms if we use the dedicated 4-byte address SPI read command when reading from SPI Flash chips > 16 MB (rather than converting the 3-byte address command to take 4 address bytes). The problem that we had is that on reset the boot loader tries to use the 3-byte address command which, doesn't work if the Flash has not been reset and Linux has converted it to accept 4-byte addresses. --- drivers/mtd/devices/m25p80.c | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index fa0f2c0..2d87aad 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -62,6 +62,11 @@ #define OPCODE_OTP_WRITE 0x42 /* Write to the OTP region */ #define OPCODE_OTP_READ 0x4b /* Read from the OTP region */ +#define OPCODE_FAST_READ4B 0x0c /* Read data, 4 byte addr (hi freq.) */ +#define OPCODE_NORM_READ4B 0x13 /* Read data, 4 byte addr (lo freq.) */ +#define OPCODE_PP4B 0x12 /* Page program (up to 256 bytes) */ +#define OPCODE_SE4B 0xdc /* Sector erase (usually 256KiB) */ + /* Status Register bits. */ #define SR_WIP 1 /* Write in progress */ #define SR_WEL 2 /* Write enable latch */ @@ -77,9 +82,11 @@ #ifdef CONFIG_M25PXX_USE_FAST_READ #define OPCODE_READ OPCODE_FAST_READ +#define OPCODE_READ4B OPCODE_FAST_READ4B #define FAST_READ_DUMMY_BYTE 1 #else #define OPCODE_READ OPCODE_NORM_READ +#define OPCODE_READ4B OPCODE_NORM_READ4B #define FAST_READ_DUMMY_BYTE 0 #endif @@ -94,6 +101,8 @@ struct m25p { u16 page_size; u16 addr_width; u8 erase_opcode; + u8 read_opcode; + u8 write_opcode; u8 *command; }; @@ -173,10 +182,20 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; return spi_write(flash->spi, flash->command, 1); default: - /* Spansion style */ - flash->command[0] = OPCODE_BRWR; - flash->command[1] = enable << 7; - return spi_write(flash->spi, flash->command, 2); + switch (jedec_id) { + case 0x010219: /* s25fl256s0/s25fl256s1 */ + case 0x010220: /* s25fl512s */ + case 0x010221: /* s70fl01gs */ + flash->read_opcode = OPCODE_READ4B; + flash->write_opcode = OPCODE_PP4B; + flash->erase_opcode = OPCODE_SE4B; + return 0; + default: + /* Spansion style */ + flash->command[0] = OPCODE_BRWR; + flash->command[1] = enable << 7; + return spi_write(flash->spi, flash->command, 2); + } } } @@ -402,7 +421,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, */ /* Set up the write data buffer. */ - flash->command[0] = OPCODE_READ; + flash->command[0] = flash->read_opcode; m25p_addr2cmd(flash, from + done, flash->command); spi_sync(flash->spi, &m); @@ -462,7 +481,7 @@ static int m25p80_write(struct mtd_info *mtd, loff_t to, size_t len, write_enable(flash); /* Set up the opcode in the write buffer. */ - flash->command[0] = OPCODE_PP; + flash->command[0] = flash->write_opcode; m25p_addr2cmd(flash, to, flash->command); page_offset = to & (flash->page_size - 1); @@ -944,7 +963,7 @@ static const struct spi_device_id m25p_ids[] = { { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) }, { "s25fl512s", INFOP(0x010220, 0x4d00, 256 * 1024, 256, 512, M25P_OTP) }, - { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, + { "s70fl01gs", INFOP(0x010221, 0x4d00, 256 * 1024, 256, 512, 0) }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, { "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64, 0) }, @@ -1172,6 +1191,9 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.erasesize = info->sector_size; } + flash->read_opcode = OPCODE_READ; + flash->write_opcode = OPCODE_PP; + if (info->flags & M25P_NO_ERASE) flash->mtd.flags |= MTD_NO_ERASE; -- 1.7.9.5