Lines Matching +full:half +full:- +full:length
1 // SPDX-License-Identifier: GPL-2.0+
8 * NOTE: This driver only supports the SPI-controller chipselects,
19 #include <asm/arch/imx-regs.h>
21 #include <asm/mach-imx/dma.h>
68 mxs_slave->max_khz = max_hz / 1000; in spi_setup_slave()
69 mxs_slave->mode = mode; in spi_setup_slave()
70 mxs_slave->regs = mxs_ssp_regs_by_bus(bus); in spi_setup_slave()
72 return &mxs_slave->slave; in spi_setup_slave()
88 struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; in spi_claim_bus()
91 mxs_reset_block(&ssp_regs->hw_ssp_ctrl0_reg); in spi_claim_bus()
93 writel((slave->cs << MXS_SSP_CHIPSELECT_SHIFT) | in spi_claim_bus()
95 &ssp_regs->hw_ssp_ctrl0); in spi_claim_bus()
98 reg |= (mxs_slave->mode & SPI_CPOL) ? SSP_CTRL1_POLARITY : 0; in spi_claim_bus()
99 reg |= (mxs_slave->mode & SPI_CPHA) ? SSP_CTRL1_PHASE : 0; in spi_claim_bus()
100 writel(reg, &ssp_regs->hw_ssp_ctrl1); in spi_claim_bus()
102 writel(0, &ssp_regs->hw_ssp_cmd0); in spi_claim_bus()
104 mxs_set_ssp_busclock(slave->bus, mxs_slave->max_khz); in spi_claim_bus()
115 writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_set); in mxs_spi_start_xfer()
116 writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_clr); in mxs_spi_start_xfer()
121 writel(SSP_CTRL0_LOCK_CS, &ssp_regs->hw_ssp_ctrl0_clr); in mxs_spi_end_xfer()
122 writel(SSP_CTRL0_IGNORE_CRC, &ssp_regs->hw_ssp_ctrl0_set); in mxs_spi_end_xfer()
126 char *data, int length, int write, unsigned long flags) in mxs_spi_xfer_pio() argument
128 struct mxs_ssp_regs *ssp_regs = slave->regs; in mxs_spi_xfer_pio()
133 while (length--) { in mxs_spi_xfer_pio()
136 writel(SSP_CTRL0_XFER_COUNT_MASK, &ssp_regs->hw_ssp_ctrl0_clr); in mxs_spi_xfer_pio()
137 writel(1, &ssp_regs->hw_ssp_ctrl0_set); in mxs_spi_xfer_pio()
139 writel(1, &ssp_regs->hw_ssp_xfer_size); in mxs_spi_xfer_pio()
142 if ((flags & SPI_XFER_END) && !length) in mxs_spi_xfer_pio()
146 writel(SSP_CTRL0_READ, &ssp_regs->hw_ssp_ctrl0_clr); in mxs_spi_xfer_pio()
148 writel(SSP_CTRL0_READ, &ssp_regs->hw_ssp_ctrl0_set); in mxs_spi_xfer_pio()
150 writel(SSP_CTRL0_RUN, &ssp_regs->hw_ssp_ctrl0_set); in mxs_spi_xfer_pio()
152 if (mxs_wait_mask_set(&ssp_regs->hw_ssp_ctrl0_reg, in mxs_spi_xfer_pio()
155 return -ETIMEDOUT; in mxs_spi_xfer_pio()
159 writel(*data++, &ssp_regs->hw_ssp_data); in mxs_spi_xfer_pio()
161 writel(SSP_CTRL0_DATA_XFER, &ssp_regs->hw_ssp_ctrl0_set); in mxs_spi_xfer_pio()
164 if (mxs_wait_mask_clr(&ssp_regs->hw_ssp_status_reg, in mxs_spi_xfer_pio()
167 return -ETIMEDOUT; in mxs_spi_xfer_pio()
170 *data = readl(&ssp_regs->hw_ssp_data); in mxs_spi_xfer_pio()
174 if (mxs_wait_mask_clr(&ssp_regs->hw_ssp_ctrl0_reg, in mxs_spi_xfer_pio()
177 return -ETIMEDOUT; in mxs_spi_xfer_pio()
185 char *data, int length, int write, unsigned long flags) in mxs_spi_xfer_dma() argument
188 const int desc_count = DIV_ROUND_UP(length, xfer_max_sz) + 1; in mxs_spi_xfer_dma()
189 struct mxs_ssp_regs *ssp_regs = slave->regs; in mxs_spi_xfer_dma()
208 ctrl0 = readl(&ssp_regs->hw_ssp_ctrl0); in mxs_spi_xfer_dma()
216 if (length % ARCH_DMA_MINALIGN) in mxs_spi_xfer_dma()
217 cache_data_count = roundup(length, ARCH_DMA_MINALIGN); in mxs_spi_xfer_dma()
219 cache_data_count = length; in mxs_spi_xfer_dma()
228 dmach = MXS_DMA_CHANNEL_AHB_APBH_SSP0 + slave->slave.bus; in mxs_spi_xfer_dma()
231 while (length) { in mxs_spi_xfer_dma()
232 dp->address = (dma_addr_t)dp; in mxs_spi_xfer_dma()
233 dp->cmd.address = (dma_addr_t)data; in mxs_spi_xfer_dma()
239 * and employed ;-) in mxs_spi_xfer_dma()
242 dp->cmd.data = MXS_DMA_DESC_COMMAND_DMA_READ; in mxs_spi_xfer_dma()
244 dp->cmd.data = MXS_DMA_DESC_COMMAND_DMA_WRITE; in mxs_spi_xfer_dma()
248 * time by setting the transfer length to 0. Setting tl to in mxs_spi_xfer_dma()
252 if (length >= 0x10000) in mxs_spi_xfer_dma()
255 tl = min(length, xfer_max_sz); in mxs_spi_xfer_dma()
257 dp->cmd.data |= in mxs_spi_xfer_dma()
264 length -= tl; in mxs_spi_xfer_dma()
266 if (!length) { in mxs_spi_xfer_dma()
267 dp->cmd.data |= MXS_DMA_DESC_IRQ | MXS_DMA_DESC_DEC_SEM; in mxs_spi_xfer_dma()
280 * a per-descriptor basis with the same size as is the in mxs_spi_xfer_dma()
283 dp->cmd.pio_words[0] = ctrl0; in mxs_spi_xfer_dma()
285 dp->cmd.pio_words[1] = 0; in mxs_spi_xfer_dma()
286 dp->cmd.pio_words[2] = 0; in mxs_spi_xfer_dma()
287 dp->cmd.pio_words[3] = tl; in mxs_spi_xfer_dma()
296 ret = -EINVAL; in mxs_spi_xfer_dma()
309 struct mxs_ssp_regs *ssp_regs = mxs_slave->regs; in spi_xfer()
324 /* Half-duplex only */ in spi_xfer()
326 return -EINVAL; in spi_xfer()
345 if (((uint32_t)data) & (ARCH_DMA_MINALIGN - 1)) in spi_xfer()
347 if (((uint32_t)len) & (ARCH_DMA_MINALIGN - 1)) in spi_xfer()
352 writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_clr); in spi_xfer()
355 writel(SSP_CTRL1_DMA_ENABLE, &ssp_regs->hw_ssp_ctrl1_set); in spi_xfer()