diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2012-10-01 17:11:42 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2013-09-14 01:13:06 -0700 |
commit | c33ea529199187e596517150fef3c4f71b045936 (patch) | |
tree | 0d8556cc9143c319c0a97485770cbfe62f1c98b4 /drivers/spi | |
parent | 9d9ad24a990b5d50a81e297a05f9a3740049a340 (diff) |
spi: tegra11: add support for HW based CS
Add support for HW based CS and add configuration
for CS setup time and hold time.
Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com>
Reviewed-on: http://git-master/r/140617
(cherry picked from commit 90dcafb1414c8e3cb53bbdf518758210aa73f21b)
Change-Id: If746f74145d3cd0804bb8dccdd8f1d0e3c2ebf3b
Signed-off-by: Deepak Nibade <dnibade@nvidia.com>
Reviewed-on: http://git-master/r/143270
Reviewed-by: Automatic_Commit_Validation_User
GVS: Gerrit_Virtual_Submit
Reviewed-by: Bharat Nihalani <bnihalani@nvidia.com>
Tested-by: Bharat Nihalani <bnihalani@nvidia.com>
Rebase-Id: R6cb1f9dbba6d78ca2cf4bc1917a1dad4b3b8b8ab
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-tegra11.c | 50 |
1 files changed, 34 insertions, 16 deletions
diff --git a/drivers/spi/spi-tegra11.c b/drivers/spi/spi-tegra11.c index 761f793266c0..bfa04fc968d6 100644 --- a/drivers/spi/spi-tegra11.c +++ b/drivers/spi/spi-tegra11.c @@ -82,23 +82,12 @@ #define SPI_TX_TAP_DELAY(x) (((x) & 0x3F) << 6) #define SPI_RX_TAP_DELAY(x) (((x) & 0x3F) << 0) -#define SPI_CS_TIM1 0x008 -#define SPI_CS_HOLD_TIME_0(x) (((x) & 0xF) << 0) -#define SPI_CS_SETUP_TIME_0(x) (((x) & 0xF) << 4) -#define SPI_CS_HOLD_TIME_1(x) (((x) & 0xF) << 8) -#define SPI_CS_SETUP_TIME_1(x) (((x) & 0xF) << 12) -#define SPI_CS_HOLD_TIME_2(x) (((x) & 0xF) << 16) -#define SPI_CS_SETUP_TIME_2(x) (((x) & 0xF) << 20) -#define SPI_CS_HOLD_TIME_3(x) (((x) & 0xF) << 24) -#define SPI_CS_SETUP_TIME_3(x) (((x) & 0xF) << 28) -#define SPI_SET_CS_SETUP_TIME(reg, cs, val) \ - (reg = ((val & 0xF) << (cs*8 + 4)) | \ - (reg & ~(0xF << (cs*8 + 4)))) -#define SPI_SET_CS_HOLD_TIME(reg, cs, val) \ - (reg = ((val & 0xF) << (cs*8)) | \ - (reg & ~(0xF << (cs*8)))) +#define SPI_CS_TIMING1 0x008 +#define SPI_SETUP_HOLD(setup, hold) ((setup << 4) | hold) +#define SPI_CS_SETUP_HOLD(reg, cs, val) (((val & 0xFFu) << (cs * 8)) | \ + (reg & ~(0xFFu << (cs * 8)))) -#define SPI_CS_TIM2 0x00C +#define SPI_CS_TIMING2 0x00C #define CYCLES_BETWEEN_PACKETS_0(x) (((x) & 0x1F) << 0) #define CS_ACTIVE_BETWEEN_PACKETS_0 (1 << 5) #define CYCLES_BETWEEN_PACKETS_1(x) (((x) & 0x1F) << 8) @@ -247,6 +236,7 @@ struct spi_tegra_data { u32 dma_control_reg; u32 def_command1_reg; u32 def_command2_reg; + u32 spi_cs_timing; struct spi_clk_parent *parent_clk_list; int parent_clk_count; @@ -748,6 +738,34 @@ static void spi_tegra_start_transfer(struct spi_device *spi, /* possibly use the hw based chip select */ tspi->is_hw_based_cs = false; + if (cdata && cdata->is_hw_based_cs && is_single_xfer) { + if ((tspi->curr_dma_words * tspi->bytes_per_word) == + (t->len - tspi->cur_pos)) { + u32 set_count; + u32 hold_count; + u32 spi_cs_timing; + u32 spi_cs_setup; + + set_count = min(cdata->cs_setup_clk_count, 16); + if (set_count) + set_count--; + + hold_count = min(cdata->cs_hold_clk_count, 16); + if (hold_count) + hold_count--; + + spi_cs_setup = SPI_SETUP_HOLD(set_count, + hold_count); + spi_cs_timing = tspi->spi_cs_timing; + spi_cs_timing = SPI_CS_SETUP_HOLD(spi_cs_timing, + spi->chip_select, + spi_cs_setup); + tspi->spi_cs_timing = spi_cs_timing; + spi_tegra_writel(tspi, spi_cs_timing, + SPI_CS_TIMING1); + tspi->is_hw_based_cs = true; + } + } if (!tspi->is_hw_based_cs) { command1 |= SPI_CS_SW_HW; if (spi->mode & SPI_CS_HIGH) |