예제 #1
0
파일: spi.c 프로젝트: siro20/coreboot
static int tegra_spi_dma_finish(struct tegra_spi_channel *spi)
{
	int ret;
	unsigned int todo;

	struct apb_dma * const apb_dma = (struct apb_dma *)TEGRA_APB_DMA_BASE;

	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))
			;
		dma_stop(spi->dma_in);
		clrbits_le32(&spi->regs->command1, SPI_CMD1_RX_EN);
		/* Disable secure access for the channel. */
		clrbits_le32(&apb_dma->security_reg,
			     SECURITY_EN_BIT(spi->dma_in->num));
		dma_release(spi->dma_in);
	}

	if (spi->dma_out) {
		while ((read32(&spi->dma_out->regs->dma_byte_sta) < todo) ||
				dma_busy(spi->dma_out))
			;
		clrbits_le32(&spi->regs->command1, SPI_CMD1_TX_EN);
		dma_stop(spi->dma_out);
		/* Disable secure access for the channel. */
		clrbits_le32(&apb_dma->security_reg,
			     SECURITY_EN_BIT(spi->dma_out->num));
		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;
}
예제 #2
0
파일: spi.c 프로젝트: canistation/coreboot
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;
}
예제 #3
0
파일: dma.c 프로젝트: killbug2004/coreboot
/* release a DMA channel */
void dma_release(struct apb_dma_channel * const channel)
{
    int i;

    /* FIXME: make this "thread" friendly */
    while (dma_busy(channel))
        ;

    channel->in_use = 0;

    /* clear the global enable bit if no channels are in use */
    for (i = 0; i < ARRAY_SIZE(apb_dma_channels); i++) {
        if (apb_dma_channels[i].in_use)
            return;
    }

    clrbits_le32(&apb_dma->command, APB_COMMAND_GEN);
}