From nobody Thu Apr 2 22:04:18 2026 Received: from smtpout-02.galae.net (smtpout-02.galae.net [185.246.84.56]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0FDF940FDAF for ; Thu, 26 Mar 2026 16:26:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.246.84.56 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774542379; cv=none; b=CsfOcnXY7u/XBggXPehzIToVvdAoyqvxVGrGmLzguzsWvMjyU09DHfu0JlJv7Ropb2oy9COSkl44zRrCflMIP50uowkPcY0IqzUzsJdjcBGMV3rVKCj/ZWjdd6RrXijlgT/tMcTdh9nelTDUbLGLrUhHEsTJXKKnasF9B6mkhqM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774542379; c=relaxed/simple; bh=bZ6BNWvdAQm3cDYqyQDwx0kuZTglGhe3G7YXvwdSTlg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=nhpuf1ELWRkkEQwZUcKdEPmeCAZUuN3vtGfw87HuMyMOI115vJTdZwB3YPEvbUvitux1C1iB5PbVesXwLaVPe5fLx8k85S6YKGSEYkWiZF5iTRilTT1Bj+4Pk/ML/aQ2DgzfCD3iFr15nOwjUnax5TV69BNnlzFexpW/ucNLD+c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=Of4KHQSA; arc=none smtp.client-ip=185.246.84.56 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="Of4KHQSA" Received: from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233]) by smtpout-02.galae.net (Postfix) with ESMTPS id C0ADC1A3008; Thu, 26 Mar 2026 16:26:11 +0000 (UTC) Received: from mail.galae.net (mail.galae.net [212.83.136.155]) by smtpout-01.galae.net (Postfix) with ESMTPS id 8EE1C601FA; Thu, 26 Mar 2026 16:26:11 +0000 (UTC) Received: from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon) with ESMTPSA id DECB810450C99; Thu, 26 Mar 2026 17:26:09 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim; t=1774542370; h=from:subject:date:message-id:to:cc:mime-version:content-type: content-transfer-encoding:in-reply-to:references; bh=rlTKENBwUOxRSRFDk4mW7jT5HzuysuTleMW111bj1mo=; b=Of4KHQSA+1zvTKT2x+KYSyjNtVJCsB6+DUdi7HQkfsgkkMtfu0LcfffKZWUeuNZQ1DwbZi zTB36Y271KDhHHeIW89XbzebSpEG08XpFJD4Vm5/Svemzbfp9zIFAAll6TN/14C5OAtILE UmchmGAcsBU4C1Qrptfn8x6Dv2owWWEc/ZcauIMuKs+jTfpxD3gCJeMvn2IpwRm3vROZe0 iCCiAR4iUVEZJTfcGF1Kem/DB4HqIsB99Yei/F40uusDRO4EEwY1GunePX83O6lGgzDYyA MHl7I4cKrKTEhQbSVdS1wfJj/ioW3YEbcXedTJsCGkeFco6aPnraD065CpOkAA== From: Miquel Raynal Date: Thu, 26 Mar 2026 17:25:50 +0100 Subject: [PATCH v2 03/11] mtd: spinand: Drop ECC dirmaps Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260326-winbond-v6-18-rc1-cont-read-v2-3-643de97a68a3@bootlin.com> References: <20260326-winbond-v6-18-rc1-cont-read-v2-0-643de97a68a3@bootlin.com> In-Reply-To: <20260326-winbond-v6-18-rc1-cont-read-v2-0-643de97a68a3@bootlin.com> To: Mark Brown , Richard Weinberger , Vignesh Raghavendra , Michael Walle , Miquel Raynal Cc: Pratyush Yadav , Thomas Petazzoni , Steam Lin , Santhosh Kumar K , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org X-Mailer: b4 0.14.3 X-Last-TLS-Session-Version: TLSv1.3 Direct mappings are very static concepts, which allow us to reuse a template to perform reads or writes in a very efficient manner after a single initialization. With the introduction of pipelined ECC engines for SPI controllers, the need to differentiate between an operation with and without correction has arised. The chosen solution at that time has been to create new direct mappings for these operations, jumping from 2 to 4 dirmaps per target. Enabling ECC was done by choosing the correct dirmap. Today, we need to further parametrize dirmaps. With the goal to enable continuous reads on a wider range of devices, we will need more flexibility regarding the read from cache operation template to pick at run time, for instance to use shorter "continuous read from cache" variants. We could create other direct mappings, but it would increase the matrix by a power of two, bringing the theoretical number of dirmaps to 8 (read/write, ecc, shorter read variants) per target. This grow is not sustainable, so let's change how dirmaps work - a little bit. Operations already carry an ECC parameter, use it to indicate whether error correction is required or not. In practice this change happens only at the core level, SPI controller drivers do not care about the direct mapping structure in this case, they just pick whatever is in the template as a base. As a result, we allow the core to dynamically change the content of the templates. He who can do more can do less, so during the checking steps, make sure to enable the ECC requirement just for the time of the checks. Signed-off-by: Miquel Raynal --- drivers/mtd/nand/spi/core.c | 52 +++++++++++++++++------------------------= ---- include/linux/mtd/spinand.h | 2 -- 2 files changed, 20 insertions(+), 34 deletions(-) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 1c3ac9ad650e..663f5d6a6bd7 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -487,10 +487,13 @@ static int spinand_read_from_cache_op(struct spinand_= device *spinand, } } =20 - if (req->mode =3D=3D MTD_OPS_RAW) - rdesc =3D spinand->dirmaps[req->pos.plane].rdesc; + rdesc =3D spinand->dirmaps[req->pos.plane].rdesc; + + if (nand->ecc.engine->integration =3D=3D NAND_ECC_ENGINE_INTEGRATION_PIPE= LINED && + req->mode !=3D MTD_OPS_RAW) + rdesc->info.op_tmpl.data.ecc =3D true; else - rdesc =3D spinand->dirmaps[req->pos.plane].rdesc_ecc; + rdesc->info.op_tmpl.data.ecc =3D false; =20 if (spinand->flags & SPINAND_HAS_READ_PLANE_SELECT_BIT) column |=3D req->pos.plane << fls(nanddev_page_size(nand)); @@ -579,10 +582,13 @@ static int spinand_write_to_cache_op(struct spinand_d= evice *spinand, req->ooblen); } =20 - if (req->mode =3D=3D MTD_OPS_RAW) - wdesc =3D spinand->dirmaps[req->pos.plane].wdesc; + wdesc =3D spinand->dirmaps[req->pos.plane].wdesc; + + if (nand->ecc.engine->integration =3D=3D NAND_ECC_ENGINE_INTEGRATION_PIPE= LINED && + req->mode !=3D MTD_OPS_RAW) + wdesc->info.op_tmpl.data.ecc =3D true; else - wdesc =3D spinand->dirmaps[req->pos.plane].wdesc_ecc; + wdesc->info.op_tmpl.data.ecc =3D false; =20 if (spinand->flags & SPINAND_HAS_PROG_PLANE_SELECT_BIT) column |=3D req->pos.plane << fls(nanddev_page_size(nand)); @@ -1231,12 +1237,17 @@ static int spinand_create_dirmap(struct spinand_dev= ice *spinand, struct nand_device *nand =3D spinand_to_nand(spinand); struct spi_mem_dirmap_info info =3D { 0 }; struct spi_mem_dirmap_desc *desc; + bool enable_ecc =3D false; + + if (nand->ecc.engine->integration =3D=3D NAND_ECC_ENGINE_INTEGRATION_PIPE= LINED) + enable_ecc =3D true; =20 /* The plane number is passed in MSB just above the column address */ info.offset =3D plane << fls(nand->memorg.pagesize); =20 + /* Write descriptor */ info.length =3D nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); - info.op_tmpl =3D *spinand->op_templates->update_cache; + info.op_tmpl.data.ecc =3D enable_ecc; desc =3D devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, spinand->spimem, &info); if (IS_ERR(desc)) @@ -1244,38 +1255,15 @@ static int spinand_create_dirmap(struct spinand_dev= ice *spinand, =20 spinand->dirmaps[plane].wdesc =3D desc; =20 + /* Read descriptor */ info.op_tmpl =3D *spinand->op_templates->read_cache; + info.op_tmpl.data.ecc =3D enable_ecc; desc =3D spinand_create_rdesc(spinand, &info); if (IS_ERR(desc)) return PTR_ERR(desc); =20 spinand->dirmaps[plane].rdesc =3D desc; =20 - if (nand->ecc.engine->integration !=3D NAND_ECC_ENGINE_INTEGRATION_PIPELI= NED) { - spinand->dirmaps[plane].wdesc_ecc =3D spinand->dirmaps[plane].wdesc; - spinand->dirmaps[plane].rdesc_ecc =3D spinand->dirmaps[plane].rdesc; - - return 0; - } - - info.length =3D nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); - info.op_tmpl =3D *spinand->op_templates->update_cache; - info.op_tmpl.data.ecc =3D true; - desc =3D devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, - spinand->spimem, &info); - if (IS_ERR(desc)) - return PTR_ERR(desc); - - spinand->dirmaps[plane].wdesc_ecc =3D desc; - - info.op_tmpl =3D *spinand->op_templates->read_cache; - info.op_tmpl.data.ecc =3D true; - desc =3D spinand_create_rdesc(spinand, &info); - if (IS_ERR(desc)) - return PTR_ERR(desc); - - spinand->dirmaps[plane].rdesc_ecc =3D desc; - return 0; } =20 diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 29ce5827032a..bbf17c346887 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -683,8 +683,6 @@ struct spinand_info { struct spinand_dirmap { struct spi_mem_dirmap_desc *wdesc; struct spi_mem_dirmap_desc *rdesc; - struct spi_mem_dirmap_desc *wdesc_ecc; - struct spi_mem_dirmap_desc *rdesc_ecc; }; =20 /** --=20 2.51.1