summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2012-10-01 17:11:42 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2013-09-14 01:13:06 -0700
commitc33ea529199187e596517150fef3c4f71b045936 (patch)
tree0d8556cc9143c319c0a97485770cbfe62f1c98b4 /drivers/spi
parent9d9ad24a990b5d50a81e297a05f9a3740049a340 (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.c50
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)