From 873e6f9e95f6cb0162fa06216682fbc71ab0202d Mon Sep 17 00:00:00 2001 From: David Hendricks Date: Mon, 4 Nov 2013 14:41:32 -0800 Subject: [PATCH] tegra124: enable flow control for APBDMA in SPI driver This enables flow control and sets the REQ_SEL field according to the SPI bus. Since REQ_SEL is just a constant that is associated with each channel, a member is added to the tegra_spi_regs struct to hold the appropriate value. BUG=none BRANCH=none TEST=built and booted on Nyan Signed-off-by: David Hendricks Change-Id: I037aee7e2d422e24a4cbcbc75280ec3c93d3e7bd Reviewed-on: https://chromium-review.googlesource.com/175630 Reviewed-by: Julius Werner Commit-Queue: David Hendricks Tested-by: David Hendricks --- src/soc/nvidia/tegra124/spi.c | 15 +++++++++++++-- src/soc/nvidia/tegra124/spi.h | 6 ++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/soc/nvidia/tegra124/spi.c b/src/soc/nvidia/tegra124/spi.c index 71f97643ad..373827820b 100644 --- a/src/soc/nvidia/tegra124/spi.c +++ b/src/soc/nvidia/tegra124/spi.c @@ -129,26 +129,32 @@ static struct tegra_spi_channel tegra_spi_channels[] = { { .slave = { .bus = 1, }, .regs = (struct tegra_spi_regs *)TEGRA_SPI1_BASE, + .req_sel = APBDMA_SLAVE_SL2B1, }, { .slave = { .bus = 2, }, .regs = (struct tegra_spi_regs *)TEGRA_SPI2_BASE, + .req_sel = APBDMA_SLAVE_SL2B2, }, { .slave = { .bus = 3, }, .regs = (struct tegra_spi_regs *)TEGRA_SPI3_BASE, + .req_sel = APBDMA_SLAVE_SL2B3, }, { .slave = { .bus = 4, }, .regs = (struct tegra_spi_regs *)TEGRA_SPI4_BASE, + .req_sel = APBDMA_SLAVE_SL2B4, }, { .slave = { .bus = 5, }, .regs = (struct tegra_spi_regs *)TEGRA_SPI5_BASE, + .req_sel = APBDMA_SLAVE_SL2B5, }, { .slave = { .bus = 6, }, .regs = (struct tegra_spi_regs *)TEGRA_SPI6_BASE, + .req_sel = APBDMA_SLAVE_SL2B6, }, }; @@ -416,8 +422,13 @@ static void setup_dma_params(struct tegra_spi_channel *spi, (AHB_BURST_MASK << AHB_BURST_SHIFT) | (AHB_SEQ_WRAP_MASK << AHB_SEQ_WRAP_SHIFT), AHB_BURST_MASK << AHB_BURST_SHIFT); - /* Set ONCE mode to transfer one "blocK" at a time (64KB). */ - setbits_le32(&dma->regs->csr, APB_CSR_ONCE); + + /* Set ONCE mode to transfer one "block" at a time (64KB) and enable + * flow control. */ + clrbits_le32(&dma->regs->csr, + APB_CSR_REQ_SEL_MASK << APB_CSR_REQ_SEL_SHIFT); + setbits_le32(&dma->regs->csr, APB_CSR_ONCE | APB_CSR_FLOW | + (spi->req_sel << APB_CSR_REQ_SEL_SHIFT)); } static int tegra_spi_dma_prepare(struct tegra_spi_channel *spi, diff --git a/src/soc/nvidia/tegra124/spi.h b/src/soc/nvidia/tegra124/spi.h index dfe9be25bd..b722240dcc 100644 --- a/src/soc/nvidia/tegra124/spi.h +++ b/src/soc/nvidia/tegra124/spi.h @@ -47,9 +47,12 @@ enum spi_xfer_mode { }; struct tegra_spi_channel { - struct spi_slave slave; struct tegra_spi_regs *regs; + /* static configuration */ + struct spi_slave slave; + unsigned int req_sel; + /* stuff that is specific to the attached device */ int rx_frame_header_enable; u8 frame_header; @@ -58,7 +61,6 @@ struct tegra_spi_channel { u8 *in_buf, *out_buf; struct apb_dma_channel *dma_out, *dma_in; enum spi_xfer_mode xfer_mode; - }; struct cbfs_media;