Skip to content

Commit

Permalink
spi: microchip-core-qspi: Support per spi-mem operation frequency swi…
Browse files Browse the repository at this point in the history
…tches

Every ->exec_op() call correctly configures the spi bus speed to the
maximum allowed frequency for the memory using the constant spi default
parameter. Since we can now have per-operation constraints, let's use
the value that comes from the spi-mem operation structure instead. In
case there is no specific limitation for this operation, the default spi
device value will be given anyway.

This controller however performed a frequency check, which is also
observed during the ->check_op() phase.

The per-operation frequency capability is thus advertised to the spi-mem
core.

Cc: Conor Dooley <conor.dooley@microchip.com>
Cc: Daire McNamara <daire.mcnamara@microchip.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://patch.msgid.link/20241224-winbond-6-11-rc1-quad-support-v2-9-ad218dbc406f@bootlin.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Miquel Raynal authored and Mark Brown committed Jan 9, 2025
1 parent 2438db5 commit 1352964
Showing 1 changed file with 22 additions and 4 deletions.
26 changes: 22 additions & 4 deletions drivers/spi/spi-microchip-core-qspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ static irqreturn_t mchp_coreqspi_isr(int irq, void *dev_id)
return ret;
}

static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_device *spi)
static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_device *spi,
const struct spi_mem_op *op)
{
unsigned long clk_hz;
u32 control, baud_rate_val = 0;
Expand All @@ -274,11 +275,11 @@ static int mchp_coreqspi_setup_clock(struct mchp_coreqspi *qspi, struct spi_devi
if (!clk_hz)
return -EINVAL;

baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * spi->max_speed_hz);
baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * op->max_freq);
if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER) {
dev_err(&spi->dev,
"could not configure the clock for spi clock %d Hz & system clock %ld Hz\n",
spi->max_speed_hz, clk_hz);
op->max_freq, clk_hz);
return -EINVAL;
}

Expand Down Expand Up @@ -399,7 +400,7 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *o
if (err)
goto error;

err = mchp_coreqspi_setup_clock(qspi, mem->spi);
err = mchp_coreqspi_setup_clock(qspi, mem->spi, op);
if (err)
goto error;

Expand Down Expand Up @@ -457,6 +458,10 @@ static int mchp_coreqspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *o

static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_op *op)
{
struct mchp_coreqspi *qspi = spi_controller_get_devdata(mem->spi->controller);
unsigned long clk_hz;
u32 baud_rate_val;

if (!spi_mem_default_supports_op(mem, op))
return false;

Expand All @@ -479,6 +484,14 @@ static bool mchp_coreqspi_supports_op(struct spi_mem *mem, const struct spi_mem_
return false;
}

clk_hz = clk_get_rate(qspi->clk);
if (!clk_hz)
return false;

baud_rate_val = DIV_ROUND_UP(clk_hz, 2 * op->max_freq);
if (baud_rate_val > MAX_DIVIDER || baud_rate_val < MIN_DIVIDER)
return false;

return true;
}

Expand All @@ -498,6 +511,10 @@ static const struct spi_controller_mem_ops mchp_coreqspi_mem_ops = {
.exec_op = mchp_coreqspi_exec_op,
};

static const struct spi_controller_mem_caps mchp_coreqspi_mem_caps = {
.per_op_freq = true,
};

static int mchp_coreqspi_probe(struct platform_device *pdev)
{
struct spi_controller *ctlr;
Expand Down Expand Up @@ -540,6 +557,7 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)

ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
ctlr->mem_ops = &mchp_coreqspi_mem_ops;
ctlr->mem_caps = &mchp_coreqspi_mem_caps;
ctlr->setup = mchp_coreqspi_setup_op;
ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_RX_DUAL | SPI_RX_QUAD |
SPI_TX_DUAL | SPI_TX_QUAD;
Expand Down

0 comments on commit 1352964

Please sign in to comment.