From patchwork Thu Nov 8 08:32:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frieder Schrempf X-Patchwork-Id: 994687 X-Patchwork-Delegate: miquel.raynal@bootlin.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.infradead.org (client-ip=2607:7c80:54:e::133; helo=bombadil.infradead.org; envelope-from=linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=kontron.De Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="GwqmmCZs"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=infradead.org header.i=@infradead.org header.b="gF7BGiOq"; dkim-atps=neutral Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:e::133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 42rGkJ231Lz9s9G for ; Thu, 8 Nov 2018 19:32:40 +1100 (AEDT) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-ID:Date:Subject:To :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: List-Owner; bh=wOuyYVs19vYxufU40T8iSUC2DaMV9idPjUWhlhQVjPQ=; b=GwqmmCZs/TQnm3 YVFatDkmmZvcPmkQxPAf+H/gHspoEG+JajiZ81Oa2muiFDq2gBq0scZ9hEm7ylMShblruXfQOb9C5 nmGPORfGZgcQjXNcnseRj5rsiR0g52tQIAKkjva5IEurRe2essjnkYY1Ud+n3FheAITarSaRBHDF2 bQ/3XNGcKbev7igMQkrBnr68qIm67Iwl9Nkan4nb/kvlNqH1Mo2qDVU5gGRI3M6URk+scImRrTBQu qHGs6PXG40bX20iLUdC17PnmTBD/cJuhgKirg8zTksgLKl/QkTgQkyT1HKO9ho++R5fZg0/GXEQD8 VW2w31PlmAW2bXNjkcXw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gKfjr-0000fB-Ky; Thu, 08 Nov 2018 08:32:31 +0000 Received: from casper.infradead.org ([2001:8b0:10b:1236::1]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gKfjp-0000f5-KK for linux-mtd@bombadil.infradead.org; Thu, 08 Nov 2018 08:32:29 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=MIME-Version:Content-Transfer-Encoding: Content-Type:Message-ID:Date:Subject:CC:To:From:Sender:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=ytml4q18vKfwM5VgAnEiCDuGyJJJAJU8yI49QC5N2RI=; b=gF7BGiOquVPBIk8QYDFdr88a2b luoSMoB3yJVi9o3utrooFlCWHYXe5+FlHHSe2u62QdtkDmZUGH74qNvszIBwspHV+QExFXnKMlis8 XwseqzaTp1bOjltAUCgT2m3SbCNyiDpcbV2RqPVbPBszZjSiXcW3GhLgmmI4XIObWuaXaA5ALu/X/ apyRJUuVAdQajOy60t1DTuXlqdGHDaqTX6IjFMwUxeKFUfaynY52QMycxPhO/RySx8okgHFdwqhwD oLdprAJ09fZAbMFn56OMWO5djUgxJjK3tWU7dk0BLQ3NI6DjXotpkGrcrOVqD+wXdML7xfrFst9Pk +tjM6drg==; Received: from skedge03.snt-world.com ([91.208.41.68]) by casper.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gKfjm-0005t0-DN for linux-mtd@lists.infradead.org; Thu, 08 Nov 2018 08:32:28 +0000 Received: from sntmail14r.snt-is.com (unknown [10.203.32.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by skedge03.snt-world.com (Postfix) with ESMTPS id 697122134261; Thu, 8 Nov 2018 09:32:11 +0100 (CET) Received: from sntmail11s.snt-is.com (10.203.32.181) by sntmail14r.snt-is.com (10.203.32.184) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1466.3; Thu, 8 Nov 2018 09:32:11 +0100 Received: from sntmail11s.snt-is.com ([fe80::b972:ad22:ada5:7c6a]) by sntmail11s.snt-is.com ([fe80::b972:ad22:ada5:7c6a%4]) with mapi id 15.01.1466.003; Thu, 8 Nov 2018 09:32:11 +0100 From: Schrempf Frieder To: Boris Brezillon , Miquel Raynal , Richard Weinberger , "David Woodhouse" , Brian Norris , Marek Vasut Subject: [PATCH] mtd: nand: spi: Add initial support for Toshiba TC58CVG2S0H Thread-Topic: [PATCH] mtd: nand: spi: Add initial support for Toshiba TC58CVG2S0H Thread-Index: AQHUdz2L3HigzaAOUUKXPQ4ku2nhHg== Date: Thu, 8 Nov 2018 08:32:11 +0000 Message-ID: <1541665796-21092-1-git-send-email-frieder.schrempf@kontron.de> Accept-Language: de-DE, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [172.25.9.42] x-c2processedorg: 51b406b7-48a2-4d03-b652-521f56ac89f3 MIME-Version: 1.0 X-SnT-MailScanner-Information: Please contact the ISP for more information X-SnT-MailScanner-ID: 697122134261.A566A X-SnT-MailScanner: Found to be clean X-SnT-MailScanner-SpamCheck: X-SnT-MailScanner-From: frieder.schrempf@kontron.de X-SnT-MailScanner-To: boris.brezillon@bootlin.com, computersforpeace@gmail.com, dwmw2@infradead.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, marek.vasut@gmail.com, miquel.raynal@bootlin.com, richard@nod.at X-Spam-Status: No X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181108_083226_652116_66BC6330 X-CRM114-Status: GOOD ( 23.72 ) X-Spam-Score: -0.0 (/) X-Spam-Report: SpamAssassin version 3.4.1 on casper.infradead.org summary: Content analysis details: (-0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [91.208.41.68 listed in list.dnswl.org] X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: "linux-mtd@lists.infradead.org" , "linux-kernel@vger.kernel.org" , Schrempf Frieder Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org Add minimal support for the Toshiba TC58CVG2S0H SPI NAND chip. Signed-off-by: Frieder Schrempf --- drivers/mtd/nand/spi/Makefile | 2 +- drivers/mtd/nand/spi/core.c | 1 + drivers/mtd/nand/spi/toshiba.c | 136 ++++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 1 + 4 files changed, 139 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile index b74e074..be5f735 100644 --- a/drivers/mtd/nand/spi/Makefile +++ b/drivers/mtd/nand/spi/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs := core.o macronix.o micron.o winbond.o +spinand-objs := core.o macronix.o micron.o toshiba.o winbond.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 30f8364..87bdf2a 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -766,6 +766,7 @@ static const struct nand_ops spinand_ops = { static const struct spinand_manufacturer *spinand_manufacturers[] = { ¯onix_spinand_manufacturer, µn_spinand_manufacturer, + &toshiba_spinand_manufacturer, &winbond_spinand_manufacturer, }; diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c new file mode 100644 index 0000000..294bcf6 --- /dev/null +++ b/drivers/mtd/nand/spi/toshiba.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 exceet electronics GmbH + * Copyright (c) 2018 Kontron Electronics GmbH + * + * Author: Frieder Schrempf + */ + +#include +#include +#include + +#define SPINAND_MFR_TOSHIBA 0x98 + +static SPINAND_OP_VARIANTS(read_cache_variants, + SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0), + SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0)); + +static SPINAND_OP_VARIANTS(write_cache_variants, + SPINAND_PROG_LOAD(true, 0, NULL, 0)); + +static SPINAND_OP_VARIANTS(update_cache_variants, + SPINAND_PROG_LOAD(false, 0, NULL, 0)); + +static int tc58cvg2s0h_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) +{ + if (section > 7) + return -ERANGE; + + region->offset = 128 + 16 * section; + region->length = 16; + + + return 0; +} + +static int tc58cvg2s0h_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *region) +{ + if (section > 7) + return -ERANGE; + + region->offset = 2 + 16 * section; + region->length = 14; + + + return 0; +} + +static const struct mtd_ooblayout_ops tc58cvg2s0h_ooblayout = { + .ecc = tc58cvg2s0h_ooblayout_ecc, + .free = tc58cvg2s0h_ooblayout_free, +}; + +static int tc58cvg2s0h_ecc_get_status(struct spinand_device *spinand, + u8 status) +{ + struct nand_device *nand = spinand_to_nand(spinand); + u8 mbf = 0; + struct spi_mem_op op = SPINAND_GET_FEATURE_OP(0x30, &mbf); + + switch (status & STATUS_ECC_MASK) { + case STATUS_ECC_NO_BITFLIPS: + return 0; + + case STATUS_ECC_UNCOR_ERROR: + return -EBADMSG; + + case STATUS_ECC_HAS_BITFLIPS: + /* + * Let's try to retrieve the real maximum number of bitflips + * in order to avoid forcing the wear-leveling layer to move + * data around if it's not necessary. + */ + if (spi_mem_exec_op(spinand->spimem, &op)) + return nand->eccreq.strength; + + mbf >>= 4; + + if (WARN_ON(mbf > nand->eccreq.strength || !mbf)) + return nand->eccreq.strength; + + return mbf; + + default: + break; + } + + return -EINVAL; +} + +static const struct spinand_info toshiba_spinand_table[] = { + SPINAND_INFO("TC58CVG2S0H", 0xCD, + NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), + NAND_ECCREQ(8, 512), + SPINAND_INFO_OP_VARIANTS(&read_cache_variants, + &write_cache_variants, + &update_cache_variants), + SPINAND_HAS_QE_BIT, + SPINAND_ECCINFO(&tc58cvg2s0h_ooblayout, + tc58cvg2s0h_ecc_get_status)), +}; + +static int toshiba_spinand_detect(struct spinand_device *spinand) +{ + u8 *id = spinand->id.data; + int ret; + + /* + * Toshiba SPI NAND read ID needs a dummy byte, + * so the first byte in id is garbage. + */ + if (id[1] != SPINAND_MFR_TOSHIBA) + return 0; + + ret = spinand_match_and_init(spinand, toshiba_spinand_table, + ARRAY_SIZE(toshiba_spinand_table), + id[2]); + if (ret) + return ret; + + return 1; +} + +static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops = { + .detect = toshiba_spinand_detect, +}; + +const struct spinand_manufacturer toshiba_spinand_manufacturer = { + .id = SPINAND_MFR_TOSHIBA, + .name = "Toshiba", + .ops = &toshiba_spinand_manuf_ops, +}; diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 088ff96..816c4b0 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -196,6 +196,7 @@ struct spinand_manufacturer { /* SPI NAND manufacturers */ extern const struct spinand_manufacturer macronix_spinand_manufacturer; extern const struct spinand_manufacturer micron_spinand_manufacturer; +extern const struct spinand_manufacturer toshiba_spinand_manufacturer; extern const struct spinand_manufacturer winbond_spinand_manufacturer; /**