@LasseRoedtnes
Please have a try this patch for r24.2.1
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 015e943..c7debce 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -242,6 +242,7 @@ struct tegra_spi_data {
u32 def_command1_reg;
u32 def_command2_reg;
u32 spi_cs_timing;
+ u32 spi_cs_timing2;
u8 def_chip_select;
struct completion xfer_completion;
@@ -974,9 +975,7 @@ static int tegra_spi_start_transfer_one(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 &&
- ((tspi->curr_dma_words * tspi->bytes_per_word) ==
- (t->len - tspi->cur_pos))) {
+ if (cdata && cdata->is_hw_based_cs && is_single_xfer) {
u32 set_count;
u32 hold_count;
u32 spi_cs_timing;
@@ -990,36 +989,43 @@ static int tegra_spi_start_transfer_one(struct spi_device *spi,
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;
- tegra_spi_writel(tspi, spi_cs_timing,
- SPI_CS_TIMING1);
+ spi_cs_setup = SPI_SETUP_HOLD(set_count, hold_count);
+ spi_cs_timing = SPI_CS_SETUP_HOLD(tspi->spi_cs_timing,
+ spi->chip_select,
+ spi_cs_setup);
+ if (tspi->spi_cs_timing != spi_cs_timing) {
+ tspi->spi_cs_timing = spi_cs_timing;
+ tegra_spi_writel(tspi, spi_cs_timing, SPI_CS_TIMING1);
+ }
tspi->is_hw_based_cs = true;
}
- if (cdata && cdata->cs_inactive_cycles) {
+ if (cdata->cs_inactive_cycles) {
u32 inactive_cycles;
SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing2,
- spi->chip_select,
- 0);
+ spi->chip_select,
+ 0);
inactive_cycles = min(cdata->cs_inactive_cycles, 32);
SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing2,
- spi->chip_select,
- inactive_cycles);
- tegra_spi_writel(tspi, spi_cs_timing2, SPI_CS_TIMING2);
+ spi->chip_select,
+ inactive_cycles);
+ if (tspi->spi_cs_timing2 != spi_cs_timing2) {
+ tspi->spi_cs_timing2 = spi_cs_timing2;
+ tegra_spi_writel(tspi, spi_cs_timing2,
+ SPI_CS_TIMING2);
+ }
tspi->is_hw_based_cs = true;
} else {
SPI_SET_CS_ACTIVE_BETWEEN_PACKETS(spi_cs_timing2,
- spi->chip_select, 1);
+ spi->chip_select, 1);
SPI_SET_CYCLES_BETWEEN_PACKETS(spi_cs_timing2,
- spi->chip_select, 0);
- tegra_spi_writel(tspi, spi_cs_timing2, SPI_CS_TIMING2);
+ spi->chip_select, 0);
+ if (tspi->spi_cs_timing2 != spi_cs_timing2) {
+ tspi->spi_cs_timing2 = spi_cs_timing2;
+ tegra_spi_writel(tspi, spi_cs_timing2,
+ SPI_CS_TIMING2);
+ }
}
if (!tspi->is_hw_based_cs) {
@@ -1972,6 +1978,8 @@ static int tegra_spi_probe(struct platform_device *pdev)
tspi->def_command1_reg |= SPI_CS_SEL(tspi->def_chip_select);
tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1);
tspi->def_command2_reg = tegra_spi_readl(tspi, SPI_COMMAND2);
+ tspi->spi_cs_timing = tegra_spi_readl(tspi, SPI_COMMAND1);
+ tspi->spi_cs_timing2 = tegra_spi_readl(tspi, SPI_COMMAND2);
tegra_spi_runtime_put(tspi);
ret = devm_request_irq(&pdev->dev, tspi->irq, tegra_spi_isr, 0,