summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-tegra.c
diff options
context:
space:
mode:
authorAmit Kamath <akamath@nvidia.com>2010-12-29 16:18:31 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:43:22 -0800
commit257f0224c3e24d6ad71e8b8b9b71b0327657ecf7 (patch)
tree4b00d40b3efaf076480a215e931d46a2f71303a5 /drivers/spi/spi-tegra.c
parent6005b31062d5b0874cc7caa79405c3ef80712770 (diff)
[ARM] tegra: spi: Fixed setup bugs
Enabled clocks at spi_setup Fixed problem with endianness for 16 bit word size Fixed issue with small packet size less than fifo depth Fixed typo that enabled RX and TX by default Integration from http://git-master/r/#change,14536 Original-Change-Id: I2cea3bdcb6a19780087671131a848095354105a3 Reviewed-on: http://git-master/r/15949 Reviewed-on: http://git-master/r/16048 Reviewed-by: Amit Kamath <akamath@nvidia.com> Tested-by: Amit Kamath <akamath@nvidia.com> Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com> Rebase-Id: Ra7c9c381f2ae897d002853c9965252ba28dc28ac
Diffstat (limited to 'drivers/spi/spi-tegra.c')
-rw-r--r--drivers/spi/spi-tegra.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/spi/spi-tegra.c b/drivers/spi/spi-tegra.c
index b7c895168855..14ac633aa4b7 100644
--- a/drivers/spi/spi-tegra.c
+++ b/drivers/spi/spi-tegra.c
@@ -129,6 +129,7 @@
#define SLINK_TX_FIFO 0x100
#define SLINK_RX_FIFO 0x180
+#define SLINK_FIFO_DEPTH 0x20
static const unsigned long spi_tegra_req_sels[] = {
TEGRA_DMA_REQ_SEL_SL2B1,
@@ -236,6 +237,7 @@ static void spi_tegra_go(struct spi_tegra_data *tspi)
{
unsigned long val;
unsigned long test_val;
+ unsigned unused_fifo_size;
wmb();
@@ -264,9 +266,12 @@ static void spi_tegra_go(struct spi_tegra_data *tspi)
/*
* TRM 24.1.1.7 wait for the FIFO to be full
*/
- test_val = spi_tegra_readl(tspi, SLINK_STATUS);
- while (!(test_val & SLINK_TX_FULL))
- test_val = spi_tegra_readl(tspi, SLINK_STATUS);
+ test_val = spi_tegra_readl(tspi, SLINK_STATUS2);
+ unused_fifo_size = (tspi->tx_dma_req.size/4) >= 0x20 ?
+ 0:
+ SLINK_FIFO_DEPTH - (tspi->tx_dma_req.size/4);
+ while (SLINK_TX_FIFO_EMPTY_COUNT(test_val) != (unused_fifo_size))
+ test_val = spi_tegra_readl(tspi, SLINK_STATUS2);
if (tspi->is_packed) {
val = spi_tegra_readl(tspi, SLINK_DMA_CTL);
@@ -315,7 +320,7 @@ static unsigned spi_tegra_fill_tx_fifo(struct spi_tegra_data *tspi,
for (i = 0; i < len; i += tspi->cur_bytes_per_word) {
val = 0;
for (j = 0; j < tspi->cur_bytes_per_word; j++)
- val |= tx_buf[i + j] << j * 8;
+ val |= tx_buf[i + j] << (tspi->cur_bytes_per_word-j-1) * 8;
tspi->tx_bb[i / tspi->cur_bytes_per_word] = val;
}
@@ -351,7 +356,8 @@ static unsigned spi_tegra_drain_rx_fifo(struct spi_tegra_data *tspi,
for (i = 0; i < len; i += tspi->cur_bytes_per_word) {
val = tspi->rx_bb[i / tspi->cur_bytes_per_word];
for (j = 0; j < tspi->cur_bytes_per_word; j++)
- rx_buf[i + j] = (val >> (j * 8)) & 0xff;
+ rx_buf[i + j] =
+ (val >> (tspi->cur_bytes_per_word - j - 1) * 8) & 0xff;
}
}
@@ -421,7 +427,7 @@ static void spi_tegra_start_transfer(struct spi_device *spi,
spi_tegra_clear_status(tspi);
val = spi_tegra_readl(tspi, SLINK_COMMAND2);
- val &= ~SLINK_SS_EN_CS(~0) | SLINK_RXEN | SLINK_TXEN;
+ val &= ~(SLINK_SS_EN_CS(~0) | SLINK_RXEN | SLINK_TXEN);
if (t->rx_buf)
val |= SLINK_RXEN;
if (t->tx_buf)
@@ -581,7 +587,6 @@ static int spi_tegra_setup(struct spi_device *spi)
spi->mode & SPI_CPHA ? "" : "~",
spi->max_speed_hz);
-
switch (spi->chip_select) {
case 0:
cs_bit = SLINK_CS_POLARITY;
@@ -605,6 +610,13 @@ static int spi_tegra_setup(struct spi_device *spi)
spin_lock_irqsave(&tspi->lock, flags);
+ if (spi->max_speed_hz != tspi->cur_speed)
+ clk_set_rate(tspi->clk, spi->max_speed_hz);
+
+ if (tspi->cur_speed == 0)
+ clk_enable(tspi->clk);
+ tspi->cur_speed = spi->max_speed_hz;
+
val = spi_tegra_readl(tspi, SLINK_COMMAND);
if (spi->mode & SPI_CS_HIGH)
val |= cs_bit;