From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 0E9344F796C; Tue, 3 Mar 2026 16:37:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555832; cv=none; b=Q/tL0VKXrJSVicSvruF/ofNKBD8x+OV5Bjb82WdDAZ2YgSzfARSmNBa6I60sBuxytxKkhc5sWH/m4uwbv2x95OfN4Gr0v8XbbEZE5JNrD4tnmBf51QsfCxt+pPfa4ZjVA+0wY0I/DG0t3kvw1dN8O4Cn2XqSfE3R8BcgrhmWyq8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555832; c=relaxed/simple; bh=ZnYngTlVQzycdtY2m/RKcREfQ/63W022ZEx/xYzEu6g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=JfL2bYJb20PpUDQmRvcOG9Cllbl26FC2wNK/ou8wBLhz1jXhhVvj+fFJlXjbjJ+IcM+9nsyR2w+5WearGx4aq/ky/+hra72c8oh32tNK7QV5JK5GMYEoAHMpWQxOqa1VO+vCbXBGjdlfOW8/NLbSym3mFk0+RuFUhhnsaLL6OOY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=RJ7ZVyJG; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="RJ7ZVyJG" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555396; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=BQpGPSsrmt5iFf8ycx5AlTFs3GDIIi8/v45rG7lvG9E=; b=RJ7ZVyJG+KcCDsqtEKVaft96gFljbG0QnrDqcEaQhES+7duAAfX9XINpkZukPWPpxkQAiT ObisQQAu7sFaBTTgu0IgG9BsNECNUic/ml4yyp0cjs2sr+vTF6boKHhnZ167h4+WexxYRc qXpCUxRKwiKqJ8ftvhF5jIjwC3MaO94llQMZ1JZOEbjKRwG7Z63eTESJFx9jxEr/p0LfRL xw0t/xF5P+4PsdGnOkw3Ed8B2ZQC1+FPr3dxDyIdqixE2tuKRjfHMgW/0pZ3WkNtBz2tX/ y/ijtE6uisHrTzbbHXhx7leBJv2D3sEarAbLex26HU8x+n2r7ahL7pUogiwnZQ== Date: Tue, 03 Mar 2026 17:29:22 +0100 Subject: [PATCH RFC 1/7] spi: Add 'rx_sampling_delay_ns' parameter for clock to RX delay 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: <20260303-fsl-qspi-rx-sampling-delay-v1-1-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2060; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=XlqBJm6qGT+yufD3x6JPfqlL1/qFkwpILnGBWgECzFk=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T9OFDXvSpisb72j5uznvPbPw02vpJ/ZntCx4pCG9w v3sRnaPjlIWBjEuBlkxRRYpfovXtmaxPvLHqqNg5rAygQxh4OIUgImcfsbwPzT+ugjrrn1B97v9 9zXN3j/Rr5G/wptL/tuMrt+SLF8vXWJk2Hr1cm7jOe9JRpKBu2ecjPu7OXmiaPC77y1v1MQDEn5 N4gUA X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Eberhard Stoll Some high speed SPI devices require a delay between the controller clock and the sampling point of the client device. This 'clock to receive data delay' value is often referenced as tCLQV in SPI device data sheets. Not respecting this can lead to data being sampled too early when the client doesn't yet reflect the correct level at the data out pin(s). There are two ways to handle the situation: 1. Reduce the controller clock to the amount where the sampling point requirement of the client is still met, meaning the clock period being greater than two times tCLQV. 2. If the host controller supports it, compensate by delaying the sampling point to meet the tCLQV requirement of the client. Add a parameter 'rx_sampling_delay_ns' in struct spi_device to enable setting the clock to RX data delay for each SPI device, so drivers can check and act upon this timing requirement. Signed-off-by: Eberhard Stoll Signed-off-by: Frieder Schrempf --- include/linux/spi/spi.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index af7cfee7b8f60..4f8a0c28e1d46 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -181,6 +181,7 @@ extern void spi_transfer_cs_change_delay_exec(struct sp= i_message *msg, * @num_tx_lanes: Number of transmit lanes wired up. * @rx_lane_map: Map of peripheral lanes (index) to controller lanes (valu= e). * @num_rx_lanes: Number of receive lanes wired up. + * @rx_sampling_delay_ns: spi clk to spi rx data delay * * A @spi_device is used to interchange data between an SPI target device * (usually a discrete chip) and CPU memory. @@ -235,6 +236,8 @@ struct spi_device { struct spi_delay cs_setup; struct spi_delay cs_hold; struct spi_delay cs_inactive; + /* Transfer characteristics */ + u32 rx_sampling_delay_ns; /* clk to rx data delay */ =20 u8 chip_select[SPI_DEVICE_CS_CNT_MAX]; u8 num_chipselect; --=20 2.53.0 From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 F369B4EA39A; Tue, 3 Mar 2026 16:37:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555832; cv=none; b=RvuwCGEPtgoAfTQdsZWiX2A5rXJrEcKtpsrjVE7OsczYyndeUH+Qaqf4MSdtAPJTnTSnHd7Ugse0HmGxmzRNFHKhaW6vW6aNFgjArt1PSXUpGdw5Z8Zz/sC/Xd8rFPFrKQGmoh+P3r8v74for1Z3MLQ9KWi7TaCD1mn38rTivOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555832; c=relaxed/simple; bh=j4nNwMuSYM3rlSzI3HUw1M8Wo+a+90ViCYEEsEfbue0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=SLDK0sflGuw4xvHRVUwWtymh1MyP5dCJ3c6iIvWpuI2ln9ZTnW/dHG5zEvXfnBPTKUrfqa1yL8rDu7qemG9vbLP7+RUL/zPWF+LKhQJ6ygJM+tra2uTpZSLg7xzVO/A8qgHo4cpGsd4j4nnxBuujervPnFlmGy3qOG7cepydC2k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=iogRgar7; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="iogRgar7" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fHCcxgpay9q2fQOrVBGP3YNnaqk0n6N/P64jHvnyofU=; b=iogRgar7uYnzR+8yuvbkV8DUafaYRQNvYxN+zNlkjQ3TPx8eqQJFCMXCdMCYC/XoXFoaE9 xb5mjVj+s4g6TUia8H60bSjERiWF/W1QW1jmboQOFkqkvSsTUZtFmLV//q3r3kT7yEzKxr pIB9Cm19dIjCo0sKuNPK94ngayx04bn0IYug5oz9vAQ1be1ophIOEFrhVJcr7Nf3d8AufR lz9HlLvSrnCx7iDNH198HHxL2rL1io3gobl1zyl2TrOF0WpDyXRJNWXEx49AHNydhVqHyY soEUIZYdho4rZHPgYUmhkWWwcRvao2MyTkFeaBwImtf+A1RcmOKQZe04AgY1+g== Date: Tue, 03 Mar 2026 17:29:23 +0100 Subject: [PATCH RFC 2/7] mtd: spinand: Add support for clock to RX delay setting 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: <20260303-fsl-qspi-rx-sampling-delay-v1-2-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=2067; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=aPAds6dnQdXTjjQL53ALn43JPMhWJpGj9MuI9SkzCsc=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T9Pk3NsnP/6KlLPaWSkf85rzh4DYrLz4zsJf+3PFm PsT5/p1lLIwiHExyIopskjxW7y2NYv1kT9WHQUzh5UJZAgDF6cATOSuJCPDeacbgeJCr6uWmpQe nXZ7R+0TM/MDq+bwvDy190jwz2wVd0aG2RuXm7UH2HeJ/7Lecld28gytuEt8J20rrjaZ/45bmNb NAQA= X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Eberhard Stoll Add the configuration parameter to set the SPI clock to receive data delay parameter for SPI NAND devices. This parameter is often referenced as tCLQV in SPI NAND device data sheets. Signed-off-by: Eberhard Stoll Signed-off-by: Frieder Schrempf --- drivers/mtd/nand/spi/core.c | 1 + include/linux/mtd/spinand.h | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index 8aa3753aaaa1d..782a605018bc3 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c @@ -1594,6 +1594,7 @@ int spinand_match_and_init(struct spinand_device *spi= nand, spinand->user_otp =3D &table[i].user_otp; spinand->read_retries =3D table[i].read_retries; spinand->set_read_retry =3D table[i].set_read_retry; + spinand->spimem->spi->rx_sampling_delay_ns =3D table[i].rx_sampling_dela= y_ns; =20 /* I/O variants selection with single-spi SDR commands */ =20 diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index 6a024cf1c53ac..b76aaf0747962 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -568,6 +568,7 @@ enum spinand_bus_interface { * @model: model name * @devid: device ID * @flags: OR-ing of the SPINAND_XXX flags + * @rx_sampling_delay_ns: clock to rx data delay timing (tCLQV) * @memorg: memory organization * @eccreq: ECC requirements * @eccinfo: on-die ECC info @@ -592,6 +593,7 @@ struct spinand_info { const char *model; struct spinand_devid devid; u32 flags; + u32 rx_sampling_delay_ns; struct nand_memory_organization memorg; struct nand_ecc_props eccreq; struct spinand_ecc_info eccinfo; @@ -643,6 +645,9 @@ struct spinand_info { #define SPINAND_CONFIGURE_CHIP(__configure_chip) \ .configure_chip =3D __configure_chip =20 +#define SPINAND_RX_SAMPLING_DELAY(__delay) \ + .rx_sampling_delay_ns =3D __delay + #define SPINAND_CONT_READ(__set_cont_read) \ .set_cont_read =3D __set_cont_read =20 --=20 2.53.0 From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 293C24F7971; Tue, 3 Mar 2026 16:37:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555832; cv=none; b=P8EiOA+RHPJqsZ5UHvLfF1Mh3lT1KdzQWGa7A+epfBQHZdSjNU6QACVdi6iukFYHT9O821FenUqj4KjNBhNKmH+BWPpwZPDkyfGj9nFjsQr4j30ZTZvxT4gaFn5SkFgj7JVYExlf+A2lGBNFqOICFqAy7uahkDgkovVRyh2/XJk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555832; c=relaxed/simple; bh=3dxAEGYFIqAqyI+u7aPXsRpynh8jkjO6QlWcUu1EGzA=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=CKJnyof6WbfWwWqVVhkAHl4JVlj79nsCzedrXrKJEZ1e8dFt7tDvEFEqtCP9MSWCxbH4ZxWws4yxtAgFdTDaN2kUpniLYRvSx/dpax+iy1hEwp5Ld3X4gG9UgvOYO9qYdjhMUhum0fb2GhtS1RwR+qdarQcc0NrfJLF5+4sf3wI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=GtRhefMy; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="GtRhefMy" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2+skttbdyrA8Trf6AOYgOJnf/VuyEM70c9jGuM4BuX0=; b=GtRhefMyG/e2ydTOzhaZXw17Gur7lx/Fkm3pW3bz8MjGnlbMC7hACU2+3bysb15phxT/9p Azdb25sbCcYaVt+IurGic7rF7Z+ZO+jNEDmq4QVIssHtCiGhUW7PLvRLf6Q4CZfshVbNeP VEEbwm9kkatEU5/4PBow1jXnC3xxbrutzJeiRTDjqRCCS/bgdsls/iTyGGM2Sks74e275K NFB691brGGJHNkhPFN60eze4tixdZPcbR84wBVbWU8W5o/hZ65sneHg54NAmWXZlJkzeso zyJuTrfEMBkv5uaSypDL9EV8B+wq5B5fGIA4M1ImhUaInH3J4+ZHe1tZWs7Z5Q== Date: Tue, 03 Mar 2026 17:29:24 +0100 Subject: [PATCH RFC 3/7] mtd: spinand: winbond: Add RX sampling delay values 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: <20260303-fsl-qspi-rx-sampling-delay-v1-3-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=7571; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=1iBTtmlkMnqLSBaVo3JQ8I4m6OqPWy8zqvU+a/8yVOk=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T9NjlS+XJllv2L+kKMag/btF7VrLZTVzm9xzjx15k HZmXtyHjlIWBjEuBlkxRRYpfovXtmaxPvLHqqNg5rAygQxh4OIUgIk0JzEyHMnoWfN0gefloDMP teLMZKd5qH+qcpSS6xFn4gs/tLbWipHhhYD/Hnd/GYkqzeTDLZyzl6yZeSEpqyxR44e8rbV+YCY /AA== X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Eberhard Stoll Add tCLQV (Clock Low to Output Valid) parameter from datasheets for Winbond SPI NAND chips. This allows to let the drivers properly handle high sampling delays at high clock speeds. Signed-off-by: Eberhard Stoll Signed-off-by: Frieder Schrempf --- drivers/mtd/nand/spi/winbond.c | 42 ++++++++++++++++++++++++++++----------= ---- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c index 6dfd0dcc8ee7a..ec223e6d695a7 100644 --- a/drivers/mtd/nand/spi/winbond.c +++ b/drivers/mtd/nand/spi/winbond.c @@ -458,7 +458,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), + SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), + SPINAND_RX_SAMPLING_DELAY(6)), /* 1G-bit densities */ SPINAND_INFO("W25N01GV", /* 3.3V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x21), @@ -468,7 +469,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), + SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), + SPINAND_RX_SAMPLING_DELAY(7)), SPINAND_INFO("W25N01GW", /* 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x21), NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), @@ -477,7 +479,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL)), + SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), + SPINAND_RX_SAMPLING_DELAY(8)), SPINAND_INFO("W25N01JW", /* high-speed 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbc, 0x21), NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), @@ -487,7 +490,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&w25n01jw_ooblayout, NULL), - SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)), + SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg), + SPINAND_RX_SAMPLING_DELAY(6)), SPINAND_INFO("W25N01KV", /* 3.3V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xae, 0x21), NAND_MEMORG(1, 2048, 96, 64, 1024, 20, 1, 1, 1), @@ -496,7 +500,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status)), + SPINAND_ECCINFO(&w25n01kv_ooblayout, w25n02kv_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(7)), SPINAND_INFO("W35N01JW", /* 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdc, 0x21), NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 1, 1), @@ -507,7 +512,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { 0, SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops), SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL), - SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)), + SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg), + SPINAND_RX_SAMPLING_DELAY(6)), SPINAND_INFO("W35N02JW", /* 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x22), NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 2, 1), @@ -518,7 +524,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { 0, SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops), SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL), - SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)), + SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg), + SPINAND_RX_SAMPLING_DELAY(6)), SPINAND_INFO("W35N04JW", /* 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xdf, 0x23), NAND_MEMORG(1, 4096, 128, 64, 512, 10, 1, 4, 1), @@ -529,7 +536,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { 0, SPINAND_INFO_VENDOR_OPS(&winbond_w35_ops), SPINAND_ECCINFO(&w35n01jw_ooblayout, NULL), - SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg)), + SPINAND_CONFIGURE_CHIP(w35n0xjw_vcr_cfg), + SPINAND_RX_SAMPLING_DELAY(6)), /* 2G-bit densities */ SPINAND_INFO("W25M02GV", /* 2x1G-bit 3.3V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xab, 0x21), @@ -541,7 +549,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { 0, SPINAND_INFO_VENDOR_OPS(&winbond_w25_ops), SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), - SPINAND_SELECT_TARGET(w25m02gv_select_target)), + SPINAND_SELECT_TARGET(w25m02gv_select_target), + SPINAND_RX_SAMPLING_DELAY(7)), SPINAND_INFO("W25N02JW", /* high-speed 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xbf, 0x22), NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 2, 1), @@ -551,7 +560,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), - SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg)), + SPINAND_CONFIGURE_CHIP(w25n0xjw_hs_cfg), + SPINAND_RX_SAMPLING_DELAY(7)), SPINAND_INFO("W25N02KV", /* 3.3V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x22), NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), @@ -560,7 +570,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(7)), SPINAND_INFO("W25N02KW", /* 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x22), NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), @@ -569,7 +580,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), /* 4G-bit densities */ SPINAND_INFO("W25N04KV", /* 3.3V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xaa, 0x23), @@ -579,7 +591,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(7)), SPINAND_INFO("W25N04KW", /* 1.8V */ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xba, 0x23), NAND_MEMORG(1, 2048, 128, 64, 4096, 40, 1, 1, 1), @@ -588,7 +601,8 @@ static const struct spinand_info winbond_spinand_table[= ] =3D { &write_cache_variants, &update_cache_variants), 0, - SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status)), + SPINAND_ECCINFO(&w25n02kv_ooblayout, w25n02kv_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), }; =20 static int winbond_spinand_init(struct spinand_device *spinand) --=20 2.53.0 From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 1332B4F796D; Tue, 3 Mar 2026 16:37:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555833; cv=none; b=Mb6C5PfRmP1X57CuUrxYXSIzX5bkYcbQksn+7MnQKFUgKLA8B6KkCRwj8k+LygIdihuHd4p6jvuBjqXkSfTquUs6BgEyo9rdPrZtyqz47r69x5V0IgoEEdxrSf/JcrXBnA8sw7FVDkY0tZ3ebovYL++PZKGWhBOZOSm5FjmEJyo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555833; c=relaxed/simple; bh=u/mj6enjZVhQTntyAzChX6YGjn8caASUn1GrbNlmsRY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=OWUb6LhI9LxAxbzUVPMLvxDbm4pRSQlDoKhFWkHBwYB5XlyOGdHlWI9UtEircwXuWpd8ptaFbpvNjsLBT7peWGPWfy/LHHKRgcDDNNM0nirfQXSLtaqtR4Ga95BVme48d9TQ+ZJXCtccfomdlEaFlxwxxW+z77sL60jhY0RkL3M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=Pr5md9R9; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="Pr5md9R9" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n4V326l6j+UN/QUc6C6H7//EMmn8uimk+2KtK4YoNFE=; b=Pr5md9R9pPJa1rWI6bCDoa9yT9iO6BLgDEl6wtN5sjCoQ7OLktynCTxAUCIktNmBpgNor7 i+TCleRAdZL7RW2bTcXgs8AHpK5Kd3oW19FtJ4XfqzNXL/dSkPAMjRs6oeH4Lrp6FTqK1a dyBlxXfF8bfrPff26q+heIpY+BBhTmzq8kWv9tNyA6EsikQa7FlRZVuHCjpyB+ZqPWVH+S te15eCRncYbcisgU9Byr4U6t4auQo/m2SNpEyE3InOQGdeEcO1gHwEueU4Da/aNPpXTQ+6 4lFO+jYgGDqJ+euBpvKEQ6TyscBA2p6XFY6QQumVoMlPo3YYUtl5pD/Ld9EYXQ== Date: Tue, 03 Mar 2026 17:29:25 +0100 Subject: [PATCH RFC 4/7] mtd: spinand: toshiba: Add RX sampling delay values 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: <20260303-fsl-qspi-rx-sampling-delay-v1-4-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=8132; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=YS9m+8/VwL0xEzMaavaBPStGEta14s9GR3DcIa/S2T4=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T9NcLc6rK749PvtjZb989Iwvn8Qi3Is/T3yWyniqQ qiYR0Wto5SFQYyLQVZMkUWK3+K1rVmsj/yx6iiYOaxMIEMYuDgFYCJxNYwMJ9dMmLr/6m49VjXb h5senFN68zVswfXjGXPeuhU53zzq38TwP/fnogvK9kcnRx5w1RARLT3k/5WzVu3nmuDLvInmjm+ u8wEA X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Frieder Schrempf Add tCLQV (Clock Low to Output Valid) parameter from datasheets for Toshiba/Kioxia SPI NAND chips. This allows to let the drivers properly handle high sampling delays at high clock speeds. Signed-off-by: Frieder Schrempf --- drivers/mtd/nand/spi/toshiba.c | 48 +++++++++++++++++++++++++++-----------= ---- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c index ef649162ee680..7679f3acbae07 100644 --- a/drivers/mtd/nand/spi/toshiba.c +++ b/drivers/mtd/nand/spi/toshiba.c @@ -118,7 +118,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 3.3V 2Gb (1st generation) */ SPINAND_INFO("TC58CVG1S3HRAIG", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCB), @@ -129,7 +130,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), /* 3.3V 4Gb (1st generation) */ SPINAND_INFO("TC58CVG2S0HRAIG", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xCD), @@ -140,7 +142,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), /* 1.8V 1Gb (1st generation) */ SPINAND_INFO("TC58CYG0S3HRAIG", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xB2), @@ -151,7 +154,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), /* 1.8V 2Gb (1st generation) */ SPINAND_INFO("TC58CYG1S3HRAIG", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBB), @@ -162,7 +166,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), /* 1.8V 4Gb (1st generation) */ SPINAND_INFO("TC58CYG2S0HRAIG", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xBD), @@ -173,7 +178,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(8)), =20 /* * 2nd generation serial nand has HOLD_D which is equivalent to @@ -189,7 +195,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 3.3V 2Gb (2nd generation) */ SPINAND_INFO("TC58CVG1S3HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xEB), @@ -200,7 +207,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 3.3V 4Gb (2nd generation) */ SPINAND_INFO("TC58CVG2S0HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xED), @@ -211,7 +219,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 3.3V 8Gb (2nd generation) */ SPINAND_INFO("TH58CVG3S0HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xE4), @@ -222,7 +231,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 1.8V 1Gb (2nd generation) */ SPINAND_INFO("TC58CYG0S3HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD2), @@ -233,7 +243,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 1.8V 2Gb (2nd generation) */ SPINAND_INFO("TC58CYG1S3HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDB), @@ -244,7 +255,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 1.8V 4Gb (2nd generation) */ SPINAND_INFO("TC58CYG2S0HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xDD), @@ -255,7 +267,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 1.8V 8Gb (2nd generation) */ SPINAND_INFO("TH58CYG3S0HRAIJ", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xD4), @@ -266,7 +279,8 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), + SPINAND_RX_SAMPLING_DELAY(6)), /* 1.8V 1Gb (1st generation) */ SPINAND_INFO("TC58NYG0S3HBAI4", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA1), @@ -277,7 +291,7 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_variants), 0, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), /* 1.8V 4Gb (1st generation) */ SPINAND_INFO("TH58NYG2S3HBAI4", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xAC), @@ -288,7 +302,7 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), /* 1.8V 8Gb (1st generation) */ SPINAND_INFO("TH58NYG3S0HBAI6", SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0xA3), @@ -299,7 +313,7 @@ static const struct spinand_info toshiba_spinand_table[= ] =3D { &update_cache_x4_variants), SPINAND_HAS_QE_BIT, SPINAND_ECCINFO(&tx58cxgxsxraix_ooblayout, - tx58cxgxsxraix_ecc_get_status)), + tx58cxgxsxraix_ecc_get_status), }; =20 static const struct spinand_manufacturer_ops toshiba_spinand_manuf_ops =3D= { --=20 2.53.0 From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 1E52F4B8DE8; Tue, 3 Mar 2026 16:30:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555409; cv=none; b=AOKinxofrkunhvoHZFtNmbChOG1XfNyS9tw1E3lw0a/gn999/f3L/sNx6PSnMFLiz+IEOmI6xoD34ERJak7oTcnp40PQ9QKFGEE1/rxKdhEaJsus7UbcJgoJL4P/Y6rbt10q1o6qiQc52aZLJ0GuOKhr9pmi+H8z4t4kPxUZR/U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555409; c=relaxed/simple; bh=hhA/kekrHLYT7uqa4N13c7/4irrilRSPetcEkoldtSg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=oaOt8n6ttGexVTt6S3Iko1J6XSwG4Xxc8Zrh6ZI62QHcCnEHfTCLgDp9ig0KOBomENB96eZZrwUoklwSvdMfnlae7GLR7nJIJLuc5huyddoRIpH9ttJZgfoL04QRiWKWJjRP6e+T6TP+1Mh+GzdWhrJ9+ajytE8MstwqUoV0a8w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=Pp6Nc3Cp; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="Pp6Nc3Cp" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555397; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9cQhV2OiJ4DlfedZpH/R3rEHE14PIfUJqqPTZYp7QUU=; b=Pp6Nc3CpwIIn5asGLiOHOSd3GqtpgaZC1ICn9uIEQ91cLlYda6UlSL/49xQ271caQwXLlq hMpMUJrpIzQIvd2vpheuMxHuaVFcwBbtz+aVFlJYnYnlZo9JtVISZr6O/dsk9rs7zuDAQ4 WXYlPvXYaFP3RreuqBjioZqs/iUaS2cuArJ2RZoI9fYOtwfNXPfLHCgzxGLfSljp5+P24L VkQChDTAf21LAJE/5LKxGteLJbi0HkFyEET7o/l5Aiviam6y5RC1NNEv1862EkCtcRfzcR DM8tJCWBige64Ri4I+nqm7o3E1x/bU1miPv2RjGx13OQr/S20Nkb8XophmrYXA== Date: Tue, 03 Mar 2026 17:29:26 +0100 Subject: [PATCH RFC 5/7] spi: Add RX sampling point adjustment 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: <20260303-fsl-qspi-rx-sampling-delay-v1-5-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=5737; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=rxgCw1+pDnvqWT9mh/JJrKWrgFwnOW+QIMt7NVQjShA=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T1PNxMPcscmFyyfYnjr8/q6q+a90g/o38crb2qQ8d mxaWDi7o5SFQYyLQVZMkUWK3+K1rVmsj/yx6iiYOaxMIEMYuDgFYCJ96xkZlh+yqPtidcB03rWP ajO+6vJd0BOUEqnI/r9s4Q9/UanKs4wMd4uyjh3jXLjs4ctnxz0k1pSpc7WKLkh7zKlYdNoncFc UOwA= X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Frieder Schrempf Some SPI devices such as SPI NAND chips specify a clock-to-RX-sampling delay constraint, which means that for the data read from the device at a certain clock rate, we need to make sure that the point at which the data is sampled is correct. The default is to assume that the data can be sampled one half clock cycle after the triggering clock edge. For high clock rates, this can be too early. To check this we introduce a new core function spi_set_rx_sampling_point() and a handler set_rx_sampling_point() in the SPI controller. Controllers implementing set_rx_sampling_point() can calculate the sampling point delay using the helper spi_calc_rx_sampling_point() and store the value to set the appropriate registers during transfer. In case the controller capabilities are not sufficient to compensate the RX delay, spi_set_rx_sampling_point() returns a reduced clock rate value that is safe to use. This commit does not introduce generic logic for controllers that don't implement set_rx_sampling_point() in order to reduce the clock rate if the RX sampling delay requirement can not be met. Signed-off-by: Frieder Schrempf --- drivers/spi/spi.c | 73 +++++++++++++++++++++++++++++++++++++++++++++= ++++ include/linux/spi/spi.h | 8 ++++++ 2 files changed, 81 insertions(+) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 61f7bde8c7fbb..b039007ed430f 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -3988,6 +3988,77 @@ static int spi_set_cs_timing(struct spi_device *spi) return status; } =20 +/** + * spi_calc_rx_sampling_point - calculate RX sampling delay cycles + * @spi: the device that requires specific a RX sampling delay + * @freq: pointer to the clock frequency setpoint for the calculation. Thi= s gets + * altered to a reduced value if required. + * @max_delay_cycles: the upper limit of supported delay cycles + * @delay_cycles_per_clock_cycle: the ratio between delay cycles and + * master clock cycles + * + * This function takes in the rx_sampling_delay_ns value from the SPI devi= ce + * and the given clock frequency setpoint and calculates the required samp= ling + * delay cycles to meet the device's spec. It uses the given controller + * constraints and if those are exceeded, it adjusts the clock frequency + * setpoint to a lower value that is safe to be used. + * + * Return: calculated number of delay cycles + */ +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned i= nt *freq, + u16 max_delay_cycles, + u16 delay_cycles_per_clock_cycle) +{ + unsigned long long temp; + u16 delay_cycles; + + /* if sampling delay is zero, we assume the default sampling point can be= used */ + if (!spi->rx_sampling_delay_ns) + return 0; + + temp =3D *freq * delay_cycles_per_clock_cycle * spi->rx_sampling_delay_ns; + do_div(temp, 1000000000UL); + delay_cycles =3D temp; + + if (delay_cycles > max_delay_cycles) { + /* + * Reduce the clock to the point where the sampling delay requirement + * can be met. + */ + delay_cycles =3D max_delay_cycles; + temp =3D (1000000000UL * delay_cycles); + do_div(temp, spi->rx_sampling_delay_ns * delay_cycles_per_clock_cycle); + *freq =3D temp; + } + + dev_dbg(&spi->controller->dev, "calculated RX sampling point delay: %u cy= cle(s) at %lu KHz", delay_cycles, *freq / 1000); + + return delay_cycles; +} +EXPORT_SYMBOL_GPL(spi_calc_rx_sampling_point); + +/** + * spi_set_rx_sampling_point - set the RX sampling delay in the controller= driver + * @spi: the device that requires specific a RX sampling delay + * @freq: the clock frequency setpoint for the RX sampling delay calculati= on + * + * This function calls the set_rx_sampling_point() handle in the controller + * driver it is available. This makes sure that the controller uses the pr= oper + * RX sampling point adjustment. This function should be called whenever + * the devices rx_sampling_delay_ns or the currently used clock frequency + * changes. + * + * Return: adjusted clock frequency + */ +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned in= t freq) +{ + if (spi->controller->set_rx_sampling_point) + return spi->controller->set_rx_sampling_point(spi, spi->max_speed_hz); + + return freq; +} +EXPORT_SYMBOL_GPL(spi_set_rx_sampling_point); + /** * spi_setup - setup SPI mode and clock rate * @spi: the device whose settings are being modified @@ -4090,6 +4161,8 @@ int spi_setup(struct spi_device *spi) } } =20 + spi->max_speed_hz =3D spi_set_rx_sampling_point(spi, spi->max_speed_hz); + status =3D spi_set_cs_timing(spi); if (status) { mutex_unlock(&spi->controller->io_mutex); diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 4f8a0c28e1d46..f5be4f54d1424 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h @@ -685,6 +685,9 @@ struct spi_controller { */ int (*set_cs_timing)(struct spi_device *spi); =20 + /* set RX sampling point */ + unsigned int (*set_rx_sampling_point)(struct spi_device *spi, unsigned in= t freq); + /* * Bidirectional bulk transfers * @@ -1337,6 +1340,11 @@ extern int spi_setup(struct spi_device *spi); extern int spi_async(struct spi_device *spi, struct spi_message *message); extern int spi_target_abort(struct spi_device *spi); =20 +unsigned int spi_calc_rx_sampling_point(struct spi_device *spi, unsigned i= nt *freq, + u16 max_delay_cycles, + u16 delay_cycles_per_clock_cycle); +unsigned int spi_set_rx_sampling_point(struct spi_device *spi, unsigned in= t freq); + static inline size_t spi_max_message_size(struct spi_device *spi) { --=20 2.53.0 From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 1E4354B8DDC; Tue, 3 Mar 2026 16:30:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555409; cv=none; b=K49Xc+SeNb8kWLz47WTIrUTDNcHhVUgXfR8BI93gmrgmEaf7Q7WIWKYmoei0xMg3V2T4Xutd6ywuTqP6V9GIPncBNS0izCxp6SwQtqe133FkKJzSC4FU5A4XBLtyNlPB24z/X0srRgsZcV2iH7YCC2HUwVUGl4Boy86QDtQ6zM8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555409; c=relaxed/simple; bh=yL/xSbcaZwuUOu6gkmddpGfg1RNwAiNrd9YKVZaYdN4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iA21YfKT7j6yb2ptsSOvEN7trQo+qPavhqlHVB5qA3otboVWGsVPSNZo3DoCd5ic6SGipXBYoPUv/8hc7BzaprcWaC6Zd24zZwYdQ9UcmCM30C8VqygEBnNUPwjNTRPQrsfT5TxsMsuAjJxZ5q85VBRUryaPPv572tzQA0nDgrw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=uh8WI7mG; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="uh8WI7mG" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555398; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=0jEzN+ZbuPiy2X43ltzsOH8xhPtq3QTkuVtmlsPHM9I=; b=uh8WI7mG1o6aI/mjEFxWTylQAQHFKTSjYQ96O6N7o74Oo8x/T7qAALbKOm4Fn3qWQ3z3EA dfVXtmnGsKr6kRsxyhIL07ctqko0sq8dVVW3l6sIZctd0O0VuTEU6WYjKPngwiGvhQfJyc ijO04WpWy1+rMVySo93grJ5edJATcvU8CzFTfZyhog53+knXMm4/buPCNyPZ6Nh2T1DvyM 28h89o48kWGG7Mffxn07dXfFk/4jmawRLZ5NLEkNRxDdZzXkoz3mD8bvv9XDJUEuZSdFPa qXa73xU0NW8g8Ot8i/88+gvV2IJSco/Sujdvnq7X0T4QzjyAsjkCzv3NwbemfQ== Date: Tue, 03 Mar 2026 17:29:27 +0100 Subject: [PATCH RFC 6/7] spi: spi-mem: Call spi_set_rx_sampling_point() for each op 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: <20260303-fsl-qspi-rx-sampling-delay-v1-6-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=789; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=LwNCpqII5STHerKJFGgtW51z+gveZ5FdSLV1sPEkDaQ=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T1P05w+c/q8f1HEL/z9e/rvzbY+NyWeGXpP/6wQ/3 bgsUW7ZUcrCIMbFICumyCLFb/Ha1izWR/5YdRTMHFYmkCEMXJwCMJHcOIb/HoluqStOqzE3b4qy +nDB45R3uEPozJs2q9cbHDpUoaH4lOGvoJtN7NmJf64wx6T4qTF9z9qRK2F/MEEjoXFpik9k1EU WAA== X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Frieder Schrempf With clock rates changing on a per-op basis, we need to make sure that we meet the RX sampling point delay constraint of the underlying SPI chip. Signed-off-by: Frieder Schrempf --- drivers/spi/spi-mem.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index a09371a075d2e..6b8bee7d6f5e3 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c @@ -589,6 +589,8 @@ void spi_mem_adjust_op_freq(struct spi_mem *mem, struct= spi_mem_op *op) { if (!op->max_freq || op->max_freq > mem->spi->max_speed_hz) op->max_freq =3D mem->spi->max_speed_hz; + + op->max_freq =3D spi_set_rx_sampling_point(mem->spi, op->max_freq); } EXPORT_SYMBOL_GPL(spi_mem_adjust_op_freq); =20 --=20 2.53.0 From nobody Thu Apr 9 18:00:41 2026 Received: from mail.fris.de (mail.fris.de [116.203.77.234]) (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 1E3A447ECCD; Tue, 3 Mar 2026 16:30:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=116.203.77.234 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555409; cv=none; b=SkeURJFUpoZyozQVno92Ekg5YoGkgSJdtjEJSaB5U3JSq8dhYncA2jOnBXVkkJ2B/uG2H73EvOmd+WlDbP8JGqEAoRFmq66OhQ7i8H5StuMqYhGON/5Jg8ApoLOiAiJgl765WCssThRA6XBdr3g9IvLV9Kx//EkubHCSZQ0twGw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772555409; c=relaxed/simple; bh=TbOHeK/mg1j4nM9RQJdsa7wWMdwNADEaugCoRnd5JV8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B+7IuxEQTPPIgqCiIog5aaRQMXFq4CS49UelBteuc3DBa+a4kpHsf7HG31GduCZheHY2ilFgSR6uU0By92/MP6ZKAswazjVjrvLy1iLYlxBmA5U6PDuouzLRtK3U+HBQzzdbvNWhY7AnGavdqwDF4SZrIisy1+987d2pSVlrKro= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de; spf=pass smtp.mailfrom=fris.de; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b=La7AI87e; arc=none smtp.client-ip=116.203.77.234 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=fris.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=fris.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=fris.de header.i=@fris.de header.b="La7AI87e" From: Frieder Schrempf DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fris.de; s=mail; t=1772555398; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5uNHkFScFKLbXXB9ZwjM5ltQMNCVgdS4C7r79FlbEvY=; b=La7AI87ecgOu8O/+k2VAc9NRK2hZnZsq1JVHmj7hZoSUH95NG247PgJy2ySiuNxFZUmCYe kFAASFxOzCX0yNsmsrrIbgoZpntAUWIZbs8+/D1LxPeNDsycyY0Yo+gkil71TPGxWMb8Tx f4y1WsN4g0tvGcs/6hefIY7GriYoosj5x+ipJaNXj7NpJkUyMt/hJrEB7Hs8sxe2lwjx/D DLxcSCHdXj/xa2yKe4how+3cFqrE5Qge/XyC89+49S/GNqIHsoQIFUO2WFdy2qQ0+Jo15Q u9FwUU7F6Q2dGX+yvbYHLURwD14iWkz25V4oNA32l510mZ+4EM3j/R2U3GMbqQ== Date: Tue, 03 Mar 2026 17:29:28 +0100 Subject: [PATCH RFC 7/7] spi: spi-fsl-qspi: Add support for RX data sampling point adjustment 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: <20260303-fsl-qspi-rx-sampling-delay-v1-7-9326bbc492d6@kontron.de> References: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> In-Reply-To: <20260303-fsl-qspi-rx-sampling-delay-v1-0-9326bbc492d6@kontron.de> To: Mark Brown , Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Han Xu Cc: Eberhard Stoll , Frieder Schrempf , Tudor Ambarus , Pratyush Yadav , Michael Walle , linux-spi@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, imx@lists.linux.dev X-Developer-Signature: v=1; a=openpgp-sha256; l=5107; i=frieder.schrempf@kontron.de; h=from:subject:message-id; bh=1Xfa4uE+iSkew2K7toE6BY8+v+eWmZiraSEE7IGgrhI=; b=owGbwMvMwCWWWSatKlDTJMZ4Wi2JIXM5T9ObmRvrL3mzrOYpOaxq/eb0/v2PmSJTZM6K+DMc+ dra/eF3RykLgxgXg6yYIosUv8VrW7NYH/lj1VEwc1iZQIYwcHEKwETEAhgZDk7ac717Ea/JleyD J4yvJ3++ZXz+1u2fcbJTgnKll3DKuzP8L3pTvcl+wtWmt3z/015Xr0ideNdLtIdxYWzSmY09dg1 BPAA= X-Developer-Key: i=frieder.schrempf@kontron.de; a=openpgp; fpr=1A0F38EB3D365D4C1FC67B5A69761B25107C8216 From: Eberhard Stoll This QSPI controller supports shifting the RX data sampling point to compensate line or SPI device response delays. This enables fast SPI data transfers even for devices which have a significant delay in the RX data stream. Implement the set_rx_sampling_point() handler to: 1. check if the sampling point needs to be adjusted 2. prepare a value for the SDRSMP bits in the SMPR register and save it 3. reduce the clock rate if sampling point adjustment is not enough During operation the SDRSMP bits in the SMPR register get updated with the calculated value. Signed-off-by: Eberhard Stoll Signed-off-by: Frieder Schrempf --- drivers/spi/spi-fsl-qspi.c | 80 ++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 80 insertions(+) diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c index a223b4bc6e637..7021db144f84b 100644 --- a/drivers/spi/spi-fsl-qspi.c +++ b/drivers/spi/spi-fsl-qspi.c @@ -88,6 +88,7 @@ =20 #define QUADSPI_SMPR 0x108 #define QUADSPI_SMPR_DDRSMP_MASK GENMASK(18, 16) +#define QUADSPI_SMPR_SDRSMP(x) ((x) << 5) #define QUADSPI_SMPR_FSDLY_MASK BIT(6) #define QUADSPI_SMPR_FSPHS_MASK BIT(5) #define QUADSPI_SMPR_HSENA_MASK BIT(0) @@ -290,6 +291,16 @@ struct fsl_qspi { struct device *dev; int selected; u32 memmap_phy; + u32 smpr; +}; + +#define RX_SAMPLING_MAX_DELAY_CYCLES 3 +#define RX_SAMPLING_DELAY_CYCLES_PER_CLOCK_CYCLE 2 + +struct fsl_qspi_chip_data { + u8 sdrsmp; + u32 rx_sampling_delay_ns; + unsigned int rate; }; =20 static bool needs_swap_endian(struct fsl_qspi *q) @@ -545,6 +556,27 @@ static void fsl_qspi_invalidate(struct fsl_qspi *q) qspi_writel(q, reg, q->iobase + QUADSPI_MCR); } =20 +static void fsl_qspi_update_rx_sampling_delay(struct fsl_qspi *q, u32 sdrs= mp) +{ + void __iomem *base =3D q->iobase; + u32 mcr, smpr =3D QUADSPI_SMPR_SDRSMP(sdrsmp); + + /* skip if requested value matches cached value */ + if (q->smpr =3D=3D smpr) + return; + + /* Disable the module */ + mcr =3D qspi_readl(q, base + QUADSPI_MCR); + qspi_writel(q, mcr | QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR); + + qspi_writel(q, smpr, base + QUADSPI_SMPR); + + /* Enable the module */ + qspi_writel(q, mcr & ~QUADSPI_MCR_MDIS_MASK, base + QUADSPI_MCR); + + q->smpr =3D smpr; +} + static void fsl_qspi_select_mem(struct fsl_qspi *q, struct spi_device *spi, const struct spi_mem_op *op) { @@ -668,6 +700,7 @@ static int fsl_qspi_readl_poll_tout(struct fsl_qspi *q,= void __iomem *base, static int fsl_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *= op) { struct fsl_qspi *q =3D spi_controller_get_devdata(mem->spi->controller); + struct fsl_qspi_chip_data *chip =3D spi_get_ctldata(mem->spi); void __iomem *base =3D q->iobase; u32 addr_offset =3D 0; int err =3D 0; @@ -679,6 +712,8 @@ static int fsl_qspi_exec_op(struct spi_mem *mem, const = struct spi_mem_op *op) fsl_qspi_readl_poll_tout(q, base + QUADSPI_SR, (QUADSPI_SR_IP_ACC_MASK | QUADSPI_SR_AHB_ACC_MASK), 10, 1000); =20 + fsl_qspi_update_rx_sampling_delay(q, chip->sdrsmp); + fsl_qspi_select_mem(q, mem->spi, op); =20 if (needs_amba_base_offset(q)) @@ -871,6 +906,28 @@ static const struct spi_controller_mem_caps fsl_qspi_m= em_caps =3D { .per_op_freq =3D true, }; =20 +static int fsl_qspi_setup_device(struct spi_device *spi) +{ + struct fsl_qspi_chip_data *chip =3D spi_get_ctldata(spi); + + if (!chip) { + chip =3D kzalloc_obj(*chip, GFP_KERNEL); + if (!chip) + return -ENOMEM; + spi_set_ctldata(spi, chip); + } + + return 0; +} + +static void fsl_qspi_cleanup_device(struct spi_device *spi) +{ + struct fsl_qspi_chip_data *chip =3D spi_get_ctldata(spi); + + kfree(chip); + spi_set_ctldata(spi, NULL); +} + static void fsl_qspi_disable(void *data) { struct fsl_qspi *q =3D data; @@ -891,6 +948,25 @@ static void fsl_qspi_cleanup(void *data) mutex_destroy(&q->lock); } =20 +static unsigned int fsl_qspi_set_rx_sampling_point(struct spi_device *spi,= unsigned int freq) +{ + struct fsl_qspi_chip_data *chip =3D spi_get_ctldata(spi); + + /* skip calculation if input clock rate and sampling delay did not change= */ + if (spi->rx_sampling_delay_ns =3D=3D chip->rx_sampling_delay_ns && + freq =3D=3D chip->rate) + return freq; + + chip->rate =3D freq; + chip->rx_sampling_delay_ns =3D spi->rx_sampling_delay_ns; + + chip->sdrsmp =3D spi_calc_rx_sampling_point(spi, &freq, + RX_SAMPLING_MAX_DELAY_CYCLES, + RX_SAMPLING_DELAY_CYCLES_PER_CLOCK_CYCLE); + + return freq; +} + static int fsl_qspi_probe(struct platform_device *pdev) { struct spi_controller *ctlr; @@ -915,6 +991,10 @@ static int fsl_qspi_probe(struct platform_device *pdev) =20 platform_set_drvdata(pdev, q); =20 + ctlr->setup =3D fsl_qspi_setup_device; + ctlr->cleanup =3D fsl_qspi_cleanup_device; + ctlr->set_rx_sampling_point =3D fsl_qspi_set_rx_sampling_point; + /* find the resources */ q->iobase =3D devm_platform_ioremap_resource_byname(pdev, "QuadSPI"); if (IS_ERR(q->iobase)) --=20 2.53.0