Commit 635b9b2e authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'spi/topic/dw', 'spi/topic/dw-mid',...

Merge remote-tracking branches 'spi/topic/dw', 'spi/topic/dw-mid', 'spi/topic/fsl-espi' and 'spi/topic/imx' into spi-next
...@@ -283,7 +283,7 @@ static void mid_spi_dma_stop(struct dw_spi *dws) ...@@ -283,7 +283,7 @@ static void mid_spi_dma_stop(struct dw_spi *dws)
} }
} }
static struct dw_spi_dma_ops mid_dma_ops = { static const struct dw_spi_dma_ops mid_dma_ops = {
.dma_init = mid_spi_dma_init, .dma_init = mid_spi_dma_init,
.dma_exit = mid_spi_dma_exit, .dma_exit = mid_spi_dma_exit,
.dma_setup = mid_spi_dma_setup, .dma_setup = mid_spi_dma_setup,
......
...@@ -425,7 +425,7 @@ static int dw_spi_setup(struct spi_device *spi) ...@@ -425,7 +425,7 @@ static int dw_spi_setup(struct spi_device *spi)
chip->type = chip_info->type; chip->type = chip_info->type;
} }
chip->tmode = 0; /* Tx & Rx */ chip->tmode = SPI_TMOD_TR;
if (gpio_is_valid(spi->cs_gpio)) { if (gpio_is_valid(spi->cs_gpio)) {
ret = gpio_direction_output(spi->cs_gpio, ret = gpio_direction_output(spi->cs_gpio,
......
...@@ -130,7 +130,7 @@ struct dw_spi { ...@@ -130,7 +130,7 @@ struct dw_spi {
struct dma_chan *rxchan; struct dma_chan *rxchan;
unsigned long dma_chan_busy; unsigned long dma_chan_busy;
dma_addr_t dma_addr; /* phy address of the Data register */ dma_addr_t dma_addr; /* phy address of the Data register */
struct dw_spi_dma_ops *dma_ops; const struct dw_spi_dma_ops *dma_ops;
void *dma_tx; void *dma_tx;
void *dma_rx; void *dma_rx;
......
...@@ -643,6 +643,11 @@ static int fsl_espi_runtime_resume(struct device *dev) ...@@ -643,6 +643,11 @@ static int fsl_espi_runtime_resume(struct device *dev)
} }
#endif #endif
static size_t fsl_espi_max_transfer_size(struct spi_device *spi)
{
return SPCOM_TRANLEN_MAX;
}
static struct spi_master * fsl_espi_probe(struct device *dev, static struct spi_master * fsl_espi_probe(struct device *dev,
struct resource *mem, unsigned int irq) struct resource *mem, unsigned int irq)
{ {
...@@ -670,6 +675,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev, ...@@ -670,6 +675,7 @@ static struct spi_master * fsl_espi_probe(struct device *dev,
master->cleanup = fsl_espi_cleanup; master->cleanup = fsl_espi_cleanup;
master->transfer_one_message = fsl_espi_do_one_msg; master->transfer_one_message = fsl_espi_do_one_msg;
master->auto_runtime_pm = true; master->auto_runtime_pm = true;
master->max_transfer_size = fsl_espi_max_transfer_size;
mpc8xxx_spi = spi_master_get_devdata(master); mpc8xxx_spi = spi_master_get_devdata(master);
......
...@@ -104,9 +104,7 @@ struct spi_imx_data { ...@@ -104,9 +104,7 @@ struct spi_imx_data {
unsigned int dma_is_inited; unsigned int dma_is_inited;
unsigned int dma_finished; unsigned int dma_finished;
bool usedma; bool usedma;
u32 rx_wml; u32 wml;
u32 tx_wml;
u32 rxt_wml;
struct completion dma_rx_completion; struct completion dma_rx_completion;
struct completion dma_tx_completion; struct completion dma_tx_completion;
...@@ -124,9 +122,14 @@ static inline int is_imx35_cspi(struct spi_imx_data *d) ...@@ -124,9 +122,14 @@ static inline int is_imx35_cspi(struct spi_imx_data *d)
return d->devtype_data->devtype == IMX35_CSPI; return d->devtype_data->devtype == IMX35_CSPI;
} }
static inline int is_imx51_ecspi(struct spi_imx_data *d)
{
return d->devtype_data->devtype == IMX51_ECSPI;
}
static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d) static inline unsigned spi_imx_get_fifosize(struct spi_imx_data *d)
{ {
return (d->devtype_data->devtype == IMX51_ECSPI) ? 64 : 8; return is_imx51_ecspi(d) ? 64 : 8;
} }
#define MXC_SPI_BUF_RX(type) \ #define MXC_SPI_BUF_RX(type) \
...@@ -201,9 +204,8 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -201,9 +204,8 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
{ {
struct spi_imx_data *spi_imx = spi_master_get_devdata(master); struct spi_imx_data *spi_imx = spi_master_get_devdata(master);
if (spi_imx->dma_is_inited if (spi_imx->dma_is_inited &&
&& transfer->len > spi_imx->rx_wml * sizeof(u32) transfer->len > spi_imx->wml * sizeof(u32))
&& transfer->len > spi_imx->tx_wml * sizeof(u32))
return true; return true;
return false; return false;
} }
...@@ -244,6 +246,9 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, ...@@ -244,6 +246,9 @@ static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi,
#define MX51_ECSPI_STAT 0x18 #define MX51_ECSPI_STAT 0x18
#define MX51_ECSPI_STAT_RR (1 << 3) #define MX51_ECSPI_STAT_RR (1 << 3)
#define MX51_ECSPI_TESTREG 0x20
#define MX51_ECSPI_TESTREG_LBC BIT(31)
/* MX51 eCSPI */ /* MX51 eCSPI */
static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi, static unsigned int mx51_ecspi_clkdiv(unsigned int fin, unsigned int fspi,
unsigned int *fres) unsigned int *fres)
...@@ -313,7 +318,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, ...@@ -313,7 +318,7 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,
{ {
u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0; u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0;
u32 tx_wml_cfg, rx_wml_cfg, rxt_wml_cfg; u32 tx_wml_cfg, rx_wml_cfg, rxt_wml_cfg;
u32 clk = config->speed_hz, delay; u32 clk = config->speed_hz, delay, reg;
/* /*
* The hardware seems to have a race condition when changing modes. The * The hardware seems to have a race condition when changing modes. The
...@@ -351,7 +356,16 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, ...@@ -351,7 +356,16 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,
else else
cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs); cfg &= ~MX51_ECSPI_CONFIG_SSBPOL(config->cs);
/* CTRL register always go first to bring out controller from reset */
writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL);
reg = readl(spi_imx->base + MX51_ECSPI_TESTREG);
if (config->mode & SPI_LOOP)
reg |= MX51_ECSPI_TESTREG_LBC;
else
reg &= ~MX51_ECSPI_TESTREG_LBC;
writel(reg, spi_imx->base + MX51_ECSPI_TESTREG);
writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG);
/* /*
...@@ -378,10 +392,9 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, ...@@ -378,10 +392,9 @@ static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx,
if (spi_imx->dma_is_inited) { if (spi_imx->dma_is_inited) {
dma = readl(spi_imx->base + MX51_ECSPI_DMA); dma = readl(spi_imx->base + MX51_ECSPI_DMA);
spi_imx->rxt_wml = spi_imx_get_fifosize(spi_imx) / 2; rx_wml_cfg = spi_imx->wml << MX51_ECSPI_DMA_RX_WML_OFFSET;
rx_wml_cfg = spi_imx->rx_wml << MX51_ECSPI_DMA_RX_WML_OFFSET; tx_wml_cfg = spi_imx->wml << MX51_ECSPI_DMA_TX_WML_OFFSET;
tx_wml_cfg = spi_imx->tx_wml << MX51_ECSPI_DMA_TX_WML_OFFSET; rxt_wml_cfg = spi_imx->wml << MX51_ECSPI_DMA_RXT_WML_OFFSET;
rxt_wml_cfg = spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET;
dma = (dma & ~MX51_ECSPI_DMA_TX_WML_MASK dma = (dma & ~MX51_ECSPI_DMA_TX_WML_MASK
& ~MX51_ECSPI_DMA_RX_WML_MASK & ~MX51_ECSPI_DMA_RX_WML_MASK
& ~MX51_ECSPI_DMA_RXT_WML_MASK) & ~MX51_ECSPI_DMA_RXT_WML_MASK)
...@@ -832,18 +845,21 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, ...@@ -832,18 +845,21 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
if (of_machine_is_compatible("fsl,imx6dl")) if (of_machine_is_compatible("fsl,imx6dl"))
return 0; return 0;
spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2;
/* Prepare for TX DMA: */ /* Prepare for TX DMA: */
master->dma_tx = dma_request_slave_channel(dev, "tx"); master->dma_tx = dma_request_slave_channel_reason(dev, "tx");
if (!master->dma_tx) { if (IS_ERR(master->dma_tx)) {
dev_err(dev, "cannot get the TX DMA channel!\n"); ret = PTR_ERR(master->dma_tx);
ret = -EINVAL; dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret);
master->dma_tx = NULL;
goto err; goto err;
} }
slave_config.direction = DMA_MEM_TO_DEV; slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = res->start + MXC_CSPITXDATA; slave_config.dst_addr = res->start + MXC_CSPITXDATA;
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
slave_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 2; slave_config.dst_maxburst = spi_imx->wml;
ret = dmaengine_slave_config(master->dma_tx, &slave_config); ret = dmaengine_slave_config(master->dma_tx, &slave_config);
if (ret) { if (ret) {
dev_err(dev, "error in TX dma configuration.\n"); dev_err(dev, "error in TX dma configuration.\n");
...@@ -851,17 +867,18 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, ...@@ -851,17 +867,18 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
} }
/* Prepare for RX : */ /* Prepare for RX : */
master->dma_rx = dma_request_slave_channel(dev, "rx"); master->dma_rx = dma_request_slave_channel_reason(dev, "rx");
if (!master->dma_rx) { if (IS_ERR(master->dma_rx)) {
dev_dbg(dev, "cannot get the DMA channel.\n"); ret = PTR_ERR(master->dma_rx);
ret = -EINVAL; dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret);
master->dma_rx = NULL;
goto err; goto err;
} }
slave_config.direction = DMA_DEV_TO_MEM; slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = res->start + MXC_CSPIRXDATA; slave_config.src_addr = res->start + MXC_CSPIRXDATA;
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
slave_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2; slave_config.src_maxburst = spi_imx->wml;
ret = dmaengine_slave_config(master->dma_rx, &slave_config); ret = dmaengine_slave_config(master->dma_rx, &slave_config);
if (ret) { if (ret) {
dev_err(dev, "error in RX dma configuration.\n"); dev_err(dev, "error in RX dma configuration.\n");
...@@ -874,8 +891,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, ...@@ -874,8 +891,6 @@ static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx,
master->max_dma_len = MAX_SDMA_BD_BYTES; master->max_dma_len = MAX_SDMA_BD_BYTES;
spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX |
SPI_MASTER_MUST_TX; SPI_MASTER_MUST_TX;
spi_imx->tx_wml = spi_imx_get_fifosize(spi_imx) / 2;
spi_imx->rx_wml = spi_imx_get_fifosize(spi_imx) / 2;
spi_imx->dma_is_inited = 1; spi_imx->dma_is_inited = 1;
return 0; return 0;
...@@ -942,14 +957,22 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, ...@@ -942,14 +957,22 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
dma = readl(spi_imx->base + MX51_ECSPI_DMA); dma = readl(spi_imx->base + MX51_ECSPI_DMA);
dma = dma & (~MX51_ECSPI_DMA_RXT_WML_MASK); dma = dma & (~MX51_ECSPI_DMA_RXT_WML_MASK);
/* Change RX_DMA_LENGTH trigger dma fetch tail data */ /* Change RX_DMA_LENGTH trigger dma fetch tail data */
left = transfer->len % spi_imx->rxt_wml; left = transfer->len % spi_imx->wml;
if (left) if (left)
writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET), writel(dma | (left << MX51_ECSPI_DMA_RXT_WML_OFFSET),
spi_imx->base + MX51_ECSPI_DMA); spi_imx->base + MX51_ECSPI_DMA);
/*
* Set these order to avoid potential RX overflow. The overflow may
* happen if we enable SPI HW before starting RX DMA due to rescheduling
* for another task and/or interrupt.
* So RX DMA enabled first to make sure data would be read out from FIFO
* ASAP. TX DMA enabled next to start filling TX FIFO with new data.
* And finaly SPI HW enabled to start actual data transfer.
*/
dma_async_issue_pending(master->dma_rx);
dma_async_issue_pending(master->dma_tx);
spi_imx->devtype_data->trigger(spi_imx); spi_imx->devtype_data->trigger(spi_imx);
dma_async_issue_pending(master->dma_tx);
dma_async_issue_pending(master->dma_rx);
/* Wait SDMA to finish the data transfer.*/ /* Wait SDMA to finish the data transfer.*/
timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion, timeout = wait_for_completion_timeout(&spi_imx->dma_tx_completion,
IMX_DMA_TIMEOUT); IMX_DMA_TIMEOUT);
...@@ -958,6 +981,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, ...@@ -958,6 +981,7 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
dev_driver_string(&master->dev), dev_driver_string(&master->dev),
dev_name(&master->dev)); dev_name(&master->dev));
dmaengine_terminate_all(master->dma_tx); dmaengine_terminate_all(master->dma_tx);
dmaengine_terminate_all(master->dma_rx);
} else { } else {
timeout = wait_for_completion_timeout( timeout = wait_for_completion_timeout(
&spi_imx->dma_rx_completion, IMX_DMA_TIMEOUT); &spi_imx->dma_rx_completion, IMX_DMA_TIMEOUT);
...@@ -968,8 +992,9 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx, ...@@ -968,8 +992,9 @@ static int spi_imx_dma_transfer(struct spi_imx_data *spi_imx,
spi_imx->devtype_data->reset(spi_imx); spi_imx->devtype_data->reset(spi_imx);
dmaengine_terminate_all(master->dma_rx); dmaengine_terminate_all(master->dma_rx);
} }
dma &= ~MX51_ECSPI_DMA_RXT_WML_MASK;
writel(dma | writel(dma |
spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET, spi_imx->wml << MX51_ECSPI_DMA_RXT_WML_OFFSET,
spi_imx->base + MX51_ECSPI_DMA); spi_imx->base + MX51_ECSPI_DMA);
} }
...@@ -1117,6 +1142,9 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1117,6 +1142,9 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx = spi_master_get_devdata(master); spi_imx = spi_master_get_devdata(master);
spi_imx->bitbang.master = master; spi_imx->bitbang.master = master;
spi_imx->devtype_data = of_id ? of_id->data :
(struct spi_imx_devtype_data *)pdev->id_entry->driver_data;
for (i = 0; i < master->num_chipselect; i++) { for (i = 0; i < master->num_chipselect; i++) {
int cs_gpio = of_get_named_gpio(np, "cs-gpios", i); int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
if (!gpio_is_valid(cs_gpio) && mxc_platform_info) if (!gpio_is_valid(cs_gpio) && mxc_platform_info)
...@@ -1142,12 +1170,11 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1142,12 +1170,11 @@ static int spi_imx_probe(struct platform_device *pdev)
spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message; spi_imx->bitbang.master->prepare_message = spi_imx_prepare_message;
spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message; spi_imx->bitbang.master->unprepare_message = spi_imx_unprepare_message;
spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH; spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
if (is_imx51_ecspi(spi_imx))
spi_imx->bitbang.master->mode_bits |= SPI_LOOP;
init_completion(&spi_imx->xfer_done); init_completion(&spi_imx->xfer_done);
spi_imx->devtype_data = of_id ? of_id->data :
(struct spi_imx_devtype_data *) pdev->id_entry->driver_data;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
spi_imx->base = devm_ioremap_resource(&pdev->dev, res); spi_imx->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(spi_imx->base)) { if (IS_ERR(spi_imx->base)) {
...@@ -1193,9 +1220,15 @@ static int spi_imx_probe(struct platform_device *pdev) ...@@ -1193,9 +1220,15 @@ static int spi_imx_probe(struct platform_device *pdev)
* Only validated on i.mx6 now, can remove the constrain if validated on * Only validated on i.mx6 now, can remove the constrain if validated on
* other chips. * other chips.
*/ */
if (spi_imx->devtype_data == &imx51_ecspi_devtype_data if (is_imx51_ecspi(spi_imx)) {
&& spi_imx_sdma_init(&pdev->dev, spi_imx, master, res)) ret = spi_imx_sdma_init(&pdev->dev, spi_imx, master, res);
dev_err(&pdev->dev, "dma setup error,use pio instead\n"); if (ret == -EPROBE_DEFER)
goto out_clk_put;
if (ret < 0)
dev_err(&pdev->dev, "dma setup error %d, use pio\n",
ret);
}
spi_imx->devtype_data->reset(spi_imx); spi_imx->devtype_data->reset(spi_imx);
......
...@@ -425,6 +425,12 @@ struct spi_master { ...@@ -425,6 +425,12 @@ struct spi_master {
#define SPI_MASTER_MUST_RX BIT(3) /* requires rx */ #define SPI_MASTER_MUST_RX BIT(3) /* requires rx */
#define SPI_MASTER_MUST_TX BIT(4) /* requires tx */ #define SPI_MASTER_MUST_TX BIT(4) /* requires tx */
/*
* on some hardware transfer size may be constrained
* the limit may depend on device transfer settings
*/
size_t (*max_transfer_size)(struct spi_device *spi);
/* lock and mutex for SPI bus locking */ /* lock and mutex for SPI bus locking */
spinlock_t bus_lock_spinlock; spinlock_t bus_lock_spinlock;
struct mutex bus_lock_mutex; struct mutex bus_lock_mutex;
...@@ -832,6 +838,15 @@ extern int spi_async(struct spi_device *spi, struct spi_message *message); ...@@ -832,6 +838,15 @@ extern int spi_async(struct spi_device *spi, struct spi_message *message);
extern int spi_async_locked(struct spi_device *spi, extern int spi_async_locked(struct spi_device *spi,
struct spi_message *message); struct spi_message *message);
static inline size_t
spi_max_transfer_size(struct spi_device *spi)
{
struct spi_master *master = spi->master;
if (!master->max_transfer_size)
return SIZE_MAX;
return master->max_transfer_size(spi);
}
/*---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------*/
/* All these synchronous SPI transfer routines are utilities layered /* All these synchronous SPI transfer routines are utilities layered
......
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