Unverified Commit 870d6fda authored by Larisa Grigore's avatar Larisa Grigore Committed by Mark Brown
Browse files

spi: spi-fsl-dspi: Use DMA for S32G controller in target mode



Switch to DMA for target mode otherwise the controller is too slow to
feed TX FIFO and UNDERFLOW occurs frequently. DMA can work only with 8
and 16 bits per word. 32bits per word is not supported, this is a
hardware limitation, so we keep the controller mode in TCFQ mode.

Signed-off-by: default avatarLarisa Grigore <larisa.grigore@nxp.com>
Signed-off-by: default avatarCiprian Marian Costea <ciprianmarian.costea@nxp.com>
Signed-off-by: default avatarJames Clark <james.clark@linaro.org>
Link: https://patch.msgid.link/20250522-james-nxp-spi-v2-9-bea884630cfb@linaro.org


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent cac7e505
Loading
Loading
Loading
Loading
+26 −0
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ enum {
	MCF5441X,
	VF610,
	S32G,
	S32G_TARGET,
};

static const struct regmap_range dspi_yes_ranges[] = {
@@ -183,6 +184,7 @@ static const struct regmap_access_table dspi_volatile_table = {

enum {
	DSPI_REGMAP,
	S32G_DSPI_REGMAP,
	DSPI_XSPI_REGMAP,
	S32G_DSPI_XSPI_REGMAP,
	DSPI_PUSHR,
@@ -198,6 +200,15 @@ static const struct regmap_config dspi_regmap_config[] = {
		.rd_table	= &dspi_access_table,
		.wr_table	= &dspi_access_table,
	},
	[S32G_DSPI_REGMAP] = {
		.reg_bits	= 32,
		.val_bits	= 32,
		.reg_stride	= 4,
		.max_register	= SPI_RXFR4,
		.volatile_table	= &dspi_volatile_table,
		.wr_table	= &s32g_dspi_access_table,
		.rd_table	= &s32g_dspi_access_table,
	},
	[DSPI_XSPI_REGMAP] = {
		.reg_bits	= 32,
		.val_bits	= 32,
@@ -296,6 +307,12 @@ static const struct fsl_dspi_devtype_data devtype_data[] = {
		.fifo_size	  = 5,
		.regmap		  = &dspi_regmap_config[S32G_DSPI_XSPI_REGMAP],
	},
	[S32G_TARGET] = {
		.trans_mode	  = DSPI_DMA_MODE,
		.max_clock_factor = 1,
		.fifo_size	  = 5,
		.regmap		  = &dspi_regmap_config[S32G_DSPI_REGMAP],
	},
};

struct fsl_dspi_dma {
@@ -351,6 +368,12 @@ struct fsl_dspi {
	void (*dev_to_host)(struct fsl_dspi *dspi, u32 rxdata);
};

static bool is_s32g_dspi(struct fsl_dspi *data)
{
	return data->devtype_data == &devtype_data[S32G] ||
	       data->devtype_data == &devtype_data[S32G_TARGET];
}

static void dspi_native_host_to_dev(struct fsl_dspi *dspi, u32 *txdata)
{
	switch (dspi->oper_word_size) {
@@ -1426,6 +1449,9 @@ static int dspi_probe(struct platform_device *pdev)
		dspi->pushr_tx = 0;
	}

	if (spi_controller_is_target(ctlr) && is_s32g_dspi(dspi))
		dspi->devtype_data = &devtype_data[S32G_TARGET];

	if (dspi->devtype_data->trans_mode == DSPI_XSPI_MODE)
		ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
	else