static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, struct spi_master *master, const struct resource *res) { int ret; /* Prepare for TX DMA: */ master->dma_tx = dma_request_slave_channel(dev, "tx"); if (!master->dma_tx) { dev_err(dev, "cannot get the TX DMA channel!\n"); ret = -EINVAL; goto err; } spi_imx->tx_config.direction = DMA_MEM_TO_DEV; spi_imx->tx_config.dst_addr = res->start + MXC_CSPITXDATA; spi_imx->tx_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; spi_imx->tx_config.dst_maxburst = spi_imx_get_fifosize(spi_imx) / 4; ret = dmaengine_slave_config(master->dma_tx, &spi_imx->tx_config); if (ret) { dev_err(dev, "error in TX dma configuration.\n"); goto err; } /* Prepare for RX : */ master->dma_rx = dma_request_slave_channel(dev, "rx"); if (!master->dma_rx) { dev_dbg(dev, "cannot get the DMA channel.\n"); ret = -EINVAL; goto err; } spi_imx->rx_config.direction = DMA_DEV_TO_MEM; spi_imx->rx_config.src_addr = res->start + MXC_CSPIRXDATA; spi_imx->rx_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; spi_imx->rx_config.src_maxburst = spi_imx_get_fifosize(spi_imx) / 2; ret = dmaengine_slave_config(master->dma_rx, &spi_imx->rx_config); if (ret) { dev_err(dev, "error in RX dma configuration.\n"); goto err; } init_completion(&spi_imx->dma_rx_completion); init_completion(&spi_imx->dma_tx_completion); master->can_dma = spi_imx_can_dma; master->max_dma_len = MAX_SDMA_BD_BYTES; spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; spi_imx->rx_wml = spi_imx->rx_config.src_maxburst; spi_imx->tx_wml = spi_imx->tx_config.dst_maxburst; spi_imx->dma_is_inited = 1; return 0; err: spi_imx_sdma_exit(spi_imx); return ret; }
static bool spi_imx_can_dma(struct spi_master *master, struct spi_device *spi, struct spi_transfer *transfer) { struct spi_imx_data *spi_imx = spi_master_get_devdata(master); if (transfer && spi_imx->dma_is_inited && (transfer->len > spi_imx_get_fifosize(spi_imx))) return true; return false; }
static void spi_imx_push(struct spi_imx_data *spi_imx) { while (spi_imx->txfifo < spi_imx_get_fifosize(spi_imx)) { if (!spi_imx->count) break; spi_imx->tx(spi_imx); spi_imx->txfifo++; } spi_imx->devtype_data->trigger(spi_imx); }
static int spi_imx_sdma_init(struct device *dev, struct spi_imx_data *spi_imx, struct spi_master *master) { int ret; /* use pio mode for i.mx6dl chip TKT238285 */ if (of_machine_is_compatible("fsl,imx6dl")) return 0; spi_imx->wml = spi_imx_get_fifosize(spi_imx) / 2; /* Prepare for TX DMA: */ master->dma_tx = dma_request_slave_channel_reason(dev, "tx"); if (IS_ERR(master->dma_tx)) { ret = PTR_ERR(master->dma_tx); dev_dbg(dev, "can't get the TX DMA channel, error %d!\n", ret); master->dma_tx = NULL; goto err; } /* Prepare for RX : */ master->dma_rx = dma_request_slave_channel_reason(dev, "rx"); if (IS_ERR(master->dma_rx)) { ret = PTR_ERR(master->dma_rx); dev_dbg(dev, "can't get the RX DMA channel, error %d\n", ret); master->dma_rx = NULL; goto err; } spi_imx_dma_configure(master, 1); init_completion(&spi_imx->dma_rx_completion); init_completion(&spi_imx->dma_tx_completion); master->can_dma = spi_imx_can_dma; master->max_dma_len = MAX_SDMA_BD_BYTES; spi_imx->bitbang.master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX; return 0; err: spi_imx_sdma_exit(spi_imx); return ret; }
static int __maybe_unused mx51_ecspi_config(struct spi_imx_data *spi_imx, struct spi_imx_config *config) { u32 ctrl = MX51_ECSPI_CTRL_ENABLE, cfg = 0, dma = 0; u32 tx_wml_cfg, rx_wml_cfg, rxt_wml_cfg; u32 clk = config->speed_hz, delay; /* * The hardware seems to have a race condition when changing modes. The * current assumption is that the selection of the channel arrives * earlier in the hardware than the mode bits when they are written at * the same time. * So set master mode for all channels as we do not support slave mode. */ ctrl |= MX51_ECSPI_CTRL_MODE_MASK; /* set clock speed */ ctrl |= mx51_ecspi_clkdiv(spi_imx->spi_clk, config->speed_hz, &clk); /* set chip select to use */ ctrl |= MX51_ECSPI_CTRL_CS(config->cs); ctrl |= (config->bpw - 1) << MX51_ECSPI_CTRL_BL_OFFSET; cfg |= MX51_ECSPI_CONFIG_SBBCTRL(config->cs); if (config->mode & SPI_CPHA) cfg |= MX51_ECSPI_CONFIG_SCLKPHA(config->cs); if (config->mode & SPI_CPOL) { cfg |= MX51_ECSPI_CONFIG_SCLKPOL(config->cs); cfg |= MX51_ECSPI_CONFIG_SCLKCTL(config->cs); } if (config->mode & SPI_CS_HIGH) cfg |= MX51_ECSPI_CONFIG_SSBPOL(config->cs); writel(ctrl, spi_imx->base + MX51_ECSPI_CTRL); writel(cfg, spi_imx->base + MX51_ECSPI_CONFIG); /* * Wait until the changes in the configuration register CONFIGREG * propagate into the hardware. It takes exactly one tick of the * SCLK clock, but we will wait two SCLK clock just to be sure. The * effect of the delay it takes for the hardware to apply changes * is noticable if the SCLK clock run very slow. In such a case, if * the polarity of SCLK should be inverted, the GPIO ChipSelect might * be asserted before the SCLK polarity changes, which would disrupt * the SPI communication as the device on the other end would consider * the change of SCLK polarity as a clock tick already. */ delay = (2 * 1000000) / clk; if (likely(delay < 10)) /* SCLK is faster than 100 kHz */ udelay(delay); else /* SCLK is _very_ slow */ usleep_range(delay, delay + 10); /* * Configure the DMA register: setup the watermark * and enable DMA request. */ if (spi_imx->dma_is_inited) { dma = readl(spi_imx->base + MX51_ECSPI_DMA); spi_imx->rxt_wml = spi_imx_get_fifosize(spi_imx) / 2; rx_wml_cfg = spi_imx->rx_wml << MX51_ECSPI_DMA_RX_WML_OFFSET; tx_wml_cfg = spi_imx->tx_wml << MX51_ECSPI_DMA_TX_WML_OFFSET; rxt_wml_cfg = spi_imx->rxt_wml << MX51_ECSPI_DMA_RXT_WML_OFFSET; dma = (dma & ~MX51_ECSPI_DMA_TX_WML_MASK & ~MX51_ECSPI_DMA_RX_WML_MASK & ~MX51_ECSPI_DMA_RXT_WML_MASK) | rx_wml_cfg | tx_wml_cfg | rxt_wml_cfg |(1 << MX51_ECSPI_DMA_TEDEN_OFFSET) |(1 << MX51_ECSPI_DMA_RXDEN_OFFSET) |(1 << MX51_ECSPI_DMA_RXTDEN_OFFSET); writel(dma, spi_imx->base + MX51_ECSPI_DMA); } return 0; }