Unverified Commit e4feefa5 authored by Clément Le Goffic's avatar Clément Le Goffic Committed by Mark Brown
Browse files

spi: stm32: Add SPI_READY mode to spi controller



The spi ready functionality is supported by our peripheral in host and
target modes on STM32MP2x SoCs.
Update our spi controller driver to allow devices to use this
functionality.

Signed-off-by: default avatarClément Le Goffic <clement.legoffic@foss.st.com>
Link: https://patch.msgid.link/20250616-spi-upstream-v1-1-7e8593f3f75d@foss.st.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 86731a2a
Loading
Loading
Loading
Loading
+24 −4
Original line number Diff line number Diff line
@@ -154,6 +154,9 @@
/* STM32H7_SPI_I2SCFGR bit fields */
#define STM32H7_SPI_I2SCFGR_I2SMOD	BIT(0)

/* STM32MP25_SPICFG2 bit fields */
#define STM32MP25_SPI_CFG2_RDIOM	BIT(13)

/* STM32MP25 SPI registers bit fields */
#define STM32MP25_SPI_HWCFGR1			0x3F0

@@ -222,6 +225,7 @@ struct stm32_spi_reg {
 * @rx: SPI RX data register
 * @tx: SPI TX data register
 * @fullcfg: SPI full or limited feature set register
 * @rdy_en: SPI ready feature register
 */
struct stm32_spi_regspec {
	const struct stm32_spi_reg en;
@@ -235,6 +239,7 @@ struct stm32_spi_regspec {
	const struct stm32_spi_reg rx;
	const struct stm32_spi_reg tx;
	const struct stm32_spi_reg fullcfg;
	const struct stm32_spi_reg rdy_en;
};

struct stm32_spi;
@@ -415,6 +420,8 @@ static const struct stm32_spi_regspec stm32mp25_spi_regspec = {
	.tx = { STM32H7_SPI_TXDR },

	.fullcfg = { STM32MP25_SPI_HWCFGR1, STM32MP25_SPI_HWCFGR1_FULLCFG },

	.rdy_en = { STM32H7_SPI_CFG2, STM32MP25_SPI_CFG2_RDIOM },
};

static inline void stm32_spi_set_bits(struct stm32_spi *spi,
@@ -1172,15 +1179,21 @@ static int stm32_spi_prepare_msg(struct spi_controller *ctrl,
	else
		clrb |= spi->cfg->regs->cs_high.mask;

	dev_dbg(spi->dev, "cpol=%d cpha=%d lsb_first=%d cs_high=%d\n",
	if (spi_dev->mode & SPI_READY)
		setb |= spi->cfg->regs->rdy_en.mask;
	else
		clrb |= spi->cfg->regs->rdy_en.mask;

	dev_dbg(spi->dev, "cpol=%d cpha=%d lsb_first=%d cs_high=%d rdy=%d\n",
		!!(spi_dev->mode & SPI_CPOL),
		!!(spi_dev->mode & SPI_CPHA),
		!!(spi_dev->mode & SPI_LSB_FIRST),
		!!(spi_dev->mode & SPI_CS_HIGH));
		!!(spi_dev->mode & SPI_CS_HIGH),
		!!(spi_dev->mode & SPI_READY));

	spin_lock_irqsave(&spi->lock, flags);

	/* CPOL, CPHA and LSB FIRST bits have common register */
	/* CPOL, CPHA, LSB FIRST, CS_HIGH and RDY_EN bits have common register */
	if (clrb || setb)
		writel_relaxed(
			(readl_relaxed(spi->base + spi->cfg->regs->cpol.reg) &
@@ -1768,6 +1781,13 @@ static int stm32_spi_transfer_one_setup(struct stm32_spi *spi,
	spi->cur_bpw = transfer->bits_per_word;
	spi->cfg->set_bpw(spi);

	if (spi_dev->mode & SPI_READY && spi->cur_bpw < 8) {
		writel_relaxed(readl_relaxed(spi->base + spi->cfg->regs->rdy_en.reg) &
				~spi->cfg->regs->rdy_en.mask,
					spi->base + spi->cfg->regs->rdy_en.reg);
		dev_dbg(spi->dev, "RDY logic disabled as bits per word < 8\n");
	}

	/* Update spi->cur_speed with real clock speed */
	if (STM32_SPI_HOST_MODE(spi)) {
		mbr = stm32_spi_prepare_mbr(spi, transfer->speed_hz,
@@ -2179,7 +2199,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
	ctrl->auto_runtime_pm = true;
	ctrl->bus_num = pdev->id;
	ctrl->mode_bits = SPI_CPHA | SPI_CPOL | SPI_CS_HIGH | SPI_LSB_FIRST |
			  SPI_3WIRE;
			  SPI_3WIRE | SPI_READY;
	ctrl->bits_per_word_mask = spi->cfg->get_bpw_mask(spi);
	ctrl->max_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_min;
	ctrl->min_speed_hz = spi->clk_rate / spi->cfg->baud_rate_div_max;