From: Moteen Shah <m-shah@ti.com>
To: Santhosh Kumar K <s-k6@ti.com>, <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>, <sebin.francis@ti.com>, <u-kumar1@ti.com>,
<a-dutta@ti.com>
Subject: Re: [PATCH v10 00/19] spi: cadence-quadspi: add PHY tuning support
Date: Thu, 29 Oct 2026 10:19:18 +0530 [thread overview]
Message-ID: <87ad0389-983d-4fd9-8c4b-0daa108a040b@ti.com> (raw)
In-Reply-To: <20260929063529.1235417-1-s-k6@ti.com>
Hey Santosh,
On 29/09/26 12:05, Santhosh Kumar K wrote:
> 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.
I tested the series on J784s4 and J721s2.
For the whole series:
Reviewed and Tested-by: Moteen Shah <m-shah@ti.com>
Regards,
Moteen
> 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-hz 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-hz 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. Also require per_op_freq
> controller capability for post-config ops in
> spi_mem_default_supports_op()
> - Patch 5: Add execute_tuning callback to spi_controller_mem_ops and
> spi_mem_execute_tuning() wrapper in SPI-MEM core;
> serialises access via spi_mem_access_start/end and
> rejects GPIO chip selects
>
> Cadence QSPI Implementation (6-14):
> - 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_PHY_TUNING_WITH_ODDR_2B_ADDR 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 at the calibrated frequency
> when both transfer boundaries are 16-byte aligned,
> falling back to non-PHY DMA otherwise; also reprograms
> DLL on chip-select switch when two devices have
> different calibrated settings
> - Patch 12: Enable PHY for indirect writes of at least
> CQSPI_PHY_MIN_INDIRECT_WRITE_LEN bytes
> - Patch 13: Reprogram per-device CS timing on any chip-select switch
> - Patch 14: Reprogram the PHY DLL (master config and RX/TX taps) on
> runtime resume, since the DLL loses its lock when the
> OSPI controller is power-gated
>
> MTD core (15-19):
> - Patch 15: Extract spinand_select_op_variant() into a shared helper
> spinand_op_find_best_variant() with a skip_mask
> - Patch 16: Negotiate optimal controller operating point before dirmap
> creation; iterate all read variants in performance order
> across ODTR and SSDR interfaces; re-pair cont_read_cache after
> PHY tuning via protocol-shape matching
> - Patch 17: Extract spi_nor_spimem_get_read_op() helper (preparatory)
> - Patch 18: Execute controller optimization in spi_nor_probe() before
> creating dirmaps
> - Patch 19: Reset max_read_op frequency for security register reads
>
> 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 | 218 MB/s |
> |----------------------------------------|
> | OSPI NAND (8S) | 9.2 MB/s | 35.6 MB/s |
> |----------------------------------------|
>
> Write throughput:
> |----------------------------------------|
> | | non-PHY | PHY |
> |----------------------------------------|
> | OSPI NAND (8S) | 6 MB/s | 9.2 MB/s |
> |----------------------------------------|
>
> Test log: https://gist.github.com/santhosh21/e1b5c7cc5cad4acb94b67e826d971ab9
> Repo: https://github.com/santhosh21/linux/commits/phy_tuning_v10
>
> Changes in v10:
> - Gate the frequency spi_nor_spimem_get_read_op() propagates on matching
> protocol shape, and add a patch resetting max_read_op.max_freq around
> the security-register read override
> - Split cqspi_tune_phy() into cqspi_tune_phy_read()/cqspi_tune_phy_write()
> so PHY_PIPELINE is never set on writes, per AM65x erratum i2189
> - Fix spinand_try_ranked_variant() to only clear, never set
> cont_read_possible on ranked-variant fallback
> - Fix other, smaller correctness issues raised by sashiko-bot
> - Collect tag from Miquel
> - Link to v9: https://lore.kernel.org/linux-spi/20260825171737.776052-1-s-k6@ti.com/
>
> Changes in v9:
> - Fix off-by-one in DDR PHY TX search loops
> - Fix cqspi_tune_phy() to unconditionally execute the disable path
> and restore CQSPI_REG_READCAPTURE on enable error rollback
> - Fix other, smaller correctness issues raised by sashiko-bot
> - Link to v8: https://lore.kernel.org/linux-spi/20260821114822.4040338-1-s-k6@ti.com/
>
> Changes in v8:
> - Re-pair cont_read_cache with the selected read_cache variant via
> protocol-shape matching after PHY tuning instead of unconditionally
> diabling continuous read
> - Rebase on v7.2
> - Collect tag from Miquel
> - Link to v7: https://lore.kernel.org/linux-spi/20260811183313.1550425-1-s-k6@ti.com/
>
> Changes in v7:
> - Serialise spi_mem_execute_tuning() with spi_mem_access_start/end and
> reject GPIO chip-select configurations
> - Fix cqspi_phy_apply_setting() to also write the calibrated
> read_delay to CQSPI_REG_READCAPTURE, previously software-only
> - Use local op copies for pattern write/verify instead of mutating
> the caller's op templates in place
> - Fix the READCAPTURE bypass bit in cqspi_tune_phy() to match the
> value validated during calibration instead of being hardcoded
> - Enable PHY before starting the indirect-write state machine instead
> of after; the old order was a guaranteed deadlock
> - Add a new patch to reprogram the PHY DLL on runtime resume
> - Fix continuous-read and ODTR/SSDR template handling on ranked
> fallback in spinand_try_ranked_variant(), preventing data
> corruption after a fallback
> - Fix other, smaller correctness issues raised by sashiko-bot
> - Rebase on v7.2-rc7
> - Link to v6: https://lore.kernel.org/linux-spi/20260723110219.3180747-1-s-k6@ti.com/
>
> Changes in v6:
> - Add maxItems to spi-max-post-config-frequency-hz property
> - Rebase on v7.2-rc4
> - Collect tag from Krzysztof
> - Link to v5: https://lore.kernel.org/linux-spi/20260717185116.2065505-1-s-k6@ti.com/
>
> Changes in v5:
> - Rename spi-max-post-config-frequency to spi-max-post-config-frequency-hz
> per DT schema unit suffix convention
> - Rename CQSPI_NO_2BYTE_ADDR_PHY_DDR quirk to
> CQSPI_NO_PHY_TUNING_WITH_ODDR_2B_ADDR for clarity
> - Rename SPI NAND identifiers to remove PHY-specific terminology:
> spinand_configure_phy() -> spinand_optimize_controller()
> spinand_try_phy_ranked() -> spinand_try_ranked_variant()
> spinand_reset_max_ops() -> spinand_reset_max_freq_ops()
> spinand_op_find_best() -> spinand_op_find_best_variant()
> phy_read_variants (field) -> all_read_variants
> - Replace bool odtr parameter with enum spinand_bus_interface iface in
> spinand_op_find_best_variant() to preserve the existing enumeration
> - Replace cqspi_get_phy_pattern_offset() with per-flash probe-time
> phandle lookup in cqspi_of_get_flash_pdata(); fixes incorrect pattern
> offset selection when multiple flash devices share a controller
> - In cqspi_tune_phy(), reprogramme and resync the DLL when the active
> device's calibrated settings differ from hardware
> - Edit cqspi_phy_apply_setting() to update phy_setting.rx and
> phy_setting.tx alongside phy_setting.read_delay
> - Reprogram per-device CS timing (CQSPI_REG_DELAY and read-capture register)
> on any chip-select switch, not only on clock changes
> - Move post_config_max_speed_hz early-return to the top of
> spinand_optimize_controller(), before any state is modified
> - Remove dead NULL guards on SSDR op templates in Pass 2
> - Downgrade tuning-failure log messages from dev_warn to dev_dbg
> - Rebase on v7.2-rc3
> - Collect tags
> - Link to v4: https://lore.kernel.org/linux-spi/20260618073725.84733-1-s-k6@ti.com/
>
> 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 (18):
> spi: dt-bindings: add spi-max-post-config-frequency-hz property
> spi: dt-bindings: add spi-phy-pattern-partition property
> spi: parse spi-max-post-config-frequency-hz 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
> spi: cadence-quadspi: reprogram CS timing on every chip-select switch
> spi: cadence-quadspi: reprogram PHY DLL on runtime resume
> mtd: spinand: extract variant ranking logic into
> spinand_op_find_best_variant()
> mtd: spinand: negotiate optimal controller operating point before
> dirmap creation
> mtd: spi-nor: run controller optimization before dirmap creation
> mtd: spi-nor: reset max_read_op frequency for security register reads
>
> .../bindings/spi/cdns,qspi-nor.yaml | 17 +
> .../bindings/spi/spi-peripheral-props.yaml | 13 +
> drivers/mtd/nand/spi/core.c | 328 ++-
> drivers/mtd/spi-nor/core.c | 94 +-
> drivers/mtd/spi-nor/otp.c | 5 +
> drivers/spi/spi-cadence-quadspi.c | 2275 ++++++++++++++++-
> drivers/spi/spi-mem.c | 55 +-
> drivers/spi/spi.c | 2 +
> include/linux/mtd/spi-nor.h | 4 +
> include/linux/mtd/spinand.h | 15 +
> include/linux/spi/spi-mem.h | 14 +
> include/linux/spi/spi.h | 3 +
> 12 files changed, 2671 insertions(+), 154 deletions(-)
>
prev parent reply other threads:[~2026-10-29 4:50 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-29 6:35 Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 01/19] spi: dt-bindings: add spi-max-post-config-frequency-hz property Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 02/19] spi: dt-bindings: add spi-phy-pattern-partition property Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 03/19] spi: parse spi-max-post-config-frequency-hz into post_config_max_speed_hz Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 04/19] spi: spi-mem: teach spi_mem_adjust_op_freq() about post-config ops Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 05/19] spi: spi-mem: add execute_tuning callback and spi_mem_execute_tuning() Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 06/19] spi: cadence-quadspi: move cqspi_readdata_capture earlier Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 07/19] spi: cadence-quadspi: add DQS support to read data capture Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 08/19] spi: cadence-quadspi: add PHY tuning support Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 09/19] spi: cadence-quadspi: skip DDR PHY tuning for 2-byte-address ops (i2383) Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 10/19] spi: cadence-quadspi: refactor direct read path for PHY support Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 11/19] spi: cadence-quadspi: enable PHY for direct reads Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 12/19] spi: cadence-quadspi: enable PHY for indirect writes Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 13/19] spi: cadence-quadspi: reprogram CS timing on every chip-select switch Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 14/19] spi: cadence-quadspi: reprogram PHY DLL on runtime resume Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 15/19] mtd: spinand: extract variant ranking logic into spinand_op_find_best_variant() Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 16/19] mtd: spinand: negotiate optimal controller operating point before dirmap creation Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 17/19] mtd: spi-nor: extract read op template construction into helper Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 18/19] mtd: spi-nor: run controller optimization before dirmap creation Santhosh Kumar K
2026-09-29 6:35 ` [PATCH v10 19/19] mtd: spi-nor: reset max_read_op frequency for security register reads Santhosh Kumar K
2026-10-15 17:47 ` [PATCH v10 00/19] spi: cadence-quadspi: add PHY tuning support Boyapally, Srikanth
2026-10-29 4:49 ` Moteen Shah [this message]
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=87ad0389-983d-4fd9-8c4b-0daa108a040b@ti.com \
--to=m-shah@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=s-k6@ti.com \
--cc=sebin.francis@ti.com \
--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
all inboxes | Powered by JetHome®