Commit e4e8276a authored by Vignesh Raghavendra's avatar Vignesh Raghavendra Committed by Mark Brown

spi: spi-omap2-mcspi: Handle DMA size restriction on AM65x

On AM654, McSPI can only support 4K - 1 bytes per transfer when DMA is
enabled. Therefore populate master->max_transfer_size callback to
inform client drivers of this restriction when DMA channels are
available.
Signed-off-by: default avatarVignesh Raghavendra <vigneshr@ti.com>
Link: https://lore.kernel.org/r/20200204124816.16735-2-vigneshr@ti.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent a5362b84
...@@ -130,6 +130,7 @@ struct omap2_mcspi { ...@@ -130,6 +130,7 @@ struct omap2_mcspi {
int fifo_depth; int fifo_depth;
bool slave_aborted; bool slave_aborted;
unsigned int pin_dir:1; unsigned int pin_dir:1;
size_t max_xfer_len;
}; };
struct omap2_mcspi_cs { struct omap2_mcspi_cs {
...@@ -1305,6 +1306,18 @@ static bool omap2_mcspi_can_dma(struct spi_master *master, ...@@ -1305,6 +1306,18 @@ static bool omap2_mcspi_can_dma(struct spi_master *master,
return (xfer->len >= DMA_MIN_BYTES); return (xfer->len >= DMA_MIN_BYTES);
} }
static size_t omap2_mcspi_max_xfer_size(struct spi_device *spi)
{
struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
struct omap2_mcspi_dma *mcspi_dma =
&mcspi->dma_channels[spi->chip_select];
if (mcspi->max_xfer_len && mcspi_dma->dma_rx)
return mcspi->max_xfer_len;
return SIZE_MAX;
}
static int omap2_mcspi_controller_setup(struct omap2_mcspi *mcspi) static int omap2_mcspi_controller_setup(struct omap2_mcspi *mcspi)
{ {
struct spi_master *master = mcspi->master; struct spi_master *master = mcspi->master;
...@@ -1373,6 +1386,11 @@ static struct omap2_mcspi_platform_config omap4_pdata = { ...@@ -1373,6 +1386,11 @@ static struct omap2_mcspi_platform_config omap4_pdata = {
.regs_offset = OMAP4_MCSPI_REG_OFFSET, .regs_offset = OMAP4_MCSPI_REG_OFFSET,
}; };
static struct omap2_mcspi_platform_config am654_pdata = {
.regs_offset = OMAP4_MCSPI_REG_OFFSET,
.max_xfer_len = SZ_4K - 1,
};
static const struct of_device_id omap_mcspi_of_match[] = { static const struct of_device_id omap_mcspi_of_match[] = {
{ {
.compatible = "ti,omap2-mcspi", .compatible = "ti,omap2-mcspi",
...@@ -1382,6 +1400,10 @@ static const struct of_device_id omap_mcspi_of_match[] = { ...@@ -1382,6 +1400,10 @@ static const struct of_device_id omap_mcspi_of_match[] = {
.compatible = "ti,omap4-mcspi", .compatible = "ti,omap4-mcspi",
.data = &omap4_pdata, .data = &omap4_pdata,
}, },
{
.compatible = "ti,am654-mcspi",
.data = &am654_pdata,
},
{ }, { },
}; };
MODULE_DEVICE_TABLE(of, omap_mcspi_of_match); MODULE_DEVICE_TABLE(of, omap_mcspi_of_match);
...@@ -1439,6 +1461,10 @@ static int omap2_mcspi_probe(struct platform_device *pdev) ...@@ -1439,6 +1461,10 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
mcspi->pin_dir = pdata->pin_dir; mcspi->pin_dir = pdata->pin_dir;
} }
regs_offset = pdata->regs_offset; regs_offset = pdata->regs_offset;
if (pdata->max_xfer_len) {
mcspi->max_xfer_len = pdata->max_xfer_len;
master->max_transfer_size = omap2_mcspi_max_xfer_size;
}
r = platform_get_resource(pdev, IORESOURCE_MEM, 0); r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
mcspi->base = devm_ioremap_resource(&pdev->dev, r); mcspi->base = devm_ioremap_resource(&pdev->dev, r);
......
...@@ -11,6 +11,7 @@ struct omap2_mcspi_platform_config { ...@@ -11,6 +11,7 @@ struct omap2_mcspi_platform_config {
unsigned short num_cs; unsigned short num_cs;
unsigned int regs_offset; unsigned int regs_offset;
unsigned int pin_dir:1; unsigned int pin_dir:1;
size_t max_xfer_len;
}; };
struct omap2_mcspi_device_config { struct omap2_mcspi_device_config {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment