From patchwork Tue Oct 5 14:56:39 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Reinhard Meyer X-Patchwork-Id: 71855 X-Patchwork-Delegate: vapier@gentoo.org Return-Path: X-Original-To: wd@gemini.denx.de Delivered-To: wd@gemini.denx.de Received: from diddl.denx.de (diddl.denx.de [10.0.0.6]) by gemini.denx.de (Postfix) with ESMTP id 5FF8A1539A2 for ; Tue, 5 Oct 2010 17:00:06 +0200 (CEST) Received: from diddl.denx.de (localhost.localdomain [127.0.0.1]) by diddl.denx.de (Postfix) with ESMTP id 4D2B7348C9D0 for ; Tue, 5 Oct 2010 17:00:06 +0200 (CEST) Received: from pop.mnet-online.de by diddl.denx.de with POP3 (fetchmail-6.3.17) for (single-drop); Tue, 05 Oct 2010 17:00:06 +0200 (CEST) Received: from murder ([192.168.8.180]) by backend2 (Cyrus v2.2.12) with LMTPA; Tue, 05 Oct 2010 16:57:47 +0200 X-Sieve: CMU Sieve 2.2 Received: from mail.m-online.net (localhost [127.0.0.1]) by frontend1.mail.m-online.net (Cyrus v2.2.12) with LMTPA; Tue, 05 Oct 2010 16:57:47 +0200 Received: from scanner-3.m-online.net (unknown [192.168.6.168]) by mail.m-online.net (Postfix) with ESMTP id 0F8A51C00345; Tue, 5 Oct 2010 16:57:47 +0200 (CEST) Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by mxin-3.m-online.net (Postfix) with ESMTP id 10DAC46C0BC; Tue, 5 Oct 2010 16:57:42 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 3D481281C4; Tue, 5 Oct 2010 16:57:15 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id U+Uq8zZi47Tq; Tue, 5 Oct 2010 16:57:15 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id D33D32820D; Tue, 5 Oct 2010 16:57:05 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 13C852819C for ; Tue, 5 Oct 2010 16:57:02 +0200 (CEST) Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id q1EC4-+3atQP for ; Tue, 5 Oct 2010 16:57:00 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.186]) by theia.denx.de (Postfix) with ESMTP id 032EF28166 for ; Tue, 5 Oct 2010 16:56:55 +0200 (CEST) Received: from localhost.localdomain (p5B201750.dip0.t-ipconnect.de [91.32.23.80]) by mrelayeu.kundenserver.de (node=mrbap0) with ESMTP (Nemesis) id 0MRBAV-1PA2hl1ObX-00Ujns; Tue, 05 Oct 2010 16:56:46 +0200 From: Reinhard Meyer To: u-boot@lists.denx.de Date: Tue, 5 Oct 2010 16:56:39 +0200 Message-Id: <1286290600-18988-2-git-send-email-u-boot@emk-elektronik.de> X-Mailer: git-send-email 1.5.6.5 In-Reply-To: <1286290600-18988-1-git-send-email-u-boot@emk-elektronik.de> References: <1286290600-18988-1-git-send-email-u-boot@emk-elektronik.de> X-Provags-ID: V02:K0:/vjzlJLXfakgpS8rrSKaeY+jyT+pThtJO7T6kCks1ki mAesIF+7VYSpG7a2bmxrNoduBIqrsF0IAegcJfPitqsRaLpa20 qTggwVHI3LBPtzj1rNuiZAOStpFbsceTALhDI4Y/OxJpj4nTOZ 5FHsGE71rutevNHgmUNNqhK5fOz5Qpl9u7WHAMv5ECLnVf9/Hj W6sRKUGGDUtZEOzj809PnPvNoQGCi6IvpiAK6zzD28= Subject: [U-Boot] [PATCH V5 1/2] MTD/SPI: introduce table driven probing X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de X-Virus-Scanned: by amavisd-new at m-online.net for JEDEC devices without and with extension bytes for non JEDEC devices Signed-off-by: Reinhard Meyer --- drivers/mtd/spi/spi_flash.c | 137 +++++++++++++++++++++++++++++-------------- 1 files changed, 93 insertions(+), 44 deletions(-) diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c index ea875dc..e19f47d 100644 --- a/drivers/mtd/spi/spi_flash.c +++ b/drivers/mtd/spi/spi_flash.c @@ -1,8 +1,26 @@ /* - * SPI flash interface + * (C) Copyright 2010 + * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.de * * Copyright (C) 2008 Atmel Corporation - * Licensed under the GPL-2 or later. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA */ #include @@ -96,13 +114,59 @@ int spi_flash_read_common(struct spi_flash *flash, const u8 *cmd, return ret; } +/* + * the following table holds all device probe functions + * + * shift: number of continuation bytes before the ID + * idcode: the expected IDCODE or 0xff for non JEDEC devices + * probe: the function to call + * + * non JEDEC devices should be ordered in the table such that + * the probe functions with best detection algorithms come first + * + * several matching entries are permitted, they will be tried + * in sequence until a probe function returns non NULL + * + * IDBUF_LEN may be redefined if a device detection requires + * more then 5 bytes read. + */ +#define IDBUF_LEN 5 +const struct { + const u8 shift; + const u8 idcode; + struct spi_flash *(*probe) (struct spi_slave *spi, u8 *idcode); +} flashes[] = { +#ifdef CONFIG_SPI_FLASH_SPANSION + { 0, 0x01, spi_flash_probe_spansion, }, +#endif +#ifdef CONFIG_SPI_FLASH_ATMEL + { 0, 0x1F, spi_flash_probe_atmel, }, +#endif +#ifdef CONFIG_SPI_FLASH_MACRONIX + { 0, 0xc2, spi_flash_probe_macronix, }, +#endif +#ifdef CONFIG_SPI_FLASH_WINBOND + { 0, 0xef, spi_flash_probe_winbond, }, +#endif +#ifdef CONFIG_SPI_FLASH_STMICRO + { 0, 0x20, spi_flash_probe_stmicro, }, + { 0, 0xff, spi_flash_probe_stmicro, }, +#endif +#ifdef CONFIG_SPI_FLASH_SST + { 0, 0xBF, spi_flash_probe_sst, }, +#endif +}; + struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int spi_mode) { struct spi_slave *spi; - struct spi_flash *flash; + struct spi_flash *flash = NULL; int ret; - u8 idcode[5]; + int shift; + int i; + u8 idbuf[IDBUF_LEN]; + u8 *idp; spi = spi_setup_slave(bus, cs, max_hz, spi_mode); if (!spi) { @@ -117,53 +181,38 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs, } /* Read the ID codes */ - ret = spi_flash_cmd(spi, CMD_READ_ID, &idcode, sizeof(idcode)); + ret = spi_flash_cmd(spi, CMD_READ_ID, &idbuf, sizeof(idbuf)); if (ret) goto err_read_id; - debug("SF: Got idcode %02x %02x %02x %02x %02x\n", idcode[0], - idcode[1], idcode[2], idcode[3], idcode[4]); - - switch (idcode[0]) { -#ifdef CONFIG_SPI_FLASH_SPANSION - case 0x01: - flash = spi_flash_probe_spansion(spi, idcode); - break; -#endif -#ifdef CONFIG_SPI_FLASH_ATMEL - case 0x1F: - flash = spi_flash_probe_atmel(spi, idcode); - break; -#endif -#ifdef CONFIG_SPI_FLASH_MACRONIX - case 0xc2: - flash = spi_flash_probe_macronix(spi, idcode); - break; -#endif -#ifdef CONFIG_SPI_FLASH_WINBOND - case 0xef: - flash = spi_flash_probe_winbond(spi, idcode); - break; -#endif -#ifdef CONFIG_SPI_FLASH_STMICRO - case 0x20: - case 0xff: /* Let the stmicro func handle non-JEDEC ids */ - flash = spi_flash_probe_stmicro(spi, idcode); - break; +#ifdef DEBUG + printf("SF: Got idcodes\n"); + print_buffer(0, idbuf, 1, sizeof(idbuf), 0); #endif -#ifdef CONFIG_SPI_FLASH_SST - case 0xBF: - flash = spi_flash_probe_sst(spi, idcode); - break; -#endif - default: - printf("SF: Unsupported manufacturer %02X\n", idcode[0]); - flash = NULL; - break; + + /* + * count the number of continuation bytes, but + * leave at least 3 bytes to the end of the buffer untouched + */ + for (shift = 0, idp = idbuf; + shift < (sizeof(idbuf) - 3) && *idp == 0x7f; + shift++, idp++) + ; + + /* search the table for matches in shift and id */ + for (i = 0; i < ARRAY_SIZE(flashes); i++) { + if (flashes[i].shift == shift && flashes[i].idcode == *idp) { + /* we have a match, call probe */ + flash = flashes[i].probe(spi, idp); + if (flash) + break; + } } - if (!flash) + if (!flash) { + printf("SF: Unsupported manufacturer %02X\n", *idp); goto err_manufacturer_probe; + } spi_release_bus(spi);