static int tegra_spi_pio_finish(struct tegra_spi_channel *spi) { u8 *p = spi->in_buf; struct stopwatch sw; clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN | SPI_CMD1_TX_EN); /* * Allow some time in case the Rx FIFO does not yet have * all packets pushed into it. See chrome-os-partner:24215. */ stopwatch_init_usecs_expire(&sw, SPI_FIFO_XFER_TIMEOUT_US); do { if (rx_fifo_count(spi) == spi_byte_count(spi)) break; } while (!stopwatch_expired(&sw)); while (!(read32(&spi->regs->fifo_status) & SPI_FIFO_STATUS_RX_FIFO_EMPTY)) { *p = read8(&spi->regs->rx_fifo); p++; } if (fifo_error(spi)) { printk(BIOS_ERR, "%s: ERROR:\n", __func__); dump_spi_regs(spi); dump_fifo_status(spi); return -1; } return 0; }
static int tegra_spi_pio_finish(struct tegra_spi_channel *spi) { u8 *p = spi->in_buf; clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN | SPI_CMD1_TX_EN); ASSERT(rx_fifo_count(spi) == spi_byte_count(spi)); if (p) { while (!(read32(&spi->regs->fifo_status) & SPI_FIFO_STATUS_RX_FIFO_EMPTY)) { *p = read8(&spi->regs->rx_fifo); p++; } } if (fifo_error(spi)) { printk(BIOS_ERR, "%s: ERROR:\n", __func__); dump_spi_regs(spi); dump_fifo_status(spi); return -1; } return 0; }
static void tegra_spi_wait(struct tegra_spi_channel *spi) { unsigned int count, dma_blk; dma_blk = 1 + (read32(&spi->regs->dma_blk) & (SPI_DMA_CTL_BLOCK_SIZE_MASK << SPI_DMA_CTL_BLOCK_SIZE_SHIFT)); while ((count = spi_byte_count(spi)) != dma_blk) spi_delay(spi, dma_blk - count); }
static void tegra_spi_wait(struct tegra_spi_channel *spi) { uint32_t dma_blk_count = 1 + (read32(&spi->regs->dma_blk) & (SPI_DMA_CTL_BLOCK_SIZE_MASK << SPI_DMA_CTL_BLOCK_SIZE_SHIFT)); while ((read32(&spi->regs->trans_status) & SPI_STATUS_RDY) != SPI_STATUS_RDY) ; /* * If RDY bit is set, we should never encounter the condition that * blocks processed is not equal to the number programmed in dma_blk * register. */ ASSERT(spi_byte_count(spi) == dma_blk_count); }
static int tegra_spi_dma_finish(struct tegra_spi_channel *spi) { int ret; unsigned int todo; todo = read32(&spi->dma_in->regs->wcount); if (spi->dma_in) { while ((read32(&spi->dma_in->regs->dma_byte_sta) < todo) || dma_busy(spi->dma_in)) ; /* this shouldn't take long, no udelay */ dma_stop(spi->dma_in); clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN); dma_release(spi->dma_in); } if (spi->dma_out) { while ((read32(&spi->dma_out->regs->dma_byte_sta) < todo) || dma_busy(spi->dma_out)) spi_delay(spi, todo - spi_byte_count(spi)); clrbits_le32(&spi->regs->command1, SPI_CMD1_TX_EN); dma_stop(spi->dma_out); dma_release(spi->dma_out); } if (fifo_error(spi)) { printk(BIOS_ERR, "%s: ERROR:\n", __func__); dump_dma_regs(spi->dma_out); dump_dma_regs(spi->dma_in); dump_spi_regs(spi); dump_fifo_status(spi); ret = -1; goto done; } ret = 0; done: spi->dma_in = NULL; spi->dma_out = NULL; return ret; }