From: Santhosh Kumar K <s-k6@ti.com>
To: <broonie@kernel.org>, <robh@kernel.org>, <krzk+dt@kernel.org>,
<conor+dt@kernel.org>, <miquel.raynal@bootlin.com>,
<richard@nod.at>, <vigneshr@ti.com>, <pratyush@kernel.org>,
<mwalle@kernel.org>, <takahiro.kuwano@infineon.com>
Cc: <linux-spi@vger.kernel.org>, <devicetree@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <linux-mtd@lists.infradead.org>,
<praneeth@ti.com>, <u-kumar1@ti.com>, <a-dutta@ti.com>,
<s-k6@ti.com>
Subject: [PATCH v4 00/16] spi: cadence-quadspi: add PHY tuning support
Date: Thu, 18 Jun 2026 13:07:09 +0530 [thread overview]
Message-ID: <20260618073725.84733-1-s-k6@ti.com> (raw)
This series implements PHY tuning support for the Cadence QSPI controller
to enable reliable high-speed operations. Without PHY tuning, controllers
use conservative timing that limits performance. PHY tuning calibrates
RX/TX delay lines to find optimal data capture timing windows, enabling
operation up to the controller's maximum frequency.
Background:
High-speed SPI memory controllers require precise timing calibration for
reliable operation. At higher frequencies, board-to-board variations make
fixed timing parameters inadequate. The Cadence QSPI controller includes
a PHY interface with programmable delay lines (0-127 taps) for RX and TX
paths, but these require runtime calibration to find the valid timing
window.
Approach:
Add SDR/DDR PHY tuning algorithms for the Cadence controller:
SDR Mode Tuning (1D search):
- Searches for two consecutive valid RX delay windows
- Selects the larger window and uses its midpoint for maximum margin
- TX delay fixed at maximum (127) as it's less critical in SDR
DDR Mode Tuning (2D search):
- Finds RX boundaries (rxlow/rxhigh) using TX window sweeps
- Finds TX boundaries (txlow/txhigh) at fixed RX positions
- Defines valid region corners and detects gaps via binary search
- Applies temperature compensation for optimal point selection
- Handles single or dual passing regions with different strategies
Patch description:
Infrastructure (1-5):
- Patch 1: Add spi-max-post-config-frequency to describe maximum
frequency achievable post controller configuration
- Patch 2: Add spi-phy-pattern-partition phandle for
NOR flash PHY tuning pattern location
- Patch 3: Parse spi-max-post-config-frequency in spi.c; adds
spi_device.post_config_max_speed_hz (0 when not set
keeping all existing DT fully compatible)
- Patch 4: Extend spi_mem_adjust_op_freq() with a bypass: if
op->max_freq equals post_config_max_speed_hz, return
immediately leaving op->max_freq unchanged. All other
ops are capped to max_speed_hz
- Patch 5: Add execute_tuning callback to spi_controller_mem_ops and
spi_mem_execute_tuning() wrapper in SPI-MEM core
Cadence QSPI Implementation (6-12):
- Patch 6: Move cqspi_readdata_capture() earlier (preparatory)
- Patch 7: Add DQS bit to cqspi_readdata_capture() (preparatory)
- Patch 8: Add complete PHY tuning support: DLL management, pattern
verification (NOR via spi-phy-pattern-partition phandle,
NAND via write-to-cache), SDR 1D and DDR 2D search
algorithms with temperature compensation, AM654-specific
execute_tuning entry point;
- Patch 9: Reject 2-byte-address DDR operations via a new
CQSPI_NO_2BYTE_ADDR_PHY_DDR quirk flag to work around
AM654 OSPI erratum i2383
- Patch 10: Refactor direct read path for PHY support (preparatory)
- Patch 11: Enable PHY for direct reads, split the transfer into an
unaligned head, a 16-byte-aligned middle section with PHY
active, and an unaligned tail
- Patch 12: Enable PHY for indirect writes of at least
CQSPI_PHY_MIN_INDIRECT_WRITE_LEN bytes
MTD core (13-16):
- Patch 13: Extract spinand_select_op_variant() into a shared helper
spinand_op_find_best() with a skip_mask
- Patch 14: Negotiate optimal PHY operating point before dirmap
creation
- Patch 15: Extract spi_nor_spimem_get_read_op() helper (preparatory)
- Patch 16: Execute PHY tuning in spi_nor_probe() before creating
dirmaps
Testing:
This series was tested on TI's
AM62Ax SK with OSPI NAND flash and
AM62Px SK with OSPI NOR flash:
Read throughput:
|----------------------------------------|
| | non-PHY | PHY |
|----------------------------------------|
| OSPI NOR (8D) | 37.5 MB/s | 216 MB/s |
|----------------------------------------|
| OSPI NAND (8S) | 9.2 MB/s | 35.1 MB/s |
|----------------------------------------|
Write throughput:
|----------------------------------------|
| | non-PHY | PHY |
|----------------------------------------|
| OSPI NAND (8S) | 6 MB/s | 9.2 MB/s |
|----------------------------------------|
Test log: https://gist.github.com/santhosh21/fe98754e52970287eb9011154100b62d
Repo: https://github.com/santhosh21/linux/commits/phy_tuning_v4/
Changes in v4:
- Add spi-max-post-config-frequency instead of extending spi-max-frequency
to accept an optional second value
- Replace spi_mem_apply_base_freq_cap() with spi_mem_adjust_op_freq() extension
- For SPI NOR/NAND, execute PHY tuning before the dirmap creation
- For SPI NAND, execute PHY tuning across all operation variants available,
perform duration comparison, and select the best resulting variant
by taking controller-specific restrictions into account
- Move i2383 check from cqspi_supports_mem_op() to cqspi_am654_ospi_execute_tuning()
- Rename cdns,phy-pattern-partition to spi-phy-pattern-partition,
cqspi_phy_enable to cqspi_tune_phy and f_pdata->use_phy to use_tuned_phy
- Remove redundant spi-max-frequency parsing in driver cqspi_of_get_flash_pdata()
- Extract DMA refactoring into a preparatory patch
- Rebase on v7.1
- Collect tags from Miquel
- Link to v3: https://lore.kernel.org/linux-spi/20260527175527.2247679-1-s-k6@ti.com/
Changes in v3:
- Drop spi-has-dqs DT property; DQS is now enabled automatically when
the selected read operation uses DDR signalling (dtr flags in the op)
- Extend spi-max-frequency to accept an optional second value forming a
[base-freq, max-freq] pair; the presence of two values signals PHY
tuning intent and encodes both the conservative base speed and the
calibration target in one property
- Add base_speed_hz to struct spi_device (spi.c/spi.h) and parse the
two-element array there; single-value DT is fully backward-compatible
- Move frequency enforcement from the cadence driver to core: new
spi_mem_apply_base_freq_cap() called from spi_mem_exec_op() replaces
the per-driver cqspi_op_matches_tuned() and non_phy_clk_rate field
- Propagate the tuned max_freq to dirmap op templates after
execute_tuning() succeeds; store persistent op templates in
spi_nor.max_read_op and spinand.{max_read,max_write}_op so the
frequency writeback survives across the probe call
- Replace NOR pattern partition lookup by name with a
cdns,phy-pattern-partition DT phandle pointing directly to the
partition node
- Add CQSPI_NO_2BYTE_ADDR_PHY_DDR quirk and reject 2-byte-address DDR
ops in cqspi_supports_mem_op() to work around AM654 erratum i2383
- Remove RFC tag
- Rebase on v7.1-rc5
- Collect tags from Miquel
- Link to v2: https://lore.kernel.org/linux-spi/20260113141617.1905039-1-s-k6@ti.com/
Changes in v2:
- Restructure the .execute_tuning() call from spi-mem clients instead
of mtdcore with best read_op and write_op (optional) passed
- Add compatible-specific .execute_tuning() call which can be called by
spi_mem_execute_tuning() if exists
- Handle tuning requirement check by controller instead of spi-mem
clients
- Add support to write the phy_pattern to cache if relevant write_op
is passed or get the partition offset which contains the phy_pattern
- Add tuning algorithm for DDR mode
- Add support for DQS
- Restrict PHY frequency to tuned operations
- Link to v1: https://lore.kernel.org/linux-spi/20250811193219.731851-1-s-k6@ti.com/
Signed-off-by: Santhosh Kumar K <s-k6@ti.com>
Pratyush Yadav (1):
mtd: spi-nor: extract read op template construction into helper
Santhosh Kumar K (15):
spi: dt-bindings: add spi-max-post-config-frequency property
spi: dt-bindings: add spi-phy-pattern-partition property
spi: parse spi-max-post-config-frequency into post_config_max_speed_hz
spi: spi-mem: teach spi_mem_adjust_op_freq() about post-config ops
spi: spi-mem: add execute_tuning callback and spi_mem_execute_tuning()
spi: cadence-quadspi: move cqspi_readdata_capture earlier
spi: cadence-quadspi: add DQS support to read data capture
spi: cadence-quadspi: add PHY tuning support
spi: cadence-quadspi: skip DDR PHY tuning for 2-byte-address ops
(i2383)
spi: cadence-quadspi: refactor direct read path for PHY support
spi: cadence-quadspi: enable PHY for direct reads
spi: cadence-quadspi: enable PHY for indirect writes
mtd: spinand: extract variant ranking logic into
spinand_op_find_best()
mtd: spinand: negotiate optimal PHY operating point before dirmap
creation
mtd: spi-nor: run PHY tuning after init and update dirmap frequency
.../bindings/spi/cdns,qspi-nor.yaml | 19 +
.../bindings/spi/spi-peripheral-props.yaml | 13 +
drivers/mtd/nand/spi/core.c | 246 +-
drivers/mtd/spi-nor/core.c | 80 +-
drivers/spi/spi-cadence-quadspi.c | 2265 +++++++++++++++--
drivers/spi/spi-mem.c | 40 +
drivers/spi/spi.c | 2 +
include/linux/mtd/spi-nor.h | 3 +
include/linux/mtd/spinand.h | 11 +
include/linux/spi/spi-mem.h | 14 +
include/linux/spi/spi.h | 3 +
11 files changed, 2493 insertions(+), 203 deletions(-)
--
2.34.1
next reply other threads:[~2026-06-18 7:38 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-18 7:37 Santhosh Kumar K [this message]
2026-06-18 7:37 ` [PATCH v4 01/16] spi: dt-bindings: add spi-max-post-config-frequency property Santhosh Kumar K
2026-06-18 7:37 ` [PATCH v4 02/16] spi: dt-bindings: add spi-phy-pattern-partition property Santhosh Kumar K
2026-06-18 7:50 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 03/16] spi: parse spi-max-post-config-frequency into post_config_max_speed_hz Santhosh Kumar K
2026-06-18 7:54 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 04/16] spi: spi-mem: teach spi_mem_adjust_op_freq() about post-config ops Santhosh Kumar K
2026-06-18 8:02 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 05/16] spi: spi-mem: add execute_tuning callback and spi_mem_execute_tuning() Santhosh Kumar K
2026-06-18 7:57 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 06/16] spi: cadence-quadspi: move cqspi_readdata_capture earlier Santhosh Kumar K
2026-06-18 7:48 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 07/16] spi: cadence-quadspi: add DQS support to read data capture Santhosh Kumar K
2026-06-18 7:37 ` [PATCH v4 08/16] spi: cadence-quadspi: add PHY tuning support Santhosh Kumar K
2026-06-18 7:59 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 09/16] spi: cadence-quadspi: skip DDR PHY tuning for 2-byte-address ops (i2383) Santhosh Kumar K
2026-06-18 8:04 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 10/16] spi: cadence-quadspi: refactor direct read path for PHY support Santhosh Kumar K
2026-06-18 7:57 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 11/16] spi: cadence-quadspi: enable PHY for direct reads Santhosh Kumar K
2026-06-18 7:53 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 12/16] spi: cadence-quadspi: enable PHY for indirect writes Santhosh Kumar K
2026-06-18 7:53 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 13/16] mtd: spinand: extract variant ranking logic into spinand_op_find_best() Santhosh Kumar K
2026-06-18 7:37 ` [PATCH v4 14/16] mtd: spinand: negotiate optimal PHY operating point before dirmap creation Santhosh Kumar K
2026-06-18 8:02 ` sashiko-bot
2026-06-18 7:37 ` [PATCH v4 15/16] mtd: spi-nor: extract read op template construction into helper Santhosh Kumar K
2026-06-18 7:37 ` [PATCH v4 16/16] mtd: spi-nor: run PHY tuning after init and update dirmap frequency Santhosh Kumar K
2026-06-18 8:01 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260618073725.84733-1-s-k6@ti.com \
--to=s-k6@ti.com \
--cc=a-dutta@ti.com \
--cc=broonie@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=krzk+dt@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=linux-spi@vger.kernel.org \
--cc=miquel.raynal@bootlin.com \
--cc=mwalle@kernel.org \
--cc=praneeth@ti.com \
--cc=pratyush@kernel.org \
--cc=richard@nod.at \
--cc=robh@kernel.org \
--cc=takahiro.kuwano@infineon.com \
--cc=u-kumar1@ti.com \
--cc=vigneshr@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox