From patchwork Mon Sep 25 10:40:08 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lukasz Majewski X-Patchwork-Id: 818170 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3y10wr6vfnz9sNr for ; Mon, 25 Sep 2017 20:40:44 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id 86408C221C2; Mon, 25 Sep 2017 10:40:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.7 required=5.0 tests=RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 00D72C220EA; Mon, 25 Sep 2017 10:40:38 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 9ECDAC220EA; Mon, 25 Sep 2017 10:40:36 +0000 (UTC) Received: from mail-out.m-online.net (mail-out.m-online.net [212.18.0.9]) by lists.denx.de (Postfix) with ESMTPS id 56032C21DA6 for ; Mon, 25 Sep 2017 10:40:36 +0000 (UTC) Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 3y10wf5GFgz1qsTh; Mon, 25 Sep 2017 12:40:34 +0200 (CEST) Received: from localhost (dynscan1.mnet-online.de [192.168.6.70]) by mail.m-online.net (Postfix) with ESMTP id 3y10wf507Dz1qqkV; Mon, 25 Sep 2017 12:40:34 +0200 (CEST) X-Virus-Scanned: amavisd-new at mnet-online.de Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.70]) (amavisd-new, port 10024) with ESMTP id N3JwcpyuIG_V; Mon, 25 Sep 2017 12:40:33 +0200 (CEST) X-Auth-Info: eF9djvXyMq7OeUJvaSfbhtG/34A2jGf/cVOTyMLFdJw= Received: from localhost.localdomain (89-64-27-66.dynamic.chello.pl [89.64.27.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPSA; Mon, 25 Sep 2017 12:40:33 +0200 (CEST) From: Lukasz Majewski To: Jagan Teki , u-boot@lists.denx.de Date: Mon, 25 Sep 2017 12:40:08 +0200 Message-Id: <1506336008-21852-1-git-send-email-lukma@denx.de> X-Mailer: git-send-email 2.1.4 Subject: [U-Boot] [PATCH v2] sf: bar: Clean BA24 Bank Address Register bit after read/write/erase operation X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" The content of Bank Address Register (BAR) is volatile. It is cleared after power cycle or reset command (RESET F0h). Some memories (like e.g. s25fl256s) use it to access memory larger than 0x1000000 (16 MiB). The problem shows up when one: 1. Reads/writes/erases memory > 16 MiB 2. Calls "reset" u-boot command (which is not causing BAR to be cleared) In the above scenario, the SoC ROM sends 0x000000 address to read SPL. Unfortunately, the BA24 bit is still set and hence it receives content from 0x1000000 (16 MiB) memory address. As a result the SoC aborts and we hang. Only power cycle can take the SoC out of this state. How to reproduce/test: sf probe; sf erase 0x1200000 0x800000; reset sf probe; sf erase 0x1200000 0x800000; sf write 0x11000000 0x1200000 0x800000; reset sf probe; sf read 0x11000000 0x1200000 0x800000; reset Signed-off-by: Lukasz Majewski --- Changes in v2: - Rename cleanup_bar() to clean_bar() - Rewrite in-code comments --- drivers/mtd/spi/spi_flash.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index 34f6888..5b3c974 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -113,6 +113,27 @@ static int write_cr(struct spi_flash *flash, u8 wc) #endif #ifdef CONFIG_SPI_FLASH_BAR +/* + * This "cleanup" is necessary in a situation when one was accessing + * spi flash memory > 16 MiB by using Bank Address Register's BA24 bit. + * + * After it the BA24 bit shall be cleared to allow access to correct + * memory region after SW reset (by calling "reset" command). + * + * Otherwise, the BA24 bit may be left set and then after reset, the + * ROM would read/write/erase SPL from 16 MiB * bank_sel address. + */ +static int clean_bar(struct spi_flash *flash) +{ + u8 cmd, bank_sel = 0; + + if (flash->bank_curr == 0) + return 0; + cmd = flash->bank_write_cmd; + + return spi_flash_write_common(flash, &cmd, 1, &bank_sel, 1); +} + static int write_bar(struct spi_flash *flash, u32 offset) { u8 cmd, bank_sel; @@ -339,6 +360,10 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len) len -= erase_size; } +#ifdef CONFIG_SPI_FLASH_BAR + ret = clean_bar(flash); +#endif + return ret; } @@ -397,6 +422,10 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset, offset += chunk_len; } +#ifdef CONFIG_SPI_FLASH_BAR + ret = clean_bar(flash); +#endif + return ret; } @@ -500,6 +529,10 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset, data += read_len; } +#ifdef CONFIG_SPI_FLASH_BAR + ret = clean_bar(flash); +#endif + free(cmd); return ret; }