Tegra SPI controller has TX_CLK_TAP_DELAY and RX_CLK_TAP_DELAY in COMMAND2 register to tune delay of the clock going out to external device during transmit and also for the clock coming in from external device during receive. TX/RX clock tap delays may vary based on the trace lengths of the platform design for each of the slaves on the SPI bus. This patch adds support for configuring TX/RX clock delays specified through device tree properties. Signed-off-by: Sowjanya Komatineni <skomatineni@xxxxxxxxxx> --- drivers/spi/spi-tegra114.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index e01962344bde..725d60364ec6 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c @@ -174,6 +174,8 @@ struct tegra_spi_client_data { int cs_setup_clk_count; int cs_hold_clk_count; int cs_inactive_cycles; + int tx_clk_tap_delay; + int rx_clk_tap_delay; }; struct tegra_spi_data { @@ -215,8 +217,10 @@ struct tegra_spi_data { u32 command1_reg; u32 dma_control_reg; u32 def_command1_reg; + u32 def_command2_reg; u32 spi_cs_timing1; u32 spi_cs_timing2; + u8 last_used_cs; struct completion xfer_completion; struct spi_transfer *curr_xfer; @@ -780,7 +784,9 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, u32 speed = t->speed_hz; u8 bits_per_word = t->bits_per_word; u32 command1; + u32 command2; int req_mode; + u32 tx_tap = 0, rx_tap = 0; if (speed != tspi->cur_speed) { clk_set_rate(tspi->clk, speed); @@ -843,7 +849,18 @@ static u32 tegra_spi_setup_transfer_one(struct spi_device *spi, command1 &= ~(SPI_CS_SW_HW | SPI_CS_SW_VAL); } - tegra_spi_writel(tspi, 0, SPI_COMMAND2); + if (tspi->last_used_cs != spi->chip_select) { + if (cdata && cdata->tx_clk_tap_delay) + tx_tap = cdata->tx_clk_tap_delay; + if (cdata && cdata->rx_clk_tap_delay) + rx_tap = cdata->rx_clk_tap_delay; + command2 = SPI_TX_TAP_DELAY(tx_tap) | + SPI_RX_TAP_DELAY(rx_tap); + if (command2 != tspi->def_command2_reg) + tegra_spi_writel(tspi, command2, SPI_COMMAND2); + tspi->last_used_cs = spi->chip_select; + } + } else { command1 = tspi->command1_reg; command1 &= ~SPI_BIT_LENGTH(~0); @@ -923,6 +940,10 @@ static struct tegra_spi_client_data &cdata->cs_hold_clk_count); of_property_read_u32(slave_np, "nvidia,cs-inactive-cycles", &cdata->cs_inactive_cycles); + of_property_read_u32(slave_np, "nvidia,tx-clk-tap-delay", + &cdata->tx_clk_tap_delay); + of_property_read_u32(slave_np, "nvidia,rx-clk-tap-delay", + &cdata->rx_clk_tap_delay); return cdata; } @@ -1379,6 +1400,8 @@ static int tegra_spi_probe(struct platform_device *pdev) tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); tspi->spi_cs_timing1 = tegra_spi_readl(tspi, SPI_CS_TIMING1); tspi->spi_cs_timing2 = tegra_spi_readl(tspi, SPI_CS_TIMING2); + tspi->def_command2_reg = tegra_spi_readl(tspi, SPI_COMMAND2); + tspi->last_used_cs = master->num_chipselect + 1; pm_runtime_put(&pdev->dev); ret = request_threaded_irq(tspi->irq, tegra_spi_isr, tegra_spi_isr_thread, IRQF_ONESHOT, @@ -1451,6 +1474,8 @@ static int tegra_spi_resume(struct device *dev) return ret; } tegra_spi_writel(tspi, tspi->command1_reg, SPI_COMMAND1); + tegra_spi_writel(tspi, tspi->def_command2_reg, SPI_COMMAND2); + tspi->last_used_cs = master->num_chipselect + 1; pm_runtime_put(dev); return spi_master_resume(master); -- 2.7.4