summaryrefslogtreecommitdiff
path: root/drivers/spi/spi-tegra11.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-tegra11.c')
-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)